mac80211: sync airtime fairness fixes with updated upstream submission
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / subsys / 350-bss-color-collision.patch
1 From 6d945a33f2b0aa24fc210dadaa0af3e8218e7002 Mon Sep 17 00:00:00 2001
2 From: Lorenzo Bianconi <lorenzo@kernel.org>
3 Date: Fri, 25 Mar 2022 11:42:41 +0100
4 Subject: [PATCH] mac80211: introduce BSS color collision detection
5
6 Add ieee80211_rx_check_bss_color_collision routine in order to introduce
7 BSS color collision detection in mac80211 if it is not supported in HW/FW
8 (e.g. for mt7915 chipset).
9 Add IEEE80211_HW_DETECTS_COLOR_COLLISION flag to let the driver notify
10 BSS color collision detection is supported in HW/FW. Set this for ath11k
11 which apparently didn't need this code.
12
13 Tested-by: Peter Chiu <Chui-Hao.Chiu@mediatek.com>
14 Co-developed-by: Ryder Lee <ryder.lee@mediatek.com>
15 Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
16 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
17 Link: https://lore.kernel.org/r/a05eeeb1841a84560dc5aaec77894fcb69a54f27.1648204871.git.lorenzo@kernel.org
18 [clarify commit message a bit, move flag to mac80211]
19 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
20 ---
21 drivers/net/wireless/ath/ath11k/mac.c | 5 ++-
22 include/net/mac80211.h | 4 +++
23 net/mac80211/debugfs.c | 1 +
24 net/mac80211/rx.c | 46 +++++++++++++++++++++++++++
25 4 files changed, 55 insertions(+), 1 deletion(-)
26
27 --- a/include/net/mac80211.h
28 +++ b/include/net/mac80211.h
29 @@ -2422,6 +2422,9 @@ struct ieee80211_txq {
30 * usage and 802.11 frames with %RX_FLAG_ONLY_MONITOR set for monitor to
31 * the stack.
32 *
33 + * @IEEE80211_HW_DETECTS_COLOR_COLLISION: HW/driver has support for BSS color
34 + * collision detection and doesn't need it in software.
35 + *
36 * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
37 */
38 enum ieee80211_hw_flags {
39 @@ -2477,6 +2480,7 @@ enum ieee80211_hw_flags {
40 IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
41 IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
42 IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP,
43 + IEEE80211_HW_DETECTS_COLOR_COLLISION,
44
45 /* keep last, obviously */
46 NUM_IEEE80211_HW_FLAGS
47 --- a/net/mac80211/debugfs.c
48 +++ b/net/mac80211/debugfs.c
49 @@ -504,6 +504,7 @@ static const char *hw_flag_names[] = {
50 FLAG(SUPPORTS_TX_ENCAP_OFFLOAD),
51 FLAG(SUPPORTS_RX_DECAP_OFFLOAD),
52 FLAG(SUPPORTS_CONC_MON_RX_DECAP),
53 + FLAG(DETECTS_COLOR_COLLISION),
54 #undef FLAG
55 };
56
57 --- a/net/mac80211/rx.c
58 +++ b/net/mac80211/rx.c
59 @@ -3177,6 +3177,49 @@ static void ieee80211_process_sa_query_r
60 ieee80211_tx_skb(sdata, skb);
61 }
62
63 +static void
64 +ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
65 +{
66 + struct ieee80211_mgmt *mgmt = (void *)rx->skb->data;
67 + const struct element *ie;
68 + size_t baselen;
69 +
70 + if (!wiphy_ext_feature_isset(rx->local->hw.wiphy,
71 + NL80211_EXT_FEATURE_BSS_COLOR))
72 + return;
73 +
74 + if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION))
75 + return;
76 +
77 + if (rx->sdata->vif.csa_active)
78 + return;
79 +
80 + baselen = mgmt->u.beacon.variable - rx->skb->data;
81 + if (baselen > rx->skb->len)
82 + return;
83 +
84 + ie = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION,
85 + mgmt->u.beacon.variable,
86 + rx->skb->len - baselen);
87 + if (ie && ie->datalen >= sizeof(struct ieee80211_he_operation) &&
88 + ie->datalen >= ieee80211_he_oper_size(ie->data + 1)) {
89 + struct ieee80211_bss_conf *bss_conf = &rx->sdata->vif.bss_conf;
90 + const struct ieee80211_he_operation *he_oper;
91 + u8 color;
92 +
93 + he_oper = (void *)(ie->data + 1);
94 + if (le32_get_bits(he_oper->he_oper_params,
95 + IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED))
96 + return;
97 +
98 + color = le32_get_bits(he_oper->he_oper_params,
99 + IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
100 + if (color == bss_conf->he_bss_color.color)
101 + ieeee80211_obss_color_collision_notify(&rx->sdata->vif,
102 + BIT_ULL(color));
103 + }
104 +}
105 +
106 static ieee80211_rx_result debug_noinline
107 ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
108 {
109 @@ -3202,6 +3245,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802
110 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
111 int sig = 0;
112
113 + /* sw bss color collision detection */
114 + ieee80211_rx_check_bss_color_collision(rx);
115 +
116 if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) &&
117 !(status->flag & RX_FLAG_NO_SIGNAL_VAL))
118 sig = status->signal;