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