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/module.h> 18 #include <asm/unaligned.h> 19 #include "mt76x2.h" 20 #include "eeprom.h" 21 22 #define EE_FIELD(_name, _value) [MT_EE_##_name] = (_value) | 1 23 24 static int 25 mt76x2_eeprom_get_macaddr(struct mt76x02_dev *dev) 26 { 27 void *src = dev->mt76.eeprom.data + MT_EE_MAC_ADDR; 28 29 memcpy(dev->mt76.macaddr, src, ETH_ALEN); 30 return 0; 31 } 32 33 static bool 34 mt76x2_has_cal_free_data(struct mt76x02_dev *dev, u8 *efuse) 35 { 36 u16 *efuse_w = (u16 *) efuse; 37 38 if (efuse_w[MT_EE_NIC_CONF_0] != 0) 39 return false; 40 41 if (efuse_w[MT_EE_XTAL_TRIM_1] == 0xffff) 42 return false; 43 44 if (efuse_w[MT_EE_TX_POWER_DELTA_BW40] != 0) 45 return false; 46 47 if (efuse_w[MT_EE_TX_POWER_0_START_2G] == 0xffff) 48 return false; 49 50 if (efuse_w[MT_EE_TX_POWER_0_GRP3_TX_POWER_DELTA] != 0) 51 return false; 52 53 if (efuse_w[MT_EE_TX_POWER_0_GRP4_TSSI_SLOPE] == 0xffff) 54 return false; 55 56 return true; 57 } 58 59 static void 60 mt76x2_apply_cal_free_data(struct mt76x02_dev *dev, u8 *efuse) 61 { 62 #define GROUP_5G(_id) \ 63 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \ 64 MT_EE_TX_POWER_0_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1, \ 65 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id), \ 66 MT_EE_TX_POWER_1_START_5G + MT_TX_POWER_GROUP_SIZE_5G * (_id) + 1 67 68 static const u8 cal_free_bytes[] = { 69 MT_EE_XTAL_TRIM_1, 70 MT_EE_TX_POWER_EXT_PA_5G + 1, 71 MT_EE_TX_POWER_0_START_2G, 72 MT_EE_TX_POWER_0_START_2G + 1, 73 MT_EE_TX_POWER_1_START_2G, 74 MT_EE_TX_POWER_1_START_2G + 1, 75 GROUP_5G(0), 76 GROUP_5G(1), 77 GROUP_5G(2), 78 GROUP_5G(3), 79 GROUP_5G(4), 80 GROUP_5G(5), 81 MT_EE_RF_2G_TSSI_OFF_TXPOWER, 82 MT_EE_RF_2G_RX_HIGH_GAIN + 1, 83 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN, 84 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN + 1, 85 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN, 86 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN + 1, 87 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN, 88 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN + 1, 89 }; 90 u8 *eeprom = dev->mt76.eeprom.data; 91 u8 prev_grp0[4] = { 92 eeprom[MT_EE_TX_POWER_0_START_5G], 93 eeprom[MT_EE_TX_POWER_0_START_5G + 1], 94 eeprom[MT_EE_TX_POWER_1_START_5G], 95 eeprom[MT_EE_TX_POWER_1_START_5G + 1] 96 }; 97 u16 val; 98 int i; 99 100 if (!mt76x2_has_cal_free_data(dev, efuse)) 101 return; 102 103 for (i = 0; i < ARRAY_SIZE(cal_free_bytes); i++) { 104 int offset = cal_free_bytes[i]; 105 106 eeprom[offset] = efuse[offset]; 107 } 108 109 if (!(efuse[MT_EE_TX_POWER_0_START_5G] | 110 efuse[MT_EE_TX_POWER_0_START_5G + 1])) 111 memcpy(eeprom + MT_EE_TX_POWER_0_START_5G, prev_grp0, 2); 112 if (!(efuse[MT_EE_TX_POWER_1_START_5G] | 113 efuse[MT_EE_TX_POWER_1_START_5G + 1])) 114 memcpy(eeprom + MT_EE_TX_POWER_1_START_5G, prev_grp0 + 2, 2); 115 116 val = get_unaligned_le16(efuse + MT_EE_BT_RCAL_RESULT); 117 if (val != 0xffff) 118 eeprom[MT_EE_BT_RCAL_RESULT] = val & 0xff; 119 120 val = get_unaligned_le16(efuse + MT_EE_BT_VCDL_CALIBRATION); 121 if (val != 0xffff) 122 eeprom[MT_EE_BT_VCDL_CALIBRATION + 1] = val >> 8; 123 124 val = get_unaligned_le16(efuse + MT_EE_BT_PMUCFG); 125 if (val != 0xffff) 126 eeprom[MT_EE_BT_PMUCFG] = val & 0xff; 127 } 128 129 static int mt76x2_check_eeprom(struct mt76x02_dev *dev) 130 { 131 u16 val = get_unaligned_le16(dev->mt76.eeprom.data); 132 133 if (!val) 134 val = get_unaligned_le16(dev->mt76.eeprom.data + MT_EE_PCI_ID); 135 136 switch (val) { 137 case 0x7662: 138 case 0x7612: 139 return 0; 140 default: 141 dev_err(dev->mt76.dev, "EEPROM data check failed: %04x\n", val); 142 return -EINVAL; 143 } 144 } 145 146 static int 147 mt76x2_eeprom_load(struct mt76x02_dev *dev) 148 { 149 void *efuse; 150 bool found; 151 int ret; 152 153 ret = mt76_eeprom_init(&dev->mt76, MT7662_EEPROM_SIZE); 154 if (ret < 0) 155 return ret; 156 157 found = ret; 158 if (found) 159 found = !mt76x2_check_eeprom(dev); 160 161 dev->mt76.otp.data = devm_kzalloc(dev->mt76.dev, MT7662_EEPROM_SIZE, 162 GFP_KERNEL); 163 dev->mt76.otp.size = MT7662_EEPROM_SIZE; 164 if (!dev->mt76.otp.data) 165 return -ENOMEM; 166 167 efuse = dev->mt76.otp.data; 168 169 if (mt76x02_get_efuse_data(dev, 0, efuse, MT7662_EEPROM_SIZE, 170 MT_EE_READ)) 171 goto out; 172 173 if (found) { 174 mt76x2_apply_cal_free_data(dev, efuse); 175 } else { 176 /* FIXME: check if efuse data is complete */ 177 found = true; 178 memcpy(dev->mt76.eeprom.data, efuse, MT7662_EEPROM_SIZE); 179 } 180 181 out: 182 if (!found) 183 return -ENOENT; 184 185 return 0; 186 } 187 188 static void 189 mt76x2_set_rx_gain_group(struct mt76x02_dev *dev, u8 val) 190 { 191 s8 *dest = dev->cal.rx.high_gain; 192 193 if (!mt76x02_field_valid(val)) { 194 dest[0] = 0; 195 dest[1] = 0; 196 return; 197 } 198 199 dest[0] = mt76x02_sign_extend(val, 4); 200 dest[1] = mt76x02_sign_extend(val >> 4, 4); 201 } 202 203 static void 204 mt76x2_set_rssi_offset(struct mt76x02_dev *dev, int chain, u8 val) 205 { 206 s8 *dest = dev->cal.rx.rssi_offset; 207 208 if (!mt76x02_field_valid(val)) { 209 dest[chain] = 0; 210 return; 211 } 212 213 dest[chain] = mt76x02_sign_extend_optional(val, 7); 214 } 215 216 static enum mt76x2_cal_channel_group 217 mt76x2_get_cal_channel_group(int channel) 218 { 219 if (channel >= 184 && channel <= 196) 220 return MT_CH_5G_JAPAN; 221 if (channel <= 48) 222 return MT_CH_5G_UNII_1; 223 if (channel <= 64) 224 return MT_CH_5G_UNII_2; 225 if (channel <= 114) 226 return MT_CH_5G_UNII_2E_1; 227 if (channel <= 144) 228 return MT_CH_5G_UNII_2E_2; 229 return MT_CH_5G_UNII_3; 230 } 231 232 static u8 233 mt76x2_get_5g_rx_gain(struct mt76x02_dev *dev, u8 channel) 234 { 235 enum mt76x2_cal_channel_group group; 236 237 group = mt76x2_get_cal_channel_group(channel); 238 switch (group) { 239 case MT_CH_5G_JAPAN: 240 return mt76x02_eeprom_get(dev, 241 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN); 242 case MT_CH_5G_UNII_1: 243 return mt76x02_eeprom_get(dev, 244 MT_EE_RF_5G_GRP0_1_RX_HIGH_GAIN) >> 8; 245 case MT_CH_5G_UNII_2: 246 return mt76x02_eeprom_get(dev, 247 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN); 248 case MT_CH_5G_UNII_2E_1: 249 return mt76x02_eeprom_get(dev, 250 MT_EE_RF_5G_GRP2_3_RX_HIGH_GAIN) >> 8; 251 case MT_CH_5G_UNII_2E_2: 252 return mt76x02_eeprom_get(dev, 253 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN); 254 default: 255 return mt76x02_eeprom_get(dev, 256 MT_EE_RF_5G_GRP4_5_RX_HIGH_GAIN) >> 8; 257 } 258 } 259 260 void mt76x2_read_rx_gain(struct mt76x02_dev *dev) 261 { 262 struct ieee80211_channel *chan = dev->mt76.chandef.chan; 263 int channel = chan->hw_value; 264 s8 lna_5g[3], lna_2g; 265 u8 lna; 266 u16 val; 267 268 if (chan->band == NL80211_BAND_2GHZ) 269 val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN) >> 8; 270 else 271 val = mt76x2_get_5g_rx_gain(dev, channel); 272 273 mt76x2_set_rx_gain_group(dev, val); 274 275 mt76x02_get_rx_gain(dev, chan->band, &val, &lna_2g, lna_5g); 276 mt76x2_set_rssi_offset(dev, 0, val); 277 mt76x2_set_rssi_offset(dev, 1, val >> 8); 278 279 dev->cal.rx.mcu_gain = (lna_2g & 0xff); 280 dev->cal.rx.mcu_gain |= (lna_5g[0] & 0xff) << 8; 281 dev->cal.rx.mcu_gain |= (lna_5g[1] & 0xff) << 16; 282 dev->cal.rx.mcu_gain |= (lna_5g[2] & 0xff) << 24; 283 284 lna = mt76x02_get_lna_gain(dev, &lna_2g, lna_5g, chan); 285 dev->cal.rx.lna_gain = mt76x02_sign_extend(lna, 8); 286 } 287 EXPORT_SYMBOL_GPL(mt76x2_read_rx_gain); 288 289 void mt76x2_get_rate_power(struct mt76x02_dev *dev, struct mt76_rate_power *t, 290 struct ieee80211_channel *chan) 291 { 292 bool is_5ghz; 293 u16 val; 294 295 is_5ghz = chan->band == NL80211_BAND_5GHZ; 296 297 memset(t, 0, sizeof(*t)); 298 299 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_CCK); 300 t->cck[0] = t->cck[1] = mt76x02_rate_power_val(val); 301 t->cck[2] = t->cck[3] = mt76x02_rate_power_val(val >> 8); 302 303 if (is_5ghz) 304 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_6M); 305 else 306 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_6M); 307 t->ofdm[0] = t->ofdm[1] = mt76x02_rate_power_val(val); 308 t->ofdm[2] = t->ofdm[3] = mt76x02_rate_power_val(val >> 8); 309 310 if (is_5ghz) 311 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_5G_24M); 312 else 313 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_OFDM_2G_24M); 314 t->ofdm[4] = t->ofdm[5] = mt76x02_rate_power_val(val); 315 t->ofdm[6] = t->ofdm[7] = mt76x02_rate_power_val(val >> 8); 316 317 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS0); 318 t->ht[0] = t->ht[1] = mt76x02_rate_power_val(val); 319 t->ht[2] = t->ht[3] = mt76x02_rate_power_val(val >> 8); 320 321 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS4); 322 t->ht[4] = t->ht[5] = mt76x02_rate_power_val(val); 323 t->ht[6] = t->ht[7] = mt76x02_rate_power_val(val >> 8); 324 325 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS8); 326 t->ht[8] = t->ht[9] = mt76x02_rate_power_val(val); 327 t->ht[10] = t->ht[11] = mt76x02_rate_power_val(val >> 8); 328 329 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_HT_MCS12); 330 t->ht[12] = t->ht[13] = mt76x02_rate_power_val(val); 331 t->ht[14] = t->ht[15] = mt76x02_rate_power_val(val >> 8); 332 333 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS0); 334 t->vht[0] = t->vht[1] = mt76x02_rate_power_val(val); 335 t->vht[2] = t->vht[3] = mt76x02_rate_power_val(val >> 8); 336 337 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS4); 338 t->vht[4] = t->vht[5] = mt76x02_rate_power_val(val); 339 t->vht[6] = t->vht[7] = mt76x02_rate_power_val(val >> 8); 340 341 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_VHT_MCS8); 342 if (!is_5ghz) 343 val >>= 8; 344 t->vht[8] = t->vht[9] = mt76x02_rate_power_val(val >> 8); 345 346 memcpy(t->stbc, t->ht, sizeof(t->stbc[0]) * 8); 347 t->stbc[8] = t->vht[8]; 348 t->stbc[9] = t->vht[9]; 349 } 350 EXPORT_SYMBOL_GPL(mt76x2_get_rate_power); 351 352 static void 353 mt76x2_get_power_info_2g(struct mt76x02_dev *dev, 354 struct mt76x2_tx_power_info *t, 355 struct ieee80211_channel *chan, 356 int chain, int offset) 357 { 358 int channel = chan->hw_value; 359 int delta_idx; 360 u8 data[6]; 361 u16 val; 362 363 if (channel < 6) 364 delta_idx = 3; 365 else if (channel < 11) 366 delta_idx = 4; 367 else 368 delta_idx = 5; 369 370 mt76x02_eeprom_copy(dev, offset, data, sizeof(data)); 371 372 t->chain[chain].tssi_slope = data[0]; 373 t->chain[chain].tssi_offset = data[1]; 374 t->chain[chain].target_power = data[2]; 375 t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); 376 377 val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_TSSI_OFF_TXPOWER); 378 t->target_power = val >> 8; 379 } 380 381 static void 382 mt76x2_get_power_info_5g(struct mt76x02_dev *dev, 383 struct mt76x2_tx_power_info *t, 384 struct ieee80211_channel *chan, 385 int chain, int offset) 386 { 387 int channel = chan->hw_value; 388 enum mt76x2_cal_channel_group group; 389 int delta_idx; 390 u16 val; 391 u8 data[5]; 392 393 group = mt76x2_get_cal_channel_group(channel); 394 offset += group * MT_TX_POWER_GROUP_SIZE_5G; 395 396 if (channel >= 192) 397 delta_idx = 4; 398 else if (channel >= 184) 399 delta_idx = 3; 400 else if (channel < 44) 401 delta_idx = 3; 402 else if (channel < 52) 403 delta_idx = 4; 404 else if (channel < 58) 405 delta_idx = 3; 406 else if (channel < 98) 407 delta_idx = 4; 408 else if (channel < 106) 409 delta_idx = 3; 410 else if (channel < 116) 411 delta_idx = 4; 412 else if (channel < 130) 413 delta_idx = 3; 414 else if (channel < 149) 415 delta_idx = 4; 416 else if (channel < 157) 417 delta_idx = 3; 418 else 419 delta_idx = 4; 420 421 mt76x02_eeprom_copy(dev, offset, data, sizeof(data)); 422 423 t->chain[chain].tssi_slope = data[0]; 424 t->chain[chain].tssi_offset = data[1]; 425 t->chain[chain].target_power = data[2]; 426 t->chain[chain].delta = mt76x02_sign_extend_optional(data[delta_idx], 7); 427 428 val = mt76x02_eeprom_get(dev, MT_EE_RF_2G_RX_HIGH_GAIN); 429 t->target_power = val & 0xff; 430 } 431 432 void mt76x2_get_power_info(struct mt76x02_dev *dev, 433 struct mt76x2_tx_power_info *t, 434 struct ieee80211_channel *chan) 435 { 436 u16 bw40, bw80; 437 438 memset(t, 0, sizeof(*t)); 439 440 bw40 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW40); 441 bw80 = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_DELTA_BW80); 442 443 if (chan->band == NL80211_BAND_5GHZ) { 444 bw40 >>= 8; 445 mt76x2_get_power_info_5g(dev, t, chan, 0, 446 MT_EE_TX_POWER_0_START_5G); 447 mt76x2_get_power_info_5g(dev, t, chan, 1, 448 MT_EE_TX_POWER_1_START_5G); 449 } else { 450 mt76x2_get_power_info_2g(dev, t, chan, 0, 451 MT_EE_TX_POWER_0_START_2G); 452 mt76x2_get_power_info_2g(dev, t, chan, 1, 453 MT_EE_TX_POWER_1_START_2G); 454 } 455 456 if (mt76x2_tssi_enabled(dev) || 457 !mt76x02_field_valid(t->target_power)) 458 t->target_power = t->chain[0].target_power; 459 460 t->delta_bw40 = mt76x02_rate_power_val(bw40); 461 t->delta_bw80 = mt76x02_rate_power_val(bw80); 462 } 463 EXPORT_SYMBOL_GPL(mt76x2_get_power_info); 464 465 int mt76x2_get_temp_comp(struct mt76x02_dev *dev, struct mt76x2_temp_comp *t) 466 { 467 enum nl80211_band band = dev->mt76.chandef.chan->band; 468 u16 val, slope; 469 u8 bounds; 470 471 memset(t, 0, sizeof(*t)); 472 473 if (!mt76x2_temp_tx_alc_enabled(dev)) 474 return -EINVAL; 475 476 if (!mt76x02_ext_pa_enabled(dev, band)) 477 return -EINVAL; 478 479 val = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G) >> 8; 480 t->temp_25_ref = val & 0x7f; 481 if (band == NL80211_BAND_5GHZ) { 482 slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_5G); 483 bounds = mt76x02_eeprom_get(dev, MT_EE_TX_POWER_EXT_PA_5G); 484 } else { 485 slope = mt76x02_eeprom_get(dev, MT_EE_RF_TEMP_COMP_SLOPE_2G); 486 bounds = mt76x02_eeprom_get(dev, 487 MT_EE_TX_POWER_DELTA_BW80) >> 8; 488 } 489 490 t->high_slope = slope & 0xff; 491 t->low_slope = slope >> 8; 492 t->lower_bound = 0 - (bounds & 0xf); 493 t->upper_bound = (bounds >> 4) & 0xf; 494 495 return 0; 496 } 497 EXPORT_SYMBOL_GPL(mt76x2_get_temp_comp); 498 499 int mt76x2_eeprom_init(struct mt76x02_dev *dev) 500 { 501 int ret; 502 503 ret = mt76x2_eeprom_load(dev); 504 if (ret) 505 return ret; 506 507 mt76x02_eeprom_parse_hw_cap(dev); 508 mt76x2_eeprom_get_macaddr(dev); 509 mt76_eeprom_override(&dev->mt76); 510 dev->mt76.macaddr[0] &= ~BIT(1); 511 512 return 0; 513 } 514 EXPORT_SYMBOL_GPL(mt76x2_eeprom_init); 515 516 MODULE_LICENSE("Dual BSD/GPL"); 517