mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
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 driver 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 (cherry picked from commit ac1d519c01ca8beb59f27962c7052d09a03f72c8)
This commit is contained in:
parent
8341284368
commit
d964b9d8ed
6 changed files with 635 additions and 53 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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_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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -896,14 +896,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) {
|
||||
|
|
@ -927,14 +927,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);
|
||||
|
|
@ -1776,6 +1776,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;
|
||||
}
|
||||
|
|
@ -1810,6 +1811,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;
|
||||
}
|
||||
|
|
@ -2163,6 +2165,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;
|
||||
}
|
||||
|
|
@ -2197,6 +2200,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;
|
||||
}
|
||||
|
|
@ -2301,6 +2305,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;
|
||||
}
|
||||
|
|
@ -2335,6 +2340,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;
|
||||
}
|
||||
|
|
@ -5332,18 +5338,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))
|
||||
list_add_tail(&wwk->entry, &lwiphy->wwk_list);
|
||||
LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
|
||||
|
||||
/*
|
||||
* See how ieee80211_queue_work() work continues in Linux or if things
|
||||
* migrate here over time?
|
||||
* Use a system queue from linux/workqueue.h for now.
|
||||
*/
|
||||
queue_work(system_wq, &lwiphy->wwk);
|
||||
}
|
||||
|
||||
void
|
||||
linuxkpi_wiphy_work_cancel(struct wiphy *wiphy, struct wiphy_work *wwk)
|
||||
{
|
||||
struct lkpi_wiphy *lwiphy;
|
||||
|
||||
lwiphy = WIPHY_TO_LWIPHY(wiphy);
|
||||
|
||||
LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
|
||||
/* Only cancel if queued. */
|
||||
if (!list_empty(&wwk->entry))
|
||||
list_del_init(&wwk->entry);
|
||||
LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
|
||||
}
|
||||
|
||||
void
|
||||
linuxkpi_wiphy_work_flush(struct wiphy *wiphy, struct wiphy_work *wwk)
|
||||
{
|
||||
struct lkpi_wiphy *lwiphy;
|
||||
struct wiphy_work *wk;
|
||||
|
||||
lwiphy = WIPHY_TO_LWIPHY(wiphy);
|
||||
LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
|
||||
/* If wwk is unset, flush everything; called when wiphy is shut down. */
|
||||
if (wwk != NULL && list_empty(&wwk->entry)) {
|
||||
LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
|
||||
return;
|
||||
}
|
||||
|
||||
while (!list_empty(&lwiphy->wwk_list)) {
|
||||
|
||||
wk = list_first_entry(&lwiphy->wwk_list, struct wiphy_work,
|
||||
entry);
|
||||
list_del_init(&wk->entry);
|
||||
LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
|
||||
wk->fn(wiphy, wk);
|
||||
LKPI_80211_LWIPHY_WORK_LOCK(lwiphy);
|
||||
if (wk == wwk)
|
||||
break;
|
||||
}
|
||||
LKPI_80211_LWIPHY_WORK_UNLOCK(lwiphy);
|
||||
}
|
||||
|
||||
void
|
||||
lkpi_wiphy_delayed_work_timer(struct timer_list *tl)
|
||||
{
|
||||
struct wiphy_delayed_work *wdwk;
|
||||
|
||||
wdwk = from_timer(wdwk, tl, timer);
|
||||
wiphy_work_queue(wdwk->wiphy, &wdwk->work);
|
||||
}
|
||||
|
||||
void
|
||||
linuxkpi_wiphy_delayed_work_queue(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *wdwk, unsigned long delay)
|
||||
{
|
||||
if (delay == 0) {
|
||||
/* Run right away. */
|
||||
del_timer(&wdwk->timer);
|
||||
wiphy_work_queue(wiphy, &wdwk->work);
|
||||
} else {
|
||||
wdwk->wiphy = wiphy;
|
||||
mod_timer(&wdwk->timer, jiffies + delay);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
linuxkpi_wiphy_delayed_work_cancel(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *wdwk)
|
||||
{
|
||||
del_timer_sync(&wdwk->timer);
|
||||
wiphy_work_cancel(wiphy, &wdwk->work);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
struct wiphy *
|
||||
linuxkpi_wiphy_new(const struct cfg80211_ops *ops, size_t priv_len)
|
||||
{
|
||||
struct lkpi_wiphy *lwiphy;
|
||||
struct wiphy *wiphy;
|
||||
|
||||
lwiphy = kzalloc(sizeof(*lwiphy) + priv_len, GFP_KERNEL);
|
||||
if (lwiphy == NULL)
|
||||
return (NULL);
|
||||
lwiphy->ops = ops;
|
||||
|
||||
/* XXX TODO */
|
||||
return (LWIPHY_TO_WIPHY(lwiphy));
|
||||
LKPI_80211_LWIPHY_WORK_LOCK_INIT(lwiphy);
|
||||
INIT_LIST_HEAD(&lwiphy->wwk_list);
|
||||
INIT_WORK(&lwiphy->wwk, lkpi_wiphy_work);
|
||||
|
||||
wiphy = LWIPHY_TO_WIPHY(lwiphy);
|
||||
|
||||
mutex_init(&wiphy->mtx);
|
||||
TODO();
|
||||
|
||||
return (wiphy);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -5354,7 +5500,12 @@ linuxkpi_wiphy_free(struct wiphy *wiphy)
|
|||
if (wiphy == NULL)
|
||||
return;
|
||||
|
||||
linuxkpi_wiphy_work_flush(wiphy, NULL);
|
||||
mutex_destroy(&wiphy->mtx);
|
||||
|
||||
lwiphy = WIPHY_TO_LWIPHY(wiphy);
|
||||
LKPI_80211_LWIPHY_WORK_LOCK_DESTROY(lwiphy);
|
||||
|
||||
kfree(lwiphy);
|
||||
}
|
||||
|
||||
|
|
@ -6291,6 +6442,43 @@ linuxkpi_cfg80211_bss_flush(struct wiphy *wiphy)
|
|||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* hw->conf get initialized/set in various places for us:
|
||||
* - linuxkpi_ieee80211_alloc_hw(): flags
|
||||
* - linuxkpi_ieee80211_ifattach(): chandef
|
||||
* - lkpi_ic_vap_create(): listen_interval
|
||||
* - lkpi_ic_set_channel(): chandef, flags
|
||||
*/
|
||||
|
||||
int lkpi_80211_update_chandef(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *new)
|
||||
{
|
||||
struct cfg80211_chan_def *cd;
|
||||
uint32_t changed;
|
||||
int error;
|
||||
|
||||
changed = 0;
|
||||
if (new == NULL || new->def.chan == NULL)
|
||||
cd = NULL;
|
||||
else
|
||||
cd = &new->def;
|
||||
|
||||
if (cd && cd->chan != hw->conf.chandef.chan) {
|
||||
/* Copy; the chan pointer is fine and will stay valid. */
|
||||
hw->conf.chandef = *cd;
|
||||
changed |= IEEE80211_CONF_CHANGE_CHANNEL;
|
||||
}
|
||||
IMPROVE("IEEE80211_CONF_CHANGE_PS, IEEE80211_CONF_CHANGE_POWER");
|
||||
|
||||
if (changed == 0)
|
||||
return (0);
|
||||
|
||||
error = lkpi_80211_mo_config(hw, changed);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
MODULE_VERSION(linuxkpi_wlan, 1);
|
||||
MODULE_DEPEND(linuxkpi_wlan, linuxkpi, 1, 1, 1);
|
||||
MODULE_DEPEND(linuxkpi_wlan, wlan, 1, 1, 1);
|
||||
|
|
|
|||
|
|
@ -205,7 +205,7 @@ struct lkpi_hw { /* name it mac80211_sc? */
|
|||
TAILQ_HEAD(, lkpi_vif) lvif_head;
|
||||
struct sx lvif_sx;
|
||||
|
||||
struct sx sx;
|
||||
struct sx sx; /* XXX-BZ Can this be wiphy->mtx in the future? */
|
||||
|
||||
struct mtx txq_mtx;
|
||||
uint32_t txq_generation[IEEE80211_NUM_ACS];
|
||||
|
|
@ -284,12 +284,29 @@ struct lkpi_chanctx {
|
|||
struct lkpi_wiphy {
|
||||
const struct cfg80211_ops *ops;
|
||||
|
||||
struct work_struct wwk;
|
||||
struct list_head wwk_list;
|
||||
struct mtx wwk_mtx;
|
||||
|
||||
/* Must be last! */
|
||||
struct wiphy wiphy __aligned(CACHE_LINE_SIZE);
|
||||
};
|
||||
#define WIPHY_TO_LWIPHY(_wiphy) container_of(_wiphy, struct lkpi_wiphy, wiphy)
|
||||
#define LWIPHY_TO_WIPHY(_lwiphy) (&(_lwiphy)->wiphy)
|
||||
|
||||
#define LKPI_80211_LWIPHY_WORK_LOCK_INIT(_lwiphy) \
|
||||
mtx_init(&(_lwiphy)->wwk_mtx, "lwiphy-work", NULL, MTX_DEF);
|
||||
#define LKPI_80211_LWIPHY_WORK_LOCK_DESTROY(_lwiphy) \
|
||||
mtx_destroy(&(_lwiphy)->wwk_mtx)
|
||||
#define LKPI_80211_LWIPHY_WORK_LOCK(_lwiphy) \
|
||||
mtx_lock(&(_lwiphy)->wwk_mtx)
|
||||
#define LKPI_80211_LWIPHY_WORK_UNLOCK(_lwiphy) \
|
||||
mtx_unlock(&(_lwiphy)->wwk_mtx)
|
||||
#define LKPI_80211_LWIPHY_WORK_LOCK_ASSERT(_lwiphy) \
|
||||
mtx_assert(&(_lwiphy)->wwk_mtx, MA_OWNED)
|
||||
#define LKPI_80211_LWIPHY_WORK_UNLOCK_ASSERT(_lwiphy) \
|
||||
mtx_assert(&(_lwiphy)->wwk_mtx, MA_NOTOWNED)
|
||||
|
||||
#define LKPI_80211_LHW_LOCK_INIT(_lhw) \
|
||||
sx_init_flags(&(_lhw)->sx, "lhw", SX_RECURSE);
|
||||
#define LKPI_80211_LHW_LOCK_DESTROY(_lhw) \
|
||||
|
|
|
|||
Loading…
Reference in a new issue