diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index a310b76a9ecb..e722cab6f1a5 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -710,6 +710,15 @@ lim_send_probe_rsp_mgmt_frame(struct mac_context *mac_ctx, is_vht_enabled = true; } + if (wlan_reg_is_6ghz_chan_freq(pe_session->curr_op_freq)) { + populate_dot11f_tx_power_env(mac_ctx, + &frm->transmit_power_env[0], + pe_session->ch_width, + pe_session->curr_op_freq, + &frm->num_transmit_power_env, + false); + } + if (lim_is_session_he_capable(pe_session)) { pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac_ctx, pe_session, diff --git a/core/mac/src/pe/sch/sch_beacon_gen.c b/core/mac/src/pe/sch/sch_beacon_gen.c index 2354913dc1e8..ab54783392ee 100644 --- a/core/mac/src/pe/sch/sch_beacon_gen.c +++ b/core/mac/src/pe/sch/sch_beacon_gen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -474,6 +474,15 @@ sch_set_fixed_beacon_fields(struct mac_context *mac_ctx, struct pe_session *sess QCN_IE_ATTR_ID_ALL); } + if (wlan_reg_is_6ghz_chan_freq(session->curr_op_freq)) { + populate_dot11f_tx_power_env(mac_ctx, + &bcn_2->transmit_power_env[0], + session->ch_width, + session->curr_op_freq, + &bcn_2->num_transmit_power_env, + false); + } + if (lim_is_session_he_capable(session)) { pe_debug("Populate HE IEs"); populate_dot11f_he_caps(mac_ctx, session, diff --git a/core/mac/src/sys/legacy/src/utils/src/parser_api.c b/core/mac/src/sys/legacy/src/utils/src/parser_api.c index 7b7662fa4489..d747004c25e2 100644 --- a/core/mac/src/sys/legacy/src/utils/src/parser_api.c +++ b/core/mac/src/sys/legacy/src/utils/src/parser_api.c @@ -265,64 +265,222 @@ populate_dot11_supp_operating_classes(struct mac_context *mac_ptr, void populate_dot11f_tx_power_env(struct mac_context *mac, - tDot11fIEtransmit_power_env *pDot11f, - enum phy_ch_width ch_width, uint32_t chan_freq, - uint16_t *num_tpe, bool is_ch_switch) + tDot11fIEtransmit_power_env *tpe_ptr, + enum phy_ch_width chan_width, uint32_t chan_freq, + uint16_t *num_tpe, bool is_chan_switch) { - uint8_t num_tx_power, i, tx_power; - int reg_max; + uint8_t count; + uint16_t eirp_power, reg_power; + int power_for_bss; + bool add_eirp_power = false; + struct ch_params chan_params; + bool psd_tpe = false; + uint32_t bw_threshold, bw_val; + int num_tpe_ies = 0; + uint32_t num_tx_power, num_tx_power_psd; + uint32_t max_tx_pwr_count, max_tx_pwr_count_psd; + qdf_freq_t psd_start_freq; - if (!is_ch_switch) - *num_tpe = 1; + if (!wlan_reg_is_6ghz_chan_freq(chan_freq)) { + psd_tpe = false; + } else { + wlan_reg_get_client_power_for_6ghz_ap(mac->pdev, + REG_DEFAULT_CLIENT, + chan_freq, + &psd_tpe, + ®_power, &eirp_power); + } - switch (ch_width) { + switch (chan_width) { case CH_WIDTH_20MHZ: - /* Max Transmit Power count = 0 (20 MHz) */ - num_tx_power = 0; - break; - case CH_WIDTH_40MHZ: - /* Max Transmit Power count = 1 (20, 40 MHz) */ + max_tx_pwr_count = 0; + max_tx_pwr_count_psd = 1; num_tx_power = 1; + num_tx_power_psd = 1; break; - case CH_WIDTH_80MHZ: - /* Max Transmit Power count = 2 (20, 40, and 80 MHz) */ + + case CH_WIDTH_40MHZ: + max_tx_pwr_count = 1; + max_tx_pwr_count_psd = 2; num_tx_power = 2; + num_tx_power_psd = 2; break; + + case CH_WIDTH_80MHZ: + max_tx_pwr_count = 2; + max_tx_pwr_count_psd = 3; + num_tx_power = 3; + num_tx_power_psd = 4; + break; + case CH_WIDTH_160MHZ: case CH_WIDTH_80P80MHZ: - /* Max Transmit Power count = 3 (20, 40, 80, 160/80+80 MHz) */ - num_tx_power = 3; + max_tx_pwr_count = 3; + max_tx_pwr_count_psd = 4; + num_tx_power = 4; + num_tx_power_psd = 8; break; default: return; } - reg_max = wlan_reg_get_channel_reg_power_for_freq(mac->pdev, chan_freq); + if (!psd_tpe) { + reg_power = wlan_reg_get_channel_reg_power_for_freq( + mac->pdev, chan_freq); - /* in 0.5 dB steps */ - reg_max *= 2; - if (reg_max > 127) - /* 63.5 has special meaning of 63.5 dBm or higher */ - reg_max = 127; + tpe_ptr->present = 1; + tpe_ptr->max_tx_pwr_count = max_tx_pwr_count; + tpe_ptr->max_tx_pwr_interpret = 0; + tpe_ptr->max_tx_pwr_category = 0; + tpe_ptr->num_tx_power = num_tx_power; + for (count = 0; count < num_tx_power; count++) + tpe_ptr->tx_power[count] = reg_power; - if (reg_max < -128) - reg_max = -128; + num_tpe_ies++; + tpe_ptr++; + } else { - if (reg_max < 0) - tx_power = 0x80 + reg_max + 128; - else - tx_power = reg_max; + bw_val = wlan_reg_get_bw_value(chan_width); + bw_threshold = 20; + power_for_bss = reg_power + 13; - /* Ignore EID field */ - pDot11f[0].present = 1; - pDot11f[0].num_tx_power = num_tx_power + 2; - /* - * Max Transmit Power count and - * Max Transmit Power units = 0 (EIRP) - */ - pDot11f[0].tx_power[0] = num_tx_power; - for (i = 0; i <= num_tx_power; i++) - pDot11f[0].tx_power[i + 1] = tx_power; + while ((eirp_power > power_for_bss) && + (bw_threshold < bw_val)) { + bw_threshold = 2 * bw_threshold; + power_for_bss += 3; + } + if (bw_threshold < bw_val) + add_eirp_power = true; + + if (add_eirp_power) { + tpe_ptr->present = 1; + tpe_ptr->max_tx_pwr_count = max_tx_pwr_count; + tpe_ptr->max_tx_pwr_interpret = 2; + tpe_ptr->max_tx_pwr_category = 0; + tpe_ptr->num_tx_power = num_tx_power; + for (count = 0, bw_val = 20; count < num_tx_power; + count++, bw_val += 20) { + if (bw_val >= bw_threshold) + tpe_ptr->tx_power[count] = + eirp_power * 2; + else + tpe_ptr->tx_power[count] = + reg_power * 2; + } + + num_tpe_ies++; + tpe_ptr++; + } + + wlan_reg_get_client_power_for_6ghz_ap(mac->pdev, + REG_SUBORDINATE_CLIENT, + chan_freq, + &psd_tpe, + ®_power, + &eirp_power); + + if (reg_power) { + bw_val = wlan_reg_get_bw_value(chan_width); + bw_threshold = 20; + power_for_bss = reg_power + 13; + + while ((eirp_power > power_for_bss) && + (bw_threshold < bw_val)) { + bw_threshold = 2 * bw_threshold; + power_for_bss += 3; + } + if (bw_threshold < bw_val) + add_eirp_power = true; + + if (add_eirp_power) { + tpe_ptr->present = 1; + tpe_ptr->max_tx_pwr_count = max_tx_pwr_count; + tpe_ptr->max_tx_pwr_interpret = 2; + tpe_ptr->max_tx_pwr_category = 1; + tpe_ptr->num_tx_power = num_tx_power; + for (count = 0, bw_val = 20; + count < num_tx_power; + count++, bw_val += 20) { + if (bw_val >= bw_threshold) + tpe_ptr->tx_power[count] = + eirp_power * 2; + else + tpe_ptr->tx_power[count] = + reg_power * 2; + } + + num_tpe_ies++; + tpe_ptr++; + } + } + + tpe_ptr->present = 1; + tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd; + tpe_ptr->max_tx_pwr_interpret = 3; + tpe_ptr->max_tx_pwr_category = 0; + tpe_ptr->num_tx_power = num_tx_power_psd; + + chan_params.ch_width = chan_width; + bw_val = wlan_reg_get_bw_value(chan_width); + wlan_reg_set_channel_params_for_freq(mac->pdev, chan_freq, + chan_freq, + &chan_params); + + psd_start_freq = chan_params.mhz_freq_seg0 - bw_val + 10; + + for (count = 0; count < num_tx_power_psd; count++) { + wlan_reg_get_client_power_for_6ghz_ap( + mac->pdev, + REG_DEFAULT_CLIENT, + psd_start_freq + + 20 * num_tx_power_psd, + &psd_tpe, + ®_power, + &eirp_power); + tpe_ptr->tx_power[count] = reg_power * 2; + } + + num_tpe_ies++; + tpe_ptr++; + + wlan_reg_get_client_power_for_6ghz_ap(mac->pdev, + REG_SUBORDINATE_CLIENT, + chan_freq, + &psd_tpe, + ®_power, + &eirp_power); + + if (reg_power) { + tpe_ptr->present = 1; + tpe_ptr->max_tx_pwr_count = max_tx_pwr_count_psd; + tpe_ptr->max_tx_pwr_interpret = 3; + tpe_ptr->max_tx_pwr_category = 1; + tpe_ptr->num_tx_power = num_tx_power_psd; + + chan_params.ch_width = chan_width; + wlan_reg_set_channel_params_for_freq(mac->pdev, + chan_freq, + chan_freq, + &chan_params); + + for (count = 0; count < num_tx_power_psd; count++) { + wlan_reg_get_client_power_for_6ghz_ap( + mac->pdev, + REG_SUBORDINATE_CLIENT, + psd_start_freq + + 20 * num_tx_power_psd, + &psd_tpe, + ®_power, + &eirp_power); + tpe_ptr->tx_power[count] = reg_power * 2; + } + + num_tpe_ies++; + tpe_ptr++; + } + } + + *num_tpe = num_tpe_ies; } void @@ -330,6 +488,7 @@ populate_dot11f_chan_switch_wrapper(struct mac_context *mac, tDot11fIEChannelSwitchWrapper *pDot11f, struct pe_session *pe_session) { + uint16_t num_tpe; /* * The new country subelement is present only when * 1. AP performs Extended Channel switching to new country. @@ -367,7 +526,7 @@ populate_dot11f_chan_switch_wrapper(struct mac_context *mac, &pDot11f->transmit_power_env, pe_session->gLimChannelSwitch.ch_width, pe_session->gLimChannelSwitch.sw_target_freq, - NULL, true); + &num_tpe, true); } }