Files
openwrt-R7800-nss/package/kernel/mac80211/patches/subsys/200-mac80211-introduce-support-for-vendor-QAM-256-in-2.4.patch
2025-02-17 19:33:46 +01:00

233 lines
7.0 KiB
Diff

From 35040d1f349f2346832ca1ebb408924dbefc1cfc Mon Sep 17 00:00:00 2001
From: Christian Marangi <ansuelsmth@gmail.com>
Date: Wed, 14 Jun 2023 07:15:48 +0200
Subject: [PATCH 1/4] mac80211: introduce support for vendor QAM-256 in 2.4GHz
802.11n
Some vendor supports non-standard QAM-256 in 2.4GHz 802.11n mode.
The implementation works by comunicating vht capabilities to the client
in 2.4GHz 802.11n, the supported client will take this info and
benefits from the additional rates of it.
Each driver needs to enable support for this by enabling the
vendor_qam256_supported in the 2G sband struct and add the required
capabilities for vht_cap.
This feature is supported by various vendor with all kind of marketing
name, but all of them have in common the use of vht capabilities in
2.4GHz 802.11n.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
include/net/cfg80211.h | 2 ++
net/mac80211/mlme.c | 14 ++++++++----
net/mac80211/util.c | 10 +++++---
net/mac80211/vht.c | 52 +++++++++++++++++++++++++++---------------
4 files changed, 51 insertions(+), 27 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 1b8619685bf6..e9c9afae9a80 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -338,11 +338,13 @@ struct ieee80211_sta_ht_cap {
* to describe 802.11ac VHT capabilities for an STA.
*
* @vht_supported: is VHT supported by the STA
+ * @qam256_supported: is QAM256 supported by the STA
* @cap: VHT capabilities map as described in 802.11ac spec
* @vht_mcs: Supported VHT MCS rates
*/
struct ieee80211_sta_vht_cap {
bool vht_supported;
+ bool vendor_qam256_supported;
u32 cap; /* use IEEE80211_VHT_CAP_ */
struct ieee80211_vht_mcs_info vht_mcs;
};
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 3827b5dcdb03..9c3b3de28dc8 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4720,7 +4720,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
const struct cfg80211_bss_ies *ies;
int ret;
u32 i;
- bool have_80mhz;
+ bool can_vht;
rcu_read_lock();
@@ -4867,18 +4867,22 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
}
/* Allow VHT if at least one channel on the sband supports 80 MHz */
- have_80mhz = false;
+ can_vht = false;
for (i = 0; i < sband->n_channels; i++) {
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
IEEE80211_CHAN_NO_80MHZ))
continue;
- have_80mhz = true;
+ can_vht = true;
break;
}
- if (!have_80mhz) {
- sdata_info(sdata, "80 MHz not supported, disabling VHT\n");
+ /* Some Vendor supports non-standard QAM-256 on 2.4GHz 802.11n */
+ if (sband->vht_cap.vendor_qam256_supported)
+ can_vht = true;
+
+ if (!can_vht) {
+ sdata_info(sdata, "80 MHz or QAM-256 not supported, disabling VHT\n");
*conn_flags |= IEEE80211_CONN_DISABLE_VHT;
}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 083ad56d08d9..3fc1e84e4275 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1951,7 +1951,7 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
int ext_rates_len;
int shift;
u32 rate_flags;
- bool have_80mhz = false;
+ bool can_vht = false;
*offset = 0;
@@ -2089,11 +2089,15 @@ static int ieee80211_build_preq_ies_band(struct ieee80211_sub_if_data *sdata,
IEEE80211_CHAN_NO_80MHZ))
continue;
- have_80mhz = true;
+ can_vht = true;
break;
}
- if (sband->vht_cap.vht_supported && have_80mhz) {
+ /* Some Vendor supports non-standard QAM-256 on 2.4GHz 802.11n */
+ if (sband->vht_cap.vendor_qam256_supported)
+ can_vht = true;
+
+ if (sband->vht_cap.vht_supported && can_vht) {
if (end - pos < 2 + sizeof(struct ieee80211_vht_cap))
goto out_err;
pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
diff --git a/net/mac80211/vht.c b/net/mac80211/vht.c
index c1250aa47808..37f4673d4194 100644
--- a/net/mac80211/vht.c
+++ b/net/mac80211/vht.c
@@ -121,7 +121,7 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap;
struct ieee80211_sta_vht_cap own_cap;
u32 cap_info, i;
- bool have_80mhz;
+ bool can_vht;
memset(vht_cap, 0, sizeof(*vht_cap));
@@ -132,17 +132,21 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
return;
/* Allow VHT if at least one channel on the sband supports 80 MHz */
- have_80mhz = false;
+ can_vht = false;
for (i = 0; i < sband->n_channels; i++) {
if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
IEEE80211_CHAN_NO_80MHZ))
continue;
- have_80mhz = true;
+ can_vht = true;
break;
}
- if (!have_80mhz)
+ /* Some Vendor supports non-standard QAM-256 on 2.4GHz 802.11n */
+ if (sband->vht_cap.vendor_qam256_supported)
+ can_vht = true;
+
+ if (!can_vht)
return;
/*
@@ -346,16 +350,16 @@ ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta)
struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap;
struct ieee80211_sta_he_cap *he_cap = &link_sta->pub->he_cap;
struct ieee80211_sta_eht_cap *eht_cap = &link_sta->pub->eht_cap;
+ struct ieee80211_bss_conf *link_conf;
+ enum ieee80211_sta_rx_bandwidth ret;
u32 cap_width;
+ rcu_read_lock();
+ link_conf = rcu_dereference(sdata->vif.link_conf[link_id]);
+
if (he_cap->has_he) {
- struct ieee80211_bss_conf *link_conf;
- enum ieee80211_sta_rx_bandwidth ret;
u8 info;
- rcu_read_lock();
- link_conf = rcu_dereference(sdata->vif.link_conf[link_id]);
-
if (eht_cap->has_eht &&
link_conf->chandef.chan->band == NL80211_BAND_6GHZ) {
info = eht_cap->eht_cap_elem.phy_cap_info[0];
@@ -383,32 +387,42 @@ ieee80211_sta_cap_rx_bw(struct link_sta_info *link_sta)
ret = IEEE80211_STA_RX_BW_80;
else
ret = IEEE80211_STA_RX_BW_20;
-out:
- rcu_read_unlock();
- return ret;
+ goto out;
}
- if (!vht_cap->vht_supported)
- return link_sta->pub->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
+ if (!vht_cap->vht_supported ||
+ (link_conf->chandef.chan->band == NL80211_BAND_2GHZ &&
+ vht_cap->vendor_qam256_supported)) {
+ ret = link_sta->pub->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40 ?
IEEE80211_STA_RX_BW_40 :
IEEE80211_STA_RX_BW_20;
+ goto out;
+ }
cap_width = vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
if (cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
- cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
- return IEEE80211_STA_RX_BW_160;
+ cap_width == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ) {
+ ret = IEEE80211_STA_RX_BW_160;
+ goto out;
+ }
/*
* If this is non-zero, then it does support 160 MHz after all,
* in one form or the other. We don't distinguish here (or even
* above) between 160 and 80+80 yet.
*/
- if (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK)
- return IEEE80211_STA_RX_BW_160;
+ if (vht_cap->cap & IEEE80211_VHT_CAP_EXT_NSS_BW_MASK) {
+ ret = IEEE80211_STA_RX_BW_160;
+ goto out;
+ }
+
+ ret = IEEE80211_STA_RX_BW_80;
- return IEEE80211_STA_RX_BW_80;
+out:
+ rcu_read_unlock();
+ return ret;
}
enum nl80211_chan_width
--
2.40.1