diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-28 04:19:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-28 04:19:40 -0400 |
commit | 1b63ba8a86c85524a8d7e5953b314ce71ebcb9c9 (patch) | |
tree | fe3dc41cbb47ae12b7c3faf6a88b097349e50d5a /drivers/net/wireless | |
parent | e35c3269edba151e1c703d87068a28ce2cd65bb0 (diff) | |
parent | d420895efb259a78dda50f95289571faa6e10e41 (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.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/dma.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 33 | ||||
-rw-r--r-- | drivers/net/wireless/prism54/islpci_eth.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 36 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00dev.c | 38 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00mac.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 36 |
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 | |||
3002 | drop_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); |
2379 | out: | 2379 | out: |
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 | |||
158 | exit_fail: | ||
159 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
160 | |||
161 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | ||
158 | } | 162 | } |
159 | 163 | ||
160 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 164 | static 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, ®); | 194 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
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 | |||
201 | exit_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 | ||
202 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | 208 | static 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 | ||
407 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | 399 | static 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 | } |
493 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 494 | EXPORT_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 | } |
436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 436 | EXPORT_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 | |||
154 | exit_fail: | ||
155 | mutex_unlock(&rt2x00dev->usb_cache_mutex); | ||
156 | |||
157 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
154 | } | 158 | } |
155 | 159 | ||
156 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 160 | static 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 | |||
196 | exit_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 | ||
197 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | 203 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, |