From: Sriram R srirrama@codeaurora.org
[ Upstream commit 69a0fcf8a9f2273040d03e5ee77c9689c09e9d3a ]
During firmware recovery, the default reg rules which are received via WMI_REG_CHAN_LIST_CC_EVENT can overwrite the currently configured user regd.
See below snap for example,
root@OpenWrt:/# iw reg get | grep country country FR: DFS-ETSI country FR: DFS-ETSI country FR: DFS-ETSI country FR: DFS-ETSI
root@OpenWrt:/# echo assert > /sys/kernel/debug/ath11k/ipq8074\ hw2.0/simulate_f w_crash <snip> [ 5290.471696] ath11k c000000.wifi1: pdev 1 successfully recovered
root@OpenWrt:/# iw reg get | grep country country FR: DFS-ETSI country US: DFS-FCC country US: DFS-FCC country US: DFS-FCC
In the above, the user configured country 'FR' is overwritten when the rules of default country 'US' are received and updated during recovery. Hence avoid processing of these rules in general during firmware recovery as they have been already applied during driver registration or after last set user country is configured.
This scenario applies for both AP and STA devices basically because cfg80211 is not aware of the recovery and only the driver recovers, but changing or resetting of the reg domain during recovery is not needed so as to continue with the configured regdomain currently in use.
Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.4.0.1-01460-QCAHKSWPL_SILICONZ-1
Signed-off-by: Sriram R srirrama@codeaurora.org Signed-off-by: Jouni Malinen jouni@codeaurora.org Signed-off-by: Kalle Valo kvalo@codeaurora.org Link: https://lore.kernel.org/r/20210721212029.142388-3-jouni@codeaurora.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/ath/ath11k/wmi.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c index fca71e00123d9..2f777d61f9065 100644 --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -5362,6 +5362,17 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
pdev_idx = reg_info->phy_id;
+ /* Avoid default reg rule updates sent during FW recovery if + * it is already available + */ + spin_lock(&ab->base_lock); + if (test_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags) && + ab->default_regd[pdev_idx]) { + spin_unlock(&ab->base_lock); + goto mem_free; + } + spin_unlock(&ab->base_lock); + if (pdev_idx >= ab->num_radios) { /* Process the event for phy0 only if single_pdev_only * is true. If pdev_idx is valid but not 0, discard the