diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/brcm80211/Kconfig | 4 | ||||
-rw-r--r-- | drivers/net/wireless/cw1200/cw1200_spi.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/cw1200/fwio.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/cw1200/hwbus.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/cw1200/hwio.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2800lib.c | 11 | ||||
-rw-r--r-- | drivers/net/wireless/rtl818x/rtl8187/dev.c | 15 |
7 files changed, 60 insertions, 16 deletions
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index fc8a0fa6d3b2..b00a7e92225f 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
@@ -28,7 +28,7 @@ config BRCMFMAC | |||
28 | 28 | ||
29 | config BRCMFMAC_SDIO | 29 | config BRCMFMAC_SDIO |
30 | bool "SDIO bus interface support for FullMAC driver" | 30 | bool "SDIO bus interface support for FullMAC driver" |
31 | depends on MMC | 31 | depends on (MMC = y || MMC = BRCMFMAC) |
32 | depends on BRCMFMAC | 32 | depends on BRCMFMAC |
33 | select FW_LOADER | 33 | select FW_LOADER |
34 | default y | 34 | default y |
@@ -39,7 +39,7 @@ config BRCMFMAC_SDIO | |||
39 | 39 | ||
40 | config BRCMFMAC_USB | 40 | config BRCMFMAC_USB |
41 | bool "USB bus interface support for FullMAC driver" | 41 | bool "USB bus interface support for FullMAC driver" |
42 | depends on USB | 42 | depends on (USB = y || USB = BRCMFMAC) |
43 | depends on BRCMFMAC | 43 | depends on BRCMFMAC |
44 | select FW_LOADER | 44 | select FW_LOADER |
45 | ---help--- | 45 | ---help--- |
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c index d06376014bcd..f5e6b489ed32 100644 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/cw1200/cw1200_spi.c | |||
@@ -40,7 +40,9 @@ struct hwbus_priv { | |||
40 | struct cw1200_common *core; | 40 | struct cw1200_common *core; |
41 | const struct cw1200_platform_data_spi *pdata; | 41 | const struct cw1200_platform_data_spi *pdata; |
42 | spinlock_t lock; /* Serialize all bus operations */ | 42 | spinlock_t lock; /* Serialize all bus operations */ |
43 | wait_queue_head_t wq; | ||
43 | int claimed; | 44 | int claimed; |
45 | int irq_disabled; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) | 48 | #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) |
@@ -197,8 +199,11 @@ static void cw1200_spi_lock(struct hwbus_priv *self) | |||
197 | { | 199 | { |
198 | unsigned long flags; | 200 | unsigned long flags; |
199 | 201 | ||
202 | DECLARE_WAITQUEUE(wait, current); | ||
203 | |||
200 | might_sleep(); | 204 | might_sleep(); |
201 | 205 | ||
206 | add_wait_queue(&self->wq, &wait); | ||
202 | spin_lock_irqsave(&self->lock, flags); | 207 | spin_lock_irqsave(&self->lock, flags); |
203 | while (1) { | 208 | while (1) { |
204 | set_current_state(TASK_UNINTERRUPTIBLE); | 209 | set_current_state(TASK_UNINTERRUPTIBLE); |
@@ -211,6 +216,7 @@ static void cw1200_spi_lock(struct hwbus_priv *self) | |||
211 | set_current_state(TASK_RUNNING); | 216 | set_current_state(TASK_RUNNING); |
212 | self->claimed = 1; | 217 | self->claimed = 1; |
213 | spin_unlock_irqrestore(&self->lock, flags); | 218 | spin_unlock_irqrestore(&self->lock, flags); |
219 | remove_wait_queue(&self->wq, &wait); | ||
214 | 220 | ||
215 | return; | 221 | return; |
216 | } | 222 | } |
@@ -222,6 +228,8 @@ static void cw1200_spi_unlock(struct hwbus_priv *self) | |||
222 | spin_lock_irqsave(&self->lock, flags); | 228 | spin_lock_irqsave(&self->lock, flags); |
223 | self->claimed = 0; | 229 | self->claimed = 0; |
224 | spin_unlock_irqrestore(&self->lock, flags); | 230 | spin_unlock_irqrestore(&self->lock, flags); |
231 | wake_up(&self->wq); | ||
232 | |||
225 | return; | 233 | return; |
226 | } | 234 | } |
227 | 235 | ||
@@ -230,6 +238,8 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id) | |||
230 | struct hwbus_priv *self = dev_id; | 238 | struct hwbus_priv *self = dev_id; |
231 | 239 | ||
232 | if (self->core) { | 240 | if (self->core) { |
241 | disable_irq_nosync(self->func->irq); | ||
242 | self->irq_disabled = 1; | ||
233 | cw1200_irq_handler(self->core); | 243 | cw1200_irq_handler(self->core); |
234 | return IRQ_HANDLED; | 244 | return IRQ_HANDLED; |
235 | } else { | 245 | } else { |
@@ -263,13 +273,22 @@ exit: | |||
263 | 273 | ||
264 | static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) | 274 | static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) |
265 | { | 275 | { |
266 | int ret = 0; | ||
267 | |||
268 | pr_debug("SW IRQ unsubscribe\n"); | 276 | pr_debug("SW IRQ unsubscribe\n"); |
269 | disable_irq_wake(self->func->irq); | 277 | disable_irq_wake(self->func->irq); |
270 | free_irq(self->func->irq, self); | 278 | free_irq(self->func->irq, self); |
271 | 279 | ||
272 | return ret; | 280 | return 0; |
281 | } | ||
282 | |||
283 | static int cw1200_spi_irq_enable(struct hwbus_priv *self, int enable) | ||
284 | { | ||
285 | /* Disables are handled by the interrupt handler */ | ||
286 | if (enable && self->irq_disabled) { | ||
287 | enable_irq(self->func->irq); | ||
288 | self->irq_disabled = 0; | ||
289 | } | ||
290 | |||
291 | return 0; | ||
273 | } | 292 | } |
274 | 293 | ||
275 | static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) | 294 | static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) |
@@ -349,6 +368,7 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = { | |||
349 | .unlock = cw1200_spi_unlock, | 368 | .unlock = cw1200_spi_unlock, |
350 | .align_size = cw1200_spi_align_size, | 369 | .align_size = cw1200_spi_align_size, |
351 | .power_mgmt = cw1200_spi_pm, | 370 | .power_mgmt = cw1200_spi_pm, |
371 | .irq_enable = cw1200_spi_irq_enable, | ||
352 | }; | 372 | }; |
353 | 373 | ||
354 | /* Probe Function to be called by SPI stack when device is discovered */ | 374 | /* Probe Function to be called by SPI stack when device is discovered */ |
@@ -400,6 +420,8 @@ static int cw1200_spi_probe(struct spi_device *func) | |||
400 | 420 | ||
401 | spi_set_drvdata(func, self); | 421 | spi_set_drvdata(func, self); |
402 | 422 | ||
423 | init_waitqueue_head(&self->wq); | ||
424 | |||
403 | status = cw1200_spi_irq_subscribe(self); | 425 | status = cw1200_spi_irq_subscribe(self); |
404 | 426 | ||
405 | status = cw1200_core_probe(&cw1200_spi_hwbus_ops, | 427 | status = cw1200_core_probe(&cw1200_spi_hwbus_ops, |
diff --git a/drivers/net/wireless/cw1200/fwio.c b/drivers/net/wireless/cw1200/fwio.c index acdff0f7f952..0b2061bbc68b 100644 --- a/drivers/net/wireless/cw1200/fwio.c +++ b/drivers/net/wireless/cw1200/fwio.c | |||
@@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv) | |||
485 | 485 | ||
486 | /* Enable interrupt signalling */ | 486 | /* Enable interrupt signalling */ |
487 | priv->hwbus_ops->lock(priv->hwbus_priv); | 487 | priv->hwbus_ops->lock(priv->hwbus_priv); |
488 | ret = __cw1200_irq_enable(priv, 1); | 488 | ret = __cw1200_irq_enable(priv, 2); |
489 | priv->hwbus_ops->unlock(priv->hwbus_priv); | 489 | priv->hwbus_ops->unlock(priv->hwbus_priv); |
490 | if (ret < 0) | 490 | if (ret < 0) |
491 | goto unsubscribe; | 491 | goto unsubscribe; |
diff --git a/drivers/net/wireless/cw1200/hwbus.h b/drivers/net/wireless/cw1200/hwbus.h index 8b2fc831c3de..51dfb3a90735 100644 --- a/drivers/net/wireless/cw1200/hwbus.h +++ b/drivers/net/wireless/cw1200/hwbus.h | |||
@@ -28,6 +28,7 @@ struct hwbus_ops { | |||
28 | void (*unlock)(struct hwbus_priv *self); | 28 | void (*unlock)(struct hwbus_priv *self); |
29 | size_t (*align_size)(struct hwbus_priv *self, size_t size); | 29 | size_t (*align_size)(struct hwbus_priv *self, size_t size); |
30 | int (*power_mgmt)(struct hwbus_priv *self, bool suspend); | 30 | int (*power_mgmt)(struct hwbus_priv *self, bool suspend); |
31 | int (*irq_enable)(struct hwbus_priv *self, int enable); | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | #endif /* CW1200_HWBUS_H */ | 34 | #endif /* CW1200_HWBUS_H */ |
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c index ff230b7aeedd..41bd7615ccaa 100644 --- a/drivers/net/wireless/cw1200/hwio.c +++ b/drivers/net/wireless/cw1200/hwio.c | |||
@@ -273,6 +273,21 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable) | |||
273 | u16 val16; | 273 | u16 val16; |
274 | int ret; | 274 | int ret; |
275 | 275 | ||
276 | /* We need to do this hack because the SPI layer can sleep on I/O | ||
277 | and the general path involves I/O to the device in interrupt | ||
278 | context. | ||
279 | |||
280 | However, the initial enable call needs to go to the hardware. | ||
281 | |||
282 | We don't worry about shutdown because we do a full reset which | ||
283 | clears the interrupt enabled bits. | ||
284 | */ | ||
285 | if (priv->hwbus_ops->irq_enable) { | ||
286 | ret = priv->hwbus_ops->irq_enable(priv->hwbus_priv, enable); | ||
287 | if (ret || enable < 2) | ||
288 | return ret; | ||
289 | } | ||
290 | |||
276 | if (HIF_8601_SILICON == priv->hw_type) { | 291 | if (HIF_8601_SILICON == priv->hw_type) { |
277 | ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); | 292 | ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); |
278 | if (ret < 0) { | 293 | if (ret < 0) { |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 95e6e61c3de0..88ce656f96cd 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -6659,19 +6659,20 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
6659 | rt2800_init_registers(rt2x00dev))) | 6659 | rt2800_init_registers(rt2x00dev))) |
6660 | return -EIO; | 6660 | return -EIO; |
6661 | 6661 | ||
6662 | if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev))) | ||
6663 | return -EIO; | ||
6664 | |||
6662 | /* | 6665 | /* |
6663 | * Send signal to firmware during boot time. | 6666 | * Send signal to firmware during boot time. |
6664 | */ | 6667 | */ |
6665 | rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); | 6668 | rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); |
6666 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); | 6669 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); |
6667 | if (rt2x00_is_usb(rt2x00dev)) { | 6670 | if (rt2x00_is_usb(rt2x00dev)) |
6668 | rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); | 6671 | rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); |
6669 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); | 6672 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); |
6670 | } | ||
6671 | msleep(1); | 6673 | msleep(1); |
6672 | 6674 | ||
6673 | if (unlikely(rt2800_wait_bbp_rf_ready(rt2x00dev) || | 6675 | if (unlikely(rt2800_wait_bbp_ready(rt2x00dev))) |
6674 | rt2800_wait_bbp_ready(rt2x00dev))) | ||
6675 | return -EIO; | 6676 | return -EIO; |
6676 | 6677 | ||
6677 | rt2800_init_bbp(rt2x00dev); | 6678 | rt2800_init_bbp(rt2x00dev); |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 841fb9dfc9da..9a6edb0c014e 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -438,17 +438,16 @@ static int rtl8187_init_urbs(struct ieee80211_hw *dev) | |||
438 | skb_queue_tail(&priv->rx_queue, skb); | 438 | skb_queue_tail(&priv->rx_queue, skb); |
439 | usb_anchor_urb(entry, &priv->anchored); | 439 | usb_anchor_urb(entry, &priv->anchored); |
440 | ret = usb_submit_urb(entry, GFP_KERNEL); | 440 | ret = usb_submit_urb(entry, GFP_KERNEL); |
441 | usb_put_urb(entry); | ||
441 | if (ret) { | 442 | if (ret) { |
442 | skb_unlink(skb, &priv->rx_queue); | 443 | skb_unlink(skb, &priv->rx_queue); |
443 | usb_unanchor_urb(entry); | 444 | usb_unanchor_urb(entry); |
444 | goto err; | 445 | goto err; |
445 | } | 446 | } |
446 | usb_free_urb(entry); | ||
447 | } | 447 | } |
448 | return ret; | 448 | return ret; |
449 | 449 | ||
450 | err: | 450 | err: |
451 | usb_free_urb(entry); | ||
452 | kfree_skb(skb); | 451 | kfree_skb(skb); |
453 | usb_kill_anchored_urbs(&priv->anchored); | 452 | usb_kill_anchored_urbs(&priv->anchored); |
454 | return ret; | 453 | return ret; |
@@ -956,8 +955,12 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
956 | (RETRY_COUNT << 8 /* short retry limit */) | | 955 | (RETRY_COUNT << 8 /* short retry limit */) | |
957 | (RETRY_COUNT << 0 /* long retry limit */) | | 956 | (RETRY_COUNT << 0 /* long retry limit */) | |
958 | (7 << 21 /* MAX TX DMA */)); | 957 | (7 << 21 /* MAX TX DMA */)); |
959 | rtl8187_init_urbs(dev); | 958 | ret = rtl8187_init_urbs(dev); |
960 | rtl8187b_init_status_urb(dev); | 959 | if (ret) |
960 | goto rtl8187_start_exit; | ||
961 | ret = rtl8187b_init_status_urb(dev); | ||
962 | if (ret) | ||
963 | usb_kill_anchored_urbs(&priv->anchored); | ||
961 | goto rtl8187_start_exit; | 964 | goto rtl8187_start_exit; |
962 | } | 965 | } |
963 | 966 | ||
@@ -966,7 +969,9 @@ static int rtl8187_start(struct ieee80211_hw *dev) | |||
966 | rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); | 969 | rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); |
967 | rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); | 970 | rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); |
968 | 971 | ||
969 | rtl8187_init_urbs(dev); | 972 | ret = rtl8187_init_urbs(dev); |
973 | if (ret) | ||
974 | goto rtl8187_start_exit; | ||
970 | 975 | ||
971 | reg = RTL818X_RX_CONF_ONLYERLPKT | | 976 | reg = RTL818X_RX_CONF_ONLYERLPKT | |
972 | RTL818X_RX_CONF_RX_AUTORESETPHY | | 977 | RTL818X_RX_CONF_RX_AUTORESETPHY | |