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