linux/drivers/net/wireless/mediatek/mt76/mt76x02_mac.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
   3 * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18#include "mt76x02.h"
  19#include "mt76x02_trace.h"
  20
  21static enum mt76x02_cipher_type
  22mt76x02_mac_get_key_info(struct ieee80211_key_conf *key, u8 *key_data)
  23{
  24        memset(key_data, 0, 32);
  25        if (!key)
  26                return MT_CIPHER_NONE;
  27
  28        if (key->keylen > 32)
  29                return MT_CIPHER_NONE;
  30
  31        memcpy(key_data, key->key, key->keylen);
  32
  33        switch (key->cipher) {
  34        case WLAN_CIPHER_SUITE_WEP40:
  35                return MT_CIPHER_WEP40;
  36        case WLAN_CIPHER_SUITE_WEP104:
  37                return MT_CIPHER_WEP104;
  38        case WLAN_CIPHER_SUITE_TKIP:
  39                return MT_CIPHER_TKIP;
  40        case WLAN_CIPHER_SUITE_CCMP:
  41                return MT_CIPHER_AES_CCMP;
  42        default:
  43                return MT_CIPHER_NONE;
  44        }
  45}
  46
  47int mt76x02_mac_shared_key_setup(struct mt76x02_dev *dev, u8 vif_idx,
  48                                 u8 key_idx, struct ieee80211_key_conf *key)
  49{
  50        enum mt76x02_cipher_type cipher;
  51        u8 key_data[32];
  52        u32 val;
  53
  54        cipher = mt76x02_mac_get_key_info(key, key_data);
  55        if (cipher == MT_CIPHER_NONE && key)
  56                return -EOPNOTSUPP;
  57
  58        val = mt76_rr(dev, MT_SKEY_MODE(vif_idx));
  59        val &= ~(MT_SKEY_MODE_MASK << MT_SKEY_MODE_SHIFT(vif_idx, key_idx));
  60        val |= cipher << MT_SKEY_MODE_SHIFT(vif_idx, key_idx);
  61        mt76_wr(dev, MT_SKEY_MODE(vif_idx), val);
  62
  63        mt76_wr_copy(dev, MT_SKEY(vif_idx, key_idx), key_data,
  64                     sizeof(key_data));
  65
  66        return 0;
  67}
  68EXPORT_SYMBOL_GPL(mt76x02_mac_shared_key_setup);
  69
  70void mt76x02_mac_wcid_sync_pn(struct mt76x02_dev *dev, u8 idx,
  71                              struct ieee80211_key_conf *key)
  72{
  73        enum mt76x02_cipher_type cipher;
  74        u8 key_data[32];
  75        u32 iv, eiv;
  76        u64 pn;
  77
  78        cipher = mt76x02_mac_get_key_info(key, key_data);
  79        iv = mt76_rr(dev, MT_WCID_IV(idx));
  80        eiv = mt76_rr(dev, MT_WCID_IV(idx) + 4);
  81
  82        pn = (u64)eiv << 16;
  83        if (cipher == MT_CIPHER_TKIP) {
  84                pn |= (iv >> 16) & 0xff;
  85                pn |= (iv & 0xff) << 8;
  86        } else if (cipher >= MT_CIPHER_AES_CCMP) {
  87                pn |= iv & 0xffff;
  88        } else {
  89                return;
  90        }
  91
  92        atomic64_set(&key->tx_pn, pn);
  93}
  94
  95
  96int mt76x02_mac_wcid_set_key(struct mt76x02_dev *dev, u8 idx,
  97                             struct ieee80211_key_conf *key)
  98{
  99        enum mt76x02_cipher_type cipher;
 100        u8 key_data[32];
 101        u8 iv_data[8];
 102        u64 pn;
 103
 104        cipher = mt76x02_mac_get_key_info(key, key_data);
 105        if (cipher == MT_CIPHER_NONE && key)
 106                return -EOPNOTSUPP;
 107
 108        mt76_wr_copy(dev, MT_WCID_KEY(idx), key_data, sizeof(key_data));
 109        mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PKEY_MODE, cipher);
 110
 111        memset(iv_data, 0, sizeof(iv_data));
 112        if (key) {
 113                mt76_rmw_field(dev, MT_WCID_ATTR(idx), MT_WCID_ATTR_PAIRWISE,
 114                               !!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE));
 115
 116                pn = atomic64_read(&key->tx_pn);
 117
 118                iv_data[3] = key->keyidx << 6;
 119                if (cipher >= MT_CIPHER_TKIP) {
 120                        iv_data[3] |= 0x20;
 121                        put_unaligned_le32(pn >> 16, &iv_data[4]);
 122                }
 123
 124                if (cipher == MT_CIPHER_TKIP) {
 125                        iv_data[0] = (pn >> 8) & 0xff;
 126                        iv_data[1] = (iv_data[0] | 0x20) & 0x7f;
 127                        iv_data[2] = pn & 0xff;
 128                } else if (cipher >= MT_CIPHER_AES_CCMP) {
 129                        put_unaligned_le16((pn & 0xffff), &iv_data[0]);
 130                }
 131        }
 132
 133        mt76_wr_copy(dev, MT_WCID_IV(idx), iv_data, sizeof(iv_data));
 134
 135        return 0;
 136}
 137
 138void mt76x02_mac_wcid_setup(struct mt76x02_dev *dev, u8 idx,
 139                            u8 vif_idx, u8 *mac)
 140{
 141        struct mt76_wcid_addr addr = {};
 142        u32 attr;
 143
 144        attr = FIELD_PREP(MT_WCID_ATTR_BSS_IDX, vif_idx & 7) |
 145               FIELD_PREP(MT_WCID_ATTR_BSS_IDX_EXT, !!(vif_idx & 8));
 146
 147        mt76_wr(dev, MT_WCID_ATTR(idx), attr);
 148
 149        if (idx >= 128)
 150                return;
 151
 152        if (mac)
 153                memcpy(addr.macaddr, mac, ETH_ALEN);
 154
 155        mt76_wr_copy(dev, MT_WCID_ADDR(idx), &addr, sizeof(addr));
 156}
 157EXPORT_SYMBOL_GPL(mt76x02_mac_wcid_setup);
 158
 159void mt76x02_mac_wcid_set_drop(struct mt76x02_dev *dev, u8 idx, bool drop)
 160{
 161        u32 val = mt76_rr(dev, MT_WCID_DROP(idx));
 162        u32 bit = MT_WCID_DROP_MASK(idx);
 163
 164        /* prevent unnecessary writes */
 165        if ((val & bit) != (bit * drop))
 166                mt76_wr(dev, MT_WCID_DROP(idx), (val & ~bit) | (bit * drop));
 167}
 168
 169static __le16
 170mt76x02_mac_tx_rate_val(struct mt76x02_dev *dev,
 171                        const struct ieee80211_tx_rate *rate, u8 *nss_val)
 172{
 173        u8 phy, rate_idx, nss, bw = 0;
 174        u16 rateval;
 175
 176        if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
 177                rate_idx = rate->idx;
 178                nss = 1 + (rate->idx >> 4);
 179                phy = MT_PHY_TYPE_VHT;
 180                if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
 181                        bw = 2;
 182                else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 183                        bw = 1;
 184        } else if (rate->flags & IEEE80211_TX_RC_MCS) {
 185                rate_idx = rate->idx;
 186                nss = 1 + (rate->idx >> 3);
 187                phy = MT_PHY_TYPE_HT;
 188                if (rate->flags & IEEE80211_TX_RC_GREEN_FIELD)
 189                        phy = MT_PHY_TYPE_HT_GF;
 190                if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
 191                        bw = 1;
 192        } else {
 193                const struct ieee80211_rate *r;
 194                int band = dev->mt76.chandef.chan->band;
 195                u16 val;
 196
 197                r = &dev->mt76.hw->wiphy->bands[band]->bitrates[rate->idx];
 198                if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
 199                        val = r->hw_value_short;
 200                else
 201                        val = r->hw_value;
 202
 203                phy = val >> 8;
 204                rate_idx = val & 0xff;
 205                nss = 1;
 206        }
 207
 208        rateval = FIELD_PREP(MT_RXWI_RATE_INDEX, rate_idx);
 209        rateval |= FIELD_PREP(MT_RXWI_RATE_PHY, phy);
 210        rateval |= FIELD_PREP(MT_RXWI_RATE_BW, bw);
 211        if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
 212                rateval |= MT_RXWI_RATE_SGI;
 213
 214        *nss_val = nss;
 215        return cpu_to_le16(rateval);
 216}
 217
 218void mt76x02_mac_wcid_set_rate(struct mt76x02_dev *dev, struct mt76_wcid *wcid,
 219                               const struct ieee80211_tx_rate *rate)
 220{
 221        s8 max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate);
 222        __le16 rateval;
 223        u32 tx_info;
 224        s8 nss;
 225
 226        rateval = mt76x02_mac_tx_rate_val(dev, rate, &nss);
 227        tx_info = FIELD_PREP(MT_WCID_TX_INFO_RATE, rateval) |
 228                  FIELD_PREP(MT_WCID_TX_INFO_NSS, nss) |
 229                  FIELD_PREP(MT_WCID_TX_INFO_TXPWR_ADJ, max_txpwr_adj) |
 230                  MT_WCID_TX_INFO_SET;
 231        wcid->tx_info = tx_info;
 232}
 233
 234void mt76x02_mac_set_short_preamble(struct mt76x02_dev *dev, bool enable)
 235{
 236        if (enable)
 237                mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
 238        else
 239                mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_PREAMB_SHORT);
 240}
 241
 242bool mt76x02_mac_load_tx_status(struct mt76x02_dev *dev,
 243                                struct mt76x02_tx_status *stat)
 244{
 245        u32 stat1, stat2;
 246
 247        stat2 = mt76_rr(dev, MT_TX_STAT_FIFO_EXT);
 248        stat1 = mt76_rr(dev, MT_TX_STAT_FIFO);
 249
 250        stat->valid = !!(stat1 & MT_TX_STAT_FIFO_VALID);
 251        if (!stat->valid)
 252                return false;
 253
 254        stat->success = !!(stat1 & MT_TX_STAT_FIFO_SUCCESS);
 255        stat->aggr = !!(stat1 & MT_TX_STAT_FIFO_AGGR);
 256        stat->ack_req = !!(stat1 & MT_TX_STAT_FIFO_ACKREQ);
 257        stat->wcid = FIELD_GET(MT_TX_STAT_FIFO_WCID, stat1);
 258        stat->rate = FIELD_GET(MT_TX_STAT_FIFO_RATE, stat1);
 259
 260        stat->retry = FIELD_GET(MT_TX_STAT_FIFO_EXT_RETRY, stat2);
 261        stat->pktid = FIELD_GET(MT_TX_STAT_FIFO_EXT_PKTID, stat2);
 262
 263        trace_mac_txstat_fetch(dev, stat);
 264
 265        return true;
 266}
 267
 268static int
 269mt76x02_mac_process_tx_rate(struct ieee80211_tx_rate *txrate, u16 rate,
 270                           enum nl80211_band band)
 271{
 272        u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
 273
 274        txrate->idx = 0;
 275        txrate->flags = 0;
 276        txrate->count = 1;
 277
 278        switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) {
 279        case MT_PHY_TYPE_OFDM:
 280                if (band == NL80211_BAND_2GHZ)
 281                        idx += 4;
 282
 283                txrate->idx = idx;
 284                return 0;
 285        case MT_PHY_TYPE_CCK:
 286                if (idx >= 8)
 287                        idx -= 8;
 288
 289                txrate->idx = idx;
 290                return 0;
 291        case MT_PHY_TYPE_HT_GF:
 292                txrate->flags |= IEEE80211_TX_RC_GREEN_FIELD;
 293                /* fall through */
 294        case MT_PHY_TYPE_HT:
 295                txrate->flags |= IEEE80211_TX_RC_MCS;
 296                txrate->idx = idx;
 297                break;
 298        case MT_PHY_TYPE_VHT:
 299                txrate->flags |= IEEE80211_TX_RC_VHT_MCS;
 300                txrate->idx = idx;
 301                break;
 302        default:
 303                return -EINVAL;
 304        }
 305
 306        switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) {
 307        case MT_PHY_BW_20:
 308                break;
 309        case MT_PHY_BW_40:
 310                txrate->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
 311                break;
 312        case MT_PHY_BW_80:
 313                txrate->flags |= IEEE80211_TX_RC_80_MHZ_WIDTH;
 314                break;
 315        default:
 316                return -EINVAL;
 317        }
 318
 319        if (rate & MT_RXWI_RATE_SGI)
 320                txrate->flags |= IEEE80211_TX_RC_SHORT_GI;
 321
 322        return 0;
 323}
 324
 325void mt76x02_mac_write_txwi(struct mt76x02_dev *dev, struct mt76x02_txwi *txwi,
 326                            struct sk_buff *skb, struct mt76_wcid *wcid,
 327                            struct ieee80211_sta *sta, int len)
 328{
 329        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 330        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 331        struct ieee80211_tx_rate *rate = &info->control.rates[0];
 332        struct ieee80211_key_conf *key = info->control.hw_key;
 333        u32 wcid_tx_info;
 334        u16 rate_ht_mask = FIELD_PREP(MT_RXWI_RATE_PHY, BIT(1) | BIT(2));
 335        u16 txwi_flags = 0;
 336        u8 nss;
 337        s8 txpwr_adj, max_txpwr_adj;
 338        u8 ccmp_pn[8], nstreams = dev->mt76.chainmask & 0xf;
 339
 340        memset(txwi, 0, sizeof(*txwi));
 341
 342        if (!info->control.hw_key && wcid && wcid->hw_key_idx != 0xff &&
 343            ieee80211_has_protected(hdr->frame_control)) {
 344                wcid = NULL;
 345                ieee80211_get_tx_rates(info->control.vif, sta, skb,
 346                                       info->control.rates, 1);
 347        }
 348
 349        if (wcid)
 350                txwi->wcid = wcid->idx;
 351        else
 352                txwi->wcid = 0xff;
 353
 354        if (wcid && wcid->sw_iv && key) {
 355                u64 pn = atomic64_inc_return(&key->tx_pn);
 356                ccmp_pn[0] = pn;
 357                ccmp_pn[1] = pn >> 8;
 358                ccmp_pn[2] = 0;
 359                ccmp_pn[3] = 0x20 | (key->keyidx << 6);
 360                ccmp_pn[4] = pn >> 16;
 361                ccmp_pn[5] = pn >> 24;
 362                ccmp_pn[6] = pn >> 32;
 363                ccmp_pn[7] = pn >> 40;
 364                txwi->iv = *((__le32 *)&ccmp_pn[0]);
 365                txwi->eiv = *((__le32 *)&ccmp_pn[4]);
 366        }
 367
 368        if (wcid && (rate->idx < 0 || !rate->count)) {
 369                wcid_tx_info = wcid->tx_info;
 370                txwi->rate = FIELD_GET(MT_WCID_TX_INFO_RATE, wcid_tx_info);
 371                max_txpwr_adj = FIELD_GET(MT_WCID_TX_INFO_TXPWR_ADJ,
 372                                          wcid_tx_info);
 373                nss = FIELD_GET(MT_WCID_TX_INFO_NSS, wcid_tx_info);
 374        } else {
 375                txwi->rate = mt76x02_mac_tx_rate_val(dev, rate, &nss);
 376                max_txpwr_adj = mt76x02_tx_get_max_txpwr_adj(dev, rate);
 377        }
 378
 379        txpwr_adj = mt76x02_tx_get_txpwr_adj(dev, dev->mt76.txpower_conf,
 380                                             max_txpwr_adj);
 381        txwi->ctl2 = FIELD_PREP(MT_TX_PWR_ADJ, txpwr_adj);
 382
 383        if (nstreams > 1 && mt76_rev(&dev->mt76) >= MT76XX_REV_E4)
 384                txwi->txstream = 0x13;
 385        else if (nstreams > 1 && mt76_rev(&dev->mt76) >= MT76XX_REV_E3 &&
 386                 !(txwi->rate & cpu_to_le16(rate_ht_mask)))
 387                txwi->txstream = 0x93;
 388
 389        if (is_mt76x2(dev) && (info->flags & IEEE80211_TX_CTL_LDPC))
 390                txwi->rate |= cpu_to_le16(MT_RXWI_RATE_LDPC);
 391        if ((info->flags & IEEE80211_TX_CTL_STBC) && nss == 1)
 392                txwi->rate |= cpu_to_le16(MT_RXWI_RATE_STBC);
 393        if (nss > 1 && sta && sta->smps_mode == IEEE80211_SMPS_DYNAMIC)
 394                txwi_flags |= MT_TXWI_FLAGS_MMPS;
 395        if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
 396                txwi->ack_ctl |= MT_TXWI_ACK_CTL_REQ;
 397        if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
 398                txwi->ack_ctl |= MT_TXWI_ACK_CTL_NSEQ;
 399        if ((info->flags & IEEE80211_TX_CTL_AMPDU) && sta) {
 400                u8 ba_size = IEEE80211_MIN_AMPDU_BUF;
 401
 402                ba_size <<= sta->ht_cap.ampdu_factor;
 403                ba_size = min_t(int, 63, ba_size - 1);
 404                if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
 405                        ba_size = 0;
 406                txwi->ack_ctl |= FIELD_PREP(MT_TXWI_ACK_CTL_BA_WINDOW, ba_size);
 407
 408                txwi_flags |= MT_TXWI_FLAGS_AMPDU |
 409                         FIELD_PREP(MT_TXWI_FLAGS_MPDU_DENSITY,
 410                                    sta->ht_cap.ampdu_density);
 411        }
 412
 413        if (ieee80211_is_probe_resp(hdr->frame_control) ||
 414            ieee80211_is_beacon(hdr->frame_control))
 415                txwi_flags |= MT_TXWI_FLAGS_TS;
 416
 417        txwi->flags |= cpu_to_le16(txwi_flags);
 418        txwi->len_ctl = cpu_to_le16(len);
 419}
 420EXPORT_SYMBOL_GPL(mt76x02_mac_write_txwi);
 421
 422static void
 423mt76x02_mac_fill_tx_status(struct mt76x02_dev *dev,
 424                           struct ieee80211_tx_info *info,
 425                           struct mt76x02_tx_status *st, int n_frames)
 426{
 427        struct ieee80211_tx_rate *rate = info->status.rates;
 428        int cur_idx, last_rate;
 429        int i;
 430
 431        if (!n_frames)
 432                return;
 433
 434        last_rate = min_t(int, st->retry, IEEE80211_TX_MAX_RATES - 1);
 435        mt76x02_mac_process_tx_rate(&rate[last_rate], st->rate,
 436                                    dev->mt76.chandef.chan->band);
 437        if (last_rate < IEEE80211_TX_MAX_RATES - 1)
 438                rate[last_rate + 1].idx = -1;
 439
 440        cur_idx = rate[last_rate].idx + last_rate;
 441        for (i = 0; i <= last_rate; i++) {
 442                rate[i].flags = rate[last_rate].flags;
 443                rate[i].idx = max_t(int, 0, cur_idx - i);
 444                rate[i].count = 1;
 445        }
 446        rate[last_rate].count = st->retry + 1 - last_rate;
 447
 448        info->status.ampdu_len = n_frames;
 449        info->status.ampdu_ack_len = st->success ? n_frames : 0;
 450
 451        if (st->aggr)
 452                info->flags |= IEEE80211_TX_CTL_AMPDU |
 453                               IEEE80211_TX_STAT_AMPDU;
 454
 455        if (!st->ack_req)
 456                info->flags |= IEEE80211_TX_CTL_NO_ACK;
 457        else if (st->success)
 458                info->flags |= IEEE80211_TX_STAT_ACK;
 459}
 460
 461void mt76x02_send_tx_status(struct mt76x02_dev *dev,
 462                            struct mt76x02_tx_status *stat, u8 *update)
 463{
 464        struct ieee80211_tx_info info = {};
 465        struct ieee80211_tx_status status = {
 466                .info = &info
 467        };
 468        struct mt76_wcid *wcid = NULL;
 469        struct mt76x02_sta *msta = NULL;
 470        struct mt76_dev *mdev = &dev->mt76;
 471        struct sk_buff_head list;
 472
 473        if (stat->pktid == MT_PACKET_ID_NO_ACK)
 474                return;
 475
 476        rcu_read_lock();
 477
 478        if (stat->wcid < ARRAY_SIZE(dev->mt76.wcid))
 479                wcid = rcu_dereference(dev->mt76.wcid[stat->wcid]);
 480
 481        if (wcid && wcid->sta) {
 482                void *priv;
 483
 484                priv = msta = container_of(wcid, struct mt76x02_sta, wcid);
 485                status.sta = container_of(priv, struct ieee80211_sta,
 486                                          drv_priv);
 487        }
 488
 489        mt76_tx_status_lock(mdev, &list);
 490
 491        if (wcid) {
 492                if (stat->pktid >= MT_PACKET_ID_FIRST)
 493                        status.skb = mt76_tx_status_skb_get(mdev, wcid,
 494                                                            stat->pktid, &list);
 495                if (status.skb)
 496                        status.info = IEEE80211_SKB_CB(status.skb);
 497        }
 498
 499        if (msta && stat->aggr && !status.skb) {
 500                u32 stat_val, stat_cache;
 501
 502                stat_val = stat->rate;
 503                stat_val |= ((u32) stat->retry) << 16;
 504                stat_cache = msta->status.rate;
 505                stat_cache |= ((u32) msta->status.retry) << 16;
 506
 507                if (*update == 0 && stat_val == stat_cache &&
 508                    stat->wcid == msta->status.wcid && msta->n_frames < 32) {
 509                        msta->n_frames++;
 510                        mt76_tx_status_unlock(mdev, &list);
 511                        rcu_read_unlock();
 512                        return;
 513                }
 514
 515                mt76x02_mac_fill_tx_status(dev, status.info, &msta->status,
 516                                           msta->n_frames);
 517
 518                msta->status = *stat;
 519                msta->n_frames = 1;
 520                *update = 0;
 521        } else {
 522                mt76x02_mac_fill_tx_status(dev, status.info, stat, 1);
 523                *update = 1;
 524        }
 525
 526        if (status.skb)
 527                mt76_tx_status_skb_done(mdev, status.skb, &list);
 528        mt76_tx_status_unlock(mdev, &list);
 529
 530        if (!status.skb)
 531                ieee80211_tx_status_ext(mt76_hw(dev), &status);
 532        rcu_read_unlock();
 533}
 534
 535static int
 536mt76x02_mac_process_rate(struct mt76x02_dev *dev,
 537                         struct mt76_rx_status *status,
 538                         u16 rate)
 539{
 540        u8 idx = FIELD_GET(MT_RXWI_RATE_INDEX, rate);
 541
 542        switch (FIELD_GET(MT_RXWI_RATE_PHY, rate)) {
 543        case MT_PHY_TYPE_OFDM:
 544                if (idx >= 8)
 545                        idx = 0;
 546
 547                if (status->band == NL80211_BAND_2GHZ)
 548                        idx += 4;
 549
 550                status->rate_idx = idx;
 551                return 0;
 552        case MT_PHY_TYPE_CCK:
 553                if (idx >= 8) {
 554                        idx -= 8;
 555                        status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
 556                }
 557
 558                if (idx >= 4)
 559                        idx = 0;
 560
 561                status->rate_idx = idx;
 562                return 0;
 563        case MT_PHY_TYPE_HT_GF:
 564                status->enc_flags |= RX_ENC_FLAG_HT_GF;
 565                /* fall through */
 566        case MT_PHY_TYPE_HT:
 567                status->encoding = RX_ENC_HT;
 568                status->rate_idx = idx;
 569                break;
 570        case MT_PHY_TYPE_VHT: {
 571                u8 n_rxstream = dev->mt76.chainmask & 0xf;
 572
 573                status->encoding = RX_ENC_VHT;
 574                status->rate_idx = FIELD_GET(MT_RATE_INDEX_VHT_IDX, idx);
 575                status->nss = min_t(u8, n_rxstream,
 576                                    FIELD_GET(MT_RATE_INDEX_VHT_NSS, idx) + 1);
 577                break;
 578        }
 579        default:
 580                return -EINVAL;
 581        }
 582
 583        if (rate & MT_RXWI_RATE_LDPC)
 584                status->enc_flags |= RX_ENC_FLAG_LDPC;
 585
 586        if (rate & MT_RXWI_RATE_SGI)
 587                status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
 588
 589        if (rate & MT_RXWI_RATE_STBC)
 590                status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT;
 591
 592        switch (FIELD_GET(MT_RXWI_RATE_BW, rate)) {
 593        case MT_PHY_BW_20:
 594                break;
 595        case MT_PHY_BW_40:
 596                status->bw = RATE_INFO_BW_40;
 597                break;
 598        case MT_PHY_BW_80:
 599                status->bw = RATE_INFO_BW_80;
 600                break;
 601        default:
 602                break;
 603        }
 604
 605        return 0;
 606}
 607
 608void mt76x02_mac_setaddr(struct mt76x02_dev *dev, const u8 *addr)
 609{
 610        static const u8 null_addr[ETH_ALEN] = {};
 611        int i;
 612
 613        ether_addr_copy(dev->mt76.macaddr, addr);
 614
 615        if (!is_valid_ether_addr(dev->mt76.macaddr)) {
 616                eth_random_addr(dev->mt76.macaddr);
 617                dev_info(dev->mt76.dev,
 618                         "Invalid MAC address, using random address %pM\n",
 619                         dev->mt76.macaddr);
 620        }
 621
 622        mt76_wr(dev, MT_MAC_ADDR_DW0, get_unaligned_le32(dev->mt76.macaddr));
 623        mt76_wr(dev, MT_MAC_ADDR_DW1,
 624                get_unaligned_le16(dev->mt76.macaddr + 4) |
 625                FIELD_PREP(MT_MAC_ADDR_DW1_U2ME_MASK, 0xff));
 626
 627        mt76_wr(dev, MT_MAC_BSSID_DW0,
 628                get_unaligned_le32(dev->mt76.macaddr));
 629        mt76_wr(dev, MT_MAC_BSSID_DW1,
 630                get_unaligned_le16(dev->mt76.macaddr + 4) |
 631                FIELD_PREP(MT_MAC_BSSID_DW1_MBSS_MODE, 3) | /* 8 APs + 8 STAs */
 632                MT_MAC_BSSID_DW1_MBSS_LOCAL_BIT);
 633
 634        for (i = 0; i < 16; i++)
 635                mt76x02_mac_set_bssid(dev, i, null_addr);
 636}
 637EXPORT_SYMBOL_GPL(mt76x02_mac_setaddr);
 638
 639static int
 640mt76x02_mac_get_rssi(struct mt76x02_dev *dev, s8 rssi, int chain)
 641{
 642        struct mt76x02_rx_freq_cal *cal = &dev->cal.rx;
 643
 644        rssi += cal->rssi_offset[chain];
 645        rssi -= cal->lna_gain;
 646
 647        return rssi;
 648}
 649
 650int mt76x02_mac_process_rx(struct mt76x02_dev *dev, struct sk_buff *skb,
 651                           void *rxi)
 652{
 653        struct mt76_rx_status *status = (struct mt76_rx_status *) skb->cb;
 654        struct mt76x02_rxwi *rxwi = rxi;
 655        struct mt76x02_sta *sta;
 656        u32 rxinfo = le32_to_cpu(rxwi->rxinfo);
 657        u32 ctl = le32_to_cpu(rxwi->ctl);
 658        u16 rate = le16_to_cpu(rxwi->rate);
 659        u16 tid_sn = le16_to_cpu(rxwi->tid_sn);
 660        bool unicast = rxwi->rxinfo & cpu_to_le32(MT_RXINFO_UNICAST);
 661        int pad_len = 0, nstreams = dev->mt76.chainmask & 0xf;
 662        s8 signal;
 663        u8 pn_len;
 664        u8 wcid;
 665        int len;
 666
 667        if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
 668                return -EINVAL;
 669
 670        if (rxinfo & MT_RXINFO_L2PAD)
 671                pad_len += 2;
 672
 673        if (rxinfo & MT_RXINFO_DECRYPT) {
 674                status->flag |= RX_FLAG_DECRYPTED;
 675                status->flag |= RX_FLAG_MMIC_STRIPPED;
 676                status->flag |= RX_FLAG_MIC_STRIPPED;
 677                status->flag |= RX_FLAG_IV_STRIPPED;
 678        }
 679
 680        wcid = FIELD_GET(MT_RXWI_CTL_WCID, ctl);
 681        sta = mt76x02_rx_get_sta(&dev->mt76, wcid);
 682        status->wcid = mt76x02_rx_get_sta_wcid(sta, unicast);
 683
 684        len = FIELD_GET(MT_RXWI_CTL_MPDU_LEN, ctl);
 685        pn_len = FIELD_GET(MT_RXINFO_PN_LEN, rxinfo);
 686        if (pn_len) {
 687                int offset = ieee80211_get_hdrlen_from_skb(skb) + pad_len;
 688                u8 *data = skb->data + offset;
 689
 690                status->iv[0] = data[7];
 691                status->iv[1] = data[6];
 692                status->iv[2] = data[5];
 693                status->iv[3] = data[4];
 694                status->iv[4] = data[1];
 695                status->iv[5] = data[0];
 696
 697                /*
 698                 * Driver CCMP validation can't deal with fragments.
 699                 * Let mac80211 take care of it.
 700                 */
 701                if (rxinfo & MT_RXINFO_FRAG) {
 702                        status->flag &= ~RX_FLAG_IV_STRIPPED;
 703                } else {
 704                        pad_len += pn_len << 2;
 705                        len -= pn_len << 2;
 706                }
 707        }
 708
 709        mt76x02_remove_hdr_pad(skb, pad_len);
 710
 711        if ((rxinfo & MT_RXINFO_BA) && !(rxinfo & MT_RXINFO_NULL))
 712                status->aggr = true;
 713
 714        if (WARN_ON_ONCE(len > skb->len))
 715                return -EINVAL;
 716
 717        pskb_trim(skb, len);
 718
 719        status->chains = BIT(0);
 720        signal = mt76x02_mac_get_rssi(dev, rxwi->rssi[0], 0);
 721        status->chain_signal[0] = signal;
 722        if (nstreams > 1) {
 723                status->chains |= BIT(1);
 724                status->chain_signal[1] = mt76x02_mac_get_rssi(dev,
 725                                                               rxwi->rssi[1],
 726                                                               1);
 727                signal = max_t(s8, signal, status->chain_signal[1]);
 728        }
 729        status->signal = signal;
 730        status->freq = dev->mt76.chandef.chan->center_freq;
 731        status->band = dev->mt76.chandef.chan->band;
 732
 733        status->tid = FIELD_GET(MT_RXWI_TID, tid_sn);
 734        status->seqno = FIELD_GET(MT_RXWI_SN, tid_sn);
 735
 736        return mt76x02_mac_process_rate(dev, status, rate);
 737}
 738
 739void mt76x02_mac_poll_tx_status(struct mt76x02_dev *dev, bool irq)
 740{
 741        struct mt76x02_tx_status stat = {};
 742        u8 update = 1;
 743        bool ret;
 744
 745        if (!test_bit(MT76_STATE_RUNNING, &dev->mt76.state))
 746                return;
 747
 748        trace_mac_txstat_poll(dev);
 749
 750        while (!irq || !kfifo_is_full(&dev->txstatus_fifo)) {
 751                if (!spin_trylock(&dev->txstatus_fifo_lock))
 752                        break;
 753
 754                ret = mt76x02_mac_load_tx_status(dev, &stat);
 755                spin_unlock(&dev->txstatus_fifo_lock);
 756
 757                if (!ret)
 758                        break;
 759
 760                if (!irq) {
 761                        mt76x02_send_tx_status(dev, &stat, &update);
 762                        continue;
 763                }
 764
 765                kfifo_put(&dev->txstatus_fifo, stat);
 766        }
 767}
 768
 769void mt76x02_tx_complete_skb(struct mt76_dev *mdev, enum mt76_txq_id qid,
 770                             struct mt76_queue_entry *e)
 771{
 772        struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
 773        struct mt76x02_txwi *txwi;
 774        u8 *txwi_ptr;
 775
 776        if (!e->txwi) {
 777                dev_kfree_skb_any(e->skb);
 778                return;
 779        }
 780
 781        mt76x02_mac_poll_tx_status(dev, false);
 782
 783        txwi_ptr = mt76_get_txwi_ptr(mdev, e->txwi);
 784        txwi = (struct mt76x02_txwi *)txwi_ptr;
 785        trace_mac_txdone_add(dev, txwi->wcid, txwi->pktid);
 786
 787        mt76_tx_complete_skb(mdev, e->skb);
 788}
 789EXPORT_SYMBOL_GPL(mt76x02_tx_complete_skb);
 790
 791void mt76x02_mac_set_rts_thresh(struct mt76x02_dev *dev, u32 val)
 792{
 793        u32 data = 0;
 794
 795        if (val != ~0)
 796                data = FIELD_PREP(MT_PROT_CFG_CTRL, 1) |
 797                       MT_PROT_CFG_RTS_THRESH;
 798
 799        mt76_rmw_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH, val);
 800
 801        mt76_rmw(dev, MT_CCK_PROT_CFG,
 802                 MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
 803        mt76_rmw(dev, MT_OFDM_PROT_CFG,
 804                 MT_PROT_CFG_CTRL | MT_PROT_CFG_RTS_THRESH, data);
 805}
 806
 807void mt76x02_mac_set_tx_protection(struct mt76x02_dev *dev, bool legacy_prot,
 808                                   int ht_mode)
 809{
 810        int mode = ht_mode & IEEE80211_HT_OP_MODE_PROTECTION;
 811        bool non_gf = !!(ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
 812        u32 prot[6];
 813        u32 vht_prot[3];
 814        int i;
 815        u16 rts_thr;
 816
 817        for (i = 0; i < ARRAY_SIZE(prot); i++) {
 818                prot[i] = mt76_rr(dev, MT_CCK_PROT_CFG + i * 4);
 819                prot[i] &= ~MT_PROT_CFG_CTRL;
 820                if (i >= 2)
 821                        prot[i] &= ~MT_PROT_CFG_RATE;
 822        }
 823
 824        for (i = 0; i < ARRAY_SIZE(vht_prot); i++) {
 825                vht_prot[i] = mt76_rr(dev, MT_TX_PROT_CFG6 + i * 4);
 826                vht_prot[i] &= ~(MT_PROT_CFG_CTRL | MT_PROT_CFG_RATE);
 827        }
 828
 829        rts_thr = mt76_get_field(dev, MT_TX_RTS_CFG, MT_TX_RTS_CFG_THRESH);
 830
 831        if (rts_thr != 0xffff)
 832                prot[0] |= MT_PROT_CTRL_RTS_CTS;
 833
 834        if (legacy_prot) {
 835                prot[1] |= MT_PROT_CTRL_CTS2SELF;
 836
 837                prot[2] |= MT_PROT_RATE_CCK_11;
 838                prot[3] |= MT_PROT_RATE_CCK_11;
 839                prot[4] |= MT_PROT_RATE_CCK_11;
 840                prot[5] |= MT_PROT_RATE_CCK_11;
 841
 842                vht_prot[0] |= MT_PROT_RATE_CCK_11;
 843                vht_prot[1] |= MT_PROT_RATE_CCK_11;
 844                vht_prot[2] |= MT_PROT_RATE_CCK_11;
 845        } else {
 846                if (rts_thr != 0xffff)
 847                        prot[1] |= MT_PROT_CTRL_RTS_CTS;
 848
 849                prot[2] |= MT_PROT_RATE_OFDM_24;
 850                prot[3] |= MT_PROT_RATE_DUP_OFDM_24;
 851                prot[4] |= MT_PROT_RATE_OFDM_24;
 852                prot[5] |= MT_PROT_RATE_DUP_OFDM_24;
 853
 854                vht_prot[0] |= MT_PROT_RATE_OFDM_24;
 855                vht_prot[1] |= MT_PROT_RATE_DUP_OFDM_24;
 856                vht_prot[2] |= MT_PROT_RATE_SGI_OFDM_24;
 857        }
 858
 859        switch (mode) {
 860        case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
 861        case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
 862                prot[2] |= MT_PROT_CTRL_RTS_CTS;
 863                prot[3] |= MT_PROT_CTRL_RTS_CTS;
 864                prot[4] |= MT_PROT_CTRL_RTS_CTS;
 865                prot[5] |= MT_PROT_CTRL_RTS_CTS;
 866                vht_prot[0] |= MT_PROT_CTRL_RTS_CTS;
 867                vht_prot[1] |= MT_PROT_CTRL_RTS_CTS;
 868                vht_prot[2] |= MT_PROT_CTRL_RTS_CTS;
 869                break;
 870        case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
 871                prot[3] |= MT_PROT_CTRL_RTS_CTS;
 872                prot[5] |= MT_PROT_CTRL_RTS_CTS;
 873                vht_prot[1] |= MT_PROT_CTRL_RTS_CTS;
 874                vht_prot[2] |= MT_PROT_CTRL_RTS_CTS;
 875                break;
 876        }
 877
 878        if (non_gf) {
 879                prot[4] |= MT_PROT_CTRL_RTS_CTS;
 880                prot[5] |= MT_PROT_CTRL_RTS_CTS;
 881        }
 882
 883        for (i = 0; i < ARRAY_SIZE(prot); i++)
 884                mt76_wr(dev, MT_CCK_PROT_CFG + i * 4, prot[i]);
 885
 886        for (i = 0; i < ARRAY_SIZE(vht_prot); i++)
 887                mt76_wr(dev, MT_TX_PROT_CFG6 + i * 4, vht_prot[i]);
 888}
 889
 890void mt76x02_update_channel(struct mt76_dev *mdev)
 891{
 892        struct mt76x02_dev *dev = container_of(mdev, struct mt76x02_dev, mt76);
 893        struct mt76_channel_state *state;
 894        u32 active, busy;
 895
 896        state = mt76_channel_state(&dev->mt76, dev->mt76.chandef.chan);
 897
 898        busy = mt76_rr(dev, MT_CH_BUSY);
 899        active = busy + mt76_rr(dev, MT_CH_IDLE);
 900
 901        spin_lock_bh(&dev->mt76.cc_lock);
 902        state->cc_busy += busy;
 903        state->cc_active += active;
 904        spin_unlock_bh(&dev->mt76.cc_lock);
 905}
 906EXPORT_SYMBOL_GPL(mt76x02_update_channel);
 907
 908static void mt76x02_check_mac_err(struct mt76x02_dev *dev)
 909{
 910        u32 val = mt76_rr(dev, 0x10f4);
 911
 912        if (!(val & BIT(29)) || !(val & (BIT(7) | BIT(5))))
 913                return;
 914
 915        dev_err(dev->mt76.dev, "mac specific condition occurred\n");
 916
 917        mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_RESET_CSR);
 918        udelay(10);
 919        mt76_wr(dev, MT_MAC_SYS_CTRL,
 920                MT_MAC_SYS_CTRL_ENABLE_TX | MT_MAC_SYS_CTRL_ENABLE_RX);
 921}
 922
 923static void
 924mt76x02_edcca_tx_enable(struct mt76x02_dev *dev, bool enable)
 925{
 926        if (enable) {
 927                u32 data;
 928
 929                mt76_set(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX);
 930                mt76_set(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_EN);
 931                /* enable pa-lna */
 932                data = mt76_rr(dev, MT_TX_PIN_CFG);
 933                data |= MT_TX_PIN_CFG_TXANT |
 934                        MT_TX_PIN_CFG_RXANT |
 935                        MT_TX_PIN_RFTR_EN |
 936                        MT_TX_PIN_TRSW_EN;
 937                mt76_wr(dev, MT_TX_PIN_CFG, data);
 938        } else {
 939                mt76_clear(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_TX);
 940                mt76_clear(dev, MT_AUTO_RSP_CFG, MT_AUTO_RSP_EN);
 941                /* disable pa-lna */
 942                mt76_clear(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT);
 943                mt76_clear(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_RXANT);
 944        }
 945        dev->ed_tx_blocked = !enable;
 946}
 947
 948void mt76x02_edcca_init(struct mt76x02_dev *dev, bool enable)
 949{
 950        dev->ed_trigger = 0;
 951        dev->ed_silent = 0;
 952
 953        if (dev->ed_monitor && enable) {
 954                struct ieee80211_channel *chan = dev->mt76.chandef.chan;
 955                u8 ed_th = chan->band == NL80211_BAND_5GHZ ? 0x0e : 0x20;
 956
 957                mt76_clear(dev, MT_TX_LINK_CFG, MT_TX_CFACK_EN);
 958                mt76_set(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
 959                mt76_rmw(dev, MT_BBP(AGC, 2), GENMASK(15, 0),
 960                         ed_th << 8 | ed_th);
 961                mt76_set(dev, MT_TXOP_HLDR_ET, MT_TXOP_HLDR_TX40M_BLK_EN);
 962        } else {
 963                mt76_set(dev, MT_TX_LINK_CFG, MT_TX_CFACK_EN);
 964                mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
 965                if (is_mt76x2(dev)) {
 966                        mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
 967                        mt76_set(dev, MT_TXOP_HLDR_ET,
 968                                 MT_TXOP_HLDR_TX40M_BLK_EN);
 969                } else {
 970                        mt76_wr(dev, MT_BBP(AGC, 2), 0x003a6464);
 971                        mt76_clear(dev, MT_TXOP_HLDR_ET,
 972                                   MT_TXOP_HLDR_TX40M_BLK_EN);
 973                }
 974        }
 975        mt76x02_edcca_tx_enable(dev, true);
 976        dev->ed_monitor_learning = true;
 977
 978        /* clear previous CCA timer value */
 979        mt76_rr(dev, MT_ED_CCA_TIMER);
 980        dev->ed_time = ktime_get_boottime();
 981}
 982EXPORT_SYMBOL_GPL(mt76x02_edcca_init);
 983
 984#define MT_EDCCA_TH             92
 985#define MT_EDCCA_BLOCK_TH       2
 986#define MT_EDCCA_LEARN_TH       50
 987#define MT_EDCCA_LEARN_CCA      180
 988#define MT_EDCCA_LEARN_TIMEOUT  (20 * HZ)
 989
 990static void mt76x02_edcca_check(struct mt76x02_dev *dev)
 991{
 992        ktime_t cur_time;
 993        u32 active, val, busy;
 994
 995        cur_time = ktime_get_boottime();
 996        val = mt76_rr(dev, MT_ED_CCA_TIMER);
 997
 998        active = ktime_to_us(ktime_sub(cur_time, dev->ed_time));
 999        dev->ed_time = cur_time;
1000
1001        busy = (val * 100) / active;
1002        busy = min_t(u32, busy, 100);
1003
1004        if (busy > MT_EDCCA_TH) {
1005                dev->ed_trigger++;
1006                dev->ed_silent = 0;
1007        } else {
1008                dev->ed_silent++;
1009                dev->ed_trigger = 0;
1010        }
1011
1012        if (dev->cal.agc_lowest_gain &&
1013            dev->cal.false_cca > MT_EDCCA_LEARN_CCA &&
1014            dev->ed_trigger > MT_EDCCA_LEARN_TH) {
1015                dev->ed_monitor_learning = false;
1016                dev->ed_trigger_timeout = jiffies + 20 * HZ;
1017        } else if (!dev->ed_monitor_learning &&
1018                   time_is_after_jiffies(dev->ed_trigger_timeout)) {
1019                dev->ed_monitor_learning = true;
1020                mt76x02_edcca_tx_enable(dev, true);
1021        }
1022
1023        if (dev->ed_monitor_learning)
1024                return;
1025
1026        if (dev->ed_trigger > MT_EDCCA_BLOCK_TH && !dev->ed_tx_blocked)
1027                mt76x02_edcca_tx_enable(dev, false);
1028        else if (dev->ed_silent > MT_EDCCA_BLOCK_TH && dev->ed_tx_blocked)
1029                mt76x02_edcca_tx_enable(dev, true);
1030}
1031
1032void mt76x02_mac_work(struct work_struct *work)
1033{
1034        struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
1035                                               mt76.mac_work.work);
1036        int i, idx;
1037
1038        mutex_lock(&dev->mt76.mutex);
1039
1040        mt76x02_update_channel(&dev->mt76);
1041        for (i = 0, idx = 0; i < 16; i++) {
1042                u32 val = mt76_rr(dev, MT_TX_AGG_CNT(i));
1043
1044                dev->aggr_stats[idx++] += val & 0xffff;
1045                dev->aggr_stats[idx++] += val >> 16;
1046        }
1047
1048        if (!dev->mt76.beacon_mask)
1049                mt76x02_check_mac_err(dev);
1050
1051        if (dev->ed_monitor)
1052                mt76x02_edcca_check(dev);
1053
1054        mutex_unlock(&dev->mt76.mutex);
1055
1056        mt76_tx_status_check(&dev->mt76, NULL, false);
1057
1058        ieee80211_queue_delayed_work(mt76_hw(dev), &dev->mt76.mac_work,
1059                                     MT_MAC_WORK_INTERVAL);
1060}
1061
1062void mt76x02_mac_set_bssid(struct mt76x02_dev *dev, u8 idx, const u8 *addr)
1063{
1064        idx &= 7;
1065        mt76_wr(dev, MT_MAC_APC_BSSID_L(idx), get_unaligned_le32(addr));
1066        mt76_rmw_field(dev, MT_MAC_APC_BSSID_H(idx), MT_MAC_APC_BSSID_H_ADDR,
1067                       get_unaligned_le16(addr + 4));
1068}
1069