AP: Include an RNR element in Beacon frames for AP MLD
- Include RNR element in Beacon frames of AP MLDs. - Whenever a new interface is added to an AP MLD, reconfigure the Beacon frame templates for all other interfaces, to allow updating their RNR elements. Signed-off-by: Ilan Peer <ilan.peer@intel.com>
This commit is contained in:
parent
0c6c948047
commit
2b541601da
4 changed files with 89 additions and 26 deletions
|
@ -2194,21 +2194,29 @@ int ieee802_11_set_beacon(struct hostapd_data *hapd)
|
|||
if (!iface->interfaces || iface->interfaces->count <= 1)
|
||||
return 0;
|
||||
|
||||
/* Update Beacon frames in case of 6 GHz colocation */
|
||||
/* Update Beacon frames in case of 6 GHz colocation or AP MLD */
|
||||
is_6g = is_6ghz_op_class(iface->conf->op_class);
|
||||
for (j = 0; j < iface->interfaces->count; j++) {
|
||||
struct hostapd_iface *colocated;
|
||||
struct hostapd_iface *other;
|
||||
bool mld_ap = false;
|
||||
|
||||
colocated = iface->interfaces->iface[j];
|
||||
if (colocated == iface || !colocated || !colocated->conf)
|
||||
other = iface->interfaces->iface[j];
|
||||
if (other == iface || !other || !other->conf)
|
||||
continue;
|
||||
|
||||
if (is_6g == is_6ghz_op_class(colocated->conf->op_class))
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (hapd->conf->mld_ap && other->bss[0]->conf->mld_ap &&
|
||||
hapd->conf->mld_id == other->bss[0]->conf->mld_id)
|
||||
mld_ap = true;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
if (is_6g == is_6ghz_op_class(other->conf->op_class) &&
|
||||
!mld_ap)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < colocated->num_bss; i++) {
|
||||
if (colocated->bss[i] && colocated->bss[i]->started)
|
||||
__ieee802_11_set_beacon(colocated->bss[i]);
|
||||
for (i = 0; i < other->num_bss; i++) {
|
||||
if (other->bss[i] && other->bss[i]->started)
|
||||
__ieee802_11_set_beacon(other->bss[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2471,6 +2471,9 @@ dfs_offload:
|
|||
for (j = 0; j < iface->num_bss; j++)
|
||||
hostapd_neighbor_set_own_report(iface->bss[j]);
|
||||
|
||||
if (iface->interfaces && iface->interfaces->count > 1)
|
||||
ieee802_11_set_beacons(iface);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -6443,6 +6443,11 @@ hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
|||
size_t total_len = 0, len = *current_len;
|
||||
int tbtt_count = 0;
|
||||
size_t i, start = 0;
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
ap_mld = !!hapd->conf->mld_ap;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
while (start < hapd->iface->num_bss) {
|
||||
if (!len ||
|
||||
|
@ -6472,8 +6477,13 @@ hostapd_eid_rnr_iface_len(struct hostapd_data *hapd,
|
|||
tbtt_count >= RNR_TBTT_INFO_COUNT_MAX)
|
||||
break;
|
||||
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
total_len += RNR_TBTT_INFO_LEN;
|
||||
if (!ap_mld) {
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
total_len += RNR_TBTT_INFO_LEN;
|
||||
} else {
|
||||
len += RNR_TBTT_INFO_MLD_LEN;
|
||||
total_len += RNR_TBTT_INFO_MLD_LEN;
|
||||
}
|
||||
tbtt_count++;
|
||||
}
|
||||
start = i;
|
||||
|
@ -6528,8 +6538,8 @@ static enum colocation_mode get_colocation_mode(struct hostapd_data *hapd)
|
|||
}
|
||||
|
||||
|
||||
static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
|
||||
size_t *current_len)
|
||||
static size_t hostapd_eid_rnr_multi_iface_len(struct hostapd_data *hapd,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_iface *iface;
|
||||
size_t len = 0;
|
||||
|
@ -6540,9 +6550,16 @@ static size_t hostapd_eid_rnr_colocation_len(struct hostapd_data *hapd,
|
|||
|
||||
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
iface = hapd->iface->interfaces->iface[i];
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
|
||||
hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
|
||||
ap_mld = true;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
if (iface == hapd->iface ||
|
||||
!is_6ghz_op_class(iface->conf->op_class))
|
||||
!(is_6ghz_op_class(iface->conf->op_class) || ap_mld))
|
||||
continue;
|
||||
|
||||
len += hostapd_eid_rnr_iface_len(iface->bss[0], hapd,
|
||||
|
@ -6557,6 +6574,11 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
|||
{
|
||||
size_t total_len = 0, current_len = 0;
|
||||
enum colocation_mode mode = get_colocation_mode(hapd);
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
ap_mld = !!hapd->conf->mld_ap;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
switch (type) {
|
||||
case WLAN_FC_STYPE_BEACON:
|
||||
|
@ -6565,9 +6587,10 @@ size_t hostapd_eid_rnr_len(struct hostapd_data *hapd, u32 type)
|
|||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (mode == COLOCATED_LOWER_BAND)
|
||||
total_len += hostapd_eid_rnr_colocation_len(
|
||||
hapd, ¤t_len);
|
||||
if (mode == COLOCATED_LOWER_BAND || ap_mld)
|
||||
total_len +=
|
||||
hostapd_eid_rnr_multi_iface_len(hapd,
|
||||
¤t_len);
|
||||
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
|
||||
!hapd->iconf->mbssid)
|
||||
|
@ -6657,6 +6680,11 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|||
size_t len = *current_len;
|
||||
u8 *tbtt_count_pos, *eid_start = eid, *size_offset = (eid - len) + 1;
|
||||
u8 tbtt_count = 0, op_class, channel, bss_param;
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
ap_mld = !!hapd->conf->mld_ap;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
if (!(iface->drv_flags & WPA_DRIVER_FLAGS_AP_CSA) || !iface->freq)
|
||||
return eid;
|
||||
|
@ -6679,7 +6707,7 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
tbtt_count_pos = eid++;
|
||||
*eid++ = RNR_TBTT_INFO_LEN;
|
||||
*eid++ = ap_mld ? RNR_TBTT_INFO_MLD_LEN : RNR_TBTT_INFO_LEN;
|
||||
*eid++ = op_class;
|
||||
*eid++ = hapd->iconf->channel;
|
||||
len += RNR_TBTT_HEADER_LEN;
|
||||
|
@ -6728,7 +6756,18 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|||
|
||||
*eid++ = bss_param;
|
||||
*eid++ = RNR_20_MHZ_PSD_MAX_TXPOWER - 1;
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
|
||||
if (!ap_mld) {
|
||||
len += RNR_TBTT_INFO_LEN;
|
||||
} else {
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
*eid++ = hapd->conf->mld_id;
|
||||
*eid++ = hapd->mld_link_id | (1 << 4);
|
||||
*eid++ = 0;
|
||||
len += RNR_TBTT_INFO_MLD_LEN;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
}
|
||||
|
||||
tbtt_count += 1;
|
||||
}
|
||||
|
||||
|
@ -6745,8 +6784,8 @@ static u8 * hostapd_eid_rnr_iface(struct hostapd_data *hapd,
|
|||
}
|
||||
|
||||
|
||||
static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
|
||||
size_t *current_len)
|
||||
static u8 * hostapd_eid_rnr_multi_iface(struct hostapd_data *hapd, u8 *eid,
|
||||
size_t *current_len)
|
||||
{
|
||||
struct hostapd_iface *iface;
|
||||
size_t i;
|
||||
|
@ -6756,9 +6795,16 @@ static u8 * hostapd_eid_rnr_colocation(struct hostapd_data *hapd, u8 *eid,
|
|||
|
||||
for (i = 0; i < hapd->iface->interfaces->count; i++) {
|
||||
iface = hapd->iface->interfaces->iface[i];
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
if (hapd->conf->mld_ap && iface->bss[0]->conf->mld_ap &&
|
||||
hapd->conf->mld_id == iface->bss[0]->conf->mld_id)
|
||||
ap_mld = true;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
if (iface == hapd->iface ||
|
||||
!is_6ghz_op_class(iface->conf->op_class))
|
||||
!(is_6ghz_op_class(iface->conf->op_class) || ap_mld))
|
||||
continue;
|
||||
|
||||
eid = hostapd_eid_rnr_iface(iface->bss[0], hapd, eid,
|
||||
|
@ -6774,6 +6820,11 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
|||
u8 *eid_start = eid;
|
||||
size_t current_len = 0;
|
||||
enum colocation_mode mode = get_colocation_mode(hapd);
|
||||
bool ap_mld = false;
|
||||
|
||||
#ifdef CONFIG_IEEE80211BE
|
||||
ap_mld = !!hapd->conf->mld_ap;
|
||||
#endif /* CONFIG_IEEE80211BE */
|
||||
|
||||
switch (type) {
|
||||
case WLAN_FC_STYPE_BEACON:
|
||||
|
@ -6782,9 +6833,9 @@ u8 * hostapd_eid_rnr(struct hostapd_data *hapd, u8 *eid, u32 type)
|
|||
/* fallthrough */
|
||||
|
||||
case WLAN_FC_STYPE_PROBE_RESP:
|
||||
if (mode == COLOCATED_LOWER_BAND)
|
||||
eid = hostapd_eid_rnr_colocation(hapd, eid,
|
||||
¤t_len);
|
||||
if (mode == COLOCATED_LOWER_BAND || ap_mld)
|
||||
eid = hostapd_eid_rnr_multi_iface(hapd, eid,
|
||||
¤t_len);
|
||||
|
||||
if (hapd->conf->rnr && hapd->iface->num_bss > 1 &&
|
||||
!hapd->iconf->mbssid)
|
||||
|
@ -7099,8 +7150,8 @@ u8 * hostapd_eid_mbssid(struct hostapd_data *hapd, u8 *eid, u8 *end,
|
|||
if (hapd->conf->rnr)
|
||||
rnr_eid = hostapd_eid_nr_db(hapd, rnr_eid, &cur_len);
|
||||
if (get_colocation_mode(hapd) == COLOCATED_LOWER_BAND)
|
||||
rnr_eid = hostapd_eid_rnr_colocation(hapd, rnr_eid,
|
||||
&cur_len);
|
||||
rnr_eid = hostapd_eid_rnr_multi_iface(hapd, rnr_eid,
|
||||
&cur_len);
|
||||
}
|
||||
|
||||
return eid;
|
||||
|
|
|
@ -2454,6 +2454,7 @@ struct ieee80211_he_mu_edca_parameter_set {
|
|||
#define RNR_TBTT_INFO_COUNT(x) (((x) & 0xf) << 4)
|
||||
#define RNR_TBTT_INFO_COUNT_MAX 16
|
||||
#define RNR_TBTT_INFO_LEN 13
|
||||
#define RNR_TBTT_INFO_MLD_LEN 16
|
||||
#define RNR_NEIGHBOR_AP_OFFSET_UNKNOWN 255
|
||||
/* Figure 9-632a - BSS Parameters subfield format */
|
||||
#define RNR_BSS_PARAM_OCT_RECOMMENDED BIT(0)
|
||||
|
|
Loading…
Reference in a new issue