301-ath9k_hw-issue-external-reset-for-QCA955x.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. From: Felix Fietkau <nbd@nbd.name>
  2. Date: Sat, 9 Jul 2016 15:26:44 +0200
  3. Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
  4. The RTC interface on the SoC needs to be reset along with the rest of
  5. the WMAC.
  6. Signed-off-by: Felix Fietkau <nbd@nbd.name>
  7. ---
  8. --- a/drivers/net/wireless/ath/ath9k/hw.c
  9. +++ b/drivers/net/wireless/ath/ath9k/hw.c
  10. @@ -1271,39 +1271,56 @@ void ath9k_hw_get_delta_slope_vals(struc
  11. *coef_exponent = coef_exp - 16;
  12. }
  13. -/* AR9330 WAR:
  14. - * call external reset function to reset WMAC if:
  15. - * - doing a cold reset
  16. - * - we have pending frames in the TX queues.
  17. - */
  18. -static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
  19. +static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
  20. {
  21. - int i, npend = 0;
  22. + int i;
  23. - for (i = 0; i < AR_NUM_QCU; i++) {
  24. - npend = ath9k_hw_numtxpending(ah, i);
  25. - if (npend)
  26. - break;
  27. - }
  28. -
  29. - if (ah->external_reset &&
  30. - (npend || type == ATH9K_RESET_COLD)) {
  31. - int reset_err = 0;
  32. -
  33. - ath_dbg(ath9k_hw_common(ah), RESET,
  34. - "reset MAC via external reset\n");
  35. -
  36. - reset_err = ah->external_reset();
  37. - if (reset_err) {
  38. - ath_err(ath9k_hw_common(ah),
  39. - "External reset failed, err=%d\n",
  40. - reset_err);
  41. - return false;
  42. + if (type == ATH9K_RESET_COLD)
  43. + return true;
  44. +
  45. + if (AR_SREV_9550(ah))
  46. + return true;
  47. +
  48. + /* AR9330 WAR:
  49. + * call external reset function to reset WMAC if:
  50. + * - doing a cold reset
  51. + * - we have pending frames in the TX queues.
  52. + */
  53. + if (AR_SREV_9330(ah)) {
  54. + for (i = 0; i < AR_NUM_QCU; i++) {
  55. + if (ath9k_hw_numtxpending(ah, i))
  56. + return true;
  57. }
  58. + }
  59. +
  60. + return false;
  61. +}
  62. +
  63. +static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
  64. +{
  65. + int err;
  66. +
  67. + if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
  68. + return true;
  69. +
  70. + ath_dbg(ath9k_hw_common(ah), RESET,
  71. + "reset MAC via external reset\n");
  72. - REG_WRITE(ah, AR_RTC_RESET, 1);
  73. + err = ah->external_reset();
  74. + if (err) {
  75. + ath_err(ath9k_hw_common(ah),
  76. + "External reset failed, err=%d\n", err);
  77. + return false;
  78. }
  79. + if (AR_SREV_9550(ah)) {
  80. + REG_WRITE(ah, AR_RTC_RESET, 0);
  81. + udelay(10);
  82. + }
  83. +
  84. + REG_WRITE(ah, AR_RTC_RESET, 1);
  85. + udelay(10);
  86. +
  87. return true;
  88. }
  89. @@ -1356,24 +1373,24 @@ static bool ath9k_hw_set_reset(struct at
  90. rst_flags |= AR_RTC_RC_MAC_COLD;
  91. }
  92. - if (AR_SREV_9330(ah)) {
  93. - if (!ath9k_hw_ar9330_reset_war(ah, type))
  94. - return false;
  95. - }
  96. -
  97. if (ath9k_hw_mci_is_enabled(ah))
  98. ar9003_mci_check_gpm_offset(ah);
  99. /* DMA HALT added to resolve ar9300 and ar9580 bus error during
  100. - * RTC_RC reg read
  101. + * RTC_RC reg read. Also needed for AR9550 external reset
  102. */
  103. - if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
  104. + if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
  105. REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
  106. ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
  107. 20 * AH_WAIT_TIMEOUT);
  108. - REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
  109. }
  110. + if (!AR_SREV_9100(ah))
  111. + ath9k_hw_external_reset(ah, type);
  112. +
  113. + if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
  114. + REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
  115. +
  116. REG_WRITE(ah, AR_RTC_RC, rst_flags);
  117. REGWRITE_BUFFER_FLUSH(ah);