linux/drivers/net/wireless/mediatek/mt76/mt7915/init.c
<<
>>
Prefs
   1// SPDX-License-Identifier: ISC
   2/* Copyright (C) 2020 MediaTek Inc. */
   3
   4#include <linux/etherdevice.h>
   5#include "mt7915.h"
   6#include "mac.h"
   7#include "eeprom.h"
   8
   9static void
  10mt7915_mac_init_band(struct mt7915_dev *dev, u8 band)
  11{
  12        u32 mask, set;
  13
  14        mt76_rmw_field(dev, MT_TMAC_CTCR0(band),
  15                       MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
  16        mt76_set(dev, MT_TMAC_CTCR0(band),
  17                 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
  18                 MT_TMAC_CTCR0_INS_DDLMT_EN);
  19
  20        mask = MT_MDP_RCFR0_MCU_RX_MGMT |
  21               MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR |
  22               MT_MDP_RCFR0_MCU_RX_CTL_BAR;
  23        set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) |
  24              FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) |
  25              FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF);
  26        mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set);
  27
  28        mask = MT_MDP_RCFR1_MCU_RX_BYPASS |
  29               MT_MDP_RCFR1_RX_DROPPED_UCAST |
  30               MT_MDP_RCFR1_RX_DROPPED_MCAST;
  31        set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |
  32              FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |
  33              FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
  34        mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);
  35
  36        mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
  37        mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
  38}
  39
  40static void mt7915_mac_init(struct mt7915_dev *dev)
  41{
  42        int i;
  43
  44        mt76_rmw_field(dev, MT_DMA_DCR0, MT_DMA_DCR0_MAX_RX_LEN, 1536);
  45        mt76_rmw_field(dev, MT_MDP_DCR1, MT_MDP_DCR1_MAX_RX_LEN, 1536);
  46        /* enable rx rate report */
  47        mt76_set(dev, MT_DMA_DCR0, MT_DMA_DCR0_RXD_G5_EN);
  48        /* disable hardware de-agg */
  49        mt76_clear(dev, MT_MDP_DCR0, MT_MDP_DCR0_DAMSDU_EN);
  50
  51        for (i = 0; i < MT7915_WTBL_SIZE; i++)
  52                mt7915_mac_wtbl_update(dev, i,
  53                                       MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
  54
  55        mt7915_mac_init_band(dev, 0);
  56        mt7915_mac_init_band(dev, 1);
  57        mt7915_mcu_set_rts_thresh(&dev->phy, 0x92b);
  58}
  59
  60static int mt7915_txbf_init(struct mt7915_dev *dev)
  61{
  62        int ret;
  63
  64        /*
  65         * TODO: DBDC & check whether iBF phase calibration data has
  66         * been stored in eeprom offset 0x651~0x7b8, then write down
  67         * 0x1111 into 0x651 and 0x651 to trigger iBF.
  68         */
  69
  70        /* trigger sounding packets */
  71        ret = mt7915_mcu_set_txbf_sounding(dev);
  72        if (ret)
  73                return ret;
  74
  75        /* enable iBF & eBF */
  76        return mt7915_mcu_set_txbf_type(dev);
  77}
  78
  79static void
  80mt7915_init_txpower_band(struct mt7915_dev *dev,
  81                         struct ieee80211_supported_band *sband)
  82{
  83        int i, n_chains = hweight8(dev->mphy.antenna_mask);
  84
  85        for (i = 0; i < sband->n_channels; i++) {
  86                struct ieee80211_channel *chan = &sband->channels[i];
  87                u32 target_power = 0;
  88                int j;
  89
  90                for (j = 0; j < n_chains; j++) {
  91                        u32 val;
  92
  93                        val = mt7915_eeprom_get_target_power(dev, chan, j);
  94                        target_power = max(target_power, val);
  95                }
  96
  97                chan->max_power = min_t(int, chan->max_reg_power,
  98                                        target_power / 2);
  99                chan->orig_mpwr = target_power / 2;
 100        }
 101}
 102
 103static void mt7915_init_txpower(struct mt7915_dev *dev)
 104{
 105        mt7915_init_txpower_band(dev, &dev->mphy.sband_2g.sband);
 106        mt7915_init_txpower_band(dev, &dev->mphy.sband_5g.sband);
 107
 108        mt7915_eeprom_init_sku(dev);
 109}
 110
 111static void mt7915_init_work(struct work_struct *work)
 112{
 113        struct mt7915_dev *dev = container_of(work, struct mt7915_dev,
 114                                 init_work);
 115
 116        mt7915_mcu_set_eeprom(dev);
 117        mt7915_mac_init(dev);
 118        mt7915_init_txpower(dev);
 119        mt7915_txbf_init(dev);
 120}
 121
 122static int mt7915_init_hardware(struct mt7915_dev *dev)
 123{
 124        int ret, idx;
 125
 126        mt76_wr(dev, MT_INT_SOURCE_CSR, ~0);
 127
 128        INIT_WORK(&dev->init_work, mt7915_init_work);
 129        spin_lock_init(&dev->token_lock);
 130        idr_init(&dev->token);
 131
 132        ret = mt7915_dma_init(dev);
 133        if (ret)
 134                return ret;
 135
 136        set_bit(MT76_STATE_INITIALIZED, &dev->mphy.state);
 137
 138        ret = mt7915_mcu_init(dev);
 139        if (ret)
 140                return ret;
 141
 142        ret = mt7915_eeprom_init(dev);
 143        if (ret < 0)
 144                return ret;
 145
 146        /* Beacon and mgmt frames should occupy wcid 0 */
 147        idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7915_WTBL_STA - 1);
 148        if (idx)
 149                return -ENOSPC;
 150
 151        dev->mt76.global_wcid.idx = idx;
 152        dev->mt76.global_wcid.hw_key_idx = -1;
 153        dev->mt76.global_wcid.tx_info |= MT_WCID_TX_INFO_SET;
 154        rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid);
 155
 156        return 0;
 157}
 158
 159#define CCK_RATE(_idx, _rate) {                                         \
 160        .bitrate = _rate,                                               \
 161        .flags = IEEE80211_RATE_SHORT_PREAMBLE,                         \
 162        .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx),                    \
 163        .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)),        \
 164}
 165
 166#define OFDM_RATE(_idx, _rate) {                                        \
 167        .bitrate = _rate,                                               \
 168        .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx),                   \
 169        .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx),             \
 170}
 171
 172static struct ieee80211_rate mt7915_rates[] = {
 173        CCK_RATE(0, 10),
 174        CCK_RATE(1, 20),
 175        CCK_RATE(2, 55),
 176        CCK_RATE(3, 110),
 177        OFDM_RATE(11, 60),
 178        OFDM_RATE(15, 90),
 179        OFDM_RATE(10, 120),
 180        OFDM_RATE(14, 180),
 181        OFDM_RATE(9,  240),
 182        OFDM_RATE(13, 360),
 183        OFDM_RATE(8,  480),
 184        OFDM_RATE(12, 540),
 185};
 186
 187static const struct ieee80211_iface_limit if_limits[] = {
 188        {
 189                .max = 1,
 190                .types = BIT(NL80211_IFTYPE_ADHOC)
 191        }, {
 192                .max = MT7915_MAX_INTERFACES,
 193                .types = BIT(NL80211_IFTYPE_AP) |
 194#ifdef CONFIG_MAC80211_MESH
 195                         BIT(NL80211_IFTYPE_MESH_POINT) |
 196#endif
 197                         BIT(NL80211_IFTYPE_STATION)
 198        }
 199};
 200
 201static const struct ieee80211_iface_combination if_comb[] = {
 202        {
 203                .limits = if_limits,
 204                .n_limits = ARRAY_SIZE(if_limits),
 205                .max_interfaces = 4,
 206                .num_different_channels = 1,
 207                .beacon_int_infra_match = true,
 208                .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
 209                                       BIT(NL80211_CHAN_WIDTH_20) |
 210                                       BIT(NL80211_CHAN_WIDTH_40) |
 211                                       BIT(NL80211_CHAN_WIDTH_80) |
 212                                       BIT(NL80211_CHAN_WIDTH_160) |
 213                                       BIT(NL80211_CHAN_WIDTH_80P80),
 214        }
 215};
 216
 217static void
 218mt7915_regd_notifier(struct wiphy *wiphy,
 219                     struct regulatory_request *request)
 220{
 221        struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 222        struct mt7915_dev *dev = mt7915_hw_dev(hw);
 223        struct mt76_phy *mphy = hw->priv;
 224        struct mt7915_phy *phy = mphy->priv;
 225        struct cfg80211_chan_def *chandef = &mphy->chandef;
 226
 227        dev->mt76.region = request->dfs_region;
 228
 229        if (!(chandef->chan->flags & IEEE80211_CHAN_RADAR))
 230                return;
 231
 232        mt7915_dfs_init_radar_detector(phy);
 233}
 234
 235static void
 236mt7915_init_wiphy(struct ieee80211_hw *hw)
 237{
 238        struct mt7915_phy *phy = mt7915_hw_phy(hw);
 239        struct wiphy *wiphy = hw->wiphy;
 240
 241        hw->queues = 4;
 242        hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
 243        hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
 244
 245        phy->slottime = 9;
 246
 247        hw->sta_data_size = sizeof(struct mt7915_sta);
 248        hw->vif_data_size = sizeof(struct mt7915_vif);
 249
 250        wiphy->iface_combinations = if_comb;
 251        wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
 252        wiphy->reg_notifier = mt7915_regd_notifier;
 253        wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
 254
 255        wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_VHT_IBSS);
 256
 257        ieee80211_hw_set(hw, HAS_RATE_CONTROL);
 258
 259        hw->max_tx_fragments = 4;
 260}
 261
 262void mt7915_set_stream_vht_txbf_caps(struct mt7915_phy *phy)
 263{
 264        int nss = hweight8(phy->chainmask);
 265        u32 *cap = &phy->mt76->sband_5g.sband.vht_cap.cap;
 266
 267        *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
 268                IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE |
 269                (3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
 270
 271        *cap &= ~(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK |
 272                  IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
 273                  IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE);
 274
 275        if (nss < 2)
 276                return;
 277
 278        *cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE |
 279                IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE |
 280                FIELD_PREP(IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_MASK,
 281                           nss - 1);
 282}
 283
 284static void
 285mt7915_set_stream_he_txbf_caps(struct ieee80211_sta_he_cap *he_cap,
 286                               int vif, int nss)
 287{
 288        struct ieee80211_he_cap_elem *elem = &he_cap->he_cap_elem;
 289        struct ieee80211_he_mcs_nss_supp *mcs = &he_cap->he_mcs_nss_supp;
 290        u8 c;
 291
 292#ifdef CONFIG_MAC80211_MESH
 293        if (vif == NL80211_IFTYPE_MESH_POINT)
 294                return;
 295#endif
 296
 297        elem->phy_cap_info[3] &= ~IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
 298        elem->phy_cap_info[4] &= ~IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
 299
 300        c = IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_UNDER_80MHZ_MASK |
 301            IEEE80211_HE_PHY_CAP5_BEAMFORMEE_NUM_SND_DIM_ABOVE_80MHZ_MASK;
 302        elem->phy_cap_info[5] &= ~c;
 303
 304        c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
 305            IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
 306        elem->phy_cap_info[6] &= ~c;
 307
 308        elem->phy_cap_info[7] &= ~IEEE80211_HE_PHY_CAP7_MAX_NC_MASK;
 309
 310        c = IEEE80211_HE_PHY_CAP2_NDP_4x_LTF_AND_3_2US |
 311            IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
 312            IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
 313        elem->phy_cap_info[2] |= c;
 314
 315        c = IEEE80211_HE_PHY_CAP4_SU_BEAMFORMEE |
 316            IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_UNDER_80MHZ_4 |
 317            IEEE80211_HE_PHY_CAP4_BEAMFORMEE_MAX_STS_ABOVE_80MHZ_4;
 318        elem->phy_cap_info[4] |= c;
 319
 320        /* do not support NG16 due to spec D4.0 changes subcarrier idx */
 321        c = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_42_SU |
 322            IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU;
 323
 324        if (vif == NL80211_IFTYPE_STATION)
 325                c |= IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
 326
 327        elem->phy_cap_info[6] |= c;
 328
 329        if (nss < 2)
 330                return;
 331
 332        if (vif != NL80211_IFTYPE_AP)
 333                return;
 334
 335        elem->phy_cap_info[3] |= IEEE80211_HE_PHY_CAP3_SU_BEAMFORMER;
 336        elem->phy_cap_info[4] |= IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
 337
 338        /* num_snd_dim */
 339        c = (nss - 1) | (max_t(int, mcs->tx_mcs_160, 1) << 3);
 340        elem->phy_cap_info[5] |= c;
 341
 342        c = IEEE80211_HE_PHY_CAP6_TRIG_SU_BEAMFORMER_FB |
 343            IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB;
 344        elem->phy_cap_info[6] |= c;
 345
 346        /* the maximum cap is 4 x 3, (Nr, Nc) = (3, 2) */
 347        elem->phy_cap_info[7] |= min_t(int, nss - 1, 2) << 3;
 348}
 349
 350static void
 351mt7915_gen_ppe_thresh(u8 *he_ppet)
 352{
 353        int ru, nss, max_nss = 1, max_ru = 3;
 354        u8 bit = 7, ru_bit_mask = 0x7;
 355        u8 ppet16_ppet8_ru3_ru0[] = {0x1c, 0xc7, 0x71};
 356
 357        he_ppet[0] = max_nss & IEEE80211_PPE_THRES_NSS_MASK;
 358        he_ppet[0] |= (ru_bit_mask <<
 359                       IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS) &
 360                        IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK;
 361
 362        for (nss = 0; nss <= max_nss; nss++) {
 363                for (ru = 0; ru < max_ru; ru++) {
 364                        u8 val;
 365                        int i;
 366
 367                        if (!(ru_bit_mask & BIT(ru)))
 368                                continue;
 369
 370                        val = (ppet16_ppet8_ru3_ru0[nss] >> (ru * 6)) &
 371                               0x3f;
 372                        val = ((val >> 3) & 0x7) | ((val & 0x7) << 3);
 373                        for (i = 5; i >= 0; i--) {
 374                                he_ppet[bit / 8] |=
 375                                        ((val >> i) & 0x1) << ((bit % 8));
 376                                bit++;
 377                        }
 378                }
 379        }
 380}
 381
 382static int
 383mt7915_init_he_caps(struct mt7915_phy *phy, enum nl80211_band band,
 384                    struct ieee80211_sband_iftype_data *data)
 385{
 386        int i, idx = 0;
 387        int nss = hweight8(phy->chainmask);
 388        u16 mcs_map = 0;
 389
 390        for (i = 0; i < 8; i++) {
 391                if (i < nss)
 392                        mcs_map |= (IEEE80211_HE_MCS_SUPPORT_0_11 << (i * 2));
 393                else
 394                        mcs_map |= (IEEE80211_HE_MCS_NOT_SUPPORTED << (i * 2));
 395        }
 396
 397        for (i = 0; i < NUM_NL80211_IFTYPES; i++) {
 398                struct ieee80211_sta_he_cap *he_cap = &data[idx].he_cap;
 399                struct ieee80211_he_cap_elem *he_cap_elem =
 400                                &he_cap->he_cap_elem;
 401                struct ieee80211_he_mcs_nss_supp *he_mcs =
 402                                &he_cap->he_mcs_nss_supp;
 403
 404                switch (i) {
 405                case NL80211_IFTYPE_STATION:
 406                case NL80211_IFTYPE_AP:
 407#ifdef CONFIG_MAC80211_MESH
 408                case NL80211_IFTYPE_MESH_POINT:
 409#endif
 410                        break;
 411                default:
 412                        continue;
 413                }
 414
 415                data[idx].types_mask = BIT(i);
 416                he_cap->has_he = true;
 417
 418                he_cap_elem->mac_cap_info[0] =
 419                        IEEE80211_HE_MAC_CAP0_HTC_HE;
 420                he_cap_elem->mac_cap_info[1] =
 421                        IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_0US |
 422                        IEEE80211_HE_MAC_CAP1_MULTI_TID_AGG_RX_QOS_1;
 423                he_cap_elem->mac_cap_info[2] =
 424                        IEEE80211_HE_MAC_CAP2_BSR;
 425                he_cap_elem->mac_cap_info[3] =
 426                        IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
 427                        IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
 428                he_cap_elem->mac_cap_info[4] =
 429                        IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
 430
 431                if (band == NL80211_BAND_2GHZ)
 432                        he_cap_elem->phy_cap_info[0] =
 433                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
 434                else if (band == NL80211_BAND_5GHZ)
 435                        he_cap_elem->phy_cap_info[0] =
 436                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
 437                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
 438                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
 439
 440                he_cap_elem->phy_cap_info[1] =
 441                        IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
 442                he_cap_elem->phy_cap_info[2] =
 443                        IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
 444                        IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;
 445
 446                /* TODO: OFDMA */
 447
 448                switch (i) {
 449                case NL80211_IFTYPE_AP:
 450                        he_cap_elem->mac_cap_info[0] |=
 451                                IEEE80211_HE_MAC_CAP0_TWT_RES;
 452                        he_cap_elem->mac_cap_info[4] |=
 453                                IEEE80211_HE_MAC_CAP4_BQR;
 454                        he_cap_elem->phy_cap_info[3] |=
 455                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
 456                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
 457                        he_cap_elem->phy_cap_info[6] |=
 458                                IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
 459                        he_cap_elem->phy_cap_info[9] |=
 460                                IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU;
 461                        break;
 462                case NL80211_IFTYPE_STATION:
 463                        he_cap_elem->mac_cap_info[0] |=
 464                                IEEE80211_HE_MAC_CAP0_TWT_REQ;
 465                        he_cap_elem->mac_cap_info[3] |=
 466                                IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED;
 467
 468                        if (band == NL80211_BAND_2GHZ)
 469                                he_cap_elem->phy_cap_info[0] |=
 470                                        IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;
 471                        else if (band == NL80211_BAND_5GHZ)
 472                                he_cap_elem->phy_cap_info[0] |=
 473                                        IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;
 474
 475                        he_cap_elem->phy_cap_info[1] |=
 476                                IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A;
 477                        he_cap_elem->phy_cap_info[8] |=
 478                                IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
 479                                IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
 480                                IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;
 481                        he_cap_elem->phy_cap_info[9] |=
 482                                IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
 483                        break;
 484#ifdef CONFIG_MAC80211_MESH
 485                case NL80211_IFTYPE_MESH_POINT:
 486                        break;
 487#endif
 488                }
 489
 490                he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);
 491                he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);
 492                he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map);
 493                he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map);
 494                he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map);
 495                he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map);
 496
 497                mt7915_set_stream_he_txbf_caps(he_cap, i, nss);
 498
 499                memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
 500                if (he_cap_elem->phy_cap_info[6] &
 501                    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
 502                        mt7915_gen_ppe_thresh(he_cap->ppe_thres);
 503                } else {
 504                        he_cap_elem->phy_cap_info[9] |=
 505                                IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US;
 506                }
 507                idx++;
 508        }
 509
 510        return idx;
 511}
 512
 513void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
 514{
 515        struct ieee80211_sband_iftype_data *data;
 516        struct ieee80211_supported_band *band;
 517        struct mt76_dev *mdev = &phy->dev->mt76;
 518        int n;
 519
 520        if (mdev->cap.has_2ghz) {
 521                data = phy->iftype[NL80211_BAND_2GHZ];
 522                n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
 523
 524                band = &phy->mt76->sband_2g.sband;
 525                band->iftype_data = data;
 526                band->n_iftype_data = n;
 527        }
 528
 529        if (mdev->cap.has_5ghz) {
 530                data = phy->iftype[NL80211_BAND_5GHZ];
 531                n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
 532
 533                band = &phy->mt76->sband_5g.sband;
 534                band->iftype_data = data;
 535                band->n_iftype_data = n;
 536        }
 537}
 538
 539static void
 540mt7915_cap_dbdc_enable(struct mt7915_dev *dev)
 541{
 542        dev->mphy.sband_5g.sband.vht_cap.cap &=
 543                        ~(IEEE80211_VHT_CAP_SHORT_GI_160 |
 544                          IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
 545
 546        if (dev->chainmask == 0xf)
 547                dev->mphy.antenna_mask = dev->chainmask >> 2;
 548        else
 549                dev->mphy.antenna_mask = dev->chainmask >> 1;
 550
 551        dev->phy.chainmask = dev->mphy.antenna_mask;
 552        dev->mphy.hw->wiphy->available_antennas_rx = dev->phy.chainmask;
 553        dev->mphy.hw->wiphy->available_antennas_tx = dev->phy.chainmask;
 554
 555        mt76_set_stream_caps(&dev->mphy, true);
 556        mt7915_set_stream_vht_txbf_caps(&dev->phy);
 557        mt7915_set_stream_he_caps(&dev->phy);
 558}
 559
 560static void
 561mt7915_cap_dbdc_disable(struct mt7915_dev *dev)
 562{
 563        dev->mphy.sband_5g.sband.vht_cap.cap |=
 564                        IEEE80211_VHT_CAP_SHORT_GI_160 |
 565                        IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
 566
 567        dev->mphy.antenna_mask = dev->chainmask;
 568        dev->phy.chainmask = dev->chainmask;
 569        dev->mphy.hw->wiphy->available_antennas_rx = dev->chainmask;
 570        dev->mphy.hw->wiphy->available_antennas_tx = dev->chainmask;
 571
 572        mt76_set_stream_caps(&dev->mphy, true);
 573        mt7915_set_stream_vht_txbf_caps(&dev->phy);
 574        mt7915_set_stream_he_caps(&dev->phy);
 575}
 576
 577int mt7915_register_ext_phy(struct mt7915_dev *dev)
 578{
 579        struct mt7915_phy *phy = mt7915_ext_phy(dev);
 580        struct mt76_phy *mphy;
 581        int ret;
 582        bool bound;
 583
 584        /* TODO: enble DBDC */
 585        bound = mt7915_l1_rr(dev, MT_HW_BOUND) & BIT(5);
 586        if (!bound)
 587                return -EINVAL;
 588
 589        if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
 590                return -EINVAL;
 591
 592        if (phy)
 593                return 0;
 594
 595        mt7915_cap_dbdc_enable(dev);
 596        mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7915_ops);
 597        if (!mphy)
 598                return -ENOMEM;
 599
 600        phy = mphy->priv;
 601        phy->dev = dev;
 602        phy->mt76 = mphy;
 603        phy->chainmask = dev->chainmask & ~dev->phy.chainmask;
 604        mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
 605        mt7915_init_wiphy(mphy->hw);
 606
 607        INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
 608
 609        /*
 610         * Make the secondary PHY MAC address local without overlapping with
 611         * the usual MAC address allocation scheme on multiple virtual interfaces
 612         */
 613        mphy->hw->wiphy->perm_addr[0] |= 2;
 614        mphy->hw->wiphy->perm_addr[0] ^= BIT(7);
 615
 616        /* The second interface does not get any packets unless it has a vif */
 617        ieee80211_hw_set(mphy->hw, WANT_MONITOR_VIF);
 618
 619        ret = mt76_register_phy(mphy);
 620        if (ret)
 621                ieee80211_free_hw(mphy->hw);
 622
 623        return ret;
 624}
 625
 626void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
 627{
 628        struct mt7915_phy *phy = mt7915_ext_phy(dev);
 629        struct mt76_phy *mphy = dev->mt76.phy2;
 630
 631        if (!phy)
 632                return;
 633
 634        mt7915_cap_dbdc_disable(dev);
 635        mt76_unregister_phy(mphy);
 636        ieee80211_free_hw(mphy->hw);
 637}
 638
 639int mt7915_register_device(struct mt7915_dev *dev)
 640{
 641        struct ieee80211_hw *hw = mt76_hw(dev);
 642        int ret;
 643
 644        dev->phy.dev = dev;
 645        dev->phy.mt76 = &dev->mt76.phy;
 646        dev->mt76.phy.priv = &dev->phy;
 647        INIT_DELAYED_WORK(&dev->phy.mac_work, mt7915_mac_work);
 648        INIT_LIST_HEAD(&dev->sta_poll_list);
 649        spin_lock_init(&dev->sta_poll_lock);
 650
 651        init_waitqueue_head(&dev->reset_wait);
 652        INIT_WORK(&dev->reset_work, mt7915_mac_reset_work);
 653
 654        ret = mt7915_init_hardware(dev);
 655        if (ret)
 656                return ret;
 657
 658        mt7915_init_wiphy(hw);
 659        dev->mphy.sband_2g.sband.ht_cap.cap |=
 660                        IEEE80211_HT_CAP_LDPC_CODING |
 661                        IEEE80211_HT_CAP_MAX_AMSDU;
 662        dev->mphy.sband_5g.sband.ht_cap.cap |=
 663                        IEEE80211_HT_CAP_LDPC_CODING |
 664                        IEEE80211_HT_CAP_MAX_AMSDU;
 665        dev->mphy.sband_5g.sband.vht_cap.cap |=
 666                        IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
 667                        IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
 668        mt7915_cap_dbdc_disable(dev);
 669        dev->phy.dfs_state = -1;
 670
 671        ret = mt76_register_device(&dev->mt76, true, mt7915_rates,
 672                                   ARRAY_SIZE(mt7915_rates));
 673        if (ret)
 674                return ret;
 675
 676        ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
 677
 678        return mt7915_init_debugfs(dev);
 679}
 680
 681void mt7915_unregister_device(struct mt7915_dev *dev)
 682{
 683        struct mt76_txwi_cache *txwi;
 684        int id;
 685
 686        mt7915_unregister_ext_phy(dev);
 687        mt76_unregister_device(&dev->mt76);
 688        mt7915_mcu_exit(dev);
 689        mt7915_dma_cleanup(dev);
 690
 691        spin_lock_bh(&dev->token_lock);
 692        idr_for_each_entry(&dev->token, txwi, id) {
 693                mt7915_txp_skb_unmap(&dev->mt76, txwi);
 694                if (txwi->skb)
 695                        dev_kfree_skb_any(txwi->skb);
 696                mt76_put_txwi(&dev->mt76, txwi);
 697        }
 698        spin_unlock_bh(&dev->token_lock);
 699        idr_destroy(&dev->token);
 700
 701        mt76_free_device(&dev->mt76);
 702}
 703