From: Felix Fietkau Date: Mon, 30 Sep 2024 08:06:31 +0000 (+0200) Subject: mac80211: reorder patches in subsys/ X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=2422dddf7a9a383214fcfa671f18c8cbb463163a;p=openwrt%2Fstaging%2Fxback.git mac80211: reorder patches in subsys/ Close some patch numbering gaps left behind by updates Signed-off-by: Felix Fietkau --- 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 index 0000000000..55376362a5 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/220-allow-ibss-mixed.patch @@ -0,0 +1,40 @@ +From: Hauke Mehrtens +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 index 0000000000..9e9e3844b7 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/230-avoid-crashing-missing-band.patch @@ -0,0 +1,34 @@ +From: David Bauer +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 +--- + +--- 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 index 0000000000..7e9be59e04 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/310-cfg80211-allow-grace-period-for-DFS-available-after-.patch @@ -0,0 +1,149 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 7e9be59e04..0000000000 --- a/package/kernel/mac80211/patches/subsys/320-cfg80211-allow-grace-period-for-DFS-available-after-.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 index 0000000000..3b6cba48e7 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/320-mac80211-add-AQL-support-for-broadcast-packets.patch @@ -0,0 +1,293 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 3b6cba48e7..0000000000 --- a/package/kernel/mac80211/patches/subsys/330-mac80211-add-AQL-support-for-broadcast-packets.patch +++ /dev/null @@ -1,293 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 index 0000000000..0a3c8ec53b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/330-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch @@ -0,0 +1,233 @@ +From: Ming Yen Hsieh +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 +Signed-off-by: Bo Jiao +Signed-off-by: Deren Wu +Signed-off-by: Quan Zhou +Signed-off-by: Ming Yen Hsieh +Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com +Signed-off-by: Johannes Berg +--- + +--- 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 index 0a3c8ec53b..0000000000 --- a/package/kernel/mac80211/patches/subsys/350-wifi-mac80211-introduce-EHT-rate-support-in-AQL-airt.patch +++ /dev/null @@ -1,233 +0,0 @@ -From: Ming Yen Hsieh -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 -Signed-off-by: Bo Jiao -Signed-off-by: Deren Wu -Signed-off-by: Quan Zhou -Signed-off-by: Ming Yen Hsieh -Link: https://patch.msgid.link/20240904111256.11734-1-mingyen.hsieh@mediatek.com -Signed-off-by: Johannes Berg ---- - ---- 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 index 55376362a5..0000000000 --- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Hauke Mehrtens -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 index ae400b78a1..0000000000 --- a/package/kernel/mac80211/patches/subsys/780-avoid-crashing-missing-band.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: David Bauer -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 ---- - ---- 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; -