Commit a97b7c3a authored by David S. Miller's avatar David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

John W. Linville says:

====================
Regarding the Bluetooth bits, Gustavo says:

"First Bluetooth fixes to 3.12, it includes:

* 3 patches to add device id for 3 new hardwares.

* 2 patches from Johan to fix the rfkill behaviour during setup stage

* a small clean up in the rfcomm TTY code that fixes a potential racy
condition (by Gianluca Anzolin)

* 2 fixes to proper set encryption key size and security level in the
peripheral role of Bluetooth LE devices. (by Andre Guedes)

* a fix for dealing devices where pairing is not necessary, we were keeping
the Bluetooth ACL connection alive for too much time. (by Syam Sidhardhan)"

Also, I fixed-up an curly-brace indentation problem in the Bluetooth
code while merging.  On top of that...

Alexey Khoroshilov brings a p54usb fix to avoid a resource leak when
request_firmware_nowait fails.

Amitkumar Karwar fixes a firmware hang caused by too much header data
being appended for USB devices using the mwifiex driver.

Arend van Spriel provides three fixes: a brcmfmac fix to relocate some
driver code outside of an .init section; a scheduling while atomic
fix for bcma; and, another scheduling while atomic fix for brcmsmac.

Bing Zhao offers a pair of mwifiex fixes: a code change to avoid
firmware timeouts on USB; and a fix for a NULL pointer dereference.

Christian Lamparter adds a device ID to p54usb.

Felix Fietkau implements a quartet of small ath9k fixes, including
a locking fix, a list management fix, a fix to properly mark a stale
buffer, and an aggregate buffering fix.

Larry Finger champions a data alignment fix to make rtlwifi work
better with ARM builds.

Solomon Peachy reverts an earlier interrupt handling fix for cw1200
and replaces it with a new threaded oneshot irq handler implementation.

Sujith Manoharan fixes an ath9k regression by reverting an earlier
patch.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 89f077a0 0a878747
...@@ -210,25 +210,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc) ...@@ -210,25 +210,6 @@ static void bcma_core_pci_config_fixup(struct bcma_drv_pci *pc)
} }
} }
static void bcma_core_pci_power_save(struct bcma_drv_pci *pc, bool up)
{
u16 data;
if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
data = up ? 0x74 : 0x7C;
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
data = up ? 0x75 : 0x7D;
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
}
}
/************************************************** /**************************************************
* Init. * Init.
**************************************************/ **************************************************/
...@@ -255,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) ...@@ -255,6 +236,32 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
bcma_core_pci_clientmode_init(pc); bcma_core_pci_clientmode_init(pc);
} }
void bcma_core_pci_power_save(struct bcma_bus *bus, bool up)
{
struct bcma_drv_pci *pc;
u16 data;
if (bus->hosttype != BCMA_HOSTTYPE_PCI)
return;
pc = &bus->drv_pci[0];
if (pc->core->id.rev >= 15 && pc->core->id.rev <= 20) {
data = up ? 0x74 : 0x7C;
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7F64);
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
} else if (pc->core->id.rev >= 21 && pc->core->id.rev <= 22) {
data = up ? 0x75 : 0x7D;
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT1, 0x7E65);
bcma_pcie_mdio_writeread(pc, BCMA_CORE_PCI_MDIO_BLK1,
BCMA_CORE_PCI_MDIO_BLK1_MGMT3, data);
}
}
EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
bool enable) bool enable)
{ {
...@@ -310,8 +317,6 @@ void bcma_core_pci_up(struct bcma_bus *bus) ...@@ -310,8 +317,6 @@ void bcma_core_pci_up(struct bcma_bus *bus)
pc = &bus->drv_pci[0]; pc = &bus->drv_pci[0];
bcma_core_pci_power_save(pc, true);
bcma_core_pci_extend_L1timer(pc, true); bcma_core_pci_extend_L1timer(pc, true);
} }
EXPORT_SYMBOL_GPL(bcma_core_pci_up); EXPORT_SYMBOL_GPL(bcma_core_pci_up);
...@@ -326,7 +331,5 @@ void bcma_core_pci_down(struct bcma_bus *bus) ...@@ -326,7 +331,5 @@ void bcma_core_pci_down(struct bcma_bus *bus)
pc = &bus->drv_pci[0]; pc = &bus->drv_pci[0];
bcma_core_pci_extend_L1timer(pc, false); bcma_core_pci_extend_L1timer(pc, false);
bcma_core_pci_power_save(pc, false);
} }
EXPORT_SYMBOL_GPL(bcma_core_pci_down); EXPORT_SYMBOL_GPL(bcma_core_pci_down);
...@@ -85,6 +85,7 @@ static struct usb_device_id ath3k_table[] = { ...@@ -85,6 +85,7 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x04CA, 0x3008) }, { USB_DEVICE(0x04CA, 0x3008) },
{ USB_DEVICE(0x13d3, 0x3362) }, { USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) }, { USB_DEVICE(0x0CF3, 0xE004) },
{ USB_DEVICE(0x0CF3, 0xE005) },
{ USB_DEVICE(0x0930, 0x0219) }, { USB_DEVICE(0x0930, 0x0219) },
{ USB_DEVICE(0x0489, 0xe057) }, { USB_DEVICE(0x0489, 0xe057) },
{ USB_DEVICE(0x13d3, 0x3393) }, { USB_DEVICE(0x13d3, 0x3393) },
...@@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { ...@@ -126,6 +127,7 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
......
...@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = { ...@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */ /* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0b05, 0x17b5) }, { USB_DEVICE(0x0b05, 0x17b5) },
{ USB_DEVICE(0x0b05, 0x17cb) },
{ USB_DEVICE(0x04ca, 0x2003) }, { USB_DEVICE(0x04ca, 0x2003) },
{ USB_DEVICE(0x0489, 0xe042) }, { USB_DEVICE(0x0489, 0xe042) },
{ USB_DEVICE(0x413c, 0x8197) }, { USB_DEVICE(0x413c, 0x8197) },
...@@ -112,6 +113,9 @@ static struct usb_device_id btusb_table[] = { ...@@ -112,6 +113,9 @@ static struct usb_device_id btusb_table[] = {
/*Broadcom devices with vendor specific id */ /*Broadcom devices with vendor specific id */
{ USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) }, { USB_VENDOR_AND_INTERFACE_INFO(0x0a5c, 0xff, 0x01, 0x01) },
/* Belkin F8065bf - Broadcom based */
{ USB_VENDOR_AND_INTERFACE_INFO(0x050d, 0xff, 0x01, 0x01) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
...@@ -148,6 +152,7 @@ static struct usb_device_id blacklist_table[] = { ...@@ -148,6 +152,7 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
......
...@@ -1269,13 +1269,6 @@ static void ath9k_antenna_check(struct ath_softc *sc, ...@@ -1269,13 +1269,6 @@ static void ath9k_antenna_check(struct ath_softc *sc,
if (!(ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)) if (!(ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB))
return; return;
/*
* All MPDUs in an aggregate will use the same LNA
* as the first MPDU.
*/
if (rs->rs_isaggr && !rs->rs_firstaggr)
return;
/* /*
* Change the default rx antenna if rx diversity * Change the default rx antenna if rx diversity
* chooses the other antenna 3 times in a row. * chooses the other antenna 3 times in a row.
......
...@@ -399,6 +399,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) ...@@ -399,6 +399,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
tbf->bf_buf_addr = bf->bf_buf_addr; tbf->bf_buf_addr = bf->bf_buf_addr;
memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len);
tbf->bf_state = bf->bf_state; tbf->bf_state = bf->bf_state;
tbf->bf_state.stale = false;
return tbf; return tbf;
} }
...@@ -1389,11 +1390,15 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, ...@@ -1389,11 +1390,15 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
u16 tid, u16 *ssn) u16 tid, u16 *ssn)
{ {
struct ath_atx_tid *txtid; struct ath_atx_tid *txtid;
struct ath_txq *txq;
struct ath_node *an; struct ath_node *an;
u8 density; u8 density;
an = (struct ath_node *)sta->drv_priv; an = (struct ath_node *)sta->drv_priv;
txtid = ATH_AN_2_TID(an, tid); txtid = ATH_AN_2_TID(an, tid);
txq = txtid->ac->txq;
ath_txq_lock(sc, txq);
/* update ampdu factor/density, they may have changed. This may happen /* update ampdu factor/density, they may have changed. This may happen
* in HT IBSS when a beacon with HT-info is received after the station * in HT IBSS when a beacon with HT-info is received after the station
...@@ -1417,6 +1422,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, ...@@ -1417,6 +1422,8 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf)); memset(txtid->tx_buf, 0, sizeof(txtid->tx_buf));
txtid->baw_head = txtid->baw_tail = 0; txtid->baw_head = txtid->baw_tail = 0;
ath_txq_unlock_complete(sc, txq);
return 0; return 0;
} }
...@@ -1555,8 +1562,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, ...@@ -1555,8 +1562,10 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
__skb_unlink(bf->bf_mpdu, tid_q); __skb_unlink(bf->bf_mpdu, tid_q);
list_add_tail(&bf->list, &bf_q); list_add_tail(&bf->list, &bf_q);
ath_set_rates(tid->an->vif, tid->an->sta, bf); ath_set_rates(tid->an->vif, tid->an->sta, bf);
ath_tx_addto_baw(sc, tid, bf); if (bf_isampdu(bf)) {
bf->bf_state.bf_type &= ~BUF_AGGR; ath_tx_addto_baw(sc, tid, bf);
bf->bf_state.bf_type &= ~BUF_AGGR;
}
if (bf_tail) if (bf_tail)
bf_tail->bf_next = bf; bf_tail->bf_next = bf;
...@@ -1950,7 +1959,9 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, ...@@ -1950,7 +1959,9 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
if (bf_is_ampdu_not_probing(bf)) if (bf_is_ampdu_not_probing(bf))
txq->axq_ampdu_depth++; txq->axq_ampdu_depth++;
bf = bf->bf_lastbf->bf_next; bf_last = bf->bf_lastbf;
bf = bf_last->bf_next;
bf_last->bf_next = NULL;
} }
} }
} }
......
...@@ -464,8 +464,6 @@ static struct sdio_driver brcmf_sdmmc_driver = { ...@@ -464,8 +464,6 @@ static struct sdio_driver brcmf_sdmmc_driver = {
static int brcmf_sdio_pd_probe(struct platform_device *pdev) static int brcmf_sdio_pd_probe(struct platform_device *pdev)
{ {
int ret;
brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Enter\n");
brcmfmac_sdio_pdata = pdev->dev.platform_data; brcmfmac_sdio_pdata = pdev->dev.platform_data;
...@@ -473,11 +471,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev) ...@@ -473,11 +471,7 @@ static int brcmf_sdio_pd_probe(struct platform_device *pdev)
if (brcmfmac_sdio_pdata->power_on) if (brcmfmac_sdio_pdata->power_on)
brcmfmac_sdio_pdata->power_on(); brcmfmac_sdio_pdata->power_on();
ret = sdio_register_driver(&brcmf_sdmmc_driver); return 0;
if (ret)
brcmf_err("sdio_register_driver failed: %d\n", ret);
return ret;
} }
static int brcmf_sdio_pd_remove(struct platform_device *pdev) static int brcmf_sdio_pd_remove(struct platform_device *pdev)
...@@ -500,6 +494,15 @@ static struct platform_driver brcmf_sdio_pd = { ...@@ -500,6 +494,15 @@ static struct platform_driver brcmf_sdio_pd = {
} }
}; };
void brcmf_sdio_register(void)
{
int ret;
ret = sdio_register_driver(&brcmf_sdmmc_driver);
if (ret)
brcmf_err("sdio_register_driver failed: %d\n", ret);
}
void brcmf_sdio_exit(void) void brcmf_sdio_exit(void)
{ {
brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Enter\n");
...@@ -510,18 +513,13 @@ void brcmf_sdio_exit(void) ...@@ -510,18 +513,13 @@ void brcmf_sdio_exit(void)
sdio_unregister_driver(&brcmf_sdmmc_driver); sdio_unregister_driver(&brcmf_sdmmc_driver);
} }
void brcmf_sdio_init(void) void __init brcmf_sdio_init(void)
{ {
int ret; int ret;
brcmf_dbg(SDIO, "Enter\n"); brcmf_dbg(SDIO, "Enter\n");
ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe);
if (ret == -ENODEV) { if (ret == -ENODEV)
brcmf_dbg(SDIO, "No platform data available, registering without.\n"); brcmf_dbg(SDIO, "No platform data available.\n");
ret = sdio_register_driver(&brcmf_sdmmc_driver);
}
if (ret)
brcmf_err("driver registration failed: %d\n", ret);
} }
...@@ -156,10 +156,11 @@ extern int brcmf_bus_start(struct device *dev); ...@@ -156,10 +156,11 @@ extern int brcmf_bus_start(struct device *dev);
#ifdef CONFIG_BRCMFMAC_SDIO #ifdef CONFIG_BRCMFMAC_SDIO
extern void brcmf_sdio_exit(void); extern void brcmf_sdio_exit(void);
extern void brcmf_sdio_init(void); extern void brcmf_sdio_init(void);
extern void brcmf_sdio_register(void);
#endif #endif
#ifdef CONFIG_BRCMFMAC_USB #ifdef CONFIG_BRCMFMAC_USB
extern void brcmf_usb_exit(void); extern void brcmf_usb_exit(void);
extern void brcmf_usb_init(void); extern void brcmf_usb_register(void);
#endif #endif
#endif /* _BRCMF_BUS_H_ */ #endif /* _BRCMF_BUS_H_ */
...@@ -1231,21 +1231,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp) ...@@ -1231,21 +1231,23 @@ u32 brcmf_get_chip_info(struct brcmf_if *ifp)
return bus->chip << 4 | bus->chiprev; return bus->chip << 4 | bus->chiprev;
} }
static void brcmf_driver_init(struct work_struct *work) static void brcmf_driver_register(struct work_struct *work)
{ {
brcmf_debugfs_init();
#ifdef CONFIG_BRCMFMAC_SDIO #ifdef CONFIG_BRCMFMAC_SDIO
brcmf_sdio_init(); brcmf_sdio_register();
#endif #endif
#ifdef CONFIG_BRCMFMAC_USB #ifdef CONFIG_BRCMFMAC_USB
brcmf_usb_init(); brcmf_usb_register();
#endif #endif
} }
static DECLARE_WORK(brcmf_driver_work, brcmf_driver_init); static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register);
static int __init brcmfmac_module_init(void) static int __init brcmfmac_module_init(void)
{ {
brcmf_debugfs_init();
#ifdef CONFIG_BRCMFMAC_SDIO
brcmf_sdio_init();
#endif
if (!schedule_work(&brcmf_driver_work)) if (!schedule_work(&brcmf_driver_work))
return -EBUSY; return -EBUSY;
......
...@@ -1539,7 +1539,7 @@ void brcmf_usb_exit(void) ...@@ -1539,7 +1539,7 @@ void brcmf_usb_exit(void)
brcmf_release_fw(&fw_image_list); brcmf_release_fw(&fw_image_list);
} }
void brcmf_usb_init(void) void brcmf_usb_register(void)
{ {
brcmf_dbg(USB, "Enter\n"); brcmf_dbg(USB, "Enter\n");
INIT_LIST_HEAD(&fw_image_list); INIT_LIST_HEAD(&fw_image_list);
......
...@@ -457,6 +457,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) ...@@ -457,6 +457,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
if (err != 0) if (err != 0)
brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n",
__func__, err); __func__, err);
bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, true);
return err; return err;
} }
...@@ -479,6 +481,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) ...@@ -479,6 +481,8 @@ static void brcms_ops_stop(struct ieee80211_hw *hw)
return; return;
} }
bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, false);
/* put driver in down state */ /* put driver in down state */
spin_lock_bh(&wl->lock); spin_lock_bh(&wl->lock);
brcms_down(wl); brcms_down(wl);
......
...@@ -42,7 +42,6 @@ struct hwbus_priv { ...@@ -42,7 +42,6 @@ struct hwbus_priv {
spinlock_t lock; /* Serialize all bus operations */ spinlock_t lock; /* Serialize all bus operations */
wait_queue_head_t wq; wait_queue_head_t wq;
int claimed; int claimed;
int irq_disabled;
}; };
#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) #define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2)
...@@ -238,8 +237,6 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id) ...@@ -238,8 +237,6 @@ static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id)
struct hwbus_priv *self = dev_id; struct hwbus_priv *self = dev_id;
if (self->core) { if (self->core) {
disable_irq_nosync(self->func->irq);
self->irq_disabled = 1;
cw1200_irq_handler(self->core); cw1200_irq_handler(self->core);
return IRQ_HANDLED; return IRQ_HANDLED;
} else { } else {
...@@ -253,9 +250,10 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self) ...@@ -253,9 +250,10 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
pr_debug("SW IRQ subscribe\n"); pr_debug("SW IRQ subscribe\n");
ret = request_any_context_irq(self->func->irq, cw1200_spi_irq_handler, ret = request_threaded_irq(self->func->irq, NULL,
IRQF_TRIGGER_HIGH, cw1200_spi_irq_handler,
"cw1200_wlan_irq", self); IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"cw1200_wlan_irq", self);
if (WARN_ON(ret < 0)) if (WARN_ON(ret < 0))
goto exit; goto exit;
...@@ -273,22 +271,13 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self) ...@@ -273,22 +271,13 @@ static int cw1200_spi_irq_subscribe(struct hwbus_priv *self)
static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self)
{ {
int ret = 0;
pr_debug("SW IRQ unsubscribe\n"); pr_debug("SW IRQ unsubscribe\n");
disable_irq_wake(self->func->irq); disable_irq_wake(self->func->irq);
free_irq(self->func->irq, self); free_irq(self->func->irq, self);
return 0; return ret;
}
static int cw1200_spi_irq_enable(struct hwbus_priv *self, int enable)
{
/* Disables are handled by the interrupt handler */
if (enable && self->irq_disabled) {
enable_irq(self->func->irq);
self->irq_disabled = 0;
}
return 0;
} }
static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata)
...@@ -368,7 +357,6 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = { ...@@ -368,7 +357,6 @@ static struct hwbus_ops cw1200_spi_hwbus_ops = {
.unlock = cw1200_spi_unlock, .unlock = cw1200_spi_unlock,
.align_size = cw1200_spi_align_size, .align_size = cw1200_spi_align_size,
.power_mgmt = cw1200_spi_pm, .power_mgmt = cw1200_spi_pm,
.irq_enable = cw1200_spi_irq_enable,
}; };
/* Probe Function to be called by SPI stack when device is discovered */ /* Probe Function to be called by SPI stack when device is discovered */
......
...@@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv) ...@@ -485,7 +485,7 @@ int cw1200_load_firmware(struct cw1200_common *priv)
/* Enable interrupt signalling */ /* Enable interrupt signalling */
priv->hwbus_ops->lock(priv->hwbus_priv); priv->hwbus_ops->lock(priv->hwbus_priv);
ret = __cw1200_irq_enable(priv, 2); ret = __cw1200_irq_enable(priv, 1);
priv->hwbus_ops->unlock(priv->hwbus_priv); priv->hwbus_ops->unlock(priv->hwbus_priv);
if (ret < 0) if (ret < 0)
goto unsubscribe; goto unsubscribe;
......
...@@ -28,7 +28,6 @@ struct hwbus_ops { ...@@ -28,7 +28,6 @@ struct hwbus_ops {
void (*unlock)(struct hwbus_priv *self); void (*unlock)(struct hwbus_priv *self);
size_t (*align_size)(struct hwbus_priv *self, size_t size); size_t (*align_size)(struct hwbus_priv *self, size_t size);
int (*power_mgmt)(struct hwbus_priv *self, bool suspend); int (*power_mgmt)(struct hwbus_priv *self, bool suspend);
int (*irq_enable)(struct hwbus_priv *self, int enable);
}; };
#endif /* CW1200_HWBUS_H */ #endif /* CW1200_HWBUS_H */
...@@ -273,21 +273,6 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable) ...@@ -273,21 +273,6 @@ int __cw1200_irq_enable(struct cw1200_common *priv, int enable)
u16 val16; u16 val16;
int ret; int ret;
/* We need to do this hack because the SPI layer can sleep on I/O
and the general path involves I/O to the device in interrupt
context.
However, the initial enable call needs to go to the hardware.
We don't worry about shutdown because we do a full reset which
clears the interrupt enabled bits.
*/
if (priv->hwbus_ops->irq_enable) {
ret = priv->hwbus_ops->irq_enable(priv->hwbus_priv, enable);
if (ret || enable < 2)
return ret;
}
if (HIF_8601_SILICON == priv->hw_type) { if (HIF_8601_SILICON == priv->hw_type) {
ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32); ret = __cw1200_reg_read_32(priv, ST90TDS_CONFIG_REG_ID, &val32);
if (ret < 0) { if (ret < 0) {
......
...@@ -150,7 +150,7 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, ...@@ -150,7 +150,7 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv,
*/ */
int int
mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *pra_list, int headroom, struct mwifiex_ra_list_tbl *pra_list,
int ptrindex, unsigned long ra_list_flags) int ptrindex, unsigned long ra_list_flags)
__releases(&priv->wmm.ra_list_spinlock) __releases(&priv->wmm.ra_list_spinlock)
{ {
...@@ -160,6 +160,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ...@@ -160,6 +160,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
int pad = 0, ret; int pad = 0, ret;
struct mwifiex_tx_param tx_param; struct mwifiex_tx_param tx_param;
struct txpd *ptx_pd = NULL; struct txpd *ptx_pd = NULL;
int headroom = adapter->iface_type == MWIFIEX_USB ? 0 : INTF_HEADER_LEN;
skb_src = skb_peek(&pra_list->skb_head); skb_src = skb_peek(&pra_list->skb_head);
if (!skb_src) { if (!skb_src) {
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv, int mwifiex_11n_deaggregate_pkt(struct mwifiex_private *priv,
struct sk_buff *skb); struct sk_buff *skb);
int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, int mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
struct mwifiex_ra_list_tbl *ptr, int headroom, struct mwifiex_ra_list_tbl *ptr,
int ptr_index, unsigned long flags) int ptr_index, unsigned long flags)
__releases(&priv->wmm.ra_list_spinlock); __releases(&priv->wmm.ra_list_spinlock);
......
...@@ -1155,7 +1155,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, ...@@ -1155,7 +1155,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions); uint32_t conditions = le32_to_cpu(phs_cfg->params.hs_config.conditions);
if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) && if (phs_cfg->action == cpu_to_le16(HS_ACTIVATE) &&
adapter->iface_type == MWIFIEX_SDIO) { adapter->iface_type != MWIFIEX_USB) {
mwifiex_hs_activated_event(priv, true); mwifiex_hs_activated_event(priv, true);
return 0; return 0;
} else { } else {
...@@ -1167,8 +1167,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv, ...@@ -1167,8 +1167,7 @@ int mwifiex_ret_802_11_hs_cfg(struct mwifiex_private *priv,
} }
if (conditions != HS_CFG_CANCEL) { if (conditions != HS_CFG_CANCEL) {
adapter->is_hs_configured = true; adapter->is_hs_configured = true;
if (adapter->iface_type == MWIFIEX_USB || if (adapter->iface_type == MWIFIEX_USB)
adapter->iface_type == MWIFIEX_PCIE)
mwifiex_hs_activated_event(priv, true); mwifiex_hs_activated_event(priv, true);
} else { } else {
adapter->is_hs_configured = false; adapter->is_hs_configured = false;
......
...@@ -447,9 +447,6 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message) ...@@ -447,9 +447,6 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
*/ */
adapter->is_suspended = true; adapter->is_suspended = true;
for (i = 0; i < adapter->priv_num; i++)
netif_carrier_off(adapter->priv[i]->netdev);
if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb) if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
usb_kill_urb(card->rx_cmd.urb); usb_kill_urb(card->rx_cmd.urb);
...@@ -509,10 +506,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf) ...@@ -509,10 +506,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
MWIFIEX_RX_CMD_BUF_SIZE); MWIFIEX_RX_CMD_BUF_SIZE);
} }
for (i = 0; i < adapter->priv_num; i++)
if (adapter->priv[i]->media_connected)
netif_carrier_on(adapter->priv[i]->netdev);
/* Disable Host Sleep */ /* Disable Host Sleep */
if (adapter->hs_activated) if (adapter->hs_activated)
mwifiex_cancel_hs(mwifiex_get_priv(adapter, mwifiex_cancel_hs(mwifiex_get_priv(adapter,
......
...@@ -1239,8 +1239,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) ...@@ -1239,8 +1239,7 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) && if (enable_tx_amsdu && mwifiex_is_amsdu_allowed(priv, tid) &&
mwifiex_is_11n_aggragation_possible(priv, ptr, mwifiex_is_11n_aggragation_possible(priv, ptr,
adapter->tx_buf_size)) adapter->tx_buf_size))
mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
ptr_index, flags);
/* ra_list_spinlock has been freed in /* ra_list_spinlock has been freed in
mwifiex_11n_aggregate_pkt() */ mwifiex_11n_aggregate_pkt() */
else else
......
...@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = { ...@@ -83,6 +83,7 @@ static struct usb_device_id p54u_table[] = {
{USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */ {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
{USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
{USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
{USB_DEVICE(0x07aa, 0x0020)}, /* Corega WLUSB2GTST USB */
{USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */ {USB_DEVICE(0x0803, 0x4310)}, /* Zoom 4410a */
{USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
{USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */ {USB_DEVICE(0x083a, 0x4531)}, /* T-Com Sinus 154 data II */
...@@ -979,6 +980,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev, ...@@ -979,6 +980,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev,
if (err) { if (err) {
dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s " dev_err(&priv->udev->dev, "(p54usb) cannot load firmware %s "
"(%d)!\n", p54u_fwlist[i].fw, err); "(%d)!\n", p54u_fwlist[i].fw, err);
usb_put_dev(udev);
} }
return err; return err;
......
...@@ -2057,7 +2057,7 @@ struct rtl_priv { ...@@ -2057,7 +2057,7 @@ struct rtl_priv {
that it points to the data allocated that it points to the data allocated
beyond this structure like: beyond this structure like:
rtl_pci_priv or rtl_usb_priv */ rtl_pci_priv or rtl_usb_priv */
u8 priv[0]; u8 priv[0] __aligned(sizeof(void *));
}; };
#define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv)) #define rtl_priv(hw) (((struct rtl_priv *)(hw)->priv))
......
...@@ -242,6 +242,7 @@ extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, ...@@ -242,6 +242,7 @@ extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
struct bcma_device *core, bool enable); struct bcma_device *core, bool enable);
extern void bcma_core_pci_up(struct bcma_bus *bus); extern void bcma_core_pci_up(struct bcma_bus *bus);
extern void bcma_core_pci_down(struct bcma_bus *bus); extern void bcma_core_pci_down(struct bcma_bus *bus);
extern void bcma_core_pci_power_save(struct bcma_bus *bus, bool up);
extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev); extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev); extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
......
...@@ -104,6 +104,7 @@ enum { ...@@ -104,6 +104,7 @@ enum {
enum { enum {
HCI_SETUP, HCI_SETUP,
HCI_AUTO_OFF, HCI_AUTO_OFF,
HCI_RFKILLED,
HCI_MGMT, HCI_MGMT,
HCI_PAIRABLE, HCI_PAIRABLE,
HCI_SERVICE_CACHE, HCI_SERVICE_CACHE,
......
...@@ -1146,7 +1146,11 @@ int hci_dev_open(__u16 dev) ...@@ -1146,7 +1146,11 @@ int hci_dev_open(__u16 dev)
goto done; goto done;
} }
if (hdev->rfkill && rfkill_blocked(hdev->rfkill)) { /* Check for rfkill but allow the HCI setup stage to proceed
* (which in itself doesn't cause any RF activity).
*/
if (test_bit(HCI_RFKILLED, &hdev->dev_flags) &&
!test_bit(HCI_SETUP, &hdev->dev_flags)) {
ret = -ERFKILL; ret = -ERFKILL;
goto done; goto done;
} }
...@@ -1566,10 +1570,13 @@ static int hci_rfkill_set_block(void *data, bool blocked) ...@@ -1566,10 +1570,13 @@ static int hci_rfkill_set_block(void *data, bool blocked)
BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked); BT_DBG("%p name %s blocked %d", hdev, hdev->name, blocked);
if (!blocked) if (blocked) {
return 0; set_bit(HCI_RFKILLED, &hdev->dev_flags);
if (!test_bit(HCI_SETUP, &hdev->dev_flags))
hci_dev_do_close(hdev); hci_dev_do_close(hdev);
} else {
clear_bit(HCI_RFKILLED, &hdev->dev_flags);
}
return 0; return 0;
} }
...@@ -1591,9 +1598,13 @@ static void hci_power_on(struct work_struct *work) ...@@ -1591,9 +1598,13 @@ static void hci_power_on(struct work_struct *work)
return; return;
} }
if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) if (test_bit(HCI_RFKILLED, &hdev->dev_flags)) {
clear_bit(HCI_AUTO_OFF, &hdev->dev_flags);
hci_dev_do_close(hdev);
} else if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) {
queue_delayed_work(hdev->req_workqueue, &hdev->power_off, queue_delayed_work(hdev->req_workqueue, &hdev->power_off,
HCI_AUTO_OFF_TIMEOUT); HCI_AUTO_OFF_TIMEOUT);
}
if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags))
mgmt_index_added(hdev); mgmt_index_added(hdev);
...@@ -2209,6 +2220,9 @@ int hci_register_dev(struct hci_dev *hdev) ...@@ -2209,6 +2220,9 @@ int hci_register_dev(struct hci_dev *hdev)
} }
} }
if (hdev->rfkill && rfkill_blocked(hdev->rfkill))
set_bit(HCI_RFKILLED, &hdev->dev_flags);
set_bit(HCI_SETUP, &hdev->dev_flags); set_bit(HCI_SETUP, &hdev->dev_flags);
if (hdev->dev_type != HCI_AMP) if (hdev->dev_type != HCI_AMP)
......
...@@ -3557,7 +3557,11 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -3557,7 +3557,11 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
cp.handle = cpu_to_le16(conn->handle); cp.handle = cpu_to_le16(conn->handle);
if (ltk->authenticated) if (ltk->authenticated)
conn->sec_level = BT_SECURITY_HIGH; conn->pending_sec_level = BT_SECURITY_HIGH;
else
conn->pending_sec_level = BT_SECURITY_MEDIUM;
conn->enc_key_size = ltk->enc_size;
hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp); hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
......
...@@ -3755,6 +3755,13 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, ...@@ -3755,6 +3755,13 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
sk = chan->sk; sk = chan->sk;
/* For certain devices (ex: HID mouse), support for authentication,
* pairing and bonding is optional. For such devices, inorder to avoid
* the ACL alive for too long after L2CAP disconnection, reset the ACL
* disc_timeout back to HCI_DISCONN_TIMEOUT during L2CAP connect.
*/
conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
bacpy(&bt_sk(sk)->src, conn->src); bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst); bacpy(&bt_sk(sk)->dst, conn->dst);
chan->psm = psm; chan->psm = psm;
......
...@@ -569,7 +569,6 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb) ...@@ -569,7 +569,6 @@ static void rfcomm_dev_data_ready(struct rfcomm_dlc *dlc, struct sk_buff *skb)
static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
{ {
struct rfcomm_dev *dev = dlc->owner; struct rfcomm_dev *dev = dlc->owner;
struct tty_struct *tty;
if (!dev) if (!dev)
return; return;
...@@ -581,38 +580,8 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err) ...@@ -581,38 +580,8 @@ static void rfcomm_dev_state_change(struct rfcomm_dlc *dlc, int err)
DPM_ORDER_DEV_AFTER_PARENT); DPM_ORDER_DEV_AFTER_PARENT);
wake_up_interruptible(&dev->port.open_wait); wake_up_interruptible(&dev->port.open_wait);
} else if (dlc->state == BT_CLOSED) { } else if (dlc->state == BT_CLOSED)
tty = tty_port_tty_get(&dev->port); tty_port_tty_hangup(&dev->port, false);
if (!tty) {
if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) {
/* Drop DLC lock here to avoid deadlock
* 1. rfcomm_dev_get will take rfcomm_dev_lock
* but in rfcomm_dev_add there's lock order:
* rfcomm_dev_lock -> dlc lock
* 2. tty_port_put will deadlock if it's
* the last reference
*
* FIXME: when we release the lock anything
* could happen to dev, even its destruction
*/
rfcomm_dlc_unlock(dlc);
if (rfcomm_dev_get(dev->id) == NULL) {
rfcomm_dlc_lock(dlc);
return;
}
if (!test_and_set_bit(RFCOMM_TTY_RELEASED,
&dev->flags))
tty_port_put(&dev->port);
tty_port_put(&dev->port);
rfcomm_dlc_lock(dlc);
}
} else {
tty_hangup(tty);
tty_kref_put(tty);
}
}
} }
static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig) static void rfcomm_dev_modem_status(struct rfcomm_dlc *dlc, u8 v24_sig)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment