developer | ebaa551 | 2023-04-19 18:23:21 +0800 | [diff] [blame] | 1 | From 40e52a97b1bc7b280198cb63e11663d784bd48c8 Mon Sep 17 00:00:00 2001 |
| 2 | From: Aloka Dixit <quic_alokad@quicinc.com> |
| 3 | Date: Mon, 30 Jan 2023 16:12:24 -0800 |
| 4 | Subject: [PATCH 5/9] wifi: cfg80211: move puncturing bitmap validation from |
| 5 | mac80211 |
| 6 | |
| 7 | - Move ieee80211_valid_disable_subchannel_bitmap() from mlme.c to |
| 8 | chan.c, rename it as cfg80211_valid_disable_subchannel_bitmap() |
| 9 | and export it. |
| 10 | - Modify the prototype to include struct cfg80211_chan_def instead |
| 11 | of only bandwidth to support a check which returns false if the |
| 12 | primary channel is punctured. |
| 13 | |
| 14 | Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com> |
| 15 | Link: https://lore.kernel.org/r/20230131001227.25014-2-quic_alokad@quicinc.com |
| 16 | Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| 17 | --- |
| 18 | include/net/cfg80211.h | 12 +++++++ |
| 19 | net/mac80211/mlme.c | 73 ++++-------------------------------------- |
| 20 | net/wireless/chan.c | 69 +++++++++++++++++++++++++++++++++++++++ |
| 21 | 3 files changed, 87 insertions(+), 67 deletions(-) |
| 22 | |
| 23 | diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h |
| 24 | index 9420086..d532612 100644 |
| 25 | --- a/include/net/cfg80211.h |
| 26 | +++ b/include/net/cfg80211.h |
| 27 | @@ -8948,4 +8948,16 @@ static inline int cfg80211_color_change_notify(struct net_device *dev) |
| 28 | 0, 0); |
| 29 | } |
| 30 | |
| 31 | +/** |
| 32 | + * cfg80211_valid_disable_subchannel_bitmap - validate puncturing bitmap |
| 33 | + * @bitmap: bitmap to be validated |
| 34 | + * @chandef: channel definition |
| 35 | + * |
| 36 | + * Validate the puncturing bitmap. |
| 37 | + * |
| 38 | + * Return: %true if the bitmap is valid. %false otherwise. |
| 39 | + */ |
| 40 | +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, |
| 41 | + const struct cfg80211_chan_def *chandef); |
| 42 | + |
| 43 | #endif /* __NET_CFG80211_H */ |
| 44 | diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c |
| 45 | index 8c69fd6..2716ae0 100644 |
| 46 | --- a/net/mac80211/mlme.c |
| 47 | +++ b/net/mac80211/mlme.c |
| 48 | @@ -88,67 +88,6 @@ MODULE_PARM_DESC(probe_wait_ms, |
| 49 | */ |
| 50 | #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 |
| 51 | |
| 52 | -struct ieee80211_per_bw_puncturing_values { |
| 53 | - u8 len; |
| 54 | - const u16 *valid_values; |
| 55 | -}; |
| 56 | - |
| 57 | -static const u16 puncturing_values_80mhz[] = { |
| 58 | - 0x8, 0x4, 0x2, 0x1 |
| 59 | -}; |
| 60 | - |
| 61 | -static const u16 puncturing_values_160mhz[] = { |
| 62 | - 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3 |
| 63 | -}; |
| 64 | - |
| 65 | -static const u16 puncturing_values_320mhz[] = { |
| 66 | - 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00, |
| 67 | - 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f, |
| 68 | - 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f |
| 69 | -}; |
| 70 | - |
| 71 | -#define IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \ |
| 72 | - { \ |
| 73 | - .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \ |
| 74 | - .valid_values = puncturing_values_ ## _bw ## mhz \ |
| 75 | - } |
| 76 | - |
| 77 | -static const struct ieee80211_per_bw_puncturing_values per_bw_puncturing[] = { |
| 78 | - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(80), |
| 79 | - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(160), |
| 80 | - IEEE80211_PER_BW_VALID_PUNCTURING_VALUES(320) |
| 81 | -}; |
| 82 | - |
| 83 | -static bool ieee80211_valid_disable_subchannel_bitmap(u16 *bitmap, |
| 84 | - enum nl80211_chan_width bw) |
| 85 | -{ |
| 86 | - u32 idx, i; |
| 87 | - |
| 88 | - switch (bw) { |
| 89 | - case NL80211_CHAN_WIDTH_80: |
| 90 | - idx = 0; |
| 91 | - break; |
| 92 | - case NL80211_CHAN_WIDTH_160: |
| 93 | - idx = 1; |
| 94 | - break; |
| 95 | - case NL80211_CHAN_WIDTH_320: |
| 96 | - idx = 2; |
| 97 | - break; |
| 98 | - default: |
| 99 | - *bitmap = 0; |
| 100 | - break; |
| 101 | - } |
| 102 | - |
| 103 | - if (!*bitmap) |
| 104 | - return true; |
| 105 | - |
| 106 | - for (i = 0; i < per_bw_puncturing[idx].len; i++) |
| 107 | - if (per_bw_puncturing[idx].valid_values[i] == *bitmap) |
| 108 | - return true; |
| 109 | - |
| 110 | - return false; |
| 111 | -} |
| 112 | - |
| 113 | /* |
| 114 | * Extract from the given disabled subchannel bitmap (raw format |
| 115 | * from the EHT Operation Element) the bits for the subchannel |
| 116 | @@ -206,8 +145,8 @@ ieee80211_handle_puncturing_bitmap(struct ieee80211_link_data *link, |
| 117 | ieee80211_extract_dis_subch_bmap(eht_oper, chandef, |
| 118 | bitmap); |
| 119 | |
| 120 | - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, |
| 121 | - chandef->width)) |
| 122 | + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap, |
| 123 | + chandef)) |
| 124 | break; |
| 125 | link->u.mgd.conn_flags |= |
| 126 | ieee80211_chandef_downgrade(chandef); |
| 127 | @@ -5584,8 +5523,8 @@ static bool ieee80211_config_puncturing(struct ieee80211_link_data *link, |
| 128 | extracted == link->conf->eht_puncturing) |
| 129 | return true; |
| 130 | |
| 131 | - if (!ieee80211_valid_disable_subchannel_bitmap(&bitmap, |
| 132 | - link->conf->chandef.width)) { |
| 133 | + if (!cfg80211_valid_disable_subchannel_bitmap(&bitmap, |
| 134 | + &link->conf->chandef)) { |
| 135 | link_info(link, |
| 136 | "Got an invalid disable subchannel bitmap from AP %pM: bitmap = 0x%x, bw = 0x%x. disconnect\n", |
| 137 | link->u.mgd.bssid, |
| 138 | @@ -7072,8 +7011,8 @@ ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata, |
| 139 | u16 bitmap; |
| 140 | |
| 141 | bitmap = get_unaligned_le16(disable_subchannel_bitmap); |
| 142 | - if (ieee80211_valid_disable_subchannel_bitmap(&bitmap, |
| 143 | - link->conf->chandef.width)) |
| 144 | + if (cfg80211_valid_disable_subchannel_bitmap(&bitmap, |
| 145 | + &link->conf->chandef)) |
| 146 | ieee80211_handle_puncturing_bitmap(link, |
| 147 | eht_oper, |
| 148 | bitmap, |
| 149 | diff --git a/net/wireless/chan.c b/net/wireless/chan.c |
| 150 | index 29b5c2f..d5ed976 100644 |
| 151 | --- a/net/wireless/chan.c |
| 152 | +++ b/net/wireless/chan.c |
| 153 | @@ -1460,3 +1460,72 @@ struct cfg80211_chan_def *wdev_chandef(struct wireless_dev *wdev, |
| 154 | } |
| 155 | } |
| 156 | EXPORT_SYMBOL(wdev_chandef); |
| 157 | + |
| 158 | +struct cfg80211_per_bw_puncturing_values { |
| 159 | + u8 len; |
| 160 | + const u16 *valid_values; |
| 161 | +}; |
| 162 | + |
| 163 | +static const u16 puncturing_values_80mhz[] = { |
| 164 | + 0x8, 0x4, 0x2, 0x1 |
| 165 | +}; |
| 166 | + |
| 167 | +static const u16 puncturing_values_160mhz[] = { |
| 168 | + 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1, 0xc0, 0x30, 0xc, 0x3 |
| 169 | +}; |
| 170 | + |
| 171 | +static const u16 puncturing_values_320mhz[] = { |
| 172 | + 0xc000, 0x3000, 0xc00, 0x300, 0xc0, 0x30, 0xc, 0x3, 0xf000, 0xf00, |
| 173 | + 0xf0, 0xf, 0xfc00, 0xf300, 0xf0c0, 0xf030, 0xf00c, 0xf003, 0xc00f, |
| 174 | + 0x300f, 0xc0f, 0x30f, 0xcf, 0x3f |
| 175 | +}; |
| 176 | + |
| 177 | +#define CFG80211_PER_BW_VALID_PUNCTURING_VALUES(_bw) \ |
| 178 | + { \ |
| 179 | + .len = ARRAY_SIZE(puncturing_values_ ## _bw ## mhz), \ |
| 180 | + .valid_values = puncturing_values_ ## _bw ## mhz \ |
| 181 | + } |
| 182 | + |
| 183 | +static const struct cfg80211_per_bw_puncturing_values per_bw_puncturing[] = { |
| 184 | + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(80), |
| 185 | + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(160), |
| 186 | + CFG80211_PER_BW_VALID_PUNCTURING_VALUES(320) |
| 187 | +}; |
| 188 | + |
| 189 | +bool cfg80211_valid_disable_subchannel_bitmap(u16 *bitmap, |
| 190 | + const struct cfg80211_chan_def *chandef) |
| 191 | +{ |
| 192 | + u32 idx, i, start_freq; |
| 193 | + |
| 194 | + switch (chandef->width) { |
| 195 | + case NL80211_CHAN_WIDTH_80: |
| 196 | + idx = 0; |
| 197 | + start_freq = chandef->center_freq1 - 40; |
| 198 | + break; |
| 199 | + case NL80211_CHAN_WIDTH_160: |
| 200 | + idx = 1; |
| 201 | + start_freq = chandef->center_freq1 - 80; |
| 202 | + break; |
| 203 | + case NL80211_CHAN_WIDTH_320: |
| 204 | + idx = 2; |
| 205 | + start_freq = chandef->center_freq1 - 160; |
| 206 | + break; |
| 207 | + default: |
| 208 | + *bitmap = 0; |
| 209 | + break; |
| 210 | + } |
| 211 | + |
| 212 | + if (!*bitmap) |
| 213 | + return true; |
| 214 | + |
| 215 | + /* check if primary channel is punctured */ |
| 216 | + if (*bitmap & (u16)BIT((chandef->chan->center_freq - start_freq) / 20)) |
| 217 | + return false; |
| 218 | + |
| 219 | + for (i = 0; i < per_bw_puncturing[idx].len; i++) |
| 220 | + if (per_bw_puncturing[idx].valid_values[i] == *bitmap) |
| 221 | + return true; |
| 222 | + |
| 223 | + return false; |
| 224 | +} |
| 225 | +EXPORT_SYMBOL(cfg80211_valid_disable_subchannel_bitmap); |
| 226 | -- |
| 227 | 2.39.2 |
| 228 | |