This is to save the transmit power envelope element and power constraint in struct ieee80211_bss_conf for 6 GHz. Lower driver will use this info to calculate the power limit. Signed-off-by: Wen Gong <wgong@xxxxxxxxxxxxxx> --- include/net/mac80211.h | 6 ++++++ net/mac80211/chan.c | 9 +++++++++ net/mac80211/mlme.c | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e89530d0d9c6..6e11e122e364 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -631,6 +631,9 @@ struct ieee80211_fils_discovery { * @s1g: BSS is S1G BSS (affects Association Request format). * @beacon_tx_rate: The configured beacon transmit rate that needs to be passed * to driver when rate control is offloaded to firmware. + * @tx_pwr_env: transmit power envelope array of BSS. + * @tx_pwr_env_num: number of @tx_pwr_env. + * @pwr_reduction: power constraint of BSS. */ struct ieee80211_bss_conf { const u8 *bssid; @@ -700,6 +703,9 @@ struct ieee80211_bss_conf { u32 unsol_bcast_probe_resp_interval; bool s1g; struct cfg80211_bitrate_mask beacon_tx_rate; + struct ieee80211_tx_pwr_env tx_pwr_env[IEEE80211_TPE_MAX_IE_COUNT]; + u8 tx_pwr_env_num; + u8 pwr_reduction; }; /** diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 907bb1f748a1..149d4ac798f6 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -721,6 +721,15 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata, lockdep_is_held(&local->chanctx_mtx)); if (conf) { + if (conf->def.chan->band == NL80211_BAND_6GHZ) { + struct ieee80211_bss_conf *bss_conf; + + bss_conf = &sdata->vif.bss_conf; + bss_conf->pwr_reduction = 0; + bss_conf->tx_pwr_env_num = 0; + memset(bss_conf->tx_pwr_env, 0, sizeof(bss_conf->tx_pwr_env)); + } + curr_ctx = container_of(conf, struct ieee80211_chanctx, conf); drv_unassign_vif_chanctx(local, sdata, curr_ctx); diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2480bd0577bb..a6d66b4ad7ee 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -5070,6 +5070,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE)) { const struct cfg80211_bss_ies *ies; + struct ieee80211_bss_conf *bss_conf; const u8 *he_oper_ie; ies = rcu_dereference(cbss->ies); @@ -5081,6 +5082,31 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, else he_oper = NULL; + if (is_6ghz) { + struct ieee802_11_elems elems; + u8 i, j = 0; + + ieee802_11_parse_elems(ies->data, ies->len, false, &elems, + NULL, NULL); + + if (elems.pwr_constr_elem) + bss_conf->pwr_reduction = *elems.pwr_constr_elem; + + BUILD_BUG_ON(ARRAY_SIZE(bss_conf->tx_pwr_env) != + ARRAY_SIZE(elems.tx_pwr_env)); + + for (i = 0; i < elems.tx_pwr_env_num; i++) { + if (elems.tx_pwr_env_len[i] > + sizeof(bss_conf->tx_pwr_env[j])) + continue; + + bss_conf->tx_pwr_env_num++; + memcpy(&bss_conf->tx_pwr_env[j], elems.tx_pwr_env[i], + elems.tx_pwr_env_len[i]); + j++; + } + } + if (!ieee80211_verify_sta_he_mcs_support(sband, he_oper)) ifmgd->flags |= IEEE80211_STA_DISABLE_HE; } -- 2.31.1