@@ -7667,6 +7667,290 @@ static u8 ath11k_mac_get_num_pwr_levels(struct cfg80211_chan_def *chan_def)
76677667 }
76687668}
76697669
7670+ static u16 ath11k_mac_get_6ghz_start_frequency (struct cfg80211_chan_def * chan_def )
7671+ {
7672+ u16 diff_seq ;
7673+
7674+ /* It is to get the lowest channel number's center frequency of the chan.
7675+ * For example,
7676+ * bandwidth=40 MHz, center frequency is 5965, lowest channel is 1
7677+ * with center frequency 5955, its diff is 5965 - 5955 = 10.
7678+ * bandwidth=80 MHz, center frequency is 5985, lowest channel is 1
7679+ * with center frequency 5955, its diff is 5985 - 5955 = 30.
7680+ * bandwidth=160 MHz, center frequency is 6025, lowest channel is 1
7681+ * with center frequency 5955, its diff is 6025 - 5955 = 70.
7682+ */
7683+ switch (chan_def -> width ) {
7684+ case NL80211_CHAN_WIDTH_160 :
7685+ diff_seq = 70 ;
7686+ break ;
7687+ case NL80211_CHAN_WIDTH_80 :
7688+ case NL80211_CHAN_WIDTH_80P80 :
7689+ diff_seq = 30 ;
7690+ break ;
7691+ case NL80211_CHAN_WIDTH_40 :
7692+ diff_seq = 10 ;
7693+ break ;
7694+ default :
7695+ diff_seq = 0 ;
7696+ }
7697+
7698+ return chan_def -> center_freq1 - diff_seq ;
7699+ }
7700+
7701+ static u16 ath11k_mac_get_seg_freq (struct cfg80211_chan_def * chan_def ,
7702+ u16 start_seq , u8 seq )
7703+ {
7704+ u16 seg_seq ;
7705+
7706+ /* It is to get the center frequency of the specific bandwidth.
7707+ * start_seq means the lowest channel number's center frequency.
7708+ * seq 0/1/2/3 means 20 MHz/40 MHz/80 MHz/160 MHz&80P80.
7709+ * For example,
7710+ * lowest channel is 1, its center frequency 5955,
7711+ * center frequency is 5955 when bandwidth=20 MHz, its diff is 5955 - 5955 = 0.
7712+ * lowest channel is 1, its center frequency 5955,
7713+ * center frequency is 5965 when bandwidth=40 MHz, its diff is 5965 - 5955 = 10.
7714+ * lowest channel is 1, its center frequency 5955,
7715+ * center frequency is 5985 when bandwidth=80 MHz, its diff is 5985 - 5955 = 30.
7716+ * lowest channel is 1, its center frequency 5955,
7717+ * center frequency is 6025 when bandwidth=160 MHz, its diff is 6025 - 5955 = 70.
7718+ */
7719+ if (chan_def -> width == NL80211_CHAN_WIDTH_80P80 && seq == 3 )
7720+ return chan_def -> center_freq2 ;
7721+
7722+ seg_seq = 10 * (BIT (seq ) - 1 );
7723+ return seg_seq + start_seq ;
7724+ }
7725+
7726+ static void ath11k_mac_get_psd_channel (struct ath11k * ar ,
7727+ u16 step_freq ,
7728+ u16 * start_freq ,
7729+ u16 * center_freq ,
7730+ u8 i ,
7731+ struct ieee80211_channel * * temp_chan ,
7732+ s8 * tx_power )
7733+ {
7734+ /* It is to get the center frequency for each 20 MHz.
7735+ * For example, if the chan is 160 MHz and center frequency is 6025,
7736+ * then it include 8 channels, they are 1/5/9/13/17/21/25/29,
7737+ * channel number 1's center frequency is 5955, it is parameter start_freq.
7738+ * parameter i is the step of the 8 channels. i is 0~7 for the 8 channels.
7739+ * the channel 1/5/9/13/17/21/25/29 maps i=0/1/2/3/4/5/6/7,
7740+ * and maps its center frequency is 5955/5975/5995/6015/6035/6055/6075/6095,
7741+ * the gap is 20 for each channel, parameter step_freq means the gap.
7742+ * after get the center frequency of each channel, it is easy to find the
7743+ * struct ieee80211_channel of it and get the max_reg_power.
7744+ */
7745+ * center_freq = * start_freq + i * step_freq ;
7746+ * temp_chan = ieee80211_get_channel (ar -> hw -> wiphy , * center_freq );
7747+ * tx_power = (* temp_chan )-> max_reg_power ;
7748+ }
7749+
7750+ static void ath11k_mac_get_eirp_power (struct ath11k * ar ,
7751+ u16 * start_freq ,
7752+ u16 * center_freq ,
7753+ u8 i ,
7754+ struct ieee80211_channel * * temp_chan ,
7755+ struct cfg80211_chan_def * def ,
7756+ s8 * tx_power )
7757+ {
7758+ /* It is to get the center frequency for 20 MHz/40 MHz/80 MHz/
7759+ * 160 MHz&80P80 bandwidth, and then plus 10 to the center frequency,
7760+ * it is the center frequency of a channel number.
7761+ * For example, when configured channel number is 1.
7762+ * center frequency is 5965 when bandwidth=40 MHz, after plus 10, it is 5975,
7763+ * then it is channel number 5.
7764+ * center frequency is 5985 when bandwidth=80 MHz, after plus 10, it is 5995,
7765+ * then it is channel number 9.
7766+ * center frequency is 6025 when bandwidth=160 MHz, after plus 10, it is 6035,
7767+ * then it is channel number 17.
7768+ * after get the center frequency of each channel, it is easy to find the
7769+ * struct ieee80211_channel of it and get the max_reg_power.
7770+ */
7771+ * center_freq = ath11k_mac_get_seg_freq (def , * start_freq , i );
7772+
7773+ /* For the 20 MHz, its center frequency is same with same channel */
7774+ if (i != 0 )
7775+ * center_freq += 10 ;
7776+
7777+ * temp_chan = ieee80211_get_channel (ar -> hw -> wiphy , * center_freq );
7778+ * tx_power = (* temp_chan )-> max_reg_power ;
7779+ }
7780+
7781+ void ath11k_mac_fill_reg_tpc_info (struct ath11k * ar ,
7782+ struct ieee80211_vif * vif ,
7783+ struct ieee80211_chanctx_conf * ctx )
7784+ {
7785+ struct ath11k_base * ab = ar -> ab ;
7786+ struct ath11k_vif * arvif = (void * )vif -> drv_priv ;
7787+ struct ieee80211_bss_conf * bss_conf = & vif -> bss_conf ;
7788+ struct ath11k_reg_tpc_power_info * reg_tpc_info = & arvif -> reg_tpc_info ;
7789+ struct ieee80211_channel * chan , * temp_chan ;
7790+ u8 pwr_lvl_idx , num_pwr_levels , pwr_reduction ;
7791+ bool is_psd_power = false, is_tpe_present = false;
7792+ s8 max_tx_power [IEEE80211_MAX_NUM_PWR_LEVEL ],
7793+ psd_power , tx_power , eirp_power ;
7794+ u16 start_freq , center_freq ;
7795+
7796+ chan = ctx -> def .chan ;
7797+ start_freq = ath11k_mac_get_6ghz_start_frequency (& ctx -> def );
7798+ pwr_reduction = bss_conf -> pwr_reduction ;
7799+
7800+ if (arvif -> reg_tpc_info .num_pwr_levels ) {
7801+ is_tpe_present = true;
7802+ num_pwr_levels = arvif -> reg_tpc_info .num_pwr_levels ;
7803+ } else {
7804+ num_pwr_levels = ath11k_mac_get_num_pwr_levels (& ctx -> def );
7805+ }
7806+
7807+ for (pwr_lvl_idx = 0 ; pwr_lvl_idx < num_pwr_levels ; pwr_lvl_idx ++ ) {
7808+ /* STA received TPE IE*/
7809+ if (is_tpe_present ) {
7810+ /* local power is PSD power*/
7811+ if (chan -> flags & IEEE80211_CHAN_PSD ) {
7812+ /* Connecting AP is psd power */
7813+ if (reg_tpc_info -> is_psd_power ) {
7814+ is_psd_power = true;
7815+ ath11k_mac_get_psd_channel (ar , 20 ,
7816+ & start_freq ,
7817+ & center_freq ,
7818+ pwr_lvl_idx ,
7819+ & temp_chan ,
7820+ & tx_power );
7821+ psd_power = temp_chan -> psd ;
7822+ eirp_power = tx_power ;
7823+ max_tx_power [pwr_lvl_idx ] =
7824+ min_t (s8 ,
7825+ psd_power ,
7826+ reg_tpc_info -> tpe [pwr_lvl_idx ]);
7827+ /* Connecting AP is not psd power */
7828+ } else {
7829+ ath11k_mac_get_eirp_power (ar ,
7830+ & start_freq ,
7831+ & center_freq ,
7832+ pwr_lvl_idx ,
7833+ & temp_chan ,
7834+ & ctx -> def ,
7835+ & tx_power );
7836+ psd_power = temp_chan -> psd ;
7837+ /* convert psd power to EIRP power based
7838+ * on channel width
7839+ */
7840+ tx_power =
7841+ min_t (s8 , tx_power ,
7842+ psd_power + 13 + pwr_lvl_idx * 3 );
7843+ max_tx_power [pwr_lvl_idx ] =
7844+ min_t (s8 ,
7845+ tx_power ,
7846+ reg_tpc_info -> tpe [pwr_lvl_idx ]);
7847+ }
7848+ /* local power is not PSD power */
7849+ } else {
7850+ /* Connecting AP is psd power */
7851+ if (reg_tpc_info -> is_psd_power ) {
7852+ is_psd_power = true;
7853+ ath11k_mac_get_psd_channel (ar , 20 ,
7854+ & start_freq ,
7855+ & center_freq ,
7856+ pwr_lvl_idx ,
7857+ & temp_chan ,
7858+ & tx_power );
7859+ eirp_power = tx_power ;
7860+ max_tx_power [pwr_lvl_idx ] =
7861+ reg_tpc_info -> tpe [pwr_lvl_idx ];
7862+ /* Connecting AP is not psd power */
7863+ } else {
7864+ ath11k_mac_get_eirp_power (ar ,
7865+ & start_freq ,
7866+ & center_freq ,
7867+ pwr_lvl_idx ,
7868+ & temp_chan ,
7869+ & ctx -> def ,
7870+ & tx_power );
7871+ max_tx_power [pwr_lvl_idx ] =
7872+ min_t (s8 ,
7873+ tx_power ,
7874+ reg_tpc_info -> tpe [pwr_lvl_idx ]);
7875+ }
7876+ }
7877+ /* STA not received TPE IE */
7878+ } else {
7879+ /* local power is PSD power*/
7880+ if (chan -> flags & IEEE80211_CHAN_PSD ) {
7881+ is_psd_power = true;
7882+ ath11k_mac_get_psd_channel (ar , 20 ,
7883+ & start_freq ,
7884+ & center_freq ,
7885+ pwr_lvl_idx ,
7886+ & temp_chan ,
7887+ & tx_power );
7888+ psd_power = temp_chan -> psd ;
7889+ eirp_power = tx_power ;
7890+ max_tx_power [pwr_lvl_idx ] = psd_power ;
7891+ } else {
7892+ ath11k_mac_get_eirp_power (ar ,
7893+ & start_freq ,
7894+ & center_freq ,
7895+ pwr_lvl_idx ,
7896+ & temp_chan ,
7897+ & ctx -> def ,
7898+ & tx_power );
7899+ max_tx_power [pwr_lvl_idx ] = tx_power ;
7900+ }
7901+ }
7902+
7903+ if (is_psd_power ) {
7904+ /* If AP local power constraint is present */
7905+ if (pwr_reduction )
7906+ eirp_power = eirp_power - pwr_reduction ;
7907+
7908+ /* If firmware updated max tx power is non zero, then take
7909+ * the min of firmware updated ap tx power
7910+ * and max power derived from above mentioned parameters.
7911+ */
7912+ ath11k_dbg (ab , ATH11K_DBG_MAC ,
7913+ "eirp power : %d firmware report power : %d\n" ,
7914+ eirp_power , ar -> max_allowed_tx_power );
7915+ /* Firmware reports lower max_allowed_tx_power during vdev
7916+ * start response. In case of 6 GHz, firmware is not aware
7917+ * of EIRP power unless driver sets EIRP power through WMI
7918+ * TPC command. So radio which does not support idle power
7919+ * save can set maximum calculated EIRP power directly to
7920+ * firmware through TPC command without min comparison with
7921+ * vdev start response's max_allowed_tx_power.
7922+ */
7923+ if (ar -> max_allowed_tx_power && ab -> hw_params .idle_ps )
7924+ eirp_power = min_t (s8 ,
7925+ eirp_power ,
7926+ ar -> max_allowed_tx_power );
7927+ } else {
7928+ /* If AP local power constraint is present */
7929+ if (pwr_reduction )
7930+ max_tx_power [pwr_lvl_idx ] =
7931+ max_tx_power [pwr_lvl_idx ] - pwr_reduction ;
7932+ /* If firmware updated max tx power is non zero, then take
7933+ * the min of firmware updated ap tx power
7934+ * and max power derived from above mentioned parameters.
7935+ */
7936+ if (ar -> max_allowed_tx_power && ab -> hw_params .idle_ps )
7937+ max_tx_power [pwr_lvl_idx ] =
7938+ min_t (s8 ,
7939+ max_tx_power [pwr_lvl_idx ],
7940+ ar -> max_allowed_tx_power );
7941+ }
7942+ reg_tpc_info -> chan_power_info [pwr_lvl_idx ].chan_cfreq = center_freq ;
7943+ reg_tpc_info -> chan_power_info [pwr_lvl_idx ].tx_power =
7944+ max_tx_power [pwr_lvl_idx ];
7945+ }
7946+
7947+ reg_tpc_info -> num_pwr_levels = num_pwr_levels ;
7948+ reg_tpc_info -> is_psd_power = is_psd_power ;
7949+ reg_tpc_info -> eirp_power = eirp_power ;
7950+ reg_tpc_info -> ap_power_type =
7951+ ath11k_reg_ap_pwr_convert (vif -> bss_conf .power_type );
7952+ }
7953+
76707954static void ath11k_mac_parse_tx_pwr_env (struct ath11k * ar ,
76717955 struct ieee80211_vif * vif ,
76727956 struct ieee80211_chanctx_conf * ctx )
0 commit comments