aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h11
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c77
2 files changed, 38 insertions, 50 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index cbec91ef6f76..704e94474b1d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -245,14 +245,11 @@ struct link_ant {
245 struct antenna_setup active; 245 struct antenna_setup active;
246 246
247 /* 247 /*
248 * RSSI information for the different antennas. 248 * RSSI history information for the antenna.
249 * These statistics are used to determine when 249 * Used to determine when to switch antenna
250 * to switch antenna when using software diversity. 250 * when using software diversity.
251 *
252 * rssi[0] -> Antenna A RSSI
253 * rssi[1] -> Antenna B RSSI
254 */ 251 */
255 int rssi_history[2]; 252 int rssi_history;
256 253
257 /* 254 /*
258 * Current RSSI average of the currently active antenna. 255 * Current RSSI average of the currently active antenna.
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index fe951dc9bacf..dd68f3a57b6d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -103,39 +103,21 @@ static int rt2x00link_antenna_get_link_rssi(struct rt2x00_dev *rt2x00dev)
103 return DEFAULT_RSSI; 103 return DEFAULT_RSSI;
104} 104}
105 105
106static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev, 106static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev)
107 enum antenna antenna)
108{ 107{
109 struct link_ant *ant = &rt2x00dev->link.ant; 108 struct link_ant *ant = &rt2x00dev->link.ant;
110 109
111 if (ant->rssi_history[antenna - ANTENNA_A]) 110 if (ant->rssi_history)
112 return ant->rssi_history[antenna - ANTENNA_A]; 111 return ant->rssi_history;
113 return DEFAULT_RSSI; 112 return DEFAULT_RSSI;
114} 113}
115/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
116#define rt2x00link_antenna_get_rssi_rx_history(__dev) \
117 rt2x00link_antenna_get_rssi_history((__dev), \
118 (__dev)->link.ant.active.rx)
119#define rt2x00link_antenna_get_rssi_tx_history(__dev) \
120 rt2x00link_antenna_get_rssi_history((__dev), \
121 (__dev)->link.ant.active.tx)
122 114
123static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev, 115static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev,
124 enum antenna antenna,
125 int rssi) 116 int rssi)
126{ 117{
127 struct link_ant *ant = &rt2x00dev->link.ant; 118 struct link_ant *ant = &rt2x00dev->link.ant;
128 ant->rssi_history[ant->active.rx - ANTENNA_A] = rssi; 119 ant->rssi_history = rssi;
129} 120}
130/* Small wrapper for rt2x00link_antenna_get_rssi_history() */
131#define rt2x00link_antenna_update_rssi_rx_history(__dev, __rssi) \
132 rt2x00link_antenna_update_rssi_history((__dev), \
133 (__dev)->link.ant.active.rx, \
134 (__rssi))
135#define rt2x00link_antenna_update_rssi_tx_history(__dev, __rssi) \
136 rt2x00link_antenna_update_rssi_history((__dev), \
137 (__dev)->link.ant.active.tx, \
138 (__rssi))
139 121
140static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev) 122static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev)
141{ 123{
@@ -146,8 +128,10 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
146{ 128{
147 struct link_ant *ant = &rt2x00dev->link.ant; 129 struct link_ant *ant = &rt2x00dev->link.ant;
148 struct antenna_setup new_ant; 130 struct antenna_setup new_ant;
149 int sample_a = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_A); 131 int other_antenna;
150 int sample_b = rt2x00link_antenna_get_rssi_history(rt2x00dev, ANTENNA_B); 132
133 int sample_current = rt2x00link_antenna_get_link_rssi(rt2x00dev);
134 int sample_other = rt2x00link_antenna_get_rssi_history(rt2x00dev);
151 135
152 memcpy(&new_ant, &ant->active, sizeof(new_ant)); 136 memcpy(&new_ant, &ant->active, sizeof(new_ant));
153 137
@@ -161,17 +145,22 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
161 * from both antennas. It now is time to determine 145 * from both antennas. It now is time to determine
162 * which antenna demonstrated the best performance. 146 * which antenna demonstrated the best performance.
163 * When we are already on the antenna with the best 147 * When we are already on the antenna with the best
164 * performance, then there really is nothing for us 148 * performance, just create a good starting point
165 * left to do. 149 * for the history and we are done.
166 */ 150 */
167 if (sample_a == sample_b) 151 if (sample_current >= sample_other) {
152 rt2x00link_antenna_update_rssi_history(rt2x00dev,
153 sample_current);
168 return; 154 return;
155 }
156
157 other_antenna = (ant->active.rx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
169 158
170 if (ant->flags & ANTENNA_RX_DIVERSITY) 159 if (ant->flags & ANTENNA_RX_DIVERSITY)
171 new_ant.rx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; 160 new_ant.rx = other_antenna;
172 161
173 if (ant->flags & ANTENNA_TX_DIVERSITY) 162 if (ant->flags & ANTENNA_TX_DIVERSITY)
174 new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; 163 new_ant.tx = other_antenna;
175 164
176 rt2x00lib_config_antenna(rt2x00dev, new_ant); 165 rt2x00lib_config_antenna(rt2x00dev, new_ant);
177} 166}
@@ -190,8 +179,8 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
190 * after that update the history with the current value. 179 * after that update the history with the current value.
191 */ 180 */
192 rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev); 181 rssi_curr = rt2x00link_antenna_get_link_rssi(rt2x00dev);
193 rssi_old = rt2x00link_antenna_get_rssi_rx_history(rt2x00dev); 182 rssi_old = rt2x00link_antenna_get_rssi_history(rt2x00dev);
194 rt2x00link_antenna_update_rssi_rx_history(rt2x00dev, rssi_curr); 183 rt2x00link_antenna_update_rssi_history(rt2x00dev, rssi_curr);
195 184
196 /* 185 /*
197 * Legacy driver indicates that we should swap antenna's 186 * Legacy driver indicates that we should swap antenna's
@@ -216,7 +205,7 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
216 rt2x00lib_config_antenna(rt2x00dev, new_ant); 205 rt2x00lib_config_antenna(rt2x00dev, new_ant);
217} 206}
218 207
219static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) 208static bool rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
220{ 209{
221 struct link_ant *ant = &rt2x00dev->link.ant; 210 struct link_ant *ant = &rt2x00dev->link.ant;
222 unsigned int flags = ant->flags; 211 unsigned int flags = ant->flags;
@@ -238,7 +227,7 @@ static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
238 if (!(ant->flags & ANTENNA_RX_DIVERSITY) && 227 if (!(ant->flags & ANTENNA_RX_DIVERSITY) &&
239 !(ant->flags & ANTENNA_TX_DIVERSITY)) { 228 !(ant->flags & ANTENNA_TX_DIVERSITY)) {
240 ant->flags = 0; 229 ant->flags = 0;
241 return; 230 return true;
242 } 231 }
243 232
244 /* Update flags */ 233 /* Update flags */
@@ -250,10 +239,15 @@ static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
250 * the data. The latter should only be performed once 239 * the data. The latter should only be performed once
251 * every 2 seconds. 240 * every 2 seconds.
252 */ 241 */
253 if (ant->flags & ANTENNA_MODE_SAMPLE) 242 if (ant->flags & ANTENNA_MODE_SAMPLE) {
254 rt2x00lib_antenna_diversity_sample(rt2x00dev); 243 rt2x00lib_antenna_diversity_sample(rt2x00dev);
255 else if (rt2x00dev->link.count & 1) 244 return true;
245 } else if (rt2x00dev->link.count & 1) {
256 rt2x00lib_antenna_diversity_eval(rt2x00dev); 246 rt2x00lib_antenna_diversity_eval(rt2x00dev);
247 return true;
248 }
249
250 return false;
257} 251}
258 252
259void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, 253void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev,
@@ -451,15 +445,12 @@ static void rt2x00link_tuner(struct work_struct *work)
451 rt2x00leds_led_quality(rt2x00dev, link->avg_rssi); 445 rt2x00leds_led_quality(rt2x00dev, link->avg_rssi);
452 446
453 /* 447 /*
454 * Evaluate antenna setup, make this the last step since this could 448 * Evaluate antenna setup, make this the last step when
455 * possibly reset some statistics. 449 * rt2x00lib_antenna_diversity made changes the quality
456 */ 450 * statistics will be reset.
457 rt2x00lib_antenna_diversity(rt2x00dev);
458
459 /*
460 * Reset the quality counters which recounted during each period.
461 */ 451 */
462 rt2x00link_reset_qual(rt2x00dev); 452 if (rt2x00lib_antenna_diversity(rt2x00dev))
453 rt2x00link_reset_qual(rt2x00dev);
463 454
464 /* 455 /*
465 * Increase tuner counter, and reschedule the next link tuner run. 456 * Increase tuner counter, and reschedule the next link tuner run.