diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 27 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 99 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00link.c | 145 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 57 |
7 files changed, 233 insertions, 199 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index e87ad43e8e8d..9104113270d0 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -600,36 +600,37 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
600 | qual->false_cca = bbp; | 600 | qual->false_cca = bbp; |
601 | } | 601 | } |
602 | 602 | ||
603 | static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level) | 603 | static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
604 | struct link_qual *qual, u8 vgc_level) | ||
604 | { | 605 | { |
605 | rt2400pci_bbp_write(rt2x00dev, 13, vgc_level); | 606 | rt2400pci_bbp_write(rt2x00dev, 13, vgc_level); |
606 | rt2x00dev->link.vgc_level = vgc_level; | 607 | qual->vgc_level = vgc_level; |
607 | rt2x00dev->link.vgc_level_reg = vgc_level; | 608 | qual->vgc_level_reg = vgc_level; |
608 | } | 609 | } |
609 | 610 | ||
610 | static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 611 | static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
612 | struct link_qual *qual) | ||
611 | { | 613 | { |
612 | rt2400pci_set_vgc(rt2x00dev, 0x08); | 614 | rt2400pci_set_vgc(rt2x00dev, qual, 0x08); |
613 | } | 615 | } |
614 | 616 | ||
615 | static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 617 | static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev, |
618 | struct link_qual *qual, const u32 count) | ||
616 | { | 619 | { |
617 | struct link *link = &rt2x00dev->link; | ||
618 | |||
619 | /* | 620 | /* |
620 | * The link tuner should not run longer then 60 seconds, | 621 | * The link tuner should not run longer then 60 seconds, |
621 | * and should run once every 2 seconds. | 622 | * and should run once every 2 seconds. |
622 | */ | 623 | */ |
623 | if (link->count > 60 || !(link->count & 1)) | 624 | if (count > 60 || !(count & 1)) |
624 | return; | 625 | return; |
625 | 626 | ||
626 | /* | 627 | /* |
627 | * Base r13 link tuning on the false cca count. | 628 | * Base r13 link tuning on the false cca count. |
628 | */ | 629 | */ |
629 | if ((link->qual.false_cca > 512) && (link->vgc_level < 0x20)) | 630 | if ((qual->false_cca > 512) && (qual->vgc_level < 0x20)) |
630 | rt2400pci_set_vgc(rt2x00dev, ++link->vgc_level); | 631 | rt2400pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level); |
631 | else if ((link->qual.false_cca < 100) && (link->vgc_level > 0x08)) | 632 | else if ((qual->false_cca < 100) && (qual->vgc_level > 0x08)) |
632 | rt2400pci_set_vgc(rt2x00dev, --link->vgc_level); | 633 | rt2400pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); |
633 | } | 634 | } |
634 | 635 | ||
635 | /* | 636 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 5b98a74a2554..fb86e2c55248 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -639,31 +639,31 @@ static void rt2500pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
639 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); | 639 | qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA); |
640 | } | 640 | } |
641 | 641 | ||
642 | static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level) | 642 | static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
643 | struct link_qual *qual, u8 vgc_level) | ||
643 | { | 644 | { |
644 | if (rt2x00dev->link.vgc_level_reg != vgc_level) { | 645 | if (qual->vgc_level_reg != vgc_level) { |
645 | rt2500pci_bbp_write(rt2x00dev, 17, vgc_level); | 646 | rt2500pci_bbp_write(rt2x00dev, 17, vgc_level); |
646 | rt2x00dev->link.vgc_level_reg = vgc_level; | 647 | qual->vgc_level_reg = vgc_level; |
647 | } | 648 | } |
648 | } | 649 | } |
649 | 650 | ||
650 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 651 | static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
652 | struct link_qual *qual) | ||
651 | { | 653 | { |
652 | rt2500pci_set_vgc(rt2x00dev, 0x48); | 654 | rt2500pci_set_vgc(rt2x00dev, qual, 0x48); |
653 | } | 655 | } |
654 | 656 | ||
655 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 657 | static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev, |
658 | struct link_qual *qual, const u32 count) | ||
656 | { | 659 | { |
657 | struct link *link = &rt2x00dev->link; | ||
658 | int rssi = rt2x00_get_link_rssi(link); | ||
659 | |||
660 | /* | 660 | /* |
661 | * To prevent collisions with MAC ASIC on chipsets | 661 | * To prevent collisions with MAC ASIC on chipsets |
662 | * up to version C the link tuning should halt after 20 | 662 | * up to version C the link tuning should halt after 20 |
663 | * seconds while being associated. | 663 | * seconds while being associated. |
664 | */ | 664 | */ |
665 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && | 665 | if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && |
666 | rt2x00dev->intf_associated && link->count > 20) | 666 | rt2x00dev->intf_associated && count > 20) |
667 | return; | 667 | return; |
668 | 668 | ||
669 | /* | 669 | /* |
@@ -681,25 +681,25 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
681 | * then corrupt the R17 tuning. To remidy this the tuning should | 681 | * then corrupt the R17 tuning. To remidy this the tuning should |
682 | * be stopped (While making sure the R17 value will not exceed limits) | 682 | * be stopped (While making sure the R17 value will not exceed limits) |
683 | */ | 683 | */ |
684 | if (rssi < -80 && link->count > 20) { | 684 | if (qual->rssi < -80 && count > 20) { |
685 | if (link->vgc_level_reg >= 0x41) | 685 | if (qual->vgc_level_reg >= 0x41) |
686 | rt2500pci_set_vgc(rt2x00dev, link->vgc_level); | 686 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
687 | return; | 687 | return; |
688 | } | 688 | } |
689 | 689 | ||
690 | /* | 690 | /* |
691 | * Special big-R17 for short distance | 691 | * Special big-R17 for short distance |
692 | */ | 692 | */ |
693 | if (rssi >= -58) { | 693 | if (qual->rssi >= -58) { |
694 | rt2500pci_set_vgc(rt2x00dev, 0x50); | 694 | rt2500pci_set_vgc(rt2x00dev, qual, 0x50); |
695 | return; | 695 | return; |
696 | } | 696 | } |
697 | 697 | ||
698 | /* | 698 | /* |
699 | * Special mid-R17 for middle distance | 699 | * Special mid-R17 for middle distance |
700 | */ | 700 | */ |
701 | if (rssi >= -74) { | 701 | if (qual->rssi >= -74) { |
702 | rt2500pci_set_vgc(rt2x00dev, 0x41); | 702 | rt2500pci_set_vgc(rt2x00dev, qual, 0x41); |
703 | return; | 703 | return; |
704 | } | 704 | } |
705 | 705 | ||
@@ -707,8 +707,8 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
707 | * Leave short or middle distance condition, restore r17 | 707 | * Leave short or middle distance condition, restore r17 |
708 | * to the dynamic tuning range. | 708 | * to the dynamic tuning range. |
709 | */ | 709 | */ |
710 | if (link->vgc_level_reg >= 0x41) { | 710 | if (qual->vgc_level_reg >= 0x41) { |
711 | rt2500pci_set_vgc(rt2x00dev, link->vgc_level); | 711 | rt2500pci_set_vgc(rt2x00dev, qual, qual->vgc_level); |
712 | return; | 712 | return; |
713 | } | 713 | } |
714 | 714 | ||
@@ -718,12 +718,12 @@ dynamic_cca_tune: | |||
718 | * R17 is inside the dynamic tuning range, | 718 | * R17 is inside the dynamic tuning range, |
719 | * start tuning the link based on the false cca counter. | 719 | * start tuning the link based on the false cca counter. |
720 | */ | 720 | */ |
721 | if (link->qual.false_cca > 512 && link->vgc_level_reg < 0x40) { | 721 | if (qual->false_cca > 512 && qual->vgc_level_reg < 0x40) { |
722 | rt2500pci_set_vgc(rt2x00dev, ++link->vgc_level_reg); | 722 | rt2500pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level_reg); |
723 | link->vgc_level = link->vgc_level_reg; | 723 | qual->vgc_level = qual->vgc_level_reg; |
724 | } else if (link->qual.false_cca < 100 && link->vgc_level_reg > 0x32) { | 724 | } else if (qual->false_cca < 100 && qual->vgc_level_reg > 0x32) { |
725 | rt2500pci_set_vgc(rt2x00dev, --link->vgc_level_reg); | 725 | rt2500pci_set_vgc(rt2x00dev, qual, --qual->vgc_level_reg); |
726 | link->vgc_level = link->vgc_level_reg; | 726 | qual->vgc_level = qual->vgc_level_reg; |
727 | } | 727 | } |
728 | } | 728 | } |
729 | 729 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 23cf585f03a4..557fcf2b30e4 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -698,7 +698,8 @@ static void rt2500usb_link_stats(struct rt2x00_dev *rt2x00dev, | |||
698 | qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); | 698 | qual->false_cca = rt2x00_get_field16(reg, STA_CSR3_FALSE_CCA_ERROR); |
699 | } | 699 | } |
700 | 700 | ||
701 | static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | 701 | static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev, |
702 | struct link_qual *qual) | ||
702 | { | 703 | { |
703 | u16 eeprom; | 704 | u16 eeprom; |
704 | u16 value; | 705 | u16 value; |
@@ -719,7 +720,7 @@ static void rt2500usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | |||
719 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER); | 720 | value = rt2x00_get_field16(eeprom, EEPROM_BBPTUNE_VGCUPPER); |
720 | rt2500usb_bbp_write(rt2x00dev, 17, value); | 721 | rt2500usb_bbp_write(rt2x00dev, 17, value); |
721 | 722 | ||
722 | rt2x00dev->link.vgc_level = value; | 723 | qual->vgc_level = value; |
723 | } | 724 | } |
724 | 725 | ||
725 | /* | 726 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 8935f2c005ce..dea502234cf8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -177,52 +177,41 @@ struct antenna_setup { | |||
177 | */ | 177 | */ |
178 | struct link_qual { | 178 | struct link_qual { |
179 | /* | 179 | /* |
180 | * Statistics required for Link tuning. | 180 | * Statistics required for Link tuning by driver |
181 | * For the average RSSI value we use the "Walking average" approach. | 181 | * The rssi value is provided by rt2x00lib during the |
182 | * When adding RSSI to the average value the following calculation | 182 | * link_tuner() callback function. |
183 | * is needed: | 183 | * The false_cca field is filled during the link_stats() |
184 | * | 184 | * callback function and could be used during the |
185 | * avg_rssi = ((avg_rssi * 7) + rssi) / 8; | 185 | * link_tuner() callback function. |
186 | */ | ||
187 | int rssi; | ||
188 | int false_cca; | ||
189 | |||
190 | /* | ||
191 | * VGC levels | ||
192 | * Hardware driver will tune the VGC level during each call | ||
193 | * to the link_tuner() callback function. This vgc_level is | ||
194 | * is determined based on the link quality statistics like | ||
195 | * average RSSI and the false CCA count. | ||
186 | * | 196 | * |
187 | * The advantage of this approach is that we only need 1 variable | 197 | * In some cases the drivers need to differentiate between |
188 | * to store the average in (No need for a count and a total). | 198 | * the currently "desired" VGC level and the level configured |
189 | * But more importantly, normal average values will over time | 199 | * in the hardware. The latter is important to reduce the |
190 | * move less and less towards newly added values this results | 200 | * number of BBP register reads to reduce register access |
191 | * that with link tuning, the device can have a very good RSSI | 201 | * overhead. For this reason we store both values here. |
192 | * for a few minutes but when the device is moved away from the AP | ||
193 | * the average will not decrease fast enough to compensate. | ||
194 | * The walking average compensates this and will move towards | ||
195 | * the new values correctly allowing a effective link tuning. | ||
196 | */ | 202 | */ |
197 | int avg_rssi; | 203 | u8 vgc_level; |
198 | int false_cca; | 204 | u8 vgc_level_reg; |
199 | 205 | ||
200 | /* | 206 | /* |
201 | * Statistics required for Signal quality calculation. | 207 | * Statistics required for Signal quality calculation. |
202 | * For calculating the Signal quality we have to determine | 208 | * These fields might be changed during the link_stats() |
203 | * the total number of success and failed RX and TX frames. | 209 | * callback function. |
204 | * After that we also use the average RSSI value to help | ||
205 | * determining the signal quality. | ||
206 | * For the calculation we will use the following algorithm: | ||
207 | * | ||
208 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
209 | * rx_percentage = (rx_success * 100) / rx_total | ||
210 | * tx_percentage = (tx_success * 100) / tx_total | ||
211 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
212 | * (WEIGHT_TX * tx_percentage) + | ||
213 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
214 | * | ||
215 | * This value should then be checked to not be greater then 100. | ||
216 | */ | 210 | */ |
217 | int rx_percentage; | ||
218 | int rx_success; | 211 | int rx_success; |
219 | int rx_failed; | 212 | int rx_failed; |
220 | int tx_percentage; | ||
221 | int tx_success; | 213 | int tx_success; |
222 | int tx_failed; | 214 | int tx_failed; |
223 | #define WEIGHT_RSSI 20 | ||
224 | #define WEIGHT_RX 40 | ||
225 | #define WEIGHT_TX 40 | ||
226 | }; | 215 | }; |
227 | 216 | ||
228 | /* | 217 | /* |
@@ -286,14 +275,16 @@ struct link { | |||
286 | struct link_ant ant; | 275 | struct link_ant ant; |
287 | 276 | ||
288 | /* | 277 | /* |
289 | * Active VGC level (for false cca tuning) | 278 | * Currently active average RSSI value |
290 | */ | 279 | */ |
291 | u8 vgc_level; | 280 | int avg_rssi; |
292 | 281 | ||
293 | /* | 282 | /* |
294 | * VGC level as configured in register | 283 | * Currently precalculated percentages of successful |
284 | * TX and RX frames. | ||
295 | */ | 285 | */ |
296 | u8 vgc_level_reg; | 286 | int rx_percentage; |
287 | int tx_percentage; | ||
297 | 288 | ||
298 | /* | 289 | /* |
299 | * Work structure for scheduling periodic link tuning. | 290 | * Work structure for scheduling periodic link tuning. |
@@ -302,28 +293,6 @@ struct link { | |||
302 | }; | 293 | }; |
303 | 294 | ||
304 | /* | 295 | /* |
305 | * Small helper macro to work with moving/walking averages. | ||
306 | */ | ||
307 | #define MOVING_AVERAGE(__avg, __val, __samples) \ | ||
308 | ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) | ||
309 | |||
310 | /* | ||
311 | * When we lack RSSI information return something less then -80 to | ||
312 | * tell the driver to tune the device to maximum sensitivity. | ||
313 | */ | ||
314 | #define DEFAULT_RSSI ( -128 ) | ||
315 | |||
316 | /* | ||
317 | * Link quality access functions. | ||
318 | */ | ||
319 | static inline int rt2x00_get_link_rssi(struct link *link) | ||
320 | { | ||
321 | if (link->qual.avg_rssi && link->qual.rx_success) | ||
322 | return link->qual.avg_rssi; | ||
323 | return DEFAULT_RSSI; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Interface structure | 296 | * Interface structure |
328 | * Per interface configuration details, this structure | 297 | * Per interface configuration details, this structure |
329 | * is allocated as the private data for ieee80211_vif. | 298 | * is allocated as the private data for ieee80211_vif. |
@@ -522,8 +491,10 @@ struct rt2x00lib_ops { | |||
522 | int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); | 491 | int (*rfkill_poll) (struct rt2x00_dev *rt2x00dev); |
523 | void (*link_stats) (struct rt2x00_dev *rt2x00dev, | 492 | void (*link_stats) (struct rt2x00_dev *rt2x00dev, |
524 | struct link_qual *qual); | 493 | struct link_qual *qual); |
525 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev); | 494 | void (*reset_tuner) (struct rt2x00_dev *rt2x00dev, |
526 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev); | 495 | struct link_qual *qual); |
496 | void (*link_tuner) (struct rt2x00_dev *rt2x00dev, | ||
497 | struct link_qual *qual, const u32 count); | ||
527 | 498 | ||
528 | /* | 499 | /* |
529 | * TX control handlers | 500 | * TX control handlers |
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c index 0462d5ab6e97..ee08f1167f59 100644 --- a/drivers/net/wireless/rt2x00/rt2x00link.c +++ b/drivers/net/wireless/rt2x00/rt2x00link.c | |||
@@ -29,6 +29,71 @@ | |||
29 | #include "rt2x00.h" | 29 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 30 | #include "rt2x00lib.h" |
31 | 31 | ||
32 | /* | ||
33 | * When we lack RSSI information return something less then -80 to | ||
34 | * tell the driver to tune the device to maximum sensitivity. | ||
35 | */ | ||
36 | #define DEFAULT_RSSI -128 | ||
37 | |||
38 | /* | ||
39 | * When no TX/RX percentage could be calculated due to lack of | ||
40 | * frames on the air, we fallback to a percentage of 50%. | ||
41 | * This will assure we will get at least get some decent value | ||
42 | * when the link tuner starts. | ||
43 | * The value will be dropped and overwritten with the correct (measured) | ||
44 | * value anyway during the first run of the link tuner. | ||
45 | */ | ||
46 | #define DEFAULT_PERCENTAGE 50 | ||
47 | |||
48 | /* | ||
49 | * Small helper macro to work with moving/walking averages. | ||
50 | * When adding a value to the average value the following calculation | ||
51 | * is needed: | ||
52 | * | ||
53 | * avg_rssi = ((avg_rssi * 7) + rssi) / 8; | ||
54 | * | ||
55 | * The advantage of this approach is that we only need 1 variable | ||
56 | * to store the average in (No need for a count and a total). | ||
57 | * But more importantly, normal average values will over time | ||
58 | * move less and less towards newly added values this results | ||
59 | * that with link tuning, the device can have a very good RSSI | ||
60 | * for a few minutes but when the device is moved away from the AP | ||
61 | * the average will not decrease fast enough to compensate. | ||
62 | * The walking average compensates this and will move towards | ||
63 | * the new values correctly allowing a effective link tuning. | ||
64 | */ | ||
65 | #define MOVING_AVERAGE(__avg, __val, __samples) \ | ||
66 | ( (((__avg) * ((__samples) - 1)) + (__val)) / (__samples) ) | ||
67 | |||
68 | /* | ||
69 | * Small helper macro for percentage calculation | ||
70 | * This is a very simple macro with the only catch that it will | ||
71 | * produce a default value in case no total value was provided. | ||
72 | */ | ||
73 | #define PERCENTAGE(__value, __total) \ | ||
74 | ( (__total) ? (((__value) * 100) / (__total)) : (DEFAULT_PERCENTAGE) ) | ||
75 | |||
76 | /* | ||
77 | * For calculating the Signal quality we have determined | ||
78 | * the total number of success and failed RX and TX frames. | ||
79 | * With the addition of the average RSSI value we can determine | ||
80 | * the link quality using the following algorithm: | ||
81 | * | ||
82 | * rssi_percentage = (avg_rssi * 100) / rssi_offset | ||
83 | * rx_percentage = (rx_success * 100) / rx_total | ||
84 | * tx_percentage = (tx_success * 100) / tx_total | ||
85 | * avg_signal = ((WEIGHT_RSSI * avg_rssi) + | ||
86 | * (WEIGHT_TX * tx_percentage) + | ||
87 | * (WEIGHT_RX * rx_percentage)) / 100 | ||
88 | * | ||
89 | * This value should then be checked to not be greater then 100. | ||
90 | * This means the values of WEIGHT_RSSI, WEIGHT_RX, WEIGHT_TX must | ||
91 | * sum up to 100 as well. | ||
92 | */ | ||
93 | #define WEIGHT_RSSI 20 | ||
94 | #define WEIGHT_RX 40 | ||
95 | #define WEIGHT_TX 40 | ||
96 | |||
32 | static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) | 97 | static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev) |
33 | { | 98 | { |
34 | struct link_ant *ant = &rt2x00dev->link.ant; | 99 | struct link_ant *ant = &rt2x00dev->link.ant; |
@@ -191,6 +256,7 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | |||
191 | struct sk_buff *skb, | 256 | struct sk_buff *skb, |
192 | struct rxdone_entry_desc *rxdesc) | 257 | struct rxdone_entry_desc *rxdesc) |
193 | { | 258 | { |
259 | struct link *link = &rt2x00dev->link; | ||
194 | struct link_qual *qual = &rt2x00dev->link.qual; | 260 | struct link_qual *qual = &rt2x00dev->link.qual; |
195 | struct link_ant *ant = &rt2x00dev->link.ant; | 261 | struct link_ant *ant = &rt2x00dev->link.ant; |
196 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 262 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
@@ -215,9 +281,9 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | |||
215 | /* | 281 | /* |
216 | * Update global RSSI | 282 | * Update global RSSI |
217 | */ | 283 | */ |
218 | if (qual->avg_rssi) | 284 | if (link->avg_rssi) |
219 | avg_rssi = MOVING_AVERAGE(qual->avg_rssi, rxdesc->rssi, 8); | 285 | avg_rssi = MOVING_AVERAGE(link->avg_rssi, rxdesc->rssi, 8); |
220 | qual->avg_rssi = avg_rssi; | 286 | link->avg_rssi = avg_rssi; |
221 | 287 | ||
222 | /* | 288 | /* |
223 | * Update antenna RSSI | 289 | * Update antenna RSSI |
@@ -229,21 +295,13 @@ void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | |||
229 | 295 | ||
230 | static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev) | 296 | static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev) |
231 | { | 297 | { |
298 | struct link *link = &rt2x00dev->link; | ||
232 | struct link_qual *qual = &rt2x00dev->link.qual; | 299 | struct link_qual *qual = &rt2x00dev->link.qual; |
233 | 300 | ||
234 | if (qual->rx_failed || qual->rx_success) | 301 | link->rx_percentage = |
235 | qual->rx_percentage = | 302 | PERCENTAGE(qual->rx_success, qual->rx_failed + qual->rx_success); |
236 | (qual->rx_success * 100) / | 303 | link->tx_percentage = |
237 | (qual->rx_failed + qual->rx_success); | 304 | PERCENTAGE(qual->tx_success, qual->tx_failed + qual->tx_success); |
238 | else | ||
239 | qual->rx_percentage = 50; | ||
240 | |||
241 | if (qual->tx_failed || qual->tx_success) | ||
242 | qual->tx_percentage = | ||
243 | (qual->tx_success * 100) / | ||
244 | (qual->tx_failed + qual->tx_success); | ||
245 | else | ||
246 | qual->tx_percentage = 50; | ||
247 | 305 | ||
248 | qual->rx_success = 0; | 306 | qual->rx_success = 0; |
249 | qual->rx_failed = 0; | 307 | qual->rx_failed = 0; |
@@ -253,7 +311,7 @@ static void rt2x00link_precalculate_signal(struct rt2x00_dev *rt2x00dev) | |||
253 | 311 | ||
254 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi) | 312 | int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi) |
255 | { | 313 | { |
256 | struct link_qual *qual = &rt2x00dev->link.qual; | 314 | struct link *link = &rt2x00dev->link; |
257 | int rssi_percentage = 0; | 315 | int rssi_percentage = 0; |
258 | int signal; | 316 | int signal; |
259 | 317 | ||
@@ -267,22 +325,22 @@ int rt2x00link_calculate_signal(struct rt2x00_dev *rt2x00dev, int rssi) | |||
267 | * Calculate the different percentages, | 325 | * Calculate the different percentages, |
268 | * which will be used for the signal. | 326 | * which will be used for the signal. |
269 | */ | 327 | */ |
270 | rssi_percentage = (rssi * 100) / rt2x00dev->rssi_offset; | 328 | rssi_percentage = PERCENTAGE(rssi, rt2x00dev->rssi_offset); |
271 | 329 | ||
272 | /* | 330 | /* |
273 | * Add the individual percentages and use the WEIGHT | 331 | * Add the individual percentages and use the WEIGHT |
274 | * defines to calculate the current link signal. | 332 | * defines to calculate the current link signal. |
275 | */ | 333 | */ |
276 | signal = ((WEIGHT_RSSI * rssi_percentage) + | 334 | signal = ((WEIGHT_RSSI * rssi_percentage) + |
277 | (WEIGHT_TX * qual->tx_percentage) + | 335 | (WEIGHT_TX * link->tx_percentage) + |
278 | (WEIGHT_RX * qual->rx_percentage)) / 100; | 336 | (WEIGHT_RX * link->rx_percentage)) / 100; |
279 | 337 | ||
280 | return max_t(int, signal, 100); | 338 | return max_t(int, signal, 100); |
281 | } | 339 | } |
282 | 340 | ||
283 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | 341 | void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) |
284 | { | 342 | { |
285 | struct link_qual *qual = &rt2x00dev->link.qual; | 343 | struct link *link = &rt2x00dev->link; |
286 | 344 | ||
287 | /* | 345 | /* |
288 | * Link tuning should only be performed when | 346 | * Link tuning should only be performed when |
@@ -293,26 +351,13 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev) | |||
293 | if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) | 351 | if (!rt2x00dev->intf_ap_count && !rt2x00dev->intf_sta_count) |
294 | return; | 352 | return; |
295 | 353 | ||
296 | /* | 354 | link->rx_percentage = DEFAULT_PERCENTAGE; |
297 | * Clear all (possibly) pre-existing quality statistics. | 355 | link->tx_percentage = DEFAULT_PERCENTAGE; |
298 | */ | ||
299 | memset(qual, 0, sizeof(*qual)); | ||
300 | |||
301 | /* | ||
302 | * The RX and TX percentage should start at 50% | ||
303 | * this will assure we will get at least get some | ||
304 | * decent value when the link tuner starts. | ||
305 | * The value will be dropped and overwritten with | ||
306 | * the correct (measured) value anyway during the | ||
307 | * first run of the link tuner. | ||
308 | */ | ||
309 | qual->rx_percentage = 50; | ||
310 | qual->tx_percentage = 50; | ||
311 | 356 | ||
312 | rt2x00link_reset_tuner(rt2x00dev, false); | 357 | rt2x00link_reset_tuner(rt2x00dev, false); |
313 | 358 | ||
314 | queue_delayed_work(rt2x00dev->hw->workqueue, | 359 | queue_delayed_work(rt2x00dev->hw->workqueue, |
315 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | 360 | &link->work, LINK_TUNE_INTERVAL); |
316 | } | 361 | } |
317 | 362 | ||
318 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) | 363 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) |
@@ -322,6 +367,8 @@ void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) | |||
322 | 367 | ||
323 | void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) | 368 | void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) |
324 | { | 369 | { |
370 | struct link_qual *qual = &rt2x00dev->link.qual; | ||
371 | |||
325 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) | 372 | if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) |
326 | return; | 373 | return; |
327 | 374 | ||
@@ -334,12 +381,12 @@ void rt2x00link_reset_tuner(struct rt2x00_dev *rt2x00dev, bool antenna) | |||
334 | * first minute after being enabled. | 381 | * first minute after being enabled. |
335 | */ | 382 | */ |
336 | rt2x00dev->link.count = 0; | 383 | rt2x00dev->link.count = 0; |
337 | rt2x00dev->link.vgc_level = 0; | 384 | memset(qual, 0, sizeof(*qual)); |
338 | 385 | ||
339 | /* | 386 | /* |
340 | * Reset the link tuner. | 387 | * Reset the link tuner. |
341 | */ | 388 | */ |
342 | rt2x00dev->ops->lib->reset_tuner(rt2x00dev); | 389 | rt2x00dev->ops->lib->reset_tuner(rt2x00dev, qual); |
343 | 390 | ||
344 | if (antenna) | 391 | if (antenna) |
345 | rt2x00link_antenna_reset(rt2x00dev); | 392 | rt2x00link_antenna_reset(rt2x00dev); |
@@ -349,6 +396,7 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
349 | { | 396 | { |
350 | struct rt2x00_dev *rt2x00dev = | 397 | struct rt2x00_dev *rt2x00dev = |
351 | container_of(work, struct rt2x00_dev, link.work.work); | 398 | container_of(work, struct rt2x00_dev, link.work.work); |
399 | struct link *link = &rt2x00dev->link; | ||
352 | struct link_qual *qual = &rt2x00dev->link.qual; | 400 | struct link_qual *qual = &rt2x00dev->link.qual; |
353 | 401 | ||
354 | /* | 402 | /* |
@@ -365,11 +413,22 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
365 | rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed; | 413 | rt2x00dev->low_level_stats.dot11FCSErrorCount += qual->rx_failed; |
366 | 414 | ||
367 | /* | 415 | /* |
416 | * Update quality RSSI for link tuning, | ||
417 | * when we have received some frames and we managed to | ||
418 | * collect the RSSI data we could use this. Otherwise we | ||
419 | * must fallback to the default RSSI value. | ||
420 | */ | ||
421 | if (!link->avg_rssi || !qual->rx_success) | ||
422 | qual->rssi = DEFAULT_RSSI; | ||
423 | else | ||
424 | qual->rssi = link->avg_rssi; | ||
425 | |||
426 | /* | ||
368 | * Only perform the link tuning when Link tuning | 427 | * Only perform the link tuning when Link tuning |
369 | * has been enabled (This could have been disabled from the EEPROM). | 428 | * has been enabled (This could have been disabled from the EEPROM). |
370 | */ | 429 | */ |
371 | if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) | 430 | if (!test_bit(CONFIG_DISABLE_LINK_TUNING, &rt2x00dev->flags)) |
372 | rt2x00dev->ops->lib->link_tuner(rt2x00dev); | 431 | rt2x00dev->ops->lib->link_tuner(rt2x00dev, qual, link->count); |
373 | 432 | ||
374 | /* | 433 | /* |
375 | * Precalculate a portion of the link signal which is | 434 | * Precalculate a portion of the link signal which is |
@@ -380,7 +439,7 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
380 | /* | 439 | /* |
381 | * Send a signal to the led to update the led signal strength. | 440 | * Send a signal to the led to update the led signal strength. |
382 | */ | 441 | */ |
383 | rt2x00leds_led_quality(rt2x00dev, qual->avg_rssi); | 442 | rt2x00leds_led_quality(rt2x00dev, link->avg_rssi); |
384 | 443 | ||
385 | /* | 444 | /* |
386 | * Evaluate antenna setup, make this the last step since this could | 445 | * Evaluate antenna setup, make this the last step since this could |
@@ -391,9 +450,9 @@ static void rt2x00link_tuner(struct work_struct *work) | |||
391 | /* | 450 | /* |
392 | * Increase tuner counter, and reschedule the next link tuner run. | 451 | * Increase tuner counter, and reschedule the next link tuner run. |
393 | */ | 452 | */ |
394 | rt2x00dev->link.count++; | 453 | link->count++; |
395 | queue_delayed_work(rt2x00dev->hw->workqueue, | 454 | queue_delayed_work(rt2x00dev->hw->workqueue, |
396 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | 455 | &link->work, LINK_TUNE_INTERVAL); |
397 | } | 456 | } |
398 | 457 | ||
399 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) | 458 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 94523f7f0d88..ed829879c941 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1046,24 +1046,25 @@ static void rt61pci_link_stats(struct rt2x00_dev *rt2x00dev, | |||
1046 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | 1046 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level) | 1049 | static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, |
1050 | struct link_qual *qual, u8 vgc_level) | ||
1050 | { | 1051 | { |
1051 | if (rt2x00dev->link.vgc_level != vgc_level) { | 1052 | if (qual->vgc_level != vgc_level) { |
1052 | rt61pci_bbp_write(rt2x00dev, 17, vgc_level); | 1053 | rt61pci_bbp_write(rt2x00dev, 17, vgc_level); |
1053 | rt2x00dev->link.vgc_level = vgc_level; | 1054 | qual->vgc_level = vgc_level; |
1054 | rt2x00dev->link.vgc_level_reg = vgc_level; | 1055 | qual->vgc_level_reg = vgc_level; |
1055 | } | 1056 | } |
1056 | } | 1057 | } |
1057 | 1058 | ||
1058 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) | 1059 | static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev, |
1060 | struct link_qual *qual) | ||
1059 | { | 1061 | { |
1060 | rt61pci_set_vgc(rt2x00dev, 0x20); | 1062 | rt61pci_set_vgc(rt2x00dev, qual, 0x20); |
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | 1065 | static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev, |
1066 | struct link_qual *qual, const u32 count) | ||
1064 | { | 1067 | { |
1065 | struct link *link = &rt2x00dev->link; | ||
1066 | int rssi = rt2x00_get_link_rssi(link); | ||
1067 | u8 up_bound; | 1068 | u8 up_bound; |
1068 | u8 low_bound; | 1069 | u8 low_bound; |
1069 | 1070 | ||
@@ -1096,32 +1097,32 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
1096 | /* | 1097 | /* |
1097 | * Special big-R17 for very short distance | 1098 | * Special big-R17 for very short distance |
1098 | */ | 1099 | */ |
1099 | if (rssi >= -35) { | 1100 | if (qual->rssi >= -35) { |
1100 | rt61pci_set_vgc(rt2x00dev, 0x60); | 1101 | rt61pci_set_vgc(rt2x00dev, qual, 0x60); |
1101 | return; | 1102 | return; |
1102 | } | 1103 | } |
1103 | 1104 | ||
1104 | /* | 1105 | /* |
1105 | * Special big-R17 for short distance | 1106 | * Special big-R17 for short distance |
1106 | */ | 1107 | */ |
1107 | if (rssi >= -58) { | 1108 | if (qual->rssi >= -58) { |
1108 | rt61pci_set_vgc(rt2x00dev, up_bound); | 1109 | rt61pci_set_vgc(rt2x00dev, qual, up_bound); |
1109 | return; | 1110 | return; |
1110 | } | 1111 | } |
1111 | 1112 | ||
1112 | /* | 1113 | /* |
1113 | * Special big-R17 for middle-short distance | 1114 | * Special big-R17 for middle-short distance |
1114 | */ | 1115 | */ |
1115 | if (rssi >= -66) { | 1116 | if (qual->rssi >= -66) { |
1116 | rt61pci_set_vgc(rt2x00dev, low_bound + 0x10); | 1117 | rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x10); |
1117 | return; | 1118 | return; |
1118 | } | 1119 | } |
1119 | 1120 | ||
1120 | /* | 1121 | /* |
1121 | * Special mid-R17 for middle distance | 1122 | * Special mid-R17 for middle distance |
1122 | */ | 1123 | */ |
1123 | if (rssi >= -74) { | 1124 | if (qual->rssi >= -74) { |
1124 | rt61pci_set_vgc(rt2x00dev, low_bound + 0x08); | 1125 | rt61pci_set_vgc(rt2x00dev, qual, low_bound + 0x08); |
1125 | return; | 1126 | return; |
1126 | } | 1127 | } |
1127 | 1128 | ||
@@ -1129,12 +1130,12 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
1129 | * Special case: Change up_bound based on the rssi. | 1130 | * Special case: Change up_bound based on the rssi. |
1130 | * Lower up_bound when rssi is weaker then -74 dBm. | 1131 | * Lower up_bound when rssi is weaker then -74 dBm. |
1131 | */ | 1132 | */ |
1132 | up_bound -= 2 * (-74 - rssi); | 1133 | up_bound -= 2 * (-74 - qual->rssi); |
1133 | if (low_bound > up_bound) | 1134 | if (low_bound > up_bound) |
1134 | up_bound = low_bound; | 1135 | up_bound = low_bound; |
1135 | 1136 | ||
1136 | if (link->vgc_level > up_bound) { | 1137 | if (qual->vgc_level > up_bound) { |
1137 | rt61pci_set_vgc(rt2x00dev, up_bound); | 1138 | rt61pci_set_vgc(rt2x00dev, qual, up_bound); |
1138 | return; | 1139 | return; |
1139 | } | 1140 | } |
1140 | 1141 | ||
@@ -1144,10 +1145,10 @@ dynamic_cca_tune: | |||
1144 | * r17 does not yet exceed upper limit, continue and base | 1145 | * r17 does not yet exceed upper limit, continue and base |
1145 | * the r17 tuning on the false CCA count. | 1146 | * the r17 tuning on the false CCA count. |
1146 | */ | 1147 | */ |
1147 | if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound)) | 1148 | if ((qual->false_cca > 512) && (qual->vgc_level < up_bound)) |
1148 | rt61pci_set_vgc(rt2x00dev, ++link->vgc_level); | 1149 | rt61pci_set_vgc(rt2x00dev, qual, ++qual->vgc_level); |
1149 | else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound)) | 1150 | else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound)) |
1150 | rt61pci_set_vgc(rt2x00dev, --link->vgc_level); | 1151 | rt61pci_set_vgc(rt2x00dev, qual, --qual->vgc_level); |
1151 | } | 1152 | } |
1152 | 1153 | ||
1153 | /* | 1154 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index b5443148d621..e99bcacfc191 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -924,24 +924,25 @@ static void rt73usb_link_stats(struct rt2x00_dev *rt2x00dev, | |||
924 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); | 924 | qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR); |
925 | } | 925 | } |
926 | 926 | ||
927 | static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level) | 927 | static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, |
928 | struct link_qual *qual, u8 vgc_level) | ||
928 | { | 929 | { |
929 | if (rt2x00dev->link.vgc_level != vgc_level) { | 930 | if (qual->vgc_level != vgc_level) { |
930 | rt73usb_bbp_write(rt2x00dev, 17, vgc_level); | 931 | rt73usb_bbp_write(rt2x00dev, 17, vgc_level); |
931 | rt2x00dev->link.vgc_level = vgc_level; | 932 | qual->vgc_level = vgc_level; |
932 | rt2x00dev->link.vgc_level_reg = vgc_level; | 933 | qual->vgc_level_reg = vgc_level; |
933 | } | 934 | } |
934 | } | 935 | } |
935 | 936 | ||
936 | static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev) | 937 | static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev, |
938 | struct link_qual *qual) | ||
937 | { | 939 | { |
938 | rt73usb_set_vgc(rt2x00dev, 0x20); | 940 | rt73usb_set_vgc(rt2x00dev, qual, 0x20); |
939 | } | 941 | } |
940 | 942 | ||
941 | static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | 943 | static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev, |
944 | struct link_qual *qual, const u32 count) | ||
942 | { | 945 | { |
943 | struct link *link = &rt2x00dev->link; | ||
944 | int rssi = rt2x00_get_link_rssi(link); | ||
945 | u8 up_bound; | 946 | u8 up_bound; |
946 | u8 low_bound; | 947 | u8 low_bound; |
947 | 948 | ||
@@ -957,10 +958,10 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
957 | up_bound += 0x10; | 958 | up_bound += 0x10; |
958 | } | 959 | } |
959 | } else { | 960 | } else { |
960 | if (rssi > -82) { | 961 | if (qual->rssi > -82) { |
961 | low_bound = 0x1c; | 962 | low_bound = 0x1c; |
962 | up_bound = 0x40; | 963 | up_bound = 0x40; |
963 | } else if (rssi > -84) { | 964 | } else if (qual->rssi > -84) { |
964 | low_bound = 0x1c; | 965 | low_bound = 0x1c; |
965 | up_bound = 0x20; | 966 | up_bound = 0x20; |
966 | } else { | 967 | } else { |
@@ -984,32 +985,32 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
984 | /* | 985 | /* |
985 | * Special big-R17 for very short distance | 986 | * Special big-R17 for very short distance |
986 | */ | 987 | */ |
987 | if (rssi > -35) { | 988 | if (qual->rssi > -35) { |
988 | rt73usb_set_vgc(rt2x00dev, 0x60); | 989 | rt73usb_set_vgc(rt2x00dev, qual, 0x60); |
989 | return; | 990 | return; |
990 | } | 991 | } |
991 | 992 | ||
992 | /* | 993 | /* |
993 | * Special big-R17 for short distance | 994 | * Special big-R17 for short distance |
994 | */ | 995 | */ |
995 | if (rssi >= -58) { | 996 | if (qual->rssi >= -58) { |
996 | rt73usb_set_vgc(rt2x00dev, up_bound); | 997 | rt73usb_set_vgc(rt2x00dev, qual, up_bound); |
997 | return; | 998 | return; |
998 | } | 999 | } |
999 | 1000 | ||
1000 | /* | 1001 | /* |
1001 | * Special big-R17 for middle-short distance | 1002 | * Special big-R17 for middle-short distance |
1002 | */ | 1003 | */ |
1003 | if (rssi >= -66) { | 1004 | if (qual->rssi >= -66) { |
1004 | rt73usb_set_vgc(rt2x00dev, low_bound + 0x10); | 1005 | rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x10); |
1005 | return; | 1006 | return; |
1006 | } | 1007 | } |
1007 | 1008 | ||
1008 | /* | 1009 | /* |
1009 | * Special mid-R17 for middle distance | 1010 | * Special mid-R17 for middle distance |
1010 | */ | 1011 | */ |
1011 | if (rssi >= -74) { | 1012 | if (qual->rssi >= -74) { |
1012 | rt73usb_set_vgc(rt2x00dev, low_bound + 0x08); | 1013 | rt73usb_set_vgc(rt2x00dev, qual, low_bound + 0x08); |
1013 | return; | 1014 | return; |
1014 | } | 1015 | } |
1015 | 1016 | ||
@@ -1017,12 +1018,12 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
1017 | * Special case: Change up_bound based on the rssi. | 1018 | * Special case: Change up_bound based on the rssi. |
1018 | * Lower up_bound when rssi is weaker then -74 dBm. | 1019 | * Lower up_bound when rssi is weaker then -74 dBm. |
1019 | */ | 1020 | */ |
1020 | up_bound -= 2 * (-74 - rssi); | 1021 | up_bound -= 2 * (-74 - qual->rssi); |
1021 | if (low_bound > up_bound) | 1022 | if (low_bound > up_bound) |
1022 | up_bound = low_bound; | 1023 | up_bound = low_bound; |
1023 | 1024 | ||
1024 | if (link->vgc_level > up_bound) { | 1025 | if (qual->vgc_level > up_bound) { |
1025 | rt73usb_set_vgc(rt2x00dev, up_bound); | 1026 | rt73usb_set_vgc(rt2x00dev, qual, up_bound); |
1026 | return; | 1027 | return; |
1027 | } | 1028 | } |
1028 | 1029 | ||
@@ -1032,12 +1033,12 @@ dynamic_cca_tune: | |||
1032 | * r17 does not yet exceed upper limit, continue and base | 1033 | * r17 does not yet exceed upper limit, continue and base |
1033 | * the r17 tuning on the false CCA count. | 1034 | * the r17 tuning on the false CCA count. |
1034 | */ | 1035 | */ |
1035 | if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound)) | 1036 | if ((qual->false_cca > 512) && (qual->vgc_level < up_bound)) |
1036 | rt73usb_set_vgc(rt2x00dev, | 1037 | rt73usb_set_vgc(rt2x00dev, qual, |
1037 | min_t(u8, link->vgc_level + 4, up_bound)); | 1038 | min_t(u8, qual->vgc_level + 4, up_bound)); |
1038 | else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound)) | 1039 | else if ((qual->false_cca < 100) && (qual->vgc_level > low_bound)) |
1039 | rt73usb_set_vgc(rt2x00dev, | 1040 | rt73usb_set_vgc(rt2x00dev, qual, |
1040 | max_t(u8, link->vgc_level - 4, low_bound)); | 1041 | max_t(u8, qual->vgc_level - 4, low_bound)); |
1041 | } | 1042 | } |
1042 | 1043 | ||
1043 | /* | 1044 | /* |