aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-14 18:00:48 -0400
committerDavid S. Miller <davem@davemloft.net>2012-05-14 18:00:48 -0400
commitc597f6653d5734c11b1e3217c7619a37e96e5a1f (patch)
tree2c24b46bbe265f3284dcec0a001f7af498794964 /drivers/net
parent669d67bf777def468970f2dcba1537edf3b2d329 (diff)
parent341352d13dae752610342923c53ebe461624ee2c (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/at76c50x-usb.c4
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig9
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c97
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c105
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c39
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h22
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c24
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c44
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c153
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rx.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-pcie.c1
-rw-r--r--drivers/net/wireless/libertas/firmware.c1
-rw-r--r--drivers/net/wireless/mwifiex/Kconfig4
-rw-r--r--drivers/net/wireless/mwifiex/fw.h3
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c7
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.c82
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00debug.h1
26 files changed, 471 insertions, 220 deletions
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 5ad74c85a038..3df0146b797e 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1122,12 +1122,12 @@ exit:
1122static void at76_dump_mib_local(struct at76_priv *priv) 1122static void at76_dump_mib_local(struct at76_priv *priv)
1123{ 1123{
1124 int ret; 1124 int ret;
1125 struct mib_local *m = kmalloc(sizeof(struct mib_phy), GFP_KERNEL); 1125 struct mib_local *m = kmalloc(sizeof(*m), GFP_KERNEL);
1126 1126
1127 if (!m) 1127 if (!m)
1128 return; 1128 return;
1129 1129
1130 ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local)); 1130 ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(*m));
1131 if (ret < 0) { 1131 if (ret < 0) {
1132 wiphy_err(priv->hw->wiphy, 1132 wiphy_err(priv->hw->wiphy,
1133 "at76_get_mib (LOCAL) failed: %d\n", ret); 1133 "at76_get_mib (LOCAL) failed: %d\n", ret);
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index c5104533e24e..b480088b3dbe 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -36,6 +36,15 @@ config BRCMFMAC_SDIO
36 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to 36 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
37 use the driver for a SDIO wireless card. 37 use the driver for a SDIO wireless card.
38 38
39config BRCMFMAC_SDIO_OOB
40 bool "Out of band interrupt support for SDIO interface chipset"
41 depends on BRCMFMAC_SDIO
42 ---help---
43 This option enables out-of-band interrupt support for Broadcom
44 SDIO Wifi chipset using fullmac in order to gain better
45 performance and deep sleep wake up capability on certain
46 platforms. Say N if you are unsure.
47
39config BRCMFMAC_USB 48config BRCMFMAC_USB
40 bool "USB bus interface support for FullMAC driver" 49 bool "USB bus interface support for FullMAC driver"
41 depends on USB 50 depends on USB
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index e925290b432b..4add7da24681 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -39,37 +39,113 @@
39 39
40#define SDIOH_API_ACCESS_RETRY_LIMIT 2 40#define SDIOH_API_ACCESS_RETRY_LIMIT 2
41 41
42static void brcmf_sdioh_irqhandler(struct sdio_func *func) 42#ifdef CONFIG_BRCMFMAC_SDIO_OOB
43static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id)
43{ 44{
44 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); 45 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id);
45 46
46 brcmf_dbg(TRACE, "***IRQHandler\n"); 47 brcmf_dbg(INTR, "oob intr triggered\n");
47 48
48 sdio_release_host(func); 49 /*
50 * out-of-band interrupt is level-triggered which won't
51 * be cleared until dpc
52 */
53 if (sdiodev->irq_en) {
54 disable_irq_nosync(irq);
55 sdiodev->irq_en = false;
56 }
49 57
50 brcmf_sdbrcm_isr(sdiodev->bus); 58 brcmf_sdbrcm_isr(sdiodev->bus);
51 59
52 sdio_claim_host(func); 60 return IRQ_HANDLED;
61}
62
63int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
64{
65 int ret = 0;
66 u8 data;
67 unsigned long flags;
68
69 brcmf_dbg(TRACE, "Entering\n");
70
71 brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq);
72 ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler,
73 sdiodev->irq_flags, "brcmf_oob_intr",
74 &sdiodev->func[1]->card->dev);
75 if (ret != 0)
76 return ret;
77 spin_lock_init(&sdiodev->irq_en_lock);
78 spin_lock_irqsave(&sdiodev->irq_en_lock, flags);
79 sdiodev->irq_en = true;
80 spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags);
81
82 ret = enable_irq_wake(sdiodev->irq);
83 if (ret != 0)
84 return ret;
85 sdiodev->irq_wake = true;
86
87 /* must configure SDIO_CCCR_IENx to enable irq */
88 data = brcmf_sdcard_cfg_read(sdiodev, SDIO_FUNC_0,
89 SDIO_CCCR_IENx, &ret);
90 data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
91 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx,
92 data, &ret);
93
94 /* redirect, configure ane enable io for interrupt signal */
95 data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
96 if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH)
97 data |= SDIO_SEPINT_ACT_HI;
98 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT,
99 data, &ret);
100
101 return 0;
102}
103
104int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
105{
106 brcmf_dbg(TRACE, "Entering\n");
107
108 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_BRCM_SEPINT,
109 0, NULL);
110 brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_0, SDIO_CCCR_IENx, 0, NULL);
111
112 if (sdiodev->irq_wake) {
113 disable_irq_wake(sdiodev->irq);
114 sdiodev->irq_wake = false;
115 }
116 free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev);
117 sdiodev->irq_en = false;
118
119 return 0;
120}
121#else /* CONFIG_BRCMFMAC_SDIO_OOB */
122static void brcmf_sdio_irqhandler(struct sdio_func *func)
123{
124 struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev);
125
126 brcmf_dbg(INTR, "ib intr triggered\n");
127
128 brcmf_sdbrcm_isr(sdiodev->bus);
53} 129}
54 130
55/* dummy handler for SDIO function 2 interrupt */ 131/* dummy handler for SDIO function 2 interrupt */
56static void brcmf_sdioh_dummy_irq_handler(struct sdio_func *func) 132static void brcmf_sdio_dummy_irqhandler(struct sdio_func *func)
57{ 133{
58} 134}
59 135
60int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev) 136int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
61{ 137{
62 brcmf_dbg(TRACE, "Entering\n"); 138 brcmf_dbg(TRACE, "Entering\n");
63 139
64 sdio_claim_host(sdiodev->func[1]); 140 sdio_claim_host(sdiodev->func[1]);
65 sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler); 141 sdio_claim_irq(sdiodev->func[1], brcmf_sdio_irqhandler);
66 sdio_claim_irq(sdiodev->func[2], brcmf_sdioh_dummy_irq_handler); 142 sdio_claim_irq(sdiodev->func[2], brcmf_sdio_dummy_irqhandler);
67 sdio_release_host(sdiodev->func[1]); 143 sdio_release_host(sdiodev->func[1]);
68 144
69 return 0; 145 return 0;
70} 146}
71 147
72int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev) 148int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
73{ 149{
74 brcmf_dbg(TRACE, "Entering\n"); 150 brcmf_dbg(TRACE, "Entering\n");
75 151
@@ -80,6 +156,7 @@ int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev)
80 156
81 return 0; 157 return 0;
82} 158}
159#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
83 160
84u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr, 161u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr,
85 int *err) 162 int *err)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 758c115b556e..dd07d33a927c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -27,6 +27,7 @@
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/sched.h> /* request_irq() */ 28#include <linux/sched.h> /* request_irq() */
29#include <linux/module.h> 29#include <linux/module.h>
30#include <linux/platform_device.h>
30#include <net/cfg80211.h> 31#include <net/cfg80211.h>
31 32
32#include <defs.h> 33#include <defs.h>
@@ -55,6 +56,15 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
55}; 56};
56MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); 57MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
57 58
59#ifdef CONFIG_BRCMFMAC_SDIO_OOB
60static struct list_head oobirq_lh;
61struct brcmf_sdio_oobirq {
62 unsigned int irq;
63 unsigned long flags;
64 struct list_head list;
65};
66#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
67
58static bool 68static bool
59brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev) 69brcmf_pm_resume_error(struct brcmf_sdio_dev *sdiodev)
60{ 70{
@@ -107,7 +117,8 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
107 } 117 }
108 sdio_release_host(sdfunc); 118 sdio_release_host(sdfunc);
109 } 119 }
110 } else if (regaddr == SDIO_CCCR_ABORT) { 120 } else if ((regaddr == SDIO_CCCR_ABORT) ||
121 (regaddr == SDIO_CCCR_IENx)) {
111 sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func), 122 sdfunc = kmemdup(sdiodev->func[0], sizeof(struct sdio_func),
112 GFP_KERNEL); 123 GFP_KERNEL);
113 if (!sdfunc) 124 if (!sdfunc)
@@ -467,12 +478,40 @@ void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev)
467 478
468} 479}
469 480
481#ifdef CONFIG_BRCMFMAC_SDIO_OOB
482static int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
483{
484 struct brcmf_sdio_oobirq *oobirq_entry;
485
486 if (list_empty(&oobirq_lh)) {
487 brcmf_dbg(ERROR, "no valid oob irq resource\n");
488 return -ENXIO;
489 }
490
491 oobirq_entry = list_first_entry(&oobirq_lh, struct brcmf_sdio_oobirq,
492 list);
493
494 sdiodev->irq = oobirq_entry->irq;
495 sdiodev->irq_flags = oobirq_entry->flags;
496 list_del(&oobirq_entry->list);
497 kfree(oobirq_entry);
498
499 return 0;
500}
501#else
502static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev)
503{
504 return 0;
505}
506#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
507
470static int brcmf_ops_sdio_probe(struct sdio_func *func, 508static int brcmf_ops_sdio_probe(struct sdio_func *func,
471 const struct sdio_device_id *id) 509 const struct sdio_device_id *id)
472{ 510{
473 int ret = 0; 511 int ret = 0;
474 struct brcmf_sdio_dev *sdiodev; 512 struct brcmf_sdio_dev *sdiodev;
475 struct brcmf_bus *bus_if; 513 struct brcmf_bus *bus_if;
514
476 brcmf_dbg(TRACE, "Enter\n"); 515 brcmf_dbg(TRACE, "Enter\n");
477 brcmf_dbg(TRACE, "func->class=%x\n", func->class); 516 brcmf_dbg(TRACE, "func->class=%x\n", func->class);
478 brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); 517 brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor);
@@ -511,6 +550,10 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func,
511 sdiodev = dev_get_drvdata(&func->card->dev); 550 sdiodev = dev_get_drvdata(&func->card->dev);
512 if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) 551 if ((!sdiodev) || (sdiodev->func[1]->card != func->card))
513 return -ENODEV; 552 return -ENODEV;
553
554 ret = brcmf_sdio_getintrcfg(sdiodev);
555 if (ret)
556 return ret;
514 sdiodev->func[2] = func; 557 sdiodev->func[2] = func;
515 558
516 bus_if = sdiodev->bus_if; 559 bus_if = sdiodev->bus_if;
@@ -603,6 +646,65 @@ static struct sdio_driver brcmf_sdmmc_driver = {
603#endif /* CONFIG_PM_SLEEP */ 646#endif /* CONFIG_PM_SLEEP */
604}; 647};
605 648
649#ifdef CONFIG_BRCMFMAC_SDIO_OOB
650static int brcmf_sdio_pd_probe(struct platform_device *pdev)
651{
652 struct resource *res;
653 struct brcmf_sdio_oobirq *oobirq_entry;
654 int i, ret;
655
656 INIT_LIST_HEAD(&oobirq_lh);
657
658 for (i = 0; ; i++) {
659 res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
660 if (!res)
661 break;
662
663 oobirq_entry = kzalloc(sizeof(struct brcmf_sdio_oobirq),
664 GFP_KERNEL);
665 oobirq_entry->irq = res->start;
666 oobirq_entry->flags = res->flags & IRQF_TRIGGER_MASK;
667 list_add_tail(&oobirq_entry->list, &oobirq_lh);
668 }
669 if (i == 0)
670 return -ENXIO;
671
672 ret = sdio_register_driver(&brcmf_sdmmc_driver);
673
674 if (ret)
675 brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
676
677 return ret;
678}
679
680static struct platform_driver brcmf_sdio_pd = {
681 .probe = brcmf_sdio_pd_probe,
682 .driver = {
683 .name = "brcmf_sdio_pd"
684 }
685};
686
687void brcmf_sdio_exit(void)
688{
689 brcmf_dbg(TRACE, "Enter\n");
690
691 sdio_unregister_driver(&brcmf_sdmmc_driver);
692
693 platform_driver_unregister(&brcmf_sdio_pd);
694}
695
696void brcmf_sdio_init(void)
697{
698 int ret;
699
700 brcmf_dbg(TRACE, "Enter\n");
701
702 ret = platform_driver_register(&brcmf_sdio_pd);
703
704 if (ret)
705 brcmf_dbg(ERROR, "platform_driver_register failed: %d\n", ret);
706}
707#else
606void brcmf_sdio_exit(void) 708void brcmf_sdio_exit(void)
607{ 709{
608 brcmf_dbg(TRACE, "Enter\n"); 710 brcmf_dbg(TRACE, "Enter\n");
@@ -621,3 +723,4 @@ void brcmf_sdio_init(void)
621 if (ret) 723 if (ret)
622 brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret); 724 brcmf_dbg(ERROR, "sdio_register_driver failed: %d\n", ret);
623} 725}
726#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index a80b840051a7..149ee67beb2e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2352,6 +2352,24 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2352 up(&bus->sdsem); 2352 up(&bus->sdsem);
2353} 2353}
2354 2354
2355#ifdef CONFIG_BRCMFMAC_SDIO_OOB
2356static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
2357{
2358 unsigned long flags;
2359
2360 spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
2361 if (!bus->sdiodev->irq_en && !bus->ipend) {
2362 enable_irq(bus->sdiodev->irq);
2363 bus->sdiodev->irq_en = true;
2364 }
2365 spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags);
2366}
2367#else
2368static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
2369{
2370}
2371#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
2372
2355static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) 2373static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2356{ 2374{
2357 u32 intstatus, newstatus = 0; 2375 u32 intstatus, newstatus = 0;
@@ -2509,6 +2527,8 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2509 bus->intstatus = intstatus; 2527 bus->intstatus = intstatus;
2510 2528
2511clkwait: 2529clkwait:
2530 brcmf_sdbrcm_clrintr(bus);
2531
2512 if (data_ok(bus) && bus->ctrl_frame_stat && 2532 if (data_ok(bus) && bus->ctrl_frame_stat &&
2513 (bus->clkstate == CLK_AVAIL)) { 2533 (bus->clkstate == CLK_AVAIL)) {
2514 int ret, i; 2534 int ret, i;
@@ -3508,8 +3528,14 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
3508 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, 3528 brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
3509 SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); 3529 SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err);
3510 3530
3531 if (ret == 0) {
3532 ret = brcmf_sdio_intr_register(bus->sdiodev);
3533 if (ret != 0)
3534 brcmf_dbg(ERROR, "intr register failed:%d\n", ret);
3535 }
3536
3511 /* If we didn't come up, turn off backplane clock */ 3537 /* If we didn't come up, turn off backplane clock */
3512 if (!ret) 3538 if (bus_if->state != BRCMF_BUS_DATA)
3513 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); 3539 brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
3514 3540
3515exit: 3541exit:
@@ -3867,7 +3893,7 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
3867 3893
3868 if (bus) { 3894 if (bus) {
3869 /* De-register interrupt handler */ 3895 /* De-register interrupt handler */
3870 brcmf_sdcard_intr_dereg(bus->sdiodev); 3896 brcmf_sdio_intr_unregister(bus->sdiodev);
3871 3897
3872 if (bus->sdiodev->bus_if->drvr) { 3898 if (bus->sdiodev->bus_if->drvr) {
3873 brcmf_detach(bus->sdiodev->dev); 3899 brcmf_detach(bus->sdiodev->dev);
@@ -3968,15 +3994,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
3968 goto fail; 3994 goto fail;
3969 } 3995 }
3970 3996
3971 /* Register interrupt callback, but mask it (not operational yet). */
3972 brcmf_dbg(INTR, "disable SDIO interrupts (not interested yet)\n");
3973 ret = brcmf_sdcard_intr_reg(bus->sdiodev);
3974 if (ret != 0) {
3975 brcmf_dbg(ERROR, "FAILED: sdcard_intr_reg returned %d\n", ret);
3976 goto fail;
3977 }
3978 brcmf_dbg(INTR, "registered SDIO interrupt function ok\n");
3979
3980 brcmf_dbg(INFO, "completed!!\n"); 3997 brcmf_dbg(INFO, "completed!!\n");
3981 3998
3982 /* if firmware path present try to download and bring up bus */ 3999 /* if firmware path present try to download and bring up bus */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 0281d207d998..7010eaf71f99 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -43,6 +43,13 @@
43/* as of sdiod rev 0, supports 3 functions */ 43/* as of sdiod rev 0, supports 3 functions */
44#define SBSDIO_NUM_FUNCTION 3 44#define SBSDIO_NUM_FUNCTION 3
45 45
46/* function 0 vendor specific CCCR registers */
47#define SDIO_CCCR_BRCM_SEPINT 0xf2
48
49#define SDIO_SEPINT_MASK 0x01
50#define SDIO_SEPINT_OE 0x02
51#define SDIO_SEPINT_ACT_HI 0x04
52
46/* function 1 miscellaneous registers */ 53/* function 1 miscellaneous registers */
47 54
48/* sprom command and status */ 55/* sprom command and status */
@@ -144,13 +151,18 @@ struct brcmf_sdio_dev {
144 wait_queue_head_t request_buffer_wait; 151 wait_queue_head_t request_buffer_wait;
145 struct device *dev; 152 struct device *dev;
146 struct brcmf_bus *bus_if; 153 struct brcmf_bus *bus_if;
154#ifdef CONFIG_BRCMFMAC_SDIO_OOB
155 unsigned int irq; /* oob interrupt number */
156 unsigned long irq_flags; /* board specific oob flags */
157 bool irq_en; /* irq enable flags */
158 spinlock_t irq_en_lock;
159 bool irq_wake; /* irq wake enable flags */
160#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
147}; 161};
148 162
149/* Register/deregister device interrupt handler. */ 163/* Register/deregister interrupt handler. */
150extern int 164extern int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev);
151brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev); 165extern int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev);
152
153extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev);
154 166
155/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). 167/* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface).
156 * fn: function number 168 * fn: function number
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index c72136c07774..9cfae0c08707 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1963,10 +1963,8 @@ static int ipw2100_wdev_init(struct net_device *dev)
1963 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites); 1963 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);
1964 1964
1965 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev); 1965 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);
1966 if (wiphy_register(wdev->wiphy)) { 1966 if (wiphy_register(wdev->wiphy))
1967 ipw2100_down(priv);
1968 return -EIO; 1967 return -EIO;
1969 }
1970 return 0; 1968 return 0;
1971} 1969}
1972 1970
@@ -6331,6 +6329,11 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6331 printk(KERN_INFO DRV_NAME 6329 printk(KERN_INFO DRV_NAME
6332 ": Detected Intel PRO/Wireless 2100 Network Connection\n"); 6330 ": Detected Intel PRO/Wireless 2100 Network Connection\n");
6333 6331
6332 err = ipw2100_wdev_init(dev);
6333 if (err)
6334 goto fail;
6335 registered = 1;
6336
6334 /* Bring up the interface. Pre 0.46, after we registered the 6337 /* Bring up the interface. Pre 0.46, after we registered the
6335 * network device we would call ipw2100_up. This introduced a race 6338 * network device we would call ipw2100_up. This introduced a race
6336 * condition with newer hotplug configurations (network was coming 6339 * condition with newer hotplug configurations (network was coming
@@ -6347,11 +6350,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6347 "Error calling register_netdev.\n"); 6350 "Error calling register_netdev.\n");
6348 goto fail; 6351 goto fail;
6349 } 6352 }
6350 registered = 1; 6353 registered = 2;
6351
6352 err = ipw2100_wdev_init(dev);
6353 if (err)
6354 goto fail;
6355 6354
6356 mutex_lock(&priv->action_mutex); 6355 mutex_lock(&priv->action_mutex);
6357 6356
@@ -6390,13 +6389,16 @@ out:
6390 6389
6391 fail_unlock: 6390 fail_unlock:
6392 mutex_unlock(&priv->action_mutex); 6391 mutex_unlock(&priv->action_mutex);
6393 wiphy_unregister(priv->ieee->wdev.wiphy);
6394 kfree(priv->ieee->bg_band.channels);
6395 fail: 6392 fail:
6396 if (dev) { 6393 if (dev) {
6397 if (registered) 6394 if (registered >= 2)
6398 unregister_netdev(dev); 6395 unregister_netdev(dev);
6399 6396
6397 if (registered) {
6398 wiphy_unregister(priv->ieee->wdev.wiphy);
6399 kfree(priv->ieee->bg_band.channels);
6400 }
6401
6400 ipw2100_hw_stop_adapter(priv); 6402 ipw2100_hw_stop_adapter(priv);
6401 6403
6402 ipw2100_disable_interrupts(priv); 6404 ipw2100_disable_interrupts(priv);
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index b3707dadad15..0036737fe8e3 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11443,20 +11443,6 @@ static void ipw_bg_down(struct work_struct *work)
11443 mutex_unlock(&priv->mutex); 11443 mutex_unlock(&priv->mutex);
11444} 11444}
11445 11445
11446/* Called by register_netdev() */
11447static int ipw_net_init(struct net_device *dev)
11448{
11449 int rc = 0;
11450 struct ipw_priv *priv = libipw_priv(dev);
11451
11452 mutex_lock(&priv->mutex);
11453 if (ipw_up(priv))
11454 rc = -EIO;
11455 mutex_unlock(&priv->mutex);
11456
11457 return rc;
11458}
11459
11460static int ipw_wdev_init(struct net_device *dev) 11446static int ipw_wdev_init(struct net_device *dev)
11461{ 11447{
11462 int i, rc = 0; 11448 int i, rc = 0;
@@ -11725,7 +11711,6 @@ static void ipw_prom_free(struct ipw_priv *priv)
11725#endif 11711#endif
11726 11712
11727static const struct net_device_ops ipw_netdev_ops = { 11713static const struct net_device_ops ipw_netdev_ops = {
11728 .ndo_init = ipw_net_init,
11729 .ndo_open = ipw_net_open, 11714 .ndo_open = ipw_net_open,
11730 .ndo_stop = ipw_net_stop, 11715 .ndo_stop = ipw_net_stop,
11731 .ndo_set_rx_mode = ipw_net_set_multicast_list, 11716 .ndo_set_rx_mode = ipw_net_set_multicast_list,
@@ -11848,17 +11833,24 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11848 goto out_release_irq; 11833 goto out_release_irq;
11849 } 11834 }
11850 11835
11851 mutex_unlock(&priv->mutex); 11836 if (ipw_up(priv)) {
11852 err = register_netdev(net_dev); 11837 mutex_unlock(&priv->mutex);
11853 if (err) { 11838 err = -EIO;
11854 IPW_ERROR("failed to register network device\n");
11855 goto out_remove_sysfs; 11839 goto out_remove_sysfs;
11856 } 11840 }
11857 11841
11842 mutex_unlock(&priv->mutex);
11843
11858 err = ipw_wdev_init(net_dev); 11844 err = ipw_wdev_init(net_dev);
11859 if (err) { 11845 if (err) {
11860 IPW_ERROR("failed to register wireless device\n"); 11846 IPW_ERROR("failed to register wireless device\n");
11861 goto out_unregister_netdev; 11847 goto out_remove_sysfs;
11848 }
11849
11850 err = register_netdev(net_dev);
11851 if (err) {
11852 IPW_ERROR("failed to register network device\n");
11853 goto out_unregister_wiphy;
11862 } 11854 }
11863 11855
11864#ifdef CONFIG_IPW2200_PROMISCUOUS 11856#ifdef CONFIG_IPW2200_PROMISCUOUS
@@ -11867,10 +11859,8 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11867 if (err) { 11859 if (err) {
11868 IPW_ERROR("Failed to register promiscuous network " 11860 IPW_ERROR("Failed to register promiscuous network "
11869 "device (error %d).\n", err); 11861 "device (error %d).\n", err);
11870 wiphy_unregister(priv->ieee->wdev.wiphy); 11862 unregister_netdev(priv->net_dev);
11871 kfree(priv->ieee->a_band.channels); 11863 goto out_unregister_wiphy;
11872 kfree(priv->ieee->bg_band.channels);
11873 goto out_unregister_netdev;
11874 } 11864 }
11875 } 11865 }
11876#endif 11866#endif
@@ -11882,8 +11872,10 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11882 11872
11883 return 0; 11873 return 0;
11884 11874
11885 out_unregister_netdev: 11875 out_unregister_wiphy:
11886 unregister_netdev(priv->net_dev); 11876 wiphy_unregister(priv->ieee->wdev.wiphy);
11877 kfree(priv->ieee->a_band.channels);
11878 kfree(priv->ieee->bg_band.channels);
11887 out_remove_sysfs: 11879 out_remove_sysfs:
11888 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group); 11880 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
11889 out_release_irq: 11881 out_release_irq:
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index e1c2bb802050..01dc44267317 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -186,76 +186,8 @@ done:
186/* 186/*
187 * BT coex 187 * BT coex
188 */ 188 */
189/* 189/* Notmal TDM */
190 * Macros to access the lookup table. 190static const __le32 iwlagn_def_3w_lookup[IWLAGN_BT_DECISION_LUT_SIZE] = {
191 *
192 * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
193* wifi_prio, wifi_txrx and wifi_sh_ant_req.
194 *
195 * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
196 *
197 * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
198 * one after another in 32-bit registers, and "registers" 0 through 7 contain
199 * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
200 *
201 * These macros encode that format.
202 */
203#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
204 wifi_txrx, wifi_sh_ant_req) \
205 (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
206 (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
207
208#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
209 lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
210#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
211 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
212 (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
213 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
214 wifi_sh_ant_req))))
215#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
216 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
217 LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
218 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
219 wifi_sh_ant_req))
220#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
221 wifi_req, wifi_prio, wifi_txrx, \
222 wifi_sh_ant_req) \
223 LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
224 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
225 wifi_sh_ant_req))
226
227#define LUT_WLAN_KILL_OP(lut, op, val) \
228 lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
229#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
230 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
231 (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
232 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
233#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
234 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
235 LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
236 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
237#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
238 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
239 LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
240 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
241
242#define LUT_ANT_SWITCH_OP(lut, op, val) \
243 lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
244#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
245 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
246 (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
247 wifi_req, wifi_prio, wifi_txrx, \
248 wifi_sh_ant_req))))
249#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
250 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
251 LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
252 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
253#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
254 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
255 LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
256 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
257
258static const __le32 iwlagn_def_3w_lookup[12] = {
259 cpu_to_le32(0xaaaaaaaa), 191 cpu_to_le32(0xaaaaaaaa),
260 cpu_to_le32(0xaaaaaaaa), 192 cpu_to_le32(0xaaaaaaaa),
261 cpu_to_le32(0xaeaaaaaa), 193 cpu_to_le32(0xaeaaaaaa),
@@ -270,7 +202,25 @@ static const __le32 iwlagn_def_3w_lookup[12] = {
270 cpu_to_le32(0xf0005000), 202 cpu_to_le32(0xf0005000),
271}; 203};
272 204
273static const __le32 iwlagn_concurrent_lookup[12] = { 205
206/* Loose Coex */
207static const __le32 iwlagn_loose_lookup[IWLAGN_BT_DECISION_LUT_SIZE] = {
208 cpu_to_le32(0xaaaaaaaa),
209 cpu_to_le32(0xaaaaaaaa),
210 cpu_to_le32(0xaeaaaaaa),
211 cpu_to_le32(0xaaaaaaaa),
212 cpu_to_le32(0xcc00ff28),
213 cpu_to_le32(0x0000aaaa),
214 cpu_to_le32(0xcc00aaaa),
215 cpu_to_le32(0x0000aaaa),
216 cpu_to_le32(0x00000000),
217 cpu_to_le32(0x00000000),
218 cpu_to_le32(0xf0005000),
219 cpu_to_le32(0xf0005000),
220};
221
222/* Full concurrency */
223static const __le32 iwlagn_concurrent_lookup[IWLAGN_BT_DECISION_LUT_SIZE] = {
274 cpu_to_le32(0xaaaaaaaa), 224 cpu_to_le32(0xaaaaaaaa),
275 cpu_to_le32(0xaaaaaaaa), 225 cpu_to_le32(0xaaaaaaaa),
276 cpu_to_le32(0xaaaaaaaa), 226 cpu_to_le32(0xaaaaaaaa),
@@ -325,6 +275,7 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
325 275
326 basic.kill_ack_mask = priv->kill_ack_mask; 276 basic.kill_ack_mask = priv->kill_ack_mask;
327 basic.kill_cts_mask = priv->kill_cts_mask; 277 basic.kill_cts_mask = priv->kill_cts_mask;
278 basic.reduce_txpower = priv->reduced_txpower;
328 basic.valid = priv->bt_valid; 279 basic.valid = priv->bt_valid;
329 280
330 /* 281 /*
@@ -610,29 +561,62 @@ static void iwlagn_print_uartmsg(struct iwl_priv *priv,
610 BT_UART_MSG_FRAME7CONNECTABLE_POS); 561 BT_UART_MSG_FRAME7CONNECTABLE_POS);
611} 562}
612 563
613static void iwlagn_set_kill_msk(struct iwl_priv *priv, 564static bool iwlagn_set_kill_msk(struct iwl_priv *priv,
614 struct iwl_bt_uart_msg *uart_msg) 565 struct iwl_bt_uart_msg *uart_msg)
615{ 566{
616 u8 kill_msk; 567 bool need_update = false;
617 static const __le32 bt_kill_ack_msg[2] = { 568 u8 kill_msk = IWL_BT_KILL_REDUCE;
569 static const __le32 bt_kill_ack_msg[3] = {
618 IWLAGN_BT_KILL_ACK_MASK_DEFAULT, 570 IWLAGN_BT_KILL_ACK_MASK_DEFAULT,
619 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO }; 571 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO,
620 static const __le32 bt_kill_cts_msg[2] = { 572 IWLAGN_BT_KILL_ACK_CTS_MASK_REDUCE};
573 static const __le32 bt_kill_cts_msg[3] = {
621 IWLAGN_BT_KILL_CTS_MASK_DEFAULT, 574 IWLAGN_BT_KILL_CTS_MASK_DEFAULT,
622 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO }; 575 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO,
576 IWLAGN_BT_KILL_ACK_CTS_MASK_REDUCE};
623 577
624 kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) 578 if (!priv->reduced_txpower)
625 ? 1 : 0; 579 kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3)
580 ? IWL_BT_KILL_OVERRIDE : IWL_BT_KILL_DEFAULT;
626 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] || 581 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] ||
627 priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) { 582 priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) {
628 priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK; 583 priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
629 priv->kill_ack_mask = bt_kill_ack_msg[kill_msk]; 584 priv->kill_ack_mask = bt_kill_ack_msg[kill_msk];
630 priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK; 585 priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK;
631 priv->kill_cts_mask = bt_kill_cts_msg[kill_msk]; 586 priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
587 need_update = true;
588 }
589 return need_update;
590}
632 591
633 /* schedule to send runtime bt_config */ 592static bool iwlagn_fill_txpower_mode(struct iwl_priv *priv,
634 queue_work(priv->workqueue, &priv->bt_runtime_config); 593 struct iwl_bt_uart_msg *uart_msg)
594{
595 bool need_update = false;
596
597 if (!priv->reduced_txpower &&
598 !iwl_is_associated(priv, IWL_RXON_CTX_PAN) &&
599 (uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
600 BT_UART_MSG_FRAME3OBEX_MSK)) &&
601 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
602 BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK))) {
603 /* enabling reduced tx power */
604 priv->reduced_txpower = true;
605 priv->bt_valid |= IWLAGN_BT_VALID_REDUCED_TX_PWR;
606 need_update = true;
607 } else if (priv->reduced_txpower &&
608 (iwl_is_associated(priv, IWL_RXON_CTX_PAN) ||
609 (uart_msg->frame3 & (BT_UART_MSG_FRAME3SCOESCO_MSK |
610 BT_UART_MSG_FRAME3SNIFF_MSK | BT_UART_MSG_FRAME3A2DP_MSK)) ||
611 !(uart_msg->frame3 & (BT_UART_MSG_FRAME3ACL_MSK |
612 BT_UART_MSG_FRAME3OBEX_MSK)))) {
613 /* disable reduced tx power */
614 priv->reduced_txpower = false;
615 priv->bt_valid &= ~IWLAGN_BT_VALID_REDUCED_TX_PWR;
616 need_update = true;
635 } 617 }
618
619 return need_update;
636} 620}
637 621
638int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv, 622int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
@@ -680,7 +664,12 @@ int iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
680 } 664 }
681 } 665 }
682 666
683 iwlagn_set_kill_msk(priv, uart_msg); 667 /* schedule to send runtime bt_config */
668 /* check reduce power before change ack/cts kill mask */
669 if (iwlagn_fill_txpower_mode(priv, uart_msg) ||
670 iwlagn_set_kill_msk(priv, uart_msg))
671 queue_work(priv->workqueue, &priv->bt_runtime_config);
672
684 673
685 /* FIXME: based on notification, adjust the prio_boost */ 674 /* FIXME: based on notification, adjust the prio_boost */
686 675
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
index 779f819cc8cb..18a383798e5d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c
@@ -764,7 +764,8 @@ static void iwlagn_pass_packet_to_mac80211(struct iwl_priv *priv,
764 fraglen = len - hdrlen; 764 fraglen = len - hdrlen;
765 765
766 if (fraglen) { 766 if (fraglen) {
767 int offset = (void *)hdr - rxb_addr(rxb) + rxb_offset(rxb); 767 int offset = (void *)hdr + hdrlen -
768 rxb_addr(rxb) + rxb_offset(rxb);
768 769
769 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, 770 skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset,
770 fraglen, rxb->truesize); 771 fraglen, rxb->truesize);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8bd9610a5d68..8d7637083fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1307,6 +1307,9 @@ static int iwl_init_geos(struct iwl_priv *priv)
1307 priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; 1307 priv->hw_params.sku &= ~EEPROM_SKU_CAP_BAND_52GHZ;
1308 } 1308 }
1309 1309
1310 if (iwlwifi_mod_params.disable_5ghz)
1311 priv->bands[IEEE80211_BAND_5GHZ].n_channels = 0;
1312
1310 IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n", 1313 IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
1311 priv->bands[IEEE80211_BAND_2GHZ].n_channels, 1314 priv->bands[IEEE80211_BAND_2GHZ].n_channels,
1312 priv->bands[IEEE80211_BAND_5GHZ].n_channels); 1315 priv->bands[IEEE80211_BAND_5GHZ].n_channels);
@@ -1417,38 +1420,37 @@ void iwl_set_hw_params(struct iwl_priv *priv)
1417 1420
1418 1421
1419 1422
1420void iwl_debug_config(struct iwl_priv *priv) 1423/* show what optional capabilities we have */
1424void iwl_option_config(struct iwl_priv *priv)
1421{ 1425{
1422 dev_printk(KERN_INFO, priv->trans->dev, "CONFIG_IWLWIFI_DEBUG "
1423#ifdef CONFIG_IWLWIFI_DEBUG 1426#ifdef CONFIG_IWLWIFI_DEBUG
1424 "enabled\n"); 1427 IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG enabled\n");
1425#else 1428#else
1426 "disabled\n"); 1429 IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUG disabled\n");
1427#endif 1430#endif
1428 dev_printk(KERN_INFO, priv->trans->dev, "CONFIG_IWLWIFI_DEBUGFS " 1431
1429#ifdef CONFIG_IWLWIFI_DEBUGFS 1432#ifdef CONFIG_IWLWIFI_DEBUGFS
1430 "enabled\n"); 1433 IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS enabled\n");
1431#else 1434#else
1432 "disabled\n"); 1435 IWL_INFO(priv, "CONFIG_IWLWIFI_DEBUGFS disabled\n");
1433#endif 1436#endif
1434 dev_printk(KERN_INFO, priv->trans->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " 1437
1435#ifdef CONFIG_IWLWIFI_DEVICE_TRACING 1438#ifdef CONFIG_IWLWIFI_DEVICE_TRACING
1436 "enabled\n"); 1439 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING enabled\n");
1437#else 1440#else
1438 "disabled\n"); 1441 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1439#endif 1442#endif
1440 1443
1441 dev_printk(KERN_INFO, priv->trans->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE "
1442#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 1444#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1443 "enabled\n"); 1445 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
1444#else 1446#else
1445 "disabled\n"); 1447 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
1446#endif 1448#endif
1447 dev_printk(KERN_INFO, priv->trans->dev, "CONFIG_IWLWIFI_P2P " 1449
1448#ifdef CONFIG_IWLWIFI_P2P 1450#ifdef CONFIG_IWLWIFI_P2P
1449 "enabled\n"); 1451 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1450#else 1452#else
1451 "disabled\n"); 1453 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P disabled\n");
1452#endif 1454#endif
1453} 1455}
1454 1456
@@ -1567,8 +1569,7 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1567 1569
1568 SET_IEEE80211_DEV(priv->hw, priv->trans->dev); 1570 SET_IEEE80211_DEV(priv->hw, priv->trans->dev);
1569 1571
1570 /* show what debugging capabilities we have */ 1572 iwl_option_config(priv);
1571 iwl_debug_config(priv);
1572 1573
1573 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); 1574 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
1574 1575
@@ -1586,7 +1587,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1586 /* these spin locks will be used in apm_ops.init and EEPROM access 1587 /* these spin locks will be used in apm_ops.init and EEPROM access
1587 * we should init now 1588 * we should init now
1588 */ 1589 */
1589 spin_lock_init(&priv->trans->reg_lock);
1590 spin_lock_init(&priv->statistics.lock); 1590 spin_lock_init(&priv->statistics.lock);
1591 1591
1592 /*********************** 1592 /***********************
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 34900e6523dd..79c0fe06f4db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -523,7 +523,7 @@ static inline const char *iwl_dvm_get_cmd_string(u8 cmd)
523void iwl_setup_deferred_work(struct iwl_priv *priv); 523void iwl_setup_deferred_work(struct iwl_priv *priv);
524int iwl_send_wimax_coex(struct iwl_priv *priv); 524int iwl_send_wimax_coex(struct iwl_priv *priv);
525int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); 525int iwl_send_bt_env(struct iwl_priv *priv, u8 action, u8 type);
526void iwl_debug_config(struct iwl_priv *priv); 526void iwl_option_config(struct iwl_priv *priv);
527void iwl_set_hw_params(struct iwl_priv *priv); 527void iwl_set_hw_params(struct iwl_priv *priv);
528void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); 528void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags);
529int iwl_init_drv(struct iwl_priv *priv); 529int iwl_init_drv(struct iwl_priv *priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 296347a8290f..83a6930f3658 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -1877,9 +1877,16 @@ struct iwl_bt_cmd {
1877 1877
1878#define IWLAGN_BT3_T7_DEFAULT 1 1878#define IWLAGN_BT3_T7_DEFAULT 1
1879 1879
1880enum iwl_bt_kill_idx {
1881 IWL_BT_KILL_DEFAULT = 0,
1882 IWL_BT_KILL_OVERRIDE = 1,
1883 IWL_BT_KILL_REDUCE = 2,
1884};
1885
1880#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000) 1886#define IWLAGN_BT_KILL_ACK_MASK_DEFAULT cpu_to_le32(0xffff0000)
1881#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000) 1887#define IWLAGN_BT_KILL_CTS_MASK_DEFAULT cpu_to_le32(0xffff0000)
1882#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff) 1888#define IWLAGN_BT_KILL_ACK_CTS_MASK_SCO cpu_to_le32(0xffffffff)
1889#define IWLAGN_BT_KILL_ACK_CTS_MASK_REDUCE cpu_to_le32(0)
1883 1890
1884#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2 1891#define IWLAGN_BT3_PRIO_SAMPLE_DEFAULT 2
1885 1892
@@ -1891,7 +1898,7 @@ struct iwl_bt_cmd {
1891#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3)) 1898#define IWLAGN_BT_VALID_3W_TIMERS cpu_to_le16(BIT(3))
1892#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4)) 1899#define IWLAGN_BT_VALID_KILL_ACK_MASK cpu_to_le16(BIT(4))
1893#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5)) 1900#define IWLAGN_BT_VALID_KILL_CTS_MASK cpu_to_le16(BIT(5))
1894#define IWLAGN_BT_VALID_BT4_TIMES cpu_to_le16(BIT(6)) 1901#define IWLAGN_BT_VALID_REDUCED_TX_PWR cpu_to_le16(BIT(6))
1895#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7)) 1902#define IWLAGN_BT_VALID_3W_LUT cpu_to_le16(BIT(7))
1896 1903
1897#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \ 1904#define IWLAGN_BT_ALL_VALID_MSK (IWLAGN_BT_VALID_ENABLE_FLAGS | \
@@ -1900,9 +1907,11 @@ struct iwl_bt_cmd {
1900 IWLAGN_BT_VALID_3W_TIMERS | \ 1907 IWLAGN_BT_VALID_3W_TIMERS | \
1901 IWLAGN_BT_VALID_KILL_ACK_MASK | \ 1908 IWLAGN_BT_VALID_KILL_ACK_MASK | \
1902 IWLAGN_BT_VALID_KILL_CTS_MASK | \ 1909 IWLAGN_BT_VALID_KILL_CTS_MASK | \
1903 IWLAGN_BT_VALID_BT4_TIMES | \ 1910 IWLAGN_BT_VALID_REDUCED_TX_PWR | \
1904 IWLAGN_BT_VALID_3W_LUT) 1911 IWLAGN_BT_VALID_3W_LUT)
1905 1912
1913#define IWLAGN_BT_DECISION_LUT_SIZE 12
1914
1906struct iwl_basic_bt_cmd { 1915struct iwl_basic_bt_cmd {
1907 u8 flags; 1916 u8 flags;
1908 u8 ledtime; /* unused */ 1917 u8 ledtime; /* unused */
@@ -1913,8 +1922,9 @@ struct iwl_basic_bt_cmd {
1913 u8 bt3_prio_sample_time; 1922 u8 bt3_prio_sample_time;
1914 u8 bt3_timer_t2_value; 1923 u8 bt3_timer_t2_value;
1915 __le16 bt4_reaction_time; /* unused */ 1924 __le16 bt4_reaction_time; /* unused */
1916 __le32 bt3_lookup_table[12]; 1925 __le32 bt3_lookup_table[IWLAGN_BT_DECISION_LUT_SIZE];
1917 __le16 bt4_decision_time; /* unused */ 1926 u8 reduce_txpower;
1927 u8 reserved;
1918 __le16 valid; 1928 __le16 valid;
1919}; 1929};
1920 1930
@@ -3634,6 +3644,9 @@ enum iwl_bt_coex_profile_traffic_load {
3634 (0x3<<BT_UART_MSG_2_FRAME7RESERVED_POS) 3644 (0x3<<BT_UART_MSG_2_FRAME7RESERVED_POS)
3635 3645
3636 3646
3647#define BT_ENABLE_REDUCED_TXPOWER_THRESHOLD (-62)
3648#define BT_DISABLE_REDUCED_TXPOWER_THRESHOLD (-65)
3649
3637struct iwl_bt_uart_msg { 3650struct iwl_bt_uart_msg {
3638 u8 header; 3651 u8 header;
3639 u8 frame1; 3652 u8 frame1;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index f70219c3b122..70062379d0ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -921,6 +921,7 @@ struct iwl_priv {
921 __le32 kill_ack_mask; 921 __le32 kill_ack_mask;
922 __le32 kill_cts_mask; 922 __le32 kill_cts_mask;
923 __le16 bt_valid; 923 __le16 bt_valid;
924 bool reduced_txpower;
924 u16 bt_on_thresh; 925 u16 bt_on_thresh;
925 u16 bt_duration; 926 u16 bt_duration;
926 u16 dynamic_frag_thresh; 927 u16 dynamic_frag_thresh;
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 05302d6f989f..3c72bad0ae56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -66,6 +66,7 @@
66#include <linux/module.h> 66#include <linux/module.h>
67 67
68#include "iwl-drv.h" 68#include "iwl-drv.h"
69#include "iwl-debug.h"
69#include "iwl-trans.h" 70#include "iwl-trans.h"
70#include "iwl-op-mode.h" 71#include "iwl-op-mode.h"
71#include "iwl-agn-hw.h" 72#include "iwl-agn-hw.h"
@@ -892,10 +893,9 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
892 int ret; 893 int ret;
893 894
894 drv = kzalloc(sizeof(*drv), GFP_KERNEL); 895 drv = kzalloc(sizeof(*drv), GFP_KERNEL);
895 if (!drv) { 896 if (!drv)
896 dev_printk(KERN_ERR, trans->dev, "Couldn't allocate iwl_drv");
897 return NULL; 897 return NULL;
898 } 898
899 drv->trans = trans; 899 drv->trans = trans;
900 drv->dev = trans->dev; 900 drv->dev = trans->dev;
901 drv->cfg = cfg; 901 drv->cfg = cfg;
@@ -905,7 +905,7 @@ struct iwl_drv *iwl_drv_start(struct iwl_trans *trans,
905 ret = iwl_request_firmware(drv, true); 905 ret = iwl_request_firmware(drv, true);
906 906
907 if (ret) { 907 if (ret) {
908 dev_printk(KERN_ERR, trans->dev, "Couldn't request the fw"); 908 IWL_ERR(trans, "Couldn't request the fw\n");
909 kfree(drv); 909 kfree(drv);
910 drv = NULL; 910 drv = NULL;
911 } 911 }
@@ -1012,3 +1012,7 @@ module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
1012 bool, S_IRUGO); 1012 bool, S_IRUGO);
1013MODULE_PARM_DESC(auto_agg, 1013MODULE_PARM_DESC(auto_agg,
1014 "enable agg w/o check traffic load (default: enable)"); 1014 "enable agg w/o check traffic load (default: enable)");
1015
1016module_param_named(5ghz_disable, iwlwifi_mod_params.disable_5ghz,
1017 bool, S_IRUGO);
1018MODULE_PARM_DESC(5ghz_disable, "disable 5GHz band (default: 0 [enabled])");
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index 558b2e63c5cf..d9a86d6b2bd7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -60,8 +60,8 @@
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 * 61 *
62 *****************************************************************************/ 62 *****************************************************************************/
63#ifndef __iwl_shared_h__ 63#ifndef __iwl_modparams_h__
64#define __iwl_shared_h__ 64#define __iwl_modparams_h__
65 65
66#include <linux/types.h> 66#include <linux/types.h>
67#include <linux/spinlock.h> 67#include <linux/spinlock.h>
@@ -103,6 +103,7 @@ enum iwl_power_level {
103 * @ant_coupling: antenna coupling in dB, default = 0 103 * @ant_coupling: antenna coupling in dB, default = 0
104 * @bt_ch_announce: BT channel inhibition, default = enable 104 * @bt_ch_announce: BT channel inhibition, default = enable
105 * @auto_agg: enable agg. without check, default = true 105 * @auto_agg: enable agg. without check, default = true
106 * @disable_5ghz: disable 5GHz capability, default = false
106 */ 107 */
107struct iwl_mod_params { 108struct iwl_mod_params {
108 int sw_crypto; 109 int sw_crypto;
@@ -119,6 +120,7 @@ struct iwl_mod_params {
119 int ant_coupling; 120 int ant_coupling;
120 bool bt_ch_announce; 121 bool bt_ch_announce;
121 bool auto_agg; 122 bool auto_agg;
123 bool disable_5ghz;
122}; 124};
123 125
124#endif /* #__iwl_shared_h__ */ 126#endif /* #__iwl_modparams_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 63557bb85cda..2e57161854b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -2175,6 +2175,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2175 2175
2176 /* Initialize the wait queue for commands */ 2176 /* Initialize the wait queue for commands */
2177 init_waitqueue_head(&trans->wait_command_queue); 2177 init_waitqueue_head(&trans->wait_command_queue);
2178 spin_lock_init(&trans->reg_lock);
2178 2179
2179 return trans; 2180 return trans;
2180 2181
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c
index 77f6504fd55d..601f2075355e 100644
--- a/drivers/net/wireless/libertas/firmware.c
+++ b/drivers/net/wireless/libertas/firmware.c
@@ -2,6 +2,7 @@
2 * Firmware loading and handling functions. 2 * Firmware loading and handling functions.
3 */ 3 */
4 4
5#include <linux/sched.h>
5#include <linux/firmware.h> 6#include <linux/firmware.h>
6#include <linux/firmware.h> 7#include <linux/firmware.h>
7#include <linux/module.h> 8#include <linux/module.h>
diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig
index 7f91cc694787..8e384fae3e68 100644
--- a/drivers/net/wireless/mwifiex/Kconfig
+++ b/drivers/net/wireless/mwifiex/Kconfig
@@ -10,12 +10,12 @@ config MWIFIEX
10 mwifiex. 10 mwifiex.
11 11
12config MWIFIEX_SDIO 12config MWIFIEX_SDIO
13 tristate "Marvell WiFi-Ex Driver for SD8787/SD8797" 13 tristate "Marvell WiFi-Ex Driver for SD8786/SD8787/SD8797"
14 depends on MWIFIEX && MMC 14 depends on MWIFIEX && MMC
15 select FW_LOADER 15 select FW_LOADER
16 ---help--- 16 ---help---
17 This adds support for wireless adapters based on Marvell 17 This adds support for wireless adapters based on Marvell
18 8787/8797 chipsets with SDIO interface. 18 8786/8787/8797 chipsets with SDIO interface.
19 19
20 If you choose to build it as a module, it will be called 20 If you choose to build it as a module, it will be called
21 mwifiex_sdio. 21 mwifiex_sdio.
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 2a2cabadb9b5..5f6adeb9b950 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -993,8 +993,7 @@ struct mwifiex_ie_types_wmm_queue_status {
993struct ieee_types_vendor_header { 993struct ieee_types_vendor_header {
994 u8 element_id; 994 u8 element_id;
995 u8 len; 995 u8 len;
996 u8 oui[3]; 996 u8 oui[4]; /* 0~2: oui, 3: oui_type */
997 u8 oui_type;
998 u8 oui_subtype; 997 u8 oui_subtype;
999 u8 version; 998 u8 version;
1000} __packed; 999} __packed;
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 1aa45c4295bb..e0377473282f 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -253,6 +253,8 @@ static int mwifiex_sdio_resume(struct device *dev)
253 return 0; 253 return 0;
254} 254}
255 255
256/* Device ID for SD8786 */
257#define SDIO_DEVICE_ID_MARVELL_8786 (0x9116)
256/* Device ID for SD8787 */ 258/* Device ID for SD8787 */
257#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) 259#define SDIO_DEVICE_ID_MARVELL_8787 (0x9119)
258/* Device ID for SD8797 */ 260/* Device ID for SD8797 */
@@ -260,6 +262,7 @@ static int mwifiex_sdio_resume(struct device *dev)
260 262
261/* WLAN IDs */ 263/* WLAN IDs */
262static const struct sdio_device_id mwifiex_ids[] = { 264static const struct sdio_device_id mwifiex_ids[] = {
265 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786)},
263 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)}, 266 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787)},
264 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)}, 267 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797)},
265 {}, 268 {},
@@ -1599,6 +1602,9 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1599 adapter->dev = &func->dev; 1602 adapter->dev = &func->dev;
1600 1603
1601 switch (func->device) { 1604 switch (func->device) {
1605 case SDIO_DEVICE_ID_MARVELL_8786:
1606 strcpy(adapter->fw_name, SD8786_DEFAULT_FW_NAME);
1607 break;
1602 case SDIO_DEVICE_ID_MARVELL_8797: 1608 case SDIO_DEVICE_ID_MARVELL_8797:
1603 strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME); 1609 strcpy(adapter->fw_name, SD8797_DEFAULT_FW_NAME);
1604 break; 1610 break;
@@ -1807,5 +1813,6 @@ MODULE_AUTHOR("Marvell International Ltd.");
1807MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); 1813MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);
1808MODULE_VERSION(SDIO_VERSION); 1814MODULE_VERSION(SDIO_VERSION);
1809MODULE_LICENSE("GPL v2"); 1815MODULE_LICENSE("GPL v2");
1816MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);
1810MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); 1817MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);
1811MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); 1818MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index 0ead152e3d1e..21033738ef0c 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -28,6 +28,7 @@
28 28
29#include "main.h" 29#include "main.h"
30 30
31#define SD8786_DEFAULT_FW_NAME "mrvl/sd8786_uapsta.bin"
31#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" 32#define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin"
32#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin" 33#define SD8797_DEFAULT_FW_NAME "mrvl/sd8797_uapsta.bin"
33 34
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index d91f4f628f65..9348521e0832 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -102,6 +102,8 @@
102#define BBP_SIZE 0x00ff 102#define BBP_SIZE 0x00ff
103#define RF_BASE 0x0004 103#define RF_BASE 0x0004
104#define RF_SIZE 0x0010 104#define RF_SIZE 0x0010
105#define RFCSR_BASE 0x0000
106#define RFCSR_SIZE 0x0040
105 107
106/* 108/*
107 * Number of TX queues. 109 * Number of TX queues.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 1cd16b416024..dfc90d34be6d 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -836,6 +836,13 @@ const struct rt2x00debug rt2800_rt2x00debug = {
836 .word_size = sizeof(u32), 836 .word_size = sizeof(u32),
837 .word_count = RF_SIZE / sizeof(u32), 837 .word_count = RF_SIZE / sizeof(u32),
838 }, 838 },
839 .rfcsr = {
840 .read = rt2800_rfcsr_read,
841 .write = rt2800_rfcsr_write,
842 .word_base = RFCSR_BASE,
843 .word_size = sizeof(u8),
844 .word_count = RFCSR_SIZE / sizeof(u8),
845 },
839}; 846};
840EXPORT_SYMBOL_GPL(rt2800_rt2x00debug); 847EXPORT_SYMBOL_GPL(rt2800_rt2x00debug);
841#endif /* CONFIG_RT2X00_LIB_DEBUGFS */ 848#endif /* CONFIG_RT2X00_LIB_DEBUGFS */
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c
index 78787fcc919e..3bb8cafbac59 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.c
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.c
@@ -70,6 +70,7 @@ struct rt2x00debug_intf {
70 * - eeprom offset/value files 70 * - eeprom offset/value files
71 * - bbp offset/value files 71 * - bbp offset/value files
72 * - rf offset/value files 72 * - rf offset/value files
73 * - rfcsr offset/value files
73 * - queue folder 74 * - queue folder
74 * - frame dump file 75 * - frame dump file
75 * - queue stats file 76 * - queue stats file
@@ -89,6 +90,8 @@ struct rt2x00debug_intf {
89 struct dentry *bbp_val_entry; 90 struct dentry *bbp_val_entry;
90 struct dentry *rf_off_entry; 91 struct dentry *rf_off_entry;
91 struct dentry *rf_val_entry; 92 struct dentry *rf_val_entry;
93 struct dentry *rfcsr_off_entry;
94 struct dentry *rfcsr_val_entry;
92 struct dentry *queue_folder; 95 struct dentry *queue_folder;
93 struct dentry *queue_frame_dump_entry; 96 struct dentry *queue_frame_dump_entry;
94 struct dentry *queue_stats_entry; 97 struct dentry *queue_stats_entry;
@@ -131,6 +134,7 @@ struct rt2x00debug_intf {
131 unsigned int offset_eeprom; 134 unsigned int offset_eeprom;
132 unsigned int offset_bbp; 135 unsigned int offset_bbp;
133 unsigned int offset_rf; 136 unsigned int offset_rf;
137 unsigned int offset_rfcsr;
134}; 138};
135 139
136void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, 140void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev,
@@ -525,6 +529,7 @@ RT2X00DEBUGFS_OPS(csr, "0x%.8x\n", u32);
525RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16); 529RT2X00DEBUGFS_OPS(eeprom, "0x%.4x\n", u16);
526RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8); 530RT2X00DEBUGFS_OPS(bbp, "0x%.2x\n", u8);
527RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32); 531RT2X00DEBUGFS_OPS(rf, "0x%.8x\n", u32);
532RT2X00DEBUGFS_OPS(rfcsr, "0x%.2x\n", u8);
528 533
529static ssize_t rt2x00debug_read_dev_flags(struct file *file, 534static ssize_t rt2x00debug_read_dev_flags(struct file *file,
530 char __user *buf, 535 char __user *buf,
@@ -614,7 +619,7 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
614 const struct rt2x00debug *debug = intf->debug; 619 const struct rt2x00debug *debug = intf->debug;
615 char *data; 620 char *data;
616 621
617 data = kzalloc(8 * MAX_LINE_LENGTH, GFP_KERNEL); 622 data = kzalloc(9 * MAX_LINE_LENGTH, GFP_KERNEL);
618 if (!data) 623 if (!data)
619 return NULL; 624 return NULL;
620 625
@@ -624,22 +629,22 @@ static struct dentry *rt2x00debug_create_file_chipset(const char *name,
624 data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev); 629 data += sprintf(data, "revision:\t%04x\n", intf->rt2x00dev->chip.rev);
625 data += sprintf(data, "\n"); 630 data += sprintf(data, "\n");
626 data += sprintf(data, "register\tbase\twords\twordsize\n"); 631 data += sprintf(data, "register\tbase\twords\twordsize\n");
627 data += sprintf(data, "csr\t%d\t%d\t%d\n", 632#define RT2X00DEBUGFS_SPRINTF_REGISTER(__name) \
628 debug->csr.word_base, 633{ \
629 debug->csr.word_count, 634 if(debug->__name.read) \
630 debug->csr.word_size); 635 data += sprintf(data, __stringify(__name) \
631 data += sprintf(data, "eeprom\t%d\t%d\t%d\n", 636 "\t%d\t%d\t%d\n", \
632 debug->eeprom.word_base, 637 debug->__name.word_base, \
633 debug->eeprom.word_count, 638 debug->__name.word_count, \
634 debug->eeprom.word_size); 639 debug->__name.word_size); \
635 data += sprintf(data, "bbp\t%d\t%d\t%d\n", 640}
636 debug->bbp.word_base, 641 RT2X00DEBUGFS_SPRINTF_REGISTER(csr);
637 debug->bbp.word_count, 642 RT2X00DEBUGFS_SPRINTF_REGISTER(eeprom);
638 debug->bbp.word_size); 643 RT2X00DEBUGFS_SPRINTF_REGISTER(bbp);
639 data += sprintf(data, "rf\t%d\t%d\t%d\n", 644 RT2X00DEBUGFS_SPRINTF_REGISTER(rf);
640 debug->rf.word_base, 645 RT2X00DEBUGFS_SPRINTF_REGISTER(rfcsr);
641 debug->rf.word_count, 646#undef RT2X00DEBUGFS_SPRINTF_REGISTER
642 debug->rf.word_size); 647
643 blob->size = strlen(blob->data); 648 blob->size = strlen(blob->data);
644 649
645 return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob); 650 return debugfs_create_blob(name, S_IRUSR, intf->driver_folder, blob);
@@ -694,31 +699,34 @@ void rt2x00debug_register(struct rt2x00_dev *rt2x00dev)
694 if (IS_ERR(intf->register_folder) || !intf->register_folder) 699 if (IS_ERR(intf->register_folder) || !intf->register_folder)
695 goto exit; 700 goto exit;
696 701
697#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ 702#define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \
698({ \ 703({ \
699 (__intf)->__name##_off_entry = \ 704 if(debug->__name.read) { \
700 debugfs_create_u32(__stringify(__name) "_offset", \ 705 (__intf)->__name##_off_entry = \
701 S_IRUSR | S_IWUSR, \ 706 debugfs_create_u32(__stringify(__name) "_offset", \
702 (__intf)->register_folder, \ 707 S_IRUSR | S_IWUSR, \
703 &(__intf)->offset_##__name); \ 708 (__intf)->register_folder, \
704 if (IS_ERR((__intf)->__name##_off_entry) \ 709 &(__intf)->offset_##__name); \
705 || !(__intf)->__name##_off_entry) \ 710 if (IS_ERR((__intf)->__name##_off_entry) \
706 goto exit; \ 711 || !(__intf)->__name##_off_entry) \
707 \ 712 goto exit; \
708 (__intf)->__name##_val_entry = \ 713 \
709 debugfs_create_file(__stringify(__name) "_value", \ 714 (__intf)->__name##_val_entry = \
710 S_IRUSR | S_IWUSR, \ 715 debugfs_create_file(__stringify(__name) "_value", \
711 (__intf)->register_folder, \ 716 S_IRUSR | S_IWUSR, \
712 (__intf), &rt2x00debug_fop_##__name);\ 717 (__intf)->register_folder, \
713 if (IS_ERR((__intf)->__name##_val_entry) \ 718 (__intf), &rt2x00debug_fop_##__name); \
714 || !(__intf)->__name##_val_entry) \ 719 if (IS_ERR((__intf)->__name##_val_entry) \
715 goto exit; \ 720 || !(__intf)->__name##_val_entry) \
721 goto exit; \
722 } \
716}) 723})
717 724
718 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr); 725 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, csr);
719 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom); 726 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, eeprom);
720 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp); 727 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, bbp);
721 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf); 728 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rf);
729 RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(intf, rfcsr);
722 730
723#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY 731#undef RT2X00DEBUGFS_CREATE_REGISTER_ENTRY
724 732
@@ -770,6 +778,8 @@ void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev)
770 debugfs_remove(intf->queue_stats_entry); 778 debugfs_remove(intf->queue_stats_entry);
771 debugfs_remove(intf->queue_frame_dump_entry); 779 debugfs_remove(intf->queue_frame_dump_entry);
772 debugfs_remove(intf->queue_folder); 780 debugfs_remove(intf->queue_folder);
781 debugfs_remove(intf->rfcsr_val_entry);
782 debugfs_remove(intf->rfcsr_off_entry);
773 debugfs_remove(intf->rf_val_entry); 783 debugfs_remove(intf->rf_val_entry);
774 debugfs_remove(intf->rf_off_entry); 784 debugfs_remove(intf->rf_off_entry);
775 debugfs_remove(intf->bbp_val_entry); 785 debugfs_remove(intf->bbp_val_entry);
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.h b/drivers/net/wireless/rt2x00/rt2x00debug.h
index fa11409cb5c6..e11d39bdfef7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00debug.h
+++ b/drivers/net/wireless/rt2x00/rt2x00debug.h
@@ -65,6 +65,7 @@ struct rt2x00debug {
65 RT2X00DEBUGFS_REGISTER_ENTRY(eeprom, u16); 65 RT2X00DEBUGFS_REGISTER_ENTRY(eeprom, u16);
66 RT2X00DEBUGFS_REGISTER_ENTRY(bbp, u8); 66 RT2X00DEBUGFS_REGISTER_ENTRY(bbp, u8);
67 RT2X00DEBUGFS_REGISTER_ENTRY(rf, u32); 67 RT2X00DEBUGFS_REGISTER_ENTRY(rf, u32);
68 RT2X00DEBUGFS_REGISTER_ENTRY(rfcsr, u8);
68}; 69};
69 70
70#endif /* RT2X00DEBUG_H */ 71#endif /* RT2X00DEBUG_H */