1 /* $OpenBSD: ar9380.c,v 1.14 2011/04/07 14:19:53 miod Exp $ */ 2 3 /*- 4 * Copyright (c) 2011 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2010 Atheros Communications Inc. 6 * 7 * Permission to use, copy, modify, and/or distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /* 21 * Driver for Atheros 802.11a/g/n chipsets. 22 * Routines for AR9380 and AR9485 chipsets. 23 */ 24 25 #include "bpfilter.h" 26 27 #include <sys/param.h> 28 #include <sys/sockio.h> 29 #include <sys/mbuf.h> 30 #include <sys/kernel.h> 31 #include <sys/socket.h> 32 #include <sys/systm.h> 33 #include <sys/malloc.h> 34 #include <sys/queue.h> 35 #include <sys/conf.h> 36 #include <sys/device.h> 37 38 #include <machine/bus.h> 39 #include <machine/endian.h> 40 41 #if NBPFILTER > 0 42 #include <net/bpf.h> 43 #endif 44 #include <net/if.h> 45 #include <net/if_arp.h> 46 #include <net/if_dl.h> 47 #include <net/if_media.h> 48 #include <net/if_types.h> 49 50 #include <netinet/in.h> 51 #include <netinet/in_systm.h> 52 #include <netinet/in_var.h> 53 #include <netinet/if_ether.h> 54 55 #include <net80211/ieee80211_var.h> 56 #include <net80211/ieee80211_amrr.h> 57 #include <net80211/ieee80211_radiotap.h> 58 59 #include <dev/ic/athnreg.h> 60 #include <dev/ic/athnvar.h> 61 62 #include <dev/ic/ar9003reg.h> 63 #include <dev/ic/ar9380reg.h> 64 65 int ar9380_attach(struct athn_softc *); 66 void ar9380_setup(struct athn_softc *); 67 const uint8_t *ar9380_get_rom_template(struct athn_softc *, uint8_t); 68 void ar9380_swap_rom(struct athn_softc *); 69 int ar9380_set_synth(struct athn_softc *, struct ieee80211_channel *, 70 struct ieee80211_channel *); 71 void ar9380_get_paprd_masks(struct athn_softc *, struct ieee80211_channel *, 72 uint32_t *, uint32_t *); 73 void ar9380_init_from_rom(struct athn_softc *, struct ieee80211_channel *, 74 struct ieee80211_channel *); 75 void ar9380_init_swreg(struct athn_softc *); 76 int ar9485_pmu_write(struct athn_softc *, uint32_t, uint32_t); 77 void ar9485_init_swreg(struct athn_softc *); 78 void ar9380_spur_mitigate_cck(struct athn_softc *, 79 struct ieee80211_channel *, struct ieee80211_channel *); 80 void ar9380_spur_mitigate_ofdm(struct athn_softc *, 81 struct ieee80211_channel *, struct ieee80211_channel *); 82 void ar9380_spur_mitigate(struct athn_softc *, struct ieee80211_channel *, 83 struct ieee80211_channel *); 84 void ar9380_set_txpower(struct athn_softc *, struct ieee80211_channel *, 85 struct ieee80211_channel *); 86 void ar9380_get_correction(struct athn_softc *, struct ieee80211_channel *, 87 int, int *, int *); 88 void ar9380_set_correction(struct athn_softc *, struct ieee80211_channel *); 89 90 /* Extern functions. */ 91 int athn_interpolate(int, int, int, int, int); 92 uint8_t athn_chan2fbin(struct ieee80211_channel *); 93 void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *); 94 int ar9003_attach(struct athn_softc *); 95 void ar9003_write_txpower(struct athn_softc *, int16_t power[]); 96 void ar9003_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *, 97 uint8_t, const uint8_t *, const struct ar_cal_target_power_leg *, 98 int, uint8_t[]); 99 void ar9003_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *, 100 uint8_t, const uint8_t *, const struct ar_cal_target_power_ht *, 101 int, uint8_t[]); 102 103 104 int 105 ar9380_attach(struct athn_softc *sc) 106 { 107 sc->ngpiopins = 17; 108 sc->ops.setup = ar9380_setup; 109 sc->ops.get_rom_template = ar9380_get_rom_template; 110 sc->ops.swap_rom = ar9380_swap_rom; 111 sc->ops.init_from_rom = ar9380_init_from_rom; 112 sc->ops.set_txpower = ar9380_set_txpower; 113 sc->ops.set_synth = ar9380_set_synth; 114 sc->ops.spur_mitigate = ar9380_spur_mitigate; 115 sc->ops.get_paprd_masks = ar9380_get_paprd_masks; 116 sc->cca_min_2g = AR9380_PHY_CCA_MIN_GOOD_VAL_2GHZ; 117 sc->cca_max_2g = AR9380_PHY_CCA_MAX_GOOD_VAL_2GHZ; 118 sc->cca_min_5g = AR9380_PHY_CCA_MIN_GOOD_VAL_5GHZ; 119 sc->cca_max_5g = AR9380_PHY_CCA_MAX_GOOD_VAL_5GHZ; 120 if (AR_SREV_9485(sc)) 121 sc->ini = &ar9485_1_0_ini; 122 else 123 sc->ini = &ar9380_2_2_ini; 124 125 return (ar9003_attach(sc)); 126 } 127 128 void 129 ar9380_setup(struct athn_softc *sc) 130 { 131 struct ieee80211com *ic = &sc->sc_ic; 132 struct ar9380_eeprom *eep = sc->eep; 133 struct ar9380_base_eep_hdr *base = &eep->baseEepHeader; 134 uint8_t type; 135 136 if (base->opFlags & AR_OPFLAGS_11A) 137 sc->flags |= ATHN_FLAG_11A; 138 if (base->opFlags & AR_OPFLAGS_11G) 139 sc->flags |= ATHN_FLAG_11G; 140 if (base->opFlags & AR_OPFLAGS_11N) 141 sc->flags |= ATHN_FLAG_11N; 142 143 IEEE80211_ADDR_COPY(ic->ic_myaddr, eep->macAddr); 144 sc->led_pin = base->wlanLedGpio; 145 146 /* Check if we have a hardware radio switch. */ 147 if (base->rfSilent & AR_EEP_RFSILENT_ENABLED) { 148 sc->flags |= ATHN_FLAG_RFSILENT; 149 /* Get GPIO pin used by hardware radio switch. */ 150 sc->rfsilent_pin = base->wlanDisableGpio; 151 } 152 153 /* Set the number of HW key cache entries. */ 154 sc->kc_entries = AR_KEYTABLE_SIZE; 155 156 sc->txchainmask = MS(base->txrxMask, AR_EEP_TX_MASK); 157 sc->rxchainmask = MS(base->txrxMask, AR_EEP_RX_MASK); 158 159 /* Fast PLL clock is always supported. */ 160 sc->flags |= ATHN_FLAG_FAST_PLL_CLOCK; 161 162 /* Enable PA predistortion if supported. */ 163 if (base->featureEnable & AR_EEP_PAPRD) 164 sc->flags |= ATHN_FLAG_PAPRD; 165 /* 166 * Some 3-stream chips may exceed the PCIe power requirements, 167 * requiring to reduce the number of Tx chains in some cases. 168 */ 169 if ((base->miscConfiguration & AR_EEP_CHAIN_MASK_REDUCE) && 170 sc->txchainmask == 0x7) 171 sc->flags |= ATHN_FLAG_3TREDUCE_CHAIN; 172 173 /* Select initialization values based on ROM. */ 174 type = MS(eep->baseEepHeader.txrxgain, AR_EEP_RX_GAIN); 175 if (!AR_SREV_9485(sc)) { 176 if (type == AR_EEP_RX_GAIN_WO_XLNA) 177 sc->rx_gain = &ar9380_2_2_rx_gain_wo_xlna; 178 else 179 sc->rx_gain = &ar9380_2_2_rx_gain; 180 } else 181 sc->rx_gain = &ar9485_1_0_rx_gain; 182 183 /* Select initialization values based on ROM. */ 184 type = MS(eep->baseEepHeader.txrxgain, AR_EEP_TX_GAIN); 185 if (!AR_SREV_9485(sc)) { 186 if (type == AR_EEP_TX_GAIN_HIGH_OB_DB) 187 sc->tx_gain = &ar9380_2_2_tx_gain_high_ob_db; 188 else if (type == AR_EEP_TX_GAIN_LOW_OB_DB) 189 sc->tx_gain = &ar9380_2_2_tx_gain_low_ob_db; 190 else if (type == AR_EEP_TX_GAIN_HIGH_POWER) 191 sc->tx_gain = &ar9380_2_2_tx_gain_high_power; 192 else 193 sc->tx_gain = &ar9380_2_2_tx_gain; 194 } else 195 sc->tx_gain = &ar9485_1_0_tx_gain; 196 } 197 198 const uint8_t * 199 ar9380_get_rom_template(struct athn_softc *sc, uint8_t ref) 200 { 201 int i; 202 203 /* Retrieve template ROM image for given reference. */ 204 for (i = 0; i < nitems(ar9380_rom_templates); i++) 205 if (ar9380_rom_templates[i][1] == ref) 206 return (ar9380_rom_templates[i]); 207 return (NULL); 208 } 209 210 void 211 ar9380_swap_rom(struct athn_softc *sc) 212 { 213 #if BYTE_ORDER == BIG_ENDIAN 214 struct ar9380_eeprom *eep = sc->eep; 215 struct ar9380_base_eep_hdr *base = &eep->baseEepHeader; 216 struct ar9380_modal_eep_header *modal; 217 int i; 218 219 base->regDmn[0] = swap16(base->regDmn[0]); 220 base->regDmn[1] = swap16(base->regDmn[1]); 221 base->swreg = swap32(base->swreg); 222 223 modal = &eep->modalHeader2G; 224 modal->antCtrlCommon = swap32(modal->antCtrlCommon); 225 modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2); 226 modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20); 227 modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40); 228 for (i = 0; i < AR9380_MAX_CHAINS; i++) 229 modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i]); 230 231 modal = &eep->modalHeader5G; 232 modal->antCtrlCommon = swap32(modal->antCtrlCommon); 233 modal->antCtrlCommon2 = swap32(modal->antCtrlCommon2); 234 modal->papdRateMaskHt20 = swap32(modal->papdRateMaskHt20); 235 modal->papdRateMaskHt40 = swap32(modal->papdRateMaskHt40); 236 for (i = 0; i < AR9380_MAX_CHAINS; i++) 237 modal->antCtrlChain[i] = swap16(modal->antCtrlChain[i]); 238 #endif 239 } 240 241 void 242 ar9380_get_paprd_masks(struct athn_softc *sc, struct ieee80211_channel *c, 243 uint32_t *ht20mask, uint32_t *ht40mask) 244 { 245 const struct ar9380_eeprom *eep = sc->eep; 246 const struct ar9380_modal_eep_header *modal; 247 248 if (IEEE80211_IS_CHAN_2GHZ(c)) 249 modal = &eep->modalHeader2G; 250 else 251 modal = &eep->modalHeader5G; 252 *ht20mask = modal->papdRateMaskHt20; 253 *ht40mask = modal->papdRateMaskHt40; 254 } 255 256 int 257 ar9380_set_synth(struct athn_softc *sc, struct ieee80211_channel *c, 258 struct ieee80211_channel *extc) 259 { 260 uint32_t freq = c->ic_freq; 261 uint32_t chansel, phy; 262 263 if (IEEE80211_IS_CHAN_2GHZ(c)) { 264 if (AR_SREV_9485(sc)) 265 chansel = ((freq << 16) - 215) / 15; 266 else 267 chansel = (freq << 16) / 15; 268 AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, AR9380_BMODE); 269 } else { 270 chansel = (freq << 15) / 15; 271 chansel >>= 1; 272 AR_WRITE(sc, AR_PHY_SYNTH_CONTROL, 0); 273 } 274 275 /* Enable Long Shift Select for synthesizer. */ 276 AR_SETBITS(sc, AR_PHY_65NM_CH0_SYNTH4, 277 AR_PHY_SYNTH4_LONG_SHIFT_SELECT); 278 AR_WRITE_BARRIER(sc); 279 280 /* Program synthesizer. */ 281 phy = (chansel << 2) | AR9380_FRACMODE; 282 DPRINTFN(4, ("AR_PHY_65NM_CH0_SYNTH7=0x%08x\n", phy)); 283 AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy); 284 AR_WRITE_BARRIER(sc); 285 /* Toggle Load Synth Channel bit. */ 286 AR_WRITE(sc, AR_PHY_65NM_CH0_SYNTH7, phy | AR9380_LOAD_SYNTH); 287 AR_WRITE_BARRIER(sc); 288 return (0); 289 } 290 291 void 292 ar9380_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c, 293 struct ieee80211_channel *extc) 294 { 295 const struct ar9380_eeprom *eep = sc->eep; 296 const struct ar9380_modal_eep_header *modal; 297 uint8_t db, margin, ant_div_ctrl; 298 uint32_t reg; 299 int i, maxchains; 300 301 if (IEEE80211_IS_CHAN_2GHZ(c)) 302 modal = &eep->modalHeader2G; 303 else 304 modal = &eep->modalHeader5G; 305 306 /* Apply XPA bias level. */ 307 if (AR_SREV_9485(sc)) { 308 reg = AR_READ(sc, AR9485_PHY_65NM_CH0_TOP2); 309 reg = RW(reg, AR9485_PHY_65NM_CH0_TOP2_XPABIASLVL, 310 modal->xpaBiasLvl); 311 AR_WRITE(sc, AR9485_PHY_65NM_CH0_TOP2, reg); 312 } else { 313 reg = AR_READ(sc, AR_PHY_65NM_CH0_TOP); 314 reg = RW(reg, AR_PHY_65NM_CH0_TOP_XPABIASLVL, 315 modal->xpaBiasLvl & 0x3); 316 AR_WRITE(sc, AR_PHY_65NM_CH0_TOP, reg); 317 reg = AR_READ(sc, AR_PHY_65NM_CH0_THERM); 318 reg = RW(reg, AR_PHY_65NM_CH0_THERM_XPABIASLVL_MSB, 319 modal->xpaBiasLvl >> 2); 320 reg |= AR_PHY_65NM_CH0_THERM_XPASHORT2GND; 321 AR_WRITE(sc, AR_PHY_65NM_CH0_THERM, reg); 322 } 323 324 /* Apply antenna control. */ 325 reg = AR_READ(sc, AR_PHY_SWITCH_COM); 326 reg = RW(reg, AR_SWITCH_TABLE_COM_ALL, modal->antCtrlCommon); 327 AR_WRITE(sc, AR_PHY_SWITCH_COM, reg); 328 reg = AR_READ(sc, AR_PHY_SWITCH_COM_2); 329 reg = RW(reg, AR_SWITCH_TABLE_COM_2_ALL, modal->antCtrlCommon2); 330 AR_WRITE(sc, AR_PHY_SWITCH_COM_2, reg); 331 332 maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS; 333 for (i = 0; i < maxchains; i++) { 334 reg = AR_READ(sc, AR_PHY_SWITCH_CHAIN(i)); 335 reg = RW(reg, AR_SWITCH_TABLE_ALL, modal->antCtrlChain[i]); 336 AR_WRITE(sc, AR_PHY_SWITCH_CHAIN(i), reg); 337 } 338 339 if (AR_SREV_9485(sc)) { 340 ant_div_ctrl = eep->base_ext1.ant_div_control; 341 reg = AR_READ(sc, AR_PHY_MC_GAIN_CTRL); 342 reg = RW(reg, AR_PHY_MC_GAIN_CTRL_ANT_DIV_CTRL_ALL, 343 MS(ant_div_ctrl, AR_EEP_ANT_DIV_CTRL_ALL)); 344 if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_ANT_DIV) 345 reg |= AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV; 346 else 347 reg &= ~AR_PHY_MC_GAIN_CTRL_ENABLE_ANT_DIV; 348 AR_WRITE(sc, AR_PHY_MC_GAIN_CTRL, reg); 349 reg = AR_READ(sc, AR_PHY_CCK_DETECT); 350 if (ant_div_ctrl & AR_EEP_ANT_DIV_CTRL_FAST_DIV) 351 reg |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 352 else 353 reg &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 354 AR_WRITE(sc, AR_PHY_CCK_DETECT, reg); 355 } 356 357 if (eep->baseEepHeader.miscConfiguration & AR_EEP_DRIVE_STRENGTH) { 358 /* Apply drive strength. */ 359 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS1); 360 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_0, 5); 361 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_1, 5); 362 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_2, 5); 363 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_3, 5); 364 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_4, 5); 365 reg = RW(reg, AR_PHY_65NM_CH0_BIAS1_5, 5); 366 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS1, reg); 367 368 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS2); 369 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_0, 5); 370 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_1, 5); 371 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_2, 5); 372 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_3, 5); 373 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_4, 5); 374 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_5, 5); 375 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_6, 5); 376 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_7, 5); 377 reg = RW(reg, AR_PHY_65NM_CH0_BIAS2_8, 5); 378 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS2, reg); 379 380 reg = AR_READ(sc, AR_PHY_65NM_CH0_BIAS4); 381 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_0, 5); 382 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_1, 5); 383 reg = RW(reg, AR_PHY_65NM_CH0_BIAS4_2, 5); 384 AR_WRITE(sc, AR_PHY_65NM_CH0_BIAS4, reg); 385 } 386 387 /* Apply attenuation settings. */ 388 maxchains = AR_SREV_9485(sc) ? 1 : AR9380_MAX_CHAINS; 389 for (i = 0; i < maxchains; i++) { 390 if (IEEE80211_IS_CHAN_5GHZ(c) && 391 eep->base_ext2.xatten1DBLow[i] != 0) { 392 if (c->ic_freq <= 5500) { 393 db = athn_interpolate(c->ic_freq, 394 5180, eep->base_ext2.xatten1DBLow[i], 395 5500, modal->xatten1DB[i]); 396 } else { 397 db = athn_interpolate(c->ic_freq, 398 5500, modal->xatten1DB[i], 399 5785, eep->base_ext2.xatten1DBHigh[i]); 400 } 401 } else 402 db = modal->xatten1DB[i]; 403 if (IEEE80211_IS_CHAN_5GHZ(c) && 404 eep->base_ext2.xatten1MarginLow[i] != 0) { 405 if (c->ic_freq <= 5500) { 406 margin = athn_interpolate(c->ic_freq, 407 5180, eep->base_ext2.xatten1MarginLow[i], 408 5500, modal->xatten1Margin[i]); 409 } else { 410 margin = athn_interpolate(c->ic_freq, 411 5500, modal->xatten1Margin[i], 412 5785, eep->base_ext2.xatten1MarginHigh[i]); 413 } 414 } else 415 margin = modal->xatten1Margin[i]; 416 reg = AR_READ(sc, AR_PHY_EXT_ATTEN_CTL(i)); 417 reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, db); 418 reg = RW(reg, AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, margin); 419 AR_WRITE(sc, AR_PHY_EXT_ATTEN_CTL(i), reg); 420 } 421 422 /* Initialize switching regulator. */ 423 if (AR_SREV_9485(sc)) 424 ar9485_init_swreg(sc); 425 else 426 ar9485_init_swreg(sc); 427 428 /* Apply tuning capabilities. */ 429 if (AR_SREV_9485(sc) && 430 (eep->baseEepHeader.featureEnable & AR_EEP_TUNING_CAPS)) { 431 reg = AR_READ(sc, AR9485_PHY_CH0_XTAL); 432 reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPINDAC, 433 eep->baseEepHeader.params_for_tuning_caps[0]); 434 reg = RW(reg, AR9485_PHY_CH0_XTAL_CAPOUTDAC, 435 eep->baseEepHeader.params_for_tuning_caps[0]); 436 AR_WRITE(sc, AR9485_PHY_CH0_XTAL, reg); 437 } 438 AR_WRITE_BARRIER(sc); 439 } 440 441 void 442 ar9380_init_swreg(struct athn_softc *sc) 443 { 444 const struct ar9380_eeprom *eep = sc->eep; 445 446 if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) { 447 /* Internal regulator is ON. */ 448 AR_CLRBITS(sc, AR_RTC_REG_CONTROL1, 449 AR_RTC_REG_CONTROL1_SWREG_PROGRAM); 450 AR_WRITE(sc, AR_RTC_REG_CONTROL0, eep->baseEepHeader.swreg); 451 AR_SETBITS(sc, AR_RTC_REG_CONTROL1, 452 AR_RTC_REG_CONTROL1_SWREG_PROGRAM); 453 } else 454 AR_SETBITS(sc, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_SWREG_PRD); 455 AR_WRITE_BARRIER(sc); 456 } 457 458 int 459 ar9485_pmu_write(struct athn_softc *sc, uint32_t addr, uint32_t val) 460 { 461 int ntries; 462 463 AR_WRITE(sc, addr, val); 464 /* Wait for write to complete. */ 465 for (ntries = 0; ntries < 100; ntries++) { 466 if (AR_READ(sc, addr) == val) 467 return (0); 468 AR_WRITE(sc, addr, val); /* Insist. */ 469 AR_WRITE_BARRIER(sc); 470 DELAY(10); 471 } 472 return (ETIMEDOUT); 473 } 474 475 #define ar9486_pmu_read AR_READ 476 477 void 478 ar9485_init_swreg(struct athn_softc *sc) 479 { 480 const struct ar9380_eeprom *eep = sc->eep; 481 uint32_t reg; 482 483 ar9485_pmu_write(sc, AR_PHY_PMU2, 484 ar9486_pmu_read(sc, AR_PHY_PMU2) & ~AR_PHY_PMU2_PGM); 485 486 if (eep->baseEepHeader.featureEnable & AR_EEP_INTERNAL_REGULATOR) { 487 ar9485_pmu_write(sc, AR_PHY_PMU1, 0x131dc17a); 488 489 reg = ar9486_pmu_read(sc, AR_PHY_PMU2); 490 reg = (reg & ~0xffc00000) | 0x10000000; 491 ar9485_pmu_write(sc, AR_PHY_PMU2, reg); 492 } else { 493 ar9485_pmu_write(sc, AR_PHY_PMU1, 494 ar9486_pmu_read(sc, AR_PHY_PMU1) | AR_PHY_PMU1_PWD); 495 } 496 497 ar9485_pmu_write(sc, AR_PHY_PMU2, 498 ar9486_pmu_read(sc, AR_PHY_PMU2) | AR_PHY_PMU2_PGM); 499 } 500 501 void 502 ar9380_spur_mitigate_cck(struct athn_softc *sc, struct ieee80211_channel *c, 503 struct ieee80211_channel *extc) 504 { 505 /* NB: It is safe to call this function for 5GHz channels. */ 506 static const int16_t freqs[] = { 2420, 2440, 2464, 2480 }; 507 int i, spur, freq; 508 uint32_t reg; 509 510 for (i = 0; i < nitems(freqs); i++) { 511 spur = freqs[i] - c->ic_freq; 512 if (abs(spur) < 10) /* +/- 10MHz range. */ 513 break; 514 } 515 if (i == nitems(freqs)) { 516 /* Disable CCK spur mitigation. */ 517 reg = AR_READ(sc, AR_PHY_AGC_CONTROL); 518 reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5); 519 AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg); 520 reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT); 521 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0); 522 reg &= ~AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT; 523 AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg); 524 AR_WRITE_BARRIER(sc); 525 return; 526 } 527 freq = (spur * 524288) / 11; 528 529 reg = AR_READ(sc, AR_PHY_AGC_CONTROL); 530 reg = RW(reg, AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7); 531 AR_WRITE(sc, AR_PHY_AGC_CONTROL, reg); 532 533 reg = AR_READ(sc, AR_PHY_CCK_SPUR_MIT); 534 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, freq); 535 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f); 536 reg = RW(reg, AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 0x2); 537 reg |= AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT; 538 AR_WRITE(sc, AR_PHY_CCK_SPUR_MIT, reg); 539 AR_WRITE_BARRIER(sc); 540 } 541 542 void 543 ar9380_spur_mitigate_ofdm(struct athn_softc *sc, struct ieee80211_channel *c, 544 struct ieee80211_channel *extc) 545 { 546 const struct ar9380_eeprom *eep = sc->eep; 547 const uint8_t *spurchans; 548 uint32_t reg; 549 int idx, spur_delta_phase, spur_off, range, i; 550 int freq, spur, spur_freq_sd, spur_subchannel_sd; 551 552 if (IEEE80211_IS_CHAN_2GHZ(c)) 553 spurchans = eep->modalHeader2G.spurChans; 554 else 555 spurchans = eep->modalHeader5G.spurChans; 556 if (spurchans[0] == 0) 557 return; 558 559 /* Disable OFDM spur mitigation. */ 560 AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER); 561 562 reg = AR_READ(sc, AR_PHY_TIMING11); 563 reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, 0); 564 reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0); 565 reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC; 566 reg &= ~AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR; 567 AR_WRITE(sc, AR_PHY_TIMING11, reg); 568 569 AR_CLRBITS(sc, AR_PHY_SFCORR_EXT, 570 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD); 571 572 AR_CLRBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI); 573 574 reg = AR_READ(sc, AR_PHY_SPUR_REG); 575 reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0); 576 reg &= ~AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI; 577 reg &= ~AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT; 578 reg &= ~AR_PHY_SPUR_REG_ENABLE_MASK_PPM; 579 AR_WRITE(sc, AR_PHY_SPUR_REG, reg); 580 AR_WRITE_BARRIER(sc); 581 582 freq = c->ic_freq; 583 #ifndef IEEE80211_NO_HT 584 if (extc != NULL) { 585 range = 19; /* +/- 19MHz range. */ 586 if (AR_READ(sc, AR_PHY_GEN_CTRL) & AR_PHY_GC_DYN2040_PRI_CH) 587 freq += 10; 588 else 589 freq -= 10; 590 } else 591 #endif 592 range = 10; /* +/- 10MHz range. */ 593 for (i = 0; i < AR9380_EEPROM_MODAL_SPURS; i++) { 594 spur = spurchans[i]; 595 if (spur == 0) 596 return; 597 /* Convert to frequency. */ 598 if (IEEE80211_IS_CHAN_2GHZ(c)) 599 spur = 2300 + spur; 600 else 601 spur = 4900 + (spur * 5); 602 spur -= freq; 603 if (abs(spur) < range) 604 break; 605 } 606 if (i == AR9380_EEPROM_MODAL_SPURS) 607 return; 608 609 /* Enable OFDM spur mitigation. */ 610 #ifndef IEEE80211_NO_HT 611 if (extc != NULL) { 612 spur_delta_phase = (spur * 131072) / 5; 613 reg = AR_READ(sc, AR_PHY_GEN_CTRL); 614 if (spur < 0) { 615 spur_subchannel_sd = 616 (reg & AR_PHY_GC_DYN2040_PRI_CH) == 0; 617 spur_off = spur + 10; 618 } else { 619 spur_subchannel_sd = 620 (reg & AR_PHY_GC_DYN2040_PRI_CH) != 0; 621 spur_off = spur - 10; 622 } 623 } else 624 #endif 625 { 626 spur_delta_phase = (spur * 262144) / 5; 627 spur_subchannel_sd = 0; 628 spur_off = spur; 629 } 630 spur_freq_sd = (spur_off * 512) / 11; 631 632 AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_FILTER); 633 634 reg = AR_READ(sc, AR_PHY_TIMING11); 635 reg = RW(reg, AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd); 636 reg = RW(reg, AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase); 637 reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC; 638 reg |= AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR; 639 AR_WRITE(sc, AR_PHY_TIMING11, reg); 640 641 reg = AR_READ(sc, AR_PHY_SFCORR_EXT); 642 if (spur_subchannel_sd) 643 reg |= AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD; 644 else 645 reg &= ~AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD; 646 AR_WRITE(sc, AR_PHY_SFCORR_EXT, reg); 647 648 AR_SETBITS(sc, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI); 649 650 reg = AR_READ(sc, AR_PHY_SPUR_REG); 651 reg = RW(reg, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff); 652 reg = RW(reg, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34); 653 reg |= AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI; 654 if (AR_READ(sc, AR_PHY_MODE) & AR_PHY_MODE_DYNAMIC) 655 reg |= AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT; 656 reg |= AR_PHY_SPUR_REG_ENABLE_MASK_PPM; 657 AR_WRITE(sc, AR_PHY_SPUR_REG, reg); 658 659 idx = (spur * 16) / 5; 660 if (idx < 0) 661 idx--; 662 663 /* Write pilot mask. */ 664 AR_SETBITS(sc, AR_PHY_TIMING4, 665 AR_PHY_TIMING4_ENABLE_PILOT_MASK | 666 AR_PHY_TIMING4_ENABLE_CHAN_MASK); 667 668 reg = AR_READ(sc, AR_PHY_PILOT_SPUR_MASK); 669 reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, idx); 670 reg = RW(reg, AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0x0c); 671 AR_WRITE(sc, AR_PHY_PILOT_SPUR_MASK, reg); 672 673 reg = AR_READ(sc, AR_PHY_SPUR_MASK_A); 674 reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, idx); 675 reg = RW(reg, AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0); 676 AR_WRITE(sc, AR_PHY_SPUR_MASK_A, reg); 677 678 reg = AR_READ(sc, AR_PHY_CHAN_SPUR_MASK); 679 reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, idx); 680 reg = RW(reg, AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0x0c); 681 AR_WRITE(sc, AR_PHY_CHAN_SPUR_MASK, reg); 682 AR_WRITE_BARRIER(sc); 683 } 684 685 void 686 ar9380_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c, 687 struct ieee80211_channel *extc) 688 { 689 /* NB: We call spur_mitigate_cck for 5GHz too, just to disable it. */ 690 ar9380_spur_mitigate_cck(sc, c, extc); 691 ar9380_spur_mitigate_ofdm(sc, c, extc); 692 } 693 694 void 695 ar9380_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c, 696 struct ieee80211_channel *extc) 697 { 698 const struct ar9380_eeprom *eep = sc->eep; 699 uint8_t tpow_cck[4], tpow_ofdm[4]; 700 uint8_t tpow_ht20[14], tpow_ht40[14]; 701 int16_t power[ATHN_POWER_COUNT]; 702 703 if (IEEE80211_IS_CHAN_2GHZ(c)) { 704 /* Get CCK target powers. */ 705 ar9003_get_lg_tpow(sc, c, AR_CTL_11B, 706 eep->calTargetFbinCck, eep->calTargetPowerCck, 707 AR9380_NUM_2G_CCK_TARGET_POWERS, tpow_cck); 708 709 /* Get OFDM target powers. */ 710 ar9003_get_lg_tpow(sc, c, AR_CTL_11G, 711 eep->calTargetFbin2G, eep->calTargetPower2G, 712 AR9380_NUM_2G_20_TARGET_POWERS, tpow_ofdm); 713 714 /* Get HT-20 target powers. */ 715 ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT20, 716 eep->calTargetFbin2GHT20, eep->calTargetPower2GHT20, 717 AR9380_NUM_2G_20_TARGET_POWERS, tpow_ht20); 718 719 if (extc != NULL) { 720 /* Get HT-40 target powers. */ 721 ar9003_get_ht_tpow(sc, c, AR_CTL_2GHT40, 722 eep->calTargetFbin2GHT40, 723 eep->calTargetPower2GHT40, 724 AR9380_NUM_2G_40_TARGET_POWERS, tpow_ht40); 725 } 726 } else { 727 /* Get OFDM target powers. */ 728 ar9003_get_lg_tpow(sc, c, AR_CTL_11A, 729 eep->calTargetFbin5G, eep->calTargetPower5G, 730 AR9380_NUM_5G_20_TARGET_POWERS, tpow_ofdm); 731 732 /* Get HT-20 target powers. */ 733 ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT20, 734 eep->calTargetFbin5GHT20, eep->calTargetPower5GHT20, 735 AR9380_NUM_5G_20_TARGET_POWERS, tpow_ht20); 736 737 if (extc != NULL) { 738 /* Get HT-40 target powers. */ 739 ar9003_get_ht_tpow(sc, c, AR_CTL_5GHT40, 740 eep->calTargetFbin5GHT40, 741 eep->calTargetPower5GHT40, 742 AR9380_NUM_5G_40_TARGET_POWERS, tpow_ht40); 743 } 744 } 745 746 memset(power, 0, sizeof(power)); 747 /* Shuffle target powers accross transmit rates. */ 748 power[ATHN_POWER_OFDM6 ] = 749 power[ATHN_POWER_OFDM9 ] = 750 power[ATHN_POWER_OFDM12] = 751 power[ATHN_POWER_OFDM18] = 752 power[ATHN_POWER_OFDM24] = tpow_ofdm[0]; 753 power[ATHN_POWER_OFDM36] = tpow_ofdm[1]; 754 power[ATHN_POWER_OFDM48] = tpow_ofdm[2]; 755 power[ATHN_POWER_OFDM54] = tpow_ofdm[3]; 756 if (IEEE80211_IS_CHAN_2GHZ(c)) { 757 power[ATHN_POWER_CCK1_LP ] = 758 power[ATHN_POWER_CCK2_LP ] = 759 power[ATHN_POWER_CCK2_SP ] = 760 power[ATHN_POWER_CCK55_LP] = tpow_cck[0]; 761 power[ATHN_POWER_CCK55_SP] = tpow_cck[1]; 762 power[ATHN_POWER_CCK11_LP] = tpow_cck[2]; 763 power[ATHN_POWER_CCK11_SP] = tpow_cck[3]; 764 } 765 /* Next entry covers MCS0, MCS8 and MCS16. */ 766 power[ATHN_POWER_HT20( 0)] = tpow_ht20[ 0]; 767 /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */ 768 power[ATHN_POWER_HT20( 1)] = tpow_ht20[ 1]; 769 power[ATHN_POWER_HT20( 4)] = tpow_ht20[ 2]; 770 power[ATHN_POWER_HT20( 5)] = tpow_ht20[ 3]; 771 power[ATHN_POWER_HT20( 6)] = tpow_ht20[ 4]; 772 power[ATHN_POWER_HT20( 7)] = tpow_ht20[ 5]; 773 power[ATHN_POWER_HT20(12)] = tpow_ht20[ 6]; 774 power[ATHN_POWER_HT20(13)] = tpow_ht20[ 7]; 775 power[ATHN_POWER_HT20(14)] = tpow_ht20[ 8]; 776 power[ATHN_POWER_HT20(15)] = tpow_ht20[ 9]; 777 power[ATHN_POWER_HT20(20)] = tpow_ht20[10]; 778 power[ATHN_POWER_HT20(21)] = tpow_ht20[11]; 779 power[ATHN_POWER_HT20(22)] = tpow_ht20[12]; 780 power[ATHN_POWER_HT20(23)] = tpow_ht20[13]; 781 if (extc != NULL) { 782 /* Next entry covers MCS0, MCS8 and MCS16. */ 783 power[ATHN_POWER_HT40( 0)] = tpow_ht40[ 0]; 784 /* Next entry covers MCS1-3, MCS9-11 and MCS17-19. */ 785 power[ATHN_POWER_HT40( 1)] = tpow_ht40[ 1]; 786 power[ATHN_POWER_HT40( 4)] = tpow_ht40[ 2]; 787 power[ATHN_POWER_HT40( 5)] = tpow_ht40[ 3]; 788 power[ATHN_POWER_HT40( 6)] = tpow_ht40[ 4]; 789 power[ATHN_POWER_HT40( 7)] = tpow_ht40[ 5]; 790 power[ATHN_POWER_HT40(12)] = tpow_ht40[ 6]; 791 power[ATHN_POWER_HT40(13)] = tpow_ht40[ 7]; 792 power[ATHN_POWER_HT40(14)] = tpow_ht40[ 8]; 793 power[ATHN_POWER_HT40(15)] = tpow_ht40[ 9]; 794 power[ATHN_POWER_HT40(20)] = tpow_ht40[10]; 795 power[ATHN_POWER_HT40(21)] = tpow_ht40[11]; 796 power[ATHN_POWER_HT40(22)] = tpow_ht40[12]; 797 power[ATHN_POWER_HT40(23)] = tpow_ht40[13]; 798 } 799 800 /* Write transmit power values to hardware. */ 801 ar9003_write_txpower(sc, power); 802 803 /* Apply transmit power correction. */ 804 ar9380_set_correction(sc, c); 805 } 806 807 void 808 ar9380_get_correction(struct athn_softc *sc, struct ieee80211_channel *c, 809 int chain, int *corr, int *temp) 810 { 811 const struct ar9380_eeprom *eep = sc->eep; 812 const struct ar9380_cal_data_per_freq_op_loop *pierdata; 813 const uint8_t *pierfreq; 814 uint8_t fbin; 815 int lo, hi, npiers; 816 817 if (IEEE80211_IS_CHAN_2GHZ(c)) { 818 pierfreq = eep->calFreqPier2G; 819 pierdata = eep->calPierData2G[chain]; 820 npiers = AR9380_NUM_2G_CAL_PIERS; 821 } else { 822 pierfreq = eep->calFreqPier5G; 823 pierdata = eep->calPierData5G[chain]; 824 npiers = AR9380_NUM_5G_CAL_PIERS; 825 } 826 /* Find channel in ROM pier table. */ 827 fbin = athn_chan2fbin(c); 828 athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi); 829 830 *corr = athn_interpolate(fbin, 831 pierfreq[lo], pierdata[lo].refPower, 832 pierfreq[hi], pierdata[hi].refPower); 833 *temp = athn_interpolate(fbin, 834 pierfreq[lo], pierdata[lo].tempMeas, 835 pierfreq[hi], pierdata[hi].tempMeas); 836 } 837 838 void 839 ar9380_set_correction(struct athn_softc *sc, struct ieee80211_channel *c) 840 { 841 const struct ar9380_eeprom *eep = sc->eep; 842 const struct ar9380_modal_eep_header *modal; 843 uint32_t reg; 844 int8_t slope; 845 int i, corr, temp, temp0; 846 847 if (IEEE80211_IS_CHAN_2GHZ(c)) 848 modal = &eep->modalHeader2G; 849 else 850 modal = &eep->modalHeader5G; 851 852 for (i = 0; i < AR9380_MAX_CHAINS; i++) { 853 ar9380_get_correction(sc, c, i, &corr, &temp); 854 if (i == 0) 855 temp0 = temp; 856 857 reg = AR_READ(sc, AR_PHY_TPC_11_B(i)); 858 reg = RW(reg, AR_PHY_TPC_11_OLPC_GAIN_DELTA, corr); 859 AR_WRITE(sc, AR_PHY_TPC_11_B(i), reg); 860 861 /* Enable open loop power control. */ 862 reg = AR_READ(sc, AR_PHY_TPC_6_B(i)); 863 reg = RW(reg, AR_PHY_TPC_6_ERROR_EST_MODE, 3); 864 AR_WRITE(sc, AR_PHY_TPC_6_B(i), reg); 865 } 866 867 /* Enable temperature compensation. */ 868 if (IEEE80211_IS_CHAN_5GHZ(c) && 869 eep->base_ext2.tempSlopeLow != 0) { 870 if (c->ic_freq <= 5500) { 871 slope = athn_interpolate(c->ic_freq, 872 5180, eep->base_ext2.tempSlopeLow, 873 5500, modal->tempSlope); 874 } else { 875 slope = athn_interpolate(c->ic_freq, 876 5500, modal->tempSlope, 877 5785, eep->base_ext2.tempSlopeHigh); 878 } 879 } else 880 slope = modal->tempSlope; 881 882 reg = AR_READ(sc, AR_PHY_TPC_19); 883 reg = RW(reg, AR_PHY_TPC_19_ALPHA_THERM, slope); 884 AR_WRITE(sc, AR_PHY_TPC_19, reg); 885 886 reg = AR_READ(sc, AR_PHY_TPC_18); 887 reg = RW(reg, AR_PHY_TPC_18_THERM_CAL, temp0); 888 AR_WRITE(sc, AR_PHY_TPC_18, reg); 889 AR_WRITE_BARRIER(sc); 890 } 891