aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS3
-rw-r--r--drivers/bcma/bcma_private.h2
-rw-r--r--drivers/bcma/driver_chipcommon.c114
-rw-r--r--drivers/bcma/driver_pci_host.c10
-rw-r--r--drivers/bcma/main.c8
-rw-r--r--drivers/net/wireless/adm8211.c6
-rw-r--r--drivers/net/wireless/airo.c6
-rw-r--r--drivers/net/wireless/ath/Kconfig7
-rw-r--r--drivers/net/wireless/ath/ar5523/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c4
-rw-r--r--drivers/net/wireless/ath/ath5k/led.c2
-rw-r--r--drivers/net/wireless/ath/ath5k/pci.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c209
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c137
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c9
-rw-r--r--drivers/net/wireless/ath/carl9170/Kconfig1
-rw-r--r--drivers/net/wireless/ath/carl9170/rx.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/tx.c7
-rw-r--r--drivers/net/wireless/atmel_pci.c6
-rw-r--r--drivers/net/wireless/b43/pcmcia.c6
-rw-r--r--drivers/net/wireless/b43/sdio.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c141
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.c112
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/debug.h23
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c33
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c61
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c471
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c64
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/pub.h5
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c4
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c12
-rw-r--r--drivers/net/wireless/iwlegacy/3945-mac.c4
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c4
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rxon.c12
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c4
-rw-r--r--drivers/net/wireless/libertas/cfg.c9
-rw-r--r--drivers/net/wireless/libertas/if_spi.c6
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c7
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c15
-rw-r--r--drivers/net/wireless/mwifiex/fw.h2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c36
-rw-r--r--drivers/net/wireless/mwifiex/usb.c2
-rw-r--r--drivers/net/wireless/mwl8k.c14
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c4
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c4
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c4
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c4
-rw-r--r--drivers/net/wireless/p54/eeprom.c5
-rw-r--r--drivers/net/wireless/p54/p54pci.c19
-rw-r--r--drivers/net/wireless/p54/p54spi.c6
-rw-r--r--drivers/net/wireless/p54/p54usb.c6
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c142
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c10
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c6
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c6
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c4
-rw-r--r--drivers/net/wireless/rtlwifi/pci.h4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ce/sw.c9
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/sw.c11
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/def.h3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/dm.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.h2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/sw.c20
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c9
-rw-r--r--drivers/net/wireless/rtlwifi/usb.c2
-rw-r--r--drivers/net/wireless/rtlwifi/usb.h2
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c4
-rw-r--r--drivers/net/wireless/ti/wl1251/sdio.c4
-rw-r--r--drivers/net/wireless/ti/wl1251/spi.c6
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c6
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/cmd.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c4
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c8
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c6
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h4
-rw-r--r--drivers/ssb/driver_chipcommon.c100
-rw-r--r--drivers/ssb/driver_chipcommon_pmu.c27
-rw-r--r--drivers/ssb/driver_extif.c24
-rw-r--r--drivers/ssb/driver_mipscore.c14
-rw-r--r--drivers/ssb/embedded.c35
-rw-r--r--drivers/ssb/main.c8
-rw-r--r--drivers/ssb/ssb_private.h31
-rw-r--r--include/linux/bcm47xx_wdt.h19
-rw-r--r--include/linux/bcma/bcma_driver_chipcommon.h7
-rw-r--r--include/linux/ieee80211.h15
-rw-r--r--include/linux/ssb/ssb.h2
-rw-r--r--include/linux/ssb/ssb_driver_chipcommon.h5
-rw-r--r--include/linux/ssb/ssb_driver_extif.h52
-rw-r--r--include/net/bluetooth/hci_core.h31
-rw-r--r--include/net/bluetooth/l2cap.h2
-rw-r--r--include/net/cfg80211.h69
-rw-r--r--include/net/ieee80211_radiotap.h24
-rw-r--r--include/net/mac80211.h12
-rw-r--r--include/uapi/linux/nl80211.h16
-rw-r--r--net/bluetooth/hci_core.c5
-rw-r--r--net/bluetooth/hci_event.c56
-rw-r--r--net/bluetooth/l2cap_core.c100
-rw-r--r--net/bluetooth/mgmt.c10
-rw-r--r--net/bluetooth/rfcomm/sock.c4
-rw-r--r--net/bluetooth/sco.c86
-rw-r--r--net/mac80211/cfg.c77
-rw-r--r--net/mac80211/debugfs_sta.c36
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/iface.c45
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mesh_plink.c3
-rw-r--r--net/mac80211/mesh_sync.c4
-rw-r--r--net/mac80211/mlme.c431
-rw-r--r--net/mac80211/offchannel.c2
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c8
-rw-r--r--net/mac80211/rx.c42
-rw-r--r--net/mac80211/scan.c21
-rw-r--r--net/mac80211/sta_info.h4
-rw-r--r--net/mac80211/status.c3
-rw-r--r--net/mac80211/tx.c9
-rw-r--r--net/mac80211/util.c58
-rw-r--r--net/nfc/llcp/llcp.c5
-rw-r--r--net/rfkill/rfkill-gpio.c2
-rw-r--r--net/rfkill/rfkill-regulator.c6
-rw-r--r--net/wireless/chan.c92
-rw-r--r--net/wireless/core.h8
-rw-r--r--net/wireless/mesh.c3
-rw-r--r--net/wireless/nl80211.c155
-rw-r--r--net/wireless/reg.c2
-rw-r--r--net/wireless/reg.h2
-rw-r--r--net/wireless/scan.c452
-rw-r--r--net/wireless/sme.c13
-rw-r--r--net/wireless/util.c9
-rw-r--r--net/wireless/wext-sme.c8
147 files changed, 2860 insertions, 1428 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index e443eb76ce5e..14cffbfbd041 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1674,10 +1674,9 @@ F: drivers/net/ethernet/broadcom/tg3.*
1674 1674
1675BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER 1675BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
1676M: Brett Rudley <brudley@broadcom.com> 1676M: Brett Rudley <brudley@broadcom.com>
1677M: Roland Vossen <rvossen@broadcom.com>
1678M: Arend van Spriel <arend@broadcom.com> 1677M: Arend van Spriel <arend@broadcom.com>
1679M: Franky (Zhenhui) Lin <frankyl@broadcom.com> 1678M: Franky (Zhenhui) Lin <frankyl@broadcom.com>
1680M: Kan Yan <kanyan@broadcom.com> 1679M: Hante Meuleman <meuleman@broadcom.com>
1681L: linux-wireless@vger.kernel.org 1680L: linux-wireless@vger.kernel.org
1682L: brcm80211-dev-list@broadcom.com 1681L: brcm80211-dev-list@broadcom.com
1683S: Supported 1682S: Supported
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 169fc58427d3..bcb830ec4bb4 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -84,6 +84,8 @@ extern void __exit bcma_host_pci_exit(void);
84/* driver_pci.c */ 84/* driver_pci.c */
85u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address); 85u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
86 86
87extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
88
87#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE 89#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
88bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc); 90bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
89void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc); 91void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index ffd74e51f02d..d017f2512275 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -4,12 +4,15 @@
4 * 4 *
5 * Copyright 2005, Broadcom Corporation 5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7 * 8 *
8 * Licensed under the GNU/GPL. See COPYING for details. 9 * Licensed under the GNU/GPL. See COPYING for details.
9 */ 10 */
10 11
11#include "bcma_private.h" 12#include "bcma_private.h"
13#include <linux/bcm47xx_wdt.h>
12#include <linux/export.h> 14#include <linux/export.h>
15#include <linux/platform_device.h>
13#include <linux/bcma/bcma.h> 16#include <linux/bcma/bcma.h>
14 17
15static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset, 18static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
@@ -22,6 +25,90 @@ static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
22 return value; 25 return value;
23} 26}
24 27
28static u32 bcma_chipco_alp_clock(struct bcma_drv_cc *cc)
29{
30 if (cc->capabilities & BCMA_CC_CAP_PMU)
31 return bcma_pmu_alp_clock(cc);
32
33 return 20000000;
34}
35
36static u32 bcma_chipco_watchdog_get_max_timer(struct bcma_drv_cc *cc)
37{
38 struct bcma_bus *bus = cc->core->bus;
39 u32 nb;
40
41 if (cc->capabilities & BCMA_CC_CAP_PMU) {
42 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
43 nb = 32;
44 else if (cc->core->id.rev < 26)
45 nb = 16;
46 else
47 nb = (cc->core->id.rev >= 37) ? 32 : 24;
48 } else {
49 nb = 28;
50 }
51 if (nb == 32)
52 return 0xffffffff;
53 else
54 return (1 << nb) - 1;
55}
56
57static u32 bcma_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
58 u32 ticks)
59{
60 struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
61
62 return bcma_chipco_watchdog_timer_set(cc, ticks);
63}
64
65static u32 bcma_chipco_watchdog_timer_set_ms_wdt(struct bcm47xx_wdt *wdt,
66 u32 ms)
67{
68 struct bcma_drv_cc *cc = bcm47xx_wdt_get_drvdata(wdt);
69 u32 ticks;
70
71 ticks = bcma_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
72 return ticks / cc->ticks_per_ms;
73}
74
75static int bcma_chipco_watchdog_ticks_per_ms(struct bcma_drv_cc *cc)
76{
77 struct bcma_bus *bus = cc->core->bus;
78
79 if (cc->capabilities & BCMA_CC_CAP_PMU) {
80 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706)
81 /* 4706 CC and PMU watchdogs are clocked at 1/4 of ALP clock */
82 return bcma_chipco_alp_clock(cc) / 4000;
83 else
84 /* based on 32KHz ILP clock */
85 return 32;
86 } else {
87 return bcma_chipco_alp_clock(cc) / 1000;
88 }
89}
90
91int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc)
92{
93 struct bcm47xx_wdt wdt = {};
94 struct platform_device *pdev;
95
96 wdt.driver_data = cc;
97 wdt.timer_set = bcma_chipco_watchdog_timer_set_wdt;
98 wdt.timer_set_ms = bcma_chipco_watchdog_timer_set_ms_wdt;
99 wdt.max_timer_ms = bcma_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
100
101 pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
102 cc->core->bus->num, &wdt,
103 sizeof(wdt));
104 if (IS_ERR(pdev))
105 return PTR_ERR(pdev);
106
107 cc->watchdog = pdev;
108
109 return 0;
110}
111
25void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc) 112void bcma_core_chipcommon_early_init(struct bcma_drv_cc *cc)
26{ 113{
27 if (cc->early_setup_done) 114 if (cc->early_setup_done)
@@ -69,15 +156,33 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
69 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) | 156 ((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
70 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT))); 157 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
71 } 158 }
159 cc->ticks_per_ms = bcma_chipco_watchdog_ticks_per_ms(cc);
72 160
73 cc->setup_done = true; 161 cc->setup_done = true;
74} 162}
75 163
76/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 164/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
77void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks) 165u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
78{ 166{
79 /* instant NMI */ 167 u32 maxt;
80 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks); 168 enum bcma_clkmode clkmode;
169
170 maxt = bcma_chipco_watchdog_get_max_timer(cc);
171 if (cc->capabilities & BCMA_CC_CAP_PMU) {
172 if (ticks == 1)
173 ticks = 2;
174 else if (ticks > maxt)
175 ticks = maxt;
176 bcma_cc_write32(cc, BCMA_CC_PMU_WATCHDOG, ticks);
177 } else {
178 clkmode = ticks ? BCMA_CLKMODE_FAST : BCMA_CLKMODE_DYNAMIC;
179 bcma_core_set_clockmode(cc->core, clkmode);
180 if (ticks > maxt)
181 ticks = maxt;
182 /* instant NMI */
183 bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
184 }
185 return ticks;
81} 186}
82 187
83void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value) 188void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
@@ -131,8 +236,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
131 struct bcma_serial_port *ports = cc->serial_ports; 236 struct bcma_serial_port *ports = cc->serial_ports;
132 237
133 if (ccrev >= 11 && ccrev != 15) { 238 if (ccrev >= 11 && ccrev != 15) {
134 /* Fixed ALP clock */ 239 baud_base = bcma_chipco_alp_clock(cc);
135 baud_base = bcma_pmu_alp_clock(cc);
136 if (ccrev >= 21) { 240 if (ccrev >= 21) {
137 /* Turn off UART clock before switching clocksource. */ 241 /* Turn off UART clock before switching clocksource. */
138 bcma_cc_write32(cc, BCMA_CC_CORECTL, 242 bcma_cc_write32(cc, BCMA_CC_CORECTL,
diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c
index e56449506695..e6b5c89469dc 100644
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -538,7 +538,7 @@ DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
538static void bcma_core_pci_fixup_addresses(struct pci_dev *dev) 538static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
539{ 539{
540 struct resource *res; 540 struct resource *res;
541 int pos; 541 int pos, err;
542 542
543 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) { 543 if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
544 /* This is not a device on the PCI-core bridge. */ 544 /* This is not a device on the PCI-core bridge. */
@@ -551,8 +551,12 @@ static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
551 551
552 for (pos = 0; pos < 6; pos++) { 552 for (pos = 0; pos < 6; pos++) {
553 res = &dev->resource[pos]; 553 res = &dev->resource[pos];
554 if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) 554 if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM)) {
555 pci_assign_resource(dev, pos); 555 err = pci_assign_resource(dev, pos);
556 if (err)
557 pr_err("PCI: Problem fixing up the addresses on %s\n",
558 pci_name(dev));
559 }
556 } 560 }
557} 561}
558DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses); 562DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index a9718893000b..debd4f142f93 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -165,6 +165,12 @@ static int bcma_register_cores(struct bcma_bus *bus)
165 } 165 }
166#endif 166#endif
167 167
168 if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
169 err = bcma_chipco_watchdog_register(&bus->drv_cc);
170 if (err)
171 bcma_err(bus, "Error registering watchdog driver\n");
172 }
173
168 return 0; 174 return 0;
169} 175}
170 176
@@ -177,6 +183,8 @@ static void bcma_unregister_cores(struct bcma_bus *bus)
177 if (core->dev_registered) 183 if (core->dev_registered)
178 device_unregister(&core->dev); 184 device_unregister(&core->dev);
179 } 185 }
186 if (bus->hosttype == BCMA_HOSTTYPE_SOC)
187 platform_device_unregister(bus->drv_cc.watchdog);
180} 188}
181 189
182int __devinit bcma_bus_register(struct bcma_bus *bus) 190int __devinit bcma_bus_register(struct bcma_bus *bus)
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 154a4965be4f..3d339e04efb7 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1761,7 +1761,7 @@ static const struct ieee80211_ops adm8211_ops = {
1761 .get_tsf = adm8211_get_tsft 1761 .get_tsf = adm8211_get_tsft
1762}; 1762};
1763 1763
1764static int __devinit adm8211_probe(struct pci_dev *pdev, 1764static int adm8211_probe(struct pci_dev *pdev,
1765 const struct pci_device_id *id) 1765 const struct pci_device_id *id)
1766{ 1766{
1767 struct ieee80211_hw *dev; 1767 struct ieee80211_hw *dev;
@@ -1935,7 +1935,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
1935} 1935}
1936 1936
1937 1937
1938static void __devexit adm8211_remove(struct pci_dev *pdev) 1938static void adm8211_remove(struct pci_dev *pdev)
1939{ 1939{
1940 struct ieee80211_hw *dev = pci_get_drvdata(pdev); 1940 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1941 struct adm8211_priv *priv; 1941 struct adm8211_priv *priv;
@@ -1985,7 +1985,7 @@ static struct pci_driver adm8211_driver = {
1985 .name = "adm8211", 1985 .name = "adm8211",
1986 .id_table = adm8211_pci_id_table, 1986 .id_table = adm8211_pci_id_table,
1987 .probe = adm8211_probe, 1987 .probe = adm8211_probe,
1988 .remove = __devexit_p(adm8211_remove), 1988 .remove = adm8211_remove,
1989#ifdef CONFIG_PM 1989#ifdef CONFIG_PM
1990 .suspend = adm8211_suspend, 1990 .suspend = adm8211_suspend,
1991 .resume = adm8211_resume, 1991 .resume = adm8211_resume,
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 57f7db1ac31b..53295418f576 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -78,7 +78,7 @@ static struct pci_driver airo_driver = {
78 .name = DRV_NAME, 78 .name = DRV_NAME,
79 .id_table = card_ids, 79 .id_table = card_ids,
80 .probe = airo_pci_probe, 80 .probe = airo_pci_probe,
81 .remove = __devexit_p(airo_pci_remove), 81 .remove = airo_pci_remove,
82 .suspend = airo_pci_suspend, 82 .suspend = airo_pci_suspend,
83 .resume = airo_pci_resume, 83 .resume = airo_pci_resume,
84}; 84};
@@ -5584,7 +5584,7 @@ static void timer_func( struct net_device *dev ) {
5584} 5584}
5585 5585
5586#ifdef CONFIG_PCI 5586#ifdef CONFIG_PCI
5587static int __devinit airo_pci_probe(struct pci_dev *pdev, 5587static int airo_pci_probe(struct pci_dev *pdev,
5588 const struct pci_device_id *pent) 5588 const struct pci_device_id *pent)
5589{ 5589{
5590 struct net_device *dev; 5590 struct net_device *dev;
@@ -5606,7 +5606,7 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
5606 return 0; 5606 return 0;
5607} 5607}
5608 5608
5609static void __devexit airo_pci_remove(struct pci_dev *pdev) 5609static void airo_pci_remove(struct pci_dev *pdev)
5610{ 5610{
5611 struct net_device *dev = pci_get_drvdata(pdev); 5611 struct net_device *dev = pci_get_drvdata(pdev);
5612 5612
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index c25dcf192fec..1a67a4f829fe 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,4 +1,7 @@
1menuconfig ATH_COMMON 1config ATH_COMMON
2 tristate
3
4menuconfig ATH_CARDS
2 tristate "Atheros Wireless Cards" 5 tristate "Atheros Wireless Cards"
3 depends on CFG80211 && (!UML || BROKEN) 6 depends on CFG80211 && (!UML || BROKEN)
4 ---help--- 7 ---help---
@@ -14,7 +17,7 @@ menuconfig ATH_COMMON
14 17
15 http://wireless.kernel.org/en/users/Drivers/Atheros 18 http://wireless.kernel.org/en/users/Drivers/Atheros
16 19
17if ATH_COMMON 20if ATH_CARDS
18 21
19config ATH_DEBUG 22config ATH_DEBUG
20 bool "Atheros wireless debugging" 23 bool "Atheros wireless debugging"
diff --git a/drivers/net/wireless/ath/ar5523/Kconfig b/drivers/net/wireless/ath/ar5523/Kconfig
index 11d99ee8de51..0d320cc7769b 100644
--- a/drivers/net/wireless/ath/ar5523/Kconfig
+++ b/drivers/net/wireless/ath/ar5523/Kconfig
@@ -1,6 +1,7 @@
1config AR5523 1config AR5523
2 tristate "Atheros AR5523 wireless driver support" 2 tristate "Atheros AR5523 wireless driver support"
3 depends on MAC80211 && USB 3 depends on MAC80211 && USB
4 select ATH_COMMON
4 select FW_LOADER 5 select FW_LOADER
5 ---help--- 6 ---help---
6 This module add support for AR5523 based USB dongles such as D-Link 7 This module add support for AR5523 based USB dongles such as D-Link
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index 338c5c42357d..c9f81a388f15 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,6 +1,7 @@
1config ATH5K 1config ATH5K
2 tristate "Atheros 5xxx wireless cards support" 2 tristate "Atheros 5xxx wireless cards support"
3 depends on (PCI || ATHEROS_AR231X) && MAC80211 3 depends on (PCI || ATHEROS_AR231X) && MAC80211
4 select ATH_COMMON
4 select MAC80211_LEDS 5 select MAC80211_LEDS
5 select LEDS_CLASS 6 select LEDS_CLASS
6 select NEW_LEDS 7 select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 2fd5bab2e22a..3a5a61e03922 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2435,7 +2435,7 @@ static const struct ieee80211_iface_combination if_comb = {
2435 .num_different_channels = 1, 2435 .num_different_channels = 1,
2436}; 2436};
2437 2437
2438int __devinit 2438int
2439ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) 2439ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops)
2440{ 2440{
2441 struct ieee80211_hw *hw = ah->hw; 2441 struct ieee80211_hw *hw = ah->hw;
@@ -2861,7 +2861,7 @@ static void ath5k_reset_work(struct work_struct *work)
2861 mutex_unlock(&ah->lock); 2861 mutex_unlock(&ah->lock);
2862} 2862}
2863 2863
2864static int __devinit 2864static int
2865ath5k_init(struct ieee80211_hw *hw) 2865ath5k_init(struct ieee80211_hw *hw)
2866{ 2866{
2867 2867
diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
index b9f708a45f4e..f77ef36acf87 100644
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -158,7 +158,7 @@ void ath5k_unregister_leds(struct ath5k_hw *ah)
158 ath5k_unregister_led(&ah->tx_led); 158 ath5k_unregister_led(&ah->tx_led);
159} 159}
160 160
161int __devinit ath5k_init_leds(struct ath5k_hw *ah) 161int ath5k_init_leds(struct ath5k_hw *ah)
162{ 162{
163 int ret = 0; 163 int ret = 0;
164 struct ieee80211_hw *hw = ah->hw; 164 struct ieee80211_hw *hw = ah->hw;
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c
index dff48fbc63bf..859db7c34f87 100644
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -155,7 +155,7 @@ static const struct ath_bus_ops ath_pci_bus_ops = {
155* PCI Initialization * 155* PCI Initialization *
156\********************/ 156\********************/
157 157
158static int __devinit 158static int
159ath5k_pci_probe(struct pci_dev *pdev, 159ath5k_pci_probe(struct pci_dev *pdev,
160 const struct pci_device_id *id) 160 const struct pci_device_id *id)
161{ 161{
@@ -285,7 +285,7 @@ err:
285 return ret; 285 return ret;
286} 286}
287 287
288static void __devexit 288static void
289ath5k_pci_remove(struct pci_dev *pdev) 289ath5k_pci_remove(struct pci_dev *pdev)
290{ 290{
291 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 291 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
@@ -336,7 +336,7 @@ static struct pci_driver ath5k_pci_driver = {
336 .name = KBUILD_MODNAME, 336 .name = KBUILD_MODNAME,
337 .id_table = ath5k_pci_id_table, 337 .id_table = ath5k_pci_id_table,
338 .probe = ath5k_pci_probe, 338 .probe = ath5k_pci_probe,
339 .remove = __devexit_p(ath5k_pci_remove), 339 .remove = ath5k_pci_remove,
340 .driver.pm = ATH5K_PM_OPS, 340 .driver.pm = ATH5K_PM_OPS,
341}; 341};
342 342
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index c7aa6646123e..5fc15bf8be09 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -17,6 +17,7 @@ config ATH9K_BTCOEX_SUPPORT
17config ATH9K 17config ATH9K
18 tristate "Atheros 802.11n wireless cards support" 18 tristate "Atheros 802.11n wireless cards support"
19 depends on MAC80211 19 depends on MAC80211
20 select ATH_COMMON
20 select ATH9K_HW 21 select ATH9K_HW
21 select MAC80211_LEDS 22 select MAC80211_LEDS
22 select LEDS_CLASS 23 select LEDS_CLASS
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 80bab1b8447a..86e26a19efda 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -259,9 +259,10 @@ struct ath_atx_tid {
259}; 259};
260 260
261struct ath_node { 261struct ath_node {
262 struct ath_softc *sc;
262 struct ieee80211_sta *sta; /* station struct we're part of */ 263 struct ieee80211_sta *sta; /* station struct we're part of */
263 struct ieee80211_vif *vif; /* interface with which we're associated */ 264 struct ieee80211_vif *vif; /* interface with which we're associated */
264 struct ath_atx_tid tid[WME_NUM_TID]; 265 struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
265 struct ath_atx_ac ac[IEEE80211_NUM_ACS]; 266 struct ath_atx_ac ac[IEEE80211_NUM_ACS];
266 int ps_key; 267 int ps_key;
267 268
@@ -269,6 +270,10 @@ struct ath_node {
269 u8 mpdudensity; 270 u8 mpdudensity;
270 271
271 bool sleeping; 272 bool sleeping;
273
274#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
275 struct dentry *node_stat;
276#endif
272}; 277};
273 278
274#define AGGR_CLEANUP BIT(1) 279#define AGGR_CLEANUP BIT(1)
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index 76b543900314..5f845beeb18b 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,7 +23,6 @@
23 23
24/* Common header for Atheros 802.11n base driver cores */ 24/* Common header for Atheros 802.11n base driver cores */
25 25
26#define WME_NUM_TID 16
27#define WME_BA_BMP_SIZE 64 26#define WME_BA_BMP_SIZE 64
28#define WME_MAX_BA WME_BA_BMP_SIZE 27#define WME_MAX_BA WME_BA_BMP_SIZE
29#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) 28#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 939308c25712..13ff9edc2401 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1509,6 +1509,215 @@ static const struct file_operations fops_btcoex = {
1509}; 1509};
1510#endif 1510#endif
1511 1511
1512static ssize_t read_file_node_stat(struct file *file, char __user *user_buf,
1513 size_t count, loff_t *ppos)
1514{
1515 struct ath_node *an = file->private_data;
1516 struct ath_softc *sc = an->sc;
1517 struct ath_atx_tid *tid;
1518 struct ath_atx_ac *ac;
1519 struct ath_txq *txq;
1520 u32 len = 0, size = 4096;
1521 char *buf;
1522 size_t retval;
1523 int tidno, acno;
1524
1525 buf = kzalloc(size, GFP_KERNEL);
1526 if (buf == NULL)
1527 return -ENOMEM;
1528
1529 if (!an->sta->ht_cap.ht_supported) {
1530 len = snprintf(buf, size, "%s\n",
1531 "HT not supported");
1532 goto exit;
1533 }
1534
1535 len = snprintf(buf, size, "Max-AMPDU: %d\n",
1536 an->maxampdu);
1537 len += snprintf(buf + len, size - len, "MPDU Density: %d\n\n",
1538 an->mpdudensity);
1539
1540 len += snprintf(buf + len, size - len,
1541 "%2s%7s\n", "AC", "SCHED");
1542
1543 for (acno = 0, ac = &an->ac[acno];
1544 acno < IEEE80211_NUM_ACS; acno++, ac++) {
1545 txq = ac->txq;
1546 ath_txq_lock(sc, txq);
1547 len += snprintf(buf + len, size - len,
1548 "%2d%7d\n",
1549 acno, ac->sched);
1550 ath_txq_unlock(sc, txq);
1551 }
1552
1553 len += snprintf(buf + len, size - len,
1554 "\n%3s%11s%10s%10s%10s%10s%9s%6s%8s\n",
1555 "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE",
1556 "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED");
1557
1558 for (tidno = 0, tid = &an->tid[tidno];
1559 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
1560 txq = tid->ac->txq;
1561 ath_txq_lock(sc, txq);
1562 len += snprintf(buf + len, size - len,
1563 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n",
1564 tid->tidno, tid->seq_start, tid->seq_next,
1565 tid->baw_size, tid->baw_head, tid->baw_tail,
1566 tid->bar_index, tid->sched, tid->paused);
1567 ath_txq_unlock(sc, txq);
1568 }
1569exit:
1570 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1571 kfree(buf);
1572
1573 return retval;
1574}
1575
1576static const struct file_operations fops_node_stat = {
1577 .read = read_file_node_stat,
1578 .open = simple_open,
1579 .owner = THIS_MODULE,
1580 .llseek = default_llseek,
1581};
1582
1583void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
1584 struct ieee80211_vif *vif,
1585 struct ieee80211_sta *sta,
1586 struct dentry *dir)
1587{
1588 struct ath_node *an = (struct ath_node *)sta->drv_priv;
1589 an->node_stat = debugfs_create_file("node_stat", S_IRUGO,
1590 dir, an, &fops_node_stat);
1591}
1592
1593void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
1594 struct ieee80211_vif *vif,
1595 struct ieee80211_sta *sta,
1596 struct dentry *dir)
1597{
1598 struct ath_node *an = (struct ath_node *)sta->drv_priv;
1599 debugfs_remove(an->node_stat);
1600}
1601
1602/* Ethtool support for get-stats */
1603
1604#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
1605static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
1606 "tx_pkts_nic",
1607 "tx_bytes_nic",
1608 "rx_pkts_nic",
1609 "rx_bytes_nic",
1610 AMKSTR(d_tx_pkts),
1611 AMKSTR(d_tx_bytes),
1612 AMKSTR(d_tx_mpdus_queued),
1613 AMKSTR(d_tx_mpdus_completed),
1614 AMKSTR(d_tx_mpdu_xretries),
1615 AMKSTR(d_tx_aggregates),
1616 AMKSTR(d_tx_ampdus_queued_hw),
1617 AMKSTR(d_tx_ampdus_queued_sw),
1618 AMKSTR(d_tx_ampdus_completed),
1619 AMKSTR(d_tx_ampdu_retries),
1620 AMKSTR(d_tx_ampdu_xretries),
1621 AMKSTR(d_tx_fifo_underrun),
1622 AMKSTR(d_tx_op_exceeded),
1623 AMKSTR(d_tx_timer_expiry),
1624 AMKSTR(d_tx_desc_cfg_err),
1625 AMKSTR(d_tx_data_underrun),
1626 AMKSTR(d_tx_delim_underrun),
1627 "d_rx_decrypt_crc_err",
1628 "d_rx_phy_err",
1629 "d_rx_mic_err",
1630 "d_rx_pre_delim_crc_err",
1631 "d_rx_post_delim_crc_err",
1632 "d_rx_decrypt_busy_err",
1633
1634 "d_rx_phyerr_radar",
1635 "d_rx_phyerr_ofdm_timing",
1636 "d_rx_phyerr_cck_timing",
1637
1638};
1639#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
1640
1641void ath9k_get_et_strings(struct ieee80211_hw *hw,
1642 struct ieee80211_vif *vif,
1643 u32 sset, u8 *data)
1644{
1645 if (sset == ETH_SS_STATS)
1646 memcpy(data, *ath9k_gstrings_stats,
1647 sizeof(ath9k_gstrings_stats));
1648}
1649
1650int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
1651 struct ieee80211_vif *vif, int sset)
1652{
1653 if (sset == ETH_SS_STATS)
1654 return ATH9K_SSTATS_LEN;
1655 return 0;
1656}
1657
1658#define AWDATA(elem) \
1659 do { \
1660 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
1661 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
1662 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
1663 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
1664 } while (0)
1665
1666#define AWDATA_RX(elem) \
1667 do { \
1668 data[i++] = sc->debug.stats.rxstats.elem; \
1669 } while (0)
1670
1671void ath9k_get_et_stats(struct ieee80211_hw *hw,
1672 struct ieee80211_vif *vif,
1673 struct ethtool_stats *stats, u64 *data)
1674{
1675 struct ath_softc *sc = hw->priv;
1676 int i = 0;
1677
1678 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
1679 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
1680 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
1681 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
1682 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
1683 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
1684 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
1685 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
1686 AWDATA_RX(rx_pkts_all);
1687 AWDATA_RX(rx_bytes_all);
1688
1689 AWDATA(tx_pkts_all);
1690 AWDATA(tx_bytes_all);
1691 AWDATA(queued);
1692 AWDATA(completed);
1693 AWDATA(xretries);
1694 AWDATA(a_aggr);
1695 AWDATA(a_queued_hw);
1696 AWDATA(a_queued_sw);
1697 AWDATA(a_completed);
1698 AWDATA(a_retries);
1699 AWDATA(a_xretries);
1700 AWDATA(fifo_underrun);
1701 AWDATA(xtxop);
1702 AWDATA(timer_exp);
1703 AWDATA(desc_cfg_err);
1704 AWDATA(data_underrun);
1705 AWDATA(delim_underrun);
1706
1707 AWDATA_RX(decrypt_crc_err);
1708 AWDATA_RX(phy_err);
1709 AWDATA_RX(mic_err);
1710 AWDATA_RX(pre_delim_crc_err);
1711 AWDATA_RX(post_delim_crc_err);
1712 AWDATA_RX(decrypt_busy_err);
1713
1714 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
1715 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
1716 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
1717
1718 WARN_ON(i != ATH9K_SSTATS_LEN);
1719}
1720
1512int ath9k_init_debug(struct ath_hw *ah) 1721int ath9k_init_debug(struct ath_hw *ah)
1513{ 1722{
1514 struct ath_common *common = ath9k_hw_common(ah); 1723 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index f9bee18de5a0..72d4893311b1 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -307,7 +307,22 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf,
307 struct ath_tx_status *ts, struct ath_txq *txq, 307 struct ath_tx_status *ts, struct ath_txq *txq,
308 unsigned int flags); 308 unsigned int flags);
309void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); 309void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs);
310 310int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
311 struct ieee80211_vif *vif, int sset);
312void ath9k_get_et_stats(struct ieee80211_hw *hw,
313 struct ieee80211_vif *vif,
314 struct ethtool_stats *stats, u64 *data);
315void ath9k_get_et_strings(struct ieee80211_hw *hw,
316 struct ieee80211_vif *vif,
317 u32 sset, u8 *data);
318void ath9k_sta_add_debugfs(struct ieee80211_hw *hw,
319 struct ieee80211_vif *vif,
320 struct ieee80211_sta *sta,
321 struct dentry *dir);
322void ath9k_sta_remove_debugfs(struct ieee80211_hw *hw,
323 struct ieee80211_vif *vif,
324 struct ieee80211_sta *sta,
325 struct dentry *dir);
311#else 326#else
312 327
313#define RX_STAT_INC(c) /* NOP */ 328#define RX_STAT_INC(c) /* NOP */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0653dbc99e31..be30a9af1528 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -331,6 +331,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
331 u8 density; 331 u8 density;
332 an = (struct ath_node *)sta->drv_priv; 332 an = (struct ath_node *)sta->drv_priv;
333 333
334 an->sc = sc;
334 an->sta = sta; 335 an->sta = sta;
335 an->vif = vif; 336 an->vif = vif;
336 337
@@ -1882,133 +1883,6 @@ static int ath9k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
1882 return 0; 1883 return 0;
1883} 1884}
1884 1885
1885#ifdef CONFIG_ATH9K_DEBUGFS
1886
1887/* Ethtool support for get-stats */
1888
1889#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
1890static const char ath9k_gstrings_stats[][ETH_GSTRING_LEN] = {
1891 "tx_pkts_nic",
1892 "tx_bytes_nic",
1893 "rx_pkts_nic",
1894 "rx_bytes_nic",
1895 AMKSTR(d_tx_pkts),
1896 AMKSTR(d_tx_bytes),
1897 AMKSTR(d_tx_mpdus_queued),
1898 AMKSTR(d_tx_mpdus_completed),
1899 AMKSTR(d_tx_mpdu_xretries),
1900 AMKSTR(d_tx_aggregates),
1901 AMKSTR(d_tx_ampdus_queued_hw),
1902 AMKSTR(d_tx_ampdus_queued_sw),
1903 AMKSTR(d_tx_ampdus_completed),
1904 AMKSTR(d_tx_ampdu_retries),
1905 AMKSTR(d_tx_ampdu_xretries),
1906 AMKSTR(d_tx_fifo_underrun),
1907 AMKSTR(d_tx_op_exceeded),
1908 AMKSTR(d_tx_timer_expiry),
1909 AMKSTR(d_tx_desc_cfg_err),
1910 AMKSTR(d_tx_data_underrun),
1911 AMKSTR(d_tx_delim_underrun),
1912
1913 "d_rx_decrypt_crc_err",
1914 "d_rx_phy_err",
1915 "d_rx_mic_err",
1916 "d_rx_pre_delim_crc_err",
1917 "d_rx_post_delim_crc_err",
1918 "d_rx_decrypt_busy_err",
1919
1920 "d_rx_phyerr_radar",
1921 "d_rx_phyerr_ofdm_timing",
1922 "d_rx_phyerr_cck_timing",
1923
1924};
1925#define ATH9K_SSTATS_LEN ARRAY_SIZE(ath9k_gstrings_stats)
1926
1927static void ath9k_get_et_strings(struct ieee80211_hw *hw,
1928 struct ieee80211_vif *vif,
1929 u32 sset, u8 *data)
1930{
1931 if (sset == ETH_SS_STATS)
1932 memcpy(data, *ath9k_gstrings_stats,
1933 sizeof(ath9k_gstrings_stats));
1934}
1935
1936static int ath9k_get_et_sset_count(struct ieee80211_hw *hw,
1937 struct ieee80211_vif *vif, int sset)
1938{
1939 if (sset == ETH_SS_STATS)
1940 return ATH9K_SSTATS_LEN;
1941 return 0;
1942}
1943
1944#define AWDATA(elem) \
1945 do { \
1946 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].elem; \
1947 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].elem; \
1948 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].elem; \
1949 data[i++] = sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].elem; \
1950 } while (0)
1951
1952#define AWDATA_RX(elem) \
1953 do { \
1954 data[i++] = sc->debug.stats.rxstats.elem; \
1955 } while (0)
1956
1957static void ath9k_get_et_stats(struct ieee80211_hw *hw,
1958 struct ieee80211_vif *vif,
1959 struct ethtool_stats *stats, u64 *data)
1960{
1961 struct ath_softc *sc = hw->priv;
1962 int i = 0;
1963
1964 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_pkts_all +
1965 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_pkts_all +
1966 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_pkts_all +
1967 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_pkts_all);
1968 data[i++] = (sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BE)].tx_bytes_all +
1969 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_BK)].tx_bytes_all +
1970 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VI)].tx_bytes_all +
1971 sc->debug.stats.txstats[PR_QNUM(IEEE80211_AC_VO)].tx_bytes_all);
1972 AWDATA_RX(rx_pkts_all);
1973 AWDATA_RX(rx_bytes_all);
1974
1975 AWDATA(tx_pkts_all);
1976 AWDATA(tx_bytes_all);
1977 AWDATA(queued);
1978 AWDATA(completed);
1979 AWDATA(xretries);
1980 AWDATA(a_aggr);
1981 AWDATA(a_queued_hw);
1982 AWDATA(a_queued_sw);
1983 AWDATA(a_completed);
1984 AWDATA(a_retries);
1985 AWDATA(a_xretries);
1986 AWDATA(fifo_underrun);
1987 AWDATA(xtxop);
1988 AWDATA(timer_exp);
1989 AWDATA(desc_cfg_err);
1990 AWDATA(data_underrun);
1991 AWDATA(delim_underrun);
1992
1993 AWDATA_RX(decrypt_crc_err);
1994 AWDATA_RX(phy_err);
1995 AWDATA_RX(mic_err);
1996 AWDATA_RX(pre_delim_crc_err);
1997 AWDATA_RX(post_delim_crc_err);
1998 AWDATA_RX(decrypt_busy_err);
1999
2000 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_RADAR]);
2001 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_OFDM_TIMING]);
2002 AWDATA_RX(phy_err_stats[ATH9K_PHYERR_CCK_TIMING]);
2003
2004 WARN_ON(i != ATH9K_SSTATS_LEN);
2005}
2006
2007/* End of ethtool get-stats functions */
2008
2009#endif
2010
2011
2012#ifdef CONFIG_PM_SLEEP 1886#ifdef CONFIG_PM_SLEEP
2013 1887
2014static void ath9k_wow_map_triggers(struct ath_softc *sc, 1888static void ath9k_wow_map_triggers(struct ath_softc *sc,
@@ -2402,7 +2276,12 @@ struct ieee80211_ops ath9k_ops = {
2402 2276
2403#ifdef CONFIG_ATH9K_DEBUGFS 2277#ifdef CONFIG_ATH9K_DEBUGFS
2404 .get_et_sset_count = ath9k_get_et_sset_count, 2278 .get_et_sset_count = ath9k_get_et_sset_count,
2405 .get_et_stats = ath9k_get_et_stats, 2279 .get_et_stats = ath9k_get_et_stats,
2406 .get_et_strings = ath9k_get_et_strings, 2280 .get_et_strings = ath9k_get_et_strings,
2281#endif
2282
2283#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)
2284 .sta_add_debugfs = ath9k_sta_add_debugfs,
2285 .sta_remove_debugfs = ath9k_sta_remove_debugfs,
2407#endif 2286#endif
2408}; 2287};
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 706378ea3ba2..5c02702f21e7 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -257,8 +257,9 @@ static void ath_mci_set_concur_txprio(struct ath_softc *sc)
257{ 257{
258 struct ath_btcoex *btcoex = &sc->btcoex; 258 struct ath_btcoex *btcoex = &sc->btcoex;
259 struct ath_mci_profile *mci = &btcoex->mci; 259 struct ath_mci_profile *mci = &btcoex->mci;
260 u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */ 260 u8 stomp_txprio[ATH_BTCOEX_STOMP_MAX];
261 261
262 memset(stomp_txprio, 0, sizeof(stomp_txprio));
262 if (mci->num_mgmt) { 263 if (mci->num_mgmt) {
263 stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO; 264 stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO;
264 if (!mci->num_pan && !mci->num_other_acl) 265 if (!mci->num_pan && !mci->num_other_acl)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 9553203ee624..8e9b826f878b 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -287,7 +287,7 @@ static void ath_pci_remove(struct pci_dev *pdev)
287 pci_release_region(pdev, 0); 287 pci_release_region(pdev, 0);
288} 288}
289 289
290#ifdef CONFIG_PM 290#ifdef CONFIG_PM_SLEEP
291 291
292static int ath_pci_suspend(struct device *device) 292static int ath_pci_suspend(struct device *device)
293{ 293{
@@ -333,22 +333,15 @@ static int ath_pci_resume(struct device *device)
333 return 0; 333 return 0;
334} 334}
335 335
336static const struct dev_pm_ops ath9k_pm_ops = { 336static SIMPLE_DEV_PM_OPS(ath9k_pm_ops, ath_pci_suspend, ath_pci_resume);
337 .suspend = ath_pci_suspend,
338 .resume = ath_pci_resume,
339 .freeze = ath_pci_suspend,
340 .thaw = ath_pci_resume,
341 .poweroff = ath_pci_suspend,
342 .restore = ath_pci_resume,
343};
344 337
345#define ATH9K_PM_OPS (&ath9k_pm_ops) 338#define ATH9K_PM_OPS (&ath9k_pm_ops)
346 339
347#else /* !CONFIG_PM */ 340#else /* !CONFIG_PM_SLEEP */
348 341
349#define ATH9K_PM_OPS NULL 342#define ATH9K_PM_OPS NULL
350 343
351#endif /* !CONFIG_PM */ 344#endif /* !CONFIG_PM_SLEEP */
352 345
353 346
354MODULE_DEVICE_TABLE(pci, ath_pci_id_table); 347MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 34130943f9de..90e48a0fafe5 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -312,7 +312,6 @@ static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
312 } 312 }
313 313
314 bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); 314 bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
315 bf->bf_next = NULL;
316 list_del(&bf->list); 315 list_del(&bf->list);
317 316
318 spin_unlock_bh(&sc->tx.txbuflock); 317 spin_unlock_bh(&sc->tx.txbuflock);
@@ -1263,7 +1262,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc,
1263 int tidno; 1262 int tidno;
1264 1263
1265 for (tidno = 0, tid = &an->tid[tidno]; 1264 for (tidno = 0, tid = &an->tid[tidno];
1266 tidno < WME_NUM_TID; tidno++, tid++) { 1265 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
1267 1266
1268 if (!tid->sched) 1267 if (!tid->sched)
1269 continue; 1268 continue;
@@ -1297,7 +1296,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
1297 int tidno; 1296 int tidno;
1298 1297
1299 for (tidno = 0, tid = &an->tid[tidno]; 1298 for (tidno = 0, tid = &an->tid[tidno];
1300 tidno < WME_NUM_TID; tidno++, tid++) { 1299 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
1301 1300
1302 ac = tid->ac; 1301 ac = tid->ac;
1303 txq = ac->txq; 1302 txq = ac->txq;
@@ -2448,7 +2447,7 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2448 int tidno, acno; 2447 int tidno, acno;
2449 2448
2450 for (tidno = 0, tid = &an->tid[tidno]; 2449 for (tidno = 0, tid = &an->tid[tidno];
2451 tidno < WME_NUM_TID; 2450 tidno < IEEE80211_NUM_TIDS;
2452 tidno++, tid++) { 2451 tidno++, tid++) {
2453 tid->an = an; 2452 tid->an = an;
2454 tid->tidno = tidno; 2453 tid->tidno = tidno;
@@ -2481,7 +2480,7 @@ void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
2481 int tidno; 2480 int tidno;
2482 2481
2483 for (tidno = 0, tid = &an->tid[tidno]; 2482 for (tidno = 0, tid = &an->tid[tidno];
2484 tidno < WME_NUM_TID; tidno++, tid++) { 2483 tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
2485 2484
2486 ac = tid->ac; 2485 ac = tid->ac;
2487 txq = ac->txq; 2486 txq = ac->txq;
diff --git a/drivers/net/wireless/ath/carl9170/Kconfig b/drivers/net/wireless/ath/carl9170/Kconfig
index 267d5dcf82dc..13a204598766 100644
--- a/drivers/net/wireless/ath/carl9170/Kconfig
+++ b/drivers/net/wireless/ath/carl9170/Kconfig
@@ -1,6 +1,7 @@
1config CARL9170 1config CARL9170
2 tristate "Linux Community AR9170 802.11n USB support" 2 tristate "Linux Community AR9170 802.11n USB support"
3 depends on USB && MAC80211 && EXPERIMENTAL 3 depends on USB && MAC80211 && EXPERIMENTAL
4 select ATH_COMMON
4 select FW_LOADER 5 select FW_LOADER
5 select CRC32 6 select CRC32
6 help 7 help
diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c
index 6d22382875bc..876a773fd0b4 100644
--- a/drivers/net/wireless/ath/carl9170/rx.c
+++ b/drivers/net/wireless/ath/carl9170/rx.c
@@ -814,6 +814,8 @@ static void carl9170_rx_untie_data(struct ar9170 *ar, u8 *buf, int len)
814 814
815 if (phy) 815 if (phy)
816 carl9170_rx_phy_status(ar, phy, &status); 816 carl9170_rx_phy_status(ar, phy, &status);
817 else
818 status.flag |= RX_FLAG_NO_SIGNAL_VAL;
817 819
818 if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status)) 820 if (carl9170_handle_mpdu(ar, buf, mpdu_len, &status))
819 goto drop; 821 goto drop;
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index 84377cf580e0..ef4ec0da6e49 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -1485,6 +1485,13 @@ void carl9170_op_tx(struct ieee80211_hw *hw,
1485 } 1485 }
1486 1486
1487 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1487 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1488 /* to static code analyzers and reviewers:
1489 * mac80211 guarantees that a valid "sta"
1490 * reference is present, if a frame is to
1491 * be part of an ampdu. Hence any extra
1492 * sta == NULL checks are redundant in this
1493 * special case.
1494 */
1488 run = carl9170_tx_ampdu_queue(ar, sta, skb); 1495 run = carl9170_tx_ampdu_queue(ar, sta, skb);
1489 if (run) 1496 if (run)
1490 carl9170_tx_ampdu(ar); 1497 carl9170_tx_ampdu(ar);
diff --git a/drivers/net/wireless/atmel_pci.c b/drivers/net/wireless/atmel_pci.c
index 51e33b53386e..c1b159ebcffe 100644
--- a/drivers/net/wireless/atmel_pci.c
+++ b/drivers/net/wireless/atmel_pci.c
@@ -45,11 +45,11 @@ static struct pci_driver atmel_driver = {
45 .name = "atmel", 45 .name = "atmel",
46 .id_table = card_ids, 46 .id_table = card_ids,
47 .probe = atmel_pci_probe, 47 .probe = atmel_pci_probe,
48 .remove = __devexit_p(atmel_pci_remove), 48 .remove = atmel_pci_remove,
49}; 49};
50 50
51 51
52static int __devinit atmel_pci_probe(struct pci_dev *pdev, 52static int atmel_pci_probe(struct pci_dev *pdev,
53 const struct pci_device_id *pent) 53 const struct pci_device_id *pent)
54{ 54{
55 struct net_device *dev; 55 struct net_device *dev;
@@ -69,7 +69,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
69 return 0; 69 return 0;
70} 70}
71 71
72static void __devexit atmel_pci_remove(struct pci_dev *pdev) 72static void atmel_pci_remove(struct pci_dev *pdev)
73{ 73{
74 stop_atmel_card(pci_get_drvdata(pdev)); 74 stop_atmel_card(pci_get_drvdata(pdev));
75} 75}
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 714cad649c45..f2ea2ceec8a9 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -60,7 +60,7 @@ static int b43_pcmcia_resume(struct pcmcia_device *dev)
60# define b43_pcmcia_resume NULL 60# define b43_pcmcia_resume NULL
61#endif /* CONFIG_PM */ 61#endif /* CONFIG_PM */
62 62
63static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) 63static int b43_pcmcia_probe(struct pcmcia_device *dev)
64{ 64{
65 struct ssb_bus *ssb; 65 struct ssb_bus *ssb;
66 int err = -ENOMEM; 66 int err = -ENOMEM;
@@ -110,7 +110,7 @@ out_error:
110 return err; 110 return err;
111} 111}
112 112
113static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev) 113static void b43_pcmcia_remove(struct pcmcia_device *dev)
114{ 114{
115 struct ssb_bus *ssb = dev->priv; 115 struct ssb_bus *ssb = dev->priv;
116 116
@@ -125,7 +125,7 @@ static struct pcmcia_driver b43_pcmcia_driver = {
125 .name = "b43-pcmcia", 125 .name = "b43-pcmcia",
126 .id_table = b43_pcmcia_tbl, 126 .id_table = b43_pcmcia_tbl,
127 .probe = b43_pcmcia_probe, 127 .probe = b43_pcmcia_probe,
128 .remove = __devexit_p(b43_pcmcia_remove), 128 .remove = b43_pcmcia_remove,
129 .suspend = b43_pcmcia_suspend, 129 .suspend = b43_pcmcia_suspend,
130 .resume = b43_pcmcia_resume, 130 .resume = b43_pcmcia_resume,
131}; 131};
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c
index a54fb2d29089..59a521800694 100644
--- a/drivers/net/wireless/b43/sdio.c
+++ b/drivers/net/wireless/b43/sdio.c
@@ -93,7 +93,7 @@ void b43_sdio_free_irq(struct b43_wldev *dev)
93 sdio->irq_handler = NULL; 93 sdio->irq_handler = NULL;
94} 94}
95 95
96static int __devinit b43_sdio_probe(struct sdio_func *func, 96static int b43_sdio_probe(struct sdio_func *func,
97 const struct sdio_device_id *id) 97 const struct sdio_device_id *id)
98{ 98{
99 struct b43_sdio *sdio; 99 struct b43_sdio *sdio;
@@ -171,7 +171,7 @@ out:
171 return error; 171 return error;
172} 172}
173 173
174static void __devexit b43_sdio_remove(struct sdio_func *func) 174static void b43_sdio_remove(struct sdio_func *func)
175{ 175{
176 struct b43_sdio *sdio = sdio_get_drvdata(func); 176 struct b43_sdio *sdio = sdio_get_drvdata(func);
177 177
@@ -193,7 +193,7 @@ static struct sdio_driver b43_sdio_driver = {
193 .name = "b43-sdio", 193 .name = "b43-sdio",
194 .id_table = b43_sdio_ids, 194 .id_table = b43_sdio_ids,
195 .probe = b43_sdio_probe, 195 .probe = b43_sdio_probe,
196 .remove = __devexit_p(b43_sdio_remove), 196 .remove = b43_sdio_remove,
197}; 197};
198 198
199int b43_sdio_init(void) 199int b43_sdio_init(void)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
index fa8fc4433417..7a00c4614baf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -314,7 +314,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
314 while ((event = brcmf_fweh_dequeue_event(fweh))) { 314 while ((event = brcmf_fweh_dequeue_event(fweh))) {
315 ifp = drvr->iflist[event->ifidx]; 315 ifp = drvr->iflist[event->ifidx];
316 316
317 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n", 317 brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM\n",
318 brcmf_fweh_event_name(event->code), event->code, 318 brcmf_fweh_event_name(event->code), event->code,
319 event->emsg.ifidx, event->emsg.bsscfgidx, 319 event->emsg.ifidx, event->emsg.bsscfgidx,
320 event->emsg.addr); 320 event->emsg.addr);
@@ -337,7 +337,7 @@ static void brcmf_fweh_event_worker(struct work_struct *work)
337 emsg.version, emsg.flags, emsg.status, emsg.reason); 337 emsg.version, emsg.flags, emsg.status, emsg.reason);
338 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, 338 brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data,
339 min_t(u32, emsg.datalen, 64), 339 min_t(u32, emsg.datalen, 64),
340 "appended:"); 340 "event payload, len=%d\n", emsg.datalen);
341 341
342 /* special handling of interface event */ 342 /* special handling of interface event */
343 if (event->code == BRCMF_E_IF) { 343 if (event->code == BRCMF_E_IF) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
index b39246a630df..240a2eafead5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -158,7 +158,7 @@ typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp,
158 */ 158 */
159struct brcmf_fweh_info { 159struct brcmf_fweh_info {
160 struct work_struct event_work; 160 struct work_struct event_work;
161 struct spinlock evt_q_lock; 161 spinlock_t evt_q_lock;
162 struct list_head event_q; 162 struct list_head event_q;
163 int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, 163 int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp,
164 const struct brcmf_event_msg *evtmsg, 164 const struct brcmf_event_msg *evtmsg,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 2044fdb55558..96bc349d7f6c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -447,7 +447,7 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
447 struct vif_params *params) 447 struct vif_params *params)
448{ 448{
449 struct brcmf_if *ifp = netdev_priv(ndev); 449 struct brcmf_if *ifp = netdev_priv(ndev);
450 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); 450 struct brcmf_cfg80211_vif *vif = ifp->vif;
451 s32 infra = 0; 451 s32 infra = 0;
452 s32 ap = 0; 452 s32 ap = 0;
453 s32 err = 0; 453 s32 err = 0;
@@ -461,15 +461,15 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
461 type); 461 type);
462 return -EOPNOTSUPP; 462 return -EOPNOTSUPP;
463 case NL80211_IFTYPE_ADHOC: 463 case NL80211_IFTYPE_ADHOC:
464 cfg->conf->mode = WL_MODE_IBSS; 464 vif->mode = WL_MODE_IBSS;
465 infra = 0; 465 infra = 0;
466 break; 466 break;
467 case NL80211_IFTYPE_STATION: 467 case NL80211_IFTYPE_STATION:
468 cfg->conf->mode = WL_MODE_BSS; 468 vif->mode = WL_MODE_BSS;
469 infra = 1; 469 infra = 1;
470 break; 470 break;
471 case NL80211_IFTYPE_AP: 471 case NL80211_IFTYPE_AP:
472 cfg->conf->mode = WL_MODE_AP; 472 vif->mode = WL_MODE_AP;
473 ap = 1; 473 ap = 1;
474 break; 474 break;
475 default: 475 default:
@@ -478,18 +478,16 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
478 } 478 }
479 479
480 if (ap) { 480 if (ap) {
481 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); 481 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
482 WL_INFO("IF Type = AP\n"); 482 WL_INFO("IF Type = AP\n");
483 } else { 483 } else {
484 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), 484 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
485 BRCMF_C_SET_INFRA, infra);
486 if (err) { 485 if (err) {
487 WL_ERR("WLC_SET_INFRA error (%d)\n", err); 486 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
488 err = -EAGAIN; 487 err = -EAGAIN;
489 goto done; 488 goto done;
490 } 489 }
491 WL_INFO("IF Type = %s\n", 490 WL_INFO("IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
492 (cfg->conf->mode == WL_MODE_IBSS) ?
493 "Adhoc" : "Infra"); 491 "Adhoc" : "Infra");
494 } 492 }
495 ndev->ieee80211_ptr->iftype = type; 493 ndev->ieee80211_ptr->iftype = type;
@@ -963,22 +961,21 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
963 } 961 }
964} 962}
965 963
966static void brcmf_link_down(struct brcmf_cfg80211_info *cfg) 964static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
967{ 965{
968 struct net_device *ndev = NULL;
969 s32 err = 0; 966 s32 err = 0;
970 967
971 WL_TRACE("Enter\n"); 968 WL_TRACE("Enter\n");
972 969
973 if (cfg->link_up) { 970 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
974 ndev = cfg_to_ndev(cfg);
975 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); 971 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
976 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), 972 err = brcmf_fil_cmd_data_set(vif->ifp,
977 BRCMF_C_DISASSOC, NULL, 0); 973 BRCMF_C_DISASSOC, NULL, 0);
978 if (err) 974 if (err)
979 WL_ERR("WLC_DISASSOC failed (%d)\n", err); 975 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
980 cfg->link_up = false; 976 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
981 } 977 }
978 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
982 WL_TRACE("Exit\n"); 979 WL_TRACE("Exit\n");
983} 980}
984 981
@@ -1130,7 +1127,6 @@ done:
1130static s32 1127static s32
1131brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1128brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1132{ 1129{
1133 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1134 struct brcmf_if *ifp = netdev_priv(ndev); 1130 struct brcmf_if *ifp = netdev_priv(ndev);
1135 s32 err = 0; 1131 s32 err = 0;
1136 1132
@@ -1138,7 +1134,7 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1138 if (!check_vif_up(ifp->vif)) 1134 if (!check_vif_up(ifp->vif))
1139 return -EIO; 1135 return -EIO;
1140 1136
1141 brcmf_link_down(cfg); 1137 brcmf_link_down(ifp->vif);
1142 1138
1143 WL_TRACE("Exit\n"); 1139 WL_TRACE("Exit\n");
1144 1140
@@ -1496,7 +1492,6 @@ static s32
1496brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, 1492brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1497 u16 reason_code) 1493 u16 reason_code)
1498{ 1494{
1499 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1500 struct brcmf_if *ifp = netdev_priv(ndev); 1495 struct brcmf_if *ifp = netdev_priv(ndev);
1501 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 1496 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1502 struct brcmf_scb_val_le scbval; 1497 struct brcmf_scb_val_le scbval;
@@ -1515,8 +1510,6 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1515 if (err) 1510 if (err)
1516 WL_ERR("error (%d)\n", err); 1511 WL_ERR("error (%d)\n", err);
1517 1512
1518 cfg->link_up = false;
1519
1520 WL_TRACE("Exit\n"); 1513 WL_TRACE("Exit\n");
1521 return err; 1514 return err;
1522} 1515}
@@ -1716,7 +1709,6 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1716 u8 key_idx, bool pairwise, const u8 *mac_addr, 1709 u8 key_idx, bool pairwise, const u8 *mac_addr,
1717 struct key_params *params) 1710 struct key_params *params)
1718{ 1711{
1719 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1720 struct brcmf_if *ifp = netdev_priv(ndev); 1712 struct brcmf_if *ifp = netdev_priv(ndev);
1721 struct brcmf_wsec_key key; 1713 struct brcmf_wsec_key key;
1722 s32 val; 1714 s32 val;
@@ -1758,7 +1750,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1758 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); 1750 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1759 break; 1751 break;
1760 case WLAN_CIPHER_SUITE_TKIP: 1752 case WLAN_CIPHER_SUITE_TKIP:
1761 if (cfg->conf->mode != WL_MODE_AP) { 1753 if (ifp->vif->mode != WL_MODE_AP) {
1762 WL_CONN("Swapping key\n"); 1754 WL_CONN("Swapping key\n");
1763 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 1755 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1764 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 1756 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
@@ -1908,7 +1900,6 @@ static s32
1908brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 1900brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1909 u8 *mac, struct station_info *sinfo) 1901 u8 *mac, struct station_info *sinfo)
1910{ 1902{
1911 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1912 struct brcmf_if *ifp = netdev_priv(ndev); 1903 struct brcmf_if *ifp = netdev_priv(ndev);
1913 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 1904 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1914 struct brcmf_scb_val_le scb_val; 1905 struct brcmf_scb_val_le scb_val;
@@ -1922,7 +1913,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1922 if (!check_vif_up(ifp->vif)) 1913 if (!check_vif_up(ifp->vif))
1923 return -EIO; 1914 return -EIO;
1924 1915
1925 if (cfg->conf->mode == WL_MODE_AP) { 1916 if (ifp->vif->mode == WL_MODE_AP) {
1926 memcpy(&sta_info_le, mac, ETH_ALEN); 1917 memcpy(&sta_info_le, mac, ETH_ALEN);
1927 err = brcmf_fil_iovar_data_get(ifp, "sta_info", 1918 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1928 &sta_info_le, 1919 &sta_info_le,
@@ -1939,7 +1930,7 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1939 } 1930 }
1940 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n", 1931 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
1941 sinfo->inactive_time, sinfo->connected_time); 1932 sinfo->inactive_time, sinfo->connected_time);
1942 } else if (cfg->conf->mode == WL_MODE_BSS) { 1933 } else if (ifp->vif->mode == WL_MODE_BSS) {
1943 if (memcmp(mac, bssid, ETH_ALEN)) { 1934 if (memcmp(mac, bssid, ETH_ALEN)) {
1944 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", 1935 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1945 mac, bssid); 1936 mac, bssid);
@@ -2249,9 +2240,9 @@ CleanUp:
2249 return err; 2240 return err;
2250} 2241}
2251 2242
2252static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg) 2243static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2253{ 2244{
2254 return cfg->conf->mode == WL_MODE_IBSS; 2245 return vif->mode == WL_MODE_IBSS;
2255} 2246}
2256 2247
2257/* 2248/*
@@ -2336,7 +2327,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2336 s32 err = 0; 2327 s32 err = 0;
2337 2328
2338 WL_TRACE("Enter\n"); 2329 WL_TRACE("Enter\n");
2339 if (brcmf_is_ibssmode(cfg)) 2330 if (brcmf_is_ibssmode(ifp->vif))
2340 return err; 2331 return err;
2341 2332
2342 ssid = &profile->ssid; 2333 ssid = &profile->ssid;
@@ -2596,17 +2587,13 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2596 * While going to suspend if associated with AP disassociate 2587 * While going to suspend if associated with AP disassociate
2597 * from AP to save power while system is in suspended state 2588 * from AP to save power while system is in suspended state
2598 */ 2589 */
2599 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state) || 2590 brcmf_link_down(vif);
2600 test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { 2591
2601 WL_INFO("Disassociating from AP before suspend\n"); 2592 /* Make sure WPA_Supplicant receives all the event
2602 brcmf_link_down(cfg); 2593 * generated due to DISASSOC call to the fw to keep
2603 2594 * the state fw and WPA_Supplicant state consistent
2604 /* Make sure WPA_Supplicant receives all the event 2595 */
2605 * generated due to DISASSOC call to the fw to keep 2596 brcmf_delay(500);
2606 * the state fw and WPA_Supplicant state consistent
2607 */
2608 brcmf_delay(500);
2609 }
2610 } 2597 }
2611 2598
2612 /* end any scanning */ 2599 /* end any scanning */
@@ -3306,11 +3293,12 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3306 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) 3293 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3307 break; 3294 break;
3308next: 3295next:
3309 remaining_len -= ie->len; 3296 remaining_len -= (ie->len + TLV_HDR_LEN);
3310 if (remaining_len <= 2) 3297 if (remaining_len <= TLV_HDR_LEN)
3311 ie = NULL; 3298 ie = NULL;
3312 else 3299 else
3313 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len); 3300 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3301 TLV_HDR_LEN);
3314 } 3302 }
3315 return err; 3303 return err;
3316} 3304}
@@ -3409,11 +3397,11 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3409 } 3397 }
3410 } 3398 }
3411 3399
3412 if (mgmt_ie_buf != NULL) { 3400 if (mgmt_ie_buf && *mgmt_ie_len) {
3413 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) && 3401 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3414 (memcmp(mgmt_ie_buf, curr_ie_buf, 3402 (memcmp(mgmt_ie_buf, curr_ie_buf,
3415 parsed_ie_buf_len) == 0)) { 3403 parsed_ie_buf_len) == 0)) {
3416 WL_TRACE("Previous mgmt IE is equals to current IE"); 3404 WL_TRACE("Previous mgmt IE equals to current IE\n");
3417 goto exit; 3405 goto exit;
3418 } 3406 }
3419 3407
@@ -3451,6 +3439,16 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3451 for (i = 0; i < new_vndr_ies.count; i++) { 3439 for (i = 0; i < new_vndr_ies.count; i++) {
3452 vndrie_info = &new_vndr_ies.ie_info[i]; 3440 vndrie_info = &new_vndr_ies.ie_info[i];
3453 3441
3442 /* verify remained buf size before copy data */
3443 if (remained_buf_len < (vndrie_info->vndrie.len +
3444 VNDR_IE_VSIE_OFFSET)) {
3445 WL_ERR("no space in mgmt_ie_buf: len left %d",
3446 remained_buf_len);
3447 break;
3448 }
3449 remained_buf_len -= (vndrie_info->ie_len +
3450 VNDR_IE_VSIE_OFFSET);
3451
3454 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", 3452 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3455 vndrie_info->vndrie.id, 3453 vndrie_info->vndrie.id,
3456 vndrie_info->vndrie.len, 3454 vndrie_info->vndrie.len,
@@ -3462,13 +3460,6 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3462 vndrie_info->ie_ptr, 3460 vndrie_info->ie_ptr,
3463 vndrie_info->ie_len, 3461 vndrie_info->ie_len,
3464 "add"); 3462 "add");
3465 /* verify remained buf size before copy data */
3466 remained_buf_len -= vndrie_info->ie_len;
3467 if (remained_buf_len < 0) {
3468 WL_ERR("no space in mgmt_ie_buf: len left %d",
3469 remained_buf_len);
3470 break;
3471 }
3472 3463
3473 /* save the parsed IE in wl struct */ 3464 /* save the parsed IE in wl struct */
3474 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr, 3465 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
@@ -3643,22 +3634,20 @@ exit:
3643static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) 3634static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3644{ 3635{
3645 struct brcmf_if *ifp = netdev_priv(ndev); 3636 struct brcmf_if *ifp = netdev_priv(ndev);
3646 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3647 s32 err = -EPERM; 3637 s32 err = -EPERM;
3648 3638
3649 WL_TRACE("Enter\n"); 3639 WL_TRACE("Enter\n");
3650 3640
3651 if (cfg->conf->mode == WL_MODE_AP) { 3641 if (ifp->vif->mode == WL_MODE_AP) {
3652 /* Due to most likely deauths outstanding we sleep */ 3642 /* Due to most likely deauths outstanding we sleep */
3653 /* first to make sure they get processed by fw. */ 3643 /* first to make sure they get processed by fw. */
3654 msleep(400); 3644 msleep(400);
3655 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), 3645 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3656 BRCMF_C_SET_AP, 0);
3657 if (err < 0) { 3646 if (err < 0) {
3658 WL_ERR("setting AP mode failed %d\n", err); 3647 WL_ERR("setting AP mode failed %d\n", err);
3659 goto exit; 3648 goto exit;
3660 } 3649 }
3661 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_UP, 0); 3650 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3662 if (err < 0) { 3651 if (err < 0) {
3663 WL_ERR("BRCMF_C_UP error %d\n", err); 3652 WL_ERR("BRCMF_C_UP error %d\n", err);
3664 goto exit; 3653 goto exit;
@@ -3849,23 +3838,20 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3849 } 3838 }
3850} 3839}
3851 3840
3852static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, 3841static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3853 const struct brcmf_event_msg *e)
3854{ 3842{
3855 u32 event = e->event_code; 3843 u32 event = e->event_code;
3856 u32 status = e->status; 3844 u32 status = e->status;
3857 3845
3858 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { 3846 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3859 WL_CONN("Processing set ssid\n"); 3847 WL_CONN("Processing set ssid\n");
3860 cfg->link_up = true;
3861 return true; 3848 return true;
3862 } 3849 }
3863 3850
3864 return false; 3851 return false;
3865} 3852}
3866 3853
3867static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, 3854static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3868 const struct brcmf_event_msg *e)
3869{ 3855{
3870 u32 event = e->event_code; 3856 u32 event = e->event_code;
3871 u16 flags = e->flags; 3857 u16 flags = e->flags;
@@ -4115,11 +4101,11 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4115 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4101 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4116 s32 err = 0; 4102 s32 err = 0;
4117 4103
4118 if (cfg->conf->mode == WL_MODE_AP) { 4104 if (ifp->vif->mode == WL_MODE_AP) {
4119 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4105 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4120 } else if (brcmf_is_linkup(cfg, e)) { 4106 } else if (brcmf_is_linkup(e)) {
4121 WL_CONN("Linkup\n"); 4107 WL_CONN("Linkup\n");
4122 if (brcmf_is_ibssmode(cfg)) { 4108 if (brcmf_is_ibssmode(ifp->vif)) {
4123 memcpy(profile->bssid, e->addr, ETH_ALEN); 4109 memcpy(profile->bssid, e->addr, ETH_ALEN);
4124 wl_inform_ibss(cfg, ndev, e->addr); 4110 wl_inform_ibss(cfg, ndev, e->addr);
4125 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); 4111 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
@@ -4129,26 +4115,19 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4129 &ifp->vif->sme_state); 4115 &ifp->vif->sme_state);
4130 } else 4116 } else
4131 brcmf_bss_connect_done(cfg, ndev, e, true); 4117 brcmf_bss_connect_done(cfg, ndev, e, true);
4132 } else if (brcmf_is_linkdown(cfg, e)) { 4118 } else if (brcmf_is_linkdown(e)) {
4133 WL_CONN("Linkdown\n"); 4119 WL_CONN("Linkdown\n");
4134 if (brcmf_is_ibssmode(cfg)) { 4120 if (!brcmf_is_ibssmode(ifp->vif)) {
4135 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4136 &ifp->vif->sme_state);
4137 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4138 &ifp->vif->sme_state))
4139 brcmf_link_down(cfg);
4140 } else {
4141 brcmf_bss_connect_done(cfg, ndev, e, false); 4121 brcmf_bss_connect_done(cfg, ndev, e, false);
4142 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, 4122 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4143 &ifp->vif->sme_state)) { 4123 &ifp->vif->sme_state))
4144 cfg80211_disconnected(ndev, 0, NULL, 0, 4124 cfg80211_disconnected(ndev, 0, NULL, 0,
4145 GFP_KERNEL); 4125 GFP_KERNEL);
4146 brcmf_link_down(cfg);
4147 }
4148 } 4126 }
4127 brcmf_link_down(ifp->vif);
4149 brcmf_init_prof(ndev_to_prof(ndev)); 4128 brcmf_init_prof(ndev_to_prof(ndev));
4150 } else if (brcmf_is_nonetwork(cfg, e)) { 4129 } else if (brcmf_is_nonetwork(cfg, e)) {
4151 if (brcmf_is_ibssmode(cfg)) 4130 if (brcmf_is_ibssmode(ifp->vif))
4152 clear_bit(BRCMF_VIF_STATUS_CONNECTING, 4131 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4153 &ifp->vif->sme_state); 4132 &ifp->vif->sme_state);
4154 else 4133 else
@@ -4197,7 +4176,6 @@ brcmf_notify_mic_status(struct brcmf_if *ifp,
4197 4176
4198static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) 4177static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4199{ 4178{
4200 conf->mode = (u32)-1;
4201 conf->frag_threshold = (u32)-1; 4179 conf->frag_threshold = (u32)-1;
4202 conf->rts_threshold = (u32)-1; 4180 conf->rts_threshold = (u32)-1;
4203 conf->retry_short = (u32)-1; 4181 conf->retry_short = (u32)-1;
@@ -4282,7 +4260,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4282 mutex_init(&cfg->usr_sync); 4260 mutex_init(&cfg->usr_sync);
4283 brcmf_init_escan(cfg); 4261 brcmf_init_escan(cfg);
4284 brcmf_init_conf(cfg->conf); 4262 brcmf_init_conf(cfg->conf);
4285 brcmf_link_down(cfg);
4286 4263
4287 return err; 4264 return err;
4288} 4265}
@@ -4290,7 +4267,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4290static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) 4267static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4291{ 4268{
4292 cfg->dongle_up = false; /* dongle down */ 4269 cfg->dongle_up = false; /* dongle down */
4293 brcmf_link_down(cfg);
4294 brcmf_abort_scanning(cfg); 4270 brcmf_abort_scanning(cfg);
4295 brcmf_deinit_priv_mem(cfg); 4271 brcmf_deinit_priv_mem(cfg);
4296} 4272}
@@ -4537,11 +4513,8 @@ static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4537 * While going down, if associated with AP disassociate 4513 * While going down, if associated with AP disassociate
4538 * from AP to save power 4514 * from AP to save power
4539 */ 4515 */
4540 if ((test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) || 4516 if (check_vif_up(ifp->vif)) {
4541 test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) && 4517 brcmf_link_down(ifp->vif);
4542 check_vif_up(ifp->vif)) {
4543 WL_INFO("Disassociating from AP");
4544 brcmf_link_down(cfg);
4545 4518
4546 /* Make sure WPA_Supplicant receives all the event 4519 /* Make sure WPA_Supplicant receives all the event
4547 generated due to DISASSOC call to the fw to keep 4520 generated due to DISASSOC call to the fw to keep
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index e2ef8519ea84..d60de187e7d9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -128,7 +128,6 @@ enum wl_mode {
128 128
129/* dongle configuration */ 129/* dongle configuration */
130struct brcmf_cfg80211_conf { 130struct brcmf_cfg80211_conf {
131 u32 mode; /* adhoc , infrastructure or ap */
132 u32 frag_threshold; 131 u32 frag_threshold;
133 u32 rts_threshold; 132 u32 rts_threshold;
134 u32 retry_short; 133 u32 retry_short;
@@ -359,7 +358,6 @@ struct brcmf_pno_scanresults_le {
359 * @active_scan: current scan mode. 358 * @active_scan: current scan mode.
360 * @sched_escan: e-scan for scheduled scan support running. 359 * @sched_escan: e-scan for scheduled scan support running.
361 * @ibss_starter: indicates this sta is ibss starter. 360 * @ibss_starter: indicates this sta is ibss starter.
362 * @link_up: link/connection up flag.
363 * @pwr_save: indicate whether dongle to support power save mode. 361 * @pwr_save: indicate whether dongle to support power save mode.
364 * @dongle_up: indicate whether dongle up or not. 362 * @dongle_up: indicate whether dongle up or not.
365 * @roam_on: on/off switch for dongle self-roaming. 363 * @roam_on: on/off switch for dongle self-roaming.
@@ -391,7 +389,6 @@ struct brcmf_cfg80211_info {
391 bool active_scan; 389 bool active_scan;
392 bool sched_escan; 390 bool sched_escan;
393 bool ibss_starter; 391 bool ibss_starter;
394 bool link_up;
395 bool pwr_save; 392 bool pwr_save;
396 bool dongle_up; 393 bool dongle_up;
397 bool roam_on; 394 bool roam_on;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
index 6ba4136c7cf6..9761deb46204 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c
@@ -1,8 +1,120 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 * Copyright (c) 2012 Canonical Ltd.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
14 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
15 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#include <linux/debugfs.h>
18#include <linux/if_ether.h>
19#include <linux/if.h>
1#include <linux/net.h> 20#include <linux/net.h>
21#include <linux/netdevice.h>
22#include <linux/ieee80211.h>
23#include <linux/module.h>
24#include <net/mac80211.h>
25
26#include <defs.h>
27#include <brcmu_wifi.h>
28#include <brcmu_utils.h>
2#include "types.h" 29#include "types.h"
30#include "main.h"
3#include "debug.h" 31#include "debug.h"
4#include "brcms_trace_events.h" 32#include "brcms_trace_events.h"
5 33
34static struct dentry *root_folder;
35
36void brcms_debugfs_init(void)
37{
38 root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
39 if (IS_ERR(root_folder))
40 root_folder = NULL;
41}
42
43void brcms_debugfs_exit(void)
44{
45 if (!root_folder)
46 return;
47
48 debugfs_remove_recursive(root_folder);
49 root_folder = NULL;
50}
51
52int brcms_debugfs_attach(struct brcms_pub *drvr)
53{
54 if (!root_folder)
55 return -ENODEV;
56
57 drvr->dbgfs_dir = debugfs_create_dir(
58 dev_name(&drvr->wlc->hw->d11core->dev), root_folder);
59 return PTR_RET(drvr->dbgfs_dir);
60}
61
62void brcms_debugfs_detach(struct brcms_pub *drvr)
63{
64 if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
65 debugfs_remove_recursive(drvr->dbgfs_dir);
66}
67
68struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr)
69{
70 return drvr->dbgfs_dir;
71}
72
73static
74ssize_t brcms_debugfs_hardware_read(struct file *f, char __user *data,
75 size_t count, loff_t *ppos)
76{
77 char buf[128];
78 int res;
79 struct brcms_pub *drvr = f->private_data;
80
81 /* only allow read from start */
82 if (*ppos > 0)
83 return 0;
84
85 res = scnprintf(buf, sizeof(buf),
86 "board vendor: %x\n"
87 "board type: %x\n"
88 "board revision: %x\n"
89 "board flags: %x\n"
90 "board flags2: %x\n"
91 "firmware revision: %x\n",
92 drvr->wlc->hw->d11core->bus->boardinfo.vendor,
93 drvr->wlc->hw->d11core->bus->boardinfo.type,
94 drvr->wlc->hw->boardrev,
95 drvr->wlc->hw->boardflags,
96 drvr->wlc->hw->boardflags2,
97 drvr->wlc->ucode_rev
98 );
99
100 return simple_read_from_buffer(data, count, ppos, buf, res);
101}
102
103static const struct file_operations brcms_debugfs_hardware_ops = {
104 .owner = THIS_MODULE,
105 .open = simple_open,
106 .read = brcms_debugfs_hardware_read
107};
108
109void brcms_debugfs_create_files(struct brcms_pub *drvr)
110{
111 struct dentry *dentry = drvr->dbgfs_dir;
112
113 if (!IS_ERR_OR_NULL(dentry))
114 debugfs_create_file("hardware", S_IRUGO, dentry,
115 drvr, &brcms_debugfs_hardware_ops);
116}
117
6#define __brcms_fn(fn) \ 118#define __brcms_fn(fn) \
7void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ 119void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \
8{ \ 120{ \
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
index f77066bda9d2..796836b0f469 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h
@@ -1,3 +1,18 @@
1/*
2 * Copyright (c) 2012 Broadcom Corporation
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
1#ifndef _BRCMS_DEBUG_H_ 16#ifndef _BRCMS_DEBUG_H_
2#define _BRCMS_DEBUG_H_ 17#define _BRCMS_DEBUG_H_
3 18
@@ -49,4 +64,12 @@ void __brcms_dbg(struct device *dev, u32 level, const char *func,
49#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) 64#define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a)
50#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) 65#define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a)
51 66
67struct brcms_pub;
68void brcms_debugfs_init(void);
69void brcms_debugfs_exit(void);
70int brcms_debugfs_attach(struct brcms_pub *drvr);
71void brcms_debugfs_detach(struct brcms_pub *drvr);
72struct dentry *brcms_debugfs_get_devdir(struct brcms_pub *drvr);
73void brcms_debugfs_create_files(struct brcms_pub *drvr);
74
52#endif /* _BRCMS_DEBUG_H_ */ 75#endif /* _BRCMS_DEBUG_H_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 511e45775c33..1860c572b3c4 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -349,10 +349,8 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags)
349{ 349{
350 uint dmactrlflags; 350 uint dmactrlflags;
351 351
352 if (di == NULL) { 352 if (di == NULL)
353 brcms_dbg_dma(di->core, "NULL dma handle\n");
354 return 0; 353 return 0;
355 }
356 354
357 dmactrlflags = di->dma.dmactrlflags; 355 dmactrlflags = di->dma.dmactrlflags;
358 dmactrlflags &= ~mask; 356 dmactrlflags &= ~mask;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 1710ccba8bac..02d27eacc0e2 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -285,8 +285,8 @@ static void brcms_ops_tx(struct ieee80211_hw *hw,
285 kfree_skb(skb); 285 kfree_skb(skb);
286 goto done; 286 goto done;
287 } 287 }
288 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); 288 if (brcms_c_sendpkt_mac80211(wl->wlc, skb, hw))
289 tx_info->rate_driver_data[0] = control->sta; 289 tx_info->rate_driver_data[0] = control->sta;
290 done: 290 done:
291 spin_unlock_bh(&wl->lock); 291 spin_unlock_bh(&wl->lock);
292} 292}
@@ -846,8 +846,10 @@ static void brcms_free(struct brcms_info *wl)
846 /* kill dpc */ 846 /* kill dpc */
847 tasklet_kill(&wl->tasklet); 847 tasklet_kill(&wl->tasklet);
848 848
849 if (wl->pub) 849 if (wl->pub) {
850 brcms_debugfs_detach(wl->pub);
850 brcms_c_module_unregister(wl->pub, "linux", wl); 851 brcms_c_module_unregister(wl->pub, "linux", wl);
852 }
851 853
852 /* free common resources */ 854 /* free common resources */
853 if (wl->wlc) { 855 if (wl->wlc) {
@@ -896,27 +898,22 @@ static void brcms_remove(struct bcma_device *pdev)
896static irqreturn_t brcms_isr(int irq, void *dev_id) 898static irqreturn_t brcms_isr(int irq, void *dev_id)
897{ 899{
898 struct brcms_info *wl; 900 struct brcms_info *wl;
899 bool ours, wantdpc; 901 irqreturn_t ret = IRQ_NONE;
900 902
901 wl = (struct brcms_info *) dev_id; 903 wl = (struct brcms_info *) dev_id;
902 904
903 spin_lock(&wl->isr_lock); 905 spin_lock(&wl->isr_lock);
904 906
905 /* call common first level interrupt handler */ 907 /* call common first level interrupt handler */
906 ours = brcms_c_isr(wl->wlc, &wantdpc); 908 if (brcms_c_isr(wl->wlc)) {
907 if (ours) { 909 /* schedule second level handler */
908 /* if more to do... */ 910 tasklet_schedule(&wl->tasklet);
909 if (wantdpc) { 911 ret = IRQ_HANDLED;
910
911 /* ...and call the second level interrupt handler */
912 /* schedule dpc */
913 tasklet_schedule(&wl->tasklet);
914 }
915 } 912 }
916 913
917 spin_unlock(&wl->isr_lock); 914 spin_unlock(&wl->isr_lock);
918 915
919 return IRQ_RETVAL(ours); 916 return ret;
920} 917}
921 918
922/* 919/*
@@ -1082,6 +1079,8 @@ static struct brcms_info *brcms_attach(struct bcma_device *pdev)
1082 regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) 1079 regulatory_hint(wl->wiphy, wl->pub->srom_ccode))
1083 wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); 1080 wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__);
1084 1081
1082 brcms_debugfs_attach(wl->pub);
1083 brcms_debugfs_create_files(wl->pub);
1085 n_adapters_found++; 1084 n_adapters_found++;
1086 return wl; 1085 return wl;
1087 1086
@@ -1100,7 +1099,7 @@ fail:
1100 * 1099 *
1101 * Perimeter lock is initialized in the course of this function. 1100 * Perimeter lock is initialized in the course of this function.
1102 */ 1101 */
1103static int __devinit brcms_bcma_probe(struct bcma_device *pdev) 1102static int brcms_bcma_probe(struct bcma_device *pdev)
1104{ 1103{
1105 struct brcms_info *wl; 1104 struct brcms_info *wl;
1106 struct ieee80211_hw *hw; 1105 struct ieee80211_hw *hw;
@@ -1166,7 +1165,7 @@ static struct bcma_driver brcms_bcma_driver = {
1166 .probe = brcms_bcma_probe, 1165 .probe = brcms_bcma_probe,
1167 .suspend = brcms_suspend, 1166 .suspend = brcms_suspend,
1168 .resume = brcms_resume, 1167 .resume = brcms_resume,
1169 .remove = __devexit_p(brcms_remove), 1168 .remove = brcms_remove,
1170 .id_table = brcms_coreid_table, 1169 .id_table = brcms_coreid_table,
1171}; 1170};
1172 1171
@@ -1190,6 +1189,7 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
1190 1189
1191static int __init brcms_module_init(void) 1190static int __init brcms_module_init(void)
1192{ 1191{
1192 brcms_debugfs_init();
1193 if (!schedule_work(&brcms_driver_work)) 1193 if (!schedule_work(&brcms_driver_work))
1194 return -EBUSY; 1194 return -EBUSY;
1195 1195
@@ -1207,6 +1207,7 @@ static void __exit brcms_module_exit(void)
1207{ 1207{
1208 cancel_work_sync(&brcms_driver_work); 1208 cancel_work_sync(&brcms_driver_work);
1209 bcma_driver_unregister(&brcms_bcma_driver); 1209 bcma_driver_unregister(&brcms_bcma_driver);
1210 brcms_debugfs_exit();
1210} 1211}
1211 1212
1212module_init(brcms_module_init); 1213module_init(brcms_module_init);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 2a44593f1e37..8fce68751e47 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -1044,11 +1044,17 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1044 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); 1044 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
1045 while (!(*fatal) 1045 while (!(*fatal)
1046 && (s1 & TXS_V)) { 1046 && (s1 & TXS_V)) {
1047 /* !give others some time to run! */
1048 if (n >= max_tx_num) {
1049 morepending = true;
1050 break;
1051 }
1047 1052
1048 if (s1 == 0xffffffff) { 1053 if (s1 == 0xffffffff) {
1049 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, 1054 brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
1050 __func__); 1055 __func__);
1051 return morepending; 1056 *fatal = true;
1057 return false;
1052 } 1058 }
1053 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); 1059 s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
1054 1060
@@ -1060,17 +1066,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
1060 1066
1061 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); 1067 *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
1062 1068
1063 /* !give others some time to run! */
1064 if (++n >= max_tx_num)
1065 break;
1066 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); 1069 s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
1070 n++;
1067 } 1071 }
1068 1072
1069 if (*fatal) 1073 if (*fatal)
1070 return 0; 1074 return false;
1071
1072 if (n >= max_tx_num)
1073 morepending = true;
1074 1075
1075 return morepending; 1076 return morepending;
1076} 1077}
@@ -2546,10 +2547,6 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr)
2546 if (macintstatus == 0) 2547 if (macintstatus == 0)
2547 return 0; 2548 return 0;
2548 2549
2549 /* interrupts are already turned off for CFE build
2550 * Caution: For CFE Turning off the interrupts again has some undesired
2551 * consequences
2552 */
2553 /* turn off the interrupts */ 2550 /* turn off the interrupts */
2554 bcma_write32(core, D11REGOFFS(macintmask), 0); 2551 bcma_write32(core, D11REGOFFS(macintmask), 0);
2555 (void)bcma_read32(core, D11REGOFFS(macintmask)); 2552 (void)bcma_read32(core, D11REGOFFS(macintmask));
@@ -2592,33 +2589,31 @@ bool brcms_c_intrsupd(struct brcms_c_info *wlc)
2592 2589
2593/* 2590/*
2594 * First-level interrupt processing. 2591 * First-level interrupt processing.
2595 * Return true if this was our interrupt, false otherwise. 2592 * Return true if this was our interrupt
2596 * *wantdpc will be set to true if further brcms_c_dpc() processing is required, 2593 * and if further brcms_c_dpc() processing is required,
2597 * false otherwise. 2594 * false otherwise.
2598 */ 2595 */
2599bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) 2596bool brcms_c_isr(struct brcms_c_info *wlc)
2600{ 2597{
2601 struct brcms_hardware *wlc_hw = wlc->hw; 2598 struct brcms_hardware *wlc_hw = wlc->hw;
2602 u32 macintstatus; 2599 u32 macintstatus;
2603 2600
2604 *wantdpc = false;
2605
2606 if (!wlc_hw->up || !wlc->macintmask) 2601 if (!wlc_hw->up || !wlc->macintmask)
2607 return false; 2602 return false;
2608 2603
2609 /* read and clear macintstatus and intstatus registers */ 2604 /* read and clear macintstatus and intstatus registers */
2610 macintstatus = wlc_intstatus(wlc, true); 2605 macintstatus = wlc_intstatus(wlc, true);
2611 2606
2612 if (macintstatus == 0xffffffff) 2607 if (macintstatus == 0xffffffff) {
2613 brcms_err(wlc_hw->d11core, 2608 brcms_err(wlc_hw->d11core,
2614 "DEVICEREMOVED detected in the ISR code path\n"); 2609 "DEVICEREMOVED detected in the ISR code path\n");
2610 return false;
2611 }
2615 2612
2616 /* it is not for us */ 2613 /* it is not for us */
2617 if (macintstatus == 0) 2614 if (macintstatus == 0)
2618 return false; 2615 return false;
2619 2616
2620 *wantdpc = true;
2621
2622 /* save interrupt status bits */ 2617 /* save interrupt status bits */
2623 wlc->macintstatus = macintstatus; 2618 wlc->macintstatus = macintstatus;
2624 2619
@@ -6928,17 +6923,20 @@ static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb)
6928 return ret; 6923 return ret;
6929} 6924}
6930 6925
6931void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, 6926bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu,
6932 struct ieee80211_hw *hw) 6927 struct ieee80211_hw *hw)
6933{ 6928{
6934 uint fifo; 6929 uint fifo;
6935 struct scb *scb = &wlc->pri_scb; 6930 struct scb *scb = &wlc->pri_scb;
6936 6931
6937 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); 6932 fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu));
6938 if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) 6933 brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0);
6939 return; 6934 if (!brcms_c_tx(wlc, sdu))
6940 if (brcms_c_tx(wlc, sdu)) 6935 return true;
6941 dev_kfree_skb_any(sdu); 6936
6937 /* packet discarded */
6938 dev_kfree_skb_any(sdu);
6939 return false;
6942} 6940}
6943 6941
6944int 6942int
@@ -7634,16 +7632,19 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
7634 7632
7635 uint n = 0; 7633 uint n = 0;
7636 uint bound_limit = bound ? RXBND : -1; 7634 uint bound_limit = bound ? RXBND : -1;
7635 bool morepending;
7637 7636
7638 skb_queue_head_init(&recv_frames); 7637 skb_queue_head_init(&recv_frames);
7639 7638
7640 /* gather received frames */ 7639 /* gather received frames */
7641 while (dma_rx(wlc_hw->di[fifo], &recv_frames)) { 7640 do {
7642
7643 /* !give others some time to run! */ 7641 /* !give others some time to run! */
7644 if (++n >= bound_limit) 7642 if (n >= bound_limit)
7645 break; 7643 break;
7646 } 7644
7645 morepending = dma_rx(wlc_hw->di[fifo], &recv_frames);
7646 n++;
7647 } while (morepending);
7647 7648
7648 /* post more rbufs */ 7649 /* post more rbufs */
7649 dma_rxfill(wlc_hw->di[fifo]); 7650 dma_rxfill(wlc_hw->di[fifo]);
@@ -7673,7 +7674,7 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound)
7673 brcms_c_recv(wlc_hw->wlc, p); 7674 brcms_c_recv(wlc_hw->wlc, p);
7674 } 7675 }
7675 7676
7676 return n >= bound_limit; 7677 return morepending;
7677} 7678}
7678 7679
7679/* second-level interrupt processing 7680/* second-level interrupt processing
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index abfd78822fb8..606b534347bc 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -1137,8 +1137,9 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
1137 gain0_15 = ((biq1 & 0xf) << 12) | 1137 gain0_15 = ((biq1 & 0xf) << 12) |
1138 ((tia & 0xf) << 8) | 1138 ((tia & 0xf) << 8) |
1139 ((lna2 & 0x3) << 6) | 1139 ((lna2 & 0x3) << 6) |
1140 ((lna2 & 1140 ((lna2 & 0x3) << 4) |
1141 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); 1141 ((lna1 & 0x3) << 2) |
1142 ((lna1 & 0x3) << 0);
1142 1143
1143 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); 1144 mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0);
1144 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); 1145 mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0);
@@ -1156,6 +1157,8 @@ wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi,
1156 } 1157 }
1157 1158
1158 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); 1159 mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0);
1160 mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11);
1161 mod_phy_reg(pi, 0x4e6, (0x3 << 3), lna1 << 3);
1159 1162
1160} 1163}
1161 1164
@@ -1328,6 +1331,43 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples)
1328 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; 1331 return (iq_est.i_pwr + iq_est.q_pwr) / nsamples;
1329} 1332}
1330 1333
1334static bool wlc_lcnphy_rx_iq_cal_gain(struct brcms_phy *pi, u16 biq1_gain,
1335 u16 tia_gain, u16 lna2_gain)
1336{
1337 u32 i_thresh_l, q_thresh_l;
1338 u32 i_thresh_h, q_thresh_h;
1339 struct lcnphy_iq_est iq_est_h, iq_est_l;
1340
1341 wlc_lcnphy_set_rx_gain_by_distribution(pi, 0, 0, 0, biq1_gain, tia_gain,
1342 lna2_gain, 0);
1343
1344 wlc_lcnphy_rx_gain_override_enable(pi, true);
1345 wlc_lcnphy_start_tx_tone(pi, 2000, (40 >> 1), 0);
1346 usleep_range(500, 500);
1347 write_radio_reg(pi, RADIO_2064_REG112, 0);
1348 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_l))
1349 return false;
1350
1351 wlc_lcnphy_start_tx_tone(pi, 2000, 40, 0);
1352 usleep_range(500, 500);
1353 write_radio_reg(pi, RADIO_2064_REG112, 0);
1354 if (!wlc_lcnphy_rx_iq_est(pi, 1024, 32, &iq_est_h))
1355 return false;
1356
1357 i_thresh_l = (iq_est_l.i_pwr << 1);
1358 i_thresh_h = (iq_est_l.i_pwr << 2) + iq_est_l.i_pwr;
1359
1360 q_thresh_l = (iq_est_l.q_pwr << 1);
1361 q_thresh_h = (iq_est_l.q_pwr << 2) + iq_est_l.q_pwr;
1362 if ((iq_est_h.i_pwr > i_thresh_l) &&
1363 (iq_est_h.i_pwr < i_thresh_h) &&
1364 (iq_est_h.q_pwr > q_thresh_l) &&
1365 (iq_est_h.q_pwr < q_thresh_h))
1366 return true;
1367
1368 return false;
1369}
1370
1331static bool 1371static bool
1332wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, 1372wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1333 const struct lcnphy_rx_iqcomp *iqcomp, 1373 const struct lcnphy_rx_iqcomp *iqcomp,
@@ -1342,8 +1382,8 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1342 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, 1382 RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old,
1343 rfoverride3_old, rfoverride3val_old, rfoverride4_old, 1383 rfoverride3_old, rfoverride3val_old, rfoverride4_old,
1344 rfoverride4val_old, afectrlovr_old, afectrlovrval_old; 1384 rfoverride4val_old, afectrlovr_old, afectrlovrval_old;
1345 int tia_gain; 1385 int tia_gain, lna2_gain, biq1_gain;
1346 u32 received_power, rx_pwr_threshold; 1386 bool set_gain;
1347 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; 1387 u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl;
1348 u16 values_to_save[11]; 1388 u16 values_to_save[11];
1349 s16 *ptr; 1389 s16 *ptr;
@@ -1368,126 +1408,134 @@ wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi,
1368 goto cal_done; 1408 goto cal_done;
1369 } 1409 }
1370 1410
1371 if (module == 1) { 1411 WARN_ON(module != 1);
1412 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
1413 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF);
1372 1414
1373 tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); 1415 for (i = 0; i < 11; i++)
1374 wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); 1416 values_to_save[i] =
1417 read_radio_reg(pi, rxiq_cal_rf_reg[i]);
1418 Core1TxControl_old = read_phy_reg(pi, 0x631);
1419
1420 or_phy_reg(pi, 0x631, 0x0015);
1421
1422 RFOverride0_old = read_phy_reg(pi, 0x44c);
1423 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
1424 rfoverride2_old = read_phy_reg(pi, 0x4b0);
1425 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
1426 rfoverride3_old = read_phy_reg(pi, 0x4f9);
1427 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
1428 rfoverride4_old = read_phy_reg(pi, 0x938);
1429 rfoverride4val_old = read_phy_reg(pi, 0x939);
1430 afectrlovr_old = read_phy_reg(pi, 0x43b);
1431 afectrlovrval_old = read_phy_reg(pi, 0x43c);
1432 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1433 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1375 1434
1376 for (i = 0; i < 11; i++) 1435 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1377 values_to_save[i] = 1436 if (tx_gain_override_old) {
1378 read_radio_reg(pi, rxiq_cal_rf_reg[i]); 1437 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1379 Core1TxControl_old = read_phy_reg(pi, 0x631); 1438 tx_gain_index_old = pi_lcn->lcnphy_current_index;
1380 1439 }
1381 or_phy_reg(pi, 0x631, 0x0015);
1382
1383 RFOverride0_old = read_phy_reg(pi, 0x44c);
1384 RFOverrideVal0_old = read_phy_reg(pi, 0x44d);
1385 rfoverride2_old = read_phy_reg(pi, 0x4b0);
1386 rfoverride2val_old = read_phy_reg(pi, 0x4b1);
1387 rfoverride3_old = read_phy_reg(pi, 0x4f9);
1388 rfoverride3val_old = read_phy_reg(pi, 0x4fa);
1389 rfoverride4_old = read_phy_reg(pi, 0x938);
1390 rfoverride4val_old = read_phy_reg(pi, 0x939);
1391 afectrlovr_old = read_phy_reg(pi, 0x43b);
1392 afectrlovrval_old = read_phy_reg(pi, 0x43c);
1393 old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da);
1394 old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db);
1395
1396 tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi);
1397 if (tx_gain_override_old) {
1398 wlc_lcnphy_get_tx_gain(pi, &old_gains);
1399 tx_gain_index_old = pi_lcn->lcnphy_current_index;
1400 }
1401 1440
1402 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); 1441 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx);
1403 1442
1404 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); 1443 mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0);
1405 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); 1444 mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0);
1406 1445
1407 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); 1446 mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1);
1408 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); 1447 mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1);
1409 1448
1410 write_radio_reg(pi, RADIO_2064_REG116, 0x06); 1449 write_radio_reg(pi, RADIO_2064_REG116, 0x06);
1411 write_radio_reg(pi, RADIO_2064_REG12C, 0x07); 1450 write_radio_reg(pi, RADIO_2064_REG12C, 0x07);
1412 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); 1451 write_radio_reg(pi, RADIO_2064_REG06A, 0xd3);
1413 write_radio_reg(pi, RADIO_2064_REG098, 0x03); 1452 write_radio_reg(pi, RADIO_2064_REG098, 0x03);
1414 write_radio_reg(pi, RADIO_2064_REG00B, 0x7); 1453 write_radio_reg(pi, RADIO_2064_REG00B, 0x7);
1415 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); 1454 mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4);
1416 write_radio_reg(pi, RADIO_2064_REG01D, 0x01); 1455 write_radio_reg(pi, RADIO_2064_REG01D, 0x01);
1417 write_radio_reg(pi, RADIO_2064_REG114, 0x01); 1456 write_radio_reg(pi, RADIO_2064_REG114, 0x01);
1418 write_radio_reg(pi, RADIO_2064_REG02E, 0x10); 1457 write_radio_reg(pi, RADIO_2064_REG02E, 0x10);
1419 write_radio_reg(pi, RADIO_2064_REG12A, 0x08); 1458 write_radio_reg(pi, RADIO_2064_REG12A, 0x08);
1420 1459
1421 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); 1460 mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0);
1422 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); 1461 mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0);
1423 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); 1462 mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1);
1424 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); 1463 mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1);
1425 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); 1464 mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2);
1426 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); 1465 mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2);
1427 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); 1466 mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3);
1428 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); 1467 mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3);
1429 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); 1468 mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5);
1430 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); 1469 mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5);
1431
1432 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
1433 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
1434
1435 wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0);
1436 write_phy_reg(pi, 0x6da, 0xffff);
1437 or_phy_reg(pi, 0x6db, 0x3);
1438 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
1439 wlc_lcnphy_rx_gain_override_enable(pi, true);
1440
1441 tia_gain = 8;
1442 rx_pwr_threshold = 950;
1443 while (tia_gain > 0) {
1444 tia_gain -= 1;
1445 wlc_lcnphy_set_rx_gain_by_distribution(pi,
1446 0, 0, 2, 2,
1447 (u16)
1448 tia_gain, 1, 0);
1449 udelay(500);
1450 1470
1451 received_power = 1471 mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0);
1452 wlc_lcnphy_measure_digital_power(pi, 2000); 1472 mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0);
1453 if (received_power < rx_pwr_threshold) 1473
1454 break; 1474 write_phy_reg(pi, 0x6da, 0xffff);
1475 or_phy_reg(pi, 0x6db, 0x3);
1476
1477 wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch);
1478 set_gain = false;
1479
1480 lna2_gain = 3;
1481 while ((lna2_gain >= 0) && !set_gain) {
1482 tia_gain = 4;
1483
1484 while ((tia_gain >= 0) && !set_gain) {
1485 biq1_gain = 6;
1486
1487 while ((biq1_gain >= 0) && !set_gain) {
1488 set_gain = wlc_lcnphy_rx_iq_cal_gain(pi,
1489 (u16)
1490 biq1_gain,
1491 (u16)
1492 tia_gain,
1493 (u16)
1494 lna2_gain);
1495 biq1_gain -= 1;
1496 }
1497 tia_gain -= 1;
1455 } 1498 }
1456 result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); 1499 lna2_gain -= 1;
1500 }
1457 1501
1458 wlc_lcnphy_stop_tx_tone(pi); 1502 if (set_gain)
1503 result = wlc_lcnphy_calc_rx_iq_comp(pi, 1024);
1504 else
1505 result = false;
1459 1506
1460 write_phy_reg(pi, 0x631, Core1TxControl_old); 1507 wlc_lcnphy_stop_tx_tone(pi);
1461 1508
1462 write_phy_reg(pi, 0x44c, RFOverrideVal0_old); 1509 write_phy_reg(pi, 0x631, Core1TxControl_old);
1463 write_phy_reg(pi, 0x44d, RFOverrideVal0_old); 1510
1464 write_phy_reg(pi, 0x4b0, rfoverride2_old); 1511 write_phy_reg(pi, 0x44c, RFOverrideVal0_old);
1465 write_phy_reg(pi, 0x4b1, rfoverride2val_old); 1512 write_phy_reg(pi, 0x44d, RFOverrideVal0_old);
1466 write_phy_reg(pi, 0x4f9, rfoverride3_old); 1513 write_phy_reg(pi, 0x4b0, rfoverride2_old);
1467 write_phy_reg(pi, 0x4fa, rfoverride3val_old); 1514 write_phy_reg(pi, 0x4b1, rfoverride2val_old);
1468 write_phy_reg(pi, 0x938, rfoverride4_old); 1515 write_phy_reg(pi, 0x4f9, rfoverride3_old);
1469 write_phy_reg(pi, 0x939, rfoverride4val_old); 1516 write_phy_reg(pi, 0x4fa, rfoverride3val_old);
1470 write_phy_reg(pi, 0x43b, afectrlovr_old); 1517 write_phy_reg(pi, 0x938, rfoverride4_old);
1471 write_phy_reg(pi, 0x43c, afectrlovrval_old); 1518 write_phy_reg(pi, 0x939, rfoverride4val_old);
1472 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); 1519 write_phy_reg(pi, 0x43b, afectrlovr_old);
1473 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); 1520 write_phy_reg(pi, 0x43c, afectrlovrval_old);
1521 write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl);
1522 write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl);
1474 1523
1475 wlc_lcnphy_clear_trsw_override(pi); 1524 wlc_lcnphy_clear_trsw_override(pi);
1476 1525
1477 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); 1526 mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2);
1478 1527
1479 for (i = 0; i < 11; i++) 1528 for (i = 0; i < 11; i++)
1480 write_radio_reg(pi, rxiq_cal_rf_reg[i], 1529 write_radio_reg(pi, rxiq_cal_rf_reg[i],
1481 values_to_save[i]); 1530 values_to_save[i]);
1482 1531
1483 if (tx_gain_override_old) 1532 if (tx_gain_override_old)
1484 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); 1533 wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old);
1485 else 1534 else
1486 wlc_lcnphy_disable_tx_gain_override(pi); 1535 wlc_lcnphy_disable_tx_gain_override(pi);
1487 1536
1488 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); 1537 wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl);
1489 wlc_lcnphy_rx_gain_override_enable(pi, false); 1538 wlc_lcnphy_rx_gain_override_enable(pi, false);
1490 }
1491 1539
1492cal_done: 1540cal_done:
1493 kfree(ptr); 1541 kfree(ptr);
@@ -1781,6 +1829,17 @@ wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel)
1781 write_radio_reg(pi, RADIO_2064_REG038, 3); 1829 write_radio_reg(pi, RADIO_2064_REG038, 3);
1782 write_radio_reg(pi, RADIO_2064_REG091, 7); 1830 write_radio_reg(pi, RADIO_2064_REG091, 7);
1783 } 1831 }
1832
1833 if (!(pi->sh->boardflags & BFL_FEM)) {
1834 u8 reg038[14] = {0xd, 0xe, 0xd, 0xd, 0xd, 0xc,
1835 0xa, 0xb, 0xb, 0x3, 0x3, 0x2, 0x0, 0x0};
1836
1837 write_radio_reg(pi, RADIO_2064_REG02A, 0xf);
1838 write_radio_reg(pi, RADIO_2064_REG091, 0x3);
1839 write_radio_reg(pi, RADIO_2064_REG038, 0x3);
1840
1841 write_radio_reg(pi, RADIO_2064_REG038, reg038[channel - 1]);
1842 }
1784} 1843}
1785 1844
1786static int 1845static int
@@ -1860,41 +1919,6 @@ wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type)
1860 return (filt_index != -1) ? 0 : -1; 1919 return (filt_index != -1) ? 0 : -1;
1861} 1920}
1862 1921
1863void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
1864{
1865 u8 channel = CHSPEC_CHANNEL(chanspec);
1866
1867 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec);
1868
1869 wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
1870
1871 or_phy_reg(pi, 0x44a, 0x44);
1872 write_phy_reg(pi, 0x44a, 0x80);
1873
1874 wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
1875 udelay(1000);
1876
1877 wlc_lcnphy_toggle_afe_pwdn(pi);
1878
1879 write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
1880 write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
1881
1882 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
1883 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
1884
1885 wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
1886 } else {
1887 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
1888
1889 wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
1890 }
1891
1892 wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
1893
1894 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
1895
1896}
1897
1898static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi) 1922static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi)
1899{ 1923{
1900 u16 pa_gain; 1924 u16 pa_gain;
@@ -1936,6 +1960,21 @@ static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi,
1936 wlc_lcnphy_enable_tx_gain_override(pi); 1960 wlc_lcnphy_enable_tx_gain_override(pi);
1937} 1961}
1938 1962
1963static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
1964{
1965 u16 m0m1;
1966 struct phytbl_info tab;
1967
1968 tab.tbl_ptr = &m0m1;
1969 tab.tbl_len = 1;
1970 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
1971 tab.tbl_offset = 87;
1972 tab.tbl_width = 16;
1973 wlc_lcnphy_read_table(pi, &tab);
1974
1975 return (u8) ((m0m1 & 0xff00) >> 8);
1976}
1977
1939static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0) 1978static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0)
1940{ 1979{
1941 u16 m0m1 = (u16) m0 << 8; 1980 u16 m0m1 = (u16) m0 << 8;
@@ -1995,6 +2034,16 @@ wlc_lcnphy_set_tssi_mux(struct brcms_phy *pi, enum lcnphy_tssi_mode pos)
1995 } else { 2034 } else {
1996 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1); 2035 mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0x1);
1997 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8); 2036 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
2037 mod_radio_reg(pi, RADIO_2064_REG028, 0x1, 0x0);
2038 mod_radio_reg(pi, RADIO_2064_REG11A, 0x4, 1<<2);
2039 mod_radio_reg(pi, RADIO_2064_REG036, 0x10, 0x0);
2040 mod_radio_reg(pi, RADIO_2064_REG11A, 0x10, 1<<4);
2041 mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
2042 mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x77);
2043 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0xe<<1);
2044 mod_radio_reg(pi, RADIO_2064_REG112, 0x80, 1<<7);
2045 mod_radio_reg(pi, RADIO_2064_REG005, 0x7, 1<<1);
2046 mod_radio_reg(pi, RADIO_2064_REG029, 0xf0, 0<<4);
1998 } 2047 }
1999 } else { 2048 } else {
2000 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2); 2049 mod_phy_reg(pi, 0x4d9, (0x1 << 2), (0x1) << 2);
@@ -2081,12 +2130,14 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi)
2081 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12)); 2130 (auxpga_vmid_temp << 0) | (auxpga_gain_temp << 12));
2082 2131
2083 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5)); 2132 mod_radio_reg(pi, RADIO_2064_REG082, (1 << 5), (1 << 5));
2133 mod_radio_reg(pi, RADIO_2064_REG07C, (1 << 0), (1 << 0));
2084} 2134}
2085 2135
2086static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) 2136static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2087{ 2137{
2088 struct phytbl_info tab; 2138 struct phytbl_info tab;
2089 u32 rfseq, ind; 2139 u32 rfseq, ind;
2140 u8 tssi_sel;
2090 2141
2091 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; 2142 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
2092 tab.tbl_width = 32; 2143 tab.tbl_width = 32;
@@ -2108,7 +2159,13 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2108 2159
2109 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4); 2160 mod_phy_reg(pi, 0x503, (0x1 << 4), (1) << 4);
2110 2161
2111 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT); 2162 if (pi->sh->boardflags & BFL_FEM) {
2163 tssi_sel = 0x1;
2164 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_EXT);
2165 } else {
2166 tssi_sel = 0xe;
2167 wlc_lcnphy_set_tssi_mux(pi, LCNPHY_TSSI_POST_PA);
2168 }
2112 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14); 2169 mod_phy_reg(pi, 0x4a4, (0x1 << 14), (0) << 14);
2113 2170
2114 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15); 2171 mod_phy_reg(pi, 0x4a4, (0x1 << 15), (1) << 15);
@@ -2144,9 +2201,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2144 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0); 2201 mod_phy_reg(pi, 0x49a, (0x1ff << 0), (0xff) << 0);
2145 2202
2146 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { 2203 if (LCNREV_IS(pi->pubpi.phy_rev, 2)) {
2147 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, 0xe); 2204 mod_radio_reg(pi, RADIO_2064_REG028, 0xf, tssi_sel);
2148 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4); 2205 mod_radio_reg(pi, RADIO_2064_REG086, 0x4, 0x4);
2149 } else { 2206 } else {
2207 mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, tssi_sel << 1);
2150 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1); 2208 mod_radio_reg(pi, RADIO_2064_REG03A, 0x1, 1);
2151 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3); 2209 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 1 << 3);
2152 } 2210 }
@@ -2193,6 +2251,10 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi)
2193 2251
2194 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8); 2252 mod_phy_reg(pi, 0x4d7, (0xf << 8), (0) << 8);
2195 2253
2254 mod_radio_reg(pi, RADIO_2064_REG035, 0xff, 0x0);
2255 mod_radio_reg(pi, RADIO_2064_REG036, 0x3, 0x0);
2256 mod_radio_reg(pi, RADIO_2064_REG11A, 0x8, 0x8);
2257
2196 wlc_lcnphy_pwrctrl_rssiparams(pi); 2258 wlc_lcnphy_pwrctrl_rssiparams(pi);
2197} 2259}
2198 2260
@@ -2811,6 +2873,8 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2811 read_radio_reg(pi, RADIO_2064_REG007) & 1; 2873 read_radio_reg(pi, RADIO_2064_REG007) & 1;
2812 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; 2874 u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10;
2813 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; 2875 u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4;
2876 u8 SAVE_bbmult = wlc_lcnphy_get_bbmult(pi);
2877
2814 idleTssi = read_phy_reg(pi, 0x4ab); 2878 idleTssi = read_phy_reg(pi, 0x4ab);
2815 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & 2879 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
2816 MCTL_EN_MAC)); 2880 MCTL_EN_MAC));
@@ -2828,6 +2892,12 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2828 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4); 2892 mod_radio_reg(pi, RADIO_2064_REG0FF, 0x10, 1 << 4);
2829 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2); 2893 mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 1 << 2);
2830 wlc_lcnphy_tssi_setup(pi); 2894 wlc_lcnphy_tssi_setup(pi);
2895
2896 mod_phy_reg(pi, 0x4d7, (0x1 << 0), (1 << 0));
2897 mod_phy_reg(pi, 0x4d7, (0x1 << 6), (1 << 6));
2898
2899 wlc_lcnphy_set_bbmult(pi, 0x0);
2900
2831 wlc_phy_do_dummy_tx(pi, true, OFF); 2901 wlc_phy_do_dummy_tx(pi, true, OFF);
2832 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) 2902 idleTssi = ((read_phy_reg(pi, 0x4ab) & (0x1ff << 0))
2833 >> 0); 2903 >> 0);
@@ -2849,6 +2919,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2849 2919
2850 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12); 2920 mod_phy_reg(pi, 0x44c, (0x1 << 12), (0) << 12);
2851 2921
2922 wlc_lcnphy_set_bbmult(pi, SAVE_bbmult);
2852 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old); 2923 wlc_lcnphy_set_tx_gain_override(pi, tx_gain_override_old);
2853 wlc_lcnphy_set_tx_gain(pi, &old_gains); 2924 wlc_lcnphy_set_tx_gain(pi, &old_gains);
2854 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl); 2925 wlc_lcnphy_set_tx_pwr_ctrl(pi, SAVE_txpwrctrl);
@@ -3062,6 +3133,11 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
3062 wlc_lcnphy_write_table(pi, &tab); 3133 wlc_lcnphy_write_table(pi, &tab);
3063 tab.tbl_offset++; 3134 tab.tbl_offset++;
3064 } 3135 }
3136 mod_phy_reg(pi, 0x4d0, (0x1 << 0), (0) << 0);
3137 mod_phy_reg(pi, 0x4d3, (0xff << 0), (0) << 0);
3138 mod_phy_reg(pi, 0x4d3, (0xff << 8), (0) << 8);
3139 mod_phy_reg(pi, 0x4d0, (0x1 << 4), (0) << 4);
3140 mod_phy_reg(pi, 0x4d0, (0x1 << 2), (0) << 2);
3065 3141
3066 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7); 3142 mod_phy_reg(pi, 0x410, (0x1 << 7), (0) << 7);
3067 3143
@@ -3075,21 +3151,6 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
3075 wlapi_enable_mac(pi->sh->physhim); 3151 wlapi_enable_mac(pi->sh->physhim);
3076} 3152}
3077 3153
3078static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi)
3079{
3080 u16 m0m1;
3081 struct phytbl_info tab;
3082
3083 tab.tbl_ptr = &m0m1;
3084 tab.tbl_len = 1;
3085 tab.tbl_id = LCNPHY_TBL_ID_IQLOCAL;
3086 tab.tbl_offset = 87;
3087 tab.tbl_width = 16;
3088 wlc_lcnphy_read_table(pi, &tab);
3089
3090 return (u8) ((m0m1 & 0xff00) >> 8);
3091}
3092
3093static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain) 3154static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain)
3094{ 3155{
3095 mod_phy_reg(pi, 0x4fb, 3156 mod_phy_reg(pi, 0x4fb,
@@ -3878,7 +3939,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
3878 target_gains.pad_gain = 21; 3939 target_gains.pad_gain = 21;
3879 target_gains.dac_gain = 0; 3940 target_gains.dac_gain = 0;
3880 wlc_lcnphy_set_tx_gain(pi, &target_gains); 3941 wlc_lcnphy_set_tx_gain(pi, &target_gains);
3881 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3882 3942
3883 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) { 3943 if (LCNREV_IS(pi->pubpi.phy_rev, 1) || pi_lcn->lcnphy_hw_iqcal_en) {
3884 3944
@@ -3889,6 +3949,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi)
3889 lcnphy_recal ? LCNPHY_CAL_RECAL : 3949 lcnphy_recal ? LCNPHY_CAL_RECAL :
3890 LCNPHY_CAL_FULL), false); 3950 LCNPHY_CAL_FULL), false);
3891 } else { 3951 } else {
3952 wlc_lcnphy_set_tx_pwr_by_index(pi, 16);
3892 wlc_lcnphy_tx_iqlo_soft_cal_full(pi); 3953 wlc_lcnphy_tx_iqlo_soft_cal_full(pi);
3893 } 3954 }
3894 3955
@@ -4313,17 +4374,22 @@ wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi,
4313 if (CHSPEC_IS5G(pi->radio_chanspec)) 4374 if (CHSPEC_IS5G(pi->radio_chanspec))
4314 pa_gain = 0x70; 4375 pa_gain = 0x70;
4315 else 4376 else
4316 pa_gain = 0x70; 4377 pa_gain = 0x60;
4317 4378
4318 if (pi->sh->boardflags & BFL_FEM) 4379 if (pi->sh->boardflags & BFL_FEM)
4319 pa_gain = 0x10; 4380 pa_gain = 0x10;
4381
4320 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; 4382 tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL;
4321 tab.tbl_width = 32; 4383 tab.tbl_width = 32;
4322 tab.tbl_len = 1; 4384 tab.tbl_len = 1;
4323 tab.tbl_ptr = &val; 4385 tab.tbl_ptr = &val;
4324 4386
4325 for (j = 0; j < 128; j++) { 4387 for (j = 0; j < 128; j++) {
4326 gm_gain = gain_table[j].gm; 4388 if (pi->sh->boardflags & BFL_FEM)
4389 gm_gain = gain_table[j].gm;
4390 else
4391 gm_gain = 15;
4392
4327 val = (((u32) pa_gain << 24) | 4393 val = (((u32) pa_gain << 24) |
4328 (gain_table[j].pad << 16) | 4394 (gain_table[j].pad << 16) |
4329 (gain_table[j].pga << 8) | gm_gain); 4395 (gain_table[j].pga << 8) | gm_gain);
@@ -4534,7 +4600,10 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
4534 4600
4535 write_phy_reg(pi, 0x4ea, 0x4688); 4601 write_phy_reg(pi, 0x4ea, 0x4688);
4536 4602
4537 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); 4603 if (pi->sh->boardflags & BFL_FEM)
4604 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0);
4605 else
4606 mod_phy_reg(pi, 0x4eb, (0x7 << 0), 3 << 0);
4538 4607
4539 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); 4608 mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6);
4540 4609
@@ -4545,6 +4614,13 @@ static void wlc_radio_2064_init(struct brcms_phy *pi)
4545 wlc_lcnphy_rcal(pi); 4614 wlc_lcnphy_rcal(pi);
4546 4615
4547 wlc_lcnphy_rc_cal(pi); 4616 wlc_lcnphy_rc_cal(pi);
4617
4618 if (!(pi->sh->boardflags & BFL_FEM)) {
4619 write_radio_reg(pi, RADIO_2064_REG032, 0x6f);
4620 write_radio_reg(pi, RADIO_2064_REG033, 0x19);
4621 write_radio_reg(pi, RADIO_2064_REG039, 0xe);
4622 }
4623
4548} 4624}
4549 4625
4550static void wlc_lcnphy_radio_init(struct brcms_phy *pi) 4626static void wlc_lcnphy_radio_init(struct brcms_phy *pi)
@@ -4574,22 +4650,20 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi)
4574 wlc_lcnphy_write_table(pi, &tab); 4650 wlc_lcnphy_write_table(pi, &tab);
4575 } 4651 }
4576 4652
4577 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; 4653 if (!(pi->sh->boardflags & BFL_FEM)) {
4578 tab.tbl_width = 16; 4654 tab.tbl_id = LCNPHY_TBL_ID_RFSEQ;
4579 tab.tbl_ptr = &val; 4655 tab.tbl_width = 16;
4580 tab.tbl_len = 1; 4656 tab.tbl_ptr = &val;
4581 4657 tab.tbl_len = 1;
4582 val = 114;
4583 tab.tbl_offset = 0;
4584 wlc_lcnphy_write_table(pi, &tab);
4585 4658
4586 val = 130; 4659 val = 150;
4587 tab.tbl_offset = 1; 4660 tab.tbl_offset = 0;
4588 wlc_lcnphy_write_table(pi, &tab); 4661 wlc_lcnphy_write_table(pi, &tab);
4589 4662
4590 val = 6; 4663 val = 220;
4591 tab.tbl_offset = 8; 4664 tab.tbl_offset = 1;
4592 wlc_lcnphy_write_table(pi, &tab); 4665 wlc_lcnphy_write_table(pi, &tab);
4666 }
4593 4667
4594 if (CHSPEC_IS2G(pi->radio_chanspec)) { 4668 if (CHSPEC_IS2G(pi->radio_chanspec)) {
4595 if (pi->sh->boardflags & BFL_FEM) 4669 if (pi->sh->boardflags & BFL_FEM)
@@ -4946,6 +5020,44 @@ void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi)
4946 } 5020 }
4947} 5021}
4948 5022
5023void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec)
5024{
5025 u8 channel = CHSPEC_CHANNEL(chanspec);
5026
5027 wlc_phy_chanspec_radio_set((struct brcms_phy_pub *)pi, chanspec);
5028
5029 wlc_lcnphy_set_chanspec_tweaks(pi, pi->radio_chanspec);
5030
5031 or_phy_reg(pi, 0x44a, 0x44);
5032 write_phy_reg(pi, 0x44a, 0x80);
5033
5034 wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel);
5035 udelay(1000);
5036
5037 wlc_lcnphy_toggle_afe_pwdn(pi);
5038
5039 write_phy_reg(pi, 0x657, lcnphy_sfo_cfg[channel - 1].ptcentreTs20);
5040 write_phy_reg(pi, 0x658, lcnphy_sfo_cfg[channel - 1].ptcentreFactor);
5041
5042 if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) {
5043 mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8);
5044
5045 wlc_lcnphy_load_tx_iir_filter(pi, false, 3);
5046 } else {
5047 mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8);
5048
5049 wlc_lcnphy_load_tx_iir_filter(pi, false, 2);
5050 }
5051
5052 if (pi->sh->boardflags & BFL_FEM)
5053 wlc_lcnphy_load_tx_iir_filter(pi, true, 0);
5054 else
5055 wlc_lcnphy_load_tx_iir_filter(pi, true, 3);
5056
5057 mod_phy_reg(pi, 0x4eb, (0x7 << 3), (1) << 3);
5058 wlc_lcnphy_tssi_setup(pi);
5059}
5060
4949void wlc_phy_detach_lcnphy(struct brcms_phy *pi) 5061void wlc_phy_detach_lcnphy(struct brcms_phy *pi)
4950{ 5062{
4951 kfree(pi->u.pi_lcnphy); 5063 kfree(pi->u.pi_lcnphy);
@@ -4982,8 +5094,7 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi)
4982 if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) 5094 if (!wlc_phy_txpwr_srom_read_lcnphy(pi))
4983 return false; 5095 return false;
4984 5096
4985 if ((pi->sh->boardflags & BFL_FEM) && 5097 if (LCNREV_IS(pi->pubpi.phy_rev, 1)) {
4986 (LCNREV_IS(pi->pubpi.phy_rev, 1))) {
4987 if (pi_lcn->lcnphy_tempsense_option == 3) { 5098 if (pi_lcn->lcnphy_tempsense_option == 3) {
4988 pi->hwpwrctrl = true; 5099 pi->hwpwrctrl = true;
4989 pi->hwpwrctrl_capable = true; 5100 pi->hwpwrctrl_capable = true;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
index 622c01ca72c5..b7e95acc2084 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phytbl_lcn.c
@@ -1992,70 +1992,70 @@ static const u16 dot11lcn_sw_ctrl_tbl_4313_epa_rev0[] = {
1992}; 1992};
1993 1993
1994static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = { 1994static const u16 dot11lcn_sw_ctrl_tbl_4313_rev0[] = {
1995 0x000a,
1996 0x0009, 1995 0x0009,
1997 0x0006,
1998 0x0005,
1999 0x000a, 1996 0x000a,
2000 0x0009,
2001 0x0006,
2002 0x0005, 1997 0x0005,
2003 0x000a,
2004 0x0009,
2005 0x0006, 1998 0x0006,
2006 0x0005,
2007 0x000a,
2008 0x0009, 1999 0x0009,
2009 0x0006,
2010 0x0005,
2011 0x000a, 2000 0x000a,
2012 0x0009,
2013 0x0006,
2014 0x0005, 2001 0x0005,
2015 0x000a,
2016 0x0009,
2017 0x0006, 2002 0x0006,
2018 0x0005,
2019 0x000a,
2020 0x0009, 2003 0x0009,
2021 0x0006,
2022 0x0005,
2023 0x000a, 2004 0x000a,
2024 0x0009,
2025 0x0006,
2026 0x0005, 2005 0x0005,
2027 0x000a,
2028 0x0009,
2029 0x0006, 2006 0x0006,
2030 0x0005,
2031 0x000a,
2032 0x0009, 2007 0x0009,
2033 0x0006,
2034 0x0005,
2035 0x000a, 2008 0x000a,
2036 0x0009,
2037 0x0006,
2038 0x0005, 2009 0x0005,
2039 0x000a,
2040 0x0009,
2041 0x0006, 2010 0x0006,
2042 0x0005, 2011 0x0009,
2043 0x000a, 2012 0x000a,
2013 0x0005,
2014 0x0006,
2044 0x0009, 2015 0x0009,
2016 0x000a,
2017 0x0005,
2045 0x0006, 2018 0x0006,
2019 0x0009,
2020 0x000a,
2046 0x0005, 2021 0x0005,
2022 0x0006,
2023 0x0009,
2047 0x000a, 2024 0x000a,
2025 0x0005,
2026 0x0006,
2048 0x0009, 2027 0x0009,
2028 0x000a,
2029 0x0005,
2049 0x0006, 2030 0x0006,
2031 0x0009,
2032 0x000a,
2050 0x0005, 2033 0x0005,
2034 0x0006,
2035 0x0009,
2051 0x000a, 2036 0x000a,
2037 0x0005,
2038 0x0006,
2052 0x0009, 2039 0x0009,
2040 0x000a,
2041 0x0005,
2053 0x0006, 2042 0x0006,
2043 0x0009,
2044 0x000a,
2054 0x0005, 2045 0x0005,
2046 0x0006,
2047 0x0009,
2055 0x000a, 2048 0x000a,
2049 0x0005,
2050 0x0006,
2056 0x0009, 2051 0x0009,
2052 0x000a,
2053 0x0005,
2057 0x0006, 2054 0x0006,
2055 0x0009,
2056 0x000a,
2058 0x0005, 2057 0x0005,
2058 0x0006,
2059}; 2059};
2060 2060
2061static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = { 2061static const u16 dot11lcn_sw_ctrl_tbl_rev0[] = {
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 0148dec104f0..4fb2834f4e64 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -176,6 +176,7 @@ struct brcms_pub {
176 bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ 176 bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */
177 177
178 struct wl_cnt *_cnt; /* low-level counters in driver */ 178 struct wl_cnt *_cnt; /* low-level counters in driver */
179 struct dentry *dbgfs_dir;
179}; 180};
180 181
181enum wlc_par_id { 182enum wlc_par_id {
@@ -282,9 +283,9 @@ extern void brcms_c_intrson(struct brcms_c_info *wlc);
282extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc); 283extern u32 brcms_c_intrsoff(struct brcms_c_info *wlc);
283extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask); 284extern void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask);
284extern bool brcms_c_intrsupd(struct brcms_c_info *wlc); 285extern bool brcms_c_intrsupd(struct brcms_c_info *wlc);
285extern bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc); 286extern bool brcms_c_isr(struct brcms_c_info *wlc);
286extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded); 287extern bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded);
287extern void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, 288extern bool brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc,
288 struct sk_buff *sdu, 289 struct sk_buff *sdu,
289 struct ieee80211_hw *hw); 290 struct ieee80211_hw *hw);
290extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid); 291extern bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 46938bc9886d..d92b21a8e597 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -6410,7 +6410,7 @@ out:
6410 goto out; 6410 goto out;
6411} 6411}
6412 6412
6413static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev) 6413static void ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6414{ 6414{
6415 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev); 6415 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6416 struct net_device *dev = priv->net_dev; 6416 struct net_device *dev = priv->net_dev;
@@ -6606,7 +6606,7 @@ static struct pci_driver ipw2100_pci_driver = {
6606 .name = DRV_NAME, 6606 .name = DRV_NAME,
6607 .id_table = ipw2100_pci_id_table, 6607 .id_table = ipw2100_pci_id_table,
6608 .probe = ipw2100_pci_init_one, 6608 .probe = ipw2100_pci_init_one,
6609 .remove = __devexit_p(ipw2100_pci_remove_one), 6609 .remove = ipw2100_pci_remove_one,
6610#ifdef CONFIG_PM 6610#ifdef CONFIG_PM
6611 .suspend = ipw2100_suspend, 6611 .suspend = ipw2100_suspend,
6612 .resume = ipw2100_resume, 6612 .resume = ipw2100_resume,
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 482f505f3f35..844f201b7b70 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -6812,7 +6812,6 @@ static int ipw_wx_get_auth(struct net_device *dev,
6812 struct libipw_device *ieee = priv->ieee; 6812 struct libipw_device *ieee = priv->ieee;
6813 struct lib80211_crypt_data *crypt; 6813 struct lib80211_crypt_data *crypt;
6814 struct iw_param *param = &wrqu->param; 6814 struct iw_param *param = &wrqu->param;
6815 int ret = 0;
6816 6815
6817 switch (param->flags & IW_AUTH_INDEX) { 6816 switch (param->flags & IW_AUTH_INDEX) {
6818 case IW_AUTH_WPA_VERSION: 6817 case IW_AUTH_WPA_VERSION:
@@ -6822,8 +6821,7 @@ static int ipw_wx_get_auth(struct net_device *dev,
6822 /* 6821 /*
6823 * wpa_supplicant will control these internally 6822 * wpa_supplicant will control these internally
6824 */ 6823 */
6825 ret = -EOPNOTSUPP; 6824 return -EOPNOTSUPP;
6826 break;
6827 6825
6828 case IW_AUTH_TKIP_COUNTERMEASURES: 6826 case IW_AUTH_TKIP_COUNTERMEASURES:
6829 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx]; 6827 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];
@@ -10774,7 +10772,7 @@ static void ipw_bg_link_down(struct work_struct *work)
10774 mutex_unlock(&priv->mutex); 10772 mutex_unlock(&priv->mutex);
10775} 10773}
10776 10774
10777static int __devinit ipw_setup_deferred_work(struct ipw_priv *priv) 10775static int ipw_setup_deferred_work(struct ipw_priv *priv)
10778{ 10776{
10779 int ret = 0; 10777 int ret = 0;
10780 10778
@@ -11728,7 +11726,7 @@ static const struct net_device_ops ipw_netdev_ops = {
11728 .ndo_validate_addr = eth_validate_addr, 11726 .ndo_validate_addr = eth_validate_addr,
11729}; 11727};
11730 11728
11731static int __devinit ipw_pci_probe(struct pci_dev *pdev, 11729static int ipw_pci_probe(struct pci_dev *pdev,
11732 const struct pci_device_id *ent) 11730 const struct pci_device_id *ent)
11733{ 11731{
11734 int err = 0; 11732 int err = 0;
@@ -11901,7 +11899,7 @@ static int __devinit ipw_pci_probe(struct pci_dev *pdev,
11901 return err; 11899 return err;
11902} 11900}
11903 11901
11904static void __devexit ipw_pci_remove(struct pci_dev *pdev) 11902static void ipw_pci_remove(struct pci_dev *pdev)
11905{ 11903{
11906 struct ipw_priv *priv = pci_get_drvdata(pdev); 11904 struct ipw_priv *priv = pci_get_drvdata(pdev);
11907 struct list_head *p, *q; 11905 struct list_head *p, *q;
@@ -12063,7 +12061,7 @@ static struct pci_driver ipw_driver = {
12063 .name = DRV_NAME, 12061 .name = DRV_NAME,
12064 .id_table = card_ids, 12062 .id_table = card_ids,
12065 .probe = ipw_pci_probe, 12063 .probe = ipw_pci_probe,
12066 .remove = __devexit_p(ipw_pci_remove), 12064 .remove = ipw_pci_remove,
12067#ifdef CONFIG_PM 12065#ifdef CONFIG_PM
12068 .suspend = ipw_pci_suspend, 12066 .suspend = ipw_pci_suspend,
12069 .resume = ipw_pci_resume, 12067 .resume = ipw_pci_resume,
diff --git a/drivers/net/wireless/iwlegacy/3945-mac.c b/drivers/net/wireless/iwlegacy/3945-mac.c
index e252acb9c862..d604b4036a76 100644
--- a/drivers/net/wireless/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/iwlegacy/3945-mac.c
@@ -3794,7 +3794,7 @@ out:
3794 return err; 3794 return err;
3795} 3795}
3796 3796
3797static void __devexit 3797static void
3798il3945_pci_remove(struct pci_dev *pdev) 3798il3945_pci_remove(struct pci_dev *pdev)
3799{ 3799{
3800 struct il_priv *il = pci_get_drvdata(pdev); 3800 struct il_priv *il = pci_get_drvdata(pdev);
@@ -3884,7 +3884,7 @@ static struct pci_driver il3945_driver = {
3884 .name = DRV_NAME, 3884 .name = DRV_NAME,
3885 .id_table = il3945_hw_card_ids, 3885 .id_table = il3945_hw_card_ids,
3886 .probe = il3945_pci_probe, 3886 .probe = il3945_pci_probe,
3887 .remove = __devexit_p(il3945_pci_remove), 3887 .remove = il3945_pci_remove,
3888 .driver.pm = IL_LEGACY_PM_OPS, 3888 .driver.pm = IL_LEGACY_PM_OPS,
3889}; 3889};
3890 3890
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 07ffa575e3ef..c3fbf6717564 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -6664,7 +6664,7 @@ out:
6664 return err; 6664 return err;
6665} 6665}
6666 6666
6667static void __devexit 6667static void
6668il4965_pci_remove(struct pci_dev *pdev) 6668il4965_pci_remove(struct pci_dev *pdev)
6669{ 6669{
6670 struct il_priv *il = pci_get_drvdata(pdev); 6670 struct il_priv *il = pci_get_drvdata(pdev);
@@ -6772,7 +6772,7 @@ static struct pci_driver il4965_driver = {
6772 .name = DRV_NAME, 6772 .name = DRV_NAME,
6773 .id_table = il4965_hw_card_ids, 6773 .id_table = il4965_hw_card_ids,
6774 .probe = il4965_pci_probe, 6774 .probe = il4965_pci_probe,
6775 .remove = __devexit_p(il4965_pci_remove), 6775 .remove = il4965_pci_remove,
6776 .driver.pm = IL_LEGACY_PM_OPS, 6776 .driver.pm = IL_LEGACY_PM_OPS,
6777}; 6777};
6778 6778
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c
index 10896393e5a0..2830ea290502 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rxon.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c
@@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,
1012 * As a consequence, it's not as complicated as it sounds, just add 1012 * As a consequence, it's not as complicated as it sounds, just add
1013 * any lower rates to the ACK rate bitmap. 1013 * any lower rates to the ACK rate bitmap.
1014 */ 1014 */
1015 if (IWL_RATE_11M_INDEX < lowest_present_ofdm) 1015 if (IWL_RATE_11M_INDEX < lowest_present_cck)
1016 ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; 1016 cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE;
1017 if (IWL_RATE_5M_INDEX < lowest_present_ofdm) 1017 if (IWL_RATE_5M_INDEX < lowest_present_cck)
1018 ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; 1018 cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE;
1019 if (IWL_RATE_2M_INDEX < lowest_present_ofdm) 1019 if (IWL_RATE_2M_INDEX < lowest_present_cck)
1020 ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; 1020 cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;
1021 /* 1M already there or needed so always add */ 1021 /* 1M already there or needed so always add */
1022 cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; 1022 cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE;
1023 1023
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 956fe6c370bc..2b7e8a0b1cd4 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -293,7 +293,7 @@ out_free_trans:
293 return -EFAULT; 293 return -EFAULT;
294} 294}
295 295
296static void __devexit iwl_pci_remove(struct pci_dev *pdev) 296static void iwl_pci_remove(struct pci_dev *pdev)
297{ 297{
298 struct iwl_trans *trans = pci_get_drvdata(pdev); 298 struct iwl_trans *trans = pci_get_drvdata(pdev);
299 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 299 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -352,7 +352,7 @@ static struct pci_driver iwl_pci_driver = {
352 .name = DRV_NAME, 352 .name = DRV_NAME,
353 .id_table = iwl_hw_card_ids, 353 .id_table = iwl_hw_card_ids,
354 .probe = iwl_pci_probe, 354 .probe = iwl_pci_probe,
355 .remove = __devexit_p(iwl_pci_remove), 355 .remove = iwl_pci_remove,
356 .driver.pm = IWL_PM_OPS, 356 .driver.pm = IWL_PM_OPS,
357}; 357};
358 358
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index ec36868f6fc5..ec6d5d6b452e 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -298,6 +298,7 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
298 const u8 *rates_eid, *ext_rates_eid; 298 const u8 *rates_eid, *ext_rates_eid;
299 int n = 0; 299 int n = 0;
300 300
301 rcu_read_lock();
301 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); 302 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
302 ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES); 303 ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
303 304
@@ -325,6 +326,7 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
325 *tlv++ = 0x96; 326 *tlv++ = 0x96;
326 n = 4; 327 n = 4;
327 } 328 }
329 rcu_read_unlock();
328 330
329 rate_tlv->header.len = cpu_to_le16(n); 331 rate_tlv->header.len = cpu_to_le16(n);
330 return sizeof(rate_tlv->header) + n; 332 return sizeof(rate_tlv->header) + n;
@@ -1140,11 +1142,13 @@ static int lbs_associate(struct lbs_private *priv,
1140 cmd->capability = cpu_to_le16(bss->capability); 1142 cmd->capability = cpu_to_le16(bss->capability);
1141 1143
1142 /* add SSID TLV */ 1144 /* add SSID TLV */
1145 rcu_read_lock();
1143 ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID); 1146 ssid_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SSID);
1144 if (ssid_eid) 1147 if (ssid_eid)
1145 pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]); 1148 pos += lbs_add_ssid_tlv(pos, ssid_eid + 2, ssid_eid[1]);
1146 else 1149 else
1147 lbs_deb_assoc("no SSID\n"); 1150 lbs_deb_assoc("no SSID\n");
1151 rcu_read_unlock();
1148 1152
1149 /* add DS param TLV */ 1153 /* add DS param TLV */
1150 if (bss->channel) 1154 if (bss->channel)
@@ -1782,7 +1786,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1782 struct cfg80211_ibss_params *params, 1786 struct cfg80211_ibss_params *params,
1783 struct cfg80211_bss *bss) 1787 struct cfg80211_bss *bss)
1784{ 1788{
1785 const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES); 1789 const u8 *rates_eid;
1786 struct cmd_ds_802_11_ad_hoc_join cmd; 1790 struct cmd_ds_802_11_ad_hoc_join cmd;
1787 u8 preamble = RADIO_PREAMBLE_SHORT; 1791 u8 preamble = RADIO_PREAMBLE_SHORT;
1788 int ret = 0; 1792 int ret = 0;
@@ -1841,6 +1845,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1841 1845
1842 /* set rates to the intersection of our rates and the rates in the 1846 /* set rates to the intersection of our rates and the rates in the
1843 bss */ 1847 bss */
1848 rcu_read_lock();
1849 rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
1844 if (!rates_eid) { 1850 if (!rates_eid) {
1845 lbs_add_rates(cmd.bss.rates); 1851 lbs_add_rates(cmd.bss.rates);
1846 } else { 1852 } else {
@@ -1860,6 +1866,7 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
1860 } 1866 }
1861 } 1867 }
1862 } 1868 }
1869 rcu_read_unlock();
1863 1870
1864 /* Only v8 and below support setting this */ 1871 /* Only v8 and below support setting this */
1865 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) { 1872 if (MRVL_FW_MAJOR_REV(priv->fwrelease) <= 8) {
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 9604a1c4a74d..4bb6574f4073 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -1124,7 +1124,7 @@ static void if_spi_resume_worker(struct work_struct *work)
1124 } 1124 }
1125} 1125}
1126 1126
1127static int __devinit if_spi_probe(struct spi_device *spi) 1127static int if_spi_probe(struct spi_device *spi)
1128{ 1128{
1129 struct if_spi_card *card; 1129 struct if_spi_card *card;
1130 struct lbs_private *priv = NULL; 1130 struct lbs_private *priv = NULL;
@@ -1226,7 +1226,7 @@ out:
1226 return err; 1226 return err;
1227} 1227}
1228 1228
1229static int __devexit libertas_spi_remove(struct spi_device *spi) 1229static int libertas_spi_remove(struct spi_device *spi)
1230{ 1230{
1231 struct if_spi_card *card = spi_get_drvdata(spi); 1231 struct if_spi_card *card = spi_get_drvdata(spi);
1232 struct lbs_private *priv = card->priv; 1232 struct lbs_private *priv = card->priv;
@@ -1285,7 +1285,7 @@ static const struct dev_pm_ops if_spi_pm_ops = {
1285 1285
1286static struct spi_driver libertas_spi_driver = { 1286static struct spi_driver libertas_spi_driver = {
1287 .probe = if_spi_probe, 1287 .probe = if_spi_probe,
1288 .remove = __devexit_p(libertas_spi_remove), 1288 .remove = libertas_spi_remove,
1289 .driver = { 1289 .driver = {
1290 .name = "libertas_spi", 1290 .name = "libertas_spi",
1291 .owner = THIS_MODULE, 1291 .owner = THIS_MODULE,
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 2aa8a1aa1184..8a61dbd320e6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1347,9 +1347,14 @@ static void hw_scan_work(struct work_struct *work)
1347 hwsim->hw_scan_vif, 1347 hwsim->hw_scan_vif,
1348 req->ssids[i].ssid, 1348 req->ssids[i].ssid,
1349 req->ssids[i].ssid_len, 1349 req->ssids[i].ssid_len,
1350 req->ie, req->ie_len); 1350 req->ie_len);
1351 if (!probe) 1351 if (!probe)
1352 continue; 1352 continue;
1353
1354 if (req->ie_len)
1355 memcpy(skb_put(probe, req->ie_len), req->ie,
1356 req->ie_len);
1357
1353 local_bh_disable(); 1358 local_bh_disable();
1354 mac80211_hwsim_tx_frame(hwsim->hw, probe, 1359 mac80211_hwsim_tx_frame(hwsim->hw, probe,
1355 hwsim->tmp_chan); 1360 hwsim->tmp_chan);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 3b1c27712ad9..a875499f8945 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1948,6 +1948,21 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
1948 else 1948 else
1949 ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC; 1949 ht_info->cap &= ~IEEE80211_HT_CAP_TX_STBC;
1950 1950
1951 if (ISSUPP_GREENFIELD(adapter->hw_dot_11n_dev_cap))
1952 ht_info->cap |= IEEE80211_HT_CAP_GRN_FLD;
1953 else
1954 ht_info->cap &= ~IEEE80211_HT_CAP_GRN_FLD;
1955
1956 if (ISENABLED_40MHZ_INTOLERANT(adapter->hw_dot_11n_dev_cap))
1957 ht_info->cap |= IEEE80211_HT_CAP_40MHZ_INTOLERANT;
1958 else
1959 ht_info->cap &= ~IEEE80211_HT_CAP_40MHZ_INTOLERANT;
1960
1961 if (ISSUPP_RXLDPC(adapter->hw_dot_11n_dev_cap))
1962 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
1963 else
1964 ht_info->cap &= ~IEEE80211_HT_CAP_LDPC_CODING;
1965
1951 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU; 1966 ht_info->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
1952 ht_info->cap |= IEEE80211_HT_CAP_SM_PS; 1967 ht_info->cap |= IEEE80211_HT_CAP_SM_PS;
1953 1968
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index dda588b35570..4dc8e2e9a889 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -194,6 +194,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
194#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25)) 194#define ISSUPP_TXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(25))
195#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26)) 195#define ISSUPP_RXSTBC(Dot11nDevCap) (Dot11nDevCap & BIT(26))
196#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29)) 196#define ISSUPP_GREENFIELD(Dot11nDevCap) (Dot11nDevCap & BIT(29))
197#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8))
198#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
197 199
198/* httxcfg bitmap 200/* httxcfg bitmap
199 * 0 reserved 201 * 0 reserved
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 237c8d2ba9f2..cb682561c438 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -160,10 +160,21 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
160{ 160{
161 int ret; 161 int ret;
162 u8 *beacon_ie; 162 u8 *beacon_ie;
163 size_t beacon_ie_len;
163 struct mwifiex_bss_priv *bss_priv = (void *)bss->priv; 164 struct mwifiex_bss_priv *bss_priv = (void *)bss->priv;
165 const struct cfg80211_bss_ies *ies;
166
167 rcu_read_lock();
168 ies = rcu_dereference(bss->ies);
169 if (WARN_ON(!ies)) {
170 /* should never happen */
171 rcu_read_unlock();
172 return -EINVAL;
173 }
174 beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
175 beacon_ie_len = ies->len;
176 rcu_read_unlock();
164 177
165 beacon_ie = kmemdup(bss->information_elements, bss->len_beacon_ies,
166 GFP_KERNEL);
167 if (!beacon_ie) { 178 if (!beacon_ie) {
168 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n"); 179 dev_err(priv->adapter->dev, " failed to alloc beacon_ie\n");
169 return -ENOMEM; 180 return -ENOMEM;
@@ -172,7 +183,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
172 memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN); 183 memcpy(bss_desc->mac_address, bss->bssid, ETH_ALEN);
173 bss_desc->rssi = bss->signal; 184 bss_desc->rssi = bss->signal;
174 bss_desc->beacon_buf = beacon_ie; 185 bss_desc->beacon_buf = beacon_ie;
175 bss_desc->beacon_buf_size = bss->len_beacon_ies; 186 bss_desc->beacon_buf_size = beacon_ie_len;
176 bss_desc->beacon_period = bss->beacon_interval; 187 bss_desc->beacon_period = bss->beacon_interval;
177 bss_desc->cap_info_bitmap = bss->capability; 188 bss_desc->cap_info_bitmap = bss->capability;
178 bss_desc->bss_band = bss_priv->band; 189 bss_desc->bss_band = bss_priv->band;
@@ -198,18 +209,23 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
198static int mwifiex_process_country_ie(struct mwifiex_private *priv, 209static int mwifiex_process_country_ie(struct mwifiex_private *priv,
199 struct cfg80211_bss *bss) 210 struct cfg80211_bss *bss)
200{ 211{
201 u8 *country_ie, country_ie_len; 212 const u8 *country_ie;
213 u8 country_ie_len;
202 struct mwifiex_802_11d_domain_reg *domain_info = 214 struct mwifiex_802_11d_domain_reg *domain_info =
203 &priv->adapter->domain_reg; 215 &priv->adapter->domain_reg;
204 216
205 country_ie = (u8 *)ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); 217 rcu_read_lock();
206 218 country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
207 if (!country_ie) 219 if (!country_ie) {
220 rcu_read_unlock();
208 return 0; 221 return 0;
222 }
209 223
210 country_ie_len = country_ie[1]; 224 country_ie_len = country_ie[1];
211 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) 225 if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) {
226 rcu_read_unlock();
212 return 0; 227 return 0;
228 }
213 229
214 domain_info->country_code[0] = country_ie[2]; 230 domain_info->country_code[0] = country_ie[2];
215 domain_info->country_code[1] = country_ie[3]; 231 domain_info->country_code[1] = country_ie[3];
@@ -223,6 +239,8 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
223 memcpy((u8 *)domain_info->triplet, 239 memcpy((u8 *)domain_info->triplet,
224 &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len); 240 &country_ie[2] + IEEE80211_COUNTRY_STRING_LEN, country_ie_len);
225 241
242 rcu_read_unlock();
243
226 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, 244 if (mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
227 HostCmd_ACT_GEN_SET, 0, NULL)) { 245 HostCmd_ACT_GEN_SET, 0, NULL)) {
228 wiphy_err(priv->adapter->wiphy, 246 wiphy_err(priv->adapter->wiphy,
@@ -461,7 +479,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
461 } 479 }
462 480
463 if (adapter->hs_activated) { 481 if (adapter->hs_activated) {
464 dev_dbg(adapter->dev, "cmd: HS Already actived\n"); 482 dev_dbg(adapter->dev, "cmd: HS Already activated\n");
465 return true; 483 return true;
466 } 484 }
467 485
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index bbe1f3518e4b..63ac9f2d11ae 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -351,7 +351,7 @@ static int mwifiex_usb_probe(struct usb_interface *intf,
351 card->udev = udev; 351 card->udev = udev;
352 card->intf = intf; 352 card->intf = intf;
353 353
354 pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocl=%#x\n", 354 pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
355 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass, 355 udev->descriptor.bcdUSB, udev->descriptor.bDeviceClass,
356 udev->descriptor.bDeviceSubClass, 356 udev->descriptor.bDeviceSubClass,
357 udev->descriptor.bDeviceProtocol); 357 udev->descriptor.bDeviceProtocol);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index 0cdae6632735..f221b95b90b3 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -5258,7 +5258,7 @@ enum {
5258#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw" 5258#define _MWL8K_8366_AP_FW(api) "mwl8k/fmimage_8366_ap-" #api ".fw"
5259#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api) 5259#define MWL8K_8366_AP_FW(api) _MWL8K_8366_AP_FW(api)
5260 5260
5261static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { 5261static struct mwl8k_device_info mwl8k_info_tbl[] = {
5262 [MWL8363] = { 5262 [MWL8363] = {
5263 .part_name = "88w8363", 5263 .part_name = "88w8363",
5264 .helper_image = "mwl8k/helper_8363.fw", 5264 .helper_image = "mwl8k/helper_8363.fw",
@@ -5756,7 +5756,7 @@ err_free_cookie:
5756 5756
5757 return rc; 5757 return rc;
5758} 5758}
5759static int __devinit mwl8k_probe(struct pci_dev *pdev, 5759static int mwl8k_probe(struct pci_dev *pdev,
5760 const struct pci_device_id *id) 5760 const struct pci_device_id *id)
5761{ 5761{
5762 static int printed_version; 5762 static int printed_version;
@@ -5873,12 +5873,7 @@ err_disable_device:
5873 return rc; 5873 return rc;
5874} 5874}
5875 5875
5876static void __devexit mwl8k_shutdown(struct pci_dev *pdev) 5876static void mwl8k_remove(struct pci_dev *pdev)
5877{
5878 printk(KERN_ERR "===>%s(%u)\n", __func__, __LINE__);
5879}
5880
5881static void __devexit mwl8k_remove(struct pci_dev *pdev)
5882{ 5877{
5883 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 5878 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
5884 struct mwl8k_priv *priv; 5879 struct mwl8k_priv *priv;
@@ -5930,8 +5925,7 @@ static struct pci_driver mwl8k_driver = {
5930 .name = MWL8K_NAME, 5925 .name = MWL8K_NAME,
5931 .id_table = mwl8k_pci_id_table, 5926 .id_table = mwl8k_pci_id_table,
5932 .probe = mwl8k_probe, 5927 .probe = mwl8k_probe,
5933 .remove = __devexit_p(mwl8k_remove), 5928 .remove = mwl8k_remove,
5934 .shutdown = __devexit_p(mwl8k_shutdown),
5935}; 5929};
5936 5930
5937module_pci_driver(mwl8k_driver); 5931module_pci_driver(mwl8k_driver);
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 326396b313a6..d73fdf6185a2 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -255,7 +255,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
255 return err; 255 return err;
256} 256}
257 257
258static void __devexit orinoco_nortel_remove_one(struct pci_dev *pdev) 258static void orinoco_nortel_remove_one(struct pci_dev *pdev)
259{ 259{
260 struct orinoco_private *priv = pci_get_drvdata(pdev); 260 struct orinoco_private *priv = pci_get_drvdata(pdev);
261 struct orinoco_pci_card *card = priv->card; 261 struct orinoco_pci_card *card = priv->card;
@@ -288,7 +288,7 @@ static struct pci_driver orinoco_nortel_driver = {
288 .name = DRIVER_NAME, 288 .name = DRIVER_NAME,
289 .id_table = orinoco_nortel_id_table, 289 .id_table = orinoco_nortel_id_table,
290 .probe = orinoco_nortel_init_one, 290 .probe = orinoco_nortel_init_one,
291 .remove = __devexit_p(orinoco_nortel_remove_one), 291 .remove = orinoco_nortel_remove_one,
292 .suspend = orinoco_pci_suspend, 292 .suspend = orinoco_pci_suspend,
293 .resume = orinoco_pci_resume, 293 .resume = orinoco_pci_resume,
294}; 294};
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index 6058c66b844e..677bf14eca84 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -199,7 +199,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
199 return err; 199 return err;
200} 200}
201 201
202static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev) 202static void orinoco_pci_remove_one(struct pci_dev *pdev)
203{ 203{
204 struct orinoco_private *priv = pci_get_drvdata(pdev); 204 struct orinoco_private *priv = pci_get_drvdata(pdev);
205 205
@@ -228,7 +228,7 @@ static struct pci_driver orinoco_pci_driver = {
228 .name = DRIVER_NAME, 228 .name = DRIVER_NAME,
229 .id_table = orinoco_pci_id_table, 229 .id_table = orinoco_pci_id_table,
230 .probe = orinoco_pci_init_one, 230 .probe = orinoco_pci_init_one,
231 .remove = __devexit_p(orinoco_pci_remove_one), 231 .remove = orinoco_pci_remove_one,
232 .suspend = orinoco_pci_suspend, 232 .suspend = orinoco_pci_suspend,
233 .resume = orinoco_pci_resume, 233 .resume = orinoco_pci_resume,
234}; 234};
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index 2bac8248a991..2559dbd6184b 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -294,7 +294,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
294 return err; 294 return err;
295} 295}
296 296
297static void __devexit orinoco_plx_remove_one(struct pci_dev *pdev) 297static void orinoco_plx_remove_one(struct pci_dev *pdev)
298{ 298{
299 struct orinoco_private *priv = pci_get_drvdata(pdev); 299 struct orinoco_private *priv = pci_get_drvdata(pdev);
300 struct orinoco_pci_card *card = priv->card; 300 struct orinoco_pci_card *card = priv->card;
@@ -334,7 +334,7 @@ static struct pci_driver orinoco_plx_driver = {
334 .name = DRIVER_NAME, 334 .name = DRIVER_NAME,
335 .id_table = orinoco_plx_id_table, 335 .id_table = orinoco_plx_id_table,
336 .probe = orinoco_plx_init_one, 336 .probe = orinoco_plx_init_one,
337 .remove = __devexit_p(orinoco_plx_remove_one), 337 .remove = orinoco_plx_remove_one,
338 .suspend = orinoco_pci_suspend, 338 .suspend = orinoco_pci_suspend,
339 .resume = orinoco_pci_resume, 339 .resume = orinoco_pci_resume,
340}; 340};
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 93159d68ec93..42afeeea2c40 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -188,7 +188,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
188 return err; 188 return err;
189} 189}
190 190
191static void __devexit orinoco_tmd_remove_one(struct pci_dev *pdev) 191static void orinoco_tmd_remove_one(struct pci_dev *pdev)
192{ 192{
193 struct orinoco_private *priv = pci_get_drvdata(pdev); 193 struct orinoco_private *priv = pci_get_drvdata(pdev);
194 struct orinoco_pci_card *card = priv->card; 194 struct orinoco_pci_card *card = priv->card;
@@ -214,7 +214,7 @@ static struct pci_driver orinoco_tmd_driver = {
214 .name = DRIVER_NAME, 214 .name = DRIVER_NAME,
215 .id_table = orinoco_tmd_id_table, 215 .id_table = orinoco_tmd_id_table,
216 .probe = orinoco_tmd_init_one, 216 .probe = orinoco_tmd_init_one,
217 .remove = __devexit_p(orinoco_tmd_remove_one), 217 .remove = orinoco_tmd_remove_one,
218 .suspend = orinoco_pci_suspend, 218 .suspend = orinoco_pci_suspend,
219 .resume = orinoco_pci_resume, 219 .resume = orinoco_pci_resume,
220}; 220};
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 1ef1bfe6a9d7..d43e3740e45d 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -541,8 +541,9 @@ static int p54_parse_rssical(struct ieee80211_hw *dev,
541 entries = (len - offset) / 541 entries = (len - offset) /
542 sizeof(struct pda_rssi_cal_ext_entry); 542 sizeof(struct pda_rssi_cal_ext_entry);
543 543
544 if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) || 544 if (len < offset ||
545 entries <= 0) { 545 (len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
546 entries == 0) {
546 wiphy_err(dev->wiphy, "invalid rssi database.\n"); 547 wiphy_err(dev->wiphy, "invalid rssi database.\n");
547 goto err_data; 548 goto err_data;
548 } 549 }
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index b4390797d78c..933e5d941937 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -540,7 +540,7 @@ out:
540 pci_dev_put(pdev); 540 pci_dev_put(pdev);
541} 541}
542 542
543static int __devinit p54p_probe(struct pci_dev *pdev, 543static int p54p_probe(struct pci_dev *pdev,
544 const struct pci_device_id *id) 544 const struct pci_device_id *id)
545{ 545{
546 struct p54p_priv *priv; 546 struct p54p_priv *priv;
@@ -639,7 +639,7 @@ static int __devinit p54p_probe(struct pci_dev *pdev,
639 return err; 639 return err;
640} 640}
641 641
642static void __devexit p54p_remove(struct pci_dev *pdev) 642static void p54p_remove(struct pci_dev *pdev)
643{ 643{
644 struct ieee80211_hw *dev = pci_get_drvdata(pdev); 644 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
645 struct p54p_priv *priv; 645 struct p54p_priv *priv;
@@ -659,7 +659,7 @@ static void __devexit p54p_remove(struct pci_dev *pdev)
659 p54_free_common(dev); 659 p54_free_common(dev);
660} 660}
661 661
662#ifdef CONFIG_PM 662#ifdef CONFIG_PM_SLEEP
663static int p54p_suspend(struct device *device) 663static int p54p_suspend(struct device *device)
664{ 664{
665 struct pci_dev *pdev = to_pci_dev(device); 665 struct pci_dev *pdev = to_pci_dev(device);
@@ -681,25 +681,18 @@ static int p54p_resume(struct device *device)
681 return pci_set_power_state(pdev, PCI_D0); 681 return pci_set_power_state(pdev, PCI_D0);
682} 682}
683 683
684static const struct dev_pm_ops p54pci_pm_ops = { 684static SIMPLE_DEV_PM_OPS(p54pci_pm_ops, p54p_suspend, p54p_resume);
685 .suspend = p54p_suspend,
686 .resume = p54p_resume,
687 .freeze = p54p_suspend,
688 .thaw = p54p_resume,
689 .poweroff = p54p_suspend,
690 .restore = p54p_resume,
691};
692 685
693#define P54P_PM_OPS (&p54pci_pm_ops) 686#define P54P_PM_OPS (&p54pci_pm_ops)
694#else 687#else
695#define P54P_PM_OPS (NULL) 688#define P54P_PM_OPS (NULL)
696#endif /* CONFIG_PM */ 689#endif /* CONFIG_PM_SLEEP */
697 690
698static struct pci_driver p54p_driver = { 691static struct pci_driver p54p_driver = {
699 .name = "p54pci", 692 .name = "p54pci",
700 .id_table = p54p_table, 693 .id_table = p54p_table,
701 .probe = p54p_probe, 694 .probe = p54p_probe,
702 .remove = __devexit_p(p54p_remove), 695 .remove = p54p_remove,
703 .driver.pm = P54P_PM_OPS, 696 .driver.pm = P54P_PM_OPS,
704}; 697};
705 698
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index f7929906d437..4fd49a007b51 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -595,7 +595,7 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
595 cancel_work_sync(&priv->work); 595 cancel_work_sync(&priv->work);
596} 596}
597 597
598static int __devinit p54spi_probe(struct spi_device *spi) 598static int p54spi_probe(struct spi_device *spi)
599{ 599{
600 struct p54s_priv *priv = NULL; 600 struct p54s_priv *priv = NULL;
601 struct ieee80211_hw *hw; 601 struct ieee80211_hw *hw;
@@ -683,7 +683,7 @@ err_free:
683 return ret; 683 return ret;
684} 684}
685 685
686static int __devexit p54spi_remove(struct spi_device *spi) 686static int p54spi_remove(struct spi_device *spi)
687{ 687{
688 struct p54s_priv *priv = dev_get_drvdata(&spi->dev); 688 struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
689 689
@@ -710,7 +710,7 @@ static struct spi_driver p54spi_driver = {
710 }, 710 },
711 711
712 .probe = p54spi_probe, 712 .probe = p54spi_probe,
713 .remove = __devexit_p(p54spi_remove), 713 .remove = p54spi_remove,
714}; 714};
715 715
716static int __init p54spi_init(void) 716static int __init p54spi_init(void)
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index effb044a8a9d..e71c702e2eb1 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -986,7 +986,7 @@ static int p54u_load_firmware(struct ieee80211_hw *dev,
986 return err; 986 return err;
987} 987}
988 988
989static int __devinit p54u_probe(struct usb_interface *intf, 989static int p54u_probe(struct usb_interface *intf,
990 const struct usb_device_id *id) 990 const struct usb_device_id *id)
991{ 991{
992 struct usb_device *udev = interface_to_usbdev(intf); 992 struct usb_device *udev = interface_to_usbdev(intf);
@@ -1057,7 +1057,7 @@ static int __devinit p54u_probe(struct usb_interface *intf,
1057 return err; 1057 return err;
1058} 1058}
1059 1059
1060static void __devexit p54u_disconnect(struct usb_interface *intf) 1060static void p54u_disconnect(struct usb_interface *intf)
1061{ 1061{
1062 struct ieee80211_hw *dev = usb_get_intfdata(intf); 1062 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1063 struct p54u_priv *priv; 1063 struct p54u_priv *priv;
@@ -1131,7 +1131,7 @@ static struct usb_driver p54u_driver = {
1131 .name = "p54usb", 1131 .name = "p54usb",
1132 .id_table = p54u_table, 1132 .id_table = p54u_table,
1133 .probe = p54u_probe, 1133 .probe = p54u_probe,
1134 .disconnect = __devexit_p(p54u_disconnect), 1134 .disconnect = p54u_disconnect,
1135 .pre_reset = p54u_pre_reset, 1135 .pre_reset = p54u_pre_reset,
1136 .post_reset = p54u_post_reset, 1136 .post_reset = p54u_post_reset,
1137#ifdef CONFIG_PM 1137#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index e3a2d9070cf6..a2d2bc2c7b3d 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1831,7 +1831,7 @@ static struct pci_driver rt2400pci_driver = {
1831 .name = KBUILD_MODNAME, 1831 .name = KBUILD_MODNAME,
1832 .id_table = rt2400pci_device_table, 1832 .id_table = rt2400pci_device_table,
1833 .probe = rt2400pci_probe, 1833 .probe = rt2400pci_probe,
1834 .remove = __devexit_p(rt2x00pci_remove), 1834 .remove = rt2x00pci_remove,
1835 .suspend = rt2x00pci_suspend, 1835 .suspend = rt2x00pci_suspend,
1836 .resume = rt2x00pci_resume, 1836 .resume = rt2x00pci_resume,
1837}; 1837};
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 479d756e275b..9bea10f53f0a 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -2122,7 +2122,7 @@ static struct pci_driver rt2500pci_driver = {
2122 .name = KBUILD_MODNAME, 2122 .name = KBUILD_MODNAME,
2123 .id_table = rt2500pci_device_table, 2123 .id_table = rt2500pci_device_table,
2124 .probe = rt2500pci_probe, 2124 .probe = rt2500pci_probe,
2125 .remove = __devexit_p(rt2x00pci_remove), 2125 .remove = rt2x00pci_remove,
2126 .suspend = rt2x00pci_suspend, 2126 .suspend = rt2x00pci_suspend,
2127 .resume = rt2x00pci_resume, 2127 .resume = rt2x00pci_resume,
2128}; 2128};
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 6d67c3ede651..4db1088a847f 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -1993,8 +1993,10 @@ struct mac_iveiv_entry {
1993 */ 1993 */
1994#define RFCSR3_K FIELD8(0x0f) 1994#define RFCSR3_K FIELD8(0x0f)
1995/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */ 1995/* Bits [7-4] for RF3320 (RT3370/RT3390), on other chipsets reserved */
1996#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70); 1996#define RFCSR3_PA1_BIAS_CCK FIELD8(0x70)
1997#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80); 1997#define RFCSR3_PA2_CASCODE_BIAS_CCKK FIELD8(0x80)
1998/* Bits for RF3290/RF5360/RF5370/RF5372/RF5390/RF5392 */
1999#define RFCSR3_VCOCAL_EN FIELD8(0x80)
1998 2000
1999/* 2001/*
2000 * FRCSR 5: 2002 * FRCSR 5:
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index c0441a715c96..d4d0c3664eb2 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2173,7 +2173,7 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev,
2173 rt2800_rfcsr_write(rt2x00dev, 59, 2173 rt2800_rfcsr_write(rt2x00dev, 59,
2174 r59_nonbt_rev[idx]); 2174 r59_nonbt_rev[idx]);
2175 } else if (rt2x00_rt(rt2x00dev, RT5390) || 2175 } else if (rt2x00_rt(rt2x00dev, RT5390) ||
2176 rt2x00_rt(rt2x00dev, RT5392)) { 2176 rt2x00_rt(rt2x00dev, RT5392)) {
2177 static const char r59_non_bt[] = {0x8f, 0x8f, 2177 static const char r59_non_bt[] = {0x8f, 0x8f,
2178 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, 2178 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d,
2179 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; 2179 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86};
@@ -2243,7 +2243,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2243 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); 2243 rt2800_rfcsr_write(rt2x00dev, 30, rfcsr);
2244 2244
2245 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); 2245 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
2246 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); 2246 rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
2247 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); 2247 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
2248 } 2248 }
2249 2249
@@ -2264,7 +2264,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2264 2264
2265 if (rf->channel <= 14) { 2265 if (rf->channel <= 14) {
2266 if (!rt2x00_rt(rt2x00dev, RT5390) && 2266 if (!rt2x00_rt(rt2x00dev, RT5390) &&
2267 !rt2x00_rt(rt2x00dev, RT5392)) { 2267 !rt2x00_rt(rt2x00dev, RT5392)) {
2268 if (test_bit(CAPABILITY_EXTERNAL_LNA_BG, 2268 if (test_bit(CAPABILITY_EXTERNAL_LNA_BG,
2269 &rt2x00dev->cap_flags)) { 2269 &rt2x00dev->cap_flags)) {
2270 rt2800_bbp_write(rt2x00dev, 82, 0x62); 2270 rt2800_bbp_write(rt2x00dev, 82, 0x62);
@@ -2804,7 +2804,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev)
2804 case RF5390: 2804 case RF5390:
2805 case RF5392: 2805 case RF5392:
2806 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); 2806 rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr);
2807 rt2x00_set_field8(&rfcsr, RFCSR30_RF_CALIBRATION, 1); 2807 rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1);
2808 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); 2808 rt2800_rfcsr_write(rt2x00dev, 3, rfcsr);
2809 break; 2809 break;
2810 default: 2810 default:
@@ -3592,8 +3592,8 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3592 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) 3592 if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D))
3593 rt2800_bbp_write(rt2x00dev, 84, 0x19); 3593 rt2800_bbp_write(rt2x00dev, 84, 0x19);
3594 else if (rt2x00_rt(rt2x00dev, RT3290) || 3594 else if (rt2x00_rt(rt2x00dev, RT3290) ||
3595 rt2x00_rt(rt2x00dev, RT5390) || 3595 rt2x00_rt(rt2x00dev, RT5390) ||
3596 rt2x00_rt(rt2x00dev, RT5392)) 3596 rt2x00_rt(rt2x00dev, RT5392))
3597 rt2800_bbp_write(rt2x00dev, 84, 0x9a); 3597 rt2800_bbp_write(rt2x00dev, 84, 0x9a);
3598 else 3598 else
3599 rt2800_bbp_write(rt2x00dev, 84, 0x99); 3599 rt2800_bbp_write(rt2x00dev, 84, 0x99);
@@ -3652,7 +3652,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3652 else if (rt2x00_rt(rt2x00dev, RT3352)) 3652 else if (rt2x00_rt(rt2x00dev, RT3352))
3653 rt2800_bbp_write(rt2x00dev, 105, 0x34); 3653 rt2800_bbp_write(rt2x00dev, 105, 0x34);
3654 else if (rt2x00_rt(rt2x00dev, RT5390) || 3654 else if (rt2x00_rt(rt2x00dev, RT5390) ||
3655 rt2x00_rt(rt2x00dev, RT5392)) 3655 rt2x00_rt(rt2x00dev, RT5392))
3656 rt2800_bbp_write(rt2x00dev, 105, 0x3c); 3656 rt2800_bbp_write(rt2x00dev, 105, 0x3c);
3657 else 3657 else
3658 rt2800_bbp_write(rt2x00dev, 105, 0x05); 3658 rt2800_bbp_write(rt2x00dev, 105, 0x05);
@@ -3746,7 +3746,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev)
3746 } 3746 }
3747 3747
3748 if (rt2x00_rt(rt2x00dev, RT5390) || 3748 if (rt2x00_rt(rt2x00dev, RT5390) ||
3749 rt2x00_rt(rt2x00dev, RT5392)) { 3749 rt2x00_rt(rt2x00dev, RT5392)) {
3750 int ant, div_mode; 3750 int ant, div_mode;
3751 3751
3752 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); 3752 rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom);
@@ -4220,66 +4220,66 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4220 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd); 4220 rt2800_rfcsr_write(rt2x00dev, 61, 0xdd);
4221 rt2800_rfcsr_write(rt2x00dev, 62, 0x00); 4221 rt2800_rfcsr_write(rt2x00dev, 62, 0x00);
4222 rt2800_rfcsr_write(rt2x00dev, 63, 0x00); 4222 rt2800_rfcsr_write(rt2x00dev, 63, 0x00);
4223 } else if (rt2x00_rt(rt2x00dev, RT5392)) { 4223 } else if (rt2x00_rt(rt2x00dev, RT5392)) {
4224 rt2800_rfcsr_write(rt2x00dev, 1, 0x17); 4224 rt2800_rfcsr_write(rt2x00dev, 1, 0x17);
4225 rt2800_rfcsr_write(rt2x00dev, 2, 0x80); 4225 rt2800_rfcsr_write(rt2x00dev, 2, 0x80);
4226 rt2800_rfcsr_write(rt2x00dev, 3, 0x88); 4226 rt2800_rfcsr_write(rt2x00dev, 3, 0x88);
4227 rt2800_rfcsr_write(rt2x00dev, 5, 0x10); 4227 rt2800_rfcsr_write(rt2x00dev, 5, 0x10);
4228 rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); 4228 rt2800_rfcsr_write(rt2x00dev, 6, 0xe0);
4229 rt2800_rfcsr_write(rt2x00dev, 7, 0x00); 4229 rt2800_rfcsr_write(rt2x00dev, 7, 0x00);
4230 rt2800_rfcsr_write(rt2x00dev, 10, 0x53); 4230 rt2800_rfcsr_write(rt2x00dev, 10, 0x53);
4231 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); 4231 rt2800_rfcsr_write(rt2x00dev, 11, 0x4a);
4232 rt2800_rfcsr_write(rt2x00dev, 12, 0x46); 4232 rt2800_rfcsr_write(rt2x00dev, 12, 0x46);
4233 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); 4233 rt2800_rfcsr_write(rt2x00dev, 13, 0x9f);
4234 rt2800_rfcsr_write(rt2x00dev, 14, 0x00); 4234 rt2800_rfcsr_write(rt2x00dev, 14, 0x00);
4235 rt2800_rfcsr_write(rt2x00dev, 15, 0x00); 4235 rt2800_rfcsr_write(rt2x00dev, 15, 0x00);
4236 rt2800_rfcsr_write(rt2x00dev, 16, 0x00); 4236 rt2800_rfcsr_write(rt2x00dev, 16, 0x00);
4237 rt2800_rfcsr_write(rt2x00dev, 18, 0x03); 4237 rt2800_rfcsr_write(rt2x00dev, 18, 0x03);
4238 rt2800_rfcsr_write(rt2x00dev, 19, 0x4d); 4238 rt2800_rfcsr_write(rt2x00dev, 19, 0x4d);
4239 rt2800_rfcsr_write(rt2x00dev, 20, 0x00); 4239 rt2800_rfcsr_write(rt2x00dev, 20, 0x00);
4240 rt2800_rfcsr_write(rt2x00dev, 21, 0x8d); 4240 rt2800_rfcsr_write(rt2x00dev, 21, 0x8d);
4241 rt2800_rfcsr_write(rt2x00dev, 22, 0x20); 4241 rt2800_rfcsr_write(rt2x00dev, 22, 0x20);
4242 rt2800_rfcsr_write(rt2x00dev, 23, 0x0b); 4242 rt2800_rfcsr_write(rt2x00dev, 23, 0x0b);
4243 rt2800_rfcsr_write(rt2x00dev, 24, 0x44); 4243 rt2800_rfcsr_write(rt2x00dev, 24, 0x44);
4244 rt2800_rfcsr_write(rt2x00dev, 25, 0x80); 4244 rt2800_rfcsr_write(rt2x00dev, 25, 0x80);
4245 rt2800_rfcsr_write(rt2x00dev, 26, 0x82); 4245 rt2800_rfcsr_write(rt2x00dev, 26, 0x82);
4246 rt2800_rfcsr_write(rt2x00dev, 27, 0x09); 4246 rt2800_rfcsr_write(rt2x00dev, 27, 0x09);
4247 rt2800_rfcsr_write(rt2x00dev, 28, 0x00); 4247 rt2800_rfcsr_write(rt2x00dev, 28, 0x00);
4248 rt2800_rfcsr_write(rt2x00dev, 29, 0x10); 4248 rt2800_rfcsr_write(rt2x00dev, 29, 0x10);
4249 rt2800_rfcsr_write(rt2x00dev, 30, 0x10); 4249 rt2800_rfcsr_write(rt2x00dev, 30, 0x10);
4250 rt2800_rfcsr_write(rt2x00dev, 31, 0x80); 4250 rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
4251 rt2800_rfcsr_write(rt2x00dev, 32, 0x20); 4251 rt2800_rfcsr_write(rt2x00dev, 32, 0x20);
4252 rt2800_rfcsr_write(rt2x00dev, 33, 0xC0); 4252 rt2800_rfcsr_write(rt2x00dev, 33, 0xC0);
4253 rt2800_rfcsr_write(rt2x00dev, 34, 0x07); 4253 rt2800_rfcsr_write(rt2x00dev, 34, 0x07);
4254 rt2800_rfcsr_write(rt2x00dev, 35, 0x12); 4254 rt2800_rfcsr_write(rt2x00dev, 35, 0x12);
4255 rt2800_rfcsr_write(rt2x00dev, 36, 0x00); 4255 rt2800_rfcsr_write(rt2x00dev, 36, 0x00);
4256 rt2800_rfcsr_write(rt2x00dev, 37, 0x08); 4256 rt2800_rfcsr_write(rt2x00dev, 37, 0x08);
4257 rt2800_rfcsr_write(rt2x00dev, 38, 0x89); 4257 rt2800_rfcsr_write(rt2x00dev, 38, 0x89);
4258 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); 4258 rt2800_rfcsr_write(rt2x00dev, 39, 0x1b);
4259 rt2800_rfcsr_write(rt2x00dev, 40, 0x0f); 4259 rt2800_rfcsr_write(rt2x00dev, 40, 0x0f);
4260 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); 4260 rt2800_rfcsr_write(rt2x00dev, 41, 0xbb);
4261 rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); 4261 rt2800_rfcsr_write(rt2x00dev, 42, 0xd5);
4262 rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); 4262 rt2800_rfcsr_write(rt2x00dev, 43, 0x9b);
4263 rt2800_rfcsr_write(rt2x00dev, 44, 0x0e); 4263 rt2800_rfcsr_write(rt2x00dev, 44, 0x0e);
4264 rt2800_rfcsr_write(rt2x00dev, 45, 0xa2); 4264 rt2800_rfcsr_write(rt2x00dev, 45, 0xa2);
4265 rt2800_rfcsr_write(rt2x00dev, 46, 0x73); 4265 rt2800_rfcsr_write(rt2x00dev, 46, 0x73);
4266 rt2800_rfcsr_write(rt2x00dev, 47, 0x0c); 4266 rt2800_rfcsr_write(rt2x00dev, 47, 0x0c);
4267 rt2800_rfcsr_write(rt2x00dev, 48, 0x10); 4267 rt2800_rfcsr_write(rt2x00dev, 48, 0x10);
4268 rt2800_rfcsr_write(rt2x00dev, 49, 0x94); 4268 rt2800_rfcsr_write(rt2x00dev, 49, 0x94);
4269 rt2800_rfcsr_write(rt2x00dev, 50, 0x94); 4269 rt2800_rfcsr_write(rt2x00dev, 50, 0x94);
4270 rt2800_rfcsr_write(rt2x00dev, 51, 0x3a); 4270 rt2800_rfcsr_write(rt2x00dev, 51, 0x3a);
4271 rt2800_rfcsr_write(rt2x00dev, 52, 0x48); 4271 rt2800_rfcsr_write(rt2x00dev, 52, 0x48);
4272 rt2800_rfcsr_write(rt2x00dev, 53, 0x44); 4272 rt2800_rfcsr_write(rt2x00dev, 53, 0x44);
4273 rt2800_rfcsr_write(rt2x00dev, 54, 0x38); 4273 rt2800_rfcsr_write(rt2x00dev, 54, 0x38);
4274 rt2800_rfcsr_write(rt2x00dev, 55, 0x43); 4274 rt2800_rfcsr_write(rt2x00dev, 55, 0x43);
4275 rt2800_rfcsr_write(rt2x00dev, 56, 0xa1); 4275 rt2800_rfcsr_write(rt2x00dev, 56, 0xa1);
4276 rt2800_rfcsr_write(rt2x00dev, 57, 0x00); 4276 rt2800_rfcsr_write(rt2x00dev, 57, 0x00);
4277 rt2800_rfcsr_write(rt2x00dev, 58, 0x39); 4277 rt2800_rfcsr_write(rt2x00dev, 58, 0x39);
4278 rt2800_rfcsr_write(rt2x00dev, 59, 0x07); 4278 rt2800_rfcsr_write(rt2x00dev, 59, 0x07);
4279 rt2800_rfcsr_write(rt2x00dev, 60, 0x45); 4279 rt2800_rfcsr_write(rt2x00dev, 60, 0x45);
4280 rt2800_rfcsr_write(rt2x00dev, 61, 0x91); 4280 rt2800_rfcsr_write(rt2x00dev, 61, 0x91);
4281 rt2800_rfcsr_write(rt2x00dev, 62, 0x39); 4281 rt2800_rfcsr_write(rt2x00dev, 62, 0x39);
4282 rt2800_rfcsr_write(rt2x00dev, 63, 0x07); 4282 rt2800_rfcsr_write(rt2x00dev, 63, 0x07);
4283 } 4283 }
4284 4284
4285 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) { 4285 if (rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070F)) {
@@ -4356,7 +4356,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4356 rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26); 4356 rt2800_bbp_read(rt2x00dev, 26, &drv_data->bbp26);
4357 4357
4358 if (!rt2x00_rt(rt2x00dev, RT5390) && 4358 if (!rt2x00_rt(rt2x00dev, RT5390) &&
4359 !rt2x00_rt(rt2x00dev, RT5392)) { 4359 !rt2x00_rt(rt2x00dev, RT5392)) {
4360 /* 4360 /*
4361 * Set back to initial state 4361 * Set back to initial state
4362 */ 4362 */
@@ -4385,7 +4385,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4385 rt2800_register_write(rt2x00dev, OPT_14_CSR, reg); 4385 rt2800_register_write(rt2x00dev, OPT_14_CSR, reg);
4386 4386
4387 if (!rt2x00_rt(rt2x00dev, RT5390) && 4387 if (!rt2x00_rt(rt2x00dev, RT5390) &&
4388 !rt2x00_rt(rt2x00dev, RT5392)) { 4388 !rt2x00_rt(rt2x00dev, RT5392)) {
4389 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr); 4389 rt2800_rfcsr_read(rt2x00dev, 17, &rfcsr);
4390 rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0); 4390 rt2x00_set_field8(&rfcsr, RFCSR17_TX_LO1_EN, 0);
4391 if (rt2x00_rt(rt2x00dev, RT3070) || 4391 if (rt2x00_rt(rt2x00dev, RT3070) ||
@@ -4457,7 +4457,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev)
4457 } 4457 }
4458 4458
4459 if (rt2x00_rt(rt2x00dev, RT5390) || 4459 if (rt2x00_rt(rt2x00dev, RT5390) ||
4460 rt2x00_rt(rt2x00dev, RT5392)) { 4460 rt2x00_rt(rt2x00dev, RT5392)) {
4461 rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr); 4461 rt2800_rfcsr_read(rt2x00dev, 38, &rfcsr);
4462 rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0); 4462 rt2x00_set_field8(&rfcsr, RFCSR38_RX_LO1_EN, 0);
4463 rt2800_rfcsr_write(rt2x00dev, 38, rfcsr); 4463 rt2800_rfcsr_write(rt2x00dev, 38, rfcsr);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 27829e1e2e38..9224d874bf24 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -1176,7 +1176,7 @@ static struct platform_driver rt2800soc_driver = {
1176 .mod_name = KBUILD_MODNAME, 1176 .mod_name = KBUILD_MODNAME,
1177 }, 1177 },
1178 .probe = rt2800soc_probe, 1178 .probe = rt2800soc_probe,
1179 .remove = __devexit_p(rt2x00soc_remove), 1179 .remove = rt2x00soc_remove,
1180 .suspend = rt2x00soc_suspend, 1180 .suspend = rt2x00soc_suspend,
1181 .resume = rt2x00soc_resume, 1181 .resume = rt2x00soc_resume,
1182}; 1182};
@@ -1193,7 +1193,7 @@ static struct pci_driver rt2800pci_driver = {
1193 .name = KBUILD_MODNAME, 1193 .name = KBUILD_MODNAME,
1194 .id_table = rt2800pci_device_table, 1194 .id_table = rt2800pci_device_table,
1195 .probe = rt2800pci_probe, 1195 .probe = rt2800pci_probe,
1196 .remove = __devexit_p(rt2x00pci_remove), 1196 .remove = rt2x00pci_remove,
1197 .suspend = rt2x00pci_suspend, 1197 .suspend = rt2x00pci_suspend,
1198 .resume = rt2x00pci_resume, 1198 .resume = rt2x00pci_resume,
1199}; 1199};
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 67d167993d45..3248b4224c4e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -1124,6 +1124,9 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev)
1124 struct ieee80211_iface_limit *if_limit; 1124 struct ieee80211_iface_limit *if_limit;
1125 struct ieee80211_iface_combination *if_combination; 1125 struct ieee80211_iface_combination *if_combination;
1126 1126
1127 if (rt2x00dev->ops->max_ap_intf < 2)
1128 return;
1129
1127 /* 1130 /*
1128 * Build up AP interface limits structure. 1131 * Build up AP interface limits structure.
1129 */ 1132 */
@@ -1183,6 +1186,13 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev)
1183 rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); 1186 rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf);
1184 1187
1185 /* 1188 /*
1189 * rt2x00 devices can only use the last n bits of the MAC address
1190 * for virtual interfaces.
1191 */
1192 rt2x00dev->hw->wiphy->addr_mask[ETH_ALEN - 1] =
1193 (rt2x00dev->ops->max_ap_intf - 1);
1194
1195 /*
1186 * Determine which operating modes are supported, all modes 1196 * Determine which operating modes are supported, all modes
1187 * which require beaconing, depend on the availability of 1197 * which require beaconing, depend on the availability of
1188 * beacon entries. 1198 * beacon entries.
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index d6582a2fa353..f95792cfcf89 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -3094,7 +3094,7 @@ static struct pci_driver rt61pci_driver = {
3094 .name = KBUILD_MODNAME, 3094 .name = KBUILD_MODNAME,
3095 .id_table = rt61pci_device_table, 3095 .id_table = rt61pci_device_table,
3096 .probe = rt61pci_probe, 3096 .probe = rt61pci_probe,
3097 .remove = __devexit_p(rt2x00pci_remove), 3097 .remove = rt2x00pci_remove,
3098 .suspend = rt2x00pci_suspend, 3098 .suspend = rt2x00pci_suspend,
3099 .resume = rt2x00pci_resume, 3099 .resume = rt2x00pci_resume,
3100}; 3100};
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index b4218a5f2066..1b3c2843221d 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -901,7 +901,7 @@ static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
901 udelay(10); 901 udelay(10);
902} 902}
903 903
904static int __devinit rtl8180_probe(struct pci_dev *pdev, 904static int rtl8180_probe(struct pci_dev *pdev,
905 const struct pci_device_id *id) 905 const struct pci_device_id *id)
906{ 906{
907 struct ieee80211_hw *dev; 907 struct ieee80211_hw *dev;
@@ -1131,7 +1131,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
1131 return err; 1131 return err;
1132} 1132}
1133 1133
1134static void __devexit rtl8180_remove(struct pci_dev *pdev) 1134static void rtl8180_remove(struct pci_dev *pdev)
1135{ 1135{
1136 struct ieee80211_hw *dev = pci_get_drvdata(pdev); 1136 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1137 struct rtl8180_priv *priv; 1137 struct rtl8180_priv *priv;
@@ -1170,7 +1170,7 @@ static struct pci_driver rtl8180_driver = {
1170 .name = KBUILD_MODNAME, 1170 .name = KBUILD_MODNAME,
1171 .id_table = rtl8180_table, 1171 .id_table = rtl8180_table,
1172 .probe = rtl8180_probe, 1172 .probe = rtl8180_probe,
1173 .remove = __devexit_p(rtl8180_remove), 1173 .remove = rtl8180_remove,
1174#ifdef CONFIG_PM 1174#ifdef CONFIG_PM
1175 .suspend = rtl8180_suspend, 1175 .suspend = rtl8180_suspend,
1176 .resume = rtl8180_resume, 1176 .resume = rtl8180_resume,
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 52e6bebcf089..4574bd213705 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -1411,7 +1411,7 @@ static void rtl8187_eeprom_register_write(struct eeprom_93cx6 *eeprom)
1411 udelay(10); 1411 udelay(10);
1412} 1412}
1413 1413
1414static int __devinit rtl8187_probe(struct usb_interface *intf, 1414static int rtl8187_probe(struct usb_interface *intf,
1415 const struct usb_device_id *id) 1415 const struct usb_device_id *id)
1416{ 1416{
1417 struct usb_device *udev = interface_to_usbdev(intf); 1417 struct usb_device *udev = interface_to_usbdev(intf);
@@ -1639,7 +1639,7 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
1639 return err; 1639 return err;
1640} 1640}
1641 1641
1642static void __devexit rtl8187_disconnect(struct usb_interface *intf) 1642static void rtl8187_disconnect(struct usb_interface *intf)
1643{ 1643{
1644 struct ieee80211_hw *dev = usb_get_intfdata(intf); 1644 struct ieee80211_hw *dev = usb_get_intfdata(intf);
1645 struct rtl8187_priv *priv; 1645 struct rtl8187_priv *priv;
@@ -1664,7 +1664,7 @@ static struct usb_driver rtl8187_driver = {
1664 .name = KBUILD_MODNAME, 1664 .name = KBUILD_MODNAME,
1665 .id_table = rtl8187_table, 1665 .id_table = rtl8187_table,
1666 .probe = rtl8187_probe, 1666 .probe = rtl8187_probe,
1667 .disconnect = __devexit_p(rtl8187_disconnect), 1667 .disconnect = rtl8187_disconnect,
1668 .disable_hub_initiated_lpm = 1, 1668 .disable_hub_initiated_lpm = 1,
1669}; 1669};
1670 1670
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index f38e30a947bc..3deacafdcd5e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -1756,7 +1756,7 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev,
1756 return true; 1756 return true;
1757} 1757}
1758 1758
1759int __devinit rtl_pci_probe(struct pci_dev *pdev, 1759int rtl_pci_probe(struct pci_dev *pdev,
1760 const struct pci_device_id *id) 1760 const struct pci_device_id *id)
1761{ 1761{
1762 struct ieee80211_hw *hw = NULL; 1762 struct ieee80211_hw *hw = NULL;
@@ -1982,6 +1982,7 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
1982} 1982}
1983EXPORT_SYMBOL(rtl_pci_disconnect); 1983EXPORT_SYMBOL(rtl_pci_disconnect);
1984 1984
1985#ifdef CONFIG_PM_SLEEP
1985/*************************************** 1986/***************************************
1986kernel pci power state define: 1987kernel pci power state define:
1987PCI_D0 ((pci_power_t __force) 0) 1988PCI_D0 ((pci_power_t __force) 0)
@@ -2021,6 +2022,7 @@ int rtl_pci_resume(struct device *dev)
2021 return 0; 2022 return 0;
2022} 2023}
2023EXPORT_SYMBOL(rtl_pci_resume); 2024EXPORT_SYMBOL(rtl_pci_resume);
2025#endif /* CONFIG_PM_SLEEP */
2024 2026
2025struct rtl_intf_ops rtl_pci_ops = { 2027struct rtl_intf_ops rtl_pci_ops = {
2026 .read_efuse_byte = read_efuse_byte, 2028 .read_efuse_byte = read_efuse_byte,
diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h
index f71b12aa8cb4..65b08f50022e 100644
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -236,11 +236,13 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw);
236 236
237extern struct rtl_intf_ops rtl_pci_ops; 237extern struct rtl_intf_ops rtl_pci_ops;
238 238
239int __devinit rtl_pci_probe(struct pci_dev *pdev, 239int rtl_pci_probe(struct pci_dev *pdev,
240 const struct pci_device_id *id); 240 const struct pci_device_id *id);
241void rtl_pci_disconnect(struct pci_dev *pdev); 241void rtl_pci_disconnect(struct pci_dev *pdev);
242#ifdef CONFIG_PM_SLEEP
242int rtl_pci_suspend(struct device *dev); 243int rtl_pci_suspend(struct device *dev);
243int rtl_pci_resume(struct device *dev); 244int rtl_pci_resume(struct device *dev);
245#endif /* CONFIG_PM_SLEEP */
244static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) 246static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
245{ 247{
246 return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); 248 return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
index 60451eea4d82..49f663bd93ff 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -372,14 +372,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
372MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 372MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
373MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 373MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
374 374
375static const struct dev_pm_ops rtlwifi_pm_ops = { 375static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
376 .suspend = rtl_pci_suspend,
377 .resume = rtl_pci_resume,
378 .freeze = rtl_pci_suspend,
379 .thaw = rtl_pci_resume,
380 .poweroff = rtl_pci_suspend,
381 .restore = rtl_pci_resume,
382};
383 376
384static struct pci_driver rtl92ce_driver = { 377static struct pci_driver rtl92ce_driver = {
385 .name = KBUILD_MODNAME, 378 .name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
index 480862c07f92..03c6d18b2e07 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -352,7 +352,7 @@ static struct rtl_hal_cfg rtl92de_hal_cfg = {
352 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 352 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
353}; 353};
354 354
355static struct pci_device_id rtl92de_pci_ids[] __devinitdata = { 355static struct pci_device_id rtl92de_pci_ids[] = {
356 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)}, 356 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8193, rtl92de_hal_cfg)},
357 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)}, 357 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x002B, rtl92de_hal_cfg)},
358 {}, 358 {},
@@ -378,14 +378,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
378MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 378MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
379MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 379MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
380 380
381static const struct dev_pm_ops rtlwifi_pm_ops = { 381static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
382 .suspend = rtl_pci_suspend,
383 .resume = rtl_pci_resume,
384 .freeze = rtl_pci_suspend,
385 .thaw = rtl_pci_resume,
386 .poweroff = rtl_pci_suspend,
387 .restore = rtl_pci_resume,
388};
389 382
390static struct pci_driver rtl92de_driver = { 383static struct pci_driver rtl92de_driver = {
391 .name = KBUILD_MODNAME, 384 .name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
index 20afec62ce05..2d255e02d795 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h
@@ -522,8 +522,7 @@ enum fwcmd_iotype {
522 FW_CMD_IQK_ENABLE = 30, 522 FW_CMD_IQK_ENABLE = 30,
523}; 523};
524 524
525/* 525/* Driver info contain PHY status
526 * Driver info contain PHY status
527 * and other variabel size info 526 * and other variabel size info
528 * PHY Status content as below 527 * PHY Status content as below
529 */ 528 */
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
index bf79a52c8a52..e551fe5f9ccd 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c
@@ -465,8 +465,8 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
465 digtable->cur_igvalue = 465 digtable->cur_igvalue =
466 digtable->rx_gain_range_min; 466 digtable->rx_gain_range_min;
467 else 467 else
468 digtable->cur_igvalue = digtable->rssi_val + 10 - 468 digtable->cur_igvalue = digtable->rssi_val + 10
469 digtable->back_val; 469 - digtable->back_val;
470 470
471 if (falsealm_cnt->cnt_all > 10000) 471 if (falsealm_cnt->cnt_all > 10000)
472 digtable->cur_igvalue = 472 digtable->cur_igvalue =
@@ -518,7 +518,7 @@ static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
518static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw) 518static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
519{ 519{
520 struct rtl_priv *rtlpriv = rtl_priv(hw); 520 struct rtl_priv *rtlpriv = rtl_priv(hw);
521 struct dig_t *digtable = &rtlpriv->dm_digtable; 521 struct dig_t *dig = &rtlpriv->dm_digtable;
522 522
523 if (rtlpriv->mac80211.act_scanning) 523 if (rtlpriv->mac80211.act_scanning)
524 return; 524 return;
@@ -526,17 +526,17 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
526 /* Decide the current status and if modify initial gain or not */ 526 /* Decide the current status and if modify initial gain or not */
527 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED || 527 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
528 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) 528 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
529 digtable->cur_sta_cstate = DIG_STA_CONNECT; 529 dig->cur_sta_cstate = DIG_STA_CONNECT;
530 else 530 else
531 digtable->cur_sta_cstate = DIG_STA_DISCONNECT; 531 dig->cur_sta_cstate = DIG_STA_DISCONNECT;
532 532
533 digtable->rssi_val = rtlpriv->dm.undec_sm_pwdb; 533 dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
534 534
535 /* Change dig mode to rssi */ 535 /* Change dig mode to rssi */
536 if (digtable->cur_sta_cstate != DIG_STA_DISCONNECT) { 536 if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
537 if (digtable->dig_twoport_algorithm == 537 if (dig->dig_twoport_algorithm ==
538 DIG_TWO_PORT_ALGO_FALSE_ALARM) { 538 DIG_TWO_PORT_ALGO_FALSE_ALARM) {
539 digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI; 539 dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
540 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS); 540 rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
541 } 541 }
542 } 542 }
@@ -544,7 +544,7 @@ static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
544 _rtl92s_dm_false_alarm_counter_statistics(hw); 544 _rtl92s_dm_false_alarm_counter_statistics(hw);
545 _rtl92s_dm_initial_gain_sta_beforeconnect(hw); 545 _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
546 546
547 digtable->pre_sta_cstate = digtable->cur_sta_cstate; 547 dig->pre_sta_cstate = dig->cur_sta_cstate;
548} 548}
549 549
550static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw) 550static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index 1d72779434ba..28526a7361f5 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -1089,8 +1089,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw)
1089 return err; 1089 return err;
1090} 1090}
1091 1091
1092void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr) 1092void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr)
1093{ 1093{
1094 /* This is a stub. */
1094} 1095}
1095 1096
1096void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 1097void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
index 1886c2644a26..a8e068c76e47 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h
@@ -54,7 +54,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw);
54int rtl92se_set_network_type(struct ieee80211_hw *hw, 54int rtl92se_set_network_type(struct ieee80211_hw *hw,
55 enum nl80211_iftype type); 55 enum nl80211_iftype type);
56void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid); 56void rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid);
57void rtl92se_set_mac_addr(struct rtl_io *io, const u8 * addr); 57void rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr);
58void rtl92se_set_qos(struct ieee80211_hw *hw, int aci); 58void rtl92se_set_qos(struct ieee80211_hw *hw, int aci);
59void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw); 59void rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw);
60void rtl92se_set_beacon_interval(struct ieee80211_hw *hw); 60void rtl92se_set_beacon_interval(struct ieee80211_hw *hw);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
index ad4b4803482d..cecc377e9e61 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -50,8 +50,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
50 /*close ASPM for AMD defaultly */ 50 /*close ASPM for AMD defaultly */
51 rtlpci->const_amdpci_aspm = 0; 51 rtlpci->const_amdpci_aspm = 0;
52 52
53 /* 53 /* ASPM PS mode.
54 * ASPM PS mode.
55 * 0 - Disable ASPM, 54 * 0 - Disable ASPM,
56 * 1 - Enable ASPM without Clock Req, 55 * 1 - Enable ASPM without Clock Req,
57 * 2 - Enable ASPM with Clock Req, 56 * 2 - Enable ASPM with Clock Req,
@@ -67,8 +66,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
67 /*Setting for PCI-E bridge */ 66 /*Setting for PCI-E bridge */
68 rtlpci->const_hostpci_aspm_setting = 0x02; 67 rtlpci->const_hostpci_aspm_setting = 0x02;
69 68
70 /* 69 /* In Hw/Sw Radio Off situation.
71 * In Hw/Sw Radio Off situation.
72 * 0 - Default, 70 * 0 - Default,
73 * 1 - From ASPM setting without low Mac Pwr, 71 * 1 - From ASPM setting without low Mac Pwr,
74 * 2 - From ASPM setting with low Mac Pwr, 72 * 2 - From ASPM setting with low Mac Pwr,
@@ -77,8 +75,7 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw)
77 */ 75 */
78 rtlpci->const_hwsw_rfoff_d3 = 2; 76 rtlpci->const_hwsw_rfoff_d3 = 2;
79 77
80 /* 78 /* This setting works for those device with
81 * This setting works for those device with
82 * backdoor ASPM setting such as EPHY setting. 79 * backdoor ASPM setting such as EPHY setting.
83 * 0 - Not support ASPM, 80 * 0 - Not support ASPM,
84 * 1 - Support ASPM, 81 * 1 - Support ASPM,
@@ -403,7 +400,7 @@ static struct rtl_hal_cfg rtl92se_hal_cfg = {
403 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15, 400 .maps[RTL_RC_HT_RATEMCS15] = DESC92_RATEMCS15,
404}; 401};
405 402
406static struct pci_device_id rtl92se_pci_ids[] __devinitdata = { 403static struct pci_device_id rtl92se_pci_ids[] = {
407 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)}, 404 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8192, rtl92se_hal_cfg)},
408 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)}, 405 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8171, rtl92se_hal_cfg)},
409 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)}, 406 {RTL_PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8172, rtl92se_hal_cfg)},
@@ -432,14 +429,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
432MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 429MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
433MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 430MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
434 431
435static const struct dev_pm_ops rtlwifi_pm_ops = { 432static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
436 .suspend = rtl_pci_suspend,
437 .resume = rtl_pci_resume,
438 .freeze = rtl_pci_suspend,
439 .thaw = rtl_pci_resume,
440 .poweroff = rtl_pci_suspend,
441 .restore = rtl_pci_resume,
442};
443 433
444static struct pci_driver rtl92se_driver = { 434static struct pci_driver rtl92se_driver = {
445 .name = KBUILD_MODNAME, 435 .name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index 0afdc240f2fd..18b0bc51766b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -367,14 +367,7 @@ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
367MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 367MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
368MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 368MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
369 369
370static const struct dev_pm_ops rtlwifi_pm_ops = { 370static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
371 .suspend = rtl_pci_suspend,
372 .resume = rtl_pci_resume,
373 .freeze = rtl_pci_suspend,
374 .thaw = rtl_pci_resume,
375 .poweroff = rtl_pci_suspend,
376 .restore = rtl_pci_resume,
377};
378 371
379static struct pci_driver rtl8723ae_driver = { 372static struct pci_driver rtl8723ae_driver = {
380 .name = KBUILD_MODNAME, 373 .name = KBUILD_MODNAME,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index e3ea4b346889..29f0969e4ba0 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -940,7 +940,7 @@ static struct rtl_intf_ops rtl_usb_ops = {
940 .waitq_insert = rtl_usb_tx_chk_waitq_insert, 940 .waitq_insert = rtl_usb_tx_chk_waitq_insert,
941}; 941};
942 942
943int __devinit rtl_usb_probe(struct usb_interface *intf, 943int rtl_usb_probe(struct usb_interface *intf,
944 const struct usb_device_id *id) 944 const struct usb_device_id *id)
945{ 945{
946 int err; 946 int err;
diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h
index 43846b329153..5235136f6dd2 100644
--- a/drivers/net/wireless/rtlwifi/usb.h
+++ b/drivers/net/wireless/rtlwifi/usb.h
@@ -156,7 +156,7 @@ struct rtl_usb_priv {
156 156
157 157
158 158
159int __devinit rtl_usb_probe(struct usb_interface *intf, 159int rtl_usb_probe(struct usb_interface *intf,
160 const struct usb_device_id *id); 160 const struct usb_device_id *id);
161void rtl_usb_disconnect(struct usb_interface *intf); 161void rtl_usb_disconnect(struct usb_interface *intf);
162int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message); 162int rtl_usb_suspend(struct usb_interface *pusb_intf, pm_message_t message);
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 441cbccbd381..f47e8b0482ad 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -896,11 +896,13 @@ static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
896 goto out; 896 goto out;
897 897
898 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len, 898 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
899 req->ie, req->ie_len); 899 req->ie_len);
900 if (!skb) { 900 if (!skb) {
901 ret = -ENOMEM; 901 ret = -ENOMEM;
902 goto out; 902 goto out;
903 } 903 }
904 if (req->ie_len)
905 memcpy(skb_put(skb, req->ie_len), req->ie, req->ie_len);
904 906
905 ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data, 907 ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
906 skb->len); 908 skb->len);
diff --git a/drivers/net/wireless/ti/wl1251/sdio.c b/drivers/net/wireless/ti/wl1251/sdio.c
index e2750a12c6f1..e57ee48edff6 100644
--- a/drivers/net/wireless/ti/wl1251/sdio.c
+++ b/drivers/net/wireless/ti/wl1251/sdio.c
@@ -305,7 +305,7 @@ out_free_hw:
305 return ret; 305 return ret;
306} 306}
307 307
308static void __devexit wl1251_sdio_remove(struct sdio_func *func) 308static void wl1251_sdio_remove(struct sdio_func *func)
309{ 309{
310 struct wl1251 *wl = sdio_get_drvdata(func); 310 struct wl1251 *wl = sdio_get_drvdata(func);
311 struct wl1251_sdio *wl_sdio = wl->if_priv; 311 struct wl1251_sdio *wl_sdio = wl->if_priv;
@@ -347,7 +347,7 @@ static struct sdio_driver wl1251_sdio_driver = {
347 .name = "wl1251_sdio", 347 .name = "wl1251_sdio",
348 .id_table = wl1251_devices, 348 .id_table = wl1251_devices,
349 .probe = wl1251_sdio_probe, 349 .probe = wl1251_sdio_probe,
350 .remove = __devexit_p(wl1251_sdio_remove), 350 .remove = wl1251_sdio_remove,
351 .drv.pm = &wl1251_sdio_pm_ops, 351 .drv.pm = &wl1251_sdio_pm_ops,
352}; 352};
353 353
diff --git a/drivers/net/wireless/ti/wl1251/spi.c b/drivers/net/wireless/ti/wl1251/spi.c
index 567660cd2fcd..3b266d3231a3 100644
--- a/drivers/net/wireless/ti/wl1251/spi.c
+++ b/drivers/net/wireless/ti/wl1251/spi.c
@@ -237,7 +237,7 @@ static const struct wl1251_if_operations wl1251_spi_ops = {
237 .power = wl1251_spi_set_power, 237 .power = wl1251_spi_set_power,
238}; 238};
239 239
240static int __devinit wl1251_spi_probe(struct spi_device *spi) 240static int wl1251_spi_probe(struct spi_device *spi)
241{ 241{
242 struct wl12xx_platform_data *pdata; 242 struct wl12xx_platform_data *pdata;
243 struct ieee80211_hw *hw; 243 struct ieee80211_hw *hw;
@@ -309,7 +309,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
309 return ret; 309 return ret;
310} 310}
311 311
312static int __devexit wl1251_spi_remove(struct spi_device *spi) 312static int wl1251_spi_remove(struct spi_device *spi)
313{ 313{
314 struct wl1251 *wl = dev_get_drvdata(&spi->dev); 314 struct wl1251 *wl = dev_get_drvdata(&spi->dev);
315 315
@@ -326,7 +326,7 @@ static struct spi_driver wl1251_spi_driver = {
326 }, 326 },
327 327
328 .probe = wl1251_spi_probe, 328 .probe = wl1251_spi_probe,
329 .remove = __devexit_p(wl1251_spi_remove), 329 .remove = wl1251_spi_remove,
330}; 330};
331 331
332static int __init wl1251_spi_init(void) 332static int __init wl1251_spi_init(void)
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index dadf1dbb002a..e5f5f8f39144 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -1696,7 +1696,7 @@ static int wl12xx_setup(struct wl1271 *wl)
1696 return 0; 1696 return 0;
1697} 1697}
1698 1698
1699static int __devinit wl12xx_probe(struct platform_device *pdev) 1699static int wl12xx_probe(struct platform_device *pdev)
1700{ 1700{
1701 struct wl1271 *wl; 1701 struct wl1271 *wl;
1702 struct ieee80211_hw *hw; 1702 struct ieee80211_hw *hw;
@@ -1725,7 +1725,7 @@ out:
1725 return ret; 1725 return ret;
1726} 1726}
1727 1727
1728static const struct platform_device_id wl12xx_id_table[] __devinitconst = { 1728static const struct platform_device_id wl12xx_id_table[] = {
1729 { "wl12xx", 0 }, 1729 { "wl12xx", 0 },
1730 { } /* Terminating Entry */ 1730 { } /* Terminating Entry */
1731}; 1731};
@@ -1733,7 +1733,7 @@ MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
1733 1733
1734static struct platform_driver wl12xx_driver = { 1734static struct platform_driver wl12xx_driver = {
1735 .probe = wl12xx_probe, 1735 .probe = wl12xx_probe,
1736 .remove = __devexit_p(wlcore_remove), 1736 .remove = wlcore_remove,
1737 .id_table = wl12xx_id_table, 1737 .id_table = wl12xx_id_table,
1738 .driver = { 1738 .driver = {
1739 .name = "wl12xx_driver", 1739 .name = "wl12xx_driver",
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index a39682a7c25f..8d8c1f8c63b7 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -1499,7 +1499,7 @@ static int wl18xx_setup(struct wl1271 *wl)
1499 return 0; 1499 return 0;
1500} 1500}
1501 1501
1502static int __devinit wl18xx_probe(struct platform_device *pdev) 1502static int wl18xx_probe(struct platform_device *pdev)
1503{ 1503{
1504 struct wl1271 *wl; 1504 struct wl1271 *wl;
1505 struct ieee80211_hw *hw; 1505 struct ieee80211_hw *hw;
@@ -1528,7 +1528,7 @@ out:
1528 return ret; 1528 return ret;
1529} 1529}
1530 1530
1531static const struct platform_device_id wl18xx_id_table[] __devinitconst = { 1531static const struct platform_device_id wl18xx_id_table[] = {
1532 { "wl18xx", 0 }, 1532 { "wl18xx", 0 },
1533 { } /* Terminating Entry */ 1533 { } /* Terminating Entry */
1534}; 1534};
@@ -1536,7 +1536,7 @@ MODULE_DEVICE_TABLE(platform, wl18xx_id_table);
1536 1536
1537static struct platform_driver wl18xx_driver = { 1537static struct platform_driver wl18xx_driver = {
1538 .probe = wl18xx_probe, 1538 .probe = wl18xx_probe,
1539 .remove = __devexit_p(wlcore_remove), 1539 .remove = wlcore_remove,
1540 .id_table = wl18xx_id_table, 1540 .id_table = wl18xx_id_table,
1541 .driver = { 1541 .driver = {
1542 .name = "wl18xx_driver", 1542 .name = "wl18xx_driver",
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c
index eaef3f41b252..27f83f72a93b 100644
--- a/drivers/net/wireless/ti/wlcore/cmd.c
+++ b/drivers/net/wireless/ti/wlcore/cmd.c
@@ -1038,11 +1038,13 @@ int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1038 u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 1038 u16 template_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
1039 1039
1040 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len, 1040 skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1041 ie, ie_len); 1041 ie_len);
1042 if (!skb) { 1042 if (!skb) {
1043 ret = -ENOMEM; 1043 ret = -ENOMEM;
1044 goto out; 1044 goto out;
1045 } 1045 }
1046 if (ie_len)
1047 memcpy(skb_put(skb, ie_len), ie, ie_len);
1046 1048
1047 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len); 1049 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
1048 1050
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 4f1a05b92d2d..ea9d8e011bc9 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5660,7 +5660,7 @@ out:
5660 complete_all(&wl->nvs_loading_complete); 5660 complete_all(&wl->nvs_loading_complete);
5661} 5661}
5662 5662
5663int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev) 5663int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5664{ 5664{
5665 int ret; 5665 int ret;
5666 5666
@@ -5683,7 +5683,7 @@ int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev)
5683} 5683}
5684EXPORT_SYMBOL_GPL(wlcore_probe); 5684EXPORT_SYMBOL_GPL(wlcore_probe);
5685 5685
5686int __devexit wlcore_remove(struct platform_device *pdev) 5686int wlcore_remove(struct platform_device *pdev)
5687{ 5687{
5688 struct wl1271 *wl = platform_get_drvdata(pdev); 5688 struct wl1271 *wl = platform_get_drvdata(pdev);
5689 5689
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 73ace4b2604e..646f703ae739 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -54,7 +54,7 @@ struct wl12xx_sdio_glue {
54 struct platform_device *core; 54 struct platform_device *core;
55}; 55};
56 56
57static const struct sdio_device_id wl1271_devices[] __devinitconst = { 57static const struct sdio_device_id wl1271_devices[] = {
58 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) }, 58 { SDIO_DEVICE(SDIO_VENDOR_ID_TI, SDIO_DEVICE_ID_TI_WL1271) },
59 {} 59 {}
60}; 60};
@@ -214,7 +214,7 @@ static struct wl1271_if_operations sdio_ops = {
214 .set_block_size = wl1271_sdio_set_block_size, 214 .set_block_size = wl1271_sdio_set_block_size,
215}; 215};
216 216
217static int __devinit wl1271_probe(struct sdio_func *func, 217static int wl1271_probe(struct sdio_func *func,
218 const struct sdio_device_id *id) 218 const struct sdio_device_id *id)
219{ 219{
220 struct wl12xx_platform_data *wlan_data; 220 struct wl12xx_platform_data *wlan_data;
@@ -319,7 +319,7 @@ out:
319 return ret; 319 return ret;
320} 320}
321 321
322static void __devexit wl1271_remove(struct sdio_func *func) 322static void wl1271_remove(struct sdio_func *func)
323{ 323{
324 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func); 324 struct wl12xx_sdio_glue *glue = sdio_get_drvdata(func);
325 325
@@ -384,7 +384,7 @@ static struct sdio_driver wl1271_sdio_driver = {
384 .name = "wl1271_sdio", 384 .name = "wl1271_sdio",
385 .id_table = wl1271_devices, 385 .id_table = wl1271_devices,
386 .probe = wl1271_probe, 386 .probe = wl1271_probe,
387 .remove = __devexit_p(wl1271_remove), 387 .remove = wl1271_remove,
388#ifdef CONFIG_PM 388#ifdef CONFIG_PM
389 .drv = { 389 .drv = {
390 .pm = &wl1271_sdio_pm_ops, 390 .pm = &wl1271_sdio_pm_ops,
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index a519bc3adec1..f06f4770ce02 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -324,7 +324,7 @@ static struct wl1271_if_operations spi_ops = {
324 .set_block_size = NULL, 324 .set_block_size = NULL,
325}; 325};
326 326
327static int __devinit wl1271_probe(struct spi_device *spi) 327static int wl1271_probe(struct spi_device *spi)
328{ 328{
329 struct wl12xx_spi_glue *glue; 329 struct wl12xx_spi_glue *glue;
330 struct wl12xx_platform_data *pdata; 330 struct wl12xx_platform_data *pdata;
@@ -403,7 +403,7 @@ out:
403 return ret; 403 return ret;
404} 404}
405 405
406static int __devexit wl1271_remove(struct spi_device *spi) 406static int wl1271_remove(struct spi_device *spi)
407{ 407{
408 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi); 408 struct wl12xx_spi_glue *glue = spi_get_drvdata(spi);
409 409
@@ -422,7 +422,7 @@ static struct spi_driver wl1271_spi_driver = {
422 }, 422 },
423 423
424 .probe = wl1271_probe, 424 .probe = wl1271_probe,
425 .remove = __devexit_p(wl1271_remove), 425 .remove = wl1271_remove,
426}; 426};
427 427
428static int __init wl1271_init(void) 428static int __init wl1271_init(void)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 68584aa0f2b0..c3884937c007 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -414,8 +414,8 @@ struct wl1271 {
414 struct completion nvs_loading_complete; 414 struct completion nvs_loading_complete;
415}; 415};
416 416
417int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); 417int wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
418int __devexit wlcore_remove(struct platform_device *pdev); 418int wlcore_remove(struct platform_device *pdev);
419struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size); 419struct ieee80211_hw *wlcore_alloc_hw(size_t priv_size, u32 aggr_buf_size);
420int wlcore_free_hw(struct wl1271 *wl); 420int wlcore_free_hw(struct wl1271 *wl);
421int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd, 421int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c
index e9d2ca11283b..95c33a05f434 100644
--- a/drivers/ssb/driver_chipcommon.c
+++ b/drivers/ssb/driver_chipcommon.c
@@ -4,6 +4,7 @@
4 * 4 *
5 * Copyright 2005, Broadcom Corporation 5 * Copyright 2005, Broadcom Corporation
6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch> 6 * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7 * 8 *
8 * Licensed under the GNU/GPL. See COPYING for details. 9 * Licensed under the GNU/GPL. See COPYING for details.
9 */ 10 */
@@ -12,6 +13,7 @@
12#include <linux/ssb/ssb_regs.h> 13#include <linux/ssb/ssb_regs.h>
13#include <linux/export.h> 14#include <linux/export.h>
14#include <linux/pci.h> 15#include <linux/pci.h>
16#include <linux/bcm47xx_wdt.h>
15 17
16#include "ssb_private.h" 18#include "ssb_private.h"
17 19
@@ -280,6 +282,69 @@ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc)
280 cc->fast_pwrup_delay = tmp; 282 cc->fast_pwrup_delay = tmp;
281} 283}
282 284
285static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc)
286{
287 if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
288 return ssb_pmu_get_alp_clock(cc);
289
290 return 20000000;
291}
292
293static u32 ssb_chipco_watchdog_get_max_timer(struct ssb_chipcommon *cc)
294{
295 u32 nb;
296
297 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
298 if (cc->dev->id.revision < 26)
299 nb = 16;
300 else
301 nb = (cc->dev->id.revision >= 37) ? 32 : 24;
302 } else {
303 nb = 28;
304 }
305 if (nb == 32)
306 return 0xffffffff;
307 else
308 return (1 << nb) - 1;
309}
310
311u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
312{
313 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
314
315 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
316 return 0;
317
318 return ssb_chipco_watchdog_timer_set(cc, ticks);
319}
320
321u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
322{
323 struct ssb_chipcommon *cc = bcm47xx_wdt_get_drvdata(wdt);
324 u32 ticks;
325
326 if (cc->dev->bus->bustype != SSB_BUSTYPE_SSB)
327 return 0;
328
329 ticks = ssb_chipco_watchdog_timer_set(cc, cc->ticks_per_ms * ms);
330 return ticks / cc->ticks_per_ms;
331}
332
333static int ssb_chipco_watchdog_ticks_per_ms(struct ssb_chipcommon *cc)
334{
335 struct ssb_bus *bus = cc->dev->bus;
336
337 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
338 /* based on 32KHz ILP clock */
339 return 32;
340 } else {
341 if (cc->dev->id.revision < 18)
342 return ssb_clockspeed(bus) / 1000;
343 else
344 return ssb_chipco_alp_clock(cc) / 1000;
345 }
346}
347
283void ssb_chipcommon_init(struct ssb_chipcommon *cc) 348void ssb_chipcommon_init(struct ssb_chipcommon *cc)
284{ 349{
285 if (!cc->dev) 350 if (!cc->dev)
@@ -297,6 +362,11 @@ void ssb_chipcommon_init(struct ssb_chipcommon *cc)
297 chipco_powercontrol_init(cc); 362 chipco_powercontrol_init(cc);
298 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST); 363 ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
299 calc_fast_powerup_delay(cc); 364 calc_fast_powerup_delay(cc);
365
366 if (cc->dev->bus->bustype == SSB_BUSTYPE_SSB) {
367 cc->ticks_per_ms = ssb_chipco_watchdog_ticks_per_ms(cc);
368 cc->max_timer_ms = ssb_chipco_watchdog_get_max_timer(cc) / cc->ticks_per_ms;
369 }
300} 370}
301 371
302void ssb_chipco_suspend(struct ssb_chipcommon *cc) 372void ssb_chipco_suspend(struct ssb_chipcommon *cc)
@@ -395,10 +465,27 @@ void ssb_chipco_timing_init(struct ssb_chipcommon *cc,
395} 465}
396 466
397/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */ 467/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
398void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks) 468u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks)
399{ 469{
400 /* instant NMI */ 470 u32 maxt;
401 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks); 471 enum ssb_clkmode clkmode;
472
473 maxt = ssb_chipco_watchdog_get_max_timer(cc);
474 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
475 if (ticks == 1)
476 ticks = 2;
477 else if (ticks > maxt)
478 ticks = maxt;
479 chipco_write32(cc, SSB_CHIPCO_PMU_WATCHDOG, ticks);
480 } else {
481 clkmode = ticks ? SSB_CLKMODE_FAST : SSB_CLKMODE_DYNAMIC;
482 ssb_chipco_set_clockmode(cc, clkmode);
483 if (ticks > maxt)
484 ticks = maxt;
485 /* instant NMI */
486 chipco_write32(cc, SSB_CHIPCO_WATCHDOG, ticks);
487 }
488 return ticks;
402} 489}
403 490
404void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value) 491void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value)
@@ -473,12 +560,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc,
473 chipco_read32(cc, SSB_CHIPCO_CORECTL) 560 chipco_read32(cc, SSB_CHIPCO_CORECTL)
474 | SSB_CHIPCO_CORECTL_UARTCLK0); 561 | SSB_CHIPCO_CORECTL_UARTCLK0);
475 } else if ((ccrev >= 11) && (ccrev != 15)) { 562 } else if ((ccrev >= 11) && (ccrev != 15)) {
476 /* Fixed ALP clock */ 563 baud_base = ssb_chipco_alp_clock(cc);
477 baud_base = 20000000;
478 if (cc->capabilities & SSB_CHIPCO_CAP_PMU) {
479 /* FIXME: baud_base is different for devices with a PMU */
480 SSB_WARN_ON(1);
481 }
482 div = 1; 564 div = 1;
483 if (ccrev >= 21) { 565 if (ccrev >= 21) {
484 /* Turn off UART clock before switching clocksource. */ 566 /* Turn off UART clock before switching clocksource. */
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index d7d58044b4bc..a43415a7fbed 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -618,6 +618,33 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on)
618EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); 618EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
619EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); 619EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
620 620
621static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc)
622{
623 u32 crystalfreq;
624 const struct pmu0_plltab_entry *e = NULL;
625
626 crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) &
627 SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT;
628 e = pmu0_plltab_find_entry(crystalfreq);
629 BUG_ON(!e);
630 return e->freq * 1000;
631}
632
633u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc)
634{
635 struct ssb_bus *bus = cc->dev->bus;
636
637 switch (bus->chip_id) {
638 case 0x5354:
639 ssb_pmu_get_alp_clock_clk0(cc);
640 default:
641 ssb_printk(KERN_ERR PFX
642 "ERROR: PMU alp clock unknown for device %04X\n",
643 bus->chip_id);
644 return 0;
645 }
646}
647
621u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) 648u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
622{ 649{
623 struct ssb_bus *bus = cc->dev->bus; 650 struct ssb_bus *bus = cc->dev->bus;
diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c
index dc47f30e9cf7..553227a3062d 100644
--- a/drivers/ssb/driver_extif.c
+++ b/drivers/ssb/driver_extif.c
@@ -112,10 +112,30 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
112 *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); 112 *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB);
113} 113}
114 114
115void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, 115u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks)
116 u32 ticks)
117{ 116{
117 struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
118
119 return ssb_extif_watchdog_timer_set(extif, ticks);
120}
121
122u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms)
123{
124 struct ssb_extif *extif = bcm47xx_wdt_get_drvdata(wdt);
125 u32 ticks = (SSB_EXTIF_WATCHDOG_CLK / 1000) * ms;
126
127 ticks = ssb_extif_watchdog_timer_set(extif, ticks);
128
129 return (ticks * 1000) / SSB_EXTIF_WATCHDOG_CLK;
130}
131
132u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
133{
134 if (ticks > SSB_EXTIF_WATCHDOG_MAX_TIMER)
135 ticks = SSB_EXTIF_WATCHDOG_MAX_TIMER;
118 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); 136 extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks);
137
138 return ticks;
119} 139}
120 140
121u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) 141u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
diff --git a/drivers/ssb/driver_mipscore.c b/drivers/ssb/driver_mipscore.c
index b918ba922306..5bd05b136d22 100644
--- a/drivers/ssb/driver_mipscore.c
+++ b/drivers/ssb/driver_mipscore.c
@@ -178,9 +178,9 @@ static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
178{ 178{
179 struct ssb_bus *bus = mcore->dev->bus; 179 struct ssb_bus *bus = mcore->dev->bus;
180 180
181 if (bus->extif.dev) 181 if (ssb_extif_available(&bus->extif))
182 mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports); 182 mcore->nr_serial_ports = ssb_extif_serial_init(&bus->extif, mcore->serial_ports);
183 else if (bus->chipco.dev) 183 else if (ssb_chipco_available(&bus->chipco))
184 mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports); 184 mcore->nr_serial_ports = ssb_chipco_serial_init(&bus->chipco, mcore->serial_ports);
185 else 185 else
186 mcore->nr_serial_ports = 0; 186 mcore->nr_serial_ports = 0;
@@ -191,7 +191,7 @@ static void ssb_mips_flash_detect(struct ssb_mipscore *mcore)
191 struct ssb_bus *bus = mcore->dev->bus; 191 struct ssb_bus *bus = mcore->dev->bus;
192 192
193 /* When there is no chipcommon on the bus there is 4MB flash */ 193 /* When there is no chipcommon on the bus there is 4MB flash */
194 if (!bus->chipco.dev) { 194 if (!ssb_chipco_available(&bus->chipco)) {
195 mcore->pflash.present = true; 195 mcore->pflash.present = true;
196 mcore->pflash.buswidth = 2; 196 mcore->pflash.buswidth = 2;
197 mcore->pflash.window = SSB_FLASH1; 197 mcore->pflash.window = SSB_FLASH1;
@@ -227,9 +227,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *mcore)
227 if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU) 227 if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
228 return ssb_pmu_get_cpu_clock(&bus->chipco); 228 return ssb_pmu_get_cpu_clock(&bus->chipco);
229 229
230 if (bus->extif.dev) { 230 if (ssb_extif_available(&bus->extif)) {
231 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m); 231 ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
232 } else if (bus->chipco.dev) { 232 } else if (ssb_chipco_available(&bus->chipco)) {
233 ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m); 233 ssb_chipco_get_clockcpu(&bus->chipco, &pll_type, &n, &m);
234 } else 234 } else
235 return 0; 235 return 0;
@@ -265,9 +265,9 @@ void ssb_mipscore_init(struct ssb_mipscore *mcore)
265 hz = 100000000; 265 hz = 100000000;
266 ns = 1000000000 / hz; 266 ns = 1000000000 / hz;
267 267
268 if (bus->extif.dev) 268 if (ssb_extif_available(&bus->extif))
269 ssb_extif_timing_init(&bus->extif, ns); 269 ssb_extif_timing_init(&bus->extif, ns);
270 else if (bus->chipco.dev) 270 else if (ssb_chipco_available(&bus->chipco))
271 ssb_chipco_timing_init(&bus->chipco, ns); 271 ssb_chipco_timing_init(&bus->chipco, ns);
272 272
273 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */ 273 /* Assign IRQs to all cores on the bus, start with irq line 2, because serial usually takes 1 */
diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c
index 9ef124f9ee2d..bb18d76f9f2c 100644
--- a/drivers/ssb/embedded.c
+++ b/drivers/ssb/embedded.c
@@ -4,11 +4,13 @@
4 * 4 *
5 * Copyright 2005-2008, Broadcom Corporation 5 * Copyright 2005-2008, Broadcom Corporation
6 * Copyright 2006-2008, Michael Buesch <m@bues.ch> 6 * Copyright 2006-2008, Michael Buesch <m@bues.ch>
7 * Copyright 2012, Hauke Mehrtens <hauke@hauke-m.de>
7 * 8 *
8 * Licensed under the GNU/GPL. See COPYING for details. 9 * Licensed under the GNU/GPL. See COPYING for details.
9 */ 10 */
10 11
11#include <linux/export.h> 12#include <linux/export.h>
13#include <linux/platform_device.h>
12#include <linux/ssb/ssb.h> 14#include <linux/ssb/ssb.h>
13#include <linux/ssb/ssb_embedded.h> 15#include <linux/ssb/ssb_embedded.h>
14#include <linux/ssb/ssb_driver_pci.h> 16#include <linux/ssb/ssb_driver_pci.h>
@@ -32,6 +34,39 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks)
32} 34}
33EXPORT_SYMBOL(ssb_watchdog_timer_set); 35EXPORT_SYMBOL(ssb_watchdog_timer_set);
34 36
37int ssb_watchdog_register(struct ssb_bus *bus)
38{
39 struct bcm47xx_wdt wdt = {};
40 struct platform_device *pdev;
41
42 if (ssb_chipco_available(&bus->chipco)) {
43 wdt.driver_data = &bus->chipco;
44 wdt.timer_set = ssb_chipco_watchdog_timer_set_wdt;
45 wdt.timer_set_ms = ssb_chipco_watchdog_timer_set_ms;
46 wdt.max_timer_ms = bus->chipco.max_timer_ms;
47 } else if (ssb_extif_available(&bus->extif)) {
48 wdt.driver_data = &bus->extif;
49 wdt.timer_set = ssb_extif_watchdog_timer_set_wdt;
50 wdt.timer_set_ms = ssb_extif_watchdog_timer_set_ms;
51 wdt.max_timer_ms = SSB_EXTIF_WATCHDOG_MAX_TIMER_MS;
52 } else {
53 return -ENODEV;
54 }
55
56 pdev = platform_device_register_data(NULL, "bcm47xx-wdt",
57 bus->busnumber, &wdt,
58 sizeof(wdt));
59 if (IS_ERR(pdev)) {
60 ssb_dprintk(KERN_INFO PFX
61 "can not register watchdog device, err: %li\n",
62 PTR_ERR(pdev));
63 return PTR_ERR(pdev);
64 }
65
66 bus->watchdog = pdev;
67 return 0;
68}
69
35u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) 70u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask)
36{ 71{
37 unsigned long flags; 72 unsigned long flags;
diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c
index df0f145c22fc..58c7da29a37c 100644
--- a/drivers/ssb/main.c
+++ b/drivers/ssb/main.c
@@ -13,6 +13,7 @@
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/platform_device.h>
16#include <linux/ssb/ssb.h> 17#include <linux/ssb/ssb.h>
17#include <linux/ssb/ssb_regs.h> 18#include <linux/ssb/ssb_regs.h>
18#include <linux/ssb/ssb_driver_gige.h> 19#include <linux/ssb/ssb_driver_gige.h>
@@ -433,6 +434,11 @@ static void ssb_devices_unregister(struct ssb_bus *bus)
433 if (sdev->dev) 434 if (sdev->dev)
434 device_unregister(sdev->dev); 435 device_unregister(sdev->dev);
435 } 436 }
437
438#ifdef CONFIG_SSB_EMBEDDED
439 if (bus->bustype == SSB_BUSTYPE_SSB)
440 platform_device_unregister(bus->watchdog);
441#endif
436} 442}
437 443
438void ssb_bus_unregister(struct ssb_bus *bus) 444void ssb_bus_unregister(struct ssb_bus *bus)
@@ -561,6 +567,8 @@ static int __devinit ssb_attach_queued_buses(void)
561 if (err) 567 if (err)
562 goto error; 568 goto error;
563 ssb_pcicore_init(&bus->pcicore); 569 ssb_pcicore_init(&bus->pcicore);
570 if (bus->bustype == SSB_BUSTYPE_SSB)
571 ssb_watchdog_register(bus);
564 ssb_bus_may_powerdown(bus); 572 ssb_bus_may_powerdown(bus);
565 573
566 err = ssb_devices_register(bus); 574 err = ssb_devices_register(bus);
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h
index a305550b4b65..8942db1d855a 100644
--- a/drivers/ssb/ssb_private.h
+++ b/drivers/ssb/ssb_private.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/ssb/ssb.h> 4#include <linux/ssb/ssb.h>
5#include <linux/types.h> 5#include <linux/types.h>
6#include <linux/bcm47xx_wdt.h>
6 7
7 8
8#define PFX "ssb: " 9#define PFX "ssb: "
@@ -210,5 +211,35 @@ static inline void b43_pci_ssb_bridge_exit(void)
210/* driver_chipcommon_pmu.c */ 211/* driver_chipcommon_pmu.c */
211extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); 212extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
212extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); 213extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
214extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc);
215
216extern u32 ssb_chipco_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
217 u32 ticks);
218extern u32 ssb_chipco_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
219
220#ifdef CONFIG_SSB_DRIVER_EXTIF
221extern u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt, u32 ticks);
222extern u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt, u32 ms);
223#else
224static inline u32 ssb_extif_watchdog_timer_set_wdt(struct bcm47xx_wdt *wdt,
225 u32 ticks)
226{
227 return 0;
228}
229static inline u32 ssb_extif_watchdog_timer_set_ms(struct bcm47xx_wdt *wdt,
230 u32 ms)
231{
232 return 0;
233}
234#endif
235
236#ifdef CONFIG_SSB_EMBEDDED
237extern int ssb_watchdog_register(struct ssb_bus *bus);
238#else /* CONFIG_SSB_EMBEDDED */
239static inline int ssb_watchdog_register(struct ssb_bus *bus)
240{
241 return 0;
242}
243#endif /* CONFIG_SSB_EMBEDDED */
213 244
214#endif /* LINUX_SSB_PRIVATE_H_ */ 245#endif /* LINUX_SSB_PRIVATE_H_ */
diff --git a/include/linux/bcm47xx_wdt.h b/include/linux/bcm47xx_wdt.h
new file mode 100644
index 000000000000..e5dfc256485b
--- /dev/null
+++ b/include/linux/bcm47xx_wdt.h
@@ -0,0 +1,19 @@
1#ifndef LINUX_BCM47XX_WDT_H_
2#define LINUX_BCM47XX_WDT_H_
3
4#include <linux/types.h>
5
6
7struct bcm47xx_wdt {
8 u32 (*timer_set)(struct bcm47xx_wdt *, u32);
9 u32 (*timer_set_ms)(struct bcm47xx_wdt *, u32);
10 u32 max_timer_ms;
11
12 void *driver_data;
13};
14
15static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt)
16{
17 return wdt->driver_data;
18}
19#endif /* LINUX_BCM47XX_WDT_H_ */
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index 145f3c56227f..e51359180b6f 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -1,6 +1,8 @@
1#ifndef LINUX_BCMA_DRIVER_CC_H_ 1#ifndef LINUX_BCMA_DRIVER_CC_H_
2#define LINUX_BCMA_DRIVER_CC_H_ 2#define LINUX_BCMA_DRIVER_CC_H_
3 3
4#include <linux/platform_device.h>
5
4/** ChipCommon core registers. **/ 6/** ChipCommon core registers. **/
5#define BCMA_CC_ID 0x0000 7#define BCMA_CC_ID 0x0000
6#define BCMA_CC_ID_ID 0x0000FFFF 8#define BCMA_CC_ID_ID 0x0000FFFF
@@ -570,6 +572,8 @@ struct bcma_drv_cc {
570 int nr_serial_ports; 572 int nr_serial_ports;
571 struct bcma_serial_port serial_ports[4]; 573 struct bcma_serial_port serial_ports[4];
572#endif /* CONFIG_BCMA_DRIVER_MIPS */ 574#endif /* CONFIG_BCMA_DRIVER_MIPS */
575 u32 ticks_per_ms;
576 struct platform_device *watchdog;
573}; 577};
574 578
575/* Register access */ 579/* Register access */
@@ -593,8 +597,7 @@ extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
593 597
594void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); 598void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
595 599
596extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, 600extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
597 u32 ticks);
598 601
599void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value); 602void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
600 603
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index f9c5a787d350..8f690e53dd89 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1213,6 +1213,21 @@ struct ieee80211_vht_cap {
1213} __packed; 1213} __packed;
1214 1214
1215/** 1215/**
1216 * enum ieee80211_vht_chanwidth - VHT channel width
1217 * @IEEE80211_VHT_CHANWIDTH_USE_HT: use the HT operation IE to
1218 * determine the channel width (20 or 40 MHz)
1219 * @IEEE80211_VHT_CHANWIDTH_80MHZ: 80 MHz bandwidth
1220 * @IEEE80211_VHT_CHANWIDTH_160MHZ: 160 MHz bandwidth
1221 * @IEEE80211_VHT_CHANWIDTH_80P80MHZ: 80+80 MHz bandwidth
1222 */
1223enum ieee80211_vht_chanwidth {
1224 IEEE80211_VHT_CHANWIDTH_USE_HT = 0,
1225 IEEE80211_VHT_CHANWIDTH_80MHZ = 1,
1226 IEEE80211_VHT_CHANWIDTH_160MHZ = 2,
1227 IEEE80211_VHT_CHANWIDTH_80P80MHZ = 3,
1228};
1229
1230/**
1216 * struct ieee80211_vht_operation - VHT operation IE 1231 * struct ieee80211_vht_operation - VHT operation IE
1217 * 1232 *
1218 * This structure is the "VHT operation element" as 1233 * This structure is the "VHT operation element" as
diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h
index bb674c02f306..1f64e3f1f22b 100644
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -8,6 +8,7 @@
8#include <linux/pci.h> 8#include <linux/pci.h>
9#include <linux/mod_devicetable.h> 9#include <linux/mod_devicetable.h>
10#include <linux/dma-mapping.h> 10#include <linux/dma-mapping.h>
11#include <linux/platform_device.h>
11 12
12#include <linux/ssb/ssb_regs.h> 13#include <linux/ssb/ssb_regs.h>
13 14
@@ -432,6 +433,7 @@ struct ssb_bus {
432#ifdef CONFIG_SSB_EMBEDDED 433#ifdef CONFIG_SSB_EMBEDDED
433 /* Lock for GPIO register access. */ 434 /* Lock for GPIO register access. */
434 spinlock_t gpio_lock; 435 spinlock_t gpio_lock;
436 struct platform_device *watchdog;
435#endif /* EMBEDDED */ 437#endif /* EMBEDDED */
436 438
437 /* Internal-only stuff follows. Do not touch. */ 439 /* Internal-only stuff follows. Do not touch. */
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index c2b02a5c86ae..38339fd68a5f 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -591,6 +591,8 @@ struct ssb_chipcommon {
591 /* Fast Powerup Delay constant */ 591 /* Fast Powerup Delay constant */
592 u16 fast_pwrup_delay; 592 u16 fast_pwrup_delay;
593 struct ssb_chipcommon_pmu pmu; 593 struct ssb_chipcommon_pmu pmu;
594 u32 ticks_per_ms;
595 u32 max_timer_ms;
594}; 596};
595 597
596static inline bool ssb_chipco_available(struct ssb_chipcommon *cc) 598static inline bool ssb_chipco_available(struct ssb_chipcommon *cc)
@@ -630,8 +632,7 @@ enum ssb_clkmode {
630extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, 632extern void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc,
631 enum ssb_clkmode mode); 633 enum ssb_clkmode mode);
632 634
633extern void ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, 635extern u32 ssb_chipco_watchdog_timer_set(struct ssb_chipcommon *cc, u32 ticks);
634 u32 ticks);
635 636
636void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value); 637void ssb_chipco_irq_mask(struct ssb_chipcommon *cc, u32 mask, u32 value);
637 638
diff --git a/include/linux/ssb/ssb_driver_extif.h b/include/linux/ssb/ssb_driver_extif.h
index 91161f0aa22b..99511d0e931d 100644
--- a/include/linux/ssb/ssb_driver_extif.h
+++ b/include/linux/ssb/ssb_driver_extif.h
@@ -152,6 +152,9 @@
152/* watchdog */ 152/* watchdog */
153#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */ 153#define SSB_EXTIF_WATCHDOG_CLK 48000000 /* Hz */
154 154
155#define SSB_EXTIF_WATCHDOG_MAX_TIMER ((1 << 28) - 1)
156#define SSB_EXTIF_WATCHDOG_MAX_TIMER_MS (SSB_EXTIF_WATCHDOG_MAX_TIMER \
157 / (SSB_EXTIF_WATCHDOG_CLK / 1000))
155 158
156 159
157#ifdef CONFIG_SSB_DRIVER_EXTIF 160#ifdef CONFIG_SSB_DRIVER_EXTIF
@@ -171,8 +174,7 @@ extern void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
171extern void ssb_extif_timing_init(struct ssb_extif *extif, 174extern void ssb_extif_timing_init(struct ssb_extif *extif,
172 unsigned long ns); 175 unsigned long ns);
173 176
174extern void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, 177extern u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks);
175 u32 ticks);
176 178
177/* Extif GPIO pin access */ 179/* Extif GPIO pin access */
178u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask); 180u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask);
@@ -205,10 +207,52 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif,
205} 207}
206 208
207static inline 209static inline
208void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, 210void ssb_extif_timing_init(struct ssb_extif *extif, unsigned long ns)
209 u32 ticks)
210{ 211{
211} 212}
212 213
214static inline
215u32 ssb_extif_watchdog_timer_set(struct ssb_extif *extif, u32 ticks)
216{
217 return 0;
218}
219
220static inline u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask)
221{
222 return 0;
223}
224
225static inline u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask,
226 u32 value)
227{
228 return 0;
229}
230
231static inline u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask,
232 u32 value)
233{
234 return 0;
235}
236
237static inline u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask,
238 u32 value)
239{
240 return 0;
241}
242
243static inline u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask,
244 u32 value)
245{
246 return 0;
247}
248
249#ifdef CONFIG_SSB_SERIAL
250static inline int ssb_extif_serial_init(struct ssb_extif *extif,
251 struct ssb_serial_port *ports)
252{
253 return 0;
254}
255#endif /* CONFIG_SSB_SERIAL */
256
213#endif /* CONFIG_SSB_DRIVER_EXTIF */ 257#endif /* CONFIG_SSB_DRIVER_EXTIF */
214#endif /* LINUX_SSB_EXTIFCORE_H_ */ 258#endif /* LINUX_SSB_EXTIFCORE_H_ */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ef5b85dac3f7..014a2eaa5389 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -376,7 +376,7 @@ extern int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt);
376extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb, 376extern int l2cap_recv_acldata(struct hci_conn *hcon, struct sk_buff *skb,
377 u16 flags); 377 u16 flags);
378 378
379extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr); 379extern int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags);
380extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status); 380extern void sco_connect_cfm(struct hci_conn *hcon, __u8 status);
381extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason); 381extern void sco_disconn_cfm(struct hci_conn *hcon, __u8 reason);
382extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb); 382extern int sco_recv_scodata(struct hci_conn *hcon, struct sk_buff *skb);
@@ -577,6 +577,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst);
577int hci_conn_del(struct hci_conn *conn); 577int hci_conn_del(struct hci_conn *conn);
578void hci_conn_hash_flush(struct hci_dev *hdev); 578void hci_conn_hash_flush(struct hci_dev *hdev);
579void hci_conn_check_pending(struct hci_dev *hdev); 579void hci_conn_check_pending(struct hci_dev *hdev);
580void hci_conn_accept(struct hci_conn *conn, int mask);
580 581
581struct hci_chan *hci_chan_create(struct hci_conn *conn); 582struct hci_chan *hci_chan_create(struct hci_conn *conn);
582void hci_chan_del(struct hci_chan *chan); 583void hci_chan_del(struct hci_chan *chan);
@@ -766,7 +767,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
766#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR) 767#define lmp_sniffsubr_capable(dev) ((dev)->features[5] & LMP_SNIFF_SUBR)
767#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC) 768#define lmp_pause_enc_capable(dev) ((dev)->features[5] & LMP_PAUSE_ENC)
768#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ) 769#define lmp_ext_inq_capable(dev) ((dev)->features[6] & LMP_EXT_INQ)
769#define lmp_le_br_capable(dev) ((dev)->features[6] & LMP_SIMUL_LE_BR) 770#define lmp_le_br_capable(dev) !!((dev)->features[6] & LMP_SIMUL_LE_BR)
770#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR) 771#define lmp_ssp_capable(dev) ((dev)->features[6] & LMP_SIMPLE_PAIR)
771#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH) 772#define lmp_no_flush_capable(dev) ((dev)->features[6] & LMP_NO_FLUSH)
772#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO) 773#define lmp_lsto_capable(dev) ((dev)->features[7] & LMP_LSTO)
@@ -775,12 +776,30 @@ void hci_conn_del_sysfs(struct hci_conn *conn);
775 776
776/* ----- Extended LMP capabilities ----- */ 777/* ----- Extended LMP capabilities ----- */
777#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP) 778#define lmp_host_ssp_capable(dev) ((dev)->host_features[0] & LMP_HOST_SSP)
778#define lmp_host_le_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE) 779#define lmp_host_le_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE)
779#define lmp_host_le_br_capable(dev) ((dev)->host_features[0] & LMP_HOST_LE_BREDR) 780#define lmp_host_le_br_capable(dev) !!((dev)->host_features[0] & LMP_HOST_LE_BREDR)
781
782/* returns true if at least one AMP active */
783static inline bool hci_amp_capable(void)
784{
785 struct hci_dev *hdev;
786 bool ret = false;
787
788 read_lock(&hci_dev_list_lock);
789 list_for_each_entry(hdev, &hci_dev_list, list)
790 if (hdev->amp_type == HCI_AMP &&
791 test_bit(HCI_UP, &hdev->flags))
792 ret = true;
793 read_unlock(&hci_dev_list_lock);
794
795 return ret;
796}
780 797
781/* ----- HCI protocols ----- */ 798/* ----- HCI protocols ----- */
799#define HCI_PROTO_DEFER 0x01
800
782static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, 801static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
783 __u8 type) 802 __u8 type, __u8 *flags)
784{ 803{
785 switch (type) { 804 switch (type) {
786 case ACL_LINK: 805 case ACL_LINK:
@@ -788,7 +807,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,
788 807
789 case SCO_LINK: 808 case SCO_LINK:
790 case ESCO_LINK: 809 case ESCO_LINK:
791 return sco_connect_ind(hdev, bdaddr); 810 return sco_connect_ind(hdev, bdaddr, flags);
792 811
793 default: 812 default:
794 BT_ERR("unknown link type %d", type); 813 BT_ERR("unknown link type %d", type);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index f57fab04e7c5..7588ef44ebaf 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@ enum {
611 CONF_MTU_DONE, 611 CONF_MTU_DONE,
612 CONF_MODE_DONE, 612 CONF_MODE_DONE,
613 CONF_CONNECT_PEND, 613 CONF_CONNECT_PEND,
614 CONF_NO_FCS_RECV, 614 CONF_RECV_NO_FCS,
615 CONF_STATE2_DEVICE, 615 CONF_STATE2_DEVICE,
616 CONF_EWS_RECV, 616 CONF_EWS_RECV,
617 CONF_LOC_CONF_PEND, 617 CONF_LOC_CONF_PEND,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e78db2cf3d1b..8e6a6b73b9c9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -58,6 +58,8 @@
58 * structures here describe these capabilities in detail. 58 * structures here describe these capabilities in detail.
59 */ 59 */
60 60
61struct wiphy;
62
61/* 63/*
62 * wireless hardware capability structures 64 * wireless hardware capability structures
63 */ 65 */
@@ -388,6 +390,22 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1,
388 const struct cfg80211_chan_def *chandef2); 390 const struct cfg80211_chan_def *chandef2);
389 391
390/** 392/**
393 * cfg80211_chandef_valid - check if a channel definition is valid
394 * @chandef: the channel definition to check
395 */
396bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef);
397
398/**
399 * cfg80211_chandef_usable - check if secondary channels can be used
400 * @wiphy: the wiphy to validate against
401 * @chandef: the channel definition to check
402 * @prohibited_flags: the regulatory chanenl flags that must not be set
403 */
404bool cfg80211_chandef_usable(struct wiphy *wiphy,
405 const struct cfg80211_chan_def *chandef,
406 u32 prohibited_flags);
407
408/**
391 * enum survey_info_flags - survey information flags 409 * enum survey_info_flags - survey information flags
392 * 410 *
393 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in 411 * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in
@@ -520,6 +538,8 @@ struct cfg80211_beacon_data {
520 * @privacy: the BSS uses privacy 538 * @privacy: the BSS uses privacy
521 * @auth_type: Authentication type (algorithm) 539 * @auth_type: Authentication type (algorithm)
522 * @inactivity_timeout: time in seconds to determine station's inactivity. 540 * @inactivity_timeout: time in seconds to determine station's inactivity.
541 * @p2p_ctwindow: P2P CT Window
542 * @p2p_opp_ps: P2P opportunistic PS
523 */ 543 */
524struct cfg80211_ap_settings { 544struct cfg80211_ap_settings {
525 struct cfg80211_chan_def chandef; 545 struct cfg80211_chan_def chandef;
@@ -534,6 +554,8 @@ struct cfg80211_ap_settings {
534 bool privacy; 554 bool privacy;
535 enum nl80211_auth_type auth_type; 555 enum nl80211_auth_type auth_type;
536 int inactivity_timeout; 556 int inactivity_timeout;
557 u8 p2p_ctwindow;
558 bool p2p_opp_ps;
537}; 559};
538 560
539/** 561/**
@@ -895,6 +917,8 @@ struct mpath_info {
895 * @ap_isolate: do not forward packets between connected stations 917 * @ap_isolate: do not forward packets between connected stations
896 * @ht_opmode: HT Operation mode 918 * @ht_opmode: HT Operation mode
897 * (u16 = opmode, -1 = do not change) 919 * (u16 = opmode, -1 = do not change)
920 * @p2p_ctwindow: P2P CT Window (-1 = no change)
921 * @p2p_opp_ps: P2P opportunistic PS (-1 = no change)
898 */ 922 */
899struct bss_parameters { 923struct bss_parameters {
900 int use_cts_prot; 924 int use_cts_prot;
@@ -904,6 +928,7 @@ struct bss_parameters {
904 u8 basic_rates_len; 928 u8 basic_rates_len;
905 int ap_isolate; 929 int ap_isolate;
906 int ht_opmode; 930 int ht_opmode;
931 s8 p2p_ctwindow, p2p_opp_ps;
907}; 932};
908 933
909/** 934/**
@@ -1045,9 +1070,6 @@ struct ieee80211_txq_params {
1045 u8 aifs; 1070 u8 aifs;
1046}; 1071};
1047 1072
1048/* from net/wireless.h */
1049struct wiphy;
1050
1051/** 1073/**
1052 * DOC: Scanning and BSS list handling 1074 * DOC: Scanning and BSS list handling
1053 * 1075 *
@@ -1184,6 +1206,18 @@ enum cfg80211_signal_type {
1184}; 1206};
1185 1207
1186/** 1208/**
1209 * struct cfg80211_bss_ie_data - BSS entry IE data
1210 * @rcu_head: internal use, for freeing
1211 * @len: length of the IEs
1212 * @data: IE data
1213 */
1214struct cfg80211_bss_ies {
1215 struct rcu_head rcu_head;
1216 int len;
1217 u8 data[];
1218};
1219
1220/**
1187 * struct cfg80211_bss - BSS description 1221 * struct cfg80211_bss - BSS description
1188 * 1222 *
1189 * This structure describes a BSS (which may also be a mesh network) 1223 * This structure describes a BSS (which may also be a mesh network)
@@ -1194,36 +1228,34 @@ enum cfg80211_signal_type {
1194 * @tsf: timestamp of last received update 1228 * @tsf: timestamp of last received update
1195 * @beacon_interval: the beacon interval as from the frame 1229 * @beacon_interval: the beacon interval as from the frame
1196 * @capability: the capability field in host byte order 1230 * @capability: the capability field in host byte order
1197 * @information_elements: the information elements (Note that there 1231 * @ies: the information elements (Note that there
1198 * is no guarantee that these are well-formed!); this is a pointer to 1232 * is no guarantee that these are well-formed!); this is a pointer to
1199 * either the beacon_ies or proberesp_ies depending on whether Probe 1233 * either the beacon_ies or proberesp_ies depending on whether Probe
1200 * Response frame has been received 1234 * Response frame has been received
1201 * @len_information_elements: total length of the information elements
1202 * @beacon_ies: the information elements from the last Beacon frame 1235 * @beacon_ies: the information elements from the last Beacon frame
1203 * @len_beacon_ies: total length of the beacon_ies
1204 * @proberesp_ies: the information elements from the last Probe Response frame 1236 * @proberesp_ies: the information elements from the last Probe Response frame
1205 * @len_proberesp_ies: total length of the proberesp_ies
1206 * @signal: signal strength value (type depends on the wiphy's signal_type) 1237 * @signal: signal strength value (type depends on the wiphy's signal_type)
1207 * @free_priv: function pointer to free private data 1238 * @free_priv: function pointer to free private data
1208 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 1239 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
1209 */ 1240 */
1210struct cfg80211_bss { 1241struct cfg80211_bss {
1242 u64 tsf;
1243
1211 struct ieee80211_channel *channel; 1244 struct ieee80211_channel *channel;
1212 1245
1213 u8 bssid[ETH_ALEN]; 1246 const struct cfg80211_bss_ies __rcu *ies;
1214 u64 tsf; 1247 const struct cfg80211_bss_ies __rcu *beacon_ies;
1248 const struct cfg80211_bss_ies __rcu *proberesp_ies;
1249
1250 void (*free_priv)(struct cfg80211_bss *bss);
1251
1252 s32 signal;
1253
1215 u16 beacon_interval; 1254 u16 beacon_interval;
1216 u16 capability; 1255 u16 capability;
1217 u8 *information_elements;
1218 size_t len_information_elements;
1219 u8 *beacon_ies;
1220 size_t len_beacon_ies;
1221 u8 *proberesp_ies;
1222 size_t len_proberesp_ies;
1223 1256
1224 s32 signal; 1257 u8 bssid[ETH_ALEN];
1225 1258
1226 void (*free_priv)(struct cfg80211_bss *bss);
1227 u8 priv[0] __attribute__((__aligned__(sizeof(void *)))); 1259 u8 priv[0] __attribute__((__aligned__(sizeof(void *))));
1228}; 1260};
1229 1261
@@ -1231,6 +1263,9 @@ struct cfg80211_bss {
1231 * ieee80211_bss_get_ie - find IE with given ID 1263 * ieee80211_bss_get_ie - find IE with given ID
1232 * @bss: the bss to search 1264 * @bss: the bss to search
1233 * @ie: the IE ID 1265 * @ie: the IE ID
1266 *
1267 * Note that the return value is an RCU-protected pointer, so
1268 * rcu_read_lock() must be held when calling this function.
1234 * Returns %NULL if not found. 1269 * Returns %NULL if not found.
1235 */ 1270 */
1236const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); 1271const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 7f0df133d119..c3999632e616 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -186,6 +186,10 @@ struct ieee80211_radiotap_header {
186 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless 186 * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless
187 * 187 *
188 * Contains the AMPDU information for the subframe. 188 * Contains the AMPDU information for the subframe.
189 *
190 * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16
191 *
192 * Contains VHT information about this frame.
189 */ 193 */
190enum ieee80211_radiotap_type { 194enum ieee80211_radiotap_type {
191 IEEE80211_RADIOTAP_TSFT = 0, 195 IEEE80211_RADIOTAP_TSFT = 0,
@@ -209,6 +213,7 @@ enum ieee80211_radiotap_type {
209 213
210 IEEE80211_RADIOTAP_MCS = 19, 214 IEEE80211_RADIOTAP_MCS = 19,
211 IEEE80211_RADIOTAP_AMPDU_STATUS = 20, 215 IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
216 IEEE80211_RADIOTAP_VHT = 21,
212 217
213 /* valid in every it_present bitmap, even vendor namespaces */ 218 /* valid in every it_present bitmap, even vendor namespaces */
214 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29, 219 IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
@@ -282,6 +287,25 @@ enum ieee80211_radiotap_type {
282#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010 287#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010
283#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020 288#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020
284 289
290/* For IEEE80211_RADIOTAP_VHT */
291#define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001
292#define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002
293#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004
294#define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008
295#define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010
296#define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020
297#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040
298#define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080
299#define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100
300
301#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01
302#define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02
303#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04
304#define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08
305#define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10
306#define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20
307
308
285/* helpers */ 309/* helpers */
286static inline int ieee80211_get_radiotap_len(unsigned char *data) 310static inline int ieee80211_get_radiotap_len(unsigned char *data)
287{ 311{
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index db7680acd0da..1c02fb3b3817 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -164,7 +164,7 @@ enum ieee80211_chanctx_change {
164 * active on the channel to receive MIMO transmissions 164 * active on the channel to receive MIMO transmissions
165 * @rx_chains_dynamic: The number of RX chains that must be enabled 165 * @rx_chains_dynamic: The number of RX chains that must be enabled
166 * after RTS/CTS handshake to receive SMPS MIMO transmissions; 166 * after RTS/CTS handshake to receive SMPS MIMO transmissions;
167 * this will always be >= @rx_chains_always. 167 * this will always be >= @rx_chains_static.
168 * @drv_priv: data area for driver use, will always be aligned to 168 * @drv_priv: data area for driver use, will always be aligned to
169 * sizeof(void *), size is determined in hw information. 169 * sizeof(void *), size is determined in hw information.
170 */ 170 */
@@ -1473,6 +1473,10 @@ enum ieee80211_hw_flags {
1473 * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only 1473 * include _FMT. Use %IEEE80211_RADIOTAP_MCS_HAVE_* values, only
1474 * adding _BW is supported today. 1474 * adding _BW is supported today.
1475 * 1475 *
1476 * @radiotap_vht_details: lists which VHT MCS information the HW reports,
1477 * the default is _GI | _BANDWIDTH.
1478 * Use the %IEEE80211_RADIOTAP_VHT_KNOWN_* values.
1479 *
1476 * @netdev_features: netdev features to be set in each netdev created 1480 * @netdev_features: netdev features to be set in each netdev created
1477 * from this HW. Note only HW checksum features are currently 1481 * from this HW. Note only HW checksum features are currently
1478 * compatible with mac80211. Other feature bits will be rejected. 1482 * compatible with mac80211. Other feature bits will be rejected.
@@ -1499,6 +1503,7 @@ struct ieee80211_hw {
1499 u8 max_tx_aggregation_subframes; 1503 u8 max_tx_aggregation_subframes;
1500 u8 offchannel_tx_hw_queue; 1504 u8 offchannel_tx_hw_queue;
1501 u8 radiotap_mcs_details; 1505 u8 radiotap_mcs_details;
1506 u16 radiotap_vht_details;
1502 netdev_features_t netdev_features; 1507 netdev_features_t netdev_features;
1503}; 1508};
1504 1509
@@ -3139,8 +3144,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
3139 * @vif: &struct ieee80211_vif pointer from the add_interface callback. 3144 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
3140 * @ssid: SSID buffer 3145 * @ssid: SSID buffer
3141 * @ssid_len: length of SSID 3146 * @ssid_len: length of SSID
3142 * @ie: buffer containing all IEs except SSID for the template 3147 * @tailroom: tailroom to reserve at end of SKB for IEs
3143 * @ie_len: length of the IE buffer
3144 * 3148 *
3145 * Creates a Probe Request template which can, for example, be uploaded to 3149 * Creates a Probe Request template which can, for example, be uploaded to
3146 * hardware. 3150 * hardware.
@@ -3148,7 +3152,7 @@ struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
3148struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, 3152struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
3149 struct ieee80211_vif *vif, 3153 struct ieee80211_vif *vif,
3150 const u8 *ssid, size_t ssid_len, 3154 const u8 *ssid, size_t ssid_len,
3151 const u8 *ie, size_t ie_len); 3155 size_t tailroom);
3152 3156
3153/** 3157/**
3154 * ieee80211_rts_get - RTS frame generation function 3158 * ieee80211_rts_get - RTS frame generation function
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 33a417481ad8..e3e19f8b16f2 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1303,6 +1303,13 @@ enum nl80211_commands {
1303 * 1303 *
1304 * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) 1304 * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
1305 * 1305 *
1306 * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with
1307 * the START_AP and SET_BSS commands
1308 * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the
1309 * START_AP and SET_BSS commands. This can have the values 0 or 1;
1310 * if not given in START_AP 0 is assumed, if not given in SET_BSS
1311 * no change is made.
1312 *
1306 * @NL80211_ATTR_MAX: highest attribute number currently defined 1313 * @NL80211_ATTR_MAX: highest attribute number currently defined
1307 * @__NL80211_ATTR_AFTER_LAST: internal use 1314 * @__NL80211_ATTR_AFTER_LAST: internal use
1308 */ 1315 */
@@ -1570,6 +1577,9 @@ enum nl80211_attrs {
1570 NL80211_ATTR_CENTER_FREQ1, 1577 NL80211_ATTR_CENTER_FREQ1,
1571 NL80211_ATTR_CENTER_FREQ2, 1578 NL80211_ATTR_CENTER_FREQ2,
1572 1579
1580 NL80211_ATTR_P2P_CTWINDOW,
1581 NL80211_ATTR_P2P_OPPPS,
1582
1573 /* add attributes here, update the policy in nl80211.c */ 1583 /* add attributes here, update the policy in nl80211.c */
1574 1584
1575 __NL80211_ATTR_AFTER_LAST, 1585 __NL80211_ATTR_AFTER_LAST,
@@ -3126,6 +3136,10 @@ enum nl80211_ap_sme_features {
3126 * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform 3136 * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform
3127 * OBSS scans and generate 20/40 BSS coex reports. This flag is used only 3137 * OBSS scans and generate 20/40 BSS coex reports. This flag is used only
3128 * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied. 3138 * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied.
3139 * @NL80211_FEATURE_P2P_GO_CTWIN: P2P GO implementation supports CT Window
3140 * setting
3141 * @NL80211_FEATURE_P2P_GO_OPPPS: P2P GO implementation supports opportunistic
3142 * powersave
3129 */ 3143 */
3130enum nl80211_feature_flags { 3144enum nl80211_feature_flags {
3131 NL80211_FEATURE_SK_TX_STATUS = 1 << 0, 3145 NL80211_FEATURE_SK_TX_STATUS = 1 << 0,
@@ -3139,6 +3153,8 @@ enum nl80211_feature_flags {
3139 NL80211_FEATURE_AP_SCAN = 1 << 8, 3153 NL80211_FEATURE_AP_SCAN = 1 << 8,
3140 NL80211_FEATURE_VIF_TXPOWER = 1 << 9, 3154 NL80211_FEATURE_VIF_TXPOWER = 1 << 9,
3141 NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10, 3155 NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10,
3156 NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11,
3157 NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12,
3142}; 3158};
3143 3159
3144/** 3160/**
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 7140f83328a2..596660d37c5e 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -861,6 +861,9 @@ static int hci_dev_do_close(struct hci_dev *hdev)
861 /* Clear flags */ 861 /* Clear flags */
862 hdev->flags = 0; 862 hdev->flags = 0;
863 863
864 /* Controller radio is available but is currently powered down */
865 hdev->amp_status = 0;
866
864 memset(hdev->eir, 0, sizeof(hdev->eir)); 867 memset(hdev->eir, 0, sizeof(hdev->eir));
865 memset(hdev->dev_class, 0, sizeof(hdev->dev_class)); 868 memset(hdev->dev_class, 0, sizeof(hdev->dev_class));
866 869
@@ -1854,6 +1857,8 @@ void hci_unregister_dev(struct hci_dev *hdev)
1854 for (i = 0; i < NUM_REASSEMBLY; i++) 1857 for (i = 0; i < NUM_REASSEMBLY; i++)
1855 kfree_skb(hdev->reassembly[i]); 1858 kfree_skb(hdev->reassembly[i]);
1856 1859
1860 cancel_work_sync(&hdev->power_on);
1861
1857 if (!test_bit(HCI_INIT, &hdev->flags) && 1862 if (!test_bit(HCI_INIT, &hdev->flags) &&
1858 !test_bit(HCI_SETUP, &hdev->dev_flags)) { 1863 !test_bit(HCI_SETUP, &hdev->dev_flags)) {
1859 hci_dev_lock(hdev); 1864 hci_dev_lock(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 9f5c5f244502..705078a0cc39 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -794,10 +794,10 @@ static void hci_set_le_support(struct hci_dev *hdev)
794 794
795 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { 795 if (test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) {
796 cp.le = 1; 796 cp.le = 1;
797 cp.simul = !!lmp_le_br_capable(hdev); 797 cp.simul = lmp_le_br_capable(hdev);
798 } 798 }
799 799
800 if (cp.le != !!lmp_host_le_capable(hdev)) 800 if (cp.le != lmp_host_le_capable(hdev))
801 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), 801 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp),
802 &cp); 802 &cp);
803} 803}
@@ -2047,15 +2047,53 @@ unlock:
2047 hci_conn_check_pending(hdev); 2047 hci_conn_check_pending(hdev);
2048} 2048}
2049 2049
2050void hci_conn_accept(struct hci_conn *conn, int mask)
2051{
2052 struct hci_dev *hdev = conn->hdev;
2053
2054 BT_DBG("conn %p", conn);
2055
2056 conn->state = BT_CONFIG;
2057
2058 if (!lmp_esco_capable(hdev)) {
2059 struct hci_cp_accept_conn_req cp;
2060
2061 bacpy(&cp.bdaddr, &conn->dst);
2062
2063 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
2064 cp.role = 0x00; /* Become master */
2065 else
2066 cp.role = 0x01; /* Remain slave */
2067
2068 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), &cp);
2069 } else /* lmp_esco_capable(hdev)) */ {
2070 struct hci_cp_accept_sync_conn_req cp;
2071
2072 bacpy(&cp.bdaddr, &conn->dst);
2073 cp.pkt_type = cpu_to_le16(conn->pkt_type);
2074
2075 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2076 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
2077 cp.max_latency = __constant_cpu_to_le16(0xffff);
2078 cp.content_format = cpu_to_le16(hdev->voice_setting);
2079 cp.retrans_effort = 0xff;
2080
2081 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
2082 sizeof(cp), &cp);
2083 }
2084}
2085
2050static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 2086static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2051{ 2087{
2052 struct hci_ev_conn_request *ev = (void *) skb->data; 2088 struct hci_ev_conn_request *ev = (void *) skb->data;
2053 int mask = hdev->link_mode; 2089 int mask = hdev->link_mode;
2090 __u8 flags = 0;
2054 2091
2055 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr, 2092 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
2056 ev->link_type); 2093 ev->link_type);
2057 2094
2058 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type); 2095 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
2096 &flags);
2059 2097
2060 if ((mask & HCI_LM_ACCEPT) && 2098 if ((mask & HCI_LM_ACCEPT) &&
2061 !hci_blacklist_lookup(hdev, &ev->bdaddr)) { 2099 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
@@ -2081,12 +2119,13 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2081 } 2119 }
2082 2120
2083 memcpy(conn->dev_class, ev->dev_class, 3); 2121 memcpy(conn->dev_class, ev->dev_class, 3);
2084 conn->state = BT_CONNECT;
2085 2122
2086 hci_dev_unlock(hdev); 2123 hci_dev_unlock(hdev);
2087 2124
2088 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) { 2125 if (ev->link_type == ACL_LINK ||
2126 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
2089 struct hci_cp_accept_conn_req cp; 2127 struct hci_cp_accept_conn_req cp;
2128 conn->state = BT_CONNECT;
2090 2129
2091 bacpy(&cp.bdaddr, &ev->bdaddr); 2130 bacpy(&cp.bdaddr, &ev->bdaddr);
2092 2131
@@ -2097,8 +2136,9 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2097 2136
2098 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp), 2137 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
2099 &cp); 2138 &cp);
2100 } else { 2139 } else if (!(flags & HCI_PROTO_DEFER)) {
2101 struct hci_cp_accept_sync_conn_req cp; 2140 struct hci_cp_accept_sync_conn_req cp;
2141 conn->state = BT_CONNECT;
2102 2142
2103 bacpy(&cp.bdaddr, &ev->bdaddr); 2143 bacpy(&cp.bdaddr, &ev->bdaddr);
2104 cp.pkt_type = cpu_to_le16(conn->pkt_type); 2144 cp.pkt_type = cpu_to_le16(conn->pkt_type);
@@ -2111,6 +2151,10 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2111 2151
2112 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ, 2152 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
2113 sizeof(cp), &cp); 2153 sizeof(cp), &cp);
2154 } else {
2155 conn->state = BT_CONNECT2;
2156 hci_proto_connect_cfm(conn, 0);
2157 hci_conn_put(conn);
2114 } 2158 }
2115 } else { 2159 } else {
2116 /* Connection rejected */ 2160 /* Connection rejected */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b52f66d22437..2c78208d793e 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -53,8 +53,7 @@ static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn,
53static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len, 53static void l2cap_send_cmd(struct l2cap_conn *conn, u8 ident, u8 code, u16 len,
54 void *data); 54 void *data);
55static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data); 55static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data);
56static void l2cap_send_disconn_req(struct l2cap_conn *conn, 56static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err);
57 struct l2cap_chan *chan, int err);
58 57
59static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control, 58static void l2cap_tx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
60 struct sk_buff_head *skbs, u8 event); 59 struct sk_buff_head *skbs, u8 event);
@@ -632,7 +631,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
632 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED && 631 if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
633 conn->hcon->type == ACL_LINK) { 632 conn->hcon->type == ACL_LINK) {
634 __set_chan_timer(chan, sk->sk_sndtimeo); 633 __set_chan_timer(chan, sk->sk_sndtimeo);
635 l2cap_send_disconn_req(conn, chan, reason); 634 l2cap_send_disconn_req(chan, reason);
636 } else 635 } else
637 l2cap_chan_del(chan, reason); 636 l2cap_chan_del(chan, reason);
638 break; 637 break;
@@ -1014,6 +1013,7 @@ static bool __amp_capable(struct l2cap_chan *chan)
1014 struct l2cap_conn *conn = chan->conn; 1013 struct l2cap_conn *conn = chan->conn;
1015 1014
1016 if (enable_hs && 1015 if (enable_hs &&
1016 hci_amp_capable() &&
1017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED && 1017 chan->chan_policy == BT_CHANNEL_POLICY_AMP_PREFERRED &&
1018 conn->fixed_chan_mask & L2CAP_FC_A2MP) 1018 conn->fixed_chan_mask & L2CAP_FC_A2MP)
1019 return true; 1019 return true;
@@ -1180,10 +1180,10 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
1180 } 1180 }
1181} 1181}
1182 1182
1183static void l2cap_send_disconn_req(struct l2cap_conn *conn, 1183static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
1184 struct l2cap_chan *chan, int err)
1185{ 1184{
1186 struct sock *sk = chan->sk; 1185 struct sock *sk = chan->sk;
1186 struct l2cap_conn *conn = chan->conn;
1187 struct l2cap_disconn_req req; 1187 struct l2cap_disconn_req req;
1188 1188
1189 if (!conn) 1189 if (!conn)
@@ -1960,7 +1960,7 @@ static void l2cap_ertm_resend(struct l2cap_chan *chan)
1960 if (chan->max_tx != 0 && 1960 if (chan->max_tx != 0 &&
1961 bt_cb(skb)->control.retries > chan->max_tx) { 1961 bt_cb(skb)->control.retries > chan->max_tx) {
1962 BT_DBG("Retry limit exceeded (%d)", chan->max_tx); 1962 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
1963 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 1963 l2cap_send_disconn_req(chan, ECONNRESET);
1964 l2cap_seq_list_clear(&chan->retrans_list); 1964 l2cap_seq_list_clear(&chan->retrans_list);
1965 break; 1965 break;
1966 } 1966 }
@@ -2666,7 +2666,7 @@ static void l2cap_tx_state_wait_f(struct l2cap_chan *chan,
2666 __set_monitor_timer(chan); 2666 __set_monitor_timer(chan);
2667 chan->retry_count++; 2667 chan->retry_count++;
2668 } else { 2668 } else {
2669 l2cap_send_disconn_req(chan->conn, chan, ECONNABORTED); 2669 l2cap_send_disconn_req(chan, ECONNABORTED);
2670 } 2670 }
2671 break; 2671 break;
2672 default: 2672 default:
@@ -3106,18 +3106,17 @@ done:
3106 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) 3106 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3107 l2cap_add_opt_efs(&ptr, chan); 3107 l2cap_add_opt_efs(&ptr, chan);
3108 3108
3109 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS))
3110 break;
3111
3112 if (chan->fcs == L2CAP_FCS_NONE ||
3113 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) {
3114 chan->fcs = L2CAP_FCS_NONE;
3115 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs);
3116 }
3117
3118 if (test_bit(FLAG_EXT_CTRL, &chan->flags)) 3109 if (test_bit(FLAG_EXT_CTRL, &chan->flags))
3119 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, 3110 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2,
3120 chan->tx_win); 3111 chan->tx_win);
3112
3113 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3114 if (chan->fcs == L2CAP_FCS_NONE ||
3115 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
3116 chan->fcs = L2CAP_FCS_NONE;
3117 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3118 chan->fcs);
3119 }
3121 break; 3120 break;
3122 3121
3123 case L2CAP_MODE_STREAMING: 3122 case L2CAP_MODE_STREAMING:
@@ -3139,14 +3138,13 @@ done:
3139 if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) 3138 if (test_bit(FLAG_EFS_ENABLE, &chan->flags))
3140 l2cap_add_opt_efs(&ptr, chan); 3139 l2cap_add_opt_efs(&ptr, chan);
3141 3140
3142 if (!(chan->conn->feat_mask & L2CAP_FEAT_FCS)) 3141 if (chan->conn->feat_mask & L2CAP_FEAT_FCS)
3143 break; 3142 if (chan->fcs == L2CAP_FCS_NONE ||
3144 3143 test_bit(CONF_RECV_NO_FCS, &chan->conf_state)) {
3145 if (chan->fcs == L2CAP_FCS_NONE || 3144 chan->fcs = L2CAP_FCS_NONE;
3146 test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) { 3145 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1,
3147 chan->fcs = L2CAP_FCS_NONE; 3146 chan->fcs);
3148 l2cap_add_conf_opt(&ptr, L2CAP_CONF_FCS, 1, chan->fcs); 3147 }
3149 }
3150 break; 3148 break;
3151 } 3149 }
3152 3150
@@ -3198,7 +3196,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data)
3198 3196
3199 case L2CAP_CONF_FCS: 3197 case L2CAP_CONF_FCS:
3200 if (val == L2CAP_FCS_NONE) 3198 if (val == L2CAP_FCS_NONE)
3201 set_bit(CONF_NO_FCS_RECV, &chan->conf_state); 3199 set_bit(CONF_RECV_NO_FCS, &chan->conf_state);
3202 break; 3200 break;
3203 3201
3204 case L2CAP_CONF_EFS: 3202 case L2CAP_CONF_EFS:
@@ -3433,6 +3431,13 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len,
3433 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), 3431 l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs),
3434 (unsigned long) &efs); 3432 (unsigned long) &efs);
3435 break; 3433 break;
3434
3435 case L2CAP_CONF_FCS:
3436 if (*result == L2CAP_CONF_PENDING)
3437 if (val == L2CAP_FCS_NONE)
3438 set_bit(CONF_RECV_NO_FCS,
3439 &chan->conf_state);
3440 break;
3436 } 3441 }
3437 } 3442 }
3438 3443
@@ -3802,7 +3807,7 @@ static inline void set_default_fcs(struct l2cap_chan *chan)
3802 */ 3807 */
3803 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING) 3808 if (chan->mode != L2CAP_MODE_ERTM && chan->mode != L2CAP_MODE_STREAMING)
3804 chan->fcs = L2CAP_FCS_NONE; 3809 chan->fcs = L2CAP_FCS_NONE;
3805 else if (!test_bit(CONF_NO_FCS_RECV, &chan->conf_state)) 3810 else if (!test_bit(CONF_RECV_NO_FCS, &chan->conf_state))
3806 chan->fcs = L2CAP_FCS_CRC16; 3811 chan->fcs = L2CAP_FCS_CRC16;
3807} 3812}
3808 3813
@@ -3877,7 +3882,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
3877 /* Complete config. */ 3882 /* Complete config. */
3878 len = l2cap_parse_conf_req(chan, rsp); 3883 len = l2cap_parse_conf_req(chan, rsp);
3879 if (len < 0) { 3884 if (len < 0) {
3880 l2cap_send_disconn_req(conn, chan, ECONNRESET); 3885 l2cap_send_disconn_req(chan, ECONNRESET);
3881 goto unlock; 3886 goto unlock;
3882 } 3887 }
3883 3888
@@ -3899,7 +3904,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
3899 err = l2cap_ertm_init(chan); 3904 err = l2cap_ertm_init(chan);
3900 3905
3901 if (err < 0) 3906 if (err < 0)
3902 l2cap_send_disconn_req(chan->conn, chan, -err); 3907 l2cap_send_disconn_req(chan, -err);
3903 else 3908 else
3904 l2cap_chan_ready(chan); 3909 l2cap_chan_ready(chan);
3905 3910
@@ -3967,7 +3972,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3967 len = l2cap_parse_conf_rsp(chan, rsp->data, len, 3972 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3968 buf, &result); 3973 buf, &result);
3969 if (len < 0) { 3974 if (len < 0) {
3970 l2cap_send_disconn_req(conn, chan, ECONNRESET); 3975 l2cap_send_disconn_req(chan, ECONNRESET);
3971 goto done; 3976 goto done;
3972 } 3977 }
3973 3978
@@ -3988,7 +3993,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3988 char req[64]; 3993 char req[64];
3989 3994
3990 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) { 3995 if (len > sizeof(req) - sizeof(struct l2cap_conf_req)) {
3991 l2cap_send_disconn_req(conn, chan, ECONNRESET); 3996 l2cap_send_disconn_req(chan, ECONNRESET);
3992 goto done; 3997 goto done;
3993 } 3998 }
3994 3999
@@ -3997,7 +4002,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
3997 len = l2cap_parse_conf_rsp(chan, rsp->data, len, 4002 len = l2cap_parse_conf_rsp(chan, rsp->data, len,
3998 req, &result); 4003 req, &result);
3999 if (len < 0) { 4004 if (len < 0) {
4000 l2cap_send_disconn_req(conn, chan, ECONNRESET); 4005 l2cap_send_disconn_req(chan, ECONNRESET);
4001 goto done; 4006 goto done;
4002 } 4007 }
4003 4008
@@ -4013,7 +4018,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
4013 l2cap_chan_set_err(chan, ECONNRESET); 4018 l2cap_chan_set_err(chan, ECONNRESET);
4014 4019
4015 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT); 4020 __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
4016 l2cap_send_disconn_req(conn, chan, ECONNRESET); 4021 l2cap_send_disconn_req(chan, ECONNRESET);
4017 goto done; 4022 goto done;
4018 } 4023 }
4019 4024
@@ -4030,7 +4035,7 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn,
4030 err = l2cap_ertm_init(chan); 4035 err = l2cap_ertm_init(chan);
4031 4036
4032 if (err < 0) 4037 if (err < 0)
4033 l2cap_send_disconn_req(chan->conn, chan, -err); 4038 l2cap_send_disconn_req(chan, -err);
4034 else 4039 else
4035 l2cap_chan_ready(chan); 4040 l2cap_chan_ready(chan);
4036 } 4041 }
@@ -4392,7 +4397,7 @@ static void l2cap_logical_fail(struct l2cap_chan *chan)
4392 /* Logical link setup failed */ 4397 /* Logical link setup failed */
4393 if (chan->state != BT_CONNECTED) { 4398 if (chan->state != BT_CONNECTED) {
4394 /* Create channel failure, disconnect */ 4399 /* Create channel failure, disconnect */
4395 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 4400 l2cap_send_disconn_req(chan, ECONNRESET);
4396 return; 4401 return;
4397 } 4402 }
4398 4403
@@ -4435,7 +4440,7 @@ static void l2cap_logical_finish_create(struct l2cap_chan *chan,
4435 4440
4436 err = l2cap_ertm_init(chan); 4441 err = l2cap_ertm_init(chan);
4437 if (err < 0) 4442 if (err < 0)
4438 l2cap_send_disconn_req(chan->conn, chan, -err); 4443 l2cap_send_disconn_req(chan, -err);
4439 else 4444 else
4440 l2cap_chan_ready(chan); 4445 l2cap_chan_ready(chan);
4441 } 4446 }
@@ -5400,7 +5405,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan,
5400 5405
5401 if (control->reqseq == chan->next_tx_seq) { 5406 if (control->reqseq == chan->next_tx_seq) {
5402 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); 5407 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
5403 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 5408 l2cap_send_disconn_req(chan, ECONNRESET);
5404 return; 5409 return;
5405 } 5410 }
5406 5411
@@ -5414,7 +5419,7 @@ static void l2cap_handle_srej(struct l2cap_chan *chan,
5414 5419
5415 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) { 5420 if (chan->max_tx != 0 && bt_cb(skb)->control.retries >= chan->max_tx) {
5416 BT_DBG("Retry limit exceeded (%d)", chan->max_tx); 5421 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
5417 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 5422 l2cap_send_disconn_req(chan, ECONNRESET);
5418 return; 5423 return;
5419 } 5424 }
5420 5425
@@ -5458,7 +5463,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan,
5458 5463
5459 if (control->reqseq == chan->next_tx_seq) { 5464 if (control->reqseq == chan->next_tx_seq) {
5460 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq); 5465 BT_DBG("Invalid reqseq %d, disconnecting", control->reqseq);
5461 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 5466 l2cap_send_disconn_req(chan, ECONNRESET);
5462 return; 5467 return;
5463 } 5468 }
5464 5469
@@ -5467,7 +5472,7 @@ static void l2cap_handle_rej(struct l2cap_chan *chan,
5467 if (chan->max_tx && skb && 5472 if (chan->max_tx && skb &&
5468 bt_cb(skb)->control.retries >= chan->max_tx) { 5473 bt_cb(skb)->control.retries >= chan->max_tx) {
5469 BT_DBG("Retry limit exceeded (%d)", chan->max_tx); 5474 BT_DBG("Retry limit exceeded (%d)", chan->max_tx);
5470 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 5475 l2cap_send_disconn_req(chan, ECONNRESET);
5471 return; 5476 return;
5472 } 5477 }
5473 5478
@@ -5651,8 +5656,7 @@ static int l2cap_rx_state_recv(struct l2cap_chan *chan,
5651 break; 5656 break;
5652 case L2CAP_TXSEQ_INVALID: 5657 case L2CAP_TXSEQ_INVALID:
5653 default: 5658 default:
5654 l2cap_send_disconn_req(chan->conn, chan, 5659 l2cap_send_disconn_req(chan, ECONNRESET);
5655 ECONNRESET);
5656 break; 5660 break;
5657 } 5661 }
5658 break; 5662 break;
@@ -5785,8 +5789,7 @@ static int l2cap_rx_state_srej_sent(struct l2cap_chan *chan,
5785 break; 5789 break;
5786 case L2CAP_TXSEQ_INVALID: 5790 case L2CAP_TXSEQ_INVALID:
5787 default: 5791 default:
5788 l2cap_send_disconn_req(chan->conn, chan, 5792 l2cap_send_disconn_req(chan, ECONNRESET);
5789 ECONNRESET);
5790 break; 5793 break;
5791 } 5794 }
5792 break; 5795 break;
@@ -5981,7 +5984,7 @@ static int l2cap_rx(struct l2cap_chan *chan, struct l2cap_ctrl *control,
5981 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d", 5984 BT_DBG("Invalid reqseq %d (next_tx_seq %d, expected_ack_seq %d",
5982 control->reqseq, chan->next_tx_seq, 5985 control->reqseq, chan->next_tx_seq,
5983 chan->expected_ack_seq); 5986 chan->expected_ack_seq);
5984 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 5987 l2cap_send_disconn_req(chan, ECONNRESET);
5985 } 5988 }
5986 5989
5987 return err; 5990 return err;
@@ -6050,7 +6053,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6050 len -= L2CAP_FCS_SIZE; 6053 len -= L2CAP_FCS_SIZE;
6051 6054
6052 if (len > chan->mps) { 6055 if (len > chan->mps) {
6053 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 6056 l2cap_send_disconn_req(chan, ECONNRESET);
6054 goto drop; 6057 goto drop;
6055 } 6058 }
6056 6059
@@ -6075,8 +6078,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6075 } 6078 }
6076 6079
6077 if (err) 6080 if (err)
6078 l2cap_send_disconn_req(chan->conn, chan, 6081 l2cap_send_disconn_req(chan, ECONNRESET);
6079 ECONNRESET);
6080 } else { 6082 } else {
6081 const u8 rx_func_to_event[4] = { 6083 const u8 rx_func_to_event[4] = {
6082 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ, 6084 L2CAP_EV_RECV_RR, L2CAP_EV_RECV_REJ,
@@ -6093,7 +6095,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6093 6095
6094 if (len != 0) { 6096 if (len != 0) {
6095 BT_ERR("Trailing bytes: %d in sframe", len); 6097 BT_ERR("Trailing bytes: %d in sframe", len);
6096 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 6098 l2cap_send_disconn_req(chan, ECONNRESET);
6097 goto drop; 6099 goto drop;
6098 } 6100 }
6099 6101
@@ -6104,7 +6106,7 @@ static int l2cap_data_rcv(struct l2cap_chan *chan, struct sk_buff *skb)
6104 6106
6105 event = rx_func_to_event[control->super]; 6107 event = rx_func_to_event[control->super];
6106 if (l2cap_rx(chan, control, skb, event)) 6108 if (l2cap_rx(chan, control, skb, event))
6107 l2cap_send_disconn_req(chan->conn, chan, ECONNRESET); 6109 l2cap_send_disconn_req(chan, ECONNRESET);
6108 } 6110 }
6109 6111
6110 return 0; 6112 return 0;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 142764aec2af..f559b966279c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1226,7 +1226,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1226 } 1226 }
1227 1227
1228 val = !!cp->val; 1228 val = !!cp->val;
1229 enabled = !!lmp_host_le_capable(hdev); 1229 enabled = lmp_host_le_capable(hdev);
1230 1230
1231 if (!hdev_is_powered(hdev) || val == enabled) { 1231 if (!hdev_is_powered(hdev) || val == enabled) {
1232 bool changed = false; 1232 bool changed = false;
@@ -1262,7 +1262,7 @@ static int set_le(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
1262 1262
1263 if (val) { 1263 if (val) {
1264 hci_cp.le = val; 1264 hci_cp.le = val;
1265 hci_cp.simul = !!lmp_le_br_capable(hdev); 1265 hci_cp.simul = lmp_le_br_capable(hdev);
1266 } 1266 }
1267 1267
1268 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp), 1268 err = hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(hci_cp),
@@ -2926,13 +2926,13 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2926 struct hci_cp_write_le_host_supported cp; 2926 struct hci_cp_write_le_host_supported cp;
2927 2927
2928 cp.le = 1; 2928 cp.le = 1;
2929 cp.simul = !!lmp_le_br_capable(hdev); 2929 cp.simul = lmp_le_br_capable(hdev);
2930 2930
2931 /* Check first if we already have the right 2931 /* Check first if we already have the right
2932 * host state (host features set) 2932 * host state (host features set)
2933 */ 2933 */
2934 if (cp.le != !!lmp_host_le_capable(hdev) || 2934 if (cp.le != lmp_host_le_capable(hdev) ||
2935 cp.simul != !!lmp_host_le_br_capable(hdev)) 2935 cp.simul != lmp_host_le_br_capable(hdev))
2936 hci_send_cmd(hdev, 2936 hci_send_cmd(hdev,
2937 HCI_OP_WRITE_LE_HOST_SUPPORTED, 2937 HCI_OP_WRITE_LE_HOST_SUPPORTED,
2938 sizeof(cp), &cp); 2938 sizeof(cp), &cp);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 4ddef57d03a7..ce3f6658f4b2 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -467,7 +467,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
467 long timeo; 467 long timeo;
468 int err = 0; 468 int err = 0;
469 469
470 lock_sock(sk); 470 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
471 471
472 if (sk->sk_type != SOCK_STREAM) { 472 if (sk->sk_type != SOCK_STREAM) {
473 err = -EINVAL; 473 err = -EINVAL;
@@ -504,7 +504,7 @@ static int rfcomm_sock_accept(struct socket *sock, struct socket *newsock, int f
504 504
505 release_sock(sk); 505 release_sock(sk);
506 timeo = schedule_timeout(timeo); 506 timeo = schedule_timeout(timeo);
507 lock_sock(sk); 507 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
508 } 508 }
509 __set_current_state(TASK_RUNNING); 509 __set_current_state(TASK_RUNNING);
510 remove_wait_queue(sk_sleep(sk), &wait); 510 remove_wait_queue(sk_sleep(sk), &wait);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 450cdcd88e5c..531a93d613d4 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -131,15 +131,6 @@ static int sco_conn_del(struct hci_conn *hcon, int err)
131 sco_sock_clear_timer(sk); 131 sco_sock_clear_timer(sk);
132 sco_chan_del(sk, err); 132 sco_chan_del(sk, err);
133 bh_unlock_sock(sk); 133 bh_unlock_sock(sk);
134
135 sco_conn_lock(conn);
136 conn->sk = NULL;
137 sco_pi(sk)->conn = NULL;
138 sco_conn_unlock(conn);
139
140 if (conn->hcon)
141 hci_conn_put(conn->hcon);
142
143 sco_sock_kill(sk); 134 sco_sock_kill(sk);
144 } 135 }
145 136
@@ -397,6 +388,7 @@ static void sco_sock_init(struct sock *sk, struct sock *parent)
397 388
398 if (parent) { 389 if (parent) {
399 sk->sk_type = parent->sk_type; 390 sk->sk_type = parent->sk_type;
391 bt_sk(sk)->flags = bt_sk(parent)->flags;
400 security_sk_clone(parent, sk); 392 security_sk_clone(parent, sk);
401 } 393 }
402} 394}
@@ -662,16 +654,57 @@ static int sco_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
662 return err; 654 return err;
663} 655}
664 656
657static int sco_sock_recvmsg(struct kiocb *iocb, struct socket *sock,
658 struct msghdr *msg, size_t len, int flags)
659{
660 struct sock *sk = sock->sk;
661 struct sco_pinfo *pi = sco_pi(sk);
662
663 lock_sock(sk);
664
665 if (sk->sk_state == BT_CONNECT2 &&
666 test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
667 hci_conn_accept(pi->conn->hcon, 0);
668 sk->sk_state = BT_CONFIG;
669
670 release_sock(sk);
671 return 0;
672 }
673
674 release_sock(sk);
675
676 return bt_sock_recvmsg(iocb, sock, msg, len, flags);
677}
678
665static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen) 679static int sco_sock_setsockopt(struct socket *sock, int level, int optname, char __user *optval, unsigned int optlen)
666{ 680{
667 struct sock *sk = sock->sk; 681 struct sock *sk = sock->sk;
668 int err = 0; 682 int err = 0;
683 u32 opt;
669 684
670 BT_DBG("sk %p", sk); 685 BT_DBG("sk %p", sk);
671 686
672 lock_sock(sk); 687 lock_sock(sk);
673 688
674 switch (optname) { 689 switch (optname) {
690
691 case BT_DEFER_SETUP:
692 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
693 err = -EINVAL;
694 break;
695 }
696
697 if (get_user(opt, (u32 __user *) optval)) {
698 err = -EFAULT;
699 break;
700 }
701
702 if (opt)
703 set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
704 else
705 clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
706 break;
707
675 default: 708 default:
676 err = -ENOPROTOOPT; 709 err = -ENOPROTOOPT;
677 break; 710 break;
@@ -753,6 +786,19 @@ static int sco_sock_getsockopt(struct socket *sock, int level, int optname, char
753 lock_sock(sk); 786 lock_sock(sk);
754 787
755 switch (optname) { 788 switch (optname) {
789
790 case BT_DEFER_SETUP:
791 if (sk->sk_state != BT_BOUND && sk->sk_state != BT_LISTEN) {
792 err = -EINVAL;
793 break;
794 }
795
796 if (put_user(test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags),
797 (u32 __user *) optval))
798 err = -EFAULT;
799
800 break;
801
756 default: 802 default:
757 err = -ENOPROTOOPT; 803 err = -ENOPROTOOPT;
758 break; 804 break;
@@ -830,6 +876,16 @@ static void sco_chan_del(struct sock *sk, int err)
830 876
831 BT_DBG("sk %p, conn %p, err %d", sk, conn, err); 877 BT_DBG("sk %p, conn %p, err %d", sk, conn, err);
832 878
879 if (conn) {
880 sco_conn_lock(conn);
881 conn->sk = NULL;
882 sco_pi(sk)->conn = NULL;
883 sco_conn_unlock(conn);
884
885 if (conn->hcon)
886 hci_conn_put(conn->hcon);
887 }
888
833 sk->sk_state = BT_CLOSED; 889 sk->sk_state = BT_CLOSED;
834 sk->sk_err = err; 890 sk->sk_err = err;
835 sk->sk_state_change(sk); 891 sk->sk_state_change(sk);
@@ -874,7 +930,10 @@ static void sco_conn_ready(struct sco_conn *conn)
874 hci_conn_hold(conn->hcon); 930 hci_conn_hold(conn->hcon);
875 __sco_chan_add(conn, sk, parent); 931 __sco_chan_add(conn, sk, parent);
876 932
877 sk->sk_state = BT_CONNECTED; 933 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags))
934 sk->sk_state = BT_CONNECT2;
935 else
936 sk->sk_state = BT_CONNECTED;
878 937
879 /* Wake up parent */ 938 /* Wake up parent */
880 parent->sk_data_ready(parent, 1); 939 parent->sk_data_ready(parent, 1);
@@ -887,7 +946,7 @@ done:
887} 946}
888 947
889/* ----- SCO interface with lower layer (HCI) ----- */ 948/* ----- SCO interface with lower layer (HCI) ----- */
890int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr) 949int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)
891{ 950{
892 struct sock *sk; 951 struct sock *sk;
893 struct hlist_node *node; 952 struct hlist_node *node;
@@ -904,6 +963,9 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
904 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) || 963 if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr) ||
905 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) { 964 !bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
906 lm |= HCI_LM_ACCEPT; 965 lm |= HCI_LM_ACCEPT;
966
967 if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
968 *flags |= HCI_PROTO_DEFER;
907 break; 969 break;
908 } 970 }
909 } 971 }
@@ -992,7 +1054,7 @@ static const struct proto_ops sco_sock_ops = {
992 .accept = sco_sock_accept, 1054 .accept = sco_sock_accept,
993 .getname = sco_sock_getname, 1055 .getname = sco_sock_getname,
994 .sendmsg = sco_sock_sendmsg, 1056 .sendmsg = sco_sock_sendmsg,
995 .recvmsg = bt_sock_recvmsg, 1057 .recvmsg = sco_sock_recvmsg,
996 .poll = bt_sock_poll, 1058 .poll = bt_sock_poll,
997 .ioctl = bt_sock_ioctl, 1059 .ioctl = bt_sock_ioctl,
998 .mmap = sock_no_mmap, 1060 .mmap = sock_no_mmap,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 4965aa6424ec..5c61677487cf 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -398,6 +398,38 @@ void sta_set_rate_info_tx(struct sta_info *sta,
398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI; 398 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
399} 399}
400 400
401void sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
402{
403 rinfo->flags = 0;
404
405 if (sta->last_rx_rate_flag & RX_FLAG_HT) {
406 rinfo->flags |= RATE_INFO_FLAGS_MCS;
407 rinfo->mcs = sta->last_rx_rate_idx;
408 } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
409 rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
410 rinfo->nss = sta->last_rx_rate_vht_nss;
411 rinfo->mcs = sta->last_rx_rate_idx;
412 } else {
413 struct ieee80211_supported_band *sband;
414
415 sband = sta->local->hw.wiphy->bands[
416 ieee80211_get_sdata_band(sta->sdata)];
417 rinfo->legacy =
418 sband->bitrates[sta->last_rx_rate_idx].bitrate;
419 }
420
421 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
422 rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
423 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
424 rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
425 if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
426 rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
427 if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
428 rinfo->flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
429 if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
430 rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
431}
432
401static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 433static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
402{ 434{
403 struct ieee80211_sub_if_data *sdata = sta->sdata; 435 struct ieee80211_sub_if_data *sdata = sta->sdata;
@@ -444,34 +476,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
444 } 476 }
445 477
446 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); 478 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
447 479 sta_set_rate_info_rx(sta, &sinfo->rxrate);
448 sinfo->rxrate.flags = 0;
449 if (sta->last_rx_rate_flag & RX_FLAG_HT) {
450 sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
451 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
452 } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
453 sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
454 sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
455 sinfo->rxrate.mcs = sta->last_rx_rate_idx;
456 } else {
457 struct ieee80211_supported_band *sband;
458
459 sband = sta->local->hw.wiphy->bands[
460 ieee80211_get_sdata_band(sta->sdata)];
461 sinfo->rxrate.legacy =
462 sband->bitrates[sta->last_rx_rate_idx].bitrate;
463 }
464
465 if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
466 sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
467 if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
468 sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
469 if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
470 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
471 if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
472 sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
473 if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
474 sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
475 480
476 if (ieee80211_vif_is_mesh(&sdata->vif)) { 481 if (ieee80211_vif_is_mesh(&sdata->vif)) {
477#ifdef CONFIG_MAC80211_MESH 482#ifdef CONFIG_MAC80211_MESH
@@ -893,7 +898,8 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
893 u32 changed = BSS_CHANGED_BEACON_INT | 898 u32 changed = BSS_CHANGED_BEACON_INT |
894 BSS_CHANGED_BEACON_ENABLED | 899 BSS_CHANGED_BEACON_ENABLED |
895 BSS_CHANGED_BEACON | 900 BSS_CHANGED_BEACON |
896 BSS_CHANGED_SSID; 901 BSS_CHANGED_SSID |
902 BSS_CHANGED_P2P_PS;
897 int err; 903 int err;
898 904
899 old = rtnl_dereference(sdata->u.ap.beacon); 905 old = rtnl_dereference(sdata->u.ap.beacon);
@@ -932,6 +938,9 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
932 sdata->vif.bss_conf.hidden_ssid = 938 sdata->vif.bss_conf.hidden_ssid =
933 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE); 939 (params->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
934 940
941 sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
942 sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
943
935 err = ieee80211_assign_beacon(sdata, &params->beacon); 944 err = ieee80211_assign_beacon(sdata, &params->beacon);
936 if (err < 0) 945 if (err < 0)
937 return err; 946 return err;
@@ -1807,6 +1816,16 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1807 changed |= BSS_CHANGED_HT; 1816 changed |= BSS_CHANGED_HT;
1808 } 1817 }
1809 1818
1819 if (params->p2p_ctwindow >= 0) {
1820 sdata->vif.bss_conf.p2p_ctwindow = params->p2p_ctwindow;
1821 changed |= BSS_CHANGED_P2P_PS;
1822 }
1823
1824 if (params->p2p_opp_ps >= 0) {
1825 sdata->vif.bss_conf.p2p_oppps = params->p2p_opp_ps;
1826 changed |= BSS_CHANGED_P2P_PS;
1827 }
1828
1810 ieee80211_bss_info_change_notify(sdata, changed); 1829 ieee80211_bss_info_change_notify(sdata, changed);
1811 1830
1812 return 0; 1831 return 0;
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 89281d24b094..49a1c70bbd70 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -53,6 +53,7 @@ static const struct file_operations sta_ ##name## _ops = { \
53STA_FILE(aid, sta.aid, D); 53STA_FILE(aid, sta.aid, D);
54STA_FILE(dev, sdata->name, S); 54STA_FILE(dev, sdata->name, S);
55STA_FILE(last_signal, last_signal, D); 55STA_FILE(last_signal, last_signal, D);
56STA_FILE(last_ack_signal, last_ack_signal, D);
56 57
57static ssize_t sta_flags_read(struct file *file, char __user *userbuf, 58static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
58 size_t count, loff_t *ppos) 59 size_t count, loff_t *ppos)
@@ -321,6 +322,38 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
321} 322}
322STA_OPS(ht_capa); 323STA_OPS(ht_capa);
323 324
325static ssize_t sta_current_tx_rate_read(struct file *file, char __user *userbuf,
326 size_t count, loff_t *ppos)
327{
328 struct sta_info *sta = file->private_data;
329 struct rate_info rinfo;
330 u16 rate;
331 sta_set_rate_info_tx(sta, &sta->last_tx_rate, &rinfo);
332 rate = cfg80211_calculate_bitrate(&rinfo);
333
334 return mac80211_format_buffer(userbuf, count, ppos,
335 "%d.%d MBit/s\n",
336 rate/10, rate%10);
337}
338STA_OPS(current_tx_rate);
339
340static ssize_t sta_last_rx_rate_read(struct file *file, char __user *userbuf,
341 size_t count, loff_t *ppos)
342{
343 struct sta_info *sta = file->private_data;
344 struct rate_info rinfo;
345 u16 rate;
346
347 sta_set_rate_info_rx(sta, &rinfo);
348
349 rate = cfg80211_calculate_bitrate(&rinfo);
350
351 return mac80211_format_buffer(userbuf, count, ppos,
352 "%d.%d MBit/s\n",
353 rate/10, rate%10);
354}
355STA_OPS(last_rx_rate);
356
324#define DEBUGFS_ADD(name) \ 357#define DEBUGFS_ADD(name) \
325 debugfs_create_file(#name, 0400, \ 358 debugfs_create_file(#name, 0400, \
326 sta->debugfs.dir, sta, &sta_ ##name## _ops); 359 sta->debugfs.dir, sta, &sta_ ##name## _ops);
@@ -369,6 +402,9 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
369 DEBUGFS_ADD(dev); 402 DEBUGFS_ADD(dev);
370 DEBUGFS_ADD(last_signal); 403 DEBUGFS_ADD(last_signal);
371 DEBUGFS_ADD(ht_capa); 404 DEBUGFS_ADD(ht_capa);
405 DEBUGFS_ADD(last_ack_signal);
406 DEBUGFS_ADD(current_tx_rate);
407 DEBUGFS_ADD(last_rx_rate);
372 408
373 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets); 409 DEBUGFS_ADD_COUNTER(rx_packets, rx_packets);
374 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets); 410 DEBUGFS_ADD_COUNTER(tx_packets, tx_packets);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 5c0d5a6946c1..42d0d0267730 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -371,6 +371,8 @@ enum ieee80211_sta_flags {
371 IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9), 371 IEEE80211_STA_RESET_SIGNAL_AVE = BIT(9),
372 IEEE80211_STA_DISABLE_40MHZ = BIT(10), 372 IEEE80211_STA_DISABLE_40MHZ = BIT(10),
373 IEEE80211_STA_DISABLE_VHT = BIT(11), 373 IEEE80211_STA_DISABLE_VHT = BIT(11),
374 IEEE80211_STA_DISABLE_80P80MHZ = BIT(12),
375 IEEE80211_STA_DISABLE_160MHZ = BIT(13),
374}; 376};
375 377
376struct ieee80211_mgd_auth_data { 378struct ieee80211_mgd_auth_data {
@@ -1032,6 +1034,7 @@ struct ieee80211_local {
1032 enum ieee80211_band hw_scan_band; 1034 enum ieee80211_band hw_scan_band;
1033 int scan_channel_idx; 1035 int scan_channel_idx;
1034 int scan_ies_len; 1036 int scan_ies_len;
1037 int hw_scan_ies_bufsize;
1035 1038
1036 struct work_struct sched_scan_stopped_work; 1039 struct work_struct sched_scan_stopped_work;
1037 struct ieee80211_sub_if_data __rcu *sched_scan_sdata; 1040 struct ieee80211_sub_if_data __rcu *sched_scan_sdata;
@@ -1573,7 +1576,7 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1573 const u8 *bssid, u16 stype, u16 reason, 1576 const u8 *bssid, u16 stype, u16 reason,
1574 bool send_frame, u8 *frame_buf); 1577 bool send_frame, u8 *frame_buf);
1575int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1578int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1576 const u8 *ie, size_t ie_len, 1579 size_t buffer_len, const u8 *ie, size_t ie_len,
1577 enum ieee80211_band band, u32 rate_mask, 1580 enum ieee80211_band band, u32 rate_mask,
1578 u8 channel); 1581 u8 channel);
1579struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1582struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 5331662489f7..40c36d5d7377 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -223,6 +223,47 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
223 return 0; 223 return 0;
224} 224}
225 225
226static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr)
227{
228 struct ieee80211_sub_if_data *sdata;
229 u64 new, mask, tmp;
230 u8 *m;
231 int ret = 0;
232
233 if (is_zero_ether_addr(local->hw.wiphy->addr_mask))
234 return 0;
235
236 m = addr;
237 new = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
238 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
239 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
240
241 m = local->hw.wiphy->addr_mask;
242 mask = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
243 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
244 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
245
246
247 mutex_lock(&local->iflist_mtx);
248 list_for_each_entry(sdata, &local->interfaces, list) {
249 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
250 continue;
251
252 m = sdata->vif.addr;
253 tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) |
254 ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
255 ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
256
257 if ((new & ~mask) != (tmp & ~mask)) {
258 ret = -EINVAL;
259 break;
260 }
261 }
262 mutex_unlock(&local->iflist_mtx);
263
264 return ret;
265}
266
226static int ieee80211_change_mac(struct net_device *dev, void *addr) 267static int ieee80211_change_mac(struct net_device *dev, void *addr)
227{ 268{
228 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 269 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -232,6 +273,10 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
232 if (ieee80211_sdata_running(sdata)) 273 if (ieee80211_sdata_running(sdata))
233 return -EBUSY; 274 return -EBUSY;
234 275
276 ret = ieee80211_verify_mac(sdata->local, sa->sa_data);
277 if (ret)
278 return ret;
279
235 ret = eth_mac_addr(dev, sa); 280 ret = eth_mac_addr(dev, sa);
236 281
237 if (ret == 0) 282 if (ret == 0)
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index f5e4c1f24bf2..1b087fff93e7 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -474,7 +474,8 @@ ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
474 .tx = 0xffff, 474 .tx = 0xffff,
475 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | 475 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
476 BIT(IEEE80211_STYPE_AUTH >> 4) | 476 BIT(IEEE80211_STYPE_AUTH >> 4) |
477 BIT(IEEE80211_STYPE_DEAUTH >> 4), 477 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
478 BIT(IEEE80211_STYPE_PROBE_REQ >> 4),
478 }, 479 },
479 [NL80211_IFTYPE_STATION] = { 480 [NL80211_IFTYPE_STATION] = {
480 .tx = 0xffff, 481 .tx = 0xffff,
@@ -638,6 +639,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
638 local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS | 639 local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
639 IEEE80211_RADIOTAP_MCS_HAVE_GI | 640 IEEE80211_RADIOTAP_MCS_HAVE_GI |
640 IEEE80211_RADIOTAP_MCS_HAVE_BW; 641 IEEE80211_RADIOTAP_MCS_HAVE_BW;
642 local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
643 IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
641 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; 644 local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
642 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask; 645 wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
643 646
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ca52dfdd5375..4b274e9c91a5 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -391,7 +391,8 @@ static struct sta_info *mesh_peer_init(struct ieee80211_sub_if_data *sdata,
391 sta->ch_width = chandef.width; 391 sta->ch_width = chandef.width;
392 } 392 }
393 393
394 rate_control_rate_init(sta); 394 if (insert)
395 rate_control_rate_init(sta);
395 spin_unlock_bh(&sta->lock); 396 spin_unlock_bh(&sta->lock);
396 397
397 if (insert && sta_info_insert(sta)) 398 if (insert && sta_info_insert(sta))
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c
index 0f40086cce18..aa8d1e437385 100644
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -195,11 +195,15 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata)
195 ifmsh->sync_offset_clockdrift_max); 195 ifmsh->sync_offset_clockdrift_max);
196 set_bit(MESH_WORK_DRIFT_ADJUST, 196 set_bit(MESH_WORK_DRIFT_ADJUST,
197 &ifmsh->wrkq_flags); 197 &ifmsh->wrkq_flags);
198
199 ifmsh->adjusting_tbtt = true;
198 } else { 200 } else {
199 msync_dbg(sdata, 201 msync_dbg(sdata,
200 "TBTT : max clockdrift=%lld; too small to adjust\n", 202 "TBTT : max clockdrift=%lld; too small to adjust\n",
201 (long long)ifmsh->sync_offset_clockdrift_max); 203 (long long)ifmsh->sync_offset_clockdrift_max);
202 ifmsh->sync_offset_clockdrift_max = 0; 204 ifmsh->sync_offset_clockdrift_max = 0;
205
206 ifmsh->adjusting_tbtt = false;
203 } 207 }
204 spin_unlock_bh(&ifmsh->sync_offset_lock); 208 spin_unlock_bh(&ifmsh->sync_offset_lock);
205} 209}
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d2a4f78b4b0f..09556303c7e1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -354,6 +354,16 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
354 /* determine capability flags */ 354 /* determine capability flags */
355 cap = vht_cap.cap; 355 cap = vht_cap.cap;
356 356
357 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_80P80MHZ) {
358 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ;
359 cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
360 }
361
362 if (sdata->u.mgd.flags & IEEE80211_STA_DISABLE_160MHZ) {
363 cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
364 cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
365 }
366
357 /* reserve and fill IE */ 367 /* reserve and fill IE */
358 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2); 368 pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
359 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap); 369 ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
@@ -543,6 +553,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
543 offset = noffset; 553 offset = noffset;
544 } 554 }
545 555
556 if (WARN_ON_ONCE((ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
557 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)))
558 ifmgd->flags |= IEEE80211_STA_DISABLE_VHT;
559
546 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) 560 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
547 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, 561 ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param,
548 sband, chan, sdata->smps_mode); 562 sband, chan, sdata->smps_mode);
@@ -775,6 +789,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
775 "not handling channel switch with channel contexts\n"); 789 "not handling channel switch with channel contexts\n");
776 ieee80211_queue_work(&sdata->local->hw, 790 ieee80211_queue_work(&sdata->local->hw,
777 &ifmgd->csa_connection_drop_work); 791 &ifmgd->csa_connection_drop_work);
792 return;
778 } 793 }
779 794
780 mutex_lock(&sdata->local->chanctx_mtx); 795 mutex_lock(&sdata->local->chanctx_mtx);
@@ -1368,19 +1383,26 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1368 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE; 1383 sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
1369 1384
1370 if (sdata->vif.p2p) { 1385 if (sdata->vif.p2p) {
1371 u8 noa[2]; 1386 const struct cfg80211_bss_ies *ies;
1372 int ret;
1373 1387
1374 ret = cfg80211_get_p2p_attr(cbss->information_elements, 1388 rcu_read_lock();
1375 cbss->len_information_elements, 1389 ies = rcu_dereference(cbss->ies);
1376 IEEE80211_P2P_ATTR_ABSENCE_NOTICE, 1390 if (ies) {
1377 noa, sizeof(noa)); 1391 u8 noa[2];
1378 if (ret >= 2) { 1392 int ret;
1379 bss_conf->p2p_oppps = noa[1] & 0x80; 1393
1380 bss_conf->p2p_ctwindow = noa[1] & 0x7f; 1394 ret = cfg80211_get_p2p_attr(
1381 bss_info_changed |= BSS_CHANGED_P2P_PS; 1395 ies->data, ies->len,
1382 sdata->u.mgd.p2p_noa_index = noa[0]; 1396 IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
1397 noa, sizeof(noa));
1398 if (ret >= 2) {
1399 bss_conf->p2p_oppps = noa[1] & 0x80;
1400 bss_conf->p2p_ctwindow = noa[1] & 0x7f;
1401 bss_info_changed |= BSS_CHANGED_P2P_PS;
1402 sdata->u.mgd.p2p_noa_index = noa[0];
1403 }
1383 } 1404 }
1405 rcu_read_unlock();
1384 } 1406 }
1385 1407
1386 /* just to be sure */ 1408 /* just to be sure */
@@ -1645,6 +1667,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1645 } else { 1667 } else {
1646 int ssid_len; 1668 int ssid_len;
1647 1669
1670 rcu_read_lock();
1648 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); 1671 ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
1649 if (WARN_ON_ONCE(ssid == NULL)) 1672 if (WARN_ON_ONCE(ssid == NULL))
1650 ssid_len = 0; 1673 ssid_len = 0;
@@ -1654,6 +1677,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1654 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL, 1677 ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid_len, NULL,
1655 0, (u32) -1, true, false, 1678 0, (u32) -1, true, false,
1656 ifmgd->associated->channel, false); 1679 ifmgd->associated->channel, false);
1680 rcu_read_unlock();
1657 } 1681 }
1658 1682
1659 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); 1683 ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
@@ -1749,6 +1773,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1749 else 1773 else
1750 return NULL; 1774 return NULL;
1751 1775
1776 rcu_read_lock();
1752 ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); 1777 ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID);
1753 if (WARN_ON_ONCE(ssid == NULL)) 1778 if (WARN_ON_ONCE(ssid == NULL))
1754 ssid_len = 0; 1779 ssid_len = 0;
@@ -1759,6 +1784,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
1759 (u32) -1, cbss->channel, 1784 (u32) -1, cbss->channel,
1760 ssid + 2, ssid_len, 1785 ssid + 2, ssid_len,
1761 NULL, 0, true); 1786 NULL, 0, true);
1787 rcu_read_unlock();
1762 1788
1763 return skb; 1789 return skb;
1764} 1790}
@@ -2844,9 +2870,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2844 auth_data->bss->bssid, auth_data->tries, 2870 auth_data->bss->bssid, auth_data->tries,
2845 IEEE80211_AUTH_MAX_TRIES); 2871 IEEE80211_AUTH_MAX_TRIES);
2846 2872
2873 rcu_read_lock();
2847 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); 2874 ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID);
2848 if (!ssidie) 2875 if (!ssidie) {
2876 rcu_read_unlock();
2849 return -EINVAL; 2877 return -EINVAL;
2878 }
2850 /* 2879 /*
2851 * Direct probe is sent to broadcast address as some APs 2880 * Direct probe is sent to broadcast address as some APs
2852 * will not answer to direct packet in unassociated state. 2881 * will not answer to direct packet in unassociated state.
@@ -2854,6 +2883,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
2854 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], 2883 ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1],
2855 NULL, 0, (u32) -1, true, false, 2884 NULL, 0, (u32) -1, true, false,
2856 auth_data->bss->channel, false); 2885 auth_data->bss->channel, false);
2886 rcu_read_unlock();
2857 } 2887 }
2858 2888
2859 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 2889 auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
@@ -3183,106 +3213,313 @@ int ieee80211_max_network_latency(struct notifier_block *nb,
3183 return 0; 3213 return 0;
3184} 3214}
3185 3215
3216static u32 chandef_downgrade(struct cfg80211_chan_def *c)
3217{
3218 u32 ret;
3219 int tmp;
3220
3221 switch (c->width) {
3222 case NL80211_CHAN_WIDTH_20:
3223 c->width = NL80211_CHAN_WIDTH_20_NOHT;
3224 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3225 break;
3226 case NL80211_CHAN_WIDTH_40:
3227 c->width = NL80211_CHAN_WIDTH_20;
3228 c->center_freq1 = c->chan->center_freq;
3229 ret = IEEE80211_STA_DISABLE_40MHZ |
3230 IEEE80211_STA_DISABLE_VHT;
3231 break;
3232 case NL80211_CHAN_WIDTH_80:
3233 tmp = (30 + c->chan->center_freq - c->center_freq1)/20;
3234 /* n_P40 */
3235 tmp /= 2;
3236 /* freq_P40 */
3237 c->center_freq1 = c->center_freq1 - 20 + 40 * tmp;
3238 c->width = NL80211_CHAN_WIDTH_40;
3239 ret = IEEE80211_STA_DISABLE_VHT;
3240 break;
3241 case NL80211_CHAN_WIDTH_80P80:
3242 c->center_freq2 = 0;
3243 c->width = NL80211_CHAN_WIDTH_80;
3244 ret = IEEE80211_STA_DISABLE_80P80MHZ |
3245 IEEE80211_STA_DISABLE_160MHZ;
3246 break;
3247 case NL80211_CHAN_WIDTH_160:
3248 /* n_P20 */
3249 tmp = (70 + c->chan->center_freq - c->center_freq1)/20;
3250 /* n_P80 */
3251 tmp /= 4;
3252 c->center_freq1 = c->center_freq1 - 40 + 80 * tmp;
3253 c->width = NL80211_CHAN_WIDTH_80;
3254 ret = IEEE80211_STA_DISABLE_80P80MHZ |
3255 IEEE80211_STA_DISABLE_160MHZ;
3256 break;
3257 default:
3258 case NL80211_CHAN_WIDTH_20_NOHT:
3259 WARN_ON_ONCE(1);
3260 c->width = NL80211_CHAN_WIDTH_20_NOHT;
3261 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3262 break;
3263 }
3264
3265 WARN_ON_ONCE(!cfg80211_chandef_valid(c));
3266
3267 return ret;
3268}
3269
3270static u32
3271ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
3272 struct ieee80211_supported_band *sband,
3273 struct ieee80211_channel *channel,
3274 const struct ieee80211_ht_operation *ht_oper,
3275 const struct ieee80211_vht_operation *vht_oper,
3276 struct cfg80211_chan_def *chandef)
3277{
3278 struct cfg80211_chan_def vht_chandef;
3279 u32 ht_cfreq, ret;
3280
3281 chandef->chan = channel;
3282 chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
3283 chandef->center_freq1 = channel->center_freq;
3284 chandef->center_freq2 = 0;
3285
3286 if (!ht_oper || !sband->ht_cap.ht_supported) {
3287 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3288 goto out;
3289 }
3290
3291 chandef->width = NL80211_CHAN_WIDTH_20;
3292
3293 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
3294 channel->band);
3295 /* check that channel matches the right operating channel */
3296 if (channel->center_freq != ht_cfreq) {
3297 /*
3298 * It's possible that some APs are confused here;
3299 * Netgear WNDR3700 sometimes reports 4 higher than
3300 * the actual channel in association responses, but
3301 * since we look at probe response/beacon data here
3302 * it should be OK.
3303 */
3304 sdata_info(sdata,
3305 "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
3306 channel->center_freq, ht_cfreq,
3307 ht_oper->primary_chan, channel->band);
3308 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
3309 goto out;
3310 }
3311
3312 /* check 40 MHz support, if we have it */
3313 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3314 switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3315 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3316 chandef->width = NL80211_CHAN_WIDTH_40;
3317 chandef->center_freq1 += 10;
3318 break;
3319 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3320 chandef->width = NL80211_CHAN_WIDTH_40;
3321 chandef->center_freq1 -= 10;
3322 break;
3323 }
3324 } else {
3325 /* 40 MHz (and 80 MHz) must be supported for VHT */
3326 ret = IEEE80211_STA_DISABLE_VHT;
3327 goto out;
3328 }
3329
3330 if (!vht_oper || !sband->vht_cap.vht_supported) {
3331 ret = IEEE80211_STA_DISABLE_VHT;
3332 goto out;
3333 }
3334
3335 vht_chandef.chan = channel;
3336 vht_chandef.center_freq1 =
3337 ieee80211_channel_to_frequency(vht_oper->center_freq_seg1_idx,
3338 channel->band);
3339 vht_chandef.center_freq2 = 0;
3340
3341 if (vht_oper->center_freq_seg2_idx)
3342 vht_chandef.center_freq2 =
3343 ieee80211_channel_to_frequency(
3344 vht_oper->center_freq_seg2_idx,
3345 channel->band);
3346
3347 switch (vht_oper->chan_width) {
3348 case IEEE80211_VHT_CHANWIDTH_USE_HT:
3349 vht_chandef.width = chandef->width;
3350 break;
3351 case IEEE80211_VHT_CHANWIDTH_80MHZ:
3352 vht_chandef.width = NL80211_CHAN_WIDTH_80;
3353 break;
3354 case IEEE80211_VHT_CHANWIDTH_160MHZ:
3355 vht_chandef.width = NL80211_CHAN_WIDTH_160;
3356 break;
3357 case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
3358 vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
3359 break;
3360 default:
3361 sdata_info(sdata,
3362 "AP VHT operation IE has invalid channel width (%d), disable VHT\n",
3363 vht_oper->chan_width);
3364 ret = IEEE80211_STA_DISABLE_VHT;
3365 goto out;
3366 }
3367
3368 if (!cfg80211_chandef_valid(&vht_chandef)) {
3369 sdata_info(sdata,
3370 "AP VHT information is invalid, disable VHT\n");
3371 ret = IEEE80211_STA_DISABLE_VHT;
3372 goto out;
3373 }
3374
3375 if (cfg80211_chandef_identical(chandef, &vht_chandef)) {
3376 ret = 0;
3377 goto out;
3378 }
3379
3380 if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
3381 sdata_info(sdata,
3382 "AP VHT information doesn't match HT, disable VHT\n");
3383 ret = IEEE80211_STA_DISABLE_VHT;
3384 goto out;
3385 }
3386
3387 *chandef = vht_chandef;
3388
3389 ret = 0;
3390
3391 while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
3392 IEEE80211_CHAN_DISABLED)) {
3393 if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
3394 ret = IEEE80211_STA_DISABLE_HT |
3395 IEEE80211_STA_DISABLE_VHT;
3396 goto out;
3397 }
3398
3399 ret = chandef_downgrade(chandef);
3400 }
3401
3402 if (chandef->width != vht_chandef.width)
3403 sdata_info(sdata,
3404 "local regulatory prevented using AP HT/VHT configuration, downgraded\n");
3405
3406out:
3407 WARN_ON_ONCE(!cfg80211_chandef_valid(chandef));
3408 return ret;
3409}
3410
3411static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,
3412 struct cfg80211_bss *cbss)
3413{
3414 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3415 const u8 *ht_cap_ie, *vht_cap_ie;
3416 const struct ieee80211_ht_cap *ht_cap;
3417 const struct ieee80211_vht_cap *vht_cap;
3418 u8 chains = 1;
3419
3420 if (ifmgd->flags & IEEE80211_STA_DISABLE_HT)
3421 return chains;
3422
3423 ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
3424 if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) {
3425 ht_cap = (void *)(ht_cap_ie + 2);
3426 chains = ieee80211_mcs_to_chains(&ht_cap->mcs);
3427 /*
3428 * TODO: use "Tx Maximum Number Spatial Streams Supported" and
3429 * "Tx Unequal Modulation Supported" fields.
3430 */
3431 }
3432
3433 if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
3434 return chains;
3435
3436 vht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_VHT_CAPABILITY);
3437 if (vht_cap_ie && vht_cap_ie[1] >= sizeof(*vht_cap)) {
3438 u8 nss;
3439 u16 tx_mcs_map;
3440
3441 vht_cap = (void *)(vht_cap_ie + 2);
3442 tx_mcs_map = le16_to_cpu(vht_cap->supp_mcs.tx_mcs_map);
3443 for (nss = 8; nss > 0; nss--) {
3444 if (((tx_mcs_map >> (2 * (nss - 1))) & 3) !=
3445 IEEE80211_VHT_MCS_NOT_SUPPORTED)
3446 break;
3447 }
3448 /* TODO: use "Tx Highest Supported Long GI Data Rate" field? */
3449 chains = max(chains, nss);
3450 }
3451
3452 return chains;
3453}
3454
3186static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata, 3455static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3187 struct cfg80211_bss *cbss) 3456 struct cfg80211_bss *cbss)
3188{ 3457{
3189 struct ieee80211_local *local = sdata->local; 3458 struct ieee80211_local *local = sdata->local;
3190 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3459 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3191 int ht_cfreq;
3192 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
3193 const u8 *ht_oper_ie;
3194 const struct ieee80211_ht_operation *ht_oper = NULL; 3460 const struct ieee80211_ht_operation *ht_oper = NULL;
3461 const struct ieee80211_vht_operation *vht_oper = NULL;
3195 struct ieee80211_supported_band *sband; 3462 struct ieee80211_supported_band *sband;
3196 struct cfg80211_chan_def chandef; 3463 struct cfg80211_chan_def chandef;
3464 int ret;
3197 3465
3198 sband = local->hw.wiphy->bands[cbss->channel->band]; 3466 sband = local->hw.wiphy->bands[cbss->channel->band];
3199 3467
3200 ifmgd->flags &= ~IEEE80211_STA_DISABLE_40MHZ; 3468 ifmgd->flags &= ~(IEEE80211_STA_DISABLE_40MHZ |
3469 IEEE80211_STA_DISABLE_80P80MHZ |
3470 IEEE80211_STA_DISABLE_160MHZ);
3201 3471
3202 if (sband->ht_cap.ht_supported) { 3472 rcu_read_lock();
3203 ht_oper_ie = cfg80211_find_ie(WLAN_EID_HT_OPERATION, 3473
3204 cbss->information_elements, 3474 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3205 cbss->len_information_elements); 3475 sband->ht_cap.ht_supported) {
3476 const u8 *ht_oper_ie;
3477
3478 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
3206 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) 3479 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
3207 ht_oper = (void *)(ht_oper_ie + 2); 3480 ht_oper = (void *)(ht_oper_ie + 2);
3208 } 3481 }
3209 3482
3210 if (ht_oper) { 3483 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3211 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, 3484 sband->vht_cap.vht_supported) {
3212 cbss->channel->band); 3485 const u8 *vht_oper_ie;
3213 /* check that channel matches the right operating channel */ 3486
3214 if (cbss->channel->center_freq != ht_cfreq) { 3487 vht_oper_ie = ieee80211_bss_get_ie(cbss,
3215 /* 3488 WLAN_EID_VHT_OPERATION);
3216 * It's possible that some APs are confused here; 3489 if (vht_oper_ie && vht_oper_ie[1] >= sizeof(*vht_oper))
3217 * Netgear WNDR3700 sometimes reports 4 higher than 3490 vht_oper = (void *)(vht_oper_ie + 2);
3218 * the actual channel in association responses, but 3491 if (vht_oper && !ht_oper) {
3219 * since we look at probe response/beacon data here 3492 vht_oper = NULL;
3220 * it should be OK.
3221 */
3222 sdata_info(sdata, 3493 sdata_info(sdata,
3223 "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", 3494 "AP advertised VHT without HT, disabling both\n");
3224 cbss->channel->center_freq, 3495 sdata->flags |= IEEE80211_STA_DISABLE_HT;
3225 ht_cfreq, ht_oper->primary_chan, 3496 sdata->flags |= IEEE80211_STA_DISABLE_VHT;
3226 cbss->channel->band);
3227 ht_oper = NULL;
3228 } 3497 }
3229 } 3498 }
3230 3499
3231 if (ht_oper) { 3500 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
3232 /* 3501 cbss->channel,
3233 * cfg80211 already verified that the channel itself can 3502 ht_oper, vht_oper,
3234 * be used, but it didn't check that we can do the right 3503 &chandef);
3235 * HT type, so do that here as well. If HT40 isn't allowed
3236 * on this channel, disable 40 MHz operation.
3237 */
3238 const u8 *ht_cap_ie;
3239 const struct ieee80211_ht_cap *ht_cap;
3240 u8 chains = 1;
3241
3242 channel_type = NL80211_CHAN_HT20;
3243
3244 if (sband->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
3245 switch (ht_oper->ht_param &
3246 IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
3247 case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
3248 if (cbss->channel->flags &
3249 IEEE80211_CHAN_NO_HT40PLUS)
3250 ifmgd->flags |=
3251 IEEE80211_STA_DISABLE_40MHZ;
3252 else
3253 channel_type = NL80211_CHAN_HT40PLUS;
3254 break;
3255 case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
3256 if (cbss->channel->flags &
3257 IEEE80211_CHAN_NO_HT40MINUS)
3258 ifmgd->flags |=
3259 IEEE80211_STA_DISABLE_40MHZ;
3260 else
3261 channel_type = NL80211_CHAN_HT40MINUS;
3262 break;
3263 }
3264 }
3265 3504
3266 ht_cap_ie = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, 3505 sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
3267 cbss->information_elements, 3506 local->rx_chains);
3268 cbss->len_information_elements); 3507
3269 if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap)) { 3508 rcu_read_unlock();
3270 ht_cap = (void *)(ht_cap_ie + 2);
3271 chains = ieee80211_mcs_to_chains(&ht_cap->mcs);
3272 }
3273 sdata->needed_rx_chains = min(chains, local->rx_chains);
3274 } else {
3275 sdata->needed_rx_chains = 1;
3276 sdata->u.mgd.flags |= IEEE80211_STA_DISABLE_HT;
3277 }
3278 3509
3279 /* will change later if needed */ 3510 /* will change later if needed */
3280 sdata->smps_mode = IEEE80211_SMPS_OFF; 3511 sdata->smps_mode = IEEE80211_SMPS_OFF;
3281 3512
3282 ieee80211_vif_release_channel(sdata); 3513 /*
3283 cfg80211_chandef_create(&chandef, cbss->channel, channel_type); 3514 * If this fails (possibly due to channel context sharing
3284 return ieee80211_vif_use_channel(sdata, &chandef, 3515 * on incompatible channels, e.g. 80+80 and 160 sharing the
3285 IEEE80211_CHANCTX_SHARED); 3516 * same control channel) try to use a smaller bandwidth.
3517 */
3518 ret = ieee80211_vif_use_channel(sdata, &chandef,
3519 IEEE80211_CHANCTX_SHARED);
3520 while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
3521 ifmgd->flags |= chandef_downgrade(&chandef);
3522 return ret;
3286} 3523}
3287 3524
3288static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, 3525static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
@@ -3510,14 +3747,21 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3510 const u8 *ssidie, *ht_ie; 3747 const u8 *ssidie, *ht_ie;
3511 int i, err; 3748 int i, err;
3512 3749
3513 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
3514 if (!ssidie)
3515 return -EINVAL;
3516
3517 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL); 3750 assoc_data = kzalloc(sizeof(*assoc_data) + req->ie_len, GFP_KERNEL);
3518 if (!assoc_data) 3751 if (!assoc_data)
3519 return -ENOMEM; 3752 return -ENOMEM;
3520 3753
3754 rcu_read_lock();
3755 ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
3756 if (!ssidie) {
3757 rcu_read_unlock();
3758 kfree(assoc_data);
3759 return -EINVAL;
3760 }
3761 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
3762 assoc_data->ssid_len = ssidie[1];
3763 rcu_read_unlock();
3764
3521 mutex_lock(&ifmgd->mtx); 3765 mutex_lock(&ifmgd->mtx);
3522 3766
3523 if (ifmgd->associated) 3767 if (ifmgd->associated)
@@ -3612,12 +3856,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3612 assoc_data->supp_rates = bss->supp_rates; 3856 assoc_data->supp_rates = bss->supp_rates;
3613 assoc_data->supp_rates_len = bss->supp_rates_len; 3857 assoc_data->supp_rates_len = bss->supp_rates_len;
3614 3858
3859 rcu_read_lock();
3615 ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); 3860 ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION);
3616 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) 3861 if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation))
3617 assoc_data->ap_ht_param = 3862 assoc_data->ap_ht_param =
3618 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; 3863 ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param;
3619 else 3864 else
3620 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 3865 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3866 rcu_read_unlock();
3621 3867
3622 if (bss->wmm_used && bss->uapsd_supported && 3868 if (bss->wmm_used && bss->uapsd_supported &&
3623 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { 3869 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
@@ -3628,9 +3874,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3628 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED; 3874 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
3629 } 3875 }
3630 3876
3631 memcpy(assoc_data->ssid, ssidie + 2, ssidie[1]);
3632 assoc_data->ssid_len = ssidie[1];
3633
3634 if (req->prev_bssid) 3877 if (req->prev_bssid)
3635 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN); 3878 memcpy(assoc_data->prev_bssid, req->prev_bssid, ETH_ALEN);
3636 3879
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 5abddfe3e101..a5379aea7d09 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -462,8 +462,6 @@ void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata)
462 list_move_tail(&roc->list, &tmp_list); 462 list_move_tail(&roc->list, &tmp_list);
463 roc->abort = true; 463 roc->abort = true;
464 } 464 }
465
466 ieee80211_start_next_roc(local);
467 mutex_unlock(&local->mtx); 465 mutex_unlock(&local->mtx);
468 466
469 list_for_each_entry_safe(roc, tmp, &tmp_list, list) { 467 list_for_each_entry_safe(roc, tmp, &tmp_list, list) {
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index fb1d4aa65e8c..9f9c453bc45d 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -389,9 +389,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
389 struct ieee80211_tx_rate *ar = info->status.rates; 389 struct ieee80211_tx_rate *ar = info->status.rates;
390 struct minstrel_rate_stats *rate, *rate2; 390 struct minstrel_rate_stats *rate, *rate2;
391 struct minstrel_priv *mp = priv; 391 struct minstrel_priv *mp = priv;
392 bool last = false; 392 bool last;
393 int group; 393 int group;
394 int i = 0; 394 int i;
395 395
396 if (!msp->is_ht) 396 if (!msp->is_ht)
397 return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb); 397 return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb);
@@ -419,13 +419,11 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
419 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) 419 if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE)
420 mi->sample_packets += info->status.ampdu_len; 420 mi->sample_packets += info->status.ampdu_len;
421 421
422 last = !minstrel_ht_txstat_valid(&ar[0]);
422 for (i = 0; !last; i++) { 423 for (i = 0; !last; i++) {
423 last = (i == IEEE80211_TX_MAX_RATES - 1) || 424 last = (i == IEEE80211_TX_MAX_RATES - 1) ||
424 !minstrel_ht_txstat_valid(&ar[i + 1]); 425 !minstrel_ht_txstat_valid(&ar[i + 1]);
425 426
426 if (!minstrel_ht_txstat_valid(&ar[i]))
427 break;
428
429 group = minstrel_ht_get_group_idx(&ar[i]); 427 group = minstrel_ht_get_group_idx(&ar[i]);
430 rate = &mi->groups[group].rates[ar[i].idx % 8]; 428 rate = &mi->groups[group].rates[ar[i].idx % 8];
431 429
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 825f33cf7bbc..db343fa8033c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -49,7 +49,7 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local,
49 /* driver bug */ 49 /* driver bug */
50 WARN_ON(1); 50 WARN_ON(1);
51 dev_kfree_skb(skb); 51 dev_kfree_skb(skb);
52 skb = NULL; 52 return NULL;
53 } 53 }
54 } 54 }
55 55
@@ -111,6 +111,11 @@ ieee80211_rx_radiotap_space(struct ieee80211_local *local,
111 len += 8; 111 len += 8;
112 } 112 }
113 113
114 if (status->flag & RX_FLAG_VHT) {
115 len = ALIGN(len, 2);
116 len += 12;
117 }
118
114 if (status->vendor_radiotap_len) { 119 if (status->vendor_radiotap_len) {
115 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0)) 120 if (WARN_ON_ONCE(status->vendor_radiotap_align == 0))
116 status->vendor_radiotap_align = 1; 121 status->vendor_radiotap_align = 1;
@@ -297,6 +302,41 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
297 *pos++ = 0; 302 *pos++ = 0;
298 } 303 }
299 304
305 if (status->flag & RX_FLAG_VHT) {
306 u16 known = local->hw.radiotap_vht_details;
307
308 rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT);
309 /* known field - how to handle 80+80? */
310 if (status->flag & RX_FLAG_80P80MHZ)
311 known &= ~IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
312 put_unaligned_le16(known, pos);
313 pos += 2;
314 /* flags */
315 if (status->flag & RX_FLAG_SHORT_GI)
316 *pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI;
317 pos++;
318 /* bandwidth */
319 if (status->flag & RX_FLAG_80MHZ)
320 *pos++ = 4;
321 else if (status->flag & RX_FLAG_80P80MHZ)
322 *pos++ = 0; /* marked not known above */
323 else if (status->flag & RX_FLAG_160MHZ)
324 *pos++ = 11;
325 else if (status->flag & RX_FLAG_40MHZ)
326 *pos++ = 1;
327 else /* 20 MHz */
328 *pos++ = 0;
329 /* MCS/NSS */
330 *pos = (status->rate_idx << 4) | status->vht_nss;
331 pos += 4;
332 /* coding field */
333 pos++;
334 /* group ID */
335 pos++;
336 /* partial_aid */
337 pos += 2;
338 }
339
300 if (status->vendor_radiotap_len) { 340 if (status->vendor_radiotap_len) {
301 /* ensure 2 byte alignment for the vendor field as required */ 341 /* ensure 2 byte alignment for the vendor field as required */
302 if ((pos - (u8 *)rthdr) & 1) 342 if ((pos - (u8 *)rthdr) & 1)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index f3340279aba3..f7176ac5a535 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -247,6 +247,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
247 local->hw_scan_req->n_channels = n_chans; 247 local->hw_scan_req->n_channels = n_chans;
248 248
249 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, 249 ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie,
250 local->hw_scan_ies_bufsize,
250 req->ie, req->ie_len, band, 251 req->ie, req->ie_len, band,
251 req->rates[band], 0); 252 req->rates[band], 0);
252 local->hw_scan_req->ie_len = ielen; 253 local->hw_scan_req->ie_len = ielen;
@@ -445,11 +446,13 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
445 if (local->ops->hw_scan) { 446 if (local->ops->hw_scan) {
446 u8 *ies; 447 u8 *ies;
447 448
449 local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN +
450 local->scan_ies_len +
451 req->ie_len;
448 local->hw_scan_req = kmalloc( 452 local->hw_scan_req = kmalloc(
449 sizeof(*local->hw_scan_req) + 453 sizeof(*local->hw_scan_req) +
450 req->n_channels * sizeof(req->channels[0]) + 454 req->n_channels * sizeof(req->channels[0]) +
451 2 + IEEE80211_MAX_SSID_LEN + local->scan_ies_len + 455 local->hw_scan_ies_bufsize, GFP_KERNEL);
452 req->ie_len, GFP_KERNEL);
453 if (!local->hw_scan_req) 456 if (!local->hw_scan_req)
454 return -ENOMEM; 457 return -ENOMEM;
455 458
@@ -928,7 +931,10 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
928{ 931{
929 struct ieee80211_local *local = sdata->local; 932 struct ieee80211_local *local = sdata->local;
930 struct ieee80211_sched_scan_ies sched_scan_ies = {}; 933 struct ieee80211_sched_scan_ies sched_scan_ies = {};
931 int ret, i; 934 int ret, i, iebufsz;
935
936 iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
937 local->scan_ies_len + req->ie_len;
932 938
933 mutex_lock(&local->mtx); 939 mutex_lock(&local->mtx);
934 940
@@ -946,10 +952,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
946 if (!local->hw.wiphy->bands[i]) 952 if (!local->hw.wiphy->bands[i])
947 continue; 953 continue;
948 954
949 sched_scan_ies.ie[i] = kzalloc(2 + IEEE80211_MAX_SSID_LEN + 955 sched_scan_ies.ie[i] = kzalloc(iebufsz, GFP_KERNEL);
950 local->scan_ies_len +
951 req->ie_len,
952 GFP_KERNEL);
953 if (!sched_scan_ies.ie[i]) { 956 if (!sched_scan_ies.ie[i]) {
954 ret = -ENOMEM; 957 ret = -ENOMEM;
955 goto out_free; 958 goto out_free;
@@ -957,8 +960,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
957 960
958 sched_scan_ies.len[i] = 961 sched_scan_ies.len[i] =
959 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i], 962 ieee80211_build_preq_ies(local, sched_scan_ies.ie[i],
960 req->ie, req->ie_len, i, 963 iebufsz, req->ie, req->ie_len,
961 (u32) -1, 0); 964 i, (u32) -1, 0);
962 } 965 }
963 966
964 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies); 967 ret = drv_sched_scan_start(local, sdata, req, &sched_scan_ies);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6835cea4e402..1489bca9ea97 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -250,6 +250,7 @@ struct sta_ampdu_mlme {
250 * @rx_dropped: number of dropped MPDUs from this STA 250 * @rx_dropped: number of dropped MPDUs from this STA
251 * @last_signal: signal of last received frame from this STA 251 * @last_signal: signal of last received frame from this STA
252 * @avg_signal: moving average of signal of received frames from this STA 252 * @avg_signal: moving average of signal of received frames from this STA
253 * @last_ack_signal: signal of last received Ack frame from this STA
253 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) 254 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
254 * @tx_filtered_count: number of frames the hardware filtered for this STA 255 * @tx_filtered_count: number of frames the hardware filtered for this STA
255 * @tx_retry_failed: number of frames that failed retry 256 * @tx_retry_failed: number of frames that failed retry
@@ -329,6 +330,7 @@ struct sta_info {
329 unsigned long rx_dropped; 330 unsigned long rx_dropped;
330 int last_signal; 331 int last_signal;
331 struct ewma avg_signal; 332 struct ewma avg_signal;
333 int last_ack_signal;
332 /* Plus 1 for non-QoS frames */ 334 /* Plus 1 for non-QoS frames */
333 __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; 335 __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
334 336
@@ -552,6 +554,8 @@ int sta_info_flush(struct ieee80211_local *local,
552void sta_set_rate_info_tx(struct sta_info *sta, 554void sta_set_rate_info_tx(struct sta_info *sta,
553 const struct ieee80211_tx_rate *rate, 555 const struct ieee80211_tx_rate *rate,
554 struct rate_info *rinfo); 556 struct rate_info *rinfo);
557void sta_set_rate_info_rx(struct sta_info *sta,
558 struct rate_info *rinfo);
555void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, 559void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
556 unsigned long exp_time); 560 unsigned long exp_time);
557 561
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index ab63237107c8..ab50285fcbab 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -539,6 +539,9 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
539 sta->lost_packets = 0; 539 sta->lost_packets = 0;
540 } 540 }
541 } 541 }
542
543 if (acked)
544 sta->last_ack_signal = info->status.ack_signal;
542 } 545 }
543 546
544 rcu_read_unlock(); 547 rcu_read_unlock();
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index d287a4f2c01b..e9eadc40c09c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2623,7 +2623,7 @@ EXPORT_SYMBOL(ieee80211_nullfunc_get);
2623struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw, 2623struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
2624 struct ieee80211_vif *vif, 2624 struct ieee80211_vif *vif,
2625 const u8 *ssid, size_t ssid_len, 2625 const u8 *ssid, size_t ssid_len,
2626 const u8 *ie, size_t ie_len) 2626 size_t tailroom)
2627{ 2627{
2628 struct ieee80211_sub_if_data *sdata; 2628 struct ieee80211_sub_if_data *sdata;
2629 struct ieee80211_local *local; 2629 struct ieee80211_local *local;
@@ -2637,7 +2637,7 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
2637 ie_ssid_len = 2 + ssid_len; 2637 ie_ssid_len = 2 + ssid_len;
2638 2638
2639 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) + 2639 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) +
2640 ie_ssid_len + ie_len); 2640 ie_ssid_len + tailroom);
2641 if (!skb) 2641 if (!skb)
2642 return NULL; 2642 return NULL;
2643 2643
@@ -2658,11 +2658,6 @@ struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
2658 memcpy(pos, ssid, ssid_len); 2658 memcpy(pos, ssid, ssid_len);
2659 pos += ssid_len; 2659 pos += ssid_len;
2660 2660
2661 if (ie) {
2662 pos = skb_put(skb, ie_len);
2663 memcpy(pos, ie, ie_len);
2664 }
2665
2666 return skb; 2661 return skb;
2667} 2662}
2668EXPORT_SYMBOL(ieee80211_probereq_get); 2663EXPORT_SYMBOL(ieee80211_probereq_get);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 08132ff98155..f11e8c540db4 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1107,12 +1107,12 @@ void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
1107} 1107}
1108 1108
1109int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1109int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1110 const u8 *ie, size_t ie_len, 1110 size_t buffer_len, const u8 *ie, size_t ie_len,
1111 enum ieee80211_band band, u32 rate_mask, 1111 enum ieee80211_band band, u32 rate_mask,
1112 u8 channel) 1112 u8 channel)
1113{ 1113{
1114 struct ieee80211_supported_band *sband; 1114 struct ieee80211_supported_band *sband;
1115 u8 *pos; 1115 u8 *pos = buffer, *end = buffer + buffer_len;
1116 size_t offset = 0, noffset; 1116 size_t offset = 0, noffset;
1117 int supp_rates_len, i; 1117 int supp_rates_len, i;
1118 u8 rates[32]; 1118 u8 rates[32];
@@ -1123,8 +1123,6 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1123 if (WARN_ON_ONCE(!sband)) 1123 if (WARN_ON_ONCE(!sband))
1124 return 0; 1124 return 0;
1125 1125
1126 pos = buffer;
1127
1128 num_rates = 0; 1126 num_rates = 0;
1129 for (i = 0; i < sband->n_bitrates; i++) { 1127 for (i = 0; i < sband->n_bitrates; i++) {
1130 if ((BIT(i) & rate_mask) == 0) 1128 if ((BIT(i) & rate_mask) == 0)
@@ -1134,6 +1132,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1134 1132
1135 supp_rates_len = min_t(int, num_rates, 8); 1133 supp_rates_len = min_t(int, num_rates, 8);
1136 1134
1135 if (end - pos < 2 + supp_rates_len)
1136 goto out_err;
1137 *pos++ = WLAN_EID_SUPP_RATES; 1137 *pos++ = WLAN_EID_SUPP_RATES;
1138 *pos++ = supp_rates_len; 1138 *pos++ = supp_rates_len;
1139 memcpy(pos, rates, supp_rates_len); 1139 memcpy(pos, rates, supp_rates_len);
@@ -1150,6 +1150,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1150 before_extrates, 1150 before_extrates,
1151 ARRAY_SIZE(before_extrates), 1151 ARRAY_SIZE(before_extrates),
1152 offset); 1152 offset);
1153 if (end - pos < noffset - offset)
1154 goto out_err;
1153 memcpy(pos, ie + offset, noffset - offset); 1155 memcpy(pos, ie + offset, noffset - offset);
1154 pos += noffset - offset; 1156 pos += noffset - offset;
1155 offset = noffset; 1157 offset = noffset;
@@ -1157,6 +1159,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1157 1159
1158 ext_rates_len = num_rates - supp_rates_len; 1160 ext_rates_len = num_rates - supp_rates_len;
1159 if (ext_rates_len > 0) { 1161 if (ext_rates_len > 0) {
1162 if (end - pos < 2 + ext_rates_len)
1163 goto out_err;
1160 *pos++ = WLAN_EID_EXT_SUPP_RATES; 1164 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1161 *pos++ = ext_rates_len; 1165 *pos++ = ext_rates_len;
1162 memcpy(pos, rates + supp_rates_len, ext_rates_len); 1166 memcpy(pos, rates + supp_rates_len, ext_rates_len);
@@ -1164,6 +1168,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1164 } 1168 }
1165 1169
1166 if (channel && sband->band == IEEE80211_BAND_2GHZ) { 1170 if (channel && sband->band == IEEE80211_BAND_2GHZ) {
1171 if (end - pos < 3)
1172 goto out_err;
1167 *pos++ = WLAN_EID_DS_PARAMS; 1173 *pos++ = WLAN_EID_DS_PARAMS;
1168 *pos++ = 1; 1174 *pos++ = 1;
1169 *pos++ = channel; 1175 *pos++ = channel;
@@ -1182,14 +1188,19 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1182 noffset = ieee80211_ie_split(ie, ie_len, 1188 noffset = ieee80211_ie_split(ie, ie_len,
1183 before_ht, ARRAY_SIZE(before_ht), 1189 before_ht, ARRAY_SIZE(before_ht),
1184 offset); 1190 offset);
1191 if (end - pos < noffset - offset)
1192 goto out_err;
1185 memcpy(pos, ie + offset, noffset - offset); 1193 memcpy(pos, ie + offset, noffset - offset);
1186 pos += noffset - offset; 1194 pos += noffset - offset;
1187 offset = noffset; 1195 offset = noffset;
1188 } 1196 }
1189 1197
1190 if (sband->ht_cap.ht_supported) 1198 if (sband->ht_cap.ht_supported) {
1199 if (end - pos < 2 + sizeof(struct ieee80211_ht_cap))
1200 goto out_err;
1191 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap, 1201 pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
1192 sband->ht_cap.cap); 1202 sband->ht_cap.cap);
1203 }
1193 1204
1194 /* 1205 /*
1195 * If adding more here, adjust code in main.c 1206 * If adding more here, adjust code in main.c
@@ -1199,15 +1210,23 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1199 /* add any remaining custom IEs */ 1210 /* add any remaining custom IEs */
1200 if (ie && ie_len) { 1211 if (ie && ie_len) {
1201 noffset = ie_len; 1212 noffset = ie_len;
1213 if (end - pos < noffset - offset)
1214 goto out_err;
1202 memcpy(pos, ie + offset, noffset - offset); 1215 memcpy(pos, ie + offset, noffset - offset);
1203 pos += noffset - offset; 1216 pos += noffset - offset;
1204 } 1217 }
1205 1218
1206 if (sband->vht_cap.vht_supported) 1219 if (sband->vht_cap.vht_supported) {
1220 if (end - pos < 2 + sizeof(struct ieee80211_vht_cap))
1221 goto out_err;
1207 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, 1222 pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap,
1208 sband->vht_cap.cap); 1223 sband->vht_cap.cap);
1224 }
1209 1225
1210 return pos - buffer; 1226 return pos - buffer;
1227 out_err:
1228 WARN_ONCE(1, "not enough space for preq IEs\n");
1229 return pos - buffer;
1211} 1230}
1212 1231
1213struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, 1232struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
@@ -1220,14 +1239,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1220 struct ieee80211_local *local = sdata->local; 1239 struct ieee80211_local *local = sdata->local;
1221 struct sk_buff *skb; 1240 struct sk_buff *skb;
1222 struct ieee80211_mgmt *mgmt; 1241 struct ieee80211_mgmt *mgmt;
1223 size_t buf_len;
1224 u8 *buf;
1225 u8 chan_no; 1242 u8 chan_no;
1226 1243 int ies_len;
1227 /* FIXME: come up with a proper value */
1228 buf = kmalloc(200 + ie_len, GFP_KERNEL);
1229 if (!buf)
1230 return NULL;
1231 1244
1232 /* 1245 /*
1233 * Do not send DS Channel parameter for directed probe requests 1246 * Do not send DS Channel parameter for directed probe requests
@@ -1239,14 +1252,16 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1239 else 1252 else
1240 chan_no = ieee80211_frequency_to_channel(chan->center_freq); 1253 chan_no = ieee80211_frequency_to_channel(chan->center_freq);
1241 1254
1242 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, chan->band,
1243 ratemask, chan_no);
1244
1245 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 1255 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1246 ssid, ssid_len, 1256 ssid, ssid_len, 100 + ie_len);
1247 buf, buf_len);
1248 if (!skb) 1257 if (!skb)
1249 goto out; 1258 return NULL;
1259
1260 ies_len = ieee80211_build_preq_ies(local, skb_tail_pointer(skb),
1261 skb_tailroom(skb),
1262 ie, ie_len, chan->band,
1263 ratemask, chan_no);
1264 skb_put(skb, ies_len);
1250 1265
1251 if (dst) { 1266 if (dst) {
1252 mgmt = (struct ieee80211_mgmt *) skb->data; 1267 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -1256,9 +1271,6 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1256 1271
1257 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1272 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1258 1273
1259 out:
1260 kfree(buf);
1261
1262 return skb; 1274 return skb;
1263} 1275}
1264 1276
@@ -1527,7 +1539,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1527 changed |= BSS_CHANGED_IBSS; 1539 changed |= BSS_CHANGED_IBSS;
1528 /* fall through */ 1540 /* fall through */
1529 case NL80211_IFTYPE_AP: 1541 case NL80211_IFTYPE_AP:
1530 changed |= BSS_CHANGED_SSID; 1542 changed |= BSS_CHANGED_SSID | BSS_CHANGED_P2P_PS;
1531 1543
1532 if (sdata->vif.type == NL80211_IFTYPE_AP) { 1544 if (sdata->vif.type == NL80211_IFTYPE_AP) {
1533 changed |= BSS_CHANGED_AP_PROBE_RESP; 1545 changed |= BSS_CHANGED_AP_PROBE_RESP;
diff --git a/net/nfc/llcp/llcp.c b/net/nfc/llcp/llcp.c
index 2df87056c6df..ec43914c92a9 100644
--- a/net/nfc/llcp/llcp.c
+++ b/net/nfc/llcp/llcp.c
@@ -985,15 +985,18 @@ static void nfc_llcp_recv_hdlc(struct nfc_llcp_local *local,
985 /* Remove skbs from the pending queue */ 985 /* Remove skbs from the pending queue */
986 if (llcp_sock->send_ack_n != nr) { 986 if (llcp_sock->send_ack_n != nr) {
987 struct sk_buff *s, *tmp; 987 struct sk_buff *s, *tmp;
988 u8 n;
988 989
989 llcp_sock->send_ack_n = nr; 990 llcp_sock->send_ack_n = nr;
990 991
991 /* Remove and free all skbs until ns == nr */ 992 /* Remove and free all skbs until ns == nr */
992 skb_queue_walk_safe(&llcp_sock->tx_pending_queue, s, tmp) { 993 skb_queue_walk_safe(&llcp_sock->tx_pending_queue, s, tmp) {
994 n = nfc_llcp_ns(s);
995
993 skb_unlink(s, &llcp_sock->tx_pending_queue); 996 skb_unlink(s, &llcp_sock->tx_pending_queue);
994 kfree_skb(s); 997 kfree_skb(s);
995 998
996 if (nfc_llcp_ns(s) == nr) 999 if (n == nr)
997 break; 1000 break;
998 } 1001 }
999 1002
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 865adb61685a..78fc0937948d 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -213,7 +213,7 @@ static int rfkill_gpio_remove(struct platform_device *pdev)
213 213
214static struct platform_driver rfkill_gpio_driver = { 214static struct platform_driver rfkill_gpio_driver = {
215 .probe = rfkill_gpio_probe, 215 .probe = rfkill_gpio_probe,
216 .remove = __devexit_p(rfkill_gpio_remove), 216 .remove = rfkill_gpio_remove,
217 .driver = { 217 .driver = {
218 .name = "rfkill_gpio", 218 .name = "rfkill_gpio",
219 .owner = THIS_MODULE, 219 .owner = THIS_MODULE,
diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
index 11da3018a853..4b5ab21ecb24 100644
--- a/net/rfkill/rfkill-regulator.c
+++ b/net/rfkill/rfkill-regulator.c
@@ -55,7 +55,7 @@ struct rfkill_ops rfkill_regulator_ops = {
55 .set_block = rfkill_regulator_set_block, 55 .set_block = rfkill_regulator_set_block,
56}; 56};
57 57
58static int __devinit rfkill_regulator_probe(struct platform_device *pdev) 58static int rfkill_regulator_probe(struct platform_device *pdev)
59{ 59{
60 struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data; 60 struct rfkill_regulator_platform_data *pdata = pdev->dev.platform_data;
61 struct rfkill_regulator_data *rfkill_data; 61 struct rfkill_regulator_data *rfkill_data;
@@ -122,7 +122,7 @@ out:
122 return ret; 122 return ret;
123} 123}
124 124
125static int __devexit rfkill_regulator_remove(struct platform_device *pdev) 125static int rfkill_regulator_remove(struct platform_device *pdev)
126{ 126{
127 struct rfkill_regulator_data *rfkill_data = platform_get_drvdata(pdev); 127 struct rfkill_regulator_data *rfkill_data = platform_get_drvdata(pdev);
128 struct rfkill *rf_kill = rfkill_data->rf_kill; 128 struct rfkill *rf_kill = rfkill_data->rf_kill;
@@ -137,7 +137,7 @@ static int __devexit rfkill_regulator_remove(struct platform_device *pdev)
137 137
138static struct platform_driver rfkill_regulator_driver = { 138static struct platform_driver rfkill_regulator_driver = {
139 .probe = rfkill_regulator_probe, 139 .probe = rfkill_regulator_probe,
140 .remove = __devexit_p(rfkill_regulator_remove), 140 .remove = rfkill_regulator_remove,
141 .driver = { 141 .driver = {
142 .name = "rfkill-regulator", 142 .name = "rfkill-regulator",
143 .owner = THIS_MODULE, 143 .owner = THIS_MODULE,
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index bf2dfd54ff3b..b5f69831e318 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -44,7 +44,7 @@ void cfg80211_chandef_create(struct cfg80211_chan_def *chandef,
44} 44}
45EXPORT_SYMBOL(cfg80211_chandef_create); 45EXPORT_SYMBOL(cfg80211_chandef_create);
46 46
47bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef) 47bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef)
48{ 48{
49 u32 control_freq; 49 u32 control_freq;
50 50
@@ -105,6 +105,7 @@ bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef)
105 105
106 return true; 106 return true;
107} 107}
108EXPORT_SYMBOL(cfg80211_chandef_valid);
108 109
109static void chandef_primary_freqs(const struct cfg80211_chan_def *c, 110static void chandef_primary_freqs(const struct cfg80211_chan_def *c,
110 int *pri40, int *pri80) 111 int *pri40, int *pri80)
@@ -187,9 +188,9 @@ cfg80211_chandef_compatible(const struct cfg80211_chan_def *c1,
187} 188}
188EXPORT_SYMBOL(cfg80211_chandef_compatible); 189EXPORT_SYMBOL(cfg80211_chandef_compatible);
189 190
190bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, 191static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
191 u32 center_freq, u32 bandwidth, 192 u32 center_freq, u32 bandwidth,
192 u32 prohibited_flags) 193 u32 prohibited_flags)
193{ 194{
194 struct ieee80211_channel *c; 195 struct ieee80211_channel *c;
195 u32 freq; 196 u32 freq;
@@ -205,55 +206,88 @@ bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
205 return true; 206 return true;
206} 207}
207 208
208static bool cfg80211_check_beacon_chans(struct wiphy *wiphy, 209bool cfg80211_chandef_usable(struct wiphy *wiphy,
209 u32 center_freq, u32 bw) 210 const struct cfg80211_chan_def *chandef,
211 u32 prohibited_flags)
210{ 212{
211 return cfg80211_secondary_chans_ok(wiphy, center_freq, bw, 213 struct ieee80211_sta_ht_cap *ht_cap;
212 IEEE80211_CHAN_DISABLED | 214 struct ieee80211_sta_vht_cap *vht_cap;
213 IEEE80211_CHAN_PASSIVE_SCAN | 215 u32 width, control_freq;
214 IEEE80211_CHAN_NO_IBSS |
215 IEEE80211_CHAN_RADAR);
216}
217 216
218bool cfg80211_reg_can_beacon(struct wiphy *wiphy, 217 if (WARN_ON(!cfg80211_chandef_valid(chandef)))
219 struct cfg80211_chan_def *chandef) 218 return false;
220{
221 u32 width;
222 bool res;
223 219
224 trace_cfg80211_reg_can_beacon(wiphy, chandef); 220 ht_cap = &wiphy->bands[chandef->chan->band]->ht_cap;
221 vht_cap = &wiphy->bands[chandef->chan->band]->vht_cap;
225 222
226 if (WARN_ON(!cfg80211_chan_def_valid(chandef))) { 223 control_freq = chandef->chan->center_freq;
227 trace_cfg80211_return_bool(false);
228 return false;
229 }
230 224
231 switch (chandef->width) { 225 switch (chandef->width) {
232 case NL80211_CHAN_WIDTH_20_NOHT:
233 case NL80211_CHAN_WIDTH_20: 226 case NL80211_CHAN_WIDTH_20:
227 if (!ht_cap->ht_supported)
228 return false;
229 case NL80211_CHAN_WIDTH_20_NOHT:
234 width = 20; 230 width = 20;
235 break; 231 break;
236 case NL80211_CHAN_WIDTH_40: 232 case NL80211_CHAN_WIDTH_40:
237 width = 40; 233 width = 40;
234 if (!ht_cap->ht_supported)
235 return false;
236 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
237 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
238 return false;
239 if (chandef->center_freq1 < control_freq &&
240 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
241 return false;
242 if (chandef->center_freq1 > control_freq &&
243 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
244 return false;
238 break; 245 break;
239 case NL80211_CHAN_WIDTH_80:
240 case NL80211_CHAN_WIDTH_80P80: 246 case NL80211_CHAN_WIDTH_80P80:
247 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
248 return false;
249 case NL80211_CHAN_WIDTH_80:
250 if (!vht_cap->vht_supported)
251 return false;
241 width = 80; 252 width = 80;
242 break; 253 break;
243 case NL80211_CHAN_WIDTH_160: 254 case NL80211_CHAN_WIDTH_160:
255 if (!vht_cap->vht_supported)
256 return false;
257 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
258 return false;
244 width = 160; 259 width = 160;
245 break; 260 break;
246 default: 261 default:
247 WARN_ON_ONCE(1); 262 WARN_ON_ONCE(1);
248 trace_cfg80211_return_bool(false);
249 return false; 263 return false;
250 } 264 }
251 265
252 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq1, width); 266 /* TODO: missing regulatory check on 80/160 bandwidth */
267
268 if (!cfg80211_secondary_chans_ok(wiphy, chandef->center_freq1,
269 width, prohibited_flags))
270 return false;
271
272 if (!chandef->center_freq2)
273 return true;
274 return cfg80211_secondary_chans_ok(wiphy, chandef->center_freq2,
275 width, prohibited_flags);
276}
277EXPORT_SYMBOL(cfg80211_chandef_usable);
278
279bool cfg80211_reg_can_beacon(struct wiphy *wiphy,
280 struct cfg80211_chan_def *chandef)
281{
282 bool res;
283
284 trace_cfg80211_reg_can_beacon(wiphy, chandef);
253 285
254 if (res && chandef->center_freq2) 286 res = cfg80211_chandef_usable(wiphy, chandef,
255 res = cfg80211_check_beacon_chans(wiphy, chandef->center_freq2, 287 IEEE80211_CHAN_DISABLED |
256 width); 288 IEEE80211_CHAN_PASSIVE_SCAN |
289 IEEE80211_CHAN_NO_IBSS |
290 IEEE80211_CHAN_RADAR);
257 291
258 trace_cfg80211_return_bool(res); 292 trace_cfg80211_return_bool(res);
259 return res; 293 return res;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index a0c8decf6a47..3563097169cb 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -138,8 +138,6 @@ struct cfg80211_internal_bss {
138 unsigned long ts; 138 unsigned long ts;
139 struct kref ref; 139 struct kref ref;
140 atomic_t hold; 140 atomic_t hold;
141 bool beacon_ies_allocated;
142 bool proberesp_ies_allocated;
143 141
144 /* must be last because of priv member */ 142 /* must be last because of priv member */
145 struct cfg80211_bss pub; 143 struct cfg80211_bss pub;
@@ -483,12 +481,6 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
483void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, 481void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev,
484 enum nl80211_iftype iftype, int num); 482 enum nl80211_iftype iftype, int num);
485 483
486bool cfg80211_chan_def_valid(const struct cfg80211_chan_def *chandef);
487
488bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
489 u32 center_freq, u32 bandwidth,
490 u32 prohibited_flags);
491
492#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 484#define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10
493 485
494#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS 486#ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS
diff --git a/net/wireless/mesh.c b/net/wireless/mesh.c
index 3ee5a7282283..f9d6ce5cfabb 100644
--- a/net/wireless/mesh.c
+++ b/net/wireless/mesh.c
@@ -146,7 +146,8 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
146 if (!setup->chandef.chan) 146 if (!setup->chandef.chan)
147 return -EINVAL; 147 return -EINVAL;
148 148
149 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;; 149 setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
150 setup->chandef.center_freq1 = setup->chandef.chan->center_freq;
150 } 151 }
151 152
152 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) 153 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef))
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d038fa45ecd1..f45706adaf34 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -363,6 +363,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
363 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, }, 363 [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, },
364 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, 364 [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN },
365 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, 365 [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
366 [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
367 [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
366}; 368};
367 369
368/* policy for the key attributes */ 370/* policy for the key attributes */
@@ -1369,9 +1371,7 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1369 struct genl_info *info, 1371 struct genl_info *info,
1370 struct cfg80211_chan_def *chandef) 1372 struct cfg80211_chan_def *chandef)
1371{ 1373{
1372 struct ieee80211_sta_ht_cap *ht_cap; 1374 u32 control_freq;
1373 struct ieee80211_sta_vht_cap *vht_cap;
1374 u32 control_freq, width;
1375 1375
1376 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) 1376 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1377 return -EINVAL; 1377 return -EINVAL;
@@ -1417,67 +1417,13 @@ static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1417 info->attrs[NL80211_ATTR_CENTER_FREQ2]); 1417 info->attrs[NL80211_ATTR_CENTER_FREQ2]);
1418 } 1418 }
1419 1419
1420 ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap; 1420 if (!cfg80211_chandef_valid(chandef))
1421 vht_cap = &rdev->wiphy.bands[chandef->chan->band]->vht_cap;
1422
1423 if (!cfg80211_chan_def_valid(chandef))
1424 return -EINVAL; 1421 return -EINVAL;
1425 1422
1426 switch (chandef->width) { 1423 if (!cfg80211_chandef_usable(&rdev->wiphy, chandef,
1427 case NL80211_CHAN_WIDTH_20: 1424 IEEE80211_CHAN_DISABLED))
1428 if (!ht_cap->ht_supported)
1429 return -EINVAL;
1430 case NL80211_CHAN_WIDTH_20_NOHT:
1431 width = 20;
1432 break;
1433 case NL80211_CHAN_WIDTH_40:
1434 width = 40;
1435 /* quick early regulatory check */
1436 if (chandef->center_freq1 < control_freq &&
1437 chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1438 return -EINVAL;
1439 if (chandef->center_freq1 > control_freq &&
1440 chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1441 return -EINVAL;
1442 if (!ht_cap->ht_supported)
1443 return -EINVAL;
1444 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1445 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1446 return -EINVAL;
1447 break;
1448 case NL80211_CHAN_WIDTH_80:
1449 width = 80;
1450 if (!vht_cap->vht_supported)
1451 return -EINVAL;
1452 break;
1453 case NL80211_CHAN_WIDTH_80P80:
1454 width = 80;
1455 if (!vht_cap->vht_supported)
1456 return -EINVAL;
1457 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
1458 return -EINVAL;
1459 break;
1460 case NL80211_CHAN_WIDTH_160:
1461 width = 160;
1462 if (!vht_cap->vht_supported)
1463 return -EINVAL;
1464 if (!(vht_cap->cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ))
1465 return -EINVAL;
1466 break;
1467 default:
1468 return -EINVAL;
1469 }
1470
1471 if (!cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq1,
1472 width, IEEE80211_CHAN_DISABLED))
1473 return -EINVAL;
1474 if (chandef->center_freq2 &&
1475 !cfg80211_secondary_chans_ok(&rdev->wiphy, chandef->center_freq2,
1476 width, IEEE80211_CHAN_DISABLED))
1477 return -EINVAL; 1425 return -EINVAL;
1478 1426
1479 /* TODO: missing regulatory check on bandwidth */
1480
1481 return 0; 1427 return 0;
1482} 1428}
1483 1429
@@ -1841,7 +1787,7 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
1841static int nl80211_send_chandef(struct sk_buff *msg, 1787static int nl80211_send_chandef(struct sk_buff *msg,
1842 struct cfg80211_chan_def *chandef) 1788 struct cfg80211_chan_def *chandef)
1843{ 1789{
1844 WARN_ON(!cfg80211_chan_def_valid(chandef)); 1790 WARN_ON(!cfg80211_chandef_valid(chandef));
1845 1791
1846 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 1792 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1847 chandef->chan->center_freq)) 1793 chandef->chan->center_freq))
@@ -2732,6 +2678,32 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2732 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); 2678 info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]);
2733 } 2679 }
2734 2680
2681 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
2682 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2683 return -EINVAL;
2684 params.p2p_ctwindow =
2685 nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
2686 if (params.p2p_ctwindow > 127)
2687 return -EINVAL;
2688 if (params.p2p_ctwindow != 0 &&
2689 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
2690 return -EINVAL;
2691 }
2692
2693 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
2694 u8 tmp;
2695
2696 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
2697 return -EINVAL;
2698 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
2699 if (tmp > 1)
2700 return -EINVAL;
2701 params.p2p_opp_ps = tmp;
2702 if (params.p2p_opp_ps != 0 &&
2703 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
2704 return -EINVAL;
2705 }
2706
2735 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 2707 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2736 err = nl80211_parse_chandef(rdev, info, &params.chandef); 2708 err = nl80211_parse_chandef(rdev, info, &params.chandef);
2737 if (err) 2709 if (err)
@@ -3698,6 +3670,8 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
3698 params.use_short_slot_time = -1; 3670 params.use_short_slot_time = -1;
3699 params.ap_isolate = -1; 3671 params.ap_isolate = -1;
3700 params.ht_opmode = -1; 3672 params.ht_opmode = -1;
3673 params.p2p_ctwindow = -1;
3674 params.p2p_opp_ps = -1;
3701 3675
3702 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) 3676 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
3703 params.use_cts_prot = 3677 params.use_cts_prot =
@@ -3720,6 +3694,32 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
3720 params.ht_opmode = 3694 params.ht_opmode =
3721 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]); 3695 nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]);
3722 3696
3697 if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) {
3698 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3699 return -EINVAL;
3700 params.p2p_ctwindow =
3701 nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]);
3702 if (params.p2p_ctwindow < 0)
3703 return -EINVAL;
3704 if (params.p2p_ctwindow != 0 &&
3705 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN))
3706 return -EINVAL;
3707 }
3708
3709 if (info->attrs[NL80211_ATTR_P2P_OPPPS]) {
3710 u8 tmp;
3711
3712 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO)
3713 return -EINVAL;
3714 tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]);
3715 if (tmp > 1)
3716 return -EINVAL;
3717 params.p2p_opp_ps = tmp;
3718 if (params.p2p_opp_ps &&
3719 !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS))
3720 return -EINVAL;
3721 }
3722
3723 if (!rdev->ops->change_bss) 3723 if (!rdev->ops->change_bss)
3724 return -EOPNOTSUPP; 3724 return -EOPNOTSUPP;
3725 3725
@@ -4808,6 +4808,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4808 struct cfg80211_internal_bss *intbss) 4808 struct cfg80211_internal_bss *intbss)
4809{ 4809{
4810 struct cfg80211_bss *res = &intbss->pub; 4810 struct cfg80211_bss *res = &intbss->pub;
4811 const struct cfg80211_bss_ies *ies;
4811 void *hdr; 4812 void *hdr;
4812 struct nlattr *bss; 4813 struct nlattr *bss;
4813 4814
@@ -4828,16 +4829,24 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4828 if (!bss) 4829 if (!bss)
4829 goto nla_put_failure; 4830 goto nla_put_failure;
4830 if ((!is_zero_ether_addr(res->bssid) && 4831 if ((!is_zero_ether_addr(res->bssid) &&
4831 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)) || 4832 nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid)))
4832 (res->information_elements && res->len_information_elements && 4833 goto nla_put_failure;
4833 nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, 4834
4834 res->len_information_elements, 4835 rcu_read_lock();
4835 res->information_elements)) || 4836 ies = rcu_dereference(res->ies);
4836 (res->beacon_ies && res->len_beacon_ies && 4837 if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
4837 res->beacon_ies != res->information_elements && 4838 ies->len, ies->data)) {
4838 nla_put(msg, NL80211_BSS_BEACON_IES, 4839 rcu_read_unlock();
4839 res->len_beacon_ies, res->beacon_ies))) 4840 goto nla_put_failure;
4841 }
4842 ies = rcu_dereference(res->beacon_ies);
4843 if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
4844 ies->len, ies->data)) {
4845 rcu_read_unlock();
4840 goto nla_put_failure; 4846 goto nla_put_failure;
4847 }
4848 rcu_read_unlock();
4849
4841 if (res->tsf && 4850 if (res->tsf &&
4842 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf)) 4851 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
4843 goto nla_put_failure; 4852 goto nla_put_failure;
@@ -5502,6 +5511,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5502 return -EINVAL; 5511 return -EINVAL;
5503 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 5512 if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
5504 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) 5513 !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS))
5514 return -EINVAL;
5505 5515
5506 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5516 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
5507 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; 5517 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
@@ -6529,14 +6539,13 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = {
6529}; 6539};
6530 6540
6531static int nl80211_set_cqm_txe(struct genl_info *info, 6541static int nl80211_set_cqm_txe(struct genl_info *info,
6532 u32 rate, u32 pkts, u32 intvl) 6542 u32 rate, u32 pkts, u32 intvl)
6533{ 6543{
6534 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6544 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6535 struct wireless_dev *wdev; 6545 struct wireless_dev *wdev;
6536 struct net_device *dev = info->user_ptr[1]; 6546 struct net_device *dev = info->user_ptr[1];
6537 6547
6538 if ((rate < 0 || rate > 100) || 6548 if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
6539 (intvl < 0 || intvl > NL80211_CQM_TXE_MAX_INTVL))
6540 return -EINVAL; 6549 return -EINVAL;
6541 6550
6542 wdev = dev->ieee80211_ptr; 6551 wdev = dev->ieee80211_ptr;
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index b75756b05af7..6e5308998e30 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1796,7 +1796,7 @@ EXPORT_SYMBOL(regulatory_hint);
1796 */ 1796 */
1797void regulatory_hint_11d(struct wiphy *wiphy, 1797void regulatory_hint_11d(struct wiphy *wiphy,
1798 enum ieee80211_band band, 1798 enum ieee80211_band band,
1799 u8 *country_ie, 1799 const u8 *country_ie,
1800 u8 country_ie_len) 1800 u8 country_ie_len)
1801{ 1801{
1802 char alpha2[2]; 1802 char alpha2[2];
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index f023c8a31c60..4c0a32ffd530 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -81,7 +81,7 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
81 */ 81 */
82void regulatory_hint_11d(struct wiphy *wiphy, 82void regulatory_hint_11d(struct wiphy *wiphy,
83 enum ieee80211_band band, 83 enum ieee80211_band band,
84 u8 *country_ie, 84 const u8 *country_ie,
85 u8 country_ie_len); 85 u8 country_ie_len);
86 86
87/** 87/**
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9596015975d2..01592d7d4789 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -23,18 +23,23 @@
23 23
24static void bss_release(struct kref *ref) 24static void bss_release(struct kref *ref)
25{ 25{
26 struct cfg80211_bss_ies *ies;
26 struct cfg80211_internal_bss *bss; 27 struct cfg80211_internal_bss *bss;
27 28
28 bss = container_of(ref, struct cfg80211_internal_bss, ref); 29 bss = container_of(ref, struct cfg80211_internal_bss, ref);
30
31 if (WARN_ON(atomic_read(&bss->hold)))
32 return;
33
29 if (bss->pub.free_priv) 34 if (bss->pub.free_priv)
30 bss->pub.free_priv(&bss->pub); 35 bss->pub.free_priv(&bss->pub);
31 36
32 if (bss->beacon_ies_allocated) 37 ies = (void *)rcu_access_pointer(bss->pub.beacon_ies);
33 kfree(bss->pub.beacon_ies); 38 if (ies)
34 if (bss->proberesp_ies_allocated) 39 kfree_rcu(ies, rcu_head);
35 kfree(bss->pub.proberesp_ies); 40 ies = (void *)rcu_access_pointer(bss->pub.proberesp_ies);
36 41 if (ies)
37 BUG_ON(atomic_read(&bss->hold)); 42 kfree_rcu(ies, rcu_head);
38 43
39 kfree(bss); 44 kfree(bss);
40} 45}
@@ -236,9 +241,8 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
236 struct cfg80211_internal_bss *bss; 241 struct cfg80211_internal_bss *bss;
237 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); 242 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
238 243
239 list_for_each_entry(bss, &dev->bss_list, list) { 244 list_for_each_entry(bss, &dev->bss_list, list)
240 bss->ts -= age_jiffies; 245 bss->ts -= age_jiffies;
241 }
242} 246}
243 247
244void cfg80211_bss_expire(struct cfg80211_registered_device *dev) 248void cfg80211_bss_expire(struct cfg80211_registered_device *dev)
@@ -287,7 +291,7 @@ const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type,
287} 291}
288EXPORT_SYMBOL(cfg80211_find_vendor_ie); 292EXPORT_SYMBOL(cfg80211_find_vendor_ie);
289 293
290static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2) 294static int cmp_ies(u8 num, const u8 *ies1, int len1, const u8 *ies2, int len2)
291{ 295{
292 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1); 296 const u8 *ie1 = cfg80211_find_ie(num, ies1, len1);
293 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2); 297 const u8 *ie2 = cfg80211_find_ie(num, ies2, len2);
@@ -307,10 +311,10 @@ static int cmp_ies(u8 num, u8 *ies1, size_t len1, u8 *ies2, size_t len2)
307 return memcmp(ie1 + 2, ie2 + 2, ie1[1]); 311 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
308} 312}
309 313
310static bool is_bss(struct cfg80211_bss *a, 314static bool is_bss(struct cfg80211_bss *a, const u8 *bssid,
311 const u8 *bssid,
312 const u8 *ssid, size_t ssid_len) 315 const u8 *ssid, size_t ssid_len)
313{ 316{
317 const struct cfg80211_bss_ies *ies;
314 const u8 *ssidie; 318 const u8 *ssidie;
315 319
316 if (bssid && !ether_addr_equal(a->bssid, bssid)) 320 if (bssid && !ether_addr_equal(a->bssid, bssid))
@@ -319,9 +323,10 @@ static bool is_bss(struct cfg80211_bss *a,
319 if (!ssid) 323 if (!ssid)
320 return true; 324 return true;
321 325
322 ssidie = cfg80211_find_ie(WLAN_EID_SSID, 326 ies = rcu_access_pointer(a->ies);
323 a->information_elements, 327 if (!ies)
324 a->len_information_elements); 328 return false;
329 ssidie = cfg80211_find_ie(WLAN_EID_SSID, ies->data, ies->len);
325 if (!ssidie) 330 if (!ssidie)
326 return false; 331 return false;
327 if (ssidie[1] != ssid_len) 332 if (ssidie[1] != ssid_len)
@@ -331,20 +336,21 @@ static bool is_bss(struct cfg80211_bss *a,
331 336
332static bool is_mesh_bss(struct cfg80211_bss *a) 337static bool is_mesh_bss(struct cfg80211_bss *a)
333{ 338{
339 const struct cfg80211_bss_ies *ies;
334 const u8 *ie; 340 const u8 *ie;
335 341
336 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) 342 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
337 return false; 343 return false;
338 344
339 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, 345 ies = rcu_access_pointer(a->ies);
340 a->information_elements, 346 if (!ies)
341 a->len_information_elements); 347 return false;
348
349 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len);
342 if (!ie) 350 if (!ie)
343 return false; 351 return false;
344 352
345 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, 353 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len);
346 a->information_elements,
347 a->len_information_elements);
348 if (!ie) 354 if (!ie)
349 return false; 355 return false;
350 356
@@ -355,14 +361,17 @@ static bool is_mesh(struct cfg80211_bss *a,
355 const u8 *meshid, size_t meshidlen, 361 const u8 *meshid, size_t meshidlen,
356 const u8 *meshcfg) 362 const u8 *meshcfg)
357{ 363{
364 const struct cfg80211_bss_ies *ies;
358 const u8 *ie; 365 const u8 *ie;
359 366
360 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability)) 367 if (!WLAN_CAPABILITY_IS_STA_BSS(a->capability))
361 return false; 368 return false;
362 369
363 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, 370 ies = rcu_access_pointer(a->ies);
364 a->information_elements, 371 if (!ies)
365 a->len_information_elements); 372 return false;
373
374 ie = cfg80211_find_ie(WLAN_EID_MESH_ID, ies->data, ies->len);
366 if (!ie) 375 if (!ie)
367 return false; 376 return false;
368 if (ie[1] != meshidlen) 377 if (ie[1] != meshidlen)
@@ -370,9 +379,7 @@ static bool is_mesh(struct cfg80211_bss *a,
370 if (memcmp(ie + 2, meshid, meshidlen)) 379 if (memcmp(ie + 2, meshid, meshidlen))
371 return false; 380 return false;
372 381
373 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, 382 ie = cfg80211_find_ie(WLAN_EID_MESH_CONFIG, ies->data, ies->len);
374 a->information_elements,
375 a->len_information_elements);
376 if (!ie) 383 if (!ie)
377 return false; 384 return false;
378 if (ie[1] != sizeof(struct ieee80211_meshconf_ie)) 385 if (ie[1] != sizeof(struct ieee80211_meshconf_ie))
@@ -384,30 +391,33 @@ static bool is_mesh(struct cfg80211_bss *a,
384 * part in the same mesh. 391 * part in the same mesh.
385 */ 392 */
386 return memcmp(ie + 2, meshcfg, 393 return memcmp(ie + 2, meshcfg,
387 sizeof(struct ieee80211_meshconf_ie) - 2) == 0; 394 sizeof(struct ieee80211_meshconf_ie) - 2) == 0;
388} 395}
389 396
390static int cmp_bss_core(struct cfg80211_bss *a, 397static int cmp_bss_core(struct cfg80211_bss *a, struct cfg80211_bss *b)
391 struct cfg80211_bss *b)
392{ 398{
399 const struct cfg80211_bss_ies *a_ies, *b_ies;
393 int r; 400 int r;
394 401
395 if (a->channel != b->channel) 402 if (a->channel != b->channel)
396 return b->channel->center_freq - a->channel->center_freq; 403 return b->channel->center_freq - a->channel->center_freq;
397 404
398 if (is_mesh_bss(a) && is_mesh_bss(b)) { 405 if (is_mesh_bss(a) && is_mesh_bss(b)) {
406 a_ies = rcu_access_pointer(a->ies);
407 if (!a_ies)
408 return -1;
409 b_ies = rcu_access_pointer(b->ies);
410 if (!b_ies)
411 return 1;
412
399 r = cmp_ies(WLAN_EID_MESH_ID, 413 r = cmp_ies(WLAN_EID_MESH_ID,
400 a->information_elements, 414 a_ies->data, a_ies->len,
401 a->len_information_elements, 415 b_ies->data, b_ies->len);
402 b->information_elements,
403 b->len_information_elements);
404 if (r) 416 if (r)
405 return r; 417 return r;
406 return cmp_ies(WLAN_EID_MESH_CONFIG, 418 return cmp_ies(WLAN_EID_MESH_CONFIG,
407 a->information_elements, 419 a_ies->data, a_ies->len,
408 a->len_information_elements, 420 b_ies->data, b_ies->len);
409 b->information_elements,
410 b->len_information_elements);
411 } 421 }
412 422
413 /* 423 /*
@@ -420,22 +430,28 @@ static int cmp_bss_core(struct cfg80211_bss *a,
420static int cmp_bss(struct cfg80211_bss *a, 430static int cmp_bss(struct cfg80211_bss *a,
421 struct cfg80211_bss *b) 431 struct cfg80211_bss *b)
422{ 432{
433 const struct cfg80211_bss_ies *a_ies, *b_ies;
423 int r; 434 int r;
424 435
425 r = cmp_bss_core(a, b); 436 r = cmp_bss_core(a, b);
426 if (r) 437 if (r)
427 return r; 438 return r;
428 439
440 a_ies = rcu_access_pointer(a->ies);
441 if (!a_ies)
442 return -1;
443 b_ies = rcu_access_pointer(b->ies);
444 if (!b_ies)
445 return 1;
446
429 return cmp_ies(WLAN_EID_SSID, 447 return cmp_ies(WLAN_EID_SSID,
430 a->information_elements, 448 a_ies->data, a_ies->len,
431 a->len_information_elements, 449 b_ies->data, b_ies->len);
432 b->information_elements,
433 b->len_information_elements);
434} 450}
435 451
436static int cmp_hidden_bss(struct cfg80211_bss *a, 452static int cmp_hidden_bss(struct cfg80211_bss *a, struct cfg80211_bss *b)
437 struct cfg80211_bss *b)
438{ 453{
454 const struct cfg80211_bss_ies *a_ies, *b_ies;
439 const u8 *ie1; 455 const u8 *ie1;
440 const u8 *ie2; 456 const u8 *ie2;
441 int i; 457 int i;
@@ -445,17 +461,26 @@ static int cmp_hidden_bss(struct cfg80211_bss *a,
445 if (r) 461 if (r)
446 return r; 462 return r;
447 463
448 ie1 = cfg80211_find_ie(WLAN_EID_SSID, 464 a_ies = rcu_access_pointer(a->ies);
449 a->information_elements, 465 if (!a_ies)
450 a->len_information_elements); 466 return -1;
451 ie2 = cfg80211_find_ie(WLAN_EID_SSID, 467 b_ies = rcu_access_pointer(b->ies);
452 b->information_elements, 468 if (!b_ies)
453 b->len_information_elements); 469 return 1;
470
471 ie1 = cfg80211_find_ie(WLAN_EID_SSID, a_ies->data, a_ies->len);
472 ie2 = cfg80211_find_ie(WLAN_EID_SSID, b_ies->data, b_ies->len);
454 473
455 /* Key comparator must use same algorithm in any rb-tree 474 /*
475 * Key comparator must use same algorithm in any rb-tree
456 * search function (order is important), otherwise ordering 476 * search function (order is important), otherwise ordering
457 * of items in the tree is broken and search gives incorrect 477 * of items in the tree is broken and search gives incorrect
458 * results. This code uses same order as cmp_ies() does. */ 478 * results. This code uses same order as cmp_ies() does.
479 *
480 * Note that due to the differring behaviour with hidden SSIDs
481 * this function only works when "b" is the tree element and
482 * "a" is the key we're looking for.
483 */
459 484
460 /* sort missing IE before (left of) present IE */ 485 /* sort missing IE before (left of) present IE */
461 if (!ie1) 486 if (!ie1)
@@ -471,10 +496,14 @@ static int cmp_hidden_bss(struct cfg80211_bss *a,
471 if (ie1[1] != ie2[1]) 496 if (ie1[1] != ie2[1])
472 return ie2[1] - ie1[1]; 497 return ie2[1] - ie1[1];
473 498
474 /* zeroed SSID ie is another indication of a hidden bss */ 499 /*
500 * zeroed SSID ie is another indication of a hidden bss;
501 * if it isn't zeroed just return the regular sort value
502 * to find the next candidate
503 */
475 for (i = 0; i < ie2[1]; i++) 504 for (i = 0; i < ie2[1]; i++)
476 if (ie2[i + 2]) 505 if (ie2[i + 2])
477 return -1; 506 return memcmp(ie1 + 2, ie2 + 2, ie1[1]);
478 507
479 return 0; 508 return 0;
480} 509}
@@ -600,7 +629,7 @@ rb_find_bss(struct cfg80211_registered_device *dev,
600 629
601static struct cfg80211_internal_bss * 630static struct cfg80211_internal_bss *
602rb_find_hidden_bss(struct cfg80211_registered_device *dev, 631rb_find_hidden_bss(struct cfg80211_registered_device *dev,
603 struct cfg80211_internal_bss *res) 632 struct cfg80211_internal_bss *res)
604{ 633{
605 struct rb_node *n = dev->bss_tree.rb_node; 634 struct rb_node *n = dev->bss_tree.rb_node;
606 struct cfg80211_internal_bss *bss; 635 struct cfg80211_internal_bss *bss;
@@ -623,127 +652,86 @@ rb_find_hidden_bss(struct cfg80211_registered_device *dev,
623 652
624static void 653static void
625copy_hidden_ies(struct cfg80211_internal_bss *res, 654copy_hidden_ies(struct cfg80211_internal_bss *res,
626 struct cfg80211_internal_bss *hidden) 655 struct cfg80211_internal_bss *hidden)
627{ 656{
628 if (unlikely(res->pub.beacon_ies)) 657 const struct cfg80211_bss_ies *ies;
629 return; 658
630 if (WARN_ON(!hidden->pub.beacon_ies)) 659 if (rcu_access_pointer(res->pub.beacon_ies))
631 return; 660 return;
632 661
633 res->pub.beacon_ies = kmalloc(hidden->pub.len_beacon_ies, GFP_ATOMIC); 662 ies = rcu_access_pointer(hidden->pub.beacon_ies);
634 if (unlikely(!res->pub.beacon_ies)) 663 if (WARN_ON(!ies))
635 return; 664 return;
636 665
637 res->beacon_ies_allocated = true; 666 ies = kmemdup(ies, sizeof(*ies) + ies->len, GFP_ATOMIC);
638 res->pub.len_beacon_ies = hidden->pub.len_beacon_ies; 667 if (unlikely(!ies))
639 memcpy(res->pub.beacon_ies, hidden->pub.beacon_ies, 668 return;
640 res->pub.len_beacon_ies); 669 rcu_assign_pointer(res->pub.beacon_ies, ies);
641} 670}
642 671
643static struct cfg80211_internal_bss * 672static struct cfg80211_internal_bss *
644cfg80211_bss_update(struct cfg80211_registered_device *dev, 673cfg80211_bss_update(struct cfg80211_registered_device *dev,
645 struct cfg80211_internal_bss *res) 674 struct cfg80211_internal_bss *tmp)
646{ 675{
647 struct cfg80211_internal_bss *found = NULL; 676 struct cfg80211_internal_bss *found = NULL;
648 677
649 /* 678 if (WARN_ON(!tmp->pub.channel))
650 * The reference to "res" is donated to this function.
651 */
652
653 if (WARN_ON(!res->pub.channel)) {
654 kref_put(&res->ref, bss_release);
655 return NULL; 679 return NULL;
656 }
657 680
658 res->ts = jiffies; 681 tmp->ts = jiffies;
659 682
660 spin_lock_bh(&dev->bss_lock); 683 spin_lock_bh(&dev->bss_lock);
661 684
662 found = rb_find_bss(dev, res); 685 if (WARN_ON(!rcu_access_pointer(tmp->pub.ies))) {
686 spin_unlock_bh(&dev->bss_lock);
687 return NULL;
688 }
689
690 found = rb_find_bss(dev, tmp);
663 691
664 if (found) { 692 if (found) {
665 found->pub.beacon_interval = res->pub.beacon_interval; 693 found->pub.beacon_interval = tmp->pub.beacon_interval;
666 found->pub.tsf = res->pub.tsf; 694 found->pub.tsf = tmp->pub.tsf;
667 found->pub.signal = res->pub.signal; 695 found->pub.signal = tmp->pub.signal;
668 found->pub.capability = res->pub.capability; 696 found->pub.capability = tmp->pub.capability;
669 found->ts = res->ts; 697 found->ts = tmp->ts;
670 698
671 /* Update IEs */ 699 /* Update IEs */
672 if (res->pub.proberesp_ies) { 700 if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
673 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 701 const struct cfg80211_bss_ies *old;
674 size_t ielen = res->pub.len_proberesp_ies;
675
676 if (found->pub.proberesp_ies &&
677 !found->proberesp_ies_allocated &&
678 ksize(found) >= used + ielen) {
679 memcpy(found->pub.proberesp_ies,
680 res->pub.proberesp_ies, ielen);
681 found->pub.len_proberesp_ies = ielen;
682 } else {
683 u8 *ies = found->pub.proberesp_ies;
684
685 if (found->proberesp_ies_allocated)
686 ies = krealloc(ies, ielen, GFP_ATOMIC);
687 else
688 ies = kmalloc(ielen, GFP_ATOMIC);
689
690 if (ies) {
691 memcpy(ies, res->pub.proberesp_ies,
692 ielen);
693 found->proberesp_ies_allocated = true;
694 found->pub.proberesp_ies = ies;
695 found->pub.len_proberesp_ies = ielen;
696 }
697 }
698 702
703 old = rcu_access_pointer(found->pub.proberesp_ies);
704
705 rcu_assign_pointer(found->pub.proberesp_ies,
706 tmp->pub.proberesp_ies);
699 /* Override possible earlier Beacon frame IEs */ 707 /* Override possible earlier Beacon frame IEs */
700 found->pub.information_elements = 708 rcu_assign_pointer(found->pub.ies,
701 found->pub.proberesp_ies; 709 tmp->pub.proberesp_ies);
702 found->pub.len_information_elements = 710 if (old)
703 found->pub.len_proberesp_ies; 711 kfree_rcu((struct cfg80211_bss_ies *)old,
704 } 712 rcu_head);
705 if (res->pub.beacon_ies) { 713 } else if (rcu_access_pointer(tmp->pub.beacon_ies)) {
706 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 714 const struct cfg80211_bss_ies *old, *ies;
707 size_t ielen = res->pub.len_beacon_ies; 715
708 bool information_elements_is_beacon_ies = 716 old = rcu_access_pointer(found->pub.beacon_ies);
709 (found->pub.information_elements == 717 ies = rcu_access_pointer(found->pub.ies);
710 found->pub.beacon_ies); 718
711 719 rcu_assign_pointer(found->pub.beacon_ies,
712 if (found->pub.beacon_ies && 720 tmp->pub.beacon_ies);
713 !found->beacon_ies_allocated &&
714 ksize(found) >= used + ielen) {
715 memcpy(found->pub.beacon_ies,
716 res->pub.beacon_ies, ielen);
717 found->pub.len_beacon_ies = ielen;
718 } else {
719 u8 *ies = found->pub.beacon_ies;
720
721 if (found->beacon_ies_allocated)
722 ies = krealloc(ies, ielen, GFP_ATOMIC);
723 else
724 ies = kmalloc(ielen, GFP_ATOMIC);
725
726 if (ies) {
727 memcpy(ies, res->pub.beacon_ies,
728 ielen);
729 found->beacon_ies_allocated = true;
730 found->pub.beacon_ies = ies;
731 found->pub.len_beacon_ies = ielen;
732 }
733 }
734 721
735 /* Override IEs if they were from a beacon before */ 722 /* Override IEs if they were from a beacon before */
736 if (information_elements_is_beacon_ies) { 723 if (old == ies)
737 found->pub.information_elements = 724 rcu_assign_pointer(found->pub.ies,
738 found->pub.beacon_ies; 725 tmp->pub.beacon_ies);
739 found->pub.len_information_elements =
740 found->pub.len_beacon_ies;
741 }
742 }
743 726
744 kref_put(&res->ref, bss_release); 727 if (old)
728 kfree_rcu((struct cfg80211_bss_ies *)old,
729 rcu_head);
730 }
745 } else { 731 } else {
732 struct cfg80211_internal_bss *new;
746 struct cfg80211_internal_bss *hidden; 733 struct cfg80211_internal_bss *hidden;
734 struct cfg80211_bss_ies *ies;
747 735
748 /* First check if the beacon is a probe response from 736 /* First check if the beacon is a probe response from
749 * a hidden bss. If so, copy beacon ies (with nullified 737 * a hidden bss. If so, copy beacon ies (with nullified
@@ -754,14 +742,32 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
754 /* TODO: The code is not trying to update existing probe 742 /* TODO: The code is not trying to update existing probe
755 * response bss entries when beacon ies are 743 * response bss entries when beacon ies are
756 * getting changed. */ 744 * getting changed. */
757 hidden = rb_find_hidden_bss(dev, res); 745 hidden = rb_find_hidden_bss(dev, tmp);
758 if (hidden) 746 if (hidden)
759 copy_hidden_ies(res, hidden); 747 copy_hidden_ies(tmp, hidden);
760 748
761 /* this "consumes" the reference */ 749 /*
762 list_add_tail(&res->list, &dev->bss_list); 750 * create a copy -- the "res" variable that is passed in
763 rb_insert_bss(dev, res); 751 * is allocated on the stack since it's not needed in the
764 found = res; 752 * more common case of an update
753 */
754 new = kzalloc(sizeof(*new) + dev->wiphy.bss_priv_size,
755 GFP_ATOMIC);
756 if (!new) {
757 ies = (void *)rcu_dereference(tmp->pub.beacon_ies);
758 if (ies)
759 kfree_rcu(ies, rcu_head);
760 ies = (void *)rcu_dereference(tmp->pub.proberesp_ies);
761 if (ies)
762 kfree_rcu(ies, rcu_head);
763 spin_unlock_bh(&dev->bss_lock);
764 return NULL;
765 }
766 memcpy(new, tmp, sizeof(*new));
767 kref_init(&new->ref);
768 list_add_tail(&new->list, &dev->bss_list);
769 rb_insert_bss(dev, new);
770 found = new;
765 } 771 }
766 772
767 dev->bss_generation++; 773 dev->bss_generation++;
@@ -810,14 +816,12 @@ cfg80211_inform_bss(struct wiphy *wiphy,
810 u16 beacon_interval, const u8 *ie, size_t ielen, 816 u16 beacon_interval, const u8 *ie, size_t ielen,
811 s32 signal, gfp_t gfp) 817 s32 signal, gfp_t gfp)
812{ 818{
813 struct cfg80211_internal_bss *res; 819 struct cfg80211_bss_ies *ies;
814 size_t privsz; 820 struct cfg80211_internal_bss tmp = {}, *res;
815 821
816 if (WARN_ON(!wiphy)) 822 if (WARN_ON(!wiphy))
817 return NULL; 823 return NULL;
818 824
819 privsz = wiphy->bss_priv_size;
820
821 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC && 825 if (WARN_ON(wiphy->signal_type == CFG80211_SIGNAL_TYPE_UNSPEC &&
822 (signal < 0 || signal > 100))) 826 (signal < 0 || signal > 100)))
823 return NULL; 827 return NULL;
@@ -826,36 +830,33 @@ cfg80211_inform_bss(struct wiphy *wiphy,
826 if (!channel) 830 if (!channel)
827 return NULL; 831 return NULL;
828 832
829 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 833 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
830 if (!res) 834 tmp.pub.channel = channel;
831 return NULL; 835 tmp.pub.signal = signal;
832 836 tmp.pub.tsf = tsf;
833 memcpy(res->pub.bssid, bssid, ETH_ALEN); 837 tmp.pub.beacon_interval = beacon_interval;
834 res->pub.channel = channel; 838 tmp.pub.capability = capability;
835 res->pub.signal = signal;
836 res->pub.tsf = tsf;
837 res->pub.beacon_interval = beacon_interval;
838 res->pub.capability = capability;
839 /* 839 /*
840 * Since we do not know here whether the IEs are from a Beacon or Probe 840 * Since we do not know here whether the IEs are from a Beacon or Probe
841 * Response frame, we need to pick one of the options and only use it 841 * Response frame, we need to pick one of the options and only use it
842 * with the driver that does not provide the full Beacon/Probe Response 842 * with the driver that does not provide the full Beacon/Probe Response
843 * frame. Use Beacon frame pointer to avoid indicating that this should 843 * frame. Use Beacon frame pointer to avoid indicating that this should
844 * override the information_elements pointer should we have received an 844 * override the iies pointer should we have received an earlier
845 * earlier indication of Probe Response data. 845 * indication of Probe Response data.
846 * 846 *
847 * The initial buffer for the IEs is allocated with the BSS entry and 847 * The initial buffer for the IEs is allocated with the BSS entry and
848 * is located after the private area. 848 * is located after the private area.
849 */ 849 */
850 res->pub.beacon_ies = (u8 *)res + sizeof(*res) + privsz; 850 ies = kmalloc(sizeof(*ies) + ielen, gfp);
851 memcpy(res->pub.beacon_ies, ie, ielen); 851 if (!ies)
852 res->pub.len_beacon_ies = ielen; 852 return NULL;
853 res->pub.information_elements = res->pub.beacon_ies; 853 ies->len = ielen;
854 res->pub.len_information_elements = res->pub.len_beacon_ies; 854 memcpy(ies->data, ie, ielen);
855 855
856 kref_init(&res->ref); 856 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
857 rcu_assign_pointer(tmp.pub.ies, ies);
857 858
858 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res); 859 res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
859 if (!res) 860 if (!res)
860 return NULL; 861 return NULL;
861 862
@@ -874,10 +875,10 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
874 struct ieee80211_mgmt *mgmt, size_t len, 875 struct ieee80211_mgmt *mgmt, size_t len,
875 s32 signal, gfp_t gfp) 876 s32 signal, gfp_t gfp)
876{ 877{
877 struct cfg80211_internal_bss *res; 878 struct cfg80211_internal_bss tmp = {}, *res;
879 struct cfg80211_bss_ies *ies;
878 size_t ielen = len - offsetof(struct ieee80211_mgmt, 880 size_t ielen = len - offsetof(struct ieee80211_mgmt,
879 u.probe_resp.variable); 881 u.probe_resp.variable);
880 size_t privsz;
881 882
882 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) != 883 BUILD_BUG_ON(offsetof(struct ieee80211_mgmt, u.probe_resp.variable) !=
883 offsetof(struct ieee80211_mgmt, u.beacon.variable)); 884 offsetof(struct ieee80211_mgmt, u.beacon.variable));
@@ -897,45 +898,31 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
897 if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable))) 898 if (WARN_ON(len < offsetof(struct ieee80211_mgmt, u.probe_resp.variable)))
898 return NULL; 899 return NULL;
899 900
900 privsz = wiphy->bss_priv_size;
901
902 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable, 901 channel = cfg80211_get_bss_channel(wiphy, mgmt->u.beacon.variable,
903 ielen, channel); 902 ielen, channel);
904 if (!channel) 903 if (!channel)
905 return NULL; 904 return NULL;
906 905
907 res = kzalloc(sizeof(*res) + privsz + ielen, gfp); 906 ies = kmalloc(sizeof(*ies) + ielen, gfp);
908 if (!res) 907 if (!ies)
909 return NULL; 908 return NULL;
909 ies->len = ielen;
910 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
910 911
911 memcpy(res->pub.bssid, mgmt->bssid, ETH_ALEN); 912 if (ieee80211_is_probe_resp(mgmt->frame_control))
912 res->pub.channel = channel; 913 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
913 res->pub.signal = signal; 914 else
914 res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 915 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
915 res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 916 rcu_assign_pointer(tmp.pub.ies, ies);
916 res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 917
917 /* 918 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
918 * The initial buffer for the IEs is allocated with the BSS entry and 919 tmp.pub.channel = channel;
919 * is located after the private area. 920 tmp.pub.signal = signal;
920 */ 921 tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
921 if (ieee80211_is_probe_resp(mgmt->frame_control)) { 922 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
922 res->pub.proberesp_ies = (u8 *) res + sizeof(*res) + privsz; 923 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
923 memcpy(res->pub.proberesp_ies, mgmt->u.probe_resp.variable, 924
924 ielen); 925 res = cfg80211_bss_update(wiphy_to_dev(wiphy), &tmp);
925 res->pub.len_proberesp_ies = ielen;
926 res->pub.information_elements = res->pub.proberesp_ies;
927 res->pub.len_information_elements = res->pub.len_proberesp_ies;
928 } else {
929 res->pub.beacon_ies = (u8 *) res + sizeof(*res) + privsz;
930 memcpy(res->pub.beacon_ies, mgmt->u.beacon.variable, ielen);
931 res->pub.len_beacon_ies = ielen;
932 res->pub.information_elements = res->pub.beacon_ies;
933 res->pub.len_information_elements = res->pub.len_beacon_ies;
934 }
935
936 kref_init(&res->ref);
937
938 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res);
939 if (!res) 926 if (!res)
940 return NULL; 927 return NULL;
941 928
@@ -1127,22 +1114,21 @@ int cfg80211_wext_siwscan(struct net_device *dev,
1127EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan); 1114EXPORT_SYMBOL_GPL(cfg80211_wext_siwscan);
1128 1115
1129static void ieee80211_scan_add_ies(struct iw_request_info *info, 1116static void ieee80211_scan_add_ies(struct iw_request_info *info,
1130 struct cfg80211_bss *bss, 1117 const struct cfg80211_bss_ies *ies,
1131 char **current_ev, char *end_buf) 1118 char **current_ev, char *end_buf)
1132{ 1119{
1133 u8 *pos, *end, *next; 1120 const u8 *pos, *end, *next;
1134 struct iw_event iwe; 1121 struct iw_event iwe;
1135 1122
1136 if (!bss->information_elements || 1123 if (!ies)
1137 !bss->len_information_elements)
1138 return; 1124 return;
1139 1125
1140 /* 1126 /*
1141 * If needed, fragment the IEs buffer (at IE boundaries) into short 1127 * If needed, fragment the IEs buffer (at IE boundaries) into short
1142 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages. 1128 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
1143 */ 1129 */
1144 pos = bss->information_elements; 1130 pos = ies->data;
1145 end = pos + bss->len_information_elements; 1131 end = pos + ies->len;
1146 1132
1147 while (end - pos > IW_GENERIC_IE_MAX) { 1133 while (end - pos > IW_GENERIC_IE_MAX) {
1148 next = pos + 2 + pos[1]; 1134 next = pos + 2 + pos[1];
@@ -1153,7 +1139,8 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
1153 iwe.cmd = IWEVGENIE; 1139 iwe.cmd = IWEVGENIE;
1154 iwe.u.data.length = next - pos; 1140 iwe.u.data.length = next - pos;
1155 *current_ev = iwe_stream_add_point(info, *current_ev, 1141 *current_ev = iwe_stream_add_point(info, *current_ev,
1156 end_buf, &iwe, pos); 1142 end_buf, &iwe,
1143 (void *)pos);
1157 1144
1158 pos = next; 1145 pos = next;
1159 } 1146 }
@@ -1163,7 +1150,8 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
1163 iwe.cmd = IWEVGENIE; 1150 iwe.cmd = IWEVGENIE;
1164 iwe.u.data.length = end - pos; 1151 iwe.u.data.length = end - pos;
1165 *current_ev = iwe_stream_add_point(info, *current_ev, 1152 *current_ev = iwe_stream_add_point(info, *current_ev,
1166 end_buf, &iwe, pos); 1153 end_buf, &iwe,
1154 (void *)pos);
1167 } 1155 }
1168} 1156}
1169 1157
@@ -1182,10 +1170,11 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1182 struct cfg80211_internal_bss *bss, char *current_ev, 1170 struct cfg80211_internal_bss *bss, char *current_ev,
1183 char *end_buf) 1171 char *end_buf)
1184{ 1172{
1173 const struct cfg80211_bss_ies *ies;
1185 struct iw_event iwe; 1174 struct iw_event iwe;
1175 const u8 *ie;
1186 u8 *buf, *cfg, *p; 1176 u8 *buf, *cfg, *p;
1187 u8 *ie = bss->pub.information_elements; 1177 int rem, i, sig;
1188 int rem = bss->pub.len_information_elements, i, sig;
1189 bool ismesh = false; 1178 bool ismesh = false;
1190 1179
1191 memset(&iwe, 0, sizeof(iwe)); 1180 memset(&iwe, 0, sizeof(iwe));
@@ -1250,7 +1239,17 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1250 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1239 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1251 &iwe, ""); 1240 &iwe, "");
1252 1241
1253 while (rem >= 2) { 1242 rcu_read_lock();
1243 ies = rcu_dereference(bss->pub.ies);
1244 if (ies) {
1245 rem = ies->len;
1246 ie = ies->data;
1247 } else {
1248 rem = 0;
1249 ie = NULL;
1250 }
1251
1252 while (ies && rem >= 2) {
1254 /* invalid data */ 1253 /* invalid data */
1255 if (ie[1] > rem - 2) 1254 if (ie[1] > rem - 2)
1256 break; 1255 break;
@@ -1262,7 +1261,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1262 iwe.u.data.length = ie[1]; 1261 iwe.u.data.length = ie[1];
1263 iwe.u.data.flags = 1; 1262 iwe.u.data.flags = 1;
1264 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1263 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1265 &iwe, ie + 2); 1264 &iwe, (u8 *)ie + 2);
1266 break; 1265 break;
1267 case WLAN_EID_MESH_ID: 1266 case WLAN_EID_MESH_ID:
1268 memset(&iwe, 0, sizeof(iwe)); 1267 memset(&iwe, 0, sizeof(iwe));
@@ -1270,7 +1269,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1270 iwe.u.data.length = ie[1]; 1269 iwe.u.data.length = ie[1];
1271 iwe.u.data.flags = 1; 1270 iwe.u.data.flags = 1;
1272 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1271 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1273 &iwe, ie + 2); 1272 &iwe, (u8 *)ie + 2);
1274 break; 1273 break;
1275 case WLAN_EID_MESH_CONFIG: 1274 case WLAN_EID_MESH_CONFIG:
1276 ismesh = true; 1275 ismesh = true;
@@ -1279,7 +1278,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1279 buf = kmalloc(50, GFP_ATOMIC); 1278 buf = kmalloc(50, GFP_ATOMIC);
1280 if (!buf) 1279 if (!buf)
1281 break; 1280 break;
1282 cfg = ie + 2; 1281 cfg = (u8 *)ie + 2;
1283 memset(&iwe, 0, sizeof(iwe)); 1282 memset(&iwe, 0, sizeof(iwe));
1284 iwe.cmd = IWEVCUSTOM; 1283 iwe.cmd = IWEVCUSTOM;
1285 sprintf(buf, "Mesh Network Path Selection Protocol ID: " 1284 sprintf(buf, "Mesh Network Path Selection Protocol ID: "
@@ -1377,7 +1376,8 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1377 kfree(buf); 1376 kfree(buf);
1378 } 1377 }
1379 1378
1380 ieee80211_scan_add_ies(info, &bss->pub, &current_ev, end_buf); 1379 ieee80211_scan_add_ies(info, ies, &current_ev, end_buf);
1380 rcu_read_unlock();
1381 1381
1382 return current_ev; 1382 return current_ev;
1383} 1383}
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index c7490027237d..f2431e41a373 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -417,7 +417,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
417 struct cfg80211_bss *bss) 417 struct cfg80211_bss *bss)
418{ 418{
419 struct wireless_dev *wdev = dev->ieee80211_ptr; 419 struct wireless_dev *wdev = dev->ieee80211_ptr;
420 u8 *country_ie; 420 const u8 *country_ie;
421#ifdef CONFIG_CFG80211_WEXT 421#ifdef CONFIG_CFG80211_WEXT
422 union iwreq_data wrqu; 422 union iwreq_data wrqu;
423#endif 423#endif
@@ -501,7 +501,15 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
501 wdev->sme_state = CFG80211_SME_CONNECTED; 501 wdev->sme_state = CFG80211_SME_CONNECTED;
502 cfg80211_upload_connect_keys(wdev); 502 cfg80211_upload_connect_keys(wdev);
503 503
504 country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY); 504 rcu_read_lock();
505 country_ie = ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
506 if (!country_ie) {
507 rcu_read_unlock();
508 return;
509 }
510
511 country_ie = kmemdup(country_ie, 2 + country_ie[1], GFP_ATOMIC);
512 rcu_read_unlock();
505 513
506 if (!country_ie) 514 if (!country_ie)
507 return; 515 return;
@@ -515,6 +523,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
515 bss->channel->band, 523 bss->channel->band,
516 country_ie + 2, 524 country_ie + 2,
517 country_ie[1]); 525 country_ie[1]);
526 kfree(country_ie);
518} 527}
519 528
520void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 529void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 3cce6e486219..16d76a807c2f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -688,10 +688,13 @@ EXPORT_SYMBOL(cfg80211_classify8021d);
688 688
689const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie) 689const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
690{ 690{
691 if (bss->information_elements == NULL) 691 const struct cfg80211_bss_ies *ies;
692
693 ies = rcu_dereference(bss->ies);
694 if (!ies)
692 return NULL; 695 return NULL;
693 return cfg80211_find_ie(ie, bss->information_elements, 696
694 bss->len_information_elements); 697 return cfg80211_find_ie(ie, ies->data, ies->len);
695} 698}
696EXPORT_SYMBOL(ieee80211_bss_get_ie); 699EXPORT_SYMBOL(ieee80211_bss_get_ie);
697 700
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 873af63187c0..fb9622f6d99c 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -242,13 +242,17 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
242 242
243 wdev_lock(wdev); 243 wdev_lock(wdev);
244 if (wdev->current_bss) { 244 if (wdev->current_bss) {
245 const u8 *ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, 245 const u8 *ie;
246 WLAN_EID_SSID); 246
247 rcu_read_lock();
248 ie = ieee80211_bss_get_ie(&wdev->current_bss->pub,
249 WLAN_EID_SSID);
247 if (ie) { 250 if (ie) {
248 data->flags = 1; 251 data->flags = 1;
249 data->length = ie[1]; 252 data->length = ie[1];
250 memcpy(ssid, ie + 2, data->length); 253 memcpy(ssid, ie + 2, data->length);
251 } 254 }
255 rcu_read_unlock();
252 } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) { 256 } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
253 data->flags = 1; 257 data->flags = 1;
254 data->length = wdev->wext.connect.ssid_len; 258 data->length = wdev->wext.connect.ssid_len;