diff options
author | Felix Fietkau <nbd@nbd.name> | 2023-08-30 12:31:44 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2023-09-11 14:29:36 +0200 |
commit | f861292abcb77655a9792ead47d397d31f1c356e (patch) | |
tree | afe289bd9fbc0d62f176a99f05da31f1426ac943 /package/kernel/mac80211/patches/subsys | |
parent | 69f12c2f23c6d32a5fdda2385b4156c9b8bfae22 (diff) | |
download | openwrt-f861292abcb77655a9792ead47d397d31f1c356e.tar.gz openwrt-f861292abcb77655a9792ead47d397d31f1c356e.tar.bz2 openwrt-f861292abcb77655a9792ead47d397d31f1c356e.zip |
mac80211: update to version 6.5
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'package/kernel/mac80211/patches/subsys')
37 files changed, 15 insertions, 5369 deletions
diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch index 4d4a2a8f5e..e3349dabd0 100644 --- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch @@ -9,7 +9,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1519,7 +1519,6 @@ static int ieee80211_stop_ap(struct wiph +@@ -1632,7 +1632,6 @@ static int ieee80211_stop_ap(struct wiph link_conf->bssid_indicator = 0; __sta_info_flush(sdata, true); diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index 10b842d9af..25b844a21b 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -8,7 +8,7 @@ Subject: [PATCH] mac80211: allow scans in access point mode (for site survey) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2727,6 +2727,8 @@ static int ieee80211_scan(struct wiphy * +@@ -2843,6 +2843,8 @@ static int ieee80211_scan(struct wiphy * */ fallthrough; case NL80211_IFTYPE_AP: diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch index 63b2177471..ffa5c17e48 100644 --- a/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch +++ b/package/kernel/mac80211/patches/subsys/301-mac80211-sta-randomize-BA-session-dialog-token-alloc.patch @@ -28,7 +28,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com> --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -554,6 +554,7 @@ __sta_info_alloc(struct ieee80211_sub_if +@@ -558,6 +558,7 @@ __sta_info_alloc(struct ieee80211_sub_if INIT_WORK(&sta->drv_deliver_wk, sta_deliver_ps_frames); INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); mutex_init(&sta->ampdu_mlme.mtx); diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch index 0ac972955f..a27925e64e 100644 --- a/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch +++ b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch @@ -12,7 +12,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask +@@ -92,6 +92,8 @@ extern const u8 ieee80211_ac_to_qos_mask */ #define AIRTIME_ACTIVE_DURATION (HZ / 10) @@ -23,7 +23,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -3984,7 +3984,7 @@ struct ieee80211_txq *ieee80211_next_txq +@@ -4059,7 +4059,7 @@ struct ieee80211_txq *ieee80211_next_txq if (deficit < 0) sta->airtime[txqi->txq.ac].deficit += @@ -32,7 +32,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> if (deficit < 0 || !aql_check) { list_move_tail(&txqi->schedule_order, -@@ -4127,7 +4127,8 @@ bool ieee80211_txq_may_transmit(struct i +@@ -4202,7 +4202,8 @@ bool ieee80211_txq_may_transmit(struct i } sta = container_of(iter->txq.sta, struct sta_info, sta); if (ieee80211_sta_deficit(sta, ac) < 0) @@ -42,7 +42,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); } -@@ -4135,7 +4136,7 @@ bool ieee80211_txq_may_transmit(struct i +@@ -4210,7 +4211,7 @@ bool ieee80211_txq_may_transmit(struct i if (sta->airtime[ac].deficit >= 0) goto out; diff --git a/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch deleted file mode 100644 index d14ba05e69..0000000000 --- a/package/kernel/mac80211/patches/subsys/306-01-v6.2-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch +++ /dev/null @@ -1,183 +0,0 @@ -From: Alexander Wetzel <alexander@wetzel-home.de> -Date: Sun, 9 Oct 2022 18:30:38 +0200 -Subject: [PATCH] wifi: mac80211: add internal handler for wake_tx_queue - -Start to align the TX handling to only use internal TX queues (iTXQs): - -Provide a handler for drivers not having a custom wake_tx_queue -callback and update the documentation. - -Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -89,15 +89,13 @@ - /** - * DOC: mac80211 software tx queueing - * -- * mac80211 provides an optional intermediate queueing implementation designed -- * to allow the driver to keep hardware queues short and provide some fairness -- * between different stations/interfaces. -- * In this model, the driver pulls data frames from the mac80211 queue instead -- * of letting mac80211 push them via drv_tx(). -- * Other frames (e.g. control or management) are still pushed using drv_tx(). -+ * mac80211 uses an intermediate queueing implementation, designed to allow the -+ * driver to keep hardware queues short and to provide some fairness between -+ * different stations/interfaces. - * -- * Drivers indicate that they use this model by implementing the .wake_tx_queue -- * driver operation. -+ * Drivers must provide the .wake_tx_queue driver operation by either -+ * linking it to ieee80211_handle_wake_tx_queue() or implementing a custom -+ * handler. - * - * Intermediate queues (struct ieee80211_txq) are kept per-sta per-tid, with - * another per-sta for non-data/non-mgmt and bufferable management frames, and -@@ -106,9 +104,12 @@ - * The driver is expected to initialize its private per-queue data for stations - * and interfaces in the .add_interface and .sta_add ops. - * -- * The driver can't access the queue directly. To dequeue a frame from a -- * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a -- * queue, it calls the .wake_tx_queue driver op. -+ * The driver can't access the internal TX queues (iTXQs) directly. -+ * Whenever mac80211 adds a new frame to a queue, it calls the .wake_tx_queue -+ * driver op. -+ * Drivers implementing a custom .wake_tx_queue op can get them by calling -+ * ieee80211_tx_dequeue(). Drivers using ieee80211_handle_wake_tx_queue() will -+ * simply get the individual frames pushed via the .tx driver operation. - * - * Drivers can optionally delegate responsibility for scheduling queues to - * mac80211, to take advantage of airtime fairness accounting. In this case, to -@@ -2248,8 +2249,8 @@ struct ieee80211_link_sta { - * For non MLO STA it will point to the deflink data. For MLO STA - * ieee80211_sta_recalc_aggregates() must be called to update it. - * @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not. -- * @txq: per-TID data TX queues (if driver uses the TXQ abstraction); note that -- * the last entry (%IEEE80211_NUM_TIDS) is used for non-data frames -+ * @txq: per-TID data TX queues; note that the last entry (%IEEE80211_NUM_TIDS) -+ * is used for non-data frames - * @deflink: This holds the default link STA information, for non MLO STA all link - * specific STA information is accessed through @deflink or through - * link[0] which points to address of @deflink. For MLO Link STA -@@ -5687,7 +5688,7 @@ void ieee80211_key_replay(struct ieee802 - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @queue: queue number (counted from zero). - * -- * Drivers should use this function instead of netif_wake_queue. -+ * Drivers must use this function instead of netif_wake_queue. - */ - void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue); - -@@ -5696,7 +5697,7 @@ void ieee80211_wake_queue(struct ieee802 - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @queue: queue number (counted from zero). - * -- * Drivers should use this function instead of netif_stop_queue. -+ * Drivers must use this function instead of netif_stop_queue. - */ - void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue); - -@@ -5705,7 +5706,7 @@ void ieee80211_stop_queue(struct ieee802 - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * @queue: queue number (counted from zero). - * -- * Drivers should use this function instead of netif_stop_queue. -+ * Drivers must use this function instead of netif_queue_stopped. - * - * Return: %true if the queue is stopped. %false otherwise. - */ -@@ -5716,7 +5717,7 @@ int ieee80211_queue_stopped(struct ieee8 - * ieee80211_stop_queues - stop all queues - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * -- * Drivers should use this function instead of netif_stop_queue. -+ * Drivers must use this function instead of netif_tx_stop_all_queues. - */ - void ieee80211_stop_queues(struct ieee80211_hw *hw); - -@@ -5724,7 +5725,7 @@ void ieee80211_stop_queues(struct ieee80 - * ieee80211_wake_queues - wake all queues - * @hw: pointer as obtained from ieee80211_alloc_hw(). - * -- * Drivers should use this function instead of netif_wake_queue. -+ * Drivers must use this function instead of netif_tx_wake_all_queues. - */ - void ieee80211_wake_queues(struct ieee80211_hw *hw); - -@@ -6946,6 +6947,18 @@ static inline struct sk_buff *ieee80211_ - } - - /** -+ * ieee80211_handle_wake_tx_queue - mac80211 handler for wake_tx_queue callback -+ * -+ * @hw: pointer as obtained from wake_tx_queue() callback(). -+ * @txq: pointer as obtained from wake_tx_queue() callback(). -+ * -+ * Drivers can use this function for the mandatory mac80211 wake_tx_queue -+ * callback in struct ieee80211_ops. They should not call this function. -+ */ -+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq); -+ -+/** - * ieee80211_next_txq - get next tx queue to pull packets from - * - * @hw: pointer as obtained from ieee80211_alloc_hw() ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -288,6 +288,52 @@ __le16 ieee80211_ctstoself_duration(stru - } - EXPORT_SYMBOL(ieee80211_ctstoself_duration); - -+static void wake_tx_push_queue(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_txq *queue) -+{ -+ int q = sdata->vif.hw_queue[queue->ac]; -+ struct ieee80211_tx_control control = { -+ .sta = queue->sta, -+ }; -+ struct sk_buff *skb; -+ unsigned long flags; -+ bool q_stopped; -+ -+ while (1) { -+ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -+ q_stopped = local->queue_stop_reasons[q]; -+ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -+ -+ if (q_stopped) -+ break; -+ -+ skb = ieee80211_tx_dequeue(&local->hw, queue); -+ if (!skb) -+ break; -+ -+ drv_tx(local, &control, skb); -+ } -+} -+ -+/* wake_tx_queue handler for driver not implementing a custom one*/ -+void ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq) -+{ -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); -+ struct ieee80211_txq *queue; -+ -+ /* Use ieee80211_next_txq() for airtime fairness accounting */ -+ ieee80211_txq_schedule_start(hw, txq->ac); -+ while ((queue = ieee80211_next_txq(hw, txq->ac))) { -+ wake_tx_push_queue(local, sdata, queue); -+ ieee80211_return_txq(hw, queue, false); -+ } -+ ieee80211_txq_schedule_end(hw, txq->ac); -+} -+EXPORT_SYMBOL(ieee80211_handle_wake_tx_queue); -+ - static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) - { - struct ieee80211_local *local = sdata->local; diff --git a/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch deleted file mode 100644 index fee038d90c..0000000000 --- a/package/kernel/mac80211/patches/subsys/306-02-v6.2-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch +++ /dev/null @@ -1,396 +0,0 @@ -From: Alexander Wetzel <alexander@wetzel-home.de> -Date: Sun, 9 Oct 2022 18:30:39 +0200 -Subject: [PATCH] wifi: mac80211: add wake_tx_queue callback to drivers - -mac80211 is fully switching over to the internal TX queue (iTXQ) -implementation. Update all drivers not yet providing the now mandatory -wake_tx_queue() callback. - -As an side effect the netdev interfaces of all updated drivers will -switch to the noqueue qdisc. - -Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> -[add staging drivers] -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/drivers/net/wireless/admtek/adm8211.c -+++ b/drivers/net/wireless/admtek/adm8211.c -@@ -1760,6 +1760,7 @@ static int adm8211_alloc_rings(struct ie - - static const struct ieee80211_ops adm8211_ops = { - .tx = adm8211_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = adm8211_start, - .stop = adm8211_stop, - .add_interface = adm8211_add_interface, ---- a/drivers/net/wireless/ath/ar5523/ar5523.c -+++ b/drivers/net/wireless/ath/ar5523/ar5523.c -@@ -1361,6 +1361,7 @@ static const struct ieee80211_ops ar5523 - .start = ar5523_start, - .stop = ar5523_stop, - .tx = ar5523_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .set_rts_threshold = ar5523_set_rts_threshold, - .add_interface = ar5523_add_interface, - .remove_interface = ar5523_remove_interface, ---- a/drivers/net/wireless/ath/ath11k/mac.c -+++ b/drivers/net/wireless/ath/ath11k/mac.c -@@ -8587,6 +8587,7 @@ err_fallback: - - static const struct ieee80211_ops ath11k_ops = { - .tx = ath11k_mac_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = ath11k_mac_op_start, - .stop = ath11k_mac_op_stop, - .reconfig_complete = ath11k_mac_op_reconfig_complete, ---- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c -+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c -@@ -781,6 +781,7 @@ static int ath5k_set_ringparam(struct ie - - const struct ieee80211_ops ath5k_hw_ops = { - .tx = ath5k_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = ath5k_start, - .stop = ath5k_stop, - .add_interface = ath5k_add_interface, ---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c -@@ -1870,6 +1870,7 @@ static void ath9k_htc_channel_switch_bea - - struct ieee80211_ops ath9k_htc_ops = { - .tx = ath9k_htc_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = ath9k_htc_start, - .stop = ath9k_htc_stop, - .add_interface = ath9k_htc_add_interface, ---- a/drivers/net/wireless/ath/carl9170/main.c -+++ b/drivers/net/wireless/ath/carl9170/main.c -@@ -1715,6 +1715,7 @@ static const struct ieee80211_ops carl91 - .start = carl9170_op_start, - .stop = carl9170_op_stop, - .tx = carl9170_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .flush = carl9170_op_flush, - .add_interface = carl9170_op_add_interface, - .remove_interface = carl9170_op_remove_interface, ---- a/drivers/net/wireless/ath/wcn36xx/main.c -+++ b/drivers/net/wireless/ath/wcn36xx/main.c -@@ -1362,6 +1362,7 @@ static const struct ieee80211_ops wcn36x - .prepare_multicast = wcn36xx_prepare_multicast, - .configure_filter = wcn36xx_configure_filter, - .tx = wcn36xx_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .set_key = wcn36xx_set_key, - .hw_scan = wcn36xx_hw_scan, - .cancel_hw_scan = wcn36xx_cancel_hw_scan, ---- a/drivers/net/wireless/atmel/at76c50x-usb.c -+++ b/drivers/net/wireless/atmel/at76c50x-usb.c -@@ -2187,6 +2187,7 @@ static int at76_set_key(struct ieee80211 - - static const struct ieee80211_ops at76_ops = { - .tx = at76_mac80211_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .add_interface = at76_add_interface, - .remove_interface = at76_remove_interface, - .config = at76_config, ---- a/drivers/net/wireless/broadcom/b43/main.c -+++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -5171,6 +5171,7 @@ static int b43_op_get_survey(struct ieee - - static const struct ieee80211_ops b43_hw_ops = { - .tx = b43_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .conf_tx = b43_op_conf_tx, - .add_interface = b43_op_add_interface, - .remove_interface = b43_op_remove_interface, ---- a/drivers/net/wireless/broadcom/b43legacy/main.c -+++ b/drivers/net/wireless/broadcom/b43legacy/main.c -@@ -3532,6 +3532,7 @@ static int b43legacy_op_get_survey(struc - - static const struct ieee80211_ops b43legacy_hw_ops = { - .tx = b43legacy_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .conf_tx = b43legacy_op_conf_tx, - .add_interface = b43legacy_op_add_interface, - .remove_interface = b43legacy_op_remove_interface, ---- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c -@@ -962,6 +962,7 @@ static int brcms_ops_beacon_set_tim(stru - - static const struct ieee80211_ops brcms_ops = { - .tx = brcms_ops_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = brcms_ops_start, - .stop = brcms_ops_stop, - .add_interface = brcms_ops_add_interface, ---- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c -+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c -@@ -3439,6 +3439,7 @@ static const struct attribute_group il39 - - static struct ieee80211_ops il3945_mac_ops __ro_after_init = { - .tx = il3945_mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = il3945_mac_start, - .stop = il3945_mac_stop, - .add_interface = il_mac_add_interface, ---- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c -+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c -@@ -6308,6 +6308,7 @@ il4965_tx_queue_set_status(struct il_pri - - static const struct ieee80211_ops il4965_mac_ops = { - .tx = il4965_mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = il4965_mac_start, - .stop = il4965_mac_stop, - .add_interface = il_mac_add_interface, ---- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c -+++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c -@@ -1571,6 +1571,7 @@ static void iwlagn_mac_sta_notify(struct - - const struct ieee80211_ops iwlagn_hw_ops = { - .tx = iwlagn_mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = iwlagn_mac_start, - .stop = iwlagn_mac_stop, - #ifdef CONFIG_PM_SLEEP ---- a/drivers/net/wireless/intersil/p54/main.c -+++ b/drivers/net/wireless/intersil/p54/main.c -@@ -705,6 +705,7 @@ static void p54_set_coverage_class(struc - - static const struct ieee80211_ops p54_ops = { - .tx = p54_tx_80211, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = p54_start, - .stop = p54_stop, - .add_interface = p54_add_interface, ---- a/drivers/net/wireless/mac80211_hwsim.c -+++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -3109,6 +3109,7 @@ static int mac80211_hwsim_change_sta_lin - - #define HWSIM_COMMON_OPS \ - .tx = mac80211_hwsim_tx, \ -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, \ - .start = mac80211_hwsim_start, \ - .stop = mac80211_hwsim_stop, \ - .add_interface = mac80211_hwsim_add_interface, \ ---- a/drivers/net/wireless/marvell/libertas_tf/main.c -+++ b/drivers/net/wireless/marvell/libertas_tf/main.c -@@ -474,6 +474,7 @@ static int lbtf_op_get_survey(struct iee - - static const struct ieee80211_ops lbtf_ops = { - .tx = lbtf_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = lbtf_op_start, - .stop = lbtf_op_stop, - .add_interface = lbtf_op_add_interface, ---- a/drivers/net/wireless/marvell/mwl8k.c -+++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5611,6 +5611,7 @@ static void mwl8k_sw_scan_complete(struc - - static const struct ieee80211_ops mwl8k_ops = { - .tx = mwl8k_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = mwl8k_start, - .stop = mwl8k_stop, - .add_interface = mwl8k_add_interface, ---- a/drivers/net/wireless/mediatek/mt7601u/main.c -+++ b/drivers/net/wireless/mediatek/mt7601u/main.c -@@ -406,6 +406,7 @@ out: - - const struct ieee80211_ops mt7601u_ops = { - .tx = mt7601u_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = mt7601u_start, - .stop = mt7601u_stop, - .add_interface = mt7601u_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c -@@ -1706,6 +1706,7 @@ static int rt2400pci_tx_last_beacon(stru - - static const struct ieee80211_ops rt2400pci_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c -@@ -2004,6 +2004,7 @@ static int rt2500pci_tx_last_beacon(stru - - static const struct ieee80211_ops rt2500pci_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c -@@ -1795,6 +1795,7 @@ static int rt2500usb_probe_hw(struct rt2 - - static const struct ieee80211_ops rt2500usb_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c -@@ -288,6 +288,7 @@ static int rt2800pci_read_eeprom(struct - - static const struct ieee80211_ops rt2800pci_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -133,6 +133,7 @@ static int rt2800soc_write_firmware(stru - - static const struct ieee80211_ops rt2800soc_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c -@@ -630,6 +630,7 @@ static int rt2800usb_probe_hw(struct rt2 - - static const struct ieee80211_ops rt2800usb_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c -@@ -2873,6 +2873,7 @@ static u64 rt61pci_get_tsf(struct ieee80 - - static const struct ieee80211_ops rt61pci_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c -@@ -2292,6 +2292,7 @@ static u64 rt73usb_get_tsf(struct ieee80 - - static const struct ieee80211_ops rt73usb_mac80211_ops = { - .tx = rt2x00mac_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rt2x00mac_start, - .stop = rt2x00mac_stop, - .add_interface = rt2x00mac_add_interface, ---- a/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c -+++ b/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c -@@ -1608,6 +1608,7 @@ static void rtl8180_configure_filter(str - - static const struct ieee80211_ops rtl8180_ops = { - .tx = rtl8180_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rtl8180_start, - .stop = rtl8180_stop, - .add_interface = rtl8180_add_interface, ---- a/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c -+++ b/drivers/net/wireless/realtek/rtl818x/rtl8187/dev.c -@@ -1378,6 +1378,7 @@ static int rtl8187_conf_tx(struct ieee80 - - static const struct ieee80211_ops rtl8187_ops = { - .tx = rtl8187_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rtl8187_start, - .stop = rtl8187_stop, - .add_interface = rtl8187_add_interface, ---- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c -@@ -6548,6 +6548,7 @@ static void rtl8xxxu_stop(struct ieee802 - - static const struct ieee80211_ops rtl8xxxu_ops = { - .tx = rtl8xxxu_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .add_interface = rtl8xxxu_add_interface, - .remove_interface = rtl8xxxu_remove_interface, - .config = rtl8xxxu_config, ---- a/drivers/net/wireless/realtek/rtlwifi/core.c -+++ b/drivers/net/wireless/realtek/rtlwifi/core.c -@@ -1912,6 +1912,7 @@ const struct ieee80211_ops rtl_ops = { - .start = rtl_op_start, - .stop = rtl_op_stop, - .tx = rtl_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .add_interface = rtl_op_add_interface, - .remove_interface = rtl_op_remove_interface, - .change_interface = rtl_op_change_interface, ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -896,6 +896,7 @@ static void rtw_ops_sta_rc_update(struct - - const struct ieee80211_ops rtw_ops = { - .tx = rtw_ops_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw_ops_wake_tx_queue, - .start = rtw_ops_start, - .stop = rtw_ops_stop, ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -918,6 +918,7 @@ static int rtw89_ops_set_tid_config(stru - - const struct ieee80211_ops rtw89_ops = { - .tx = rtw89_ops_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw89_ops_wake_tx_queue, - .start = rtw89_ops_start, - .stop = rtw89_ops_stop, ---- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c -+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c -@@ -1958,6 +1958,7 @@ static int rsi_mac80211_resume(struct ie - - static const struct ieee80211_ops mac80211_ops = { - .tx = rsi_mac80211_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = rsi_mac80211_start, - .stop = rsi_mac80211_stop, - .add_interface = rsi_mac80211_add_interface, ---- a/drivers/net/wireless/st/cw1200/main.c -+++ b/drivers/net/wireless/st/cw1200/main.c -@@ -209,6 +209,7 @@ static const struct ieee80211_ops cw1200 - .remove_interface = cw1200_remove_interface, - .change_interface = cw1200_change_interface, - .tx = cw1200_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .hw_scan = cw1200_hw_scan, - .set_tim = cw1200_set_tim, - .sta_notify = cw1200_sta_notify, ---- a/drivers/net/wireless/ti/wl1251/main.c -+++ b/drivers/net/wireless/ti/wl1251/main.c -@@ -1359,6 +1359,7 @@ static const struct ieee80211_ops wl1251 - .prepare_multicast = wl1251_op_prepare_multicast, - .configure_filter = wl1251_op_configure_filter, - .tx = wl1251_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .set_key = wl1251_op_set_key, - .hw_scan = wl1251_op_hw_scan, - .bss_info_changed = wl1251_op_bss_info_changed, ---- a/drivers/net/wireless/ti/wlcore/main.c -+++ b/drivers/net/wireless/ti/wlcore/main.c -@@ -5942,6 +5942,7 @@ static const struct ieee80211_ops wl1271 - .prepare_multicast = wl1271_op_prepare_multicast, - .configure_filter = wl1271_op_configure_filter, - .tx = wl1271_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .set_key = wlcore_op_set_key, - .hw_scan = wl1271_op_hw_scan, - .cancel_hw_scan = wl1271_op_cancel_hw_scan, ---- a/drivers/net/wireless/zydas/zd1211rw/zd_mac.c -+++ b/drivers/net/wireless/zydas/zd1211rw/zd_mac.c -@@ -1344,6 +1344,7 @@ static u64 zd_op_get_tsf(struct ieee8021 - - static const struct ieee80211_ops zd_ops = { - .tx = zd_op_tx, -+ .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .start = zd_op_start, - .stop = zd_op_stop, - .add_interface = zd_op_add_interface, diff --git a/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch b/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch deleted file mode 100644 index f9f9977cee..0000000000 --- a/package/kernel/mac80211/patches/subsys/306-03-v6.2-wifi-mac80211-Drop-support-for-TX-push-path.patch +++ /dev/null @@ -1,683 +0,0 @@ -From: Alexander Wetzel <alexander@wetzel-home.de> -Date: Sun, 9 Oct 2022 18:30:40 +0200 -Subject: [PATCH] wifi: mac80211: Drop support for TX push path - -All drivers are now using mac80211 internal queues (iTXQs). -Drop mac80211 internal support for the old push path. - -Signed-off-by: Alexander Wetzel <alexander@wetzel-home.de> -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -4346,9 +4346,6 @@ static int ieee80211_get_txq_stats(struc - struct ieee80211_sub_if_data *sdata; - int ret = 0; - -- if (!local->ops->wake_tx_queue) -- return 1; -- - spin_lock_bh(&local->fq.lock); - rcu_read_lock(); - ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -663,9 +663,7 @@ void debugfs_hw_add(struct ieee80211_loc - DEBUGFS_ADD_MODE(force_tx_status, 0600); - DEBUGFS_ADD_MODE(aql_enable, 0600); - DEBUGFS_ADD(aql_pending); -- -- if (local->ops->wake_tx_queue) -- DEBUGFS_ADD_MODE(aqm, 0600); -+ DEBUGFS_ADD_MODE(aqm, 0600); - - DEBUGFS_ADD_MODE(airtime_flags, 0600); - ---- a/net/mac80211/debugfs_netdev.c -+++ b/net/mac80211/debugfs_netdev.c -@@ -677,8 +677,7 @@ static void add_common_files(struct ieee - DEBUGFS_ADD(rc_rateidx_vht_mcs_mask_5ghz); - DEBUGFS_ADD(hw_queues); - -- if (sdata->local->ops->wake_tx_queue && -- sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -+ if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && - sdata->vif.type != NL80211_IFTYPE_NAN) - DEBUGFS_ADD(aqm); - } ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -1057,10 +1057,8 @@ void ieee80211_sta_debugfs_add(struct st - DEBUGFS_ADD_COUNTER(rx_fragments, deflink.rx_stats.fragments); - DEBUGFS_ADD_COUNTER(tx_filtered, deflink.status_stats.filtered); - -- if (local->ops->wake_tx_queue) { -- DEBUGFS_ADD(aqm); -- DEBUGFS_ADD(airtime); -- } -+ DEBUGFS_ADD(aqm); -+ DEBUGFS_ADD(airtime); - - if (wiphy_ext_feature_isset(local->hw.wiphy, - NL80211_EXT_FEATURE_AQL)) ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -2294,7 +2294,6 @@ void ieee80211_wake_queue_by_reason(stru - void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, - enum queue_stop_reason reason, - bool refcounted); --void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); - void ieee80211_add_pending_skb(struct ieee80211_local *local, - struct sk_buff *skb); - void ieee80211_add_pending_skbs(struct ieee80211_local *local, ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -460,12 +460,6 @@ static void ieee80211_do_stop(struct iee - if (cancel_scan) - ieee80211_scan_cancel(local); - -- /* -- * Stop TX on this interface first. -- */ -- if (!local->ops->wake_tx_queue && sdata->dev) -- netif_tx_stop_all_queues(sdata->dev); -- - ieee80211_roc_purge(local, sdata); - - switch (sdata->vif.type) { -@@ -813,13 +807,6 @@ static void ieee80211_uninit(struct net_ - ieee80211_teardown_sdata(IEEE80211_DEV_TO_SUB_IF(dev)); - } - --static u16 ieee80211_netdev_select_queue(struct net_device *dev, -- struct sk_buff *skb, -- struct net_device *sb_dev) --{ -- return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); --} -- - static void - ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { -@@ -833,7 +820,6 @@ static const struct net_device_ops ieee8 - .ndo_start_xmit = ieee80211_subif_start_xmit, - .ndo_set_rx_mode = ieee80211_set_multicast_list, - .ndo_set_mac_address = ieee80211_change_mac, -- .ndo_select_queue = ieee80211_netdev_select_queue, - .ndo_get_stats64 = ieee80211_get_stats64, - }; - -@@ -941,7 +927,6 @@ static const struct net_device_ops ieee8 - .ndo_start_xmit = ieee80211_subif_start_xmit_8023, - .ndo_set_rx_mode = ieee80211_set_multicast_list, - .ndo_set_mac_address = ieee80211_change_mac, -- .ndo_select_queue = ieee80211_netdev_select_queue, - .ndo_get_stats64 = ieee80211_get_stats64, - .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, - }; -@@ -1443,35 +1428,6 @@ int ieee80211_do_open(struct wireless_de - - ieee80211_recalc_ps(local); - -- if (sdata->vif.type == NL80211_IFTYPE_MONITOR || -- sdata->vif.type == NL80211_IFTYPE_AP_VLAN || -- local->ops->wake_tx_queue) { -- /* XXX: for AP_VLAN, actually track AP queues */ -- if (dev) -- netif_tx_start_all_queues(dev); -- } else if (dev) { -- unsigned long flags; -- int n_acs = IEEE80211_NUM_ACS; -- int ac; -- -- if (local->hw.queues < IEEE80211_NUM_ACS) -- n_acs = 1; -- -- spin_lock_irqsave(&local->queue_stop_reason_lock, flags); -- if (sdata->vif.cab_queue == IEEE80211_INVAL_HW_QUEUE || -- (local->queue_stop_reasons[sdata->vif.cab_queue] == 0 && -- skb_queue_empty(&local->pending[sdata->vif.cab_queue]))) { -- for (ac = 0; ac < n_acs; ac++) { -- int ac_queue = sdata->vif.hw_queue[ac]; -- -- if (local->queue_stop_reasons[ac_queue] == 0 && -- skb_queue_empty(&local->pending[ac_queue])) -- netif_start_subqueue(dev, ac); -- } -- } -- spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); -- } -- - set_bit(SDATA_STATE_RUNNING, &sdata->state); - - return 0; -@@ -1501,17 +1457,12 @@ static void ieee80211_if_setup(struct ne - { - ether_setup(dev); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; -+ dev->priv_flags |= IFF_NO_QUEUE; - dev->netdev_ops = &ieee80211_dataif_ops; - dev->needs_free_netdev = true; - dev->priv_destructor = ieee80211_if_free; - } - --static void ieee80211_if_setup_no_queue(struct net_device *dev) --{ -- ieee80211_if_setup(dev); -- dev->priv_flags |= IFF_NO_QUEUE; --} -- - static void ieee80211_iface_process_skb(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb) -@@ -2096,9 +2047,7 @@ int ieee80211_if_add(struct ieee80211_lo - struct net_device *ndev = NULL; - struct ieee80211_sub_if_data *sdata = NULL; - struct txq_info *txqi; -- void (*if_setup)(struct net_device *dev); - int ret, i; -- int txqs = 1; - - ASSERT_RTNL(); - -@@ -2121,30 +2070,18 @@ int ieee80211_if_add(struct ieee80211_lo - sizeof(void *)); - int txq_size = 0; - -- if (local->ops->wake_tx_queue && -- type != NL80211_IFTYPE_AP_VLAN && -+ if (type != NL80211_IFTYPE_AP_VLAN && - (type != NL80211_IFTYPE_MONITOR || - (params->flags & MONITOR_FLAG_ACTIVE))) - txq_size += sizeof(struct txq_info) + - local->hw.txq_data_size; - -- if (local->ops->wake_tx_queue) { -- if_setup = ieee80211_if_setup_no_queue; -- } else { -- if_setup = ieee80211_if_setup; -- if (local->hw.queues >= IEEE80211_NUM_ACS) -- txqs = IEEE80211_NUM_ACS; -- } -- - ndev = alloc_netdev_mqs(size + txq_size, - name, name_assign_type, -- if_setup, txqs, 1); -+ ieee80211_if_setup, 1, 1); - if (!ndev) - return -ENOMEM; - -- if (!local->ops->wake_tx_queue && local->hw.wiphy->tx_queue_len) -- ndev->tx_queue_len = local->hw.wiphy->tx_queue_len; -- - dev_net_set(ndev, wiphy_net(local->hw.wiphy)); - - ndev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -630,7 +630,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - - if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config || - !ops->add_interface || !ops->remove_interface || -- !ops->configure_filter)) -+ !ops->configure_filter || !ops->wake_tx_queue)) - return NULL; - - if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove))) -@@ -719,9 +719,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - if (!ops->set_key) - wiphy->flags |= WIPHY_FLAG_IBSS_RSN; - -- if (ops->wake_tx_queue) -- wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); -- -+ wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_TXQS); - wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_RRM); - - wiphy->bss_priv_size = sizeof(struct ieee80211_bss); -@@ -834,10 +832,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - atomic_set(&local->agg_queue_stop[i], 0); - } - tasklet_setup(&local->tx_pending_tasklet, ieee80211_tx_pending); -- -- if (ops->wake_tx_queue) -- tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); -- -+ tasklet_setup(&local->wake_txqs_tasklet, ieee80211_wake_txqs); - tasklet_setup(&local->tasklet, ieee80211_tasklet_handler); - - skb_queue_head_init(&local->skb_queue); ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -1571,9 +1571,6 @@ static void sta_ps_start(struct sta_info - - ieee80211_clear_fast_xmit(sta); - -- if (!sta->sta.txq[0]) -- return; -- - for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { - struct ieee80211_txq *txq = sta->sta.txq[tid]; - struct txq_info *txqi = to_txq_info(txq); ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -140,17 +140,15 @@ static void __cleanup_single_sta(struct - atomic_dec(&ps->num_sta_ps); - } - -- if (sta->sta.txq[0]) { -- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { -- struct txq_info *txqi; -+ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { -+ struct txq_info *txqi; - -- if (!sta->sta.txq[i]) -- continue; -+ if (!sta->sta.txq[i]) -+ continue; - -- txqi = to_txq_info(sta->sta.txq[i]); -+ txqi = to_txq_info(sta->sta.txq[i]); - -- ieee80211_txq_purge(local, txqi); -- } -+ ieee80211_txq_purge(local, txqi); - } - - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -@@ -425,8 +423,7 @@ void sta_info_free(struct ieee80211_loca - - sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); - -- if (sta->sta.txq[0]) -- kfree(to_txq_info(sta->sta.txq[0])); -+ kfree(to_txq_info(sta->sta.txq[0])); - kfree(rcu_dereference_raw(sta->sta.rates)); - #ifdef CPTCFG_MAC80211_MESH - kfree(sta->mesh); -@@ -527,6 +524,8 @@ __sta_info_alloc(struct ieee80211_sub_if - struct ieee80211_local *local = sdata->local; - struct ieee80211_hw *hw = &local->hw; - struct sta_info *sta; -+ void *txq_data; -+ int size; - int i; - - sta = kzalloc(sizeof(*sta) + hw->sta_data_size, gfp); -@@ -597,21 +596,18 @@ __sta_info_alloc(struct ieee80211_sub_if - - sta->last_connected = ktime_get_seconds(); - -- if (local->ops->wake_tx_queue) { -- void *txq_data; -- int size = sizeof(struct txq_info) + -- ALIGN(hw->txq_data_size, sizeof(void *)); -+ size = sizeof(struct txq_info) + -+ ALIGN(hw->txq_data_size, sizeof(void *)); - -- txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp); -- if (!txq_data) -- goto free; -+ txq_data = kcalloc(ARRAY_SIZE(sta->sta.txq), size, gfp); -+ if (!txq_data) -+ goto free; - -- for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { -- struct txq_info *txq = txq_data + i * size; -+ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { -+ struct txq_info *txq = txq_data + i * size; - -- /* might not do anything for the bufferable MMPDU TXQ */ -- ieee80211_txq_init(sdata, sta, txq, i); -- } -+ /* might not do anything for the (bufferable) MMPDU TXQ */ -+ ieee80211_txq_init(sdata, sta, txq, i); - } - - if (sta_prepare_rate_control(local, sta, gfp)) -@@ -685,8 +681,7 @@ __sta_info_alloc(struct ieee80211_sub_if - return sta; - - free_txq: -- if (sta->sta.txq[0]) -- kfree(to_txq_info(sta->sta.txq[0])); -+ kfree(to_txq_info(sta->sta.txq[0])); - free: - sta_info_free_link(&sta->deflink); - #ifdef CPTCFG_MAC80211_MESH -@@ -1960,9 +1955,6 @@ ieee80211_sta_ps_deliver_response(struct - * TIM recalculation. - */ - -- if (!sta->sta.txq[0]) -- return; -- - for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { - if (!sta->sta.txq[tid] || - !(driver_release_tids & BIT(tid)) || -@@ -2447,7 +2439,7 @@ static void sta_set_tidstats(struct sta_ - tidstats->tx_msdu_failed = sta->deflink.status_stats.msdu_failed[tid]; - } - -- if (local->ops->wake_tx_queue && tid < IEEE80211_NUM_TIDS) { -+ if (tid < IEEE80211_NUM_TIDS) { - spin_lock_bh(&local->fq.lock); - rcu_read_lock(); - -@@ -2775,9 +2767,6 @@ unsigned long ieee80211_sta_last_active( - - static void sta_update_codel_params(struct sta_info *sta, u32 thr) - { -- if (!sta->sdata->local->ops->wake_tx_queue) -- return; -- - if (thr && thr < STA_SLOW_THRESHOLD * sta->local->num_sta) { - sta->cparams.target = MS2TIME(50); - sta->cparams.interval = MS2TIME(300); ---- a/net/mac80211/tdls.c -+++ b/net/mac80211/tdls.c -@@ -1016,7 +1016,6 @@ ieee80211_tdls_prep_mgmt_packet(struct w - skb->priority = 256 + 5; - break; - } -- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, skb)); - - /* - * Set the WLAN_TDLS_TEARDOWN flag to indicate a teardown in progress. ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1600,9 +1600,6 @@ int ieee80211_txq_setup_flows(struct iee - bool supp_vht = false; - enum nl80211_band band; - -- if (!local->ops->wake_tx_queue) -- return 0; -- - ret = fq_init(fq, 4096); - if (ret) - return ret; -@@ -1650,9 +1647,6 @@ void ieee80211_txq_teardown_flows(struct - { - struct fq *fq = &local->fq; - -- if (!local->ops->wake_tx_queue) -- return; -- - kfree(local->cvars); - local->cvars = NULL; - -@@ -1669,8 +1663,7 @@ static bool ieee80211_queue_skb(struct i - struct ieee80211_vif *vif; - struct txq_info *txqi; - -- if (!local->ops->wake_tx_queue || -- sdata->vif.type == NL80211_IFTYPE_MONITOR) -+ if (sdata->vif.type == NL80211_IFTYPE_MONITOR) - return false; - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) -@@ -4193,12 +4186,7 @@ void __ieee80211_subif_start_xmit(struct - if (IS_ERR(sta)) - sta = NULL; - -- if (local->ops->wake_tx_queue) { -- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -- skb_set_queue_mapping(skb, queue); -- skb_get_hash(skb); -- } -- -+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); - ieee80211_aggr_check(sdata, sta, skb); - - sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -@@ -4509,11 +4497,7 @@ static void ieee80211_8023_xmit(struct i - struct tid_ampdu_tx *tid_tx; - u8 tid; - -- if (local->ops->wake_tx_queue) { -- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -- skb_set_queue_mapping(skb, queue); -- skb_get_hash(skb); -- } -+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); - - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) -@@ -4767,9 +4751,6 @@ void ieee80211_tx_pending(struct tasklet - if (!txok) - break; - } -- -- if (skb_queue_empty(&local->pending[i])) -- ieee80211_propagate_queue_wake(local, i); - } - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - -@@ -5962,10 +5943,9 @@ int ieee80211_tx_control_port(struct wip - } - - if (!IS_ERR(sta)) { -- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -+ u16 queue = ieee80211_select_queue(sdata, sta, skb); - - skb_set_queue_mapping(skb, queue); -- skb_get_hash(skb); - - /* - * for MLO STA, the SA should be the AP MLD address, but ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -444,39 +444,6 @@ void ieee80211_wake_txqs(struct tasklet_ - spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); - } - --void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) --{ -- struct ieee80211_sub_if_data *sdata; -- int n_acs = IEEE80211_NUM_ACS; -- -- if (local->ops->wake_tx_queue) -- return; -- -- if (local->hw.queues < IEEE80211_NUM_ACS) -- n_acs = 1; -- -- list_for_each_entry_rcu(sdata, &local->interfaces, list) { -- int ac; -- -- if (!sdata->dev) -- continue; -- -- if (sdata->vif.cab_queue != IEEE80211_INVAL_HW_QUEUE && -- local->queue_stop_reasons[sdata->vif.cab_queue] != 0) -- continue; -- -- for (ac = 0; ac < n_acs; ac++) { -- int ac_queue = sdata->vif.hw_queue[ac]; -- -- if (ac_queue == queue || -- (sdata->vif.cab_queue == queue && -- local->queue_stop_reasons[ac_queue] == 0 && -- skb_queue_empty(&local->pending[ac_queue]))) -- netif_wake_subqueue(sdata->dev, ac); -- } -- } --} -- - static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue, - enum queue_stop_reason reason, - bool refcounted, -@@ -507,11 +474,7 @@ static void __ieee80211_wake_queue(struc - /* someone still has this queue stopped */ - return; - -- if (skb_queue_empty(&local->pending[queue])) { -- rcu_read_lock(); -- ieee80211_propagate_queue_wake(local, queue); -- rcu_read_unlock(); -- } else -+ if (!skb_queue_empty(&local->pending[queue])) - tasklet_schedule(&local->tx_pending_tasklet); - - /* -@@ -521,12 +484,10 @@ static void __ieee80211_wake_queue(struc - * release someone's lock, but it is fine because all the callers of - * __ieee80211_wake_queue call it right before releasing the lock. - */ -- if (local->ops->wake_tx_queue) { -- if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) -- tasklet_schedule(&local->wake_txqs_tasklet); -- else -- _ieee80211_wake_txqs(local, flags); -- } -+ if (reason == IEEE80211_QUEUE_STOP_REASON_DRIVER) -+ tasklet_schedule(&local->wake_txqs_tasklet); -+ else -+ _ieee80211_wake_txqs(local, flags); - } - - void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, -@@ -554,8 +515,6 @@ static void __ieee80211_stop_queue(struc - bool refcounted) - { - struct ieee80211_local *local = hw_to_local(hw); -- struct ieee80211_sub_if_data *sdata; -- int n_acs = IEEE80211_NUM_ACS; - - trace_stop_queue(local, queue, reason); - -@@ -567,27 +526,7 @@ static void __ieee80211_stop_queue(struc - else - local->q_stop_reasons[queue][reason]++; - -- if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) -- return; -- -- if (local->hw.queues < IEEE80211_NUM_ACS) -- n_acs = 1; -- -- rcu_read_lock(); -- list_for_each_entry_rcu(sdata, &local->interfaces, list) { -- int ac; -- -- if (!sdata->dev) -- continue; -- -- for (ac = 0; ac < n_acs; ac++) { -- if (!local->ops->wake_tx_queue && -- (sdata->vif.hw_queue[ac] == queue || -- sdata->vif.cab_queue == queue)) -- netif_stop_subqueue(sdata->dev, ac); -- } -- } -- rcu_read_unlock(); -+ set_bit(reason, &local->queue_stop_reasons[queue]); - } - - void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, ---- a/net/mac80211/wme.c -+++ b/net/mac80211/wme.c -@@ -122,6 +122,9 @@ u16 ieee80211_select_queue_80211(struct - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); - u8 *p; - -+ /* Ensure hash is set prior to potential SW encryption */ -+ skb_get_hash(skb); -+ - if ((info->control.flags & IEEE80211_TX_CTRL_DONT_REORDER) || - local->hw.queues < IEEE80211_NUM_ACS) - return 0; -@@ -141,13 +144,16 @@ u16 ieee80211_select_queue_80211(struct - return ieee80211_downgrade_queue(sdata, NULL, skb); - } - --u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- struct sta_info *sta, struct sk_buff *skb) -+u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, struct sk_buff *skb) - { - const struct ethhdr *eth = (void *)skb->data; - struct mac80211_qos_map *qos_map; - bool qos; - -+ /* Ensure hash is set prior to potential SW encryption */ -+ skb_get_hash(skb); -+ - /* all mesh/ocb stations are required to support WME */ - if ((sdata->vif.type == NL80211_IFTYPE_MESH_POINT && - !is_multicast_ether_addr(eth->h_dest)) || -@@ -178,59 +184,6 @@ u16 __ieee80211_select_queue(struct ieee - return ieee80211_downgrade_queue(sdata, sta, skb); - } - -- --/* Indicate which queue to use. */ --u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb) --{ -- struct ieee80211_local *local = sdata->local; -- struct sta_info *sta = NULL; -- const u8 *ra = NULL; -- u16 ret; -- -- /* when using iTXQ, we can do this later */ -- if (local->ops->wake_tx_queue) -- return 0; -- -- if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { -- skb->priority = 0; /* required for correct WPA/11i MIC */ -- return 0; -- } -- -- rcu_read_lock(); -- switch (sdata->vif.type) { -- case NL80211_IFTYPE_AP_VLAN: -- sta = rcu_dereference(sdata->u.vlan.sta); -- if (sta) -- break; -- fallthrough; -- case NL80211_IFTYPE_AP: -- ra = skb->data; -- break; -- case NL80211_IFTYPE_STATION: -- /* might be a TDLS station */ -- sta = sta_info_get(sdata, skb->data); -- if (sta) -- break; -- -- ra = sdata->deflink.u.mgd.bssid; -- break; -- case NL80211_IFTYPE_ADHOC: -- ra = skb->data; -- break; -- default: -- break; -- } -- -- if (!sta && ra && !is_multicast_ether_addr(ra)) -- sta = sta_info_get(sdata, ra); -- -- ret = __ieee80211_select_queue(sdata, sta, skb); -- -- rcu_read_unlock(); -- return ret; --} -- - /** - * ieee80211_set_qos_hdr - Fill in the QoS header if there is one. - * ---- a/net/mac80211/wme.h -+++ b/net/mac80211/wme.h -@@ -13,10 +13,8 @@ - u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb, - struct ieee80211_hdr *hdr); --u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- struct sta_info *sta, struct sk_buff *skb); - u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb); -+ struct sta_info *sta, struct sk_buff *skb); - void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, - struct sk_buff *skb); - diff --git a/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch deleted file mode 100644 index f0dfc75a78..0000000000 --- a/package/kernel/mac80211/patches/subsys/306-04-v6.2-wifi-realtek-remove-duplicated-wake_tx_queue.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Mon, 10 Oct 2022 19:17:46 +0200 -Subject: [PATCH] wifi: realtek: remove duplicated wake_tx_queue - -By accident, the previous patch duplicated the initialization -of the wake_tx_queue callback. Fix that by removing the new -initializations. - -Fixes: a790cc3a4fad ("wifi: mac80211: add wake_tx_queue callback to drivers") -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/drivers/net/wireless/realtek/rtw88/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c -@@ -896,7 +896,6 @@ static void rtw_ops_sta_rc_update(struct - - const struct ieee80211_ops rtw_ops = { - .tx = rtw_ops_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw_ops_wake_tx_queue, - .start = rtw_ops_start, - .stop = rtw_ops_stop, ---- a/drivers/net/wireless/realtek/rtw89/mac80211.c -+++ b/drivers/net/wireless/realtek/rtw89/mac80211.c -@@ -918,7 +918,6 @@ static int rtw89_ops_set_tid_config(stru - - const struct ieee80211_ops rtw89_ops = { - .tx = rtw89_ops_tx, -- .wake_tx_queue = ieee80211_handle_wake_tx_queue, - .wake_tx_queue = rtw89_ops_wake_tx_queue, - .start = rtw89_ops_start, - .stop = rtw89_ops_stop, diff --git a/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch index f7391a5809..f362751e0a 100644 --- a/package/kernel/mac80211/patches/subsys/338-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch +++ b/package/kernel/mac80211/patches/subsys/310-mac80211-split-mesh-fast-tx-cache-into-local-proxied.patch @@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c -@@ -703,6 +703,9 @@ bool ieee80211_mesh_xmit_fast(struct iee +@@ -765,6 +765,9 @@ bool ieee80211_mesh_xmit_fast(struct iee struct sk_buff *skb, u32 ctrl_flags) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; @@ -24,7 +24,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> struct ieee80211_mesh_fast_tx *entry; struct ieee80211s_hdr *meshhdr; u8 sa[ETH_ALEN] __aligned(2); -@@ -738,7 +741,10 @@ bool ieee80211_mesh_xmit_fast(struct iee +@@ -800,7 +803,10 @@ bool ieee80211_mesh_xmit_fast(struct iee return false; } @@ -38,7 +38,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h -@@ -133,9 +133,33 @@ struct mesh_path { +@@ -134,9 +134,33 @@ struct mesh_path { #define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ /** @@ -73,7 +73,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> * @fast_tx: base fast_tx data * @hdr: cached mesh and rfc1042 headers * @hdrlen: length of mesh + rfc1042 -@@ -146,7 +170,7 @@ struct mesh_path { +@@ -147,7 +171,7 @@ struct mesh_path { */ struct ieee80211_mesh_fast_tx { struct rhash_head rhash; @@ -82,7 +82,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> struct ieee80211_fast_tx fast_tx; u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; -@@ -329,7 +353,8 @@ void mesh_path_tx_root_frame(struct ieee +@@ -334,7 +358,8 @@ void mesh_path_tx_root_frame(struct ieee bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); struct ieee80211_mesh_fast_tx * @@ -189,7 +189,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c -@@ -2726,7 +2726,10 @@ ieee80211_rx_mesh_fast_forward(struct ie +@@ -2727,7 +2727,10 @@ ieee80211_rx_mesh_fast_forward(struct ie struct sk_buff *skb, int hdrlen) { struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; @@ -201,7 +201,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name> struct ieee80211s_hdr *mesh_hdr; struct tid_ampdu_tx *tid_tx; struct sta_info *sta; -@@ -2735,9 +2738,13 @@ ieee80211_rx_mesh_fast_forward(struct ie +@@ -2736,9 +2739,13 @@ ieee80211_rx_mesh_fast_forward(struct ie mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) diff --git a/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch deleted file mode 100644 index 812b12189c..0000000000 --- a/package/kernel/mac80211/patches/subsys/310-v6.2-mac80211-add-support-for-restricting-netdev-features.patch +++ /dev/null @@ -1,506 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 9 Oct 2022 20:15:46 +0200 -Subject: [PATCH] mac80211: add support for restricting netdev features per vif - -This can be used to selectively disable feature flags for checksum offload, -scatter/gather or GSO by changing vif->netdev_features. -Removing features from vif->netdev_features does not affect the netdev -features themselves, but instead fixes up skbs in the tx path so that the -offloads are not needed in the driver. - -Aside from making it easier to deal with vif type based hardware limitations, -this also makes it possible to optimize performance on hardware without native -GSO support by declaring GSO support in hw->netdev_features and removing it -from vif->netdev_features. This allows mac80211 to handle GSO segmentation -after the sta lookup, but before itxq enqueue, thus reducing the number of -unnecessary sta lookups, as well as some other per-packet processing. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/include/net/fq_impl.h -+++ b/include/net/fq_impl.h -@@ -200,6 +200,7 @@ static void fq_tin_enqueue(struct fq *fq - fq_skb_free_t free_func) - { - struct fq_flow *flow; -+ struct sk_buff *next; - bool oom; - - lockdep_assert_held(&fq->lock); -@@ -214,11 +215,15 @@ static void fq_tin_enqueue(struct fq *fq - } - - flow->tin = tin; -- flow->backlog += skb->len; -- tin->backlog_bytes += skb->len; -- tin->backlog_packets++; -- fq->memory_usage += skb->truesize; -- fq->backlog++; -+ skb_list_walk_safe(skb, skb, next) { -+ skb_mark_not_on_list(skb); -+ flow->backlog += skb->len; -+ tin->backlog_bytes += skb->len; -+ tin->backlog_packets++; -+ fq->memory_usage += skb->truesize; -+ fq->backlog++; -+ __skb_queue_tail(&flow->queue, skb); -+ } - - if (list_empty(&flow->flowchain)) { - flow->deficit = fq->quantum; -@@ -226,7 +231,6 @@ static void fq_tin_enqueue(struct fq *fq - &tin->new_flows); - } - -- __skb_queue_tail(&flow->queue, skb); - oom = (fq->memory_usage > fq->memory_limit); - while (fq->backlog > fq->limit || oom) { - flow = fq_find_fattest_flow(fq); ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1807,6 +1807,10 @@ struct ieee80211_vif_cfg { - * @addr: address of this interface - * @p2p: indicates whether this AP or STA interface is a p2p - * interface, i.e. a GO or p2p-sta respectively -+ * @netdev_features: tx netdev features supported by the hardware for this -+ * vif. mac80211 initializes this to hw->netdev_features, and the driver -+ * can mask out specific tx features. mac80211 will handle software fixup -+ * for masked offloads (GSO, CSUM) - * @driver_flags: flags/capabilities the driver has for this interface, - * these need to be set (or cleared) when the interface is added - * or, if supported by the driver, the interface type is changed -@@ -1846,6 +1850,7 @@ struct ieee80211_vif { - - struct ieee80211_txq *txq; - -+ netdev_features_t netdev_features; - u32 driver_flags; - u32 offload_flags; - ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -2181,6 +2181,7 @@ int ieee80211_if_add(struct ieee80211_lo - ndev->priv_flags |= IFF_LIVE_ADDR_CHANGE; - ndev->hw_features |= ndev->features & - MAC80211_SUPPORTED_FEATURES_TX; -+ sdata->vif.netdev_features = local->hw.netdev_features; - - netdev_set_default_ethtool_ops(ndev, &ieee80211_ethtool_ops); - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1356,7 +1356,11 @@ static struct txq_info *ieee80211_get_tx - - static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) - { -- IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); -+ struct sk_buff *next; -+ codel_time_t now = codel_get_time(); -+ -+ skb_list_walk_safe(skb, skb, next) -+ IEEE80211_SKB_CB(skb)->control.enqueue_time = now; - } - - static u32 codel_skb_len_func(const struct sk_buff *skb) -@@ -3579,55 +3583,79 @@ ieee80211_xmit_fast_finish(struct ieee80 - return TX_CONTINUE; - } - --static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -- struct sta_info *sta, -- struct ieee80211_fast_tx *fast_tx, -- struct sk_buff *skb) -+static netdev_features_t -+ieee80211_sdata_netdev_features(struct ieee80211_sub_if_data *sdata) - { -- struct ieee80211_local *local = sdata->local; -- u16 ethertype = (skb->data[12] << 8) | skb->data[13]; -- int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -- int hw_headroom = sdata->local->hw.extra_tx_headroom; -- struct ethhdr eth; -- struct ieee80211_tx_info *info; -- struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -- struct ieee80211_tx_data tx; -- ieee80211_tx_result r; -- struct tid_ampdu_tx *tid_tx = NULL; -- u8 tid = IEEE80211_NUM_TIDS; -+ if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) -+ return sdata->vif.netdev_features; - -- /* control port protocol needs a lot of special handling */ -- if (cpu_to_be16(ethertype) == sdata->control_port_protocol) -- return false; -+ if (!sdata->bss) -+ return 0; - -- /* only RFC 1042 SNAP */ -- if (ethertype < ETH_P_802_3_MIN) -- return false; -+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, u.ap); -+ return sdata->vif.netdev_features; -+} - -- /* don't handle TX status request here either */ -- if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -- return false; -+static struct sk_buff * -+ieee80211_tx_skb_fixup(struct sk_buff *skb, netdev_features_t features) -+{ -+ if (skb_is_gso(skb)) { -+ struct sk_buff *segs; - -- if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -- tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -- if (tid_tx) { -- if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) -- return false; -- if (tid_tx->timeout) -- tid_tx->last_tx = jiffies; -- } -+ segs = skb_gso_segment(skb, features); -+ if (!segs) -+ return skb; -+ if (IS_ERR(segs)) -+ goto free; -+ -+ consume_skb(skb); -+ return segs; - } - -- /* after this point (skb is modified) we cannot return false */ -+ if (skb_needs_linearize(skb, features) && __skb_linearize(skb)) -+ goto free; -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ int ofs = skb_checksum_start_offset(skb); -+ -+ if (skb->encapsulation) -+ skb_set_inner_transport_header(skb, ofs); -+ else -+ skb_set_transport_header(skb, ofs); -+ -+ if (skb_csum_hwoffload_help(skb, features)) -+ goto free; -+ } -+ -+ skb_mark_not_on_list(skb); -+ return skb; -+ -+free: -+ kfree_skb(skb); -+ return NULL; -+} -+ -+static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, -+ struct ieee80211_fast_tx *fast_tx, -+ struct sk_buff *skb, u8 tid, bool ampdu) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -+ struct ieee80211_tx_info *info; -+ struct ieee80211_tx_data tx; -+ ieee80211_tx_result r; -+ int hw_headroom = sdata->local->hw.extra_tx_headroom; -+ int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -+ struct ethhdr eth; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (unlikely(!skb)) -- return true; -+ return; - - if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && - ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) -- return true; -+ return; - - /* will not be crypto-handled beyond what we do here, so use false - * as the may-encrypt argument for the resize to not account for -@@ -3636,10 +3664,8 @@ static bool ieee80211_xmit_fast(struct i - if (unlikely(ieee80211_skb_resize(sdata, skb, - max_t(int, extra_head + hw_headroom - - skb_headroom(skb), 0), -- ENCRYPT_NO))) { -- kfree_skb(skb); -- return true; -- } -+ ENCRYPT_NO))) -+ goto free; - - memcpy(ð, skb->data, ETH_HLEN - 2); - hdr = skb_push(skb, extra_head); -@@ -3653,7 +3679,7 @@ static bool ieee80211_xmit_fast(struct i - info->control.vif = &sdata->vif; - info->flags = IEEE80211_TX_CTL_FIRST_FRAGMENT | - IEEE80211_TX_CTL_DONTFRAG | -- (tid_tx ? IEEE80211_TX_CTL_AMPDU : 0); -+ (ampdu ? IEEE80211_TX_CTL_AMPDU : 0); - info->control.flags = IEEE80211_TX_CTRL_FAST_XMIT | - u32_encode_bits(IEEE80211_LINK_UNSPECIFIED, - IEEE80211_TX_CTRL_MLO_LINK); -@@ -3677,16 +3703,14 @@ static bool ieee80211_xmit_fast(struct i - tx.key = fast_tx->key; - - if (ieee80211_queue_skb(local, sdata, sta, skb)) -- return true; -+ return; - - tx.skb = skb; - r = ieee80211_xmit_fast_finish(sdata, sta, fast_tx->pn_offs, - fast_tx->key, &tx); - tx.skb = NULL; -- if (r == TX_DROP) { -- kfree_skb(skb); -- return true; -- } -+ if (r == TX_DROP) -+ goto free; - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, -@@ -3694,6 +3718,56 @@ static bool ieee80211_xmit_fast(struct i - - __skb_queue_tail(&tx.skbs, skb); - ieee80211_tx_frags(local, &sdata->vif, sta, &tx.skbs, false); -+ return; -+ -+free: -+ kfree_skb(skb); -+} -+ -+static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, -+ struct ieee80211_fast_tx *fast_tx, -+ struct sk_buff *skb) -+{ -+ u16 ethertype = (skb->data[12] << 8) | skb->data[13]; -+ struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -+ struct tid_ampdu_tx *tid_tx = NULL; -+ struct sk_buff *next; -+ u8 tid = IEEE80211_NUM_TIDS; -+ -+ /* control port protocol needs a lot of special handling */ -+ if (cpu_to_be16(ethertype) == sdata->control_port_protocol) -+ return false; -+ -+ /* only RFC 1042 SNAP */ -+ if (ethertype < ETH_P_802_3_MIN) -+ return false; -+ -+ /* don't handle TX status request here either */ -+ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -+ return false; -+ -+ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -+ if (tid_tx) { -+ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) -+ return false; -+ if (tid_tx->timeout) -+ tid_tx->last_tx = jiffies; -+ } -+ } -+ -+ /* after this point (skb is modified) we cannot return false */ -+ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -+ if (!skb) -+ return true; -+ -+ skb_list_walk_safe(skb, skb, next) { -+ skb_mark_not_on_list(skb); -+ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); -+ } -+ - return true; - } - -@@ -4201,31 +4275,14 @@ void __ieee80211_subif_start_xmit(struct - goto out; - } - -- if (skb_is_gso(skb)) { -- struct sk_buff *segs; -- -- segs = skb_gso_segment(skb, 0); -- if (IS_ERR(segs)) { -- goto out_free; -- } else if (segs) { -- consume_skb(skb); -- skb = segs; -- } -- } else { -- /* we cannot process non-linear frames on this path */ -- if (skb_linearize(skb)) -- goto out_free; -- -- /* the frame could be fragmented, software-encrypted, and other -- * things so we cannot really handle checksum offload with it - -- * fix it up in software before we handle anything else. -- */ -- if (skb->ip_summed == CHECKSUM_PARTIAL) { -- skb_set_transport_header(skb, -- skb_checksum_start_offset(skb)); -- if (skb_checksum_help(skb)) -- goto out_free; -- } -+ /* the frame could be fragmented, software-encrypted, and other -+ * things so we cannot really handle checksum or GSO offload. -+ * fix it up in software before we handle anything else. -+ */ -+ skb = ieee80211_tx_skb_fixup(skb, 0); -+ if (!skb) { -+ len = 0; -+ goto out; - } - - skb_list_walk_safe(skb, skb, next) { -@@ -4443,9 +4500,11 @@ normal: - return NETDEV_TX_OK; - } - --static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -- struct sk_buff *skb, struct sta_info *sta, -- bool txpending) -+ -+ -+static bool __ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, struct sta_info *sta, -+ bool txpending) - { - struct ieee80211_local *local = sdata->local; - struct ieee80211_tx_control control = {}; -@@ -4454,14 +4513,6 @@ static bool ieee80211_tx_8023(struct iee - unsigned long flags; - int q = info->hw_queue; - -- if (sta) -- sk_pacing_shift_update(skb->sk, local->hw.tx_sk_pacing_shift); -- -- ieee80211_tpt_led_trig_tx(local, skb->len); -- -- if (ieee80211_queue_skb(local, sdata, sta, skb)) -- return true; -- - spin_lock_irqsave(&local->queue_stop_reason_lock, flags); - - if (local->queue_stop_reasons[q] || -@@ -4488,6 +4539,26 @@ static bool ieee80211_tx_8023(struct iee - return true; - } - -+static bool ieee80211_tx_8023(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, struct sta_info *sta, -+ bool txpending) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct sk_buff *next; -+ bool ret = true; -+ -+ if (ieee80211_queue_skb(local, sdata, sta, skb)) -+ return true; -+ -+ skb_list_walk_safe(skb, skb, next) { -+ skb_mark_not_on_list(skb); -+ if (!__ieee80211_tx_8023(sdata, skb, sta, txpending)) -+ ret = false; -+ } -+ -+ return ret; -+} -+ - static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, - struct net_device *dev, struct sta_info *sta, - struct ieee80211_key *key, struct sk_buff *skb) -@@ -4495,9 +4566,13 @@ static void ieee80211_8023_xmit(struct i - struct ieee80211_tx_info *info; - struct ieee80211_local *local = sdata->local; - struct tid_ampdu_tx *tid_tx; -+ struct sk_buff *seg, *next; -+ unsigned int skbs = 0, len = 0; -+ u16 queue; - u8 tid; - -- skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -+ queue = ieee80211_select_queue(sdata, sta, skb); -+ skb_set_queue_mapping(skb, queue); - - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) -@@ -4507,9 +4582,6 @@ static void ieee80211_8023_xmit(struct i - if (unlikely(!skb)) - return; - -- info = IEEE80211_SKB_CB(skb); -- memset(info, 0, sizeof(*info)); -- - ieee80211_aggr_check(sdata, sta, skb); - - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -@@ -4523,22 +4595,20 @@ static void ieee80211_8023_xmit(struct i - return; - } - -- info->flags |= IEEE80211_TX_CTL_AMPDU; - if (tid_tx->timeout) - tid_tx->last_tx = jiffies; - } - -- if (unlikely(skb->sk && -- skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) -- info->ack_frame_id = ieee80211_store_ack_skb(local, skb, -- &info->flags, NULL); -+ skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); -+ if (!skb) -+ return; - -- info->hw_queue = sdata->vif.hw_queue[skb_get_queue_mapping(skb)]; -+ info = IEEE80211_SKB_CB(skb); -+ memset(info, 0, sizeof(*info)); -+ if (tid_tx) -+ info->flags |= IEEE80211_TX_CTL_AMPDU; - -- dev_sw_netstats_tx_add(dev, 1, skb->len); -- -- sta->deflink.tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; -- sta->deflink.tx_stats.packets[skb_get_queue_mapping(skb)]++; -+ info->hw_queue = sdata->vif.hw_queue[queue]; - - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) - sdata = container_of(sdata->bss, -@@ -4550,6 +4620,24 @@ static void ieee80211_8023_xmit(struct i - if (key) - info->control.hw_key = &key->conf; - -+ skb_list_walk_safe(skb, seg, next) { -+ skbs++; -+ len += seg->len; -+ if (seg != skb) -+ memcpy(IEEE80211_SKB_CB(seg), info, sizeof(*info)); -+ } -+ -+ if (unlikely(skb->sk && -+ skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS)) -+ info->ack_frame_id = ieee80211_store_ack_skb(local, skb, -+ &info->flags, NULL); -+ -+ dev_sw_netstats_tx_add(dev, skbs, len); -+ sta->deflink.tx_stats.packets[queue] += skbs; -+ sta->deflink.tx_stats.bytes[queue] += len; -+ -+ ieee80211_tpt_led_trig_tx(local, len); -+ - ieee80211_tx_8023(sdata, skb, sta, false); - - return; -@@ -4591,6 +4679,7 @@ netdev_tx_t ieee80211_subif_start_xmit_8 - key->conf.cipher == WLAN_CIPHER_SUITE_TKIP)) - goto skip_offload; - -+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); - ieee80211_8023_xmit(sdata, dev, sta, key, skb); - goto out; - diff --git a/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch b/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch deleted file mode 100644 index 804b02eb30..0000000000 --- a/package/kernel/mac80211/patches/subsys/311-v6.2-wifi-mac80211-fix-and-simplify-unencrypted-drop-chec.patch +++ /dev/null @@ -1,87 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Thu, 1 Dec 2022 14:57:30 +0100 -Subject: [PATCH] wifi: mac80211: fix and simplify unencrypted drop check for - mesh - -ieee80211_drop_unencrypted is called from ieee80211_rx_h_mesh_fwding and -ieee80211_frame_allowed. - -Since ieee80211_rx_h_mesh_fwding can forward packets for other mesh nodes -and is called earlier, it needs to check the decryptions status and if the -packet is using the control protocol on its own, instead of deferring to -the later call from ieee80211_frame_allowed. - -Because of that, ieee80211_drop_unencrypted has a mesh specific check -that skips over the mesh header in order to check the payload protocol. -This code is invalid when called from ieee80211_frame_allowed, since that -happens after the 802.11->802.3 conversion. - -Fix this by moving the mesh specific check directly into -ieee80211_rx_h_mesh_fwding. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> -Link: https://lore.kernel.org/r/20221201135730.19723-1-nbd@nbd.name -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2403,7 +2403,6 @@ static int ieee80211_802_1x_port_control - - static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) - { -- struct ieee80211_hdr *hdr = (void *)rx->skb->data; - struct sk_buff *skb = rx->skb; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); - -@@ -2414,31 +2413,6 @@ static int ieee80211_drop_unencrypted(st - if (status->flag & RX_FLAG_DECRYPTED) - return 0; - -- /* check mesh EAPOL frames first */ -- if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) && -- ieee80211_is_data(fc))) { -- struct ieee80211s_hdr *mesh_hdr; -- u16 hdr_len = ieee80211_hdrlen(fc); -- u16 ethertype_offset; -- __be16 ethertype; -- -- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr)) -- goto drop_check; -- -- /* make sure fixed part of mesh header is there, also checks skb len */ -- if (!pskb_may_pull(rx->skb, hdr_len + 6)) -- goto drop_check; -- -- mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len); -- ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) + -- sizeof(rfc1042_header); -- -- if (skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2) == 0 && -- ethertype == rx->sdata->control_port_protocol) -- return 0; -- } -- --drop_check: - /* Drop unencrypted frames if key is set. */ - if (unlikely(!ieee80211_has_protected(fc) && - !ieee80211_is_any_nullfunc(fc) && -@@ -2892,8 +2866,16 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 - hdr = (struct ieee80211_hdr *) skb->data; - mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); - -- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) -- return RX_DROP_MONITOR; -+ if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { -+ int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + -+ sizeof(rfc1042_header); -+ __be16 ethertype; -+ -+ if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || -+ skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || -+ ethertype != rx->sdata->control_port_protocol) -+ return RX_DROP_MONITOR; -+ } - - /* frame is in RMC, don't forward */ - if (ieee80211_is_data(hdr->frame_control) && diff --git a/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch b/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch deleted file mode 100644 index f668905cca..0000000000 --- a/package/kernel/mac80211/patches/subsys/312-v6.3-wifi-cfg80211-move-A-MSDU-check-in-ieee80211_data_to.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Fri, 2 Dec 2022 13:53:11 +0100 -Subject: [PATCH] wifi: cfg80211: move A-MSDU check in - ieee80211_data_to_8023_exthdr - -When parsing the outer A-MSDU header, don't check for inner bridge tunnel -or RFC1042 headers. This is handled by ieee80211_amsdu_to_8023s already. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -631,8 +631,9 @@ int ieee80211_data_to_8023_exthdr(struct - break; - } - -- if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -- ((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && -+ if (likely(!is_amsdu && -+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -+ ((ether_addr_equal(payload.hdr, rfc1042_header) && - payload.proto != htons(ETH_P_AARP) && - payload.proto != htons(ETH_P_IPX)) || - ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { diff --git a/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch b/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch deleted file mode 100644 index 8641057869..0000000000 --- a/package/kernel/mac80211/patches/subsys/313-v6.3-wifi-cfg80211-factor-out-bridge-tunnel-RFC1042-heade.patch +++ /dev/null @@ -1,76 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Fri, 2 Dec 2022 13:54:15 +0100 -Subject: [PATCH] wifi: cfg80211: factor out bridge tunnel / RFC1042 header - check - -The same check is done in multiple places, unify it. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -542,6 +542,21 @@ unsigned int ieee80211_get_mesh_hdrlen(s - } - EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); - -+static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -+{ -+ const __be16 *hdr_proto = hdr + ETH_ALEN; -+ -+ if (!(ether_addr_equal(hdr, rfc1042_header) && -+ *hdr_proto != htons(ETH_P_AARP) && -+ *hdr_proto != htons(ETH_P_IPX)) && -+ !ether_addr_equal(hdr, bridge_tunnel_header)) -+ return false; -+ -+ *proto = *hdr_proto; -+ -+ return true; -+} -+ - int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, - const u8 *addr, enum nl80211_iftype iftype, - u8 data_offset, bool is_amsdu) -@@ -633,14 +648,9 @@ int ieee80211_data_to_8023_exthdr(struct - - if (likely(!is_amsdu && - skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -- ((ether_addr_equal(payload.hdr, rfc1042_header) && -- payload.proto != htons(ETH_P_AARP) && -- payload.proto != htons(ETH_P_IPX)) || -- ether_addr_equal(payload.hdr, bridge_tunnel_header)))) { -- /* remove RFC1042 or Bridge-Tunnel encapsulation and -- * replace EtherType */ -+ ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { -+ /* remove RFC1042 or Bridge-Tunnel encapsulation */ - hdrlen += ETH_ALEN + 2; -- tmp.h_proto = payload.proto; - skb_postpull_rcsum(skb, &payload, ETH_ALEN + 2); - } else { - tmp.h_proto = htons(skb->len - hdrlen); -@@ -756,8 +766,6 @@ void ieee80211_amsdu_to_8023s(struct sk_ - { - unsigned int hlen = ALIGN(extra_headroom, 4); - struct sk_buff *frame = NULL; -- u16 ethertype; -- u8 *payload; - int offset = 0, remaining; - struct ethhdr eth; - bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); -@@ -811,14 +819,8 @@ void ieee80211_amsdu_to_8023s(struct sk_ - frame->dev = skb->dev; - frame->priority = skb->priority; - -- payload = frame->data; -- ethertype = (payload[6] << 8) | payload[7]; -- if (likely((ether_addr_equal(payload, rfc1042_header) && -- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || -- ether_addr_equal(payload, bridge_tunnel_header))) { -- eth.h_proto = htons(ethertype); -+ if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) - skb_pull(frame, ETH_ALEN + 2); -- } - - memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); - __skb_queue_tail(list, frame); diff --git a/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch b/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch deleted file mode 100644 index 515176f0de..0000000000 --- a/package/kernel/mac80211/patches/subsys/314-v6.3-wifi-mac80211-remove-mesh-forwarding-congestion-chec.patch +++ /dev/null @@ -1,54 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Fri, 2 Dec 2022 17:01:46 +0100 -Subject: [PATCH] wifi: mac80211: remove mesh forwarding congestion check - -Now that all drivers use iTXQ, it does not make sense to check to drop -tx forwarding packets when the driver has stopped the queues. -fq_codel will take care of dropping packets when the queues fill up - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/debugfs_netdev.c -+++ b/net/mac80211/debugfs_netdev.c -@@ -603,8 +603,6 @@ IEEE80211_IF_FILE(fwded_mcast, u.mesh.ms - IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); - IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); - IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); --IEEE80211_IF_FILE(dropped_frames_congestion, -- u.mesh.mshstats.dropped_frames_congestion, DEC); - IEEE80211_IF_FILE(dropped_frames_no_route, - u.mesh.mshstats.dropped_frames_no_route, DEC); - -@@ -740,7 +738,6 @@ static void add_mesh_stats(struct ieee80 - MESHSTATS_ADD(fwded_frames); - MESHSTATS_ADD(dropped_frames_ttl); - MESHSTATS_ADD(dropped_frames_no_route); -- MESHSTATS_ADD(dropped_frames_congestion); - #undef MESHSTATS_ADD - } - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -329,7 +329,6 @@ struct mesh_stats { - __u32 fwded_frames; /* Mesh total forwarded frames */ - __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ - __u32 dropped_frames_no_route; /* Not transmitted, no route found */ -- __u32 dropped_frames_congestion;/* Not forwarded due to congestion */ - }; - - #define PREQ_Q_F_START 0x1 ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2926,11 +2926,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 - return RX_CONTINUE; - - ac = ieee802_1d_to_ac[skb->priority]; -- q = sdata->vif.hw_queue[ac]; -- if (ieee80211_queue_stopped(&local->hw, q)) { -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); -- return RX_DROP_MONITOR; -- } - skb_set_queue_mapping(skb, ac); - - if (!--mesh_hdr->ttl) { diff --git a/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch b/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch deleted file mode 100644 index 59b799b6b1..0000000000 --- a/package/kernel/mac80211/patches/subsys/315-v6.3-wifi-mac80211-fix-receiving-A-MSDU-frames-on-mesh-in.patch +++ /dev/null @@ -1,762 +0,0 @@ -From 986e43b19ae9176093da35e0a844e65c8bf9ede7 Mon Sep 17 00:00:00 2001 -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 13 Feb 2023 11:08:54 +0100 -Subject: [PATCH] wifi: mac80211: fix receiving A-MSDU frames on mesh - interfaces - -The current mac80211 mesh A-MSDU receive path fails to parse A-MSDU packets -on mesh interfaces, because it assumes that the Mesh Control field is always -directly after the 802.11 header. -802.11-2020 9.3.2.2.2 Figure 9-70 shows that the Mesh Control field is -actually part of the A-MSDU subframe header. -This makes more sense, since it allows packets for multiple different -destinations to be included in the same A-MSDU, as long as RA and TID are -still the same. -Another issue is the fact that the A-MSDU subframe length field was apparently -accidentally defined as little-endian in the standard. - -In order to fix this, the mesh forwarding path needs happen at a different -point in the receive path. - -ieee80211_data_to_8023_exthdr is changed to ignore the mesh control field -and leave it in after the ethernet header. This also affects the source/dest -MAC address fields, which now in the case of mesh point to the mesh SA/DA. - -ieee80211_amsdu_to_8023s is changed to deal with the endian difference and -to add the Mesh Control length to the subframe length, since it's not covered -by the MSDU length field. - -With these changes, the mac80211 will get the same packet structure for -converted regular data packets and unpacked A-MSDU subframes. - -The mesh forwarding checks are now only performed after the A-MSDU decap. -For locally received packets, the Mesh Control header is stripped away. -For forwarded packets, a new 802.11 header gets added. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> -Link: https://lore.kernel.org/r/20230213100855.34315-4-nbd@nbd.name -[fix fortify build error] -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - .../wireless/marvell/mwifiex/11n_rxreorder.c | 2 +- - include/net/cfg80211.h | 27 +- - net/mac80211/rx.c | 350 ++++++++++-------- - net/wireless/util.c | 120 +++--- - 4 files changed, 297 insertions(+), 202 deletions(-) - ---- a/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -+++ b/drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c -@@ -33,7 +33,7 @@ static int mwifiex_11n_dispatch_amsdu_pk - skb_trim(skb, le16_to_cpu(local_rx_pd->rx_pkt_length)); - - ieee80211_amsdu_to_8023s(skb, &list, priv->curr_addr, -- priv->wdev.iftype, 0, NULL, NULL); -+ priv->wdev.iftype, 0, NULL, NULL, false); - - while (!skb_queue_empty(&list)) { - struct rx_packet_hdr *rx_hdr; ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -6208,11 +6208,36 @@ static inline int ieee80211_data_to_8023 - * @extra_headroom: The hardware extra headroom for SKBs in the @list. - * @check_da: DA to check in the inner ethernet header, or NULL - * @check_sa: SA to check in the inner ethernet header, or NULL -+ * @mesh_control: A-MSDU subframe header includes the mesh control field - */ - void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, - const u8 *addr, enum nl80211_iftype iftype, - const unsigned int extra_headroom, -- const u8 *check_da, const u8 *check_sa); -+ const u8 *check_da, const u8 *check_sa, -+ bool mesh_control); -+ -+/** -+ * ieee80211_get_8023_tunnel_proto - get RFC1042 or bridge tunnel encap protocol -+ * -+ * Check for RFC1042 or bridge tunnel header and fetch the encapsulated -+ * protocol. -+ * -+ * @hdr: pointer to the MSDU payload -+ * @proto: destination pointer to store the protocol -+ * Return: true if encapsulation was found -+ */ -+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto); -+ -+/** -+ * ieee80211_strip_8023_mesh_hdr - strip mesh header from converted 802.3 frames -+ * -+ * Strip the mesh header, which was left in by ieee80211_data_to_8023 as part -+ * of the MSDU data. Also move any source/destination addresses from the mesh -+ * header to the ethernet header (if present). -+ * -+ * @skb: The 802.3 frame with embedded mesh header -+ */ -+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb); - - /** - * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2720,6 +2720,174 @@ ieee80211_deliver_skb(struct ieee80211_r - } - } - -+static ieee80211_rx_result -+ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, -+ struct sk_buff *skb) -+{ -+#ifdef CPTCFG_MAC80211_MESH -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+ struct ieee80211_local *local = sdata->local; -+ uint16_t fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA; -+ struct ieee80211_hdr hdr = { -+ .frame_control = cpu_to_le16(fc) -+ }; -+ struct ieee80211_hdr *fwd_hdr; -+ struct ieee80211s_hdr *mesh_hdr; -+ struct ieee80211_tx_info *info; -+ struct sk_buff *fwd_skb; -+ struct ethhdr *eth; -+ bool multicast; -+ int tailroom = 0; -+ int hdrlen, mesh_hdrlen; -+ u8 *qos; -+ -+ if (!ieee80211_vif_is_mesh(&sdata->vif)) -+ return RX_CONTINUE; -+ -+ if (!pskb_may_pull(skb, sizeof(*eth) + 6)) -+ return RX_DROP_MONITOR; -+ -+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth)); -+ mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr); -+ -+ if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen)) -+ return RX_DROP_MONITOR; -+ -+ eth = (struct ethhdr *)skb->data; -+ multicast = is_multicast_ether_addr(eth->h_dest); -+ -+ mesh_hdr = (struct ieee80211s_hdr *)(eth + 1); -+ if (!mesh_hdr->ttl) -+ return RX_DROP_MONITOR; -+ -+ /* frame is in RMC, don't forward */ -+ if (is_multicast_ether_addr(eth->h_dest) && -+ mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) -+ return RX_DROP_MONITOR; -+ -+ /* Frame has reached destination. Don't forward */ -+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -+ goto rx_accept; -+ -+ if (!ifmsh->mshcfg.dot11MeshForwarding) { -+ if (is_multicast_ether_addr(eth->h_dest)) -+ goto rx_accept; -+ -+ return RX_DROP_MONITOR; -+ } -+ -+ /* forward packet */ -+ if (sdata->crypto_tx_tailroom_needed_cnt) -+ tailroom = IEEE80211_ENCRYPT_TAILROOM; -+ -+ if (!--mesh_hdr->ttl) { -+ if (multicast) -+ goto rx_accept; -+ -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -+ return RX_DROP_MONITOR; -+ } -+ -+ if (mesh_hdr->flags & MESH_FLAGS_AE) { -+ struct mesh_path *mppath; -+ char *proxied_addr; -+ -+ if (multicast) -+ proxied_addr = mesh_hdr->eaddr1; -+ else if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) -+ /* has_a4 already checked in ieee80211_rx_mesh_check */ -+ proxied_addr = mesh_hdr->eaddr2; -+ else -+ return RX_DROP_MONITOR; -+ -+ rcu_read_lock(); -+ mppath = mpp_path_lookup(sdata, proxied_addr); -+ if (!mppath) { -+ mpp_path_add(sdata, proxied_addr, eth->h_source); -+ } else { -+ spin_lock_bh(&mppath->state_lock); -+ if (!ether_addr_equal(mppath->mpp, eth->h_source)) -+ memcpy(mppath->mpp, eth->h_source, ETH_ALEN); -+ mppath->exp_time = jiffies; -+ spin_unlock_bh(&mppath->state_lock); -+ } -+ rcu_read_unlock(); -+ } -+ -+ skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); -+ -+ ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, -+ eth->h_dest, eth->h_source); -+ hdrlen = ieee80211_hdrlen(hdr.frame_control); -+ if (multicast) { -+ int extra_head = sizeof(struct ieee80211_hdr) - sizeof(*eth); -+ -+ fwd_skb = skb_copy_expand(skb, local->tx_headroom + extra_head + -+ IEEE80211_ENCRYPT_HEADROOM, -+ tailroom, GFP_ATOMIC); -+ if (!fwd_skb) -+ goto rx_accept; -+ } else { -+ fwd_skb = skb; -+ skb = NULL; -+ -+ if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) -+ return RX_DROP_UNUSABLE; -+ } -+ -+ fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); -+ memcpy(fwd_hdr, &hdr, hdrlen - 2); -+ qos = ieee80211_get_qos_ctl(fwd_hdr); -+ qos[0] = qos[1] = 0; -+ -+ skb_reset_mac_header(fwd_skb); -+ hdrlen += mesh_hdrlen; -+ if (ieee80211_get_8023_tunnel_proto(fwd_skb->data + hdrlen, -+ &fwd_skb->protocol)) -+ hdrlen += ETH_ALEN; -+ else -+ fwd_skb->protocol = htons(fwd_skb->len - hdrlen); -+ skb_set_network_header(fwd_skb, hdrlen); -+ -+ info = IEEE80211_SKB_CB(fwd_skb); -+ memset(info, 0, sizeof(*info)); -+ info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -+ info->control.vif = &sdata->vif; -+ info->control.jiffies = jiffies; -+ if (multicast) { -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -+ memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -+ /* update power mode indication when forwarding */ -+ ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); -+ } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { -+ /* mesh power mode flags updated in mesh_nexthop_lookup */ -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -+ } else { -+ /* unable to resolve next hop */ -+ if (sta) -+ mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, -+ hdr.addr3, 0, -+ WLAN_REASON_MESH_PATH_NOFORWARD, -+ sta->sta.addr); -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); -+ kfree_skb(fwd_skb); -+ goto rx_accept; -+ } -+ -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -+ fwd_skb->dev = sdata->dev; -+ ieee80211_add_pending_skb(local, fwd_skb); -+ -+rx_accept: -+ if (!skb) -+ return RX_QUEUED; -+ -+ ieee80211_strip_8023_mesh_hdr(skb); -+#endif -+ -+ return RX_CONTINUE; -+} -+ - static ieee80211_rx_result debug_noinline - __ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx, u8 data_offset) - { -@@ -2728,8 +2896,10 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - __le16 fc = hdr->frame_control; - struct sk_buff_head frame_list; -+ static ieee80211_rx_result res; - struct ethhdr ethhdr; - const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; -+ bool mesh = false; - - if (unlikely(ieee80211_has_a4(hdr->frame_control))) { - check_da = NULL; -@@ -2746,6 +2916,8 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - break; - case NL80211_IFTYPE_MESH_POINT: - check_sa = NULL; -+ check_da = NULL; -+ mesh = true; - break; - default: - break; -@@ -2763,17 +2935,29 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, - rx->sdata->vif.type, - rx->local->hw.extra_tx_headroom, -- check_da, check_sa); -+ check_da, check_sa, mesh); - - while (!skb_queue_empty(&frame_list)) { - rx->skb = __skb_dequeue(&frame_list); - -- if (!ieee80211_frame_allowed(rx, fc)) { -- dev_kfree_skb(rx->skb); -+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -+ switch (res) { -+ case RX_QUEUED: - continue; -+ case RX_CONTINUE: -+ break; -+ default: -+ goto free; - } - -+ if (!ieee80211_frame_allowed(rx, fc)) -+ goto free; -+ - ieee80211_deliver_skb(rx); -+ continue; -+ -+free: -+ dev_kfree_skb(rx->skb); - } - - return RX_QUEUED; -@@ -2806,6 +2990,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx - if (!rx->sdata->u.mgd.use_4addr) - return RX_DROP_UNUSABLE; - break; -+ case NL80211_IFTYPE_MESH_POINT: -+ break; - default: - return RX_DROP_UNUSABLE; - } -@@ -2834,155 +3020,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx - return __ieee80211_rx_h_amsdu(rx, 0); - } - --#ifdef CPTCFG_MAC80211_MESH --static ieee80211_rx_result --ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) --{ -- struct ieee80211_hdr *fwd_hdr, *hdr; -- struct ieee80211_tx_info *info; -- struct ieee80211s_hdr *mesh_hdr; -- struct sk_buff *skb = rx->skb, *fwd_skb; -- struct ieee80211_local *local = rx->local; -- struct ieee80211_sub_if_data *sdata = rx->sdata; -- struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -- u16 ac, q, hdrlen; -- int tailroom = 0; -- -- hdr = (struct ieee80211_hdr *) skb->data; -- hdrlen = ieee80211_hdrlen(hdr->frame_control); -- -- /* make sure fixed part of mesh header is there, also checks skb len */ -- if (!pskb_may_pull(rx->skb, hdrlen + 6)) -- return RX_DROP_MONITOR; -- -- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -- -- /* make sure full mesh header is there, also checks skb len */ -- if (!pskb_may_pull(rx->skb, -- hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr))) -- return RX_DROP_MONITOR; -- -- /* reload pointers */ -- hdr = (struct ieee80211_hdr *) skb->data; -- mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); -- -- if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) { -- int offset = hdrlen + ieee80211_get_mesh_hdrlen(mesh_hdr) + -- sizeof(rfc1042_header); -- __be16 ethertype; -- -- if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr) || -- skb_copy_bits(rx->skb, offset, ðertype, 2) != 0 || -- ethertype != rx->sdata->control_port_protocol) -- return RX_DROP_MONITOR; -- } -- -- /* frame is in RMC, don't forward */ -- if (ieee80211_is_data(hdr->frame_control) && -- is_multicast_ether_addr(hdr->addr1) && -- mesh_rmc_check(rx->sdata, hdr->addr3, mesh_hdr)) -- return RX_DROP_MONITOR; -- -- if (!ieee80211_is_data(hdr->frame_control)) -- return RX_CONTINUE; -- -- if (!mesh_hdr->ttl) -- return RX_DROP_MONITOR; -- -- if (mesh_hdr->flags & MESH_FLAGS_AE) { -- struct mesh_path *mppath; -- char *proxied_addr; -- char *mpp_addr; -- -- if (is_multicast_ether_addr(hdr->addr1)) { -- mpp_addr = hdr->addr3; -- proxied_addr = mesh_hdr->eaddr1; -- } else if ((mesh_hdr->flags & MESH_FLAGS_AE) == -- MESH_FLAGS_AE_A5_A6) { -- /* has_a4 already checked in ieee80211_rx_mesh_check */ -- mpp_addr = hdr->addr4; -- proxied_addr = mesh_hdr->eaddr2; -- } else { -- return RX_DROP_MONITOR; -- } -- -- rcu_read_lock(); -- mppath = mpp_path_lookup(sdata, proxied_addr); -- if (!mppath) { -- mpp_path_add(sdata, proxied_addr, mpp_addr); -- } else { -- spin_lock_bh(&mppath->state_lock); -- if (!ether_addr_equal(mppath->mpp, mpp_addr)) -- memcpy(mppath->mpp, mpp_addr, ETH_ALEN); -- mppath->exp_time = jiffies; -- spin_unlock_bh(&mppath->state_lock); -- } -- rcu_read_unlock(); -- } -- -- /* Frame has reached destination. Don't forward */ -- if (!is_multicast_ether_addr(hdr->addr1) && -- ether_addr_equal(sdata->vif.addr, hdr->addr3)) -- return RX_CONTINUE; -- -- ac = ieee802_1d_to_ac[skb->priority]; -- skb_set_queue_mapping(skb, ac); -- -- if (!--mesh_hdr->ttl) { -- if (!is_multicast_ether_addr(hdr->addr1)) -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, -- dropped_frames_ttl); -- goto out; -- } -- -- if (!ifmsh->mshcfg.dot11MeshForwarding) -- goto out; -- -- if (sdata->crypto_tx_tailroom_needed_cnt) -- tailroom = IEEE80211_ENCRYPT_TAILROOM; -- -- fwd_skb = skb_copy_expand(skb, local->tx_headroom + -- IEEE80211_ENCRYPT_HEADROOM, -- tailroom, GFP_ATOMIC); -- if (!fwd_skb) -- goto out; -- -- fwd_skb->dev = sdata->dev; -- fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; -- fwd_hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_RETRY); -- info = IEEE80211_SKB_CB(fwd_skb); -- memset(info, 0, sizeof(*info)); -- info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; -- info->control.vif = &rx->sdata->vif; -- info->control.jiffies = jiffies; -- if (is_multicast_ether_addr(fwd_hdr->addr1)) { -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); -- memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -- /* update power mode indication when forwarding */ -- ieee80211_mps_set_frame_flags(sdata, NULL, fwd_hdr); -- } else if (!mesh_nexthop_lookup(sdata, fwd_skb)) { -- /* mesh power mode flags updated in mesh_nexthop_lookup */ -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -- } else { -- /* unable to resolve next hop */ -- mesh_path_error_tx(sdata, ifmsh->mshcfg.element_ttl, -- fwd_hdr->addr3, 0, -- WLAN_REASON_MESH_PATH_NOFORWARD, -- fwd_hdr->addr2); -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_no_route); -- kfree_skb(fwd_skb); -- return RX_DROP_MONITOR; -- } -- -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -- ieee80211_add_pending_skb(local, fwd_skb); -- out: -- if (is_multicast_ether_addr(hdr->addr1)) -- return RX_CONTINUE; -- return RX_DROP_MONITOR; --} --#endif -- - static ieee80211_rx_result debug_noinline - ieee80211_rx_h_data(struct ieee80211_rx_data *rx) - { -@@ -2991,6 +3028,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_ - struct net_device *dev = sdata->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; - __le16 fc = hdr->frame_control; -+ static ieee80211_rx_result res; - bool port_control; - int err; - -@@ -3017,6 +3055,10 @@ ieee80211_rx_h_data(struct ieee80211_rx_ - if (unlikely(err)) - return RX_DROP_UNUSABLE; - -+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -+ if (res != RX_CONTINUE) -+ return res; -+ - if (!ieee80211_frame_allowed(rx, fc)) - return RX_DROP_MONITOR; - -@@ -3987,10 +4029,6 @@ static void ieee80211_rx_handlers(struct - CALL_RXH(ieee80211_rx_h_defragment); - CALL_RXH(ieee80211_rx_h_michael_mic_verify); - /* must be after MMIC verify so header is counted in MPDU mic */ --#ifdef CPTCFG_MAC80211_MESH -- if (ieee80211_vif_is_mesh(&rx->sdata->vif)) -- CALL_RXH(ieee80211_rx_h_mesh_fwding); --#endif - CALL_RXH(ieee80211_rx_h_amsdu); - CALL_RXH(ieee80211_rx_h_data); - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -542,7 +542,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s - } - EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); - --static bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) -+bool ieee80211_get_8023_tunnel_proto(const void *hdr, __be16 *proto) - { - const __be16 *hdr_proto = hdr + ETH_ALEN; - -@@ -556,6 +556,49 @@ static bool ieee80211_get_8023_tunnel_pr - - return true; - } -+EXPORT_SYMBOL(ieee80211_get_8023_tunnel_proto); -+ -+int ieee80211_strip_8023_mesh_hdr(struct sk_buff *skb) -+{ -+ const void *mesh_addr; -+ struct { -+ struct ethhdr eth; -+ u8 flags; -+ } payload; -+ int hdrlen; -+ int ret; -+ -+ ret = skb_copy_bits(skb, 0, &payload, sizeof(payload)); -+ if (ret) -+ return ret; -+ -+ hdrlen = sizeof(payload.eth) + __ieee80211_get_mesh_hdrlen(payload.flags); -+ -+ if (likely(pskb_may_pull(skb, hdrlen + 8) && -+ ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, -+ &payload.eth.h_proto))) -+ hdrlen += ETH_ALEN + 2; -+ else if (!pskb_may_pull(skb, hdrlen)) -+ return -EINVAL; -+ -+ mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN; -+ switch (payload.flags & MESH_FLAGS_AE) { -+ case MESH_FLAGS_AE_A4: -+ memcpy(&payload.eth.h_source, mesh_addr, ETH_ALEN); -+ break; -+ case MESH_FLAGS_AE_A5_A6: -+ memcpy(&payload.eth, mesh_addr, 2 * ETH_ALEN); -+ break; -+ default: -+ break; -+ } -+ -+ pskb_pull(skb, hdrlen - sizeof(payload.eth)); -+ memcpy(skb->data, &payload.eth, sizeof(payload.eth)); -+ -+ return 0; -+} -+EXPORT_SYMBOL(ieee80211_strip_8023_mesh_hdr); - - int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr, - const u8 *addr, enum nl80211_iftype iftype, -@@ -568,7 +611,6 @@ int ieee80211_data_to_8023_exthdr(struct - } payload; - struct ethhdr tmp; - u16 hdrlen; -- u8 mesh_flags = 0; - - if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) - return -1; -@@ -589,12 +631,6 @@ int ieee80211_data_to_8023_exthdr(struct - memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); - memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); - -- if (iftype == NL80211_IFTYPE_MESH_POINT && -- skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) -- return -1; -- -- mesh_flags &= MESH_FLAGS_AE; -- - switch (hdr->frame_control & - cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { - case cpu_to_le16(IEEE80211_FCTL_TODS): -@@ -608,17 +644,6 @@ int ieee80211_data_to_8023_exthdr(struct - iftype != NL80211_IFTYPE_AP_VLAN && - iftype != NL80211_IFTYPE_STATION)) - return -1; -- if (iftype == NL80211_IFTYPE_MESH_POINT) { -- if (mesh_flags == MESH_FLAGS_AE_A4) -- return -1; -- if (mesh_flags == MESH_FLAGS_AE_A5_A6 && -- skb_copy_bits(skb, hdrlen + -- offsetof(struct ieee80211s_hdr, eaddr1), -- tmp.h_dest, 2 * ETH_ALEN) < 0) -- return -1; -- -- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -- } - break; - case cpu_to_le16(IEEE80211_FCTL_FROMDS): - if ((iftype != NL80211_IFTYPE_STATION && -@@ -627,16 +652,6 @@ int ieee80211_data_to_8023_exthdr(struct - (is_multicast_ether_addr(tmp.h_dest) && - ether_addr_equal(tmp.h_source, addr))) - return -1; -- if (iftype == NL80211_IFTYPE_MESH_POINT) { -- if (mesh_flags == MESH_FLAGS_AE_A5_A6) -- return -1; -- if (mesh_flags == MESH_FLAGS_AE_A4 && -- skb_copy_bits(skb, hdrlen + -- offsetof(struct ieee80211s_hdr, eaddr1), -- tmp.h_source, ETH_ALEN) < 0) -- return -1; -- hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -- } - break; - case cpu_to_le16(0): - if (iftype != NL80211_IFTYPE_ADHOC && -@@ -646,7 +661,7 @@ int ieee80211_data_to_8023_exthdr(struct - break; - } - -- if (likely(!is_amsdu && -+ if (likely(!is_amsdu && iftype != NL80211_IFTYPE_MESH_POINT && - skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && - ieee80211_get_8023_tunnel_proto(&payload, &tmp.h_proto))) { - /* remove RFC1042 or Bridge-Tunnel encapsulation */ -@@ -722,7 +737,8 @@ __ieee80211_amsdu_copy_frag(struct sk_bu - - static struct sk_buff * - __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, -- int offset, int len, bool reuse_frag) -+ int offset, int len, bool reuse_frag, -+ int min_len) - { - struct sk_buff *frame; - int cur_len = len; -@@ -736,7 +752,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s - * in the stack later. - */ - if (reuse_frag) -- cur_len = min_t(int, len, 32); -+ cur_len = min_t(int, len, min_len); - - /* - * Allocate and reserve two bytes more for payload -@@ -746,6 +762,7 @@ __ieee80211_amsdu_copy(struct sk_buff *s - if (!frame) - return NULL; - -+ frame->priority = skb->priority; - skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); - skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len); - -@@ -762,23 +779,37 @@ __ieee80211_amsdu_copy(struct sk_buff *s - void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, - const u8 *addr, enum nl80211_iftype iftype, - const unsigned int extra_headroom, -- const u8 *check_da, const u8 *check_sa) -+ const u8 *check_da, const u8 *check_sa, -+ bool mesh_control) - { - unsigned int hlen = ALIGN(extra_headroom, 4); - struct sk_buff *frame = NULL; - int offset = 0, remaining; -- struct ethhdr eth; -+ struct { -+ struct ethhdr eth; -+ uint8_t flags; -+ } hdr; - bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); - bool reuse_skb = false; - bool last = false; -+ int copy_len = sizeof(hdr.eth); -+ -+ if (iftype == NL80211_IFTYPE_MESH_POINT) -+ copy_len = sizeof(hdr); - - while (!last) { - unsigned int subframe_len; -- int len; -+ int len, mesh_len = 0; - u8 padding; - -- skb_copy_bits(skb, offset, ð, sizeof(eth)); -- len = ntohs(eth.h_proto); -+ skb_copy_bits(skb, offset, &hdr, copy_len); -+ if (iftype == NL80211_IFTYPE_MESH_POINT) -+ mesh_len = __ieee80211_get_mesh_hdrlen(hdr.flags); -+ if (mesh_control) -+ len = le16_to_cpu(*(__le16 *)&hdr.eth.h_proto) + mesh_len; -+ else -+ len = ntohs(hdr.eth.h_proto); -+ - subframe_len = sizeof(struct ethhdr) + len; - padding = (4 - subframe_len) & 0x3; - -@@ -787,16 +818,16 @@ void ieee80211_amsdu_to_8023s(struct sk_ - if (subframe_len > remaining) - goto purge; - /* mitigate A-MSDU aggregation injection attacks */ -- if (ether_addr_equal(eth.h_dest, rfc1042_header)) -+ if (ether_addr_equal(hdr.eth.h_dest, rfc1042_header)) - goto purge; - - offset += sizeof(struct ethhdr); - last = remaining <= subframe_len + padding; - - /* FIXME: should we really accept multicast DA? */ -- if ((check_da && !is_multicast_ether_addr(eth.h_dest) && -- !ether_addr_equal(check_da, eth.h_dest)) || -- (check_sa && !ether_addr_equal(check_sa, eth.h_source))) { -+ if ((check_da && !is_multicast_ether_addr(hdr.eth.h_dest) && -+ !ether_addr_equal(check_da, hdr.eth.h_dest)) || -+ (check_sa && !ether_addr_equal(check_sa, hdr.eth.h_source))) { - offset += len + padding; - continue; - } -@@ -808,7 +839,7 @@ void ieee80211_amsdu_to_8023s(struct sk_ - reuse_skb = true; - } else { - frame = __ieee80211_amsdu_copy(skb, hlen, offset, len, -- reuse_frag); -+ reuse_frag, 32 + mesh_len); - if (!frame) - goto purge; - -@@ -819,10 +850,11 @@ void ieee80211_amsdu_to_8023s(struct sk_ - frame->dev = skb->dev; - frame->priority = skb->priority; - -- if (likely(ieee80211_get_8023_tunnel_proto(frame->data, ð.h_proto))) -+ if (likely(iftype != NL80211_IFTYPE_MESH_POINT && -+ ieee80211_get_8023_tunnel_proto(frame->data, &hdr.eth.h_proto))) - skb_pull(frame, ETH_ALEN + 2); - -- memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); -+ memcpy(skb_push(frame, sizeof(hdr.eth)), &hdr.eth, sizeof(hdr.eth)); - __skb_queue_tail(list, frame); - } - diff --git a/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch b/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch deleted file mode 100644 index 6dc98ae16a..0000000000 --- a/package/kernel/mac80211/patches/subsys/316-v6.3-wifi-mac80211-add-a-workaround-for-receiving-non-sta.patch +++ /dev/null @@ -1,145 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Fri, 9 Dec 2022 21:15:04 +0100 -Subject: [PATCH] wifi: mac80211: add a workaround for receiving - non-standard mesh A-MSDU - -At least ath10k and ath11k supported hardware (maybe more) does not implement -mesh A-MSDU aggregation in a standard compliant way. -802.11-2020 9.3.2.2.2 declares that the Mesh Control field is part of the -A-MSDU header. As such, its length must not be included in the subframe -length field. -Hardware affected by this bug treats the mesh control field as part of the -MSDU data and sets the length accordingly. -In order to avoid packet loss, keep track of which stations are affected -by this and take it into account when converting A-MSDU to 802.3 + mesh control -packets. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -6194,6 +6194,19 @@ static inline int ieee80211_data_to_8023 - } - - /** -+ * ieee80211_is_valid_amsdu - check if subframe lengths of an A-MSDU are valid -+ * -+ * This is used to detect non-standard A-MSDU frames, e.g. the ones generated -+ * by ath10k and ath11k, where the subframe length includes the length of the -+ * mesh control field. -+ * -+ * @skb: The input A-MSDU frame without any headers. -+ * @mesh_hdr: use standard compliant mesh A-MSDU subframe header -+ * Returns: true if subframe header lengths are valid for the @mesh_hdr mode -+ */ -+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr); -+ -+/** - * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame - * - * Decode an IEEE 802.11 A-MSDU and convert it to a list of 802.3 frames. ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2899,7 +2899,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - static ieee80211_rx_result res; - struct ethhdr ethhdr; - const u8 *check_da = ethhdr.h_dest, *check_sa = ethhdr.h_source; -- bool mesh = false; - - if (unlikely(ieee80211_has_a4(hdr->frame_control))) { - check_da = NULL; -@@ -2917,7 +2916,6 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - case NL80211_IFTYPE_MESH_POINT: - check_sa = NULL; - check_da = NULL; -- mesh = true; - break; - default: - break; -@@ -2932,10 +2930,21 @@ __ieee80211_rx_h_amsdu(struct ieee80211_ - data_offset, true)) - return RX_DROP_UNUSABLE; - -+ if (rx->sta && rx->sta->amsdu_mesh_control < 0) { -+ bool valid_std = ieee80211_is_valid_amsdu(skb, true); -+ bool valid_nonstd = ieee80211_is_valid_amsdu(skb, false); -+ -+ if (valid_std && !valid_nonstd) -+ rx->sta->amsdu_mesh_control = 1; -+ else if (valid_nonstd && !valid_std) -+ rx->sta->amsdu_mesh_control = 0; -+ } -+ - ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, - rx->sdata->vif.type, - rx->local->hw.extra_tx_headroom, -- check_da, check_sa, mesh); -+ check_da, check_sa, -+ rx->sta->amsdu_mesh_control); - - while (!skb_queue_empty(&frame_list)) { - rx->skb = __skb_dequeue(&frame_list); ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -591,6 +591,9 @@ __sta_info_alloc(struct ieee80211_sub_if - - sta->sta_state = IEEE80211_STA_NONE; - -+ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) -+ sta->amsdu_mesh_control = -1; -+ - /* Mark TID as unreserved */ - sta->reserved_tid = IEEE80211_TID_UNRESERVED; - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -702,6 +702,7 @@ struct sta_info { - struct codel_params cparams; - - u8 reserved_tid; -+ s8 amsdu_mesh_control; - - struct cfg80211_chan_def tdls_chandef; - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -776,6 +776,38 @@ __ieee80211_amsdu_copy(struct sk_buff *s - return frame; - } - -+bool ieee80211_is_valid_amsdu(struct sk_buff *skb, bool mesh_hdr) -+{ -+ int offset = 0, remaining, subframe_len, padding; -+ -+ for (offset = 0; offset < skb->len; offset += subframe_len + padding) { -+ struct { -+ __be16 len; -+ u8 mesh_flags; -+ } hdr; -+ u16 len; -+ -+ if (skb_copy_bits(skb, offset + 2 * ETH_ALEN, &hdr, sizeof(hdr)) < 0) -+ return false; -+ -+ if (mesh_hdr) -+ len = le16_to_cpu(*(__le16 *)&hdr.len) + -+ __ieee80211_get_mesh_hdrlen(hdr.mesh_flags); -+ else -+ len = ntohs(hdr.len); -+ -+ subframe_len = sizeof(struct ethhdr) + len; -+ padding = (4 - subframe_len) & 0x3; -+ remaining = skb->len - offset; -+ -+ if (subframe_len > remaining) -+ return false; -+ } -+ -+ return true; -+} -+EXPORT_SYMBOL(ieee80211_is_valid_amsdu); -+ - void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, - const u8 *addr, enum nl80211_iftype iftype, - const unsigned int extra_headroom, diff --git a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch b/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch deleted file mode 100644 index 7d01ffdfff..0000000000 --- a/package/kernel/mac80211/patches/subsys/318-wifi-mac80211-fix-race-in-mesh-sequence-number-assig.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Wed, 15 Feb 2023 15:21:37 +0100 -Subject: [PATCH] wifi: mac80211: fix race in mesh sequence number - assignment - -Since the sequence number is shared across different tx queues, it needs -to be atomic in order to avoid accidental duplicate assignment - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -696,7 +696,7 @@ struct ieee80211_if_mesh { - struct mesh_stats mshstats; - struct mesh_config mshcfg; - atomic_t estab_plinks; -- u32 mesh_seqnum; -+ atomic_t mesh_seqnum; - bool accepting_plinks; - int num_gates; - struct beacon_data __rcu *beacon; ---- a/net/mac80211/mesh.c -+++ b/net/mac80211/mesh.c -@@ -752,10 +752,8 @@ unsigned int ieee80211_new_mesh_header(s - - meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; - -- /* FIXME: racy -- TX on multiple queues can be concurrent */ -- put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); -- sdata->u.mesh.mesh_seqnum++; -- -+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), -+ &meshhdr->seqnum); - if (addr4or5 && !addr6) { - meshhdr->flags |= MESH_FLAGS_AE_A4; - memcpy(meshhdr->eaddr1, addr4or5, ETH_ALEN); diff --git a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch b/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch deleted file mode 100644 index 968d2885f2..0000000000 --- a/package/kernel/mac80211/patches/subsys/319-wifi-mac80211-mesh-fast-xmit-support.patch +++ /dev/null @@ -1,850 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 26 Feb 2023 13:53:08 +0100 -Subject: [PATCH] wifi: mac80211: mesh fast xmit support - -Previously, fast xmit only worked on interface types where initially a -sta lookup is performed, and a cached header can be attached to the sta, -requiring only some fields to be updated at runtime. - -This technique is not directly applicable for a mesh device type due -to the dynamic nature of the topology and protocol. There are more -addresses that need to be filled, and there is an extra header with a -dynamic length based on the addressing mode. - -Change the code to cache entries contain a copy of the mesh subframe header + -bridge tunnel header, as well as an embedded struct ieee80211_fast_tx, which -contains the information for building the 802.11 header. - -Add a mesh specific early fast xmit call, which looks up a cached entry and -adds only the mesh subframe header, before passing it over to the generic -fast xmit code. - -To ensure the changes in network are reflected in these cached headers, -flush affected cached entries on path changes, as well as other conditions -that currently trigger a fast xmit check in other modes (key changes etc.) - -This code is loosely based on a previous implementation by: -Sriram R <quic_srirrama@quicinc.com> - -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -37,6 +37,7 @@ - extern const struct cfg80211_ops mac80211_config_ops; - - struct ieee80211_local; -+struct ieee80211_mesh_fast_tx; - - /* Maximum number of broadcast/multicast frames to buffer when some of the - * associated stations are using power saving. */ -@@ -656,6 +657,19 @@ struct mesh_table { - atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ - }; - -+/** -+ * struct mesh_tx_cache - mesh fast xmit header cache -+ * -+ * @rht: hash table containing struct ieee80211_mesh_fast_tx, using skb DA as key -+ * @walk_head: linked list containing all ieee80211_mesh_fast_tx objects -+ * @walk_lock: lock protecting walk_head and rht -+ */ -+struct mesh_tx_cache { -+ struct rhashtable rht; -+ struct hlist_head walk_head; -+ spinlock_t walk_lock; -+}; -+ - struct ieee80211_if_mesh { - struct timer_list housekeeping_timer; - struct timer_list mesh_path_timer; -@@ -734,6 +748,7 @@ struct ieee80211_if_mesh { - struct mesh_table mpp_paths; /* Store paths for MPP&MAP */ - int mesh_paths_generation; - int mpp_paths_generation; -+ struct mesh_tx_cache tx_cache; - }; - - #ifdef CPTCFG_MAC80211_MESH -@@ -2002,6 +2017,11 @@ int ieee80211_tx_control_port(struct wip - int link_id, u64 *cookie); - int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, - const u8 *buf, size_t len); -+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, -+ struct ieee80211_fast_tx *fast_tx, -+ struct sk_buff *skb, bool ampdu, -+ const u8 *da, const u8 *sa); - - /* HT */ - void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/mesh.c -+++ b/net/mac80211/mesh.c -@@ -10,6 +10,7 @@ - #include <asm/unaligned.h> - #include "ieee80211_i.h" - #include "mesh.h" -+#include "wme.h" - #include "driver-ops.h" - - static int mesh_allocated; -@@ -698,6 +699,95 @@ ieee80211_mesh_update_bss_params(struct - __le32_to_cpu(he_oper->he_oper_params); - } - -+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, u32 ctrl_flags) -+{ -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+ struct ieee80211_mesh_fast_tx *entry; -+ struct ieee80211s_hdr *meshhdr; -+ u8 sa[ETH_ALEN] __aligned(2); -+ struct tid_ampdu_tx *tid_tx; -+ struct sta_info *sta; -+ bool copy_sa = false; -+ u16 ethertype; -+ u8 tid; -+ -+ if (ctrl_flags & IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP) -+ return false; -+ -+ if (ifmsh->mshcfg.dot11MeshNolearn) -+ return false; -+ -+ /* Add support for these cases later */ -+ if (ifmsh->ps_peers_light_sleep || ifmsh->ps_peers_deep_sleep) -+ return false; -+ -+ if (is_multicast_ether_addr(skb->data)) -+ return false; -+ -+ ethertype = (skb->data[12] << 8) | skb->data[13]; -+ if (ethertype < ETH_P_802_3_MIN) -+ return false; -+ -+ if (skb->sk && skb_shinfo(skb)->tx_flags & SKBTX_WIFI_STATUS) -+ return false; -+ -+ if (skb->ip_summed == CHECKSUM_PARTIAL) { -+ skb_set_transport_header(skb, skb_checksum_start_offset(skb)); -+ if (skb_checksum_help(skb)) -+ return false; -+ } -+ -+ entry = mesh_fast_tx_get(sdata, skb->data); -+ if (!entry) -+ return false; -+ -+ if (skb_headroom(skb) < entry->hdrlen + entry->fast_tx.hdr_len) -+ return false; -+ -+ sta = rcu_dereference(entry->mpath->next_hop); -+ if (!sta) -+ return false; -+ -+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -+ if (tid_tx) { -+ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) -+ return false; -+ if (tid_tx->timeout) -+ tid_tx->last_tx = jiffies; -+ } -+ -+ skb = skb_share_check(skb, GFP_ATOMIC); -+ if (!skb) -+ return true; -+ -+ skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); -+ -+ meshhdr = (struct ieee80211s_hdr *)entry->hdr; -+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { -+ /* preserve SA from eth header for 6-addr frames */ -+ ether_addr_copy(sa, skb->data + ETH_ALEN); -+ copy_sa = true; -+ } -+ -+ memcpy(skb_push(skb, entry->hdrlen - 2 * ETH_ALEN), entry->hdr, -+ entry->hdrlen); -+ -+ meshhdr = (struct ieee80211s_hdr *)skb->data; -+ put_unaligned_le32(atomic_inc_return(&sdata->u.mesh.mesh_seqnum), -+ &meshhdr->seqnum); -+ meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; -+ if (copy_sa) -+ ether_addr_copy(meshhdr->eaddr2, sa); -+ -+ skb_push(skb, 2 * ETH_ALEN); -+ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, -+ entry->mpath->dst, sdata->vif.addr); -+ -+ return true; -+} -+ - /** - * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame - * @hdr: 802.11 frame header -@@ -780,6 +870,8 @@ static void ieee80211_mesh_housekeeping( - changed = mesh_accept_plinks_update(sdata); - ieee80211_mbss_info_change_notify(sdata, changed); - -+ mesh_fast_tx_gc(sdata); -+ - mod_timer(&ifmsh->housekeeping_timer, - round_jiffies(jiffies + - IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); ---- a/net/mac80211/mesh.h -+++ b/net/mac80211/mesh.h -@@ -122,11 +122,41 @@ struct mesh_path { - u8 rann_snd_addr[ETH_ALEN]; - u32 rann_metric; - unsigned long last_preq_to_root; -+ unsigned long fast_tx_check; - bool is_root; - bool is_gate; - u32 path_change_count; - }; - -+#define MESH_FAST_TX_CACHE_MAX_SIZE 512 -+#define MESH_FAST_TX_CACHE_THRESHOLD_SIZE 384 -+#define MESH_FAST_TX_CACHE_TIMEOUT 8000 /* msecs */ -+ -+/** -+ * struct ieee80211_mesh_fast_tx - cached mesh fast tx entry -+ * @rhash: rhashtable pointer -+ * @addr_key: The Ethernet DA which is the key for this entry -+ * @fast_tx: base fast_tx data -+ * @hdr: cached mesh and rfc1042 headers -+ * @hdrlen: length of mesh + rfc1042 -+ * @walk_list: list containing all the fast tx entries -+ * @mpath: mesh path corresponding to the Mesh DA -+ * @mppath: MPP entry corresponding to this DA -+ * @timestamp: Last used time of this entry -+ */ -+struct ieee80211_mesh_fast_tx { -+ struct rhash_head rhash; -+ u8 addr_key[ETH_ALEN] __aligned(2); -+ -+ struct ieee80211_fast_tx fast_tx; -+ u8 hdr[sizeof(struct ieee80211s_hdr) + sizeof(rfc1042_header)]; -+ u16 hdrlen; -+ -+ struct mesh_path *mpath, *mppath; -+ struct hlist_node walk_list; -+ unsigned long timestamp; -+}; -+ - /* Recent multicast cache */ - /* RMC_BUCKETS must be a power of 2, maximum 256 */ - #define RMC_BUCKETS 256 -@@ -298,6 +328,20 @@ void mesh_path_discard_frame(struct ieee - void mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata); - - bool mesh_action_is_path_sel(struct ieee80211_mgmt *mgmt); -+struct ieee80211_mesh_fast_tx * -+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr); -+bool ieee80211_mesh_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, u32 ctrl_flags); -+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, struct mesh_path *mpath); -+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata); -+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, -+ const u8 *addr); -+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath); -+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta); -+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, -+ struct mesh_path *mpath, const u8 *addr); - - #ifdef CPTCFG_MAC80211_MESH - static inline ---- a/net/mac80211/mesh_hwmp.c -+++ b/net/mac80211/mesh_hwmp.c -@@ -394,6 +394,7 @@ static u32 hwmp_route_info_get(struct ie - u32 orig_sn, orig_metric; - unsigned long orig_lifetime, exp_time; - u32 last_hop_metric, new_metric; -+ bool flush_mpath = false; - bool process = true; - u8 hopcount; - -@@ -491,8 +492,10 @@ static u32 hwmp_route_info_get(struct ie - } - - if (fresh_info) { -- if (rcu_access_pointer(mpath->next_hop) != sta) -+ if (rcu_access_pointer(mpath->next_hop) != sta) { - mpath->path_change_count++; -+ flush_mpath = true; -+ } - mesh_path_assign_nexthop(mpath, sta); - mpath->flags |= MESH_PATH_SN_VALID; - mpath->metric = new_metric; -@@ -502,6 +505,8 @@ static u32 hwmp_route_info_get(struct ie - mpath->hop_count = hopcount; - mesh_path_activate(mpath); - spin_unlock_bh(&mpath->state_lock); -+ if (flush_mpath) -+ mesh_fast_tx_flush_mpath(mpath); - ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); - /* init it at a low value - 0 start is tricky */ - ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); -@@ -539,8 +544,10 @@ static u32 hwmp_route_info_get(struct ie - } - - if (fresh_info) { -- if (rcu_access_pointer(mpath->next_hop) != sta) -+ if (rcu_access_pointer(mpath->next_hop) != sta) { - mpath->path_change_count++; -+ flush_mpath = true; -+ } - mesh_path_assign_nexthop(mpath, sta); - mpath->metric = last_hop_metric; - mpath->exp_time = time_after(mpath->exp_time, exp_time) -@@ -548,6 +555,8 @@ static u32 hwmp_route_info_get(struct ie - mpath->hop_count = 1; - mesh_path_activate(mpath); - spin_unlock_bh(&mpath->state_lock); -+ if (flush_mpath) -+ mesh_fast_tx_flush_mpath(mpath); - ewma_mesh_fail_avg_init(&sta->mesh->fail_avg); - /* init it at a low value - 0 start is tricky */ - ewma_mesh_fail_avg_add(&sta->mesh->fail_avg, 1); -@@ -1215,6 +1224,20 @@ static int mesh_nexthop_lookup_nolearn(s - return 0; - } - -+void mesh_path_refresh(struct ieee80211_sub_if_data *sdata, -+ struct mesh_path *mpath, const u8 *addr) -+{ -+ if (mpath->flags & (MESH_PATH_REQ_QUEUED | MESH_PATH_FIXED | -+ MESH_PATH_RESOLVING)) -+ return; -+ -+ if (time_after(jiffies, -+ mpath->exp_time - -+ msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && -+ (!addr || ether_addr_equal(sdata->vif.addr, addr))) -+ mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); -+} -+ - /** - * mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling - * this function is considered "using" the associated mpath, so preempt a path -@@ -1242,19 +1265,15 @@ int mesh_nexthop_lookup(struct ieee80211 - if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) - return -ENOENT; - -- if (time_after(jiffies, -- mpath->exp_time - -- msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && -- ether_addr_equal(sdata->vif.addr, hdr->addr4) && -- !(mpath->flags & MESH_PATH_RESOLVING) && -- !(mpath->flags & MESH_PATH_FIXED)) -- mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); -+ mesh_path_refresh(sdata, mpath, hdr->addr4); - - next_hop = rcu_dereference(mpath->next_hop); - if (next_hop) { - memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN); - memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); - ieee80211_mps_set_frame_flags(sdata, next_hop, hdr); -+ if (ieee80211_hw_check(&sdata->local->hw, SUPPORT_FAST_XMIT)) -+ mesh_fast_tx_cache(sdata, skb, mpath); - return 0; - } - ---- a/net/mac80211/mesh_pathtbl.c -+++ b/net/mac80211/mesh_pathtbl.c -@@ -14,6 +14,7 @@ - #include "wme.h" - #include "ieee80211_i.h" - #include "mesh.h" -+#include <linux/rhashtable.h> - - static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); - -@@ -32,6 +33,41 @@ static const struct rhashtable_params me - .hashfn = mesh_table_hash, - }; - -+static const struct rhashtable_params fast_tx_rht_params = { -+ .nelem_hint = 10, -+ .automatic_shrinking = true, -+ .key_len = ETH_ALEN, -+ .key_offset = offsetof(struct ieee80211_mesh_fast_tx, addr_key), -+ .head_offset = offsetof(struct ieee80211_mesh_fast_tx, rhash), -+ .hashfn = mesh_table_hash, -+}; -+ -+static void __mesh_fast_tx_entry_free(void *ptr, void *tblptr) -+{ -+ struct ieee80211_mesh_fast_tx *entry = ptr; -+ -+ kfree_rcu(entry, fast_tx.rcu_head); -+} -+ -+static void mesh_fast_tx_deinit(struct ieee80211_sub_if_data *sdata) -+{ -+ struct mesh_tx_cache *cache; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ rhashtable_free_and_destroy(&cache->rht, -+ __mesh_fast_tx_entry_free, NULL); -+} -+ -+static void mesh_fast_tx_init(struct ieee80211_sub_if_data *sdata) -+{ -+ struct mesh_tx_cache *cache; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ rhashtable_init(&cache->rht, &fast_tx_rht_params); -+ INIT_HLIST_HEAD(&cache->walk_head); -+ spin_lock_init(&cache->walk_lock); -+} -+ - static inline bool mpath_expired(struct mesh_path *mpath) - { - return (mpath->flags & MESH_PATH_ACTIVE) && -@@ -381,6 +417,243 @@ struct mesh_path *mesh_path_new(struct i - return new_mpath; - } - -+static void mesh_fast_tx_entry_free(struct mesh_tx_cache *cache, -+ struct ieee80211_mesh_fast_tx *entry) -+{ -+ hlist_del_rcu(&entry->walk_list); -+ rhashtable_remove_fast(&cache->rht, &entry->rhash, fast_tx_rht_params); -+ kfree_rcu(entry, fast_tx.rcu_head); -+} -+ -+struct ieee80211_mesh_fast_tx * -+mesh_fast_tx_get(struct ieee80211_sub_if_data *sdata, const u8 *addr) -+{ -+ struct ieee80211_mesh_fast_tx *entry; -+ struct mesh_tx_cache *cache; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -+ if (!entry) -+ return NULL; -+ -+ if (!(entry->mpath->flags & MESH_PATH_ACTIVE) || -+ mpath_expired(entry->mpath)) { -+ spin_lock_bh(&cache->walk_lock); -+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -+ if (entry) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+ return NULL; -+ } -+ -+ mesh_path_refresh(sdata, entry->mpath, NULL); -+ if (entry->mppath) -+ entry->mppath->exp_time = jiffies; -+ entry->timestamp = jiffies; -+ -+ return entry; -+} -+ -+void mesh_fast_tx_cache(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, struct mesh_path *mpath) -+{ -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_mesh_fast_tx *entry, *prev; -+ struct ieee80211_mesh_fast_tx build = {}; -+ struct ieee80211s_hdr *meshhdr; -+ struct mesh_tx_cache *cache; -+ struct ieee80211_key *key; -+ struct mesh_path *mppath; -+ struct sta_info *sta; -+ u8 *qc; -+ -+ if (sdata->noack_map || -+ !ieee80211_is_data_qos(hdr->frame_control)) -+ return; -+ -+ build.fast_tx.hdr_len = ieee80211_hdrlen(hdr->frame_control); -+ meshhdr = (struct ieee80211s_hdr *)(skb->data + build.fast_tx.hdr_len); -+ build.hdrlen = ieee80211_get_mesh_hdrlen(meshhdr); -+ -+ cache = &sdata->u.mesh.tx_cache; -+ if (atomic_read(&cache->rht.nelems) >= MESH_FAST_TX_CACHE_MAX_SIZE) -+ return; -+ -+ sta = rcu_dereference(mpath->next_hop); -+ if (!sta) -+ return; -+ -+ if ((meshhdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) { -+ /* This is required to keep the mppath alive */ -+ mppath = mpp_path_lookup(sdata, meshhdr->eaddr1); -+ if (!mppath) -+ return; -+ build.mppath = mppath; -+ } else if (ieee80211_has_a4(hdr->frame_control)) { -+ mppath = mpath; -+ } else { -+ return; -+ } -+ -+ /* rate limit, in case fast xmit can't be enabled */ -+ if (mppath->fast_tx_check == jiffies) -+ return; -+ -+ mppath->fast_tx_check = jiffies; -+ -+ /* -+ * Same use of the sta lock as in ieee80211_check_fast_xmit, in order -+ * to protect against concurrent sta key updates. -+ */ -+ spin_lock_bh(&sta->lock); -+ key = rcu_access_pointer(sta->ptk[sta->ptk_idx]); -+ if (!key) -+ key = rcu_access_pointer(sdata->default_unicast_key); -+ build.fast_tx.key = key; -+ -+ if (key) { -+ bool gen_iv, iv_spc; -+ -+ gen_iv = key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV; -+ iv_spc = key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE; -+ -+ if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) || -+ (key->flags & KEY_FLAG_TAINTED)) -+ goto unlock_sta; -+ -+ switch (key->conf.cipher) { -+ case WLAN_CIPHER_SUITE_CCMP: -+ case WLAN_CIPHER_SUITE_CCMP_256: -+ if (gen_iv) -+ build.fast_tx.pn_offs = build.fast_tx.hdr_len; -+ if (gen_iv || iv_spc) -+ build.fast_tx.hdr_len += IEEE80211_CCMP_HDR_LEN; -+ break; -+ case WLAN_CIPHER_SUITE_GCMP: -+ case WLAN_CIPHER_SUITE_GCMP_256: -+ if (gen_iv) -+ build.fast_tx.pn_offs = build.fast_tx.hdr_len; -+ if (gen_iv || iv_spc) -+ build.fast_tx.hdr_len += IEEE80211_GCMP_HDR_LEN; -+ break; -+ default: -+ goto unlock_sta; -+ } -+ } -+ -+ memcpy(build.addr_key, mppath->dst, ETH_ALEN); -+ build.timestamp = jiffies; -+ build.fast_tx.band = info->band; -+ build.fast_tx.da_offs = offsetof(struct ieee80211_hdr, addr3); -+ build.fast_tx.sa_offs = offsetof(struct ieee80211_hdr, addr4); -+ build.mpath = mpath; -+ memcpy(build.hdr, meshhdr, build.hdrlen); -+ memcpy(build.hdr + build.hdrlen, rfc1042_header, sizeof(rfc1042_header)); -+ build.hdrlen += sizeof(rfc1042_header); -+ memcpy(build.fast_tx.hdr, hdr, build.fast_tx.hdr_len); -+ -+ hdr = (struct ieee80211_hdr *)build.fast_tx.hdr; -+ if (build.fast_tx.key) -+ hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -+ -+ qc = ieee80211_get_qos_ctl(hdr); -+ qc[1] |= IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT >> 8; -+ -+ entry = kmemdup(&build, sizeof(build), GFP_ATOMIC); -+ if (!entry) -+ goto unlock_sta; -+ -+ spin_lock(&cache->walk_lock); -+ prev = rhashtable_lookup_get_insert_fast(&cache->rht, -+ &entry->rhash, -+ fast_tx_rht_params); -+ if (unlikely(IS_ERR(prev))) { -+ kfree(entry); -+ goto unlock_cache; -+ } -+ -+ /* -+ * replace any previous entry in the hash table, in case we're -+ * replacing it with a different type (e.g. mpath -> mpp) -+ */ -+ if (unlikely(prev)) { -+ rhashtable_replace_fast(&cache->rht, &prev->rhash, -+ &entry->rhash, fast_tx_rht_params); -+ hlist_del_rcu(&prev->walk_list); -+ kfree_rcu(prev, fast_tx.rcu_head); -+ } -+ -+ hlist_add_head(&entry->walk_list, &cache->walk_head); -+ -+unlock_cache: -+ spin_unlock(&cache->walk_lock); -+unlock_sta: -+ spin_unlock_bh(&sta->lock); -+} -+ -+void mesh_fast_tx_gc(struct ieee80211_sub_if_data *sdata) -+{ -+ unsigned long timeout = msecs_to_jiffies(MESH_FAST_TX_CACHE_TIMEOUT); -+ struct mesh_tx_cache *cache; -+ struct ieee80211_mesh_fast_tx *entry; -+ struct hlist_node *n; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ if (atomic_read(&cache->rht.nelems) < MESH_FAST_TX_CACHE_THRESHOLD_SIZE) -+ return; -+ -+ spin_lock_bh(&cache->walk_lock); -+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -+ if (!time_is_after_jiffies(entry->timestamp + timeout)) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+} -+ -+void mesh_fast_tx_flush_mpath(struct mesh_path *mpath) -+{ -+ struct ieee80211_sub_if_data *sdata = mpath->sdata; -+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -+ struct ieee80211_mesh_fast_tx *entry; -+ struct hlist_node *n; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ spin_lock_bh(&cache->walk_lock); -+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -+ if (entry->mpath == mpath) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+} -+ -+void mesh_fast_tx_flush_sta(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta) -+{ -+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -+ struct ieee80211_mesh_fast_tx *entry; -+ struct hlist_node *n; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ spin_lock_bh(&cache->walk_lock); -+ hlist_for_each_entry_safe(entry, n, &cache->walk_head, walk_list) -+ if (rcu_access_pointer(entry->mpath->next_hop) == sta) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+} -+ -+void mesh_fast_tx_flush_addr(struct ieee80211_sub_if_data *sdata, -+ const u8 *addr) -+{ -+ struct mesh_tx_cache *cache = &sdata->u.mesh.tx_cache; -+ struct ieee80211_mesh_fast_tx *entry; -+ -+ cache = &sdata->u.mesh.tx_cache; -+ spin_lock_bh(&cache->walk_lock); -+ entry = rhashtable_lookup(&cache->rht, addr, fast_tx_rht_params); -+ if (entry) -+ mesh_fast_tx_entry_free(cache, entry); -+ spin_unlock_bh(&cache->walk_lock); -+} -+ - /** - * mesh_path_add - allocate and add a new path to the mesh path table - * @dst: destination address of the path (ETH_ALEN length) -@@ -464,6 +737,8 @@ int mpp_path_add(struct ieee80211_sub_if - - if (ret) - kfree(new_mpath); -+ else -+ mesh_fast_tx_flush_addr(sdata, dst); - - sdata->u.mesh.mpp_paths_generation++; - return ret; -@@ -523,6 +798,10 @@ static void __mesh_path_del(struct mesh_ - { - hlist_del_rcu(&mpath->walk_list); - rhashtable_remove_fast(&tbl->rhead, &mpath->rhash, mesh_rht_params); -+ if (tbl == &mpath->sdata->u.mesh.mpp_paths) -+ mesh_fast_tx_flush_addr(mpath->sdata, mpath->dst); -+ else -+ mesh_fast_tx_flush_mpath(mpath); - mesh_path_free_rcu(tbl, mpath); - } - -@@ -747,6 +1026,7 @@ void mesh_path_fix_nexthop(struct mesh_p - mpath->exp_time = 0; - mpath->flags = MESH_PATH_FIXED | MESH_PATH_SN_VALID; - mesh_path_activate(mpath); -+ mesh_fast_tx_flush_mpath(mpath); - spin_unlock_bh(&mpath->state_lock); - ewma_mesh_fail_avg_init(&next_hop->mesh->fail_avg); - /* init it at a low value - 0 start is tricky */ -@@ -758,6 +1038,7 @@ void mesh_pathtbl_init(struct ieee80211_ - { - mesh_table_init(&sdata->u.mesh.mesh_paths); - mesh_table_init(&sdata->u.mesh.mpp_paths); -+ mesh_fast_tx_init(sdata); - } - - static -@@ -785,6 +1066,7 @@ void mesh_path_expire(struct ieee80211_s - - void mesh_pathtbl_unregister(struct ieee80211_sub_if_data *sdata) - { -+ mesh_fast_tx_deinit(sdata); - mesh_table_free(&sdata->u.mesh.mesh_paths); - mesh_table_free(&sdata->u.mesh.mpp_paths); - } ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2791,6 +2791,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ - if (mesh_hdr->flags & MESH_FLAGS_AE) { - struct mesh_path *mppath; - char *proxied_addr; -+ bool update = false; - - if (multicast) - proxied_addr = mesh_hdr->eaddr1; -@@ -2806,11 +2807,18 @@ ieee80211_rx_mesh_data(struct ieee80211_ - mpp_path_add(sdata, proxied_addr, eth->h_source); - } else { - spin_lock_bh(&mppath->state_lock); -- if (!ether_addr_equal(mppath->mpp, eth->h_source)) -+ if (!ether_addr_equal(mppath->mpp, eth->h_source)) { - memcpy(mppath->mpp, eth->h_source, ETH_ALEN); -+ update = true; -+ } - mppath->exp_time = jiffies; - spin_unlock_bh(&mppath->state_lock); - } -+ -+ /* flush fast xmit cache if the address path changed */ -+ if (update) -+ mesh_fast_tx_flush_addr(sdata, proxied_addr); -+ - rcu_read_unlock(); - } - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3022,6 +3022,9 @@ void ieee80211_check_fast_xmit(struct st - if (!ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT)) - return; - -+ if (ieee80211_vif_is_mesh(&sdata->vif)) -+ mesh_fast_tx_flush_sta(sdata, sta); -+ - /* Locking here protects both the pointer itself, and against concurrent - * invocations winning data access races to, e.g., the key pointer that - * is used. -@@ -3403,6 +3406,9 @@ static bool ieee80211_amsdu_aggregate(st - if (sdata->vif.offload_flags & IEEE80211_OFFLOAD_ENCAP_ENABLED) - return false; - -+ if (ieee80211_vif_is_mesh(&sdata->vif)) -+ return false; -+ - if (skb_is_gso(skb)) - return false; - -@@ -3635,10 +3641,11 @@ free: - return NULL; - } - --static void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -- struct sta_info *sta, -- struct ieee80211_fast_tx *fast_tx, -- struct sk_buff *skb, u8 tid, bool ampdu) -+void __ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, -+ struct ieee80211_fast_tx *fast_tx, -+ struct sk_buff *skb, bool ampdu, -+ const u8 *da, const u8 *sa) - { - struct ieee80211_local *local = sdata->local; - struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -@@ -3647,7 +3654,6 @@ static void __ieee80211_xmit_fast(struct - ieee80211_tx_result r; - int hw_headroom = sdata->local->hw.extra_tx_headroom; - int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); -- struct ethhdr eth; - - skb = skb_share_check(skb, GFP_ATOMIC); - if (unlikely(!skb)) -@@ -3667,11 +3673,10 @@ static void __ieee80211_xmit_fast(struct - ENCRYPT_NO))) - goto free; - -- memcpy(ð, skb->data, ETH_HLEN - 2); - hdr = skb_push(skb, extra_head); - memcpy(skb->data, fast_tx->hdr, fast_tx->hdr_len); -- memcpy(skb->data + fast_tx->da_offs, eth.h_dest, ETH_ALEN); -- memcpy(skb->data + fast_tx->sa_offs, eth.h_source, ETH_ALEN); -+ memcpy(skb->data + fast_tx->da_offs, da, ETH_ALEN); -+ memcpy(skb->data + fast_tx->sa_offs, sa, ETH_ALEN); - - info = IEEE80211_SKB_CB(skb); - memset(info, 0, sizeof(*info)); -@@ -3690,7 +3695,8 @@ static void __ieee80211_xmit_fast(struct - #endif - - if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -- tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ - *ieee80211_get_qos_ctl(hdr) = tid; - } - -@@ -3733,6 +3739,7 @@ static bool ieee80211_xmit_fast(struct i - struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; - struct tid_ampdu_tx *tid_tx = NULL; - struct sk_buff *next; -+ struct ethhdr eth; - u8 tid = IEEE80211_NUM_TIDS; - - /* control port protocol needs a lot of special handling */ -@@ -3758,6 +3765,8 @@ static bool ieee80211_xmit_fast(struct i - } - } - -+ memcpy(ð, skb->data, ETH_HLEN - 2); -+ - /* after this point (skb is modified) we cannot return false */ - skb = ieee80211_tx_skb_fixup(skb, ieee80211_sdata_netdev_features(sdata)); - if (!skb) -@@ -3765,7 +3774,8 @@ static bool ieee80211_xmit_fast(struct i - - skb_list_walk_safe(skb, skb, next) { - skb_mark_not_on_list(skb); -- __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid, tid_tx); -+ __ieee80211_xmit_fast(sdata, sta, fast_tx, skb, tid_tx, -+ eth.h_dest, eth.h_source); - } - - return true; -@@ -4252,8 +4262,15 @@ void __ieee80211_subif_start_xmit(struct - return; - } - -+ sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -+ - rcu_read_lock(); - -+ if (ieee80211_vif_is_mesh(&sdata->vif) && -+ ieee80211_hw_check(&local->hw, SUPPORT_FAST_XMIT) && -+ ieee80211_mesh_xmit_fast(sdata, skb, ctrl_flags)) -+ goto out; -+ - if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) - goto out_free; - -@@ -4263,8 +4280,6 @@ void __ieee80211_subif_start_xmit(struct - skb_set_queue_mapping(skb, ieee80211_select_queue(sdata, sta, skb)); - ieee80211_aggr_check(sdata, sta, skb); - -- sk_pacing_shift_update(skb->sk, sdata->local->hw.tx_sk_pacing_shift); -- - if (sta) { - struct ieee80211_fast_tx *fast_tx; - diff --git a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch b/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch deleted file mode 100644 index 28b1ff1106..0000000000 --- a/package/kernel/mac80211/patches/subsys/320-wifi-mac80211-use-mesh-header-cache-to-speed-up-mesh.patch +++ /dev/null @@ -1,132 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Thu, 16 Feb 2023 11:07:30 +0100 -Subject: [PATCH] wifi: mac80211: use mesh header cache to speed up mesh - forwarding - -Significantly reduces mesh forwarding path CPU usage and enables the -direct use of iTXQ. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2720,6 +2720,65 @@ ieee80211_deliver_skb(struct ieee80211_r - } - } - -+#ifdef CPTCFG_MAC80211_MESH -+static bool -+ieee80211_rx_mesh_fast_forward(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb, int hdrlen) -+{ -+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; -+ struct ieee80211_mesh_fast_tx *entry = NULL; -+ struct ieee80211s_hdr *mesh_hdr; -+ struct tid_ampdu_tx *tid_tx; -+ struct sta_info *sta; -+ struct ethhdr eth; -+ u8 tid; -+ -+ mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(eth)); -+ if ((mesh_hdr->flags & MESH_FLAGS_AE) == MESH_FLAGS_AE_A5_A6) -+ entry = mesh_fast_tx_get(sdata, mesh_hdr->eaddr1); -+ else if (!(mesh_hdr->flags & MESH_FLAGS_AE)) -+ entry = mesh_fast_tx_get(sdata, skb->data); -+ if (!entry) -+ return false; -+ -+ sta = rcu_dereference(entry->mpath->next_hop); -+ if (!sta) -+ return false; -+ -+ if (skb_linearize(skb)) -+ return false; -+ -+ tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -+ if (tid_tx) { -+ if (!test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) -+ return false; -+ -+ if (tid_tx->timeout) -+ tid_tx->last_tx = jiffies; -+ } -+ -+ ieee80211_aggr_check(sdata, sta, skb); -+ -+ if (ieee80211_get_8023_tunnel_proto(skb->data + hdrlen, -+ &skb->protocol)) -+ hdrlen += ETH_ALEN; -+ else -+ skb->protocol = htons(skb->len - hdrlen); -+ skb_set_network_header(skb, hdrlen + 2); -+ -+ skb->dev = sdata->dev; -+ memcpy(ð, skb->data, ETH_HLEN - 2); -+ skb_pull(skb, 2); -+ __ieee80211_xmit_fast(sdata, sta, &entry->fast_tx, skb, tid_tx, -+ eth.h_dest, eth.h_source); -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_unicast); -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -+ -+ return true; -+} -+#endif -+ - static ieee80211_rx_result - ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, - struct sk_buff *skb) -@@ -2824,6 +2883,10 @@ ieee80211_rx_mesh_data(struct ieee80211_ - - skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); - -+ if (!multicast && -+ ieee80211_rx_mesh_fast_forward(sdata, skb, mesh_hdrlen)) -+ return RX_QUEUED; -+ - ieee80211_fill_mesh_addresses(&hdr, &hdr.frame_control, - eth->h_dest, eth->h_source); - hdrlen = ieee80211_hdrlen(hdr.frame_control); -@@ -2862,6 +2925,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ - info->control.flags |= IEEE80211_TX_INTCFL_NEED_TXPROCESSING; - info->control.vif = &sdata->vif; - info->control.jiffies = jiffies; -+ fwd_skb->dev = sdata->dev; - if (multicast) { - IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_mcast); - memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); -@@ -2883,7 +2947,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ - } - - IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); -- fwd_skb->dev = sdata->dev; - ieee80211_add_pending_skb(local, fwd_skb); - - rx_accept: ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -2022,6 +2022,8 @@ void __ieee80211_xmit_fast(struct ieee80 - struct ieee80211_fast_tx *fast_tx, - struct sk_buff *skb, bool ampdu, - const u8 *da, const u8 *sa); -+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, struct sk_buff *skb); - - /* HT */ - void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -1191,10 +1191,8 @@ static bool ieee80211_tx_prep_agg(struct - return queued; - } - --static void --ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -- struct sta_info *sta, -- struct sk_buff *skb) -+void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta, struct sk_buff *skb) - { - struct rate_control_ref *ref = sdata->local->rate_ctrl; - u16 tid; diff --git a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch deleted file mode 100644 index e2b268ae4c..0000000000 --- a/package/kernel/mac80211/patches/subsys/321-mac80211-fix-mesh-forwarding.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 20 Feb 2023 12:50:50 +0100 -Subject: [PATCH] mac80211: fix mesh forwarding - -Linearize packets (needed for forwarding A-MSDU subframes). -Fix network header offset to fix flow dissector (and fair queueing). - -Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2904,6 +2904,9 @@ ieee80211_rx_mesh_data(struct ieee80211_ - - if (skb_cow_head(fwd_skb, hdrlen - sizeof(struct ethhdr))) - return RX_DROP_UNUSABLE; -+ -+ if (skb_linearize(fwd_skb)) -+ return RX_DROP_UNUSABLE; - } - - fwd_hdr = skb_push(fwd_skb, hdrlen - sizeof(struct ethhdr)); -@@ -2918,7 +2921,7 @@ ieee80211_rx_mesh_data(struct ieee80211_ - hdrlen += ETH_ALEN; - else - fwd_skb->protocol = htons(fwd_skb->len - hdrlen); -- skb_set_network_header(fwd_skb, hdrlen); -+ skb_set_network_header(fwd_skb, hdrlen + 2); - - info = IEEE80211_SKB_CB(fwd_skb); - memset(info, 0, sizeof(*info)); diff --git a/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch b/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch deleted file mode 100644 index 292a89ef92..0000000000 --- a/package/kernel/mac80211/patches/subsys/322-wifi-mac80211-fix-mesh-path-discovery-based-on-unica.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 26 Feb 2023 20:30:20 +0100 -Subject: [PATCH] wifi: mac80211: fix mesh path discovery based on unicast - packets - -If a packet has reached its intended destination, it was bumped to the code -that accepts it, without first checking if a mesh_path needs to be created -based on the discovered source. -Fix this by moving the destination address check further down - -Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2824,17 +2824,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ - mesh_rmc_check(sdata, eth->h_source, mesh_hdr)) - return RX_DROP_MONITOR; - -- /* Frame has reached destination. Don't forward */ -- if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -- goto rx_accept; -- -- if (!ifmsh->mshcfg.dot11MeshForwarding) { -- if (is_multicast_ether_addr(eth->h_dest)) -- goto rx_accept; -- -- return RX_DROP_MONITOR; -- } -- - /* forward packet */ - if (sdata->crypto_tx_tailroom_needed_cnt) - tailroom = IEEE80211_ENCRYPT_TAILROOM; -@@ -2881,6 +2870,17 @@ ieee80211_rx_mesh_data(struct ieee80211_ - rcu_read_unlock(); - } - -+ /* Frame has reached destination. Don't forward */ -+ if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) -+ goto rx_accept; -+ -+ if (!ifmsh->mshcfg.dot11MeshForwarding) { -+ if (is_multicast_ether_addr(eth->h_dest)) -+ goto rx_accept; -+ -+ return RX_DROP_MONITOR; -+ } -+ - skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]); - - if (!multicast && diff --git a/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch b/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch deleted file mode 100644 index e23dc4d226..0000000000 --- a/package/kernel/mac80211/patches/subsys/323-v6.3-wifi-mac80211-Add-VHT-MU-MIMO-related-flags-in-ieee8.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Muna Sinada <quic_msinada@quicinc.com> -Date: Wed, 5 Oct 2022 14:54:45 -0700 -Subject: [PATCH] wifi: mac80211: Add VHT MU-MIMO related flags in - ieee80211_bss_conf - -Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and -MU Beamformee for VHT. This is utilized to pass MU-MIMO -configurations from user space to driver in AP mode. - -Signed-off-by: Muna Sinada <quic_msinada@quicinc.com> -Link: https://lore.kernel.org/r/1665006886-23874-1-git-send-email-quic_msinada@quicinc.com -[fixed indentation, removed redundant !!] -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -653,6 +653,14 @@ struct ieee80211_fils_discovery { - * write-protected by sdata_lock and local->mtx so holding either is fine - * for read access. - * @color_change_color: the bss color that will be used after the change. -+ * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU -+ * beamformer -+ * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU -+ * beamformee -+ * @vht_mu_beamformer: in AP mode, does this BSS support operation as an VHT MU -+ * beamformer -+ * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU -+ * beamformee - */ - struct ieee80211_bss_conf { - const u8 *bssid; -@@ -726,6 +734,11 @@ struct ieee80211_bss_conf { - - bool color_change_active; - u8 color_change_color; -+ -+ bool vht_su_beamformer; -+ bool vht_su_beamformee; -+ bool vht_mu_beamformer; -+ bool vht_mu_beamformee; - }; - - /** ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1252,6 +1252,21 @@ static int ieee80211_start_ap(struct wip - prev_beacon_int = link_conf->beacon_int; - link_conf->beacon_int = params->beacon_interval; - -+ if (params->vht_cap) { -+ link_conf->vht_su_beamformer = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); -+ link_conf->vht_su_beamformee = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE); -+ link_conf->vht_mu_beamformer = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE); -+ link_conf->vht_mu_beamformee = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE); -+ } -+ - if (params->he_cap && params->he_oper) { - link_conf->he_support = true; - link_conf->htc_trig_based_pkt_ext = diff --git a/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch b/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch deleted file mode 100644 index f843dba123..0000000000 --- a/package/kernel/mac80211/patches/subsys/324-v6.3-wifi-mac80211-Add-HE-MU-MIMO-related-flags-in-ieee80.patch +++ /dev/null @@ -1,68 +0,0 @@ -From: Muna Sinada <quic_msinada@quicinc.com> -Date: Wed, 5 Oct 2022 14:54:46 -0700 -Subject: [PATCH] wifi: mac80211: Add HE MU-MIMO related flags in - ieee80211_bss_conf - -Adding flags for SU Beamformer, SU Beamformee, MU Beamformer and Full -Bandwidth UL MU-MIMO for HE. This is utilized to pass MU-MIMO -configurations from user space to driver in AP mode. - -Signed-off-by: Muna Sinada <quic_msinada@quicinc.com> -Link: https://lore.kernel.org/r/1665006886-23874-2-git-send-email-quic_msinada@quicinc.com -[fixed indentation, removed redundant !!] -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -661,6 +661,15 @@ struct ieee80211_fils_discovery { - * beamformer - * @vht_mu_beamformee: in AP mode, does this BSS support operation as an VHT MU - * beamformee -+ * @he_su_beamformer: in AP-mode, does this BSS support operation as an HE SU -+ * beamformer -+ * @he_su_beamformee: in AP-mode, does this BSS support operation as an HE SU -+ * beamformee -+ * @he_mu_beamformer: in AP-mode, does this BSS support operation as an HE MU -+ * beamformer -+ * @he_full_ul_mumimo: does this BSS support the reception (AP) or transmission -+ * (non-AP STA) of an HE TB PPDU on an RU that spans the entire PPDU -+ * bandwidth - */ - struct ieee80211_bss_conf { - const u8 *bssid; -@@ -739,6 +748,10 @@ struct ieee80211_bss_conf { - bool vht_su_beamformee; - bool vht_mu_beamformer; - bool vht_mu_beamformee; -+ bool he_su_beamformer; -+ bool he_su_beamformee; -+ bool he_mu_beamformer; -+ bool he_full_ul_mumimo; - }; - - /** ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1281,6 +1281,21 @@ static int ieee80211_start_ap(struct wip - changed |= BSS_CHANGED_HE_BSS_COLOR; - } - -+ if (params->he_cap) { -+ link_conf->he_su_beamformer = -+ params->he_cap->phy_cap_info[3] & -+ IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; -+ link_conf->he_su_beamformee = -+ params->he_cap->phy_cap_info[4] & -+ IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE; -+ link_conf->he_mu_beamformer = -+ params->he_cap->phy_cap_info[4] & -+ IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER; -+ link_conf->he_full_ul_mumimo = -+ params->he_cap->phy_cap_info[2] & -+ IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO; -+ } -+ - if (sdata->vif.type == NL80211_IFTYPE_AP && - params->mbssid_config.tx_wdev) { - err = ieee80211_set_ap_mbssid_options(sdata, diff --git a/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch b/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch deleted file mode 100644 index 1be5fcfbfa..0000000000 --- a/package/kernel/mac80211/patches/subsys/325-wifi-mac80211-introduce-ieee80211_refresh_tx_agg_ses.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Ryder Lee <ryder.lee@mediatek.com> -Date: Sat, 18 Feb 2023 01:50:05 +0800 -Subject: [PATCH] wifi: mac80211: introduce - ieee80211_refresh_tx_agg_session_timer() - -This allows low level drivers to refresh the tx agg session timer, based on -querying stats from the firmware usually. Especially for some mt76 devices -support .net_fill_forward_path would bypass mac80211, which leads to tx BA -session timeout for certain clients. - -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -5964,6 +5964,18 @@ void ieee80211_queue_delayed_work(struct - unsigned long delay); - - /** -+ * ieee80211_refresh_tx_agg_session_timer - Refresh a tx agg session timer. -+ * @sta: the station for which to start a BA session -+ * @tid: the TID to BA on. -+ * -+ * This function allows low level driver to refresh tx agg session timer -+ * to maintain BA session, the session level will still be managed by the -+ * mac80211. -+ */ -+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta, -+ u16 tid); -+ -+/** - * ieee80211_start_tx_ba_session - Start a tx Block Ack session. - * @sta: the station for which to start a BA session - * @tid: the TID to BA on. ---- a/net/mac80211/agg-tx.c -+++ b/net/mac80211/agg-tx.c -@@ -554,6 +554,23 @@ void ieee80211_tx_ba_session_handle_star - ieee80211_send_addba_with_timeout(sta, tid_tx); - } - -+void ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *pubsta, -+ u16 tid) -+{ -+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+ struct tid_ampdu_tx *tid_tx; -+ -+ if (WARN_ON_ONCE(tid >= IEEE80211_NUM_TIDS)) -+ return; -+ -+ tid_tx = rcu_dereference(sta->ampdu_mlme.tid_tx[tid]); -+ if (!tid_tx) -+ return; -+ -+ tid_tx->last_tx = jiffies; -+} -+EXPORT_SYMBOL(ieee80211_refresh_tx_agg_session_timer); -+ - /* - * After accepting the AddBA Response we activated a timer, - * resetting it after each frame that we send. diff --git a/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch b/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch deleted file mode 100644 index 11f39c2d10..0000000000 --- a/package/kernel/mac80211/patches/subsys/326-wifi-mac80211-add-mesh-fast-rx-support.patch +++ /dev/null @@ -1,77 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Thu, 2 Mar 2023 13:52:29 +0100 -Subject: [PATCH] wifi: mac80211: add mesh fast-rx support - -This helps bring down rx CPU usage by avoiding calls to the rx handlers in -the slow path. Supports forwarding and local rx, including A-MSDU. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -4564,6 +4564,12 @@ void ieee80211_check_fast_rx(struct sta_ - } - - break; -+ case NL80211_IFTYPE_MESH_POINT: -+ fastrx.expected_ds_bits = cpu_to_le16(IEEE80211_FCTL_FROMDS | -+ IEEE80211_FCTL_TODS); -+ fastrx.da_offs = offsetof(struct ieee80211_hdr, addr3); -+ fastrx.sa_offs = offsetof(struct ieee80211_hdr, addr4); -+ break; - default: - goto clear; - } -@@ -4772,6 +4778,7 @@ static bool ieee80211_invoke_fast_rx(str - struct sk_buff *skb = rx->skb; - struct ieee80211_hdr *hdr = (void *)skb->data; - struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -+ static ieee80211_rx_result res; - int orig_len = skb->len; - int hdrlen = ieee80211_hdrlen(hdr->frame_control); - int snap_offs = hdrlen; -@@ -4833,7 +4840,8 @@ static bool ieee80211_invoke_fast_rx(str - snap_offs += IEEE80211_CCMP_HDR_LEN; - } - -- if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { -+ if (!ieee80211_vif_is_mesh(&rx->sdata->vif) && -+ !(status->rx_flags & IEEE80211_RX_AMSDU)) { - if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) - return false; - -@@ -4872,13 +4880,29 @@ static bool ieee80211_invoke_fast_rx(str - /* do the header conversion - first grab the addresses */ - ether_addr_copy(addrs.da, skb->data + fast_rx->da_offs); - ether_addr_copy(addrs.sa, skb->data + fast_rx->sa_offs); -- skb_postpull_rcsum(skb, skb->data + snap_offs, -- sizeof(rfc1042_header) + 2); -- /* remove the SNAP but leave the ethertype */ -- skb_pull(skb, snap_offs + sizeof(rfc1042_header)); -+ if (ieee80211_vif_is_mesh(&rx->sdata->vif)) { -+ skb_pull(skb, snap_offs - 2); -+ put_unaligned_be16(skb->len - 2, skb->data); -+ } else { -+ skb_postpull_rcsum(skb, skb->data + snap_offs, -+ sizeof(rfc1042_header) + 2); -+ -+ /* remove the SNAP but leave the ethertype */ -+ skb_pull(skb, snap_offs + sizeof(rfc1042_header)); -+ } - /* push the addresses in front */ - memcpy(skb_push(skb, sizeof(addrs)), &addrs, sizeof(addrs)); - -+ res = ieee80211_rx_mesh_data(rx->sdata, rx->sta, rx->skb); -+ switch (res) { -+ case RX_QUEUED: -+ return true; -+ case RX_CONTINUE: -+ break; -+ default: -+ goto drop; -+ } -+ - ieee80211_rx_8023(rx, fast_rx, orig_len); - - return true; diff --git a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch b/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch deleted file mode 100644 index ac290b5360..0000000000 --- a/package/kernel/mac80211/patches/subsys/327-wifi-mac80211-add-support-for-letting-drivers-regist.patch +++ /dev/null @@ -1,149 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Mon, 20 Mar 2023 14:28:08 +0100 -Subject: [PATCH] wifi: mac80211: add support for letting drivers register tc - offload support - -On newer MediaTek SoCs (e.g. MT7986), WLAN->WLAN or WLAN->Ethernet flows can -be offloaded by the SoC. In order to support that, the .ndo_setup_tc op is -needed. - -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -4192,6 +4192,10 @@ struct ieee80211_prep_tx_info { - * Note that a sta can also be inserted or removed with valid links, - * i.e. passed to @sta_add/@sta_state with sta->valid_links not zero. - * In fact, cannot change from having valid_links and not having them. -+ * @net_setup_tc: Called from .ndo_setup_tc in order to prepare hardware -+ * flow offloading for flows originating from the vif. -+ * Note that the driver must not assume that the vif driver_data is valid -+ * at this point, since the callback can be called during netdev teardown. - */ - struct ieee80211_ops { - void (*tx)(struct ieee80211_hw *hw, -@@ -4547,6 +4551,11 @@ struct ieee80211_ops { - struct ieee80211_vif *vif, - struct ieee80211_sta *sta, - u16 old_links, u16 new_links); -+ int (*net_setup_tc)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct net_device *dev, -+ enum tc_setup_type type, -+ void *type_data); - }; - - /** ---- a/net/mac80211/driver-ops.h -+++ b/net/mac80211/driver-ops.h -@@ -1470,6 +1470,23 @@ static inline int drv_net_fill_forward_p - return ret; - } - -+static inline int drv_net_setup_tc(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct net_device *dev, -+ enum tc_setup_type type, void *type_data) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ sdata = get_bss_sdata(sdata); -+ trace_drv_net_setup_tc(local, sdata, type); -+ if (local->ops->net_setup_tc) -+ ret = local->ops->net_setup_tc(&local->hw, &sdata->vif, dev, -+ type, type_data); -+ trace_drv_return_int(local, ret); -+ -+ return ret; -+} -+ - int drv_change_vif_links(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - u16 old_links, u16 new_links, ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1939,7 +1939,8 @@ void ieee80211_color_collision_detection - /* interface handling */ - #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ - NETIF_F_HW_CSUM | NETIF_F_SG | \ -- NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE) -+ NETIF_F_HIGHDMA | NETIF_F_GSO_SOFTWARE | \ -+ NETIF_F_HW_TC) - #define MAC80211_SUPPORTED_FEATURES_RX (NETIF_F_RXCSUM) - #define MAC80211_SUPPORTED_FEATURES (MAC80211_SUPPORTED_FEATURES_TX | \ - MAC80211_SUPPORTED_FEATURES_RX) ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -813,6 +813,21 @@ ieee80211_get_stats64(struct net_device - dev_fetch_sw_netstats(stats, dev->tstats); - } - -+static int ieee80211_netdev_setup_tc(struct net_device *dev, -+ enum tc_setup_type type, void *type_data) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_local *local; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(dev); -+ local = sdata->local; -+ -+ if (!local->ops->net_setup_tc) -+ return -EOPNOTSUPP; -+ -+ return drv_net_setup_tc(local, sdata, dev, type, type_data); -+} -+ - static const struct net_device_ops ieee80211_dataif_ops = { - .ndo_open = ieee80211_open, - .ndo_stop = ieee80211_stop, -@@ -821,6 +836,7 @@ static const struct net_device_ops ieee8 - .ndo_set_rx_mode = ieee80211_set_multicast_list, - .ndo_set_mac_address = ieee80211_change_mac, - .ndo_get_stats64 = ieee80211_get_stats64, -+ .ndo_setup_tc = ieee80211_netdev_setup_tc, - }; - - static u16 ieee80211_monitor_select_queue(struct net_device *dev, -@@ -929,6 +945,7 @@ static const struct net_device_ops ieee8 - .ndo_set_mac_address = ieee80211_change_mac, - .ndo_get_stats64 = ieee80211_get_stats64, - .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, -+ .ndo_setup_tc = ieee80211_netdev_setup_tc, - }; - - static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype) ---- a/net/mac80211/trace.h -+++ b/net/mac80211/trace.h -@@ -2478,6 +2478,31 @@ DEFINE_EVENT(sta_event, drv_net_fill_for - TP_ARGS(local, sdata, sta) - ); - -+TRACE_EVENT(drv_net_setup_tc, -+ TP_PROTO(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ u8 type), -+ -+ TP_ARGS(local, sdata, type), -+ -+ TP_STRUCT__entry( -+ LOCAL_ENTRY -+ VIF_ENTRY -+ __field(u8, type) -+ ), -+ -+ TP_fast_assign( -+ LOCAL_ASSIGN; -+ VIF_ASSIGN; -+ __entry->type = type; -+ ), -+ -+ TP_printk( -+ LOCAL_PR_FMT VIF_PR_FMT " type:%d\n", -+ LOCAL_PR_ARG, VIF_PR_ARG, __entry->type -+ ) -+); -+ - TRACE_EVENT(drv_change_vif_links, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch b/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch deleted file mode 100644 index 6882694da8..0000000000 --- a/package/kernel/mac80211/patches/subsys/329-wifi-mac80211-fix-receiving-mesh-packets-in-forwardi.patch +++ /dev/null @@ -1,50 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Sun, 26 Mar 2023 17:11:34 +0200 -Subject: [PATCH] wifi: mac80211: fix receiving mesh packets in forwarding=0 - networks -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When forwarding is set to 0, frames are typically sent with ttl=1. -Move the ttl decrement check below the check for local receive in order to -fix packet drops. - -Reported-by: Thomas Hühn <thomas.huehn@hs-nordhausen.de> -Reported-by: Nick Hainke <vincent@systemli.org> -Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2828,14 +2828,6 @@ ieee80211_rx_mesh_data(struct ieee80211_ - if (sdata->crypto_tx_tailroom_needed_cnt) - tailroom = IEEE80211_ENCRYPT_TAILROOM; - -- if (!--mesh_hdr->ttl) { -- if (multicast) -- goto rx_accept; -- -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -- return RX_DROP_MONITOR; -- } -- - if (mesh_hdr->flags & MESH_FLAGS_AE) { - struct mesh_path *mppath; - char *proxied_addr; -@@ -2874,6 +2866,14 @@ ieee80211_rx_mesh_data(struct ieee80211_ - if (ether_addr_equal(sdata->vif.addr, eth->h_dest)) - goto rx_accept; - -+ if (!--mesh_hdr->ttl) { -+ if (multicast) -+ goto rx_accept; -+ -+ IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl); -+ return RX_DROP_MONITOR; -+ } -+ - if (!ifmsh->mshcfg.dot11MeshForwarding) { - if (is_multicast_ether_addr(eth->h_dest)) - goto rx_accept; diff --git a/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch b/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch deleted file mode 100644 index 079dd2a868..0000000000 --- a/package/kernel/mac80211/patches/subsys/330-wifi-ieee80211-correctly-mark-FTM-frames-non-buffera.patch +++ /dev/null @@ -1,134 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Wed, 29 Mar 2023 16:46:26 +0200 -Subject: [PATCH] wifi: ieee80211: correctly mark FTM frames non-bufferable - -The checks of whether or not a frame is bufferable were not -taking into account that some action frames aren't, such as -FTM. Check this, which requires some changes to the function -ieee80211_is_bufferable_mmpdu() since we need the whole skb -for the checks now. - -Signed-off-by: Johannes Berg <johannes.berg@intel.com> -Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com> -Reviewed-by: Peer, Ilan <ilan.peer@intel.com> ---- - ---- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c -@@ -601,8 +601,9 @@ static void iwl_mvm_skb_prepare_status(s - - static int iwl_mvm_get_ctrl_vif_queue(struct iwl_mvm *mvm, - struct ieee80211_tx_info *info, -- struct ieee80211_hdr *hdr) -+ struct sk_buff *skb) - { -+ struct ieee80211_hdr *hdr = (void *)skb->data; - struct iwl_mvm_vif *mvmvif = - iwl_mvm_vif_from_mac80211(info->control.vif); - __le16 fc = hdr->frame_control; -@@ -621,7 +622,7 @@ static int iwl_mvm_get_ctrl_vif_queue(st - * reason 7 ("Class 3 frame received from nonassociated STA"). - */ - if (ieee80211_is_mgmt(fc) && -- (!ieee80211_is_bufferable_mmpdu(fc) || -+ (!ieee80211_is_bufferable_mmpdu(skb) || - ieee80211_is_deauth(fc) || ieee80211_is_disassoc(fc))) - return mvm->probe_queue; - -@@ -740,7 +741,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mv - else - sta_id = mvmvif->mcast_sta.sta_id; - -- queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, hdr); -+ queue = iwl_mvm_get_ctrl_vif_queue(mvm, &info, skb); - } else if (info.control.vif->type == NL80211_IFTYPE_MONITOR) { - queue = mvm->snif_queue; - sta_id = mvm->snif_sta.sta_id; ---- a/include/linux/ieee80211.h -+++ b/include/linux/ieee80211.h -@@ -772,20 +772,6 @@ static inline bool ieee80211_is_any_null - } - - /** -- * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -- * @fc: frame control field in little-endian byteorder -- */ --static inline bool ieee80211_is_bufferable_mmpdu(__le16 fc) --{ -- /* IEEE 802.11-2012, definition of "bufferable management frame"; -- * note that this ignores the IBSS special case. */ -- return ieee80211_is_mgmt(fc) && -- (ieee80211_is_action(fc) || -- ieee80211_is_disassoc(fc) || -- ieee80211_is_deauth(fc)); --} -- --/** - * ieee80211_is_first_frag - check if IEEE80211_SCTL_FRAG is not set - * @seq_ctrl: frame sequence control bytes in little-endian byteorder - */ -@@ -4121,6 +4107,44 @@ static inline u8 *ieee80211_get_DA(struc - } - - /** -+ * ieee80211_is_bufferable_mmpdu - check if frame is bufferable MMPDU -+ * @skb: the skb to check, starting with the 802.11 header -+ */ -+static inline bool ieee80211_is_bufferable_mmpdu(struct sk_buff *skb) -+{ -+ struct ieee80211_mgmt *mgmt = (void *)skb->data; -+ __le16 fc = mgmt->frame_control; -+ -+ /* -+ * IEEE 802.11 REVme D2.0 definition of bufferable MMPDU; -+ * note that this ignores the IBSS special case. -+ */ -+ if (!ieee80211_is_mgmt(fc)) -+ return false; -+ -+ if (ieee80211_is_disassoc(fc) || ieee80211_is_deauth(fc)) -+ return true; -+ -+ if (!ieee80211_is_action(fc)) -+ return false; -+ -+ if (skb->len < offsetofend(typeof(*mgmt), u.action.u.ftm.action_code)) -+ return true; -+ -+ /* action frame - additionally check for non-bufferable FTM */ -+ -+ if (mgmt->u.action.category != WLAN_CATEGORY_PUBLIC && -+ mgmt->u.action.category != WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION) -+ return true; -+ -+ if (mgmt->u.action.u.ftm.action_code == WLAN_PUB_ACTION_FTM_REQUEST || -+ mgmt->u.action.u.ftm.action_code == WLAN_PUBLIC_ACTION_FTM_RESPONSE) -+ return false; -+ -+ return true; -+} -+ -+/** - * _ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame - * @hdr: the frame (buffer must include at least the first octet of payload) - */ ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -488,7 +488,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee - int ac = skb_get_queue_mapping(tx->skb); - - if (ieee80211_is_mgmt(hdr->frame_control) && -- !ieee80211_is_bufferable_mmpdu(hdr->frame_control)) { -+ !ieee80211_is_bufferable_mmpdu(tx->skb)) { - info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; - return TX_CONTINUE; - } -@@ -1326,7 +1326,7 @@ static struct txq_info *ieee80211_get_tx - if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) && - unlikely(!ieee80211_is_data_present(hdr->frame_control))) { - if ((!ieee80211_is_mgmt(hdr->frame_control) || -- ieee80211_is_bufferable_mmpdu(hdr->frame_control) || -+ ieee80211_is_bufferable_mmpdu(skb) || - vif->type == NL80211_IFTYPE_STATION) && - sta && sta->uploaded) { - /* diff --git a/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch b/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch deleted file mode 100644 index 00232ec1b9..0000000000 --- a/package/kernel/mac80211/patches/subsys/331-wifi-mac80211-flush-queues-on-STA-removal.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Mon, 13 Mar 2023 11:42:12 +0100 -Subject: [PATCH] wifi: mac80211: flush queues on STA removal - -When we remove a station, we first make it unreachable, -then we (must) remove its keys, and then remove the -station itself. Depending on the hardware design, if -we have hardware crypto at all, frames still sitting -on hardware queues may then be transmitted without a -valid key, possibly unencrypted or with a fixed key. - -Fix this by flushing the queues when removing stations -so this cannot happen. - -Cc: stable@vger.kernel.org -Signed-off-by: Johannes Berg <johannes.berg@intel.com> -Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com> ---- - ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -1271,6 +1271,14 @@ static void __sta_info_destroy_part2(str - WARN_ON_ONCE(ret); - } - -+ /* Flush queues before removing keys, as that might remove them -+ * from hardware, and then depending on the offload method, any -+ * frames sitting on hardware queues might be sent out without -+ * any encryption at all. -+ */ -+ if (local->ops->set_key) -+ ieee80211_flush_queues(local, sta->sdata, false); -+ - /* now keys can no longer be reached */ - ieee80211_free_sta_keys(local, sta); - diff --git a/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch b/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch deleted file mode 100644 index 3c31dfeddc..0000000000 --- a/package/kernel/mac80211/patches/subsys/332-wifi-iwlwifi-mvm-support-flush-on-AP-interfaces.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Mon, 13 Mar 2023 12:02:58 +0100 -Subject: [PATCH] wifi: iwlwifi: mvm: support flush on AP interfaces - -Support TX flush on AP interfaces so that we will do a -proper flush for frames on the queue before keys are -removed. - -Signed-off-by: Johannes Berg <johannes.berg@intel.com> -Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com> ---- - ---- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -@@ -4854,9 +4854,6 @@ static void iwl_mvm_mac_flush(struct iee - return; - } - -- if (vif->type != NL80211_IFTYPE_STATION) -- return; -- - /* Make sure we're done with the deferred traffic before flushing */ - flush_work(&mvm->add_stream_wk); - -@@ -4874,9 +4871,6 @@ static void iwl_mvm_mac_flush(struct iee - if (mvmsta->vif != vif) - continue; - -- /* make sure only TDLS peers or the AP are flushed */ -- WARN_ON(i != mvmvif->ap_sta_id && !sta->tdls); -- - if (drop) { - if (iwl_mvm_flush_sta(mvm, mvmsta, false)) - IWL_ERR(mvm, "flush request fail\n"); diff --git a/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch deleted file mode 100644 index 3bba0b7e66..0000000000 --- a/package/kernel/mac80211/patches/subsys/333-wifi-mac80211-add-flush_sta-method.patch +++ /dev/null @@ -1,91 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Mon, 13 Mar 2023 11:53:51 +0100 -Subject: [PATCH] wifi: mac80211: add flush_sta method - -Some drivers like iwlwifi might have per-STA queues, so we -may want to flush/drop just those queues rather than all -when removing a station. Add a separate method for that. - -Signed-off-by: Johannes Berg <johannes.berg@intel.com> -Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -3918,6 +3918,10 @@ struct ieee80211_prep_tx_info { - * Note that vif can be NULL. - * The callback can sleep. - * -+ * @flush_sta: Flush or drop all pending frames from the hardware queue(s) for -+ * the given station, as it's about to be removed. -+ * The callback can sleep. -+ * - * @channel_switch: Drivers that need (or want) to offload the channel - * switch operation for CSAs received from the AP may implement this - * callback. They must then call ieee80211_chswitch_done() to indicate -@@ -4372,6 +4376,8 @@ struct ieee80211_ops { - #endif - void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, - u32 queues, bool drop); -+ void (*flush_sta)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta); - void (*channel_switch)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_channel_switch *ch_switch); ---- a/net/mac80211/driver-ops.h -+++ b/net/mac80211/driver-ops.h -@@ -617,6 +617,21 @@ static inline void drv_flush(struct ieee - trace_drv_return_void(local); - } - -+static inline void drv_flush_sta(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct sta_info *sta) -+{ -+ might_sleep(); -+ -+ if (sdata && !check_sdata_in_driver(sdata)) -+ return; -+ -+ trace_drv_flush_sta(local, sdata, &sta->sta); -+ if (local->ops->flush_sta) -+ local->ops->flush_sta(&local->hw, &sdata->vif, &sta->sta); -+ trace_drv_return_void(local); -+} -+ - static inline void drv_channel_switch(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, - struct ieee80211_channel_switch *ch_switch) ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -1276,8 +1276,12 @@ static void __sta_info_destroy_part2(str - * frames sitting on hardware queues might be sent out without - * any encryption at all. - */ -- if (local->ops->set_key) -- ieee80211_flush_queues(local, sta->sdata, false); -+ if (local->ops->set_key) { -+ if (local->ops->flush_sta) -+ drv_flush_sta(local, sta->sdata, sta); -+ else -+ ieee80211_flush_queues(local, sta->sdata, false); -+ } - - /* now keys can no longer be reached */ - ieee80211_free_sta_keys(local, sta); ---- a/net/mac80211/trace.h -+++ b/net/mac80211/trace.h -@@ -1177,6 +1177,13 @@ TRACE_EVENT(drv_flush, - ) - ); - -+DEFINE_EVENT(sta_event, drv_flush_sta, -+ TP_PROTO(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_sta *sta), -+ TP_ARGS(local, sdata, sta) -+); -+ - TRACE_EVENT(drv_channel_switch, - TP_PROTO(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch b/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch deleted file mode 100644 index 18f39d505f..0000000000 --- a/package/kernel/mac80211/patches/subsys/334-wifi-iwlwifi-mvm-support-new-flush_sta-method.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Johannes Berg <johannes.berg@intel.com> -Date: Mon, 13 Mar 2023 12:05:35 +0100 -Subject: [PATCH] wifi: iwlwifi: mvm: support new flush_sta method - -For iwlwifi this is simple to implement, and on newer hardware -it's an improvement since we have per-station queues. - -Signed-off-by: Johannes Berg <johannes.berg@intel.com> -Reviewed-by: Greenman, Gregory <gregory.greenman@intel.com> ---- - ---- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c -@@ -4890,6 +4890,31 @@ static void iwl_mvm_mac_flush(struct iee - iwl_trans_wait_tx_queues_empty(mvm->trans, msk); - } - -+static void iwl_mvm_mac_flush_sta(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta) -+{ -+ struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); -+ int i; -+ -+ mutex_lock(&mvm->mutex); -+ for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { -+ struct iwl_mvm_sta *mvmsta; -+ struct ieee80211_sta *tmp; -+ -+ tmp = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], -+ lockdep_is_held(&mvm->mutex)); -+ if (tmp != sta) -+ continue; -+ -+ mvmsta = iwl_mvm_sta_from_mac80211(sta); -+ -+ if (iwl_mvm_flush_sta(mvm, mvmsta, false)) -+ IWL_ERR(mvm, "flush request fail\n"); -+ } -+ mutex_unlock(&mvm->mutex); -+} -+ - static int iwl_mvm_mac_get_survey(struct ieee80211_hw *hw, int idx, - struct survey_info *survey) - { -@@ -5417,6 +5442,7 @@ const struct ieee80211_ops iwl_mvm_hw_op - .mgd_complete_tx = iwl_mvm_mac_mgd_complete_tx, - .mgd_protect_tdls_discover = iwl_mvm_mac_mgd_protect_tdls_discover, - .flush = iwl_mvm_mac_flush, -+ .flush_sta = iwl_mvm_mac_flush_sta, - .sched_scan_start = iwl_mvm_mac_sched_scan_start, - .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, - .set_key = iwl_mvm_mac_set_key, diff --git a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch b/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch deleted file mode 100644 index 1b379b76ae..0000000000 --- a/package/kernel/mac80211/patches/subsys/335-wifi-mac80211-add-LDPC-related-flags-in-ieee80211_bs.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Ryder Lee <ryder.lee@mediatek.com> -Date: Sat, 18 Feb 2023 01:49:25 +0800 -Subject: [PATCH] wifi: mac80211: add LDPC related flags in ieee80211_bss_conf - -This is utilized to pass LDPC configurations from user space -(i.e. hostapd) to driver. - -Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> -Link: https://lore.kernel.org/r/1de696aaa34efd77a926eb657b8c0fda05aaa177.1676628065.git.ryder.lee@mediatek.com -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -653,6 +653,9 @@ struct ieee80211_fils_discovery { - * write-protected by sdata_lock and local->mtx so holding either is fine - * for read access. - * @color_change_color: the bss color that will be used after the change. -+ * @ht_ldpc: in AP mode, indicates interface has HT LDPC capability. -+ * @vht_ldpc: in AP mode, indicates interface has VHT LDPC capability. -+ * @he_ldpc: in AP mode, indicates interface has HE LDPC capability. - * @vht_su_beamformer: in AP mode, does this BSS support operation as an VHT SU - * beamformer - * @vht_su_beamformee: in AP mode, does this BSS support operation as an VHT SU -@@ -744,6 +747,9 @@ struct ieee80211_bss_conf { - bool color_change_active; - u8 color_change_color; - -+ bool ht_ldpc; -+ bool vht_ldpc; -+ bool he_ldpc; - bool vht_su_beamformer; - bool vht_su_beamformee; - bool vht_mu_beamformer; ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1252,7 +1252,15 @@ static int ieee80211_start_ap(struct wip - prev_beacon_int = link_conf->beacon_int; - link_conf->beacon_int = params->beacon_interval; - -+ if (params->ht_cap) -+ link_conf->ht_ldpc = -+ params->ht_cap->cap_info & -+ cpu_to_le16(IEEE80211_HT_CAP_LDPC_CODING); -+ - if (params->vht_cap) { -+ link_conf->vht_ldpc = -+ params->vht_cap->vht_cap_info & -+ cpu_to_le32(IEEE80211_VHT_CAP_RXLDPC); - link_conf->vht_su_beamformer = - params->vht_cap->vht_cap_info & - cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE); -@@ -1282,6 +1290,9 @@ static int ieee80211_start_ap(struct wip - } - - if (params->he_cap) { -+ link_conf->he_ldpc = -+ params->he_cap->phy_cap_info[1] & -+ IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD; - link_conf->he_su_beamformer = - params->he_cap->phy_cap_info[3] & - IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER; diff --git a/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch deleted file mode 100644 index 088f468e37..0000000000 --- a/package/kernel/mac80211/patches/subsys/336-v6.4-wifi-mac80211-generate-EMA-beacons-in-AP-mode.patch +++ /dev/null @@ -1,372 +0,0 @@ -From bd54f3c29077f23dad92ef82a78061b40be30c65 Mon Sep 17 00:00:00 2001 -From: Aloka Dixit <quic_alokad@quicinc.com> -Date: Mon, 5 Dec 2022 16:50:37 -0800 -Subject: [PATCH] wifi: mac80211: generate EMA beacons in AP mode - -Add APIs to generate an array of beacons for an EMA AP (enhanced -multiple BSSID advertisements), each including a single MBSSID element. -EMA profile periodicity equals the count of elements. - -- ieee80211_beacon_get_template_ema_list() - Generate and return all -EMA beacon templates. Drivers must call ieee80211_beacon_free_ema_list() -to free the memory. No change in the prototype for the existing API, -ieee80211_beacon_get_template(), which should be used for non-EMA AP. - -- ieee80211_beacon_get_template_ema_index() - Generate a beacon which -includes the multiple BSSID element at the given index. Drivers can use -this function in a loop until NULL is returned which indicates end of -available MBSSID elements. - -- ieee80211_beacon_free_ema_list() - free the memory allocated for the -list of EMA beacon templates. - -Modify existing functions ieee80211_beacon_get_ap(), -ieee80211_get_mbssid_beacon_len() and ieee80211_beacon_add_mbssid() -to accept a new parameter for EMA index. - -Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com> -Co-developed-by: John Crispin <john@phrozen.org> -Signed-off-by: John Crispin <john@phrozen.org> -Link: https://lore.kernel.org/r/20221206005040.3177-2-quic_alokad@quicinc.com -Signed-off-by: Johannes Berg <johannes.berg@intel.com> ---- - include/net/mac80211.h | 68 +++++++++++++++++++ - net/mac80211/cfg.c | 11 +-- - net/mac80211/ieee80211_i.h | 10 ++- - net/mac80211/tx.c | 134 ++++++++++++++++++++++++++++++++++--- - 4 files changed, 205 insertions(+), 18 deletions(-) - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -5252,6 +5252,74 @@ ieee80211_beacon_get_template(struct iee - unsigned int link_id); - - /** -+ * ieee80211_beacon_get_template_ema_index - EMA beacon template generation -+ * @hw: pointer obtained from ieee80211_alloc_hw(). -+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -+ * @offs: &struct ieee80211_mutable_offsets pointer to struct that will -+ * receive the offsets that may be updated by the driver. -+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP). -+ * @ema_index: index of the beacon in the EMA set. -+ * -+ * This function follows the same rules as ieee80211_beacon_get_template() -+ * but returns a beacon template which includes multiple BSSID element at the -+ * requested index. -+ * -+ * Return: The beacon template. %NULL indicates the end of EMA templates. -+ */ -+struct sk_buff * -+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_mutable_offsets *offs, -+ unsigned int link_id, u8 ema_index); -+ -+/** -+ * struct ieee80211_ema_beacons - List of EMA beacons -+ * @cnt: count of EMA beacons. -+ * -+ * @bcn: array of EMA beacons. -+ * @bcn.skb: the skb containing this specific beacon -+ * @bcn.offs: &struct ieee80211_mutable_offsets pointer to struct that will -+ * receive the offsets that may be updated by the driver. -+ */ -+struct ieee80211_ema_beacons { -+ u8 cnt; -+ struct { -+ struct sk_buff *skb; -+ struct ieee80211_mutable_offsets offs; -+ } bcn[]; -+}; -+ -+/** -+ * ieee80211_beacon_get_template_ema_list - EMA beacon template generation -+ * @hw: pointer obtained from ieee80211_alloc_hw(). -+ * @vif: &struct ieee80211_vif pointer from the add_interface callback. -+ * @link_id: the link id to which the beacon belongs (or 0 for a non-MLD AP) -+ * -+ * This function follows the same rules as ieee80211_beacon_get_template() -+ * but allocates and returns a pointer to list of all beacon templates required -+ * to cover all profiles in the multiple BSSID set. Each template includes only -+ * one multiple BSSID element. -+ * -+ * Driver must call ieee80211_beacon_free_ema_list() to free the memory. -+ * -+ * Return: EMA beacon templates of type struct ieee80211_ema_beacons *. -+ * %NULL on error. -+ */ -+struct ieee80211_ema_beacons * -+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ unsigned int link_id); -+ -+/** -+ * ieee80211_beacon_free_ema_list - free an EMA beacon template list -+ * @ema_beacons: list of EMA beacons of type &struct ieee80211_ema_beacons pointers. -+ * -+ * This function will free a list previously acquired by calling -+ * ieee80211_beacon_get_template_ema_list() -+ */ -+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons); -+ -+/** - * ieee80211_beacon_get_tim - beacon generation function - * @hw: pointer obtained from ieee80211_alloc_hw(). - * @vif: &struct ieee80211_vif pointer from the add_interface callback. ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1122,11 +1122,11 @@ static int ieee80211_assign_beacon(struc - if (params->mbssid_ies) { - mbssid = params->mbssid_ies; - size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -- size += ieee80211_get_mbssid_beacon_len(mbssid); -+ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); - } else if (old && old->mbssid_ies) { - mbssid = old->mbssid_ies; - size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -- size += ieee80211_get_mbssid_beacon_len(mbssid); -+ size += ieee80211_get_mbssid_beacon_len(mbssid, mbssid->cnt); - } - - new = kzalloc(size, GFP_KERNEL); -@@ -3384,8 +3384,11 @@ cfg80211_beacon_dup(struct cfg80211_beac - - len = beacon->head_len + beacon->tail_len + beacon->beacon_ies_len + - beacon->proberesp_ies_len + beacon->assocresp_ies_len + -- beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + -- ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); -+ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len; -+ -+ if (beacon->mbssid_ies) -+ len += ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, -+ beacon->mbssid_ies->cnt); - - new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); - if (!new_beacon) ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1182,13 +1182,17 @@ ieee80211_vif_get_shift(struct ieee80211 - } - - static inline int --ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) -+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, u8 i) - { -- int i, len = 0; -+ int len = 0; - -- if (!elems) -+ if (!elems || !elems->cnt || i > elems->cnt) - return 0; - -+ if (i < elems->cnt) -+ return elems->elem[i].len; -+ -+ /* i == elems->cnt, calculate total length of all MBSSID elements */ - for (i = 0; i < elems->cnt; i++) - len += elems->elem[i].len; - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -5205,13 +5205,20 @@ ieee80211_beacon_get_finish(struct ieee8 - } - - static void --ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) -+ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon, -+ u8 i) - { -- int i; -+ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt || -+ i > beacon->mbssid_ies->cnt) -+ return; - -- if (!beacon->mbssid_ies) -+ if (i < beacon->mbssid_ies->cnt) { -+ skb_put_data(skb, beacon->mbssid_ies->elem[i].data, -+ beacon->mbssid_ies->elem[i].len); - return; -+ } - -+ /* i == beacon->mbssid_ies->cnt, include all MBSSID elements */ - for (i = 0; i < beacon->mbssid_ies->cnt; i++) - skb_put_data(skb, beacon->mbssid_ies->elem[i].data, - beacon->mbssid_ies->elem[i].len); -@@ -5224,7 +5231,8 @@ ieee80211_beacon_get_ap(struct ieee80211 - struct ieee80211_mutable_offsets *offs, - bool is_template, - struct beacon_data *beacon, -- struct ieee80211_chanctx_conf *chanctx_conf) -+ struct ieee80211_chanctx_conf *chanctx_conf, -+ u8 ema_index) - { - struct ieee80211_local *local = hw_to_local(hw); - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -@@ -5243,7 +5251,9 @@ ieee80211_beacon_get_ap(struct ieee80211 - /* headroom, head length, - * tail length, maximum TIM length and multiple BSSID length - */ -- mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); -+ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies, -+ ema_index); -+ - skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + - beacon->tail_len + 256 + - local->hw.extra_beacon_tailroom + mbssid_len); -@@ -5261,7 +5271,7 @@ ieee80211_beacon_get_ap(struct ieee80211 - offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; - - if (mbssid_len) { -- ieee80211_beacon_add_mbssid(skb, beacon); -+ ieee80211_beacon_add_mbssid(skb, beacon, ema_index); - offs->mbssid_off = skb->len - mbssid_len; - } - -@@ -5280,12 +5290,51 @@ ieee80211_beacon_get_ap(struct ieee80211 - return skb; - } - -+static struct ieee80211_ema_beacons * -+ieee80211_beacon_get_ap_ema_list(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_link_data *link, -+ struct ieee80211_mutable_offsets *offs, -+ bool is_template, struct beacon_data *beacon, -+ struct ieee80211_chanctx_conf *chanctx_conf) -+{ -+ struct ieee80211_ema_beacons *ema = NULL; -+ -+ if (!beacon->mbssid_ies || !beacon->mbssid_ies->cnt) -+ return NULL; -+ -+ ema = kzalloc(struct_size(ema, bcn, beacon->mbssid_ies->cnt), -+ GFP_ATOMIC); -+ if (!ema) -+ return NULL; -+ -+ for (ema->cnt = 0; ema->cnt < beacon->mbssid_ies->cnt; ema->cnt++) { -+ ema->bcn[ema->cnt].skb = -+ ieee80211_beacon_get_ap(hw, vif, link, -+ &ema->bcn[ema->cnt].offs, -+ is_template, beacon, -+ chanctx_conf, ema->cnt); -+ if (!ema->bcn[ema->cnt].skb) -+ break; -+ } -+ -+ if (ema->cnt == beacon->mbssid_ies->cnt) -+ return ema; -+ -+ ieee80211_beacon_free_ema_list(ema); -+ return NULL; -+} -+ -+#define IEEE80211_INCLUDE_ALL_MBSSID_ELEMS -1 -+ - static struct sk_buff * - __ieee80211_beacon_get(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - struct ieee80211_mutable_offsets *offs, - bool is_template, -- unsigned int link_id) -+ unsigned int link_id, -+ int ema_index, -+ struct ieee80211_ema_beacons **ema_beacons) - { - struct ieee80211_local *local = hw_to_local(hw); - struct beacon_data *beacon = NULL; -@@ -5314,8 +5363,29 @@ __ieee80211_beacon_get(struct ieee80211_ - if (!beacon) - goto out; - -- skb = ieee80211_beacon_get_ap(hw, vif, link, offs, is_template, -- beacon, chanctx_conf); -+ if (ema_beacons) { -+ *ema_beacons = -+ ieee80211_beacon_get_ap_ema_list(hw, vif, link, -+ offs, -+ is_template, -+ beacon, -+ chanctx_conf); -+ } else { -+ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { -+ if (ema_index >= beacon->mbssid_ies->cnt) -+ goto out; /* End of MBSSID elements */ -+ -+ if (ema_index <= IEEE80211_INCLUDE_ALL_MBSSID_ELEMS) -+ ema_index = beacon->mbssid_ies->cnt; -+ } else { -+ ema_index = 0; -+ } -+ -+ skb = ieee80211_beacon_get_ap(hw, vif, link, offs, -+ is_template, beacon, -+ chanctx_conf, -+ ema_index); -+ } - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - struct ieee80211_hdr *hdr; -@@ -5403,10 +5473,50 @@ ieee80211_beacon_get_template(struct iee - struct ieee80211_mutable_offsets *offs, - unsigned int link_id) - { -- return __ieee80211_beacon_get(hw, vif, offs, true, link_id); -+ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, -+ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, NULL); - } - EXPORT_SYMBOL(ieee80211_beacon_get_template); - -+struct sk_buff * -+ieee80211_beacon_get_template_ema_index(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_mutable_offsets *offs, -+ unsigned int link_id, u8 ema_index) -+{ -+ return __ieee80211_beacon_get(hw, vif, offs, true, link_id, ema_index, -+ NULL); -+} -+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_index); -+ -+void ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *ema_beacons) -+{ -+ u8 i; -+ -+ if (!ema_beacons) -+ return; -+ -+ for (i = 0; i < ema_beacons->cnt; i++) -+ kfree_skb(ema_beacons->bcn[i].skb); -+ -+ kfree(ema_beacons); -+} -+EXPORT_SYMBOL(ieee80211_beacon_free_ema_list); -+ -+struct ieee80211_ema_beacons * -+ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ unsigned int link_id) -+{ -+ struct ieee80211_ema_beacons *ema_beacons = NULL; -+ -+ WARN_ON(__ieee80211_beacon_get(hw, vif, NULL, false, link_id, 0, -+ &ema_beacons)); -+ -+ return ema_beacons; -+} -+EXPORT_SYMBOL(ieee80211_beacon_get_template_ema_list); -+ - struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, - u16 *tim_offset, u16 *tim_length, -@@ -5414,7 +5524,9 @@ struct sk_buff *ieee80211_beacon_get_tim - { - struct ieee80211_mutable_offsets offs = {}; - struct sk_buff *bcn = __ieee80211_beacon_get(hw, vif, &offs, false, -- link_id); -+ link_id, -+ IEEE80211_INCLUDE_ALL_MBSSID_ELEMS, -+ NULL); - struct sk_buff *copy; - int shift; - diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch deleted file mode 100644 index 67b4284949..0000000000 --- a/package/kernel/mac80211/patches/subsys/337-mac80211-fix-sband-iftype-data-lookup-for-AP_VLAN.patch +++ /dev/null @@ -1,23 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Thu, 22 Jun 2023 18:02:25 +0200 -Subject: [PATCH] mac80211: fix sband iftype data lookup for AP_VLAN - -AP_VLAN interfaces are virtual, so doesn't really exist as a type for -capabilities. When passed in as a type, AP is the one that's really intended. - -Fixes: c4cbaf7973a7 ("cfg80211: Add support for HE") -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -567,6 +567,9 @@ ieee80211_get_sband_iftype_data(const st - if (WARN_ON(iftype >= NL80211_IFTYPE_MAX)) - return NULL; - -+ if (iftype == NL80211_IFTYPE_AP_VLAN) -+ iftype = NL80211_IFTYPE_AP; -+ - for (i = 0; i < sband->n_iftype_data; i++) { - const struct ieee80211_sband_iftype_data *data = - &sband->iftype_data[i]; diff --git a/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch b/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch deleted file mode 100644 index e32c6ae1f3..0000000000 --- a/package/kernel/mac80211/patches/subsys/339-wifi-cfg80211-fix-receving-mesh-packets-without-RFC1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau <nbd@nbd.name> -Date: Tue, 11 Jul 2023 13:30:12 +0200 -Subject: [PATCH] wifi: cfg80211: fix receving mesh packets without RFC1042 - header - -Fix ethernet header length field after stripping the mesh header - -Cc: stable@vger.kernel.org -Link: https://lore.kernel.org/all/CT5GNZSK28AI.2K6M69OXM9RW5@syracuse/ -Fixes: 986e43b19ae9 ("wifi: mac80211: fix receiving A-MSDU frames on mesh interfaces") -Reported-by: Nicolas Escande <nico.escande@gmail.com> -Signed-off-by: Felix Fietkau <nbd@nbd.name> ---- - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -580,6 +580,8 @@ int ieee80211_strip_8023_mesh_hdr(struct - hdrlen += ETH_ALEN + 2; - else if (!pskb_may_pull(skb, hdrlen)) - return -EINVAL; -+ else -+ payload.eth.h_proto = htons(skb->len - hdrlen); - - mesh_addr = skb->data + sizeof(payload.eth) + ETH_ALEN; - switch (payload.flags & MESH_FLAGS_AE) { diff --git a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch index c38fa13f03..ad24dfda5a 100644 --- a/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch +++ b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch @@ -16,7 +16,7 @@ and we should ignore this. --- a/net/wireless/core.c +++ b/net/wireless/core.c -@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str +@@ -649,21 +649,6 @@ static int wiphy_verify_combinations(str c->limits[j].max > 1)) return -EINVAL; |