mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
wifi: mac80211: parse enhanced critical updates field
For association and link reconfiguration response, parse and store the enhanced BSS parameter change counter out of the enhanced critical updates field in the multi-link common info or per-STA profile. These are required for UHR connections. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20260714134154.adb9fc29252d.I625580fbadbbf4a1440d88d3675586477f1a3263@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
40918ce98b
commit
c4b825b50c
|
|
@ -481,6 +481,7 @@ struct ieee80211_multi_link_elem {
|
|||
#define IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP 0x0100
|
||||
#define IEEE80211_MLC_BASIC_PRES_MLD_ID 0x0200
|
||||
#define IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP 0x0400
|
||||
#define IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD 0x0800
|
||||
|
||||
#define IEEE80211_MED_SYNC_DELAY_DURATION 0x00ff
|
||||
#define IEEE80211_MED_SYNC_DELAY_SYNC_OFDM_ED_THRESH 0x0f00
|
||||
|
|
@ -809,6 +810,49 @@ static inline u16 ieee80211_mle_get_ext_mld_capa_op(const u8 *data)
|
|||
return get_unaligned_le16(common);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_get_enh_crit_upd_info - returns the enhanced critical
|
||||
* updates information
|
||||
* @data: pointer to the multi-link element
|
||||
* Return: the enhanced critical updates information field, or %NULL
|
||||
*
|
||||
* The element is assumed to be of the correct type (BASIC) and big enough,
|
||||
* this must be checked using ieee80211_mle_type_ok().
|
||||
*/
|
||||
static inline const struct ieee80211_enh_crit_upd *
|
||||
ieee80211_mle_get_enh_crit_upd_info(const u8 *data)
|
||||
{
|
||||
const struct ieee80211_multi_link_elem *mle = (const void *)data;
|
||||
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_ENH_CRIT_UPD))
|
||||
return NULL;
|
||||
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_LINK_ID)
|
||||
common += 1;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT)
|
||||
common += 1;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_MED_SYNC_DELAY)
|
||||
common += 2;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_EML_CAPA)
|
||||
common += 2;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP)
|
||||
common += 2;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_MLD_ID)
|
||||
common += 1;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)
|
||||
common += 2;
|
||||
|
||||
return (const void *)common;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_get_mld_id - returns the MLD ID
|
||||
* @data: pointer to the multi-link element
|
||||
|
|
@ -883,6 +927,8 @@ static inline bool ieee80211_mle_size_ok(const u8 *data, size_t len)
|
|||
common += 1;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_EXT_MLD_CAPA_OP)
|
||||
common += 2;
|
||||
if (control & IEEE80211_MLC_BASIC_PRES_ENH_CRIT_UPD)
|
||||
common += 1;
|
||||
break;
|
||||
case IEEE80211_ML_CONTROL_TYPE_PREQ:
|
||||
common += sizeof(struct ieee80211_mle_preq_common_info);
|
||||
|
|
@ -959,6 +1005,8 @@ enum ieee80211_mle_subelems {
|
|||
#define IEEE80211_MLE_STA_CONTROL_NSTR_LINK_PAIR_PRESENT 0x0200
|
||||
#define IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE 0x0400
|
||||
#define IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT 0x0800
|
||||
#define IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT 0x1000
|
||||
#define IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT 0x2000
|
||||
|
||||
struct ieee80211_mle_per_sta_profile {
|
||||
__le16 control;
|
||||
|
|
@ -1004,6 +1052,12 @@ static inline bool ieee80211_mle_basic_sta_prof_size_ok(const u8 *data,
|
|||
if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)
|
||||
info_len += 1;
|
||||
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_ENH_CRIT_UPD_PRESENT)
|
||||
info_len += 1;
|
||||
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_AP_CONDUCTED_TX_PWR_PRESENT)
|
||||
info_len += 1;
|
||||
|
||||
return prof->sta_info_len >= info_len &&
|
||||
fixed + prof->sta_info_len - 1 <= len;
|
||||
}
|
||||
|
|
@ -1044,6 +1098,44 @@ ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(const struct ieee80211_mle_per_sta
|
|||
return *pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_mle_basic_sta_prof_enh_crit_upd - get per-STA profile enhanced
|
||||
* critical updates field
|
||||
* @prof: the per-STA profile, having been checked with
|
||||
* ieee80211_mle_basic_sta_prof_size_ok() for the correct length
|
||||
*
|
||||
* Return: The enhanced critical updates field if present, %NULL otherwise.
|
||||
*/
|
||||
static inline const struct ieee80211_enh_crit_upd *
|
||||
ieee80211_mle_basic_sta_prof_enh_crit_upd(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_ENH_CRIT_UPD_PRESENT))
|
||||
return NULL;
|
||||
|
||||
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_LINK_PAIR_PRESENT) {
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_NSTR_BITMAP_SIZE)
|
||||
pos += 2;
|
||||
else
|
||||
pos += 1;
|
||||
}
|
||||
if (control & IEEE80211_MLE_STA_CONTROL_BSS_PARAM_CHANGE_CNT_PRESENT)
|
||||
pos += 1;
|
||||
|
||||
return (const void *)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
|
||||
|
|
|
|||
|
|
@ -790,6 +790,10 @@ struct ieee80211_bss_npca_params {
|
|||
* be updated to 1, even if bss_param_ch_cnt didn't change. This allows
|
||||
* the link to know that it heard the latest value from its own beacon
|
||||
* (as opposed to hearing its value from another link's beacon).
|
||||
* @enh_bss_param_ch_cnt: In BSS-mode, the enhanced BSS parameters change
|
||||
* counter. See @bss_param_ch_cnt, it works the same way.
|
||||
* @enh_bss_param_ch_cnt_link_id: In BSS-mode, the link_id for the enhanced
|
||||
* BSS parameter change counter, see @bss_param_ch_cnt_link_id.
|
||||
* @s1g_long_beacon_period: number of beacon intervals between each long
|
||||
* beacon transmission.
|
||||
* @npca: NPCA parameters
|
||||
|
|
@ -894,6 +898,8 @@ struct ieee80211_bss_conf {
|
|||
|
||||
u8 bss_param_ch_cnt;
|
||||
u8 bss_param_ch_cnt_link_id;
|
||||
u8 enh_bss_param_ch_cnt;
|
||||
u8 enh_bss_param_ch_cnt_link_id;
|
||||
|
||||
u8 s1g_long_beacon_period;
|
||||
|
||||
|
|
|
|||
|
|
@ -5931,11 +5931,28 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
|||
ieee80211_mle_basic_sta_prof_bss_param_ch_cnt(elems->prof);
|
||||
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
bss_conf->bss_param_ch_cnt_link_id = link_id;
|
||||
|
||||
if (link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_UHR) {
|
||||
const struct ieee80211_enh_crit_upd *enh_crit_upd;
|
||||
|
||||
enh_crit_upd = ieee80211_mle_basic_sta_prof_enh_crit_upd(elems->prof);
|
||||
if (!enh_crit_upd) {
|
||||
link_info(link,
|
||||
"per-STA profile missing enhanced critical updates\n");
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bss_conf->enh_bss_param_ch_cnt =
|
||||
u8_get_bits(enh_crit_upd->v,
|
||||
IEEE80211_ENH_CRIT_UPD_EBPCC);
|
||||
bss_conf->enh_bss_param_ch_cnt_link_id = link_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (link_id == assoc_data->assoc_link_id && elems->ml_basic) {
|
||||
int bss_param_ch_cnt =
|
||||
ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
|
||||
const void *mle = (const void *)elems->ml_basic;
|
||||
int bss_param_ch_cnt = ieee80211_mle_get_bss_param_ch_cnt(mle);
|
||||
|
||||
if (bss_param_ch_cnt < 0) {
|
||||
sdata_info(sdata,
|
||||
|
|
@ -5945,6 +5962,23 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
|||
}
|
||||
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
bss_conf->bss_param_ch_cnt_link_id = link_id;
|
||||
|
||||
if (link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_UHR) {
|
||||
const struct ieee80211_enh_crit_upd *enh_crit_upd;
|
||||
|
||||
enh_crit_upd = ieee80211_mle_get_enh_crit_upd_info(mle);
|
||||
if (!enh_crit_upd) {
|
||||
link_info(link,
|
||||
"No enhanced critical updates in assoc response\n");
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bss_conf->enh_bss_param_ch_cnt =
|
||||
u8_get_bits(enh_crit_upd->v,
|
||||
IEEE80211_ENH_CRIT_UPD_EBPCC);
|
||||
bss_conf->enh_bss_param_ch_cnt_link_id = link_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_s1g && !elems->supp_rates) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user