mac80211: fix traffic stalls on forwarded mesh packets due to wrong AC selection
[openwrt/staging/chunkeey.git] / package / kernel / mac80211 / patches / subsys / 317-cfg80211-schedule-offchan_cac_abort_wk-in-cfg80211_r.patch
1 From: Lorenzo Bianconi <lorenzo@kernel.org>
2 Date: Tue, 16 Nov 2021 12:41:52 +0100
3 Subject: [PATCH] cfg80211: schedule offchan_cac_abort_wk in
4 cfg80211_radar_event
5
6 If necessary schedule offchan_cac_abort_wk work in cfg80211_radar_event
7 routine adding offchan parameter to cfg80211_radar_event signature.
8 Rename cfg80211_radar_event in __cfg80211_radar_event and introduce
9 the two following inline helpers:
10 - cfg80211_radar_event
11 - cfg80211_offchan_radar_event
12 Doing so the drv will not need to run cfg80211_offchan_cac_abort() after
13 radar detection on the offchannel chain.
14
15 Tested-by: Owen Peng <owen.peng@mediatek.com>
16 Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
17 Link: https://lore.kernel.org/r/3ff583e021e3343a3ced54a7b09b5e184d1880dc.1637062727.git.lorenzo@kernel.org
18 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
19 ---
20
21 --- a/include/net/cfg80211.h
22 +++ b/include/net/cfg80211.h
23 @@ -7580,15 +7580,33 @@ void cfg80211_cqm_txe_notify(struct net_
24 void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp);
25
26 /**
27 - * cfg80211_radar_event - radar detection event
28 + * __cfg80211_radar_event - radar detection event
29 * @wiphy: the wiphy
30 * @chandef: chandef for the current channel
31 + * @offchan: the radar has been detected on the offchannel chain
32 * @gfp: context flags
33 *
34 * This function is called when a radar is detected on the current chanenl.
35 */
36 -void cfg80211_radar_event(struct wiphy *wiphy,
37 - struct cfg80211_chan_def *chandef, gfp_t gfp);
38 +void __cfg80211_radar_event(struct wiphy *wiphy,
39 + struct cfg80211_chan_def *chandef,
40 + bool offchan, gfp_t gfp);
41 +
42 +static inline void
43 +cfg80211_radar_event(struct wiphy *wiphy,
44 + struct cfg80211_chan_def *chandef,
45 + gfp_t gfp)
46 +{
47 + __cfg80211_radar_event(wiphy, chandef, false, gfp);
48 +}
49 +
50 +static inline void
51 +cfg80211_offchan_radar_event(struct wiphy *wiphy,
52 + struct cfg80211_chan_def *chandef,
53 + gfp_t gfp)
54 +{
55 + __cfg80211_radar_event(wiphy, chandef, true, gfp);
56 +}
57
58 /**
59 * cfg80211_sta_opmode_change_notify - STA's ht/vht operation mode change event
60 --- a/net/wireless/mlme.c
61 +++ b/net/wireless/mlme.c
62 @@ -905,13 +905,13 @@ void cfg80211_dfs_channels_update_work(s
63 }
64
65
66 -void cfg80211_radar_event(struct wiphy *wiphy,
67 - struct cfg80211_chan_def *chandef,
68 - gfp_t gfp)
69 +void __cfg80211_radar_event(struct wiphy *wiphy,
70 + struct cfg80211_chan_def *chandef,
71 + bool offchan, gfp_t gfp)
72 {
73 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
74
75 - trace_cfg80211_radar_event(wiphy, chandef);
76 + trace_cfg80211_radar_event(wiphy, chandef, offchan);
77
78 /* only set the chandef supplied channel to unavailable, in
79 * case the radar is detected on only one of multiple channels
80 @@ -919,6 +919,9 @@ void cfg80211_radar_event(struct wiphy *
81 */
82 cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_UNAVAILABLE);
83
84 + if (offchan)
85 + queue_work(cfg80211_wq, &rdev->offchan_cac_abort_wk);
86 +
87 cfg80211_sched_dfs_chan_update(rdev);
88
89 nl80211_radar_notify(rdev, chandef, NL80211_RADAR_DETECTED, NULL, gfp);
90 @@ -926,7 +929,7 @@ void cfg80211_radar_event(struct wiphy *
91 memcpy(&rdev->radar_chandef, chandef, sizeof(struct cfg80211_chan_def));
92 queue_work(cfg80211_wq, &rdev->propagate_radar_detect_wk);
93 }
94 -EXPORT_SYMBOL(cfg80211_radar_event);
95 +EXPORT_SYMBOL(__cfg80211_radar_event);
96
97 void cfg80211_cac_event(struct net_device *netdev,
98 const struct cfg80211_chan_def *chandef,
99 @@ -998,7 +1001,8 @@ __cfg80211_offchan_cac_event(struct cfg8
100 rdev->offchan_radar_wdev = NULL;
101 break;
102 case NL80211_RADAR_CAC_ABORTED:
103 - cancel_delayed_work(&rdev->offchan_cac_done_wk);
104 + if (!cancel_delayed_work(&rdev->offchan_cac_done_wk))
105 + return;
106 wdev = rdev->offchan_radar_wdev;
107 rdev->offchan_radar_wdev = NULL;
108 break;
109 --- a/net/wireless/trace.h
110 +++ b/net/wireless/trace.h
111 @@ -3022,18 +3022,21 @@ TRACE_EVENT(cfg80211_ch_switch_started_n
112 );
113
114 TRACE_EVENT(cfg80211_radar_event,
115 - TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef),
116 - TP_ARGS(wiphy, chandef),
117 + TP_PROTO(struct wiphy *wiphy, struct cfg80211_chan_def *chandef,
118 + bool offchan),
119 + TP_ARGS(wiphy, chandef, offchan),
120 TP_STRUCT__entry(
121 WIPHY_ENTRY
122 CHAN_DEF_ENTRY
123 + __field(bool, offchan)
124 ),
125 TP_fast_assign(
126 WIPHY_ASSIGN;
127 CHAN_DEF_ASSIGN(chandef);
128 + __entry->offchan = offchan;
129 ),
130 - TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT,
131 - WIPHY_PR_ARG, CHAN_DEF_PR_ARG)
132 + TP_printk(WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT ", offchan %d",
133 + WIPHY_PR_ARG, CHAN_DEF_PR_ARG, __entry->offchan)
134 );
135
136 TRACE_EVENT(cfg80211_cac_event,