3 @@ -1014,9 +1014,7 @@ ath_attach(u_int16_t devid, struct net_d
5 sc->sc_hasveol = ath_hal_hasveol(ah);
7 - /* Interference mitigation/ambient noise immunity (ANI).
8 - * In modes other than HAL_M_STA, it causes receive sensitivity
9 - * problems for OFDM. */
10 + /* Interference mitigation/ambient noise immunity (ANI). */
11 sc->sc_hasintmit = ath_hal_hasintmit(ah);
13 /* get mac address from hardware */
14 @@ -1144,6 +1142,11 @@ ath_attach(u_int16_t devid, struct net_d
15 sc->sc_rp_lasttsf = 0;
18 + /* set all 3 to auto */
20 + sc->sc_noise_immunity = -1;
21 + sc->sc_ofdm_weak_det = -1;
25 ieee80211_ifdetach(ic);
26 @@ -2428,6 +2431,43 @@ ath_chan2flags(struct ieee80211_channel
30 +static int ath_setintmit(struct ath_softc *sc)
32 + struct ath_hal *ah = sc->sc_ah;
36 + if (!sc->sc_hasintmit)
39 + switch(sc->sc_intmit) {
41 + if (sc->sc_opmode != IEEE80211_M_MONITOR)
46 + case 0: /* disabled */
47 + case 1: /* enabled */
48 + val = sc->sc_intmit;
53 + ret = ath_hal_setintmit(ah, val);
57 + /* manual settings */
58 + if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5))
59 + ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL);
60 + if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1))
61 + ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL);
68 * Context: process context
70 @@ -2493,8 +2533,7 @@ ath_init(struct net_device *dev)
72 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
74 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
75 - ath_hal_setintmit(ah, 0);
79 * This is needed only to setup initial state
80 @@ -2530,7 +2569,7 @@ ath_init(struct net_device *dev)
81 * Enable MIB interrupts when there are hardware phy counters.
82 * Note we only do this (at the moment) for station mode.
84 - if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA)
85 + if (sc->sc_needmib && ath_hal_getintmit(ah, NULL))
86 sc->sc_imask |= HAL_INT_MIB;
87 ath_hal_intrset(ah, sc->sc_imask);
89 @@ -2787,9 +2826,7 @@ ath_reset(struct net_device *dev)
90 EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
91 ath_get_hal_status_desc(status), status);
93 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
94 - ath_hal_setintmit(ah, 0);
97 ath_update_txpow(sc); /* update tx power state */
99 ath_setdefantenna(sc, sc->sc_defant);
100 @@ -4174,6 +4211,8 @@ ath_calcrxfilter(struct ath_softc *sc)
101 if (sc->sc_nmonvaps > 0)
102 rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
103 HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
104 + if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
105 + rfilt |= HAL_RX_FILTER_PHYERR;
106 if (sc->sc_curchan.privFlags & CHANNEL_DFS)
107 rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
109 @@ -6526,9 +6565,6 @@ process_rx_again:
112 len = rs->rs_datalen;
113 - /* DMA sync. dies spectacularly if len == 0 */
119 @@ -8876,9 +8912,7 @@ ath_chan_set(struct ath_softc *sc, struc
121 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
123 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
124 - ath_hal_setintmit(ah, 0);
127 sc->sc_curchan = hchan;
128 ath_update_txpow(sc); /* update tx power state */
129 ath_radar_update(sc);
130 @@ -10655,9 +10689,54 @@ enum {
132 ATH_RADAR_IGNORED = 25,
135 + ATH_NOISE_IMMUNITY = 28,
136 + ATH_OFDM_WEAK_DET = 29
140 +ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
146 + sc->sc_intmit = val;
148 + case ATH_NOISE_IMMUNITY:
149 + sc->sc_noise_immunity = val;
151 + case ATH_OFDM_WEAK_DET:
152 + sc->sc_ofdm_weak_det = val;
157 + ret = ath_setintmit(sc);
158 + ath_calcrxfilter(sc);
163 +ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val)
165 + struct ath_hal *ah = sc->sc_ah;
169 + *val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK);
171 + case ATH_NOISE_IMMUNITY:
172 + return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val);
173 + case ATH_OFDM_WEAK_DET:
174 + return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val);
182 ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
184 struct ath_softc *sc = ctl->extra1;
185 @@ -10843,6 +10922,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
186 case ATH_RADAR_IGNORED:
187 sc->sc_radar_ignored = val;
190 + case ATH_NOISE_IMMUNITY:
191 + case ATH_OFDM_WEAK_DET:
192 + ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
197 @@ -10909,6 +10993,11 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
198 case ATH_RADAR_IGNORED:
199 val = sc->sc_radar_ignored;
202 + case ATH_NOISE_IMMUNITY:
203 + case ATH_OFDM_WEAK_DET:
204 + ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
209 @@ -11086,6 +11175,24 @@ static const ctl_table ath_sysctl_templa
210 .proc_handler = ath_sysctl_halparam,
211 .extra2 = (void *)ATH_RADAR_IGNORED,
213 + { .ctl_name = CTL_AUTO,
214 + .procname = "intmit",
216 + .proc_handler = ath_sysctl_halparam,
217 + .extra2 = (void *)ATH_INTMIT,
219 + { .ctl_name = CTL_AUTO,
220 + .procname = "noise_immunity",
222 + .proc_handler = ath_sysctl_halparam,
223 + .extra2 = (void *)ATH_NOISE_IMMUNITY,
225 + { .ctl_name = CTL_AUTO,
226 + .procname = "ofdm_weak_det",
228 + .proc_handler = ath_sysctl_halparam,
229 + .extra2 = (void *)ATH_OFDM_WEAK_DET,
234 --- a/ath/if_athvar.h
235 +++ b/ath/if_athvar.h
236 @@ -693,6 +693,10 @@ struct ath_softc {
237 unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
238 unsigned int sc_txcont_rate; /* Continuous transmit rate in Mbps */
240 + int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */
241 + int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */
242 + int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
245 const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
246 const HAL_RATE_TABLE *sc_currates; /* current rate table */
247 --- a/ath/if_ath_hal.h
248 +++ b/ath/if_ath_hal.h
249 @@ -67,14 +67,14 @@ static inline HAL_POWER_MODE ath_hal_get
251 static inline HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request,
252 const void *args, u_int32_t argsize,
255 u_int32_t *resultsize)
258 ATH_HAL_LOCK_IRQ(ah->ah_sc);
259 ath_hal_set_function(__func__);
261 - ah->ah_getDiagState(ah, request, args, argsize, *result,
262 + ah->ah_getDiagState(ah, request, args, argsize, result,
264 ath_hal_set_function(NULL);
265 ATH_HAL_UNLOCK_IRQ(ah->ah_sc);