1 /* $OpenBSD: ar5416.c,v 1.14 2014/07/22 13:12:11 mpi Exp $ */ 2 3 /*- 4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr> 5 * Copyright (c) 2008-2009 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 AR5416, AR5418 and AR9160 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/timeout.h> 36 #include <sys/conf.h> 37 #include <sys/device.h> 38 39 #include <machine/bus.h> 40 #include <machine/endian.h> 41 #include <machine/intr.h> 42 43 #if NBPFILTER > 0 44 #include <net/bpf.h> 45 #endif 46 #include <net/if.h> 47 #include <net/if_arp.h> 48 #include <net/if_dl.h> 49 #include <net/if_media.h> 50 #include <net/if_types.h> 51 52 #include <netinet/in.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/ar5008reg.h> 63 #include <dev/ic/ar5416reg.h> 64 65 int ar5416_attach(struct athn_softc *); 66 void ar5416_setup(struct athn_softc *); 67 void ar5416_swap_rom(struct athn_softc *); 68 const struct ar_spur_chan * 69 ar5416_get_spur_chans(struct athn_softc *, int); 70 int ar5416_set_synth(struct athn_softc *, struct ieee80211_channel *, 71 struct ieee80211_channel *); 72 uint8_t ar5416_reverse_bits(uint8_t, int); 73 uint8_t ar5416_get_rf_rev(struct athn_softc *); 74 void ar5416_init_from_rom(struct athn_softc *, struct ieee80211_channel *, 75 struct ieee80211_channel *); 76 int ar5416_init_calib(struct athn_softc *, struct ieee80211_channel *, 77 struct ieee80211_channel *); 78 void ar5416_set_power_calib(struct athn_softc *, 79 struct ieee80211_channel *); 80 void ar5416_set_txpower(struct athn_softc *, struct ieee80211_channel *, 81 struct ieee80211_channel *); 82 void ar5416_spur_mitigate(struct athn_softc *, struct ieee80211_channel *, 83 struct ieee80211_channel *); 84 void ar5416_rw_rfbits(uint32_t *, int, int, uint32_t, int); 85 void ar5416_rw_bank6tpc(struct athn_softc *, struct ieee80211_channel *, 86 uint32_t *); 87 void ar5416_rf_reset(struct athn_softc *, struct ieee80211_channel *); 88 void ar5416_reset_bb_gain(struct athn_softc *, struct ieee80211_channel *); 89 void ar5416_force_bias(struct athn_softc *, struct ieee80211_channel *); 90 void ar9160_rw_addac(struct athn_softc *, struct ieee80211_channel *, 91 uint32_t *); 92 void ar5416_reset_addac(struct athn_softc *, struct ieee80211_channel *); 93 void ar5416_get_pdadcs(struct athn_softc *, struct ieee80211_channel *, 94 int, int, uint8_t, uint8_t *, uint8_t *); 95 96 /* Extern functions. */ 97 uint8_t athn_chan2fbin(struct ieee80211_channel *); 98 void athn_get_pier_ival(uint8_t, const uint8_t *, int, int *, int *); 99 int ar5008_attach(struct athn_softc *); 100 void ar5008_write_txpower(struct athn_softc *, int16_t power[]); 101 void ar5008_get_pdadcs(struct athn_softc *, uint8_t, struct athn_pier *, 102 struct athn_pier *, int, int, uint8_t, uint8_t *, uint8_t *); 103 void ar5008_set_viterbi_mask(struct athn_softc *, int); 104 void ar5008_get_lg_tpow(struct athn_softc *, struct ieee80211_channel *, 105 uint8_t, const struct ar_cal_target_power_leg *, int, uint8_t[]); 106 void ar5008_get_ht_tpow(struct athn_softc *, struct ieee80211_channel *, 107 uint8_t, const struct ar_cal_target_power_ht *, int, uint8_t[]); 108 void ar9280_olpc_get_pdadcs(struct athn_softc *, struct ieee80211_channel *, 109 int, uint8_t *, uint8_t *, uint8_t *); 110 111 112 int 113 ar5416_attach(struct athn_softc *sc) 114 { 115 sc->eep_base = AR5416_EEP_START_LOC; 116 sc->eep_size = sizeof(struct ar5416_eeprom); 117 sc->def_nf = AR5416_PHY_CCA_MAX_GOOD_VALUE; 118 sc->ngpiopins = 14; 119 sc->led_pin = 1; 120 sc->workaround = AR5416_WA_DEFAULT; 121 sc->ops.setup = ar5416_setup; 122 sc->ops.swap_rom = ar5416_swap_rom; 123 sc->ops.init_from_rom = ar5416_init_from_rom; 124 sc->ops.set_txpower = ar5416_set_txpower; 125 sc->ops.set_synth = ar5416_set_synth; 126 sc->ops.spur_mitigate = ar5416_spur_mitigate; 127 sc->ops.get_spur_chans = ar5416_get_spur_chans; 128 if (AR_SREV_9160_10_OR_LATER(sc)) 129 sc->ini = &ar9160_ini; 130 else 131 sc->ini = &ar5416_ini; 132 sc->serdes = &ar5416_serdes; 133 134 return (ar5008_attach(sc)); 135 } 136 137 void 138 ar5416_setup(struct athn_softc *sc) 139 { 140 /* Select ADDAC programming. */ 141 if (AR_SREV_9160_11(sc)) 142 sc->addac = &ar9160_1_1_addac; 143 else if (AR_SREV_9160_10_OR_LATER(sc)) 144 sc->addac = &ar9160_1_0_addac; 145 else if (AR_SREV_5416_22_OR_LATER(sc)) 146 sc->addac = &ar5416_2_2_addac; 147 else 148 sc->addac = &ar5416_2_1_addac; 149 } 150 151 void 152 ar5416_swap_rom(struct athn_softc *sc) 153 { 154 struct ar5416_eeprom *eep = sc->eep; 155 struct ar5416_modal_eep_header *modal; 156 int i, j; 157 158 for (i = 0; i < 2; i++) { /* Dual-band. */ 159 modal = &eep->modalHeader[i]; 160 161 modal->antCtrlCommon = swap32(modal->antCtrlCommon); 162 for (j = 0; j < AR5416_MAX_CHAINS; j++) { 163 modal->antCtrlChain[j] = 164 swap32(modal->antCtrlChain[j]); 165 } 166 for (j = 0; j < AR_EEPROM_MODAL_SPURS; j++) { 167 modal->spurChans[j].spurChan = 168 swap16(modal->spurChans[j].spurChan); 169 } 170 } 171 } 172 173 const struct ar_spur_chan * 174 ar5416_get_spur_chans(struct athn_softc *sc, int is2ghz) 175 { 176 const struct ar5416_eeprom *eep = sc->eep; 177 178 return (eep->modalHeader[is2ghz].spurChans); 179 } 180 181 int 182 ar5416_set_synth(struct athn_softc *sc, struct ieee80211_channel *c, 183 struct ieee80211_channel *extc) 184 { 185 uint32_t phy, reg; 186 uint32_t freq = c->ic_freq; 187 uint8_t chansel; 188 189 phy = 0; 190 if (IEEE80211_IS_CHAN_2GHZ(c)) { 191 if (((freq - 2192) % 5) == 0) { 192 chansel = ((freq - 672) * 2 - 3040) / 10; 193 } else if (((freq - 2224) % 5) == 0) { 194 chansel = ((freq - 704) * 2 - 3040) / 10; 195 phy |= AR5416_BMODE_SYNTH; 196 } else 197 return (EINVAL); 198 chansel <<= 2; 199 200 reg = AR_READ(sc, AR_PHY_CCK_TX_CTRL); 201 if (freq == 2484) /* Channel 14. */ 202 reg |= AR_PHY_CCK_TX_CTRL_JAPAN; 203 else 204 reg &= ~AR_PHY_CCK_TX_CTRL_JAPAN; 205 AR_WRITE(sc, AR_PHY_CCK_TX_CTRL, reg); 206 207 /* Fix for orientation sensitivity issue. */ 208 if (AR_SREV_5416(sc)) 209 ar5416_force_bias(sc, c); 210 } else { 211 if (freq >= 5120 && (freq % 20) == 0) { 212 chansel = (freq - 4800) / 20; 213 chansel <<= 2; 214 phy |= SM(AR5416_AMODE_REFSEL, 2); 215 } else if ((freq % 10) == 0) { 216 chansel = (freq - 4800) / 10; 217 chansel <<= 1; 218 if (AR_SREV_9160_10_OR_LATER(sc)) 219 phy |= SM(AR5416_AMODE_REFSEL, 1); 220 else 221 phy |= SM(AR5416_AMODE_REFSEL, 2); 222 } else if ((freq % 5) == 0) { 223 chansel = (freq - 4800) / 5; 224 phy |= SM(AR5416_AMODE_REFSEL, 2); 225 } else 226 return (EINVAL); 227 } 228 chansel = ar5416_reverse_bits(chansel, 8); 229 phy |= chansel << 8 | 1 << 5 | 1; 230 DPRINTFN(4, ("AR_PHY(0x37)=0x%08x\n", phy)); 231 AR_WRITE(sc, AR_PHY(0x37), phy); 232 return (0); 233 } 234 235 void 236 ar5416_init_from_rom(struct athn_softc *sc, struct ieee80211_channel *c, 237 struct ieee80211_channel *extc) 238 { 239 static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 }; 240 const struct ar5416_eeprom *eep = sc->eep; 241 const struct ar5416_modal_eep_header *modal; 242 uint32_t reg, offset; 243 uint8_t txRxAtten; 244 int i; 245 246 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)]; 247 248 AR_WRITE(sc, AR_PHY_SWITCH_COM, modal->antCtrlCommon); 249 250 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 251 if (AR_SREV_5416_20_OR_LATER(sc) && 252 (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5)) 253 offset = chainoffset[i]; 254 else 255 offset = i * 0x1000; 256 257 AR_WRITE(sc, AR_PHY_SWITCH_CHAIN_0 + offset, 258 modal->antCtrlChain[i]); 259 260 reg = AR_READ(sc, AR_PHY_TIMING_CTRL4_0 + offset); 261 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, 262 modal->iqCalICh[i]); 263 reg = RW(reg, AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, 264 modal->iqCalQCh[i]); 265 AR_WRITE(sc, AR_PHY_TIMING_CTRL4_0 + offset, reg); 266 267 if (i > 0 && !AR_SREV_5416_20_OR_LATER(sc)) 268 continue; 269 270 if (sc->eep_rev >= AR_EEP_MINOR_VER_3) { 271 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset); 272 reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_MARGIN, 273 modal->bswMargin[i]); 274 reg = RW(reg, AR_PHY_GAIN_2GHZ_BSW_ATTEN, 275 modal->bswAtten[i]); 276 AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg); 277 } 278 if (sc->eep_rev >= AR_EEP_MINOR_VER_3) 279 txRxAtten = modal->txRxAttenCh[i]; 280 else /* Workaround for ROM versions < 14.3. */ 281 txRxAtten = IEEE80211_IS_CHAN_2GHZ(c) ? 23 : 44; 282 reg = AR_READ(sc, AR_PHY_RXGAIN + offset); 283 reg = RW(reg, AR_PHY_RXGAIN_TXRX_ATTEN, txRxAtten); 284 AR_WRITE(sc, AR_PHY_RXGAIN + offset, reg); 285 286 reg = AR_READ(sc, AR_PHY_GAIN_2GHZ + offset); 287 reg = RW(reg, AR_PHY_GAIN_2GHZ_RXTX_MARGIN, 288 modal->rxTxMarginCh[i]); 289 AR_WRITE(sc, AR_PHY_GAIN_2GHZ + offset, reg); 290 } 291 reg = AR_READ(sc, AR_PHY_SETTLING); 292 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->switchSettling); 293 AR_WRITE(sc, AR_PHY_SETTLING, reg); 294 295 reg = AR_READ(sc, AR_PHY_DESIRED_SZ); 296 reg = RW(reg, AR_PHY_DESIRED_SZ_ADC, modal->adcDesiredSize); 297 reg = RW(reg, AR_PHY_DESIRED_SZ_PGA, modal->pgaDesiredSize); 298 AR_WRITE(sc, AR_PHY_DESIRED_SZ, reg); 299 300 reg = SM(AR_PHY_RF_CTL4_TX_END_XPAA_OFF, modal->txEndToXpaOff); 301 reg |= SM(AR_PHY_RF_CTL4_TX_END_XPAB_OFF, modal->txEndToXpaOff); 302 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAA_ON, modal->txFrameToXpaOn); 303 reg |= SM(AR_PHY_RF_CTL4_FRAME_XPAB_ON, modal->txFrameToXpaOn); 304 AR_WRITE(sc, AR_PHY_RF_CTL4, reg); 305 306 reg = AR_READ(sc, AR_PHY_RF_CTL3); 307 reg = RW(reg, AR_PHY_TX_END_TO_A2_RX_ON, modal->txEndToRxOn); 308 AR_WRITE(sc, AR_PHY_RF_CTL3, reg); 309 310 reg = AR_READ(sc, AR_PHY_CCA(0)); 311 reg = RW(reg, AR_PHY_CCA_THRESH62, modal->thresh62); 312 AR_WRITE(sc, AR_PHY_CCA(0), reg); 313 314 reg = AR_READ(sc, AR_PHY_EXT_CCA(0)); 315 reg = RW(reg, AR_PHY_EXT_CCA_THRESH62, modal->thresh62); 316 AR_WRITE(sc, AR_PHY_EXT_CCA(0), reg); 317 318 if (sc->eep_rev >= AR_EEP_MINOR_VER_2) { 319 reg = AR_READ(sc, AR_PHY_RF_CTL2); 320 reg = RW(reg, AR_PHY_TX_END_DATA_START, 321 modal->txFrameToDataStart); 322 reg = RW(reg, AR_PHY_TX_END_PA_ON, modal->txFrameToPaOn); 323 AR_WRITE(sc, AR_PHY_RF_CTL2, reg); 324 } 325 #ifndef IEEE80211_NO_HT 326 if (sc->eep_rev >= AR_EEP_MINOR_VER_3 && extc != NULL) { 327 /* Overwrite switch settling with HT-40 value. */ 328 reg = AR_READ(sc, AR_PHY_SETTLING); 329 reg = RW(reg, AR_PHY_SETTLING_SWITCH, modal->swSettleHt40); 330 AR_WRITE(sc, AR_PHY_SETTLING, reg); 331 } 332 #endif 333 } 334 335 int 336 ar5416_init_calib(struct athn_softc *sc, struct ieee80211_channel *c, 337 struct ieee80211_channel *extc) 338 { 339 int ntries; 340 341 if (AR_SREV_9280_10_OR_LATER(sc)) { 342 /* XXX Linux tests AR9287?! */ 343 AR_CLRBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); 344 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, 345 AR_PHY_AGC_CONTROL_FLTR_CAL); 346 } 347 /* Calibrate the AGC. */ 348 AR_SETBITS(sc, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); 349 /* Poll for offset calibration completion. */ 350 for (ntries = 0; ntries < 10000; ntries++) { 351 if (!(AR_READ(sc, AR_PHY_AGC_CONTROL) & 352 AR_PHY_AGC_CONTROL_CAL)) 353 break; 354 DELAY(10); 355 } 356 if (ntries == 10000) 357 return (ETIMEDOUT); 358 if (AR_SREV_9280_10_OR_LATER(sc)) { 359 AR_SETBITS(sc, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); 360 AR_CLRBITS(sc, AR_PHY_AGC_CONTROL, 361 AR_PHY_AGC_CONTROL_FLTR_CAL); 362 } 363 return (0); 364 } 365 366 void 367 ar5416_get_pdadcs(struct athn_softc *sc, struct ieee80211_channel *c, 368 int chain, int nxpdgains, uint8_t overlap, uint8_t *boundaries, 369 uint8_t *pdadcs) 370 { 371 const struct ar5416_eeprom *eep = sc->eep; 372 const struct ar5416_cal_data_per_freq *pierdata; 373 const uint8_t *pierfreq; 374 struct athn_pier lopier, hipier; 375 int16_t delta; 376 uint8_t fbin, pwroff; 377 int i, lo, hi, npiers; 378 379 if (IEEE80211_IS_CHAN_2GHZ(c)) { 380 pierfreq = eep->calFreqPier2G; 381 pierdata = eep->calPierData2G[chain]; 382 npiers = AR5416_NUM_2G_CAL_PIERS; 383 } else { 384 pierfreq = eep->calFreqPier5G; 385 pierdata = eep->calPierData5G[chain]; 386 npiers = AR5416_NUM_5G_CAL_PIERS; 387 } 388 /* Find channel in ROM pier table. */ 389 fbin = athn_chan2fbin(c); 390 athn_get_pier_ival(fbin, pierfreq, npiers, &lo, &hi); 391 392 lopier.fbin = pierfreq[lo]; 393 hipier.fbin = pierfreq[hi]; 394 for (i = 0; i < nxpdgains; i++) { 395 lopier.pwr[i] = pierdata[lo].pwrPdg[i]; 396 lopier.vpd[i] = pierdata[lo].vpdPdg[i]; 397 hipier.pwr[i] = pierdata[lo].pwrPdg[i]; 398 hipier.vpd[i] = pierdata[lo].vpdPdg[i]; 399 } 400 ar5008_get_pdadcs(sc, fbin, &lopier, &hipier, nxpdgains, 401 AR5416_PD_GAIN_ICEPTS, overlap, boundaries, pdadcs); 402 403 if (!AR_SREV_9280_20_OR_LATER(sc)) 404 return; 405 406 if (sc->eep_rev >= AR_EEP_MINOR_VER_21) 407 pwroff = eep->baseEepHeader.pwrTableOffset; 408 else 409 pwroff = AR_PWR_TABLE_OFFSET_DB; 410 delta = (pwroff - AR_PWR_TABLE_OFFSET_DB) * 2; /* In half dB. */ 411 412 /* Change the original gain boundaries setting. */ 413 for (i = 0; i < nxpdgains; i++) { 414 /* XXX Possible overflows? */ 415 boundaries[i] -= delta; 416 if (boundaries[i] > AR_MAX_RATE_POWER - overlap) 417 boundaries[i] = AR_MAX_RATE_POWER - overlap; 418 } 419 if (delta != 0) { 420 /* Shift the PDADC table to start at the new offset. */ 421 for (i = 0; i < AR_NUM_PDADC_VALUES; i++) 422 pdadcs[i] = pdadcs[MIN(i + delta, 423 AR_NUM_PDADC_VALUES - 1)]; 424 } 425 } 426 427 void 428 ar5416_set_power_calib(struct athn_softc *sc, struct ieee80211_channel *c) 429 { 430 static const uint32_t chainoffset[] = { 0x0000, 0x2000, 0x1000 }; 431 const struct ar5416_eeprom *eep = sc->eep; 432 const struct ar5416_modal_eep_header *modal; 433 uint8_t boundaries[AR_PD_GAINS_IN_MASK]; 434 uint8_t pdadcs[AR_NUM_PDADC_VALUES]; 435 uint8_t xpdgains[AR5416_NUM_PD_GAINS]; 436 uint8_t overlap, txgain; 437 uint32_t reg, offset; 438 int i, j, nxpdgains; 439 440 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)]; 441 442 if (sc->eep_rev < AR_EEP_MINOR_VER_2) { 443 overlap = MS(AR_READ(sc, AR_PHY_TPCRG5), 444 AR_PHY_TPCRG5_PD_GAIN_OVERLAP); 445 } else 446 overlap = modal->pdGainOverlap; 447 448 if ((sc->flags & ATHN_FLAG_OLPC) && IEEE80211_IS_CHAN_2GHZ(c)) { 449 /* XXX not here. */ 450 sc->pdadc = 451 ((const struct ar_cal_data_per_freq_olpc *) 452 eep->calPierData2G[0])->vpdPdg[0][0]; 453 } 454 455 nxpdgains = 0; 456 memset(xpdgains, 0, sizeof(xpdgains)); 457 for (i = AR5416_PD_GAINS_IN_MASK - 1; i >= 0; i--) { 458 if (nxpdgains >= AR5416_NUM_PD_GAINS) 459 break; /* Can't happen. */ 460 if (modal->xpdGain & (1 << i)) 461 xpdgains[nxpdgains++] = i; 462 } 463 reg = AR_READ(sc, AR_PHY_TPCRG1); 464 reg = RW(reg, AR_PHY_TPCRG1_NUM_PD_GAIN, nxpdgains - 1); 465 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_1, xpdgains[0]); 466 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_2, xpdgains[1]); 467 reg = RW(reg, AR_PHY_TPCRG1_PD_GAIN_3, xpdgains[2]); 468 AR_WRITE(sc, AR_PHY_TPCRG1, reg); 469 470 for (i = 0; i < AR5416_MAX_CHAINS; i++) { 471 if (!(sc->txchainmask & (1 << i))) 472 continue; 473 474 if (AR_SREV_5416_20_OR_LATER(sc) && 475 (sc->rxchainmask == 0x5 || sc->txchainmask == 0x5)) 476 offset = chainoffset[i]; 477 else 478 offset = i * 0x1000; 479 480 if (sc->flags & ATHN_FLAG_OLPC) { 481 ar9280_olpc_get_pdadcs(sc, c, i, boundaries, 482 pdadcs, &txgain); 483 484 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_0); 485 reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 486 AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_0, reg); 487 488 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL6_1); 489 reg = RW(reg, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); 490 AR_WRITE(sc, AR_PHY_TX_PWRCTRL6_1, reg); 491 492 reg = AR_READ(sc, AR_PHY_TX_PWRCTRL7); 493 reg = RW(reg, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, txgain); 494 AR_WRITE(sc, AR_PHY_TX_PWRCTRL7, reg); 495 496 overlap = 6; 497 } else { 498 ar5416_get_pdadcs(sc, c, i, nxpdgains, overlap, 499 boundaries, pdadcs); 500 } 501 /* Write boundaries. */ 502 if (i == 0 || AR_SREV_5416_20_OR_LATER(sc)) { 503 reg = SM(AR_PHY_TPCRG5_PD_GAIN_OVERLAP, 504 overlap); 505 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1, 506 boundaries[0]); 507 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2, 508 boundaries[1]); 509 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3, 510 boundaries[2]); 511 reg |= SM(AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4, 512 boundaries[3]); 513 AR_WRITE(sc, AR_PHY_TPCRG5 + offset, reg); 514 } 515 /* Write PDADC values. */ 516 for (j = 0; j < AR_NUM_PDADC_VALUES; j += 4) { 517 AR_WRITE(sc, AR_PHY_PDADC_TBL_BASE + offset + j, 518 pdadcs[j + 0] << 0 | 519 pdadcs[j + 1] << 8 | 520 pdadcs[j + 2] << 16 | 521 pdadcs[j + 3] << 24); 522 } 523 } 524 } 525 526 void 527 ar5416_set_txpower(struct athn_softc *sc, struct ieee80211_channel *c, 528 struct ieee80211_channel *extc) 529 { 530 const struct ar5416_eeprom *eep = sc->eep; 531 const struct ar5416_modal_eep_header *modal; 532 uint8_t tpow_cck[4], tpow_ofdm[4]; 533 #ifndef IEEE80211_NO_HT 534 uint8_t tpow_cck_ext[4], tpow_ofdm_ext[4]; 535 uint8_t tpow_ht20[8], tpow_ht40[8]; 536 uint8_t ht40inc; 537 #endif 538 int16_t pwr = 0, pwroff, max_ant_gain, power[ATHN_POWER_COUNT]; 539 uint8_t cckinc; 540 int i; 541 542 ar5416_set_power_calib(sc, c); 543 544 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)]; 545 546 /* Compute transmit power reduction due to antenna gain. */ 547 max_ant_gain = MAX(modal->antennaGainCh[0], modal->antennaGainCh[1]); 548 max_ant_gain = MAX(modal->antennaGainCh[2], max_ant_gain); 549 /* XXX */ 550 551 /* 552 * Reduce scaled power by number of active chains to get per-chain 553 * transmit power level. 554 */ 555 if (sc->ntxchains == 2) 556 pwr -= AR_PWR_DECREASE_FOR_2_CHAIN; 557 else if (sc->ntxchains == 3) 558 pwr -= AR_PWR_DECREASE_FOR_3_CHAIN; 559 if (pwr < 0) 560 pwr = 0; 561 562 if (IEEE80211_IS_CHAN_2GHZ(c)) { 563 /* Get CCK target powers. */ 564 ar5008_get_lg_tpow(sc, c, AR_CTL_11B, eep->calTargetPowerCck, 565 AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck); 566 567 /* Get OFDM target powers. */ 568 ar5008_get_lg_tpow(sc, c, AR_CTL_11G, eep->calTargetPower2G, 569 AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm); 570 571 #ifndef IEEE80211_NO_HT 572 /* Get HT-20 target powers. */ 573 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT20, 574 eep->calTargetPower2GHT20, AR5416_NUM_2G_20_TARGET_POWERS, 575 tpow_ht20); 576 577 if (extc != NULL) { 578 /* Get HT-40 target powers. */ 579 ar5008_get_ht_tpow(sc, c, AR_CTL_2GHT40, 580 eep->calTargetPower2GHT40, 581 AR5416_NUM_2G_40_TARGET_POWERS, tpow_ht40); 582 583 /* Get secondary channel CCK target powers. */ 584 ar5008_get_lg_tpow(sc, extc, AR_CTL_11B, 585 eep->calTargetPowerCck, 586 AR5416_NUM_2G_CCK_TARGET_POWERS, tpow_cck_ext); 587 588 /* Get secondary channel OFDM target powers. */ 589 ar5008_get_lg_tpow(sc, extc, AR_CTL_11G, 590 eep->calTargetPower2G, 591 AR5416_NUM_2G_20_TARGET_POWERS, tpow_ofdm_ext); 592 } 593 #endif 594 } else { 595 /* Get OFDM target powers. */ 596 ar5008_get_lg_tpow(sc, c, AR_CTL_11A, eep->calTargetPower5G, 597 AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm); 598 599 #ifndef IEEE80211_NO_HT 600 /* Get HT-20 target powers. */ 601 ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT20, 602 eep->calTargetPower5GHT20, AR5416_NUM_5G_20_TARGET_POWERS, 603 tpow_ht20); 604 605 if (extc != NULL) { 606 /* Get HT-40 target powers. */ 607 ar5008_get_ht_tpow(sc, c, AR_CTL_5GHT40, 608 eep->calTargetPower5GHT40, 609 AR5416_NUM_5G_40_TARGET_POWERS, tpow_ht40); 610 611 /* Get secondary channel OFDM target powers. */ 612 ar5008_get_lg_tpow(sc, extc, AR_CTL_11A, 613 eep->calTargetPower5G, 614 AR5416_NUM_5G_20_TARGET_POWERS, tpow_ofdm_ext); 615 } 616 #endif 617 } 618 619 /* Compute CCK/OFDM delta. */ 620 cckinc = (sc->flags & ATHN_FLAG_OLPC) ? -2 : 0; 621 622 memset(power, 0, sizeof(power)); 623 /* Shuffle target powers accross transmit rates. */ 624 power[ATHN_POWER_OFDM6 ] = 625 power[ATHN_POWER_OFDM9 ] = 626 power[ATHN_POWER_OFDM12] = 627 power[ATHN_POWER_OFDM18] = 628 power[ATHN_POWER_OFDM24] = tpow_ofdm[0]; 629 power[ATHN_POWER_OFDM36] = tpow_ofdm[1]; 630 power[ATHN_POWER_OFDM48] = tpow_ofdm[2]; 631 power[ATHN_POWER_OFDM54] = tpow_ofdm[3]; 632 power[ATHN_POWER_XR ] = tpow_ofdm[0]; 633 if (IEEE80211_IS_CHAN_2GHZ(c)) { 634 power[ATHN_POWER_CCK1_LP ] = tpow_cck[0] + cckinc; 635 power[ATHN_POWER_CCK2_LP ] = 636 power[ATHN_POWER_CCK2_SP ] = tpow_cck[1] + cckinc; 637 power[ATHN_POWER_CCK55_LP] = 638 power[ATHN_POWER_CCK55_SP] = tpow_cck[2] + cckinc; 639 power[ATHN_POWER_CCK11_LP] = 640 power[ATHN_POWER_CCK11_SP] = tpow_cck[3] + cckinc; 641 } 642 #ifndef IEEE80211_NO_HT 643 for (i = 0; i < nitems(tpow_ht20); i++) 644 power[ATHN_POWER_HT20(i)] = tpow_ht20[i]; 645 if (extc != NULL) { 646 /* Correct PAR difference between HT40 and HT20/Legacy. */ 647 if (sc->eep_rev >= AR_EEP_MINOR_VER_2) 648 ht40inc = modal->ht40PowerIncForPdadc; 649 else 650 ht40inc = AR_HT40_POWER_INC_FOR_PDADC; 651 for (i = 0; i < nitems(tpow_ht40); i++) 652 power[ATHN_POWER_HT40(i)] = tpow_ht40[i] + ht40inc; 653 power[ATHN_POWER_OFDM_DUP] = tpow_ht40[0]; 654 power[ATHN_POWER_CCK_DUP ] = tpow_ht40[0] + cckinc; 655 power[ATHN_POWER_OFDM_EXT] = tpow_ofdm_ext[0]; 656 if (IEEE80211_IS_CHAN_2GHZ(c)) 657 power[ATHN_POWER_CCK_EXT] = tpow_cck_ext[0] + cckinc; 658 } 659 #endif 660 661 if (AR_SREV_9280_10_OR_LATER(sc)) { 662 if (sc->eep_rev >= AR_EEP_MINOR_VER_21) 663 pwroff = eep->baseEepHeader.pwrTableOffset; 664 else 665 pwroff = AR_PWR_TABLE_OFFSET_DB; 666 for (i = 0; i < ATHN_POWER_COUNT; i++) 667 power[i] -= pwroff * 2; /* In half dB. */ 668 } 669 for (i = 0; i < ATHN_POWER_COUNT; i++) { 670 if (power[i] > AR_MAX_RATE_POWER) 671 power[i] = AR_MAX_RATE_POWER; 672 } 673 674 /* Write transmit power values to hardware. */ 675 ar5008_write_txpower(sc, power); 676 677 /* 678 * Write transmit power substraction for dynamic chain changing 679 * and per-packet transmit power. 680 */ 681 AR_WRITE(sc, AR_PHY_POWER_TX_SUB, 682 (modal->pwrDecreaseFor3Chain & 0x3f) << 6 | 683 (modal->pwrDecreaseFor2Chain & 0x3f)); 684 } 685 686 void 687 ar5416_spur_mitigate(struct athn_softc *sc, struct ieee80211_channel *c, 688 struct ieee80211_channel *extc) 689 { 690 const struct ar_spur_chan *spurchans; 691 int i, spur, bin, spur_delta_phase, spur_freq_sd; 692 693 spurchans = sc->ops.get_spur_chans(sc, IEEE80211_IS_CHAN_2GHZ(c)); 694 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 695 spur = spurchans[i].spurChan; 696 if (spur == AR_NO_SPUR) 697 return; /* XXX disable if it was enabled! */ 698 spur -= c->ic_freq * 10; 699 /* Verify range +/-9.5MHz */ 700 if (abs(spur) < 95) 701 break; 702 } 703 if (i == AR_EEPROM_MODAL_SPURS) 704 return; /* XXX disable if it was enabled! */ 705 DPRINTFN(2, ("enabling spur mitigation\n")); 706 707 AR_SETBITS(sc, AR_PHY_TIMING_CTRL4_0, 708 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 709 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 710 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 711 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 712 713 AR_WRITE(sc, AR_PHY_SPUR_REG, 714 AR_PHY_SPUR_REG_MASK_RATE_CNTL | 715 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 716 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 717 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 718 SM(AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, AR_SPUR_RSSI_THRESH)); 719 720 spur_delta_phase = (spur * 524288) / 100; 721 if (IEEE80211_IS_CHAN_2GHZ(c)) 722 spur_freq_sd = (spur * 2048) / 440; 723 else 724 spur_freq_sd = (spur * 2048) / 400; 725 726 AR_WRITE(sc, AR_PHY_TIMING11, 727 AR_PHY_TIMING11_USE_SPUR_IN_AGC | 728 SM(AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd) | 729 SM(AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase)); 730 731 bin = spur * 32; 732 ar5008_set_viterbi_mask(sc, bin); 733 } 734 735 uint8_t 736 ar5416_reverse_bits(uint8_t v, int nbits) 737 { 738 KASSERT(nbits <= 8); 739 v = ((v >> 1) & 0x55) | ((v & 0x55) << 1); 740 v = ((v >> 2) & 0x33) | ((v & 0x33) << 2); 741 v = ((v >> 4) & 0x0f) | ((v & 0x0f) << 4); 742 return (v >> (8 - nbits)); 743 } 744 745 uint8_t 746 ar5416_get_rf_rev(struct athn_softc *sc) 747 { 748 uint8_t rev, reg; 749 int i; 750 751 /* Allow access to analog chips. */ 752 AR_WRITE(sc, AR_PHY(0), 0x00000007); 753 754 AR_WRITE(sc, AR_PHY(0x36), 0x00007058); 755 for (i = 0; i < 8; i++) 756 AR_WRITE(sc, AR_PHY(0x20), 0x00010000); 757 reg = (AR_READ(sc, AR_PHY(256)) >> 24) & 0xff; 758 reg = (reg & 0xf0) >> 4 | (reg & 0x0f) << 4; 759 760 rev = ar5416_reverse_bits(reg, 8); 761 if ((rev & AR_RADIO_SREV_MAJOR) == 0) 762 rev = AR_RAD5133_SREV_MAJOR; 763 return (rev); 764 } 765 766 /* 767 * Replace bits "off" to "off+nbits-1" in column "col" with the specified 768 * value. 769 */ 770 void 771 ar5416_rw_rfbits(uint32_t *buf, int col, int off, uint32_t val, int nbits) 772 { 773 int idx, bit; 774 775 KASSERT(off >= 1 && col < 4 && nbits <= 32); 776 777 off--; /* Starts at 1. */ 778 while (nbits-- > 0) { 779 idx = off / 8; 780 bit = off % 8; 781 buf[idx] &= ~(1 << (bit + col * 8)); 782 buf[idx] |= ((val >> nbits) & 1) << (bit + col * 8); 783 off++; 784 } 785 } 786 787 /* 788 * Overwrite db and ob based on ROM settings. 789 */ 790 void 791 ar5416_rw_bank6tpc(struct athn_softc *sc, struct ieee80211_channel *c, 792 uint32_t *rwbank6tpc) 793 { 794 const struct ar5416_eeprom *eep = sc->eep; 795 const struct ar5416_modal_eep_header *modal; 796 797 if (IEEE80211_IS_CHAN_5GHZ(c)) { 798 modal = &eep->modalHeader[0]; 799 /* 5GHz db in column 0, bits [200-202]. */ 800 ar5416_rw_rfbits(rwbank6tpc, 0, 200, modal->db, 3); 801 /* 5GHz ob in column 0, bits [203-205]. */ 802 ar5416_rw_rfbits(rwbank6tpc, 0, 203, modal->ob, 3); 803 } else { 804 modal = &eep->modalHeader[1]; 805 /* 2GHz db in column 0, bits [194-196]. */ 806 ar5416_rw_rfbits(rwbank6tpc, 0, 194, modal->db, 3); 807 /* 2GHz ob in column 0, bits [197-199]. */ 808 ar5416_rw_rfbits(rwbank6tpc, 0, 197, modal->ob, 3); 809 } 810 } 811 812 /* 813 * Program analog RF. 814 */ 815 void 816 ar5416_rf_reset(struct athn_softc *sc, struct ieee80211_channel *c) 817 { 818 const uint32_t *bank6tpc; 819 int i; 820 821 /* Bank 0. */ 822 AR_WRITE(sc, 0x98b0, 0x1e5795e5); 823 AR_WRITE(sc, 0x98e0, 0x02008020); 824 825 /* Bank 1. */ 826 AR_WRITE(sc, 0x98b0, 0x02108421); 827 AR_WRITE(sc, 0x98ec, 0x00000008); 828 829 /* Bank 2. */ 830 AR_WRITE(sc, 0x98b0, 0x0e73ff17); 831 AR_WRITE(sc, 0x98e0, 0x00000420); 832 833 /* Bank 3. */ 834 if (IEEE80211_IS_CHAN_5GHZ(c)) 835 AR_WRITE(sc, 0x98f0, 0x01400018); 836 else 837 AR_WRITE(sc, 0x98f0, 0x01c00018); 838 839 /* Select the Bank 6 TPC values to use. */ 840 if (AR_SREV_9160_10_OR_LATER(sc)) 841 bank6tpc = ar9160_bank6tpc_vals; 842 else 843 bank6tpc = ar5416_bank6tpc_vals; 844 if (sc->eep_rev >= AR_EEP_MINOR_VER_2) { 845 uint32_t *rwbank6tpc = sc->rwbuf; 846 847 /* Copy values from .rodata to writable buffer. */ 848 memcpy(rwbank6tpc, bank6tpc, 32 * sizeof(uint32_t)); 849 ar5416_rw_bank6tpc(sc, c, rwbank6tpc); 850 bank6tpc = rwbank6tpc; 851 } 852 /* Bank 6 TPC. */ 853 for (i = 0; i < 32; i++) 854 AR_WRITE(sc, 0x989c, bank6tpc[i]); 855 if (IEEE80211_IS_CHAN_5GHZ(c)) 856 AR_WRITE(sc, 0x98d0, 0x0000000f); 857 else 858 AR_WRITE(sc, 0x98d0, 0x0010000f); 859 860 /* Bank 7. */ 861 AR_WRITE(sc, 0x989c, 0x00000500); 862 AR_WRITE(sc, 0x989c, 0x00000800); 863 AR_WRITE(sc, 0x98cc, 0x0000000e); 864 } 865 866 void 867 ar5416_reset_bb_gain(struct athn_softc *sc, struct ieee80211_channel *c) 868 { 869 const uint32_t *pvals; 870 int i; 871 872 if (IEEE80211_IS_CHAN_2GHZ(c)) 873 pvals = ar5416_bb_rfgain_vals_2g; 874 else 875 pvals = ar5416_bb_rfgain_vals_5g; 876 for (i = 0; i < 64; i++) 877 AR_WRITE(sc, AR_PHY_BB_RFGAIN(i), pvals[i]); 878 } 879 880 /* 881 * Fix orientation sensitivity issue on AR5416/2GHz by increasing 882 * rf_pwd_icsyndiv. 883 */ 884 void 885 ar5416_force_bias(struct athn_softc *sc, struct ieee80211_channel *c) 886 { 887 uint32_t *rwbank6 = sc->rwbuf; 888 uint8_t bias; 889 int i; 890 891 KASSERT(IEEE80211_IS_CHAN_2GHZ(c)); 892 893 /* Copy values from .rodata to writable buffer. */ 894 memcpy(rwbank6, ar5416_bank6_vals, sizeof(ar5416_bank6_vals)); 895 896 if (c->ic_freq < 2412) 897 bias = 0; 898 else if (c->ic_freq < 2422) 899 bias = 1; 900 else 901 bias = 2; 902 ar5416_reverse_bits(bias, 3); 903 904 /* Overwrite "rf_pwd_icsyndiv" (column 3, bits [181-183].) */ 905 ar5416_rw_rfbits(rwbank6, 3, 181, bias, 3); 906 907 /* Write Bank 6. */ 908 for (i = 0; i < 32; i++) 909 AR_WRITE(sc, 0x989c, rwbank6[i]); 910 AR_WRITE(sc, 0x98d0, 0x0010000f); 911 } 912 913 /* 914 * Overwrite XPA bias level based on ROM setting. 915 */ 916 void 917 ar9160_rw_addac(struct athn_softc *sc, struct ieee80211_channel *c, 918 uint32_t *addac) 919 { 920 struct ar5416_eeprom *eep = sc->eep; 921 struct ar5416_modal_eep_header *modal; 922 uint8_t fbin, bias; 923 int i; 924 925 /* XXX xpaBiasLvlFreq values have not been endian-swapped? */ 926 927 /* Get the XPA bias level to use for the specified channel. */ 928 modal = &eep->modalHeader[IEEE80211_IS_CHAN_2GHZ(c)]; 929 if (modal->xpaBiasLvl == 0xff) { 930 bias = modal->xpaBiasLvlFreq[0] >> 14; 931 fbin = athn_chan2fbin(c); 932 for (i = 1; i < 3; i++) { 933 if (modal->xpaBiasLvlFreq[i] == 0) 934 break; 935 if ((modal->xpaBiasLvlFreq[i] & 0xff) < fbin) 936 break; 937 bias = modal->xpaBiasLvlFreq[i] >> 14; 938 } 939 } else 940 bias = modal->xpaBiasLvl & 0x3; 941 942 bias = ar5416_reverse_bits(bias, 2); /* Put in host bit-order. */ 943 DPRINTFN(4, ("bias level=%d\n", bias)); 944 if (IEEE80211_IS_CHAN_2GHZ(c)) 945 ar5416_rw_rfbits(addac, 0, 60, bias, 2); 946 else 947 ar5416_rw_rfbits(addac, 0, 55, bias, 2); 948 } 949 950 void 951 ar5416_reset_addac(struct athn_softc *sc, struct ieee80211_channel *c) 952 { 953 const struct athn_addac *addac = sc->addac; 954 const uint32_t *pvals; 955 int i; 956 957 if (AR_SREV_9160(sc) && sc->eep_rev >= AR_EEP_MINOR_VER_7) { 958 uint32_t *rwaddac = sc->rwbuf; 959 960 /* Copy values from .rodata to writable buffer. */ 961 memcpy(rwaddac, addac->vals, addac->nvals * sizeof(uint32_t)); 962 ar9160_rw_addac(sc, c, rwaddac); 963 pvals = rwaddac; 964 } else 965 pvals = addac->vals; 966 for (i = 0; i < addac->nvals; i++) 967 AR_WRITE(sc, 0x989c, pvals[i]); 968 AR_WRITE(sc, 0x98cc, 0); /* Finalize. */ 969 } 970