aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ar9002_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9002_hw.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c109
1 files changed, 75 insertions, 34 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index a8a8cdc04af..7ba9dd68cc0 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -18,6 +18,7 @@
18#include "ar5008_initvals.h" 18#include "ar5008_initvals.h"
19#include "ar9001_initvals.h" 19#include "ar9001_initvals.h"
20#include "ar9002_initvals.h" 20#include "ar9002_initvals.h"
21#include "ar9002_phy.h"
21 22
22/* General hardware code for the A5008/AR9001/AR9002 hadware families */ 23/* General hardware code for the A5008/AR9001/AR9002 hadware families */
23 24
@@ -436,55 +437,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
436 } 437 }
437 438
438 udelay(1000); 439 udelay(1000);
440 }
439 441
440 /* set bit 19 to allow forcing of pcie core into L1 state */ 442 if (power_off) {
441 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 443 /* clear bit 19 to disable L1 */
444 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
442 445
443 /* Several PCIe massages to ensure proper behaviour */ 446 val = REG_READ(ah, AR_WA);
447
448 /*
449 * Set PCIe workaround bits
450 * In AR9280 and AR9285, bit 14 in WA register (disable L1)
451 * should only be set when device enters D3 and be
452 * cleared when device comes back to D0.
453 */
454 if (ah->config.pcie_waen) {
455 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
456 val |= AR_WA_D3_L1_DISABLE;
457 } else {
458 if (((AR_SREV_9285(ah) ||
459 AR_SREV_9271(ah) ||
460 AR_SREV_9287(ah)) &&
461 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
462 (AR_SREV_9280(ah) &&
463 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
464 val |= AR_WA_D3_L1_DISABLE;
465 }
466 }
467
468 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
469 /*
470 * Disable bit 6 and 7 before entering D3 to
471 * prevent system hang.
472 */
473 val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
474 }
475
476 if (AR_SREV_9285E_20(ah))
477 val |= AR_WA_BIT23;
478
479 REG_WRITE(ah, AR_WA, val);
480 } else {
444 if (ah->config.pcie_waen) { 481 if (ah->config.pcie_waen) {
445 val = ah->config.pcie_waen; 482 val = ah->config.pcie_waen;
446 if (!power_off) 483 if (!power_off)
447 val &= (~AR_WA_D3_L1_DISABLE); 484 val &= (~AR_WA_D3_L1_DISABLE);
448 } else { 485 } else {
449 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || 486 if (AR_SREV_9285(ah) ||
487 AR_SREV_9271(ah) ||
450 AR_SREV_9287(ah)) { 488 AR_SREV_9287(ah)) {
451 val = AR9285_WA_DEFAULT; 489 val = AR9285_WA_DEFAULT;
452 if (!power_off) 490 if (!power_off)
453 val &= (~AR_WA_D3_L1_DISABLE); 491 val &= (~AR_WA_D3_L1_DISABLE);
454 } else if (AR_SREV_9280(ah)) { 492 }
493 else if (AR_SREV_9280(ah)) {
455 /* 494 /*
456 * On AR9280 chips bit 22 of 0x4004 needs to be 495 * For AR9280 chips, bit 22 of 0x4004
457 * set otherwise card may disappear. 496 * needs to be set.
458 */ 497 */
459 val = AR9280_WA_DEFAULT; 498 val = AR9280_WA_DEFAULT;
460 if (!power_off) 499 if (!power_off)
461 val &= (~AR_WA_D3_L1_DISABLE); 500 val &= (~AR_WA_D3_L1_DISABLE);
462 } else 501 } else {
463 val = AR_WA_DEFAULT; 502 val = AR_WA_DEFAULT;
503 }
504 }
505
506 /* WAR for ASPM system hang */
507 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
508 val |= (AR_WA_BIT6 | AR_WA_BIT7);
464 } 509 }
465 510
511 if (AR_SREV_9285E_20(ah))
512 val |= AR_WA_BIT23;
513
466 REG_WRITE(ah, AR_WA, val); 514 REG_WRITE(ah, AR_WA, val);
467 }
468 515
469 if (power_off) { 516 /* set bit 19 to allow forcing of pcie core into L1 state */
470 /* 517 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
471 * Set PCIe workaround bits
472 * bit 14 in WA register (disable L1) should only
473 * be set when device enters D3 and be cleared
474 * when device comes back to D0.
475 */
476 if (ah->config.pcie_waen) {
477 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
478 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
479 } else {
480 if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
481 AR_SREV_9287(ah)) &&
482 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
483 (AR_SREV_9280(ah) &&
484 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
485 REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
486 }
487 }
488 } 518 }
489} 519}
490 520
@@ -536,18 +566,29 @@ int ar9002_hw_rf_claim(struct ath_hw *ah)
536 return 0; 566 return 0;
537} 567}
538 568
569void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
570{
571 if (AR_SREV_9287_13_OR_LATER(ah)) {
572 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
573 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
574 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
575 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
576 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
577 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
578 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
579 }
580}
581
539/* 582/*
540 * Enable ASYNC FIFO
541 *
542 * If Async FIFO is enabled, the following counters change as MAC now runs 583 * If Async FIFO is enabled, the following counters change as MAC now runs
543 * at 117 Mhz instead of 88/44MHz when async FIFO is disabled. 584 * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
544 * 585 *
545 * The values below tested for ht40 2 chain. 586 * The values below tested for ht40 2 chain.
546 * Overwrite the delay/timeouts initialized in process ini. 587 * Overwrite the delay/timeouts initialized in process ini.
547 */ 588 */
548void ar9002_hw_enable_async_fifo(struct ath_hw *ah) 589void ar9002_hw_update_async_fifo(struct ath_hw *ah)
549{ 590{
550 if (AR_SREV_9287_12_OR_LATER(ah)) { 591 if (AR_SREV_9287_13_OR_LATER(ah)) {
551 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 592 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
552 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); 593 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
553 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 594 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
@@ -571,9 +612,9 @@ void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
571 */ 612 */
572void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) 613void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
573{ 614{
574 if (AR_SREV_9287_12_OR_LATER(ah)) { 615 if (AR_SREV_9287_13_OR_LATER(ah)) {
575 REG_SET_BIT(ah, AR_PCU_MISC_MODE2, 616 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
576 AR_PCU_MISC_MODE2_ENABLE_AGGWEP); 617 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
577 } 618 }
578} 619}
579 620