1/* 2 * Copyright (c) 2008-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 "hw-ops.h" 19#include "../regd.h" 20#include "ar9002_phy.h" 21 22/* All code below is for AR5008, AR9001, AR9002 */ 23 24static const int firstep_table[] = 25/* level: 0 1 2 3 4 5 6 7 8 */ 26 { -4, -2, 0, 2, 4, 6, 8, 10, 12 }; /* lvl 0-8, default 2 */ 27 28static const int cycpwrThr1_table[] = 29/* level: 0 1 2 3 4 5 6 7 8 */ 30 { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ 31 32/* 33 * register values to turn OFDM weak signal detection OFF 34 */ 35static const int m1ThreshLow_off = 127; 36static const int m2ThreshLow_off = 127; 37static const int m1Thresh_off = 127; 38static const int m2Thresh_off = 127; 39static const int m2CountThr_off = 31; 40static const int m2CountThrLow_off = 63; 41static const int m1ThreshLowExt_off = 127; 42static const int m2ThreshLowExt_off = 127; 43static const int m1ThreshExt_off = 127; 44static const int m2ThreshExt_off = 127; 45 46 47/** 48 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters 49 * @rfbuf: 50 * @reg32: 51 * @numBits: 52 * @firstBit: 53 * @column: 54 * 55 * Performs analog "swizzling" of parameters into their location. 56 * Used on external AR2133/AR5133 radios. 57 */ 58static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, 59 u32 numBits, u32 firstBit, 60 u32 column) 61{ 62 u32 tmp32, mask, arrayEntry, lastBit; 63 int32_t bitPosition, bitsLeft; 64 65 tmp32 = ath9k_hw_reverse_bits(reg32, numBits); 66 arrayEntry = (firstBit - 1) / 8; 67 bitPosition = (firstBit - 1) % 8; 68 bitsLeft = numBits; 69 while (bitsLeft > 0) { 70 lastBit = (bitPosition + bitsLeft > 8) ? 71 8 : bitPosition + bitsLeft; 72 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << 73 (column * 8); 74 rfBuf[arrayEntry] &= ~mask; 75 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << 76 (column * 8)) & mask; 77 bitsLeft -= 8 - bitPosition; 78 tmp32 = tmp32 >> (8 - bitPosition); 79 bitPosition = 0; 80 arrayEntry++; 81 } 82} 83 84/* 85 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing 86 * rf_pwd_icsyndiv. 87 * 88 * Theoretical Rules: 89 * if 2 GHz band 90 * if forceBiasAuto 91 * if synth_freq < 2412 92 * bias = 0 93 * else if 2412 <= synth_freq <= 2422 94 * bias = 1 95 * else // synth_freq > 2422 96 * bias = 2 97 * else if forceBias > 0 98 * bias = forceBias & 7 99 * else 100 * no change, use value from ini file 101 * else 102 * no change, invalid band 103 * 104 * 1st Mod: 105 * 2422 also uses value of 2 106 * <approved> 107 * 108 * 2nd Mod: 109 * Less than 2412 uses value of 0, 2412 and above uses value of 2 110 */ 111static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) 112{ 113 struct ath_common *common = ath9k_hw_common(ah); 114 u32 tmp_reg; 115 int reg_writes = 0; 116 u32 new_bias = 0; 117 118 if (!AR_SREV_5416(ah) || synth_freq >= 3000) 119 return; 120 121 BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); 122 123 if (synth_freq < 2412) 124 new_bias = 0; 125 else if (synth_freq < 2422) 126 new_bias = 1; 127 else 128 new_bias = 2; 129 130 /* pre-reverse this field */ 131 tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); 132 133 ath_print(common, ATH_DBG_CONFIG, 134 "Force rf_pwd_icsyndiv to %1d on %4d\n", 135 new_bias, synth_freq); 136 137 /* swizzle rf_pwd_icsyndiv */ 138 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); 139 140 /* write Bank 6 with new params */ 141 REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); 142} 143 144/** 145 * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios 146 * @ah: atheros hardware stucture 147 * @chan: 148 * 149 * For the external AR2133/AR5133 radios, takes the MHz channel value and set 150 * the channel value. Assumes writes enabled to analog bus and bank6 register 151 * cache in ah->analogBank6Data. 152 */ 153static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) 154{ 155 struct ath_common *common = ath9k_hw_common(ah); 156 u32 channelSel = 0; 157 u32 bModeSynth = 0; 158 u32 aModeRefSel = 0; 159 u32 reg32 = 0; 160 u16 freq; 161 struct chan_centers centers; 162 163 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 164 freq = centers.synth_center; 165 166 if (freq < 4800) { 167 u32 txctl; 168 169 if (((freq - 2192) % 5) == 0) { 170 channelSel = ((freq - 672) * 2 - 3040) / 10; 171 bModeSynth = 0; 172 } else if (((freq - 2224) % 5) == 0) { 173 channelSel = ((freq - 704) * 2 - 3040) / 10; 174 bModeSynth = 1; 175 } else { 176 ath_print(common, ATH_DBG_FATAL, 177 "Invalid channel %u MHz\n", freq); 178 return -EINVAL; 179 } 180 181 channelSel = (channelSel << 2) & 0xff; 182 channelSel = ath9k_hw_reverse_bits(channelSel, 8); 183 184 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); 185 if (freq == 2484) { 186 187 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 188 txctl | AR_PHY_CCK_TX_CTRL_JAPAN); 189 } else { 190 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, 191 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); 192 } 193 194 } else if ((freq % 20) == 0 && freq >= 5120) { 195 channelSel = 196 ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8); 197 aModeRefSel = ath9k_hw_reverse_bits(1, 2); 198 } else if ((freq % 10) == 0) { 199 channelSel = 200 ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8); 201 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) 202 aModeRefSel = ath9k_hw_reverse_bits(2, 2); 203 else 204 aModeRefSel = ath9k_hw_reverse_bits(1, 2); 205 } else if ((freq % 5) == 0) { 206 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); 207 aModeRefSel = ath9k_hw_reverse_bits(1, 2); 208 } else { 209 ath_print(common, ATH_DBG_FATAL, 210 "Invalid channel %u MHz\n", freq); 211 return -EINVAL; 212 } 213 214 ar5008_hw_force_bias(ah, freq); 215 216 reg32 = 217 (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | 218 (1 << 5) | 0x1; 219 220 REG_WRITE(ah, AR_PHY(0x37), reg32); 221 222 ah->curchan = chan; 223 ah->curchan_rad_index = -1; 224 225 return 0; 226} 227 228/** 229 * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios 230 * @ah: atheros hardware structure 231 * @chan: 232 * 233 * For non single-chip solutions. Converts to baseband spur frequency given the 234 * input channel frequency and compute register settings below. 235 */ 236static void ar5008_hw_spur_mitigate(struct ath_hw *ah, 237 struct ath9k_channel *chan) 238{ 239 int bb_spur = AR_NO_SPUR; 240 int bin, cur_bin; 241 int spur_freq_sd; 242 int spur_delta_phase; 243 int denominator; 244 int upper, lower, cur_vit_mask; 245 int tmp, new; 246 int i; 247 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, 248 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 249 }; 250 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, 251 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 252 }; 253 int inc[4] = { 0, 100, 0, 0 }; 254 255 int8_t mask_m[123]; 256 int8_t mask_p[123]; 257 int8_t mask_amt; 258 int tmp_mask; 259 int cur_bb_spur; 260 bool is2GHz = IS_CHAN_2GHZ(chan); 261 262 memset(&mask_m, 0, sizeof(int8_t) * 123); 263 memset(&mask_p, 0, sizeof(int8_t) * 123); 264 265 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { 266 cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); 267 if (AR_NO_SPUR == cur_bb_spur) 268 break; 269 cur_bb_spur = cur_bb_spur - (chan->channel * 10); 270 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { 271 bb_spur = cur_bb_spur; 272 break; 273 } 274 } 275 276 if (AR_NO_SPUR == bb_spur) 277 return; 278 279 bin = bb_spur * 32; 280 281 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); 282 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | 283 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | 284 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | 285 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); 286 287 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); 288 289 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | 290 AR_PHY_SPUR_REG_ENABLE_MASK_PPM | 291 AR_PHY_SPUR_REG_MASK_RATE_SELECT | 292 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | 293 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); 294 REG_WRITE(ah, AR_PHY_SPUR_REG, new); 295 296 spur_delta_phase = ((bb_spur * 524288) / 100) & 297 AR_PHY_TIMING11_SPUR_DELTA_PHASE; 298 299 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; 300 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; 301 302 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | 303 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | 304 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); 305 REG_WRITE(ah, AR_PHY_TIMING11, new); 306 307 cur_bin = -6000; 308 upper = bin + 100; 309 lower = bin - 100; 310 311 for (i = 0; i < 4; i++) { 312 int pilot_mask = 0; 313 int chan_mask = 0; 314 int bp = 0; 315 for (bp = 0; bp < 30; bp++) { 316 if ((cur_bin > lower) && (cur_bin < upper)) { 317 pilot_mask = pilot_mask | 0x1 << bp; 318 chan_mask = chan_mask | 0x1 << bp; 319 } 320 cur_bin += 100; 321 } 322 cur_bin += inc[i]; 323 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); 324 REG_WRITE(ah, chan_mask_reg[i], chan_mask); 325 } 326 327 cur_vit_mask = 6100; 328 upper = bin + 120; 329 lower = bin - 120; 330 331 for (i = 0; i < 123; i++) { 332 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { 333 334 volatile int tmp_v = abs(cur_vit_mask - bin); 335 336 if (tmp_v < 75) 337 mask_amt = 1; 338 else 339 mask_amt = 0; 340 if (cur_vit_mask < 0) 341 mask_m[abs(cur_vit_mask / 100)] = mask_amt; 342 else 343 mask_p[cur_vit_mask / 100] = mask_amt; 344 } 345 cur_vit_mask -= 100; 346 } 347 348 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) 349 | (mask_m[48] << 26) | (mask_m[49] << 24) 350 | (mask_m[50] << 22) | (mask_m[51] << 20) 351 | (mask_m[52] << 18) | (mask_m[53] << 16) 352 | (mask_m[54] << 14) | (mask_m[55] << 12) 353 | (mask_m[56] << 10) | (mask_m[57] << 8) 354 | (mask_m[58] << 6) | (mask_m[59] << 4) 355 | (mask_m[60] << 2) | (mask_m[61] << 0); 356 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); 357 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); 358 359 tmp_mask = (mask_m[31] << 28) 360 | (mask_m[32] << 26) | (mask_m[33] << 24) 361 | (mask_m[34] << 22) | (mask_m[35] << 20) 362 | (mask_m[36] << 18) | (mask_m[37] << 16) 363 | (mask_m[48] << 14) | (mask_m[39] << 12) 364 | (mask_m[40] << 10) | (mask_m[41] << 8) 365 | (mask_m[42] << 6) | (mask_m[43] << 4) 366 | (mask_m[44] << 2) | (mask_m[45] << 0); 367 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); 368 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); 369 370 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) 371 | (mask_m[18] << 26) | (mask_m[18] << 24) 372 | (mask_m[20] << 22) | (mask_m[20] << 20) 373 | (mask_m[22] << 18) | (mask_m[22] << 16) 374 | (mask_m[24] << 14) | (mask_m[24] << 12) 375 | (mask_m[25] << 10) | (mask_m[26] << 8) 376 | (mask_m[27] << 6) | (mask_m[28] << 4) 377 | (mask_m[29] << 2) | (mask_m[30] << 0); 378 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); 379 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); 380 381 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) 382 | (mask_m[2] << 26) | (mask_m[3] << 24) 383 | (mask_m[4] << 22) | (mask_m[5] << 20) 384 | (mask_m[6] << 18) | (mask_m[7] << 16) 385 | (mask_m[8] << 14) | (mask_m[9] << 12) 386 | (mask_m[10] << 10) | (mask_m[11] << 8) 387 | (mask_m[12] << 6) | (mask_m[13] << 4) 388 | (mask_m[14] << 2) | (mask_m[15] << 0); 389 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); 390 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); 391 392 tmp_mask = (mask_p[15] << 28) 393 | (mask_p[14] << 26) | (mask_p[13] << 24) 394 | (mask_p[12] << 22) | (mask_p[11] << 20) 395 | (mask_p[10] << 18) | (mask_p[9] << 16) 396 | (mask_p[8] << 14) | (mask_p[7] << 12) 397 | (mask_p[6] << 10) | (mask_p[5] << 8) 398 | (mask_p[4] << 6) | (mask_p[3] << 4) 399 | (mask_p[2] << 2) | (mask_p[1] << 0); 400 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); 401 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); 402 403 tmp_mask = (mask_p[30] << 28) 404 | (mask_p[29] << 26) | (mask_p[28] << 24) 405 | (mask_p[27] << 22) | (mask_p[26] << 20) 406 | (mask_p[25] << 18) | (mask_p[24] << 16) 407 | (mask_p[23] << 14) | (mask_p[22] << 12) 408 | (mask_p[21] << 10) | (mask_p[20] << 8) 409 | (mask_p[19] << 6) | (mask_p[18] << 4) 410 | (mask_p[17] << 2) | (mask_p[16] << 0); 411 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); 412 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); 413 414 tmp_mask = (mask_p[45] << 28) 415 | (mask_p[44] << 26) | (mask_p[43] << 24) 416 | (mask_p[42] << 22) | (mask_p[41] << 20) 417 | (mask_p[40] << 18) | (mask_p[39] << 16) 418 | (mask_p[38] << 14) | (mask_p[37] << 12) 419 | (mask_p[36] << 10) | (mask_p[35] << 8) 420 | (mask_p[34] << 6) | (mask_p[33] << 4) 421 | (mask_p[32] << 2) | (mask_p[31] << 0); 422 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); 423 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); 424 425 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) 426 | (mask_p[59] << 26) | (mask_p[58] << 24) 427 | (mask_p[57] << 22) | (mask_p[56] << 20) 428 | (mask_p[55] << 18) | (mask_p[54] << 16) 429 | (mask_p[53] << 14) | (mask_p[52] << 12) 430 | (mask_p[51] << 10) | (mask_p[50] << 8) 431 | (mask_p[49] << 6) | (mask_p[48] << 4) 432 | (mask_p[47] << 2) | (mask_p[46] << 0); 433 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); 434 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); 435} 436 437/** 438 * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming 439 * @ah: atheros hardware structure 440 * 441 * Only required for older devices with external AR2133/AR5133 radios. 442 */ 443static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) 444{ 445#define ATH_ALLOC_BANK(bank, size) do { \ 446 bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ 447 if (!bank) { \ 448 ath_print(common, ATH_DBG_FATAL, \ 449 "Cannot allocate RF banks\n"); \ 450 return -ENOMEM; \ 451 } \ 452 } while (0); 453 454 struct ath_common *common = ath9k_hw_common(ah); 455 456 BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); 457 458 ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); 459 ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); 460 ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); 461 ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); 462 ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); 463 ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); 464 ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); 465 ATH_ALLOC_BANK(ah->addac5416_21, 466 ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); 467 ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); 468 469 return 0; 470#undef ATH_ALLOC_BANK 471} 472 473 474/** 475 * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers 476 * @ah: atheros hardware struture 477 * For the external AR2133/AR5133 radios banks. 478 */ 479static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) 480{ 481#define ATH_FREE_BANK(bank) do { \ 482 kfree(bank); \ 483 bank = NULL; \ 484 } while (0); 485 486 BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); 487 488 ATH_FREE_BANK(ah->analogBank0Data); 489 ATH_FREE_BANK(ah->analogBank1Data); 490 ATH_FREE_BANK(ah->analogBank2Data); 491 ATH_FREE_BANK(ah->analogBank3Data); 492 ATH_FREE_BANK(ah->analogBank6Data); 493 ATH_FREE_BANK(ah->analogBank6TPCData); 494 ATH_FREE_BANK(ah->analogBank7Data); 495 ATH_FREE_BANK(ah->addac5416_21); 496 ATH_FREE_BANK(ah->bank6Temp); 497 498#undef ATH_FREE_BANK 499} 500 501/* * 502 * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM 503 * @ah: atheros hardware structure 504 * @chan: 505 * @modesIndex: 506 * 507 * Used for the external AR2133/AR5133 radios. 508 * 509 * Reads the EEPROM header info from the device structure and programs 510 * all rf registers. This routine requires access to the analog 511 * rf device. This is not required for single-chip devices. 512 */ 513static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, 514 struct ath9k_channel *chan, 515 u16 modesIndex) 516{ 517 u32 eepMinorRev; 518 u32 ob5GHz = 0, db5GHz = 0; 519 u32 ob2GHz = 0, db2GHz = 0; 520 int regWrites = 0; 521 522 /* 523 * Software does not need to program bank data 524 * for single chip devices, that is AR9280 or anything 525 * after that. 526 */ 527 if (AR_SREV_9280_10_OR_LATER(ah)) 528 return true; 529 530 /* Setup rf parameters */ 531 eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); 532 533 /* Setup Bank 0 Write */ 534 RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); 535 536 /* Setup Bank 1 Write */ 537 RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); 538 539 /* Setup Bank 2 Write */ 540 RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); 541 542 /* Setup Bank 6 Write */ 543 RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, 544 modesIndex); 545 { 546 int i; 547 for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { 548 ah->analogBank6Data[i] = 549 INI_RA(&ah->iniBank6TPC, i, modesIndex); 550 } 551 } 552 553 /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ 554 if (eepMinorRev >= 2) { 555 if (IS_CHAN_2GHZ(chan)) { 556 ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); 557 db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2); 558 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, 559 ob2GHz, 3, 197, 0); 560 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, 561 db2GHz, 3, 194, 0); 562 } else { 563 ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5); 564 db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5); 565 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, 566 ob5GHz, 3, 203, 0); 567 ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, 568 db5GHz, 3, 200, 0); 569 } 570 } 571 572 /* Setup Bank 7 Setup */ 573 RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); 574 575 /* Write Analog registers */ 576 REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, 577 regWrites); 578 REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, 579 regWrites); 580 REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, 581 regWrites); 582 REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, 583 regWrites); 584 REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, 585 regWrites); 586 REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, 587 regWrites); 588 589 return true; 590} 591 592static void ar5008_hw_init_bb(struct ath_hw *ah, 593 struct ath9k_channel *chan) 594{ 595 u32 synthDelay; 596 597 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 598 if (IS_CHAN_B(chan)) 599 synthDelay = (4 * synthDelay) / 22; 600 else 601 synthDelay /= 10; 602 603 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); 604 605 udelay(synthDelay + BASE_ACTIVATE_DELAY); 606} 607 608static void ar5008_hw_init_chain_masks(struct ath_hw *ah) 609{ 610 int rx_chainmask, tx_chainmask; 611 612 rx_chainmask = ah->rxchainmask; 613 tx_chainmask = ah->txchainmask; 614 615 ENABLE_REGWRITE_BUFFER(ah); 616 617 switch (rx_chainmask) { 618 case 0x5: 619 DISABLE_REGWRITE_BUFFER(ah); 620 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 621 AR_PHY_SWAP_ALT_CHAIN); 622 ENABLE_REGWRITE_BUFFER(ah); 623 case 0x3: 624 if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { 625 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); 626 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); 627 break; 628 } 629 case 0x1: 630 case 0x2: 631 case 0x7: 632 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 633 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 634 break; 635 default: 636 break; 637 } 638 639 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); 640 641 REGWRITE_BUFFER_FLUSH(ah); 642 DISABLE_REGWRITE_BUFFER(ah); 643 644 if (tx_chainmask == 0x5) { 645 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, 646 AR_PHY_SWAP_ALT_CHAIN); 647 } 648 if (AR_SREV_9100(ah)) 649 REG_WRITE(ah, AR_PHY_ANALOG_SWAP, 650 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); 651} 652 653static void ar5008_hw_override_ini(struct ath_hw *ah, 654 struct ath9k_channel *chan) 655{ 656 u32 val; 657 658 /* 659 * Set the RX_ABORT and RX_DIS and clear if off only after 660 * RXE is set for MAC. This prevents frames with corrupted 661 * descriptor status. 662 */ 663 REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); 664 665 if (AR_SREV_9280_10_OR_LATER(ah)) { 666 val = REG_READ(ah, AR_PCU_MISC_MODE2); 667 668 if (!AR_SREV_9271(ah)) 669 val &= ~AR_PCU_MISC_MODE2_HWWAR1; 670 671 if (AR_SREV_9287_10_OR_LATER(ah)) 672 val = val & (~AR_PCU_MISC_MODE2_HWWAR2); 673 674 REG_WRITE(ah, AR_PCU_MISC_MODE2, val); 675 } 676 677 if (!AR_SREV_5416_20_OR_LATER(ah) || 678 AR_SREV_9280_10_OR_LATER(ah)) 679 return; 680 /* 681 * Disable BB clock gating 682 * Necessary to avoid issues on AR5416 2.0 683 */ 684 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 685 686 /* 687 * Disable RIFS search on some chips to avoid baseband 688 * hang issues. 689 */ 690 if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { 691 val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); 692 val &= ~AR_PHY_RIFS_INIT_DELAY; 693 REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); 694 } 695} 696 697static void ar5008_hw_set_channel_regs(struct ath_hw *ah, 698 struct ath9k_channel *chan) 699{ 700 u32 phymode; 701 u32 enableDacFifo = 0; 702 703 if (AR_SREV_9285_10_OR_LATER(ah)) 704 enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & 705 AR_PHY_FC_ENABLE_DAC_FIFO); 706 707 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 708 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; 709 710 if (IS_CHAN_HT40(chan)) { 711 phymode |= AR_PHY_FC_DYN2040_EN; 712 713 if ((chan->chanmode == CHANNEL_A_HT40PLUS) || 714 (chan->chanmode == CHANNEL_G_HT40PLUS)) 715 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 716 717 } 718 REG_WRITE(ah, AR_PHY_TURBO, phymode); 719 720 ath9k_hw_set11nmac2040(ah); 721 722 ENABLE_REGWRITE_BUFFER(ah); 723 724 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); 725 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 726 727 REGWRITE_BUFFER_FLUSH(ah); 728 DISABLE_REGWRITE_BUFFER(ah); 729} 730 731 732static int ar5008_hw_process_ini(struct ath_hw *ah, 733 struct ath9k_channel *chan) 734{ 735 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); 736 int i, regWrites = 0; 737 struct ieee80211_channel *channel = chan->chan; 738 u32 modesIndex, freqIndex; 739 740 switch (chan->chanmode) { 741 case CHANNEL_A: 742 case CHANNEL_A_HT20: 743 modesIndex = 1; 744 freqIndex = 1; 745 break; 746 case CHANNEL_A_HT40PLUS: 747 case CHANNEL_A_HT40MINUS: 748 modesIndex = 2; 749 freqIndex = 1; 750 break; 751 case CHANNEL_G: 752 case CHANNEL_G_HT20: 753 case CHANNEL_B: 754 modesIndex = 4; 755 freqIndex = 2; 756 break; 757 case CHANNEL_G_HT40PLUS: 758 case CHANNEL_G_HT40MINUS: 759 modesIndex = 3; 760 freqIndex = 2; 761 break; 762 763 default: 764 return -EINVAL; 765 } 766 767 /* 768 * Set correct baseband to analog shift setting to 769 * access analog chips. 770 */ 771 REG_WRITE(ah, AR_PHY(0), 0x00000007); 772 773 /* Write ADDAC shifts */ 774 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); 775 ah->eep_ops->set_addac(ah, chan); 776 777 if (AR_SREV_5416_22_OR_LATER(ah)) { 778 REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); 779 } else { 780 struct ar5416IniArray temp; 781 u32 addacSize = 782 sizeof(u32) * ah->iniAddac.ia_rows * 783 ah->iniAddac.ia_columns; 784 785 /* For AR5416 2.0/2.1 */ 786 memcpy(ah->addac5416_21, 787 ah->iniAddac.ia_array, addacSize); 788 789 /* override CLKDRV value at [row, column] = [31, 1] */ 790 (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; 791 792 temp.ia_array = ah->addac5416_21; 793 temp.ia_columns = ah->iniAddac.ia_columns; 794 temp.ia_rows = ah->iniAddac.ia_rows; 795 REG_WRITE_ARRAY(&temp, 1, regWrites); 796 } 797 798 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); 799 800 ENABLE_REGWRITE_BUFFER(ah); 801 802 for (i = 0; i < ah->iniModes.ia_rows; i++) { 803 u32 reg = INI_RA(&ah->iniModes, i, 0); 804 u32 val = INI_RA(&ah->iniModes, i, modesIndex); 805 806 if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup) 807 val &= ~AR_AN_TOP2_PWDCLKIND; 808 809 REG_WRITE(ah, reg, val); 810 811 if (reg >= 0x7800 && reg < 0x78a0 812 && ah->config.analog_shiftreg) { 813 udelay(100); 814 } 815 816 DO_DELAY(regWrites); 817 } 818 819 REGWRITE_BUFFER_FLUSH(ah); 820 DISABLE_REGWRITE_BUFFER(ah); 821 822 if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah)) 823 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); 824 825 if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) || 826 AR_SREV_9287_10_OR_LATER(ah)) 827 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 828 829 if (AR_SREV_9271_10(ah)) 830 REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, 831 modesIndex, regWrites); 832 833 ENABLE_REGWRITE_BUFFER(ah); 834 835 /* Write common array parameters */ 836 for (i = 0; i < ah->iniCommon.ia_rows; i++) { 837 u32 reg = INI_RA(&ah->iniCommon, i, 0); 838 u32 val = INI_RA(&ah->iniCommon, i, 1); 839 840 REG_WRITE(ah, reg, val); 841 842 if (reg >= 0x7800 && reg < 0x78a0 843 && ah->config.analog_shiftreg) { 844 udelay(100); 845 } 846 847 DO_DELAY(regWrites); 848 } 849 850 REGWRITE_BUFFER_FLUSH(ah); 851 DISABLE_REGWRITE_BUFFER(ah); 852 853 if (AR_SREV_9271(ah)) { 854 if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) 855 REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, 856 modesIndex, regWrites); 857 else 858 REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, 859 modesIndex, regWrites); 860 } 861 862 REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); 863 864 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { 865 REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, 866 regWrites); 867 } 868 869 ar5008_hw_override_ini(ah, chan); 870 ar5008_hw_set_channel_regs(ah, chan); 871 ar5008_hw_init_chain_masks(ah); 872 ath9k_olc_init(ah); 873 874 /* Set TX power */ 875 ah->eep_ops->set_txpower(ah, chan, 876 ath9k_regd_get_ctl(regulatory, chan), 877 channel->max_antenna_gain * 2, 878 channel->max_power * 2, 879 min((u32) MAX_RATE_POWER, 880 (u32) regulatory->power_limit)); 881 882 /* Write analog registers */ 883 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { 884 ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, 885 "ar5416SetRfRegs failed\n"); 886 return -EIO; 887 } 888 889 return 0; 890} 891 892static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) 893{ 894 u32 rfMode = 0; 895 896 if (chan == NULL) 897 return; 898 899 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) 900 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; 901 902 if (!AR_SREV_9280_10_OR_LATER(ah)) 903 rfMode |= (IS_CHAN_5GHZ(chan)) ? 904 AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; 905 906 if (IS_CHAN_A_FAST_CLOCK(ah, chan)) 907 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); 908 909 REG_WRITE(ah, AR_PHY_MODE, rfMode); 910} 911 912static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah) 913{ 914 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); 915} 916 917static void ar5008_hw_set_delta_slope(struct ath_hw *ah, 918 struct ath9k_channel *chan) 919{ 920 u32 coef_scaled, ds_coef_exp, ds_coef_man; 921 u32 clockMhzScaled = 0x64000000; 922 struct chan_centers centers; 923 924 if (IS_CHAN_HALF_RATE(chan)) 925 clockMhzScaled = clockMhzScaled >> 1; 926 else if (IS_CHAN_QUARTER_RATE(chan)) 927 clockMhzScaled = clockMhzScaled >> 2; 928 929 ath9k_hw_get_channel_centers(ah, chan, ¢ers); 930 coef_scaled = clockMhzScaled / centers.synth_center; 931 932 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, 933 &ds_coef_exp); 934 935 REG_RMW_FIELD(ah, AR_PHY_TIMING3, 936 AR_PHY_TIMING3_DSC_MAN, ds_coef_man); 937 REG_RMW_FIELD(ah, AR_PHY_TIMING3, 938 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); 939 940 coef_scaled = (9 * coef_scaled) / 10; 941 942 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, 943 &ds_coef_exp); 944 945 REG_RMW_FIELD(ah, AR_PHY_HALFGI, 946 AR_PHY_HALFGI_DSC_MAN, ds_coef_man); 947 REG_RMW_FIELD(ah, AR_PHY_HALFGI, 948 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); 949} 950 951static bool ar5008_hw_rfbus_req(struct ath_hw *ah) 952{ 953 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); 954 return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, 955 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT); 956} 957 958static void ar5008_hw_rfbus_done(struct ath_hw *ah) 959{ 960 u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; 961 if (IS_CHAN_B(ah->curchan)) 962 synthDelay = (4 * synthDelay) / 22; 963 else 964 synthDelay /= 10; 965 966 udelay(synthDelay + BASE_ACTIVATE_DELAY); 967 968 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); 969} 970 971static void ar5008_hw_enable_rfkill(struct ath_hw *ah) 972{ 973 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, 974 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); 975 976 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, 977 AR_GPIO_INPUT_MUX2_RFSILENT); 978 979 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); 980 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); 981} 982 983static void ar5008_restore_chainmask(struct ath_hw *ah) 984{ 985 int rx_chainmask = ah->rxchainmask; 986 987 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { 988 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); 989 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); 990 } 991} 992 993static void ar5008_set_diversity(struct ath_hw *ah, bool value) 994{ 995 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); 996 if (value) 997 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 998 else 999 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; 1000 REG_WRITE(ah, AR_PHY_CCK_DETECT, v); 1001} 1002 1003static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah, 1004 struct ath9k_channel *chan) 1005{ 1006 if (chan && IS_CHAN_5GHZ(chan)) 1007 return 0x1450; 1008 return 0x1458; 1009} 1010 1011static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah, 1012 struct ath9k_channel *chan) 1013{ 1014 u32 pll; 1015 1016 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); 1017 1018 if (chan && IS_CHAN_HALF_RATE(chan)) 1019 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); 1020 else if (chan && IS_CHAN_QUARTER_RATE(chan)) 1021 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); 1022 1023 if (chan && IS_CHAN_5GHZ(chan)) 1024 pll |= SM(0x50, AR_RTC_9160_PLL_DIV); 1025 else 1026 pll |= SM(0x58, AR_RTC_9160_PLL_DIV); 1027 1028 return pll; 1029} 1030 1031static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah, 1032 struct ath9k_channel *chan) 1033{ 1034 u32 pll; 1035 1036 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; 1037 1038 if (chan && IS_CHAN_HALF_RATE(chan)) 1039 pll |= SM(0x1, AR_RTC_PLL_CLKSEL); 1040 else if (chan && IS_CHAN_QUARTER_RATE(chan)) 1041 pll |= SM(0x2, AR_RTC_PLL_CLKSEL); 1042 1043 if (chan && IS_CHAN_5GHZ(chan)) 1044 pll |= SM(0xa, AR_RTC_PLL_DIV); 1045 else 1046 pll |= SM(0xb, AR_RTC_PLL_DIV); 1047 1048 return pll; 1049} 1050 1051static bool ar5008_hw_ani_control_old(struct ath_hw *ah, 1052 enum ath9k_ani_cmd cmd, 1053 int param) 1054{ 1055 struct ar5416AniState *aniState = ah->curani; 1056 struct ath_common *common = ath9k_hw_common(ah); 1057 1058 switch (cmd & ah->ani_function) { 1059 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ 1060 u32 level = param; 1061 1062 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { 1063 ath_print(common, ATH_DBG_ANI, 1064 "level out of range (%u > %u)\n", 1065 level, 1066 (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); 1067 return false; 1068 } 1069 1070 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, 1071 AR_PHY_DESIRED_SZ_TOT_DES, 1072 ah->totalSizeDesired[level]); 1073 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 1074 AR_PHY_AGC_CTL1_COARSE_LOW, 1075 ah->coarse_low[level]); 1076 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, 1077 AR_PHY_AGC_CTL1_COARSE_HIGH, 1078 ah->coarse_high[level]); 1079 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 1080 AR_PHY_FIND_SIG_FIRPWR, 1081 ah->firpwr[level]); 1082 1083 if (level > aniState->noiseImmunityLevel) 1084 ah->stats.ast_ani_niup++; 1085 else if (level < aniState->noiseImmunityLevel) 1086 ah->stats.ast_ani_nidown++; 1087 aniState->noiseImmunityLevel = level; 1088 break; 1089 } 1090 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 1091 const int m1ThreshLow[] = { 127, 50 }; 1092 const int m2ThreshLow[] = { 127, 40 }; 1093 const int m1Thresh[] = { 127, 0x4d }; 1094 const int m2Thresh[] = { 127, 0x40 }; 1095 const int m2CountThr[] = { 31, 16 }; 1096 const int m2CountThrLow[] = { 63, 48 }; 1097 u32 on = param ? 1 : 0; 1098 1099 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1100 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 1101 m1ThreshLow[on]); 1102 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1103 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 1104 m2ThreshLow[on]); 1105 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1106 AR_PHY_SFCORR_M1_THRESH, 1107 m1Thresh[on]); 1108 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1109 AR_PHY_SFCORR_M2_THRESH, 1110 m2Thresh[on]); 1111 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1112 AR_PHY_SFCORR_M2COUNT_THR, 1113 m2CountThr[on]); 1114 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1115 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 1116 m2CountThrLow[on]); 1117 1118 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1119 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, 1120 m1ThreshLow[on]); 1121 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1122 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, 1123 m2ThreshLow[on]); 1124 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1125 AR_PHY_SFCORR_EXT_M1_THRESH, 1126 m1Thresh[on]); 1127 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1128 AR_PHY_SFCORR_EXT_M2_THRESH, 1129 m2Thresh[on]); 1130 1131 if (on) 1132 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 1133 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 1134 else 1135 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, 1136 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 1137 1138 if (!on != aniState->ofdmWeakSigDetectOff) { 1139 if (on) 1140 ah->stats.ast_ani_ofdmon++; 1141 else 1142 ah->stats.ast_ani_ofdmoff++; 1143 aniState->ofdmWeakSigDetectOff = !on; 1144 } 1145 break; 1146 } 1147 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ 1148 const int weakSigThrCck[] = { 8, 6 }; 1149 u32 high = param ? 1 : 0; 1150 1151 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, 1152 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, 1153 weakSigThrCck[high]); 1154 if (high != aniState->cckWeakSigThreshold) { 1155 if (high) 1156 ah->stats.ast_ani_cckhigh++; 1157 else 1158 ah->stats.ast_ani_ccklow++; 1159 aniState->cckWeakSigThreshold = high; 1160 } 1161 break; 1162 } 1163 case ATH9K_ANI_FIRSTEP_LEVEL:{ 1164 const int firstep[] = { 0, 4, 8 }; 1165 u32 level = param; 1166 1167 if (level >= ARRAY_SIZE(firstep)) { 1168 ath_print(common, ATH_DBG_ANI, 1169 "level out of range (%u > %u)\n", 1170 level, 1171 (unsigned) ARRAY_SIZE(firstep)); 1172 return false; 1173 } 1174 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 1175 AR_PHY_FIND_SIG_FIRSTEP, 1176 firstep[level]); 1177 if (level > aniState->firstepLevel) 1178 ah->stats.ast_ani_stepup++; 1179 else if (level < aniState->firstepLevel) 1180 ah->stats.ast_ani_stepdown++; 1181 aniState->firstepLevel = level; 1182 break; 1183 } 1184 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 1185 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; 1186 u32 level = param; 1187 1188 if (level >= ARRAY_SIZE(cycpwrThr1)) { 1189 ath_print(common, ATH_DBG_ANI, 1190 "level out of range (%u > %u)\n", 1191 level, 1192 (unsigned) ARRAY_SIZE(cycpwrThr1)); 1193 return false; 1194 } 1195 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 1196 AR_PHY_TIMING5_CYCPWR_THR1, 1197 cycpwrThr1[level]); 1198 if (level > aniState->spurImmunityLevel) 1199 ah->stats.ast_ani_spurup++; 1200 else if (level < aniState->spurImmunityLevel) 1201 ah->stats.ast_ani_spurdown++; 1202 aniState->spurImmunityLevel = level; 1203 break; 1204 } 1205 case ATH9K_ANI_PRESENT: 1206 break; 1207 default: 1208 ath_print(common, ATH_DBG_ANI, 1209 "invalid cmd %u\n", cmd); 1210 return false; 1211 } 1212 1213 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); 1214 ath_print(common, ATH_DBG_ANI, 1215 "noiseImmunityLevel=%d, spurImmunityLevel=%d, " 1216 "ofdmWeakSigDetectOff=%d\n", 1217 aniState->noiseImmunityLevel, 1218 aniState->spurImmunityLevel, 1219 !aniState->ofdmWeakSigDetectOff); 1220 ath_print(common, ATH_DBG_ANI, 1221 "cckWeakSigThreshold=%d, " 1222 "firstepLevel=%d, listenTime=%d\n", 1223 aniState->cckWeakSigThreshold, 1224 aniState->firstepLevel, 1225 aniState->listenTime); 1226 ath_print(common, ATH_DBG_ANI, 1227 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", 1228 aniState->cycleCount, 1229 aniState->ofdmPhyErrCount, 1230 aniState->cckPhyErrCount); 1231 1232 return true; 1233} 1234 1235static bool ar5008_hw_ani_control_new(struct ath_hw *ah, 1236 enum ath9k_ani_cmd cmd, 1237 int param) 1238{ 1239 struct ar5416AniState *aniState = ah->curani; 1240 struct ath_common *common = ath9k_hw_common(ah); 1241 struct ath9k_channel *chan = ah->curchan; 1242 s32 value, value2; 1243 1244 switch (cmd & ah->ani_function) { 1245 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ 1246 /* 1247 * on == 1 means ofdm weak signal detection is ON 1248 * on == 1 is the default, for less noise immunity 1249 * 1250 * on == 0 means ofdm weak signal detection is OFF 1251 * on == 0 means more noise imm 1252 */ 1253 u32 on = param ? 1 : 0; 1254 /* 1255 * make register setting for default 1256 * (weak sig detect ON) come from INI file 1257 */ 1258 int m1ThreshLow = on ? 1259 aniState->iniDef.m1ThreshLow : m1ThreshLow_off; 1260 int m2ThreshLow = on ? 1261 aniState->iniDef.m2ThreshLow : m2ThreshLow_off; 1262 int m1Thresh = on ? 1263 aniState->iniDef.m1Thresh : m1Thresh_off; 1264 int m2Thresh = on ? 1265 aniState->iniDef.m2Thresh : m2Thresh_off; 1266 int m2CountThr = on ? 1267 aniState->iniDef.m2CountThr : m2CountThr_off; 1268 int m2CountThrLow = on ? 1269 aniState->iniDef.m2CountThrLow : m2CountThrLow_off; 1270 int m1ThreshLowExt = on ? 1271 aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off; 1272 int m2ThreshLowExt = on ? 1273 aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off; 1274 int m1ThreshExt = on ? 1275 aniState->iniDef.m1ThreshExt : m1ThreshExt_off; 1276 int m2ThreshExt = on ? 1277 aniState->iniDef.m2ThreshExt : m2ThreshExt_off; 1278 1279 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1280 AR_PHY_SFCORR_LOW_M1_THRESH_LOW, 1281 m1ThreshLow); 1282 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1283 AR_PHY_SFCORR_LOW_M2_THRESH_LOW, 1284 m2ThreshLow); 1285 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1286 AR_PHY_SFCORR_M1_THRESH, m1Thresh); 1287 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1288 AR_PHY_SFCORR_M2_THRESH, m2Thresh); 1289 REG_RMW_FIELD(ah, AR_PHY_SFCORR, 1290 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr); 1291 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, 1292 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, 1293 m2CountThrLow); 1294 1295 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1296 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt); 1297 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1298 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt); 1299 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1300 AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt); 1301 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, 1302 AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt); 1303 1304 if (on) 1305 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, 1306 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 1307 else 1308 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, 1309 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); 1310 1311 if (!on != aniState->ofdmWeakSigDetectOff) { 1312 ath_print(common, ATH_DBG_ANI, 1313 "** ch %d: ofdm weak signal: %s=>%s\n", 1314 chan->channel, 1315 !aniState->ofdmWeakSigDetectOff ? 1316 "on" : "off", 1317 on ? "on" : "off"); 1318 if (on) 1319 ah->stats.ast_ani_ofdmon++; 1320 else 1321 ah->stats.ast_ani_ofdmoff++; 1322 aniState->ofdmWeakSigDetectOff = !on; 1323 } 1324 break; 1325 } 1326 case ATH9K_ANI_FIRSTEP_LEVEL:{ 1327 u32 level = param; 1328 1329 if (level >= ARRAY_SIZE(firstep_table)) { 1330 ath_print(common, ATH_DBG_ANI, 1331 "ATH9K_ANI_FIRSTEP_LEVEL: level " 1332 "out of range (%u > %u)\n", 1333 level, 1334 (unsigned) ARRAY_SIZE(firstep_table)); 1335 return false; 1336 } 1337 1338 /* 1339 * make register setting relative to default 1340 * from INI file & cap value 1341 */ 1342 value = firstep_table[level] - 1343 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + 1344 aniState->iniDef.firstep; 1345 if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN) 1346 value = ATH9K_SIG_FIRSTEP_SETTING_MIN; 1347 if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX) 1348 value = ATH9K_SIG_FIRSTEP_SETTING_MAX; 1349 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, 1350 AR_PHY_FIND_SIG_FIRSTEP, 1351 value); 1352 /* 1353 * we need to set first step low register too 1354 * make register setting relative to default 1355 * from INI file & cap value 1356 */ 1357 value2 = firstep_table[level] - 1358 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] + 1359 aniState->iniDef.firstepLow; 1360 if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN) 1361 value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN; 1362 if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX) 1363 value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX; 1364 1365 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW, 1366 AR_PHY_FIND_SIG_FIRSTEP_LOW, value2); 1367 1368 if (level != aniState->firstepLevel) { 1369 ath_print(common, ATH_DBG_ANI, 1370 "** ch %d: level %d=>%d[def:%d] " 1371 "firstep[level]=%d ini=%d\n", 1372 chan->channel, 1373 aniState->firstepLevel, 1374 level, 1375 ATH9K_ANI_FIRSTEP_LVL_NEW, 1376 value, 1377 aniState->iniDef.firstep); 1378 ath_print(common, ATH_DBG_ANI, 1379 "** ch %d: level %d=>%d[def:%d] " 1380 "firstep_low[level]=%d ini=%d\n", 1381 chan->channel, 1382 aniState->firstepLevel, 1383 level, 1384 ATH9K_ANI_FIRSTEP_LVL_NEW, 1385 value2, 1386 aniState->iniDef.firstepLow); 1387 if (level > aniState->firstepLevel) 1388 ah->stats.ast_ani_stepup++; 1389 else if (level < aniState->firstepLevel) 1390 ah->stats.ast_ani_stepdown++; 1391 aniState->firstepLevel = level; 1392 } 1393 break; 1394 } 1395 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ 1396 u32 level = param; 1397 1398 if (level >= ARRAY_SIZE(cycpwrThr1_table)) { 1399 ath_print(common, ATH_DBG_ANI, 1400 "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level " 1401 "out of range (%u > %u)\n", 1402 level, 1403 (unsigned) ARRAY_SIZE(cycpwrThr1_table)); 1404 return false; 1405 } 1406 /* 1407 * make register setting relative to default 1408 * from INI file & cap value 1409 */ 1410 value = cycpwrThr1_table[level] - 1411 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + 1412 aniState->iniDef.cycpwrThr1; 1413 if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN) 1414 value = ATH9K_SIG_SPUR_IMM_SETTING_MIN; 1415 if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX) 1416 value = ATH9K_SIG_SPUR_IMM_SETTING_MAX; 1417 REG_RMW_FIELD(ah, AR_PHY_TIMING5, 1418 AR_PHY_TIMING5_CYCPWR_THR1, 1419 value); 1420 1421 /* 1422 * set AR_PHY_EXT_CCA for extension channel 1423 * make register setting relative to default 1424 * from INI file & cap value 1425 */ 1426 value2 = cycpwrThr1_table[level] - 1427 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] + 1428 aniState->iniDef.cycpwrThr1Ext; 1429 if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN) 1430 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN; 1431 if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX) 1432 value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX; 1433 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA, 1434 AR_PHY_EXT_TIMING5_CYCPWR_THR1, value2); 1435 1436 if (level != aniState->spurImmunityLevel) { 1437 ath_print(common, ATH_DBG_ANI, 1438 "** ch %d: level %d=>%d[def:%d] " 1439 "cycpwrThr1[level]=%d ini=%d\n", 1440 chan->channel, 1441 aniState->spurImmunityLevel, 1442 level, 1443 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, 1444 value, 1445 aniState->iniDef.cycpwrThr1); 1446 ath_print(common, ATH_DBG_ANI, 1447 "** ch %d: level %d=>%d[def:%d] " 1448 "cycpwrThr1Ext[level]=%d ini=%d\n", 1449 chan->channel, 1450 aniState->spurImmunityLevel, 1451 level, 1452 ATH9K_ANI_SPUR_IMMUNE_LVL_NEW, 1453 value2, 1454 aniState->iniDef.cycpwrThr1Ext); 1455 if (level > aniState->spurImmunityLevel) 1456 ah->stats.ast_ani_spurup++; 1457 else if (level < aniState->spurImmunityLevel) 1458 ah->stats.ast_ani_spurdown++; 1459 aniState->spurImmunityLevel = level; 1460 } 1461 break; 1462 } 1463 case ATH9K_ANI_MRC_CCK: 1464 /* 1465 * You should not see this as AR5008, AR9001, AR9002 1466 * does not have hardware support for MRC CCK. 1467 */ 1468 WARN_ON(1); 1469 break; 1470 case ATH9K_ANI_PRESENT: 1471 break; 1472 default: 1473 ath_print(common, ATH_DBG_ANI, 1474 "invalid cmd %u\n", cmd); 1475 return false; 1476 } 1477 1478 ath_print(common, ATH_DBG_ANI, 1479 "ANI parameters: SI=%d, ofdmWS=%s FS=%d " 1480 "MRCcck=%s listenTime=%d CC=%d listen=%d " 1481 "ofdmErrs=%d cckErrs=%d\n", 1482 aniState->spurImmunityLevel, 1483 !aniState->ofdmWeakSigDetectOff ? "on" : "off", 1484 aniState->firstepLevel, 1485 !aniState->mrcCCKOff ? "on" : "off", 1486 aniState->listenTime, 1487 aniState->cycleCount, 1488 aniState->listenTime, 1489 aniState->ofdmPhyErrCount, 1490 aniState->cckPhyErrCount); 1491 return true; 1492} 1493 1494static void ar5008_hw_do_getnf(struct ath_hw *ah, 1495 int16_t nfarray[NUM_NF_READINGS]) 1496{ 1497 int16_t nf; 1498 1499 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); 1500 nfarray[0] = sign_extend(nf, 9); 1501 1502 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); 1503 nfarray[1] = sign_extend(nf, 9); 1504 1505 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); 1506 nfarray[2] = sign_extend(nf, 9); 1507 1508 if (!IS_CHAN_HT40(ah->curchan)) 1509 return; 1510 1511 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); 1512 nfarray[3] = sign_extend(nf, 9); 1513 1514 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); 1515 nfarray[4] = sign_extend(nf, 9); 1516 1517 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); 1518 nfarray[5] = sign_extend(nf, 9); 1519} 1520 1521/* 1522 * Initialize the ANI register values with default (ini) values. 1523 * This routine is called during a (full) hardware reset after 1524 * all the registers are initialised from the INI. 1525 */ 1526static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah) 1527{ 1528 struct ar5416AniState *aniState; 1529 struct ath_common *common = ath9k_hw_common(ah); 1530 struct ath9k_channel *chan = ah->curchan; 1531 struct ath9k_ani_default *iniDef; 1532 int index; 1533 u32 val; 1534 1535 index = ath9k_hw_get_ani_channel_idx(ah, chan); 1536 aniState = &ah->ani[index]; 1537 ah->curani = aniState; 1538 iniDef = &aniState->iniDef; 1539 1540 ath_print(common, ATH_DBG_ANI, 1541 "ver %d.%d opmode %u chan %d Mhz/0x%x\n", 1542 ah->hw_version.macVersion, 1543 ah->hw_version.macRev, 1544 ah->opmode, 1545 chan->channel, 1546 chan->channelFlags); 1547 1548 val = REG_READ(ah, AR_PHY_SFCORR); 1549 iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH); 1550 iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH); 1551 iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR); 1552 1553 val = REG_READ(ah, AR_PHY_SFCORR_LOW); 1554 iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW); 1555 iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW); 1556 iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW); 1557 1558 val = REG_READ(ah, AR_PHY_SFCORR_EXT); 1559 iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH); 1560 iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH); 1561 iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW); 1562 iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW); 1563 iniDef->firstep = REG_READ_FIELD(ah, 1564 AR_PHY_FIND_SIG, 1565 AR_PHY_FIND_SIG_FIRSTEP); 1566 iniDef->firstepLow = REG_READ_FIELD(ah, 1567 AR_PHY_FIND_SIG_LOW, 1568 AR_PHY_FIND_SIG_FIRSTEP_LOW); 1569 iniDef->cycpwrThr1 = REG_READ_FIELD(ah, 1570 AR_PHY_TIMING5, 1571 AR_PHY_TIMING5_CYCPWR_THR1); 1572 iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah, 1573 AR_PHY_EXT_CCA, 1574 AR_PHY_EXT_TIMING5_CYCPWR_THR1); 1575 1576 /* these levels just got reset to defaults by the INI */ 1577 aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW; 1578 aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW; 1579 aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG; 1580 aniState->mrcCCKOff = true; /* not available on pre AR9003 */ 1581 1582 aniState->cycleCount = 0; 1583} 1584 1585static void ar5008_hw_set_nf_limits(struct ath_hw *ah) 1586{ 1587 ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ; 1588 ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ; 1589 ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ; 1590 ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ; 1591 ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ; 1592 ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ; 1593} 1594 1595void ar5008_hw_attach_phy_ops(struct ath_hw *ah) 1596{ 1597 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 1598 const u32 ar5416_cca_regs[6] = { 1599 AR_PHY_CCA, 1600 AR_PHY_CH1_CCA, 1601 AR_PHY_CH2_CCA, 1602 AR_PHY_EXT_CCA, 1603 AR_PHY_CH1_EXT_CCA, 1604 AR_PHY_CH2_EXT_CCA 1605 }; 1606 1607 priv_ops->rf_set_freq = ar5008_hw_set_channel; 1608 priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; 1609 1610 priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks; 1611 priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks; 1612 priv_ops->set_rf_regs = ar5008_hw_set_rf_regs; 1613 priv_ops->set_channel_regs = ar5008_hw_set_channel_regs; 1614 priv_ops->init_bb = ar5008_hw_init_bb; 1615 priv_ops->process_ini = ar5008_hw_process_ini; 1616 priv_ops->set_rfmode = ar5008_hw_set_rfmode; 1617 priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive; 1618 priv_ops->set_delta_slope = ar5008_hw_set_delta_slope; 1619 priv_ops->rfbus_req = ar5008_hw_rfbus_req; 1620 priv_ops->rfbus_done = ar5008_hw_rfbus_done; 1621 priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; 1622 priv_ops->restore_chainmask = ar5008_restore_chainmask; 1623 priv_ops->set_diversity = ar5008_set_diversity; 1624 priv_ops->do_getnf = ar5008_hw_do_getnf; 1625 1626 if (modparam_force_new_ani) { 1627 priv_ops->ani_control = ar5008_hw_ani_control_new; 1628 priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs; 1629 } else 1630 priv_ops->ani_control = ar5008_hw_ani_control_old; 1631 1632 if (AR_SREV_9100(ah)) 1633 priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; 1634 else if (AR_SREV_9160_10_OR_LATER(ah)) 1635 priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; 1636 else 1637 priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; 1638 1639 ar5008_hw_set_nf_limits(ah); 1640 memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs)); 1641} 1642