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[3] =
 421                        IEEE80211_HE_MAC_CAP3_OMI_CONTROL |
 422                        IEEE80211_HE_MAC_CAP3_MAX_AMPDU_LEN_EXP_RESERVED;
 423                he_cap_elem->mac_cap_info[4] =
 424                        IEEE80211_HE_MAC_CAP4_AMDSU_IN_AMPDU;
 425
 426                if (band == NL80211_BAND_2GHZ)
 427                        he_cap_elem->phy_cap_info[0] =
 428                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_IN_2G;
 429                else if (band == NL80211_BAND_5GHZ)
 430                        he_cap_elem->phy_cap_info[0] =
 431                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_40MHZ_80MHZ_IN_5G |
 432                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G |
 433                                IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_80PLUS80_MHZ_IN_5G;
 434
 435                he_cap_elem->phy_cap_info[1] =
 436                        IEEE80211_HE_PHY_CAP1_LDPC_CODING_IN_PAYLOAD;
 437                he_cap_elem->phy_cap_info[2] =
 438                        IEEE80211_HE_PHY_CAP2_STBC_TX_UNDER_80MHZ |
 439                        IEEE80211_HE_PHY_CAP2_STBC_RX_UNDER_80MHZ;
 440
 441                switch (i) {
 442                case NL80211_IFTYPE_AP:
 443                        he_cap_elem->mac_cap_info[0] |=
 444                                IEEE80211_HE_MAC_CAP0_TWT_RES;
 445                        he_cap_elem->mac_cap_info[2] |=
 446                                IEEE80211_HE_MAC_CAP2_BSR;
 447                        he_cap_elem->mac_cap_info[4] |=
 448                                IEEE80211_HE_MAC_CAP4_BQR;
 449                        he_cap_elem->mac_cap_info[5] |=
 450                                IEEE80211_HE_MAC_CAP5_OM_CTRL_UL_MU_DATA_DIS_RX;
 451                        he_cap_elem->phy_cap_info[3] |=
 452                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
 453                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
 454                        he_cap_elem->phy_cap_info[6] |=
 455                                IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
 456                        break;
 457                case NL80211_IFTYPE_STATION:
 458                        he_cap_elem->mac_cap_info[0] |=
 459                                IEEE80211_HE_MAC_CAP0_TWT_REQ;
 460                        he_cap_elem->mac_cap_info[1] |=
 461                                IEEE80211_HE_MAC_CAP1_TF_MAC_PAD_DUR_16US;
 462
 463                        if (band == NL80211_BAND_2GHZ)
 464                                he_cap_elem->phy_cap_info[0] |=
 465                                        IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_2G;
 466                        else if (band == NL80211_BAND_5GHZ)
 467                                he_cap_elem->phy_cap_info[0] |=
 468                                        IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_RU_MAPPING_IN_5G;
 469
 470                        he_cap_elem->phy_cap_info[1] |=
 471                                IEEE80211_HE_PHY_CAP1_DEVICE_CLASS_A |
 472                                IEEE80211_HE_PHY_CAP1_HE_LTF_AND_GI_FOR_HE_PPDUS_0_8US;
 473                        he_cap_elem->phy_cap_info[3] |=
 474                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_QPSK |
 475                                IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_QPSK;
 476                        he_cap_elem->phy_cap_info[6] |=
 477                                IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
 478                                IEEE80211_HE_PHY_CAP6_PARTIAL_BW_EXT_RANGE |
 479                                IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT;
 480                        he_cap_elem->phy_cap_info[7] |=
 481                                IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
 482                                IEEE80211_HE_PHY_CAP7_HE_SU_MU_PPDU_4XLTF_AND_08_US_GI;
 483                        he_cap_elem->phy_cap_info[8] |=
 484                                IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
 485                                IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
 486                                IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU |
 487                                IEEE80211_HE_PHY_CAP8_DCM_MAX_RU_484;
 488                        he_cap_elem->phy_cap_info[9] |=
 489                                IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |
 490                                IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
 491                                IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
 492                                IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
 493                                IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
 494                                IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
 495                        break;
 496                }
 497
 498                he_mcs->rx_mcs_80 = cpu_to_le16(mcs_map);
 499                he_mcs->tx_mcs_80 = cpu_to_le16(mcs_map);
 500                he_mcs->rx_mcs_160 = cpu_to_le16(mcs_map);
 501                he_mcs->tx_mcs_160 = cpu_to_le16(mcs_map);
 502                he_mcs->rx_mcs_80p80 = cpu_to_le16(mcs_map);
 503                he_mcs->tx_mcs_80p80 = cpu_to_le16(mcs_map);
 504
 505                mt7915_set_stream_he_txbf_caps(he_cap, i, nss);
 506
 507                memset(he_cap->ppe_thres, 0, sizeof(he_cap->ppe_thres));
 508                if (he_cap_elem->phy_cap_info[6] &
 509                    IEEE80211_HE_PHY_CAP6_PPE_THRESHOLD_PRESENT) {
 510                        mt7915_gen_ppe_thresh(he_cap->ppe_thres);
 511                } else {
 512                        he_cap_elem->phy_cap_info[9] |=
 513                                IEEE80211_HE_PHY_CAP9_NOMIMAL_PKT_PADDING_16US;
 514                }
 515                idx++;
 516        }
 517
 518        return idx;
 519}
 520
 521void mt7915_set_stream_he_caps(struct mt7915_phy *phy)
 522{
 523        struct ieee80211_sband_iftype_data *data;
 524        struct ieee80211_supported_band *band;
 525        struct mt76_dev *mdev = &phy->dev->mt76;
 526        int n;
 527
 528        if (mdev->cap.has_2ghz) {
 529                data = phy->iftype[NL80211_BAND_2GHZ];
 530                n = mt7915_init_he_caps(phy, NL80211_BAND_2GHZ, data);
 531
 532                band = &phy->mt76->sband_2g.sband;
 533                band->iftype_data = data;
 534                band->n_iftype_data = n;
 535        }
 536
 537        if (mdev->cap.has_5ghz) {
 538                data = phy->iftype[NL80211_BAND_5GHZ];
 539                n = mt7915_init_he_caps(phy, NL80211_BAND_5GHZ, data);
 540
 541                band = &phy->mt76->sband_5g.sband;
 542                band->iftype_data = data;
 543                band->n_iftype_data = n;
 544        }
 545}
 546
 547static void
 548mt7915_cap_dbdc_enable(struct mt7915_dev *dev)
 549{
 550        dev->mphy.sband_5g.sband.vht_cap.cap &=
 551                        ~(IEEE80211_VHT_CAP_SHORT_GI_160 |
 552                          IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ);
 553
 554        if (dev->chainmask == 0xf)
 555                dev->mphy.antenna_mask = dev->chainmask >> 2;
 556        else
 557                dev->mphy.antenna_mask = dev->chainmask >> 1;
 558
 559        dev->phy.chainmask = dev->mphy.antenna_mask;
 560        dev->mphy.hw->wiphy->available_antennas_rx = dev->phy.chainmask;
 561        dev->mphy.hw->wiphy->available_antennas_tx = dev->phy.chainmask;
 562
 563        mt76_set_stream_caps(&dev->mphy, true);
 564        mt7915_set_stream_vht_txbf_caps(&dev->phy);
 565        mt7915_set_stream_he_caps(&dev->phy);
 566}
 567
 568static void
 569mt7915_cap_dbdc_disable(struct mt7915_dev *dev)
 570{
 571        dev->mphy.sband_5g.sband.vht_cap.cap |=
 572                        IEEE80211_VHT_CAP_SHORT_GI_160 |
 573                        IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
 574
 575        dev->mphy.antenna_mask = dev->chainmask;
 576        dev->phy.chainmask = dev->chainmask;
 577        dev->mphy.hw->wiphy->available_antennas_rx = dev->chainmask;
 578        dev->mphy.hw->wiphy->available_antennas_tx = dev->chainmask;
 579
 580        mt76_set_stream_caps(&dev->mphy, true);
 581        mt7915_set_stream_vht_txbf_caps(&dev->phy);
 582        mt7915_set_stream_he_caps(&dev->phy);
 583}
 584
 585int mt7915_register_ext_phy(struct mt7915_dev *dev)
 586{
 587        struct mt7915_phy *phy = mt7915_ext_phy(dev);
 588        struct mt76_phy *mphy;
 589        int ret;
 590        bool bound;
 591
 592        /* TODO: enble DBDC */
 593        bound = mt7915_l1_rr(dev, MT_HW_BOUND) & BIT(5);
 594        if (!bound)
 595                return -EINVAL;
 596
 597        if (test_bit(MT76_STATE_RUNNING, &dev->mphy.state))
 598                return -EINVAL;
 599
 600        if (phy)
 601                return 0;
 602
 603        mt7915_cap_dbdc_enable(dev);
 604        mphy = mt76_alloc_phy(&dev->mt76, sizeof(*phy), &mt7915_ops);
 605        if (!mphy)
 606                return -ENOMEM;
 607
 608        phy = mphy->priv;
 609        phy->dev = dev;
 610        phy->mt76 = mphy;
 611        phy->chainmask = dev->chainmask & ~dev->phy.chainmask;
 612        mphy->antenna_mask = BIT(hweight8(phy->chainmask)) - 1;
 613        mt7915_init_wiphy(mphy->hw);
 614
 615        INIT_DELAYED_WORK(&phy->mac_work, mt7915_mac_work);
 616
 617        /*
 618         * Make the secondary PHY MAC address local without overlapping with
 619         * the usual MAC address allocation scheme on multiple virtual interfaces
 620         */
 621        mphy->hw->wiphy->perm_addr[0] |= 2;
 622        mphy->hw->wiphy->perm_addr[0] ^= BIT(7);
 623
 624        /* The second interface does not get any packets unless it has a vif */
 625        ieee80211_hw_set(mphy->hw, WANT_MONITOR_VIF);
 626
 627        ret = mt76_register_phy(mphy);
 628        if (ret)
 629                ieee80211_free_hw(mphy->hw);
 630
 631        return ret;
 632}
 633
 634void mt7915_unregister_ext_phy(struct mt7915_dev *dev)
 635{
 636        struct mt7915_phy *phy = mt7915_ext_phy(dev);
 637        struct mt76_phy *mphy = dev->mt76.phy2;
 638
 639        if (!phy)
 640                return;
 641
 642        mt7915_cap_dbdc_disable(dev);
 643        mt76_unregister_phy(mphy);
 644        ieee80211_free_hw(mphy->hw);
 645}
 646
 647int mt7915_register_device(struct mt7915_dev *dev)
 648{
 649        struct ieee80211_hw *hw = mt76_hw(dev);
 650        int ret;
 651
 652        dev->phy.dev = dev;
 653        dev->phy.mt76 = &dev->mt76.phy;
 654        dev->mt76.phy.priv = &dev->phy;
 655        INIT_DELAYED_WORK(&dev->phy.mac_work, mt7915_mac_work);
 656        INIT_LIST_HEAD(&dev->sta_poll_list);
 657        spin_lock_init(&dev->sta_poll_lock);
 658
 659        init_waitqueue_head(&dev->reset_wait);
 660        INIT_WORK(&dev->reset_work, mt7915_mac_reset_work);
 661
 662        ret = mt7915_init_hardware(dev);
 663        if (ret)
 664                return ret;
 665
 666        mt7915_init_wiphy(hw);
 667        dev->mphy.sband_2g.sband.ht_cap.cap |=
 668                        IEEE80211_HT_CAP_LDPC_CODING |
 669                        IEEE80211_HT_CAP_MAX_AMSDU;
 670        dev->mphy.sband_5g.sband.ht_cap.cap |=
 671                        IEEE80211_HT_CAP_LDPC_CODING |
 672                        IEEE80211_HT_CAP_MAX_AMSDU;
 673        dev->mphy.sband_5g.sband.vht_cap.cap |=
 674                        IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991 |
 675                        IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK;
 676        mt7915_cap_dbdc_disable(dev);
 677        dev->phy.dfs_state = -1;
 678
 679        ret = mt76_register_device(&dev->mt76, true, mt7915_rates,
 680                                   ARRAY_SIZE(mt7915_rates));
 681        if (ret)
 682                return ret;
 683
 684        ieee80211_queue_work(mt76_hw(dev), &dev->init_work);
 685
 686        return mt7915_init_debugfs(dev);
 687}
 688
 689void mt7915_unregister_device(struct mt7915_dev *dev)
 690{
 691        struct mt76_txwi_cache *txwi;
 692        int id;
 693
 694        mt7915_unregister_ext_phy(dev);
 695        mt76_unregister_device(&dev->mt76);
 696        mt7915_mcu_exit(dev);
 697        mt7915_dma_cleanup(dev);
 698
 699        spin_lock_bh(&dev->token_lock);
 700        idr_for_each_entry(&dev->token, txwi, id) {
 701                mt7915_txp_skb_unmap(&dev->mt76, txwi);
 702                if (txwi->skb) {
 703                        struct ieee80211_hw *hw;
 704
 705                        hw = mt76_tx_status_get_hw(&dev->mt76, txwi->skb);
 706                        ieee80211_free_txskb(hw, txwi->skb);
 707                }
 708                mt76_put_txwi(&dev->mt76, txwi);
 709        }
 710        spin_unlock_bh(&dev->token_lock);
 711        idr_destroy(&dev->token);
 712
 713        mt76_free_device(&dev->mt76);
 714}
 715