Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/dev/mediatek/mt76/mt76_connac_mcu.c
48378 views
1
// SPDX-License-Identifier: ISC
2
/* Copyright (C) 2020 MediaTek Inc. */
3
4
#include <linux/firmware.h>
5
#include "mt76_connac2_mac.h"
6
#include "mt76_connac_mcu.h"
7
8
int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
9
{
10
struct {
11
__le32 option;
12
__le32 addr;
13
} req = {
14
.option = cpu_to_le32(option),
15
.addr = cpu_to_le32(addr),
16
};
17
18
return mt76_mcu_send_msg(dev, MCU_CMD(FW_START_REQ), &req,
19
sizeof(req), true);
20
}
21
EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
22
23
int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
24
{
25
u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
26
struct {
27
__le32 op;
28
} req = {
29
.op = cpu_to_le32(op),
30
};
31
32
return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_SEM_CONTROL),
33
&req, sizeof(req), true);
34
}
35
EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
36
37
int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
38
{
39
struct {
40
u8 check_crc;
41
u8 reserved[3];
42
} req = {
43
.check_crc = 0,
44
};
45
46
return mt76_mcu_send_msg(dev, MCU_CMD(PATCH_FINISH_REQ),
47
&req, sizeof(req), true);
48
}
49
EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
50
51
#define MCU_PATCH_ADDRESS 0x200000
52
53
int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
54
u32 mode)
55
{
56
struct {
57
__le32 addr;
58
__le32 len;
59
__le32 mode;
60
} req = {
61
.addr = cpu_to_le32(addr),
62
.len = cpu_to_le32(len),
63
.mode = cpu_to_le32(mode),
64
};
65
int cmd;
66
67
if ((!is_connac_v1(dev) && addr == MCU_PATCH_ADDRESS) ||
68
(is_mt7921(dev) && addr == 0x900000) ||
69
(is_mt7925(dev) && (addr == 0x900000 || addr == 0xe0002800)) ||
70
(is_mt799x(dev) && addr == 0x900000))
71
cmd = MCU_CMD(PATCH_START_REQ);
72
else
73
cmd = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
74
75
return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
76
}
77
EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
78
79
int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
80
{
81
int len, i, n_max_channels, n_2ch = 0, n_5ch = 0, n_6ch = 0;
82
struct mt76_connac_mcu_channel_domain {
83
u8 alpha2[4]; /* regulatory_request.alpha2 */
84
u8 bw_2g; /* BW_20_40M 0
85
* BW_20M 1
86
* BW_20_40_80M 2
87
* BW_20_40_80_160M 3
88
* BW_20_40_80_8080M 4
89
*/
90
u8 bw_5g;
91
u8 bw_6g;
92
u8 pad;
93
u8 n_2ch;
94
u8 n_5ch;
95
u8 n_6ch;
96
u8 pad2;
97
} __packed hdr = {
98
.bw_2g = 0,
99
.bw_5g = 3, /* BW_20_40_80_160M */
100
.bw_6g = 3,
101
};
102
struct mt76_connac_mcu_chan {
103
__le16 hw_value;
104
__le16 pad;
105
__le32 flags;
106
} __packed channel;
107
struct mt76_dev *dev = phy->dev;
108
struct ieee80211_channel *chan;
109
struct sk_buff *skb;
110
111
n_max_channels = phy->sband_2g.sband.n_channels +
112
phy->sband_5g.sband.n_channels +
113
phy->sband_6g.sband.n_channels;
114
len = sizeof(hdr) + n_max_channels * sizeof(channel);
115
116
skb = mt76_mcu_msg_alloc(dev, NULL, len);
117
if (!skb)
118
return -ENOMEM;
119
120
skb_reserve(skb, sizeof(hdr));
121
122
for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
123
chan = &phy->sband_2g.sband.channels[i];
124
if (chan->flags & IEEE80211_CHAN_DISABLED)
125
continue;
126
127
channel.hw_value = cpu_to_le16(chan->hw_value);
128
channel.flags = cpu_to_le32(chan->flags);
129
channel.pad = 0;
130
131
skb_put_data(skb, &channel, sizeof(channel));
132
n_2ch++;
133
}
134
for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
135
chan = &phy->sband_5g.sband.channels[i];
136
if (chan->flags & IEEE80211_CHAN_DISABLED)
137
continue;
138
139
channel.hw_value = cpu_to_le16(chan->hw_value);
140
channel.flags = cpu_to_le32(chan->flags);
141
channel.pad = 0;
142
143
skb_put_data(skb, &channel, sizeof(channel));
144
n_5ch++;
145
}
146
for (i = 0; i < phy->sband_6g.sband.n_channels; i++) {
147
chan = &phy->sband_6g.sband.channels[i];
148
if (chan->flags & IEEE80211_CHAN_DISABLED)
149
continue;
150
151
channel.hw_value = cpu_to_le16(chan->hw_value);
152
channel.flags = cpu_to_le32(chan->flags);
153
channel.pad = 0;
154
155
skb_put_data(skb, &channel, sizeof(channel));
156
n_6ch++;
157
}
158
159
BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
160
memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
161
hdr.n_2ch = n_2ch;
162
hdr.n_5ch = n_5ch;
163
hdr.n_6ch = n_6ch;
164
165
memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
166
167
return mt76_mcu_skb_send_msg(dev, skb, MCU_CE_CMD(SET_CHAN_DOMAIN),
168
false);
169
}
170
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
171
172
int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
173
bool hdr_trans)
174
{
175
struct {
176
u8 enable;
177
u8 band;
178
u8 rsv[2];
179
} __packed req_mac = {
180
.enable = enable,
181
.band = band,
182
};
183
184
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(MAC_INIT_CTRL), &req_mac,
185
sizeof(req_mac), true);
186
}
187
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
188
189
int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
190
{
191
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
192
struct {
193
u8 bss_idx;
194
u8 ps_state; /* 0: device awake
195
* 1: static power save
196
* 2: dynamic power saving
197
*/
198
} req = {
199
.bss_idx = mvif->idx,
200
.ps_state = vif->cfg.ps ? 2 : 0,
201
};
202
203
if (vif->type != NL80211_IFTYPE_STATION)
204
return -EOPNOTSUPP;
205
206
return mt76_mcu_send_msg(dev, MCU_CE_CMD(SET_PS_PROFILE),
207
&req, sizeof(req), false);
208
}
209
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
210
211
int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
212
{
213
struct {
214
u8 prot_idx;
215
u8 band;
216
u8 rsv[2];
217
__le32 len_thresh;
218
__le32 pkt_thresh;
219
} __packed req = {
220
.prot_idx = 1,
221
.band = band,
222
.len_thresh = cpu_to_le32(val),
223
.pkt_thresh = cpu_to_le32(0x2),
224
};
225
226
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PROTECT_CTRL), &req,
227
sizeof(req), true);
228
}
229
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
230
231
void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
232
struct ieee80211_vif *vif)
233
{
234
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
235
struct mt76_connac_beacon_loss_event *event = priv;
236
237
if (mvif->idx != event->bss_idx)
238
return;
239
240
if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
241
return;
242
243
ieee80211_beacon_loss(vif);
244
}
245
EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
246
247
struct tlv *
248
mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
249
void *sta_ntlv, void *sta_wtbl)
250
{
251
struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
252
struct tlv *sta_hdr = sta_wtbl;
253
struct tlv *ptlv, tlv = {
254
.tag = cpu_to_le16(tag),
255
.len = cpu_to_le16(len),
256
};
257
u16 ntlv;
258
259
ptlv = skb_put_zero(skb, len);
260
memcpy(ptlv, &tlv, sizeof(tlv));
261
262
ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
263
ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
264
265
if (sta_hdr) {
266
len += le16_to_cpu(sta_hdr->len);
267
sta_hdr->len = cpu_to_le16(len);
268
}
269
270
return ptlv;
271
}
272
EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
273
274
struct sk_buff *
275
__mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif_link *mvif,
276
struct mt76_wcid *wcid, int len)
277
{
278
struct sta_req_hdr hdr = {
279
.bss_idx = mvif->idx,
280
.muar_idx = wcid ? mvif->omac_idx : 0,
281
.is_tlv_append = 1,
282
};
283
struct sk_buff *skb;
284
285
if (wcid && !wcid->sta && !wcid->sta_disabled)
286
hdr.muar_idx = 0xe;
287
288
mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
289
&hdr.wlan_idx_hi);
290
skb = __mt76_mcu_msg_alloc(dev, NULL, len, len, GFP_ATOMIC);
291
if (!skb)
292
return ERR_PTR(-ENOMEM);
293
294
skb_put_data(skb, &hdr, sizeof(hdr));
295
296
return skb;
297
}
298
EXPORT_SYMBOL_GPL(__mt76_connac_mcu_alloc_sta_req);
299
300
struct wtbl_req_hdr *
301
mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
302
int cmd, void *sta_wtbl, struct sk_buff **skb)
303
{
304
struct tlv *sta_hdr = sta_wtbl;
305
struct wtbl_req_hdr hdr = {
306
.operation = cmd,
307
};
308
struct sk_buff *nskb = *skb;
309
310
mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
311
&hdr.wlan_idx_hi);
312
if (!nskb) {
313
nskb = mt76_mcu_msg_alloc(dev, NULL,
314
MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
315
if (!nskb)
316
return ERR_PTR(-ENOMEM);
317
318
*skb = nskb;
319
}
320
321
if (sta_hdr)
322
le16_add_cpu(&sta_hdr->len, sizeof(hdr));
323
324
return skb_put_data(nskb, &hdr, sizeof(hdr));
325
}
326
EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
327
328
void mt76_connac_mcu_bss_omac_tlv(struct sk_buff *skb,
329
struct ieee80211_vif *vif)
330
{
331
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
332
u8 omac_idx = mvif->omac_idx;
333
struct bss_info_omac *omac;
334
struct tlv *tlv;
335
u32 type = 0;
336
337
switch (vif->type) {
338
case NL80211_IFTYPE_MONITOR:
339
case NL80211_IFTYPE_MESH_POINT:
340
case NL80211_IFTYPE_AP:
341
if (vif->p2p)
342
type = CONNECTION_P2P_GO;
343
else
344
type = CONNECTION_INFRA_AP;
345
break;
346
case NL80211_IFTYPE_STATION:
347
if (vif->p2p)
348
type = CONNECTION_P2P_GC;
349
else
350
type = CONNECTION_INFRA_STA;
351
break;
352
case NL80211_IFTYPE_ADHOC:
353
type = CONNECTION_IBSS_ADHOC;
354
break;
355
default:
356
WARN_ON(1);
357
break;
358
}
359
360
tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac));
361
362
omac = (struct bss_info_omac *)tlv;
363
omac->conn_type = cpu_to_le32(type);
364
omac->omac_idx = mvif->omac_idx;
365
omac->band_idx = mvif->band_idx;
366
omac->hw_bss_idx = omac_idx > EXT_BSSID_START ? HW_BSSID_0 : omac_idx;
367
}
368
EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_omac_tlv);
369
370
void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
371
struct ieee80211_bss_conf *link_conf,
372
struct ieee80211_link_sta *link_sta,
373
int conn_state, bool newly)
374
{
375
struct ieee80211_vif *vif = link_conf->vif;
376
struct sta_rec_basic *basic;
377
struct tlv *tlv;
378
int conn_type;
379
380
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
381
382
basic = (struct sta_rec_basic *)tlv;
383
basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
384
385
if (newly && conn_state != CONN_STATE_DISCONNECT)
386
basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
387
basic->conn_state = conn_state;
388
389
if (!link_sta) {
390
basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
391
392
if (vif->type == NL80211_IFTYPE_STATION &&
393
!is_zero_ether_addr(link_conf->bssid)) {
394
memcpy(basic->peer_addr, link_conf->bssid, ETH_ALEN);
395
basic->aid = cpu_to_le16(vif->cfg.aid);
396
} else {
397
eth_broadcast_addr(basic->peer_addr);
398
}
399
return;
400
}
401
402
switch (vif->type) {
403
case NL80211_IFTYPE_MESH_POINT:
404
case NL80211_IFTYPE_AP:
405
if (vif->p2p && !is_mt7921(dev))
406
conn_type = CONNECTION_P2P_GC;
407
else
408
conn_type = CONNECTION_INFRA_STA;
409
basic->conn_type = cpu_to_le32(conn_type);
410
basic->aid = cpu_to_le16(link_sta->sta->aid);
411
break;
412
case NL80211_IFTYPE_STATION:
413
if (vif->p2p && !is_mt7921(dev))
414
conn_type = CONNECTION_P2P_GO;
415
else
416
conn_type = CONNECTION_INFRA_AP;
417
basic->conn_type = cpu_to_le32(conn_type);
418
basic->aid = cpu_to_le16(vif->cfg.aid);
419
break;
420
case NL80211_IFTYPE_ADHOC:
421
basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
422
basic->aid = cpu_to_le16(link_sta->sta->aid);
423
break;
424
default:
425
WARN_ON(1);
426
break;
427
}
428
429
memcpy(basic->peer_addr, link_sta->addr, ETH_ALEN);
430
basic->qos = link_sta->sta->wme;
431
}
432
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
433
434
void mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
435
struct ieee80211_sta *sta)
436
{
437
struct sta_rec_uapsd *uapsd;
438
struct tlv *tlv;
439
440
if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
441
return;
442
443
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
444
uapsd = (struct sta_rec_uapsd *)tlv;
445
446
if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
447
uapsd->dac_map |= BIT(3);
448
uapsd->tac_map |= BIT(3);
449
}
450
if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
451
uapsd->dac_map |= BIT(2);
452
uapsd->tac_map |= BIT(2);
453
}
454
if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
455
uapsd->dac_map |= BIT(1);
456
uapsd->tac_map |= BIT(1);
457
}
458
if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
459
uapsd->dac_map |= BIT(0);
460
uapsd->tac_map |= BIT(0);
461
}
462
uapsd->max_sp = sta->max_sp;
463
}
464
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_uapsd);
465
466
void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
467
struct ieee80211_vif *vif,
468
struct mt76_wcid *wcid,
469
void *sta_wtbl, void *wtbl_tlv)
470
{
471
struct wtbl_hdr_trans *htr;
472
struct tlv *tlv;
473
474
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS,
475
sizeof(*htr),
476
wtbl_tlv, sta_wtbl);
477
htr = (struct wtbl_hdr_trans *)tlv;
478
htr->no_rx_trans = true;
479
480
if (vif->type == NL80211_IFTYPE_STATION)
481
htr->to_ds = true;
482
else
483
htr->from_ds = true;
484
485
if (!wcid)
486
return;
487
488
htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
489
if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
490
htr->to_ds = true;
491
htr->from_ds = true;
492
}
493
}
494
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
495
496
int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
497
struct ieee80211_vif *vif,
498
struct mt76_wcid *wcid, int cmd)
499
{
500
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
501
struct wtbl_req_hdr *wtbl_hdr;
502
struct tlv *sta_wtbl;
503
struct sk_buff *skb;
504
505
skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
506
if (IS_ERR(skb))
507
return PTR_ERR(skb);
508
509
sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
510
sizeof(struct tlv));
511
512
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
513
sta_wtbl, &skb);
514
if (IS_ERR(wtbl_hdr))
515
return PTR_ERR(wtbl_hdr);
516
517
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr);
518
519
return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
520
}
521
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
522
523
int mt76_connac_mcu_wtbl_update_hdr_trans(struct mt76_dev *dev,
524
struct ieee80211_vif *vif,
525
struct ieee80211_sta *sta)
526
{
527
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
528
struct wtbl_req_hdr *wtbl_hdr;
529
struct sk_buff *skb = NULL;
530
531
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET, NULL,
532
&skb);
533
if (IS_ERR(wtbl_hdr))
534
return PTR_ERR(wtbl_hdr);
535
536
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, NULL, wtbl_hdr);
537
538
return mt76_mcu_skb_send_msg(dev, skb, MCU_EXT_CMD(WTBL_UPDATE), true);
539
}
540
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_update_hdr_trans);
541
542
void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
543
struct sk_buff *skb,
544
struct ieee80211_vif *vif,
545
struct ieee80211_sta *sta,
546
void *sta_wtbl, void *wtbl_tlv)
547
{
548
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
549
struct wtbl_generic *generic;
550
struct wtbl_rx *rx;
551
struct wtbl_spe *spe;
552
struct tlv *tlv;
553
554
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
555
sizeof(*generic),
556
wtbl_tlv, sta_wtbl);
557
558
generic = (struct wtbl_generic *)tlv;
559
560
if (sta) {
561
if (vif->type == NL80211_IFTYPE_STATION)
562
generic->partial_aid = cpu_to_le16(vif->cfg.aid);
563
else
564
generic->partial_aid = cpu_to_le16(sta->aid);
565
memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
566
generic->muar_idx = mvif->omac_idx;
567
generic->qos = sta->wme;
568
} else {
569
if (!is_connac_v1(dev) && vif->type == NL80211_IFTYPE_STATION)
570
memcpy(generic->peer_addr, vif->bss_conf.bssid,
571
ETH_ALEN);
572
else
573
eth_broadcast_addr(generic->peer_addr);
574
575
generic->muar_idx = 0xe;
576
}
577
578
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
579
wtbl_tlv, sta_wtbl);
580
581
rx = (struct wtbl_rx *)tlv;
582
rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
583
rx->rca2 = 1;
584
rx->rv = 1;
585
586
if (!is_connac_v1(dev))
587
return;
588
589
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
590
wtbl_tlv, sta_wtbl);
591
spe = (struct wtbl_spe *)tlv;
592
spe->spe_idx = 24;
593
}
594
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
595
596
static void
597
mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
598
struct ieee80211_vif *vif)
599
{
600
struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
601
struct sta_rec_amsdu *amsdu;
602
struct tlv *tlv;
603
604
if (vif->type != NL80211_IFTYPE_AP &&
605
vif->type != NL80211_IFTYPE_STATION)
606
return;
607
608
if (!sta->deflink.agg.max_amsdu_len)
609
return;
610
611
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
612
amsdu = (struct sta_rec_amsdu *)tlv;
613
amsdu->max_amsdu_num = 8;
614
amsdu->amsdu_en = true;
615
amsdu->max_mpdu_size = sta->deflink.agg.max_amsdu_len >=
616
IEEE80211_MAX_MPDU_LEN_VHT_7991;
617
618
wcid->amsdu = true;
619
}
620
621
#define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p)
622
#define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m)
623
static void
624
mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
625
{
626
struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
627
struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
628
struct sta_rec_he *he;
629
struct tlv *tlv;
630
u32 cap = 0;
631
632
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
633
634
he = (struct sta_rec_he *)tlv;
635
636
if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
637
cap |= STA_REC_HE_CAP_HTC;
638
639
if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
640
cap |= STA_REC_HE_CAP_BSR;
641
642
if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
643
cap |= STA_REC_HE_CAP_OM;
644
645
if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
646
cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
647
648
if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
649
cap |= STA_REC_HE_CAP_BQR;
650
651
if (elem->phy_cap_info[0] &
652
(IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
653
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
654
cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
655
656
if (elem->phy_cap_info[1] &
657
IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
658
cap |= STA_REC_HE_CAP_LDPC;
659
660
if (elem->phy_cap_info[1] &
661
IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
662
cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
663
664
if (elem->phy_cap_info[2] &
665
IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
666
cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
667
668
if (elem->phy_cap_info[2] &
669
IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
670
cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
671
672
if (elem->phy_cap_info[2] &
673
IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
674
cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
675
676
if (elem->phy_cap_info[6] &
677
IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
678
cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
679
680
if (elem->phy_cap_info[7] &
681
IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
682
cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
683
684
if (elem->phy_cap_info[7] &
685
IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
686
cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
687
688
if (elem->phy_cap_info[7] &
689
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
690
cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
691
692
if (elem->phy_cap_info[8] &
693
IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
694
cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
695
696
if (elem->phy_cap_info[8] &
697
IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
698
cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
699
700
if (elem->phy_cap_info[9] &
701
IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
702
cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
703
704
if (elem->phy_cap_info[9] &
705
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
706
cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
707
708
if (elem->phy_cap_info[9] &
709
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
710
cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
711
712
he->he_cap = cpu_to_le32(cap);
713
714
switch (sta->deflink.bandwidth) {
715
case IEEE80211_STA_RX_BW_160:
716
if (elem->phy_cap_info[0] &
717
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
718
he->max_nss_mcs[CMD_HE_MCS_BW8080] =
719
he_cap->he_mcs_nss_supp.rx_mcs_80p80;
720
721
he->max_nss_mcs[CMD_HE_MCS_BW160] =
722
he_cap->he_mcs_nss_supp.rx_mcs_160;
723
fallthrough;
724
default:
725
he->max_nss_mcs[CMD_HE_MCS_BW80] =
726
he_cap->he_mcs_nss_supp.rx_mcs_80;
727
break;
728
}
729
730
he->t_frame_dur =
731
HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
732
he->max_ampdu_exp =
733
HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
734
735
he->bw_set =
736
HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
737
he->device_class =
738
HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
739
he->punc_pream_rx =
740
HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
741
742
he->dcm_tx_mode =
743
HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
744
he->dcm_tx_max_nss =
745
HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
746
he->dcm_rx_mode =
747
HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
748
he->dcm_rx_max_nss =
749
HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
750
he->dcm_rx_max_nss =
751
HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
752
753
he->pkt_ext = 2;
754
}
755
756
void
757
mt76_connac_mcu_sta_he_tlv_v2(struct sk_buff *skb, struct ieee80211_sta *sta)
758
{
759
struct ieee80211_sta_he_cap *he_cap = &sta->deflink.he_cap;
760
struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
761
struct sta_rec_he_v2 *he;
762
struct tlv *tlv;
763
764
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_V2, sizeof(*he));
765
766
he = (struct sta_rec_he_v2 *)tlv;
767
memcpy(he->he_phy_cap, elem->phy_cap_info, sizeof(he->he_phy_cap));
768
memcpy(he->he_mac_cap, elem->mac_cap_info, sizeof(he->he_mac_cap));
769
770
switch (sta->deflink.bandwidth) {
771
case IEEE80211_STA_RX_BW_160:
772
if (elem->phy_cap_info[0] &
773
IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
774
he->max_nss_mcs[CMD_HE_MCS_BW8080] =
775
he_cap->he_mcs_nss_supp.rx_mcs_80p80;
776
777
he->max_nss_mcs[CMD_HE_MCS_BW160] =
778
he_cap->he_mcs_nss_supp.rx_mcs_160;
779
fallthrough;
780
default:
781
he->max_nss_mcs[CMD_HE_MCS_BW80] =
782
he_cap->he_mcs_nss_supp.rx_mcs_80;
783
break;
784
}
785
786
he->pkt_ext = IEEE80211_HE_PHY_CAP9_NOMINAL_PKT_PADDING_16US;
787
}
788
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_he_tlv_v2);
789
790
u8
791
mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
792
enum nl80211_band band,
793
struct ieee80211_link_sta *link_sta)
794
{
795
struct ieee80211_sta_ht_cap *ht_cap;
796
struct ieee80211_sta_vht_cap *vht_cap;
797
const struct ieee80211_sta_he_cap *he_cap;
798
const struct ieee80211_sta_eht_cap *eht_cap;
799
u8 mode = 0;
800
801
if (link_sta) {
802
ht_cap = &link_sta->ht_cap;
803
vht_cap = &link_sta->vht_cap;
804
he_cap = &link_sta->he_cap;
805
eht_cap = &link_sta->eht_cap;
806
} else {
807
struct ieee80211_supported_band *sband;
808
809
sband = mphy->hw->wiphy->bands[band];
810
ht_cap = &sband->ht_cap;
811
vht_cap = &sband->vht_cap;
812
he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
813
eht_cap = ieee80211_get_eht_iftype_cap(sband, vif->type);
814
}
815
816
if (band == NL80211_BAND_2GHZ) {
817
mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
818
819
if (ht_cap->ht_supported)
820
mode |= PHY_TYPE_BIT_HT;
821
822
if (he_cap && he_cap->has_he)
823
mode |= PHY_TYPE_BIT_HE;
824
825
if (eht_cap && eht_cap->has_eht)
826
mode |= PHY_TYPE_BIT_BE;
827
} else if (band == NL80211_BAND_5GHZ || band == NL80211_BAND_6GHZ) {
828
mode |= PHY_TYPE_BIT_OFDM;
829
830
if (ht_cap->ht_supported)
831
mode |= PHY_TYPE_BIT_HT;
832
833
if (vht_cap->vht_supported)
834
mode |= PHY_TYPE_BIT_VHT;
835
836
if (he_cap && he_cap->has_he)
837
mode |= PHY_TYPE_BIT_HE;
838
839
if (eht_cap && eht_cap->has_eht)
840
mode |= PHY_TYPE_BIT_BE;
841
}
842
843
return mode;
844
}
845
EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode_v2);
846
847
void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
848
struct ieee80211_sta *sta,
849
struct ieee80211_vif *vif,
850
u8 rcpi, u8 sta_state)
851
{
852
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
853
struct cfg80211_chan_def *chandef = mvif->ctx ?
854
&mvif->ctx->def : &mphy->chandef;
855
enum nl80211_band band = chandef->chan->band;
856
struct mt76_dev *dev = mphy->dev;
857
struct sta_rec_ra_info *ra_info;
858
struct sta_rec_state *state;
859
struct sta_rec_phy *phy;
860
struct tlv *tlv;
861
u16 supp_rates;
862
863
/* starec ht */
864
if (sta->deflink.ht_cap.ht_supported) {
865
struct sta_rec_ht *ht;
866
867
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
868
ht = (struct sta_rec_ht *)tlv;
869
ht->ht_cap = cpu_to_le16(sta->deflink.ht_cap.cap);
870
}
871
872
/* starec vht */
873
if (sta->deflink.vht_cap.vht_supported) {
874
struct sta_rec_vht *vht;
875
int len;
876
877
len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
878
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
879
vht = (struct sta_rec_vht *)tlv;
880
vht->vht_cap = cpu_to_le32(sta->deflink.vht_cap.cap);
881
vht->vht_rx_mcs_map = sta->deflink.vht_cap.vht_mcs.rx_mcs_map;
882
vht->vht_tx_mcs_map = sta->deflink.vht_cap.vht_mcs.tx_mcs_map;
883
}
884
885
/* starec uapsd */
886
mt76_connac_mcu_sta_uapsd(skb, vif, sta);
887
888
if (!is_mt7921(dev))
889
return;
890
891
if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_cap.has_he)
892
mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
893
894
/* starec he */
895
if (sta->deflink.he_cap.has_he) {
896
mt76_connac_mcu_sta_he_tlv(skb, sta);
897
mt76_connac_mcu_sta_he_tlv_v2(skb, sta);
898
if (band == NL80211_BAND_6GHZ &&
899
sta_state == MT76_STA_INFO_STATE_ASSOC) {
900
struct sta_rec_he_6g_capa *he_6g_capa;
901
902
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE_6G,
903
sizeof(*he_6g_capa));
904
he_6g_capa = (struct sta_rec_he_6g_capa *)tlv;
905
he_6g_capa->capa = sta->deflink.he_6ghz_capa.capa;
906
}
907
}
908
909
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
910
phy = (struct sta_rec_phy *)tlv;
911
phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band,
912
&sta->deflink);
913
phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
914
phy->rcpi = rcpi;
915
phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
916
sta->deflink.ht_cap.ampdu_factor) |
917
FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
918
sta->deflink.ht_cap.ampdu_density);
919
920
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
921
ra_info = (struct sta_rec_ra_info *)tlv;
922
923
supp_rates = sta->deflink.supp_rates[band];
924
if (band == NL80211_BAND_2GHZ)
925
supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
926
FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
927
else
928
supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates);
929
930
ra_info->legacy = cpu_to_le16(supp_rates);
931
932
if (sta->deflink.ht_cap.ht_supported)
933
memcpy(ra_info->rx_mcs_bitmask,
934
sta->deflink.ht_cap.mcs.rx_mask,
935
HT_MCS_MASK_NUM);
936
937
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
938
state = (struct sta_rec_state *)tlv;
939
state->state = sta_state;
940
941
if (sta->deflink.vht_cap.vht_supported) {
942
state->vht_opmode = sta->deflink.bandwidth;
943
state->vht_opmode |= (sta->deflink.rx_nss - 1) <<
944
IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
945
}
946
}
947
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
948
949
void mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb,
950
struct ieee80211_sta *sta,
951
void *sta_wtbl, void *wtbl_tlv)
952
{
953
struct wtbl_smps *smps;
954
struct tlv *tlv;
955
956
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
957
wtbl_tlv, sta_wtbl);
958
smps = (struct wtbl_smps *)tlv;
959
smps->smps = (sta->deflink.smps_mode == IEEE80211_SMPS_DYNAMIC);
960
}
961
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_smps_tlv);
962
963
void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
964
struct ieee80211_sta *sta, void *sta_wtbl,
965
void *wtbl_tlv, bool ht_ldpc, bool vht_ldpc)
966
{
967
struct wtbl_ht *ht = NULL;
968
struct tlv *tlv;
969
u32 flags = 0;
970
971
if (sta->deflink.ht_cap.ht_supported || sta->deflink.he_6ghz_capa.capa) {
972
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
973
wtbl_tlv, sta_wtbl);
974
ht = (struct wtbl_ht *)tlv;
975
ht->ldpc = ht_ldpc &&
976
!!(sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
977
978
if (sta->deflink.ht_cap.ht_supported) {
979
ht->af = sta->deflink.ht_cap.ampdu_factor;
980
ht->mm = sta->deflink.ht_cap.ampdu_density;
981
} else {
982
ht->af = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
983
IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP);
984
ht->mm = le16_get_bits(sta->deflink.he_6ghz_capa.capa,
985
IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START);
986
}
987
988
ht->ht = true;
989
}
990
991
if (sta->deflink.vht_cap.vht_supported || sta->deflink.he_6ghz_capa.capa) {
992
struct wtbl_vht *vht;
993
u8 af;
994
995
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
996
sizeof(*vht), wtbl_tlv,
997
sta_wtbl);
998
vht = (struct wtbl_vht *)tlv;
999
vht->ldpc = vht_ldpc &&
1000
!!(sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
1001
vht->vht = true;
1002
1003
af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
1004
sta->deflink.vht_cap.cap);
1005
if (ht)
1006
ht->af = max(ht->af, af);
1007
}
1008
1009
mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
1010
1011
if (is_connac_v1(dev) && sta->deflink.ht_cap.ht_supported) {
1012
/* sgi */
1013
u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
1014
MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
1015
struct wtbl_raw *raw;
1016
1017
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
1018
sizeof(*raw), wtbl_tlv,
1019
sta_wtbl);
1020
1021
if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
1022
flags |= MT_WTBL_W5_SHORT_GI_20;
1023
if (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
1024
flags |= MT_WTBL_W5_SHORT_GI_40;
1025
1026
if (sta->deflink.vht_cap.vht_supported) {
1027
if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
1028
flags |= MT_WTBL_W5_SHORT_GI_80;
1029
if (sta->deflink.vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
1030
flags |= MT_WTBL_W5_SHORT_GI_160;
1031
}
1032
raw = (struct wtbl_raw *)tlv;
1033
raw->val = cpu_to_le32(flags);
1034
raw->msk = cpu_to_le32(~msk);
1035
raw->wtbl_idx = 1;
1036
raw->dw = 5;
1037
}
1038
}
1039
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
1040
1041
int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
1042
struct mt76_sta_cmd_info *info)
1043
{
1044
struct mt76_vif_link *mvif = (struct mt76_vif_link *)info->vif->drv_priv;
1045
struct ieee80211_link_sta *link_sta;
1046
struct mt76_dev *dev = phy->dev;
1047
struct wtbl_req_hdr *wtbl_hdr;
1048
struct tlv *sta_wtbl;
1049
struct sk_buff *skb;
1050
int conn_state;
1051
1052
if (!info->link_conf)
1053
info->link_conf = &info->vif->bss_conf;
1054
1055
skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
1056
if (IS_ERR(skb))
1057
return PTR_ERR(skb);
1058
1059
conn_state = info->enable ? CONN_STATE_PORT_SECURE :
1060
CONN_STATE_DISCONNECT;
1061
link_sta = info->sta ? &info->sta->deflink : NULL;
1062
if (info->sta || !info->offload_fw)
1063
mt76_connac_mcu_sta_basic_tlv(dev, skb, info->link_conf,
1064
link_sta, conn_state,
1065
info->newly);
1066
if (info->sta && info->enable)
1067
mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
1068
info->vif, info->rcpi,
1069
info->state);
1070
1071
sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1072
sizeof(struct tlv));
1073
1074
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
1075
WTBL_RESET_AND_SET,
1076
sta_wtbl, &skb);
1077
if (IS_ERR(wtbl_hdr))
1078
return PTR_ERR(wtbl_hdr);
1079
1080
if (info->enable) {
1081
mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
1082
info->sta, sta_wtbl,
1083
wtbl_hdr);
1084
mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
1085
sta_wtbl, wtbl_hdr);
1086
if (info->sta)
1087
mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
1088
sta_wtbl, wtbl_hdr,
1089
true, true);
1090
}
1091
1092
return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
1093
}
1094
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
1095
1096
void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
1097
struct ieee80211_ampdu_params *params,
1098
bool enable, bool tx, void *sta_wtbl,
1099
void *wtbl_tlv)
1100
{
1101
struct wtbl_ba *ba;
1102
struct tlv *tlv;
1103
1104
tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
1105
wtbl_tlv, sta_wtbl);
1106
1107
ba = (struct wtbl_ba *)tlv;
1108
ba->tid = params->tid;
1109
1110
if (tx) {
1111
ba->ba_type = MT_BA_TYPE_ORIGINATOR;
1112
ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
1113
ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
1114
ba->ba_en = enable;
1115
} else {
1116
memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
1117
ba->ba_type = MT_BA_TYPE_RECIPIENT;
1118
ba->rst_ba_tid = params->tid;
1119
ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
1120
ba->rst_ba_sb = 1;
1121
}
1122
1123
if (!is_connac_v1(dev)) {
1124
ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
1125
return;
1126
}
1127
1128
if (enable && tx) {
1129
static const u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
1130
int i;
1131
1132
for (i = 7; i > 0; i--) {
1133
if (params->buf_size >= ba_range[i])
1134
break;
1135
}
1136
ba->ba_winsize_idx = i;
1137
}
1138
}
1139
EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
1140
1141
int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
1142
struct ieee80211_bss_conf *bss_conf,
1143
struct mt76_vif_link *mvif,
1144
struct mt76_wcid *wcid,
1145
bool enable)
1146
{
1147
struct mt76_dev *dev = phy->dev;
1148
struct {
1149
struct {
1150
u8 omac_idx;
1151
u8 band_idx;
1152
__le16 pad;
1153
} __packed hdr;
1154
struct req_tlv {
1155
__le16 tag;
1156
__le16 len;
1157
u8 active;
1158
u8 link_idx; /* not link_id */
1159
u8 omac_addr[ETH_ALEN];
1160
} __packed tlv;
1161
} dev_req = {
1162
.hdr = {
1163
.omac_idx = mvif->omac_idx,
1164
.band_idx = mvif->band_idx,
1165
},
1166
.tlv = {
1167
.tag = cpu_to_le16(DEV_INFO_ACTIVE),
1168
.len = cpu_to_le16(sizeof(struct req_tlv)),
1169
.active = enable,
1170
.link_idx = mvif->link_idx,
1171
},
1172
};
1173
struct {
1174
struct {
1175
u8 bss_idx;
1176
u8 pad[3];
1177
} __packed hdr;
1178
struct mt76_connac_bss_basic_tlv basic;
1179
} basic_req = {
1180
.hdr = {
1181
.bss_idx = mvif->idx,
1182
},
1183
.basic = {
1184
.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1185
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1186
.omac_idx = mvif->omac_idx,
1187
.band_idx = mvif->band_idx,
1188
.wmm_idx = mvif->wmm_idx,
1189
.active = enable,
1190
.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
1191
.sta_idx = cpu_to_le16(wcid->idx),
1192
.conn_state = 1,
1193
.link_idx = mvif->link_idx,
1194
},
1195
};
1196
int err, idx, cmd, len;
1197
void *data;
1198
1199
switch (bss_conf->vif->type) {
1200
case NL80211_IFTYPE_MESH_POINT:
1201
case NL80211_IFTYPE_MONITOR:
1202
case NL80211_IFTYPE_AP:
1203
basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
1204
break;
1205
case NL80211_IFTYPE_STATION:
1206
basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
1207
break;
1208
case NL80211_IFTYPE_P2P_DEVICE:
1209
basic_req.basic.conn_type = cpu_to_le32(CONNECTION_P2P_GO);
1210
break;
1211
case NL80211_IFTYPE_ADHOC:
1212
basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1213
break;
1214
default:
1215
WARN_ON(1);
1216
break;
1217
}
1218
1219
idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1220
basic_req.basic.hw_bss_idx = idx;
1221
1222
memcpy(dev_req.tlv.omac_addr, bss_conf->addr, ETH_ALEN);
1223
1224
cmd = enable ? MCU_UNI_CMD(DEV_INFO_UPDATE) : MCU_UNI_CMD(BSS_INFO_UPDATE);
1225
data = enable ? (void *)&dev_req : (void *)&basic_req;
1226
len = enable ? sizeof(dev_req) : sizeof(basic_req);
1227
1228
err = mt76_mcu_send_msg(dev, cmd, data, len, true);
1229
if (err < 0)
1230
return err;
1231
1232
cmd = enable ? MCU_UNI_CMD(BSS_INFO_UPDATE) : MCU_UNI_CMD(DEV_INFO_UPDATE);
1233
data = enable ? (void *)&basic_req : (void *)&dev_req;
1234
len = enable ? sizeof(basic_req) : sizeof(dev_req);
1235
1236
return mt76_mcu_send_msg(dev, cmd, data, len, true);
1237
}
1238
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
1239
1240
void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
1241
struct ieee80211_ampdu_params *params,
1242
bool enable, bool tx)
1243
{
1244
struct sta_rec_ba *ba;
1245
struct tlv *tlv;
1246
1247
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
1248
1249
ba = (struct sta_rec_ba *)tlv;
1250
ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
1251
ba->winsize = cpu_to_le16(params->buf_size);
1252
ba->ssn = cpu_to_le16(params->ssn);
1253
ba->ba_en = enable << params->tid;
1254
ba->amsdu = params->amsdu;
1255
ba->tid = params->tid;
1256
}
1257
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
1258
1259
int mt76_connac_mcu_sta_wed_update(struct mt76_dev *dev, struct sk_buff *skb)
1260
{
1261
if (!mt76_is_mmio(dev))
1262
return 0;
1263
1264
if (!mtk_wed_device_active(&dev->mmio.wed))
1265
return 0;
1266
1267
return mtk_wed_device_update_msg(&dev->mmio.wed, WED_WO_STA_REC,
1268
skb->data, skb->len);
1269
}
1270
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_wed_update);
1271
1272
int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif_link *mvif,
1273
struct ieee80211_ampdu_params *params,
1274
int cmd, bool enable, bool tx)
1275
{
1276
struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
1277
struct wtbl_req_hdr *wtbl_hdr;
1278
struct tlv *sta_wtbl;
1279
struct sk_buff *skb;
1280
int ret;
1281
1282
skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1283
if (IS_ERR(skb))
1284
return PTR_ERR(skb);
1285
1286
sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1287
sizeof(struct tlv));
1288
1289
wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
1290
sta_wtbl, &skb);
1291
if (IS_ERR(wtbl_hdr))
1292
return PTR_ERR(wtbl_hdr);
1293
1294
mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
1295
wtbl_hdr);
1296
1297
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
1298
if (ret)
1299
return ret;
1300
1301
ret = mt76_mcu_skb_send_msg(dev, skb, cmd, true);
1302
if (ret)
1303
return ret;
1304
1305
skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1306
if (IS_ERR(skb))
1307
return PTR_ERR(skb);
1308
1309
mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
1310
1311
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
1312
if (ret)
1313
return ret;
1314
1315
return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
1316
}
1317
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
1318
1319
u8 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
1320
enum nl80211_band band,
1321
struct ieee80211_link_sta *link_sta)
1322
{
1323
struct mt76_dev *dev = phy->dev;
1324
const struct ieee80211_sta_he_cap *he_cap;
1325
struct ieee80211_sta_vht_cap *vht_cap;
1326
struct ieee80211_sta_ht_cap *ht_cap;
1327
u8 mode = 0;
1328
1329
if (is_connac_v1(dev))
1330
return 0x38;
1331
1332
if (link_sta) {
1333
ht_cap = &link_sta->ht_cap;
1334
vht_cap = &link_sta->vht_cap;
1335
he_cap = &link_sta->he_cap;
1336
} else {
1337
struct ieee80211_supported_band *sband;
1338
1339
sband = phy->hw->wiphy->bands[band];
1340
ht_cap = &sband->ht_cap;
1341
vht_cap = &sband->vht_cap;
1342
he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
1343
}
1344
1345
if (band == NL80211_BAND_2GHZ) {
1346
mode |= PHY_MODE_B | PHY_MODE_G;
1347
1348
if (ht_cap->ht_supported)
1349
mode |= PHY_MODE_GN;
1350
1351
if (he_cap && he_cap->has_he)
1352
mode |= PHY_MODE_AX_24G;
1353
} else if (band == NL80211_BAND_5GHZ) {
1354
mode |= PHY_MODE_A;
1355
1356
if (ht_cap->ht_supported)
1357
mode |= PHY_MODE_AN;
1358
1359
if (vht_cap->vht_supported)
1360
mode |= PHY_MODE_AC;
1361
1362
if (he_cap && he_cap->has_he)
1363
mode |= PHY_MODE_AX_5G;
1364
} else if (band == NL80211_BAND_6GHZ) {
1365
mode |= PHY_MODE_A | PHY_MODE_AN |
1366
PHY_MODE_AC | PHY_MODE_AX_5G;
1367
}
1368
1369
return mode;
1370
}
1371
EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode);
1372
1373
u8 mt76_connac_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_bss_conf *conf,
1374
enum nl80211_band band)
1375
{
1376
const struct ieee80211_sta_eht_cap *eht_cap;
1377
struct ieee80211_supported_band *sband;
1378
u8 mode = 0;
1379
1380
if (band == NL80211_BAND_6GHZ)
1381
mode |= PHY_MODE_AX_6G;
1382
1383
sband = phy->hw->wiphy->bands[band];
1384
eht_cap = ieee80211_get_eht_iftype_cap(sband, conf->vif->type);
1385
1386
if (!eht_cap || !eht_cap->has_eht || !conf->eht_support)
1387
return mode;
1388
1389
switch (band) {
1390
case NL80211_BAND_6GHZ:
1391
mode |= PHY_MODE_BE_6G;
1392
break;
1393
case NL80211_BAND_5GHZ:
1394
mode |= PHY_MODE_BE_5G;
1395
break;
1396
case NL80211_BAND_2GHZ:
1397
mode |= PHY_MODE_BE_24G;
1398
break;
1399
default:
1400
break;
1401
}
1402
1403
return mode;
1404
}
1405
EXPORT_SYMBOL_GPL(mt76_connac_get_phy_mode_ext);
1406
1407
const struct ieee80211_sta_he_cap *
1408
mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1409
{
1410
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1411
struct cfg80211_chan_def *chandef = mvif->ctx ?
1412
&mvif->ctx->def : &phy->chandef;
1413
enum nl80211_band band = chandef->chan->band;
1414
struct ieee80211_supported_band *sband;
1415
1416
sband = phy->hw->wiphy->bands[band];
1417
1418
return ieee80211_get_he_iftype_cap(sband, vif->type);
1419
}
1420
EXPORT_SYMBOL_GPL(mt76_connac_get_he_phy_cap);
1421
1422
const struct ieee80211_sta_eht_cap *
1423
mt76_connac_get_eht_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1424
{
1425
enum nl80211_band band = phy->chandef.chan->band;
1426
struct ieee80211_supported_band *sband;
1427
1428
sband = phy->hw->wiphy->bands[band];
1429
1430
return ieee80211_get_eht_iftype_cap(sband, vif->type);
1431
}
1432
EXPORT_SYMBOL_GPL(mt76_connac_get_eht_phy_cap);
1433
1434
#define DEFAULT_HE_PE_DURATION 4
1435
#define DEFAULT_HE_DURATION_RTS_THRES 1023
1436
static void
1437
mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
1438
struct tlv *tlv)
1439
{
1440
const struct ieee80211_sta_he_cap *cap;
1441
struct bss_info_uni_he *he;
1442
1443
cap = mt76_connac_get_he_phy_cap(phy, vif);
1444
1445
he = (struct bss_info_uni_he *)tlv;
1446
he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
1447
if (!he->he_pe_duration)
1448
he->he_pe_duration = DEFAULT_HE_PE_DURATION;
1449
1450
he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
1451
if (!he->he_rts_thres)
1452
he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
1453
1454
he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
1455
he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
1456
he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
1457
}
1458
1459
int mt76_connac_mcu_uni_set_chctx(struct mt76_phy *phy, struct mt76_vif_link *mvif,
1460
struct ieee80211_chanctx_conf *ctx)
1461
{
1462
struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef;
1463
int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1464
enum nl80211_band band = chandef->chan->band;
1465
struct mt76_dev *mdev = phy->dev;
1466
struct {
1467
struct {
1468
u8 bss_idx;
1469
u8 pad[3];
1470
} __packed hdr;
1471
struct rlm_tlv {
1472
__le16 tag;
1473
__le16 len;
1474
u8 control_channel;
1475
u8 center_chan;
1476
u8 center_chan2;
1477
u8 bw;
1478
u8 tx_streams;
1479
u8 rx_streams;
1480
u8 short_st;
1481
u8 ht_op_info;
1482
u8 sco;
1483
u8 band;
1484
u8 pad[2];
1485
} __packed rlm;
1486
} __packed rlm_req = {
1487
.hdr = {
1488
.bss_idx = mvif->idx,
1489
},
1490
.rlm = {
1491
.tag = cpu_to_le16(UNI_BSS_INFO_RLM),
1492
.len = cpu_to_le16(sizeof(struct rlm_tlv)),
1493
.control_channel = chandef->chan->hw_value,
1494
.center_chan = ieee80211_frequency_to_channel(freq1),
1495
.center_chan2 = ieee80211_frequency_to_channel(freq2),
1496
.tx_streams = hweight8(phy->antenna_mask),
1497
.ht_op_info = 4, /* set HT 40M allowed */
1498
.rx_streams = phy->chainmask,
1499
.short_st = true,
1500
.band = band,
1501
},
1502
};
1503
1504
switch (chandef->width) {
1505
case NL80211_CHAN_WIDTH_40:
1506
rlm_req.rlm.bw = CMD_CBW_40MHZ;
1507
break;
1508
case NL80211_CHAN_WIDTH_80:
1509
rlm_req.rlm.bw = CMD_CBW_80MHZ;
1510
break;
1511
case NL80211_CHAN_WIDTH_80P80:
1512
rlm_req.rlm.bw = CMD_CBW_8080MHZ;
1513
break;
1514
case NL80211_CHAN_WIDTH_160:
1515
rlm_req.rlm.bw = CMD_CBW_160MHZ;
1516
break;
1517
case NL80211_CHAN_WIDTH_5:
1518
rlm_req.rlm.bw = CMD_CBW_5MHZ;
1519
break;
1520
case NL80211_CHAN_WIDTH_10:
1521
rlm_req.rlm.bw = CMD_CBW_10MHZ;
1522
break;
1523
case NL80211_CHAN_WIDTH_20_NOHT:
1524
case NL80211_CHAN_WIDTH_20:
1525
default:
1526
rlm_req.rlm.bw = CMD_CBW_20MHZ;
1527
rlm_req.rlm.ht_op_info = 0;
1528
break;
1529
}
1530
1531
if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
1532
rlm_req.rlm.sco = 1; /* SCA */
1533
else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
1534
rlm_req.rlm.sco = 3; /* SCB */
1535
1536
return mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &rlm_req,
1537
sizeof(rlm_req), true);
1538
}
1539
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_set_chctx);
1540
1541
int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
1542
struct ieee80211_vif *vif,
1543
struct mt76_wcid *wcid,
1544
bool enable,
1545
struct ieee80211_chanctx_conf *ctx)
1546
{
1547
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1548
struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &phy->chandef;
1549
enum nl80211_band band = chandef->chan->band;
1550
struct mt76_dev *mdev = phy->dev;
1551
struct {
1552
struct {
1553
u8 bss_idx;
1554
u8 pad[3];
1555
} __packed hdr;
1556
struct mt76_connac_bss_basic_tlv basic;
1557
struct mt76_connac_bss_qos_tlv qos;
1558
} basic_req = {
1559
.hdr = {
1560
.bss_idx = mvif->idx,
1561
},
1562
.basic = {
1563
.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1564
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1565
.bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1566
.dtim_period = vif->bss_conf.dtim_period,
1567
.omac_idx = mvif->omac_idx,
1568
.band_idx = mvif->band_idx,
1569
.wmm_idx = mvif->wmm_idx,
1570
.active = true, /* keep bss deactivated */
1571
.phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
1572
},
1573
.qos = {
1574
.tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
1575
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
1576
.qos = vif->bss_conf.qos,
1577
},
1578
};
1579
int err, conn_type;
1580
u8 idx, basic_phy;
1581
1582
idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1583
basic_req.basic.hw_bss_idx = idx;
1584
if (band == NL80211_BAND_6GHZ)
1585
basic_req.basic.phymode_ext = PHY_MODE_AX_6G;
1586
1587
basic_phy = mt76_connac_get_phy_mode_v2(phy, vif, band, NULL);
1588
basic_req.basic.nonht_basic_phy = cpu_to_le16(basic_phy);
1589
1590
switch (vif->type) {
1591
case NL80211_IFTYPE_MESH_POINT:
1592
case NL80211_IFTYPE_AP:
1593
if (vif->p2p)
1594
conn_type = CONNECTION_P2P_GO;
1595
else
1596
conn_type = CONNECTION_INFRA_AP;
1597
basic_req.basic.conn_type = cpu_to_le32(conn_type);
1598
/* Fully active/deactivate BSS network in AP mode only */
1599
basic_req.basic.active = enable;
1600
break;
1601
case NL80211_IFTYPE_STATION:
1602
if (vif->p2p)
1603
conn_type = CONNECTION_P2P_GC;
1604
else
1605
conn_type = CONNECTION_INFRA_STA;
1606
basic_req.basic.conn_type = cpu_to_le32(conn_type);
1607
break;
1608
case NL80211_IFTYPE_ADHOC:
1609
basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1610
break;
1611
default:
1612
WARN_ON(1);
1613
break;
1614
}
1615
1616
memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
1617
basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
1618
basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
1619
basic_req.basic.conn_state = !enable;
1620
1621
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE), &basic_req,
1622
sizeof(basic_req), true);
1623
if (err < 0)
1624
return err;
1625
1626
if (vif->bss_conf.he_support) {
1627
struct {
1628
struct {
1629
u8 bss_idx;
1630
u8 pad[3];
1631
} __packed hdr;
1632
struct bss_info_uni_he he;
1633
struct bss_info_uni_bss_color bss_color;
1634
} he_req = {
1635
.hdr = {
1636
.bss_idx = mvif->idx,
1637
},
1638
.he = {
1639
.tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
1640
.len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
1641
},
1642
.bss_color = {
1643
.tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
1644
.len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
1645
.enable = 0,
1646
.bss_color = 0,
1647
},
1648
};
1649
1650
if (enable) {
1651
he_req.bss_color.enable =
1652
vif->bss_conf.he_bss_color.enabled;
1653
he_req.bss_color.bss_color =
1654
vif->bss_conf.he_bss_color.color;
1655
}
1656
1657
mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
1658
(struct tlv *)&he_req.he);
1659
err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
1660
&he_req, sizeof(he_req), true);
1661
if (err < 0)
1662
return err;
1663
}
1664
1665
return mt76_connac_mcu_uni_set_chctx(phy, mvif, ctx);
1666
}
1667
EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
1668
1669
void mt76_connac_mcu_build_rnr_scan_param(struct mt76_dev *mdev,
1670
struct cfg80211_scan_request *sreq)
1671
{
1672
struct ieee80211_channel **scan_list = sreq->channels;
1673
int i, bssid_index = 0;
1674
1675
/* clear 6G active Scan BSSID table */
1676
memset(&mdev->rnr, 0, sizeof(mdev->rnr));
1677
1678
for (i = 0; i < sreq->n_6ghz_params; i++) {
1679
u8 ch_idx = sreq->scan_6ghz_params[i].channel_idx;
1680
int k = 0;
1681
1682
/* Remove the duplicated BSSID */
1683
for (k = 0; k < bssid_index; k++) {
1684
if (!memcmp(&mdev->rnr.bssid[k],
1685
sreq->scan_6ghz_params[i].bssid,
1686
ETH_ALEN))
1687
break;
1688
}
1689
1690
if (k == bssid_index &&
1691
bssid_index < MT76_RNR_SCAN_MAX_BSSIDS) {
1692
memcpy(&mdev->rnr.bssid[bssid_index++],
1693
sreq->scan_6ghz_params[i].bssid, ETH_ALEN);
1694
mdev->rnr.channel[k] = scan_list[ch_idx]->hw_value;
1695
}
1696
}
1697
1698
mdev->rnr.bssid_num = bssid_index;
1699
1700
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1701
memcpy(mdev->rnr.random_mac, sreq->mac_addr, ETH_ALEN);
1702
mdev->rnr.sreq_flag = sreq->flags;
1703
}
1704
}
1705
EXPORT_SYMBOL_GPL(mt76_connac_mcu_build_rnr_scan_param);
1706
1707
#define MT76_CONNAC_SCAN_CHANNEL_TIME 60
1708
int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
1709
struct ieee80211_scan_request *scan_req)
1710
{
1711
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1712
struct cfg80211_scan_request *sreq = &scan_req->req;
1713
int n_ssids = 0, err, i, duration;
1714
int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
1715
struct ieee80211_channel **scan_list = sreq->channels;
1716
struct mt76_dev *mdev = phy->dev;
1717
struct mt76_connac_mcu_scan_channel *chan;
1718
struct mt76_connac_hw_scan_req *req;
1719
struct sk_buff *skb;
1720
1721
if (test_bit(MT76_HW_SCANNING, &phy->state))
1722
return -EBUSY;
1723
1724
skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
1725
if (!skb)
1726
return -ENOMEM;
1727
1728
set_bit(MT76_HW_SCANNING, &phy->state);
1729
mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1730
1731
req = (struct mt76_connac_hw_scan_req *)skb_put_zero(skb, sizeof(*req));
1732
1733
req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
1734
req->bss_idx = mvif->idx;
1735
req->scan_type = sreq->n_ssids ? 1 : 0;
1736
req->probe_req_num = sreq->n_ssids ? 2 : 0;
1737
req->version = 1;
1738
1739
for (i = 0; i < sreq->n_ssids; i++) {
1740
if (!sreq->ssids[i].ssid_len)
1741
continue;
1742
1743
req->ssids[n_ssids].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
1744
memcpy(req->ssids[n_ssids].ssid, sreq->ssids[i].ssid,
1745
sreq->ssids[i].ssid_len);
1746
n_ssids++;
1747
}
1748
req->ssid_type = n_ssids ? BIT(2) : BIT(0);
1749
req->ssid_type_ext = n_ssids ? BIT(0) : 0;
1750
req->ssids_num = n_ssids;
1751
1752
duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
1753
/* increase channel time for passive scan */
1754
if (!sreq->n_ssids)
1755
duration *= 2;
1756
req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
1757
req->channel_min_dwell_time = cpu_to_le16(duration);
1758
req->channel_dwell_time = cpu_to_le16(duration);
1759
1760
if (sreq->n_channels == 0 || sreq->n_channels > 64) {
1761
req->channel_type = 0;
1762
req->channels_num = 0;
1763
req->ext_channels_num = 0;
1764
} else {
1765
req->channel_type = 4;
1766
req->channels_num = min_t(u8, sreq->n_channels, 32);
1767
req->ext_channels_num = min_t(u8, ext_channels_num, 32);
1768
}
1769
1770
for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
1771
if (i >= 32)
1772
chan = &req->ext_channels[i - 32];
1773
else
1774
chan = &req->channels[i];
1775
1776
switch (scan_list[i]->band) {
1777
case NL80211_BAND_2GHZ:
1778
chan->band = 1;
1779
break;
1780
case NL80211_BAND_6GHZ:
1781
chan->band = 3;
1782
break;
1783
default:
1784
chan->band = 2;
1785
break;
1786
}
1787
chan->channel_num = scan_list[i]->hw_value;
1788
}
1789
1790
if (sreq->ie_len > 0) {
1791
memcpy(req->ies, sreq->ie, sreq->ie_len);
1792
req->ies_len = cpu_to_le16(sreq->ie_len);
1793
}
1794
1795
if (is_mt7921(phy->dev))
1796
req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
1797
1798
memcpy(req->bssid, sreq->bssid, ETH_ALEN);
1799
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1800
get_random_mask_addr(req->random_mac, sreq->mac_addr,
1801
sreq->mac_addr_mask);
1802
req->scan_func |= SCAN_FUNC_RANDOM_MAC;
1803
}
1804
1805
err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(START_HW_SCAN),
1806
false);
1807
if (err < 0)
1808
clear_bit(MT76_HW_SCANNING, &phy->state);
1809
1810
return err;
1811
}
1812
EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
1813
1814
int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
1815
struct ieee80211_vif *vif)
1816
{
1817
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1818
struct {
1819
u8 seq_num;
1820
u8 is_ext_channel;
1821
u8 rsv[2];
1822
} __packed req = {
1823
.seq_num = mvif->scan_seq_num,
1824
};
1825
1826
if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
1827
struct cfg80211_scan_info info = {
1828
.aborted = true,
1829
};
1830
1831
ieee80211_scan_completed(phy->hw, &info);
1832
}
1833
1834
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(CANCEL_HW_SCAN),
1835
&req, sizeof(req), false);
1836
}
1837
EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
1838
1839
int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
1840
struct ieee80211_vif *vif,
1841
struct cfg80211_sched_scan_request *sreq)
1842
{
1843
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
1844
struct ieee80211_channel **scan_list = sreq->channels;
1845
struct mt76_connac_mcu_scan_channel *chan;
1846
struct mt76_connac_sched_scan_req *req;
1847
struct mt76_dev *mdev = phy->dev;
1848
struct cfg80211_match_set *match;
1849
struct cfg80211_ssid *ssid;
1850
struct sk_buff *skb;
1851
int i;
1852
1853
skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
1854
if (!skb)
1855
return -ENOMEM;
1856
1857
mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1858
1859
req = (struct mt76_connac_sched_scan_req *)skb_put_zero(skb, sizeof(*req));
1860
req->version = 1;
1861
req->seq_num = mvif->scan_seq_num | mvif->band_idx << 7;
1862
1863
if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1864
u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
1865
: req->mt7921.random_mac;
1866
1867
req->scan_func = 1;
1868
get_random_mask_addr(addr, sreq->mac_addr,
1869
sreq->mac_addr_mask);
1870
}
1871
if (is_mt7921(phy->dev)) {
1872
req->mt7921.bss_idx = mvif->idx;
1873
req->mt7921.delay = cpu_to_le32(sreq->delay);
1874
}
1875
1876
req->ssids_num = sreq->n_ssids;
1877
for (i = 0; i < req->ssids_num; i++) {
1878
ssid = &sreq->ssids[i];
1879
memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
1880
req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
1881
}
1882
1883
req->match_num = sreq->n_match_sets;
1884
for (i = 0; i < req->match_num; i++) {
1885
match = &sreq->match_sets[i];
1886
memcpy(req->match[i].ssid, match->ssid.ssid,
1887
match->ssid.ssid_len);
1888
req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
1889
req->match[i].ssid_len = match->ssid.ssid_len;
1890
}
1891
1892
req->channel_type = sreq->n_channels ? 4 : 0;
1893
req->channels_num = min_t(u8, sreq->n_channels, 64);
1894
for (i = 0; i < req->channels_num; i++) {
1895
chan = &req->channels[i];
1896
1897
switch (scan_list[i]->band) {
1898
case NL80211_BAND_2GHZ:
1899
chan->band = 1;
1900
break;
1901
case NL80211_BAND_6GHZ:
1902
chan->band = 3;
1903
break;
1904
default:
1905
chan->band = 2;
1906
break;
1907
}
1908
chan->channel_num = scan_list[i]->hw_value;
1909
}
1910
1911
req->intervals_num = sreq->n_scan_plans;
1912
for (i = 0; i < req->intervals_num; i++)
1913
req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
1914
1915
if (sreq->ie_len > 0) {
1916
req->ie_len = cpu_to_le16(sreq->ie_len);
1917
memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
1918
}
1919
1920
return mt76_mcu_skb_send_msg(mdev, skb, MCU_CE_CMD(SCHED_SCAN_REQ),
1921
false);
1922
}
1923
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
1924
1925
int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
1926
struct ieee80211_vif *vif,
1927
bool enable)
1928
{
1929
struct {
1930
u8 active; /* 0: enabled 1: disabled */
1931
u8 rsv[3];
1932
} __packed req = {
1933
.active = !enable,
1934
};
1935
1936
if (enable)
1937
set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1938
else
1939
clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1940
1941
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SCHED_SCAN_ENABLE),
1942
&req, sizeof(req), false);
1943
}
1944
EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
1945
1946
int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
1947
{
1948
struct mt76_connac_config req = {
1949
.resp_type = 0,
1950
};
1951
1952
memcpy(req.data, "assert", 7);
1953
1954
return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
1955
&req, sizeof(req), false);
1956
}
1957
EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
1958
1959
int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
1960
{
1961
struct mt76_connac_config req = {
1962
.resp_type = 0,
1963
};
1964
1965
snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
1966
1967
return mt76_mcu_send_msg(dev, MCU_CE_CMD(CHIP_CONFIG),
1968
&req, sizeof(req), false);
1969
}
1970
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
1971
1972
int mt76_connac_sta_state_dp(struct mt76_dev *dev,
1973
enum ieee80211_sta_state old_state,
1974
enum ieee80211_sta_state new_state)
1975
{
1976
if ((old_state == IEEE80211_STA_ASSOC &&
1977
new_state == IEEE80211_STA_AUTHORIZED) ||
1978
(old_state == IEEE80211_STA_NONE &&
1979
new_state == IEEE80211_STA_NOTEXIST))
1980
mt76_connac_mcu_set_deep_sleep(dev, true);
1981
1982
if ((old_state == IEEE80211_STA_NOTEXIST &&
1983
new_state == IEEE80211_STA_NONE) ||
1984
(old_state == IEEE80211_STA_AUTHORIZED &&
1985
new_state == IEEE80211_STA_ASSOC))
1986
mt76_connac_mcu_set_deep_sleep(dev, false);
1987
1988
return 0;
1989
}
1990
EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
1991
1992
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
1993
struct mt76_connac_coredump *coredump)
1994
{
1995
spin_lock_bh(&dev->lock);
1996
__skb_queue_tail(&coredump->msg_list, skb);
1997
spin_unlock_bh(&dev->lock);
1998
1999
coredump->last_activity = jiffies;
2000
2001
queue_delayed_work(dev->wq, &coredump->work,
2002
MT76_CONNAC_COREDUMP_TIMEOUT);
2003
}
2004
EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
2005
2006
static void
2007
mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
2008
struct mt76_power_limits *limits,
2009
enum nl80211_band band)
2010
{
2011
int max_power = is_mt7921(dev) ? 127 : 63;
2012
int i, offset = sizeof(limits->cck);
2013
2014
memset(sku, max_power, MT_SKU_POWER_LIMIT);
2015
2016
if (band == NL80211_BAND_2GHZ) {
2017
/* cck */
2018
memcpy(sku, limits->cck, sizeof(limits->cck));
2019
}
2020
2021
/* ofdm */
2022
memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
2023
offset += sizeof(limits->ofdm);
2024
2025
/* ht */
2026
for (i = 0; i < 2; i++) {
2027
memcpy(&sku[offset], limits->mcs[i], 8);
2028
offset += 8;
2029
}
2030
sku[offset++] = limits->mcs[0][0];
2031
2032
/* vht */
2033
for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
2034
memcpy(&sku[offset], limits->mcs[i],
2035
ARRAY_SIZE(limits->mcs[i]));
2036
offset += 12;
2037
}
2038
2039
if (!is_mt7921(dev))
2040
return;
2041
2042
/* he */
2043
for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
2044
memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
2045
offset += ARRAY_SIZE(limits->ru[i]);
2046
}
2047
}
2048
2049
s8 mt76_connac_get_ch_power(struct mt76_phy *phy,
2050
struct ieee80211_channel *chan,
2051
s8 target_power)
2052
{
2053
struct mt76_dev *dev = phy->dev;
2054
struct ieee80211_supported_band *sband;
2055
int i;
2056
2057
switch (chan->band) {
2058
case NL80211_BAND_2GHZ:
2059
sband = &phy->sband_2g.sband;
2060
break;
2061
case NL80211_BAND_5GHZ:
2062
sband = &phy->sband_5g.sband;
2063
break;
2064
case NL80211_BAND_6GHZ:
2065
sband = &phy->sband_6g.sband;
2066
break;
2067
default:
2068
return target_power;
2069
}
2070
2071
for (i = 0; i < sband->n_channels; i++) {
2072
struct ieee80211_channel *ch = &sband->channels[i];
2073
2074
if (ch->hw_value == chan->hw_value) {
2075
if (!(ch->flags & IEEE80211_CHAN_DISABLED)) {
2076
int power = 2 * ch->max_reg_power;
2077
2078
if (is_mt7663(dev) && (power > 63 || power < -64))
2079
power = 63;
2080
target_power = min_t(s8, power, target_power);
2081
}
2082
break;
2083
}
2084
}
2085
2086
return target_power;
2087
}
2088
EXPORT_SYMBOL_GPL(mt76_connac_get_ch_power);
2089
2090
static int
2091
mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
2092
enum nl80211_band band)
2093
{
2094
struct mt76_dev *dev = phy->dev;
2095
int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
2096
static const u8 chan_list_2ghz[] = {
2097
1, 2, 3, 4, 5, 6, 7,
2098
8, 9, 10, 11, 12, 13, 14
2099
};
2100
static const u8 chan_list_5ghz[] = {
2101
36, 38, 40, 42, 44, 46, 48,
2102
50, 52, 54, 56, 58, 60, 62,
2103
64, 100, 102, 104, 106, 108, 110,
2104
112, 114, 116, 118, 120, 122, 124,
2105
126, 128, 132, 134, 136, 138, 140,
2106
142, 144, 149, 151, 153, 155, 157,
2107
159, 161, 165, 169, 173, 177
2108
};
2109
static const u8 chan_list_6ghz[] = {
2110
1, 3, 5, 7, 9, 11, 13,
2111
15, 17, 19, 21, 23, 25, 27,
2112
29, 33, 35, 37, 39, 41, 43,
2113
45, 47, 49, 51, 53, 55, 57,
2114
59, 61, 65, 67, 69, 71, 73,
2115
75, 77, 79, 81, 83, 85, 87,
2116
89, 91, 93, 97, 99, 101, 103,
2117
105, 107, 109, 111, 113, 115, 117,
2118
119, 121, 123, 125, 129, 131, 133,
2119
135, 137, 139, 141, 143, 145, 147,
2120
149, 151, 153, 155, 157, 161, 163,
2121
165, 167, 169, 171, 173, 175, 177,
2122
179, 181, 183, 185, 187, 189, 193,
2123
195, 197, 199, 201, 203, 205, 207,
2124
209, 211, 213, 215, 217, 219, 221,
2125
225, 227, 229, 233
2126
};
2127
int i, n_chan, batch_size, idx = 0, tx_power, last_ch, err = 0;
2128
struct mt76_connac_sku_tlv sku_tlbv;
2129
struct mt76_power_limits *limits;
2130
const u8 *ch_list;
2131
2132
limits = devm_kmalloc(dev->dev, sizeof(*limits), GFP_KERNEL);
2133
if (!limits)
2134
return -ENOMEM;
2135
2136
sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
2137
tx_power = 2 * phy->hw->conf.power_level;
2138
if (!tx_power)
2139
tx_power = 127;
2140
2141
if (band == NL80211_BAND_2GHZ) {
2142
n_chan = ARRAY_SIZE(chan_list_2ghz);
2143
ch_list = chan_list_2ghz;
2144
} else if (band == NL80211_BAND_6GHZ) {
2145
n_chan = ARRAY_SIZE(chan_list_6ghz);
2146
ch_list = chan_list_6ghz;
2147
} else {
2148
n_chan = ARRAY_SIZE(chan_list_5ghz);
2149
ch_list = chan_list_5ghz;
2150
}
2151
batch_size = DIV_ROUND_UP(n_chan, batch_len);
2152
2153
if (phy->cap.has_6ghz)
2154
last_ch = chan_list_6ghz[ARRAY_SIZE(chan_list_6ghz) - 1];
2155
else if (phy->cap.has_5ghz)
2156
last_ch = chan_list_5ghz[ARRAY_SIZE(chan_list_5ghz) - 1];
2157
else
2158
last_ch = chan_list_2ghz[ARRAY_SIZE(chan_list_2ghz) - 1];
2159
2160
for (i = 0; i < batch_size; i++) {
2161
struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {};
2162
int j, msg_len, num_ch;
2163
struct sk_buff *skb;
2164
2165
num_ch = i == batch_size - 1 ? n_chan - i * batch_len : batch_len;
2166
msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
2167
skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
2168
if (!skb) {
2169
err = -ENOMEM;
2170
goto out;
2171
}
2172
2173
skb_reserve(skb, sizeof(tx_power_tlv));
2174
2175
BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
2176
memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
2177
tx_power_tlv.n_chan = num_ch;
2178
2179
switch (band) {
2180
case NL80211_BAND_2GHZ:
2181
tx_power_tlv.band = 1;
2182
break;
2183
case NL80211_BAND_6GHZ:
2184
tx_power_tlv.band = 3;
2185
break;
2186
default:
2187
tx_power_tlv.band = 2;
2188
break;
2189
}
2190
2191
for (j = 0; j < num_ch; j++, idx++) {
2192
struct ieee80211_channel chan = {
2193
.hw_value = ch_list[idx],
2194
.band = band,
2195
};
2196
s8 reg_power, sar_power;
2197
2198
reg_power = mt76_connac_get_ch_power(phy, &chan,
2199
tx_power);
2200
sar_power = mt76_get_sar_power(phy, &chan, reg_power);
2201
2202
mt76_get_rate_power_limits(phy, &chan, limits,
2203
sar_power);
2204
2205
tx_power_tlv.last_msg = ch_list[idx] == last_ch;
2206
sku_tlbv.channel = ch_list[idx];
2207
2208
mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
2209
limits, band);
2210
skb_put_data(skb, &sku_tlbv, sku_len);
2211
}
2212
__skb_push(skb, sizeof(tx_power_tlv));
2213
memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
2214
2215
err = mt76_mcu_skb_send_msg(dev, skb,
2216
MCU_CE_CMD(SET_RATE_TX_POWER),
2217
false);
2218
if (err < 0)
2219
goto out;
2220
}
2221
2222
out:
2223
devm_kfree(dev->dev, limits);
2224
return err;
2225
}
2226
2227
int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
2228
{
2229
int err;
2230
2231
if (phy->cap.has_2ghz) {
2232
err = mt76_connac_mcu_rate_txpower_band(phy,
2233
NL80211_BAND_2GHZ);
2234
if (err < 0)
2235
return err;
2236
}
2237
if (phy->cap.has_5ghz) {
2238
err = mt76_connac_mcu_rate_txpower_band(phy,
2239
NL80211_BAND_5GHZ);
2240
if (err < 0)
2241
return err;
2242
}
2243
if (phy->cap.has_6ghz) {
2244
err = mt76_connac_mcu_rate_txpower_band(phy,
2245
NL80211_BAND_6GHZ);
2246
if (err < 0)
2247
return err;
2248
}
2249
2250
return 0;
2251
}
2252
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
2253
2254
int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
2255
struct mt76_vif_link *vif,
2256
struct ieee80211_bss_conf *info)
2257
{
2258
struct ieee80211_vif *mvif = container_of(info, struct ieee80211_vif,
2259
bss_conf);
2260
struct sk_buff *skb;
2261
int i, len = min_t(int, mvif->cfg.arp_addr_cnt,
2262
IEEE80211_BSS_ARP_ADDR_LIST_LEN);
2263
struct {
2264
struct {
2265
u8 bss_idx;
2266
u8 pad[3];
2267
} __packed hdr;
2268
struct mt76_connac_arpns_tlv arp;
2269
} req_hdr = {
2270
.hdr = {
2271
.bss_idx = vif->idx,
2272
},
2273
.arp = {
2274
.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2275
.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2276
.ips_num = len,
2277
.mode = 2, /* update */
2278
.option = 1,
2279
},
2280
};
2281
2282
skb = mt76_mcu_msg_alloc(dev, NULL,
2283
sizeof(req_hdr) + len * sizeof(__be32));
2284
if (!skb)
2285
return -ENOMEM;
2286
2287
skb_put_data(skb, &req_hdr, sizeof(req_hdr));
2288
for (i = 0; i < len; i++)
2289
skb_put_data(skb, &mvif->cfg.arp_addr_list[i], sizeof(__be32));
2290
2291
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(OFFLOAD), true);
2292
}
2293
EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
2294
2295
int mt76_connac_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
2296
struct ieee80211_vif *vif)
2297
{
2298
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2299
int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
2300
struct mt76_phy *phy = hw->priv;
2301
struct {
2302
__le32 ct_win;
2303
u8 bss_idx;
2304
u8 rsv[3];
2305
} __packed req = {
2306
.ct_win = cpu_to_le32(ct_window),
2307
.bss_idx = mvif->idx,
2308
};
2309
2310
return mt76_mcu_send_msg(phy->dev, MCU_CE_CMD(SET_P2P_OPPPS),
2311
&req, sizeof(req), false);
2312
}
2313
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_p2p_oppps);
2314
2315
#ifdef CONFIG_PM
2316
2317
const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
2318
.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
2319
WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
2320
.n_patterns = 1,
2321
.pattern_min_len = 1,
2322
.pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
2323
.max_nd_match_sets = 10,
2324
};
2325
EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
2326
2327
static void
2328
mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
2329
struct ieee80211_vif *vif,
2330
struct ieee80211_sta *sta,
2331
struct ieee80211_key_conf *key,
2332
void *data)
2333
{
2334
struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
2335
u32 cipher;
2336
2337
if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
2338
key->cipher != WLAN_CIPHER_SUITE_CCMP &&
2339
key->cipher != WLAN_CIPHER_SUITE_TKIP)
2340
return;
2341
2342
if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
2343
cipher = BIT(3);
2344
else
2345
cipher = BIT(4);
2346
2347
/* we are assuming here to have a single pairwise key */
2348
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
2349
if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
2350
gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
2351
else
2352
gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
2353
2354
gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
2355
gtk_tlv->keyid = key->keyidx;
2356
} else {
2357
gtk_tlv->group_cipher = cpu_to_le32(cipher);
2358
}
2359
}
2360
2361
int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
2362
struct ieee80211_vif *vif,
2363
struct cfg80211_gtk_rekey_data *key)
2364
{
2365
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2366
struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
2367
struct mt76_phy *phy = hw->priv;
2368
struct sk_buff *skb;
2369
struct {
2370
u8 bss_idx;
2371
u8 pad[3];
2372
} __packed hdr = {
2373
.bss_idx = mvif->idx,
2374
};
2375
2376
skb = mt76_mcu_msg_alloc(phy->dev, NULL,
2377
sizeof(hdr) + sizeof(*gtk_tlv));
2378
if (!skb)
2379
return -ENOMEM;
2380
2381
skb_put_data(skb, &hdr, sizeof(hdr));
2382
gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put_zero(skb,
2383
sizeof(*gtk_tlv));
2384
gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
2385
gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
2386
gtk_tlv->rekey_mode = 2;
2387
gtk_tlv->option = 1;
2388
2389
rcu_read_lock();
2390
ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
2391
rcu_read_unlock();
2392
2393
memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
2394
memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
2395
memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
2396
2397
return mt76_mcu_skb_send_msg(phy->dev, skb,
2398
MCU_UNI_CMD(OFFLOAD), true);
2399
}
2400
EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
2401
2402
static int
2403
mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
2404
bool suspend)
2405
{
2406
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2407
struct {
2408
struct {
2409
u8 bss_idx;
2410
u8 pad[3];
2411
} __packed hdr;
2412
struct mt76_connac_arpns_tlv arpns;
2413
} req = {
2414
.hdr = {
2415
.bss_idx = mvif->idx,
2416
},
2417
.arpns = {
2418
.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2419
.len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2420
.mode = suspend,
2421
},
2422
};
2423
2424
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
2425
sizeof(req), true);
2426
}
2427
2428
int
2429
mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
2430
bool suspend)
2431
{
2432
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2433
struct {
2434
struct {
2435
u8 bss_idx;
2436
u8 pad[3];
2437
} __packed hdr;
2438
struct mt76_connac_gtk_rekey_tlv gtk_tlv;
2439
} __packed req = {
2440
.hdr = {
2441
.bss_idx = mvif->idx,
2442
},
2443
.gtk_tlv = {
2444
.tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
2445
.len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
2446
.rekey_mode = !suspend,
2447
},
2448
};
2449
2450
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(OFFLOAD), &req,
2451
sizeof(req), true);
2452
}
2453
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_gtk_rekey);
2454
2455
int
2456
mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
2457
struct ieee80211_vif *vif,
2458
bool enable, u8 mdtim,
2459
bool wow_suspend)
2460
{
2461
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2462
struct {
2463
struct {
2464
u8 bss_idx;
2465
u8 pad[3];
2466
} __packed hdr;
2467
struct mt76_connac_suspend_tlv suspend_tlv;
2468
} req = {
2469
.hdr = {
2470
.bss_idx = mvif->idx,
2471
},
2472
.suspend_tlv = {
2473
.tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
2474
.len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
2475
.enable = enable,
2476
.mdtim = mdtim,
2477
.wow_suspend = wow_suspend,
2478
},
2479
};
2480
2481
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
2482
sizeof(req), true);
2483
}
2484
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_mode);
2485
2486
static int
2487
mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
2488
struct ieee80211_vif *vif,
2489
u8 index, bool enable,
2490
struct cfg80211_pkt_pattern *pattern)
2491
{
2492
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2493
struct mt76_connac_wow_pattern_tlv *ptlv;
2494
struct sk_buff *skb;
2495
struct req_hdr {
2496
u8 bss_idx;
2497
u8 pad[3];
2498
} __packed hdr = {
2499
.bss_idx = mvif->idx,
2500
};
2501
2502
skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
2503
if (!skb)
2504
return -ENOMEM;
2505
2506
skb_put_data(skb, &hdr, sizeof(hdr));
2507
ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put_zero(skb, sizeof(*ptlv));
2508
ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
2509
ptlv->len = cpu_to_le16(sizeof(*ptlv));
2510
ptlv->data_len = pattern->pattern_len;
2511
ptlv->enable = enable;
2512
ptlv->index = index;
2513
2514
memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
2515
memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
2516
2517
return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD(SUSPEND), true);
2518
}
2519
2520
int
2521
mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
2522
bool suspend, struct cfg80211_wowlan *wowlan)
2523
{
2524
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2525
struct mt76_dev *dev = phy->dev;
2526
struct {
2527
struct {
2528
u8 bss_idx;
2529
u8 pad[3];
2530
} __packed hdr;
2531
struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
2532
struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
2533
} req = {
2534
.hdr = {
2535
.bss_idx = mvif->idx,
2536
},
2537
.wow_ctrl_tlv = {
2538
.tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
2539
.len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
2540
.cmd = suspend ? 1 : 2,
2541
},
2542
.gpio_tlv = {
2543
.tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
2544
.len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
2545
.gpio_pin = 0xff, /* follow fw about GPIO pin */
2546
},
2547
};
2548
2549
if (wowlan->magic_pkt)
2550
req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
2551
if (wowlan->disconnect)
2552
req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
2553
UNI_WOW_DETECT_TYPE_BCN_LOST);
2554
if (wowlan->nd_config) {
2555
mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
2556
req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
2557
mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
2558
}
2559
if (wowlan->n_patterns)
2560
req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
2561
2562
if (mt76_is_mmio(dev))
2563
req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
2564
else if (mt76_is_usb(dev))
2565
req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
2566
else if (mt76_is_sdio(dev))
2567
req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
2568
2569
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(SUSPEND), &req,
2570
sizeof(req), true);
2571
}
2572
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_wow_ctrl);
2573
2574
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend, bool wait_resp)
2575
{
2576
struct {
2577
struct {
2578
u8 hif_type; /* 0x0: HIF_SDIO
2579
* 0x1: HIF_USB
2580
* 0x2: HIF_PCIE
2581
*/
2582
u8 pad[3];
2583
} __packed hdr;
2584
struct hif_suspend_tlv {
2585
__le16 tag;
2586
__le16 len;
2587
u8 suspend;
2588
u8 pad[7];
2589
} __packed hif_suspend;
2590
} req = {
2591
.hif_suspend = {
2592
.tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
2593
.len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
2594
.suspend = suspend,
2595
},
2596
};
2597
2598
if (mt76_is_mmio(dev))
2599
req.hdr.hif_type = 2;
2600
else if (mt76_is_usb(dev))
2601
req.hdr.hif_type = 1;
2602
else if (mt76_is_sdio(dev))
2603
req.hdr.hif_type = 0;
2604
2605
return mt76_mcu_send_msg(dev, MCU_UNI_CMD(HIF_CTRL), &req,
2606
sizeof(req), wait_resp);
2607
}
2608
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
2609
2610
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
2611
struct ieee80211_vif *vif)
2612
{
2613
struct mt76_phy *phy = priv;
2614
bool suspend = !test_bit(MT76_STATE_RUNNING, &phy->state);
2615
struct ieee80211_hw *hw = phy->hw;
2616
struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
2617
int i;
2618
2619
mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
2620
mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
2621
2622
mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
2623
2624
for (i = 0; i < wowlan->n_patterns; i++)
2625
mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
2626
&wowlan->patterns[i]);
2627
mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
2628
}
2629
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
2630
#endif /* CONFIG_PM */
2631
2632
u32 mt76_connac_mcu_reg_rr(struct mt76_dev *dev, u32 offset)
2633
{
2634
struct {
2635
__le32 addr;
2636
__le32 val;
2637
} __packed req = {
2638
.addr = cpu_to_le32(offset),
2639
};
2640
2641
return mt76_mcu_send_msg(dev, MCU_CE_QUERY(REG_READ), &req,
2642
sizeof(req), true);
2643
}
2644
EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_rr);
2645
2646
void mt76_connac_mcu_reg_wr(struct mt76_dev *dev, u32 offset, u32 val)
2647
{
2648
struct {
2649
__le32 addr;
2650
__le32 val;
2651
} __packed req = {
2652
.addr = cpu_to_le32(offset),
2653
.val = cpu_to_le32(val),
2654
};
2655
2656
mt76_mcu_send_msg(dev, MCU_CE_CMD(REG_WRITE), &req,
2657
sizeof(req), false);
2658
}
2659
EXPORT_SYMBOL_GPL(mt76_connac_mcu_reg_wr);
2660
2661
static int
2662
mt76_connac_mcu_sta_key_tlv(struct mt76_connac_sta_key_conf *sta_key_conf,
2663
struct sk_buff *skb,
2664
struct ieee80211_key_conf *key,
2665
enum set_key_cmd cmd)
2666
{
2667
struct sta_rec_sec *sec;
2668
u32 len = sizeof(*sec);
2669
struct tlv *tlv;
2670
2671
tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_KEY_V2, sizeof(*sec));
2672
sec = (struct sta_rec_sec *)tlv;
2673
sec->add = cmd;
2674
2675
if (cmd == SET_KEY) {
2676
struct sec_key *sec_key;
2677
u8 cipher;
2678
2679
cipher = mt76_connac_mcu_get_cipher(key->cipher);
2680
if (cipher == MCU_CIPHER_NONE)
2681
return -EOPNOTSUPP;
2682
2683
sec_key = &sec->key[0];
2684
sec_key->cipher_len = sizeof(*sec_key);
2685
2686
if (cipher == MCU_CIPHER_BIP_CMAC_128) {
2687
sec_key->cipher_id = MCU_CIPHER_AES_CCMP;
2688
sec_key->key_id = sta_key_conf->keyidx;
2689
sec_key->key_len = 16;
2690
memcpy(sec_key->key, sta_key_conf->key, 16);
2691
2692
sec_key = &sec->key[1];
2693
sec_key->cipher_id = MCU_CIPHER_BIP_CMAC_128;
2694
sec_key->cipher_len = sizeof(*sec_key);
2695
sec_key->key_len = 16;
2696
memcpy(sec_key->key, key->key, 16);
2697
sec->n_cipher = 2;
2698
} else {
2699
sec_key->cipher_id = cipher;
2700
sec_key->key_id = key->keyidx;
2701
sec_key->key_len = key->keylen;
2702
memcpy(sec_key->key, key->key, key->keylen);
2703
2704
if (cipher == MCU_CIPHER_TKIP) {
2705
/* Rx/Tx MIC keys are swapped */
2706
memcpy(sec_key->key + 16, key->key + 24, 8);
2707
memcpy(sec_key->key + 24, key->key + 16, 8);
2708
}
2709
2710
/* store key_conf for BIP batch update */
2711
if (cipher == MCU_CIPHER_AES_CCMP) {
2712
memcpy(sta_key_conf->key, key->key, key->keylen);
2713
sta_key_conf->keyidx = key->keyidx;
2714
}
2715
2716
len -= sizeof(*sec_key);
2717
sec->n_cipher = 1;
2718
}
2719
} else {
2720
len -= sizeof(sec->key);
2721
sec->n_cipher = 0;
2722
}
2723
sec->len = cpu_to_le16(len);
2724
2725
return 0;
2726
}
2727
2728
int mt76_connac_mcu_add_key(struct mt76_dev *dev, struct ieee80211_vif *vif,
2729
struct mt76_connac_sta_key_conf *sta_key_conf,
2730
struct ieee80211_key_conf *key, int mcu_cmd,
2731
struct mt76_wcid *wcid, enum set_key_cmd cmd)
2732
{
2733
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2734
struct sk_buff *skb;
2735
int ret;
2736
2737
skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
2738
if (IS_ERR(skb))
2739
return PTR_ERR(skb);
2740
2741
ret = mt76_connac_mcu_sta_key_tlv(sta_key_conf, skb, key, cmd);
2742
if (ret)
2743
return ret;
2744
2745
ret = mt76_connac_mcu_sta_wed_update(dev, skb);
2746
if (ret)
2747
return ret;
2748
2749
return mt76_mcu_skb_send_msg(dev, skb, mcu_cmd, true);
2750
}
2751
EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_key);
2752
2753
/* SIFS 20us + 512 byte beacon transmitted by 1Mbps (3906us) */
2754
#define BCN_TX_ESTIMATE_TIME (4096 + 20)
2755
void mt76_connac_mcu_bss_ext_tlv(struct sk_buff *skb, struct mt76_vif_link *mvif)
2756
{
2757
struct bss_info_ext_bss *ext;
2758
int ext_bss_idx, tsf_offset;
2759
struct tlv *tlv;
2760
2761
ext_bss_idx = mvif->omac_idx - EXT_BSSID_START;
2762
if (ext_bss_idx < 0)
2763
return;
2764
2765
tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_EXT_BSS, sizeof(*ext));
2766
2767
ext = (struct bss_info_ext_bss *)tlv;
2768
tsf_offset = ext_bss_idx * BCN_TX_ESTIMATE_TIME;
2769
ext->mbss_tsf_offset = cpu_to_le32(tsf_offset);
2770
}
2771
EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_ext_tlv);
2772
2773
int mt76_connac_mcu_bss_basic_tlv(struct sk_buff *skb,
2774
struct ieee80211_vif *vif,
2775
struct ieee80211_sta *sta,
2776
struct mt76_phy *phy, u16 wlan_idx,
2777
bool enable)
2778
{
2779
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
2780
u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
2781
struct bss_info_basic *bss;
2782
struct tlv *tlv;
2783
2784
tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
2785
bss = (struct bss_info_basic *)tlv;
2786
2787
switch (vif->type) {
2788
case NL80211_IFTYPE_MESH_POINT:
2789
case NL80211_IFTYPE_MONITOR:
2790
break;
2791
case NL80211_IFTYPE_AP:
2792
if (ieee80211_hw_check(phy->hw, SUPPORTS_MULTI_BSSID)) {
2793
u8 bssid_id = vif->bss_conf.bssid_indicator;
2794
struct wiphy *wiphy = phy->hw->wiphy;
2795
2796
if (bssid_id > ilog2(wiphy->mbssid_max_interfaces))
2797
return -EINVAL;
2798
2799
bss->non_tx_bssid = vif->bss_conf.bssid_index;
2800
bss->max_bssid = bssid_id;
2801
}
2802
break;
2803
case NL80211_IFTYPE_STATION:
2804
if (enable) {
2805
rcu_read_lock();
2806
if (!sta)
2807
sta = ieee80211_find_sta(vif,
2808
vif->bss_conf.bssid);
2809
/* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
2810
if (sta) {
2811
struct mt76_wcid *wcid;
2812
2813
wcid = (struct mt76_wcid *)sta->drv_priv;
2814
wlan_idx = wcid->idx;
2815
}
2816
rcu_read_unlock();
2817
}
2818
break;
2819
case NL80211_IFTYPE_ADHOC:
2820
type = NETWORK_IBSS;
2821
break;
2822
default:
2823
WARN_ON(1);
2824
break;
2825
}
2826
2827
bss->network_type = cpu_to_le32(type);
2828
bss->bmc_wcid_lo = to_wcid_lo(wlan_idx);
2829
bss->bmc_wcid_hi = to_wcid_hi(wlan_idx);
2830
bss->wmm_idx = mvif->wmm_idx;
2831
bss->active = enable;
2832
bss->cipher = mvif->cipher;
2833
2834
if (vif->type != NL80211_IFTYPE_MONITOR) {
2835
struct cfg80211_chan_def *chandef = &phy->chandef;
2836
2837
memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
2838
bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
2839
bss->dtim_period = vif->bss_conf.dtim_period;
2840
bss->phy_mode = mt76_connac_get_phy_mode(phy, vif,
2841
chandef->chan->band, NULL);
2842
} else {
2843
memcpy(bss->bssid, phy->macaddr, ETH_ALEN);
2844
}
2845
2846
return 0;
2847
}
2848
EXPORT_SYMBOL_GPL(mt76_connac_mcu_bss_basic_tlv);
2849
2850
#define ENTER_PM_STATE 1
2851
#define EXIT_PM_STATE 2
2852
int mt76_connac_mcu_set_pm(struct mt76_dev *dev, int band, int enter)
2853
{
2854
struct {
2855
u8 pm_number;
2856
u8 pm_state;
2857
u8 bssid[ETH_ALEN];
2858
u8 dtim_period;
2859
u8 wlan_idx_lo;
2860
__le16 bcn_interval;
2861
__le32 aid;
2862
__le32 rx_filter;
2863
u8 band_idx;
2864
u8 wlan_idx_hi;
2865
u8 rsv[2];
2866
__le32 feature;
2867
u8 omac_idx;
2868
u8 wmm_idx;
2869
u8 bcn_loss_cnt;
2870
u8 bcn_sp_duration;
2871
} __packed req = {
2872
.pm_number = 5,
2873
.pm_state = enter ? ENTER_PM_STATE : EXIT_PM_STATE,
2874
.band_idx = band,
2875
};
2876
2877
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(PM_STATE_CTRL), &req,
2878
sizeof(req), true);
2879
}
2880
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_pm);
2881
2882
int mt76_connac_mcu_restart(struct mt76_dev *dev)
2883
{
2884
struct {
2885
u8 power_mode;
2886
u8 rsv[3];
2887
} req = {
2888
.power_mode = 1,
2889
};
2890
2891
return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req,
2892
sizeof(req), false);
2893
}
2894
EXPORT_SYMBOL_GPL(mt76_connac_mcu_restart);
2895
2896
int mt76_connac_mcu_del_wtbl_all(struct mt76_dev *dev)
2897
{
2898
struct wtbl_req_hdr req = {
2899
.operation = WTBL_RESET_ALL,
2900
};
2901
2902
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(WTBL_UPDATE),
2903
&req, sizeof(req), true);
2904
}
2905
EXPORT_SYMBOL_GPL(mt76_connac_mcu_del_wtbl_all);
2906
2907
int mt76_connac_mcu_rdd_cmd(struct mt76_dev *dev, int cmd, u8 index,
2908
u8 rx_sel, u8 val)
2909
{
2910
struct {
2911
u8 ctrl;
2912
u8 rdd_idx;
2913
u8 rdd_rx_sel;
2914
u8 val;
2915
u8 rsv[4];
2916
} __packed req = {
2917
.ctrl = cmd,
2918
.rdd_idx = index,
2919
.rdd_rx_sel = rx_sel,
2920
.val = val,
2921
};
2922
2923
return mt76_mcu_send_msg(dev, MCU_EXT_CMD(SET_RDD_CTRL), &req,
2924
sizeof(req), true);
2925
}
2926
EXPORT_SYMBOL_GPL(mt76_connac_mcu_rdd_cmd);
2927
2928
static int
2929
mt76_connac_mcu_send_ram_firmware(struct mt76_dev *dev,
2930
const struct mt76_connac2_fw_trailer *hdr,
2931
const u8 *data, bool is_wa)
2932
{
2933
int i, offset = 0, max_len = mt76_is_sdio(dev) ? 2048 : 4096;
2934
u32 override = 0, option = 0;
2935
2936
for (i = 0; i < hdr->n_region; i++) {
2937
const struct mt76_connac2_fw_region *region;
2938
u32 len, addr, mode;
2939
int err;
2940
2941
region = (const void *)((const u8 *)hdr -
2942
(hdr->n_region - i) * sizeof(*region));
2943
mode = mt76_connac_mcu_gen_dl_mode(dev, region->feature_set,
2944
is_wa);
2945
len = le32_to_cpu(region->len);
2946
addr = le32_to_cpu(region->addr);
2947
2948
if (region->feature_set & FW_FEATURE_NON_DL)
2949
goto next;
2950
2951
if (region->feature_set & FW_FEATURE_OVERRIDE_ADDR)
2952
override = addr;
2953
2954
err = mt76_connac_mcu_init_download(dev, addr, len, mode);
2955
if (err) {
2956
dev_err(dev->dev, "Download request failed\n");
2957
return err;
2958
}
2959
2960
err = __mt76_mcu_send_firmware(dev, MCU_CMD(FW_SCATTER),
2961
data + offset, len, max_len);
2962
if (err) {
2963
dev_err(dev->dev, "Failed to send firmware.\n");
2964
return err;
2965
}
2966
2967
next:
2968
offset += len;
2969
}
2970
2971
if (override)
2972
option |= FW_START_OVERRIDE;
2973
if (is_wa)
2974
option |= FW_START_WORKING_PDA_CR4;
2975
2976
return mt76_connac_mcu_start_firmware(dev, override, option);
2977
}
2978
2979
int mt76_connac2_load_ram(struct mt76_dev *dev, const char *fw_wm,
2980
const char *fw_wa)
2981
{
2982
const struct mt76_connac2_fw_trailer *hdr;
2983
const struct firmware *fw;
2984
int ret;
2985
2986
ret = request_firmware(&fw, fw_wm, dev->dev);
2987
if (ret)
2988
return ret;
2989
2990
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
2991
dev_err(dev->dev, "Invalid firmware\n");
2992
ret = -EINVAL;
2993
goto out;
2994
}
2995
2996
hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
2997
dev_info(dev->dev, "WM Firmware Version: %.10s, Build Time: %.15s\n",
2998
hdr->fw_ver, hdr->build_date);
2999
3000
ret = mt76_connac_mcu_send_ram_firmware(dev, hdr, fw->data, false);
3001
if (ret) {
3002
dev_err(dev->dev, "Failed to start WM firmware\n");
3003
goto out;
3004
}
3005
3006
snprintf(dev->hw->wiphy->fw_version,
3007
sizeof(dev->hw->wiphy->fw_version),
3008
"%.10s-%.15s", hdr->fw_ver, hdr->build_date);
3009
3010
release_firmware(fw);
3011
3012
if (!fw_wa)
3013
return 0;
3014
3015
ret = request_firmware(&fw, fw_wa, dev->dev);
3016
if (ret)
3017
return ret;
3018
3019
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
3020
dev_err(dev->dev, "Invalid firmware\n");
3021
ret = -EINVAL;
3022
goto out;
3023
}
3024
3025
hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
3026
dev_info(dev->dev, "WA Firmware Version: %.10s, Build Time: %.15s\n",
3027
hdr->fw_ver, hdr->build_date);
3028
3029
ret = mt76_connac_mcu_send_ram_firmware(dev, hdr, fw->data, true);
3030
if (ret) {
3031
dev_err(dev->dev, "Failed to start WA firmware\n");
3032
goto out;
3033
}
3034
3035
snprintf(dev->hw->wiphy->fw_version,
3036
sizeof(dev->hw->wiphy->fw_version),
3037
"%.10s-%.15s", hdr->fw_ver, hdr->build_date);
3038
3039
out:
3040
release_firmware(fw);
3041
3042
return ret;
3043
}
3044
EXPORT_SYMBOL_GPL(mt76_connac2_load_ram);
3045
3046
static u32 mt76_connac2_get_data_mode(struct mt76_dev *dev, u32 info)
3047
{
3048
u32 mode = DL_MODE_NEED_RSP;
3049
3050
if ((!is_mt7921(dev) && !is_mt7925(dev)) || info == PATCH_SEC_NOT_SUPPORT)
3051
return mode;
3052
3053
switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) {
3054
case PATCH_SEC_ENC_TYPE_PLAIN:
3055
break;
3056
case PATCH_SEC_ENC_TYPE_AES:
3057
mode |= DL_MODE_ENCRYPT;
3058
mode |= FIELD_PREP(DL_MODE_KEY_IDX,
3059
(info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX;
3060
mode |= DL_MODE_RESET_SEC_IV;
3061
break;
3062
case PATCH_SEC_ENC_TYPE_SCRAMBLE:
3063
mode |= DL_MODE_ENCRYPT;
3064
mode |= DL_CONFIG_ENCRY_MODE_SEL;
3065
mode |= DL_MODE_RESET_SEC_IV;
3066
break;
3067
default:
3068
dev_err(dev->dev, "Encryption type not support!\n");
3069
}
3070
3071
return mode;
3072
}
3073
3074
int mt76_connac2_load_patch(struct mt76_dev *dev, const char *fw_name)
3075
{
3076
int i, ret, sem, max_len = mt76_is_sdio(dev) ? 2048 : 4096;
3077
const struct mt76_connac2_patch_hdr *hdr;
3078
const struct firmware *fw = NULL;
3079
3080
sem = mt76_connac_mcu_patch_sem_ctrl(dev, true);
3081
switch (sem) {
3082
case PATCH_IS_DL:
3083
return 0;
3084
case PATCH_NOT_DL_SEM_SUCCESS:
3085
break;
3086
default:
3087
dev_err(dev->dev, "Failed to get patch semaphore\n");
3088
return -EAGAIN;
3089
}
3090
3091
ret = request_firmware(&fw, fw_name, dev->dev);
3092
if (ret)
3093
goto out;
3094
3095
if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
3096
dev_err(dev->dev, "Invalid firmware\n");
3097
ret = -EINVAL;
3098
goto out;
3099
}
3100
3101
hdr = (const void *)fw->data;
3102
dev_info(dev->dev, "HW/SW Version: 0x%x, Build Time: %.16s\n",
3103
be32_to_cpu(hdr->hw_sw_ver), hdr->build_date);
3104
3105
for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
3106
#if defined(__linux__)
3107
struct mt76_connac2_patch_sec *sec;
3108
#elif defined(__FreeBSD__)
3109
const struct mt76_connac2_patch_sec *sec;
3110
#endif
3111
u32 len, addr, mode;
3112
const u8 *dl;
3113
u32 sec_info;
3114
3115
#if defined(__linux__)
3116
sec = (void *)(fw->data + sizeof(*hdr) + i * sizeof(*sec));
3117
#elif defined(__FreeBSD__)
3118
sec = (const void *)(fw->data + sizeof(*hdr) + i * sizeof(*sec));
3119
#endif
3120
if ((be32_to_cpu(sec->type) & PATCH_SEC_TYPE_MASK) !=
3121
PATCH_SEC_TYPE_INFO) {
3122
ret = -EINVAL;
3123
goto out;
3124
}
3125
3126
addr = be32_to_cpu(sec->info.addr);
3127
len = be32_to_cpu(sec->info.len);
3128
dl = fw->data + be32_to_cpu(sec->offs);
3129
sec_info = be32_to_cpu(sec->info.sec_key_idx);
3130
mode = mt76_connac2_get_data_mode(dev, sec_info);
3131
3132
ret = mt76_connac_mcu_init_download(dev, addr, len, mode);
3133
if (ret) {
3134
dev_err(dev->dev, "Download request failed\n");
3135
goto out;
3136
}
3137
3138
ret = __mt76_mcu_send_firmware(dev, MCU_CMD(FW_SCATTER),
3139
dl, len, max_len);
3140
if (ret) {
3141
dev_err(dev->dev, "Failed to send patch\n");
3142
goto out;
3143
}
3144
}
3145
3146
ret = mt76_connac_mcu_start_patch(dev);
3147
if (ret)
3148
dev_err(dev->dev, "Failed to start patch\n");
3149
3150
out:
3151
sem = mt76_connac_mcu_patch_sem_ctrl(dev, false);
3152
switch (sem) {
3153
case PATCH_REL_SEM_SUCCESS:
3154
break;
3155
default:
3156
ret = -EAGAIN;
3157
dev_err(dev->dev, "Failed to release patch semaphore\n");
3158
break;
3159
}
3160
3161
release_firmware(fw);
3162
3163
return ret;
3164
}
3165
EXPORT_SYMBOL_GPL(mt76_connac2_load_patch);
3166
3167
int mt76_connac2_mcu_fill_message(struct mt76_dev *dev, struct sk_buff *skb,
3168
int cmd, int *wait_seq)
3169
{
3170
int txd_len, mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
3171
struct mt76_connac2_mcu_uni_txd *uni_txd;
3172
struct mt76_connac2_mcu_txd *mcu_txd;
3173
__le32 *txd;
3174
u32 val;
3175
u8 seq;
3176
3177
/* TODO: make dynamic based on msg type */
3178
dev->mcu.timeout = 20 * HZ;
3179
3180
seq = ++dev->mcu.msg_seq & 0xf;
3181
if (!seq)
3182
seq = ++dev->mcu.msg_seq & 0xf;
3183
3184
if (cmd == MCU_CMD(FW_SCATTER))
3185
goto exit;
3186
3187
txd_len = cmd & __MCU_CMD_FIELD_UNI ? sizeof(*uni_txd) : sizeof(*mcu_txd);
3188
txd = (__le32 *)skb_push(skb, txd_len);
3189
3190
val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
3191
FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
3192
FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
3193
txd[0] = cpu_to_le32(val);
3194
3195
val = MT_TXD1_LONG_FORMAT |
3196
FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_CMD);
3197
txd[1] = cpu_to_le32(val);
3198
3199
if (cmd & __MCU_CMD_FIELD_UNI) {
3200
uni_txd = (struct mt76_connac2_mcu_uni_txd *)txd;
3201
uni_txd->len = cpu_to_le16(skb->len - sizeof(uni_txd->txd));
3202
uni_txd->option = MCU_CMD_UNI_EXT_ACK;
3203
uni_txd->cid = cpu_to_le16(mcu_cmd);
3204
uni_txd->s2d_index = MCU_S2D_H2N;
3205
uni_txd->pkt_type = MCU_PKT_ID;
3206
uni_txd->seq = seq;
3207
3208
goto exit;
3209
}
3210
3211
mcu_txd = (struct mt76_connac2_mcu_txd *)txd;
3212
mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
3213
mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
3214
MT_TX_MCU_PORT_RX_Q0));
3215
mcu_txd->pkt_type = MCU_PKT_ID;
3216
mcu_txd->seq = seq;
3217
mcu_txd->cid = mcu_cmd;
3218
mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
3219
3220
if (mcu_txd->ext_cid || (cmd & __MCU_CMD_FIELD_CE)) {
3221
if (cmd & __MCU_CMD_FIELD_QUERY)
3222
mcu_txd->set_query = MCU_Q_QUERY;
3223
else
3224
mcu_txd->set_query = MCU_Q_SET;
3225
mcu_txd->ext_cid_ack = !!mcu_txd->ext_cid;
3226
} else {
3227
mcu_txd->set_query = MCU_Q_NA;
3228
}
3229
3230
if (cmd & __MCU_CMD_FIELD_WA)
3231
mcu_txd->s2d_index = MCU_S2D_H2C;
3232
else
3233
mcu_txd->s2d_index = MCU_S2D_H2N;
3234
3235
exit:
3236
if (wait_seq)
3237
*wait_seq = seq;
3238
3239
return 0;
3240
}
3241
EXPORT_SYMBOL_GPL(mt76_connac2_mcu_fill_message);
3242
3243
MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
3244
MODULE_DESCRIPTION("MediaTek MT76x connac layer helpers");
3245
MODULE_LICENSE("Dual BSD/GPL");
3246
3247