aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c27
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c50
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h9
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c49
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c52
5 files changed, 92 insertions, 95 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 1afba42cc128..e87ad43e8e8d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -600,35 +600,36 @@ static void rt2400pci_link_stats(struct rt2x00_dev *rt2x00dev,
600 qual->false_cca = bbp; 600 qual->false_cca = bbp;
601} 601}
602 602
603static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
604{
605 rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
606 rt2x00dev->link.vgc_level = vgc_level;
607 rt2x00dev->link.vgc_level_reg = vgc_level;
608}
609
603static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev) 610static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
604{ 611{
605 rt2400pci_bbp_write(rt2x00dev, 13, 0x08); 612 rt2400pci_set_vgc(rt2x00dev, 0x08);
606 rt2x00dev->link.vgc_level = 0x08;
607} 613}
608 614
609static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) 615static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
610{ 616{
611 u8 reg; 617 struct link *link = &rt2x00dev->link;
612 618
613 /* 619 /*
614 * The link tuner should not run longer then 60 seconds, 620 * The link tuner should not run longer then 60 seconds,
615 * and should run once every 2 seconds. 621 * and should run once every 2 seconds.
616 */ 622 */
617 if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1)) 623 if (link->count > 60 || !(link->count & 1))
618 return; 624 return;
619 625
620 /* 626 /*
621 * Base r13 link tuning on the false cca count. 627 * Base r13 link tuning on the false cca count.
622 */ 628 */
623 rt2400pci_bbp_read(rt2x00dev, 13, &reg); 629 if ((link->qual.false_cca > 512) && (link->vgc_level < 0x20))
624 630 rt2400pci_set_vgc(rt2x00dev, ++link->vgc_level);
625 if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) { 631 else if ((link->qual.false_cca < 100) && (link->vgc_level > 0x08))
626 rt2400pci_bbp_write(rt2x00dev, 13, ++reg); 632 rt2400pci_set_vgc(rt2x00dev, --link->vgc_level);
627 rt2x00dev->link.vgc_level = reg;
628 } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
629 rt2400pci_bbp_write(rt2x00dev, 13, --reg);
630 rt2x00dev->link.vgc_level = reg;
631 }
632} 633}
633 634
634/* 635/*
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index bf5e81162f25..5b98a74a2554 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -639,16 +639,23 @@ 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
642static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
643{
644 if (rt2x00dev->link.vgc_level_reg != vgc_level) {
645 rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
646 rt2x00dev->link.vgc_level_reg = vgc_level;
647 }
648}
649
642static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev) 650static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
643{ 651{
644 rt2500pci_bbp_write(rt2x00dev, 17, 0x48); 652 rt2500pci_set_vgc(rt2x00dev, 0x48);
645 rt2x00dev->link.vgc_level = 0x48;
646} 653}
647 654
648static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev) 655static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
649{ 656{
650 int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); 657 struct link *link = &rt2x00dev->link;
651 u8 r17; 658 int rssi = rt2x00_get_link_rssi(link);
652 659
653 /* 660 /*
654 * To prevent collisions with MAC ASIC on chipsets 661 * To prevent collisions with MAC ASIC on chipsets
@@ -656,12 +663,9 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
656 * seconds while being associated. 663 * seconds while being associated.
657 */ 664 */
658 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D && 665 if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
659 rt2x00dev->intf_associated && 666 rt2x00dev->intf_associated && link->count > 20)
660 rt2x00dev->link.count > 20)
661 return; 667 return;
662 668
663 rt2500pci_bbp_read(rt2x00dev, 17, &r17);
664
665 /* 669 /*
666 * Chipset versions C and lower should directly continue 670 * Chipset versions C and lower should directly continue
667 * to the dynamic CCA tuning. Chipset version D and higher 671 * to the dynamic CCA tuning. Chipset version D and higher
@@ -677,11 +681,9 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
677 * then corrupt the R17 tuning. To remidy this the tuning should 681 * then corrupt the R17 tuning. To remidy this the tuning should
678 * 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)
679 */ 683 */
680 if (rssi < -80 && rt2x00dev->link.count > 20) { 684 if (rssi < -80 && link->count > 20) {
681 if (r17 >= 0x41) { 685 if (link->vgc_level_reg >= 0x41)
682 r17 = rt2x00dev->link.vgc_level; 686 rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
683 rt2500pci_bbp_write(rt2x00dev, 17, r17);
684 }
685 return; 687 return;
686 } 688 }
687 689
@@ -689,8 +691,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
689 * Special big-R17 for short distance 691 * Special big-R17 for short distance
690 */ 692 */
691 if (rssi >= -58) { 693 if (rssi >= -58) {
692 if (r17 != 0x50) 694 rt2500pci_set_vgc(rt2x00dev, 0x50);
693 rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
694 return; 695 return;
695 } 696 }
696 697
@@ -698,8 +699,7 @@ static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
698 * Special mid-R17 for middle distance 699 * Special mid-R17 for middle distance
699 */ 700 */
700 if (rssi >= -74) { 701 if (rssi >= -74) {
701 if (r17 != 0x41) 702 rt2500pci_set_vgc(rt2x00dev, 0x41);
702 rt2500pci_bbp_write(rt2x00dev, 17, 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 (r17 >= 0x41) { 710 if (link->vgc_level_reg >= 0x41) {
711 rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level); 711 rt2500pci_set_vgc(rt2x00dev, link->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 (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) { 721 if (link->qual.false_cca > 512 && link->vgc_level_reg < 0x40) {
722 rt2500pci_bbp_write(rt2x00dev, 17, ++r17); 722 rt2500pci_set_vgc(rt2x00dev, ++link->vgc_level_reg);
723 rt2x00dev->link.vgc_level = r17; 723 link->vgc_level = link->vgc_level_reg;
724 } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) { 724 } else if (link->qual.false_cca < 100 && link->vgc_level_reg > 0x32) {
725 rt2500pci_bbp_write(rt2x00dev, 17, --r17); 725 rt2500pci_set_vgc(rt2x00dev, --link->vgc_level_reg);
726 rt2x00dev->link.vgc_level = r17; 726 link->vgc_level = link->vgc_level_reg;
727 } 727 }
728} 728}
729 729
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 19c068727a85..8935f2c005ce 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -286,9 +286,14 @@ struct link {
286 struct link_ant ant; 286 struct link_ant ant;
287 287
288 /* 288 /*
289 * Active VGC level 289 * Active VGC level (for false cca tuning)
290 */ 290 */
291 int vgc_level; 291 u8 vgc_level;
292
293 /*
294 * VGC level as configured in register
295 */
296 u8 vgc_level_reg;
292 297
293 /* 298 /*
294 * Work structure for scheduling periodic link tuning. 299 * Work structure for scheduling periodic link tuning.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index c7ab744f0052..94523f7f0d88 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -1046,21 +1046,27 @@ 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
1049static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
1050{
1051 if (rt2x00dev->link.vgc_level != vgc_level) {
1052 rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
1053 rt2x00dev->link.vgc_level = vgc_level;
1054 rt2x00dev->link.vgc_level_reg = vgc_level;
1055 }
1056}
1057
1049static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev) 1058static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
1050{ 1059{
1051 rt61pci_bbp_write(rt2x00dev, 17, 0x20); 1060 rt61pci_set_vgc(rt2x00dev, 0x20);
1052 rt2x00dev->link.vgc_level = 0x20;
1053} 1061}
1054 1062
1055static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev) 1063static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1056{ 1064{
1057 int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); 1065 struct link *link = &rt2x00dev->link;
1058 u8 r17; 1066 int rssi = rt2x00_get_link_rssi(link);
1059 u8 up_bound; 1067 u8 up_bound;
1060 u8 low_bound; 1068 u8 low_bound;
1061 1069
1062 rt61pci_bbp_read(rt2x00dev, 17, &r17);
1063
1064 /* 1070 /*
1065 * Determine r17 bounds. 1071 * Determine r17 bounds.
1066 */ 1072 */
@@ -1091,8 +1097,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1091 * Special big-R17 for very short distance 1097 * Special big-R17 for very short distance
1092 */ 1098 */
1093 if (rssi >= -35) { 1099 if (rssi >= -35) {
1094 if (r17 != 0x60) 1100 rt61pci_set_vgc(rt2x00dev, 0x60);
1095 rt61pci_bbp_write(rt2x00dev, 17, 0x60);
1096 return; 1101 return;
1097 } 1102 }
1098 1103
@@ -1100,8 +1105,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1100 * Special big-R17 for short distance 1105 * Special big-R17 for short distance
1101 */ 1106 */
1102 if (rssi >= -58) { 1107 if (rssi >= -58) {
1103 if (r17 != up_bound) 1108 rt61pci_set_vgc(rt2x00dev, up_bound);
1104 rt61pci_bbp_write(rt2x00dev, 17, up_bound);
1105 return; 1109 return;
1106 } 1110 }
1107 1111
@@ -1109,9 +1113,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1109 * Special big-R17 for middle-short distance 1113 * Special big-R17 for middle-short distance
1110 */ 1114 */
1111 if (rssi >= -66) { 1115 if (rssi >= -66) {
1112 low_bound += 0x10; 1116 rt61pci_set_vgc(rt2x00dev, low_bound + 0x10);
1113 if (r17 != low_bound)
1114 rt61pci_bbp_write(rt2x00dev, 17, low_bound);
1115 return; 1117 return;
1116 } 1118 }
1117 1119
@@ -1119,9 +1121,7 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1119 * Special mid-R17 for middle distance 1121 * Special mid-R17 for middle distance
1120 */ 1122 */
1121 if (rssi >= -74) { 1123 if (rssi >= -74) {
1122 low_bound += 0x08; 1124 rt61pci_set_vgc(rt2x00dev, low_bound + 0x08);
1123 if (r17 != low_bound)
1124 rt61pci_bbp_write(rt2x00dev, 17, low_bound);
1125 return; 1125 return;
1126 } 1126 }
1127 1127
@@ -1133,8 +1133,8 @@ static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
1133 if (low_bound > up_bound) 1133 if (low_bound > up_bound)
1134 up_bound = low_bound; 1134 up_bound = low_bound;
1135 1135
1136 if (r17 > up_bound) { 1136 if (link->vgc_level > up_bound) {
1137 rt61pci_bbp_write(rt2x00dev, 17, up_bound); 1137 rt61pci_set_vgc(rt2x00dev, up_bound);
1138 return; 1138 return;
1139 } 1139 }
1140 1140
@@ -1144,15 +1144,10 @@ dynamic_cca_tune:
1144 * r17 does not yet exceed upper limit, continue and base 1144 * r17 does not yet exceed upper limit, continue and base
1145 * the r17 tuning on the false CCA count. 1145 * the r17 tuning on the false CCA count.
1146 */ 1146 */
1147 if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { 1147 if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
1148 if (++r17 > up_bound) 1148 rt61pci_set_vgc(rt2x00dev, ++link->vgc_level);
1149 r17 = up_bound; 1149 else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
1150 rt61pci_bbp_write(rt2x00dev, 17, r17); 1150 rt61pci_set_vgc(rt2x00dev, --link->vgc_level);
1151 } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
1152 if (--r17 < low_bound)
1153 r17 = low_bound;
1154 rt61pci_bbp_write(rt2x00dev, 17, r17);
1155 }
1156} 1151}
1157 1152
1158/* 1153/*
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ae3b31d0d511..b5443148d621 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -924,21 +924,27 @@ 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
927static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
928{
929 if (rt2x00dev->link.vgc_level != vgc_level) {
930 rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
931 rt2x00dev->link.vgc_level = vgc_level;
932 rt2x00dev->link.vgc_level_reg = vgc_level;
933 }
934}
935
927static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev) 936static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
928{ 937{
929 rt73usb_bbp_write(rt2x00dev, 17, 0x20); 938 rt73usb_set_vgc(rt2x00dev, 0x20);
930 rt2x00dev->link.vgc_level = 0x20;
931} 939}
932 940
933static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev) 941static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
934{ 942{
935 int rssi = rt2x00_get_link_rssi(&rt2x00dev->link); 943 struct link *link = &rt2x00dev->link;
936 u8 r17; 944 int rssi = rt2x00_get_link_rssi(link);
937 u8 up_bound; 945 u8 up_bound;
938 u8 low_bound; 946 u8 low_bound;
939 947
940 rt73usb_bbp_read(rt2x00dev, 17, &r17);
941
942 /* 948 /*
943 * Determine r17 bounds. 949 * Determine r17 bounds.
944 */ 950 */
@@ -979,8 +985,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
979 * Special big-R17 for very short distance 985 * Special big-R17 for very short distance
980 */ 986 */
981 if (rssi > -35) { 987 if (rssi > -35) {
982 if (r17 != 0x60) 988 rt73usb_set_vgc(rt2x00dev, 0x60);
983 rt73usb_bbp_write(rt2x00dev, 17, 0x60);
984 return; 989 return;
985 } 990 }
986 991
@@ -988,8 +993,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
988 * Special big-R17 for short distance 993 * Special big-R17 for short distance
989 */ 994 */
990 if (rssi >= -58) { 995 if (rssi >= -58) {
991 if (r17 != up_bound) 996 rt73usb_set_vgc(rt2x00dev, up_bound);
992 rt73usb_bbp_write(rt2x00dev, 17, up_bound);
993 return; 997 return;
994 } 998 }
995 999
@@ -997,9 +1001,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
997 * Special big-R17 for middle-short distance 1001 * Special big-R17 for middle-short distance
998 */ 1002 */
999 if (rssi >= -66) { 1003 if (rssi >= -66) {
1000 low_bound += 0x10; 1004 rt73usb_set_vgc(rt2x00dev, low_bound + 0x10);
1001 if (r17 != low_bound)
1002 rt73usb_bbp_write(rt2x00dev, 17, low_bound);
1003 return; 1005 return;
1004 } 1006 }
1005 1007
@@ -1007,8 +1009,7 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
1007 * Special mid-R17 for middle distance 1009 * Special mid-R17 for middle distance
1008 */ 1010 */
1009 if (rssi >= -74) { 1011 if (rssi >= -74) {
1010 if (r17 != (low_bound + 0x10)) 1012 rt73usb_set_vgc(rt2x00dev, low_bound + 0x08);
1011 rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
1012 return; 1013 return;
1013 } 1014 }
1014 1015
@@ -1020,8 +1021,8 @@ static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
1020 if (low_bound > up_bound) 1021 if (low_bound > up_bound)
1021 up_bound = low_bound; 1022 up_bound = low_bound;
1022 1023
1023 if (r17 > up_bound) { 1024 if (link->vgc_level > up_bound) {
1024 rt73usb_bbp_write(rt2x00dev, 17, up_bound); 1025 rt73usb_set_vgc(rt2x00dev, up_bound);
1025 return; 1026 return;
1026 } 1027 }
1027 1028
@@ -1031,17 +1032,12 @@ dynamic_cca_tune:
1031 * r17 does not yet exceed upper limit, continue and base 1032 * r17 does not yet exceed upper limit, continue and base
1032 * the r17 tuning on the false CCA count. 1033 * the r17 tuning on the false CCA count.
1033 */ 1034 */
1034 if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) { 1035 if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
1035 r17 += 4; 1036 rt73usb_set_vgc(rt2x00dev,
1036 if (r17 > up_bound) 1037 min_t(u8, link->vgc_level + 4, up_bound));
1037 r17 = up_bound; 1038 else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
1038 rt73usb_bbp_write(rt2x00dev, 17, r17); 1039 rt73usb_set_vgc(rt2x00dev,
1039 } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) { 1040 max_t(u8, link->vgc_level - 4, low_bound));
1040 r17 -= 4;
1041 if (r17 < low_bound)
1042 r17 = low_bound;
1043 rt73usb_bbp_write(rt2x00dev, 17, r17);
1044 }
1045} 1041}
1046 1042
1047/* 1043/*