mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-04 04:06:26 +00:00
wifi: mac80211: make bss_param_ch_cnt available for the low level driver
Drivers may need to track this. Make it available for them, and maintain the value when beacons are received. When link X receives a beacon, iterate the RNR elements and update all the links with their respective data. Track the link id that updated the data so that each link can know whether the update came from its own beacon or from another link. In case, the update came from the link's own beacon, always update the updater link id. The purpose is to let the low level driver know if a link is losing its beacons. If link X is losing its beacons, it can still track the bss_param_ch_cnt and know where the update came from. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Link: https://patch.msgid.link/20241007144851.e2d8d1a722ad.I04b883daba2cd48e5730659eb62ca1614c899cbb@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
9c5f2c7eeb
commit
e21dd758cf
@ -740,6 +740,19 @@ struct ieee80211_parsed_tpe {
|
||||
* @eht_80mhz_full_bw_ul_mumimo: in AP-mode, does this BSS support the
|
||||
* reception of an EHT TB PPDU on an RU that spans the entire PPDU
|
||||
* bandwidth
|
||||
* @bss_param_ch_cnt: in BSS-mode, the BSS params change count. This
|
||||
* information is the latest known value. It can come from this link's
|
||||
* beacon or from a beacon sent by another link.
|
||||
* @bss_param_ch_cnt_link_id: in BSS-mode, the link_id to which the beacon
|
||||
* that updated &bss_param_ch_cnt belongs. E.g. if link 1 doesn't hear
|
||||
* its beacons, and link 2 sent a beacon with an RNR element that updated
|
||||
* link 1's BSS params change count, then, link 1's
|
||||
* bss_param_ch_cnt_link_id will be 2. That means that link 1 knows that
|
||||
* link 2 was the link that updated its bss_param_ch_cnt value.
|
||||
* In case link 1 hears its beacon again, bss_param_ch_cnt_link_id will
|
||||
* 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).
|
||||
*/
|
||||
struct ieee80211_bss_conf {
|
||||
struct ieee80211_vif *vif;
|
||||
@ -834,6 +847,8 @@ struct ieee80211_bss_conf {
|
||||
bool eht_su_beamformee;
|
||||
bool eht_mu_beamformer;
|
||||
bool eht_80mhz_full_bw_ul_mumimo;
|
||||
u8 bss_param_ch_cnt;
|
||||
u8 bss_param_ch_cnt_link_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1015,8 +1015,6 @@ struct ieee80211_link_data_managed {
|
||||
|
||||
int wmm_last_param_set;
|
||||
int mu_edca_last_param_set;
|
||||
|
||||
u8 bss_param_ch_cnt;
|
||||
};
|
||||
|
||||
struct ieee80211_link_data_ap {
|
||||
|
@ -2643,6 +2643,89 @@ ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
|
||||
&ifmgd->csa_connection_drop_work);
|
||||
}
|
||||
|
||||
struct sta_bss_param_ch_cnt_data {
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
u8 reporting_link_id;
|
||||
u8 mld_id;
|
||||
};
|
||||
|
||||
static enum cfg80211_rnr_iter_ret
|
||||
ieee80211_sta_bss_param_ch_cnt_iter(void *_data, u8 type,
|
||||
const struct ieee80211_neighbor_ap_info *info,
|
||||
const u8 *tbtt_info, u8 tbtt_info_len)
|
||||
{
|
||||
struct sta_bss_param_ch_cnt_data *data = _data;
|
||||
struct ieee80211_sub_if_data *sdata = data->sdata;
|
||||
const struct ieee80211_tbtt_info_ge_11 *ti;
|
||||
u8 bss_param_ch_cnt;
|
||||
int link_id;
|
||||
|
||||
if (type != IEEE80211_TBTT_INFO_TYPE_TBTT)
|
||||
return RNR_ITER_CONTINUE;
|
||||
|
||||
if (tbtt_info_len < sizeof(*ti))
|
||||
return RNR_ITER_CONTINUE;
|
||||
|
||||
ti = (const void *)tbtt_info;
|
||||
|
||||
if (ti->mld_params.mld_id != data->mld_id)
|
||||
return RNR_ITER_CONTINUE;
|
||||
|
||||
link_id = le16_get_bits(ti->mld_params.params,
|
||||
IEEE80211_RNR_MLD_PARAMS_LINK_ID);
|
||||
bss_param_ch_cnt =
|
||||
le16_get_bits(ti->mld_params.params,
|
||||
IEEE80211_RNR_MLD_PARAMS_BSS_CHANGE_COUNT);
|
||||
|
||||
if (bss_param_ch_cnt != 255 &&
|
||||
link_id < ARRAY_SIZE(sdata->link)) {
|
||||
struct ieee80211_link_data *link =
|
||||
sdata_dereference(sdata->link[link_id], sdata);
|
||||
|
||||
if (link && link->conf->bss_param_ch_cnt != bss_param_ch_cnt) {
|
||||
link->conf->bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
link->conf->bss_param_ch_cnt_link_id =
|
||||
data->reporting_link_id;
|
||||
}
|
||||
}
|
||||
|
||||
return RNR_ITER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_mgd_update_bss_param_ch_cnt(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
struct ieee802_11_elems *elems)
|
||||
{
|
||||
struct sta_bss_param_ch_cnt_data data = {
|
||||
.reporting_link_id = bss_conf->link_id,
|
||||
.sdata = sdata,
|
||||
};
|
||||
int bss_param_ch_cnt;
|
||||
|
||||
if (!elems->ml_basic)
|
||||
return;
|
||||
|
||||
data.mld_id = ieee80211_mle_get_mld_id((const void *)elems->ml_basic);
|
||||
|
||||
cfg80211_iter_rnr(elems->ie_start, elems->total_len,
|
||||
ieee80211_sta_bss_param_ch_cnt_iter, &data);
|
||||
|
||||
bss_param_ch_cnt =
|
||||
ieee80211_mle_get_bss_param_ch_cnt((const void *)elems->ml_basic);
|
||||
|
||||
/*
|
||||
* Update bss_param_ch_cnt_link_id even if bss_param_ch_cnt
|
||||
* didn't change to indicate that we got a beacon on our own
|
||||
* link.
|
||||
*/
|
||||
if (bss_param_ch_cnt >= 0 && bss_param_ch_cnt != 255) {
|
||||
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
bss_conf->bss_param_ch_cnt_link_id =
|
||||
bss_conf->link_id;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_channel *channel,
|
||||
@ -4667,7 +4750,8 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
link->u.mgd.bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
bss_conf->bss_param_ch_cnt = bss_param_ch_cnt;
|
||||
bss_conf->bss_param_ch_cnt_link_id = link_id;
|
||||
}
|
||||
} else if (elems->parse_error & IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC ||
|
||||
!elems->prof ||
|
||||
@ -4677,6 +4761,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
|
||||
} else {
|
||||
const u8 *ptr = elems->prof->variable +
|
||||
elems->prof->sta_info_len - 1;
|
||||
int bss_param_ch_cnt;
|
||||
|
||||
/*
|
||||
* During parsing, we validated that these fields exist,
|
||||
@ -4684,8 +4769,10 @@ 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 =
|
||||
bss_param_ch_cnt =
|
||||
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 (assoc_data->link[link_id].status != WLAN_STATUS_SUCCESS) {
|
||||
link_info(link, "association response status code=%u\n",
|
||||
@ -6913,6 +7000,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
|
||||
/* note that after this elems->ml_basic can no longer be used fully */
|
||||
ieee80211_mgd_check_cross_link_csa(sdata, rx_status->link_id, elems);
|
||||
|
||||
ieee80211_mgd_update_bss_param_ch_cnt(sdata, bss_conf, elems);
|
||||
|
||||
if (!link->u.mgd.disable_wmm_tracking &&
|
||||
ieee80211_sta_wmm_params(local, link, elems->wmm_param,
|
||||
elems->wmm_param_len,
|
||||
|
Loading…
Reference in New Issue
Block a user