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 (!mt76x02_tssi_enabled(&dev->mt76)) 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->mt76, chan->band)) 39 flag |= BIT(8); 40 41 mt76x02_mcu_calibrate(&dev->mt76, 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->mt76, MCU_CAL_LC, 0, true); 66 67 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TX_LOFT, is_5ghz, true); 68 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TXIQ, is_5ghz, true); 69 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXIQC_FI, is_5ghz, true); 70 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_TEMP_SENSOR, 0, true); 71 mt76x02_mcu_calibrate(&dev->mt76, 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_get_agc_gain(struct mt76x02_dev *dev, u8 *dest) 129 { 130 dest[0] = mt76_get_field(dev, MT_BBP(AGC, 8), MT_BBP_AGC_GAIN); 131 dest[1] = mt76_get_field(dev, MT_BBP(AGC, 9), MT_BBP_AGC_GAIN); 132 } 133 134 static int 135 mt76x2_get_rssi_gain_thresh(struct mt76x02_dev *dev) 136 { 137 switch (dev->mt76.chandef.width) { 138 case NL80211_CHAN_WIDTH_80: 139 return -62; 140 case NL80211_CHAN_WIDTH_40: 141 return -65; 142 default: 143 return -68; 144 } 145 } 146 147 static int 148 mt76x2_get_low_rssi_gain_thresh(struct mt76x02_dev *dev) 149 { 150 switch (dev->mt76.chandef.width) { 151 case NL80211_CHAN_WIDTH_80: 152 return -76; 153 case NL80211_CHAN_WIDTH_40: 154 return -79; 155 default: 156 return -82; 157 } 158 } 159 160 static void 161 mt76x2_phy_set_gain_val(struct mt76x02_dev *dev) 162 { 163 u32 val; 164 u8 gain_val[2]; 165 166 gain_val[0] = dev->cal.agc_gain_cur[0] - dev->cal.agc_gain_adjust; 167 gain_val[1] = dev->cal.agc_gain_cur[1] - dev->cal.agc_gain_adjust; 168 169 if (dev->mt76.chandef.width >= NL80211_CHAN_WIDTH_40) 170 val = 0x1e42 << 16; 171 else 172 val = 0x1836 << 16; 173 174 val |= 0xf8; 175 176 mt76_wr(dev, MT_BBP(AGC, 8), 177 val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[0])); 178 mt76_wr(dev, MT_BBP(AGC, 9), 179 val | FIELD_PREP(MT_BBP_AGC_GAIN, gain_val[1])); 180 181 if (dev->mt76.chandef.chan->flags & IEEE80211_CHAN_RADAR) 182 mt76x2_dfs_adjust_agc(dev); 183 } 184 185 static void 186 mt76x2_phy_adjust_vga_gain(struct mt76x02_dev *dev) 187 { 188 u32 false_cca; 189 u8 limit = dev->cal.low_gain > 0 ? 16 : 4; 190 191 false_cca = FIELD_GET(MT_RX_STAT_1_CCA_ERRORS, mt76_rr(dev, MT_RX_STAT_1)); 192 dev->cal.false_cca = false_cca; 193 if (false_cca > 800 && dev->cal.agc_gain_adjust < limit) 194 dev->cal.agc_gain_adjust += 2; 195 else if ((false_cca < 10 && dev->cal.agc_gain_adjust > 0) || 196 (dev->cal.agc_gain_adjust >= limit && false_cca < 500)) 197 dev->cal.agc_gain_adjust -= 2; 198 else 199 return; 200 201 mt76x2_phy_set_gain_val(dev); 202 } 203 204 static void 205 mt76x2_phy_update_channel_gain(struct mt76x02_dev *dev) 206 { 207 u8 *gain = dev->cal.agc_gain_init; 208 u8 low_gain_delta, gain_delta; 209 bool gain_change; 210 int low_gain; 211 u32 val; 212 213 dev->cal.avg_rssi_all = mt76x02_phy_get_min_avg_rssi(&dev->mt76); 214 215 low_gain = (dev->cal.avg_rssi_all > mt76x2_get_rssi_gain_thresh(dev)) + 216 (dev->cal.avg_rssi_all > mt76x2_get_low_rssi_gain_thresh(dev)); 217 218 gain_change = (dev->cal.low_gain & 2) ^ (low_gain & 2); 219 dev->cal.low_gain = low_gain; 220 221 if (!gain_change) { 222 mt76x2_phy_adjust_vga_gain(dev); 223 return; 224 } 225 226 if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) { 227 mt76_wr(dev, MT_BBP(RXO, 14), 0x00560211); 228 val = mt76_rr(dev, MT_BBP(AGC, 26)) & ~0xf; 229 if (low_gain == 2) 230 val |= 0x3; 231 else 232 val |= 0x5; 233 mt76_wr(dev, MT_BBP(AGC, 26), val); 234 } else { 235 mt76_wr(dev, MT_BBP(RXO, 14), 0x00560423); 236 } 237 238 if (mt76x2_has_ext_lna(dev)) 239 low_gain_delta = 10; 240 else 241 low_gain_delta = 14; 242 243 if (low_gain == 2) { 244 mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a990); 245 mt76_wr(dev, MT_BBP(AGC, 35), 0x08080808); 246 mt76_wr(dev, MT_BBP(AGC, 37), 0x08080808); 247 gain_delta = low_gain_delta; 248 dev->cal.agc_gain_adjust = 0; 249 } else { 250 mt76_wr(dev, MT_BBP(RXO, 18), 0xf000a991); 251 if (dev->mt76.chandef.width == NL80211_CHAN_WIDTH_80) 252 mt76_wr(dev, MT_BBP(AGC, 35), 0x10101014); 253 else 254 mt76_wr(dev, MT_BBP(AGC, 35), 0x11111116); 255 mt76_wr(dev, MT_BBP(AGC, 37), 0x2121262C); 256 gain_delta = 0; 257 dev->cal.agc_gain_adjust = low_gain_delta; 258 } 259 260 dev->cal.agc_gain_cur[0] = gain[0] - gain_delta; 261 dev->cal.agc_gain_cur[1] = gain[1] - gain_delta; 262 mt76x2_phy_set_gain_val(dev); 263 264 /* clear false CCA counters */ 265 mt76_rr(dev, MT_RX_STAT_1); 266 } 267 268 int mt76x2_phy_set_channel(struct mt76x02_dev *dev, 269 struct cfg80211_chan_def *chandef) 270 { 271 struct ieee80211_channel *chan = chandef->chan; 272 bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); 273 enum nl80211_band band = chan->band; 274 u8 channel; 275 276 u32 ext_cca_chan[4] = { 277 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | 278 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | 279 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 280 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 281 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), 282 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | 283 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | 284 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 285 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 286 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), 287 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | 288 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | 289 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 290 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 291 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), 292 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | 293 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | 294 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 295 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 296 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), 297 }; 298 int ch_group_index; 299 u8 bw, bw_index; 300 int freq, freq1; 301 int ret; 302 303 dev->cal.channel_cal_done = false; 304 freq = chandef->chan->center_freq; 305 freq1 = chandef->center_freq1; 306 channel = chan->hw_value; 307 308 switch (chandef->width) { 309 case NL80211_CHAN_WIDTH_40: 310 bw = 1; 311 if (freq1 > freq) { 312 bw_index = 1; 313 ch_group_index = 0; 314 } else { 315 bw_index = 3; 316 ch_group_index = 1; 317 } 318 channel += 2 - ch_group_index * 4; 319 break; 320 case NL80211_CHAN_WIDTH_80: 321 ch_group_index = (freq - freq1 + 30) / 20; 322 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) 323 ch_group_index = 0; 324 bw = 2; 325 bw_index = ch_group_index; 326 channel += 6 - ch_group_index * 4; 327 break; 328 default: 329 bw = 0; 330 bw_index = 0; 331 ch_group_index = 0; 332 break; 333 } 334 335 mt76x2_read_rx_gain(dev); 336 mt76x2_phy_set_txpower_regs(dev, band); 337 mt76x2_configure_tx_delay(dev, band, bw); 338 mt76x2_phy_set_txpower(dev); 339 340 mt76x2_phy_set_band(dev, chan->band, ch_group_index & 1); 341 mt76x2_phy_set_bw(dev, chandef->width, ch_group_index); 342 343 mt76_rmw(dev, MT_EXT_CCA_CFG, 344 (MT_EXT_CCA_CFG_CCA0 | 345 MT_EXT_CCA_CFG_CCA1 | 346 MT_EXT_CCA_CFG_CCA2 | 347 MT_EXT_CCA_CFG_CCA3 | 348 MT_EXT_CCA_CFG_CCA_MASK), 349 ext_cca_chan[ch_group_index]); 350 351 ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); 352 if (ret) 353 return ret; 354 355 mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); 356 357 mt76x2_phy_set_antenna(dev); 358 359 /* Enable LDPC Rx */ 360 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 361 mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); 362 363 if (!dev->cal.init_cal_done) { 364 u8 val = mt76x02_eeprom_get(&dev->mt76, MT_EE_BT_RCAL_RESULT); 365 366 if (val != 0xff) 367 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_R, 0, true); 368 } 369 370 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RXDCOC, channel, true); 371 372 /* Rx LPF calibration */ 373 if (!dev->cal.init_cal_done) 374 mt76x02_mcu_calibrate(&dev->mt76, MCU_CAL_RC, 0, true); 375 376 dev->cal.init_cal_done = true; 377 378 mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2); 379 mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); 380 mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); 381 mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); 382 mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F); 383 384 if (scan) 385 return 0; 386 387 dev->cal.low_gain = -1; 388 mt76x2_phy_channel_calibrate(dev, true); 389 mt76x2_get_agc_gain(dev, dev->cal.agc_gain_init); 390 memcpy(dev->cal.agc_gain_cur, dev->cal.agc_gain_init, 391 sizeof(dev->cal.agc_gain_cur)); 392 393 /* init default values for temp compensation */ 394 if (mt76x02_tssi_enabled(&dev->mt76)) { 395 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 396 0x38); 397 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 398 0x38); 399 } 400 401 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 402 MT_CALIBRATE_INTERVAL); 403 404 return 0; 405 } 406 407 static void 408 mt76x2_phy_temp_compensate(struct mt76x02_dev *dev) 409 { 410 struct mt76x2_temp_comp t; 411 int temp, db_diff; 412 413 if (mt76x2_get_temp_comp(dev, &t)) 414 return; 415 416 temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL); 417 temp -= t.temp_25_ref; 418 temp = (temp * 1789) / 1000 + 25; 419 dev->cal.temp = temp; 420 421 if (temp > 25) 422 db_diff = (temp - 25) / t.high_slope; 423 else 424 db_diff = (25 - temp) / t.low_slope; 425 426 db_diff = min(db_diff, t.upper_bound); 427 db_diff = max(db_diff, t.lower_bound); 428 429 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 430 db_diff * 2); 431 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 432 db_diff * 2); 433 } 434 435 void mt76x2_phy_calibrate(struct work_struct *work) 436 { 437 struct mt76x02_dev *dev; 438 439 dev = container_of(work, struct mt76x02_dev, cal_work.work); 440 mt76x2_phy_channel_calibrate(dev, false); 441 mt76x2_phy_tssi_compensate(dev, true); 442 mt76x2_phy_temp_compensate(dev); 443 mt76x2_phy_update_channel_gain(dev); 444 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 445 MT_CALIBRATE_INTERVAL); 446 } 447 448 int mt76x2_phy_start(struct mt76x02_dev *dev) 449 { 450 int ret; 451 452 ret = mt76x02_mcu_set_radio_state(&dev->mt76, true, true); 453 if (ret) 454 return ret; 455 456 mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); 457 458 return ret; 459 } 460