diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-06 08:23:39 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-06 08:23:39 -0400 |
commit | 68083e05d72d94f347293d8cc0067050ba904bfa (patch) | |
tree | 842e71365bd90866be7add181661a4039d891564 /drivers/net/wireless | |
parent | 7baac8b91f9871ba8cb09af84de4ae1d86d07812 (diff) | |
parent | b7279469d66b55119784b8b9529c99c1955fe747 (diff) |
Merge commit 'v2.6.26-rc9' into cpus4096
Diffstat (limited to 'drivers/net/wireless')
37 files changed, 478 insertions, 296 deletions
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 4e1c690ff45f..32019fb878d8 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -2905,7 +2905,7 @@ EXPORT_SYMBOL(init_airo_card); | |||
2905 | 2905 | ||
2906 | static int waitbusy (struct airo_info *ai) { | 2906 | static int waitbusy (struct airo_info *ai) { |
2907 | int delay = 0; | 2907 | int delay = 0; |
2908 | while ((IN4500 (ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { | 2908 | while ((IN4500(ai, COMMAND) & COMMAND_BUSY) && (delay < 10000)) { |
2909 | udelay (10); | 2909 | udelay (10); |
2910 | if ((++delay % 20) == 0) | 2910 | if ((++delay % 20) == 0) |
2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); | 2911 | OUT4500(ai, EVACK, EV_CLEARCOMMANDBUSY); |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 37783cdd301a..d3db298c05fc 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -630,7 +630,6 @@ struct b43_pio { | |||
630 | 630 | ||
631 | /* Context information for a noise calculation (Link Quality). */ | 631 | /* Context information for a noise calculation (Link Quality). */ |
632 | struct b43_noise_calculation { | 632 | struct b43_noise_calculation { |
633 | u8 channel_at_start; | ||
634 | bool calculation_running; | 633 | bool calculation_running; |
635 | u8 nr_samples; | 634 | u8 nr_samples; |
636 | s8 samples[8][4]; | 635 | s8 samples[8][4]; |
@@ -737,6 +736,7 @@ struct b43_wl { | |||
737 | struct ieee80211_tx_control beacon_txctl; | 736 | struct ieee80211_tx_control beacon_txctl; |
738 | bool beacon0_uploaded; | 737 | bool beacon0_uploaded; |
739 | bool beacon1_uploaded; | 738 | bool beacon1_uploaded; |
739 | bool beacon_templates_virgin; /* Never wrote the templates? */ | ||
740 | struct work_struct beacon_update_trigger; | 740 | struct work_struct beacon_update_trigger; |
741 | 741 | ||
742 | /* The current QOS parameters for the 4 queues. | 742 | /* The current QOS parameters for the 4 queues. |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 6dcbb3c87e72..e23f2f172bd7 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -795,24 +795,49 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
795 | { | 795 | { |
796 | struct b43_dmaring *ring; | 796 | struct b43_dmaring *ring; |
797 | int err; | 797 | int err; |
798 | int nr_slots; | ||
799 | dma_addr_t dma_test; | 798 | dma_addr_t dma_test; |
800 | 799 | ||
801 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); | 800 | ring = kzalloc(sizeof(*ring), GFP_KERNEL); |
802 | if (!ring) | 801 | if (!ring) |
803 | goto out; | 802 | goto out; |
804 | ring->type = type; | ||
805 | 803 | ||
806 | nr_slots = B43_RXRING_SLOTS; | 804 | ring->nr_slots = B43_RXRING_SLOTS; |
807 | if (for_tx) | 805 | if (for_tx) |
808 | nr_slots = B43_TXRING_SLOTS; | 806 | ring->nr_slots = B43_TXRING_SLOTS; |
809 | 807 | ||
810 | ring->meta = kcalloc(nr_slots, sizeof(struct b43_dmadesc_meta), | 808 | ring->meta = kcalloc(ring->nr_slots, sizeof(struct b43_dmadesc_meta), |
811 | GFP_KERNEL); | 809 | GFP_KERNEL); |
812 | if (!ring->meta) | 810 | if (!ring->meta) |
813 | goto err_kfree_ring; | 811 | goto err_kfree_ring; |
812 | |||
813 | ring->type = type; | ||
814 | ring->dev = dev; | ||
815 | ring->mmio_base = b43_dmacontroller_base(type, controller_index); | ||
816 | ring->index = controller_index; | ||
817 | if (type == B43_DMA_64BIT) | ||
818 | ring->ops = &dma64_ops; | ||
819 | else | ||
820 | ring->ops = &dma32_ops; | ||
814 | if (for_tx) { | 821 | if (for_tx) { |
815 | ring->txhdr_cache = kcalloc(nr_slots, | 822 | ring->tx = 1; |
823 | ring->current_slot = -1; | ||
824 | } else { | ||
825 | if (ring->index == 0) { | ||
826 | ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; | ||
827 | ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; | ||
828 | } else if (ring->index == 3) { | ||
829 | ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; | ||
830 | ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; | ||
831 | } else | ||
832 | B43_WARN_ON(1); | ||
833 | } | ||
834 | spin_lock_init(&ring->lock); | ||
835 | #ifdef CONFIG_B43_DEBUG | ||
836 | ring->last_injected_overflow = jiffies; | ||
837 | #endif | ||
838 | |||
839 | if (for_tx) { | ||
840 | ring->txhdr_cache = kcalloc(ring->nr_slots, | ||
816 | b43_txhdr_size(dev), | 841 | b43_txhdr_size(dev), |
817 | GFP_KERNEL); | 842 | GFP_KERNEL); |
818 | if (!ring->txhdr_cache) | 843 | if (!ring->txhdr_cache) |
@@ -828,7 +853,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
828 | b43_txhdr_size(dev), 1)) { | 853 | b43_txhdr_size(dev), 1)) { |
829 | /* ugh realloc */ | 854 | /* ugh realloc */ |
830 | kfree(ring->txhdr_cache); | 855 | kfree(ring->txhdr_cache); |
831 | ring->txhdr_cache = kcalloc(nr_slots, | 856 | ring->txhdr_cache = kcalloc(ring->nr_slots, |
832 | b43_txhdr_size(dev), | 857 | b43_txhdr_size(dev), |
833 | GFP_KERNEL | GFP_DMA); | 858 | GFP_KERNEL | GFP_DMA); |
834 | if (!ring->txhdr_cache) | 859 | if (!ring->txhdr_cache) |
@@ -853,32 +878,6 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
853 | DMA_TO_DEVICE); | 878 | DMA_TO_DEVICE); |
854 | } | 879 | } |
855 | 880 | ||
856 | ring->dev = dev; | ||
857 | ring->nr_slots = nr_slots; | ||
858 | ring->mmio_base = b43_dmacontroller_base(type, controller_index); | ||
859 | ring->index = controller_index; | ||
860 | if (type == B43_DMA_64BIT) | ||
861 | ring->ops = &dma64_ops; | ||
862 | else | ||
863 | ring->ops = &dma32_ops; | ||
864 | if (for_tx) { | ||
865 | ring->tx = 1; | ||
866 | ring->current_slot = -1; | ||
867 | } else { | ||
868 | if (ring->index == 0) { | ||
869 | ring->rx_buffersize = B43_DMA0_RX_BUFFERSIZE; | ||
870 | ring->frameoffset = B43_DMA0_RX_FRAMEOFFSET; | ||
871 | } else if (ring->index == 3) { | ||
872 | ring->rx_buffersize = B43_DMA3_RX_BUFFERSIZE; | ||
873 | ring->frameoffset = B43_DMA3_RX_FRAMEOFFSET; | ||
874 | } else | ||
875 | B43_WARN_ON(1); | ||
876 | } | ||
877 | spin_lock_init(&ring->lock); | ||
878 | #ifdef CONFIG_B43_DEBUG | ||
879 | ring->last_injected_overflow = jiffies; | ||
880 | #endif | ||
881 | |||
882 | err = alloc_ringmemory(ring); | 881 | err = alloc_ringmemory(ring); |
883 | if (err) | 882 | if (err) |
884 | goto err_kfree_txhdr_cache; | 883 | goto err_kfree_txhdr_cache; |
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 8fdba9415c04..a70827793086 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1145,7 +1145,6 @@ static void b43_generate_noise_sample(struct b43_wldev *dev) | |||
1145 | b43_jssi_write(dev, 0x7F7F7F7F); | 1145 | b43_jssi_write(dev, 0x7F7F7F7F); |
1146 | b43_write32(dev, B43_MMIO_MACCMD, | 1146 | b43_write32(dev, B43_MMIO_MACCMD, |
1147 | b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE); | 1147 | b43_read32(dev, B43_MMIO_MACCMD) | B43_MACCMD_BGNOISE); |
1148 | B43_WARN_ON(dev->noisecalc.channel_at_start != dev->phy.channel); | ||
1149 | } | 1148 | } |
1150 | 1149 | ||
1151 | static void b43_calculate_link_quality(struct b43_wldev *dev) | 1150 | static void b43_calculate_link_quality(struct b43_wldev *dev) |
@@ -1154,7 +1153,6 @@ static void b43_calculate_link_quality(struct b43_wldev *dev) | |||
1154 | 1153 | ||
1155 | if (dev->noisecalc.calculation_running) | 1154 | if (dev->noisecalc.calculation_running) |
1156 | return; | 1155 | return; |
1157 | dev->noisecalc.channel_at_start = dev->phy.channel; | ||
1158 | dev->noisecalc.calculation_running = 1; | 1156 | dev->noisecalc.calculation_running = 1; |
1159 | dev->noisecalc.nr_samples = 0; | 1157 | dev->noisecalc.nr_samples = 0; |
1160 | 1158 | ||
@@ -1171,9 +1169,16 @@ static void handle_irq_noise(struct b43_wldev *dev) | |||
1171 | 1169 | ||
1172 | /* Bottom half of Link Quality calculation. */ | 1170 | /* Bottom half of Link Quality calculation. */ |
1173 | 1171 | ||
1172 | /* Possible race condition: It might be possible that the user | ||
1173 | * changed to a different channel in the meantime since we | ||
1174 | * started the calculation. We ignore that fact, since it's | ||
1175 | * not really that much of a problem. The background noise is | ||
1176 | * an estimation only anyway. Slightly wrong results will get damped | ||
1177 | * by the averaging of the 8 sample rounds. Additionally the | ||
1178 | * value is shortlived. So it will be replaced by the next noise | ||
1179 | * calculation round soon. */ | ||
1180 | |||
1174 | B43_WARN_ON(!dev->noisecalc.calculation_running); | 1181 | B43_WARN_ON(!dev->noisecalc.calculation_running); |
1175 | if (dev->noisecalc.channel_at_start != phy->channel) | ||
1176 | goto drop_calculation; | ||
1177 | *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); | 1182 | *((__le32 *)noise) = cpu_to_le32(b43_jssi_read(dev)); |
1178 | if (noise[0] == 0x7F || noise[1] == 0x7F || | 1183 | if (noise[0] == 0x7F || noise[1] == 0x7F || |
1179 | noise[2] == 0x7F || noise[3] == 0x7F) | 1184 | noise[2] == 0x7F || noise[3] == 0x7F) |
@@ -1214,11 +1219,10 @@ static void handle_irq_noise(struct b43_wldev *dev) | |||
1214 | average -= 48; | 1219 | average -= 48; |
1215 | 1220 | ||
1216 | dev->stats.link_noise = average; | 1221 | dev->stats.link_noise = average; |
1217 | drop_calculation: | ||
1218 | dev->noisecalc.calculation_running = 0; | 1222 | dev->noisecalc.calculation_running = 0; |
1219 | return; | 1223 | return; |
1220 | } | 1224 | } |
1221 | generate_new: | 1225 | generate_new: |
1222 | b43_generate_noise_sample(dev); | 1226 | b43_generate_noise_sample(dev); |
1223 | } | 1227 | } |
1224 | 1228 | ||
@@ -1544,6 +1548,30 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev, | |||
1544 | kfree(probe_resp_data); | 1548 | kfree(probe_resp_data); |
1545 | } | 1549 | } |
1546 | 1550 | ||
1551 | static void b43_upload_beacon0(struct b43_wldev *dev) | ||
1552 | { | ||
1553 | struct b43_wl *wl = dev->wl; | ||
1554 | |||
1555 | if (wl->beacon0_uploaded) | ||
1556 | return; | ||
1557 | b43_write_beacon_template(dev, 0x68, 0x18); | ||
1558 | /* FIXME: Probe resp upload doesn't really belong here, | ||
1559 | * but we don't use that feature anyway. */ | ||
1560 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | ||
1561 | &__b43_ratetable[3]); | ||
1562 | wl->beacon0_uploaded = 1; | ||
1563 | } | ||
1564 | |||
1565 | static void b43_upload_beacon1(struct b43_wldev *dev) | ||
1566 | { | ||
1567 | struct b43_wl *wl = dev->wl; | ||
1568 | |||
1569 | if (wl->beacon1_uploaded) | ||
1570 | return; | ||
1571 | b43_write_beacon_template(dev, 0x468, 0x1A); | ||
1572 | wl->beacon1_uploaded = 1; | ||
1573 | } | ||
1574 | |||
1547 | static void handle_irq_beacon(struct b43_wldev *dev) | 1575 | static void handle_irq_beacon(struct b43_wldev *dev) |
1548 | { | 1576 | { |
1549 | struct b43_wl *wl = dev->wl; | 1577 | struct b43_wl *wl = dev->wl; |
@@ -1568,24 +1596,27 @@ static void handle_irq_beacon(struct b43_wldev *dev) | |||
1568 | return; | 1596 | return; |
1569 | } | 1597 | } |
1570 | 1598 | ||
1571 | if (!beacon0_valid) { | 1599 | if (unlikely(wl->beacon_templates_virgin)) { |
1572 | if (!wl->beacon0_uploaded) { | 1600 | /* We never uploaded a beacon before. |
1573 | b43_write_beacon_template(dev, 0x68, 0x18); | 1601 | * Upload both templates now, but only mark one valid. */ |
1574 | b43_write_probe_resp_template(dev, 0x268, 0x4A, | 1602 | wl->beacon_templates_virgin = 0; |
1575 | &__b43_ratetable[3]); | 1603 | b43_upload_beacon0(dev); |
1576 | wl->beacon0_uploaded = 1; | 1604 | b43_upload_beacon1(dev); |
1577 | } | ||
1578 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | 1605 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1579 | cmd |= B43_MACCMD_BEACON0_VALID; | 1606 | cmd |= B43_MACCMD_BEACON0_VALID; |
1580 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | 1607 | b43_write32(dev, B43_MMIO_MACCMD, cmd); |
1581 | } else if (!beacon1_valid) { | 1608 | } else { |
1582 | if (!wl->beacon1_uploaded) { | 1609 | if (!beacon0_valid) { |
1583 | b43_write_beacon_template(dev, 0x468, 0x1A); | 1610 | b43_upload_beacon0(dev); |
1584 | wl->beacon1_uploaded = 1; | 1611 | cmd = b43_read32(dev, B43_MMIO_MACCMD); |
1612 | cmd |= B43_MACCMD_BEACON0_VALID; | ||
1613 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1614 | } else if (!beacon1_valid) { | ||
1615 | b43_upload_beacon1(dev); | ||
1616 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1617 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1618 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1585 | } | 1619 | } |
1586 | cmd = b43_read32(dev, B43_MMIO_MACCMD); | ||
1587 | cmd |= B43_MACCMD_BEACON1_VALID; | ||
1588 | b43_write32(dev, B43_MMIO_MACCMD, cmd); | ||
1589 | } | 1620 | } |
1590 | } | 1621 | } |
1591 | 1622 | ||
@@ -2852,12 +2883,11 @@ static int b43_op_tx(struct ieee80211_hw *hw, | |||
2852 | 2883 | ||
2853 | if (unlikely(skb->len < 2 + 2 + 6)) { | 2884 | if (unlikely(skb->len < 2 + 2 + 6)) { |
2854 | /* Too short, this can't be a valid frame. */ | 2885 | /* Too short, this can't be a valid frame. */ |
2855 | dev_kfree_skb_any(skb); | 2886 | goto drop_packet; |
2856 | return NETDEV_TX_OK; | ||
2857 | } | 2887 | } |
2858 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); | 2888 | B43_WARN_ON(skb_shinfo(skb)->nr_frags); |
2859 | if (unlikely(!dev)) | 2889 | if (unlikely(!dev)) |
2860 | return NETDEV_TX_BUSY; | 2890 | goto drop_packet; |
2861 | 2891 | ||
2862 | /* Transmissions on seperate queues can run concurrently. */ | 2892 | /* Transmissions on seperate queues can run concurrently. */ |
2863 | read_lock_irqsave(&wl->tx_lock, flags); | 2893 | read_lock_irqsave(&wl->tx_lock, flags); |
@@ -2873,7 +2903,12 @@ static int b43_op_tx(struct ieee80211_hw *hw, | |||
2873 | read_unlock_irqrestore(&wl->tx_lock, flags); | 2903 | read_unlock_irqrestore(&wl->tx_lock, flags); |
2874 | 2904 | ||
2875 | if (unlikely(err)) | 2905 | if (unlikely(err)) |
2876 | return NETDEV_TX_BUSY; | 2906 | goto drop_packet; |
2907 | return NETDEV_TX_OK; | ||
2908 | |||
2909 | drop_packet: | ||
2910 | /* We can not transmit this packet. Drop it. */ | ||
2911 | dev_kfree_skb_any(skb); | ||
2877 | return NETDEV_TX_OK; | 2912 | return NETDEV_TX_OK; |
2878 | } | 2913 | } |
2879 | 2914 | ||
@@ -4073,6 +4108,9 @@ static int b43_op_start(struct ieee80211_hw *hw) | |||
4073 | wl->filter_flags = 0; | 4108 | wl->filter_flags = 0; |
4074 | wl->radiotap_enabled = 0; | 4109 | wl->radiotap_enabled = 0; |
4075 | b43_qos_clear(wl); | 4110 | b43_qos_clear(wl); |
4111 | wl->beacon0_uploaded = 0; | ||
4112 | wl->beacon1_uploaded = 0; | ||
4113 | wl->beacon_templates_virgin = 1; | ||
4076 | 4114 | ||
4077 | /* First register RFkill. | 4115 | /* First register RFkill. |
4078 | * LEDs that are registered later depend on it. */ | 4116 | * LEDs that are registered later depend on it. */ |
@@ -4241,7 +4279,9 @@ static void b43_chip_reset(struct work_struct *work) | |||
4241 | goto out; | 4279 | goto out; |
4242 | } | 4280 | } |
4243 | } | 4281 | } |
4244 | out: | 4282 | out: |
4283 | if (err) | ||
4284 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
4245 | mutex_unlock(&wl->mutex); | 4285 | mutex_unlock(&wl->mutex); |
4246 | if (err) | 4286 | if (err) |
4247 | b43err(wl, "Controller restart FAILED\n"); | 4287 | b43err(wl, "Controller restart FAILED\n"); |
@@ -4382,9 +4422,11 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
4382 | struct b43_wldev *wldev; | 4422 | struct b43_wldev *wldev; |
4383 | struct b43_wl *wl; | 4423 | struct b43_wl *wl; |
4384 | 4424 | ||
4425 | /* Do not cancel ieee80211-workqueue based work here. | ||
4426 | * See comment in b43_remove(). */ | ||
4427 | |||
4385 | wldev = ssb_get_drvdata(dev); | 4428 | wldev = ssb_get_drvdata(dev); |
4386 | wl = wldev->wl; | 4429 | wl = wldev->wl; |
4387 | cancel_work_sync(&wldev->restart_work); | ||
4388 | b43_debugfs_remove_device(wldev); | 4430 | b43_debugfs_remove_device(wldev); |
4389 | b43_wireless_core_detach(wldev); | 4431 | b43_wireless_core_detach(wldev); |
4390 | list_del(&wldev->list); | 4432 | list_del(&wldev->list); |
@@ -4569,6 +4611,10 @@ static void b43_remove(struct ssb_device *dev) | |||
4569 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 4611 | struct b43_wl *wl = ssb_get_devtypedata(dev); |
4570 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 4612 | struct b43_wldev *wldev = ssb_get_drvdata(dev); |
4571 | 4613 | ||
4614 | /* We must cancel any work here before unregistering from ieee80211, | ||
4615 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
4616 | cancel_work_sync(&wldev->restart_work); | ||
4617 | |||
4572 | B43_WARN_ON(!wl); | 4618 | B43_WARN_ON(!wl); |
4573 | if (wl->current_dev == wldev) | 4619 | if (wl->current_dev == wldev) |
4574 | ieee80211_unregister_hw(wl->hw); | 4620 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index c990f87b107a..93ddc1cbcc8b 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 14a5eea2573e..3e612d0a13e8 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
@@ -2378,8 +2378,10 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw, | |||
2378 | } else | 2378 | } else |
2379 | err = b43legacy_dma_tx(dev, skb, ctl); | 2379 | err = b43legacy_dma_tx(dev, skb, ctl); |
2380 | out: | 2380 | out: |
2381 | if (unlikely(err)) | 2381 | if (unlikely(err)) { |
2382 | return NETDEV_TX_BUSY; | 2382 | /* Drop the packet. */ |
2383 | dev_kfree_skb_any(skb); | ||
2384 | } | ||
2383 | return NETDEV_TX_OK; | 2385 | return NETDEV_TX_OK; |
2384 | } | 2386 | } |
2385 | 2387 | ||
@@ -3039,7 +3041,6 @@ static void b43legacy_set_pretbtt(struct b43legacy_wldev *dev) | |||
3039 | /* Locking: wl->mutex */ | 3041 | /* Locking: wl->mutex */ |
3040 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | 3042 | static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) |
3041 | { | 3043 | { |
3042 | struct b43legacy_wl *wl = dev->wl; | ||
3043 | struct b43legacy_phy *phy = &dev->phy; | 3044 | struct b43legacy_phy *phy = &dev->phy; |
3044 | u32 macctl; | 3045 | u32 macctl; |
3045 | 3046 | ||
@@ -3054,12 +3055,6 @@ static void b43legacy_wireless_core_exit(struct b43legacy_wldev *dev) | |||
3054 | macctl |= B43legacy_MACCTL_PSM_JMP0; | 3055 | macctl |= B43legacy_MACCTL_PSM_JMP0; |
3055 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); | 3056 | b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); |
3056 | 3057 | ||
3057 | mutex_unlock(&wl->mutex); | ||
3058 | /* Must unlock as it would otherwise deadlock. No races here. | ||
3059 | * Cancel possibly pending workqueues. */ | ||
3060 | cancel_work_sync(&dev->restart_work); | ||
3061 | mutex_lock(&wl->mutex); | ||
3062 | |||
3063 | b43legacy_leds_exit(dev); | 3058 | b43legacy_leds_exit(dev); |
3064 | b43legacy_rng_exit(dev->wl); | 3059 | b43legacy_rng_exit(dev->wl); |
3065 | b43legacy_pio_free(dev); | 3060 | b43legacy_pio_free(dev); |
@@ -3486,6 +3481,8 @@ static void b43legacy_chip_reset(struct work_struct *work) | |||
3486 | } | 3481 | } |
3487 | } | 3482 | } |
3488 | out: | 3483 | out: |
3484 | if (err) | ||
3485 | wl->current_dev = NULL; /* Failed to init the dev. */ | ||
3489 | mutex_unlock(&wl->mutex); | 3486 | mutex_unlock(&wl->mutex); |
3490 | if (err) | 3487 | if (err) |
3491 | b43legacyerr(wl, "Controller restart FAILED\n"); | 3488 | b43legacyerr(wl, "Controller restart FAILED\n"); |
@@ -3618,9 +3615,11 @@ static void b43legacy_one_core_detach(struct ssb_device *dev) | |||
3618 | struct b43legacy_wldev *wldev; | 3615 | struct b43legacy_wldev *wldev; |
3619 | struct b43legacy_wl *wl; | 3616 | struct b43legacy_wl *wl; |
3620 | 3617 | ||
3618 | /* Do not cancel ieee80211-workqueue based work here. | ||
3619 | * See comment in b43legacy_remove(). */ | ||
3620 | |||
3621 | wldev = ssb_get_drvdata(dev); | 3621 | wldev = ssb_get_drvdata(dev); |
3622 | wl = wldev->wl; | 3622 | wl = wldev->wl; |
3623 | cancel_work_sync(&wldev->restart_work); | ||
3624 | b43legacy_debugfs_remove_device(wldev); | 3623 | b43legacy_debugfs_remove_device(wldev); |
3625 | b43legacy_wireless_core_detach(wldev); | 3624 | b43legacy_wireless_core_detach(wldev); |
3626 | list_del(&wldev->list); | 3625 | list_del(&wldev->list); |
@@ -3789,6 +3788,10 @@ static void b43legacy_remove(struct ssb_device *dev) | |||
3789 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); | 3788 | struct b43legacy_wl *wl = ssb_get_devtypedata(dev); |
3790 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); | 3789 | struct b43legacy_wldev *wldev = ssb_get_drvdata(dev); |
3791 | 3790 | ||
3791 | /* We must cancel any work here before unregistering from ieee80211, | ||
3792 | * as the ieee80211 unreg will destroy the workqueue. */ | ||
3793 | cancel_work_sync(&wldev->restart_work); | ||
3794 | |||
3792 | B43legacy_WARN_ON(!wl); | 3795 | B43legacy_WARN_ON(!wl); |
3793 | if (wl->current_dev == wldev) | 3796 | if (wl->current_dev == wldev) |
3794 | ieee80211_unregister_hw(wl->hw); | 3797 | ieee80211_unregister_hw(wl->hw); |
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c index 4fd73809602e..020f450e9dba 100644 --- a/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/drivers/net/wireless/hostap/hostap_80211_rx.c | |||
@@ -64,7 +64,7 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, | |||
64 | int hdrlen, phdrlen, head_need, tail_need; | 64 | int hdrlen, phdrlen, head_need, tail_need; |
65 | u16 fc; | 65 | u16 fc; |
66 | int prism_header, ret; | 66 | int prism_header, ret; |
67 | struct ieee80211_hdr_4addr *hdr; | 67 | struct ieee80211_hdr_4addr *fhdr; |
68 | 68 | ||
69 | iface = netdev_priv(dev); | 69 | iface = netdev_priv(dev); |
70 | local = iface->local; | 70 | local = iface->local; |
@@ -83,8 +83,8 @@ int prism2_rx_80211(struct net_device *dev, struct sk_buff *skb, | |||
83 | phdrlen = 0; | 83 | phdrlen = 0; |
84 | } | 84 | } |
85 | 85 | ||
86 | hdr = (struct ieee80211_hdr_4addr *) skb->data; | 86 | fhdr = (struct ieee80211_hdr_4addr *) skb->data; |
87 | fc = le16_to_cpu(hdr->frame_ctl); | 87 | fc = le16_to_cpu(fhdr->frame_ctl); |
88 | 88 | ||
89 | if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) { | 89 | if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) { |
90 | printk(KERN_DEBUG "%s: dropped management frame with header " | 90 | printk(KERN_DEBUG "%s: dropped management frame with header " |
@@ -551,7 +551,7 @@ hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr, | |||
551 | hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || | 551 | hdr->addr1[2] != 0xff || hdr->addr1[3] != 0xff || |
552 | hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { | 552 | hdr->addr1[4] != 0xff || hdr->addr1[5] != 0xff)) { |
553 | /* RA (or BSSID) is not ours - drop */ | 553 | /* RA (or BSSID) is not ours - drop */ |
554 | PDEBUG(DEBUG_EXTRA, "%s: received WDS frame with " | 554 | PDEBUG(DEBUG_EXTRA2, "%s: received WDS frame with " |
555 | "not own or broadcast %s=%s\n", | 555 | "not own or broadcast %s=%s\n", |
556 | local->dev->name, | 556 | local->dev->name, |
557 | fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", | 557 | fc & IEEE80211_FCTL_FROMDS ? "RA" : "BSSID", |
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 0acd9589c48c..ab981afd481d 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
@@ -1930,7 +1930,7 @@ static void handle_pspoll(local_info_t *local, | |||
1930 | PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); | 1930 | PDEBUG(DEBUG_PS, " PSPOLL and AID[15:14] not set\n"); |
1931 | return; | 1931 | return; |
1932 | } | 1932 | } |
1933 | aid &= ~BIT(15) & ~BIT(14); | 1933 | aid &= ~(BIT(15) | BIT(14)); |
1934 | if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { | 1934 | if (aid == 0 || aid > MAX_AID_TABLE_SIZE) { |
1935 | PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); | 1935 | PDEBUG(DEBUG_PS, " invalid aid=%d\n", aid); |
1936 | return; | 1936 | return; |
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index ed4317a17cbb..80039a0ae027 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -533,10 +533,10 @@ static void prism2_detach(struct pcmcia_device *link) | |||
533 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) | 533 | do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) |
534 | 534 | ||
535 | #define CFG_CHECK2(fn, retf) \ | 535 | #define CFG_CHECK2(fn, retf) \ |
536 | do { int ret = (retf); \ | 536 | do { int _ret = (retf); \ |
537 | if (ret != 0) { \ | 537 | if (_ret != 0) { \ |
538 | PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ | 538 | PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", _ret); \ |
539 | cs_error(link, fn, ret); \ | 539 | cs_error(link, fn, _ret); \ |
540 | goto next_entry; \ | 540 | goto next_entry; \ |
541 | } \ | 541 | } \ |
542 | } while (0) | 542 | } while (0) |
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index cdf90c40f11b..936f52e3d95c 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c | |||
@@ -2835,7 +2835,7 @@ static void hostap_passive_scan(unsigned long data) | |||
2835 | { | 2835 | { |
2836 | local_info_t *local = (local_info_t *) data; | 2836 | local_info_t *local = (local_info_t *) data; |
2837 | struct net_device *dev = local->dev; | 2837 | struct net_device *dev = local->dev; |
2838 | u16 channel; | 2838 | u16 chan; |
2839 | 2839 | ||
2840 | if (local->passive_scan_interval <= 0) | 2840 | if (local->passive_scan_interval <= 0) |
2841 | return; | 2841 | return; |
@@ -2872,11 +2872,11 @@ static void hostap_passive_scan(unsigned long data) | |||
2872 | 2872 | ||
2873 | printk(KERN_DEBUG "%s: passive scan channel %d\n", | 2873 | printk(KERN_DEBUG "%s: passive scan channel %d\n", |
2874 | dev->name, local->passive_scan_channel); | 2874 | dev->name, local->passive_scan_channel); |
2875 | channel = local->passive_scan_channel; | 2875 | chan = local->passive_scan_channel; |
2876 | local->passive_scan_state = PASSIVE_SCAN_WAIT; | 2876 | local->passive_scan_state = PASSIVE_SCAN_WAIT; |
2877 | local->passive_scan_timer.expires = jiffies + HZ / 10; | 2877 | local->passive_scan_timer.expires = jiffies + HZ / 10; |
2878 | } else { | 2878 | } else { |
2879 | channel = local->channel; | 2879 | chan = local->channel; |
2880 | local->passive_scan_state = PASSIVE_SCAN_LISTEN; | 2880 | local->passive_scan_state = PASSIVE_SCAN_LISTEN; |
2881 | local->passive_scan_timer.expires = jiffies + | 2881 | local->passive_scan_timer.expires = jiffies + |
2882 | local->passive_scan_interval * HZ; | 2882 | local->passive_scan_interval * HZ; |
@@ -2884,9 +2884,9 @@ static void hostap_passive_scan(unsigned long data) | |||
2884 | 2884 | ||
2885 | if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | | 2885 | if (hfa384x_cmd_callback(dev, HFA384X_CMDCODE_TEST | |
2886 | (HFA384X_TEST_CHANGE_CHANNEL << 8), | 2886 | (HFA384X_TEST_CHANGE_CHANNEL << 8), |
2887 | channel, NULL, 0)) | 2887 | chan, NULL, 0)) |
2888 | printk(KERN_ERR "%s: passive scan channel set %d " | 2888 | printk(KERN_ERR "%s: passive scan channel set %d " |
2889 | "failed\n", dev->name, channel); | 2889 | "failed\n", dev->name, chan); |
2890 | 2890 | ||
2891 | add_timer(&local->passive_scan_timer); | 2891 | add_timer(&local->passive_scan_timer); |
2892 | } | 2892 | } |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 20d387f6658c..a38e85f334df 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -594,7 +594,8 @@ void hostap_dump_tx_header(const char *name, const struct hfa384x_tx_frame *tx) | |||
594 | } | 594 | } |
595 | 595 | ||
596 | 596 | ||
597 | int hostap_80211_header_parse(const struct sk_buff *skb, unsigned char *haddr) | 597 | static int hostap_80211_header_parse(const struct sk_buff *skb, |
598 | unsigned char *haddr) | ||
598 | { | 599 | { |
599 | struct hostap_interface *iface = netdev_priv(skb->dev); | 600 | struct hostap_interface *iface = netdev_priv(skb->dev); |
600 | local_info_t *local = iface->local; | 601 | local_info_t *local = iface->local; |
@@ -682,7 +683,13 @@ static int prism2_close(struct net_device *dev) | |||
682 | netif_device_detach(dev); | 683 | netif_device_detach(dev); |
683 | } | 684 | } |
684 | 685 | ||
685 | flush_scheduled_work(); | 686 | cancel_work_sync(&local->reset_queue); |
687 | cancel_work_sync(&local->set_multicast_list_queue); | ||
688 | cancel_work_sync(&local->set_tim_queue); | ||
689 | #ifndef PRISM2_NO_STATION_MODES | ||
690 | cancel_work_sync(&local->info_queue); | ||
691 | #endif | ||
692 | cancel_work_sync(&local->comms_qual_update); | ||
686 | 693 | ||
687 | module_put(local->hw_module); | 694 | module_put(local->hw_module); |
688 | 695 | ||
@@ -851,7 +858,6 @@ const struct header_ops hostap_80211_ops = { | |||
851 | .rebuild = eth_rebuild_header, | 858 | .rebuild = eth_rebuild_header, |
852 | .cache = eth_header_cache, | 859 | .cache = eth_header_cache, |
853 | .cache_update = eth_header_cache_update, | 860 | .cache_update = eth_header_cache_update, |
854 | |||
855 | .parse = hostap_80211_header_parse, | 861 | .parse = hostap_80211_header_parse, |
856 | }; | 862 | }; |
857 | EXPORT_SYMBOL(hostap_80211_ops); | 863 | EXPORT_SYMBOL(hostap_80211_ops); |
@@ -1144,7 +1150,6 @@ EXPORT_SYMBOL(hostap_set_roaming); | |||
1144 | EXPORT_SYMBOL(hostap_set_auth_algs); | 1150 | EXPORT_SYMBOL(hostap_set_auth_algs); |
1145 | EXPORT_SYMBOL(hostap_dump_rx_header); | 1151 | EXPORT_SYMBOL(hostap_dump_rx_header); |
1146 | EXPORT_SYMBOL(hostap_dump_tx_header); | 1152 | EXPORT_SYMBOL(hostap_dump_tx_header); |
1147 | EXPORT_SYMBOL(hostap_80211_header_parse); | ||
1148 | EXPORT_SYMBOL(hostap_80211_get_hdrlen); | 1153 | EXPORT_SYMBOL(hostap_80211_get_hdrlen); |
1149 | EXPORT_SYMBOL(hostap_get_stats); | 1154 | EXPORT_SYMBOL(hostap_get_stats); |
1150 | EXPORT_SYMBOL(hostap_setup_dev); | 1155 | EXPORT_SYMBOL(hostap_setup_dev); |
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index d74c061994ae..6e704608947c 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -1753,6 +1753,8 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio) | |||
1753 | 1753 | ||
1754 | if (priv->workqueue) { | 1754 | if (priv->workqueue) { |
1755 | cancel_delayed_work(&priv->request_scan); | 1755 | cancel_delayed_work(&priv->request_scan); |
1756 | cancel_delayed_work(&priv->request_direct_scan); | ||
1757 | cancel_delayed_work(&priv->request_passive_scan); | ||
1756 | cancel_delayed_work(&priv->scan_event); | 1758 | cancel_delayed_work(&priv->scan_event); |
1757 | } | 1759 | } |
1758 | queue_work(priv->workqueue, &priv->down); | 1760 | queue_work(priv->workqueue, &priv->down); |
@@ -2005,6 +2007,8 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
2005 | wake_up_interruptible(&priv->wait_command_queue); | 2007 | wake_up_interruptible(&priv->wait_command_queue); |
2006 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); | 2008 | priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING); |
2007 | cancel_delayed_work(&priv->request_scan); | 2009 | cancel_delayed_work(&priv->request_scan); |
2010 | cancel_delayed_work(&priv->request_direct_scan); | ||
2011 | cancel_delayed_work(&priv->request_passive_scan); | ||
2008 | cancel_delayed_work(&priv->scan_event); | 2012 | cancel_delayed_work(&priv->scan_event); |
2009 | schedule_work(&priv->link_down); | 2013 | schedule_work(&priv->link_down); |
2010 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); | 2014 | queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ); |
@@ -4712,6 +4716,12 @@ static void ipw_rx_notification(struct ipw_priv *priv, | |||
4712 | priv->status &= ~STATUS_SCAN_FORCED; | 4716 | priv->status &= ~STATUS_SCAN_FORCED; |
4713 | #endif /* CONFIG_IPW2200_MONITOR */ | 4717 | #endif /* CONFIG_IPW2200_MONITOR */ |
4714 | 4718 | ||
4719 | /* Do queued direct scans first */ | ||
4720 | if (priv->status & STATUS_DIRECT_SCAN_PENDING) { | ||
4721 | queue_delayed_work(priv->workqueue, | ||
4722 | &priv->request_direct_scan, 0); | ||
4723 | } | ||
4724 | |||
4715 | if (!(priv->status & (STATUS_ASSOCIATED | | 4725 | if (!(priv->status & (STATUS_ASSOCIATED | |
4716 | STATUS_ASSOCIATING | | 4726 | STATUS_ASSOCIATING | |
4717 | STATUS_ROAMING | | 4727 | STATUS_ROAMING | |
@@ -6267,7 +6277,7 @@ static void ipw_add_scan_channels(struct ipw_priv *priv, | |||
6267 | } | 6277 | } |
6268 | } | 6278 | } |
6269 | 6279 | ||
6270 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | 6280 | static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct) |
6271 | { | 6281 | { |
6272 | struct ipw_scan_request_ext scan; | 6282 | struct ipw_scan_request_ext scan; |
6273 | int err = 0, scan_type; | 6283 | int err = 0, scan_type; |
@@ -6278,22 +6288,31 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6278 | 6288 | ||
6279 | mutex_lock(&priv->mutex); | 6289 | mutex_lock(&priv->mutex); |
6280 | 6290 | ||
6291 | if (direct && (priv->direct_scan_ssid_len == 0)) { | ||
6292 | IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n"); | ||
6293 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6294 | goto done; | ||
6295 | } | ||
6296 | |||
6281 | if (priv->status & STATUS_SCANNING) { | 6297 | if (priv->status & STATUS_SCANNING) { |
6282 | IPW_DEBUG_HC("Concurrent scan requested. Ignoring.\n"); | 6298 | IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n"); |
6283 | priv->status |= STATUS_SCAN_PENDING; | 6299 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6300 | STATUS_SCAN_PENDING; | ||
6284 | goto done; | 6301 | goto done; |
6285 | } | 6302 | } |
6286 | 6303 | ||
6287 | if (!(priv->status & STATUS_SCAN_FORCED) && | 6304 | if (!(priv->status & STATUS_SCAN_FORCED) && |
6288 | priv->status & STATUS_SCAN_ABORTING) { | 6305 | priv->status & STATUS_SCAN_ABORTING) { |
6289 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); | 6306 | IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n"); |
6290 | priv->status |= STATUS_SCAN_PENDING; | 6307 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6308 | STATUS_SCAN_PENDING; | ||
6291 | goto done; | 6309 | goto done; |
6292 | } | 6310 | } |
6293 | 6311 | ||
6294 | if (priv->status & STATUS_RF_KILL_MASK) { | 6312 | if (priv->status & STATUS_RF_KILL_MASK) { |
6295 | IPW_DEBUG_HC("Aborting scan due to RF Kill activation\n"); | 6313 | IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n"); |
6296 | priv->status |= STATUS_SCAN_PENDING; | 6314 | priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING : |
6315 | STATUS_SCAN_PENDING; | ||
6297 | goto done; | 6316 | goto done; |
6298 | } | 6317 | } |
6299 | 6318 | ||
@@ -6321,6 +6340,7 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6321 | cpu_to_le16(20); | 6340 | cpu_to_le16(20); |
6322 | 6341 | ||
6323 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | 6342 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); |
6343 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
6324 | 6344 | ||
6325 | #ifdef CONFIG_IPW2200_MONITOR | 6345 | #ifdef CONFIG_IPW2200_MONITOR |
6326 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { | 6346 | if (priv->ieee->iw_mode == IW_MODE_MONITOR) { |
@@ -6360,13 +6380,23 @@ static int ipw_request_scan_helper(struct ipw_priv *priv, int type) | |||
6360 | cpu_to_le16(2000); | 6380 | cpu_to_le16(2000); |
6361 | } else { | 6381 | } else { |
6362 | #endif /* CONFIG_IPW2200_MONITOR */ | 6382 | #endif /* CONFIG_IPW2200_MONITOR */ |
6363 | /* If we are roaming, then make this a directed scan for the | 6383 | /* Honor direct scans first, otherwise if we are roaming make |
6364 | * current network. Otherwise, ensure that every other scan | 6384 | * this a direct scan for the current network. Finally, |
6365 | * is a fast channel hop scan */ | 6385 | * ensure that every other scan is a fast channel hop scan */ |
6366 | if ((priv->status & STATUS_ROAMING) | 6386 | if (direct) { |
6367 | || (!(priv->status & STATUS_ASSOCIATED) | 6387 | err = ipw_send_ssid(priv, priv->direct_scan_ssid, |
6368 | && (priv->config & CFG_STATIC_ESSID) | 6388 | priv->direct_scan_ssid_len); |
6369 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | 6389 | if (err) { |
6390 | IPW_DEBUG_HC("Attempt to send SSID command " | ||
6391 | "failed\n"); | ||
6392 | goto done; | ||
6393 | } | ||
6394 | |||
6395 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
6396 | } else if ((priv->status & STATUS_ROAMING) | ||
6397 | || (!(priv->status & STATUS_ASSOCIATED) | ||
6398 | && (priv->config & CFG_STATIC_ESSID) | ||
6399 | && (le32_to_cpu(scan.full_scan_index) % 2))) { | ||
6370 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); | 6400 | err = ipw_send_ssid(priv, priv->essid, priv->essid_len); |
6371 | if (err) { | 6401 | if (err) { |
6372 | IPW_DEBUG_HC("Attempt to send SSID command " | 6402 | IPW_DEBUG_HC("Attempt to send SSID command " |
@@ -6391,7 +6421,12 @@ send_request: | |||
6391 | } | 6421 | } |
6392 | 6422 | ||
6393 | priv->status |= STATUS_SCANNING; | 6423 | priv->status |= STATUS_SCANNING; |
6394 | priv->status &= ~STATUS_SCAN_PENDING; | 6424 | if (direct) { |
6425 | priv->status &= ~STATUS_DIRECT_SCAN_PENDING; | ||
6426 | priv->direct_scan_ssid_len = 0; | ||
6427 | } else | ||
6428 | priv->status &= ~STATUS_SCAN_PENDING; | ||
6429 | |||
6395 | queue_delayed_work(priv->workqueue, &priv->scan_check, | 6430 | queue_delayed_work(priv->workqueue, &priv->scan_check, |
6396 | IPW_SCAN_CHECK_WATCHDOG); | 6431 | IPW_SCAN_CHECK_WATCHDOG); |
6397 | done: | 6432 | done: |
@@ -6402,15 +6437,22 @@ done: | |||
6402 | static void ipw_request_passive_scan(struct work_struct *work) | 6437 | static void ipw_request_passive_scan(struct work_struct *work) |
6403 | { | 6438 | { |
6404 | struct ipw_priv *priv = | 6439 | struct ipw_priv *priv = |
6405 | container_of(work, struct ipw_priv, request_passive_scan); | 6440 | container_of(work, struct ipw_priv, request_passive_scan.work); |
6406 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE); | 6441 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0); |
6407 | } | 6442 | } |
6408 | 6443 | ||
6409 | static void ipw_request_scan(struct work_struct *work) | 6444 | static void ipw_request_scan(struct work_struct *work) |
6410 | { | 6445 | { |
6411 | struct ipw_priv *priv = | 6446 | struct ipw_priv *priv = |
6412 | container_of(work, struct ipw_priv, request_scan.work); | 6447 | container_of(work, struct ipw_priv, request_scan.work); |
6413 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE); | 6448 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0); |
6449 | } | ||
6450 | |||
6451 | static void ipw_request_direct_scan(struct work_struct *work) | ||
6452 | { | ||
6453 | struct ipw_priv *priv = | ||
6454 | container_of(work, struct ipw_priv, request_direct_scan.work); | ||
6455 | ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1); | ||
6414 | } | 6456 | } |
6415 | 6457 | ||
6416 | static void ipw_bg_abort_scan(struct work_struct *work) | 6458 | static void ipw_bg_abort_scan(struct work_struct *work) |
@@ -7558,8 +7600,31 @@ static int ipw_associate(void *data) | |||
7558 | priv->ieee->iw_mode == IW_MODE_ADHOC && | 7600 | priv->ieee->iw_mode == IW_MODE_ADHOC && |
7559 | priv->config & CFG_ADHOC_CREATE && | 7601 | priv->config & CFG_ADHOC_CREATE && |
7560 | priv->config & CFG_STATIC_ESSID && | 7602 | priv->config & CFG_STATIC_ESSID && |
7561 | priv->config & CFG_STATIC_CHANNEL && | 7603 | priv->config & CFG_STATIC_CHANNEL) { |
7562 | !list_empty(&priv->ieee->network_free_list)) { | 7604 | /* Use oldest network if the free list is empty */ |
7605 | if (list_empty(&priv->ieee->network_free_list)) { | ||
7606 | struct ieee80211_network *oldest = NULL; | ||
7607 | struct ieee80211_network *target; | ||
7608 | DECLARE_MAC_BUF(mac); | ||
7609 | |||
7610 | list_for_each_entry(target, &priv->ieee->network_list, list) { | ||
7611 | if ((oldest == NULL) || | ||
7612 | (target->last_scanned < oldest->last_scanned)) | ||
7613 | oldest = target; | ||
7614 | } | ||
7615 | |||
7616 | /* If there are no more slots, expire the oldest */ | ||
7617 | list_del(&oldest->list); | ||
7618 | target = oldest; | ||
7619 | IPW_DEBUG_ASSOC("Expired '%s' (%s) from " | ||
7620 | "network list.\n", | ||
7621 | escape_essid(target->ssid, | ||
7622 | target->ssid_len), | ||
7623 | print_mac(mac, target->bssid)); | ||
7624 | list_add_tail(&target->list, | ||
7625 | &priv->ieee->network_free_list); | ||
7626 | } | ||
7627 | |||
7563 | element = priv->ieee->network_free_list.next; | 7628 | element = priv->ieee->network_free_list.next; |
7564 | network = list_entry(element, struct ieee80211_network, list); | 7629 | network = list_entry(element, struct ieee80211_network, list); |
7565 | ipw_adhoc_create(priv, network); | 7630 | ipw_adhoc_create(priv, network); |
@@ -9454,99 +9519,38 @@ static int ipw_wx_get_retry(struct net_device *dev, | |||
9454 | return 0; | 9519 | return 0; |
9455 | } | 9520 | } |
9456 | 9521 | ||
9457 | static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, | ||
9458 | int essid_len) | ||
9459 | { | ||
9460 | struct ipw_scan_request_ext scan; | ||
9461 | int err = 0, scan_type; | ||
9462 | |||
9463 | if (!(priv->status & STATUS_INIT) || | ||
9464 | (priv->status & STATUS_EXIT_PENDING)) | ||
9465 | return 0; | ||
9466 | |||
9467 | mutex_lock(&priv->mutex); | ||
9468 | |||
9469 | if (priv->status & STATUS_RF_KILL_MASK) { | ||
9470 | IPW_DEBUG_HC("Aborting scan due to RF kill activation\n"); | ||
9471 | priv->status |= STATUS_SCAN_PENDING; | ||
9472 | goto done; | ||
9473 | } | ||
9474 | |||
9475 | IPW_DEBUG_HC("starting request direct scan!\n"); | ||
9476 | |||
9477 | if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { | ||
9478 | /* We should not sleep here; otherwise we will block most | ||
9479 | * of the system (for instance, we hold rtnl_lock when we | ||
9480 | * get here). | ||
9481 | */ | ||
9482 | err = -EAGAIN; | ||
9483 | goto done; | ||
9484 | } | ||
9485 | memset(&scan, 0, sizeof(scan)); | ||
9486 | |||
9487 | if (priv->config & CFG_SPEED_SCAN) | ||
9488 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9489 | cpu_to_le16(30); | ||
9490 | else | ||
9491 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = | ||
9492 | cpu_to_le16(20); | ||
9493 | |||
9494 | scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = | ||
9495 | cpu_to_le16(20); | ||
9496 | scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120); | ||
9497 | scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20); | ||
9498 | |||
9499 | scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee)); | ||
9500 | |||
9501 | err = ipw_send_ssid(priv, essid, essid_len); | ||
9502 | if (err) { | ||
9503 | IPW_DEBUG_HC("Attempt to send SSID command failed\n"); | ||
9504 | goto done; | ||
9505 | } | ||
9506 | scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN; | ||
9507 | |||
9508 | ipw_add_scan_channels(priv, &scan, scan_type); | ||
9509 | |||
9510 | err = ipw_send_scan_request_ext(priv, &scan); | ||
9511 | if (err) { | ||
9512 | IPW_DEBUG_HC("Sending scan command failed: %08X\n", err); | ||
9513 | goto done; | ||
9514 | } | ||
9515 | |||
9516 | priv->status |= STATUS_SCANNING; | ||
9517 | |||
9518 | done: | ||
9519 | mutex_unlock(&priv->mutex); | ||
9520 | return err; | ||
9521 | } | ||
9522 | |||
9523 | static int ipw_wx_set_scan(struct net_device *dev, | 9522 | static int ipw_wx_set_scan(struct net_device *dev, |
9524 | struct iw_request_info *info, | 9523 | struct iw_request_info *info, |
9525 | union iwreq_data *wrqu, char *extra) | 9524 | union iwreq_data *wrqu, char *extra) |
9526 | { | 9525 | { |
9527 | struct ipw_priv *priv = ieee80211_priv(dev); | 9526 | struct ipw_priv *priv = ieee80211_priv(dev); |
9528 | struct iw_scan_req *req = (struct iw_scan_req *)extra; | 9527 | struct iw_scan_req *req = (struct iw_scan_req *)extra; |
9528 | struct delayed_work *work = NULL; | ||
9529 | 9529 | ||
9530 | mutex_lock(&priv->mutex); | 9530 | mutex_lock(&priv->mutex); |
9531 | |||
9531 | priv->user_requested_scan = 1; | 9532 | priv->user_requested_scan = 1; |
9532 | mutex_unlock(&priv->mutex); | ||
9533 | 9533 | ||
9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { | 9534 | if (wrqu->data.length == sizeof(struct iw_scan_req)) { |
9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { | 9535 | if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { |
9536 | ipw_request_direct_scan(priv, req->essid, | 9536 | int len = min((int)req->essid_len, |
9537 | req->essid_len); | 9537 | (int)sizeof(priv->direct_scan_ssid)); |
9538 | return 0; | 9538 | memcpy(priv->direct_scan_ssid, req->essid, len); |
9539 | } | 9539 | priv->direct_scan_ssid_len = len; |
9540 | if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { | 9540 | work = &priv->request_direct_scan; |
9541 | queue_work(priv->workqueue, | 9541 | } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) { |
9542 | &priv->request_passive_scan); | 9542 | work = &priv->request_passive_scan; |
9543 | return 0; | ||
9544 | } | 9543 | } |
9544 | } else { | ||
9545 | /* Normal active broadcast scan */ | ||
9546 | work = &priv->request_scan; | ||
9545 | } | 9547 | } |
9546 | 9548 | ||
9549 | mutex_unlock(&priv->mutex); | ||
9550 | |||
9547 | IPW_DEBUG_WX("Start scan\n"); | 9551 | IPW_DEBUG_WX("Start scan\n"); |
9548 | 9552 | ||
9549 | queue_delayed_work(priv->workqueue, &priv->request_scan, 0); | 9553 | queue_delayed_work(priv->workqueue, work, 0); |
9550 | 9554 | ||
9551 | return 0; | 9555 | return 0; |
9552 | } | 9556 | } |
@@ -10708,6 +10712,8 @@ static void ipw_link_up(struct ipw_priv *priv) | |||
10708 | } | 10712 | } |
10709 | 10713 | ||
10710 | cancel_delayed_work(&priv->request_scan); | 10714 | cancel_delayed_work(&priv->request_scan); |
10715 | cancel_delayed_work(&priv->request_direct_scan); | ||
10716 | cancel_delayed_work(&priv->request_passive_scan); | ||
10711 | cancel_delayed_work(&priv->scan_event); | 10717 | cancel_delayed_work(&priv->scan_event); |
10712 | ipw_reset_stats(priv); | 10718 | ipw_reset_stats(priv); |
10713 | /* Ensure the rate is updated immediately */ | 10719 | /* Ensure the rate is updated immediately */ |
@@ -10738,6 +10744,8 @@ static void ipw_link_down(struct ipw_priv *priv) | |||
10738 | 10744 | ||
10739 | /* Cancel any queued work ... */ | 10745 | /* Cancel any queued work ... */ |
10740 | cancel_delayed_work(&priv->request_scan); | 10746 | cancel_delayed_work(&priv->request_scan); |
10747 | cancel_delayed_work(&priv->request_direct_scan); | ||
10748 | cancel_delayed_work(&priv->request_passive_scan); | ||
10741 | cancel_delayed_work(&priv->adhoc_check); | 10749 | cancel_delayed_work(&priv->adhoc_check); |
10742 | cancel_delayed_work(&priv->gather_stats); | 10750 | cancel_delayed_work(&priv->gather_stats); |
10743 | 10751 | ||
@@ -10777,8 +10785,9 @@ static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) | |||
10777 | INIT_WORK(&priv->up, ipw_bg_up); | 10785 | INIT_WORK(&priv->up, ipw_bg_up); |
10778 | INIT_WORK(&priv->down, ipw_bg_down); | 10786 | INIT_WORK(&priv->down, ipw_bg_down); |
10779 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); | 10787 | INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan); |
10788 | INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan); | ||
10789 | INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10780 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); | 10790 | INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event); |
10781 | INIT_WORK(&priv->request_passive_scan, ipw_request_passive_scan); | ||
10782 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); | 10791 | INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats); |
10783 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); | 10792 | INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan); |
10784 | INIT_WORK(&priv->roam, ipw_bg_roam); | 10793 | INIT_WORK(&priv->roam, ipw_bg_roam); |
@@ -11812,6 +11821,8 @@ static void __devexit ipw_pci_remove(struct pci_dev *pdev) | |||
11812 | cancel_delayed_work(&priv->adhoc_check); | 11821 | cancel_delayed_work(&priv->adhoc_check); |
11813 | cancel_delayed_work(&priv->gather_stats); | 11822 | cancel_delayed_work(&priv->gather_stats); |
11814 | cancel_delayed_work(&priv->request_scan); | 11823 | cancel_delayed_work(&priv->request_scan); |
11824 | cancel_delayed_work(&priv->request_direct_scan); | ||
11825 | cancel_delayed_work(&priv->request_passive_scan); | ||
11815 | cancel_delayed_work(&priv->scan_event); | 11826 | cancel_delayed_work(&priv->scan_event); |
11816 | cancel_delayed_work(&priv->rf_kill); | 11827 | cancel_delayed_work(&priv->rf_kill); |
11817 | cancel_delayed_work(&priv->scan_check); | 11828 | cancel_delayed_work(&priv->scan_check); |
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h index cd3295b66dd6..d4ab28b73b32 100644 --- a/drivers/net/wireless/ipw2200.h +++ b/drivers/net/wireless/ipw2200.h | |||
@@ -1037,6 +1037,7 @@ struct ipw_cmd { /* XXX */ | |||
1037 | #define STATUS_DISASSOC_PENDING (1<<12) | 1037 | #define STATUS_DISASSOC_PENDING (1<<12) |
1038 | #define STATUS_STATE_PENDING (1<<13) | 1038 | #define STATUS_STATE_PENDING (1<<13) |
1039 | 1039 | ||
1040 | #define STATUS_DIRECT_SCAN_PENDING (1<<19) | ||
1040 | #define STATUS_SCAN_PENDING (1<<20) | 1041 | #define STATUS_SCAN_PENDING (1<<20) |
1041 | #define STATUS_SCANNING (1<<21) | 1042 | #define STATUS_SCANNING (1<<21) |
1042 | #define STATUS_SCAN_ABORTING (1<<22) | 1043 | #define STATUS_SCAN_ABORTING (1<<22) |
@@ -1292,6 +1293,8 @@ struct ipw_priv { | |||
1292 | struct iw_public_data wireless_data; | 1293 | struct iw_public_data wireless_data; |
1293 | 1294 | ||
1294 | int user_requested_scan; | 1295 | int user_requested_scan; |
1296 | u8 direct_scan_ssid[IW_ESSID_MAX_SIZE]; | ||
1297 | u8 direct_scan_ssid_len; | ||
1295 | 1298 | ||
1296 | struct workqueue_struct *workqueue; | 1299 | struct workqueue_struct *workqueue; |
1297 | 1300 | ||
@@ -1301,8 +1304,9 @@ struct ipw_priv { | |||
1301 | struct work_struct system_config; | 1304 | struct work_struct system_config; |
1302 | struct work_struct rx_replenish; | 1305 | struct work_struct rx_replenish; |
1303 | struct delayed_work request_scan; | 1306 | struct delayed_work request_scan; |
1307 | struct delayed_work request_direct_scan; | ||
1308 | struct delayed_work request_passive_scan; | ||
1304 | struct delayed_work scan_event; | 1309 | struct delayed_work scan_event; |
1305 | struct work_struct request_passive_scan; | ||
1306 | struct work_struct adapter_restart; | 1310 | struct work_struct adapter_restart; |
1307 | struct delayed_work rf_kill; | 1311 | struct delayed_work rf_kill; |
1308 | struct work_struct up; | 1312 | struct work_struct up; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c index d200d08fb086..8b1528e52d43 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c | |||
@@ -229,14 +229,15 @@ static int iwl3945_led_register_led(struct iwl3945_priv *priv, | |||
229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; | 229 | led->led_dev.brightness_set = iwl3945_led_brightness_set; |
230 | led->led_dev.default_trigger = trigger; | 230 | led->led_dev.default_trigger = trigger; |
231 | 231 | ||
232 | led->priv = priv; | ||
233 | led->type = type; | ||
234 | |||
232 | ret = led_classdev_register(device, &led->led_dev); | 235 | ret = led_classdev_register(device, &led->led_dev); |
233 | if (ret) { | 236 | if (ret) { |
234 | IWL_ERROR("Error: failed to register led handler.\n"); | 237 | IWL_ERROR("Error: failed to register led handler.\n"); |
235 | return ret; | 238 | return ret; |
236 | } | 239 | } |
237 | 240 | ||
238 | led->priv = priv; | ||
239 | led->type = type; | ||
240 | led->registered = 1; | 241 | led->registered = 1; |
241 | 242 | ||
242 | if (set_led && led->led_on) | 243 | if (set_led && led->led_on) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c index c9847b1a67f7..3a7f0cb710ec 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c | |||
@@ -1162,7 +1162,6 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, | |||
1162 | 1162 | ||
1163 | /* Higher rate not available, use the original */ | 1163 | /* Higher rate not available, use the original */ |
1164 | } else { | 1164 | } else { |
1165 | new_rate = rate; | ||
1166 | break; | 1165 | break; |
1167 | } | 1166 | } |
1168 | } | 1167 | } |
@@ -2009,7 +2008,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, | |||
2009 | * 2) Not just finishing up a search | 2008 | * 2) Not just finishing up a search |
2010 | * 3) Allowing a new search | 2009 | * 3) Allowing a new search |
2011 | */ | 2010 | */ |
2012 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl) { | 2011 | if (!update_lq && !done_search && !lq_sta->stay_in_tbl && window->counter) { |
2013 | /* Save current throughput to compare with "search" throughput*/ | 2012 | /* Save current throughput to compare with "search" throughput*/ |
2014 | lq_sta->last_tpt = current_tpt; | 2013 | lq_sta->last_tpt = current_tpt; |
2015 | 2014 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 13925b627e3b..b1b3c523185d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2227,7 +2227,10 @@ static int iwl3945_scan_initiate(struct iwl3945_priv *priv) | |||
2227 | } | 2227 | } |
2228 | 2228 | ||
2229 | IWL_DEBUG_INFO("Starting scan...\n"); | 2229 | IWL_DEBUG_INFO("Starting scan...\n"); |
2230 | priv->scan_bands = 2; | 2230 | if (priv->cfg->sku & IWL_SKU_G) |
2231 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
2232 | if (priv->cfg->sku & IWL_SKU_A) | ||
2233 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
2231 | set_bit(STATUS_SCANNING, &priv->status); | 2234 | set_bit(STATUS_SCANNING, &priv->status); |
2232 | priv->scan_start = jiffies; | 2235 | priv->scan_start = jiffies; |
2233 | priv->scan_pass_start = priv->scan_start; | 2236 | priv->scan_pass_start = priv->scan_start; |
@@ -3352,13 +3355,18 @@ static void iwl3945_rx_scan_complete_notif(struct iwl3945_priv *priv, | |||
3352 | cancel_delayed_work(&priv->scan_check); | 3355 | cancel_delayed_work(&priv->scan_check); |
3353 | 3356 | ||
3354 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 3357 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
3355 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 3358 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
3359 | "2.4" : "5.2", | ||
3356 | jiffies_to_msecs(elapsed_jiffies | 3360 | jiffies_to_msecs(elapsed_jiffies |
3357 | (priv->scan_pass_start, jiffies))); | 3361 | (priv->scan_pass_start, jiffies))); |
3358 | 3362 | ||
3359 | /* Remove this scanned band from the list | 3363 | /* Remove this scanned band from the list of pending |
3360 | * of pending bands to scan */ | 3364 | * bands to scan, band G precedes A in order of scanning |
3361 | priv->scan_bands--; | 3365 | * as seen in iwl3945_bg_request_scan */ |
3366 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3367 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3368 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3369 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3362 | 3370 | ||
3363 | /* If a request to abort was given, or the scan did not succeed | 3371 | /* If a request to abort was given, or the scan did not succeed |
3364 | * then we reset the scan state machine and terminate, | 3372 | * then we reset the scan state machine and terminate, |
@@ -4972,7 +4980,7 @@ static int iwl3945_get_channels_for_scan(struct iwl3945_priv *priv, | |||
4972 | 4980 | ||
4973 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); | 4981 | ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel); |
4974 | if (!is_channel_valid(ch_info)) { | 4982 | if (!is_channel_valid(ch_info)) { |
4975 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4983 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4976 | scan_ch->channel); | 4984 | scan_ch->channel); |
4977 | continue; | 4985 | continue; |
4978 | } | 4986 | } |
@@ -6315,21 +6323,16 @@ static void iwl3945_bg_request_scan(struct work_struct *data) | |||
6315 | 6323 | ||
6316 | /* flags + rate selection */ | 6324 | /* flags + rate selection */ |
6317 | 6325 | ||
6318 | switch (priv->scan_bands) { | 6326 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
6319 | case 2: | ||
6320 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 6327 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
6321 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 6328 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
6322 | scan->good_CRC_th = 0; | 6329 | scan->good_CRC_th = 0; |
6323 | band = IEEE80211_BAND_2GHZ; | 6330 | band = IEEE80211_BAND_2GHZ; |
6324 | break; | 6331 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
6325 | |||
6326 | case 1: | ||
6327 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 6332 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
6328 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 6333 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
6329 | band = IEEE80211_BAND_5GHZ; | 6334 | band = IEEE80211_BAND_5GHZ; |
6330 | break; | 6335 | } else { |
6331 | |||
6332 | default: | ||
6333 | IWL_WARNING("Invalid scan band count\n"); | 6336 | IWL_WARNING("Invalid scan band count\n"); |
6334 | goto done; | 6337 | goto done; |
6335 | } | 6338 | } |
@@ -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/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index 883b42f7e998..5ed16ce78468 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -1774,7 +1774,10 @@ static int iwl4965_scan_initiate(struct iwl_priv *priv) | |||
1774 | } | 1774 | } |
1775 | 1775 | ||
1776 | IWL_DEBUG_INFO("Starting scan...\n"); | 1776 | IWL_DEBUG_INFO("Starting scan...\n"); |
1777 | priv->scan_bands = 2; | 1777 | if (priv->cfg->sku & IWL_SKU_G) |
1778 | priv->scan_bands |= BIT(IEEE80211_BAND_2GHZ); | ||
1779 | if (priv->cfg->sku & IWL_SKU_A) | ||
1780 | priv->scan_bands |= BIT(IEEE80211_BAND_5GHZ); | ||
1778 | set_bit(STATUS_SCANNING, &priv->status); | 1781 | set_bit(STATUS_SCANNING, &priv->status); |
1779 | priv->scan_start = jiffies; | 1782 | priv->scan_start = jiffies; |
1780 | priv->scan_pass_start = priv->scan_start; | 1783 | priv->scan_pass_start = priv->scan_start; |
@@ -3023,8 +3026,9 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv, | |||
3023 | 3026 | ||
3024 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); | 3027 | IWL_DEBUG_TX_REPLY("Tx queue reclaim %d\n", index); |
3025 | if (index != -1) { | 3028 | if (index != -1) { |
3026 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3027 | #ifdef CONFIG_IWL4965_HT | 3029 | #ifdef CONFIG_IWL4965_HT |
3030 | int freed = iwl4965_tx_queue_reclaim(priv, txq_id, index); | ||
3031 | |||
3028 | if (tid != MAX_TID_COUNT) | 3032 | if (tid != MAX_TID_COUNT) |
3029 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; | 3033 | priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; |
3030 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && | 3034 | if (iwl4965_queue_space(&txq->q) > txq->q.low_mark && |
@@ -3276,13 +3280,18 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | |||
3276 | cancel_delayed_work(&priv->scan_check); | 3280 | cancel_delayed_work(&priv->scan_check); |
3277 | 3281 | ||
3278 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", | 3282 | IWL_DEBUG_INFO("Scan pass on %sGHz took %dms\n", |
3279 | (priv->scan_bands == 2) ? "2.4" : "5.2", | 3283 | (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) ? |
3284 | "2.4" : "5.2", | ||
3280 | jiffies_to_msecs(elapsed_jiffies | 3285 | jiffies_to_msecs(elapsed_jiffies |
3281 | (priv->scan_pass_start, jiffies))); | 3286 | (priv->scan_pass_start, jiffies))); |
3282 | 3287 | ||
3283 | /* Remove this scanned band from the list | 3288 | /* Remove this scanned band from the list of pending |
3284 | * of pending bands to scan */ | 3289 | * bands to scan, band G precedes A in order of scanning |
3285 | priv->scan_bands--; | 3290 | * as seen in iwl_bg_request_scan */ |
3291 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) | ||
3292 | priv->scan_bands &= ~BIT(IEEE80211_BAND_2GHZ); | ||
3293 | else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) | ||
3294 | priv->scan_bands &= ~BIT(IEEE80211_BAND_5GHZ); | ||
3286 | 3295 | ||
3287 | /* If a request to abort was given, or the scan did not succeed | 3296 | /* If a request to abort was given, or the scan did not succeed |
3288 | * then we reset the scan state machine and terminate, | 3297 | * then we reset the scan state machine and terminate, |
@@ -3292,7 +3301,7 @@ static void iwl4965_rx_scan_complete_notif(struct iwl_priv *priv, | |||
3292 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); | 3301 | clear_bit(STATUS_SCAN_ABORTING, &priv->status); |
3293 | } else { | 3302 | } else { |
3294 | /* If there are more bands on this scan pass reschedule */ | 3303 | /* If there are more bands on this scan pass reschedule */ |
3295 | if (priv->scan_bands > 0) | 3304 | if (priv->scan_bands) |
3296 | goto reschedule; | 3305 | goto reschedule; |
3297 | } | 3306 | } |
3298 | 3307 | ||
@@ -4635,10 +4644,9 @@ static int iwl4965_get_channels_for_scan(struct iwl_priv *priv, | |||
4635 | 4644 | ||
4636 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); | 4645 | scan_ch->channel = ieee80211_frequency_to_channel(channels[i].center_freq); |
4637 | 4646 | ||
4638 | ch_info = iwl_get_channel_info(priv, band, | 4647 | ch_info = iwl_get_channel_info(priv, band, scan_ch->channel); |
4639 | scan_ch->channel); | ||
4640 | if (!is_channel_valid(ch_info)) { | 4648 | if (!is_channel_valid(ch_info)) { |
4641 | IWL_DEBUG_SCAN("Channel %d is INVALID for this SKU.\n", | 4649 | IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n", |
4642 | scan_ch->channel); | 4650 | scan_ch->channel); |
4643 | continue; | 4651 | continue; |
4644 | } | 4652 | } |
@@ -5830,8 +5838,7 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5830 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; | 5838 | scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; |
5831 | 5839 | ||
5832 | 5840 | ||
5833 | switch (priv->scan_bands) { | 5841 | if (priv->scan_bands & BIT(IEEE80211_BAND_2GHZ)) { |
5834 | case 2: | ||
5835 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 5842 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
5836 | scan->tx_cmd.rate_n_flags = | 5843 | scan->tx_cmd.rate_n_flags = |
5837 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, | 5844 | iwl4965_hw_set_rate_n_flags(IWL_RATE_1M_PLCP, |
@@ -5839,17 +5846,13 @@ static void iwl4965_bg_request_scan(struct work_struct *data) | |||
5839 | 5846 | ||
5840 | scan->good_CRC_th = 0; | 5847 | scan->good_CRC_th = 0; |
5841 | band = IEEE80211_BAND_2GHZ; | 5848 | band = IEEE80211_BAND_2GHZ; |
5842 | break; | 5849 | } else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) { |
5843 | |||
5844 | case 1: | ||
5845 | scan->tx_cmd.rate_n_flags = | 5850 | scan->tx_cmd.rate_n_flags = |
5846 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, | 5851 | iwl4965_hw_set_rate_n_flags(IWL_RATE_6M_PLCP, |
5847 | RATE_MCS_ANT_B_MSK); | 5852 | RATE_MCS_ANT_B_MSK); |
5848 | scan->good_CRC_th = IWL_GOOD_CRC_TH; | 5853 | scan->good_CRC_th = IWL_GOOD_CRC_TH; |
5849 | band = IEEE80211_BAND_5GHZ; | 5854 | band = IEEE80211_BAND_5GHZ; |
5850 | break; | 5855 | } else { |
5851 | |||
5852 | default: | ||
5853 | IWL_WARNING("Invalid scan band count\n"); | 5856 | IWL_WARNING("Invalid scan band count\n"); |
5854 | goto done; | 5857 | goto done; |
5855 | } | 5858 | } |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 6328b9593877..8124fd9b1353 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -1842,6 +1842,9 @@ static void lbs_send_confirmsleep(struct lbs_private *priv) | |||
1842 | 1842 | ||
1843 | spin_lock_irqsave(&priv->driver_lock, flags); | 1843 | spin_lock_irqsave(&priv->driver_lock, flags); |
1844 | 1844 | ||
1845 | /* We don't get a response on the sleep-confirmation */ | ||
1846 | priv->dnld_sent = DNLD_RES_RECEIVED; | ||
1847 | |||
1845 | /* If nothing to do, go back to sleep (?) */ | 1848 | /* If nothing to do, go back to sleep (?) */ |
1846 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) | 1849 | if (!__kfifo_len(priv->event_fifo) && !priv->resp_len[priv->resp_idx]) |
1847 | priv->psstate = PS_STATE_SLEEP; | 1850 | priv->psstate = PS_STATE_SLEEP; |
@@ -1904,12 +1907,12 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
1904 | 1907 | ||
1905 | lbs_deb_enter(LBS_DEB_HOST); | 1908 | lbs_deb_enter(LBS_DEB_HOST); |
1906 | 1909 | ||
1910 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1907 | if (priv->dnld_sent) { | 1911 | if (priv->dnld_sent) { |
1908 | allowed = 0; | 1912 | allowed = 0; |
1909 | lbs_deb_host("dnld_sent was set\n"); | 1913 | lbs_deb_host("dnld_sent was set\n"); |
1910 | } | 1914 | } |
1911 | 1915 | ||
1912 | spin_lock_irqsave(&priv->driver_lock, flags); | ||
1913 | /* In-progress command? */ | 1916 | /* In-progress command? */ |
1914 | if (priv->cur_cmd) { | 1917 | if (priv->cur_cmd) { |
1915 | allowed = 0; | 1918 | allowed = 0; |
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c index ad2fabca9116..0aa0ce3b2c42 100644 --- a/drivers/net/wireless/libertas/debugfs.c +++ b/drivers/net/wireless/libertas/debugfs.c | |||
@@ -312,8 +312,8 @@ static ssize_t lbs_threshold_write(uint16_t tlv_type, uint16_t event_mask, | |||
312 | if (tlv_type != TLV_TYPE_BCNMISS) | 312 | if (tlv_type != TLV_TYPE_BCNMISS) |
313 | tlv->freq = freq; | 313 | tlv->freq = freq; |
314 | 314 | ||
315 | /* The command header, the event mask, and the one TLV */ | 315 | /* The command header, the action, the event mask, and one TLV */ |
316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 2 + sizeof(*tlv)); | 316 | events->hdr.size = cpu_to_le16(sizeof(events->hdr) + 4 + sizeof(*tlv)); |
317 | 317 | ||
318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); | 318 | ret = lbs_cmd_with_response(priv, CMD_802_11_SUBSCRIBE_EVENT, events); |
319 | 319 | ||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index e1f066068590..acfc4bfcc262 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -732,8 +732,8 @@ static int lbs_thread(void *data) | |||
732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", | 732 | lbs_deb_thread("4: currenttxskb %p, dnld_sent %d\n", |
733 | priv->currenttxskb, priv->dnld_sent); | 733 | priv->currenttxskb, priv->dnld_sent); |
734 | 734 | ||
735 | spin_lock_irq(&priv->driver_lock); | ||
736 | /* Process any pending command response */ | 735 | /* Process any pending command response */ |
736 | spin_lock_irq(&priv->driver_lock); | ||
737 | resp_idx = priv->resp_idx; | 737 | resp_idx = priv->resp_idx; |
738 | if (priv->resp_len[resp_idx]) { | 738 | if (priv->resp_len[resp_idx]) { |
739 | spin_unlock_irq(&priv->driver_lock); | 739 | spin_unlock_irq(&priv->driver_lock); |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 98ddbb3b3273..1610a7308c1d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -49,6 +49,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ | 49 | {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ |
50 | 50 | ||
51 | /* Version 2 devices (3887) */ | 51 | /* Version 2 devices (3887) */ |
52 | {USB_DEVICE(0x0471, 0x1230)}, /* Philips CPWUA054/00 */ | ||
52 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ | 53 | {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ |
53 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ | 54 | {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ |
54 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ | 55 | {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ |
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/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index d0b1fb15c709..18c9931e3267 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -116,6 +116,7 @@ MODULE_PARM_DESC(workaround_interval, | |||
116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) | 116 | #define OID_802_11_ENCRYPTION_STATUS ccpu2(0x0d01011b) |
117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) | 117 | #define OID_802_11_ADD_KEY ccpu2(0x0d01011d) |
118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) | 118 | #define OID_802_11_REMOVE_KEY ccpu2(0x0d01011e) |
119 | #define OID_802_11_ASSOCIATION_INFORMATION ccpu2(0x0d01011f) | ||
119 | #define OID_802_11_PMKID ccpu2(0x0d010123) | 120 | #define OID_802_11_PMKID ccpu2(0x0d010123) |
120 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) | 121 | #define OID_802_11_NETWORK_TYPES_SUPPORTED ccpu2(0x0d010203) |
121 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) | 122 | #define OID_802_11_NETWORK_TYPE_IN_USE ccpu2(0x0d010204) |
@@ -271,6 +272,26 @@ struct ndis_config_param { | |||
271 | __le32 value_length; | 272 | __le32 value_length; |
272 | } __attribute__((packed)); | 273 | } __attribute__((packed)); |
273 | 274 | ||
275 | struct ndis_80211_assoc_info { | ||
276 | __le32 length; | ||
277 | __le16 req_ies; | ||
278 | struct req_ie { | ||
279 | __le16 capa; | ||
280 | __le16 listen_interval; | ||
281 | u8 cur_ap_address[6]; | ||
282 | } req_ie; | ||
283 | __le32 req_ie_length; | ||
284 | __le32 offset_req_ies; | ||
285 | __le16 resp_ies; | ||
286 | struct resp_ie { | ||
287 | __le16 capa; | ||
288 | __le16 status_code; | ||
289 | __le16 assoc_id; | ||
290 | } resp_ie; | ||
291 | __le32 resp_ie_length; | ||
292 | __le32 offset_resp_ies; | ||
293 | } __attribute__((packed)); | ||
294 | |||
274 | /* these have to match what is in wpa_supplicant */ | 295 | /* these have to match what is in wpa_supplicant */ |
275 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; | 296 | enum wpa_alg { WPA_ALG_NONE, WPA_ALG_WEP, WPA_ALG_TKIP, WPA_ALG_CCMP }; |
276 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, | 297 | enum wpa_cipher { CIPHER_NONE, CIPHER_WEP40, CIPHER_TKIP, CIPHER_CCMP, |
@@ -674,6 +695,12 @@ static int get_bssid(struct usbnet *usbdev, u8 bssid[ETH_ALEN]) | |||
674 | return ret; | 695 | return ret; |
675 | } | 696 | } |
676 | 697 | ||
698 | static int get_association_info(struct usbnet *usbdev, | ||
699 | struct ndis_80211_assoc_info *info, int len) | ||
700 | { | ||
701 | return rndis_query_oid(usbdev, OID_802_11_ASSOCIATION_INFORMATION, | ||
702 | info, &len); | ||
703 | } | ||
677 | 704 | ||
678 | static int is_associated(struct usbnet *usbdev) | 705 | static int is_associated(struct usbnet *usbdev) |
679 | { | 706 | { |
@@ -2182,11 +2209,40 @@ static void rndis_wext_worker(struct work_struct *work) | |||
2182 | struct usbnet *usbdev = priv->usbdev; | 2209 | struct usbnet *usbdev = priv->usbdev; |
2183 | union iwreq_data evt; | 2210 | union iwreq_data evt; |
2184 | unsigned char bssid[ETH_ALEN]; | 2211 | unsigned char bssid[ETH_ALEN]; |
2185 | int ret; | 2212 | struct ndis_80211_assoc_info *info; |
2213 | int assoc_size = sizeof(*info) + IW_CUSTOM_MAX + 32; | ||
2214 | int ret, offset; | ||
2186 | 2215 | ||
2187 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { | 2216 | if (test_and_clear_bit(WORK_CONNECTION_EVENT, &priv->work_pending)) { |
2188 | ret = get_bssid(usbdev, bssid); | 2217 | info = kzalloc(assoc_size, GFP_KERNEL); |
2218 | if (!info) | ||
2219 | goto get_bssid; | ||
2220 | |||
2221 | /* Get association info IEs from device and send them back to | ||
2222 | * userspace. */ | ||
2223 | ret = get_association_info(usbdev, info, assoc_size); | ||
2224 | if (!ret) { | ||
2225 | evt.data.length = le32_to_cpu(info->req_ie_length); | ||
2226 | if (evt.data.length > 0) { | ||
2227 | offset = le32_to_cpu(info->offset_req_ies); | ||
2228 | wireless_send_event(usbdev->net, | ||
2229 | IWEVASSOCREQIE, &evt, | ||
2230 | (char *)info + offset); | ||
2231 | } | ||
2232 | |||
2233 | evt.data.length = le32_to_cpu(info->resp_ie_length); | ||
2234 | if (evt.data.length > 0) { | ||
2235 | offset = le32_to_cpu(info->offset_resp_ies); | ||
2236 | wireless_send_event(usbdev->net, | ||
2237 | IWEVASSOCRESPIE, &evt, | ||
2238 | (char *)info + offset); | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | kfree(info); | ||
2189 | 2243 | ||
2244 | get_bssid: | ||
2245 | ret = get_bssid(usbdev, bssid); | ||
2190 | if (!ret) { | 2246 | if (!ret) { |
2191 | evt.data.flags = 0; | 2247 | evt.data.flags = 0; |
2192 | evt.data.length = 0; | 2248 | evt.data.length = 0; |
@@ -2414,6 +2470,11 @@ static int bcm4320_early_init(struct usbnet *dev) | |||
2414 | else if (priv->param_power_save > 2) | 2470 | else if (priv->param_power_save > 2) |
2415 | priv->param_power_save = 2; | 2471 | priv->param_power_save = 2; |
2416 | 2472 | ||
2473 | if (priv->param_power_output < 0) | ||
2474 | priv->param_power_output = 0; | ||
2475 | else if (priv->param_power_output > 3) | ||
2476 | priv->param_power_output = 3; | ||
2477 | |||
2417 | if (priv->param_roamtrigger < -80) | 2478 | if (priv->param_roamtrigger < -80) |
2418 | priv->param_roamtrigger = -80; | 2479 | priv->param_roamtrigger = -80; |
2419 | else if (priv->param_roamtrigger > -60) | 2480 | else if (priv->param_roamtrigger > -60) |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index ab1029e79884..2d611876bbe0 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
@@ -32,12 +32,13 @@ config RT2X00_LIB_FIRMWARE | |||
32 | config RT2X00_LIB_RFKILL | 32 | config RT2X00_LIB_RFKILL |
33 | boolean | 33 | boolean |
34 | depends on RT2X00_LIB | 34 | depends on RT2X00_LIB |
35 | depends on INPUT | ||
35 | select RFKILL | 36 | select RFKILL |
36 | select INPUT_POLLDEV | 37 | select INPUT_POLLDEV |
37 | 38 | ||
38 | config RT2X00_LIB_LEDS | 39 | config RT2X00_LIB_LEDS |
39 | boolean | 40 | boolean |
40 | depends on RT2X00_LIB | 41 | depends on RT2X00_LIB && NEW_LEDS |
41 | 42 | ||
42 | config RT2400PCI | 43 | config RT2400PCI |
43 | tristate "Ralink rt2400 pci/pcmcia support" | 44 | tristate "Ralink rt2400 pci/pcmcia support" |
@@ -51,7 +52,7 @@ config RT2400PCI | |||
51 | 52 | ||
52 | config RT2400PCI_RFKILL | 53 | config RT2400PCI_RFKILL |
53 | bool "RT2400 rfkill support" | 54 | bool "RT2400 rfkill support" |
54 | depends on RT2400PCI | 55 | depends on RT2400PCI && INPUT |
55 | select RT2X00_LIB_RFKILL | 56 | select RT2X00_LIB_RFKILL |
56 | ---help--- | 57 | ---help--- |
57 | This adds support for integrated rt2400 devices that feature a | 58 | This adds support for integrated rt2400 devices that feature a |
@@ -60,7 +61,7 @@ config RT2400PCI_RFKILL | |||
60 | 61 | ||
61 | config RT2400PCI_LEDS | 62 | config RT2400PCI_LEDS |
62 | bool "RT2400 leds support" | 63 | bool "RT2400 leds support" |
63 | depends on RT2400PCI | 64 | depends on RT2400PCI && NEW_LEDS |
64 | select LEDS_CLASS | 65 | select LEDS_CLASS |
65 | select RT2X00_LIB_LEDS | 66 | select RT2X00_LIB_LEDS |
66 | ---help--- | 67 | ---help--- |
@@ -78,7 +79,7 @@ config RT2500PCI | |||
78 | 79 | ||
79 | config RT2500PCI_RFKILL | 80 | config RT2500PCI_RFKILL |
80 | bool "RT2500 rfkill support" | 81 | bool "RT2500 rfkill support" |
81 | depends on RT2500PCI | 82 | depends on RT2500PCI && INPUT |
82 | select RT2X00_LIB_RFKILL | 83 | select RT2X00_LIB_RFKILL |
83 | ---help--- | 84 | ---help--- |
84 | This adds support for integrated rt2500 devices that feature a | 85 | This adds support for integrated rt2500 devices that feature a |
@@ -87,7 +88,7 @@ config RT2500PCI_RFKILL | |||
87 | 88 | ||
88 | config RT2500PCI_LEDS | 89 | config RT2500PCI_LEDS |
89 | bool "RT2500 leds support" | 90 | bool "RT2500 leds support" |
90 | depends on RT2500PCI | 91 | depends on RT2500PCI && NEW_LEDS |
91 | select LEDS_CLASS | 92 | select LEDS_CLASS |
92 | select RT2X00_LIB_LEDS | 93 | select RT2X00_LIB_LEDS |
93 | ---help--- | 94 | ---help--- |
@@ -107,7 +108,7 @@ config RT61PCI | |||
107 | 108 | ||
108 | config RT61PCI_RFKILL | 109 | config RT61PCI_RFKILL |
109 | bool "RT61 rfkill support" | 110 | bool "RT61 rfkill support" |
110 | depends on RT61PCI | 111 | depends on RT61PCI && INPUT |
111 | select RT2X00_LIB_RFKILL | 112 | select RT2X00_LIB_RFKILL |
112 | ---help--- | 113 | ---help--- |
113 | This adds support for integrated rt61 devices that feature a | 114 | This adds support for integrated rt61 devices that feature a |
@@ -116,7 +117,7 @@ config RT61PCI_RFKILL | |||
116 | 117 | ||
117 | config RT61PCI_LEDS | 118 | config RT61PCI_LEDS |
118 | bool "RT61 leds support" | 119 | bool "RT61 leds support" |
119 | depends on RT61PCI | 120 | depends on RT61PCI && NEW_LEDS |
120 | select LEDS_CLASS | 121 | select LEDS_CLASS |
121 | select RT2X00_LIB_LEDS | 122 | select RT2X00_LIB_LEDS |
122 | ---help--- | 123 | ---help--- |
@@ -133,7 +134,7 @@ config RT2500USB | |||
133 | 134 | ||
134 | config RT2500USB_LEDS | 135 | config RT2500USB_LEDS |
135 | bool "RT2500 leds support" | 136 | bool "RT2500 leds support" |
136 | depends on RT2500USB | 137 | depends on RT2500USB && NEW_LEDS |
137 | select LEDS_CLASS | 138 | select LEDS_CLASS |
138 | select RT2X00_LIB_LEDS | 139 | select RT2X00_LIB_LEDS |
139 | ---help--- | 140 | ---help--- |
@@ -152,7 +153,7 @@ config RT73USB | |||
152 | 153 | ||
153 | config RT73USB_LEDS | 154 | config RT73USB_LEDS |
154 | bool "RT73 leds support" | 155 | bool "RT73 leds support" |
155 | depends on RT73USB | 156 | depends on RT73USB && NEW_LEDS |
156 | select LEDS_CLASS | 157 | select LEDS_CLASS |
157 | select RT2X00_LIB_LEDS | 158 | select RT2X00_LIB_LEDS |
158 | ---help--- | 159 | ---help--- |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index fdbd0ef2be4b..61e59c17a60a 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 57bdc153952f..b4bf1e09cf9a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -328,6 +328,11 @@ static inline int rt2x00_get_link_ant_rssi(struct link *link) | |||
328 | return DEFAULT_RSSI; | 328 | return DEFAULT_RSSI; |
329 | } | 329 | } |
330 | 330 | ||
331 | static inline void rt2x00_reset_link_ant_rssi(struct link *link) | ||
332 | { | ||
333 | link->ant.rssi_ant = 0; | ||
334 | } | ||
335 | |||
331 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, | 336 | static inline int rt2x00_get_link_ant_rssi_history(struct link *link, |
332 | enum antenna ant) | 337 | enum antenna ant) |
333 | { | 338 | { |
@@ -816,6 +821,7 @@ struct rt2x00_dev { | |||
816 | /* | 821 | /* |
817 | * Scheduled work. | 822 | * Scheduled work. |
818 | */ | 823 | */ |
824 | struct workqueue_struct *workqueue; | ||
819 | struct work_struct intf_work; | 825 | struct work_struct intf_work; |
820 | struct work_struct filter_work; | 826 | struct work_struct filter_work; |
821 | 827 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index a9930a03f450..48608e8cc8b4 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -129,6 +129,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
129 | */ | 129 | */ |
130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); | 130 | rt2x00dev->ops->lib->config(rt2x00dev, &libconf, CONFIG_UPDATE_ANTENNA); |
131 | rt2x00lib_reset_link_tuner(rt2x00dev); | 131 | rt2x00lib_reset_link_tuner(rt2x00dev); |
132 | rt2x00_reset_link_ant_rssi(&rt2x00dev->link); | ||
132 | 133 | ||
133 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; | 134 | rt2x00dev->link.ant.active.rx = libconf.ant.rx; |
134 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; | 135 | rt2x00dev->link.ant.active.tx = libconf.ant.tx; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index b22c02737185..c997d4f28ab3 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -75,7 +75,7 @@ static void rt2x00lib_start_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
75 | 75 | ||
76 | rt2x00lib_reset_link_tuner(rt2x00dev); | 76 | rt2x00lib_reset_link_tuner(rt2x00dev); |
77 | 77 | ||
78 | queue_delayed_work(rt2x00dev->hw->workqueue, | 78 | queue_delayed_work(rt2x00dev->workqueue, |
79 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); | 79 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
80 | } | 80 | } |
81 | 81 | ||
@@ -137,14 +137,6 @@ void rt2x00lib_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
137 | return; | 137 | return; |
138 | 138 | ||
139 | /* | 139 | /* |
140 | * Stop all scheduled work. | ||
141 | */ | ||
142 | if (work_pending(&rt2x00dev->intf_work)) | ||
143 | cancel_work_sync(&rt2x00dev->intf_work); | ||
144 | if (work_pending(&rt2x00dev->filter_work)) | ||
145 | cancel_work_sync(&rt2x00dev->filter_work); | ||
146 | |||
147 | /* | ||
148 | * Stop the TX queues. | 140 | * Stop the TX queues. |
149 | */ | 141 | */ |
150 | ieee80211_stop_queues(rt2x00dev->hw); | 142 | ieee80211_stop_queues(rt2x00dev->hw); |
@@ -398,8 +390,8 @@ static void rt2x00lib_link_tuner(struct work_struct *work) | |||
398 | * Increase tuner counter, and reschedule the next link tuner run. | 390 | * Increase tuner counter, and reschedule the next link tuner run. |
399 | */ | 391 | */ |
400 | rt2x00dev->link.count++; | 392 | rt2x00dev->link.count++; |
401 | queue_delayed_work(rt2x00dev->hw->workqueue, &rt2x00dev->link.work, | 393 | queue_delayed_work(rt2x00dev->workqueue, |
402 | LINK_TUNE_INTERVAL); | 394 | &rt2x00dev->link.work, LINK_TUNE_INTERVAL); |
403 | } | 395 | } |
404 | 396 | ||
405 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) | 397 | static void rt2x00lib_packetfilter_scheduled(struct work_struct *work) |
@@ -433,6 +425,15 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
433 | 425 | ||
434 | spin_unlock(&intf->lock); | 426 | spin_unlock(&intf->lock); |
435 | 427 | ||
428 | /* | ||
429 | * It is possible the radio was disabled while the work had been | ||
430 | * scheduled. If that happens we should return here immediately, | ||
431 | * note that in the spinlock protected area above the delayed_flags | ||
432 | * have been cleared correctly. | ||
433 | */ | ||
434 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | ||
435 | return; | ||
436 | |||
436 | if (delayed_flags & DELAYED_UPDATE_BEACON) { | 437 | if (delayed_flags & DELAYED_UPDATE_BEACON) { |
437 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); | 438 | skb = ieee80211_beacon_get(rt2x00dev->hw, vif, &control); |
438 | if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, | 439 | if (skb && rt2x00dev->ops->hw->beacon_update(rt2x00dev->hw, |
@@ -441,7 +442,7 @@ static void rt2x00lib_intf_scheduled_iter(void *data, u8 *mac, | |||
441 | } | 442 | } |
442 | 443 | ||
443 | if (delayed_flags & DELAYED_CONFIG_ERP) | 444 | if (delayed_flags & DELAYED_CONFIG_ERP) |
444 | rt2x00lib_config_erp(rt2x00dev, intf, &intf->conf); | 445 | rt2x00lib_config_erp(rt2x00dev, intf, &conf); |
445 | 446 | ||
446 | if (delayed_flags & DELAYED_LED_ASSOC) | 447 | if (delayed_flags & DELAYED_LED_ASSOC) |
447 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); | 448 | rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); |
@@ -483,11 +484,11 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev) | |||
483 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) | 484 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags)) |
484 | return; | 485 | return; |
485 | 486 | ||
486 | ieee80211_iterate_active_interfaces(rt2x00dev->hw, | 487 | ieee80211_iterate_active_interfaces_atomic(rt2x00dev->hw, |
487 | rt2x00lib_beacondone_iter, | 488 | rt2x00lib_beacondone_iter, |
488 | rt2x00dev); | 489 | rt2x00dev); |
489 | 490 | ||
490 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 491 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
491 | } | 492 | } |
492 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 493 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); |
493 | 494 | ||
@@ -507,7 +508,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
507 | * Update TX statistics. | 508 | * Update TX statistics. |
508 | */ | 509 | */ |
509 | rt2x00dev->link.qual.tx_success += success; | 510 | rt2x00dev->link.qual.tx_success += success; |
510 | rt2x00dev->link.qual.tx_failed += txdesc->retry + fail; | 511 | rt2x00dev->link.qual.tx_failed += fail; |
511 | 512 | ||
512 | /* | 513 | /* |
513 | * Initialize TX status | 514 | * Initialize TX status |
@@ -1130,6 +1131,10 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) | |||
1130 | /* | 1131 | /* |
1131 | * Initialize configuration work. | 1132 | * Initialize configuration work. |
1132 | */ | 1133 | */ |
1134 | rt2x00dev->workqueue = create_singlethread_workqueue("rt2x00lib"); | ||
1135 | if (!rt2x00dev->workqueue) | ||
1136 | goto exit; | ||
1137 | |||
1133 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); | 1138 | INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); |
1134 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); | 1139 | INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); |
1135 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); | 1140 | INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); |
@@ -1190,6 +1195,13 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
1190 | rt2x00leds_unregister(rt2x00dev); | 1195 | rt2x00leds_unregister(rt2x00dev); |
1191 | 1196 | ||
1192 | /* | 1197 | /* |
1198 | * Stop all queued work. Note that most tasks will already be halted | ||
1199 | * during rt2x00lib_disable_radio() and rt2x00lib_uninitialize(). | ||
1200 | */ | ||
1201 | flush_workqueue(rt2x00dev->workqueue); | ||
1202 | destroy_workqueue(rt2x00dev->workqueue); | ||
1203 | |||
1204 | /* | ||
1193 | * Free ieee80211_hw memory. | 1205 | * Free ieee80211_hw memory. |
1194 | */ | 1206 | */ |
1195 | rt2x00lib_remove_hw(rt2x00dev); | 1207 | rt2x00lib_remove_hw(rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c206b5092070..9cb023edd2e9 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -93,6 +93,7 @@ int rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
93 | */ | 93 | */ |
94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { | 94 | if (!test_bit(DEVICE_PRESENT, &rt2x00dev->flags)) { |
95 | ieee80211_stop_queues(hw); | 95 | ieee80211_stop_queues(hw); |
96 | dev_kfree_skb_any(skb); | ||
96 | return NETDEV_TX_OK; | 97 | return NETDEV_TX_OK; |
97 | } | 98 | } |
98 | 99 | ||
@@ -427,7 +428,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw, | |||
427 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) | 428 | if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) |
428 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); | 429 | rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); |
429 | else | 430 | else |
430 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); | 431 | queue_work(rt2x00dev->workqueue, &rt2x00dev->filter_work); |
431 | } | 432 | } |
432 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 433 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
433 | 434 | ||
@@ -508,7 +509,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
508 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); | 509 | memcpy(&intf->conf, bss_conf, sizeof(*bss_conf)); |
509 | if (delayed) { | 510 | if (delayed) { |
510 | intf->delayed_flags |= delayed; | 511 | intf->delayed_flags |= delayed; |
511 | queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); | 512 | queue_work(rt2x00dev->workqueue, &rt2x00dev->intf_work); |
512 | } | 513 | } |
513 | spin_unlock(&intf->lock); | 514 | spin_unlock(&intf->lock); |
514 | } | 515 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 971af2546b59..60893de3bf8f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -412,8 +412,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
412 | if (pci_set_mwi(pci_dev)) | 412 | if (pci_set_mwi(pci_dev)) |
413 | ERROR_PROBE("MWI not available.\n"); | 413 | ERROR_PROBE("MWI not available.\n"); |
414 | 414 | ||
415 | if (pci_set_dma_mask(pci_dev, DMA_64BIT_MASK) && | 415 | if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { |
416 | pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | ||
417 | ERROR_PROBE("PCI DMA not supported.\n"); | 416 | ERROR_PROBE("PCI DMA not supported.\n"); |
418 | retval = -EIO; | 417 | retval = -EIO; |
419 | goto exit_disable_device; | 418 | goto exit_disable_device; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 5a331674dcb2..e5ceae805b57 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -362,6 +362,12 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
362 | } | 362 | } |
363 | } | 363 | } |
364 | 364 | ||
365 | /* | ||
366 | * Kill guardian urb (if required by driver). | ||
367 | */ | ||
368 | if (!test_bit(DRIVER_REQUIRE_BEACON_GUARD, &rt2x00dev->flags)) | ||
369 | return; | ||
370 | |||
365 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { | 371 | for (i = 0; i < rt2x00dev->bcn->limit; i++) { |
366 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; | 372 | priv_bcn = rt2x00dev->bcn->entries[i].priv_data; |
367 | usb_kill_urb(priv_bcn->urb); | 373 | usb_kill_urb(priv_bcn->urb); |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index da19a3a91f4d..83cc0147f698 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, |
@@ -2131,6 +2137,7 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2131 | /* D-Link */ | 2137 | /* D-Link */ |
2132 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, | 2138 | { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) }, |
2133 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, | 2139 | { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) }, |
2140 | { USB_DEVICE(0x07d1, 0x3c06), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2134 | { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, | 2141 | { USB_DEVICE(0x07d1, 0x3c07), USB_DEVICE_DATA(&rt73usb_ops) }, |
2135 | /* Gemtek */ | 2142 | /* Gemtek */ |
2136 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, | 2143 | { USB_DEVICE(0x15a9, 0x0004), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/drivers/net/wireless/rtl8180_grf5101.c b/drivers/net/wireless/rtl8180_grf5101.c index 5d47935dbac3..947ee55f18b2 100644 --- a/drivers/net/wireless/rtl8180_grf5101.c +++ b/drivers/net/wireless/rtl8180_grf5101.c | |||
@@ -88,7 +88,7 @@ static void grf5101_rf_set_channel(struct ieee80211_hw *dev, | |||
88 | write_grf5101(dev, 0x0B, chan); | 88 | write_grf5101(dev, 0x0B, chan); |
89 | write_grf5101(dev, 0x07, 0x1000); | 89 | write_grf5101(dev, 0x07, 0x1000); |
90 | 90 | ||
91 | grf5101_write_phy_antenna(dev, chan); | 91 | grf5101_write_phy_antenna(dev, channel); |
92 | } | 92 | } |
93 | 93 | ||
94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) | 94 | static void grf5101_rf_stop(struct ieee80211_hw *dev) |
diff --git a/drivers/net/wireless/rtl8180_max2820.c b/drivers/net/wireless/rtl8180_max2820.c index a34dfd382b6d..6c825fd7f3b6 100644 --- a/drivers/net/wireless/rtl8180_max2820.c +++ b/drivers/net/wireless/rtl8180_max2820.c | |||
@@ -78,7 +78,8 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
78 | struct ieee80211_conf *conf) | 78 | struct ieee80211_conf *conf) |
79 | { | 79 | { |
80 | struct rtl8180_priv *priv = dev->priv; | 80 | struct rtl8180_priv *priv = dev->priv; |
81 | int channel = ieee80211_frequency_to_channel(conf->channel->center_freq); | 81 | int channel = conf ? |
82 | ieee80211_frequency_to_channel(conf->channel->center_freq) : 1; | ||
82 | unsigned int chan_idx = channel - 1; | 83 | unsigned int chan_idx = channel - 1; |
83 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; | 84 | u32 txpw = priv->channels[chan_idx].hw_value & 0xFF; |
84 | u32 chan = max2820_chan[chan_idx]; | 85 | u32 chan = max2820_chan[chan_idx]; |
@@ -87,7 +88,7 @@ static void max2820_rf_set_channel(struct ieee80211_hw *dev, | |||
87 | * sa2400, for MAXIM we do this directly from BB */ | 88 | * sa2400, for MAXIM we do this directly from BB */ |
88 | rtl8180_write_phy(dev, 3, txpw); | 89 | rtl8180_write_phy(dev, 3, txpw); |
89 | 90 | ||
90 | max2820_write_phy_antenna(dev, chan); | 91 | max2820_write_phy_antenna(dev, channel); |
91 | write_max2820(dev, 3, chan); | 92 | write_max2820(dev, 3, chan); |
92 | } | 93 | } |
93 | 94 | ||
diff --git a/drivers/net/wireless/rtl8180_sa2400.c b/drivers/net/wireless/rtl8180_sa2400.c index 0311b4ea124c..cea4e0ccb92d 100644 --- a/drivers/net/wireless/rtl8180_sa2400.c +++ b/drivers/net/wireless/rtl8180_sa2400.c | |||
@@ -86,7 +86,7 @@ static void sa2400_rf_set_channel(struct ieee80211_hw *dev, | |||
86 | 86 | ||
87 | write_sa2400(dev, 7, txpw); | 87 | write_sa2400(dev, 7, txpw); |
88 | 88 | ||
89 | sa2400_write_phy_antenna(dev, chan); | 89 | sa2400_write_phy_antenna(dev, channel); |
90 | 90 | ||
91 | write_sa2400(dev, 0, chan); | 91 | write_sa2400(dev, 0, chan); |
92 | write_sa2400(dev, 1, 0xbb50); | 92 | write_sa2400(dev, 1, 0xbb50); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6424e5a2c83d..418606ac1c3b 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -719,7 +719,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
719 | fc = le16_to_cpu(*((__le16 *) buffer)); | 719 | fc = le16_to_cpu(*((__le16 *) buffer)); |
720 | 720 | ||
721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | 721 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && |
722 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_QOS_DATA); | 722 | (fc & IEEE80211_STYPE_QOS_DATA); |
723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 723 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == |
724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 724 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); |
725 | need_padding = is_qos ^ is_4addr; | 725 | need_padding = is_qos ^ is_4addr; |