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