1 // SPDX-License-Identifier: ISC
2 /* Copyright (C) 2020 MediaTek Inc. */
3
4 #include "mt76_connac_mcu.h"
5
mt76_connac_mcu_start_firmware(struct mt76_dev * dev,u32 addr,u32 option)6 int 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 }
19 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_firmware);
20
mt76_connac_mcu_patch_sem_ctrl(struct mt76_dev * dev,bool get)21 int 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 }
33 EXPORT_SYMBOL_GPL(mt76_connac_mcu_patch_sem_ctrl);
34
mt76_connac_mcu_start_patch(struct mt76_dev * dev)35 int 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 }
47 EXPORT_SYMBOL_GPL(mt76_connac_mcu_start_patch);
48
49 #define MCU_PATCH_ADDRESS 0x200000
50
mt76_connac_mcu_init_download(struct mt76_dev * dev,u32 addr,u32 len,u32 mode)51 int 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 }
73 EXPORT_SYMBOL_GPL(mt76_connac_mcu_init_download);
74
mt76_connac_mcu_set_channel_domain(struct mt76_phy * phy)75 int 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]; /* regulatory_request.alpha2 */
80 u8 bw_2g; /* BW_20_40M 0
81 * BW_20M 1
82 * BW_20_40_80M 2
83 * BW_20_40_80_160M 3
84 * BW_20_40_80_8080M 4
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 }
148 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_channel_domain);
149
mt76_connac_mcu_set_mac_enable(struct mt76_dev * dev,int band,bool enable,bool hdr_trans)150 int 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 }
165 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_mac_enable);
166
mt76_connac_mcu_set_vif_ps(struct mt76_dev * dev,struct ieee80211_vif * vif)167 int 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; /* 0: device awake
173 * 1: static power save
174 * 2: dynamic power saving
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 }
187 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_vif_ps);
188
mt76_connac_mcu_set_rts_thresh(struct mt76_dev * dev,u32 val,u8 band)189 int 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 }
207 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rts_thresh);
208
mt76_connac_mcu_beacon_loss_iter(void * priv,u8 * mac,struct ieee80211_vif * vif)209 void 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 }
223 EXPORT_SYMBOL_GPL(mt76_connac_mcu_beacon_loss_iter);
224
225 struct tlv *
mt76_connac_mcu_add_nested_tlv(struct sk_buff * skb,int tag,int len,void * sta_ntlv,void * sta_wtbl)226 mt76_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 }
251 EXPORT_SYMBOL_GPL(mt76_connac_mcu_add_nested_tlv);
252
253 struct sk_buff *
mt76_connac_mcu_alloc_sta_req(struct mt76_dev * dev,struct mt76_vif * mvif,struct mt76_wcid * wcid)254 mt76_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 }
274 EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_sta_req);
275
276 struct wtbl_req_hdr *
mt76_connac_mcu_alloc_wtbl_req(struct mt76_dev * dev,struct mt76_wcid * wcid,int cmd,void * sta_wtbl,struct sk_buff ** skb)277 mt76_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 le16_add_cpu(&sta_hdr->len, sizeof(hdr));
299
300 return skb_put_data(nskb, &hdr, sizeof(hdr));
301 }
302 EXPORT_SYMBOL_GPL(mt76_connac_mcu_alloc_wtbl_req);
303
mt76_connac_mcu_sta_basic_tlv(struct sk_buff * skb,struct ieee80211_vif * vif,struct ieee80211_sta * sta,bool enable,bool newly)304 void 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 }
362 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_basic_tlv);
363
364 static void
mt76_connac_mcu_sta_uapsd(struct sk_buff * skb,struct ieee80211_vif * vif,struct ieee80211_sta * sta)365 mt76_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
mt76_connac_mcu_wtbl_hdr_trans_tlv(struct sk_buff * skb,struct ieee80211_vif * vif,struct mt76_wcid * wcid,void * sta_wtbl,void * wtbl_tlv)396 void 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 }
420 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_hdr_trans_tlv);
421
mt76_connac_mcu_sta_update_hdr_trans(struct mt76_dev * dev,struct ieee80211_vif * vif,struct mt76_wcid * wcid,int cmd)422 int 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 }
447 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_update_hdr_trans);
448
mt76_connac_mcu_wtbl_generic_tlv(struct mt76_dev * dev,struct sk_buff * skb,struct ieee80211_vif * vif,struct ieee80211_sta * sta,void * sta_wtbl,void * wtbl_tlv)449 void 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 }
502 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_generic_tlv);
503
504 static void
mt76_connac_mcu_sta_amsdu_tlv(struct sk_buff * skb,struct ieee80211_sta * sta,struct ieee80211_vif * vif)505 mt76_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)
531 static void
mt76_connac_mcu_sta_he_tlv(struct sk_buff * skb,struct ieee80211_sta * sta)532 mt76_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
664 static u8
mt76_connac_get_phy_mode_v2(struct mt76_phy * mphy,struct ieee80211_vif * vif,enum nl80211_band band,struct ieee80211_sta * sta)665 mt76_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 && 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 && he_cap->has_he)
704 mode |= PHY_TYPE_BIT_HE;
705 }
706
707 return mode;
708 }
709
mt76_connac_mcu_sta_tlv(struct mt76_phy * mphy,struct sk_buff * skb,struct ieee80211_sta * sta,struct ieee80211_vif * vif,u8 rcpi,u8 sta_state)710 void 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 u16 supp_rates;
723
724 /* starec ht */
725 if (sta->ht_cap.ht_supported) {
726 struct sta_rec_ht *ht;
727
728 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_HT, sizeof(*ht));
729 ht = (struct sta_rec_ht *)tlv;
730 ht->ht_cap = cpu_to_le16(sta->ht_cap.cap);
731 }
732
733 /* starec vht */
734 if (sta->vht_cap.vht_supported) {
735 struct sta_rec_vht *vht;
736 int len;
737
738 len = is_mt7921(dev) ? sizeof(*vht) : sizeof(*vht) - 4;
739 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_VHT, len);
740 vht = (struct sta_rec_vht *)tlv;
741 vht->vht_cap = cpu_to_le32(sta->vht_cap.cap);
742 vht->vht_rx_mcs_map = sta->vht_cap.vht_mcs.rx_mcs_map;
743 vht->vht_tx_mcs_map = sta->vht_cap.vht_mcs.tx_mcs_map;
744 }
745
746 /* starec uapsd */
747 mt76_connac_mcu_sta_uapsd(skb, vif, sta);
748
749 if (!is_mt7921(dev))
750 return;
751
752 if (sta->ht_cap.ht_supported)
753 mt76_connac_mcu_sta_amsdu_tlv(skb, sta, vif);
754
755 /* starec he */
756 if (sta->he_cap.has_he)
757 mt76_connac_mcu_sta_he_tlv(skb, sta);
758
759 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_PHY, sizeof(*phy));
760 phy = (struct sta_rec_phy *)tlv;
761 phy->phy_type = mt76_connac_get_phy_mode_v2(mphy, vif, band, sta);
762 phy->basic_rate = cpu_to_le16((u16)vif->bss_conf.basic_rates);
763 phy->rcpi = rcpi;
764 phy->ampdu = FIELD_PREP(IEEE80211_HT_AMPDU_PARM_FACTOR,
765 sta->ht_cap.ampdu_factor) |
766 FIELD_PREP(IEEE80211_HT_AMPDU_PARM_DENSITY,
767 sta->ht_cap.ampdu_density);
768
769 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_RA, sizeof(*ra_info));
770 ra_info = (struct sta_rec_ra_info *)tlv;
771
772 supp_rates = sta->supp_rates[band];
773 if (band == NL80211_BAND_2GHZ)
774 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
775 FIELD_PREP(RA_LEGACY_CCK, supp_rates & 0xf);
776 else
777 supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates);
778
779 ra_info->legacy = cpu_to_le16(supp_rates);
780
781 if (sta->ht_cap.ht_supported)
782 memcpy(ra_info->rx_mcs_bitmask, sta->ht_cap.mcs.rx_mask,
783 HT_MCS_MASK_NUM);
784
785 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_STATE, sizeof(*state));
786 state = (struct sta_rec_state *)tlv;
787 state->state = sta_state;
788
789 if (sta->vht_cap.vht_supported) {
790 state->vht_opmode = sta->bandwidth;
791 state->vht_opmode |= (sta->rx_nss - 1) <<
792 IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
793 }
794 }
795 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_tlv);
796
797 static void
mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff * skb,struct ieee80211_sta * sta,void * sta_wtbl,void * wtbl_tlv)798 mt76_connac_mcu_wtbl_smps_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
799 void *sta_wtbl, void *wtbl_tlv)
800 {
801 struct wtbl_smps *smps;
802 struct tlv *tlv;
803
804 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_SMPS, sizeof(*smps),
805 wtbl_tlv, sta_wtbl);
806 smps = (struct wtbl_smps *)tlv;
807
808 if (sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
809 smps->smps = true;
810 }
811
mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev * dev,struct sk_buff * skb,struct ieee80211_sta * sta,void * sta_wtbl,void * wtbl_tlv)812 void mt76_connac_mcu_wtbl_ht_tlv(struct mt76_dev *dev, struct sk_buff *skb,
813 struct ieee80211_sta *sta, void *sta_wtbl,
814 void *wtbl_tlv)
815 {
816 struct wtbl_ht *ht = NULL;
817 struct tlv *tlv;
818 u32 flags = 0;
819
820 if (sta->ht_cap.ht_supported) {
821 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_HT, sizeof(*ht),
822 wtbl_tlv, sta_wtbl);
823 ht = (struct wtbl_ht *)tlv;
824 ht->ldpc = !!(sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING);
825 ht->af = sta->ht_cap.ampdu_factor;
826 ht->mm = sta->ht_cap.ampdu_density;
827 ht->ht = true;
828 }
829
830 if (sta->vht_cap.vht_supported) {
831 struct wtbl_vht *vht;
832 u8 af;
833
834 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_VHT,
835 sizeof(*vht), wtbl_tlv,
836 sta_wtbl);
837 vht = (struct wtbl_vht *)tlv;
838 vht->ldpc = !!(sta->vht_cap.cap & IEEE80211_VHT_CAP_RXLDPC);
839 vht->vht = true;
840
841 af = FIELD_GET(IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK,
842 sta->vht_cap.cap);
843 if (ht)
844 ht->af = max(ht->af, af);
845 }
846
847 mt76_connac_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_tlv);
848
849 if (!is_mt7921(dev) && sta->ht_cap.ht_supported) {
850 /* sgi */
851 u32 msk = MT_WTBL_W5_SHORT_GI_20 | MT_WTBL_W5_SHORT_GI_40 |
852 MT_WTBL_W5_SHORT_GI_80 | MT_WTBL_W5_SHORT_GI_160;
853 struct wtbl_raw *raw;
854
855 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_RAW_DATA,
856 sizeof(*raw), wtbl_tlv,
857 sta_wtbl);
858
859 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20)
860 flags |= MT_WTBL_W5_SHORT_GI_20;
861 if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)
862 flags |= MT_WTBL_W5_SHORT_GI_40;
863
864 if (sta->vht_cap.vht_supported) {
865 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80)
866 flags |= MT_WTBL_W5_SHORT_GI_80;
867 if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_160)
868 flags |= MT_WTBL_W5_SHORT_GI_160;
869 }
870 raw = (struct wtbl_raw *)tlv;
871 raw->val = cpu_to_le32(flags);
872 raw->msk = cpu_to_le32(~msk);
873 raw->wtbl_idx = 1;
874 raw->dw = 5;
875 }
876 }
877 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ht_tlv);
878
mt76_connac_mcu_sta_cmd(struct mt76_phy * phy,struct mt76_sta_cmd_info * info)879 int mt76_connac_mcu_sta_cmd(struct mt76_phy *phy,
880 struct mt76_sta_cmd_info *info)
881 {
882 struct mt76_vif *mvif = (struct mt76_vif *)info->vif->drv_priv;
883 struct mt76_dev *dev = phy->dev;
884 struct wtbl_req_hdr *wtbl_hdr;
885 struct tlv *sta_wtbl;
886 struct sk_buff *skb;
887
888 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, info->wcid);
889 if (IS_ERR(skb))
890 return PTR_ERR(skb);
891
892 if (info->sta || !info->offload_fw)
893 mt76_connac_mcu_sta_basic_tlv(skb, info->vif, info->sta,
894 info->enable, info->newly);
895 if (info->sta && info->enable)
896 mt76_connac_mcu_sta_tlv(phy, skb, info->sta,
897 info->vif, info->rcpi,
898 info->state);
899
900 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
901 sizeof(struct tlv));
902
903 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, info->wcid,
904 WTBL_RESET_AND_SET,
905 sta_wtbl, &skb);
906 if (IS_ERR(wtbl_hdr))
907 return PTR_ERR(wtbl_hdr);
908
909 if (info->enable) {
910 mt76_connac_mcu_wtbl_generic_tlv(dev, skb, info->vif,
911 info->sta, sta_wtbl,
912 wtbl_hdr);
913 mt76_connac_mcu_wtbl_hdr_trans_tlv(skb, info->vif, info->wcid,
914 sta_wtbl, wtbl_hdr);
915 if (info->sta)
916 mt76_connac_mcu_wtbl_ht_tlv(dev, skb, info->sta,
917 sta_wtbl, wtbl_hdr);
918 }
919
920 return mt76_mcu_skb_send_msg(dev, skb, info->cmd, true);
921 }
922 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_cmd);
923
mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev * dev,struct sk_buff * skb,struct ieee80211_ampdu_params * params,bool enable,bool tx,void * sta_wtbl,void * wtbl_tlv)924 void mt76_connac_mcu_wtbl_ba_tlv(struct mt76_dev *dev, struct sk_buff *skb,
925 struct ieee80211_ampdu_params *params,
926 bool enable, bool tx, void *sta_wtbl,
927 void *wtbl_tlv)
928 {
929 struct wtbl_ba *ba;
930 struct tlv *tlv;
931
932 tlv = mt76_connac_mcu_add_nested_tlv(skb, WTBL_BA, sizeof(*ba),
933 wtbl_tlv, sta_wtbl);
934
935 ba = (struct wtbl_ba *)tlv;
936 ba->tid = params->tid;
937
938 if (tx) {
939 ba->ba_type = MT_BA_TYPE_ORIGINATOR;
940 ba->sn = enable ? cpu_to_le16(params->ssn) : 0;
941 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
942 ba->ba_en = enable;
943 } else {
944 memcpy(ba->peer_addr, params->sta->addr, ETH_ALEN);
945 ba->ba_type = MT_BA_TYPE_RECIPIENT;
946 ba->rst_ba_tid = params->tid;
947 ba->rst_ba_sel = RST_BA_MAC_TID_MATCH;
948 ba->rst_ba_sb = 1;
949 }
950
951 if (is_mt7921(dev)) {
952 ba->ba_winsize = enable ? cpu_to_le16(params->buf_size) : 0;
953 return;
954 }
955
956 if (enable && tx) {
957 u8 ba_range[] = { 4, 8, 12, 24, 36, 48, 54, 64 };
958 int i;
959
960 for (i = 7; i > 0; i--) {
961 if (params->buf_size >= ba_range[i])
962 break;
963 }
964 ba->ba_winsize_idx = i;
965 }
966 }
967 EXPORT_SYMBOL_GPL(mt76_connac_mcu_wtbl_ba_tlv);
968
mt76_connac_mcu_uni_add_dev(struct mt76_phy * phy,struct ieee80211_vif * vif,struct mt76_wcid * wcid,bool enable)969 int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,
970 struct ieee80211_vif *vif,
971 struct mt76_wcid *wcid,
972 bool enable)
973 {
974 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
975 struct mt76_dev *dev = phy->dev;
976 struct {
977 struct {
978 u8 omac_idx;
979 u8 band_idx;
980 __le16 pad;
981 } __packed hdr;
982 struct req_tlv {
983 __le16 tag;
984 __le16 len;
985 u8 active;
986 u8 pad;
987 u8 omac_addr[ETH_ALEN];
988 } __packed tlv;
989 } dev_req = {
990 .hdr = {
991 .omac_idx = mvif->omac_idx,
992 .band_idx = mvif->band_idx,
993 },
994 .tlv = {
995 .tag = cpu_to_le16(DEV_INFO_ACTIVE),
996 .len = cpu_to_le16(sizeof(struct req_tlv)),
997 .active = enable,
998 },
999 };
1000 struct {
1001 struct {
1002 u8 bss_idx;
1003 u8 pad[3];
1004 } __packed hdr;
1005 struct mt76_connac_bss_basic_tlv basic;
1006 } basic_req = {
1007 .hdr = {
1008 .bss_idx = mvif->idx,
1009 },
1010 .basic = {
1011 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1012 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1013 .omac_idx = mvif->omac_idx,
1014 .band_idx = mvif->band_idx,
1015 .wmm_idx = mvif->wmm_idx,
1016 .active = enable,
1017 .bmc_tx_wlan_idx = cpu_to_le16(wcid->idx),
1018 .sta_idx = cpu_to_le16(wcid->idx),
1019 .conn_state = 1,
1020 },
1021 };
1022 int err, idx, cmd, len;
1023 void *data;
1024
1025 switch (vif->type) {
1026 case NL80211_IFTYPE_MESH_POINT:
1027 case NL80211_IFTYPE_MONITOR:
1028 case NL80211_IFTYPE_AP:
1029 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
1030 break;
1031 case NL80211_IFTYPE_STATION:
1032 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
1033 break;
1034 case NL80211_IFTYPE_ADHOC:
1035 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1036 break;
1037 default:
1038 WARN_ON(1);
1039 break;
1040 }
1041
1042 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1043 basic_req.basic.hw_bss_idx = idx;
1044
1045 memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
1046
1047 cmd = enable ? MCU_UNI_CMD_DEV_INFO_UPDATE : MCU_UNI_CMD_BSS_INFO_UPDATE;
1048 data = enable ? (void *)&dev_req : (void *)&basic_req;
1049 len = enable ? sizeof(dev_req) : sizeof(basic_req);
1050
1051 err = mt76_mcu_send_msg(dev, cmd, data, len, true);
1052 if (err < 0)
1053 return err;
1054
1055 cmd = enable ? MCU_UNI_CMD_BSS_INFO_UPDATE : MCU_UNI_CMD_DEV_INFO_UPDATE;
1056 data = enable ? (void *)&basic_req : (void *)&dev_req;
1057 len = enable ? sizeof(basic_req) : sizeof(dev_req);
1058
1059 return mt76_mcu_send_msg(dev, cmd, data, len, true);
1060 }
1061 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_dev);
1062
mt76_connac_mcu_sta_ba_tlv(struct sk_buff * skb,struct ieee80211_ampdu_params * params,bool enable,bool tx)1063 void mt76_connac_mcu_sta_ba_tlv(struct sk_buff *skb,
1064 struct ieee80211_ampdu_params *params,
1065 bool enable, bool tx)
1066 {
1067 struct sta_rec_ba *ba;
1068 struct tlv *tlv;
1069
1070 tlv = mt76_connac_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
1071
1072 ba = (struct sta_rec_ba *)tlv;
1073 ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
1074 ba->winsize = cpu_to_le16(params->buf_size);
1075 ba->ssn = cpu_to_le16(params->ssn);
1076 ba->ba_en = enable << params->tid;
1077 ba->amsdu = params->amsdu;
1078 ba->tid = params->tid;
1079 }
1080 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba_tlv);
1081
mt76_connac_mcu_sta_ba(struct mt76_dev * dev,struct mt76_vif * mvif,struct ieee80211_ampdu_params * params,bool enable,bool tx)1082 int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
1083 struct ieee80211_ampdu_params *params,
1084 bool enable, bool tx)
1085 {
1086 struct mt76_wcid *wcid = (struct mt76_wcid *)params->sta->drv_priv;
1087 struct wtbl_req_hdr *wtbl_hdr;
1088 struct tlv *sta_wtbl;
1089 struct sk_buff *skb;
1090 int ret;
1091
1092 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1093 if (IS_ERR(skb))
1094 return PTR_ERR(skb);
1095
1096 sta_wtbl = mt76_connac_mcu_add_tlv(skb, STA_REC_WTBL,
1097 sizeof(struct tlv));
1098
1099 wtbl_hdr = mt76_connac_mcu_alloc_wtbl_req(dev, wcid, WTBL_SET,
1100 sta_wtbl, &skb);
1101 if (IS_ERR(wtbl_hdr))
1102 return PTR_ERR(wtbl_hdr);
1103
1104 mt76_connac_mcu_wtbl_ba_tlv(dev, skb, params, enable, tx, sta_wtbl,
1105 wtbl_hdr);
1106
1107 ret = mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE, true);
1108 if (ret)
1109 return ret;
1110
1111 skb = mt76_connac_mcu_alloc_sta_req(dev, mvif, wcid);
1112 if (IS_ERR(skb))
1113 return PTR_ERR(skb);
1114
1115 mt76_connac_mcu_sta_ba_tlv(skb, params, enable, tx);
1116
1117 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_STA_REC_UPDATE,
1118 true);
1119 }
1120 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sta_ba);
1121
1122 static u8
mt76_connac_get_phy_mode(struct mt76_phy * phy,struct ieee80211_vif * vif,enum nl80211_band band,struct ieee80211_sta * sta)1123 mt76_connac_get_phy_mode(struct mt76_phy *phy, struct ieee80211_vif *vif,
1124 enum nl80211_band band,
1125 struct ieee80211_sta *sta)
1126 {
1127 struct mt76_dev *dev = phy->dev;
1128 const struct ieee80211_sta_he_cap *he_cap;
1129 struct ieee80211_sta_vht_cap *vht_cap;
1130 struct ieee80211_sta_ht_cap *ht_cap;
1131 u8 mode = 0;
1132
1133 if (!is_mt7921(dev))
1134 return 0x38;
1135
1136 if (sta) {
1137 ht_cap = &sta->ht_cap;
1138 vht_cap = &sta->vht_cap;
1139 he_cap = &sta->he_cap;
1140 } else {
1141 struct ieee80211_supported_band *sband;
1142
1143 sband = phy->hw->wiphy->bands[band];
1144 ht_cap = &sband->ht_cap;
1145 vht_cap = &sband->vht_cap;
1146 he_cap = ieee80211_get_he_iftype_cap(sband, vif->type);
1147 }
1148
1149 if (band == NL80211_BAND_2GHZ) {
1150 mode |= PHY_MODE_B | PHY_MODE_G;
1151
1152 if (ht_cap->ht_supported)
1153 mode |= PHY_MODE_GN;
1154
1155 if (he_cap->has_he)
1156 mode |= PHY_MODE_AX_24G;
1157 } else if (band == NL80211_BAND_5GHZ) {
1158 mode |= PHY_MODE_A;
1159
1160 if (ht_cap->ht_supported)
1161 mode |= PHY_MODE_AN;
1162
1163 if (vht_cap->vht_supported)
1164 mode |= PHY_MODE_AC;
1165
1166 if (he_cap->has_he)
1167 mode |= PHY_MODE_AX_5G;
1168 }
1169
1170 return mode;
1171 }
1172
1173 static const struct ieee80211_sta_he_cap *
mt76_connac_get_he_phy_cap(struct mt76_phy * phy,struct ieee80211_vif * vif)1174 mt76_connac_get_he_phy_cap(struct mt76_phy *phy, struct ieee80211_vif *vif)
1175 {
1176 enum nl80211_band band = phy->chandef.chan->band;
1177 struct ieee80211_supported_band *sband;
1178
1179 sband = phy->hw->wiphy->bands[band];
1180
1181 return ieee80211_get_he_iftype_cap(sband, vif->type);
1182 }
1183
1184 #define DEFAULT_HE_PE_DURATION 4
1185 #define DEFAULT_HE_DURATION_RTS_THRES 1023
1186 static void
mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy * phy,struct ieee80211_vif * vif,struct tlv * tlv)1187 mt76_connac_mcu_uni_bss_he_tlv(struct mt76_phy *phy, struct ieee80211_vif *vif,
1188 struct tlv *tlv)
1189 {
1190 const struct ieee80211_sta_he_cap *cap;
1191 struct bss_info_uni_he *he;
1192
1193 cap = mt76_connac_get_he_phy_cap(phy, vif);
1194
1195 he = (struct bss_info_uni_he *)tlv;
1196 he->he_pe_duration = vif->bss_conf.htc_trig_based_pkt_ext;
1197 if (!he->he_pe_duration)
1198 he->he_pe_duration = DEFAULT_HE_PE_DURATION;
1199
1200 he->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
1201 if (!he->he_rts_thres)
1202 he->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
1203
1204 he->max_nss_mcs[CMD_HE_MCS_BW80] = cap->he_mcs_nss_supp.tx_mcs_80;
1205 he->max_nss_mcs[CMD_HE_MCS_BW160] = cap->he_mcs_nss_supp.tx_mcs_160;
1206 he->max_nss_mcs[CMD_HE_MCS_BW8080] = cap->he_mcs_nss_supp.tx_mcs_80p80;
1207 }
1208
mt76_connac_mcu_uni_add_bss(struct mt76_phy * phy,struct ieee80211_vif * vif,struct mt76_wcid * wcid,bool enable)1209 int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
1210 struct ieee80211_vif *vif,
1211 struct mt76_wcid *wcid,
1212 bool enable)
1213 {
1214 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1215 struct cfg80211_chan_def *chandef = &phy->chandef;
1216 int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2;
1217 enum nl80211_band band = chandef->chan->band;
1218 struct mt76_dev *mdev = phy->dev;
1219 struct {
1220 struct {
1221 u8 bss_idx;
1222 u8 pad[3];
1223 } __packed hdr;
1224 struct mt76_connac_bss_basic_tlv basic;
1225 struct mt76_connac_bss_qos_tlv qos;
1226 } basic_req = {
1227 .hdr = {
1228 .bss_idx = mvif->idx,
1229 },
1230 .basic = {
1231 .tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
1232 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
1233 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
1234 .dtim_period = vif->bss_conf.dtim_period,
1235 .omac_idx = mvif->omac_idx,
1236 .band_idx = mvif->band_idx,
1237 .wmm_idx = mvif->wmm_idx,
1238 .active = true, /* keep bss deactivated */
1239 .phymode = mt76_connac_get_phy_mode(phy, vif, band, NULL),
1240 },
1241 .qos = {
1242 .tag = cpu_to_le16(UNI_BSS_INFO_QBSS),
1243 .len = cpu_to_le16(sizeof(struct mt76_connac_bss_qos_tlv)),
1244 .qos = vif->bss_conf.qos,
1245 },
1246 };
1247 struct {
1248 struct {
1249 u8 bss_idx;
1250 u8 pad[3];
1251 } __packed hdr;
1252 struct rlm_tlv {
1253 __le16 tag;
1254 __le16 len;
1255 u8 control_channel;
1256 u8 center_chan;
1257 u8 center_chan2;
1258 u8 bw;
1259 u8 tx_streams;
1260 u8 rx_streams;
1261 u8 short_st;
1262 u8 ht_op_info;
1263 u8 sco;
1264 u8 pad[3];
1265 } __packed rlm;
1266 } __packed rlm_req = {
1267 .hdr = {
1268 .bss_idx = mvif->idx,
1269 },
1270 .rlm = {
1271 .tag = cpu_to_le16(UNI_BSS_INFO_RLM),
1272 .len = cpu_to_le16(sizeof(struct rlm_tlv)),
1273 .control_channel = chandef->chan->hw_value,
1274 .center_chan = ieee80211_frequency_to_channel(freq1),
1275 .center_chan2 = ieee80211_frequency_to_channel(freq2),
1276 .tx_streams = hweight8(phy->antenna_mask),
1277 .ht_op_info = 4, /* set HT 40M allowed */
1278 .rx_streams = phy->chainmask,
1279 .short_st = true,
1280 },
1281 };
1282 int err, conn_type;
1283 u8 idx;
1284
1285 idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
1286 basic_req.basic.hw_bss_idx = idx;
1287
1288 switch (vif->type) {
1289 case NL80211_IFTYPE_MESH_POINT:
1290 case NL80211_IFTYPE_AP:
1291 if (vif->p2p)
1292 conn_type = CONNECTION_P2P_GO;
1293 else
1294 conn_type = CONNECTION_INFRA_AP;
1295 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1296 break;
1297 case NL80211_IFTYPE_STATION:
1298 if (vif->p2p)
1299 conn_type = CONNECTION_P2P_GC;
1300 else
1301 conn_type = CONNECTION_INFRA_STA;
1302 basic_req.basic.conn_type = cpu_to_le32(conn_type);
1303 break;
1304 case NL80211_IFTYPE_ADHOC:
1305 basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
1306 break;
1307 default:
1308 WARN_ON(1);
1309 break;
1310 }
1311
1312 memcpy(basic_req.basic.bssid, vif->bss_conf.bssid, ETH_ALEN);
1313 basic_req.basic.bmc_tx_wlan_idx = cpu_to_le16(wcid->idx);
1314 basic_req.basic.sta_idx = cpu_to_le16(wcid->idx);
1315 basic_req.basic.conn_state = !enable;
1316
1317 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &basic_req,
1318 sizeof(basic_req), true);
1319 if (err < 0)
1320 return err;
1321
1322 if (vif->bss_conf.he_support) {
1323 struct {
1324 struct {
1325 u8 bss_idx;
1326 u8 pad[3];
1327 } __packed hdr;
1328 struct bss_info_uni_he he;
1329 struct bss_info_uni_bss_color bss_color;
1330 } he_req = {
1331 .hdr = {
1332 .bss_idx = mvif->idx,
1333 },
1334 .he = {
1335 .tag = cpu_to_le16(UNI_BSS_INFO_HE_BASIC),
1336 .len = cpu_to_le16(sizeof(struct bss_info_uni_he)),
1337 },
1338 .bss_color = {
1339 .tag = cpu_to_le16(UNI_BSS_INFO_BSS_COLOR),
1340 .len = cpu_to_le16(sizeof(struct bss_info_uni_bss_color)),
1341 .enable = 0,
1342 .bss_color = 0,
1343 },
1344 };
1345
1346 if (enable) {
1347 he_req.bss_color.enable =
1348 vif->bss_conf.he_bss_color.enabled;
1349 he_req.bss_color.bss_color =
1350 vif->bss_conf.he_bss_color.color;
1351 }
1352
1353 mt76_connac_mcu_uni_bss_he_tlv(phy, vif,
1354 (struct tlv *)&he_req.he);
1355 err = mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE,
1356 &he_req, sizeof(he_req), true);
1357 if (err < 0)
1358 return err;
1359 }
1360
1361 switch (chandef->width) {
1362 case NL80211_CHAN_WIDTH_40:
1363 rlm_req.rlm.bw = CMD_CBW_40MHZ;
1364 break;
1365 case NL80211_CHAN_WIDTH_80:
1366 rlm_req.rlm.bw = CMD_CBW_80MHZ;
1367 break;
1368 case NL80211_CHAN_WIDTH_80P80:
1369 rlm_req.rlm.bw = CMD_CBW_8080MHZ;
1370 break;
1371 case NL80211_CHAN_WIDTH_160:
1372 rlm_req.rlm.bw = CMD_CBW_160MHZ;
1373 break;
1374 case NL80211_CHAN_WIDTH_5:
1375 rlm_req.rlm.bw = CMD_CBW_5MHZ;
1376 break;
1377 case NL80211_CHAN_WIDTH_10:
1378 rlm_req.rlm.bw = CMD_CBW_10MHZ;
1379 break;
1380 case NL80211_CHAN_WIDTH_20_NOHT:
1381 case NL80211_CHAN_WIDTH_20:
1382 default:
1383 rlm_req.rlm.bw = CMD_CBW_20MHZ;
1384 rlm_req.rlm.ht_op_info = 0;
1385 break;
1386 }
1387
1388 if (rlm_req.rlm.control_channel < rlm_req.rlm.center_chan)
1389 rlm_req.rlm.sco = 1; /* SCA */
1390 else if (rlm_req.rlm.control_channel > rlm_req.rlm.center_chan)
1391 rlm_req.rlm.sco = 3; /* SCB */
1392
1393 return mt76_mcu_send_msg(mdev, MCU_UNI_CMD_BSS_INFO_UPDATE, &rlm_req,
1394 sizeof(rlm_req), true);
1395 }
1396 EXPORT_SYMBOL_GPL(mt76_connac_mcu_uni_add_bss);
1397
1398 #define MT76_CONNAC_SCAN_CHANNEL_TIME 60
mt76_connac_mcu_hw_scan(struct mt76_phy * phy,struct ieee80211_vif * vif,struct ieee80211_scan_request * scan_req)1399 int mt76_connac_mcu_hw_scan(struct mt76_phy *phy, struct ieee80211_vif *vif,
1400 struct ieee80211_scan_request *scan_req)
1401 {
1402 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1403 struct cfg80211_scan_request *sreq = &scan_req->req;
1404 int n_ssids = 0, err, i, duration;
1405 int ext_channels_num = max_t(int, sreq->n_channels - 32, 0);
1406 struct ieee80211_channel **scan_list = sreq->channels;
1407 struct mt76_dev *mdev = phy->dev;
1408 bool ext_phy = phy == mdev->phy2;
1409 struct mt76_connac_mcu_scan_channel *chan;
1410 struct mt76_connac_hw_scan_req *req;
1411 struct sk_buff *skb;
1412
1413 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req));
1414 if (!skb)
1415 return -ENOMEM;
1416
1417 set_bit(MT76_HW_SCANNING, &phy->state);
1418 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1419
1420 req = (struct mt76_connac_hw_scan_req *)skb_put(skb, sizeof(*req));
1421
1422 req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1423 req->bss_idx = mvif->idx;
1424 req->scan_type = sreq->n_ssids ? 1 : 0;
1425 req->probe_req_num = sreq->n_ssids ? 2 : 0;
1426 req->version = 1;
1427
1428 for (i = 0; i < sreq->n_ssids; i++) {
1429 if (!sreq->ssids[i].ssid_len)
1430 continue;
1431
1432 req->ssids[i].ssid_len = cpu_to_le32(sreq->ssids[i].ssid_len);
1433 memcpy(req->ssids[i].ssid, sreq->ssids[i].ssid,
1434 sreq->ssids[i].ssid_len);
1435 n_ssids++;
1436 }
1437 req->ssid_type = n_ssids ? BIT(2) : BIT(0);
1438 req->ssid_type_ext = n_ssids ? BIT(0) : 0;
1439 req->ssids_num = n_ssids;
1440
1441 duration = is_mt7921(phy->dev) ? 0 : MT76_CONNAC_SCAN_CHANNEL_TIME;
1442 /* increase channel time for passive scan */
1443 if (!sreq->n_ssids)
1444 duration *= 2;
1445 req->timeout_value = cpu_to_le16(sreq->n_channels * duration);
1446 req->channel_min_dwell_time = cpu_to_le16(duration);
1447 req->channel_dwell_time = cpu_to_le16(duration);
1448
1449 if (sreq->n_channels == 0 || sreq->n_channels > 64) {
1450 req->channel_type = 0;
1451 req->channels_num = 0;
1452 req->ext_channels_num = 0;
1453 } else {
1454 req->channel_type = 4;
1455 req->channels_num = min_t(u8, sreq->n_channels, 32);
1456 req->ext_channels_num = min_t(u8, ext_channels_num, 32);
1457 }
1458
1459 for (i = 0; i < req->channels_num + req->ext_channels_num; i++) {
1460 if (i >= 32)
1461 chan = &req->ext_channels[i - 32];
1462 else
1463 chan = &req->channels[i];
1464
1465 chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1466 chan->channel_num = scan_list[i]->hw_value;
1467 }
1468
1469 if (sreq->ie_len > 0) {
1470 memcpy(req->ies, sreq->ie, sreq->ie_len);
1471 req->ies_len = cpu_to_le16(sreq->ie_len);
1472 }
1473
1474 if (is_mt7921(phy->dev))
1475 req->scan_func |= SCAN_FUNC_SPLIT_SCAN;
1476
1477 memcpy(req->bssid, sreq->bssid, ETH_ALEN);
1478 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1479 get_random_mask_addr(req->random_mac, sreq->mac_addr,
1480 sreq->mac_addr_mask);
1481 req->scan_func |= SCAN_FUNC_RANDOM_MAC;
1482 }
1483
1484 err = mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_START_HW_SCAN, false);
1485 if (err < 0)
1486 clear_bit(MT76_HW_SCANNING, &phy->state);
1487
1488 return err;
1489 }
1490 EXPORT_SYMBOL_GPL(mt76_connac_mcu_hw_scan);
1491
mt76_connac_mcu_cancel_hw_scan(struct mt76_phy * phy,struct ieee80211_vif * vif)1492 int mt76_connac_mcu_cancel_hw_scan(struct mt76_phy *phy,
1493 struct ieee80211_vif *vif)
1494 {
1495 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1496 struct {
1497 u8 seq_num;
1498 u8 is_ext_channel;
1499 u8 rsv[2];
1500 } __packed req = {
1501 .seq_num = mvif->scan_seq_num,
1502 };
1503
1504 if (test_and_clear_bit(MT76_HW_SCANNING, &phy->state)) {
1505 struct cfg80211_scan_info info = {
1506 .aborted = true,
1507 };
1508
1509 ieee80211_scan_completed(phy->hw, &info);
1510 }
1511
1512 return mt76_mcu_send_msg(phy->dev, MCU_CMD_CANCEL_HW_SCAN, &req,
1513 sizeof(req), false);
1514 }
1515 EXPORT_SYMBOL_GPL(mt76_connac_mcu_cancel_hw_scan);
1516
mt76_connac_mcu_sched_scan_req(struct mt76_phy * phy,struct ieee80211_vif * vif,struct cfg80211_sched_scan_request * sreq)1517 int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
1518 struct ieee80211_vif *vif,
1519 struct cfg80211_sched_scan_request *sreq)
1520 {
1521 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1522 struct ieee80211_channel **scan_list = sreq->channels;
1523 struct mt76_connac_mcu_scan_channel *chan;
1524 struct mt76_connac_sched_scan_req *req;
1525 struct mt76_dev *mdev = phy->dev;
1526 bool ext_phy = phy == mdev->phy2;
1527 struct cfg80211_match_set *match;
1528 struct cfg80211_ssid *ssid;
1529 struct sk_buff *skb;
1530 int i;
1531
1532 skb = mt76_mcu_msg_alloc(mdev, NULL, sizeof(*req) + sreq->ie_len);
1533 if (!skb)
1534 return -ENOMEM;
1535
1536 mvif->scan_seq_num = (mvif->scan_seq_num + 1) & 0x7f;
1537
1538 req = (struct mt76_connac_sched_scan_req *)skb_put(skb, sizeof(*req));
1539 req->version = 1;
1540 req->seq_num = mvif->scan_seq_num | ext_phy << 7;
1541
1542 if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
1543 u8 *addr = is_mt7663(phy->dev) ? req->mt7663.random_mac
1544 : req->mt7921.random_mac;
1545
1546 req->scan_func = 1;
1547 get_random_mask_addr(addr, sreq->mac_addr,
1548 sreq->mac_addr_mask);
1549 }
1550 if (is_mt7921(phy->dev))
1551 req->mt7921.bss_idx = mvif->idx;
1552
1553 req->ssids_num = sreq->n_ssids;
1554 for (i = 0; i < req->ssids_num; i++) {
1555 ssid = &sreq->ssids[i];
1556 memcpy(req->ssids[i].ssid, ssid->ssid, ssid->ssid_len);
1557 req->ssids[i].ssid_len = cpu_to_le32(ssid->ssid_len);
1558 }
1559
1560 req->match_num = sreq->n_match_sets;
1561 for (i = 0; i < req->match_num; i++) {
1562 match = &sreq->match_sets[i];
1563 memcpy(req->match[i].ssid, match->ssid.ssid,
1564 match->ssid.ssid_len);
1565 req->match[i].rssi_th = cpu_to_le32(match->rssi_thold);
1566 req->match[i].ssid_len = match->ssid.ssid_len;
1567 }
1568
1569 req->channel_type = sreq->n_channels ? 4 : 0;
1570 req->channels_num = min_t(u8, sreq->n_channels, 64);
1571 for (i = 0; i < req->channels_num; i++) {
1572 chan = &req->channels[i];
1573 chan->band = scan_list[i]->band == NL80211_BAND_2GHZ ? 1 : 2;
1574 chan->channel_num = scan_list[i]->hw_value;
1575 }
1576
1577 req->intervals_num = sreq->n_scan_plans;
1578 for (i = 0; i < req->intervals_num; i++)
1579 req->intervals[i] = cpu_to_le16(sreq->scan_plans[i].interval);
1580
1581 if (sreq->ie_len > 0) {
1582 req->ie_len = cpu_to_le16(sreq->ie_len);
1583 memcpy(skb_put(skb, sreq->ie_len), sreq->ie, sreq->ie_len);
1584 }
1585
1586 return mt76_mcu_skb_send_msg(mdev, skb, MCU_CMD_SCHED_SCAN_REQ, false);
1587 }
1588 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_req);
1589
mt76_connac_mcu_sched_scan_enable(struct mt76_phy * phy,struct ieee80211_vif * vif,bool enable)1590 int mt76_connac_mcu_sched_scan_enable(struct mt76_phy *phy,
1591 struct ieee80211_vif *vif,
1592 bool enable)
1593 {
1594 struct {
1595 u8 active; /* 0: enabled 1: disabled */
1596 u8 rsv[3];
1597 } __packed req = {
1598 .active = !enable,
1599 };
1600
1601 if (enable)
1602 set_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1603 else
1604 clear_bit(MT76_HW_SCHED_SCANNING, &phy->state);
1605
1606 return mt76_mcu_send_msg(phy->dev, MCU_CMD_SCHED_SCAN_ENABLE, &req,
1607 sizeof(req), false);
1608 }
1609 EXPORT_SYMBOL_GPL(mt76_connac_mcu_sched_scan_enable);
1610
mt76_connac_mcu_chip_config(struct mt76_dev * dev)1611 int mt76_connac_mcu_chip_config(struct mt76_dev *dev)
1612 {
1613 struct mt76_connac_config req = {
1614 .resp_type = 0,
1615 };
1616
1617 memcpy(req.data, "assert", 7);
1618
1619 return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1620 false);
1621 }
1622 EXPORT_SYMBOL_GPL(mt76_connac_mcu_chip_config);
1623
mt76_connac_mcu_set_deep_sleep(struct mt76_dev * dev,bool enable)1624 int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
1625 {
1626 struct mt76_connac_config req = {
1627 .resp_type = 0,
1628 };
1629
1630 snprintf(req.data, sizeof(req.data), "KeepFullPwr %d", !enable);
1631
1632 return mt76_mcu_send_msg(dev, MCU_CMD_CHIP_CONFIG, &req, sizeof(req),
1633 false);
1634 }
1635 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
1636
mt76_connac_sta_state_dp(struct mt76_dev * dev,enum ieee80211_sta_state old_state,enum ieee80211_sta_state new_state)1637 int mt76_connac_sta_state_dp(struct mt76_dev *dev,
1638 enum ieee80211_sta_state old_state,
1639 enum ieee80211_sta_state new_state)
1640 {
1641 if ((old_state == IEEE80211_STA_ASSOC &&
1642 new_state == IEEE80211_STA_AUTHORIZED) ||
1643 (old_state == IEEE80211_STA_NONE &&
1644 new_state == IEEE80211_STA_NOTEXIST))
1645 mt76_connac_mcu_set_deep_sleep(dev, true);
1646
1647 if ((old_state == IEEE80211_STA_NOTEXIST &&
1648 new_state == IEEE80211_STA_NONE) ||
1649 (old_state == IEEE80211_STA_AUTHORIZED &&
1650 new_state == IEEE80211_STA_ASSOC))
1651 mt76_connac_mcu_set_deep_sleep(dev, false);
1652
1653 return 0;
1654 }
1655 EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
1656
mt76_connac_mcu_coredump_event(struct mt76_dev * dev,struct sk_buff * skb,struct mt76_connac_coredump * coredump)1657 void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
1658 struct mt76_connac_coredump *coredump)
1659 {
1660 spin_lock_bh(&dev->lock);
1661 __skb_queue_tail(&coredump->msg_list, skb);
1662 spin_unlock_bh(&dev->lock);
1663
1664 coredump->last_activity = jiffies;
1665
1666 queue_delayed_work(dev->wq, &coredump->work,
1667 MT76_CONNAC_COREDUMP_TIMEOUT);
1668 }
1669 EXPORT_SYMBOL_GPL(mt76_connac_mcu_coredump_event);
1670
mt76_connac_mcu_get_nic_capability(struct mt76_phy * phy)1671 int mt76_connac_mcu_get_nic_capability(struct mt76_phy *phy)
1672 {
1673 struct mt76_connac_cap_hdr {
1674 __le16 n_element;
1675 u8 rsv[2];
1676 } __packed * hdr;
1677 struct sk_buff *skb;
1678 int ret, i;
1679
1680 ret = mt76_mcu_send_and_get_msg(phy->dev, MCU_CMD_GET_NIC_CAPAB, NULL,
1681 0, true, &skb);
1682 if (ret)
1683 return ret;
1684
1685 hdr = (struct mt76_connac_cap_hdr *)skb->data;
1686 if (skb->len < sizeof(*hdr)) {
1687 ret = -EINVAL;
1688 goto out;
1689 }
1690
1691 skb_pull(skb, sizeof(*hdr));
1692
1693 for (i = 0; i < le16_to_cpu(hdr->n_element); i++) {
1694 struct tlv_hdr {
1695 __le32 type;
1696 __le32 len;
1697 } __packed * tlv = (struct tlv_hdr *)skb->data;
1698 int len;
1699
1700 if (skb->len < sizeof(*tlv))
1701 break;
1702
1703 skb_pull(skb, sizeof(*tlv));
1704
1705 len = le32_to_cpu(tlv->len);
1706 if (skb->len < len)
1707 break;
1708
1709 switch (le32_to_cpu(tlv->type)) {
1710 case MT_NIC_CAP_6G:
1711 phy->cap.has_6ghz = skb->data[0];
1712 break;
1713 default:
1714 break;
1715 }
1716 skb_pull(skb, len);
1717 }
1718 out:
1719 dev_kfree_skb(skb);
1720
1721 return ret;
1722 }
1723 EXPORT_SYMBOL_GPL(mt76_connac_mcu_get_nic_capability);
1724
1725 static void
mt76_connac_mcu_build_sku(struct mt76_dev * dev,s8 * sku,struct mt76_power_limits * limits,enum nl80211_band band)1726 mt76_connac_mcu_build_sku(struct mt76_dev *dev, s8 *sku,
1727 struct mt76_power_limits *limits,
1728 enum nl80211_band band)
1729 {
1730 int max_power = is_mt7921(dev) ? 127 : 63;
1731 int i, offset = sizeof(limits->cck);
1732
1733 memset(sku, max_power, MT_SKU_POWER_LIMIT);
1734
1735 if (band == NL80211_BAND_2GHZ) {
1736 /* cck */
1737 memcpy(sku, limits->cck, sizeof(limits->cck));
1738 }
1739
1740 /* ofdm */
1741 memcpy(&sku[offset], limits->ofdm, sizeof(limits->ofdm));
1742 offset += sizeof(limits->ofdm);
1743
1744 /* ht */
1745 for (i = 0; i < 2; i++) {
1746 memcpy(&sku[offset], limits->mcs[i], 8);
1747 offset += 8;
1748 }
1749 sku[offset++] = limits->mcs[0][0];
1750
1751 /* vht */
1752 for (i = 0; i < ARRAY_SIZE(limits->mcs); i++) {
1753 memcpy(&sku[offset], limits->mcs[i],
1754 ARRAY_SIZE(limits->mcs[i]));
1755 offset += 12;
1756 }
1757
1758 if (!is_mt7921(dev))
1759 return;
1760
1761 /* he */
1762 for (i = 0; i < ARRAY_SIZE(limits->ru); i++) {
1763 memcpy(&sku[offset], limits->ru[i], ARRAY_SIZE(limits->ru[i]));
1764 offset += ARRAY_SIZE(limits->ru[i]);
1765 }
1766 }
1767
1768 static int
mt76_connac_mcu_rate_txpower_band(struct mt76_phy * phy,enum nl80211_band band)1769 mt76_connac_mcu_rate_txpower_band(struct mt76_phy *phy,
1770 enum nl80211_band band)
1771 {
1772 struct mt76_dev *dev = phy->dev;
1773 int sku_len, batch_len = is_mt7921(dev) ? 8 : 16;
1774 static const u8 chan_list_2ghz[] = {
1775 1, 2, 3, 4, 5, 6, 7,
1776 8, 9, 10, 11, 12, 13, 14
1777 };
1778 static const u8 chan_list_5ghz[] = {
1779 36, 38, 40, 42, 44, 46, 48,
1780 50, 52, 54, 56, 58, 60, 62,
1781 64, 100, 102, 104, 106, 108, 110,
1782 112, 114, 116, 118, 120, 122, 124,
1783 126, 128, 132, 134, 136, 138, 140,
1784 142, 144, 149, 151, 153, 155, 157,
1785 159, 161, 165
1786 };
1787 int i, n_chan, batch_size, idx = 0, tx_power, last_ch;
1788 struct mt76_connac_sku_tlv sku_tlbv;
1789 struct mt76_power_limits limits;
1790 const u8 *ch_list;
1791
1792 sku_len = is_mt7921(dev) ? sizeof(sku_tlbv) : sizeof(sku_tlbv) - 92;
1793 tx_power = 2 * phy->hw->conf.power_level;
1794 if (!tx_power)
1795 tx_power = 127;
1796
1797 if (band == NL80211_BAND_2GHZ) {
1798 n_chan = ARRAY_SIZE(chan_list_2ghz);
1799 ch_list = chan_list_2ghz;
1800 } else {
1801 n_chan = ARRAY_SIZE(chan_list_5ghz);
1802 ch_list = chan_list_5ghz;
1803 }
1804 batch_size = DIV_ROUND_UP(n_chan, batch_len);
1805
1806 if (!phy->cap.has_5ghz)
1807 last_ch = chan_list_2ghz[n_chan - 1];
1808 else
1809 last_ch = chan_list_5ghz[n_chan - 1];
1810
1811 for (i = 0; i < batch_size; i++) {
1812 struct mt76_connac_tx_power_limit_tlv tx_power_tlv = {
1813 .band = band == NL80211_BAND_2GHZ ? 1 : 2,
1814 };
1815 int j, err, msg_len, num_ch;
1816 struct sk_buff *skb;
1817
1818 num_ch = i == batch_size - 1 ? n_chan % batch_len : batch_len;
1819 msg_len = sizeof(tx_power_tlv) + num_ch * sizeof(sku_tlbv);
1820 skb = mt76_mcu_msg_alloc(dev, NULL, msg_len);
1821 if (!skb)
1822 return -ENOMEM;
1823
1824 skb_reserve(skb, sizeof(tx_power_tlv));
1825
1826 BUILD_BUG_ON(sizeof(dev->alpha2) > sizeof(tx_power_tlv.alpha2));
1827 memcpy(tx_power_tlv.alpha2, dev->alpha2, sizeof(dev->alpha2));
1828 tx_power_tlv.n_chan = num_ch;
1829
1830 for (j = 0; j < num_ch; j++, idx++) {
1831 struct ieee80211_channel chan = {
1832 .hw_value = ch_list[idx],
1833 .band = band,
1834 };
1835
1836 mt76_get_rate_power_limits(phy, &chan, &limits,
1837 tx_power);
1838
1839 tx_power_tlv.last_msg = ch_list[idx] == last_ch;
1840 sku_tlbv.channel = ch_list[idx];
1841
1842 mt76_connac_mcu_build_sku(dev, sku_tlbv.pwr_limit,
1843 &limits, band);
1844 skb_put_data(skb, &sku_tlbv, sku_len);
1845 }
1846 __skb_push(skb, sizeof(tx_power_tlv));
1847 memcpy(skb->data, &tx_power_tlv, sizeof(tx_power_tlv));
1848
1849 err = mt76_mcu_skb_send_msg(dev, skb,
1850 MCU_CMD_SET_RATE_TX_POWER, false);
1851 if (err < 0)
1852 return err;
1853 }
1854
1855 return 0;
1856 }
1857
mt76_connac_mcu_set_rate_txpower(struct mt76_phy * phy)1858 int mt76_connac_mcu_set_rate_txpower(struct mt76_phy *phy)
1859 {
1860 int err;
1861
1862 if (phy->cap.has_2ghz) {
1863 err = mt76_connac_mcu_rate_txpower_band(phy,
1864 NL80211_BAND_2GHZ);
1865 if (err < 0)
1866 return err;
1867 }
1868 if (phy->cap.has_5ghz) {
1869 err = mt76_connac_mcu_rate_txpower_band(phy,
1870 NL80211_BAND_5GHZ);
1871 if (err < 0)
1872 return err;
1873 }
1874
1875 return 0;
1876 }
1877 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_rate_txpower);
1878
mt76_connac_mcu_update_arp_filter(struct mt76_dev * dev,struct mt76_vif * vif,struct ieee80211_bss_conf * info)1879 int mt76_connac_mcu_update_arp_filter(struct mt76_dev *dev,
1880 struct mt76_vif *vif,
1881 struct ieee80211_bss_conf *info)
1882 {
1883 struct sk_buff *skb;
1884 int i, len = min_t(int, info->arp_addr_cnt,
1885 IEEE80211_BSS_ARP_ADDR_LIST_LEN);
1886 struct {
1887 struct {
1888 u8 bss_idx;
1889 u8 pad[3];
1890 } __packed hdr;
1891 struct mt76_connac_arpns_tlv arp;
1892 } req_hdr = {
1893 .hdr = {
1894 .bss_idx = vif->idx,
1895 },
1896 .arp = {
1897 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
1898 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
1899 .ips_num = len,
1900 .mode = 2, /* update */
1901 .option = 1,
1902 },
1903 };
1904
1905 skb = mt76_mcu_msg_alloc(dev, NULL,
1906 sizeof(req_hdr) + len * sizeof(__be32));
1907 if (!skb)
1908 return -ENOMEM;
1909
1910 skb_put_data(skb, &req_hdr, sizeof(req_hdr));
1911 for (i = 0; i < len; i++) {
1912 u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
1913
1914 memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
1915 }
1916
1917 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_OFFLOAD, true);
1918 }
1919 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_arp_filter);
1920
1921 #ifdef CONFIG_PM
1922
1923 const struct wiphy_wowlan_support mt76_connac_wowlan_support = {
1924 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
1925 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
1926 .n_patterns = 1,
1927 .pattern_min_len = 1,
1928 .pattern_max_len = MT76_CONNAC_WOW_PATTEN_MAX_LEN,
1929 .max_nd_match_sets = 10,
1930 };
1931 EXPORT_SYMBOL_GPL(mt76_connac_wowlan_support);
1932
1933 static void
mt76_connac_mcu_key_iter(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,void * data)1934 mt76_connac_mcu_key_iter(struct ieee80211_hw *hw,
1935 struct ieee80211_vif *vif,
1936 struct ieee80211_sta *sta,
1937 struct ieee80211_key_conf *key,
1938 void *data)
1939 {
1940 struct mt76_connac_gtk_rekey_tlv *gtk_tlv = data;
1941 u32 cipher;
1942
1943 if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
1944 key->cipher != WLAN_CIPHER_SUITE_CCMP &&
1945 key->cipher != WLAN_CIPHER_SUITE_TKIP)
1946 return;
1947
1948 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1949 cipher = BIT(3);
1950 else
1951 cipher = BIT(4);
1952
1953 /* we are assuming here to have a single pairwise key */
1954 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
1955 if (key->cipher == WLAN_CIPHER_SUITE_TKIP)
1956 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
1957 else
1958 gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
1959
1960 gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
1961 gtk_tlv->keyid = key->keyidx;
1962 } else {
1963 gtk_tlv->group_cipher = cpu_to_le32(cipher);
1964 }
1965 }
1966
mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct cfg80211_gtk_rekey_data * key)1967 int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
1968 struct ieee80211_vif *vif,
1969 struct cfg80211_gtk_rekey_data *key)
1970 {
1971 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
1972 struct mt76_connac_gtk_rekey_tlv *gtk_tlv;
1973 struct mt76_phy *phy = hw->priv;
1974 struct sk_buff *skb;
1975 struct {
1976 u8 bss_idx;
1977 u8 pad[3];
1978 } __packed hdr = {
1979 .bss_idx = mvif->idx,
1980 };
1981
1982 skb = mt76_mcu_msg_alloc(phy->dev, NULL,
1983 sizeof(hdr) + sizeof(*gtk_tlv));
1984 if (!skb)
1985 return -ENOMEM;
1986
1987 skb_put_data(skb, &hdr, sizeof(hdr));
1988 gtk_tlv = (struct mt76_connac_gtk_rekey_tlv *)skb_put(skb,
1989 sizeof(*gtk_tlv));
1990 gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
1991 gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
1992 gtk_tlv->rekey_mode = 2;
1993 gtk_tlv->option = 1;
1994
1995 rcu_read_lock();
1996 ieee80211_iter_keys_rcu(hw, vif, mt76_connac_mcu_key_iter, gtk_tlv);
1997 rcu_read_unlock();
1998
1999 memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
2000 memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
2001 memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
2002
2003 return mt76_mcu_skb_send_msg(phy->dev, skb, MCU_UNI_CMD_OFFLOAD, true);
2004 }
2005 EXPORT_SYMBOL_GPL(mt76_connac_mcu_update_gtk_rekey);
2006
2007 static int
mt76_connac_mcu_set_arp_filter(struct mt76_dev * dev,struct ieee80211_vif * vif,bool suspend)2008 mt76_connac_mcu_set_arp_filter(struct mt76_dev *dev, struct ieee80211_vif *vif,
2009 bool suspend)
2010 {
2011 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2012 struct {
2013 struct {
2014 u8 bss_idx;
2015 u8 pad[3];
2016 } __packed hdr;
2017 struct mt76_connac_arpns_tlv arpns;
2018 } req = {
2019 .hdr = {
2020 .bss_idx = mvif->idx,
2021 },
2022 .arpns = {
2023 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
2024 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
2025 .mode = suspend,
2026 },
2027 };
2028
2029 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2030 true);
2031 }
2032
2033 static int
mt76_connac_mcu_set_gtk_rekey(struct mt76_dev * dev,struct ieee80211_vif * vif,bool suspend)2034 mt76_connac_mcu_set_gtk_rekey(struct mt76_dev *dev, struct ieee80211_vif *vif,
2035 bool suspend)
2036 {
2037 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2038 struct {
2039 struct {
2040 u8 bss_idx;
2041 u8 pad[3];
2042 } __packed hdr;
2043 struct mt76_connac_gtk_rekey_tlv gtk_tlv;
2044 } __packed req = {
2045 .hdr = {
2046 .bss_idx = mvif->idx,
2047 },
2048 .gtk_tlv = {
2049 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
2050 .len = cpu_to_le16(sizeof(struct mt76_connac_gtk_rekey_tlv)),
2051 .rekey_mode = !suspend,
2052 },
2053 };
2054
2055 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
2056 true);
2057 }
2058
2059 static int
mt76_connac_mcu_set_suspend_mode(struct mt76_dev * dev,struct ieee80211_vif * vif,bool enable,u8 mdtim,bool wow_suspend)2060 mt76_connac_mcu_set_suspend_mode(struct mt76_dev *dev,
2061 struct ieee80211_vif *vif,
2062 bool enable, u8 mdtim,
2063 bool wow_suspend)
2064 {
2065 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2066 struct {
2067 struct {
2068 u8 bss_idx;
2069 u8 pad[3];
2070 } __packed hdr;
2071 struct mt76_connac_suspend_tlv suspend_tlv;
2072 } req = {
2073 .hdr = {
2074 .bss_idx = mvif->idx,
2075 },
2076 .suspend_tlv = {
2077 .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
2078 .len = cpu_to_le16(sizeof(struct mt76_connac_suspend_tlv)),
2079 .enable = enable,
2080 .mdtim = mdtim,
2081 .wow_suspend = wow_suspend,
2082 },
2083 };
2084
2085 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2086 true);
2087 }
2088
2089 static int
mt76_connac_mcu_set_wow_pattern(struct mt76_dev * dev,struct ieee80211_vif * vif,u8 index,bool enable,struct cfg80211_pkt_pattern * pattern)2090 mt76_connac_mcu_set_wow_pattern(struct mt76_dev *dev,
2091 struct ieee80211_vif *vif,
2092 u8 index, bool enable,
2093 struct cfg80211_pkt_pattern *pattern)
2094 {
2095 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2096 struct mt76_connac_wow_pattern_tlv *ptlv;
2097 struct sk_buff *skb;
2098 struct req_hdr {
2099 u8 bss_idx;
2100 u8 pad[3];
2101 } __packed hdr = {
2102 .bss_idx = mvif->idx,
2103 };
2104
2105 skb = mt76_mcu_msg_alloc(dev, NULL, sizeof(hdr) + sizeof(*ptlv));
2106 if (!skb)
2107 return -ENOMEM;
2108
2109 skb_put_data(skb, &hdr, sizeof(hdr));
2110 ptlv = (struct mt76_connac_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
2111 ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
2112 ptlv->len = cpu_to_le16(sizeof(*ptlv));
2113 ptlv->data_len = pattern->pattern_len;
2114 ptlv->enable = enable;
2115 ptlv->index = index;
2116
2117 memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
2118 memcpy(ptlv->mask, pattern->mask, DIV_ROUND_UP(pattern->pattern_len, 8));
2119
2120 return mt76_mcu_skb_send_msg(dev, skb, MCU_UNI_CMD_SUSPEND, true);
2121 }
2122
2123 static int
mt76_connac_mcu_set_wow_ctrl(struct mt76_phy * phy,struct ieee80211_vif * vif,bool suspend,struct cfg80211_wowlan * wowlan)2124 mt76_connac_mcu_set_wow_ctrl(struct mt76_phy *phy, struct ieee80211_vif *vif,
2125 bool suspend, struct cfg80211_wowlan *wowlan)
2126 {
2127 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
2128 struct mt76_dev *dev = phy->dev;
2129 struct {
2130 struct {
2131 u8 bss_idx;
2132 u8 pad[3];
2133 } __packed hdr;
2134 struct mt76_connac_wow_ctrl_tlv wow_ctrl_tlv;
2135 struct mt76_connac_wow_gpio_param_tlv gpio_tlv;
2136 } req = {
2137 .hdr = {
2138 .bss_idx = mvif->idx,
2139 },
2140 .wow_ctrl_tlv = {
2141 .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
2142 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_ctrl_tlv)),
2143 .cmd = suspend ? 1 : 2,
2144 },
2145 .gpio_tlv = {
2146 .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
2147 .len = cpu_to_le16(sizeof(struct mt76_connac_wow_gpio_param_tlv)),
2148 .gpio_pin = 0xff, /* follow fw about GPIO pin */
2149 },
2150 };
2151
2152 if (wowlan->magic_pkt)
2153 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_MAGIC;
2154 if (wowlan->disconnect)
2155 req.wow_ctrl_tlv.trigger |= (UNI_WOW_DETECT_TYPE_DISCONNECT |
2156 UNI_WOW_DETECT_TYPE_BCN_LOST);
2157 if (wowlan->nd_config) {
2158 mt76_connac_mcu_sched_scan_req(phy, vif, wowlan->nd_config);
2159 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_SCH_SCAN_HIT;
2160 mt76_connac_mcu_sched_scan_enable(phy, vif, suspend);
2161 }
2162 if (wowlan->n_patterns)
2163 req.wow_ctrl_tlv.trigger |= UNI_WOW_DETECT_TYPE_BITMAP;
2164
2165 if (mt76_is_mmio(dev))
2166 req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
2167 else if (mt76_is_usb(dev))
2168 req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
2169 else if (mt76_is_sdio(dev))
2170 req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
2171
2172 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_SUSPEND, &req, sizeof(req),
2173 true);
2174 }
2175
mt76_connac_mcu_set_hif_suspend(struct mt76_dev * dev,bool suspend)2176 int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend)
2177 {
2178 struct {
2179 struct {
2180 u8 hif_type; /* 0x0: HIF_SDIO
2181 * 0x1: HIF_USB
2182 * 0x2: HIF_PCIE
2183 */
2184 u8 pad[3];
2185 } __packed hdr;
2186 struct hif_suspend_tlv {
2187 __le16 tag;
2188 __le16 len;
2189 u8 suspend;
2190 } __packed hif_suspend;
2191 } req = {
2192 .hif_suspend = {
2193 .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
2194 .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
2195 .suspend = suspend,
2196 },
2197 };
2198
2199 if (mt76_is_mmio(dev))
2200 req.hdr.hif_type = 2;
2201 else if (mt76_is_usb(dev))
2202 req.hdr.hif_type = 1;
2203 else if (mt76_is_sdio(dev))
2204 req.hdr.hif_type = 0;
2205
2206 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_HIF_CTRL, &req, sizeof(req),
2207 true);
2208 }
2209 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_hif_suspend);
2210
mt76_connac_mcu_set_suspend_iter(void * priv,u8 * mac,struct ieee80211_vif * vif)2211 void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
2212 struct ieee80211_vif *vif)
2213 {
2214 struct mt76_phy *phy = priv;
2215 bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->state);
2216 struct ieee80211_hw *hw = phy->hw;
2217 struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
2218 int i;
2219
2220 mt76_connac_mcu_set_gtk_rekey(phy->dev, vif, suspend);
2221 mt76_connac_mcu_set_arp_filter(phy->dev, vif, suspend);
2222
2223 mt76_connac_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
2224
2225 for (i = 0; i < wowlan->n_patterns; i++)
2226 mt76_connac_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
2227 &wowlan->patterns[i]);
2228 mt76_connac_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
2229 }
2230 EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_suspend_iter);
2231
2232 #endif /* CONFIG_PM */
2233
2234 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
2235 MODULE_LICENSE("Dual BSD/GPL");
2236