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