diff options
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00link.c | 77 |
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 | ||
106 | static int rt2x00link_antenna_get_rssi_history(struct rt2x00_dev *rt2x00dev, | 106 | static 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 | ||
123 | static void rt2x00link_antenna_update_rssi_history(struct rt2x00_dev *rt2x00dev, | 115 | static 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 | ||
140 | static void rt2x00link_antenna_reset(struct rt2x00_dev *rt2x00dev) | 122 | static 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 | ||
219 | static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | 208 | static 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 | ||
259 | void rt2x00link_update_stats(struct rt2x00_dev *rt2x00dev, | 253 | void 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. |