326-ath9k-make-NF-load-complete-quickly-and-reliably.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. From: Miaoqing Pan <miaoqing@codeaurora.org>
  2. Date: Fri, 5 Feb 2016 09:45:50 +0800
  3. Subject: [PATCH] ath9k: make NF load complete quickly and reliably
  4. Make NF load complete quickly and reliably. NF load execution
  5. is delayed by HW to end of frame if frame Rx or Tx is ongoing.
  6. Increasing timeout to max frame duration. If NF cal is ongoing
  7. before NF load, stop it before load, and restart it afterwards.
  8. Signed-off-by: Miaoqing Pan <miaoqing@codeaurora.org>
  9. ---
  10. --- a/drivers/net/wireless/ath/ath9k/calib.c
  11. +++ b/drivers/net/wireless/ath/ath9k/calib.c
  12. @@ -241,6 +241,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
  13. u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
  14. struct ath_common *common = ath9k_hw_common(ah);
  15. s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
  16. + u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL);
  17. if (ah->caldata)
  18. h = ah->caldata->nfCalHist;
  19. @@ -264,6 +265,16 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
  20. }
  21. /*
  22. + * stop NF cal if ongoing to ensure NF load completes immediately
  23. + * (or after end rx/tx frame if ongoing)
  24. + */
  25. + if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
  26. + REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
  27. + REG_RMW_BUFFER_FLUSH(ah);
  28. + ENABLE_REG_RMW_BUFFER(ah);
  29. + }
  30. +
  31. + /*
  32. * Load software filtered NF value into baseband internal minCCApwr
  33. * variable.
  34. */
  35. @@ -276,18 +287,33 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
  36. /*
  37. * Wait for load to complete, should be fast, a few 10s of us.
  38. - * The max delay was changed from an original 250us to 10000us
  39. - * since 250us often results in NF load timeout and causes deaf
  40. - * condition during stress testing 12/12/2009
  41. + * The max delay was changed from an original 250us to 22.2 msec.
  42. + * This would increase timeout to the longest possible frame
  43. + * (11n max length 22.1 msec)
  44. */
  45. - for (j = 0; j < 10000; j++) {
  46. + for (j = 0; j < 22200; j++) {
  47. if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
  48. - AR_PHY_AGC_CONTROL_NF) == 0)
  49. + AR_PHY_AGC_CONTROL_NF) == 0)
  50. break;
  51. udelay(10);
  52. }
  53. /*
  54. + * Restart NF so it can continue.
  55. + */
  56. + if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
  57. + ENABLE_REG_RMW_BUFFER(ah);
  58. + if (bb_agc_ctl & AR_PHY_AGC_CONTROL_ENABLE_NF)
  59. + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
  60. + AR_PHY_AGC_CONTROL_ENABLE_NF);
  61. + if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NO_UPDATE_NF)
  62. + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
  63. + AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
  64. + REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
  65. + REG_RMW_BUFFER_FLUSH(ah);
  66. + }
  67. +
  68. + /*
  69. * We timed out waiting for the noisefloor to load, probably due to an
  70. * in-progress rx. Simply return here and allow the load plenty of time
  71. * to complete before the next calibration interval. We need to avoid
  72. @@ -296,7 +322,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s
  73. * here, the baseband nf cal will just be capped by our present
  74. * noisefloor until the next calibration timer.
  75. */
  76. - if (j == 10000) {
  77. + if (j == 22200) {
  78. ath_dbg(common, ANY,
  79. "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
  80. REG_READ(ah, AR_PHY_AGC_CONTROL));