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