Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * (c) Copyright 2002-2010, Ralink Technology, Inc.
0004  * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
0005  * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
0006  * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
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     /* Note: we don't turn off WLAN_CLK because that makes the device
0022      *   not respond properly on the probe path.
0023      *   In case anyone (PSM?) wants to use this function we can
0024      *   bring the clock stuff back and fixup the probe path.
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     /* Note: vendor driver tries to disable/enable wlan here and retry
0037      *       but the code which does it is so buggy it must have never
0038      *       triggered, so don't bother.
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     /* Enable PBF and MAC clock SYS_CTRL[11:10] = 0x3 */
0115     RANDOM_WRITE(dev, mt76x0_mac_reg_table);
0116 
0117     /* Release BBP and MAC reset MAC_SYS_CTRL[1:0] = 0x0 */
0118     mt76_clear(dev, MT_MAC_SYS_CTRL, 0x3);
0119 
0120     /* Set 0x141C[15:12]=0xF */
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      * tx_ring 9 is for mgmt frame
0127      * tx_ring 8 is for in-band command frame.
0128      * WMM_RG0_TXQMA: this register setting is for FCE to
0129      *        define the rule of tx_ring 9
0130      * WMM_RG1_TXQMA: this register setting is for FCE to
0131      *        define the rule of tx_ring 8
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     /* Page count on TxQ */
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     /* Page count on RxQ */
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     /* Wait for ASIC ready after FW load. */
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);