]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath11k: support DBS and DFS compatibility
authorYu Zhang(Yuriy) <quic_yuzha@quicinc.com>
Wed, 27 Nov 2024 02:27:42 +0000 (10:27 +0800)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Fri, 16 May 2025 18:32:10 +0000 (11:32 -0700)
Now some chips which support 'support_dual_stations' will enable DBS,
but will disable DFS. Restructure the ath11k_mac_setup_iface_combinations
function to support DBS and DFS compatibility.

About 'support_dual_station' feature can refer:
https://msgid.link/20230714023801.2621802-2-quic_cjhuang@quicinc.com

Add a ieee80211_iface_combination to support DBS and DFS compatibility,
one combination can support DFS(same with non dual sta), another
combination can support DBS. When running different scenarios that will
use different ieee80211_iface_combination due to mac80211 will go through
all of possible interface combinations.

In addition, maximum number of interfaces of these types should be total
allowed in this group.

The chips affected are:

 QCA6390 hw2.0
 WCN6855 hw2.0
 WCN6855 hw2.1

Other chips are not affected.

Tested-on: IPQ8074 hw2.0 AHB WLAN.HK.2.1.0.1-00410-QCAHKSWPL_SILICONZ-2
Tested-on: IPQ6018 hw1.0 AHB WLAN.HK.2.1.0.1-01161-QCAHKSWPL_SILICONZ-1
Tested-on: WCN6855 hw2.1 PCI WLAN.HSP.1.1-04402-QCAHSPSWPL_V1_V2_SILICONZ_IOE-1.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-05266-QCAHSTSWPLZ_V2_TO_X86-1

Signed-off-by: Yu Zhang (Yuriy) <quic_yuzha@quicinc.com>
Reviewed-by: Baochen Qiang <quic_bqiang@quicinc.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
Tested-by: Mihai Moldovan <ionic@ionic.de>
Link: https://patch.msgid.link/20241127022742.4016870-1-quic_yuzha@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath11k/mac.c

index 8191ee14a1fd18f6f1d67b0f5a8bbef3606f212b..08d7b136851fabb0a1c1032abcf9c01550e9f4f5 100644 (file)
@@ -9972,12 +9972,17 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
        struct ath11k_base *ab = ar->ab;
        struct ieee80211_iface_combination *combinations;
        struct ieee80211_iface_limit *limits;
-       int n_limits;
+       int n_limits, n_combos;
        bool p2p;
 
        p2p = ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_P2P_DEVICE);
 
-       combinations = kzalloc(sizeof(*combinations), GFP_KERNEL);
+       if (ab->hw_params.support_dual_stations)
+               n_combos = 2;
+       else
+               n_combos = 1;
+
+       combinations = kcalloc(n_combos, sizeof(*combinations), GFP_KERNEL);
        if (!combinations)
                return -ENOMEM;
 
@@ -9992,7 +9997,9 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
                return -ENOMEM;
        }
 
+       limits[0].max = 1;
        limits[0].types |= BIT(NL80211_IFTYPE_STATION);
+       limits[1].max = 16;
        limits[1].types |= BIT(NL80211_IFTYPE_AP);
        if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
            ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
@@ -10002,25 +10009,24 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
        combinations[0].n_limits = n_limits;
        combinations[0].beacon_int_infra_match = true;
        combinations[0].beacon_int_min_gcd = 100;
+       combinations[0].max_interfaces = 16;
+       combinations[0].num_different_channels = 1;
+       combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
+                                               BIT(NL80211_CHAN_WIDTH_20) |
+                                               BIT(NL80211_CHAN_WIDTH_40) |
+                                               BIT(NL80211_CHAN_WIDTH_80) |
+                                               BIT(NL80211_CHAN_WIDTH_80P80) |
+                                               BIT(NL80211_CHAN_WIDTH_160);
 
        if (ab->hw_params.support_dual_stations) {
                limits[0].max = 2;
-               limits[1].max = 1;
-
-               combinations[0].max_interfaces = ab->hw_params.num_vdevs;
-               combinations[0].num_different_channels = 2;
-       } else {
-               limits[0].max = 1;
-               limits[1].max = 16;
 
-               combinations[0].max_interfaces = 16;
-               combinations[0].num_different_channels = 1;
-               combinations[0].radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
-                                                       BIT(NL80211_CHAN_WIDTH_20) |
-                                                       BIT(NL80211_CHAN_WIDTH_40) |
-                                                       BIT(NL80211_CHAN_WIDTH_80) |
-                                                       BIT(NL80211_CHAN_WIDTH_80P80) |
-                                                       BIT(NL80211_CHAN_WIDTH_160);
+               combinations[1].limits = limits;
+               combinations[1].n_limits = n_limits;
+               combinations[1].beacon_int_infra_match = true;
+               combinations[1].beacon_int_min_gcd = 100;
+               combinations[1].max_interfaces = ab->hw_params.num_vdevs;
+               combinations[1].num_different_channels = 2;
        }
 
        if (p2p) {
@@ -10031,7 +10037,7 @@ static int ath11k_mac_setup_iface_combinations(struct ath11k *ar)
        }
 
        ar->hw->wiphy->iface_combinations = combinations;
-       ar->hw->wiphy->n_iface_combinations = 1;
+       ar->hw->wiphy->n_iface_combinations = n_combos;
 
        return 0;
 }