aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-28 04:19:40 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-28 04:19:40 -0400
commit1b63ba8a86c85524a8d7e5953b314ce71ebcb9c9 (patch)
treefe3dc41cbb47ae12b7c3faf6a88b097349e50d5a /drivers/net/wireless
parente35c3269edba151e1c703d87068a28ce2cd65bb0 (diff)
parentd420895efb259a78dda50f95289571faa6e10e41 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl4965-base.c
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/b43/leds.c3
-rw-r--r--drivers/net/wireless/b43/main.c12
-rw-r--r--drivers/net/wireless/b43legacy/dma.c2
-rw-r--r--drivers/net/wireless/b43legacy/main.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c33
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c33
-rw-r--r--drivers/net/wireless/prism54/islpci_eth.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c36
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c38
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c36
12 files changed, 123 insertions, 83 deletions
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c
index 36a9c42df835..76f4c7bad8b8 100644
--- a/drivers/net/wireless/b43/leds.c
+++ b/drivers/net/wireless/b43/leds.c
@@ -72,6 +72,9 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
72 struct b43_wldev *dev = led->dev; 72 struct b43_wldev *dev = led->dev;
73 bool radio_enabled; 73 bool radio_enabled;
74 74
75 if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED))
76 return;
77
75 /* Checking the radio-enabled status here is slightly racy, 78 /* Checking the radio-enabled status here is slightly racy,
76 * but we want to avoid the locking overhead and we don't care 79 * but we want to avoid the locking overhead and we don't care
77 * whether the LED has the wrong state for a second. */ 80 * whether the LED has the wrong state for a second. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 7bca8e981512..704dd3551fff 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2976,12 +2976,11 @@ static int b43_op_tx(struct ieee80211_hw *hw,
2976 2976
2977 if (unlikely(skb->len < 2 + 2 + 6)) { 2977 if (unlikely(skb->len < 2 + 2 + 6)) {
2978 /* Too short, this can't be a valid frame. */ 2978 /* Too short, this can't be a valid frame. */
2979 dev_kfree_skb_any(skb); 2979 goto drop_packet;
2980 return NETDEV_TX_OK;
2981 } 2980 }
2982 B43_WARN_ON(skb_shinfo(skb)->nr_frags); 2981 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
2983 if (unlikely(!dev)) 2982 if (unlikely(!dev))
2984 return NETDEV_TX_BUSY; 2983 goto drop_packet;
2985 2984
2986 /* Transmissions on seperate queues can run concurrently. */ 2985 /* Transmissions on seperate queues can run concurrently. */
2987 read_lock_irqsave(&wl->tx_lock, flags); 2986 read_lock_irqsave(&wl->tx_lock, flags);
@@ -2997,7 +2996,12 @@ static int b43_op_tx(struct ieee80211_hw *hw,
2997 read_unlock_irqrestore(&wl->tx_lock, flags); 2996 read_unlock_irqrestore(&wl->tx_lock, flags);
2998 2997
2999 if (unlikely(err)) 2998 if (unlikely(err))
3000 return NETDEV_TX_BUSY; 2999 goto drop_packet;
3000 return NETDEV_TX_OK;
3001
3002drop_packet:
3003 /* We can not transmit this packet. Drop it. */
3004 dev_kfree_skb_any(skb);
3001 return NETDEV_TX_OK; 3005 return NETDEV_TX_OK;
3002} 3006}
3003 3007
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 33cc256c5baf..203b0f42ac58 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -876,6 +876,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
876 if (!ring) 876 if (!ring)
877 goto out; 877 goto out;
878 ring->type = type; 878 ring->type = type;
879 ring->dev = dev;
879 880
880 nr_slots = B43legacy_RXRING_SLOTS; 881 nr_slots = B43legacy_RXRING_SLOTS;
881 if (for_tx) 882 if (for_tx)
@@ -922,7 +923,6 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
922 DMA_TO_DEVICE); 923 DMA_TO_DEVICE);
923 } 924 }
924 925
925 ring->dev = dev;
926 ring->nr_slots = nr_slots; 926 ring->nr_slots = nr_slots;
927 ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index); 927 ring->mmio_base = b43legacy_dmacontroller_base(type, controller_index);
928 ring->index = controller_index; 928 ring->index = controller_index;
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 5f533b93ad5d..069157eea05c 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -2377,8 +2377,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
2377 } else 2377 } else
2378 err = b43legacy_dma_tx(dev, skb); 2378 err = b43legacy_dma_tx(dev, skb);
2379out: 2379out:
2380 if (unlikely(err)) 2380 if (unlikely(err)) {
2381 return NETDEV_TX_BUSY; 2381 /* Drop the packet. */
2382 dev_kfree_skb_any(skb);
2383 }
2382 return NETDEV_TX_OK; 2384 return NETDEV_TX_OK;
2383} 2385}
2384 2386
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 5ca181f7125d..5b420b43af5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -276,13 +276,18 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
276 cancel_delayed_work(&priv->scan_check); 276 cancel_delayed_work(&priv->scan_check);
277 277
278 IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", 278 IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
279 (priv->scan_bands == 2) ? "2.4" : "5.2", 279 (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
280 "2.4" : "5.2",
280 jiffies_to_msecs(elapsed_jiffies 281 jiffies_to_msecs(elapsed_jiffies
281 (priv->scan_pass_start, jiffies))); 282 (priv->scan_pass_start, jiffies)));
282 283
283 /* Remove this scanned band from the list 284 /* Remove this scanned band from the list of pending
284 * of pending bands to scan */ 285 * bands to scan, band G precedes A in order of scanning
285 priv->scan_bands--; 286 * as seen in iwl_bg_request_scan */
287 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
288 priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
289 else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
290 priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
286 291
287 /* If a request to abort was given, or the scan did not succeed 292 /* If a request to abort was given, or the scan did not succeed
288 * then we reset the scan state machine and terminate, 293 * then we reset the scan state machine and terminate,
@@ -292,7 +297,7 @@ static void iwl_rx_scan_complete_notif(struct iwl_priv *priv,
292 clear_bit(STATUS_SCAN_ABORTING, &priv->status); 297 clear_bit(STATUS_SCAN_ABORTING, &priv->status);
293 } else { 298 } else {
294 /* If there are more bands on this scan pass reschedule */ 299 /* If there are more bands on this scan pass reschedule */
295 if (priv->scan_bands > 0) 300 if (priv->scan_bands)
296 goto reschedule; 301 goto reschedule;
297 } 302 }
298 303
@@ -389,7 +394,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
389 394
390 ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); 395 ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
391 if (!is_channel_valid(ch_info)) { 396 if (!is_channel_valid(ch_info)) {
392 IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", 397 IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
393 scan_ch->channel); 398 scan_ch->channel);
394 continue; 399 continue;
395 } 400 }
@@ -465,7 +470,10 @@ int iwl_scan_initiate(struct iwl_priv *priv)
465 } 470 }
466 471
467 IWL_DEBUG_INFO("Starting scan...\n"); 472 IWL_DEBUG_INFO("Starting scan...\n");
468 priv->scan_bands = 2; 473 if (priv->cfg->sku & IWL_SKU_G)
474 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
475 if (priv->cfg->sku & IWL_SKU_A)
476 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
469 set_bit(STATUS_SCANNING, &priv->status); 477 set_bit(STATUS_SCANNING, &priv->status);
470 priv->scan_start = jiffies; 478 priv->scan_start = jiffies;
471 priv->scan_pass_start = priv->scan_start; 479 priv->scan_pass_start = priv->scan_start;
@@ -803,8 +811,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
803 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 811 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
804 812
805 813
806 switch (priv->scan_bands) { 814 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
807 case 2:
808 band = IEEE80211_BAND_2GHZ; 815 band = IEEE80211_BAND_2GHZ;
809 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 816 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
810 tx_ant = iwl_scan_tx_ant(priv, band); 817 tx_ant = iwl_scan_tx_ant(priv, band);
@@ -818,9 +825,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
818 tx_ant | 825 tx_ant |
819 RATE_MCS_CCK_MSK); 826 RATE_MCS_CCK_MSK);
820 scan->good_CRC_th = 0; 827 scan->good_CRC_th = 0;
821 break; 828 } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
822
823 case 1:
824 band = IEEE80211_BAND_5GHZ; 829 band = IEEE80211_BAND_5GHZ;
825 tx_ant = iwl_scan_tx_ant(priv, band); 830 tx_ant = iwl_scan_tx_ant(priv, band);
826 scan->tx_cmd.rate_n_flags = 831 scan->tx_cmd.rate_n_flags =
@@ -833,9 +838,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
833 * MIMO is not used here, but value is required */ 838 * MIMO is not used here, but value is required */
834 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 839 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
835 rx_chain = 0x6; 840 rx_chain = 0x6;
836 841 } else {
837 break;
838 default:
839 IWL_WARNING("Invalid scan band count\n"); 842 IWL_WARNING("Invalid scan band count\n");
840 goto done; 843 goto done;
841 } 844 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 47cf4b997f50..92d1b2e312d4 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2217,7 +2217,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv)
2217 } 2217 }
2218 2218
2219 IWL_DEBUG_INFO("Starting scan...\n"); 2219 IWL_DEBUG_INFO("Starting scan...\n");
2220 priv->scan_bands = 2; 2220 if (priv->cfg->sku & IWL_SKU_G)
2221 priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ);
2222 if (priv->cfg->sku & IWL_SKU_A)
2223 priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ);
2221 set_bit(STATUS_SCANNING, &priv->status); 2224 set_bit(STATUS_SCANNING, &priv->status);
2222 priv->scan_start = jiffies; 2225 priv->scan_start = jiffies;
2223 priv->scan_pass_start = priv->scan_start; 2226 priv->scan_pass_start = priv->scan_start;
@@ -3342,13 +3345,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv,
3342 cancel_delayed_work(&priv->scan_check); 3345 cancel_delayed_work(&priv->scan_check);
3343 3346
3344 IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", 3347 IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n",
3345 (priv->scan_bands == 2) ? "2.4" : "5.2", 3348 (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ?
3349 "2.4" : "5.2",
3346 jiffies_to_msecs(elapsed_jiffies 3350 jiffies_to_msecs(elapsed_jiffies
3347 (priv->scan_pass_start, jiffies))); 3351 (priv->scan_pass_start, jiffies)));
3348 3352
3349 /* Remove this scanned band from the list 3353 /* Remove this scanned band from the list of pending
3350 * of pending bands to scan */ 3354 * bands to scan, band G precedes A in order of scanning
3351 priv->scan_bands--; 3355 * as seen in iwl3945_bg_request_scan */
3356 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ))
3357 priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ);
3358 else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ))
3359 priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ);
3352 3360
3353 /* If a request to abort was given, or the scan did not succeed 3361 /* If a request to abort was given, or the scan did not succeed
3354 * then we reset the scan state machine and terminate, 3362 * then we reset the scan state machine and terminate,
@@ -4961,7 +4969,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv,
4961 4969
4962 ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); 4970 ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
4963 if (!is_channel_valid(ch_info)) { 4971 if (!is_channel_valid(ch_info)) {
4964 IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", 4972 IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
4965 scan_ch->channel); 4973 scan_ch->channel);
4966 continue; 4974 continue;
4967 } 4975 }
@@ -6316,21 +6324,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
6316 6324
6317 /* flags + rate selection */ 6325 /* flags + rate selection */
6318 6326
6319 switch (priv->scan_bands) { 6327 if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) {
6320 case 2:
6321 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 6328 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
6322 scan->tx_cmd.rate = IWL_RATE_1M_PLCP; 6329 scan->tx_cmd.rate = IWL_RATE_1M_PLCP;
6323 scan->good_CRC_th = 0; 6330 scan->good_CRC_th = 0;
6324 band = IEEE80211_BAND_2GHZ; 6331 band = IEEE80211_BAND_2GHZ;
6325 break; 6332 } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {
6326
6327 case 1:
6328 scan->tx_cmd.rate = IWL_RATE_6M_PLCP; 6333 scan->tx_cmd.rate = IWL_RATE_6M_PLCP;
6329 scan->good_CRC_th = IWL_GOOD_CRC_TH; 6334 scan->good_CRC_th = IWL_GOOD_CRC_TH;
6330 band = IEEE80211_BAND_5GHZ; 6335 band = IEEE80211_BAND_5GHZ;
6331 break; 6336 } else {
6332
6333 default:
6334 IWL_WARNING("Invalid scan band count\n"); 6337 IWL_WARNING("Invalid scan band count\n");
6335 goto done; 6338 goto done;
6336 } 6339 }
@@ -6770,7 +6773,7 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
6770 ch_info = iwl3945_get_channel_info(priv, conf->channel->band, 6773 ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
6771 conf->channel->hw_value); 6774 conf->channel->hw_value);
6772 if (!is_channel_valid(ch_info)) { 6775 if (!is_channel_valid(ch_info)) {
6773 IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this SKU.\n", 6776 IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
6774 conf->channel->hw_value, conf->channel->band); 6777 conf->channel->hw_value, conf->channel->band);
6775 IWL_DEBUG_MAC80211("leave - invalid channel\n"); 6778 IWL_DEBUG_MAC80211("leave - invalid channel\n");
6776 spin_unlock_irqrestore(&priv->lock, flags); 6779 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 762e85bef55d..e43bae97ed8f 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -290,7 +290,7 @@ islpci_monitor_rx(islpci_private *priv, struct sk_buff **skb)
290 290
291 avs->version = cpu_to_be32(P80211CAPTURE_VERSION); 291 avs->version = cpu_to_be32(P80211CAPTURE_VERSION);
292 avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header)); 292 avs->length = cpu_to_be32(sizeof (struct avs_80211_1_header));
293 avs->mactime = cpu_to_be64(le64_to_cpu(clock)); 293 avs->mactime = cpu_to_be64(clock);
294 avs->hosttime = cpu_to_be64(jiffies); 294 avs->hosttime = cpu_to_be64(jiffies);
295 avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */ 295 avs->phytype = cpu_to_be32(6); /*OFDM: 6 for (g), 8 for (a) */
296 avs->channel = cpu_to_be32(channel_of_freq(freq)); 296 avs->channel = cpu_to_be32(channel_of_freq(freq));
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 9851cefaabf3..0462d6d35b8a 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -138,11 +138,8 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
138 * Wait until the BBP becomes ready. 138 * Wait until the BBP becomes ready.
139 */ 139 */
140 reg = rt2500usb_bbp_check(rt2x00dev); 140 reg = rt2500usb_bbp_check(rt2x00dev);
141 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { 141 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
142 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); 142 goto exit_fail;
143 mutex_unlock(&rt2x00dev->usb_cache_mutex);
144 return;
145 }
146 143
147 /* 144 /*
148 * Write the data into the BBP. 145 * Write the data into the BBP.
@@ -155,6 +152,13 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
155 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); 152 rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
156 153
157 mutex_unlock(&rt2x00dev->usb_cache_mutex); 154 mutex_unlock(&rt2x00dev->usb_cache_mutex);
155
156 return;
157
158exit_fail:
159 mutex_unlock(&rt2x00dev->usb_cache_mutex);
160
161 ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
158} 162}
159 163
160static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, 164static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -168,10 +172,8 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
168 * Wait until the BBP becomes ready. 172 * Wait until the BBP becomes ready.
169 */ 173 */
170 reg = rt2500usb_bbp_check(rt2x00dev); 174 reg = rt2500usb_bbp_check(rt2x00dev);
171 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { 175 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
172 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); 176 goto exit_fail;
173 return;
174 }
175 177
176 /* 178 /*
177 * Write the request into the BBP. 179 * Write the request into the BBP.
@@ -186,17 +188,21 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
186 * Wait until the BBP becomes ready. 188 * Wait until the BBP becomes ready.
187 */ 189 */
188 reg = rt2500usb_bbp_check(rt2x00dev); 190 reg = rt2500usb_bbp_check(rt2x00dev);
189 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) { 191 if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
190 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); 192 goto exit_fail;
191 *value = 0xff;
192 mutex_unlock(&rt2x00dev->usb_cache_mutex);
193 return;
194 }
195 193
196 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg); 194 rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
197 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); 195 *value = rt2x00_get_field16(reg, PHY_CSR7_DATA);
198 196
199 mutex_unlock(&rt2x00dev->usb_cache_mutex); 197 mutex_unlock(&rt2x00dev->usb_cache_mutex);
198
199 return;
200
201exit_fail:
202 mutex_unlock(&rt2x00dev->usb_cache_mutex);
203
204 ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
205 *value = 0xff;
200} 206}
201 207
202static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, 208static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 0da8f972a1b2..52d8e9688219 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -818,6 +818,7 @@ struct rt2x00_dev {
818 /* 818 /*
819 * Scheduled work. 819 * Scheduled work.
820 */ 820 */
821 struct workqueue_struct *workqueue;
821 struct work_struct intf_work; 822 struct work_struct intf_work;
822 struct work_struct filter_work; 823 struct work_struct filter_work;
823 824
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 9ea677320daa..cc4fee105ed6 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -74,7 +74,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev)
74 74
75 rt2x00lib_reset_link_tuner(rt2x00dev); 75 rt2x00lib_reset_link_tuner(rt2x00dev);
76 76
77 queue_delayed_work(rt2x00dev->hw->workqueue, 77 queue_delayed_work(rt2x00dev->workqueue,
78 &rt2x00dev->link.work, LINK_TUNE_INTERVAL); 78 &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
79} 79}
80 80
@@ -138,14 +138,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev)
138 return; 138 return;
139 139
140 /* 140 /*
141 * Stop all scheduled work.
142 */
143 if (work_pending(&rt2x00dev->intf_work))
144 cancel_work_sync(&rt2x00dev->intf_work);
145 if (work_pending(&rt2x00dev->filter_work))
146 cancel_work_sync(&rt2x00dev->filter_work);
147
148 /*
149 * Stop the TX queues. 141 * Stop the TX queues.
150 */ 142 */
151 ieee80211_stop_queues(rt2x00dev->hw); 143 ieee80211_stop_queues(rt2x00dev->hw);
@@ -400,8 +392,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work)
400 * Increase tuner counter, and reschedule the next link tuner run. 392 * Increase tuner counter, and reschedule the next link tuner run.
401 */ 393 */
402 rt2x00dev->link.count++; 394 rt2x00dev->link.count++;
403 queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, 395 queue_delayed_work(rt2x00dev->workqueue,
404 LINK_TUNE_INTERVAL); 396 &rt2x00dev->link.work, LINK_TUNE_INTERVAL);
405} 397}
406 398
407static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) 399static void rt2x00lib_packetfilter_scheduled(struct work_struct *work)
@@ -434,6 +426,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
434 426
435 spin_unlock(&intf->lock); 427 spin_unlock(&intf->lock);
436 428
429 /*
430 * It is possible the radio was disabled while the work had been
431 * scheduled. If that happens we should return here immediately,
432 * note that in the spinlock protected area above the delayed_flags
433 * have been cleared correctly.
434 */
435 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags))
436 return;
437
437 if (delayed_flags & DELAYED_UPDATE_BEACON) { 438 if (delayed_flags & DELAYED_UPDATE_BEACON) {
438 skb = ieee80211_beacon_get(rt2x00dev->hw, vif); 439 skb = ieee80211_beacon_get(rt2x00dev->hw, vif);
439 if (skb && 440 if (skb &&
@@ -442,7 +443,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac,
442 } 443 }
443 444
444 if (delayed_flags & DELAYED_CONFIG_ERP) 445 if (delayed_flags & DELAYED_CONFIG_ERP)
445 rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); 446 rt2x00lib_config_erp(rt2x00dev, intf, &conf);
446 447
447 if (delayed_flags & DELAYED_LED_ASSOC) 448 if (delayed_flags & DELAYED_LED_ASSOC)
448 rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); 449 rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated);
@@ -488,7 +489,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
488 rt2x00lib_beacondone_iter, 489 rt2x00lib_beacondone_iter,
489 rt2x00dev); 490 rt2x00dev);
490 491
491 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); 492 queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
492} 493}
493EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); 494EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
494 495
@@ -1003,6 +1004,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1003 /* 1004 /*
1004 * Initialize configuration work. 1005 * Initialize configuration work.
1005 */ 1006 */
1007 rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib");
1008 if (!rt2x00dev->workqueue)
1009 goto exit;
1010
1006 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); 1011 INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled);
1007 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); 1012 INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled);
1008 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); 1013 INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner);
@@ -1063,6 +1068,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
1063 rt2x00leds_unregister(rt2x00dev); 1068 rt2x00leds_unregister(rt2x00dev);
1064 1069
1065 /* 1070 /*
1071 * Stop all queued work. Note that most tasks will already be halted
1072 * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize().
1073 */
1074 flush_workqueue(rt2x00dev->workqueue);
1075 destroy_workqueue(rt2x00dev->workqueue);
1076
1077 /*
1066 * Free ieee80211_hw memory. 1078 * Free ieee80211_hw memory.
1067 */ 1079 */
1068 rt2x00lib_remove_hw(rt2x00dev); 1080 rt2x00lib_remove_hw(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index c90992f613fe..1253da89295b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -431,7 +431,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); 432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
433 else 433 else
434 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); 434 queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work);
435} 435}
436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
437 437
@@ -512,7 +512,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
512 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); 512 memcpy(&intf->conf, bss_conf, sizeof(*bss_conf));
513 if (delayed) { 513 if (delayed) {
514 intf->delayed_flags |= delayed; 514 intf->delayed_flags |= delayed;
515 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); 515 queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work);
516 } 516 }
517 spin_unlock(&intf->lock); 517 spin_unlock(&intf->lock);
518} 518}
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index fceefd730ab8..675ff7900eee 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -134,11 +134,8 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
134 * Wait until the BBP becomes ready. 134 * Wait until the BBP becomes ready.
135 */ 135 */
136 reg = rt73usb_bbp_check(rt2x00dev); 136 reg = rt73usb_bbp_check(rt2x00dev);
137 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 137 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
138 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); 138 goto exit_fail;
139 mutex_unlock(&rt2x00dev->usb_cache_mutex);
140 return;
141 }
142 139
143 /* 140 /*
144 * Write the data into the BBP. 141 * Write the data into the BBP.
@@ -151,6 +148,13 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev,
151 148
152 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); 149 rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg);
153 mutex_unlock(&rt2x00dev->usb_cache_mutex); 150 mutex_unlock(&rt2x00dev->usb_cache_mutex);
151
152 return;
153
154exit_fail:
155 mutex_unlock(&rt2x00dev->usb_cache_mutex);
156
157 ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n");
154} 158}
155 159
156static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, 160static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -164,11 +168,8 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
164 * Wait until the BBP becomes ready. 168 * Wait until the BBP becomes ready.
165 */ 169 */
166 reg = rt73usb_bbp_check(rt2x00dev); 170 reg = rt73usb_bbp_check(rt2x00dev);
167 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 171 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
168 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 172 goto exit_fail;
169 mutex_unlock(&rt2x00dev->usb_cache_mutex);
170 return;
171 }
172 173
173 /* 174 /*
174 * Write the request into the BBP. 175 * Write the request into the BBP.
@@ -184,14 +185,19 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev,
184 * Wait until the BBP becomes ready. 185 * Wait until the BBP becomes ready.
185 */ 186 */
186 reg = rt73usb_bbp_check(rt2x00dev); 187 reg = rt73usb_bbp_check(rt2x00dev);
187 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) { 188 if (rt2x00_get_field32(reg, PHY_CSR3_BUSY))
188 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); 189 goto exit_fail;
189 *value = 0xff;
190 return;
191 }
192 190
193 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); 191 *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
194 mutex_unlock(&rt2x00dev->usb_cache_mutex); 192 mutex_unlock(&rt2x00dev->usb_cache_mutex);
193
194 return;
195
196exit_fail:
197 mutex_unlock(&rt2x00dev->usb_cache_mutex);
198
199 ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n");
200 *value = 0xff;
195} 201}
196 202
197static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, 203static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev,