Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt7603/init.c
48525 views
1
// SPDX-License-Identifier: ISC
2
3
#include <linux/etherdevice.h>
4
#include "mt7603.h"
5
#include "mac.h"
6
#include "eeprom.h"
7
8
const struct mt76_driver_ops mt7603_drv_ops = {
9
.txwi_size = MT_TXD_SIZE,
10
.drv_flags = MT_DRV_SW_RX_AIRTIME,
11
.survey_flags = SURVEY_INFO_TIME_TX,
12
.tx_prepare_skb = mt7603_tx_prepare_skb,
13
.tx_complete_skb = mt7603_tx_complete_skb,
14
.rx_skb = mt7603_queue_rx_skb,
15
.rx_poll_complete = mt7603_rx_poll_complete,
16
.sta_ps = mt7603_sta_ps,
17
.sta_add = mt7603_sta_add,
18
.sta_event = mt7603_sta_event,
19
.sta_remove = mt7603_sta_remove,
20
.update_survey = mt7603_update_channel,
21
.set_channel = mt7603_set_channel,
22
};
23
24
static void
25
mt7603_set_tmac_template(struct mt7603_dev *dev)
26
{
27
u32 desc[5] = {
28
[1] = FIELD_PREP(MT_TXD3_REM_TX_COUNT, 0xf),
29
[3] = MT_TXD5_SW_POWER_MGMT
30
};
31
u32 addr;
32
int i;
33
34
addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR);
35
addr += MT_CLIENT_TMAC_INFO_TEMPLATE;
36
for (i = 0; i < ARRAY_SIZE(desc); i++)
37
mt76_wr(dev, addr + 4 * i, desc[i]);
38
}
39
40
static void
41
mt7603_dma_sched_init(struct mt7603_dev *dev)
42
{
43
int page_size = 128;
44
int page_count;
45
int max_len = 1792;
46
int max_amsdu_pages = 4096 / page_size;
47
int max_mcu_len = 4096;
48
int max_beacon_len = 512 * 4 + max_len;
49
int max_mcast_pages = 4 * max_len / page_size;
50
int reserved_count = 0;
51
int beacon_pages;
52
int mcu_pages;
53
int i;
54
55
page_count = mt76_get_field(dev, MT_PSE_FC_P0,
56
MT_PSE_FC_P0_MAX_QUOTA);
57
beacon_pages = 4 * (max_beacon_len / page_size);
58
mcu_pages = max_mcu_len / page_size;
59
60
mt76_wr(dev, MT_PSE_FRP,
61
FIELD_PREP(MT_PSE_FRP_P0, 7) |
62
FIELD_PREP(MT_PSE_FRP_P1, 6) |
63
FIELD_PREP(MT_PSE_FRP_P2_RQ2, 4));
64
65
mt76_wr(dev, MT_HIGH_PRIORITY_1, 0x55555553);
66
mt76_wr(dev, MT_HIGH_PRIORITY_2, 0x78555555);
67
68
mt76_wr(dev, MT_QUEUE_PRIORITY_1, 0x2b1a096e);
69
mt76_wr(dev, MT_QUEUE_PRIORITY_2, 0x785f4d3c);
70
71
mt76_wr(dev, MT_PRIORITY_MASK, 0xffffffff);
72
73
mt76_wr(dev, MT_SCH_1, page_count | (2 << 28));
74
mt76_wr(dev, MT_SCH_2, max_amsdu_pages);
75
76
for (i = 0; i <= 4; i++)
77
mt76_wr(dev, MT_PAGE_COUNT(i), max_amsdu_pages);
78
reserved_count += 5 * max_amsdu_pages;
79
80
mt76_wr(dev, MT_PAGE_COUNT(5), mcu_pages);
81
reserved_count += mcu_pages;
82
83
mt76_wr(dev, MT_PAGE_COUNT(7), beacon_pages);
84
reserved_count += beacon_pages;
85
86
mt76_wr(dev, MT_PAGE_COUNT(8), max_mcast_pages);
87
reserved_count += max_mcast_pages;
88
89
if (is_mt7603(dev))
90
reserved_count = 0;
91
92
mt76_wr(dev, MT_RSV_MAX_THRESH, page_count - reserved_count);
93
94
if (is_mt7603(dev) && mt76xx_rev(dev) >= MT7603_REV_E2) {
95
mt76_wr(dev, MT_GROUP_THRESH(0),
96
page_count - beacon_pages - mcu_pages);
97
mt76_wr(dev, MT_GROUP_THRESH(1), beacon_pages);
98
mt76_wr(dev, MT_BMAP_0, 0x0080ff5f);
99
mt76_wr(dev, MT_GROUP_THRESH(2), mcu_pages);
100
mt76_wr(dev, MT_BMAP_1, 0x00000020);
101
} else {
102
mt76_wr(dev, MT_GROUP_THRESH(0), page_count);
103
mt76_wr(dev, MT_BMAP_0, 0xffff);
104
}
105
106
mt76_wr(dev, MT_SCH_4, 0);
107
108
for (i = 0; i <= 15; i++)
109
mt76_wr(dev, MT_TXTIME_THRESH(i), 0xfffff);
110
111
mt76_set(dev, MT_SCH_4, BIT(6));
112
}
113
114
static void
115
mt7603_phy_init(struct mt7603_dev *dev)
116
{
117
int rx_chains = dev->mphy.antenna_mask;
118
int tx_chains = hweight8(rx_chains) - 1;
119
120
mt76_rmw(dev, MT_WF_RMAC_RMCR,
121
(MT_WF_RMAC_RMCR_SMPS_MODE |
122
MT_WF_RMAC_RMCR_RX_STREAMS),
123
(FIELD_PREP(MT_WF_RMAC_RMCR_SMPS_MODE, 3) |
124
FIELD_PREP(MT_WF_RMAC_RMCR_RX_STREAMS, rx_chains)));
125
126
mt76_rmw_field(dev, MT_TMAC_TCR, MT_TMAC_TCR_TX_STREAMS,
127
tx_chains);
128
129
dev->agc0 = mt76_rr(dev, MT_AGC(0));
130
dev->agc3 = mt76_rr(dev, MT_AGC(3));
131
}
132
133
static void
134
mt7603_mac_init(struct mt7603_dev *dev)
135
{
136
u8 bc_addr[ETH_ALEN];
137
u32 addr;
138
int i;
139
140
mt76_wr(dev, MT_AGG_BA_SIZE_LIMIT_0,
141
(MT_AGG_SIZE_LIMIT(0) << 0 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
142
(MT_AGG_SIZE_LIMIT(1) << 1 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
143
(MT_AGG_SIZE_LIMIT(2) << 2 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
144
(MT_AGG_SIZE_LIMIT(3) << 3 * MT_AGG_BA_SIZE_LIMIT_SHIFT));
145
146
mt76_wr(dev, MT_AGG_BA_SIZE_LIMIT_1,
147
(MT_AGG_SIZE_LIMIT(4) << 0 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
148
(MT_AGG_SIZE_LIMIT(5) << 1 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
149
(MT_AGG_SIZE_LIMIT(6) << 2 * MT_AGG_BA_SIZE_LIMIT_SHIFT) |
150
(MT_AGG_SIZE_LIMIT(7) << 3 * MT_AGG_BA_SIZE_LIMIT_SHIFT));
151
152
mt76_wr(dev, MT_AGG_LIMIT,
153
FIELD_PREP(MT_AGG_LIMIT_AC(0), 24) |
154
FIELD_PREP(MT_AGG_LIMIT_AC(1), 24) |
155
FIELD_PREP(MT_AGG_LIMIT_AC(2), 24) |
156
FIELD_PREP(MT_AGG_LIMIT_AC(3), 24));
157
158
mt76_wr(dev, MT_AGG_LIMIT_1,
159
FIELD_PREP(MT_AGG_LIMIT_AC(0), 24) |
160
FIELD_PREP(MT_AGG_LIMIT_AC(1), 24) |
161
FIELD_PREP(MT_AGG_LIMIT_AC(2), 24) |
162
FIELD_PREP(MT_AGG_LIMIT_AC(3), 24));
163
164
mt76_wr(dev, MT_AGG_CONTROL,
165
FIELD_PREP(MT_AGG_CONTROL_BAR_RATE, 0x4b) |
166
FIELD_PREP(MT_AGG_CONTROL_CFEND_RATE, 0x69) |
167
MT_AGG_CONTROL_NO_BA_AR_RULE);
168
169
mt76_wr(dev, MT_AGG_RETRY_CONTROL,
170
FIELD_PREP(MT_AGG_RETRY_CONTROL_BAR_LIMIT, 1) |
171
FIELD_PREP(MT_AGG_RETRY_CONTROL_RTS_LIMIT, 15));
172
173
mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP |
174
FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 4096));
175
176
mt76_rmw(dev, MT_DMA_VCFR0, BIT(0), BIT(13));
177
mt76_rmw(dev, MT_DMA_TMCFR0, BIT(0) | BIT(1), BIT(13));
178
179
mt76_clear(dev, MT_WF_RMAC_TMR_PA, BIT(31));
180
181
mt76_set(dev, MT_WF_RMACDR, MT_WF_RMACDR_MAXLEN_20BIT);
182
mt76_rmw(dev, MT_WF_RMAC_MAXMINLEN, 0xffffff, 0x19000);
183
184
mt76_wr(dev, MT_WF_RFCR1, 0);
185
186
mt76_set(dev, MT_TMAC_TCR, MT_TMAC_TCR_RX_RIFS_MODE);
187
188
if (is_mt7628(dev)) {
189
mt76_set(dev, MT_TMAC_TCR,
190
MT_TMAC_TCR_TXOP_BURST_STOP | BIT(1) | BIT(0));
191
mt76_set(dev, MT_TXREQ, BIT(27));
192
mt76_set(dev, MT_AGG_TMP, GENMASK(4, 2));
193
}
194
195
mt7603_set_tmac_template(dev);
196
197
/* Enable RX group to HIF */
198
addr = mt7603_reg_map(dev, MT_CLIENT_BASE_PHYS_ADDR);
199
mt76_set(dev, addr + MT_CLIENT_RXINF, MT_CLIENT_RXINF_RXSH_GROUPS);
200
201
/* Enable RX group to MCU */
202
mt76_set(dev, MT_DMA_DCR1, GENMASK(13, 11));
203
204
mt76_rmw_field(dev, MT_AGG_PCR_RTS, MT_AGG_PCR_RTS_PKT_THR, 3);
205
mt76_set(dev, MT_TMAC_PCR, MT_TMAC_PCR_SPE_EN);
206
207
/* include preamble detection in CCA trigger signal */
208
mt76_rmw_field(dev, MT_TXREQ, MT_TXREQ_CCA_SRC_SEL, 2);
209
210
mt76_wr(dev, MT_RXREQ, 4);
211
212
/* Configure all rx packets to HIF */
213
mt76_wr(dev, MT_DMA_RCFR0, 0xc0000000);
214
215
/* Configure MCU txs selection with aggregation */
216
mt76_wr(dev, MT_DMA_TCFR0,
217
FIELD_PREP(MT_DMA_TCFR_TXS_AGGR_TIMEOUT, 1) | /* 32 us */
218
MT_DMA_TCFR_TXS_AGGR_COUNT);
219
220
/* Configure HIF txs selection with aggregation */
221
mt76_wr(dev, MT_DMA_TCFR1,
222
FIELD_PREP(MT_DMA_TCFR_TXS_AGGR_TIMEOUT, 1) | /* 32 us */
223
MT_DMA_TCFR_TXS_AGGR_COUNT | /* Maximum count */
224
MT_DMA_TCFR_TXS_BIT_MAP);
225
226
mt76_wr(dev, MT_MCU_PCIE_REMAP_1, MT_PSE_WTBL_2_PHYS_ADDR);
227
228
for (i = 0; i < MT7603_WTBL_SIZE; i++)
229
mt7603_wtbl_clear(dev, i);
230
231
eth_broadcast_addr(bc_addr);
232
mt7603_wtbl_init(dev, MT7603_WTBL_RESERVED, -1, bc_addr);
233
dev->global_sta.wcid.idx = MT7603_WTBL_RESERVED;
234
rcu_assign_pointer(dev->mt76.wcid[MT7603_WTBL_RESERVED],
235
&dev->global_sta.wcid);
236
237
mt76_rmw_field(dev, MT_LPON_BTEIR, MT_LPON_BTEIR_MBSS_MODE, 2);
238
mt76_rmw_field(dev, MT_WF_RMACDR, MT_WF_RMACDR_MBSSID_MASK, 2);
239
240
mt76_wr(dev, MT_AGG_ARUCR,
241
FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7) |
242
FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 2) |
243
FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), 2) |
244
FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), 2) |
245
FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), 1) |
246
FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), 1) |
247
FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), 1) |
248
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), 1));
249
250
mt76_wr(dev, MT_AGG_ARDCR,
251
FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), MT7603_RATE_RETRY - 1) |
252
FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), MT7603_RATE_RETRY - 1) |
253
FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7603_RATE_RETRY - 1) |
254
FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7603_RATE_RETRY - 1) |
255
FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7603_RATE_RETRY - 1) |
256
FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), MT7603_RATE_RETRY - 1) |
257
FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), MT7603_RATE_RETRY - 1) |
258
FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7603_RATE_RETRY - 1));
259
260
mt76_wr(dev, MT_AGG_ARCR,
261
(FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) |
262
MT_AGG_ARCR_RATE_DOWN_RATIO_EN |
263
FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) |
264
FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4)));
265
266
mt76_set(dev, MT_WTBL_RMVTCR, MT_WTBL_RMVTCR_RX_MV_MODE);
267
268
mt76_clear(dev, MT_SEC_SCR, MT_SEC_SCR_MASK_ORDER);
269
mt76_clear(dev, MT_SEC_SCR, BIT(18));
270
271
/* Set secondary beacon time offsets */
272
for (i = 0; i <= 4; i++)
273
mt76_rmw_field(dev, MT_LPON_SBTOR(i), MT_LPON_SBTOR_TIME_OFFSET,
274
(i + 1) * (20 + 4096));
275
}
276
277
static int
278
mt7603_init_hardware(struct mt7603_dev *dev)
279
{
280
int i, ret;
281
282
mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
283
284
ret = mt7603_eeprom_init(dev);
285
if (ret < 0)
286
return ret;
287
288
ret = mt7603_dma_init(dev);
289
if (ret)
290
return ret;
291
292
mt76_wr(dev, MT_WPDMA_GLO_CFG, 0x52000850);
293
mt7603_mac_dma_start(dev);
294
dev->rxfilter = mt76_rr(dev, MT_WF_RFCR);
295
set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
296
297
for (i = 0; i < MT7603_WTBL_SIZE; i++) {
298
mt76_wr(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY | MT_PSE_RTA_WRITE |
299
FIELD_PREP(MT_PSE_RTA_TAG_ID, i));
300
mt76_poll(dev, MT_PSE_RTA, MT_PSE_RTA_BUSY, 0, 5000);
301
}
302
303
ret = mt7603_mcu_init(dev);
304
if (ret)
305
return ret;
306
307
mt7603_dma_sched_init(dev);
308
mt7603_mcu_set_eeprom(dev);
309
mt7603_phy_init(dev);
310
mt7603_mac_init(dev);
311
312
return 0;
313
}
314
315
static const struct ieee80211_iface_limit if_limits[] = {
316
{
317
.max = 1,
318
.types = BIT(NL80211_IFTYPE_ADHOC)
319
}, {
320
.max = MT7603_MAX_INTERFACES,
321
.types = BIT(NL80211_IFTYPE_STATION) |
322
#ifdef CONFIG_MAC80211_MESH
323
BIT(NL80211_IFTYPE_MESH_POINT) |
324
#endif
325
BIT(NL80211_IFTYPE_P2P_CLIENT) |
326
BIT(NL80211_IFTYPE_P2P_GO) |
327
BIT(NL80211_IFTYPE_AP)
328
},
329
};
330
331
static const struct ieee80211_iface_combination if_comb[] = {
332
{
333
.limits = if_limits,
334
.n_limits = ARRAY_SIZE(if_limits),
335
.max_interfaces = 4,
336
.num_different_channels = 1,
337
.beacon_int_infra_match = true,
338
}
339
};
340
341
static void mt7603_led_set_config(struct mt76_phy *mphy, u8 delay_on,
342
u8 delay_off)
343
{
344
struct mt7603_dev *dev = container_of(mphy->dev, struct mt7603_dev,
345
mt76);
346
u32 val, addr;
347
348
val = FIELD_PREP(MT_LED_STATUS_DURATION, 0xffff) |
349
FIELD_PREP(MT_LED_STATUS_OFF, delay_off) |
350
FIELD_PREP(MT_LED_STATUS_ON, delay_on);
351
352
addr = mt7603_reg_map(dev, MT_LED_STATUS_0(mphy->leds.pin));
353
mt76_wr(dev, addr, val);
354
addr = mt7603_reg_map(dev, MT_LED_STATUS_1(mphy->leds.pin));
355
mt76_wr(dev, addr, val);
356
357
val = MT_LED_CTRL_REPLAY(mphy->leds.pin) |
358
MT_LED_CTRL_KICK(mphy->leds.pin);
359
if (mphy->leds.al)
360
val |= MT_LED_CTRL_POLARITY(mphy->leds.pin);
361
addr = mt7603_reg_map(dev, MT_LED_CTRL);
362
mt76_wr(dev, addr, val);
363
}
364
365
static int mt7603_led_set_blink(struct led_classdev *led_cdev,
366
unsigned long *delay_on,
367
unsigned long *delay_off)
368
{
369
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
370
leds.cdev);
371
u8 delta_on, delta_off;
372
373
delta_off = max_t(u8, *delay_off / 10, 1);
374
delta_on = max_t(u8, *delay_on / 10, 1);
375
376
mt7603_led_set_config(mphy, delta_on, delta_off);
377
return 0;
378
}
379
380
static void mt7603_led_set_brightness(struct led_classdev *led_cdev,
381
enum led_brightness brightness)
382
{
383
struct mt76_phy *mphy = container_of(led_cdev, struct mt76_phy,
384
leds.cdev);
385
386
if (!brightness)
387
mt7603_led_set_config(mphy, 0, 0xff);
388
else
389
mt7603_led_set_config(mphy, 0xff, 0);
390
}
391
392
static u32 __mt7603_reg_addr(struct mt7603_dev *dev, u32 addr)
393
{
394
if (addr < 0x100000)
395
return addr;
396
397
return mt7603_reg_map(dev, addr);
398
}
399
400
static u32 mt7603_rr(struct mt76_dev *mdev, u32 offset)
401
{
402
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
403
u32 addr = __mt7603_reg_addr(dev, offset);
404
405
return dev->bus_ops->rr(mdev, addr);
406
}
407
408
static void mt7603_wr(struct mt76_dev *mdev, u32 offset, u32 val)
409
{
410
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
411
u32 addr = __mt7603_reg_addr(dev, offset);
412
413
dev->bus_ops->wr(mdev, addr, val);
414
}
415
416
static u32 mt7603_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
417
{
418
struct mt7603_dev *dev = container_of(mdev, struct mt7603_dev, mt76);
419
u32 addr = __mt7603_reg_addr(dev, offset);
420
421
return dev->bus_ops->rmw(mdev, addr, mask, val);
422
}
423
424
static void
425
mt7603_regd_notifier(struct wiphy *wiphy,
426
struct regulatory_request *request)
427
{
428
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
429
struct mt7603_dev *dev = hw->priv;
430
431
dev->mt76.region = request->dfs_region;
432
dev->ed_monitor = dev->ed_monitor_enabled &&
433
dev->mt76.region == NL80211_DFS_ETSI;
434
}
435
436
static int
437
mt7603_txpower_signed(int val)
438
{
439
bool sign = val & BIT(6);
440
441
if (!(val & BIT(7)))
442
return 0;
443
444
val &= GENMASK(5, 0);
445
if (!sign)
446
val = -val;
447
448
return val;
449
}
450
451
static void
452
mt7603_init_txpower(struct mt7603_dev *dev,
453
struct ieee80211_supported_band *sband)
454
{
455
struct ieee80211_channel *chan;
456
u8 *eeprom = (u8 *)dev->mt76.eeprom.data;
457
int target_power = eeprom[MT_EE_TX_POWER_0_START_2G + 2] & ~BIT(7);
458
u8 *rate_power = &eeprom[MT_EE_TX_POWER_CCK];
459
bool ext_pa = eeprom[MT_EE_NIC_CONF_0 + 1] & BIT(1);
460
u8 ext_pa_pwr;
461
int max_offset, cur_offset;
462
int i;
463
464
ext_pa_pwr = eeprom[MT_EE_TX_POWER_TSSI_OFF];
465
if (ext_pa && is_mt7603(dev) && ext_pa_pwr != 0 && ext_pa_pwr != 0xff)
466
target_power = ext_pa_pwr & ~BIT(7);
467
468
if (target_power & BIT(6))
469
target_power = -(target_power & GENMASK(5, 0));
470
471
max_offset = 0;
472
for (i = 0; i < 14; i++) {
473
cur_offset = mt7603_txpower_signed(rate_power[i]);
474
max_offset = max(max_offset, cur_offset);
475
}
476
477
target_power += max_offset;
478
479
dev->tx_power_limit = target_power;
480
dev->mphy.txpower_cur = target_power;
481
482
target_power = DIV_ROUND_UP(target_power, 2);
483
484
/* add 3 dBm for 2SS devices (combined output) */
485
if (dev->mphy.antenna_mask & BIT(1))
486
target_power += 3;
487
488
for (i = 0; i < sband->n_channels; i++) {
489
chan = &sband->channels[i];
490
chan->max_power = min_t(int, chan->max_reg_power, target_power);
491
chan->orig_mpwr = target_power;
492
}
493
}
494
495
int mt7603_register_device(struct mt7603_dev *dev)
496
{
497
struct mt76_bus_ops *bus_ops;
498
struct ieee80211_hw *hw = mt76_hw(dev);
499
struct wiphy *wiphy = hw->wiphy;
500
int ret;
501
502
dev->bus_ops = dev->mt76.bus;
503
bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops),
504
GFP_KERNEL);
505
if (!bus_ops)
506
return -ENOMEM;
507
508
bus_ops->rr = mt7603_rr;
509
bus_ops->wr = mt7603_wr;
510
bus_ops->rmw = mt7603_rmw;
511
dev->mt76.bus = bus_ops;
512
513
spin_lock_init(&dev->ps_lock);
514
515
INIT_DELAYED_WORK(&dev->mphy.mac_work, mt7603_mac_work);
516
tasklet_setup(&dev->mt76.pre_tbtt_tasklet, mt7603_pre_tbtt_tasklet);
517
518
dev->slottime = 9;
519
dev->sensitivity_limit = 28;
520
dev->dynamic_sensitivity = true;
521
522
ret = mt7603_init_hardware(dev);
523
if (ret)
524
return ret;
525
526
hw->queues = 4;
527
hw->max_rates = 3;
528
hw->max_report_rates = 7;
529
hw->max_rate_tries = 11;
530
hw->max_tx_fragments = 1;
531
532
hw->radiotap_timestamp.units_pos =
533
IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US;
534
535
hw->sta_data_size = sizeof(struct mt7603_sta);
536
hw->vif_data_size = sizeof(struct mt7603_vif);
537
538
wiphy->iface_combinations = if_comb;
539
wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
540
541
ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN);
542
ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
543
ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);
544
545
/* init led callbacks */
546
if (IS_ENABLED(CONFIG_MT76_LEDS)) {
547
dev->mphy.leds.cdev.brightness_set = mt7603_led_set_brightness;
548
dev->mphy.leds.cdev.blink_set = mt7603_led_set_blink;
549
}
550
551
wiphy->reg_notifier = mt7603_regd_notifier;
552
553
ret = mt76_register_device(&dev->mt76, true, mt76_rates,
554
ARRAY_SIZE(mt76_rates));
555
if (ret)
556
return ret;
557
558
mt7603_init_debugfs(dev);
559
mt7603_init_txpower(dev, &dev->mphy.sband_2g.sband);
560
561
return 0;
562
}
563
564
void mt7603_unregister_device(struct mt7603_dev *dev)
565
{
566
tasklet_disable(&dev->mt76.pre_tbtt_tasklet);
567
mt76_unregister_device(&dev->mt76);
568
mt7603_mcu_exit(dev);
569
mt7603_dma_cleanup(dev);
570
mt76_free_device(&dev->mt76);
571
}
572
573