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