diff options
25 files changed, 207 insertions, 78 deletions
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index a5ac2bd58b5b..4f3ada622f9b 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -2101,6 +2101,9 @@ static int gelic_wl_associate_bss(struct gelic_wl_info *wl, | |||
2101 | if (ret) { | 2101 | if (ret) { |
2102 | pr_debug("%s: WEP/WPA setup failed %d\n", __func__, | 2102 | pr_debug("%s: WEP/WPA setup failed %d\n", __func__, |
2103 | ret); | 2103 | ret); |
2104 | ret = -EPERM; | ||
2105 | gelic_wl_send_iwap_event(wl, NULL); | ||
2106 | goto out; | ||
2104 | } | 2107 | } |
2105 | 2108 | ||
2106 | /* start association */ | 2109 | /* start association */ |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index f21a6171c691..c36d3a3d655f 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -6713,11 +6713,11 @@ static int airo_set_auth(struct net_device *dev, | |||
6713 | local->config.authType = AUTH_ENCRYPT; | 6713 | local->config.authType = AUTH_ENCRYPT; |
6714 | } else | 6714 | } else |
6715 | return -EINVAL; | 6715 | return -EINVAL; |
6716 | break; | ||
6717 | 6716 | ||
6718 | /* Commit the changes to flags if needed */ | 6717 | /* Commit the changes to flags if needed */ |
6719 | if (local->config.authType != currentAuthType) | 6718 | if (local->config.authType != currentAuthType) |
6720 | set_bit (FLAG_COMMIT, &local->flags); | 6719 | set_bit (FLAG_COMMIT, &local->flags); |
6720 | break; | ||
6721 | } | 6721 | } |
6722 | 6722 | ||
6723 | case IW_AUTH_WPA_ENABLED: | 6723 | case IW_AUTH_WPA_ENABLED: |
diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h index 13091bd9d815..53e250a4278f 100644 --- a/drivers/net/wireless/ar9170/hw.h +++ b/drivers/net/wireless/ar9170/hw.h | |||
@@ -310,7 +310,7 @@ struct ar9170_tx_control { | |||
310 | 310 | ||
311 | struct ar9170_rx_head { | 311 | struct ar9170_rx_head { |
312 | u8 plcp[12]; | 312 | u8 plcp[12]; |
313 | }; | 313 | } __packed; |
314 | 314 | ||
315 | struct ar9170_rx_tail { | 315 | struct ar9170_rx_tail { |
316 | union { | 316 | union { |
@@ -318,16 +318,16 @@ struct ar9170_rx_tail { | |||
318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, | 318 | u8 rssi_ant0, rssi_ant1, rssi_ant2, |
319 | rssi_ant0x, rssi_ant1x, rssi_ant2x, | 319 | rssi_ant0x, rssi_ant1x, rssi_ant2x, |
320 | rssi_combined; | 320 | rssi_combined; |
321 | }; | 321 | } __packed; |
322 | u8 rssi[7]; | 322 | u8 rssi[7]; |
323 | }; | 323 | } __packed; |
324 | 324 | ||
325 | u8 evm_stream0[6], evm_stream1[6]; | 325 | u8 evm_stream0[6], evm_stream1[6]; |
326 | u8 phy_err; | 326 | u8 phy_err; |
327 | u8 SAidx, DAidx; | 327 | u8 SAidx, DAidx; |
328 | u8 error; | 328 | u8 error; |
329 | u8 status; | 329 | u8 status; |
330 | }; | 330 | } __packed; |
331 | 331 | ||
332 | #define AR9170_ENC_ALG_NONE 0x0 | 332 | #define AR9170_ENC_ALG_NONE 0x0 |
333 | #define AR9170_ENC_ALG_WEP64 0x1 | 333 | #define AR9170_ENC_ALG_WEP64 0x1 |
diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c index ad296840893e..c9e422ead925 100644 --- a/drivers/net/wireless/ar9170/usb.c +++ b/drivers/net/wireless/ar9170/usb.c | |||
@@ -59,6 +59,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
59 | { USB_DEVICE(0x0cf3, 0x9170) }, | 59 | { USB_DEVICE(0x0cf3, 0x9170) }, |
60 | /* Atheros TG121N */ | 60 | /* Atheros TG121N */ |
61 | { USB_DEVICE(0x0cf3, 0x1001) }, | 61 | { USB_DEVICE(0x0cf3, 0x1001) }, |
62 | /* Cace Airpcap NX */ | ||
63 | { USB_DEVICE(0xcace, 0x0300) }, | ||
62 | /* D-Link DWA 160A */ | 64 | /* D-Link DWA 160A */ |
63 | { USB_DEVICE(0x07d1, 0x3c10) }, | 65 | { USB_DEVICE(0x07d1, 0x3c10) }, |
64 | /* Netgear WNDA3100 */ | 66 | /* Netgear WNDA3100 */ |
@@ -67,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
67 | { USB_DEVICE(0x0846, 0x9001) }, | 69 | { USB_DEVICE(0x0846, 0x9001) }, |
68 | /* Zydas ZD1221 */ | 70 | /* Zydas ZD1221 */ |
69 | { USB_DEVICE(0x0ace, 0x1221) }, | 71 | { USB_DEVICE(0x0ace, 0x1221) }, |
72 | /* ZyXEL NWD271N */ | ||
73 | { USB_DEVICE(0x0586, 0x3417) }, | ||
70 | /* Z-Com UB81 BG */ | 74 | /* Z-Com UB81 BG */ |
71 | { USB_DEVICE(0x0cde, 0x0023) }, | 75 | { USB_DEVICE(0x0cde, 0x0023) }, |
72 | /* Z-Com UB82 ABG */ | 76 | /* Z-Com UB82 ABG */ |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 0c02f1c2bd94..744f4f4dd3d1 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -250,6 +250,8 @@ static struct usb_device_id dev_table[] = { | |||
250 | { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, | 250 | { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, |
251 | /* Siemens Gigaset USB WLAN Adapter 11 */ | 251 | /* Siemens Gigaset USB WLAN Adapter 11 */ |
252 | { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, | 252 | { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, |
253 | /* OQO Model 01+ Internal Wi-Fi */ | ||
254 | { USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) }, | ||
253 | /* | 255 | /* |
254 | * at76c505amx-rfmd | 256 | * at76c505amx-rfmd |
255 | */ | 257 | */ |
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 71cb18d6757d..dd1f30156740 100644 --- a/drivers/net/wireless/ath9k/recv.c +++ b/drivers/net/wireless/ath9k/recv.c | |||
@@ -493,6 +493,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
493 | int hdrlen, padsize, retval; | 493 | int hdrlen, padsize, retval; |
494 | bool decrypt_error = false; | 494 | bool decrypt_error = false; |
495 | u8 keyix; | 495 | u8 keyix; |
496 | __le16 fc; | ||
496 | 497 | ||
497 | spin_lock_bh(&sc->rx.rxbuflock); | 498 | spin_lock_bh(&sc->rx.rxbuflock); |
498 | 499 | ||
@@ -606,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
606 | /* see if any padding is done by the hw and remove it */ | 607 | /* see if any padding is done by the hw and remove it */ |
607 | hdr = (struct ieee80211_hdr *)skb->data; | 608 | hdr = (struct ieee80211_hdr *)skb->data; |
608 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 609 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
610 | fc = hdr->frame_control; | ||
609 | 611 | ||
610 | /* The MAC header is padded to have 32-bit boundary if the | 612 | /* The MAC header is padded to have 32-bit boundary if the |
611 | * packet payload is non-zero. The general calculation for | 613 | * packet payload is non-zero. The general calculation for |
@@ -690,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
690 | sc->rx.rxotherant = 0; | 692 | sc->rx.rxotherant = 0; |
691 | } | 693 | } |
692 | 694 | ||
693 | if (ieee80211_is_beacon(hdr->frame_control) && | 695 | if (ieee80211_is_beacon(fc) && |
694 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { | 696 | (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { |
695 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; | 697 | sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; |
696 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); | 698 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index e228c1de6e11..eae680b53052 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -555,11 +555,32 @@ address_error: | |||
555 | return 1; | 555 | return 1; |
556 | } | 556 | } |
557 | 557 | ||
558 | static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) | ||
559 | { | ||
560 | unsigned char *f = skb->data + ring->frameoffset; | ||
561 | |||
562 | return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF); | ||
563 | } | ||
564 | |||
565 | static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb) | ||
566 | { | ||
567 | struct b43_rxhdr_fw4 *rxhdr; | ||
568 | unsigned char *frame; | ||
569 | |||
570 | /* This poisons the RX buffer to detect DMA failures. */ | ||
571 | |||
572 | rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); | ||
573 | rxhdr->frame_len = 0; | ||
574 | |||
575 | B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2); | ||
576 | frame = skb->data + ring->frameoffset; | ||
577 | memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */); | ||
578 | } | ||
579 | |||
558 | static int setup_rx_descbuffer(struct b43_dmaring *ring, | 580 | static int setup_rx_descbuffer(struct b43_dmaring *ring, |
559 | struct b43_dmadesc_generic *desc, | 581 | struct b43_dmadesc_generic *desc, |
560 | struct b43_dmadesc_meta *meta, gfp_t gfp_flags) | 582 | struct b43_dmadesc_meta *meta, gfp_t gfp_flags) |
561 | { | 583 | { |
562 | struct b43_rxhdr_fw4 *rxhdr; | ||
563 | dma_addr_t dmaaddr; | 584 | dma_addr_t dmaaddr; |
564 | struct sk_buff *skb; | 585 | struct sk_buff *skb; |
565 | 586 | ||
@@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
568 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); | 589 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); |
569 | if (unlikely(!skb)) | 590 | if (unlikely(!skb)) |
570 | return -ENOMEM; | 591 | return -ENOMEM; |
592 | b43_poison_rx_buffer(ring, skb); | ||
571 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); | 593 | dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); |
572 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { | 594 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
573 | /* ugh. try to realloc in zone_dma */ | 595 | /* ugh. try to realloc in zone_dma */ |
@@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
578 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); | 600 | skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); |
579 | if (unlikely(!skb)) | 601 | if (unlikely(!skb)) |
580 | return -ENOMEM; | 602 | return -ENOMEM; |
603 | b43_poison_rx_buffer(ring, skb); | ||
581 | dmaaddr = map_descbuffer(ring, skb->data, | 604 | dmaaddr = map_descbuffer(ring, skb->data, |
582 | ring->rx_buffersize, 0); | 605 | ring->rx_buffersize, 0); |
583 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { | 606 | if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { |
@@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, | |||
592 | ring->ops->fill_descriptor(ring, desc, dmaaddr, | 615 | ring->ops->fill_descriptor(ring, desc, dmaaddr, |
593 | ring->rx_buffersize, 0, 0, 0); | 616 | ring->rx_buffersize, 0, 0, 0); |
594 | 617 | ||
595 | rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); | ||
596 | rxhdr->frame_len = 0; | ||
597 | |||
598 | return 0; | 618 | return 0; |
599 | } | 619 | } |
600 | 620 | ||
@@ -1483,12 +1503,17 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1483 | len = le16_to_cpu(rxhdr->frame_len); | 1503 | len = le16_to_cpu(rxhdr->frame_len); |
1484 | } while (len == 0 && i++ < 5); | 1504 | } while (len == 0 && i++ < 5); |
1485 | if (unlikely(len == 0)) { | 1505 | if (unlikely(len == 0)) { |
1486 | /* recycle the descriptor buffer. */ | 1506 | dmaaddr = meta->dmaaddr; |
1487 | sync_descbuffer_for_device(ring, meta->dmaaddr, | 1507 | goto drop_recycle_buffer; |
1488 | ring->rx_buffersize); | ||
1489 | goto drop; | ||
1490 | } | 1508 | } |
1491 | } | 1509 | } |
1510 | if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) { | ||
1511 | /* Something went wrong with the DMA. | ||
1512 | * The device did not touch the buffer and did not overwrite the poison. */ | ||
1513 | b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n"); | ||
1514 | dmaaddr = meta->dmaaddr; | ||
1515 | goto drop_recycle_buffer; | ||
1516 | } | ||
1492 | if (unlikely(len > ring->rx_buffersize)) { | 1517 | if (unlikely(len > ring->rx_buffersize)) { |
1493 | /* The data did not fit into one descriptor buffer | 1518 | /* The data did not fit into one descriptor buffer |
1494 | * and is split over multiple buffers. | 1519 | * and is split over multiple buffers. |
@@ -1501,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1501 | while (1) { | 1526 | while (1) { |
1502 | desc = ops->idx2desc(ring, *slot, &meta); | 1527 | desc = ops->idx2desc(ring, *slot, &meta); |
1503 | /* recycle the descriptor buffer. */ | 1528 | /* recycle the descriptor buffer. */ |
1529 | b43_poison_rx_buffer(ring, meta->skb); | ||
1504 | sync_descbuffer_for_device(ring, meta->dmaaddr, | 1530 | sync_descbuffer_for_device(ring, meta->dmaaddr, |
1505 | ring->rx_buffersize); | 1531 | ring->rx_buffersize); |
1506 | *slot = next_slot(ring, *slot); | 1532 | *slot = next_slot(ring, *slot); |
@@ -1519,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1519 | err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); | 1545 | err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); |
1520 | if (unlikely(err)) { | 1546 | if (unlikely(err)) { |
1521 | b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n"); | 1547 | b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n"); |
1522 | sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); | 1548 | goto drop_recycle_buffer; |
1523 | goto drop; | ||
1524 | } | 1549 | } |
1525 | 1550 | ||
1526 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); | 1551 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); |
@@ -1530,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) | |||
1530 | b43_rx(ring->dev, skb, rxhdr); | 1555 | b43_rx(ring->dev, skb, rxhdr); |
1531 | drop: | 1556 | drop: |
1532 | return; | 1557 | return; |
1558 | |||
1559 | drop_recycle_buffer: | ||
1560 | /* Poison and recycle the RX buffer. */ | ||
1561 | b43_poison_rx_buffer(ring, skb); | ||
1562 | sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); | ||
1533 | } | 1563 | } |
1534 | 1564 | ||
1535 | void b43_dma_rx(struct b43_dmaring *ring) | 1565 | void b43_dma_rx(struct b43_dmaring *ring) |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4896e0831114..79b685e300c7 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -3974,6 +3974,11 @@ static void setup_struct_phy_for_init(struct b43_wldev *dev, | |||
3974 | phy->next_txpwr_check_time = jiffies; | 3974 | phy->next_txpwr_check_time = jiffies; |
3975 | /* PHY TX errors counter. */ | 3975 | /* PHY TX errors counter. */ |
3976 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); | 3976 | atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); |
3977 | |||
3978 | #if B43_DEBUG | ||
3979 | phy->phy_locked = 0; | ||
3980 | phy->radio_locked = 0; | ||
3981 | #endif | ||
3977 | } | 3982 | } |
3978 | 3983 | ||
3979 | static void setup_struct_wldev_for_init(struct b43_wldev *dev) | 3984 | static void setup_struct_wldev_for_init(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index 026b61c03fb9..e176b6e0d9cf 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
@@ -131,12 +131,16 @@ void b43_radio_lock(struct b43_wldev *dev) | |||
131 | { | 131 | { |
132 | u32 macctl; | 132 | u32 macctl; |
133 | 133 | ||
134 | #if B43_DEBUG | ||
135 | B43_WARN_ON(dev->phy.radio_locked); | ||
136 | dev->phy.radio_locked = 1; | ||
137 | #endif | ||
138 | |||
134 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 139 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
135 | B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK); | ||
136 | macctl |= B43_MACCTL_RADIOLOCK; | 140 | macctl |= B43_MACCTL_RADIOLOCK; |
137 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 141 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
138 | /* Commit the write and wait for the device | 142 | /* Commit the write and wait for the firmware |
139 | * to exit any radio register access. */ | 143 | * to finish any radio register access. */ |
140 | b43_read32(dev, B43_MMIO_MACCTL); | 144 | b43_read32(dev, B43_MMIO_MACCTL); |
141 | udelay(10); | 145 | udelay(10); |
142 | } | 146 | } |
@@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *dev) | |||
145 | { | 149 | { |
146 | u32 macctl; | 150 | u32 macctl; |
147 | 151 | ||
152 | #if B43_DEBUG | ||
153 | B43_WARN_ON(!dev->phy.radio_locked); | ||
154 | dev->phy.radio_locked = 0; | ||
155 | #endif | ||
156 | |||
148 | /* Commit any write */ | 157 | /* Commit any write */ |
149 | b43_read16(dev, B43_MMIO_PHY_VER); | 158 | b43_read16(dev, B43_MMIO_PHY_VER); |
150 | /* unlock */ | 159 | /* unlock */ |
151 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 160 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
152 | B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK)); | ||
153 | macctl &= ~B43_MACCTL_RADIOLOCK; | 161 | macctl &= ~B43_MACCTL_RADIOLOCK; |
154 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 162 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
155 | } | 163 | } |
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index c9f5430d1d7d..b2d99101947b 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h | |||
@@ -245,8 +245,10 @@ struct b43_phy { | |||
245 | atomic_t txerr_cnt; | 245 | atomic_t txerr_cnt; |
246 | 246 | ||
247 | #ifdef CONFIG_B43_DEBUG | 247 | #ifdef CONFIG_B43_DEBUG |
248 | /* PHY registers locked by b43_phy_lock()? */ | 248 | /* PHY registers locked (w.r.t. firmware) */ |
249 | bool phy_locked; | 249 | bool phy_locked; |
250 | /* Radio registers locked (w.r.t. firmware) */ | ||
251 | bool radio_locked; | ||
250 | #endif /* B43_DEBUG */ | 252 | #endif /* B43_DEBUG */ |
251 | }; | 253 | }; |
252 | 254 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ce729281ff62..8d738d752487 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -4913,6 +4913,8 @@ static int iwl3945_setup_mac(struct iwl_priv *priv) | |||
4913 | 4913 | ||
4914 | hw->wiphy->custom_regulatory = true; | 4914 | hw->wiphy->custom_regulatory = true; |
4915 | 4915 | ||
4916 | hw->wiphy->max_scan_ssids = 1; /* WILL FIX */ | ||
4917 | |||
4916 | /* Default value; 4 EDCA QOS priorities */ | 4918 | /* Default value; 4 EDCA QOS priorities */ |
4917 | hw->queues = 4; | 4919 | hw->queues = 4; |
4918 | 4920 | ||
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 63d7e19ce9bd..8e669775cb5d 100644 --- a/drivers/net/wireless/libertas/rx.c +++ b/drivers/net/wireless/libertas/rx.c | |||
@@ -170,6 +170,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
170 | lbs_deb_rx("rx err: frame received with bad length\n"); | 170 | lbs_deb_rx("rx err: frame received with bad length\n"); |
171 | dev->stats.rx_length_errors++; | 171 | dev->stats.rx_length_errors++; |
172 | ret = 0; | 172 | ret = 0; |
173 | dev_kfree_skb(skb); | ||
173 | goto done; | 174 | goto done; |
174 | } | 175 | } |
175 | 176 | ||
@@ -181,6 +182,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | |||
181 | lbs_pr_alert("rxpd not ok\n"); | 182 | lbs_pr_alert("rxpd not ok\n"); |
182 | dev->stats.rx_errors++; | 183 | dev->stats.rx_errors++; |
183 | ret = 0; | 184 | ret = 0; |
185 | dev_kfree_skb(skb); | ||
184 | goto done; | 186 | goto done; |
185 | } | 187 | } |
186 | 188 | ||
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 081428d9409e..632fac86a308 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -372,15 +372,13 @@ int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx, | |||
372 | } | 372 | } |
373 | 373 | ||
374 | /* Wait upto 100ms for tx queue to empty */ | 374 | /* Wait upto 100ms for tx queue to empty */ |
375 | k = 100; | 375 | for (k = 100; k > 0; k--) { |
376 | do { | ||
377 | k--; | ||
378 | udelay(1000); | 376 | udelay(1000); |
379 | ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, | 377 | ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, |
380 | &xmitting); | 378 | &xmitting); |
381 | if (ret) | 379 | if (ret || !xmitting) |
382 | break; | 380 | break; |
383 | } while ((k > 0) && xmitting); | 381 | } |
384 | 382 | ||
385 | if (k == 0) | 383 | if (k == 0) |
386 | ret = -ETIMEDOUT; | 384 | ret = -ETIMEDOUT; |
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 2dda5fe418b6..ecf8b6ed5a47 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -14,9 +14,9 @@ | |||
14 | * published by the Free Software Foundation. | 14 | * published by the Free Software Foundation. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifdef CONFIG_MAC80211_LEDS | 17 | #ifdef CONFIG_P54_LEDS |
18 | #include <linux/leds.h> | 18 | #include <linux/leds.h> |
19 | #endif /* CONFIG_MAC80211_LEDS */ | 19 | #endif /* CONFIG_P54_LEDS */ |
20 | 20 | ||
21 | enum p54_control_frame_types { | 21 | enum p54_control_frame_types { |
22 | P54_CONTROL_TYPE_SETUP = 0, | 22 | P54_CONTROL_TYPE_SETUP = 0, |
@@ -116,7 +116,7 @@ enum fw_state { | |||
116 | FW_STATE_RESETTING, | 116 | FW_STATE_RESETTING, |
117 | }; | 117 | }; |
118 | 118 | ||
119 | #ifdef CONFIG_MAC80211_LEDS | 119 | #ifdef CONFIG_P54_LEDS |
120 | 120 | ||
121 | #define P54_LED_MAX_NAME_LEN 31 | 121 | #define P54_LED_MAX_NAME_LEN 31 |
122 | 122 | ||
@@ -129,7 +129,7 @@ struct p54_led_dev { | |||
129 | unsigned int registered; | 129 | unsigned int registered; |
130 | }; | 130 | }; |
131 | 131 | ||
132 | #endif /* CONFIG_MAC80211_LEDS */ | 132 | #endif /* CONFIG_P54_LEDS */ |
133 | 133 | ||
134 | struct p54_common { | 134 | struct p54_common { |
135 | struct ieee80211_hw *hw; | 135 | struct ieee80211_hw *hw; |
@@ -177,10 +177,10 @@ struct p54_common { | |||
177 | u8 privacy_caps; | 177 | u8 privacy_caps; |
178 | u8 rx_keycache_size; | 178 | u8 rx_keycache_size; |
179 | /* LED management */ | 179 | /* LED management */ |
180 | #ifdef CONFIG_MAC80211_LEDS | 180 | #ifdef CONFIG_P54_LEDS |
181 | struct p54_led_dev assoc_led; | 181 | struct p54_led_dev assoc_led; |
182 | struct p54_led_dev tx_led; | 182 | struct p54_led_dev tx_led; |
183 | #endif /* CONFIG_MAC80211_LEDS */ | 183 | #endif /* CONFIG_P54_LEDS */ |
184 | u16 softled_state; /* bit field of glowing LEDs */ | 184 | u16 softled_state; /* bit field of glowing LEDs */ |
185 | }; | 185 | }; |
186 | 186 | ||
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 2b222aaa6f0a..d1fe577de3d4 100644 --- a/drivers/net/wireless/p54/p54spi.c +++ b/drivers/net/wireless/p54/p54spi.c | |||
@@ -457,9 +457,10 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
457 | struct ieee80211_tx_info *info; | 457 | struct ieee80211_tx_info *info; |
458 | struct p54_tx_info *minfo; | 458 | struct p54_tx_info *minfo; |
459 | struct p54s_tx_info *dinfo; | 459 | struct p54s_tx_info *dinfo; |
460 | unsigned long flags; | ||
460 | int ret = 0; | 461 | int ret = 0; |
461 | 462 | ||
462 | spin_lock_bh(&priv->tx_lock); | 463 | spin_lock_irqsave(&priv->tx_lock, flags); |
463 | 464 | ||
464 | while (!list_empty(&priv->tx_pending)) { | 465 | while (!list_empty(&priv->tx_pending)) { |
465 | entry = list_entry(priv->tx_pending.next, | 466 | entry = list_entry(priv->tx_pending.next, |
@@ -467,7 +468,7 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
467 | 468 | ||
468 | list_del_init(&entry->tx_list); | 469 | list_del_init(&entry->tx_list); |
469 | 470 | ||
470 | spin_unlock_bh(&priv->tx_lock); | 471 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
471 | 472 | ||
472 | dinfo = container_of((void *) entry, struct p54s_tx_info, | 473 | dinfo = container_of((void *) entry, struct p54s_tx_info, |
473 | tx_list); | 474 | tx_list); |
@@ -479,16 +480,14 @@ static int p54spi_wq_tx(struct p54s_priv *priv) | |||
479 | 480 | ||
480 | ret = p54spi_tx_frame(priv, skb); | 481 | ret = p54spi_tx_frame(priv, skb); |
481 | 482 | ||
482 | spin_lock_bh(&priv->tx_lock); | ||
483 | |||
484 | if (ret < 0) { | 483 | if (ret < 0) { |
485 | p54_free_skb(priv->hw, skb); | 484 | p54_free_skb(priv->hw, skb); |
486 | goto out; | 485 | return ret; |
487 | } | 486 | } |
488 | } | ||
489 | 487 | ||
490 | out: | 488 | spin_lock_irqsave(&priv->tx_lock, flags); |
491 | spin_unlock_bh(&priv->tx_lock); | 489 | } |
490 | spin_unlock_irqrestore(&priv->tx_lock, flags); | ||
492 | return ret; | 491 | return ret; |
493 | } | 492 | } |
494 | 493 | ||
@@ -498,12 +497,13 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
498 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 497 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
499 | struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; | 498 | struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; |
500 | struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; | 499 | struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; |
500 | unsigned long flags; | ||
501 | 501 | ||
502 | BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); | 502 | BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); |
503 | 503 | ||
504 | spin_lock_bh(&priv->tx_lock); | 504 | spin_lock_irqsave(&priv->tx_lock, flags); |
505 | list_add_tail(&di->tx_list, &priv->tx_pending); | 505 | list_add_tail(&di->tx_list, &priv->tx_pending); |
506 | spin_unlock_bh(&priv->tx_lock); | 506 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
507 | 507 | ||
508 | queue_work(priv->hw->workqueue, &priv->work); | 508 | queue_work(priv->hw->workqueue, &priv->work); |
509 | } | 509 | } |
@@ -604,6 +604,7 @@ out: | |||
604 | static void p54spi_op_stop(struct ieee80211_hw *dev) | 604 | static void p54spi_op_stop(struct ieee80211_hw *dev) |
605 | { | 605 | { |
606 | struct p54s_priv *priv = dev->priv; | 606 | struct p54s_priv *priv = dev->priv; |
607 | unsigned long flags; | ||
607 | 608 | ||
608 | if (mutex_lock_interruptible(&priv->mutex)) { | 609 | if (mutex_lock_interruptible(&priv->mutex)) { |
609 | /* FIXME: how to handle this error? */ | 610 | /* FIXME: how to handle this error? */ |
@@ -615,9 +616,9 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) | |||
615 | cancel_work_sync(&priv->work); | 616 | cancel_work_sync(&priv->work); |
616 | 617 | ||
617 | p54spi_power_off(priv); | 618 | p54spi_power_off(priv); |
618 | spin_lock_bh(&priv->tx_lock); | 619 | spin_lock_irqsave(&priv->tx_lock, flags); |
619 | INIT_LIST_HEAD(&priv->tx_pending); | 620 | INIT_LIST_HEAD(&priv->tx_pending); |
620 | spin_unlock_bh(&priv->tx_lock); | 621 | spin_unlock_irqrestore(&priv->tx_lock, flags); |
621 | 622 | ||
622 | priv->fw_state = FW_STATE_OFF; | 623 | priv->fw_state = FW_STATE_OFF; |
623 | mutex_unlock(&priv->mutex); | 624 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index da6640afc835..6cc6cbc9234f 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -71,6 +71,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
71 | {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ | 71 | {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ |
72 | {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ | 72 | {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ |
73 | {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ | 73 | {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ |
74 | {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ | ||
74 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | 75 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ |
75 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | 76 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ |
76 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ | 77 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 05f94e21b423..5752aaae906b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -646,10 +646,8 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
646 | * Register HW. | 646 | * Register HW. |
647 | */ | 647 | */ |
648 | status = ieee80211_register_hw(rt2x00dev->hw); | 648 | status = ieee80211_register_hw(rt2x00dev->hw); |
649 | if (status) { | 649 | if (status) |
650 | rt2x00lib_remove_hw(rt2x00dev); | ||
651 | return status; | 650 | return status; |
652 | } | ||
653 | 651 | ||
654 | set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); | 652 | set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); |
655 | 653 | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 420fff42c0dd..853b2b279b64 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -2369,6 +2369,8 @@ static struct usb_device_id rt73usb_device_table[] = { | |||
2369 | /* Buffalo */ | 2369 | /* Buffalo */ |
2370 | { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, | 2370 | { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, |
2371 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, | 2371 | { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, |
2372 | { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2373 | { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, | ||
2372 | /* CNet */ | 2374 | /* CNet */ |
2373 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, | 2375 | { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, |
2374 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, | 2376 | { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a6f1d8a869bc..fbcbed6cad01 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -258,7 +258,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
258 | (chan->max_power - local->power_constr_level) : | 258 | (chan->max_power - local->power_constr_level) : |
259 | chan->max_power; | 259 | chan->max_power; |
260 | 260 | ||
261 | if (local->user_power_level) | 261 | if (local->user_power_level >= 0) |
262 | power = min(power, local->user_power_level); | 262 | power = min(power, local->user_power_level); |
263 | 263 | ||
264 | if (local->hw.conf.power_level != power) { | 264 | if (local->hw.conf.power_level != power) { |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 7ecda9d59d8a..1619e0cd26e2 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -441,6 +441,9 @@ static bool ieee80211_check_tim(struct ieee802_11_elems *elems, u16 aid) | |||
441 | u8 index, indexn1, indexn2; | 441 | u8 index, indexn1, indexn2; |
442 | struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; | 442 | struct ieee80211_tim_ie *tim = (struct ieee80211_tim_ie *) elems->tim; |
443 | 443 | ||
444 | if (unlikely(!tim || elems->tim_len < 4)) | ||
445 | return false; | ||
446 | |||
444 | aid &= 0x3fff; | 447 | aid &= 0x3fff; |
445 | index = aid / 8; | 448 | index = aid / 8; |
446 | mask = 1 << (aid & 7); | 449 | mask = 1 << (aid & 7); |
@@ -945,9 +948,13 @@ void ieee80211_beacon_loss_work(struct work_struct *work) | |||
945 | u.mgd.beacon_loss_work); | 948 | u.mgd.beacon_loss_work); |
946 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 949 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
947 | 950 | ||
948 | printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " | 951 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
949 | "- sending probe request\n", sdata->dev->name, | 952 | if (net_ratelimit()) { |
950 | sdata->u.mgd.bssid); | 953 | printk(KERN_DEBUG "%s: driver reports beacon loss from AP %pM " |
954 | "- sending probe request\n", sdata->dev->name, | ||
955 | sdata->u.mgd.bssid); | ||
956 | } | ||
957 | #endif | ||
951 | 958 | ||
952 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 959 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
953 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 960 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
@@ -1007,9 +1014,13 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata) | |||
1007 | (local->hw.conf.flags & IEEE80211_CONF_PS)) && | 1014 | (local->hw.conf.flags & IEEE80211_CONF_PS)) && |
1008 | time_after(jiffies, | 1015 | time_after(jiffies, |
1009 | ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) { | 1016 | ifmgd->last_beacon + IEEE80211_MONITORING_INTERVAL)) { |
1010 | printk(KERN_DEBUG "%s: beacon loss from AP %pM " | 1017 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1011 | "- sending probe request\n", | 1018 | if (net_ratelimit()) { |
1012 | sdata->dev->name, ifmgd->bssid); | 1019 | printk(KERN_DEBUG "%s: beacon loss from AP %pM " |
1020 | "- sending probe request\n", | ||
1021 | sdata->dev->name, ifmgd->bssid); | ||
1022 | } | ||
1023 | #endif | ||
1013 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; | 1024 | ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; |
1014 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, | 1025 | ieee80211_send_probe_req(sdata, ifmgd->bssid, ifmgd->ssid, |
1015 | ifmgd->ssid_len, NULL, 0); | 1026 | ifmgd->ssid_len, NULL, 0); |
@@ -2105,12 +2116,13 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work) | |||
2105 | struct ieee80211_local *local = | 2116 | struct ieee80211_local *local = |
2106 | container_of(work, struct ieee80211_local, | 2117 | container_of(work, struct ieee80211_local, |
2107 | dynamic_ps_enable_work); | 2118 | dynamic_ps_enable_work); |
2119 | /* XXX: using scan_sdata is completely broken! */ | ||
2108 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 2120 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
2109 | 2121 | ||
2110 | if (local->hw.conf.flags & IEEE80211_CONF_PS) | 2122 | if (local->hw.conf.flags & IEEE80211_CONF_PS) |
2111 | return; | 2123 | return; |
2112 | 2124 | ||
2113 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) | 2125 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK && sdata) |
2114 | ieee80211_send_nullfunc(local, sdata, 1); | 2126 | ieee80211_send_nullfunc(local, sdata, 1); |
2115 | 2127 | ||
2116 | local->hw.conf.flags |= IEEE80211_CONF_PS; | 2128 | local->hw.conf.flags |= IEEE80211_CONF_PS; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 64ebe664effc..5fa7aedd90ed 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -29,6 +29,7 @@ | |||
29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 29 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
30 | struct tid_ampdu_rx *tid_agg_rx, | 30 | struct tid_ampdu_rx *tid_agg_rx, |
31 | struct sk_buff *skb, | 31 | struct sk_buff *skb, |
32 | struct ieee80211_rx_status *status, | ||
32 | u16 mpdu_seq_num, | 33 | u16 mpdu_seq_num, |
33 | int bar_req); | 34 | int bar_req); |
34 | /* | 35 | /* |
@@ -1688,7 +1689,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1688 | /* manage reordering buffer according to requested */ | 1689 | /* manage reordering buffer according to requested */ |
1689 | /* sequence number */ | 1690 | /* sequence number */ |
1690 | rcu_read_lock(); | 1691 | rcu_read_lock(); |
1691 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, | 1692 | ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, NULL, NULL, |
1692 | start_seq_num, 1); | 1693 | start_seq_num, 1); |
1693 | rcu_read_unlock(); | 1694 | rcu_read_unlock(); |
1694 | return RX_DROP_UNUSABLE; | 1695 | return RX_DROP_UNUSABLE; |
@@ -2293,6 +2294,7 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
2293 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 2294 | static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, |
2294 | struct tid_ampdu_rx *tid_agg_rx, | 2295 | struct tid_ampdu_rx *tid_agg_rx, |
2295 | struct sk_buff *skb, | 2296 | struct sk_buff *skb, |
2297 | struct ieee80211_rx_status *rxstatus, | ||
2296 | u16 mpdu_seq_num, | 2298 | u16 mpdu_seq_num, |
2297 | int bar_req) | 2299 | int bar_req) |
2298 | { | 2300 | { |
@@ -2374,6 +2376,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2374 | 2376 | ||
2375 | /* put the frame in the reordering buffer */ | 2377 | /* put the frame in the reordering buffer */ |
2376 | tid_agg_rx->reorder_buf[index] = skb; | 2378 | tid_agg_rx->reorder_buf[index] = skb; |
2379 | memcpy(tid_agg_rx->reorder_buf[index]->cb, rxstatus, | ||
2380 | sizeof(*rxstatus)); | ||
2377 | tid_agg_rx->stored_mpdu_num++; | 2381 | tid_agg_rx->stored_mpdu_num++; |
2378 | /* release the buffer until next missing frame */ | 2382 | /* release the buffer until next missing frame */ |
2379 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) | 2383 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) |
@@ -2399,7 +2403,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2399 | } | 2403 | } |
2400 | 2404 | ||
2401 | static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | 2405 | static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, |
2402 | struct sk_buff *skb) | 2406 | struct sk_buff *skb, |
2407 | struct ieee80211_rx_status *status) | ||
2403 | { | 2408 | { |
2404 | struct ieee80211_hw *hw = &local->hw; | 2409 | struct ieee80211_hw *hw = &local->hw; |
2405 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2410 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -2448,7 +2453,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2448 | 2453 | ||
2449 | /* according to mpdu sequence number deal with reordering buffer */ | 2454 | /* according to mpdu sequence number deal with reordering buffer */ |
2450 | mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; | 2455 | mpdu_seq_num = (sc & IEEE80211_SCTL_SEQ) >> 4; |
2451 | ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, | 2456 | ret = ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb, status, |
2452 | mpdu_seq_num, 0); | 2457 | mpdu_seq_num, 0); |
2453 | end_reorder: | 2458 | end_reorder: |
2454 | return ret; | 2459 | return ret; |
@@ -2512,7 +2517,7 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2512 | return; | 2517 | return; |
2513 | } | 2518 | } |
2514 | 2519 | ||
2515 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2520 | if (!ieee80211_rx_reorder_ampdu(local, skb, status)) |
2516 | __ieee80211_rx_handle_packet(hw, skb, status, rate); | 2521 | __ieee80211_rx_handle_packet(hw, skb, status, rate); |
2517 | 2522 | ||
2518 | rcu_read_unlock(); | 2523 | rcu_read_unlock(); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index deb4ecec122a..959aa8379ccf 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -417,6 +417,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
417 | { | 417 | { |
418 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 418 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
419 | struct ieee80211_channel* chan = local->hw.conf.channel; | 419 | struct ieee80211_channel* chan = local->hw.conf.channel; |
420 | bool reconf = false; | ||
420 | u32 reconf_flags = 0; | 421 | u32 reconf_flags = 0; |
421 | int new_power_level; | 422 | int new_power_level; |
422 | 423 | ||
@@ -427,14 +428,38 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
427 | if (!chan) | 428 | if (!chan) |
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | 430 | ||
430 | if (data->txpower.fixed) | 431 | /* only change when not disabling */ |
431 | new_power_level = min(data->txpower.value, chan->max_power); | 432 | if (!data->txpower.disabled) { |
432 | else /* Automatic power level setting */ | 433 | if (data->txpower.fixed) { |
433 | new_power_level = chan->max_power; | 434 | if (data->txpower.value < 0) |
435 | return -EINVAL; | ||
436 | new_power_level = data->txpower.value; | ||
437 | /* | ||
438 | * Debatable, but we cannot do a fixed power | ||
439 | * level above the regulatory constraint. | ||
440 | * Use "iwconfig wlan0 txpower 15dBm" instead. | ||
441 | */ | ||
442 | if (new_power_level > chan->max_power) | ||
443 | return -EINVAL; | ||
444 | } else { | ||
445 | /* | ||
446 | * Automatic power level setting, max being the value | ||
447 | * passed in from userland. | ||
448 | */ | ||
449 | if (data->txpower.value < 0) | ||
450 | new_power_level = -1; | ||
451 | else | ||
452 | new_power_level = data->txpower.value; | ||
453 | } | ||
454 | |||
455 | reconf = true; | ||
434 | 456 | ||
435 | local->user_power_level = new_power_level; | 457 | /* |
436 | if (local->hw.conf.power_level != new_power_level) | 458 | * ieee80211_hw_config() will limit to the channel's |
437 | reconf_flags |= IEEE80211_CONF_CHANGE_POWER; | 459 | * max power and possibly power constraint from AP. |
460 | */ | ||
461 | local->user_power_level = new_power_level; | ||
462 | } | ||
438 | 463 | ||
439 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { | 464 | if (local->hw.conf.radio_enabled != !(data->txpower.disabled)) { |
440 | local->hw.conf.radio_enabled = !(data->txpower.disabled); | 465 | local->hw.conf.radio_enabled = !(data->txpower.disabled); |
@@ -442,7 +467,7 @@ static int ieee80211_ioctl_siwtxpower(struct net_device *dev, | |||
442 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); | 467 | ieee80211_led_radio(local, local->hw.conf.radio_enabled); |
443 | } | 468 | } |
444 | 469 | ||
445 | if (reconf_flags) | 470 | if (reconf || reconf_flags) |
446 | ieee80211_hw_config(local, reconf_flags); | 471 | ieee80211_hw_config(local, reconf_flags); |
447 | 472 | ||
448 | return 0; | 473 | return 0; |
@@ -530,7 +555,7 @@ static int ieee80211_ioctl_giwfrag(struct net_device *dev, | |||
530 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 555 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
531 | 556 | ||
532 | frag->value = local->fragmentation_threshold; | 557 | frag->value = local->fragmentation_threshold; |
533 | frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD); | 558 | frag->disabled = (frag->value >= IEEE80211_MAX_FRAG_THRESHOLD); |
534 | frag->fixed = 1; | 559 | frag->fixed = 1; |
535 | 560 | ||
536 | return 0; | 561 | return 0; |
diff --git a/net/wireless/core.h b/net/wireless/core.h index d43daa236ef9..0a592e4295f0 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -90,7 +90,7 @@ struct cfg80211_internal_bss { | |||
90 | struct rb_node rbn; | 90 | struct rb_node rbn; |
91 | unsigned long ts; | 91 | unsigned long ts; |
92 | struct kref ref; | 92 | struct kref ref; |
93 | bool hold; | 93 | bool hold, ies_allocated; |
94 | 94 | ||
95 | /* must be last because of priv member */ | 95 | /* must be last because of priv member */ |
96 | struct cfg80211_bss pub; | 96 | struct cfg80211_bss pub; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 6327e1617acb..6c1993d99902 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -2095,11 +2095,12 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2095 | /* Caller must hold cfg80211_mutex */ | 2095 | /* Caller must hold cfg80211_mutex */ |
2096 | void reg_device_remove(struct wiphy *wiphy) | 2096 | void reg_device_remove(struct wiphy *wiphy) |
2097 | { | 2097 | { |
2098 | struct wiphy *request_wiphy; | 2098 | struct wiphy *request_wiphy = NULL; |
2099 | 2099 | ||
2100 | assert_cfg80211_lock(); | 2100 | assert_cfg80211_lock(); |
2101 | 2101 | ||
2102 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 2102 | if (last_request) |
2103 | request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | ||
2103 | 2104 | ||
2104 | kfree(wiphy->regd); | 2105 | kfree(wiphy->regd); |
2105 | if (!last_request || !request_wiphy) | 2106 | if (!last_request || !request_wiphy) |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2a00e362f5fe..2ae65b39b529 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -58,6 +58,10 @@ static void bss_release(struct kref *ref) | |||
58 | bss = container_of(ref, struct cfg80211_internal_bss, ref); | 58 | bss = container_of(ref, struct cfg80211_internal_bss, ref); |
59 | if (bss->pub.free_priv) | 59 | if (bss->pub.free_priv) |
60 | bss->pub.free_priv(&bss->pub); | 60 | bss->pub.free_priv(&bss->pub); |
61 | |||
62 | if (bss->ies_allocated) | ||
63 | kfree(bss->pub.information_elements); | ||
64 | |||
61 | kfree(bss); | 65 | kfree(bss); |
62 | } | 66 | } |
63 | 67 | ||
@@ -360,19 +364,41 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, | |||
360 | 364 | ||
361 | found = rb_find_bss(dev, res); | 365 | found = rb_find_bss(dev, res); |
362 | 366 | ||
363 | if (found && overwrite) { | 367 | if (found) { |
364 | list_replace(&found->list, &res->list); | ||
365 | rb_replace_node(&found->rbn, &res->rbn, | ||
366 | &dev->bss_tree); | ||
367 | kref_put(&found->ref, bss_release); | ||
368 | found = res; | ||
369 | } else if (found) { | ||
370 | kref_get(&found->ref); | 368 | kref_get(&found->ref); |
371 | found->pub.beacon_interval = res->pub.beacon_interval; | 369 | found->pub.beacon_interval = res->pub.beacon_interval; |
372 | found->pub.tsf = res->pub.tsf; | 370 | found->pub.tsf = res->pub.tsf; |
373 | found->pub.signal = res->pub.signal; | 371 | found->pub.signal = res->pub.signal; |
374 | found->pub.capability = res->pub.capability; | 372 | found->pub.capability = res->pub.capability; |
375 | found->ts = res->ts; | 373 | found->ts = res->ts; |
374 | |||
375 | /* overwrite IEs */ | ||
376 | if (overwrite) { | ||
377 | size_t used = dev->wiphy.bss_priv_size + sizeof(*res); | ||
378 | size_t ielen = res->pub.len_information_elements; | ||
379 | |||
380 | if (ksize(found) >= used + ielen) { | ||
381 | memcpy(found->pub.information_elements, | ||
382 | res->pub.information_elements, ielen); | ||
383 | found->pub.len_information_elements = ielen; | ||
384 | } else { | ||
385 | u8 *ies = found->pub.information_elements; | ||
386 | |||
387 | if (found->ies_allocated) { | ||
388 | if (ksize(ies) < ielen) | ||
389 | ies = krealloc(ies, ielen, | ||
390 | GFP_ATOMIC); | ||
391 | } else | ||
392 | ies = kmalloc(ielen, GFP_ATOMIC); | ||
393 | |||
394 | if (ies) { | ||
395 | memcpy(ies, res->pub.information_elements, ielen); | ||
396 | found->ies_allocated = true; | ||
397 | found->pub.information_elements = ies; | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | |||
376 | kref_put(&res->ref, bss_release); | 402 | kref_put(&res->ref, bss_release); |
377 | } else { | 403 | } else { |
378 | /* this "consumes" the reference */ | 404 | /* this "consumes" the reference */ |