Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2020 MediaTek Inc. */
0003 
0004 #include <linux/fs.h>
0005 #include "mt7921.h"
0006 #include "mt7921_trace.h"
0007 #include "mcu.h"
0008 #include "mac.h"
0009 
0010 #define MT_STA_BFER         BIT(0)
0011 #define MT_STA_BFEE         BIT(1)
0012 
0013 static int
0014 mt7921_mcu_parse_eeprom(struct mt76_dev *dev, struct sk_buff *skb)
0015 {
0016     struct mt7921_mcu_eeprom_info *res;
0017     u8 *buf;
0018 
0019     if (!skb)
0020         return -EINVAL;
0021 
0022     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0023 
0024     res = (struct mt7921_mcu_eeprom_info *)skb->data;
0025     buf = dev->eeprom.data + le32_to_cpu(res->addr);
0026     memcpy(buf, res->data, 16);
0027 
0028     return 0;
0029 }
0030 
0031 int mt7921_mcu_parse_response(struct mt76_dev *mdev, int cmd,
0032                   struct sk_buff *skb, int seq)
0033 {
0034     int mcu_cmd = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
0035     struct mt76_connac2_mcu_rxd *rxd;
0036     int ret = 0;
0037 
0038     if (!skb) {
0039         dev_err(mdev->dev, "Message %08x (seq %d) timeout\n",
0040             cmd, seq);
0041         mt7921_reset(mdev);
0042 
0043         return -ETIMEDOUT;
0044     }
0045 
0046     rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
0047     if (seq != rxd->seq)
0048         return -EAGAIN;
0049 
0050     if (cmd == MCU_CMD(PATCH_SEM_CONTROL) ||
0051         cmd == MCU_CMD(PATCH_FINISH_REQ)) {
0052         skb_pull(skb, sizeof(*rxd) - 4);
0053         ret = *skb->data;
0054     } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
0055         skb_pull(skb, sizeof(*rxd) + 4);
0056         ret = le32_to_cpu(*(__le32 *)skb->data);
0057     } else if (cmd == MCU_EXT_CMD(EFUSE_ACCESS)) {
0058         ret = mt7921_mcu_parse_eeprom(mdev, skb);
0059     } else if (cmd == MCU_UNI_CMD(DEV_INFO_UPDATE) ||
0060            cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) ||
0061            cmd == MCU_UNI_CMD(STA_REC_UPDATE) ||
0062            cmd == MCU_UNI_CMD(HIF_CTRL) ||
0063            cmd == MCU_UNI_CMD(OFFLOAD) ||
0064            cmd == MCU_UNI_CMD(SUSPEND)) {
0065         struct mt7921_mcu_uni_event *event;
0066 
0067         skb_pull(skb, sizeof(*rxd));
0068         event = (struct mt7921_mcu_uni_event *)skb->data;
0069         ret = le32_to_cpu(event->status);
0070         /* skip invalid event */
0071         if (mcu_cmd != event->cid)
0072             ret = -EAGAIN;
0073     } else if (cmd == MCU_CE_QUERY(REG_READ)) {
0074         struct mt7921_mcu_reg_event *event;
0075 
0076         skb_pull(skb, sizeof(*rxd));
0077         event = (struct mt7921_mcu_reg_event *)skb->data;
0078         ret = (int)le32_to_cpu(event->val);
0079     } else {
0080         skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0081     }
0082 
0083     return ret;
0084 }
0085 EXPORT_SYMBOL_GPL(mt7921_mcu_parse_response);
0086 
0087 #ifdef CONFIG_PM
0088 
0089 static int
0090 mt7921_mcu_set_ipv6_ns_filter(struct mt76_dev *dev,
0091                   struct ieee80211_vif *vif, bool suspend)
0092 {
0093     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0094     struct {
0095         struct {
0096             u8 bss_idx;
0097             u8 pad[3];
0098         } __packed hdr;
0099         struct mt76_connac_arpns_tlv arpns;
0100     } req = {
0101         .hdr = {
0102             .bss_idx = mvif->mt76.idx,
0103         },
0104         .arpns = {
0105             .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ND),
0106             .len = cpu_to_le16(sizeof(struct mt76_connac_arpns_tlv)),
0107             .mode = suspend,
0108         },
0109     };
0110 
0111     return mt76_mcu_send_msg(dev, MCU_UNI_CMD_OFFLOAD, &req, sizeof(req),
0112                  true);
0113 }
0114 
0115 void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
0116 {
0117     if (IS_ENABLED(CONFIG_IPV6)) {
0118         struct mt76_phy *phy = priv;
0119 
0120         mt7921_mcu_set_ipv6_ns_filter(phy->dev, vif,
0121                           !test_bit(MT76_STATE_RUNNING,
0122                           &phy->state));
0123     }
0124 
0125     mt76_connac_mcu_set_suspend_iter(priv, mac, vif);
0126 }
0127 
0128 #endif /* CONFIG_PM */
0129 
0130 static void
0131 mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb)
0132 {
0133     struct mt76_phy *mphy = &dev->mt76.phy;
0134     struct mt7921_phy *phy = (struct mt7921_phy *)mphy->priv;
0135 
0136     spin_lock_bh(&dev->mt76.lock);
0137     __skb_queue_tail(&phy->scan_event_list, skb);
0138     spin_unlock_bh(&dev->mt76.lock);
0139 
0140     ieee80211_queue_delayed_work(mphy->hw, &phy->scan_work,
0141                      MT7921_HW_SCAN_TIMEOUT);
0142 }
0143 
0144 static void
0145 mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
0146                 struct ieee80211_vif *vif)
0147 {
0148     struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
0149     struct mt76_connac_beacon_loss_event *event = priv;
0150 
0151     if (mvif->idx != event->bss_idx)
0152         return;
0153 
0154     if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER) ||
0155         vif->type != NL80211_IFTYPE_STATION)
0156         return;
0157 
0158     ieee80211_connection_loss(vif);
0159 }
0160 
0161 static void
0162 mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
0163 {
0164     struct mt76_connac_beacon_loss_event *event;
0165     struct mt76_phy *mphy = &dev->mt76.phy;
0166 
0167     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0168     event = (struct mt76_connac_beacon_loss_event *)skb->data;
0169 
0170     ieee80211_iterate_active_interfaces_atomic(mphy->hw,
0171                     IEEE80211_IFACE_ITER_RESUME_ALL,
0172                     mt7921_mcu_connection_loss_iter, event);
0173 }
0174 
0175 static void
0176 mt7921_mcu_bss_event(struct mt7921_dev *dev, struct sk_buff *skb)
0177 {
0178     struct mt76_phy *mphy = &dev->mt76.phy;
0179     struct mt76_connac_mcu_bss_event *event;
0180 
0181     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0182     event = (struct mt76_connac_mcu_bss_event *)skb->data;
0183     if (event->is_absent)
0184         ieee80211_stop_queues(mphy->hw);
0185     else
0186         ieee80211_wake_queues(mphy->hw);
0187 }
0188 
0189 static void
0190 mt7921_mcu_debug_msg_event(struct mt7921_dev *dev, struct sk_buff *skb)
0191 {
0192     struct mt7921_debug_msg {
0193         __le16 id;
0194         u8 type;
0195         u8 flag;
0196         __le32 value;
0197         __le16 len;
0198         u8 content[512];
0199     } __packed * msg;
0200 
0201     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0202     msg = (struct mt7921_debug_msg *)skb->data;
0203 
0204     if (msg->type == 3) { /* fw log */
0205         u16 len = min_t(u16, le16_to_cpu(msg->len), 512);
0206         int i;
0207 
0208         for (i = 0 ; i < len; i++) {
0209             if (!msg->content[i])
0210                 msg->content[i] = ' ';
0211         }
0212         wiphy_info(mt76_hw(dev)->wiphy, "%.*s", len, msg->content);
0213     }
0214 }
0215 
0216 static void
0217 mt7921_mcu_low_power_event(struct mt7921_dev *dev, struct sk_buff *skb)
0218 {
0219     struct mt7921_mcu_lp_event {
0220         u8 state;
0221         u8 reserved[3];
0222     } __packed * event;
0223 
0224     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0225     event = (struct mt7921_mcu_lp_event *)skb->data;
0226 
0227     trace_lp_event(dev, event->state);
0228 }
0229 
0230 static void
0231 mt7921_mcu_tx_done_event(struct mt7921_dev *dev, struct sk_buff *skb)
0232 {
0233     struct mt7921_mcu_tx_done_event *event;
0234 
0235     skb_pull(skb, sizeof(struct mt76_connac2_mcu_rxd));
0236     event = (struct mt7921_mcu_tx_done_event *)skb->data;
0237 
0238     mt7921_mac_add_txs(dev, event->txs);
0239 }
0240 
0241 static void
0242 mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
0243 {
0244     struct mt76_connac2_mcu_rxd *rxd;
0245 
0246     rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
0247     switch (rxd->eid) {
0248     case MCU_EVENT_BSS_BEACON_LOSS:
0249         mt7921_mcu_connection_loss_event(dev, skb);
0250         break;
0251     case MCU_EVENT_SCHED_SCAN_DONE:
0252     case MCU_EVENT_SCAN_DONE:
0253         mt7921_mcu_scan_event(dev, skb);
0254         return;
0255     case MCU_EVENT_BSS_ABSENCE:
0256         mt7921_mcu_bss_event(dev, skb);
0257         break;
0258     case MCU_EVENT_DBG_MSG:
0259         mt7921_mcu_debug_msg_event(dev, skb);
0260         break;
0261     case MCU_EVENT_COREDUMP:
0262         dev->fw_assert = true;
0263         mt76_connac_mcu_coredump_event(&dev->mt76, skb,
0264                            &dev->coredump);
0265         return;
0266     case MCU_EVENT_LP_INFO:
0267         mt7921_mcu_low_power_event(dev, skb);
0268         break;
0269     case MCU_EVENT_TX_DONE:
0270         mt7921_mcu_tx_done_event(dev, skb);
0271         break;
0272     default:
0273         break;
0274     }
0275     dev_kfree_skb(skb);
0276 }
0277 
0278 void mt7921_mcu_rx_event(struct mt7921_dev *dev, struct sk_buff *skb)
0279 {
0280     struct mt76_connac2_mcu_rxd *rxd;
0281 
0282     if (skb_linearize(skb))
0283         return;
0284 
0285     rxd = (struct mt76_connac2_mcu_rxd *)skb->data;
0286 
0287     if (rxd->eid == 0x6) {
0288         mt76_mcu_rx_event(&dev->mt76, skb);
0289         return;
0290     }
0291 
0292     if (rxd->ext_eid == MCU_EXT_EVENT_RATE_REPORT ||
0293         rxd->eid == MCU_EVENT_BSS_BEACON_LOSS ||
0294         rxd->eid == MCU_EVENT_SCHED_SCAN_DONE ||
0295         rxd->eid == MCU_EVENT_BSS_ABSENCE ||
0296         rxd->eid == MCU_EVENT_SCAN_DONE ||
0297         rxd->eid == MCU_EVENT_TX_DONE ||
0298         rxd->eid == MCU_EVENT_DBG_MSG ||
0299         rxd->eid == MCU_EVENT_COREDUMP ||
0300         rxd->eid == MCU_EVENT_LP_INFO ||
0301         !rxd->seq)
0302         mt7921_mcu_rx_unsolicited_event(dev, skb);
0303     else
0304         mt76_mcu_rx_event(&dev->mt76, skb);
0305 }
0306 
0307 /** starec & wtbl **/
0308 int mt7921_mcu_uni_tx_ba(struct mt7921_dev *dev,
0309              struct ieee80211_ampdu_params *params,
0310              bool enable)
0311 {
0312     struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
0313 
0314     if (enable && !params->amsdu)
0315         msta->wcid.amsdu = false;
0316 
0317     return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
0318                       MCU_UNI_CMD(STA_REC_UPDATE),
0319                       enable, true);
0320 }
0321 
0322 int mt7921_mcu_uni_rx_ba(struct mt7921_dev *dev,
0323              struct ieee80211_ampdu_params *params,
0324              bool enable)
0325 {
0326     struct mt7921_sta *msta = (struct mt7921_sta *)params->sta->drv_priv;
0327 
0328     return mt76_connac_mcu_sta_ba(&dev->mt76, &msta->vif->mt76, params,
0329                       MCU_UNI_CMD(STA_REC_UPDATE),
0330                       enable, false);
0331 }
0332 
0333 static char *mt7921_patch_name(struct mt7921_dev *dev)
0334 {
0335     char *ret;
0336 
0337     if (is_mt7922(&dev->mt76))
0338         ret = MT7922_ROM_PATCH;
0339     else
0340         ret = MT7921_ROM_PATCH;
0341 
0342     return ret;
0343 }
0344 
0345 static char *mt7921_ram_name(struct mt7921_dev *dev)
0346 {
0347     char *ret;
0348 
0349     if (is_mt7922(&dev->mt76))
0350         ret = MT7922_FIRMWARE_WM;
0351     else
0352         ret = MT7921_FIRMWARE_WM;
0353 
0354     return ret;
0355 }
0356 
0357 static int mt7921_load_firmware(struct mt7921_dev *dev)
0358 {
0359     int ret;
0360 
0361     ret = mt76_get_field(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY);
0362     if (ret && mt76_is_mmio(&dev->mt76)) {
0363         dev_dbg(dev->mt76.dev, "Firmware is already download\n");
0364         goto fw_loaded;
0365     }
0366 
0367     ret = mt76_connac2_load_patch(&dev->mt76, mt7921_patch_name(dev));
0368     if (ret)
0369         return ret;
0370 
0371     if (mt76_is_sdio(&dev->mt76)) {
0372         /* activate again */
0373         ret = __mt7921_mcu_fw_pmctrl(dev);
0374         if (!ret)
0375             ret = __mt7921_mcu_drv_pmctrl(dev);
0376     }
0377 
0378     ret = mt76_connac2_load_ram(&dev->mt76, mt7921_ram_name(dev), NULL);
0379     if (ret)
0380         return ret;
0381 
0382     if (!mt76_poll_msec(dev, MT_CONN_ON_MISC, MT_TOP_MISC2_FW_N9_RDY,
0383                 MT_TOP_MISC2_FW_N9_RDY, 1500)) {
0384         dev_err(dev->mt76.dev, "Timeout for initializing firmware\n");
0385 
0386         return -EIO;
0387     }
0388 
0389 fw_loaded:
0390 
0391 #ifdef CONFIG_PM
0392     dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
0393 #endif /* CONFIG_PM */
0394 
0395     dev_dbg(dev->mt76.dev, "Firmware init done\n");
0396 
0397     return 0;
0398 }
0399 
0400 int mt7921_mcu_fw_log_2_host(struct mt7921_dev *dev, u8 ctrl)
0401 {
0402     struct {
0403         u8 ctrl_val;
0404         u8 pad[3];
0405     } data = {
0406         .ctrl_val = ctrl
0407     };
0408 
0409     return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(FWLOG_2_HOST),
0410                  &data, sizeof(data), false);
0411 }
0412 
0413 int mt7921_run_firmware(struct mt7921_dev *dev)
0414 {
0415     int err;
0416 
0417     err = mt7921_load_firmware(dev);
0418     if (err)
0419         return err;
0420 
0421     err = mt76_connac_mcu_get_nic_capability(&dev->mphy);
0422     if (err)
0423         return err;
0424 
0425     set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
0426     return mt7921_mcu_fw_log_2_host(dev, 1);
0427 }
0428 EXPORT_SYMBOL_GPL(mt7921_run_firmware);
0429 
0430 int mt7921_mcu_set_tx(struct mt7921_dev *dev, struct ieee80211_vif *vif)
0431 {
0432     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0433     struct edca {
0434         __le16 cw_min;
0435         __le16 cw_max;
0436         __le16 txop;
0437         __le16 aifs;
0438         u8 guardtime;
0439         u8 acm;
0440     } __packed;
0441     struct mt7921_mcu_tx {
0442         struct edca edca[IEEE80211_NUM_ACS];
0443         u8 bss_idx;
0444         u8 qos;
0445         u8 wmm_idx;
0446         u8 pad;
0447     } __packed req = {
0448         .bss_idx = mvif->mt76.idx,
0449         .qos = vif->bss_conf.qos,
0450         .wmm_idx = mvif->mt76.wmm_idx,
0451     };
0452     struct mu_edca {
0453         u8 cw_min;
0454         u8 cw_max;
0455         u8 aifsn;
0456         u8 acm;
0457         u8 timer;
0458         u8 padding[3];
0459     };
0460     struct mt7921_mcu_mu_tx {
0461         u8 ver;
0462         u8 pad0;
0463         __le16 len;
0464         u8 bss_idx;
0465         u8 qos;
0466         u8 wmm_idx;
0467         u8 pad1;
0468         struct mu_edca edca[IEEE80211_NUM_ACS];
0469         u8 pad3[32];
0470     } __packed req_mu = {
0471         .bss_idx = mvif->mt76.idx,
0472         .qos = vif->bss_conf.qos,
0473         .wmm_idx = mvif->mt76.wmm_idx,
0474     };
0475     static const int to_aci[] = { 1, 0, 2, 3 };
0476     int ac, ret;
0477 
0478     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
0479         struct ieee80211_tx_queue_params *q = &mvif->queue_params[ac];
0480         struct edca *e = &req.edca[to_aci[ac]];
0481 
0482         e->aifs = cpu_to_le16(q->aifs);
0483         e->txop = cpu_to_le16(q->txop);
0484 
0485         if (q->cw_min)
0486             e->cw_min = cpu_to_le16(q->cw_min);
0487         else
0488             e->cw_min = cpu_to_le16(5);
0489 
0490         if (q->cw_max)
0491             e->cw_max = cpu_to_le16(q->cw_max);
0492         else
0493             e->cw_max = cpu_to_le16(10);
0494     }
0495 
0496     ret = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_EDCA_PARMS), &req,
0497                 sizeof(req), false);
0498     if (ret)
0499         return ret;
0500 
0501     if (!vif->bss_conf.he_support)
0502         return 0;
0503 
0504     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
0505         struct ieee80211_he_mu_edca_param_ac_rec *q;
0506         struct mu_edca *e;
0507 
0508         if (!mvif->queue_params[ac].mu_edca)
0509             break;
0510 
0511         q = &mvif->queue_params[ac].mu_edca_param_rec;
0512         e = &(req_mu.edca[to_aci[ac]]);
0513 
0514         e->cw_min = q->ecw_min_max & 0xf;
0515         e->cw_max = (q->ecw_min_max & 0xf0) >> 4;
0516         e->aifsn = q->aifsn;
0517         e->timer = q->mu_edca_timer;
0518     }
0519 
0520     return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_MU_EDCA_PARMS),
0521                  &req_mu, sizeof(req_mu), false);
0522 }
0523 
0524 int mt7921_mcu_set_chan_info(struct mt7921_phy *phy, int cmd)
0525 {
0526     struct mt7921_dev *dev = phy->dev;
0527     struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
0528     int freq1 = chandef->center_freq1;
0529     struct {
0530         u8 control_ch;
0531         u8 center_ch;
0532         u8 bw;
0533         u8 tx_streams_num;
0534         u8 rx_streams;  /* mask or num */
0535         u8 switch_reason;
0536         u8 band_idx;
0537         u8 center_ch2;  /* for 80+80 only */
0538         __le16 cac_case;
0539         u8 channel_band;
0540         u8 rsv0;
0541         __le32 outband_freq;
0542         u8 txpower_drop;
0543         u8 ap_bw;
0544         u8 ap_center_ch;
0545         u8 rsv1[57];
0546     } __packed req = {
0547         .control_ch = chandef->chan->hw_value,
0548         .center_ch = ieee80211_frequency_to_channel(freq1),
0549         .bw = mt76_connac_chan_bw(chandef),
0550         .tx_streams_num = hweight8(phy->mt76->antenna_mask),
0551         .rx_streams = phy->mt76->antenna_mask,
0552         .band_idx = phy != &dev->phy,
0553     };
0554 
0555     if (chandef->chan->band == NL80211_BAND_6GHZ)
0556         req.channel_band = 2;
0557     else
0558         req.channel_band = chandef->chan->band;
0559 
0560     if (cmd == MCU_EXT_CMD(SET_RX_PATH) ||
0561         dev->mt76.hw->conf.flags & IEEE80211_CONF_MONITOR)
0562         req.switch_reason = CH_SWITCH_NORMAL;
0563     else if (dev->mt76.hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
0564         req.switch_reason = CH_SWITCH_SCAN_BYPASS_DPD;
0565     else if (!cfg80211_reg_can_beacon(dev->mt76.hw->wiphy, chandef,
0566                       NL80211_IFTYPE_AP))
0567         req.switch_reason = CH_SWITCH_DFS;
0568     else
0569         req.switch_reason = CH_SWITCH_NORMAL;
0570 
0571     if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
0572         req.rx_streams = hweight8(req.rx_streams);
0573 
0574     if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
0575         int freq2 = chandef->center_freq2;
0576 
0577         req.center_ch2 = ieee80211_frequency_to_channel(freq2);
0578     }
0579 
0580     return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
0581 }
0582 
0583 int mt7921_mcu_set_eeprom(struct mt7921_dev *dev)
0584 {
0585     struct req_hdr {
0586         u8 buffer_mode;
0587         u8 format;
0588         __le16 len;
0589     } __packed req = {
0590         .buffer_mode = EE_MODE_EFUSE,
0591         .format = EE_FORMAT_WHOLE,
0592     };
0593 
0594     return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
0595                  &req, sizeof(req), true);
0596 }
0597 EXPORT_SYMBOL_GPL(mt7921_mcu_set_eeprom);
0598 
0599 int mt7921_mcu_uni_bss_ps(struct mt7921_dev *dev, struct ieee80211_vif *vif)
0600 {
0601     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0602     struct {
0603         struct {
0604             u8 bss_idx;
0605             u8 pad[3];
0606         } __packed hdr;
0607         struct ps_tlv {
0608             __le16 tag;
0609             __le16 len;
0610             u8 ps_state; /* 0: device awake
0611                       * 1: static power save
0612                       * 2: dynamic power saving
0613                       * 3: enter TWT power saving
0614                       * 4: leave TWT power saving
0615                       */
0616             u8 pad[3];
0617         } __packed ps;
0618     } __packed ps_req = {
0619         .hdr = {
0620             .bss_idx = mvif->mt76.idx,
0621         },
0622         .ps = {
0623             .tag = cpu_to_le16(UNI_BSS_INFO_PS),
0624             .len = cpu_to_le16(sizeof(struct ps_tlv)),
0625             .ps_state = vif->cfg.ps ? 2 : 0,
0626         },
0627     };
0628 
0629     if (vif->type != NL80211_IFTYPE_STATION)
0630         return -EOPNOTSUPP;
0631 
0632     return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
0633                  &ps_req, sizeof(ps_req), true);
0634 }
0635 
0636 static int
0637 mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
0638              bool enable)
0639 {
0640     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0641     struct {
0642         struct {
0643             u8 bss_idx;
0644             u8 pad[3];
0645         } __packed hdr;
0646         struct bcnft_tlv {
0647             __le16 tag;
0648             __le16 len;
0649             __le16 bcn_interval;
0650             u8 dtim_period;
0651             u8 pad;
0652         } __packed bcnft;
0653     } __packed bcnft_req = {
0654         .hdr = {
0655             .bss_idx = mvif->mt76.idx,
0656         },
0657         .bcnft = {
0658             .tag = cpu_to_le16(UNI_BSS_INFO_BCNFT),
0659             .len = cpu_to_le16(sizeof(struct bcnft_tlv)),
0660             .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
0661             .dtim_period = vif->bss_conf.dtim_period,
0662         },
0663     };
0664 
0665     if (vif->type != NL80211_IFTYPE_STATION)
0666         return 0;
0667 
0668     return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
0669                  &bcnft_req, sizeof(bcnft_req), true);
0670 }
0671 
0672 int
0673 mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
0674               bool enable)
0675 {
0676     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0677     struct {
0678         u8 bss_idx;
0679         u8 dtim_period;
0680         __le16 aid;
0681         __le16 bcn_interval;
0682         __le16 atim_window;
0683         u8 uapsd;
0684         u8 bmc_delivered_ac;
0685         u8 bmc_triggered_ac;
0686         u8 pad;
0687     } req = {
0688         .bss_idx = mvif->mt76.idx,
0689         .aid = cpu_to_le16(vif->cfg.aid),
0690         .dtim_period = vif->bss_conf.dtim_period,
0691         .bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int),
0692     };
0693     struct {
0694         u8 bss_idx;
0695         u8 pad[3];
0696     } req_hdr = {
0697         .bss_idx = mvif->mt76.idx,
0698     };
0699     int err;
0700 
0701     err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
0702                 &req_hdr, sizeof(req_hdr), false);
0703     if (err < 0 || !enable)
0704         return err;
0705 
0706     return mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_CONNECTED),
0707                  &req, sizeof(req), false);
0708 }
0709 
0710 int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
0711               struct ieee80211_vif *vif, bool enable,
0712               enum mt76_sta_info_state state)
0713 {
0714     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0715     int rssi = -ewma_rssi_read(&mvif->rssi);
0716     struct mt76_sta_cmd_info info = {
0717         .sta = sta,
0718         .vif = vif,
0719         .enable = enable,
0720         .cmd = MCU_UNI_CMD(STA_REC_UPDATE),
0721         .state = state,
0722         .offload_fw = true,
0723         .rcpi = to_rcpi(rssi),
0724     };
0725     struct mt7921_sta *msta;
0726 
0727     msta = sta ? (struct mt7921_sta *)sta->drv_priv : NULL;
0728     info.wcid = msta ? &msta->wcid : &mvif->sta.wcid;
0729     info.newly = msta ? state != MT76_STA_INFO_STATE_ASSOC : true;
0730 
0731     return mt76_connac_mcu_sta_cmd(&dev->mphy, &info);
0732 }
0733 
0734 int mt7921_mcu_drv_pmctrl(struct mt7921_dev *dev)
0735 {
0736     struct mt76_phy *mphy = &dev->mt76.phy;
0737     struct mt76_connac_pm *pm = &dev->pm;
0738     int err = 0;
0739 
0740     mutex_lock(&pm->mutex);
0741 
0742     if (!test_bit(MT76_STATE_PM, &mphy->state))
0743         goto out;
0744 
0745     err = __mt7921_mcu_drv_pmctrl(dev);
0746 out:
0747     mutex_unlock(&pm->mutex);
0748 
0749     if (err)
0750         mt7921_reset(&dev->mt76);
0751 
0752     return err;
0753 }
0754 EXPORT_SYMBOL_GPL(mt7921_mcu_drv_pmctrl);
0755 
0756 int mt7921_mcu_fw_pmctrl(struct mt7921_dev *dev)
0757 {
0758     struct mt76_phy *mphy = &dev->mt76.phy;
0759     struct mt76_connac_pm *pm = &dev->pm;
0760     int err = 0;
0761 
0762     mutex_lock(&pm->mutex);
0763 
0764     if (mt76_connac_skip_fw_pmctrl(mphy, pm))
0765         goto out;
0766 
0767     err = __mt7921_mcu_fw_pmctrl(dev);
0768 out:
0769     mutex_unlock(&pm->mutex);
0770 
0771     if (err)
0772         mt7921_reset(&dev->mt76);
0773 
0774     return err;
0775 }
0776 EXPORT_SYMBOL_GPL(mt7921_mcu_fw_pmctrl);
0777 
0778 int mt7921_mcu_set_beacon_filter(struct mt7921_dev *dev,
0779                  struct ieee80211_vif *vif,
0780                  bool enable)
0781 {
0782     int err;
0783 
0784     if (enable) {
0785         err = mt7921_mcu_uni_bss_bcnft(dev, vif, true);
0786         if (err)
0787             return err;
0788 
0789         mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
0790 
0791         return 0;
0792     }
0793 
0794     err = mt7921_mcu_set_bss_pm(dev, vif, false);
0795     if (err)
0796         return err;
0797 
0798     mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
0799 
0800     return 0;
0801 }
0802 
0803 int mt7921_get_txpwr_info(struct mt7921_dev *dev, struct mt7921_txpwr *txpwr)
0804 {
0805     struct mt7921_txpwr_event *event;
0806     struct mt7921_txpwr_req req = {
0807         .dbdc_idx = 0,
0808     };
0809     struct sk_buff *skb;
0810     int ret;
0811 
0812     ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_CE_CMD(GET_TXPWR),
0813                     &req, sizeof(req), true, &skb);
0814     if (ret)
0815         return ret;
0816 
0817     event = (struct mt7921_txpwr_event *)skb->data;
0818     WARN_ON(skb->len != le16_to_cpu(event->len));
0819     memcpy(txpwr, &event->txpwr, sizeof(event->txpwr));
0820 
0821     dev_kfree_skb(skb);
0822 
0823     return 0;
0824 }
0825 
0826 int mt7921_mcu_set_sniffer(struct mt7921_dev *dev, struct ieee80211_vif *vif,
0827                bool enable)
0828 {
0829     struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
0830     struct {
0831         struct {
0832             u8 band_idx;
0833             u8 pad[3];
0834         } __packed hdr;
0835         struct sniffer_enable_tlv {
0836             __le16 tag;
0837             __le16 len;
0838             u8 enable;
0839             u8 pad[3];
0840         } __packed enable;
0841     } req = {
0842         .hdr = {
0843             .band_idx = mvif->band_idx,
0844         },
0845         .enable = {
0846             .tag = cpu_to_le16(0),
0847             .len = cpu_to_le16(sizeof(struct sniffer_enable_tlv)),
0848             .enable = enable,
0849         },
0850     };
0851 
0852     return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(SNIFFER), &req, sizeof(req),
0853                  true);
0854 }
0855 
0856 int
0857 mt7921_mcu_uni_add_beacon_offload(struct mt7921_dev *dev,
0858                   struct ieee80211_hw *hw,
0859                   struct ieee80211_vif *vif,
0860                   bool enable)
0861 {
0862     struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
0863     struct mt76_wcid *wcid = &dev->mt76.global_wcid;
0864     struct ieee80211_mutable_offsets offs;
0865     struct {
0866         struct req_hdr {
0867             u8 bss_idx;
0868             u8 pad[3];
0869         } __packed hdr;
0870         struct bcn_content_tlv {
0871             __le16 tag;
0872             __le16 len;
0873             __le16 tim_ie_pos;
0874             __le16 csa_ie_pos;
0875             __le16 bcc_ie_pos;
0876             /* 0: disable beacon offload
0877              * 1: enable beacon offload
0878              * 2: update probe respond offload
0879              */
0880             u8 enable;
0881             /* 0: legacy format (TXD + payload)
0882              * 1: only cap field IE
0883              */
0884             u8 type;
0885             __le16 pkt_len;
0886             u8 pkt[512];
0887         } __packed beacon_tlv;
0888     } req = {
0889         .hdr = {
0890             .bss_idx = mvif->mt76.idx,
0891         },
0892         .beacon_tlv = {
0893             .tag = cpu_to_le16(UNI_BSS_INFO_BCN_CONTENT),
0894             .len = cpu_to_le16(sizeof(struct bcn_content_tlv)),
0895             .enable = enable,
0896         },
0897     };
0898     struct sk_buff *skb;
0899 
0900     /* support enable/update process only
0901      * disable flow would be handled in bss stop handler automatically
0902      */
0903     if (!enable)
0904         return -EOPNOTSUPP;
0905 
0906     skb = ieee80211_beacon_get_template(mt76_hw(dev), vif, &offs, 0);
0907     if (!skb)
0908         return -EINVAL;
0909 
0910     if (skb->len > 512 - MT_TXD_SIZE) {
0911         dev_err(dev->mt76.dev, "beacon size limit exceed\n");
0912         dev_kfree_skb(skb);
0913         return -EINVAL;
0914     }
0915 
0916     mt76_connac2_mac_write_txwi(&dev->mt76, (__le32 *)(req.beacon_tlv.pkt),
0917                     skb, wcid, NULL, 0, 0, BSS_CHANGED_BEACON);
0918     memcpy(req.beacon_tlv.pkt + MT_TXD_SIZE, skb->data, skb->len);
0919     req.beacon_tlv.pkt_len = cpu_to_le16(MT_TXD_SIZE + skb->len);
0920     req.beacon_tlv.tim_ie_pos = cpu_to_le16(MT_TXD_SIZE + offs.tim_offset);
0921 
0922     if (offs.cntdwn_counter_offs[0]) {
0923         u16 csa_offs;
0924 
0925         csa_offs = MT_TXD_SIZE + offs.cntdwn_counter_offs[0] - 4;
0926         req.beacon_tlv.csa_ie_pos = cpu_to_le16(csa_offs);
0927     }
0928     dev_kfree_skb(skb);
0929 
0930     return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD(BSS_INFO_UPDATE),
0931                  &req, sizeof(req), true);
0932 }