Message ID | 20250408042128.720263-3-quic_rajson@quicinc.com |
---|---|
State | New |
Headers | show |
Series | wifi: ath12k: Properly update frequency range | expand |
On 4/8/2025 9:51 AM, Rajat Soni wrote: > From: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> > > During the initial WMI exchange, the firmware updates the > hardware-supported start and end frequencies in the > ath12k_wmi_hal_reg_capabilities_ext_arg structure. These frequencies, > being hardware-supported, may not always align with the current > regulatory operating frequencies. When operating as multiple grouped > hardwares under a single wiphy, the driver advertises these values > directly to the upper layer in the per-radio frequency range, > which can be misleading. > > Sample output snippet from iw phyX info command - > > [..] > Supported wiphy radios: > * Idx 0: > Frequency Range: 2312 MHz - 2732 MHz > [..] > > * Idx 1: > Frequency Range: 5150 MHz - 5330 MHz > [..] > [..] > > The frequency range displayed above is incorrect because the driver > directly advertises the hardware-supported values to the upper layer. > > The driver is aware of the current operating regulatory rules, and > hence it can use this information to determine the final operating > start and end frequencies. > > To resolve this issue, add support to store the start and end > frequencies received during the regulatory update event. > Then, intersect these with the hardware-supported start and > end frequencies, and finally, advertise the intersected values to the > upper layer. > > Sample output snippet from iw phyX info command after the fix - > > [..] > Supported wiphy radios: > * Idx 0: > Frequency Range: 2402 MHz - 2472 MHz > [..] > > * Idx 1: > Frequency Range: 5170 MHz - 5330 MHz > [..] > [..] > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 > > Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> > Co-developed-by: Rajat Soni <quic_rajson@quicinc.com> > Signed-off-by: Rajat Soni <quic_rajson@quicinc.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
On 4/8/2025 9:51 AM, Rajat Soni wrote: > From: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> > > During the initial WMI exchange, the firmware updates the > hardware-supported start and end frequencies in the > ath12k_wmi_hal_reg_capabilities_ext_arg structure. These frequencies, > being hardware-supported, may not always align with the current > regulatory operating frequencies. When operating as multiple grouped > hardwares under a single wiphy, the driver advertises these values > directly to the upper layer in the per-radio frequency range, > which can be misleading. > > Sample output snippet from iw phyX info command - > > [..] > Supported wiphy radios: > * Idx 0: > Frequency Range: 2312 MHz - 2732 MHz > [..] > > * Idx 1: > Frequency Range: 5150 MHz - 5330 MHz > [..] > [..] > > The frequency range displayed above is incorrect because the driver > directly advertises the hardware-supported values to the upper layer. > > The driver is aware of the current operating regulatory rules, and > hence it can use this information to determine the final operating > start and end frequencies. > > To resolve this issue, add support to store the start and end > frequencies received during the regulatory update event. > Then, intersect these with the hardware-supported start and > end frequencies, and finally, advertise the intersected values to the > upper layer. > > Sample output snippet from iw phyX info command after the fix - > > [..] > Supported wiphy radios: > * Idx 0: > Frequency Range: 2402 MHz - 2472 MHz > [..] > > * Idx 1: > Frequency Range: 5170 MHz - 5330 MHz > [..] > [..] > > Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00199-QCAHKSWPL_SILICONZ-1 > Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 > > Signed-off-by: Aditya Kumar Singh <aditya.kumar.singh@oss.qualcomm.com> > Co-developed-by: Rajat Soni <quic_rajson@quicinc.com> > Signed-off-by: Rajat Soni <quic_rajson@quicinc.com> > --- > drivers/net/wireless/ath/ath12k/core.h | 9 ++++++ > drivers/net/wireless/ath/ath12k/mac.c | 39 ++++++++++++++++++-------- > drivers/net/wireless/ath/ath12k/reg.c | 13 +++++++++ > 3 files changed, 49 insertions(+), 12 deletions(-) > You may need to rebase the series Applying: wifi: ath12k: Add helper function ath12k_mac_update_freq_range() Applying: wifi: ath12k: Fix frequency range in driver error: patch failed: drivers/net/wireless/ath/ath12k/core.h:1122 error: drivers/net/wireless/ath/ath12k/core.h: patch does not apply Patch failed at 0002 wifi: ath12k: Fix frequency range in driver
On 4/15/2025 9:09 PM, Vasanthakumar Thiagarajan wrote: > You may need to rebase the series > > Applying: wifi: ath12k: Add helper function ath12k_mac_update_freq_range() > Applying: wifi: ath12k: Fix frequency range in driver > error: patch failed: drivers/net/wireless/ath/ath12k/core.h:1122 > error: drivers/net/wireless/ath/ath12k/core.h: patch does not apply > Patch failed at 0002 wifi: ath12k: Fix frequency range in driver It applied to my 'pending' branch with: b4 am --prep-3way ... git am -3 ... /jeff
On 4/16/2025 8:12 PM, Jeff Johnson wrote: > On 4/15/2025 9:09 PM, Vasanthakumar Thiagarajan wrote: >> You may need to rebase the series >> >> Applying: wifi: ath12k: Add helper function ath12k_mac_update_freq_range() >> Applying: wifi: ath12k: Fix frequency range in driver >> error: patch failed: drivers/net/wireless/ath/ath12k/core.h:1122 >> error: drivers/net/wireless/ath/ath12k/core.h: patch does not apply >> Patch failed at 0002 wifi: ath12k: Fix frequency range in driver > > It applied to my 'pending' branch with: > b4 am --prep-3way ... > git am -3 ... > Ok. I was trying them on main branch. I'll use pending branch for such checks. Thanks.
diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h index e8d2a0c859f6..8099a5f54e83 100644 --- a/drivers/net/wireless/ath/ath12k/core.h +++ b/drivers/net/wireless/ath/ath12k/core.h @@ -880,6 +880,11 @@ struct ath12k_soc_dp_stats { struct ath12k_soc_dp_tx_err_stats tx_err; }; +struct ath12k_reg_freq { + u32 start_freq; + u32 end_freq; +}; + struct ath12k_mlo_memory { struct target_mem_chunk chunk[ATH12K_QMI_WLANFW_MAX_NUM_MEM_SEG_V01]; int mlo_mem_size; @@ -1122,6 +1127,10 @@ struct ath12k_base { enum ath12k_firmware_mode fw_mode; struct ath12k_ftm_event_obj ftm_event_obj; + struct ath12k_reg_freq reg_freq_2ghz; + struct ath12k_reg_freq reg_freq_5ghz; + struct ath12k_reg_freq reg_freq_6ghz; + /* must be last */ u8 drv_priv[] __aligned(sizeof(void *)); }; diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index 449aca719ad3..8c971a58fb6f 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -10859,16 +10859,17 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar, { struct ieee80211_supported_band *band; struct ath12k_wmi_hal_reg_capabilities_ext_arg *reg_cap; + struct ath12k_base *ab = ar->ab; + u32 phy_id, freq_low, freq_high; struct ath12k_hw *ah = ar->ah; void *channels; - u32 phy_id; BUILD_BUG_ON((ARRAY_SIZE(ath12k_2ghz_channels) + ARRAY_SIZE(ath12k_5ghz_channels) + ARRAY_SIZE(ath12k_6ghz_channels)) != ATH12K_NUM_CHANS); - reg_cap = &ar->ab->hal_reg_cap[ar->pdev_idx]; + reg_cap = &ab->hal_reg_cap[ar->pdev_idx]; if (supported_bands & WMI_HOST_WLAN_2GHZ_CAP) { channels = kmemdup(ath12k_2ghz_channels, @@ -10885,16 +10886,21 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar, band->bitrates = ath12k_g_rates; bands[NL80211_BAND_2GHZ] = band; - if (ar->ab->hw_params->single_pdev_only) { + if (ab->hw_params->single_pdev_only) { phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_2GHZ_CAP); - reg_cap = &ar->ab->hal_reg_cap[phy_id]; + reg_cap = &ab->hal_reg_cap[phy_id]; } + + freq_low = max(reg_cap->low_2ghz_chan, + ab->reg_freq_2ghz.start_freq); + freq_high = min(reg_cap->high_2ghz_chan, + ab->reg_freq_2ghz.end_freq); + ath12k_mac_update_ch_list(ar, band, reg_cap->low_2ghz_chan, reg_cap->high_2ghz_chan); - ath12k_mac_update_freq_range(ar, reg_cap->low_2ghz_chan, - reg_cap->high_2ghz_chan); + ath12k_mac_update_freq_range(ar, freq_low, freq_high); } if (supported_bands & WMI_HOST_WLAN_5GHZ_CAP) { @@ -10914,12 +10920,17 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar, band->n_bitrates = ath12k_a_rates_size; band->bitrates = ath12k_a_rates; bands[NL80211_BAND_6GHZ] = band; + + freq_low = max(reg_cap->low_5ghz_chan, + ab->reg_freq_6ghz.start_freq); + freq_high = min(reg_cap->high_5ghz_chan, + ab->reg_freq_6ghz.end_freq); + ath12k_mac_update_ch_list(ar, band, reg_cap->low_5ghz_chan, reg_cap->high_5ghz_chan); - ath12k_mac_update_freq_range(ar, reg_cap->low_5ghz_chan, - reg_cap->high_5ghz_chan); + ath12k_mac_update_freq_range(ar, freq_low, freq_high); ah->use_6ghz_regd = true; } @@ -10941,17 +10952,21 @@ static int ath12k_mac_setup_channels_rates(struct ath12k *ar, band->bitrates = ath12k_a_rates; bands[NL80211_BAND_5GHZ] = band; - if (ar->ab->hw_params->single_pdev_only) { + if (ab->hw_params->single_pdev_only) { phy_id = ath12k_get_phy_id(ar, WMI_HOST_WLAN_5GHZ_CAP); - reg_cap = &ar->ab->hal_reg_cap[phy_id]; + reg_cap = &ab->hal_reg_cap[phy_id]; } + freq_low = max(reg_cap->low_5ghz_chan, + ab->reg_freq_5ghz.start_freq); + freq_high = min(reg_cap->high_5ghz_chan, + ab->reg_freq_5ghz.end_freq); + ath12k_mac_update_ch_list(ar, band, reg_cap->low_5ghz_chan, reg_cap->high_5ghz_chan); - ath12k_mac_update_freq_range(ar, reg_cap->low_5ghz_chan, - reg_cap->high_5ghz_chan); + ath12k_mac_update_freq_range(ar, freq_low, freq_high); } } diff --git a/drivers/net/wireless/ath/ath12k/reg.c b/drivers/net/wireless/ath/ath12k/reg.c index 893650f76fb2..e1007b878f91 100644 --- a/drivers/net/wireless/ath/ath12k/reg.c +++ b/drivers/net/wireless/ath/ath12k/reg.c @@ -651,6 +651,16 @@ ath12k_reg_update_weather_radar_band(struct ath12k_base *ab, *rule_idx = i; } +static void ath12k_reg_update_freq_range(struct ath12k_reg_freq *reg_freq, + struct ath12k_reg_rule *reg_rule) +{ + if (reg_freq->start_freq > reg_rule->start_freq) + reg_freq->start_freq = reg_rule->start_freq; + + if (reg_freq->end_freq < reg_rule->end_freq) + reg_freq->end_freq = reg_rule->end_freq; +} + struct ieee80211_regdomain * ath12k_reg_build_regd(struct ath12k_base *ab, struct ath12k_reg_info *reg_info, bool intersect) @@ -704,6 +714,7 @@ ath12k_reg_build_regd(struct ath12k_base *ab, max_bw = min_t(u16, reg_rule->max_bw, reg_info->max_bw_2g); flags = 0; + ath12k_reg_update_freq_range(&ab->reg_freq_2ghz, reg_rule); } else if (reg_info->num_5g_reg_rules && (j < reg_info->num_5g_reg_rules)) { reg_rule = reg_info->reg_rules_5g_ptr + j++; @@ -717,6 +728,7 @@ ath12k_reg_build_regd(struct ath12k_base *ab, * per other BW rule flags we pass from here */ flags = NL80211_RRF_AUTO_BW; + ath12k_reg_update_freq_range(&ab->reg_freq_5ghz, reg_rule); } else if (reg_info->is_ext_reg_event && reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP] && (k < reg_info->num_6g_reg_rules_ap[WMI_REG_INDOOR_AP])) { @@ -724,6 +736,7 @@ ath12k_reg_build_regd(struct ath12k_base *ab, max_bw = min_t(u16, reg_rule->max_bw, reg_info->max_bw_6g_ap[WMI_REG_INDOOR_AP]); flags = NL80211_RRF_AUTO_BW; + ath12k_reg_update_freq_range(&ab->reg_freq_6ghz, reg_rule); } else { break; }