blob: 9d533fa5c618b982d13075826b44b6e358872836 [file] [log] [blame]
developer0f312e82022-11-01 12:31:52 +08001// SPDX-License-Identifier: ISC
2/* Copyright (C) 2020 MediaTek Inc. */
3
4#include <linux/fs.h>
5#include <linux/firmware.h>
6#include "mt7921.h"
7#include "mt7921_trace.h"
8#include "eeprom.h"
9#include "mcu.h"
10#include "mac.h"
11
12#define MT_STA_BFER BIT(0)
13#define MT_STA_BFEE BIT(1)
14
15static bool mt7921_disable_clc;
16module_param_named(disable_clc, mt7921_disable_clc, bool, 0644);
17MODULE_PARM_DESC(disable_clc, "disable CLC support");
18
19static int
20mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb)
21{
22 struct mt7921_mcu_eeprom_info *res;
23 u8 *buf;
24
25 if (!skb)
26 return -EINVAL;
27
28 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
29
30 res = (struct mt7921_mcu_eeprom_info *)skb->data;
31 buf = dev->eeprom.data + le32_to_cpu(res->addr);
32 memcpy(buf, res->data, 16);
33
34 return 0;
35}
36
37int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
38 struct sk_buff *skb, int seq)
39{
40 int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
41 struct mt76_connac2_mcu_rxd *rxd;
42 int ret = 0;
43
44 if (!skb) {
45 dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
46 cmd, seq);
47 mt7921_reset(mdev);
48
49 return -ETIMEDOUT;
50 }
51
52 rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
53 if (seq != rxd->seq)
54 return -EAGAIN;
55
56 if (cmd == MCU_CMD(PATCH_SEM_CONTROL) ||
57 cmd == MCU_CMD(PATCH_FINISH_REQ)) {
58 skb_pull(skb, sizeof(*rxd) - 4);
59 ret = *skb->data;
60 } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
61 skb_pull(skb, sizeof(*rxd) + 4);
62 ret = le32_to_cpu(*(__le32 *)skb->data);
63 } else if (cmd == MCU_EXT_CMD(EFUSE_ACCESS)) {
64 ret = mt7921_mcu_parse_eeprom(mdev, skb);
65 } else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
66 cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
67 cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
68 cmd == MCU_UNI_CMD(HIF_CTRL) ||
69 cmd == MCU_UNI_CMD(OFFLOAD) ||
70 cmd == MCU_UNI_CMD(SUSPEND)) {
71 struct mt7921_mcu_uni_event *event;
72
73 skb_pull(skb, sizeof(*rxd));
74 event = (struct mt7921_mcu_uni_event *)skb->data;
75 ret = le32_to_cpu(event->status);
76 /* skip invalid event */
77 if (mcu_cmd != event->cid)
78 ret = -EAGAIN;
79 } else if (cmd == MCU_CE_QUERY(REG_READ)) {
80 struct mt7921_mcu_reg_event *event;
81
82 skb_pull(skb, sizeof(*rxd));
83 event = (struct mt7921_mcu_reg_event *)skb->data;
84 ret = (int)le32_to_cpu(event->val);
85 } else {
86 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
87 }
88
89 return ret;
90}
91EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response);
92
93static int mt7921_mcu_read_eeprom(struct mt7921_dev *dev, u32 offset, u8 *val)
94{
95 struct mt7921_mcu_eeprom_info *res, req = {
96 .addr = cpu_to_le32(round_down(offset,
97 MT7921_EEPROM_BLOCK_SIZE)),
98 };
99 struct sk_buff *skb;
100 int ret;
101
102 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS),
103 &req, sizeof(req), true, &skb);
104 if (ret)
105 return ret;
106
107 res = (struct mt7921_mcu_eeprom_info *)skb->data;
108 *val = res->data[offset % MT7921_EEPROM_BLOCK_SIZE];
109 dev_kfree_skb(skb);
110
111 return 0;
112}
113
114#ifdef CONFIG_PM
115
116static int
117mt7921_mcu_set_ipv6_ns_filter(struct mt76_dev *dev,
118 struct ieee80211_vif *vif, bool suspend)
119{
120 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
121 struct {
122 struct {
123 u8 bss_idx;
124 u8 pad[3];
125 } __packed hdr;
126 struct mt76_connac_arpns_tlv arpns;
127 } req = {
128 .hdr = {
129 .bss_idx = mvif->mt76.idx,
130 },
131 .arpns = {
132 .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ND),
133 .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
134 .mode = suspend,
135 },
136 };
137
138 return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
139 true);
140}
141
142void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
143{
144 if (IS_ENABLED(CONFIG_IPV6)) {
145 struct mt76_phy *phy = priv;
146
147 mt7921_mcu_set_ipv6_ns_filter(phy->dev, vif,
148 !test_bit(MT76_STATE_RUNNING,
149 &phy->state));
150 }
151
152 mt76_connac_mcu_set_suspend_iter(priv, mac, vif);
153}
154
155#endif /* CONFIG_PM */
156
157static void
158mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb)
159{
160 struct mt76_phy *mphy = &dev->mt76.phy;
161 struct mt7921_phy *phy = (struct mt7921_phy *)mphy->priv;
162
163 spin_lock_bh(&dev->mt76.lock);
164 __skb_queue_tail(&phy->scan_event_list, skb);
165 spin_unlock_bh(&dev->mt76.lock);
166
167 ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work,
168 MT7921_HW_SCAN_TIMEOUT);
169}
170
171static void
172mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
173 struct ieee80211_vif *vif)
174{
175 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
176 struct mt76_connac_beacon_loss_event *event = priv;
177
178 if (mvif->idx != event->bss_idx)
179 return;
180
181 if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
182 vif->type != NL80211_IFTYPE_STATION)
183 return;
184
185 ieee80211_connection_loss(vif);
186}
187
188static void
189mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
190{
191 struct mt76_connac_beacon_loss_event *event;
192 struct mt76_phy *mphy = &dev->mt76.phy;
193
194 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
195 event = (struct mt76_connac_beacon_loss_event *)skb->data;
196
197 ieee80211_iterate_active_interfaces_atomic(mphy->hw,
198 IEEE80211_IFACE_ITER_RESUME_ALL,
199 mt7921_mcu_connection_loss_iter, event);
200}
201
202static void
203mt7921_mcu_bss_event(struct mt7921_dev *dev, struct sk_buff *skb)
204{
205 struct mt76_phy *mphy = &dev->mt76.phy;
206 struct mt76_connac_mcu_bss_event *event;
207
208 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
209 event = (struct mt76_connac_mcu_bss_event *)skb->data;
210 if (event->is_absent)
211 ieee80211_stop_queues(mphy->hw);
212 else
213 ieee80211_wake_queues(mphy->hw);
214}
215
216static void
217mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb)
218{
219 struct mt7921_debug_msg {
220 __le16 id;
221 u8 type;
222 u8 flag;
223 __le32 value;
224 __le16 len;
225 u8 content[512];
226 } __packed * msg;
227
228 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
229 msg = (struct mt7921_debug_msg *)skb->data;
230
231 if (msg->type == 3) { /* fw log */
232 u16 len = min_t(u16, le16_to_cpu(msg->len), 512);
233 int i;
234
235 for (i = 0 ; i < len; i++) {
236 if (!msg->content[i])
237 msg->content[i] = ' ';
238 }
239 wiphy_info(mt76_hw(dev)->wiphy, "%.*s", len, msg->content);
240 }
241}
242
243static void
244mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
245{
246 struct mt7921_mcu_lp_event {
247 u8 state;
248 u8 reserved[3];
249 } __packed * event;
250
251 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
252 event = (struct mt7921_mcu_lp_event *)skb->data;
253
254 trace_lp_event(dev, event->state);
255}
256
257static void
258mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
259{
260 struct mt7921_mcu_tx_done_event *event;
261
262 skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
263 event = (struct mt7921_mcu_tx_done_event *)skb->data;
264
265 mt7921_mac_add_txs(dev, event->txs);
266}
267
268static void
269mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
270{
271 struct mt76_connac2_mcu_rxd *rxd;
272
273 rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
274 switch (rxd->eid) {
275 case MCU_EVENT_BSS_BEACON_LOSS:
276 mt7921_mcu_connection_loss_event(dev, skb);
277 break;
278 case MCU_EVENT_SCHED_SCAN_DONE:
279 case MCU_EVENT_SCAN_DONE:
280 mt7921_mcu_scan_event(dev, skb);
281 return;
282 case MCU_EVENT_BSS_ABSENCE:
283 mt7921_mcu_bss_event(dev, skb);
284 break;
285 case MCU_EVENT_DBG_MSG:
286 mt7921_mcu_debug_msg_event(dev, skb);
287 break;
288 case MCU_EVENT_COREDUMP:
289 dev->fw_assert = true;
290 mt76_connac_mcu_coredump_event(&dev->mt76, skb,
291 &dev->coredump);
292 return;
293 case MCU_EVENT_LP_INFO:
294 mt7921_mcu_low_power_event(dev, skb);
295 break;
296 case MCU_EVENT_TX_DONE:
297 mt7921_mcu_tx_done_event(dev, skb);
298 break;
299 default:
300 break;
301 }
302 dev_kfree_skb(skb);
303}
304
305void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb)
306{
307 struct mt76_connac2_mcu_rxd *rxd;
308
309 if (skb_linearize(skb))
310 return;
311
312 rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
313
314 if (rxd->eid == 0x6) {
315 mt76_mcu_rx_event(&dev->mt76, skb);
316 return;
317 }
318
319 if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
320 rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
321 rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
322 rxd->eid == MCU_EVENT_BSS_ABSENCE ||
323 rxd->eid == MCU_EVENT_SCAN_DONE ||
324 rxd->eid == MCU_EVENT_TX_DONE ||
325 rxd->eid == MCU_EVENT_DBG_MSG ||
326 rxd->eid == MCU_EVENT_COREDUMP ||
327 rxd->eid == MCU_EVENT_LP_INFO ||
328 !rxd->seq)
329 mt7921_mcu_rx_unsolicited_event(dev, skb);
330 else
331 mt76_mcu_rx_event(&dev->mt76, skb);
332}
333
334/** starec & wtbl **/
335int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev,
336 struct ieee80211_ampdu_params *params,
337 bool enable)
338{
339 struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
340
341 if (enable && !params->amsdu)
342 msta->wcid.amsdu = false;
343
344 return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
345 MCU_UNI_CMD(STA_REC_UPDATE),
346 enable, true);
347}
348
349int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev,
350 struct ieee80211_ampdu_params *params,
351 bool enable)
352{
353 struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
354
355 return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
356 MCU_UNI_CMD(STA_REC_UPDATE),
357 enable, false);
358}
359
360static char *mt7921_patch_name(struct mt7921_dev *dev)
361{
362 char *ret;
363
364 if (is_mt7922(&dev->mt76))
365 ret = MT7922_ROM_PATCH;
366 else
367 ret = MT7921_ROM_PATCH;
368
369 return ret;
370}
371
372static char *mt7921_ram_name(struct mt7921_dev *dev)
373{
374 char *ret;
375
376 if (is_mt7922(&dev->mt76))
377 ret = MT7922_FIRMWARE_WM;
378 else
379 ret = MT7921_FIRMWARE_WM;
380
381 return ret;
382}
383
384static int mt7921_load_clc(struct mt7921_dev *dev, const char *fw_name)
385{
386 const struct mt76_connac2_fw_trailer *hdr;
387 const struct mt76_connac2_fw_region *region;
388 const struct mt7921_clc *clc;
389 struct mt76_dev *mdev = &dev->mt76;
390 struct mt7921_phy *phy = &dev->phy;
391 const struct firmware *fw;
392 int ret, i, len, offset = 0;
393 u8 *clc_base = NULL, hw_encap = 0;
394
395 if (mt7921_disable_clc ||
396 mt76_is_usb(&dev->mt76))
397 return 0;
398
399 if (mt76_is_mmio(&dev->mt76)) {
400 ret = mt7921_mcu_read_eeprom(dev, MT_EE_HW_TYPE, &hw_encap);
401 if (ret)
402 return ret;
403 hw_encap = u8_get_bits(hw_encap, MT_EE_HW_TYPE_ENCAP);
404 }
405
406 ret = request_firmware(&fw, fw_name, mdev->dev);
407 if (ret)
408 return ret;
409
410 if (!fw || !fw->data || fw->size < sizeof(*hdr)) {
411 dev_err(mdev->dev, "Invalid firmware\n");
412 ret = -EINVAL;
413 goto out;
414 }
415
416 hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
417 for (i = 0; i < hdr->n_region; i++) {
418 region = (const void *)((const u8 *)hdr -
419 (hdr->n_region - i) * sizeof(*region));
420 len = le32_to_cpu(region->len);
421
422 /* check if we have valid buffer size */
423 if (offset + len > fw->size) {
424 dev_err(mdev->dev, "Invalid firmware region\n");
425 ret = -EINVAL;
426 goto out;
427 }
428
429 if ((region->feature_set & FW_FEATURE_NON_DL) &&
430 region->type == FW_TYPE_CLC) {
431 clc_base = (u8 *)(fw->data + offset);
432 break;
433 }
434 offset += len;
435 }
436
437 if (!clc_base)
438 goto out;
439
440 for (offset = 0; offset < len; offset += le32_to_cpu(clc->len)) {
441 clc = (const struct mt7921_clc *)(clc_base + offset);
442
443 /* do not init buf again if chip reset triggered */
444 if (phy->clc[clc->idx])
445 continue;
446
447 /* header content sanity */
448 if (clc->idx == MT7921_CLC_POWER &&
449 u8_get_bits(clc->type, MT_EE_HW_TYPE_ENCAP) != hw_encap)
450 continue;
451
452 phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
453 le32_to_cpu(clc->len),
454 GFP_KERNEL);
455
456 if (!phy->clc[clc->idx]) {
457 ret = -ENOMEM;
458 goto out;
459 }
460 }
461 ret = mt7921_mcu_set_clc(dev, "00", ENVIRON_INDOOR);
462out:
463 release_firmware(fw);
464
465 return ret;
466}
467
468static int mt7921_load_firmware(struct mt7921_dev *dev)
469{
470 int ret;
471
472 ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
473 if (ret && mt76_is_mmio(&dev->mt76)) {
474 dev_dbg(dev->mt76.dev, "Firmware is already download\n");
475 goto fw_loaded;
476 }
477
478 ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev));
479 if (ret)
480 return ret;
481
482 if (mt76_is_sdio(&dev->mt76)) {
483 /* activate again */
484 ret = __mt7921_mcu_fw_pmctrl(dev);
485 if (!ret)
486 ret = __mt7921_mcu_drv_pmctrl(dev);
487 }
488
489 ret = mt76_connac2_load_ram(&dev->mt76, mt7921_ram_name(dev), NULL);
490 if (ret)
491 return ret;
492
493 if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
494 MT_TOP_MISC2_FW_N9_RDY, 1500)) {
495 dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
496
497 return -EIO;
498 }
499
500fw_loaded:
501
502#ifdef CONFIG_PM
503 dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
504#endif /* CONFIG_PM */
505
506 dev_dbg(dev->mt76.dev, "Firmware init done\n");
507
508 return 0;
509}
510
511int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl)
512{
513 struct {
514 u8 ctrl_val;
515 u8 pad[3];
516 } data = {
517 .ctrl_val = ctrl
518 };
519
520 return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(FWLOG_2_HOST),
521 &data, sizeof(data), false);
522}
523
524int mt7921_run_firmware(struct mt7921_dev *dev)
525{
526 int err;
527
528 err = mt7921_load_firmware(dev);
529 if (err)
530 return err;
531
532 err = mt76_connac_mcu_get_nic_capability(&dev->mphy);
533 if (err)
534 return err;
535
536 set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
537 err = mt7921_load_clc(dev, mt7921_ram_name(dev));
538 if (err)
539 return err;
540
541 return mt7921_mcu_fw_log_2_host(dev, 1);
542}
543EXPORT_SYMBOL_GPL(mt7921_run_firmware);
544
545int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
546{
547 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
548 struct edca {
549 __le16 cw_min;
550 __le16 cw_max;
551 __le16 txop;
552 __le16 aifs;
553 u8 guardtime;
554 u8 acm;
555 } __packed;
556 struct mt7921_mcu_tx {
557 struct edca edca[IEEE80211_NUM_ACS];
558 u8 bss_idx;
559 u8 qos;
560 u8 wmm_idx;
561 u8 pad;
562 } __packed req = {
563 .bss_idx = mvif->mt76.idx,
564 .qos = vif->bss_conf.qos,
565 .wmm_idx = mvif->mt76.wmm_idx,
566 };
567 struct mu_edca {
568 u8 cw_min;
569 u8 cw_max;
570 u8 aifsn;
571 u8 acm;
572 u8 timer;
573 u8 padding[3];
574 };
575 struct mt7921_mcu_mu_tx {
576 u8 ver;
577 u8 pad0;
578 __le16 len;
579 u8 bss_idx;
580 u8 qos;
581 u8 wmm_idx;
582 u8 pad1;
583 struct mu_edca edca[IEEE80211_NUM_ACS];
584 u8 pad3[32];
585 } __packed req_mu = {
586 .bss_idx = mvif->mt76.idx,
587 .qos = vif->bss_conf.qos,
588 .wmm_idx = mvif->mt76.wmm_idx,
589 };
590 static const int to_aci[] = { 1, 0, 2, 3 };
591 int ac, ret;
592
593 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
594 struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];
595 struct edca *e = &req.edca[to_aci[ac]];
596
597 e->aifs = cpu_to_le16(q->aifs);
598 e->txop = cpu_to_le16(q->txop);
599
600 if (q->cw_min)
601 e->cw_min = cpu_to_le16(q->cw_min);
602 else
603 e->cw_min = cpu_to_le16(5);
604
605 if (q->cw_max)
606 e->cw_max = cpu_to_le16(q->cw_max);
607 else
608 e->cw_max = cpu_to_le16(10);
609 }
610
611 ret = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_EDCA_PARMS), &req,
612 sizeof(req), false);
613 if (ret)
614 return ret;
615
616 if (!vif->bss_conf.he_support)
617 return 0;
618
619 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
620 struct ieee80211_he_mu_edca_param_ac_rec *q;
621 struct mu_edca *e;
622
623 if (!mvif->queue_params[ac].mu_edca)
624 break;
625
626 q = &mvif->queue_params[ac].mu_edca_param_rec;
627 e = &(req_mu.edca[to_aci[ac]]);
628
629 e->cw_min = q->ecw_min_max & 0xf;
630 e->cw_max = (q->ecw_min_max & 0xf0) >> 4;
631 e->aifsn = q->aifsn;
632 e->timer = q->mu_edca_timer;
633 }
634
635 return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_MU_EDCA_PARMS),
636 &req_mu, sizeof(req_mu), false);
637}
638
639int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
640{
641 struct mt7921_dev *dev = phy->dev;
642 struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
643 int freq1 = chandef->center_freq1;
644 struct {
645 u8 control_ch;
646 u8 center_ch;
647 u8 bw;
648 u8 tx_streams_num;
649 u8 rx_streams; /* mask or num */
650 u8 switch_reason;
651 u8 band_idx;
652 u8 center_ch2; /* for 80+80 only */
653 __le16 cac_case;
654 u8 channel_band;
655 u8 rsv0;
656 __le32 outband_freq;
657 u8 txpower_drop;
658 u8 ap_bw;
659 u8 ap_center_ch;
660 u8 rsv1[57];
661 } __packed req = {
662 .control_ch = chandef->chan->hw_value,
663 .center_ch = ieee80211_frequency_to_channel(freq1),
664 .bw = mt76_connac_chan_bw(chandef),
665 .tx_streams_num = hweight8(phy->mt76->antenna_mask),
666 .rx_streams = phy->mt76->antenna_mask,
667 .band_idx = phy != &dev->phy,
668 };
669
670 if (chandef->chan->band == NL80211_BAND_6GHZ)
671 req.channel_band = 2;
672 else
673 req.channel_band = chandef->chan->band;
674
675 if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
676 dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
677 req.switch_reason = CH_SWITCH_NORMAL;
678 else if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
679 req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
680 else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
681 NL80211_IFTYPE_AP))
682 req.switch_reason = CH_SWITCH_DFS;
683 else
684 req.switch_reason = CH_SWITCH_NORMAL;
685
686 if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
687 req.rx_streams = hweight8(req.rx_streams);
688
689 if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
690 int freq2 = chandef->center_freq2;
691
692 req.center_ch2 = ieee80211_frequency_to_channel(freq2);
693 }
694
695 return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
696}
697
698int mt7921_mcu_set_eeprom(struct mt7921_dev *dev)
699{
700 struct req_hdr {
701 u8 buffer_mode;
702 u8 format;
703 __le16 len;
704 } __packed req = {
705 .buffer_mode = EE_MODE_EFUSE,
706 .format = EE_FORMAT_WHOLE,
707 };
708
709 return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
710 &req, sizeof(req), true);
711}
712EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom);
713
714int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif)
715{
716 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
717 struct {
718 struct {
719 u8 bss_idx;
720 u8 pad[3];
721 } __packed hdr;
722 struct ps_tlv {
723 __le16 tag;
724 __le16 len;
725 u8 ps_state; /* 0: device awake
726 * 1: static power save
727 * 2: dynamic power saving
728 * 3: enter TWT power saving
729 * 4: leave TWT power saving
730 */
731 u8 pad[3];
732 } __packed ps;
733 } __packed ps_req = {
734 .hdr = {
735 .bss_idx = mvif->mt76.idx,
736 },
737 .ps = {
738 .tag = cpu_to_le16(UNI_BSS_INFO_PS),
739 .len = cpu_to_le16(sizeof(struct ps_tlv)),
740 .ps_state = vif->bss_conf.ps ? 2 : 0,
741 },
742 };
743
744 if (vif->type != NL80211_IFTYPE_STATION)
745 return -EOPNOTSUPP;
746
747 return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
748 &ps_req, sizeof(ps_req), true);
749}
750
751static int
752mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
753 bool enable)
754{
755 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
756 struct {
757 struct {
758 u8 bss_idx;
759 u8 pad[3];
760 } __packed hdr;
761 struct bcnft_tlv {
762 __le16 tag;
763 __le16 len;
764 __le16 bcn_interval;
765 u8 dtim_period;
766 u8 pad;
767 } __packed bcnft;
768 } __packed bcnft_req = {
769 .hdr = {
770 .bss_idx = mvif->mt76.idx,
771 },
772 .bcnft = {
773 .tag = cpu_to_le16(UNI_BSS_INFO_BCNFT),
774 .len = cpu_to_le16(sizeof(struct bcnft_tlv)),
775 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
776 .dtim_period = vif->bss_conf.dtim_period,
777 },
778 };
779
780 if (vif->type != NL80211_IFTYPE_STATION)
781 return 0;
782
783 return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
784 &bcnft_req, sizeof(bcnft_req), true);
785}
786
787int
788mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
789 bool enable)
790{
791 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
792 struct {
793 u8 bss_idx;
794 u8 dtim_period;
795 __le16 aid;
796 __le16 bcn_interval;
797 __le16 atim_window;
798 u8 uapsd;
799 u8 bmc_delivered_ac;
800 u8 bmc_triggered_ac;
801 u8 pad;
802 } req = {
803 .bss_idx = mvif->mt76.idx,
804 .aid = cpu_to_le16(vif->bss_conf.aid),
805 .dtim_period = vif->bss_conf.dtim_period,
806 .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
807 };
808 struct {
809 u8 bss_idx;
810 u8 pad[3];
811 } req_hdr = {
812 .bss_idx = mvif->mt76.idx,
813 };
814 int err;
815
816 err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
817 &req_hdr, sizeof(req_hdr), false);
818 if (err < 0 || !enable)
819 return err;
820
821 return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
822 &req, sizeof(req), false);
823}
824
825int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
826 struct ieee80211_vif *vif, bool enable,
827 enum mt76_sta_info_state state)
828{
829 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
830 int rssi = -ewma_rssi_read(&mvif->rssi);
831 struct mt76_sta_cmd_info info = {
832 .sta = sta,
833 .vif = vif,
834 .enable = enable,
835 .cmd = MCU_UNI_CMD(STA_REC_UPDATE),
836 .state = state,
837 .offload_fw = true,
838 .rcpi = to_rcpi(rssi),
839 };
840 struct mt7921_sta *msta;
841
842 msta = sta ? (struct mt7921_sta *)sta->drv_priv : NULL;
843 info.wcid = msta ? &msta->wcid : &mvif->sta.wcid;
844 info.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true;
845
846 return mt76_connac_mcu_sta_cmd(&dev->mphy, &info);
847}
848
849int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
850{
851 struct mt76_phy *mphy = &dev->mt76.phy;
852 struct mt76_connac_pm *pm = &dev->pm;
853 int err = 0;
854
855 mutex_lock(&pm->mutex);
856
857 if (!test_bit(MT76_STATE_PM, &mphy->state))
858 goto out;
859
860 err = __mt7921_mcu_drv_pmctrl(dev);
861out:
862 mutex_unlock(&pm->mutex);
863
864 if (err)
865 mt7921_reset(&dev->mt76);
866
867 return err;
868}
869EXPORT_SYMBOL_GPL(mt7921_mcu_drv_pmctrl);
870
871int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev)
872{
873 struct mt76_phy *mphy = &dev->mt76.phy;
874 struct mt76_connac_pm *pm = &dev->pm;
875 int err = 0;
876
877 mutex_lock(&pm->mutex);
878
879 if (mt76_connac_skip_fw_pmctrl(mphy, pm))
880 goto out;
881
882 err = __mt7921_mcu_fw_pmctrl(dev);
883out:
884 mutex_unlock(&pm->mutex);
885
886 if (err)
887 mt7921_reset(&dev->mt76);
888
889 return err;
890}
891EXPORT_SYMBOL_GPL(mt7921_mcu_fw_pmctrl);
892
893int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
894 struct ieee80211_vif *vif,
895 bool enable)
896{
897 int err;
898
899 if (enable) {
900 err = mt7921_mcu_uni_bss_bcnft(dev, vif, true);
901 if (err)
902 return err;
903
904 mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
905
906 return 0;
907 }
908
909 err = mt7921_mcu_set_bss_pm(dev, vif, false);
910 if (err)
911 return err;
912
913 mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
914
915 return 0;
916}
917
918int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr)
919{
920 struct mt7921_txpwr_event *event;
921 struct mt7921_txpwr_req req = {
922 .dbdc_idx = 0,
923 };
924 struct sk_buff *skb;
925 int ret;
926
927 ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(GET_TXPWR),
928 &req, sizeof(req), true, &skb);
929 if (ret)
930 return ret;
931
932 event = (struct mt7921_txpwr_event *)skb->data;
933 WARN_ON(skb->len != le16_to_cpu(event->len));
934 memcpy(txpwr, &event->txpwr, sizeof(event->txpwr));
935
936 dev_kfree_skb(skb);
937
938 return 0;
939}
940
941int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
942 bool enable)
943{
944 struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
945 struct {
946 struct {
947 u8 band_idx;
948 u8 pad[3];
949 } __packed hdr;
950 struct sniffer_enable_tlv {
951 __le16 tag;
952 __le16 len;
953 u8 enable;
954 u8 pad[3];
955 } __packed enable;
956 } req = {
957 .hdr = {
958 .band_idx = mvif->band_idx,
959 },
960 .enable = {
961 .tag = cpu_to_le16(0),
962 .len = cpu_to_le16(sizeof(struct sniffer_enable_tlv)),
963 .enable = enable,
964 },
965 };
966
967 return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
968 true);
969}
970
971int
972mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
973 struct ieee80211_hw *hw,
974 struct ieee80211_vif *vif,
975 bool enable)
976{
977 struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
978 struct mt76_wcid *wcid = &dev->mt76.global_wcid;
979 struct ieee80211_mutable_offsets offs;
980 struct {
981 struct req_hdr {
982 u8 bss_idx;
983 u8 pad[3];
984 } __packed hdr;
985 struct bcn_content_tlv {
986 __le16 tag;
987 __le16 len;
988 __le16 tim_ie_pos;
989 __le16 csa_ie_pos;
990 __le16 bcc_ie_pos;
991 /* 0: disable beacon offload
992 * 1: enable beacon offload
993 * 2: update probe respond offload
994 */
995 u8 enable;
996 /* 0: legacy format (TXD + payload)
997 * 1: only cap field IE
998 */
999 u8 type;
1000 __le16 pkt_len;
1001 u8 pkt[512];
1002 } __packed beacon_tlv;
1003 } req = {
1004 .hdr = {
1005 .bss_idx = mvif->mt76.idx,
1006 },
1007 .beacon_tlv = {
1008 .tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
1009 .len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
1010 .enable = enable,
1011 },
1012 };
1013 struct sk_buff *skb;
1014
1015 /* support enable/update process only
1016 * disable flow would be handled in bss stop handler automatically
1017 */
1018 if (!enable)
1019 return -EOPNOTSUPP;
1020
1021 skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs);
1022 if (!skb)
1023 return -EINVAL;
1024
1025 if (skb->len > 512 - MT_TXD_SIZE) {
1026 dev_err(dev->mt76.dev, "beacon size limit exceed\n");
1027 dev_kfree_skb(skb);
1028 return -EINVAL;
1029 }
1030
1031 mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt),
1032 skb, wcid, NULL, 0, 0, BSS_CHANGED_BEACON);
1033 memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
1034 req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
1035 req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
1036
1037 if (offs.cntdwn_counter_offs[0]) {
1038 u16 csa_offs;
1039
1040 csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
1041 req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
1042 }
1043 dev_kfree_skb(skb);
1044
1045 return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
1046 &req, sizeof(req), true);
1047}
1048
1049static
1050int __mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
1051 enum environment_cap env_cap,
1052 struct mt7921_clc *clc,
1053 u8 idx)
1054{
1055 struct sk_buff *skb;
1056 struct {
1057 u8 ver;
1058 u8 pad0;
1059 __le16 len;
1060 u8 idx;
1061 u8 env;
1062 u8 pad1[2];
1063 u8 alpha2[2];
1064 u8 type[2];
1065 u8 rsvd[64];
1066 } __packed req = {
1067 .idx = idx,
1068 .env = env_cap,
1069 };
1070 int ret, valid_cnt = 0;
1071 u8 i, *pos;
1072
1073 if (!clc)
1074 return 0;
1075
1076 pos = clc->data;
1077 for (i = 0; i < clc->nr_country; i++) {
1078 struct mt7921_clc_rule *rule = (struct mt7921_clc_rule *)pos;
1079 u16 len = le16_to_cpu(rule->len);
1080
1081 pos += len + sizeof(*rule);
1082 if (rule->alpha2[0] != alpha2[0] ||
1083 rule->alpha2[1] != alpha2[1])
1084 continue;
1085
1086 memcpy(req.alpha2, rule->alpha2, 2);
1087 memcpy(req.type, rule->type, 2);
1088
1089 req.len = cpu_to_le16(sizeof(req) + len);
1090 skb = __mt76_mcu_msg_alloc(&dev->mt76, &req,
1091 le16_to_cpu(req.len),
1092 sizeof(req), GFP_KERNEL);
1093 if (!skb)
1094 return -ENOMEM;
1095 skb_put_data(skb, rule->data, len);
1096
1097 ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
1098 MCU_CE_CMD(SET_CLC), false);
1099 if (ret < 0)
1100 return ret;
1101 valid_cnt++;
1102 }
1103
1104 if (!valid_cnt)
1105 return -ENOENT;
1106
1107 return 0;
1108}
1109
1110int mt7921_mcu_set_clc(struct mt7921_dev *dev, u8 *alpha2,
1111 enum environment_cap env_cap)
1112{
1113 struct mt7921_phy *phy = (struct mt7921_phy *)&dev->phy;
1114 int i, ret;
1115
1116 /* submit all clc config */
1117 for (i = 0; i < ARRAY_SIZE(phy->clc); i++) {
1118 ret = __mt7921_mcu_set_clc(dev, alpha2, env_cap,
1119 phy->clc[i], i);
1120
1121 /* If no country found, set "00" as default */
1122 if (ret == -ENOENT)
1123 ret = __mt7921_mcu_set_clc(dev, "00",
1124 ENVIRON_INDOOR,
1125 phy->clc[i], i);
1126 if (ret < 0)
1127 return ret;
1128 }
1129 return 0;
1130}