wifi: mac80211: store BSS param change count from assoc response
When receiving a multi-link association response, make sure to track the BSS parameter change count for each link, including the assoc link. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Gregory Greenman <gregory.greenman@intel.com> Link: https://lore.kernel.org/r/20230619161906.1799c164e7e9.I8e2c1f5eec6eec3fab525ae2dead9f6f099a2427@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
76a3059cf1
commit
5c1f97537b
@ -4689,6 +4689,34 @@ static inline u8 ieee80211_mle_common_size(const u8 *data)
|
||||
return sizeof(*mle) + common + mle->variable[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_get_bss_param_ch_cnt - returns the BSS parameter change count
|
||||
* @mle: the basic multi link element
|
||||
*
|
||||
* The element is assumed to be of the correct type (BASIC) and big enough,
|
||||
* this must be checked using ieee80211_mle_type_ok().
|
||||
*
|
||||
* If the BSS parameter change count value can't be found (the presence bit
|
||||
* for it is clear), 0 will be returned.
|
||||
*/
|
||||
static inline u8
|
||||
ieee80211_mle_get_bss_param_ch_cnt(const struct ieee80211_multi_link_elem *mle)
|
||||
{
|
||||
u16 control = le16_to_cpu(mle->control);
|
||||
const u8 *common = mle->variable;
|
||||
|
||||
/* common points now at the beginning of ieee80211_mle_basic_common_info */
|
||||
common += sizeof(struct ieee80211_mle_basic_common_info);
|
||||
|
||||
if (!(control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT))
|
||||
return 0;
|
||||
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
|
||||
common += 1;
|
||||
|
||||
return *common;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_get_eml_sync_delay - returns the medium sync delay
|
||||
* @data: pointer to the multi link EHT IE
|
||||
@ -4902,6 +4930,42 @@ static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data,
|
||||
fixed + prof->sta_info_len <= len;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_basic_sta_prof_bss_param_ch_cnt - get per-STA profile BSS
|
||||
* parameter change count
|
||||
* @prof: the per-STA profile, having been checked with
|
||||
* ieee80211_mle_basic_sta_prof_size_ok() for the correct length
|
||||
*
|
||||
* Return: The BSS parameter change count value if present, 0 otherwise.
|
||||
*/
|
||||
static inline u8
|
||||
ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta_profile *prof)
|
||||
{
|
||||
u16 control = le16_to_cpu(prof->control);
|
||||
const u8 *pos = prof->variable;
|
||||
|
||||
if (!(control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT))
|
||||
return 0;
|
||||
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT)
|
||||
pos += 6;
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT)
|
||||
pos += 2;
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT)
|
||||
pos += 8;
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_DTIM_INFO_PRESENT)
|
||||
pos += 2;
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE &&
|
||||
control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE) {
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE)
|
||||
pos += 2;
|
||||
else
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
return *pos;
|
||||
}
|
||||
|
||||
#define IEEE80211_MLE_STA_RECONF_CONTROL_LINK_ID 0x000f
|
||||
#define IEEE80211_MLE_STA_RECONF_CONTROL_COMPLETE_PROFILE 0x0010
|
||||
#define IEEE80211_MLE_STA_RECONF_CONTROL_STA_MAC_ADDR_PRESENT 0x0020
|
||||
|
@ -951,6 +951,8 @@ struct ieee80211_link_data_managed {
|
||||
int wmm_last_param_set;
|
||||
int mu_edca_last_param_set;
|
||||
|
||||
u8 bss_param_ch_cnt;
|
||||
|
||||
struct cfg80211_bss *bss;
|
||||
};
|
||||
|
||||
|
@ -4018,6 +4018,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
||||
const struct cfg80211_bss_ies *bss_ies = NULL;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee802_11_elems *elems;
|
||||
const __le16 prof_bss_param_ch_present =
|
||||
cpu_to_le16(IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT);
|
||||
u16 capab_info;
|
||||
bool ret;
|
||||
|
||||
@ -4033,7 +4035,17 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
||||
* successful, so set the status directly to success
|
||||
*/
|
||||
assoc_data->link[link_id].status = WLAN_STATUS_SUCCESS;
|
||||
} else if (!elems->prof) {
|
||||
if (elems->ml_basic) {
|
||||
if (!(elems->ml_basic->control &
|
||||
cpu_to_le16(IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT))) {
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
link->u.mgd.bss_param_ch_cnt =
|
||||
ieee80211_mle_get_bss_param_ch_cnt(elems->ml_basic);
|
||||
}
|
||||
} else if (!elems->prof ||
|
||||
!(elems->prof->control & prof_bss_param_ch_present)) {
|
||||
ret = false;
|
||||
goto out;
|
||||
} else {
|
||||
@ -4046,6 +4058,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
||||
*/
|
||||
capab_info = get_unaligned_le16(ptr);
|
||||
assoc_data->link[link_id].status = get_unaligned_le16(ptr + 2);
|
||||
link->u.mgd.bss_param_ch_cnt =
|
||||
ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
|
||||
|
||||
if (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
|
||||
link_info(link, "association response status code=%u\n",
|
||||
|
Loading…
Reference in New Issue
Block a user