refresh some madwifi patches
[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 @@ -2347,16 +2350,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 @@ -2426,6 +2419,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 @@ -2491,8 +2521,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 @@ -2528,7 +2557,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 @@ -2785,9 +2814,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 @@ -4165,6 +4192,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 @@ -6513,9 +6542,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 @@ -8865,9 +8891,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 @@ -10644,9 +10668,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 @@ -10832,6 +10901,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 @@ -10898,6 +10972,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 @@ -11075,6 +11154,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);