11802d0beSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
210de7a8bSStanislaw Gruszka /*
310de7a8bSStanislaw Gruszka * (c) Copyright 2002-2010, Ralink Technology, Inc.
410de7a8bSStanislaw Gruszka * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
510de7a8bSStanislaw Gruszka * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
610de7a8bSStanislaw Gruszka * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
710de7a8bSStanislaw Gruszka */
810de7a8bSStanislaw Gruszka
966a34c66SLorenzo Bianconi #include <linux/kernel.h>
1066a34c66SLorenzo Bianconi #include <linux/etherdevice.h>
1166a34c66SLorenzo Bianconi
1210de7a8bSStanislaw Gruszka #include "mt76x0.h"
1310de7a8bSStanislaw Gruszka #include "mcu.h"
1410de7a8bSStanislaw Gruszka #include "eeprom.h"
1510de7a8bSStanislaw Gruszka #include "phy.h"
1610de7a8bSStanislaw Gruszka #include "initvals.h"
1710de7a8bSStanislaw Gruszka #include "initvals_phy.h"
181f4db1fdSLorenzo Bianconi #include "../mt76x02_phy.h"
1910de7a8bSStanislaw Gruszka
2010de7a8bSStanislaw Gruszka static int
mt76x0_rf_csr_wr(struct mt76x02_dev * dev,u32 offset,u8 value)21b2d871c0SLorenzo Bianconi mt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value)
2210de7a8bSStanislaw Gruszka {
2310de7a8bSStanislaw Gruszka int ret = 0;
2410de7a8bSStanislaw Gruszka u8 bank, reg;
2510de7a8bSStanislaw Gruszka
26011849e0SFelix Fietkau if (test_bit(MT76_REMOVED, &dev->mphy.state))
2710de7a8bSStanislaw Gruszka return -ENODEV;
2810de7a8bSStanislaw Gruszka
2910de7a8bSStanislaw Gruszka bank = MT_RF_BANK(offset);
3010de7a8bSStanislaw Gruszka reg = MT_RF_REG(offset);
3110de7a8bSStanislaw Gruszka
32a14054ceSLorenzo Bianconi if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8))
3310de7a8bSStanislaw Gruszka return -EINVAL;
3410de7a8bSStanislaw Gruszka
35b2d871c0SLorenzo Bianconi mutex_lock(&dev->phy_mutex);
3610de7a8bSStanislaw Gruszka
3710de7a8bSStanislaw Gruszka if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) {
3810de7a8bSStanislaw Gruszka ret = -ETIMEDOUT;
3910de7a8bSStanislaw Gruszka goto out;
4010de7a8bSStanislaw Gruszka }
4110de7a8bSStanislaw Gruszka
4210de7a8bSStanislaw Gruszka mt76_wr(dev, MT_RF_CSR_CFG,
4310de7a8bSStanislaw Gruszka FIELD_PREP(MT_RF_CSR_CFG_DATA, value) |
4410de7a8bSStanislaw Gruszka FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |
4510de7a8bSStanislaw Gruszka FIELD_PREP(MT_RF_CSR_CFG_REG_ID, reg) |
4610de7a8bSStanislaw Gruszka MT_RF_CSR_CFG_WR |
4710de7a8bSStanislaw Gruszka MT_RF_CSR_CFG_KICK);
48e0168dc6SLorenzo Bianconi
4910de7a8bSStanislaw Gruszka out:
50b2d871c0SLorenzo Bianconi mutex_unlock(&dev->phy_mutex);
5110de7a8bSStanislaw Gruszka
5210de7a8bSStanislaw Gruszka if (ret < 0)
5310de7a8bSStanislaw Gruszka dev_err(dev->mt76.dev, "Error: RF write %d:%d failed:%d!!\n",
5410de7a8bSStanislaw Gruszka bank, reg, ret);
5510de7a8bSStanislaw Gruszka
5610de7a8bSStanislaw Gruszka return ret;
5710de7a8bSStanislaw Gruszka }
5810de7a8bSStanislaw Gruszka
mt76x0_rf_csr_rr(struct mt76x02_dev * dev,u32 offset)59b2d871c0SLorenzo Bianconi static int mt76x0_rf_csr_rr(struct mt76x02_dev *dev, u32 offset)
6010de7a8bSStanislaw Gruszka {
6110de7a8bSStanislaw Gruszka int ret = -ETIMEDOUT;
6210de7a8bSStanislaw Gruszka u32 val;
6310de7a8bSStanislaw Gruszka u8 bank, reg;
6410de7a8bSStanislaw Gruszka
65011849e0SFelix Fietkau if (test_bit(MT76_REMOVED, &dev->mphy.state))
6610de7a8bSStanislaw Gruszka return -ENODEV;
6710de7a8bSStanislaw Gruszka
6810de7a8bSStanislaw Gruszka bank = MT_RF_BANK(offset);
6910de7a8bSStanislaw Gruszka reg = MT_RF_REG(offset);
7010de7a8bSStanislaw Gruszka
71a14054ceSLorenzo Bianconi if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8))
7210de7a8bSStanislaw Gruszka return -EINVAL;
7310de7a8bSStanislaw Gruszka
74b2d871c0SLorenzo Bianconi mutex_lock(&dev->phy_mutex);
7510de7a8bSStanislaw Gruszka
7610de7a8bSStanislaw Gruszka if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))
7710de7a8bSStanislaw Gruszka goto out;
7810de7a8bSStanislaw Gruszka
7910de7a8bSStanislaw Gruszka mt76_wr(dev, MT_RF_CSR_CFG,
8010de7a8bSStanislaw Gruszka FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |
8110de7a8bSStanislaw Gruszka FIELD_PREP(MT_RF_CSR_CFG_REG_ID, reg) |
8210de7a8bSStanislaw Gruszka MT_RF_CSR_CFG_KICK);
8310de7a8bSStanislaw Gruszka
8410de7a8bSStanislaw Gruszka if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))
8510de7a8bSStanislaw Gruszka goto out;
8610de7a8bSStanislaw Gruszka
8710de7a8bSStanislaw Gruszka val = mt76_rr(dev, MT_RF_CSR_CFG);
8810de7a8bSStanislaw Gruszka if (FIELD_GET(MT_RF_CSR_CFG_REG_ID, val) == reg &&
89e0168dc6SLorenzo Bianconi FIELD_GET(MT_RF_CSR_CFG_REG_BANK, val) == bank)
9010de7a8bSStanislaw Gruszka ret = FIELD_GET(MT_RF_CSR_CFG_DATA, val);
91e0168dc6SLorenzo Bianconi
9210de7a8bSStanislaw Gruszka out:
93b2d871c0SLorenzo Bianconi mutex_unlock(&dev->phy_mutex);
9410de7a8bSStanislaw Gruszka
9510de7a8bSStanislaw Gruszka if (ret < 0)
9610de7a8bSStanislaw Gruszka dev_err(dev->mt76.dev, "Error: RF read %d:%d failed:%d!!\n",
9710de7a8bSStanislaw Gruszka bank, reg, ret);
9810de7a8bSStanislaw Gruszka
9910de7a8bSStanislaw Gruszka return ret;
10010de7a8bSStanislaw Gruszka }
10110de7a8bSStanislaw Gruszka
10210de7a8bSStanislaw Gruszka static int
mt76x0_rf_wr(struct mt76x02_dev * dev,u32 offset,u8 val)1039c410782SLorenzo Bianconi mt76x0_rf_wr(struct mt76x02_dev *dev, u32 offset, u8 val)
10410de7a8bSStanislaw Gruszka {
10561c51a74SLorenzo Bianconi if (mt76_is_usb(&dev->mt76)) {
10610de7a8bSStanislaw Gruszka struct mt76_reg_pair pair = {
10710de7a8bSStanislaw Gruszka .reg = offset,
10810de7a8bSStanislaw Gruszka .value = val,
10910de7a8bSStanislaw Gruszka };
11010de7a8bSStanislaw Gruszka
11169cacac3SStanislaw Gruszka WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING,
112011849e0SFelix Fietkau &dev->mphy.state));
11317507157SLorenzo Bianconi return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1);
11410de7a8bSStanislaw Gruszka } else {
11510de7a8bSStanislaw Gruszka return mt76x0_rf_csr_wr(dev, offset, val);
11610de7a8bSStanislaw Gruszka }
11710de7a8bSStanislaw Gruszka }
11810de7a8bSStanislaw Gruszka
mt76x0_rf_rr(struct mt76x02_dev * dev,u32 offset)1199c410782SLorenzo Bianconi static int mt76x0_rf_rr(struct mt76x02_dev *dev, u32 offset)
12010de7a8bSStanislaw Gruszka {
12110de7a8bSStanislaw Gruszka int ret;
12210de7a8bSStanislaw Gruszka u32 val;
12310de7a8bSStanislaw Gruszka
12461c51a74SLorenzo Bianconi if (mt76_is_usb(&dev->mt76)) {
12510de7a8bSStanislaw Gruszka struct mt76_reg_pair pair = {
12610de7a8bSStanislaw Gruszka .reg = offset,
12710de7a8bSStanislaw Gruszka };
12810de7a8bSStanislaw Gruszka
12969cacac3SStanislaw Gruszka WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING,
130011849e0SFelix Fietkau &dev->mphy.state));
13117507157SLorenzo Bianconi ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1);
13210de7a8bSStanislaw Gruszka val = pair.value;
13310de7a8bSStanislaw Gruszka } else {
13410de7a8bSStanislaw Gruszka ret = val = mt76x0_rf_csr_rr(dev, offset);
13510de7a8bSStanislaw Gruszka }
13610de7a8bSStanislaw Gruszka
13710de7a8bSStanislaw Gruszka return (ret < 0) ? ret : val;
13810de7a8bSStanislaw Gruszka }
13910de7a8bSStanislaw Gruszka
14010de7a8bSStanislaw Gruszka static int
mt76x0_rf_rmw(struct mt76x02_dev * dev,u32 offset,u8 mask,u8 val)1419c410782SLorenzo Bianconi mt76x0_rf_rmw(struct mt76x02_dev *dev, u32 offset, u8 mask, u8 val)
14210de7a8bSStanislaw Gruszka {
14310de7a8bSStanislaw Gruszka int ret;
14410de7a8bSStanislaw Gruszka
1459c410782SLorenzo Bianconi ret = mt76x0_rf_rr(dev, offset);
14610de7a8bSStanislaw Gruszka if (ret < 0)
14710de7a8bSStanislaw Gruszka return ret;
14810de7a8bSStanislaw Gruszka
1499c410782SLorenzo Bianconi val |= ret & ~mask;
1509c410782SLorenzo Bianconi
1519c410782SLorenzo Bianconi ret = mt76x0_rf_wr(dev, offset, val);
1529c410782SLorenzo Bianconi return ret ? ret : val;
15310de7a8bSStanislaw Gruszka }
15410de7a8bSStanislaw Gruszka
15510de7a8bSStanislaw Gruszka static int
mt76x0_rf_set(struct mt76x02_dev * dev,u32 offset,u8 val)1569c410782SLorenzo Bianconi mt76x0_rf_set(struct mt76x02_dev *dev, u32 offset, u8 val)
15710de7a8bSStanislaw Gruszka {
1589c410782SLorenzo Bianconi return mt76x0_rf_rmw(dev, offset, 0, val);
15910de7a8bSStanislaw Gruszka }
16010de7a8bSStanislaw Gruszka
16110de7a8bSStanislaw Gruszka static int
mt76x0_rf_clear(struct mt76x02_dev * dev,u32 offset,u8 mask)162d3caa060SLorenzo Bianconi mt76x0_rf_clear(struct mt76x02_dev *dev, u32 offset, u8 mask)
16310de7a8bSStanislaw Gruszka {
1649c410782SLorenzo Bianconi return mt76x0_rf_rmw(dev, offset, mask, 0);
16510de7a8bSStanislaw Gruszka }
16610de7a8bSStanislaw Gruszka
167f2761e53SStanislaw Gruszka static void
mt76x0_phy_rf_csr_wr_rp(struct mt76x02_dev * dev,const struct mt76_reg_pair * data,int n)1689c410782SLorenzo Bianconi mt76x0_phy_rf_csr_wr_rp(struct mt76x02_dev *dev,
1699c410782SLorenzo Bianconi const struct mt76_reg_pair *data,
170f2761e53SStanislaw Gruszka int n)
171f2761e53SStanislaw Gruszka {
172f2761e53SStanislaw Gruszka while (n-- > 0) {
173f2761e53SStanislaw Gruszka mt76x0_rf_csr_wr(dev, data->reg, data->value);
174f2761e53SStanislaw Gruszka data++;
175f2761e53SStanislaw Gruszka }
176f2761e53SStanislaw Gruszka }
177f2761e53SStanislaw Gruszka
178f2761e53SStanislaw Gruszka #define RF_RANDOM_WRITE(dev, tab) do { \
17961c51a74SLorenzo Bianconi if (mt76_is_mmio(&dev->mt76)) \
1809c410782SLorenzo Bianconi mt76x0_phy_rf_csr_wr_rp(dev, tab, ARRAY_SIZE(tab)); \
181f2761e53SStanislaw Gruszka else \
182f2761e53SStanislaw Gruszka mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, tab, ARRAY_SIZE(tab));\
183f2761e53SStanislaw Gruszka } while (0)
18410de7a8bSStanislaw Gruszka
mt76x0_phy_wait_bbp_ready(struct mt76x02_dev * dev)1859c410782SLorenzo Bianconi int mt76x0_phy_wait_bbp_ready(struct mt76x02_dev *dev)
18610de7a8bSStanislaw Gruszka {
18710de7a8bSStanislaw Gruszka int i = 20;
18810de7a8bSStanislaw Gruszka u32 val;
18910de7a8bSStanislaw Gruszka
19010de7a8bSStanislaw Gruszka do {
19110de7a8bSStanislaw Gruszka val = mt76_rr(dev, MT_BBP(CORE, 0));
19210de7a8bSStanislaw Gruszka if (val && ~val)
19310de7a8bSStanislaw Gruszka break;
19410de7a8bSStanislaw Gruszka } while (--i);
19510de7a8bSStanislaw Gruszka
19610de7a8bSStanislaw Gruszka if (!i) {
19710de7a8bSStanislaw Gruszka dev_err(dev->mt76.dev, "Error: BBP is not ready\n");
19810de7a8bSStanislaw Gruszka return -EIO;
19910de7a8bSStanislaw Gruszka }
20010de7a8bSStanislaw Gruszka
201bed25905SStanislaw Gruszka dev_dbg(dev->mt76.dev, "BBP version %08x\n", val);
20210de7a8bSStanislaw Gruszka return 0;
20310de7a8bSStanislaw Gruszka }
20410de7a8bSStanislaw Gruszka
20510de7a8bSStanislaw Gruszka static void
mt76x0_phy_set_band(struct mt76x02_dev * dev,enum nl80211_band band)206b2d871c0SLorenzo Bianconi mt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band)
20710de7a8bSStanislaw Gruszka {
20810de7a8bSStanislaw Gruszka switch (band) {
20910de7a8bSStanislaw Gruszka case NL80211_BAND_2GHZ:
21010de7a8bSStanislaw Gruszka RF_RANDOM_WRITE(dev, mt76x0_rf_2g_channel_0_tab);
21110de7a8bSStanislaw Gruszka
2129c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(5, 0), 0x45);
2139c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(6, 0), 0x44);
21410de7a8bSStanislaw Gruszka
21510de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007);
21610de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002);
21710de7a8bSStanislaw Gruszka break;
21810de7a8bSStanislaw Gruszka case NL80211_BAND_5GHZ:
21910de7a8bSStanislaw Gruszka RF_RANDOM_WRITE(dev, mt76x0_rf_5g_channel_0_tab);
22010de7a8bSStanislaw Gruszka
2219c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(5, 0), 0x44);
2229c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(6, 0), 0x45);
22310de7a8bSStanislaw Gruszka
22410de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX_ALC_VGA3, 0x00000005);
22510de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102);
22610de7a8bSStanislaw Gruszka break;
22710de7a8bSStanislaw Gruszka default:
22810de7a8bSStanislaw Gruszka break;
22910de7a8bSStanislaw Gruszka }
23010de7a8bSStanislaw Gruszka }
23110de7a8bSStanislaw Gruszka
23210de7a8bSStanislaw Gruszka static void
mt76x0_phy_set_chan_rf_params(struct mt76x02_dev * dev,u8 channel,u16 rf_bw_band)233ff97c52aSRyder Lee mt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel,
234ff97c52aSRyder Lee u16 rf_bw_band)
23510de7a8bSStanislaw Gruszka {
236d3caa060SLorenzo Bianconi const struct mt76x0_freq_item *freq_item;
23710de7a8bSStanislaw Gruszka u16 rf_band = rf_bw_band & 0xff00;
23810de7a8bSStanislaw Gruszka u16 rf_bw = rf_bw_band & 0x00ff;
239443569a5SLorenzo Bianconi enum nl80211_band band;
240d3caa060SLorenzo Bianconi bool b_sdm = false;
24110de7a8bSStanislaw Gruszka u32 mac_reg;
24210de7a8bSStanislaw Gruszka int i;
24310de7a8bSStanislaw Gruszka
24410de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_sdm_channel); i++) {
24510de7a8bSStanislaw Gruszka if (channel == mt76x0_sdm_channel[i]) {
246d3caa060SLorenzo Bianconi b_sdm = true;
24710de7a8bSStanislaw Gruszka break;
24810de7a8bSStanislaw Gruszka }
24910de7a8bSStanislaw Gruszka }
25010de7a8bSStanislaw Gruszka
25110de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_frequency_plan); i++) {
25210de7a8bSStanislaw Gruszka if (channel == mt76x0_frequency_plan[i].channel) {
25310de7a8bSStanislaw Gruszka rf_band = mt76x0_frequency_plan[i].band;
25410de7a8bSStanislaw Gruszka
255d3caa060SLorenzo Bianconi if (b_sdm)
256ff97c52aSRyder Lee freq_item = &mt76x0_sdm_frequency_plan[i];
25710de7a8bSStanislaw Gruszka else
258ff97c52aSRyder Lee freq_item = &mt76x0_frequency_plan[i];
25910de7a8bSStanislaw Gruszka
2609c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 37), freq_item->pllR37);
2619c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 36), freq_item->pllR36);
2629c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 35), freq_item->pllR35);
2639c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 34), freq_item->pllR34);
2649c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 33), freq_item->pllR33);
26510de7a8bSStanislaw Gruszka
266d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 32), 0xe0,
267d3caa060SLorenzo Bianconi freq_item->pllR32_b7b5);
26810de7a8bSStanislaw Gruszka
26910de7a8bSStanislaw Gruszka /* R32<4:0> pll_den: (Denomina - 8) */
270d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 32), MT_RF_PLL_DEN_MASK,
271d3caa060SLorenzo Bianconi freq_item->pllR32_b4b0);
27210de7a8bSStanislaw Gruszka
27310de7a8bSStanislaw Gruszka /* R31<7:5> */
274d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 31), 0xe0,
275d3caa060SLorenzo Bianconi freq_item->pllR31_b7b5);
27610de7a8bSStanislaw Gruszka
27710de7a8bSStanislaw Gruszka /* R31<4:0> pll_k(Nominator) */
278d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 31), MT_RF_PLL_K_MASK,
279d3caa060SLorenzo Bianconi freq_item->pllR31_b4b0);
28010de7a8bSStanislaw Gruszka
28110de7a8bSStanislaw Gruszka /* R30<7> sdm_reset_n */
282d3caa060SLorenzo Bianconi if (b_sdm) {
283d3caa060SLorenzo Bianconi mt76x0_rf_clear(dev, MT_RF(0, 30),
284d3caa060SLorenzo Bianconi MT_RF_SDM_RESET_MASK);
285d3caa060SLorenzo Bianconi mt76x0_rf_set(dev, MT_RF(0, 30),
286d3caa060SLorenzo Bianconi MT_RF_SDM_RESET_MASK);
28710de7a8bSStanislaw Gruszka } else {
288d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 30),
289d3caa060SLorenzo Bianconi MT_RF_SDM_RESET_MASK,
290d3caa060SLorenzo Bianconi freq_item->pllR30_b7);
29110de7a8bSStanislaw Gruszka }
29210de7a8bSStanislaw Gruszka
29310de7a8bSStanislaw Gruszka /* R30<6:2> sdmmash_prbs,sin */
294d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 30),
295d3caa060SLorenzo Bianconi MT_RF_SDM_MASH_PRBS_MASK,
296d3caa060SLorenzo Bianconi freq_item->pllR30_b6b2);
29710de7a8bSStanislaw Gruszka
29810de7a8bSStanislaw Gruszka /* R30<1> sdm_bp */
299d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 30), MT_RF_SDM_BP_MASK,
300d3caa060SLorenzo Bianconi freq_item->pllR30_b1 << 1);
30110de7a8bSStanislaw Gruszka
30210de7a8bSStanislaw Gruszka /* R30<0> R29<7:0> (hex) pll_n */
303d3caa060SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 29),
304d3caa060SLorenzo Bianconi freq_item->pll_n & 0xff);
30510de7a8bSStanislaw Gruszka
306d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 30), 0x1,
307d3caa060SLorenzo Bianconi (freq_item->pll_n >> 8) & 0x1);
30810de7a8bSStanislaw Gruszka
30910de7a8bSStanislaw Gruszka /* R28<7:6> isi_iso */
310d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_ISI_ISO_MASK,
311d3caa060SLorenzo Bianconi freq_item->pllR28_b7b6);
31210de7a8bSStanislaw Gruszka
31310de7a8bSStanislaw Gruszka /* R28<5:4> pfd_dly */
314d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_PFD_DLY_MASK,
315d3caa060SLorenzo Bianconi freq_item->pllR28_b5b4);
31610de7a8bSStanislaw Gruszka
31710de7a8bSStanislaw Gruszka /* R28<3:2> clksel option */
318d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_CLK_SEL_MASK,
319d3caa060SLorenzo Bianconi freq_item->pllR28_b3b2);
32010de7a8bSStanislaw Gruszka
32110de7a8bSStanislaw Gruszka /* R28<1:0> R27<7:0> R26<7:0> (hex) sdm_k */
322d3caa060SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 26),
323d3caa060SLorenzo Bianconi freq_item->pll_sdm_k & 0xff);
324d3caa060SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 27),
325d3caa060SLorenzo Bianconi (freq_item->pll_sdm_k >> 8) & 0xff);
32610de7a8bSStanislaw Gruszka
327d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 28), 0x3,
328d3caa060SLorenzo Bianconi (freq_item->pll_sdm_k >> 16) & 0x3);
32910de7a8bSStanislaw Gruszka
33010de7a8bSStanislaw Gruszka /* R24<1:0> xo_div */
331d3caa060SLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 24), MT_RF_XO_DIV_MASK,
332d3caa060SLorenzo Bianconi freq_item->pllR24_b1b0);
33310de7a8bSStanislaw Gruszka
33410de7a8bSStanislaw Gruszka break;
33510de7a8bSStanislaw Gruszka }
33610de7a8bSStanislaw Gruszka }
33710de7a8bSStanislaw Gruszka
33810de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_rf_bw_switch_tab); i++) {
33910de7a8bSStanislaw Gruszka if (rf_bw == mt76x0_rf_bw_switch_tab[i].bw_band) {
3409c410782SLorenzo Bianconi mt76x0_rf_wr(dev,
3419c410782SLorenzo Bianconi mt76x0_rf_bw_switch_tab[i].rf_bank_reg,
34210de7a8bSStanislaw Gruszka mt76x0_rf_bw_switch_tab[i].value);
34310de7a8bSStanislaw Gruszka } else if ((rf_bw == (mt76x0_rf_bw_switch_tab[i].bw_band & 0xFF)) &&
34410de7a8bSStanislaw Gruszka (rf_band & mt76x0_rf_bw_switch_tab[i].bw_band)) {
3459c410782SLorenzo Bianconi mt76x0_rf_wr(dev,
3469c410782SLorenzo Bianconi mt76x0_rf_bw_switch_tab[i].rf_bank_reg,
34710de7a8bSStanislaw Gruszka mt76x0_rf_bw_switch_tab[i].value);
34810de7a8bSStanislaw Gruszka }
34910de7a8bSStanislaw Gruszka }
35010de7a8bSStanislaw Gruszka
35110de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_rf_band_switch_tab); i++) {
35210de7a8bSStanislaw Gruszka if (mt76x0_rf_band_switch_tab[i].bw_band & rf_band) {
3539c410782SLorenzo Bianconi mt76x0_rf_wr(dev,
3549c410782SLorenzo Bianconi mt76x0_rf_band_switch_tab[i].rf_bank_reg,
35510de7a8bSStanislaw Gruszka mt76x0_rf_band_switch_tab[i].value);
35610de7a8bSStanislaw Gruszka }
35710de7a8bSStanislaw Gruszka }
35810de7a8bSStanislaw Gruszka
359d3caa060SLorenzo Bianconi mt76_clear(dev, MT_RF_MISC, 0xc);
36010de7a8bSStanislaw Gruszka
361443569a5SLorenzo Bianconi band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
36226a9daa6SLorenzo Bianconi if (mt76x02_ext_pa_enabled(dev, band)) {
363ff97c52aSRyder Lee /* MT_RF_MISC (offset: 0x0518)
364ff97c52aSRyder Lee * [2]1'b1: enable external A band PA
365ff97c52aSRyder Lee * 1'b0: disable external A band PA
366ff97c52aSRyder Lee * [3]1'b1: enable external G band PA
367ff97c52aSRyder Lee * 1'b0: disable external G band PA
36810de7a8bSStanislaw Gruszka */
369d3caa060SLorenzo Bianconi if (rf_band & RF_A_BAND)
370d3caa060SLorenzo Bianconi mt76_set(dev, MT_RF_MISC, BIT(2));
371d3caa060SLorenzo Bianconi else
372d3caa060SLorenzo Bianconi mt76_set(dev, MT_RF_MISC, BIT(3));
37310de7a8bSStanislaw Gruszka
37410de7a8bSStanislaw Gruszka /* External PA */
37510de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_rf_ext_pa_tab); i++)
37610de7a8bSStanislaw Gruszka if (mt76x0_rf_ext_pa_tab[i].bw_band & rf_band)
3779c410782SLorenzo Bianconi mt76x0_rf_wr(dev,
3789c410782SLorenzo Bianconi mt76x0_rf_ext_pa_tab[i].rf_bank_reg,
37910de7a8bSStanislaw Gruszka mt76x0_rf_ext_pa_tab[i].value);
38010de7a8bSStanislaw Gruszka }
38110de7a8bSStanislaw Gruszka
38210de7a8bSStanislaw Gruszka if (rf_band & RF_G_BAND) {
38310de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x63707400);
38410de7a8bSStanislaw Gruszka /* Set Atten mode = 2 For G band, Disable Tx Inc dcoc. */
38510de7a8bSStanislaw Gruszka mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
38610de7a8bSStanislaw Gruszka mac_reg &= 0x896400FF;
38710de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
38810de7a8bSStanislaw Gruszka } else {
38910de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x686A7800);
390ff97c52aSRyder Lee /* Set Atten mode = 0
391ff97c52aSRyder Lee * For Ext A band, Disable Tx Inc dcoc Cal.
392ff97c52aSRyder Lee */
39310de7a8bSStanislaw Gruszka mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
39410de7a8bSStanislaw Gruszka mac_reg &= 0x890400FF;
39510de7a8bSStanislaw Gruszka mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
39610de7a8bSStanislaw Gruszka }
39710de7a8bSStanislaw Gruszka }
39810de7a8bSStanislaw Gruszka
39910de7a8bSStanislaw Gruszka static void
mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev * dev,u16 rf_bw_band)4007859c543SLorenzo Bianconi mt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u16 rf_bw_band)
40110de7a8bSStanislaw Gruszka {
40210de7a8bSStanislaw Gruszka int i;
40310de7a8bSStanislaw Gruszka
40410de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_bbp_switch_tab); i++) {
40510de7a8bSStanislaw Gruszka const struct mt76x0_bbp_switch_item *item = &mt76x0_bbp_switch_tab[i];
40610de7a8bSStanislaw Gruszka const struct mt76_reg_pair *pair = &item->reg_pair;
40710de7a8bSStanislaw Gruszka
40810de7a8bSStanislaw Gruszka if ((rf_bw_band & item->bw_band) != rf_bw_band)
40910de7a8bSStanislaw Gruszka continue;
41010de7a8bSStanislaw Gruszka
41110de7a8bSStanislaw Gruszka if (pair->reg == MT_BBP(AGC, 8)) {
41210de7a8bSStanislaw Gruszka u32 val = pair->value;
4132daa6758SLorenzo Bianconi u8 gain;
41410de7a8bSStanislaw Gruszka
4152daa6758SLorenzo Bianconi gain = FIELD_GET(MT_BBP_AGC_GAIN, val);
416b2d871c0SLorenzo Bianconi gain -= dev->cal.rx.lna_gain * 2;
41710de7a8bSStanislaw Gruszka val &= ~MT_BBP_AGC_GAIN;
41810de7a8bSStanislaw Gruszka val |= FIELD_PREP(MT_BBP_AGC_GAIN, gain);
41910de7a8bSStanislaw Gruszka mt76_wr(dev, pair->reg, val);
42010de7a8bSStanislaw Gruszka } else {
42110de7a8bSStanislaw Gruszka mt76_wr(dev, pair->reg, pair->value);
42210de7a8bSStanislaw Gruszka }
42310de7a8bSStanislaw Gruszka }
42410de7a8bSStanislaw Gruszka }
42510de7a8bSStanislaw Gruszka
mt76x0_phy_ant_select(struct mt76x02_dev * dev)4269c410782SLorenzo Bianconi static void mt76x0_phy_ant_select(struct mt76x02_dev *dev)
4274468e92cSLorenzo Bianconi {
428ef442b73SStanislaw Gruszka u16 ee_ant = mt76x02_eeprom_get(dev, MT_EE_ANTENNA);
42910ece008SFelix Fietkau u16 ee_cfg1 = mt76x02_eeprom_get(dev, MT_EE_CFG1_INIT);
430ef442b73SStanislaw Gruszka u16 nic_conf2 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2);
43110ece008SFelix Fietkau u32 wlan, coex3;
432ef442b73SStanislaw Gruszka bool ant_div;
4334468e92cSLorenzo Bianconi
434ef442b73SStanislaw Gruszka wlan = mt76_rr(dev, MT_WLAN_FUN_CTRL);
435ef442b73SStanislaw Gruszka coex3 = mt76_rr(dev, MT_COEXCFG3);
436ef442b73SStanislaw Gruszka
43710ece008SFelix Fietkau ee_ant &= ~(BIT(14) | BIT(12));
438ef442b73SStanislaw Gruszka wlan &= ~(BIT(6) | BIT(5));
439ef442b73SStanislaw Gruszka coex3 &= ~GENMASK(5, 2);
440ef442b73SStanislaw Gruszka
441ef442b73SStanislaw Gruszka if (ee_ant & MT_EE_ANTENNA_DUAL) {
442ef442b73SStanislaw Gruszka /* dual antenna mode */
443ef442b73SStanislaw Gruszka ant_div = !(nic_conf2 & MT_EE_NIC_CONF_2_ANT_OPT) &&
444ef442b73SStanislaw Gruszka (nic_conf2 & MT_EE_NIC_CONF_2_ANT_DIV);
445ef442b73SStanislaw Gruszka if (ant_div)
44610ece008SFelix Fietkau ee_ant |= BIT(12);
447ef442b73SStanislaw Gruszka else
448ef442b73SStanislaw Gruszka coex3 |= BIT(4);
449ef442b73SStanislaw Gruszka coex3 |= BIT(3);
45048dbce5cSLorenzo Bianconi if (dev->mphy.cap.has_2ghz)
451ef442b73SStanislaw Gruszka wlan |= BIT(6);
4524468e92cSLorenzo Bianconi } else {
453ef442b73SStanislaw Gruszka /* sigle antenna mode */
45448dbce5cSLorenzo Bianconi if (dev->mphy.cap.has_5ghz) {
455ef442b73SStanislaw Gruszka coex3 |= BIT(3) | BIT(4);
456ef442b73SStanislaw Gruszka } else {
457ef442b73SStanislaw Gruszka wlan |= BIT(6);
458ef442b73SStanislaw Gruszka coex3 |= BIT(1);
4594468e92cSLorenzo Bianconi }
460ef442b73SStanislaw Gruszka }
461ef442b73SStanislaw Gruszka
462ef442b73SStanislaw Gruszka if (is_mt7630(dev))
46310ece008SFelix Fietkau ee_ant |= BIT(14) | BIT(11);
464ef442b73SStanislaw Gruszka
465ef442b73SStanislaw Gruszka mt76_wr(dev, MT_WLAN_FUN_CTRL, wlan);
46610ece008SFelix Fietkau mt76_rmw(dev, MT_CMB_CTRL, GENMASK(15, 0), ee_ant);
46710ece008SFelix Fietkau mt76_rmw(dev, MT_CSR_EE_CFG1, GENMASK(15, 0), ee_cfg1);
4684468e92cSLorenzo Bianconi mt76_clear(dev, MT_COEXCFG0, BIT(2));
469ef442b73SStanislaw Gruszka mt76_wr(dev, MT_COEXCFG3, coex3);
4704468e92cSLorenzo Bianconi }
4714468e92cSLorenzo Bianconi
47210de7a8bSStanislaw Gruszka static void
mt76x0_phy_bbp_set_bw(struct mt76x02_dev * dev,enum nl80211_chan_width width)4739c410782SLorenzo Bianconi mt76x0_phy_bbp_set_bw(struct mt76x02_dev *dev, enum nl80211_chan_width width)
47410de7a8bSStanislaw Gruszka {
47510de7a8bSStanislaw Gruszka enum { BW_20 = 0, BW_40 = 1, BW_80 = 2, BW_10 = 4};
47610de7a8bSStanislaw Gruszka int bw;
47710de7a8bSStanislaw Gruszka
47810de7a8bSStanislaw Gruszka switch (width) {
47910de7a8bSStanislaw Gruszka default:
48010de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_20_NOHT:
48110de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_20:
48210de7a8bSStanislaw Gruszka bw = BW_20;
48310de7a8bSStanislaw Gruszka break;
48410de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_40:
48510de7a8bSStanislaw Gruszka bw = BW_40;
48610de7a8bSStanislaw Gruszka break;
48710de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_80:
48810de7a8bSStanislaw Gruszka bw = BW_80;
48910de7a8bSStanislaw Gruszka break;
49010de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_10:
49110de7a8bSStanislaw Gruszka bw = BW_10;
49210de7a8bSStanislaw Gruszka break;
49310de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_80P80:
49410de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_160:
49510de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_5:
49610de7a8bSStanislaw Gruszka /* TODO error */
49710de7a8bSStanislaw Gruszka return;
49810de7a8bSStanislaw Gruszka }
49910de7a8bSStanislaw Gruszka
5003d2d61b5SStanislaw Gruszka mt76x02_mcu_function_select(dev, BW_SETTING, bw);
50110de7a8bSStanislaw Gruszka }
50210de7a8bSStanislaw Gruszka
mt76x0_phy_tssi_dc_calibrate(struct mt76x02_dev * dev)5033548a9ddSLorenzo Bianconi static void mt76x0_phy_tssi_dc_calibrate(struct mt76x02_dev *dev)
5043548a9ddSLorenzo Bianconi {
50596747a51SFelix Fietkau struct ieee80211_channel *chan = dev->mphy.chandef.chan;
5063548a9ddSLorenzo Bianconi u32 val;
5073548a9ddSLorenzo Bianconi
5083548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_5GHZ)
5093548a9ddSLorenzo Bianconi mt76x0_rf_clear(dev, MT_RF(0, 67), 0xf);
5103548a9ddSLorenzo Bianconi
5113548a9ddSLorenzo Bianconi /* bypass ADDA control */
5123548a9ddSLorenzo Bianconi mt76_wr(dev, MT_RF_SETTING_0, 0x60002237);
5133548a9ddSLorenzo Bianconi mt76_wr(dev, MT_RF_BYPASS_0, 0xffffffff);
5143548a9ddSLorenzo Bianconi
5153548a9ddSLorenzo Bianconi /* bbp sw reset */
5163548a9ddSLorenzo Bianconi mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
5173548a9ddSLorenzo Bianconi usleep_range(500, 1000);
5183548a9ddSLorenzo Bianconi mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
5193548a9ddSLorenzo Bianconi
5203548a9ddSLorenzo Bianconi val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
5213548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(CORE, 34), val);
5223548a9ddSLorenzo Bianconi
5233548a9ddSLorenzo Bianconi /* enable TX with DAC0 input */
5243548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(TXBE, 6), BIT(31));
5253548a9ddSLorenzo Bianconi
5263548a9ddSLorenzo Bianconi mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200);
5273548a9ddSLorenzo Bianconi dev->cal.tssi_dc = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5283548a9ddSLorenzo Bianconi
5293548a9ddSLorenzo Bianconi /* stop bypass ADDA */
5303548a9ddSLorenzo Bianconi mt76_wr(dev, MT_RF_BYPASS_0, 0);
5313548a9ddSLorenzo Bianconi /* stop TX */
5323548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(TXBE, 6), 0);
5333548a9ddSLorenzo Bianconi /* bbp sw reset */
5343548a9ddSLorenzo Bianconi mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
5353548a9ddSLorenzo Bianconi usleep_range(500, 1000);
5363548a9ddSLorenzo Bianconi mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
5373548a9ddSLorenzo Bianconi
5383548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_5GHZ)
5393548a9ddSLorenzo Bianconi mt76x0_rf_rmw(dev, MT_RF(0, 67), 0xf, 0x4);
5403548a9ddSLorenzo Bianconi }
5413548a9ddSLorenzo Bianconi
5423548a9ddSLorenzo Bianconi static int
mt76x0_phy_tssi_adc_calibrate(struct mt76x02_dev * dev,s16 * ltssi,u8 * info)5433548a9ddSLorenzo Bianconi mt76x0_phy_tssi_adc_calibrate(struct mt76x02_dev *dev, s16 *ltssi,
5443548a9ddSLorenzo Bianconi u8 *info)
5453548a9ddSLorenzo Bianconi {
54696747a51SFelix Fietkau struct ieee80211_channel *chan = dev->mphy.chandef.chan;
5473548a9ddSLorenzo Bianconi u32 val;
5483548a9ddSLorenzo Bianconi
5493548a9ddSLorenzo Bianconi val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
5503548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(CORE, 34), val);
5513548a9ddSLorenzo Bianconi
5523548a9ddSLorenzo Bianconi if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
5533548a9ddSLorenzo Bianconi mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
5543548a9ddSLorenzo Bianconi return -ETIMEDOUT;
5553548a9ddSLorenzo Bianconi }
5563548a9ddSLorenzo Bianconi
5573548a9ddSLorenzo Bianconi *ltssi = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5583548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_5GHZ)
5593548a9ddSLorenzo Bianconi *ltssi += 128;
5603548a9ddSLorenzo Bianconi
5613548a9ddSLorenzo Bianconi /* set packet info#1 mode */
5623548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(CORE, 34), 0x80041);
5633548a9ddSLorenzo Bianconi info[0] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5643548a9ddSLorenzo Bianconi
5653548a9ddSLorenzo Bianconi /* set packet info#2 mode */
5663548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(CORE, 34), 0x80042);
5673548a9ddSLorenzo Bianconi info[1] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5683548a9ddSLorenzo Bianconi
5693548a9ddSLorenzo Bianconi /* set packet info#3 mode */
5703548a9ddSLorenzo Bianconi mt76_wr(dev, MT_BBP(CORE, 34), 0x80043);
5713548a9ddSLorenzo Bianconi info[2] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5723548a9ddSLorenzo Bianconi
5733548a9ddSLorenzo Bianconi return 0;
5743548a9ddSLorenzo Bianconi }
5753548a9ddSLorenzo Bianconi
mt76x0_phy_get_rf_pa_mode(struct mt76x02_dev * dev,int index,u8 tx_rate)5763548a9ddSLorenzo Bianconi static u8 mt76x0_phy_get_rf_pa_mode(struct mt76x02_dev *dev,
5773548a9ddSLorenzo Bianconi int index, u8 tx_rate)
5783548a9ddSLorenzo Bianconi {
5793548a9ddSLorenzo Bianconi u32 val, reg;
5803548a9ddSLorenzo Bianconi
5813548a9ddSLorenzo Bianconi reg = (index == 1) ? MT_RF_PA_MODE_CFG1 : MT_RF_PA_MODE_CFG0;
5823548a9ddSLorenzo Bianconi val = mt76_rr(dev, reg);
5833548a9ddSLorenzo Bianconi return (val & (3 << (tx_rate * 2))) >> (tx_rate * 2);
5843548a9ddSLorenzo Bianconi }
5853548a9ddSLorenzo Bianconi
5863548a9ddSLorenzo Bianconi static int
mt76x0_phy_get_target_power(struct mt76x02_dev * dev,u8 tx_mode,u8 * info,s8 * target_power,s8 * target_pa_power)5873548a9ddSLorenzo Bianconi mt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
5883548a9ddSLorenzo Bianconi u8 *info, s8 *target_power,
5893548a9ddSLorenzo Bianconi s8 *target_pa_power)
5903548a9ddSLorenzo Bianconi {
5913548a9ddSLorenzo Bianconi u8 tx_rate, cur_power;
5923548a9ddSLorenzo Bianconi
5933548a9ddSLorenzo Bianconi cur_power = mt76_rr(dev, MT_TX_ALC_CFG_0) & MT_TX_ALC_CFG_0_CH_INIT_0;
5943548a9ddSLorenzo Bianconi switch (tx_mode) {
5953548a9ddSLorenzo Bianconi case 0:
5963548a9ddSLorenzo Bianconi /* cck rates */
5973548a9ddSLorenzo Bianconi tx_rate = (info[0] & 0x60) >> 5;
598b376d963SFelix Fietkau *target_power = cur_power + dev->rate_power.cck[tx_rate];
5993548a9ddSLorenzo Bianconi *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, tx_rate);
6003548a9ddSLorenzo Bianconi break;
6013548a9ddSLorenzo Bianconi case 1: {
6023548a9ddSLorenzo Bianconi u8 index;
6033548a9ddSLorenzo Bianconi
6043548a9ddSLorenzo Bianconi /* ofdm rates */
6053548a9ddSLorenzo Bianconi tx_rate = (info[0] & 0xf0) >> 4;
6063548a9ddSLorenzo Bianconi switch (tx_rate) {
6073548a9ddSLorenzo Bianconi case 0xb:
6083548a9ddSLorenzo Bianconi index = 0;
6093548a9ddSLorenzo Bianconi break;
6103548a9ddSLorenzo Bianconi case 0xf:
6113548a9ddSLorenzo Bianconi index = 1;
6123548a9ddSLorenzo Bianconi break;
6133548a9ddSLorenzo Bianconi case 0xa:
6143548a9ddSLorenzo Bianconi index = 2;
6153548a9ddSLorenzo Bianconi break;
6163548a9ddSLorenzo Bianconi case 0xe:
6173548a9ddSLorenzo Bianconi index = 3;
6183548a9ddSLorenzo Bianconi break;
6193548a9ddSLorenzo Bianconi case 0x9:
6203548a9ddSLorenzo Bianconi index = 4;
6213548a9ddSLorenzo Bianconi break;
6223548a9ddSLorenzo Bianconi case 0xd:
6233548a9ddSLorenzo Bianconi index = 5;
6243548a9ddSLorenzo Bianconi break;
6253548a9ddSLorenzo Bianconi case 0x8:
6263548a9ddSLorenzo Bianconi index = 6;
6273548a9ddSLorenzo Bianconi break;
6283548a9ddSLorenzo Bianconi case 0xc:
6293548a9ddSLorenzo Bianconi index = 7;
6303548a9ddSLorenzo Bianconi break;
6313548a9ddSLorenzo Bianconi default:
6323548a9ddSLorenzo Bianconi return -EINVAL;
6333548a9ddSLorenzo Bianconi }
6343548a9ddSLorenzo Bianconi
635b376d963SFelix Fietkau *target_power = cur_power + dev->rate_power.ofdm[index];
6363548a9ddSLorenzo Bianconi *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, index + 4);
6373548a9ddSLorenzo Bianconi break;
6383548a9ddSLorenzo Bianconi }
6393548a9ddSLorenzo Bianconi case 4:
6403548a9ddSLorenzo Bianconi /* vht rates */
6413548a9ddSLorenzo Bianconi tx_rate = info[1] & 0xf;
6423548a9ddSLorenzo Bianconi if (tx_rate > 9)
6433548a9ddSLorenzo Bianconi return -EINVAL;
6443548a9ddSLorenzo Bianconi
645*6e1abc51SLorenzo Bianconi *target_power = cur_power;
646*6e1abc51SLorenzo Bianconi if (tx_rate > 7)
647*6e1abc51SLorenzo Bianconi *target_power += dev->rate_power.vht[tx_rate - 8];
648*6e1abc51SLorenzo Bianconi else
649*6e1abc51SLorenzo Bianconi *target_power += dev->rate_power.ht[tx_rate];
650*6e1abc51SLorenzo Bianconi
6513548a9ddSLorenzo Bianconi *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
6523548a9ddSLorenzo Bianconi break;
6533548a9ddSLorenzo Bianconi default:
6543548a9ddSLorenzo Bianconi /* ht rates */
6553548a9ddSLorenzo Bianconi tx_rate = info[1] & 0x7f;
6563548a9ddSLorenzo Bianconi if (tx_rate > 9)
6573548a9ddSLorenzo Bianconi return -EINVAL;
6583548a9ddSLorenzo Bianconi
659b376d963SFelix Fietkau *target_power = cur_power + dev->rate_power.ht[tx_rate];
6603548a9ddSLorenzo Bianconi *target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
6613548a9ddSLorenzo Bianconi break;
6623548a9ddSLorenzo Bianconi }
6633548a9ddSLorenzo Bianconi
6643548a9ddSLorenzo Bianconi return 0;
6653548a9ddSLorenzo Bianconi }
6663548a9ddSLorenzo Bianconi
mt76x0_phy_lin2db(u16 val)6673548a9ddSLorenzo Bianconi static s16 mt76x0_phy_lin2db(u16 val)
6683548a9ddSLorenzo Bianconi {
6693548a9ddSLorenzo Bianconi u32 mantissa = val << 4;
6703548a9ddSLorenzo Bianconi int ret, data;
6713548a9ddSLorenzo Bianconi s16 exp = -4;
6723548a9ddSLorenzo Bianconi
6733548a9ddSLorenzo Bianconi while (mantissa < BIT(15)) {
6743548a9ddSLorenzo Bianconi mantissa <<= 1;
6753548a9ddSLorenzo Bianconi if (--exp < -20)
6763548a9ddSLorenzo Bianconi return -10000;
6773548a9ddSLorenzo Bianconi }
6783548a9ddSLorenzo Bianconi while (mantissa > 0xffff) {
6793548a9ddSLorenzo Bianconi mantissa >>= 1;
6803548a9ddSLorenzo Bianconi if (++exp > 20)
6813548a9ddSLorenzo Bianconi return -10000;
6823548a9ddSLorenzo Bianconi }
6833548a9ddSLorenzo Bianconi
6843548a9ddSLorenzo Bianconi /* s(15,0) */
6853548a9ddSLorenzo Bianconi if (mantissa <= 47104)
6863548a9ddSLorenzo Bianconi data = mantissa + (mantissa >> 3) + (mantissa >> 4) - 38400;
6873548a9ddSLorenzo Bianconi else
6883548a9ddSLorenzo Bianconi data = mantissa - (mantissa >> 3) - (mantissa >> 6) - 23040;
6893548a9ddSLorenzo Bianconi data = max_t(int, 0, data);
6903548a9ddSLorenzo Bianconi
6913548a9ddSLorenzo Bianconi ret = ((15 + exp) << 15) + data;
6923548a9ddSLorenzo Bianconi ret = (ret << 2) + (ret << 1) + (ret >> 6) + (ret >> 7);
6933548a9ddSLorenzo Bianconi return ret >> 10;
6943548a9ddSLorenzo Bianconi }
6953548a9ddSLorenzo Bianconi
6963548a9ddSLorenzo Bianconi static int
mt76x0_phy_get_delta_power(struct mt76x02_dev * dev,u8 tx_mode,s8 target_power,s8 target_pa_power,s16 ltssi)6973548a9ddSLorenzo Bianconi mt76x0_phy_get_delta_power(struct mt76x02_dev *dev, u8 tx_mode,
6983548a9ddSLorenzo Bianconi s8 target_power, s8 target_pa_power,
6993548a9ddSLorenzo Bianconi s16 ltssi)
7003548a9ddSLorenzo Bianconi {
70196747a51SFelix Fietkau struct ieee80211_channel *chan = dev->mphy.chandef.chan;
7023548a9ddSLorenzo Bianconi int tssi_target = target_power << 12, tssi_slope;
7033548a9ddSLorenzo Bianconi int tssi_offset, tssi_db, ret;
7043548a9ddSLorenzo Bianconi u32 data;
7053548a9ddSLorenzo Bianconi u16 val;
7063548a9ddSLorenzo Bianconi
7073548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_5GHZ) {
7083548a9ddSLorenzo Bianconi u8 bound[7];
7093548a9ddSLorenzo Bianconi int i, err;
7103548a9ddSLorenzo Bianconi
7113548a9ddSLorenzo Bianconi err = mt76x02_eeprom_copy(dev, MT_EE_TSSI_BOUND1, bound,
7123548a9ddSLorenzo Bianconi sizeof(bound));
7133548a9ddSLorenzo Bianconi if (err < 0)
7143548a9ddSLorenzo Bianconi return err;
7153548a9ddSLorenzo Bianconi
7163548a9ddSLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(bound); i++) {
7173548a9ddSLorenzo Bianconi if (chan->hw_value <= bound[i] || !bound[i])
7183548a9ddSLorenzo Bianconi break;
7193548a9ddSLorenzo Bianconi }
7203548a9ddSLorenzo Bianconi val = mt76x02_eeprom_get(dev, MT_EE_TSSI_SLOPE_5G + i * 2);
7213548a9ddSLorenzo Bianconi
7223548a9ddSLorenzo Bianconi tssi_offset = val >> 8;
7233548a9ddSLorenzo Bianconi if ((tssi_offset >= 64 && tssi_offset <= 127) ||
7243548a9ddSLorenzo Bianconi (tssi_offset & BIT(7)))
7253548a9ddSLorenzo Bianconi tssi_offset -= BIT(8);
7263548a9ddSLorenzo Bianconi } else {
7273548a9ddSLorenzo Bianconi val = mt76x02_eeprom_get(dev, MT_EE_TSSI_SLOPE_2G);
7283548a9ddSLorenzo Bianconi
7293548a9ddSLorenzo Bianconi tssi_offset = val >> 8;
7303548a9ddSLorenzo Bianconi if (tssi_offset & BIT(7))
7313548a9ddSLorenzo Bianconi tssi_offset -= BIT(8);
7323548a9ddSLorenzo Bianconi }
7333548a9ddSLorenzo Bianconi tssi_slope = val & 0xff;
7343548a9ddSLorenzo Bianconi
7353548a9ddSLorenzo Bianconi switch (target_pa_power) {
7363548a9ddSLorenzo Bianconi case 1:
7373548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_2GHZ)
7383548a9ddSLorenzo Bianconi tssi_target += 29491; /* 3.6 * 8192 */
739aab662ccSGustavo A. R. Silva fallthrough;
7403548a9ddSLorenzo Bianconi case 0:
7413548a9ddSLorenzo Bianconi break;
7423548a9ddSLorenzo Bianconi default:
7433548a9ddSLorenzo Bianconi tssi_target += 4424; /* 0.54 * 8192 */
7443548a9ddSLorenzo Bianconi break;
7453548a9ddSLorenzo Bianconi }
7463548a9ddSLorenzo Bianconi
7473548a9ddSLorenzo Bianconi if (!tx_mode) {
7483548a9ddSLorenzo Bianconi data = mt76_rr(dev, MT_BBP(CORE, 1));
74961c51a74SLorenzo Bianconi if (is_mt7630(dev) && mt76_is_mmio(&dev->mt76)) {
7503548a9ddSLorenzo Bianconi int offset;
7513548a9ddSLorenzo Bianconi
7523548a9ddSLorenzo Bianconi /* 2.3 * 8192 or 1.5 * 8192 */
7533548a9ddSLorenzo Bianconi offset = (data & BIT(5)) ? 18841 : 12288;
7543548a9ddSLorenzo Bianconi tssi_target += offset;
7553548a9ddSLorenzo Bianconi } else if (data & BIT(5)) {
7563548a9ddSLorenzo Bianconi /* 0.8 * 8192 */
7573548a9ddSLorenzo Bianconi tssi_target += 6554;
7583548a9ddSLorenzo Bianconi }
7593548a9ddSLorenzo Bianconi }
7603548a9ddSLorenzo Bianconi
7613548a9ddSLorenzo Bianconi data = mt76_rr(dev, MT_BBP(TXBE, 4));
7623548a9ddSLorenzo Bianconi switch (data & 0x3) {
7633548a9ddSLorenzo Bianconi case 1:
7643548a9ddSLorenzo Bianconi tssi_target -= 49152; /* -6db * 8192 */
7653548a9ddSLorenzo Bianconi break;
7663548a9ddSLorenzo Bianconi case 2:
7673548a9ddSLorenzo Bianconi tssi_target -= 98304; /* -12db * 8192 */
7683548a9ddSLorenzo Bianconi break;
7693548a9ddSLorenzo Bianconi case 3:
7703548a9ddSLorenzo Bianconi tssi_target += 49152; /* 6db * 8192 */
7713548a9ddSLorenzo Bianconi break;
7723548a9ddSLorenzo Bianconi default:
7733548a9ddSLorenzo Bianconi break;
7743548a9ddSLorenzo Bianconi }
7753548a9ddSLorenzo Bianconi
7763548a9ddSLorenzo Bianconi tssi_db = mt76x0_phy_lin2db(ltssi - dev->cal.tssi_dc) * tssi_slope;
7773548a9ddSLorenzo Bianconi if (chan->band == NL80211_BAND_5GHZ) {
7783548a9ddSLorenzo Bianconi tssi_db += ((tssi_offset - 50) << 10); /* offset s4.3 */
7793548a9ddSLorenzo Bianconi tssi_target -= tssi_db;
7803548a9ddSLorenzo Bianconi if (ltssi > 254 && tssi_target > 0) {
7813548a9ddSLorenzo Bianconi /* upper saturate */
7823548a9ddSLorenzo Bianconi tssi_target = 0;
7833548a9ddSLorenzo Bianconi }
7843548a9ddSLorenzo Bianconi } else {
7853548a9ddSLorenzo Bianconi tssi_db += (tssi_offset << 9); /* offset s3.4 */
7863548a9ddSLorenzo Bianconi tssi_target -= tssi_db;
7873548a9ddSLorenzo Bianconi /* upper-lower saturate */
7883548a9ddSLorenzo Bianconi if ((ltssi > 126 && tssi_target > 0) ||
7893548a9ddSLorenzo Bianconi ((ltssi - dev->cal.tssi_dc) < 1 && tssi_target < 0)) {
7903548a9ddSLorenzo Bianconi tssi_target = 0;
7913548a9ddSLorenzo Bianconi }
7923548a9ddSLorenzo Bianconi }
7933548a9ddSLorenzo Bianconi
7943548a9ddSLorenzo Bianconi if ((dev->cal.tssi_target ^ tssi_target) < 0 &&
7953548a9ddSLorenzo Bianconi dev->cal.tssi_target > -4096 && dev->cal.tssi_target < 4096 &&
7963548a9ddSLorenzo Bianconi tssi_target > -4096 && tssi_target < 4096) {
7973548a9ddSLorenzo Bianconi if ((tssi_target < 0 &&
7983548a9ddSLorenzo Bianconi tssi_target + dev->cal.tssi_target > 0) ||
7993548a9ddSLorenzo Bianconi (tssi_target > 0 &&
8003548a9ddSLorenzo Bianconi tssi_target + dev->cal.tssi_target <= 0))
8013548a9ddSLorenzo Bianconi tssi_target = 0;
8023548a9ddSLorenzo Bianconi else
8033548a9ddSLorenzo Bianconi dev->cal.tssi_target = tssi_target;
8043548a9ddSLorenzo Bianconi } else {
8053548a9ddSLorenzo Bianconi dev->cal.tssi_target = tssi_target;
8063548a9ddSLorenzo Bianconi }
8073548a9ddSLorenzo Bianconi
8083548a9ddSLorenzo Bianconi /* make the compensate value to the nearest compensate code */
8093548a9ddSLorenzo Bianconi if (tssi_target > 0)
8103548a9ddSLorenzo Bianconi tssi_target += 2048;
8113548a9ddSLorenzo Bianconi else
8123548a9ddSLorenzo Bianconi tssi_target -= 2048;
8133548a9ddSLorenzo Bianconi tssi_target >>= 12;
8143548a9ddSLorenzo Bianconi
8153548a9ddSLorenzo Bianconi ret = mt76_get_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP);
8163548a9ddSLorenzo Bianconi if (ret & BIT(5))
8173548a9ddSLorenzo Bianconi ret -= BIT(6);
8183548a9ddSLorenzo Bianconi ret += tssi_target;
8193548a9ddSLorenzo Bianconi
8203548a9ddSLorenzo Bianconi ret = min_t(int, 31, ret);
8213548a9ddSLorenzo Bianconi return max_t(int, -32, ret);
8223548a9ddSLorenzo Bianconi }
8233548a9ddSLorenzo Bianconi
mt76x0_phy_tssi_calibrate(struct mt76x02_dev * dev)8243548a9ddSLorenzo Bianconi static void mt76x0_phy_tssi_calibrate(struct mt76x02_dev *dev)
8253548a9ddSLorenzo Bianconi {
8263548a9ddSLorenzo Bianconi s8 target_power, target_pa_power;
8273548a9ddSLorenzo Bianconi u8 tssi_info[3], tx_mode;
8283548a9ddSLorenzo Bianconi s16 ltssi;
8293548a9ddSLorenzo Bianconi s8 val;
8303548a9ddSLorenzo Bianconi
8313548a9ddSLorenzo Bianconi if (mt76x0_phy_tssi_adc_calibrate(dev, <ssi, tssi_info) < 0)
8323548a9ddSLorenzo Bianconi return;
8333548a9ddSLorenzo Bianconi
8343548a9ddSLorenzo Bianconi tx_mode = tssi_info[0] & 0x7;
8353548a9ddSLorenzo Bianconi if (mt76x0_phy_get_target_power(dev, tx_mode, tssi_info,
8363548a9ddSLorenzo Bianconi &target_power, &target_pa_power) < 0)
8373548a9ddSLorenzo Bianconi return;
8383548a9ddSLorenzo Bianconi
8393548a9ddSLorenzo Bianconi val = mt76x0_phy_get_delta_power(dev, tx_mode, target_power,
8403548a9ddSLorenzo Bianconi target_pa_power, ltssi);
8413548a9ddSLorenzo Bianconi mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, val);
8423548a9ddSLorenzo Bianconi }
8433548a9ddSLorenzo Bianconi
mt76x0_phy_set_txpower(struct mt76x02_dev * dev)844b2d871c0SLorenzo Bianconi void mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
84510de7a8bSStanislaw Gruszka {
846b376d963SFelix Fietkau struct mt76x02_rate_power *t = &dev->rate_power;
84705672636SLorenzo Bianconi s8 info;
84810de7a8bSStanislaw Gruszka
84996747a51SFelix Fietkau mt76x0_get_tx_power_per_rate(dev, dev->mphy.chandef.chan, t);
85096747a51SFelix Fietkau mt76x0_get_power_info(dev, dev->mphy.chandef.chan, &info);
8511f4db1fdSLorenzo Bianconi
85205672636SLorenzo Bianconi mt76x02_add_rate_power_offset(t, info);
8539e5f6dd7SFelix Fietkau mt76x02_limit_rate_power(t, dev->txpower_conf);
854beaaeb6bSFelix Fietkau dev->mphy.txpower_cur = mt76x02_get_max_rate_power(t);
85505672636SLorenzo Bianconi mt76x02_add_rate_power_offset(t, -info);
8561f4db1fdSLorenzo Bianconi
8570bee1ff6SLorenzo Bianconi dev->target_power = info;
85805672636SLorenzo Bianconi mt76x02_phy_set_txpower(dev, info, info);
85910de7a8bSStanislaw Gruszka }
86010de7a8bSStanislaw Gruszka
mt76x0_phy_calibrate(struct mt76x02_dev * dev,bool power_on)8619aec146dSLorenzo Bianconi void mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on)
8629aec146dSLorenzo Bianconi {
86396747a51SFelix Fietkau struct ieee80211_channel *chan = dev->mphy.chandef.chan;
864ad3f993aSStanislaw Gruszka int is_5ghz = (chan->band == NL80211_BAND_5GHZ) ? 1 : 0;
8659aec146dSLorenzo Bianconi u32 val, tx_alc, reg_val;
8669aec146dSLorenzo Bianconi
867a83150eaSStanislaw Gruszka if (is_mt7630(dev))
868a83150eaSStanislaw Gruszka return;
869a83150eaSStanislaw Gruszka
8709aec146dSLorenzo Bianconi if (power_on) {
8714ece1e0aSStanislaw Gruszka mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0);
8724ece1e0aSStanislaw Gruszka mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value);
8739aec146dSLorenzo Bianconi usleep_range(10, 20);
8743548a9ddSLorenzo Bianconi
8753548a9ddSLorenzo Bianconi if (mt76x0_tssi_enabled(dev)) {
8763548a9ddSLorenzo Bianconi mt76_wr(dev, MT_MAC_SYS_CTRL,
8773548a9ddSLorenzo Bianconi MT_MAC_SYS_CTRL_ENABLE_RX);
8783548a9ddSLorenzo Bianconi mt76x0_phy_tssi_dc_calibrate(dev);
8793548a9ddSLorenzo Bianconi mt76_wr(dev, MT_MAC_SYS_CTRL,
8803548a9ddSLorenzo Bianconi MT_MAC_SYS_CTRL_ENABLE_TX |
8813548a9ddSLorenzo Bianconi MT_MAC_SYS_CTRL_ENABLE_RX);
8823548a9ddSLorenzo Bianconi }
8839aec146dSLorenzo Bianconi }
8849aec146dSLorenzo Bianconi
8859aec146dSLorenzo Bianconi tx_alc = mt76_rr(dev, MT_TX_ALC_CFG_0);
8869aec146dSLorenzo Bianconi mt76_wr(dev, MT_TX_ALC_CFG_0, 0);
8879aec146dSLorenzo Bianconi usleep_range(500, 700);
8889aec146dSLorenzo Bianconi
8899aec146dSLorenzo Bianconi reg_val = mt76_rr(dev, MT_BBP(IBI, 9));
8909aec146dSLorenzo Bianconi mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e);
8919aec146dSLorenzo Bianconi
892ad3f993aSStanislaw Gruszka if (is_5ghz) {
8939aec146dSLorenzo Bianconi if (chan->hw_value < 100)
8949aec146dSLorenzo Bianconi val = 0x701;
8959aec146dSLorenzo Bianconi else if (chan->hw_value < 140)
8969aec146dSLorenzo Bianconi val = 0x801;
8979aec146dSLorenzo Bianconi else
8989aec146dSLorenzo Bianconi val = 0x901;
8999aec146dSLorenzo Bianconi } else {
9009aec146dSLorenzo Bianconi val = 0x600;
9019aec146dSLorenzo Bianconi }
9029aec146dSLorenzo Bianconi
9034ece1e0aSStanislaw Gruszka mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val);
9044ece1e0aSStanislaw Gruszka mt76x02_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz);
9059aec146dSLorenzo Bianconi usleep_range(15000, 20000);
9069aec146dSLorenzo Bianconi
9079aec146dSLorenzo Bianconi mt76_wr(dev, MT_BBP(IBI, 9), reg_val);
9089aec146dSLorenzo Bianconi mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc);
9094ece1e0aSStanislaw Gruszka mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1);
9109aec146dSLorenzo Bianconi }
9119aec146dSLorenzo Bianconi EXPORT_SYMBOL_GPL(mt76x0_phy_calibrate);
9129aec146dSLorenzo Bianconi
mt76x0_phy_set_channel(struct mt76x02_dev * dev,struct cfg80211_chan_def * chandef)9130c168e10SStanislaw Gruszka void mt76x0_phy_set_channel(struct mt76x02_dev *dev,
91410de7a8bSStanislaw Gruszka struct cfg80211_chan_def *chandef)
91510de7a8bSStanislaw Gruszka {
91610de7a8bSStanislaw Gruszka u32 ext_cca_chan[4] = {
91710de7a8bSStanislaw Gruszka [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
91810de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
91910de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
92010de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
92110de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
92210de7a8bSStanislaw Gruszka [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
92310de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
92410de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
92510de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
92610de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
92710de7a8bSStanislaw Gruszka [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
92810de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
92910de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
93010de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
93110de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
93210de7a8bSStanislaw Gruszka [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
93310de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
93410de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
93510de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
93610de7a8bSStanislaw Gruszka FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
93710de7a8bSStanislaw Gruszka };
938011849e0SFelix Fietkau bool scan = test_bit(MT76_SCANNING, &dev->mphy.state);
93910de7a8bSStanislaw Gruszka int ch_group_index, freq, freq1;
94010de7a8bSStanislaw Gruszka u8 channel;
94110de7a8bSStanislaw Gruszka u32 val;
94210de7a8bSStanislaw Gruszka u16 rf_bw_band;
94310de7a8bSStanislaw Gruszka
94410de7a8bSStanislaw Gruszka freq = chandef->chan->center_freq;
94510de7a8bSStanislaw Gruszka freq1 = chandef->center_freq1;
94610de7a8bSStanislaw Gruszka channel = chandef->chan->hw_value;
94710de7a8bSStanislaw Gruszka rf_bw_band = (channel <= 14) ? RF_G_BAND : RF_A_BAND;
94810de7a8bSStanislaw Gruszka
94910de7a8bSStanislaw Gruszka switch (chandef->width) {
95010de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_40:
95110de7a8bSStanislaw Gruszka if (freq1 > freq)
95210de7a8bSStanislaw Gruszka ch_group_index = 0;
95310de7a8bSStanislaw Gruszka else
95410de7a8bSStanislaw Gruszka ch_group_index = 1;
95510de7a8bSStanislaw Gruszka channel += 2 - ch_group_index * 4;
95610de7a8bSStanislaw Gruszka rf_bw_band |= RF_BW_40;
95710de7a8bSStanislaw Gruszka break;
95810de7a8bSStanislaw Gruszka case NL80211_CHAN_WIDTH_80:
95910de7a8bSStanislaw Gruszka ch_group_index = (freq - freq1 + 30) / 20;
96010de7a8bSStanislaw Gruszka if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
96110de7a8bSStanislaw Gruszka ch_group_index = 0;
96210de7a8bSStanislaw Gruszka channel += 6 - ch_group_index * 4;
96310de7a8bSStanislaw Gruszka rf_bw_band |= RF_BW_80;
96410de7a8bSStanislaw Gruszka break;
96510de7a8bSStanislaw Gruszka default:
96610de7a8bSStanislaw Gruszka ch_group_index = 0;
96710de7a8bSStanislaw Gruszka rf_bw_band |= RF_BW_20;
96810de7a8bSStanislaw Gruszka break;
96910de7a8bSStanislaw Gruszka }
97010de7a8bSStanislaw Gruszka
97161c51a74SLorenzo Bianconi if (mt76_is_usb(&dev->mt76)) {
9729c410782SLorenzo Bianconi mt76x0_phy_bbp_set_bw(dev, chandef->width);
973592ebc9cSLorenzo Bianconi } else {
974592ebc9cSLorenzo Bianconi if (chandef->width == NL80211_CHAN_WIDTH_80 ||
975592ebc9cSLorenzo Bianconi chandef->width == NL80211_CHAN_WIDTH_40)
976592ebc9cSLorenzo Bianconi val = 0x201;
977592ebc9cSLorenzo Bianconi else
978592ebc9cSLorenzo Bianconi val = 0x601;
979592ebc9cSLorenzo Bianconi mt76_wr(dev, MT_TX_SW_CFG0, val);
980592ebc9cSLorenzo Bianconi }
981032c08f4SLorenzo Bianconi mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
982370c6415SLorenzo Bianconi mt76x02_phy_set_band(dev, chandef->chan->band,
983370c6415SLorenzo Bianconi ch_group_index & 1);
98410de7a8bSStanislaw Gruszka
98510de7a8bSStanislaw Gruszka mt76_rmw(dev, MT_EXT_CCA_CFG,
98610de7a8bSStanislaw Gruszka (MT_EXT_CCA_CFG_CCA0 |
98710de7a8bSStanislaw Gruszka MT_EXT_CCA_CFG_CCA1 |
98810de7a8bSStanislaw Gruszka MT_EXT_CCA_CFG_CCA2 |
98910de7a8bSStanislaw Gruszka MT_EXT_CCA_CFG_CCA3 |
99010de7a8bSStanislaw Gruszka MT_EXT_CCA_CFG_CCA_MASK),
99110de7a8bSStanislaw Gruszka ext_cca_chan[ch_group_index]);
99210de7a8bSStanislaw Gruszka
99310de7a8bSStanislaw Gruszka mt76x0_phy_set_band(dev, chandef->chan->band);
99410de7a8bSStanislaw Gruszka mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band);
99510de7a8bSStanislaw Gruszka
99610de7a8bSStanislaw Gruszka /* set Japan Tx filter at channel 14 */
99710de7a8bSStanislaw Gruszka if (channel == 14)
998d3caa060SLorenzo Bianconi mt76_set(dev, MT_BBP(CORE, 1), 0x20);
99910de7a8bSStanislaw Gruszka else
1000d3caa060SLorenzo Bianconi mt76_clear(dev, MT_BBP(CORE, 1), 0x20);
100110de7a8bSStanislaw Gruszka
1002592ebc9cSLorenzo Bianconi mt76x0_read_rx_gain(dev);
10037859c543SLorenzo Bianconi mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band);
100410de7a8bSStanislaw Gruszka
1005592ebc9cSLorenzo Bianconi /* enable vco */
10069c410782SLorenzo Bianconi mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
10074606a26cSFelix Fietkau if (scan)
10080c168e10SStanislaw Gruszka return;
1009bbd10586SLorenzo Bianconi
1010f1b8ee35SStanislaw Gruszka mt76x02_init_agc_gain(dev);
1011bbd10586SLorenzo Bianconi mt76x0_phy_calibrate(dev, false);
10121f4db1fdSLorenzo Bianconi mt76x0_phy_set_txpower(dev);
101310de7a8bSStanislaw Gruszka
1014bbd10586SLorenzo Bianconi ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
1015bbd10586SLorenzo Bianconi MT_CALIBRATE_INTERVAL);
101610de7a8bSStanislaw Gruszka }
101710de7a8bSStanislaw Gruszka
mt76x0_phy_temp_sensor(struct mt76x02_dev * dev)10189c410782SLorenzo Bianconi static void mt76x0_phy_temp_sensor(struct mt76x02_dev *dev)
101910de7a8bSStanislaw Gruszka {
102010de7a8bSStanislaw Gruszka u8 rf_b7_73, rf_b0_66, rf_b0_67;
102166a34c66SLorenzo Bianconi s8 val;
102210de7a8bSStanislaw Gruszka
10239c410782SLorenzo Bianconi rf_b7_73 = mt76x0_rf_rr(dev, MT_RF(7, 73));
10249c410782SLorenzo Bianconi rf_b0_66 = mt76x0_rf_rr(dev, MT_RF(0, 66));
10259c410782SLorenzo Bianconi rf_b0_67 = mt76x0_rf_rr(dev, MT_RF(0, 67));
102610de7a8bSStanislaw Gruszka
10279c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(7, 73), 0x02);
10289c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 66), 0x23);
10299c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 67), 0x01);
103010de7a8bSStanislaw Gruszka
103110de7a8bSStanislaw Gruszka mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055);
10320464cbfcSLorenzo Bianconi if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
103366a34c66SLorenzo Bianconi mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
103410de7a8bSStanislaw Gruszka goto done;
103510de7a8bSStanislaw Gruszka }
103610de7a8bSStanislaw Gruszka
103766a34c66SLorenzo Bianconi val = mt76_rr(dev, MT_BBP(CORE, 35));
103866a34c66SLorenzo Bianconi val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25;
103910de7a8bSStanislaw Gruszka
104066a34c66SLorenzo Bianconi if (abs(val - dev->cal.temp_vco) > 20) {
104166a34c66SLorenzo Bianconi mt76x02_mcu_calibrate(dev, MCU_CAL_VCO,
104296747a51SFelix Fietkau dev->mphy.chandef.chan->hw_value);
104366a34c66SLorenzo Bianconi dev->cal.temp_vco = val;
104466a34c66SLorenzo Bianconi }
104566a34c66SLorenzo Bianconi if (abs(val - dev->cal.temp) > 30) {
104666a34c66SLorenzo Bianconi mt76x0_phy_calibrate(dev, false);
104766a34c66SLorenzo Bianconi dev->cal.temp = val;
104866a34c66SLorenzo Bianconi }
104910de7a8bSStanislaw Gruszka
105010de7a8bSStanislaw Gruszka done:
10519c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(7, 73), rf_b7_73);
10529c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 66), rf_b0_66);
10539c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 67), rf_b0_67);
105410de7a8bSStanislaw Gruszka }
105510de7a8bSStanislaw Gruszka
mt76x0_phy_set_gain_val(struct mt76x02_dev * dev)10564636a254SLorenzo Bianconi static void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev)
105710de7a8bSStanislaw Gruszka {
10584636a254SLorenzo Bianconi u8 gain = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
105910de7a8bSStanislaw Gruszka
1060b983a5b9SStanislaw Gruszka mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, gain);
1061801ccc8aSLorenzo Bianconi
106296747a51SFelix Fietkau if ((dev->mphy.chandef.chan->flags & IEEE80211_CHAN_RADAR) &&
1063801ccc8aSLorenzo Bianconi !is_mt7630(dev))
1064801ccc8aSLorenzo Bianconi mt76x02_phy_dfs_adjust_agc(dev);
10654636a254SLorenzo Bianconi }
106610de7a8bSStanislaw Gruszka
10674636a254SLorenzo Bianconi static void
mt76x0_phy_update_channel_gain(struct mt76x02_dev * dev)10684636a254SLorenzo Bianconi mt76x0_phy_update_channel_gain(struct mt76x02_dev *dev)
10694636a254SLorenzo Bianconi {
10704636a254SLorenzo Bianconi bool gain_change;
10714636a254SLorenzo Bianconi u8 gain_delta;
10724636a254SLorenzo Bianconi int low_gain;
10734636a254SLorenzo Bianconi
10748af63fedSFelix Fietkau dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, false);
1075ef13edc0SFelix Fietkau if (!dev->cal.avg_rssi_all)
1076ef13edc0SFelix Fietkau dev->cal.avg_rssi_all = -75;
10774636a254SLorenzo Bianconi
10784636a254SLorenzo Bianconi low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
10794636a254SLorenzo Bianconi (dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev));
10804636a254SLorenzo Bianconi
10814784a3ccSStanislaw Gruszka gain_change = dev->cal.low_gain < 0 ||
10824784a3ccSStanislaw Gruszka (dev->cal.low_gain & 2) ^ (low_gain & 2);
10834636a254SLorenzo Bianconi dev->cal.low_gain = low_gain;
10844636a254SLorenzo Bianconi
10854636a254SLorenzo Bianconi if (!gain_change) {
10864636a254SLorenzo Bianconi if (mt76x02_phy_adjust_vga_gain(dev))
10874636a254SLorenzo Bianconi mt76x0_phy_set_gain_val(dev);
10884636a254SLorenzo Bianconi return;
10894636a254SLorenzo Bianconi }
10904636a254SLorenzo Bianconi
10914636a254SLorenzo Bianconi dev->cal.agc_gain_adjust = (low_gain == 2) ? 0 : 10;
10924636a254SLorenzo Bianconi gain_delta = (low_gain == 2) ? 10 : 0;
10934636a254SLorenzo Bianconi
10944636a254SLorenzo Bianconi dev->cal.agc_gain_cur[0] = dev->cal.agc_gain_init[0] - gain_delta;
10954636a254SLorenzo Bianconi mt76x0_phy_set_gain_val(dev);
10964636a254SLorenzo Bianconi
10974636a254SLorenzo Bianconi /* clear false CCA counters */
10984636a254SLorenzo Bianconi mt76_rr(dev, MT_RX_STAT_1);
109910de7a8bSStanislaw Gruszka }
110010de7a8bSStanislaw Gruszka
mt76x0_phy_calibration_work(struct work_struct * work)11013eaf05deSLorenzo Bianconi static void mt76x0_phy_calibration_work(struct work_struct *work)
110210de7a8bSStanislaw Gruszka {
1103b2d871c0SLorenzo Bianconi struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
110410de7a8bSStanislaw Gruszka cal_work.work);
110510de7a8bSStanislaw Gruszka
11064636a254SLorenzo Bianconi mt76x0_phy_update_channel_gain(dev);
11073548a9ddSLorenzo Bianconi if (mt76x0_tssi_enabled(dev))
11083548a9ddSLorenzo Bianconi mt76x0_phy_tssi_calibrate(dev);
11093548a9ddSLorenzo Bianconi else
11109c410782SLorenzo Bianconi mt76x0_phy_temp_sensor(dev);
111110de7a8bSStanislaw Gruszka
111210de7a8bSStanislaw Gruszka ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
11133548a9ddSLorenzo Bianconi 4 * MT_CALIBRATE_INTERVAL);
111410de7a8bSStanislaw Gruszka }
111510de7a8bSStanislaw Gruszka
mt76x0_rf_patch_reg_array(struct mt76x02_dev * dev,const struct mt76_reg_pair * rp,int len)1116cadc83efSFelix Fietkau static void mt76x0_rf_patch_reg_array(struct mt76x02_dev *dev,
1117cadc83efSFelix Fietkau const struct mt76_reg_pair *rp, int len)
1118cadc83efSFelix Fietkau {
1119cadc83efSFelix Fietkau int i;
1120cadc83efSFelix Fietkau
1121cadc83efSFelix Fietkau for (i = 0; i < len; i++) {
1122cadc83efSFelix Fietkau u32 reg = rp[i].reg;
1123cadc83efSFelix Fietkau u8 val = rp[i].value;
1124cadc83efSFelix Fietkau
1125cadc83efSFelix Fietkau switch (reg) {
1126cadc83efSFelix Fietkau case MT_RF(0, 3):
112761c51a74SLorenzo Bianconi if (mt76_is_mmio(&dev->mt76)) {
1128cadc83efSFelix Fietkau if (is_mt7630(dev))
1129cadc83efSFelix Fietkau val = 0x70;
1130cadc83efSFelix Fietkau else
1131cadc83efSFelix Fietkau val = 0x63;
1132cadc83efSFelix Fietkau } else {
1133cadc83efSFelix Fietkau val = 0x73;
1134cadc83efSFelix Fietkau }
1135cadc83efSFelix Fietkau break;
1136cadc83efSFelix Fietkau case MT_RF(0, 21):
1137cadc83efSFelix Fietkau if (is_mt7610e(dev))
1138cadc83efSFelix Fietkau val = 0x10;
1139cadc83efSFelix Fietkau else
1140cadc83efSFelix Fietkau val = 0x12;
1141cadc83efSFelix Fietkau break;
1142cadc83efSFelix Fietkau case MT_RF(5, 2):
1143cadc83efSFelix Fietkau if (is_mt7630(dev))
1144cadc83efSFelix Fietkau val = 0x1d;
1145cadc83efSFelix Fietkau else if (is_mt7610e(dev))
1146cadc83efSFelix Fietkau val = 0x00;
1147cadc83efSFelix Fietkau else
1148cadc83efSFelix Fietkau val = 0x0c;
1149cadc83efSFelix Fietkau break;
1150cadc83efSFelix Fietkau default:
1151cadc83efSFelix Fietkau break;
1152cadc83efSFelix Fietkau }
1153cadc83efSFelix Fietkau mt76x0_rf_wr(dev, reg, val);
1154cadc83efSFelix Fietkau }
1155cadc83efSFelix Fietkau }
1156cadc83efSFelix Fietkau
mt76x0_phy_rf_init(struct mt76x02_dev * dev)11579c410782SLorenzo Bianconi static void mt76x0_phy_rf_init(struct mt76x02_dev *dev)
115810de7a8bSStanislaw Gruszka {
115910de7a8bSStanislaw Gruszka int i;
116010de7a8bSStanislaw Gruszka
1161cadc83efSFelix Fietkau mt76x0_rf_patch_reg_array(dev, mt76x0_rf_central_tab,
1162cadc83efSFelix Fietkau ARRAY_SIZE(mt76x0_rf_central_tab));
1163cadc83efSFelix Fietkau mt76x0_rf_patch_reg_array(dev, mt76x0_rf_2g_channel_0_tab,
1164cadc83efSFelix Fietkau ARRAY_SIZE(mt76x0_rf_2g_channel_0_tab));
116510de7a8bSStanislaw Gruszka RF_RANDOM_WRITE(dev, mt76x0_rf_5g_channel_0_tab);
116610de7a8bSStanislaw Gruszka RF_RANDOM_WRITE(dev, mt76x0_rf_vga_channel_0_tab);
116710de7a8bSStanislaw Gruszka
116810de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_rf_bw_switch_tab); i++) {
116910de7a8bSStanislaw Gruszka const struct mt76x0_rf_switch_item *item = &mt76x0_rf_bw_switch_tab[i];
117010de7a8bSStanislaw Gruszka
117110de7a8bSStanislaw Gruszka if (item->bw_band == RF_BW_20)
11729c410782SLorenzo Bianconi mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
1173ff97c52aSRyder Lee else if (((RF_G_BAND | RF_BW_20) & item->bw_band) ==
1174ff97c52aSRyder Lee (RF_G_BAND | RF_BW_20))
11759c410782SLorenzo Bianconi mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
117610de7a8bSStanislaw Gruszka }
117710de7a8bSStanislaw Gruszka
117810de7a8bSStanislaw Gruszka for (i = 0; i < ARRAY_SIZE(mt76x0_rf_band_switch_tab); i++) {
117910de7a8bSStanislaw Gruszka if (mt76x0_rf_band_switch_tab[i].bw_band & RF_G_BAND) {
11809c410782SLorenzo Bianconi mt76x0_rf_wr(dev,
118110de7a8bSStanislaw Gruszka mt76x0_rf_band_switch_tab[i].rf_bank_reg,
118210de7a8bSStanislaw Gruszka mt76x0_rf_band_switch_tab[i].value);
118310de7a8bSStanislaw Gruszka }
118410de7a8bSStanislaw Gruszka }
118510de7a8bSStanislaw Gruszka
1186ff97c52aSRyder Lee /* Frequency calibration
1187ff97c52aSRyder Lee * E1: B0.R22<6:0>: xo_cxo<6:0>
1188ff97c52aSRyder Lee * E2: B0.R21<0>: xo_cxo<0>, B0.R22<7:0>: xo_cxo<8:1>
118910de7a8bSStanislaw Gruszka */
11909c410782SLorenzo Bianconi mt76x0_rf_wr(dev, MT_RF(0, 22),
1191b2d871c0SLorenzo Bianconi min_t(u8, dev->cal.rx.freq_offset, 0xbf));
1192373954efSChen Wandun mt76x0_rf_rr(dev, MT_RF(0, 22));
119310de7a8bSStanislaw Gruszka
1194d3caa060SLorenzo Bianconi /* Reset procedure DAC during power-up:
1195d3caa060SLorenzo Bianconi * - set B0.R73<7>
1196d3caa060SLorenzo Bianconi * - clear B0.R73<7>
1197d3caa060SLorenzo Bianconi * - set B0.R73<7>
119810de7a8bSStanislaw Gruszka */
1199d3caa060SLorenzo Bianconi mt76x0_rf_set(dev, MT_RF(0, 73), BIT(7));
1200d3caa060SLorenzo Bianconi mt76x0_rf_clear(dev, MT_RF(0, 73), BIT(7));
1201d3caa060SLorenzo Bianconi mt76x0_rf_set(dev, MT_RF(0, 73), BIT(7));
120210de7a8bSStanislaw Gruszka
1203d3caa060SLorenzo Bianconi /* vcocal_en: initiate VCO calibration (reset after completion)) */
12049c410782SLorenzo Bianconi mt76x0_rf_set(dev, MT_RF(0, 4), 0x80);
120510de7a8bSStanislaw Gruszka }
120610de7a8bSStanislaw Gruszka
mt76x0_phy_init(struct mt76x02_dev * dev)1207b2d871c0SLorenzo Bianconi void mt76x0_phy_init(struct mt76x02_dev *dev)
120810de7a8bSStanislaw Gruszka {
12093eaf05deSLorenzo Bianconi INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibration_work);
121010de7a8bSStanislaw Gruszka
1211ef442b73SStanislaw Gruszka mt76x0_phy_ant_select(dev);
12129c410782SLorenzo Bianconi mt76x0_phy_rf_init(dev);
1213bfdff5d0SLorenzo Bianconi mt76x02_phy_set_rxpath(dev);
1214bfdff5d0SLorenzo Bianconi mt76x02_phy_set_txdac(dev);
121510de7a8bSStanislaw Gruszka }
1216