Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7603/main.c
48526 views
1
// SPDX-License-Identifier: ISC
2
3
#include <linux/etherdevice.h>
4
#include <linux/platform_device.h>
5
#include <linux/pci.h>
6
#include <linux/module.h>
7
#include "mt7603.h"
8
#include "mac.h"
9
#include "eeprom.h"
10
11
static int
12
mt7603_start(struct ieee80211_hw *hw)
13
{
14
struct mt7603_dev *dev = hw->priv;
15
16
mt7603_mac_reset_counters(dev);
17
mt7603_mac_start(dev);
18
dev->mphy.survey_time = ktime_get_boottime();
19
set_bit(MT76_STATE_RUNNING, &dev->mphy.state);
20
mt7603_mac_work(&dev->mphy.mac_work.work);
21
22
return 0;
23
}
24
25
static void
26
mt7603_stop(struct ieee80211_hw *hw, bool suspend)
27
{
28
struct mt7603_dev *dev = hw->priv;
29
30
clear_bit(MT76_STATE_RUNNING, &dev->mphy.state);
31
cancel_delayed_work_sync(&dev->mphy.mac_work);
32
mt7603_mac_stop(dev);
33
}
34
35
static int
36
mt7603_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
37
{
38
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
39
struct mt7603_dev *dev = hw->priv;
40
struct mt76_txq *mtxq;
41
u8 bc_addr[ETH_ALEN];
42
int idx;
43
int ret = 0;
44
45
mutex_lock(&dev->mt76.mutex);
46
47
mvif->idx = __ffs64(~dev->mt76.vif_mask);
48
if (mvif->idx >= MT7603_MAX_INTERFACES) {
49
ret = -ENOSPC;
50
goto out;
51
}
52
53
mt76_wr(dev, MT_MAC_ADDR0(mvif->idx),
54
get_unaligned_le32(vif->addr));
55
mt76_wr(dev, MT_MAC_ADDR1(mvif->idx),
56
(get_unaligned_le16(vif->addr + 4) |
57
MT_MAC_ADDR1_VALID));
58
59
if (vif->type == NL80211_IFTYPE_AP) {
60
mt76_wr(dev, MT_BSSID0(mvif->idx),
61
get_unaligned_le32(vif->addr));
62
mt76_wr(dev, MT_BSSID1(mvif->idx),
63
(get_unaligned_le16(vif->addr + 4) |
64
MT_BSSID1_VALID));
65
}
66
67
idx = MT7603_WTBL_RESERVED - 1 - mvif->idx;
68
dev->mt76.vif_mask |= BIT_ULL(mvif->idx);
69
mvif->sta.wcid.idx = idx;
70
mvif->sta.vif = mvif;
71
mt76_wcid_init(&mvif->sta.wcid, 0);
72
73
eth_broadcast_addr(bc_addr);
74
mt7603_wtbl_init(dev, idx, mvif->idx, bc_addr);
75
76
mtxq = (struct mt76_txq *)vif->txq->drv_priv;
77
mtxq->wcid = idx;
78
rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
79
80
out:
81
mutex_unlock(&dev->mt76.mutex);
82
83
return ret;
84
}
85
86
static void
87
mt7603_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
88
{
89
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
90
struct mt7603_sta *msta = &mvif->sta;
91
struct mt7603_dev *dev = hw->priv;
92
int idx = msta->wcid.idx;
93
94
mt76_wr(dev, MT_MAC_ADDR0(mvif->idx), 0);
95
mt76_wr(dev, MT_MAC_ADDR1(mvif->idx), 0);
96
mt76_wr(dev, MT_BSSID0(mvif->idx), 0);
97
mt76_wr(dev, MT_BSSID1(mvif->idx), 0);
98
mt7603_beacon_set_timer(dev, mvif->idx, 0);
99
100
rcu_assign_pointer(dev->mt76.wcid[idx], NULL);
101
102
spin_lock_bh(&dev->mt76.sta_poll_lock);
103
if (!list_empty(&msta->wcid.poll_list))
104
list_del_init(&msta->wcid.poll_list);
105
spin_unlock_bh(&dev->mt76.sta_poll_lock);
106
107
mutex_lock(&dev->mt76.mutex);
108
dev->mt76.vif_mask &= ~BIT_ULL(mvif->idx);
109
mutex_unlock(&dev->mt76.mutex);
110
111
mt76_wcid_cleanup(&dev->mt76, &mvif->sta.wcid);
112
}
113
114
void mt7603_init_edcca(struct mt7603_dev *dev)
115
{
116
/* Set lower signal level to -65dBm */
117
mt76_rmw_field(dev, MT_RXTD(8), MT_RXTD_8_LOWER_SIGNAL, 0x23);
118
119
/* clear previous energy detect monitor results */
120
mt76_rr(dev, MT_MIB_STAT_ED);
121
122
if (dev->ed_monitor)
123
mt76_set(dev, MT_MIB_CTL, MT_MIB_CTL_ED_TIME);
124
else
125
mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_ED_TIME);
126
127
dev->ed_strict_mode = 0xff;
128
dev->ed_strong_signal = 0;
129
dev->ed_time = ktime_get_boottime();
130
131
mt7603_edcca_set_strict(dev, false);
132
}
133
134
int mt7603_set_channel(struct mt76_phy *mphy)
135
{
136
struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev, mt76);
137
struct cfg80211_chan_def *def = &mphy->chandef;
138
139
u8 *rssi_data = (u8 *)dev->mt76.eeprom.data;
140
int idx, ret;
141
u8 bw = MT_BW_20;
142
bool failed = false;
143
144
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
145
146
mt7603_beacon_set_timer(dev, -1, 0);
147
mt7603_mac_stop(dev);
148
149
if (def->width == NL80211_CHAN_WIDTH_40)
150
bw = MT_BW_40;
151
152
mt76_rmw_field(dev, MT_AGG_BWCR, MT_AGG_BWCR_BW, bw);
153
ret = mt7603_mcu_set_channel(dev);
154
if (ret) {
155
failed = true;
156
goto out;
157
}
158
159
if (def->chan->band == NL80211_BAND_5GHZ) {
160
idx = 1;
161
rssi_data += MT_EE_RSSI_OFFSET_5G;
162
} else {
163
idx = 0;
164
rssi_data += MT_EE_RSSI_OFFSET_2G;
165
}
166
167
memcpy(dev->rssi_offset, rssi_data, sizeof(dev->rssi_offset));
168
169
idx |= (def->chan -
170
mt76_hw(dev)->wiphy->bands[def->chan->band]->channels) << 1;
171
mt76_wr(dev, MT_WF_RMAC_CH_FREQ, idx);
172
mt7603_mac_set_timing(dev);
173
mt7603_mac_start(dev);
174
175
ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mphy.mac_work,
176
msecs_to_jiffies(MT7603_WATCHDOG_TIME));
177
178
/* reset channel stats */
179
mt76_clear(dev, MT_MIB_CTL, MT_MIB_CTL_READ_CLR_DIS);
180
mt76_set(dev, MT_MIB_CTL,
181
MT_MIB_CTL_CCA_NAV_TX | MT_MIB_CTL_PSCCA_TIME);
182
mt76_rr(dev, MT_MIB_STAT_CCA);
183
mt7603_cca_stats_reset(dev);
184
185
dev->mphy.survey_time = ktime_get_boottime();
186
187
mt7603_init_edcca(dev);
188
189
out:
190
if (!mphy->offchannel)
191
mt7603_beacon_set_timer(dev, -1, dev->mt76.beacon_int);
192
193
tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
194
195
if (failed)
196
mt7603_mac_work(&dev->mphy.mac_work.work);
197
198
return ret;
199
}
200
201
static int mt7603_set_sar_specs(struct ieee80211_hw *hw,
202
const struct cfg80211_sar_specs *sar)
203
{
204
struct mt7603_dev *dev = hw->priv;
205
struct mt76_phy *mphy = &dev->mphy;
206
int err;
207
208
if (!cfg80211_chandef_valid(&mphy->chandef))
209
return -EINVAL;
210
211
err = mt76_init_sar_power(hw, sar);
212
if (err)
213
return err;
214
215
return mt76_update_channel(mphy);
216
}
217
218
static int
219
mt7603_config(struct ieee80211_hw *hw, int radio_idx, u32 changed)
220
{
221
struct mt7603_dev *dev = hw->priv;
222
int ret = 0;
223
224
if (changed & (IEEE80211_CONF_CHANGE_CHANNEL |
225
IEEE80211_CONF_CHANGE_POWER))
226
ret = mt76_update_channel(&dev->mphy);
227
228
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
229
mutex_lock(&dev->mt76.mutex);
230
231
if (!(hw->conf.flags & IEEE80211_CONF_MONITOR))
232
dev->rxfilter |= MT_WF_RFCR_DROP_OTHER_UC;
233
else
234
dev->rxfilter &= ~MT_WF_RFCR_DROP_OTHER_UC;
235
236
mt76_wr(dev, MT_WF_RFCR, dev->rxfilter);
237
238
mutex_unlock(&dev->mt76.mutex);
239
}
240
241
return ret;
242
}
243
244
static void
245
mt7603_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags,
246
unsigned int *total_flags, u64 multicast)
247
{
248
struct mt7603_dev *dev = hw->priv;
249
u32 flags = 0;
250
251
#define MT76_FILTER(_flag, _hw) do { \
252
flags |= *total_flags & FIF_##_flag; \
253
dev->rxfilter &= ~(_hw); \
254
dev->rxfilter |= !(flags & FIF_##_flag) * (_hw); \
255
} while (0)
256
257
dev->rxfilter &= ~(MT_WF_RFCR_DROP_OTHER_BSS |
258
MT_WF_RFCR_DROP_OTHER_BEACON |
259
MT_WF_RFCR_DROP_FRAME_REPORT |
260
MT_WF_RFCR_DROP_PROBEREQ |
261
MT_WF_RFCR_DROP_MCAST_FILTERED |
262
MT_WF_RFCR_DROP_MCAST |
263
MT_WF_RFCR_DROP_BCAST |
264
MT_WF_RFCR_DROP_DUPLICATE |
265
MT_WF_RFCR_DROP_A2_BSSID |
266
MT_WF_RFCR_DROP_UNWANTED_CTL |
267
MT_WF_RFCR_DROP_STBC_MULTI);
268
269
MT76_FILTER(OTHER_BSS, MT_WF_RFCR_DROP_OTHER_TIM |
270
MT_WF_RFCR_DROP_A3_MAC |
271
MT_WF_RFCR_DROP_A3_BSSID);
272
273
MT76_FILTER(FCSFAIL, MT_WF_RFCR_DROP_FCSFAIL);
274
275
MT76_FILTER(CONTROL, MT_WF_RFCR_DROP_CTS |
276
MT_WF_RFCR_DROP_RTS |
277
MT_WF_RFCR_DROP_CTL_RSV |
278
MT_WF_RFCR_DROP_NDPA);
279
280
*total_flags = flags;
281
mt76_wr(dev, MT_WF_RFCR, dev->rxfilter);
282
}
283
284
static void
285
mt7603_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
286
struct ieee80211_bss_conf *info, u64 changed)
287
{
288
struct mt7603_dev *dev = hw->priv;
289
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
290
291
mutex_lock(&dev->mt76.mutex);
292
293
if (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BSSID)) {
294
if (vif->cfg.assoc || vif->cfg.ibss_joined) {
295
mt76_wr(dev, MT_BSSID0(mvif->idx),
296
get_unaligned_le32(info->bssid));
297
mt76_wr(dev, MT_BSSID1(mvif->idx),
298
(get_unaligned_le16(info->bssid + 4) |
299
MT_BSSID1_VALID));
300
} else {
301
mt76_wr(dev, MT_BSSID0(mvif->idx), 0);
302
mt76_wr(dev, MT_BSSID1(mvif->idx), 0);
303
}
304
}
305
306
if (changed & BSS_CHANGED_ERP_SLOT) {
307
int slottime = info->use_short_slot ? 9 : 20;
308
309
if (slottime != dev->slottime) {
310
dev->slottime = slottime;
311
mt7603_mac_set_timing(dev);
312
}
313
}
314
315
if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON_INT)) {
316
int beacon_int = !!info->enable_beacon * info->beacon_int;
317
318
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
319
mt7603_beacon_set_timer(dev, mvif->idx, beacon_int);
320
tasklet_enable(&dev->mt76.pre_tbtt_tasklet);
321
}
322
323
mutex_unlock(&dev->mt76.mutex);
324
}
325
326
int
327
mt7603_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
328
struct ieee80211_sta *sta)
329
{
330
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
331
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
332
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
333
int idx;
334
int ret = 0;
335
336
idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7603_WTBL_STA - 1);
337
if (idx < 0)
338
return -ENOSPC;
339
340
INIT_LIST_HEAD(&msta->wcid.poll_list);
341
__skb_queue_head_init(&msta->psq);
342
msta->ps = ~0;
343
msta->smps = ~0;
344
msta->wcid.sta = 1;
345
msta->wcid.idx = idx;
346
msta->vif = mvif;
347
mt7603_wtbl_init(dev, idx, mvif->idx, sta->addr);
348
mt7603_wtbl_set_ps(dev, msta, false);
349
350
if (vif->type == NL80211_IFTYPE_AP)
351
set_bit(MT_WCID_FLAG_CHECK_PS, &msta->wcid.flags);
352
353
return ret;
354
}
355
356
int
357
mt7603_sta_event(struct mt76_dev *mdev, struct ieee80211_vif *vif,
358
struct ieee80211_sta *sta, enum mt76_sta_event ev)
359
{
360
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
361
362
if (ev == MT76_STA_EVENT_ASSOC) {
363
mutex_lock(&dev->mt76.mutex);
364
mt7603_wtbl_update_cap(dev, sta);
365
mutex_unlock(&dev->mt76.mutex);
366
}
367
368
return 0;
369
}
370
371
void
372
mt7603_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
373
struct ieee80211_sta *sta)
374
{
375
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
376
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
377
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
378
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
379
380
spin_lock_bh(&dev->ps_lock);
381
__skb_queue_purge(&msta->psq);
382
mt7603_filter_tx(dev, mvif->idx, wcid->idx, true);
383
spin_unlock_bh(&dev->ps_lock);
384
385
spin_lock_bh(&mdev->sta_poll_lock);
386
if (!list_empty(&msta->wcid.poll_list))
387
list_del_init(&msta->wcid.poll_list);
388
spin_unlock_bh(&mdev->sta_poll_lock);
389
390
mt7603_wtbl_clear(dev, wcid->idx);
391
}
392
393
static void
394
mt7603_ps_tx_list(struct mt7603_dev *dev, struct sk_buff_head *list)
395
{
396
struct sk_buff *skb;
397
398
while ((skb = __skb_dequeue(list)) != NULL) {
399
int qid = skb_get_queue_mapping(skb);
400
401
mt76_tx_queue_skb_raw(dev, dev->mphy.q_tx[qid], skb, 0);
402
}
403
}
404
405
void
406
mt7603_sta_ps(struct mt76_dev *mdev, struct ieee80211_sta *sta, bool ps)
407
{
408
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
409
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
410
struct sk_buff_head list;
411
412
mt76_stop_tx_queues(&dev->mphy, sta, true);
413
mt7603_wtbl_set_ps(dev, msta, ps);
414
if (ps)
415
return;
416
417
__skb_queue_head_init(&list);
418
419
spin_lock_bh(&dev->ps_lock);
420
skb_queue_splice_tail_init(&msta->psq, &list);
421
spin_unlock_bh(&dev->ps_lock);
422
423
mt7603_ps_tx_list(dev, &list);
424
}
425
426
static void
427
mt7603_ps_set_more_data(struct sk_buff *skb)
428
{
429
struct ieee80211_hdr *hdr;
430
431
hdr = (struct ieee80211_hdr *)&skb->data[MT_TXD_SIZE];
432
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
433
}
434
435
static void
436
mt7603_release_buffered_frames(struct ieee80211_hw *hw,
437
struct ieee80211_sta *sta,
438
u16 tids, int nframes,
439
enum ieee80211_frame_release_type reason,
440
bool more_data)
441
{
442
struct mt7603_dev *dev = hw->priv;
443
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
444
struct sk_buff_head list;
445
struct sk_buff *skb, *tmp;
446
447
__skb_queue_head_init(&list);
448
449
mt7603_wtbl_set_ps(dev, msta, false);
450
451
spin_lock_bh(&dev->ps_lock);
452
skb_queue_walk_safe(&msta->psq, skb, tmp) {
453
if (!nframes)
454
break;
455
456
if (!(tids & BIT(skb->priority)))
457
continue;
458
459
skb_set_queue_mapping(skb, MT_TXQ_PSD);
460
__skb_unlink(skb, &msta->psq);
461
mt7603_ps_set_more_data(skb);
462
__skb_queue_tail(&list, skb);
463
nframes--;
464
}
465
spin_unlock_bh(&dev->ps_lock);
466
467
if (!skb_queue_empty(&list))
468
ieee80211_sta_eosp(sta);
469
470
mt7603_ps_tx_list(dev, &list);
471
472
if (nframes)
473
mt76_release_buffered_frames(hw, sta, tids, nframes, reason,
474
more_data);
475
}
476
477
static int
478
mt7603_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
479
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
480
struct ieee80211_key_conf *key)
481
{
482
struct mt7603_dev *dev = hw->priv;
483
struct mt7603_vif *mvif = (struct mt7603_vif *)vif->drv_priv;
484
struct mt7603_sta *msta = sta ? (struct mt7603_sta *)sta->drv_priv :
485
&mvif->sta;
486
struct mt76_wcid *wcid = &msta->wcid;
487
int idx = key->keyidx;
488
489
/* fall back to sw encryption for unsupported ciphers */
490
switch (key->cipher) {
491
case WLAN_CIPHER_SUITE_TKIP:
492
case WLAN_CIPHER_SUITE_CCMP:
493
break;
494
default:
495
return -EOPNOTSUPP;
496
}
497
498
/*
499
* The hardware does not support per-STA RX GTK, fall back
500
* to software mode for these.
501
*/
502
if ((vif->type == NL80211_IFTYPE_ADHOC ||
503
vif->type == NL80211_IFTYPE_MESH_POINT) &&
504
(key->cipher == WLAN_CIPHER_SUITE_TKIP ||
505
key->cipher == WLAN_CIPHER_SUITE_CCMP) &&
506
!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
507
return -EOPNOTSUPP;
508
509
if (cmd != SET_KEY) {
510
if (idx == wcid->hw_key_idx)
511
wcid->hw_key_idx = -1;
512
513
return 0;
514
}
515
516
key->hw_key_idx = wcid->idx;
517
wcid->hw_key_idx = idx;
518
mt76_wcid_key_setup(&dev->mt76, wcid, key);
519
520
return mt7603_wtbl_set_key(dev, wcid->idx, key);
521
}
522
523
static int
524
mt7603_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
525
unsigned int link_id, u16 queue,
526
const struct ieee80211_tx_queue_params *params)
527
{
528
struct mt7603_dev *dev = hw->priv;
529
u16 cw_min = (1 << 5) - 1;
530
u16 cw_max = (1 << 10) - 1;
531
u32 val;
532
533
queue = dev->mphy.q_tx[queue]->hw_idx;
534
535
if (params->cw_min)
536
cw_min = params->cw_min;
537
if (params->cw_max)
538
cw_max = params->cw_max;
539
540
mutex_lock(&dev->mt76.mutex);
541
mt7603_mac_stop(dev);
542
543
val = mt76_rr(dev, MT_WMM_TXOP(queue));
544
val &= ~(MT_WMM_TXOP_MASK << MT_WMM_TXOP_SHIFT(queue));
545
val |= params->txop << MT_WMM_TXOP_SHIFT(queue);
546
mt76_wr(dev, MT_WMM_TXOP(queue), val);
547
548
val = mt76_rr(dev, MT_WMM_AIFSN);
549
val &= ~(MT_WMM_AIFSN_MASK << MT_WMM_AIFSN_SHIFT(queue));
550
val |= params->aifs << MT_WMM_AIFSN_SHIFT(queue);
551
mt76_wr(dev, MT_WMM_AIFSN, val);
552
553
val = mt76_rr(dev, MT_WMM_CWMIN);
554
val &= ~(MT_WMM_CWMIN_MASK << MT_WMM_CWMIN_SHIFT(queue));
555
val |= cw_min << MT_WMM_CWMIN_SHIFT(queue);
556
mt76_wr(dev, MT_WMM_CWMIN, val);
557
558
val = mt76_rr(dev, MT_WMM_CWMAX(queue));
559
val &= ~(MT_WMM_CWMAX_MASK << MT_WMM_CWMAX_SHIFT(queue));
560
val |= cw_max << MT_WMM_CWMAX_SHIFT(queue);
561
mt76_wr(dev, MT_WMM_CWMAX(queue), val);
562
563
mt7603_mac_start(dev);
564
mutex_unlock(&dev->mt76.mutex);
565
566
return 0;
567
}
568
569
static void
570
mt7603_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
571
u32 queues, bool drop)
572
{
573
}
574
575
static int
576
mt7603_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
577
struct ieee80211_ampdu_params *params)
578
{
579
enum ieee80211_ampdu_mlme_action action = params->action;
580
struct mt7603_dev *dev = hw->priv;
581
struct ieee80211_sta *sta = params->sta;
582
struct ieee80211_txq *txq = sta->txq[params->tid];
583
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
584
u16 tid = params->tid;
585
u16 ssn = params->ssn;
586
u8 ba_size = params->buf_size;
587
struct mt76_txq *mtxq;
588
int ret = 0;
589
590
if (!txq)
591
return -EINVAL;
592
593
mtxq = (struct mt76_txq *)txq->drv_priv;
594
595
mutex_lock(&dev->mt76.mutex);
596
switch (action) {
597
case IEEE80211_AMPDU_RX_START:
598
mt76_rx_aggr_start(&dev->mt76, &msta->wcid, tid, ssn,
599
params->buf_size);
600
mt7603_mac_rx_ba_reset(dev, sta->addr, tid);
601
break;
602
case IEEE80211_AMPDU_RX_STOP:
603
mt76_rx_aggr_stop(&dev->mt76, &msta->wcid, tid);
604
break;
605
case IEEE80211_AMPDU_TX_OPERATIONAL:
606
mtxq->aggr = true;
607
mtxq->send_bar = false;
608
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, ba_size);
609
break;
610
case IEEE80211_AMPDU_TX_STOP_FLUSH:
611
case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
612
mtxq->aggr = false;
613
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
614
break;
615
case IEEE80211_AMPDU_TX_START:
616
mtxq->agg_ssn = IEEE80211_SN_TO_SEQ(ssn);
617
ret = IEEE80211_AMPDU_TX_START_IMMEDIATE;
618
break;
619
case IEEE80211_AMPDU_TX_STOP_CONT:
620
mtxq->aggr = false;
621
mt7603_mac_tx_ba_reset(dev, msta->wcid.idx, tid, -1);
622
ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
623
break;
624
}
625
mutex_unlock(&dev->mt76.mutex);
626
627
return ret;
628
}
629
630
static void
631
mt7603_sta_rate_tbl_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
632
struct ieee80211_sta *sta)
633
{
634
struct mt7603_dev *dev = hw->priv;
635
struct mt7603_sta *msta = (struct mt7603_sta *)sta->drv_priv;
636
struct ieee80211_sta_rates *sta_rates = rcu_dereference(sta->rates);
637
int i;
638
639
if (!sta_rates)
640
return;
641
642
spin_lock_bh(&dev->mt76.lock);
643
for (i = 0; i < ARRAY_SIZE(msta->rates); i++) {
644
msta->rates[i].idx = sta_rates->rate[i].idx;
645
msta->rates[i].count = sta_rates->rate[i].count;
646
msta->rates[i].flags = sta_rates->rate[i].flags;
647
648
if (msta->rates[i].idx < 0 || !msta->rates[i].count)
649
break;
650
}
651
msta->n_rates = i;
652
mt7603_wtbl_set_rates(dev, msta, NULL, msta->rates);
653
msta->rate_probe = false;
654
mt7603_wtbl_set_smps(dev, msta,
655
sta->deflink.smps_mode == IEEE80211_SMPS_DYNAMIC);
656
spin_unlock_bh(&dev->mt76.lock);
657
}
658
659
static void
660
mt7603_set_coverage_class(struct ieee80211_hw *hw, int radio_idx,
661
s16 coverage_class)
662
{
663
struct mt7603_dev *dev = hw->priv;
664
665
mutex_lock(&dev->mt76.mutex);
666
dev->coverage_class = max_t(s16, coverage_class, 0);
667
mt7603_mac_set_timing(dev);
668
mutex_unlock(&dev->mt76.mutex);
669
}
670
671
static void mt7603_tx(struct ieee80211_hw *hw,
672
struct ieee80211_tx_control *control,
673
struct sk_buff *skb)
674
{
675
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
676
struct ieee80211_vif *vif = info->control.vif;
677
struct mt7603_dev *dev = hw->priv;
678
struct mt76_wcid *wcid = &dev->global_sta.wcid;
679
680
if (control->sta) {
681
struct mt7603_sta *msta;
682
683
msta = (struct mt7603_sta *)control->sta->drv_priv;
684
wcid = &msta->wcid;
685
} else if (vif) {
686
struct mt7603_vif *mvif;
687
688
mvif = (struct mt7603_vif *)vif->drv_priv;
689
wcid = &mvif->sta.wcid;
690
}
691
692
mt76_tx(&dev->mphy, control->sta, wcid, skb);
693
}
694
695
const struct ieee80211_ops mt7603_ops = {
696
.add_chanctx = ieee80211_emulate_add_chanctx,
697
.remove_chanctx = ieee80211_emulate_remove_chanctx,
698
.change_chanctx = ieee80211_emulate_change_chanctx,
699
.switch_vif_chanctx = ieee80211_emulate_switch_vif_chanctx,
700
.tx = mt7603_tx,
701
.start = mt7603_start,
702
.stop = mt7603_stop,
703
.add_interface = mt7603_add_interface,
704
.remove_interface = mt7603_remove_interface,
705
.config = mt7603_config,
706
.configure_filter = mt7603_configure_filter,
707
.bss_info_changed = mt7603_bss_info_changed,
708
.sta_state = mt76_sta_state,
709
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
710
.set_key = mt7603_set_key,
711
.conf_tx = mt7603_conf_tx,
712
.sw_scan_start = mt76_sw_scan,
713
.sw_scan_complete = mt76_sw_scan_complete,
714
.flush = mt7603_flush,
715
.ampdu_action = mt7603_ampdu_action,
716
.get_txpower = mt76_get_txpower,
717
.wake_tx_queue = mt76_wake_tx_queue,
718
.sta_rate_tbl_update = mt7603_sta_rate_tbl_update,
719
.release_buffered_frames = mt7603_release_buffered_frames,
720
.set_coverage_class = mt7603_set_coverage_class,
721
.set_tim = mt76_set_tim,
722
.get_survey = mt76_get_survey,
723
.get_antenna = mt76_get_antenna,
724
.set_sar_specs = mt7603_set_sar_specs,
725
};
726
727
MODULE_DESCRIPTION("MediaTek MT7603E and MT76x8 wireless driver");
728
MODULE_LICENSE("Dual BSD/GPL");
729
730
static int __init mt7603_init(void)
731
{
732
int ret;
733
734
ret = platform_driver_register(&mt76_wmac_driver);
735
if (ret)
736
return ret;
737
738
#ifdef CONFIG_PCI
739
ret = pci_register_driver(&mt7603_pci_driver);
740
if (ret)
741
platform_driver_unregister(&mt76_wmac_driver);
742
#endif
743
return ret;
744
}
745
746
static void __exit mt7603_exit(void)
747
{
748
#ifdef CONFIG_PCI
749
pci_unregister_driver(&mt7603_pci_driver);
750
#endif
751
platform_driver_unregister(&mt76_wmac_driver);
752
}
753
754
module_init(mt7603_init);
755
module_exit(mt7603_exit);
756
757