From ec9a1d8c13e36440eda0f3c79b8149080e3ab5ba Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Fri, 27 Mar 2009 22:51:58 +0100 Subject: b43: Poison RX buffers This patch adds poisoning and sanity checking to the RX DMA buffers. This is used for protection against buggy hardware/firmware that raises RX interrupts without doing an actual DMA transfer. This mechanism protects against rare "bad packets" (due to uninitialized skb data) and rare kernel crashes due to uninitialized RX headers. The poison is selected to not match on valid frames and to be cheap for checking. The poison check mechanism _might_ trigger incorrectly, if we are voluntarily receiving frames with bad PLCP headers. However, this is nonfatal, because the chance of such a match is basically zero and in case it happens it just results in dropping the packet. Bad-PLCP RX defaults to off, and you should leave it off unless you want to listen to the latest news broadcasted by your microwave oven. This patch also moves the initialization of the RX-header "length" field in front of the mapping of the DMA buffer. The CPU should not touch the buffer after we mapped it. Cc: stable@kernel.org Reported-by: Francesco Gringoli Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index e228c1de6e1..dfa6c72c3bd 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -555,11 +555,32 @@ address_error: return 1; } +static bool b43_rx_buffer_is_poisoned(struct b43_dmaring *ring, struct sk_buff *skb) +{ + unsigned char *f = skb->data + ring->frameoffset; + + return ((f[0] & f[1] & f[2] & f[3] & f[4] & f[5] & f[6] & f[7]) == 0xFF); +} + +static void b43_poison_rx_buffer(struct b43_dmaring *ring, struct sk_buff *skb) +{ + struct b43_rxhdr_fw4 *rxhdr; + unsigned char *frame; + + /* This poisons the RX buffer to detect DMA failures. */ + + rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); + rxhdr->frame_len = 0; + + B43_WARN_ON(ring->rx_buffersize < ring->frameoffset + sizeof(struct b43_plcp_hdr6) + 2); + frame = skb->data + ring->frameoffset; + memset(frame, 0xFF, sizeof(struct b43_plcp_hdr6) + 2 /* padding */); +} + static int setup_rx_descbuffer(struct b43_dmaring *ring, struct b43_dmadesc_generic *desc, struct b43_dmadesc_meta *meta, gfp_t gfp_flags) { - struct b43_rxhdr_fw4 *rxhdr; dma_addr_t dmaaddr; struct sk_buff *skb; @@ -568,6 +589,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); if (unlikely(!skb)) return -ENOMEM; + b43_poison_rx_buffer(ring, skb); dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { /* ugh. try to realloc in zone_dma */ @@ -578,6 +600,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags); if (unlikely(!skb)) return -ENOMEM; + b43_poison_rx_buffer(ring, skb); dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0); if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) { @@ -592,9 +615,6 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring, ring->ops->fill_descriptor(ring, desc, dmaaddr, ring->rx_buffersize, 0, 0, 0); - rxhdr = (struct b43_rxhdr_fw4 *)(skb->data); - rxhdr->frame_len = 0; - return 0; } @@ -1489,6 +1509,15 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) goto drop; } } + if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) { + /* Something went wrong with the DMA. + * The device did not touch the buffer and did not overwrite the poison. */ + b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n"); + /* recycle the descriptor buffer. */ + sync_descbuffer_for_device(ring, meta->dmaaddr, + ring->rx_buffersize); + goto drop; + } if (unlikely(len > ring->rx_buffersize)) { /* The data did not fit into one descriptor buffer * and is split over multiple buffers. -- cgit v1.2.3 From cf68636a9773aa97915497fe54fa4a51e3f08f3a Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 28 Mar 2009 00:41:25 +0100 Subject: b43: Refresh RX poison on buffer recycling The RX buffer poison needs to be refreshed, if we recycle an RX buffer, because it might be (partially) overwritten by some DMA operations. Cc: stable@kernel.org Cc: Francesco Gringoli Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/dma.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index dfa6c72c3bd..eae680b5305 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c @@ -1503,20 +1503,16 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) len = le16_to_cpu(rxhdr->frame_len); } while (len == 0 && i++ < 5); if (unlikely(len == 0)) { - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - goto drop; + dmaaddr = meta->dmaaddr; + goto drop_recycle_buffer; } } if (unlikely(b43_rx_buffer_is_poisoned(ring, skb))) { /* Something went wrong with the DMA. * The device did not touch the buffer and did not overwrite the poison. */ b43dbg(ring->dev->wl, "DMA RX: Dropping poisoned buffer.\n"); - /* recycle the descriptor buffer. */ - sync_descbuffer_for_device(ring, meta->dmaaddr, - ring->rx_buffersize); - goto drop; + dmaaddr = meta->dmaaddr; + goto drop_recycle_buffer; } if (unlikely(len > ring->rx_buffersize)) { /* The data did not fit into one descriptor buffer @@ -1530,6 +1526,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) while (1) { desc = ops->idx2desc(ring, *slot, &meta); /* recycle the descriptor buffer. */ + b43_poison_rx_buffer(ring, meta->skb); sync_descbuffer_for_device(ring, meta->dmaaddr, ring->rx_buffersize); *slot = next_slot(ring, *slot); @@ -1548,8 +1545,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) err = setup_rx_descbuffer(ring, desc, meta, GFP_ATOMIC); if (unlikely(err)) { b43dbg(ring->dev->wl, "DMA RX: setup_rx_descbuffer() failed\n"); - sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); - goto drop; + goto drop_recycle_buffer; } unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); @@ -1559,6 +1555,11 @@ static void dma_rx(struct b43_dmaring *ring, int *slot) b43_rx(ring->dev, skb, rxhdr); drop: return; + +drop_recycle_buffer: + /* Poison and recycle the RX buffer. */ + b43_poison_rx_buffer(ring, skb); + sync_descbuffer_for_device(ring, dmaaddr, ring->rx_buffersize); } void b43_dma_rx(struct b43_dmaring *ring) -- cgit v1.2.3 From 540828196e48ec54b64067a2b9defd870bff3ece Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Wed, 25 Mar 2009 03:11:44 +0100 Subject: p54: replace MAC80211_LEDS with P54_LEDS in p54.h I'm very sorry, as this change belongs to the other patch: "[PATCH] p54: fix SoftLED compile dependencies". however I must have somehow lost "git add" for that file. Signed-off-by: Christian Lamparter Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 2dda5fe418b..ecf8b6ed5a4 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h @@ -14,9 +14,9 @@ * published by the Free Software Foundation. */ -#ifdef CONFIG_MAC80211_LEDS +#ifdef CONFIG_P54_LEDS #include -#endif /* CONFIG_MAC80211_LEDS */ +#endif /* CONFIG_P54_LEDS */ enum p54_control_frame_types { P54_CONTROL_TYPE_SETUP = 0, @@ -116,7 +116,7 @@ enum fw_state { FW_STATE_RESETTING, }; -#ifdef CONFIG_MAC80211_LEDS +#ifdef CONFIG_P54_LEDS #define P54_LED_MAX_NAME_LEN 31 @@ -129,7 +129,7 @@ struct p54_led_dev { unsigned int registered; }; -#endif /* CONFIG_MAC80211_LEDS */ +#endif /* CONFIG_P54_LEDS */ struct p54_common { struct ieee80211_hw *hw; @@ -177,10 +177,10 @@ struct p54_common { u8 privacy_caps; u8 rx_keycache_size; /* LED management */ - #ifdef CONFIG_MAC80211_LEDS +#ifdef CONFIG_P54_LEDS struct p54_led_dev assoc_led; struct p54_led_dev tx_led; - #endif /* CONFIG_MAC80211_LEDS */ +#endif /* CONFIG_P54_LEDS */ u16 softled_state; /* bit field of glowing LEDs */ }; -- cgit v1.2.3 From 731c6531684250c46d732e369b25b003356f3947 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Mon, 30 Mar 2009 15:55:24 +0200 Subject: p54spi: fix locking warning in p54spi_op_tx This patch fixes the following waring: > ------------[ cut here ]------------ >WARNING: at kernel/softirq.c:138 local_bh_enable+0x54/0xbc() >Modules linked in: p54spi >[] (dump_stack+0x0/0x14) >[] (warn_on_slowpath+0x0/0x68) >[] (local_bh_enable+0x0/0xbc) >[] (p54spi_op_tx+0x0/0x4c [p54spi]) >[] (p54_sta_unlock+0x0/0x78) p54spi_op_tx needs to be called from different locking contexts. Therefore we have to protect the linked list with irqsave spinlocks. Reported-by: Max Filippov Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54spi.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c index 2b222aaa6f0..d1fe577de3d 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) struct ieee80211_tx_info *info; struct p54_tx_info *minfo; struct p54s_tx_info *dinfo; + unsigned long flags; int ret = 0; - spin_lock_bh(&priv->tx_lock); + spin_lock_irqsave(&priv->tx_lock, flags); while (!list_empty(&priv->tx_pending)) { entry = list_entry(priv->tx_pending.next, @@ -467,7 +468,7 @@ static int p54spi_wq_tx(struct p54s_priv *priv) list_del_init(&entry->tx_list); - spin_unlock_bh(&priv->tx_lock); + spin_unlock_irqrestore(&priv->tx_lock, flags); dinfo = container_of((void *) entry, struct p54s_tx_info, tx_list); @@ -479,16 +480,14 @@ static int p54spi_wq_tx(struct p54s_priv *priv) ret = p54spi_tx_frame(priv, skb); - spin_lock_bh(&priv->tx_lock); - if (ret < 0) { p54_free_skb(priv->hw, skb); - goto out; + return ret; } - } -out: - spin_unlock_bh(&priv->tx_lock); + spin_lock_irqsave(&priv->tx_lock, flags); + } + spin_unlock_irqrestore(&priv->tx_lock, flags); return ret; } @@ -498,12 +497,13 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct p54_tx_info *mi = (struct p54_tx_info *) info->rate_driver_data; struct p54s_tx_info *di = (struct p54s_tx_info *) mi->data; + unsigned long flags; BUILD_BUG_ON(sizeof(*di) > sizeof((mi->data))); - spin_lock_bh(&priv->tx_lock); + spin_lock_irqsave(&priv->tx_lock, flags); list_add_tail(&di->tx_list, &priv->tx_pending); - spin_unlock_bh(&priv->tx_lock); + spin_unlock_irqrestore(&priv->tx_lock, flags); queue_work(priv->hw->workqueue, &priv->work); } @@ -604,6 +604,7 @@ out: static void p54spi_op_stop(struct ieee80211_hw *dev) { struct p54s_priv *priv = dev->priv; + unsigned long flags; if (mutex_lock_interruptible(&priv->mutex)) { /* FIXME: how to handle this error? */ @@ -615,9 +616,9 @@ static void p54spi_op_stop(struct ieee80211_hw *dev) cancel_work_sync(&priv->work); p54spi_power_off(priv); - spin_lock_bh(&priv->tx_lock); + spin_lock_irqsave(&priv->tx_lock, flags); INIT_LIST_HEAD(&priv->tx_pending); - spin_unlock_bh(&priv->tx_lock); + spin_unlock_irqrestore(&priv->tx_lock, flags); priv->fw_state = FW_STATE_OFF; mutex_unlock(&priv->mutex); -- cgit v1.2.3 From c6dbe17f193c4adc8afc6884f26efb5fa27aa8af Mon Sep 17 00:00:00 2001 From: Masakazu Mokuno Date: Mon, 30 Mar 2009 11:04:36 -0700 Subject: net/ps3: Fix wireless AP connect error handling This patch fixes the bug that the driver tries to continue to connect(associate) to AP even if gelic_wl_do_{wpa,wep}_setup() fails, Signed-off-by: Masakazu Mokuno Signed-off-by: Geoff Levand Signed-off-by: John W. Linville --- drivers/net/ps3_gelic_wireless.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index a5ac2bd58b5..4f3ada622f9 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, if (ret) { pr_debug("%s: WEP/WPA setup failed %d\n", __func__, ret); + ret = -EPERM; + gelic_wl_send_iwap_event(wl, NULL); + goto out; } /* start association */ -- cgit v1.2.3 From 853da11b94e674445e93660f47a5f0aeeea09623 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Fri, 3 Apr 2009 20:10:26 -0400 Subject: ath9k: fix access to a freed skb in ath_rx_tasklet() Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/recv.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c index 71cb18d6757..dd1f3015674 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) int hdrlen, padsize, retval; bool decrypt_error = false; u8 keyix; + __le16 fc; spin_lock_bh(&sc->rx.rxbuflock); @@ -606,6 +607,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) /* see if any padding is done by the hw and remove it */ hdr = (struct ieee80211_hdr *)skb->data; hdrlen = ieee80211_get_hdrlen_from_skb(skb); + fc = hdr->frame_control; /* The MAC header is padded to have 32-bit boundary if the * packet payload is non-zero. The general calculation for @@ -690,7 +692,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) sc->rx.rxotherant = 0; } - if (ieee80211_is_beacon(hdr->frame_control) && + if (ieee80211_is_beacon(fc) && (sc->sc_flags & SC_OP_WAIT_FOR_BEACON)) { sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); -- cgit v1.2.3 From f54930f363113a9357c9ae008965b6484a61cd29 Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Tue, 7 Apr 2009 12:41:17 -0700 Subject: libertas: don't leak skb on receive error Don't lead memory when receive errors Signed-off-by: Philip Rakity Acked-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/rx.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c index 63d7e19ce9b..8e669775cb5 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) lbs_deb_rx("rx err: frame received with bad length\n"); dev->stats.rx_length_errors++; ret = 0; + dev_kfree_skb(skb); goto done; } @@ -181,6 +182,7 @@ int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) lbs_pr_alert("rxpd not ok\n"); dev->stats.rx_errors++; ret = 0; + dev_kfree_skb(skb); goto done; } -- cgit v1.2.3 From 02a9a39294017f105aedebcca5f49d552b18dbaa Mon Sep 17 00:00:00 2001 From: Jamie Lentin Date: Tue, 7 Apr 2009 22:59:56 +0100 Subject: at76c50x-usb: Add device ID for OQO model 01+ Add USB device ID for OQO 01+'s internal wireless LAN An OQO employee mentions the chip's true identity here:- ftp://ftp.oqo.com/unsupported/linux/OQOLinux.html Signed-off-by: Jamie Lentin Acked-by: Kalle Valo Signed-off-by: John W. Linville --- drivers/net/wireless/at76c50x-usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index 0c02f1c2bd9..744f4f4dd3d 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[] = { { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) }, /* Siemens Gigaset USB WLAN Adapter 11 */ { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) }, + /* OQO Model 01+ Internal Wi-Fi */ + { USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A) }, /* * at76c505amx-rfmd */ -- cgit v1.2.3 From 011f5c5bb20c08af93faa8bfd8d611c8cf85134f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 8 Apr 2009 10:15:17 -0400 Subject: airo: queue SIOCSIWAUTH-requested auth mode change for next commit Code was clearly wrong, plus callers expect the mode change to happen as soon as possible, not dropped on the floor until the next time some other config value changes and a commit happens. Signed-off-by: Dan Williams Signed-off-by: John W. Linville --- drivers/net/wireless/airo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index f21a6171c69..c36d3a3d655 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, local->config.authType = AUTH_ENCRYPT; } else return -EINVAL; - break; /* Commit the changes to flags if needed */ if (local->config.authType != currentAuthType) set_bit (FLAG_COMMIT, &local->flags); + break; } case IW_AUTH_WPA_ENABLED: -- cgit v1.2.3 From 4fc298b86635c60061bbd81cef8de2b031e5c4a7 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Tue, 24 Mar 2009 21:58:08 +0100 Subject: ar9170: add Cace Airpcap NX usb_id This patch adds a new device to ar9170usb. Reported-by: Mike Kershaw/Dragorn Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ar9170/usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c index ad296840893..43e8d8de9a5 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[] = { { USB_DEVICE(0x0cf3, 0x9170) }, /* Atheros TG121N */ { USB_DEVICE(0x0cf3, 0x1001) }, + /* Cace Airpcap NX */ + { USB_DEVICE(0xcace, 0x0300) }, /* D-Link DWA 160A */ { USB_DEVICE(0x07d1, 0x3c10) }, /* Netgear WNDA3100 */ -- cgit v1.2.3 From e3062403f5f71c48cf26e791e576f4feca4c9c0f Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sun, 29 Mar 2009 22:50:28 +0200 Subject: p54usb: add Telsey 802.11g USB2.0 Adapter Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/p54/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index da6640afc83..6cc6cbc9234 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 = { {USB_DEVICE(0x1260, 0xee22)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ + {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ -- cgit v1.2.3 From 6aabd4c4441133836ac969a9488458b37f83b677 Mon Sep 17 00:00:00 2001 From: Ivo van Doorn Date: Sat, 28 Mar 2009 20:52:14 +0100 Subject: rt2x00: Add rt73usb USB IDs Signed-off-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt73usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 420fff42c0d..853b2b279b6 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[] = { /* Buffalo */ { USB_DEVICE(0x0411, 0x00d8), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x0411, 0x00f4), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x0116), USB_DEVICE_DATA(&rt73usb_ops) }, + { USB_DEVICE(0x0411, 0x0119), USB_DEVICE_DATA(&rt73usb_ops) }, /* CNet */ { USB_DEVICE(0x1371, 0x9022), USB_DEVICE_DATA(&rt73usb_ops) }, { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) }, -- cgit v1.2.3 From 591f3dc200abb2100c473248a121ce14bfeeabd6 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 31 Mar 2009 12:27:32 +0200 Subject: b43: Do radio lock assertion in software The assertion of the lock-bit in the hardware register is unreliable, because there are devices with quirks that will randomly set the bit. Do the assertion in software, only. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/net/wireless/b43/main.c | 5 +++++ drivers/net/wireless/b43/phy_common.c | 16 ++++++++++++---- drivers/net/wireless/b43/phy_common.h | 4 +++- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 4896e083111..79b685e300c 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, phy->next_txpwr_check_time = jiffies; /* PHY TX errors counter. */ atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT); + +#if B43_DEBUG + phy->phy_locked = 0; + phy->radio_locked = 0; +#endif } 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 026b61c03fb..e176b6e0d9c 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) { u32 macctl; +#if B43_DEBUG + B43_WARN_ON(dev->phy.radio_locked); + dev->phy.radio_locked = 1; +#endif + macctl = b43_read32(dev, B43_MMIO_MACCTL); - B43_WARN_ON(macctl & B43_MACCTL_RADIOLOCK); macctl |= B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); - /* Commit the write and wait for the device - * to exit any radio register access. */ + /* Commit the write and wait for the firmware + * to finish any radio register access. */ b43_read32(dev, B43_MMIO_MACCTL); udelay(10); } @@ -145,11 +149,15 @@ void b43_radio_unlock(struct b43_wldev *dev) { u32 macctl; +#if B43_DEBUG + B43_WARN_ON(!dev->phy.radio_locked); + dev->phy.radio_locked = 0; +#endif + /* Commit any write */ b43_read16(dev, B43_MMIO_PHY_VER); /* unlock */ macctl = b43_read32(dev, B43_MMIO_MACCTL); - B43_WARN_ON(!(macctl & B43_MACCTL_RADIOLOCK)); macctl &= ~B43_MACCTL_RADIOLOCK; b43_write32(dev, B43_MMIO_MACCTL, macctl); } diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h index c9f5430d1d7..b2d99101947 100644 --- a/drivers/net/wireless/b43/phy_common.h +++ b/drivers/net/wireless/b43/phy_common.h @@ -245,8 +245,10 @@ struct b43_phy { atomic_t txerr_cnt; #ifdef CONFIG_B43_DEBUG - /* PHY registers locked by b43_phy_lock()? */ + /* PHY registers locked (w.r.t. firmware) */ bool phy_locked; + /* Radio registers locked (w.r.t. firmware) */ + bool radio_locked; #endif /* B43_DEBUG */ }; -- cgit v1.2.3 From d60cc91acdc45f234d8830409203f504d03513c9 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 9 Apr 2009 09:56:02 +0200 Subject: fix iwl3945 registration regression I forgot that iwl3945 registration is separate from iwlagn. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index ce729281ff6..8d738d75248 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) hw->wiphy->custom_regulatory = true; + hw->wiphy->max_scan_ssids = 1; /* WILL FIX */ + /* Default value; 4 EDCA QOS priorities */ hw->queues = 4; -- cgit v1.2.3 From f05faa31c387fb07f4c561350f00ba12cf673c9f Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Fri, 10 Apr 2009 18:05:14 -0300 Subject: rt2x00: prevent double kfree when failing to register hardware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In a scenario where there isn't any firmware available, we will have a double kfree of rt2x00dev->spec.channels_info when ieee80211_register_hw returns an error status inside rt2x00lib_probe_hw. The problem is that if ieee80211_register_hw fails, we call rt2x00lib_remove_hw twice: * first inside rt2x00lib_probe_hw upon failure of ieee80211_register_hw * error status is returned to rt2x00lib_probe_dev, which then sees it and calls in this case rt2x00lib_remove_dev that will again run rt2x00lib_remove_hw Prevent this avoiding calling rt2x00lib_remove_hw inside rt2x00lib_probe_hw Problem was detected with CONFIG_DEBUG_PAGEALLOC=y, CONFIG_SLUB_DEBUG=y, CONFIG_SLUB_DEBUG_ON=y, that dumps this with no firmware available: rt61pci 0000:00:07.0: PCI INT A -> GSI 19 (level, low) -> IRQ 19 wmaster0 (rt61pci): not using net_device_ops yet phy0: Selected rate control algorithm 'pid' phy0: Failed to initialize wep: -2 phy0 -> rt2x00lib_probe_dev: Error - Failed to initialize hw. ============================================================================= BUG kmalloc-128: Object already free ----------------------------------------------------------------------------- INFO: Allocated in rt61pci_probe_hw+0x3e5/0x6e0 [rt61pci] age=340 cpu=0 pid=21 INFO: Freed in rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] age=0 cpu=0 pid=21 INFO: Slab 0xc13ac3e0 objects=23 used=10 fp=0xdd59f6e0 flags=0x400000c3 INFO: Object 0xdd59f6e0 @offset=1760 fp=0xdd59f790 Bytes b4 0xdd59f6d0: 15 00 00 00 b2 8a fb ff 5a 5a 5a 5a 5a 5a 5a 5a ....².ûÿZZZZZZZZ Object 0xdd59f6e0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f6f0: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f700: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f710: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f720: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f730: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f740: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b kkkkkkkkkkkkkkkk Object 0xdd59f750: 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b 6b a5 kkkkkkkkkkkkkkk¥ Redzone 0xdd59f760: bb bb bb bb »»»» Padding 0xdd59f788: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ Pid: 21, comm: stage1 Not tainted 2.6.29.1-desktop-1.1mnb #1 Call Trace: [] print_trailer+0xd3/0x120 [] object_err+0x37/0x50 [] __slab_free+0xe7/0x2f0 [] kfree+0x7e/0xd0 [] ? rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] [] ? rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] [] rt2x00lib_remove_hw+0x59/0x70 [rt2x00lib] [] rt2x00lib_remove_dev+0x37/0x50 [rt2x00lib] [] rt2x00lib_probe_dev+0x1a7/0x3b0 [rt2x00lib] [] rt2x00pci_probe+0xdf/0x1ee [rt2x00pci] [] local_pci_probe+0xe/0x10 [] pci_device_probe+0x60/0x80 [] driver_probe_device+0x9a/0x2e0 [] __driver_attach+0x89/0x90 [] bus_for_each_dev+0x4b/0x70 [] ? pci_device_remove+0x0/0x40 [] driver_attach+0x19/0x20 [] ? __driver_attach+0x0/0x90 [] bus_add_driver+0x1cf/0x2a0 [] ? pci_device_remove+0x0/0x40 [] driver_register+0x69/0x140 [] __pci_register_driver+0x40/0x80 [] ? rt61pci_init+0x0/0x19 [rt61pci] [] rt61pci_init+0x17/0x19 [rt61pci] [] do_one_initcall+0x26/0x1c0 [] ? slab_pad_check+0x3c/0x120 [] ? slab_pad_check+0x3c/0x120 [] ? check_object+0xda/0x210 [] ? percpu_free+0x46/0x50 [] ? __slab_free+0x22e/0x2f0 [] ? percpu_free+0x46/0x50 [] ? percpu_free+0x46/0x50 [] ? percpu_free+0x46/0x50 [] ? stop_machine_destroy+0x3c/0x40 [] ? load_module+0xa5/0x1c50 [] ? rt61pci_eepromregister_read+0x0/0x40 [rt61pci] [] ? rt2x00pci_write_tx_data+0x0/0x90 [rt2x00pci] [] ? mutex_lock+0xb/0x20 [] ? mutex_lock+0xb/0x20 [] ? tracepoint_update_probe_range+0x76/0xa0 [] ? tracepoint_module_notify+0x2f/0x40 [] ? notifier_call_chain+0x2d/0x70 [] ? __blocking_notifier_call_chain+0x4d/0x60 [] ? blocking_notifier_call_chain+0x1a/0x20 [] sys_init_module+0x96/0x1d0 [] ? sys_munmap+0x46/0x60 [] syscall_call+0x7/0xb FIX kmalloc-128: Object at 0xdd59f6e0 not freed rt61pci 0000:00:07.0: PCI INT A disabled rt61pci: probe of 0000:00:07.0 failed with error -2 Signed-off-by: Herton Ronaldo Krzesinski Acked-by: Ivo van Doorn Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 05f94e21b42..5752aaae906 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) * Register HW. */ status = ieee80211_register_hw(rt2x00dev->hw); - if (status) { - rt2x00lib_remove_hw(rt2x00dev); + if (status) return status; - } set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags); -- cgit v1.2.3 From 91fe9ca74e8220f17e2fa71a92cda330857daac4 Mon Sep 17 00:00:00 2001 From: Pavel Roskin Date: Thu, 9 Apr 2009 21:41:05 -0400 Subject: orinoco: correct timeout logic in __orinoco_hw_set_tkip_key() If the value read from HERMES_RID_TXQUEUEEMPTY becomes 0 after exactly 100 readings, we wrongly consider it a timeout. Rewrite the clever while loop as a for loop that does the right thing and looks simpler. Reported by Juha Leppanen Signed-off-by: Pavel Roskin Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/hw.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 081428d9409..632fac86a30 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, } /* Wait upto 100ms for tx queue to empty */ - k = 100; - do { - k--; + for (k = 100; k > 0; k--) { udelay(1000); ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY, &xmitting); - if (ret) + if (ret || !xmitting) break; - } while ((k > 0) && xmitting); + } if (k == 0) ret = -ETIMEDOUT; -- cgit v1.2.3 From 1269fa737f21b3f643e4b12d3ac9938b142a7f00 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 10 Apr 2009 10:02:45 +0200 Subject: ar9170: fix struct layout on arm arm will pad even between u8's, so mark the structs/unions packed. Fixes a build bug on arm due to BUILD_BUG_ON tests in the code. Signed-off-by: Johannes Berg Reported-by: Al Viro Signed-off-by: John W. Linville --- drivers/net/wireless/ar9170/hw.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ar9170/hw.h b/drivers/net/wireless/ar9170/hw.h index 13091bd9d81..53e250a4278 100644 --- a/drivers/net/wireless/ar9170/hw.h +++ b/drivers/net/wireless/ar9170/hw.h @@ -310,7 +310,7 @@ struct ar9170_tx_control { struct ar9170_rx_head { u8 plcp[12]; -}; +} __packed; struct ar9170_rx_tail { union { @@ -318,16 +318,16 @@ struct ar9170_rx_tail { u8 rssi_ant0, rssi_ant1, rssi_ant2, rssi_ant0x, rssi_ant1x, rssi_ant2x, rssi_combined; - }; + } __packed; u8 rssi[7]; - }; + } __packed; u8 evm_stream0[6], evm_stream1[6]; u8 phy_err; u8 SAidx, DAidx; u8 error; u8 status; -}; +} __packed; #define AR9170_ENC_ALG_NONE 0x0 #define AR9170_ENC_ALG_WEP64 0x1 -- cgit v1.2.3 From 957b0516f7881284b48f2f2e4a909a1c5de0ddf8 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 17 Apr 2009 14:52:23 +0200 Subject: ar9170usb: add ZyXEL NWD271N Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ar9170/usb.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ar9170/usb.c b/drivers/net/wireless/ar9170/usb.c index 43e8d8de9a5..c9e422ead92 100644 --- a/drivers/net/wireless/ar9170/usb.c +++ b/drivers/net/wireless/ar9170/usb.c @@ -69,6 +69,8 @@ static struct usb_device_id ar9170_usb_ids[] = { { USB_DEVICE(0x0846, 0x9001) }, /* Zydas ZD1221 */ { USB_DEVICE(0x0ace, 0x1221) }, + /* ZyXEL NWD271N */ + { USB_DEVICE(0x0586, 0x3417) }, /* Z-Com UB81 BG */ { USB_DEVICE(0x0cde, 0x0023) }, /* Z-Com UB82 ABG */ -- cgit v1.2.3