blob: 2ab7252662764c932433988bd3c03ef558ab1a6c [file] [log] [blame]
developer0415fc32024-04-19 18:29:00 +08001From 3a7f4236d9d089c749bbc4ff537f8ff2437acf2e Mon Sep 17 00:00:00 2001
2From: Shayne Chen <shayne.chen@mediatek.com>
3Date: Tue, 12 Mar 2024 11:29:55 +0800
4Subject: [PATCH 07/61] sync backports patches/subsys
5
6Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
7---
8 include/net/cfg80211.h | 28 +++++++++++
9 net/mac80211/cfg.c | 2 +
10 net/mac80211/debugfs.c | 13 +++++-
11 net/mac80211/ieee80211_i.h | 4 ++
12 net/mac80211/main.c | 19 +-------
13 net/mac80211/mesh.c | 8 +++-
14 net/mac80211/mesh.h | 31 ++++++++++--
15 net/mac80211/mesh_pathtbl.c | 19 +++++---
16 net/mac80211/rc80211_minstrel_ht.c | 75 +++++++-----------------------
17 net/mac80211/rc80211_minstrel_ht.h | 2 +-
18 net/mac80211/rx.c | 13 ++++--
19 net/mac80211/sta_info.c | 29 +++++++-----
20 net/mac80211/tx.c | 46 +++++++++---------
21 net/wireless/ap.c | 6 +--
22 net/wireless/chan.c | 45 ++++++++++++++++++
23 net/wireless/core.c | 15 ------
24 net/wireless/core.h | 2 +
25 net/wireless/mlme.c | 7 +--
26 net/wireless/sysfs.c | 27 +++++++++--
27 19 files changed, 240 insertions(+), 151 deletions(-)
28
29diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
30index 0b5799f..4c5daf9 100644
31--- a/include/net/cfg80211.h
32+++ b/include/net/cfg80211.h
33@@ -189,6 +189,8 @@ enum ieee80211_channel_flags {
34 * @dfs_state: current state of this channel. Only relevant if radar is required
35 * on this channel.
36 * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
37+ * @dfs_state_last_available: timestamp (jiffies) of the last time when the
38+ * channel was available.
39 * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
40 * @psd: power spectral density (in dBm)
41 */
42@@ -206,6 +208,7 @@ struct ieee80211_channel {
43 int orig_mag, orig_mpwr;
44 enum nl80211_dfs_state dfs_state;
45 unsigned long dfs_state_entered;
46+ unsigned long dfs_state_last_available;
47 unsigned int dfs_cac_ms;
48 s8 psd;
49 };
50@@ -1075,6 +1078,30 @@ int cfg80211_chandef_primary(const struct cfg80211_chan_def *chandef,
51 enum nl80211_chan_width primary_chan_width,
52 u16 *punctured);
53
54+/**
55+ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable and we
56+ * can/need start CAC on such channel
57+ * @wiphy: the wiphy to validate against
58+ * @chandef: the channel definition to check
59+ *
60+ * Return: true if all channels available and at least
61+ * one channel requires CAC (NL80211_DFS_USABLE)
62+ */
63+bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy,
64+ const struct cfg80211_chan_def *chandef);
65+
66+/**
67+ * cfg80211_chandef_dfs_cac_time - get the DFS CAC time (in ms) for given
68+ * channel definition
69+ * @wiphy: the wiphy to validate against
70+ * @chandef: the channel definition to check
71+ *
72+ * Returns: DFS CAC time (in ms) which applies for this channel definition
73+ */
74+unsigned int
75+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
76+ const struct cfg80211_chan_def *chandef);
77+
78 /**
79 * nl80211_send_chandef - sends the channel definition.
80 * @msg: the msg to send channel definition
81@@ -3413,6 +3440,7 @@ enum wiphy_params_flags {
82 /* The per TXQ device queue limit in airtime */
83 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000
84 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000
85+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC 50000
86
87 /* The per interface airtime threshold to switch to lower queue limit */
88 #define IEEE80211_AQL_THRESHOLD 24000
89diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
90index db71792..72e64be 100644
91--- a/net/mac80211/cfg.c
92+++ b/net/mac80211/cfg.c
93@@ -2851,6 +2851,8 @@ static int ieee80211_scan(struct wiphy *wiphy,
94 */
95 fallthrough;
96 case NL80211_IFTYPE_AP:
97+ /* skip check */
98+ break;
99 /*
100 * If the scan has been forced (and the driver supports
101 * forcing), don't care about being beaconing already.
102diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
103index c660138..f9c5ed8 100644
104--- a/net/mac80211/debugfs.c
105+++ b/net/mac80211/debugfs.c
106@@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct file *file,
107 "VI %u us\n"
108 "BE %u us\n"
109 "BK %u us\n"
110+ "BC/MC %u us\n"
111 "total %u us\n",
112 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
113 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
114 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
115 atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
116+ atomic_read(&local->aql_bc_pending_airtime),
117 atomic_read(&local->aql_total_pending_airtime));
118 return simple_read_from_buffer(user_buf, count, ppos,
119 buf, len);
120@@ -245,7 +247,8 @@ static ssize_t aql_txq_limit_read(struct file *file,
121 "VO %u %u\n"
122 "VI %u %u\n"
123 "BE %u %u\n"
124- "BK %u %u\n",
125+ "BK %u %u\n"
126+ "BC/MC %u\n",
127 local->aql_txq_limit_low[IEEE80211_AC_VO],
128 local->aql_txq_limit_high[IEEE80211_AC_VO],
129 local->aql_txq_limit_low[IEEE80211_AC_VI],
130@@ -253,7 +256,8 @@ static ssize_t aql_txq_limit_read(struct file *file,
131 local->aql_txq_limit_low[IEEE80211_AC_BE],
132 local->aql_txq_limit_high[IEEE80211_AC_BE],
133 local->aql_txq_limit_low[IEEE80211_AC_BK],
134- local->aql_txq_limit_high[IEEE80211_AC_BK]);
135+ local->aql_txq_limit_high[IEEE80211_AC_BK],
136+ local->aql_txq_limit_bc);
137 return simple_read_from_buffer(user_buf, count, ppos,
138 buf, len);
139 }
140@@ -279,6 +283,11 @@ static ssize_t aql_txq_limit_write(struct file *file,
141 else
142 buf[count] = '\0';
143
144+ if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
145+ local->aql_txq_limit_bc = q_limit_low;
146+ return count;
147+ }
148+
149 if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
150 return -EINVAL;
151
152diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
153index 4827825..c5781c3 100644
154--- a/net/mac80211/ieee80211_i.h
155+++ b/net/mac80211/ieee80211_i.h
156@@ -102,6 +102,8 @@ ieee80211_sta_keep_active(struct sta_info *sta, u8 ac)
157 return time_before_eq(jiffies, sta->airtime[ac].last_active + HZ / 10);
158 }
159
160+#define AIRTIME_QUANTUM_SHIFT 3
161+
162 struct ieee80211_bss {
163 u32 device_ts_beacon, device_ts_presp;
164
165@@ -1343,10 +1345,12 @@ struct ieee80211_local {
166 spinlock_t handle_wake_tx_queue_lock;
167
168 u16 airtime_flags;
169+ u32 aql_txq_limit_bc;
170 u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
171 u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
172 u32 aql_threshold;
173 atomic_t aql_total_pending_airtime;
174+ atomic_t aql_bc_pending_airtime;
175 atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
176
177 const struct ieee80211_ops *ops;
178diff --git a/net/mac80211/main.c b/net/mac80211/main.c
179index 6518ca5..81a9645 100644
180--- a/net/mac80211/main.c
181+++ b/net/mac80211/main.c
182@@ -944,6 +944,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
183 spin_lock_init(&local->rx_path_lock);
184 spin_lock_init(&local->queue_stop_reason_lock);
185
186+ local->aql_txq_limit_bc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC;
187 for (i = 0; i < IEEE80211_NUM_ACS; i++) {
188 INIT_LIST_HEAD(&local->active_txqs[i]);
189 spin_lock_init(&local->active_txq_lock[i]);
190@@ -1562,24 +1563,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
191 debugfs_hw_add(local);
192 rate_control_add_debugfs(local);
193
194- rtnl_lock();
195- wiphy_lock(hw->wiphy);
196-
197- /* add one default STA interface if supported */
198- if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_STATION) &&
199- !ieee80211_hw_check(hw, NO_AUTO_VIF)) {
200- struct vif_params params = {0};
201-
202- result = ieee80211_if_add(local, "wlan%d", NET_NAME_ENUM, NULL,
203- NL80211_IFTYPE_STATION, &params);
204- if (result)
205- wiphy_warn(local->hw.wiphy,
206- "Failed to add default virtual iface\n");
207- }
208-
209- wiphy_unlock(hw->wiphy);
210- rtnl_unlock();
211-
212 #ifdef CONFIG_INET
213 local->ifa_notifier.notifier_call = ieee80211_ifa_changed;
214 result = register_inetaddr_notifier(&local->ifa_notifier);
215diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
216index 32475da..cbc9b5e 100644
217--- a/net/mac80211/mesh.c
218+++ b/net/mac80211/mesh.c
219@@ -747,6 +747,9 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
220 struct sk_buff *skb, u32 ctrl_flags)
221 {
222 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
223+ struct ieee80211_mesh_fast_tx_key key = {
224+ .type = MESH_FAST_TX_TYPE_LOCAL
225+ };
226 struct ieee80211_mesh_fast_tx *entry;
227 struct ieee80211s_hdr *meshhdr;
228 u8 sa[ETH_ALEN] __aligned(2);
229@@ -782,7 +785,10 @@ bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
230 return false;
231 }
232
233- entry = mesh_fast_tx_get(sdata, skb->data);
234+ ether_addr_copy(key.addr, skb->data);
235+ if (!ether_addr_equal(skb->data + ETH_ALEN, sdata->vif.addr))
236+ key.type = MESH_FAST_TX_TYPE_PROXIED;
237+ entry = mesh_fast_tx_get(sdata, &key);
238 if (!entry)
239 return false;
240
241diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
242index c472b49..c0c357f 100644
243--- a/net/mac80211/mesh.h
244+++ b/net/mac80211/mesh.h
245@@ -134,10 +134,34 @@ struct mesh_path {
246 #define MESH_FAST_TX_CACHE_THRESHOLD_SIZE 384
247 #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */
248
249+/**
250+ * enum ieee80211_mesh_fast_tx_type - cached mesh fast tx entry type
251+ *
252+ * @MESH_FAST_TX_TYPE_LOCAL: tx from the local vif address as SA
253+ * @MESH_FAST_TX_TYPE_PROXIED: local tx with a different SA (e.g. bridged)
254+ * @MESH_FAST_TX_TYPE_FORWARDED: forwarded from a different mesh point
255+ */
256+enum ieee80211_mesh_fast_tx_type {
257+ MESH_FAST_TX_TYPE_LOCAL,
258+ MESH_FAST_TX_TYPE_PROXIED,
259+ MESH_FAST_TX_TYPE_FORWARDED,
260+};
261+
262+/**
263+ * struct ieee80211_mesh_fast_tx_key - cached mesh fast tx entry key
264+ *
265+ * @addr: The Ethernet DA for this entry
266+ * @type: cache entry type
267+ */
268+struct ieee80211_mesh_fast_tx_key {
269+ u8 addr[ETH_ALEN] __aligned(2);
270+ enum ieee80211_mesh_fast_tx_type type;
271+};
272+
273 /**
274 * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry
275 * @rhash: rhashtable pointer
276- * @addr_key: The Ethernet DA which is the key for this entry
277+ * @key: the lookup key for this cache entry
278 * @fast_tx: base fast_tx data
279 * @hdr: cached mesh and rfc1042 headers
280 * @hdrlen: length of mesh + rfc1042
281@@ -148,7 +172,7 @@ struct mesh_path {
282 */
283 struct ieee80211_mesh_fast_tx {
284 struct rhash_head rhash;
285- u8 addr_key[ETH_ALEN] __aligned(2);
286+ struct ieee80211_mesh_fast_tx_key key;
287
288 struct ieee80211_fast_tx fast_tx;
289 u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)];
290@@ -334,7 +358,8 @@ void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata);
291
292 bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt);
293 struct ieee80211_mesh_fast_tx *
294-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr);
295+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
296+ struct ieee80211_mesh_fast_tx_key *key);
297 bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata,
298 struct sk_buff *skb, u32 ctrl_flags);
299 void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
300diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
301index 91b55d6..93f6a03 100644
302--- a/net/mac80211/mesh_pathtbl.c
303+++ b/net/mac80211/mesh_pathtbl.c
304@@ -37,8 +37,8 @@ static const struct rhashtable_params mesh_rht_params = {
305 static const struct rhashtable_params fast_tx_rht_params = {
306 .nelem_hint = 10,
307 .automatic_shrinking = true,
308- .key_len = ETH_ALEN,
309- .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key),
310+ .key_len = sizeof(struct ieee80211_mesh_fast_tx_key),
311+ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, key),
312 .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash),
313 .hashfn = mesh_table_hash,
314 };
315@@ -431,20 +431,21 @@ static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache,
316 }
317
318 struct ieee80211_mesh_fast_tx *
319-mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr)
320+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata,
321+ struct ieee80211_mesh_fast_tx_key *key)
322 {
323 struct ieee80211_mesh_fast_tx *entry;
324 struct mesh_tx_cache *cache;
325
326 cache = &sdata->u.mesh.tx_cache;
327- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
328+ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
329 if (!entry)
330 return NULL;
331
332 if (!(entry->mpath->flags & MESH_PATH_ACTIVE) ||
333 mpath_expired(entry->mpath)) {
334 spin_lock_bh(&cache->walk_lock);
335- entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params);
336+ entry = rhashtable_lookup(&cache->rht, key, fast_tx_rht_params);
337 if (entry)
338 mesh_fast_tx_entry_free(cache, entry);
339 spin_unlock_bh(&cache->walk_lock);
340@@ -489,18 +490,24 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
341 if (!sta)
342 return;
343
344+ build.key.type = MESH_FAST_TX_TYPE_LOCAL;
345 if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) {
346 /* This is required to keep the mppath alive */
347 mppath = mpp_path_lookup(sdata, meshhdr->eaddr1);
348 if (!mppath)
349 return;
350 build.mppath = mppath;
351+ if (!ether_addr_equal(meshhdr->eaddr2, sdata->vif.addr))
352+ build.key.type = MESH_FAST_TX_TYPE_PROXIED;
353 } else if (ieee80211_has_a4(hdr->frame_control)) {
354 mppath = mpath;
355 } else {
356 return;
357 }
358
359+ if (!ether_addr_equal(hdr->addr4, sdata->vif.addr))
360+ build.key.type = MESH_FAST_TX_TYPE_FORWARDED;
361+
362 /* rate limit, in case fast xmit can't be enabled */
363 if (mppath->fast_tx_check == jiffies)
364 return;
365@@ -547,7 +554,7 @@ void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata,
366 }
367 }
368
369- memcpy(build.addr_key, mppath->dst, ETH_ALEN);
370+ memcpy(build.key.addr, mppath->dst, ETH_ALEN);
371 build.timestamp = jiffies;
372 build.fast_tx.band = info->band;
373 build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3);
374diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
375index 62f323a..74413d7 100644
376--- a/net/mac80211/rc80211_minstrel_ht.c
377+++ b/net/mac80211/rc80211_minstrel_ht.c
378@@ -582,6 +582,14 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
379 int cur_tp_avg, cur_group, cur_idx;
380 int max_gpr_group, max_gpr_idx;
381 int max_gpr_tp_avg, max_gpr_prob;
382+ int min_dur;
383+
384+ min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]),
385+ minstrel_get_duration(mi->max_tp_rate[1]));
386+
387+ /* make the rate at least 18% slower than max tp rates */
388+ if (minstrel_get_duration(index) <= min_dur * 19 / 16)
389+ return;
390
391 cur_group = MI_RATE_GROUP(index);
392 cur_idx = MI_RATE_IDX(index);
393@@ -603,11 +611,6 @@ minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u16 *dest, u16 index)
394 !minstrel_ht_is_legacy_group(max_tp_group))
395 return;
396
397- /* skip rates faster than max tp rate with lower prob */
398- if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) &&
399- mrs->prob_avg < max_tp_prob)
400- return;
401-
402 max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate);
403 max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate);
404 max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg;
405@@ -665,40 +668,6 @@ minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi,
406
407 }
408
409-/*
410- * Try to increase robustness of max_prob rate by decrease number of
411- * streams if possible.
412- */
413-static inline void
414-minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi)
415-{
416- struct minstrel_mcs_group_data *mg;
417- int tmp_max_streams, group, tmp_idx, tmp_prob;
418- int tmp_tp = 0;
419-
420- if (!mi->sta->deflink.ht_cap.ht_supported)
421- return;
422-
423- group = MI_RATE_GROUP(mi->max_tp_rate[0]);
424- tmp_max_streams = minstrel_mcs_groups[group].streams;
425- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) {
426- mg = &mi->groups[group];
427- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP)
428- continue;
429-
430- tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate);
431- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg;
432-
433- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) &&
434- (minstrel_mcs_groups[group].streams < tmp_max_streams)) {
435- mi->max_prob_rate = mg->max_group_prob_rate;
436- tmp_tp = minstrel_ht_get_tp_avg(mi, group,
437- tmp_idx,
438- tmp_prob);
439- }
440- }
441-}
442-
443 static u16
444 __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi,
445 enum minstrel_sample_type type)
446@@ -771,7 +740,8 @@ minstrel_ht_calc_rate_stats(struct minstrel_priv *mp,
447 unsigned int cur_prob;
448
449 if (unlikely(mrs->attempts > 0)) {
450- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts);
451+ cur_prob = MINSTREL_FRAC(mrs->success + mrs->last_success,
452+ mrs->attempts + mrs->last_attempts);
453 minstrel_filter_avg_add(&mrs->prob_avg,
454 &mrs->prob_avg_1, cur_prob);
455 mrs->att_hist += mrs->attempts;
456@@ -1177,8 +1147,6 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi)
457
458 mi->max_prob_rate = tmp_max_prob_rate;
459
460- /* Try to increase robustness of max_prob_rate*/
461- minstrel_ht_prob_rate_reduce_streams(mi);
462 minstrel_ht_refill_sample_rates(mi);
463
464 #ifdef CPTCFG_MAC80211_DEBUGFS
465@@ -1257,7 +1225,7 @@ minstrel_ht_ri_txstat_valid(struct minstrel_priv *mp,
466 }
467
468 static void
469-minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
470+minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx)
471 {
472 int group, orig_group;
473
474@@ -1272,11 +1240,7 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary)
475 minstrel_mcs_groups[orig_group].streams)
476 continue;
477
478- if (primary)
479- *idx = mi->groups[group].max_group_tp_rate[0];
480- else
481- *idx = mi->groups[group].max_group_tp_rate[1];
482- break;
483+ *idx = mi->groups[group].max_group_prob_rate;
484 }
485 }
486
487@@ -1287,7 +1251,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
488 struct ieee80211_tx_info *info = st->info;
489 struct minstrel_ht_sta *mi = priv_sta;
490 struct ieee80211_tx_rate *ar = info->status.rates;
491- struct minstrel_rate_stats *rate, *rate2;
492+ struct minstrel_rate_stats *rate;
493 struct minstrel_priv *mp = priv;
494 u32 update_interval = mp->update_interval;
495 bool last, update = false;
496@@ -1355,18 +1319,13 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
497 /*
498 * check for sudden death of spatial multiplexing,
499 * downgrade to a lower number of streams if necessary.
500+ * only do this for the max_prob_rate to prevent spurious
501+ * rate fluctuations when the link changes suddenly
502 */
503- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]);
504+ rate = minstrel_get_ratestats(mi, mi->max_prob_rate);
505 if (rate->attempts > 30 &&
506 rate->success < rate->attempts / 4) {
507- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true);
508- update = true;
509- }
510-
511- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]);
512- if (rate2->attempts > 30 &&
513- rate2->success < rate2->attempts / 4) {
514- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false);
515+ minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate);
516 update = true;
517 }
518 }
519diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h
520index f385cf6..1f78a94 100644
521--- a/net/mac80211/rc80211_minstrel_ht.h
522+++ b/net/mac80211/rc80211_minstrel_ht.h
523@@ -14,7 +14,7 @@
524
525 /* scaled fraction values */
526 #define MINSTREL_SCALE 12
527-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div)
528+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div))
529 #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE)
530
531 #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */
532diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
533index 42ffd1e..be724c2 100644
534--- a/net/mac80211/rx.c
535+++ b/net/mac80211/rx.c
536@@ -2767,7 +2767,10 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
537 struct sk_buff *skb, int hdrlen)
538 {
539 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
540- struct ieee80211_mesh_fast_tx *entry = NULL;
541+ struct ieee80211_mesh_fast_tx_key key = {
542+ .type = MESH_FAST_TX_TYPE_FORWARDED
543+ };
544+ struct ieee80211_mesh_fast_tx *entry;
545 struct ieee80211s_hdr *mesh_hdr;
546 struct tid_ampdu_tx *tid_tx;
547 struct sta_info *sta;
548@@ -2776,9 +2779,13 @@ ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata,
549
550 mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth));
551 if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6)
552- entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1);
553+ ether_addr_copy(key.addr, mesh_hdr->eaddr1);
554 else if (!(mesh_hdr->flags & MESH_FLAGS_AE))
555- entry = mesh_fast_tx_get(sdata, skb->data);
556+ ether_addr_copy(key.addr, skb->data);
557+ else
558+ return false;
559+
560+ entry = mesh_fast_tx_get(sdata, &key);
561 if (!entry)
562 return false;
563
564diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
565index 32d050c..411a610 100644
566--- a/net/mac80211/sta_info.c
567+++ b/net/mac80211/sta_info.c
568@@ -912,6 +912,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
569
570 if (ieee80211_vif_is_mesh(&sdata->vif))
571 mesh_accept_plinks_update(sdata);
572+ ieee80211_check_fast_xmit(sta);
573
574 ieee80211_check_fast_xmit(sta);
575
576@@ -2354,28 +2355,27 @@ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
577 struct sta_info *sta, u8 ac,
578 u16 tx_airtime, bool tx_completed)
579 {
580+ atomic_t *counter;
581 int tx_pending;
582
583 if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
584 return;
585
586- if (!tx_completed) {
587- if (sta)
588- atomic_add(tx_airtime,
589- &sta->airtime[ac].aql_tx_pending);
590+ if (sta)
591+ counter = &sta->airtime[ac].aql_tx_pending;
592+ else
593+ counter = &local->aql_bc_pending_airtime;
594
595+ if (!tx_completed) {
596+ atomic_add(tx_airtime, counter);
597 atomic_add(tx_airtime, &local->aql_total_pending_airtime);
598 atomic_add(tx_airtime, &local->aql_ac_pending_airtime[ac]);
599 return;
600 }
601
602- if (sta) {
603- tx_pending = atomic_sub_return(tx_airtime,
604- &sta->airtime[ac].aql_tx_pending);
605- if (tx_pending < 0)
606- atomic_cmpxchg(&sta->airtime[ac].aql_tx_pending,
607- tx_pending, 0);
608- }
609+ tx_pending = atomic_sub_return(tx_airtime, counter);
610+ if (tx_pending < 0)
611+ atomic_cmpxchg(counter, tx_pending, 0);
612
613 atomic_sub(tx_airtime, &local->aql_total_pending_airtime);
614 tx_pending = atomic_sub_return(tx_airtime,
615@@ -2439,6 +2439,13 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u32 rate,
616
617 sband = local->hw.wiphy->bands[band];
618
619+ if (!sband) {
620+ wiphy_warn(local->hw.wiphy,
621+ "Invalid band %d\n",
622+ band);
623+ break;
624+ }
625+
626 if (WARN_ON_ONCE(!sband->bitrates))
627 break;
628
629diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
630index 141b094..f479d87 100644
631--- a/net/mac80211/tx.c
632+++ b/net/mac80211/tx.c
633@@ -3978,9 +3978,8 @@ begin:
634 encap_out:
635 info->control.vif = vif;
636
637- if (tx.sta &&
638- wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
639- bool ampdu = txq->ac != IEEE80211_AC_VO;
640+ if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
641+ bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
642 u32 airtime;
643
644 airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
645@@ -4043,6 +4042,7 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
646 struct ieee80211_txq *ret = NULL;
647 struct txq_info *txqi = NULL, *head = NULL;
648 bool found_eligible_txq = false;
649+ bool aql_check;
650
651 spin_lock_bh(&local->active_txq_lock[ac]);
652
653@@ -4066,26 +4066,26 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac)
654 if (!head)
655 head = txqi;
656
657+ aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
658+ if (aql_check)
659+ found_eligible_txq = true;
660+
661 if (txqi->txq.sta) {
662 struct sta_info *sta = container_of(txqi->txq.sta,
663 struct sta_info, sta);
664- bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
665- s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
666-
667- if (aql_check)
668- found_eligible_txq = true;
669-
670- if (deficit < 0)
671+ if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
672 sta->airtime[txqi->txq.ac].deficit +=
673- sta->airtime_weight;
674-
675- if (deficit < 0 || !aql_check) {
676- list_move_tail(&txqi->schedule_order,
677- &local->active_txqs[txqi->txq.ac]);
678- goto begin;
679+ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
680+ aql_check = false;
681 }
682 }
683
684+ if (!aql_check) {
685+ list_move_tail(&txqi->schedule_order,
686+ &local->active_txqs[txqi->txq.ac]);
687+ goto begin;
688+ }
689+
690 if (txqi->schedule_round == local->schedule_round[ac])
691 goto out;
692
693@@ -4150,7 +4150,8 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw,
694 return true;
695
696 if (!txq->sta)
697- return true;
698+ return atomic_read(&local->aql_bc_pending_airtime) <
699+ local->aql_txq_limit_bc;
700
701 if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
702 return true;
703@@ -4199,15 +4200,15 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
704
705 spin_lock_bh(&local->active_txq_lock[ac]);
706
707- if (!txqi->txq.sta)
708- goto out;
709-
710 if (list_empty(&txqi->schedule_order))
711 goto out;
712
713 if (!ieee80211_txq_schedule_airtime_check(local, ac))
714 goto out;
715
716+ if (!txqi->txq.sta)
717+ goto out;
718+
719 list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
720 schedule_order) {
721 if (iter == txqi)
722@@ -4220,7 +4221,8 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
723 }
724 sta = container_of(iter->txq.sta, struct sta_info, sta);
725 if (ieee80211_sta_deficit(sta, ac) < 0)
726- sta->airtime[ac].deficit += sta->airtime_weight;
727+ sta->airtime[ac].deficit += sta->airtime_weight <<
728+ AIRTIME_QUANTUM_SHIFT;
729 list_move_tail(&iter->schedule_order, &local->active_txqs[ac]);
730 }
731
732@@ -4228,7 +4230,7 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw,
733 if (sta->airtime[ac].deficit >= 0)
734 goto out;
735
736- sta->airtime[ac].deficit += sta->airtime_weight;
737+ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
738 list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]);
739 spin_unlock_bh(&local->active_txq_lock[ac]);
740
741diff --git a/net/wireless/ap.c b/net/wireless/ap.c
742index 9a9a870..9cd0ab4 100644
743--- a/net/wireless/ap.c
744+++ b/net/wireless/ap.c
745@@ -30,6 +30,9 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
746 if (!wdev->links[link_id].ap.beacon_interval)
747 return -ENOENT;
748
749+ cfg80211_update_last_available(wdev->wiphy,
750+ &wdev->links[link_id].ap.chandef);
751+
752 err = rdev_stop_ap(rdev, dev, link_id);
753 if (!err) {
754 wdev->conn_owner_nlportid = 0;
755@@ -41,9 +44,6 @@ static int ___cfg80211_stop_ap(struct cfg80211_registered_device *rdev,
756 if (notify)
757 nl80211_send_ap_stopped(wdev, link_id);
758
759- /* Should we apply the grace period during beaconing interface
760- * shutdown also?
761- */
762 cfg80211_sched_dfs_chan_update(rdev);
763 }
764
765diff --git a/net/wireless/chan.c b/net/wireless/chan.c
766index 14c27bc..4bac395 100644
767--- a/net/wireless/chan.c
768+++ b/net/wireless/chan.c
769@@ -560,6 +560,8 @@ static void cfg80211_set_chans_dfs_state(struct wiphy *wiphy, u32 center_freq,
770
771 c->dfs_state = dfs_state;
772 c->dfs_state_entered = jiffies;
773+ if (dfs_state == NL80211_DFS_AVAILABLE)
774+ c->dfs_state_last_available = jiffies;
775 }
776 }
777
778@@ -1049,6 +1051,49 @@ static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy,
779 return true;
780 }
781
782+static void
783+__cfg80211_update_last_available(struct wiphy *wiphy,
784+ u32 center_freq,
785+ u32 bandwidth)
786+{
787+ struct ieee80211_channel *c;
788+ u32 freq, start_freq, end_freq;
789+
790+ start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
791+ end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
792+
793+ /*
794+ * Check entire range of channels for the bandwidth.
795+ * If any channel in between is disabled or has not
796+ * had gone through CAC return false
797+ */
798+ for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
799+ c = ieee80211_get_channel_khz(wiphy, freq);
800+ if (!c)
801+ return;
802+
803+ c->dfs_state_last_available = jiffies;
804+ }
805+}
806+
807+void cfg80211_update_last_available(struct wiphy *wiphy,
808+ const struct cfg80211_chan_def *chandef)
809+{
810+ int width;
811+
812+ width = cfg80211_chandef_get_width(chandef);
813+ if (width < 0)
814+ return;
815+
816+ __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq1),
817+ width);
818+ if (chandef->width != NL80211_CHAN_WIDTH_80P80)
819+ return;
820+
821+ __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq2),
822+ width);
823+}
824+
825 static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
826 const struct cfg80211_chan_def *chandef)
827 {
828diff --git a/net/wireless/core.c b/net/wireless/core.c
829index 0cd5c78..ac9417e 100644
830--- a/net/wireless/core.c
831+++ b/net/wireless/core.c
832@@ -662,21 +662,6 @@ static int wiphy_verify_combinations(struct wiphy *wiphy)
833 c->limits[j].max > 1))
834 return -EINVAL;
835
836- /*
837- * This isn't well-defined right now. If you have an
838- * IBSS interface, then its beacon interval may change
839- * by joining other networks, and nothing prevents it
840- * from doing that.
841- * So technically we probably shouldn't even allow AP
842- * and IBSS in the same interface, but it seems that
843- * some drivers support that, possibly only with fixed
844- * beacon intervals for IBSS.
845- */
846- if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) &&
847- c->beacon_int_min_gcd)) {
848- return -EINVAL;
849- }
850-
851 cnt += c->limits[j].max;
852 /*
853 * Don't advertise an unsupported type
854diff --git a/net/wireless/core.h b/net/wireless/core.h
855index 2e19279..7bef6b0 100644
856--- a/net/wireless/core.h
857+++ b/net/wireless/core.h
858@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,
859 enum nl80211_dfs_state dfs_state);
860
861 void cfg80211_dfs_channels_update_work(struct work_struct *work);
862+void cfg80211_update_last_available(struct wiphy *wiphy,
863+ const struct cfg80211_chan_def *chandef);
864
865 void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
866
867diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
868index 3b0fe7c..c7e62eb 100644
869--- a/net/wireless/mlme.c
870+++ b/net/wireless/mlme.c
871@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
872 if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
873 time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
874 radar_event = NL80211_RADAR_NOP_FINISHED;
875+ timeout = c->dfs_state_entered +
876+ msecs_to_jiffies(time_dfs_update);
877 } else {
878 if (regulatory_pre_cac_allowed(wiphy) ||
879 cfg80211_any_wiphy_oper_chan(wiphy, c))
880@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(struct work_struct *work)
881
882 time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
883 radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
884+ timeout = c->dfs_state_last_available +
885+ msecs_to_jiffies(time_dfs_update);
886 }
887
888- timeout = c->dfs_state_entered +
889- msecs_to_jiffies(time_dfs_update);
890-
891 if (time_after_eq(jiffies, timeout)) {
892 c->dfs_state = NL80211_DFS_USABLE;
893 c->dfs_state_entered = jiffies;
894diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
895index 1387106..49aac4c 100644
896--- a/net/wireless/sysfs.c
897+++ b/net/wireless/sysfs.c
898@@ -24,18 +24,35 @@ static inline struct cfg80211_registered_device *dev_to_rdev(
899 return container_of(dev, struct cfg80211_registered_device, wiphy.dev);
900 }
901
902-#define SHOW_FMT(name, fmt, member) \
903+#define SHOW_FMT(name, fmt, member, mode) \
904 static ssize_t name ## _show(struct device *dev, \
905 struct device_attribute *attr, \
906 char *buf) \
907 { \
908 return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \
909 } \
910-static DEVICE_ATTR_RO(name)
911+static DEVICE_ATTR_##mode(name)
912
913-SHOW_FMT(index, "%d", wiphy_idx);
914-SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
915-SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
916+static ssize_t macaddress_store(struct device *dev,
917+ struct device_attribute *attr,
918+ const char *buf, size_t len)
919+{
920+ u8 mac[ETH_ALEN];
921+
922+ if (!mac_pton(buf, mac))
923+ return -EINVAL;
924+
925+ if (buf[3 * ETH_ALEN - 1] && buf[3 * ETH_ALEN - 1] != '\n')
926+ return -EINVAL;
927+
928+ memcpy(dev_to_rdev(dev)->wiphy.perm_addr, mac, ETH_ALEN);
929+
930+ return strnlen(buf, len);
931+}
932+
933+SHOW_FMT(index, "%d", wiphy_idx, RO);
934+SHOW_FMT(macaddress, "%pM", wiphy.perm_addr, RW);
935+SHOW_FMT(address_mask, "%pM", wiphy.addr_mask, RO);
936
937 static ssize_t name_show(struct device *dev,
938 struct device_attribute *attr,
939--
9402.39.2
941