1
2
3
4#include "mt76_connac_mcu.h"
5
6int mt76_connac_mcu_start_firmware(struct mt76_dev *dev, u32 addr, u32 option)
7{
8 struct {
9 __le32 option;
10 __le32 addr;
11 } req = {
12 .option = cpu_to_le32(option),
13 .addr = cpu_to_le32(addr),
14 };
15
16 return mt76_mcu_send_msg(dev, MCU_CMD_FW_START_REQ, &req, sizeof(req),
17 true);
18}
19EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
20
21int mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev *dev, bool get)
22{
23 u32 op = get ? PATCH_SEM_GET : PATCH_SEM_RELEASE;
24 struct {
25 __le32 op;
26 } req = {
27 .op = cpu_to_le32(op),
28 };
29
30 return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_SEM_CONTROL, &req,
31 sizeof(req), true);
32}
33EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
34
35int mt76_connac_mcu_start_patch(struct mt76_dev *dev)
36{
37 struct {
38 u8 check_crc;
39 u8 reserved[3];
40 } req = {
41 .check_crc = 0,
42 };
43
44 return mt76_mcu_send_msg(dev, MCU_CMD_PATCH_FINISH_REQ, &req,
45 sizeof(req), true);
46}
47EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
48
49#define MCU_PATCH_ADDRESS 0x200000
50
51int mt76_connac_mcu_init_download(struct mt76_dev *dev, u32 addr, u32 len,
52 u32 mode)
53{
54 struct {
55 __le32 addr;
56 __le32 len;
57 __le32 mode;
58 } req = {
59 .addr = cpu_to_le32(addr),
60 .len = cpu_to_le32(len),
61 .mode = cpu_to_le32(mode),
62 };
63 int cmd;
64
65 if (is_mt7921(dev) &&
66 (req.addr == cpu_to_le32(MCU_PATCH_ADDRESS) || addr == 0x900000))
67 cmd = MCU_CMD_PATCH_START_REQ;
68 else
69 cmd = MCU_CMD_TARGET_ADDRESS_LEN_REQ;
70
71 return mt76_mcu_send_msg(dev, cmd, &req, sizeof(req), true);
72}
73EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
74
75int mt76_connac_mcu_set_channel_domain(struct mt76_phy *phy)
76{
77 struct mt76_dev *dev = phy->dev;
78 struct mt76_connac_mcu_channel_domain {
79 u8 alpha2[4];
80 u8 bw_2g;
81
82
83
84
85
86 u8 bw_5g;
87 __le16 pad;
88 u8 n_2ch;
89 u8 n_5ch;
90 __le16 pad2;
91 } __packed hdr = {
92 .bw_2g = 0,
93 .bw_5g = 3,
94 };
95 struct mt76_connac_mcu_chan {
96 __le16 hw_value;
97 __le16 pad;
98 __le32 flags;
99 } __packed channel;
100 int len, i, n_max_channels, n_2ch = 0, n_5ch = 0;
101 struct ieee80211_channel *chan;
102 struct sk_buff *skb;
103
104 n_max_channels = phy->sband_2g.sband.n_channels +
105 phy->sband_5g.sband.n_channels;
106 len = sizeof(hdr) + n_max_channels * sizeof(channel);
107
108 skb = mt76_mcu_msg_alloc(dev, NULL, len);
109 if (!skb)
110 return -ENOMEM;
111
112 skb_reserve(skb, sizeof(hdr));
113
114 for (i = 0; i < phy->sband_2g.sband.n_channels; i++) {
115 chan = &phy->sband_2g.sband.channels[i];
116 if (chan->flags & IEEE80211_CHAN_DISABLED)
117 continue;
118
119 channel.hw_value = cpu_to_le16(chan->hw_value);
120 channel.flags = cpu_to_le32(chan->flags);
121 channel.pad = 0;
122
123 skb_put_data(skb, &channel, sizeof(channel));
124 n_2ch++;
125 }
126 for (i = 0; i < phy->sband_5g.sband.n_channels; i++) {
127 chan = &phy->sband_5g.sband.channels[i];
128 if (chan->flags & IEEE80211_CHAN_DISABLED)
129 continue;
130
131 channel.hw_value = cpu_to_le16(chan->hw_value);
132 channel.flags = cpu_to_le32(chan->flags);
133 channel.pad = 0;
134
135 skb_put_data(skb, &channel, sizeof(channel));
136 n_5ch++;
137 }
138
139 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(hdr.alpha2));
140 memcpy(hdr.alpha2, dev->alpha2, sizeof(dev->alpha2));
141 hdr.n_2ch = n_2ch;
142 hdr.n_5ch = n_5ch;
143
144 memcpy(__skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
145
146 return mt76_mcu_skb_send_msg(dev, skb, MCU_CMD_SET_CHAN_DOMAIN, false);
147}
148EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
149
150int mt76_connac_mcu_set_mac_enable(struct mt76_dev *dev, int band, bool enable,
151 bool hdr_trans)
152{
153 struct {
154 u8 enable;
155 u8 band;
156 u8 rsv[2];
157 } __packed req_mac = {
158 .enable = enable,
159 .band = band,
160 };
161
162 return mt76_mcu_send_msg(dev, MCU_EXT_CMD_MAC_INIT_CTRL, &req_mac,
163 sizeof(req_mac), true);
164}
165EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
166
167int mt76_connac_mcu_set_vif_ps(struct mt76_dev *dev, struct ieee80211_vif *vif)
168{
169 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
170 struct {
171 u8 bss_idx;
172 u8 ps_state;
173
174
175
176 } req = {
177 .bss_idx = mvif->idx,
178 .ps_state = vif->bss_conf.ps ? 2 : 0,
179 };
180
181 if (vif->type != NL80211_IFTYPE_STATION)
182 return -EOPNOTSUPP;
183
184 return mt76_mcu_send_msg(dev, MCU_CMD_SET_PS_PROFILE, &req,
185 sizeof(req), false);
186}
187EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
188
189int mt76_connac_mcu_set_rts_thresh(struct mt76_dev *dev, u32 val, u8 band)
190{
191 struct {
192 u8 prot_idx;
193 u8 band;
194 u8 rsv[2];
195 __le32 len_thresh;
196 __le32 pkt_thresh;
197 } __packed req = {
198 .prot_idx = 1,
199 .band = band,
200 .len_thresh = cpu_to_le32(val),
201 .pkt_thresh = cpu_to_le32(0x2),
202 };
203
204 return mt76_mcu_send_msg(dev, MCU_EXT_CMD_PROTECT_CTRL, &req,
205 sizeof(req), true);
206}
207EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
208
209void mt76_connac_mcu_beacon_loss_iter(void *priv, u8 *mac,
210 struct ieee80211_vif *vif)
211{
212 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
213 struct mt76_connac_beacon_loss_event *event = priv;
214
215 if (mvif->idx != event->bss_idx)
216 return;
217
218 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
219 return;
220
221 ieee80211_beacon_loss(vif);
222}
223EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
224
225struct tlv *
226mt76_connac_mcu_add_nested_tlv(struct sk_buff *skb, int tag, int len,
227 void *sta_ntlv, void *sta_wtbl)
228{
229 struct sta_ntlv_hdr *ntlv_hdr = sta_ntlv;
230 struct tlv *sta_hdr = sta_wtbl;
231 struct tlv *ptlv, tlv = {
232 .tag = cpu_to_le16(tag),
233 .len = cpu_to_le16(len),
234 };
235 u16 ntlv;
236
237 ptlv = skb_put(skb, len);
238 memcpy(ptlv, &tlv, sizeof(tlv));
239
240 ntlv = le16_to_cpu(ntlv_hdr->tlv_num);
241 ntlv_hdr->tlv_num = cpu_to_le16(ntlv + 1);
242
243 if (sta_hdr) {
244 u16 size = le16_to_cpu(sta_hdr->len);
245
246 sta_hdr->len = cpu_to_le16(size + len);
247 }
248
249 return ptlv;
250}
251EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
252
253struct sk_buff *
254mt76_connac_mcu_alloc_sta_req(struct mt76_dev *dev, struct mt76_vif *mvif,
255 struct mt76_wcid *wcid)
256{
257 struct sta_req_hdr hdr = {
258 .bss_idx = mvif->idx,
259 .muar_idx = wcid ? mvif->omac_idx : 0,
260 .is_tlv_append = 1,
261 };
262 struct sk_buff *skb;
263
264 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
265 &hdr.wlan_idx_hi);
266 skb = mt76_mcu_msg_alloc(dev, NULL, MT76_CONNAC_STA_UPDATE_MAX_SIZE);
267 if (!skb)
268 return ERR_PTR(-ENOMEM);
269
270 skb_put_data(skb, &hdr, sizeof(hdr));
271
272 return skb;
273}
274EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_sta_req);
275
276struct wtbl_req_hdr *
277mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev *dev, struct mt76_wcid *wcid,
278 int cmd, void *sta_wtbl, struct sk_buff **skb)
279{
280 struct tlv *sta_hdr = sta_wtbl;
281 struct wtbl_req_hdr hdr = {
282 .operation = cmd,
283 };
284 struct sk_buff *nskb = *skb;
285
286 mt76_connac_mcu_get_wlan_idx(dev, wcid, &hdr.wlan_idx_lo,
287 &hdr.wlan_idx_hi);
288 if (!nskb) {
289 nskb = mt76_mcu_msg_alloc(dev, NULL,
290 MT76_CONNAC_WTBL_UPDATE_MAX_SIZE);
291 if (!nskb)
292 return ERR_PTR(-ENOMEM);
293
294 *skb = nskb;
295 }
296
297 if (sta_hdr)
298 sta_hdr->len = cpu_to_le16(sizeof(hdr));
299
300 return skb_put_data(nskb, &hdr, sizeof(hdr));
301}
302EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
303
304void mt76_connac_mcu_sta_basic_tlv(struct sk_buff *skb,
305 struct ieee80211_vif *vif,
306 struct ieee80211_sta *sta,
307 bool enable, bool newly)
308{
309 struct sta_rec_basic *basic;
310 struct tlv *tlv;
311 int conn_type;
312
313 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
314
315 basic = (struct sta_rec_basic *)tlv;
316 basic->extra_info = cpu_to_le16(EXTRA_INFO_VER);
317
318 if (enable) {
319 if (newly)
320 basic->extra_info |= cpu_to_le16(EXTRA_INFO_NEW);
321 basic->conn_state = CONN_STATE_PORT_SECURE;
322 } else {
323 basic->conn_state = CONN_STATE_DISCONNECT;
324 }
325
326 if (!sta) {
327 basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
328 eth_broadcast_addr(basic->peer_addr);
329 return;
330 }
331
332 switch (vif->type) {
333 case NL80211_IFTYPE_MESH_POINT:
334 case NL80211_IFTYPE_AP:
335 if (vif->p2p)
336 conn_type = CONNECTION_P2P_GC;
337 else
338 conn_type = CONNECTION_INFRA_STA;
339 basic->conn_type = cpu_to_le32(conn_type);
340 basic->aid = cpu_to_le16(sta->aid);
341 break;
342 case NL80211_IFTYPE_STATION:
343 if (vif->p2p)
344 conn_type = CONNECTION_P2P_GO;
345 else
346 conn_type = CONNECTION_INFRA_AP;
347 basic->conn_type = cpu_to_le32(conn_type);
348 basic->aid = cpu_to_le16(vif->bss_conf.aid);
349 break;
350 case NL80211_IFTYPE_ADHOC:
351 basic->conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
352 basic->aid = cpu_to_le16(sta->aid);
353 break;
354 default:
355 WARN_ON(1);
356 break;
357 }
358
359 memcpy(basic->peer_addr, sta->addr, ETH_ALEN);
360 basic->qos = sta->wme;
361}
362EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
363
364static void
365mt76_connac_mcu_sta_uapsd(struct sk_buff *skb, struct ieee80211_vif *vif,
366 struct ieee80211_sta *sta)
367{
368 struct sta_rec_uapsd *uapsd;
369 struct tlv *tlv;
370
371 if (vif->type != NL80211_IFTYPE_AP || !sta->wme)
372 return;
373
374 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_APPS, sizeof(*uapsd));
375 uapsd = (struct sta_rec_uapsd *)tlv;
376
377 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) {
378 uapsd->dac_map |= BIT(3);
379 uapsd->tac_map |= BIT(3);
380 }
381 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) {
382 uapsd->dac_map |= BIT(2);
383 uapsd->tac_map |= BIT(2);
384 }
385 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) {
386 uapsd->dac_map |= BIT(1);
387 uapsd->tac_map |= BIT(1);
388 }
389 if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) {
390 uapsd->dac_map |= BIT(0);
391 uapsd->tac_map |= BIT(0);
392 }
393 uapsd->max_sp = sta->max_sp;
394}
395
396void mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff *skb,
397 struct ieee80211_vif *vif,
398 struct mt76_wcid *wcid,
399 void *sta_wtbl, void *wtbl_tlv)
400{
401 struct wtbl_hdr_trans *htr;
402 struct tlv *tlv;
403
404 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HDR_TRANS,
405 sizeof(*htr),
406 wtbl_tlv, sta_wtbl);
407 htr = (struct wtbl_hdr_trans *)tlv;
408 htr->no_rx_trans = !test_bit(MT_WCID_FLAG_HDR_TRANS, &wcid->flags);
409
410 if (vif->type == NL80211_IFTYPE_STATION)
411 htr->to_ds = true;
412 else
413 htr->from_ds = true;
414
415 if (test_bit(MT_WCID_FLAG_4ADDR, &wcid->flags)) {
416 htr->to_ds = true;
417 htr->from_ds = true;
418 }
419}
420EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
421
422int mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev *dev,
423 struct ieee80211_vif *vif,
424 struct mt76_wcid *wcid, int cmd)
425{
426 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
427 struct wtbl_req_hdr *wtbl_hdr;
428 struct tlv *sta_wtbl;
429 struct sk_buff *skb;
430
431 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
432 if (IS_ERR(skb))
433 return PTR_ERR(skb);
434
435 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
436 sizeof(struct tlv));
437
438 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
439 sta_wtbl, &skb);
440 if (IS_ERR(wtbl_hdr))
441 return PTR_ERR(wtbl_hdr);
442
443 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, vif, wcid, sta_wtbl, wtbl_hdr);
444
445 return mt76_mcu_skb_send_msg(dev, skb, cmd, true);
446}
447EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
448
449void mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev *dev,
450 struct sk_buff *skb,
451 struct ieee80211_vif *vif,
452 struct ieee80211_sta *sta,
453 void *sta_wtbl, void *wtbl_tlv)
454{
455 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
456 struct wtbl_generic *generic;
457 struct wtbl_rx *rx;
458 struct wtbl_spe *spe;
459 struct tlv *tlv;
460
461 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_GENERIC,
462 sizeof(*generic),
463 wtbl_tlv, sta_wtbl);
464
465 generic = (struct wtbl_generic *)tlv;
466
467 if (sta) {
468 if (vif->type == NL80211_IFTYPE_STATION)
469 generic->partial_aid = cpu_to_le16(vif->bss_conf.aid);
470 else
471 generic->partial_aid = cpu_to_le16(sta->aid);
472 memcpy(generic->peer_addr, sta->addr, ETH_ALEN);
473 generic->muar_idx = mvif->omac_idx;
474 generic->qos = sta->wme;
475 } else {
476 if (is_mt7921(dev) &&
477 vif->type == NL80211_IFTYPE_STATION)
478 memcpy(generic->peer_addr, vif->bss_conf.bssid,
479 ETH_ALEN);
480 else
481 eth_broadcast_addr(generic->peer_addr);
482
483 generic->muar_idx = 0xe;
484 }
485
486 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RX, sizeof(*rx),
487 wtbl_tlv, sta_wtbl);
488
489 rx = (struct wtbl_rx *)tlv;
490 rx->rca1 = sta ? vif->type != NL80211_IFTYPE_AP : 1;
491 rx->rca2 = 1;
492 rx->rv = 1;
493
494 if (is_mt7921(dev))
495 return;
496
497 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SPE, sizeof(*spe),
498 wtbl_tlv, sta_wtbl);
499 spe = (struct wtbl_spe *)tlv;
500 spe->spe_idx = 24;
501}
502EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
503
504static void
505mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
506 struct ieee80211_vif *vif)
507{
508 struct mt76_wcid *wcid = (struct mt76_wcid *)sta->drv_priv;
509 struct sta_rec_amsdu *amsdu;
510 struct tlv *tlv;
511
512 if (vif->type != NL80211_IFTYPE_AP &&
513 vif->type != NL80211_IFTYPE_STATION)
514 return;
515
516 if (!sta->max_amsdu_len)
517 return;
518
519 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HW_AMSDU, sizeof(*amsdu));
520 amsdu = (struct sta_rec_amsdu *)tlv;
521 amsdu->max_amsdu_num = 8;
522 amsdu->amsdu_en = true;
523 amsdu->max_mpdu_size = sta->max_amsdu_len >=
524 IEEE80211_MAX_MPDU_LEN_VHT_7991;
525
526 wcid->amsdu = true;
527}
528
529#define HE_PHY(p, c) u8_get_bits(c, IEEE80211_HE_PHY_##p)
530#define HE_MAC(m, c) u8_get_bits(c, IEEE80211_HE_MAC_##m)
531static void
532mt76_connac_mcu_sta_he_tlv(struct sk_buff *skb, struct ieee80211_sta *sta)
533{
534 struct ieee80211_sta_he_cap *he_cap = &sta->he_cap;
535 struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
536 struct sta_rec_he *he;
537 struct tlv *tlv;
538 u32 cap = 0;
539
540 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HE, sizeof(*he));
541
542 he = (struct sta_rec_he *)tlv;
543
544 if (elem->mac_cap_info[0] & IEEE80211_HE_MAC_CAP0_HTC_HE)
545 cap |= STA_REC_HE_CAP_HTC;
546
547 if (elem->mac_cap_info[2] & IEEE80211_HE_MAC_CAP2_BSR)
548 cap |= STA_REC_HE_CAP_BSR;
549
550 if (elem->mac_cap_info[3] & IEEE80211_HE_MAC_CAP3_OMI_CONTROL)
551 cap |= STA_REC_HE_CAP_OM;
552
553 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_AMSDU_IN_AMPDU)
554 cap |= STA_REC_HE_CAP_AMSDU_IN_AMPDU;
555
556 if (elem->mac_cap_info[4] & IEEE80211_HE_MAC_CAP4_BQR)
557 cap |= STA_REC_HE_CAP_BQR;
558
559 if (elem->phy_cap_info[0] &
560 (IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G |
561 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G))
562 cap |= STA_REC_HE_CAP_BW20_RU242_SUPPORT;
563
564 if (elem->phy_cap_info[1] &
565 IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD)
566 cap |= STA_REC_HE_CAP_LDPC;
567
568 if (elem->phy_cap_info[1] &
569 IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US)
570 cap |= STA_REC_HE_CAP_SU_PPDU_1LTF_8US_GI;
571
572 if (elem->phy_cap_info[2] &
573 IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US)
574 cap |= STA_REC_HE_CAP_NDP_4LTF_3DOT2MS_GI;
575
576 if (elem->phy_cap_info[2] &
577 IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ)
578 cap |= STA_REC_HE_CAP_LE_EQ_80M_TX_STBC;
579
580 if (elem->phy_cap_info[2] &
581 IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ)
582 cap |= STA_REC_HE_CAP_LE_EQ_80M_RX_STBC;
583
584 if (elem->phy_cap_info[6] &
585 IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE)
586 cap |= STA_REC_HE_CAP_PARTIAL_BW_EXT_RANGE;
587
588 if (elem->phy_cap_info[7] &
589 IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI)
590 cap |= STA_REC_HE_CAP_SU_MU_PPDU_4LTF_8US_GI;
591
592 if (elem->phy_cap_info[7] &
593 IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ)
594 cap |= STA_REC_HE_CAP_GT_80M_TX_STBC;
595
596 if (elem->phy_cap_info[7] &
597 IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ)
598 cap |= STA_REC_HE_CAP_GT_80M_RX_STBC;
599
600 if (elem->phy_cap_info[8] &
601 IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI)
602 cap |= STA_REC_HE_CAP_ER_SU_PPDU_4LTF_8US_GI;
603
604 if (elem->phy_cap_info[8] &
605 IEEE80211_HE_PHY_CAP8_HE_ER_SU_1XLTF_AND_08_US_GI)
606 cap |= STA_REC_HE_CAP_ER_SU_PPDU_1LTF_8US_GI;
607
608 if (elem->phy_cap_info[9] &
609 IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK)
610 cap |= STA_REC_HE_CAP_TRIG_CQI_FK;
611
612 if (elem->phy_cap_info[9] &
613 IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU)
614 cap |= STA_REC_HE_CAP_TX_1024QAM_UNDER_RU242;
615
616 if (elem->phy_cap_info[9] &
617 IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU)
618 cap |= STA_REC_HE_CAP_RX_1024QAM_UNDER_RU242;
619
620 he->he_cap = cpu_to_le32(cap);
621
622 switch (sta->bandwidth) {
623 case IEEE80211_STA_RX_BW_160:
624 if (elem->phy_cap_info[0] &
625 IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G)
626 he->max_nss_mcs[CMD_HE_MCS_BW8080] =
627 he_cap->he_mcs_nss_supp.rx_mcs_80p80;
628
629 he->max_nss_mcs[CMD_HE_MCS_BW160] =
630 he_cap->he_mcs_nss_supp.rx_mcs_160;
631 fallthrough;
632 default:
633 he->max_nss_mcs[CMD_HE_MCS_BW80] =
634 he_cap->he_mcs_nss_supp.rx_mcs_80;
635 break;
636 }
637
638 he->t_frame_dur =
639 HE_MAC(CAP1_TF_MAC_PAD_DUR_MASK, elem->mac_cap_info[1]);
640 he->max_ampdu_exp =
641 HE_MAC(CAP3_MAX_AMPDU_LEN_EXP_MASK, elem->mac_cap_info[3]);
642
643 he->bw_set =
644 HE_PHY(CAP0_CHANNEL_WIDTH_SET_MASK, elem->phy_cap_info[0]);
645 he->device_class =
646 HE_PHY(CAP1_DEVICE_CLASS_A, elem->phy_cap_info[1]);
647 he->punc_pream_rx =
648 HE_PHY(CAP1_PREAMBLE_PUNC_RX_MASK, elem->phy_cap_info[1]);
649
650 he->dcm_tx_mode =
651 HE_PHY(CAP3_DCM_MAX_CONST_TX_MASK, elem->phy_cap_info[3]);
652 he->dcm_tx_max_nss =
653 HE_PHY(CAP3_DCM_MAX_TX_NSS_2, elem->phy_cap_info[3]);
654 he->dcm_rx_mode =
655 HE_PHY(CAP3_DCM_MAX_CONST_RX_MASK, elem->phy_cap_info[3]);
656 he->dcm_rx_max_nss =
657 HE_PHY(CAP3_DCM_MAX_RX_NSS_2, elem->phy_cap_info[3]);
658 he->dcm_rx_max_nss =
659 HE_PHY(CAP8_DCM_MAX_RU_MASK, elem->phy_cap_info[8]);
660
661 he->pkt_ext = 2;
662}
663
664static u8
665mt76_connac_get_phy_mode_v2(struct mt76_phy *mphy, struct ieee80211_vif *vif,
666 enum nl80211_band band, struct ieee80211_sta *sta)
667{
668 struct ieee80211_sta_ht_cap *ht_cap;
669 struct ieee80211_sta_vht_cap *vht_cap;
670 const struct ieee80211_sta_he_cap *he_cap;
671 u8 mode = 0;
672
673 if (sta) {
674 ht_cap = &sta->ht_cap;
675 vht_cap = &sta->vht_cap;
676 he_cap = &sta->he_cap;
677 } else {
678 struct ieee80211_supported_band *sband;
679
680 sband = mphy->hw->wiphy->bands[band];
681 ht_cap = &sband->ht_cap;
682 vht_cap = &sband->vht_cap;
683 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
684 }
685
686 if (band == NL80211_BAND_2GHZ) {
687 mode |= PHY_TYPE_BIT_HR_DSSS | PHY_TYPE_BIT_ERP;
688
689 if (ht_cap->ht_supported)
690 mode |= PHY_TYPE_BIT_HT;
691
692 if (he_cap->has_he)
693 mode |= PHY_TYPE_BIT_HE;
694 } else if (band == NL80211_BAND_5GHZ) {
695 mode |= PHY_TYPE_BIT_OFDM;
696
697 if (ht_cap->ht_supported)
698 mode |= PHY_TYPE_BIT_HT;
699
700 if (vht_cap->vht_supported)
701 mode |= PHY_TYPE_BIT_VHT;
702
703 if (he_cap->has_he)
704 mode |= PHY_TYPE_BIT_HE;
705 }
706
707 return mode;
708}
709
710void mt76_connac_mcu_sta_tlv(struct mt76_phy *mphy, struct sk_buff *skb,
711 struct ieee80211_sta *sta,
712 struct ieee80211_vif *vif,
713 u8 rcpi, u8 sta_state)
714{
715 struct cfg80211_chan_def *chandef = &mphy->chandef;
716 enum nl80211_band band = chandef->chan->band;
717 struct mt76_dev *dev = mphy->dev;
718 struct sta_rec_ra_info *ra_info;
719 struct sta_rec_state *state;
720 struct sta_rec_phy *phy;
721 struct tlv *tlv;
722
723
724 if (sta->ht_cap.ht_supported) {
725 struct sta_rec_ht *ht;
726
727 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
728 ht = (struct sta_rec_ht *)tlv;
729 ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
730 }
731
732
733 if (sta->vht_cap.vht_supported) {
734 struct sta_rec_vht *vht;
735 int len;
736
737 len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
738 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
739 vht = (struct sta_rec_vht *)tlv;
740 vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
741 vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
742 vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
743 }
744
745
746 mt76_connac_mcu_sta_uapsd(skb, vif, sta);
747
748 if (!is_mt7921(dev))
749 return;
750
751 if (sta->ht_cap.ht_supported)
752 mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
753
754
755 if (sta->he_cap.has_he)
756 mt76_connac_mcu_sta_he_tlv(skb, sta);
757
758 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
759 phy = (struct sta_rec_phy *)tlv;
760 phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
761 phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
762 phy->rcpi = rcpi;
763 phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
764 sta->ht_cap.ampdu_factor) |
765 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
766 sta->ht_cap.ampdu_density);
767
768 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
769 ra_info = (struct sta_rec_ra_info *)tlv;
770 ra_info->legacy = cpu_to_le16((u16)sta->supp_rates[band]);
771
772 if (sta->ht_cap.ht_supported)
773 memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask,
774 HT_MCS_MASK_NUM);
775
776 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
777 state = (struct sta_rec_state *)tlv;
778 state->state = sta_state;
779
780 if (sta->vht_cap.vht_supported) {
781 state->vht_opmode = sta->bandwidth;
782 state->vht_opmode |= (sta->rx_nss - 1) <<
783 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
784 }
785}
786EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
787
788static void
789mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
790 void *sta_wtbl, void *wtbl_tlv)
791{
792 struct wtbl_smps *smps;
793 struct tlv *tlv;
794
795 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
796 wtbl_tlv, sta_wtbl);
797 smps = (struct wtbl_smps *)tlv;
798
799 if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
800 smps->smps = true;
801}
802
803void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
804 struct ieee80211_sta *sta, void *sta_wtbl,
805 void *wtbl_tlv)
806{
807 struct wtbl_ht *ht = NULL;
808 struct tlv *tlv;
809 u32 flags = 0;
810
811 if (sta->ht_cap.ht_supported) {
812 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
813 wtbl_tlv, sta_wtbl);
814 ht = (struct wtbl_ht *)tlv;
815 ht->ldpc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
816 ht->af = sta->ht_cap.ampdu_factor;
817 ht->mm = sta->ht_cap.ampdu_density;
818 ht->ht = true;
819 }
820
821 if (sta->vht_cap.vht_supported) {
822 struct wtbl_vht *vht;
823 u8 af;
824
825 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
826 sizeof(*vht), wtbl_tlv,
827 sta_wtbl);
828 vht = (struct wtbl_vht *)tlv;
829 vht->ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
830 vht->vht = true;
831
832 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
833 sta->vht_cap.cap);
834 if (ht)
835 ht->af = max(ht->af, af);
836 }
837
838 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
839
840 if (!is_mt7921(dev) && sta->ht_cap.ht_supported) {
841
842 u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
843 MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
844 struct wtbl_raw *raw;
845
846 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
847 sizeof(*raw), wtbl_tlv,
848 sta_wtbl);
849
850 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
851 flags |= MT_WTBL_W5_SHORT_GI_20;
852 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
853 flags |= MT_WTBL_W5_SHORT_GI_40;
854
855 if (sta->vht_cap.vht_supported) {
856 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
857 flags |= MT_WTBL_W5_SHORT_GI_80;
858 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
859 flags |= MT_WTBL_W5_SHORT_GI_160;
860 }
861 raw = (struct wtbl_raw *)tlv;
862 raw->val = cpu_to_le32(flags);
863 raw->msk = cpu_to_le32(~msk);
864 raw->wtbl_idx = 1;
865 raw->dw = 5;
866 }
867}
868EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
869
870int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
871 struct mt76_sta_cmd_info *info)
872{
873 struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
874 struct mt76_dev *dev = phy->dev;
875 struct wtbl_req_hdr *wtbl_hdr;
876 struct tlv *sta_wtbl;
877 struct sk_buff *skb;
878
879 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
880 if (IS_ERR(skb))
881 return PTR_ERR(skb);
882
883 if (info->sta || !info->offload_fw)
884 mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
885 info->enable, info->newly);
886 if (info->sta && info->enable)
887 mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
888 info->vif, info->rcpi,
889 info->state);
890
891 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
892 sizeof(struct tlv));
893
894 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
895 WTBL_RESET_AND_SET,
896 sta_wtbl, &skb);
897 if (IS_ERR(wtbl_hdr))
898 return PTR_ERR(wtbl_hdr);
899
900 if (info->enable) {
901 mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
902 info->sta, sta_wtbl,
903 wtbl_hdr);
904 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
905 sta_wtbl, wtbl_hdr);
906 if (info->sta)
907 mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
908 sta_wtbl, wtbl_hdr);
909 }
910
911 return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
912}
913EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
914
915void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
916 struct ieee80211_ampdu_params *params,
917 bool enable, bool tx, void *sta_wtbl,
918 void *wtbl_tlv)
919{
920 struct wtbl_ba *ba;
921 struct tlv *tlv;
922
923 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
924 wtbl_tlv, sta_wtbl);
925
926 ba = (struct wtbl_ba *)tlv;
927 ba->tid = params->tid;
928
929 if (tx) {
930 ba->ba_type = MT_BA_TYPE_ORIGINATOR;
931 ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
932 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
933 ba->ba_en = enable;
934 } else {
935 memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
936 ba->ba_type = MT_BA_TYPE_RECIPIENT;
937 ba->rst_ba_tid = params->tid;
938 ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
939 ba->rst_ba_sb = 1;
940 }
941
942 if (is_mt7921(dev)) {
943 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
944 return;
945 }
946
947 if (enable && tx) {
948 u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
949 int i;
950
951 for (i = 7; i > 0; i--) {
952 if (params->buf_size >= ba_range[i])
953 break;
954 }
955 ba->ba_winsize_idx = i;
956 }
957}
958EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
959
960int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
961 struct ieee80211_vif *vif,
962 struct mt76_wcid *wcid,
963 bool enable)
964{
965 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
966 struct mt76_dev *dev = phy->dev;
967 struct {
968 struct {
969 u8 omac_idx;
970 u8 band_idx;
971 __le16 pad;
972 } __packed hdr;
973 struct req_tlv {
974 __le16 tag;
975 __le16 len;
976 u8 active;
977 u8 pad;
978 u8 omac_addr[ETH_ALEN];
979 } __packed tlv;
980 } dev_req = {
981 .hdr = {
982 .omac_idx = mvif->omac_idx,
983 .band_idx = mvif->band_idx,
984 },
985 .tlv = {
986 .tag = cpu_to_le16(DEV_INFO_ACTIVE),
987 .len = cpu_to_le16(sizeof(struct req_tlv)),
988 .active = enable,
989 },
990 };
991 struct {
992 struct {
993 u8 bss_idx;
994 u8 pad[3];
995 } __packed hdr;
996 struct mt76_connac_bss_basic_tlv basic;
997 } basic_req = {
998 .hdr = {
999 .bss_idx = mvif->idx,
1000 },
1001 .basic = {
1002 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1003 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1004 .omac_idx = mvif->omac_idx,
1005 .band_idx = mvif->band_idx,
1006 .wmm_idx = mvif->wmm_idx,
1007 .active = enable,
1008 .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
1009 .sta_idx = cpu_to_le16(wcid->idx),
1010 .conn_state = 1,
1011 },
1012 };
1013 int err, idx, cmd, len;
1014 void *data;
1015
1016 switch (vif->type) {
1017 case NL80211_IFTYPE_MESH_POINT:
1018 case NL80211_IFTYPE_MONITOR:
1019 case NL80211_IFTYPE_AP:
1020 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
1021 break;
1022 case NL80211_IFTYPE_STATION:
1023 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
1024 break;
1025 case NL80211_IFTYPE_ADHOC:
1026 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1027 break;
1028 default:
1029 WARN_ON(1);
1030 break;
1031 }
1032
1033 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1034 basic_req.basic.hw_bss_idx = idx;
1035
1036 memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
1037
1038 cmd = enable ? MCU_UNI_CMD_DEV_INFO_UPDATE : MCU_UNI_CMD_BSS_INFO_UPDATE;
1039 data = enable ? (void *)&dev_req : (void *)&basic_req;
1040 len = enable ? sizeof(dev_req) : sizeof(basic_req);
1041
1042 err = mt76_mcu_send_msg(dev, cmd, data, len, true);
1043 if (err < 0)
1044 return err;
1045
1046 cmd = enable ? MCU_UNI_CMD_BSS_INFO_UPDATE : MCU_UNI_CMD_DEV_INFO_UPDATE;
1047 data = enable ? (void *)&basic_req : (void *)&dev_req;
1048 len = enable ? sizeof(basic_req) : sizeof(dev_req);
1049
1050 return mt76_mcu_send_msg(dev, cmd, data, len, true);
1051}
1052EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
1053
1054void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
1055 struct ieee80211_ampdu_params *params,
1056 bool enable, bool tx)
1057{
1058 struct sta_rec_ba *ba;
1059 struct tlv *tlv;
1060
1061 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
1062
1063 ba = (struct sta_rec_ba *)tlv;
1064 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
1065 ba->winsize = cpu_to_le16(params->buf_size);
1066 ba->ssn = cpu_to_le16(params->ssn);
1067 ba->ba_en = enable << params->tid;
1068 ba->amsdu = params->amsdu;
1069 ba->tid = params->tid;
1070}
1071EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
1072
1073int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
1074 struct ieee80211_ampdu_params *params,
1075 bool enable, bool tx)
1076{
1077 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
1078 struct wtbl_req_hdr *wtbl_hdr;
1079 struct tlv *sta_wtbl;
1080 struct sk_buff *skb;
1081 int ret;
1082
1083 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1084 if (IS_ERR(skb))
1085 return PTR_ERR(skb);
1086
1087 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1088 sizeof(struct tlv));
1089
1090 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
1091 sta_wtbl, &skb);
1092 if (IS_ERR(wtbl_hdr))
1093 return PTR_ERR(wtbl_hdr);
1094
1095 mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
1096 wtbl_hdr);
1097
1098 ret = mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE, true);
1099 if (ret)
1100 return ret;
1101
1102 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1103 if (IS_ERR(skb))
1104 return PTR_ERR(skb);
1105
1106 mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
1107
1108 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE,
1109 true);
1110}
1111EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
1112
1113static u8
1114mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
1115 enum nl80211_band band,
1116 struct ieee80211_sta *sta)
1117{
1118 struct mt76_dev *dev = phy->dev;
1119 const struct ieee80211_sta_he_cap *he_cap;
1120 struct ieee80211_sta_vht_cap *vht_cap;
1121 struct ieee80211_sta_ht_cap *ht_cap;
1122 u8 mode = 0;
1123
1124 if (!is_mt7921(dev))
1125 return 0x38;
1126
1127 if (sta) {
1128 ht_cap = &sta->ht_cap;
1129 vht_cap = &sta->vht_cap;
1130 he_cap = &sta->he_cap;
1131 } else {
1132 struct ieee80211_supported_band *sband;
1133
1134 sband = phy->hw->wiphy->bands[band];
1135 ht_cap = &sband->ht_cap;
1136 vht_cap = &sband->vht_cap;
1137 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
1138 }
1139
1140 if (band == NL80211_BAND_2GHZ) {
1141 mode |= PHY_MODE_B | PHY_MODE_G;
1142
1143 if (ht_cap->ht_supported)
1144 mode |= PHY_MODE_GN;
1145
1146 if (he_cap->has_he)
1147 mode |= PHY_MODE_AX_24G;
1148 } else if (band == NL80211_BAND_5GHZ) {
1149 mode |= PHY_MODE_A;
1150
1151 if (ht_cap->ht_supported)
1152 mode |= PHY_MODE_AN;
1153
1154 if (vht_cap->vht_supported)
1155 mode |= PHY_MODE_AC;
1156
1157 if (he_cap->has_he)
1158 mode |= PHY_MODE_AX_5G;
1159 }
1160
1161 return mode;
1162}
1163
1164static const struct ieee80211_sta_he_cap *
1165mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1166{
1167 enum nl80211_band band = phy->chandef.chan->band;
1168 struct ieee80211_supported_band *sband;
1169
1170 sband = phy->hw->wiphy->bands[band];
1171
1172 return ieee80211_get_he_iftype_cap(sband, vif->type);
1173}
1174
1175#define DEFAULT_HE_PE_DURATION 4
1176#define DEFAULT_HE_DURATION_RTS_THRES 1023
1177static void
1178mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
1179 struct tlv *tlv)
1180{
1181 const struct ieee80211_sta_he_cap *cap;
1182 struct bss_info_uni_he *he;
1183
1184 cap = mt76_connac_get_he_phy_cap(phy, vif);
1185
1186 he = (struct bss_info_uni_he *)tlv;
1187 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
1188 if (!he->he_pe_duration)
1189 he->he_pe_duration = DEFAULT_HE_PE_DURATION;
1190
1191 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
1192 if (!he->he_rts_thres)
1193 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
1194
1195 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
1196 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
1197 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
1198}
1199
1200int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
1201 struct ieee80211_vif *vif,
1202 struct mt76_wcid *wcid,
1203 bool enable)
1204{
1205 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1206 struct cfg80211_chan_def *chandef = &phy->chandef;
1207 int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1208 enum nl80211_band band = chandef->chan->band;
1209 struct mt76_dev *mdev = phy->dev;
1210 struct {
1211 struct {
1212 u8 bss_idx;
1213 u8 pad[3];
1214 } __packed hdr;
1215 struct mt76_connac_bss_basic_tlv basic;
1216 struct mt76_connac_bss_qos_tlv qos;
1217 } basic_req = {
1218 .hdr = {
1219 .bss_idx = mvif->idx,
1220 },
1221 .basic = {
1222 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1223 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1224 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1225 .dtim_period = vif->bss_conf.dtim_period,
1226 .omac_idx = mvif->omac_idx,
1227 .band_idx = mvif->band_idx,
1228 .wmm_idx = mvif->wmm_idx,
1229 .active = true,
1230 .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
1231 },
1232 .qos = {
1233 .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
1234 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
1235 .qos = vif->bss_conf.qos,
1236 },
1237 };
1238 struct {
1239 struct {
1240 u8 bss_idx;
1241 u8 pad[3];
1242 } __packed hdr;
1243 struct rlm_tlv {
1244 __le16 tag;
1245 __le16 len;
1246 u8 control_channel;
1247 u8 center_chan;
1248 u8 center_chan2;
1249 u8 bw;
1250 u8 tx_streams;
1251 u8 rx_streams;
1252 u8 short_st;
1253 u8 ht_op_info;
1254 u8 sco;
1255 u8 pad[3];
1256 } __packed rlm;
1257 } __packed rlm_req = {
1258 .hdr = {
1259 .bss_idx = mvif->idx,
1260 },
1261 .rlm = {
1262 .tag = cpu_to_le16(UNI_BSS_INFO_RLM),
1263 .len = cpu_to_le16(sizeof(struct rlm_tlv)),
1264 .control_channel = chandef->chan->hw_value,
1265 .center_chan = ieee80211_frequency_to_channel(freq1),
1266 .center_chan2 = ieee80211_frequency_to_channel(freq2),
1267 .tx_streams = hweight8(phy->antenna_mask),
1268 .ht_op_info = 4,
1269 .rx_streams = phy->chainmask,
1270 .short_st = true,
1271 },
1272 };
1273 int err, conn_type;
1274 u8 idx;
1275
1276 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1277 basic_req.basic.hw_bss_idx = idx;
1278
1279 switch (vif->type) {
1280 case NL80211_IFTYPE_MESH_POINT:
1281 case NL80211_IFTYPE_AP:
1282 if (vif->p2p)
1283 conn_type = CONNECTION_P2P_GO;
1284 else
1285 conn_type = CONNECTION_INFRA_AP;
1286 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1287 break;
1288 case NL80211_IFTYPE_STATION:
1289 if (vif->p2p)
1290 conn_type = CONNECTION_P2P_GC;
1291 else
1292 conn_type = CONNECTION_INFRA_STA;
1293 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1294 break;
1295 case NL80211_IFTYPE_ADHOC:
1296 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1297 break;
1298 default:
1299 WARN_ON(1);
1300 break;
1301 }
1302
1303 memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
1304 basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
1305 basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
1306 basic_req.basic.conn_state = !enable;
1307
1308 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &basic_req,
1309 sizeof(basic_req), true);
1310 if (err < 0)
1311 return err;
1312
1313 if (vif->bss_conf.he_support) {
1314 struct {
1315 struct {
1316 u8 bss_idx;
1317 u8 pad[3];
1318 } __packed hdr;
1319 struct bss_info_uni_he he;
1320 struct bss_info_uni_bss_color bss_color;
1321 } he_req = {
1322 .hdr = {
1323 .bss_idx = mvif->idx,
1324 },
1325 .he = {
1326 .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
1327 .len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
1328 },
1329 .bss_color = {
1330 .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
1331 .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
1332 .enable = 0,
1333 .bss_color = 0,
1334 },
1335 };
1336
1337 if (enable) {
1338 he_req.bss_color.enable =
1339 vif->bss_conf.he_bss_color.enabled;
1340 he_req.bss_color.bss_color =
1341 vif->bss_conf.he_bss_color.color;
1342 }
1343
1344 mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
1345 (struct tlv *)&he_req.he);
1346 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE,
1347 &he_req, sizeof(he_req), true);
1348 if (err < 0)
1349 return err;
1350 }
1351
1352 switch (chandef->width) {
1353 case NL80211_CHAN_WIDTH_40:
1354 rlm_req.rlm.bw = CMD_CBW_40MHZ;
1355 break;
1356 case NL80211_CHAN_WIDTH_80:
1357 rlm_req.rlm.bw = CMD_CBW_80MHZ;
1358 break;
1359 case NL80211_CHAN_WIDTH_80P80:
1360 rlm_req.rlm.bw = CMD_CBW_8080MHZ;
1361 break;
1362 case NL80211_CHAN_WIDTH_160:
1363 rlm_req.rlm.bw = CMD_CBW_160MHZ;
1364 break;
1365 case NL80211_CHAN_WIDTH_5:
1366 rlm_req.rlm.bw = CMD_CBW_5MHZ;
1367 break;
1368 case NL80211_CHAN_WIDTH_10:
1369 rlm_req.rlm.bw = CMD_CBW_10MHZ;
1370 break;
1371 case NL80211_CHAN_WIDTH_20_NOHT:
1372 case NL80211_CHAN_WIDTH_20:
1373 default:
1374 rlm_req.rlm.bw = CMD_CBW_20MHZ;
1375 rlm_req.rlm.ht_op_info = 0;
1376 break;
1377 }
1378
1379 if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
1380 rlm_req.rlm.sco = 1;
1381 else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
1382 rlm_req.rlm.sco = 3;
1383
1384 return mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &rlm_req,
1385 sizeof(rlm_req), true);
1386}
1387EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
1388
1389#define MT76_CONNAC_SCAN_CHANNEL_TIME 60
1390int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
1391 struct ieee80211_scan_request *scan_req)
1392{
1393 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1394 struct cfg80211_scan_request *sreq = &scan_req->req;
1395 int n_ssids = 0, err, i, duration;
1396 int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
1397 struct ieee80211_channel **scan_list = sreq->channels;
1398 struct mt76_dev *mdev = phy->dev;
1399 bool ext_phy = phy == mdev->phy2;
1400 struct mt76_connac_mcu_scan_channel *chan;
1401 struct mt76_connac_hw_scan_req *req;
1402 struct sk_buff *skb;
1403
1404 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
1405 if (!skb)
1406 return -ENOMEM;
1407
1408 set_bit(MT76_HW_SCANNING, &phy->state);
1409 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1410
1411 req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
1412
1413 req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1414 req->bss_idx = mvif->idx;
1415 req->scan_type = sreq->n_ssids ? 1 : 0;
1416 req->probe_req_num = sreq->n_ssids ? 2 : 0;
1417 req->version = 1;
1418
1419 for (i = 0; i < sreq->n_ssids; i++) {
1420 if (!sreq->ssids[i].ssid_len)
1421 continue;
1422
1423 req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
1424 memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
1425 sreq->ssids[i].ssid_len);
1426 n_ssids++;
1427 }
1428 req->ssid_type = n_ssids ? BIT(2) : BIT(0);
1429 req->ssid_type_ext = n_ssids ? BIT(0) : 0;
1430 req->ssids_num = n_ssids;
1431
1432 duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
1433
1434 if (!sreq->n_ssids)
1435 duration *= 2;
1436 req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
1437 req->channel_min_dwell_time = cpu_to_le16(duration);
1438 req->channel_dwell_time = cpu_to_le16(duration);
1439
1440 req->channels_num = min_t(u8, sreq->n_channels, 32);
1441 req->ext_channels_num = min_t(u8, ext_channels_num, 32);
1442 for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
1443 if (i >= 32)
1444 chan = &req->ext_channels[i - 32];
1445 else
1446 chan = &req->channels[i];
1447
1448 chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1449 chan->channel_num = scan_list[i]->hw_value;
1450 }
1451 req->channel_type = sreq->n_channels ? 4 : 0;
1452
1453 if (sreq->ie_len > 0) {
1454 memcpy(req->ies, sreq->ie, sreq->ie_len);
1455 req->ies_len = cpu_to_le16(sreq->ie_len);
1456 }
1457
1458 if (is_mt7921(phy->dev))
1459 req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
1460
1461 memcpy(req->bssid, sreq->bssid, ETH_ALEN);
1462 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1463 get_random_mask_addr(req->random_mac, sreq->mac_addr,
1464 sreq->mac_addr_mask);
1465 req->scan_func |= SCAN_FUNC_RANDOM_MAC;
1466 }
1467
1468 err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
1469 if (err < 0)
1470 clear_bit(MT76_HW_SCANNING, &phy->state);
1471
1472 return err;
1473}
1474EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
1475
1476int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
1477 struct ieee80211_vif *vif)
1478{
1479 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1480 struct {
1481 u8 seq_num;
1482 u8 is_ext_channel;
1483 u8 rsv[2];
1484 } __packed req = {
1485 .seq_num = mvif->scan_seq_num,
1486 };
1487
1488 if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
1489 struct cfg80211_scan_info info = {
1490 .aborted = true,
1491 };
1492
1493 ieee80211_scan_completed(phy->hw, &info);
1494 }
1495
1496 return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
1497 sizeof(req), false);
1498}
1499EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
1500
1501int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
1502 struct ieee80211_vif *vif,
1503 struct cfg80211_sched_scan_request *sreq)
1504{
1505 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1506 struct ieee80211_channel **scan_list = sreq->channels;
1507 struct mt76_connac_mcu_scan_channel *chan;
1508 struct mt76_connac_sched_scan_req *req;
1509 struct mt76_dev *mdev = phy->dev;
1510 bool ext_phy = phy == mdev->phy2;
1511 struct cfg80211_match_set *match;
1512 struct cfg80211_ssid *ssid;
1513 struct sk_buff *skb;
1514 int i;
1515
1516 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
1517 if (!skb)
1518 return -ENOMEM;
1519
1520 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1521
1522 req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
1523 req->version = 1;
1524 req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1525
1526 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1527 u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
1528 : req->mt7921.random_mac;
1529
1530 req->scan_func = 1;
1531 get_random_mask_addr(addr, sreq->mac_addr,
1532 sreq->mac_addr_mask);
1533 }
1534 if (is_mt7921(phy->dev))
1535 req->mt7921.bss_idx = mvif->idx;
1536
1537 req->ssids_num = sreq->n_ssids;
1538 for (i = 0; i < req->ssids_num; i++) {
1539 ssid = &sreq->ssids[i];
1540 memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
1541 req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
1542 }
1543
1544 req->match_num = sreq->n_match_sets;
1545 for (i = 0; i < req->match_num; i++) {
1546 match = &sreq->match_sets[i];
1547 memcpy(req->match[i].ssid, match->ssid.ssid,
1548 match->ssid.ssid_len);
1549 req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
1550 req->match[i].ssid_len = match->ssid.ssid_len;
1551 }
1552
1553 req->channel_type = sreq->n_channels ? 4 : 0;
1554 req->channels_num = min_t(u8, sreq->n_channels, 64);
1555 for (i = 0; i < req->channels_num; i++) {
1556 chan = &req->channels[i];
1557 chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1558 chan->channel_num = scan_list[i]->hw_value;
1559 }
1560
1561 req->intervals_num = sreq->n_scan_plans;
1562 for (i = 0; i < req->intervals_num; i++)
1563 req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
1564
1565 if (sreq->ie_len > 0) {
1566 req->ie_len = cpu_to_le16(sreq->ie_len);
1567 memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
1568 }
1569
1570 return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
1571}
1572EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
1573
1574int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
1575 struct ieee80211_vif *vif,
1576 bool enable)
1577{
1578 struct {
1579 u8 active;
1580 u8 rsv[3];
1581 } __packed req = {
1582 .active = !enable,
1583 };
1584
1585 if (enable)
1586 set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1587 else
1588 clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1589
1590 return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
1591 sizeof(req), false);
1592}
1593EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
1594
1595int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
1596{
1597 struct mt76_connac_config req = {
1598 .resp_type = 0,
1599 };
1600
1601 memcpy(req.data, "assert", 7);
1602
1603 return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1604 false);
1605}
1606EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
1607
1608int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
1609{
1610 struct mt76_connac_config req = {
1611 .resp_type = 0,
1612 };
1613
1614 snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
1615
1616 return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1617 false);
1618}
1619EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
1620
1621int mt76_connac_sta_state_dp(struct mt76_dev *dev,
1622 enum ieee80211_sta_state old_state,
1623 enum ieee80211_sta_state new_state)
1624{
1625 if ((old_state == IEEE80211_STA_ASSOC &&
1626 new_state == IEEE80211_STA_AUTHORIZED) ||
1627 (old_state == IEEE80211_STA_NONE &&
1628 new_state == IEEE80211_STA_NOTEXIST))
1629 mt76_connac_mcu_set_deep_sleep(dev, true);
1630
1631 if ((old_state == IEEE80211_STA_NOTEXIST &&
1632 new_state == IEEE80211_STA_NONE) ||
1633 (old_state == IEEE80211_STA_AUTHORIZED &&
1634 new_state == IEEE80211_STA_ASSOC))
1635 mt76_connac_mcu_set_deep_sleep(dev, false);
1636
1637 return 0;
1638}
1639EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
1640
1641void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
1642 struct mt76_connac_coredump *coredump)
1643{
1644 spin_lock_bh(&dev->lock);
1645 __skb_queue_tail(&coredump->msg_list, skb);
1646 spin_unlock_bh(&dev->lock);
1647
1648 coredump->last_activity = jiffies;
1649
1650 queue_delayed_work(dev->wq, &coredump->work,
1651 MT76_CONNAC_COREDUMP_TIMEOUT);
1652}
1653EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
1654
1655int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
1656{
1657 struct mt76_connac_cap_hdr {
1658 __le16 n_element;
1659 u8 rsv[2];
1660 } __packed * hdr;
1661 struct sk_buff *skb;
1662 int ret, i;
1663
1664 ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CMD_GET_NIC_CAPAB, NULL,
1665 0, true, &skb);
1666 if (ret)
1667 return ret;
1668
1669 hdr = (struct mt76_connac_cap_hdr *)skb->data;
1670 if (skb->len < sizeof(*hdr)) {
1671 ret = -EINVAL;
1672 goto out;
1673 }
1674
1675 skb_pull(skb, sizeof(*hdr));
1676
1677 for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
1678 struct tlv_hdr {
1679 __le32 type;
1680 __le32 len;
1681 } __packed * tlv = (struct tlv_hdr *)skb->data;
1682 int len;
1683
1684 if (skb->len < sizeof(*tlv))
1685 break;
1686
1687 skb_pull(skb, sizeof(*tlv));
1688
1689 len = le32_to_cpu(tlv->len);
1690 if (skb->len < len)
1691 break;
1692
1693 switch (le32_to_cpu(tlv->type)) {
1694 case MT_NIC_CAP_6G:
1695 phy->cap.has_6ghz = skb->data[0];
1696 break;
1697 default:
1698 break;
1699 }
1700 skb_pull(skb, len);
1701 }
1702out:
1703 dev_kfree_skb(skb);
1704
1705 return ret;
1706}
1707EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability);
1708
1709static void
1710mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
1711 struct mt76_power_limits *limits,
1712 enum nl80211_band band)
1713{
1714 int max_power = is_mt7921(dev) ? 127 : 63;
1715 int i, offset = sizeof(limits->cck);
1716
1717 memset(sku, max_power, MT_SKU_POWER_LIMIT);
1718
1719 if (band == NL80211_BAND_2GHZ) {
1720
1721 memcpy(sku, limits->cck, sizeof(limits->cck));
1722 }
1723
1724
1725 memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
1726 offset += sizeof(limits->ofdm);
1727
1728
1729 for (i = 0; i < 2; i++) {
1730 memcpy(&sku[offset], limits->mcs[i], 8);
1731 offset += 8;
1732 }
1733 sku[offset++] = limits->mcs[0][0];
1734
1735
1736 for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
1737 memcpy(&sku[offset], limits->mcs[i],
1738 ARRAY_SIZE(limits->mcs[i]));
1739 offset += 12;
1740 }
1741
1742 if (!is_mt7921(dev))
1743 return;
1744
1745
1746 for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
1747 memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
1748 offset += ARRAY_SIZE(limits->ru[i]);
1749 }
1750}
1751
1752static int
1753mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
1754 enum nl80211_band band)
1755{
1756 struct mt76_dev *dev = phy->dev;
1757 int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
1758 static const u8 chan_list_2ghz[] = {
1759 1, 2, 3, 4, 5, 6, 7,
1760 8, 9, 10, 11, 12, 13, 14
1761 };
1762 static const u8 chan_list_5ghz[] = {
1763 36, 38, 40, 42, 44, 46, 48,
1764 50, 52, 54, 56, 58, 60, 62,
1765 64, 100, 102, 104, 106, 108, 110,
1766 112, 114, 116, 118, 120, 122, 124,
1767 126, 128, 132, 134, 136, 138, 140,
1768 142, 144, 149, 151, 153, 155, 157,
1769 159, 161, 165
1770 };
1771 int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
1772 struct mt76_connac_sku_tlv sku_tlbv;
1773 struct mt76_power_limits limits;
1774 const u8 *ch_list;
1775
1776 sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
1777 tx_power = 2 * phy->hw->conf.power_level;
1778 if (!tx_power)
1779 tx_power = 127;
1780
1781 if (band == NL80211_BAND_2GHZ) {
1782 n_chan = ARRAY_SIZE(chan_list_2ghz);
1783 ch_list = chan_list_2ghz;
1784 } else {
1785 n_chan = ARRAY_SIZE(chan_list_5ghz);
1786 ch_list = chan_list_5ghz;
1787 }
1788 batch_size = DIV_ROUND_UP(n_chan, batch_len);
1789
1790 if (!phy->cap.has_5ghz)
1791 last_ch = chan_list_2ghz[n_chan - 1];
1792 else
1793 last_ch = chan_list_5ghz[n_chan - 1];
1794
1795 for (i = 0; i < batch_size; i++) {
1796 struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {
1797 .band = band == NL80211_BAND_2GHZ ? 1 : 2,
1798 };
1799 int j, err, msg_len, num_ch;
1800 struct sk_buff *skb;
1801
1802 num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len;
1803 msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
1804 skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
1805 if (!skb)
1806 return -ENOMEM;
1807
1808 skb_reserve(skb, sizeof(tx_power_tlv));
1809
1810 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
1811 memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
1812 tx_power_tlv.n_chan = num_ch;
1813
1814 for (j = 0; j < num_ch; j++, idx++) {
1815 struct ieee80211_channel chan = {
1816 .hw_value = ch_list[idx],
1817 .band = band,
1818 };
1819
1820 mt76_get_rate_power_limits(phy, &chan, &limits,
1821 tx_power);
1822
1823 tx_power_tlv.last_msg = ch_list[idx] == last_ch;
1824 sku_tlbv.channel = ch_list[idx];
1825
1826 mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
1827 &limits, band);
1828 skb_put_data(skb, &sku_tlbv, sku_len);
1829 }
1830 __skb_push(skb, sizeof(tx_power_tlv));
1831 memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
1832
1833 err = mt76_mcu_skb_send_msg(dev, skb,
1834 MCU_CMD_SET_RATE_TX_POWER, false);
1835 if (err < 0)
1836 return err;
1837 }
1838
1839 return 0;
1840}
1841
1842int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
1843{
1844 int err;
1845
1846 if (phy->cap.has_2ghz) {
1847 err = mt76_connac_mcu_rate_txpower_band(phy,
1848 NL80211_BAND_2GHZ);
1849 if (err < 0)
1850 return err;
1851 }
1852 if (phy->cap.has_5ghz) {
1853 err = mt76_connac_mcu_rate_txpower_band(phy,
1854 NL80211_BAND_5GHZ);
1855 if (err < 0)
1856 return err;
1857 }
1858
1859 return 0;
1860}
1861EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
1862
1863int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
1864 struct mt76_vif *vif,
1865 struct ieee80211_bss_conf *info)
1866{
1867 struct sk_buff *skb;
1868 int i, len = min_t(int, info->arp_addr_cnt,
1869 IEEE80211_BSS_ARP_ADDR_LIST_LEN);
1870 struct {
1871 struct {
1872 u8 bss_idx;
1873 u8 pad[3];
1874 } __packed hdr;
1875 struct mt76_connac_arpns_tlv arp;
1876 } req_hdr = {
1877 .hdr = {
1878 .bss_idx = vif->idx,
1879 },
1880 .arp = {
1881 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
1882 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
1883 .ips_num = len,
1884 .mode = 2,
1885 .option = 1,
1886 },
1887 };
1888
1889 skb = mt76_mcu_msg_alloc(dev, NULL,
1890 sizeof(req_hdr) + len * sizeof(__be32));
1891 if (!skb)
1892 return -ENOMEM;
1893
1894 skb_put_data(skb, &req_hdr, sizeof(req_hdr));
1895 for (i = 0; i < len; i++) {
1896 u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
1897
1898 memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
1899 }
1900
1901 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_OFFLOAD, true);
1902}
1903EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
1904
1905#ifdef CONFIG_PM
1906
1907const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
1908 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
1909 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
1910 .n_patterns = 1,
1911 .pattern_min_len = 1,
1912 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
1913 .max_nd_match_sets = 10,
1914};
1915EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
1916
1917static void
1918mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
1919 struct ieee80211_vif *vif,
1920 struct ieee80211_sta *sta,
1921 struct ieee80211_key_conf *key,
1922 void *data)
1923{
1924 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
1925 u32 cipher;
1926
1927 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
1928 key->cipher != WLAN_CIPHER_SUITE_CCMP &&
1929 key->cipher != WLAN_CIPHER_SUITE_TKIP)
1930 return;
1931
1932 if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
1933 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
1934 cipher = BIT(3);
1935 } else {
1936 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
1937 cipher = BIT(4);
1938 }
1939
1940
1941 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1942 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
1943 gtk_tlv->group_cipher = cpu_to_le32(cipher);
1944 gtk_tlv->keyid = key->keyidx;
1945 }
1946}
1947
1948int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
1949 struct ieee80211_vif *vif,
1950 struct cfg80211_gtk_rekey_data *key)
1951{
1952 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1953 struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
1954 struct mt76_phy *phy = hw->priv;
1955 struct sk_buff *skb;
1956 struct {
1957 u8 bss_idx;
1958 u8 pad[3];
1959 } __packed hdr = {
1960 .bss_idx = mvif->idx,
1961 };
1962
1963 skb = mt76_mcu_msg_alloc(phy->dev, NULL,
1964 sizeof(hdr) + sizeof(*gtk_tlv));
1965 if (!skb)
1966 return -ENOMEM;
1967
1968 skb_put_data(skb, &hdr, sizeof(hdr));
1969 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
1970 sizeof(*gtk_tlv));
1971 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
1972 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
1973 gtk_tlv->rekey_mode = 2;
1974 gtk_tlv->option = 1;
1975
1976 rcu_read_lock();
1977 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
1978 rcu_read_unlock();
1979
1980 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
1981 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
1982 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
1983
1984 return mt76_mcu_skb_send_msg(phy->dev, skb, MCU_UNI_CMD_OFFLOAD, true);
1985}
1986EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
1987
1988static int
1989mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
1990 bool suspend)
1991{
1992 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1993 struct {
1994 struct {
1995 u8 bss_idx;
1996 u8 pad[3];
1997 } __packed hdr;
1998 struct mt76_connac_arpns_tlv arpns;
1999 } req = {
2000 .hdr = {
2001 .bss_idx = mvif->idx,
2002 },
2003 .arpns = {
2004 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2005 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2006 .mode = suspend,
2007 },
2008 };
2009
2010 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2011 true);
2012}
2013
2014static int
2015mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
2016 bool suspend)
2017{
2018 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2019 struct {
2020 struct {
2021 u8 bss_idx;
2022 u8 pad[3];
2023 } __packed hdr;
2024 struct mt76_connac_gtk_rekey_tlv gtk_tlv;
2025 } __packed req = {
2026 .hdr = {
2027 .bss_idx = mvif->idx,
2028 },
2029 .gtk_tlv = {
2030 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
2031 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
2032 .rekey_mode = !suspend,
2033 },
2034 };
2035
2036 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2037 true);
2038}
2039
2040static int
2041mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
2042 struct ieee80211_vif *vif,
2043 bool enable, u8 mdtim,
2044 bool wow_suspend)
2045{
2046 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2047 struct {
2048 struct {
2049 u8 bss_idx;
2050 u8 pad[3];
2051 } __packed hdr;
2052 struct mt76_connac_suspend_tlv suspend_tlv;
2053 } req = {
2054 .hdr = {
2055 .bss_idx = mvif->idx,
2056 },
2057 .suspend_tlv = {
2058 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
2059 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
2060 .enable = enable,
2061 .mdtim = mdtim,
2062 .wow_suspend = wow_suspend,
2063 },
2064 };
2065
2066 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2067 true);
2068}
2069
2070static int
2071mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
2072 struct ieee80211_vif *vif,
2073 u8 index, bool enable,
2074 struct cfg80211_pkt_pattern *pattern)
2075{
2076 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2077 struct mt76_connac_wow_pattern_tlv *ptlv;
2078 struct sk_buff *skb;
2079 struct req_hdr {
2080 u8 bss_idx;
2081 u8 pad[3];
2082 } __packed hdr = {
2083 .bss_idx = mvif->idx,
2084 };
2085
2086 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
2087 if (!skb)
2088 return -ENOMEM;
2089
2090 skb_put_data(skb, &hdr, sizeof(hdr));
2091 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
2092 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
2093 ptlv->len = cpu_to_le16(sizeof(*ptlv));
2094 ptlv->data_len = pattern->pattern_len;
2095 ptlv->enable = enable;
2096 ptlv->index = index;
2097
2098 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
2099 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
2100
2101 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
2102}
2103
2104static int
2105mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
2106 bool suspend, struct cfg80211_wowlan *wowlan)
2107{
2108 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2109 struct mt76_dev *dev = phy->dev;
2110 struct {
2111 struct {
2112 u8 bss_idx;
2113 u8 pad[3];
2114 } __packed hdr;
2115 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
2116 struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
2117 } req = {
2118 .hdr = {
2119 .bss_idx = mvif->idx,
2120 },
2121 .wow_ctrl_tlv = {
2122 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
2123 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
2124 .cmd = suspend ? 1 : 2,
2125 },
2126 .gpio_tlv = {
2127 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
2128 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
2129 .gpio_pin = 0xff,
2130 },
2131 };
2132
2133 if (wowlan->magic_pkt)
2134 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
2135 if (wowlan->disconnect)
2136 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
2137 UNI_WOW_DETECT_TYPE_BCN_LOST);
2138 if (wowlan->nd_config) {
2139 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
2140 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
2141 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
2142 }
2143 if (wowlan->n_patterns)
2144 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
2145
2146 if (mt76_is_mmio(dev))
2147 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
2148 else if (mt76_is_usb(dev))
2149 req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
2150 else if (mt76_is_sdio(dev))
2151 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
2152
2153 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2154 true);
2155}
2156
2157int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2158{
2159 struct {
2160 struct {
2161 u8 hif_type;
2162
2163
2164
2165 u8 pad[3];
2166 } __packed hdr;
2167 struct hif_suspend_tlv {
2168 __le16 tag;
2169 __le16 len;
2170 u8 suspend;
2171 } __packed hif_suspend;
2172 } req = {
2173 .hif_suspend = {
2174 .tag = cpu_to_le16(0),
2175 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
2176 .suspend = suspend,
2177 },
2178 };
2179
2180 if (mt76_is_mmio(dev))
2181 req.hdr.hif_type = 2;
2182 else if (mt76_is_usb(dev))
2183 req.hdr.hif_type = 1;
2184 else if (mt76_is_sdio(dev))
2185 req.hdr.hif_type = 0;
2186
2187 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_HIF_CTRL, &req, sizeof(req),
2188 true);
2189}
2190EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
2191
2192void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
2193 struct ieee80211_vif *vif)
2194{
2195 struct mt76_phy *phy = priv;
2196 bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->state);
2197 struct ieee80211_hw *hw = phy->hw;
2198 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
2199 int i;
2200
2201 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
2202 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
2203
2204 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
2205
2206 for (i = 0; i < wowlan->n_patterns; i++)
2207 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
2208 &wowlan->patterns[i]);
2209 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
2210}
2211EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
2212
2213#endif
2214
2215MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
2216MODULE_LICENSE("Dual BSD/GPL");
2217