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