16c92544dSBjoern A. Zeeb // SPDX-License-Identifier: ISC
26c92544dSBjoern A. Zeeb /*
36c92544dSBjoern A. Zeeb  * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
46c92544dSBjoern A. Zeeb  */
56c92544dSBjoern A. Zeeb 
66c92544dSBjoern A. Zeeb #include <linux/delay.h>
76c92544dSBjoern A. Zeeb #include "mt76x2.h"
86c92544dSBjoern A. Zeeb #include "mcu.h"
96c92544dSBjoern A. Zeeb #include "eeprom.h"
106c92544dSBjoern A. Zeeb #include "../mt76x02_phy.h"
116c92544dSBjoern A. Zeeb 
126c92544dSBjoern A. Zeeb static bool
mt76x2_phy_tssi_init_cal(struct mt76x02_dev * dev)136c92544dSBjoern A. Zeeb mt76x2_phy_tssi_init_cal(struct mt76x02_dev *dev)
146c92544dSBjoern A. Zeeb {
156c92544dSBjoern A. Zeeb 	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
166c92544dSBjoern A. Zeeb 	u32 flag = 0;
176c92544dSBjoern A. Zeeb 
186c92544dSBjoern A. Zeeb 	if (!mt76x2_tssi_enabled(dev))
196c92544dSBjoern A. Zeeb 		return false;
206c92544dSBjoern A. Zeeb 
216c92544dSBjoern A. Zeeb 	if (mt76x2_channel_silent(dev))
226c92544dSBjoern A. Zeeb 		return false;
236c92544dSBjoern A. Zeeb 
246c92544dSBjoern A. Zeeb 	if (chan->band == NL80211_BAND_5GHZ)
256c92544dSBjoern A. Zeeb 		flag |= BIT(0);
266c92544dSBjoern A. Zeeb 
276c92544dSBjoern A. Zeeb 	if (mt76x02_ext_pa_enabled(dev, chan->band))
286c92544dSBjoern A. Zeeb 		flag |= BIT(8);
296c92544dSBjoern A. Zeeb 
306c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag);
316c92544dSBjoern A. Zeeb 	dev->cal.tssi_cal_done = true;
326c92544dSBjoern A. Zeeb 	return true;
336c92544dSBjoern A. Zeeb }
346c92544dSBjoern A. Zeeb 
356c92544dSBjoern A. Zeeb static void
mt76x2_phy_channel_calibrate(struct mt76x02_dev * dev,bool mac_stopped)366c92544dSBjoern A. Zeeb mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped)
376c92544dSBjoern A. Zeeb {
386c92544dSBjoern A. Zeeb 	struct ieee80211_channel *chan = dev->mphy.chandef.chan;
396c92544dSBjoern A. Zeeb 	bool is_5ghz = chan->band == NL80211_BAND_5GHZ;
406c92544dSBjoern A. Zeeb 
416c92544dSBjoern A. Zeeb 	if (dev->cal.channel_cal_done)
426c92544dSBjoern A. Zeeb 		return;
436c92544dSBjoern A. Zeeb 
446c92544dSBjoern A. Zeeb 	if (mt76x2_channel_silent(dev))
456c92544dSBjoern A. Zeeb 		return;
466c92544dSBjoern A. Zeeb 
476c92544dSBjoern A. Zeeb 	if (!dev->cal.tssi_cal_done)
486c92544dSBjoern A. Zeeb 		mt76x2_phy_tssi_init_cal(dev);
496c92544dSBjoern A. Zeeb 
506c92544dSBjoern A. Zeeb 	if (!mac_stopped)
516c92544dSBjoern A. Zeeb 		mt76x2_mac_stop(dev, false);
526c92544dSBjoern A. Zeeb 
536c92544dSBjoern A. Zeeb 	if (is_5ghz)
546c92544dSBjoern A. Zeeb 		mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0);
556c92544dSBjoern A. Zeeb 
566c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz);
576c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz);
586c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz);
596c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0);
606c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0);
616c92544dSBjoern A. Zeeb 
626c92544dSBjoern A. Zeeb 	if (!mac_stopped)
636c92544dSBjoern A. Zeeb 		mt76x2_mac_resume(dev);
646c92544dSBjoern A. Zeeb 
656c92544dSBjoern A. Zeeb 	mt76x2_apply_gain_adj(dev);
666c92544dSBjoern A. Zeeb 	mt76x02_edcca_init(dev);
676c92544dSBjoern A. Zeeb 
686c92544dSBjoern A. Zeeb 	dev->cal.channel_cal_done = true;
696c92544dSBjoern A. Zeeb }
706c92544dSBjoern A. Zeeb 
mt76x2_phy_set_antenna(struct mt76x02_dev * dev)716c92544dSBjoern A. Zeeb void mt76x2_phy_set_antenna(struct mt76x02_dev *dev)
726c92544dSBjoern A. Zeeb {
736c92544dSBjoern A. Zeeb 	u32 val;
746c92544dSBjoern A. Zeeb 
756c92544dSBjoern A. Zeeb 	val = mt76_rr(dev, MT_BBP(AGC, 0));
766c92544dSBjoern A. Zeeb 	val &= ~(BIT(4) | BIT(1));
776c92544dSBjoern A. Zeeb 	switch (dev->mphy.antenna_mask) {
786c92544dSBjoern A. Zeeb 	case 1:
796c92544dSBjoern A. Zeeb 		/* disable mac DAC control */
806c92544dSBjoern A. Zeeb 		mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
816c92544dSBjoern A. Zeeb 		mt76_clear(dev, MT_BBP(TXBE, 5), 3);
826c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3);
836c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2);
846c92544dSBjoern A. Zeeb 		/* disable DAC 1 */
856c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4);
866c92544dSBjoern A. Zeeb 
876c92544dSBjoern A. Zeeb 		val &= ~(BIT(3) | BIT(0));
886c92544dSBjoern A. Zeeb 		break;
896c92544dSBjoern A. Zeeb 	case 2:
906c92544dSBjoern A. Zeeb 		/* disable mac DAC control */
916c92544dSBjoern A. Zeeb 		mt76_clear(dev, MT_BBP(IBI, 9), BIT(11));
926c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1);
936c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc);
946c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1);
956c92544dSBjoern A. Zeeb 		/* disable DAC 0 */
966c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1);
976c92544dSBjoern A. Zeeb 
986c92544dSBjoern A. Zeeb 		val &= ~BIT(3);
996c92544dSBjoern A. Zeeb 		val |= BIT(0);
1006c92544dSBjoern A. Zeeb 		break;
1016c92544dSBjoern A. Zeeb 	case 3:
1026c92544dSBjoern A. Zeeb 	default:
1036c92544dSBjoern A. Zeeb 		/* enable mac DAC control */
1046c92544dSBjoern A. Zeeb 		mt76_set(dev, MT_BBP(IBI, 9), BIT(11));
1056c92544dSBjoern A. Zeeb 		mt76_set(dev, MT_BBP(TXBE, 5), 3);
1066c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf);
1076c92544dSBjoern A. Zeeb 		mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20));
1086c92544dSBjoern A. Zeeb 		mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9));
1096c92544dSBjoern A. Zeeb 
1106c92544dSBjoern A. Zeeb 		val &= ~BIT(0);
1116c92544dSBjoern A. Zeeb 		val |= BIT(3);
1126c92544dSBjoern A. Zeeb 		break;
1136c92544dSBjoern A. Zeeb 	}
1146c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_BBP(AGC, 0), val);
1156c92544dSBjoern A. Zeeb }
1166c92544dSBjoern A. Zeeb 
mt76x2_phy_set_channel(struct mt76x02_dev * dev,struct cfg80211_chan_def * chandef)1176c92544dSBjoern A. Zeeb int mt76x2_phy_set_channel(struct mt76x02_dev *dev,
1186c92544dSBjoern A. Zeeb 			   struct cfg80211_chan_def *chandef)
1196c92544dSBjoern A. Zeeb {
1206c92544dSBjoern A. Zeeb 	struct ieee80211_channel *chan = chandef->chan;
1216c92544dSBjoern A. Zeeb 	bool scan = test_bit(MT76_SCANNING, &dev->mphy.state);
1226c92544dSBjoern A. Zeeb 	enum nl80211_band band = chan->band;
1236c92544dSBjoern A. Zeeb 	u8 channel;
1246c92544dSBjoern A. Zeeb 
1256c92544dSBjoern A. Zeeb 	u32 ext_cca_chan[4] = {
1266c92544dSBjoern A. Zeeb 		[0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) |
1276c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) |
1286c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
1296c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
1306c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)),
1316c92544dSBjoern A. Zeeb 		[1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) |
1326c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) |
1336c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) |
1346c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) |
1356c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)),
1366c92544dSBjoern A. Zeeb 		[2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) |
1376c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) |
1386c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
1396c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
1406c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)),
1416c92544dSBjoern A. Zeeb 		[3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) |
1426c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) |
1436c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) |
1446c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) |
1456c92544dSBjoern A. Zeeb 		      FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)),
1466c92544dSBjoern A. Zeeb 	};
1476c92544dSBjoern A. Zeeb 	int ch_group_index;
1486c92544dSBjoern A. Zeeb 	u8 bw, bw_index;
1496c92544dSBjoern A. Zeeb 	int freq, freq1;
1506c92544dSBjoern A. Zeeb 	int ret;
1516c92544dSBjoern A. Zeeb 
1526c92544dSBjoern A. Zeeb 	dev->cal.channel_cal_done = false;
1536c92544dSBjoern A. Zeeb 	freq = chandef->chan->center_freq;
1546c92544dSBjoern A. Zeeb 	freq1 = chandef->center_freq1;
1556c92544dSBjoern A. Zeeb 	channel = chan->hw_value;
1566c92544dSBjoern A. Zeeb 
1576c92544dSBjoern A. Zeeb 	switch (chandef->width) {
1586c92544dSBjoern A. Zeeb 	case NL80211_CHAN_WIDTH_40:
1596c92544dSBjoern A. Zeeb 		bw = 1;
1606c92544dSBjoern A. Zeeb 		if (freq1 > freq) {
1616c92544dSBjoern A. Zeeb 			bw_index = 1;
1626c92544dSBjoern A. Zeeb 			ch_group_index = 0;
1636c92544dSBjoern A. Zeeb 		} else {
1646c92544dSBjoern A. Zeeb 			bw_index = 3;
1656c92544dSBjoern A. Zeeb 			ch_group_index = 1;
1666c92544dSBjoern A. Zeeb 		}
1676c92544dSBjoern A. Zeeb 		channel += 2 - ch_group_index * 4;
1686c92544dSBjoern A. Zeeb 		break;
1696c92544dSBjoern A. Zeeb 	case NL80211_CHAN_WIDTH_80:
1706c92544dSBjoern A. Zeeb 		ch_group_index = (freq - freq1 + 30) / 20;
1716c92544dSBjoern A. Zeeb 		if (WARN_ON(ch_group_index < 0 || ch_group_index > 3))
1726c92544dSBjoern A. Zeeb 			ch_group_index = 0;
1736c92544dSBjoern A. Zeeb 		bw = 2;
1746c92544dSBjoern A. Zeeb 		bw_index = ch_group_index;
1756c92544dSBjoern A. Zeeb 		channel += 6 - ch_group_index * 4;
1766c92544dSBjoern A. Zeeb 		break;
1776c92544dSBjoern A. Zeeb 	default:
1786c92544dSBjoern A. Zeeb 		bw = 0;
1796c92544dSBjoern A. Zeeb 		bw_index = 0;
1806c92544dSBjoern A. Zeeb 		ch_group_index = 0;
1816c92544dSBjoern A. Zeeb 		break;
1826c92544dSBjoern A. Zeeb 	}
1836c92544dSBjoern A. Zeeb 
1846c92544dSBjoern A. Zeeb 	mt76x2_read_rx_gain(dev);
1856c92544dSBjoern A. Zeeb 	mt76x2_phy_set_txpower_regs(dev, band);
1866c92544dSBjoern A. Zeeb 	mt76x2_configure_tx_delay(dev, band, bw);
1876c92544dSBjoern A. Zeeb 	mt76x2_phy_set_txpower(dev);
1886c92544dSBjoern A. Zeeb 
1896c92544dSBjoern A. Zeeb 	mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1);
1906c92544dSBjoern A. Zeeb 	mt76x02_phy_set_bw(dev, chandef->width, ch_group_index);
1916c92544dSBjoern A. Zeeb 
1926c92544dSBjoern A. Zeeb 	mt76_rmw(dev, MT_EXT_CCA_CFG,
1936c92544dSBjoern A. Zeeb 		 (MT_EXT_CCA_CFG_CCA0 |
1946c92544dSBjoern A. Zeeb 		  MT_EXT_CCA_CFG_CCA1 |
1956c92544dSBjoern A. Zeeb 		  MT_EXT_CCA_CFG_CCA2 |
1966c92544dSBjoern A. Zeeb 		  MT_EXT_CCA_CFG_CCA3 |
1976c92544dSBjoern A. Zeeb 		  MT_EXT_CCA_CFG_CCA_MASK),
1986c92544dSBjoern A. Zeeb 		 ext_cca_chan[ch_group_index]);
1996c92544dSBjoern A. Zeeb 
2006c92544dSBjoern A. Zeeb 	ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan);
2016c92544dSBjoern A. Zeeb 	if (ret)
2026c92544dSBjoern A. Zeeb 		return ret;
2036c92544dSBjoern A. Zeeb 
2046c92544dSBjoern A. Zeeb 	mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true);
2056c92544dSBjoern A. Zeeb 
2066c92544dSBjoern A. Zeeb 	mt76x2_phy_set_antenna(dev);
2076c92544dSBjoern A. Zeeb 
2086c92544dSBjoern A. Zeeb 	/* Enable LDPC Rx */
2096c92544dSBjoern A. Zeeb 	if (mt76xx_rev(dev) >= MT76XX_REV_E3)
2106c92544dSBjoern A. Zeeb 		mt76_set(dev, MT_BBP(RXO, 13), BIT(10));
2116c92544dSBjoern A. Zeeb 
2126c92544dSBjoern A. Zeeb 	if (!dev->cal.init_cal_done) {
2136c92544dSBjoern A. Zeeb 		u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT);
2146c92544dSBjoern A. Zeeb 
2156c92544dSBjoern A. Zeeb 		if (val != 0xff)
2166c92544dSBjoern A. Zeeb 			mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0);
2176c92544dSBjoern A. Zeeb 	}
2186c92544dSBjoern A. Zeeb 
2196c92544dSBjoern A. Zeeb 	mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel);
2206c92544dSBjoern A. Zeeb 
2216c92544dSBjoern A. Zeeb 	/* Rx LPF calibration */
2226c92544dSBjoern A. Zeeb 	if (!dev->cal.init_cal_done)
2236c92544dSBjoern A. Zeeb 		mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0);
2246c92544dSBjoern A. Zeeb 
2256c92544dSBjoern A. Zeeb 	dev->cal.init_cal_done = true;
2266c92544dSBjoern A. Zeeb 
2276c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2);
2286c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010);
2296c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404);
2306c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070);
2316c92544dSBjoern A. Zeeb 	mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F);
2326c92544dSBjoern A. Zeeb 
2336c92544dSBjoern A. Zeeb 	if (scan)
2346c92544dSBjoern A. Zeeb 		return 0;
2356c92544dSBjoern A. Zeeb 
2366c92544dSBjoern A. Zeeb 	mt76x2_phy_channel_calibrate(dev, true);
2376c92544dSBjoern A. Zeeb 	mt76x02_init_agc_gain(dev);
2386c92544dSBjoern A. Zeeb 
2396c92544dSBjoern A. Zeeb 	/* init default values for temp compensation */
2406c92544dSBjoern A. Zeeb 	if (mt76x2_tssi_enabled(dev)) {
2416c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
2426c92544dSBjoern A. Zeeb 			       0x38);
2436c92544dSBjoern A. Zeeb 		mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
2446c92544dSBjoern A. Zeeb 			       0x38);
2456c92544dSBjoern A. Zeeb 	}
2466c92544dSBjoern A. Zeeb 
2476c92544dSBjoern A. Zeeb 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
2486c92544dSBjoern A. Zeeb 				     MT_CALIBRATE_INTERVAL);
2496c92544dSBjoern A. Zeeb 
2506c92544dSBjoern A. Zeeb 	return 0;
2516c92544dSBjoern A. Zeeb }
2526c92544dSBjoern A. Zeeb 
2536c92544dSBjoern A. Zeeb static void
mt76x2_phy_temp_compensate(struct mt76x02_dev * dev)2546c92544dSBjoern A. Zeeb mt76x2_phy_temp_compensate(struct mt76x02_dev *dev)
2556c92544dSBjoern A. Zeeb {
2566c92544dSBjoern A. Zeeb 	struct mt76x2_temp_comp t;
2576c92544dSBjoern A. Zeeb 	int temp, db_diff;
2586c92544dSBjoern A. Zeeb 
2596c92544dSBjoern A. Zeeb 	if (mt76x2_get_temp_comp(dev, &t))
2606c92544dSBjoern A. Zeeb 		return;
2616c92544dSBjoern A. Zeeb 
2626c92544dSBjoern A. Zeeb 	temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL);
2636c92544dSBjoern A. Zeeb 	temp -= t.temp_25_ref;
2646c92544dSBjoern A. Zeeb 	temp = (temp * 1789) / 1000 + 25;
2656c92544dSBjoern A. Zeeb 	dev->cal.temp = temp;
2666c92544dSBjoern A. Zeeb 
2676c92544dSBjoern A. Zeeb 	if (temp > 25)
2686c92544dSBjoern A. Zeeb 		db_diff = (temp - 25) / t.high_slope;
2696c92544dSBjoern A. Zeeb 	else
2706c92544dSBjoern A. Zeeb 		db_diff = (25 - temp) / t.low_slope;
2716c92544dSBjoern A. Zeeb 
2726c92544dSBjoern A. Zeeb 	db_diff = min(db_diff, t.upper_bound);
2736c92544dSBjoern A. Zeeb 	db_diff = max(db_diff, t.lower_bound);
2746c92544dSBjoern A. Zeeb 
2756c92544dSBjoern A. Zeeb 	mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP,
2766c92544dSBjoern A. Zeeb 		       db_diff * 2);
2776c92544dSBjoern A. Zeeb 	mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP,
2786c92544dSBjoern A. Zeeb 		       db_diff * 2);
2796c92544dSBjoern A. Zeeb }
2806c92544dSBjoern A. Zeeb 
mt76x2_phy_calibrate(struct work_struct * work)2816c92544dSBjoern A. Zeeb void mt76x2_phy_calibrate(struct work_struct *work)
2826c92544dSBjoern A. Zeeb {
2836c92544dSBjoern A. Zeeb 	struct mt76x02_dev *dev;
2846c92544dSBjoern A. Zeeb 
2856c92544dSBjoern A. Zeeb 	dev = container_of(work, struct mt76x02_dev, cal_work.work);
2866c92544dSBjoern A. Zeeb 
2876c92544dSBjoern A. Zeeb 	mutex_lock(&dev->mt76.mutex);
2886c92544dSBjoern A. Zeeb 
2896c92544dSBjoern A. Zeeb 	mt76x2_phy_channel_calibrate(dev, false);
2906c92544dSBjoern A. Zeeb 	mt76x2_phy_tssi_compensate(dev);
2916c92544dSBjoern A. Zeeb 	mt76x2_phy_temp_compensate(dev);
2926c92544dSBjoern A. Zeeb 	mt76x2_phy_update_channel_gain(dev);
2936c92544dSBjoern A. Zeeb 
2946c92544dSBjoern A. Zeeb 	mutex_unlock(&dev->mt76.mutex);
2956c92544dSBjoern A. Zeeb 
2966c92544dSBjoern A. Zeeb 	ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work,
2976c92544dSBjoern A. Zeeb 				     MT_CALIBRATE_INTERVAL);
2986c92544dSBjoern A. Zeeb }
2996c92544dSBjoern A. Zeeb 
mt76x2_phy_start(struct mt76x02_dev * dev)3006c92544dSBjoern A. Zeeb int mt76x2_phy_start(struct mt76x02_dev *dev)
3016c92544dSBjoern A. Zeeb {
3026c92544dSBjoern A. Zeeb 	int ret;
3036c92544dSBjoern A. Zeeb 
3046c92544dSBjoern A. Zeeb 	ret = mt76x02_mcu_set_radio_state(dev, true);
3056c92544dSBjoern A. Zeeb 	if (ret)
3066c92544dSBjoern A. Zeeb 		return ret;
3076c92544dSBjoern A. Zeeb 
3086c92544dSBjoern A. Zeeb 	mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0);
3096c92544dSBjoern A. Zeeb 
3106c92544dSBjoern A. Zeeb 	return ret;
3116c92544dSBjoern A. Zeeb }
312