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