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