0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "mt76x0.h"
0010 #include "eeprom.h"
0011 #include "mcu.h"
0012 #include "initvals.h"
0013 #include "initvals_init.h"
0014 #include "../mt76x02_phy.h"
0015
0016 static void
0017 mt76x0_set_wlan_state(struct mt76x02_dev *dev, u32 val, bool enable)
0018 {
0019 u32 mask = MT_CMB_CTRL_XTAL_RDY | MT_CMB_CTRL_PLL_LD;
0020
0021
0022
0023
0024
0025
0026
0027 if (enable)
0028 val |= (MT_WLAN_FUN_CTRL_WLAN_EN |
0029 MT_WLAN_FUN_CTRL_WLAN_CLK_EN);
0030 else
0031 val &= ~(MT_WLAN_FUN_CTRL_WLAN_EN);
0032
0033 mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
0034 udelay(20);
0035
0036
0037
0038
0039
0040 if (enable && !mt76_poll(dev, MT_CMB_CTRL, mask, mask, 2000))
0041 dev_err(dev->mt76.dev, "PLL and XTAL check failed\n");
0042 }
0043
0044 void mt76x0_chip_onoff(struct mt76x02_dev *dev, bool enable, bool reset)
0045 {
0046 u32 val;
0047
0048 val = mt76_rr(dev, MT_WLAN_FUN_CTRL);
0049
0050 if (reset) {
0051 val |= MT_WLAN_FUN_CTRL_GPIO_OUT_EN;
0052 val &= ~MT_WLAN_FUN_CTRL_FRC_WL_ANT_SEL;
0053
0054 if (val & MT_WLAN_FUN_CTRL_WLAN_EN) {
0055 val |= (MT_WLAN_FUN_CTRL_WLAN_RESET |
0056 MT_WLAN_FUN_CTRL_WLAN_RESET_RF);
0057 mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
0058 udelay(20);
0059
0060 val &= ~(MT_WLAN_FUN_CTRL_WLAN_RESET |
0061 MT_WLAN_FUN_CTRL_WLAN_RESET_RF);
0062 }
0063 }
0064
0065 mt76_wr(dev, MT_WLAN_FUN_CTRL, val);
0066 udelay(20);
0067
0068 mt76x0_set_wlan_state(dev, val, enable);
0069 }
0070 EXPORT_SYMBOL_GPL(mt76x0_chip_onoff);
0071
0072 static void mt76x0_reset_csr_bbp(struct mt76x02_dev *dev)
0073 {
0074 mt76_wr(dev, MT_MAC_SYS_CTRL,
0075 MT_MAC_SYS_CTRL_RESET_CSR |
0076 MT_MAC_SYS_CTRL_RESET_BBP);
0077 msleep(200);
0078 mt76_clear(dev, MT_MAC_SYS_CTRL,
0079 MT_MAC_SYS_CTRL_RESET_CSR |
0080 MT_MAC_SYS_CTRL_RESET_BBP);
0081 }
0082
0083 #define RANDOM_WRITE(dev, tab) \
0084 mt76_wr_rp(dev, MT_MCU_MEMMAP_WLAN, \
0085 tab, ARRAY_SIZE(tab))
0086
0087 static int mt76x0_init_bbp(struct mt76x02_dev *dev)
0088 {
0089 int ret, i;
0090
0091 ret = mt76x0_phy_wait_bbp_ready(dev);
0092 if (ret)
0093 return ret;
0094
0095 RANDOM_WRITE(dev, mt76x0_bbp_init_tab);
0096
0097 for (i = 0; i < ARRAY_SIZE(mt76x0_bbp_switch_tab); i++) {
0098 const struct mt76x0_bbp_switch_item *item = &mt76x0_bbp_switch_tab[i];
0099 const struct mt76_reg_pair *pair = &item->reg_pair;
0100
0101 if (((RF_G_BAND | RF_BW_20) & item->bw_band) == (RF_G_BAND | RF_BW_20))
0102 mt76_wr(dev, pair->reg, pair->value);
0103 }
0104
0105 RANDOM_WRITE(dev, mt76x0_dcoc_tab);
0106
0107 return 0;
0108 }
0109
0110 static void mt76x0_init_mac_registers(struct mt76x02_dev *dev)
0111 {
0112 RANDOM_WRITE(dev, common_mac_reg_table);
0113
0114
0115 RANDOM_WRITE(dev, mt76x0_mac_reg_table);
0116
0117
0118 mt76_clear(dev, MT_MAC_SYS_CTRL, 0x3);
0119
0120
0121 mt76_set(dev, MT_EXT_CCA_CFG, 0xf000);
0122
0123 mt76_clear(dev, MT_FCE_L2_STUFF, MT_FCE_L2_STUFF_WR_MPDU_LEN_EN);
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 mt76_rmw(dev, MT_WMM_CTRL, 0x3ff, 0x201);
0134 }
0135
0136 void mt76x0_mac_stop(struct mt76x02_dev *dev)
0137 {
0138 int i = 200, ok = 0;
0139
0140 mt76_clear(dev, MT_TXOP_CTRL_CFG, MT_TXOP_ED_CCA_EN);
0141
0142
0143 while (i-- && ((mt76_rr(dev, 0x0438) & 0xffffffff) ||
0144 (mt76_rr(dev, 0x0a30) & 0x000000ff) ||
0145 (mt76_rr(dev, 0x0a34) & 0x00ff00ff)))
0146 msleep(10);
0147
0148 if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_TX, 0, 1000))
0149 dev_warn(dev->mt76.dev, "Warning: MAC TX did not stop!\n");
0150
0151 mt76_clear(dev, MT_MAC_SYS_CTRL, MT_MAC_SYS_CTRL_ENABLE_RX |
0152 MT_MAC_SYS_CTRL_ENABLE_TX);
0153
0154
0155 for (i = 0; i < 200; i++) {
0156 if (!(mt76_rr(dev, MT_RXQ_STA) & 0x00ff0000) &&
0157 !mt76_rr(dev, 0x0a30) &&
0158 !mt76_rr(dev, 0x0a34)) {
0159 if (ok++ > 5)
0160 break;
0161 continue;
0162 }
0163 msleep(1);
0164 }
0165
0166 if (!mt76_poll(dev, MT_MAC_STATUS, MT_MAC_STATUS_RX, 0, 1000))
0167 dev_warn(dev->mt76.dev, "Warning: MAC RX did not stop!\n");
0168 }
0169 EXPORT_SYMBOL_GPL(mt76x0_mac_stop);
0170
0171 int mt76x0_init_hardware(struct mt76x02_dev *dev)
0172 {
0173 int ret, i, k;
0174
0175 if (!mt76x02_wait_for_wpdma(&dev->mt76, 1000))
0176 return -EIO;
0177
0178
0179 if (!mt76x02_wait_for_mac(&dev->mt76))
0180 return -ETIMEDOUT;
0181
0182 mt76x0_reset_csr_bbp(dev);
0183 ret = mt76x02_mcu_function_select(dev, Q_SELECT, 1);
0184 if (ret)
0185 return ret;
0186
0187 mt76x0_init_mac_registers(dev);
0188
0189 if (!mt76x02_wait_for_txrx_idle(&dev->mt76))
0190 return -EIO;
0191
0192 ret = mt76x0_init_bbp(dev);
0193 if (ret)
0194 return ret;
0195
0196 dev->mt76.rxfilter = mt76_rr(dev, MT_RX_FILTR_CFG);
0197
0198 for (i = 0; i < 16; i++)
0199 for (k = 0; k < 4; k++)
0200 mt76x02_mac_shared_key_setup(dev, i, k, NULL);
0201
0202 for (i = 0; i < 256; i++)
0203 mt76x02_mac_wcid_setup(dev, i, 0, NULL);
0204
0205 ret = mt76x0_eeprom_init(dev);
0206 if (ret)
0207 return ret;
0208
0209 mt76x0_phy_init(dev);
0210
0211 return 0;
0212 }
0213 EXPORT_SYMBOL_GPL(mt76x0_init_hardware);
0214
0215 static void
0216 mt76x0_init_txpower(struct mt76x02_dev *dev,
0217 struct ieee80211_supported_band *sband)
0218 {
0219 struct ieee80211_channel *chan;
0220 struct mt76_rate_power t;
0221 s8 tp;
0222 int i;
0223
0224 for (i = 0; i < sband->n_channels; i++) {
0225 chan = &sband->channels[i];
0226
0227 mt76x0_get_tx_power_per_rate(dev, chan, &t);
0228 mt76x0_get_power_info(dev, chan, &tp);
0229
0230 chan->orig_mpwr = (mt76x02_get_max_rate_power(&t) + tp) / 2;
0231 chan->max_power = min_t(int, chan->max_reg_power,
0232 chan->orig_mpwr);
0233 }
0234 }
0235
0236 int mt76x0_register_device(struct mt76x02_dev *dev)
0237 {
0238 int ret;
0239
0240 ret = mt76x02_init_device(dev);
0241 if (ret)
0242 return ret;
0243
0244 mt76x02_config_mac_addr_list(dev);
0245
0246 ret = mt76_register_device(&dev->mt76, true, mt76x02_rates,
0247 ARRAY_SIZE(mt76x02_rates));
0248 if (ret)
0249 return ret;
0250
0251 if (dev->mphy.cap.has_5ghz) {
0252 struct ieee80211_supported_band *sband;
0253
0254 sband = &dev->mphy.sband_5g.sband;
0255 sband->vht_cap.cap &= ~IEEE80211_VHT_CAP_RXLDPC;
0256 mt76x0_init_txpower(dev, sband);
0257 }
0258
0259 if (dev->mphy.cap.has_2ghz)
0260 mt76x0_init_txpower(dev, &dev->mphy.sband_2g.sband);
0261
0262 mt76x02_init_debugfs(dev);
0263
0264 return 0;
0265 }
0266 EXPORT_SYMBOL_GPL(mt76x0_register_device);