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); 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); 66 67 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_LOFT, is_5ghz); 68 mt76x02_mcu_calibrate(dev, MCU_CAL_TXIQ, is_5ghz); 69 mt76x02_mcu_calibrate(dev, MCU_CAL_RXIQC_FI, is_5ghz); 70 mt76x02_mcu_calibrate(dev, MCU_CAL_TEMP_SENSOR, 0); 71 mt76x02_mcu_calibrate(dev, MCU_CAL_TX_SHAPING, 0); 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 int mt76x2_phy_set_channel(struct mt76x02_dev *dev, 128 struct cfg80211_chan_def *chandef) 129 { 130 struct ieee80211_channel *chan = chandef->chan; 131 bool scan = test_bit(MT76_SCANNING, &dev->mt76.state); 132 enum nl80211_band band = chan->band; 133 u8 channel; 134 135 u32 ext_cca_chan[4] = { 136 [0] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 0) | 137 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 1) | 138 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 139 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 140 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(0)), 141 [1] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 1) | 142 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 0) | 143 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 2) | 144 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 3) | 145 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(1)), 146 [2] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 2) | 147 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 3) | 148 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 149 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 150 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(2)), 151 [3] = FIELD_PREP(MT_EXT_CCA_CFG_CCA0, 3) | 152 FIELD_PREP(MT_EXT_CCA_CFG_CCA1, 2) | 153 FIELD_PREP(MT_EXT_CCA_CFG_CCA2, 1) | 154 FIELD_PREP(MT_EXT_CCA_CFG_CCA3, 0) | 155 FIELD_PREP(MT_EXT_CCA_CFG_CCA_MASK, BIT(3)), 156 }; 157 int ch_group_index; 158 u8 bw, bw_index; 159 int freq, freq1; 160 int ret; 161 162 dev->cal.channel_cal_done = false; 163 freq = chandef->chan->center_freq; 164 freq1 = chandef->center_freq1; 165 channel = chan->hw_value; 166 167 switch (chandef->width) { 168 case NL80211_CHAN_WIDTH_40: 169 bw = 1; 170 if (freq1 > freq) { 171 bw_index = 1; 172 ch_group_index = 0; 173 } else { 174 bw_index = 3; 175 ch_group_index = 1; 176 } 177 channel += 2 - ch_group_index * 4; 178 break; 179 case NL80211_CHAN_WIDTH_80: 180 ch_group_index = (freq - freq1 + 30) / 20; 181 if (WARN_ON(ch_group_index < 0 || ch_group_index > 3)) 182 ch_group_index = 0; 183 bw = 2; 184 bw_index = ch_group_index; 185 channel += 6 - ch_group_index * 4; 186 break; 187 default: 188 bw = 0; 189 bw_index = 0; 190 ch_group_index = 0; 191 break; 192 } 193 194 mt76x2_read_rx_gain(dev); 195 mt76x2_phy_set_txpower_regs(dev, band); 196 mt76x2_configure_tx_delay(dev, band, bw); 197 mt76x2_phy_set_txpower(dev); 198 199 mt76x02_phy_set_band(dev, chan->band, ch_group_index & 1); 200 mt76x02_phy_set_bw(dev, chandef->width, ch_group_index); 201 202 mt76_rmw(dev, MT_EXT_CCA_CFG, 203 (MT_EXT_CCA_CFG_CCA0 | 204 MT_EXT_CCA_CFG_CCA1 | 205 MT_EXT_CCA_CFG_CCA2 | 206 MT_EXT_CCA_CFG_CCA3 | 207 MT_EXT_CCA_CFG_CCA_MASK), 208 ext_cca_chan[ch_group_index]); 209 210 ret = mt76x2_mcu_set_channel(dev, channel, bw, bw_index, scan); 211 if (ret) 212 return ret; 213 214 mt76x2_mcu_init_gain(dev, channel, dev->cal.rx.mcu_gain, true); 215 216 mt76x2_phy_set_antenna(dev); 217 218 /* Enable LDPC Rx */ 219 if (mt76xx_rev(dev) >= MT76XX_REV_E3) 220 mt76_set(dev, MT_BBP(RXO, 13), BIT(10)); 221 222 if (!dev->cal.init_cal_done) { 223 u8 val = mt76x02_eeprom_get(dev, MT_EE_BT_RCAL_RESULT); 224 225 if (val != 0xff) 226 mt76x02_mcu_calibrate(dev, MCU_CAL_R, 0); 227 } 228 229 mt76x02_mcu_calibrate(dev, MCU_CAL_RXDCOC, channel); 230 231 /* Rx LPF calibration */ 232 if (!dev->cal.init_cal_done) 233 mt76x02_mcu_calibrate(dev, MCU_CAL_RC, 0); 234 235 dev->cal.init_cal_done = true; 236 237 mt76_wr(dev, MT_BBP(AGC, 61), 0xFF64A4E2); 238 mt76_wr(dev, MT_BBP(AGC, 7), 0x08081010); 239 mt76_wr(dev, MT_BBP(AGC, 11), 0x00000404); 240 mt76_wr(dev, MT_BBP(AGC, 2), 0x00007070); 241 mt76_wr(dev, MT_TXOP_CTRL_CFG, 0x04101B3F); 242 243 if (scan) 244 return 0; 245 246 mt76x2_phy_channel_calibrate(dev, true); 247 mt76x02_init_agc_gain(dev); 248 249 /* init default values for temp compensation */ 250 if (mt76x2_tssi_enabled(dev)) { 251 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 252 0x38); 253 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 254 0x38); 255 } 256 257 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 258 MT_CALIBRATE_INTERVAL); 259 260 return 0; 261 } 262 263 static void 264 mt76x2_phy_temp_compensate(struct mt76x02_dev *dev) 265 { 266 struct mt76x2_temp_comp t; 267 int temp, db_diff; 268 269 if (mt76x2_get_temp_comp(dev, &t)) 270 return; 271 272 temp = mt76_get_field(dev, MT_TEMP_SENSOR, MT_TEMP_SENSOR_VAL); 273 temp -= t.temp_25_ref; 274 temp = (temp * 1789) / 1000 + 25; 275 dev->cal.temp = temp; 276 277 if (temp > 25) 278 db_diff = (temp - 25) / t.high_slope; 279 else 280 db_diff = (25 - temp) / t.low_slope; 281 282 db_diff = min(db_diff, t.upper_bound); 283 db_diff = max(db_diff, t.lower_bound); 284 285 mt76_rmw_field(dev, MT_TX_ALC_CFG_1, MT_TX_ALC_CFG_1_TEMP_COMP, 286 db_diff * 2); 287 mt76_rmw_field(dev, MT_TX_ALC_CFG_2, MT_TX_ALC_CFG_2_TEMP_COMP, 288 db_diff * 2); 289 } 290 291 void mt76x2_phy_calibrate(struct work_struct *work) 292 { 293 struct mt76x02_dev *dev; 294 295 dev = container_of(work, struct mt76x02_dev, cal_work.work); 296 mt76x2_phy_channel_calibrate(dev, false); 297 mt76x2_phy_tssi_compensate(dev); 298 mt76x2_phy_temp_compensate(dev); 299 mt76x2_phy_update_channel_gain(dev); 300 ieee80211_queue_delayed_work(mt76_hw(dev), &dev->cal_work, 301 MT_CALIBRATE_INTERVAL); 302 } 303 304 int mt76x2_phy_start(struct mt76x02_dev *dev) 305 { 306 int ret; 307 308 ret = mt76x02_mcu_set_radio_state(dev, true); 309 if (ret) 310 return ret; 311 312 mt76x2_mcu_load_cr(dev, MT_RF_BBP_CR, 0, 0); 313 314 return ret; 315 } 316