1/* 2 * Copyright (c) 2010 Atheros Communications Inc. 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 "hw.h" 18#include "ar9003_phy.h" 19 20static const int firstep_table[] = 21/* level: 0 1 2 3 4 5 6 7 8 */ 22 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ 23 24static const int cycpwrThr1_table[] = 25/* level: 0 1 2 3 4 5 6 7 8 */ 26 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ 27 28/* 29 * register values to turn OFDM weak signal detection OFF 30 */ 31static const int m1ThreshLow_off = 127; 32static const int m2ThreshLow_off = 127; 33static const int m1Thresh_off = 127; 34static const int m2Thresh_off = 127; 35static const int m2CountThr_off = 31; 36static const int m2CountThrLow_off = 63; 37static const int m1ThreshLowExt_off = 127; 38static const int m2ThreshLowExt_off = 127; 39static const int m1ThreshExt_off = 127; 40static const int m2ThreshExt_off = 127; 41 42/** 43 * ar9003_hw_set_channel - set channel on single-chip device 44 * @ah: atheros hardware structure 45 * @chan: 46 * 47 * This is the function to change channel on single-chip devices, that is 48 * all devices after ar9280. 49 * 50 * This function takes the channel value in MHz and sets 51 * hardware channel value. Assumes writes have been enabled to analog bus. 52 * 53 * Actual Expression, 54 * 55 * For 2GHz channel, 56 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 57 * (freq_ref = 40MHz) 58 * 59 * For 5GHz channel, 60 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) 61 * (freq_ref = 40MHz/(24>>amodeRefSel)) 62 * 63 * For 5GHz channels which are 5MHz spaced, 64 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) 65 * (freq_ref = 40MHz) 66 */ 67static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) 68{ 69 u16 bMode, fracMode = 0, aModeRefSel = 0; 70 u32 freq, channelSel = 0, reg32 = 0; 71 struct chan_centers centers; 72 int loadSynthChannel; 73 74 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 75 freq = centers.synth_center; 76 77 if (freq < 4800) { /* 2 GHz, fractional mode */ 78 channelSel = CHANSEL_2G(freq); 79 /* Set to 2G mode */ 80 bMode = 1; 81 } else { 82 channelSel = CHANSEL_5G(freq); 83 /* Doubler is ON, so, divide channelSel by 2. */ 84 channelSel >>= 1; 85 /* Set to 5G mode */ 86 bMode = 0; 87 } 88 89 /* Enable fractional mode for all channels */ 90 fracMode = 1; 91 aModeRefSel = 0; 92 loadSynthChannel = 0; 93 94 reg32 = (bMode << 29); 95 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); 96 97 /* Enable Long shift Select for Synthesizer */ 98 REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4, 99 AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1); 100 101 /* Program Synth. setting */ 102 reg32 = (channelSel << 2) | (fracMode << 30) | 103 (aModeRefSel << 28) | (loadSynthChannel << 31); 104 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); 105 106 /* Toggle Load Synth channel bit */ 107 loadSynthChannel = 1; 108 reg32 = (channelSel << 2) | (fracMode << 30) | 109 (aModeRefSel << 28) | (loadSynthChannel << 31); 110 REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); 111 112 ah->curchan = chan; 113 ah->curchan_rad_index = -1; 114 115 return 0; 116} 117 118/** 119 * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency 120 * @ah: atheros hardware structure 121 * @chan: 122 * 123 * For single-chip solutions. Converts to baseband spur frequency given the 124 * input channel frequency and compute register settings below. 125 * 126 * Spur mitigation for MRC CCK 127 */ 128static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, 129 struct ath9k_channel *chan) 130{ 131 u32 spur_freq[4] = { 2420, 2440, 2464, 2480 }; 132 int cur_bb_spur, negative = 0, cck_spur_freq; 133 int i; 134 135 /* 136 * Need to verify range +/- 10 MHz in control channel, otherwise spur 137 * is out-of-band and can be ignored. 138 */ 139 140 for (i = 0; i < 4; i++) { 141 negative = 0; 142 cur_bb_spur = spur_freq[i] - chan->channel; 143 144 if (cur_bb_spur < 0) { 145 negative = 1; 146 cur_bb_spur = -cur_bb_spur; 147 } 148 if (cur_bb_spur < 10) { 149 cck_spur_freq = (int)((cur_bb_spur << 19) / 11); 150 151 if (negative == 1) 152 cck_spur_freq = -cck_spur_freq; 153 154 cck_spur_freq = cck_spur_freq & 0xfffff; 155 156 REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, 157 AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7); 158 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 159 AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f); 160 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 161 AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, 162 0x2); 163 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 164 AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 165 0x1); 166 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 167 AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 168 cck_spur_freq); 169 170 return; 171 } 172 } 173 174 REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, 175 AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5); 176 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 177 AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0); 178 REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, 179 AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0); 180} 181 182/* Clean all spur register fields */ 183static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah) 184{ 185 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 186 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0); 187 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 188 AR_PHY_TIMING11_SPUR_FREQ_SD, 0); 189 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 190 AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0); 191 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 192 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0); 193 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 194 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0); 195 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 196 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0); 197 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 198 AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0); 199 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 200 AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0); 201 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 202 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0); 203 204 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 205 AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0); 206 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 207 AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0); 208 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 209 AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0); 210 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, 211 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0); 212 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, 213 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0); 214 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, 215 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0); 216 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, 217 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0); 218 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, 219 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0); 220 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, 221 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0); 222 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 223 AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0); 224} 225 226static void ar9003_hw_spur_ofdm(struct ath_hw *ah, 227 int freq_offset, 228 int spur_freq_sd, 229 int spur_delta_phase, 230 int spur_subchannel_sd) 231{ 232 int mask_index = 0; 233 234 /* OFDM Spur mitigation */ 235 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 236 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1); 237 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 238 AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd); 239 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 240 AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase); 241 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 242 AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd); 243 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 244 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1); 245 REG_RMW_FIELD(ah, AR_PHY_TIMING11, 246 AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); 247 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 248 AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1); 249 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 250 AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34); 251 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 252 AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1); 253 254 if (REG_READ_FIELD(ah, AR_PHY_MODE, 255 AR_PHY_MODE_DYNAMIC) == 0x1) 256 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 257 AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1); 258 259 mask_index = (freq_offset << 4) / 5; 260 if (mask_index < 0) 261 mask_index = mask_index - 1; 262 263 mask_index = mask_index & 0x7f; 264 265 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 266 AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1); 267 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 268 AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1); 269 REG_RMW_FIELD(ah, AR_PHY_TIMING4, 270 AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1); 271 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, 272 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index); 273 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, 274 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index); 275 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, 276 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index); 277 REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, 278 AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc); 279 REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, 280 AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc); 281 REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, 282 AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0); 283 REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, 284 AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff); 285} 286 287static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, 288 struct ath9k_channel *chan, 289 int freq_offset) 290{ 291 int spur_freq_sd = 0; 292 int spur_subchannel_sd = 0; 293 int spur_delta_phase = 0; 294 295 if (IS_CHAN_HT40(chan)) { 296 if (freq_offset < 0) { 297 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, 298 AR_PHY_GC_DYN2040_PRI_CH) == 0x0) 299 spur_subchannel_sd = 1; 300 else 301 spur_subchannel_sd = 0; 302 303 spur_freq_sd = ((freq_offset + 10) << 9) / 11; 304 305 } else { 306 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, 307 AR_PHY_GC_DYN2040_PRI_CH) == 0x0) 308 spur_subchannel_sd = 0; 309 else 310 spur_subchannel_sd = 1; 311 312 spur_freq_sd = ((freq_offset - 10) << 9) / 11; 313 314 } 315 316 spur_delta_phase = (freq_offset << 17) / 5; 317 318 } else { 319 spur_subchannel_sd = 0; 320 spur_freq_sd = (freq_offset << 9) /11; 321 spur_delta_phase = (freq_offset << 18) / 5; 322 } 323 324 spur_freq_sd = spur_freq_sd & 0x3ff; 325 spur_delta_phase = spur_delta_phase & 0xfffff; 326 327 ar9003_hw_spur_ofdm(ah, 328 freq_offset, 329 spur_freq_sd, 330 spur_delta_phase, 331 spur_subchannel_sd); 332} 333 334/* Spur mitigation for OFDM */ 335static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, 336 struct ath9k_channel *chan) 337{ 338 int synth_freq; 339 int range = 10; 340 int freq_offset = 0; 341 int mode; 342 u8* spurChansPtr; 343 unsigned int i; 344 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; 345 346 if (IS_CHAN_5GHZ(chan)) { 347 spurChansPtr = &(eep->modalHeader5G.spurChans[0]); 348 mode = 0; 349 } 350 else { 351 spurChansPtr = &(eep->modalHeader2G.spurChans[0]); 352 mode = 1; 353 } 354 355 if (spurChansPtr[0] == 0) 356 return; /* No spur in the mode */ 357 358 if (IS_CHAN_HT40(chan)) { 359 range = 19; 360 if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, 361 AR_PHY_GC_DYN2040_PRI_CH) == 0x0) 362 synth_freq = chan->channel - 10; 363 else 364 synth_freq = chan->channel + 10; 365 } else { 366 range = 10; 367 synth_freq = chan->channel; 368 } 369 370 ar9003_hw_spur_ofdm_clear(ah); 371 372 for (i = 0; spurChansPtr[i] && i < 5; i++) { 373 freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; 374 if (abs(freq_offset) < range) { 375 ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); 376 break; 377 } 378 } 379} 380 381static void ar9003_hw_spur_mitigate(struct ath_hw *ah, 382 struct ath9k_channel *chan) 383{ 384 ar9003_hw_spur_mitigate_mrc_cck(ah, chan); 385 ar9003_hw_spur_mitigate_ofdm(ah, chan); 386} 387 388static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, 389 struct ath9k_channel *chan) 390{ 391 u32 pll; 392 393 pll = SM(0x5, AR_RTC_9300_PLL_REFDIV); 394 395 if (chan && IS_CHAN_HALF_RATE(chan)) 396 pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL); 397 else if (chan && IS_CHAN_QUARTER_RATE(chan)) 398 pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL); 399 400 pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); 401 402 return pll; 403} 404 405static void ar9003_hw_set_channel_regs(struct ath_hw *ah, 406 struct ath9k_channel *chan) 407{ 408 u32 phymode; 409 u32 enableDacFifo = 0; 410 411 enableDacFifo = 412 (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO); 413 414 /* Enable 11n HT, 20 MHz */ 415 phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH | 416 AR_PHY_GC_SHORT_GI_40 | enableDacFifo; 417 418 /* Configure baseband for dynamic 20/40 operation */ 419 if (IS_CHAN_HT40(chan)) { 420 phymode |= AR_PHY_GC_DYN2040_EN; 421 /* Configure control (primary) channel at +-10MHz */ 422 if ((chan->chanmode == CHANNEL_A_HT40PLUS) || 423 (chan->chanmode == CHANNEL_G_HT40PLUS)) 424 phymode |= AR_PHY_GC_DYN2040_PRI_CH; 425 426 } 427 428 /* make sure we preserve INI settings */ 429 phymode |= REG_READ(ah, AR_PHY_GEN_CTRL); 430 /* turn off Green Field detection for STA for now */ 431 phymode &= ~AR_PHY_GC_GF_DETECT_EN; 432 433 REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode); 434 435 /* Configure MAC for 20/40 operation */ 436 ath9k_hw_set11nmac2040(ah); 437 438 /* global transmit timeout (25 TUs default)*/ 439 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); 440 /* carrier sense timeout */ 441 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 442} 443 444static void ar9003_hw_init_bb(struct ath_hw *ah, 445 struct ath9k_channel *chan) 446{ 447 u32 synthDelay; 448 449 /* 450 * Wait for the frequency synth to settle (synth goes on 451 * via AR_PHY_ACTIVE_EN). Read the phy active delay register. 452 * Value is in 100ns increments. 453 */ 454 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 455 if (IS_CHAN_B(chan)) 456 synthDelay = (4 * synthDelay) / 22; 457 else 458 synthDelay /= 10; 459 460 /* Activate the PHY (includes baseband activate + synthesizer on) */ 461 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 462 463 udelay(synthDelay + BASE_ACTIVATE_DELAY); 464} 465 466void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) 467{ 468 switch (rx) { 469 case 0x5: 470 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 471 AR_PHY_SWAP_ALT_CHAIN); 472 case 0x3: 473 case 0x1: 474 case 0x2: 475 case 0x7: 476 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); 477 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); 478 break; 479 default: 480 break; 481 } 482 483 REG_WRITE(ah, AR_SELFGEN_MASK, tx); 484 if (tx == 0x5) { 485 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 486 AR_PHY_SWAP_ALT_CHAIN); 487 } 488} 489 490/* 491 * Override INI values with chip specific configuration. 492 */ 493static void ar9003_hw_override_ini(struct ath_hw *ah) 494{ 495 u32 val; 496 497 /* 498 * Set the RX_ABORT and RX_DIS and clear it only after 499 * RXE is set for MAC. This prevents frames with 500 * corrupted descriptor status. 501 */ 502 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 503 504 /* 505 * For AR9280 and above, there is a new feature that allows 506 * Multicast search based on both MAC Address and Key ID. By default, 507 * this feature is enabled. But since the driver is not using this 508 * feature, we switch it off; otherwise multicast search based on 509 * MAC addr only will fail. 510 */ 511 val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); 512 REG_WRITE(ah, AR_PCU_MISC_MODE2, 513 val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); 514} 515 516static void ar9003_hw_prog_ini(struct ath_hw *ah, 517 struct ar5416IniArray *iniArr, 518 int column) 519{ 520 unsigned int i, regWrites = 0; 521 522 /* New INI format: Array may be undefined (pre, core, post arrays) */ 523 if (!iniArr->ia_array) 524 return; 525 526 /* 527 * New INI format: Pre, core, and post arrays for a given subsystem 528 * may be modal (> 2 columns) or non-modal (2 columns). Determine if 529 * the array is non-modal and force the column to 1. 530 */ 531 if (column >= iniArr->ia_columns) 532 column = 1; 533 534 for (i = 0; i < iniArr->ia_rows; i++) { 535 u32 reg = INI_RA(iniArr, i, 0); 536 u32 val = INI_RA(iniArr, i, column); 537 538 if (reg >= 0x16000 && reg < 0x17000) 539 ath9k_hw_analog_shift_regwrite(ah, reg, val); 540 else 541 REG_WRITE(ah, reg, val); 542 543 DO_DELAY(regWrites); 544 } 545} 546 547static int ar9003_hw_process_ini(struct ath_hw *ah, 548 struct ath9k_channel *chan) 549{ 550 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 551 unsigned int regWrites = 0, i; 552 struct ieee80211_channel *channel = chan->chan; 553 u32 modesIndex, freqIndex; 554 555 switch (chan->chanmode) { 556 case CHANNEL_A: 557 case CHANNEL_A_HT20: 558 modesIndex = 1; 559 freqIndex = 1; 560 break; 561 case CHANNEL_A_HT40PLUS: 562 case CHANNEL_A_HT40MINUS: 563 modesIndex = 2; 564 freqIndex = 1; 565 break; 566 case CHANNEL_G: 567 case CHANNEL_G_HT20: 568 case CHANNEL_B: 569 modesIndex = 4; 570 freqIndex = 2; 571 break; 572 case CHANNEL_G_HT40PLUS: 573 case CHANNEL_G_HT40MINUS: 574 modesIndex = 3; 575 freqIndex = 2; 576 break; 577 578 default: 579 return -EINVAL; 580 } 581 582 for (i = 0; i < ATH_INI_NUM_SPLIT; i++) { 583 ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex); 584 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); 585 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); 586 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); 587 } 588 589 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); 590 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 591 592 /* 593 * For 5GHz channels requiring Fast Clock, apply 594 * different modal values. 595 */ 596 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 597 REG_WRITE_ARRAY(&ah->iniModesAdditional, 598 modesIndex, regWrites); 599 600 ar9003_hw_override_ini(ah); 601 ar9003_hw_set_channel_regs(ah, chan); 602 ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); 603 604 /* Set TX power */ 605 ah->eep_ops->set_txpower(ah, chan, 606 ath9k_regd_get_ctl(regulatory, chan), 607 channel->max_antenna_gain * 2, 608 channel->max_power * 2, 609 min((u32) MAX_RATE_POWER, 610 (u32) regulatory->power_limit)); 611 612 return 0; 613} 614 615static void ar9003_hw_set_rfmode(struct ath_hw *ah, 616 struct ath9k_channel *chan) 617{ 618 u32 rfMode = 0; 619 620 if (chan == NULL) 621 return; 622 623 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) 624 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 625 626 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 627 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); 628 629 REG_WRITE(ah, AR_PHY_MODE, rfMode); 630} 631 632static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah) 633{ 634 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 635} 636 637static void ar9003_hw_set_delta_slope(struct ath_hw *ah, 638 struct ath9k_channel *chan) 639{ 640 u32 coef_scaled, ds_coef_exp, ds_coef_man; 641 u32 clockMhzScaled = 0x64000000; 642 struct chan_centers centers; 643 644 /* 645 * half and quarter rate can divide the scaled clock by 2 or 4 646 * scale for selected channel bandwidth 647 */ 648 if (IS_CHAN_HALF_RATE(chan)) 649 clockMhzScaled = clockMhzScaled >> 1; 650 else if (IS_CHAN_QUARTER_RATE(chan)) 651 clockMhzScaled = clockMhzScaled >> 2; 652 653 /* 654 * ALGO -> coef = 1e8/fcarrier*fclock/40; 655 * scaled coef to provide precision for this floating calculation 656 */ 657 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 658 coef_scaled = clockMhzScaled / centers.synth_center; 659 660 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, 661 &ds_coef_exp); 662 663 REG_RMW_FIELD(ah, AR_PHY_TIMING3, 664 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 665 REG_RMW_FIELD(ah, AR_PHY_TIMING3, 666 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 667 668 /* 669 * For Short GI, 670 * scaled coeff is 9/10 that of normal coeff 671 */ 672 coef_scaled = (9 * coef_scaled) / 10; 673 674 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, 675 &ds_coef_exp); 676 677 /* for short gi */ 678 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, 679 AR_PHY_SGI_DSC_MAN, ds_coef_man); 680 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, 681 AR_PHY_SGI_DSC_EXP, ds_coef_exp); 682} 683 684static bool ar9003_hw_rfbus_req(struct ath_hw *ah) 685{ 686 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); 687 return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, 688 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT); 689} 690 691/* 692 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN). 693 * Read the phy active delay register. Value is in 100ns increments. 694 */ 695static void ar9003_hw_rfbus_done(struct ath_hw *ah) 696{ 697 u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 698 if (IS_CHAN_B(ah->curchan)) 699 synthDelay = (4 * synthDelay) / 22; 700 else 701 synthDelay /= 10; 702 703 udelay(synthDelay + BASE_ACTIVATE_DELAY); 704 705 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 706} 707 708/* 709 * Set the interrupt and GPIO values so the ISR can disable RF 710 * on a switch signal. Assumes GPIO port and interrupt polarity 711 * are set prior to call. 712 */ 713static void ar9003_hw_enable_rfkill(struct ath_hw *ah) 714{ 715 /* Connect rfsilent_bb_l to baseband */ 716 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, 717 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); 718 /* Set input mux for rfsilent_bb_l to GPIO #0 */ 719 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, 720 AR_GPIO_INPUT_MUX2_RFSILENT); 721 722 /* 723 * Configure the desired GPIO port for input and 724 * enable baseband rf silence. 725 */ 726 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); 727 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); 728} 729 730static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) 731{ 732 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); 733 if (value) 734 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 735 else 736 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 737 REG_WRITE(ah, AR_PHY_CCK_DETECT, v); 738} 739 740static bool ar9003_hw_ani_control(struct ath_hw *ah, 741 enum ath9k_ani_cmd cmd, int param) 742{ 743 struct ar5416AniState *aniState = ah->curani; 744 struct ath_common *common = ath9k_hw_common(ah); 745 struct ath9k_channel *chan = ah->curchan; 746 s32 value, value2; 747 748 switch (cmd & ah->ani_function) { 749 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 750 /* 751 * on == 1 means ofdm weak signal detection is ON 752 * on == 1 is the default, for less noise immunity 753 * 754 * on == 0 means ofdm weak signal detection is OFF 755 * on == 0 means more noise imm 756 */ 757 u32 on = param ? 1 : 0; 758 /* 759 * make register setting for default 760 * (weak sig detect ON) come from INI file 761 */ 762 int m1ThreshLow = on ? 763 aniState->iniDef.m1ThreshLow : m1ThreshLow_off; 764 int m2ThreshLow = on ? 765 aniState->iniDef.m2ThreshLow : m2ThreshLow_off; 766 int m1Thresh = on ? 767 aniState->iniDef.m1Thresh : m1Thresh_off; 768 int m2Thresh = on ? 769 aniState->iniDef.m2Thresh : m2Thresh_off; 770 int m2CountThr = on ? 771 aniState->iniDef.m2CountThr : m2CountThr_off; 772 int m2CountThrLow = on ? 773 aniState->iniDef.m2CountThrLow : m2CountThrLow_off; 774 int m1ThreshLowExt = on ? 775 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; 776 int m2ThreshLowExt = on ? 777 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; 778 int m1ThreshExt = on ? 779 aniState->iniDef.m1ThreshExt : m1ThreshExt_off; 780 int m2ThreshExt = on ? 781 aniState->iniDef.m2ThreshExt : m2ThreshExt_off; 782 783 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 784 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 785 m1ThreshLow); 786 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 787 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 788 m2ThreshLow); 789 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 790 AR_PHY_SFCORR_M1_THRESH, m1Thresh); 791 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 792 AR_PHY_SFCORR_M2_THRESH, m2Thresh); 793 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 794 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); 795 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 796 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 797 m2CountThrLow); 798 799 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 800 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); 801 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 802 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); 803 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 804 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); 805 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 806 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); 807 808 if (on) 809 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 810 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 811 else 812 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, 813 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 814 815 if (!on != aniState->ofdmWeakSigDetectOff) { 816 ath_print(common, ATH_DBG_ANI, 817 "** ch %d: ofdm weak signal: %s=>%s\n", 818 chan->channel, 819 !aniState->ofdmWeakSigDetectOff ? 820 "on" : "off", 821 on ? "on" : "off"); 822 if (on) 823 ah->stats.ast_ani_ofdmon++; 824 else 825 ah->stats.ast_ani_ofdmoff++; 826 aniState->ofdmWeakSigDetectOff = !on; 827 } 828 break; 829 } 830 case ATH9K_ANI_FIRSTEP_LEVEL:{ 831 u32 level = param; 832 833 if (level >= ARRAY_SIZE(firstep_table)) { 834 ath_print(common, ATH_DBG_ANI, 835 "ATH9K_ANI_FIRSTEP_LEVEL: level " 836 "out of range (%u > %u)\n", 837 level, 838 (unsigned) ARRAY_SIZE(firstep_table)); 839 return false; 840 } 841 842 /* 843 * make register setting relative to default 844 * from INI file & cap value 845 */ 846 value = firstep_table[level] - 847 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + 848 aniState->iniDef.firstep; 849 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) 850 value = ATH9K_SIG_FIRSTEP_SETTING_MIN; 851 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) 852 value = ATH9K_SIG_FIRSTEP_SETTING_MAX; 853 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 854 AR_PHY_FIND_SIG_FIRSTEP, 855 value); 856 /* 857 * we need to set first step low register too 858 * make register setting relative to default 859 * from INI file & cap value 860 */ 861 value2 = firstep_table[level] - 862 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + 863 aniState->iniDef.firstepLow; 864 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) 865 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; 866 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) 867 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; 868 869 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, 870 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2); 871 872 if (level != aniState->firstepLevel) { 873 ath_print(common, ATH_DBG_ANI, 874 "** ch %d: level %d=>%d[def:%d] " 875 "firstep[level]=%d ini=%d\n", 876 chan->channel, 877 aniState->firstepLevel, 878 level, 879 ATH9K_ANI_FIRSTEP_LVL_NEW, 880 value, 881 aniState->iniDef.firstep); 882 ath_print(common, ATH_DBG_ANI, 883 "** ch %d: level %d=>%d[def:%d] " 884 "firstep_low[level]=%d ini=%d\n", 885 chan->channel, 886 aniState->firstepLevel, 887 level, 888 ATH9K_ANI_FIRSTEP_LVL_NEW, 889 value2, 890 aniState->iniDef.firstepLow); 891 if (level > aniState->firstepLevel) 892 ah->stats.ast_ani_stepup++; 893 else if (level < aniState->firstepLevel) 894 ah->stats.ast_ani_stepdown++; 895 aniState->firstepLevel = level; 896 } 897 break; 898 } 899 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 900 u32 level = param; 901 902 if (level >= ARRAY_SIZE(cycpwrThr1_table)) { 903 ath_print(common, ATH_DBG_ANI, 904 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " 905 "out of range (%u > %u)\n", 906 level, 907 (unsigned) ARRAY_SIZE(cycpwrThr1_table)); 908 return false; 909 } 910 /* 911 * make register setting relative to default 912 * from INI file & cap value 913 */ 914 value = cycpwrThr1_table[level] - 915 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + 916 aniState->iniDef.cycpwrThr1; 917 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) 918 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; 919 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) 920 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; 921 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 922 AR_PHY_TIMING5_CYCPWR_THR1, 923 value); 924 925 /* 926 * set AR_PHY_EXT_CCA for extension channel 927 * make register setting relative to default 928 * from INI file & cap value 929 */ 930 value2 = cycpwrThr1_table[level] - 931 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + 932 aniState->iniDef.cycpwrThr1Ext; 933 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) 934 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; 935 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) 936 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; 937 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, 938 AR_PHY_EXT_CYCPWR_THR1, value2); 939 940 if (level != aniState->spurImmunityLevel) { 941 ath_print(common, ATH_DBG_ANI, 942 "** ch %d: level %d=>%d[def:%d] " 943 "cycpwrThr1[level]=%d ini=%d\n", 944 chan->channel, 945 aniState->spurImmunityLevel, 946 level, 947 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, 948 value, 949 aniState->iniDef.cycpwrThr1); 950 ath_print(common, ATH_DBG_ANI, 951 "** ch %d: level %d=>%d[def:%d] " 952 "cycpwrThr1Ext[level]=%d ini=%d\n", 953 chan->channel, 954 aniState->spurImmunityLevel, 955 level, 956 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, 957 value2, 958 aniState->iniDef.cycpwrThr1Ext); 959 if (level > aniState->spurImmunityLevel) 960 ah->stats.ast_ani_spurup++; 961 else if (level < aniState->spurImmunityLevel) 962 ah->stats.ast_ani_spurdown++; 963 aniState->spurImmunityLevel = level; 964 } 965 break; 966 } 967 case ATH9K_ANI_MRC_CCK:{ 968 /* 969 * is_on == 1 means MRC CCK ON (default, less noise imm) 970 * is_on == 0 means MRC CCK is OFF (more noise imm) 971 */ 972 bool is_on = param ? 1 : 0; 973 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, 974 AR_PHY_MRC_CCK_ENABLE, is_on); 975 REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL, 976 AR_PHY_MRC_CCK_MUX_REG, is_on); 977 if (!is_on != aniState->mrcCCKOff) { 978 ath_print(common, ATH_DBG_ANI, 979 "** ch %d: MRC CCK: %s=>%s\n", 980 chan->channel, 981 !aniState->mrcCCKOff ? "on" : "off", 982 is_on ? "on" : "off"); 983 if (is_on) 984 ah->stats.ast_ani_ccklow++; 985 else 986 ah->stats.ast_ani_cckhigh++; 987 aniState->mrcCCKOff = !is_on; 988 } 989 break; 990 } 991 case ATH9K_ANI_PRESENT: 992 break; 993 default: 994 ath_print(common, ATH_DBG_ANI, 995 "invalid cmd %u\n", cmd); 996 return false; 997 } 998 999 ath_print(common, ATH_DBG_ANI, 1000 "ANI parameters: SI=%d, ofdmWS=%s FS=%d " 1001 "MRCcck=%s listenTime=%d CC=%d listen=%d " 1002 "ofdmErrs=%d cckErrs=%d\n", 1003 aniState->spurImmunityLevel, 1004 !aniState->ofdmWeakSigDetectOff ? "on" : "off", 1005 aniState->firstepLevel, 1006 !aniState->mrcCCKOff ? "on" : "off", 1007 aniState->listenTime, 1008 aniState->cycleCount, 1009 aniState->listenTime, 1010 aniState->ofdmPhyErrCount, 1011 aniState->cckPhyErrCount); 1012 return true; 1013} 1014 1015static void ar9003_hw_do_getnf(struct ath_hw *ah, 1016 int16_t nfarray[NUM_NF_READINGS]) 1017{ 1018 int16_t nf; 1019 1020 nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); 1021 nfarray[0] = sign_extend(nf, 9); 1022 1023 nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); 1024 nfarray[1] = sign_extend(nf, 9); 1025 1026 nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); 1027 nfarray[2] = sign_extend(nf, 9); 1028 1029 if (!IS_CHAN_HT40(ah->curchan)) 1030 return; 1031 1032 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 1033 nfarray[3] = sign_extend(nf, 9); 1034 1035 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); 1036 nfarray[4] = sign_extend(nf, 9); 1037 1038 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); 1039 nfarray[5] = sign_extend(nf, 9); 1040} 1041 1042static void ar9003_hw_set_nf_limits(struct ath_hw *ah) 1043{ 1044 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; 1045 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; 1046 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ; 1047 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; 1048 ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; 1049 ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ; 1050} 1051 1052/* 1053 * Initialize the ANI register values with default (ini) values. 1054 * This routine is called during a (full) hardware reset after 1055 * all the registers are initialised from the INI. 1056 */ 1057static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah) 1058{ 1059 struct ar5416AniState *aniState; 1060 struct ath_common *common = ath9k_hw_common(ah); 1061 struct ath9k_channel *chan = ah->curchan; 1062 struct ath9k_ani_default *iniDef; 1063 int index; 1064 u32 val; 1065 1066 index = ath9k_hw_get_ani_channel_idx(ah, chan); 1067 aniState = &ah->ani[index]; 1068 ah->curani = aniState; 1069 iniDef = &aniState->iniDef; 1070 1071 ath_print(common, ATH_DBG_ANI, 1072 "ver %d.%d opmode %u chan %d Mhz/0x%x\n", 1073 ah->hw_version.macVersion, 1074 ah->hw_version.macRev, 1075 ah->opmode, 1076 chan->channel, 1077 chan->channelFlags); 1078 1079 val = REG_READ(ah, AR_PHY_SFCORR); 1080 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); 1081 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH); 1082 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR); 1083 1084 val = REG_READ(ah, AR_PHY_SFCORR_LOW); 1085 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW); 1086 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW); 1087 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); 1088 1089 val = REG_READ(ah, AR_PHY_SFCORR_EXT); 1090 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH); 1091 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH); 1092 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW); 1093 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW); 1094 iniDef->firstep = REG_READ_FIELD(ah, 1095 AR_PHY_FIND_SIG, 1096 AR_PHY_FIND_SIG_FIRSTEP); 1097 iniDef->firstepLow = REG_READ_FIELD(ah, 1098 AR_PHY_FIND_SIG_LOW, 1099 AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW); 1100 iniDef->cycpwrThr1 = REG_READ_FIELD(ah, 1101 AR_PHY_TIMING5, 1102 AR_PHY_TIMING5_CYCPWR_THR1); 1103 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah, 1104 AR_PHY_EXT_CCA, 1105 AR_PHY_EXT_CYCPWR_THR1); 1106 1107 /* these levels just got reset to defaults by the INI */ 1108 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; 1109 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 1110 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1111 aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK; 1112 1113 aniState->cycleCount = 0; 1114} 1115 1116void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 1117{ 1118 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1119 const u32 ar9300_cca_regs[6] = { 1120 AR_PHY_CCA_0, 1121 AR_PHY_CCA_1, 1122 AR_PHY_CCA_2, 1123 AR_PHY_EXT_CCA, 1124 AR_PHY_EXT_CCA_1, 1125 AR_PHY_EXT_CCA_2, 1126 }; 1127 1128 priv_ops->rf_set_freq = ar9003_hw_set_channel; 1129 priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; 1130 priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; 1131 priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; 1132 priv_ops->init_bb = ar9003_hw_init_bb; 1133 priv_ops->process_ini = ar9003_hw_process_ini; 1134 priv_ops->set_rfmode = ar9003_hw_set_rfmode; 1135 priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive; 1136 priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; 1137 priv_ops->rfbus_req = ar9003_hw_rfbus_req; 1138 priv_ops->rfbus_done = ar9003_hw_rfbus_done; 1139 priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; 1140 priv_ops->set_diversity = ar9003_hw_set_diversity; 1141 priv_ops->ani_control = ar9003_hw_ani_control; 1142 priv_ops->do_getnf = ar9003_hw_do_getnf; 1143 priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; 1144 1145 ar9003_hw_set_nf_limits(ah); 1146 memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs)); 1147} 1148 1149void ar9003_hw_bb_watchdog_config(struct ath_hw *ah) 1150{ 1151 struct ath_common *common = ath9k_hw_common(ah); 1152 u32 idle_tmo_ms = ah->bb_watchdog_timeout_ms; 1153 u32 val, idle_count; 1154 1155 if (!idle_tmo_ms) { 1156 /* disable IRQ, disable chip-reset for BB panic */ 1157 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2, 1158 REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & 1159 ~(AR_PHY_WATCHDOG_RST_ENABLE | 1160 AR_PHY_WATCHDOG_IRQ_ENABLE)); 1161 1162 /* disable watchdog in non-IDLE mode, disable in IDLE mode */ 1163 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1, 1164 REG_READ(ah, AR_PHY_WATCHDOG_CTL_1) & 1165 ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE | 1166 AR_PHY_WATCHDOG_IDLE_ENABLE)); 1167 1168 ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n"); 1169 return; 1170 } 1171 1172 /* enable IRQ, disable chip-reset for BB watchdog */ 1173 val = REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & AR_PHY_WATCHDOG_CNTL2_MASK; 1174 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2, 1175 (val | AR_PHY_WATCHDOG_IRQ_ENABLE) & 1176 ~AR_PHY_WATCHDOG_RST_ENABLE); 1177 1178 /* bound limit to 10 secs */ 1179 if (idle_tmo_ms > 10000) 1180 idle_tmo_ms = 10000; 1181 1182 /* 1183 * The time unit for watchdog event is 2^15 44/88MHz cycles. 1184 * 1185 * For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick 1186 * For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick 1187 * 1188 * Given we use fast clock now in 5 GHz, these time units should 1189 * be common for both 2 GHz and 5 GHz. 1190 */ 1191 idle_count = (100 * idle_tmo_ms) / 74; 1192 if (ah->curchan && IS_CHAN_HT40(ah->curchan)) 1193 idle_count = (100 * idle_tmo_ms) / 37; 1194 1195 /* 1196 * enable watchdog in non-IDLE mode, disable in IDLE mode, 1197 * set idle time-out. 1198 */ 1199 REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1, 1200 AR_PHY_WATCHDOG_NON_IDLE_ENABLE | 1201 AR_PHY_WATCHDOG_IDLE_MASK | 1202 (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2))); 1203 1204 ath_print(common, ATH_DBG_RESET, 1205 "Enabled BB Watchdog timeout (%u ms)\n", 1206 idle_tmo_ms); 1207} 1208 1209void ar9003_hw_bb_watchdog_read(struct ath_hw *ah) 1210{ 1211 /* 1212 * we want to avoid printing in ISR context so we save the 1213 * watchdog status to be printed later in bottom half context. 1214 */ 1215 ah->bb_watchdog_last_status = REG_READ(ah, AR_PHY_WATCHDOG_STATUS); 1216 1217 /* 1218 * the watchdog timer should reset on status read but to be sure 1219 * sure we write 0 to the watchdog status bit. 1220 */ 1221 REG_WRITE(ah, AR_PHY_WATCHDOG_STATUS, 1222 ah->bb_watchdog_last_status & ~AR_PHY_WATCHDOG_STATUS_CLR); 1223} 1224 1225void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah) 1226{ 1227 struct ath_common *common = ath9k_hw_common(ah); 1228 u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status; 1229 1230 if (likely(!(common->debug_mask & ATH_DBG_RESET))) 1231 return; 1232 1233 status = ah->bb_watchdog_last_status; 1234 ath_print(common, ATH_DBG_RESET, 1235 "\n==== BB update: BB status=0x%08x ====\n", status); 1236 ath_print(common, ATH_DBG_RESET, 1237 "** BB state: wd=%u det=%u rdar=%u rOFDM=%d " 1238 "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n", 1239 MS(status, AR_PHY_WATCHDOG_INFO), 1240 MS(status, AR_PHY_WATCHDOG_DET_HANG), 1241 MS(status, AR_PHY_WATCHDOG_RADAR_SM), 1242 MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM), 1243 MS(status, AR_PHY_WATCHDOG_RX_CCK_SM), 1244 MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM), 1245 MS(status, AR_PHY_WATCHDOG_TX_CCK_SM), 1246 MS(status, AR_PHY_WATCHDOG_AGC_SM), 1247 MS(status,AR_PHY_WATCHDOG_SRCH_SM)); 1248 1249 ath_print(common, ATH_DBG_RESET, 1250 "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n", 1251 REG_READ(ah, AR_PHY_WATCHDOG_CTL_1), 1252 REG_READ(ah, AR_PHY_WATCHDOG_CTL_2)); 1253 ath_print(common, ATH_DBG_RESET, 1254 "** BB mode: BB_gen_controls=0x%08x **\n", 1255 REG_READ(ah, AR_PHY_GEN_CTRL)); 1256 1257 if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt)) 1258 ath_print(common, ATH_DBG_RESET, 1259 "** BB busy times: rx_clear=%d%%, " 1260 "rx_frame=%d%%, tx_frame=%d%% **\n", 1261 rxc_pcnt, rxf_pcnt, txf_pcnt); 1262 1263 ath_print(common, ATH_DBG_RESET, 1264 "==== BB update: done ====\n\n"); 1265} 1266EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info); 1267