improve wds sta mode compatibility
[openwrt/openwrt.git] / package / madwifi / patches / 352-ani_fix.patch
1 --- a/ath/if_ath.c
2 +++ b/ath/if_ath.c
3 @@ -1014,9 +1014,7 @@
4 */
5 sc->sc_hasveol = ath_hal_hasveol(ah);
6
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);
12
13 /* get mac address from hardware */
14 @@ -1144,6 +1142,11 @@
15 sc->sc_rp_lasttsf = 0;
16 sc->sc_last_tsf = 0;
17
18 + /* set all 3 to auto */
19 + sc->sc_intmit = -1;
20 + sc->sc_noise_immunity = -1;
21 + sc->sc_ofdm_weak_det = -1;
22 +
23 return 0;
24 bad3:
25 ieee80211_ifdetach(ic);
26 @@ -2351,16 +2354,6 @@
27 }
28 if (status & HAL_INT_MIB) {
29 sc->sc_stats.ast_mib++;
30 - /* When the card receives lots of PHY errors, the MIB
31 - * interrupt will fire at a very rapid rate. We will use
32 - * a timer to enforce at least 1 jiffy delay between
33 - * MIB interrupts. This should be unproblematic, since
34 - * the hardware will continue to update the counters in
35 - * the mean time. */
36 - sc->sc_imask &= ~HAL_INT_MIB;
37 - ath_hal_intrset(ah, sc->sc_imask);
38 - mod_timer(&sc->sc_mib_enable, jiffies + 1);
39 -
40 /* Let the HAL handle the event. */
41 ath_hal_mibevent(ah, &sc->sc_halstats);
42 }
43 @@ -2430,6 +2423,43 @@
44 return flags;
45 }
46
47 +static int ath_setintmit(struct ath_softc *sc)
48 +{
49 + struct ath_hal *ah = sc->sc_ah;
50 + int ret;
51 + int val;
52 +
53 + if (!sc->sc_hasintmit)
54 + return 0;
55 +
56 + switch(sc->sc_intmit) {
57 + case -1:
58 + if (sc->sc_opmode != IEEE80211_M_MONITOR)
59 + val = 1;
60 + else
61 + val = 0;
62 + break;
63 + case 0: /* disabled */
64 + case 1: /* enabled */
65 + val = sc->sc_intmit;
66 + break;
67 + default:
68 + return 0;
69 + }
70 + ret = ath_hal_setintmit(ah, val);
71 + if (val)
72 + goto done;
73 +
74 + /* manual settings */
75 + if ((sc->sc_noise_immunity >= 0) && (sc->sc_noise_immunity <= 5))
76 + ath_hal_setcapability(ah, HAL_CAP_INTMIT, 2, sc->sc_noise_immunity, NULL);
77 + if ((sc->sc_ofdm_weak_det == 0) || (sc->sc_ofdm_weak_det == 1))
78 + ath_hal_setcapability(ah, HAL_CAP_INTMIT, 3, sc->sc_ofdm_weak_det, NULL);
79 +
80 +done:
81 + return ret;
82 +}
83 +
84 /*
85 * Context: process context
86 */
87 @@ -2495,8 +2525,7 @@
88 if (sc->sc_softled)
89 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
90
91 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
92 - ath_hal_setintmit(ah, 0);
93 + ath_setintmit(sc);
94
95 /*
96 * This is needed only to setup initial state
97 @@ -2532,7 +2561,7 @@
98 * Enable MIB interrupts when there are hardware phy counters.
99 * Note we only do this (at the moment) for station mode.
100 */
101 - if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA)
102 + if (sc->sc_needmib && ath_hal_getintmit(ah, NULL))
103 sc->sc_imask |= HAL_INT_MIB;
104 ath_hal_intrset(ah, sc->sc_imask);
105
106 @@ -2789,9 +2818,7 @@
107 EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
108 ath_get_hal_status_desc(status), status);
109
110 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
111 - ath_hal_setintmit(ah, 0);
112 -
113 + ath_setintmit(sc);
114 ath_update_txpow(sc); /* update tx power state */
115 ath_radar_update(sc);
116 ath_setdefantenna(sc, sc->sc_defant);
117 @@ -4176,6 +4203,8 @@
118 if (sc->sc_nmonvaps > 0)
119 rfilt |= (HAL_RX_FILTER_CONTROL | HAL_RX_FILTER_BEACON |
120 HAL_RX_FILTER_PROBEREQ | HAL_RX_FILTER_PROM);
121 + if (sc->sc_hasintmit && !sc->sc_needmib && ath_hal_getintmit(ah, NULL))
122 + rfilt |= HAL_RX_FILTER_PHYERR;
123 if (sc->sc_curchan.privFlags & CHANNEL_DFS)
124 rfilt |= (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR);
125 return rfilt;
126 @@ -6526,9 +6555,6 @@
127 rs->rs_rssi = 0;
128
129 len = rs->rs_datalen;
130 - /* DMA sync. dies spectacularly if len == 0 */
131 - if (len == 0)
132 - goto rx_next;
133
134 if (rs->rs_more) {
135 /*
136 @@ -8880,9 +8906,7 @@
137 if (sc->sc_softled)
138 ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
139
140 - if ((sc->sc_opmode != HAL_M_STA) && sc->sc_hasintmit)
141 - ath_hal_setintmit(ah, 0);
142 -
143 + ath_setintmit(sc);
144 sc->sc_curchan = hchan;
145 ath_update_txpow(sc); /* update tx power state */
146 ath_radar_update(sc);
147 @@ -10659,9 +10683,54 @@
148 ATH_RP_IGNORED = 24,
149 ATH_RADAR_IGNORED = 25,
150 ATH_MAXVAPS = 26,
151 + ATH_INTMIT = 27,
152 + ATH_NOISE_IMMUNITY = 28,
153 + ATH_OFDM_WEAK_DET = 29
154 };
155
156 static int
157 +ath_sysctl_set_intmit(struct ath_softc *sc, long ctl, u_int val)
158 +{
159 + int ret;
160 +
161 + switch(ctl) {
162 + case ATH_INTMIT:
163 + sc->sc_intmit = val;
164 + break;
165 + case ATH_NOISE_IMMUNITY:
166 + sc->sc_noise_immunity = val;
167 + break;
168 + case ATH_OFDM_WEAK_DET:
169 + sc->sc_ofdm_weak_det = val;
170 + break;
171 + default:
172 + return -EINVAL;
173 + }
174 + ret = ath_setintmit(sc);
175 + ath_calcrxfilter(sc);
176 + return ret;
177 +}
178 +
179 +static int
180 +ath_sysctl_get_intmit(struct ath_softc *sc, long ctl, u_int *val)
181 +{
182 + struct ath_hal *ah = sc->sc_ah;
183 +
184 + switch(ctl) {
185 + case ATH_INTMIT:
186 + *val = (ath_hal_getcapability(ah, HAL_CAP_INTMIT, 1, NULL) == HAL_OK);
187 + break;
188 + case ATH_NOISE_IMMUNITY:
189 + return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 2, val);
190 + case ATH_OFDM_WEAK_DET:
191 + return ath_hal_getcapability(ah, HAL_CAP_INTMIT, 3, val);
192 + default:
193 + return -EINVAL;
194 + }
195 + return 0;
196 +}
197 +
198 +static int
199 ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl, write, filp, buffer, lenp, ppos)
200 {
201 struct ath_softc *sc = ctl->extra1;
202 @@ -10847,6 +10916,11 @@
203 case ATH_RADAR_IGNORED:
204 sc->sc_radar_ignored = val;
205 break;
206 + case ATH_INTMIT:
207 + case ATH_NOISE_IMMUNITY:
208 + case ATH_OFDM_WEAK_DET:
209 + ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
210 + break;
211 default:
212 ret = -EINVAL;
213 break;
214 @@ -10913,6 +10987,11 @@
215 case ATH_RADAR_IGNORED:
216 val = sc->sc_radar_ignored;
217 break;
218 + case ATH_INTMIT:
219 + case ATH_NOISE_IMMUNITY:
220 + case ATH_OFDM_WEAK_DET:
221 + ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
222 + break;
223 default:
224 ret = -EINVAL;
225 break;
226 @@ -11090,6 +11169,24 @@
227 .proc_handler = ath_sysctl_halparam,
228 .extra2 = (void *)ATH_RADAR_IGNORED,
229 },
230 + { .ctl_name = CTL_AUTO,
231 + .procname = "intmit",
232 + .mode = 0644,
233 + .proc_handler = ath_sysctl_halparam,
234 + .extra2 = (void *)ATH_INTMIT,
235 + },
236 + { .ctl_name = CTL_AUTO,
237 + .procname = "noise_immunity",
238 + .mode = 0644,
239 + .proc_handler = ath_sysctl_halparam,
240 + .extra2 = (void *)ATH_NOISE_IMMUNITY,
241 + },
242 + { .ctl_name = CTL_AUTO,
243 + .procname = "ofdm_weak_det",
244 + .mode = 0644,
245 + .proc_handler = ath_sysctl_halparam,
246 + .extra2 = (void *)ATH_OFDM_WEAK_DET,
247 + },
248 { 0 }
249 };
250
251 --- a/ath/if_athvar.h
252 +++ b/ath/if_athvar.h
253 @@ -693,6 +693,10 @@
254 unsigned int sc_txcont_power; /* Continuous transmit power in 0.5dBm units */
255 unsigned int sc_txcont_rate; /* Continuous transmit rate in Mbps */
256
257 + int8_t sc_intmit; /* Interference mitigation enabled, -1 = auto, based on mode, 0/1 = off/on */
258 + int8_t sc_noise_immunity; /* Noise immunity level, 0-4, -1 == auto) */
259 + int8_t sc_ofdm_weak_det; /* OFDM weak frames detection, -1 == auto */
260 +
261 /* rate tables */
262 const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
263 const HAL_RATE_TABLE *sc_currates; /* current rate table */
264 --- a/ath/if_ath_hal.h
265 +++ b/ath/if_ath_hal.h
266 @@ -67,14 +67,14 @@
267
268 static inline HAL_BOOL ath_hal_getdiagstate(struct ath_hal *ah, int request,
269 const void *args, u_int32_t argsize,
270 - void **result,
271 + void *result,
272 u_int32_t *resultsize)
273 {
274 HAL_BOOL ret;
275 ATH_HAL_LOCK_IRQ(ah->ah_sc);
276 ath_hal_set_function(__func__);
277 ret =
278 - ah->ah_getDiagState(ah, request, args, argsize, *result,
279 + ah->ah_getDiagState(ah, request, args, argsize, result,
280 resultsize);
281 ath_hal_set_function(NULL);
282 ATH_HAL_UNLOCK_IRQ(ah->ah_sc);