Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: ISC
0002 /* Copyright (C) 2020 MediaTek Inc. */
0003 
0004 #include "mt76_connac.h"
0005 #include "mt76_connac2_mac.h"
0006 #include "dma.h"
0007 
0008 #define HE_BITS(f)      cpu_to_le16(IEEE80211_RADIOTAP_HE_##f)
0009 #define HE_PREP(f, m, v)    le16_encode_bits(le32_get_bits(v, MT_CRXV_HE_##m),\
0010                          IEEE80211_RADIOTAP_HE_##f)
0011 
0012 int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm)
0013 {
0014     struct mt76_dev *dev = phy->dev;
0015 
0016     if (mt76_is_usb(dev))
0017         return 0;
0018 
0019     cancel_delayed_work_sync(&pm->ps_work);
0020     if (!test_bit(MT76_STATE_PM, &phy->state))
0021         return 0;
0022 
0023     if (pm->suspended)
0024         return 0;
0025 
0026     queue_work(dev->wq, &pm->wake_work);
0027     if (!wait_event_timeout(pm->wait,
0028                 !test_bit(MT76_STATE_PM, &phy->state),
0029                 3 * HZ)) {
0030         ieee80211_wake_queues(phy->hw);
0031         return -ETIMEDOUT;
0032     }
0033 
0034     return 0;
0035 }
0036 EXPORT_SYMBOL_GPL(mt76_connac_pm_wake);
0037 
0038 void mt76_connac_power_save_sched(struct mt76_phy *phy,
0039                   struct mt76_connac_pm *pm)
0040 {
0041     struct mt76_dev *dev = phy->dev;
0042 
0043     if (mt76_is_usb(dev))
0044         return;
0045 
0046     if (!pm->enable)
0047         return;
0048 
0049     if (pm->suspended)
0050         return;
0051 
0052     pm->last_activity = jiffies;
0053 
0054     if (!test_bit(MT76_STATE_PM, &phy->state)) {
0055         cancel_delayed_work(&phy->mac_work);
0056         queue_delayed_work(dev->wq, &pm->ps_work, pm->idle_timeout);
0057     }
0058 }
0059 EXPORT_SYMBOL_GPL(mt76_connac_power_save_sched);
0060 
0061 void mt76_connac_free_pending_tx_skbs(struct mt76_connac_pm *pm,
0062                       struct mt76_wcid *wcid)
0063 {
0064     int i;
0065 
0066     spin_lock_bh(&pm->txq_lock);
0067     for (i = 0; i < IEEE80211_NUM_ACS; i++) {
0068         if (wcid && pm->tx_q[i].wcid != wcid)
0069             continue;
0070 
0071         dev_kfree_skb(pm->tx_q[i].skb);
0072         pm->tx_q[i].skb = NULL;
0073     }
0074     spin_unlock_bh(&pm->txq_lock);
0075 }
0076 EXPORT_SYMBOL_GPL(mt76_connac_free_pending_tx_skbs);
0077 
0078 void mt76_connac_pm_queue_skb(struct ieee80211_hw *hw,
0079                   struct mt76_connac_pm *pm,
0080                   struct mt76_wcid *wcid,
0081                   struct sk_buff *skb)
0082 {
0083     int qid = skb_get_queue_mapping(skb);
0084     struct mt76_phy *phy = hw->priv;
0085 
0086     spin_lock_bh(&pm->txq_lock);
0087     if (!pm->tx_q[qid].skb) {
0088         ieee80211_stop_queues(hw);
0089         pm->tx_q[qid].wcid = wcid;
0090         pm->tx_q[qid].skb = skb;
0091         queue_work(phy->dev->wq, &pm->wake_work);
0092     } else {
0093         dev_kfree_skb(skb);
0094     }
0095     spin_unlock_bh(&pm->txq_lock);
0096 }
0097 EXPORT_SYMBOL_GPL(mt76_connac_pm_queue_skb);
0098 
0099 void mt76_connac_pm_dequeue_skbs(struct mt76_phy *phy,
0100                  struct mt76_connac_pm *pm)
0101 {
0102     int i;
0103 
0104     spin_lock_bh(&pm->txq_lock);
0105     for (i = 0; i < IEEE80211_NUM_ACS; i++) {
0106         struct mt76_wcid *wcid = pm->tx_q[i].wcid;
0107         struct ieee80211_sta *sta = NULL;
0108 
0109         if (!pm->tx_q[i].skb)
0110             continue;
0111 
0112         if (wcid && wcid->sta)
0113             sta = container_of((void *)wcid, struct ieee80211_sta,
0114                        drv_priv);
0115 
0116         mt76_tx(phy, sta, wcid, pm->tx_q[i].skb);
0117         pm->tx_q[i].skb = NULL;
0118     }
0119     spin_unlock_bh(&pm->txq_lock);
0120 
0121     mt76_worker_schedule(&phy->dev->tx_worker);
0122 }
0123 EXPORT_SYMBOL_GPL(mt76_connac_pm_dequeue_skbs);
0124 
0125 void mt76_connac_tx_complete_skb(struct mt76_dev *mdev,
0126                  struct mt76_queue_entry *e)
0127 {
0128     if (!e->txwi) {
0129         dev_kfree_skb_any(e->skb);
0130         return;
0131     }
0132 
0133     /* error path */
0134     if (e->skb == DMA_DUMMY_DATA) {
0135         struct mt76_connac_txp_common *txp;
0136         struct mt76_txwi_cache *t;
0137         u16 token;
0138 
0139         txp = mt76_connac_txwi_to_txp(mdev, e->txwi);
0140         if (is_mt76_fw_txp(mdev))
0141             token = le16_to_cpu(txp->fw.token);
0142         else
0143             token = le16_to_cpu(txp->hw.msdu_id[0]) &
0144                 ~MT_MSDU_ID_VALID;
0145 
0146         t = mt76_token_put(mdev, token);
0147         e->skb = t ? t->skb : NULL;
0148     }
0149 
0150     if (e->skb)
0151         mt76_tx_complete_skb(mdev, e->wcid, e->skb);
0152 }
0153 EXPORT_SYMBOL_GPL(mt76_connac_tx_complete_skb);
0154 
0155 void mt76_connac_write_hw_txp(struct mt76_dev *dev,
0156                   struct mt76_tx_info *tx_info,
0157                   void *txp_ptr, u32 id)
0158 {
0159     struct mt76_connac_hw_txp *txp = txp_ptr;
0160     struct mt76_connac_txp_ptr *ptr = &txp->ptr[0];
0161     int i, nbuf = tx_info->nbuf - 1;
0162     u32 last_mask;
0163 
0164     tx_info->buf[0].len = MT_TXD_SIZE + sizeof(*txp);
0165     tx_info->nbuf = 1;
0166 
0167     txp->msdu_id[0] = cpu_to_le16(id | MT_MSDU_ID_VALID);
0168 
0169     if (is_mt7663(dev) || is_mt7921(dev))
0170         last_mask = MT_TXD_LEN_LAST;
0171     else
0172         last_mask = MT_TXD_LEN_AMSDU_LAST |
0173                 MT_TXD_LEN_MSDU_LAST;
0174 
0175     for (i = 0; i < nbuf; i++) {
0176         u16 len = tx_info->buf[i + 1].len & MT_TXD_LEN_MASK;
0177         u32 addr = tx_info->buf[i + 1].addr;
0178 
0179         if (i == nbuf - 1)
0180             len |= last_mask;
0181 
0182         if (i & 1) {
0183             ptr->buf1 = cpu_to_le32(addr);
0184             ptr->len1 = cpu_to_le16(len);
0185             ptr++;
0186         } else {
0187             ptr->buf0 = cpu_to_le32(addr);
0188             ptr->len0 = cpu_to_le16(len);
0189         }
0190     }
0191 }
0192 EXPORT_SYMBOL_GPL(mt76_connac_write_hw_txp);
0193 
0194 static void
0195 mt76_connac_txp_skb_unmap_fw(struct mt76_dev *mdev,
0196                  struct mt76_connac_fw_txp *txp)
0197 {
0198     struct device *dev = is_connac_v1(mdev) ? mdev->dev : mdev->dma_dev;
0199     int i;
0200 
0201     for (i = 0; i < txp->nbuf; i++)
0202         dma_unmap_single(dev, le32_to_cpu(txp->buf[i]),
0203                  le16_to_cpu(txp->len[i]), DMA_TO_DEVICE);
0204 }
0205 
0206 static void
0207 mt76_connac_txp_skb_unmap_hw(struct mt76_dev *dev,
0208                  struct mt76_connac_hw_txp *txp)
0209 {
0210     u32 last_mask;
0211     int i;
0212 
0213     if (is_mt7663(dev) || is_mt7921(dev))
0214         last_mask = MT_TXD_LEN_LAST;
0215     else
0216         last_mask = MT_TXD_LEN_MSDU_LAST;
0217 
0218     for (i = 0; i < ARRAY_SIZE(txp->ptr); i++) {
0219         struct mt76_connac_txp_ptr *ptr = &txp->ptr[i];
0220         bool last;
0221         u16 len;
0222 
0223         len = le16_to_cpu(ptr->len0);
0224         last = len & last_mask;
0225         len &= MT_TXD_LEN_MASK;
0226         dma_unmap_single(dev->dev, le32_to_cpu(ptr->buf0), len,
0227                  DMA_TO_DEVICE);
0228         if (last)
0229             break;
0230 
0231         len = le16_to_cpu(ptr->len1);
0232         last = len & last_mask;
0233         len &= MT_TXD_LEN_MASK;
0234         dma_unmap_single(dev->dev, le32_to_cpu(ptr->buf1), len,
0235                  DMA_TO_DEVICE);
0236         if (last)
0237             break;
0238     }
0239 }
0240 
0241 void mt76_connac_txp_skb_unmap(struct mt76_dev *dev,
0242                    struct mt76_txwi_cache *t)
0243 {
0244     struct mt76_connac_txp_common *txp;
0245 
0246     txp = mt76_connac_txwi_to_txp(dev, t);
0247     if (is_mt76_fw_txp(dev))
0248         mt76_connac_txp_skb_unmap_fw(dev, &txp->fw);
0249     else
0250         mt76_connac_txp_skb_unmap_hw(dev, &txp->hw);
0251 }
0252 EXPORT_SYMBOL_GPL(mt76_connac_txp_skb_unmap);
0253 
0254 int mt76_connac_init_tx_queues(struct mt76_phy *phy, int idx, int n_desc,
0255                    int ring_base, u32 flags)
0256 {
0257     int i, err;
0258 
0259     err = mt76_init_tx_queue(phy, 0, idx, n_desc, ring_base, flags);
0260     if (err < 0)
0261         return err;
0262 
0263     for (i = 1; i <= MT_TXQ_PSD; i++)
0264         phy->q_tx[i] = phy->q_tx[0];
0265 
0266     return 0;
0267 }
0268 EXPORT_SYMBOL_GPL(mt76_connac_init_tx_queues);
0269 
0270 static u16
0271 mt76_connac2_mac_tx_rate_val(struct mt76_phy *mphy, struct ieee80211_vif *vif,
0272                  bool beacon, bool mcast)
0273 {
0274     u8 mode = 0, band = mphy->chandef.chan->band;
0275     int rateidx = 0, mcast_rate;
0276 
0277     if (!vif)
0278         goto legacy;
0279 
0280     if (is_mt7921(mphy->dev)) {
0281         rateidx = ffs(vif->bss_conf.basic_rates) - 1;
0282         goto legacy;
0283     }
0284 
0285     if (beacon) {
0286         struct cfg80211_bitrate_mask *mask;
0287 
0288         mask = &vif->bss_conf.beacon_tx_rate;
0289         if (hweight16(mask->control[band].he_mcs[0]) == 1) {
0290             rateidx = ffs(mask->control[band].he_mcs[0]) - 1;
0291             mode = MT_PHY_TYPE_HE_SU;
0292             goto out;
0293         } else if (hweight16(mask->control[band].vht_mcs[0]) == 1) {
0294             rateidx = ffs(mask->control[band].vht_mcs[0]) - 1;
0295             mode = MT_PHY_TYPE_VHT;
0296             goto out;
0297         } else if (hweight8(mask->control[band].ht_mcs[0]) == 1) {
0298             rateidx = ffs(mask->control[band].ht_mcs[0]) - 1;
0299             mode = MT_PHY_TYPE_HT;
0300             goto out;
0301         } else if (hweight32(mask->control[band].legacy) == 1) {
0302             rateidx = ffs(mask->control[band].legacy) - 1;
0303             goto legacy;
0304         }
0305     }
0306 
0307     mcast_rate = vif->bss_conf.mcast_rate[band];
0308     if (mcast && mcast_rate > 0)
0309         rateidx = mcast_rate - 1;
0310     else
0311         rateidx = ffs(vif->bss_conf.basic_rates) - 1;
0312 
0313 legacy:
0314     rateidx = mt76_calculate_default_rate(mphy, rateidx);
0315     mode = rateidx >> 8;
0316     rateidx &= GENMASK(7, 0);
0317 
0318 out:
0319     return FIELD_PREP(MT_TX_RATE_IDX, rateidx) |
0320            FIELD_PREP(MT_TX_RATE_MODE, mode);
0321 }
0322 
0323 static void
0324 mt76_connac2_mac_write_txwi_8023(__le32 *txwi, struct sk_buff *skb,
0325                  struct mt76_wcid *wcid)
0326 {
0327     u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
0328     u8 fc_type, fc_stype;
0329     u16 ethertype;
0330     bool wmm = false;
0331     u32 val;
0332 
0333     if (wcid->sta) {
0334         struct ieee80211_sta *sta;
0335 
0336         sta = container_of((void *)wcid, struct ieee80211_sta, drv_priv);
0337         wmm = sta->wme;
0338     }
0339 
0340     val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_3) |
0341           FIELD_PREP(MT_TXD1_TID, tid);
0342 
0343     ethertype = get_unaligned_be16(&skb->data[12]);
0344     if (ethertype >= ETH_P_802_3_MIN)
0345         val |= MT_TXD1_ETH_802_3;
0346 
0347     txwi[1] |= cpu_to_le32(val);
0348 
0349     fc_type = IEEE80211_FTYPE_DATA >> 2;
0350     fc_stype = wmm ? IEEE80211_STYPE_QOS_DATA >> 4 : 0;
0351 
0352     val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
0353           FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype);
0354 
0355     txwi[2] |= cpu_to_le32(val);
0356 
0357     val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
0358           FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
0359 
0360     txwi[7] |= cpu_to_le32(val);
0361 }
0362 
0363 static void
0364 mt76_connac2_mac_write_txwi_80211(struct mt76_dev *dev, __le32 *txwi,
0365                   struct sk_buff *skb,
0366                   struct ieee80211_key_conf *key)
0367 {
0368     struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
0369     struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
0370     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0371     bool multicast = is_multicast_ether_addr(hdr->addr1);
0372     u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
0373     __le16 fc = hdr->frame_control;
0374     u8 fc_type, fc_stype;
0375     u32 val;
0376 
0377     if (ieee80211_is_action(fc) &&
0378         mgmt->u.action.category == WLAN_CATEGORY_BACK &&
0379         mgmt->u.action.u.addba_req.action_code == WLAN_ACTION_ADDBA_REQ) {
0380         u16 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
0381 
0382         txwi[5] |= cpu_to_le32(MT_TXD5_ADD_BA);
0383         tid = (capab >> 2) & IEEE80211_QOS_CTL_TID_MASK;
0384     } else if (ieee80211_is_back_req(hdr->frame_control)) {
0385         struct ieee80211_bar *bar = (struct ieee80211_bar *)hdr;
0386         u16 control = le16_to_cpu(bar->control);
0387 
0388         tid = FIELD_GET(IEEE80211_BAR_CTRL_TID_INFO_MASK, control);
0389     }
0390 
0391     val = FIELD_PREP(MT_TXD1_HDR_FORMAT, MT_HDR_FORMAT_802_11) |
0392           FIELD_PREP(MT_TXD1_HDR_INFO,
0393              ieee80211_get_hdrlen_from_skb(skb) / 2) |
0394           FIELD_PREP(MT_TXD1_TID, tid);
0395 
0396     txwi[1] |= cpu_to_le32(val);
0397 
0398     fc_type = (le16_to_cpu(fc) & IEEE80211_FCTL_FTYPE) >> 2;
0399     fc_stype = (le16_to_cpu(fc) & IEEE80211_FCTL_STYPE) >> 4;
0400 
0401     val = FIELD_PREP(MT_TXD2_FRAME_TYPE, fc_type) |
0402           FIELD_PREP(MT_TXD2_SUB_TYPE, fc_stype) |
0403           FIELD_PREP(MT_TXD2_MULTICAST, multicast);
0404 
0405     if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) &&
0406         key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
0407         val |= MT_TXD2_BIP;
0408         txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
0409     }
0410 
0411     if (!ieee80211_is_data(fc) || multicast ||
0412         info->flags & IEEE80211_TX_CTL_USE_MINRATE)
0413         val |= MT_TXD2_FIX_RATE;
0414 
0415     txwi[2] |= cpu_to_le32(val);
0416 
0417     if (ieee80211_is_beacon(fc)) {
0418         txwi[3] &= ~cpu_to_le32(MT_TXD3_SW_POWER_MGMT);
0419         txwi[3] |= cpu_to_le32(MT_TXD3_REM_TX_COUNT);
0420         if (!is_mt7921(dev))
0421             txwi[7] |= cpu_to_le32(FIELD_PREP(MT_TXD7_SPE_IDX,
0422                               0x18));
0423     }
0424 
0425     if (info->flags & IEEE80211_TX_CTL_INJECTED) {
0426         u16 seqno = le16_to_cpu(hdr->seq_ctrl);
0427 
0428         if (ieee80211_is_back_req(hdr->frame_control)) {
0429             struct ieee80211_bar *bar;
0430 
0431             bar = (struct ieee80211_bar *)skb->data;
0432             seqno = le16_to_cpu(bar->start_seq_num);
0433         }
0434 
0435         val = MT_TXD3_SN_VALID |
0436               FIELD_PREP(MT_TXD3_SEQ, IEEE80211_SEQ_TO_SN(seqno));
0437         txwi[3] |= cpu_to_le32(val);
0438         txwi[7] &= ~cpu_to_le32(MT_TXD7_HW_AMSDU);
0439     }
0440 
0441     if (mt76_is_mmio(dev)) {
0442         val = FIELD_PREP(MT_TXD7_TYPE, fc_type) |
0443               FIELD_PREP(MT_TXD7_SUB_TYPE, fc_stype);
0444         txwi[7] |= cpu_to_le32(val);
0445     } else {
0446         val = FIELD_PREP(MT_TXD8_L_TYPE, fc_type) |
0447               FIELD_PREP(MT_TXD8_L_SUB_TYPE, fc_stype);
0448         txwi[8] |= cpu_to_le32(val);
0449     }
0450 }
0451 
0452 void mt76_connac2_mac_write_txwi(struct mt76_dev *dev, __le32 *txwi,
0453                  struct sk_buff *skb, struct mt76_wcid *wcid,
0454                  struct ieee80211_key_conf *key, int pid,
0455                  enum mt76_txq_id qid, u32 changed)
0456 {
0457     struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
0458     u8 phy_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
0459     struct ieee80211_vif *vif = info->control.vif;
0460     struct mt76_phy *mphy = &dev->phy;
0461     u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0, band_idx = 0;
0462     u32 val, sz_txd = mt76_is_mmio(dev) ? MT_TXD_SIZE : MT_SDIO_TXD_SIZE;
0463     bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
0464     bool beacon = !!(changed & (BSS_CHANGED_BEACON |
0465                     BSS_CHANGED_BEACON_ENABLED));
0466     bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
0467                      BSS_CHANGED_FILS_DISCOVERY));
0468 
0469     if (vif) {
0470         struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
0471 
0472         omac_idx = mvif->omac_idx;
0473         wmm_idx = mvif->wmm_idx;
0474         band_idx = mvif->band_idx;
0475     }
0476 
0477     if (phy_idx && dev->phys[MT_BAND1])
0478         mphy = dev->phys[MT_BAND1];
0479 
0480     if (inband_disc) {
0481         p_fmt = MT_TX_TYPE_FW;
0482         q_idx = MT_LMAC_ALTX0;
0483     } else if (beacon) {
0484         p_fmt = MT_TX_TYPE_FW;
0485         q_idx = MT_LMAC_BCN0;
0486     } else if (qid >= MT_TXQ_PSD) {
0487         p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
0488         q_idx = MT_LMAC_ALTX0;
0489     } else {
0490         p_fmt = mt76_is_mmio(dev) ? MT_TX_TYPE_CT : MT_TX_TYPE_SF;
0491         q_idx = wmm_idx * MT76_CONNAC_MAX_WMM_SETS +
0492             mt76_connac_lmac_mapping(skb_get_queue_mapping(skb));
0493     }
0494 
0495     val = FIELD_PREP(MT_TXD0_TX_BYTES, skb->len + sz_txd) |
0496           FIELD_PREP(MT_TXD0_PKT_FMT, p_fmt) |
0497           FIELD_PREP(MT_TXD0_Q_IDX, q_idx);
0498     txwi[0] = cpu_to_le32(val);
0499 
0500     val = MT_TXD1_LONG_FORMAT |
0501           FIELD_PREP(MT_TXD1_WLAN_IDX, wcid->idx) |
0502           FIELD_PREP(MT_TXD1_OWN_MAC, omac_idx);
0503     if (!is_mt7921(dev))
0504         val |= MT_TXD1_VTA;
0505     if (phy_idx || band_idx)
0506         val |= MT_TXD1_TGID;
0507 
0508     txwi[1] = cpu_to_le32(val);
0509     txwi[2] = 0;
0510 
0511     val = FIELD_PREP(MT_TXD3_REM_TX_COUNT, 15);
0512     if (!is_mt7921(dev))
0513         val |= MT_TXD3_SW_POWER_MGMT;
0514     if (key)
0515         val |= MT_TXD3_PROTECT_FRAME;
0516     if (info->flags & IEEE80211_TX_CTL_NO_ACK)
0517         val |= MT_TXD3_NO_ACK;
0518 
0519     txwi[3] = cpu_to_le32(val);
0520     txwi[4] = 0;
0521 
0522     val = FIELD_PREP(MT_TXD5_PID, pid);
0523     if (pid >= MT_PACKET_ID_FIRST)
0524         val |= MT_TXD5_TX_STATUS_HOST;
0525 
0526     txwi[5] = cpu_to_le32(val);
0527     txwi[6] = 0;
0528     txwi[7] = wcid->amsdu ? cpu_to_le32(MT_TXD7_HW_AMSDU) : 0;
0529 
0530     if (is_8023)
0531         mt76_connac2_mac_write_txwi_8023(txwi, skb, wcid);
0532     else
0533         mt76_connac2_mac_write_txwi_80211(dev, txwi, skb, key);
0534 
0535     if (txwi[2] & cpu_to_le32(MT_TXD2_FIX_RATE)) {
0536         /* Fixed rata is available just for 802.11 txd */
0537         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
0538         bool multicast = is_multicast_ether_addr(hdr->addr1);
0539         u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon,
0540                             multicast);
0541         u32 val = MT_TXD6_FIXED_BW;
0542 
0543         /* hardware won't add HTC for mgmt/ctrl frame */
0544         txwi[2] |= cpu_to_le32(MT_TXD2_HTC_VLD);
0545 
0546         val |= FIELD_PREP(MT_TXD6_TX_RATE, rate);
0547         txwi[6] |= cpu_to_le32(val);
0548         txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
0549     }
0550 }
0551 EXPORT_SYMBOL_GPL(mt76_connac2_mac_write_txwi);
0552 
0553 bool mt76_connac2_mac_add_txs_skb(struct mt76_dev *dev, struct mt76_wcid *wcid,
0554                   int pid, __le32 *txs_data,
0555                   struct mt76_sta_stats *stats)
0556 {
0557     struct ieee80211_supported_band *sband;
0558     struct mt76_phy *mphy;
0559     struct ieee80211_tx_info *info;
0560     struct sk_buff_head list;
0561     struct rate_info rate = {};
0562     struct sk_buff *skb;
0563     bool cck = false;
0564     u32 txrate, txs, mode;
0565 
0566     mt76_tx_status_lock(dev, &list);
0567     skb = mt76_tx_status_skb_get(dev, wcid, pid, &list);
0568     if (!skb)
0569         goto out;
0570 
0571     txs = le32_to_cpu(txs_data[0]);
0572 
0573     info = IEEE80211_SKB_CB(skb);
0574     if (!(txs & MT_TXS0_ACK_ERROR_MASK))
0575         info->flags |= IEEE80211_TX_STAT_ACK;
0576 
0577     info->status.ampdu_len = 1;
0578     info->status.ampdu_ack_len = !!(info->flags &
0579                     IEEE80211_TX_STAT_ACK);
0580 
0581     info->status.rates[0].idx = -1;
0582 
0583     txrate = FIELD_GET(MT_TXS0_TX_RATE, txs);
0584 
0585     rate.mcs = FIELD_GET(MT_TX_RATE_IDX, txrate);
0586     rate.nss = FIELD_GET(MT_TX_RATE_NSS, txrate) + 1;
0587 
0588     if (rate.nss - 1 < ARRAY_SIZE(stats->tx_nss))
0589         stats->tx_nss[rate.nss - 1]++;
0590     if (rate.mcs < ARRAY_SIZE(stats->tx_mcs))
0591         stats->tx_mcs[rate.mcs]++;
0592 
0593     mode = FIELD_GET(MT_TX_RATE_MODE, txrate);
0594     switch (mode) {
0595     case MT_PHY_TYPE_CCK:
0596         cck = true;
0597         fallthrough;
0598     case MT_PHY_TYPE_OFDM:
0599         mphy = &dev->phy;
0600         if (wcid->phy_idx == MT_BAND1 && dev->phys[MT_BAND1])
0601             mphy = dev->phys[MT_BAND1];
0602 
0603         if (mphy->chandef.chan->band == NL80211_BAND_5GHZ)
0604             sband = &mphy->sband_5g.sband;
0605         else if (mphy->chandef.chan->band == NL80211_BAND_6GHZ)
0606             sband = &mphy->sband_6g.sband;
0607         else
0608             sband = &mphy->sband_2g.sband;
0609 
0610         rate.mcs = mt76_get_rate(mphy->dev, sband, rate.mcs, cck);
0611         rate.legacy = sband->bitrates[rate.mcs].bitrate;
0612         break;
0613     case MT_PHY_TYPE_HT:
0614     case MT_PHY_TYPE_HT_GF:
0615         if (rate.mcs > 31)
0616             goto out;
0617 
0618         rate.flags = RATE_INFO_FLAGS_MCS;
0619         if (wcid->rate.flags & RATE_INFO_FLAGS_SHORT_GI)
0620             rate.flags |= RATE_INFO_FLAGS_SHORT_GI;
0621         break;
0622     case MT_PHY_TYPE_VHT:
0623         if (rate.mcs > 9)
0624             goto out;
0625 
0626         rate.flags = RATE_INFO_FLAGS_VHT_MCS;
0627         break;
0628     case MT_PHY_TYPE_HE_SU:
0629     case MT_PHY_TYPE_HE_EXT_SU:
0630     case MT_PHY_TYPE_HE_TB:
0631     case MT_PHY_TYPE_HE_MU:
0632         if (rate.mcs > 11)
0633             goto out;
0634 
0635         rate.he_gi = wcid->rate.he_gi;
0636         rate.he_dcm = FIELD_GET(MT_TX_RATE_DCM, txrate);
0637         rate.flags = RATE_INFO_FLAGS_HE_MCS;
0638         break;
0639     default:
0640         goto out;
0641     }
0642 
0643     stats->tx_mode[mode]++;
0644 
0645     switch (FIELD_GET(MT_TXS0_BW, txs)) {
0646     case IEEE80211_STA_RX_BW_160:
0647         rate.bw = RATE_INFO_BW_160;
0648         stats->tx_bw[3]++;
0649         break;
0650     case IEEE80211_STA_RX_BW_80:
0651         rate.bw = RATE_INFO_BW_80;
0652         stats->tx_bw[2]++;
0653         break;
0654     case IEEE80211_STA_RX_BW_40:
0655         rate.bw = RATE_INFO_BW_40;
0656         stats->tx_bw[1]++;
0657         break;
0658     default:
0659         rate.bw = RATE_INFO_BW_20;
0660         stats->tx_bw[0]++;
0661         break;
0662     }
0663     wcid->rate = rate;
0664 
0665 out:
0666     if (skb)
0667         mt76_tx_status_skb_done(dev, skb, &list);
0668 
0669     mt76_tx_status_unlock(dev, &list);
0670 
0671     return !!skb;
0672 }
0673 EXPORT_SYMBOL_GPL(mt76_connac2_mac_add_txs_skb);
0674 
0675 static void
0676 mt76_connac2_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
0677                        struct ieee80211_radiotap_he *he,
0678                        __le32 *rxv)
0679 {
0680     u32 ru_h, ru_l;
0681     u8 ru, offs = 0;
0682 
0683     ru_l = le32_get_bits(rxv[0], MT_PRXV_HE_RU_ALLOC_L);
0684     ru_h = le32_get_bits(rxv[1], MT_PRXV_HE_RU_ALLOC_H);
0685     ru = (u8)(ru_l | ru_h << 4);
0686 
0687     status->bw = RATE_INFO_BW_HE_RU;
0688 
0689     switch (ru) {
0690     case 0 ... 36:
0691         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_26;
0692         offs = ru;
0693         break;
0694     case 37 ... 52:
0695         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_52;
0696         offs = ru - 37;
0697         break;
0698     case 53 ... 60:
0699         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_106;
0700         offs = ru - 53;
0701         break;
0702     case 61 ... 64:
0703         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_242;
0704         offs = ru - 61;
0705         break;
0706     case 65 ... 66:
0707         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_484;
0708         offs = ru - 65;
0709         break;
0710     case 67:
0711         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_996;
0712         break;
0713     case 68:
0714         status->he_ru = NL80211_RATE_INFO_HE_RU_ALLOC_2x996;
0715         break;
0716     }
0717 
0718     he->data1 |= HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
0719     he->data2 |= HE_BITS(DATA2_RU_OFFSET_KNOWN) |
0720              le16_encode_bits(offs,
0721                       IEEE80211_RADIOTAP_HE_DATA2_RU_OFFSET);
0722 }
0723 
0724 static void
0725 mt76_connac2_mac_decode_he_mu_radiotap(struct mt76_dev *dev, struct sk_buff *skb,
0726                        __le32 *rxv)
0727 {
0728     struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
0729     static struct ieee80211_radiotap_he_mu mu_known = {
0730         .flags1 = HE_BITS(MU_FLAGS1_SIG_B_MCS_KNOWN) |
0731               HE_BITS(MU_FLAGS1_SIG_B_DCM_KNOWN) |
0732               HE_BITS(MU_FLAGS1_CH1_RU_KNOWN) |
0733               HE_BITS(MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN),
0734         .flags2 = HE_BITS(MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN),
0735     };
0736     struct ieee80211_radiotap_he_mu *he_mu;
0737 
0738     if (is_mt7921(dev)) {
0739         mu_known.flags1 |= HE_BITS(MU_FLAGS1_SIG_B_COMP_KNOWN);
0740         mu_known.flags2 |= HE_BITS(MU_FLAGS2_PUNC_FROM_SIG_A_BW_KNOWN);
0741     }
0742 
0743     status->flag |= RX_FLAG_RADIOTAP_HE_MU;
0744 
0745     he_mu = skb_push(skb, sizeof(mu_known));
0746     memcpy(he_mu, &mu_known, sizeof(mu_known));
0747 
0748 #define MU_PREP(f, v)   le16_encode_bits(v, IEEE80211_RADIOTAP_HE_MU_##f)
0749 
0750     he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_MCS, status->rate_idx);
0751     if (status->he_dcm)
0752         he_mu->flags1 |= MU_PREP(FLAGS1_SIG_B_DCM, status->he_dcm);
0753 
0754     he_mu->flags2 |= MU_PREP(FLAGS2_BW_FROM_SIG_A_BW, status->bw) |
0755              MU_PREP(FLAGS2_SIG_B_SYMS_USERS,
0756                  le32_get_bits(rxv[2], MT_CRXV_HE_NUM_USER));
0757 
0758     he_mu->ru_ch1[0] = le32_get_bits(rxv[3], MT_CRXV_HE_RU0);
0759 
0760     if (status->bw >= RATE_INFO_BW_40) {
0761         he_mu->flags1 |= HE_BITS(MU_FLAGS1_CH2_RU_KNOWN);
0762         he_mu->ru_ch2[0] =
0763             le32_get_bits(rxv[3], MT_CRXV_HE_RU1);
0764     }
0765 
0766     if (status->bw >= RATE_INFO_BW_80) {
0767         he_mu->ru_ch1[1] =
0768             le32_get_bits(rxv[3], MT_CRXV_HE_RU2);
0769         he_mu->ru_ch2[1] =
0770             le32_get_bits(rxv[3], MT_CRXV_HE_RU3);
0771     }
0772 }
0773 
0774 void mt76_connac2_mac_decode_he_radiotap(struct mt76_dev *dev,
0775                      struct sk_buff *skb,
0776                      __le32 *rxv, u32 mode)
0777 {
0778     struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
0779     static const struct ieee80211_radiotap_he known = {
0780         .data1 = HE_BITS(DATA1_DATA_MCS_KNOWN) |
0781              HE_BITS(DATA1_DATA_DCM_KNOWN) |
0782              HE_BITS(DATA1_STBC_KNOWN) |
0783              HE_BITS(DATA1_CODING_KNOWN) |
0784              HE_BITS(DATA1_LDPC_XSYMSEG_KNOWN) |
0785              HE_BITS(DATA1_DOPPLER_KNOWN) |
0786              HE_BITS(DATA1_SPTL_REUSE_KNOWN) |
0787              HE_BITS(DATA1_BSS_COLOR_KNOWN),
0788         .data2 = HE_BITS(DATA2_GI_KNOWN) |
0789              HE_BITS(DATA2_TXBF_KNOWN) |
0790              HE_BITS(DATA2_PE_DISAMBIG_KNOWN) |
0791              HE_BITS(DATA2_TXOP_KNOWN),
0792     };
0793     u32 ltf_size = le32_get_bits(rxv[2], MT_CRXV_HE_LTF_SIZE) + 1;
0794     struct ieee80211_radiotap_he *he;
0795 
0796     status->flag |= RX_FLAG_RADIOTAP_HE;
0797 
0798     he = skb_push(skb, sizeof(known));
0799     memcpy(he, &known, sizeof(known));
0800 
0801     he->data3 = HE_PREP(DATA3_BSS_COLOR, BSS_COLOR, rxv[14]) |
0802             HE_PREP(DATA3_LDPC_XSYMSEG, LDPC_EXT_SYM, rxv[2]);
0803     he->data4 = HE_PREP(DATA4_SU_MU_SPTL_REUSE, SR_MASK, rxv[11]);
0804     he->data5 = HE_PREP(DATA5_PE_DISAMBIG, PE_DISAMBIG, rxv[2]) |
0805             le16_encode_bits(ltf_size,
0806                      IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE);
0807     if (le32_to_cpu(rxv[0]) & MT_PRXV_TXBF)
0808         he->data5 |= HE_BITS(DATA5_TXBF);
0809     he->data6 = HE_PREP(DATA6_TXOP, TXOP_DUR, rxv[14]) |
0810             HE_PREP(DATA6_DOPPLER, DOPPLER, rxv[14]);
0811 
0812     switch (mode) {
0813     case MT_PHY_TYPE_HE_SU:
0814         he->data1 |= HE_BITS(DATA1_FORMAT_SU) |
0815                  HE_BITS(DATA1_UL_DL_KNOWN) |
0816                  HE_BITS(DATA1_BEAM_CHANGE_KNOWN) |
0817                  HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
0818 
0819         he->data3 |= HE_PREP(DATA3_BEAM_CHANGE, BEAM_CHNG, rxv[14]) |
0820                  HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
0821         break;
0822     case MT_PHY_TYPE_HE_EXT_SU:
0823         he->data1 |= HE_BITS(DATA1_FORMAT_EXT_SU) |
0824                  HE_BITS(DATA1_UL_DL_KNOWN) |
0825                  HE_BITS(DATA1_BW_RU_ALLOC_KNOWN);
0826 
0827         he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
0828         break;
0829     case MT_PHY_TYPE_HE_MU:
0830         he->data1 |= HE_BITS(DATA1_FORMAT_MU) |
0831                  HE_BITS(DATA1_UL_DL_KNOWN);
0832 
0833         he->data3 |= HE_PREP(DATA3_UL_DL, UPLINK, rxv[2]);
0834         he->data4 |= HE_PREP(DATA4_MU_STA_ID, MU_AID, rxv[7]);
0835 
0836         mt76_connac2_mac_decode_he_radiotap_ru(status, he, rxv);
0837         mt76_connac2_mac_decode_he_mu_radiotap(dev, skb, rxv);
0838         break;
0839     case MT_PHY_TYPE_HE_TB:
0840         he->data1 |= HE_BITS(DATA1_FORMAT_TRIG) |
0841                  HE_BITS(DATA1_SPTL_REUSE2_KNOWN) |
0842                  HE_BITS(DATA1_SPTL_REUSE3_KNOWN) |
0843                  HE_BITS(DATA1_SPTL_REUSE4_KNOWN);
0844 
0845         he->data4 |= HE_PREP(DATA4_TB_SPTL_REUSE1, SR_MASK, rxv[11]) |
0846                  HE_PREP(DATA4_TB_SPTL_REUSE2, SR1_MASK, rxv[11]) |
0847                  HE_PREP(DATA4_TB_SPTL_REUSE3, SR2_MASK, rxv[11]) |
0848                  HE_PREP(DATA4_TB_SPTL_REUSE4, SR3_MASK, rxv[11]);
0849 
0850         mt76_connac2_mac_decode_he_radiotap_ru(status, he, rxv);
0851         break;
0852     default:
0853         break;
0854     }
0855 }
0856 EXPORT_SYMBOL_GPL(mt76_connac2_mac_decode_he_radiotap);
0857 
0858 /* The HW does not translate the mac header to 802.3 for mesh point */
0859 int mt76_connac2_reverse_frag0_hdr_trans(struct ieee80211_vif *vif,
0860                      struct sk_buff *skb, u16 hdr_offset)
0861 {
0862     struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
0863     struct ethhdr *eth_hdr = (struct ethhdr *)(skb->data + hdr_offset);
0864     __le32 *rxd = (__le32 *)skb->data;
0865     struct ieee80211_sta *sta;
0866     struct ieee80211_hdr hdr;
0867     u16 frame_control;
0868 
0869     if (le32_get_bits(rxd[3], MT_RXD3_NORMAL_ADDR_TYPE) !=
0870         MT_RXD3_NORMAL_U2M)
0871         return -EINVAL;
0872 
0873     if (!(le32_to_cpu(rxd[1]) & MT_RXD1_NORMAL_GROUP_4))
0874         return -EINVAL;
0875 
0876     sta = container_of((void *)status->wcid, struct ieee80211_sta, drv_priv);
0877 
0878     /* store the info from RXD and ethhdr to avoid being overridden */
0879     frame_control = le32_get_bits(rxd[6], MT_RXD6_FRAME_CONTROL);
0880     hdr.frame_control = cpu_to_le16(frame_control);
0881     hdr.seq_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_SEQ_CTRL));
0882     hdr.duration_id = 0;
0883 
0884     ether_addr_copy(hdr.addr1, vif->addr);
0885     ether_addr_copy(hdr.addr2, sta->addr);
0886     switch (frame_control & (IEEE80211_FCTL_TODS |
0887                  IEEE80211_FCTL_FROMDS)) {
0888     case 0:
0889         ether_addr_copy(hdr.addr3, vif->bss_conf.bssid);
0890         break;
0891     case IEEE80211_FCTL_FROMDS:
0892         ether_addr_copy(hdr.addr3, eth_hdr->h_source);
0893         break;
0894     case IEEE80211_FCTL_TODS:
0895         ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
0896         break;
0897     case IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS:
0898         ether_addr_copy(hdr.addr3, eth_hdr->h_dest);
0899         ether_addr_copy(hdr.addr4, eth_hdr->h_source);
0900         break;
0901     default:
0902         break;
0903     }
0904 
0905     skb_pull(skb, hdr_offset + sizeof(struct ethhdr) - 2);
0906     if (eth_hdr->h_proto == cpu_to_be16(ETH_P_AARP) ||
0907         eth_hdr->h_proto == cpu_to_be16(ETH_P_IPX))
0908         ether_addr_copy(skb_push(skb, ETH_ALEN), bridge_tunnel_header);
0909     else if (be16_to_cpu(eth_hdr->h_proto) >= ETH_P_802_3_MIN)
0910         ether_addr_copy(skb_push(skb, ETH_ALEN), rfc1042_header);
0911     else
0912         skb_pull(skb, 2);
0913 
0914     if (ieee80211_has_order(hdr.frame_control))
0915         memcpy(skb_push(skb, IEEE80211_HT_CTL_LEN), &rxd[9],
0916                IEEE80211_HT_CTL_LEN);
0917     if (ieee80211_is_data_qos(hdr.frame_control)) {
0918         __le16 qos_ctrl;
0919 
0920         qos_ctrl = cpu_to_le16(le32_get_bits(rxd[8], MT_RXD8_QOS_CTL));
0921         memcpy(skb_push(skb, IEEE80211_QOS_CTL_LEN), &qos_ctrl,
0922                IEEE80211_QOS_CTL_LEN);
0923     }
0924 
0925     if (ieee80211_has_a4(hdr.frame_control))
0926         memcpy(skb_push(skb, sizeof(hdr)), &hdr, sizeof(hdr));
0927     else
0928         memcpy(skb_push(skb, sizeof(hdr) - 6), &hdr, sizeof(hdr) - 6);
0929 
0930     return 0;
0931 }
0932 EXPORT_SYMBOL_GPL(mt76_connac2_reverse_frag0_hdr_trans);
0933 
0934 int mt76_connac2_mac_fill_rx_rate(struct mt76_dev *dev,
0935                   struct mt76_rx_status *status,
0936                   struct ieee80211_supported_band *sband,
0937                   __le32 *rxv, u8 *mode)
0938 {
0939     u32 v0, v2;
0940     u8 stbc, gi, bw, dcm, nss;
0941     int i, idx;
0942     bool cck = false;
0943 
0944     v0 = le32_to_cpu(rxv[0]);
0945     v2 = le32_to_cpu(rxv[2]);
0946 
0947     idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0);
0948     nss = FIELD_GET(MT_PRXV_NSTS, v0) + 1;
0949 
0950     if (!is_mt7915(dev)) {
0951         stbc = FIELD_GET(MT_PRXV_HT_STBC, v0);
0952         gi = FIELD_GET(MT_PRXV_HT_SGI, v0);
0953         *mode = FIELD_GET(MT_PRXV_TX_MODE, v0);
0954         if (is_mt7921(dev))
0955             dcm = !!(idx & MT_PRXV_TX_DCM);
0956         else
0957             dcm = FIELD_GET(MT_PRXV_DCM, v0);
0958         bw = FIELD_GET(MT_PRXV_FRAME_MODE, v0);
0959     } else {
0960         stbc = FIELD_GET(MT_CRXV_HT_STBC, v2);
0961         gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, v2);
0962         *mode = FIELD_GET(MT_CRXV_TX_MODE, v2);
0963         dcm = !!(idx & GENMASK(3, 0) & MT_PRXV_TX_DCM);
0964         bw = FIELD_GET(MT_CRXV_FRAME_MODE, v2);
0965     }
0966 
0967     switch (*mode) {
0968     case MT_PHY_TYPE_CCK:
0969         cck = true;
0970         fallthrough;
0971     case MT_PHY_TYPE_OFDM:
0972         i = mt76_get_rate(dev, sband, i, cck);
0973         break;
0974     case MT_PHY_TYPE_HT_GF:
0975     case MT_PHY_TYPE_HT:
0976         status->encoding = RX_ENC_HT;
0977         if (gi)
0978             status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
0979         if (i > 31)
0980             return -EINVAL;
0981         break;
0982     case MT_PHY_TYPE_VHT:
0983         status->nss = nss;
0984         status->encoding = RX_ENC_VHT;
0985         if (gi)
0986             status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
0987         if (i > 11)
0988             return -EINVAL;
0989         break;
0990     case MT_PHY_TYPE_HE_MU:
0991     case MT_PHY_TYPE_HE_SU:
0992     case MT_PHY_TYPE_HE_EXT_SU:
0993     case MT_PHY_TYPE_HE_TB:
0994         status->nss = nss;
0995         status->encoding = RX_ENC_HE;
0996         i &= GENMASK(3, 0);
0997 
0998         if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
0999             status->he_gi = gi;
1000 
1001         status->he_dcm = dcm;
1002         break;
1003     default:
1004         return -EINVAL;
1005     }
1006     status->rate_idx = i;
1007 
1008     switch (bw) {
1009     case IEEE80211_STA_RX_BW_20:
1010         break;
1011     case IEEE80211_STA_RX_BW_40:
1012         if (*mode & MT_PHY_TYPE_HE_EXT_SU &&
1013             (idx & MT_PRXV_TX_ER_SU_106T)) {
1014             status->bw = RATE_INFO_BW_HE_RU;
1015             status->he_ru =
1016                 NL80211_RATE_INFO_HE_RU_ALLOC_106;
1017         } else {
1018             status->bw = RATE_INFO_BW_40;
1019         }
1020         break;
1021     case IEEE80211_STA_RX_BW_80:
1022         status->bw = RATE_INFO_BW_80;
1023         break;
1024     case IEEE80211_STA_RX_BW_160:
1025         status->bw = RATE_INFO_BW_160;
1026         break;
1027     default:
1028         return -EINVAL;
1029     }
1030 
1031     status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
1032     if (*mode < MT_PHY_TYPE_HE_SU && gi)
1033         status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
1034 
1035     return 0;
1036 }
1037 EXPORT_SYMBOL_GPL(mt76_connac2_mac_fill_rx_rate);