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 13 static void mt7615_phy_init(struct mt7615_dev *dev) 14 { 15 /* disable band 0 rf low power beacon mode */ 16 mt76_rmw(dev, MT_WF_PHY_WF2_RFCTRL0, MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN, 17 MT_WF_PHY_WF2_RFCTRL0_LPBCN_EN); 18 } 19 20 static void mt7615_mac_init(struct mt7615_dev *dev) 21 { 22 /* enable band 0 clk */ 23 mt76_rmw(dev, MT_CFG_CCR, 24 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN, 25 MT_CFG_CCR_MAC_D0_1X_GC_EN | MT_CFG_CCR_MAC_D0_2X_GC_EN); 26 27 mt76_rmw_field(dev, MT_TMAC_CTCR0, 28 MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f); 29 mt76_rmw_field(dev, MT_TMAC_CTCR0, 30 MT_TMAC_CTCR0_INS_DDLMT_DENSITY, 0x3); 31 mt76_rmw(dev, MT_TMAC_CTCR0, 32 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | 33 MT_TMAC_CTCR0_INS_DDLMT_EN, 34 MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN | 35 MT_TMAC_CTCR0_INS_DDLMT_EN); 36 37 mt7615_mcu_set_rts_thresh(dev, 0x92b); 38 39 mt76_rmw(dev, MT_AGG_SCR, MT_AGG_SCR_NLNAV_MID_PTEC_DIS, 40 MT_AGG_SCR_NLNAV_MID_PTEC_DIS); 41 42 mt7615_mcu_init_mac(dev); 43 44 mt76_wr(dev, MT_DMA_DCR0, MT_DMA_DCR0_RX_VEC_DROP | 45 FIELD_PREP(MT_DMA_DCR0_MAX_RX_LEN, 3072)); 46 47 mt76_wr(dev, MT_AGG_ARUCR, FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 7)); 48 mt76_wr(dev, MT_AGG_ARDCR, 49 FIELD_PREP(MT_AGG_ARxCR_LIMIT(0), 0) | 50 FIELD_PREP(MT_AGG_ARxCR_LIMIT(1), 51 max_t(int, 0, MT7615_RATE_RETRY - 2)) | 52 FIELD_PREP(MT_AGG_ARxCR_LIMIT(2), MT7615_RATE_RETRY - 1) | 53 FIELD_PREP(MT_AGG_ARxCR_LIMIT(3), MT7615_RATE_RETRY - 1) | 54 FIELD_PREP(MT_AGG_ARxCR_LIMIT(4), MT7615_RATE_RETRY - 1) | 55 FIELD_PREP(MT_AGG_ARxCR_LIMIT(5), MT7615_RATE_RETRY - 1) | 56 FIELD_PREP(MT_AGG_ARxCR_LIMIT(6), MT7615_RATE_RETRY - 1) | 57 FIELD_PREP(MT_AGG_ARxCR_LIMIT(7), MT7615_RATE_RETRY - 1)); 58 59 mt76_wr(dev, MT_AGG_ARCR, 60 (MT_AGG_ARCR_INIT_RATE1 | 61 FIELD_PREP(MT_AGG_ARCR_RTS_RATE_THR, 2) | 62 MT_AGG_ARCR_RATE_DOWN_RATIO_EN | 63 FIELD_PREP(MT_AGG_ARCR_RATE_DOWN_RATIO, 1) | 64 FIELD_PREP(MT_AGG_ARCR_RATE_UP_EXTRA_TH, 4))); 65 66 dev->mt76.global_wcid.idx = MT7615_WTBL_RESERVED; 67 dev->mt76.global_wcid.hw_key_idx = -1; 68 rcu_assign_pointer(dev->mt76.wcid[MT7615_WTBL_RESERVED], 69 &dev->mt76.global_wcid); 70 } 71 72 static int mt7615_init_hardware(struct mt7615_dev *dev) 73 { 74 int ret; 75 76 mt76_wr(dev, MT_INT_SOURCE_CSR, ~0); 77 78 spin_lock_init(&dev->token_lock); 79 idr_init(&dev->token); 80 81 ret = mt7615_eeprom_init(dev); 82 if (ret < 0) 83 return ret; 84 85 ret = mt7615_dma_init(dev); 86 if (ret) 87 return ret; 88 89 set_bit(MT76_STATE_INITIALIZED, &dev->mt76.state); 90 91 ret = mt7615_mcu_init(dev); 92 if (ret) 93 return ret; 94 95 mt7615_mcu_set_eeprom(dev); 96 mt7615_mac_init(dev); 97 mt7615_phy_init(dev); 98 mt7615_mcu_ctrl_pm_state(dev, 0); 99 mt7615_mcu_del_wtbl_all(dev); 100 101 return 0; 102 } 103 104 #define CCK_RATE(_idx, _rate) { \ 105 .bitrate = _rate, \ 106 .flags = IEEE80211_RATE_SHORT_PREAMBLE, \ 107 .hw_value = (MT_PHY_TYPE_CCK << 8) | (_idx), \ 108 .hw_value_short = (MT_PHY_TYPE_CCK << 8) | (4 + (_idx)), \ 109 } 110 111 #define OFDM_RATE(_idx, _rate) { \ 112 .bitrate = _rate, \ 113 .hw_value = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 114 .hw_value_short = (MT_PHY_TYPE_OFDM << 8) | (_idx), \ 115 } 116 117 static struct ieee80211_rate mt7615_rates[] = { 118 CCK_RATE(0, 10), 119 CCK_RATE(1, 20), 120 CCK_RATE(2, 55), 121 CCK_RATE(3, 110), 122 OFDM_RATE(11, 60), 123 OFDM_RATE(15, 90), 124 OFDM_RATE(10, 120), 125 OFDM_RATE(14, 180), 126 OFDM_RATE(9, 240), 127 OFDM_RATE(13, 360), 128 OFDM_RATE(8, 480), 129 OFDM_RATE(12, 540), 130 }; 131 132 static const struct ieee80211_iface_limit if_limits[] = { 133 { 134 .max = MT7615_MAX_INTERFACES, 135 .types = BIT(NL80211_IFTYPE_AP) | 136 BIT(NL80211_IFTYPE_STATION) 137 } 138 }; 139 140 static const struct ieee80211_iface_combination if_comb[] = { 141 { 142 .limits = if_limits, 143 .n_limits = ARRAY_SIZE(if_limits), 144 .max_interfaces = 4, 145 .num_different_channels = 1, 146 .beacon_int_infra_match = true, 147 } 148 }; 149 150 static int mt7615_init_debugfs(struct mt7615_dev *dev) 151 { 152 struct dentry *dir; 153 154 dir = mt76_register_debugfs(&dev->mt76); 155 if (!dir) 156 return -ENOMEM; 157 158 return 0; 159 } 160 161 int mt7615_register_device(struct mt7615_dev *dev) 162 { 163 struct ieee80211_hw *hw = mt76_hw(dev); 164 struct wiphy *wiphy = hw->wiphy; 165 int ret; 166 167 ret = mt7615_init_hardware(dev); 168 if (ret) 169 return ret; 170 171 INIT_DELAYED_WORK(&dev->mt76.mac_work, mt7615_mac_work); 172 173 hw->queues = 4; 174 hw->max_rates = 3; 175 hw->max_report_rates = 7; 176 hw->max_rate_tries = 11; 177 178 hw->sta_data_size = sizeof(struct mt7615_sta); 179 hw->vif_data_size = sizeof(struct mt7615_vif); 180 181 wiphy->iface_combinations = if_comb; 182 wiphy->n_iface_combinations = ARRAY_SIZE(if_comb); 183 184 ieee80211_hw_set(hw, SUPPORTS_REORDERING_BUFFER); 185 ieee80211_hw_set(hw, TX_STATUS_NO_AMPDU_LEN); 186 187 dev->mt76.sband_2g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; 188 dev->mt76.sband_5g.sband.ht_cap.cap |= IEEE80211_HT_CAP_LDPC_CODING; 189 dev->mt76.sband_5g.sband.vht_cap.cap |= 190 IEEE80211_VHT_CAP_SHORT_GI_160 | 191 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 192 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK | 193 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ; 194 dev->mt76.chainmask = 0x404; 195 dev->mt76.antenna_mask = 0xf; 196 197 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 198 BIT(NL80211_IFTYPE_AP); 199 200 ret = mt76_register_device(&dev->mt76, true, mt7615_rates, 201 ARRAY_SIZE(mt7615_rates)); 202 if (ret) 203 return ret; 204 205 hw->max_tx_fragments = MT_TXP_MAX_BUF_NUM; 206 207 return mt7615_init_debugfs(dev); 208 } 209 210 void mt7615_unregister_device(struct mt7615_dev *dev) 211 { 212 struct mt76_txwi_cache *txwi; 213 int id; 214 215 spin_lock_bh(&dev->token_lock); 216 idr_for_each_entry(&dev->token, txwi, id) { 217 mt7615_txp_skb_unmap(&dev->mt76, txwi); 218 if (txwi->skb) 219 dev_kfree_skb_any(txwi->skb); 220 mt76_put_txwi(&dev->mt76, txwi); 221 } 222 spin_unlock_bh(&dev->token_lock); 223 idr_destroy(&dev->token); 224 mt76_unregister_device(&dev->mt76); 225 mt7615_mcu_exit(dev); 226 mt7615_dma_cleanup(dev); 227 228 ieee80211_free_hw(mt76_hw(dev)); 229 } 230