forked from Lienol/openwrt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mac80211: ath10k fix vht160 firmware crash
When the 160mhz width is selected the ath10k firmware crash. This fix this problem. Signed-off-by: Ansuel Smith <[email protected]>
- Loading branch information
Showing
2 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
132 changes: 132 additions & 0 deletions
132
...ches/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
From: Sebastian Gottschall <[email protected]> | ||
|
||
current handling of peer_bw_rxnss_override parameter is based on guessing the | ||
VHT160/8080 capability by rx rate. this is wrong and may lead | ||
to a non initialized peer_bw_rxnss_override parameter which is required since | ||
VHT160 operation mode only supports 2x2 chainmasks in addition the original code | ||
initialized the parameter with wrong masked values. | ||
This patch uses the peer phymode and peer nss information for correct | ||
initialisation of the peer_bw_rxnss_override parameter. | ||
if this peer information is not available, we initialize the parameter by | ||
minimum nss which is suggested by QCA as temporary workaround according | ||
to the QCA sourcecodes. | ||
|
||
Signed-off-by: Sebastian Gottschall <[email protected]> | ||
|
||
v2: remove debug messages | ||
v3: apply some cosmetics, update documentation | ||
v4: fix compile warning and truncate nss to maximum of 2x2 since current | ||
chipsets only support 2x2 at vht160 | ||
v5: handle maximum nss for chipsets supportig vht160 with 1x1 only | ||
v7: use more simple code variant and take care about hw/sw chainmask | ||
configuration | ||
--- | ||
drivers/net/wireless/ath/ath10k/mac.c | 40 +++++++++++++++------------ | ||
drivers/net/wireless/ath/ath10k/wmi.c | 7 +---- | ||
drivers/net/wireless/ath/ath10k/wmi.h | 14 +++++++++- | ||
3 files changed, 36 insertions(+), 25 deletions(-) | ||
|
||
--- a/drivers/net/wireless/ath/ath10k/mac.c | ||
+++ b/drivers/net/wireless/ath/ath10k/mac.c | ||
@@ -2466,7 +2466,7 @@ static void ath10k_peer_assoc_h_vht(stru | ||
const u16 *vht_mcs_mask; | ||
u8 ampdu_factor; | ||
u8 max_nss, vht_mcs; | ||
- int i; | ||
+ int i, nss160; | ||
|
||
if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) | ||
return; | ||
@@ -2526,23 +2526,27 @@ static void ath10k_peer_assoc_h_vht(stru | ||
__le16_to_cpu(vht_cap->vht_mcs.tx_highest); | ||
arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit( | ||
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask); | ||
+ arg->peer_bw_rxnss_override = 0; | ||
+ nss160 = 1; /* 1x1 default config for VHT160 */ | ||
|
||
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", | ||
- sta->addr, arg->peer_max_mpdu, arg->peer_flags); | ||
- | ||
- if (arg->peer_vht_rates.rx_max_rate && | ||
- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) { | ||
- switch (arg->peer_vht_rates.rx_max_rate) { | ||
- case 1560: | ||
- /* Must be 2x2 at 160Mhz is all it can do. */ | ||
- arg->peer_bw_rxnss_override = 2; | ||
- break; | ||
- case 780: | ||
- /* Can only do 1x1 at 160Mhz (Long Guard Interval) */ | ||
- arg->peer_bw_rxnss_override = 1; | ||
- break; | ||
- } | ||
+ /* only 4x4 configuration do support 2x2 for VHT160, everything else must use 1x1 */ | ||
+ if (ar->cfg_rx_chainmask == 15) | ||
+ nss160 = arg->peer_num_spatial_streams <= 2 ? arg->peer_num_spatial_streams : 2; | ||
+ | ||
+ /* in case if peer is connected with vht160 or vht80+80, we need to properly adjust rxnss parameters otherwise firmware will raise a assert */ | ||
+ switch(arg->peer_phymode) { | ||
+ case MODE_11AC_VHT80_80: | ||
+ arg->peer_bw_rxnss_override = BW_NSS_FWCONF_80_80(nss160); | ||
+ /* fall through */ | ||
+ case MODE_11AC_VHT160: | ||
+ arg->peer_bw_rxnss_override |= BW_NSS_FWCONF_160(nss160); | ||
+ break; | ||
+ default: | ||
+ break; | ||
} | ||
+ | ||
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x peer_bw_rxnss_override 0x%x\n", | ||
+ sta->addr, arg->peer_max_mpdu, arg->peer_flags, arg->peer_bw_rxnss_override); | ||
} | ||
|
||
static void ath10k_peer_assoc_h_qos(struct ath10k *ar, | ||
@@ -2694,9 +2698,9 @@ static int ath10k_peer_assoc_prepare(str | ||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg); | ||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg); | ||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg); | ||
+ ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); | ||
ath10k_peer_assoc_h_vht(ar, vif, sta, arg); | ||
ath10k_peer_assoc_h_qos(ar, vif, sta, arg); | ||
- ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); | ||
|
||
return 0; | ||
} | ||
--- a/drivers/net/wireless/ath/ath10k/wmi.c | ||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c | ||
@@ -6760,12 +6760,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a | ||
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf; | ||
|
||
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg); | ||
- if (arg->peer_bw_rxnss_override) | ||
- cmd->peer_bw_rxnss_override = | ||
- __cpu_to_le32((arg->peer_bw_rxnss_override - 1) | | ||
- BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET)); | ||
- else | ||
- cmd->peer_bw_rxnss_override = 0; | ||
+ cmd->peer_bw_rxnss_override = __cpu_to_le32(arg->peer_bw_rxnss_override); | ||
} | ||
|
||
static int | ||
--- a/drivers/net/wireless/ath/ath10k/wmi.h | ||
+++ b/drivers/net/wireless/ath/ath10k/wmi.h | ||
@@ -6209,7 +6209,19 @@ struct wmi_10_2_peer_assoc_complete_cmd | ||
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ | ||
} __packed; | ||
|
||
-#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31 | ||
+#define BW_NSS_FWCONF_MAP_ENABLE (1 << 31) | ||
+#define BW_NSS_FWCONF_MAP_160MHZ_S (0) | ||
+#define BW_NSS_FWCONF_MAP_160MHZ_M (0x00000007) | ||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_S (3) | ||
+#define BW_NSS_FWCONF_MAP_80_80MHZ_M (0x00000038) | ||
+#define BW_NSS_FWCONF_MAP_M (0x0000003F) | ||
+ | ||
+#define GET_BW_NSS_FWCONF_160(x) ((((x) & BW_NSS_FWCONF_MAP_160MHZ_M) >> BW_NSS_FWCONF_MAP_160MHZ_S) + 1) | ||
+#define GET_BW_NSS_FWCONF_80_80(x) ((((x) & BW_NSS_FWCONF_MAP_80_80MHZ_M) >> BW_NSS_FWCONF_MAP_80_80MHZ_S) + 1) | ||
+ | ||
+/* Values defined to set 160 MHz Bandwidth NSS Mapping into FW*/ | ||
+#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_160MHZ_S) & BW_NSS_FWCONF_MAP_160MHZ_M)) | ||
+#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | (((x - 1) << BW_NSS_FWCONF_MAP_80_80MHZ_S) & BW_NSS_FWCONF_MAP_80_80MHZ_M)) | ||
|
||
struct wmi_10_4_peer_assoc_complete_cmd { | ||
struct wmi_10_2_peer_assoc_complete_cmd cmd; |
50 changes: 50 additions & 0 deletions
50
...211/patches/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
From: Sebastian Gottschall <[email protected]> | ||
|
||
starting with firmware 10.4.3.4.x series QCA changed the handling of the channel property band_center_freq1 and band_center_freq2 in vht160 operation mode | ||
likelly for backward compatiblity with vht80 only capable clients. | ||
this patch adjusts the handling to get vht160 to work again with official qca firmwares newer than 3.3 | ||
consider that this patch will not work with older firmwares anymore. to avoid undefined behaviour this we disable vht160 capability for outdated firmwares | ||
--- | ||
drivers/net/wireless/ath/ath10k/mac.c | 7 ------- | ||
drivers/net/wireless/ath/ath10k/wmi.c | 11 ++++++++--- | ||
2 files changed, 8 insertions(+), 10 deletions(-) | ||
--- a/drivers/net/wireless/ath/ath10k/mac.c | ||
+++ b/drivers/net/wireless/ath/ath10k/mac.c | ||
@@ -4416,13 +4416,6 @@ static struct ieee80211_sta_vht_cap ath1 | ||
vht_cap.cap |= val; | ||
} | ||
|
||
- /* Currently the firmware seems to be buggy, don't enable 80+80 | ||
- * mode until that's resolved. | ||
- */ | ||
- if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) && | ||
- (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0) | ||
- vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ; | ||
- | ||
mcs_map = 0; | ||
for (i = 0; i < 8; i++) { | ||
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i))) | ||
--- a/drivers/net/wireless/ath/ath10k/wmi.c | ||
+++ b/drivers/net/wireless/ath/ath10k/wmi.c | ||
@@ -1660,13 +1660,18 @@ void ath10k_wmi_put_wmi_channel(struct w | ||
flags |= WMI_CHAN_FLAG_HT40_PLUS; | ||
if (arg->chan_radar) | ||
flags |= WMI_CHAN_FLAG_DFS; | ||
- | ||
+ ch->band_center_freq2 = 0; | ||
ch->mhz = __cpu_to_le32(arg->freq); | ||
ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); | ||
if (arg->mode == MODE_11AC_VHT80_80) | ||
ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2); | ||
- else | ||
- ch->band_center_freq2 = 0; | ||
+ if (arg->mode == MODE_11AC_VHT160) { | ||
+ if (arg->freq < arg->band_center_freq1) | ||
+ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 - 40); | ||
+ else | ||
+ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 + 40); | ||
+ ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1); | ||
+ } | ||
ch->min_power = arg->min_power; | ||
ch->max_power = arg->max_power; | ||
ch->reg_power = arg->max_reg_power; |