diff options
author | Lars Ericsson <Lars_Ericsson@telia.com> | 2009-08-08 17:54:24 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:13:52 -0400 |
commit | 193df183b15cda78f6b2373f576e243327ea0d8f (patch) | |
tree | 18e2eb38a90ed0ee07287c836aaff0c7be7873da /drivers/net/wireless/rt2x00 | |
parent | 93354cbbcbfca920495377158c0f61c36be79e13 (diff) |
rt2x00: Fix quality houskeeping for software diversity
Antanna quality statistics is not handled correctly, which leads to
software diversity being shutdown completly.
The main problem is that during antenna diversity statistics can
be reset resulting in loosing the signal strength just before
evaluation.
rssi history is not updated correctly leading to incorrect comparison
material for basing antenna switching on.
Signed-off-by: Lars Ericsson <Lars_Ericsson@telia.com>
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00')
-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. |