diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9002_hw.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9002_hw.c | 109 |
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 | ||
569 | void 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 | */ |
548 | void ar9002_hw_enable_async_fifo(struct ath_hw *ah) | 589 | void 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 | */ |
572 | void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) | 613 | void 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 | ||