diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9002_hw.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/reg.h | 3 |
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 |