1 /* 2 * Copyright (c) 2008-2011 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 <linux/moduleparam.h> 18 #include "hw.h" 19 #include "ar5008_initvals.h" 20 #include "ar9001_initvals.h" 21 #include "ar9002_initvals.h" 22 #include "ar9002_phy.h" 23 24 int modparam_force_new_ani; 25 module_param_named(force_new_ani, modparam_force_new_ani, int, 0444); 26 MODULE_PARM_DESC(force_new_ani, "Force new ANI for AR5008, AR9001, AR9002"); 27 28 /* General hardware code for the A5008/AR9001/AR9002 hadware families */ 29 30 static void ar9002_hw_init_mode_regs(struct ath_hw *ah) 31 { 32 if (AR_SREV_9271(ah)) { 33 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, 34 ARRAY_SIZE(ar9271Modes_9271), 5); 35 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, 36 ARRAY_SIZE(ar9271Common_9271), 2); 37 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, 38 ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); 39 return; 40 } 41 42 if (ah->config.pcie_clock_req) 43 INIT_INI_ARRAY(&ah->iniPcieSerdes, 44 ar9280PciePhy_clkreq_off_L1_9280, 45 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2); 46 else 47 INIT_INI_ARRAY(&ah->iniPcieSerdes, 48 ar9280PciePhy_clkreq_always_on_L1_9280, 49 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); 50 51 if (AR_SREV_9287_11_OR_LATER(ah)) { 52 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, 53 ARRAY_SIZE(ar9287Modes_9287_1_1), 5); 54 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, 55 ARRAY_SIZE(ar9287Common_9287_1_1), 2); 56 } else if (AR_SREV_9285_12_OR_LATER(ah)) { 57 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, 58 ARRAY_SIZE(ar9285Modes_9285_1_2), 5); 59 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, 60 ARRAY_SIZE(ar9285Common_9285_1_2), 2); 61 } else if (AR_SREV_9280_20_OR_LATER(ah)) { 62 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, 63 ARRAY_SIZE(ar9280Modes_9280_2), 5); 64 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, 65 ARRAY_SIZE(ar9280Common_9280_2), 2); 66 67 INIT_INI_ARRAY(&ah->iniModesFastClock, 68 ar9280Modes_fast_clock_9280_2, 69 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); 70 } else if (AR_SREV_9160_10_OR_LATER(ah)) { 71 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, 72 ARRAY_SIZE(ar5416Modes_9160), 5); 73 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, 74 ARRAY_SIZE(ar5416Common_9160), 2); 75 if (AR_SREV_9160_11(ah)) { 76 INIT_INI_ARRAY(&ah->iniAddac, 77 ar5416Addac_9160_1_1, 78 ARRAY_SIZE(ar5416Addac_9160_1_1), 2); 79 } else { 80 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, 81 ARRAY_SIZE(ar5416Addac_9160), 2); 82 } 83 } else if (AR_SREV_9100_OR_LATER(ah)) { 84 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, 85 ARRAY_SIZE(ar5416Modes_9100), 5); 86 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, 87 ARRAY_SIZE(ar5416Common_9100), 2); 88 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, 89 ARRAY_SIZE(ar5416Bank6_9100), 3); 90 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, 91 ARRAY_SIZE(ar5416Addac_9100), 2); 92 } else { 93 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, 94 ARRAY_SIZE(ar5416Modes), 5); 95 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, 96 ARRAY_SIZE(ar5416Common), 2); 97 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, 98 ARRAY_SIZE(ar5416Bank6TPC), 3); 99 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, 100 ARRAY_SIZE(ar5416Addac), 2); 101 } 102 103 if (!AR_SREV_9280_20_OR_LATER(ah)) { 104 /* Common for AR5416, AR913x, AR9160 */ 105 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, 106 ARRAY_SIZE(ar5416BB_RfGain), 3); 107 108 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, 109 ARRAY_SIZE(ar5416Bank0), 2); 110 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, 111 ARRAY_SIZE(ar5416Bank1), 2); 112 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, 113 ARRAY_SIZE(ar5416Bank2), 2); 114 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, 115 ARRAY_SIZE(ar5416Bank3), 3); 116 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, 117 ARRAY_SIZE(ar5416Bank7), 2); 118 119 /* Common for AR5416, AR9160 */ 120 if (!AR_SREV_9100(ah)) 121 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, 122 ARRAY_SIZE(ar5416Bank6), 3); 123 124 /* Common for AR913x, AR9160 */ 125 if (!AR_SREV_5416(ah)) 126 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, 127 ARRAY_SIZE(ar5416Bank6TPC_9100), 3); 128 } 129 130 /* iniAddac needs to be modified for these chips */ 131 if (AR_SREV_9160(ah) || !AR_SREV_5416_22_OR_LATER(ah)) { 132 struct ar5416IniArray *addac = &ah->iniAddac; 133 u32 size = sizeof(u32) * addac->ia_rows * addac->ia_columns; 134 u32 *data; 135 136 data = kmalloc(size, GFP_KERNEL); 137 if (!data) 138 return; 139 140 memcpy(data, addac->ia_array, size); 141 addac->ia_array = data; 142 143 if (!AR_SREV_5416_22_OR_LATER(ah)) { 144 /* override CLKDRV value */ 145 INI_RA(addac, 31,1) = 0; 146 } 147 } 148 if (AR_SREV_9287_11_OR_LATER(ah)) { 149 INIT_INI_ARRAY(&ah->iniCckfirNormal, 150 ar9287Common_normal_cck_fir_coeff_9287_1_1, 151 ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), 152 2); 153 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 154 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, 155 ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), 156 2); 157 } 158 } 159 160 static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) 161 { 162 u32 rxgain_type; 163 164 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= 165 AR5416_EEP_MINOR_VER_17) { 166 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE); 167 168 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) 169 INIT_INI_ARRAY(&ah->iniModesRxGain, 170 ar9280Modes_backoff_13db_rxgain_9280_2, 171 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 5); 172 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) 173 INIT_INI_ARRAY(&ah->iniModesRxGain, 174 ar9280Modes_backoff_23db_rxgain_9280_2, 175 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 5); 176 else 177 INIT_INI_ARRAY(&ah->iniModesRxGain, 178 ar9280Modes_original_rxgain_9280_2, 179 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); 180 } else { 181 INIT_INI_ARRAY(&ah->iniModesRxGain, 182 ar9280Modes_original_rxgain_9280_2, 183 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); 184 } 185 } 186 187 static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) 188 { 189 if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= 190 AR5416_EEP_MINOR_VER_19) { 191 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) 192 INIT_INI_ARRAY(&ah->iniModesTxGain, 193 ar9280Modes_high_power_tx_gain_9280_2, 194 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 5); 195 else 196 INIT_INI_ARRAY(&ah->iniModesTxGain, 197 ar9280Modes_original_tx_gain_9280_2, 198 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); 199 } else { 200 INIT_INI_ARRAY(&ah->iniModesTxGain, 201 ar9280Modes_original_tx_gain_9280_2, 202 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); 203 } 204 } 205 206 static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) 207 { 208 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) 209 INIT_INI_ARRAY(&ah->iniModesTxGain, 210 ar9271Modes_high_power_tx_gain_9271, 211 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); 212 else 213 INIT_INI_ARRAY(&ah->iniModesTxGain, 214 ar9271Modes_normal_power_tx_gain_9271, 215 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); 216 } 217 218 static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) 219 { 220 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); 221 222 if (AR_SREV_9287_11_OR_LATER(ah)) 223 INIT_INI_ARRAY(&ah->iniModesRxGain, 224 ar9287Modes_rx_gain_9287_1_1, 225 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 5); 226 else if (AR_SREV_9280_20(ah)) 227 ar9280_20_hw_init_rxgain_ini(ah); 228 229 if (AR_SREV_9271(ah)) { 230 ar9271_hw_init_txgain_ini(ah, txgain_type); 231 } else if (AR_SREV_9287_11_OR_LATER(ah)) { 232 INIT_INI_ARRAY(&ah->iniModesTxGain, 233 ar9287Modes_tx_gain_9287_1_1, 234 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); 235 } else if (AR_SREV_9280_20(ah)) { 236 ar9280_20_hw_init_txgain_ini(ah, txgain_type); 237 } else if (AR_SREV_9285_12_OR_LATER(ah)) { 238 /* txgain table */ 239 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { 240 if (AR_SREV_9285E_20(ah)) { 241 INIT_INI_ARRAY(&ah->iniModesTxGain, 242 ar9285Modes_XE2_0_high_power, 243 ARRAY_SIZE( 244 ar9285Modes_XE2_0_high_power), 5); 245 } else { 246 INIT_INI_ARRAY(&ah->iniModesTxGain, 247 ar9285Modes_high_power_tx_gain_9285_1_2, 248 ARRAY_SIZE( 249 ar9285Modes_high_power_tx_gain_9285_1_2), 5); 250 } 251 } else { 252 if (AR_SREV_9285E_20(ah)) { 253 INIT_INI_ARRAY(&ah->iniModesTxGain, 254 ar9285Modes_XE2_0_normal_power, 255 ARRAY_SIZE( 256 ar9285Modes_XE2_0_normal_power), 5); 257 } else { 258 INIT_INI_ARRAY(&ah->iniModesTxGain, 259 ar9285Modes_original_tx_gain_9285_1_2, 260 ARRAY_SIZE( 261 ar9285Modes_original_tx_gain_9285_1_2), 5); 262 } 263 } 264 } 265 } 266 267 /* 268 * Helper for ASPM support. 269 * 270 * Disable PLL when in L0s as well as receiver clock when in L1. 271 * This power saving option must be enabled through the SerDes. 272 * 273 * Programming the SerDes must go through the same 288 bit serial shift 274 * register as the other analog registers. Hence the 9 writes. 275 */ 276 static void ar9002_hw_configpcipowersave(struct ath_hw *ah, 277 bool power_off) 278 { 279 u8 i; 280 u32 val; 281 282 /* Nothing to do on restore for 11N */ 283 if (!power_off /* !restore */) { 284 if (AR_SREV_9280_20_OR_LATER(ah)) { 285 /* 286 * AR9280 2.0 or later chips use SerDes values from the 287 * initvals.h initialized depending on chipset during 288 * __ath9k_hw_init() 289 */ 290 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { 291 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), 292 INI_RA(&ah->iniPcieSerdes, i, 1)); 293 } 294 } else { 295 ENABLE_REGWRITE_BUFFER(ah); 296 297 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); 298 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); 299 300 /* RX shut off when elecidle is asserted */ 301 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); 302 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); 303 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); 304 305 /* 306 * Ignore ah->ah_config.pcie_clock_req setting for 307 * pre-AR9280 11n 308 */ 309 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); 310 311 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); 312 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); 313 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); 314 315 /* Load the new settings */ 316 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); 317 318 REGWRITE_BUFFER_FLUSH(ah); 319 } 320 321 udelay(1000); 322 } 323 324 if (power_off) { 325 /* clear bit 19 to disable L1 */ 326 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 327 328 val = REG_READ(ah, AR_WA); 329 330 /* 331 * Set PCIe workaround bits 332 * In AR9280 and AR9285, bit 14 in WA register (disable L1) 333 * should only be set when device enters D3 and be 334 * cleared when device comes back to D0. 335 */ 336 if (ah->config.pcie_waen) { 337 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) 338 val |= AR_WA_D3_L1_DISABLE; 339 } else { 340 if (((AR_SREV_9285(ah) || 341 AR_SREV_9271(ah) || 342 AR_SREV_9287(ah)) && 343 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || 344 (AR_SREV_9280(ah) && 345 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { 346 val |= AR_WA_D3_L1_DISABLE; 347 } 348 } 349 350 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) { 351 /* 352 * Disable bit 6 and 7 before entering D3 to 353 * prevent system hang. 354 */ 355 val &= ~(AR_WA_BIT6 | AR_WA_BIT7); 356 } 357 358 if (AR_SREV_9280(ah)) 359 val |= AR_WA_BIT22; 360 361 if (AR_SREV_9285E_20(ah)) 362 val |= AR_WA_BIT23; 363 364 REG_WRITE(ah, AR_WA, val); 365 } else { 366 if (ah->config.pcie_waen) { 367 val = ah->config.pcie_waen; 368 if (!power_off) 369 val &= (~AR_WA_D3_L1_DISABLE); 370 } else { 371 if (AR_SREV_9285(ah) || 372 AR_SREV_9271(ah) || 373 AR_SREV_9287(ah)) { 374 val = AR9285_WA_DEFAULT; 375 if (!power_off) 376 val &= (~AR_WA_D3_L1_DISABLE); 377 } 378 else if (AR_SREV_9280(ah)) { 379 /* 380 * For AR9280 chips, bit 22 of 0x4004 381 * needs to be set. 382 */ 383 val = AR9280_WA_DEFAULT; 384 if (!power_off) 385 val &= (~AR_WA_D3_L1_DISABLE); 386 } else { 387 val = AR_WA_DEFAULT; 388 } 389 } 390 391 /* WAR for ASPM system hang */ 392 if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) 393 val |= (AR_WA_BIT6 | AR_WA_BIT7); 394 395 if (AR_SREV_9285E_20(ah)) 396 val |= AR_WA_BIT23; 397 398 REG_WRITE(ah, AR_WA, val); 399 400 /* set bit 19 to allow forcing of pcie core into L1 state */ 401 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 402 } 403 } 404 405 static int ar9002_hw_get_radiorev(struct ath_hw *ah) 406 { 407 u32 val; 408 int i; 409 410 ENABLE_REGWRITE_BUFFER(ah); 411 412 REG_WRITE(ah, AR_PHY(0x36), 0x00007058); 413 for (i = 0; i < 8; i++) 414 REG_WRITE(ah, AR_PHY(0x20), 0x00010000); 415 416 REGWRITE_BUFFER_FLUSH(ah); 417 418 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; 419 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); 420 421 return ath9k_hw_reverse_bits(val, 8); 422 } 423 424 int ar9002_hw_rf_claim(struct ath_hw *ah) 425 { 426 u32 val; 427 428 REG_WRITE(ah, AR_PHY(0), 0x00000007); 429 430 val = ar9002_hw_get_radiorev(ah); 431 switch (val & AR_RADIO_SREV_MAJOR) { 432 case 0: 433 val = AR_RAD5133_SREV_MAJOR; 434 break; 435 case AR_RAD5133_SREV_MAJOR: 436 case AR_RAD5122_SREV_MAJOR: 437 case AR_RAD2133_SREV_MAJOR: 438 case AR_RAD2122_SREV_MAJOR: 439 break; 440 default: 441 ath_err(ath9k_hw_common(ah), 442 "Radio Chip Rev 0x%02X not supported\n", 443 val & AR_RADIO_SREV_MAJOR); 444 return -EOPNOTSUPP; 445 } 446 447 ah->hw_version.analog5GhzRev = val; 448 449 return 0; 450 } 451 452 void ar9002_hw_enable_async_fifo(struct ath_hw *ah) 453 { 454 if (AR_SREV_9287_13_OR_LATER(ah)) { 455 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, 456 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); 457 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); 458 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, 459 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); 460 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, 461 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); 462 } 463 } 464 465 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ 466 void ar9002_hw_attach_ops(struct ath_hw *ah) 467 { 468 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 469 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 470 471 priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; 472 priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; 473 474 ops->config_pci_powersave = ar9002_hw_configpcipowersave; 475 476 ar5008_hw_attach_phy_ops(ah); 477 if (AR_SREV_9280_20_OR_LATER(ah)) 478 ar9002_hw_attach_phy_ops(ah); 479 480 ar9002_hw_attach_calib_ops(ah); 481 ar9002_hw_attach_mac_ops(ah); 482 } 483 484 void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan) 485 { 486 u32 modesIndex; 487 int i; 488 489 switch (chan->chanmode) { 490 case CHANNEL_A: 491 case CHANNEL_A_HT20: 492 modesIndex = 1; 493 break; 494 case CHANNEL_A_HT40PLUS: 495 case CHANNEL_A_HT40MINUS: 496 modesIndex = 2; 497 break; 498 case CHANNEL_G: 499 case CHANNEL_G_HT20: 500 case CHANNEL_B: 501 modesIndex = 4; 502 break; 503 case CHANNEL_G_HT40PLUS: 504 case CHANNEL_G_HT40MINUS: 505 modesIndex = 3; 506 break; 507 508 default: 509 return; 510 } 511 512 ENABLE_REGWRITE_BUFFER(ah); 513 514 for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) { 515 u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0); 516 u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex); 517 u32 val_orig; 518 519 if (reg == AR_PHY_CCK_DETECT) { 520 val_orig = REG_READ(ah, reg); 521 val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; 522 val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK; 523 524 REG_WRITE(ah, reg, val|val_orig); 525 } else 526 REG_WRITE(ah, reg, val); 527 } 528 529 REGWRITE_BUFFER_FLUSH(ah); 530 } 531