1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> 4 */ 5 6 #include "mt76x2u.h" 7 #include "eeprom.h" 8 #include "../mt76x02_phy.h" 9 10 static void 11 mt76x2u_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped) 12 { 13 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 14 bool is_5ghz = chan->band == NL80211_BAND_5GHZ; 15 16 if (dev->cal.channel_cal_done) 17 return; 18 19 if (mt76x2_channel_silent(dev)) 20 return; 21 22 if (!mac_stopped) 23 mt76x2u_mac_stop(dev); 24 25 if (is_5ghz) 26 mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0); 27 28 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); 29 mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); 30 mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); 31 mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); 32 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0); 33 34 if (!mac_stopped) 35 mt76x2_mac_resume(dev); 36 mt76x2_apply_gain_adj(dev); 37 mt76x02_edcca_init(dev); 38 39 dev->cal.channel_cal_done = true; 40 } 41 42 void mt76x2u_phy_calibrate(struct work_struct *work) 43 { 44 struct mt76x02_dev *dev; 45 46 dev = container_of(work, struct mt76x02_dev, cal_work.work); 47 48 mutex_lock(&dev->mt76.mutex); 49 50 mt76x2u_phy_channel_calibrate(dev, false); 51 mt76x2_phy_tssi_compensate(dev); 52 mt76x2_phy_update_channel_gain(dev); 53 54 mutex_unlock(&dev->mt76.mutex); 55 56 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 57 MT_CALIBRATE_INTERVAL); 58 } 59 60 int mt76x2u_phy_set_channel(struct mt76x02_dev *dev, 61 struct cfg80211_chan_def *chandef) 62 { 63 u32 ext_cca_chan[4] = { 64 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | 65 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | 66 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 67 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 68 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), 69 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | 70 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | 71 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 72 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 73 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), 74 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | 75 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | 76 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 77 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 78 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), 79 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | 80 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | 81 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 82 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 83 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), 84 }; 85 bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); 86 struct ieee80211_channel *chan = chandef->chan; 87 u8 channel = chan->hw_value, bw, bw_index; 88 int ch_group_index, freq, freq1, ret; 89 90 dev->cal.channel_cal_done = false; 91 freq = chandef->chan->center_freq; 92 freq1 = chandef->center_freq1; 93 94 switch (chandef->width) { 95 case NL80211_CHAN_WIDTH_40: 96 bw = 1; 97 if (freq1 > freq) { 98 bw_index = 1; 99 ch_group_index = 0; 100 } else { 101 bw_index = 3; 102 ch_group_index = 1; 103 } 104 channel += 2 - ch_group_index * 4; 105 break; 106 case NL80211_CHAN_WIDTH_80: 107 ch_group_index = (freq - freq1 + 30) / 20; 108 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) 109 ch_group_index = 0; 110 bw = 2; 111 bw_index = ch_group_index; 112 channel += 6 - ch_group_index * 4; 113 break; 114 default: 115 bw = 0; 116 bw_index = 0; 117 ch_group_index = 0; 118 break; 119 } 120 121 mt76x2_read_rx_gain(dev); 122 mt76x2_phy_set_txpower_regs(dev, chan->band); 123 mt76x2_configure_tx_delay(dev, chan->band, bw); 124 mt76x2_phy_set_txpower(dev); 125 126 mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); 127 mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); 128 129 mt76_rmw(dev, MT_EXT_CCA_CFG, 130 (MT_EXT_CCA_CFG_CCA0 | 131 MT_EXT_CCA_CFG_CCA1 | 132 MT_EXT_CCA_CFG_CCA2 | 133 MT_EXT_CCA_CFG_CCA3 | 134 MT_EXT_CCA_CFG_CCA_MASK), 135 ext_cca_chan[ch_group_index]); 136 137 ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); 138 if (ret) 139 return ret; 140 141 mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); 142 143 /* Enable LDPC Rx */ 144 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 145 mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); 146 147 if (!dev->cal.init_cal_done) { 148 u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); 149 150 if (val != 0xff) 151 mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0); 152 } 153 154 mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); 155 156 /* Rx LPF calibration */ 157 if (!dev->cal.init_cal_done) 158 mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0); 159 dev->cal.init_cal_done = true; 160 161 mt76_wr(dev, MT_BBP(AGC, 61), 0xff64a4e2); 162 mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); 163 mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); 164 mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); 165 mt76_wr(dev, MT_TXOP_CTRL_CFG, 0X04101b3f); 166 167 mt76_set(dev, MT_BBP(TXO, 4), BIT(25)); 168 mt76_set(dev, MT_BBP(RXO, 13), BIT(8)); 169 170 if (scan) 171 return 0; 172 173 mt76x2u_phy_channel_calibrate(dev, true); 174 mt76x02_init_agc_gain(dev); 175 176 if (mt76x2_tssi_enabled(dev)) { 177 /* init default values for temp compensation */ 178 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 179 0x38); 180 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 181 0x38); 182 183 /* init tssi calibration */ 184 if (!mt76x2_channel_silent(dev)) { 185 struct ieee80211_channel *chan; 186 u32 flag = 0; 187 188 chan = dev->mt76.chandef.chan; 189 if (chan->band == NL80211_BAND_5GHZ) 190 flag |= BIT(0); 191 if (mt76x02_ext_pa_enabled(dev, chan->band)) 192 flag |= BIT(8); 193 mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag); 194 dev->cal.tssi_cal_done = true; 195 } 196 } 197 198 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 199 MT_CALIBRATE_INTERVAL); 200 return 0; 201 } 202