Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / net / wireless / rt2x00 / rt2x00link.c
1 /*
2         Copyright (C) 2004 - 2009 Ivo van Doorn <IvDoorn@gmail.com>
3         <http://rt2x00.serialmonkey.com>
4
5         This program is free software; you can redistribute it and/or modify
6         it under the terms of the GNU General Public License as published by
7         the Free Software Foundation; either version 2 of the License, or
8         (at your option) any later version.
9
10         This program is distributed in the hope that it will be useful,
11         but WITHOUT ANY WARRANTY; without even the implied warranty of
12         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13         GNU General Public License for more details.
14
15         You should have received a copy of the GNU General Public License
16         along with this program; if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 /*
20         Module: rt2x00lib
21         Abstract: rt2x00 generic link tuning routines.
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26
27 #include "rt2x00.h"
28 #include "rt2x00lib.h"
29
30 /*
31  * When we lack RSSI information return something less then -80 to
32  * tell the driver to tune the device to maximum sensitivity.
33  */
34 #define DEFAULT_RSSI            -128
35
36 /* Constants for EWMA calculations. */
37 #define RT2X00_EWMA_FACTOR      1024
38 #define RT2X00_EWMA_WEIGHT      8
39
40 static inline int rt2x00link_get_avg_rssi(struct ewma *ewma)
41 {
42         unsigned long avg;
43
44         avg = ewma_read(ewma);
45         if (avg)
46                 return -avg;
47
48         return DEFAULT_RSSI;
49 }
50
51 static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
52 {
53         struct link_ant *ant = &rt2x00dev->link.ant;
54
55         if (rt2x00dev->link.qual.rx_success)
56                 return rt2x00link_get_avg_rssi(&ant->rssi_ant);
57
58         return DEFAULT_RSSI;
59 }
60
61 static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev)
62 {
63         struct link_ant *ant = &rt2x00dev->link.ant;
64
65         if (ant->rssi_history)
66                 return ant->rssi_history;
67         return DEFAULT_RSSI;
68 }
69
70 static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
71                                                    int rssi)
72 {
73         struct link_ant *ant = &rt2x00dev->link.ant;
74         ant->rssi_history = rssi;
75 }
76
77 static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
78 {
79         ewma_init(&rt2x00dev->link.ant.rssi_ant, RT2X00_EWMA_FACTOR,
80                   RT2X00_EWMA_WEIGHT);
81 }
82
83 static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
84 {
85         struct link_ant *ant = &rt2x00dev->link.ant;
86         struct antenna_setup new_ant;
87         int other_antenna;
88
89         int sample_current = rt2x00link_antenna_get_link_rssi(rt2x00dev);
90         int sample_other = rt2x00link_antenna_get_rssi_history(rt2x00dev);
91
92         memcpy(&new_ant, &ant->active, sizeof(new_ant));
93
94         /*
95          * We are done sampling. Now we should evaluate the results.
96          */
97         ant->flags &= ~ANTENNA_MODE_SAMPLE;
98
99         /*
100          * During the last period we have sampled the RSSI
101          * from both antennas. It now is time to determine
102          * which antenna demonstrated the best performance.
103          * When we are already on the antenna with the best
104          * performance, just create a good starting point
105          * for the history and we are done.
106          */
107         if (sample_current >= sample_other) {
108                 rt2x00link_antenna_update_rssi_history(rt2x00dev,
109                         sample_current);
110                 return;
111         }
112
113         other_antenna = (ant->active.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
114
115         if (ant->flags & ANTENNA_RX_DIVERSITY)
116                 new_ant.rx = other_antenna;
117
118         if (ant->flags & ANTENNA_TX_DIVERSITY)
119                 new_ant.tx = other_antenna;
120
121         rt2x00lib_config_antenna(rt2x00dev, new_ant);
122 }
123
124 static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
125 {
126         struct link_ant *ant = &rt2x00dev->link.ant;
127         struct antenna_setup new_ant;
128         int rssi_curr;
129         int rssi_old;
130
131         memcpy(&new_ant, &ant->active, sizeof(new_ant));
132
133         /*
134          * Get current RSSI value along with the historical value,
135          * after that update the history with the current value.
136          */
137         rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
138         rssi_old = rt2x00link_antenna_get_rssi_history(rt2x00dev);
139         rt2x00link_antenna_update_rssi_history(rt2x00dev, rssi_curr);
140
141         /*
142          * Legacy driver indicates that we should swap antenna's
143          * when the difference in RSSI is greater that 5. This
144          * also should be done when the RSSI was actually better
145          * then the previous sample.
146          * When the difference exceeds the threshold we should
147          * sample the rssi from the other antenna to make a valid
148          * comparison between the 2 antennas.
149          */
150         if (abs(rssi_curr - rssi_old) < 5)
151                 return;
152
153         ant->flags |= ANTENNA_MODE_SAMPLE;
154
155         if (ant->flags & ANTENNA_RX_DIVERSITY)
156                 new_ant.rx = (new_ant.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
157
158         if (ant->flags & ANTENNA_TX_DIVERSITY)
159                 new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
160
161         rt2x00lib_config_antenna(rt2x00dev, new_ant);
162 }
163
164 static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
165 {
166         struct link_ant *ant = &rt2x00dev->link.ant;
167
168         /*
169          * Determine if software diversity is enabled for
170          * either the TX or RX antenna (or both).
171          */
172         if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
173             !(ant->flags & ANTENNA_TX_DIVERSITY)) {
174                 ant->flags = 0;
175                 return true;
176         }
177
178         /*
179          * If we have only sampled the data over the last period
180          * we should now harvest the data. Otherwise just evaluate
181          * the data. The latter should only be performed once
182          * every 2 seconds.
183          */
184         if (ant->flags & ANTENNA_MODE_SAMPLE) {
185                 rt2x00lib_antenna_diversity_sample(rt2x00dev);
186                 return true;
187         } else if (rt2x00dev->link.count & 1) {
188                 rt2x00lib_antenna_diversity_eval(rt2x00dev);
189                 return true;
190         }
191
192         return false;
193 }
194
195 void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
196                              struct sk_buff *skb,
197                              struct rxdone_entry_desc *rxdesc)
198 {
199         struct link *link = &rt2x00dev->link;
200         struct link_qual *qual = &rt2x00dev->link.qual;
201         struct link_ant *ant = &rt2x00dev->link.ant;
202         struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
203
204         /*
205          * No need to update the stats for !=STA interfaces
206          */
207         if (!rt2x00dev->intf_sta_count)
208                 return;
209
210         /*
211          * Frame was received successfully since non-succesfull
212          * frames would have been dropped by the hardware.
213          */
214         qual->rx_success++;
215
216         /*
217          * We are only interested in quality statistics from
218          * beacons which came from the BSS which we are
219          * associated with.
220          */
221         if (!ieee80211_is_beacon(hdr->frame_control) ||
222             !(rxdesc->dev_flags & RXDONE_MY_BSS))
223                 return;
224
225         /*
226          * Update global RSSI
227          */
228         ewma_add(&link->avg_rssi, -rxdesc->rssi);
229
230         /*
231          * Update antenna RSSI
232          */
233         ewma_add(&ant->rssi_ant, -rxdesc->rssi);
234 }
235
236 void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
237 {
238         struct link *link = &rt2x00dev->link;
239
240         /*
241          * Link tuning should only be performed when
242          * an active sta interface exists. AP interfaces
243          * don't need link tuning and monitor mode interfaces
244          * should never have to work with link tuners.
245          */
246         if (!rt2x00dev->intf_sta_count)
247                 return;
248
249         /**
250          * While scanning, link tuning is disabled. By default
251          * the most sensitive settings will be used to make sure
252          * that all beacons and probe responses will be received
253          * during the scan.
254          */
255         if (test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
256                 return;
257
258         rt2x00link_reset_tuner(rt2x00dev, false);
259
260         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
261                 ieee80211_queue_delayed_work(rt2x00dev->hw,
262                                              &link->work, LINK_TUNE_INTERVAL);
263 }
264
265 void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
266 {
267         cancel_delayed_work_sync(&rt2x00dev->link.work);
268 }
269
270 void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna)
271 {
272         struct link_qual *qual = &rt2x00dev->link.qual;
273         u8 vgc_level = qual->vgc_level_reg;
274
275         if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
276                 return;
277
278         /*
279          * Reset link information.
280          * Both the currently active vgc level as well as
281          * the link tuner counter should be reset. Resetting
282          * the counter is important for devices where the
283          * device should only perform link tuning during the
284          * first minute after being enabled.
285          */
286         rt2x00dev->link.count = 0;
287         memset(qual, 0, sizeof(*qual));
288         ewma_init(&rt2x00dev->link.avg_rssi, RT2X00_EWMA_FACTOR,
289                   RT2X00_EWMA_WEIGHT);
290
291         /*
292          * Restore the VGC level as stored in the registers,
293          * the driver can use this to determine if the register
294          * must be updated during reset or not.
295          */
296         qual->vgc_level_reg = vgc_level;
297
298         /*
299          * Reset the link tuner.
300          */
301         rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual);
302
303         if (antenna)
304                 rt2x00link_antenna_reset(rt2x00dev);
305 }
306
307 static void rt2x00link_reset_qual(struct rt2x00_dev *rt2x00dev)
308 {
309         struct link_qual *qual = &rt2x00dev->link.qual;
310
311         qual->rx_success = 0;
312         qual->rx_failed = 0;
313         qual->tx_success = 0;
314         qual->tx_failed = 0;
315 }
316
317 static void rt2x00link_tuner(struct work_struct *work)
318 {
319         struct rt2x00_dev *rt2x00dev =
320             container_of(work, struct rt2x00_dev, link.work.work);
321         struct link *link = &rt2x00dev->link;
322         struct link_qual *qual = &rt2x00dev->link.qual;
323
324         /*
325          * When the radio is shutting down we should
326          * immediately cease all link tuning.
327          */
328         if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) ||
329             test_bit(DEVICE_STATE_SCANNING, &rt2x00dev->flags))
330                 return;
331
332         /*
333          * Update statistics.
334          */
335         rt2x00dev->ops->lib->link_stats(rt2x00dev, qual);
336         rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed;
337
338         /*
339          * Update quality RSSI for link tuning,
340          * when we have received some frames and we managed to
341          * collect the RSSI data we could use this. Otherwise we
342          * must fallback to the default RSSI value.
343          */
344         if (!qual->rx_success)
345                 qual->rssi = DEFAULT_RSSI;
346         else
347                 qual->rssi = rt2x00link_get_avg_rssi(&link->avg_rssi);
348
349         /*
350          * Check if link tuning is supported by the hardware, some hardware
351          * do not support link tuning at all, while other devices can disable
352          * the feature from the EEPROM.
353          */
354         if (rt2x00_has_cap_link_tuning(rt2x00dev))
355                 rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count);
356
357         /*
358          * Send a signal to the led to update the led signal strength.
359          */
360         rt2x00leds_led_quality(rt2x00dev, qual->rssi);
361
362         /*
363          * Evaluate antenna setup, make this the last step when
364          * rt2x00lib_antenna_diversity made changes the quality
365          * statistics will be reset.
366          */
367         if (rt2x00lib_antenna_diversity(rt2x00dev))
368                 rt2x00link_reset_qual(rt2x00dev);
369
370         /*
371          * Increase tuner counter, and reschedule the next link tuner run.
372          */
373         link->count++;
374
375         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
376                 ieee80211_queue_delayed_work(rt2x00dev->hw,
377                                              &link->work, LINK_TUNE_INTERVAL);
378 }
379
380 void rt2x00link_start_watchdog(struct rt2x00_dev *rt2x00dev)
381 {
382         struct link *link = &rt2x00dev->link;
383
384         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
385             rt2x00dev->ops->lib->watchdog)
386                 ieee80211_queue_delayed_work(rt2x00dev->hw,
387                                              &link->watchdog_work,
388                                              WATCHDOG_INTERVAL);
389 }
390
391 void rt2x00link_stop_watchdog(struct rt2x00_dev *rt2x00dev)
392 {
393         cancel_delayed_work_sync(&rt2x00dev->link.watchdog_work);
394 }
395
396 static void rt2x00link_watchdog(struct work_struct *work)
397 {
398         struct rt2x00_dev *rt2x00dev =
399             container_of(work, struct rt2x00_dev, link.watchdog_work.work);
400         struct link *link = &rt2x00dev->link;
401
402         /*
403          * When the radio is shutting down we should
404          * immediately cease the watchdog monitoring.
405          */
406         if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
407                 return;
408
409         rt2x00dev->ops->lib->watchdog(rt2x00dev);
410
411         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
412                 ieee80211_queue_delayed_work(rt2x00dev->hw,
413                                              &link->watchdog_work,
414                                              WATCHDOG_INTERVAL);
415 }
416
417 void rt2x00link_start_agc(struct rt2x00_dev *rt2x00dev)
418 {
419         struct link *link = &rt2x00dev->link;
420
421         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
422             rt2x00dev->ops->lib->gain_calibration)
423                 ieee80211_queue_delayed_work(rt2x00dev->hw,
424                                              &link->agc_work,
425                                              AGC_INTERVAL);
426 }
427
428 void rt2x00link_start_vcocal(struct rt2x00_dev *rt2x00dev)
429 {
430         struct link *link = &rt2x00dev->link;
431
432         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) &&
433             rt2x00dev->ops->lib->vco_calibration)
434                 ieee80211_queue_delayed_work(rt2x00dev->hw,
435                                              &link->vco_work,
436                                              VCO_INTERVAL);
437 }
438
439 void rt2x00link_stop_agc(struct rt2x00_dev *rt2x00dev)
440 {
441         cancel_delayed_work_sync(&rt2x00dev->link.agc_work);
442 }
443
444 void rt2x00link_stop_vcocal(struct rt2x00_dev *rt2x00dev)
445 {
446         cancel_delayed_work_sync(&rt2x00dev->link.vco_work);
447 }
448
449 static void rt2x00link_agc(struct work_struct *work)
450 {
451         struct rt2x00_dev *rt2x00dev =
452             container_of(work, struct rt2x00_dev, link.agc_work.work);
453         struct link *link = &rt2x00dev->link;
454
455         /*
456          * When the radio is shutting down we should
457          * immediately cease the watchdog monitoring.
458          */
459         if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
460                 return;
461
462         rt2x00dev->ops->lib->gain_calibration(rt2x00dev);
463
464         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
465                 ieee80211_queue_delayed_work(rt2x00dev->hw,
466                                              &link->agc_work,
467                                              AGC_INTERVAL);
468 }
469
470 static void rt2x00link_vcocal(struct work_struct *work)
471 {
472         struct rt2x00_dev *rt2x00dev =
473             container_of(work, struct rt2x00_dev, link.vco_work.work);
474         struct link *link = &rt2x00dev->link;
475
476         /*
477          * When the radio is shutting down we should
478          * immediately cease the VCO calibration.
479          */
480         if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
481                 return;
482
483         rt2x00dev->ops->lib->vco_calibration(rt2x00dev);
484
485         if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
486                 ieee80211_queue_delayed_work(rt2x00dev->hw,
487                                              &link->vco_work,
488                                              VCO_INTERVAL);
489 }
490
491 void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
492 {
493         INIT_DELAYED_WORK(&rt2x00dev->link.agc_work, rt2x00link_agc);
494         if (rt2x00_has_cap_vco_recalibration(rt2x00dev))
495                 INIT_DELAYED_WORK(&rt2x00dev->link.vco_work, rt2x00link_vcocal);
496         INIT_DELAYED_WORK(&rt2x00dev->link.watchdog_work, rt2x00link_watchdog);
497         INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00link_tuner);
498 }