1 /* 2 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include <linux/delay.h> 18 #include "mt76x2.h" 19 #include "mcu.h" 20 #include "eeprom.h" 21 #include "../mt76x02_phy.h" 22 23 static bool 24 mt76x2_phy_tssi_init_cal(struct mt76x02_dev *dev) 25 { 26 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 27 u32 flag = 0; 28 29 if (!mt76x2_tssi_enabled(dev)) 30 return false; 31 32 if (mt76x2_channel_silent(dev)) 33 return false; 34 35 if (chan->band == NL80211_BAND_5GHZ) 36 flag |= BIT(0); 37 38 if (mt76x02_ext_pa_enabled(dev, chan->band)) 39 flag |= BIT(8); 40 41 mt76x02_mcu_calibrate(dev, MCU_CAL_TSSI, flag, true); 42 dev->cal.tssi_cal_done = true; 43 return true; 44 } 45 46 static void 47 mt76x2_phy_channel_calibrate(struct mt76x02_dev *dev, bool mac_stopped) 48 { 49 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 50 bool is_5ghz = chan->band == NL80211_BAND_5GHZ; 51 52 if (dev->cal.channel_cal_done) 53 return; 54 55 if (mt76x2_channel_silent(dev)) 56 return; 57 58 if (!dev->cal.tssi_cal_done) 59 mt76x2_phy_tssi_init_cal(dev); 60 61 if (!mac_stopped) 62 mt76x2_mac_stop(dev, false); 63 64 if (is_5ghz) 65 mt76x02_mcu_calibrate(dev, MCU_CAL_LC, 0, true); 66 67 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz, true); 68 mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz, true); 69 mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz, true); 70 mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0, true); 71 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0, true); 72 73 if (!mac_stopped) 74 mt76x2_mac_resume(dev); 75 76 mt76x2_apply_gain_adj(dev); 77 78 dev->cal.channel_cal_done = true; 79 } 80 81 void mt76x2_phy_set_antenna(struct mt76x02_dev *dev) 82 { 83 u32 val; 84 85 val = mt76_rr(dev, MT_BBP(AGC, 0)); 86 val &= ~(BIT(4) | BIT(1)); 87 switch (dev->mt76.antenna_mask) { 88 case 1: 89 /* disable mac DAC control */ 90 mt76_clear(dev, MT_BBP(IBI, 9), BIT(11)); 91 mt76_clear(dev, MT_BBP(TXBE, 5), 3); 92 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0x3); 93 mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 2); 94 /* disable DAC 1 */ 95 mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 4); 96 97 val &= ~(BIT(3) | BIT(0)); 98 break; 99 case 2: 100 /* disable mac DAC control */ 101 mt76_clear(dev, MT_BBP(IBI, 9), BIT(11)); 102 mt76_rmw_field(dev, MT_BBP(TXBE, 5), 3, 1); 103 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xc); 104 mt76_rmw_field(dev, MT_BBP(CORE, 32), GENMASK(21, 20), 1); 105 /* disable DAC 0 */ 106 mt76_rmw_field(dev, MT_BBP(CORE, 33), GENMASK(12, 9), 1); 107 108 val &= ~BIT(3); 109 val |= BIT(0); 110 break; 111 case 3: 112 default: 113 /* enable mac DAC control */ 114 mt76_set(dev, MT_BBP(IBI, 9), BIT(11)); 115 mt76_set(dev, MT_BBP(TXBE, 5), 3); 116 mt76_rmw_field(dev, MT_TX_PIN_CFG, MT_TX_PIN_CFG_TXANT, 0xf); 117 mt76_clear(dev, MT_BBP(CORE, 32), GENMASK(21, 20)); 118 mt76_clear(dev, MT_BBP(CORE, 33), GENMASK(12, 9)); 119 120 val &= ~BIT(0); 121 val |= BIT(3); 122 break; 123 } 124 mt76_wr(dev, MT_BBP(AGC, 0), val); 125 } 126 127 static void 128 mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) 129 { 130 u32 val; 131 u8 gain_val[2]; 132 133 gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust; 134 gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust; 135 136 if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40) 137 val = 0x1e42 << 16; 138 else 139 val = 0x1836 << 16; 140 141 val |= 0xf8; 142 143 mt76_wr(dev, MT_BBP(AGC, 8), 144 val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0])); 145 mt76_wr(dev, MT_BBP(AGC, 9), 146 val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1])); 147 148 if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) 149 mt76x2_dfs_adjust_agc(dev); 150 } 151 152 static void 153 mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) 154 { 155 u8 *gain = dev->cal.agc_gain_init; 156 u8 low_gain_delta, gain_delta; 157 bool gain_change; 158 int low_gain; 159 u32 val; 160 161 dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(dev); 162 163 low_gain = (dev->cal.avg_rssi_all > mt76x02_get_rssi_gain_thresh(dev)) + 164 (dev->cal.avg_rssi_all > mt76x02_get_low_rssi_gain_thresh(dev)); 165 166 gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2); 167 dev->cal.low_gain = low_gain; 168 169 if (!gain_change) { 170 if (mt76x02_phy_adjust_vga_gain(dev)) 171 mt76x2_phy_set_gain_val(dev); 172 return; 173 } 174 175 if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) { 176 mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211); 177 val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf; 178 if (low_gain == 2) 179 val |= 0x3; 180 else 181 val |= 0x5; 182 mt76_wr(dev, MT_BBP(AGC, 26), val); 183 } else { 184 mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423); 185 } 186 187 if (mt76x2_has_ext_lna(dev)) 188 low_gain_delta = 10; 189 else 190 low_gain_delta = 14; 191 192 if (low_gain == 2) { 193 mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990); 194 mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808); 195 mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808); 196 gain_delta = low_gain_delta; 197 dev->cal.agc_gain_adjust = 0; 198 } else { 199 mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991); 200 if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) 201 mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014); 202 else 203 mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116); 204 mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C); 205 gain_delta = 0; 206 dev->cal.agc_gain_adjust = low_gain_delta; 207 } 208 209 dev->cal.agc_gain_cur[0] = gain[0] - gain_delta; 210 dev->cal.agc_gain_cur[1] = gain[1] - gain_delta; 211 mt76x2_phy_set_gain_val(dev); 212 213 /* clear false CCA counters */ 214 mt76_rr(dev, MT_RX_STAT_1); 215 } 216 217 int mt76x2_phy_set_channel(struct mt76x02_dev *dev, 218 struct cfg80211_chan_def *chandef) 219 { 220 struct ieee80211_channel *chan = chandef->chan; 221 bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); 222 enum nl80211_band band = chan->band; 223 u8 channel; 224 225 u32 ext_cca_chan[4] = { 226 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | 227 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | 228 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 229 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 230 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), 231 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | 232 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | 233 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 234 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 235 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), 236 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | 237 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | 238 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 239 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 240 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), 241 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | 242 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | 243 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 244 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 245 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), 246 }; 247 int ch_group_index; 248 u8 bw, bw_index; 249 int freq, freq1; 250 int ret; 251 252 dev->cal.channel_cal_done = false; 253 freq = chandef->chan->center_freq; 254 freq1 = chandef->center_freq1; 255 channel = chan->hw_value; 256 257 switch (chandef->width) { 258 case NL80211_CHAN_WIDTH_40: 259 bw = 1; 260 if (freq1 > freq) { 261 bw_index = 1; 262 ch_group_index = 0; 263 } else { 264 bw_index = 3; 265 ch_group_index = 1; 266 } 267 channel += 2 - ch_group_index * 4; 268 break; 269 case NL80211_CHAN_WIDTH_80: 270 ch_group_index = (freq - freq1 + 30) / 20; 271 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) 272 ch_group_index = 0; 273 bw = 2; 274 bw_index = ch_group_index; 275 channel += 6 - ch_group_index * 4; 276 break; 277 default: 278 bw = 0; 279 bw_index = 0; 280 ch_group_index = 0; 281 break; 282 } 283 284 mt76x2_read_rx_gain(dev); 285 mt76x2_phy_set_txpower_regs(dev, band); 286 mt76x2_configure_tx_delay(dev, band, bw); 287 mt76x2_phy_set_txpower(dev); 288 289 mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); 290 mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); 291 292 mt76_rmw(dev, MT_EXT_CCA_CFG, 293 (MT_EXT_CCA_CFG_CCA0 | 294 MT_EXT_CCA_CFG_CCA1 | 295 MT_EXT_CCA_CFG_CCA2 | 296 MT_EXT_CCA_CFG_CCA3 | 297 MT_EXT_CCA_CFG_CCA_MASK), 298 ext_cca_chan[ch_group_index]); 299 300 ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); 301 if (ret) 302 return ret; 303 304 mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); 305 306 mt76x2_phy_set_antenna(dev); 307 308 /* Enable LDPC Rx */ 309 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 310 mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); 311 312 if (!dev->cal.init_cal_done) { 313 u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); 314 315 if (val != 0xff) 316 mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0, true); 317 } 318 319 mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel, true); 320 321 /* Rx LPF calibration */ 322 if (!dev->cal.init_cal_done) 323 mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0, true); 324 325 dev->cal.init_cal_done = true; 326 327 mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2); 328 mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); 329 mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); 330 mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); 331 mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F); 332 333 if (scan) 334 return 0; 335 336 mt76x2_phy_channel_calibrate(dev, true); 337 mt76x02_init_agc_gain(dev); 338 339 /* init default values for temp compensation */ 340 if (mt76x2_tssi_enabled(dev)) { 341 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 342 0x38); 343 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 344 0x38); 345 } 346 347 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 348 MT_CALIBRATE_INTERVAL); 349 350 return 0; 351 } 352 353 static void 354 mt76x2_phy_temp_compensate(struct mt76x02_dev *dev) 355 { 356 struct mt76x2_temp_comp t; 357 int temp, db_diff; 358 359 if (mt76x2_get_temp_comp(dev, &t)) 360 return; 361 362 temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL); 363 temp -= t.temp_25_ref; 364 temp = (temp * 1789) / 1000 + 25; 365 dev->cal.temp = temp; 366 367 if (temp > 25) 368 db_diff = (temp - 25) / t.high_slope; 369 else 370 db_diff = (25 - temp) / t.low_slope; 371 372 db_diff = min(db_diff, t.upper_bound); 373 db_diff = max(db_diff, t.lower_bound); 374 375 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 376 db_diff * 2); 377 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 378 db_diff * 2); 379 } 380 381 void mt76x2_phy_calibrate(struct work_struct *work) 382 { 383 struct mt76x02_dev *dev; 384 385 dev = container_of(work, struct mt76x02_dev, cal_work.work); 386 mt76x2_phy_channel_calibrate(dev, false); 387 mt76x2_phy_tssi_compensate(dev, true); 388 mt76x2_phy_temp_compensate(dev); 389 mt76x2_phy_update_channel_gain(dev); 390 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 391 MT_CALIBRATE_INTERVAL); 392 } 393 394 int mt76x2_phy_start(struct mt76x02_dev *dev) 395 { 396 int ret; 397 398 ret = mt76x02_mcu_set_radio_state(dev, true, true); 399 if (ret) 400 return ret; 401 402 mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); 403 404 return ret; 405 } 406