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 |
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;
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
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.
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
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 --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 {