wifi: ath11k: support 2 station interfaces
authorCarl Huang <quic_cjhuang@quicinc.com>
Wed, 14 Feb 2024 08:38:10 +0000 (10:38 +0200)
committerKalle Valo <quic_kvalo@quicinc.com>
Thu, 15 Feb 2024 11:22:46 +0000 (13:22 +0200)
Add hardware parameter support_dual_stations to indicate whether 2 station
interfaces are supported. For chips which support this feature, limit total
number of AP interface and mesh point to 1. The max interfaces are 3 for such
chips.

The chips affected are:

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

Other chips are not affected.

For affected chips, remove radar_detect_widths because now
num_different_channels is set to 2. radar_detect_widths can be set only when
num_different_channels is 1, see mac80211 function wiphy_verify_combinations
for details. This means that in affectected chips DFS cannot be enabled in AP
mode.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3

Signed-off-by: Carl Huang <quic_cjhuang@quicinc.com>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://msgid.link/20230714023801.2621802-2-quic_cjhuang@quicinc.com
drivers/net/wireless/ath/ath11k/core.c
drivers/net/wireless/ath/ath11k/hw.c
drivers/net/wireless/ath/ath11k/hw.h
drivers/net/wireless/ath/ath11k/mac.c

index 0c6ecbb9a0661cbd2bff2aa3c5239820ef8a6c0d..3c1ba8fd28f47c2aecd25526aef6305a1ebcbc52 100644 (file)
@@ -122,6 +122,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tcl_ring_retry = true,
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
+               .support_dual_stations = false,
        },
        {
                .hw_rev = ATH11K_HW_IPQ6018_HW10,
@@ -205,6 +206,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = false,
+               .support_dual_stations = false,
        },
        {
                .name = "qca6390 hw2.0",
@@ -255,7 +257,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .coldboot_cal_ftm = false,
                .cbcal_restart_fw = false,
                .fw_mem_mode = 0,
-               .num_vdevs = 16 + 1,
+               .num_vdevs = 2 + 1,
                .num_peers = 512,
                .supports_suspend = true,
                .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
@@ -290,6 +292,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = true,
+               .support_dual_stations = true,
        },
        {
                .name = "qcn9074 hw1.0",
@@ -372,6 +375,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = false,
+               .support_dual_stations = false,
        },
        {
                .name = "wcn6855 hw2.0",
@@ -422,7 +426,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .coldboot_cal_ftm = false,
                .cbcal_restart_fw = false,
                .fw_mem_mode = 0,
-               .num_vdevs = 16 + 1,
+               .num_vdevs = 2 + 1,
                .num_peers = 512,
                .supports_suspend = true,
                .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
@@ -457,6 +461,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = true,
+               .support_dual_stations = true,
        },
        {
                .name = "wcn6855 hw2.1",
@@ -505,7 +510,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .coldboot_cal_ftm = false,
                .cbcal_restart_fw = false,
                .fw_mem_mode = 0,
-               .num_vdevs = 16 + 1,
+               .num_vdevs = 2 + 1,
                .num_peers = 512,
                .supports_suspend = true,
                .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855),
@@ -540,6 +545,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = true,
+               .support_dual_stations = true,
        },
        {
                .name = "wcn6750 hw1.0",
@@ -621,6 +627,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE_WCN6750,
                .smp2p_wow_exit = true,
                .support_fw_mac_sequence = true,
+               .support_dual_stations = false,
        },
        {
                .hw_rev = ATH11K_HW_IPQ5018_HW10,
@@ -702,6 +709,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
                .tx_ring_size = DP_TCL_DATA_RING_SIZE,
                .smp2p_wow_exit = false,
                .support_fw_mac_sequence = false,
+               .support_dual_stations = false,
        },
 };
 
index 77d8f9237680b28868d411d3fd1f39703e3ba164..caa6dc12a790b5072d5453ac123a604cf440a20a 100644 (file)
@@ -58,7 +58,7 @@ static void ath11k_hw_wcn6855_tx_mesh_enable(struct ath11k_base *ab,
 static void ath11k_init_wmi_config_qca6390(struct ath11k_base *ab,
                                           struct target_resource_config *config)
 {
-       config->num_vdevs = 4;
+       config->num_vdevs = ab->hw_params.num_vdevs;
        config->num_peers = 16;
        config->num_tids = 32;
 
index 1b070747a5dbfe082ff27ad283672d8dd506582b..14ef4eb48f807dede8da4f43d63547a1795ee75a 100644 (file)
@@ -226,6 +226,7 @@ struct ath11k_hw_params {
        u32 tx_ring_size;
        bool smp2p_wow_exit;
        bool support_fw_mac_sequence;
+       bool support_dual_stations;
 };
 
 struct ath11k_hw_ops {
index 7bf5d1068164a2658abb8a17a276169fba675e93..7180ce9dbf982ad02b1591c01ca44cb5c0a37698 100644 (file)
@@ -9843,28 +9843,46 @@ 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))
-               limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
-
-       combinations[0].limits = limits;
-       combinations[0].n_limits = n_limits;
-       combinations[0].max_interfaces = 16;
-       combinations[0].num_different_channels = 1;
-       combinations[0].beacon_int_infra_match = true;
-       combinations[0].beacon_int_min_gcd = 100;
-       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[0].types |= BIT(NL80211_IFTYPE_STATION);
+
+               limits[1].max = 1;
+               limits[1].types |= BIT(NL80211_IFTYPE_AP);
+               if (IS_ENABLED(CONFIG_MAC80211_MESH) &&
+                   ab->hw_params.interface_modes & BIT(NL80211_IFTYPE_MESH_POINT))
+                       limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
+
+               combinations[0].limits = limits;
+               combinations[0].n_limits = 2;
+               combinations[0].max_interfaces = ab->hw_params.num_vdevs;
+               combinations[0].num_different_channels = 2;
+               combinations[0].beacon_int_infra_match = true;
+               combinations[0].beacon_int_min_gcd = 100;
+       } else {
+               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))
+                       limits[1].types |= BIT(NL80211_IFTYPE_MESH_POINT);
+
+               combinations[0].limits = limits;
+               combinations[0].n_limits = 2;
+               combinations[0].max_interfaces = 16;
+               combinations[0].num_different_channels = 1;
+               combinations[0].beacon_int_infra_match = true;
+               combinations[0].beacon_int_min_gcd = 100;
+               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);
+       }
 
        ar->hw->wiphy->iface_combinations = combinations;
        ar->hw->wiphy->n_iface_combinations = 1;