From 8d90b9fef1ef6b01228c6af73cf06ecbe5d0adaf Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sat, 10 Dec 2022 12:36:44 +0100 Subject: mac80211: update to linux 6.1-rc8 This should help stay in sync with upstream development Signed-off-by: Felix Fietkau --- .../subsys/110-mac80211_keep_keys_on_stop_ap.patch | 6 +- .../patches/subsys/150-disable_addr_notifier.patch | 75 -- .../mac80211/patches/subsys/210-ap_scan.patch | 16 +- ...a-randomize-BA-session-dialog-token-alloc.patch | 2 +- ...80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch | 21 + ...nstrel_ht-reduce-fluctuations-in-rate-pro.patch | 30 + ...et-up-the-fwd_skb-dev-for-mesh-forwarding.patch | 62 - ...nstrel_ht-rework-rate-downgrade-code-and-.patch | 151 +++ ...11-increase-quantum-for-airtime-scheduler.patch | 53 + ...11-add-internal-handler-for-wake_tx_queue.patch | 192 +++ ...211-add-wake_tx_queue-callback-to-drivers.patch | 396 +++++++ ...fi-mac80211-Drop-support-for-TX-push-path.patch | 655 ++++++++++ ...i-realtek-remove-duplicated-wake_tx_queue.patch | 32 + ...e-coarse-boottime-for-airtime-fairness-co.patch | 60 - ...mac80211_hwsim-make-6-GHz-channels-usable.patch | 74 -- ...11-add-support-for-.ndo_fill_forward_path.patch | 178 --- ...80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch | 21 - ...d-support-for-restricting-netdev-features.patch | 506 ++++++++ ...nstrel_ht-reduce-fluctuations-in-rate-pro.patch | 30 - ...nstrel_ht-rework-rate-downgrade-code-and-.patch | 151 --- ...mac80211-split-beacon-retrieval-functions.patch | 262 ---- ...nl80211-MBSSID-and-EMA-support-in-AP-mode.patch | 493 -------- ...plement-APIs-for-dedicated-radar-detectio.patch | 378 ------ ...ove-offchan_cac_event-to-a-dedicated-work.patch | 183 --- ...x-possible-NULL-pointer-dereference-in-cf.patch | 99 -- ...hedule-offchan_cac_abort_wk-in-cfg80211_r.patch | 136 --- ...low-continuous-radar-monitoring-on-offcha.patch | 220 ---- ...0211-introduce-set_radar_offchan-callback.patch | 67 -- ...name-offchannel_chain-structs-to-backgrou.patch | 532 --------- ...0211-MBSSID-support-in-interface-handling.patch | 144 --- ...ac80211-MBSSID-beacon-handling-in-AP-mode.patch | 326 ----- .../325-v5.18-mac80211-MBSSID-channel-switch.patch | 52 - ...date-bssid_indicator-in-ieee80211_assign_.patch | 25 - ...-not-wake-queues-on-a-vif-that-is-being-s.patch | 38 - ...itch-airtime-fairness-back-to-deficit-rou.patch | 1249 -------------------- ...ke-sta-airtime-deficit-field-s32-instead-.patch | 52 - ...nsider-aql_tx_pending-when-checking-airti.patch | 48 - ...ep-recently-active-tx-queues-in-schedulin.patch | 118 -- ...d-a-per-PHY-AQL-limit-to-improve-fairness.patch | 131 -- ...d-debugfs-file-to-display-per-phy-AQL-pen.patch | 58 - ...ly-accumulate-airtime-deficit-for-active-.patch | 36 - ...11-increase-quantum-for-airtime-scheduler.patch | 53 - ...clude-multicast-packets-from-AQL-pending-.patch | 30 - ...11-do-not-abuse-fq.lock-in-ieee80211_do_s.patch | 46 - ...x-deadlock-Don-t-start-TX-while-holding-f.patch | 40 - ...sure-vif-queues-are-operational-after-sta.patch | 47 - ...11-fix-decap-offload-for-stations-on-AP_V.patch | 37 - ...11-fix-ieee80211_data_to_8023_exthdr-hand.patch | 99 -- ...11-do-not-drop-packets-smaller-than-the-L.patch | 25 - ...11-fix-mesh-airtime-link-metric-estimatin.patch | 36 - .../subsys/363-v5.19-bss-color-collision.patch | 118 -- ...d-support-for-restricting-netdev-features.patch | 513 -------- .../patches/subsys/400-allow-ibss-mixed.patch | 2 +- .../500-mac80211_configure_antenna_gain.patch | 40 +- .../mac80211/patches/subsys/783-sync-nl80211.patch | 22 - ...80211-mask-nested-A-MSDU-support-for-mesh.patch | 2 +- 56 files changed, 2070 insertions(+), 6398 deletions(-) delete mode 100644 package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch create mode 100644 package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch create mode 100644 package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch delete mode 100644 package/kernel/mac80211/patches/subsys/303-v5.16-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch create mode 100644 package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch create mode 100644 package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch create mode 100644 package/kernel/mac80211/patches/subsys/306-01-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch create mode 100644 package/kernel/mac80211/patches/subsys/306-02-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch create mode 100644 package/kernel/mac80211/patches/subsys/306-03-wifi-mac80211-Drop-support-for-TX-push-path.patch create mode 100644 package/kernel/mac80211/patches/subsys/306-04-wifi-realtek-remove-duplicated-wake_tx_queue.patch delete mode 100644 package/kernel/mac80211/patches/subsys/306-v5.17-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch delete mode 100644 package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch delete mode 100644 package/kernel/mac80211/patches/subsys/308-v5.17-mac80211-add-support-for-.ndo_fill_forward_path.patch delete mode 100644 package/kernel/mac80211/patches/subsys/309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch create mode 100644 package/kernel/mac80211/patches/subsys/310-mac80211-add-support-for-restricting-netdev-features.patch delete mode 100644 package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch delete mode 100644 package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch delete mode 100644 package/kernel/mac80211/patches/subsys/312-v5.16-mac80211-split-beacon-retrieval-functions.patch delete mode 100644 package/kernel/mac80211/patches/subsys/313-v5.16-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/subsys/314-v5.17-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch delete mode 100644 package/kernel/mac80211/patches/subsys/315-v5.17-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch delete mode 100644 package/kernel/mac80211/patches/subsys/316-v5.17-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch delete mode 100644 package/kernel/mac80211/patches/subsys/317-v5.17-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch delete mode 100644 package/kernel/mac80211/patches/subsys/318-v5.17-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch delete mode 100644 package/kernel/mac80211/patches/subsys/319-v5.17-mac80211-introduce-set_radar_offchan-callback.patch delete mode 100644 package/kernel/mac80211/patches/subsys/320-v5.17-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch delete mode 100644 package/kernel/mac80211/patches/subsys/323-v5.16-mac80211-MBSSID-support-in-interface-handling.patch delete mode 100644 package/kernel/mac80211/patches/subsys/324-v5.18-mac80211-MBSSID-beacon-handling-in-AP-mode.patch delete mode 100644 package/kernel/mac80211/patches/subsys/325-v5.18-mac80211-MBSSID-channel-switch.patch delete mode 100644 package/kernel/mac80211/patches/subsys/326-v5.18-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch delete mode 100644 package/kernel/mac80211/patches/subsys/328-v5.19-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch delete mode 100644 package/kernel/mac80211/patches/subsys/330-v6.0-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch delete mode 100644 package/kernel/mac80211/patches/subsys/331-v6.0-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch delete mode 100644 package/kernel/mac80211/patches/subsys/332-v6.0-mac80211-consider-aql_tx_pending-when-checking-airti.patch delete mode 100644 package/kernel/mac80211/patches/subsys/333-v6.0-mac80211-keep-recently-active-tx-queues-in-schedulin.patch delete mode 100644 package/kernel/mac80211/patches/subsys/334-v6.0-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch delete mode 100644 package/kernel/mac80211/patches/subsys/335-v6.0-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch delete mode 100644 package/kernel/mac80211/patches/subsys/336-v6.0-mac80211-only-accumulate-airtime-deficit-for-active-.patch delete mode 100644 package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch delete mode 100644 package/kernel/mac80211/patches/subsys/339-v6.0-mac80211-exclude-multicast-packets-from-AQL-pending-.patch delete mode 100644 package/kernel/mac80211/patches/subsys/340-v5.19-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch delete mode 100644 package/kernel/mac80211/patches/subsys/341-v6.0-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch delete mode 100644 package/kernel/mac80211/patches/subsys/342-v6.0-mac80211-Ensure-vif-queues-are-operational-after-sta.patch delete mode 100644 package/kernel/mac80211/patches/subsys/343-v6.1-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch delete mode 100644 package/kernel/mac80211/patches/subsys/344-v6.1-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch delete mode 100644 package/kernel/mac80211/patches/subsys/345-v6.1-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch delete mode 100644 package/kernel/mac80211/patches/subsys/346-v6.0-wifi-mac80211-fix-mesh-airtime-link-metric-estimatin.patch delete mode 100644 package/kernel/mac80211/patches/subsys/363-v5.19-bss-color-collision.patch delete mode 100644 package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch delete mode 100644 package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch (limited to 'package/kernel/mac80211/patches/subsys') 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 397026b80b..4dd26da2ec 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,11 +9,11 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnect --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1319,7 +1319,6 @@ static int ieee80211_stop_ap(struct wiph - sdata->vif.bss_conf.ftmr_params = NULL; +@@ -1512,7 +1512,6 @@ static int ieee80211_stop_ap(struct wiph + link_conf->ftmr_params = NULL; __sta_info_flush(sdata, true); - ieee80211_free_keys(sdata, true); - sdata->vif.bss_conf.enable_beacon = false; + link_conf->enable_beacon = false; sdata->beacon_rate_set = false; diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch deleted file mode 100644 index 7ad5427ceb..0000000000 --- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Felix Fietkau -Date: Sun, 24 Feb 2013 00:00:00 +0100 -Subject: [PATCH] mac80211: disable ipv4/ipv6 address notifiers - ---- - net/mac80211/main.c | 18 +++++++++--------- - 1 file changed, 9 insertions(+), 9 deletions(-) - ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -337,7 +337,7 @@ void ieee80211_restart_hw(struct ieee802 - } - EXPORT_SYMBOL(ieee80211_restart_hw); - --#ifdef CONFIG_INET -+#ifdef __disabled__CONFIG_INET - static int ieee80211_ifa_changed(struct notifier_block *nb, - unsigned long data, void *arg) - { -@@ -396,7 +396,7 @@ static int ieee80211_ifa_changed(struct - } - #endif - --#if IS_ENABLED(CONFIG_IPV6) -+#if IS_ENABLED(__disabled__CONFIG_IPV6) - static int ieee80211_ifa6_changed(struct notifier_block *nb, - unsigned long data, void *arg) - { -@@ -1321,14 +1321,14 @@ int ieee80211_register_hw(struct ieee802 - wiphy_unlock(hw->wiphy); - rtnl_unlock(); - --#ifdef CONFIG_INET -+#ifdef __disabled__CONFIG_INET - local->ifa_notifier.notifier_call = ieee80211_ifa_changed; - result = register_inetaddr_notifier(&local->ifa_notifier); - if (result) - goto fail_ifa; - #endif - --#if IS_ENABLED(CONFIG_IPV6) -+#if IS_ENABLED(__disabled__CONFIG_IPV6) - local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; - result = register_inet6addr_notifier(&local->ifa6_notifier); - if (result) -@@ -1337,13 +1337,13 @@ int ieee80211_register_hw(struct ieee802 - - return 0; - --#if IS_ENABLED(CONFIG_IPV6) -+#if IS_ENABLED(__disabled__CONFIG_IPV6) - fail_ifa6: --#ifdef CONFIG_INET -+#ifdef __disabled__CONFIG_INET - unregister_inetaddr_notifier(&local->ifa_notifier); - #endif - #endif --#if defined(CONFIG_INET) || defined(CONFIG_IPV6) -+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6) - fail_ifa: - #endif - wiphy_unregister(local->hw.wiphy); -@@ -1373,10 +1373,10 @@ void ieee80211_unregister_hw(struct ieee - tasklet_kill(&local->tx_pending_tasklet); - tasklet_kill(&local->tasklet); - --#ifdef CONFIG_INET -+#ifdef __disabled__CONFIG_INET - unregister_inetaddr_notifier(&local->ifa_notifier); - #endif --#if IS_ENABLED(CONFIG_IPV6) -+#if IS_ENABLED(__disabled__CONFIG_IPV6) - unregister_inet6addr_notifier(&local->ifa6_notifier); - #endif - diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index 9b8e084232..bfbb28c55c 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -8,12 +8,12 @@ Subject: [PATCH] mac80211: allow scans in access point mode (for site survey) --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2497,7 +2497,7 @@ static int ieee80211_scan(struct wiphy * - * the frames sent while scanning on other channel will be - * lost) +@@ -2720,6 +2720,8 @@ static int ieee80211_scan(struct wiphy * */ -- if (sdata->u.ap.beacon && -+ if (0 && sdata->u.ap.beacon && - (!(wiphy->features & NL80211_FEATURE_AP_SCAN) || - !(req->flags & NL80211_SCAN_FLAG_AP))) - return -EOPNOTSUPP; + fallthrough; + case NL80211_IFTYPE_AP: ++ /* skip check */ ++ break; + /* + * If the scan has been forced (and the driver supports + * forcing), don't care about being beaconing already. 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 d09d70725e..63b2177471 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 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c -@@ -357,6 +357,7 @@ struct sta_info *sta_info_alloc(struct i +@@ -554,6 +554,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/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch b/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch new file mode 100644 index 0000000000..0d475b7329 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/302-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Wed, 28 Apr 2021 21:03:13 +0200 +Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro + +Add missing braces to avoid issues with e.g. using additions in the +div expression + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -14,7 +14,7 @@ + + /* scaled fraction values */ + #define MINSTREL_SCALE 12 +-#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) ++#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div)) + #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) + + #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch new file mode 100644 index 0000000000..f26477e811 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch @@ -0,0 +1,30 @@ +From: Felix Fietkau +Date: Sat, 6 Feb 2021 16:08:01 +0100 +Subject: [PATCH] mac80211: minstrel_ht: reduce fluctuations in rate + probability stats + +In some scenarios when there is a lot of fluctuation in packet error rates, +rate switching can be amplified when the statistics get skewed by time slots +with very few tries. +Make the input data to the moving average more smooth by adding the +success/attempts count from the last stats window as well. This has the +advantage of smoothing the data without introducing any extra lag to sampling +rates. +This significantly improves rate stability on a strong test link subjected to +periodic noise bursts generated with a SDR + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -769,7 +769,8 @@ minstrel_ht_calc_rate_stats(struct minst + unsigned int cur_prob; + + if (unlikely(mrs->attempts > 0)) { +- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); ++ cur_prob = MINSTREL_FRAC(mrs->success + mrs->last_success, ++ mrs->attempts + mrs->last_attempts); + minstrel_filter_avg_add(&mrs->prob_avg, + &mrs->prob_avg_1, cur_prob); + mrs->att_hist += mrs->attempts; diff --git a/package/kernel/mac80211/patches/subsys/303-v5.16-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch b/package/kernel/mac80211/patches/subsys/303-v5.16-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch deleted file mode 100644 index 159aad564b..0000000000 --- a/package/kernel/mac80211/patches/subsys/303-v5.16-mac80211-set-up-the-fwd_skb-dev-for-mesh-forwarding.patch +++ /dev/null @@ -1,62 +0,0 @@ -From: Xing Song -Date: Tue, 23 Nov 2021 11:31:23 +0800 -Subject: [PATCH] mac80211: set up the fwd_skb->dev for mesh forwarding - -Mesh forwarding requires that the fwd_skb->dev is set up for TX handling, -otherwise the following warning will be generated, so set it up for the -pending frames. - -[ 72.835674 ] WARNING: CPU: 0 PID: 1193 at __skb_flow_dissect+0x284/0x1298 -[ 72.842379 ] Modules linked in: ksmbd pppoe ppp_async l2tp_ppp ... -[ 72.962020 ] CPU: 0 PID: 1193 Comm: kworker/u5:1 Tainted: P S 5.4.137 #0 -[ 72.969938 ] Hardware name: MT7622_MT7531 RFB (DT) -[ 72.974659 ] Workqueue: napi_workq napi_workfn -[ 72.979025 ] pstate: 60000005 (nZCv daif -PAN -UAO) -[ 72.983822 ] pc : __skb_flow_dissect+0x284/0x1298 -[ 72.988444 ] lr : __skb_flow_dissect+0x54/0x1298 -[ 72.992977 ] sp : ffffffc010c738c0 -[ 72.996293 ] x29: ffffffc010c738c0 x28: 0000000000000000 -[ 73.001615 ] x27: 000000000000ffc2 x26: ffffff800c2eb818 -[ 73.006937 ] x25: ffffffc010a987c8 x24: 00000000000000ce -[ 73.012259 ] x23: ffffffc010c73a28 x22: ffffffc010a99c60 -[ 73.017581 ] x21: 000000000000ffc2 x20: ffffff80094da800 -[ 73.022903 ] x19: 0000000000000000 x18: 0000000000000014 -[ 73.028226 ] x17: 00000000084d16af x16: 00000000d1fc0bab -[ 73.033548 ] x15: 00000000715f6034 x14: 000000009dbdd301 -[ 73.038870 ] x13: 00000000ea4dcbc3 x12: 0000000000000040 -[ 73.044192 ] x11: 000000000eb00ff0 x10: 0000000000000000 -[ 73.049513 ] x9 : 000000000eb00073 x8 : 0000000000000088 -[ 73.054834 ] x7 : 0000000000000000 x6 : 0000000000000001 -[ 73.060155 ] x5 : 0000000000000000 x4 : 0000000000000000 -[ 73.065476 ] x3 : ffffffc010a98000 x2 : 0000000000000000 -[ 73.070797 ] x1 : 0000000000000000 x0 : 0000000000000000 -[ 73.076120 ] Call trace: -[ 73.078572 ] __skb_flow_dissect+0x284/0x1298 -[ 73.082846 ] __skb_get_hash+0x7c/0x228 -[ 73.086629 ] ieee80211_txq_may_transmit+0x7fc/0x17b8 [mac80211] -[ 73.092564 ] ieee80211_tx_prepare_skb+0x20c/0x268 [mac80211] -[ 73.098238 ] ieee80211_tx_pending+0x144/0x330 [mac80211] -[ 73.103560 ] tasklet_action_common.isra.16+0xb4/0x158 -[ 73.108618 ] tasklet_action+0x2c/0x38 -[ 73.112286 ] __do_softirq+0x168/0x3b0 -[ 73.115954 ] do_softirq.part.15+0x88/0x98 -[ 73.119969 ] __local_bh_enable_ip+0xb0/0xb8 -[ 73.124156 ] napi_workfn+0x58/0x90 -[ 73.127565 ] process_one_work+0x20c/0x478 -[ 73.131579 ] worker_thread+0x50/0x4f0 -[ 73.135249 ] kthread+0x124/0x128 -[ 73.138484 ] ret_from_fork+0x10/0x1c - -Signed-off-by: Xing Song ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2950,6 +2950,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 - 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); diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch new file mode 100644 index 0000000000..9b3cc3a664 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch @@ -0,0 +1,151 @@ +From: Felix Fietkau +Date: Sat, 6 Feb 2021 16:33:14 +0100 +Subject: [PATCH] mac80211: minstrel_ht: rework rate downgrade code and + max_prob rate selection + +The current fallback code for fast rate switching on potentially failing rates +is triggering too often if there is some strong noise on the channel. This can +lead to wild fluctuations in the rate selection. +Additionally, switching down to max_prob_rate can create a significant gap down +in throughput, especially when using only 2 spatial streams, because max_prob_rate +is limited to using fewer streams than the max_tp rates. +In order to improve throughput without reducing reliability too much, use the +rate downgrade code for the max_prob_rate only, and allow the non-downgraded +max_prob_rate to use as many spatial streams as the max_tp rates + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -580,6 +580,14 @@ minstrel_ht_set_best_prob_rate(struct mi + int cur_tp_avg, cur_group, cur_idx; + int max_gpr_group, max_gpr_idx; + int max_gpr_tp_avg, max_gpr_prob; ++ int min_dur; ++ ++ min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]), ++ minstrel_get_duration(mi->max_tp_rate[1])); ++ ++ /* make the rate at least 18% slower than max tp rates */ ++ if (minstrel_get_duration(index) <= min_dur * 19 / 16) ++ return; + + cur_group = MI_RATE_GROUP(index); + cur_idx = MI_RATE_IDX(index); +@@ -601,11 +609,6 @@ minstrel_ht_set_best_prob_rate(struct mi + !minstrel_ht_is_legacy_group(max_tp_group)) + return; + +- /* skip rates faster than max tp rate with lower prob */ +- if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && +- mrs->prob_avg < max_tp_prob) +- return; +- + max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); + max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); + max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; +@@ -663,40 +666,6 @@ minstrel_ht_assign_best_tp_rates(struct + + } + +-/* +- * Try to increase robustness of max_prob rate by decrease number of +- * streams if possible. +- */ +-static inline void +-minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) +-{ +- struct minstrel_mcs_group_data *mg; +- int tmp_max_streams, group, tmp_idx, tmp_prob; +- int tmp_tp = 0; +- +- if (!mi->sta->deflink.ht_cap.ht_supported) +- return; +- +- group = MI_RATE_GROUP(mi->max_tp_rate[0]); +- tmp_max_streams = minstrel_mcs_groups[group].streams; +- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { +- mg = &mi->groups[group]; +- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) +- continue; +- +- tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); +- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; +- +- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && +- (minstrel_mcs_groups[group].streams < tmp_max_streams)) { +- mi->max_prob_rate = mg->max_group_prob_rate; +- tmp_tp = minstrel_ht_get_tp_avg(mi, group, +- tmp_idx, +- tmp_prob); +- } +- } +-} +- + static u16 + __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, + enum minstrel_sample_type type) +@@ -1176,8 +1145,6 @@ minstrel_ht_update_stats(struct minstrel + + mi->max_prob_rate = tmp_max_prob_rate; + +- /* Try to increase robustness of max_prob_rate*/ +- minstrel_ht_prob_rate_reduce_streams(mi); + minstrel_ht_refill_sample_rates(mi); + + #ifdef CPTCFG_MAC80211_DEBUGFS +@@ -1256,7 +1223,7 @@ minstrel_ht_ri_txstat_valid(struct minst + } + + static void +-minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) ++minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx) + { + int group, orig_group; + +@@ -1271,11 +1238,7 @@ minstrel_downgrade_rate(struct minstrel_ + minstrel_mcs_groups[orig_group].streams) + continue; + +- if (primary) +- *idx = mi->groups[group].max_group_tp_rate[0]; +- else +- *idx = mi->groups[group].max_group_tp_rate[1]; +- break; ++ *idx = mi->groups[group].max_group_prob_rate; + } + } + +@@ -1286,7 +1249,7 @@ minstrel_ht_tx_status(void *priv, struct + struct ieee80211_tx_info *info = st->info; + struct minstrel_ht_sta *mi = priv_sta; + struct ieee80211_tx_rate *ar = info->status.rates; +- struct minstrel_rate_stats *rate, *rate2; ++ struct minstrel_rate_stats *rate; + struct minstrel_priv *mp = priv; + u32 update_interval = mp->update_interval; + bool last, update = false; +@@ -1354,18 +1317,13 @@ minstrel_ht_tx_status(void *priv, struct + /* + * check for sudden death of spatial multiplexing, + * downgrade to a lower number of streams if necessary. ++ * only do this for the max_prob_rate to prevent spurious ++ * rate fluctuations when the link changes suddenly + */ +- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); ++ rate = minstrel_get_ratestats(mi, mi->max_prob_rate); + if (rate->attempts > 30 && + rate->success < rate->attempts / 4) { +- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); +- update = true; +- } +- +- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); +- if (rate2->attempts > 30 && +- rate2->success < rate2->attempts / 4) { +- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); ++ minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate); + update = true; + } + } 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 new file mode 100644 index 0000000000..d541b621fd --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/305-mac80211-increase-quantum-for-airtime-scheduler.patch @@ -0,0 +1,53 @@ +From: Felix Fietkau +Date: Sun, 26 Jun 2022 11:43:25 +0200 +Subject: [PATCH] mac80211: increase quantum for airtime scheduler + +Given the typical AQL budget and queue length, a quantum of 256 with the +default station weight often requires iterating over all queues frequently, +until one of them becomes eligible. +Improve performance by using 8 times station weight as scheduler quantum + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask + */ + #define AIRTIME_ACTIVE_DURATION (HZ / 10) + ++#define AIRTIME_QUANTUM_SHIFT 3 ++ + struct ieee80211_bss { + u32 device_ts_beacon, device_ts_presp; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3976,7 +3976,7 @@ struct ieee80211_txq *ieee80211_next_txq + + if (deficit < 0) + sta->airtime[txqi->txq.ac].deficit += +- sta->airtime_weight; ++ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; + + if (deficit < 0 || !aql_check) { + list_move_tail(&txqi->schedule_order, +@@ -4119,7 +4119,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) +- sta->airtime[ac].deficit += sta->airtime_weight; ++ sta->airtime[ac].deficit += sta->airtime_weight << ++ AIRTIME_QUANTUM_SHIFT; + list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); + } + +@@ -4127,7 +4128,7 @@ bool ieee80211_txq_may_transmit(struct i + if (sta->airtime[ac].deficit >= 0) + goto out; + +- sta->airtime[ac].deficit += sta->airtime_weight; ++ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; + list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); + spin_unlock_bh(&local->active_txq_lock[ac]); + diff --git a/package/kernel/mac80211/patches/subsys/306-01-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-01-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch new file mode 100644 index 0000000000..76869830ce --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-01-wifi-mac80211-add-internal-handler-for-wake_tx_queue.patch @@ -0,0 +1,192 @@ +From: Alexander Wetzel +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 +Signed-off-by: Johannes Berg +--- + +--- 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 +@@ -1826,7 +1827,7 @@ struct ieee80211_vif_cfg { + * for this interface. + * @drv_priv: data area for driver use, will always be aligned to + * sizeof(void \*). +- * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) ++ * @txq: the multicast data TX queue + * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped, + * protected by fq->lock. + * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see +@@ -2252,8 +2253,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 +@@ -5691,7 +5692,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); + +@@ -5700,7 +5701,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); + +@@ -5709,7 +5710,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. + */ +@@ -5720,7 +5721,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); + +@@ -5728,7 +5729,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); + +@@ -6950,6 +6951,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-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch b/package/kernel/mac80211/patches/subsys/306-02-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch new file mode 100644 index 0000000000..8e2c205059 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-02-wifi-mac80211-add-wake_tx_queue-callback-to-drivers.patch @@ -0,0 +1,396 @@ +From: Alexander Wetzel +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 +[add staging drivers] +Signed-off-by: Johannes Berg +--- + +--- 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 +@@ -1355,6 +1355,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 +@@ -8539,6 +8539,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 +@@ -3435,6 +3435,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 +@@ -6304,6 +6304,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 +@@ -6561,6 +6561,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-wifi-mac80211-Drop-support-for-TX-push-path.patch b/package/kernel/mac80211/patches/subsys/306-03-wifi-mac80211-Drop-support-for-TX-push-path.patch new file mode 100644 index 0000000000..9d58345555 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-03-wifi-mac80211-Drop-support-for-TX-push-path.patch @@ -0,0 +1,655 @@ +From: Alexander Wetzel +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 +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -4339,9 +4339,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 +@@ -1056,10 +1056,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 +@@ -2290,7 +2290,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 +@@ -458,12 +458,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) { +@@ -811,13 +805,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) + { +@@ -831,7 +818,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, + }; + +@@ -939,7 +925,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, + }; +@@ -1441,35 +1426,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; +@@ -1499,17 +1455,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) +@@ -2094,9 +2045,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(); + +@@ -2119,30 +2068,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 +@@ -1959,9 +1954,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)) || +@@ -2446,7 +2438,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(); + +@@ -2774,9 +2766,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 +@@ -1599,9 +1599,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; +@@ -1649,9 +1646,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; + +@@ -1668,8 +1662,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) +@@ -4185,12 +4178,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); +@@ -4501,11 +4489,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)) +@@ -4759,9 +4743,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); + +@@ -5954,10 +5935,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 +@@ -446,39 +446,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, +@@ -509,11 +476,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); + + /* +@@ -523,12 +486,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, +@@ -585,10 +546,6 @@ static void __ieee80211_stop_queue(struc + for (ac = 0; ac < n_acs; ac++) { + if (sdata->vif.hw_queue[ac] == queue || + sdata->vif.cab_queue == queue) { +- if (!local->ops->wake_tx_queue) { +- netif_stop_subqueue(sdata->dev, ac); +- continue; +- } + spin_lock(&local->fq.lock); + sdata->vif.txqs_stopped[ac] = true; + spin_unlock(&local->fq.lock); +--- 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,12 +144,15 @@ 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) + { + 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 (sta && (sdata->vif.type == NL80211_IFTYPE_MESH_POINT || + sdata->vif.type == NL80211_IFTYPE_OCB)) +@@ -176,59 +182,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-wifi-realtek-remove-duplicated-wake_tx_queue.patch b/package/kernel/mac80211/patches/subsys/306-04-wifi-realtek-remove-duplicated-wake_tx_queue.patch new file mode 100644 index 0000000000..f0dfc75a78 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-04-wifi-realtek-remove-duplicated-wake_tx_queue.patch @@ -0,0 +1,32 @@ +From: Johannes Berg +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 +--- + +--- 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/306-v5.17-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch b/package/kernel/mac80211/patches/subsys/306-v5.17-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch deleted file mode 100644 index c43cd3acb9..0000000000 --- a/package/kernel/mac80211/patches/subsys/306-v5.17-mac80211-use-coarse-boottime-for-airtime-fairness-co.patch +++ /dev/null @@ -1,60 +0,0 @@ -From: Felix Fietkau -Date: Tue, 14 Dec 2021 17:53:12 +0100 -Subject: [PATCH] mac80211: use coarse boottime for airtime fairness code - -The time values used by the airtime fairness code only need to be accurate -enough to cover station activity detection. -Using ktime_get_coarse_boottime_ns instead of ktime_get_boottime_ns will -drop the accuracy down to jiffies intervals, but at the same time saves -a lot of CPU cycles in a hot path - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3820,7 +3820,7 @@ struct ieee80211_txq *ieee80211_next_txq - { - struct ieee80211_local *local = hw_to_local(hw); - struct airtime_sched_info *air_sched; -- u64 now = ktime_get_boottime_ns(); -+ u64 now = ktime_get_coarse_boottime_ns(); - struct ieee80211_txq *ret = NULL; - struct airtime_info *air_info; - struct txq_info *txqi = NULL; -@@ -3947,7 +3947,7 @@ void ieee80211_update_airtime_weight(str - u64 weight_sum = 0; - - if (unlikely(!now)) -- now = ktime_get_boottime_ns(); -+ now = ktime_get_coarse_boottime_ns(); - - lockdep_assert_held(&air_sched->lock); - -@@ -3973,7 +3973,7 @@ void ieee80211_schedule_txq(struct ieee8 - struct ieee80211_local *local = hw_to_local(hw); - struct txq_info *txqi = to_txq_info(txq); - struct airtime_sched_info *air_sched; -- u64 now = ktime_get_boottime_ns(); -+ u64 now = ktime_get_coarse_boottime_ns(); - struct airtime_info *air_info; - u8 ac = txq->ac; - bool was_active; -@@ -4031,7 +4031,7 @@ static void __ieee80211_unschedule_txq(s - - if (!purge) - airtime_set_active(air_sched, air_info, -- ktime_get_boottime_ns()); -+ ktime_get_coarse_boottime_ns()); - - rb_erase_cached(&txqi->schedule_order, - &air_sched->active_txqs); -@@ -4119,7 +4119,7 @@ bool ieee80211_txq_may_transmit(struct i - if (RB_EMPTY_NODE(&txqi->schedule_order)) - goto out; - -- now = ktime_get_boottime_ns(); -+ now = ktime_get_coarse_boottime_ns(); - - /* Like in ieee80211_next_txq(), make sure the first station in the - * scheduling order is eligible for transmission to avoid starvation. diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch b/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch deleted file mode 100644 index 9c3b38adbf..0000000000 --- a/package/kernel/mac80211/patches/subsys/307-mac80211_hwsim-make-6-GHz-channels-usable.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Felix Fietkau -Date: Mon, 24 May 2021 11:46:09 +0200 -Subject: [PATCH] mac80211_hwsim: make 6 GHz channels usable - -The previous commit that claimed to add 6 GHz channels didn't actually make -them usable, since the 6 GHz band was not registered with mac80211. - -Fixes: 28881922abd7 ("mac80211_hwsim: add 6GHz channels") -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/mac80211_hwsim.c -+++ b/drivers/net/wireless/mac80211_hwsim.c -@@ -3008,15 +3008,19 @@ static void mac80211_hwsim_he_capab(stru - { - u16 n_iftype_data; - -- if (sband->band == NL80211_BAND_2GHZ) { -+ switch (sband->band) { -+ case NL80211_BAND_2GHZ: - n_iftype_data = ARRAY_SIZE(he_capa_2ghz); - sband->iftype_data = - (struct ieee80211_sband_iftype_data *)he_capa_2ghz; -- } else if (sband->band == NL80211_BAND_5GHZ) { -+ break; -+ case NL80211_BAND_5GHZ: -+ case NL80211_BAND_6GHZ: - n_iftype_data = ARRAY_SIZE(he_capa_5ghz); - sband->iftype_data = - (struct ieee80211_sband_iftype_data *)he_capa_5ghz; -- } else { -+ break; -+ default: - return; - } - -@@ -3306,6 +3310,12 @@ static int mac80211_hwsim_new_radio(stru - sband->vht_cap.vht_mcs.tx_mcs_map = - sband->vht_cap.vht_mcs.rx_mcs_map; - break; -+ case NL80211_BAND_6GHZ: -+ sband->channels = data->channels_6ghz; -+ sband->n_channels = ARRAY_SIZE(hwsim_channels_6ghz); -+ sband->bitrates = data->rates + 4; -+ sband->n_bitrates = ARRAY_SIZE(hwsim_rates) - 4; -+ break; - case NL80211_BAND_S1GHZ: - memcpy(&sband->s1g_cap, &hwsim_s1g_cap, - sizeof(sband->s1g_cap)); -@@ -3316,6 +3326,13 @@ static int mac80211_hwsim_new_radio(stru - continue; - } - -+ mac80211_hwsim_he_capab(sband); -+ -+ hw->wiphy->bands[band] = sband; -+ -+ if (band == NL80211_BAND_6GHZ) -+ continue; -+ - sband->ht_cap.ht_supported = true; - sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | - IEEE80211_HT_CAP_GRN_FLD | -@@ -3329,10 +3346,6 @@ static int mac80211_hwsim_new_radio(stru - sband->ht_cap.mcs.rx_mask[0] = 0xff; - sband->ht_cap.mcs.rx_mask[1] = 0xff; - sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; -- -- mac80211_hwsim_he_capab(sband); -- -- hw->wiphy->bands[band] = sband; - } - - /* By default all radios belong to the first group */ diff --git a/package/kernel/mac80211/patches/subsys/308-v5.17-mac80211-add-support-for-.ndo_fill_forward_path.patch b/package/kernel/mac80211/patches/subsys/308-v5.17-mac80211-add-support-for-.ndo_fill_forward_path.patch deleted file mode 100644 index a9a6182ab2..0000000000 --- a/package/kernel/mac80211/patches/subsys/308-v5.17-mac80211-add-support-for-.ndo_fill_forward_path.patch +++ /dev/null @@ -1,178 +0,0 @@ -From: Felix Fietkau -Date: Fri, 12 Nov 2021 12:22:23 +0100 -Subject: [PATCH] mac80211: add support for .ndo_fill_forward_path - -This allows drivers to provide a destination device + info for flow offload -Only supported in combination with 802.3 encap offload - -Signed-off-by: Felix Fietkau -Tested-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/20211112112223.1209-1-nbd@nbd.name -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -3937,6 +3937,8 @@ struct ieee80211_prep_tx_info { - * twt structure. - * @twt_teardown_request: Update the hw with TWT teardown request received - * from the peer. -+ * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to -+ * resolve a path for hardware flow offloading - */ - struct ieee80211_ops { - void (*tx)(struct ieee80211_hw *hw, -@@ -4265,6 +4267,13 @@ struct ieee80211_ops { - struct ieee80211_twt_setup *twt); - void (*twt_teardown_request)(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 flowid); -+#if LINUX_VERSION_IS_GEQ(5,10,0) -+ int (*net_fill_forward_path)(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+ struct net_device_path_ctx *ctx, -+ struct net_device_path *path); -+#endif - }; - - /** ---- a/net/mac80211/driver-ops.h -+++ b/net/mac80211/driver-ops.h -@@ -1486,4 +1486,28 @@ static inline void drv_twt_teardown_requ - trace_drv_return_void(local); - } - -+#if LINUX_VERSION_IS_GEQ(5,10,0) -+static inline int drv_net_fill_forward_path(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_sta *sta, -+ struct net_device_path_ctx *ctx, -+ struct net_device_path *path) -+{ -+ int ret = -EOPNOTSUPP; -+ -+ sdata = get_bss_sdata(sdata); -+ if (!check_sdata_in_driver(sdata)) -+ return -EIO; -+ -+ trace_drv_net_fill_forward_path(local, sdata, sta); -+ if (local->ops->net_fill_forward_path) -+ ret = local->ops->net_fill_forward_path(&local->hw, -+ &sdata->vif, sta, -+ ctx, path); -+ trace_drv_return_int(local, ret); -+ -+ return ret; -+} -+#endif -+ - #endif /* __MAC80211_DRIVER_OPS */ ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1489,7 +1489,7 @@ struct ieee80211_local { - }; - - static inline struct ieee80211_sub_if_data * --IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) -+IEEE80211_DEV_TO_SUB_IF(const struct net_device *dev) - { - return netdev_priv(dev); - } ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -822,6 +822,66 @@ static const struct net_device_ops ieee8 - - }; - -+#if LINUX_VERSION_IS_GEQ(5,10,0) -+static int ieee80211_netdev_fill_forward_path(struct net_device_path_ctx *ctx, -+ struct net_device_path *path) -+{ -+ struct ieee80211_sub_if_data *sdata; -+ struct ieee80211_local *local; -+ struct sta_info *sta; -+ int ret = -ENOENT; -+ -+ sdata = IEEE80211_DEV_TO_SUB_IF(ctx->dev); -+ local = sdata->local; -+ -+ if (!local->ops->net_fill_forward_path) -+ return -EOPNOTSUPP; -+ -+ rcu_read_lock(); -+ switch (sdata->vif.type) { -+ case NL80211_IFTYPE_AP_VLAN: -+ sta = rcu_dereference(sdata->u.vlan.sta); -+ if (sta) -+ break; -+ if (sdata->wdev.use_4addr) -+ goto out; -+ if (is_multicast_ether_addr(ctx->daddr)) -+ goto out; -+ sta = sta_info_get_bss(sdata, ctx->daddr); -+ break; -+ case NL80211_IFTYPE_AP: -+ if (is_multicast_ether_addr(ctx->daddr)) -+ goto out; -+ sta = sta_info_get(sdata, ctx->daddr); -+ break; -+ case NL80211_IFTYPE_STATION: -+ if (sdata->wdev.wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) { -+ sta = sta_info_get(sdata, ctx->daddr); -+ if (sta && test_sta_flag(sta, WLAN_STA_TDLS_PEER)) { -+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) -+ goto out; -+ -+ break; -+ } -+ } -+ -+ sta = sta_info_get(sdata, sdata->u.mgd.bssid); -+ break; -+ default: -+ goto out; -+ } -+ -+ if (!sta) -+ goto out; -+ -+ ret = drv_net_fill_forward_path(local, sdata, &sta->sta, ctx, path); -+out: -+ rcu_read_unlock(); -+ -+ return ret; -+} -+#endif -+ - static const struct net_device_ops ieee80211_dataif_8023_ops = { - #if LINUX_VERSION_IS_LESS(4,10,0) - .ndo_change_mtu = __change_mtu, -@@ -839,7 +899,9 @@ static const struct net_device_ops ieee8 - #else - .ndo_get_stats64 = bp_ieee80211_get_stats64, - #endif -- -+#if LINUX_VERSION_IS_GEQ(5,10,0) -+ .ndo_fill_forward_path = ieee80211_netdev_fill_forward_path, -+#endif - }; - - static bool ieee80211_iftype_supports_hdr_offload(enum nl80211_iftype iftype) ---- a/net/mac80211/trace.h -+++ b/net/mac80211/trace.h -@@ -2892,6 +2892,15 @@ TRACE_EVENT(drv_twt_teardown_request, - ) - ); - -+#if LINUX_VERSION_IS_GEQ(5,10,0) -+DEFINE_EVENT(sta_event, drv_net_fill_forward_path, -+ TP_PROTO(struct ieee80211_local *local, -+ struct ieee80211_sub_if_data *sdata, -+ struct ieee80211_sta *sta), -+ TP_ARGS(local, sdata, sta) -+); -+#endif -+ - #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ - - #undef TRACE_INCLUDE_PATH diff --git a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch deleted file mode 100644 index 0d475b7329..0000000000 --- a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel_ht-fix-MINSTREL_FRAC-macro.patch +++ /dev/null @@ -1,21 +0,0 @@ -From: Felix Fietkau -Date: Wed, 28 Apr 2021 21:03:13 +0200 -Subject: [PATCH] mac80211: minstrel_ht: fix MINSTREL_FRAC macro - -Add missing braces to avoid issues with e.g. using additions in the -div expression - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -14,7 +14,7 @@ - - /* scaled fraction values */ - #define MINSTREL_SCALE 12 --#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / div) -+#define MINSTREL_FRAC(val, div) (((val) << MINSTREL_SCALE) / (div)) - #define MINSTREL_TRUNC(val) ((val) >> MINSTREL_SCALE) - - #define EWMA_LEVEL 96 /* ewma weighting factor [/EWMA_DIV] */ diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-add-support-for-restricting-netdev-features.patch new file mode 100644 index 0000000000..cd6048b4fd --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/310-mac80211-add-support-for-restricting-netdev-features.patch @@ -0,0 +1,506 @@ +From: Felix Fietkau +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 +--- + +--- 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 +@@ -1848,6 +1852,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 +@@ -2179,6 +2179,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 +@@ -1355,7 +1355,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) +@@ -3578,55 +3582,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 +@@ -3635,10 +3663,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); +@@ -3652,7 +3678,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); +@@ -3676,16 +3702,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, +@@ -3693,6 +3717,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; + } + +@@ -4193,31 +4267,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) { +@@ -4435,9 +4492,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 = {}; +@@ -4446,14 +4505,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] || +@@ -4480,6 +4531,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) +@@ -4487,9 +4558,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)) +@@ -4499,9 +4574,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; +@@ -4515,22 +4587,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, +@@ -4542,6 +4612,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; +@@ -4583,6 +4671,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/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch deleted file mode 100644 index 3be43b8782..0000000000 --- a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-reduce-fluctuations-in-rate-pro.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Sat, 6 Feb 2021 16:08:01 +0100 -Subject: [PATCH] mac80211: minstrel_ht: reduce fluctuations in rate - probability stats - -In some scenarios when there is a lot of fluctuation in packet error rates, -rate switching can be amplified when the statistics get skewed by time slots -with very few tries. -Make the input data to the moving average more smooth by adding the -success/attempts count from the last stats window as well. This has the -advantage of smoothing the data without introducing any extra lag to sampling -rates. -This significantly improves rate stability on a strong test link subjected to -periodic noise bursts generated with a SDR - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -703,7 +703,8 @@ minstrel_ht_calc_rate_stats(struct minst - unsigned int cur_prob; - - if (unlikely(mrs->attempts > 0)) { -- cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); -+ cur_prob = MINSTREL_FRAC(mrs->success + mrs->last_success, -+ mrs->attempts + mrs->last_attempts); - minstrel_filter_avg_add(&mrs->prob_avg, - &mrs->prob_avg_1, cur_prob); - mrs->att_hist += mrs->attempts; diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch deleted file mode 100644 index 13bed48ec6..0000000000 --- a/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-rework-rate-downgrade-code-and-.patch +++ /dev/null @@ -1,151 +0,0 @@ -From: Felix Fietkau -Date: Sat, 6 Feb 2021 16:33:14 +0100 -Subject: [PATCH] mac80211: minstrel_ht: rework rate downgrade code and - max_prob rate selection - -The current fallback code for fast rate switching on potentially failing rates -is triggering too often if there is some strong noise on the channel. This can -lead to wild fluctuations in the rate selection. -Additionally, switching down to max_prob_rate can create a significant gap down -in throughput, especially when using only 2 spatial streams, because max_prob_rate -is limited to using fewer streams than the max_tp rates. -In order to improve throughput without reducing reliability too much, use the -rate downgrade code for the max_prob_rate only, and allow the non-downgraded -max_prob_rate to use as many spatial streams as the max_tp rates - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -514,6 +514,14 @@ minstrel_ht_set_best_prob_rate(struct mi - int cur_tp_avg, cur_group, cur_idx; - int max_gpr_group, max_gpr_idx; - int max_gpr_tp_avg, max_gpr_prob; -+ int min_dur; -+ -+ min_dur = max(minstrel_get_duration(mi->max_tp_rate[0]), -+ minstrel_get_duration(mi->max_tp_rate[1])); -+ -+ /* make the rate at least 18% slower than max tp rates */ -+ if (minstrel_get_duration(index) <= min_dur * 19 / 16) -+ return; - - cur_group = MI_RATE_GROUP(index); - cur_idx = MI_RATE_IDX(index); -@@ -535,11 +543,6 @@ minstrel_ht_set_best_prob_rate(struct mi - !minstrel_ht_is_legacy_group(max_tp_group)) - return; - -- /* skip rates faster than max tp rate with lower prob */ -- if (minstrel_get_duration(mi->max_tp_rate[0]) > minstrel_get_duration(index) && -- mrs->prob_avg < max_tp_prob) -- return; -- - max_gpr_group = MI_RATE_GROUP(mg->max_group_prob_rate); - max_gpr_idx = MI_RATE_IDX(mg->max_group_prob_rate); - max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; -@@ -597,40 +600,6 @@ minstrel_ht_assign_best_tp_rates(struct - - } - --/* -- * Try to increase robustness of max_prob rate by decrease number of -- * streams if possible. -- */ --static inline void --minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) --{ -- struct minstrel_mcs_group_data *mg; -- int tmp_max_streams, group, tmp_idx, tmp_prob; -- int tmp_tp = 0; -- -- if (!mi->sta->ht_cap.ht_supported) -- return; -- -- group = MI_RATE_GROUP(mi->max_tp_rate[0]); -- tmp_max_streams = minstrel_mcs_groups[group].streams; -- for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { -- mg = &mi->groups[group]; -- if (!mi->supported[group] || group == MINSTREL_CCK_GROUP) -- continue; -- -- tmp_idx = MI_RATE_IDX(mg->max_group_prob_rate); -- tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; -- -- if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && -- (minstrel_mcs_groups[group].streams < tmp_max_streams)) { -- mi->max_prob_rate = mg->max_group_prob_rate; -- tmp_tp = minstrel_ht_get_tp_avg(mi, group, -- tmp_idx, -- tmp_prob); -- } -- } --} -- - static u16 - __minstrel_ht_get_sample_rate(struct minstrel_ht_sta *mi, - enum minstrel_sample_type type) -@@ -1110,8 +1079,6 @@ minstrel_ht_update_stats(struct minstrel - - mi->max_prob_rate = tmp_max_prob_rate; - -- /* Try to increase robustness of max_prob_rate*/ -- minstrel_ht_prob_rate_reduce_streams(mi); - minstrel_ht_refill_sample_rates(mi); - - #ifdef CPTCFG_MAC80211_DEBUGFS -@@ -1156,7 +1123,7 @@ minstrel_ht_txstat_valid(struct minstrel - } - - static void --minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u16 *idx, bool primary) -+minstrel_downgrade_prob_rate(struct minstrel_ht_sta *mi, u16 *idx) - { - int group, orig_group; - -@@ -1171,11 +1138,7 @@ minstrel_downgrade_rate(struct minstrel_ - minstrel_mcs_groups[orig_group].streams) - continue; - -- if (primary) -- *idx = mi->groups[group].max_group_tp_rate[0]; -- else -- *idx = mi->groups[group].max_group_tp_rate[1]; -- break; -+ *idx = mi->groups[group].max_group_prob_rate; - } - } - -@@ -1186,7 +1149,7 @@ minstrel_ht_tx_status(void *priv, struct - struct ieee80211_tx_info *info = st->info; - struct minstrel_ht_sta *mi = priv_sta; - struct ieee80211_tx_rate *ar = info->status.rates; -- struct minstrel_rate_stats *rate, *rate2; -+ struct minstrel_rate_stats *rate; - struct minstrel_priv *mp = priv; - u32 update_interval = mp->update_interval; - bool last, update = false; -@@ -1236,18 +1199,13 @@ minstrel_ht_tx_status(void *priv, struct - /* - * check for sudden death of spatial multiplexing, - * downgrade to a lower number of streams if necessary. -+ * only do this for the max_prob_rate to prevent spurious -+ * rate fluctuations when the link changes suddenly - */ -- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -+ rate = minstrel_get_ratestats(mi, mi->max_prob_rate); - if (rate->attempts > 30 && - rate->success < rate->attempts / 4) { -- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); -- update = true; -- } -- -- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); -- if (rate2->attempts > 30 && -- rate2->success < rate2->attempts / 4) { -- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); -+ minstrel_downgrade_prob_rate(mi, &mi->max_prob_rate); - update = true; - } - } diff --git a/package/kernel/mac80211/patches/subsys/312-v5.16-mac80211-split-beacon-retrieval-functions.patch b/package/kernel/mac80211/patches/subsys/312-v5.16-mac80211-split-beacon-retrieval-functions.patch deleted file mode 100644 index 18b1951f6e..0000000000 --- a/package/kernel/mac80211/patches/subsys/312-v5.16-mac80211-split-beacon-retrieval-functions.patch +++ /dev/null @@ -1,262 +0,0 @@ -From: Aloka Dixit -Date: Tue, 5 Oct 2021 21:09:36 -0700 -Subject: [PATCH] mac80211: split beacon retrieval functions - -Split __ieee80211_beacon_get() into a separate function for AP mode -ieee80211_beacon_get_ap(). -Also, move the code common to all modes (AP, adhoc and mesh) to -a separate function ieee80211_beacon_get_finish(). - -Signed-off-by: Aloka Dixit -Link: https://lore.kernel.org/r/20211006040938.9531-2-alokad@codeaurora.org -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -4987,6 +4987,115 @@ static int ieee80211_beacon_protect(stru - return 0; - } - -+static void -+ieee80211_beacon_get_finish(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_mutable_offsets *offs, -+ struct beacon_data *beacon, -+ struct sk_buff *skb, -+ struct ieee80211_chanctx_conf *chanctx_conf, -+ u16 csa_off_base) -+{ -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -+ struct ieee80211_tx_info *info; -+ enum nl80211_band band; -+ struct ieee80211_tx_rate_control txrc; -+ -+ /* CSA offsets */ -+ if (offs && beacon) { -+ u16 i; -+ -+ for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) { -+ u16 csa_off = beacon->cntdwn_counter_offsets[i]; -+ -+ if (!csa_off) -+ continue; -+ -+ offs->cntdwn_counter_offs[i] = csa_off_base + csa_off; -+ } -+ } -+ -+ band = chanctx_conf->def.chan->band; -+ info = IEEE80211_SKB_CB(skb); -+ info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; -+ info->flags |= IEEE80211_TX_CTL_NO_ACK; -+ info->band = band; -+ -+ memset(&txrc, 0, sizeof(txrc)); -+ txrc.hw = hw; -+ txrc.sband = local->hw.wiphy->bands[band]; -+ txrc.bss_conf = &sdata->vif.bss_conf; -+ txrc.skb = skb; -+ txrc.reported_rate.idx = -1; -+ if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band]) -+ txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band]; -+ else -+ txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; -+ txrc.bss = true; -+ rate_control_get_rate(sdata, NULL, &txrc); -+ -+ info->control.vif = vif; -+ info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT | -+ IEEE80211_TX_CTL_ASSIGN_SEQ | -+ IEEE80211_TX_CTL_FIRST_FRAGMENT; -+} -+ -+static struct sk_buff * -+ieee80211_beacon_get_ap(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_mutable_offsets *offs, -+ bool is_template, -+ struct beacon_data *beacon, -+ struct ieee80211_chanctx_conf *chanctx_conf) -+{ -+ struct ieee80211_local *local = hw_to_local(hw); -+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -+ struct ieee80211_if_ap *ap = &sdata->u.ap; -+ struct sk_buff *skb = NULL; -+ u16 csa_off_base = 0; -+ -+ if (beacon->cntdwn_counter_offsets[0]) { -+ if (!is_template) -+ ieee80211_beacon_update_cntdwn(vif); -+ -+ ieee80211_set_beacon_cntdwn(sdata, beacon); -+ } -+ -+ /* headroom, head length, -+ * tail length and maximum TIM length -+ */ -+ skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + -+ beacon->tail_len + 256 + -+ local->hw.extra_beacon_tailroom); -+ if (!skb) -+ return NULL; -+ -+ skb_reserve(skb, local->tx_headroom); -+ skb_put_data(skb, beacon->head, beacon->head_len); -+ -+ ieee80211_beacon_add_tim(sdata, &ap->ps, skb, is_template); -+ -+ if (offs) { -+ offs->tim_offset = beacon->head_len; -+ offs->tim_length = skb->len - beacon->head_len; -+ offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; -+ -+ /* for AP the csa offsets are from tail */ -+ csa_off_base = skb->len; -+ } -+ -+ if (beacon->tail) -+ skb_put_data(skb, beacon->tail, beacon->tail_len); -+ -+ if (ieee80211_beacon_protect(skb, local, sdata) < 0) -+ return NULL; -+ -+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, chanctx_conf, -+ csa_off_base); -+ return skb; -+} -+ - static struct sk_buff * - __ieee80211_beacon_get(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, -@@ -4996,12 +5105,8 @@ __ieee80211_beacon_get(struct ieee80211_ - struct ieee80211_local *local = hw_to_local(hw); - struct beacon_data *beacon = NULL; - struct sk_buff *skb = NULL; -- struct ieee80211_tx_info *info; - struct ieee80211_sub_if_data *sdata = NULL; -- enum nl80211_band band; -- struct ieee80211_tx_rate_control txrc; - struct ieee80211_chanctx_conf *chanctx_conf; -- int csa_off_base = 0; - - rcu_read_lock(); - -@@ -5018,48 +5123,11 @@ __ieee80211_beacon_get(struct ieee80211_ - struct ieee80211_if_ap *ap = &sdata->u.ap; - - beacon = rcu_dereference(ap->beacon); -- if (beacon) { -- if (beacon->cntdwn_counter_offsets[0]) { -- if (!is_template) -- ieee80211_beacon_update_cntdwn(vif); -- -- ieee80211_set_beacon_cntdwn(sdata, beacon); -- } -- -- /* -- * headroom, head length, -- * tail length and maximum TIM length -- */ -- skb = dev_alloc_skb(local->tx_headroom + -- beacon->head_len + -- beacon->tail_len + 256 + -- local->hw.extra_beacon_tailroom); -- if (!skb) -- goto out; -- -- skb_reserve(skb, local->tx_headroom); -- skb_put_data(skb, beacon->head, beacon->head_len); -- -- ieee80211_beacon_add_tim(sdata, &ap->ps, skb, -- is_template); -- -- if (offs) { -- offs->tim_offset = beacon->head_len; -- offs->tim_length = skb->len - beacon->head_len; -- offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; -- -- /* for AP the csa offsets are from tail */ -- csa_off_base = skb->len; -- } -- -- if (beacon->tail) -- skb_put_data(skb, beacon->tail, -- beacon->tail_len); -- -- if (ieee80211_beacon_protect(skb, local, sdata) < 0) -- goto out; -- } else -+ if (!beacon) - goto out; -+ -+ skb = ieee80211_beacon_get_ap(hw, vif, offs, is_template, -+ beacon, chanctx_conf); - } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { - struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; - struct ieee80211_hdr *hdr; -@@ -5085,6 +5153,9 @@ __ieee80211_beacon_get(struct ieee80211_ - hdr = (struct ieee80211_hdr *) skb->data; - hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_BEACON); -+ -+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, -+ chanctx_conf, 0); - } else if (ieee80211_vif_is_mesh(&sdata->vif)) { - struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; - -@@ -5124,51 +5195,13 @@ __ieee80211_beacon_get(struct ieee80211_ - } - - skb_put_data(skb, beacon->tail, beacon->tail_len); -+ ieee80211_beacon_get_finish(hw, vif, offs, beacon, skb, -+ chanctx_conf, 0); - } else { - WARN_ON(1); - goto out; - } - -- /* CSA offsets */ -- if (offs && beacon) { -- int i; -- -- for (i = 0; i < IEEE80211_MAX_CNTDWN_COUNTERS_NUM; i++) { -- u16 csa_off = beacon->cntdwn_counter_offsets[i]; -- -- if (!csa_off) -- continue; -- -- offs->cntdwn_counter_offs[i] = csa_off_base + csa_off; -- } -- } -- -- band = chanctx_conf->def.chan->band; -- -- info = IEEE80211_SKB_CB(skb); -- -- info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; -- info->flags |= IEEE80211_TX_CTL_NO_ACK; -- info->band = band; -- -- memset(&txrc, 0, sizeof(txrc)); -- txrc.hw = hw; -- txrc.sband = local->hw.wiphy->bands[band]; -- txrc.bss_conf = &sdata->vif.bss_conf; -- txrc.skb = skb; -- txrc.reported_rate.idx = -1; -- if (sdata->beacon_rate_set && sdata->beacon_rateidx_mask[band]) -- txrc.rate_idx_mask = sdata->beacon_rateidx_mask[band]; -- else -- txrc.rate_idx_mask = sdata->rc_rateidx_mask[band]; -- txrc.bss = true; -- rate_control_get_rate(sdata, NULL, &txrc); -- -- info->control.vif = vif; -- -- info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT | -- IEEE80211_TX_CTL_ASSIGN_SEQ | -- IEEE80211_TX_CTL_FIRST_FRAGMENT; - out: - rcu_read_unlock(); - return skb; diff --git a/package/kernel/mac80211/patches/subsys/313-v5.16-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/313-v5.16-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch deleted file mode 100644 index 429886d701..0000000000 --- a/package/kernel/mac80211/patches/subsys/313-v5.16-nl80211-MBSSID-and-EMA-support-in-AP-mode.patch +++ /dev/null @@ -1,493 +0,0 @@ -From: John Crispin -Date: Wed, 15 Sep 2021 19:54:34 -0700 -Subject: [PATCH] nl80211: MBSSID and EMA support in AP mode - -Add new attributes to configure support for multiple BSSID -and advanced multi-BSSID advertisements (EMA) in AP mode. - -- NL80211_ATTR_MBSSID_CONFIG used for per interface configuration. -- NL80211_ATTR_MBSSID_ELEMS used to MBSSID elements for beacons. - -Memory for the elements is allocated dynamically. This change frees -the memory in existing functions which call nl80211_parse_beacon(), -a comment is added to indicate the new references to do the same. - -Signed-off-by: John Crispin -Co-developed-by: Aloka Dixit -Signed-off-by: Aloka Dixit -Link: https://lore.kernel.org/r/20210916025437.29138-2-alokad@codeaurora.org -[don't leave ERR_PTR hanging around] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -1046,6 +1046,36 @@ struct cfg80211_crypto_settings { - }; - - /** -+ * struct cfg80211_mbssid_config - AP settings for multi bssid -+ * -+ * @tx_wdev: pointer to the transmitted interface in the MBSSID set -+ * @index: index of this AP in the multi bssid group. -+ * @ema: set to true if the beacons should be sent out in EMA mode. -+ */ -+struct cfg80211_mbssid_config { -+ struct wireless_dev *tx_wdev; -+ u8 index; -+ bool ema; -+}; -+ -+/** -+ * struct cfg80211_mbssid_elems - Multiple BSSID elements -+ * -+ * @cnt: Number of elements in array %elems. -+ * -+ * @elem: Array of multiple BSSID element(s) to be added into Beacon frames. -+ * @elem.data: Data for multiple BSSID elements. -+ * @elem.len: Length of data. -+ */ -+struct cfg80211_mbssid_elems { -+ u8 cnt; -+ struct { -+ const u8 *data; -+ size_t len; -+ } elem[]; -+}; -+ -+/** - * struct cfg80211_beacon_data - beacon data - * @head: head portion of beacon (before TIM IE) - * or %NULL if not changed -@@ -1063,6 +1093,7 @@ struct cfg80211_crypto_settings { - * @assocresp_ies_len: length of assocresp_ies in octets - * @probe_resp_len: length of probe response template (@probe_resp) - * @probe_resp: probe response template (AP mode only) -+ * @mbssid_ies: multiple BSSID elements - * @ftm_responder: enable FTM responder functionality; -1 for no change - * (which also implies no change in LCI/civic location data) - * @lci: Measurement Report element content, starting with Measurement Token -@@ -1080,6 +1111,7 @@ struct cfg80211_beacon_data { - const u8 *probe_resp; - const u8 *lci; - const u8 *civicloc; -+ struct cfg80211_mbssid_elems *mbssid_ies; - s8 ftm_responder; - - size_t head_len, tail_len; -@@ -1194,6 +1226,7 @@ enum cfg80211_ap_settings_flags { - * @he_oper: HE operation IE (or %NULL if HE isn't enabled) - * @fils_discovery: FILS discovery transmission parameters - * @unsol_bcast_probe_resp: Unsolicited broadcast probe response parameters -+ * @mbssid_config: AP settings for multiple bssid - */ - struct cfg80211_ap_settings { - struct cfg80211_chan_def chandef; -@@ -1226,6 +1259,7 @@ struct cfg80211_ap_settings { - struct cfg80211_he_bss_color he_bss_color; - struct cfg80211_fils_discovery fils_discovery; - struct cfg80211_unsol_bcast_probe_resp unsol_bcast_probe_resp; -+ struct cfg80211_mbssid_config mbssid_config; - }; - - /** -@@ -4986,6 +5020,13 @@ struct wiphy_iftype_akm_suites { - * %NL80211_TID_CONFIG_ATTR_RETRY_LONG attributes - * @sar_capa: SAR control capabilities - * @rfkill: a pointer to the rfkill structure -+ * -+ * @mbssid_max_interfaces: maximum number of interfaces supported by the driver -+ * in a multiple BSSID set. This field must be set to a non-zero value -+ * by the driver to advertise MBSSID support. -+ * @mbssid_max_ema_profile_periodicity: maximum profile periodicity supported by -+ * the driver. Setting this field to a non-zero value indicates that the -+ * driver supports enhanced multi-BSSID advertisements (EMA AP). - */ - struct wiphy { - struct mutex mtx; -@@ -5133,6 +5174,9 @@ struct wiphy { - - struct rfkill *rfkill; - -+ u8 mbssid_max_interfaces; -+ u8 ema_max_profile_periodicity; -+ - char priv[] __aligned(NETDEV_ALIGN); - }; - ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -337,7 +337,10 @@ - * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes - * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from - * userspace to request deletion of a virtual interface, then requires -- * attribute %NL80211_ATTR_IFINDEX. -+ * attribute %NL80211_ATTR_IFINDEX. If multiple BSSID advertisements are -+ * enabled using %NL80211_ATTR_MBSSID_CONFIG, %NL80211_ATTR_MBSSID_ELEMS, -+ * and if this command is used for the transmitting interface, then all -+ * the non-transmitting interfaces are deleted as well. - * - * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified - * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. -@@ -2593,6 +2596,18 @@ enum nl80211_commands { - * @NL80211_ATTR_COLOR_CHANGE_ELEMS: Nested set of attributes containing the IE - * information for the time while performing a color switch. - * -+ * @NL80211_ATTR_MBSSID_CONFIG: Nested attribute for multiple BSSID -+ * advertisements (MBSSID) parameters in AP mode. -+ * Kernel uses this attribute to indicate the driver's support for MBSSID -+ * and enhanced multi-BSSID advertisements (EMA AP) to the userspace. -+ * Userspace should use this attribute to configure per interface MBSSID -+ * parameters. -+ * See &enum nl80211_mbssid_config_attributes for details. -+ * -+ * @NL80211_ATTR_MBSSID_ELEMS: Nested parameter to pass multiple BSSID elements. -+ * Mandatory parameter for the transmitting interface to enable MBSSID. -+ * Optional for the non-transmitting interfaces. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3096,6 +3111,9 @@ enum nl80211_attrs { - NL80211_ATTR_COLOR_CHANGE_COLOR, - NL80211_ATTR_COLOR_CHANGE_ELEMS, - -+ NL80211_ATTR_MBSSID_CONFIG, -+ NL80211_ATTR_MBSSID_ELEMS, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -7349,4 +7367,60 @@ enum nl80211_sar_specs_attrs { - NL80211_SAR_ATTR_SPECS_MAX = __NL80211_SAR_ATTR_SPECS_LAST - 1, - }; - -+/** -+ * enum nl80211_mbssid_config_attributes - multiple BSSID (MBSSID) and enhanced -+ * multi-BSSID advertisements (EMA) in AP mode. -+ * Kernel uses some of these attributes to advertise driver's support for -+ * MBSSID and EMA. -+ * Remaining attributes should be used by the userspace to configure the -+ * features. -+ * -+ * @__NL80211_MBSSID_CONFIG_ATTR_INVALID: Invalid -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES: Used by the kernel to advertise -+ * the maximum number of MBSSID interfaces supported by the driver. -+ * Driver should indicate MBSSID support by setting -+ * wiphy->mbssid_max_interfaces to a value more than or equal to 2. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY: Used by the kernel -+ * to advertise the maximum profile periodicity supported by the driver -+ * if EMA is enabled. Driver should indicate EMA support to the userspace -+ * by setting wiphy->mbssid_max_ema_profile_periodicity to -+ * a non-zero value. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_INDEX: Mandatory parameter to pass the index of -+ * this BSS (u8) in the multiple BSSID set. -+ * Value must be set to 0 for the transmitting interface and non-zero for -+ * all non-transmitting interfaces. The userspace will be responsible -+ * for using unique indices for the interfaces. -+ * Range: 0 to wiphy->mbssid_max_interfaces-1. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX: Mandatory parameter for -+ * a non-transmitted profile which provides the interface index (u32) of -+ * the transmitted profile. The value must match one of the interface -+ * indices advertised by the kernel. Optional if the interface being set up -+ * is the transmitting one, however, if provided then the value must match -+ * the interface index of the same. -+ * -+ * @NL80211_MBSSID_CONFIG_ATTR_EMA: Flag used to enable EMA AP feature. -+ * Setting this flag is permitted only if the driver advertises EMA support -+ * by setting wiphy->mbssid_max_ema_profile_periodicity to non-zero. -+ * -+ * @__NL80211_MBSSID_CONFIG_ATTR_LAST: Internal -+ * @NL80211_MBSSID_CONFIG_ATTR_MAX: highest attribute -+ */ -+enum nl80211_mbssid_config_attributes { -+ __NL80211_MBSSID_CONFIG_ATTR_INVALID, -+ -+ NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES, -+ NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY, -+ NL80211_MBSSID_CONFIG_ATTR_INDEX, -+ NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX, -+ NL80211_MBSSID_CONFIG_ATTR_EMA, -+ -+ /* keep last */ -+ __NL80211_MBSSID_CONFIG_ATTR_LAST, -+ NL80211_MBSSID_CONFIG_ATTR_MAX = __NL80211_MBSSID_CONFIG_ATTR_LAST - 1, -+}; -+ - #endif /* __LINUX_NL80211_H */ ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -442,6 +442,16 @@ sar_policy[NL80211_SAR_ATTR_MAX + 1] = { - [NL80211_SAR_ATTR_SPECS] = NLA_POLICY_NESTED_ARRAY(sar_specs_policy), - }; - -+static const struct nla_policy -+nl80211_mbssid_config_policy[NL80211_MBSSID_CONFIG_ATTR_MAX + 1] = { -+ [NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES] = NLA_POLICY_MIN(NLA_U8, 2), -+ [NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY] = -+ NLA_POLICY_MIN(NLA_U8, 1), -+ [NL80211_MBSSID_CONFIG_ATTR_INDEX] = { .type = NLA_U8 }, -+ [NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX] = { .type = NLA_U32 }, -+ [NL80211_MBSSID_CONFIG_ATTR_EMA] = { .type = NLA_FLAG }, -+}; -+ - static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { - [0] = { .strict_start_type = NL80211_ATTR_HE_OBSS_PD }, - [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, -@@ -788,6 +798,9 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_COLOR_CHANGE_COUNT] = { .type = NLA_U8 }, - [NL80211_ATTR_COLOR_CHANGE_COLOR] = { .type = NLA_U8 }, - [NL80211_ATTR_COLOR_CHANGE_ELEMS] = NLA_POLICY_NESTED(nl80211_policy), -+ [NL80211_ATTR_MBSSID_CONFIG] = -+ NLA_POLICY_NESTED(nl80211_mbssid_config_policy), -+ [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, - }; - - /* policy for the key attributes */ -@@ -2236,6 +2249,35 @@ fail: - return -ENOBUFS; - } - -+static int nl80211_put_mbssid_support(struct wiphy *wiphy, struct sk_buff *msg) -+{ -+ struct nlattr *config; -+ -+ if (!wiphy->mbssid_max_interfaces) -+ return 0; -+ -+ config = nla_nest_start(msg, NL80211_ATTR_MBSSID_CONFIG); -+ if (!config) -+ return -ENOBUFS; -+ -+ if (nla_put_u8(msg, NL80211_MBSSID_CONFIG_ATTR_MAX_INTERFACES, -+ wiphy->mbssid_max_interfaces)) -+ goto fail; -+ -+ if (wiphy->ema_max_profile_periodicity && -+ nla_put_u8(msg, -+ NL80211_MBSSID_CONFIG_ATTR_MAX_EMA_PROFILE_PERIODICITY, -+ wiphy->ema_max_profile_periodicity)) -+ goto fail; -+ -+ nla_nest_end(msg, config); -+ return 0; -+ -+fail: -+ nla_nest_cancel(msg, config); -+ return -ENOBUFS; -+} -+ - struct nl80211_dump_wiphy_state { - s64 filter_wiphy; - long start; -@@ -2821,6 +2863,9 @@ static int nl80211_send_wiphy(struct cfg - if (nl80211_put_sar_specs(rdev, msg)) - goto nla_put_failure; - -+ if (nl80211_put_mbssid_support(&rdev->wiphy, msg)) -+ goto nla_put_failure; -+ - /* done */ - state->split_start = 0; - break; -@@ -5020,6 +5065,96 @@ static int validate_beacon_tx_rate(struc - return 0; - } - -+static int nl80211_parse_mbssid_config(struct wiphy *wiphy, -+ struct net_device *dev, -+ struct nlattr *attrs, -+ struct cfg80211_mbssid_config *config, -+ u8 num_elems) -+{ -+ struct nlattr *tb[NL80211_MBSSID_CONFIG_ATTR_MAX + 1]; -+ -+ if (!wiphy->mbssid_max_interfaces) -+ return -EOPNOTSUPP; -+ -+ if (nla_parse_nested(tb, NL80211_MBSSID_CONFIG_ATTR_MAX, attrs, NULL, -+ NULL) || -+ !tb[NL80211_MBSSID_CONFIG_ATTR_INDEX]) -+ return -EINVAL; -+ -+ config->ema = nla_get_flag(tb[NL80211_MBSSID_CONFIG_ATTR_EMA]); -+ if (config->ema) { -+ if (!wiphy->ema_max_profile_periodicity) -+ return -EOPNOTSUPP; -+ -+ if (num_elems > wiphy->ema_max_profile_periodicity) -+ return -EINVAL; -+ } -+ -+ config->index = nla_get_u8(tb[NL80211_MBSSID_CONFIG_ATTR_INDEX]); -+ if (config->index >= wiphy->mbssid_max_interfaces || -+ (!config->index && !num_elems)) -+ return -EINVAL; -+ -+ if (tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]) { -+ u32 tx_ifindex = -+ nla_get_u32(tb[NL80211_MBSSID_CONFIG_ATTR_TX_IFINDEX]); -+ -+ if ((!config->index && tx_ifindex != dev->ifindex) || -+ (config->index && tx_ifindex == dev->ifindex)) -+ return -EINVAL; -+ -+ if (tx_ifindex != dev->ifindex) { -+ struct net_device *tx_netdev = -+ dev_get_by_index(wiphy_net(wiphy), tx_ifindex); -+ -+ if (!tx_netdev || !tx_netdev->ieee80211_ptr || -+ tx_netdev->ieee80211_ptr->wiphy != wiphy || -+ tx_netdev->ieee80211_ptr->iftype != -+ NL80211_IFTYPE_AP) { -+ dev_put(tx_netdev); -+ return -EINVAL; -+ } -+ -+ config->tx_wdev = tx_netdev->ieee80211_ptr; -+ } else { -+ config->tx_wdev = dev->ieee80211_ptr; -+ } -+ } else if (!config->index) { -+ config->tx_wdev = dev->ieee80211_ptr; -+ } else { -+ return -EINVAL; -+ } -+ -+ return 0; -+} -+ -+static struct cfg80211_mbssid_elems * -+nl80211_parse_mbssid_elems(struct wiphy *wiphy, struct nlattr *attrs) -+{ -+ struct nlattr *nl_elems; -+ struct cfg80211_mbssid_elems *elems; -+ int rem_elems; -+ u8 i = 0, num_elems = 0; -+ -+ if (!wiphy->mbssid_max_interfaces) -+ return ERR_PTR(-EINVAL); -+ -+ nla_for_each_nested(nl_elems, attrs, rem_elems) -+ num_elems++; -+ -+ elems = kzalloc(struct_size(elems, elem, num_elems), GFP_KERNEL); -+ if (!elems) -+ return ERR_PTR(-ENOMEM); -+ -+ nla_for_each_nested(nl_elems, attrs, rem_elems) { -+ elems->elem[i].data = nla_data(nl_elems); -+ elems->elem[i].len = nla_len(nl_elems); -+ i++; -+ } -+ elems->cnt = num_elems; -+ return elems; -+} -+ - static int nl80211_parse_beacon(struct cfg80211_registered_device *rdev, - struct nlattr *attrs[], - struct cfg80211_beacon_data *bcn) -@@ -5100,6 +5235,17 @@ static int nl80211_parse_beacon(struct c - bcn->ftm_responder = -1; - } - -+ if (attrs[NL80211_ATTR_MBSSID_ELEMS]) { -+ struct cfg80211_mbssid_elems *mbssid = -+ nl80211_parse_mbssid_elems(&rdev->wiphy, -+ attrs[NL80211_ATTR_MBSSID_ELEMS]); -+ -+ if (IS_ERR(mbssid)) -+ return PTR_ERR(mbssid); -+ -+ bcn->mbssid_ies = mbssid; -+ } -+ - return 0; - } - -@@ -5556,6 +5702,17 @@ static int nl80211_start_ap(struct sk_bu - goto out; - } - -+ if (info->attrs[NL80211_ATTR_MBSSID_CONFIG]) { -+ err = nl80211_parse_mbssid_config(&rdev->wiphy, dev, -+ info->attrs[NL80211_ATTR_MBSSID_CONFIG], -+ ¶ms.mbssid_config, -+ params.beacon.mbssid_ies ? -+ params.beacon.mbssid_ies->cnt : -+ 0); -+ if (err) -+ goto out; -+ } -+ - nl80211_calculate_ap_params(¶ms); - - if (info->attrs[NL80211_ATTR_EXTERNAL_AUTH_SUPPORT]) -@@ -5577,6 +5734,11 @@ static int nl80211_start_ap(struct sk_bu - - out: - kfree(params.acl); -+ kfree(params.beacon.mbssid_ies); -+ if (params.mbssid_config.tx_wdev && -+ params.mbssid_config.tx_wdev->netdev && -+ params.mbssid_config.tx_wdev->netdev != dev) -+ dev_put(params.mbssid_config.tx_wdev->netdev); - - return err; - } -@@ -5601,12 +5763,14 @@ static int nl80211_set_beacon(struct sk_ - - err = nl80211_parse_beacon(rdev, info->attrs, ¶ms); - if (err) -- return err; -+ goto out; - - wdev_lock(wdev); - err = rdev_change_beacon(rdev, dev, ¶ms); - wdev_unlock(wdev); - -+out: -+ kfree(params.mbssid_ies); - return err; - } - -@@ -9283,12 +9447,14 @@ static int nl80211_channel_switch(struct - - err = nl80211_parse_beacon(rdev, info->attrs, ¶ms.beacon_after); - if (err) -- return err; -+ goto free; - - csa_attrs = kcalloc(NL80211_ATTR_MAX + 1, sizeof(*csa_attrs), - GFP_KERNEL); -- if (!csa_attrs) -- return -ENOMEM; -+ if (!csa_attrs) { -+ err = -ENOMEM; -+ goto free; -+ } - - err = nla_parse_nested_deprecated(csa_attrs, NL80211_ATTR_MAX, - info->attrs[NL80211_ATTR_CSA_IES], -@@ -9407,6 +9573,8 @@ skip_beacons: - wdev_unlock(wdev); - - free: -+ kfree(params.beacon_after.mbssid_ies); -+ kfree(params.beacon_csa.mbssid_ies); - kfree(csa_attrs); - return err; - } -@@ -14959,6 +15127,8 @@ static int nl80211_color_change(struct s - wdev_unlock(wdev); - - out: -+ kfree(params.beacon_next.mbssid_ies); -+ kfree(params.beacon_color_change.mbssid_ies); - kfree(tb); - return err; - } diff --git a/package/kernel/mac80211/patches/subsys/314-v5.17-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch b/package/kernel/mac80211/patches/subsys/314-v5.17-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch deleted file mode 100644 index 2038ee69db..0000000000 --- a/package/kernel/mac80211/patches/subsys/314-v5.17-cfg80211-implement-APIs-for-dedicated-radar-detectio.patch +++ /dev/null @@ -1,378 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 23 Oct 2021 11:10:50 +0200 -Subject: [PATCH] cfg80211: implement APIs for dedicated radar detection HW - -If a dedicated (off-channel) radar detection hardware (chain) -is available in the hardware/driver, allow this to be used by -calling the NL80211_CMD_RADAR_DETECT command with a new flag -attribute requesting off-channel radar detection is used. - -Offchannel CAC (channel availability check) avoids the CAC -downtime when switching to a radar channel or when turning on -the AP. - -Drivers advertise support for this using the new feature flag -NL80211_EXT_FEATURE_RADAR_OFFCHAN. - -Tested-by: Evelyn Tsai -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/7468e291ef5d05d692c1738d25b8f778d8ea5c3f.1634979655.git.lorenzo@kernel.org -Link: https://lore.kernel.org/r/1e60e60fef00e14401adae81c3d49f3e5f307537.1634979655.git.lorenzo@kernel.org -Link: https://lore.kernel.org/r/85fa50f57fc3adb2934c8d9ca0be30394de6b7e8.1634979655.git.lorenzo@kernel.org -Link: https://lore.kernel.org/r/4b6c08671ad59aae0ac46fc94c02f31b1610eb72.1634979655.git.lorenzo@kernel.org -Link: https://lore.kernel.org/r/241849ccaf2c228873c6f8495bf87b19159ba458.1634979655.git.lorenzo@kernel.org -[remove offchan_mutex, fix cfg80211_stop_offchan_radar_detection(), - remove gfp_t argument, fix documentation, fix tracing] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -4057,6 +4057,15 @@ struct mgmt_frame_regs { - * @set_sar_specs: Update the SAR (TX power) settings. - * - * @color_change: Initiate a color change. -+ * -+ * @set_radar_offchan: Configure dedicated offchannel chain available for -+ * radar/CAC detection on some hw. This chain can't be used to transmit -+ * or receive frames and it is bounded to a running wdev. -+ * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * switching to a different channel during CAC detection on the selected -+ * radar channel. -+ * The caller is expected to set chandef pointer to NULL in order to -+ * disable offchannel CAC/radar detection. - */ - struct cfg80211_ops { - int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -@@ -4387,6 +4396,8 @@ struct cfg80211_ops { - int (*color_change)(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_color_change_settings *params); -+ int (*set_radar_offchan)(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef); - }; - - /* -@@ -7608,6 +7619,20 @@ void cfg80211_cac_event(struct net_devic - const struct cfg80211_chan_def *chandef, - enum nl80211_radar_event event, gfp_t gfp); - -+/** -+ * cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event -+ * @wiphy: the wiphy -+ * @chandef: chandef for the current channel -+ * @event: type of event -+ * -+ * This function is called when a Channel Availability Check (CAC) is finished, -+ * started or aborted by a offchannel dedicated chain. -+ * -+ * Note that this acquires the wiphy lock. -+ */ -+void cfg80211_offchan_cac_event(struct wiphy *wiphy, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event); - - /** - * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -2608,6 +2608,13 @@ enum nl80211_commands { - * Mandatory parameter for the transmitting interface to enable MBSSID. - * Optional for the non-transmitting interfaces. - * -+ * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for -+ * radar/CAC detection on some hw. This chain can't be used to transmit -+ * or receive frames and it is bounded to a running wdev. -+ * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * switching on a different channel during CAC detection on the selected -+ * radar channel. -+ * - * @NUM_NL80211_ATTR: total number of nl80211_attrs available - * @NL80211_ATTR_MAX: highest attribute number currently defined - * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3114,6 +3121,8 @@ enum nl80211_attrs { - NL80211_ATTR_MBSSID_CONFIG, - NL80211_ATTR_MBSSID_ELEMS, - -+ NL80211_ATTR_RADAR_OFFCHAN, -+ - /* add attributes here, update the policy in nl80211.c */ - - __NL80211_ATTR_AFTER_LAST, -@@ -6013,6 +6022,9 @@ enum nl80211_feature_flags { - * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision - * detection and change announcemnts. - * -+ * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC -+ * detection. -+ * - * @NUM_NL80211_EXT_FEATURES: number of extended features. - * @MAX_NL80211_EXT_FEATURES: highest extended feature index. - */ -@@ -6078,6 +6090,7 @@ enum nl80211_ext_feature_index { - NL80211_EXT_FEATURE_SECURE_RTT, - NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, - NL80211_EXT_FEATURE_BSS_COLOR, -+ NL80211_EXT_FEATURE_RADAR_OFFCHAN, - - /* add new features before the definition below */ - NUM_NL80211_EXT_FEATURES, ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -543,6 +543,7 @@ use_default_name: - INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); - INIT_WORK(&rdev->conn_work, cfg80211_conn_work); - INIT_WORK(&rdev->event_work, cfg80211_event_work); -+ INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work); - - init_waitqueue_head(&rdev->dev_wait); - -@@ -1205,6 +1206,8 @@ void __cfg80211_leave(struct cfg80211_re - - cfg80211_pmsr_wdev_down(wdev); - -+ cfg80211_stop_offchan_radar_detection(wdev); -+ - switch (wdev->iftype) { - case NL80211_IFTYPE_ADHOC: - __cfg80211_leave_ibss(rdev, dev, true); ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -84,6 +84,10 @@ struct cfg80211_registered_device { - - struct delayed_work dfs_update_channels_wk; - -+ struct wireless_dev *offchan_radar_wdev; -+ struct cfg80211_chan_def offchan_radar_chandef; -+ struct delayed_work offchan_cac_work; -+ - /* netlink port which started critical protocol (0 means not started) */ - u32 crit_proto_nlportid; - -@@ -491,6 +495,15 @@ cfg80211_chandef_dfs_cac_time(struct wip - - void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); - -+int -+cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef); -+ -+void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); -+ -+void cfg80211_offchan_cac_work(struct work_struct *work); -+ - bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan); - ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -970,3 +970,116 @@ void cfg80211_cac_event(struct net_devic - nl80211_radar_notify(rdev, chandef, event, netdev, gfp); - } - EXPORT_SYMBOL(cfg80211_cac_event); -+ -+void cfg80211_offchan_cac_work(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = to_delayed_work(work); -+ struct cfg80211_registered_device *rdev; -+ -+ rdev = container_of(delayed_work, struct cfg80211_registered_device, -+ offchan_cac_work); -+ cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef, -+ NL80211_RADAR_CAC_FINISHED); -+} -+ -+static void -+__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event) -+{ -+ struct wiphy *wiphy = &rdev->wiphy; -+ struct net_device *netdev; -+ -+ lockdep_assert_wiphy(&rdev->wiphy); -+ -+ if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) -+ return; -+ -+ switch (event) { -+ case NL80211_RADAR_CAC_FINISHED: -+ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); -+ memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); -+ queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); -+ cfg80211_sched_dfs_chan_update(rdev); -+ wdev = rdev->offchan_radar_wdev; -+ rdev->offchan_radar_wdev = NULL; -+ break; -+ case NL80211_RADAR_CAC_ABORTED: -+ cancel_delayed_work(&rdev->offchan_cac_work); -+ wdev = rdev->offchan_radar_wdev; -+ rdev->offchan_radar_wdev = NULL; -+ break; -+ case NL80211_RADAR_CAC_STARTED: -+ WARN_ON(!wdev); -+ rdev->offchan_radar_wdev = wdev; -+ break; -+ default: -+ return; -+ } -+ -+ netdev = wdev ? wdev->netdev : NULL; -+ nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL); -+} -+ -+void cfg80211_offchan_cac_event(struct wiphy *wiphy, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event) -+{ -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ -+ wiphy_lock(wiphy); -+ __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); -+ wiphy_unlock(wiphy); -+} -+EXPORT_SYMBOL(cfg80211_offchan_cac_event); -+ -+int -+cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef) -+{ -+ unsigned int cac_time_ms; -+ int err; -+ -+ lockdep_assert_wiphy(&rdev->wiphy); -+ -+ if (!wiphy_ext_feature_isset(&rdev->wiphy, -+ NL80211_EXT_FEATURE_RADAR_OFFCHAN)) -+ return -EOPNOTSUPP; -+ -+ if (rdev->offchan_radar_wdev) -+ return -EBUSY; -+ -+ err = rdev_set_radar_offchan(rdev, chandef); -+ if (err) -+ return err; -+ -+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, chandef); -+ if (!cac_time_ms) -+ cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; -+ -+ rdev->offchan_radar_chandef = *chandef; -+ __cfg80211_offchan_cac_event(rdev, wdev, chandef, -+ NL80211_RADAR_CAC_STARTED); -+ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work, -+ msecs_to_jiffies(cac_time_ms)); -+ -+ return 0; -+} -+ -+void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) -+{ -+ struct wiphy *wiphy = wdev->wiphy; -+ struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); -+ -+ lockdep_assert_wiphy(wiphy); -+ -+ if (wdev != rdev->offchan_radar_wdev) -+ return; -+ -+ rdev_set_radar_offchan(rdev, NULL); -+ -+ __cfg80211_offchan_cac_event(rdev, NULL, NULL, -+ NL80211_RADAR_CAC_ABORTED); -+} ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -801,6 +801,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_MBSSID_CONFIG] = - NLA_POLICY_NESTED(nl80211_mbssid_config_policy), - [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, -+ [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, - }; - - /* policy for the key attributes */ -@@ -9287,12 +9288,6 @@ static int nl80211_start_radar_detection - if (err) - return err; - -- if (netif_carrier_ok(dev)) -- return -EBUSY; -- -- if (wdev->cac_started) -- return -EBUSY; -- - err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); - if (err < 0) - return err; -@@ -9303,6 +9298,16 @@ static int nl80211_start_radar_detection - if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) - return -EINVAL; - -+ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) -+ return cfg80211_start_offchan_radar_detection(rdev, wdev, -+ &chandef); -+ -+ if (netif_carrier_ok(dev)) -+ return -EBUSY; -+ -+ if (wdev->cac_started) -+ return -EBUSY; -+ - /* CAC start is offloaded to HW and can't be started manually */ - if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) - return -EOPNOTSUPP; ---- a/net/wireless/rdev-ops.h -+++ b/net/wireless/rdev-ops.h -@@ -1381,4 +1381,21 @@ static inline int rdev_color_change(stru - return ret; - } - -+static inline int -+rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct wiphy *wiphy = &rdev->wiphy; -+ int ret; -+ -+ if (!rdev->ops->set_radar_offchan) -+ return -EOPNOTSUPP; -+ -+ trace_rdev_set_radar_offchan(wiphy, chandef); -+ ret = rdev->ops->set_radar_offchan(wiphy, chandef); -+ trace_rdev_return_int(wiphy, ret); -+ -+ return ret; -+} -+ - #endif /* __CFG80211_RDEV_OPS */ ---- a/net/wireless/trace.h -+++ b/net/wireless/trace.h -@@ -3643,6 +3643,25 @@ TRACE_EVENT(cfg80211_bss_color_notify, - __entry->color_bitmap) - ); - -+TRACE_EVENT(rdev_set_radar_offchan, -+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), -+ -+ TP_ARGS(wiphy, chandef), -+ -+ TP_STRUCT__entry( -+ WIPHY_ENTRY -+ CHAN_DEF_ENTRY -+ ), -+ -+ TP_fast_assign( -+ WIPHY_ASSIGN; -+ CHAN_DEF_ASSIGN(chandef) -+ ), -+ -+ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, -+ WIPHY_PR_ARG, CHAN_DEF_PR_ARG) -+); -+ - #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ - - #undef TRACE_INCLUDE_PATH diff --git a/package/kernel/mac80211/patches/subsys/315-v5.17-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch b/package/kernel/mac80211/patches/subsys/315-v5.17-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch deleted file mode 100644 index b1a1d2c894..0000000000 --- a/package/kernel/mac80211/patches/subsys/315-v5.17-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch +++ /dev/null @@ -1,183 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 27 Oct 2021 11:03:42 +0200 -Subject: [PATCH] cfg80211: move offchan_cac_event to a dedicated work - -In order to make cfg80211_offchan_cac_abort() (renamed from -cfg80211_offchan_cac_event) callable in other contexts and -without so much locking restrictions, make it trigger a new -work instead of operating directly. - -Do some other renames while at it to clarify. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/6145c3d0f30400a568023f67981981d24c7c6133.1635325205.git.lorenzo@kernel.org -[rewrite commit log] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -7620,19 +7620,13 @@ void cfg80211_cac_event(struct net_devic - enum nl80211_radar_event event, gfp_t gfp); - - /** -- * cfg80211_offchan_cac_event - Channel Availability Check (CAC) offchan event -+ * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event - * @wiphy: the wiphy -- * @chandef: chandef for the current channel -- * @event: type of event - * -- * This function is called when a Channel Availability Check (CAC) is finished, -- * started or aborted by a offchannel dedicated chain. -- * -- * Note that this acquires the wiphy lock. -+ * This function is called by the driver when a Channel Availability Check -+ * (CAC) is aborted by a offchannel dedicated chain. - */ --void cfg80211_offchan_cac_event(struct wiphy *wiphy, -- const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event); -+void cfg80211_offchan_cac_abort(struct wiphy *wiphy); - - /** - * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -543,7 +543,9 @@ use_default_name: - INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); - INIT_WORK(&rdev->conn_work, cfg80211_conn_work); - INIT_WORK(&rdev->event_work, cfg80211_event_work); -- INIT_DELAYED_WORK(&rdev->offchan_cac_work, cfg80211_offchan_cac_work); -+ INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); -+ INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, -+ cfg80211_offchan_cac_done_wk); - - init_waitqueue_head(&rdev->dev_wait); - -@@ -1053,11 +1055,13 @@ void wiphy_unregister(struct wiphy *wiph - cancel_work_sync(&rdev->conn_work); - flush_work(&rdev->event_work); - cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); -+ cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); - flush_work(&rdev->destroy_work); - flush_work(&rdev->sched_scan_stop_wk); - flush_work(&rdev->propagate_radar_detect_wk); - flush_work(&rdev->propagate_cac_done_wk); - flush_work(&rdev->mgmt_registrations_update_wk); -+ flush_work(&rdev->offchan_cac_abort_wk); - - #ifdef CONFIG_PM - if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -86,7 +86,8 @@ struct cfg80211_registered_device { - - struct wireless_dev *offchan_radar_wdev; - struct cfg80211_chan_def offchan_radar_chandef; -- struct delayed_work offchan_cac_work; -+ struct delayed_work offchan_cac_done_wk; -+ struct work_struct offchan_cac_abort_wk; - - /* netlink port which started critical protocol (0 means not started) */ - u32 crit_proto_nlportid; -@@ -502,7 +503,9 @@ cfg80211_start_offchan_radar_detection(s - - void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); - --void cfg80211_offchan_cac_work(struct work_struct *work); -+void cfg80211_offchan_cac_done_wk(struct work_struct *work); -+ -+void cfg80211_offchan_cac_abort_wk(struct work_struct *work); - - bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan); ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -971,17 +971,6 @@ void cfg80211_cac_event(struct net_devic - } - EXPORT_SYMBOL(cfg80211_cac_event); - --void cfg80211_offchan_cac_work(struct work_struct *work) --{ -- struct delayed_work *delayed_work = to_delayed_work(work); -- struct cfg80211_registered_device *rdev; -- -- rdev = container_of(delayed_work, struct cfg80211_registered_device, -- offchan_cac_work); -- cfg80211_offchan_cac_event(&rdev->wiphy, &rdev->offchan_radar_chandef, -- NL80211_RADAR_CAC_FINISHED); --} -- - static void - __cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, - struct wireless_dev *wdev, -@@ -1006,7 +995,7 @@ __cfg80211_offchan_cac_event(struct cfg8 - rdev->offchan_radar_wdev = NULL; - break; - case NL80211_RADAR_CAC_ABORTED: -- cancel_delayed_work(&rdev->offchan_cac_work); -+ cancel_delayed_work(&rdev->offchan_cac_done_wk); - wdev = rdev->offchan_radar_wdev; - rdev->offchan_radar_wdev = NULL; - break; -@@ -1022,17 +1011,44 @@ __cfg80211_offchan_cac_event(struct cfg8 - nl80211_radar_notify(rdev, chandef, event, netdev, GFP_KERNEL); - } - --void cfg80211_offchan_cac_event(struct wiphy *wiphy, -- const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event) -+static void -+cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event) -+{ -+ wiphy_lock(&rdev->wiphy); -+ __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); -+ wiphy_unlock(&rdev->wiphy); -+} -+ -+void cfg80211_offchan_cac_done_wk(struct work_struct *work) -+{ -+ struct delayed_work *delayed_work = to_delayed_work(work); -+ struct cfg80211_registered_device *rdev; -+ -+ rdev = container_of(delayed_work, struct cfg80211_registered_device, -+ offchan_cac_done_wk); -+ cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -+ NL80211_RADAR_CAC_FINISHED); -+} -+ -+void cfg80211_offchan_cac_abort_wk(struct work_struct *work) -+{ -+ struct cfg80211_registered_device *rdev; -+ -+ rdev = container_of(work, struct cfg80211_registered_device, -+ offchan_cac_abort_wk); -+ cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -+ NL80211_RADAR_CAC_ABORTED); -+} -+ -+void cfg80211_offchan_cac_abort(struct wiphy *wiphy) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - -- wiphy_lock(wiphy); -- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); -- wiphy_unlock(wiphy); -+ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); - } --EXPORT_SYMBOL(cfg80211_offchan_cac_event); -+EXPORT_SYMBOL(cfg80211_offchan_cac_abort); - - int - cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -@@ -1062,7 +1078,7 @@ cfg80211_start_offchan_radar_detection(s - rdev->offchan_radar_chandef = *chandef; - __cfg80211_offchan_cac_event(rdev, wdev, chandef, - NL80211_RADAR_CAC_STARTED); -- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_work, -+ queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, - msecs_to_jiffies(cac_time_ms)); - - return 0; diff --git a/package/kernel/mac80211/patches/subsys/316-v5.17-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch b/package/kernel/mac80211/patches/subsys/316-v5.17-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch deleted file mode 100644 index 362bb885d7..0000000000 --- a/package/kernel/mac80211/patches/subsys/316-v5.17-cfg80211-fix-possible-NULL-pointer-dereference-in-cf.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: Lorenzo Bianconi -Date: Wed, 3 Nov 2021 18:02:35 +0100 -Subject: [PATCH] cfg80211: fix possible NULL pointer dereference in - cfg80211_stop_offchan_radar_detection - -Fix the following NULL pointer dereference in -cfg80211_stop_offchan_radar_detection routine that occurs when hostapd -is stopped during the CAC on offchannel chain: - -Sat Jan 1 0[ 779.567851] ESR = 0x96000005 -0:12:50 2000 dae[ 779.572346] EC = 0x25: DABT (current EL), IL = 32 bits -mon.debug hostap[ 779.578984] SET = 0, FnV = 0 -d: hostapd_inter[ 779.583445] EA = 0, S1PTW = 0 -face_deinit_free[ 779.587936] Data abort info: -: num_bss=1 conf[ 779.592224] ISV = 0, ISS = 0x00000005 -->num_bss=1 -Sat[ 779.597403] CM = 0, WnR = 0 - Jan 1 00:12:50[ 779.601749] user pgtable: 4k pages, 39-bit VAs, pgdp=00000000418b2000 - 2000 daemon.deb[ 779.609601] [0000000000000000] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 -ug hostapd: host[ 779.619657] Internal error: Oops: 96000005 [#1] SMP -[ 779.770810] CPU: 0 PID: 2202 Comm: hostapd Not tainted 5.10.75 #0 -[ 779.776892] Hardware name: MediaTek MT7622 RFB1 board (DT) -[ 779.782370] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO BTYPE=--) -[ 779.788384] pc : cfg80211_chandef_valid+0x10/0x490 [cfg80211] -[ 779.794128] lr : cfg80211_check_station_change+0x3190/0x3950 [cfg80211] -[ 779.800731] sp : ffffffc01204b7e0 -[ 779.804036] x29: ffffffc01204b7e0 x28: ffffff80039bdc00 -[ 779.809340] x27: 0000000000000000 x26: ffffffc008cb3050 -[ 779.814644] x25: 0000000000000000 x24: 0000000000000002 -[ 779.819948] x23: ffffff8002630000 x22: ffffff8003e748d0 -[ 779.825252] x21: 0000000000000cc0 x20: ffffff8003da4a00 -[ 779.830556] x19: 0000000000000000 x18: ffffff8001bf7ce0 -[ 779.835860] x17: 00000000ffffffff x16: 0000000000000000 -[ 779.841164] x15: 0000000040d59200 x14: 00000000000019c0 -[ 779.846467] x13: 00000000000001c8 x12: 000636b9e9dab1c6 -[ 779.851771] x11: 0000000000000141 x10: 0000000000000820 -[ 779.857076] x9 : 0000000000000000 x8 : ffffff8003d7d038 -[ 779.862380] x7 : 0000000000000000 x6 : ffffff8003d7d038 -[ 779.867683] x5 : 0000000000000e90 x4 : 0000000000000038 -[ 779.872987] x3 : 0000000000000002 x2 : 0000000000000004 -[ 779.878291] x1 : 0000000000000000 x0 : 0000000000000000 -[ 779.883594] Call trace: -[ 779.886039] cfg80211_chandef_valid+0x10/0x490 [cfg80211] -[ 779.891434] cfg80211_check_station_change+0x3190/0x3950 [cfg80211] -[ 779.897697] nl80211_radar_notify+0x138/0x19c [cfg80211] -[ 779.903005] cfg80211_stop_offchan_radar_detection+0x7c/0x8c [cfg80211] -[ 779.909616] __cfg80211_leave+0x2c/0x190 [cfg80211] -[ 779.914490] cfg80211_register_netdevice+0x1c0/0x6d0 [cfg80211] -[ 779.920404] raw_notifier_call_chain+0x50/0x70 -[ 779.924841] call_netdevice_notifiers_info+0x54/0xa0 -[ 779.929796] __dev_close_many+0x40/0x100 -[ 779.933712] __dev_change_flags+0x98/0x190 -[ 779.937800] dev_change_flags+0x20/0x60 -[ 779.941628] devinet_ioctl+0x534/0x6d0 -[ 779.945370] inet_ioctl+0x1bc/0x230 -[ 779.948849] sock_do_ioctl+0x44/0x200 -[ 779.952502] sock_ioctl+0x268/0x4c0 -[ 779.955985] __arm64_sys_ioctl+0xac/0xd0 -[ 779.959900] el0_svc_common.constprop.0+0x60/0x110 -[ 779.964682] do_el0_svc+0x1c/0x24 -[ 779.967990] el0_svc+0x10/0x1c -[ 779.971036] el0_sync_handler+0x9c/0x120 -[ 779.974950] el0_sync+0x148/0x180 -[ 779.978259] Code: a9bc7bfd 910003fd a90153f3 aa0003f3 (f9400000) -[ 779.984344] ---[ end trace 0e67b4f5d6cdeec7 ]--- -[ 779.996400] Kernel panic - not syncing: Oops: Fatal exception -[ 780.002139] SMP: stopping secondary CPUs -[ 780.006057] Kernel Offset: disabled -[ 780.009537] CPU features: 0x0000002,04002004 -[ 780.013796] Memory Limit: none - -Fixes: b8f5facf286b ("cfg80211: implement APIs for dedicated radar detection HW") -Reported-by: Evelyn Tsai -Tested-by: Evelyn Tsai -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/c2e34c065bf8839c5ffa45498ae154021a72a520.1635958796.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -982,6 +982,9 @@ __cfg80211_offchan_cac_event(struct cfg8 - - lockdep_assert_wiphy(&rdev->wiphy); - -+ if (!cfg80211_chandef_valid(chandef)) -+ return; -+ - if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) - return; - -@@ -1096,6 +1099,6 @@ void cfg80211_stop_offchan_radar_detecti - - rdev_set_radar_offchan(rdev, NULL); - -- __cfg80211_offchan_cac_event(rdev, NULL, NULL, -+ __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, - NL80211_RADAR_CAC_ABORTED); - } diff --git a/package/kernel/mac80211/patches/subsys/317-v5.17-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch b/package/kernel/mac80211/patches/subsys/317-v5.17-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch deleted file mode 100644 index df7afefb34..0000000000 --- a/package/kernel/mac80211/patches/subsys/317-v5.17-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch +++ /dev/null @@ -1,136 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 16 Nov 2021 12:41:52 +0100 -Subject: [PATCH] cfg80211: schedule offchan_cac_abort_wk in - cfg80211_radar_event - -If necessary schedule offchan_cac_abort_wk work in cfg80211_radar_event -routine adding offchan parameter to cfg80211_radar_event signature. -Rename cfg80211_radar_event in __cfg80211_radar_event and introduce -the two following inline helpers: -- cfg80211_radar_event -- cfg80211_offchan_radar_event -Doing so the drv will not need to run cfg80211_offchan_cac_abort() after -radar detection on the offchannel chain. - -Tested-by: Owen Peng -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/3ff583e021e3343a3ced54a7b09b5e184d1880dc.1637062727.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -7580,15 +7580,33 @@ void cfg80211_cqm_txe_notify(struct net_ - void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp); - - /** -- * cfg80211_radar_event - radar detection event -+ * __cfg80211_radar_event - radar detection event - * @wiphy: the wiphy - * @chandef: chandef for the current channel -+ * @offchan: the radar has been detected on the offchannel chain - * @gfp: context flags - * - * This function is called when a radar is detected on the current chanenl. - */ --void cfg80211_radar_event(struct wiphy *wiphy, -- struct cfg80211_chan_def *chandef, gfp_t gfp); -+void __cfg80211_radar_event(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef, -+ bool offchan, gfp_t gfp); -+ -+static inline void -+cfg80211_radar_event(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef, -+ gfp_t gfp) -+{ -+ __cfg80211_radar_event(wiphy, chandef, false, gfp); -+} -+ -+static inline void -+cfg80211_offchan_radar_event(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef, -+ gfp_t gfp) -+{ -+ __cfg80211_radar_event(wiphy, chandef, true, gfp); -+} - - /** - * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -905,13 +905,13 @@ void cfg80211_dfs_channels_update_work(s - } - - --void cfg80211_radar_event(struct wiphy *wiphy, -- struct cfg80211_chan_def *chandef, -- gfp_t gfp) -+void __cfg80211_radar_event(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef, -+ bool offchan, gfp_t gfp) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - -- trace_cfg80211_radar_event(wiphy, chandef); -+ trace_cfg80211_radar_event(wiphy, chandef, offchan); - - /* only set the chandef supplied channel to unavailable, in - * case the radar is detected on only one of multiple channels -@@ -919,6 +919,9 @@ void cfg80211_radar_event(struct wiphy * - */ - cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); - -+ if (offchan) -+ queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -+ - cfg80211_sched_dfs_chan_update(rdev); - - nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp); -@@ -926,7 +929,7 @@ void cfg80211_radar_event(struct wiphy * - memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def)); - queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk); - } --EXPORT_SYMBOL(cfg80211_radar_event); -+EXPORT_SYMBOL(__cfg80211_radar_event); - - void cfg80211_cac_event(struct net_device *netdev, - const struct cfg80211_chan_def *chandef, -@@ -998,7 +1001,8 @@ __cfg80211_offchan_cac_event(struct cfg8 - rdev->offchan_radar_wdev = NULL; - break; - case NL80211_RADAR_CAC_ABORTED: -- cancel_delayed_work(&rdev->offchan_cac_done_wk); -+ if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) -+ return; - wdev = rdev->offchan_radar_wdev; - rdev->offchan_radar_wdev = NULL; - break; ---- a/net/wireless/trace.h -+++ b/net/wireless/trace.h -@@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_n - ); - - TRACE_EVENT(cfg80211_radar_event, -- TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), -- TP_ARGS(wiphy, chandef), -+ TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef, -+ bool offchan), -+ TP_ARGS(wiphy, chandef, offchan), - TP_STRUCT__entry( - WIPHY_ENTRY - CHAN_DEF_ENTRY -+ __field(bool, offchan) - ), - TP_fast_assign( - WIPHY_ASSIGN; - CHAN_DEF_ASSIGN(chandef); -+ __entry->offchan = offchan; - ), -- TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT, -- WIPHY_PR_ARG, CHAN_DEF_PR_ARG) -+ TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", offchan %d", -+ WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->offchan) - ); - - TRACE_EVENT(cfg80211_cac_event, diff --git a/package/kernel/mac80211/patches/subsys/318-v5.17-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch b/package/kernel/mac80211/patches/subsys/318-v5.17-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch deleted file mode 100644 index a1b6e3c80d..0000000000 --- a/package/kernel/mac80211/patches/subsys/318-v5.17-cfg80211-allow-continuous-radar-monitoring-on-offcha.patch +++ /dev/null @@ -1,220 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 16 Nov 2021 15:03:36 +0100 -Subject: [PATCH] cfg80211: allow continuous radar monitoring on offchannel - chain - -Allow continuous radar detection on the offchannel chain in order -to switch to the monitored channel whenever the underlying driver -reports a radar pattern on the main channel. - -Tested-by: Owen Peng -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/d46217310a49b14ff0e9c002f0a6e0547d70fd2c.1637071350.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/net/wireless/chan.c -+++ b/net/wireless/chan.c -@@ -712,6 +712,19 @@ static bool cfg80211_is_wiphy_oper_chan( - return false; - } - -+static bool -+cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, -+ struct ieee80211_channel *channel) -+{ -+ if (!rdev->offchan_radar_wdev) -+ return false; -+ -+ if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) -+ return false; -+ -+ return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); -+} -+ - bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan) - { -@@ -728,6 +741,9 @@ bool cfg80211_any_wiphy_oper_chan(struct - - if (cfg80211_is_wiphy_oper_chan(&rdev->wiphy, chan)) - return true; -+ -+ if (cfg80211_offchan_chain_is_active(rdev, chan)) -+ return true; - } - - return false; ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 - if (!cfg80211_chandef_valid(chandef)) - return; - -- if (event != NL80211_RADAR_CAC_STARTED && !rdev->offchan_radar_wdev) -+ if (!rdev->offchan_radar_wdev) - return; - - switch (event) { -@@ -998,17 +998,13 @@ __cfg80211_offchan_cac_event(struct cfg8 - queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); - cfg80211_sched_dfs_chan_update(rdev); - wdev = rdev->offchan_radar_wdev; -- rdev->offchan_radar_wdev = NULL; - break; - case NL80211_RADAR_CAC_ABORTED: - if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) - return; - wdev = rdev->offchan_radar_wdev; -- rdev->offchan_radar_wdev = NULL; - break; - case NL80211_RADAR_CAC_STARTED: -- WARN_ON(!wdev); -- rdev->offchan_radar_wdev = wdev; - break; - default: - return; -@@ -1024,7 +1020,8 @@ cfg80211_offchan_cac_event(struct cfg802 - enum nl80211_radar_event event) - { - wiphy_lock(&rdev->wiphy); -- __cfg80211_offchan_cac_event(rdev, NULL, chandef, event); -+ __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, -+ chandef, event); - wiphy_unlock(&rdev->wiphy); - } - -@@ -1071,7 +1068,13 @@ cfg80211_start_offchan_radar_detection(s - NL80211_EXT_FEATURE_RADAR_OFFCHAN)) - return -EOPNOTSUPP; - -- if (rdev->offchan_radar_wdev) -+ /* Offchannel chain already locked by another wdev */ -+ if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) -+ return -EBUSY; -+ -+ /* CAC already in progress on the offchannel chain */ -+ if (rdev->offchan_radar_wdev == wdev && -+ delayed_work_pending(&rdev->offchan_cac_done_wk)) - return -EBUSY; - - err = rdev_set_radar_offchan(rdev, chandef); -@@ -1083,6 +1086,8 @@ cfg80211_start_offchan_radar_detection(s - cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; - - rdev->offchan_radar_chandef = *chandef; -+ rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ -+ - __cfg80211_offchan_cac_event(rdev, wdev, chandef, - NL80211_RADAR_CAC_STARTED); - queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, -@@ -1102,6 +1107,7 @@ void cfg80211_stop_offchan_radar_detecti - return; - - rdev_set_radar_offchan(rdev, NULL); -+ rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ - - __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, - NL80211_RADAR_CAC_ABORTED); ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -9278,42 +9278,60 @@ static int nl80211_start_radar_detection - struct cfg80211_chan_def chandef; - enum nl80211_dfs_regions dfs_region; - unsigned int cac_time_ms; -- int err; -+ int err = -EINVAL; -+ -+ flush_delayed_work(&rdev->dfs_update_channels_wk); -+ -+ wiphy_lock(wiphy); - - dfs_region = reg_get_dfs_region(wiphy); - if (dfs_region == NL80211_DFS_UNSET) -- return -EINVAL; -+ goto unlock; - - err = nl80211_parse_chandef(rdev, info, &chandef); - if (err) -- return err; -+ goto unlock; - - err = cfg80211_chandef_dfs_required(wiphy, &chandef, wdev->iftype); - if (err < 0) -- return err; -+ goto unlock; - -- if (err == 0) -- return -EINVAL; -+ if (err == 0) { -+ err = -EINVAL; -+ goto unlock; -+ } - -- if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) -- return -EINVAL; -+ if (!cfg80211_chandef_dfs_usable(wiphy, &chandef)) { -+ err = -EINVAL; -+ goto unlock; -+ } - -- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) -- return cfg80211_start_offchan_radar_detection(rdev, wdev, -- &chandef); -+ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { -+ err = cfg80211_start_offchan_radar_detection(rdev, wdev, -+ &chandef); -+ goto unlock; -+ } - -- if (netif_carrier_ok(dev)) -- return -EBUSY; -+ if (netif_carrier_ok(dev)) { -+ err = -EBUSY; -+ goto unlock; -+ } - -- if (wdev->cac_started) -- return -EBUSY; -+ if (wdev->cac_started) { -+ err = -EBUSY; -+ goto unlock; -+ } - - /* CAC start is offloaded to HW and can't be started manually */ -- if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) -- return -EOPNOTSUPP; -+ if (wiphy_ext_feature_isset(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD)) { -+ err = -EOPNOTSUPP; -+ goto unlock; -+ } - -- if (!rdev->ops->start_radar_detection) -- return -EOPNOTSUPP; -+ if (!rdev->ops->start_radar_detection) { -+ err = -EOPNOTSUPP; -+ goto unlock; -+ } - - cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef); - if (WARN_ON(!cac_time_ms)) -@@ -9326,6 +9344,9 @@ static int nl80211_start_radar_detection - wdev->cac_start_time = jiffies; - wdev->cac_time_ms = cac_time_ms; - } -+unlock: -+ wiphy_unlock(wiphy); -+ - return err; - } - -@@ -15961,7 +15982,8 @@ static const struct genl_small_ops nl802 - .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, - .doit = nl80211_start_radar_detection, - .flags = GENL_UNS_ADMIN_PERM, -- .internal_flags = NL80211_FLAG_NEED_NETDEV_UP, -+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | -+ NL80211_FLAG_NO_WIPHY_MTX, - }, - { - .cmd = NL80211_CMD_GET_PROTOCOL_FEATURES, diff --git a/package/kernel/mac80211/patches/subsys/319-v5.17-mac80211-introduce-set_radar_offchan-callback.patch b/package/kernel/mac80211/patches/subsys/319-v5.17-mac80211-introduce-set_radar_offchan-callback.patch deleted file mode 100644 index 6197abda56..0000000000 --- a/package/kernel/mac80211/patches/subsys/319-v5.17-mac80211-introduce-set_radar_offchan-callback.patch +++ /dev/null @@ -1,67 +0,0 @@ -From: Lorenzo Bianconi -Date: Sat, 23 Oct 2021 11:10:51 +0200 -Subject: [PATCH] mac80211: introduce set_radar_offchan callback - -Similar to cfg80211, introduce set_radar_offchan callback in mac80211_ops -in order to configure a dedicated offchannel chain available on some hw -(e.g. mt7915) to perform offchannel CAC detection and avoid tx/rx downtime. - -Tested-by: Evelyn Tsai -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/201110606d4f3a7dfdf31440e351f2e2c375d4f0.1634979655.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -3937,6 +3937,14 @@ struct ieee80211_prep_tx_info { - * twt structure. - * @twt_teardown_request: Update the hw with TWT teardown request received - * from the peer. -+ * @set_radar_offchan: Configure dedicated offchannel chain available for -+ * radar/CAC detection on some hw. This chain can't be used to transmit -+ * or receive frames and it is bounded to a running wdev. -+ * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * switching to a different channel during CAC detection on the selected -+ * radar channel. -+ * The caller is expected to set chandef pointer to NULL in order to -+ * disable offchannel CAC/radar detection. - * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to - * resolve a path for hardware flow offloading - */ -@@ -4267,6 +4275,8 @@ struct ieee80211_ops { - struct ieee80211_twt_setup *twt); - void (*twt_teardown_request)(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 flowid); -+ int (*set_radar_offchan)(struct ieee80211_hw *hw, -+ struct cfg80211_chan_def *chandef); - #if LINUX_VERSION_IS_GEQ(5,10,0) - int (*net_fill_forward_path)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -4341,6 +4341,18 @@ out: - return err; - } - -+static int -+ieee80211_set_radar_offchan(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) -+{ -+ struct ieee80211_local *local = wiphy_priv(wiphy); -+ -+ if (!local->ops->set_radar_offchan) -+ return -EOPNOTSUPP; -+ -+ return local->ops->set_radar_offchan(&local->hw, chandef); -+} -+ - const struct cfg80211_ops mac80211_config_ops = { - .add_virtual_intf = ieee80211_add_iface, - .del_virtual_intf = ieee80211_del_iface, -@@ -4445,4 +4457,5 @@ const struct cfg80211_ops mac80211_confi - .reset_tid_config = ieee80211_reset_tid_config, - .set_sar_specs = ieee80211_set_sar_specs, - .color_change = ieee80211_color_change, -+ .set_radar_offchan = ieee80211_set_radar_offchan, - }; diff --git a/package/kernel/mac80211/patches/subsys/320-v5.17-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch b/package/kernel/mac80211/patches/subsys/320-v5.17-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch deleted file mode 100644 index 608e72468d..0000000000 --- a/package/kernel/mac80211/patches/subsys/320-v5.17-cfg80211-rename-offchannel_chain-structs-to-backgrou.patch +++ /dev/null @@ -1,532 +0,0 @@ -From: Lorenzo Bianconi -Date: Mon, 29 Nov 2021 14:11:24 +0100 -Subject: [PATCH] cfg80211: rename offchannel_chain structs to background_chain - to avoid confusion with ETSI standard - -ETSI standard defines "Offchannel CAC" as: -"Off-Channel CAC is performed by a number of non-continuous checks -spread over a period in time. This period, which is required to -determine the presence of radar signals, is defined as the Off-Channel -CAC Time.. -Minimum Off-Channel CAC Time 6 minutes and Maximum Off-Channel CAC Time -4 hours..". -mac80211 implementation refers to a dedicated hw chain used for continuous -radar monitoring. Rename offchannel_* references to background_* in -order to avoid confusion with ETSI standard. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/4204cc1d648d76b44557981713231e030a3bd991.1638190762.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -4058,14 +4058,14 @@ struct mgmt_frame_regs { - * - * @color_change: Initiate a color change. - * -- * @set_radar_offchan: Configure dedicated offchannel chain available for -+ * @set_radar_background: Configure dedicated offchannel chain available for - * radar/CAC detection on some hw. This chain can't be used to transmit - * or receive frames and it is bounded to a running wdev. -- * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * Background radar/CAC detection allows to avoid the CAC downtime - * switching to a different channel during CAC detection on the selected - * radar channel. - * The caller is expected to set chandef pointer to NULL in order to -- * disable offchannel CAC/radar detection. -+ * disable background CAC/radar detection. - */ - struct cfg80211_ops { - int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); -@@ -4396,8 +4396,8 @@ struct cfg80211_ops { - int (*color_change)(struct wiphy *wiphy, - struct net_device *dev, - struct cfg80211_color_change_settings *params); -- int (*set_radar_offchan)(struct wiphy *wiphy, -- struct cfg80211_chan_def *chandef); -+ int (*set_radar_background)(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef); - }; - - /* -@@ -7601,9 +7601,9 @@ cfg80211_radar_event(struct wiphy *wiphy - } - - static inline void --cfg80211_offchan_radar_event(struct wiphy *wiphy, -- struct cfg80211_chan_def *chandef, -- gfp_t gfp) -+cfg80211_background_radar_event(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef, -+ gfp_t gfp) - { - __cfg80211_radar_event(wiphy, chandef, true, gfp); - } -@@ -7638,13 +7638,13 @@ void cfg80211_cac_event(struct net_devic - enum nl80211_radar_event event, gfp_t gfp); - - /** -- * cfg80211_offchan_cac_abort - Channel Availability Check offchan abort event -+ * cfg80211_background_cac_abort - Channel Availability Check offchan abort event - * @wiphy: the wiphy - * - * This function is called by the driver when a Channel Availability Check - * (CAC) is aborted by a offchannel dedicated chain. - */ --void cfg80211_offchan_cac_abort(struct wiphy *wiphy); -+void cfg80211_background_cac_abort(struct wiphy *wiphy); - - /** - * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -3937,14 +3937,14 @@ struct ieee80211_prep_tx_info { - * twt structure. - * @twt_teardown_request: Update the hw with TWT teardown request received - * from the peer. -- * @set_radar_offchan: Configure dedicated offchannel chain available for -+ * @set_radar_background: Configure dedicated offchannel chain available for - * radar/CAC detection on some hw. This chain can't be used to transmit - * or receive frames and it is bounded to a running wdev. -- * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * Background radar/CAC detection allows to avoid the CAC downtime - * switching to a different channel during CAC detection on the selected - * radar channel. - * The caller is expected to set chandef pointer to NULL in order to -- * disable offchannel CAC/radar detection. -+ * disable background CAC/radar detection. - * @net_fill_forward_path: Called from .ndo_fill_forward_path in order to - * resolve a path for hardware flow offloading - */ -@@ -4275,8 +4275,8 @@ struct ieee80211_ops { - struct ieee80211_twt_setup *twt); - void (*twt_teardown_request)(struct ieee80211_hw *hw, - struct ieee80211_sta *sta, u8 flowid); -- int (*set_radar_offchan)(struct ieee80211_hw *hw, -- struct cfg80211_chan_def *chandef); -+ int (*set_radar_background)(struct ieee80211_hw *hw, -+ struct cfg80211_chan_def *chandef); - #if LINUX_VERSION_IS_GEQ(5,10,0) - int (*net_fill_forward_path)(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -2608,10 +2608,10 @@ enum nl80211_commands { - * Mandatory parameter for the transmitting interface to enable MBSSID. - * Optional for the non-transmitting interfaces. - * -- * @NL80211_ATTR_RADAR_OFFCHAN: Configure dedicated offchannel chain available for -- * radar/CAC detection on some hw. This chain can't be used to transmit -- * or receive frames and it is bounded to a running wdev. -- * Offchannel radar/CAC detection allows to avoid the CAC downtime -+ * @NL80211_ATTR_RADAR_BACKGROUND: Configure dedicated offchannel chain -+ * available for radar/CAC detection on some hw. This chain can't be used -+ * to transmit or receive frames and it is bounded to a running wdev. -+ * Background radar/CAC detection allows to avoid the CAC downtime - * switching on a different channel during CAC detection on the selected - * radar channel. - * -@@ -3121,7 +3121,7 @@ enum nl80211_attrs { - NL80211_ATTR_MBSSID_CONFIG, - NL80211_ATTR_MBSSID_ELEMS, - -- NL80211_ATTR_RADAR_OFFCHAN, -+ NL80211_ATTR_RADAR_BACKGROUND, - - /* add attributes here, update the policy in nl80211.c */ - -@@ -6022,7 +6022,7 @@ enum nl80211_feature_flags { - * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision - * detection and change announcemnts. - * -- * @NL80211_EXT_FEATURE_RADAR_OFFCHAN: Device supports offchannel radar/CAC -+ * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC - * detection. - * - * @NUM_NL80211_EXT_FEATURES: number of extended features. -@@ -6090,7 +6090,7 @@ enum nl80211_ext_feature_index { - NL80211_EXT_FEATURE_SECURE_RTT, - NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, - NL80211_EXT_FEATURE_BSS_COLOR, -- NL80211_EXT_FEATURE_RADAR_OFFCHAN, -+ NL80211_EXT_FEATURE_RADAR_BACKGROUND, - - /* add new features before the definition below */ - NUM_NL80211_EXT_FEATURES, ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -4342,15 +4342,15 @@ out: - } - - static int --ieee80211_set_radar_offchan(struct wiphy *wiphy, -- struct cfg80211_chan_def *chandef) -+ieee80211_set_radar_background(struct wiphy *wiphy, -+ struct cfg80211_chan_def *chandef) - { - struct ieee80211_local *local = wiphy_priv(wiphy); - -- if (!local->ops->set_radar_offchan) -+ if (!local->ops->set_radar_background) - return -EOPNOTSUPP; - -- return local->ops->set_radar_offchan(&local->hw, chandef); -+ return local->ops->set_radar_background(&local->hw, chandef); - } - - const struct cfg80211_ops mac80211_config_ops = { -@@ -4457,5 +4457,5 @@ const struct cfg80211_ops mac80211_confi - .reset_tid_config = ieee80211_reset_tid_config, - .set_sar_specs = ieee80211_set_sar_specs, - .color_change = ieee80211_color_change, -- .set_radar_offchan = ieee80211_set_radar_offchan, -+ .set_radar_background = ieee80211_set_radar_background, - }; ---- a/net/wireless/chan.c -+++ b/net/wireless/chan.c -@@ -716,13 +716,13 @@ static bool - cfg80211_offchan_chain_is_active(struct cfg80211_registered_device *rdev, - struct ieee80211_channel *channel) - { -- if (!rdev->offchan_radar_wdev) -+ if (!rdev->background_radar_wdev) - return false; - -- if (!cfg80211_chandef_valid(&rdev->offchan_radar_chandef)) -+ if (!cfg80211_chandef_valid(&rdev->background_radar_chandef)) - return false; - -- return cfg80211_is_sub_chan(&rdev->offchan_radar_chandef, channel); -+ return cfg80211_is_sub_chan(&rdev->background_radar_chandef, channel); - } - - bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, ---- a/net/wireless/core.c -+++ b/net/wireless/core.c -@@ -543,9 +543,10 @@ use_default_name: - INIT_WORK(&rdev->rfkill_block, cfg80211_rfkill_block_work); - INIT_WORK(&rdev->conn_work, cfg80211_conn_work); - INIT_WORK(&rdev->event_work, cfg80211_event_work); -- INIT_WORK(&rdev->offchan_cac_abort_wk, cfg80211_offchan_cac_abort_wk); -- INIT_DELAYED_WORK(&rdev->offchan_cac_done_wk, -- cfg80211_offchan_cac_done_wk); -+ INIT_WORK(&rdev->background_cac_abort_wk, -+ cfg80211_background_cac_abort_wk); -+ INIT_DELAYED_WORK(&rdev->background_cac_done_wk, -+ cfg80211_background_cac_done_wk); - - init_waitqueue_head(&rdev->dev_wait); - -@@ -1055,13 +1056,13 @@ void wiphy_unregister(struct wiphy *wiph - cancel_work_sync(&rdev->conn_work); - flush_work(&rdev->event_work); - cancel_delayed_work_sync(&rdev->dfs_update_channels_wk); -- cancel_delayed_work_sync(&rdev->offchan_cac_done_wk); -+ cancel_delayed_work_sync(&rdev->background_cac_done_wk); - flush_work(&rdev->destroy_work); - flush_work(&rdev->sched_scan_stop_wk); - flush_work(&rdev->propagate_radar_detect_wk); - flush_work(&rdev->propagate_cac_done_wk); - flush_work(&rdev->mgmt_registrations_update_wk); -- flush_work(&rdev->offchan_cac_abort_wk); -+ flush_work(&rdev->background_cac_abort_wk); - - #ifdef CONFIG_PM - if (rdev->wiphy.wowlan_config && rdev->ops->set_wakeup) -@@ -1210,7 +1211,7 @@ void __cfg80211_leave(struct cfg80211_re - - cfg80211_pmsr_wdev_down(wdev); - -- cfg80211_stop_offchan_radar_detection(wdev); -+ cfg80211_stop_background_radar_detection(wdev); - - switch (wdev->iftype) { - case NL80211_IFTYPE_ADHOC: ---- a/net/wireless/core.h -+++ b/net/wireless/core.h -@@ -84,10 +84,10 @@ struct cfg80211_registered_device { - - struct delayed_work dfs_update_channels_wk; - -- struct wireless_dev *offchan_radar_wdev; -- struct cfg80211_chan_def offchan_radar_chandef; -- struct delayed_work offchan_cac_done_wk; -- struct work_struct offchan_cac_abort_wk; -+ struct wireless_dev *background_radar_wdev; -+ struct cfg80211_chan_def background_radar_chandef; -+ struct delayed_work background_cac_done_wk; -+ struct work_struct background_cac_abort_wk; - - /* netlink port which started critical protocol (0 means not started) */ - u32 crit_proto_nlportid; -@@ -497,15 +497,15 @@ cfg80211_chandef_dfs_cac_time(struct wip - void cfg80211_sched_dfs_chan_update(struct cfg80211_registered_device *rdev); - - int --cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev, -- struct cfg80211_chan_def *chandef); -+cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef); - --void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev); -+void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev); - --void cfg80211_offchan_cac_done_wk(struct work_struct *work); -+void cfg80211_background_cac_done_wk(struct work_struct *work); - --void cfg80211_offchan_cac_abort_wk(struct work_struct *work); -+void cfg80211_background_cac_abort_wk(struct work_struct *work); - - bool cfg80211_any_wiphy_oper_chan(struct wiphy *wiphy, - struct ieee80211_channel *chan); ---- a/net/wireless/mlme.c -+++ b/net/wireless/mlme.c -@@ -920,7 +920,7 @@ void __cfg80211_radar_event(struct wiphy - cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE); - - if (offchan) -- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -+ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); - - cfg80211_sched_dfs_chan_update(rdev); - -@@ -975,10 +975,10 @@ void cfg80211_cac_event(struct net_devic - EXPORT_SYMBOL(cfg80211_cac_event); - - static void --__cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev, -- const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event) -+__cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event) - { - struct wiphy *wiphy = &rdev->wiphy; - struct net_device *netdev; -@@ -988,7 +988,7 @@ __cfg80211_offchan_cac_event(struct cfg8 - if (!cfg80211_chandef_valid(chandef)) - return; - -- if (!rdev->offchan_radar_wdev) -+ if (!rdev->background_radar_wdev) - return; - - switch (event) { -@@ -997,12 +997,12 @@ __cfg80211_offchan_cac_event(struct cfg8 - memcpy(&rdev->cac_done_chandef, chandef, sizeof(*chandef)); - queue_work(cfg80211_wq, &rdev->propagate_cac_done_wk); - cfg80211_sched_dfs_chan_update(rdev); -- wdev = rdev->offchan_radar_wdev; -+ wdev = rdev->background_radar_wdev; - break; - case NL80211_RADAR_CAC_ABORTED: -- if (!cancel_delayed_work(&rdev->offchan_cac_done_wk)) -+ if (!cancel_delayed_work(&rdev->background_cac_done_wk)) - return; -- wdev = rdev->offchan_radar_wdev; -+ wdev = rdev->background_radar_wdev; - break; - case NL80211_RADAR_CAC_STARTED: - break; -@@ -1015,49 +1015,49 @@ __cfg80211_offchan_cac_event(struct cfg8 - } - - static void --cfg80211_offchan_cac_event(struct cfg80211_registered_device *rdev, -- const struct cfg80211_chan_def *chandef, -- enum nl80211_radar_event event) -+cfg80211_background_cac_event(struct cfg80211_registered_device *rdev, -+ const struct cfg80211_chan_def *chandef, -+ enum nl80211_radar_event event) - { - wiphy_lock(&rdev->wiphy); -- __cfg80211_offchan_cac_event(rdev, rdev->offchan_radar_wdev, -- chandef, event); -+ __cfg80211_background_cac_event(rdev, rdev->background_radar_wdev, -+ chandef, event); - wiphy_unlock(&rdev->wiphy); - } - --void cfg80211_offchan_cac_done_wk(struct work_struct *work) -+void cfg80211_background_cac_done_wk(struct work_struct *work) - { - struct delayed_work *delayed_work = to_delayed_work(work); - struct cfg80211_registered_device *rdev; - - rdev = container_of(delayed_work, struct cfg80211_registered_device, -- offchan_cac_done_wk); -- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -- NL80211_RADAR_CAC_FINISHED); -+ background_cac_done_wk); -+ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, -+ NL80211_RADAR_CAC_FINISHED); - } - --void cfg80211_offchan_cac_abort_wk(struct work_struct *work) -+void cfg80211_background_cac_abort_wk(struct work_struct *work) - { - struct cfg80211_registered_device *rdev; - - rdev = container_of(work, struct cfg80211_registered_device, -- offchan_cac_abort_wk); -- cfg80211_offchan_cac_event(rdev, &rdev->offchan_radar_chandef, -- NL80211_RADAR_CAC_ABORTED); -+ background_cac_abort_wk); -+ cfg80211_background_cac_event(rdev, &rdev->background_radar_chandef, -+ NL80211_RADAR_CAC_ABORTED); - } - --void cfg80211_offchan_cac_abort(struct wiphy *wiphy) -+void cfg80211_background_cac_abort(struct wiphy *wiphy) - { - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - -- queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk); -+ queue_work(cfg80211_wq, &rdev->background_cac_abort_wk); - } --EXPORT_SYMBOL(cfg80211_offchan_cac_abort); -+EXPORT_SYMBOL(cfg80211_background_cac_abort); - - int --cfg80211_start_offchan_radar_detection(struct cfg80211_registered_device *rdev, -- struct wireless_dev *wdev, -- struct cfg80211_chan_def *chandef) -+cfg80211_start_background_radar_detection(struct cfg80211_registered_device *rdev, -+ struct wireless_dev *wdev, -+ struct cfg80211_chan_def *chandef) - { - unsigned int cac_time_ms; - int err; -@@ -1065,19 +1065,19 @@ cfg80211_start_offchan_radar_detection(s - lockdep_assert_wiphy(&rdev->wiphy); - - if (!wiphy_ext_feature_isset(&rdev->wiphy, -- NL80211_EXT_FEATURE_RADAR_OFFCHAN)) -+ NL80211_EXT_FEATURE_RADAR_BACKGROUND)) - return -EOPNOTSUPP; - - /* Offchannel chain already locked by another wdev */ -- if (rdev->offchan_radar_wdev && rdev->offchan_radar_wdev != wdev) -+ if (rdev->background_radar_wdev && rdev->background_radar_wdev != wdev) - return -EBUSY; - - /* CAC already in progress on the offchannel chain */ -- if (rdev->offchan_radar_wdev == wdev && -- delayed_work_pending(&rdev->offchan_cac_done_wk)) -+ if (rdev->background_radar_wdev == wdev && -+ delayed_work_pending(&rdev->background_cac_done_wk)) - return -EBUSY; - -- err = rdev_set_radar_offchan(rdev, chandef); -+ err = rdev_set_radar_background(rdev, chandef); - if (err) - return err; - -@@ -1085,30 +1085,31 @@ cfg80211_start_offchan_radar_detection(s - if (!cac_time_ms) - cac_time_ms = IEEE80211_DFS_MIN_CAC_TIME_MS; - -- rdev->offchan_radar_chandef = *chandef; -- rdev->offchan_radar_wdev = wdev; /* Get offchain ownership */ -+ rdev->background_radar_chandef = *chandef; -+ rdev->background_radar_wdev = wdev; /* Get offchain ownership */ - -- __cfg80211_offchan_cac_event(rdev, wdev, chandef, -- NL80211_RADAR_CAC_STARTED); -- queue_delayed_work(cfg80211_wq, &rdev->offchan_cac_done_wk, -+ __cfg80211_background_cac_event(rdev, wdev, chandef, -+ NL80211_RADAR_CAC_STARTED); -+ queue_delayed_work(cfg80211_wq, &rdev->background_cac_done_wk, - msecs_to_jiffies(cac_time_ms)); - - return 0; - } - --void cfg80211_stop_offchan_radar_detection(struct wireless_dev *wdev) -+void cfg80211_stop_background_radar_detection(struct wireless_dev *wdev) - { - struct wiphy *wiphy = wdev->wiphy; - struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); - - lockdep_assert_wiphy(wiphy); - -- if (wdev != rdev->offchan_radar_wdev) -+ if (wdev != rdev->background_radar_wdev) - return; - -- rdev_set_radar_offchan(rdev, NULL); -- rdev->offchan_radar_wdev = NULL; /* Release offchain ownership */ -+ rdev_set_radar_background(rdev, NULL); -+ rdev->background_radar_wdev = NULL; /* Release offchain ownership */ - -- __cfg80211_offchan_cac_event(rdev, wdev, &rdev->offchan_radar_chandef, -- NL80211_RADAR_CAC_ABORTED); -+ __cfg80211_background_cac_event(rdev, wdev, -+ &rdev->background_radar_chandef, -+ NL80211_RADAR_CAC_ABORTED); - } ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -801,7 +801,7 @@ static const struct nla_policy nl80211_p - [NL80211_ATTR_MBSSID_CONFIG] = - NLA_POLICY_NESTED(nl80211_mbssid_config_policy), - [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, -- [NL80211_ATTR_RADAR_OFFCHAN] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, - }; - - /* policy for the key attributes */ -@@ -9306,9 +9306,9 @@ static int nl80211_start_radar_detection - goto unlock; - } - -- if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_OFFCHAN])) { -- err = cfg80211_start_offchan_radar_detection(rdev, wdev, -- &chandef); -+ if (nla_get_flag(info->attrs[NL80211_ATTR_RADAR_BACKGROUND])) { -+ err = cfg80211_start_background_radar_detection(rdev, wdev, -+ &chandef); - goto unlock; - } - ---- a/net/wireless/rdev-ops.h -+++ b/net/wireless/rdev-ops.h -@@ -1382,17 +1382,17 @@ static inline int rdev_color_change(stru - } - - static inline int --rdev_set_radar_offchan(struct cfg80211_registered_device *rdev, -- struct cfg80211_chan_def *chandef) -+rdev_set_radar_background(struct cfg80211_registered_device *rdev, -+ struct cfg80211_chan_def *chandef) - { - struct wiphy *wiphy = &rdev->wiphy; - int ret; - -- if (!rdev->ops->set_radar_offchan) -+ if (!rdev->ops->set_radar_background) - return -EOPNOTSUPP; - -- trace_rdev_set_radar_offchan(wiphy, chandef); -- ret = rdev->ops->set_radar_offchan(wiphy, chandef); -+ trace_rdev_set_radar_background(wiphy, chandef); -+ ret = rdev->ops->set_radar_background(wiphy, chandef); - trace_rdev_return_int(wiphy, ret); - - return ret; ---- a/net/wireless/trace.h -+++ b/net/wireless/trace.h -@@ -3646,7 +3646,7 @@ TRACE_EVENT(cfg80211_bss_color_notify, - __entry->color_bitmap) - ); - --TRACE_EVENT(rdev_set_radar_offchan, -+TRACE_EVENT(rdev_set_radar_background, - TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef), - - TP_ARGS(wiphy, chandef), diff --git a/package/kernel/mac80211/patches/subsys/323-v5.16-mac80211-MBSSID-support-in-interface-handling.patch b/package/kernel/mac80211/patches/subsys/323-v5.16-mac80211-MBSSID-support-in-interface-handling.patch deleted file mode 100644 index a135e3d1b5..0000000000 --- a/package/kernel/mac80211/patches/subsys/323-v5.16-mac80211-MBSSID-support-in-interface-handling.patch +++ /dev/null @@ -1,144 +0,0 @@ -From: John Crispin -Date: Wed, 15 Sep 2021 19:54:35 -0700 -Subject: [PATCH] mac80211: MBSSID support in interface handling - -Configure multiple BSSID and enhanced multi-BSSID advertisement (EMA) -parameters in mac80211 for AP mode. - -For each interface, 'mbssid_tx_vif' points to the transmitting interface of -the MBSSID set. The pointer is set to NULL if MBSSID is disabled. - -Function ieee80211_stop() is modified to always bring down all the -non-transmitting interfaces first and the transmitting interface last. - -Signed-off-by: John Crispin -Co-developed-by: Aloka Dixit -Signed-off-by: Aloka Dixit -Link: https://lore.kernel.org/r/20210916025437.29138-3-alokad@codeaurora.org -[slightly change logic to be more obvious] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1719,6 +1719,7 @@ enum ieee80211_offload_flags { - * 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. -+ * @mbssid_tx_vif: Pointer to the transmitting interface if MBSSID is enabled. - */ - struct ieee80211_vif { - enum nl80211_iftype type; -@@ -1750,6 +1751,8 @@ struct ieee80211_vif { - bool color_change_active; - u8 color_change_color; - -+ struct ieee80211_vif *mbssid_tx_vif; -+ - /* must be last */ - u8 drv_priv[] __aligned(sizeof(void *)); - }; ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -112,6 +112,36 @@ static int ieee80211_set_mon_options(str - return 0; - } - -+static int ieee80211_set_ap_mbssid_options(struct ieee80211_sub_if_data *sdata, -+ struct cfg80211_mbssid_config params) -+{ -+ struct ieee80211_sub_if_data *tx_sdata; -+ -+ sdata->vif.mbssid_tx_vif = NULL; -+ sdata->vif.bss_conf.bssid_index = 0; -+ sdata->vif.bss_conf.nontransmitted = false; -+ sdata->vif.bss_conf.ema_ap = false; -+ -+ if (sdata->vif.type != NL80211_IFTYPE_AP || !params.tx_wdev) -+ return -EINVAL; -+ -+ tx_sdata = IEEE80211_WDEV_TO_SUB_IF(params.tx_wdev); -+ if (!tx_sdata) -+ return -EINVAL; -+ -+ if (tx_sdata == sdata) { -+ sdata->vif.mbssid_tx_vif = &sdata->vif; -+ } else { -+ sdata->vif.mbssid_tx_vif = &tx_sdata->vif; -+ sdata->vif.bss_conf.nontransmitted = true; -+ sdata->vif.bss_conf.bssid_index = params.index; -+ } -+ if (params.ema) -+ sdata->vif.bss_conf.ema_ap = true; -+ -+ return 0; -+} -+ - static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, - const char *name, - unsigned char name_assign_type, -@@ -1107,6 +1137,14 @@ static int ieee80211_start_ap(struct wip - changed |= BSS_CHANGED_HE_BSS_COLOR; - } - -+ if (sdata->vif.type == NL80211_IFTYPE_AP && -+ params->mbssid_config.tx_wdev) { -+ err = ieee80211_set_ap_mbssid_options(sdata, -+ params->mbssid_config); -+ if (err) -+ return err; -+ } -+ - mutex_lock(&local->mtx); - err = ieee80211_vif_use_channel(sdata, ¶ms->chandef, - IEEE80211_CHANCTX_SHARED); ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -632,17 +632,46 @@ static void ieee80211_do_stop(struct iee - ieee80211_add_virtual_monitor(local); - } - -+static void ieee80211_stop_mbssid(struct ieee80211_sub_if_data *sdata) -+{ -+ struct ieee80211_sub_if_data *tx_sdata, *non_tx_sdata, *tmp_sdata; -+ struct ieee80211_vif *tx_vif = sdata->vif.mbssid_tx_vif; -+ -+ if (!tx_vif) -+ return; -+ -+ tx_sdata = vif_to_sdata(tx_vif); -+ sdata->vif.mbssid_tx_vif = NULL; -+ -+ list_for_each_entry_safe(non_tx_sdata, tmp_sdata, -+ &tx_sdata->local->interfaces, list) { -+ if (non_tx_sdata != sdata && non_tx_sdata != tx_sdata && -+ non_tx_sdata->vif.mbssid_tx_vif == tx_vif && -+ ieee80211_sdata_running(non_tx_sdata)) { -+ non_tx_sdata->vif.mbssid_tx_vif = NULL; -+ dev_close(non_tx_sdata->wdev.netdev); -+ } -+ } -+ -+ if (sdata != tx_sdata && ieee80211_sdata_running(tx_sdata)) { -+ tx_sdata->vif.mbssid_tx_vif = NULL; -+ dev_close(tx_sdata->wdev.netdev); -+ } -+} -+ - static int ieee80211_stop(struct net_device *dev) - { - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - -- /* close all dependent VLAN interfaces before locking wiphy */ -+ /* close dependent VLAN and MBSSID interfaces before locking wiphy */ - if (sdata->vif.type == NL80211_IFTYPE_AP) { - struct ieee80211_sub_if_data *vlan, *tmpsdata; - - list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans, - u.vlan.list) - dev_close(vlan->dev); -+ -+ ieee80211_stop_mbssid(sdata); - } - - wiphy_lock(sdata->local->hw.wiphy); diff --git a/package/kernel/mac80211/patches/subsys/324-v5.18-mac80211-MBSSID-beacon-handling-in-AP-mode.patch b/package/kernel/mac80211/patches/subsys/324-v5.18-mac80211-MBSSID-beacon-handling-in-AP-mode.patch deleted file mode 100644 index a8fc02f92d..0000000000 --- a/package/kernel/mac80211/patches/subsys/324-v5.18-mac80211-MBSSID-beacon-handling-in-AP-mode.patch +++ /dev/null @@ -1,326 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Feb 2022 12:54:58 +0100 -Subject: [PATCH] mac80211: MBSSID beacon handling in AP mode - -Add new fields in struct beacon_data to store all MBSSID elements. -Generate a beacon template which includes all MBSSID elements. -Move CSA offset to reflect the MBSSID element length. - -Co-developed-by: Aloka Dixit -Signed-off-by: Aloka Dixit -Co-developed-by: John Crispin -Signed-off-by: John Crispin -Signed-off-by: Lorenzo Bianconi -Tested-by: Money Wang -Link: https://lore.kernel.org/r/5322db3c303f431adaf191ab31c45e151dde5465.1645702516.git.lorenzo@kernel.org -[small cleanups] -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -4938,12 +4938,14 @@ void ieee80211_report_low_ack(struct iee - * @cntdwn_counter_offs: array of IEEE80211_MAX_CNTDWN_COUNTERS_NUM offsets - * to countdown counters. This array can contain zero values which - * should be ignored. -+ * @mbssid_off: position of the multiple bssid element - */ - struct ieee80211_mutable_offsets { - u16 tim_offset; - u16 tim_length; - - u16 cntdwn_counter_offs[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; -+ u16 mbssid_off; - }; - - /** ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -989,11 +989,29 @@ static int ieee80211_set_ftm_responder_p - return 0; - } - -+static int -+ieee80211_copy_mbssid_beacon(u8 *pos, struct cfg80211_mbssid_elems *dst, -+ struct cfg80211_mbssid_elems *src) -+{ -+ int i, offset = 0; -+ -+ for (i = 0; i < src->cnt; i++) { -+ memcpy(pos + offset, src->elem[i].data, src->elem[i].len); -+ dst->elem[i].len = src->elem[i].len; -+ dst->elem[i].data = pos + offset; -+ offset += dst->elem[i].len; -+ } -+ dst->cnt = src->cnt; -+ -+ return offset; -+} -+ - static int ieee80211_assign_beacon(struct ieee80211_sub_if_data *sdata, - struct cfg80211_beacon_data *params, - const struct ieee80211_csa_settings *csa, - const struct ieee80211_color_change_settings *cca) - { -+ struct cfg80211_mbssid_elems *mbssid = NULL; - struct beacon_data *new, *old; - int new_head_len, new_tail_len; - int size, err; -@@ -1021,6 +1039,17 @@ static int ieee80211_assign_beacon(struc - - size = sizeof(*new) + new_head_len + new_tail_len; - -+ /* new or old multiple BSSID elements? */ -+ if (params->mbssid_ies) { -+ mbssid = params->mbssid_ies; -+ size += struct_size(new->mbssid_ies, elem, mbssid->cnt); -+ size += ieee80211_get_mbssid_beacon_len(mbssid); -+ } 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); -+ } -+ - new = kzalloc(size, GFP_KERNEL); - if (!new) - return -ENOMEM; -@@ -1029,12 +1058,20 @@ static int ieee80211_assign_beacon(struc - - /* - * pointers go into the block we allocated, -- * memory is | beacon_data | head | tail | -+ * memory is | beacon_data | head | tail | mbssid_ies - */ - new->head = ((u8 *) new) + sizeof(*new); - new->tail = new->head + new_head_len; - new->head_len = new_head_len; - new->tail_len = new_tail_len; -+ /* copy in optional mbssid_ies */ -+ if (mbssid) { -+ u8 *pos = new->tail + new->tail_len; -+ -+ new->mbssid_ies = (void *)pos; -+ pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); -+ ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); -+ } - - if (csa) { - new->cntdwn_current_counter = csa->count; -@@ -1332,8 +1369,11 @@ static int ieee80211_stop_ap(struct wiph - - mutex_unlock(&local->mtx); - -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; -+ if (sdata->u.ap.next_beacon) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ } - - /* turn off carrier for this interface and dependent VLANs */ - list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) -@@ -3126,12 +3166,24 @@ 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; -+ beacon->probe_resp_len + beacon->lci_len + beacon->civicloc_len + -+ ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); - - new_beacon = kzalloc(sizeof(*new_beacon) + len, GFP_KERNEL); - if (!new_beacon) - return NULL; - -+ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) { -+ new_beacon->mbssid_ies = -+ kzalloc(struct_size(new_beacon->mbssid_ies, -+ elem, beacon->mbssid_ies->cnt), -+ GFP_KERNEL); -+ if (!new_beacon->mbssid_ies) { -+ kfree(new_beacon); -+ return NULL; -+ } -+ } -+ - pos = (u8 *)(new_beacon + 1); - if (beacon->head_len) { - new_beacon->head_len = beacon->head_len; -@@ -3169,6 +3221,10 @@ cfg80211_beacon_dup(struct cfg80211_beac - memcpy(pos, beacon->probe_resp, beacon->probe_resp_len); - pos += beacon->probe_resp_len; - } -+ if (beacon->mbssid_ies && beacon->mbssid_ies->cnt) -+ pos += ieee80211_copy_mbssid_beacon(pos, -+ new_beacon->mbssid_ies, -+ beacon->mbssid_ies); - - /* might copy -1, meaning no changes requested */ - new_beacon->ftm_responder = beacon->ftm_responder; -@@ -3206,8 +3262,11 @@ static int ieee80211_set_after_csa_beaco - case NL80211_IFTYPE_AP: - err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, - NULL, NULL); -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; -+ if (sdata->u.ap.next_beacon) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ } - - if (err < 0) - return err; -@@ -3362,8 +3421,12 @@ static int ieee80211_set_csa_beacon(stru - if ((params->n_counter_offsets_beacon > - IEEE80211_MAX_CNTDWN_COUNTERS_NUM) || - (params->n_counter_offsets_presp > -- IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) -+ IEEE80211_MAX_CNTDWN_COUNTERS_NUM)) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; - return -EINVAL; -+ } - - csa.counter_offsets_beacon = params->counter_offsets_beacon; - csa.counter_offsets_presp = params->counter_offsets_presp; -@@ -3373,7 +3436,9 @@ static int ieee80211_set_csa_beacon(stru - - err = ieee80211_assign_beacon(sdata, ¶ms->beacon_csa, &csa, NULL); - if (err < 0) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); - kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; - return err; - } - *changed |= err; -@@ -3460,8 +3525,11 @@ static int ieee80211_set_csa_beacon(stru - static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata) - { - sdata->vif.color_change_active = false; -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; -+ if (sdata->u.ap.next_beacon) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ } - - cfg80211_color_change_aborted_notify(sdata->dev); - } -@@ -4199,8 +4267,11 @@ ieee80211_set_after_color_change_beacon( - - ret = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon, - NULL, NULL); -- kfree(sdata->u.ap.next_beacon); -- sdata->u.ap.next_beacon = NULL; -+ if (sdata->u.ap.next_beacon) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ } - - if (ret < 0) - return ret; -@@ -4243,7 +4314,11 @@ ieee80211_set_color_change_beacon(struct - err = ieee80211_assign_beacon(sdata, ¶ms->beacon_color_change, - NULL, &color_change); - if (err < 0) { -- kfree(sdata->u.ap.next_beacon); -+ if (sdata->u.ap.next_beacon) { -+ kfree(sdata->u.ap.next_beacon->mbssid_ies); -+ kfree(sdata->u.ap.next_beacon); -+ sdata->u.ap.next_beacon = NULL; -+ } - return err; - } - *changed |= err; ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -261,6 +261,7 @@ struct beacon_data { - struct ieee80211_meshconf_ie *meshconf; - u16 cntdwn_counter_offsets[IEEE80211_MAX_CNTDWN_COUNTERS_NUM]; - u8 cntdwn_current_counter; -+ struct cfg80211_mbssid_elems *mbssid_ies; - struct rcu_head rcu_head; - }; - -@@ -1082,6 +1083,20 @@ ieee80211_vif_get_shift(struct ieee80211 - return shift; - } - -+static inline int -+ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems) -+{ -+ int i, len = 0; -+ -+ if (!elems) -+ return 0; -+ -+ for (i = 0; i < elems->cnt; i++) -+ len += elems->elem[i].len; -+ -+ return len; -+} -+ - enum { - IEEE80211_RX_MSG = 1, - IEEE80211_TX_STATUS_MSG = 2, ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -5041,6 +5041,19 @@ ieee80211_beacon_get_finish(struct ieee8 - IEEE80211_TX_CTL_FIRST_FRAGMENT; - } - -+static void -+ieee80211_beacon_add_mbssid(struct sk_buff *skb, struct beacon_data *beacon) -+{ -+ int i; -+ -+ if (!beacon->mbssid_ies) -+ return; -+ -+ 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); -+} -+ - static struct sk_buff * - ieee80211_beacon_get_ap(struct ieee80211_hw *hw, - struct ieee80211_vif *vif, -@@ -5054,6 +5067,7 @@ ieee80211_beacon_get_ap(struct ieee80211 - struct ieee80211_if_ap *ap = &sdata->u.ap; - struct sk_buff *skb = NULL; - u16 csa_off_base = 0; -+ int mbssid_len; - - if (beacon->cntdwn_counter_offsets[0]) { - if (!is_template) -@@ -5063,11 +5077,12 @@ ieee80211_beacon_get_ap(struct ieee80211 - } - - /* headroom, head length, -- * tail length and maximum TIM length -+ * tail length, maximum TIM length and multiple BSSID length - */ -+ mbssid_len = ieee80211_get_mbssid_beacon_len(beacon->mbssid_ies); - skb = dev_alloc_skb(local->tx_headroom + beacon->head_len + - beacon->tail_len + 256 + -- local->hw.extra_beacon_tailroom); -+ local->hw.extra_beacon_tailroom + mbssid_len); - if (!skb) - return NULL; - -@@ -5081,6 +5096,11 @@ ieee80211_beacon_get_ap(struct ieee80211 - offs->tim_length = skb->len - beacon->head_len; - offs->cntdwn_counter_offs[0] = beacon->cntdwn_counter_offsets[0]; - -+ if (mbssid_len) { -+ ieee80211_beacon_add_mbssid(skb, beacon); -+ offs->mbssid_off = skb->len - mbssid_len; -+ } -+ - /* for AP the csa offsets are from tail */ - csa_off_base = skb->len; - } diff --git a/package/kernel/mac80211/patches/subsys/325-v5.18-mac80211-MBSSID-channel-switch.patch b/package/kernel/mac80211/patches/subsys/325-v5.18-mac80211-MBSSID-channel-switch.patch deleted file mode 100644 index 38b0de180e..0000000000 --- a/package/kernel/mac80211/patches/subsys/325-v5.18-mac80211-MBSSID-channel-switch.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: John Crispin -Date: Thu, 24 Feb 2022 12:54:59 +0100 -Subject: [PATCH] mac80211: MBSSID channel switch - -Trigger ieee80211_csa_finish() on the non-transmitting interfaces -when channel switch concludes on the transmitting interface. - -Co-developed-by: Lorenzo Bianconi -Signed-off-by: Lorenzo Bianconi -Co-developed-by: Aloka Dixit -Signed-off-by: Aloka Dixit -Signed-off-by: John Crispin -Link: https://lore.kernel.org/r/6fde4d7f9fa387494f46a7aa4a584478dcda06f1.1645702516.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -3247,9 +3247,31 @@ cfg80211_beacon_dup(struct cfg80211_beac - void ieee80211_csa_finish(struct ieee80211_vif *vif) - { - struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -+ struct ieee80211_local *local = sdata->local; - -- ieee80211_queue_work(&sdata->local->hw, -- &sdata->csa_finalize_work); -+ rcu_read_lock(); -+ -+ if (vif->mbssid_tx_vif == vif) { -+ /* Trigger ieee80211_csa_finish() on the non-transmitting -+ * interfaces when channel switch is received on -+ * transmitting interface -+ */ -+ struct ieee80211_sub_if_data *iter; -+ -+ list_for_each_entry_rcu(iter, &local->interfaces, list) { -+ if (!ieee80211_sdata_running(iter)) -+ continue; -+ -+ if (iter == sdata || iter->vif.mbssid_tx_vif != vif) -+ continue; -+ -+ ieee80211_queue_work(&iter->local->hw, -+ &iter->csa_finalize_work); -+ } -+ } -+ ieee80211_queue_work(&local->hw, &sdata->csa_finalize_work); -+ -+ rcu_read_unlock(); - } - EXPORT_SYMBOL(ieee80211_csa_finish); - diff --git a/package/kernel/mac80211/patches/subsys/326-v5.18-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch b/package/kernel/mac80211/patches/subsys/326-v5.18-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch deleted file mode 100644 index 1955568607..0000000000 --- a/package/kernel/mac80211/patches/subsys/326-v5.18-mac80211-update-bssid_indicator-in-ieee80211_assign_.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Lorenzo Bianconi -Date: Thu, 24 Feb 2022 12:55:00 +0100 -Subject: [PATCH] mac80211: update bssid_indicator in - ieee80211_assign_beacon - -Update bssid_indicator in ieee80211_bss_conf according to the -number of bssid in the set. - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/f92317e002fca9933f05a445fcefb4f53291d601.1645702516.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1071,6 +1071,9 @@ static int ieee80211_assign_beacon(struc - new->mbssid_ies = (void *)pos; - pos += struct_size(new->mbssid_ies, elem, mbssid->cnt); - ieee80211_copy_mbssid_beacon(pos, new->mbssid_ies, mbssid); -+ /* update bssid_indicator */ -+ sdata->vif.bss_conf.bssid_indicator = -+ ilog2(__roundup_pow_of_two(mbssid->cnt + 1)); - } - - if (csa) { diff --git a/package/kernel/mac80211/patches/subsys/328-v5.19-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch b/package/kernel/mac80211/patches/subsys/328-v5.19-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch deleted file mode 100644 index f0150ddef0..0000000000 --- a/package/kernel/mac80211/patches/subsys/328-v5.19-mac80211-do-not-wake-queues-on-a-vif-that-is-being-s.patch +++ /dev/null @@ -1,38 +0,0 @@ -From: Felix Fietkau -Date: Sat, 26 Mar 2022 23:58:35 +0100 -Subject: [PATCH] mac80211: do not wake queues on a vif that is being stopped - -When a vif is being removed and sdata->bss is cleared, __ieee80211_wake_txqs -can still be called on it, which crashes as soon as sdata->bss is being -dereferenced. -To fix this properly, check for SDATA_STATE_RUNNING before waking queues, -and take the fq lock when setting it (to ensure that __ieee80211_wake_txqs -observes the change when running on a different CPU - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -377,7 +377,9 @@ static void ieee80211_do_stop(struct iee - bool cancel_scan; - struct cfg80211_nan_func *func; - -+ spin_lock_bh(&local->fq.lock); - clear_bit(SDATA_STATE_RUNNING, &sdata->state); -+ spin_unlock_bh(&local->fq.lock); - - cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; - if (cancel_scan) ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -301,6 +301,9 @@ static void __ieee80211_wake_txqs(struct - local_bh_disable(); - spin_lock(&fq->lock); - -+ if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) -+ goto out; -+ - if (sdata->vif.type == NL80211_IFTYPE_AP) - ps = &sdata->bss->ps; - diff --git a/package/kernel/mac80211/patches/subsys/330-v6.0-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch b/package/kernel/mac80211/patches/subsys/330-v6.0-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch deleted file mode 100644 index e59036f5a2..0000000000 --- a/package/kernel/mac80211/patches/subsys/330-v6.0-mac80211-switch-airtime-fairness-back-to-deficit-rou.patch +++ /dev/null @@ -1,1249 +0,0 @@ -From: Felix Fietkau -Date: Sun, 19 Jun 2022 23:13:05 +0200 -Subject: [PATCH] mac80211: switch airtime fairness back to deficit round-robin - scheduling - -This reverts commits 6a789ba679d652587532cec2a0e0274fda172f3b and -2433647bc8d983a543e7d31b41ca2de1c7e2c198. - -The virtual time scheduler code has a number of issues: -- queues slowed down by hardware/firmware powersave handling were not properly - handled. -- on ath10k in push-pull mode, tx queues that the driver tries to pull from - were starved, causing excessive latency -- delay between tx enqueue and reported airtime use were causing excessively - bursty tx behavior - -The bursty behavior may also be present on the round-robin scheduler, but there -it is much easier to fix without introducing additional regressions - -Signed-off-by: Felix Fietkau ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -6666,6 +6666,9 @@ static inline void ieee80211_txq_schedul - { - } - -+void __ieee80211_schedule_txq(struct ieee80211_hw *hw, -+ struct ieee80211_txq *txq, bool force); -+ - /** - * ieee80211_schedule_txq - schedule a TXQ for transmission - * -@@ -6678,7 +6681,11 @@ static inline void ieee80211_txq_schedul - * The driver may call this function if it has buffered packets for - * this TXQ internally. - */ --void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); -+static inline void -+ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) -+{ -+ __ieee80211_schedule_txq(hw, txq, true); -+} - - /** - * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() -@@ -6690,8 +6697,12 @@ void ieee80211_schedule_txq(struct ieee8 - * The driver may set force=true if it has buffered packets for this TXQ - * internally. - */ --void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, -- bool force); -+static inline void -+ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, -+ bool force) -+{ -+ __ieee80211_schedule_txq(hw, txq, force); -+} - - /** - * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit ---- a/net/mac80211/cfg.c -+++ b/net/mac80211/cfg.c -@@ -1554,38 +1554,6 @@ static void sta_apply_mesh_params(struct - #endif - } - --static void sta_apply_airtime_params(struct ieee80211_local *local, -- struct sta_info *sta, -- struct station_parameters *params) --{ -- u8 ac; -- -- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- struct airtime_sched_info *air_sched = &local->airtime[ac]; -- struct airtime_info *air_info = &sta->airtime[ac]; -- struct txq_info *txqi; -- u8 tid; -- -- spin_lock_bh(&air_sched->lock); -- for (tid = 0; tid < IEEE80211_NUM_TIDS + 1; tid++) { -- if (air_info->weight == params->airtime_weight || -- !sta->sta.txq[tid] || -- ac != ieee80211_ac_from_tid(tid)) -- continue; -- -- airtime_weight_set(air_info, params->airtime_weight); -- -- txqi = to_txq_info(sta->sta.txq[tid]); -- if (RB_EMPTY_NODE(&txqi->schedule_order)) -- continue; -- -- ieee80211_update_airtime_weight(local, air_sched, -- 0, true); -- } -- spin_unlock_bh(&air_sched->lock); -- } --} -- - static int sta_apply_parameters(struct ieee80211_local *local, - struct sta_info *sta, - struct station_parameters *params) -@@ -1773,8 +1741,7 @@ static int sta_apply_parameters(struct i - sta_apply_mesh_params(local, sta, params); - - if (params->airtime_weight) -- sta_apply_airtime_params(local, sta, params); -- -+ sta->airtime_weight = params->airtime_weight; - - /* set the STA state after all sta info from usermode has been set */ - if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -216,14 +216,14 @@ static ssize_t aql_txq_limit_read(struct - "VI %u %u\n" - "BE %u %u\n" - "BK %u %u\n", -- local->airtime[IEEE80211_AC_VO].aql_txq_limit_low, -- local->airtime[IEEE80211_AC_VO].aql_txq_limit_high, -- local->airtime[IEEE80211_AC_VI].aql_txq_limit_low, -- local->airtime[IEEE80211_AC_VI].aql_txq_limit_high, -- local->airtime[IEEE80211_AC_BE].aql_txq_limit_low, -- local->airtime[IEEE80211_AC_BE].aql_txq_limit_high, -- local->airtime[IEEE80211_AC_BK].aql_txq_limit_low, -- local->airtime[IEEE80211_AC_BK].aql_txq_limit_high); -+ local->aql_txq_limit_low[IEEE80211_AC_VO], -+ local->aql_txq_limit_high[IEEE80211_AC_VO], -+ local->aql_txq_limit_low[IEEE80211_AC_VI], -+ local->aql_txq_limit_high[IEEE80211_AC_VI], -+ local->aql_txq_limit_low[IEEE80211_AC_BE], -+ local->aql_txq_limit_high[IEEE80211_AC_BE], -+ local->aql_txq_limit_low[IEEE80211_AC_BK], -+ local->aql_txq_limit_high[IEEE80211_AC_BK]); - return simple_read_from_buffer(user_buf, count, ppos, - buf, len); - } -@@ -255,11 +255,11 @@ static ssize_t aql_txq_limit_write(struc - if (ac >= IEEE80211_NUM_ACS) - return -EINVAL; - -- q_limit_low_old = local->airtime[ac].aql_txq_limit_low; -- q_limit_high_old = local->airtime[ac].aql_txq_limit_high; -+ q_limit_low_old = local->aql_txq_limit_low[ac]; -+ q_limit_high_old = local->aql_txq_limit_high[ac]; - -- local->airtime[ac].aql_txq_limit_low = q_limit_low; -- local->airtime[ac].aql_txq_limit_high = q_limit_high; -+ local->aql_txq_limit_low[ac] = q_limit_low; -+ local->aql_txq_limit_high[ac] = q_limit_high; - - mutex_lock(&local->sta_mtx); - list_for_each_entry(sta, &local->sta_list, list) { -@@ -382,46 +382,6 @@ static const struct file_operations forc - .llseek = default_llseek, - }; - --static ssize_t airtime_read(struct file *file, -- char __user *user_buf, -- size_t count, -- loff_t *ppos) --{ -- struct ieee80211_local *local = file->private_data; -- char buf[200]; -- u64 v_t[IEEE80211_NUM_ACS]; -- u64 wt[IEEE80211_NUM_ACS]; -- int len = 0, ac; -- -- for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- spin_lock_bh(&local->airtime[ac].lock); -- v_t[ac] = local->airtime[ac].v_t; -- wt[ac] = local->airtime[ac].weight_sum; -- spin_unlock_bh(&local->airtime[ac].lock); -- } -- len = scnprintf(buf, sizeof(buf), -- "\tVO VI BE BK\n" -- "Virt-t\t%-10llu %-10llu %-10llu %-10llu\n" -- "Weight\t%-10llu %-10llu %-10llu %-10llu\n", -- v_t[0], -- v_t[1], -- v_t[2], -- v_t[3], -- wt[0], -- wt[1], -- wt[2], -- wt[3]); -- -- return simple_read_from_buffer(user_buf, count, ppos, -- buf, len); --} -- --static const struct file_operations airtime_ops = { -- .read = airtime_read, -- .open = simple_open, -- .llseek = default_llseek, --}; -- - #ifdef CONFIG_PM - static ssize_t reset_write(struct file *file, const char __user *user_buf, - size_t count, loff_t *ppos) -@@ -672,11 +632,7 @@ void debugfs_hw_add(struct ieee80211_loc - if (local->ops->wake_tx_queue) - DEBUGFS_ADD_MODE(aqm, 0600); - -- if (wiphy_ext_feature_isset(local->hw.wiphy, -- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { -- DEBUGFS_ADD_MODE(airtime, 0600); -- DEBUGFS_ADD_MODE(airtime_flags, 0600); -- } -+ DEBUGFS_ADD_MODE(airtime_flags, 0600); - - DEBUGFS_ADD(aql_txq_limit); - debugfs_create_u32("aql_threshold", 0600, ---- a/net/mac80211/debugfs_netdev.c -+++ b/net/mac80211/debugfs_netdev.c -@@ -512,34 +512,6 @@ static ssize_t ieee80211_if_fmt_aqm( - } - IEEE80211_IF_FILE_R(aqm); - --static ssize_t ieee80211_if_fmt_airtime( -- const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) --{ -- struct ieee80211_local *local = sdata->local; -- struct ieee80211_txq *txq = sdata->vif.txq; -- struct airtime_info *air_info; -- int len; -- -- if (!txq) -- return 0; -- -- spin_lock_bh(&local->airtime[txq->ac].lock); -- air_info = to_airtime_info(txq); -- len = scnprintf(buf, -- buflen, -- "RX: %llu us\nTX: %llu us\nWeight: %u\n" -- "Virt-T: %lld us\n", -- air_info->rx_airtime, -- air_info->tx_airtime, -- air_info->weight, -- air_info->v_t); -- spin_unlock_bh(&local->airtime[txq->ac].lock); -- -- return len; --} -- --IEEE80211_IF_FILE_R(airtime); -- - IEEE80211_IF_FILE(multicast_to_unicast, u.ap.multicast_to_unicast, HEX); - - /* IBSS attributes */ -@@ -685,10 +657,8 @@ static void add_common_files(struct ieee - - if (sdata->local->ops->wake_tx_queue && - sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && -- sdata->vif.type != NL80211_IFTYPE_NAN) { -+ sdata->vif.type != NL80211_IFTYPE_NAN) - DEBUGFS_ADD(aqm); -- DEBUGFS_ADD(airtime); -- } - } - - static void add_sta_files(struct ieee80211_sub_if_data *sdata) ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f - size_t bufsz = 400; - char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; - u64 rx_airtime = 0, tx_airtime = 0; -- u64 v_t[IEEE80211_NUM_ACS]; -+ s64 deficit[IEEE80211_NUM_ACS]; - ssize_t rv; - int ac; - -@@ -210,18 +210,18 @@ static ssize_t sta_airtime_read(struct f - return -ENOMEM; - - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- spin_lock_bh(&local->airtime[ac].lock); -+ spin_lock_bh(&local->active_txq_lock[ac]); - rx_airtime += sta->airtime[ac].rx_airtime; - tx_airtime += sta->airtime[ac].tx_airtime; -- v_t[ac] = sta->airtime[ac].v_t; -- spin_unlock_bh(&local->airtime[ac].lock); -+ deficit[ac] = sta->airtime[ac].deficit; -+ spin_unlock_bh(&local->active_txq_lock[ac]); - } - - p += scnprintf(p, bufsz + buf - p, - "RX: %llu us\nTX: %llu us\nWeight: %u\n" -- "Virt-T: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -- rx_airtime, tx_airtime, sta->airtime[0].weight, -- v_t[0], v_t[1], v_t[2], v_t[3]); -+ "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -+ rx_airtime, tx_airtime, sta->airtime_weight, -+ deficit[0], deficit[1], deficit[2], deficit[3]); - - rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); - kfree(buf); -@@ -236,11 +236,11 @@ static ssize_t sta_airtime_write(struct - int ac; - - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- spin_lock_bh(&local->airtime[ac].lock); -+ spin_lock_bh(&local->active_txq_lock[ac]); - sta->airtime[ac].rx_airtime = 0; - sta->airtime[ac].tx_airtime = 0; -- sta->airtime[ac].v_t = 0; -- spin_unlock_bh(&local->airtime[ac].lock); -+ sta->airtime[ac].deficit = sta->airtime_weight; -+ spin_unlock_bh(&local->active_txq_lock[ac]); - } - - return count; -@@ -263,10 +263,10 @@ static ssize_t sta_aql_read(struct file - return -ENOMEM; - - for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { -- spin_lock_bh(&local->airtime[ac].lock); -+ spin_lock_bh(&local->active_txq_lock[ac]); - q_limit_l[ac] = sta->airtime[ac].aql_limit_low; - q_limit_h[ac] = sta->airtime[ac].aql_limit_high; -- spin_unlock_bh(&local->airtime[ac].lock); -+ spin_unlock_bh(&local->active_txq_lock[ac]); - q_depth[ac] = atomic_read(&sta->airtime[ac].aql_tx_pending); - } - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -862,16 +862,20 @@ enum txq_info_flags { - * @def_flow: used as a fallback flow when a packet destined to @tin hashes to - * a fq_flow which is already owned by a different tin - * @def_cvars: codel vars for @def_flow -- * @schedule_order: used with ieee80211_local->active_txqs - * @frags: used to keep fragments created after dequeue -+ * @schedule_order: used with ieee80211_local->active_txqs -+ * @schedule_round: counter to prevent infinite loops on TXQ scheduling - */ - struct txq_info { - struct fq_tin tin; - struct codel_vars def_cvars; - struct codel_stats cstats; -- struct rb_node schedule_order; -+ -+ u16 schedule_round; -+ struct list_head schedule_order; - - struct sk_buff_head frags; -+ - unsigned long flags; - - /* keep last! */ -@@ -948,8 +952,6 @@ struct ieee80211_sub_if_data { - struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS]; - struct mac80211_qos_map __rcu *qos_map; - -- struct airtime_info airtime[IEEE80211_NUM_ACS]; -- - struct work_struct csa_finalize_work; - bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */ - struct cfg80211_chan_def csa_chandef; -@@ -1184,44 +1186,6 @@ enum mac80211_scan_state { - SCAN_ABORT, - }; - --/** -- * struct airtime_sched_info - state used for airtime scheduling and AQL -- * -- * @lock: spinlock that protects all the fields in this struct -- * @active_txqs: rbtree of currently backlogged queues, sorted by virtual time -- * @schedule_pos: the current position maintained while a driver walks the tree -- * with ieee80211_next_txq() -- * @active_list: list of struct airtime_info structs that were active within -- * the last AIRTIME_ACTIVE_DURATION (100 ms), used to compute -- * weight_sum -- * @last_weight_update: used for rate limiting walking active_list -- * @last_schedule_time: tracks the last time a transmission was scheduled; used -- * for catching up v_t if no stations are eligible for -- * transmission. -- * @v_t: global virtual time; queues with v_t < this are eligible for -- * transmission -- * @weight_sum: total sum of all active stations used for dividing airtime -- * @weight_sum_reciprocal: reciprocal of weight_sum (to avoid divisions in fast -- * path - see comment above -- * IEEE80211_RECIPROCAL_DIVISOR_64) -- * @aql_txq_limit_low: AQL limit when total outstanding airtime -- * is < IEEE80211_AQL_THRESHOLD -- * @aql_txq_limit_high: AQL limit when total outstanding airtime -- * is > IEEE80211_AQL_THRESHOLD -- */ --struct airtime_sched_info { -- spinlock_t lock; -- struct rb_root_cached active_txqs; -- struct rb_node *schedule_pos; -- struct list_head active_list; -- u64 last_weight_update; -- u64 last_schedule_activity; -- u64 v_t; -- u64 weight_sum; -- u64 weight_sum_reciprocal; -- u32 aql_txq_limit_low; -- u32 aql_txq_limit_high; --}; - DECLARE_STATIC_KEY_FALSE(aql_disable); - - struct ieee80211_local { -@@ -1235,8 +1199,13 @@ struct ieee80211_local { - struct codel_params cparams; - - /* protects active_txqs and txqi->schedule_order */ -- struct airtime_sched_info airtime[IEEE80211_NUM_ACS]; -+ spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; -+ struct list_head active_txqs[IEEE80211_NUM_ACS]; -+ u16 schedule_round[IEEE80211_NUM_ACS]; -+ - u16 airtime_flags; -+ u32 aql_txq_limit_low[IEEE80211_NUM_ACS]; -+ u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; - u32 aql_threshold; - atomic_t aql_total_pending_airtime; - -@@ -1660,125 +1629,6 @@ static inline bool txq_has_queue(struct - return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets); - } - --static inline struct airtime_info *to_airtime_info(struct ieee80211_txq *txq) --{ -- struct ieee80211_sub_if_data *sdata; -- struct sta_info *sta; -- -- if (txq->sta) { -- sta = container_of(txq->sta, struct sta_info, sta); -- return &sta->airtime[txq->ac]; -- } -- -- sdata = vif_to_sdata(txq->vif); -- return &sdata->airtime[txq->ac]; --} -- --/* To avoid divisions in the fast path, we keep pre-computed reciprocals for -- * airtime weight calculations. There are two different weights to keep track -- * of: The per-station weight and the sum of weights per phy. -- * -- * For the per-station weights (kept in airtime_info below), we use 32-bit -- * reciprocals with a devisor of 2^19. This lets us keep the multiplications and -- * divisions for the station weights as 32-bit operations at the cost of a bit -- * of rounding error for high weights; but the choice of divisor keeps rounding -- * errors <10% for weights <2^15, assuming no more than 8ms of airtime is -- * reported at a time. -- * -- * For the per-phy sum of weights the values can get higher, so we use 64-bit -- * operations for those with a 32-bit divisor, which should avoid any -- * significant rounding errors. -- */ --#define IEEE80211_RECIPROCAL_DIVISOR_64 0x100000000ULL --#define IEEE80211_RECIPROCAL_SHIFT_64 32 --#define IEEE80211_RECIPROCAL_DIVISOR_32 0x80000U --#define IEEE80211_RECIPROCAL_SHIFT_32 19 -- --static inline void airtime_weight_set(struct airtime_info *air_info, u16 weight) --{ -- if (air_info->weight == weight) -- return; -- -- air_info->weight = weight; -- if (weight) { -- air_info->weight_reciprocal = -- IEEE80211_RECIPROCAL_DIVISOR_32 / weight; -- } else { -- air_info->weight_reciprocal = 0; -- } --} -- --static inline void airtime_weight_sum_set(struct airtime_sched_info *air_sched, -- int weight_sum) --{ -- if (air_sched->weight_sum == weight_sum) -- return; -- -- air_sched->weight_sum = weight_sum; -- if (air_sched->weight_sum) { -- air_sched->weight_sum_reciprocal = IEEE80211_RECIPROCAL_DIVISOR_64; -- do_div(air_sched->weight_sum_reciprocal, air_sched->weight_sum); -- } else { -- air_sched->weight_sum_reciprocal = 0; -- } --} -- --/* A problem when trying to enforce airtime fairness is that we want to divide -- * the airtime between the currently *active* stations. However, basing this on -- * the instantaneous queue state of stations doesn't work, as queues tend to -- * oscillate very quickly between empty and occupied, leading to the scheduler -- * thinking only a single station is active when deciding whether to allow -- * transmission (and thus not throttling correctly). -- * -- * To fix this we use a timer-based notion of activity: a station is considered -- * active if it has been scheduled within the last 100 ms; we keep a separate -- * list of all the stations considered active in this manner, and lazily update -- * the total weight of active stations from this list (filtering the stations in -- * the list by their 'last active' time). -- * -- * We add one additional safeguard to guard against stations that manage to get -- * scheduled every 100 ms but don't transmit a lot of data, and thus don't use -- * up any airtime. Such stations would be able to get priority for an extended -- * period of time if they do start transmitting at full capacity again, and so -- * we add an explicit maximum for how far behind a station is allowed to fall in -- * the virtual airtime domain. This limit is set to a relatively high value of -- * 20 ms because the main mechanism for catching up idle stations is the active -- * state as described above; i.e., the hard limit should only be hit in -- * pathological cases. -- */ --#define AIRTIME_ACTIVE_DURATION (100 * NSEC_PER_MSEC) --#define AIRTIME_MAX_BEHIND 20000 /* 20 ms */ -- --static inline bool airtime_is_active(struct airtime_info *air_info, u64 now) --{ -- return air_info->last_scheduled >= now - AIRTIME_ACTIVE_DURATION; --} -- --static inline void airtime_set_active(struct airtime_sched_info *air_sched, -- struct airtime_info *air_info, u64 now) --{ -- air_info->last_scheduled = now; -- air_sched->last_schedule_activity = now; -- list_move_tail(&air_info->list, &air_sched->active_list); --} -- --static inline bool airtime_catchup_v_t(struct airtime_sched_info *air_sched, -- u64 v_t, u64 now) --{ -- air_sched->v_t = v_t; -- return true; --} -- --static inline void init_airtime_info(struct airtime_info *air_info, -- struct airtime_sched_info *air_sched) --{ -- atomic_set(&air_info->aql_tx_pending, 0); -- air_info->aql_limit_low = air_sched->aql_txq_limit_low; -- air_info->aql_limit_high = air_sched->aql_txq_limit_high; -- airtime_weight_set(air_info, IEEE80211_DEFAULT_AIRTIME_WEIGHT); -- INIT_LIST_HEAD(&air_info->list); --} -- - static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) - { - return ether_addr_equal(raddr, addr) || -@@ -2024,14 +1874,6 @@ int ieee80211_tx_control_port(struct wip - u64 *cookie); - int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, - const u8 *buf, size_t len); --void ieee80211_resort_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq); --void ieee80211_unschedule_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq, -- bool purge); --void ieee80211_update_airtime_weight(struct ieee80211_local *local, -- struct airtime_sched_info *air_sched, -- u64 now, bool force); - - /* HT */ - void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -2192,9 +2192,6 @@ int ieee80211_if_add(struct ieee80211_lo - } - } - -- for (i = 0; i < IEEE80211_NUM_ACS; i++) -- init_airtime_info(&sdata->airtime[i], &local->airtime[i]); -- - ieee80211_set_default_queues(sdata); - - sdata->ap_power_level = IEEE80211_UNSET_POWER_LEVEL; ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -707,13 +707,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - spin_lock_init(&local->queue_stop_reason_lock); - - for (i = 0; i < IEEE80211_NUM_ACS; i++) { -- struct airtime_sched_info *air_sched = &local->airtime[i]; -- -- air_sched->active_txqs = RB_ROOT_CACHED; -- INIT_LIST_HEAD(&air_sched->active_list); -- spin_lock_init(&air_sched->lock); -- air_sched->aql_txq_limit_low = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; -- air_sched->aql_txq_limit_high = -+ INIT_LIST_HEAD(&local->active_txqs[i]); -+ spin_lock_init(&local->active_txq_lock[i]); -+ local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; -+ local->aql_txq_limit_high[i] = - IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; - } - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -1583,8 +1583,12 @@ static void sta_ps_start(struct sta_info - - for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { - struct ieee80211_txq *txq = sta->sta.txq[tid]; -+ struct txq_info *txqi = to_txq_info(txq); - -- ieee80211_unschedule_txq(&local->hw, txq, false); -+ spin_lock(&local->active_txq_lock[txq->ac]); -+ if (!list_empty(&txqi->schedule_order)) -+ list_del_init(&txqi->schedule_order); -+ spin_unlock(&local->active_txq_lock[txq->ac]); - - if (txq_has_queue(txq)) - set_bit(tid, &sta->txq_buffered_tids); ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -426,11 +426,15 @@ struct sta_info *sta_info_alloc(struct i - if (sta_prepare_rate_control(local, sta, gfp)) - goto free_txq; - -+ sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; - - for (i = 0; i < IEEE80211_NUM_ACS; i++) { - skb_queue_head_init(&sta->ps_tx_buf[i]); - skb_queue_head_init(&sta->tx_filtered[i]); -- init_airtime_info(&sta->airtime[i], &local->airtime[i]); -+ sta->airtime[i].deficit = sta->airtime_weight; -+ atomic_set(&sta->airtime[i].aql_tx_pending, 0); -+ sta->airtime[i].aql_limit_low = local->aql_txq_limit_low[i]; -+ sta->airtime[i].aql_limit_high = local->aql_txq_limit_high[i]; - } - - for (i = 0; i < IEEE80211_NUM_TIDS; i++) -@@ -1889,59 +1893,24 @@ void ieee80211_sta_set_buffered(struct i - } - EXPORT_SYMBOL(ieee80211_sta_set_buffered); - --void ieee80211_register_airtime(struct ieee80211_txq *txq, -- u32 tx_airtime, u32 rx_airtime) -+void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, -+ u32 tx_airtime, u32 rx_airtime) - { -- struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif); -- struct ieee80211_local *local = sdata->local; -- u64 weight_sum, weight_sum_reciprocal; -- struct airtime_sched_info *air_sched; -- struct airtime_info *air_info; -+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); -+ struct ieee80211_local *local = sta->sdata->local; -+ u8 ac = ieee80211_ac_from_tid(tid); - u32 airtime = 0; - -- air_sched = &local->airtime[txq->ac]; -- air_info = to_airtime_info(txq); -- -- if (local->airtime_flags & AIRTIME_USE_TX) -+ if (sta->local->airtime_flags & AIRTIME_USE_TX) - airtime += tx_airtime; -- if (local->airtime_flags & AIRTIME_USE_RX) -+ if (sta->local->airtime_flags & AIRTIME_USE_RX) - airtime += rx_airtime; - -- /* Weights scale so the unit weight is 256 */ -- airtime <<= 8; -- -- spin_lock_bh(&air_sched->lock); -- -- air_info->tx_airtime += tx_airtime; -- air_info->rx_airtime += rx_airtime; -- -- if (air_sched->weight_sum) { -- weight_sum = air_sched->weight_sum; -- weight_sum_reciprocal = air_sched->weight_sum_reciprocal; -- } else { -- weight_sum = air_info->weight; -- weight_sum_reciprocal = air_info->weight_reciprocal; -- } -- -- /* Round the calculation of global vt */ -- air_sched->v_t += (u64)((airtime + (weight_sum >> 1)) * -- weight_sum_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_64; -- air_info->v_t += (u32)((airtime + (air_info->weight >> 1)) * -- air_info->weight_reciprocal) >> IEEE80211_RECIPROCAL_SHIFT_32; -- ieee80211_resort_txq(&local->hw, txq); -- -- spin_unlock_bh(&air_sched->lock); --} -- --void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, -- u32 tx_airtime, u32 rx_airtime) --{ -- struct ieee80211_txq *txq = pubsta->txq[tid]; -- -- if (!txq) -- return; -- -- ieee80211_register_airtime(txq, tx_airtime, rx_airtime); -+ spin_lock_bh(&local->active_txq_lock[ac]); -+ sta->airtime[ac].tx_airtime += tx_airtime; -+ sta->airtime[ac].rx_airtime += rx_airtime; -+ sta->airtime[ac].deficit -= airtime; -+ spin_unlock_bh(&local->active_txq_lock[ac]); - } - EXPORT_SYMBOL(ieee80211_sta_register_airtime); - -@@ -2385,7 +2354,7 @@ void sta_set_sinfo(struct sta_info *sta, - } - - if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { -- sinfo->airtime_weight = sta->airtime[0].weight; -+ sinfo->airtime_weight = sta->airtime_weight; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); - } - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -135,25 +135,18 @@ enum ieee80211_agg_stop_reason { - #define AIRTIME_USE_TX BIT(0) - #define AIRTIME_USE_RX BIT(1) - -- - struct airtime_info { - u64 rx_airtime; - u64 tx_airtime; -- u64 v_t; -- u64 last_scheduled; -- struct list_head list; -+ s64 deficit; - atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ - u32 aql_limit_low; - u32 aql_limit_high; -- u32 weight_reciprocal; -- u16 weight; - }; - - void ieee80211_sta_update_pending_airtime(struct ieee80211_local *local, - struct sta_info *sta, u8 ac, - u16 tx_airtime, bool tx_completed); --void ieee80211_register_airtime(struct ieee80211_txq *txq, -- u32 tx_airtime, u32 rx_airtime); - - struct sta_info; - -@@ -523,6 +516,7 @@ struct ieee80211_fragment_cache { - * @tid_seq: per-TID sequence numbers for sending to this STA - * @airtime: per-AC struct airtime_info describing airtime statistics for this - * station -+ * @airtime_weight: station weight for airtime fairness calculation purposes - * @ampdu_mlme: A-MPDU state machine state - * @mesh: mesh STA information - * @debugfs_dir: debug filesystem directory dentry -@@ -653,6 +647,7 @@ struct sta_info { - u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; - - struct airtime_info airtime[IEEE80211_NUM_ACS]; -+ u16 airtime_weight; - - /* - * Aggregation information, locked with lock. ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -983,25 +983,6 @@ static void __ieee80211_tx_status(struct - if (!(info->flags & IEEE80211_TX_CTL_INJECTED) && acked) - ieee80211_frame_acked(sta, skb); - -- } else if (wiphy_ext_feature_isset(local->hw.wiphy, -- NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) { -- struct ieee80211_sub_if_data *sdata; -- struct ieee80211_txq *txq; -- u32 airtime; -- -- /* Account airtime to multicast queue */ -- sdata = ieee80211_sdata_from_skb(local, skb); -- -- if (sdata && (txq = sdata->vif.txq)) { -- airtime = info->status.tx_time ?: -- ieee80211_calc_expected_tx_airtime(hw, -- &sdata->vif, -- NULL, -- skb->len, -- false); -- -- ieee80211_register_airtime(txq, airtime, 0); -- } - } - - /* SNMP counters ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -18,7 +18,6 @@ - #include - #include - #include --#include - #include - #include - #include -@@ -1480,7 +1479,7 @@ void ieee80211_txq_init(struct ieee80211 - codel_vars_init(&txqi->def_cvars); - codel_stats_init(&txqi->cstats); - __skb_queue_head_init(&txqi->frags); -- RB_CLEAR_NODE(&txqi->schedule_order); -+ INIT_LIST_HEAD(&txqi->schedule_order); - - txqi->txq.vif = &sdata->vif; - -@@ -1524,7 +1523,9 @@ void ieee80211_txq_purge(struct ieee8021 - ieee80211_purge_tx_queue(&local->hw, &txqi->frags); - spin_unlock_bh(&fq->lock); - -- ieee80211_unschedule_txq(&local->hw, &txqi->txq, true); -+ spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); -+ list_del_init(&txqi->schedule_order); -+ spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); - } - - void ieee80211_txq_set_params(struct ieee80211_local *local) -@@ -3819,259 +3820,102 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); - struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) - { - struct ieee80211_local *local = hw_to_local(hw); -- struct airtime_sched_info *air_sched; -- u64 now = ktime_get_coarse_boottime_ns(); - struct ieee80211_txq *ret = NULL; -- struct airtime_info *air_info; -- struct txq_info *txqi = NULL; -- struct rb_node *node; -- bool first = false; -+ struct txq_info *txqi = NULL, *head = NULL; -+ bool found_eligible_txq = false; - -- air_sched = &local->airtime[ac]; -- spin_lock_bh(&air_sched->lock); -+ spin_lock_bh(&local->active_txq_lock[ac]); - -- node = air_sched->schedule_pos; -- --begin: -- if (!node) { -- node = rb_first_cached(&air_sched->active_txqs); -- first = true; -- } else { -- node = rb_next(node); -- } -- -- if (!node) -- goto out; -- -- txqi = container_of(node, struct txq_info, schedule_order); -- air_info = to_airtime_info(&txqi->txq); -- -- if (air_info->v_t > air_sched->v_t && -- (!first || !airtime_catchup_v_t(air_sched, air_info->v_t, now))) -+ begin: -+ txqi = list_first_entry_or_null(&local->active_txqs[ac], -+ struct txq_info, -+ schedule_order); -+ if (!txqi) - goto out; - -- if (!ieee80211_txq_airtime_check(hw, &txqi->txq)) { -- first = false; -- goto begin; -- } -- -- air_sched->schedule_pos = node; -- air_sched->last_schedule_activity = now; -- ret = &txqi->txq; --out: -- spin_unlock_bh(&air_sched->lock); -- return ret; --} --EXPORT_SYMBOL(ieee80211_next_txq); -- --static void __ieee80211_insert_txq(struct rb_root_cached *root, -- struct txq_info *txqi) --{ -- struct rb_node **new = &root->rb_root.rb_node; -- struct airtime_info *old_air, *new_air; -- struct rb_node *parent = NULL; -- struct txq_info *__txqi; -- bool leftmost = true; -- -- while (*new) { -- parent = *new; -- __txqi = rb_entry(parent, struct txq_info, schedule_order); -- old_air = to_airtime_info(&__txqi->txq); -- new_air = to_airtime_info(&txqi->txq); -- -- if (new_air->v_t <= old_air->v_t) { -- new = &parent->rb_left; -- } else { -- new = &parent->rb_right; -- leftmost = false; -- } -+ if (txqi == head) { -+ if (!found_eligible_txq) -+ goto out; -+ else -+ found_eligible_txq = false; - } - -- rb_link_node(&txqi->schedule_order, parent, new); -- rb_insert_color_cached(&txqi->schedule_order, root, leftmost); --} -- --void ieee80211_resort_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq) --{ -- struct airtime_info *air_info = to_airtime_info(txq); -- struct ieee80211_local *local = hw_to_local(hw); -- struct txq_info *txqi = to_txq_info(txq); -- struct airtime_sched_info *air_sched; -- -- air_sched = &local->airtime[txq->ac]; -+ if (!head) -+ head = txqi; - -- lockdep_assert_held(&air_sched->lock); -- -- if (!RB_EMPTY_NODE(&txqi->schedule_order)) { -- struct airtime_info *a_prev = NULL, *a_next = NULL; -- struct txq_info *t_prev, *t_next; -- struct rb_node *n_prev, *n_next; -+ if (txqi->txq.sta) { -+ struct sta_info *sta = container_of(txqi->txq.sta, -+ struct sta_info, sta); -+ bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); -+ s64 deficit = sta->airtime[txqi->txq.ac].deficit; - -- /* Erasing a node can cause an expensive rebalancing operation, -- * so we check the previous and next nodes first and only remove -- * and re-insert if the current node is not already in the -- * correct position. -- */ -- if ((n_prev = rb_prev(&txqi->schedule_order)) != NULL) { -- t_prev = container_of(n_prev, struct txq_info, -- schedule_order); -- a_prev = to_airtime_info(&t_prev->txq); -- } -+ if (aql_check) -+ found_eligible_txq = true; - -- if ((n_next = rb_next(&txqi->schedule_order)) != NULL) { -- t_next = container_of(n_next, struct txq_info, -- schedule_order); -- a_next = to_airtime_info(&t_next->txq); -+ if (deficit < 0) -+ sta->airtime[txqi->txq.ac].deficit += -+ sta->airtime_weight; -+ -+ if (deficit < 0 || !aql_check) { -+ list_move_tail(&txqi->schedule_order, -+ &local->active_txqs[txqi->txq.ac]); -+ goto begin; - } -- -- if ((!a_prev || a_prev->v_t <= air_info->v_t) && -- (!a_next || a_next->v_t > air_info->v_t)) -- return; -- -- if (air_sched->schedule_pos == &txqi->schedule_order) -- air_sched->schedule_pos = n_prev; -- -- rb_erase_cached(&txqi->schedule_order, -- &air_sched->active_txqs); -- RB_CLEAR_NODE(&txqi->schedule_order); -- __ieee80211_insert_txq(&air_sched->active_txqs, txqi); - } --} -- --void ieee80211_update_airtime_weight(struct ieee80211_local *local, -- struct airtime_sched_info *air_sched, -- u64 now, bool force) --{ -- struct airtime_info *air_info, *tmp; -- u64 weight_sum = 0; -- -- if (unlikely(!now)) -- now = ktime_get_coarse_boottime_ns(); -- -- lockdep_assert_held(&air_sched->lock); -- -- if (!force && (air_sched->last_weight_update < -- now - AIRTIME_ACTIVE_DURATION)) -- return; -- -- list_for_each_entry_safe(air_info, tmp, -- &air_sched->active_list, list) { -- if (airtime_is_active(air_info, now)) -- weight_sum += air_info->weight; -- else -- list_del_init(&air_info->list); -- } -- airtime_weight_sum_set(air_sched, weight_sum); -- air_sched->last_weight_update = now; --} - --void ieee80211_schedule_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq) -- __acquires(txq_lock) __releases(txq_lock) --{ -- struct ieee80211_local *local = hw_to_local(hw); -- struct txq_info *txqi = to_txq_info(txq); -- struct airtime_sched_info *air_sched; -- u64 now = ktime_get_coarse_boottime_ns(); -- struct airtime_info *air_info; -- u8 ac = txq->ac; -- bool was_active; - -- air_sched = &local->airtime[ac]; -- air_info = to_airtime_info(txq); -- -- spin_lock_bh(&air_sched->lock); -- was_active = airtime_is_active(air_info, now); -- airtime_set_active(air_sched, air_info, now); -- -- if (!RB_EMPTY_NODE(&txqi->schedule_order)) -+ if (txqi->schedule_round == local->schedule_round[ac]) - goto out; - -- /* If the station has been inactive for a while, catch up its v_t so it -- * doesn't get indefinite priority; see comment above the definition of -- * AIRTIME_MAX_BEHIND. -- */ -- if ((!was_active && air_info->v_t < air_sched->v_t) || -- air_info->v_t < air_sched->v_t - AIRTIME_MAX_BEHIND) -- air_info->v_t = air_sched->v_t; -- -- ieee80211_update_airtime_weight(local, air_sched, now, !was_active); -- __ieee80211_insert_txq(&air_sched->active_txqs, txqi); -+ list_del_init(&txqi->schedule_order); -+ txqi->schedule_round = local->schedule_round[ac]; -+ ret = &txqi->txq; - - out: -- spin_unlock_bh(&air_sched->lock); --} --EXPORT_SYMBOL(ieee80211_schedule_txq); -- --static void __ieee80211_unschedule_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq, -- bool purge) --{ -- struct ieee80211_local *local = hw_to_local(hw); -- struct txq_info *txqi = to_txq_info(txq); -- struct airtime_sched_info *air_sched; -- struct airtime_info *air_info; -- -- air_sched = &local->airtime[txq->ac]; -- air_info = to_airtime_info(&txqi->txq); -- -- lockdep_assert_held(&air_sched->lock); -- -- if (purge) { -- list_del_init(&air_info->list); -- ieee80211_update_airtime_weight(local, air_sched, 0, true); -- } -- -- if (RB_EMPTY_NODE(&txqi->schedule_order)) -- return; -- -- if (air_sched->schedule_pos == &txqi->schedule_order) -- air_sched->schedule_pos = rb_prev(&txqi->schedule_order); -- -- if (!purge) -- airtime_set_active(air_sched, air_info, -- ktime_get_coarse_boottime_ns()); -- -- rb_erase_cached(&txqi->schedule_order, -- &air_sched->active_txqs); -- RB_CLEAR_NODE(&txqi->schedule_order); -+ spin_unlock_bh(&local->active_txq_lock[ac]); -+ return ret; - } -+EXPORT_SYMBOL(ieee80211_next_txq); - --void ieee80211_unschedule_txq(struct ieee80211_hw *hw, -+void __ieee80211_schedule_txq(struct ieee80211_hw *hw, - struct ieee80211_txq *txq, -- bool purge) -- __acquires(txq_lock) __releases(txq_lock) --{ -- struct ieee80211_local *local = hw_to_local(hw); -- -- spin_lock_bh(&local->airtime[txq->ac].lock); -- __ieee80211_unschedule_txq(hw, txq, purge); -- spin_unlock_bh(&local->airtime[txq->ac].lock); --} -- --void ieee80211_return_txq(struct ieee80211_hw *hw, -- struct ieee80211_txq *txq, bool force) -+ bool force) - { - struct ieee80211_local *local = hw_to_local(hw); - struct txq_info *txqi = to_txq_info(txq); - -- spin_lock_bh(&local->airtime[txq->ac].lock); -+ spin_lock_bh(&local->active_txq_lock[txq->ac]); - -- if (!RB_EMPTY_NODE(&txqi->schedule_order) && !force && -- !txq_has_queue(txq)) -- __ieee80211_unschedule_txq(hw, txq, false); -+ if (list_empty(&txqi->schedule_order) && -+ (force || !skb_queue_empty(&txqi->frags) || -+ txqi->tin.backlog_packets)) { -+ /* If airtime accounting is active, always enqueue STAs at the -+ * head of the list to ensure that they only get moved to the -+ * back by the airtime DRR scheduler once they have a negative -+ * deficit. A station that already has a negative deficit will -+ * get immediately moved to the back of the list on the next -+ * call to ieee80211_next_txq(). -+ */ -+ if (txqi->txq.sta && local->airtime_flags && -+ wiphy_ext_feature_isset(local->hw.wiphy, -+ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) -+ list_add(&txqi->schedule_order, -+ &local->active_txqs[txq->ac]); -+ else -+ list_add_tail(&txqi->schedule_order, -+ &local->active_txqs[txq->ac]); -+ } - -- spin_unlock_bh(&local->airtime[txq->ac].lock); -+ spin_unlock_bh(&local->active_txq_lock[txq->ac]); - } --EXPORT_SYMBOL(ieee80211_return_txq); -+EXPORT_SYMBOL(__ieee80211_schedule_txq); - - DEFINE_STATIC_KEY_FALSE(aql_disable); - - bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, - struct ieee80211_txq *txq) - { -- struct airtime_info *air_info = to_airtime_info(txq); -+ struct sta_info *sta; - struct ieee80211_local *local = hw_to_local(hw); - - if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) -@@ -4086,12 +3930,15 @@ bool ieee80211_txq_airtime_check(struct - if (unlikely(txq->tid == IEEE80211_NUM_TIDS)) - return true; - -- if (atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_low) -+ sta = container_of(txq->sta, struct sta_info, sta); -+ if (atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < -+ sta->airtime[txq->ac].aql_limit_low) - return true; - - if (atomic_read(&local->aql_total_pending_airtime) < - local->aql_threshold && -- atomic_read(&air_info->aql_tx_pending) < air_info->aql_limit_high) -+ atomic_read(&sta->airtime[txq->ac].aql_tx_pending) < -+ sta->airtime[txq->ac].aql_limit_high) - return true; - - return false; -@@ -4101,59 +3948,60 @@ EXPORT_SYMBOL(ieee80211_txq_airtime_chec - bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, - struct ieee80211_txq *txq) - { -- struct txq_info *first_txqi = NULL, *txqi = to_txq_info(txq); - struct ieee80211_local *local = hw_to_local(hw); -- struct airtime_sched_info *air_sched; -- struct airtime_info *air_info; -- struct rb_node *node = NULL; -- bool ret = false; -- u64 now; -- -+ struct txq_info *iter, *tmp, *txqi = to_txq_info(txq); -+ struct sta_info *sta; -+ u8 ac = txq->ac; - -- if (!ieee80211_txq_airtime_check(hw, txq)) -- return false; -+ spin_lock_bh(&local->active_txq_lock[ac]); - -- air_sched = &local->airtime[txq->ac]; -- spin_lock_bh(&air_sched->lock); -+ if (!txqi->txq.sta) -+ goto out; - -- if (RB_EMPTY_NODE(&txqi->schedule_order)) -+ if (list_empty(&txqi->schedule_order)) - goto out; - -- now = ktime_get_coarse_boottime_ns(); -+ list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], -+ schedule_order) { -+ if (iter == txqi) -+ break; - -- /* Like in ieee80211_next_txq(), make sure the first station in the -- * scheduling order is eligible for transmission to avoid starvation. -- */ -- node = rb_first_cached(&air_sched->active_txqs); -- if (node) { -- first_txqi = container_of(node, struct txq_info, -- schedule_order); -- air_info = to_airtime_info(&first_txqi->txq); -- -- if (air_sched->v_t < air_info->v_t) -- airtime_catchup_v_t(air_sched, air_info->v_t, now); -+ if (!iter->txq.sta) { -+ list_move_tail(&iter->schedule_order, -+ &local->active_txqs[ac]); -+ continue; -+ } -+ sta = container_of(iter->txq.sta, struct sta_info, sta); -+ if (sta->airtime[ac].deficit < 0) -+ sta->airtime[ac].deficit += sta->airtime_weight; -+ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); - } - -- air_info = to_airtime_info(&txqi->txq); -- if (air_info->v_t <= air_sched->v_t) { -- air_sched->last_schedule_activity = now; -- ret = true; -- } -+ sta = container_of(txqi->txq.sta, struct sta_info, sta); -+ if (sta->airtime[ac].deficit >= 0) -+ goto out; -+ -+ sta->airtime[ac].deficit += sta->airtime_weight; -+ list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); -+ spin_unlock_bh(&local->active_txq_lock[ac]); - -+ return false; - out: -- spin_unlock_bh(&air_sched->lock); -- return ret; -+ if (!list_empty(&txqi->schedule_order)) -+ list_del_init(&txqi->schedule_order); -+ spin_unlock_bh(&local->active_txq_lock[ac]); -+ -+ return true; - } - EXPORT_SYMBOL(ieee80211_txq_may_transmit); - - void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) - { - struct ieee80211_local *local = hw_to_local(hw); -- struct airtime_sched_info *air_sched = &local->airtime[ac]; - -- spin_lock_bh(&air_sched->lock); -- air_sched->schedule_pos = NULL; -- spin_unlock_bh(&air_sched->lock); -+ spin_lock_bh(&local->active_txq_lock[ac]); -+ local->schedule_round[ac]++; -+ spin_unlock_bh(&local->active_txq_lock[ac]); - } - EXPORT_SYMBOL(ieee80211_txq_schedule_start); - diff --git a/package/kernel/mac80211/patches/subsys/331-v6.0-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch b/package/kernel/mac80211/patches/subsys/331-v6.0-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch deleted file mode 100644 index c006d3762a..0000000000 --- a/package/kernel/mac80211/patches/subsys/331-v6.0-mac80211-make-sta-airtime-deficit-field-s32-instead-.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Jun 2022 14:53:04 +0200 -Subject: [PATCH] mac80211: make sta airtime deficit field s32 instead of - s64 - -32 bit is more than enough range for the airtime deficit - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -202,7 +202,7 @@ static ssize_t sta_airtime_read(struct f - size_t bufsz = 400; - char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; - u64 rx_airtime = 0, tx_airtime = 0; -- s64 deficit[IEEE80211_NUM_ACS]; -+ s32 deficit[IEEE80211_NUM_ACS]; - ssize_t rv; - int ac; - -@@ -219,7 +219,7 @@ static ssize_t sta_airtime_read(struct f - - p += scnprintf(p, bufsz + buf - p, - "RX: %llu us\nTX: %llu us\nWeight: %u\n" -- "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", -+ "Deficit: VO: %d us VI: %d us BE: %d us BK: %d us\n", - rx_airtime, tx_airtime, sta->airtime_weight, - deficit[0], deficit[1], deficit[2], deficit[3]); - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -138,7 +138,7 @@ enum ieee80211_agg_stop_reason { - struct airtime_info { - u64 rx_airtime; - u64 tx_airtime; -- s64 deficit; -+ s32 deficit; - atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ - u32 aql_limit_low; - u32 aql_limit_high; ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3847,7 +3847,7 @@ struct ieee80211_txq *ieee80211_next_txq - struct sta_info *sta = container_of(txqi->txq.sta, - struct sta_info, sta); - bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); -- s64 deficit = sta->airtime[txqi->txq.ac].deficit; -+ s32 deficit = sta->airtime[txqi->txq.ac].deficit; - - if (aql_check) - found_eligible_txq = true; diff --git a/package/kernel/mac80211/patches/subsys/332-v6.0-mac80211-consider-aql_tx_pending-when-checking-airti.patch b/package/kernel/mac80211/patches/subsys/332-v6.0-mac80211-consider-aql_tx_pending-when-checking-airti.patch deleted file mode 100644 index c214294603..0000000000 --- a/package/kernel/mac80211/patches/subsys/332-v6.0-mac80211-consider-aql_tx_pending-when-checking-airti.patch +++ /dev/null @@ -1,48 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Jun 2022 14:59:09 +0200 -Subject: [PATCH] mac80211: consider aql_tx_pending when checking airtime - deficit - -When queueing packets for a station, deficit only gets added once the packets -have been transmitted, which could be much later. During that time, a lot of -temporary unfairness could happen, which could lead to bursty behavior. -Fix this by subtracting the aql_tx_pending when checking the deficit in tx -scheduling. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3817,6 +3817,13 @@ out: - } - EXPORT_SYMBOL(ieee80211_tx_dequeue); - -+static inline s32 ieee80211_sta_deficit(struct sta_info *sta, u8 ac) -+{ -+ struct airtime_info *air_info = &sta->airtime[ac]; -+ -+ return air_info->deficit - atomic_read(&air_info->aql_tx_pending); -+} -+ - struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) - { - struct ieee80211_local *local = hw_to_local(hw); -@@ -3847,7 +3854,7 @@ struct ieee80211_txq *ieee80211_next_txq - struct sta_info *sta = container_of(txqi->txq.sta, - struct sta_info, sta); - bool aql_check = ieee80211_txq_airtime_check(hw, &txqi->txq); -- s32 deficit = sta->airtime[txqi->txq.ac].deficit; -+ s32 deficit = ieee80211_sta_deficit(sta, txqi->txq.ac); - - if (aql_check) - found_eligible_txq = true; -@@ -3972,7 +3979,7 @@ bool ieee80211_txq_may_transmit(struct i - continue; - } - sta = container_of(iter->txq.sta, struct sta_info, sta); -- if (sta->airtime[ac].deficit < 0) -+ if (ieee80211_sta_deficit(sta, ac) < 0) - sta->airtime[ac].deficit += sta->airtime_weight; - list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); - } diff --git a/package/kernel/mac80211/patches/subsys/333-v6.0-mac80211-keep-recently-active-tx-queues-in-schedulin.patch b/package/kernel/mac80211/patches/subsys/333-v6.0-mac80211-keep-recently-active-tx-queues-in-schedulin.patch deleted file mode 100644 index 317e4f0653..0000000000 --- a/package/kernel/mac80211/patches/subsys/333-v6.0-mac80211-keep-recently-active-tx-queues-in-schedulin.patch +++ /dev/null @@ -1,118 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Jun 2022 20:52:50 +0200 -Subject: [PATCH] mac80211: keep recently active tx queues in scheduling - list - -This allows proper deficit accounting to ensure that they don't carry their -deficit until the next time they become active - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -83,6 +83,13 @@ extern const u8 ieee80211_ac_to_qos_mask - - #define IEEE80211_MAX_NAN_INSTANCE_ID 255 - -+ -+/* -+ * Keep a station's queues on the active list for deficit accounting purposes -+ * if it was active or queued during the last 100ms -+ */ -+#define AIRTIME_ACTIVE_DURATION (HZ / 10) -+ - struct ieee80211_bss { - u32 device_ts_beacon, device_ts_presp; - ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -138,6 +138,7 @@ enum ieee80211_agg_stop_reason { - struct airtime_info { - u64 rx_airtime; - u64 tx_airtime; -+ u32 last_active; - s32 deficit; - atomic_t aql_tx_pending; /* Estimated airtime for frames pending */ - u32 aql_limit_low; ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3824,6 +3824,36 @@ static inline s32 ieee80211_sta_deficit( - return air_info->deficit - atomic_read(&air_info->aql_tx_pending); - } - -+static void -+ieee80211_txq_set_active(struct txq_info *txqi) -+{ -+ struct sta_info *sta; -+ -+ if (!txqi->txq.sta) -+ return; -+ -+ sta = container_of(txqi->txq.sta, struct sta_info, sta); -+ sta->airtime[txqi->txq.ac].last_active = (u32)jiffies; -+} -+ -+static bool -+ieee80211_txq_keep_active(struct txq_info *txqi) -+{ -+ struct sta_info *sta; -+ u32 diff; -+ -+ if (!txqi->txq.sta) -+ return false; -+ -+ sta = container_of(txqi->txq.sta, struct sta_info, sta); -+ if (ieee80211_sta_deficit(sta, txqi->txq.ac) >= 0) -+ return false; -+ -+ diff = (u32)jiffies - sta->airtime[txqi->txq.ac].last_active; -+ -+ return diff <= AIRTIME_ACTIVE_DURATION; -+} -+ - struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) - { - struct ieee80211_local *local = hw_to_local(hw); -@@ -3870,7 +3900,6 @@ struct ieee80211_txq *ieee80211_next_txq - } - } - -- - if (txqi->schedule_round == local->schedule_round[ac]) - goto out; - -@@ -3890,12 +3919,13 @@ void __ieee80211_schedule_txq(struct iee - { - struct ieee80211_local *local = hw_to_local(hw); - struct txq_info *txqi = to_txq_info(txq); -+ bool has_queue; - - spin_lock_bh(&local->active_txq_lock[txq->ac]); - -+ has_queue = force || txq_has_queue(txq); - if (list_empty(&txqi->schedule_order) && -- (force || !skb_queue_empty(&txqi->frags) || -- txqi->tin.backlog_packets)) { -+ (has_queue || ieee80211_txq_keep_active(txqi))) { - /* If airtime accounting is active, always enqueue STAs at the - * head of the list to ensure that they only get moved to the - * back by the airtime DRR scheduler once they have a negative -@@ -3903,7 +3933,7 @@ void __ieee80211_schedule_txq(struct iee - * get immediately moved to the back of the list on the next - * call to ieee80211_next_txq(). - */ -- if (txqi->txq.sta && local->airtime_flags && -+ if (txqi->txq.sta && local->airtime_flags && has_queue && - wiphy_ext_feature_isset(local->hw.wiphy, - NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) - list_add(&txqi->schedule_order, -@@ -3911,6 +3941,8 @@ void __ieee80211_schedule_txq(struct iee - else - list_add_tail(&txqi->schedule_order, - &local->active_txqs[txq->ac]); -+ if (has_queue) -+ ieee80211_txq_set_active(txqi); - } - - spin_unlock_bh(&local->active_txq_lock[txq->ac]); diff --git a/package/kernel/mac80211/patches/subsys/334-v6.0-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch b/package/kernel/mac80211/patches/subsys/334-v6.0-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch deleted file mode 100644 index fb6fd6eac6..0000000000 --- a/package/kernel/mac80211/patches/subsys/334-v6.0-mac80211-add-a-per-PHY-AQL-limit-to-improve-fairness.patch +++ /dev/null @@ -1,131 +0,0 @@ -From: Felix Fietkau -Date: Mon, 20 Jun 2022 21:26:34 +0200 -Subject: [PATCH] mac80211: add a per-PHY AQL limit to improve fairness - -In order to maintain fairness, the amount of queueing needs to be limited -beyond the simple per-station AQL budget, otherwise the driver can simply -repeatedly do scheduling rounds until all queues that have not used their -AQL budget become eligble. - -To be conservative, use the high AQL limit for the first txq and add half -of the low AQL for each subsequent queue. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -1215,6 +1215,7 @@ struct ieee80211_local { - u32 aql_txq_limit_high[IEEE80211_NUM_ACS]; - u32 aql_threshold; - atomic_t aql_total_pending_airtime; -+ atomic_t aql_ac_pending_airtime[IEEE80211_NUM_ACS]; - - const struct ieee80211_ops *ops; - ---- a/net/mac80211/main.c -+++ b/net/mac80211/main.c -@@ -712,6 +712,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ - local->aql_txq_limit_low[i] = IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L; - local->aql_txq_limit_high[i] = - IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H; -+ atomic_set(&local->aql_ac_pending_airtime[i], 0); - } - - local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX; ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -1929,6 +1929,7 @@ void ieee80211_sta_update_pending_airtim - &sta->airtime[ac].aql_tx_pending); - - atomic_add(tx_airtime, &local->aql_total_pending_airtime); -+ atomic_add(tx_airtime, &local->aql_ac_pending_airtime[ac]); - return; - } - -@@ -1940,14 +1941,17 @@ void ieee80211_sta_update_pending_airtim - tx_pending, 0); - } - -+ atomic_sub(tx_airtime, &local->aql_total_pending_airtime); - tx_pending = atomic_sub_return(tx_airtime, -- &local->aql_total_pending_airtime); -+ &local->aql_ac_pending_airtime[ac]); - if (WARN_ONCE(tx_pending < 0, - "Device %s AC %d pending airtime underflow: %u, %u", - wiphy_name(local->hw.wiphy), ac, tx_pending, -- tx_airtime)) -- atomic_cmpxchg(&local->aql_total_pending_airtime, -+ tx_airtime)) { -+ atomic_cmpxchg(&local->aql_ac_pending_airtime[ac], - tx_pending, 0); -+ atomic_sub(tx_pending, &local->aql_total_pending_airtime); -+ } - } - - int sta_info_move_state(struct sta_info *sta, ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3863,6 +3863,9 @@ struct ieee80211_txq *ieee80211_next_txq - - spin_lock_bh(&local->active_txq_lock[ac]); - -+ if (!local->schedule_round[ac]) -+ goto out; -+ - begin: - txqi = list_first_entry_or_null(&local->active_txqs[ac], - struct txq_info, -@@ -3984,6 +3987,25 @@ bool ieee80211_txq_airtime_check(struct - } - EXPORT_SYMBOL(ieee80211_txq_airtime_check); - -+static bool -+ieee80211_txq_schedule_airtime_check(struct ieee80211_local *local, u8 ac) -+{ -+ unsigned int num_txq = 0; -+ struct txq_info *txq; -+ u32 aql_limit; -+ -+ if (!wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) -+ return true; -+ -+ list_for_each_entry(txq, &local->active_txqs[ac], schedule_order) -+ num_txq++; -+ -+ aql_limit = (num_txq - 1) * local->aql_txq_limit_low[ac] / 2 + -+ local->aql_txq_limit_high[ac]; -+ -+ return atomic_read(&local->aql_ac_pending_airtime[ac]) < aql_limit; -+} -+ - bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, - struct ieee80211_txq *txq) - { -@@ -4000,6 +4022,9 @@ bool ieee80211_txq_may_transmit(struct i - if (list_empty(&txqi->schedule_order)) - goto out; - -+ if (!ieee80211_txq_schedule_airtime_check(local, ac)) -+ goto out; -+ - list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], - schedule_order) { - if (iter == txqi) -@@ -4039,7 +4064,15 @@ void ieee80211_txq_schedule_start(struct - struct ieee80211_local *local = hw_to_local(hw); - - spin_lock_bh(&local->active_txq_lock[ac]); -- local->schedule_round[ac]++; -+ -+ if (ieee80211_txq_schedule_airtime_check(local, ac)) { -+ local->schedule_round[ac]++; -+ if (!local->schedule_round[ac]) -+ local->schedule_round[ac]++; -+ } else { -+ local->schedule_round[ac] = 0; -+ } -+ - spin_unlock_bh(&local->active_txq_lock[ac]); - } - EXPORT_SYMBOL(ieee80211_txq_schedule_start); diff --git a/package/kernel/mac80211/patches/subsys/335-v6.0-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch b/package/kernel/mac80211/patches/subsys/335-v6.0-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch deleted file mode 100644 index df45a520fa..0000000000 --- a/package/kernel/mac80211/patches/subsys/335-v6.0-mac80211-add-debugfs-file-to-display-per-phy-AQL-pen.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Felix Fietkau -Date: Sat, 25 Jun 2022 21:25:40 +0200 -Subject: [PATCH] mac80211: add debugfs file to display per-phy AQL pending - airtime - -Now that the global pending airtime is more relevant for airtime fairness, -it makes sense to make it accessible via debugfs for debugging - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -201,6 +201,36 @@ static const struct file_operations airt - .llseek = default_llseek, - }; - -+static ssize_t aql_pending_read(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct ieee80211_local *local = file->private_data; -+ char buf[400]; -+ int len = 0; -+ -+ len = scnprintf(buf, sizeof(buf), -+ "AC AQL pending\n" -+ "VO %u us\n" -+ "VI %u us\n" -+ "BE %u us\n" -+ "BK %u us\n" -+ "total %u us\n", -+ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VO]), -+ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_VI]), -+ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BE]), -+ atomic_read(&local->aql_ac_pending_airtime[IEEE80211_AC_BK]), -+ atomic_read(&local->aql_total_pending_airtime)); -+ return simple_read_from_buffer(user_buf, count, ppos, -+ buf, len); -+} -+ -+static const struct file_operations aql_pending_ops = { -+ .read = aql_pending_read, -+ .open = simple_open, -+ .llseek = default_llseek, -+}; -+ - static ssize_t aql_txq_limit_read(struct file *file, - char __user *user_buf, - size_t count, -@@ -628,6 +658,7 @@ void debugfs_hw_add(struct ieee80211_loc - DEBUGFS_ADD(hw_conf); - 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); diff --git a/package/kernel/mac80211/patches/subsys/336-v6.0-mac80211-only-accumulate-airtime-deficit-for-active-.patch b/package/kernel/mac80211/patches/subsys/336-v6.0-mac80211-only-accumulate-airtime-deficit-for-active-.patch deleted file mode 100644 index 35f07c1a97..0000000000 --- a/package/kernel/mac80211/patches/subsys/336-v6.0-mac80211-only-accumulate-airtime-deficit-for-active-.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Felix Fietkau -Date: Sat, 25 Jun 2022 23:10:19 +0200 -Subject: [PATCH] mac80211: only accumulate airtime deficit for active - clients - -When a client does not generate any local tx activity, accumulating airtime -deficit for the round-robin scheduler can be harmful. If this goes on for too -long, the deficit could grow quite large, which might cause unreasonable -initial latency once the client becomes active - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -1900,6 +1900,7 @@ void ieee80211_sta_register_airtime(stru - struct ieee80211_local *local = sta->sdata->local; - u8 ac = ieee80211_ac_from_tid(tid); - u32 airtime = 0; -+ u32 diff; - - if (sta->local->airtime_flags & AIRTIME_USE_TX) - airtime += tx_airtime; -@@ -1909,7 +1910,11 @@ void ieee80211_sta_register_airtime(stru - spin_lock_bh(&local->active_txq_lock[ac]); - sta->airtime[ac].tx_airtime += tx_airtime; - sta->airtime[ac].rx_airtime += rx_airtime; -- sta->airtime[ac].deficit -= airtime; -+ -+ diff = (u32)jiffies - sta->airtime[ac].last_active; -+ if (diff <= AIRTIME_ACTIVE_DURATION) -+ sta->airtime[ac].deficit -= airtime; -+ - spin_unlock_bh(&local->active_txq_lock[ac]); - } - EXPORT_SYMBOL(ieee80211_sta_register_airtime); diff --git a/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch b/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch deleted file mode 100644 index 74e857679e..0000000000 --- a/package/kernel/mac80211/patches/subsys/337-mac80211-increase-quantum-for-airtime-scheduler.patch +++ /dev/null @@ -1,53 +0,0 @@ -From: Felix Fietkau -Date: Sun, 26 Jun 2022 11:43:25 +0200 -Subject: [PATCH] mac80211: increase quantum for airtime scheduler - -Given the typical AQL budget and queue length, a quantum of 256 with the -default station weight often requires iterating over all queues frequently, -until one of them becomes eligible. -Improve performance by using 8 times station weight as scheduler quantum - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/ieee80211_i.h -+++ b/net/mac80211/ieee80211_i.h -@@ -90,6 +90,8 @@ extern const u8 ieee80211_ac_to_qos_mask - */ - #define AIRTIME_ACTIVE_DURATION (HZ / 10) - -+#define AIRTIME_QUANTUM_SHIFT 3 -+ - struct ieee80211_bss { - u32 device_ts_beacon, device_ts_presp; - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3894,7 +3894,7 @@ struct ieee80211_txq *ieee80211_next_txq - - if (deficit < 0) - sta->airtime[txqi->txq.ac].deficit += -- sta->airtime_weight; -+ sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; - - if (deficit < 0 || !aql_check) { - list_move_tail(&txqi->schedule_order, -@@ -4037,7 +4037,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) -- sta->airtime[ac].deficit += sta->airtime_weight; -+ sta->airtime[ac].deficit += sta->airtime_weight << -+ AIRTIME_QUANTUM_SHIFT; - list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); - } - -@@ -4045,7 +4046,7 @@ bool ieee80211_txq_may_transmit(struct i - if (sta->airtime[ac].deficit >= 0) - goto out; - -- sta->airtime[ac].deficit += sta->airtime_weight; -+ sta->airtime[ac].deficit += sta->airtime_weight << AIRTIME_QUANTUM_SHIFT; - list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); - spin_unlock_bh(&local->active_txq_lock[ac]); - diff --git a/package/kernel/mac80211/patches/subsys/339-v6.0-mac80211-exclude-multicast-packets-from-AQL-pending-.patch b/package/kernel/mac80211/patches/subsys/339-v6.0-mac80211-exclude-multicast-packets-from-AQL-pending-.patch deleted file mode 100644 index 43c3e75d65..0000000000 --- a/package/kernel/mac80211/patches/subsys/339-v6.0-mac80211-exclude-multicast-packets-from-AQL-pending-.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Felix Fietkau -Date: Wed, 13 Jul 2022 07:32:26 +0200 -Subject: [PATCH] mac80211: exclude multicast packets from AQL pending airtime - -In AP mode, multicast traffic is handled very differently from normal traffic, -especially if at least one client is in powersave mode. -This means that multicast packets can be buffered a lot longer than normal -unicast packets, and can eat up the AQL budget very quickly because of the low -data rate. -Along with the recent change to maintain a global PHY AQL limit, this can lead -to significant latency spikes for unicast traffic. - -Since queueing multicast to hardware is currently not constrained by AQL limits -anyway, let's just exclude it from the AQL pending airtime calculation entirely. - -Fixes: 8e4bac067105 ("wifi: mac80211: add a per-PHY AQL limit to improve fairness") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/tx.c -+++ b/net/mac80211/tx.c -@@ -3792,7 +3792,7 @@ begin: - encap_out: - IEEE80211_SKB_CB(skb)->control.vif = vif; - -- if (vif && -+ if (tx.sta && - wiphy_ext_feature_isset(local->hw.wiphy, NL80211_EXT_FEATURE_AQL)) { - bool ampdu = txq->ac != IEEE80211_AC_VO; - u32 airtime; diff --git a/package/kernel/mac80211/patches/subsys/340-v5.19-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch b/package/kernel/mac80211/patches/subsys/340-v5.19-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch deleted file mode 100644 index 82243f1d98..0000000000 --- a/package/kernel/mac80211/patches/subsys/340-v5.19-wifi-mac80211-do-not-abuse-fq.lock-in-ieee80211_do_s.patch +++ /dev/null @@ -1,46 +0,0 @@ -From aa40d5a43526cca9439a2b45fcfdcd016594dece Mon Sep 17 00:00:00 2001 -From: Tetsuo Handa -Date: Sun, 17 Jul 2022 21:21:52 +0900 -Subject: [PATCH] wifi: mac80211: do not abuse fq.lock in ieee80211_do_stop() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -lockdep complains use of uninitialized spinlock at ieee80211_do_stop() [1], -for commit f856373e2f31ffd3 ("wifi: mac80211: do not wake queues on a vif -that is being stopped") guards clear_bit() using fq.lock even before -fq_init() from ieee80211_txq_setup_flows() initializes this spinlock. - -According to discussion [2], Toke was not happy with expanding usage of -fq.lock. Since __ieee80211_wake_txqs() is called under RCU read lock, we -can instead use synchronize_rcu() for flushing ieee80211_wake_txqs(). - -Link: https://syzkaller.appspot.com/bug?extid=eceab52db7c4b961e9d6 [1] -Link: https://lkml.kernel.org/r/874k0zowh2.fsf@toke.dk [2] -Reported-by: syzbot -Signed-off-by: Tetsuo Handa -Fixes: f856373e2f31ffd3 ("wifi: mac80211: do not wake queues on a vif that is being stopped") -Tested-by: syzbot -Acked-by: Toke Høiland-Jørgensen -Signed-off-by: Kalle Valo -Link: https://lore.kernel.org/r/9cc9b81d-75a3-3925-b612-9d0ad3cab82b@I-love.SAKURA.ne.jp -[ pick up commit 3598cb6e1862 ("wifi: mac80211: do not abuse fq.lock in ieee80211_do_stop()") from -next] -Link: https://lore.kernel.org/all/87o7xcq6qt.fsf@kernel.org/ -Signed-off-by: Jakub Kicinski ---- - net/mac80211/iface.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -377,9 +377,8 @@ static void ieee80211_do_stop(struct iee - bool cancel_scan; - struct cfg80211_nan_func *func; - -- spin_lock_bh(&local->fq.lock); - clear_bit(SDATA_STATE_RUNNING, &sdata->state); -- spin_unlock_bh(&local->fq.lock); -+ synchronize_rcu(); /* flush _ieee80211_wake_txqs() */ - - cancel_scan = rcu_access_pointer(local->scan_sdata) == sdata; - if (cancel_scan) diff --git a/package/kernel/mac80211/patches/subsys/341-v6.0-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch b/package/kernel/mac80211/patches/subsys/341-v6.0-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch deleted file mode 100644 index 8c56acbf88..0000000000 --- a/package/kernel/mac80211/patches/subsys/341-v6.0-mac80211-Fix-deadlock-Don-t-start-TX-while-holding-f.patch +++ /dev/null @@ -1,40 +0,0 @@ -From: Alexander Wetzel -Date: Thu, 15 Sep 2022 14:41:20 +0200 -Subject: [PATCH] mac80211: Fix deadlock: Don't start TX while holding - fq->lock - -ieee80211_txq_purge() calls fq_tin_reset() and -ieee80211_purge_tx_queue(); Both are then calling -ieee80211_free_txskb(). Which can decide to TX the skb again. - -There are at least two ways to get a deadlock: - -1) When we have a TDLS teardown packet queued in either tin or frags - ieee80211_tdls_td_tx_handle() will call ieee80211_subif_start_xmit() - while we still hold fq->lock. ieee80211_txq_enqueue() will thus - deadlock. - -2) A variant of the above happens if aggregation is up and running: - In that case ieee80211_iface_work() will deadlock with the original - task: The original tasks already holds fq->lock and tries to get - sta->lock after kicking off ieee80211_iface_work(). But the worker - can get sta->lock prior to the original task and will then spin for - fq->lock. - -Avoid these deadlocks by not sending out any skbs when called via -ieee80211_free_txskb(). - -Signed-off-by: Alexander Wetzel ---- - ---- a/net/mac80211/status.c -+++ b/net/mac80211/status.c -@@ -698,7 +698,7 @@ static void ieee80211_report_used_skb(st - - if (!sdata) { - skb->dev = NULL; -- } else { -+ } else if (!dropped) { - unsigned int hdr_size = - ieee80211_hdrlen(hdr->frame_control); - diff --git a/package/kernel/mac80211/patches/subsys/342-v6.0-mac80211-Ensure-vif-queues-are-operational-after-sta.patch b/package/kernel/mac80211/patches/subsys/342-v6.0-mac80211-Ensure-vif-queues-are-operational-after-sta.patch deleted file mode 100644 index 4310329319..0000000000 --- a/package/kernel/mac80211/patches/subsys/342-v6.0-mac80211-Ensure-vif-queues-are-operational-after-sta.patch +++ /dev/null @@ -1,47 +0,0 @@ -From: Alexander Wetzel -Date: Thu, 15 Sep 2022 15:09:46 +0200 -Subject: [PATCH] mac80211: Ensure vif queues are operational after start - -Make sure local->queue_stop_reasons and vif.txqs_stopped stay in sync. - -When a new vif is created the queues may end up in an inconsistent state -and be inoperable: -Communication not using iTXQ will work, allowing to e.g. complete the -association. But the 4-way handshake will time out. The sta will not -send out any skbs queued in iTXQs. - -All normal attempts to start the queues will fail when reaching this -state. -local->queue_stop_reasons will have marked all queues as operational but -vif.txqs_stopped will still be set, creating an inconsistent internal -state. - -In reality this seems to be race between the mac80211 function -ieee80211_do_open() setting SDATA_STATE_RUNNING and the wake_txqs_tasklet: -Depending on the driver and the timing the queues may end up to be -operational or not. - -Cc: stable@vger.kernel.org -Fixes: f856373e2f31 ("wifi: mac80211: do not wake queues on a vif that is being stopped") -Signed-off-by: Alexander Wetzel ---- - ---- a/net/mac80211/util.c -+++ b/net/mac80211/util.c -@@ -301,14 +301,14 @@ static void __ieee80211_wake_txqs(struct - local_bh_disable(); - spin_lock(&fq->lock); - -+ sdata->vif.txqs_stopped[ac] = false; -+ - if (!test_bit(SDATA_STATE_RUNNING, &sdata->state)) - goto out; - - if (sdata->vif.type == NL80211_IFTYPE_AP) - ps = &sdata->bss->ps; - -- sdata->vif.txqs_stopped[ac] = false; -- - list_for_each_entry_rcu(sta, &local->sta_list, list) { - if (sdata != sta->sdata) - continue; diff --git a/package/kernel/mac80211/patches/subsys/343-v6.1-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch b/package/kernel/mac80211/patches/subsys/343-v6.1-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch deleted file mode 100644 index 0246785475..0000000000 --- a/package/kernel/mac80211/patches/subsys/343-v6.1-wifi-mac80211-fix-decap-offload-for-stations-on-AP_V.patch +++ /dev/null @@ -1,37 +0,0 @@ -From: Felix Fietkau -Date: Wed, 28 Sep 2022 13:50:34 +0200 -Subject: [PATCH] wifi: mac80211: fix decap offload for stations on AP_VLAN - interfaces - -Since AP_VLAN interfaces are not passed to the driver, check offload_flags -on the bss vif instead. - -Reported-by: Howard Hsu -Fixes: 80a915ec4427 ("mac80211: add rx decapsulation offload support") -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -4267,6 +4267,7 @@ void ieee80211_check_fast_rx(struct sta_ - .vif_type = sdata->vif.type, - .control_port_protocol = sdata->control_port_protocol, - }, *old, *new = NULL; -+ u32 offload_flags; - bool set_offload = false; - bool assign = false; - bool offload; -@@ -4382,10 +4383,10 @@ void ieee80211_check_fast_rx(struct sta_ - if (assign) - new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL); - -- offload = assign && -- (sdata->vif.offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED); -+ offload_flags = get_bss_sdata(sdata)->vif.offload_flags; -+ offload = offload_flags & IEEE80211_OFFLOAD_DECAP_ENABLED; - -- if (offload) -+ if (assign && offload) - set_offload = !test_and_set_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); - else - set_offload = test_and_clear_sta_flag(sta, WLAN_STA_DECAP_OFFLOAD); diff --git a/package/kernel/mac80211/patches/subsys/344-v6.1-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch b/package/kernel/mac80211/patches/subsys/344-v6.1-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch deleted file mode 100644 index 161c7d6c8f..0000000000 --- a/package/kernel/mac80211/patches/subsys/344-v6.1-wifi-cfg80211-fix-ieee80211_data_to_8023_exthdr-hand.patch +++ /dev/null @@ -1,99 +0,0 @@ -From: Felix Fietkau -Date: Fri, 7 Oct 2022 10:54:47 +0200 -Subject: [PATCH] wifi: cfg80211: fix ieee80211_data_to_8023_exthdr - handling of small packets - -STP topology change notification packets only have a payload of 7 bytes, -so they get dropped due to the skb->len < hdrlen + 8 check. -Fix this by removing skb->len based checks and instead check the return code -on the skb_copy_bits calls. - -Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") -Reported-by: Chad Monroe -Signed-off-by: Felix Fietkau ---- - ---- a/net/wireless/util.c -+++ b/net/wireless/util.c -@@ -557,7 +557,7 @@ int ieee80211_data_to_8023_exthdr(struct - return -1; - - hdrlen = ieee80211_hdrlen(hdr->frame_control) + data_offset; -- if (skb->len < hdrlen + 8) -+ if (skb->len < hdrlen) - return -1; - - /* convert IEEE 802.11 header + possible LLC headers into Ethernet -@@ -572,8 +572,9 @@ 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); -+ if (iftype == NL80211_IFTYPE_MESH_POINT && -+ skb_copy_bits(skb, hdrlen, &mesh_flags, 1) < 0) -+ return -1; - - mesh_flags &= MESH_FLAGS_AE; - -@@ -593,11 +594,12 @@ int ieee80211_data_to_8023_exthdr(struct - 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); -- } -+ 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; -@@ -611,10 +613,11 @@ int ieee80211_data_to_8023_exthdr(struct - 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); -+ 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; -@@ -626,18 +629,18 @@ int ieee80211_data_to_8023_exthdr(struct - break; - } - -- skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); -- tmp.h_proto = payload.proto; -- -- if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) && -- tmp.h_proto != htons(ETH_P_AARP) && -- tmp.h_proto != htons(ETH_P_IPX)) || -- ether_addr_equal(payload.hdr, bridge_tunnel_header))) -+ if (likely(skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)) == 0 && -+ ((!is_amsdu && 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 */ - hdrlen += ETH_ALEN + 2; -- else -+ tmp.h_proto = payload.proto; -+ } else { - tmp.h_proto = htons(skb->len - hdrlen); -+ } - - pskb_pull(skb, hdrlen); - diff --git a/package/kernel/mac80211/patches/subsys/345-v6.1-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch b/package/kernel/mac80211/patches/subsys/345-v6.1-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch deleted file mode 100644 index 23047f68c9..0000000000 --- a/package/kernel/mac80211/patches/subsys/345-v6.1-wifi-mac80211-do-not-drop-packets-smaller-than-the-L.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Felix Fietkau -Date: Fri, 7 Oct 2022 10:58:26 +0200 -Subject: [PATCH] wifi: mac80211: do not drop packets smaller than the - LLC-SNAP header on fast-rx - -Since STP TCN frames are only 7 bytes, the pskb_may_pull call returns an error. -Instead of dropping those packets, bump them back to the slow path for proper -processing. - -Fixes: 49ddf8e6e234 ("mac80211: add fast-rx path") -Reported-by: Chad Monroe -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -4603,7 +4603,7 @@ static bool ieee80211_invoke_fast_rx(str - - if (!(status->rx_flags & IEEE80211_RX_AMSDU)) { - if (!pskb_may_pull(skb, snap_offs + sizeof(*payload))) -- goto drop; -+ return false; - - payload = (void *)(skb->data + snap_offs); - diff --git a/package/kernel/mac80211/patches/subsys/346-v6.0-wifi-mac80211-fix-mesh-airtime-link-metric-estimatin.patch b/package/kernel/mac80211/patches/subsys/346-v6.0-wifi-mac80211-fix-mesh-airtime-link-metric-estimatin.patch deleted file mode 100644 index 7185a7fed6..0000000000 --- a/package/kernel/mac80211/patches/subsys/346-v6.0-wifi-mac80211-fix-mesh-airtime-link-metric-estimatin.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Aditya Kumar Singh -Date: Fri, 1 Jul 2022 19:06:11 +0530 -Subject: [PATCH] wifi: mac80211: fix mesh airtime link metric estimating - -ieee80211s_update_metric function uses sta_set_rate_info_tx -function to get struct rate_info data from ieee80211_tx_rate -struct, present in ieee80211_sta->deflink.tx_stats. However, -drivers can skip tx rate calculation by setting rate idx as --1. Such drivers provides rate_info directly and hence -ieee80211s metric is updated incorrectly since ieee80211_tx_rate -has inconsistent data. - -Add fix to use rate_info directly if present instead of -sta_set_rate_info_tx for updating ieee80211s metric. - -Signed-off-by: Aditya Kumar Singh -Link: https://lore.kernel.org/r/20220701133611.544-1-quic_adisi@quicinc.com -Signed-off-by: Johannes Berg ---- - ---- a/net/mac80211/mesh_hwmp.c -+++ b/net/mac80211/mesh_hwmp.c -@@ -310,7 +310,12 @@ void ieee80211s_update_metric(struct iee - LINK_FAIL_THRESH) - mesh_plink_broken(sta); - -- sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo); -+ /* use rate info set by the driver directly if present */ -+ if (st->rate) -+ rinfo = sta->tx_stats.last_rate_info; -+ else -+ sta_set_rate_info_tx(sta, &sta->tx_stats.last_rate, &rinfo); -+ - ewma_mesh_tx_rate_avg_add(&sta->mesh->tx_rate_avg, - cfg80211_calculate_bitrate(&rinfo)); - } diff --git a/package/kernel/mac80211/patches/subsys/363-v5.19-bss-color-collision.patch b/package/kernel/mac80211/patches/subsys/363-v5.19-bss-color-collision.patch deleted file mode 100644 index edee4b3ee0..0000000000 --- a/package/kernel/mac80211/patches/subsys/363-v5.19-bss-color-collision.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 6d945a33f2b0aa24fc210dadaa0af3e8218e7002 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -Date: Fri, 25 Mar 2022 11:42:41 +0100 -Subject: [PATCH] mac80211: introduce BSS color collision detection - -Add ieee80211_rx_check_bss_color_collision routine in order to introduce -BSS color collision detection in mac80211 if it is not supported in HW/FW -(e.g. for mt7915 chipset). -Add IEEE80211_HW_DETECTS_COLOR_COLLISION flag to let the driver notify -BSS color collision detection is supported in HW/FW. Set this for ath11k -which apparently didn't need this code. - -Tested-by: Peter Chiu -Co-developed-by: Ryder Lee -Signed-off-by: Ryder Lee -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/a05eeeb1841a84560dc5aaec77894fcb69a54f27.1648204871.git.lorenzo@kernel.org -[clarify commit message a bit, move flag to mac80211] -Signed-off-by: Johannes Berg ---- - drivers/net/wireless/ath/ath11k/mac.c | 5 ++- - include/net/mac80211.h | 4 +++ - net/mac80211/debugfs.c | 1 + - net/mac80211/rx.c | 46 +++++++++++++++++++++++++++ - 4 files changed, 55 insertions(+), 1 deletion(-) - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -2418,6 +2418,9 @@ struct ieee80211_txq { - * usage and 802.11 frames with %RX_FLAG_ONLY_MONITOR set for monitor to - * the stack. - * -+ * @IEEE80211_HW_DETECTS_COLOR_COLLISION: HW/driver has support for BSS color -+ * collision detection and doesn't need it in software. -+ * - * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays - */ - enum ieee80211_hw_flags { -@@ -2473,6 +2476,7 @@ enum ieee80211_hw_flags { - IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD, - IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD, - IEEE80211_HW_SUPPORTS_CONC_MON_RX_DECAP, -+ IEEE80211_HW_DETECTS_COLOR_COLLISION, - - /* keep last, obviously */ - NUM_IEEE80211_HW_FLAGS ---- a/net/mac80211/debugfs.c -+++ b/net/mac80211/debugfs.c -@@ -494,6 +494,7 @@ static const char *hw_flag_names[] = { - FLAG(SUPPORTS_TX_ENCAP_OFFLOAD), - FLAG(SUPPORTS_RX_DECAP_OFFLOAD), - FLAG(SUPPORTS_CONC_MON_RX_DECAP), -+ FLAG(DETECTS_COLOR_COLLISION), - #undef FLAG - }; - ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -3182,6 +3182,49 @@ static void ieee80211_process_sa_query_r - ieee80211_tx_skb(sdata, skb); - } - -+static void -+ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx) -+{ -+ struct ieee80211_mgmt *mgmt = (void *)rx->skb->data; -+ const struct element *ie; -+ size_t baselen; -+ -+ if (!wiphy_ext_feature_isset(rx->local->hw.wiphy, -+ NL80211_EXT_FEATURE_BSS_COLOR)) -+ return; -+ -+ if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION)) -+ return; -+ -+ if (rx->sdata->vif.csa_active) -+ return; -+ -+ baselen = mgmt->u.beacon.variable - rx->skb->data; -+ if (baselen > rx->skb->len) -+ return; -+ -+ ie = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_OPERATION, -+ mgmt->u.beacon.variable, -+ rx->skb->len - baselen); -+ if (ie && ie->datalen >= sizeof(struct ieee80211_he_operation) && -+ ie->datalen >= ieee80211_he_oper_size(ie->data + 1)) { -+ struct ieee80211_bss_conf *bss_conf = &rx->sdata->vif.bss_conf; -+ const struct ieee80211_he_operation *he_oper; -+ u8 color; -+ -+ he_oper = (void *)(ie->data + 1); -+ if (le32_get_bits(he_oper->he_oper_params, -+ IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED)) -+ return; -+ -+ color = le32_get_bits(he_oper->he_oper_params, -+ IEEE80211_HE_OPERATION_BSS_COLOR_MASK); -+ if (color == bss_conf->he_bss_color.color) -+ ieeee80211_obss_color_collision_notify(&rx->sdata->vif, -+ BIT_ULL(color)); -+ } -+} -+ - static ieee80211_rx_result debug_noinline - ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx) - { -@@ -3207,6 +3250,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802 - !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) { - int sig = 0; - -+ /* sw bss color collision detection */ -+ ieee80211_rx_check_bss_color_collision(rx); -+ - if (ieee80211_hw_check(&rx->local->hw, SIGNAL_DBM) && - !(status->flag & RX_FLAG_NO_SIGNAL_VAL)) - sig = status->signal; diff --git a/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch b/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch deleted file mode 100644 index d133ed91eb..0000000000 --- a/package/kernel/mac80211/patches/subsys/364-mac80211-add-support-for-restricting-netdev-features.patch +++ /dev/null @@ -1,513 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 -@@ -1685,6 +1685,10 @@ enum ieee80211_offload_flags { - * write-protected by sdata_lock and local->mtx so holding either is fine - * for read access. - * @mu_mimo_owner: indicates interface owns MU-MIMO capability -+ * @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 -@@ -1736,6 +1740,7 @@ struct ieee80211_vif { - - struct ieee80211_chanctx_conf __rcu *chanctx_conf; - -+ netdev_features_t netdev_features; - u32 driver_flags; - u32 offload_flags; - ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -2209,6 +2209,7 @@ int ieee80211_if_add(struct ieee80211_lo - ndev->features |= local->hw.netdev_features; - 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 -@@ -1310,7 +1310,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) -@@ -3499,47 +3503,71 @@ 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; -+ } -+ -+ 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; - } - -- /* after this point (skb is modified) we cannot return false */ -+ 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; - - if (skb_shared(skb)) { - struct sk_buff *tmp_skb = skb; -@@ -3548,12 +3576,12 @@ static bool ieee80211_xmit_fast(struct i - kfree_skb(tmp_skb); - - if (!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 -@@ -3562,10 +3590,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); -@@ -3579,7 +3605,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; - - #ifdef CPTCFG_MAC80211_DEBUGFS -@@ -3601,16 +3627,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, -@@ -3618,6 +3642,55 @@ 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; -+ } -+ } -+ -+ 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; - } - -@@ -4123,31 +4196,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) { -@@ -4310,9 +4366,11 @@ netdev_tx_t ieee80211_subif_start_xmit(s - 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 = {}; -@@ -4321,14 +4379,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] || -@@ -4355,27 +4405,50 @@ 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) - { -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ 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; - - if (local->ops->wake_tx_queue) { -- u16 queue = __ieee80211_select_queue(sdata, sta, skb); -+ queue = __ieee80211_select_queue(sdata, sta, skb); - skb_set_queue_mapping(skb, queue); - skb_get_hash(skb); -+ } else { -+ queue = skb_get_queue_mapping(skb); - } - - if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) && - test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state)) - goto out_free; - -- memset(info, 0, sizeof(*info)); -- - ieee80211_aggr_check(sdata, sta, skb); - - tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; -@@ -4387,22 +4460,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->tx_stats.bytes[skb_get_queue_mapping(skb)] += skb->len; -- sta->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, -@@ -4414,6 +4485,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->tx_stats.packets[queue] += skbs; -+ sta->tx_stats.bytes[queue] += len; -+ -+ ieee80211_tpt_led_trig_tx(local, len); -+ - ieee80211_tx_8023(sdata, skb, sta, false); - - return; -@@ -4455,6 +4544,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/400-allow-ibss-mixed.patch b/package/kernel/mac80211/patches/subsys/400-allow-ibss-mixed.patch index f0f850dc6f..c38fa13f03 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 -@@ -625,21 +625,6 @@ static int wiphy_verify_combinations(str +@@ -614,21 +614,6 @@ static int wiphy_verify_combinations(str c->limits[j].max > 1)) return -EINVAL; diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch index 962ae93cc7..13b374aae7 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -3869,6 +3869,7 @@ struct mgmt_frame_regs { +@@ -4081,6 +4081,7 @@ struct mgmt_frame_regs { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting * functions to adjust rfkill hw state -@@ -4202,6 +4203,7 @@ struct cfg80211_ops { +@@ -4431,6 +4432,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -18,7 +18,7 @@ --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1566,6 +1566,7 @@ enum ieee80211_smps_mode { +@@ -1645,6 +1645,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1586,6 +1587,7 @@ enum ieee80211_smps_mode { +@@ -1665,6 +1666,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -36,19 +36,19 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2615,6 +2615,9 @@ enum nl80211_commands { - * switching on a different channel during CAC detection on the selected - * radar channel. - * +@@ -2749,6 +2749,9 @@ enum nl80211_commands { + * When used with %NL80211_CMD_FRAME_TX_STATUS, indicates the ack RX + * timestamp. When used with %NL80211_CMD_FRAME RX notification, indicates + * the incoming frame RX timestamp. + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -3123,6 +3126,8 @@ enum nl80211_attrs { - - NL80211_ATTR_RADAR_BACKGROUND, +@@ -3277,6 +3280,8 @@ enum nl80211_attrs { + NL80211_ATTR_TX_HW_TIMESTAMP, + NL80211_ATTR_RX_HW_TIMESTAMP, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2812,6 +2812,19 @@ static int ieee80211_get_tx_power(struct +@@ -2998,6 +2998,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy) { struct ieee80211_local *local = wiphy_priv(wiphy); -@@ -4513,6 +4526,7 @@ const struct cfg80211_ops mac80211_confi +@@ -4881,6 +4894,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -87,7 +87,7 @@ CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1447,6 +1447,7 @@ struct ieee80211_local { +@@ -1521,6 +1521,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ @@ -119,7 +119,7 @@ if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; -@@ -679,6 +685,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -762,6 +768,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ IEEE80211_RADIOTAP_MCS_HAVE_BW; local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; @@ -129,15 +129,15 @@ local->hw.max_mtu = IEEE80211_MAX_DATA_LEN; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -802,6 +802,7 @@ static const struct nla_policy nl80211_p - NLA_POLICY_NESTED(nl80211_mbssid_config_policy), - [NL80211_ATTR_MBSSID_ELEMS] = { .type = NLA_NESTED }, - [NL80211_ATTR_RADAR_BACKGROUND] = { .type = NLA_FLAG }, +@@ -799,6 +799,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_MLD_ADDR] = NLA_POLICY_EXACT_LEN(ETH_ALEN), + [NL80211_ATTR_MLO_SUPPORT] = { .type = NLA_FLAG }, + [NL80211_ATTR_MAX_NUM_AKM_SUITES] = { .type = NLA_REJECT }, + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -3391,6 +3392,22 @@ static int nl80211_set_wiphy(struct sk_b +@@ -3511,6 +3512,22 @@ static int nl80211_set_wiphy(struct sk_b if (result) goto out; } diff --git a/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch b/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch deleted file mode 100644 index dc2b05b1a3..0000000000 --- a/package/kernel/mac80211/patches/subsys/783-sync-nl80211.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -6027,6 +6027,11 @@ enum nl80211_feature_flags { - * @NL80211_EXT_FEATURE_BSS_COLOR: The driver supports BSS color collision - * detection and change announcemnts. - * -+ * @NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD: Driver running in AP mode supports -+ * FILS encryption and decryption for (Re)Association Request and Response -+ * frames. Userspace has to share FILS AAD details to the driver by using -+ * @NL80211_CMD_SET_FILS_AAD. -+ * - * @NL80211_EXT_FEATURE_RADAR_BACKGROUND: Device supports background radar/CAC - * detection. - * -@@ -6095,6 +6100,7 @@ enum nl80211_ext_feature_index { - NL80211_EXT_FEATURE_SECURE_RTT, - NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE, - NL80211_EXT_FEATURE_BSS_COLOR, -+ NL80211_EXT_FEATURE_FILS_CRYPTO_OFFLOAD, - NL80211_EXT_FEATURE_RADAR_BACKGROUND, - - /* add new features before the definition below */ diff --git a/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch b/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch index a17d6f6161..56cc523022 100644 --- a/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch +++ b/package/kernel/mac80211/patches/subsys/800-mac80211-mask-nested-A-MSDU-support-for-mesh.patch @@ -18,7 +18,7 @@ Signed-off-by: David Bauer --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c -@@ -251,7 +251,11 @@ static void ieee80211_send_addba_resp(st +@@ -254,7 +254,11 @@ static void ieee80211_send_addba_resp(st mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; mgmt->u.action.u.addba_resp.dialog_token = dialog_token; -- cgit v1.2.3