3 @@ -383,6 +383,8 @@ static void ath_poll_disable(struct net_
4 static void ath_poll_enable(struct net_device *dev);
5 static void ath_fetch_idle_time(struct ath_softc *sc);
6 static void ath_set_timing(struct ath_softc *sc);
7 +static void ath_update_cca_thresh(struct ath_softc *sc);
8 +static int ath_hw_read_nf(struct ath_softc *sc);
10 /* calibrate every 30 secs in steady state but check every second at first. */
11 static int ath_calinterval = ATH_SHORT_CALINTERVAL;
12 @@ -2623,6 +2625,10 @@ ath_init(struct net_device *dev)
16 + ath_hal_process_noisefloor(ah);
17 + ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
18 + ath_update_cca_thresh(sc);
21 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
23 @@ -3024,6 +3030,10 @@ ath_reset(struct net_device *dev)
24 EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
25 ath_get_hal_status_desc(status), status);
27 + ath_hal_process_noisefloor(ah);
28 + ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
29 + ath_update_cca_thresh(sc);
32 ath_update_txpow(sc); /* update tx power state */
34 @@ -9374,9 +9384,11 @@ ath_calibrate(unsigned long arg)
35 sc->sc_curchan.channel);
36 sc->sc_stats.ast_per_calfail++;
38 - ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
40 ath_hal_process_noisefloor(ah);
41 + ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
42 + ath_update_cca_thresh(sc);
44 if (isIQdone == AH_TRUE) {
45 /* Unless user has overridden calibration interval,
46 * upgrade to less frequent calibration */
47 @@ -9711,8 +9723,6 @@ ath_newstate(struct ieee80211vap *vap, e
51 - ath_hal_process_noisefloor(ah);
52 - ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
54 * Reset rssi stats; maybe not the best place...
56 @@ -10968,6 +10978,7 @@ enum {
64 @@ -11110,6 +11121,66 @@ ath_sysctl_get_intmit(struct ath_softc *
68 +#define AR_PHY_CCA 0x9864
69 +#define AR_PHY_MINCCA_PWR 0x0FF80000
70 +#define AR_PHY_MINCCA_PWR_S 19
71 +#define AR_PHY_CCA_THRESH62 0x0007F000
72 +#define AR_PHY_CCA_THRESH62_S 12
75 +ath_nf_from_cca(u32 phy_cca)
77 + int nf = (phy_cca >> 19) & 0x1ff;
78 + nf = -((nf ^ 0x1ff) + 1);
83 +ath_hw_read_nf(struct ath_softc *sc)
85 + return ath_nf_from_cca(OS_REG_READ(sc->sc_ah, AR_PHY_CCA));
89 +ath_update_cca_thresh(struct ath_softc *sc)
91 + struct ath_hal *ah = sc->sc_ah;
96 + phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
97 + if (sc->sc_cca_thresh < 0) {
98 + newthr = sc->sc_cca_thresh - ath_nf_from_cca(phy_cca);
100 + /* 0xf is a typical eeprom value for thresh62,
101 + * use it as minimum for signal based thresholds
102 + * to prevent complete connection drops */
106 + newthr = sc->sc_cca_thresh;
109 + if ((newthr < 4) || (newthr >= 127))
112 + phy_cca &= ~AR_PHY_CCA_THRESH62;
113 + phy_cca |= newthr << AR_PHY_CCA_THRESH62_S;
114 + OS_REG_WRITE(ah, AR_PHY_CCA, phy_cca);
118 +ath_get_cca_thresh(struct ath_softc *sc)
120 + struct ath_hal *ah = sc->sc_ah;
123 + phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
124 + return ath_nf_from_cca(phy_cca) +
125 + ((phy_cca & AR_PHY_CCA_THRESH62) >> AR_PHY_CCA_THRESH62_S);
129 ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
131 @@ -11356,6 +11427,10 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
132 case ATH_OFDM_WEAK_DET:
133 ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
135 + case ATH_CCA_THRESH:
136 + sc->sc_cca_thresh = val;
137 + ath_update_cca_thresh(sc);
142 @@ -11436,6 +11511,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
143 case ATH_OFDM_WEAK_DET:
144 ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
146 + case ATH_CCA_THRESH:
147 + val = ath_get_cca_thresh(sc);
152 @@ -11667,6 +11745,12 @@ static const ctl_table ath_sysctl_templa
153 .proc_handler = ath_sysctl_halparam,
154 .extra2 = (void *)ATH_OFDM_WEAK_DET,
156 + { .ctl_name = CTL_AUTO,
157 + .procname = "cca_thresh",
159 + .proc_handler = ath_sysctl_halparam,
160 + .extra2 = (void *)ATH_CCA_THRESH,
165 --- a/ath/if_athvar.h
166 +++ b/ath/if_athvar.h
167 @@ -844,6 +844,7 @@ struct ath_softc {
168 int sc_cal_interval; /* current calibration interval */
169 struct timer_list sc_cal_ch; /* calibration timer */
170 HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
171 + int sc_cca_thresh; /* configured CCA threshold */
173 struct ctl_table_header *sc_sysctl_header;
174 struct ctl_table *sc_sysctls;
175 --- a/ath/ath_wprobe.c
176 +++ b/ath/ath_wprobe.c
177 @@ -133,8 +133,7 @@ ath_wprobe_sync(struct wprobe_iface *dev
178 rx = READ_CLR(ah, AR5K_RXFC);
179 tx = READ_CLR(ah, AR5K_TXFC);
180 OS_REG_WRITE(ah, AR5K_MIBC, 0);
181 - noise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
182 - ic->ic_channoise = noise;
183 + noise = ath_hw_read_nf(sc);
185 WPROBE_FILL_BEGIN(val, ath_wprobe_globals);
186 if (cc & 0xf0000000) {