aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_hw.c85
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h3
2 files changed, 60 insertions, 28 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
index a8a8cdc04afa..748449cd5872 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c
@@ -436,55 +436,84 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
436 } 436 }
437 437
438 udelay(1000); 438 udelay(1000);
439 }
439 440
440 /* set bit 19 to allow forcing of pcie core into L1 state */ 441 if (power_off) {
441 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); 442 /* clear bit 19 to disable L1 */
443 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
444
445 val = REG_READ(ah, AR_WA);
442 446
443 /* Several PCIe massages to ensure proper behaviour */ 447 /*
448 * Set PCIe workaround bits
449 * In AR9280 and AR9285, bit 14 in WA register (disable L1)
450 * should only be set when device enters D3 and be
451 * cleared when device comes back to D0.
452 */
453 if (ah->config.pcie_waen) {
454 if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
455 val |= AR_WA_D3_L1_DISABLE;
456 } else {
457 if (((AR_SREV_9285(ah) ||
458 AR_SREV_9271(ah) ||
459 AR_SREV_9287(ah)) &&
460 (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
461 (AR_SREV_9280(ah) &&
462 (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
463 val |= AR_WA_D3_L1_DISABLE;
464 }
465 }
466
467 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
468 /*
469 * Disable bit 6 and 7 before entering D3 to
470 * prevent system hang.
471 */
472 val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
473 }
474
475 if (AR_SREV_9285E_20(ah))
476 val |= AR_WA_BIT23;
477
478 REG_WRITE(ah, AR_WA, val);
479 } else {
444 if (ah->config.pcie_waen) { 480 if (ah->config.pcie_waen) {
445 val = ah->config.pcie_waen; 481 val = ah->config.pcie_waen;
446 if (!power_off) 482 if (!power_off)
447 val &= (~AR_WA_D3_L1_DISABLE); 483 val &= (~AR_WA_D3_L1_DISABLE);
448 } else { 484 } else {
449 if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || 485 if (AR_SREV_9285(ah) ||
486 AR_SREV_9271(ah) ||
450 AR_SREV_9287(ah)) { 487 AR_SREV_9287(ah)) {
451 val = AR9285_WA_DEFAULT; 488 val = AR9285_WA_DEFAULT;
452 if (!power_off) 489 if (!power_off)
453 val &= (~AR_WA_D3_L1_DISABLE); 490 val &= (~AR_WA_D3_L1_DISABLE);
454 } else if (AR_SREV_9280(ah)) { 491 }
492 else if (AR_SREV_9280(ah)) {
455 /* 493 /*
456 * On AR9280 chips bit 22 of 0x4004 needs to be 494 * For AR9280 chips, bit 22 of 0x4004
457 * set otherwise card may disappear. 495 * needs to be set.
458 */ 496 */
459 val = AR9280_WA_DEFAULT; 497 val = AR9280_WA_DEFAULT;
460 if (!power_off) 498 if (!power_off)
461 val &= (~AR_WA_D3_L1_DISABLE); 499 val &= (~AR_WA_D3_L1_DISABLE);
462 } else 500 } else {
463 val = AR_WA_DEFAULT; 501 val = AR_WA_DEFAULT;
502 }
503 }
504
505 /* WAR for ASPM system hang */
506 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
507 val |= (AR_WA_BIT6 | AR_WA_BIT7);
464 } 508 }
465 509
510 if (AR_SREV_9285E_20(ah))
511 val |= AR_WA_BIT23;
512
466 REG_WRITE(ah, AR_WA, val); 513 REG_WRITE(ah, AR_WA, val);
467 }
468 514
469 if (power_off) { 515 /* set bit 19 to allow forcing of pcie core into L1 state */
470 /* 516 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 } 517 }
489} 518}
490 519
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index c9a009fab221..a7371a080491 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -700,6 +700,9 @@
700#define AR_RC_HOSTIF 0x00000100 700#define AR_RC_HOSTIF 0x00000100
701 701
702#define AR_WA 0x4004 702#define AR_WA 0x4004
703#define AR_WA_BIT6 (1 << 6)
704#define AR_WA_BIT7 (1 << 7)
705#define AR_WA_BIT23 (1 << 23)
703#define AR_WA_D3_L1_DISABLE (1 << 14) 706#define AR_WA_D3_L1_DISABLE (1 << 14)
704#define AR9285_WA_DEFAULT 0x004a050b 707#define AR9285_WA_DEFAULT 0x004a050b
705#define AR9280_WA_DEFAULT 0x0040073b 708#define AR9280_WA_DEFAULT 0x0040073b