The branch main has been updated by bz:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ac1d519c01ca8beb59f27962c7052d09a03f72c8

commit ac1d519c01ca8beb59f27962c7052d09a03f72c8
Author:     Bjoern A. Zeeb <b...@freebsd.org>
AuthorDate: 2024-10-28 12:02:56 +0000
Commit:     Bjoern A. Zeeb <b...@freebsd.org>
CommitDate: 2024-10-28 12:05:06 +0000

    LinuxKPI: 802.11: adjustments for v6.11 iwlwifi, rtw88 and rtw89
    
    Bring ing the LinuxKPI 802.11 compat bits which are not altering
    the mac80211 ops KPI.
    
    * Add various functions for drvier updates.
    * Add functions (some compat code to I assume cleanup some
      mac80211 ops) emulating chanctx changes doing (*config) updates.
    * Adjust structs and defines.
    * Deal with an enum growing more than 32 bits in printf.
    * Add a mtx to struct wiphy which is exposed to the drivers.
      Handle initialization and destruction for now.
    * Implementation of wiphy_work and wiphy_delayed_work.
    * Set was_assoc for deassoc/deauth in prep_tx_info.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
---
 .../linuxkpi/common/include/linux/ieee80211.h      |  43 +++-
 sys/compat/linuxkpi/common/include/linux/nl80211.h |   1 +
 sys/compat/linuxkpi/common/include/net/cfg80211.h  | 250 +++++++++++++++++++--
 sys/compat/linuxkpi/common/include/net/mac80211.h  | 173 +++++++++++++-
 sys/compat/linuxkpi/common/src/linux_80211.c       | 202 ++++++++++++++++-
 sys/compat/linuxkpi/common/src/linux_80211.h       |  19 +-
 6 files changed, 635 insertions(+), 53 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h 
b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index ce6a18f798d1..865d85c6f7b7 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -42,8 +42,8 @@ extern int linuxkpi_debug_80211;
 #ifndef        D80211_TODO
 #define        D80211_TODO             0x1
 #endif
-#define        TODO(...)               if (linuxkpi_debug_80211 & D80211_TODO) 
\
-    printf("%s:%d: XXX LKPI80211 TODO\n", __func__, __LINE__)
+#define        TODO(fmt, ...)          if (linuxkpi_debug_80211 & D80211_TODO) 
\
+    printf("%s:%d: XXX LKPI80211 TODO " fmt "\n", __func__, __LINE__, 
##__VA_ARGS__)
 
 
 /* 9.4.2.55 Management MIC element (CMAC-256, GMAC-128, and GMAC-256). */
@@ -138,16 +138,18 @@ enum wlan_ht_cap_sm_ps {
 #define        WLAN_PMKID_LEN                          16
 #define        WLAN_PMK_LEN_SUITE_B_192                48
 
-#define        WLAN_KEY_LEN_WEP40                      5
-#define        WLAN_KEY_LEN_WEP104                     13
-#define        WLAN_KEY_LEN_TKIP                       32
-#define        WLAN_KEY_LEN_CCMP                       16
-#define        WLAN_KEY_LEN_GCMP                       16
-#define        WLAN_KEY_LEN_AES_CMAC                   16
-#define        WLAN_KEY_LEN_GCMP_256                   32
-#define        WLAN_KEY_LEN_BIP_CMAC_256               32
-#define        WLAN_KEY_LEN_BIP_GMAC_128               16
-#define        WLAN_KEY_LEN_BIP_GMAC_256               32
+enum ieee80211_key_len {
+       WLAN_KEY_LEN_WEP40                      = 5,
+       WLAN_KEY_LEN_WEP104                     = 13,
+       WLAN_KEY_LEN_TKIP                       = 32,
+       WLAN_KEY_LEN_CCMP                       = 16,
+       WLAN_KEY_LEN_GCMP                       = 16,
+       WLAN_KEY_LEN_AES_CMAC                   = 16,
+       WLAN_KEY_LEN_GCMP_256                   = 32,
+       WLAN_KEY_LEN_BIP_CMAC_256               = 32,
+       WLAN_KEY_LEN_BIP_GMAC_128               = 16,
+       WLAN_KEY_LEN_BIP_GMAC_256               = 32,
+};
 
 /* 802.11-2020, 9.4.2.55.3, Table 9-185 Subfields of the A-MPDU Parameters 
field */
 enum ieee80211_min_mpdu_start_spacing {
@@ -483,9 +485,14 @@ enum ieee80211_back {
        WLAN_ACTION_ADDBA_REQ           = 0,
 };
 
+enum ieee80211_sa_query {
+       WLAN_ACTION_SA_QUERY_RESPONSE   = 1,
+};
+
 /* 802.11-2020, Table 9-51-Category values */
 enum ieee80211_category {
        WLAN_CATEGORY_BACK              = 3,
+       WLAN_CATEGORY_SA_QUERY          = 8,    /* 
net80211::IEEE80211_ACTION_CAT_SA_QUERY */
 };
 
 /* 80211-2020 9.3.3.2 Format of Management frames */
@@ -601,6 +608,7 @@ enum ieee80211_eid {
        WLAN_EID_TIM                            = 5,
        WLAN_EID_COUNTRY                        = 7,    /* 
IEEE80211_ELEMID_COUNTRY */
        WLAN_EID_REQUEST                        = 10,
+       WLAN_EID_QBSS_LOAD                      = 11,   /* 
IEEE80211_ELEMID_BSSLOAD */
        WLAN_EID_CHANNEL_SWITCH                 = 37,
        WLAN_EID_MEASURE_REPORT                 = 39,
        WLAN_EID_HT_CAPABILITY                  = 45,   /* 
IEEE80211_ELEMID_HTCAP */
@@ -612,6 +620,7 @@ enum ieee80211_eid {
        WLAN_EID_MULTI_BSSID_IDX                = 85,
        WLAN_EID_EXT_CAPABILITY                 = 127,
        WLAN_EID_VHT_CAPABILITY                 = 191,  /* 
IEEE80211_ELEMID_VHT_CAP */
+       WLAN_EID_S1G_TWT                        = 216,
        WLAN_EID_VENDOR_SPECIFIC                = 221,  /* 
IEEE80211_ELEMID_VENDOR */
 };
 
@@ -760,6 +769,16 @@ enum ieee80211_tx_pwr_interpretation_subfield_enc {
        IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
 };
 
+enum ieee80211_tx_pwr_category_6ghz {
+       IEEE80211_TPE_CAT_6GHZ_DEFAULT,
+};
+
+/* 802.11-2020, 9.4.2.27 BSS Load element */
+struct ieee80211_bss_load_elem {
+       uint16_t                                sta_count;
+       uint8_t                                 channel_util;
+       uint16_t                                avail_adm_capa;
+};
 
 /* net80211: IEEE80211_IS_CTL() */
 static __inline bool
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h 
b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index 6916957731e2..254ed6e13f5c 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -84,6 +84,7 @@ enum nl80211_reg_rule_flags {
        NL80211_RRF_NO_6GHZ_VLP_CLIENT                  = BIT(14),
        NL80211_RRF_NO_6GHZ_AFC_CLIENT                  = BIT(15),
        NL80211_RRF_PSD                                 = BIT(16),
+       NL80211_RRF_ALLOW_6GHZ_VLP_AP                   = BIT(17),
 };
 #define        NL80211_RRF_NO_HT40     
(NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS)
 
diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h 
b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index 7e57ce67cc26..f489e7a7da11 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  * Copyright (c) 2021-2022 Bjoern A. Zeeb
  *
  * This software was developed by Björn Zeeb under sponsorship from
@@ -39,6 +39,8 @@
 #include <linux/netdevice.h>
 #include <linux/random.h>
 #include <linux/skbuff.h>
+#include <linux/timer.h>
+#include <linux/workqueue.h>
 #include <net/regulatory.h>
 
 /* linux_80211.c */
@@ -49,8 +51,8 @@ extern int linuxkpi_debug_80211;
 #ifndef        D80211_IMPROVE
 #define        D80211_IMPROVE          0x2
 #endif
-#define        TODO(...)               if (linuxkpi_debug_80211 & D80211_TODO) 
\
-    printf("%s:%d: XXX LKPI80211 TODO\n", __func__, __LINE__)
+#define        TODO(fmt, ...)          if (linuxkpi_debug_80211 & D80211_TODO) 
\
+    printf("%s:%d: XXX LKPI80211 TODO " fmt "\n",  __func__, __LINE__, 
##__VA_ARGS__)
 #define        IMPROVE(...)    if (linuxkpi_debug_80211 & D80211_IMPROVE)      
\
     printf("%s:%d: XXX LKPI80211 IMPROVE\n", __func__, __LINE__)
 
@@ -106,6 +108,11 @@ enum ieee80211_channel_flags {
        IEEE80211_CHAN_NO_80MHZ                 = BIT(7),
        IEEE80211_CHAN_NO_160MHZ                = BIT(8),
        IEEE80211_CHAN_NO_OFDM                  = BIT(9),
+       IEEE80211_CHAN_NO_6GHZ_VLP_CLIENT       = BIT(10),
+       IEEE80211_CHAN_NO_6GHZ_AFC_CLIENT       = BIT(11),
+       IEEE80211_CHAN_PSD                      = BIT(12),
+       IEEE80211_CHAN_ALLOW_6GHZ_VLP_AP        = BIT(13),
+       IEEE80211_CHAN_CAN_MONITOR              = BIT(14),
 };
 #define        IEEE80211_CHAN_NO_HT40  
(IEEE80211_CHAN_NO_HT40MINUS|IEEE80211_CHAN_NO_HT40PLUS)
 
@@ -275,6 +282,9 @@ struct cfg80211_bss_ies {
 struct cfg80211_bss {
                /* XXX TODO */
        struct cfg80211_bss_ies         *ies;
+       struct cfg80211_bss_ies         *beacon_ies;
+
+       int32_t                         signal;
 };
 
 struct cfg80211_chan_def {
@@ -283,6 +293,7 @@ struct cfg80211_chan_def {
        enum nl80211_chan_width         width;
        uint32_t                        center_freq1;
        uint32_t                        center_freq2;
+       uint16_t                        punctured;
 };
 
 struct cfg80211_ftm_responder_stats {
@@ -378,11 +389,16 @@ struct cfg80211_match_set {
 
 struct cfg80211_scan_request {
                /* XXX TODO */
-       int     duration, duration_mandatory, flags;
        bool                                    no_cck;
        bool                                    scan_6ghz;
+       bool                                    duration_mandatory;
+       int8_t                                  tsf_report_link_id;
+       uint16_t                                duration;
+       uint32_t                                flags;
        struct wireless_dev                     *wdev;
        struct wiphy                            *wiphy;
+       uint64_t                                scan_start;
+       uint32_t                                rates[NUM_NL80211_BANDS];
        int                                     ie_len;
        uint8_t                                 *ie;
        uint8_t                                 mac_addr[ETH_ALEN], 
mac_addr_mask[ETH_ALEN];
@@ -774,6 +790,7 @@ struct linuxkpi_ieee80211_regdomain {
 #define        IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE1          0x05
 #define        IEEE80211_EHT_MAC_CAP0_TRIG_TXOP_SHARING_MODE2          0x06
 #define        IEEE80211_EHT_MAC_CAP0_MAX_MPDU_LEN_7991                0x07
+#define        IEEE80211_EHT_MAC_CAP0_SCS_TRAFFIC_DESC                 0x08
 
 #define        IEEE80211_EHT_MAC_CAP1_MAX_AMPDU_LEN_MASK               0x01
 
@@ -895,16 +912,26 @@ struct ieee80211_sta_he_6ghz_capa {
 };
 
 struct ieee80211_eht_mcs_nss_supp_20mhz_only {
-       uint8_t                                 rx_tx_mcs7_max_nss;
-       uint8_t                                 rx_tx_mcs9_max_nss;
-       uint8_t                                 rx_tx_mcs11_max_nss;
-       uint8_t                                 rx_tx_mcs13_max_nss;
+       union {
+               struct {
+                       uint8_t                         rx_tx_mcs7_max_nss;
+                       uint8_t                         rx_tx_mcs9_max_nss;
+                       uint8_t                         rx_tx_mcs11_max_nss;
+                       uint8_t                         rx_tx_mcs13_max_nss;
+               };
+               uint8_t                                 rx_tx_max_nss[4];
+       };
 };
 
 struct ieee80211_eht_mcs_nss_supp_bw {
-       uint8_t                                 rx_tx_mcs9_max_nss;
-       uint8_t                                 rx_tx_mcs11_max_nss;
-       uint8_t                                 rx_tx_mcs13_max_nss;
+       union {
+               struct {
+                       uint8_t                         rx_tx_mcs9_max_nss;
+                       uint8_t                         rx_tx_mcs11_max_nss;
+                       uint8_t                         rx_tx_mcs13_max_nss;
+               };
+               uint8_t                                 rx_tx_max_nss[3];
+       };
 };
 
 struct ieee80211_eht_cap_elem_fixed {
@@ -1096,7 +1123,7 @@ struct wiphy_iftype_ext_capab {
        const uint8_t                           *extended_capabilities_mask;
        uint8_t                                 extended_capabilities_len;
        uint16_t                                eml_capabilities;
-
+       uint16_t                                mld_capa_and_ops;
 };
 
 struct tid_config_support {
@@ -1133,10 +1160,23 @@ enum wiphy_flags {
        WIPHY_FLAG_4ADDR_AP                     = BIT(14),
        WIPHY_FLAG_4ADDR_STATION                = BIT(15),
        WIPHY_FLAG_SUPPORTS_MLO                 = BIT(16),
+       WIPHY_FLAG_DISABLE_WEXT                 = BIT(17),
 };
 
-struct wiphy {
+struct wiphy_work;
+typedef void (*wiphy_work_fn)(struct wiphy *, struct wiphy_work *);
+struct wiphy_work {
+       struct list_head                        entry;
+       wiphy_work_fn                           fn;
+};
+struct wiphy_delayed_work {
+       struct wiphy_work                       work;
+       struct wiphy                            *wiphy;
+       struct timer_list                       timer;
+};
 
+struct wiphy {
+       struct mutex                            mtx;
        struct device                           *dev;
        struct mac_address                      *addresses;
        int                                     n_addresses;
@@ -1185,6 +1225,9 @@ struct wiphy {
        uint8_t                                 priv[0] 
__aligned(CACHE_LINE_SIZE);
 };
 
+#define        lockdep_assert_wiphy(wiphy)                                     
\
+    lockdep_assert_held(&(wiphy)->mtx)
+
 struct wireless_dev {
                /* XXX TODO, like ic? */
        int             iftype;
@@ -1249,6 +1292,15 @@ struct cfg80211_ops {
 struct wiphy *linuxkpi_wiphy_new(const struct cfg80211_ops *, size_t);
 void linuxkpi_wiphy_free(struct wiphy *wiphy);
 
+void linuxkpi_wiphy_work_queue(struct wiphy *, struct wiphy_work *);
+void linuxkpi_wiphy_work_cancel(struct wiphy *, struct wiphy_work *);
+void linuxkpi_wiphy_work_flush(struct wiphy *, struct wiphy_work *);
+void lkpi_wiphy_delayed_work_timer(struct timer_list *);
+void linuxkpi_wiphy_delayed_work_queue(struct wiphy *,
+    struct wiphy_delayed_work *, unsigned long);
+void linuxkpi_wiphy_delayed_work_cancel(struct wiphy *,
+    struct wiphy_delayed_work *);
+
 int linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
     struct linuxkpi_ieee80211_regdomain *regd);
 uint32_t linuxkpi_ieee80211_channel_to_frequency(uint32_t, enum nl80211_band);
@@ -1300,16 +1352,8 @@ wiphy_dev(struct wiphy *wiphy)
        return (wiphy->dev);
 }
 
-#define        wiphy_err(_wiphy, _fmt, ...)                                    
\
-    dev_err((_wiphy)->dev, _fmt, __VA_ARGS__)
-
-static __inline const struct linuxkpi_ieee80211_regdomain *
-wiphy_dereference(struct wiphy *wiphy,
-    const struct linuxkpi_ieee80211_regdomain *regd)
-{
-       TODO();
-        return (NULL);
-}
+#define        wiphy_dereference(wiphy, p)                                     
\
+    rcu_dereference_check(p, lockdep_is_held(&(wiphy)->mtx))
 
 static __inline void
 wiphy_lock(struct wiphy *wiphy)
@@ -1661,6 +1705,12 @@ wiphy_ext_feature_set(struct wiphy *wiphy, enum 
nl80211_ext_feature ef)
        set_bit(ef, wiphy->ext_features);
 }
 
+static inline bool
+wiphy_ext_feature_isset(struct wiphy *wiphy, enum nl80211_ext_feature ef)
+{
+       return (test_bit(ef, wiphy->ext_features));
+}
+
 static __inline void *
 wiphy_net(struct wiphy *wiphy)
 {
@@ -1984,6 +2034,44 @@ cfg80211_chandef_valid(const struct cfg80211_chan_def 
*chandef)
        return (false);
 }
 
+static __inline bool
+cfg80211_chandef_dfs_usable(struct wiphy *wiphy, const struct 
cfg80211_chan_def *chandef)
+{
+       TODO();
+       return (false);
+}
+
+static __inline unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy, const struct 
cfg80211_chan_def *chandef)
+{
+       TODO();
+       return (0);
+}
+
+static inline void
+_ieee80211_set_sband_iftype_data(struct ieee80211_supported_band *band,
+    struct ieee80211_sband_iftype_data *iftype_data, size_t nitems)
+{
+       band->iftype_data = iftype_data;
+       band->n_iftype_data = nitems;
+}
+
+static inline const struct ieee80211_sband_iftype_data *
+ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *band,
+    enum nl80211_iftype iftype)
+{
+       const struct ieee80211_sband_iftype_data *iftype_data;
+       int i;
+
+       for (i = 0; i < band->n_iftype_data; i++) {
+               iftype_data = (const void *)&band->iftype_data[i];
+               if (iftype_data->types_mask & BIT(iftype))
+                       return (iftype_data);
+       }
+
+       return (NULL);
+}
+
 static __inline const struct ieee80211_sta_eht_cap *
 ieee80211_get_eht_iftype_cap(const struct ieee80211_supported_band *band,
     enum nl80211_iftype iftype)
@@ -1992,8 +2080,122 @@ ieee80211_get_eht_iftype_cap(const struct 
ieee80211_supported_band *band,
        return (NULL);
 }
 
+static inline bool
+cfg80211_ssid_eq(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
+{
+       int error;
+
+       if (ssid1 == NULL || ssid2 == NULL)     /* Can we KASSERT this? */
+               return (false);
+
+       if (ssid1->ssid_len != ssid2->ssid_len)
+               return (false);
+       error = memcmp(ssid1->ssid, ssid2->ssid, ssid2->ssid_len);
+       if (error != 0)
+               return (false);
+       return (true);
+}
+
+static inline void
+cfg80211_rx_unprot_mlme_mgmt(struct net_device *ndev, const uint8_t *hdr,
+    uint32_t len)
+{
+       TODO();
+}
+
+static inline const struct wiphy_iftype_ext_capab *
+cfg80211_get_iftype_ext_capa(struct wiphy *wiphy, enum nl80211_iftype iftype)
+{
+
+       TODO();
+       return (NULL);
+}
+
+static inline int
+nl80211_chan_width_to_mhz(enum nl80211_chan_width width)
+{
+       switch (width) {
+       case NL80211_CHAN_WIDTH_5:
+               return (5);
+               break;
+       case NL80211_CHAN_WIDTH_10:
+               return (10);
+               break;
+       case NL80211_CHAN_WIDTH_20_NOHT:
+       case NL80211_CHAN_WIDTH_20:
+               return (20);
+               break;
+       case NL80211_CHAN_WIDTH_40:
+               return (40);
+               break;
+       case NL80211_CHAN_WIDTH_80:
+       case NL80211_CHAN_WIDTH_80P80:
+               return (80);
+               break;
+       case NL80211_CHAN_WIDTH_160:
+               return (160);
+               break;
+       case NL80211_CHAN_WIDTH_320:
+               return (320);
+               break;
+       }
+}
+
+/* -------------------------------------------------------------------------- 
*/
+
+static inline void
+wiphy_work_init(struct wiphy_work *wwk, wiphy_work_fn fn)
+{
+       INIT_LIST_HEAD(&wwk->entry);
+       wwk->fn = fn;
+}
+
+static inline void
+wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+       linuxkpi_wiphy_work_queue(wiphy, wwk);
+}
+
+static inline void
+wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+       linuxkpi_wiphy_work_cancel(wiphy, wwk);
+}
+
+static inline void
+wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+       linuxkpi_wiphy_work_flush(wiphy, wwk);
+}
+
+static inline void
+wiphy_delayed_work_init(struct wiphy_delayed_work *wdwk, wiphy_work_fn fn)
+{
+       wiphy_work_init(&wdwk->work, fn);
+       timer_setup(&wdwk->timer, lkpi_wiphy_delayed_work_timer, 0);
+}
+
+static inline void
+wiphy_delayed_work_queue(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk,
+    unsigned long delay)
+{
+       linuxkpi_wiphy_delayed_work_queue(wiphy, wdwk, delay);
+}
+
+static inline void
+wiphy_delayed_work_cancel(struct wiphy *wiphy, struct wiphy_delayed_work *wdwk)
+{
+       linuxkpi_wiphy_delayed_work_cancel(wiphy, wdwk);
+}
+
+/* -------------------------------------------------------------------------- 
*/
+
+#define        wiphy_err(_wiphy, _fmt, ...)                                    
\
+    dev_err((_wiphy)->dev, _fmt, __VA_ARGS__)
 #define        wiphy_info(wiphy, fmt, ...)                                     
\
-       printf("%s:%d XXX TODO " fmt, __func__, __LINE__, __VA_ARGS__)
+    dev_info(&(wiphy)->dev, fmt, ##__VA_ARGS__)
+#define        wiphy_info_once(wiphy, fmt, ...)                                
\
+    dev_info_once(&(wiphy)->dev, fmt, ##__VA_ARGS__)
 
 #ifndef LINUXKPI_NET80211
 #define        ieee80211_channel               linuxkpi_ieee80211_channel
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h 
b/sys/compat/linuxkpi/common/include/net/mac80211.h
index c3b07b68090a..6dbf07c85bb8 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  * Copyright (c) 2020-2022 Bjoern A. Zeeb
  *
  * This software was developed by Björn Zeeb under sponsorship from
@@ -83,6 +83,7 @@ enum mcast_filter_flags {
        FIF_OTHER_BSS                   = BIT(4),
        FIF_PSPOLL                      = BIT(5),
        FIF_CONTROL                     = BIT(6),
+       FIF_MCAST_ACTION                = BIT(7),
 };
 
 enum ieee80211_bss_changed {
@@ -117,6 +118,9 @@ enum ieee80211_bss_changed {
        BSS_CHANGED_TWT                 = BIT(28),
        BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = BIT(30),
        BSS_CHANGED_EHT_PUNCTURING      = BIT(31),
+       BSS_CHANGED_MLD_VALID_LINKS     = BIT_ULL(32),
+       BSS_CHANGED_MLD_TTLM            = BIT_ULL(33),
+       BSS_CHANGED_TPE                 = BIT_ULL(34),
 };
 
 /* 802.11 Figure 9-256 Suite selector format. [OUI(3), SUITE TYPE(1)] */
@@ -167,13 +171,24 @@ enum ieee80211_bss_changed {
 #define        TKIP_PN_TO_IV16(_x)             ((uint16_t)(_x & 0xffff))
 #define        TKIP_PN_TO_IV32(_x)             ((uint32_t)((_x >> 16) & 
0xffffffff))
 
-struct ieee80211_sta;
+enum ieee80211_neg_ttlm_res {
+       NEG_TTLM_RES_ACCEPT,
+       NEG_TTLM_RES_REJECT,
+};
+
+#define        IEEE80211_TTLM_NUM_TIDS 8
+struct ieee80211_neg_ttlm {
+       uint16_t downlink[IEEE80211_TTLM_NUM_TIDS];
+       uint16_t uplink[IEEE80211_TTLM_NUM_TIDS];
+};
 
 /* 802.11-2020 9.4.2.55.3 A-MPDU Parameters field */
 #define        IEEE80211_HT_AMPDU_PARM_FACTOR          0x3
 #define        IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT   2
 #define        IEEE80211_HT_AMPDU_PARM_DENSITY         (0x7 << 
IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT)
 
+struct ieee80211_sta;
+
 struct ieee80211_ampdu_params {
        struct ieee80211_sta                    *sta;
        enum ieee80211_ampdu_mlme_action        action;
@@ -217,11 +232,13 @@ struct mac80211_fils_discovery {
 };
 
 struct ieee80211_chanctx_conf {
-       /* TODO FIXME */
-       int             rx_chains_dynamic, rx_chains_static;
-       bool                                    radar_enabled;
        struct cfg80211_chan_def                def;
        struct cfg80211_chan_def                min_def;
+       struct cfg80211_chan_def                ap;
+
+       uint8_t                                 rx_chains_dynamic;
+       uint8_t                                 rx_chains_static;
+       bool                                    radar_enabled;
 
        /* Must stay last. */
        uint8_t                                 drv_priv[0] 
__aligned(CACHE_LINE_SIZE);
@@ -240,12 +257,39 @@ struct ieee80211_ema_beacons {
        } bcn[0];
 };
 
+struct ieee80211_chanreq {
+       struct cfg80211_chan_def oper;
+};
+
 #define        WLAN_MEMBERSHIP_LEN                     (8)
 #define        WLAN_USER_POSITION_LEN                  (16)
 
+/*
+ * 802.11ac-2013, 8.4.2.164 VHT Transmit Power Envelope element
+ * 802.11-???? ?
+ */
+struct ieee80211_parsed_tpe_eirp {
+       int8_t                                  power[5];
+       uint8_t                                 count;
+       bool                                    valid;
+};
+struct ieee80211_parsed_tpe_psd {
+       int8_t                                  power[16];
+       uint8_t                                 count;
+       bool                                    valid;
+};
+struct ieee80211_parsed_tpe {
+       /* We see access to [0] so assume at least 2. */
+       struct ieee80211_parsed_tpe_eirp        max_local[2];
+       struct ieee80211_parsed_tpe_eirp        max_reg_client[2];
+       struct ieee80211_parsed_tpe_psd         psd_local[2];
+       struct ieee80211_parsed_tpe_psd         psd_reg_client[2];
+};
+
 struct ieee80211_bss_conf {
        /* TODO FIXME */
        struct ieee80211_vif                    *vif;
+       struct cfg80211_bss                     *bss;
        const uint8_t                           *bssid;
        uint8_t                                 addr[ETH_ALEN];
        uint8_t                                 link_id;
@@ -308,6 +352,7 @@ struct ieee80211_bss_conf {
        struct mac80211_fils_discovery          fils_discovery;
        struct ieee80211_chanctx_conf           *chanctx_conf;
        struct ieee80211_vif                    *mbssid_tx_vif;
+       struct ieee80211_parsed_tpe             tpe;
 
        int             ack_enabled, bssid_index, bssid_indicator, 
cqm_rssi_hyst, cqm_rssi_thold, ema_ap, frame_time_rts_th, ftm_responder;
        int             htc_trig_based_pkt_ext;
@@ -322,6 +367,7 @@ struct ieee80211_bss_conf {
 struct ieee80211_channel_switch {
        /* TODO FIXME */
        int             block_tx, count, delay, device_timestamp, timestamp;
+       uint8_t                                 link_id;
        struct cfg80211_chan_def                chandef;
 };
 
@@ -444,6 +490,10 @@ enum ieee80211_hw_flags {
        IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
        IEEE80211_HW_SUPPORTS_RC_TABLE,
        IEEE80211_HW_DETECTS_COLOR_COLLISION,
+       IEEE80211_HW_DISALLOW_PUNCTURING,
+       IEEE80211_HW_DISALLOW_PUNCTURING_5GHZ,
+       IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN,
+       IEEE80211_HW_HANDLES_QUIET_CSA,
 
        /* Keep last. */
        NUM_IEEE80211_HW_FLAGS
@@ -500,6 +550,7 @@ enum ieee802111_key_flag {
        IEEE80211_KEY_FLAG_GENERATE_IV_MGMT     = BIT(6),
        IEEE80211_KEY_FLAG_GENERATE_MMIE        = BIT(7),
        IEEE80211_KEY_FLAG_RESERVE_TAILROOM     = BIT(8),
+       IEEE80211_KEY_FLAG_SPP_AMSDU            = BIT(9),
 };
 
 struct ieee80211_key_conf {
@@ -569,6 +620,9 @@ enum ieee80211_rx_status_flags {
        RX_FLAG_SKIP_MONITOR            = BIT(26),
        RX_FLAG_8023                    = BIT(27),
        RX_FLAG_RADIOTAP_TLV_AT_END     = BIT(28),
+       RX_FLAG_MACTIME                 = BIT(29),
+       RX_FLAG_MACTIME_IS_RTAP_TS64    = BIT(30),
+       RX_FLAG_FAILED_PLCP_CRC         = BIT(31),
 };
 
 enum mac80211_rx_encoding {
@@ -742,7 +796,9 @@ enum ieee80211_vif_driver_flags {
        IEEE80211_VIF_BEACON_FILTER             = BIT(0),
        IEEE80211_VIF_SUPPORTS_CQM_RSSI         = BIT(1),
        IEEE80211_VIF_SUPPORTS_UAPSD            = BIT(2),
-       IEEE80211_VIF_DISABLE_SMPS_OVERRIDE     = BIT(3),
+       IEEE80211_VIF_DISABLE_SMPS_OVERRIDE     = BIT(3),       /* Renamed to 
IEEE80211_VIF_EML_ACTIVE. */
+       IEEE80211_VIF_EML_ACTIVE                = BIT(4),
+       IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW     = BIT(5),
 };
 
 #define        IEEE80211_BSS_ARP_ADDR_LIST_LEN         4
@@ -799,6 +855,8 @@ struct ieee80211_vif_chanctx_switch {
 struct ieee80211_prep_tx_info {
        u16                             duration;
        bool                            success;
+       bool                            was_assoc;
+       int                             link_id;
 };
 
 /* XXX-BZ too big, over-reduce size to u8, and array sizes to minuimum to fit 
in skb->cb. */
@@ -813,6 +871,7 @@ struct ieee80211_tx_info {
                struct {
                        struct ieee80211_tx_rate        rates[4];
                        bool                            use_rts;
+                       uint8_t                         antennas:2;
                        struct ieee80211_vif            *vif;
                        struct ieee80211_key_conf       *hw_key;
                        enum ieee80211_tx_control_flags flags;
@@ -1044,6 +1103,8 @@ struct ieee80211_ops {
 
        int (*change_vif_links)(struct ieee80211_hw *, struct ieee80211_vif *, 
u16, u16, struct ieee80211_bss_conf *[IEEE80211_MLD_MAX_NUM_LINKS]);
        int (*change_sta_links)(struct ieee80211_hw *, struct ieee80211_vif *, 
struct ieee80211_sta *, u16, u16);
+       bool (*can_activate_links)(struct ieee80211_hw *, struct ieee80211_vif 
*, u16);
+       enum ieee80211_neg_ttlm_res (*can_neg_ttlm)(struct ieee80211_hw *, 
struct ieee80211_vif *, struct ieee80211_neg_ttlm *);
 
 /* #ifdef CONFIG_MAC80211_DEBUGFS */   /* Do not change depending on 
compile-time option. */
        void (*sta_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *, 
struct ieee80211_sta *, struct dentry *);
@@ -2052,7 +2113,6 @@ ieee80211_queue_work(struct ieee80211_hw *hw, struct 
work_struct *w)
 static __inline void
 ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
-
        linuxkpi_ieee80211_tx_status(hw, skb);
 }
 
@@ -2060,14 +2120,14 @@ static __inline void
 ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        IMPROVE();
-       ieee80211_tx_status(hw, skb);
+       linuxkpi_ieee80211_tx_status(hw, skb);
 }
 
 static __inline void
 ieee80211_tx_status_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
        IMPROVE();
-       ieee80211_tx_status(hw, skb);
+       linuxkpi_ieee80211_tx_status(hw, skb);
 }
 
 static __inline void
@@ -2370,7 +2430,102 @@ ieee80211_get_eht_iftype_cap_vif(const struct 
ieee80211_supported_band *band,
        return (NULL);
 }
 
+static inline uint32_t
+ieee80211_vif_usable_links(const struct ieee80211_vif *vif)
+{
+       TODO();
+       return (1);
+}
+
+static inline bool
+ieee80211_vif_link_active(const struct ieee80211_vif *vif, uint8_t link_id)
+{
+       if (ieee80211_vif_is_mld(vif))
+               return (vif->active_links & BIT(link_id));
+       return (link_id == 0);
+}
+
+static inline void
+ieee80211_set_active_links_async(struct ieee80211_vif *vif,
+    uint32_t new_active_links)
+{
+       TODO();
+}
+
+static inline int
+ieee80211_set_active_links(struct ieee80211_vif *vif,
+    uint32_t active_links)
+{
+       TODO();
+       return (-ENXIO);
+}
+
+static inline void
+ieee80211_cqm_beacon_loss_notify(struct ieee80211_vif *vif, gfp_t gfp __unused)
+{
+       IMPROVE("we notify user space by a vap state change eventually");
+       linuxkpi_ieee80211_beacon_loss(vif);
+}
+
 #define        ieee80211_send_bar(_v, _r, _t, _s)                              
\
     linuxkpi_ieee80211_send_bar(_v, _r, _t, _s)
 
+/* -------------------------------------------------------------------------- 
*/
+
+int lkpi_80211_update_chandef(struct ieee80211_hw *,
+    struct ieee80211_chanctx_conf *);
+
+static inline int
+ieee80211_emulate_add_chanctx(struct ieee80211_hw *hw,
+    struct ieee80211_chanctx_conf *chanctx_conf)
+{
+       int error;
+
+       hw->conf.radar_enabled = chanctx_conf->radar_enabled;
+       error = lkpi_80211_update_chandef(hw, chanctx_conf);
+       return (error);
+}
+
+static inline void
+ieee80211_emulate_remove_chanctx(struct ieee80211_hw *hw,
+    struct ieee80211_chanctx_conf *chanctx_conf __unused)
+{
+       hw->conf.radar_enabled = false;
+       lkpi_80211_update_chandef(hw, NULL);
+}
+
+static inline void
+ieee80211_emulate_change_chanctx(struct ieee80211_hw *hw,
+    struct ieee80211_chanctx_conf *chanctx_conf, uint32_t changed __unused)
+{
+       hw->conf.radar_enabled = chanctx_conf->radar_enabled;
+       lkpi_80211_update_chandef(hw, chanctx_conf);
+}
+
+static inline int
+ieee80211_emulate_switch_vif_chanctx(struct ieee80211_hw *hw,
+    struct ieee80211_vif_chanctx_switch *vifs, int n_vifs,
+    enum ieee80211_chanctx_switch_mode mode __unused)
+{
+       struct ieee80211_chanctx_conf *chanctx_conf;
+       int error;
+
+       /* Sanity check. */
+       if (n_vifs <= 0)
+               return (-EINVAL);
+       if (vifs == NULL || vifs[0].new_ctx == NULL)
+               return (-EINVAL);
+
+       /*
+        * What to do if n_vifs > 1?
+        * Does that make sense for drivers not supporting chanctx?
+        */
+       hw->conf.radar_enabled = vifs[0].new_ctx->radar_enabled;
+       chanctx_conf = vifs[0].new_ctx;
+       error = lkpi_80211_update_chandef(hw, chanctx_conf);
+       return (error);
+}
+
+/* -------------------------------------------------------------------------- 
*/
+
 #endif /* _LINUXKPI_NET_MAC80211_H */
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c 
b/sys/compat/linuxkpi/common/src/linux_80211.c
index 4171f0789977..9e4c368617b6 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  * Copyright (c) 2020-2022 Bjoern A. Zeeb
  *
  * This software was developed by Björn Zeeb under sponsorship from
@@ -895,14 +895,14 @@ lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct 
ieee80211_node *ni,
        if (linuxkpi_debug_80211 & D80211_TRACE)
                printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
                    "dtim_period %u sync_dtim_count %u sync_tsf %ju "
-                   "sync_device_ts %u bss_changed %#08x\n",
+                   "sync_device_ts %u bss_changed %#010jx\n",
                        __func__, __LINE__, _f, _l,
                        vif->cfg.assoc, vif->cfg.aid,
                        vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
                        vif->bss_conf.sync_dtim_count,
                        (uintmax_t)vif->bss_conf.sync_tsf,
                        vif->bss_conf.sync_device_ts,
-                       bss_changed);
+                       (uintmax_t)bss_changed);
 #endif
 
        if (vif->bss_conf.beacon_int != ni->ni_intval) {
@@ -926,14 +926,14 @@ lkpi_update_dtim_tsf(struct ieee80211_vif *vif, struct 
ieee80211_node *ni,
        if (linuxkpi_debug_80211 & D80211_TRACE)
                printf("%s:%d [%s:%d] assoc %d aid %d beacon_int %u "
                    "dtim_period %u sync_dtim_count %u sync_tsf %ju "
-                   "sync_device_ts %u bss_changed %#08x\n",
+                   "sync_device_ts %u bss_changed %#010jx\n",
                        __func__, __LINE__, _f, _l,
                        vif->cfg.assoc, vif->cfg.aid,
                        vif->bss_conf.beacon_int, vif->bss_conf.dtim_period,
                        vif->bss_conf.sync_dtim_count,
                        (uintmax_t)vif->bss_conf.sync_tsf,
                        vif->bss_conf.sync_device_ts,
-                       bss_changed);
+                       (uintmax_t)bss_changed);
 #endif
 
        return (bss_changed);
@@ -1775,6 +1775,7 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum 
ieee80211_state nstate, i
            !lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.duration = PREP_TX_INFO_DURATION;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = true;
        }
@@ -1809,6 +1810,7 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum 
ieee80211_state nstate, i
        if (lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.success = false;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = false;
        }
@@ -2162,6 +2164,7 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
            !lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.duration = PREP_TX_INFO_DURATION;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = true;
        }
@@ -2196,6 +2199,7 @@ lkpi_sta_run_to_assoc(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
        if (lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.success = false;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = false;
        }
@@ -2300,6 +2304,7 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
            !lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.duration = PREP_TX_INFO_DURATION;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_prepare_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = true;
        }
@@ -2334,6 +2339,7 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum 
ieee80211_state nstate, int
        if (lsta->in_mgd) {
                memset(&prep_tx_info, 0, sizeof(prep_tx_info));
                prep_tx_info.success = false;
+               prep_tx_info.was_assoc = true;
                lkpi_80211_mo_mgd_complete_tx(hw, vif, &prep_tx_info);
                lsta->in_mgd = false;
        }
@@ -5331,18 +5337,158 @@ linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *hdr, 
bool nonqos_ok)
        return (tid);
 }
 
+/* -------------------------------------------------------------------------- 
*/
+
+static void
+lkpi_wiphy_work(struct work_struct *work)
+{
+       struct lkpi_wiphy *lwiphy;
+       struct wiphy *wiphy;
+       struct wiphy_work *wk;
+
+       lwiphy = container_of(work, struct lkpi_wiphy, wwk);
+       wiphy = LWIPHY_TO_WIPHY(lwiphy);
+
+       wiphy_lock(wiphy);
+
+       LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
+       wk = list_first_entry_or_null(&lwiphy->wwk_list, struct wiphy_work, 
entry);
+       /* If there is nothing we do nothing. */
+       if (wk == NULL) {
+               LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
+               wiphy_unlock(wiphy);
+               return;
+       }
+       list_del_init(&wk->entry);
+
+       /* More work to do? */
+       if (!list_empty(&lwiphy->wwk_list))
+               schedule_work(work);
+       LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
+
+       /* Finally call the (*wiphy_work_fn)() function. */
+       wk->fn(wiphy, wk);
+
+       wiphy_unlock(wiphy);
+}
+
+void
+linuxkpi_wiphy_work_queue(struct wiphy *wiphy, struct wiphy_work *wwk)
+{
+       struct lkpi_wiphy *lwiphy;
+
+       lwiphy = WIPHY_TO_LWIPHY(wiphy);
+
+       LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
+       /* Do not double-queue. */
+       if (list_empty(&wwk->entry))
*** 212 LINES SKIPPED ***

Reply via email to