diff mbox series

[V13,4/9] wifi: ath12k: generate rx and tx mcs maps for supported HE mcs

Message ID 20250418174818.3336510-5-quic_pradeepc@quicinc.com
State Superseded
Headers show
Series wifi: ath12k: add MU-MIMO and 160 MHz bandwidth support | expand

Commit Message

Pradeep Kumar Chitrapu April 18, 2025, 5:48 p.m. UTC
Generate rx and tx mcs maps in ath12k_mac_set_hemcsmap() based
on number of supported tx/rx chains and set them in supported
mcs/nss for HE capabilities.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1

Co-developed-by: Muna Sinada <quic_msinada@quicinc.com>
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
---
 drivers/net/wireless/ath/ath12k/mac.c | 40 ++++++++++++++++++++-------
 1 file changed, 30 insertions(+), 10 deletions(-)

Comments

Uraj Sasan May 29, 2025, 6:59 a.m. UTC | #1
On 4/18/2025 11:18 PM, Pradeep Kumar Chitrapu wrote:
> Generate rx and tx mcs maps in ath12k_mac_set_hemcsmap() based
> on number of supported tx/rx chains and set them in supported
> mcs/nss for HE capabilities.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Co-developed-by: Muna Sinada <quic_msinada@quicinc.com>
> Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
> ---
>  drivers/net/wireless/ath/ath12k/mac.c | 40 ++++++++++++++++++++-------
>  1 file changed, 30 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 30c7d5770ef6..178c89029922 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -6947,20 +6947,40 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap,
>  	return cpu_to_le16(bcap->he_6ghz_capa);
>  }
>  
> -static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap,
> +static void ath12k_mac_set_hemcsmap(struct ath12k *ar,
> +				    struct ath12k_pdev_cap *cap,
>  				    struct ieee80211_sta_he_cap *he_cap)
>  {
>  	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
> +	u16 txmcs_map, rxmcs_map;
> +	u32 i;
> +
> +	rxmcs_map = 0;
> +	txmcs_map = 0;
> +	for (i = 0; i < 8; i++) {
> +		if (i < ar->num_tx_chains &&
> +		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
> +			txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
> +		else
> +			txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
> +
> +		if (i < ar->num_rx_chains &&
> +		    (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))

I could see the changes are already in external review but wanted to post it internally,

Shouldn't this be cap->rx_chain_mask_shift ?

*"i < ar->num_tx_chains and i < ar->num_rx_chains "*, this is issue since the value of ar->num_tx_chains is not the max supported by the hw always,
but it gets updated later also via iw phy set antenna command and if user provides any value from 0-15 we will have
issue. E.g if the value are non continues 1's eg 4 , 5, 6 it will fail and set the VHT/HT/EHT caps to disabled state,
and only 1,3,7,15 would work correctly.

> +			rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
> +		else
> +			rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
> +	}
>  
> -	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
> -	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
> -	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
> -	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
> -	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
> -	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
> +	mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff);
> +	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
> +	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
> +	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
> +	mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff);
> +	mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff);
>  }
>  
> -static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
> +static void ath12k_mac_copy_he_cap(struct ath12k *ar,
> +				   struct ath12k_band_cap *band_cap,
>  				   int iftype, u8 num_tx_chains,
>  				   struct ieee80211_sta_he_cap *he_cap)
>  {
> @@ -7004,7 +7024,7 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
>  		break;
>  	}
>  
> -	ath12k_mac_set_hemcsmap(band_cap, he_cap);
> +	ath12k_mac_set_hemcsmap(ar, &ar->pdev->cap, he_cap);
>  	memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
>  	if (he_cap_elem->phy_cap_info[6] &
>  	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
> @@ -7194,7 +7214,7 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
>  
>  		data[idx].types_mask = BIT(i);
>  
> -		ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap);
> +		ath12k_mac_copy_he_cap(ar, band_cap, i, ar->num_tx_chains, he_cap);
>  		if (band == NL80211_BAND_6GHZ) {
>  			data[idx].he_6ghz_capa.capa =
>  				ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
Pradeep Kumar Chitrapu May 30, 2025, 11:01 p.m. UTC | #2
On 5/28/2025 11:59 PM, Uraj Sasan wrote:
> 
> On 4/18/2025 11:18 PM, Pradeep Kumar Chitrapu wrote:
>> Generate rx and tx mcs maps in ath12k_mac_set_hemcsmap() based
>> on number of supported tx/rx chains and set them in supported
>> mcs/nss for HE capabilities.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Co-developed-by: Muna Sinada <quic_msinada@quicinc.com>
>> Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
>> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
>> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
>> ---
>>   drivers/net/wireless/ath/ath12k/mac.c | 40 ++++++++++++++++++++-------
>>   1 file changed, 30 insertions(+), 10 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
>> index 30c7d5770ef6..178c89029922 100644
>> --- a/drivers/net/wireless/ath/ath12k/mac.c
>> +++ b/drivers/net/wireless/ath/ath12k/mac.c
>> @@ -6947,20 +6947,40 @@ static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap,
>>   	return cpu_to_le16(bcap->he_6ghz_capa);
>>   }
>>   
>> -static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap,
>> +static void ath12k_mac_set_hemcsmap(struct ath12k *ar,
>> +				    struct ath12k_pdev_cap *cap,
>>   				    struct ieee80211_sta_he_cap *he_cap)
>>   {
>>   	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
>> +	u16 txmcs_map, rxmcs_map;
>> +	u32 i;
>> +
>> +	rxmcs_map = 0;
>> +	txmcs_map = 0;
>> +	for (i = 0; i < 8; i++) {
>> +		if (i < ar->num_tx_chains &&
>> +		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
>> +			txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
>> +		else
>> +			txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
>> +
>> +		if (i < ar->num_rx_chains &&
>> +		    (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
> 
> I could see the changes are already in external review but wanted to post it internally,
> 
> Shouldn't this be cap->rx_chain_mask_shift ?
Hi Uraj

I expect tx_chain_mask_shift and rx_chain_mask_shift must be same. Do 
you see any specific issue with this? This will help me debug more.
> 
> *"i < ar->num_tx_chains and i < ar->num_rx_chains "*, this is issue since the value of ar->num_tx_chains is not the max supported by the hw always,
> but it gets updated later also via iw phy set antenna command and if user provides any value from 0-15 we will have
> issue. E.g if the value are non continues 1's eg 4 , 5, 6 it will fail and set the VHT/HT/EHT caps to disabled state,
> and only 1,3,7,15 would work correctly.
I see that when userspace changes chainmask, __ath12k_set_antenna calls 
ath12k_mac_setup_ht_vht_cap() to reconfigure caps. Please let me know if 
you are seeing any specific issue, so that I can address it better..

Thanks
pradeep
> 
>> +			rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
>> +		else
>> +			rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
>> +	}
>>   
>> -	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
>> -	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
>> -	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
>> -	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
>> -	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
>> -	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
>> +	mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff);
>> +	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
>> +	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
>> +	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
>> +	mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff);
>> +	mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff);
>>   }
>>   
>> -static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
>> +static void ath12k_mac_copy_he_cap(struct ath12k *ar,
>> +				   struct ath12k_band_cap *band_cap,
>>   				   int iftype, u8 num_tx_chains,
>>   				   struct ieee80211_sta_he_cap *he_cap)
>>   {
>> @@ -7004,7 +7024,7 @@ static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
>>   		break;
>>   	}
>>   
>> -	ath12k_mac_set_hemcsmap(band_cap, he_cap);
>> +	ath12k_mac_set_hemcsmap(ar, &ar->pdev->cap, he_cap);
>>   	memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
>>   	if (he_cap_elem->phy_cap_info[6] &
>>   	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
>> @@ -7194,7 +7214,7 @@ static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
>>   
>>   		data[idx].types_mask = BIT(i);
>>   
>> -		ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap);
>> +		ath12k_mac_copy_he_cap(ar, band_cap, i, ar->num_tx_chains, he_cap);
>>   		if (band == NL80211_BAND_6GHZ) {
>>   			data[idx].he_6ghz_capa.capa =
>>   				ath12k_mac_setup_he_6ghz_cap(cap, band_cap);
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 30c7d5770ef6..178c89029922 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -6947,20 +6947,40 @@  static __le16 ath12k_mac_setup_he_6ghz_cap(struct ath12k_pdev_cap *pcap,
 	return cpu_to_le16(bcap->he_6ghz_capa);
 }
 
-static void ath12k_mac_set_hemcsmap(struct ath12k_band_cap *band_cap,
+static void ath12k_mac_set_hemcsmap(struct ath12k *ar,
+				    struct ath12k_pdev_cap *cap,
 				    struct ieee80211_sta_he_cap *he_cap)
 {
 	struct ieee80211_he_mcs_nss_supp *mcs_nss = &he_cap->he_mcs_nss_supp;
+	u16 txmcs_map, rxmcs_map;
+	u32 i;
+
+	rxmcs_map = 0;
+	txmcs_map = 0;
+	for (i = 0; i < 8; i++) {
+		if (i < ar->num_tx_chains &&
+		    (ar->cfg_tx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
+			txmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
+		else
+			txmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
+
+		if (i < ar->num_rx_chains &&
+		    (ar->cfg_rx_chainmask >> cap->tx_chain_mask_shift) & BIT(i))
+			rxmcs_map |= IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2);
+		else
+			rxmcs_map |= IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2);
+	}
 
-	mcs_nss->rx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
-	mcs_nss->tx_mcs_80 = cpu_to_le16(band_cap->he_mcs & 0xffff);
-	mcs_nss->rx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
-	mcs_nss->tx_mcs_160 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
-	mcs_nss->rx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
-	mcs_nss->tx_mcs_80p80 = cpu_to_le16((band_cap->he_mcs >> 16) & 0xffff);
+	mcs_nss->rx_mcs_80 = cpu_to_le16(rxmcs_map & 0xffff);
+	mcs_nss->tx_mcs_80 = cpu_to_le16(txmcs_map & 0xffff);
+	mcs_nss->rx_mcs_160 = cpu_to_le16(rxmcs_map & 0xffff);
+	mcs_nss->tx_mcs_160 = cpu_to_le16(txmcs_map & 0xffff);
+	mcs_nss->rx_mcs_80p80 = cpu_to_le16(rxmcs_map & 0xffff);
+	mcs_nss->tx_mcs_80p80 = cpu_to_le16(txmcs_map & 0xffff);
 }
 
-static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
+static void ath12k_mac_copy_he_cap(struct ath12k *ar,
+				   struct ath12k_band_cap *band_cap,
 				   int iftype, u8 num_tx_chains,
 				   struct ieee80211_sta_he_cap *he_cap)
 {
@@ -7004,7 +7024,7 @@  static void ath12k_mac_copy_he_cap(struct ath12k_band_cap *band_cap,
 		break;
 	}
 
-	ath12k_mac_set_hemcsmap(band_cap, he_cap);
+	ath12k_mac_set_hemcsmap(ar, &ar->pdev->cap, he_cap);
 	memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
 	if (he_cap_elem->phy_cap_info[6] &
 	    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT)
@@ -7194,7 +7214,7 @@  static int ath12k_mac_copy_sband_iftype_data(struct ath12k *ar,
 
 		data[idx].types_mask = BIT(i);
 
-		ath12k_mac_copy_he_cap(band_cap, i, ar->num_tx_chains, he_cap);
+		ath12k_mac_copy_he_cap(ar, band_cap, i, ar->num_tx_chains, he_cap);
 		if (band == NL80211_BAND_6GHZ) {
 			data[idx].he_6ghz_capa.capa =
 				ath12k_mac_setup_he_6ghz_cap(cap, band_cap);