diff mbox series

[V13,8/9] wifi: ath12k: add support for 160 MHz bandwidth

Message ID 20250418174818.3336510-9-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
Add support to configure maximum NSS in 160 MHz bandwidth.
Firmware advertises support for handling NSS ratio information
as a part of service ready ext event using nss_ratio_enabled
flag. Save this information in ath12k_pdev_cap to calculate
NSS ratio.

Additionally, reorder the code by moving
ath12k_peer_assoc_h_phymode() before ath12k_peer_assoc_h_vht()
to ensure that arg->peer_phymode correctly reflects the bandwidth
in the max NSS calculation.

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

Co-developed-by: P Praneesh <quic_ppranees@quicinc.com>
Signed-off-by: P Praneesh <quic_ppranees@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/core.h |  2 +
 drivers/net/wireless/ath/ath12k/mac.c  | 88 ++++++++++++++++++++++----
 drivers/net/wireless/ath/ath12k/mac.h  |  2 +
 drivers/net/wireless/ath/ath12k/wmi.c  |  7 +-
 drivers/net/wireless/ath/ath12k/wmi.h  | 28 ++++++++
 5 files changed, 114 insertions(+), 13 deletions(-)

Comments

Nicolas Escande May 19, 2025, 3:11 p.m. UTC | #1
On Fri Apr 18, 2025 at 7:48 PM CEST, Pradeep Kumar Chitrapu wrote:
> Add support to configure maximum NSS in 160 MHz bandwidth.
> Firmware advertises support for handling NSS ratio information
> as a part of service ready ext event using nss_ratio_enabled
> flag. Save this information in ath12k_pdev_cap to calculate
> NSS ratio.
>
> Additionally, reorder the code by moving
> ath12k_peer_assoc_h_phymode() before ath12k_peer_assoc_h_vht()
> to ensure that arg->peer_phymode correctly reflects the bandwidth
> in the max NSS calculation.
>
> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>
> Co-developed-by: P Praneesh <quic_ppranees@quicinc.com>
> Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
[...]

Hello,

With this patch set we sometimes see the following warning shortly followed by a
firmware crash on QCN9274 running WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1

[  242.416516] ------------[ cut here ]------------
[  242.423608] WARNING: CPU: 2 PID: 1427 at drivers/net/wireless/ath/ath12k/mac.c:3224 ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k]
[  242.428475] Modules linked in: dvb_usb_af9035 dvb_usb_dib0700 dib0070 dib7000m dibx000_common at24 ath12k qmi_helpers nf_nat_sip nf_conntrack_sip dwc3_qcom nf_nat_pptp nf_conntrack_pptp ipq_lpass
[  242.444176] CPU: 2 UID: 0 PID: 1427 Comm: memcheck-arm64- Not tainted 6.13.0-02013-gd424b7b9a373-dirty #140
[  242.466407] Hardware name: XXX (DT)
[  242.476124] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[  242.480639] pc : ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k]
[  242.487584] lr : ath12k_peer_assoc_h_phymode+0x540/0x800 [ath12k]
[  242.493834] sp : ffffffc08588b4b0
[  242.499820] x29: ffffffc08588b4b0 x28: 0000000000000008 x27: ffffff802781bb60
[  242.503123] x26: ffffff802cfa9af0 x25: ffffff802781bb60 x24: ffffff8016f38be0
[  242.510241] x23: ffffff802cfa9fb0 x22: ffffff802781bce0 x21: ffffff802d50dc00
[  242.517360] x20: ffffff8016f38be0 x19: ffffff802781bce0 x18: ffffffffffffffff
[  242.524477] x17: 30363120726f6620 x16: 6f666e6920797469 x15: 6c69626170616320
[  242.531595] x14: 5948502054485620 x13: 0000000000000001 x12: 0000000000000060
[  242.538714] x11: ffffffc08126c6b0 x10: 0000000000000274 x9 : ffffffc08010468c
[  242.545832] x8 : 00000000ffffdfff x7 : 00000000ffffe000 x6 : 0000000000000001
[  242.552949] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
[  242.560067] x2 : ffffff80bff6de70 x1 : ffffff80bff640c8 x0 : 0000000000000021
[  242.567186] Call trace:
[  242.574299]  ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k] (P)
[  242.576560]  ath12k_peer_assoc_prepare+0x5d4/0x1608 [ath12k]
[  242.582809]  ath12k_mac_op_sta_state+0x1f4/0x1100 [ath12k]
[  242.588451]  drv_sta_state+0xa0/0x5e0
[  242.593745]  _sta_info_move_state+0x20c/0x4b8
[  242.597477]  sta_info_move_state+0x18/0x28
[  242.601817]  sta_apply_auth_flags.isra.0+0x190/0x1c0
[  242.605812]  sta_apply_parameters+0x240/0x5e0
[  242.610933]  ieee80211_change_station+0x164/0x200
[  242.615187]  nl80211_set_station+0x3bc/0x520
[  242.619874]  genl_family_rcv_msg_doit+0xbc/0x128
[  242.624215]  genl_rcv_msg+0x1c0/0x260
[  242.628815]  netlink_rcv_skb+0x40/0x100
[  242.632373]  genl_rcv+0x3c/0x60
[  242.636018]  netlink_unicast+0x2d8/0x338
[  242.639144]  netlink_sendmsg+0x158/0x398
[  242.643311]  ____sys_sendmsg+0x104/0x290
[  242.647217]  ___sys_sendmsg+0x70/0xa0
[  242.651123]  __sys_sendmsg+0x64/0xb0
[  242.654682]  __arm64_sys_sendmsg+0x28/0x38
[  242.658329]  do_el0_svc+0x70/0x100
[  242.662234]  el0_svc+0x18/0x60
[  242.665619]  el0t_64_sync_handler+0x104/0x130
[  242.668659]  el0t_64_sync+0x154/0x158
[  242.673086] ---[ end trace 0000000000000000 ]---

It's probably there since v1 of thies series but I just finally got to the
bottom of this now and I've tracked it down to the following hunk:

> @@ -2822,11 +2883,12 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
>  						    struct ieee80211_link_sta *link_sta)
>  {
>  	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) {
> -		if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
> +		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
> +		    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))
>  			return MODE_11AC_VHT160;
>  
>  		/* not sure if this is a valid case? */
> -		return MODE_11AC_VHT160;
> +		return MODE_UNKNOWN;
>  	}
>  
>  	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_80)

Which led me to understand that a sta that supports both VHT 160 and 80+80 ie
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ will end up with a phy mode
MODE_UNKNOWN send to the firmware. Which I guess is the reason of the crash.

I understand that VHT 80+80 is not supported by this chipset, but shouldn't we
just allow the sta to connect using VHT 160 right ? Something like this maybe ?

diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index 048d62a48c88..d3a87af076e7 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -3041,7 +3041,7 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
 						    struct ieee80211_link_sta *link_sta)
 {
 	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) {
-		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
 		    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))
 			return MODE_11AC_VHT160;
Pradeep Kumar Chitrapu May 21, 2025, 9:38 p.m. UTC | #2
On 5/19/2025 8:11 AM, Nicolas Escande wrote:
> On Fri Apr 18, 2025 at 7:48 PM CEST, Pradeep Kumar Chitrapu wrote:
>> Add support to configure maximum NSS in 160 MHz bandwidth.
>> Firmware advertises support for handling NSS ratio information
>> as a part of service ready ext event using nss_ratio_enabled
>> flag. Save this information in ath12k_pdev_cap to calculate
>> NSS ratio.
>>
>> Additionally, reorder the code by moving
>> ath12k_peer_assoc_h_phymode() before ath12k_peer_assoc_h_vht()
>> to ensure that arg->peer_phymode correctly reflects the bandwidth
>> in the max NSS calculation.
>>
>> Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.0.1-00029-QCAHKSWPL_SILICONZ-1
>>
>> Co-developed-by: P Praneesh <quic_ppranees@quicinc.com>
>> Signed-off-by: P Praneesh <quic_ppranees@quicinc.com>
>> Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
>> Acked-by: Jeff Johnson <quic_jjohnson@quicinc.com>
> [...]
> 
> Hello,
> 
> With this patch set we sometimes see the following warning shortly followed by a
> firmware crash on QCN9274 running WLAN.WBE.1.3.1-00218-QCAHKSWPL_SILICONZ-1
> 
> [  242.416516] ------------[ cut here ]------------
> [  242.423608] WARNING: CPU: 2 PID: 1427 at drivers/net/wireless/ath/ath12k/mac.c:3224 ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k]
> [  242.428475] Modules linked in: dvb_usb_af9035 dvb_usb_dib0700 dib0070 dib7000m dibx000_common at24 ath12k qmi_helpers nf_nat_sip nf_conntrack_sip dwc3_qcom nf_nat_pptp nf_conntrack_pptp ipq_lpass
> [  242.444176] CPU: 2 UID: 0 PID: 1427 Comm: memcheck-arm64- Not tainted 6.13.0-02013-gd424b7b9a373-dirty #140
> [  242.466407] Hardware name: XXX (DT)
> [  242.476124] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [  242.480639] pc : ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k]
> [  242.487584] lr : ath12k_peer_assoc_h_phymode+0x540/0x800 [ath12k]
> [  242.493834] sp : ffffffc08588b4b0
> [  242.499820] x29: ffffffc08588b4b0 x28: 0000000000000008 x27: ffffff802781bb60
> [  242.503123] x26: ffffff802cfa9af0 x25: ffffff802781bb60 x24: ffffff8016f38be0
> [  242.510241] x23: ffffff802cfa9fb0 x22: ffffff802781bce0 x21: ffffff802d50dc00
> [  242.517360] x20: ffffff8016f38be0 x19: ffffff802781bce0 x18: ffffffffffffffff
> [  242.524477] x17: 30363120726f6620 x16: 6f666e6920797469 x15: 6c69626170616320
> [  242.531595] x14: 5948502054485620 x13: 0000000000000001 x12: 0000000000000060
> [  242.538714] x11: ffffffc08126c6b0 x10: 0000000000000274 x9 : ffffffc08010468c
> [  242.545832] x8 : 00000000ffffdfff x7 : 00000000ffffe000 x6 : 0000000000000001
> [  242.552949] x5 : 0000000000000000 x4 : 0000000000000000 x3 : 0000000000000000
> [  242.560067] x2 : ffffff80bff6de70 x1 : ffffff80bff640c8 x0 : 0000000000000021
> [  242.567186] Call trace:
> [  242.574299]  ath12k_peer_assoc_h_phymode+0xd4/0x800 [ath12k] (P)
> [  242.576560]  ath12k_peer_assoc_prepare+0x5d4/0x1608 [ath12k]
> [  242.582809]  ath12k_mac_op_sta_state+0x1f4/0x1100 [ath12k]
> [  242.588451]  drv_sta_state+0xa0/0x5e0
> [  242.593745]  _sta_info_move_state+0x20c/0x4b8
> [  242.597477]  sta_info_move_state+0x18/0x28
> [  242.601817]  sta_apply_auth_flags.isra.0+0x190/0x1c0
> [  242.605812]  sta_apply_parameters+0x240/0x5e0
> [  242.610933]  ieee80211_change_station+0x164/0x200
> [  242.615187]  nl80211_set_station+0x3bc/0x520
> [  242.619874]  genl_family_rcv_msg_doit+0xbc/0x128
> [  242.624215]  genl_rcv_msg+0x1c0/0x260
> [  242.628815]  netlink_rcv_skb+0x40/0x100
> [  242.632373]  genl_rcv+0x3c/0x60
> [  242.636018]  netlink_unicast+0x2d8/0x338
> [  242.639144]  netlink_sendmsg+0x158/0x398
> [  242.643311]  ____sys_sendmsg+0x104/0x290
> [  242.647217]  ___sys_sendmsg+0x70/0xa0
> [  242.651123]  __sys_sendmsg+0x64/0xb0
> [  242.654682]  __arm64_sys_sendmsg+0x28/0x38
> [  242.658329]  do_el0_svc+0x70/0x100
> [  242.662234]  el0_svc+0x18/0x60
> [  242.665619]  el0t_64_sync_handler+0x104/0x130
> [  242.668659]  el0t_64_sync+0x154/0x158
> [  242.673086] ---[ end trace 0000000000000000 ]---
> 
> It's probably there since v1 of thies series but I just finally got to the
> bottom of this now and I've tracked it down to the following hunk:
> 
>> @@ -2822,11 +2883,12 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
>>   						    struct ieee80211_link_sta *link_sta)
>>   {
>>   	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) {
>> -		if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
>> +		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
>> +		    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))
>>   			return MODE_11AC_VHT160;
>>   
>>   		/* not sure if this is a valid case? */
>> -		return MODE_11AC_VHT160;
>> +		return MODE_UNKNOWN;
>>   	}
>>   
>>   	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_80)
> 
> Which led me to understand that a sta that supports both VHT 160 and 80+80 ie
> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ will end up with a phy mode
> MODE_UNKNOWN send to the firmware. Which I guess is the reason of the crash.
> 
> I understand that VHT 80+80 is not supported by this chipset, but shouldn't we
> just allow the sta to connect using VHT 160 right ? Something like this maybe ?
> 
> diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
> index 048d62a48c88..d3a87af076e7 100644
> --- a/drivers/net/wireless/ath/ath12k/mac.c
> +++ b/drivers/net/wireless/ath/ath12k/mac.c
> @@ -3041,7 +3041,7 @@ static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
>   						    struct ieee80211_link_sta *link_sta)
>   {
>   	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) {
> -		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
> +		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK |
>   		    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))
>   			return MODE_11AC_VHT160;
Thanks Nicolas,

I believe IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ mean only 
80PLUS80 not both 160 and 80PLUS80 and STA must set 
IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ flags for indicating 160 MHz 
support. Please correct me if my understanding is correct. However I 
agree that we must allow STA to connect irrespective of which flag STA 
sets as long as bandwidth is 160MHz. I see ath10k and ath11k also allows 
this by setting default phymode of MODE_11AC_VHT160 for BW 
==IEEE80211_STA_RX_BW_160 case.
I will make this change in next revision.
Thanks
Pradeep
Nicolas Escande May 22, 2025, 8:34 a.m. UTC | #3
On Wed May 21, 2025 at 11:38 PM CEST, Pradeep Kumar Chitrapu wrote:
[...]
> Thanks Nicolas,
>
> I believe IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ mean only 
> 80PLUS80 not both 160 and 80PLUS80 and STA must set 
> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ flags for indicating 160 MHz 
> support. Please correct me if my understanding is correct. However I 
> agree that we must allow STA to connect irrespective of which flag STA 
> sets as long as bandwidth is 160MHz. I see ath10k and ath11k also allows 
> this by setting default phymode of MODE_11AC_VHT160 for BW 
> ==IEEE80211_STA_RX_BW_160 case.
> I will make this change in next revision.
> Thanks
> Pradeep

Hello Pradeep,

Well this is quite unclear for me maybe Johannes or someone more aware of the
evolutions of the standard could shime in.
Pradeep Kumar Chitrapu May 28, 2025, 6:16 p.m. UTC | #4
On 5/22/2025 1:34 AM, Nicolas Escande wrote:
> On Wed May 21, 2025 at 11:38 PM CEST, Pradeep Kumar Chitrapu wrote:
> [...]
>> Thanks Nicolas,
>>
>> I believe IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ mean only
>> 80PLUS80 not both 160 and 80PLUS80 and STA must set
>> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ flags for indicating 160 MHz
>> support. Please correct me if my understanding is correct. However I
>> agree that we must allow STA to connect irrespective of which flag STA
>> sets as long as bandwidth is 160MHz. I see ath10k and ath11k also allows
>> this by setting default phymode of MODE_11AC_VHT160 for BW
>> ==IEEE80211_STA_RX_BW_160 case.
>> I will make this change in next revision.
>> Thanks
>> Pradeep
> 
> Hello Pradeep,
> 
> Well this is quite unclear for me maybe Johannes or someone more aware of the
> evolutions of the standard could shime in.
> 
>  From what I've gathered:
>    - the naming IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ implies both
>      which points it was the case when added
>    - and the original 802.11ac-2013 Table 8-183v states:
> 	Set to 0 if the STA does not support either 160 or 80+80 MHz.
> 	Set to 1 if the STA supports 160 MHz.
> 	Set to 2 if the STA supports 160 MHz and 80+80 MHz.
> 	The value 3 is reserved.
> 
> Things get complicated after:
>   - later versions like 802.11-2020 have deprecated value 2 in favor of the new
>     Extendeed NSS BW feature
>   - Table 9-272 still implies both 160 & 80+80
>   - Table 11-23 & Table 11-24 implies only 80+80 but both talk about the
>     'VHT Operation' Channel Width field and not the 'VHT Capabilities' Supported
>     Channel Width. And thoses had different values even in the first AC amendment
> 
> So it feels like when no Extended NSS BW Support is used (first gen AC devices),
> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ really means both 160 & 80+80
Thanks Nicolas for detailed response.
Request you to kindly review V14 series and let me know if it works?

Thanks
Pradeep
Nicolas Escande June 2, 2025, 9:05 a.m. UTC | #5
On Wed May 28, 2025 at 8:16 PM CEST, Pradeep Kumar Chitrapu wrote:
>
>
> On 5/22/2025 1:34 AM, Nicolas Escande wrote:
>> On Wed May 21, 2025 at 11:38 PM CEST, Pradeep Kumar Chitrapu wrote:
>> [...]
>>> Thanks Nicolas,
>>>
>>> I believe IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ mean only
>>> 80PLUS80 not both 160 and 80PLUS80 and STA must set
>>> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ flags for indicating 160 MHz
>>> support. Please correct me if my understanding is correct. However I
>>> agree that we must allow STA to connect irrespective of which flag STA
>>> sets as long as bandwidth is 160MHz. I see ath10k and ath11k also allows
>>> this by setting default phymode of MODE_11AC_VHT160 for BW
>>> ==IEEE80211_STA_RX_BW_160 case.
>>> I will make this change in next revision.
>>> Thanks
>>> Pradeep
>> 
>> Hello Pradeep,
>> 
>> Well this is quite unclear for me maybe Johannes or someone more aware of the
>> evolutions of the standard could shime in.
>> 
>>  From what I've gathered:
>>    - the naming IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ implies both
>>      which points it was the case when added
>>    - and the original 802.11ac-2013 Table 8-183v states:
>> 	Set to 0 if the STA does not support either 160 or 80+80 MHz.
>> 	Set to 1 if the STA supports 160 MHz.
>> 	Set to 2 if the STA supports 160 MHz and 80+80 MHz.
>> 	The value 3 is reserved.
>> 
>> Things get complicated after:
>>   - later versions like 802.11-2020 have deprecated value 2 in favor of the new
>>     Extendeed NSS BW feature
>>   - Table 9-272 still implies both 160 & 80+80
>>   - Table 11-23 & Table 11-24 implies only 80+80 but both talk about the
>>     'VHT Operation' Channel Width field and not the 'VHT Capabilities' Supported
>>     Channel Width. And thoses had different values even in the first AC amendment
>> 
>> So it feels like when no Extended NSS BW Support is used (first gen AC devices),
>> IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ really means both 160 & 80+80
> Thanks Nicolas for detailed response.
> Request you to kindly review V14 series and let me know if it works?
>
> Thanks
> Pradeep

Hello Pradeep,

Yes your new version fixes the problem for me.

Thanks
diff mbox series

Patch

diff --git a/drivers/net/wireless/ath/ath12k/core.h b/drivers/net/wireless/ath/ath12k/core.h
index 4b8f434e3e9a..d2b79180a534 100644
--- a/drivers/net/wireless/ath/ath12k/core.h
+++ b/drivers/net/wireless/ath/ath12k/core.h
@@ -841,6 +841,8 @@  struct ath12k_pdev_cap {
 	struct ath12k_band_cap band[NUM_NL80211_BANDS];
 	u32 eml_cap;
 	u32 mld_cap;
+	bool nss_ratio_enabled;
+	u8 nss_ratio_info;
 };
 
 struct mlo_timestamp {
diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c
index e7c15a3c4c80..ecd47f15ef95 100644
--- a/drivers/net/wireless/ath/ath12k/mac.c
+++ b/drivers/net/wireless/ath/ath12k/mac.c
@@ -2167,6 +2167,34 @@  ath12k_peer_assoc_h_vht_limit(u16 tx_mcs_set,
 	return tx_mcs_set;
 }
 
+static u8 ath12k_get_nss_160mhz(struct ath12k *ar,
+				u8 max_nss)
+{
+	u8 nss_ratio_info = ar->pdev->cap.nss_ratio_info;
+	u8 max_sup_nss = 0;
+
+	switch (nss_ratio_info) {
+	case WMI_NSS_RATIO_1BY2_NSS:
+		max_sup_nss = max_nss >> 1;
+		break;
+	case WMI_NSS_RATIO_3BY4_NSS:
+		ath12k_warn(ar->ab, "WMI_NSS_RATIO_3BY4_NSS not supported\n");
+		break;
+	case WMI_NSS_RATIO_1_NSS:
+		max_sup_nss = max_nss;
+		break;
+	case WMI_NSS_RATIO_2_NSS:
+		ath12k_warn(ar->ab, "WMI_NSS_RATIO_2_NSS not supported\n");
+		break;
+	default:
+		ath12k_warn(ar->ab, "invalid nss ratio received from fw: %d\n",
+			    nss_ratio_info);
+		break;
+	}
+
+	return max_sup_nss;
+}
+
 static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
 				    struct ath12k_link_vif *arvif,
 				    struct ath12k_link_sta *arsta,
@@ -2184,6 +2212,7 @@  static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
 	u8 max_nss, vht_mcs;
 	int i, vht_nss, nss_idx;
 	bool user_rate_valid = true;
+	u32 rx_nss, tx_nss, nss_160;
 
 	lockdep_assert_wiphy(ath12k_ar_to_hw(ar)->wiphy);
 
@@ -2288,10 +2317,24 @@  static void ath12k_peer_assoc_h_vht(struct ath12k *ar,
 	/* TODO:  Check */
 	arg->tx_max_mcs_nss = 0xFF;
 
-	ath12k_dbg(ar->ab, ATH12K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
-		   arsta->addr, arg->peer_max_mpdu, arg->peer_flags);
+	if (arg->peer_phymode == MODE_11AC_VHT160) {
+		tx_nss = ath12k_get_nss_160mhz(ar, max_nss);
+		rx_nss = min(arg->peer_nss, tx_nss);
+		arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE;
+
+		if (!rx_nss) {
+			ath12k_warn(ar->ab, "invalid max_nss\n");
+			return;
+		}
+
+		nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ);
+		arg->peer_bw_rxnss_override |= nss_160;
+	}
 
-	/* TODO: rxnss_override */
+	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
+		   "mac vht peer %pM max_mpdu %d flags 0x%x nss_override 0x%x\n",
+		   arsta->addr, arg->peer_max_mpdu, arg->peer_flags,
+		   arg->peer_bw_rxnss_override);
 }
 
 static int ath12k_mac_get_max_he_mcs_map(u16 mcs_map, int nss)
@@ -2384,6 +2427,7 @@  static void ath12k_peer_assoc_h_he(struct ath12k *ar,
 	u16 he_tx_mcs = 0, v = 0;
 	int he_nss, nss_idx;
 	bool user_rate_valid = true;
+	u32 rx_nss, tx_nss, nss_160;
 
 	if (WARN_ON(ath12k_mac_vif_link_chan(vif, link_id, &def)))
 		return;
@@ -2578,10 +2622,27 @@  static void ath12k_peer_assoc_h_he(struct ath12k *ar,
 			max_nss = i + 1;
 	}
 	arg->peer_nss = min(link_sta->rx_nss, max_nss);
+	max_nss = min(max_nss, ar->num_tx_chains);
+
+	if (arg->peer_phymode == MODE_11AX_HE160) {
+		tx_nss = ath12k_get_nss_160mhz(ar, max_nss);
+		rx_nss = min(arg->peer_nss, tx_nss);
+		arg->peer_bw_rxnss_override = ATH12K_BW_NSS_MAP_ENABLE;
+
+		if (!rx_nss) {
+			ath12k_warn(ar->ab, "invalid max_nss\n");
+			return;
+		}
+
+		nss_160 = u32_encode_bits(rx_nss - 1, ATH12K_PEER_RX_NSS_160MHZ);
+		arg->peer_bw_rxnss_override |= nss_160;
+	}
 
 	ath12k_dbg(ar->ab, ATH12K_DBG_MAC,
-		   "mac he peer %pM nss %d mcs cnt %d\n",
-		   arsta->addr, arg->peer_nss, arg->peer_he_mcs_count);
+		   "mac he peer %pM nss %d mcs cnt %d nss_override 0x%x\n",
+		   arsta->addr, arg->peer_nss,
+		   arg->peer_he_mcs_count,
+		   arg->peer_bw_rxnss_override);
 }
 
 static void ath12k_peer_assoc_h_he_6ghz(struct ath12k *ar,
@@ -2822,11 +2883,12 @@  static enum wmi_phy_mode ath12k_mac_get_phymode_vht(struct ath12k *ar,
 						    struct ieee80211_link_sta *link_sta)
 {
 	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_160) {
-		if (link_sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ)
+		if (link_sta->vht_cap.cap & (IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+		    IEEE80211_VHT_CAP_EXT_NSS_BW_MASK))
 			return MODE_11AC_VHT160;
 
 		/* not sure if this is a valid case? */
-		return MODE_11AC_VHT160;
+		return MODE_UNKNOWN;
 	}
 
 	if (link_sta->bandwidth == IEEE80211_STA_RX_BW_80)
@@ -6983,10 +7045,8 @@  ath12k_create_vht_cap(struct ath12k *ar, u32 rate_cap_tx_chainmask,
 
 	ath12k_set_vht_txbf_cap(ar, &vht_cap.cap);
 
-	/* TODO: Enable back VHT160 mode once association issues are fixed */
-	/* Disabling VHT160 and VHT80+80 modes */
-	vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
-	vht_cap.cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
+	/* 80P80 is not supported */
+	vht_cap.cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
 
 	rxmcs_map = 0;
 	txmcs_map = 0;
@@ -11808,7 +11868,8 @@  ath12k_mac_setup_radio_iface_comb(struct ath12k *ar,
 		comb[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_80) |
+						BIT(NL80211_CHAN_WIDTH_160);
 	}
 
 	return 0;
@@ -12184,6 +12245,9 @@  static int ath12k_mac_hw_register(struct ath12k_hw *ah)
 	ieee80211_hw_set(hw, REPORTS_LOW_ACK);
 	ieee80211_hw_set(hw, NO_VIRTUAL_MONITOR);
 
+	if (cap->nss_ratio_enabled)
+		ieee80211_hw_set(hw, SUPPORTS_VHT_EXT_NSS_BW);
+
 	if ((ht_cap & WMI_HT_CAP_ENABLED) || is_6ghz) {
 		ieee80211_hw_set(hw, AMPDU_AGGREGATION);
 		ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
diff --git a/drivers/net/wireless/ath/ath12k/mac.h b/drivers/net/wireless/ath/ath12k/mac.h
index 3ddfa00a5a17..e625740e57f3 100644
--- a/drivers/net/wireless/ath/ath12k/mac.h
+++ b/drivers/net/wireless/ath/ath12k/mac.h
@@ -41,6 +41,8 @@  struct ath12k_generic_iter {
 #define IEEE80211_DISABLE_VHT_MCS_SUPPORT_0_11	BIT(24)
 
 #define ATH12K_CHAN_WIDTH_NUM			14
+#define ATH12K_BW_NSS_MAP_ENABLE		BIT(31)
+#define ATH12K_PEER_RX_NSS_160MHZ		GENMASK(2, 0)
 
 #define ATH12K_TX_POWER_MAX_VAL	70
 #define ATH12K_TX_POWER_MIN_VAL	0
diff --git a/drivers/net/wireless/ath/ath12k/wmi.c b/drivers/net/wireless/ath/ath12k/wmi.c
index a74a1549143b..ee837a66f6ac 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.c
+++ b/drivers/net/wireless/ath/ath12k/wmi.c
@@ -532,6 +532,10 @@  ath12k_pull_mac_phy_cap_svc_ready_ext(struct ath12k_wmi_pdev *wmi_handle,
 		pdev_cap->he_mcs = le32_to_cpu(mac_caps->he_supp_mcs_5g);
 		pdev_cap->tx_chain_mask = le32_to_cpu(mac_caps->tx_chain_mask_5g);
 		pdev_cap->rx_chain_mask = le32_to_cpu(mac_caps->rx_chain_mask_5g);
+		pdev_cap->nss_ratio_enabled =
+			WMI_NSS_RATIO_EN_DIS_GET(mac_caps->nss_ratio);
+		pdev_cap->nss_ratio_info =
+			WMI_NSS_RATIO_INFO_GET(mac_caps->nss_ratio);
 	} else {
 		return -EINVAL;
 	}
@@ -1054,7 +1058,8 @@  static void ath12k_wmi_put_wmi_channel(struct ath12k_wmi_channel_params *chan,
 
 		chan->band_center_freq2 = cpu_to_le32(center_freq1);
 
-	} else if (arg->mode == MODE_11BE_EHT160) {
+	} else if (arg->mode == MODE_11BE_EHT160 ||
+		   arg->mode == MODE_11AX_HE160) {
 		if (arg->freq > center_freq1)
 			chan->band_center_freq1 = cpu_to_le32(center_freq1 + 40);
 		else
diff --git a/drivers/net/wireless/ath/ath12k/wmi.h b/drivers/net/wireless/ath/ath12k/wmi.h
index 6747ca60b7fa..e53eb69285d0 100644
--- a/drivers/net/wireless/ath/ath12k/wmi.h
+++ b/drivers/net/wireless/ath/ath12k/wmi.h
@@ -2306,6 +2306,21 @@  enum wmi_direct_buffer_module {
 	WMI_DIRECT_BUF_MAX
 };
 
+/**
+ * enum wmi_nss_ratio - NSS ratio received from FW during service ready ext event
+ * @WMI_NSS_RATIO_1BY2_NSS: Max nss of 160MHz is equals to half of the max nss of 80MHz
+ * @WMI_NSS_RATIO_3BY4_NSS: Max nss of 160MHz is equals to 3/4 of the max nss of 80MHz
+ * @WMI_NSS_RATIO_1_NSS: Max nss of 160MHz is equals to the max nss of 80MHz
+ * @WMI_NSS_RATIO_2_NSS: Max nss of 160MHz is equals to two times the max nss of 80MHz
+ */
+
+enum wmi_nss_ratio {
+	WMI_NSS_RATIO_1BY2_NSS,
+	WMI_NSS_RATIO_3BY4_NSS,
+	WMI_NSS_RATIO_1_NSS,
+	WMI_NSS_RATIO_2_NSS
+};
+
 struct ath12k_wmi_pdev_band_arg {
 	u32 pdev_id;
 	u32 start_freq;
@@ -2623,6 +2638,12 @@  struct ath12k_wmi_hw_mode_cap_params {
 } __packed;
 
 #define WMI_MAX_HECAP_PHY_SIZE                 (3)
+#define WMI_NSS_RATIO_EN_DIS_BITPOS    BIT(0)
+#define WMI_NSS_RATIO_EN_DIS_GET(_val) \
+	le32_get_bits(_val, WMI_NSS_RATIO_EN_DIS_BITPOS)
+#define WMI_NSS_RATIO_INFO_BITPOS              GENMASK(4, 1)
+#define WMI_NSS_RATIO_INFO_GET(_val) \
+	le32_get_bits(_val, WMI_NSS_RATIO_INFO_BITPOS)
 
 /* pdev_id is present in lower 16 bits of pdev_and_hw_link_ids in
  * ath12k_wmi_mac_phy_caps_params & ath12k_wmi_caps_ext_params.
@@ -2664,6 +2685,13 @@  struct ath12k_wmi_mac_phy_caps_params {
 	__le32 he_cap_info_2g_ext;
 	__le32 he_cap_info_5g_ext;
 	__le32 he_cap_info_internal;
+	__le32 wireless_modes;
+	__le32 low_2ghz_chan_freq;
+	__le32 high_2ghz_chan_freq;
+	__le32 low_5ghz_chan_freq;
+	__le32 high_5ghz_chan_freq;
+	__le32 nss_ratio;
+
 } __packed;
 
 struct ath12k_wmi_hal_reg_caps_ext_params {