aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00mac.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-08-29 15:04:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-29 16:24:11 -0400
commit0262ab0df64a67d4c0ed7577a29b7d866819cc68 (patch)
tree95c5e7842787c60140fe6c35ff7a1bc8b43bebaf /drivers/net/wireless/rt2x00/rt2x00mac.c
parentde9cc7a4e6f975ca5e91cf8745b3e35a7e780bae (diff)
rt2x00: Fix race conditions in flag handling
Some of the flags should be accessed atomically to prevent race conditions. The flags that are most important are those that can change often and indicate the actual state of the device, queue or queue entry. The big flag rename was done to move all state flags to the same naming type as the other rt2x00dev flags and made sure all places where the flags were used were changed. ;) Thanks to Stephen for most of the queue flags updates, which fixes some of the most obvious consequences of the race conditions. Among those the notorious: rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0. rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0. rt2x00queue_write_tx_frame: Error - Arrived at non-free entry in the non-full queue 0. Signed-off-by: Stephen Blackheath <tramp.enshrine.stephen@blacksapphire.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/rt2x00mac.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 3af427339417..11be8957b5c2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -117,7 +117,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
117 * Note that we can only stop the TX queues inside the TX path 117 * Note that we can only stop the TX queues inside the TX path
118 * due to possible race conditions in mac80211. 118 * due to possible race conditions in mac80211.
119 */ 119 */
120 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 120 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
121 goto exit_fail; 121 goto exit_fail;
122 122
123 /* 123 /*
@@ -175,7 +175,7 @@ int rt2x00mac_start(struct ieee80211_hw *hw)
175{ 175{
176 struct rt2x00_dev *rt2x00dev = hw->priv; 176 struct rt2x00_dev *rt2x00dev = hw->priv;
177 177
178 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 178 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
179 return 0; 179 return 0;
180 180
181 return rt2x00lib_start(rt2x00dev); 181 return rt2x00lib_start(rt2x00dev);
@@ -186,7 +186,7 @@ void rt2x00mac_stop(struct ieee80211_hw *hw)
186{ 186{
187 struct rt2x00_dev *rt2x00dev = hw->priv; 187 struct rt2x00_dev *rt2x00dev = hw->priv;
188 188
189 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 189 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
190 return; 190 return;
191 191
192 rt2x00lib_stop(rt2x00dev); 192 rt2x00lib_stop(rt2x00dev);
@@ -206,8 +206,8 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
206 * Don't allow interfaces to be added 206 * Don't allow interfaces to be added
207 * the device has disappeared. 207 * the device has disappeared.
208 */ 208 */
209 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || 209 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
210 !test_bit(DEVICE_STARTED, &rt2x00dev->flags)) 210 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags))
211 return -ENODEV; 211 return -ENODEV;
212 212
213 switch (conf->type) { 213 switch (conf->type) {
@@ -256,7 +256,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
256 */ 256 */
257 for (i = 0; i < queue->limit; i++) { 257 for (i = 0; i < queue->limit; i++) {
258 entry = &queue->entries[i]; 258 entry = &queue->entries[i];
259 if (!__test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags)) 259 if (!test_and_set_bit(ENTRY_BCN_ASSIGNED, &entry->flags))
260 break; 260 break;
261 } 261 }
262 262
@@ -310,7 +310,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
310 * either the device has disappeared or when 310 * either the device has disappeared or when
311 * no interface is present. 311 * no interface is present.
312 */ 312 */
313 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags) || 313 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) ||
314 (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) || 314 (conf->type == IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_ap_count) ||
315 (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count)) 315 (conf->type != IEEE80211_IF_TYPE_AP && !rt2x00dev->intf_sta_count))
316 return; 316 return;
@@ -324,7 +324,7 @@ void rt2x00mac_remove_interface(struct ieee80211_hw *hw,
324 * Release beacon entry so it is available for 324 * Release beacon entry so it is available for
325 * new interfaces again. 325 * new interfaces again.
326 */ 326 */
327 __clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags); 327 clear_bit(ENTRY_BCN_ASSIGNED, &intf->beacon->flags);
328 328
329 /* 329 /*
330 * Make sure the bssid and mac address registers 330 * Make sure the bssid and mac address registers
@@ -344,14 +344,14 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
344 * Mac80211 might be calling this function while we are trying 344 * Mac80211 might be calling this function while we are trying
345 * to remove the device or perhaps suspending it. 345 * to remove the device or perhaps suspending it.
346 */ 346 */
347 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 347 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
348 return 0; 348 return 0;
349 349
350 /* 350 /*
351 * Check if we need to disable the radio, 351 * Check if we need to disable the radio,
352 * if this is not the case, at least the RX must be disabled. 352 * if this is not the case, at least the RX must be disabled.
353 */ 353 */
354 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) { 354 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) {
355 if (!conf->radio_enabled) 355 if (!conf->radio_enabled)
356 rt2x00lib_disable_radio(rt2x00dev); 356 rt2x00lib_disable_radio(rt2x00dev);
357 else 357 else
@@ -366,14 +366,14 @@ int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)
366 * initialized. 366 * initialized.
367 */ 367 */
368 force_reconfig = 368 force_reconfig =
369 __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags); 369 test_and_clear_bit(DEVICE_STATE_DIRTY_CONFIG, &rt2x00dev->flags);
370 370
371 rt2x00lib_config(rt2x00dev, conf, force_reconfig); 371 rt2x00lib_config(rt2x00dev, conf, force_reconfig);
372 372
373 /* 373 /*
374 * Reenable RX only if the radio should be on. 374 * Reenable RX only if the radio should be on.
375 */ 375 */
376 if (test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) 376 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
377 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 377 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
378 else if (conf->radio_enabled) 378 else if (conf->radio_enabled)
379 return rt2x00lib_enable_radio(rt2x00dev); 379 return rt2x00lib_enable_radio(rt2x00dev);
@@ -395,7 +395,7 @@ int rt2x00mac_config_interface(struct ieee80211_hw *hw,
395 * Mac80211 might be calling this function while we are trying 395 * Mac80211 might be calling this function while we are trying
396 * to remove the device or perhaps suspending it. 396 * to remove the device or perhaps suspending it.
397 */ 397 */
398 if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) 398 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
399 return 0; 399 return 0;
400 400
401 spin_lock(&intf->lock); 401 spin_lock(&intf->lock);