1 // SPDX-License-Identifier: ISC 2 /* Copyright (C) 2019 MediaTek Inc. 3 * 4 * Author: Roy Luo <royluo@google.com> 5 * Ryder Lee <ryder.lee@mediatek.com> 6 * Felix Fietkau <nbd@nbd.name> 7 */ 8 9 #include <linux/etherdevice.h> 10 #include "mt7615.h" 11 #include "mac.h" 12 #include "eeprom.h" 13 14 static void mt7615_phy_init(struct mt7615_dev *dev) 15 { 16 /* disable band 0 rf low power beacon mode */ 17 mt76_rmw(dev, MT_WF_PHY_WF2_RFCTRL0, MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN, 18 MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN); 19 } 20 21 static void mt7615_mac_init(struct mt7615_dev *dev) 22 { 23 /* enable band 0 clk */ 24 mt76_rmw(dev, MT_CFG_CCR, 25 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN, 26 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN); 27 28 mt76_rmw_field(dev, MT_TMAC_CTCR0, 29 MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f); 30 mt76_rmw_field(dev, MT_TMAC_CTCR0, 31 MT_TMAC_CTCR0_INS_DDLMT_DENSITY, 0x3); 32 mt76_rmw(dev, MT_TMAC_CTCR0, 33 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | 34 MT_TMAC_CTCR0_INS_DDLMT_EN, 35 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | 36 MT_TMAC_CTCR0_INS_DDLMT_EN); 37 38 mt7615_mcu_set_rts_thresh(dev, 0x92b); 39 40 mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS, 41 MT_AGG_SCR_NLNAV_MID_PTEC_DIS); 42 43 mt7615_mcu_init_mac(dev); 44 45 mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP | 46 FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072)); 47 48 mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7)); 49 mt76_wr(dev, MT_AGG_ARDCR, 50 FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) | 51 FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 52 max_t(int, 0, MT7615_RATE_RETRY - 2)) | 53 FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) | 54 FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) | 55 FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) | 56 FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), MT7615_RATE_RETRY - 1) | 57 FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), MT7615_RATE_RETRY - 1) | 58 FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1)); 59 60 mt76_wr(dev, MT_AGG_ARCR, 61 (MT_AGG_ARCR_INIT_RATE1 | 62 FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) | 63 MT_AGG_ARCR_RATE_DOWN_RATIO_EN | 64 FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) | 65 FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4))); 66 } 67 68 static int mt7615_init_hardware(struct mt7615_dev *dev) 69 { 70 int ret, idx; 71 72 mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); 73 74 spin_lock_init(&dev->token_lock); 75 idr_init(&dev->token); 76 77 ret = mt7615_eeprom_init(dev); 78 if (ret < 0) 79 return ret; 80 81 ret = mt7615_dma_init(dev); 82 if (ret) 83 return ret; 84 85 set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); 86 87 ret = mt7615_mcu_init(dev); 88 if (ret) 89 return ret; 90 91 mt7615_mcu_set_eeprom(dev); 92 mt7615_mac_init(dev); 93 mt7615_phy_init(dev); 94 mt7615_mcu_ctrl_pm_state(dev, 0); 95 mt7615_mcu_del_wtbl_all(dev); 96 97 /* Beacon and mgmt frames should occupy wcid 0 */ 98 idx = mt76_wcid_alloc(dev->mt76.wcid_mask, MT7615_WTBL_STA - 1); 99 if (idx) 100 return -ENOSPC; 101 102 dev->mt76.global_wcid.idx = idx; 103 dev->mt76.global_wcid.hw_key_idx = -1; 104 rcu_assign_pointer(dev->mt76.wcid[idx], &dev->mt76.global_wcid); 105 106 return 0; 107 } 108 109 #define CCK_RATE(_idx, _rate) { \ 110 .bitrate = _rate, \ 111 .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 112 .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 113 .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)), \ 114 } 115 116 #define OFDM_RATE(_idx, _rate) { \ 117 .bitrate = _rate, \ 118 .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 119 .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 120 } 121 122 static struct ieee80211_rate mt7615_rates[] = { 123 CCK_RATE(0, 10), 124 CCK_RATE(1, 20), 125 CCK_RATE(2, 55), 126 CCK_RATE(3, 110), 127 OFDM_RATE(11, 60), 128 OFDM_RATE(15, 90), 129 OFDM_RATE(10, 120), 130 OFDM_RATE(14, 180), 131 OFDM_RATE(9, 240), 132 OFDM_RATE(13, 360), 133 OFDM_RATE(8, 480), 134 OFDM_RATE(12, 540), 135 }; 136 137 static const struct ieee80211_iface_limit if_limits[] = { 138 { 139 .max = MT7615_MAX_INTERFACES, 140 .types = BIT(NL80211_IFTYPE_AP) | 141 #ifdef CONFIG_MAC80211_MESH 142 BIT(NL80211_IFTYPE_MESH_POINT) | 143 #endif 144 BIT(NL80211_IFTYPE_STATION) 145 } 146 }; 147 148 static const struct ieee80211_iface_combination if_comb[] = { 149 { 150 .limits = if_limits, 151 .n_limits = ARRAY_SIZE(if_limits), 152 .max_interfaces = 4, 153 .num_different_channels = 1, 154 .beacon_int_infra_match = true, 155 } 156 }; 157 158 static int mt7615_init_debugfs(struct mt7615_dev *dev) 159 { 160 struct dentry *dir; 161 162 dir = mt76_register_debugfs(&dev->mt76); 163 if (!dir) 164 return -ENOMEM; 165 166 return 0; 167 } 168 169 static void 170 mt7615_init_txpower(struct mt7615_dev *dev, 171 struct ieee80211_supported_band *sband) 172 { 173 int i, n_chains = hweight8(dev->mt76.antenna_mask), target_chains; 174 u8 *eep = (u8 *)dev->mt76.eeprom.data; 175 enum nl80211_band band = sband->band; 176 177 target_chains = mt7615_ext_pa_enabled(dev, band) ? 1 : n_chains; 178 for (i = 0; i < sband->n_channels; i++) { 179 struct ieee80211_channel *chan = &sband->channels[i]; 180 u8 target_power = 0; 181 int j; 182 183 for (j = 0; j < target_chains; j++) { 184 int index; 185 186 index = mt7615_eeprom_get_power_index(dev, chan, j); 187 target_power = max(target_power, eep[index]); 188 } 189 190 target_power = DIV_ROUND_UP(target_power, 2); 191 switch (n_chains) { 192 case 4: 193 target_power += 6; 194 break; 195 case 3: 196 target_power += 4; 197 break; 198 case 2: 199 target_power += 3; 200 break; 201 default: 202 break; 203 } 204 205 chan->max_power = min_t(int, chan->max_reg_power, 206 target_power); 207 chan->orig_mpwr = target_power; 208 } 209 } 210 211 int mt7615_register_device(struct mt7615_dev *dev) 212 { 213 struct ieee80211_hw *hw = mt76_hw(dev); 214 struct wiphy *wiphy = hw->wiphy; 215 int ret; 216 217 ret = mt7615_init_hardware(dev); 218 if (ret) 219 return ret; 220 221 INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7615_mac_work); 222 223 hw->queues = 4; 224 hw->max_rates = 3; 225 hw->max_report_rates = 7; 226 hw->max_rate_tries = 11; 227 228 hw->sta_data_size = sizeof(struct mt7615_sta); 229 hw->vif_data_size = sizeof(struct mt7615_vif); 230 231 wiphy->iface_combinations = if_comb; 232 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); 233 234 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); 235 ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN); 236 237 dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; 238 dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; 239 dev->mt76.sband_5g.sband.vht_cap.cap |= 240 IEEE80211_VHT_CAP_SHORT_GI_160 | 241 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 242 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | 243 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 244 dev->mt76.chainmask = 0x404; 245 dev->mt76.antenna_mask = 0xf; 246 247 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 248 #ifdef CONFIG_MAC80211_MESH 249 BIT(NL80211_IFTYPE_MESH_POINT) | 250 #endif 251 BIT(NL80211_IFTYPE_AP); 252 253 ret = mt76_register_device(&dev->mt76, true, mt7615_rates, 254 ARRAY_SIZE(mt7615_rates)); 255 if (ret) 256 return ret; 257 258 mt7615_init_txpower(dev, &dev->mt76.sband_2g.sband); 259 mt7615_init_txpower(dev, &dev->mt76.sband_5g.sband); 260 261 hw->max_tx_fragments = MT_TXP_MAX_BUF_NUM; 262 263 return mt7615_init_debugfs(dev); 264 } 265 266 void mt7615_unregister_device(struct mt7615_dev *dev) 267 { 268 struct mt76_txwi_cache *txwi; 269 int id; 270 271 mt76_unregister_device(&dev->mt76); 272 mt7615_mcu_exit(dev); 273 mt7615_dma_cleanup(dev); 274 275 spin_lock_bh(&dev->token_lock); 276 idr_for_each_entry(&dev->token, txwi, id) { 277 mt7615_txp_skb_unmap(&dev->mt76, txwi); 278 if (txwi->skb) 279 dev_kfree_skb_any(txwi->skb); 280 mt76_put_txwi(&dev->mt76, txwi); 281 } 282 spin_unlock_bh(&dev->token_lock); 283 idr_destroy(&dev->token); 284 285 mt76_free_device(&dev->mt76); 286 } 287