aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/subsys/315-cfg80211-move-offchan_cac_event-to-a-dedicated-work.patch
blob: b1a1d2c8945d49e9be27b3f3464c10bcdd7786dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
From: Lorenzo Bianconi <lorenzo@kernel.org>
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 <lorenzo@kernel.org>
Link: https://lore.kernel.org/r/6145c3d0f30400a568023f67981981d24c7c6133.1635325205.git.lorenzo@kernel.org
[rewrite commit log]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---

--- 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;