1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 */ 5 6 #include <linux/delay.h> 7 #include "mt76x2.h" 8 #include "mcu.h" 9 #include "eeprom.h" 10 #include "../mt76x02_phy.h" 11 12 static bool 13 mt76x2_phy_tssi_init_cal(struct mt76x02_dev *dev) 14 { 15 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 16 u32 flag = 0; 17 18 if (!mt76x2_tssi_enabled(dev)) 19 return false; 20 21 if (mt76x2_channel_silent(dev)) 22 return false; 23 24 if (chan->band == NL80211_BAND_5GHZ) 25 flag |= BIT(0); 26 27 if (mt76x02_ext_pa_enabled(dev, chan->band)) 28 flag |= BIT(8); 29 30 mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag); 31 dev->cal.tssi_cal_done = true; 32 return true; 33 } 34 35 static void 36 mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped) 37 { 38 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 39 bool is_5ghz = chan->band == NL80211_BAND_5GHZ; 40 41 if (dev->cal.channel_cal_done) 42 return; 43 44 if (mt76x2_channel_silent(dev)) 45 return; 46 47 if (!dev->cal.tssi_cal_done) 48 mt76x2_phy_tssi_init_cal(dev); 49 50 if (!mac_stopped) 51 mt76x2_mac_stop(dev, false); 52 53 if (is_5ghz) 54 mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0); 55 56 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); 57 mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); 58 mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); 59 mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); 60 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0); 61 62 if (!mac_stopped) 63 mt76x2_mac_resume(dev); 64 65 mt76x2_apply_gain_adj(dev); 66 mt76x02_edcca_init(dev); 67 68 dev->cal.channel_cal_done = true; 69 } 70 71 void mt76x2_phy_set_antenna(struct mt76x02_dev *dev) 72 { 73 u32 val; 74 75 val = mt76_rr(dev, MT_BBP(AGC, 0)); 76 val &= ~(BIT(4) | BIT(1)); 77 switch (dev->mt76.antenna_mask) { 78 case 1: 79 /* disable mac DAC control */ 80 mt76_clear(dev, MT_BBP(IBI, 9), BIT(11)); 81 mt76_clear(dev, MT_BBP(TXBE, 5), 3); 82 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3); 83 mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2); 84 /* disable DAC 1 */ 85 mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4); 86 87 val &= ~(BIT(3) | BIT(0)); 88 break; 89 case 2: 90 /* disable mac DAC control */ 91 mt76_clear(dev, MT_BBP(IBI, 9), BIT(11)); 92 mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1); 93 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc); 94 mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1); 95 /* disable DAC 0 */ 96 mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1); 97 98 val &= ~BIT(3); 99 val |= BIT(0); 100 break; 101 case 3: 102 default: 103 /* enable mac DAC control */ 104 mt76_set(dev, MT_BBP(IBI, 9), BIT(11)); 105 mt76_set(dev, MT_BBP(TXBE, 5), 3); 106 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf); 107 mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20)); 108 mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9)); 109 110 val &= ~BIT(0); 111 val |= BIT(3); 112 break; 113 } 114 mt76_wr(dev, MT_BBP(AGC, 0), val); 115 } 116 117 int mt76x2_phy_set_channel(struct mt76x02_dev *dev, 118 struct cfg80211_chan_def *chandef) 119 { 120 struct ieee80211_channel *chan = chandef->chan; 121 bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); 122 enum nl80211_band band = chan->band; 123 u8 channel; 124 125 u32 ext_cca_chan[4] = { 126 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | 127 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | 128 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 129 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 130 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), 131 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | 132 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | 133 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 134 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 135 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), 136 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | 137 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | 138 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 139 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 140 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), 141 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | 142 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | 143 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 144 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 145 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), 146 }; 147 int ch_group_index; 148 u8 bw, bw_index; 149 int freq, freq1; 150 int ret; 151 152 dev->cal.channel_cal_done = false; 153 freq = chandef->chan->center_freq; 154 freq1 = chandef->center_freq1; 155 channel = chan->hw_value; 156 157 switch (chandef->width) { 158 case NL80211_CHAN_WIDTH_40: 159 bw = 1; 160 if (freq1 > freq) { 161 bw_index = 1; 162 ch_group_index = 0; 163 } else { 164 bw_index = 3; 165 ch_group_index = 1; 166 } 167 channel += 2 - ch_group_index * 4; 168 break; 169 case NL80211_CHAN_WIDTH_80: 170 ch_group_index = (freq - freq1 + 30) / 20; 171 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) 172 ch_group_index = 0; 173 bw = 2; 174 bw_index = ch_group_index; 175 channel += 6 - ch_group_index * 4; 176 break; 177 default: 178 bw = 0; 179 bw_index = 0; 180 ch_group_index = 0; 181 break; 182 } 183 184 mt76x2_read_rx_gain(dev); 185 mt76x2_phy_set_txpower_regs(dev, band); 186 mt76x2_configure_tx_delay(dev, band, bw); 187 mt76x2_phy_set_txpower(dev); 188 189 mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); 190 mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); 191 192 mt76_rmw(dev, MT_EXT_CCA_CFG, 193 (MT_EXT_CCA_CFG_CCA0 | 194 MT_EXT_CCA_CFG_CCA1 | 195 MT_EXT_CCA_CFG_CCA2 | 196 MT_EXT_CCA_CFG_CCA3 | 197 MT_EXT_CCA_CFG_CCA_MASK), 198 ext_cca_chan[ch_group_index]); 199 200 ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); 201 if (ret) 202 return ret; 203 204 mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); 205 206 mt76x2_phy_set_antenna(dev); 207 208 /* Enable LDPC Rx */ 209 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 210 mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); 211 212 if (!dev->cal.init_cal_done) { 213 u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); 214 215 if (val != 0xff) 216 mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0); 217 } 218 219 mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); 220 221 /* Rx LPF calibration */ 222 if (!dev->cal.init_cal_done) 223 mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0); 224 225 dev->cal.init_cal_done = true; 226 227 mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2); 228 mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); 229 mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); 230 mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); 231 mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F); 232 233 if (scan) 234 return 0; 235 236 mt76x2_phy_channel_calibrate(dev, true); 237 mt76x02_init_agc_gain(dev); 238 239 /* init default values for temp compensation */ 240 if (mt76x2_tssi_enabled(dev)) { 241 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 242 0x38); 243 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 244 0x38); 245 } 246 247 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 248 MT_CALIBRATE_INTERVAL); 249 250 return 0; 251 } 252 253 static void 254 mt76x2_phy_temp_compensate(struct mt76x02_dev *dev) 255 { 256 struct mt76x2_temp_comp t; 257 int temp, db_diff; 258 259 if (mt76x2_get_temp_comp(dev, &t)) 260 return; 261 262 temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL); 263 temp -= t.temp_25_ref; 264 temp = (temp * 1789) / 1000 + 25; 265 dev->cal.temp = temp; 266 267 if (temp > 25) 268 db_diff = (temp - 25) / t.high_slope; 269 else 270 db_diff = (25 - temp) / t.low_slope; 271 272 db_diff = min(db_diff, t.upper_bound); 273 db_diff = max(db_diff, t.lower_bound); 274 275 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 276 db_diff * 2); 277 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 278 db_diff * 2); 279 } 280 281 void mt76x2_phy_calibrate(struct work_struct *work) 282 { 283 struct mt76x02_dev *dev; 284 285 dev = container_of(work, struct mt76x02_dev, cal_work.work); 286 287 mutex_lock(&dev->mt76.mutex); 288 289 mt76x2_phy_channel_calibrate(dev, false); 290 mt76x2_phy_tssi_compensate(dev); 291 mt76x2_phy_temp_compensate(dev); 292 mt76x2_phy_update_channel_gain(dev); 293 294 mutex_unlock(&dev->mt76.mutex); 295 296 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 297 MT_CALIBRATE_INTERVAL); 298 } 299 300 int mt76x2_phy_start(struct mt76x02_dev *dev) 301 { 302 int ret; 303 304 ret = mt76x02_mcu_set_radio_state(dev, true); 305 if (ret) 306 return ret; 307 308 mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); 309 310 return ret; 311 } 312