Merge tag 'mt76-for-kvalo-2021-01-29' of https://github.com/nbd168/wireless
[linux-2.6-microblaze.git] / drivers / net / wireless / mediatek / mt76 / mt7915 / mcu.c
index 5fdd1a6..1959292 100644 (file)
@@ -66,9 +66,6 @@ struct mt7915_fw_region {
 
 #define MCU_PATCH_ADDRESS              0x200000
 
-#define MT_STA_BFER                    BIT(0)
-#define MT_STA_BFEE                    BIT(1)
-
 #define FW_FEATURE_SET_ENCRYPT         BIT(0)
 #define FW_FEATURE_SET_KEY_IDX         GENMASK(2, 1)
 #define FW_FEATURE_OVERRIDE_ADDR       BIT(5)
@@ -232,18 +229,14 @@ mt7915_mcu_parse_response(struct mt76_dev *mdev, int cmd,
        if (seq != rxd->seq)
                return -EAGAIN;
 
-       switch (cmd) {
-       case -MCU_CMD_PATCH_SEM_CONTROL:
+       if (cmd == MCU_CMD(PATCH_SEM_CONTROL)) {
                skb_pull(skb, sizeof(*rxd) - 4);
                ret = *skb->data;
-               break;
-       case MCU_EXT_CMD_THERMAL_CTRL:
+       } else if (cmd == MCU_EXT_CMD(THERMAL_CTRL)) {
                skb_pull(skb, sizeof(*rxd) + 4);
                ret = le32_to_cpu(*(__le32 *)skb->data);
-               break;
-       default:
+       } else {
                skb_pull(skb, sizeof(struct mt7915_mcu_rxd));
-               break;
        }
 
        return ret;
@@ -255,10 +248,10 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
 {
        struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
        struct mt7915_mcu_txd *mcu_txd;
-       u8 seq, pkt_fmt, qidx;
-       enum mt76_txq_id txq;
+       enum mt76_mcuq_id qid;
        __le32 *txd;
        u32 val;
+       u8 seq;
 
        /* TODO: make dynamic based on msg type */
        mdev->mcu.timeout = 20 * HZ;
@@ -267,28 +260,22 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
        if (!seq)
                seq = ++dev->mt76.mcu.msg_seq & 0xf;
 
-       if (cmd == -MCU_CMD_FW_SCATTER) {
-               txq = MT_MCUQ_FWDL;
+       if (cmd == MCU_CMD(FW_SCATTER)) {
+               qid = MT_MCUQ_FWDL;
                goto exit;
        }
 
        mcu_txd = (struct mt7915_mcu_txd *)skb_push(skb, sizeof(*mcu_txd));
-
-       if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state)) {
-               txq = MT_MCUQ_WA;
-               qidx = MT_TX_MCU_PORT_RX_Q0;
-               pkt_fmt = MT_TX_TYPE_CMD;
-       } else {
-               txq = MT_MCUQ_WM;
-               qidx = MT_TX_MCU_PORT_RX_Q0;
-               pkt_fmt = MT_TX_TYPE_CMD;
-       }
+       if (test_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state))
+               qid = MT_MCUQ_WA;
+       else
+               qid = MT_MCUQ_WM;
 
        txd = mcu_txd->txd;
 
        val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len) |
-             FIELD_PREP(MT_TXD0_PKT_FMT, pkt_fmt) |
-             FIELD_PREP(MT_TXD0_Q_IDX, qidx);
+             FIELD_PREP(MT_TXD0_PKT_FMT, MT_TX_TYPE_CMD) |
+             FIELD_PREP(MT_TXD0_Q_IDX, MT_TX_MCU_PORT_RX_Q0);
        txd[0] = cpu_to_le32(val);
 
        val = MT_TXD1_LONG_FORMAT |
@@ -296,37 +283,50 @@ mt7915_mcu_send_message(struct mt76_dev *mdev, struct sk_buff *skb,
        txd[1] = cpu_to_le32(val);
 
        mcu_txd->len = cpu_to_le16(skb->len - sizeof(mcu_txd->txd));
-       mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU, qidx));
+       mcu_txd->pq_id = cpu_to_le16(MCU_PQ_ID(MT_TX_PORT_IDX_MCU,
+                                              MT_TX_MCU_PORT_RX_Q0));
        mcu_txd->pkt_type = MCU_PKT_ID;
        mcu_txd->seq = seq;
 
-       if (cmd < 0) {
-               mcu_txd->set_query = MCU_Q_NA;
-               mcu_txd->cid = -cmd;
-       } else {
-               mcu_txd->cid = MCU_CMD_EXT_CID;
-               mcu_txd->ext_cid = cmd;
+       mcu_txd->cid = FIELD_GET(__MCU_CMD_FIELD_ID, cmd);
+       mcu_txd->set_query = MCU_Q_NA;
+       mcu_txd->ext_cid = FIELD_GET(__MCU_CMD_FIELD_EXT_ID, cmd);
+       if (mcu_txd->ext_cid) {
                mcu_txd->ext_cid_ack = 1;
 
                /* do not use Q_SET for efuse */
-               if (cmd == MCU_EXT_CMD_EFUSE_ACCESS)
+               if (cmd & __MCU_CMD_FIELD_QUERY)
                        mcu_txd->set_query = MCU_Q_QUERY;
                else
                        mcu_txd->set_query = MCU_Q_SET;
        }
 
-       if (cmd == MCU_EXT_CMD_MWDS_SUPPORT)
+       if (cmd & __MCU_CMD_FIELD_WA)
                mcu_txd->s2d_index = MCU_S2D_H2C;
        else
                mcu_txd->s2d_index = MCU_S2D_H2N;
-       WARN_ON(cmd == MCU_EXT_CMD_EFUSE_ACCESS &&
-               mcu_txd->set_query != MCU_Q_QUERY);
 
 exit:
        if (wait_seq)
                *wait_seq = seq;
 
-       return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[txq], skb, 0);
+       return mt76_tx_queue_skb_raw(dev, mdev->q_mcu[qid], skb, 0);
+}
+
+static void
+mt7915_mcu_wa_cmd(struct mt7915_dev *dev, int cmd, u32 a1, u32 a2, u32 a3)
+{
+       struct {
+               __le32 args[3];
+       } req = {
+               .args = {
+                       cpu_to_le32(a1),
+                       cpu_to_le32(a2),
+                       cpu_to_le32(a3),
+               },
+       };
+
+       mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
 }
 
 static void
@@ -674,6 +674,7 @@ mt7915_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
        switch (vif->type) {
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_MONITOR:
                break;
        case NL80211_IFTYPE_STATION:
                /* TODO: enable BSS_INFO_UAPSD & BSS_INFO_PM */
@@ -702,16 +703,21 @@ mt7915_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
        }
 
        bss = (struct bss_info_basic *)tlv;
-       memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
-       bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
        bss->network_type = cpu_to_le32(type);
-       bss->dtim_period = vif->bss_conf.dtim_period;
        bss->bmc_wcid_lo = to_wcid_lo(wlan_idx);
        bss->bmc_wcid_hi = to_wcid_hi(wlan_idx);
-       bss->phy_mode = mt7915_get_phy_mode(phy->dev, vif, band, NULL);
        bss->wmm_idx = mvif->wmm_idx;
        bss->active = enable;
 
+       if (vif->type != NL80211_IFTYPE_MONITOR) {
+               memcpy(bss->bssid, vif->bss_conf.bssid, ETH_ALEN);
+               bss->bcn_interval = cpu_to_le16(vif->bss_conf.beacon_int);
+               bss->dtim_period = vif->bss_conf.dtim_period;
+               bss->phy_mode = mt7915_get_phy_mode(phy->dev, vif, band, NULL);
+       } else {
+               memcpy(bss->bssid, phy->mt76->macaddr, ETH_ALEN);
+       }
+
        return 0;
 }
 
@@ -727,6 +733,7 @@ mt7915_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
        tlv = mt7915_mcu_add_tlv(skb, BSS_INFO_OMAC, sizeof(*omac));
 
        switch (vif->type) {
+       case NL80211_IFTYPE_MONITOR:
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
                type = CONNECTION_INFRA_AP;
@@ -832,9 +839,9 @@ static void
 mt7915_mcu_bss_ra_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
                      struct mt7915_phy *phy)
 {
+       int max_nss = hweight8(phy->mt76->chainmask);
        struct bss_info_ra *ra;
        struct tlv *tlv;
-       int max_nss = hweight8(phy->chainmask);
 
        tlv = mt7915_mcu_add_tlv(skb, BSS_INFO_RA, sizeof(*ra));
 
@@ -972,7 +979,7 @@ mt7915_mcu_muar_config(struct mt7915_phy *phy, struct ieee80211_vif *vif,
        if (enable)
                ether_addr_copy(req.addr, addr);
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_MUAR_UPDATE, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MUAR_UPDATE), &req,
                                 sizeof(req), true);
 }
 
@@ -996,6 +1003,9 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
 
        mt7915_mcu_bss_basic_tlv(skb, vif, phy, enable);
 
+       if (vif->type == NL80211_IFTYPE_MONITOR)
+               goto out;
+
        if (enable) {
                mt7915_mcu_bss_rfch_tlv(skb, vif, phy);
                mt7915_mcu_bss_bmc_tlv(skb, phy);
@@ -1009,16 +1019,17 @@ int mt7915_mcu_add_bss_info(struct mt7915_phy *phy,
                    mvif->omac_idx < REPEATER_BSSID_START)
                        mt7915_mcu_bss_ext_tlv(skb, mvif);
        }
-
+out:
        return mt76_mcu_skb_send_msg(&phy->dev->mt76, skb,
-                                    MCU_EXT_CMD_BSS_INFO_UPDATE, true);
+                                    MCU_EXT_CMD(BSS_INFO_UPDATE), true);
 }
 
 /** starec & wtbl **/
 static int
-mt7915_mcu_sta_key_tlv(struct sk_buff *skb, struct ieee80211_key_conf *key,
-                      enum set_key_cmd cmd)
+mt7915_mcu_sta_key_tlv(struct mt7915_sta *msta, struct sk_buff *skb,
+                      struct ieee80211_key_conf *key, enum set_key_cmd cmd)
 {
+       struct mt7915_sta_key_conf *bip = &msta->bip;
        struct sta_rec_sec *sec;
        struct tlv *tlv;
        u32 len = sizeof(*sec);
@@ -1038,22 +1049,23 @@ mt7915_mcu_sta_key_tlv(struct sk_buff *skb, struct ieee80211_key_conf *key,
 
                sec_key = &sec->key[0];
                sec_key->cipher_len = sizeof(*sec_key);
-               sec_key->key_id = key->keyidx;
 
                if (cipher == MT_CIPHER_BIP_CMAC_128) {
                        sec_key->cipher_id = MT_CIPHER_AES_CCMP;
+                       sec_key->key_id = bip->keyidx;
                        sec_key->key_len = 16;
-                       memcpy(sec_key->key, key->key, 16);
+                       memcpy(sec_key->key, bip->key, 16);
 
                        sec_key = &sec->key[1];
                        sec_key->cipher_id = MT_CIPHER_BIP_CMAC_128;
                        sec_key->cipher_len = sizeof(*sec_key);
                        sec_key->key_len = 16;
-                       memcpy(sec_key->key, key->key + 16, 16);
+                       memcpy(sec_key->key, key->key, 16);
 
                        sec->n_cipher = 2;
                } else {
                        sec_key->cipher_id = cipher;
+                       sec_key->key_id = key->keyidx;
                        sec_key->key_len = key->keylen;
                        memcpy(sec_key->key, key->key, key->keylen);
 
@@ -1063,6 +1075,12 @@ mt7915_mcu_sta_key_tlv(struct sk_buff *skb, struct ieee80211_key_conf *key,
                                memcpy(sec_key->key + 24, key->key + 16, 8);
                        }
 
+                       /* store key_conf for BIP batch update */
+                       if (cipher == MT_CIPHER_AES_CCMP) {
+                               memcpy(bip->key, key->key, key->keylen);
+                               bip->keyidx = key->keyidx;
+                       }
+
                        len -= sizeof(*sec_key);
                        sec->n_cipher = 1;
                }
@@ -1088,12 +1106,12 @@ int mt7915_mcu_add_key(struct mt7915_dev *dev, struct ieee80211_vif *vif,
        if (IS_ERR(skb))
                return PTR_ERR(skb);
 
-       ret = mt7915_mcu_sta_key_tlv(skb, key, cmd);
+       ret = mt7915_mcu_sta_key_tlv(msta, skb, key, cmd);
        if (ret)
                return ret;
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 static void
@@ -1107,7 +1125,7 @@ mt7915_mcu_sta_ba_tlv(struct sk_buff *skb,
        tlv = mt7915_mcu_add_tlv(skb, STA_REC_BA, sizeof(*ba));
 
        ba = (struct sta_rec_ba *)tlv;
-       ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT,
+       ba->ba_type = tx ? MT_BA_TYPE_ORIGINATOR : MT_BA_TYPE_RECIPIENT;
        ba->winsize = cpu_to_le16(params->buf_size);
        ba->ssn = cpu_to_le16(params->ssn);
        ba->ba_en = enable << params->tid;
@@ -1173,7 +1191,7 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
        mt7915_mcu_wtbl_ba_tlv(skb, params, enable, tx, sta_wtbl, wtbl_hdr);
 
        ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                   MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                   MCU_EXT_CMD(STA_REC_UPDATE), true);
        if (ret)
                return ret;
 
@@ -1185,7 +1203,7 @@ mt7915_mcu_sta_ba(struct mt7915_dev *dev,
        mt7915_mcu_sta_ba_tlv(skb, params, enable, tx);
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 int mt7915_mcu_add_tx_ba(struct mt7915_dev *dev,
@@ -1521,7 +1539,7 @@ mt7915_mcu_add_mu(struct mt7915_dev *dev, struct ieee80211_vif *vif,
        mt7915_mcu_sta_muru_tlv(skb, sta);
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 static void
@@ -1688,7 +1706,7 @@ int mt7915_mcu_sta_update_hdr_trans(struct mt7915_dev *dev,
        wtbl_hdr = mt7915_mcu_alloc_wtbl_req(dev, msta, WTBL_SET, NULL, &skb);
        mt7915_mcu_wtbl_hdr_trans_tlv(skb, vif, sta, NULL, wtbl_hdr);
 
-       return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD_WTBL_UPDATE,
+       return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_EXT_CMD(WTBL_UPDATE),
                                     true);
 }
 
@@ -1713,12 +1731,13 @@ int mt7915_mcu_add_smps(struct mt7915_dev *dev, struct ieee80211_vif *vif,
        mt7915_mcu_wtbl_smps_tlv(skb, sta, sta_wtbl, wtbl_hdr);
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 static void
 mt7915_mcu_sta_sounding_rate(struct sta_rec_bf *bf)
 {
+       bf->bf_cap = MT_EBF;
        bf->sounding_phy = MT_PHY_TYPE_OFDM;
        bf->ndp_rate = 0;                               /* mcs0 */
        bf->ndpa_rate = MT7915_CFEND_RATE_DEFAULT;      /* ofdm 24m */
@@ -1726,13 +1745,14 @@ mt7915_mcu_sta_sounding_rate(struct sta_rec_bf *bf)
 }
 
 static void
-mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct sta_rec_bf *bf)
+mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
+                      struct sta_rec_bf *bf)
 {
        struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
        u8 n = 0;
 
        bf->tx_mode = MT_PHY_TYPE_HT;
-       bf->bf_cap |= MT_IBF;
+       bf->bf_cap = MT_IBF;
 
        if (mcs->tx_params & IEEE80211_HT_MCS_TX_RX_DIFF &&
            (mcs->tx_params & IEEE80211_HT_MCS_TX_DEFINED))
@@ -1745,43 +1765,46 @@ mt7915_mcu_sta_bfer_ht(struct ieee80211_sta *sta, struct sta_rec_bf *bf)
        else if (mcs->rx_mask[1])
                n = 1;
 
+       bf->nr = hweight8(phy->mt76->chainmask) - 1;
        bf->nc = min_t(u8, bf->nr, n);
-       bf->ibf_ncol = bf->nc;
-
-       if (sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->nc)
-               bf->ibf_timeout = 0x48;
+       bf->ibf_ncol = n;
 }
 
 static void
 mt7915_mcu_sta_bfer_vht(struct ieee80211_sta *sta, struct mt7915_phy *phy,
-                       struct sta_rec_bf *bf)
+                       struct sta_rec_bf *bf, bool explicit)
 {
        struct ieee80211_sta_vht_cap *pc = &sta->vht_cap;
        struct ieee80211_sta_vht_cap *vc = &phy->mt76->sband_5g.sband.vht_cap;
-       u8 bfee_nr, bfer_nr, n, tx_ant = hweight8(phy->chainmask) - 1;
-       u16 mcs_map;
+       u16 mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
+       u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
+       u8 tx_ant = hweight8(phy->mt76->chainmask) - 1;
 
        bf->tx_mode = MT_PHY_TYPE_VHT;
-       bf->bf_cap |= MT_EBF;
-
-       mt7915_mcu_sta_sounding_rate(bf);
 
-       bfee_nr = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,
-                           pc->cap);
-       bfer_nr = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
-                           vc->cap);
-       mcs_map = le16_to_cpu(pc->vht_mcs.rx_mcs_map);
+       if (explicit) {
+               u8 bfee_nr, bfer_nr;
 
-       n = min_t(u8, bfer_nr, bfee_nr);
-       bf->nr = min_t(u8, n, tx_ant);
-       n = mt7915_mcu_get_sta_nss(mcs_map);
+               mt7915_mcu_sta_sounding_rate(bf);
+               bfee_nr = FIELD_GET(IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK,
+                                   pc->cap);
+               bfer_nr = FIELD_GET(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
+                                   vc->cap);
+               bf->nr = min_t(u8, min_t(u8, bfer_nr, bfee_nr), tx_ant);
+               bf->nc = min_t(u8, nss_mcs, bf->nr);
+               bf->ibf_ncol = bf->nc;
 
-       bf->nc = min_t(u8, n, bf->nr);
-       bf->ibf_ncol = bf->nc;
+               if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
+                       bf->nr = 1;
+       } else {
+               bf->bf_cap = MT_IBF;
+               bf->nr = tx_ant;
+               bf->nc = min_t(u8, nss_mcs, bf->nr);
+               bf->ibf_ncol = nss_mcs;
 
-       /* force nr from 4 to 2 */
-       if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
-               bf->nr = 1;
+               if (sta->bandwidth == IEEE80211_STA_RX_BW_160)
+                       bf->ibf_nrow = 1;
+       }
 }
 
 static void
@@ -1790,19 +1813,14 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
 {
        struct ieee80211_sta_he_cap *pc = &sta->he_cap;
        struct ieee80211_he_cap_elem *pe = &pc->he_cap_elem;
-       const struct ieee80211_he_cap_elem *ve;
-       const struct ieee80211_sta_he_cap *vc;
-       u8 bfee_nr, bfer_nr, nss_mcs;
-       u16 mcs_map;
-
-       vc = mt7915_get_he_phy_cap(phy, vif);
-       ve = &vc->he_cap_elem;
+       const struct ieee80211_sta_he_cap *vc = mt7915_get_he_phy_cap(phy, vif);
+       const struct ieee80211_he_cap_elem *ve = &vc->he_cap_elem;
+       u16 mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.rx_mcs_80);
+       u8 nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
+       u8 bfee_nr, bfer_nr;
 
        bf->tx_mode = MT_PHY_TYPE_HE_SU;
-       bf->bf_cap |= MT_EBF;
-
        mt7915_mcu_sta_sounding_rate(bf);
-
        bf->trigger_su = HE_PHY(CAP6_TRIG_SU_BEAMFORMER_FB,
                                pe->phy_cap_info[6]);
        bf->trigger_mu = HE_PHY(CAP6_TRIG_MU_BEAMFORMER_FB,
@@ -1811,10 +1829,6 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
                         ve->phy_cap_info[5]);
        bfee_nr = HE_PHY(CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_MASK,
                         pe->phy_cap_info[4]);
-
-       mcs_map = le16_to_cpu(pc->he_mcs_nss_supp.tx_mcs_80);
-       nss_mcs = mt7915_mcu_get_sta_nss(mcs_map);
-
        bf->nr = min_t(u8, bfer_nr, bfee_nr);
        bf->nc = min_t(u8, nss_mcs, bf->nr);
        bf->ibf_ncol = bf->nc;
@@ -1853,11 +1867,11 @@ mt7915_mcu_sta_bfer_he(struct ieee80211_sta *sta, struct ieee80211_vif *vif,
 static void
 mt7915_mcu_sta_bfer_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
                        struct ieee80211_vif *vif, struct mt7915_phy *phy,
-                       bool enable)
+                       bool enable, bool explicit)
 {
+       int tx_ant = hweight8(phy->mt76->chainmask) - 1;
        struct sta_rec_bf *bf;
        struct tlv *tlv;
-       int tx_ant = hweight8(phy->chainmask) - 1;
        const u8 matrix[4][4] = {
                {0, 0, 0, 0},
                {1, 1, 0, 0},   /* 2x1, 2x2, 2x3, 2x4 */
@@ -1875,19 +1889,29 @@ mt7915_mcu_sta_bfer_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
                return;
        }
 
+       /* he: eBF only, in accordance with spec
+        * vht: support eBF and iBF
+        * ht: iBF only, since mac80211 lacks of eBF support
+        */
+       if (sta->he_cap.has_he && explicit)
+               mt7915_mcu_sta_bfer_he(sta, vif, phy, bf);
+       else if (sta->vht_cap.vht_supported)
+               mt7915_mcu_sta_bfer_vht(sta, phy, bf, explicit);
+       else if (sta->ht_cap.ht_supported)
+               mt7915_mcu_sta_bfer_ht(sta, phy, bf);
+       else
+               return;
+
        bf->bw = sta->bandwidth;
        bf->ibf_dbw = sta->bandwidth;
        bf->ibf_nrow = tx_ant;
-       bf->ibf_timeout = 0x18;
 
-       if (sta->he_cap.has_he)
-               mt7915_mcu_sta_bfer_he(sta, vif, phy, bf);
-       else if (sta->vht_cap.vht_supported)
-               mt7915_mcu_sta_bfer_vht(sta, phy, bf);
-       else if (sta->ht_cap.ht_supported)
-               mt7915_mcu_sta_bfer_ht(sta, bf);
+       if (!explicit && sta->bandwidth <= IEEE80211_STA_RX_BW_40 && !bf->nc)
+               bf->ibf_timeout = 0x48;
+       else
+               bf->ibf_timeout = 0x18;
 
-       if (bf->bf_cap & MT_EBF && bf->nr != tx_ant)
+       if (explicit && bf->nr != tx_ant)
                bf->mem_20m = matrix[tx_ant][bf->nc];
        else
                bf->mem_20m = matrix[bf->nr][bf->nc];
@@ -1910,9 +1934,9 @@ static void
 mt7915_mcu_sta_bfee_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
                        struct mt7915_phy *phy)
 {
+       int tx_ant = hweight8(phy->mt76->chainmask) - 1;
        struct sta_rec_bfee *bfee;
        struct tlv *tlv;
-       int tx_ant = hweight8(phy->chainmask) - 1;
        u8 nr = 0;
 
        tlv = mt7915_mcu_add_tlv(skb, STA_REC_BFEE, sizeof(*bfee));
@@ -1931,20 +1955,26 @@ mt7915_mcu_sta_bfee_tlv(struct sk_buff *skb, struct ieee80211_sta *sta,
        }
 
        /* reply with identity matrix to avoid 2x2 BF negative gain */
-       if (nr == 1 && tx_ant == 2)
-               bfee->fb_identity_matrix = true;
+       bfee->fb_identity_matrix = !!(nr == 1 && tx_ant == 2);
 }
 
-static u8
-mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
-                        struct ieee80211_sta *sta)
+static int
+mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
+                   struct ieee80211_sta *sta, bool enable)
 {
-       u8 type = 0;
+       struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
+       struct mt7915_phy *phy;
+       struct sk_buff *skb;
+       int r, len;
+       bool ebfee = 0, ebf = 0;
 
        if (vif->type != NL80211_IFTYPE_STATION &&
            vif->type != NL80211_IFTYPE_AP)
                return 0;
 
+       phy = mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
+
        if (sta->he_cap.has_he) {
                struct ieee80211_he_cap_elem *pe;
                const struct ieee80211_he_cap_elem *ve;
@@ -1954,15 +1984,12 @@ mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
                vc = mt7915_get_he_phy_cap(phy, vif);
                ve = &vc->he_cap_elem;
 
-               if ((HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]) ||
-                    HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4])) &&
-                   HE_PHY(CAP4_SU_BEAMFORMEE, ve->phy_cap_info[4]))
-                       type |= MT_STA_BFEE;
-
-               if ((HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) ||
-                    HE_PHY(CAP4_MU_BEAMFORMER, ve->phy_cap_info[4])) &&
-                   HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]))
-                       type |= MT_STA_BFER;
+               ebfee = !!((HE_PHY(CAP3_SU_BEAMFORMER, pe->phy_cap_info[3]) ||
+                           HE_PHY(CAP4_MU_BEAMFORMER, pe->phy_cap_info[4])) &&
+                          HE_PHY(CAP4_SU_BEAMFORMEE, ve->phy_cap_info[4]));
+               ebf = !!((HE_PHY(CAP3_SU_BEAMFORMER, ve->phy_cap_info[3]) ||
+                         HE_PHY(CAP4_MU_BEAMFORMER, ve->phy_cap_info[4])) &&
+                        HE_PHY(CAP4_SU_BEAMFORMEE, pe->phy_cap_info[4]));
        } else if (sta->vht_cap.vht_supported) {
                struct ieee80211_sta_vht_cap *pc;
                struct ieee80211_sta_vht_cap *vc;
@@ -1975,53 +2002,30 @@ mt7915_mcu_sta_txbf_type(struct mt7915_phy *phy, struct ieee80211_vif *vif,
                ce = IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
                     IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
 
-               if ((pc->cap & cr) && (vc->cap & ce))
-                       type |= MT_STA_BFEE;
-
-               if ((vc->cap & cr) && (pc->cap & ce))
-                       type |= MT_STA_BFER;
-       } else if (sta->ht_cap.ht_supported) {
-               /* TODO: iBF */
+               ebfee = !!((pc->cap & cr) && (vc->cap & ce));
+               ebf = !!((vc->cap & cr) && (pc->cap & ce));
        }
 
-       return type;
-}
-
-static int
-mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-                   struct ieee80211_sta *sta, bool enable)
-{
-       struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
-       struct mt7915_phy *phy;
-       struct sk_buff *skb;
-       int r, len;
-       u8 type;
-
-       phy = mvif->band_idx ? mt7915_ext_phy(dev) : &dev->phy;
-
-       type = mt7915_mcu_sta_txbf_type(phy, vif, sta);
-
        /* must keep each tag independent */
 
        /* starec bf */
-       if (type & MT_STA_BFER) {
+       if (ebf || dev->ibf) {
                len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_bf);
 
                skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
                if (IS_ERR(skb))
                        return PTR_ERR(skb);
 
-               mt7915_mcu_sta_bfer_tlv(skb, sta, vif, phy, enable);
+               mt7915_mcu_sta_bfer_tlv(skb, sta, vif, phy, enable, ebf);
 
                r = mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                         MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                         MCU_EXT_CMD(STA_REC_UPDATE), true);
                if (r)
                        return r;
        }
 
        /* starec bfee */
-       if (type & MT_STA_BFEE) {
+       if (ebfee) {
                len = sizeof(struct sta_req_hdr) + sizeof(struct sta_rec_bfee);
 
                skb = mt7915_mcu_alloc_sta_req(dev, mvif, msta, len);
@@ -2031,7 +2035,7 @@ mt7915_mcu_add_txbf(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                mt7915_mcu_sta_bfee_tlv(skb, sta, phy);
 
                r = mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                         MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                         MCU_EXT_CMD(STA_REC_UPDATE), true);
                if (r)
                        return r;
        }
@@ -2199,33 +2203,7 @@ int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,
        mt7915_mcu_sta_rate_ctrl_tlv(skb, dev, vif, sta);
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
-}
-
-static int
-mt7915_mcu_add_group(struct mt7915_dev *dev, struct ieee80211_vif *vif,
-                    struct ieee80211_sta *sta)
-{
-#define MT_STA_BSS_GROUP               1
-       struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-       struct mt7915_sta *msta = (struct mt7915_sta *)sta->drv_priv;
-       struct {
-               __le32 action;
-               u8 wlan_idx_lo;
-               u8 status;
-               u8 wlan_idx_hi;
-               u8 rsv0[5];
-               __le32 val;
-               u8 rsv1[8];
-       } __packed req = {
-               .action = cpu_to_le32(MT_STA_BSS_GROUP),
-               .wlan_idx_lo = to_wcid_lo(msta->wcid.idx),
-               .wlan_idx_hi = to_wcid_hi(msta->wcid.idx),
-               .val = cpu_to_le32(mvif->idx % 16),
-       };
-
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_DRR_CTRL, &req,
-                                sizeof(req), true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
@@ -2237,10 +2215,6 @@ int mt7915_mcu_add_sta_adv(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                return 0;
 
        /* must keep the order */
-       ret = mt7915_mcu_add_group(dev, vif, sta);
-       if (ret)
-               return ret;
-
        ret = mt7915_mcu_add_txbf(dev, vif, sta, enable);
        if (ret)
                return ret;
@@ -2287,7 +2261,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
        }
 
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
@@ -2333,7 +2307,7 @@ int mt7915_mcu_set_fixed_rate(struct mt7915_dev *dev,
 
 out:
        return mt76_mcu_skb_send_msg(&dev->mt76, skb,
-                                    MCU_EXT_CMD_STA_REC_UPDATE, true);
+                                    MCU_EXT_CMD(STA_REC_UPDATE), true);
 }
 
 int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
@@ -2375,7 +2349,7 @@ int mt7915_mcu_add_dev_info(struct mt7915_phy *phy,
                return mt7915_mcu_muar_config(phy, vif, false, enable);
 
        memcpy(data.tlv.omac_addr, vif->addr, ETH_ALEN);
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_DEV_INFO_UPDATE,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(DEV_INFO_UPDATE),
                                 &data, sizeof(data), true);
 }
 
@@ -2468,7 +2442,7 @@ int mt7915_mcu_add_beacon(struct ieee80211_hw *hw,
        dev_kfree_skb(skb);
 
        return mt76_mcu_skb_send_msg(&phy->dev->mt76, rskb,
-                                    MCU_EXT_CMD_BSS_INFO_UPDATE, true);
+                                    MCU_EXT_CMD(BSS_INFO_UPDATE), true);
 }
 
 static int mt7915_mcu_start_firmware(struct mt7915_dev *dev, u32 addr,
@@ -2482,7 +2456,7 @@ static int mt7915_mcu_start_firmware(struct mt7915_dev *dev, u32 addr,
                .addr = cpu_to_le32(addr),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_FW_START_REQ, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_CMD(FW_START_REQ), &req,
                                 sizeof(req), true);
 }
 
@@ -2495,7 +2469,7 @@ static int mt7915_mcu_restart(struct mt76_dev *dev)
                .power_mode = 1,
        };
 
-       return mt76_mcu_send_msg(dev, -MCU_CMD_NIC_POWER_CTRL, &req,
+       return mt76_mcu_send_msg(dev, MCU_CMD(NIC_POWER_CTRL), &req,
                                 sizeof(req), false);
 }
 
@@ -2507,7 +2481,7 @@ static int mt7915_mcu_patch_sem_ctrl(struct mt7915_dev *dev, bool get)
                .op = cpu_to_le32(get ? PATCH_SEM_GET : PATCH_SEM_RELEASE),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_PATCH_SEM_CONTROL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_CMD(PATCH_SEM_CONTROL), &req,
                                 sizeof(req), true);
 }
 
@@ -2520,7 +2494,7 @@ static int mt7915_mcu_start_patch(struct mt7915_dev *dev)
                .check_crc = 0,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, -MCU_CMD_PATCH_FINISH_REQ, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_CMD(PATCH_FINISH_REQ), &req,
                                 sizeof(req), true);
 }
 
@@ -2553,9 +2527,9 @@ static int mt7915_mcu_init_download(struct mt7915_dev *dev, u32 addr,
        int attr;
 
        if (req.addr == cpu_to_le32(MCU_PATCH_ADDRESS))
-               attr = -MCU_CMD_PATCH_START_REQ;
+               attr = MCU_CMD(PATCH_START_REQ);
        else
-               attr = -MCU_CMD_TARGET_ADDRESS_LEN_REQ;
+               attr = MCU_CMD(TARGET_ADDRESS_LEN_REQ);
 
        return mt76_mcu_send_msg(&dev->mt76, attr, &req, sizeof(req), true);
 }
@@ -2616,7 +2590,7 @@ static int mt7915_load_patch(struct mt7915_dev *dev)
                        goto out;
                }
 
-               ret = mt76_mcu_send_firmware(&dev->mt76, -MCU_CMD_FW_SCATTER,
+               ret = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
                                             dl, len);
                if (ret) {
                        dev_err(dev->mt76.dev, "Failed to send patch\n");
@@ -2685,7 +2659,7 @@ mt7915_mcu_send_ram_firmware(struct mt7915_dev *dev,
                        return err;
                }
 
-               err = mt76_mcu_send_firmware(&dev->mt76, -MCU_CMD_FW_SCATTER,
+               err = mt76_mcu_send_firmware(&dev->mt76, MCU_CMD(FW_SCATTER),
                                             data + offset, len);
                if (err) {
                        dev_err(dev->mt76.dev, "Failed to send firmware.\n");
@@ -2815,7 +2789,7 @@ int mt7915_mcu_fw_log_2_host(struct mt7915_dev *dev, u8 ctrl)
                .ctrl_val = ctrl
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_FW_LOG_2_HOST, &data,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(FW_LOG_2_HOST), &data,
                                 sizeof(data), true);
 }
 
@@ -2833,7 +2807,7 @@ int mt7915_mcu_fw_dbg_ctrl(struct mt7915_dev *dev, u32 module, u8 level)
                .level = level,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_FW_DBG_CTRL, &data,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(FW_DBG_CTRL), &data,
                                 sizeof(data), false);
 }
 
@@ -2846,7 +2820,7 @@ static int mt7915_mcu_set_mwds(struct mt7915_dev *dev, bool enabled)
                .enable = enabled
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_MWDS_SUPPORT, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_WA_EXT_CMD(MWDS_SUPPORT), &req,
                                 sizeof(req), false);
 }
 
@@ -2873,6 +2847,7 @@ int mt7915_mcu_init(struct mt7915_dev *dev)
        set_bit(MT76_STATE_MCU_RUNNING, &dev->mphy.state);
        mt7915_mcu_fw_log_2_host(dev, 0);
        mt7915_mcu_set_mwds(dev, 1);
+       mt7915_mcu_wa_cmd(dev, MCU_WA_PARAM_CMD(SET), MCU_WA_PARAM_RED, 0, 0);
 
        return 0;
 }
@@ -2919,12 +2894,12 @@ int mt7915_mcu_set_mac(struct mt7915_dev *dev, int band,
        };
        int ret;
 
-       ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RX_HDR_TRANS,
+       ret = mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RX_HDR_TRANS),
                                &req_trans, sizeof(req_trans), false);
        if (ret)
                return ret;
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_MAC_INIT_CTRL,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(MAC_INIT_CTRL),
                                 &req_mac, sizeof(req_mac), true);
 }
 
@@ -2940,7 +2915,7 @@ int mt7915_mcu_set_scs(struct mt7915_dev *dev, u8 band, bool enable)
                .enable = enable + 1,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SCS_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SCS_CTRL), &req,
                                 sizeof(req), false);
 }
 
@@ -2960,34 +2935,25 @@ int mt7915_mcu_set_rts_thresh(struct mt7915_phy *phy, u32 val)
                .pkt_thresh = cpu_to_le32(0x2),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_PROTECT_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(PROTECT_CTRL), &req,
                                 sizeof(req), true);
 }
 
+int mt7915_mcu_update_edca(struct mt7915_dev *dev, void *param)
+{
+       struct mt7915_mcu_tx *req = (struct mt7915_mcu_tx *)param;
+       u8 num = req->total;
+       size_t len = sizeof(*req) -
+                    (IEEE80211_NUM_ACS - num) * sizeof(struct edca);
+
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCA_UPDATE), req,
+                                len, true);
+}
+
 int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif)
 {
-#define WMM_AIFS_SET           BIT(0)
-#define WMM_CW_MIN_SET         BIT(1)
-#define WMM_CW_MAX_SET         BIT(2)
-#define WMM_TXOP_SET           BIT(3)
-#define WMM_PARAM_SET          GENMASK(3, 0)
 #define TX_CMD_MODE            1
-       struct edca {
-               u8 queue;
-               u8 set;
-               u8 aifs;
-               u8 cw_min;
-               __le16 cw_max;
-               __le16 txop;
-       };
-       struct mt7915_mcu_tx {
-               u8 total;
-               u8 action;
-               u8 valid;
-               u8 mode;
-
-               struct edca edca[IEEE80211_NUM_ACS];
-       } __packed req = {
+       struct mt7915_mcu_tx req = {
                .valid = true,
                .mode = TX_CMD_MODE,
                .total = IEEE80211_NUM_ACS,
@@ -3014,8 +2980,8 @@ int mt7915_mcu_set_tx(struct mt7915_dev *dev, struct ieee80211_vif *vif)
                else
                        e->cw_max = cpu_to_le16(10);
        }
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EDCA_UPDATE, &req,
-                                sizeof(req), true);
+
+       return mt7915_mcu_update_edca(dev, &req);
 }
 
 int mt7915_mcu_set_pm(struct mt7915_dev *dev, int band, int enter)
@@ -3045,7 +3011,7 @@ int mt7915_mcu_set_pm(struct mt7915_dev *dev, int band, int enter)
                .band_idx = band,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_PM_STATE_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(PM_STATE_CTRL), &req,
                                 sizeof(req), true);
 }
 
@@ -3066,7 +3032,7 @@ int mt7915_mcu_rdd_cmd(struct mt7915_dev *dev,
                .val = val,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_CTRL), &req,
                                 sizeof(req), true);
 }
 
@@ -3081,7 +3047,7 @@ int mt7915_mcu_set_fcc5_lpn(struct mt7915_dev *dev, int val)
                .min_lpn = cpu_to_le16(val),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
                                 sizeof(req), true);
 }
 
@@ -3112,7 +3078,7 @@ int mt7915_mcu_set_pulse_th(struct mt7915_dev *dev,
 #undef __req_field
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
                                 sizeof(req), true);
 }
 
@@ -3129,8 +3095,8 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
                u8 max_crpn;
                u8 min_crpr;
                u8 min_pw;
-               u32 min_pri;
-               u32 max_pri;
+               __le32 min_pri;
+               __le32 max_pri;
                u8 max_pw;
                u8 min_crbn;
                u8 max_crbn;
@@ -3138,7 +3104,7 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
                u8 max_stgpn;
                u8 min_stgpr;
                u8 rsv[2];
-               u32 min_stgpr_diff;
+               __le32 min_stgpr_diff;
        } __packed req = {
                .tag = cpu_to_le32(0x2),
                .radar_type = cpu_to_le16(index),
@@ -3164,7 +3130,7 @@ int mt7915_mcu_set_radar_th(struct mt7915_dev *dev, int index,
 #undef __req_field_u32
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_RDD_TH, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_RDD_TH), &req,
                                 sizeof(req), true);
 }
 
@@ -3173,6 +3139,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
        struct mt7915_dev *dev = phy->dev;
        struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
        int freq1 = chandef->center_freq1;
+       bool ext_phy = phy != &dev->phy;
        struct {
                u8 control_ch;
                u8 center_ch;
@@ -3196,16 +3163,22 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
                .bw = mt7915_mcu_chan_bw(chandef),
                .tx_streams_num = hweight8(phy->mt76->antenna_mask),
                .rx_streams = phy->mt76->antenna_mask,
-               .band_idx = phy != &dev->phy,
+               .band_idx = ext_phy,
                .channel_band = chandef->chan->band,
        };
 
 #ifdef CONFIG_NL80211_TESTMODE
-       if (dev->mt76.test.tx_antenna_mask &&
-           (dev->mt76.test.state == MT76_TM_STATE_TX_FRAMES ||
-            dev->mt76.test.state == MT76_TM_STATE_RX_FRAMES)) {
-               req.tx_streams_num = fls(dev->mt76.test.tx_antenna_mask);
-               req.rx_streams = dev->mt76.test.tx_antenna_mask;
+       if (phy->mt76->test.tx_antenna_mask &&
+           (phy->mt76->test.state == MT76_TM_STATE_TX_FRAMES ||
+            phy->mt76->test.state == MT76_TM_STATE_RX_FRAMES ||
+            phy->mt76->test.state == MT76_TM_STATE_TX_CONT)) {
+               req.tx_streams_num = fls(phy->mt76->test.tx_antenna_mask);
+               req.rx_streams = phy->mt76->test.tx_antenna_mask;
+
+               if (ext_phy) {
+                       req.tx_streams_num = 2;
+                       req.rx_streams >>= 2;
+               }
        }
 #endif
 
@@ -3217,7 +3190,7 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
        else
                req.switch_reason = CH_SWITCH_NORMAL;
 
-       if (cmd == MCU_EXT_CMD_CHANNEL_SWITCH)
+       if (cmd == MCU_EXT_CMD(CHANNEL_SWITCH))
                req.rx_streams = hweight8(req.rx_streams);
 
        if (chandef->width == NL80211_CHAN_WIDTH_80P80) {
@@ -3229,18 +3202,58 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd)
        return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true);
 }
 
+static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev)
+{
+#define TOTAL_PAGE_MASK                GENMASK(7, 5)
+#define PAGE_IDX_MASK          GENMASK(4, 2)
+#define PER_PAGE_SIZE          0x400
+       struct mt7915_mcu_eeprom req = { .buffer_mode = EE_MODE_BUFFER };
+       u8 total = MT7915_EEPROM_SIZE / PER_PAGE_SIZE;
+       u8 *eep = (u8 *)dev->mt76.eeprom.data;
+       int eep_len;
+       int i;
+
+       for (i = 0; i <= total; i++, eep += eep_len) {
+               struct sk_buff *skb;
+               int ret;
+
+               if (i == total)
+                       eep_len = MT7915_EEPROM_SIZE % PER_PAGE_SIZE;
+               else
+                       eep_len = PER_PAGE_SIZE;
+
+               skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+                                        sizeof(req) + eep_len);
+               if (!skb)
+                       return -ENOMEM;
+
+               req.format = FIELD_PREP(TOTAL_PAGE_MASK, total) |
+                            FIELD_PREP(PAGE_IDX_MASK, i) | EE_FORMAT_WHOLE;
+               req.len = cpu_to_le16(eep_len);
+
+               skb_put_data(skb, &req, sizeof(req));
+               skb_put_data(skb, eep, eep_len);
+
+               ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+                                           MCU_EXT_CMD(EFUSE_BUFFER_MODE), true);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 int mt7915_mcu_set_eeprom(struct mt7915_dev *dev)
 {
-       struct req_hdr {
-               u8 buffer_mode;
-               u8 format;
-               __le16 len;
-       } __packed req = {
+       struct mt7915_mcu_eeprom req = {
                .buffer_mode = EE_MODE_EFUSE,
                .format = EE_FORMAT_WHOLE,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE,
+       if (dev->flash_mode)
+               return mt7915_mcu_set_eeprom_flash(dev);
+
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EFUSE_BUFFER_MODE),
                                 &req, sizeof(req), true);
 }
 
@@ -3254,7 +3267,7 @@ int mt7915_mcu_get_eeprom(struct mt7915_dev *dev, u32 offset)
        int ret;
        u8 *buf;
 
-       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_ACCESS, &req,
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_QUERY(EFUSE_ACCESS), &req,
                                sizeof(req), true, &skb);
        if (ret)
                return ret;
@@ -3279,7 +3292,7 @@ int mt7915_mcu_get_temperature(struct mt7915_dev *dev, int index)
                .action = index,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_THERMAL_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(THERMAL_CTRL), &req,
                                 sizeof(req), true);
 }
 
@@ -3297,7 +3310,7 @@ int mt7915_mcu_get_tx_rate(struct mt7915_dev *dev, u32 cmd, u16 wlan_idx)
                .dump_group = cpu_to_le16(1),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_RATE_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(RATE_CTRL), &req,
                                 sizeof(req), false);
 }
 
@@ -3326,7 +3339,7 @@ int mt7915_mcu_set_sku(struct mt7915_phy *phy)
                req.val[i] = hw->conf.power_level * 2 + delta[i];
 
        return mt76_mcu_send_msg(&dev->mt76,
-                                MCU_EXT_CMD_TX_POWER_FEATURE_CTRL, &req,
+                                MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
                                 sizeof(req), true);
 }
 
@@ -3348,7 +3361,7 @@ int mt7915_mcu_set_test_param(struct mt7915_dev *dev, u8 param, bool test_mode,
                .enable = en,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_ATE_CTRL, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(ATE_CTRL), &req,
                                 sizeof(req), false);
 }
 
@@ -3367,7 +3380,7 @@ int mt7915_mcu_set_sku_en(struct mt7915_phy *phy, bool enable)
        };
 
        return mt76_mcu_send_msg(&dev->mt76,
-                                MCU_EXT_CMD_TX_POWER_FEATURE_CTRL, &req,
+                                MCU_EXT_CMD(TX_POWER_FEATURE_CTRL), &req,
                                 sizeof(req), true);
 }
 
@@ -3384,10 +3397,29 @@ int mt7915_mcu_set_ser(struct mt7915_dev *dev, u8 action, u8 set, u8 band)
                .band = band,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_SER_TRIGGER,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_SER_TRIGGER),
                                 &req, sizeof(req), false);
 }
 
+int mt7915_mcu_set_txbf_module(struct mt7915_dev *dev)
+{
+#define MT_BF_MODULE_UPDATE               25
+       struct {
+               u8 action;
+               u8 bf_num;
+               u8 bf_bitmap;
+               u8 bf_sel[8];
+               u8 rsv[8];
+       } __packed req = {
+               .action = MT_BF_MODULE_UPDATE,
+               .bf_num = 2,
+               .bf_bitmap = GENMASK(1, 0),
+       };
+
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
+                                sizeof(req), true);
+}
+
 int mt7915_mcu_set_txbf_type(struct mt7915_dev *dev)
 {
 #define MT_BF_TYPE_UPDATE              20
@@ -3399,10 +3431,10 @@ int mt7915_mcu_set_txbf_type(struct mt7915_dev *dev)
        } __packed req = {
                .action = MT_BF_TYPE_UPDATE,
                .ebf = true,
-               .ibf = false,
+               .ibf = dev->ibf,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXBF_ACTION, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
                                 sizeof(req), true);
 }
 
@@ -3421,7 +3453,7 @@ int mt7915_mcu_set_txbf_sounding(struct mt7915_dev *dev)
                .snd_mode = MT_BF_PROCESSING,
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_TXBF_ACTION, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(TXBF_ACTION), &req,
                                 sizeof(req), true);
 }
 
@@ -3446,7 +3478,7 @@ int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                .val = cpu_to_le32(enable),
        };
 
-       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_SET_SPR, &req,
+       return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(SET_SPR), &req,
                                 sizeof(req), true);
 }
 
@@ -3473,7 +3505,7 @@ int mt7915_mcu_get_rx_rate(struct mt7915_phy *phy, struct ieee80211_vif *vif,
        int ret;
        int i;
 
-       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD_PHY_STAT_INFO,
+       ret = mt76_mcu_send_and_get_msg(&dev->mt76, MCU_EXT_CMD(PHY_STAT_INFO),
                                        &req, sizeof(req), true, &skb);
        if (ret)
                return ret;