|
@@ -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;
|
|
|
-
|
|
|
- if (!is_ch_switch)
|
|
|
- *num_tpe = 1;
|
|
|
+ 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 (!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;
|
|
|
+ max_tx_pwr_count = 0;
|
|
|
+ max_tx_pwr_count_psd = 1;
|
|
|
+ num_tx_power = 1;
|
|
|
+ num_tx_power_psd = 1;
|
|
|
break;
|
|
|
+
|
|
|
case CH_WIDTH_40MHZ:
|
|
|
- /* Max Transmit Power count = 1 (20, 40 MHz) */
|
|
|
- num_tx_power = 1;
|
|
|
+ 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 Transmit Power count = 2 (20, 40, and 80 MHz) */
|
|
|
- num_tx_power = 2;
|
|
|
+ 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);
|
|
|
}
|
|
|
}
|
|
|
|