Many changes all over:
* HE (802.11ax) work continues * WPA3 offloads * work on extended key ID handling continues * fixes to honour AP supported rates with auth/assoc frames * nl80211 netlink policy improvements to fix some issues with strict validation on new commands with old attrs -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEH1e1rEeCd0AIMq6MB8qZga/fl8QFAl0Dq/sACgkQB8qZga/f l8RqFg/+MBcuqvW2xTy5o5Lbw7Drx5ROgFT2ZRAO6PTeboQ43NOBiXt2dEhDbp+w mHChImF85px3SFMBSvuf97zlScNV6+VJraDDjoZFixt/gIZ/XsdURo5i4IGmUbfj +LY1oPm7suC5Cold+yPicHTukFpeU7cSwceslFsecqiN5unlzIxf6gY9H7OL7WGT s0Wis0x3y2m9mMi4cvQfHkFzplcTc5SBgPLyLQtHUNx1eySEZ+AymlNVmbGrRWr9 vaCU5W9+Wz0N6lEB/UI5y6fZzj5mhkcimGck1Os7dFeC7KWjntjT9iKIkFHWehxi QfLcK6pGjLpPpMTQtOEfl34ZGnOyO8N9GmOLaaUaBeaZItabYJwfgbdr7NxiJvta 1cyqXek+D2G7WOa0aIrWhmwswKGBa3nIBqS/ZP/SEWLEzU1Cn0NiAD5Ba016TC4C D+1BBXIdpQDoZCgfd6KkGs2Ynf/8N3OwHW+EwjpAu3IARTQzb6tMWSvkAuAgJt1F dBD7NqdFhWXFfxqf9NpB8bkmpyNKM4Km6eO2HKpCg/5suKqYJ1Xj9EeQin1B+QsE Jntj69hQ6Kj2gKBPy+RnCBFbxMNuFhpc1kmUOGj9U9aAcOntV0woVOyFGsbRmFo3 MI8aVU/gjQDCcHHD5xtJGHa11uIefXq1r2H7Um3sxKYeBsqFjP4= =j+Um -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-davem-2019-06-14' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== Many changes all over: * HE (802.11ax) work continues * WPA3 offloads * work on extended key ID handling continues * fixes to honour AP supported rates with auth/assoc frames * nl80211 netlink policy improvements to fix some issues with strict validation on new commands with old attrs ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
d96ec97511
|
@ -226,9 +226,6 @@ TBD
|
|||
.. kernel-doc:: include/net/mac80211.h
|
||||
:functions: ieee80211_tx_rate_control
|
||||
|
||||
.. kernel-doc:: include/net/mac80211.h
|
||||
:functions: rate_control_send_low
|
||||
|
||||
TBD
|
||||
|
||||
This part of the book describes mac80211 internals.
|
||||
|
|
|
@ -646,9 +646,6 @@ il3945_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
|
|||
il_sta = NULL;
|
||||
}
|
||||
|
||||
if (rate_control_send_low(sta, il_sta, txrc))
|
||||
return;
|
||||
|
||||
rate_mask = sta->supp_rates[sband->band];
|
||||
|
||||
/* get user max rate if set */
|
||||
|
|
|
@ -2224,10 +2224,6 @@ il4965_rs_get_rate(void *il_r, struct ieee80211_sta *sta, void *il_sta,
|
|||
il_sta = NULL;
|
||||
}
|
||||
|
||||
/* Send management frames and NO_ACK data using lowest rate. */
|
||||
if (rate_control_send_low(sta, il_sta, txrc))
|
||||
return;
|
||||
|
||||
if (!lq_sta)
|
||||
return;
|
||||
|
||||
|
|
|
@ -2731,10 +2731,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
|
|||
priv_sta = NULL;
|
||||
}
|
||||
|
||||
/* Send management frames and NO_ACK data using lowest rate. */
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
rate_idx = lq_sta->last_txrate_idx;
|
||||
|
||||
if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
|
|
|
@ -2960,10 +2960,6 @@ static void rs_drv_get_rate(void *mvm_r, struct ieee80211_sta *sta,
|
|||
mvm_sta = NULL;
|
||||
}
|
||||
|
||||
/* Send management frames and NO_ACK data using lowest rate. */
|
||||
if (rate_control_send_low(sta, mvm_sta, txrc))
|
||||
return;
|
||||
|
||||
if (!mvm_sta)
|
||||
return;
|
||||
|
||||
|
|
|
@ -457,6 +457,8 @@ static struct wiphy_vendor_command mac80211_hwsim_vendor_commands[] = {
|
|||
.subcmd = QCA_NL80211_SUBCMD_TEST },
|
||||
.flags = WIPHY_VENDOR_CMD_NEED_NETDEV,
|
||||
.doit = mac80211_hwsim_vendor_cmd_test,
|
||||
.policy = hwsim_vendor_test_policy,
|
||||
.maxattr = QCA_WLAN_VENDOR_ATTR_MAX,
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -173,9 +173,6 @@ static void rtl_get_rate(void *ppriv, struct ieee80211_sta *sta,
|
|||
u8 try_per_rate, i, rix;
|
||||
bool not_data = !ieee80211_is_data(fc);
|
||||
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
rix = _rtl_rc_get_highest_rix(rtlpriv, sta, skb, not_data);
|
||||
try_per_rate = 1;
|
||||
_rtl_rc_rate_set_series(rtlpriv, sta, &rates[0], txrc,
|
||||
|
|
|
@ -2612,6 +2612,7 @@ enum ieee80211_key_len {
|
|||
#define FILS_ERP_MAX_RRK_LEN 64
|
||||
|
||||
#define PMK_MAX_LEN 64
|
||||
#define SAE_PASSWORD_MAX_LEN 128
|
||||
|
||||
/* Public action codes (IEEE Std 802.11-2016, 9.6.8.1, Table 9-307) */
|
||||
enum ieee80211_pub_actioncode {
|
||||
|
@ -2712,6 +2713,13 @@ enum ieee80211_tdls_actioncode {
|
|||
#define WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT BIT(5)
|
||||
#define WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT BIT(6)
|
||||
|
||||
/*
|
||||
* When set, indicates that the AP is able to tolerate 26-tone RU UL
|
||||
* OFDMA transmissions using HE TB PPDU from OBSS (not falsely classify the
|
||||
* 26-tone RU UL OFDMA transmissions as radar pulses).
|
||||
*/
|
||||
#define WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT BIT(7)
|
||||
|
||||
/* Defines support for enhanced multi-bssid advertisement*/
|
||||
#define WLAN_EXT_CAPA11_EMA_SUPPORT BIT(1)
|
||||
|
||||
|
|
|
@ -381,6 +381,26 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_get_he_iftype_cap - return HE capabilities for an sband's iftype
|
||||
* @sband: the sband to search for the iftype on
|
||||
* @iftype: enum nl80211_iftype
|
||||
*
|
||||
* Return: pointer to the struct ieee80211_sta_he_cap, or NULL is none found
|
||||
*/
|
||||
static inline const struct ieee80211_sta_he_cap *
|
||||
ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *sband,
|
||||
u8 iftype)
|
||||
{
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
ieee80211_get_sband_iftype_data(sband, iftype);
|
||||
|
||||
if (data && data->he_cap.has_he)
|
||||
return &data->he_cap;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_get_he_sta_cap - return HE capabilities for an sband's STA
|
||||
* @sband: the sband to search for the STA on
|
||||
|
@ -390,13 +410,7 @@ ieee80211_get_sband_iftype_data(const struct ieee80211_supported_band *sband,
|
|||
static inline const struct ieee80211_sta_he_cap *
|
||||
ieee80211_get_he_sta_cap(const struct ieee80211_supported_band *sband)
|
||||
{
|
||||
const struct ieee80211_sband_iftype_data *data =
|
||||
ieee80211_get_sband_iftype_data(sband, NL80211_IFTYPE_STATION);
|
||||
|
||||
if (data && data->he_cap.has_he)
|
||||
return &data->he_cap;
|
||||
|
||||
return NULL;
|
||||
return ieee80211_get_he_iftype_cap(sband, NL80211_IFTYPE_STATION);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -742,6 +756,9 @@ struct survey_info {
|
|||
* CFG80211_MAX_WEP_KEYS WEP keys
|
||||
* @wep_tx_key: key index (0..3) of the default TX static WEP key
|
||||
* @psk: PSK (for devices supporting 4-way-handshake offload)
|
||||
* @sae_pwd: password for SAE authentication (for devices supporting SAE
|
||||
* offload)
|
||||
* @sae_pwd_len: length of SAE password (for devices supporting SAE offload)
|
||||
*/
|
||||
struct cfg80211_crypto_settings {
|
||||
u32 wpa_versions;
|
||||
|
@ -757,6 +774,8 @@ struct cfg80211_crypto_settings {
|
|||
struct key_params *wep_keys;
|
||||
int wep_tx_key;
|
||||
const u8 *psk;
|
||||
const u8 *sae_pwd;
|
||||
u8 sae_pwd_len;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -878,6 +897,7 @@ enum cfg80211_ap_settings_flags {
|
|||
* @he_cap: HE capabilities (or %NULL if HE isn't enabled)
|
||||
* @ht_required: stations must support HT
|
||||
* @vht_required: stations must support VHT
|
||||
* @twt_responder: Enable Target Wait Time
|
||||
* @flags: flags, as defined in enum cfg80211_ap_settings_flags
|
||||
*/
|
||||
struct cfg80211_ap_settings {
|
||||
|
@ -904,6 +924,7 @@ struct cfg80211_ap_settings {
|
|||
const struct ieee80211_vht_cap *vht_cap;
|
||||
const struct ieee80211_he_cap_elem *he_cap;
|
||||
bool ht_required, vht_required;
|
||||
bool twt_responder;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
|
@ -4151,6 +4172,8 @@ struct sta_opmode_info {
|
|||
u8 rx_nss;
|
||||
};
|
||||
|
||||
#define VENDOR_CMD_RAW_DATA ((const struct nla_policy *)ERR_PTR(-ENODATA))
|
||||
|
||||
/**
|
||||
* struct wiphy_vendor_command - vendor command definition
|
||||
* @info: vendor command identifying information, as used in nl80211
|
||||
|
@ -4161,6 +4184,10 @@ struct sta_opmode_info {
|
|||
* @dumpit: dump callback, for transferring bigger/multiple items. The
|
||||
* @storage points to cb->args[5], ie. is preserved over the multiple
|
||||
* dumpit calls.
|
||||
* @policy: policy pointer for attributes within %NL80211_ATTR_VENDOR_DATA.
|
||||
* Set this to %VENDOR_CMD_RAW_DATA if no policy can be given and the
|
||||
* attribute is just raw data (e.g. a firmware command).
|
||||
* @maxattr: highest attribute number in policy
|
||||
* It's recommended to not have the same sub command with both @doit and
|
||||
* @dumpit, so that userspace can assume certain ones are get and others
|
||||
* are used with dump requests.
|
||||
|
@ -4173,6 +4200,8 @@ struct wiphy_vendor_command {
|
|||
int (*dumpit)(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
struct sk_buff *skb, const void *data, int data_len,
|
||||
unsigned long *storage);
|
||||
const struct nla_policy *policy;
|
||||
unsigned int maxattr;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5721,6 +5750,26 @@ void cfg80211_put_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
|
|||
*/
|
||||
void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss);
|
||||
|
||||
/**
|
||||
* cfg80211_bss_iter - iterate all BSS entries
|
||||
*
|
||||
* This function iterates over the BSS entries associated with the given wiphy
|
||||
* and calls the callback for the iterated BSS. The iterator function is not
|
||||
* allowed to call functions that might modify the internal state of the BSS DB.
|
||||
*
|
||||
* @wiphy: the wiphy
|
||||
* @chandef: if given, the iterator function will be called only if the channel
|
||||
* of the currently iterated BSS is a subset of the given channel.
|
||||
* @iter: the iterator function to call
|
||||
* @iter_data: an argument to the iterator function
|
||||
*/
|
||||
void cfg80211_bss_iter(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
void (*iter)(struct wiphy *wiphy,
|
||||
struct cfg80211_bss *bss,
|
||||
void *data),
|
||||
void *iter_data);
|
||||
|
||||
static inline enum nl80211_bss_scan_width
|
||||
cfg80211_chandef_to_scan_width(const struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
|
@ -6231,8 +6280,11 @@ struct cfg80211_fils_resp_params {
|
|||
* case.
|
||||
* @bssid: The BSSID of the AP (may be %NULL)
|
||||
* @bss: Entry of bss to which STA got connected to, can be obtained through
|
||||
* cfg80211_get_bss() (may be %NULL). Only one parameter among @bssid and
|
||||
* @bss needs to be specified.
|
||||
* cfg80211_get_bss() (may be %NULL). But it is recommended to store the
|
||||
* bss from the connect_request and hold a reference to it and return
|
||||
* through this param to avoid a warning if the bss is expired during the
|
||||
* connection, esp. for those drivers implementing connect op.
|
||||
* Only one parameter among @bssid and @bss needs to be specified.
|
||||
* @req_ie: Association request IEs (may be %NULL)
|
||||
* @req_ie_len: Association request IEs length
|
||||
* @resp_ie: Association response IEs (may be %NULL)
|
||||
|
@ -6280,8 +6332,12 @@ void cfg80211_connect_done(struct net_device *dev,
|
|||
*
|
||||
* @dev: network device
|
||||
* @bssid: the BSSID of the AP
|
||||
* @bss: entry of bss to which STA got connected to, can be obtained
|
||||
* through cfg80211_get_bss (may be %NULL)
|
||||
* @bss: Entry of bss to which STA got connected to, can be obtained through
|
||||
* cfg80211_get_bss() (may be %NULL). But it is recommended to store the
|
||||
* bss from the connect_request and hold a reference to it and return
|
||||
* through this param to avoid a warning if the bss is expired during the
|
||||
* connection, esp. for those drivers implementing connect op.
|
||||
* Only one parameter among @bssid and @bss needs to be specified.
|
||||
* @req_ie: association request IEs (maybe be %NULL)
|
||||
* @req_ie_len: association request IEs length
|
||||
* @resp_ie: association response IEs (may be %NULL)
|
||||
|
@ -6491,6 +6547,16 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
|
|||
struct ieee80211_channel *chan,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_tx_mgmt_expired - tx_mgmt duration expired
|
||||
* @wdev: wireless device
|
||||
* @cookie: the requested cookie
|
||||
* @chan: The current channel (from tx_mgmt request)
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_sinfo_alloc_tid_stats - allocate per-tid statistics.
|
||||
*
|
||||
|
|
|
@ -317,6 +317,7 @@ struct ieee80211_vif_chanctx_switch {
|
|||
* @BSS_CHANGED_MCAST_RATE: Multicast Rate setting changed for this interface
|
||||
* @BSS_CHANGED_FTM_RESPONDER: fime timing reasurement request responder
|
||||
* functionality changed for this BSS (AP mode).
|
||||
* @BSS_CHANGED_TWT: TWT status changed
|
||||
*
|
||||
*/
|
||||
enum ieee80211_bss_change {
|
||||
|
@ -347,6 +348,7 @@ enum ieee80211_bss_change {
|
|||
BSS_CHANGED_KEEP_ALIVE = 1<<24,
|
||||
BSS_CHANGED_MCAST_RATE = 1<<25,
|
||||
BSS_CHANGED_FTM_RESPONDER = 1<<26,
|
||||
BSS_CHANGED_TWT = 1<<27,
|
||||
|
||||
/* when adding here, make sure to change ieee80211_reconfig */
|
||||
};
|
||||
|
@ -504,6 +506,8 @@ struct ieee80211_ftm_responder_params {
|
|||
* @he_support: does this BSS support HE
|
||||
* @twt_requester: does this BSS support TWT requester (relevant for managed
|
||||
* mode only, set if the AP advertises TWT responder role)
|
||||
* @twt_responder: does this BSS support TWT requester (relevant for managed
|
||||
* mode only, set if the AP advertises TWT responder role)
|
||||
* @assoc: association status
|
||||
* @ibss_joined: indicates whether this station is part of an IBSS
|
||||
* or not
|
||||
|
@ -611,6 +615,7 @@ struct ieee80211_bss_conf {
|
|||
u16 frame_time_rts_th;
|
||||
bool he_support;
|
||||
bool twt_requester;
|
||||
bool twt_responder;
|
||||
/* association related data */
|
||||
bool assoc, ibss_joined;
|
||||
bool ibss_creator;
|
||||
|
@ -2269,6 +2274,9 @@ struct ieee80211_txq {
|
|||
* @IEEE80211_HW_EXT_KEY_ID_NATIVE: Driver and hardware are supporting Extended
|
||||
* Key ID and can handle two unicast keys per station for Rx and Tx.
|
||||
*
|
||||
* @IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT: The card/driver can't handle
|
||||
* active Tx A-MPDU sessions with Extended Key IDs during rekey.
|
||||
*
|
||||
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
|
||||
*/
|
||||
enum ieee80211_hw_flags {
|
||||
|
@ -2321,6 +2329,7 @@ enum ieee80211_hw_flags {
|
|||
IEEE80211_HW_SUPPORTS_MULTI_BSSID,
|
||||
IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
|
||||
IEEE80211_HW_EXT_KEY_ID_NATIVE,
|
||||
IEEE80211_HW_NO_AMPDU_KEYBORDER_SUPPORT,
|
||||
|
||||
/* keep last, obviously */
|
||||
NUM_IEEE80211_HW_FLAGS
|
||||
|
@ -5951,29 +5960,6 @@ static inline int rate_supported(struct ieee80211_sta *sta,
|
|||
return (sta == NULL || sta->supp_rates[band] & BIT(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* rate_control_send_low - helper for drivers for management/no-ack frames
|
||||
*
|
||||
* Rate control algorithms that agree to use the lowest rate to
|
||||
* send management frames and NO_ACK data with the respective hw
|
||||
* retries should use this in the beginning of their mac80211 get_rate
|
||||
* callback. If true is returned the rate control can simply return.
|
||||
* If false is returned we guarantee that sta and sta and priv_sta is
|
||||
* not null.
|
||||
*
|
||||
* Rate control algorithms wishing to do more intelligent selection of
|
||||
* rate for multicast/broadcast frames may choose to not use this.
|
||||
*
|
||||
* @sta: &struct ieee80211_sta pointer to the target destination. Note
|
||||
* that this may be null.
|
||||
* @priv_sta: private rate control structure. This may be null.
|
||||
* @txrc: rate control information we sholud populate for mac80211.
|
||||
*/
|
||||
bool rate_control_send_low(struct ieee80211_sta *sta,
|
||||
void *priv_sta,
|
||||
struct ieee80211_tx_rate_control *txrc);
|
||||
|
||||
|
||||
static inline s8
|
||||
rate_lowest_index(struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta)
|
||||
|
|
|
@ -1754,6 +1754,15 @@ static inline int __nla_validate_nested(const struct nlattr *start, int maxtype,
|
|||
validate, extack);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nl80211_validate_nested(const struct nlattr *start, int maxtype,
|
||||
const struct nla_policy *policy,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
return __nla_validate_nested(start, maxtype, policy,
|
||||
NL_VALIDATE_STRICT, extack);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nla_validate_nested_deprecated(const struct nlattr *start, int maxtype,
|
||||
const struct nla_policy *policy,
|
||||
|
|
|
@ -234,6 +234,15 @@
|
|||
* use in a FILS shared key connection with PMKSA caching.
|
||||
*/
|
||||
|
||||
/**
|
||||
* DOC: SAE authentication offload
|
||||
*
|
||||
* By setting @NL80211_EXT_FEATURE_SAE_OFFLOAD flag drivers can indicate they
|
||||
* support offloading SAE authentication for WPA3-Personal networks. In
|
||||
* %NL80211_CMD_CONNECT the password for SAE should be specified using
|
||||
* %NL80211_ATTR_SAE_PASSWORD.
|
||||
*/
|
||||
|
||||
/**
|
||||
* enum nl80211_commands - supported nl80211 commands
|
||||
*
|
||||
|
@ -2341,6 +2350,12 @@ enum nl80211_commands {
|
|||
* should be picking up the lowest tx power, either tx power per-interface
|
||||
* or per-station.
|
||||
*
|
||||
* @NL80211_ATTR_SAE_PASSWORD: attribute for passing SAE password material. It
|
||||
* is used with %NL80211_CMD_CONNECT to provide password for offloading
|
||||
* SAE authentication for WPA3-Personal networks.
|
||||
*
|
||||
* @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support.
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
|
@ -2794,6 +2809,10 @@ enum nl80211_attrs {
|
|||
NL80211_ATTR_STA_TX_POWER_SETTING,
|
||||
NL80211_ATTR_STA_TX_POWER,
|
||||
|
||||
NL80211_ATTR_SAE_PASSWORD,
|
||||
|
||||
NL80211_ATTR_TWT_RESPONDER,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
|
@ -4406,6 +4425,7 @@ enum nl80211_mfp {
|
|||
enum nl80211_wpa_versions {
|
||||
NL80211_WPA_VERSION_1 = 1 << 0,
|
||||
NL80211_WPA_VERSION_2 = 1 << 1,
|
||||
NL80211_WPA_VERSION_3 = 1 << 2,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -5422,6 +5442,9 @@ enum nl80211_feature_flags {
|
|||
* @NL80211_EXT_FEATURE_STA_TX_PWR: This driver supports controlling tx power
|
||||
* to a station.
|
||||
*
|
||||
* @NL80211_EXT_FEATURE_SAE_OFFLOAD: Device wants to do SAE authentication in
|
||||
* station mode (SAE password is passed as part of the connect command).
|
||||
*
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
|
@ -5466,6 +5489,7 @@ enum nl80211_ext_feature_index {
|
|||
NL80211_EXT_FEATURE_SCHED_SCAN_BAND_SPECIFIC_RSSI_THOLD,
|
||||
NL80211_EXT_FEATURE_EXT_KEY_ID,
|
||||
NL80211_EXT_FEATURE_STA_TX_PWR,
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018-2019 Intel Corporation
|
||||
*
|
||||
* This file is GPLv2 as found in COPYING.
|
||||
*/
|
||||
|
@ -975,7 +975,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_SSID |
|
||||
BSS_CHANGED_P2P_PS |
|
||||
BSS_CHANGED_TXPOWER;
|
||||
BSS_CHANGED_TXPOWER |
|
||||
BSS_CHANGED_TWT;
|
||||
int err;
|
||||
int prev_beacon_int;
|
||||
|
||||
|
@ -1045,6 +1046,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
|||
sdata->vif.bss_conf.dtim_period = params->dtim_period;
|
||||
sdata->vif.bss_conf.enable_beacon = true;
|
||||
sdata->vif.bss_conf.allow_p2p_go_ps = sdata->vif.p2p;
|
||||
sdata->vif.bss_conf.twt_responder = params->twt_responder;
|
||||
|
||||
sdata->vif.bss_conf.ssid_len = params->ssid_len;
|
||||
if (params->ssid_len)
|
||||
|
@ -1466,7 +1468,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (params->supported_rates) {
|
||||
if (params->supported_rates && params->supported_rates_len) {
|
||||
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
||||
sband, params->supported_rates,
|
||||
params->supported_rates_len,
|
||||
|
|
|
@ -274,6 +274,7 @@ static const char *hw_flag_names[] = {
|
|||
FLAG(SUPPORTS_MULTI_BSSID),
|
||||
FLAG(SUPPORTS_ONLY_HE_MULTI_BSSID),
|
||||
FLAG(EXT_KEY_ID_NATIVE),
|
||||
FLAG(NO_AMPDU_KEYBORDER_SUPPORT),
|
||||
#undef FLAG
|
||||
};
|
||||
|
||||
|
|
|
@ -342,9 +342,6 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
|
|||
key->debugfs.dir = debugfs_create_dir(buf,
|
||||
key->local->debugfs.keys);
|
||||
|
||||
if (!key->debugfs.dir)
|
||||
return;
|
||||
|
||||
sta = key->sta;
|
||||
if (sta) {
|
||||
sprintf(buf, "../../netdev:%s/stations/%pM",
|
||||
|
|
|
@ -818,9 +818,8 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata)
|
|||
sprintf(buf, "netdev:%s", sdata->name);
|
||||
sdata->vif.debugfs_dir = debugfs_create_dir(buf,
|
||||
sdata->local->hw.wiphy->debugfsdir);
|
||||
if (sdata->vif.debugfs_dir)
|
||||
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
|
||||
sdata->vif.debugfs_dir);
|
||||
sdata->debugfs.subdir_stations = debugfs_create_dir("stations",
|
||||
sdata->vif.debugfs_dir);
|
||||
add_files(sdata);
|
||||
}
|
||||
|
||||
|
@ -845,8 +844,5 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata)
|
|||
return;
|
||||
|
||||
sprintf(buf, "netdev:%s", sdata->name);
|
||||
if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
|
||||
sdata_err(sdata,
|
||||
"debugfs: failed to rename debugfs dir to %s\n",
|
||||
buf);
|
||||
debugfs_rename(dir->d_parent, dir, dir->d_parent, buf);
|
||||
}
|
||||
|
|
|
@ -960,8 +960,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
|
|||
* dir might still be around.
|
||||
*/
|
||||
sta->debugfs_dir = debugfs_create_dir(mac, stations_dir);
|
||||
if (!sta->debugfs_dir)
|
||||
return;
|
||||
|
||||
DEBUGFS_ADD(flags);
|
||||
DEBUGFS_ADD(aid);
|
||||
|
|
|
@ -274,50 +274,61 @@ int ieee80211_set_tx_key(struct ieee80211_key *key)
|
|||
|
||||
old = key_mtx_dereference(local, sta->ptk[sta->ptk_idx]);
|
||||
sta->ptk_idx = key->conf.keyidx;
|
||||
|
||||
if (ieee80211_hw_check(&local->hw, NO_AMPDU_KEYBORDER_SUPPORT))
|
||||
clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
ieee80211_check_fast_xmit(sta);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
|
||||
struct ieee80211_key *new_key,
|
||||
bool pairwise)
|
||||
static void ieee80211_pairwise_rekey(struct ieee80211_key *old,
|
||||
struct ieee80211_key *new)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_local *local;
|
||||
struct sta_info *sta;
|
||||
int ret;
|
||||
struct ieee80211_local *local = new->local;
|
||||
struct sta_info *sta = new->sta;
|
||||
int i;
|
||||
|
||||
/* Aggregation sessions are OK when running on SW crypto.
|
||||
* A broken remote STA may cause issues not observed with HW
|
||||
* crypto, though.
|
||||
*/
|
||||
if (!(old_key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
return 0;
|
||||
assert_key_lock(local);
|
||||
|
||||
assert_key_lock(old_key->local);
|
||||
sta = old_key->sta;
|
||||
if (new->conf.flags & IEEE80211_KEY_FLAG_NO_AUTO_TX) {
|
||||
/* Extended Key ID key install, initial one or rekey */
|
||||
|
||||
/* Unicast rekey without Extended Key ID needs special handling */
|
||||
if (new_key && sta && pairwise &&
|
||||
rcu_access_pointer(sta->ptk[sta->ptk_idx]) == old_key) {
|
||||
local = old_key->local;
|
||||
sdata = old_key->sdata;
|
||||
|
||||
/* Stop TX till we are on the new key */
|
||||
old_key->flags |= KEY_FLAG_TAINTED;
|
||||
ieee80211_clear_fast_xmit(sta);
|
||||
|
||||
/* Aggregation sessions during rekey are complicated due to the
|
||||
* reorder buffer and retransmits. Side step that by blocking
|
||||
* aggregation during rekey and tear down running sessions.
|
||||
if (sta->ptk_idx != INVALID_PTK_KEYIDX &&
|
||||
ieee80211_hw_check(&local->hw,
|
||||
NO_AMPDU_KEYBORDER_SUPPORT)) {
|
||||
/* Aggregation Sessions with Extended Key ID must not
|
||||
* mix MPDUs with different keyIDs within one A-MPDU.
|
||||
* Tear down any running Tx aggregation and all new
|
||||
* Rx/Tx aggregation request during rekey if the driver
|
||||
* asks us to do so. (Blocking Tx only would be
|
||||
* sufficient but WLAN_STA_BLOCK_BA gets the job done
|
||||
* for the few ms we need it.)
|
||||
*/
|
||||
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
mutex_lock(&sta->ampdu_mlme.mtx);
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||
___ieee80211_stop_tx_ba_session(sta, i,
|
||||
AGG_STOP_LOCAL_REQUEST);
|
||||
mutex_unlock(&sta->ampdu_mlme.mtx);
|
||||
}
|
||||
} else if (old) {
|
||||
/* Rekey without Extended Key ID.
|
||||
* Aggregation sessions are OK when running on SW crypto.
|
||||
* A broken remote STA may cause issues not observed with HW
|
||||
* crypto, though.
|
||||
*/
|
||||
if (!(old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
return;
|
||||
|
||||
/* Stop Tx till we are on the new key */
|
||||
old->flags |= KEY_FLAG_TAINTED;
|
||||
ieee80211_clear_fast_xmit(sta);
|
||||
if (ieee80211_hw_check(&local->hw, AMPDU_AGGREGATION)) {
|
||||
set_sta_flag(sta, WLAN_STA_BLOCK_BA);
|
||||
ieee80211_sta_tear_down_BA_sessions(sta,
|
||||
AGG_STOP_LOCAL_REQUEST);
|
||||
}
|
||||
|
||||
if (!wiphy_ext_feature_isset(local->hw.wiphy,
|
||||
NL80211_EXT_FEATURE_CAN_REPLACE_PTK0)) {
|
||||
pr_warn_ratelimited("Rekeying PTK for STA %pM but driver can't safely do that.",
|
||||
|
@ -325,18 +336,9 @@ static int ieee80211_hw_key_replace(struct ieee80211_key *old_key,
|
|||
/* Flushing the driver queues *may* help prevent
|
||||
* the clear text leaks and freezes.
|
||||
*/
|
||||
ieee80211_flush_queues(local, sdata, false);
|
||||
ieee80211_flush_queues(local, old->sdata, false);
|
||||
}
|
||||
}
|
||||
|
||||
ieee80211_key_disable_hw_accel(old_key);
|
||||
|
||||
if (new_key)
|
||||
ret = ieee80211_key_enable_hw_accel(new_key);
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata,
|
||||
|
@ -394,7 +396,6 @@ void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata,
|
|||
mutex_unlock(&sdata->local->key_mtx);
|
||||
}
|
||||
|
||||
|
||||
static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
bool pairwise,
|
||||
|
@ -402,7 +403,7 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_key *new)
|
||||
{
|
||||
int idx;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
bool defunikey, defmultikey, defmgmtkey;
|
||||
|
||||
/* caller must provide at least one old/new */
|
||||
|
@ -414,16 +415,27 @@ static int ieee80211_key_replace(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
WARN_ON(new && old && new->conf.keyidx != old->conf.keyidx);
|
||||
|
||||
if (new && sta && pairwise) {
|
||||
/* Unicast rekey needs special handling. With Extended Key ID
|
||||
* old is still NULL for the first rekey.
|
||||
*/
|
||||
ieee80211_pairwise_rekey(old, new);
|
||||
}
|
||||
|
||||
if (old) {
|
||||
idx = old->conf.keyidx;
|
||||
ret = ieee80211_hw_key_replace(old, new, pairwise);
|
||||
|
||||
if (old->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
|
||||
ieee80211_key_disable_hw_accel(old);
|
||||
|
||||
if (new)
|
||||
ret = ieee80211_key_enable_hw_accel(new);
|
||||
}
|
||||
} else {
|
||||
/* new must be provided in case old is not */
|
||||
idx = new->conf.keyidx;
|
||||
if (!new->local->wowlan)
|
||||
ret = ieee80211_key_enable_hw_accel(new);
|
||||
else
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
|
|
@ -3148,6 +3148,19 @@ static bool ieee80211_twt_req_supported(const struct sta_info *sta,
|
|||
IEEE80211_HE_MAC_CAP0_TWT_RES;
|
||||
}
|
||||
|
||||
static int ieee80211_recalc_twt_req(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
struct ieee802_11_elems *elems)
|
||||
{
|
||||
bool twt = ieee80211_twt_req_supported(sta, elems);
|
||||
|
||||
if (sdata->vif.bss_conf.twt_requester != twt) {
|
||||
sdata->vif.bss_conf.twt_requester = twt;
|
||||
return BSS_CHANGED_TWT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_bss *cbss,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
|
@ -3330,8 +3343,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
sta);
|
||||
|
||||
bss_conf->he_support = sta->sta.he_cap.has_he;
|
||||
bss_conf->twt_requester =
|
||||
ieee80211_twt_req_supported(sta, &elems);
|
||||
changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
|
||||
} else {
|
||||
bss_conf->he_support = false;
|
||||
bss_conf->twt_requester = false;
|
||||
|
@ -3991,6 +4003,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
mutex_lock(&local->sta_mtx);
|
||||
sta = sta_info_get(sdata, bssid);
|
||||
|
||||
changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
|
||||
|
||||
if (ieee80211_config_bw(sdata, sta,
|
||||
elems.ht_cap_elem, elems.ht_operation,
|
||||
elems.vht_operation, elems.he_operation,
|
||||
|
@ -4941,7 +4955,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
|
|||
basic_rates = BIT(min_rate_index);
|
||||
}
|
||||
|
||||
new_sta->sta.supp_rates[cbss->channel->band] = rates;
|
||||
if (rates)
|
||||
new_sta->sta.supp_rates[cbss->channel->band] = rates;
|
||||
else
|
||||
sdata_info(sdata,
|
||||
"No rates found, keeping mandatory only\n");
|
||||
|
||||
sdata->vif.bss_conf.basic_rates = basic_rates;
|
||||
|
||||
/* cf. IEEE 802.11 9.2.12 */
|
||||
|
|
|
@ -202,6 +202,10 @@ static void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc)
|
|||
cfg80211_remain_on_channel_expired(&roc->sdata->wdev,
|
||||
roc->cookie, roc->chan,
|
||||
GFP_KERNEL);
|
||||
else
|
||||
cfg80211_tx_mgmt_expired(&roc->sdata->wdev,
|
||||
roc->mgmt_tx_cookie,
|
||||
roc->chan, GFP_KERNEL);
|
||||
|
||||
list_del(&roc->list);
|
||||
kfree(roc);
|
||||
|
|
|
@ -357,8 +357,10 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
|
|||
break;
|
||||
}
|
||||
WARN_ONCE(i == sband->n_bitrates,
|
||||
"no supported rates (0x%x) in rate_mask 0x%x with flags 0x%x\n",
|
||||
"no supported rates for sta %pM (0x%x, band %d) in rate_mask 0x%x with flags 0x%x\n",
|
||||
sta ? sta->addr : NULL,
|
||||
sta ? sta->supp_rates[sband->band] : -1,
|
||||
sband->band,
|
||||
rate_mask, rate_flags);
|
||||
|
||||
info->control.rates[0].count =
|
||||
|
@ -369,9 +371,8 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
|
||||
bool rate_control_send_low(struct ieee80211_sta *pubsta,
|
||||
void *priv_sta,
|
||||
struct ieee80211_tx_rate_control *txrc)
|
||||
static bool rate_control_send_low(struct ieee80211_sta *pubsta,
|
||||
struct ieee80211_tx_rate_control *txrc)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
|
||||
struct ieee80211_supported_band *sband = txrc->sband;
|
||||
|
@ -379,7 +380,7 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
|
|||
int mcast_rate;
|
||||
bool use_basicrate = false;
|
||||
|
||||
if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
|
||||
if (!pubsta || rc_no_data_or_no_ack_use_min(txrc)) {
|
||||
__rate_control_send_low(txrc->hw, sband, pubsta, info,
|
||||
txrc->rate_idx_mask);
|
||||
|
||||
|
@ -405,7 +406,6 @@ bool rate_control_send_low(struct ieee80211_sta *pubsta,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
EXPORT_SYMBOL(rate_control_send_low);
|
||||
|
||||
static bool rate_idx_match_legacy_mask(s8 *rate_idx, int n_bitrates, u32 mask)
|
||||
{
|
||||
|
@ -888,26 +888,29 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
|
||||
int i;
|
||||
|
||||
if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
|
||||
ista = &sta->sta;
|
||||
priv_sta = sta->rate_ctrl_priv;
|
||||
}
|
||||
|
||||
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
|
||||
info->control.rates[i].idx = -1;
|
||||
info->control.rates[i].flags = 0;
|
||||
info->control.rates[i].count = 0;
|
||||
}
|
||||
|
||||
if (rate_control_send_low(sta ? &sta->sta : NULL, txrc))
|
||||
return;
|
||||
|
||||
if (ieee80211_hw_check(&sdata->local->hw, HAS_RATE_CONTROL))
|
||||
return;
|
||||
|
||||
if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
|
||||
ista = &sta->sta;
|
||||
priv_sta = sta->rate_ctrl_priv;
|
||||
}
|
||||
|
||||
if (ista) {
|
||||
spin_lock_bh(&sta->rate_ctrl_lock);
|
||||
ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
|
||||
spin_unlock_bh(&sta->rate_ctrl_lock);
|
||||
} else {
|
||||
ref->ops->get_rate(ref->priv, NULL, NULL, txrc);
|
||||
rate_control_send_low(NULL, txrc);
|
||||
}
|
||||
|
||||
if (ieee80211_hw_check(&sdata->local->hw, SUPPORTS_RC_TABLE))
|
||||
|
|
|
@ -340,10 +340,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
|
|||
int delta;
|
||||
int sampling_ratio;
|
||||
|
||||
/* management/no-ack frames do not use rate control */
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
/* check multi-rate-retry capabilities & adjust lookaround_rate */
|
||||
mrr_capable = mp->has_mrr &&
|
||||
!txrc->rts &&
|
||||
|
|
|
@ -1098,9 +1098,6 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
|
|||
struct minstrel_priv *mp = priv;
|
||||
int sample_idx;
|
||||
|
||||
if (rate_control_send_low(sta, priv_sta, txrc))
|
||||
return;
|
||||
|
||||
if (!msp->is_ht)
|
||||
return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||
* Copyright (C) 2018 Intel Corporation
|
||||
* Copyright (C) 2018-2019 Intel Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
|
@ -404,6 +404,47 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||
for (i = 0; i < IEEE80211_NUM_TIDS; i++)
|
||||
sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX);
|
||||
|
||||
for (i = 0; i < NUM_NL80211_BANDS; i++) {
|
||||
u32 mandatory = 0;
|
||||
int r;
|
||||
|
||||
if (!hw->wiphy->bands[i])
|
||||
continue;
|
||||
|
||||
switch (i) {
|
||||
case NL80211_BAND_2GHZ:
|
||||
/*
|
||||
* We use both here, even if we cannot really know for
|
||||
* sure the station will support both, but the only use
|
||||
* for this is when we don't know anything yet and send
|
||||
* management frames, and then we'll pick the lowest
|
||||
* possible rate anyway.
|
||||
* If we don't include _G here, we cannot find a rate
|
||||
* in P2P, and thus trigger the WARN_ONCE() in rate.c
|
||||
*/
|
||||
mandatory = IEEE80211_RATE_MANDATORY_B |
|
||||
IEEE80211_RATE_MANDATORY_G;
|
||||
break;
|
||||
case NL80211_BAND_5GHZ:
|
||||
mandatory = IEEE80211_RATE_MANDATORY_A;
|
||||
break;
|
||||
case NL80211_BAND_60GHZ:
|
||||
WARN_ON(1);
|
||||
mandatory = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (r = 0; r < hw->wiphy->bands[i]->n_bitrates; r++) {
|
||||
struct ieee80211_rate *rate;
|
||||
|
||||
rate = &hw->wiphy->bands[i]->bitrates[r];
|
||||
|
||||
if (!(rate->flags & mandatory))
|
||||
continue;
|
||||
sta->sta.supp_rates[i] |= BIT(r);
|
||||
}
|
||||
}
|
||||
|
||||
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
||||
|
|
|
@ -859,6 +859,19 @@ int wiphy_register(struct wiphy *wiphy)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < rdev->wiphy.n_vendor_commands; i++) {
|
||||
/*
|
||||
* Validate we have a policy (can be explicitly set to
|
||||
* VENDOR_CMD_RAW_DATA which is non-NULL) and also that
|
||||
* we have at least one of doit/dumpit.
|
||||
*/
|
||||
if (WARN_ON(!rdev->wiphy.vendor_commands[i].policy))
|
||||
return -EINVAL;
|
||||
if (WARN_ON(!rdev->wiphy.vendor_commands[i].doit &&
|
||||
!rdev->wiphy.vendor_commands[i].dumpit))
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
if (WARN_ON(rdev->wiphy.wowlan && rdev->wiphy.wowlan->n_patterns &&
|
||||
(!rdev->wiphy.wowlan->pattern_min_len ||
|
||||
|
|
|
@ -531,6 +531,10 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev,
|
|||
void cfg80211_stop_nan(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
|
||||
struct cfg80211_internal_bss *
|
||||
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_internal_bss *tmp,
|
||||
bool signal_valid, unsigned long ts);
|
||||
#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
|
||||
#define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond)
|
||||
#else
|
||||
|
|
|
@ -304,8 +304,11 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
|
||||
|
||||
[NL80211_ATTR_MAC] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_MAC] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
|
||||
[NL80211_ATTR_PREV_BSSID] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
|
||||
[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
|
||||
[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
|
||||
|
@ -356,7 +359,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED },
|
||||
[NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG },
|
||||
|
||||
[NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN },
|
||||
[NL80211_ATTR_HT_CAPABILITY] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = NL80211_HT_CAPABILITY_LEN
|
||||
},
|
||||
|
||||
[NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_IE] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
|
||||
|
@ -386,7 +392,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_PID] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
|
||||
[NL80211_ATTR_PMKID] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = WLAN_PMKID_LEN
|
||||
},
|
||||
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
|
||||
[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
|
||||
|
@ -448,7 +457,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_WDEV] = { .type = NLA_U64 },
|
||||
[NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_AUTH_DATA] = { .type = NLA_BINARY, },
|
||||
[NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
|
||||
[NL80211_ATTR_VHT_CAPABILITY] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = NL80211_VHT_CAPABILITY_LEN
|
||||
},
|
||||
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_P2P_CTWINDOW] = NLA_POLICY_MAX(NLA_U8, 127),
|
||||
[NL80211_ATTR_P2P_OPPPS] = NLA_POLICY_MAX(NLA_U8, 1),
|
||||
|
@ -484,7 +496,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_VENDOR_DATA] = { .type = NLA_BINARY },
|
||||
[NL80211_ATTR_QOS_MAP] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_QOS_MAP_LEN_MAX },
|
||||
[NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_MAC_HINT] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_SOCKET_OWNER] = { .type = NLA_FLAG },
|
||||
|
@ -495,7 +510,10 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
NLA_POLICY_MAX(NLA_U8, IEEE80211_NUM_UPS - 1),
|
||||
[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
|
||||
[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
|
||||
[NL80211_ATTR_MAC_MASK] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_MAC_MASK] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_ATTR_WIPHY_SELF_MANAGED_REG] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
|
||||
|
@ -507,15 +525,21 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_MU_MIMO_GROUP_DATA] = {
|
||||
.len = VHT_MUMIMO_GROUPS_DATA_LEN
|
||||
},
|
||||
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_MU_MIMO_FOLLOW_MAC_ADDR] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_ATTR_NAN_MASTER_PREF] = NLA_POLICY_MIN(NLA_U8, 1),
|
||||
[NL80211_ATTR_BANDS] = { .type = NLA_U32 },
|
||||
[NL80211_ATTR_NAN_FUNC] = { .type = NLA_NESTED },
|
||||
[NL80211_ATTR_FILS_KEK] = { .type = NLA_BINARY,
|
||||
.len = FILS_MAX_KEK_LEN },
|
||||
[NL80211_ATTR_FILS_NONCES] = { .len = 2 * FILS_NONCE_LEN },
|
||||
[NL80211_ATTR_FILS_NONCES] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = 2 * FILS_NONCE_LEN
|
||||
},
|
||||
[NL80211_ATTR_MULTICAST_TO_UNICAST_ENABLED] = { .type = NLA_FLAG, },
|
||||
[NL80211_ATTR_BSSID] = { .len = ETH_ALEN },
|
||||
[NL80211_ATTR_BSSID] = { .type = NLA_EXACT_LEN_WARN, .len = ETH_ALEN },
|
||||
[NL80211_ATTR_SCHED_SCAN_RELATIVE_RSSI] = { .type = NLA_S8 },
|
||||
[NL80211_ATTR_SCHED_SCAN_RSSI_ADJUST] = {
|
||||
.len = sizeof(struct nl80211_bss_select_rssi_adjust)
|
||||
|
@ -528,7 +552,7 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_FILS_ERP_NEXT_SEQ_NUM] = { .type = NLA_U16 },
|
||||
[NL80211_ATTR_FILS_ERP_RRK] = { .type = NLA_BINARY,
|
||||
.len = FILS_ERP_MAX_RRK_LEN },
|
||||
[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
|
||||
[NL80211_ATTR_FILS_CACHE_ID] = { .type = NLA_EXACT_LEN_WARN, .len = 2 },
|
||||
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
|
||||
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
|
||||
[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT] = { .type = NLA_FLAG },
|
||||
|
@ -547,6 +571,9 @@ const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
|||
[NL80211_ATTR_PEER_MEASUREMENTS] =
|
||||
NLA_POLICY_NESTED(nl80211_pmsr_attr_policy),
|
||||
[NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1),
|
||||
[NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY,
|
||||
.len = SAE_PASSWORD_MAX_LEN },
|
||||
[NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
|
@ -589,10 +616,13 @@ static const struct nla_policy
|
|||
nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
|
||||
[NL80211_WOWLAN_TCP_SRC_IPV4] = { .type = NLA_U32 },
|
||||
[NL80211_WOWLAN_TCP_DST_IPV4] = { .type = NLA_U32 },
|
||||
[NL80211_WOWLAN_TCP_DST_MAC] = { .len = ETH_ALEN },
|
||||
[NL80211_WOWLAN_TCP_DST_MAC] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_WOWLAN_TCP_SRC_PORT] = { .type = NLA_U16 },
|
||||
[NL80211_WOWLAN_TCP_DST_PORT] = { .type = NLA_U16 },
|
||||
[NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .len = 1 },
|
||||
[NL80211_WOWLAN_TCP_DATA_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
|
||||
[NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ] = {
|
||||
.len = sizeof(struct nl80211_wowlan_tcp_data_seq)
|
||||
},
|
||||
|
@ -600,8 +630,8 @@ nl80211_wowlan_tcp_policy[NUM_NL80211_WOWLAN_TCP] = {
|
|||
.len = sizeof(struct nl80211_wowlan_tcp_data_token)
|
||||
},
|
||||
[NL80211_WOWLAN_TCP_DATA_INTERVAL] = { .type = NLA_U32 },
|
||||
[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .len = 1 },
|
||||
[NL80211_WOWLAN_TCP_WAKE_MASK] = { .len = 1 },
|
||||
[NL80211_WOWLAN_TCP_WAKE_PAYLOAD] = { .type = NLA_MIN_LEN, .len = 1 },
|
||||
[NL80211_WOWLAN_TCP_WAKE_MASK] = { .type = NLA_MIN_LEN, .len = 1 },
|
||||
};
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
|
@ -619,9 +649,12 @@ nl80211_coalesce_policy[NUM_NL80211_ATTR_COALESCE_RULE] = {
|
|||
/* policy for GTK rekey offload attributes */
|
||||
static const struct nla_policy
|
||||
nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
|
||||
[NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
|
||||
[NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
|
||||
[NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
|
||||
[NL80211_REKEY_DATA_KEK] = { .type = NLA_EXACT_LEN_WARN, .len = NL80211_KEK_LEN },
|
||||
[NL80211_REKEY_DATA_KCK] = { .type = NLA_EXACT_LEN_WARN, .len = NL80211_KCK_LEN },
|
||||
[NL80211_REKEY_DATA_REPLAY_CTR] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = NL80211_REPLAY_CTR_LEN
|
||||
},
|
||||
};
|
||||
|
||||
static const struct nla_policy
|
||||
|
@ -635,7 +668,10 @@ static const struct nla_policy
|
|||
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_SSID_LEN },
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
|
||||
[NL80211_SCHED_SCAN_MATCH_PER_BAND_RSSI] =
|
||||
NLA_POLICY_NESTED(nl80211_match_band_rssi_policy),
|
||||
|
@ -667,7 +703,10 @@ nl80211_nan_func_policy[NL80211_NAN_FUNC_ATTR_MAX + 1] = {
|
|||
[NL80211_NAN_FUNC_SUBSCRIBE_ACTIVE] = { .type = NLA_FLAG },
|
||||
[NL80211_NAN_FUNC_FOLLOW_UP_ID] = { .type = NLA_U8 },
|
||||
[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] = { .type = NLA_U8 },
|
||||
[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = { .len = ETH_ALEN },
|
||||
[NL80211_NAN_FUNC_FOLLOW_UP_DEST] = {
|
||||
.type = NLA_EXACT_LEN_WARN,
|
||||
.len = ETH_ALEN
|
||||
},
|
||||
[NL80211_NAN_FUNC_CLOSE_RANGE] = { .type = NLA_FLAG },
|
||||
[NL80211_NAN_FUNC_TTL] = { .type = NLA_U32 },
|
||||
[NL80211_NAN_FUNC_SERVICE_INFO] = { .type = NLA_BINARY,
|
||||
|
@ -4057,7 +4096,7 @@ static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = {
|
|||
.len = NL80211_MAX_SUPP_RATES },
|
||||
[NL80211_TXRATE_HT] = { .type = NLA_BINARY,
|
||||
.len = NL80211_MAX_SUPP_HT_RATES },
|
||||
[NL80211_TXRATE_VHT] = { .len = sizeof(struct nl80211_txrate_vht)},
|
||||
[NL80211_TXRATE_VHT] = { .type = NLA_EXACT_LEN_WARN, .len = sizeof(struct nl80211_txrate_vht)},
|
||||
[NL80211_TXRATE_GI] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
|
@ -4398,6 +4437,8 @@ static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev,
|
|||
return true;
|
||||
case NL80211_CMD_CONNECT:
|
||||
if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) &&
|
||||
!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD) &&
|
||||
auth_type == NL80211_AUTHTYPE_SAE)
|
||||
return false;
|
||||
|
||||
|
@ -4588,6 +4629,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
|
|||
return PTR_ERR(params.acl);
|
||||
}
|
||||
|
||||
params.twt_responder =
|
||||
nla_get_flag(info->attrs[NL80211_ATTR_TWT_RESPONDER]);
|
||||
|
||||
nl80211_calculate_ap_params(¶ms);
|
||||
|
||||
if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT])
|
||||
|
@ -8700,7 +8744,8 @@ static int nl80211_dump_survey(struct sk_buff *skb, struct netlink_callback *cb)
|
|||
static bool nl80211_valid_wpa_versions(u32 wpa_versions)
|
||||
{
|
||||
return !(wpa_versions & ~(NL80211_WPA_VERSION_1 |
|
||||
NL80211_WPA_VERSION_2));
|
||||
NL80211_WPA_VERSION_2 |
|
||||
NL80211_WPA_VERSION_3));
|
||||
}
|
||||
|
||||
static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
|
||||
|
@ -8936,6 +8981,16 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
|
|||
settings->psk = nla_data(info->attrs[NL80211_ATTR_PMK]);
|
||||
}
|
||||
|
||||
if (info->attrs[NL80211_ATTR_SAE_PASSWORD]) {
|
||||
if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_SAE_OFFLOAD))
|
||||
return -EINVAL;
|
||||
settings->sae_pwd =
|
||||
nla_data(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
|
||||
settings->sae_pwd_len =
|
||||
nla_len(info->attrs[NL80211_ATTR_SAE_PASSWORD]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -12618,6 +12673,29 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int nl80211_vendor_check_policy(const struct wiphy_vendor_command *vcmd,
|
||||
struct nlattr *attr,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
if (vcmd->policy == VENDOR_CMD_RAW_DATA) {
|
||||
if (attr->nla_type & NLA_F_NESTED) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr,
|
||||
"unexpected nested data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(attr->nla_type & NLA_F_NESTED)) {
|
||||
NL_SET_ERR_MSG_ATTR(extack, attr, "expected nested data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return nl80211_validate_nested(attr, vcmd->maxattr, vcmd->policy,
|
||||
extack);
|
||||
}
|
||||
|
||||
static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
|
@ -12676,11 +12754,16 @@ static int nl80211_vendor_cmd(struct sk_buff *skb, struct genl_info *info)
|
|||
if (info->attrs[NL80211_ATTR_VENDOR_DATA]) {
|
||||
data = nla_data(info->attrs[NL80211_ATTR_VENDOR_DATA]);
|
||||
len = nla_len(info->attrs[NL80211_ATTR_VENDOR_DATA]);
|
||||
|
||||
err = nl80211_vendor_check_policy(vcmd,
|
||||
info->attrs[NL80211_ATTR_VENDOR_DATA],
|
||||
info->extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
rdev->cur_cmd_info = info;
|
||||
err = rdev->wiphy.vendor_commands[i].doit(&rdev->wiphy, wdev,
|
||||
data, len);
|
||||
err = vcmd->doit(&rdev->wiphy, wdev, data, len);
|
||||
rdev->cur_cmd_info = NULL;
|
||||
return err;
|
||||
}
|
||||
|
@ -12767,6 +12850,13 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
|
|||
if (attrbuf[NL80211_ATTR_VENDOR_DATA]) {
|
||||
data = nla_data(attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
data_len = nla_len(attrbuf[NL80211_ATTR_VENDOR_DATA]);
|
||||
|
||||
err = nl80211_vendor_check_policy(
|
||||
&(*rdev)->wiphy.vendor_commands[vcmd_idx],
|
||||
attrbuf[NL80211_ATTR_VENDOR_DATA],
|
||||
cb->extack);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* 0 is the first index - add 1 to parse only once */
|
||||
|
@ -15035,7 +15125,9 @@ void nl80211_send_port_authorized(struct cfg80211_registered_device *rdev,
|
|||
return;
|
||||
}
|
||||
|
||||
if (nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
@ -15325,6 +15417,19 @@ void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie,
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_remain_on_channel_expired);
|
||||
|
||||
void cfg80211_tx_mgmt_expired(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wiphy *wiphy = wdev->wiphy;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
|
||||
trace_cfg80211_tx_mgmt_expired(wdev, cookie, chan);
|
||||
nl80211_send_remain_on_chan_event(NL80211_CMD_FRAME_WAIT_CANCEL,
|
||||
rdev, wdev, cookie, chan, 0, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_tx_mgmt_expired);
|
||||
|
||||
void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,
|
||||
struct station_info *sinfo, gfp_t gfp)
|
||||
{
|
||||
|
|
|
@ -1092,17 +1092,17 @@ struct cfg80211_non_tx_bss {
|
|||
};
|
||||
|
||||
/* Returned bss is reference counted and must be cleaned up appropriately. */
|
||||
static struct cfg80211_internal_bss *
|
||||
struct cfg80211_internal_bss *
|
||||
cfg80211_bss_update(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_internal_bss *tmp,
|
||||
bool signal_valid)
|
||||
bool signal_valid, unsigned long ts)
|
||||
{
|
||||
struct cfg80211_internal_bss *found = NULL;
|
||||
|
||||
if (WARN_ON(!tmp->pub.channel))
|
||||
return NULL;
|
||||
|
||||
tmp->ts = jiffies;
|
||||
tmp->ts = ts;
|
||||
|
||||
spin_lock_bh(&rdev->bss_lock);
|
||||
|
||||
|
@ -1425,7 +1425,8 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy,
|
|||
|
||||
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
|
||||
jiffies);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
@ -1842,7 +1843,8 @@ cfg80211_inform_single_bss_frame_data(struct wiphy *wiphy,
|
|||
|
||||
signal_valid = abs(data->chan->center_freq - channel->center_freq) <=
|
||||
wiphy->max_adj_channel_rssi_comp;
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid);
|
||||
res = cfg80211_bss_update(wiphy_to_rdev(wiphy), &tmp, signal_valid,
|
||||
jiffies);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
||||
|
@ -1972,6 +1974,27 @@ out:
|
|||
}
|
||||
EXPORT_SYMBOL(cfg80211_unlink_bss);
|
||||
|
||||
void cfg80211_bss_iter(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef,
|
||||
void (*iter)(struct wiphy *wiphy,
|
||||
struct cfg80211_bss *bss,
|
||||
void *data),
|
||||
void *iter_data)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct cfg80211_internal_bss *bss;
|
||||
|
||||
spin_lock_bh(&rdev->bss_lock);
|
||||
|
||||
list_for_each_entry(bss, &rdev->bss_list, list) {
|
||||
if (!chandef || cfg80211_is_sub_chan(chandef, bss->pub.channel))
|
||||
iter(wiphy, &bss->pub, iter_data);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&rdev->bss_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_bss_iter);
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
static struct cfg80211_registered_device *
|
||||
cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
|
||||
|
|
|
@ -796,12 +796,36 @@ void cfg80211_connect_done(struct net_device *dev,
|
|||
u8 *next;
|
||||
|
||||
if (params->bss) {
|
||||
/* Make sure the bss entry provided by the driver is valid. */
|
||||
struct cfg80211_internal_bss *ibss = bss_from_pub(params->bss);
|
||||
|
||||
if (WARN_ON(list_empty(&ibss->list))) {
|
||||
cfg80211_put_bss(wdev->wiphy, params->bss);
|
||||
return;
|
||||
if (list_empty(&ibss->list)) {
|
||||
struct cfg80211_bss *found = NULL, *tmp = params->bss;
|
||||
|
||||
found = cfg80211_get_bss(wdev->wiphy, NULL,
|
||||
params->bss->bssid,
|
||||
wdev->ssid, wdev->ssid_len,
|
||||
wdev->conn_bss_type,
|
||||
IEEE80211_PRIVACY_ANY);
|
||||
if (found) {
|
||||
/* The same BSS is already updated so use it
|
||||
* instead, as it has latest info.
|
||||
*/
|
||||
params->bss = found;
|
||||
} else {
|
||||
/* Update with BSS provided by driver, it will
|
||||
* be freshly added and ref cnted, we can free
|
||||
* the old one.
|
||||
*
|
||||
* signal_valid can be false, as we are not
|
||||
* expecting the BSS to be found.
|
||||
*
|
||||
* keep the old timestamp to avoid confusion
|
||||
*/
|
||||
cfg80211_bss_update(rdev, ibss, false,
|
||||
ibss->ts);
|
||||
}
|
||||
|
||||
cfg80211_put_bss(wdev->wiphy, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2752,6 +2752,24 @@ TRACE_EVENT(cfg80211_ready_on_channel_expired,
|
|||
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_tx_mgmt_expired,
|
||||
TP_PROTO(struct wireless_dev *wdev, u64 cookie,
|
||||
struct ieee80211_channel *chan),
|
||||
TP_ARGS(wdev, cookie, chan),
|
||||
TP_STRUCT__entry(
|
||||
WDEV_ENTRY
|
||||
__field(u64, cookie)
|
||||
CHAN_ENTRY
|
||||
),
|
||||
TP_fast_assign(
|
||||
WDEV_ASSIGN;
|
||||
__entry->cookie = cookie;
|
||||
CHAN_ASSIGN(chan);
|
||||
),
|
||||
TP_printk(WDEV_PR_FMT ", cookie: %llu, " CHAN_PR_FMT,
|
||||
WDEV_PR_ARG, __entry->cookie, CHAN_PR_ARG)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_new_sta,
|
||||
TP_PROTO(struct net_device *netdev, const u8 *mac_addr,
|
||||
struct station_info *sinfo),
|
||||
|
|
Loading…
Reference in New Issue