18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * (c) Copyright 2002-2010, Ralink Technology, Inc.
48c2ecf20Sopenharmony_ci * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
58c2ecf20Sopenharmony_ci * Copyright (C) 2015 Jakub Kicinski <kubakici@wp.pl>
68c2ecf20Sopenharmony_ci * Copyright (C) 2018 Stanislaw Gruszka <stf_xl@wp.pl>
78c2ecf20Sopenharmony_ci */
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/kernel.h>
108c2ecf20Sopenharmony_ci#include <linux/etherdevice.h>
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include "mt76x0.h"
138c2ecf20Sopenharmony_ci#include "mcu.h"
148c2ecf20Sopenharmony_ci#include "eeprom.h"
158c2ecf20Sopenharmony_ci#include "phy.h"
168c2ecf20Sopenharmony_ci#include "initvals.h"
178c2ecf20Sopenharmony_ci#include "initvals_phy.h"
188c2ecf20Sopenharmony_ci#include "../mt76x02_phy.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistatic int
218c2ecf20Sopenharmony_cimt76x0_rf_csr_wr(struct mt76x02_dev *dev, u32 offset, u8 value)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	int ret = 0;
248c2ecf20Sopenharmony_ci	u8 bank, reg;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	if (test_bit(MT76_REMOVED, &dev->mphy.state))
278c2ecf20Sopenharmony_ci		return -ENODEV;
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	bank = MT_RF_BANK(offset);
308c2ecf20Sopenharmony_ci	reg = MT_RF_REG(offset);
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8))
338c2ecf20Sopenharmony_ci		return -EINVAL;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	mutex_lock(&dev->phy_mutex);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100)) {
388c2ecf20Sopenharmony_ci		ret = -ETIMEDOUT;
398c2ecf20Sopenharmony_ci		goto out;
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_RF_CSR_CFG,
438c2ecf20Sopenharmony_ci		FIELD_PREP(MT_RF_CSR_CFG_DATA, value) |
448c2ecf20Sopenharmony_ci		FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |
458c2ecf20Sopenharmony_ci		FIELD_PREP(MT_RF_CSR_CFG_REG_ID, reg) |
468c2ecf20Sopenharmony_ci		MT_RF_CSR_CFG_WR |
478c2ecf20Sopenharmony_ci		MT_RF_CSR_CFG_KICK);
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ciout:
508c2ecf20Sopenharmony_ci	mutex_unlock(&dev->phy_mutex);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	if (ret < 0)
538c2ecf20Sopenharmony_ci		dev_err(dev->mt76.dev, "Error: RF write %d:%d failed:%d!!\n",
548c2ecf20Sopenharmony_ci			bank, reg, ret);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	return ret;
578c2ecf20Sopenharmony_ci}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cistatic int mt76x0_rf_csr_rr(struct mt76x02_dev *dev, u32 offset)
608c2ecf20Sopenharmony_ci{
618c2ecf20Sopenharmony_ci	int ret = -ETIMEDOUT;
628c2ecf20Sopenharmony_ci	u32 val;
638c2ecf20Sopenharmony_ci	u8 bank, reg;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	if (test_bit(MT76_REMOVED, &dev->mphy.state))
668c2ecf20Sopenharmony_ci		return -ENODEV;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	bank = MT_RF_BANK(offset);
698c2ecf20Sopenharmony_ci	reg = MT_RF_REG(offset);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(reg > 127) || WARN_ON_ONCE(bank > 8))
728c2ecf20Sopenharmony_ci		return -EINVAL;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	mutex_lock(&dev->phy_mutex);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))
778c2ecf20Sopenharmony_ci		goto out;
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_RF_CSR_CFG,
808c2ecf20Sopenharmony_ci		FIELD_PREP(MT_RF_CSR_CFG_REG_BANK, bank) |
818c2ecf20Sopenharmony_ci		FIELD_PREP(MT_RF_CSR_CFG_REG_ID, reg) |
828c2ecf20Sopenharmony_ci		MT_RF_CSR_CFG_KICK);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	if (!mt76_poll(dev, MT_RF_CSR_CFG, MT_RF_CSR_CFG_KICK, 0, 100))
858c2ecf20Sopenharmony_ci		goto out;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	val = mt76_rr(dev, MT_RF_CSR_CFG);
888c2ecf20Sopenharmony_ci	if (FIELD_GET(MT_RF_CSR_CFG_REG_ID, val) == reg &&
898c2ecf20Sopenharmony_ci	    FIELD_GET(MT_RF_CSR_CFG_REG_BANK, val) == bank)
908c2ecf20Sopenharmony_ci		ret = FIELD_GET(MT_RF_CSR_CFG_DATA, val);
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciout:
938c2ecf20Sopenharmony_ci	mutex_unlock(&dev->phy_mutex);
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci	if (ret < 0)
968c2ecf20Sopenharmony_ci		dev_err(dev->mt76.dev, "Error: RF read %d:%d failed:%d!!\n",
978c2ecf20Sopenharmony_ci			bank, reg, ret);
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	return ret;
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic int
1038c2ecf20Sopenharmony_cimt76x0_rf_wr(struct mt76x02_dev *dev, u32 offset, u8 val)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	if (mt76_is_usb(&dev->mt76)) {
1068c2ecf20Sopenharmony_ci		struct mt76_reg_pair pair = {
1078c2ecf20Sopenharmony_ci			.reg = offset,
1088c2ecf20Sopenharmony_ci			.value = val,
1098c2ecf20Sopenharmony_ci		};
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci		WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING,
1128c2ecf20Sopenharmony_ci				       &dev->mphy.state));
1138c2ecf20Sopenharmony_ci		return mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1);
1148c2ecf20Sopenharmony_ci	} else {
1158c2ecf20Sopenharmony_ci		return mt76x0_rf_csr_wr(dev, offset, val);
1168c2ecf20Sopenharmony_ci	}
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_cistatic int mt76x0_rf_rr(struct mt76x02_dev *dev, u32 offset)
1208c2ecf20Sopenharmony_ci{
1218c2ecf20Sopenharmony_ci	int ret;
1228c2ecf20Sopenharmony_ci	u32 val;
1238c2ecf20Sopenharmony_ci
1248c2ecf20Sopenharmony_ci	if (mt76_is_usb(&dev->mt76)) {
1258c2ecf20Sopenharmony_ci		struct mt76_reg_pair pair = {
1268c2ecf20Sopenharmony_ci			.reg = offset,
1278c2ecf20Sopenharmony_ci		};
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci		WARN_ON_ONCE(!test_bit(MT76_STATE_MCU_RUNNING,
1308c2ecf20Sopenharmony_ci				       &dev->mphy.state));
1318c2ecf20Sopenharmony_ci		ret = mt76_rd_rp(dev, MT_MCU_MEMMAP_RF, &pair, 1);
1328c2ecf20Sopenharmony_ci		val = pair.value;
1338c2ecf20Sopenharmony_ci	} else {
1348c2ecf20Sopenharmony_ci		ret = val = mt76x0_rf_csr_rr(dev, offset);
1358c2ecf20Sopenharmony_ci	}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	return (ret < 0) ? ret : val;
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_cistatic int
1418c2ecf20Sopenharmony_cimt76x0_rf_rmw(struct mt76x02_dev *dev, u32 offset, u8 mask, u8 val)
1428c2ecf20Sopenharmony_ci{
1438c2ecf20Sopenharmony_ci	int ret;
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	ret = mt76x0_rf_rr(dev, offset);
1468c2ecf20Sopenharmony_ci	if (ret < 0)
1478c2ecf20Sopenharmony_ci		return ret;
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_ci	val |= ret & ~mask;
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_ci	ret = mt76x0_rf_wr(dev, offset, val);
1528c2ecf20Sopenharmony_ci	return ret ? ret : val;
1538c2ecf20Sopenharmony_ci}
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_cistatic int
1568c2ecf20Sopenharmony_cimt76x0_rf_set(struct mt76x02_dev *dev, u32 offset, u8 val)
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	return mt76x0_rf_rmw(dev, offset, 0, val);
1598c2ecf20Sopenharmony_ci}
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_cistatic int
1628c2ecf20Sopenharmony_cimt76x0_rf_clear(struct mt76x02_dev *dev, u32 offset, u8 mask)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	return mt76x0_rf_rmw(dev, offset, mask, 0);
1658c2ecf20Sopenharmony_ci}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_cistatic void
1688c2ecf20Sopenharmony_cimt76x0_phy_rf_csr_wr_rp(struct mt76x02_dev *dev,
1698c2ecf20Sopenharmony_ci			const struct mt76_reg_pair *data,
1708c2ecf20Sopenharmony_ci			int n)
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	while (n-- > 0) {
1738c2ecf20Sopenharmony_ci		mt76x0_rf_csr_wr(dev, data->reg, data->value);
1748c2ecf20Sopenharmony_ci		data++;
1758c2ecf20Sopenharmony_ci	}
1768c2ecf20Sopenharmony_ci}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci#define RF_RANDOM_WRITE(dev, tab) do {					\
1798c2ecf20Sopenharmony_ci	if (mt76_is_mmio(&dev->mt76))					\
1808c2ecf20Sopenharmony_ci		mt76x0_phy_rf_csr_wr_rp(dev, tab, ARRAY_SIZE(tab));	\
1818c2ecf20Sopenharmony_ci	else								\
1828c2ecf20Sopenharmony_ci		mt76_wr_rp(dev, MT_MCU_MEMMAP_RF, tab, ARRAY_SIZE(tab));\
1838c2ecf20Sopenharmony_ci} while (0)
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ciint mt76x0_phy_wait_bbp_ready(struct mt76x02_dev *dev)
1868c2ecf20Sopenharmony_ci{
1878c2ecf20Sopenharmony_ci	int i = 20;
1888c2ecf20Sopenharmony_ci	u32 val;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	do {
1918c2ecf20Sopenharmony_ci		val = mt76_rr(dev, MT_BBP(CORE, 0));
1928c2ecf20Sopenharmony_ci		if (val && ~val)
1938c2ecf20Sopenharmony_ci			break;
1948c2ecf20Sopenharmony_ci	} while (--i);
1958c2ecf20Sopenharmony_ci
1968c2ecf20Sopenharmony_ci	if (!i) {
1978c2ecf20Sopenharmony_ci		dev_err(dev->mt76.dev, "Error: BBP is not ready\n");
1988c2ecf20Sopenharmony_ci		return -EIO;
1998c2ecf20Sopenharmony_ci	}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_ci	dev_dbg(dev->mt76.dev, "BBP version %08x\n", val);
2028c2ecf20Sopenharmony_ci	return 0;
2038c2ecf20Sopenharmony_ci}
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_cistatic void
2068c2ecf20Sopenharmony_cimt76x0_phy_set_band(struct mt76x02_dev *dev, enum nl80211_band band)
2078c2ecf20Sopenharmony_ci{
2088c2ecf20Sopenharmony_ci	switch (band) {
2098c2ecf20Sopenharmony_ci	case NL80211_BAND_2GHZ:
2108c2ecf20Sopenharmony_ci		RF_RANDOM_WRITE(dev, mt76x0_rf_2g_channel_0_tab);
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci		mt76x0_rf_wr(dev, MT_RF(5, 0), 0x45);
2138c2ecf20Sopenharmony_ci		mt76x0_rf_wr(dev, MT_RF(6, 0), 0x44);
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX_ALC_VGA3, 0x00050007);
2168c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x003E0002);
2178c2ecf20Sopenharmony_ci		break;
2188c2ecf20Sopenharmony_ci	case NL80211_BAND_5GHZ:
2198c2ecf20Sopenharmony_ci		RF_RANDOM_WRITE(dev, mt76x0_rf_5g_channel_0_tab);
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci		mt76x0_rf_wr(dev, MT_RF(5, 0), 0x44);
2228c2ecf20Sopenharmony_ci		mt76x0_rf_wr(dev, MT_RF(6, 0), 0x45);
2238c2ecf20Sopenharmony_ci
2248c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX_ALC_VGA3, 0x00000005);
2258c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX0_RF_GAIN_CORR, 0x01010102);
2268c2ecf20Sopenharmony_ci		break;
2278c2ecf20Sopenharmony_ci	default:
2288c2ecf20Sopenharmony_ci		break;
2298c2ecf20Sopenharmony_ci	}
2308c2ecf20Sopenharmony_ci}
2318c2ecf20Sopenharmony_ci
2328c2ecf20Sopenharmony_cistatic void
2338c2ecf20Sopenharmony_cimt76x0_phy_set_chan_rf_params(struct mt76x02_dev *dev, u8 channel,
2348c2ecf20Sopenharmony_ci			      u16 rf_bw_band)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	const struct mt76x0_freq_item *freq_item;
2378c2ecf20Sopenharmony_ci	u16 rf_band = rf_bw_band & 0xff00;
2388c2ecf20Sopenharmony_ci	u16 rf_bw = rf_bw_band & 0x00ff;
2398c2ecf20Sopenharmony_ci	enum nl80211_band band;
2408c2ecf20Sopenharmony_ci	bool b_sdm = false;
2418c2ecf20Sopenharmony_ci	u32 mac_reg;
2428c2ecf20Sopenharmony_ci	int i;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_sdm_channel); i++) {
2458c2ecf20Sopenharmony_ci		if (channel == mt76x0_sdm_channel[i]) {
2468c2ecf20Sopenharmony_ci			b_sdm = true;
2478c2ecf20Sopenharmony_ci			break;
2488c2ecf20Sopenharmony_ci		}
2498c2ecf20Sopenharmony_ci	}
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_frequency_plan); i++) {
2528c2ecf20Sopenharmony_ci		if (channel == mt76x0_frequency_plan[i].channel) {
2538c2ecf20Sopenharmony_ci			rf_band = mt76x0_frequency_plan[i].band;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci			if (b_sdm)
2568c2ecf20Sopenharmony_ci				freq_item = &mt76x0_sdm_frequency_plan[i];
2578c2ecf20Sopenharmony_ci			else
2588c2ecf20Sopenharmony_ci				freq_item = &mt76x0_frequency_plan[i];
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 37), freq_item->pllR37);
2618c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 36), freq_item->pllR36);
2628c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 35), freq_item->pllR35);
2638c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 34), freq_item->pllR34);
2648c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 33), freq_item->pllR33);
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 32), 0xe0,
2678c2ecf20Sopenharmony_ci				      freq_item->pllR32_b7b5);
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci			/* R32<4:0> pll_den: (Denomina - 8) */
2708c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 32), MT_RF_PLL_DEN_MASK,
2718c2ecf20Sopenharmony_ci				      freq_item->pllR32_b4b0);
2728c2ecf20Sopenharmony_ci
2738c2ecf20Sopenharmony_ci			/* R31<7:5> */
2748c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 31), 0xe0,
2758c2ecf20Sopenharmony_ci				      freq_item->pllR31_b7b5);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci			/* R31<4:0> pll_k(Nominator) */
2788c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 31), MT_RF_PLL_K_MASK,
2798c2ecf20Sopenharmony_ci				      freq_item->pllR31_b4b0);
2808c2ecf20Sopenharmony_ci
2818c2ecf20Sopenharmony_ci			/* R30<7> sdm_reset_n */
2828c2ecf20Sopenharmony_ci			if (b_sdm) {
2838c2ecf20Sopenharmony_ci				mt76x0_rf_clear(dev, MT_RF(0, 30),
2848c2ecf20Sopenharmony_ci						MT_RF_SDM_RESET_MASK);
2858c2ecf20Sopenharmony_ci				mt76x0_rf_set(dev, MT_RF(0, 30),
2868c2ecf20Sopenharmony_ci					      MT_RF_SDM_RESET_MASK);
2878c2ecf20Sopenharmony_ci			} else {
2888c2ecf20Sopenharmony_ci				mt76x0_rf_rmw(dev, MT_RF(0, 30),
2898c2ecf20Sopenharmony_ci					      MT_RF_SDM_RESET_MASK,
2908c2ecf20Sopenharmony_ci					      freq_item->pllR30_b7);
2918c2ecf20Sopenharmony_ci			}
2928c2ecf20Sopenharmony_ci
2938c2ecf20Sopenharmony_ci			/* R30<6:2> sdmmash_prbs,sin */
2948c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 30),
2958c2ecf20Sopenharmony_ci				      MT_RF_SDM_MASH_PRBS_MASK,
2968c2ecf20Sopenharmony_ci				      freq_item->pllR30_b6b2);
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci			/* R30<1> sdm_bp */
2998c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 30), MT_RF_SDM_BP_MASK,
3008c2ecf20Sopenharmony_ci				      freq_item->pllR30_b1 << 1);
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_ci			/* R30<0> R29<7:0> (hex) pll_n */
3038c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 29),
3048c2ecf20Sopenharmony_ci				     freq_item->pll_n & 0xff);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 30), 0x1,
3078c2ecf20Sopenharmony_ci				      (freq_item->pll_n >> 8) & 0x1);
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_ci			/* R28<7:6> isi_iso */
3108c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_ISI_ISO_MASK,
3118c2ecf20Sopenharmony_ci				      freq_item->pllR28_b7b6);
3128c2ecf20Sopenharmony_ci
3138c2ecf20Sopenharmony_ci			/* R28<5:4> pfd_dly */
3148c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_PFD_DLY_MASK,
3158c2ecf20Sopenharmony_ci				      freq_item->pllR28_b5b4);
3168c2ecf20Sopenharmony_ci
3178c2ecf20Sopenharmony_ci			/* R28<3:2> clksel option */
3188c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 28), MT_RF_CLK_SEL_MASK,
3198c2ecf20Sopenharmony_ci				      freq_item->pllR28_b3b2);
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci			/* R28<1:0> R27<7:0> R26<7:0> (hex) sdm_k */
3228c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 26),
3238c2ecf20Sopenharmony_ci				     freq_item->pll_sdm_k & 0xff);
3248c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, MT_RF(0, 27),
3258c2ecf20Sopenharmony_ci				     (freq_item->pll_sdm_k >> 8) & 0xff);
3268c2ecf20Sopenharmony_ci
3278c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 28), 0x3,
3288c2ecf20Sopenharmony_ci				      (freq_item->pll_sdm_k >> 16) & 0x3);
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci			/* R24<1:0> xo_div */
3318c2ecf20Sopenharmony_ci			mt76x0_rf_rmw(dev, MT_RF(0, 24), MT_RF_XO_DIV_MASK,
3328c2ecf20Sopenharmony_ci				      freq_item->pllR24_b1b0);
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci			break;
3358c2ecf20Sopenharmony_ci		}
3368c2ecf20Sopenharmony_ci	}
3378c2ecf20Sopenharmony_ci
3388c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_rf_bw_switch_tab); i++) {
3398c2ecf20Sopenharmony_ci		if (rf_bw == mt76x0_rf_bw_switch_tab[i].bw_band) {
3408c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev,
3418c2ecf20Sopenharmony_ci				     mt76x0_rf_bw_switch_tab[i].rf_bank_reg,
3428c2ecf20Sopenharmony_ci				     mt76x0_rf_bw_switch_tab[i].value);
3438c2ecf20Sopenharmony_ci		} else if ((rf_bw == (mt76x0_rf_bw_switch_tab[i].bw_band & 0xFF)) &&
3448c2ecf20Sopenharmony_ci			   (rf_band & mt76x0_rf_bw_switch_tab[i].bw_band)) {
3458c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev,
3468c2ecf20Sopenharmony_ci				     mt76x0_rf_bw_switch_tab[i].rf_bank_reg,
3478c2ecf20Sopenharmony_ci				     mt76x0_rf_bw_switch_tab[i].value);
3488c2ecf20Sopenharmony_ci		}
3498c2ecf20Sopenharmony_ci	}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_rf_band_switch_tab); i++) {
3528c2ecf20Sopenharmony_ci		if (mt76x0_rf_band_switch_tab[i].bw_band & rf_band) {
3538c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev,
3548c2ecf20Sopenharmony_ci				     mt76x0_rf_band_switch_tab[i].rf_bank_reg,
3558c2ecf20Sopenharmony_ci				     mt76x0_rf_band_switch_tab[i].value);
3568c2ecf20Sopenharmony_ci		}
3578c2ecf20Sopenharmony_ci	}
3588c2ecf20Sopenharmony_ci
3598c2ecf20Sopenharmony_ci	mt76_clear(dev, MT_RF_MISC, 0xc);
3608c2ecf20Sopenharmony_ci
3618c2ecf20Sopenharmony_ci	band = (rf_band & RF_G_BAND) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
3628c2ecf20Sopenharmony_ci	if (mt76x02_ext_pa_enabled(dev, band)) {
3638c2ecf20Sopenharmony_ci		/* MT_RF_MISC (offset: 0x0518)
3648c2ecf20Sopenharmony_ci		 * [2]1'b1: enable external A band PA
3658c2ecf20Sopenharmony_ci		 *    1'b0: disable external A band PA
3668c2ecf20Sopenharmony_ci		 * [3]1'b1: enable external G band PA
3678c2ecf20Sopenharmony_ci		 *    1'b0: disable external G band PA
3688c2ecf20Sopenharmony_ci		 */
3698c2ecf20Sopenharmony_ci		if (rf_band & RF_A_BAND)
3708c2ecf20Sopenharmony_ci			mt76_set(dev, MT_RF_MISC, BIT(2));
3718c2ecf20Sopenharmony_ci		else
3728c2ecf20Sopenharmony_ci			mt76_set(dev, MT_RF_MISC, BIT(3));
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci		/* External PA */
3758c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(mt76x0_rf_ext_pa_tab); i++)
3768c2ecf20Sopenharmony_ci			if (mt76x0_rf_ext_pa_tab[i].bw_band & rf_band)
3778c2ecf20Sopenharmony_ci				mt76x0_rf_wr(dev,
3788c2ecf20Sopenharmony_ci					mt76x0_rf_ext_pa_tab[i].rf_bank_reg,
3798c2ecf20Sopenharmony_ci					mt76x0_rf_ext_pa_tab[i].value);
3808c2ecf20Sopenharmony_ci	}
3818c2ecf20Sopenharmony_ci
3828c2ecf20Sopenharmony_ci	if (rf_band & RF_G_BAND) {
3838c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x63707400);
3848c2ecf20Sopenharmony_ci		/* Set Atten mode = 2 For G band, Disable Tx Inc dcoc. */
3858c2ecf20Sopenharmony_ci		mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
3868c2ecf20Sopenharmony_ci		mac_reg &= 0x896400FF;
3878c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
3888c2ecf20Sopenharmony_ci	} else {
3898c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX0_RF_GAIN_ATTEN, 0x686A7800);
3908c2ecf20Sopenharmony_ci		/* Set Atten mode = 0
3918c2ecf20Sopenharmony_ci		 * For Ext A band, Disable Tx Inc dcoc Cal.
3928c2ecf20Sopenharmony_ci		 */
3938c2ecf20Sopenharmony_ci		mac_reg = mt76_rr(dev, MT_TX_ALC_CFG_1);
3948c2ecf20Sopenharmony_ci		mac_reg &= 0x890400FF;
3958c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX_ALC_CFG_1, mac_reg);
3968c2ecf20Sopenharmony_ci	}
3978c2ecf20Sopenharmony_ci}
3988c2ecf20Sopenharmony_ci
3998c2ecf20Sopenharmony_cistatic void
4008c2ecf20Sopenharmony_cimt76x0_phy_set_chan_bbp_params(struct mt76x02_dev *dev, u16 rf_bw_band)
4018c2ecf20Sopenharmony_ci{
4028c2ecf20Sopenharmony_ci	int i;
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_bbp_switch_tab); i++) {
4058c2ecf20Sopenharmony_ci		const struct mt76x0_bbp_switch_item *item = &mt76x0_bbp_switch_tab[i];
4068c2ecf20Sopenharmony_ci		const struct mt76_reg_pair *pair = &item->reg_pair;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci		if ((rf_bw_band & item->bw_band) != rf_bw_band)
4098c2ecf20Sopenharmony_ci			continue;
4108c2ecf20Sopenharmony_ci
4118c2ecf20Sopenharmony_ci		if (pair->reg == MT_BBP(AGC, 8)) {
4128c2ecf20Sopenharmony_ci			u32 val = pair->value;
4138c2ecf20Sopenharmony_ci			u8 gain;
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_ci			gain = FIELD_GET(MT_BBP_AGC_GAIN, val);
4168c2ecf20Sopenharmony_ci			gain -= dev->cal.rx.lna_gain * 2;
4178c2ecf20Sopenharmony_ci			val &= ~MT_BBP_AGC_GAIN;
4188c2ecf20Sopenharmony_ci			val |= FIELD_PREP(MT_BBP_AGC_GAIN, gain);
4198c2ecf20Sopenharmony_ci			mt76_wr(dev, pair->reg, val);
4208c2ecf20Sopenharmony_ci		} else {
4218c2ecf20Sopenharmony_ci			mt76_wr(dev, pair->reg, pair->value);
4228c2ecf20Sopenharmony_ci		}
4238c2ecf20Sopenharmony_ci	}
4248c2ecf20Sopenharmony_ci}
4258c2ecf20Sopenharmony_ci
4268c2ecf20Sopenharmony_cistatic void mt76x0_phy_ant_select(struct mt76x02_dev *dev)
4278c2ecf20Sopenharmony_ci{
4288c2ecf20Sopenharmony_ci	u16 ee_ant = mt76x02_eeprom_get(dev, MT_EE_ANTENNA);
4298c2ecf20Sopenharmony_ci	u16 ee_cfg1 = mt76x02_eeprom_get(dev, MT_EE_CFG1_INIT);
4308c2ecf20Sopenharmony_ci	u16 nic_conf2 = mt76x02_eeprom_get(dev, MT_EE_NIC_CONF_2);
4318c2ecf20Sopenharmony_ci	u32 wlan, coex3;
4328c2ecf20Sopenharmony_ci	bool ant_div;
4338c2ecf20Sopenharmony_ci
4348c2ecf20Sopenharmony_ci	wlan = mt76_rr(dev, MT_WLAN_FUN_CTRL);
4358c2ecf20Sopenharmony_ci	coex3 = mt76_rr(dev, MT_COEXCFG3);
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	ee_ant &= ~(BIT(14) | BIT(12));
4388c2ecf20Sopenharmony_ci	wlan  &= ~(BIT(6) | BIT(5));
4398c2ecf20Sopenharmony_ci	coex3 &= ~GENMASK(5, 2);
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_ci	if (ee_ant & MT_EE_ANTENNA_DUAL) {
4428c2ecf20Sopenharmony_ci		/* dual antenna mode */
4438c2ecf20Sopenharmony_ci		ant_div = !(nic_conf2 & MT_EE_NIC_CONF_2_ANT_OPT) &&
4448c2ecf20Sopenharmony_ci			  (nic_conf2 & MT_EE_NIC_CONF_2_ANT_DIV);
4458c2ecf20Sopenharmony_ci		if (ant_div)
4468c2ecf20Sopenharmony_ci			ee_ant |= BIT(12);
4478c2ecf20Sopenharmony_ci		else
4488c2ecf20Sopenharmony_ci			coex3 |= BIT(4);
4498c2ecf20Sopenharmony_ci		coex3 |= BIT(3);
4508c2ecf20Sopenharmony_ci		if (dev->mphy.cap.has_2ghz)
4518c2ecf20Sopenharmony_ci			wlan |= BIT(6);
4528c2ecf20Sopenharmony_ci	} else {
4538c2ecf20Sopenharmony_ci		/* sigle antenna mode */
4548c2ecf20Sopenharmony_ci		if (dev->mphy.cap.has_5ghz) {
4558c2ecf20Sopenharmony_ci			coex3 |= BIT(3) | BIT(4);
4568c2ecf20Sopenharmony_ci		} else {
4578c2ecf20Sopenharmony_ci			wlan |= BIT(6);
4588c2ecf20Sopenharmony_ci			coex3 |= BIT(1);
4598c2ecf20Sopenharmony_ci		}
4608c2ecf20Sopenharmony_ci	}
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	if (is_mt7630(dev))
4638c2ecf20Sopenharmony_ci		ee_ant |= BIT(14) | BIT(11);
4648c2ecf20Sopenharmony_ci
4658c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_WLAN_FUN_CTRL, wlan);
4668c2ecf20Sopenharmony_ci	mt76_rmw(dev, MT_CMB_CTRL, GENMASK(15, 0), ee_ant);
4678c2ecf20Sopenharmony_ci	mt76_rmw(dev, MT_CSR_EE_CFG1, GENMASK(15, 0), ee_cfg1);
4688c2ecf20Sopenharmony_ci	mt76_clear(dev, MT_COEXCFG0, BIT(2));
4698c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_COEXCFG3, coex3);
4708c2ecf20Sopenharmony_ci}
4718c2ecf20Sopenharmony_ci
4728c2ecf20Sopenharmony_cistatic void
4738c2ecf20Sopenharmony_cimt76x0_phy_bbp_set_bw(struct mt76x02_dev *dev, enum nl80211_chan_width width)
4748c2ecf20Sopenharmony_ci{
4758c2ecf20Sopenharmony_ci	enum { BW_20 = 0, BW_40 = 1, BW_80 = 2, BW_10 = 4};
4768c2ecf20Sopenharmony_ci	int bw;
4778c2ecf20Sopenharmony_ci
4788c2ecf20Sopenharmony_ci	switch (width) {
4798c2ecf20Sopenharmony_ci	default:
4808c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_20_NOHT:
4818c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_20:
4828c2ecf20Sopenharmony_ci		bw = BW_20;
4838c2ecf20Sopenharmony_ci		break;
4848c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_40:
4858c2ecf20Sopenharmony_ci		bw = BW_40;
4868c2ecf20Sopenharmony_ci		break;
4878c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_80:
4888c2ecf20Sopenharmony_ci		bw = BW_80;
4898c2ecf20Sopenharmony_ci		break;
4908c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_10:
4918c2ecf20Sopenharmony_ci		bw = BW_10;
4928c2ecf20Sopenharmony_ci		break;
4938c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_80P80:
4948c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_160:
4958c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_5:
4968c2ecf20Sopenharmony_ci		/* TODO error */
4978c2ecf20Sopenharmony_ci		return;
4988c2ecf20Sopenharmony_ci	}
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci	mt76x02_mcu_function_select(dev, BW_SETTING, bw);
5018c2ecf20Sopenharmony_ci}
5028c2ecf20Sopenharmony_ci
5038c2ecf20Sopenharmony_cistatic void mt76x0_phy_tssi_dc_calibrate(struct mt76x02_dev *dev)
5048c2ecf20Sopenharmony_ci{
5058c2ecf20Sopenharmony_ci	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
5068c2ecf20Sopenharmony_ci	u32 val;
5078c2ecf20Sopenharmony_ci
5088c2ecf20Sopenharmony_ci	if (chan->band == NL80211_BAND_5GHZ)
5098c2ecf20Sopenharmony_ci		mt76x0_rf_clear(dev, MT_RF(0, 67), 0xf);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	/* bypass ADDA control */
5128c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_RF_SETTING_0, 0x60002237);
5138c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_RF_BYPASS_0, 0xffffffff);
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci	/* bbp sw reset */
5168c2ecf20Sopenharmony_ci	mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
5178c2ecf20Sopenharmony_ci	usleep_range(500, 1000);
5188c2ecf20Sopenharmony_ci	mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
5218c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), val);
5228c2ecf20Sopenharmony_ci
5238c2ecf20Sopenharmony_ci	/* enable TX with DAC0 input */
5248c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(TXBE, 6), BIT(31));
5258c2ecf20Sopenharmony_ci
5268c2ecf20Sopenharmony_ci	mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200);
5278c2ecf20Sopenharmony_ci	dev->cal.tssi_dc = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	/* stop bypass ADDA */
5308c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_RF_BYPASS_0, 0);
5318c2ecf20Sopenharmony_ci	/* stop TX */
5328c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(TXBE, 6), 0);
5338c2ecf20Sopenharmony_ci	/* bbp sw reset */
5348c2ecf20Sopenharmony_ci	mt76_set(dev, MT_BBP(CORE, 4), BIT(0));
5358c2ecf20Sopenharmony_ci	usleep_range(500, 1000);
5368c2ecf20Sopenharmony_ci	mt76_clear(dev, MT_BBP(CORE, 4), BIT(0));
5378c2ecf20Sopenharmony_ci
5388c2ecf20Sopenharmony_ci	if (chan->band == NL80211_BAND_5GHZ)
5398c2ecf20Sopenharmony_ci		mt76x0_rf_rmw(dev, MT_RF(0, 67), 0xf, 0x4);
5408c2ecf20Sopenharmony_ci}
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_cistatic int
5438c2ecf20Sopenharmony_cimt76x0_phy_tssi_adc_calibrate(struct mt76x02_dev *dev, s16 *ltssi,
5448c2ecf20Sopenharmony_ci			      u8 *info)
5458c2ecf20Sopenharmony_ci{
5468c2ecf20Sopenharmony_ci	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
5478c2ecf20Sopenharmony_ci	u32 val;
5488c2ecf20Sopenharmony_ci
5498c2ecf20Sopenharmony_ci	val = (chan->band == NL80211_BAND_5GHZ) ? 0x80055 : 0x80050;
5508c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), val);
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
5538c2ecf20Sopenharmony_ci		mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
5548c2ecf20Sopenharmony_ci		return -ETIMEDOUT;
5558c2ecf20Sopenharmony_ci	}
5568c2ecf20Sopenharmony_ci
5578c2ecf20Sopenharmony_ci	*ltssi = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5588c2ecf20Sopenharmony_ci	if (chan->band == NL80211_BAND_5GHZ)
5598c2ecf20Sopenharmony_ci		*ltssi += 128;
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci	/* set packet info#1 mode */
5628c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), 0x80041);
5638c2ecf20Sopenharmony_ci	info[0] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5648c2ecf20Sopenharmony_ci
5658c2ecf20Sopenharmony_ci	/* set packet info#2 mode */
5668c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), 0x80042);
5678c2ecf20Sopenharmony_ci	info[1] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5688c2ecf20Sopenharmony_ci
5698c2ecf20Sopenharmony_ci	/* set packet info#3 mode */
5708c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), 0x80043);
5718c2ecf20Sopenharmony_ci	info[2] = mt76_rr(dev, MT_BBP(CORE, 35)) & 0xff;
5728c2ecf20Sopenharmony_ci
5738c2ecf20Sopenharmony_ci	return 0;
5748c2ecf20Sopenharmony_ci}
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_cistatic u8 mt76x0_phy_get_rf_pa_mode(struct mt76x02_dev *dev,
5778c2ecf20Sopenharmony_ci				    int index, u8 tx_rate)
5788c2ecf20Sopenharmony_ci{
5798c2ecf20Sopenharmony_ci	u32 val, reg;
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_ci	reg = (index == 1) ? MT_RF_PA_MODE_CFG1 : MT_RF_PA_MODE_CFG0;
5828c2ecf20Sopenharmony_ci	val = mt76_rr(dev, reg);
5838c2ecf20Sopenharmony_ci	return (val & (3 << (tx_rate * 2))) >> (tx_rate * 2);
5848c2ecf20Sopenharmony_ci}
5858c2ecf20Sopenharmony_ci
5868c2ecf20Sopenharmony_cistatic int
5878c2ecf20Sopenharmony_cimt76x0_phy_get_target_power(struct mt76x02_dev *dev, u8 tx_mode,
5888c2ecf20Sopenharmony_ci			    u8 *info, s8 *target_power,
5898c2ecf20Sopenharmony_ci			    s8 *target_pa_power)
5908c2ecf20Sopenharmony_ci{
5918c2ecf20Sopenharmony_ci	u8 tx_rate, cur_power;
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_ci	cur_power = mt76_rr(dev, MT_TX_ALC_CFG_0) & MT_TX_ALC_CFG_0_CH_INIT_0;
5948c2ecf20Sopenharmony_ci	switch (tx_mode) {
5958c2ecf20Sopenharmony_ci	case 0:
5968c2ecf20Sopenharmony_ci		/* cck rates */
5978c2ecf20Sopenharmony_ci		tx_rate = (info[0] & 0x60) >> 5;
5988c2ecf20Sopenharmony_ci		if (tx_rate > 3)
5998c2ecf20Sopenharmony_ci			return -EINVAL;
6008c2ecf20Sopenharmony_ci
6018c2ecf20Sopenharmony_ci		*target_power = cur_power + dev->mt76.rate_power.cck[tx_rate];
6028c2ecf20Sopenharmony_ci		*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, tx_rate);
6038c2ecf20Sopenharmony_ci		break;
6048c2ecf20Sopenharmony_ci	case 1: {
6058c2ecf20Sopenharmony_ci		u8 index;
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_ci		/* ofdm rates */
6088c2ecf20Sopenharmony_ci		tx_rate = (info[0] & 0xf0) >> 4;
6098c2ecf20Sopenharmony_ci		switch (tx_rate) {
6108c2ecf20Sopenharmony_ci		case 0xb:
6118c2ecf20Sopenharmony_ci			index = 0;
6128c2ecf20Sopenharmony_ci			break;
6138c2ecf20Sopenharmony_ci		case 0xf:
6148c2ecf20Sopenharmony_ci			index = 1;
6158c2ecf20Sopenharmony_ci			break;
6168c2ecf20Sopenharmony_ci		case 0xa:
6178c2ecf20Sopenharmony_ci			index = 2;
6188c2ecf20Sopenharmony_ci			break;
6198c2ecf20Sopenharmony_ci		case 0xe:
6208c2ecf20Sopenharmony_ci			index = 3;
6218c2ecf20Sopenharmony_ci			break;
6228c2ecf20Sopenharmony_ci		case 0x9:
6238c2ecf20Sopenharmony_ci			index = 4;
6248c2ecf20Sopenharmony_ci			break;
6258c2ecf20Sopenharmony_ci		case 0xd:
6268c2ecf20Sopenharmony_ci			index = 5;
6278c2ecf20Sopenharmony_ci			break;
6288c2ecf20Sopenharmony_ci		case 0x8:
6298c2ecf20Sopenharmony_ci			index = 6;
6308c2ecf20Sopenharmony_ci			break;
6318c2ecf20Sopenharmony_ci		case 0xc:
6328c2ecf20Sopenharmony_ci			index = 7;
6338c2ecf20Sopenharmony_ci			break;
6348c2ecf20Sopenharmony_ci		default:
6358c2ecf20Sopenharmony_ci			return -EINVAL;
6368c2ecf20Sopenharmony_ci		}
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci		*target_power = cur_power + dev->mt76.rate_power.ofdm[index];
6398c2ecf20Sopenharmony_ci		*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 0, index + 4);
6408c2ecf20Sopenharmony_ci		break;
6418c2ecf20Sopenharmony_ci	}
6428c2ecf20Sopenharmony_ci	case 4:
6438c2ecf20Sopenharmony_ci		/* vht rates */
6448c2ecf20Sopenharmony_ci		tx_rate = info[1] & 0xf;
6458c2ecf20Sopenharmony_ci		if (tx_rate > 9)
6468c2ecf20Sopenharmony_ci			return -EINVAL;
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci		*target_power = cur_power + dev->mt76.rate_power.vht[tx_rate];
6498c2ecf20Sopenharmony_ci		*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
6508c2ecf20Sopenharmony_ci		break;
6518c2ecf20Sopenharmony_ci	default:
6528c2ecf20Sopenharmony_ci		/* ht rates */
6538c2ecf20Sopenharmony_ci		tx_rate = info[1] & 0x7f;
6548c2ecf20Sopenharmony_ci		if (tx_rate > 9)
6558c2ecf20Sopenharmony_ci			return -EINVAL;
6568c2ecf20Sopenharmony_ci
6578c2ecf20Sopenharmony_ci		*target_power = cur_power + dev->mt76.rate_power.ht[tx_rate];
6588c2ecf20Sopenharmony_ci		*target_pa_power = mt76x0_phy_get_rf_pa_mode(dev, 1, tx_rate);
6598c2ecf20Sopenharmony_ci		break;
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	return 0;
6638c2ecf20Sopenharmony_ci}
6648c2ecf20Sopenharmony_ci
6658c2ecf20Sopenharmony_cistatic s16 mt76x0_phy_lin2db(u16 val)
6668c2ecf20Sopenharmony_ci{
6678c2ecf20Sopenharmony_ci	u32 mantissa = val << 4;
6688c2ecf20Sopenharmony_ci	int ret, data;
6698c2ecf20Sopenharmony_ci	s16 exp = -4;
6708c2ecf20Sopenharmony_ci
6718c2ecf20Sopenharmony_ci	while (mantissa < BIT(15)) {
6728c2ecf20Sopenharmony_ci		mantissa <<= 1;
6738c2ecf20Sopenharmony_ci		if (--exp < -20)
6748c2ecf20Sopenharmony_ci			return -10000;
6758c2ecf20Sopenharmony_ci	}
6768c2ecf20Sopenharmony_ci	while (mantissa > 0xffff) {
6778c2ecf20Sopenharmony_ci		mantissa >>= 1;
6788c2ecf20Sopenharmony_ci		if (++exp > 20)
6798c2ecf20Sopenharmony_ci			return -10000;
6808c2ecf20Sopenharmony_ci	}
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci	/* s(15,0) */
6838c2ecf20Sopenharmony_ci	if (mantissa <= 47104)
6848c2ecf20Sopenharmony_ci		data = mantissa + (mantissa >> 3) + (mantissa >> 4) - 38400;
6858c2ecf20Sopenharmony_ci	else
6868c2ecf20Sopenharmony_ci		data = mantissa - (mantissa >> 3) - (mantissa >> 6) - 23040;
6878c2ecf20Sopenharmony_ci	data = max_t(int, 0, data);
6888c2ecf20Sopenharmony_ci
6898c2ecf20Sopenharmony_ci	ret = ((15 + exp) << 15) + data;
6908c2ecf20Sopenharmony_ci	ret = (ret << 2) + (ret << 1) + (ret >> 6) + (ret >> 7);
6918c2ecf20Sopenharmony_ci	return ret >> 10;
6928c2ecf20Sopenharmony_ci}
6938c2ecf20Sopenharmony_ci
6948c2ecf20Sopenharmony_cistatic int
6958c2ecf20Sopenharmony_cimt76x0_phy_get_delta_power(struct mt76x02_dev *dev, u8 tx_mode,
6968c2ecf20Sopenharmony_ci			   s8 target_power, s8 target_pa_power,
6978c2ecf20Sopenharmony_ci			   s16 ltssi)
6988c2ecf20Sopenharmony_ci{
6998c2ecf20Sopenharmony_ci	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
7008c2ecf20Sopenharmony_ci	int tssi_target = target_power << 12, tssi_slope;
7018c2ecf20Sopenharmony_ci	int tssi_offset, tssi_db, ret;
7028c2ecf20Sopenharmony_ci	u32 data;
7038c2ecf20Sopenharmony_ci	u16 val;
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ci	if (chan->band == NL80211_BAND_5GHZ) {
7068c2ecf20Sopenharmony_ci		u8 bound[7];
7078c2ecf20Sopenharmony_ci		int i, err;
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci		err = mt76x02_eeprom_copy(dev, MT_EE_TSSI_BOUND1, bound,
7108c2ecf20Sopenharmony_ci					  sizeof(bound));
7118c2ecf20Sopenharmony_ci		if (err < 0)
7128c2ecf20Sopenharmony_ci			return err;
7138c2ecf20Sopenharmony_ci
7148c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(bound); i++) {
7158c2ecf20Sopenharmony_ci			if (chan->hw_value <= bound[i] || !bound[i])
7168c2ecf20Sopenharmony_ci				break;
7178c2ecf20Sopenharmony_ci		}
7188c2ecf20Sopenharmony_ci		val = mt76x02_eeprom_get(dev, MT_EE_TSSI_SLOPE_5G + i * 2);
7198c2ecf20Sopenharmony_ci
7208c2ecf20Sopenharmony_ci		tssi_offset = val >> 8;
7218c2ecf20Sopenharmony_ci		if ((tssi_offset >= 64 && tssi_offset <= 127) ||
7228c2ecf20Sopenharmony_ci		    (tssi_offset & BIT(7)))
7238c2ecf20Sopenharmony_ci			tssi_offset -= BIT(8);
7248c2ecf20Sopenharmony_ci	} else {
7258c2ecf20Sopenharmony_ci		val = mt76x02_eeprom_get(dev, MT_EE_TSSI_SLOPE_2G);
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci		tssi_offset = val >> 8;
7288c2ecf20Sopenharmony_ci		if (tssi_offset & BIT(7))
7298c2ecf20Sopenharmony_ci			tssi_offset -= BIT(8);
7308c2ecf20Sopenharmony_ci	}
7318c2ecf20Sopenharmony_ci	tssi_slope = val & 0xff;
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_ci	switch (target_pa_power) {
7348c2ecf20Sopenharmony_ci	case 1:
7358c2ecf20Sopenharmony_ci		if (chan->band == NL80211_BAND_2GHZ)
7368c2ecf20Sopenharmony_ci			tssi_target += 29491; /* 3.6 * 8192 */
7378c2ecf20Sopenharmony_ci		fallthrough;
7388c2ecf20Sopenharmony_ci	case 0:
7398c2ecf20Sopenharmony_ci		break;
7408c2ecf20Sopenharmony_ci	default:
7418c2ecf20Sopenharmony_ci		tssi_target += 4424; /* 0.54 * 8192 */
7428c2ecf20Sopenharmony_ci		break;
7438c2ecf20Sopenharmony_ci	}
7448c2ecf20Sopenharmony_ci
7458c2ecf20Sopenharmony_ci	if (!tx_mode) {
7468c2ecf20Sopenharmony_ci		data = mt76_rr(dev, MT_BBP(CORE, 1));
7478c2ecf20Sopenharmony_ci		if (is_mt7630(dev) && mt76_is_mmio(&dev->mt76)) {
7488c2ecf20Sopenharmony_ci			int offset;
7498c2ecf20Sopenharmony_ci
7508c2ecf20Sopenharmony_ci			/* 2.3 * 8192 or 1.5 * 8192 */
7518c2ecf20Sopenharmony_ci			offset = (data & BIT(5)) ? 18841 : 12288;
7528c2ecf20Sopenharmony_ci			tssi_target += offset;
7538c2ecf20Sopenharmony_ci		} else if (data & BIT(5)) {
7548c2ecf20Sopenharmony_ci			/* 0.8 * 8192 */
7558c2ecf20Sopenharmony_ci			tssi_target += 6554;
7568c2ecf20Sopenharmony_ci		}
7578c2ecf20Sopenharmony_ci	}
7588c2ecf20Sopenharmony_ci
7598c2ecf20Sopenharmony_ci	data = mt76_rr(dev, MT_BBP(TXBE, 4));
7608c2ecf20Sopenharmony_ci	switch (data & 0x3) {
7618c2ecf20Sopenharmony_ci	case 1:
7628c2ecf20Sopenharmony_ci		tssi_target -= 49152; /* -6db * 8192 */
7638c2ecf20Sopenharmony_ci		break;
7648c2ecf20Sopenharmony_ci	case 2:
7658c2ecf20Sopenharmony_ci		tssi_target -= 98304; /* -12db * 8192 */
7668c2ecf20Sopenharmony_ci		break;
7678c2ecf20Sopenharmony_ci	case 3:
7688c2ecf20Sopenharmony_ci		tssi_target += 49152; /* 6db * 8192 */
7698c2ecf20Sopenharmony_ci		break;
7708c2ecf20Sopenharmony_ci	default:
7718c2ecf20Sopenharmony_ci		break;
7728c2ecf20Sopenharmony_ci	}
7738c2ecf20Sopenharmony_ci
7748c2ecf20Sopenharmony_ci	tssi_db = mt76x0_phy_lin2db(ltssi - dev->cal.tssi_dc) * tssi_slope;
7758c2ecf20Sopenharmony_ci	if (chan->band == NL80211_BAND_5GHZ) {
7768c2ecf20Sopenharmony_ci		tssi_db += ((tssi_offset - 50) << 10); /* offset s4.3 */
7778c2ecf20Sopenharmony_ci		tssi_target -= tssi_db;
7788c2ecf20Sopenharmony_ci		if (ltssi > 254 && tssi_target > 0) {
7798c2ecf20Sopenharmony_ci			/* upper saturate */
7808c2ecf20Sopenharmony_ci			tssi_target = 0;
7818c2ecf20Sopenharmony_ci		}
7828c2ecf20Sopenharmony_ci	} else {
7838c2ecf20Sopenharmony_ci		tssi_db += (tssi_offset << 9); /* offset s3.4 */
7848c2ecf20Sopenharmony_ci		tssi_target -= tssi_db;
7858c2ecf20Sopenharmony_ci		/* upper-lower saturate */
7868c2ecf20Sopenharmony_ci		if ((ltssi > 126 && tssi_target > 0) ||
7878c2ecf20Sopenharmony_ci		    ((ltssi - dev->cal.tssi_dc) < 1 && tssi_target < 0)) {
7888c2ecf20Sopenharmony_ci			tssi_target = 0;
7898c2ecf20Sopenharmony_ci		}
7908c2ecf20Sopenharmony_ci	}
7918c2ecf20Sopenharmony_ci
7928c2ecf20Sopenharmony_ci	if ((dev->cal.tssi_target ^ tssi_target) < 0 &&
7938c2ecf20Sopenharmony_ci	    dev->cal.tssi_target > -4096 && dev->cal.tssi_target < 4096 &&
7948c2ecf20Sopenharmony_ci	    tssi_target > -4096 && tssi_target < 4096) {
7958c2ecf20Sopenharmony_ci		if ((tssi_target < 0 &&
7968c2ecf20Sopenharmony_ci		     tssi_target + dev->cal.tssi_target > 0) ||
7978c2ecf20Sopenharmony_ci		    (tssi_target > 0 &&
7988c2ecf20Sopenharmony_ci		     tssi_target + dev->cal.tssi_target <= 0))
7998c2ecf20Sopenharmony_ci			tssi_target = 0;
8008c2ecf20Sopenharmony_ci		else
8018c2ecf20Sopenharmony_ci			dev->cal.tssi_target = tssi_target;
8028c2ecf20Sopenharmony_ci	} else {
8038c2ecf20Sopenharmony_ci		dev->cal.tssi_target = tssi_target;
8048c2ecf20Sopenharmony_ci	}
8058c2ecf20Sopenharmony_ci
8068c2ecf20Sopenharmony_ci	/* make the compensate value to the nearest compensate code */
8078c2ecf20Sopenharmony_ci	if (tssi_target > 0)
8088c2ecf20Sopenharmony_ci		tssi_target += 2048;
8098c2ecf20Sopenharmony_ci	else
8108c2ecf20Sopenharmony_ci		tssi_target -= 2048;
8118c2ecf20Sopenharmony_ci	tssi_target >>= 12;
8128c2ecf20Sopenharmony_ci
8138c2ecf20Sopenharmony_ci	ret = mt76_get_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP);
8148c2ecf20Sopenharmony_ci	if (ret & BIT(5))
8158c2ecf20Sopenharmony_ci		ret -= BIT(6);
8168c2ecf20Sopenharmony_ci	ret += tssi_target;
8178c2ecf20Sopenharmony_ci
8188c2ecf20Sopenharmony_ci	ret = min_t(int, 31, ret);
8198c2ecf20Sopenharmony_ci	return max_t(int, -32, ret);
8208c2ecf20Sopenharmony_ci}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_cistatic void mt76x0_phy_tssi_calibrate(struct mt76x02_dev *dev)
8238c2ecf20Sopenharmony_ci{
8248c2ecf20Sopenharmony_ci	s8 target_power, target_pa_power;
8258c2ecf20Sopenharmony_ci	u8 tssi_info[3], tx_mode;
8268c2ecf20Sopenharmony_ci	s16 ltssi;
8278c2ecf20Sopenharmony_ci	s8 val;
8288c2ecf20Sopenharmony_ci
8298c2ecf20Sopenharmony_ci	if (mt76x0_phy_tssi_adc_calibrate(dev, &ltssi, tssi_info) < 0)
8308c2ecf20Sopenharmony_ci		return;
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci	tx_mode = tssi_info[0] & 0x7;
8338c2ecf20Sopenharmony_ci	if (mt76x0_phy_get_target_power(dev, tx_mode, tssi_info,
8348c2ecf20Sopenharmony_ci					&target_power, &target_pa_power) < 0)
8358c2ecf20Sopenharmony_ci		return;
8368c2ecf20Sopenharmony_ci
8378c2ecf20Sopenharmony_ci	val = mt76x0_phy_get_delta_power(dev, tx_mode, target_power,
8388c2ecf20Sopenharmony_ci					 target_pa_power, ltssi);
8398c2ecf20Sopenharmony_ci	mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, val);
8408c2ecf20Sopenharmony_ci}
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_civoid mt76x0_phy_set_txpower(struct mt76x02_dev *dev)
8438c2ecf20Sopenharmony_ci{
8448c2ecf20Sopenharmony_ci	struct mt76_rate_power *t = &dev->mt76.rate_power;
8458c2ecf20Sopenharmony_ci	s8 info;
8468c2ecf20Sopenharmony_ci
8478c2ecf20Sopenharmony_ci	mt76x0_get_tx_power_per_rate(dev, dev->mphy.chandef.chan, t);
8488c2ecf20Sopenharmony_ci	mt76x0_get_power_info(dev, dev->mphy.chandef.chan, &info);
8498c2ecf20Sopenharmony_ci
8508c2ecf20Sopenharmony_ci	mt76x02_add_rate_power_offset(t, info);
8518c2ecf20Sopenharmony_ci	mt76x02_limit_rate_power(t, dev->txpower_conf);
8528c2ecf20Sopenharmony_ci	dev->mphy.txpower_cur = mt76x02_get_max_rate_power(t);
8538c2ecf20Sopenharmony_ci	mt76x02_add_rate_power_offset(t, -info);
8548c2ecf20Sopenharmony_ci
8558c2ecf20Sopenharmony_ci	dev->target_power = info;
8568c2ecf20Sopenharmony_ci	mt76x02_phy_set_txpower(dev, info, info);
8578c2ecf20Sopenharmony_ci}
8588c2ecf20Sopenharmony_ci
8598c2ecf20Sopenharmony_civoid mt76x0_phy_calibrate(struct mt76x02_dev *dev, bool power_on)
8608c2ecf20Sopenharmony_ci{
8618c2ecf20Sopenharmony_ci	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
8628c2ecf20Sopenharmony_ci	int is_5ghz = (chan->band == NL80211_BAND_5GHZ) ? 1 : 0;
8638c2ecf20Sopenharmony_ci	u32 val, tx_alc, reg_val;
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	if (is_mt7630(dev))
8668c2ecf20Sopenharmony_ci		return;
8678c2ecf20Sopenharmony_ci
8688c2ecf20Sopenharmony_ci	if (power_on) {
8698c2ecf20Sopenharmony_ci		mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0);
8708c2ecf20Sopenharmony_ci		mt76x02_mcu_calibrate(dev, MCU_CAL_VCO, chan->hw_value);
8718c2ecf20Sopenharmony_ci		usleep_range(10, 20);
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci		if (mt76x0_tssi_enabled(dev)) {
8748c2ecf20Sopenharmony_ci			mt76_wr(dev, MT_MAC_SYS_CTRL,
8758c2ecf20Sopenharmony_ci				MT_MAC_SYS_CTRL_ENABLE_RX);
8768c2ecf20Sopenharmony_ci			mt76x0_phy_tssi_dc_calibrate(dev);
8778c2ecf20Sopenharmony_ci			mt76_wr(dev, MT_MAC_SYS_CTRL,
8788c2ecf20Sopenharmony_ci				MT_MAC_SYS_CTRL_ENABLE_TX |
8798c2ecf20Sopenharmony_ci				MT_MAC_SYS_CTRL_ENABLE_RX);
8808c2ecf20Sopenharmony_ci		}
8818c2ecf20Sopenharmony_ci	}
8828c2ecf20Sopenharmony_ci
8838c2ecf20Sopenharmony_ci	tx_alc = mt76_rr(dev, MT_TX_ALC_CFG_0);
8848c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_TX_ALC_CFG_0, 0);
8858c2ecf20Sopenharmony_ci	usleep_range(500, 700);
8868c2ecf20Sopenharmony_ci
8878c2ecf20Sopenharmony_ci	reg_val = mt76_rr(dev, MT_BBP(IBI, 9));
8888c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(IBI, 9), 0xffffff7e);
8898c2ecf20Sopenharmony_ci
8908c2ecf20Sopenharmony_ci	if (is_5ghz) {
8918c2ecf20Sopenharmony_ci		if (chan->hw_value < 100)
8928c2ecf20Sopenharmony_ci			val = 0x701;
8938c2ecf20Sopenharmony_ci		else if (chan->hw_value < 140)
8948c2ecf20Sopenharmony_ci			val = 0x801;
8958c2ecf20Sopenharmony_ci		else
8968c2ecf20Sopenharmony_ci			val = 0x901;
8978c2ecf20Sopenharmony_ci	} else {
8988c2ecf20Sopenharmony_ci		val = 0x600;
8998c2ecf20Sopenharmony_ci	}
9008c2ecf20Sopenharmony_ci
9018c2ecf20Sopenharmony_ci	mt76x02_mcu_calibrate(dev, MCU_CAL_FULL, val);
9028c2ecf20Sopenharmony_ci	mt76x02_mcu_calibrate(dev, MCU_CAL_LC, is_5ghz);
9038c2ecf20Sopenharmony_ci	usleep_range(15000, 20000);
9048c2ecf20Sopenharmony_ci
9058c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(IBI, 9), reg_val);
9068c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_TX_ALC_CFG_0, tx_alc);
9078c2ecf20Sopenharmony_ci	mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, 1);
9088c2ecf20Sopenharmony_ci}
9098c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mt76x0_phy_calibrate);
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_civoid mt76x0_phy_set_channel(struct mt76x02_dev *dev,
9128c2ecf20Sopenharmony_ci			    struct cfg80211_chan_def *chandef)
9138c2ecf20Sopenharmony_ci{
9148c2ecf20Sopenharmony_ci	u32 ext_cca_chan[4] = {
9158c2ecf20Sopenharmony_ci		[0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
9168c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
9178c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
9188c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
9198c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
9208c2ecf20Sopenharmony_ci		[1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
9218c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
9228c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
9238c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
9248c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
9258c2ecf20Sopenharmony_ci		[2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
9268c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
9278c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
9288c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
9298c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
9308c2ecf20Sopenharmony_ci		[3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
9318c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
9328c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
9338c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
9348c2ecf20Sopenharmony_ci		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
9358c2ecf20Sopenharmony_ci	};
9368c2ecf20Sopenharmony_ci	bool scan = test_bit(MT76_SCANNING, &dev->mphy.state);
9378c2ecf20Sopenharmony_ci	int ch_group_index, freq, freq1;
9388c2ecf20Sopenharmony_ci	u8 channel;
9398c2ecf20Sopenharmony_ci	u32 val;
9408c2ecf20Sopenharmony_ci	u16 rf_bw_band;
9418c2ecf20Sopenharmony_ci
9428c2ecf20Sopenharmony_ci	freq = chandef->chan->center_freq;
9438c2ecf20Sopenharmony_ci	freq1 = chandef->center_freq1;
9448c2ecf20Sopenharmony_ci	channel = chandef->chan->hw_value;
9458c2ecf20Sopenharmony_ci	rf_bw_band = (channel <= 14) ? RF_G_BAND : RF_A_BAND;
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci	switch (chandef->width) {
9488c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_40:
9498c2ecf20Sopenharmony_ci		if (freq1 > freq)
9508c2ecf20Sopenharmony_ci			ch_group_index = 0;
9518c2ecf20Sopenharmony_ci		else
9528c2ecf20Sopenharmony_ci			ch_group_index = 1;
9538c2ecf20Sopenharmony_ci		channel += 2 - ch_group_index * 4;
9548c2ecf20Sopenharmony_ci		rf_bw_band |= RF_BW_40;
9558c2ecf20Sopenharmony_ci		break;
9568c2ecf20Sopenharmony_ci	case NL80211_CHAN_WIDTH_80:
9578c2ecf20Sopenharmony_ci		ch_group_index = (freq - freq1 + 30) / 20;
9588c2ecf20Sopenharmony_ci		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
9598c2ecf20Sopenharmony_ci			ch_group_index = 0;
9608c2ecf20Sopenharmony_ci		channel += 6 - ch_group_index * 4;
9618c2ecf20Sopenharmony_ci		rf_bw_band |= RF_BW_80;
9628c2ecf20Sopenharmony_ci		break;
9638c2ecf20Sopenharmony_ci	default:
9648c2ecf20Sopenharmony_ci		ch_group_index = 0;
9658c2ecf20Sopenharmony_ci		rf_bw_band |= RF_BW_20;
9668c2ecf20Sopenharmony_ci		break;
9678c2ecf20Sopenharmony_ci	}
9688c2ecf20Sopenharmony_ci
9698c2ecf20Sopenharmony_ci	if (mt76_is_usb(&dev->mt76)) {
9708c2ecf20Sopenharmony_ci		mt76x0_phy_bbp_set_bw(dev, chandef->width);
9718c2ecf20Sopenharmony_ci	} else {
9728c2ecf20Sopenharmony_ci		if (chandef->width == NL80211_CHAN_WIDTH_80 ||
9738c2ecf20Sopenharmony_ci		    chandef->width == NL80211_CHAN_WIDTH_40)
9748c2ecf20Sopenharmony_ci			val = 0x201;
9758c2ecf20Sopenharmony_ci		else
9768c2ecf20Sopenharmony_ci			val = 0x601;
9778c2ecf20Sopenharmony_ci		mt76_wr(dev, MT_TX_SW_CFG0, val);
9788c2ecf20Sopenharmony_ci	}
9798c2ecf20Sopenharmony_ci	mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
9808c2ecf20Sopenharmony_ci	mt76x02_phy_set_band(dev, chandef->chan->band,
9818c2ecf20Sopenharmony_ci			     ch_group_index & 1);
9828c2ecf20Sopenharmony_ci
9838c2ecf20Sopenharmony_ci	mt76_rmw(dev, MT_EXT_CCA_CFG,
9848c2ecf20Sopenharmony_ci		 (MT_EXT_CCA_CFG_CCA0 |
9858c2ecf20Sopenharmony_ci		  MT_EXT_CCA_CFG_CCA1 |
9868c2ecf20Sopenharmony_ci		  MT_EXT_CCA_CFG_CCA2 |
9878c2ecf20Sopenharmony_ci		  MT_EXT_CCA_CFG_CCA3 |
9888c2ecf20Sopenharmony_ci		  MT_EXT_CCA_CFG_CCA_MASK),
9898c2ecf20Sopenharmony_ci		 ext_cca_chan[ch_group_index]);
9908c2ecf20Sopenharmony_ci
9918c2ecf20Sopenharmony_ci	mt76x0_phy_set_band(dev, chandef->chan->band);
9928c2ecf20Sopenharmony_ci	mt76x0_phy_set_chan_rf_params(dev, channel, rf_bw_band);
9938c2ecf20Sopenharmony_ci
9948c2ecf20Sopenharmony_ci	/* set Japan Tx filter at channel 14 */
9958c2ecf20Sopenharmony_ci	if (channel == 14)
9968c2ecf20Sopenharmony_ci		mt76_set(dev, MT_BBP(CORE, 1), 0x20);
9978c2ecf20Sopenharmony_ci	else
9988c2ecf20Sopenharmony_ci		mt76_clear(dev, MT_BBP(CORE, 1), 0x20);
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_ci	mt76x0_read_rx_gain(dev);
10018c2ecf20Sopenharmony_ci	mt76x0_phy_set_chan_bbp_params(dev, rf_bw_band);
10028c2ecf20Sopenharmony_ci
10038c2ecf20Sopenharmony_ci	/* enable vco */
10048c2ecf20Sopenharmony_ci	mt76x0_rf_set(dev, MT_RF(0, 4), BIT(7));
10058c2ecf20Sopenharmony_ci	if (scan)
10068c2ecf20Sopenharmony_ci		return;
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci	mt76x02_init_agc_gain(dev);
10098c2ecf20Sopenharmony_ci	mt76x0_phy_calibrate(dev, false);
10108c2ecf20Sopenharmony_ci	mt76x0_phy_set_txpower(dev);
10118c2ecf20Sopenharmony_ci
10128c2ecf20Sopenharmony_ci	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
10138c2ecf20Sopenharmony_ci				     MT_CALIBRATE_INTERVAL);
10148c2ecf20Sopenharmony_ci}
10158c2ecf20Sopenharmony_ci
10168c2ecf20Sopenharmony_cistatic void mt76x0_phy_temp_sensor(struct mt76x02_dev *dev)
10178c2ecf20Sopenharmony_ci{
10188c2ecf20Sopenharmony_ci	u8 rf_b7_73, rf_b0_66, rf_b0_67;
10198c2ecf20Sopenharmony_ci	s8 val;
10208c2ecf20Sopenharmony_ci
10218c2ecf20Sopenharmony_ci	rf_b7_73 = mt76x0_rf_rr(dev, MT_RF(7, 73));
10228c2ecf20Sopenharmony_ci	rf_b0_66 = mt76x0_rf_rr(dev, MT_RF(0, 66));
10238c2ecf20Sopenharmony_ci	rf_b0_67 = mt76x0_rf_rr(dev, MT_RF(0, 67));
10248c2ecf20Sopenharmony_ci
10258c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(7, 73), 0x02);
10268c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(0, 66), 0x23);
10278c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(0, 67), 0x01);
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	mt76_wr(dev, MT_BBP(CORE, 34), 0x00080055);
10308c2ecf20Sopenharmony_ci	if (!mt76_poll_msec(dev, MT_BBP(CORE, 34), BIT(4), 0, 200)) {
10318c2ecf20Sopenharmony_ci		mt76_clear(dev, MT_BBP(CORE, 34), BIT(4));
10328c2ecf20Sopenharmony_ci		goto done;
10338c2ecf20Sopenharmony_ci	}
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci	val = mt76_rr(dev, MT_BBP(CORE, 35));
10368c2ecf20Sopenharmony_ci	val = (35 * (val - dev->cal.rx.temp_offset)) / 10 + 25;
10378c2ecf20Sopenharmony_ci
10388c2ecf20Sopenharmony_ci	if (abs(val - dev->cal.temp_vco) > 20) {
10398c2ecf20Sopenharmony_ci		mt76x02_mcu_calibrate(dev, MCU_CAL_VCO,
10408c2ecf20Sopenharmony_ci				      dev->mphy.chandef.chan->hw_value);
10418c2ecf20Sopenharmony_ci		dev->cal.temp_vco = val;
10428c2ecf20Sopenharmony_ci	}
10438c2ecf20Sopenharmony_ci	if (abs(val - dev->cal.temp) > 30) {
10448c2ecf20Sopenharmony_ci		mt76x0_phy_calibrate(dev, false);
10458c2ecf20Sopenharmony_ci		dev->cal.temp = val;
10468c2ecf20Sopenharmony_ci	}
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_cidone:
10498c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(7, 73), rf_b7_73);
10508c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(0, 66), rf_b0_66);
10518c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(0, 67), rf_b0_67);
10528c2ecf20Sopenharmony_ci}
10538c2ecf20Sopenharmony_ci
10548c2ecf20Sopenharmony_cistatic void mt76x0_phy_set_gain_val(struct mt76x02_dev *dev)
10558c2ecf20Sopenharmony_ci{
10568c2ecf20Sopenharmony_ci	u8 gain = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust;
10578c2ecf20Sopenharmony_ci
10588c2ecf20Sopenharmony_ci	mt76_rmw_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN, gain);
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci	if ((dev->mphy.chandef.chan->flags & IEEE80211_CHAN_RADAR) &&
10618c2ecf20Sopenharmony_ci	    !is_mt7630(dev))
10628c2ecf20Sopenharmony_ci		mt76x02_phy_dfs_adjust_agc(dev);
10638c2ecf20Sopenharmony_ci}
10648c2ecf20Sopenharmony_ci
10658c2ecf20Sopenharmony_cistatic void
10668c2ecf20Sopenharmony_cimt76x0_phy_update_channel_gain(struct mt76x02_dev *dev)
10678c2ecf20Sopenharmony_ci{
10688c2ecf20Sopenharmony_ci	bool gain_change;
10698c2ecf20Sopenharmony_ci	u8 gain_delta;
10708c2ecf20Sopenharmony_ci	int low_gain;
10718c2ecf20Sopenharmony_ci
10728c2ecf20Sopenharmony_ci	dev->cal.avg_rssi_all = mt76_get_min_avg_rssi(&dev->mt76, false);
10738c2ecf20Sopenharmony_ci	if (!dev->cal.avg_rssi_all)
10748c2ecf20Sopenharmony_ci		dev->cal.avg_rssi_all = -75;
10758c2ecf20Sopenharmony_ci
10768c2ecf20Sopenharmony_ci	low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) +
10778c2ecf20Sopenharmony_ci		(dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev));
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_ci	gain_change = dev->cal.low_gain < 0 ||
10808c2ecf20Sopenharmony_ci		      (dev->cal.low_gain & 2) ^ (low_gain & 2);
10818c2ecf20Sopenharmony_ci	dev->cal.low_gain = low_gain;
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	if (!gain_change) {
10848c2ecf20Sopenharmony_ci		if (mt76x02_phy_adjust_vga_gain(dev))
10858c2ecf20Sopenharmony_ci			mt76x0_phy_set_gain_val(dev);
10868c2ecf20Sopenharmony_ci		return;
10878c2ecf20Sopenharmony_ci	}
10888c2ecf20Sopenharmony_ci
10898c2ecf20Sopenharmony_ci	dev->cal.agc_gain_adjust = (low_gain == 2) ? 0 : 10;
10908c2ecf20Sopenharmony_ci	gain_delta = (low_gain == 2) ? 10 : 0;
10918c2ecf20Sopenharmony_ci
10928c2ecf20Sopenharmony_ci	dev->cal.agc_gain_cur[0] = dev->cal.agc_gain_init[0] - gain_delta;
10938c2ecf20Sopenharmony_ci	mt76x0_phy_set_gain_val(dev);
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_ci	/* clear false CCA counters */
10968c2ecf20Sopenharmony_ci	mt76_rr(dev, MT_RX_STAT_1);
10978c2ecf20Sopenharmony_ci}
10988c2ecf20Sopenharmony_ci
10998c2ecf20Sopenharmony_cistatic void mt76x0_phy_calibration_work(struct work_struct *work)
11008c2ecf20Sopenharmony_ci{
11018c2ecf20Sopenharmony_ci	struct mt76x02_dev *dev = container_of(work, struct mt76x02_dev,
11028c2ecf20Sopenharmony_ci					       cal_work.work);
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_ci	mt76x0_phy_update_channel_gain(dev);
11058c2ecf20Sopenharmony_ci	if (mt76x0_tssi_enabled(dev))
11068c2ecf20Sopenharmony_ci		mt76x0_phy_tssi_calibrate(dev);
11078c2ecf20Sopenharmony_ci	else
11088c2ecf20Sopenharmony_ci		mt76x0_phy_temp_sensor(dev);
11098c2ecf20Sopenharmony_ci
11108c2ecf20Sopenharmony_ci	ieee80211_queue_delayed_work(dev->mt76.hw, &dev->cal_work,
11118c2ecf20Sopenharmony_ci				     4 * MT_CALIBRATE_INTERVAL);
11128c2ecf20Sopenharmony_ci}
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_cistatic void mt76x0_rf_patch_reg_array(struct mt76x02_dev *dev,
11158c2ecf20Sopenharmony_ci				      const struct mt76_reg_pair *rp, int len)
11168c2ecf20Sopenharmony_ci{
11178c2ecf20Sopenharmony_ci	int i;
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ci	for (i = 0; i < len; i++) {
11208c2ecf20Sopenharmony_ci		u32 reg = rp[i].reg;
11218c2ecf20Sopenharmony_ci		u8 val = rp[i].value;
11228c2ecf20Sopenharmony_ci
11238c2ecf20Sopenharmony_ci		switch (reg) {
11248c2ecf20Sopenharmony_ci		case MT_RF(0, 3):
11258c2ecf20Sopenharmony_ci			if (mt76_is_mmio(&dev->mt76)) {
11268c2ecf20Sopenharmony_ci				if (is_mt7630(dev))
11278c2ecf20Sopenharmony_ci					val = 0x70;
11288c2ecf20Sopenharmony_ci				else
11298c2ecf20Sopenharmony_ci					val = 0x63;
11308c2ecf20Sopenharmony_ci			} else {
11318c2ecf20Sopenharmony_ci				val = 0x73;
11328c2ecf20Sopenharmony_ci			}
11338c2ecf20Sopenharmony_ci			break;
11348c2ecf20Sopenharmony_ci		case MT_RF(0, 21):
11358c2ecf20Sopenharmony_ci			if (is_mt7610e(dev))
11368c2ecf20Sopenharmony_ci				val = 0x10;
11378c2ecf20Sopenharmony_ci			else
11388c2ecf20Sopenharmony_ci				val = 0x12;
11398c2ecf20Sopenharmony_ci			break;
11408c2ecf20Sopenharmony_ci		case MT_RF(5, 2):
11418c2ecf20Sopenharmony_ci			if (is_mt7630(dev))
11428c2ecf20Sopenharmony_ci				val = 0x1d;
11438c2ecf20Sopenharmony_ci			else if (is_mt7610e(dev))
11448c2ecf20Sopenharmony_ci				val = 0x00;
11458c2ecf20Sopenharmony_ci			else
11468c2ecf20Sopenharmony_ci				val = 0x0c;
11478c2ecf20Sopenharmony_ci			break;
11488c2ecf20Sopenharmony_ci		default:
11498c2ecf20Sopenharmony_ci			break;
11508c2ecf20Sopenharmony_ci		}
11518c2ecf20Sopenharmony_ci		mt76x0_rf_wr(dev, reg, val);
11528c2ecf20Sopenharmony_ci	}
11538c2ecf20Sopenharmony_ci}
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_cistatic void mt76x0_phy_rf_init(struct mt76x02_dev *dev)
11568c2ecf20Sopenharmony_ci{
11578c2ecf20Sopenharmony_ci	int i;
11588c2ecf20Sopenharmony_ci
11598c2ecf20Sopenharmony_ci	mt76x0_rf_patch_reg_array(dev, mt76x0_rf_central_tab,
11608c2ecf20Sopenharmony_ci				  ARRAY_SIZE(mt76x0_rf_central_tab));
11618c2ecf20Sopenharmony_ci	mt76x0_rf_patch_reg_array(dev, mt76x0_rf_2g_channel_0_tab,
11628c2ecf20Sopenharmony_ci				  ARRAY_SIZE(mt76x0_rf_2g_channel_0_tab));
11638c2ecf20Sopenharmony_ci	RF_RANDOM_WRITE(dev, mt76x0_rf_5g_channel_0_tab);
11648c2ecf20Sopenharmony_ci	RF_RANDOM_WRITE(dev, mt76x0_rf_vga_channel_0_tab);
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_rf_bw_switch_tab); i++) {
11678c2ecf20Sopenharmony_ci		const struct mt76x0_rf_switch_item *item = &mt76x0_rf_bw_switch_tab[i];
11688c2ecf20Sopenharmony_ci
11698c2ecf20Sopenharmony_ci		if (item->bw_band == RF_BW_20)
11708c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
11718c2ecf20Sopenharmony_ci		else if (((RF_G_BAND | RF_BW_20) & item->bw_band) ==
11728c2ecf20Sopenharmony_ci			  (RF_G_BAND | RF_BW_20))
11738c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev, item->rf_bank_reg, item->value);
11748c2ecf20Sopenharmony_ci	}
11758c2ecf20Sopenharmony_ci
11768c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mt76x0_rf_band_switch_tab); i++) {
11778c2ecf20Sopenharmony_ci		if (mt76x0_rf_band_switch_tab[i].bw_band & RF_G_BAND) {
11788c2ecf20Sopenharmony_ci			mt76x0_rf_wr(dev,
11798c2ecf20Sopenharmony_ci				     mt76x0_rf_band_switch_tab[i].rf_bank_reg,
11808c2ecf20Sopenharmony_ci				     mt76x0_rf_band_switch_tab[i].value);
11818c2ecf20Sopenharmony_ci		}
11828c2ecf20Sopenharmony_ci	}
11838c2ecf20Sopenharmony_ci
11848c2ecf20Sopenharmony_ci	/* Frequency calibration
11858c2ecf20Sopenharmony_ci	 * E1: B0.R22<6:0>: xo_cxo<6:0>
11868c2ecf20Sopenharmony_ci	 * E2: B0.R21<0>: xo_cxo<0>, B0.R22<7:0>: xo_cxo<8:1>
11878c2ecf20Sopenharmony_ci	 */
11888c2ecf20Sopenharmony_ci	mt76x0_rf_wr(dev, MT_RF(0, 22),
11898c2ecf20Sopenharmony_ci		     min_t(u8, dev->cal.rx.freq_offset, 0xbf));
11908c2ecf20Sopenharmony_ci	mt76x0_rf_rr(dev, MT_RF(0, 22));
11918c2ecf20Sopenharmony_ci
11928c2ecf20Sopenharmony_ci	/* Reset procedure DAC during power-up:
11938c2ecf20Sopenharmony_ci	 * - set B0.R73<7>
11948c2ecf20Sopenharmony_ci	 * - clear B0.R73<7>
11958c2ecf20Sopenharmony_ci	 * - set B0.R73<7>
11968c2ecf20Sopenharmony_ci	 */
11978c2ecf20Sopenharmony_ci	mt76x0_rf_set(dev, MT_RF(0, 73), BIT(7));
11988c2ecf20Sopenharmony_ci	mt76x0_rf_clear(dev, MT_RF(0, 73), BIT(7));
11998c2ecf20Sopenharmony_ci	mt76x0_rf_set(dev, MT_RF(0, 73), BIT(7));
12008c2ecf20Sopenharmony_ci
12018c2ecf20Sopenharmony_ci	/* vcocal_en: initiate VCO calibration (reset after completion)) */
12028c2ecf20Sopenharmony_ci	mt76x0_rf_set(dev, MT_RF(0, 4), 0x80);
12038c2ecf20Sopenharmony_ci}
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_civoid mt76x0_phy_init(struct mt76x02_dev *dev)
12068c2ecf20Sopenharmony_ci{
12078c2ecf20Sopenharmony_ci	INIT_DELAYED_WORK(&dev->cal_work, mt76x0_phy_calibration_work);
12088c2ecf20Sopenharmony_ci
12098c2ecf20Sopenharmony_ci	mt76x0_phy_ant_select(dev);
12108c2ecf20Sopenharmony_ci	mt76x0_phy_rf_init(dev);
12118c2ecf20Sopenharmony_ci	mt76x02_phy_set_rxpath(dev);
12128c2ecf20Sopenharmony_ci	mt76x02_phy_set_txdac(dev);
12138c2ecf20Sopenharmony_ci}
1214