hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/net/wireless/mediatek/mt76/mt76x0/main.c
....@@ -1,402 +1,66 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
34 * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
45 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2
8
- * as published by the Free Software Foundation
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 */
157
16
-#include "mt76x0.h"
17
-#include "mac.h"
188 #include <linux/etherdevice.h>
9
+#include "mt76x0.h"
1910
20
-static int mt76x0_start(struct ieee80211_hw *hw)
11
+static void
12
+mt76x0_set_channel(struct mt76x02_dev *dev, struct cfg80211_chan_def *chandef)
2113 {
22
- struct mt76x0_dev *dev = hw->priv;
23
- int ret;
24
-
25
- mutex_lock(&dev->mutex);
26
-
27
- ret = mt76x0_mac_start(dev);
28
- if (ret)
29
- goto out;
30
-
31
- ieee80211_queue_delayed_work(dev->mt76.hw, &dev->mac_work,
32
- MT_CALIBRATE_INTERVAL);
33
- ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
34
- MT_CALIBRATE_INTERVAL);
35
-out:
36
- mutex_unlock(&dev->mutex);
37
- return ret;
38
-}
39
-
40
-static void mt76x0_stop(struct ieee80211_hw *hw)
41
-{
42
- struct mt76x0_dev *dev = hw->priv;
43
-
44
- mutex_lock(&dev->mutex);
45
-
4614 cancel_delayed_work_sync(&dev->cal_work);
47
- cancel_delayed_work_sync(&dev->mac_work);
48
- mt76x0_mac_stop(dev);
15
+ mt76x02_pre_tbtt_enable(dev, false);
16
+ if (mt76_is_mmio(&dev->mt76))
17
+ tasklet_disable(&dev->dfs_pd.dfs_tasklet);
4918
50
- mutex_unlock(&dev->mutex);
51
-}
19
+ mt76_set_channel(&dev->mphy);
20
+ mt76x0_phy_set_channel(dev, chandef);
5221
22
+ mt76x02_mac_cc_reset(dev);
23
+ mt76x02_edcca_init(dev);
5324
54
-static int mt76x0_add_interface(struct ieee80211_hw *hw,
55
- struct ieee80211_vif *vif)
56
-{
57
- struct mt76x0_dev *dev = hw->priv;
58
- struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
59
- unsigned int idx;
60
-
61
- idx = ffs(~dev->vif_mask);
62
- if (!idx || idx > 8)
63
- return -ENOSPC;
64
-
65
- idx--;
66
- dev->vif_mask |= BIT(idx);
67
-
68
- mvif->idx = idx;
69
- mvif->group_wcid.idx = GROUP_WCID(idx);
70
- mvif->group_wcid.hw_key_idx = -1;
71
-
72
- return 0;
73
-}
74
-
75
-static void mt76x0_remove_interface(struct ieee80211_hw *hw,
76
- struct ieee80211_vif *vif)
77
-{
78
- struct mt76x0_dev *dev = hw->priv;
79
- struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
80
-
81
- dev->vif_mask &= ~BIT(mvif->idx);
82
-}
83
-
84
-static int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
85
-{
86
- struct mt76x0_dev *dev = hw->priv;
87
- int ret = 0;
88
-
89
- mutex_lock(&dev->mutex);
90
-
91
- if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
92
- if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
93
- dev->rxfilter |= MT_RX_FILTR_CFG_PROMISC;
94
- else
95
- dev->rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
96
-
97
- mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
25
+ if (mt76_is_mmio(&dev->mt76)) {
26
+ mt76x02_dfs_init_params(dev);
27
+ tasklet_enable(&dev->dfs_pd.dfs_tasklet);
9828 }
29
+ mt76x02_pre_tbtt_enable(dev, true);
30
+
31
+ mt76_txq_schedule_all(&dev->mphy);
32
+}
33
+
34
+int mt76x0_config(struct ieee80211_hw *hw, u32 changed)
35
+{
36
+ struct mt76x02_dev *dev = hw->priv;
37
+
38
+ mutex_lock(&dev->mt76.mutex);
9939
10040 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
10141 ieee80211_stop_queues(hw);
102
- ret = mt76x0_phy_set_channel(dev, &hw->conf.chandef);
42
+ mt76x0_set_channel(dev, &hw->conf.chandef);
10343 ieee80211_wake_queues(hw);
10444 }
10545
106
- mutex_unlock(&dev->mutex);
46
+ if (changed & IEEE80211_CONF_CHANGE_POWER) {
47
+ dev->txpower_conf = hw->conf.power_level * 2;
10748
108
- return ret;
109
-}
110
-
111
-static void
112
-mt76_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
113
- unsigned int *total_flags, u64 multicast)
114
-{
115
- struct mt76x0_dev *dev = hw->priv;
116
- u32 flags = 0;
117
-
118
-#define MT76_FILTER(_flag, _hw) do { \
119
- flags |= *total_flags & FIF_##_flag; \
120
- dev->rxfilter &= ~(_hw); \
121
- dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
122
- } while (0)
123
-
124
- mutex_lock(&dev->mutex);
125
-
126
- dev->rxfilter &= ~MT_RX_FILTR_CFG_OTHER_BSS;
127
-
128
- MT76_FILTER(FCSFAIL, MT_RX_FILTR_CFG_CRC_ERR);
129
- MT76_FILTER(PLCPFAIL, MT_RX_FILTR_CFG_PHY_ERR);
130
- MT76_FILTER(CONTROL, MT_RX_FILTR_CFG_ACK |
131
- MT_RX_FILTR_CFG_CTS |
132
- MT_RX_FILTR_CFG_CFEND |
133
- MT_RX_FILTR_CFG_CFACK |
134
- MT_RX_FILTR_CFG_BA |
135
- MT_RX_FILTR_CFG_CTRL_RSV);
136
- MT76_FILTER(PSPOLL, MT_RX_FILTR_CFG_PSPOLL);
137
-
138
- *total_flags = flags;
139
- mt76_wr(dev, MT_RX_FILTR_CFG, dev->rxfilter);
140
-
141
- mutex_unlock(&dev->mutex);
142
-}
143
-
144
-static void
145
-mt76x0_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
146
- struct ieee80211_bss_conf *info, u32 changed)
147
-{
148
- struct mt76x0_dev *dev = hw->priv;
149
-
150
- mutex_lock(&dev->mutex);
151
-
152
- if (changed & BSS_CHANGED_ASSOC)
153
- mt76x0_phy_con_cal_onoff(dev, info);
154
-
155
- if (changed & BSS_CHANGED_BSSID) {
156
- mt76x0_addr_wr(dev, MT_MAC_BSSID_DW0, info->bssid);
157
-
158
- /* Note: this is a hack because beacon_int is not changed
159
- * on leave nor is any more appropriate event generated.
160
- * rt2x00 doesn't seem to be bothered though.
161
- */
162
- if (is_zero_ether_addr(info->bssid))
163
- mt76x0_mac_config_tsf(dev, false, 0);
49
+ if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
50
+ mt76x0_phy_set_txpower(dev);
16451 }
16552
166
- if (changed & BSS_CHANGED_BASIC_RATES) {
167
- mt76_wr(dev, MT_LEGACY_BASIC_RATE, info->basic_rates);
168
- mt76_wr(dev, MT_HT_FBK_CFG0, 0x65432100);
169
- mt76_wr(dev, MT_HT_FBK_CFG1, 0xedcba980);
170
- mt76_wr(dev, MT_LG_FBK_CFG0, 0xedcba988);
171
- mt76_wr(dev, MT_LG_FBK_CFG1, 0x00002100);
53
+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
54
+ if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
55
+ dev->mt76.rxfilter |= MT_RX_FILTR_CFG_PROMISC;
56
+ else
57
+ dev->mt76.rxfilter &= ~MT_RX_FILTR_CFG_PROMISC;
58
+
59
+ mt76_wr(dev, MT_RX_FILTR_CFG, dev->mt76.rxfilter);
17260 }
17361
174
- if (changed & BSS_CHANGED_BEACON_INT)
175
- mt76x0_mac_config_tsf(dev, true, info->beacon_int);
176
-
177
- if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
178
- mt76x0_mac_set_protection(dev, info->use_cts_prot,
179
- info->ht_operation_mode);
180
-
181
- if (changed & BSS_CHANGED_ERP_PREAMBLE)
182
- mt76x0_mac_set_short_preamble(dev, info->use_short_preamble);
183
-
184
- if (changed & BSS_CHANGED_ERP_SLOT) {
185
- int slottime = info->use_short_slot ? 9 : 20;
186
-
187
- mt76_rmw_field(dev, MT_BKOFF_SLOT_CFG,
188
- MT_BKOFF_SLOT_CFG_SLOTTIME, slottime);
189
- }
190
-
191
- if (changed & BSS_CHANGED_ASSOC)
192
- mt76x0_phy_recalibrate_after_assoc(dev);
193
-
194
- mutex_unlock(&dev->mutex);
195
-}
196
-
197
-static int
198
-mt76x0_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
199
- struct ieee80211_sta *sta)
200
-{
201
- struct mt76x0_dev *dev = hw->priv;
202
- struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
203
- struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
204
- int ret = 0;
205
- int idx = 0;
206
-
207
- mutex_lock(&dev->mutex);
208
-
209
- idx = mt76_wcid_alloc(dev->wcid_mask, ARRAY_SIZE(dev->wcid));
210
- if (idx < 0) {
211
- ret = -ENOSPC;
212
- goto out;
213
- }
214
-
215
- msta->wcid.idx = idx;
216
- msta->wcid.hw_key_idx = -1;
217
- mt76x0_mac_wcid_setup(dev, idx, mvif->idx, sta->addr);
218
- mt76_clear(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx));
219
- rcu_assign_pointer(dev->wcid[idx], &msta->wcid);
220
- mt76x0_mac_set_ampdu_factor(dev);
221
-
222
-out:
223
- mutex_unlock(&dev->mutex);
224
-
225
- return ret;
226
-}
227
-
228
-static int
229
-mt76x0_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
230
- struct ieee80211_sta *sta)
231
-{
232
- struct mt76x0_dev *dev = hw->priv;
233
- struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
234
- int idx = msta->wcid.idx;
235
-
236
- mutex_lock(&dev->mutex);
237
- rcu_assign_pointer(dev->wcid[idx], NULL);
238
- mt76_set(dev, MT_WCID_DROP(idx), MT_WCID_DROP_MASK(idx));
239
- dev->wcid_mask[idx / BITS_PER_LONG] &= ~BIT(idx % BITS_PER_LONG);
240
- mt76x0_mac_wcid_setup(dev, idx, 0, NULL);
241
- mt76x0_mac_set_ampdu_factor(dev);
242
- mutex_unlock(&dev->mutex);
62
+ mutex_unlock(&dev->mt76.mutex);
24363
24464 return 0;
24565 }
246
-
247
-static void
248
-mt76x0_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
249
- enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
250
-{
251
-}
252
-
253
-static void
254
-mt76x0_sw_scan(struct ieee80211_hw *hw,
255
- struct ieee80211_vif *vif,
256
- const u8 *mac_addr)
257
-{
258
- struct mt76x0_dev *dev = hw->priv;
259
-
260
- cancel_delayed_work_sync(&dev->cal_work);
261
- mt76x0_agc_save(dev);
262
- set_bit(MT76_SCANNING, &dev->mt76.state);
263
-}
264
-
265
-static void
266
-mt76x0_sw_scan_complete(struct ieee80211_hw *hw,
267
- struct ieee80211_vif *vif)
268
-{
269
- struct mt76x0_dev *dev = hw->priv;
270
-
271
- mt76x0_agc_restore(dev);
272
- clear_bit(MT76_SCANNING, &dev->mt76.state);
273
-
274
- ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
275
- MT_CALIBRATE_INTERVAL);
276
-}
277
-
278
-static int
279
-mt76x0_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
280
- struct ieee80211_vif *vif, struct ieee80211_sta *sta,
281
- struct ieee80211_key_conf *key)
282
-{
283
- struct mt76x0_dev *dev = hw->priv;
284
- struct mt76_vif *mvif = (struct mt76_vif *) vif->drv_priv;
285
- struct mt76_sta *msta = sta ? (struct mt76_sta *) sta->drv_priv : NULL;
286
- struct mt76_wcid *wcid = msta ? &msta->wcid : &mvif->group_wcid;
287
- int idx = key->keyidx;
288
- int ret;
289
-
290
- if (cmd == SET_KEY) {
291
- key->hw_key_idx = wcid->idx;
292
- wcid->hw_key_idx = idx;
293
- } else {
294
- if (idx == wcid->hw_key_idx)
295
- wcid->hw_key_idx = -1;
296
-
297
- key = NULL;
298
- }
299
-
300
- if (!msta) {
301
- if (key || wcid->hw_key_idx == idx) {
302
- ret = mt76x0_mac_wcid_set_key(dev, wcid->idx, key);
303
- if (ret)
304
- return ret;
305
- }
306
-
307
- return mt76x0_mac_shared_key_setup(dev, mvif->idx, idx, key);
308
- }
309
-
310
- return mt76x0_mac_wcid_set_key(dev, msta->wcid.idx, key);
311
-}
312
-
313
-static int mt76x0_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
314
-{
315
- struct mt76x0_dev *dev = hw->priv;
316
-
317
- mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, value);
318
-
319
- return 0;
320
-}
321
-
322
-static int
323
-mt76_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
324
- struct ieee80211_ampdu_params *params)
325
-{
326
- struct mt76x0_dev *dev = hw->priv;
327
- struct ieee80211_sta *sta = params->sta;
328
- enum ieee80211_ampdu_mlme_action action = params->action;
329
- u16 tid = params->tid;
330
- u16 *ssn = &params->ssn;
331
- struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
332
-
333
- WARN_ON(msta->wcid.idx > N_WCIDS);
334
-
335
- switch (action) {
336
- case IEEE80211_AMPDU_RX_START:
337
- mt76_set(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
338
- break;
339
- case IEEE80211_AMPDU_RX_STOP:
340
- mt76_clear(dev, MT_WCID_ADDR(msta->wcid.idx) + 4, BIT(16 + tid));
341
- break;
342
- case IEEE80211_AMPDU_TX_OPERATIONAL:
343
- ieee80211_send_bar(vif, sta->addr, tid, msta->agg_ssn[tid]);
344
- break;
345
- case IEEE80211_AMPDU_TX_STOP_FLUSH:
346
- case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
347
- break;
348
- case IEEE80211_AMPDU_TX_START:
349
- msta->agg_ssn[tid] = *ssn << 4;
350
- ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
351
- break;
352
- case IEEE80211_AMPDU_TX_STOP_CONT:
353
- ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
354
- break;
355
- }
356
-
357
- return 0;
358
-}
359
-
360
-static void
361
-mt76_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
362
- struct ieee80211_sta *sta)
363
-{
364
- struct mt76x0_dev *dev = hw->priv;
365
- struct mt76_sta *msta = (struct mt76_sta *) sta->drv_priv;
366
- struct ieee80211_sta_rates *rates;
367
- struct ieee80211_tx_rate rate = {};
368
-
369
- rcu_read_lock();
370
- rates = rcu_dereference(sta->rates);
371
-
372
- if (!rates)
373
- goto out;
374
-
375
- rate.idx = rates->rate[0].idx;
376
- rate.flags = rates->rate[0].flags;
377
- mt76x0_mac_wcid_set_rate(dev, &msta->wcid, &rate);
378
-
379
-out:
380
- rcu_read_unlock();
381
-}
382
-
383
-const struct ieee80211_ops mt76x0_ops = {
384
- .tx = mt76x0_tx,
385
- .start = mt76x0_start,
386
- .stop = mt76x0_stop,
387
- .add_interface = mt76x0_add_interface,
388
- .remove_interface = mt76x0_remove_interface,
389
- .config = mt76x0_config,
390
- .configure_filter = mt76_configure_filter,
391
- .bss_info_changed = mt76x0_bss_info_changed,
392
- .sta_add = mt76x0_sta_add,
393
- .sta_remove = mt76x0_sta_remove,
394
- .sta_notify = mt76x0_sta_notify,
395
- .set_key = mt76x0_set_key,
396
- .conf_tx = mt76x0_conf_tx,
397
- .sw_scan_start = mt76x0_sw_scan,
398
- .sw_scan_complete = mt76x0_sw_scan_complete,
399
- .ampdu_action = mt76_ampdu_action,
400
- .sta_rate_tbl_update = mt76_sta_rate_tbl_update,
401
- .set_rts_threshold = mt76x0_set_rts_threshold,
402
-};
66
+EXPORT_SYMBOL_GPL(mt76x0_config);