[PATCH v3] wifi: ath11k: support DBS and DFS compatibility

Baochen Qiang quic_bqiang at quicinc.com
Sun May 11 19:56:55 PDT 2025



On 11/27/2024 10:27 AM, Yu Zhang(Yuriy) wrote:
> 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-by: Mihai Moldovan <ionic at ionic.de>
> 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 at quicinc.com>
> ---
> v2:
>  - Add tested-on IPQ8074 and IPQ6018.
> v3:
>  - Add tested-on QCA6390.  
> ---
>  drivers/net/wireless/ath/ath11k/mac.c | 42 +++++++++++++++------------
>  1 file changed, 24 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
> index 31ae9b384a29..aa63f5e20f2b 100644
> --- a/drivers/net/wireless/ath/ath11k/mac.c
> +++ b/drivers/net/wireless/ath/ath11k/mac.c
> @@ -9911,12 +9911,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;
>  
> @@ -9931,7 +9936,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))
> @@ -9941,25 +9948,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;

as this limits array is assigned to combinations[0], don't you need another array that
would be assigned to combinations[1]?

> -		limits[1].max = 1;

why is this removed?

> -
> -		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) {
> @@ -9970,7 +9976,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;
>  }




More information about the ath11k mailing list