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