mac80211: reorder patches in subsys/
authorFelix Fietkau <nbd@nbd.name>
Mon, 30 Sep 2024 08:06:31 +0000 (10:06 +0200)
committerFelix Fietkau <nbd@nbd.name>
Mon, 30 Sep 2024 09:32:38 +0000 (11:32 +0200)
Close some patch numbering gaps left behind by updates

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch [deleted file]
package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/330-mac80211-add-AQL-support-for-broadcast-packets.patch [deleted file]
package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch [new file with mode: 0644]
package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch [deleted file]
package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch [deleted file]
package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch [deleted file]

diff --git a/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch
new file mode 100644 (file)
index 0000000..5537636
--- /dev/null
@@ -0,0 +1,40 @@
+From: Hauke Mehrtens <hauke@hauke-m.de>
+Date: Mon, 24 Feb 2020 00:00:00 +0100
+Subject: [PATCH] mac80211: Allow IBSS mode and different beacon intervals
+
+ath10k-ct supports the combination to select IBSS (ADHOC) mode and
+different beacon intervals together. mac80211 does not like this
+combination, but Ben says this is ok, so remove this check.
+
+ath10k-ct starting with version 5.2 allows the combination of
+NL80211_IFTYPE_ADHOC and beacon_int_min_gcd in ath10k_10x_ct_if_comb
+which triggers this warning. Ben told me that this is not a big problem
+and we should ignore this.
+---
+ net/wireless/core.c | 15 ---------------
+ 1 file changed, 15 deletions(-)
+
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -654,21 +654,6 @@ static int wiphy_verify_combinations(str
+                                   c->limits[j].max > 1))
+                               return -EINVAL;
+-                      /*
+-                       * This isn't well-defined right now. If you have an
+-                       * IBSS interface, then its beacon interval may change
+-                       * by joining other networks, and nothing prevents it
+-                       * from doing that.
+-                       * So technically we probably shouldn't even allow AP
+-                       * and IBSS in the same interface, but it seems that
+-                       * some drivers support that, possibly only with fixed
+-                       * beacon intervals for IBSS.
+-                       */
+-                      if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) &&
+-                                  c->beacon_int_min_gcd)) {
+-                              return -EINVAL;
+-                      }
+-
+                       cnt += c->limits[j].max;
+                       /*
+                        * Don't advertise an unsupported type
diff --git a/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch b/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch
new file mode 100644 (file)
index 0000000..9e9e384
--- /dev/null
@@ -0,0 +1,34 @@
+From: David Bauer <mail@david-bauer.net>
+Date: Thu, 30 Nov 2023 07:32:52 +0100
+Subject: [PATCH] mac80211: avoid crashing on invalid band info
+
+Frequent crashes have been observed on MT7916 based platforms. While the
+root of these crashes are currently unknown, they happen when decoding
+rate information of connected STAs in AP mode. The rate-information is
+associated with a band which is not available on the PHY.
+
+Check for this condition in order to avoid crashing the whole system.
+This patch should be removed once the roout cause has been found and
+fixed.
+
+Link: https://github.com/freifunk-gluon/gluon/issues/2980
+
+Signed-off-by: David Bauer <mail@david-bauer.net>
+---
+
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2439,6 +2439,13 @@ static void sta_stats_decode_rate(struct
+               sband = local->hw.wiphy->bands[band];
++              if (!sband) {
++                      wiphy_warn(local->hw.wiphy,
++                                  "Invalid band %d\n",
++                                  band);
++                      break;
++              }
++
+               if (WARN_ON_ONCE(!sband->bitrates))
+                       break;
diff --git a/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch b/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch
new file mode 100644 (file)
index 0000000..7e9be59
--- /dev/null
@@ -0,0 +1,149 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Thu, 14 Sep 2023 13:17:16 +0200
+Subject: [PATCH] cfg80211: allow grace period for DFS available after beacon
+ shutdown
+
+Fixes reconfiguring an AP on a DFS channel in non-ETSI regdomain
+
+Fixes: b35a51c7dd25 ("cfg80211: Make pre-CAC results valid only for ETSI domain")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -187,6 +187,8 @@ enum ieee80211_channel_flags {
+  * @dfs_state: current state of this channel. Only relevant if radar is required
+  *    on this channel.
+  * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
++ * @dfs_state_last_available: timestamp (jiffies) of the last time when the
++ *    channel was available.
+  * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
+  * @psd: power spectral density (in dBm)
+  */
+@@ -204,6 +206,7 @@ struct ieee80211_channel {
+       int orig_mag, orig_mpwr;
+       enum nl80211_dfs_state dfs_state;
+       unsigned long dfs_state_entered;
++      unsigned long dfs_state_last_available;
+       unsigned int dfs_cac_ms;
+       s8 psd;
+ };
+--- a/net/wireless/ap.c
++++ b/net/wireless/ap.c
+@@ -30,6 +30,9 @@ static int ___cfg80211_stop_ap(struct cf
+       if (!wdev->links[link_id].ap.beacon_interval)
+               return -ENOENT;
++      cfg80211_update_last_available(wdev->wiphy,
++                                     &wdev->links[link_id].ap.chandef);
++
+       err = rdev_stop_ap(rdev, dev, link_id);
+       if (!err) {
+               wdev->conn_owner_nlportid = 0;
+@@ -41,9 +44,6 @@ static int ___cfg80211_stop_ap(struct cf
+               if (notify)
+                       nl80211_send_ap_stopped(wdev, link_id);
+-              /* Should we apply the grace period during beaconing interface
+-               * shutdown also?
+-               */
+               cfg80211_sched_dfs_chan_update(rdev);
+       }
+--- a/net/wireless/chan.c
++++ b/net/wireless/chan.c
+@@ -598,6 +598,8 @@ static void cfg80211_set_chans_dfs_state
+               c->dfs_state = dfs_state;
+               c->dfs_state_entered = jiffies;
++              if (dfs_state == NL80211_DFS_AVAILABLE)
++                      c->dfs_state_last_available = jiffies;
+       }
+ }
+@@ -1087,6 +1089,49 @@ static bool cfg80211_get_chans_dfs_avail
+       return true;
+ }
++static void
++__cfg80211_update_last_available(struct wiphy *wiphy,
++                                       u32 center_freq,
++                                       u32 bandwidth)
++{
++      struct ieee80211_channel *c;
++      u32 freq, start_freq, end_freq;
++
++      start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
++      end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
++
++      /*
++       * Check entire range of channels for the bandwidth.
++       * If any channel in between is disabled or has not
++       * had gone through CAC return false
++       */
++      for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
++              c = ieee80211_get_channel_khz(wiphy, freq);
++              if (!c)
++                      return;
++
++              c->dfs_state_last_available = jiffies;
++      }
++}
++
++void cfg80211_update_last_available(struct wiphy *wiphy,
++                                  const struct cfg80211_chan_def *chandef)
++{
++      int width;
++
++      width = cfg80211_chandef_get_width(chandef);
++      if (width < 0)
++              return;
++
++      __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq1),
++                                               width);
++      if (chandef->width != NL80211_CHAN_WIDTH_80P80)
++          return;
++
++      __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq2),
++                                               width);
++}
++
+ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
+                               const struct cfg80211_chan_def *chandef)
+ {
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy
+                           enum nl80211_dfs_state dfs_state);
+ void cfg80211_dfs_channels_update_work(struct work_struct *work);
++void cfg80211_update_last_available(struct wiphy *wiphy,
++                                  const struct cfg80211_chan_def *chandef);
+ void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(s
+                       if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
+                               time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
+                               radar_event = NL80211_RADAR_NOP_FINISHED;
++                              timeout = c->dfs_state_entered +
++                                        msecs_to_jiffies(time_dfs_update);
+                       } else {
+                               if (regulatory_pre_cac_allowed(wiphy) ||
+                                   cfg80211_any_wiphy_oper_chan(wiphy, c))
+@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(s
+                               time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
+                               radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
++                              timeout = c->dfs_state_last_available +
++                                        msecs_to_jiffies(time_dfs_update);
+                       }
+-                      timeout = c->dfs_state_entered +
+-                                msecs_to_jiffies(time_dfs_update);
+-
+                       if (time_after_eq(jiffies, timeout)) {
+                               c->dfs_state = NL80211_DFS_USABLE;
+                               c->dfs_state_entered = jiffies;
diff --git a/package/kernel/mac80211/patches/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch b/package/kernel/mac80211/patches/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch
deleted file mode 100644 (file)
index 7e9be59..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Thu, 14 Sep 2023 13:17:16 +0200
-Subject: [PATCH] cfg80211: allow grace period for DFS available after beacon
- shutdown
-
-Fixes reconfiguring an AP on a DFS channel in non-ETSI regdomain
-
-Fixes: b35a51c7dd25 ("cfg80211: Make pre-CAC results valid only for ETSI domain")
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -187,6 +187,8 @@ enum ieee80211_channel_flags {
-  * @dfs_state: current state of this channel. Only relevant if radar is required
-  *    on this channel.
-  * @dfs_state_entered: timestamp (jiffies) when the dfs state was entered.
-+ * @dfs_state_last_available: timestamp (jiffies) of the last time when the
-+ *    channel was available.
-  * @dfs_cac_ms: DFS CAC time in milliseconds, this is valid for DFS channels.
-  * @psd: power spectral density (in dBm)
-  */
-@@ -204,6 +206,7 @@ struct ieee80211_channel {
-       int orig_mag, orig_mpwr;
-       enum nl80211_dfs_state dfs_state;
-       unsigned long dfs_state_entered;
-+      unsigned long dfs_state_last_available;
-       unsigned int dfs_cac_ms;
-       s8 psd;
- };
---- a/net/wireless/ap.c
-+++ b/net/wireless/ap.c
-@@ -30,6 +30,9 @@ static int ___cfg80211_stop_ap(struct cf
-       if (!wdev->links[link_id].ap.beacon_interval)
-               return -ENOENT;
-+      cfg80211_update_last_available(wdev->wiphy,
-+                                     &wdev->links[link_id].ap.chandef);
-+
-       err = rdev_stop_ap(rdev, dev, link_id);
-       if (!err) {
-               wdev->conn_owner_nlportid = 0;
-@@ -41,9 +44,6 @@ static int ___cfg80211_stop_ap(struct cf
-               if (notify)
-                       nl80211_send_ap_stopped(wdev, link_id);
--              /* Should we apply the grace period during beaconing interface
--               * shutdown also?
--               */
-               cfg80211_sched_dfs_chan_update(rdev);
-       }
---- a/net/wireless/chan.c
-+++ b/net/wireless/chan.c
-@@ -598,6 +598,8 @@ static void cfg80211_set_chans_dfs_state
-               c->dfs_state = dfs_state;
-               c->dfs_state_entered = jiffies;
-+              if (dfs_state == NL80211_DFS_AVAILABLE)
-+                      c->dfs_state_last_available = jiffies;
-       }
- }
-@@ -1087,6 +1089,49 @@ static bool cfg80211_get_chans_dfs_avail
-       return true;
- }
-+static void
-+__cfg80211_update_last_available(struct wiphy *wiphy,
-+                                       u32 center_freq,
-+                                       u32 bandwidth)
-+{
-+      struct ieee80211_channel *c;
-+      u32 freq, start_freq, end_freq;
-+
-+      start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
-+      end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
-+
-+      /*
-+       * Check entire range of channels for the bandwidth.
-+       * If any channel in between is disabled or has not
-+       * had gone through CAC return false
-+       */
-+      for (freq = start_freq; freq <= end_freq; freq += MHZ_TO_KHZ(20)) {
-+              c = ieee80211_get_channel_khz(wiphy, freq);
-+              if (!c)
-+                      return;
-+
-+              c->dfs_state_last_available = jiffies;
-+      }
-+}
-+
-+void cfg80211_update_last_available(struct wiphy *wiphy,
-+                                  const struct cfg80211_chan_def *chandef)
-+{
-+      int width;
-+
-+      width = cfg80211_chandef_get_width(chandef);
-+      if (width < 0)
-+              return;
-+
-+      __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq1),
-+                                               width);
-+      if (chandef->width != NL80211_CHAN_WIDTH_80P80)
-+          return;
-+
-+      __cfg80211_update_last_available(wiphy, MHZ_TO_KHZ(chandef->center_freq2),
-+                                               width);
-+}
-+
- static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
-                               const struct cfg80211_chan_def *chandef)
- {
---- a/net/wireless/core.h
-+++ b/net/wireless/core.h
-@@ -467,6 +467,8 @@ void cfg80211_set_dfs_state(struct wiphy
-                           enum nl80211_dfs_state dfs_state);
- void cfg80211_dfs_channels_update_work(struct work_struct *work);
-+void cfg80211_update_last_available(struct wiphy *wiphy,
-+                                  const struct cfg80211_chan_def *chandef);
- void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev);
---- a/net/wireless/mlme.c
-+++ b/net/wireless/mlme.c
-@@ -1037,6 +1037,8 @@ void cfg80211_dfs_channels_update_work(s
-                       if (c->dfs_state == NL80211_DFS_UNAVAILABLE) {
-                               time_dfs_update = IEEE80211_DFS_MIN_NOP_TIME_MS;
-                               radar_event = NL80211_RADAR_NOP_FINISHED;
-+                              timeout = c->dfs_state_entered +
-+                                        msecs_to_jiffies(time_dfs_update);
-                       } else {
-                               if (regulatory_pre_cac_allowed(wiphy) ||
-                                   cfg80211_any_wiphy_oper_chan(wiphy, c))
-@@ -1044,11 +1046,10 @@ void cfg80211_dfs_channels_update_work(s
-                               time_dfs_update = REG_PRE_CAC_EXPIRY_GRACE_MS;
-                               radar_event = NL80211_RADAR_PRE_CAC_EXPIRED;
-+                              timeout = c->dfs_state_last_available +
-+                                        msecs_to_jiffies(time_dfs_update);
-                       }
--                      timeout = c->dfs_state_entered +
--                                msecs_to_jiffies(time_dfs_update);
--
-                       if (time_after_eq(jiffies, timeout)) {
-                               c->dfs_state = NL80211_DFS_USABLE;
-                               c->dfs_state_entered = jiffies;
diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch
new file mode 100644 (file)
index 0000000..3b6cba4
--- /dev/null
@@ -0,0 +1,293 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Fri, 9 Feb 2024 19:43:40 +0100
+Subject: [PATCH] mac80211: add AQL support for broadcast packets
+
+Excessive broadcast traffic with little competing unicast traffic can easily
+flood hardware queues, leading to throughput issues. Additionally, filling
+the hardware queues with too many packets breaks FQ for broadcast data.
+Fix this by enabling AQL for broadcast packets.
+
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -3423,6 +3423,7 @@ enum wiphy_params_flags {
+ /* The per TXQ device queue limit in airtime */
+ #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L     5000
+ #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H     12000
++#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC    50000
+ /* The per interface airtime threshold to switch to lower queue limit */
+ #define IEEE80211_AQL_THRESHOLD                       24000
+--- a/net/mac80211/debugfs.c
++++ b/net/mac80211/debugfs.c
+@@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct f
+                       "VI     %u us\n"
+                       "BE     %u us\n"
+                       "BK     %u us\n"
++                      "BC/MC  %u us\n"
+                       "total  %u us\n",
+                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
+                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
+                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
+                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
++                      atomic_read(&local->aql_bc_pending_airtime),
+                       atomic_read(&local->aql_total_pending_airtime));
+       return simple_read_from_buffer(user_buf, count, ppos,
+                                      buf, len);
+@@ -245,7 +247,8 @@ static ssize_t aql_txq_limit_read(struct
+                       "VO     %u              %u\n"
+                       "VI     %u              %u\n"
+                       "BE     %u              %u\n"
+-                      "BK     %u              %u\n",
++                      "BK     %u              %u\n"
++                      "BC/MC  %u\n",
+                       local->aql_txq_limit_low[IEEE80211_AC_VO],
+                       local->aql_txq_limit_high[IEEE80211_AC_VO],
+                       local->aql_txq_limit_low[IEEE80211_AC_VI],
+@@ -253,7 +256,8 @@ static ssize_t aql_txq_limit_read(struct
+                       local->aql_txq_limit_low[IEEE80211_AC_BE],
+                       local->aql_txq_limit_high[IEEE80211_AC_BE],
+                       local->aql_txq_limit_low[IEEE80211_AC_BK],
+-                      local->aql_txq_limit_high[IEEE80211_AC_BK]);
++                      local->aql_txq_limit_high[IEEE80211_AC_BK],
++                      local->aql_txq_limit_bc);
+       return simple_read_from_buffer(user_buf, count, ppos,
+                                      buf, len);
+ }
+@@ -279,6 +283,11 @@ static ssize_t aql_txq_limit_write(struc
+       else
+               buf[count] = '\0';
++      if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
++              local->aql_txq_limit_bc = q_limit_low;
++              return count;
++      }
++
+       if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
+               return -EINVAL;
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1351,10 +1351,12 @@ struct ieee80211_local {
+       spinlock_t handle_wake_tx_queue_lock;
+       u16 airtime_flags;
++      u32 aql_txq_limit_bc;
+       u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
+       u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
+       u32 aql_threshold;
+       atomic_t aql_total_pending_airtime;
++      atomic_t aql_bc_pending_airtime;
+       atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
+       const struct ieee80211_ops *ops;
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -952,6 +952,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
+       spin_lock_init(&local->rx_path_lock);
+       spin_lock_init(&local->queue_stop_reason_lock);
++      local->aql_txq_limit_bc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC;
+       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
+               INIT_LIST_HEAD(&local->active_txqs[i]);
+               spin_lock_init(&local->active_txq_lock[i]);
+--- a/net/mac80211/sta_info.c
++++ b/net/mac80211/sta_info.c
+@@ -2353,13 +2353,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre
+ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
+                                         struct sta_info *sta, u8 ac,
+-                                        u16 tx_airtime, bool tx_completed)
++                                        u16 tx_airtime, bool tx_completed,
++                                        bool mcast)
+ {
+       int tx_pending;
+       if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
+               return;
++      if (mcast) {
++              if (!tx_completed) {
++                      atomic_add(tx_airtime, &local->aql_bc_pending_airtime);
++                      return;
++              }
++
++              tx_pending = atomic_sub_return(tx_airtime,
++                                             &local->aql_bc_pending_airtime);
++              if (tx_pending < 0)
++                      atomic_cmpxchg(&local->aql_bc_pending_airtime,
++                                     tx_pending, 0);
++              return;
++      }
++
+       if (!tx_completed) {
+               if (sta)
+                       atomic_add(tx_airtime,
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -2554,7 +2554,7 @@ static u16 ieee80211_store_ack_skb(struc
+               spin_lock_irqsave(&local->ack_status_lock, flags);
+               id = idr_alloc(&local->ack_status_frames, ack_skb,
+-                             1, 0x2000, GFP_ATOMIC);
++                             1, 0x1000, GFP_ATOMIC);
+               spin_unlock_irqrestore(&local->ack_status_lock, flags);
+               if (id >= 0) {
+@@ -3982,20 +3982,20 @@ begin:
+ encap_out:
+       info->control.vif = vif;
+-      if (tx.sta &&
+-          wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
+-              bool ampdu = txq->ac != IEEE80211_AC_VO;
++      if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
++              bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
+               u32 airtime;
+               airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
+                                                            skb->len, ampdu);
+-              if (airtime) {
+-                      airtime = ieee80211_info_set_tx_time_est(info, airtime);
+-                      ieee80211_sta_update_pending_airtime(local, tx.sta,
+-                                                           txq->ac,
+-                                                           airtime,
+-                                                           false);
+-              }
++              if (!airtime)
++                      return skb;
++
++              airtime = ieee80211_info_set_tx_time_est(info, airtime);
++              info->tx_time_mc = !tx.sta;
++              ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
++                                                   airtime, false,
++                                                   info->tx_time_mc);
+       }
+       return skb;
+@@ -4047,6 +4047,7 @@ struct ieee80211_txq *ieee80211_next_txq
+       struct ieee80211_txq *ret = NULL;
+       struct txq_info *txqi = NULL, *head = NULL;
+       bool found_eligible_txq = false;
++      bool aql_check;
+       spin_lock_bh(&local->active_txq_lock[ac]);
+@@ -4070,26 +4071,26 @@ struct ieee80211_txq *ieee80211_next_txq
+       if (!head)
+               head = txqi;
++      aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
++      if (aql_check)
++              found_eligible_txq = true;
++
+       if (txqi->txq.sta) {
+               struct sta_info *sta = container_of(txqi->txq.sta,
+                                                   struct sta_info, sta);
+-              bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
+-              s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
+-
+-              if (aql_check)
+-                      found_eligible_txq = true;
+-
+-              if (deficit < 0)
++              if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
+                       sta->airtime[txqi->txq.ac].deficit +=
+                               sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
+-
+-              if (deficit < 0 || !aql_check) {
+-                      list_move_tail(&txqi->schedule_order,
+-                                     &local->active_txqs[txqi->txq.ac]);
+-                      goto begin;
++                      aql_check = false;
+               }
+       }
++      if (!aql_check) {
++              list_move_tail(&txqi->schedule_order,
++                                 &local->active_txqs[txqi->txq.ac]);
++              goto begin;
++      }
++
+       if (txqi->schedule_round == local->schedule_round[ac])
+               goto out;
+@@ -4154,7 +4155,8 @@ bool ieee80211_txq_airtime_check(struct
+               return true;
+       if (!txq->sta)
+-              return true;
++              return atomic_read(&local->aql_bc_pending_airtime) <
++                     local->aql_txq_limit_bc;
+       if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
+               return true;
+@@ -4203,15 +4205,15 @@ bool ieee80211_txq_may_transmit(struct i
+       spin_lock_bh(&local->active_txq_lock[ac]);
+-      if (!txqi->txq.sta)
+-              goto out;
+-
+       if (list_empty(&txqi->schedule_order))
+               goto out;
+       if (!ieee80211_txq_schedule_airtime_check(local, ac))
+               goto out;
++      if (!txqi->txq.sta)
++              goto out;
++
+       list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
+                                schedule_order) {
+               if (iter == txqi)
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1221,8 +1221,8 @@ struct ieee80211_tx_info {
+           status_data_idr:1,
+           status_data:13,
+           hw_queue:4,
++          tx_time_mc:1,
+           tx_time_est:10;
+-      /* 1 free bit */
+       union {
+               struct {
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -147,7 +147,8 @@ struct airtime_info {
+ void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
+                                         struct sta_info *sta, u8 ac,
+-                                        u16 tx_airtime, bool tx_completed);
++                                        u16 tx_airtime, bool tx_completed,
++                                        bool mcast);
+ struct sta_info;
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -734,7 +734,7 @@ static void ieee80211_report_used_skb(st
+               ieee80211_sta_update_pending_airtime(local, sta,
+                                                    skb_get_queue_mapping(skb),
+                                                    tx_time_est,
+-                                                   true);
++                                                   true, info->tx_time_mc);
+               rcu_read_unlock();
+       }
+@@ -1158,10 +1158,11 @@ void ieee80211_tx_status_ext(struct ieee
+               /* Do this here to avoid the expensive lookup of the sta
+                * in ieee80211_report_used_skb().
+                */
++              bool mcast = IEEE80211_SKB_CB(skb)->tx_time_mc;
+               ieee80211_sta_update_pending_airtime(local, sta,
+                                                    skb_get_queue_mapping(skb),
+                                                    tx_time_est,
+-                                                   true);
++                                                   true, mcast);
+               ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
+       }
diff --git a/package/kernel/mac80211/patches/subsys/330-mac80211-add-AQL-support-for-broadcast-packets.patch b/package/kernel/mac80211/patches/subsys/330-mac80211-add-AQL-support-for-broadcast-packets.patch
deleted file mode 100644 (file)
index 3b6cba4..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Fri, 9 Feb 2024 19:43:40 +0100
-Subject: [PATCH] mac80211: add AQL support for broadcast packets
-
-Excessive broadcast traffic with little competing unicast traffic can easily
-flood hardware queues, leading to throughput issues. Additionally, filling
-the hardware queues with too many packets breaks FQ for broadcast data.
-Fix this by enabling AQL for broadcast packets.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/include/net/cfg80211.h
-+++ b/include/net/cfg80211.h
-@@ -3423,6 +3423,7 @@ enum wiphy_params_flags {
- /* The per TXQ device queue limit in airtime */
- #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L     5000
- #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H     12000
-+#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC    50000
- /* The per interface airtime threshold to switch to lower queue limit */
- #define IEEE80211_AQL_THRESHOLD                       24000
---- a/net/mac80211/debugfs.c
-+++ b/net/mac80211/debugfs.c
-@@ -215,11 +215,13 @@ static ssize_t aql_pending_read(struct f
-                       "VI     %u us\n"
-                       "BE     %u us\n"
-                       "BK     %u us\n"
-+                      "BC/MC  %u us\n"
-                       "total  %u us\n",
-                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]),
-                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]),
-                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]),
-                       atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]),
-+                      atomic_read(&local->aql_bc_pending_airtime),
-                       atomic_read(&local->aql_total_pending_airtime));
-       return simple_read_from_buffer(user_buf, count, ppos,
-                                      buf, len);
-@@ -245,7 +247,8 @@ static ssize_t aql_txq_limit_read(struct
-                       "VO     %u              %u\n"
-                       "VI     %u              %u\n"
-                       "BE     %u              %u\n"
--                      "BK     %u              %u\n",
-+                      "BK     %u              %u\n"
-+                      "BC/MC  %u\n",
-                       local->aql_txq_limit_low[IEEE80211_AC_VO],
-                       local->aql_txq_limit_high[IEEE80211_AC_VO],
-                       local->aql_txq_limit_low[IEEE80211_AC_VI],
-@@ -253,7 +256,8 @@ static ssize_t aql_txq_limit_read(struct
-                       local->aql_txq_limit_low[IEEE80211_AC_BE],
-                       local->aql_txq_limit_high[IEEE80211_AC_BE],
-                       local->aql_txq_limit_low[IEEE80211_AC_BK],
--                      local->aql_txq_limit_high[IEEE80211_AC_BK]);
-+                      local->aql_txq_limit_high[IEEE80211_AC_BK],
-+                      local->aql_txq_limit_bc);
-       return simple_read_from_buffer(user_buf, count, ppos,
-                                      buf, len);
- }
-@@ -279,6 +283,11 @@ static ssize_t aql_txq_limit_write(struc
-       else
-               buf[count] = '\0';
-+      if (sscanf(buf, "mcast %u", &q_limit_low) == 1) {
-+              local->aql_txq_limit_bc = q_limit_low;
-+              return count;
-+      }
-+
-       if (sscanf(buf, "%u %u %u", &ac, &q_limit_low, &q_limit_high) != 3)
-               return -EINVAL;
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -1351,10 +1351,12 @@ struct ieee80211_local {
-       spinlock_t handle_wake_tx_queue_lock;
-       u16 airtime_flags;
-+      u32 aql_txq_limit_bc;
-       u32 aql_txq_limit_low[IEEE80211_NUM_ACS];
-       u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
-       u32 aql_threshold;
-       atomic_t aql_total_pending_airtime;
-+      atomic_t aql_bc_pending_airtime;
-       atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS];
-       const struct ieee80211_ops *ops;
---- a/net/mac80211/main.c
-+++ b/net/mac80211/main.c
-@@ -952,6 +952,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
-       spin_lock_init(&local->rx_path_lock);
-       spin_lock_init(&local->queue_stop_reason_lock);
-+      local->aql_txq_limit_bc = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_BC;
-       for (i = 0; i < IEEE80211_NUM_ACS; i++) {
-               INIT_LIST_HEAD(&local->active_txqs[i]);
-               spin_lock_init(&local->active_txq_lock[i]);
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -2353,13 +2353,28 @@ EXPORT_SYMBOL(ieee80211_sta_recalc_aggre
- void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
-                                         struct sta_info *sta, u8 ac,
--                                        u16 tx_airtime, bool tx_completed)
-+                                        u16 tx_airtime, bool tx_completed,
-+                                        bool mcast)
- {
-       int tx_pending;
-       if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL))
-               return;
-+      if (mcast) {
-+              if (!tx_completed) {
-+                      atomic_add(tx_airtime, &local->aql_bc_pending_airtime);
-+                      return;
-+              }
-+
-+              tx_pending = atomic_sub_return(tx_airtime,
-+                                             &local->aql_bc_pending_airtime);
-+              if (tx_pending < 0)
-+                      atomic_cmpxchg(&local->aql_bc_pending_airtime,
-+                                     tx_pending, 0);
-+              return;
-+      }
-+
-       if (!tx_completed) {
-               if (sta)
-                       atomic_add(tx_airtime,
---- a/net/mac80211/tx.c
-+++ b/net/mac80211/tx.c
-@@ -2554,7 +2554,7 @@ static u16 ieee80211_store_ack_skb(struc
-               spin_lock_irqsave(&local->ack_status_lock, flags);
-               id = idr_alloc(&local->ack_status_frames, ack_skb,
--                             1, 0x2000, GFP_ATOMIC);
-+                             1, 0x1000, GFP_ATOMIC);
-               spin_unlock_irqrestore(&local->ack_status_lock, flags);
-               if (id >= 0) {
-@@ -3982,20 +3982,20 @@ begin:
- encap_out:
-       info->control.vif = vif;
--      if (tx.sta &&
--          wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
--              bool ampdu = txq->ac != IEEE80211_AC_VO;
-+      if (wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) {
-+              bool ampdu = txq->sta && txq->ac != IEEE80211_AC_VO;
-               u32 airtime;
-               airtime = ieee80211_calc_expected_tx_airtime(hw, vif, txq->sta,
-                                                            skb->len, ampdu);
--              if (airtime) {
--                      airtime = ieee80211_info_set_tx_time_est(info, airtime);
--                      ieee80211_sta_update_pending_airtime(local, tx.sta,
--                                                           txq->ac,
--                                                           airtime,
--                                                           false);
--              }
-+              if (!airtime)
-+                      return skb;
-+
-+              airtime = ieee80211_info_set_tx_time_est(info, airtime);
-+              info->tx_time_mc = !tx.sta;
-+              ieee80211_sta_update_pending_airtime(local, tx.sta, txq->ac,
-+                                                   airtime, false,
-+                                                   info->tx_time_mc);
-       }
-       return skb;
-@@ -4047,6 +4047,7 @@ struct ieee80211_txq *ieee80211_next_txq
-       struct ieee80211_txq *ret = NULL;
-       struct txq_info *txqi = NULL, *head = NULL;
-       bool found_eligible_txq = false;
-+      bool aql_check;
-       spin_lock_bh(&local->active_txq_lock[ac]);
-@@ -4070,26 +4071,26 @@ struct ieee80211_txq *ieee80211_next_txq
-       if (!head)
-               head = txqi;
-+      aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
-+      if (aql_check)
-+              found_eligible_txq = true;
-+
-       if (txqi->txq.sta) {
-               struct sta_info *sta = container_of(txqi->txq.sta,
-                                                   struct sta_info, sta);
--              bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq);
--              s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac);
--
--              if (aql_check)
--                      found_eligible_txq = true;
--
--              if (deficit < 0)
-+              if (ieee80211_sta_deficit(sta, txqi->txq.ac) < 0) {
-                       sta->airtime[txqi->txq.ac].deficit +=
-                               sta->airtime_weight << AIRTIME_QUANTUM_SHIFT;
--
--              if (deficit < 0 || !aql_check) {
--                      list_move_tail(&txqi->schedule_order,
--                                     &local->active_txqs[txqi->txq.ac]);
--                      goto begin;
-+                      aql_check = false;
-               }
-       }
-+      if (!aql_check) {
-+              list_move_tail(&txqi->schedule_order,
-+                                 &local->active_txqs[txqi->txq.ac]);
-+              goto begin;
-+      }
-+
-       if (txqi->schedule_round == local->schedule_round[ac])
-               goto out;
-@@ -4154,7 +4155,8 @@ bool ieee80211_txq_airtime_check(struct
-               return true;
-       if (!txq->sta)
--              return true;
-+              return atomic_read(&local->aql_bc_pending_airtime) <
-+                     local->aql_txq_limit_bc;
-       if (unlikely(txq->tid == IEEE80211_NUM_TIDS))
-               return true;
-@@ -4203,15 +4205,15 @@ bool ieee80211_txq_may_transmit(struct i
-       spin_lock_bh(&local->active_txq_lock[ac]);
--      if (!txqi->txq.sta)
--              goto out;
--
-       if (list_empty(&txqi->schedule_order))
-               goto out;
-       if (!ieee80211_txq_schedule_airtime_check(local, ac))
-               goto out;
-+      if (!txqi->txq.sta)
-+              goto out;
-+
-       list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac],
-                                schedule_order) {
-               if (iter == txqi)
---- a/include/net/mac80211.h
-+++ b/include/net/mac80211.h
-@@ -1221,8 +1221,8 @@ struct ieee80211_tx_info {
-           status_data_idr:1,
-           status_data:13,
-           hw_queue:4,
-+          tx_time_mc:1,
-           tx_time_est:10;
--      /* 1 free bit */
-       union {
-               struct {
---- a/net/mac80211/sta_info.h
-+++ b/net/mac80211/sta_info.h
-@@ -147,7 +147,8 @@ struct airtime_info {
- void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local,
-                                         struct sta_info *sta, u8 ac,
--                                        u16 tx_airtime, bool tx_completed);
-+                                        u16 tx_airtime, bool tx_completed,
-+                                        bool mcast);
- struct sta_info;
---- a/net/mac80211/status.c
-+++ b/net/mac80211/status.c
-@@ -734,7 +734,7 @@ static void ieee80211_report_used_skb(st
-               ieee80211_sta_update_pending_airtime(local, sta,
-                                                    skb_get_queue_mapping(skb),
-                                                    tx_time_est,
--                                                   true);
-+                                                   true, info->tx_time_mc);
-               rcu_read_unlock();
-       }
-@@ -1158,10 +1158,11 @@ void ieee80211_tx_status_ext(struct ieee
-               /* Do this here to avoid the expensive lookup of the sta
-                * in ieee80211_report_used_skb().
-                */
-+              bool mcast = IEEE80211_SKB_CB(skb)->tx_time_mc;
-               ieee80211_sta_update_pending_airtime(local, sta,
-                                                    skb_get_queue_mapping(skb),
-                                                    tx_time_est,
--                                                   true);
-+                                                   true, mcast);
-               ieee80211_info_set_tx_time_est(IEEE80211_SKB_CB(skb), 0);
-       }
diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch b/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch
new file mode 100644 (file)
index 0000000..0a3c8ec
--- /dev/null
@@ -0,0 +1,233 @@
+From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Date: Wed, 4 Sep 2024 19:12:56 +0800
+Subject: [PATCH] wifi: mac80211: introduce EHT rate support in AQL airtime
+
+Add definitions related to EHT mode and airtime calculation
+according to the 802.11BE_D4.0.
+
+Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
+Signed-off-by: Deren Wu <deren.wu@mediatek.com>
+Signed-off-by: Quan Zhou <quan.zhou@mediatek.com>
+Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
+Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/airtime.c
++++ b/net/mac80211/airtime.c
+@@ -55,10 +55,21 @@
+ #define HE_DURATION_S(shift, streams, gi, bps)                \
+       (HE_DURATION(streams, gi, bps) >> shift)
++/* gi in HE/EHT is identical. It matches enum nl80211_eht_gi as well */
++#define EHT_GI_08 HE_GI_08
++#define EHT_GI_16 HE_GI_16
++#define EHT_GI_32 HE_GI_32
++
++#define EHT_DURATION(streams, gi, bps)                        \
++      HE_DURATION(streams, gi, bps)
++#define EHT_DURATION_S(shift, streams, gi, bps)               \
++      HE_DURATION_S(shift, streams, gi, bps)
++
+ #define BW_20                 0
+ #define BW_40                 1
+ #define BW_80                 2
+ #define BW_160                        3
++#define BW_320                        4
+ /*
+  * Define group sort order: HT40 -> SGI -> #streams
+@@ -68,17 +79,26 @@
+ #define IEEE80211_VHT_STREAM_GROUPS   8 /* BW(=4) * SGI(=2) */
+ #define IEEE80211_HE_MAX_STREAMS      8
++#define IEEE80211_HE_STREAM_GROUPS    12 /* BW(=4) * GI(=3) */
++
++#define IEEE80211_EHT_MAX_STREAMS     8
++#define IEEE80211_EHT_STREAM_GROUPS   15 /* BW(=5) * GI(=3) */
+ #define IEEE80211_HT_GROUPS_NB        (IEEE80211_MAX_STREAMS *        \
+                                IEEE80211_HT_STREAM_GROUPS)
+ #define IEEE80211_VHT_GROUPS_NB       (IEEE80211_MAX_STREAMS *        \
+                                        IEEE80211_VHT_STREAM_GROUPS)
++#define IEEE80211_HE_GROUPS_NB        (IEEE80211_HE_MAX_STREAMS *     \
++                               IEEE80211_HE_STREAM_GROUPS)
++#define IEEE80211_EHT_GROUPS_NB       (IEEE80211_EHT_MAX_STREAMS *    \
++                               IEEE80211_EHT_STREAM_GROUPS)
+ #define IEEE80211_HT_GROUP_0  0
+ #define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
+ #define IEEE80211_HE_GROUP_0  (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
++#define IEEE80211_EHT_GROUP_0 (IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB)
+-#define MCS_GROUP_RATES               12
++#define MCS_GROUP_RATES               14
+ #define HT_GROUP_IDX(_streams, _sgi, _ht40)   \
+       IEEE80211_HT_GROUP_0 +                  \
+@@ -203,6 +223,69 @@
+ #define HE_GROUP(_streams, _gi, _bw)                                  \
+       __HE_GROUP(_streams, _gi, _bw,                          \
+                  HE_GROUP_SHIFT(_streams, _gi, _bw))
++
++#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1)                                  \
++      ((_bw) == BW_320 ? r5 : BW2VBPS(_bw, r4, r3, r2, r1))
++
++#define EHT_GROUP_IDX(_streams, _gi, _bw)                             \
++      (IEEE80211_EHT_GROUP_0 +                                        \
++       IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) +                        \
++       IEEE80211_EHT_MAX_STREAMS * (_gi) +                            \
++       (_streams) - 1)
++
++#define __EHT_GROUP(_streams, _gi, _bw, _s)                                           \
++      [EHT_GROUP_IDX(_streams, _gi, _bw)] = {                                         \
++      .shift = _s,                                                                    \
++      .duration = {                                                                   \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw,  1960,   980,  490,  234,  117)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw,  3920,  1960,  980,  468,  234)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw,  5880,  2937, 1470,  702,  351)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw,  7840,  3920, 1960,  936,  468)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 11760,  5880, 2940, 1404,  702)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 15680,  7840, 3920, 1872,  936)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 17640,  8820, 4410, 2106, 1053)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 19600,  9800, 4900, 2340, 1170)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 23520, 11760, 5880, 2808, 1404)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 26133, 13066, 6533, 3120, 1560)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 29400, 14700, 7350, 3510, 1755)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 32666, 16333, 8166, 3900, 1950)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 35280, 17640, 8820, 4212, 2106)),       \
++              EHT_DURATION_S(_s, _streams, _gi,                                       \
++                             EHT_BW2VBPS(_bw, 39200, 19600, 9800, 4680, 2340))        \
++              }                                                                       \
++}
++
++#define EHT_GROUP_SHIFT(_streams, _gi, _bw)                                           \
++      GROUP_SHIFT(EHT_DURATION(_streams, _gi,                                         \
++                               EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)))
++
++#define EHT_GROUP(_streams, _gi, _bw)                                 \
++      __EHT_GROUP(_streams, _gi, _bw,                         \
++                 EHT_GROUP_SHIFT(_streams, _gi, _bw))
++
++#define EHT_GROUP_RANGE(_gi, _bw)     \
++      EHT_GROUP(1, _gi, _bw),         \
++      EHT_GROUP(2, _gi, _bw),         \
++      EHT_GROUP(3, _gi, _bw),         \
++      EHT_GROUP(4, _gi, _bw),         \
++      EHT_GROUP(5, _gi, _bw),         \
++      EHT_GROUP(6, _gi, _bw),         \
++      EHT_GROUP(7, _gi, _bw),         \
++      EHT_GROUP(8, _gi, _bw)
++
+ struct mcs_group {
+       u8 shift;
+       u16 duration[MCS_GROUP_RATES];
+@@ -376,6 +459,26 @@ static const struct mcs_group airtime_mc
+       HE_GROUP(6, HE_GI_32, BW_160),
+       HE_GROUP(7, HE_GI_32, BW_160),
+       HE_GROUP(8, HE_GI_32, BW_160),
++
++      EHT_GROUP_RANGE(EHT_GI_08, BW_20),
++      EHT_GROUP_RANGE(EHT_GI_16, BW_20),
++      EHT_GROUP_RANGE(EHT_GI_32, BW_20),
++
++      EHT_GROUP_RANGE(EHT_GI_08, BW_40),
++      EHT_GROUP_RANGE(EHT_GI_16, BW_40),
++      EHT_GROUP_RANGE(EHT_GI_32, BW_40),
++
++      EHT_GROUP_RANGE(EHT_GI_08, BW_80),
++      EHT_GROUP_RANGE(EHT_GI_16, BW_80),
++      EHT_GROUP_RANGE(EHT_GI_32, BW_80),
++
++      EHT_GROUP_RANGE(EHT_GI_08, BW_160),
++      EHT_GROUP_RANGE(EHT_GI_16, BW_160),
++      EHT_GROUP_RANGE(EHT_GI_32, BW_160),
++
++      EHT_GROUP_RANGE(EHT_GI_08, BW_320),
++      EHT_GROUP_RANGE(EHT_GI_16, BW_320),
++      EHT_GROUP_RANGE(EHT_GI_32, BW_320),
+ };
+ static u32
+@@ -422,6 +525,9 @@ static u32 ieee80211_get_rate_duration(s
+       case RATE_INFO_BW_160:
+               bw = BW_160;
+               break;
++      case RATE_INFO_BW_320:
++              bw = BW_320;
++              break;
+       default:
+               WARN_ON_ONCE(1);
+               return 0;
+@@ -443,14 +549,27 @@ static u32 ieee80211_get_rate_duration(s
+               idx = status->rate_idx;
+               group = HE_GROUP_IDX(streams, status->he_gi, bw);
+               break;
++      case RX_ENC_EHT:
++              streams = status->nss;
++              idx = status->rate_idx;
++              group = EHT_GROUP_IDX(streams, status->eht.gi, bw);
++              break;
+       default:
+               WARN_ON_ONCE(1);
+               return 0;
+       }
+-      if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
+-                       (status->encoding == RX_ENC_HE && streams > 8)))
+-              return 0;
++      switch (status->encoding) {
++      case RX_ENC_EHT:
++      case RX_ENC_HE:
++              if (WARN_ON_ONCE(streams > 8))
++                      return 0;
++              break;
++      default:
++              if (WARN_ON_ONCE(streams > 4))
++                      return 0;
++              break;
++      }
+       if (idx >= MCS_GROUP_RATES)
+               return 0;
+@@ -517,7 +636,9 @@ static bool ieee80211_fill_rate_info(str
+       stat->nss = ri->nss;
+       stat->rate_idx = ri->mcs;
+-      if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
++      if (ri->flags & RATE_INFO_FLAGS_EHT_MCS)
++              stat->encoding = RX_ENC_EHT;
++      else if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
+               stat->encoding = RX_ENC_HE;
+       else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
+               stat->encoding = RX_ENC_VHT;
+@@ -529,7 +650,14 @@ static bool ieee80211_fill_rate_info(str
+       if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
+               stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+-      stat->he_gi = ri->he_gi;
++      switch (stat->encoding) {
++      case RX_ENC_EHT:
++              stat->eht.gi = ri->eht_gi;
++              break;
++      default:
++              stat->he_gi = ri->he_gi;
++              break;
++      }
+       if (stat->encoding != RX_ENC_LEGACY)
+               return true;
diff --git a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch b/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch
deleted file mode 100644 (file)
index 0a3c8ec..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-From: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
-Date: Wed, 4 Sep 2024 19:12:56 +0800
-Subject: [PATCH] wifi: mac80211: introduce EHT rate support in AQL airtime
-
-Add definitions related to EHT mode and airtime calculation
-according to the 802.11BE_D4.0.
-
-Co-developed-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Bo Jiao <Bo.Jiao@mediatek.com>
-Signed-off-by: Deren Wu <deren.wu@mediatek.com>
-Signed-off-by: Quan Zhou <quan.zhou@mediatek.com>
-Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
-Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com
-Signed-off-by: Johannes Berg <johannes.berg@intel.com>
----
-
---- a/net/mac80211/airtime.c
-+++ b/net/mac80211/airtime.c
-@@ -55,10 +55,21 @@
- #define HE_DURATION_S(shift, streams, gi, bps)                \
-       (HE_DURATION(streams, gi, bps) >> shift)
-+/* gi in HE/EHT is identical. It matches enum nl80211_eht_gi as well */
-+#define EHT_GI_08 HE_GI_08
-+#define EHT_GI_16 HE_GI_16
-+#define EHT_GI_32 HE_GI_32
-+
-+#define EHT_DURATION(streams, gi, bps)                        \
-+      HE_DURATION(streams, gi, bps)
-+#define EHT_DURATION_S(shift, streams, gi, bps)               \
-+      HE_DURATION_S(shift, streams, gi, bps)
-+
- #define BW_20                 0
- #define BW_40                 1
- #define BW_80                 2
- #define BW_160                        3
-+#define BW_320                        4
- /*
-  * Define group sort order: HT40 -> SGI -> #streams
-@@ -68,17 +79,26 @@
- #define IEEE80211_VHT_STREAM_GROUPS   8 /* BW(=4) * SGI(=2) */
- #define IEEE80211_HE_MAX_STREAMS      8
-+#define IEEE80211_HE_STREAM_GROUPS    12 /* BW(=4) * GI(=3) */
-+
-+#define IEEE80211_EHT_MAX_STREAMS     8
-+#define IEEE80211_EHT_STREAM_GROUPS   15 /* BW(=5) * GI(=3) */
- #define IEEE80211_HT_GROUPS_NB        (IEEE80211_MAX_STREAMS *        \
-                                IEEE80211_HT_STREAM_GROUPS)
- #define IEEE80211_VHT_GROUPS_NB       (IEEE80211_MAX_STREAMS *        \
-                                        IEEE80211_VHT_STREAM_GROUPS)
-+#define IEEE80211_HE_GROUPS_NB        (IEEE80211_HE_MAX_STREAMS *     \
-+                               IEEE80211_HE_STREAM_GROUPS)
-+#define IEEE80211_EHT_GROUPS_NB       (IEEE80211_EHT_MAX_STREAMS *    \
-+                               IEEE80211_EHT_STREAM_GROUPS)
- #define IEEE80211_HT_GROUP_0  0
- #define IEEE80211_VHT_GROUP_0 (IEEE80211_HT_GROUP_0 + IEEE80211_HT_GROUPS_NB)
- #define IEEE80211_HE_GROUP_0  (IEEE80211_VHT_GROUP_0 + IEEE80211_VHT_GROUPS_NB)
-+#define IEEE80211_EHT_GROUP_0 (IEEE80211_HE_GROUP_0 + IEEE80211_HE_GROUPS_NB)
--#define MCS_GROUP_RATES               12
-+#define MCS_GROUP_RATES               14
- #define HT_GROUP_IDX(_streams, _sgi, _ht40)   \
-       IEEE80211_HT_GROUP_0 +                  \
-@@ -203,6 +223,69 @@
- #define HE_GROUP(_streams, _gi, _bw)                                  \
-       __HE_GROUP(_streams, _gi, _bw,                          \
-                  HE_GROUP_SHIFT(_streams, _gi, _bw))
-+
-+#define EHT_BW2VBPS(_bw, r5, r4, r3, r2, r1)                                  \
-+      ((_bw) == BW_320 ? r5 : BW2VBPS(_bw, r4, r3, r2, r1))
-+
-+#define EHT_GROUP_IDX(_streams, _gi, _bw)                             \
-+      (IEEE80211_EHT_GROUP_0 +                                        \
-+       IEEE80211_EHT_MAX_STREAMS * 3 * (_bw) +                        \
-+       IEEE80211_EHT_MAX_STREAMS * (_gi) +                            \
-+       (_streams) - 1)
-+
-+#define __EHT_GROUP(_streams, _gi, _bw, _s)                                           \
-+      [EHT_GROUP_IDX(_streams, _gi, _bw)] = {                                         \
-+      .shift = _s,                                                                    \
-+      .duration = {                                                                   \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw,  1960,   980,  490,  234,  117)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw,  3920,  1960,  980,  468,  234)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw,  5880,  2937, 1470,  702,  351)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw,  7840,  3920, 1960,  936,  468)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 11760,  5880, 2940, 1404,  702)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 15680,  7840, 3920, 1872,  936)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 17640,  8820, 4410, 2106, 1053)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 19600,  9800, 4900, 2340, 1170)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 23520, 11760, 5880, 2808, 1404)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 26133, 13066, 6533, 3120, 1560)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 29400, 14700, 7350, 3510, 1755)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 32666, 16333, 8166, 3900, 1950)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 35280, 17640, 8820, 4212, 2106)),       \
-+              EHT_DURATION_S(_s, _streams, _gi,                                       \
-+                             EHT_BW2VBPS(_bw, 39200, 19600, 9800, 4680, 2340))        \
-+              }                                                                       \
-+}
-+
-+#define EHT_GROUP_SHIFT(_streams, _gi, _bw)                                           \
-+      GROUP_SHIFT(EHT_DURATION(_streams, _gi,                                         \
-+                               EHT_BW2VBPS(_bw, 1960, 980, 490, 234, 117)))
-+
-+#define EHT_GROUP(_streams, _gi, _bw)                                 \
-+      __EHT_GROUP(_streams, _gi, _bw,                         \
-+                 EHT_GROUP_SHIFT(_streams, _gi, _bw))
-+
-+#define EHT_GROUP_RANGE(_gi, _bw)     \
-+      EHT_GROUP(1, _gi, _bw),         \
-+      EHT_GROUP(2, _gi, _bw),         \
-+      EHT_GROUP(3, _gi, _bw),         \
-+      EHT_GROUP(4, _gi, _bw),         \
-+      EHT_GROUP(5, _gi, _bw),         \
-+      EHT_GROUP(6, _gi, _bw),         \
-+      EHT_GROUP(7, _gi, _bw),         \
-+      EHT_GROUP(8, _gi, _bw)
-+
- struct mcs_group {
-       u8 shift;
-       u16 duration[MCS_GROUP_RATES];
-@@ -376,6 +459,26 @@ static const struct mcs_group airtime_mc
-       HE_GROUP(6, HE_GI_32, BW_160),
-       HE_GROUP(7, HE_GI_32, BW_160),
-       HE_GROUP(8, HE_GI_32, BW_160),
-+
-+      EHT_GROUP_RANGE(EHT_GI_08, BW_20),
-+      EHT_GROUP_RANGE(EHT_GI_16, BW_20),
-+      EHT_GROUP_RANGE(EHT_GI_32, BW_20),
-+
-+      EHT_GROUP_RANGE(EHT_GI_08, BW_40),
-+      EHT_GROUP_RANGE(EHT_GI_16, BW_40),
-+      EHT_GROUP_RANGE(EHT_GI_32, BW_40),
-+
-+      EHT_GROUP_RANGE(EHT_GI_08, BW_80),
-+      EHT_GROUP_RANGE(EHT_GI_16, BW_80),
-+      EHT_GROUP_RANGE(EHT_GI_32, BW_80),
-+
-+      EHT_GROUP_RANGE(EHT_GI_08, BW_160),
-+      EHT_GROUP_RANGE(EHT_GI_16, BW_160),
-+      EHT_GROUP_RANGE(EHT_GI_32, BW_160),
-+
-+      EHT_GROUP_RANGE(EHT_GI_08, BW_320),
-+      EHT_GROUP_RANGE(EHT_GI_16, BW_320),
-+      EHT_GROUP_RANGE(EHT_GI_32, BW_320),
- };
- static u32
-@@ -422,6 +525,9 @@ static u32 ieee80211_get_rate_duration(s
-       case RATE_INFO_BW_160:
-               bw = BW_160;
-               break;
-+      case RATE_INFO_BW_320:
-+              bw = BW_320;
-+              break;
-       default:
-               WARN_ON_ONCE(1);
-               return 0;
-@@ -443,14 +549,27 @@ static u32 ieee80211_get_rate_duration(s
-               idx = status->rate_idx;
-               group = HE_GROUP_IDX(streams, status->he_gi, bw);
-               break;
-+      case RX_ENC_EHT:
-+              streams = status->nss;
-+              idx = status->rate_idx;
-+              group = EHT_GROUP_IDX(streams, status->eht.gi, bw);
-+              break;
-       default:
-               WARN_ON_ONCE(1);
-               return 0;
-       }
--      if (WARN_ON_ONCE((status->encoding != RX_ENC_HE && streams > 4) ||
--                       (status->encoding == RX_ENC_HE && streams > 8)))
--              return 0;
-+      switch (status->encoding) {
-+      case RX_ENC_EHT:
-+      case RX_ENC_HE:
-+              if (WARN_ON_ONCE(streams > 8))
-+                      return 0;
-+              break;
-+      default:
-+              if (WARN_ON_ONCE(streams > 4))
-+                      return 0;
-+              break;
-+      }
-       if (idx >= MCS_GROUP_RATES)
-               return 0;
-@@ -517,7 +636,9 @@ static bool ieee80211_fill_rate_info(str
-       stat->nss = ri->nss;
-       stat->rate_idx = ri->mcs;
--      if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
-+      if (ri->flags & RATE_INFO_FLAGS_EHT_MCS)
-+              stat->encoding = RX_ENC_EHT;
-+      else if (ri->flags & RATE_INFO_FLAGS_HE_MCS)
-               stat->encoding = RX_ENC_HE;
-       else if (ri->flags & RATE_INFO_FLAGS_VHT_MCS)
-               stat->encoding = RX_ENC_VHT;
-@@ -529,7 +650,14 @@ static bool ieee80211_fill_rate_info(str
-       if (ri->flags & RATE_INFO_FLAGS_SHORT_GI)
-               stat->enc_flags |= RX_ENC_FLAG_SHORT_GI;
--      stat->he_gi = ri->he_gi;
-+      switch (stat->encoding) {
-+      case RX_ENC_EHT:
-+              stat->eht.gi = ri->eht_gi;
-+              break;
-+      default:
-+              stat->he_gi = ri->he_gi;
-+              break;
-+      }
-       if (stat->encoding != RX_ENC_LEGACY)
-               return true;
diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch
deleted file mode 100644 (file)
index 5537636..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Mon, 24 Feb 2020 00:00:00 +0100
-Subject: [PATCH] mac80211: Allow IBSS mode and different beacon intervals
-
-ath10k-ct supports the combination to select IBSS (ADHOC) mode and
-different beacon intervals together. mac80211 does not like this
-combination, but Ben says this is ok, so remove this check.
-
-ath10k-ct starting with version 5.2 allows the combination of
-NL80211_IFTYPE_ADHOC and beacon_int_min_gcd in ath10k_10x_ct_if_comb
-which triggers this warning. Ben told me that this is not a big problem
-and we should ignore this.
----
- net/wireless/core.c | 15 ---------------
- 1 file changed, 15 deletions(-)
-
---- a/net/wireless/core.c
-+++ b/net/wireless/core.c
-@@ -654,21 +654,6 @@ static int wiphy_verify_combinations(str
-                                   c->limits[j].max > 1))
-                               return -EINVAL;
--                      /*
--                       * This isn't well-defined right now. If you have an
--                       * IBSS interface, then its beacon interval may change
--                       * by joining other networks, and nothing prevents it
--                       * from doing that.
--                       * So technically we probably shouldn't even allow AP
--                       * and IBSS in the same interface, but it seems that
--                       * some drivers support that, possibly only with fixed
--                       * beacon intervals for IBSS.
--                       */
--                      if (WARN_ON(types & BIT(NL80211_IFTYPE_ADHOC) &&
--                                  c->beacon_int_min_gcd)) {
--                              return -EINVAL;
--                      }
--
-                       cnt += c->limits[j].max;
-                       /*
-                        * Don't advertise an unsupported type
diff --git a/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch b/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch
deleted file mode 100644 (file)
index ae400b7..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-From: David Bauer <mail@david-bauer.net>
-Date: Thu, 30 Nov 2023 07:32:52 +0100
-Subject: [PATCH] mac80211: avoid crashing on invalid band info
-
-Frequent crashes have been observed on MT7916 based platforms. While the
-root of these crashes are currently unknown, they happen when decoding
-rate information of connected STAs in AP mode. The rate-information is
-associated with a band which is not available on the PHY.
-
-Check for this condition in order to avoid crashing the whole system.
-This patch should be removed once the roout cause has been found and
-fixed.
-
-Link: https://github.com/freifunk-gluon/gluon/issues/2980
-
-Signed-off-by: David Bauer <mail@david-bauer.net>
----
-
---- a/net/mac80211/sta_info.c
-+++ b/net/mac80211/sta_info.c
-@@ -2455,6 +2455,13 @@ static void sta_stats_decode_rate(struct
-               sband = local->hw.wiphy->bands[band];
-+              if (!sband) {
-+                      wiphy_warn(local->hw.wiphy,
-+                                  "Invalid band %d\n",
-+                                  band);
-+                      break;
-+              }
-+
-               if (WARN_ON_ONCE(!sband->bitrates))
-                       break;