blob: 44043ac3ec42b2cf5b76512d3d6929890b1944ad [file] [log] [blame]
developer05f3b2b2024-08-19 19:17:34 +08001From a218fd8e2e8a2d390d995e62ba9e351c6cee30fb Mon Sep 17 00:00:00 2001
2From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
3Date: Tue, 11 Jun 2024 16:10:12 +0800
4Subject: [PATCH 78/89] mtk: mac80211: add per-radio antenna config
5
6Add per-radio antenna config
7
8Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
9---
10 include/net/cfg80211.h | 9 ++--
11 include/net/mac80211.h | 4 +-
12 net/mac80211/cfg.c | 19 +++++---
13 net/mac80211/driver-ops.h | 12 ++---
14 net/mac80211/trace.h | 22 +++++----
15 net/wireless/nl80211.c | 97 +++++++++++++++++++++++++--------------
16 net/wireless/rdev-ops.h | 12 ++---
17 net/wireless/trace.h | 24 ++++++----
18 8 files changed, 122 insertions(+), 77 deletions(-)
19
20diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
21index 110e555..835735f 100644
22--- a/include/net/cfg80211.h
23+++ b/include/net/cfg80211.h
24@@ -4881,8 +4881,8 @@ struct cfg80211_ops {
25 struct wireless_dev *wdev,
26 struct mgmt_frame_regs *upd);
27
28- int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
29- int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
30+ int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant, int band);
31+ int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant, int band);
32
33 int (*sched_scan_start)(struct wiphy *wiphy,
34 struct net_device *dev,
35@@ -5831,8 +5831,9 @@ struct wiphy {
36
37 u8 max_num_pmkids;
38
39- u32 available_antennas_tx;
40- u32 available_antennas_rx;
41+ /* FIXME: This should move to per-radio data struct */
42+ u32 available_antennas_tx[NUM_NL80211_BANDS];
43+ u32 available_antennas_rx[NUM_NL80211_BANDS];
44
45 u32 probe_resp_offload;
46
47diff --git a/include/net/mac80211.h b/include/net/mac80211.h
48index 08c15a7..9471892 100644
49--- a/include/net/mac80211.h
50+++ b/include/net/mac80211.h
51@@ -4650,8 +4650,8 @@ struct ieee80211_ops {
52 void (*channel_switch)(struct ieee80211_hw *hw,
53 struct ieee80211_vif *vif,
54 struct ieee80211_channel_switch *ch_switch);
55- int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
56- int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
57+ int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant, int band);
58+ int (*get_antenna)(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant, int band);
59
60 int (*remain_on_channel)(struct ieee80211_hw *hw,
61 struct ieee80211_vif *vif,
62diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
63index 51a9b21..69c3e81 100644
64--- a/net/mac80211/cfg.c
65+++ b/net/mac80211/cfg.c
66@@ -4255,15 +4255,22 @@ ieee80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
67 ieee80211_configure_filter(local);
68 }
69
70-static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
71+static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant, int band)
72 {
73 struct ieee80211_local *local = wiphy_priv(wiphy);
74 int ret;
75
76- if (local->started)
77- return -EOPNOTSUPP;
78+ /* FIXME:
79+ * This flag should be moved to per-radio data struct; otherwise,
80+ * radio 1 or 2 will be blocked when radio 0 is started.
81+ * Temporarily disable this check until we have a better solution.
82+ * if (local->started)
83+ * return -EOPNOTSUPP;
84+ */
85+ wiphy_info(wiphy,
86+ "Temporarily disable local->started check during setting antenna\n");
87
88- ret = drv_set_antenna(local, tx_ant, rx_ant);
89+ ret = drv_set_antenna(local, tx_ant, rx_ant, band);
90 if (ret)
91 return ret;
92
93@@ -4271,11 +4278,11 @@ static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
94 return 0;
95 }
96
97-static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
98+static int ieee80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant, int band)
99 {
100 struct ieee80211_local *local = wiphy_priv(wiphy);
101
102- return drv_get_antenna(local, tx_ant, rx_ant);
103+ return drv_get_antenna(local, tx_ant, rx_ant, band);
104 }
105
106 static int ieee80211_set_rekey_data(struct wiphy *wiphy,
107diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
108index 4c0ac85..3bf8768 100644
109--- a/net/mac80211/driver-ops.h
110+++ b/net/mac80211/driver-ops.h
111@@ -762,26 +762,26 @@ static inline void drv_channel_switch(struct ieee80211_local *local,
112
113
114 static inline int drv_set_antenna(struct ieee80211_local *local,
115- u32 tx_ant, u32 rx_ant)
116+ u32 tx_ant, u32 rx_ant, int band)
117 {
118 int ret = -EOPNOTSUPP;
119 might_sleep();
120 lockdep_assert_wiphy(local->hw.wiphy);
121 if (local->ops->set_antenna)
122- ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant);
123- trace_drv_set_antenna(local, tx_ant, rx_ant, ret);
124+ ret = local->ops->set_antenna(&local->hw, tx_ant, rx_ant, band);
125+ trace_drv_set_antenna(local, tx_ant, rx_ant, band, ret);
126 return ret;
127 }
128
129 static inline int drv_get_antenna(struct ieee80211_local *local,
130- u32 *tx_ant, u32 *rx_ant)
131+ u32 *tx_ant, u32 *rx_ant, int band)
132 {
133 int ret = -EOPNOTSUPP;
134 might_sleep();
135 lockdep_assert_wiphy(local->hw.wiphy);
136 if (local->ops->get_antenna)
137- ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant);
138- trace_drv_get_antenna(local, *tx_ant, *rx_ant, ret);
139+ ret = local->ops->get_antenna(&local->hw, tx_ant, rx_ant, band);
140+ trace_drv_get_antenna(local, *tx_ant, *rx_ant, band, ret);
141 return ret;
142 }
143
144diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
145index 48fcc8f..84b5c35 100644
146--- a/net/mac80211/trace.h
147+++ b/net/mac80211/trace.h
148@@ -1263,14 +1263,16 @@ DEFINE_EVENT(chanswitch_evt, drv_channel_switch,
149 );
150
151 TRACE_EVENT(drv_set_antenna,
152- TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
153+ TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant,
154+ int band, int ret),
155
156- TP_ARGS(local, tx_ant, rx_ant, ret),
157+ TP_ARGS(local, tx_ant, rx_ant, band, ret),
158
159 TP_STRUCT__entry(
160 LOCAL_ENTRY
161 __field(u32, tx_ant)
162 __field(u32, rx_ant)
163+ __field(int, band)
164 __field(int, ret)
165 ),
166
167@@ -1278,24 +1280,27 @@ TRACE_EVENT(drv_set_antenna,
168 LOCAL_ASSIGN;
169 __entry->tx_ant = tx_ant;
170 __entry->rx_ant = rx_ant;
171+ __entry->band = band;
172 __entry->ret = ret;
173 ),
174
175 TP_printk(
176- LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
177- LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
178+ LOCAL_PR_FMT " tx_ant:%d rx_ant:%d band:%d ret:%d",
179+ LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant,
180+ __entry->band, __entry->ret
181 )
182 );
183
184 TRACE_EVENT(drv_get_antenna,
185- TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int ret),
186+ TP_PROTO(struct ieee80211_local *local, u32 tx_ant, u32 rx_ant, int band, int ret),
187
188- TP_ARGS(local, tx_ant, rx_ant, ret),
189+ TP_ARGS(local, tx_ant, rx_ant, band, ret),
190
191 TP_STRUCT__entry(
192 LOCAL_ENTRY
193 __field(u32, tx_ant)
194 __field(u32, rx_ant)
195+ __field(int, band)
196 __field(int, ret)
197 ),
198
199@@ -1303,12 +1308,13 @@ TRACE_EVENT(drv_get_antenna,
200 LOCAL_ASSIGN;
201 __entry->tx_ant = tx_ant;
202 __entry->rx_ant = rx_ant;
203+ __entry->rx_ant = band;
204 __entry->ret = ret;
205 ),
206
207 TP_printk(
208- LOCAL_PR_FMT " tx_ant:%d rx_ant:%d ret:%d",
209- LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->ret
210+ LOCAL_PR_FMT " tx_ant:%d rx_ant:%d band:%d ret:%d",
211+ LOCAL_PR_ARG, __entry->tx_ant, __entry->rx_ant, __entry->band, __entry->ret
212 )
213 );
214
215diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
216index e62116e..c38a5d0 100644
217--- a/net/wireless/nl80211.c
218+++ b/net/wireless/nl80211.c
219@@ -618,8 +618,6 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
220 [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 },
221 [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 },
222 [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 },
223- [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 },
224- [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 },
225 [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 },
226 [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG },
227 [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED },
228@@ -2626,10 +2624,12 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
229 nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE))
230 goto nla_put_failure;
231
232- if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
233- rdev->wiphy.available_antennas_tx) ||
234- nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
235- rdev->wiphy.available_antennas_rx))
236+ if (nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX,
237+ sizeof(rdev->wiphy.available_antennas_tx),
238+ rdev->wiphy.available_antennas_tx) ||
239+ nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX,
240+ sizeof(rdev->wiphy.available_antennas_rx),
241+ rdev->wiphy.available_antennas_rx))
242 goto nla_put_failure;
243
244 if ((rdev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) &&
245@@ -2637,22 +2637,29 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
246 rdev->wiphy.probe_resp_offload))
247 goto nla_put_failure;
248
249- if ((rdev->wiphy.available_antennas_tx ||
250- rdev->wiphy.available_antennas_rx) &&
251- rdev->ops->get_antenna) {
252- u32 tx_ant = 0, rx_ant = 0;
253+ if (rdev->ops->get_antenna) {
254+ u32 tx_ants[NUM_NL80211_BANDS], rx_ants[NUM_NL80211_BANDS];
255+ u32 tx_ant, rx_ant;
256 int res;
257
258- res = rdev_get_antenna(rdev, &tx_ant, &rx_ant);
259- if (!res) {
260- if (nla_put_u32(msg,
261- NL80211_ATTR_WIPHY_ANTENNA_TX,
262- tx_ant) ||
263- nla_put_u32(msg,
264- NL80211_ATTR_WIPHY_ANTENNA_RX,
265- rx_ant))
266- goto nla_put_failure;
267+ memset(tx_ants, 0, sizeof(tx_ants));
268+ memset(rx_ants, 0, sizeof(rx_ants));
269+ for (i = 0; i < NUM_NL80211_BANDS; i++) {
270+ if (!rdev->wiphy.available_antennas_tx[i] ||
271+ !rdev->wiphy.available_antennas_rx[i])
272+ continue;
273+
274+ res = rdev_get_antenna(rdev, &tx_ant, &rx_ant, i);
275+ if (!res) {
276+ tx_ants[i] = tx_ant;
277+ rx_ants[i] = rx_ant;
278+ }
279 }
280+ if (nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_TX,
281+ sizeof(tx_ants), tx_ants) ||
282+ nla_put(msg, NL80211_ATTR_WIPHY_ANTENNA_RX,
283+ sizeof(rx_ants), rx_ants))
284+ goto nla_put_failure;
285 }
286
287 state->split_start++;
288@@ -3784,32 +3791,52 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
289
290 if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] &&
291 info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) {
292- u32 tx_ant, rx_ant;
293+ u32 *tx_ants, *rx_ants;
294+ int bandid, tx_num, rx_num;
295
296- if ((!rdev->wiphy.available_antennas_tx &&
297- !rdev->wiphy.available_antennas_rx) ||
298- !rdev->ops->set_antenna) {
299+ if (!rdev->ops->set_antenna) {
300 result = -EOPNOTSUPP;
301 goto out;
302 }
303
304- tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
305- rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
306-
307- /* reject antenna configurations which don't match the
308- * available antenna masks, except for the "all" mask */
309- if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) ||
310- (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) {
311+ tx_num = nla_len(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]) / sizeof(u32);
312+ rx_num = nla_len(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) / sizeof(u32);
313+ if (tx_num != rx_num || tx_num != NUM_NL80211_BANDS) {
314 result = -EINVAL;
315 goto out;
316 }
317+ tx_ants = nla_data(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]);
318+ rx_ants = nla_data(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]);
319
320- tx_ant = tx_ant & rdev->wiphy.available_antennas_tx;
321- rx_ant = rx_ant & rdev->wiphy.available_antennas_rx;
322+ /* reject antenna configurations which don't match the
323+ * available antenna masks in wiphy, except for the "all" mask
324+ */
325+ for (bandid = 0; bandid < NUM_NL80211_BANDS; bandid++) {
326+ struct ieee80211_supported_band *sband = rdev->wiphy.bands[bandid];
327+ u32 tx_ant = tx_ants[bandid], rx_ant = rx_ants[bandid];
328+ u32 avail_ants_tx = rdev->wiphy.available_antennas_tx[bandid];
329+ u32 avail_ants_rx = rdev->wiphy.available_antennas_rx[bandid];
330
331- result = rdev_set_antenna(rdev, tx_ant, rx_ant);
332- if (result)
333- goto out;
334+ if (!sband || !tx_ant || !rx_ant)
335+ continue;
336+
337+ if (!avail_ants_tx && !avail_ants_rx) {
338+ result = -EOPNOTSUPP;
339+ goto out;
340+ }
341+
342+ if ((~tx_ant && (tx_ant & ~avail_ants_tx)) ||
343+ (~rx_ant && (rx_ant & ~avail_ants_rx))) {
344+ result = -EINVAL;
345+ goto out;
346+ }
347+
348+ tx_ant = tx_ant & avail_ants_tx;
349+ rx_ant = rx_ant & avail_ants_rx;
350+ result = rdev_set_antenna(rdev, tx_ant, rx_ant, bandid);
351+ if (result)
352+ goto out;
353+ }
354 }
355
356 changed = 0;
357diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h
358index 9b411db..bcd51fc 100644
359--- a/net/wireless/rdev-ops.h
360+++ b/net/wireless/rdev-ops.h
361@@ -857,26 +857,26 @@ rdev_update_mgmt_frame_registrations(struct cfg80211_registered_device *rdev,
362 }
363
364 static inline int rdev_set_antenna(struct cfg80211_registered_device *rdev,
365- u32 tx_ant, u32 rx_ant)
366+ u32 tx_ant, u32 rx_ant, int band)
367 {
368 int ret;
369- trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant);
370- ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant);
371+ trace_rdev_set_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
372+ ret = rdev->ops->set_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
373 trace_rdev_return_int(&rdev->wiphy, ret);
374 return ret;
375 }
376
377 static inline int rdev_get_antenna(struct cfg80211_registered_device *rdev,
378- u32 *tx_ant, u32 *rx_ant)
379+ u32 *tx_ant, u32 *rx_ant, int band)
380 {
381 int ret;
382 trace_rdev_get_antenna(&rdev->wiphy);
383- ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant);
384+ ret = rdev->ops->get_antenna(&rdev->wiphy, tx_ant, rx_ant, band);
385 if (ret)
386 trace_rdev_return_int(&rdev->wiphy, ret);
387 else
388 trace_rdev_return_int_tx_rx(&rdev->wiphy, ret, *tx_ant,
389- *rx_ant);
390+ *rx_ant, band);
391 return ret;
392 }
393
394diff --git a/net/wireless/trace.h b/net/wireless/trace.h
395index 6af432e..90ba38a 100644
396--- a/net/wireless/trace.h
397+++ b/net/wireless/trace.h
398@@ -1818,22 +1818,24 @@ TRACE_EVENT(rdev_update_mgmt_frame_registrations,
399 );
400
401 TRACE_EVENT(rdev_return_int_tx_rx,
402- TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx),
403- TP_ARGS(wiphy, ret, tx, rx),
404+ TP_PROTO(struct wiphy *wiphy, int ret, u32 tx, u32 rx, int band),
405+ TP_ARGS(wiphy, ret, tx, rx, band),
406 TP_STRUCT__entry(
407 WIPHY_ENTRY
408 __field(int, ret)
409 __field(u32, tx)
410 __field(u32, rx)
411+ __field(int, band)
412 ),
413 TP_fast_assign(
414 WIPHY_ASSIGN;
415 __entry->ret = ret;
416 __entry->tx = tx;
417 __entry->rx = rx;
418+ __entry->band = band;
419 ),
420- TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u",
421- WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx)
422+ TP_printk(WIPHY_PR_FMT ", returned %d, tx: %u, rx: %u band %d",
423+ WIPHY_PR_ARG, __entry->ret, __entry->tx, __entry->rx, __entry->band)
424 );
425
426 TRACE_EVENT(rdev_return_void_tx_rx,
427@@ -1860,25 +1862,27 @@ TRACE_EVENT(rdev_return_void_tx_rx,
428 );
429
430 DECLARE_EVENT_CLASS(tx_rx_evt,
431- TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
432- TP_ARGS(wiphy, tx, rx),
433+ TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx, int band),
434+ TP_ARGS(wiphy, rx, tx, band),
435 TP_STRUCT__entry(
436 WIPHY_ENTRY
437 __field(u32, tx)
438 __field(u32, rx)
439+ __field(int, band)
440 ),
441 TP_fast_assign(
442 WIPHY_ASSIGN;
443 __entry->tx = tx;
444 __entry->rx = rx;
445+ __entry->band = band;
446 ),
447- TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u ",
448- WIPHY_PR_ARG, __entry->tx, __entry->rx)
449+ TP_printk(WIPHY_PR_FMT ", tx: %u, rx: %u band: %d ",
450+ WIPHY_PR_ARG, __entry->tx, __entry->rx, __entry->band)
451 );
452
453 DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
454- TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx),
455- TP_ARGS(wiphy, tx, rx)
456+ TP_PROTO(struct wiphy *wiphy, u32 tx, u32 rx, int band),
457+ TP_ARGS(wiphy, rx, tx, band)
458 );
459
460 DECLARE_EVENT_CLASS(wiphy_netdev_id_evt,
461--
4622.18.0
463