diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-07-20 12:30:48 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-07-20 12:30:48 -0400 |
commit | 90b90f60c4f8e3a8525dfeb4aec46a9c7a29c857 (patch) | |
tree | 9b1d8ca6084012a02b302520bc26e5be65ba7b2a | |
parent | 769162e38b91e1d300752e666260fa6c7b203fbc (diff) | |
parent | 36eb22e97a2b621fb707eead58ef915ab0f46e9e (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
163 files changed, 5129 insertions, 2905 deletions
diff --git a/Documentation/DocBook/80211.tmpl b/Documentation/DocBook/80211.tmpl index f3e214f9e256..42e7f030cb16 100644 --- a/Documentation/DocBook/80211.tmpl +++ b/Documentation/DocBook/80211.tmpl | |||
@@ -404,7 +404,6 @@ | |||
404 | !Finclude/net/mac80211.h ieee80211_get_tkip_p1k | 404 | !Finclude/net/mac80211.h ieee80211_get_tkip_p1k |
405 | !Finclude/net/mac80211.h ieee80211_get_tkip_p1k_iv | 405 | !Finclude/net/mac80211.h ieee80211_get_tkip_p1k_iv |
406 | !Finclude/net/mac80211.h ieee80211_get_tkip_p2k | 406 | !Finclude/net/mac80211.h ieee80211_get_tkip_p2k |
407 | !Finclude/net/mac80211.h ieee80211_key_removed | ||
408 | </chapter> | 407 | </chapter> |
409 | 408 | ||
410 | <chapter id="powersave"> | 409 | <chapter id="powersave"> |
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index fb7c80fb721e..06b3207adebd 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
@@ -46,6 +46,25 @@ config BCMA_DRIVER_MIPS | |||
46 | 46 | ||
47 | If unsure, say N | 47 | If unsure, say N |
48 | 48 | ||
49 | config BCMA_SFLASH | ||
50 | bool | ||
51 | depends on BCMA_DRIVER_MIPS && BROKEN | ||
52 | default y | ||
53 | |||
54 | config BCMA_NFLASH | ||
55 | bool | ||
56 | depends on BCMA_DRIVER_MIPS && BROKEN | ||
57 | default y | ||
58 | |||
59 | config BCMA_DRIVER_GMAC_CMN | ||
60 | bool "BCMA Broadcom GBIT MAC COMMON core driver" | ||
61 | depends on BCMA | ||
62 | help | ||
63 | Driver for the Broadcom GBIT MAC COMMON core attached to Broadcom | ||
64 | specific Advanced Microcontroller Bus. | ||
65 | |||
66 | If unsure, say N | ||
67 | |||
49 | config BCMA_DEBUG | 68 | config BCMA_DEBUG |
50 | bool "BCMA debugging" | 69 | bool "BCMA debugging" |
51 | depends on BCMA | 70 | depends on BCMA |
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile index 82de24e5340c..8ad42d41b2f2 100644 --- a/drivers/bcma/Makefile +++ b/drivers/bcma/Makefile | |||
@@ -1,8 +1,11 @@ | |||
1 | bcma-y += main.o scan.o core.o sprom.o | 1 | bcma-y += main.o scan.o core.o sprom.o |
2 | bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o | 2 | bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o |
3 | bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o | ||
4 | bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o | ||
3 | bcma-y += driver_pci.o | 5 | bcma-y += driver_pci.o |
4 | bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o | 6 | bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE) += driver_pci_host.o |
5 | bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o | 7 | bcma-$(CONFIG_BCMA_DRIVER_MIPS) += driver_mips.o |
8 | bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN) += driver_gmac_cmn.o | ||
6 | bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o | 9 | bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o |
7 | bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o | 10 | bcma-$(CONFIG_BCMA_HOST_SOC) += host_soc.o |
8 | obj-$(CONFIG_BCMA) += bcma.o | 11 | obj-$(CONFIG_BCMA) += bcma.o |
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index f6589eb7c45f..3cf9cc923cd2 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -51,6 +51,28 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc); | |||
51 | u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc); | 51 | u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc); |
52 | u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc); | 52 | u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc); |
53 | 53 | ||
54 | #ifdef CONFIG_BCMA_SFLASH | ||
55 | /* driver_chipcommon_sflash.c */ | ||
56 | int bcma_sflash_init(struct bcma_drv_cc *cc); | ||
57 | #else | ||
58 | static inline int bcma_sflash_init(struct bcma_drv_cc *cc) | ||
59 | { | ||
60 | bcma_err(cc->core->bus, "Serial flash not supported\n"); | ||
61 | return 0; | ||
62 | } | ||
63 | #endif /* CONFIG_BCMA_SFLASH */ | ||
64 | |||
65 | #ifdef CONFIG_BCMA_NFLASH | ||
66 | /* driver_chipcommon_nflash.c */ | ||
67 | int bcma_nflash_init(struct bcma_drv_cc *cc); | ||
68 | #else | ||
69 | static inline int bcma_nflash_init(struct bcma_drv_cc *cc) | ||
70 | { | ||
71 | bcma_err(cc->core->bus, "NAND flash not supported\n"); | ||
72 | return 0; | ||
73 | } | ||
74 | #endif /* CONFIG_BCMA_NFLASH */ | ||
75 | |||
54 | #ifdef CONFIG_BCMA_HOST_PCI | 76 | #ifdef CONFIG_BCMA_HOST_PCI |
55 | /* host_pci.c */ | 77 | /* host_pci.c */ |
56 | extern int __init bcma_host_pci_init(void); | 78 | extern int __init bcma_host_pci_init(void); |
diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c new file mode 100644 index 000000000000..574d62435bc2 --- /dev/null +++ b/drivers/bcma/driver_chipcommon_nflash.c | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Broadcom specific AMBA | ||
3 | * ChipCommon NAND flash interface | ||
4 | * | ||
5 | * Licensed under the GNU/GPL. See COPYING for details. | ||
6 | */ | ||
7 | |||
8 | #include <linux/bcma/bcma.h> | ||
9 | #include <linux/bcma/bcma_driver_chipcommon.h> | ||
10 | #include <linux/delay.h> | ||
11 | |||
12 | #include "bcma_private.h" | ||
13 | |||
14 | /* Initialize NAND flash access */ | ||
15 | int bcma_nflash_init(struct bcma_drv_cc *cc) | ||
16 | { | ||
17 | bcma_err(cc->core->bus, "NAND flash support is broken\n"); | ||
18 | return 0; | ||
19 | } | ||
diff --git a/drivers/bcma/driver_chipcommon_sflash.c b/drivers/bcma/driver_chipcommon_sflash.c new file mode 100644 index 000000000000..6e157a58a1d7 --- /dev/null +++ b/drivers/bcma/driver_chipcommon_sflash.c | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Broadcom specific AMBA | ||
3 | * ChipCommon serial flash interface | ||
4 | * | ||
5 | * Licensed under the GNU/GPL. See COPYING for details. | ||
6 | */ | ||
7 | |||
8 | #include <linux/bcma/bcma.h> | ||
9 | #include <linux/bcma/bcma_driver_chipcommon.h> | ||
10 | #include <linux/delay.h> | ||
11 | |||
12 | #include "bcma_private.h" | ||
13 | |||
14 | /* Initialize serial flash access */ | ||
15 | int bcma_sflash_init(struct bcma_drv_cc *cc) | ||
16 | { | ||
17 | bcma_err(cc->core->bus, "Serial flash support is broken\n"); | ||
18 | return 0; | ||
19 | } | ||
diff --git a/drivers/bcma/driver_gmac_cmn.c b/drivers/bcma/driver_gmac_cmn.c new file mode 100644 index 000000000000..834225f65e8f --- /dev/null +++ b/drivers/bcma/driver_gmac_cmn.c | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * Broadcom specific AMBA | ||
3 | * GBIT MAC COMMON Core | ||
4 | * | ||
5 | * Licensed under the GNU/GPL. See COPYING for details. | ||
6 | */ | ||
7 | |||
8 | #include "bcma_private.h" | ||
9 | #include <linux/bcma/bcma.h> | ||
10 | |||
11 | void __devinit bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) | ||
12 | { | ||
13 | mutex_init(&gc->phy_mutex); | ||
14 | } | ||
diff --git a/drivers/bcma/driver_mips.c b/drivers/bcma/driver_mips.c index ef34ed25bf00..b013b049476d 100644 --- a/drivers/bcma/driver_mips.c +++ b/drivers/bcma/driver_mips.c | |||
@@ -185,10 +185,11 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | |||
185 | switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { | 185 | switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) { |
186 | case BCMA_CC_FLASHT_STSER: | 186 | case BCMA_CC_FLASHT_STSER: |
187 | case BCMA_CC_FLASHT_ATSER: | 187 | case BCMA_CC_FLASHT_ATSER: |
188 | bcma_err(bus, "Serial flash not supported.\n"); | 188 | bcma_debug(bus, "Found serial flash\n"); |
189 | bcma_sflash_init(&bus->drv_cc); | ||
189 | break; | 190 | break; |
190 | case BCMA_CC_FLASHT_PARA: | 191 | case BCMA_CC_FLASHT_PARA: |
191 | bcma_info(bus, "found parallel flash.\n"); | 192 | bcma_debug(bus, "Found parallel flash\n"); |
192 | bus->drv_cc.pflash.window = 0x1c000000; | 193 | bus->drv_cc.pflash.window = 0x1c000000; |
193 | bus->drv_cc.pflash.window_size = 0x02000000; | 194 | bus->drv_cc.pflash.window_size = 0x02000000; |
194 | 195 | ||
@@ -199,7 +200,15 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore) | |||
199 | bus->drv_cc.pflash.buswidth = 2; | 200 | bus->drv_cc.pflash.buswidth = 2; |
200 | break; | 201 | break; |
201 | default: | 202 | default: |
202 | bcma_err(bus, "flash not supported.\n"); | 203 | bcma_err(bus, "Flash type not supported\n"); |
204 | } | ||
205 | |||
206 | if (bus->drv_cc.core->id.rev == 38 || | ||
207 | bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { | ||
208 | if (bus->drv_cc.capabilities & BCMA_CC_CAP_NFLASH) { | ||
209 | bcma_debug(bus, "Found NAND flash\n"); | ||
210 | bcma_nflash_init(&bus->drv_cc); | ||
211 | } | ||
203 | } | 212 | } |
204 | } | 213 | } |
205 | 214 | ||
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 7ff4bac6f9e1..758af9ccdef0 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -61,6 +61,13 @@ static struct bus_type bcma_bus_type = { | |||
61 | .dev_attrs = bcma_device_attrs, | 61 | .dev_attrs = bcma_device_attrs, |
62 | }; | 62 | }; |
63 | 63 | ||
64 | static u16 bcma_cc_core_id(struct bcma_bus *bus) | ||
65 | { | ||
66 | if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) | ||
67 | return BCMA_CORE_4706_CHIPCOMMON; | ||
68 | return BCMA_CORE_CHIPCOMMON; | ||
69 | } | ||
70 | |||
64 | struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) | 71 | struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid) |
65 | { | 72 | { |
66 | struct bcma_device *core; | 73 | struct bcma_device *core; |
@@ -91,10 +98,12 @@ static int bcma_register_cores(struct bcma_bus *bus) | |||
91 | list_for_each_entry(core, &bus->cores, list) { | 98 | list_for_each_entry(core, &bus->cores, list) { |
92 | /* We support that cores ourself */ | 99 | /* We support that cores ourself */ |
93 | switch (core->id.id) { | 100 | switch (core->id.id) { |
101 | case BCMA_CORE_4706_CHIPCOMMON: | ||
94 | case BCMA_CORE_CHIPCOMMON: | 102 | case BCMA_CORE_CHIPCOMMON: |
95 | case BCMA_CORE_PCI: | 103 | case BCMA_CORE_PCI: |
96 | case BCMA_CORE_PCIE: | 104 | case BCMA_CORE_PCIE: |
97 | case BCMA_CORE_MIPS_74K: | 105 | case BCMA_CORE_MIPS_74K: |
106 | case BCMA_CORE_4706_MAC_GBIT_COMMON: | ||
98 | continue; | 107 | continue; |
99 | } | 108 | } |
100 | 109 | ||
@@ -157,7 +166,7 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) | |||
157 | } | 166 | } |
158 | 167 | ||
159 | /* Init CC core */ | 168 | /* Init CC core */ |
160 | core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); | 169 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); |
161 | if (core) { | 170 | if (core) { |
162 | bus->drv_cc.core = core; | 171 | bus->drv_cc.core = core; |
163 | bcma_core_chipcommon_init(&bus->drv_cc); | 172 | bcma_core_chipcommon_init(&bus->drv_cc); |
@@ -177,6 +186,13 @@ int __devinit bcma_bus_register(struct bcma_bus *bus) | |||
177 | bcma_core_pci_init(&bus->drv_pci); | 186 | bcma_core_pci_init(&bus->drv_pci); |
178 | } | 187 | } |
179 | 188 | ||
189 | /* Init GBIT MAC COMMON core */ | ||
190 | core = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); | ||
191 | if (core) { | ||
192 | bus->drv_gmac_cmn.core = core; | ||
193 | bcma_core_gmac_cmn_init(&bus->drv_gmac_cmn); | ||
194 | } | ||
195 | |||
180 | /* Try to get SPROM */ | 196 | /* Try to get SPROM */ |
181 | err = bcma_sprom_get(bus); | 197 | err = bcma_sprom_get(bus); |
182 | if (err == -ENOENT) { | 198 | if (err == -ENOENT) { |
@@ -208,7 +224,7 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, | |||
208 | bcma_init_bus(bus); | 224 | bcma_init_bus(bus); |
209 | 225 | ||
210 | match.manuf = BCMA_MANUF_BCM; | 226 | match.manuf = BCMA_MANUF_BCM; |
211 | match.id = BCMA_CORE_CHIPCOMMON; | 227 | match.id = bcma_cc_core_id(bus); |
212 | match.class = BCMA_CL_SIM; | 228 | match.class = BCMA_CL_SIM; |
213 | match.rev = BCMA_ANY_REV; | 229 | match.rev = BCMA_ANY_REV; |
214 | 230 | ||
@@ -232,7 +248,7 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, | |||
232 | } | 248 | } |
233 | 249 | ||
234 | /* Init CC core */ | 250 | /* Init CC core */ |
235 | core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); | 251 | core = bcma_find_core(bus, bcma_cc_core_id(bus)); |
236 | if (core) { | 252 | if (core) { |
237 | bus->drv_cc.core = core; | 253 | bus->drv_cc.core = core; |
238 | bcma_core_chipcommon_init(&bus->drv_cc); | 254 | bcma_core_chipcommon_init(&bus->drv_cc); |
@@ -271,8 +287,7 @@ int bcma_bus_resume(struct bcma_bus *bus) | |||
271 | struct bcma_device *core; | 287 | struct bcma_device *core; |
272 | 288 | ||
273 | /* Init CC core */ | 289 | /* Init CC core */ |
274 | core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON); | 290 | if (bus->drv_cc.core) { |
275 | if (core) { | ||
276 | bus->drv_cc.setup_done = false; | 291 | bus->drv_cc.setup_done = false; |
277 | bcma_core_chipcommon_init(&bus->drv_cc); | 292 | bcma_core_chipcommon_init(&bus->drv_cc); |
278 | } | 293 | } |
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index a0272bbfc4f6..5672b13d0951 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c | |||
@@ -21,6 +21,7 @@ struct bcma_device_id_name { | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | static const struct bcma_device_id_name bcma_arm_device_names[] = { | 23 | static const struct bcma_device_id_name bcma_arm_device_names[] = { |
24 | { BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" }, | ||
24 | { BCMA_CORE_ARM_1176, "ARM 1176" }, | 25 | { BCMA_CORE_ARM_1176, "ARM 1176" }, |
25 | { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" }, | 26 | { BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" }, |
26 | { BCMA_CORE_ARM_CM3, "ARM CM3" }, | 27 | { BCMA_CORE_ARM_CM3, "ARM CM3" }, |
@@ -33,7 +34,6 @@ static const struct bcma_device_id_name bcma_bcm_device_names[] = { | |||
33 | { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" }, | 34 | { BCMA_CORE_4706_MAC_GBIT, "BCM4706 GBit MAC" }, |
34 | { BCMA_CORE_AMEMC, "AMEMC (DDR)" }, | 35 | { BCMA_CORE_AMEMC, "AMEMC (DDR)" }, |
35 | { BCMA_CORE_ALTA, "ALTA (I2S)" }, | 36 | { BCMA_CORE_ALTA, "ALTA (I2S)" }, |
36 | { BCMA_CORE_4706_MAC_GBIT_COMMON, "BCM4706 GBit MAC Common" }, | ||
37 | { BCMA_CORE_INVALID, "Invalid" }, | 37 | { BCMA_CORE_INVALID, "Invalid" }, |
38 | { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, | 38 | { BCMA_CORE_CHIPCOMMON, "ChipCommon" }, |
39 | { BCMA_CORE_ILINE20, "ILine 20" }, | 39 | { BCMA_CORE_ILINE20, "ILine 20" }, |
@@ -295,11 +295,15 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
295 | 295 | ||
296 | /* check if component is a core at all */ | 296 | /* check if component is a core at all */ |
297 | if (wrappers[0] + wrappers[1] == 0) { | 297 | if (wrappers[0] + wrappers[1] == 0) { |
298 | /* we could save addrl of the router | 298 | /* Some specific cores don't need wrappers */ |
299 | if (cid == BCMA_CORE_OOB_ROUTER) | 299 | switch (core->id.id) { |
300 | */ | 300 | case BCMA_CORE_4706_MAC_GBIT_COMMON: |
301 | bcma_erom_skip_component(bus, eromptr); | 301 | /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ |
302 | return -ENXIO; | 302 | break; |
303 | default: | ||
304 | bcma_erom_skip_component(bus, eromptr); | ||
305 | return -ENXIO; | ||
306 | } | ||
303 | } | 307 | } |
304 | 308 | ||
305 | if (bcma_erom_is_bridge(bus, eromptr)) { | 309 | if (bcma_erom_is_bridge(bus, eromptr)) { |
@@ -487,7 +491,7 @@ int bcma_bus_scan(struct bcma_bus *bus) | |||
487 | core->id.manuf, core->id.id, core->id.rev, | 491 | core->id.manuf, core->id.id, core->id.rev, |
488 | core->id.class); | 492 | core->id.class); |
489 | 493 | ||
490 | list_add(&core->list, &bus->cores); | 494 | list_add_tail(&core->list, &bus->cores); |
491 | } | 495 | } |
492 | 496 | ||
493 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) | 497 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) |
@@ -542,7 +546,7 @@ int __init bcma_bus_scan_early(struct bcma_bus *bus, | |||
542 | core->id.manuf, core->id.id, core->id.rev, | 546 | core->id.manuf, core->id.id, core->id.rev, |
543 | core->id.class); | 547 | core->id.class); |
544 | 548 | ||
545 | list_add(&core->list, &bus->cores); | 549 | list_add_tail(&core->list, &bus->cores); |
546 | err = 0; | 550 | err = 0; |
547 | break; | 551 | break; |
548 | } | 552 | } |
diff --git a/drivers/bcma/scan.h b/drivers/bcma/scan.h index 113e6a66884c..30eb475e4d19 100644 --- a/drivers/bcma/scan.h +++ b/drivers/bcma/scan.h | |||
@@ -27,7 +27,7 @@ | |||
27 | #define SCAN_CIB_NMW 0x0007C000 | 27 | #define SCAN_CIB_NMW 0x0007C000 |
28 | #define SCAN_CIB_NMW_SHIFT 14 | 28 | #define SCAN_CIB_NMW_SHIFT 14 |
29 | #define SCAN_CIB_NSW 0x00F80000 | 29 | #define SCAN_CIB_NSW 0x00F80000 |
30 | #define SCAN_CIB_NSW_SHIFT 17 | 30 | #define SCAN_CIB_NSW_SHIFT 19 |
31 | #define SCAN_CIB_REV 0xFF000000 | 31 | #define SCAN_CIB_REV 0xFF000000 |
32 | #define SCAN_CIB_REV_SHIFT 24 | 32 | #define SCAN_CIB_REV_SHIFT 24 |
33 | 33 | ||
diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index 5ccf142ef0b8..e9f203eadb1f 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig | |||
@@ -81,6 +81,18 @@ config BT_HCIUART_LL | |||
81 | 81 | ||
82 | Say Y here to compile support for HCILL protocol. | 82 | Say Y here to compile support for HCILL protocol. |
83 | 83 | ||
84 | config BT_HCIUART_3WIRE | ||
85 | bool "Three-wire UART (H5) protocol support" | ||
86 | depends on BT_HCIUART | ||
87 | help | ||
88 | The HCI Three-wire UART Transport Layer makes it possible to | ||
89 | user the Bluetooth HCI over a serial port interface. The HCI | ||
90 | Three-wire UART Transport Layer assumes that the UART | ||
91 | communication may have bit errors, overrun errors or burst | ||
92 | errors and thereby making CTS/RTS lines unnecessary. | ||
93 | |||
94 | Say Y here to compile support for Three-wire UART protocol. | ||
95 | |||
84 | config BT_HCIBCM203X | 96 | config BT_HCIBCM203X |
85 | tristate "HCI BCM203x USB driver" | 97 | tristate "HCI BCM203x USB driver" |
86 | depends on USB | 98 | depends on USB |
diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index f4460f4f4b78..4afae20df512 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile | |||
@@ -28,4 +28,5 @@ hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o | |||
28 | hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o | 28 | hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o |
29 | hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o | 29 | hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o |
30 | hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o | 30 | hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o |
31 | hci_uart-$(CONFIG_BT_HCIUART_3WIRE) += hci_h5.o | ||
31 | hci_uart-objs := $(hci_uart-y) | 32 | hci_uart-objs := $(hci_uart-y) |
diff --git a/drivers/bluetooth/bluecard_cs.c b/drivers/bluetooth/bluecard_cs.c index 585c88e01893..66c3a6770c41 100644 --- a/drivers/bluetooth/bluecard_cs.c +++ b/drivers/bluetooth/bluecard_cs.c | |||
@@ -621,7 +621,6 @@ static int bluecard_hci_flush(struct hci_dev *hdev) | |||
621 | static int bluecard_hci_open(struct hci_dev *hdev) | 621 | static int bluecard_hci_open(struct hci_dev *hdev) |
622 | { | 622 | { |
623 | bluecard_info_t *info = hci_get_drvdata(hdev); | 623 | bluecard_info_t *info = hci_get_drvdata(hdev); |
624 | unsigned int iobase = info->p_dev->resource[0]->start; | ||
625 | 624 | ||
626 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) | 625 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) |
627 | bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); | 626 | bluecard_hci_set_baud_rate(hdev, DEFAULT_BAUD_RATE); |
@@ -630,6 +629,8 @@ static int bluecard_hci_open(struct hci_dev *hdev) | |||
630 | return 0; | 629 | return 0; |
631 | 630 | ||
632 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { | 631 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { |
632 | unsigned int iobase = info->p_dev->resource[0]->start; | ||
633 | |||
633 | /* Enable LED */ | 634 | /* Enable LED */ |
634 | outb(0x08 | 0x20, iobase + 0x30); | 635 | outb(0x08 | 0x20, iobase + 0x30); |
635 | } | 636 | } |
@@ -641,7 +642,6 @@ static int bluecard_hci_open(struct hci_dev *hdev) | |||
641 | static int bluecard_hci_close(struct hci_dev *hdev) | 642 | static int bluecard_hci_close(struct hci_dev *hdev) |
642 | { | 643 | { |
643 | bluecard_info_t *info = hci_get_drvdata(hdev); | 644 | bluecard_info_t *info = hci_get_drvdata(hdev); |
644 | unsigned int iobase = info->p_dev->resource[0]->start; | ||
645 | 645 | ||
646 | if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) | 646 | if (!test_and_clear_bit(HCI_RUNNING, &(hdev->flags))) |
647 | return 0; | 647 | return 0; |
@@ -649,6 +649,8 @@ static int bluecard_hci_close(struct hci_dev *hdev) | |||
649 | bluecard_hci_flush(hdev); | 649 | bluecard_hci_flush(hdev); |
650 | 650 | ||
651 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { | 651 | if (test_bit(CARD_HAS_PCCARD_ID, &(info->hw_state))) { |
652 | unsigned int iobase = info->p_dev->resource[0]->start; | ||
653 | |||
652 | /* Disable LED */ | 654 | /* Disable LED */ |
653 | outb(0x00, iobase + 0x30); | 655 | outb(0x00, iobase + 0x30); |
654 | } | 656 | } |
diff --git a/drivers/bluetooth/bt3c_cs.c b/drivers/bluetooth/bt3c_cs.c index b2b0fbbb43b5..8925b6d672a6 100644 --- a/drivers/bluetooth/bt3c_cs.c +++ b/drivers/bluetooth/bt3c_cs.c | |||
@@ -664,7 +664,7 @@ static int bt3c_check_config(struct pcmcia_device *p_dev, void *priv_data) | |||
664 | { | 664 | { |
665 | int *try = priv_data; | 665 | int *try = priv_data; |
666 | 666 | ||
667 | if (try == 0) | 667 | if (!try) |
668 | p_dev->io_lines = 16; | 668 | p_dev->io_lines = 16; |
669 | 669 | ||
670 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) | 670 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) |
diff --git a/drivers/bluetooth/btmrvl_main.c b/drivers/bluetooth/btmrvl_main.c index dc304def8400..3a4343b3bd6d 100644 --- a/drivers/bluetooth/btmrvl_main.c +++ b/drivers/bluetooth/btmrvl_main.c | |||
@@ -47,10 +47,11 @@ EXPORT_SYMBOL_GPL(btmrvl_interrupt); | |||
47 | bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) | 47 | bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) |
48 | { | 48 | { |
49 | struct hci_event_hdr *hdr = (void *) skb->data; | 49 | struct hci_event_hdr *hdr = (void *) skb->data; |
50 | struct hci_ev_cmd_complete *ec; | ||
51 | u16 opcode, ocf, ogf; | ||
52 | 50 | ||
53 | if (hdr->evt == HCI_EV_CMD_COMPLETE) { | 51 | if (hdr->evt == HCI_EV_CMD_COMPLETE) { |
52 | struct hci_ev_cmd_complete *ec; | ||
53 | u16 opcode, ocf, ogf; | ||
54 | |||
54 | ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); | 55 | ec = (void *) (skb->data + HCI_EVENT_HDR_SIZE); |
55 | opcode = __le16_to_cpu(ec->opcode); | 56 | opcode = __le16_to_cpu(ec->opcode); |
56 | ocf = hci_opcode_ocf(opcode); | 57 | ocf = hci_opcode_ocf(opcode); |
@@ -64,7 +65,8 @@ bool btmrvl_check_evtpkt(struct btmrvl_private *priv, struct sk_buff *skb) | |||
64 | } | 65 | } |
65 | 66 | ||
66 | if (ogf == OGF) { | 67 | if (ogf == OGF) { |
67 | BT_DBG("vendor event skipped: ogf 0x%4.4x", ogf); | 68 | BT_DBG("vendor event skipped: ogf 0x%4.4x ocf 0x%4.4x", |
69 | ogf, ocf); | ||
68 | kfree_skb(skb); | 70 | kfree_skb(skb); |
69 | return false; | 71 | return false; |
70 | } | 72 | } |
diff --git a/drivers/bluetooth/btmrvl_sdio.c b/drivers/bluetooth/btmrvl_sdio.c index cf7588edba0d..6a9e9717d3ab 100644 --- a/drivers/bluetooth/btmrvl_sdio.c +++ b/drivers/bluetooth/btmrvl_sdio.c | |||
@@ -568,8 +568,9 @@ static int btmrvl_sdio_card_to_host(struct btmrvl_private *priv) | |||
568 | if (type == HCI_EVENT_PKT) { | 568 | if (type == HCI_EVENT_PKT) { |
569 | if (btmrvl_check_evtpkt(priv, skb)) | 569 | if (btmrvl_check_evtpkt(priv, skb)) |
570 | hci_recv_frame(skb); | 570 | hci_recv_frame(skb); |
571 | } else | 571 | } else { |
572 | hci_recv_frame(skb); | 572 | hci_recv_frame(skb); |
573 | } | ||
573 | 574 | ||
574 | hdev->stat.byte_rx += buf_len; | 575 | hdev->stat.byte_rx += buf_len; |
575 | break; | 576 | break; |
diff --git a/drivers/bluetooth/btuart_cs.c b/drivers/bluetooth/btuart_cs.c index 65b8d996840c..21e803a6a281 100644 --- a/drivers/bluetooth/btuart_cs.c +++ b/drivers/bluetooth/btuart_cs.c | |||
@@ -593,7 +593,7 @@ static int btuart_check_config(struct pcmcia_device *p_dev, void *priv_data) | |||
593 | { | 593 | { |
594 | int *try = priv_data; | 594 | int *try = priv_data; |
595 | 595 | ||
596 | if (try == 0) | 596 | if (!try) |
597 | p_dev->io_lines = 16; | 597 | p_dev->io_lines = 16; |
598 | 598 | ||
599 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) | 599 | if ((p_dev->resource[0]->end != 8) || (p_dev->resource[0]->start == 0)) |
diff --git a/drivers/bluetooth/dtl1_cs.c b/drivers/bluetooth/dtl1_cs.c index b1b37ccd3cd4..97a7784db4a2 100644 --- a/drivers/bluetooth/dtl1_cs.c +++ b/drivers/bluetooth/dtl1_cs.c | |||
@@ -586,29 +586,31 @@ static int dtl1_confcheck(struct pcmcia_device *p_dev, void *priv_data) | |||
586 | static int dtl1_config(struct pcmcia_device *link) | 586 | static int dtl1_config(struct pcmcia_device *link) |
587 | { | 587 | { |
588 | dtl1_info_t *info = link->priv; | 588 | dtl1_info_t *info = link->priv; |
589 | int i; | 589 | int ret; |
590 | 590 | ||
591 | /* Look for a generic full-sized window */ | 591 | /* Look for a generic full-sized window */ |
592 | link->resource[0]->end = 8; | 592 | link->resource[0]->end = 8; |
593 | if (pcmcia_loop_config(link, dtl1_confcheck, NULL) < 0) | 593 | ret = pcmcia_loop_config(link, dtl1_confcheck, NULL); |
594 | if (ret) | ||
594 | goto failed; | 595 | goto failed; |
595 | 596 | ||
596 | i = pcmcia_request_irq(link, dtl1_interrupt); | 597 | ret = pcmcia_request_irq(link, dtl1_interrupt); |
597 | if (i != 0) | 598 | if (ret) |
598 | goto failed; | 599 | goto failed; |
599 | 600 | ||
600 | i = pcmcia_enable_device(link); | 601 | ret = pcmcia_enable_device(link); |
601 | if (i != 0) | 602 | if (ret) |
602 | goto failed; | 603 | goto failed; |
603 | 604 | ||
604 | if (dtl1_open(info) != 0) | 605 | ret = dtl1_open(info); |
606 | if (ret) | ||
605 | goto failed; | 607 | goto failed; |
606 | 608 | ||
607 | return 0; | 609 | return 0; |
608 | 610 | ||
609 | failed: | 611 | failed: |
610 | dtl1_detach(link); | 612 | dtl1_detach(link); |
611 | return -ENODEV; | 613 | return ret; |
612 | } | 614 | } |
613 | 615 | ||
614 | static const struct pcmcia_device_id dtl1_ids[] = { | 616 | static const struct pcmcia_device_id dtl1_ids[] = { |
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c new file mode 100644 index 000000000000..b6154d5a07a5 --- /dev/null +++ b/drivers/bluetooth/hci_h5.c | |||
@@ -0,0 +1,747 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Bluetooth HCI Three-wire UART driver | ||
4 | * | ||
5 | * Copyright (C) 2012 Intel Corporation | ||
6 | * | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/skbuff.h> | ||
27 | |||
28 | #include <net/bluetooth/bluetooth.h> | ||
29 | #include <net/bluetooth/hci_core.h> | ||
30 | |||
31 | #include "hci_uart.h" | ||
32 | |||
33 | #define HCI_3WIRE_ACK_PKT 0 | ||
34 | #define HCI_3WIRE_LINK_PKT 15 | ||
35 | |||
36 | /* Sliding window size */ | ||
37 | #define H5_TX_WIN_MAX 4 | ||
38 | |||
39 | #define H5_ACK_TIMEOUT msecs_to_jiffies(250) | ||
40 | #define H5_SYNC_TIMEOUT msecs_to_jiffies(100) | ||
41 | |||
42 | /* | ||
43 | * Maximum Three-wire packet: | ||
44 | * 4 byte header + max value for 12-bit length + 2 bytes for CRC | ||
45 | */ | ||
46 | #define H5_MAX_LEN (4 + 0xfff + 2) | ||
47 | |||
48 | /* Convenience macros for reading Three-wire header values */ | ||
49 | #define H5_HDR_SEQ(hdr) ((hdr)[0] & 0x07) | ||
50 | #define H5_HDR_ACK(hdr) (((hdr)[0] >> 3) & 0x07) | ||
51 | #define H5_HDR_CRC(hdr) (((hdr)[0] >> 6) & 0x01) | ||
52 | #define H5_HDR_RELIABLE(hdr) (((hdr)[0] >> 7) & 0x01) | ||
53 | #define H5_HDR_PKT_TYPE(hdr) ((hdr)[1] & 0x0f) | ||
54 | #define H5_HDR_LEN(hdr) ((((hdr)[1] >> 4) & 0xff) + ((hdr)[2] << 4)) | ||
55 | |||
56 | #define SLIP_DELIMITER 0xc0 | ||
57 | #define SLIP_ESC 0xdb | ||
58 | #define SLIP_ESC_DELIM 0xdc | ||
59 | #define SLIP_ESC_ESC 0xdd | ||
60 | |||
61 | /* H5 state flags */ | ||
62 | enum { | ||
63 | H5_RX_ESC, /* SLIP escape mode */ | ||
64 | H5_TX_ACK_REQ, /* Pending ack to send */ | ||
65 | }; | ||
66 | |||
67 | struct h5 { | ||
68 | struct sk_buff_head unack; /* Unack'ed packets queue */ | ||
69 | struct sk_buff_head rel; /* Reliable packets queue */ | ||
70 | struct sk_buff_head unrel; /* Unreliable packets queue */ | ||
71 | |||
72 | unsigned long flags; | ||
73 | |||
74 | struct sk_buff *rx_skb; /* Receive buffer */ | ||
75 | size_t rx_pending; /* Expecting more bytes */ | ||
76 | u8 rx_ack; /* Last ack number received */ | ||
77 | |||
78 | int (*rx_func) (struct hci_uart *hu, u8 c); | ||
79 | |||
80 | struct timer_list timer; /* Retransmission timer */ | ||
81 | |||
82 | u8 tx_seq; /* Next seq number to send */ | ||
83 | u8 tx_ack; /* Next ack number to send */ | ||
84 | u8 tx_win; /* Sliding window size */ | ||
85 | |||
86 | enum { | ||
87 | H5_UNINITIALIZED, | ||
88 | H5_INITIALIZED, | ||
89 | H5_ACTIVE, | ||
90 | } state; | ||
91 | |||
92 | enum { | ||
93 | H5_AWAKE, | ||
94 | H5_SLEEPING, | ||
95 | H5_WAKING_UP, | ||
96 | } sleep; | ||
97 | }; | ||
98 | |||
99 | static void h5_reset_rx(struct h5 *h5); | ||
100 | |||
101 | static void h5_link_control(struct hci_uart *hu, const void *data, size_t len) | ||
102 | { | ||
103 | struct h5 *h5 = hu->priv; | ||
104 | struct sk_buff *nskb; | ||
105 | |||
106 | nskb = alloc_skb(3, GFP_ATOMIC); | ||
107 | if (!nskb) | ||
108 | return; | ||
109 | |||
110 | bt_cb(nskb)->pkt_type = HCI_3WIRE_LINK_PKT; | ||
111 | |||
112 | memcpy(skb_put(nskb, len), data, len); | ||
113 | |||
114 | skb_queue_tail(&h5->unrel, nskb); | ||
115 | } | ||
116 | |||
117 | static u8 h5_cfg_field(struct h5 *h5) | ||
118 | { | ||
119 | u8 field = 0; | ||
120 | |||
121 | /* Sliding window size (first 3 bits) */ | ||
122 | field |= (h5->tx_win & 7); | ||
123 | |||
124 | return field; | ||
125 | } | ||
126 | |||
127 | static void h5_timed_event(unsigned long arg) | ||
128 | { | ||
129 | const unsigned char sync_req[] = { 0x01, 0x7e }; | ||
130 | unsigned char conf_req[] = { 0x03, 0xfc, 0x01 }; | ||
131 | struct hci_uart *hu = (struct hci_uart *) arg; | ||
132 | struct h5 *h5 = hu->priv; | ||
133 | struct sk_buff *skb; | ||
134 | unsigned long flags; | ||
135 | |||
136 | BT_DBG("%s", hu->hdev->name); | ||
137 | |||
138 | if (h5->state == H5_UNINITIALIZED) | ||
139 | h5_link_control(hu, sync_req, sizeof(sync_req)); | ||
140 | |||
141 | if (h5->state == H5_INITIALIZED) { | ||
142 | conf_req[2] = h5_cfg_field(h5); | ||
143 | h5_link_control(hu, conf_req, sizeof(conf_req)); | ||
144 | } | ||
145 | |||
146 | if (h5->state != H5_ACTIVE) { | ||
147 | mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); | ||
148 | goto wakeup; | ||
149 | } | ||
150 | |||
151 | if (h5->sleep != H5_AWAKE) { | ||
152 | h5->sleep = H5_SLEEPING; | ||
153 | goto wakeup; | ||
154 | } | ||
155 | |||
156 | BT_DBG("hu %p retransmitting %u pkts", hu, h5->unack.qlen); | ||
157 | |||
158 | spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING); | ||
159 | |||
160 | while ((skb = __skb_dequeue_tail(&h5->unack)) != NULL) { | ||
161 | h5->tx_seq = (h5->tx_seq - 1) & 0x07; | ||
162 | skb_queue_head(&h5->rel, skb); | ||
163 | } | ||
164 | |||
165 | spin_unlock_irqrestore(&h5->unack.lock, flags); | ||
166 | |||
167 | wakeup: | ||
168 | hci_uart_tx_wakeup(hu); | ||
169 | } | ||
170 | |||
171 | static int h5_open(struct hci_uart *hu) | ||
172 | { | ||
173 | struct h5 *h5; | ||
174 | const unsigned char sync[] = { 0x01, 0x7e }; | ||
175 | |||
176 | BT_DBG("hu %p", hu); | ||
177 | |||
178 | h5 = kzalloc(sizeof(*h5), GFP_KERNEL); | ||
179 | if (!h5) | ||
180 | return -ENOMEM; | ||
181 | |||
182 | hu->priv = h5; | ||
183 | |||
184 | skb_queue_head_init(&h5->unack); | ||
185 | skb_queue_head_init(&h5->rel); | ||
186 | skb_queue_head_init(&h5->unrel); | ||
187 | |||
188 | h5_reset_rx(h5); | ||
189 | |||
190 | init_timer(&h5->timer); | ||
191 | h5->timer.function = h5_timed_event; | ||
192 | h5->timer.data = (unsigned long) hu; | ||
193 | |||
194 | h5->tx_win = H5_TX_WIN_MAX; | ||
195 | |||
196 | set_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags); | ||
197 | |||
198 | /* Send initial sync request */ | ||
199 | h5_link_control(hu, sync, sizeof(sync)); | ||
200 | mod_timer(&h5->timer, jiffies + H5_SYNC_TIMEOUT); | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int h5_close(struct hci_uart *hu) | ||
206 | { | ||
207 | struct h5 *h5 = hu->priv; | ||
208 | |||
209 | skb_queue_purge(&h5->unack); | ||
210 | skb_queue_purge(&h5->rel); | ||
211 | skb_queue_purge(&h5->unrel); | ||
212 | |||
213 | del_timer(&h5->timer); | ||
214 | |||
215 | kfree(h5); | ||
216 | |||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static void h5_pkt_cull(struct h5 *h5) | ||
221 | { | ||
222 | struct sk_buff *skb, *tmp; | ||
223 | unsigned long flags; | ||
224 | int i, to_remove; | ||
225 | u8 seq; | ||
226 | |||
227 | spin_lock_irqsave(&h5->unack.lock, flags); | ||
228 | |||
229 | to_remove = skb_queue_len(&h5->unack); | ||
230 | if (to_remove == 0) | ||
231 | goto unlock; | ||
232 | |||
233 | seq = h5->tx_seq; | ||
234 | |||
235 | while (to_remove > 0) { | ||
236 | if (h5->rx_ack == seq) | ||
237 | break; | ||
238 | |||
239 | to_remove--; | ||
240 | seq = (seq - 1) % 8; | ||
241 | } | ||
242 | |||
243 | if (seq != h5->rx_ack) | ||
244 | BT_ERR("Controller acked invalid packet"); | ||
245 | |||
246 | i = 0; | ||
247 | skb_queue_walk_safe(&h5->unack, skb, tmp) { | ||
248 | if (i++ >= to_remove) | ||
249 | break; | ||
250 | |||
251 | __skb_unlink(skb, &h5->unack); | ||
252 | kfree_skb(skb); | ||
253 | } | ||
254 | |||
255 | if (skb_queue_empty(&h5->unack)) | ||
256 | del_timer(&h5->timer); | ||
257 | |||
258 | unlock: | ||
259 | spin_unlock_irqrestore(&h5->unack.lock, flags); | ||
260 | } | ||
261 | |||
262 | static void h5_handle_internal_rx(struct hci_uart *hu) | ||
263 | { | ||
264 | struct h5 *h5 = hu->priv; | ||
265 | const unsigned char sync_req[] = { 0x01, 0x7e }; | ||
266 | const unsigned char sync_rsp[] = { 0x02, 0x7d }; | ||
267 | unsigned char conf_req[] = { 0x03, 0xfc, 0x01 }; | ||
268 | const unsigned char conf_rsp[] = { 0x04, 0x7b }; | ||
269 | const unsigned char wakeup_req[] = { 0x05, 0xfa }; | ||
270 | const unsigned char woken_req[] = { 0x06, 0xf9 }; | ||
271 | const unsigned char sleep_req[] = { 0x07, 0x78 }; | ||
272 | const unsigned char *hdr = h5->rx_skb->data; | ||
273 | const unsigned char *data = &h5->rx_skb->data[4]; | ||
274 | |||
275 | BT_DBG("%s", hu->hdev->name); | ||
276 | |||
277 | if (H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) | ||
278 | return; | ||
279 | |||
280 | if (H5_HDR_LEN(hdr) < 2) | ||
281 | return; | ||
282 | |||
283 | conf_req[2] = h5_cfg_field(h5); | ||
284 | |||
285 | if (memcmp(data, sync_req, 2) == 0) { | ||
286 | h5_link_control(hu, sync_rsp, 2); | ||
287 | } else if (memcmp(data, sync_rsp, 2) == 0) { | ||
288 | h5->state = H5_INITIALIZED; | ||
289 | h5_link_control(hu, conf_req, 3); | ||
290 | } else if (memcmp(data, conf_req, 2) == 0) { | ||
291 | h5_link_control(hu, conf_rsp, 2); | ||
292 | h5_link_control(hu, conf_req, 3); | ||
293 | } else if (memcmp(data, conf_rsp, 2) == 0) { | ||
294 | if (H5_HDR_LEN(hdr) > 2) | ||
295 | h5->tx_win = (data[2] & 7); | ||
296 | BT_DBG("Three-wire init complete. tx_win %u", h5->tx_win); | ||
297 | h5->state = H5_ACTIVE; | ||
298 | hci_uart_init_ready(hu); | ||
299 | return; | ||
300 | } else if (memcmp(data, sleep_req, 2) == 0) { | ||
301 | BT_DBG("Peer went to sleep"); | ||
302 | h5->sleep = H5_SLEEPING; | ||
303 | return; | ||
304 | } else if (memcmp(data, woken_req, 2) == 0) { | ||
305 | BT_DBG("Peer woke up"); | ||
306 | h5->sleep = H5_AWAKE; | ||
307 | } else if (memcmp(data, wakeup_req, 2) == 0) { | ||
308 | BT_DBG("Peer requested wakeup"); | ||
309 | h5_link_control(hu, woken_req, 2); | ||
310 | h5->sleep = H5_AWAKE; | ||
311 | } else { | ||
312 | BT_DBG("Link Control: 0x%02hhx 0x%02hhx", data[0], data[1]); | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | hci_uart_tx_wakeup(hu); | ||
317 | } | ||
318 | |||
319 | static void h5_complete_rx_pkt(struct hci_uart *hu) | ||
320 | { | ||
321 | struct h5 *h5 = hu->priv; | ||
322 | const unsigned char *hdr = h5->rx_skb->data; | ||
323 | |||
324 | if (H5_HDR_RELIABLE(hdr)) { | ||
325 | h5->tx_ack = (h5->tx_ack + 1) % 8; | ||
326 | set_bit(H5_TX_ACK_REQ, &h5->flags); | ||
327 | hci_uart_tx_wakeup(hu); | ||
328 | } | ||
329 | |||
330 | h5->rx_ack = H5_HDR_ACK(hdr); | ||
331 | |||
332 | h5_pkt_cull(h5); | ||
333 | |||
334 | switch (H5_HDR_PKT_TYPE(hdr)) { | ||
335 | case HCI_EVENT_PKT: | ||
336 | case HCI_ACLDATA_PKT: | ||
337 | case HCI_SCODATA_PKT: | ||
338 | bt_cb(h5->rx_skb)->pkt_type = H5_HDR_PKT_TYPE(hdr); | ||
339 | |||
340 | /* Remove Three-wire header */ | ||
341 | skb_pull(h5->rx_skb, 4); | ||
342 | |||
343 | hci_recv_frame(h5->rx_skb); | ||
344 | h5->rx_skb = NULL; | ||
345 | |||
346 | break; | ||
347 | |||
348 | default: | ||
349 | h5_handle_internal_rx(hu); | ||
350 | break; | ||
351 | } | ||
352 | |||
353 | h5_reset_rx(h5); | ||
354 | } | ||
355 | |||
356 | static int h5_rx_crc(struct hci_uart *hu, unsigned char c) | ||
357 | { | ||
358 | struct h5 *h5 = hu->priv; | ||
359 | |||
360 | h5_complete_rx_pkt(hu); | ||
361 | h5_reset_rx(h5); | ||
362 | |||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int h5_rx_payload(struct hci_uart *hu, unsigned char c) | ||
367 | { | ||
368 | struct h5 *h5 = hu->priv; | ||
369 | const unsigned char *hdr = h5->rx_skb->data; | ||
370 | |||
371 | if (H5_HDR_CRC(hdr)) { | ||
372 | h5->rx_func = h5_rx_crc; | ||
373 | h5->rx_pending = 2; | ||
374 | } else { | ||
375 | h5_complete_rx_pkt(hu); | ||
376 | h5_reset_rx(h5); | ||
377 | } | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int h5_rx_3wire_hdr(struct hci_uart *hu, unsigned char c) | ||
383 | { | ||
384 | struct h5 *h5 = hu->priv; | ||
385 | const unsigned char *hdr = h5->rx_skb->data; | ||
386 | |||
387 | BT_DBG("%s rx: seq %u ack %u crc %u rel %u type %u len %u", | ||
388 | hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr), | ||
389 | H5_HDR_CRC(hdr), H5_HDR_RELIABLE(hdr), H5_HDR_PKT_TYPE(hdr), | ||
390 | H5_HDR_LEN(hdr)); | ||
391 | |||
392 | if (((hdr[0] + hdr[1] + hdr[2] + hdr[3]) & 0xff) != 0xff) { | ||
393 | BT_ERR("Invalid header checksum"); | ||
394 | h5_reset_rx(h5); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | if (H5_HDR_RELIABLE(hdr) && H5_HDR_SEQ(hdr) != h5->tx_ack) { | ||
399 | BT_ERR("Out-of-order packet arrived (%u != %u)", | ||
400 | H5_HDR_SEQ(hdr), h5->tx_ack); | ||
401 | h5_reset_rx(h5); | ||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | if (h5->state != H5_ACTIVE && | ||
406 | H5_HDR_PKT_TYPE(hdr) != HCI_3WIRE_LINK_PKT) { | ||
407 | BT_ERR("Non-link packet received in non-active state"); | ||
408 | h5_reset_rx(h5); | ||
409 | } | ||
410 | |||
411 | h5->rx_func = h5_rx_payload; | ||
412 | h5->rx_pending = H5_HDR_LEN(hdr); | ||
413 | |||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int h5_rx_pkt_start(struct hci_uart *hu, unsigned char c) | ||
418 | { | ||
419 | struct h5 *h5 = hu->priv; | ||
420 | |||
421 | if (c == SLIP_DELIMITER) | ||
422 | return 1; | ||
423 | |||
424 | h5->rx_func = h5_rx_3wire_hdr; | ||
425 | h5->rx_pending = 4; | ||
426 | |||
427 | h5->rx_skb = bt_skb_alloc(H5_MAX_LEN, GFP_ATOMIC); | ||
428 | if (!h5->rx_skb) { | ||
429 | BT_ERR("Can't allocate mem for new packet"); | ||
430 | h5_reset_rx(h5); | ||
431 | return -ENOMEM; | ||
432 | } | ||
433 | |||
434 | h5->rx_skb->dev = (void *) hu->hdev; | ||
435 | |||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | static int h5_rx_delimiter(struct hci_uart *hu, unsigned char c) | ||
440 | { | ||
441 | struct h5 *h5 = hu->priv; | ||
442 | |||
443 | if (c == SLIP_DELIMITER) | ||
444 | h5->rx_func = h5_rx_pkt_start; | ||
445 | |||
446 | return 1; | ||
447 | } | ||
448 | |||
449 | static void h5_unslip_one_byte(struct h5 *h5, unsigned char c) | ||
450 | { | ||
451 | const u8 delim = SLIP_DELIMITER, esc = SLIP_ESC; | ||
452 | const u8 *byte = &c; | ||
453 | |||
454 | if (!test_bit(H5_RX_ESC, &h5->flags) && c == SLIP_ESC) { | ||
455 | set_bit(H5_RX_ESC, &h5->flags); | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | if (test_and_clear_bit(H5_RX_ESC, &h5->flags)) { | ||
460 | switch (c) { | ||
461 | case SLIP_ESC_DELIM: | ||
462 | byte = &delim; | ||
463 | break; | ||
464 | case SLIP_ESC_ESC: | ||
465 | byte = &esc; | ||
466 | break; | ||
467 | default: | ||
468 | BT_ERR("Invalid esc byte 0x%02hhx", c); | ||
469 | h5_reset_rx(h5); | ||
470 | return; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | memcpy(skb_put(h5->rx_skb, 1), byte, 1); | ||
475 | h5->rx_pending--; | ||
476 | |||
477 | BT_DBG("unsliped 0x%02hhx, rx_pending %zu", *byte, h5->rx_pending); | ||
478 | } | ||
479 | |||
480 | static void h5_reset_rx(struct h5 *h5) | ||
481 | { | ||
482 | if (h5->rx_skb) { | ||
483 | kfree_skb(h5->rx_skb); | ||
484 | h5->rx_skb = NULL; | ||
485 | } | ||
486 | |||
487 | h5->rx_func = h5_rx_delimiter; | ||
488 | h5->rx_pending = 0; | ||
489 | clear_bit(H5_RX_ESC, &h5->flags); | ||
490 | } | ||
491 | |||
492 | static int h5_recv(struct hci_uart *hu, void *data, int count) | ||
493 | { | ||
494 | struct h5 *h5 = hu->priv; | ||
495 | unsigned char *ptr = data; | ||
496 | |||
497 | BT_DBG("%s pending %zu count %d", hu->hdev->name, h5->rx_pending, | ||
498 | count); | ||
499 | |||
500 | while (count > 0) { | ||
501 | int processed; | ||
502 | |||
503 | if (h5->rx_pending > 0) { | ||
504 | if (*ptr == SLIP_DELIMITER) { | ||
505 | BT_ERR("Too short H5 packet"); | ||
506 | h5_reset_rx(h5); | ||
507 | continue; | ||
508 | } | ||
509 | |||
510 | h5_unslip_one_byte(h5, *ptr); | ||
511 | |||
512 | ptr++; count--; | ||
513 | continue; | ||
514 | } | ||
515 | |||
516 | processed = h5->rx_func(hu, *ptr); | ||
517 | if (processed < 0) | ||
518 | return processed; | ||
519 | |||
520 | ptr += processed; | ||
521 | count -= processed; | ||
522 | } | ||
523 | |||
524 | return 0; | ||
525 | } | ||
526 | |||
527 | static int h5_enqueue(struct hci_uart *hu, struct sk_buff *skb) | ||
528 | { | ||
529 | struct h5 *h5 = hu->priv; | ||
530 | |||
531 | if (skb->len > 0xfff) { | ||
532 | BT_ERR("Packet too long (%u bytes)", skb->len); | ||
533 | kfree_skb(skb); | ||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | if (h5->state != H5_ACTIVE) { | ||
538 | BT_ERR("Ignoring HCI data in non-active state"); | ||
539 | kfree_skb(skb); | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | switch (bt_cb(skb)->pkt_type) { | ||
544 | case HCI_ACLDATA_PKT: | ||
545 | case HCI_COMMAND_PKT: | ||
546 | skb_queue_tail(&h5->rel, skb); | ||
547 | break; | ||
548 | |||
549 | case HCI_SCODATA_PKT: | ||
550 | skb_queue_tail(&h5->unrel, skb); | ||
551 | break; | ||
552 | |||
553 | default: | ||
554 | BT_ERR("Unknown packet type %u", bt_cb(skb)->pkt_type); | ||
555 | kfree_skb(skb); | ||
556 | break; | ||
557 | } | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static void h5_slip_delim(struct sk_buff *skb) | ||
563 | { | ||
564 | const char delim = SLIP_DELIMITER; | ||
565 | |||
566 | memcpy(skb_put(skb, 1), &delim, 1); | ||
567 | } | ||
568 | |||
569 | static void h5_slip_one_byte(struct sk_buff *skb, u8 c) | ||
570 | { | ||
571 | const char esc_delim[2] = { SLIP_ESC, SLIP_ESC_DELIM }; | ||
572 | const char esc_esc[2] = { SLIP_ESC, SLIP_ESC_ESC }; | ||
573 | |||
574 | switch (c) { | ||
575 | case SLIP_DELIMITER: | ||
576 | memcpy(skb_put(skb, 2), &esc_delim, 2); | ||
577 | break; | ||
578 | case SLIP_ESC: | ||
579 | memcpy(skb_put(skb, 2), &esc_esc, 2); | ||
580 | break; | ||
581 | default: | ||
582 | memcpy(skb_put(skb, 1), &c, 1); | ||
583 | } | ||
584 | } | ||
585 | |||
586 | static bool valid_packet_type(u8 type) | ||
587 | { | ||
588 | switch (type) { | ||
589 | case HCI_ACLDATA_PKT: | ||
590 | case HCI_COMMAND_PKT: | ||
591 | case HCI_SCODATA_PKT: | ||
592 | case HCI_3WIRE_LINK_PKT: | ||
593 | case HCI_3WIRE_ACK_PKT: | ||
594 | return true; | ||
595 | default: | ||
596 | return false; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static struct sk_buff *h5_prepare_pkt(struct hci_uart *hu, u8 pkt_type, | ||
601 | const u8 *data, size_t len) | ||
602 | { | ||
603 | struct h5 *h5 = hu->priv; | ||
604 | struct sk_buff *nskb; | ||
605 | u8 hdr[4]; | ||
606 | int i; | ||
607 | |||
608 | if (!valid_packet_type(pkt_type)) { | ||
609 | BT_ERR("Unknown packet type %u", pkt_type); | ||
610 | return NULL; | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * Max len of packet: (original len + 4 (H5 hdr) + 2 (crc)) * 2 | ||
615 | * (because bytes 0xc0 and 0xdb are escaped, worst case is when | ||
616 | * the packet is all made of 0xc0 and 0xdb) + 2 (0xc0 | ||
617 | * delimiters at start and end). | ||
618 | */ | ||
619 | nskb = alloc_skb((len + 6) * 2 + 2, GFP_ATOMIC); | ||
620 | if (!nskb) | ||
621 | return NULL; | ||
622 | |||
623 | bt_cb(nskb)->pkt_type = pkt_type; | ||
624 | |||
625 | h5_slip_delim(nskb); | ||
626 | |||
627 | hdr[0] = h5->tx_ack << 3; | ||
628 | clear_bit(H5_TX_ACK_REQ, &h5->flags); | ||
629 | |||
630 | /* Reliable packet? */ | ||
631 | if (pkt_type == HCI_ACLDATA_PKT || pkt_type == HCI_COMMAND_PKT) { | ||
632 | hdr[0] |= 1 << 7; | ||
633 | hdr[0] |= h5->tx_seq; | ||
634 | h5->tx_seq = (h5->tx_seq + 1) % 8; | ||
635 | } | ||
636 | |||
637 | hdr[1] = pkt_type | ((len & 0x0f) << 4); | ||
638 | hdr[2] = len >> 4; | ||
639 | hdr[3] = ~((hdr[0] + hdr[1] + hdr[2]) & 0xff); | ||
640 | |||
641 | BT_DBG("%s tx: seq %u ack %u crc %u rel %u type %u len %u", | ||
642 | hu->hdev->name, H5_HDR_SEQ(hdr), H5_HDR_ACK(hdr), | ||
643 | H5_HDR_CRC(hdr), H5_HDR_RELIABLE(hdr), H5_HDR_PKT_TYPE(hdr), | ||
644 | H5_HDR_LEN(hdr)); | ||
645 | |||
646 | for (i = 0; i < 4; i++) | ||
647 | h5_slip_one_byte(nskb, hdr[i]); | ||
648 | |||
649 | for (i = 0; i < len; i++) | ||
650 | h5_slip_one_byte(nskb, data[i]); | ||
651 | |||
652 | h5_slip_delim(nskb); | ||
653 | |||
654 | return nskb; | ||
655 | } | ||
656 | |||
657 | static struct sk_buff *h5_dequeue(struct hci_uart *hu) | ||
658 | { | ||
659 | struct h5 *h5 = hu->priv; | ||
660 | unsigned long flags; | ||
661 | struct sk_buff *skb, *nskb; | ||
662 | |||
663 | if (h5->sleep != H5_AWAKE) { | ||
664 | const unsigned char wakeup_req[] = { 0x05, 0xfa }; | ||
665 | |||
666 | if (h5->sleep == H5_WAKING_UP) | ||
667 | return NULL; | ||
668 | |||
669 | h5->sleep = H5_WAKING_UP; | ||
670 | BT_DBG("Sending wakeup request"); | ||
671 | |||
672 | mod_timer(&h5->timer, jiffies + HZ / 100); | ||
673 | return h5_prepare_pkt(hu, HCI_3WIRE_LINK_PKT, wakeup_req, 2); | ||
674 | } | ||
675 | |||
676 | if ((skb = skb_dequeue(&h5->unrel)) != NULL) { | ||
677 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, | ||
678 | skb->data, skb->len); | ||
679 | if (nskb) { | ||
680 | kfree_skb(skb); | ||
681 | return nskb; | ||
682 | } | ||
683 | |||
684 | skb_queue_head(&h5->unrel, skb); | ||
685 | BT_ERR("Could not dequeue pkt because alloc_skb failed"); | ||
686 | } | ||
687 | |||
688 | spin_lock_irqsave_nested(&h5->unack.lock, flags, SINGLE_DEPTH_NESTING); | ||
689 | |||
690 | if (h5->unack.qlen >= h5->tx_win) | ||
691 | goto unlock; | ||
692 | |||
693 | if ((skb = skb_dequeue(&h5->rel)) != NULL) { | ||
694 | nskb = h5_prepare_pkt(hu, bt_cb(skb)->pkt_type, | ||
695 | skb->data, skb->len); | ||
696 | if (nskb) { | ||
697 | __skb_queue_tail(&h5->unack, skb); | ||
698 | mod_timer(&h5->timer, jiffies + H5_ACK_TIMEOUT); | ||
699 | spin_unlock_irqrestore(&h5->unack.lock, flags); | ||
700 | return nskb; | ||
701 | } | ||
702 | |||
703 | skb_queue_head(&h5->rel, skb); | ||
704 | BT_ERR("Could not dequeue pkt because alloc_skb failed"); | ||
705 | } | ||
706 | |||
707 | unlock: | ||
708 | spin_unlock_irqrestore(&h5->unack.lock, flags); | ||
709 | |||
710 | if (test_bit(H5_TX_ACK_REQ, &h5->flags)) | ||
711 | return h5_prepare_pkt(hu, HCI_3WIRE_ACK_PKT, NULL, 0); | ||
712 | |||
713 | return NULL; | ||
714 | } | ||
715 | |||
716 | static int h5_flush(struct hci_uart *hu) | ||
717 | { | ||
718 | BT_DBG("hu %p", hu); | ||
719 | return 0; | ||
720 | } | ||
721 | |||
722 | static struct hci_uart_proto h5p = { | ||
723 | .id = HCI_UART_3WIRE, | ||
724 | .open = h5_open, | ||
725 | .close = h5_close, | ||
726 | .recv = h5_recv, | ||
727 | .enqueue = h5_enqueue, | ||
728 | .dequeue = h5_dequeue, | ||
729 | .flush = h5_flush, | ||
730 | }; | ||
731 | |||
732 | int __init h5_init(void) | ||
733 | { | ||
734 | int err = hci_uart_register_proto(&h5p); | ||
735 | |||
736 | if (!err) | ||
737 | BT_INFO("HCI Three-wire UART (H5) protocol initialized"); | ||
738 | else | ||
739 | BT_ERR("HCI Three-wire UART (H5) protocol init failed"); | ||
740 | |||
741 | return err; | ||
742 | } | ||
743 | |||
744 | int __exit h5_deinit(void) | ||
745 | { | ||
746 | return hci_uart_unregister_proto(&h5p); | ||
747 | } | ||
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 2f9b796e106e..74e0966b3ead 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -156,6 +156,35 @@ restart: | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static void hci_uart_init_work(struct work_struct *work) | ||
160 | { | ||
161 | struct hci_uart *hu = container_of(work, struct hci_uart, init_ready); | ||
162 | int err; | ||
163 | |||
164 | if (!test_and_clear_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) | ||
165 | return; | ||
166 | |||
167 | err = hci_register_dev(hu->hdev); | ||
168 | if (err < 0) { | ||
169 | BT_ERR("Can't register HCI device"); | ||
170 | hci_free_dev(hu->hdev); | ||
171 | hu->hdev = NULL; | ||
172 | hu->proto->close(hu); | ||
173 | } | ||
174 | |||
175 | set_bit(HCI_UART_REGISTERED, &hu->flags); | ||
176 | } | ||
177 | |||
178 | int hci_uart_init_ready(struct hci_uart *hu) | ||
179 | { | ||
180 | if (!test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) | ||
181 | return -EALREADY; | ||
182 | |||
183 | schedule_work(&hu->init_ready); | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
159 | /* ------- Interface to HCI layer ------ */ | 188 | /* ------- Interface to HCI layer ------ */ |
160 | /* Initialize device */ | 189 | /* Initialize device */ |
161 | static int hci_uart_open(struct hci_dev *hdev) | 190 | static int hci_uart_open(struct hci_dev *hdev) |
@@ -264,6 +293,8 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
264 | hu->tty = tty; | 293 | hu->tty = tty; |
265 | tty->receive_room = 65536; | 294 | tty->receive_room = 65536; |
266 | 295 | ||
296 | INIT_WORK(&hu->init_ready, hci_uart_init_work); | ||
297 | |||
267 | spin_lock_init(&hu->rx_lock); | 298 | spin_lock_init(&hu->rx_lock); |
268 | 299 | ||
269 | /* Flush any pending characters in the driver and line discipline. */ | 300 | /* Flush any pending characters in the driver and line discipline. */ |
@@ -286,28 +317,30 @@ static int hci_uart_tty_open(struct tty_struct *tty) | |||
286 | static void hci_uart_tty_close(struct tty_struct *tty) | 317 | static void hci_uart_tty_close(struct tty_struct *tty) |
287 | { | 318 | { |
288 | struct hci_uart *hu = (void *)tty->disc_data; | 319 | struct hci_uart *hu = (void *)tty->disc_data; |
320 | struct hci_dev *hdev; | ||
289 | 321 | ||
290 | BT_DBG("tty %p", tty); | 322 | BT_DBG("tty %p", tty); |
291 | 323 | ||
292 | /* Detach from the tty */ | 324 | /* Detach from the tty */ |
293 | tty->disc_data = NULL; | 325 | tty->disc_data = NULL; |
294 | 326 | ||
295 | if (hu) { | 327 | if (!hu) |
296 | struct hci_dev *hdev = hu->hdev; | 328 | return; |
297 | 329 | ||
298 | if (hdev) | 330 | hdev = hu->hdev; |
299 | hci_uart_close(hdev); | 331 | if (hdev) |
332 | hci_uart_close(hdev); | ||
300 | 333 | ||
301 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { | 334 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { |
302 | if (hdev) { | 335 | if (hdev) { |
336 | if (test_bit(HCI_UART_REGISTERED, &hu->flags)) | ||
303 | hci_unregister_dev(hdev); | 337 | hci_unregister_dev(hdev); |
304 | hci_free_dev(hdev); | 338 | hci_free_dev(hdev); |
305 | } | ||
306 | hu->proto->close(hu); | ||
307 | } | 339 | } |
308 | 340 | hu->proto->close(hu); | |
309 | kfree(hu); | ||
310 | } | 341 | } |
342 | |||
343 | kfree(hu); | ||
311 | } | 344 | } |
312 | 345 | ||
313 | /* hci_uart_tty_wakeup() | 346 | /* hci_uart_tty_wakeup() |
@@ -401,12 +434,17 @@ static int hci_uart_register_dev(struct hci_uart *hu) | |||
401 | else | 434 | else |
402 | hdev->dev_type = HCI_BREDR; | 435 | hdev->dev_type = HCI_BREDR; |
403 | 436 | ||
437 | if (test_bit(HCI_UART_INIT_PENDING, &hu->hdev_flags)) | ||
438 | return 0; | ||
439 | |||
404 | if (hci_register_dev(hdev) < 0) { | 440 | if (hci_register_dev(hdev) < 0) { |
405 | BT_ERR("Can't register HCI device"); | 441 | BT_ERR("Can't register HCI device"); |
406 | hci_free_dev(hdev); | 442 | hci_free_dev(hdev); |
407 | return -ENODEV; | 443 | return -ENODEV; |
408 | } | 444 | } |
409 | 445 | ||
446 | set_bit(HCI_UART_REGISTERED, &hu->flags); | ||
447 | |||
410 | return 0; | 448 | return 0; |
411 | } | 449 | } |
412 | 450 | ||
@@ -558,6 +596,9 @@ static int __init hci_uart_init(void) | |||
558 | #ifdef CONFIG_BT_HCIUART_ATH3K | 596 | #ifdef CONFIG_BT_HCIUART_ATH3K |
559 | ath_init(); | 597 | ath_init(); |
560 | #endif | 598 | #endif |
599 | #ifdef CONFIG_BT_HCIUART_3WIRE | ||
600 | h5_init(); | ||
601 | #endif | ||
561 | 602 | ||
562 | return 0; | 603 | return 0; |
563 | } | 604 | } |
@@ -578,6 +619,9 @@ static void __exit hci_uart_exit(void) | |||
578 | #ifdef CONFIG_BT_HCIUART_ATH3K | 619 | #ifdef CONFIG_BT_HCIUART_ATH3K |
579 | ath_deinit(); | 620 | ath_deinit(); |
580 | #endif | 621 | #endif |
622 | #ifdef CONFIG_BT_HCIUART_3WIRE | ||
623 | h5_deinit(); | ||
624 | #endif | ||
581 | 625 | ||
582 | /* Release tty registration of line discipline */ | 626 | /* Release tty registration of line discipline */ |
583 | if ((err = tty_unregister_ldisc(N_HCI))) | 627 | if ((err = tty_unregister_ldisc(N_HCI))) |
diff --git a/drivers/bluetooth/hci_uart.h b/drivers/bluetooth/hci_uart.h index 6cf6ab22ad21..fffa61ff5cb1 100644 --- a/drivers/bluetooth/hci_uart.h +++ b/drivers/bluetooth/hci_uart.h | |||
@@ -47,6 +47,7 @@ | |||
47 | #define HCI_UART_RAW_DEVICE 0 | 47 | #define HCI_UART_RAW_DEVICE 0 |
48 | #define HCI_UART_RESET_ON_INIT 1 | 48 | #define HCI_UART_RESET_ON_INIT 1 |
49 | #define HCI_UART_CREATE_AMP 2 | 49 | #define HCI_UART_CREATE_AMP 2 |
50 | #define HCI_UART_INIT_PENDING 3 | ||
50 | 51 | ||
51 | struct hci_uart; | 52 | struct hci_uart; |
52 | 53 | ||
@@ -66,6 +67,8 @@ struct hci_uart { | |||
66 | unsigned long flags; | 67 | unsigned long flags; |
67 | unsigned long hdev_flags; | 68 | unsigned long hdev_flags; |
68 | 69 | ||
70 | struct work_struct init_ready; | ||
71 | |||
69 | struct hci_uart_proto *proto; | 72 | struct hci_uart_proto *proto; |
70 | void *priv; | 73 | void *priv; |
71 | 74 | ||
@@ -76,6 +79,7 @@ struct hci_uart { | |||
76 | 79 | ||
77 | /* HCI_UART proto flag bits */ | 80 | /* HCI_UART proto flag bits */ |
78 | #define HCI_UART_PROTO_SET 0 | 81 | #define HCI_UART_PROTO_SET 0 |
82 | #define HCI_UART_REGISTERED 1 | ||
79 | 83 | ||
80 | /* TX states */ | 84 | /* TX states */ |
81 | #define HCI_UART_SENDING 1 | 85 | #define HCI_UART_SENDING 1 |
@@ -84,6 +88,7 @@ struct hci_uart { | |||
84 | int hci_uart_register_proto(struct hci_uart_proto *p); | 88 | int hci_uart_register_proto(struct hci_uart_proto *p); |
85 | int hci_uart_unregister_proto(struct hci_uart_proto *p); | 89 | int hci_uart_unregister_proto(struct hci_uart_proto *p); |
86 | int hci_uart_tx_wakeup(struct hci_uart *hu); | 90 | int hci_uart_tx_wakeup(struct hci_uart *hu); |
91 | int hci_uart_init_ready(struct hci_uart *hu); | ||
87 | 92 | ||
88 | #ifdef CONFIG_BT_HCIUART_H4 | 93 | #ifdef CONFIG_BT_HCIUART_H4 |
89 | int h4_init(void); | 94 | int h4_init(void); |
@@ -104,3 +109,8 @@ int ll_deinit(void); | |||
104 | int ath_init(void); | 109 | int ath_init(void); |
105 | int ath_deinit(void); | 110 | int ath_deinit(void); |
106 | #endif | 111 | #endif |
112 | |||
113 | #ifdef CONFIG_BT_HCIUART_3WIRE | ||
114 | int h5_init(void); | ||
115 | int h5_deinit(void); | ||
116 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 420d69b2674c..6169fbd23ed1 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -216,6 +216,7 @@ void ath_printk(const char *level, const struct ath_common *common, | |||
216 | * used exclusively for WLAN-BT coexistence starting from | 216 | * used exclusively for WLAN-BT coexistence starting from |
217 | * AR9462. | 217 | * AR9462. |
218 | * @ATH_DBG_DFS: radar datection | 218 | * @ATH_DBG_DFS: radar datection |
219 | * @ATH_DBG_WOW: Wake on Wireless | ||
219 | * @ATH_DBG_ANY: enable all debugging | 220 | * @ATH_DBG_ANY: enable all debugging |
220 | * | 221 | * |
221 | * The debug level is used to control the amount and type of debugging output | 222 | * The debug level is used to control the amount and type of debugging output |
@@ -243,6 +244,7 @@ enum ATH_DEBUG { | |||
243 | ATH_DBG_BSTUCK = 0x00008000, | 244 | ATH_DBG_BSTUCK = 0x00008000, |
244 | ATH_DBG_MCI = 0x00010000, | 245 | ATH_DBG_MCI = 0x00010000, |
245 | ATH_DBG_DFS = 0x00020000, | 246 | ATH_DBG_DFS = 0x00020000, |
247 | ATH_DBG_WOW = 0x00040000, | ||
246 | ATH_DBG_ANY = 0xffffffff | 248 | ATH_DBG_ANY = 0xffffffff |
247 | }; | 249 | }; |
248 | 250 | ||
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 22b80af0f47c..260e7dc7f751 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -594,7 +594,7 @@ ath5k_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, | |||
594 | qi.tqi_aifs = params->aifs; | 594 | qi.tqi_aifs = params->aifs; |
595 | qi.tqi_cw_min = params->cw_min; | 595 | qi.tqi_cw_min = params->cw_min; |
596 | qi.tqi_cw_max = params->cw_max; | 596 | qi.tqi_cw_max = params->cw_max; |
597 | qi.tqi_burst_time = params->txop; | 597 | qi.tqi_burst_time = params->txop * 32; |
598 | 598 | ||
599 | ATH5K_DBG(ah, ATH5K_DEBUG_ANY, | 599 | ATH5K_DBG(ah, ATH5K_DEBUG_ANY, |
600 | "Configure tx [queue %d], " | 600 | "Configure tx [queue %d], " |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index aca1d2689e90..86aeef4b9d7e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c | |||
@@ -966,11 +966,11 @@ static int ath6kl_set_probed_ssids(struct ath6kl *ar, | |||
966 | return 0; | 966 | return 0; |
967 | } | 967 | } |
968 | 968 | ||
969 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | 969 | static int ath6kl_cfg80211_scan(struct wiphy *wiphy, |
970 | struct cfg80211_scan_request *request) | 970 | struct cfg80211_scan_request *request) |
971 | { | 971 | { |
972 | struct ath6kl *ar = ath6kl_priv(ndev); | 972 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev); |
973 | struct ath6kl_vif *vif = netdev_priv(ndev); | 973 | struct ath6kl *ar = ath6kl_priv(vif->ndev); |
974 | s8 n_channels = 0; | 974 | s8 n_channels = 0; |
975 | u16 *channels = NULL; | 975 | u16 *channels = NULL; |
976 | int ret = 0; | 976 | int ret = 0; |
@@ -1487,14 +1487,14 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
1487 | return 0; | 1487 | return 0; |
1488 | } | 1488 | } |
1489 | 1489 | ||
1490 | static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | 1490 | static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, |
1491 | char *name, | 1491 | char *name, |
1492 | enum nl80211_iftype type, | 1492 | enum nl80211_iftype type, |
1493 | u32 *flags, | 1493 | u32 *flags, |
1494 | struct vif_params *params) | 1494 | struct vif_params *params) |
1495 | { | 1495 | { |
1496 | struct ath6kl *ar = wiphy_priv(wiphy); | 1496 | struct ath6kl *ar = wiphy_priv(wiphy); |
1497 | struct net_device *ndev; | 1497 | struct wireless_dev *wdev; |
1498 | u8 if_idx, nw_type; | 1498 | u8 if_idx, nw_type; |
1499 | 1499 | ||
1500 | if (ar->num_vif == ar->vif_max) { | 1500 | if (ar->num_vif == ar->vif_max) { |
@@ -1507,20 +1507,20 @@ static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, | |||
1507 | return ERR_PTR(-EINVAL); | 1507 | return ERR_PTR(-EINVAL); |
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); | 1510 | wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type); |
1511 | if (!ndev) | 1511 | if (!wdev) |
1512 | return ERR_PTR(-ENOMEM); | 1512 | return ERR_PTR(-ENOMEM); |
1513 | 1513 | ||
1514 | ar->num_vif++; | 1514 | ar->num_vif++; |
1515 | 1515 | ||
1516 | return ndev; | 1516 | return wdev; |
1517 | } | 1517 | } |
1518 | 1518 | ||
1519 | static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, | 1519 | static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, |
1520 | struct net_device *ndev) | 1520 | struct wireless_dev *wdev) |
1521 | { | 1521 | { |
1522 | struct ath6kl *ar = wiphy_priv(wiphy); | 1522 | struct ath6kl *ar = wiphy_priv(wiphy); |
1523 | struct ath6kl_vif *vif = netdev_priv(ndev); | 1523 | struct ath6kl_vif *vif = netdev_priv(wdev->netdev); |
1524 | 1524 | ||
1525 | spin_lock_bh(&ar->list_lock); | 1525 | spin_lock_bh(&ar->list_lock); |
1526 | list_del(&vif->list); | 1526 | list_del(&vif->list); |
@@ -2975,14 +2975,14 @@ static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, | |||
2975 | } | 2975 | } |
2976 | 2976 | ||
2977 | static int ath6kl_remain_on_channel(struct wiphy *wiphy, | 2977 | static int ath6kl_remain_on_channel(struct wiphy *wiphy, |
2978 | struct net_device *dev, | 2978 | struct wireless_dev *wdev, |
2979 | struct ieee80211_channel *chan, | 2979 | struct ieee80211_channel *chan, |
2980 | enum nl80211_channel_type channel_type, | 2980 | enum nl80211_channel_type channel_type, |
2981 | unsigned int duration, | 2981 | unsigned int duration, |
2982 | u64 *cookie) | 2982 | u64 *cookie) |
2983 | { | 2983 | { |
2984 | struct ath6kl *ar = ath6kl_priv(dev); | 2984 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); |
2985 | struct ath6kl_vif *vif = netdev_priv(dev); | 2985 | struct ath6kl *ar = ath6kl_priv(vif->ndev); |
2986 | u32 id; | 2986 | u32 id; |
2987 | 2987 | ||
2988 | /* TODO: if already pending or ongoing remain-on-channel, | 2988 | /* TODO: if already pending or ongoing remain-on-channel, |
@@ -2999,11 +2999,11 @@ static int ath6kl_remain_on_channel(struct wiphy *wiphy, | |||
2999 | } | 2999 | } |
3000 | 3000 | ||
3001 | static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy, | 3001 | static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy, |
3002 | struct net_device *dev, | 3002 | struct wireless_dev *wdev, |
3003 | u64 cookie) | 3003 | u64 cookie) |
3004 | { | 3004 | { |
3005 | struct ath6kl *ar = ath6kl_priv(dev); | 3005 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); |
3006 | struct ath6kl_vif *vif = netdev_priv(dev); | 3006 | struct ath6kl *ar = ath6kl_priv(vif->ndev); |
3007 | 3007 | ||
3008 | if (cookie != vif->last_roc_id) | 3008 | if (cookie != vif->last_roc_id) |
3009 | return -ENOENT; | 3009 | return -ENOENT; |
@@ -3134,15 +3134,15 @@ static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len) | |||
3134 | return false; | 3134 | return false; |
3135 | } | 3135 | } |
3136 | 3136 | ||
3137 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | 3137 | static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
3138 | struct ieee80211_channel *chan, bool offchan, | 3138 | struct ieee80211_channel *chan, bool offchan, |
3139 | enum nl80211_channel_type channel_type, | 3139 | enum nl80211_channel_type channel_type, |
3140 | bool channel_type_valid, unsigned int wait, | 3140 | bool channel_type_valid, unsigned int wait, |
3141 | const u8 *buf, size_t len, bool no_cck, | 3141 | const u8 *buf, size_t len, bool no_cck, |
3142 | bool dont_wait_for_ack, u64 *cookie) | 3142 | bool dont_wait_for_ack, u64 *cookie) |
3143 | { | 3143 | { |
3144 | struct ath6kl *ar = ath6kl_priv(dev); | 3144 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); |
3145 | struct ath6kl_vif *vif = netdev_priv(dev); | 3145 | struct ath6kl *ar = ath6kl_priv(vif->ndev); |
3146 | u32 id; | 3146 | u32 id; |
3147 | const struct ieee80211_mgmt *mgmt; | 3147 | const struct ieee80211_mgmt *mgmt; |
3148 | bool more_data, queued; | 3148 | bool more_data, queued; |
@@ -3187,10 +3187,10 @@ static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
3187 | } | 3187 | } |
3188 | 3188 | ||
3189 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, | 3189 | static void ath6kl_mgmt_frame_register(struct wiphy *wiphy, |
3190 | struct net_device *dev, | 3190 | struct wireless_dev *wdev, |
3191 | u16 frame_type, bool reg) | 3191 | u16 frame_type, bool reg) |
3192 | { | 3192 | { |
3193 | struct ath6kl_vif *vif = netdev_priv(dev); | 3193 | struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev); |
3194 | 3194 | ||
3195 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n", | 3195 | ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n", |
3196 | __func__, frame_type, reg); | 3196 | __func__, frame_type, reg); |
@@ -3477,9 +3477,9 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) | |||
3477 | ar->num_vif--; | 3477 | ar->num_vif--; |
3478 | } | 3478 | } |
3479 | 3479 | ||
3480 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 3480 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, |
3481 | enum nl80211_iftype type, u8 fw_vif_idx, | 3481 | enum nl80211_iftype type, |
3482 | u8 nw_type) | 3482 | u8 fw_vif_idx, u8 nw_type) |
3483 | { | 3483 | { |
3484 | struct net_device *ndev; | 3484 | struct net_device *ndev; |
3485 | struct ath6kl_vif *vif; | 3485 | struct ath6kl_vif *vif; |
@@ -3533,7 +3533,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | |||
3533 | list_add_tail(&vif->list, &ar->vif_list); | 3533 | list_add_tail(&vif->list, &ar->vif_list); |
3534 | spin_unlock_bh(&ar->list_lock); | 3534 | spin_unlock_bh(&ar->list_lock); |
3535 | 3535 | ||
3536 | return ndev; | 3536 | return &vif->wdev; |
3537 | 3537 | ||
3538 | err: | 3538 | err: |
3539 | aggr_module_destroy(vif->aggr_cntxt); | 3539 | aggr_module_destroy(vif->aggr_cntxt); |
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index b992046a1b0e..56b1ebe79812 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h | |||
@@ -25,9 +25,9 @@ enum ath6kl_cfg_suspend_mode { | |||
25 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, | 25 | ATH6KL_CFG_SUSPEND_SCHED_SCAN, |
26 | }; | 26 | }; |
27 | 27 | ||
28 | struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, | 28 | struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, |
29 | enum nl80211_iftype type, | 29 | enum nl80211_iftype type, |
30 | u8 fw_vif_idx, u8 nw_type); | 30 | u8 fw_vif_idx, u8 nw_type); |
31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, | 31 | void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, |
32 | enum wmi_phy_mode mode); | 32 | enum wmi_phy_mode mode); |
33 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); | 33 | void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); |
diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index fdb3b1decc76..82c4dd2a960e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c | |||
@@ -56,7 +56,7 @@ EXPORT_SYMBOL(ath6kl_core_rx_complete); | |||
56 | int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | 56 | int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) |
57 | { | 57 | { |
58 | struct ath6kl_bmi_target_info targ_info; | 58 | struct ath6kl_bmi_target_info targ_info; |
59 | struct net_device *ndev; | 59 | struct wireless_dev *wdev; |
60 | int ret = 0, i; | 60 | int ret = 0, i; |
61 | 61 | ||
62 | switch (htc_type) { | 62 | switch (htc_type) { |
@@ -187,12 +187,12 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
187 | rtnl_lock(); | 187 | rtnl_lock(); |
188 | 188 | ||
189 | /* Add an initial station interface */ | 189 | /* Add an initial station interface */ |
190 | ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, | 190 | wdev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, |
191 | INFRA_NETWORK); | 191 | INFRA_NETWORK); |
192 | 192 | ||
193 | rtnl_unlock(); | 193 | rtnl_unlock(); |
194 | 194 | ||
195 | if (!ndev) { | 195 | if (!wdev) { |
196 | ath6kl_err("Failed to instantiate a network device\n"); | 196 | ath6kl_err("Failed to instantiate a network device\n"); |
197 | ret = -ENOMEM; | 197 | ret = -ENOMEM; |
198 | wiphy_unregister(ar->wiphy); | 198 | wiphy_unregister(ar->wiphy); |
@@ -200,7 +200,7 @@ int ath6kl_core_init(struct ath6kl *ar, enum ath6kl_htc_type htc_type) | |||
200 | } | 200 | } |
201 | 201 | ||
202 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", | 202 | ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", |
203 | __func__, ndev->name, ndev, ar); | 203 | __func__, wdev->netdev->name, wdev->netdev, ar); |
204 | 204 | ||
205 | return ret; | 205 | return ret; |
206 | 206 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index d38a31de344c..cec49a31029a 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h | |||
@@ -589,6 +589,11 @@ struct ath6kl_vif { | |||
589 | struct list_head mc_filter; | 589 | struct list_head mc_filter; |
590 | }; | 590 | }; |
591 | 591 | ||
592 | static inline struct ath6kl_vif *ath6kl_vif_from_wdev(struct wireless_dev *wdev) | ||
593 | { | ||
594 | return container_of(wdev, struct ath6kl_vif, wdev); | ||
595 | } | ||
596 | |||
592 | #define WOW_LIST_ID 0 | 597 | #define WOW_LIST_ID 0 |
593 | #define WOW_HOST_REQ_DELAY 500 /* ms */ | 598 | #define WOW_HOST_REQ_DELAY 500 /* ms */ |
594 | 599 | ||
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index a6caa673e8ad..c30ab4b11d61 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -474,7 +474,7 @@ static int ath6kl_wmi_remain_on_chnl_event_rx(struct wmi *wmi, u8 *datap, | |||
474 | return -EINVAL; | 474 | return -EINVAL; |
475 | } | 475 | } |
476 | id = vif->last_roc_id; | 476 | id = vif->last_roc_id; |
477 | cfg80211_ready_on_channel(vif->ndev, id, chan, NL80211_CHAN_NO_HT, | 477 | cfg80211_ready_on_channel(&vif->wdev, id, chan, NL80211_CHAN_NO_HT, |
478 | dur, GFP_ATOMIC); | 478 | dur, GFP_ATOMIC); |
479 | 479 | ||
480 | return 0; | 480 | return 0; |
@@ -513,7 +513,7 @@ static int ath6kl_wmi_cancel_remain_on_chnl_event_rx(struct wmi *wmi, | |||
513 | else | 513 | else |
514 | id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ | 514 | id = vif->last_roc_id; /* timeout on uncanceled r-o-c */ |
515 | vif->last_cancel_roc_id = 0; | 515 | vif->last_cancel_roc_id = 0; |
516 | cfg80211_remain_on_channel_expired(vif->ndev, id, chan, | 516 | cfg80211_remain_on_channel_expired(&vif->wdev, id, chan, |
517 | NL80211_CHAN_NO_HT, GFP_ATOMIC); | 517 | NL80211_CHAN_NO_HT, GFP_ATOMIC); |
518 | 518 | ||
519 | return 0; | 519 | return 0; |
@@ -533,7 +533,7 @@ static int ath6kl_wmi_tx_status_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
533 | ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n", | 533 | ath6kl_dbg(ATH6KL_DBG_WMI, "tx_status: id=%x ack_status=%u\n", |
534 | id, ev->ack_status); | 534 | id, ev->ack_status); |
535 | if (wmi->last_mgmt_tx_frame) { | 535 | if (wmi->last_mgmt_tx_frame) { |
536 | cfg80211_mgmt_tx_status(vif->ndev, id, | 536 | cfg80211_mgmt_tx_status(&vif->wdev, id, |
537 | wmi->last_mgmt_tx_frame, | 537 | wmi->last_mgmt_tx_frame, |
538 | wmi->last_mgmt_tx_frame_len, | 538 | wmi->last_mgmt_tx_frame_len, |
539 | !!ev->ack_status, GFP_ATOMIC); | 539 | !!ev->ack_status, GFP_ATOMIC); |
@@ -568,7 +568,7 @@ static int ath6kl_wmi_rx_probe_req_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
568 | dlen, freq, vif->probe_req_report); | 568 | dlen, freq, vif->probe_req_report); |
569 | 569 | ||
570 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) | 570 | if (vif->probe_req_report || vif->nw_type == AP_NETWORK) |
571 | cfg80211_rx_mgmt(vif->ndev, freq, 0, | 571 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, |
572 | ev->data, dlen, GFP_ATOMIC); | 572 | ev->data, dlen, GFP_ATOMIC); |
573 | 573 | ||
574 | return 0; | 574 | return 0; |
@@ -608,7 +608,7 @@ static int ath6kl_wmi_rx_action_event_rx(struct wmi *wmi, u8 *datap, int len, | |||
608 | return -EINVAL; | 608 | return -EINVAL; |
609 | } | 609 | } |
610 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); | 610 | ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); |
611 | cfg80211_rx_mgmt(vif->ndev, freq, 0, | 611 | cfg80211_rx_mgmt(&vif->wdev, freq, 0, |
612 | ev->data, dlen, GFP_ATOMIC); | 612 | ev->data, dlen, GFP_ATOMIC); |
613 | 613 | ||
614 | return 0; | 614 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index e507e78398f3..c7aa6646123e 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -64,7 +64,7 @@ config ATH9K_DEBUGFS | |||
64 | 64 | ||
65 | config ATH9K_DFS_CERTIFIED | 65 | config ATH9K_DFS_CERTIFIED |
66 | bool "Atheros DFS support for certified platforms" | 66 | bool "Atheros DFS support for certified platforms" |
67 | depends on ATH9K && EXPERT | 67 | depends on ATH9K && CFG80211_CERTIFICATION_ONUS |
68 | default n | 68 | default n |
69 | ---help--- | 69 | ---help--- |
70 | This option enables DFS support for initiating radiation on | 70 | This option enables DFS support for initiating radiation on |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 9c41232b0cd0..2ad8f9474ba1 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -17,6 +17,7 @@ ath9k-$(CONFIG_ATH9K_DFS_CERTIFIED) += \ | |||
17 | dfs.o \ | 17 | dfs.o \ |
18 | dfs_pattern_detector.o \ | 18 | dfs_pattern_detector.o \ |
19 | dfs_pri_detector.o | 19 | dfs_pri_detector.o |
20 | ath9k-$(CONFIG_PM_SLEEP) += wow.o | ||
20 | 21 | ||
21 | obj-$(CONFIG_ATH9K) += ath9k.o | 22 | obj-$(CONFIG_ATH9K) += ath9k.o |
22 | 23 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c index edf21ea4fe93..648da3e885e9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -26,101 +26,74 @@ | |||
26 | static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | 26 | static void ar9002_hw_init_mode_regs(struct ath_hw *ah) |
27 | { | 27 | { |
28 | if (AR_SREV_9271(ah)) { | 28 | if (AR_SREV_9271(ah)) { |
29 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, | 29 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271); |
30 | ARRAY_SIZE(ar9271Modes_9271), 5); | 30 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271); |
31 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, | 31 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg); |
32 | ARRAY_SIZE(ar9271Common_9271), 2); | ||
33 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, | ||
34 | ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 5); | ||
35 | return; | 32 | return; |
36 | } | 33 | } |
37 | 34 | ||
38 | if (ah->config.pcie_clock_req) | 35 | if (ah->config.pcie_clock_req) |
39 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 36 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
40 | ar9280PciePhy_clkreq_off_L1_9280, | 37 | ar9280PciePhy_clkreq_off_L1_9280); |
41 | ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2); | ||
42 | else | 38 | else |
43 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 39 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
44 | ar9280PciePhy_clkreq_always_on_L1_9280, | 40 | ar9280PciePhy_clkreq_always_on_L1_9280); |
45 | ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); | 41 | #ifdef CONFIG_PM_SLEEP |
42 | INIT_INI_ARRAY(&ah->iniPcieSerdesWow, | ||
43 | ar9280PciePhy_awow); | ||
44 | #endif | ||
46 | 45 | ||
47 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 46 | if (AR_SREV_9287_11_OR_LATER(ah)) { |
48 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, | 47 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1); |
49 | ARRAY_SIZE(ar9287Modes_9287_1_1), 5); | 48 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1); |
50 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, | ||
51 | ARRAY_SIZE(ar9287Common_9287_1_1), 2); | ||
52 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | 49 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { |
53 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, | 50 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2); |
54 | ARRAY_SIZE(ar9285Modes_9285_1_2), 5); | 51 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2); |
55 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, | ||
56 | ARRAY_SIZE(ar9285Common_9285_1_2), 2); | ||
57 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | 52 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { |
58 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, | 53 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2); |
59 | ARRAY_SIZE(ar9280Modes_9280_2), 5); | 54 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2); |
60 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, | ||
61 | ARRAY_SIZE(ar9280Common_9280_2), 2); | ||
62 | 55 | ||
63 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 56 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
64 | ar9280Modes_fast_clock_9280_2, | 57 | ar9280Modes_fast_clock_9280_2); |
65 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); | ||
66 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | 58 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { |
67 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, | 59 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160); |
68 | ARRAY_SIZE(ar5416Modes_9160), 5); | 60 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160); |
69 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, | ||
70 | ARRAY_SIZE(ar5416Common_9160), 2); | ||
71 | if (AR_SREV_9160_11(ah)) { | 61 | if (AR_SREV_9160_11(ah)) { |
72 | INIT_INI_ARRAY(&ah->iniAddac, | 62 | INIT_INI_ARRAY(&ah->iniAddac, |
73 | ar5416Addac_9160_1_1, | 63 | ar5416Addac_9160_1_1); |
74 | ARRAY_SIZE(ar5416Addac_9160_1_1), 2); | ||
75 | } else { | 64 | } else { |
76 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, | 65 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160); |
77 | ARRAY_SIZE(ar5416Addac_9160), 2); | ||
78 | } | 66 | } |
79 | } else if (AR_SREV_9100_OR_LATER(ah)) { | 67 | } else if (AR_SREV_9100_OR_LATER(ah)) { |
80 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, | 68 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100); |
81 | ARRAY_SIZE(ar5416Modes_9100), 5); | 69 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100); |
82 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, | 70 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100); |
83 | ARRAY_SIZE(ar5416Common_9100), 2); | 71 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100); |
84 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, | ||
85 | ARRAY_SIZE(ar5416Bank6_9100), 3); | ||
86 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, | ||
87 | ARRAY_SIZE(ar5416Addac_9100), 2); | ||
88 | } else { | 72 | } else { |
89 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, | 73 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes); |
90 | ARRAY_SIZE(ar5416Modes), 5); | 74 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common); |
91 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, | 75 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC); |
92 | ARRAY_SIZE(ar5416Common), 2); | 76 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac); |
93 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, | ||
94 | ARRAY_SIZE(ar5416Bank6TPC), 3); | ||
95 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, | ||
96 | ARRAY_SIZE(ar5416Addac), 2); | ||
97 | } | 77 | } |
98 | 78 | ||
99 | if (!AR_SREV_9280_20_OR_LATER(ah)) { | 79 | if (!AR_SREV_9280_20_OR_LATER(ah)) { |
100 | /* Common for AR5416, AR913x, AR9160 */ | 80 | /* Common for AR5416, AR913x, AR9160 */ |
101 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, | 81 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain); |
102 | ARRAY_SIZE(ar5416BB_RfGain), 3); | 82 | |
103 | 83 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0); | |
104 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, | 84 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1); |
105 | ARRAY_SIZE(ar5416Bank0), 2); | 85 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2); |
106 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, | 86 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3); |
107 | ARRAY_SIZE(ar5416Bank1), 2); | 87 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7); |
108 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, | ||
109 | ARRAY_SIZE(ar5416Bank2), 2); | ||
110 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, | ||
111 | ARRAY_SIZE(ar5416Bank3), 3); | ||
112 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, | ||
113 | ARRAY_SIZE(ar5416Bank7), 2); | ||
114 | 88 | ||
115 | /* Common for AR5416, AR9160 */ | 89 | /* Common for AR5416, AR9160 */ |
116 | if (!AR_SREV_9100(ah)) | 90 | if (!AR_SREV_9100(ah)) |
117 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, | 91 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6); |
118 | ARRAY_SIZE(ar5416Bank6), 3); | ||
119 | 92 | ||
120 | /* Common for AR913x, AR9160 */ | 93 | /* Common for AR913x, AR9160 */ |
121 | if (!AR_SREV_5416(ah)) | 94 | if (!AR_SREV_5416(ah)) |
122 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, | 95 | INIT_INI_ARRAY(&ah->iniBank6TPC, |
123 | ARRAY_SIZE(ar5416Bank6TPC_9100), 3); | 96 | ar5416Bank6TPC_9100); |
124 | } | 97 | } |
125 | 98 | ||
126 | /* iniAddac needs to be modified for these chips */ | 99 | /* iniAddac needs to be modified for these chips */ |
@@ -143,13 +116,9 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | |||
143 | } | 116 | } |
144 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 117 | if (AR_SREV_9287_11_OR_LATER(ah)) { |
145 | INIT_INI_ARRAY(&ah->iniCckfirNormal, | 118 | INIT_INI_ARRAY(&ah->iniCckfirNormal, |
146 | ar9287Common_normal_cck_fir_coeff_9287_1_1, | 119 | ar9287Common_normal_cck_fir_coeff_9287_1_1); |
147 | ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1), | ||
148 | 2); | ||
149 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | 120 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, |
150 | ar9287Common_japan_2484_cck_fir_coeff_9287_1_1, | 121 | ar9287Common_japan_2484_cck_fir_coeff_9287_1_1); |
151 | ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1), | ||
152 | 2); | ||
153 | } | 122 | } |
154 | } | 123 | } |
155 | 124 | ||
@@ -163,20 +132,16 @@ static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) | |||
163 | 132 | ||
164 | if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) | 133 | if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) |
165 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 134 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
166 | ar9280Modes_backoff_13db_rxgain_9280_2, | 135 | ar9280Modes_backoff_13db_rxgain_9280_2); |
167 | ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 5); | ||
168 | else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) | 136 | else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) |
169 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 137 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
170 | ar9280Modes_backoff_23db_rxgain_9280_2, | 138 | ar9280Modes_backoff_23db_rxgain_9280_2); |
171 | ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 5); | ||
172 | else | 139 | else |
173 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 140 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
174 | ar9280Modes_original_rxgain_9280_2, | 141 | ar9280Modes_original_rxgain_9280_2); |
175 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); | ||
176 | } else { | 142 | } else { |
177 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 143 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
178 | ar9280Modes_original_rxgain_9280_2, | 144 | ar9280Modes_original_rxgain_9280_2); |
179 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 5); | ||
180 | } | 145 | } |
181 | } | 146 | } |
182 | 147 | ||
@@ -186,16 +151,13 @@ static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) | |||
186 | AR5416_EEP_MINOR_VER_19) { | 151 | AR5416_EEP_MINOR_VER_19) { |
187 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | 152 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) |
188 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 153 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
189 | ar9280Modes_high_power_tx_gain_9280_2, | 154 | ar9280Modes_high_power_tx_gain_9280_2); |
190 | ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 5); | ||
191 | else | 155 | else |
192 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 156 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
193 | ar9280Modes_original_tx_gain_9280_2, | 157 | ar9280Modes_original_tx_gain_9280_2); |
194 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); | ||
195 | } else { | 158 | } else { |
196 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 159 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
197 | ar9280Modes_original_tx_gain_9280_2, | 160 | ar9280Modes_original_tx_gain_9280_2); |
198 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 5); | ||
199 | } | 161 | } |
200 | } | 162 | } |
201 | 163 | ||
@@ -203,12 +165,10 @@ static void ar9271_hw_init_txgain_ini(struct ath_hw *ah, u32 txgain_type) | |||
203 | { | 165 | { |
204 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | 166 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) |
205 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 167 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
206 | ar9271Modes_high_power_tx_gain_9271, | 168 | ar9271Modes_high_power_tx_gain_9271); |
207 | ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 5); | ||
208 | else | 169 | else |
209 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 170 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
210 | ar9271Modes_normal_power_tx_gain_9271, | 171 | ar9271Modes_normal_power_tx_gain_9271); |
211 | ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 5); | ||
212 | } | 172 | } |
213 | 173 | ||
214 | static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | 174 | static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) |
@@ -217,8 +177,7 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
217 | 177 | ||
218 | if (AR_SREV_9287_11_OR_LATER(ah)) | 178 | if (AR_SREV_9287_11_OR_LATER(ah)) |
219 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 179 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
220 | ar9287Modes_rx_gain_9287_1_1, | 180 | ar9287Modes_rx_gain_9287_1_1); |
221 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 5); | ||
222 | else if (AR_SREV_9280_20(ah)) | 181 | else if (AR_SREV_9280_20(ah)) |
223 | ar9280_20_hw_init_rxgain_ini(ah); | 182 | ar9280_20_hw_init_rxgain_ini(ah); |
224 | 183 | ||
@@ -226,8 +185,7 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
226 | ar9271_hw_init_txgain_ini(ah, txgain_type); | 185 | ar9271_hw_init_txgain_ini(ah, txgain_type); |
227 | } else if (AR_SREV_9287_11_OR_LATER(ah)) { | 186 | } else if (AR_SREV_9287_11_OR_LATER(ah)) { |
228 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 187 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
229 | ar9287Modes_tx_gain_9287_1_1, | 188 | ar9287Modes_tx_gain_9287_1_1); |
230 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 5); | ||
231 | } else if (AR_SREV_9280_20(ah)) { | 189 | } else if (AR_SREV_9280_20(ah)) { |
232 | ar9280_20_hw_init_txgain_ini(ah, txgain_type); | 190 | ar9280_20_hw_init_txgain_ini(ah, txgain_type); |
233 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | 191 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { |
@@ -235,26 +193,18 @@ static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | |||
235 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { | 193 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { |
236 | if (AR_SREV_9285E_20(ah)) { | 194 | if (AR_SREV_9285E_20(ah)) { |
237 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 195 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
238 | ar9285Modes_XE2_0_high_power, | 196 | ar9285Modes_XE2_0_high_power); |
239 | ARRAY_SIZE( | ||
240 | ar9285Modes_XE2_0_high_power), 5); | ||
241 | } else { | 197 | } else { |
242 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 198 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
243 | ar9285Modes_high_power_tx_gain_9285_1_2, | 199 | ar9285Modes_high_power_tx_gain_9285_1_2); |
244 | ARRAY_SIZE( | ||
245 | ar9285Modes_high_power_tx_gain_9285_1_2), 5); | ||
246 | } | 200 | } |
247 | } else { | 201 | } else { |
248 | if (AR_SREV_9285E_20(ah)) { | 202 | if (AR_SREV_9285E_20(ah)) { |
249 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 203 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
250 | ar9285Modes_XE2_0_normal_power, | 204 | ar9285Modes_XE2_0_normal_power); |
251 | ARRAY_SIZE( | ||
252 | ar9285Modes_XE2_0_normal_power), 5); | ||
253 | } else { | 205 | } else { |
254 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 206 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
255 | ar9285Modes_original_tx_gain_9285_1_2, | 207 | ar9285Modes_original_tx_gain_9285_1_2); |
256 | ARRAY_SIZE( | ||
257 | ar9285Modes_original_tx_gain_9285_1_2), 5); | ||
258 | } | 208 | } |
259 | } | 209 | } |
260 | } | 210 | } |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 4d18c66a6790..beb6162cf97c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h | |||
@@ -925,6 +925,20 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { | |||
925 | {0x00004044, 0x00000000}, | 925 | {0x00004044, 0x00000000}, |
926 | }; | 926 | }; |
927 | 927 | ||
928 | static const u32 ar9280PciePhy_awow[][2] = { | ||
929 | /* Addr allmodes */ | ||
930 | {0x00004040, 0x9248fd00}, | ||
931 | {0x00004040, 0x24924924}, | ||
932 | {0x00004040, 0xa8000019}, | ||
933 | {0x00004040, 0x13160820}, | ||
934 | {0x00004040, 0xe5980560}, | ||
935 | {0x00004040, 0xc01dcffd}, | ||
936 | {0x00004040, 0x1aaabe41}, | ||
937 | {0x00004040, 0xbe105554}, | ||
938 | {0x00004040, 0x00043007}, | ||
939 | {0x00004044, 0x00000000}, | ||
940 | }; | ||
941 | |||
928 | static const u32 ar9285Modes_9285_1_2[][5] = { | 942 | static const u32 ar9285Modes_9285_1_2[][5] = { |
929 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 943 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
930 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | 944 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index ab2bfcb3bed2..2588848f4a82 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -131,8 +131,9 @@ static const struct ar9300_eeprom ar9300_default = { | |||
131 | .thresh62 = 28, | 131 | .thresh62 = 28, |
132 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), | 132 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), |
133 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), | 133 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), |
134 | .xlna_bias_strength = 0, | ||
134 | .futureModal = { | 135 | .futureModal = { |
135 | 0, 0, 0, 0, 0, 0, 0, 0, | 136 | 0, 0, 0, 0, 0, 0, 0, |
136 | }, | 137 | }, |
137 | }, | 138 | }, |
138 | .base_ext1 = { | 139 | .base_ext1 = { |
@@ -331,8 +332,9 @@ static const struct ar9300_eeprom ar9300_default = { | |||
331 | .thresh62 = 28, | 332 | .thresh62 = 28, |
332 | .papdRateMaskHt20 = LE32(0x0c80c080), | 333 | .papdRateMaskHt20 = LE32(0x0c80c080), |
333 | .papdRateMaskHt40 = LE32(0x0080c080), | 334 | .papdRateMaskHt40 = LE32(0x0080c080), |
335 | .xlna_bias_strength = 0, | ||
334 | .futureModal = { | 336 | .futureModal = { |
335 | 0, 0, 0, 0, 0, 0, 0, 0, | 337 | 0, 0, 0, 0, 0, 0, 0, |
336 | }, | 338 | }, |
337 | }, | 339 | }, |
338 | .base_ext2 = { | 340 | .base_ext2 = { |
@@ -704,8 +706,9 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
704 | .thresh62 = 28, | 706 | .thresh62 = 28, |
705 | .papdRateMaskHt20 = LE32(0x0c80c080), | 707 | .papdRateMaskHt20 = LE32(0x0c80c080), |
706 | .papdRateMaskHt40 = LE32(0x0080c080), | 708 | .papdRateMaskHt40 = LE32(0x0080c080), |
709 | .xlna_bias_strength = 0, | ||
707 | .futureModal = { | 710 | .futureModal = { |
708 | 0, 0, 0, 0, 0, 0, 0, 0, | 711 | 0, 0, 0, 0, 0, 0, 0, |
709 | }, | 712 | }, |
710 | }, | 713 | }, |
711 | .base_ext1 = { | 714 | .base_ext1 = { |
@@ -904,8 +907,9 @@ static const struct ar9300_eeprom ar9300_x113 = { | |||
904 | .thresh62 = 28, | 907 | .thresh62 = 28, |
905 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), | 908 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), |
906 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), | 909 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), |
910 | .xlna_bias_strength = 0, | ||
907 | .futureModal = { | 911 | .futureModal = { |
908 | 0, 0, 0, 0, 0, 0, 0, 0, | 912 | 0, 0, 0, 0, 0, 0, 0, |
909 | }, | 913 | }, |
910 | }, | 914 | }, |
911 | .base_ext2 = { | 915 | .base_ext2 = { |
@@ -1278,8 +1282,9 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1278 | .thresh62 = 28, | 1282 | .thresh62 = 28, |
1279 | .papdRateMaskHt20 = LE32(0x0c80c080), | 1283 | .papdRateMaskHt20 = LE32(0x0c80c080), |
1280 | .papdRateMaskHt40 = LE32(0x0080c080), | 1284 | .papdRateMaskHt40 = LE32(0x0080c080), |
1285 | .xlna_bias_strength = 0, | ||
1281 | .futureModal = { | 1286 | .futureModal = { |
1282 | 0, 0, 0, 0, 0, 0, 0, 0, | 1287 | 0, 0, 0, 0, 0, 0, 0, |
1283 | }, | 1288 | }, |
1284 | }, | 1289 | }, |
1285 | .base_ext1 = { | 1290 | .base_ext1 = { |
@@ -1478,8 +1483,9 @@ static const struct ar9300_eeprom ar9300_h112 = { | |||
1478 | .thresh62 = 28, | 1483 | .thresh62 = 28, |
1479 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), | 1484 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), |
1480 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), | 1485 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), |
1486 | .xlna_bias_strength = 0, | ||
1481 | .futureModal = { | 1487 | .futureModal = { |
1482 | 0, 0, 0, 0, 0, 0, 0, 0, | 1488 | 0, 0, 0, 0, 0, 0, 0, |
1483 | }, | 1489 | }, |
1484 | }, | 1490 | }, |
1485 | .base_ext2 = { | 1491 | .base_ext2 = { |
@@ -1852,8 +1858,9 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
1852 | .thresh62 = 28, | 1858 | .thresh62 = 28, |
1853 | .papdRateMaskHt20 = LE32(0x0c80c080), | 1859 | .papdRateMaskHt20 = LE32(0x0c80c080), |
1854 | .papdRateMaskHt40 = LE32(0x0080c080), | 1860 | .papdRateMaskHt40 = LE32(0x0080c080), |
1861 | .xlna_bias_strength = 0, | ||
1855 | .futureModal = { | 1862 | .futureModal = { |
1856 | 0, 0, 0, 0, 0, 0, 0, 0, | 1863 | 0, 0, 0, 0, 0, 0, 0, |
1857 | }, | 1864 | }, |
1858 | }, | 1865 | }, |
1859 | .base_ext1 = { | 1866 | .base_ext1 = { |
@@ -2052,8 +2059,9 @@ static const struct ar9300_eeprom ar9300_x112 = { | |||
2052 | .thresh62 = 28, | 2059 | .thresh62 = 28, |
2053 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), | 2060 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), |
2054 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), | 2061 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), |
2062 | .xlna_bias_strength = 0, | ||
2055 | .futureModal = { | 2063 | .futureModal = { |
2056 | 0, 0, 0, 0, 0, 0, 0, 0, | 2064 | 0, 0, 0, 0, 0, 0, 0, |
2057 | }, | 2065 | }, |
2058 | }, | 2066 | }, |
2059 | .base_ext2 = { | 2067 | .base_ext2 = { |
@@ -2425,8 +2433,9 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2425 | .thresh62 = 28, | 2433 | .thresh62 = 28, |
2426 | .papdRateMaskHt20 = LE32(0x0c80C080), | 2434 | .papdRateMaskHt20 = LE32(0x0c80C080), |
2427 | .papdRateMaskHt40 = LE32(0x0080C080), | 2435 | .papdRateMaskHt40 = LE32(0x0080C080), |
2436 | .xlna_bias_strength = 0, | ||
2428 | .futureModal = { | 2437 | .futureModal = { |
2429 | 0, 0, 0, 0, 0, 0, 0, 0, | 2438 | 0, 0, 0, 0, 0, 0, 0, |
2430 | }, | 2439 | }, |
2431 | }, | 2440 | }, |
2432 | .base_ext1 = { | 2441 | .base_ext1 = { |
@@ -2625,8 +2634,9 @@ static const struct ar9300_eeprom ar9300_h116 = { | |||
2625 | .thresh62 = 28, | 2634 | .thresh62 = 28, |
2626 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), | 2635 | .papdRateMaskHt20 = LE32(0x0cf0e0e0), |
2627 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), | 2636 | .papdRateMaskHt40 = LE32(0x6cf0e0e0), |
2637 | .xlna_bias_strength = 0, | ||
2628 | .futureModal = { | 2638 | .futureModal = { |
2629 | 0, 0, 0, 0, 0, 0, 0, 0, | 2639 | 0, 0, 0, 0, 0, 0, 0, |
2630 | }, | 2640 | }, |
2631 | }, | 2641 | }, |
2632 | .base_ext2 = { | 2642 | .base_ext2 = { |
@@ -2971,14 +2981,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | |||
2971 | return (pBase->txrxMask >> 4) & 0xf; | 2981 | return (pBase->txrxMask >> 4) & 0xf; |
2972 | case EEP_RX_MASK: | 2982 | case EEP_RX_MASK: |
2973 | return pBase->txrxMask & 0xf; | 2983 | return pBase->txrxMask & 0xf; |
2974 | case EEP_DRIVE_STRENGTH: | ||
2975 | #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1 | ||
2976 | return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH; | ||
2977 | case EEP_INTERNAL_REGULATOR: | ||
2978 | /* Bit 4 is internal regulator flag */ | ||
2979 | return (pBase->featureEnable & 0x10) >> 4; | ||
2980 | case EEP_SWREG: | ||
2981 | return le32_to_cpu(pBase->swreg); | ||
2982 | case EEP_PAPRD: | 2984 | case EEP_PAPRD: |
2983 | return !!(pBase->featureEnable & BIT(5)); | 2985 | return !!(pBase->featureEnable & BIT(5)); |
2984 | case EEP_CHAIN_MASK_REDUCE: | 2986 | case EEP_CHAIN_MASK_REDUCE: |
@@ -2989,8 +2991,6 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | |||
2989 | return eep->modalHeader5G.antennaGain; | 2991 | return eep->modalHeader5G.antennaGain; |
2990 | case EEP_ANTENNA_GAIN_2G: | 2992 | case EEP_ANTENNA_GAIN_2G: |
2991 | return eep->modalHeader2G.antennaGain; | 2993 | return eep->modalHeader2G.antennaGain; |
2992 | case EEP_QUICK_DROP: | ||
2993 | return pBase->miscConfiguration & BIT(1); | ||
2994 | default: | 2994 | default: |
2995 | return 0; | 2995 | return 0; |
2996 | } | 2996 | } |
@@ -3260,10 +3260,20 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | |||
3260 | int it; | 3260 | int it; |
3261 | u16 checksum, mchecksum; | 3261 | u16 checksum, mchecksum; |
3262 | struct ath_common *common = ath9k_hw_common(ah); | 3262 | struct ath_common *common = ath9k_hw_common(ah); |
3263 | struct ar9300_eeprom *eep; | ||
3263 | eeprom_read_op read; | 3264 | eeprom_read_op read; |
3264 | 3265 | ||
3265 | if (ath9k_hw_use_flash(ah)) | 3266 | if (ath9k_hw_use_flash(ah)) { |
3266 | return ar9300_eeprom_restore_flash(ah, mptr, mdata_size); | 3267 | u8 txrx; |
3268 | |||
3269 | ar9300_eeprom_restore_flash(ah, mptr, mdata_size); | ||
3270 | |||
3271 | /* check if eeprom contains valid data */ | ||
3272 | eep = (struct ar9300_eeprom *) mptr; | ||
3273 | txrx = eep->baseEepHeader.txrxMask; | ||
3274 | if (txrx != 0 && txrx != 0xff) | ||
3275 | return 0; | ||
3276 | } | ||
3267 | 3277 | ||
3268 | word = kzalloc(2048, GFP_KERNEL); | 3278 | word = kzalloc(2048, GFP_KERNEL); |
3269 | if (!word) | 3279 | if (!word) |
@@ -3493,19 +3503,20 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) | |||
3493 | return 0; | 3503 | return 0; |
3494 | } | 3504 | } |
3495 | 3505 | ||
3496 | static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) | 3506 | static struct ar9300_modal_eep_header *ar9003_modal_header(struct ath_hw *ah, |
3507 | bool is2ghz) | ||
3497 | { | 3508 | { |
3498 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3509 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
3499 | 3510 | ||
3500 | if (is2ghz) | 3511 | if (is2ghz) |
3501 | return eep->modalHeader2G.xpaBiasLvl; | 3512 | return &eep->modalHeader2G; |
3502 | else | 3513 | else |
3503 | return eep->modalHeader5G.xpaBiasLvl; | 3514 | return &eep->modalHeader5G; |
3504 | } | 3515 | } |
3505 | 3516 | ||
3506 | static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | 3517 | static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) |
3507 | { | 3518 | { |
3508 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); | 3519 | int bias = ar9003_modal_header(ah, is2ghz)->xpaBiasLvl; |
3509 | 3520 | ||
3510 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) | 3521 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) |
3511 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); | 3522 | REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); |
@@ -3521,57 +3532,26 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | |||
3521 | } | 3532 | } |
3522 | } | 3533 | } |
3523 | 3534 | ||
3524 | static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is_2ghz) | 3535 | static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz) |
3525 | { | 3536 | { |
3526 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3537 | return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt); |
3527 | __le16 val; | ||
3528 | |||
3529 | if (is_2ghz) | ||
3530 | val = eep->modalHeader2G.switchcomspdt; | ||
3531 | else | ||
3532 | val = eep->modalHeader5G.switchcomspdt; | ||
3533 | return le16_to_cpu(val); | ||
3534 | } | 3538 | } |
3535 | 3539 | ||
3536 | 3540 | ||
3537 | static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) | 3541 | static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) |
3538 | { | 3542 | { |
3539 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3543 | return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon); |
3540 | __le32 val; | ||
3541 | |||
3542 | if (is2ghz) | ||
3543 | val = eep->modalHeader2G.antCtrlCommon; | ||
3544 | else | ||
3545 | val = eep->modalHeader5G.antCtrlCommon; | ||
3546 | return le32_to_cpu(val); | ||
3547 | } | 3544 | } |
3548 | 3545 | ||
3549 | static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) | 3546 | static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) |
3550 | { | 3547 | { |
3551 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3548 | return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2); |
3552 | __le32 val; | ||
3553 | |||
3554 | if (is2ghz) | ||
3555 | val = eep->modalHeader2G.antCtrlCommon2; | ||
3556 | else | ||
3557 | val = eep->modalHeader5G.antCtrlCommon2; | ||
3558 | return le32_to_cpu(val); | ||
3559 | } | 3549 | } |
3560 | 3550 | ||
3561 | static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | 3551 | static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain, |
3562 | int chain, | ||
3563 | bool is2ghz) | 3552 | bool is2ghz) |
3564 | { | 3553 | { |
3565 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3554 | __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain]; |
3566 | __le16 val = 0; | ||
3567 | |||
3568 | if (chain >= 0 && chain < AR9300_MAX_CHAINS) { | ||
3569 | if (is2ghz) | ||
3570 | val = eep->modalHeader2G.antCtrlChain[chain]; | ||
3571 | else | ||
3572 | val = eep->modalHeader5G.antCtrlChain[chain]; | ||
3573 | } | ||
3574 | |||
3575 | return le16_to_cpu(val); | 3555 | return le16_to_cpu(val); |
3576 | } | 3556 | } |
3577 | 3557 | ||
@@ -3681,11 +3661,12 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | |||
3681 | 3661 | ||
3682 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) | 3662 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) |
3683 | { | 3663 | { |
3664 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3665 | struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; | ||
3684 | int drive_strength; | 3666 | int drive_strength; |
3685 | unsigned long reg; | 3667 | unsigned long reg; |
3686 | 3668 | ||
3687 | drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH); | 3669 | drive_strength = pBase->miscConfiguration & BIT(0); |
3688 | |||
3689 | if (!drive_strength) | 3670 | if (!drive_strength) |
3690 | return; | 3671 | return; |
3691 | 3672 | ||
@@ -3815,11 +3796,11 @@ static bool is_pmu_set(struct ath_hw *ah, u32 pmu_reg, int pmu_set) | |||
3815 | 3796 | ||
3816 | void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | 3797 | void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) |
3817 | { | 3798 | { |
3818 | int internal_regulator = | 3799 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
3819 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); | 3800 | struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; |
3820 | u32 reg_val; | 3801 | u32 reg_val; |
3821 | 3802 | ||
3822 | if (internal_regulator) { | 3803 | if (pBase->featureEnable & BIT(4)) { |
3823 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { | 3804 | if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { |
3824 | int reg_pmu_set; | 3805 | int reg_pmu_set; |
3825 | 3806 | ||
@@ -3863,11 +3844,11 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | |||
3863 | if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) | 3844 | if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) |
3864 | return; | 3845 | return; |
3865 | } else if (AR_SREV_9462(ah)) { | 3846 | } else if (AR_SREV_9462(ah)) { |
3866 | reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); | 3847 | reg_val = le32_to_cpu(pBase->swreg); |
3867 | REG_WRITE(ah, AR_PHY_PMU1, reg_val); | 3848 | REG_WRITE(ah, AR_PHY_PMU1, reg_val); |
3868 | } else { | 3849 | } else { |
3869 | /* Internal regulator is ON. Write swreg register. */ | 3850 | /* Internal regulator is ON. Write swreg register. */ |
3870 | reg_val = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); | 3851 | reg_val = le32_to_cpu(pBase->swreg); |
3871 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, | 3852 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, |
3872 | REG_READ(ah, AR_RTC_REG_CONTROL1) & | 3853 | REG_READ(ah, AR_RTC_REG_CONTROL1) & |
3873 | (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); | 3854 | (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); |
@@ -3909,6 +3890,9 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) | |||
3909 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3890 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
3910 | u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; | 3891 | u8 tuning_caps_param = eep->baseEepHeader.params_for_tuning_caps[0]; |
3911 | 3892 | ||
3893 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) | ||
3894 | return; | ||
3895 | |||
3912 | if (eep->baseEepHeader.featureEnable & 0x40) { | 3896 | if (eep->baseEepHeader.featureEnable & 0x40) { |
3913 | tuning_caps_param &= 0x7f; | 3897 | tuning_caps_param &= 0x7f; |
3914 | REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC, | 3898 | REG_RMW_FIELD(ah, AR_CH0_XTAL, AR_CH0_XTAL_CAPINDAC, |
@@ -3921,10 +3905,11 @@ static void ar9003_hw_apply_tuning_caps(struct ath_hw *ah) | |||
3921 | static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) | 3905 | static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) |
3922 | { | 3906 | { |
3923 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 3907 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; |
3924 | int quick_drop = ath9k_hw_ar9300_get_eeprom(ah, EEP_QUICK_DROP); | 3908 | struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; |
3909 | int quick_drop; | ||
3925 | s32 t[3], f[3] = {5180, 5500, 5785}; | 3910 | s32 t[3], f[3] = {5180, 5500, 5785}; |
3926 | 3911 | ||
3927 | if (!quick_drop) | 3912 | if (!(pBase->miscConfiguration & BIT(1))) |
3928 | return; | 3913 | return; |
3929 | 3914 | ||
3930 | if (freq < 4000) | 3915 | if (freq < 4000) |
@@ -3938,13 +3923,11 @@ static void ar9003_hw_quick_drop_apply(struct ath_hw *ah, u16 freq) | |||
3938 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); | 3923 | REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); |
3939 | } | 3924 | } |
3940 | 3925 | ||
3941 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq) | 3926 | static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz) |
3942 | { | 3927 | { |
3943 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3944 | u32 value; | 3928 | u32 value; |
3945 | 3929 | ||
3946 | value = (freq < 4000) ? eep->modalHeader2G.txEndToXpaOff : | 3930 | value = ar9003_modal_header(ah, is2ghz)->txEndToXpaOff; |
3947 | eep->modalHeader5G.txEndToXpaOff; | ||
3948 | 3931 | ||
3949 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | 3932 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, |
3950 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); | 3933 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF, value); |
@@ -3952,19 +3935,63 @@ static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, u16 freq) | |||
3952 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); | 3935 | AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF, value); |
3953 | } | 3936 | } |
3954 | 3937 | ||
3938 | static void ar9003_hw_xpa_timing_control_apply(struct ath_hw *ah, bool is2ghz) | ||
3939 | { | ||
3940 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3941 | u8 xpa_ctl; | ||
3942 | |||
3943 | if (!(eep->baseEepHeader.featureEnable & 0x80)) | ||
3944 | return; | ||
3945 | |||
3946 | if (!AR_SREV_9300(ah) && !AR_SREV_9340(ah) && !AR_SREV_9580(ah)) | ||
3947 | return; | ||
3948 | |||
3949 | xpa_ctl = ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; | ||
3950 | if (is2ghz) | ||
3951 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3952 | AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON, xpa_ctl); | ||
3953 | else | ||
3954 | REG_RMW_FIELD(ah, AR_PHY_XPA_TIMING_CTL, | ||
3955 | AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON, xpa_ctl); | ||
3956 | } | ||
3957 | |||
3958 | static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz) | ||
3959 | { | ||
3960 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
3961 | u8 bias; | ||
3962 | |||
3963 | if (!(eep->baseEepHeader.featureEnable & 0x40)) | ||
3964 | return; | ||
3965 | |||
3966 | if (!AR_SREV_9300(ah)) | ||
3967 | return; | ||
3968 | |||
3969 | bias = ar9003_modal_header(ah, is2ghz)->xlna_bias_strength; | ||
3970 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, | ||
3971 | bias & 0x3); | ||
3972 | bias >>= 2; | ||
3973 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, | ||
3974 | bias & 0x3); | ||
3975 | bias >>= 2; | ||
3976 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, AR_PHY_65NM_RXTX4_XLNA_BIAS, | ||
3977 | bias & 0x3); | ||
3978 | } | ||
3979 | |||
3955 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | 3980 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, |
3956 | struct ath9k_channel *chan) | 3981 | struct ath9k_channel *chan) |
3957 | { | 3982 | { |
3958 | ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); | 3983 | bool is2ghz = IS_CHAN_2GHZ(chan); |
3959 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | 3984 | ar9003_hw_xpa_timing_control_apply(ah, is2ghz); |
3985 | ar9003_hw_xpa_bias_level_apply(ah, is2ghz); | ||
3986 | ar9003_hw_ant_ctrl_apply(ah, is2ghz); | ||
3960 | ar9003_hw_drive_strength_apply(ah); | 3987 | ar9003_hw_drive_strength_apply(ah); |
3988 | ar9003_hw_xlna_bias_strength_apply(ah, is2ghz); | ||
3961 | ar9003_hw_atten_apply(ah, chan); | 3989 | ar9003_hw_atten_apply(ah, chan); |
3962 | ar9003_hw_quick_drop_apply(ah, chan->channel); | 3990 | ar9003_hw_quick_drop_apply(ah, chan->channel); |
3963 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah)) | 3991 | if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9550(ah)) |
3964 | ar9003_hw_internal_regulator_apply(ah); | 3992 | ar9003_hw_internal_regulator_apply(ah); |
3965 | if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) | 3993 | ar9003_hw_apply_tuning_caps(ah); |
3966 | ar9003_hw_apply_tuning_caps(ah); | 3994 | ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); |
3967 | ar9003_hw_txend_to_xpa_off_apply(ah, chan->channel); | ||
3968 | } | 3995 | } |
3969 | 3996 | ||
3970 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, | 3997 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, |
@@ -5100,14 +5127,9 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) | |||
5100 | return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ | 5127 | return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ |
5101 | } | 5128 | } |
5102 | 5129 | ||
5103 | u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is_2ghz) | 5130 | u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz) |
5104 | { | 5131 | { |
5105 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 5132 | return ar9003_modal_header(ah, is2ghz)->spurChans; |
5106 | |||
5107 | if (is_2ghz) | ||
5108 | return eep->modalHeader2G.spurChans; | ||
5109 | else | ||
5110 | return eep->modalHeader5G.spurChans; | ||
5111 | } | 5133 | } |
5112 | 5134 | ||
5113 | unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, | 5135 | unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 8396d150ce01..3a1ff55bceb9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -231,7 +231,8 @@ struct ar9300_modal_eep_header { | |||
231 | __le32 papdRateMaskHt20; | 231 | __le32 papdRateMaskHt20; |
232 | __le32 papdRateMaskHt40; | 232 | __le32 papdRateMaskHt40; |
233 | __le16 switchcomspdt; | 233 | __le16 switchcomspdt; |
234 | u8 futureModal[8]; | 234 | u8 xlna_bias_strength; |
235 | u8 futureModal[7]; | ||
235 | } __packed; | 236 | } __packed; |
236 | 237 | ||
237 | struct ar9300_cal_data_per_freq_op_loop { | 238 | struct ar9300_cal_data_per_freq_op_loop { |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 41e88c660e48..1e8a4da5952f 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -44,462 +44,310 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | |||
44 | ar9462_2p0_baseband_core_txfir_coeff_japan_2484 | 44 | ar9462_2p0_baseband_core_txfir_coeff_japan_2484 |
45 | if (AR_SREV_9330_11(ah)) { | 45 | if (AR_SREV_9330_11(ah)) { |
46 | /* mac */ | 46 | /* mac */ |
47 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
48 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 47 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
49 | ar9331_1p1_mac_core, | 48 | ar9331_1p1_mac_core); |
50 | ARRAY_SIZE(ar9331_1p1_mac_core), 2); | ||
51 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 49 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
52 | ar9331_1p1_mac_postamble, | 50 | ar9331_1p1_mac_postamble); |
53 | ARRAY_SIZE(ar9331_1p1_mac_postamble), 5); | ||
54 | 51 | ||
55 | /* bb */ | 52 | /* bb */ |
56 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
57 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 53 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
58 | ar9331_1p1_baseband_core, | 54 | ar9331_1p1_baseband_core); |
59 | ARRAY_SIZE(ar9331_1p1_baseband_core), 2); | ||
60 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 55 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
61 | ar9331_1p1_baseband_postamble, | 56 | ar9331_1p1_baseband_postamble); |
62 | ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5); | ||
63 | 57 | ||
64 | /* radio */ | 58 | /* radio */ |
65 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
66 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 59 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
67 | ar9331_1p1_radio_core, | 60 | ar9331_1p1_radio_core); |
68 | ARRAY_SIZE(ar9331_1p1_radio_core), 2); | ||
69 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); | ||
70 | 61 | ||
71 | /* soc */ | 62 | /* soc */ |
72 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 63 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
73 | ar9331_1p1_soc_preamble, | 64 | ar9331_1p1_soc_preamble); |
74 | ARRAY_SIZE(ar9331_1p1_soc_preamble), 2); | ||
75 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
76 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 65 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
77 | ar9331_1p1_soc_postamble, | 66 | ar9331_1p1_soc_postamble); |
78 | ARRAY_SIZE(ar9331_1p1_soc_postamble), 2); | ||
79 | 67 | ||
80 | /* rx/tx gain */ | 68 | /* rx/tx gain */ |
81 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 69 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
82 | ar9331_common_rx_gain_1p1, | 70 | ar9331_common_rx_gain_1p1); |
83 | ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2); | ||
84 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 71 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
85 | ar9331_modes_lowest_ob_db_tx_gain_1p1, | 72 | ar9331_modes_lowest_ob_db_tx_gain_1p1); |
86 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), | ||
87 | 5); | ||
88 | 73 | ||
89 | /* additional clock settings */ | 74 | /* additional clock settings */ |
90 | if (ah->is_clk_25mhz) | 75 | if (ah->is_clk_25mhz) |
91 | INIT_INI_ARRAY(&ah->iniAdditional, | 76 | INIT_INI_ARRAY(&ah->iniAdditional, |
92 | ar9331_1p1_xtal_25M, | 77 | ar9331_1p1_xtal_25M); |
93 | ARRAY_SIZE(ar9331_1p1_xtal_25M), 2); | ||
94 | else | 78 | else |
95 | INIT_INI_ARRAY(&ah->iniAdditional, | 79 | INIT_INI_ARRAY(&ah->iniAdditional, |
96 | ar9331_1p1_xtal_40M, | 80 | ar9331_1p1_xtal_40M); |
97 | ARRAY_SIZE(ar9331_1p1_xtal_40M), 2); | ||
98 | } else if (AR_SREV_9330_12(ah)) { | 81 | } else if (AR_SREV_9330_12(ah)) { |
99 | /* mac */ | 82 | /* mac */ |
100 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
101 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 83 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
102 | ar9331_1p2_mac_core, | 84 | ar9331_1p2_mac_core); |
103 | ARRAY_SIZE(ar9331_1p2_mac_core), 2); | ||
104 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 85 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
105 | ar9331_1p2_mac_postamble, | 86 | ar9331_1p2_mac_postamble); |
106 | ARRAY_SIZE(ar9331_1p2_mac_postamble), 5); | ||
107 | 87 | ||
108 | /* bb */ | 88 | /* bb */ |
109 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
110 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 89 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
111 | ar9331_1p2_baseband_core, | 90 | ar9331_1p2_baseband_core); |
112 | ARRAY_SIZE(ar9331_1p2_baseband_core), 2); | ||
113 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 91 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
114 | ar9331_1p2_baseband_postamble, | 92 | ar9331_1p2_baseband_postamble); |
115 | ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5); | ||
116 | 93 | ||
117 | /* radio */ | 94 | /* radio */ |
118 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
119 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 95 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
120 | ar9331_1p2_radio_core, | 96 | ar9331_1p2_radio_core); |
121 | ARRAY_SIZE(ar9331_1p2_radio_core), 2); | ||
122 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0); | ||
123 | 97 | ||
124 | /* soc */ | 98 | /* soc */ |
125 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 99 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
126 | ar9331_1p2_soc_preamble, | 100 | ar9331_1p2_soc_preamble); |
127 | ARRAY_SIZE(ar9331_1p2_soc_preamble), 2); | ||
128 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
129 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 101 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
130 | ar9331_1p2_soc_postamble, | 102 | ar9331_1p2_soc_postamble); |
131 | ARRAY_SIZE(ar9331_1p2_soc_postamble), 2); | ||
132 | 103 | ||
133 | /* rx/tx gain */ | 104 | /* rx/tx gain */ |
134 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 105 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
135 | ar9331_common_rx_gain_1p2, | 106 | ar9331_common_rx_gain_1p2); |
136 | ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2); | ||
137 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 107 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
138 | ar9331_modes_lowest_ob_db_tx_gain_1p2, | 108 | ar9331_modes_lowest_ob_db_tx_gain_1p2); |
139 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), | ||
140 | 5); | ||
141 | 109 | ||
142 | /* additional clock settings */ | 110 | /* additional clock settings */ |
143 | if (ah->is_clk_25mhz) | 111 | if (ah->is_clk_25mhz) |
144 | INIT_INI_ARRAY(&ah->iniAdditional, | 112 | INIT_INI_ARRAY(&ah->iniAdditional, |
145 | ar9331_1p2_xtal_25M, | 113 | ar9331_1p2_xtal_25M); |
146 | ARRAY_SIZE(ar9331_1p2_xtal_25M), 2); | ||
147 | else | 114 | else |
148 | INIT_INI_ARRAY(&ah->iniAdditional, | 115 | INIT_INI_ARRAY(&ah->iniAdditional, |
149 | ar9331_1p2_xtal_40M, | 116 | ar9331_1p2_xtal_40M); |
150 | ARRAY_SIZE(ar9331_1p2_xtal_40M), 2); | ||
151 | } else if (AR_SREV_9340(ah)) { | 117 | } else if (AR_SREV_9340(ah)) { |
152 | /* mac */ | 118 | /* mac */ |
153 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
154 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 119 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
155 | ar9340_1p0_mac_core, | 120 | ar9340_1p0_mac_core); |
156 | ARRAY_SIZE(ar9340_1p0_mac_core), 2); | ||
157 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 121 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
158 | ar9340_1p0_mac_postamble, | 122 | ar9340_1p0_mac_postamble); |
159 | ARRAY_SIZE(ar9340_1p0_mac_postamble), 5); | ||
160 | 123 | ||
161 | /* bb */ | 124 | /* bb */ |
162 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
163 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 125 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
164 | ar9340_1p0_baseband_core, | 126 | ar9340_1p0_baseband_core); |
165 | ARRAY_SIZE(ar9340_1p0_baseband_core), 2); | ||
166 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 127 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
167 | ar9340_1p0_baseband_postamble, | 128 | ar9340_1p0_baseband_postamble); |
168 | ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5); | ||
169 | 129 | ||
170 | /* radio */ | 130 | /* radio */ |
171 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
172 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 131 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
173 | ar9340_1p0_radio_core, | 132 | ar9340_1p0_radio_core); |
174 | ARRAY_SIZE(ar9340_1p0_radio_core), 2); | ||
175 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 133 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
176 | ar9340_1p0_radio_postamble, | 134 | ar9340_1p0_radio_postamble); |
177 | ARRAY_SIZE(ar9340_1p0_radio_postamble), 5); | ||
178 | 135 | ||
179 | /* soc */ | 136 | /* soc */ |
180 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 137 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
181 | ar9340_1p0_soc_preamble, | 138 | ar9340_1p0_soc_preamble); |
182 | ARRAY_SIZE(ar9340_1p0_soc_preamble), 2); | ||
183 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
184 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 139 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
185 | ar9340_1p0_soc_postamble, | 140 | ar9340_1p0_soc_postamble); |
186 | ARRAY_SIZE(ar9340_1p0_soc_postamble), 5); | ||
187 | 141 | ||
188 | /* rx/tx gain */ | 142 | /* rx/tx gain */ |
189 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 143 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
190 | ar9340Common_wo_xlna_rx_gain_table_1p0, | 144 | ar9340Common_wo_xlna_rx_gain_table_1p0); |
191 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||
192 | 5); | ||
193 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 145 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
194 | ar9340Modes_high_ob_db_tx_gain_table_1p0, | 146 | ar9340Modes_high_ob_db_tx_gain_table_1p0); |
195 | ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), | ||
196 | 5); | ||
197 | 147 | ||
198 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 148 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
199 | ar9340Modes_fast_clock_1p0, | 149 | ar9340Modes_fast_clock_1p0); |
200 | ARRAY_SIZE(ar9340Modes_fast_clock_1p0), | ||
201 | 3); | ||
202 | 150 | ||
203 | if (!ah->is_clk_25mhz) | 151 | if (!ah->is_clk_25mhz) |
204 | INIT_INI_ARRAY(&ah->iniAdditional, | 152 | INIT_INI_ARRAY(&ah->iniAdditional, |
205 | ar9340_1p0_radio_core_40M, | 153 | ar9340_1p0_radio_core_40M); |
206 | ARRAY_SIZE(ar9340_1p0_radio_core_40M), | ||
207 | 2); | ||
208 | } else if (AR_SREV_9485_11(ah)) { | 154 | } else if (AR_SREV_9485_11(ah)) { |
209 | /* mac */ | 155 | /* mac */ |
210 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
211 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 156 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
212 | ar9485_1_1_mac_core, | 157 | ar9485_1_1_mac_core); |
213 | ARRAY_SIZE(ar9485_1_1_mac_core), 2); | ||
214 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 158 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
215 | ar9485_1_1_mac_postamble, | 159 | ar9485_1_1_mac_postamble); |
216 | ARRAY_SIZE(ar9485_1_1_mac_postamble), 5); | ||
217 | 160 | ||
218 | /* bb */ | 161 | /* bb */ |
219 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1, | 162 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1); |
220 | ARRAY_SIZE(ar9485_1_1), 2); | ||
221 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 163 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
222 | ar9485_1_1_baseband_core, | 164 | ar9485_1_1_baseband_core); |
223 | ARRAY_SIZE(ar9485_1_1_baseband_core), 2); | ||
224 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 165 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
225 | ar9485_1_1_baseband_postamble, | 166 | ar9485_1_1_baseband_postamble); |
226 | ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5); | ||
227 | 167 | ||
228 | /* radio */ | 168 | /* radio */ |
229 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
230 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 169 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
231 | ar9485_1_1_radio_core, | 170 | ar9485_1_1_radio_core); |
232 | ARRAY_SIZE(ar9485_1_1_radio_core), 2); | ||
233 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 171 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
234 | ar9485_1_1_radio_postamble, | 172 | ar9485_1_1_radio_postamble); |
235 | ARRAY_SIZE(ar9485_1_1_radio_postamble), 2); | ||
236 | 173 | ||
237 | /* soc */ | 174 | /* soc */ |
238 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 175 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
239 | ar9485_1_1_soc_preamble, | 176 | ar9485_1_1_soc_preamble); |
240 | ARRAY_SIZE(ar9485_1_1_soc_preamble), 2); | ||
241 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
242 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0); | ||
243 | 177 | ||
244 | /* rx/tx gain */ | 178 | /* rx/tx gain */ |
245 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 179 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
246 | ar9485Common_wo_xlna_rx_gain_1_1, | 180 | ar9485Common_wo_xlna_rx_gain_1_1); |
247 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2); | ||
248 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 181 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
249 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | 182 | ar9485_modes_lowest_ob_db_tx_gain_1_1); |
250 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | ||
251 | 5); | ||
252 | 183 | ||
253 | /* Load PCIE SERDES settings from INI */ | 184 | /* Load PCIE SERDES settings from INI */ |
254 | 185 | ||
255 | /* Awake Setting */ | 186 | /* Awake Setting */ |
256 | 187 | ||
257 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 188 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
258 | ar9485_1_1_pcie_phy_clkreq_disable_L1, | 189 | ar9485_1_1_pcie_phy_clkreq_disable_L1); |
259 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), | ||
260 | 2); | ||
261 | 190 | ||
262 | /* Sleep Setting */ | 191 | /* Sleep Setting */ |
263 | 192 | ||
264 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 193 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
265 | ar9485_1_1_pcie_phy_clkreq_disable_L1, | 194 | ar9485_1_1_pcie_phy_clkreq_disable_L1); |
266 | ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1), | ||
267 | 2); | ||
268 | } else if (AR_SREV_9462_20(ah)) { | 195 | } else if (AR_SREV_9462_20(ah)) { |
269 | 196 | ||
270 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | 197 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); |
271 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core, | ||
272 | ARRAY_SIZE(ar9462_2p0_mac_core), 2); | ||
273 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 198 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
274 | ar9462_2p0_mac_postamble, | 199 | ar9462_2p0_mac_postamble); |
275 | ARRAY_SIZE(ar9462_2p0_mac_postamble), 5); | ||
276 | 200 | ||
277 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
278 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 201 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
279 | ar9462_2p0_baseband_core, | 202 | ar9462_2p0_baseband_core); |
280 | ARRAY_SIZE(ar9462_2p0_baseband_core), 2); | ||
281 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 203 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
282 | ar9462_2p0_baseband_postamble, | 204 | ar9462_2p0_baseband_postamble); |
283 | ARRAY_SIZE(ar9462_2p0_baseband_postamble), 5); | ||
284 | 205 | ||
285 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
286 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 206 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
287 | ar9462_2p0_radio_core, | 207 | ar9462_2p0_radio_core); |
288 | ARRAY_SIZE(ar9462_2p0_radio_core), 2); | ||
289 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 208 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
290 | ar9462_2p0_radio_postamble, | 209 | ar9462_2p0_radio_postamble); |
291 | ARRAY_SIZE(ar9462_2p0_radio_postamble), 5); | ||
292 | INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant, | 210 | INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant, |
293 | ar9462_2p0_radio_postamble_sys2ant, | 211 | ar9462_2p0_radio_postamble_sys2ant); |
294 | ARRAY_SIZE(ar9462_2p0_radio_postamble_sys2ant), | ||
295 | 5); | ||
296 | 212 | ||
297 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 213 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
298 | ar9462_2p0_soc_preamble, | 214 | ar9462_2p0_soc_preamble); |
299 | ARRAY_SIZE(ar9462_2p0_soc_preamble), 2); | ||
300 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
301 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 215 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
302 | ar9462_2p0_soc_postamble, | 216 | ar9462_2p0_soc_postamble); |
303 | ARRAY_SIZE(ar9462_2p0_soc_postamble), 5); | ||
304 | 217 | ||
305 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 218 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
306 | ar9462_common_rx_gain_table_2p0, | 219 | ar9462_common_rx_gain_table_2p0); |
307 | ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), 2); | ||
308 | 220 | ||
309 | /* Awake -> Sleep Setting */ | 221 | /* Awake -> Sleep Setting */ |
310 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 222 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
311 | PCIE_PLL_ON_CREQ_DIS_L1_2P0, | 223 | PCIE_PLL_ON_CREQ_DIS_L1_2P0); |
312 | ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0), | ||
313 | 2); | ||
314 | /* Sleep -> Awake Setting */ | 224 | /* Sleep -> Awake Setting */ |
315 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 225 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
316 | PCIE_PLL_ON_CREQ_DIS_L1_2P0, | 226 | PCIE_PLL_ON_CREQ_DIS_L1_2P0); |
317 | ARRAY_SIZE(PCIE_PLL_ON_CREQ_DIS_L1_2P0), | ||
318 | 2); | ||
319 | 227 | ||
320 | /* Fast clock modal settings */ | 228 | /* Fast clock modal settings */ |
321 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 229 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
322 | ar9462_modes_fast_clock_2p0, | 230 | ar9462_modes_fast_clock_2p0); |
323 | ARRAY_SIZE(ar9462_modes_fast_clock_2p0), 3); | ||
324 | 231 | ||
325 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | 232 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, |
326 | AR9462_BB_CTX_COEFJ(2p0), | 233 | AR9462_BB_CTX_COEFJ(2p0)); |
327 | ARRAY_SIZE(AR9462_BB_CTX_COEFJ(2p0)), 2); | ||
328 | 234 | ||
329 | INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ, | 235 | INIT_INI_ARRAY(&ah->ini_japan2484, AR9462_BBC_TXIFR_COEFFJ); |
330 | ARRAY_SIZE(AR9462_BBC_TXIFR_COEFFJ), 2); | ||
331 | } else if (AR_SREV_9550(ah)) { | 236 | } else if (AR_SREV_9550(ah)) { |
332 | /* mac */ | 237 | /* mac */ |
333 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
334 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 238 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
335 | ar955x_1p0_mac_core, | 239 | ar955x_1p0_mac_core); |
336 | ARRAY_SIZE(ar955x_1p0_mac_core), 2); | ||
337 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 240 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
338 | ar955x_1p0_mac_postamble, | 241 | ar955x_1p0_mac_postamble); |
339 | ARRAY_SIZE(ar955x_1p0_mac_postamble), 5); | ||
340 | 242 | ||
341 | /* bb */ | 243 | /* bb */ |
342 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
343 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 244 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
344 | ar955x_1p0_baseband_core, | 245 | ar955x_1p0_baseband_core); |
345 | ARRAY_SIZE(ar955x_1p0_baseband_core), 2); | ||
346 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 246 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
347 | ar955x_1p0_baseband_postamble, | 247 | ar955x_1p0_baseband_postamble); |
348 | ARRAY_SIZE(ar955x_1p0_baseband_postamble), 5); | ||
349 | 248 | ||
350 | /* radio */ | 249 | /* radio */ |
351 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
352 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 250 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
353 | ar955x_1p0_radio_core, | 251 | ar955x_1p0_radio_core); |
354 | ARRAY_SIZE(ar955x_1p0_radio_core), 2); | ||
355 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 252 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
356 | ar955x_1p0_radio_postamble, | 253 | ar955x_1p0_radio_postamble); |
357 | ARRAY_SIZE(ar955x_1p0_radio_postamble), 5); | ||
358 | 254 | ||
359 | /* soc */ | 255 | /* soc */ |
360 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 256 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
361 | ar955x_1p0_soc_preamble, | 257 | ar955x_1p0_soc_preamble); |
362 | ARRAY_SIZE(ar955x_1p0_soc_preamble), 2); | ||
363 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
364 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 258 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
365 | ar955x_1p0_soc_postamble, | 259 | ar955x_1p0_soc_postamble); |
366 | ARRAY_SIZE(ar955x_1p0_soc_postamble), 5); | ||
367 | 260 | ||
368 | /* rx/tx gain */ | 261 | /* rx/tx gain */ |
369 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 262 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
370 | ar955x_1p0_common_wo_xlna_rx_gain_table, | 263 | ar955x_1p0_common_wo_xlna_rx_gain_table); |
371 | ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_table), | ||
372 | 2); | ||
373 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | 264 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, |
374 | ar955x_1p0_common_wo_xlna_rx_gain_bounds, | 265 | ar955x_1p0_common_wo_xlna_rx_gain_bounds); |
375 | ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_bounds), | ||
376 | 5); | ||
377 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 266 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
378 | ar955x_1p0_modes_xpa_tx_gain_table, | 267 | ar955x_1p0_modes_xpa_tx_gain_table); |
379 | ARRAY_SIZE(ar955x_1p0_modes_xpa_tx_gain_table), | ||
380 | 9); | ||
381 | 268 | ||
382 | /* Fast clock modal settings */ | 269 | /* Fast clock modal settings */ |
383 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 270 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
384 | ar955x_1p0_modes_fast_clock, | 271 | ar955x_1p0_modes_fast_clock); |
385 | ARRAY_SIZE(ar955x_1p0_modes_fast_clock), 3); | ||
386 | } else if (AR_SREV_9580(ah)) { | 272 | } else if (AR_SREV_9580(ah)) { |
387 | /* mac */ | 273 | /* mac */ |
388 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
389 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 274 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
390 | ar9580_1p0_mac_core, | 275 | ar9580_1p0_mac_core); |
391 | ARRAY_SIZE(ar9580_1p0_mac_core), 2); | ||
392 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 276 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
393 | ar9580_1p0_mac_postamble, | 277 | ar9580_1p0_mac_postamble); |
394 | ARRAY_SIZE(ar9580_1p0_mac_postamble), 5); | ||
395 | 278 | ||
396 | /* bb */ | 279 | /* bb */ |
397 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
398 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 280 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
399 | ar9580_1p0_baseband_core, | 281 | ar9580_1p0_baseband_core); |
400 | ARRAY_SIZE(ar9580_1p0_baseband_core), 2); | ||
401 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 282 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
402 | ar9580_1p0_baseband_postamble, | 283 | ar9580_1p0_baseband_postamble); |
403 | ARRAY_SIZE(ar9580_1p0_baseband_postamble), 5); | ||
404 | 284 | ||
405 | /* radio */ | 285 | /* radio */ |
406 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
407 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 286 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
408 | ar9580_1p0_radio_core, | 287 | ar9580_1p0_radio_core); |
409 | ARRAY_SIZE(ar9580_1p0_radio_core), 2); | ||
410 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 288 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
411 | ar9580_1p0_radio_postamble, | 289 | ar9580_1p0_radio_postamble); |
412 | ARRAY_SIZE(ar9580_1p0_radio_postamble), 5); | ||
413 | 290 | ||
414 | /* soc */ | 291 | /* soc */ |
415 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 292 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
416 | ar9580_1p0_soc_preamble, | 293 | ar9580_1p0_soc_preamble); |
417 | ARRAY_SIZE(ar9580_1p0_soc_preamble), 2); | ||
418 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
419 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 294 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
420 | ar9580_1p0_soc_postamble, | 295 | ar9580_1p0_soc_postamble); |
421 | ARRAY_SIZE(ar9580_1p0_soc_postamble), 5); | ||
422 | 296 | ||
423 | /* rx/tx gain */ | 297 | /* rx/tx gain */ |
424 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 298 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
425 | ar9580_1p0_rx_gain_table, | 299 | ar9580_1p0_rx_gain_table); |
426 | ARRAY_SIZE(ar9580_1p0_rx_gain_table), 2); | ||
427 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 300 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
428 | ar9580_1p0_low_ob_db_tx_gain_table, | 301 | ar9580_1p0_low_ob_db_tx_gain_table); |
429 | ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), | ||
430 | 5); | ||
431 | 302 | ||
432 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 303 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
433 | ar9580_1p0_modes_fast_clock, | 304 | ar9580_1p0_modes_fast_clock); |
434 | ARRAY_SIZE(ar9580_1p0_modes_fast_clock), | ||
435 | 3); | ||
436 | } else { | 305 | } else { |
437 | /* mac */ | 306 | /* mac */ |
438 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
439 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | 307 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], |
440 | ar9300_2p2_mac_core, | 308 | ar9300_2p2_mac_core); |
441 | ARRAY_SIZE(ar9300_2p2_mac_core), 2); | ||
442 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | 309 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], |
443 | ar9300_2p2_mac_postamble, | 310 | ar9300_2p2_mac_postamble); |
444 | ARRAY_SIZE(ar9300_2p2_mac_postamble), 5); | ||
445 | 311 | ||
446 | /* bb */ | 312 | /* bb */ |
447 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
448 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | 313 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], |
449 | ar9300_2p2_baseband_core, | 314 | ar9300_2p2_baseband_core); |
450 | ARRAY_SIZE(ar9300_2p2_baseband_core), 2); | ||
451 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | 315 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], |
452 | ar9300_2p2_baseband_postamble, | 316 | ar9300_2p2_baseband_postamble); |
453 | ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5); | ||
454 | 317 | ||
455 | /* radio */ | 318 | /* radio */ |
456 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
457 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | 319 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], |
458 | ar9300_2p2_radio_core, | 320 | ar9300_2p2_radio_core); |
459 | ARRAY_SIZE(ar9300_2p2_radio_core), 2); | ||
460 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | 321 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], |
461 | ar9300_2p2_radio_postamble, | 322 | ar9300_2p2_radio_postamble); |
462 | ARRAY_SIZE(ar9300_2p2_radio_postamble), 5); | ||
463 | 323 | ||
464 | /* soc */ | 324 | /* soc */ |
465 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | 325 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], |
466 | ar9300_2p2_soc_preamble, | 326 | ar9300_2p2_soc_preamble); |
467 | ARRAY_SIZE(ar9300_2p2_soc_preamble), 2); | ||
468 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
469 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | 327 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], |
470 | ar9300_2p2_soc_postamble, | 328 | ar9300_2p2_soc_postamble); |
471 | ARRAY_SIZE(ar9300_2p2_soc_postamble), 5); | ||
472 | 329 | ||
473 | /* rx/tx gain */ | 330 | /* rx/tx gain */ |
474 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 331 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
475 | ar9300Common_rx_gain_table_2p2, | 332 | ar9300Common_rx_gain_table_2p2); |
476 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2); | ||
477 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 333 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
478 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2, | 334 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2); |
479 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), | ||
480 | 5); | ||
481 | 335 | ||
482 | /* Load PCIE SERDES settings from INI */ | 336 | /* Load PCIE SERDES settings from INI */ |
483 | 337 | ||
484 | /* Awake Setting */ | 338 | /* Awake Setting */ |
485 | 339 | ||
486 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | 340 | INIT_INI_ARRAY(&ah->iniPcieSerdes, |
487 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, | 341 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p2); |
488 | ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), | ||
489 | 2); | ||
490 | 342 | ||
491 | /* Sleep Setting */ | 343 | /* Sleep Setting */ |
492 | 344 | ||
493 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | 345 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, |
494 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p2, | 346 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p2); |
495 | ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2), | ||
496 | 2); | ||
497 | 347 | ||
498 | /* Fast clock modal settings */ | 348 | /* Fast clock modal settings */ |
499 | INIT_INI_ARRAY(&ah->iniModesFastClock, | 349 | INIT_INI_ARRAY(&ah->iniModesFastClock, |
500 | ar9300Modes_fast_clock_2p2, | 350 | ar9300Modes_fast_clock_2p2); |
501 | ARRAY_SIZE(ar9300Modes_fast_clock_2p2), | ||
502 | 3); | ||
503 | } | 351 | } |
504 | } | 352 | } |
505 | 353 | ||
@@ -507,156 +355,110 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) | |||
507 | { | 355 | { |
508 | if (AR_SREV_9330_12(ah)) | 356 | if (AR_SREV_9330_12(ah)) |
509 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 357 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
510 | ar9331_modes_lowest_ob_db_tx_gain_1p2, | 358 | ar9331_modes_lowest_ob_db_tx_gain_1p2); |
511 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2), | ||
512 | 5); | ||
513 | else if (AR_SREV_9330_11(ah)) | 359 | else if (AR_SREV_9330_11(ah)) |
514 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 360 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
515 | ar9331_modes_lowest_ob_db_tx_gain_1p1, | 361 | ar9331_modes_lowest_ob_db_tx_gain_1p1); |
516 | ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1), | ||
517 | 5); | ||
518 | else if (AR_SREV_9340(ah)) | 362 | else if (AR_SREV_9340(ah)) |
519 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 363 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
520 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 364 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0); |
521 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
522 | 5); | ||
523 | else if (AR_SREV_9485_11(ah)) | 365 | else if (AR_SREV_9485_11(ah)) |
524 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 366 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
525 | ar9485_modes_lowest_ob_db_tx_gain_1_1, | 367 | ar9485_modes_lowest_ob_db_tx_gain_1_1); |
526 | ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | ||
527 | 5); | ||
528 | else if (AR_SREV_9550(ah)) | 368 | else if (AR_SREV_9550(ah)) |
529 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 369 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
530 | ar955x_1p0_modes_xpa_tx_gain_table, | 370 | ar955x_1p0_modes_xpa_tx_gain_table); |
531 | ARRAY_SIZE(ar955x_1p0_modes_xpa_tx_gain_table), | ||
532 | 9); | ||
533 | else if (AR_SREV_9580(ah)) | 371 | else if (AR_SREV_9580(ah)) |
534 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 372 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
535 | ar9580_1p0_lowest_ob_db_tx_gain_table, | 373 | ar9580_1p0_lowest_ob_db_tx_gain_table); |
536 | ARRAY_SIZE(ar9580_1p0_lowest_ob_db_tx_gain_table), | ||
537 | 5); | ||
538 | else if (AR_SREV_9462_20(ah)) | 374 | else if (AR_SREV_9462_20(ah)) |
539 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 375 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
540 | ar9462_modes_low_ob_db_tx_gain_table_2p0, | 376 | ar9462_modes_low_ob_db_tx_gain_table_2p0); |
541 | ARRAY_SIZE(ar9462_modes_low_ob_db_tx_gain_table_2p0), | ||
542 | 5); | ||
543 | else | 377 | else |
544 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 378 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
545 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2, | 379 | ar9300Modes_lowest_ob_db_tx_gain_table_2p2); |
546 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2), | ||
547 | 5); | ||
548 | } | 380 | } |
549 | 381 | ||
550 | static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) | 382 | static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) |
551 | { | 383 | { |
552 | if (AR_SREV_9330_12(ah)) | 384 | if (AR_SREV_9330_12(ah)) |
553 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 385 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
554 | ar9331_modes_high_ob_db_tx_gain_1p2, | 386 | ar9331_modes_high_ob_db_tx_gain_1p2); |
555 | ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2), | ||
556 | 5); | ||
557 | else if (AR_SREV_9330_11(ah)) | 387 | else if (AR_SREV_9330_11(ah)) |
558 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 388 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
559 | ar9331_modes_high_ob_db_tx_gain_1p1, | 389 | ar9331_modes_high_ob_db_tx_gain_1p1); |
560 | ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1), | ||
561 | 5); | ||
562 | else if (AR_SREV_9340(ah)) | 390 | else if (AR_SREV_9340(ah)) |
563 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 391 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
564 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 392 | ar9340Modes_high_ob_db_tx_gain_table_1p0); |
565 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
566 | 5); | ||
567 | else if (AR_SREV_9485_11(ah)) | 393 | else if (AR_SREV_9485_11(ah)) |
568 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 394 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
569 | ar9485Modes_high_ob_db_tx_gain_1_1, | 395 | ar9485Modes_high_ob_db_tx_gain_1_1); |
570 | ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), | ||
571 | 5); | ||
572 | else if (AR_SREV_9580(ah)) | 396 | else if (AR_SREV_9580(ah)) |
573 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 397 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
574 | ar9580_1p0_high_ob_db_tx_gain_table, | 398 | ar9580_1p0_high_ob_db_tx_gain_table); |
575 | ARRAY_SIZE(ar9580_1p0_high_ob_db_tx_gain_table), | ||
576 | 5); | ||
577 | else if (AR_SREV_9550(ah)) | 399 | else if (AR_SREV_9550(ah)) |
578 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 400 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
579 | ar955x_1p0_modes_no_xpa_tx_gain_table, | 401 | ar955x_1p0_modes_no_xpa_tx_gain_table); |
580 | ARRAY_SIZE(ar955x_1p0_modes_no_xpa_tx_gain_table), | ||
581 | 9); | ||
582 | else if (AR_SREV_9462_20(ah)) | 402 | else if (AR_SREV_9462_20(ah)) |
583 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 403 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
584 | ar9462_modes_high_ob_db_tx_gain_table_2p0, | 404 | ar9462_modes_high_ob_db_tx_gain_table_2p0); |
585 | ARRAY_SIZE(ar9462_modes_high_ob_db_tx_gain_table_2p0), | ||
586 | 5); | ||
587 | else | 405 | else |
588 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 406 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
589 | ar9300Modes_high_ob_db_tx_gain_table_2p2, | 407 | ar9300Modes_high_ob_db_tx_gain_table_2p2); |
590 | ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2), | ||
591 | 5); | ||
592 | } | 408 | } |
593 | 409 | ||
594 | static void ar9003_tx_gain_table_mode2(struct ath_hw *ah) | 410 | static void ar9003_tx_gain_table_mode2(struct ath_hw *ah) |
595 | { | 411 | { |
596 | if (AR_SREV_9330_12(ah)) | 412 | if (AR_SREV_9330_12(ah)) |
597 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 413 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
598 | ar9331_modes_low_ob_db_tx_gain_1p2, | 414 | ar9331_modes_low_ob_db_tx_gain_1p2); |
599 | ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2), | ||
600 | 5); | ||
601 | else if (AR_SREV_9330_11(ah)) | 415 | else if (AR_SREV_9330_11(ah)) |
602 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 416 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
603 | ar9331_modes_low_ob_db_tx_gain_1p1, | 417 | ar9331_modes_low_ob_db_tx_gain_1p1); |
604 | ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1), | ||
605 | 5); | ||
606 | else if (AR_SREV_9340(ah)) | 418 | else if (AR_SREV_9340(ah)) |
607 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 419 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
608 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 420 | ar9340Modes_low_ob_db_tx_gain_table_1p0); |
609 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
610 | 5); | ||
611 | else if (AR_SREV_9485_11(ah)) | 421 | else if (AR_SREV_9485_11(ah)) |
612 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 422 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
613 | ar9485Modes_low_ob_db_tx_gain_1_1, | 423 | ar9485Modes_low_ob_db_tx_gain_1_1); |
614 | ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), | ||
615 | 5); | ||
616 | else if (AR_SREV_9580(ah)) | 424 | else if (AR_SREV_9580(ah)) |
617 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 425 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
618 | ar9580_1p0_low_ob_db_tx_gain_table, | 426 | ar9580_1p0_low_ob_db_tx_gain_table); |
619 | ARRAY_SIZE(ar9580_1p0_low_ob_db_tx_gain_table), | ||
620 | 5); | ||
621 | else | 427 | else |
622 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 428 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
623 | ar9300Modes_low_ob_db_tx_gain_table_2p2, | 429 | ar9300Modes_low_ob_db_tx_gain_table_2p2); |
624 | ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2), | ||
625 | 5); | ||
626 | } | 430 | } |
627 | 431 | ||
628 | static void ar9003_tx_gain_table_mode3(struct ath_hw *ah) | 432 | static void ar9003_tx_gain_table_mode3(struct ath_hw *ah) |
629 | { | 433 | { |
630 | if (AR_SREV_9330_12(ah)) | 434 | if (AR_SREV_9330_12(ah)) |
631 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 435 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
632 | ar9331_modes_high_power_tx_gain_1p2, | 436 | ar9331_modes_high_power_tx_gain_1p2); |
633 | ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2), | ||
634 | 5); | ||
635 | else if (AR_SREV_9330_11(ah)) | 437 | else if (AR_SREV_9330_11(ah)) |
636 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 438 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
637 | ar9331_modes_high_power_tx_gain_1p1, | 439 | ar9331_modes_high_power_tx_gain_1p1); |
638 | ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1), | ||
639 | 5); | ||
640 | else if (AR_SREV_9340(ah)) | 440 | else if (AR_SREV_9340(ah)) |
641 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 441 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
642 | ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | 442 | ar9340Modes_high_power_tx_gain_table_1p0); |
643 | ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||
644 | 5); | ||
645 | else if (AR_SREV_9485_11(ah)) | 443 | else if (AR_SREV_9485_11(ah)) |
646 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 444 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
647 | ar9485Modes_high_power_tx_gain_1_1, | 445 | ar9485Modes_high_power_tx_gain_1_1); |
648 | ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), | ||
649 | 5); | ||
650 | else if (AR_SREV_9580(ah)) | 446 | else if (AR_SREV_9580(ah)) |
651 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 447 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
652 | ar9580_1p0_high_power_tx_gain_table, | 448 | ar9580_1p0_high_power_tx_gain_table); |
653 | ARRAY_SIZE(ar9580_1p0_high_power_tx_gain_table), | ||
654 | 5); | ||
655 | else | 449 | else |
656 | INIT_INI_ARRAY(&ah->iniModesTxGain, | 450 | INIT_INI_ARRAY(&ah->iniModesTxGain, |
657 | ar9300Modes_high_power_tx_gain_table_2p2, | 451 | ar9300Modes_high_power_tx_gain_table_2p2); |
658 | ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2), | 452 | } |
659 | 5); | 453 | |
454 | static void ar9003_tx_gain_table_mode4(struct ath_hw *ah) | ||
455 | { | ||
456 | if (AR_SREV_9340(ah)) | ||
457 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
458 | ar9340Modes_mixed_ob_db_tx_gain_table_1p0); | ||
459 | else if (AR_SREV_9580(ah)) | ||
460 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
461 | ar9580_1p0_mixed_ob_db_tx_gain_table); | ||
660 | } | 462 | } |
661 | 463 | ||
662 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | 464 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) |
@@ -675,6 +477,9 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
675 | case 3: | 477 | case 3: |
676 | ar9003_tx_gain_table_mode3(ah); | 478 | ar9003_tx_gain_table_mode3(ah); |
677 | break; | 479 | break; |
480 | case 4: | ||
481 | ar9003_tx_gain_table_mode4(ah); | ||
482 | break; | ||
678 | } | 483 | } |
679 | } | 484 | } |
680 | 485 | ||
@@ -682,104 +487,67 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah) | |||
682 | { | 487 | { |
683 | if (AR_SREV_9330_12(ah)) | 488 | if (AR_SREV_9330_12(ah)) |
684 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 489 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
685 | ar9331_common_rx_gain_1p2, | 490 | ar9331_common_rx_gain_1p2); |
686 | ARRAY_SIZE(ar9331_common_rx_gain_1p2), | ||
687 | 2); | ||
688 | else if (AR_SREV_9330_11(ah)) | 491 | else if (AR_SREV_9330_11(ah)) |
689 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 492 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
690 | ar9331_common_rx_gain_1p1, | 493 | ar9331_common_rx_gain_1p1); |
691 | ARRAY_SIZE(ar9331_common_rx_gain_1p1), | ||
692 | 2); | ||
693 | else if (AR_SREV_9340(ah)) | 494 | else if (AR_SREV_9340(ah)) |
694 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 495 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
695 | ar9340Common_rx_gain_table_1p0, | 496 | ar9340Common_rx_gain_table_1p0); |
696 | ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), | ||
697 | 2); | ||
698 | else if (AR_SREV_9485_11(ah)) | 497 | else if (AR_SREV_9485_11(ah)) |
699 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 498 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
700 | ar9485Common_wo_xlna_rx_gain_1_1, | 499 | ar9485Common_wo_xlna_rx_gain_1_1); |
701 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | ||
702 | 2); | ||
703 | else if (AR_SREV_9550(ah)) { | 500 | else if (AR_SREV_9550(ah)) { |
704 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 501 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
705 | ar955x_1p0_common_rx_gain_table, | 502 | ar955x_1p0_common_rx_gain_table); |
706 | ARRAY_SIZE(ar955x_1p0_common_rx_gain_table), | ||
707 | 2); | ||
708 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | 503 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, |
709 | ar955x_1p0_common_rx_gain_bounds, | 504 | ar955x_1p0_common_rx_gain_bounds); |
710 | ARRAY_SIZE(ar955x_1p0_common_rx_gain_bounds), | ||
711 | 5); | ||
712 | } else if (AR_SREV_9580(ah)) | 505 | } else if (AR_SREV_9580(ah)) |
713 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 506 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
714 | ar9580_1p0_rx_gain_table, | 507 | ar9580_1p0_rx_gain_table); |
715 | ARRAY_SIZE(ar9580_1p0_rx_gain_table), | ||
716 | 2); | ||
717 | else if (AR_SREV_9462_20(ah)) | 508 | else if (AR_SREV_9462_20(ah)) |
718 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 509 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
719 | ar9462_common_rx_gain_table_2p0, | 510 | ar9462_common_rx_gain_table_2p0); |
720 | ARRAY_SIZE(ar9462_common_rx_gain_table_2p0), | ||
721 | 2); | ||
722 | else | 511 | else |
723 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 512 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
724 | ar9300Common_rx_gain_table_2p2, | 513 | ar9300Common_rx_gain_table_2p2); |
725 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), | ||
726 | 2); | ||
727 | } | 514 | } |
728 | 515 | ||
729 | static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) | 516 | static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) |
730 | { | 517 | { |
731 | if (AR_SREV_9330_12(ah)) | 518 | if (AR_SREV_9330_12(ah)) |
732 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 519 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
733 | ar9331_common_wo_xlna_rx_gain_1p2, | 520 | ar9331_common_wo_xlna_rx_gain_1p2); |
734 | ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2), | ||
735 | 2); | ||
736 | else if (AR_SREV_9330_11(ah)) | 521 | else if (AR_SREV_9330_11(ah)) |
737 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 522 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
738 | ar9331_common_wo_xlna_rx_gain_1p1, | 523 | ar9331_common_wo_xlna_rx_gain_1p1); |
739 | ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1), | ||
740 | 2); | ||
741 | else if (AR_SREV_9340(ah)) | 524 | else if (AR_SREV_9340(ah)) |
742 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 525 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
743 | ar9340Common_wo_xlna_rx_gain_table_1p0, | 526 | ar9340Common_wo_xlna_rx_gain_table_1p0); |
744 | ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||
745 | 2); | ||
746 | else if (AR_SREV_9485_11(ah)) | 527 | else if (AR_SREV_9485_11(ah)) |
747 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 528 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
748 | ar9485Common_wo_xlna_rx_gain_1_1, | 529 | ar9485Common_wo_xlna_rx_gain_1_1); |
749 | ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | ||
750 | 2); | ||
751 | else if (AR_SREV_9462_20(ah)) | 530 | else if (AR_SREV_9462_20(ah)) |
752 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 531 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
753 | ar9462_common_wo_xlna_rx_gain_table_2p0, | 532 | ar9462_common_wo_xlna_rx_gain_table_2p0); |
754 | ARRAY_SIZE(ar9462_common_wo_xlna_rx_gain_table_2p0), | ||
755 | 2); | ||
756 | else if (AR_SREV_9550(ah)) { | 533 | else if (AR_SREV_9550(ah)) { |
757 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 534 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
758 | ar955x_1p0_common_wo_xlna_rx_gain_table, | 535 | ar955x_1p0_common_wo_xlna_rx_gain_table); |
759 | ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_table), | ||
760 | 2); | ||
761 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, | 536 | INIT_INI_ARRAY(&ah->ini_modes_rx_gain_bounds, |
762 | ar955x_1p0_common_wo_xlna_rx_gain_bounds, | 537 | ar955x_1p0_common_wo_xlna_rx_gain_bounds); |
763 | ARRAY_SIZE(ar955x_1p0_common_wo_xlna_rx_gain_bounds), | ||
764 | 5); | ||
765 | } else if (AR_SREV_9580(ah)) | 538 | } else if (AR_SREV_9580(ah)) |
766 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 539 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
767 | ar9580_1p0_wo_xlna_rx_gain_table, | 540 | ar9580_1p0_wo_xlna_rx_gain_table); |
768 | ARRAY_SIZE(ar9580_1p0_wo_xlna_rx_gain_table), | ||
769 | 2); | ||
770 | else | 541 | else |
771 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 542 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
772 | ar9300Common_wo_xlna_rx_gain_table_2p2, | 543 | ar9300Common_wo_xlna_rx_gain_table_2p2); |
773 | ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2), | ||
774 | 2); | ||
775 | } | 544 | } |
776 | 545 | ||
777 | static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) | 546 | static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) |
778 | { | 547 | { |
779 | if (AR_SREV_9462_20(ah)) | 548 | if (AR_SREV_9462_20(ah)) |
780 | INIT_INI_ARRAY(&ah->iniModesRxGain, | 549 | INIT_INI_ARRAY(&ah->iniModesRxGain, |
781 | ar9462_common_mixed_rx_gain_table_2p0, | 550 | ar9462_common_mixed_rx_gain_table_2p0); |
782 | ARRAY_SIZE(ar9462_common_mixed_rx_gain_table_2p0), 2); | ||
783 | } | 551 | } |
784 | 552 | ||
785 | static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | 553 | static void ar9003_rx_gain_table_apply(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index d2346dbad6cd..e476f9f92ce3 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -117,8 +117,8 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
117 | ah->is_clk_25mhz) { | 117 | ah->is_clk_25mhz) { |
118 | u32 chan_frac; | 118 | u32 chan_frac; |
119 | 119 | ||
120 | channelSel = (freq * 2) / 75; | 120 | channelSel = freq / 75; |
121 | chan_frac = (((freq * 2) % 75) * 0x20000) / 75; | 121 | chan_frac = ((freq % 75) * 0x20000) / 75; |
122 | channelSel = (channelSel << 17) | chan_frac; | 122 | channelSel = (channelSel << 17) | chan_frac; |
123 | } else { | 123 | } else { |
124 | channelSel = CHANSEL_5G(freq); | 124 | channelSel = CHANSEL_5G(freq); |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 751c83b21493..7bfbaf065a43 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -633,6 +633,8 @@ | |||
633 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 | 633 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 |
634 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc | 634 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc |
635 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c | 635 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c |
636 | #define AR_PHY_65NM_CH1_RXTX4 0x1650c | ||
637 | #define AR_PHY_65NM_CH2_RXTX4 0x1690c | ||
636 | 638 | ||
637 | #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ | 639 | #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ |
638 | ((AR_SREV_9462(ah) ? 0x1628c : 0x16280))) | 640 | ((AR_SREV_9462(ah) ? 0x1628c : 0x16280))) |
@@ -876,6 +878,9 @@ | |||
876 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 | 878 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 |
877 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 | 879 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 |
878 | 880 | ||
881 | #define AR_PHY_65NM_RXTX4_XLNA_BIAS 0xC0000000 | ||
882 | #define AR_PHY_65NM_RXTX4_XLNA_BIAS_S 30 | ||
883 | |||
879 | /* | 884 | /* |
880 | * Channel 1 Register Map | 885 | * Channel 1 Register Map |
881 | */ | 886 | */ |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 79840d6deef2..b09285c36c4a 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -297,6 +297,8 @@ struct ath_tx { | |||
297 | struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; | 297 | struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; |
298 | struct ath_descdma txdma; | 298 | struct ath_descdma txdma; |
299 | struct ath_txq *txq_map[WME_NUM_AC]; | 299 | struct ath_txq *txq_map[WME_NUM_AC]; |
300 | u32 txq_max_pending[WME_NUM_AC]; | ||
301 | u16 max_aggr_framelen[WME_NUM_AC][4][32]; | ||
300 | }; | 302 | }; |
301 | 303 | ||
302 | struct ath_rx_edma { | 304 | struct ath_rx_edma { |
@@ -341,6 +343,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs); | |||
341 | void ath_tx_cleanup(struct ath_softc *sc); | 343 | void ath_tx_cleanup(struct ath_softc *sc); |
342 | int ath_txq_update(struct ath_softc *sc, int qnum, | 344 | int ath_txq_update(struct ath_softc *sc, int qnum, |
343 | struct ath9k_tx_queue_info *q); | 345 | struct ath9k_tx_queue_info *q); |
346 | void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop); | ||
344 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | 347 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, |
345 | struct ath_tx_control *txctl); | 348 | struct ath_tx_control *txctl); |
346 | void ath_tx_tasklet(struct ath_softc *sc); | 349 | void ath_tx_tasklet(struct ath_softc *sc); |
@@ -360,7 +363,7 @@ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, | |||
360 | 363 | ||
361 | struct ath_vif { | 364 | struct ath_vif { |
362 | int av_bslot; | 365 | int av_bslot; |
363 | bool is_bslot_active, primary_sta_vif; | 366 | bool primary_sta_vif; |
364 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ | 367 | __le64 tsf_adjust; /* TSF adjustment for staggered beacons */ |
365 | struct ath_buf *av_bcbuf; | 368 | struct ath_buf *av_bcbuf; |
366 | }; | 369 | }; |
@@ -386,6 +389,7 @@ struct ath_beacon_config { | |||
386 | u16 dtim_period; | 389 | u16 dtim_period; |
387 | u16 bmiss_timeout; | 390 | u16 bmiss_timeout; |
388 | u8 dtim_count; | 391 | u8 dtim_count; |
392 | bool enable_beacon; | ||
389 | }; | 393 | }; |
390 | 394 | ||
391 | struct ath_beacon { | 395 | struct ath_beacon { |
@@ -397,7 +401,6 @@ struct ath_beacon { | |||
397 | 401 | ||
398 | u32 beaconq; | 402 | u32 beaconq; |
399 | u32 bmisscnt; | 403 | u32 bmisscnt; |
400 | u32 ast_be_xmit; | ||
401 | u32 bc_tstamp; | 404 | u32 bc_tstamp; |
402 | struct ieee80211_vif *bslot[ATH_BCBUF]; | 405 | struct ieee80211_vif *bslot[ATH_BCBUF]; |
403 | int slottime; | 406 | int slottime; |
@@ -411,12 +414,14 @@ struct ath_beacon { | |||
411 | bool tx_last; | 414 | bool tx_last; |
412 | }; | 415 | }; |
413 | 416 | ||
414 | void ath_beacon_tasklet(unsigned long data); | 417 | void ath9k_beacon_tasklet(unsigned long data); |
415 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); | 418 | bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif); |
416 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif); | 419 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, |
417 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp); | 420 | u32 changed); |
418 | int ath_beaconq_config(struct ath_softc *sc); | 421 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
419 | void ath_set_beacon(struct ath_softc *sc); | 422 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
423 | void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); | ||
424 | void ath9k_set_beacon(struct ath_softc *sc); | ||
420 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | 425 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); |
421 | 426 | ||
422 | /*******************/ | 427 | /*******************/ |
@@ -442,9 +447,12 @@ void ath_rx_poll(unsigned long data); | |||
442 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); | 447 | void ath_start_rx_poll(struct ath_softc *sc, u8 nbeacon); |
443 | void ath_paprd_calibrate(struct work_struct *work); | 448 | void ath_paprd_calibrate(struct work_struct *work); |
444 | void ath_ani_calibrate(unsigned long data); | 449 | void ath_ani_calibrate(unsigned long data); |
445 | void ath_start_ani(struct ath_common *common); | 450 | void ath_start_ani(struct ath_softc *sc); |
451 | void ath_stop_ani(struct ath_softc *sc); | ||
452 | void ath_check_ani(struct ath_softc *sc); | ||
446 | int ath_update_survey_stats(struct ath_softc *sc); | 453 | int ath_update_survey_stats(struct ath_softc *sc); |
447 | void ath_update_survey_nf(struct ath_softc *sc, int channel); | 454 | void ath_update_survey_nf(struct ath_softc *sc, int channel); |
455 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); | ||
448 | 456 | ||
449 | /**********/ | 457 | /**********/ |
450 | /* BTCOEX */ | 458 | /* BTCOEX */ |
@@ -510,6 +518,12 @@ static inline void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) | |||
510 | } | 518 | } |
511 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 519 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
512 | 520 | ||
521 | struct ath9k_wow_pattern { | ||
522 | u8 pattern_bytes[MAX_PATTERN_SIZE]; | ||
523 | u8 mask_bytes[MAX_PATTERN_SIZE]; | ||
524 | u32 pattern_len; | ||
525 | }; | ||
526 | |||
513 | /********************/ | 527 | /********************/ |
514 | /* LED Control */ | 528 | /* LED Control */ |
515 | /********************/ | 529 | /********************/ |
@@ -613,7 +627,6 @@ enum sc_op_flags { | |||
613 | SC_OP_INVALID, | 627 | SC_OP_INVALID, |
614 | SC_OP_BEACONS, | 628 | SC_OP_BEACONS, |
615 | SC_OP_RXFLUSH, | 629 | SC_OP_RXFLUSH, |
616 | SC_OP_TSF_RESET, | ||
617 | SC_OP_ANI_RUN, | 630 | SC_OP_ANI_RUN, |
618 | SC_OP_PRIM_STA_VIF, | 631 | SC_OP_PRIM_STA_VIF, |
619 | SC_OP_HW_RESET, | 632 | SC_OP_HW_RESET, |
@@ -711,6 +724,13 @@ struct ath_softc { | |||
711 | struct ath_ant_comb ant_comb; | 724 | struct ath_ant_comb ant_comb; |
712 | u8 ant_tx, ant_rx; | 725 | u8 ant_tx, ant_rx; |
713 | struct dfs_pattern_detector *dfs_detector; | 726 | struct dfs_pattern_detector *dfs_detector; |
727 | u32 wow_enabled; | ||
728 | |||
729 | #ifdef CONFIG_PM_SLEEP | ||
730 | atomic_t wow_got_bmiss_intr; | ||
731 | atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ | ||
732 | u32 wow_intr_before_sleep; | ||
733 | #endif | ||
714 | }; | 734 | }; |
715 | 735 | ||
716 | void ath9k_tasklet(unsigned long data); | 736 | void ath9k_tasklet(unsigned long data); |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 40775da8941e..76f07d8c272d 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -30,7 +30,7 @@ static void ath9k_reset_beacon_status(struct ath_softc *sc) | |||
30 | * the operating mode of the station (AP or AdHoc). Parameters are AIFS | 30 | * the operating mode of the station (AP or AdHoc). Parameters are AIFS |
31 | * settings and channel width min/max | 31 | * settings and channel width min/max |
32 | */ | 32 | */ |
33 | int ath_beaconq_config(struct ath_softc *sc) | 33 | static void ath9k_beaconq_config(struct ath_softc *sc) |
34 | { | 34 | { |
35 | struct ath_hw *ah = sc->sc_ah; | 35 | struct ath_hw *ah = sc->sc_ah; |
36 | struct ath_common *common = ath9k_hw_common(ah); | 36 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -38,6 +38,7 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
38 | struct ath_txq *txq; | 38 | struct ath_txq *txq; |
39 | 39 | ||
40 | ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); | 40 | ath9k_hw_get_txq_props(ah, sc->beacon.beaconq, &qi); |
41 | |||
41 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { | 42 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { |
42 | /* Always burst out beacon and CAB traffic. */ | 43 | /* Always burst out beacon and CAB traffic. */ |
43 | qi.tqi_aifs = 1; | 44 | qi.tqi_aifs = 1; |
@@ -56,12 +57,9 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
56 | } | 57 | } |
57 | 58 | ||
58 | if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { | 59 | if (!ath9k_hw_set_txq_props(ah, sc->beacon.beaconq, &qi)) { |
59 | ath_err(common, | 60 | ath_err(common, "Unable to update h/w beacon queue parameters\n"); |
60 | "Unable to update h/w beacon queue parameters\n"); | ||
61 | return 0; | ||
62 | } else { | 61 | } else { |
63 | ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); | 62 | ath9k_hw_resettxqueue(ah, sc->beacon.beaconq); |
64 | return 1; | ||
65 | } | 63 | } |
66 | } | 64 | } |
67 | 65 | ||
@@ -70,7 +68,7 @@ int ath_beaconq_config(struct ath_softc *sc) | |||
70 | * up rate codes, and channel flags. Beacons are always sent out at the | 68 | * up rate codes, and channel flags. Beacons are always sent out at the |
71 | * lowest rate, and are not retried. | 69 | * lowest rate, and are not retried. |
72 | */ | 70 | */ |
73 | static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | 71 | static void ath9k_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, |
74 | struct ath_buf *bf, int rateidx) | 72 | struct ath_buf *bf, int rateidx) |
75 | { | 73 | { |
76 | struct sk_buff *skb = bf->bf_mpdu; | 74 | struct sk_buff *skb = bf->bf_mpdu; |
@@ -81,8 +79,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
81 | u8 chainmask = ah->txchainmask; | 79 | u8 chainmask = ah->txchainmask; |
82 | u8 rate = 0; | 80 | u8 rate = 0; |
83 | 81 | ||
84 | ath9k_reset_beacon_status(sc); | ||
85 | |||
86 | sband = &sc->sbands[common->hw->conf.channel->band]; | 82 | sband = &sc->sbands[common->hw->conf.channel->band]; |
87 | rate = sband->bitrates[rateidx].hw_value; | 83 | rate = sband->bitrates[rateidx].hw_value; |
88 | if (vif->bss_conf.use_short_preamble) | 84 | if (vif->bss_conf.use_short_preamble) |
@@ -111,7 +107,7 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
111 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); | 107 | ath9k_hw_set_txdesc(ah, bf->bf_desc, &info); |
112 | } | 108 | } |
113 | 109 | ||
114 | static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | 110 | static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) |
115 | { | 111 | { |
116 | struct ath_softc *sc = hw->priv; | 112 | struct ath_softc *sc = hw->priv; |
117 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 113 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -128,28 +124,22 @@ static void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
128 | } | 124 | } |
129 | } | 125 | } |
130 | 126 | ||
131 | static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | 127 | static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, |
132 | struct ieee80211_vif *vif) | 128 | struct ieee80211_vif *vif) |
133 | { | 129 | { |
134 | struct ath_softc *sc = hw->priv; | 130 | struct ath_softc *sc = hw->priv; |
135 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 131 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
136 | struct ath_buf *bf; | 132 | struct ath_buf *bf; |
137 | struct ath_vif *avp; | 133 | struct ath_vif *avp = (void *)vif->drv_priv; |
138 | struct sk_buff *skb; | 134 | struct sk_buff *skb; |
139 | struct ath_txq *cabq; | 135 | struct ath_txq *cabq = sc->beacon.cabq; |
140 | struct ieee80211_tx_info *info; | 136 | struct ieee80211_tx_info *info; |
137 | struct ieee80211_mgmt *mgmt_hdr; | ||
141 | int cabq_depth; | 138 | int cabq_depth; |
142 | 139 | ||
143 | ath9k_reset_beacon_status(sc); | 140 | if (avp->av_bcbuf == NULL) |
144 | |||
145 | avp = (void *)vif->drv_priv; | ||
146 | cabq = sc->beacon.cabq; | ||
147 | |||
148 | if ((avp->av_bcbuf == NULL) || !avp->is_bslot_active) | ||
149 | return NULL; | 141 | return NULL; |
150 | 142 | ||
151 | /* Release the old beacon first */ | ||
152 | |||
153 | bf = avp->av_bcbuf; | 143 | bf = avp->av_bcbuf; |
154 | skb = bf->bf_mpdu; | 144 | skb = bf->bf_mpdu; |
155 | if (skb) { | 145 | if (skb) { |
@@ -159,14 +149,14 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
159 | bf->bf_buf_addr = 0; | 149 | bf->bf_buf_addr = 0; |
160 | } | 150 | } |
161 | 151 | ||
162 | /* Get a new beacon from mac80211 */ | ||
163 | |||
164 | skb = ieee80211_beacon_get(hw, vif); | 152 | skb = ieee80211_beacon_get(hw, vif); |
165 | bf->bf_mpdu = skb; | ||
166 | if (skb == NULL) | 153 | if (skb == NULL) |
167 | return NULL; | 154 | return NULL; |
168 | ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = | 155 | |
169 | avp->tsf_adjust; | 156 | bf->bf_mpdu = skb; |
157 | |||
158 | mgmt_hdr = (struct ieee80211_mgmt *)skb->data; | ||
159 | mgmt_hdr->u.beacon.timestamp = avp->tsf_adjust; | ||
170 | 160 | ||
171 | info = IEEE80211_SKB_CB(skb); | 161 | info = IEEE80211_SKB_CB(skb); |
172 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 162 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
@@ -212,61 +202,52 @@ static struct ath_buf *ath_beacon_generate(struct ieee80211_hw *hw, | |||
212 | } | 202 | } |
213 | } | 203 | } |
214 | 204 | ||
215 | ath_beacon_setup(sc, vif, bf, info->control.rates[0].idx); | 205 | ath9k_beacon_setup(sc, vif, bf, info->control.rates[0].idx); |
216 | 206 | ||
217 | while (skb) { | 207 | while (skb) { |
218 | ath_tx_cabq(hw, skb); | 208 | ath9k_tx_cabq(hw, skb); |
219 | skb = ieee80211_get_buffered_bc(hw, vif); | 209 | skb = ieee80211_get_buffered_bc(hw, vif); |
220 | } | 210 | } |
221 | 211 | ||
222 | return bf; | 212 | return bf; |
223 | } | 213 | } |
224 | 214 | ||
225 | int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | 215 | void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif) |
226 | { | 216 | { |
227 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 217 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
228 | struct ath_vif *avp; | 218 | struct ath_vif *avp = (void *)vif->drv_priv; |
229 | struct ath_buf *bf; | 219 | int slot; |
230 | struct sk_buff *skb; | 220 | |
231 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 221 | avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, struct ath_buf, list); |
232 | __le64 tstamp; | 222 | list_del(&avp->av_bcbuf->list); |
233 | 223 | ||
234 | avp = (void *)vif->drv_priv; | 224 | for (slot = 0; slot < ATH_BCBUF; slot++) { |
235 | 225 | if (sc->beacon.bslot[slot] == NULL) { | |
236 | /* Allocate a beacon descriptor if we haven't done so. */ | 226 | avp->av_bslot = slot; |
237 | if (!avp->av_bcbuf) { | 227 | break; |
238 | /* Allocate beacon state for hostap/ibss. We know | ||
239 | * a buffer is available. */ | ||
240 | avp->av_bcbuf = list_first_entry(&sc->beacon.bbuf, | ||
241 | struct ath_buf, list); | ||
242 | list_del(&avp->av_bcbuf->list); | ||
243 | |||
244 | if (ath9k_uses_beacons(vif->type)) { | ||
245 | int slot; | ||
246 | /* | ||
247 | * Assign the vif to a beacon xmit slot. As | ||
248 | * above, this cannot fail to find one. | ||
249 | */ | ||
250 | avp->av_bslot = 0; | ||
251 | for (slot = 0; slot < ATH_BCBUF; slot++) | ||
252 | if (sc->beacon.bslot[slot] == NULL) { | ||
253 | avp->av_bslot = slot; | ||
254 | avp->is_bslot_active = false; | ||
255 | |||
256 | /* NB: keep looking for a double slot */ | ||
257 | if (slot == 0 || !sc->beacon.bslot[slot-1]) | ||
258 | break; | ||
259 | } | ||
260 | BUG_ON(sc->beacon.bslot[avp->av_bslot] != NULL); | ||
261 | sc->beacon.bslot[avp->av_bslot] = vif; | ||
262 | sc->nbcnvifs++; | ||
263 | } | 228 | } |
264 | } | 229 | } |
265 | 230 | ||
266 | /* release the previous beacon frame, if it already exists. */ | 231 | sc->beacon.bslot[avp->av_bslot] = vif; |
267 | bf = avp->av_bcbuf; | 232 | sc->nbcnvifs++; |
268 | if (bf->bf_mpdu != NULL) { | 233 | |
269 | skb = bf->bf_mpdu; | 234 | ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", |
235 | avp->av_bslot); | ||
236 | } | ||
237 | |||
238 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif) | ||
239 | { | ||
240 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
241 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
242 | struct ath_buf *bf = avp->av_bcbuf; | ||
243 | |||
244 | ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", | ||
245 | avp->av_bslot); | ||
246 | |||
247 | tasklet_disable(&sc->bcon_tasklet); | ||
248 | |||
249 | if (bf && bf->bf_mpdu) { | ||
250 | struct sk_buff *skb = bf->bf_mpdu; | ||
270 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 251 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
271 | skb->len, DMA_TO_DEVICE); | 252 | skb->len, DMA_TO_DEVICE); |
272 | dev_kfree_skb_any(skb); | 253 | dev_kfree_skb_any(skb); |
@@ -274,99 +255,74 @@ int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
274 | bf->bf_buf_addr = 0; | 255 | bf->bf_buf_addr = 0; |
275 | } | 256 | } |
276 | 257 | ||
277 | /* NB: the beacon data buffer must be 32-bit aligned. */ | 258 | avp->av_bcbuf = NULL; |
278 | skb = ieee80211_beacon_get(sc->hw, vif); | 259 | sc->beacon.bslot[avp->av_bslot] = NULL; |
279 | if (skb == NULL) | 260 | sc->nbcnvifs--; |
280 | return -ENOMEM; | 261 | list_add_tail(&bf->list, &sc->beacon.bbuf); |
281 | 262 | ||
282 | tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; | 263 | tasklet_enable(&sc->bcon_tasklet); |
283 | sc->beacon.bc_tstamp = (u32) le64_to_cpu(tstamp); | 264 | } |
284 | /* Calculate a TSF adjustment factor required for staggered beacons. */ | ||
285 | if (avp->av_bslot > 0) { | ||
286 | u64 tsfadjust; | ||
287 | int intval; | ||
288 | |||
289 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; | ||
290 | 265 | ||
291 | /* | 266 | static int ath9k_beacon_choose_slot(struct ath_softc *sc) |
292 | * Calculate the TSF offset for this beacon slot, i.e., the | 267 | { |
293 | * number of usecs that need to be added to the timestamp field | 268 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
294 | * in Beacon and Probe Response frames. Beacon slot 0 is | 269 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
295 | * processed at the correct offset, so it does not require TSF | 270 | u16 intval; |
296 | * adjustment. Other slots are adjusted to get the timestamp | 271 | u32 tsftu; |
297 | * close to the TBTT for the BSS. | 272 | u64 tsf; |
298 | */ | 273 | int slot; |
299 | tsfadjust = TU_TO_USEC(intval * avp->av_bslot) / ATH_BCBUF; | ||
300 | avp->tsf_adjust = cpu_to_le64(tsfadjust); | ||
301 | 274 | ||
302 | ath_dbg(common, BEACON, | 275 | if (sc->sc_ah->opmode != NL80211_IFTYPE_AP) { |
303 | "stagger beacons, bslot %d intval %u tsfadjust %llu\n", | 276 | ath_dbg(common, BEACON, "slot 0, tsf: %llu\n", |
304 | avp->av_bslot, intval, (unsigned long long)tsfadjust); | 277 | ath9k_hw_gettsf64(sc->sc_ah)); |
278 | return 0; | ||
279 | } | ||
305 | 280 | ||
306 | ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp = | 281 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; |
307 | avp->tsf_adjust; | 282 | tsf = ath9k_hw_gettsf64(sc->sc_ah); |
308 | } else | 283 | tsf += TU_TO_USEC(sc->sc_ah->config.sw_beacon_response_time); |
309 | avp->tsf_adjust = cpu_to_le64(0); | 284 | tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); |
285 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; | ||
310 | 286 | ||
311 | bf->bf_mpdu = skb; | 287 | ath_dbg(common, BEACON, "slot: %d tsf: %llu tsftu: %u\n", |
312 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 288 | slot, tsf, tsftu / ATH_BCBUF); |
313 | skb->len, DMA_TO_DEVICE); | ||
314 | if (unlikely(dma_mapping_error(sc->dev, bf->bf_buf_addr))) { | ||
315 | dev_kfree_skb_any(skb); | ||
316 | bf->bf_mpdu = NULL; | ||
317 | bf->bf_buf_addr = 0; | ||
318 | ath_err(common, "dma_mapping_error on beacon alloc\n"); | ||
319 | return -ENOMEM; | ||
320 | } | ||
321 | avp->is_bslot_active = true; | ||
322 | 289 | ||
323 | return 0; | 290 | return slot; |
324 | } | 291 | } |
325 | 292 | ||
326 | void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp) | 293 | void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) |
327 | { | 294 | { |
328 | if (avp->av_bcbuf != NULL) { | 295 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
329 | struct ath_buf *bf; | 296 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
330 | 297 | struct ath_vif *avp = (void *)vif->drv_priv; | |
331 | avp->is_bslot_active = false; | 298 | u64 tsfadjust; |
332 | if (avp->av_bslot != -1) { | ||
333 | sc->beacon.bslot[avp->av_bslot] = NULL; | ||
334 | sc->nbcnvifs--; | ||
335 | avp->av_bslot = -1; | ||
336 | } | ||
337 | 299 | ||
338 | bf = avp->av_bcbuf; | 300 | if (avp->av_bslot == 0) |
339 | if (bf->bf_mpdu != NULL) { | 301 | return; |
340 | struct sk_buff *skb = bf->bf_mpdu; | ||
341 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | ||
342 | skb->len, DMA_TO_DEVICE); | ||
343 | dev_kfree_skb_any(skb); | ||
344 | bf->bf_mpdu = NULL; | ||
345 | bf->bf_buf_addr = 0; | ||
346 | } | ||
347 | list_add_tail(&bf->list, &sc->beacon.bbuf); | ||
348 | 302 | ||
349 | avp->av_bcbuf = NULL; | 303 | tsfadjust = cur_conf->beacon_interval * avp->av_bslot / ATH_BCBUF; |
350 | } | 304 | avp->tsf_adjust = cpu_to_le64(TU_TO_USEC(tsfadjust)); |
305 | |||
306 | ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", | ||
307 | (unsigned long long)tsfadjust, avp->av_bslot); | ||
351 | } | 308 | } |
352 | 309 | ||
353 | void ath_beacon_tasklet(unsigned long data) | 310 | void ath9k_beacon_tasklet(unsigned long data) |
354 | { | 311 | { |
355 | struct ath_softc *sc = (struct ath_softc *)data; | 312 | struct ath_softc *sc = (struct ath_softc *)data; |
356 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
357 | struct ath_hw *ah = sc->sc_ah; | 313 | struct ath_hw *ah = sc->sc_ah; |
358 | struct ath_common *common = ath9k_hw_common(ah); | 314 | struct ath_common *common = ath9k_hw_common(ah); |
359 | struct ath_buf *bf = NULL; | 315 | struct ath_buf *bf = NULL; |
360 | struct ieee80211_vif *vif; | 316 | struct ieee80211_vif *vif; |
361 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 317 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
362 | int slot; | 318 | int slot; |
363 | u32 bfaddr, bc = 0; | ||
364 | 319 | ||
365 | if (work_pending(&sc->hw_reset_work)) { | 320 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { |
366 | ath_dbg(common, RESET, | 321 | ath_dbg(common, RESET, |
367 | "reset work is pending, skip beaconing now\n"); | 322 | "reset work is pending, skip beaconing now\n"); |
368 | return; | 323 | return; |
369 | } | 324 | } |
325 | |||
370 | /* | 326 | /* |
371 | * Check if the previous beacon has gone out. If | 327 | * Check if the previous beacon has gone out. If |
372 | * not don't try to post another, skip this period | 328 | * not don't try to post another, skip this period |
@@ -390,55 +346,25 @@ void ath_beacon_tasklet(unsigned long data) | |||
390 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { | 346 | } else if (sc->beacon.bmisscnt >= BSTUCK_THRESH) { |
391 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); | 347 | ath_dbg(common, BSTUCK, "beacon is officially stuck\n"); |
392 | sc->beacon.bmisscnt = 0; | 348 | sc->beacon.bmisscnt = 0; |
393 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | 349 | ath9k_queue_reset(sc, RESET_TYPE_BEACON_STUCK); |
394 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
395 | } | 350 | } |
396 | 351 | ||
397 | return; | 352 | return; |
398 | } | 353 | } |
399 | 354 | ||
400 | /* | 355 | slot = ath9k_beacon_choose_slot(sc); |
401 | * Generate beacon frames. we are sending frames | 356 | vif = sc->beacon.bslot[slot]; |
402 | * staggered so calculate the slot for this frame based | ||
403 | * on the tsf to safeguard against missing an swba. | ||
404 | */ | ||
405 | |||
406 | |||
407 | if (ah->opmode == NL80211_IFTYPE_AP) { | ||
408 | u16 intval; | ||
409 | u32 tsftu; | ||
410 | u64 tsf; | ||
411 | |||
412 | intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL; | ||
413 | tsf = ath9k_hw_gettsf64(ah); | ||
414 | tsf += TU_TO_USEC(ah->config.sw_beacon_response_time); | ||
415 | tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF); | ||
416 | slot = (tsftu % (intval * ATH_BCBUF)) / intval; | ||
417 | vif = sc->beacon.bslot[slot]; | ||
418 | |||
419 | ath_dbg(common, BEACON, | ||
420 | "slot %d [tsf %llu tsftu %u intval %u] vif %p\n", | ||
421 | slot, tsf, tsftu / ATH_BCBUF, intval, vif); | ||
422 | } else { | ||
423 | slot = 0; | ||
424 | vif = sc->beacon.bslot[slot]; | ||
425 | } | ||
426 | 357 | ||
358 | if (!vif || !vif->bss_conf.enable_beacon) | ||
359 | return; | ||
427 | 360 | ||
428 | bfaddr = 0; | 361 | bf = ath9k_beacon_generate(sc->hw, vif); |
429 | if (vif) { | 362 | WARN_ON(!bf); |
430 | bf = ath_beacon_generate(sc->hw, vif); | ||
431 | if (bf != NULL) { | ||
432 | bfaddr = bf->bf_daddr; | ||
433 | bc = 1; | ||
434 | } | ||
435 | 363 | ||
436 | if (sc->beacon.bmisscnt != 0) { | 364 | if (sc->beacon.bmisscnt != 0) { |
437 | ath_dbg(common, BSTUCK, | 365 | ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n", |
438 | "resume beacon xmit after %u misses\n", | 366 | sc->beacon.bmisscnt); |
439 | sc->beacon.bmisscnt); | 367 | sc->beacon.bmisscnt = 0; |
440 | sc->beacon.bmisscnt = 0; | ||
441 | } | ||
442 | } | 368 | } |
443 | 369 | ||
444 | /* | 370 | /* |
@@ -458,39 +384,40 @@ void ath_beacon_tasklet(unsigned long data) | |||
458 | * set to ATH_BCBUF so this check is a noop. | 384 | * set to ATH_BCBUF so this check is a noop. |
459 | */ | 385 | */ |
460 | if (sc->beacon.updateslot == UPDATE) { | 386 | if (sc->beacon.updateslot == UPDATE) { |
461 | sc->beacon.updateslot = COMMIT; /* commit next beacon */ | 387 | sc->beacon.updateslot = COMMIT; |
462 | sc->beacon.slotupdate = slot; | 388 | sc->beacon.slotupdate = slot; |
463 | } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { | 389 | } else if (sc->beacon.updateslot == COMMIT && |
390 | sc->beacon.slotupdate == slot) { | ||
464 | ah->slottime = sc->beacon.slottime; | 391 | ah->slottime = sc->beacon.slottime; |
465 | ath9k_hw_init_global_settings(ah); | 392 | ath9k_hw_init_global_settings(ah); |
466 | sc->beacon.updateslot = OK; | 393 | sc->beacon.updateslot = OK; |
467 | } | 394 | } |
468 | if (bfaddr != 0) { | 395 | |
396 | if (bf) { | ||
397 | ath9k_reset_beacon_status(sc); | ||
398 | |||
399 | ath_dbg(common, BEACON, | ||
400 | "Transmitting beacon for slot: %d\n", slot); | ||
401 | |||
469 | /* NB: cabq traffic should already be queued and primed */ | 402 | /* NB: cabq traffic should already be queued and primed */ |
470 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bfaddr); | 403 | ath9k_hw_puttxbuf(ah, sc->beacon.beaconq, bf->bf_daddr); |
471 | 404 | ||
472 | if (!edma) | 405 | if (!edma) |
473 | ath9k_hw_txstart(ah, sc->beacon.beaconq); | 406 | ath9k_hw_txstart(ah, sc->beacon.beaconq); |
474 | |||
475 | sc->beacon.ast_be_xmit += bc; /* XXX per-vif? */ | ||
476 | } | 407 | } |
477 | } | 408 | } |
478 | 409 | ||
479 | static void ath9k_beacon_init(struct ath_softc *sc, | 410 | static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, u32 intval) |
480 | u32 next_beacon, | ||
481 | u32 beacon_period) | ||
482 | { | 411 | { |
483 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { | 412 | struct ath_hw *ah = sc->sc_ah; |
484 | ath9k_ps_wakeup(sc); | ||
485 | ath9k_hw_reset_tsf(sc->sc_ah); | ||
486 | } | ||
487 | |||
488 | ath9k_hw_beaconinit(sc->sc_ah, next_beacon, beacon_period); | ||
489 | 413 | ||
490 | if (test_bit(SC_OP_TSF_RESET, &sc->sc_flags)) { | 414 | ath9k_hw_disable_interrupts(ah); |
491 | ath9k_ps_restore(sc); | 415 | ath9k_hw_reset_tsf(ah); |
492 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); | 416 | ath9k_beaconq_config(sc); |
493 | } | 417 | ath9k_hw_beaconinit(ah, nexttbtt, intval); |
418 | sc->beacon.bmisscnt = 0; | ||
419 | ath9k_hw_set_interrupts(ah); | ||
420 | ath9k_hw_enable_interrupts(ah); | ||
494 | } | 421 | } |
495 | 422 | ||
496 | /* | 423 | /* |
@@ -498,32 +425,27 @@ static void ath9k_beacon_init(struct ath_softc *sc, | |||
498 | * burst together. For the former arrange for the SWBA to be delivered for each | 425 | * burst together. For the former arrange for the SWBA to be delivered for each |
499 | * slot. Slots that are not occupied will generate nothing. | 426 | * slot. Slots that are not occupied will generate nothing. |
500 | */ | 427 | */ |
501 | static void ath_beacon_config_ap(struct ath_softc *sc, | 428 | static void ath9k_beacon_config_ap(struct ath_softc *sc, |
502 | struct ath_beacon_config *conf) | 429 | struct ath_beacon_config *conf) |
503 | { | 430 | { |
504 | struct ath_hw *ah = sc->sc_ah; | 431 | struct ath_hw *ah = sc->sc_ah; |
432 | struct ath_common *common = ath9k_hw_common(ah); | ||
505 | u32 nexttbtt, intval; | 433 | u32 nexttbtt, intval; |
506 | 434 | ||
507 | /* NB: the beacon interval is kept internally in TU's */ | 435 | /* NB: the beacon interval is kept internally in TU's */ |
508 | intval = TU_TO_USEC(conf->beacon_interval); | 436 | intval = TU_TO_USEC(conf->beacon_interval); |
509 | intval /= ATH_BCBUF; /* for staggered beacons */ | 437 | intval /= ATH_BCBUF; |
510 | nexttbtt = intval; | 438 | nexttbtt = intval; |
511 | 439 | ||
512 | /* | 440 | if (conf->enable_beacon) |
513 | * In AP mode we enable the beacon timers and SWBA interrupts to | 441 | ah->imask |= ATH9K_INT_SWBA; |
514 | * prepare beacon frames. | 442 | else |
515 | */ | 443 | ah->imask &= ~ATH9K_INT_SWBA; |
516 | ah->imask |= ATH9K_INT_SWBA; | ||
517 | ath_beaconq_config(sc); | ||
518 | 444 | ||
519 | /* Set the computed AP beacon timers */ | 445 | ath_dbg(common, BEACON, "AP nexttbtt: %u intval: %u conf_intval: %u\n", |
446 | nexttbtt, intval, conf->beacon_interval); | ||
520 | 447 | ||
521 | ath9k_hw_disable_interrupts(ah); | ||
522 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | ||
523 | ath9k_beacon_init(sc, nexttbtt, intval); | 448 | ath9k_beacon_init(sc, nexttbtt, intval); |
524 | sc->beacon.bmisscnt = 0; | ||
525 | ath9k_hw_set_interrupts(ah); | ||
526 | ath9k_hw_enable_interrupts(ah); | ||
527 | } | 449 | } |
528 | 450 | ||
529 | /* | 451 | /* |
@@ -534,8 +456,8 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
534 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP | 456 | * we'll receive a BMISS interrupt when we stop seeing beacons from the AP |
535 | * we've associated with. | 457 | * we've associated with. |
536 | */ | 458 | */ |
537 | static void ath_beacon_config_sta(struct ath_softc *sc, | 459 | static void ath9k_beacon_config_sta(struct ath_softc *sc, |
538 | struct ath_beacon_config *conf) | 460 | struct ath_beacon_config *conf) |
539 | { | 461 | { |
540 | struct ath_hw *ah = sc->sc_ah; | 462 | struct ath_hw *ah = sc->sc_ah; |
541 | struct ath_common *common = ath9k_hw_common(ah); | 463 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -547,7 +469,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
547 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; | 469 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; |
548 | 470 | ||
549 | /* No need to configure beacon if we are not associated */ | 471 | /* No need to configure beacon if we are not associated */ |
550 | if (!common->curaid) { | 472 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
551 | ath_dbg(common, BEACON, | 473 | ath_dbg(common, BEACON, |
552 | "STA is not yet associated..skipping beacon config\n"); | 474 | "STA is not yet associated..skipping beacon config\n"); |
553 | return; | 475 | return; |
@@ -654,97 +576,65 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
654 | ath9k_hw_enable_interrupts(ah); | 576 | ath9k_hw_enable_interrupts(ah); |
655 | } | 577 | } |
656 | 578 | ||
657 | static void ath_beacon_config_adhoc(struct ath_softc *sc, | 579 | static void ath9k_beacon_config_adhoc(struct ath_softc *sc, |
658 | struct ath_beacon_config *conf) | 580 | struct ath_beacon_config *conf) |
659 | { | 581 | { |
660 | struct ath_hw *ah = sc->sc_ah; | 582 | struct ath_hw *ah = sc->sc_ah; |
661 | struct ath_common *common = ath9k_hw_common(ah); | 583 | struct ath_common *common = ath9k_hw_common(ah); |
662 | u32 tsf, intval, nexttbtt; | 584 | u32 intval, nexttbtt; |
663 | 585 | ||
664 | ath9k_reset_beacon_status(sc); | 586 | ath9k_reset_beacon_status(sc); |
665 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | ||
666 | ath9k_hw_settsf64(ah, sc->beacon.bc_tstamp); | ||
667 | 587 | ||
668 | intval = TU_TO_USEC(conf->beacon_interval); | 588 | intval = TU_TO_USEC(conf->beacon_interval); |
669 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); | 589 | nexttbtt = intval; |
670 | nexttbtt = tsf + intval; | ||
671 | |||
672 | ath_dbg(common, BEACON, "IBSS nexttbtt %u intval %u (%u)\n", | ||
673 | nexttbtt, intval, conf->beacon_interval); | ||
674 | |||
675 | /* | ||
676 | * In IBSS mode enable the beacon timers but only enable SWBA interrupts | ||
677 | * if we need to manually prepare beacon frames. Otherwise we use a | ||
678 | * self-linked tx descriptor and let the hardware deal with things. | ||
679 | */ | ||
680 | ah->imask |= ATH9K_INT_SWBA; | ||
681 | 590 | ||
682 | ath_beaconq_config(sc); | 591 | if (conf->enable_beacon) |
592 | ah->imask |= ATH9K_INT_SWBA; | ||
593 | else | ||
594 | ah->imask &= ~ATH9K_INT_SWBA; | ||
683 | 595 | ||
684 | /* Set the computed ADHOC beacon timers */ | 596 | ath_dbg(common, BEACON, "IBSS nexttbtt: %u intval: %u conf_intval: %u\n", |
597 | nexttbtt, intval, conf->beacon_interval); | ||
685 | 598 | ||
686 | ath9k_hw_disable_interrupts(ah); | ||
687 | ath9k_beacon_init(sc, nexttbtt, intval); | 599 | ath9k_beacon_init(sc, nexttbtt, intval); |
688 | sc->beacon.bmisscnt = 0; | ||
689 | |||
690 | ath9k_hw_set_interrupts(ah); | ||
691 | ath9k_hw_enable_interrupts(ah); | ||
692 | } | 600 | } |
693 | 601 | ||
694 | static bool ath9k_allow_beacon_config(struct ath_softc *sc, | 602 | bool ath9k_allow_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) |
695 | struct ieee80211_vif *vif) | ||
696 | { | 603 | { |
697 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
698 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 604 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
699 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
700 | struct ath_vif *avp = (void *)vif->drv_priv; | 605 | struct ath_vif *avp = (void *)vif->drv_priv; |
701 | 606 | ||
702 | /* | 607 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { |
703 | * Can not have different beacon interval on multiple | 608 | if ((vif->type != NL80211_IFTYPE_AP) || |
704 | * AP interface case | 609 | (sc->nbcnvifs > 1)) { |
705 | */ | 610 | ath_dbg(common, CONFIG, |
706 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | 611 | "An AP interface is already present !\n"); |
707 | (sc->nbcnvifs > 1) && | 612 | return false; |
708 | (vif->type == NL80211_IFTYPE_AP) && | 613 | } |
709 | (cur_conf->beacon_interval != bss_conf->beacon_int)) { | ||
710 | ath_dbg(common, CONFIG, | ||
711 | "Changing beacon interval of multiple AP interfaces !\n"); | ||
712 | return false; | ||
713 | } | ||
714 | /* | ||
715 | * Can not configure station vif's beacon config | ||
716 | * while on AP opmode | ||
717 | */ | ||
718 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) && | ||
719 | (vif->type != NL80211_IFTYPE_AP)) { | ||
720 | ath_dbg(common, CONFIG, | ||
721 | "STA vif's beacon not allowed on AP mode\n"); | ||
722 | return false; | ||
723 | } | 614 | } |
724 | /* | 615 | |
725 | * Do not allow beacon config if HW was already configured | 616 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { |
726 | * with another STA vif | 617 | if ((vif->type == NL80211_IFTYPE_STATION) && |
727 | */ | 618 | test_bit(SC_OP_BEACONS, &sc->sc_flags) && |
728 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 619 | !avp->primary_sta_vif) { |
729 | (vif->type == NL80211_IFTYPE_STATION) && | 620 | ath_dbg(common, CONFIG, |
730 | test_bit(SC_OP_BEACONS, &sc->sc_flags) && | 621 | "Beacon already configured for a station interface\n"); |
731 | !avp->primary_sta_vif) { | 622 | return false; |
732 | ath_dbg(common, CONFIG, | 623 | } |
733 | "Beacon already configured for a station interface\n"); | ||
734 | return false; | ||
735 | } | 624 | } |
625 | |||
736 | return true; | 626 | return true; |
737 | } | 627 | } |
738 | 628 | ||
739 | void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | 629 | static void ath9k_cache_beacon_config(struct ath_softc *sc, |
630 | struct ieee80211_bss_conf *bss_conf) | ||
740 | { | 631 | { |
632 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
741 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 633 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
742 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
743 | 634 | ||
744 | if (!ath9k_allow_beacon_config(sc, vif)) | 635 | ath_dbg(common, BEACON, |
745 | return; | 636 | "Caching beacon data for BSS: %pM\n", bss_conf->bssid); |
746 | 637 | ||
747 | /* Setup the beacon configuration parameters */ | ||
748 | cur_conf->beacon_interval = bss_conf->beacon_int; | 638 | cur_conf->beacon_interval = bss_conf->beacon_int; |
749 | cur_conf->dtim_period = bss_conf->dtim_period; | 639 | cur_conf->dtim_period = bss_conf->dtim_period; |
750 | cur_conf->listen_interval = 1; | 640 | cur_conf->listen_interval = 1; |
@@ -769,73 +659,62 @@ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
769 | if (cur_conf->dtim_period == 0) | 659 | if (cur_conf->dtim_period == 0) |
770 | cur_conf->dtim_period = 1; | 660 | cur_conf->dtim_period = 1; |
771 | 661 | ||
772 | ath_set_beacon(sc); | ||
773 | } | 662 | } |
774 | 663 | ||
775 | static bool ath_has_valid_bslot(struct ath_softc *sc) | 664 | void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, |
665 | u32 changed) | ||
776 | { | 666 | { |
777 | struct ath_vif *avp; | 667 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
778 | int slot; | 668 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
779 | bool found = false; | ||
780 | 669 | ||
781 | for (slot = 0; slot < ATH_BCBUF; slot++) { | 670 | if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { |
782 | if (sc->beacon.bslot[slot]) { | 671 | ath9k_cache_beacon_config(sc, bss_conf); |
783 | avp = (void *)sc->beacon.bslot[slot]->drv_priv; | 672 | ath9k_set_beacon(sc); |
784 | if (avp->is_bslot_active) { | 673 | set_bit(SC_OP_BEACONS, &sc->sc_flags); |
785 | found = true; | 674 | } else { |
786 | break; | 675 | /* |
676 | * Take care of multiple interfaces when | ||
677 | * enabling/disabling SWBA. | ||
678 | */ | ||
679 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | ||
680 | if (!bss_conf->enable_beacon && | ||
681 | (sc->nbcnvifs <= 1)) { | ||
682 | cur_conf->enable_beacon = false; | ||
683 | } else if (bss_conf->enable_beacon) { | ||
684 | cur_conf->enable_beacon = true; | ||
685 | ath9k_cache_beacon_config(sc, bss_conf); | ||
787 | } | 686 | } |
788 | } | 687 | } |
688 | |||
689 | if (cur_conf->beacon_interval) { | ||
690 | ath9k_set_beacon(sc); | ||
691 | |||
692 | if (cur_conf->enable_beacon) | ||
693 | set_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
694 | else | ||
695 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
696 | } | ||
789 | } | 697 | } |
790 | return found; | ||
791 | } | 698 | } |
792 | 699 | ||
793 | 700 | void ath9k_set_beacon(struct ath_softc *sc) | |
794 | void ath_set_beacon(struct ath_softc *sc) | ||
795 | { | 701 | { |
796 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 702 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
797 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | 703 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; |
798 | 704 | ||
799 | switch (sc->sc_ah->opmode) { | 705 | switch (sc->sc_ah->opmode) { |
800 | case NL80211_IFTYPE_AP: | 706 | case NL80211_IFTYPE_AP: |
801 | if (ath_has_valid_bslot(sc)) | 707 | ath9k_beacon_config_ap(sc, cur_conf); |
802 | ath_beacon_config_ap(sc, cur_conf); | ||
803 | break; | 708 | break; |
804 | case NL80211_IFTYPE_ADHOC: | 709 | case NL80211_IFTYPE_ADHOC: |
805 | case NL80211_IFTYPE_MESH_POINT: | 710 | case NL80211_IFTYPE_MESH_POINT: |
806 | ath_beacon_config_adhoc(sc, cur_conf); | 711 | ath9k_beacon_config_adhoc(sc, cur_conf); |
807 | break; | 712 | break; |
808 | case NL80211_IFTYPE_STATION: | 713 | case NL80211_IFTYPE_STATION: |
809 | ath_beacon_config_sta(sc, cur_conf); | 714 | ath9k_beacon_config_sta(sc, cur_conf); |
810 | break; | 715 | break; |
811 | default: | 716 | default: |
812 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); | 717 | ath_dbg(common, CONFIG, "Unsupported beaconing mode\n"); |
813 | return; | 718 | return; |
814 | } | 719 | } |
815 | |||
816 | set_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
817 | } | ||
818 | |||
819 | void ath9k_set_beaconing_status(struct ath_softc *sc, bool status) | ||
820 | { | ||
821 | struct ath_hw *ah = sc->sc_ah; | ||
822 | |||
823 | if (!ath_has_valid_bslot(sc)) { | ||
824 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
825 | return; | ||
826 | } | ||
827 | |||
828 | ath9k_ps_wakeup(sc); | ||
829 | if (status) { | ||
830 | /* Re-enable beaconing */ | ||
831 | ah->imask |= ATH9K_INT_SWBA; | ||
832 | ath9k_hw_set_interrupts(ah); | ||
833 | } else { | ||
834 | /* Disable SWBA interrupt */ | ||
835 | ah->imask &= ~ATH9K_INT_SWBA; | ||
836 | ath9k_hw_set_interrupts(ah); | ||
837 | tasklet_kill(&sc->bcon_tasklet); | ||
838 | ath9k_hw_stop_dma_queue(ah, sc->beacon.beaconq); | ||
839 | } | ||
840 | ath9k_ps_restore(sc); | ||
841 | } | 720 | } |
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index 3b33996d97df..1060c19a5012 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
@@ -30,10 +30,10 @@ struct ar5416IniArray { | |||
30 | u32 ia_columns; | 30 | u32 ia_columns; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \ | 33 | #define INIT_INI_ARRAY(iniarray, array) do { \ |
34 | (iniarray)->ia_array = (u32 *)(array); \ | 34 | (iniarray)->ia_array = (u32 *)(array); \ |
35 | (iniarray)->ia_rows = (rows); \ | 35 | (iniarray)->ia_rows = ARRAY_SIZE(array); \ |
36 | (iniarray)->ia_columns = (columns); \ | 36 | (iniarray)->ia_columns = ARRAY_SIZE(array[0]); \ |
37 | } while (0) | 37 | } while (0) |
38 | 38 | ||
39 | #define INI_RA(iniarray, row, column) \ | 39 | #define INI_RA(iniarray, row, column) \ |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 5c3192ffc196..68b643c8943c 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -206,10 +206,9 @@ static ssize_t write_file_disable_ani(struct file *file, | |||
206 | 206 | ||
207 | if (disable_ani) { | 207 | if (disable_ani) { |
208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 208 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); |
209 | del_timer_sync(&common->ani.timer); | 209 | ath_stop_ani(sc); |
210 | } else { | 210 | } else { |
211 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 211 | ath_check_ani(sc); |
212 | ath_start_ani(common); | ||
213 | } | 212 | } |
214 | 213 | ||
215 | return count; | 214 | return count; |
@@ -1556,6 +1555,14 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1556 | &fops_interrupt); | 1555 | &fops_interrupt); |
1557 | debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, | 1556 | debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, sc, |
1558 | &fops_xmit); | 1557 | &fops_xmit); |
1558 | debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1559 | &sc->tx.txq_max_pending[WME_AC_BK]); | ||
1560 | debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1561 | &sc->tx.txq_max_pending[WME_AC_BE]); | ||
1562 | debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1563 | &sc->tx.txq_max_pending[WME_AC_VI]); | ||
1564 | debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1565 | &sc->tx.txq_max_pending[WME_AC_VO]); | ||
1559 | debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, | 1566 | debugfs_create_file("stations", S_IRUSR, sc->debug.debugfs_phy, sc, |
1560 | &fops_stations); | 1567 | &fops_stations); |
1561 | debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, | 1568 | debugfs_create_file("misc", S_IRUSR, sc->debug.debugfs_phy, sc, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index d0f851cea43a..8b9d080d89da 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -32,6 +32,19 @@ struct ath_buf; | |||
32 | #define RESET_STAT_INC(sc, type) do { } while (0) | 32 | #define RESET_STAT_INC(sc, type) do { } while (0) |
33 | #endif | 33 | #endif |
34 | 34 | ||
35 | enum ath_reset_type { | ||
36 | RESET_TYPE_BB_HANG, | ||
37 | RESET_TYPE_BB_WATCHDOG, | ||
38 | RESET_TYPE_FATAL_INT, | ||
39 | RESET_TYPE_TX_ERROR, | ||
40 | RESET_TYPE_TX_HANG, | ||
41 | RESET_TYPE_PLL_HANG, | ||
42 | RESET_TYPE_MAC_HANG, | ||
43 | RESET_TYPE_BEACON_STUCK, | ||
44 | RESET_TYPE_MCI, | ||
45 | __RESET_TYPE_MAX | ||
46 | }; | ||
47 | |||
35 | #ifdef CONFIG_ATH9K_DEBUGFS | 48 | #ifdef CONFIG_ATH9K_DEBUGFS |
36 | 49 | ||
37 | /** | 50 | /** |
@@ -209,17 +222,6 @@ struct ath_rx_stats { | |||
209 | u32 rx_frags; | 222 | u32 rx_frags; |
210 | }; | 223 | }; |
211 | 224 | ||
212 | enum ath_reset_type { | ||
213 | RESET_TYPE_BB_HANG, | ||
214 | RESET_TYPE_BB_WATCHDOG, | ||
215 | RESET_TYPE_FATAL_INT, | ||
216 | RESET_TYPE_TX_ERROR, | ||
217 | RESET_TYPE_TX_HANG, | ||
218 | RESET_TYPE_PLL_HANG, | ||
219 | RESET_TYPE_MAC_HANG, | ||
220 | __RESET_TYPE_MAX | ||
221 | }; | ||
222 | |||
223 | struct ath_stats { | 225 | struct ath_stats { |
224 | struct ath_interrupt_stats istats; | 226 | struct ath_interrupt_stats istats; |
225 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; | 227 | struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 33acb920ed3f..484b31305906 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -241,16 +241,12 @@ enum eeprom_param { | |||
241 | EEP_TEMPSENSE_SLOPE, | 241 | EEP_TEMPSENSE_SLOPE, |
242 | EEP_TEMPSENSE_SLOPE_PAL_ON, | 242 | EEP_TEMPSENSE_SLOPE_PAL_ON, |
243 | EEP_PWR_TABLE_OFFSET, | 243 | EEP_PWR_TABLE_OFFSET, |
244 | EEP_DRIVE_STRENGTH, | ||
245 | EEP_INTERNAL_REGULATOR, | ||
246 | EEP_SWREG, | ||
247 | EEP_PAPRD, | 244 | EEP_PAPRD, |
248 | EEP_MODAL_VER, | 245 | EEP_MODAL_VER, |
249 | EEP_ANT_DIV_CTL1, | 246 | EEP_ANT_DIV_CTL1, |
250 | EEP_CHAIN_MASK_REDUCE, | 247 | EEP_CHAIN_MASK_REDUCE, |
251 | EEP_ANTENNA_GAIN_2G, | 248 | EEP_ANTENNA_GAIN_2G, |
252 | EEP_ANTENNA_GAIN_5G, | 249 | EEP_ANTENNA_GAIN_5G, |
253 | EEP_QUICK_DROP | ||
254 | }; | 250 | }; |
255 | 251 | ||
256 | enum ar5416_rates { | 252 | enum ar5416_rates { |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 374c32ed905a..c785129692ff 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1111,7 +1111,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | |||
1111 | 1111 | ||
1112 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && | 1112 | if ((priv->ah->opmode == NL80211_IFTYPE_AP) && |
1113 | !test_bit(OP_ANI_RUNNING, &priv->op_flags)) { | 1113 | !test_bit(OP_ANI_RUNNING, &priv->op_flags)) { |
1114 | ath9k_hw_set_tsfadjust(priv->ah, 1); | 1114 | ath9k_hw_set_tsfadjust(priv->ah, true); |
1115 | ath9k_htc_start_ani(priv); | 1115 | ath9k_htc_start_ani(priv); |
1116 | } | 1116 | } |
1117 | 1117 | ||
@@ -1351,7 +1351,7 @@ static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, | |||
1351 | qi.tqi_aifs = params->aifs; | 1351 | qi.tqi_aifs = params->aifs; |
1352 | qi.tqi_cwmin = params->cw_min; | 1352 | qi.tqi_cwmin = params->cw_min; |
1353 | qi.tqi_cwmax = params->cw_max; | 1353 | qi.tqi_cwmax = params->cw_max; |
1354 | qi.tqi_burstTime = params->txop; | 1354 | qi.tqi_burstTime = params->txop * 32; |
1355 | 1355 | ||
1356 | qnum = get_hw_qnum(queue, priv->hwq_map); | 1356 | qnum = get_hw_qnum(queue, priv->hwq_map); |
1357 | 1357 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index c1659d079513..cfa91ab7acf8 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -671,10 +671,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
671 | if (!AR_SREV_9300_20_OR_LATER(ah)) | 671 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
672 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; | 672 | ah->ani_function &= ~ATH9K_ANI_MRC_CCK; |
673 | 673 | ||
674 | /* disable ANI for 9340 */ | ||
675 | if (AR_SREV_9340(ah)) | ||
676 | ah->config.enable_ani = false; | ||
677 | |||
678 | ath9k_hw_init_mode_regs(ah); | 674 | ath9k_hw_init_mode_regs(ah); |
679 | 675 | ||
680 | if (!ah->is_pciexpress) | 676 | if (!ah->is_pciexpress) |
@@ -2589,6 +2585,14 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
2589 | } | 2585 | } |
2590 | 2586 | ||
2591 | 2587 | ||
2588 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
2589 | pCap->hw_caps |= ATH9K_HW_WOW_DEVICE_CAPABLE | | ||
2590 | ATH9K_HW_WOW_PATTERN_MATCH_EXACT; | ||
2591 | |||
2592 | if (AR_SREV_9280(ah)) | ||
2593 | pCap->hw_caps |= ATH9K_HW_WOW_PATTERN_MATCH_DWORD; | ||
2594 | } | ||
2595 | |||
2592 | return 0; | 2596 | return 0; |
2593 | } | 2597 | } |
2594 | 2598 | ||
@@ -2908,9 +2912,9 @@ void ath9k_hw_reset_tsf(struct ath_hw *ah) | |||
2908 | } | 2912 | } |
2909 | EXPORT_SYMBOL(ath9k_hw_reset_tsf); | 2913 | EXPORT_SYMBOL(ath9k_hw_reset_tsf); |
2910 | 2914 | ||
2911 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) | 2915 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set) |
2912 | { | 2916 | { |
2913 | if (setting) | 2917 | if (set) |
2914 | ah->misc_mode |= AR_PCU_TX_ADD_TSF; | 2918 | ah->misc_mode |= AR_PCU_TX_ADD_TSF; |
2915 | else | 2919 | else |
2916 | ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; | 2920 | ah->misc_mode &= ~AR_PCU_TX_ADD_TSF; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 26da1732978d..dd0c146d81dc 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -180,6 +180,37 @@ | |||
180 | #define PAPRD_TABLE_SZ 24 | 180 | #define PAPRD_TABLE_SZ 24 |
181 | #define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0 | 181 | #define PAPRD_IDEAL_AGC2_PWR_RANGE 0xe0 |
182 | 182 | ||
183 | /* | ||
184 | * Wake on Wireless | ||
185 | */ | ||
186 | |||
187 | /* Keep Alive Frame */ | ||
188 | #define KAL_FRAME_LEN 28 | ||
189 | #define KAL_FRAME_TYPE 0x2 /* data frame */ | ||
190 | #define KAL_FRAME_SUB_TYPE 0x4 /* null data frame */ | ||
191 | #define KAL_DURATION_ID 0x3d | ||
192 | #define KAL_NUM_DATA_WORDS 6 | ||
193 | #define KAL_NUM_DESC_WORDS 12 | ||
194 | #define KAL_ANTENNA_MODE 1 | ||
195 | #define KAL_TO_DS 1 | ||
196 | #define KAL_DELAY 4 /*delay of 4ms between 2 KAL frames */ | ||
197 | #define KAL_TIMEOUT 900 | ||
198 | |||
199 | #define MAX_PATTERN_SIZE 256 | ||
200 | #define MAX_PATTERN_MASK_SIZE 32 | ||
201 | #define MAX_NUM_PATTERN 8 | ||
202 | #define MAX_NUM_USER_PATTERN 6 /* deducting the disassociate and | ||
203 | deauthenticate packets */ | ||
204 | |||
205 | /* | ||
206 | * WoW trigger mapping to hardware code | ||
207 | */ | ||
208 | |||
209 | #define AH_WOW_USER_PATTERN_EN BIT(0) | ||
210 | #define AH_WOW_MAGIC_PATTERN_EN BIT(1) | ||
211 | #define AH_WOW_LINK_CHANGE BIT(2) | ||
212 | #define AH_WOW_BEACON_MISS BIT(3) | ||
213 | |||
183 | enum ath_hw_txq_subtype { | 214 | enum ath_hw_txq_subtype { |
184 | ATH_TXQ_AC_BE = 0, | 215 | ATH_TXQ_AC_BE = 0, |
185 | ATH_TXQ_AC_BK = 1, | 216 | ATH_TXQ_AC_BK = 1, |
@@ -212,8 +243,22 @@ enum ath9k_hw_caps { | |||
212 | ATH9K_HW_CAP_RTT = BIT(14), | 243 | ATH9K_HW_CAP_RTT = BIT(14), |
213 | ATH9K_HW_CAP_MCI = BIT(15), | 244 | ATH9K_HW_CAP_MCI = BIT(15), |
214 | ATH9K_HW_CAP_DFS = BIT(16), | 245 | ATH9K_HW_CAP_DFS = BIT(16), |
246 | ATH9K_HW_WOW_DEVICE_CAPABLE = BIT(17), | ||
247 | ATH9K_HW_WOW_PATTERN_MATCH_EXACT = BIT(18), | ||
248 | ATH9K_HW_WOW_PATTERN_MATCH_DWORD = BIT(19), | ||
215 | }; | 249 | }; |
216 | 250 | ||
251 | /* | ||
252 | * WoW device capabilities | ||
253 | * @ATH9K_HW_WOW_DEVICE_CAPABLE: device revision is capable of WoW. | ||
254 | * @ATH9K_HW_WOW_PATTERN_MATCH_EXACT: device is capable of matching | ||
255 | * an exact user defined pattern or de-authentication/disassoc pattern. | ||
256 | * @ATH9K_HW_WOW_PATTERN_MATCH_DWORD: device requires the first four | ||
257 | * bytes of the pattern for user defined pattern, de-authentication and | ||
258 | * disassociation patterns for all types of possible frames recieved | ||
259 | * of those types. | ||
260 | */ | ||
261 | |||
217 | struct ath9k_hw_capabilities { | 262 | struct ath9k_hw_capabilities { |
218 | u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ | 263 | u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */ |
219 | u16 rts_aggr_limit; | 264 | u16 rts_aggr_limit; |
@@ -815,6 +860,9 @@ struct ath_hw { | |||
815 | struct ar5416IniArray iniBank7; | 860 | struct ar5416IniArray iniBank7; |
816 | struct ar5416IniArray iniAddac; | 861 | struct ar5416IniArray iniAddac; |
817 | struct ar5416IniArray iniPcieSerdes; | 862 | struct ar5416IniArray iniPcieSerdes; |
863 | #ifdef CONFIG_PM_SLEEP | ||
864 | struct ar5416IniArray iniPcieSerdesWow; | ||
865 | #endif | ||
818 | struct ar5416IniArray iniPcieSerdesLowPower; | 866 | struct ar5416IniArray iniPcieSerdesLowPower; |
819 | struct ar5416IniArray iniModesFastClock; | 867 | struct ar5416IniArray iniModesFastClock; |
820 | struct ar5416IniArray iniAdditional; | 868 | struct ar5416IniArray iniAdditional; |
@@ -863,6 +911,9 @@ struct ath_hw { | |||
863 | /* Enterprise mode cap */ | 911 | /* Enterprise mode cap */ |
864 | u32 ent_mode; | 912 | u32 ent_mode; |
865 | 913 | ||
914 | #ifdef CONFIG_PM_SLEEP | ||
915 | u32 wow_event_mask; | ||
916 | #endif | ||
866 | bool is_clk_25mhz; | 917 | bool is_clk_25mhz; |
867 | int (*get_mac_revision)(void); | 918 | int (*get_mac_revision)(void); |
868 | int (*external_reset)(void); | 919 | int (*external_reset)(void); |
@@ -943,7 +994,7 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah); | |||
943 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); | 994 | u64 ath9k_hw_gettsf64(struct ath_hw *ah); |
944 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | 995 | void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); |
945 | void ath9k_hw_reset_tsf(struct ath_hw *ah); | 996 | void ath9k_hw_reset_tsf(struct ath_hw *ah); |
946 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | 997 | void ath9k_hw_set_tsfadjust(struct ath_hw *ah, bool set); |
947 | void ath9k_hw_init_global_settings(struct ath_hw *ah); | 998 | void ath9k_hw_init_global_settings(struct ath_hw *ah); |
948 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | 999 | u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); |
949 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); | 1000 | void ath9k_hw_set11nmac2040(struct ath_hw *ah); |
@@ -1061,6 +1112,37 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah) | |||
1061 | } | 1112 | } |
1062 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ | 1113 | #endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */ |
1063 | 1114 | ||
1115 | |||
1116 | #ifdef CONFIG_PM_SLEEP | ||
1117 | const char *ath9k_hw_wow_event_to_string(u32 wow_event); | ||
1118 | void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, | ||
1119 | u8 *user_mask, int pattern_count, | ||
1120 | int pattern_len); | ||
1121 | u32 ath9k_hw_wow_wakeup(struct ath_hw *ah); | ||
1122 | void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable); | ||
1123 | #else | ||
1124 | static inline const char *ath9k_hw_wow_event_to_string(u32 wow_event) | ||
1125 | { | ||
1126 | return NULL; | ||
1127 | } | ||
1128 | static inline void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, | ||
1129 | u8 *user_pattern, | ||
1130 | u8 *user_mask, | ||
1131 | int pattern_count, | ||
1132 | int pattern_len) | ||
1133 | { | ||
1134 | } | ||
1135 | static inline u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) | ||
1136 | { | ||
1137 | return 0; | ||
1138 | } | ||
1139 | static inline void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) | ||
1140 | { | ||
1141 | } | ||
1142 | #endif | ||
1143 | |||
1144 | |||
1145 | |||
1064 | #define ATH9K_CLOCK_RATE_CCK 22 | 1146 | #define ATH9K_CLOCK_RATE_CCK 22 |
1065 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 | 1147 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 |
1066 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | 1148 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 9dfce1a69c73..f33712140fa5 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -434,6 +434,7 @@ static int ath9k_init_queues(struct ath_softc *sc) | |||
434 | for (i = 0; i < WME_NUM_AC; i++) { | 434 | for (i = 0; i < WME_NUM_AC; i++) { |
435 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); | 435 | sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); |
436 | sc->tx.txq_map[i]->mac80211_qnum = i; | 436 | sc->tx.txq_map[i]->mac80211_qnum = i; |
437 | sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; | ||
437 | } | 438 | } |
438 | return 0; | 439 | return 0; |
439 | } | 440 | } |
@@ -558,7 +559,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, | |||
558 | spin_lock_init(&sc->debug.samp_lock); | 559 | spin_lock_init(&sc->debug.samp_lock); |
559 | #endif | 560 | #endif |
560 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); | 561 | tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); |
561 | tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, | 562 | tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, |
562 | (unsigned long)sc); | 563 | (unsigned long)sc); |
563 | 564 | ||
564 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); | 565 | INIT_WORK(&sc->hw_reset_work, ath_reset_work); |
@@ -713,6 +714,24 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
713 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | 714 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; |
714 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 715 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
715 | 716 | ||
717 | #ifdef CONFIG_PM_SLEEP | ||
718 | |||
719 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && | ||
720 | device_can_wakeup(sc->dev)) { | ||
721 | |||
722 | hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | | ||
723 | WIPHY_WOWLAN_DISCONNECT; | ||
724 | hw->wiphy->wowlan.n_patterns = MAX_NUM_USER_PATTERN; | ||
725 | hw->wiphy->wowlan.pattern_min_len = 1; | ||
726 | hw->wiphy->wowlan.pattern_max_len = MAX_PATTERN_SIZE; | ||
727 | |||
728 | } | ||
729 | |||
730 | atomic_set(&sc->wow_sleep_proc_intr, -1); | ||
731 | atomic_set(&sc->wow_got_bmiss_intr, -1); | ||
732 | |||
733 | #endif | ||
734 | |||
716 | hw->queues = 4; | 735 | hw->queues = 4; |
717 | hw->max_rates = 4; | 736 | hw->max_rates = 4; |
718 | hw->channel_change_time = 5000; | 737 | hw->channel_change_time = 5000; |
diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index 91650fe50461..d4549e9aac5c 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c | |||
@@ -50,8 +50,7 @@ void ath_tx_complete_poll_work(struct work_struct *work) | |||
50 | if (needreset) { | 50 | if (needreset) { |
51 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, | 51 | ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, |
52 | "tx hung, resetting the chip\n"); | 52 | "tx hung, resetting the chip\n"); |
53 | RESET_STAT_INC(sc, RESET_TYPE_TX_HANG); | 53 | ath9k_queue_reset(sc, RESET_TYPE_TX_HANG); |
54 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
55 | return; | 54 | return; |
56 | } | 55 | } |
57 | 56 | ||
@@ -69,6 +68,7 @@ void ath_hw_check(struct work_struct *work) | |||
69 | unsigned long flags; | 68 | unsigned long flags; |
70 | int busy; | 69 | int busy; |
71 | u8 is_alive, nbeacon = 1; | 70 | u8 is_alive, nbeacon = 1; |
71 | enum ath_reset_type type; | ||
72 | 72 | ||
73 | ath9k_ps_wakeup(sc); | 73 | ath9k_ps_wakeup(sc); |
74 | is_alive = ath9k_hw_check_alive(sc->sc_ah); | 74 | is_alive = ath9k_hw_check_alive(sc->sc_ah); |
@@ -78,7 +78,7 @@ void ath_hw_check(struct work_struct *work) | |||
78 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { | 78 | else if (!is_alive && AR_SREV_9300(sc->sc_ah)) { |
79 | ath_dbg(common, RESET, | 79 | ath_dbg(common, RESET, |
80 | "DCU stuck is detected. Schedule chip reset\n"); | 80 | "DCU stuck is detected. Schedule chip reset\n"); |
81 | RESET_STAT_INC(sc, RESET_TYPE_MAC_HANG); | 81 | type = RESET_TYPE_MAC_HANG; |
82 | goto sched_reset; | 82 | goto sched_reset; |
83 | } | 83 | } |
84 | 84 | ||
@@ -90,7 +90,7 @@ void ath_hw_check(struct work_struct *work) | |||
90 | busy, sc->hw_busy_count + 1); | 90 | busy, sc->hw_busy_count + 1); |
91 | if (busy >= 99) { | 91 | if (busy >= 99) { |
92 | if (++sc->hw_busy_count >= 3) { | 92 | if (++sc->hw_busy_count >= 3) { |
93 | RESET_STAT_INC(sc, RESET_TYPE_BB_HANG); | 93 | type = RESET_TYPE_BB_HANG; |
94 | goto sched_reset; | 94 | goto sched_reset; |
95 | } | 95 | } |
96 | } else if (busy >= 0) { | 96 | } else if (busy >= 0) { |
@@ -102,7 +102,7 @@ void ath_hw_check(struct work_struct *work) | |||
102 | goto out; | 102 | goto out; |
103 | 103 | ||
104 | sched_reset: | 104 | sched_reset: |
105 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 105 | ath9k_queue_reset(sc, type); |
106 | out: | 106 | out: |
107 | ath9k_ps_restore(sc); | 107 | ath9k_ps_restore(sc); |
108 | } | 108 | } |
@@ -119,8 +119,7 @@ static bool ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | |||
119 | count++; | 119 | count++; |
120 | if (count == 3) { | 120 | if (count == 3) { |
121 | ath_dbg(common, RESET, "PLL WAR, resetting the chip\n"); | 121 | ath_dbg(common, RESET, "PLL WAR, resetting the chip\n"); |
122 | RESET_STAT_INC(sc, RESET_TYPE_PLL_HANG); | 122 | ath9k_queue_reset(sc, RESET_TYPE_PLL_HANG); |
123 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
124 | count = 0; | 123 | count = 0; |
125 | return true; | 124 | return true; |
126 | } | 125 | } |
@@ -432,26 +431,72 @@ set_timer: | |||
432 | } | 431 | } |
433 | } | 432 | } |
434 | 433 | ||
435 | void ath_start_ani(struct ath_common *common) | 434 | void ath_start_ani(struct ath_softc *sc) |
436 | { | 435 | { |
437 | struct ath_hw *ah = common->ah; | 436 | struct ath_hw *ah = sc->sc_ah; |
437 | struct ath_common *common = ath9k_hw_common(ah); | ||
438 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 438 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
439 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
440 | |||
441 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) | ||
442 | return; | ||
443 | 439 | ||
444 | if (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL) | 440 | if (common->disable_ani || |
441 | !test_bit(SC_OP_ANI_RUN, &sc->sc_flags) || | ||
442 | (sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) | ||
445 | return; | 443 | return; |
446 | 444 | ||
447 | common->ani.longcal_timer = timestamp; | 445 | common->ani.longcal_timer = timestamp; |
448 | common->ani.shortcal_timer = timestamp; | 446 | common->ani.shortcal_timer = timestamp; |
449 | common->ani.checkani_timer = timestamp; | 447 | common->ani.checkani_timer = timestamp; |
450 | 448 | ||
449 | ath_dbg(common, ANI, "Starting ANI\n"); | ||
451 | mod_timer(&common->ani.timer, | 450 | mod_timer(&common->ani.timer, |
452 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); | 451 | jiffies + msecs_to_jiffies((u32)ah->config.ani_poll_interval)); |
453 | } | 452 | } |
454 | 453 | ||
454 | void ath_stop_ani(struct ath_softc *sc) | ||
455 | { | ||
456 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
457 | |||
458 | ath_dbg(common, ANI, "Stopping ANI\n"); | ||
459 | del_timer_sync(&common->ani.timer); | ||
460 | } | ||
461 | |||
462 | void ath_check_ani(struct ath_softc *sc) | ||
463 | { | ||
464 | struct ath_hw *ah = sc->sc_ah; | ||
465 | struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf; | ||
466 | |||
467 | /* | ||
468 | * Check for the various conditions in which ANI has to | ||
469 | * be stopped. | ||
470 | */ | ||
471 | if (ah->opmode == NL80211_IFTYPE_ADHOC) { | ||
472 | if (!cur_conf->enable_beacon) | ||
473 | goto stop_ani; | ||
474 | } else if (ah->opmode == NL80211_IFTYPE_AP) { | ||
475 | if (!cur_conf->enable_beacon) { | ||
476 | /* | ||
477 | * Disable ANI only when there are no | ||
478 | * associated stations. | ||
479 | */ | ||
480 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
481 | goto stop_ani; | ||
482 | } | ||
483 | } else if (ah->opmode == NL80211_IFTYPE_STATION) { | ||
484 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | ||
485 | goto stop_ani; | ||
486 | } | ||
487 | |||
488 | if (!test_bit(SC_OP_ANI_RUN, &sc->sc_flags)) { | ||
489 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
490 | ath_start_ani(sc); | ||
491 | } | ||
492 | |||
493 | return; | ||
494 | |||
495 | stop_ani: | ||
496 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
497 | ath_stop_ani(sc); | ||
498 | } | ||
499 | |||
455 | void ath_update_survey_nf(struct ath_softc *sc, int channel) | 500 | void ath_update_survey_nf(struct ath_softc *sc, int channel) |
456 | { | 501 | { |
457 | struct ath_hw *ah = sc->sc_ah; | 502 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 248e5b24acfa..6049d8b82855 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -19,6 +19,9 @@ | |||
19 | #include "ath9k.h" | 19 | #include "ath9k.h" |
20 | #include "btcoex.h" | 20 | #include "btcoex.h" |
21 | 21 | ||
22 | static void ath9k_set_assoc_state(struct ath_softc *sc, | ||
23 | struct ieee80211_vif *vif); | ||
24 | |||
22 | u8 ath9k_parse_mpdudensity(u8 mpdudensity) | 25 | u8 ath9k_parse_mpdudensity(u8 mpdudensity) |
23 | { | 26 | { |
24 | /* | 27 | /* |
@@ -167,8 +170,6 @@ static void ath_cancel_work(struct ath_softc *sc) | |||
167 | 170 | ||
168 | static void ath_restart_work(struct ath_softc *sc) | 171 | static void ath_restart_work(struct ath_softc *sc) |
169 | { | 172 | { |
170 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
171 | |||
172 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 173 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
173 | 174 | ||
174 | if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) || | 175 | if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) || |
@@ -177,21 +178,18 @@ static void ath_restart_work(struct ath_softc *sc) | |||
177 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); | 178 | msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); |
178 | 179 | ||
179 | ath_start_rx_poll(sc, 3); | 180 | ath_start_rx_poll(sc, 3); |
180 | 181 | ath_start_ani(sc); | |
181 | if (!common->disable_ani) | ||
182 | ath_start_ani(common); | ||
183 | } | 182 | } |
184 | 183 | ||
185 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) | 184 | static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) |
186 | { | 185 | { |
187 | struct ath_hw *ah = sc->sc_ah; | 186 | struct ath_hw *ah = sc->sc_ah; |
188 | struct ath_common *common = ath9k_hw_common(ah); | ||
189 | bool ret = true; | 187 | bool ret = true; |
190 | 188 | ||
191 | ieee80211_stop_queues(sc->hw); | 189 | ieee80211_stop_queues(sc->hw); |
192 | 190 | ||
193 | sc->hw_busy_count = 0; | 191 | sc->hw_busy_count = 0; |
194 | del_timer_sync(&common->ani.timer); | 192 | ath_stop_ani(sc); |
195 | del_timer_sync(&sc->rx_poll_timer); | 193 | del_timer_sync(&sc->rx_poll_timer); |
196 | 194 | ||
197 | ath9k_debug_samp_bb_mac(sc); | 195 | ath9k_debug_samp_bb_mac(sc); |
@@ -236,7 +234,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
236 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) | 234 | if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) |
237 | goto work; | 235 | goto work; |
238 | 236 | ||
239 | ath_set_beacon(sc); | 237 | ath9k_set_beacon(sc); |
240 | 238 | ||
241 | if (ah->opmode == NL80211_IFTYPE_STATION && | 239 | if (ah->opmode == NL80211_IFTYPE_STATION && |
242 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | 240 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
@@ -365,6 +363,7 @@ void ath9k_tasklet(unsigned long data) | |||
365 | struct ath_softc *sc = (struct ath_softc *)data; | 363 | struct ath_softc *sc = (struct ath_softc *)data; |
366 | struct ath_hw *ah = sc->sc_ah; | 364 | struct ath_hw *ah = sc->sc_ah; |
367 | struct ath_common *common = ath9k_hw_common(ah); | 365 | struct ath_common *common = ath9k_hw_common(ah); |
366 | enum ath_reset_type type; | ||
368 | unsigned long flags; | 367 | unsigned long flags; |
369 | u32 status = sc->intrstatus; | 368 | u32 status = sc->intrstatus; |
370 | u32 rxmask; | 369 | u32 rxmask; |
@@ -374,18 +373,13 @@ void ath9k_tasklet(unsigned long data) | |||
374 | 373 | ||
375 | if ((status & ATH9K_INT_FATAL) || | 374 | if ((status & ATH9K_INT_FATAL) || |
376 | (status & ATH9K_INT_BB_WATCHDOG)) { | 375 | (status & ATH9K_INT_BB_WATCHDOG)) { |
377 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
378 | enum ath_reset_type type; | ||
379 | 376 | ||
380 | if (status & ATH9K_INT_FATAL) | 377 | if (status & ATH9K_INT_FATAL) |
381 | type = RESET_TYPE_FATAL_INT; | 378 | type = RESET_TYPE_FATAL_INT; |
382 | else | 379 | else |
383 | type = RESET_TYPE_BB_WATCHDOG; | 380 | type = RESET_TYPE_BB_WATCHDOG; |
384 | 381 | ||
385 | RESET_STAT_INC(sc, type); | 382 | ath9k_queue_reset(sc, type); |
386 | #endif | ||
387 | set_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
388 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
389 | goto out; | 383 | goto out; |
390 | } | 384 | } |
391 | 385 | ||
@@ -493,6 +487,17 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
493 | if (status & SCHED_INTR) | 487 | if (status & SCHED_INTR) |
494 | sched = true; | 488 | sched = true; |
495 | 489 | ||
490 | #ifdef CONFIG_PM_SLEEP | ||
491 | if (status & ATH9K_INT_BMISS) { | ||
492 | if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { | ||
493 | ath_dbg(common, ANY, "during WoW we got a BMISS\n"); | ||
494 | atomic_inc(&sc->wow_got_bmiss_intr); | ||
495 | atomic_dec(&sc->wow_sleep_proc_intr); | ||
496 | } | ||
497 | ath_dbg(common, INTERRUPT, "beacon miss interrupt\n"); | ||
498 | } | ||
499 | #endif | ||
500 | |||
496 | /* | 501 | /* |
497 | * If a FATAL or RXORN interrupt is received, we have to reset the | 502 | * If a FATAL or RXORN interrupt is received, we have to reset the |
498 | * chip immediately. | 503 | * chip immediately. |
@@ -575,6 +580,15 @@ static int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
575 | return r; | 580 | return r; |
576 | } | 581 | } |
577 | 582 | ||
583 | void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type) | ||
584 | { | ||
585 | #ifdef CONFIG_ATH9K_DEBUGFS | ||
586 | RESET_STAT_INC(sc, type); | ||
587 | #endif | ||
588 | set_bit(SC_OP_HW_RESET, &sc->sc_flags); | ||
589 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
590 | } | ||
591 | |||
578 | void ath_reset_work(struct work_struct *work) | 592 | void ath_reset_work(struct work_struct *work) |
579 | { | 593 | { |
580 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); | 594 | struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); |
@@ -841,16 +855,6 @@ bool ath9k_uses_beacons(int type) | |||
841 | } | 855 | } |
842 | } | 856 | } |
843 | 857 | ||
844 | static void ath9k_reclaim_beacon(struct ath_softc *sc, | ||
845 | struct ieee80211_vif *vif) | ||
846 | { | ||
847 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
848 | |||
849 | ath9k_set_beaconing_status(sc, false); | ||
850 | ath_beacon_return(sc, avp); | ||
851 | ath9k_set_beaconing_status(sc, true); | ||
852 | } | ||
853 | |||
854 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 858 | static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
855 | { | 859 | { |
856 | struct ath9k_vif_iter_data *iter_data = data; | 860 | struct ath9k_vif_iter_data *iter_data = data; |
@@ -882,6 +886,18 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
882 | } | 886 | } |
883 | } | 887 | } |
884 | 888 | ||
889 | static void ath9k_sta_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
890 | { | ||
891 | struct ath_softc *sc = data; | ||
892 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
893 | |||
894 | if (vif->type != NL80211_IFTYPE_STATION) | ||
895 | return; | ||
896 | |||
897 | if (avp->primary_sta_vif) | ||
898 | ath9k_set_assoc_state(sc, vif); | ||
899 | } | ||
900 | |||
885 | /* Called with sc->mutex held. */ | 901 | /* Called with sc->mutex held. */ |
886 | void ath9k_calculate_iter_data(struct ieee80211_hw *hw, | 902 | void ath9k_calculate_iter_data(struct ieee80211_hw *hw, |
887 | struct ieee80211_vif *vif, | 903 | struct ieee80211_vif *vif, |
@@ -915,21 +931,18 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
915 | struct ath_hw *ah = sc->sc_ah; | 931 | struct ath_hw *ah = sc->sc_ah; |
916 | struct ath_common *common = ath9k_hw_common(ah); | 932 | struct ath_common *common = ath9k_hw_common(ah); |
917 | struct ath9k_vif_iter_data iter_data; | 933 | struct ath9k_vif_iter_data iter_data; |
934 | enum nl80211_iftype old_opmode = ah->opmode; | ||
918 | 935 | ||
919 | ath9k_calculate_iter_data(hw, vif, &iter_data); | 936 | ath9k_calculate_iter_data(hw, vif, &iter_data); |
920 | 937 | ||
921 | /* Set BSSID mask. */ | ||
922 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); | 938 | memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); |
923 | ath_hw_setbssidmask(common); | 939 | ath_hw_setbssidmask(common); |
924 | 940 | ||
925 | /* Set op-mode & TSF */ | ||
926 | if (iter_data.naps > 0) { | 941 | if (iter_data.naps > 0) { |
927 | ath9k_hw_set_tsfadjust(ah, 1); | 942 | ath9k_hw_set_tsfadjust(ah, true); |
928 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | ||
929 | ah->opmode = NL80211_IFTYPE_AP; | 943 | ah->opmode = NL80211_IFTYPE_AP; |
930 | } else { | 944 | } else { |
931 | ath9k_hw_set_tsfadjust(ah, 0); | 945 | ath9k_hw_set_tsfadjust(ah, false); |
932 | clear_bit(SC_OP_TSF_RESET, &sc->sc_flags); | ||
933 | 946 | ||
934 | if (iter_data.nmeshes) | 947 | if (iter_data.nmeshes) |
935 | ah->opmode = NL80211_IFTYPE_MESH_POINT; | 948 | ah->opmode = NL80211_IFTYPE_MESH_POINT; |
@@ -941,9 +954,8 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
941 | ah->opmode = NL80211_IFTYPE_STATION; | 954 | ah->opmode = NL80211_IFTYPE_STATION; |
942 | } | 955 | } |
943 | 956 | ||
944 | /* | 957 | ath9k_hw_setopmode(ah); |
945 | * Enable MIB interrupts when there are hardware phy counters. | 958 | |
946 | */ | ||
947 | if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) | 959 | if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) |
948 | ah->imask |= ATH9K_INT_TSFOOR; | 960 | ah->imask |= ATH9K_INT_TSFOOR; |
949 | else | 961 | else |
@@ -951,34 +963,15 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
951 | 963 | ||
952 | ath9k_hw_set_interrupts(ah); | 964 | ath9k_hw_set_interrupts(ah); |
953 | 965 | ||
954 | /* Set up ANI */ | 966 | /* |
955 | if (iter_data.naps > 0) { | 967 | * If we are changing the opmode to STATION, |
956 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 968 | * a beacon sync needs to be done. |
957 | 969 | */ | |
958 | if (!common->disable_ani) { | 970 | if (ah->opmode == NL80211_IFTYPE_STATION && |
959 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 971 | old_opmode == NL80211_IFTYPE_AP && |
960 | ath_start_ani(common); | 972 | test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { |
961 | } | 973 | ieee80211_iterate_active_interfaces_atomic(sc->hw, |
962 | 974 | ath9k_sta_vif_iter, sc); | |
963 | } else { | ||
964 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
965 | del_timer_sync(&common->ani.timer); | ||
966 | } | ||
967 | } | ||
968 | |||
969 | /* Called with sc->mutex held, vif counts set up properly. */ | ||
970 | static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw, | ||
971 | struct ieee80211_vif *vif) | ||
972 | { | ||
973 | struct ath_softc *sc = hw->priv; | ||
974 | |||
975 | ath9k_calculate_summary_state(hw, vif); | ||
976 | |||
977 | if (ath9k_uses_beacons(vif->type)) { | ||
978 | /* Reserve a beacon slot for the vif */ | ||
979 | ath9k_set_beaconing_status(sc, false); | ||
980 | ath_beacon_alloc(sc, vif); | ||
981 | ath9k_set_beaconing_status(sc, true); | ||
982 | } | 975 | } |
983 | } | 976 | } |
984 | 977 | ||
@@ -1021,7 +1014,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1021 | 1014 | ||
1022 | sc->nvifs++; | 1015 | sc->nvifs++; |
1023 | 1016 | ||
1024 | ath9k_do_vif_add_setup(hw, vif); | 1017 | ath9k_calculate_summary_state(hw, vif); |
1018 | if (ath9k_uses_beacons(vif->type)) | ||
1019 | ath9k_beacon_assign_slot(sc, vif); | ||
1020 | |||
1025 | out: | 1021 | out: |
1026 | mutex_unlock(&sc->mutex); | 1022 | mutex_unlock(&sc->mutex); |
1027 | ath9k_ps_restore(sc); | 1023 | ath9k_ps_restore(sc); |
@@ -1038,6 +1034,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1038 | int ret = 0; | 1034 | int ret = 0; |
1039 | 1035 | ||
1040 | ath_dbg(common, CONFIG, "Change Interface\n"); | 1036 | ath_dbg(common, CONFIG, "Change Interface\n"); |
1037 | |||
1041 | mutex_lock(&sc->mutex); | 1038 | mutex_lock(&sc->mutex); |
1042 | ath9k_ps_wakeup(sc); | 1039 | ath9k_ps_wakeup(sc); |
1043 | 1040 | ||
@@ -1050,15 +1047,16 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1050 | } | 1047 | } |
1051 | } | 1048 | } |
1052 | 1049 | ||
1053 | /* Clean up old vif stuff */ | ||
1054 | if (ath9k_uses_beacons(vif->type)) | 1050 | if (ath9k_uses_beacons(vif->type)) |
1055 | ath9k_reclaim_beacon(sc, vif); | 1051 | ath9k_beacon_remove_slot(sc, vif); |
1056 | 1052 | ||
1057 | /* Add new settings */ | ||
1058 | vif->type = new_type; | 1053 | vif->type = new_type; |
1059 | vif->p2p = p2p; | 1054 | vif->p2p = p2p; |
1060 | 1055 | ||
1061 | ath9k_do_vif_add_setup(hw, vif); | 1056 | ath9k_calculate_summary_state(hw, vif); |
1057 | if (ath9k_uses_beacons(vif->type)) | ||
1058 | ath9k_beacon_assign_slot(sc, vif); | ||
1059 | |||
1062 | out: | 1060 | out: |
1063 | ath9k_ps_restore(sc); | 1061 | ath9k_ps_restore(sc); |
1064 | mutex_unlock(&sc->mutex); | 1062 | mutex_unlock(&sc->mutex); |
@@ -1078,9 +1076,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1078 | 1076 | ||
1079 | sc->nvifs--; | 1077 | sc->nvifs--; |
1080 | 1078 | ||
1081 | /* Reclaim beacon resources */ | ||
1082 | if (ath9k_uses_beacons(vif->type)) | 1079 | if (ath9k_uses_beacons(vif->type)) |
1083 | ath9k_reclaim_beacon(sc, vif); | 1080 | ath9k_beacon_remove_slot(sc, vif); |
1084 | 1081 | ||
1085 | ath9k_calculate_summary_state(hw, NULL); | 1082 | ath9k_calculate_summary_state(hw, NULL); |
1086 | 1083 | ||
@@ -1377,21 +1374,18 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw, | |||
1377 | qi.tqi_aifs = params->aifs; | 1374 | qi.tqi_aifs = params->aifs; |
1378 | qi.tqi_cwmin = params->cw_min; | 1375 | qi.tqi_cwmin = params->cw_min; |
1379 | qi.tqi_cwmax = params->cw_max; | 1376 | qi.tqi_cwmax = params->cw_max; |
1380 | qi.tqi_burstTime = params->txop; | 1377 | qi.tqi_burstTime = params->txop * 32; |
1381 | 1378 | ||
1382 | ath_dbg(common, CONFIG, | 1379 | ath_dbg(common, CONFIG, |
1383 | "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | 1380 | "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", |
1384 | queue, txq->axq_qnum, params->aifs, params->cw_min, | 1381 | queue, txq->axq_qnum, params->aifs, params->cw_min, |
1385 | params->cw_max, params->txop); | 1382 | params->cw_max, params->txop); |
1386 | 1383 | ||
1384 | ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime); | ||
1387 | ret = ath_txq_update(sc, txq->axq_qnum, &qi); | 1385 | ret = ath_txq_update(sc, txq->axq_qnum, &qi); |
1388 | if (ret) | 1386 | if (ret) |
1389 | ath_err(common, "TXQ Update failed\n"); | 1387 | ath_err(common, "TXQ Update failed\n"); |
1390 | 1388 | ||
1391 | if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) | ||
1392 | if (queue == WME_AC_BE && !ret) | ||
1393 | ath_beaconq_config(sc); | ||
1394 | |||
1395 | mutex_unlock(&sc->mutex); | 1389 | mutex_unlock(&sc->mutex); |
1396 | ath9k_ps_restore(sc); | 1390 | ath9k_ps_restore(sc); |
1397 | 1391 | ||
@@ -1460,86 +1454,53 @@ static int ath9k_set_key(struct ieee80211_hw *hw, | |||
1460 | 1454 | ||
1461 | return ret; | 1455 | return ret; |
1462 | } | 1456 | } |
1463 | static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 1457 | |
1458 | static void ath9k_set_assoc_state(struct ath_softc *sc, | ||
1459 | struct ieee80211_vif *vif) | ||
1464 | { | 1460 | { |
1465 | struct ath_softc *sc = data; | ||
1466 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1461 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1467 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1468 | struct ath_vif *avp = (void *)vif->drv_priv; | 1462 | struct ath_vif *avp = (void *)vif->drv_priv; |
1463 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1469 | unsigned long flags; | 1464 | unsigned long flags; |
1465 | |||
1466 | set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); | ||
1467 | avp->primary_sta_vif = true; | ||
1468 | |||
1470 | /* | 1469 | /* |
1471 | * Skip iteration if primary station vif's bss info | 1470 | * Set the AID, BSSID and do beacon-sync only when |
1472 | * was not changed | 1471 | * the HW opmode is STATION. |
1472 | * | ||
1473 | * But the primary bit is set above in any case. | ||
1473 | */ | 1474 | */ |
1474 | if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) | 1475 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) |
1475 | return; | 1476 | return; |
1476 | 1477 | ||
1477 | if (bss_conf->assoc) { | 1478 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1478 | set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); | 1479 | common->curaid = bss_conf->aid; |
1479 | avp->primary_sta_vif = true; | 1480 | ath9k_hw_write_associd(sc->sc_ah); |
1480 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1481 | common->curaid = bss_conf->aid; | ||
1482 | ath9k_hw_write_associd(sc->sc_ah); | ||
1483 | ath_dbg(common, CONFIG, "Bss Info ASSOC %d, bssid: %pM\n", | ||
1484 | bss_conf->aid, common->curbssid); | ||
1485 | ath_beacon_config(sc, vif); | ||
1486 | /* | ||
1487 | * Request a re-configuration of Beacon related timers | ||
1488 | * on the receipt of the first Beacon frame (i.e., | ||
1489 | * after time sync with the AP). | ||
1490 | */ | ||
1491 | spin_lock_irqsave(&sc->sc_pm_lock, flags); | ||
1492 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||
1493 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||
1494 | |||
1495 | /* Reset rssi stats */ | ||
1496 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
1497 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
1498 | 1481 | ||
1499 | ath_start_rx_poll(sc, 3); | 1482 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
1483 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
1500 | 1484 | ||
1501 | if (!common->disable_ani) { | 1485 | spin_lock_irqsave(&sc->sc_pm_lock, flags); |
1502 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | 1486 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
1503 | ath_start_ani(common); | 1487 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
1504 | } | ||
1505 | 1488 | ||
1506 | } | 1489 | ath_dbg(common, CONFIG, |
1490 | "Primary Station interface: %pM, BSSID: %pM\n", | ||
1491 | vif->addr, common->curbssid); | ||
1507 | } | 1492 | } |
1508 | 1493 | ||
1509 | static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | 1494 | static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif) |
1510 | { | 1495 | { |
1511 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1496 | struct ath_softc *sc = data; |
1512 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1497 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
1513 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
1514 | 1498 | ||
1515 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | 1499 | if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) |
1516 | return; | 1500 | return; |
1517 | 1501 | ||
1518 | /* Reconfigure bss info */ | 1502 | if (bss_conf->assoc) |
1519 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 1503 | ath9k_set_assoc_state(sc, vif); |
1520 | ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n", | ||
1521 | common->curaid, common->curbssid); | ||
1522 | clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); | ||
1523 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
1524 | avp->primary_sta_vif = false; | ||
1525 | memset(common->curbssid, 0, ETH_ALEN); | ||
1526 | common->curaid = 0; | ||
1527 | } | ||
1528 | |||
1529 | ieee80211_iterate_active_interfaces_atomic( | ||
1530 | sc->hw, ath9k_bss_iter, sc); | ||
1531 | |||
1532 | /* | ||
1533 | * None of station vifs are associated. | ||
1534 | * Clear bssid & aid | ||
1535 | */ | ||
1536 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | ||
1537 | ath9k_hw_write_associd(sc->sc_ah); | ||
1538 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
1539 | del_timer_sync(&common->ani.timer); | ||
1540 | del_timer_sync(&sc->rx_poll_timer); | ||
1541 | memset(&sc->caldata, 0, sizeof(sc->caldata)); | ||
1542 | } | ||
1543 | } | 1504 | } |
1544 | 1505 | ||
1545 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | 1506 | static void ath9k_bss_info_changed(struct ieee80211_hw *hw, |
@@ -1547,6 +1508,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1547 | struct ieee80211_bss_conf *bss_conf, | 1508 | struct ieee80211_bss_conf *bss_conf, |
1548 | u32 changed) | 1509 | u32 changed) |
1549 | { | 1510 | { |
1511 | #define CHECK_ANI \ | ||
1512 | (BSS_CHANGED_ASSOC | \ | ||
1513 | BSS_CHANGED_IBSS | \ | ||
1514 | BSS_CHANGED_BEACON_ENABLED) | ||
1515 | |||
1550 | struct ath_softc *sc = hw->priv; | 1516 | struct ath_softc *sc = hw->priv; |
1551 | struct ath_hw *ah = sc->sc_ah; | 1517 | struct ath_hw *ah = sc->sc_ah; |
1552 | struct ath_common *common = ath9k_hw_common(ah); | 1518 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -1557,53 +1523,41 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1557 | mutex_lock(&sc->mutex); | 1523 | mutex_lock(&sc->mutex); |
1558 | 1524 | ||
1559 | if (changed & BSS_CHANGED_ASSOC) { | 1525 | if (changed & BSS_CHANGED_ASSOC) { |
1560 | ath9k_config_bss(sc, vif); | 1526 | ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n", |
1527 | bss_conf->bssid, bss_conf->assoc); | ||
1561 | 1528 | ||
1562 | ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", | 1529 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
1563 | common->curbssid, common->curaid); | 1530 | clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); |
1531 | avp->primary_sta_vif = false; | ||
1532 | |||
1533 | if (ah->opmode == NL80211_IFTYPE_STATION) | ||
1534 | clear_bit(SC_OP_BEACONS, &sc->sc_flags); | ||
1535 | } | ||
1536 | |||
1537 | ieee80211_iterate_active_interfaces_atomic(sc->hw, | ||
1538 | ath9k_bss_assoc_iter, sc); | ||
1539 | |||
1540 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) && | ||
1541 | ah->opmode == NL80211_IFTYPE_STATION) { | ||
1542 | memset(common->curbssid, 0, ETH_ALEN); | ||
1543 | common->curaid = 0; | ||
1544 | ath9k_hw_write_associd(sc->sc_ah); | ||
1545 | } | ||
1564 | } | 1546 | } |
1565 | 1547 | ||
1566 | if (changed & BSS_CHANGED_IBSS) { | 1548 | if (changed & BSS_CHANGED_IBSS) { |
1567 | /* There can be only one vif available */ | ||
1568 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1549 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1569 | common->curaid = bss_conf->aid; | 1550 | common->curaid = bss_conf->aid; |
1570 | ath9k_hw_write_associd(sc->sc_ah); | 1551 | ath9k_hw_write_associd(sc->sc_ah); |
1571 | |||
1572 | if (bss_conf->ibss_joined) { | ||
1573 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
1574 | |||
1575 | if (!common->disable_ani) { | ||
1576 | set_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
1577 | ath_start_ani(common); | ||
1578 | } | ||
1579 | |||
1580 | } else { | ||
1581 | clear_bit(SC_OP_ANI_RUN, &sc->sc_flags); | ||
1582 | del_timer_sync(&common->ani.timer); | ||
1583 | del_timer_sync(&sc->rx_poll_timer); | ||
1584 | } | ||
1585 | } | 1552 | } |
1586 | 1553 | ||
1587 | /* | 1554 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || |
1588 | * In case of AP mode, the HW TSF has to be reset | 1555 | (changed & BSS_CHANGED_BEACON_INT)) { |
1589 | * when the beacon interval changes. | 1556 | if (ah->opmode == NL80211_IFTYPE_AP && |
1590 | */ | 1557 | bss_conf->enable_beacon) |
1591 | if ((changed & BSS_CHANGED_BEACON_INT) && | 1558 | ath9k_set_tsfadjust(sc, vif); |
1592 | (vif->type == NL80211_IFTYPE_AP)) | 1559 | if (ath9k_allow_beacon_config(sc, vif)) |
1593 | set_bit(SC_OP_TSF_RESET, &sc->sc_flags); | 1560 | ath9k_beacon_config(sc, vif, changed); |
1594 | |||
1595 | /* Configure beaconing (AP, IBSS, MESH) */ | ||
1596 | if (ath9k_uses_beacons(vif->type) && | ||
1597 | ((changed & BSS_CHANGED_BEACON) || | ||
1598 | (changed & BSS_CHANGED_BEACON_ENABLED) || | ||
1599 | (changed & BSS_CHANGED_BEACON_INT))) { | ||
1600 | ath9k_set_beaconing_status(sc, false); | ||
1601 | if (bss_conf->enable_beacon) | ||
1602 | ath_beacon_alloc(sc, vif); | ||
1603 | else | ||
1604 | avp->is_bslot_active = false; | ||
1605 | ath_beacon_config(sc, vif); | ||
1606 | ath9k_set_beaconing_status(sc, true); | ||
1607 | } | 1561 | } |
1608 | 1562 | ||
1609 | if (changed & BSS_CHANGED_ERP_SLOT) { | 1563 | if (changed & BSS_CHANGED_ERP_SLOT) { |
@@ -1625,8 +1579,13 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1625 | } | 1579 | } |
1626 | } | 1580 | } |
1627 | 1581 | ||
1582 | if (changed & CHECK_ANI) | ||
1583 | ath_check_ani(sc); | ||
1584 | |||
1628 | mutex_unlock(&sc->mutex); | 1585 | mutex_unlock(&sc->mutex); |
1629 | ath9k_ps_restore(sc); | 1586 | ath9k_ps_restore(sc); |
1587 | |||
1588 | #undef CHECK_ANI | ||
1630 | } | 1589 | } |
1631 | 1590 | ||
1632 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 1591 | static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) |
@@ -1855,10 +1814,11 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | |||
1855 | if (!vif) | 1814 | if (!vif) |
1856 | return 0; | 1815 | return 0; |
1857 | 1816 | ||
1858 | avp = (void *)vif->drv_priv; | 1817 | if (!vif->bss_conf.enable_beacon) |
1859 | if (!avp->is_bslot_active) | ||
1860 | return 0; | 1818 | return 0; |
1861 | 1819 | ||
1820 | avp = (void *)vif->drv_priv; | ||
1821 | |||
1862 | if (!sc->beacon.tx_processed && !edma) { | 1822 | if (!sc->beacon.tx_processed && !edma) { |
1863 | tasklet_disable(&sc->bcon_tasklet); | 1823 | tasklet_disable(&sc->bcon_tasklet); |
1864 | 1824 | ||
@@ -1912,12 +1872,29 @@ static u32 fill_chainmask(u32 cap, u32 new) | |||
1912 | return filled; | 1872 | return filled; |
1913 | } | 1873 | } |
1914 | 1874 | ||
1875 | static bool validate_antenna_mask(struct ath_hw *ah, u32 val) | ||
1876 | { | ||
1877 | switch (val & 0x7) { | ||
1878 | case 0x1: | ||
1879 | case 0x3: | ||
1880 | case 0x7: | ||
1881 | return true; | ||
1882 | case 0x2: | ||
1883 | return (ah->caps.rx_chainmask == 1); | ||
1884 | default: | ||
1885 | return false; | ||
1886 | } | ||
1887 | } | ||
1888 | |||
1915 | static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) | 1889 | static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) |
1916 | { | 1890 | { |
1917 | struct ath_softc *sc = hw->priv; | 1891 | struct ath_softc *sc = hw->priv; |
1918 | struct ath_hw *ah = sc->sc_ah; | 1892 | struct ath_hw *ah = sc->sc_ah; |
1919 | 1893 | ||
1920 | if (!rx_ant || !tx_ant) | 1894 | if (ah->caps.rx_chainmask != 1) |
1895 | rx_ant |= tx_ant; | ||
1896 | |||
1897 | if (!validate_antenna_mask(ah, rx_ant) || !tx_ant) | ||
1921 | return -EINVAL; | 1898 | return -EINVAL; |
1922 | 1899 | ||
1923 | sc->ant_rx = rx_ant; | 1900 | sc->ant_rx = rx_ant; |
@@ -2075,6 +2052,362 @@ static void ath9k_get_et_stats(struct ieee80211_hw *hw, | |||
2075 | #endif | 2052 | #endif |
2076 | 2053 | ||
2077 | 2054 | ||
2055 | #ifdef CONFIG_PM_SLEEP | ||
2056 | |||
2057 | static void ath9k_wow_map_triggers(struct ath_softc *sc, | ||
2058 | struct cfg80211_wowlan *wowlan, | ||
2059 | u32 *wow_triggers) | ||
2060 | { | ||
2061 | if (wowlan->disconnect) | ||
2062 | *wow_triggers |= AH_WOW_LINK_CHANGE | | ||
2063 | AH_WOW_BEACON_MISS; | ||
2064 | if (wowlan->magic_pkt) | ||
2065 | *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN; | ||
2066 | |||
2067 | if (wowlan->n_patterns) | ||
2068 | *wow_triggers |= AH_WOW_USER_PATTERN_EN; | ||
2069 | |||
2070 | sc->wow_enabled = *wow_triggers; | ||
2071 | |||
2072 | } | ||
2073 | |||
2074 | static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc) | ||
2075 | { | ||
2076 | struct ath_hw *ah = sc->sc_ah; | ||
2077 | struct ath_common *common = ath9k_hw_common(ah); | ||
2078 | struct ath9k_hw_capabilities *pcaps = &ah->caps; | ||
2079 | int pattern_count = 0; | ||
2080 | int i, byte_cnt; | ||
2081 | u8 dis_deauth_pattern[MAX_PATTERN_SIZE]; | ||
2082 | u8 dis_deauth_mask[MAX_PATTERN_SIZE]; | ||
2083 | |||
2084 | memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE); | ||
2085 | memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE); | ||
2086 | |||
2087 | /* | ||
2088 | * Create Dissassociate / Deauthenticate packet filter | ||
2089 | * | ||
2090 | * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes | ||
2091 | * +--------------+----------+---------+--------+--------+---- | ||
2092 | * + Frame Control+ Duration + DA + SA + BSSID + | ||
2093 | * +--------------+----------+---------+--------+--------+---- | ||
2094 | * | ||
2095 | * The above is the management frame format for disassociate/ | ||
2096 | * deauthenticate pattern, from this we need to match the first byte | ||
2097 | * of 'Frame Control' and DA, SA, and BSSID fields | ||
2098 | * (skipping 2nd byte of FC and Duration feild. | ||
2099 | * | ||
2100 | * Disassociate pattern | ||
2101 | * -------------------- | ||
2102 | * Frame control = 00 00 1010 | ||
2103 | * DA, SA, BSSID = x:x:x:x:x:x | ||
2104 | * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x | ||
2105 | * | x:x:x:x:x:x -- 22 bytes | ||
2106 | * | ||
2107 | * Deauthenticate pattern | ||
2108 | * ---------------------- | ||
2109 | * Frame control = 00 00 1100 | ||
2110 | * DA, SA, BSSID = x:x:x:x:x:x | ||
2111 | * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x | ||
2112 | * | x:x:x:x:x:x -- 22 bytes | ||
2113 | */ | ||
2114 | |||
2115 | /* Create Disassociate Pattern first */ | ||
2116 | |||
2117 | byte_cnt = 0; | ||
2118 | |||
2119 | /* Fill out the mask with all FF's */ | ||
2120 | |||
2121 | for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++) | ||
2122 | dis_deauth_mask[i] = 0xff; | ||
2123 | |||
2124 | /* copy the first byte of frame control field */ | ||
2125 | dis_deauth_pattern[byte_cnt] = 0xa0; | ||
2126 | byte_cnt++; | ||
2127 | |||
2128 | /* skip 2nd byte of frame control and Duration field */ | ||
2129 | byte_cnt += 3; | ||
2130 | |||
2131 | /* | ||
2132 | * need not match the destination mac address, it can be a broadcast | ||
2133 | * mac address or an unicast to this station | ||
2134 | */ | ||
2135 | byte_cnt += 6; | ||
2136 | |||
2137 | /* copy the source mac address */ | ||
2138 | memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); | ||
2139 | |||
2140 | byte_cnt += 6; | ||
2141 | |||
2142 | /* copy the bssid, its same as the source mac address */ | ||
2143 | |||
2144 | memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN); | ||
2145 | |||
2146 | /* Create Disassociate pattern mask */ | ||
2147 | |||
2148 | if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) { | ||
2149 | |||
2150 | if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) { | ||
2151 | /* | ||
2152 | * for AR9280, because of hardware limitation, the | ||
2153 | * first 4 bytes have to be matched for all patterns. | ||
2154 | * the mask for disassociation and de-auth pattern | ||
2155 | * matching need to enable the first 4 bytes. | ||
2156 | * also the duration field needs to be filled. | ||
2157 | */ | ||
2158 | dis_deauth_mask[0] = 0xf0; | ||
2159 | |||
2160 | /* | ||
2161 | * fill in duration field | ||
2162 | FIXME: what is the exact value ? | ||
2163 | */ | ||
2164 | dis_deauth_pattern[2] = 0xff; | ||
2165 | dis_deauth_pattern[3] = 0xff; | ||
2166 | } else { | ||
2167 | dis_deauth_mask[0] = 0xfe; | ||
2168 | } | ||
2169 | |||
2170 | dis_deauth_mask[1] = 0x03; | ||
2171 | dis_deauth_mask[2] = 0xc0; | ||
2172 | } else { | ||
2173 | dis_deauth_mask[0] = 0xef; | ||
2174 | dis_deauth_mask[1] = 0x3f; | ||
2175 | dis_deauth_mask[2] = 0x00; | ||
2176 | dis_deauth_mask[3] = 0xfc; | ||
2177 | } | ||
2178 | |||
2179 | ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n"); | ||
2180 | |||
2181 | ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, | ||
2182 | pattern_count, byte_cnt); | ||
2183 | |||
2184 | pattern_count++; | ||
2185 | /* | ||
2186 | * for de-authenticate pattern, only the first byte of the frame | ||
2187 | * control field gets changed from 0xA0 to 0xC0 | ||
2188 | */ | ||
2189 | dis_deauth_pattern[0] = 0xC0; | ||
2190 | |||
2191 | ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask, | ||
2192 | pattern_count, byte_cnt); | ||
2193 | |||
2194 | } | ||
2195 | |||
2196 | static void ath9k_wow_add_pattern(struct ath_softc *sc, | ||
2197 | struct cfg80211_wowlan *wowlan) | ||
2198 | { | ||
2199 | struct ath_hw *ah = sc->sc_ah; | ||
2200 | struct ath9k_wow_pattern *wow_pattern = NULL; | ||
2201 | struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns; | ||
2202 | int mask_len; | ||
2203 | s8 i = 0; | ||
2204 | |||
2205 | if (!wowlan->n_patterns) | ||
2206 | return; | ||
2207 | |||
2208 | /* | ||
2209 | * Add the new user configured patterns | ||
2210 | */ | ||
2211 | for (i = 0; i < wowlan->n_patterns; i++) { | ||
2212 | |||
2213 | wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL); | ||
2214 | |||
2215 | if (!wow_pattern) | ||
2216 | return; | ||
2217 | |||
2218 | /* | ||
2219 | * TODO: convert the generic user space pattern to | ||
2220 | * appropriate chip specific/802.11 pattern. | ||
2221 | */ | ||
2222 | |||
2223 | mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8); | ||
2224 | memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE); | ||
2225 | memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE); | ||
2226 | memcpy(wow_pattern->pattern_bytes, patterns[i].pattern, | ||
2227 | patterns[i].pattern_len); | ||
2228 | memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len); | ||
2229 | wow_pattern->pattern_len = patterns[i].pattern_len; | ||
2230 | |||
2231 | /* | ||
2232 | * just need to take care of deauth and disssoc pattern, | ||
2233 | * make sure we don't overwrite them. | ||
2234 | */ | ||
2235 | |||
2236 | ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes, | ||
2237 | wow_pattern->mask_bytes, | ||
2238 | i + 2, | ||
2239 | wow_pattern->pattern_len); | ||
2240 | kfree(wow_pattern); | ||
2241 | |||
2242 | } | ||
2243 | |||
2244 | } | ||
2245 | |||
2246 | static int ath9k_suspend(struct ieee80211_hw *hw, | ||
2247 | struct cfg80211_wowlan *wowlan) | ||
2248 | { | ||
2249 | struct ath_softc *sc = hw->priv; | ||
2250 | struct ath_hw *ah = sc->sc_ah; | ||
2251 | struct ath_common *common = ath9k_hw_common(ah); | ||
2252 | u32 wow_triggers_enabled = 0; | ||
2253 | int ret = 0; | ||
2254 | |||
2255 | mutex_lock(&sc->mutex); | ||
2256 | |||
2257 | ath_cancel_work(sc); | ||
2258 | del_timer_sync(&common->ani.timer); | ||
2259 | del_timer_sync(&sc->rx_poll_timer); | ||
2260 | |||
2261 | if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { | ||
2262 | ath_dbg(common, ANY, "Device not present\n"); | ||
2263 | ret = -EINVAL; | ||
2264 | goto fail_wow; | ||
2265 | } | ||
2266 | |||
2267 | if (WARN_ON(!wowlan)) { | ||
2268 | ath_dbg(common, WOW, "None of the WoW triggers enabled\n"); | ||
2269 | ret = -EINVAL; | ||
2270 | goto fail_wow; | ||
2271 | } | ||
2272 | |||
2273 | if (!device_can_wakeup(sc->dev)) { | ||
2274 | ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n"); | ||
2275 | ret = 1; | ||
2276 | goto fail_wow; | ||
2277 | } | ||
2278 | |||
2279 | /* | ||
2280 | * none of the sta vifs are associated | ||
2281 | * and we are not currently handling multivif | ||
2282 | * cases, for instance we have to seperately | ||
2283 | * configure 'keep alive frame' for each | ||
2284 | * STA. | ||
2285 | */ | ||
2286 | |||
2287 | if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { | ||
2288 | ath_dbg(common, WOW, "None of the STA vifs are associated\n"); | ||
2289 | ret = 1; | ||
2290 | goto fail_wow; | ||
2291 | } | ||
2292 | |||
2293 | if (sc->nvifs > 1) { | ||
2294 | ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); | ||
2295 | ret = 1; | ||
2296 | goto fail_wow; | ||
2297 | } | ||
2298 | |||
2299 | ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled); | ||
2300 | |||
2301 | ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n", | ||
2302 | wow_triggers_enabled); | ||
2303 | |||
2304 | ath9k_ps_wakeup(sc); | ||
2305 | |||
2306 | ath9k_stop_btcoex(sc); | ||
2307 | |||
2308 | /* | ||
2309 | * Enable wake up on recieving disassoc/deauth | ||
2310 | * frame by default. | ||
2311 | */ | ||
2312 | ath9k_wow_add_disassoc_deauth_pattern(sc); | ||
2313 | |||
2314 | if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN) | ||
2315 | ath9k_wow_add_pattern(sc, wowlan); | ||
2316 | |||
2317 | spin_lock_bh(&sc->sc_pcu_lock); | ||
2318 | /* | ||
2319 | * To avoid false wake, we enable beacon miss interrupt only | ||
2320 | * when we go to sleep. We save the current interrupt mask | ||
2321 | * so we can restore it after the system wakes up | ||
2322 | */ | ||
2323 | sc->wow_intr_before_sleep = ah->imask; | ||
2324 | ah->imask &= ~ATH9K_INT_GLOBAL; | ||
2325 | ath9k_hw_disable_interrupts(ah); | ||
2326 | ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL; | ||
2327 | ath9k_hw_set_interrupts(ah); | ||
2328 | ath9k_hw_enable_interrupts(ah); | ||
2329 | |||
2330 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
2331 | |||
2332 | /* | ||
2333 | * we can now sync irq and kill any running tasklets, since we already | ||
2334 | * disabled interrupts and not holding a spin lock | ||
2335 | */ | ||
2336 | synchronize_irq(sc->irq); | ||
2337 | tasklet_kill(&sc->intr_tq); | ||
2338 | |||
2339 | ath9k_hw_wow_enable(ah, wow_triggers_enabled); | ||
2340 | |||
2341 | ath9k_ps_restore(sc); | ||
2342 | ath_dbg(common, ANY, "WoW enabled in ath9k\n"); | ||
2343 | atomic_inc(&sc->wow_sleep_proc_intr); | ||
2344 | |||
2345 | fail_wow: | ||
2346 | mutex_unlock(&sc->mutex); | ||
2347 | return ret; | ||
2348 | } | ||
2349 | |||
2350 | static int ath9k_resume(struct ieee80211_hw *hw) | ||
2351 | { | ||
2352 | struct ath_softc *sc = hw->priv; | ||
2353 | struct ath_hw *ah = sc->sc_ah; | ||
2354 | struct ath_common *common = ath9k_hw_common(ah); | ||
2355 | u32 wow_status; | ||
2356 | |||
2357 | mutex_lock(&sc->mutex); | ||
2358 | |||
2359 | ath9k_ps_wakeup(sc); | ||
2360 | |||
2361 | spin_lock_bh(&sc->sc_pcu_lock); | ||
2362 | |||
2363 | ath9k_hw_disable_interrupts(ah); | ||
2364 | ah->imask = sc->wow_intr_before_sleep; | ||
2365 | ath9k_hw_set_interrupts(ah); | ||
2366 | ath9k_hw_enable_interrupts(ah); | ||
2367 | |||
2368 | spin_unlock_bh(&sc->sc_pcu_lock); | ||
2369 | |||
2370 | wow_status = ath9k_hw_wow_wakeup(ah); | ||
2371 | |||
2372 | if (atomic_read(&sc->wow_got_bmiss_intr) == 0) { | ||
2373 | /* | ||
2374 | * some devices may not pick beacon miss | ||
2375 | * as the reason they woke up so we add | ||
2376 | * that here for that shortcoming. | ||
2377 | */ | ||
2378 | wow_status |= AH_WOW_BEACON_MISS; | ||
2379 | atomic_dec(&sc->wow_got_bmiss_intr); | ||
2380 | ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n"); | ||
2381 | } | ||
2382 | |||
2383 | atomic_dec(&sc->wow_sleep_proc_intr); | ||
2384 | |||
2385 | if (wow_status) { | ||
2386 | ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n", | ||
2387 | ath9k_hw_wow_event_to_string(wow_status), wow_status); | ||
2388 | } | ||
2389 | |||
2390 | ath_restart_work(sc); | ||
2391 | ath9k_start_btcoex(sc); | ||
2392 | |||
2393 | ath9k_ps_restore(sc); | ||
2394 | mutex_unlock(&sc->mutex); | ||
2395 | |||
2396 | return 0; | ||
2397 | } | ||
2398 | |||
2399 | static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) | ||
2400 | { | ||
2401 | struct ath_softc *sc = hw->priv; | ||
2402 | |||
2403 | mutex_lock(&sc->mutex); | ||
2404 | device_init_wakeup(sc->dev, 1); | ||
2405 | device_set_wakeup_enable(sc->dev, enabled); | ||
2406 | mutex_unlock(&sc->mutex); | ||
2407 | } | ||
2408 | |||
2409 | #endif | ||
2410 | |||
2078 | struct ieee80211_ops ath9k_ops = { | 2411 | struct ieee80211_ops ath9k_ops = { |
2079 | .tx = ath9k_tx, | 2412 | .tx = ath9k_tx, |
2080 | .start = ath9k_start, | 2413 | .start = ath9k_start, |
@@ -2104,6 +2437,12 @@ struct ieee80211_ops ath9k_ops = { | |||
2104 | .set_antenna = ath9k_set_antenna, | 2437 | .set_antenna = ath9k_set_antenna, |
2105 | .get_antenna = ath9k_get_antenna, | 2438 | .get_antenna = ath9k_get_antenna, |
2106 | 2439 | ||
2440 | #ifdef CONFIG_PM_SLEEP | ||
2441 | .suspend = ath9k_suspend, | ||
2442 | .resume = ath9k_resume, | ||
2443 | .set_wakeup = ath9k_set_wakeup, | ||
2444 | #endif | ||
2445 | |||
2107 | #ifdef CONFIG_ATH9K_DEBUGFS | 2446 | #ifdef CONFIG_ATH9K_DEBUGFS |
2108 | .get_et_sset_count = ath9k_get_et_sset_count, | 2447 | .get_et_sset_count = ath9k_get_et_sset_count, |
2109 | .get_et_stats = ath9k_get_et_stats, | 2448 | .get_et_stats = ath9k_get_et_stats, |
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index 87acff7fdaae..fb536e7e661b 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c | |||
@@ -202,7 +202,7 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) | |||
202 | case MCI_GPM_BT_CAL_REQ: | 202 | case MCI_GPM_BT_CAL_REQ: |
203 | if (mci_hw->bt_state == MCI_BT_AWAKE) { | 203 | if (mci_hw->bt_state == MCI_BT_AWAKE) { |
204 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); | 204 | ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); |
205 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | 205 | ath9k_queue_reset(sc, RESET_TYPE_MCI); |
206 | } | 206 | } |
207 | ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); | 207 | ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); |
208 | break; | 208 | break; |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index aa0e83ac51f4..87b89d55e637 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -313,6 +313,9 @@ static int ath_pci_suspend(struct device *device) | |||
313 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 313 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
314 | struct ath_softc *sc = hw->priv; | 314 | struct ath_softc *sc = hw->priv; |
315 | 315 | ||
316 | if (sc->wow_enabled) | ||
317 | return 0; | ||
318 | |||
316 | /* The device has to be moved to FULLSLEEP forcibly. | 319 | /* The device has to be moved to FULLSLEEP forcibly. |
317 | * Otherwise the chip never moved to full sleep, | 320 | * Otherwise the chip never moved to full sleep, |
318 | * when no interface is up. | 321 | * when no interface is up. |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 11f3703a420a..12aca02228c2 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -553,7 +553,7 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
553 | sc->ps_flags &= ~PS_BEACON_SYNC; | 553 | sc->ps_flags &= ~PS_BEACON_SYNC; |
554 | ath_dbg(common, PS, | 554 | ath_dbg(common, PS, |
555 | "Reconfigure Beacon timers based on timestamp from the AP\n"); | 555 | "Reconfigure Beacon timers based on timestamp from the AP\n"); |
556 | ath_set_beacon(sc); | 556 | ath9k_set_beacon(sc); |
557 | } | 557 | } |
558 | 558 | ||
559 | if (ath_beacon_dtim_pending_cab(skb)) { | 559 | if (ath_beacon_dtim_pending_cab(skb)) { |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 6592c07ac646..87cac8eb7834 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -696,9 +696,12 @@ | |||
696 | #define AR_WA_BIT7 (1 << 7) | 696 | #define AR_WA_BIT7 (1 << 7) |
697 | #define AR_WA_BIT23 (1 << 23) | 697 | #define AR_WA_BIT23 (1 << 23) |
698 | #define AR_WA_D3_L1_DISABLE (1 << 14) | 698 | #define AR_WA_D3_L1_DISABLE (1 << 14) |
699 | #define AR_WA_UNTIE_RESET_EN (1 << 15) /* Enable PCI Reset | ||
700 | to POR (power-on-reset) */ | ||
699 | #define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16) | 701 | #define AR_WA_D3_TO_L1_DISABLE_REAL (1 << 16) |
700 | #define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17) | 702 | #define AR_WA_ASPM_TIMER_BASED_DISABLE (1 << 17) |
701 | #define AR_WA_RESET_EN (1 << 18) /* Sw Control to enable PCI-Reset to POR (bit 15) */ | 703 | #define AR_WA_RESET_EN (1 << 18) /* Enable PCI-Reset to |
704 | POR (bit 15) */ | ||
702 | #define AR_WA_ANALOG_SHIFT (1 << 20) | 705 | #define AR_WA_ANALOG_SHIFT (1 << 20) |
703 | #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ | 706 | #define AR_WA_POR_SHORT (1 << 21) /* PCI-E Phy reset control */ |
704 | #define AR_WA_BIT22 (1 << 22) | 707 | #define AR_WA_BIT22 (1 << 22) |
@@ -1032,6 +1035,8 @@ enum { | |||
1032 | #define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014) | 1035 | #define AR_PCIE_PM_CTRL (AR_SREV_9340(ah) ? 0x4004 : 0x4014) |
1033 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 | 1036 | #define AR_PCIE_PM_CTRL_ENA 0x00080000 |
1034 | 1037 | ||
1038 | #define AR_PCIE_PHY_REG3 0x18c08 | ||
1039 | |||
1035 | #define AR_NUM_GPIO 14 | 1040 | #define AR_NUM_GPIO 14 |
1036 | #define AR928X_NUM_GPIO 10 | 1041 | #define AR928X_NUM_GPIO 10 |
1037 | #define AR9285_NUM_GPIO 12 | 1042 | #define AR9285_NUM_GPIO 12 |
@@ -1235,6 +1240,8 @@ enum { | |||
1235 | #define AR_RTC_PLL_CLKSEL 0x00000300 | 1240 | #define AR_RTC_PLL_CLKSEL 0x00000300 |
1236 | #define AR_RTC_PLL_CLKSEL_S 8 | 1241 | #define AR_RTC_PLL_CLKSEL_S 8 |
1237 | #define AR_RTC_PLL_BYPASS 0x00010000 | 1242 | #define AR_RTC_PLL_BYPASS 0x00010000 |
1243 | #define AR_RTC_PLL_NOPWD 0x00040000 | ||
1244 | #define AR_RTC_PLL_NOPWD_S 18 | ||
1238 | 1245 | ||
1239 | #define PLL3 0x16188 | 1246 | #define PLL3 0x16188 |
1240 | #define PLL3_DO_MEAS_MASK 0x40000000 | 1247 | #define PLL3_DO_MEAS_MASK 0x40000000 |
@@ -1887,6 +1894,8 @@ enum { | |||
1887 | #define AR_PCU_MISC_MODE2_HWWAR2 0x02000000 | 1894 | #define AR_PCU_MISC_MODE2_HWWAR2 0x02000000 |
1888 | #define AR_PCU_MISC_MODE2_RESERVED2 0xFFFE0000 | 1895 | #define AR_PCU_MISC_MODE2_RESERVED2 0xFFFE0000 |
1889 | 1896 | ||
1897 | #define AR_PCU_MISC_MODE3 0x83d0 | ||
1898 | |||
1890 | #define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 | 1899 | #define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358 |
1891 | #define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 | 1900 | #define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400 |
1892 | #define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 | 1901 | #define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000 |
@@ -1909,6 +1918,140 @@ enum { | |||
1909 | #define AR_RATE_DURATION_32 0x8780 | 1918 | #define AR_RATE_DURATION_32 0x8780 |
1910 | #define AR_RATE_DURATION(_n) (AR_RATE_DURATION_0 + ((_n)<<2)) | 1919 | #define AR_RATE_DURATION(_n) (AR_RATE_DURATION_0 + ((_n)<<2)) |
1911 | 1920 | ||
1921 | /* WoW - Wake On Wireless */ | ||
1922 | |||
1923 | #define AR_PMCTRL_AUX_PWR_DET 0x10000000 /* Puts Chip in L2 state */ | ||
1924 | #define AR_PMCTRL_D3COLD_VAUX 0x00800000 | ||
1925 | #define AR_PMCTRL_HOST_PME_EN 0x00400000 /* Send OOB WAKE_L on WoW | ||
1926 | event */ | ||
1927 | #define AR_PMCTRL_WOW_PME_CLR 0x00200000 /* Clear WoW event */ | ||
1928 | #define AR_PMCTRL_PWR_STATE_MASK 0x0f000000 /* Power State Mask */ | ||
1929 | #define AR_PMCTRL_PWR_STATE_D1D3 0x0f000000 /* Activate D1 and D3 */ | ||
1930 | #define AR_PMCTRL_PWR_STATE_D1D3_REAL 0x0f000000 /* Activate D1 and D3 */ | ||
1931 | #define AR_PMCTRL_PWR_STATE_D0 0x08000000 /* Activate D0 */ | ||
1932 | #define AR_PMCTRL_PWR_PM_CTRL_ENA 0x00008000 /* Enable power mgmt */ | ||
1933 | |||
1934 | #define AR_WOW_BEACON_TIMO_MAX 0xffffffff | ||
1935 | |||
1936 | /* | ||
1937 | * MAC WoW Registers | ||
1938 | */ | ||
1939 | |||
1940 | #define AR_WOW_PATTERN 0x825C | ||
1941 | #define AR_WOW_COUNT 0x8260 | ||
1942 | #define AR_WOW_BCN_EN 0x8270 | ||
1943 | #define AR_WOW_BCN_TIMO 0x8274 | ||
1944 | #define AR_WOW_KEEP_ALIVE_TIMO 0x8278 | ||
1945 | #define AR_WOW_KEEP_ALIVE 0x827c | ||
1946 | #define AR_WOW_US_SCALAR 0x8284 | ||
1947 | #define AR_WOW_KEEP_ALIVE_DELAY 0x8288 | ||
1948 | #define AR_WOW_PATTERN_MATCH 0x828c | ||
1949 | #define AR_WOW_PATTERN_OFF1 0x8290 /* pattern bytes 0 -> 3 */ | ||
1950 | #define AR_WOW_PATTERN_OFF2 0x8294 /* pattern bytes 4 -> 7 */ | ||
1951 | |||
1952 | /* for AR9285 or later version of chips */ | ||
1953 | #define AR_WOW_EXACT 0x829c | ||
1954 | #define AR_WOW_LENGTH1 0x8360 | ||
1955 | #define AR_WOW_LENGTH2 0X8364 | ||
1956 | /* register to enable match for less than 256 bytes packets */ | ||
1957 | #define AR_WOW_PATTERN_MATCH_LT_256B 0x8368 | ||
1958 | |||
1959 | #define AR_SW_WOW_CONTROL 0x20018 | ||
1960 | #define AR_SW_WOW_ENABLE 0x1 | ||
1961 | #define AR_SWITCH_TO_REFCLK 0x2 | ||
1962 | #define AR_RESET_CONTROL 0x4 | ||
1963 | #define AR_RESET_VALUE_MASK 0x8 | ||
1964 | #define AR_HW_WOW_DISABLE 0x10 | ||
1965 | #define AR_CLR_MAC_INTERRUPT 0x20 | ||
1966 | #define AR_CLR_KA_INTERRUPT 0x40 | ||
1967 | |||
1968 | /* AR_WOW_PATTERN register values */ | ||
1969 | #define AR_WOW_BACK_OFF_SHIFT(x) ((x & 0xf) << 28) /* in usecs */ | ||
1970 | #define AR_WOW_MAC_INTR_EN 0x00040000 | ||
1971 | #define AR_WOW_MAGIC_EN 0x00010000 | ||
1972 | #define AR_WOW_PATTERN_EN(x) (x & 0xff) | ||
1973 | #define AR_WOW_PAT_FOUND_SHIFT 8 | ||
1974 | #define AR_WOW_PATTERN_FOUND(x) (x & (0xff << AR_WOW_PAT_FOUND_SHIFT)) | ||
1975 | #define AR_WOW_PATTERN_FOUND_MASK ((0xff) << AR_WOW_PAT_FOUND_SHIFT) | ||
1976 | #define AR_WOW_MAGIC_PAT_FOUND 0x00020000 | ||
1977 | #define AR_WOW_MAC_INTR 0x00080000 | ||
1978 | #define AR_WOW_KEEP_ALIVE_FAIL 0x00100000 | ||
1979 | #define AR_WOW_BEACON_FAIL 0x00200000 | ||
1980 | |||
1981 | #define AR_WOW_STATUS(x) (x & (AR_WOW_PATTERN_FOUND_MASK | \ | ||
1982 | AR_WOW_MAGIC_PAT_FOUND | \ | ||
1983 | AR_WOW_KEEP_ALIVE_FAIL | \ | ||
1984 | AR_WOW_BEACON_FAIL)) | ||
1985 | #define AR_WOW_CLEAR_EVENTS(x) (x & ~(AR_WOW_PATTERN_EN(0xff) | \ | ||
1986 | AR_WOW_MAGIC_EN | \ | ||
1987 | AR_WOW_MAC_INTR_EN | \ | ||
1988 | AR_WOW_BEACON_FAIL | \ | ||
1989 | AR_WOW_KEEP_ALIVE_FAIL)) | ||
1990 | |||
1991 | /* AR_WOW_COUNT register values */ | ||
1992 | #define AR_WOW_AIFS_CNT(x) (x & 0xff) | ||
1993 | #define AR_WOW_SLOT_CNT(x) ((x & 0xff) << 8) | ||
1994 | #define AR_WOW_KEEP_ALIVE_CNT(x) ((x & 0xff) << 16) | ||
1995 | |||
1996 | /* AR_WOW_BCN_EN register */ | ||
1997 | #define AR_WOW_BEACON_FAIL_EN 0x00000001 | ||
1998 | |||
1999 | /* AR_WOW_BCN_TIMO rgister */ | ||
2000 | #define AR_WOW_BEACON_TIMO 0x40000000 /* valid if BCN_EN is set */ | ||
2001 | |||
2002 | /* AR_WOW_KEEP_ALIVE_TIMO register */ | ||
2003 | #define AR_WOW_KEEP_ALIVE_TIMO_VALUE | ||
2004 | #define AR_WOW_KEEP_ALIVE_NEVER 0xffffffff | ||
2005 | |||
2006 | /* AR_WOW_KEEP_ALIVE register */ | ||
2007 | #define AR_WOW_KEEP_ALIVE_AUTO_DIS 0x00000001 | ||
2008 | #define AR_WOW_KEEP_ALIVE_FAIL_DIS 0x00000002 | ||
2009 | |||
2010 | /* AR_WOW_KEEP_ALIVE_DELAY register */ | ||
2011 | #define AR_WOW_KEEP_ALIVE_DELAY_VALUE 0x000003e8 /* 1 msec */ | ||
2012 | |||
2013 | |||
2014 | /* | ||
2015 | * keep it long for beacon workaround - ensure no false alarm | ||
2016 | */ | ||
2017 | #define AR_WOW_BMISSTHRESHOLD 0x20 | ||
2018 | |||
2019 | /* AR_WOW_PATTERN_MATCH register */ | ||
2020 | #define AR_WOW_PAT_END_OF_PKT(x) (x & 0xf) | ||
2021 | #define AR_WOW_PAT_OFF_MATCH(x) ((x & 0xf) << 8) | ||
2022 | |||
2023 | /* | ||
2024 | * default values for Wow Configuration for backoff, aifs, slot, keep-alive | ||
2025 | * to be programmed into various registers. | ||
2026 | */ | ||
2027 | #define AR_WOW_PAT_BACKOFF 0x00000004 /* AR_WOW_PATTERN_REG */ | ||
2028 | #define AR_WOW_CNT_AIFS_CNT 0x00000022 /* AR_WOW_COUNT_REG */ | ||
2029 | #define AR_WOW_CNT_SLOT_CNT 0x00000009 /* AR_WOW_COUNT_REG */ | ||
2030 | /* | ||
2031 | * Keepalive count applicable for AR9280 2.0 and above. | ||
2032 | */ | ||
2033 | #define AR_WOW_CNT_KA_CNT 0x00000008 /* AR_WOW_COUNT register */ | ||
2034 | |||
2035 | /* WoW - Transmit buffer for keep alive frames */ | ||
2036 | #define AR_WOW_TRANSMIT_BUFFER 0xe000 /* E000 - EFFC */ | ||
2037 | |||
2038 | #define AR_WOW_TXBUF(i) (AR_WOW_TRANSMIT_BUFFER + ((i) << 2)) | ||
2039 | |||
2040 | #define AR_WOW_KA_DESC_WORD2 0xe000 | ||
2041 | |||
2042 | #define AR_WOW_KA_DATA_WORD0 0xe030 | ||
2043 | |||
2044 | /* WoW Transmit Buffer for patterns */ | ||
2045 | #define AR_WOW_TB_PATTERN(i) (0xe100 + (i << 8)) | ||
2046 | #define AR_WOW_TB_MASK(i) (0xec00 + (i << 5)) | ||
2047 | |||
2048 | /* Currently Pattern 0-7 are supported - so bit 0-7 are set */ | ||
2049 | #define AR_WOW_PATTERN_SUPPORTED 0xff | ||
2050 | #define AR_WOW_LENGTH_MAX 0xff | ||
2051 | #define AR_WOW_LEN1_SHIFT(_i) ((0x3 - ((_i) & 0x3)) << 0x3) | ||
2052 | #define AR_WOW_LENGTH1_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN1_SHIFT(_i)) | ||
2053 | #define AR_WOW_LEN2_SHIFT(_i) ((0x7 - ((_i) & 0x7)) << 0x3) | ||
2054 | #define AR_WOW_LENGTH2_MASK(_i) (AR_WOW_LENGTH_MAX << AR_WOW_LEN2_SHIFT(_i)) | ||
1912 | 2055 | ||
1913 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ | 2056 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ |
1914 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ | 2057 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ |
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c new file mode 100644 index 000000000000..44a08eb53c62 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -0,0 +1,532 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Qualcomm Atheros, Inc. | ||
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 | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/export.h> | ||
18 | #include "ath9k.h" | ||
19 | #include "reg.h" | ||
20 | #include "hw-ops.h" | ||
21 | |||
22 | const char *ath9k_hw_wow_event_to_string(u32 wow_event) | ||
23 | { | ||
24 | if (wow_event & AH_WOW_MAGIC_PATTERN_EN) | ||
25 | return "Magic pattern"; | ||
26 | if (wow_event & AH_WOW_USER_PATTERN_EN) | ||
27 | return "User pattern"; | ||
28 | if (wow_event & AH_WOW_LINK_CHANGE) | ||
29 | return "Link change"; | ||
30 | if (wow_event & AH_WOW_BEACON_MISS) | ||
31 | return "Beacon miss"; | ||
32 | |||
33 | return "unknown reason"; | ||
34 | } | ||
35 | EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); | ||
36 | |||
37 | static void ath9k_hw_config_serdes_wow_sleep(struct ath_hw *ah) | ||
38 | { | ||
39 | int i; | ||
40 | |||
41 | for (i = 0; i < ah->iniPcieSerdesWow.ia_rows; i++) | ||
42 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdesWow, i, 0), | ||
43 | INI_RA(&ah->iniPcieSerdesWow, i, 1)); | ||
44 | |||
45 | usleep_range(1000, 1500); | ||
46 | } | ||
47 | |||
48 | static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) | ||
49 | { | ||
50 | struct ath_common *common = ath9k_hw_common(ah); | ||
51 | |||
52 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | ||
53 | |||
54 | /* set rx disable bit */ | ||
55 | REG_WRITE(ah, AR_CR, AR_CR_RXD); | ||
56 | |||
57 | if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) { | ||
58 | ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n", | ||
59 | REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW)); | ||
60 | return; | ||
61 | } else { | ||
62 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
63 | REG_WRITE(ah, AR_RXDP, 0x0); | ||
64 | } | ||
65 | |||
66 | /* AR9280 WoW has sleep issue, do not set it to sleep */ | ||
67 | if (AR_SREV_9280_20(ah)) | ||
68 | return; | ||
69 | |||
70 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); | ||
71 | } | ||
72 | |||
73 | static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah) | ||
74 | { | ||
75 | struct ath_common *common = ath9k_hw_common(ah); | ||
76 | u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN]; | ||
77 | u32 ctl[13] = {0}; | ||
78 | u32 data_word[KAL_NUM_DATA_WORDS]; | ||
79 | u8 i; | ||
80 | u32 wow_ka_data_word0; | ||
81 | |||
82 | memcpy(sta_mac_addr, common->macaddr, ETH_ALEN); | ||
83 | memcpy(ap_mac_addr, common->curbssid, ETH_ALEN); | ||
84 | |||
85 | /* set the transmit buffer */ | ||
86 | ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16)); | ||
87 | |||
88 | if (!(AR_SREV_9300_20_OR_LATER(ah))) | ||
89 | ctl[0] += (KAL_ANTENNA_MODE << 25); | ||
90 | |||
91 | ctl[1] = 0; | ||
92 | ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */ | ||
93 | ctl[4] = 0; | ||
94 | ctl[7] = (ah->txchainmask) << 2; | ||
95 | |||
96 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
97 | ctl[2] = 0xf << 16; /* tx_tries 0 */ | ||
98 | else | ||
99 | ctl[2] = 0x7 << 16; /* tx_tries 0 */ | ||
100 | |||
101 | |||
102 | for (i = 0; i < KAL_NUM_DESC_WORDS; i++) | ||
103 | REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); | ||
104 | |||
105 | /* for AR9300 family 13 descriptor words */ | ||
106 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
107 | REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]); | ||
108 | |||
109 | data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) | | ||
110 | (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16); | ||
111 | data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | | ||
112 | (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); | ||
113 | data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) | | ||
114 | (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); | ||
115 | data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) | | ||
116 | (sta_mac_addr[3] << 8) | (sta_mac_addr[2]); | ||
117 | data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) | | ||
118 | (ap_mac_addr[1] << 8) | (ap_mac_addr[0]); | ||
119 | data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]); | ||
120 | |||
121 | if (AR_SREV_9462_20_OR_LATER(ah)) { | ||
122 | /* AR9462 2.0 has an extra descriptor word (time based | ||
123 | * discard) compared to other chips */ | ||
124 | REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0); | ||
125 | wow_ka_data_word0 = AR_WOW_TXBUF(13); | ||
126 | } else { | ||
127 | wow_ka_data_word0 = AR_WOW_TXBUF(12); | ||
128 | } | ||
129 | |||
130 | for (i = 0; i < KAL_NUM_DATA_WORDS; i++) | ||
131 | REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); | ||
132 | |||
133 | } | ||
134 | |||
135 | void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, | ||
136 | u8 *user_mask, int pattern_count, | ||
137 | int pattern_len) | ||
138 | { | ||
139 | int i; | ||
140 | u32 pattern_val, mask_val; | ||
141 | u32 set, clr; | ||
142 | |||
143 | /* FIXME: should check count by querying the hardware capability */ | ||
144 | if (pattern_count >= MAX_NUM_PATTERN) | ||
145 | return; | ||
146 | |||
147 | REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); | ||
148 | |||
149 | /* set the registers for pattern */ | ||
150 | for (i = 0; i < MAX_PATTERN_SIZE; i += 4) { | ||
151 | memcpy(&pattern_val, user_pattern, 4); | ||
152 | REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i), | ||
153 | pattern_val); | ||
154 | user_pattern += 4; | ||
155 | } | ||
156 | |||
157 | /* set the registers for mask */ | ||
158 | for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) { | ||
159 | memcpy(&mask_val, user_mask, 4); | ||
160 | REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val); | ||
161 | user_mask += 4; | ||
162 | } | ||
163 | |||
164 | /* set the pattern length to be matched | ||
165 | * | ||
166 | * AR_WOW_LENGTH1_REG1 | ||
167 | * bit 31:24 pattern 0 length | ||
168 | * bit 23:16 pattern 1 length | ||
169 | * bit 15:8 pattern 2 length | ||
170 | * bit 7:0 pattern 3 length | ||
171 | * | ||
172 | * AR_WOW_LENGTH1_REG2 | ||
173 | * bit 31:24 pattern 4 length | ||
174 | * bit 23:16 pattern 5 length | ||
175 | * bit 15:8 pattern 6 length | ||
176 | * bit 7:0 pattern 7 length | ||
177 | * | ||
178 | * the below logic writes out the new | ||
179 | * pattern length for the corresponding | ||
180 | * pattern_count, while masking out the | ||
181 | * other fields | ||
182 | */ | ||
183 | |||
184 | ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); | ||
185 | |||
186 | if (!AR_SREV_9285_12_OR_LATER(ah)) | ||
187 | return; | ||
188 | |||
189 | if (pattern_count < 4) { | ||
190 | /* Pattern 0-3 uses AR_WOW_LENGTH1 register */ | ||
191 | set = (pattern_len & AR_WOW_LENGTH_MAX) << | ||
192 | AR_WOW_LEN1_SHIFT(pattern_count); | ||
193 | clr = AR_WOW_LENGTH1_MASK(pattern_count); | ||
194 | REG_RMW(ah, AR_WOW_LENGTH1, set, clr); | ||
195 | } else { | ||
196 | /* Pattern 4-7 uses AR_WOW_LENGTH2 register */ | ||
197 | set = (pattern_len & AR_WOW_LENGTH_MAX) << | ||
198 | AR_WOW_LEN2_SHIFT(pattern_count); | ||
199 | clr = AR_WOW_LENGTH2_MASK(pattern_count); | ||
200 | REG_RMW(ah, AR_WOW_LENGTH2, set, clr); | ||
201 | } | ||
202 | |||
203 | } | ||
204 | EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); | ||
205 | |||
206 | u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) | ||
207 | { | ||
208 | u32 wow_status = 0; | ||
209 | u32 val = 0, rval; | ||
210 | /* | ||
211 | * read the WoW status register to know | ||
212 | * the wakeup reason | ||
213 | */ | ||
214 | rval = REG_READ(ah, AR_WOW_PATTERN); | ||
215 | val = AR_WOW_STATUS(rval); | ||
216 | |||
217 | /* | ||
218 | * mask only the WoW events that we have enabled. Sometimes | ||
219 | * we have spurious WoW events from the AR_WOW_PATTERN | ||
220 | * register. This mask will clean it up. | ||
221 | */ | ||
222 | |||
223 | val &= ah->wow_event_mask; | ||
224 | |||
225 | if (val) { | ||
226 | |||
227 | if (val & AR_WOW_MAGIC_PAT_FOUND) | ||
228 | wow_status |= AH_WOW_MAGIC_PATTERN_EN; | ||
229 | |||
230 | if (AR_WOW_PATTERN_FOUND(val)) | ||
231 | wow_status |= AH_WOW_USER_PATTERN_EN; | ||
232 | |||
233 | if (val & AR_WOW_KEEP_ALIVE_FAIL) | ||
234 | wow_status |= AH_WOW_LINK_CHANGE; | ||
235 | |||
236 | if (val & AR_WOW_BEACON_FAIL) | ||
237 | wow_status |= AH_WOW_BEACON_MISS; | ||
238 | |||
239 | } | ||
240 | |||
241 | /* | ||
242 | * set and clear WOW_PME_CLEAR registers for the chip to | ||
243 | * generate next wow signal. | ||
244 | * disable D3 before accessing other registers ? | ||
245 | */ | ||
246 | |||
247 | /* do we need to check the bit value 0x01000000 (7-10) ?? */ | ||
248 | REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR, | ||
249 | AR_PMCTRL_PWR_STATE_D1D3); | ||
250 | |||
251 | /* | ||
252 | * clear all events | ||
253 | */ | ||
254 | REG_WRITE(ah, AR_WOW_PATTERN, | ||
255 | AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); | ||
256 | |||
257 | /* | ||
258 | * tie reset register for AR9002 family of chipsets | ||
259 | * NB: not tieing it back might have some repurcussions. | ||
260 | */ | ||
261 | |||
262 | if (!AR_SREV_9300_20_OR_LATER(ah)) { | ||
263 | REG_SET_BIT(ah, AR_WA, AR_WA_UNTIE_RESET_EN | | ||
264 | AR_WA_POR_SHORT | AR_WA_RESET_EN); | ||
265 | } | ||
266 | |||
267 | |||
268 | /* | ||
269 | * restore the beacon threshold to init value | ||
270 | */ | ||
271 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); | ||
272 | |||
273 | /* | ||
274 | * Restore the way the PCI-E reset, Power-On-Reset, external | ||
275 | * PCIE_POR_SHORT pins are tied to its original value. | ||
276 | * Previously just before WoW sleep, we untie the PCI-E | ||
277 | * reset to our Chip's Power On Reset so that any PCI-E | ||
278 | * reset from the bus will not reset our chip | ||
279 | */ | ||
280 | |||
281 | if (AR_SREV_9280_20_OR_LATER(ah) && ah->is_pciexpress) | ||
282 | ath9k_hw_configpcipowersave(ah, false); | ||
283 | |||
284 | ah->wow_event_mask = 0; | ||
285 | |||
286 | return wow_status; | ||
287 | } | ||
288 | EXPORT_SYMBOL(ath9k_hw_wow_wakeup); | ||
289 | |||
290 | void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) | ||
291 | { | ||
292 | u32 wow_event_mask; | ||
293 | u32 set, clr; | ||
294 | |||
295 | /* | ||
296 | * wow_event_mask is a mask to the AR_WOW_PATTERN register to | ||
297 | * indicate which WoW events we have enabled. The WoW events | ||
298 | * are from the 'pattern_enable' in this function and | ||
299 | * 'pattern_count' of ath9k_hw_wow_apply_pattern() | ||
300 | */ | ||
301 | |||
302 | wow_event_mask = ah->wow_event_mask; | ||
303 | |||
304 | /* | ||
305 | * Untie Power-on-Reset from the PCI-E-Reset. When we are in | ||
306 | * WOW sleep, we do want the Reset from the PCI-E to disturb | ||
307 | * our hw state | ||
308 | */ | ||
309 | |||
310 | if (ah->is_pciexpress) { | ||
311 | |||
312 | /* | ||
313 | * we need to untie the internal POR (power-on-reset) | ||
314 | * to the external PCI-E reset. We also need to tie | ||
315 | * the PCI-E Phy reset to the PCI-E reset. | ||
316 | */ | ||
317 | |||
318 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
319 | set = AR_WA_RESET_EN | AR_WA_POR_SHORT; | ||
320 | clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE; | ||
321 | REG_RMW(ah, AR_WA, set, clr); | ||
322 | } else { | ||
323 | if (AR_SREV_9285(ah) || AR_SREV_9287(ah)) | ||
324 | set = AR9285_WA_DEFAULT; | ||
325 | else | ||
326 | set = AR9280_WA_DEFAULT; | ||
327 | |||
328 | /* | ||
329 | * In AR9280 and AR9285, bit 14 in WA register | ||
330 | * (disable L1) should only be set when device | ||
331 | * enters D3 state and be cleared when device | ||
332 | * comes back to D0 | ||
333 | */ | ||
334 | |||
335 | if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) | ||
336 | set |= AR_WA_D3_L1_DISABLE; | ||
337 | |||
338 | clr = AR_WA_UNTIE_RESET_EN; | ||
339 | set |= AR_WA_RESET_EN | AR_WA_POR_SHORT; | ||
340 | REG_RMW(ah, AR_WA, set, clr); | ||
341 | |||
342 | /* | ||
343 | * for WoW sleep, we reprogram the SerDes so that the | ||
344 | * PLL and CLK REQ are both enabled. This uses more | ||
345 | * power but otherwise WoW sleep is unstable and the | ||
346 | * chip may disappear. | ||
347 | */ | ||
348 | |||
349 | if (AR_SREV_9285_12_OR_LATER(ah)) | ||
350 | ath9k_hw_config_serdes_wow_sleep(ah); | ||
351 | |||
352 | } | ||
353 | } | ||
354 | |||
355 | /* | ||
356 | * set the power states appropriately and enable PME | ||
357 | */ | ||
358 | set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA | | ||
359 | AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR; | ||
360 | |||
361 | /* | ||
362 | * set and clear WOW_PME_CLEAR registers for the chip | ||
363 | * to generate next wow signal. | ||
364 | */ | ||
365 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); | ||
366 | clr = AR_PMCTRL_WOW_PME_CLR; | ||
367 | REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); | ||
368 | |||
369 | /* | ||
370 | * Setup for: | ||
371 | * - beacon misses | ||
372 | * - magic pattern | ||
373 | * - keep alive timeout | ||
374 | * - pattern matching | ||
375 | */ | ||
376 | |||
377 | /* | ||
378 | * Program default values for pattern backoff, aifs/slot/KAL count, | ||
379 | * beacon miss timeout, KAL timeout, etc. | ||
380 | */ | ||
381 | |||
382 | set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF); | ||
383 | REG_SET_BIT(ah, AR_WOW_PATTERN, set); | ||
384 | |||
385 | set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) | | ||
386 | AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) | | ||
387 | AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT); | ||
388 | REG_SET_BIT(ah, AR_WOW_COUNT, set); | ||
389 | |||
390 | if (pattern_enable & AH_WOW_BEACON_MISS) | ||
391 | set = AR_WOW_BEACON_TIMO; | ||
392 | /* We are not using beacon miss, program a large value */ | ||
393 | else | ||
394 | set = AR_WOW_BEACON_TIMO_MAX; | ||
395 | |||
396 | REG_WRITE(ah, AR_WOW_BCN_TIMO, set); | ||
397 | |||
398 | /* | ||
399 | * Keep alive timo in ms except AR9280 | ||
400 | */ | ||
401 | if (!pattern_enable || AR_SREV_9280(ah)) | ||
402 | set = AR_WOW_KEEP_ALIVE_NEVER; | ||
403 | else | ||
404 | set = KAL_TIMEOUT * 32; | ||
405 | |||
406 | REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); | ||
407 | |||
408 | /* | ||
409 | * Keep alive delay in us. based on 'power on clock', | ||
410 | * therefore in usec | ||
411 | */ | ||
412 | set = KAL_DELAY * 1000; | ||
413 | REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); | ||
414 | |||
415 | /* | ||
416 | * Create keep alive pattern to respond to beacons | ||
417 | */ | ||
418 | ath9k_wow_create_keep_alive_pattern(ah); | ||
419 | |||
420 | /* | ||
421 | * Configure MAC WoW Registers | ||
422 | */ | ||
423 | |||
424 | set = 0; | ||
425 | /* Send keep alive timeouts anyway */ | ||
426 | clr = AR_WOW_KEEP_ALIVE_AUTO_DIS; | ||
427 | |||
428 | if (pattern_enable & AH_WOW_LINK_CHANGE) | ||
429 | wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL; | ||
430 | else | ||
431 | set = AR_WOW_KEEP_ALIVE_FAIL_DIS; | ||
432 | |||
433 | /* | ||
434 | * FIXME: For now disable keep alive frame | ||
435 | * failure. This seems to sometimes trigger | ||
436 | * unnecessary wake up with AR9485 chipsets. | ||
437 | */ | ||
438 | set = AR_WOW_KEEP_ALIVE_FAIL_DIS; | ||
439 | |||
440 | REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); | ||
441 | |||
442 | |||
443 | /* | ||
444 | * we are relying on a bmiss failure. ensure we have | ||
445 | * enough threshold to prevent false positives | ||
446 | */ | ||
447 | REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, | ||
448 | AR_WOW_BMISSTHRESHOLD); | ||
449 | |||
450 | set = 0; | ||
451 | clr = 0; | ||
452 | |||
453 | if (pattern_enable & AH_WOW_BEACON_MISS) { | ||
454 | set = AR_WOW_BEACON_FAIL_EN; | ||
455 | wow_event_mask |= AR_WOW_BEACON_FAIL; | ||
456 | } else { | ||
457 | clr = AR_WOW_BEACON_FAIL_EN; | ||
458 | } | ||
459 | |||
460 | REG_RMW(ah, AR_WOW_BCN_EN, set, clr); | ||
461 | |||
462 | set = 0; | ||
463 | clr = 0; | ||
464 | /* | ||
465 | * Enable the magic packet registers | ||
466 | */ | ||
467 | if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) { | ||
468 | set = AR_WOW_MAGIC_EN; | ||
469 | wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND; | ||
470 | } else { | ||
471 | clr = AR_WOW_MAGIC_EN; | ||
472 | } | ||
473 | set |= AR_WOW_MAC_INTR_EN; | ||
474 | REG_RMW(ah, AR_WOW_PATTERN, set, clr); | ||
475 | |||
476 | /* | ||
477 | * For AR9285 and later version of chipsets | ||
478 | * enable WoW pattern match for packets less | ||
479 | * than 256 bytes for all patterns | ||
480 | */ | ||
481 | if (AR_SREV_9285_12_OR_LATER(ah)) | ||
482 | REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B, | ||
483 | AR_WOW_PATTERN_SUPPORTED); | ||
484 | |||
485 | /* | ||
486 | * Set the power states appropriately and enable PME | ||
487 | */ | ||
488 | clr = 0; | ||
489 | set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN | | ||
490 | AR_PMCTRL_PWR_PM_CTRL_ENA; | ||
491 | /* | ||
492 | * This is needed for AR9300 chipsets to wake-up | ||
493 | * the host. | ||
494 | */ | ||
495 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
496 | clr = AR_PCIE_PM_CTRL_ENA; | ||
497 | |||
498 | REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); | ||
499 | |||
500 | if (AR_SREV_9462(ah)) { | ||
501 | /* | ||
502 | * this is needed to prevent the chip waking up | ||
503 | * the host within 3-4 seconds with certain | ||
504 | * platform/BIOS. The fix is to enable | ||
505 | * D1 & D3 to match original definition and | ||
506 | * also match the OTP value. Anyway this | ||
507 | * is more related to SW WOW. | ||
508 | */ | ||
509 | clr = AR_PMCTRL_PWR_STATE_D1D3; | ||
510 | REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr); | ||
511 | |||
512 | set = AR_PMCTRL_PWR_STATE_D1D3_REAL; | ||
513 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); | ||
514 | } | ||
515 | |||
516 | |||
517 | |||
518 | REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); | ||
519 | |||
520 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
521 | /* to bring down WOW power low margin */ | ||
522 | set = BIT(13); | ||
523 | REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set); | ||
524 | /* HW WoW */ | ||
525 | clr = BIT(5); | ||
526 | REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr); | ||
527 | } | ||
528 | |||
529 | ath9k_hw_set_powermode_wow_sleep(ah); | ||
530 | ah->wow_event_mask = wow_event_mask; | ||
531 | } | ||
532 | EXPORT_SYMBOL(ath9k_hw_wow_enable); | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index cafb4a09729a..2c9da6b2ecb1 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #define HT_LTF(_ns) (4 * (_ns)) | 29 | #define HT_LTF(_ns) (4 * (_ns)) |
30 | #define SYMBOL_TIME(_ns) ((_ns) << 2) /* ns * 4 us */ | 30 | #define SYMBOL_TIME(_ns) ((_ns) << 2) /* ns * 4 us */ |
31 | #define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) /* ns * 3.6 us */ | 31 | #define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) /* ns * 3.6 us */ |
32 | #define TIME_SYMBOLS(t) ((t) >> 2) | ||
33 | #define TIME_SYMBOLS_HALFGI(t) (((t) * 5 - 4) / 18) | ||
32 | #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2) | 34 | #define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2) |
33 | #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18) | 35 | #define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18) |
34 | 36 | ||
@@ -74,33 +76,6 @@ enum { | |||
74 | MCS_HT40_SGI, | 76 | MCS_HT40_SGI, |
75 | }; | 77 | }; |
76 | 78 | ||
77 | static int ath_max_4ms_framelen[4][32] = { | ||
78 | [MCS_HT20] = { | ||
79 | 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172, | ||
80 | 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280, | ||
81 | 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532, | ||
82 | 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532, | ||
83 | }, | ||
84 | [MCS_HT20_SGI] = { | ||
85 | 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744, | ||
86 | 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532, | ||
87 | 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532, | ||
88 | 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532, | ||
89 | }, | ||
90 | [MCS_HT40] = { | ||
91 | 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532, | ||
92 | 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532, | ||
93 | 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532, | ||
94 | 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532, | ||
95 | }, | ||
96 | [MCS_HT40_SGI] = { | ||
97 | 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532, | ||
98 | 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532, | ||
99 | 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532, | ||
100 | 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532, | ||
101 | } | ||
102 | }; | ||
103 | |||
104 | /*********************/ | 79 | /*********************/ |
105 | /* Aggregation logic */ | 80 | /* Aggregation logic */ |
106 | /*********************/ | 81 | /*********************/ |
@@ -614,10 +589,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
614 | 589 | ||
615 | rcu_read_unlock(); | 590 | rcu_read_unlock(); |
616 | 591 | ||
617 | if (needreset) { | 592 | if (needreset) |
618 | RESET_STAT_INC(sc, RESET_TYPE_TX_ERROR); | 593 | ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR); |
619 | ieee80211_queue_work(sc->hw, &sc->hw_reset_work); | ||
620 | } | ||
621 | } | 594 | } |
622 | 595 | ||
623 | static bool ath_lookup_legacy(struct ath_buf *bf) | 596 | static bool ath_lookup_legacy(struct ath_buf *bf) |
@@ -650,6 +623,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
650 | struct ieee80211_tx_rate *rates; | 623 | struct ieee80211_tx_rate *rates; |
651 | u32 max_4ms_framelen, frmlen; | 624 | u32 max_4ms_framelen, frmlen; |
652 | u16 aggr_limit, bt_aggr_limit, legacy = 0; | 625 | u16 aggr_limit, bt_aggr_limit, legacy = 0; |
626 | int q = tid->ac->txq->mac80211_qnum; | ||
653 | int i; | 627 | int i; |
654 | 628 | ||
655 | skb = bf->bf_mpdu; | 629 | skb = bf->bf_mpdu; |
@@ -658,8 +632,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
658 | 632 | ||
659 | /* | 633 | /* |
660 | * Find the lowest frame length among the rate series that will have a | 634 | * Find the lowest frame length among the rate series that will have a |
661 | * 4ms transmit duration. | 635 | * 4ms (or TXOP limited) transmit duration. |
662 | * TODO - TXOP limit needs to be considered. | ||
663 | */ | 636 | */ |
664 | max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; | 637 | max_4ms_framelen = ATH_AMPDU_LIMIT_MAX; |
665 | 638 | ||
@@ -682,7 +655,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
682 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | 655 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) |
683 | modeidx++; | 656 | modeidx++; |
684 | 657 | ||
685 | frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; | 658 | frmlen = sc->tx.max_aggr_framelen[q][modeidx][rates[i].idx]; |
686 | max_4ms_framelen = min(max_4ms_framelen, frmlen); | 659 | max_4ms_framelen = min(max_4ms_framelen, frmlen); |
687 | } | 660 | } |
688 | 661 | ||
@@ -929,6 +902,44 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, int pktlen, | |||
929 | return duration; | 902 | return duration; |
930 | } | 903 | } |
931 | 904 | ||
905 | static int ath_max_framelen(int usec, int mcs, bool ht40, bool sgi) | ||
906 | { | ||
907 | int streams = HT_RC_2_STREAMS(mcs); | ||
908 | int symbols, bits; | ||
909 | int bytes = 0; | ||
910 | |||
911 | symbols = sgi ? TIME_SYMBOLS_HALFGI(usec) : TIME_SYMBOLS(usec); | ||
912 | bits = symbols * bits_per_symbol[mcs % 8][ht40] * streams; | ||
913 | bits -= OFDM_PLCP_BITS; | ||
914 | bytes = bits / 8; | ||
915 | bytes -= L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | ||
916 | if (bytes > 65532) | ||
917 | bytes = 65532; | ||
918 | |||
919 | return bytes; | ||
920 | } | ||
921 | |||
922 | void ath_update_max_aggr_framelen(struct ath_softc *sc, int queue, int txop) | ||
923 | { | ||
924 | u16 *cur_ht20, *cur_ht20_sgi, *cur_ht40, *cur_ht40_sgi; | ||
925 | int mcs; | ||
926 | |||
927 | /* 4ms is the default (and maximum) duration */ | ||
928 | if (!txop || txop > 4096) | ||
929 | txop = 4096; | ||
930 | |||
931 | cur_ht20 = sc->tx.max_aggr_framelen[queue][MCS_HT20]; | ||
932 | cur_ht20_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT20_SGI]; | ||
933 | cur_ht40 = sc->tx.max_aggr_framelen[queue][MCS_HT40]; | ||
934 | cur_ht40_sgi = sc->tx.max_aggr_framelen[queue][MCS_HT40_SGI]; | ||
935 | for (mcs = 0; mcs < 32; mcs++) { | ||
936 | cur_ht20[mcs] = ath_max_framelen(txop, mcs, false, false); | ||
937 | cur_ht20_sgi[mcs] = ath_max_framelen(txop, mcs, false, true); | ||
938 | cur_ht40[mcs] = ath_max_framelen(txop, mcs, true, false); | ||
939 | cur_ht40_sgi[mcs] = ath_max_framelen(txop, mcs, true, true); | ||
940 | } | ||
941 | } | ||
942 | |||
932 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, | 943 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, |
933 | struct ath_tx_info *info, int len) | 944 | struct ath_tx_info *info, int len) |
934 | { | 945 | { |
@@ -1403,16 +1414,6 @@ int ath_txq_update(struct ath_softc *sc, int qnum, | |||
1403 | int error = 0; | 1414 | int error = 0; |
1404 | struct ath9k_tx_queue_info qi; | 1415 | struct ath9k_tx_queue_info qi; |
1405 | 1416 | ||
1406 | if (qnum == sc->beacon.beaconq) { | ||
1407 | /* | ||
1408 | * XXX: for beacon queue, we just save the parameter. | ||
1409 | * It will be picked up by ath_beaconq_config when | ||
1410 | * it's necessary. | ||
1411 | */ | ||
1412 | sc->beacon.beacon_qi = *qinfo; | ||
1413 | return 0; | ||
1414 | } | ||
1415 | |||
1416 | BUG_ON(sc->tx.txq[qnum].axq_qnum != qnum); | 1417 | BUG_ON(sc->tx.txq[qnum].axq_qnum != qnum); |
1417 | 1418 | ||
1418 | ath9k_hw_get_txq_props(ah, qnum, &qi); | 1419 | ath9k_hw_get_txq_props(ah, qnum, &qi); |
@@ -1586,7 +1587,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
1586 | struct ath_atx_ac *ac, *ac_tmp, *last_ac; | 1587 | struct ath_atx_ac *ac, *ac_tmp, *last_ac; |
1587 | struct ath_atx_tid *tid, *last_tid; | 1588 | struct ath_atx_tid *tid, *last_tid; |
1588 | 1589 | ||
1589 | if (work_pending(&sc->hw_reset_work) || list_empty(&txq->axq_acq) || | 1590 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags) || |
1591 | list_empty(&txq->axq_acq) || | ||
1590 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) | 1592 | txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) |
1591 | return; | 1593 | return; |
1592 | 1594 | ||
@@ -1988,7 +1990,8 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1988 | 1990 | ||
1989 | ath_txq_lock(sc, txq); | 1991 | ath_txq_lock(sc, txq); |
1990 | if (txq == sc->tx.txq_map[q] && | 1992 | if (txq == sc->tx.txq_map[q] && |
1991 | ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { | 1993 | ++txq->pending_frames > sc->tx.txq_max_pending[q] && |
1994 | !txq->stopped) { | ||
1992 | ieee80211_stop_queue(sc->hw, q); | 1995 | ieee80211_stop_queue(sc->hw, q); |
1993 | txq->stopped = true; | 1996 | txq->stopped = true; |
1994 | } | 1997 | } |
@@ -2047,7 +2050,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
2047 | if (WARN_ON(--txq->pending_frames < 0)) | 2050 | if (WARN_ON(--txq->pending_frames < 0)) |
2048 | txq->pending_frames = 0; | 2051 | txq->pending_frames = 0; |
2049 | 2052 | ||
2050 | if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { | 2053 | if (txq->stopped && |
2054 | txq->pending_frames < sc->tx.txq_max_pending[q]) { | ||
2051 | ieee80211_wake_queue(sc->hw, q); | 2055 | ieee80211_wake_queue(sc->hw, q); |
2052 | txq->stopped = false; | 2056 | txq->stopped = false; |
2053 | } | 2057 | } |
@@ -2191,7 +2195,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2191 | 2195 | ||
2192 | ath_txq_lock(sc, txq); | 2196 | ath_txq_lock(sc, txq); |
2193 | for (;;) { | 2197 | for (;;) { |
2194 | if (work_pending(&sc->hw_reset_work)) | 2198 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) |
2195 | break; | 2199 | break; |
2196 | 2200 | ||
2197 | if (list_empty(&txq->axq_q)) { | 2201 | if (list_empty(&txq->axq_q)) { |
@@ -2274,7 +2278,7 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2274 | int status; | 2278 | int status; |
2275 | 2279 | ||
2276 | for (;;) { | 2280 | for (;;) { |
2277 | if (work_pending(&sc->hw_reset_work)) | 2281 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) |
2278 | break; | 2282 | break; |
2279 | 2283 | ||
2280 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); | 2284 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index c06b6cb5c91e..7c899fc7ddd0 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -870,13 +870,6 @@ struct b43_wl { | |||
870 | * handler, only. This basically is just the IRQ mask register. */ | 870 | * handler, only. This basically is just the IRQ mask register. */ |
871 | spinlock_t hardirq_lock; | 871 | spinlock_t hardirq_lock; |
872 | 872 | ||
873 | /* The number of queues that were registered with the mac80211 subsystem | ||
874 | * initially. This is a backup copy of hw->queues in case hw->queues has | ||
875 | * to be dynamically lowered at runtime (Firmware does not support QoS). | ||
876 | * hw->queues has to be restored to the original value before unregistering | ||
877 | * from the mac80211 subsystem. */ | ||
878 | u16 mac80211_initially_registered_queues; | ||
879 | |||
880 | /* Set this if we call ieee80211_register_hw() and check if we call | 873 | /* Set this if we call ieee80211_register_hw() and check if we call |
881 | * ieee80211_unregister_hw(). */ | 874 | * ieee80211_unregister_hw(). */ |
882 | bool hw_registred; | 875 | bool hw_registred; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 1b988f26bdf1..b80352b308d5 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -2359,6 +2359,8 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
2359 | if (err) | 2359 | if (err) |
2360 | goto err_load; | 2360 | goto err_load; |
2361 | 2361 | ||
2362 | fw->opensource = (ctx->req_type == B43_FWTYPE_OPENSOURCE); | ||
2363 | |||
2362 | return 0; | 2364 | return 0; |
2363 | 2365 | ||
2364 | err_no_ucode: | 2366 | err_no_ucode: |
@@ -2434,6 +2436,10 @@ static void b43_request_firmware(struct work_struct *work) | |||
2434 | goto out; | 2436 | goto out; |
2435 | 2437 | ||
2436 | start_ieee80211: | 2438 | start_ieee80211: |
2439 | wl->hw->queues = B43_QOS_QUEUE_NUM; | ||
2440 | if (!modparam_qos || dev->fw.opensource) | ||
2441 | wl->hw->queues = 1; | ||
2442 | |||
2437 | err = ieee80211_register_hw(wl->hw); | 2443 | err = ieee80211_register_hw(wl->hw); |
2438 | if (err) | 2444 | if (err) |
2439 | goto err_one_core_detach; | 2445 | goto err_one_core_detach; |
@@ -2537,11 +2543,9 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2537 | dev->fw.hdr_format = B43_FW_HDR_410; | 2543 | dev->fw.hdr_format = B43_FW_HDR_410; |
2538 | else | 2544 | else |
2539 | dev->fw.hdr_format = B43_FW_HDR_351; | 2545 | dev->fw.hdr_format = B43_FW_HDR_351; |
2540 | dev->fw.opensource = (fwdate == 0xFFFF); | 2546 | WARN_ON(dev->fw.opensource != (fwdate == 0xFFFF)); |
2541 | 2547 | ||
2542 | /* Default to use-all-queues. */ | 2548 | dev->qos_enabled = dev->wl->hw->queues > 1; |
2543 | dev->wl->hw->queues = dev->wl->mac80211_initially_registered_queues; | ||
2544 | dev->qos_enabled = !!modparam_qos; | ||
2545 | /* Default to firmware/hardware crypto acceleration. */ | 2549 | /* Default to firmware/hardware crypto acceleration. */ |
2546 | dev->hwcrypto_enabled = true; | 2550 | dev->hwcrypto_enabled = true; |
2547 | 2551 | ||
@@ -2559,14 +2563,8 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
2559 | /* Disable hardware crypto and fall back to software crypto. */ | 2563 | /* Disable hardware crypto and fall back to software crypto. */ |
2560 | dev->hwcrypto_enabled = false; | 2564 | dev->hwcrypto_enabled = false; |
2561 | } | 2565 | } |
2562 | if (!(fwcapa & B43_FWCAPA_QOS)) { | 2566 | /* adding QoS support should use an offline discovery mechanism */ |
2563 | b43info(dev->wl, "QoS not supported by firmware\n"); | 2567 | WARN(fwcapa & B43_FWCAPA_QOS, "QoS in OpenFW not supported\n"); |
2564 | /* Disable QoS. Tweak hw->queues to 1. It will be restored before | ||
2565 | * ieee80211_unregister to make sure the networking core can | ||
2566 | * properly free possible resources. */ | ||
2567 | dev->wl->hw->queues = 1; | ||
2568 | dev->qos_enabled = false; | ||
2569 | } | ||
2570 | } else { | 2568 | } else { |
2571 | b43info(dev->wl, "Loading firmware version %u.%u " | 2569 | b43info(dev->wl, "Loading firmware version %u.%u " |
2572 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", | 2570 | "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", |
@@ -5298,8 +5296,6 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) | |||
5298 | 5296 | ||
5299 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; | 5297 | hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; |
5300 | 5298 | ||
5301 | hw->queues = modparam_qos ? B43_QOS_QUEUE_NUM : 1; | ||
5302 | wl->mac80211_initially_registered_queues = hw->queues; | ||
5303 | wl->hw_registred = false; | 5299 | wl->hw_registred = false; |
5304 | hw->max_rates = 2; | 5300 | hw->max_rates = 2; |
5305 | SET_IEEE80211_DEV(hw, dev->dev); | 5301 | SET_IEEE80211_DEV(hw, dev->dev); |
@@ -5374,10 +5370,6 @@ static void b43_bcma_remove(struct bcma_device *core) | |||
5374 | 5370 | ||
5375 | B43_WARN_ON(!wl); | 5371 | B43_WARN_ON(!wl); |
5376 | if (wl->current_dev == wldev && wl->hw_registred) { | 5372 | if (wl->current_dev == wldev && wl->hw_registred) { |
5377 | /* Restore the queues count before unregistering, because firmware detect | ||
5378 | * might have modified it. Restoring is important, so the networking | ||
5379 | * stack can properly free resources. */ | ||
5380 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
5381 | b43_leds_stop(wldev); | 5373 | b43_leds_stop(wldev); |
5382 | ieee80211_unregister_hw(wl->hw); | 5374 | ieee80211_unregister_hw(wl->hw); |
5383 | } | 5375 | } |
@@ -5452,10 +5444,6 @@ static void b43_ssb_remove(struct ssb_device *sdev) | |||
5452 | 5444 | ||
5453 | B43_WARN_ON(!wl); | 5445 | B43_WARN_ON(!wl); |
5454 | if (wl->current_dev == wldev && wl->hw_registred) { | 5446 | if (wl->current_dev == wldev && wl->hw_registred) { |
5455 | /* Restore the queues count before unregistering, because firmware detect | ||
5456 | * might have modified it. Restoring is important, so the networking | ||
5457 | * stack can properly free resources. */ | ||
5458 | wl->hw->queues = wl->mac80211_initially_registered_queues; | ||
5459 | b43_leds_stop(wldev); | 5447 | b43_leds_stop(wldev); |
5460 | ieee80211_unregister_hw(wl->hw); | 5448 | ieee80211_unregister_hw(wl->hw); |
5461 | } | 5449 | } |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index b31ccc02fa21..136510edf3cf 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -663,7 +663,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
663 | u32 uninitialized_var(macstat); | 663 | u32 uninitialized_var(macstat); |
664 | u16 chanid; | 664 | u16 chanid; |
665 | u16 phytype; | 665 | u16 phytype; |
666 | int padding; | 666 | int padding, rate_idx; |
667 | 667 | ||
668 | memset(&status, 0, sizeof(status)); | 668 | memset(&status, 0, sizeof(status)); |
669 | 669 | ||
@@ -766,16 +766,17 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
766 | } | 766 | } |
767 | 767 | ||
768 | if (phystat0 & B43_RX_PHYST0_OFDM) | 768 | if (phystat0 & B43_RX_PHYST0_OFDM) |
769 | status.rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, | 769 | rate_idx = b43_plcp_get_bitrate_idx_ofdm(plcp, |
770 | phytype == B43_PHYTYPE_A); | 770 | phytype == B43_PHYTYPE_A); |
771 | else | 771 | else |
772 | status.rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); | 772 | rate_idx = b43_plcp_get_bitrate_idx_cck(plcp); |
773 | if (unlikely(status.rate_idx == -1)) { | 773 | if (unlikely(rate_idx == -1)) { |
774 | /* PLCP seems to be corrupted. | 774 | /* PLCP seems to be corrupted. |
775 | * Drop the frame, if we are not interested in corrupted frames. */ | 775 | * Drop the frame, if we are not interested in corrupted frames. */ |
776 | if (!(dev->wl->filter_flags & FIF_PLCPFAIL)) | 776 | if (!(dev->wl->filter_flags & FIF_PLCPFAIL)) |
777 | goto drop; | 777 | goto drop; |
778 | } | 778 | } |
779 | status.rate_idx = rate_idx; | ||
779 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); | 780 | status.antenna = !!(phystat0 & B43_RX_PHYST0_ANT); |
780 | 781 | ||
781 | /* | 782 | /* |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index d13ae9c299f2..28c5fbb4af26 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -691,9 +691,10 @@ scan_out: | |||
691 | } | 691 | } |
692 | 692 | ||
693 | static s32 | 693 | static s32 |
694 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, | 694 | brcmf_cfg80211_scan(struct wiphy *wiphy, |
695 | struct cfg80211_scan_request *request) | 695 | struct cfg80211_scan_request *request) |
696 | { | 696 | { |
697 | struct net_device *ndev = request->wdev->netdev; | ||
697 | s32 err = 0; | 698 | s32 err = 0; |
698 | 699 | ||
699 | WL_TRACE("Enter\n"); | 700 | WL_TRACE("Enter\n"); |
@@ -919,9 +920,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
919 | set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); | 920 | set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); |
920 | 921 | ||
921 | if (params->bssid) | 922 | if (params->bssid) |
922 | WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n", | 923 | WL_CONN("BSSID: %pM\n", params->bssid); |
923 | params->bssid[0], params->bssid[1], params->bssid[2], | ||
924 | params->bssid[3], params->bssid[4], params->bssid[5]); | ||
925 | else | 924 | else |
926 | WL_CONN("No BSSID specified\n"); | 925 | WL_CONN("No BSSID specified\n"); |
927 | 926 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 01b190a25d94..be5bcfb9153b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -663,9 +663,6 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | |||
663 | /* patch the first MPDU */ | 663 | /* patch the first MPDU */ |
664 | if (count == 1) { | 664 | if (count == 1) { |
665 | u8 plcp0, plcp3, is40, sgi; | 665 | u8 plcp0, plcp3, is40, sgi; |
666 | struct ieee80211_sta *sta; | ||
667 | |||
668 | sta = tx_info->control.sta; | ||
669 | 666 | ||
670 | if (rr) { | 667 | if (rr) { |
671 | plcp0 = plcp[0]; | 668 | plcp0 = plcp[0]; |
@@ -1195,8 +1192,8 @@ static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) | |||
1195 | bool rc; | 1192 | bool rc; |
1196 | 1193 | ||
1197 | rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; | 1194 | rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; |
1198 | rc = rc && (tx_info->control.sta == NULL || ampdu_pars->sta == NULL || | 1195 | rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL || |
1199 | tx_info->control.sta == ampdu_pars->sta); | 1196 | tx_info->rate_driver_data[0] == ampdu_pars->sta); |
1200 | rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); | 1197 | rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); |
1201 | return rc; | 1198 | return rc; |
1202 | } | 1199 | } |
@@ -1210,8 +1207,8 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) | |||
1210 | struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi; | 1207 | struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi; |
1211 | 1208 | ||
1212 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | 1209 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && |
1213 | (tx_info->control.sta == sta || sta == NULL)) | 1210 | (tx_info->rate_driver_data[0] == sta || sta == NULL)) |
1214 | tx_info->control.sta = NULL; | 1211 | tx_info->rate_driver_data[0] = NULL; |
1215 | } | 1212 | } |
1216 | 1213 | ||
1217 | /* | 1214 | /* |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 2b57f57a7927..9e79d47e077f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -267,6 +267,7 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) | |||
267 | static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 267 | static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
268 | { | 268 | { |
269 | struct brcms_info *wl = hw->priv; | 269 | struct brcms_info *wl = hw->priv; |
270 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
270 | 271 | ||
271 | spin_lock_bh(&wl->lock); | 272 | spin_lock_bh(&wl->lock); |
272 | if (!wl->pub->up) { | 273 | if (!wl->pub->up) { |
@@ -275,6 +276,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
275 | goto done; | 276 | goto done; |
276 | } | 277 | } |
277 | brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); | 278 | brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); |
279 | tx_info->rate_driver_data[0] = tx_info->control.sta; | ||
278 | done: | 280 | done: |
279 | spin_unlock_bh(&wl->lock); | 281 | spin_unlock_bh(&wl->lock); |
280 | } | 282 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index cb73f2250b11..03ca65324845 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -893,7 +893,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
893 | tx_info = IEEE80211_SKB_CB(p); | 893 | tx_info = IEEE80211_SKB_CB(p); |
894 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); | 894 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); |
895 | 895 | ||
896 | if (tx_info->control.sta) | 896 | if (tx_info->rate_driver_data[0]) |
897 | scb = &wlc->pri_scb; | 897 | scb = &wlc->pri_scb; |
898 | 898 | ||
899 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 899 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index 0f8a7703eea3..0370403fd0bd 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c | |||
@@ -5359,7 +5359,7 @@ il_mac_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
5359 | if (changes & BSS_CHANGED_ASSOC) { | 5359 | if (changes & BSS_CHANGED_ASSOC) { |
5360 | D_MAC80211("ASSOC %d\n", bss_conf->assoc); | 5360 | D_MAC80211("ASSOC %d\n", bss_conf->assoc); |
5361 | if (bss_conf->assoc) { | 5361 | if (bss_conf->assoc) { |
5362 | il->timestamp = bss_conf->last_tsf; | 5362 | il->timestamp = bss_conf->sync_tsf; |
5363 | 5363 | ||
5364 | if (!il_is_rfkill(il)) | 5364 | if (!il_is_rfkill(il)) |
5365 | il->ops->post_associate(il); | 5365 | il->ops->post_associate(il); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/commands.h b/drivers/net/wireless/iwlwifi/dvm/commands.h index 97bea16f3592..4a361c55c543 100644 --- a/drivers/net/wireless/iwlwifi/dvm/commands.h +++ b/drivers/net/wireless/iwlwifi/dvm/commands.h | |||
@@ -1905,6 +1905,7 @@ struct iwl_bt_cmd { | |||
1905 | #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF | 1905 | #define IWLAGN_BT_PRIO_BOOST_MAX 0xFF |
1906 | #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 | 1906 | #define IWLAGN_BT_PRIO_BOOST_MIN 0x00 |
1907 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 | 1907 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT 0xF0 |
1908 | #define IWLAGN_BT_PRIO_BOOST_DEFAULT32 0xF0F0F0F0 | ||
1908 | 1909 | ||
1909 | #define IWLAGN_BT_MAX_KILL_DEFAULT 5 | 1910 | #define IWLAGN_BT_MAX_KILL_DEFAULT 5 |
1910 | 1911 | ||
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c index 207ae91a83aa..bef88c1a2c9b 100644 --- a/drivers/net/wireless/iwlwifi/dvm/lib.c +++ b/drivers/net/wireless/iwlwifi/dvm/lib.c | |||
@@ -265,6 +265,8 @@ void iwlagn_send_advance_bt_config(struct iwl_priv *priv) | |||
265 | bt_cmd_v2.tx_prio_boost = 0; | 265 | bt_cmd_v2.tx_prio_boost = 0; |
266 | bt_cmd_v2.rx_prio_boost = 0; | 266 | bt_cmd_v2.rx_prio_boost = 0; |
267 | } else { | 267 | } else { |
268 | /* older version only has 8 bits */ | ||
269 | WARN_ON(priv->cfg->bt_params->bt_prio_boost & ~0xFF); | ||
268 | bt_cmd_v1.prio_boost = | 270 | bt_cmd_v1.prio_boost = |
269 | priv->cfg->bt_params->bt_prio_boost; | 271 | priv->cfg->bt_params->bt_prio_boost; |
270 | bt_cmd_v1.tx_prio_boost = 0; | 272 | bt_cmd_v1.tx_prio_boost = 0; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 612f05d757db..84d3db5aa506 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c | |||
@@ -1232,7 +1232,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans, | |||
1232 | struct iwl_trans_config trans_cfg; | 1232 | struct iwl_trans_config trans_cfg; |
1233 | static const u8 no_reclaim_cmds[] = { | 1233 | static const u8 no_reclaim_cmds[] = { |
1234 | REPLY_RX_PHY_CMD, | 1234 | REPLY_RX_PHY_CMD, |
1235 | REPLY_RX, | ||
1236 | REPLY_RX_MPDU_CMD, | 1235 | REPLY_RX_MPDU_CMD, |
1237 | REPLY_COMPRESSED_BA, | 1236 | REPLY_COMPRESSED_BA, |
1238 | STATISTICS_NOTIFICATION, | 1237 | STATISTICS_NOTIFICATION, |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c index c1f7a18e08dd..fee5cffa1669 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rx.c +++ b/drivers/net/wireless/iwlwifi/dvm/rx.c | |||
@@ -88,7 +88,6 @@ const char *iwl_dvm_cmd_strings[REPLY_MAX] = { | |||
88 | IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD), | 88 | IWL_CMD_ENTRY(REPLY_PHY_CALIBRATION_CMD), |
89 | IWL_CMD_ENTRY(REPLY_RX_PHY_CMD), | 89 | IWL_CMD_ENTRY(REPLY_RX_PHY_CMD), |
90 | IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD), | 90 | IWL_CMD_ENTRY(REPLY_RX_MPDU_CMD), |
91 | IWL_CMD_ENTRY(REPLY_RX), | ||
92 | IWL_CMD_ENTRY(REPLY_COMPRESSED_BA), | 91 | IWL_CMD_ENTRY(REPLY_COMPRESSED_BA), |
93 | IWL_CMD_ENTRY(CALIBRATION_CFG_CMD), | 92 | IWL_CMD_ENTRY(CALIBRATION_CFG_CMD), |
94 | IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION), | 93 | IWL_CMD_ENTRY(CALIBRATION_RES_NOTIFICATION), |
@@ -895,8 +894,7 @@ static int iwlagn_calc_rssi(struct iwl_priv *priv, | |||
895 | return max_rssi - agc - IWLAGN_RSSI_OFFSET; | 894 | return max_rssi - agc - IWLAGN_RSSI_OFFSET; |
896 | } | 895 | } |
897 | 896 | ||
898 | /* Called for REPLY_RX (legacy ABG frames), or | 897 | /* Called for REPLY_RX_MPDU_CMD */ |
899 | * REPLY_RX_MPDU_CMD (HT high-throughput N frames). */ | ||
900 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | 898 | static int iwlagn_rx_reply_rx(struct iwl_priv *priv, |
901 | struct iwl_rx_cmd_buffer *rxb, | 899 | struct iwl_rx_cmd_buffer *rxb, |
902 | struct iwl_device_cmd *cmd) | 900 | struct iwl_device_cmd *cmd) |
@@ -911,37 +909,17 @@ static int iwlagn_rx_reply_rx(struct iwl_priv *priv, | |||
911 | u32 ampdu_status; | 909 | u32 ampdu_status; |
912 | u32 rate_n_flags; | 910 | u32 rate_n_flags; |
913 | 911 | ||
914 | /** | 912 | if (!priv->last_phy_res_valid) { |
915 | * REPLY_RX and REPLY_RX_MPDU_CMD are handled differently. | 913 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); |
916 | * REPLY_RX: physical layer info is in this buffer | 914 | return 0; |
917 | * REPLY_RX_MPDU_CMD: physical layer info was sent in separate | ||
918 | * command and cached in priv->last_phy_res | ||
919 | * | ||
920 | * Here we set up local variables depending on which command is | ||
921 | * received. | ||
922 | */ | ||
923 | if (pkt->hdr.cmd == REPLY_RX) { | ||
924 | phy_res = (struct iwl_rx_phy_res *)pkt->data; | ||
925 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*phy_res) | ||
926 | + phy_res->cfg_phy_cnt); | ||
927 | |||
928 | len = le16_to_cpu(phy_res->byte_count); | ||
929 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*phy_res) + | ||
930 | phy_res->cfg_phy_cnt + len); | ||
931 | ampdu_status = le32_to_cpu(rx_pkt_status); | ||
932 | } else { | ||
933 | if (!priv->last_phy_res_valid) { | ||
934 | IWL_ERR(priv, "MPDU frame without cached PHY data\n"); | ||
935 | return 0; | ||
936 | } | ||
937 | phy_res = &priv->last_phy_res; | ||
938 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; | ||
939 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); | ||
940 | len = le16_to_cpu(amsdu->byte_count); | ||
941 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); | ||
942 | ampdu_status = iwlagn_translate_rx_status(priv, | ||
943 | le32_to_cpu(rx_pkt_status)); | ||
944 | } | 915 | } |
916 | phy_res = &priv->last_phy_res; | ||
917 | amsdu = (struct iwl_rx_mpdu_res_start *)pkt->data; | ||
918 | header = (struct ieee80211_hdr *)(pkt->data + sizeof(*amsdu)); | ||
919 | len = le16_to_cpu(amsdu->byte_count); | ||
920 | rx_pkt_status = *(__le32 *)(pkt->data + sizeof(*amsdu) + len); | ||
921 | ampdu_status = iwlagn_translate_rx_status(priv, | ||
922 | le32_to_cpu(rx_pkt_status)); | ||
945 | 923 | ||
946 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { | 924 | if ((unlikely(phy_res->cfg_phy_cnt > 20))) { |
947 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d\n", | 925 | IWL_DEBUG_DROP(priv, "dsp size out of range [0,20]: %d\n", |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 6ee940f497f9..10896393e5a0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c | |||
@@ -1447,7 +1447,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
1447 | 1447 | ||
1448 | if (changes & BSS_CHANGED_ASSOC) { | 1448 | if (changes & BSS_CHANGED_ASSOC) { |
1449 | if (bss_conf->assoc) { | 1449 | if (bss_conf->assoc) { |
1450 | priv->timestamp = bss_conf->last_tsf; | 1450 | priv->timestamp = bss_conf->sync_tsf; |
1451 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 1451 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
1452 | } else { | 1452 | } else { |
1453 | /* | 1453 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 10e47938b635..87f465a49df1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -177,7 +177,7 @@ struct iwl_base_params { | |||
177 | struct iwl_bt_params { | 177 | struct iwl_bt_params { |
178 | bool advanced_bt_coexist; | 178 | bool advanced_bt_coexist; |
179 | u8 bt_init_traffic_load; | 179 | u8 bt_init_traffic_load; |
180 | u8 bt_prio_boost; | 180 | u32 bt_prio_boost; |
181 | u16 agg_time_limit; | 181 | u16 agg_time_limit; |
182 | bool bt_sco_disable; | 182 | bool bt_sco_disable; |
183 | bool bt_session_2; | 183 | bool bt_session_2; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 867d8e194da4..92576a3e84ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -458,6 +458,7 @@ struct iwl_trans { | |||
458 | /* The following fields are internal only */ | 458 | /* The following fields are internal only */ |
459 | struct kmem_cache *dev_cmd_pool; | 459 | struct kmem_cache *dev_cmd_pool; |
460 | size_t dev_cmd_headroom; | 460 | size_t dev_cmd_headroom; |
461 | char dev_cmd_pool_name[50]; | ||
461 | 462 | ||
462 | /* pointer to trans specific struct */ | 463 | /* pointer to trans specific struct */ |
463 | /*Ensure that this pointer will always be aligned to sizeof pointer */ | 464 | /*Ensure that this pointer will always be aligned to sizeof pointer */ |
diff --git a/drivers/net/wireless/iwlwifi/pcie/2000.c b/drivers/net/wireless/iwlwifi/pcie/2000.c index fd4e78f56fa6..9fbde32f7559 100644 --- a/drivers/net/wireless/iwlwifi/pcie/2000.c +++ b/drivers/net/wireless/iwlwifi/pcie/2000.c | |||
@@ -112,7 +112,7 @@ static const struct iwl_bt_params iwl2030_bt_params = { | |||
112 | .advanced_bt_coexist = true, | 112 | .advanced_bt_coexist = true, |
113 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, | 113 | .agg_time_limit = BT_AGG_THRESHOLD_DEF, |
114 | .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, | 114 | .bt_init_traffic_load = IWL_BT_COEX_TRAFFIC_LOAD_NONE, |
115 | .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT, | 115 | .bt_prio_boost = IWLAGN_BT_PRIO_BOOST_DEFAULT32, |
116 | .bt_sco_disable = true, | 116 | .bt_sco_disable = true, |
117 | .bt_session_2 = true, | 117 | .bt_session_2 = true, |
118 | }; | 118 | }; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 09795afccb23..939c2f78df58 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -2080,7 +2080,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2080 | { | 2080 | { |
2081 | struct iwl_trans_pcie *trans_pcie; | 2081 | struct iwl_trans_pcie *trans_pcie; |
2082 | struct iwl_trans *trans; | 2082 | struct iwl_trans *trans; |
2083 | char cmd_pool_name[100]; | ||
2084 | u16 pci_cmd; | 2083 | u16 pci_cmd; |
2085 | int err; | 2084 | int err; |
2086 | 2085 | ||
@@ -2178,12 +2177,12 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2178 | init_waitqueue_head(&trans->wait_command_queue); | 2177 | init_waitqueue_head(&trans->wait_command_queue); |
2179 | spin_lock_init(&trans->reg_lock); | 2178 | spin_lock_init(&trans->reg_lock); |
2180 | 2179 | ||
2181 | snprintf(cmd_pool_name, sizeof(cmd_pool_name), "iwl_cmd_pool:%s", | 2180 | snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name), |
2182 | dev_name(trans->dev)); | 2181 | "iwl_cmd_pool:%s", dev_name(trans->dev)); |
2183 | 2182 | ||
2184 | trans->dev_cmd_headroom = 0; | 2183 | trans->dev_cmd_headroom = 0; |
2185 | trans->dev_cmd_pool = | 2184 | trans->dev_cmd_pool = |
2186 | kmem_cache_create(cmd_pool_name, | 2185 | kmem_cache_create(trans->dev_cmd_pool_name, |
2187 | sizeof(struct iwl_device_cmd) | 2186 | sizeof(struct iwl_device_cmd) |
2188 | + trans->dev_cmd_headroom, | 2187 | + trans->dev_cmd_headroom, |
2189 | sizeof(void *), | 2188 | sizeof(void *), |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index f4a203049fb4..eb5de800ed90 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -805,7 +805,6 @@ void lbs_scan_done(struct lbs_private *priv) | |||
805 | } | 805 | } |
806 | 806 | ||
807 | static int lbs_cfg_scan(struct wiphy *wiphy, | 807 | static int lbs_cfg_scan(struct wiphy *wiphy, |
808 | struct net_device *dev, | ||
809 | struct cfg80211_scan_request *request) | 808 | struct cfg80211_scan_request *request) |
810 | { | 809 | { |
811 | struct lbs_private *priv = wiphy_priv(wiphy); | 810 | struct lbs_private *priv = wiphy_priv(wiphy); |
@@ -2181,13 +2180,15 @@ int lbs_reg_notifier(struct wiphy *wiphy, | |||
2181 | struct regulatory_request *request) | 2180 | struct regulatory_request *request) |
2182 | { | 2181 | { |
2183 | struct lbs_private *priv = wiphy_priv(wiphy); | 2182 | struct lbs_private *priv = wiphy_priv(wiphy); |
2184 | int ret; | 2183 | int ret = 0; |
2185 | 2184 | ||
2186 | lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " | 2185 | lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain " |
2187 | "callback for domain %c%c\n", request->alpha2[0], | 2186 | "callback for domain %c%c\n", request->alpha2[0], |
2188 | request->alpha2[1]); | 2187 | request->alpha2[1]); |
2189 | 2188 | ||
2190 | ret = lbs_set_11d_domain_info(priv, request, wiphy->bands); | 2189 | memcpy(priv->country_code, request->alpha2, sizeof(request->alpha2)); |
2190 | if (lbs_iface_active(priv)) | ||
2191 | ret = lbs_set_11d_domain_info(priv); | ||
2191 | 2192 | ||
2192 | lbs_deb_leave(LBS_DEB_CFG80211); | 2193 | lbs_deb_leave(LBS_DEB_CFG80211); |
2193 | return ret; | 2194 | return ret; |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index d798bcc0d83a..26e68326710b 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -733,15 +733,13 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | |||
733 | * to the firmware | 733 | * to the firmware |
734 | * | 734 | * |
735 | * @priv: pointer to &struct lbs_private | 735 | * @priv: pointer to &struct lbs_private |
736 | * @request: cfg80211 regulatory request structure | ||
737 | * @bands: the device's supported bands and channels | ||
738 | * | 736 | * |
739 | * returns: 0 on success, error code on failure | 737 | * returns: 0 on success, error code on failure |
740 | */ | 738 | */ |
741 | int lbs_set_11d_domain_info(struct lbs_private *priv, | 739 | int lbs_set_11d_domain_info(struct lbs_private *priv) |
742 | struct regulatory_request *request, | ||
743 | struct ieee80211_supported_band **bands) | ||
744 | { | 740 | { |
741 | struct wiphy *wiphy = priv->wdev->wiphy; | ||
742 | struct ieee80211_supported_band **bands = wiphy->bands; | ||
745 | struct cmd_ds_802_11d_domain_info cmd; | 743 | struct cmd_ds_802_11d_domain_info cmd; |
746 | struct mrvl_ie_domain_param_set *domain = &cmd.domain; | 744 | struct mrvl_ie_domain_param_set *domain = &cmd.domain; |
747 | struct ieee80211_country_ie_triplet *t; | 745 | struct ieee80211_country_ie_triplet *t; |
@@ -752,21 +750,23 @@ int lbs_set_11d_domain_info(struct lbs_private *priv, | |||
752 | u8 first_channel = 0, next_chan = 0, max_pwr = 0; | 750 | u8 first_channel = 0, next_chan = 0, max_pwr = 0; |
753 | u8 i, flag = 0; | 751 | u8 i, flag = 0; |
754 | size_t triplet_size; | 752 | size_t triplet_size; |
755 | int ret; | 753 | int ret = 0; |
756 | 754 | ||
757 | lbs_deb_enter(LBS_DEB_11D); | 755 | lbs_deb_enter(LBS_DEB_11D); |
756 | if (!priv->country_code[0]) | ||
757 | goto out; | ||
758 | 758 | ||
759 | memset(&cmd, 0, sizeof(cmd)); | 759 | memset(&cmd, 0, sizeof(cmd)); |
760 | cmd.action = cpu_to_le16(CMD_ACT_SET); | 760 | cmd.action = cpu_to_le16(CMD_ACT_SET); |
761 | 761 | ||
762 | lbs_deb_11d("Setting country code '%c%c'\n", | 762 | lbs_deb_11d("Setting country code '%c%c'\n", |
763 | request->alpha2[0], request->alpha2[1]); | 763 | priv->country_code[0], priv->country_code[1]); |
764 | 764 | ||
765 | domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); | 765 | domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN); |
766 | 766 | ||
767 | /* Set country code */ | 767 | /* Set country code */ |
768 | domain->country_code[0] = request->alpha2[0]; | 768 | domain->country_code[0] = priv->country_code[0]; |
769 | domain->country_code[1] = request->alpha2[1]; | 769 | domain->country_code[1] = priv->country_code[1]; |
770 | domain->country_code[2] = ' '; | 770 | domain->country_code[2] = ' '; |
771 | 771 | ||
772 | /* Now set up the channel triplets; firmware is somewhat picky here | 772 | /* Now set up the channel triplets; firmware is somewhat picky here |
@@ -848,6 +848,7 @@ int lbs_set_11d_domain_info(struct lbs_private *priv, | |||
848 | 848 | ||
849 | ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); | 849 | ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd); |
850 | 850 | ||
851 | out: | ||
851 | lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); | 852 | lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret); |
852 | return ret; | 853 | return ret; |
853 | } | 854 | } |
@@ -1019,9 +1020,9 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
1019 | if (ret) { | 1020 | if (ret) { |
1020 | netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n", | 1021 | netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n", |
1021 | ret); | 1022 | ret); |
1022 | /* Let the timer kick in and retry, and potentially reset | 1023 | /* Reset dnld state machine, report failure */ |
1023 | the whole thing if the condition persists */ | 1024 | priv->dnld_sent = DNLD_RES_RECEIVED; |
1024 | timeo = HZ/4; | 1025 | lbs_complete_command(priv, cmdnode, ret); |
1025 | } | 1026 | } |
1026 | 1027 | ||
1027 | if (command == CMD_802_11_DEEP_SLEEP) { | 1028 | if (command == CMD_802_11_DEEP_SLEEP) { |
diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index b280ef7a0aea..ab07608e13d0 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h | |||
@@ -128,9 +128,7 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable); | |||
128 | 128 | ||
129 | int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf); | 129 | int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf); |
130 | 130 | ||
131 | int lbs_set_11d_domain_info(struct lbs_private *priv, | 131 | int lbs_set_11d_domain_info(struct lbs_private *priv); |
132 | struct regulatory_request *request, | ||
133 | struct ieee80211_supported_band **bands); | ||
134 | 132 | ||
135 | int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value); | 133 | int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value); |
136 | 134 | ||
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index 60996ce89f77..6bd1608992b0 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h | |||
@@ -49,6 +49,7 @@ struct lbs_private { | |||
49 | bool wiphy_registered; | 49 | bool wiphy_registered; |
50 | struct cfg80211_scan_request *scan_req; | 50 | struct cfg80211_scan_request *scan_req; |
51 | u8 assoc_bss[ETH_ALEN]; | 51 | u8 assoc_bss[ETH_ALEN]; |
52 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; | ||
52 | u8 disassoc_reason; | 53 | u8 disassoc_reason; |
53 | 54 | ||
54 | /* Mesh */ | 55 | /* Mesh */ |
diff --git a/drivers/net/wireless/libertas/firmware.c b/drivers/net/wireless/libertas/firmware.c index 601f2075355e..c0f9e7e862f6 100644 --- a/drivers/net/wireless/libertas/firmware.c +++ b/drivers/net/wireless/libertas/firmware.c | |||
@@ -4,9 +4,7 @@ | |||
4 | 4 | ||
5 | #include <linux/sched.h> | 5 | #include <linux/sched.h> |
6 | #include <linux/firmware.h> | 6 | #include <linux/firmware.h> |
7 | #include <linux/firmware.h> | ||
8 | #include <linux/module.h> | 7 | #include <linux/module.h> |
9 | #include <linux/sched.h> | ||
10 | 8 | ||
11 | #include "dev.h" | 9 | #include "dev.h" |
12 | #include "decl.h" | 10 | #include "decl.h" |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 64b7dc5de126..55a77e41170a 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -309,7 +309,6 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
309 | cardp->surprise_removed = 1; | 309 | cardp->surprise_removed = 1; |
310 | 310 | ||
311 | if (priv) { | 311 | if (priv) { |
312 | priv->surpriseremoved = 1; | ||
313 | lbs_stop_card(priv); | 312 | lbs_stop_card(priv); |
314 | lbs_remove_card(priv); | 313 | lbs_remove_card(priv); |
315 | } | 314 | } |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index e96ee0aa8439..58048189bd24 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -152,6 +152,12 @@ int lbs_start_iface(struct lbs_private *priv) | |||
152 | goto err; | 152 | goto err; |
153 | } | 153 | } |
154 | 154 | ||
155 | ret = lbs_set_11d_domain_info(priv); | ||
156 | if (ret) { | ||
157 | lbs_deb_net("set 11d domain info failed\n"); | ||
158 | goto err; | ||
159 | } | ||
160 | |||
155 | lbs_update_channel(priv); | 161 | lbs_update_channel(priv); |
156 | 162 | ||
157 | priv->iface_running = true; | 163 | priv->iface_running = true; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 200bcc0ead98..643f968b05ee 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -1540,11 +1540,6 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, | |||
1540 | /* now send back TX status */ | 1540 | /* now send back TX status */ |
1541 | txi = IEEE80211_SKB_CB(skb); | 1541 | txi = IEEE80211_SKB_CB(skb); |
1542 | 1542 | ||
1543 | if (txi->control.vif) | ||
1544 | hwsim_check_magic(txi->control.vif); | ||
1545 | if (txi->control.sta) | ||
1546 | hwsim_check_sta_magic(txi->control.sta); | ||
1547 | |||
1548 | ieee80211_tx_info_clear_status(txi); | 1543 | ieee80211_tx_info_clear_status(txi); |
1549 | 1544 | ||
1550 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | 1545 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c7a177c62625..fe42137384da 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -48,10 +48,9 @@ static const struct ieee80211_iface_combination mwifiex_iface_comb_ap_sta = { | |||
48 | * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE | 48 | * Others -> IEEE80211_HT_PARAM_CHA_SEC_NONE |
49 | */ | 49 | */ |
50 | static u8 | 50 | static u8 |
51 | mwifiex_cfg80211_channel_type_to_sec_chan_offset(enum nl80211_channel_type | 51 | mwifiex_chan_type_to_sec_chan_offset(enum nl80211_channel_type chan_type) |
52 | channel_type) | ||
53 | { | 52 | { |
54 | switch (channel_type) { | 53 | switch (chan_type) { |
55 | case NL80211_CHAN_NO_HT: | 54 | case NL80211_CHAN_NO_HT: |
56 | case NL80211_CHAN_HT20: | 55 | case NL80211_CHAN_HT20: |
57 | return IEEE80211_HT_PARAM_CHA_SEC_NONE; | 56 | return IEEE80211_HT_PARAM_CHA_SEC_NONE; |
@@ -339,79 +338,6 @@ static int mwifiex_reg_notifier(struct wiphy *wiphy, | |||
339 | } | 338 | } |
340 | 339 | ||
341 | /* | 340 | /* |
342 | * This function sets the RF channel. | ||
343 | * | ||
344 | * This function creates multiple IOCTL requests, populates them accordingly | ||
345 | * and issues them to set the band/channel and frequency. | ||
346 | */ | ||
347 | static int | ||
348 | mwifiex_set_rf_channel(struct mwifiex_private *priv, | ||
349 | struct ieee80211_channel *chan, | ||
350 | enum nl80211_channel_type channel_type) | ||
351 | { | ||
352 | struct mwifiex_chan_freq_power cfp; | ||
353 | u32 config_bands = 0; | ||
354 | struct wiphy *wiphy = priv->wdev->wiphy; | ||
355 | struct mwifiex_adapter *adapter = priv->adapter; | ||
356 | |||
357 | if (chan) { | ||
358 | /* Set appropriate bands */ | ||
359 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
360 | if (channel_type == NL80211_CHAN_NO_HT) | ||
361 | if (priv->adapter->config_bands == BAND_B || | ||
362 | priv->adapter->config_bands == BAND_G) | ||
363 | config_bands = | ||
364 | priv->adapter->config_bands; | ||
365 | else | ||
366 | config_bands = BAND_B | BAND_G; | ||
367 | else | ||
368 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
369 | } else { | ||
370 | if (channel_type == NL80211_CHAN_NO_HT) | ||
371 | config_bands = BAND_A; | ||
372 | else | ||
373 | config_bands = BAND_AN | BAND_A; | ||
374 | } | ||
375 | |||
376 | if (!((config_bands | adapter->fw_bands) & | ||
377 | ~adapter->fw_bands)) { | ||
378 | adapter->config_bands = config_bands; | ||
379 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | ||
380 | adapter->adhoc_start_band = config_bands; | ||
381 | if ((config_bands & BAND_GN) || | ||
382 | (config_bands & BAND_AN)) | ||
383 | adapter->adhoc_11n_enabled = true; | ||
384 | else | ||
385 | adapter->adhoc_11n_enabled = false; | ||
386 | } | ||
387 | } | ||
388 | adapter->sec_chan_offset = | ||
389 | mwifiex_cfg80211_channel_type_to_sec_chan_offset | ||
390 | (channel_type); | ||
391 | adapter->channel_type = channel_type; | ||
392 | |||
393 | mwifiex_send_domain_info_cmd_fw(wiphy); | ||
394 | } | ||
395 | |||
396 | wiphy_dbg(wiphy, "info: setting band %d, chan offset %d, mode %d\n", | ||
397 | config_bands, adapter->sec_chan_offset, priv->bss_mode); | ||
398 | if (!chan) | ||
399 | return 0; | ||
400 | |||
401 | memset(&cfp, 0, sizeof(cfp)); | ||
402 | cfp.freq = chan->center_freq; | ||
403 | cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); | ||
404 | |||
405 | if (priv->bss_type == MWIFIEX_BSS_TYPE_STA) { | ||
406 | if (mwifiex_bss_set_channel(priv, &cfp)) | ||
407 | return -EFAULT; | ||
408 | return mwifiex_drv_change_adhoc_chan(priv, cfp.channel); | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * This function sets the fragmentation threshold. | 341 | * This function sets the fragmentation threshold. |
416 | * | 342 | * |
417 | * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE | 343 | * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE |
@@ -626,7 +552,7 @@ static int | |||
626 | mwifiex_dump_station_info(struct mwifiex_private *priv, | 552 | mwifiex_dump_station_info(struct mwifiex_private *priv, |
627 | struct station_info *sinfo) | 553 | struct station_info *sinfo) |
628 | { | 554 | { |
629 | struct mwifiex_rate_cfg rate; | 555 | u32 rate; |
630 | 556 | ||
631 | sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | | 557 | sinfo->filled = STATION_INFO_RX_BYTES | STATION_INFO_TX_BYTES | |
632 | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | | 558 | STATION_INFO_RX_PACKETS | STATION_INFO_TX_PACKETS | |
@@ -652,9 +578,9 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
652 | 578 | ||
653 | /* | 579 | /* |
654 | * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid | 580 | * Bit 0 in tx_htinfo indicates that current Tx rate is 11n rate. Valid |
655 | * MCS index values for us are 0 to 7. | 581 | * MCS index values for us are 0 to 15. |
656 | */ | 582 | */ |
657 | if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 8)) { | 583 | if ((priv->tx_htinfo & BIT(0)) && (priv->tx_rate < 16)) { |
658 | sinfo->txrate.mcs = priv->tx_rate; | 584 | sinfo->txrate.mcs = priv->tx_rate; |
659 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; | 585 | sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; |
660 | /* 40MHz rate */ | 586 | /* 40MHz rate */ |
@@ -672,7 +598,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, | |||
672 | sinfo->tx_packets = priv->stats.tx_packets; | 598 | sinfo->tx_packets = priv->stats.tx_packets; |
673 | sinfo->signal = priv->bcn_rssi_avg; | 599 | sinfo->signal = priv->bcn_rssi_avg; |
674 | /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ | 600 | /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ |
675 | sinfo->txrate.legacy = rate.rate * 5; | 601 | sinfo->txrate.legacy = rate * 5; |
676 | 602 | ||
677 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { | 603 | if (priv->bss_mode == NL80211_IFTYPE_STATION) { |
678 | sinfo->filled |= STATION_INFO_BSS_PARAM; | 604 | sinfo->filled |= STATION_INFO_BSS_PARAM; |
@@ -827,8 +753,8 @@ static const u32 mwifiex_cipher_suites[] = { | |||
827 | /* | 753 | /* |
828 | * CFG802.11 operation handler for setting bit rates. | 754 | * CFG802.11 operation handler for setting bit rates. |
829 | * | 755 | * |
830 | * Function selects legacy bang B/G/BG from corresponding bitrates selection. | 756 | * Function configures data rates to firmware using bitrate mask |
831 | * Currently only 2.4GHz band is supported. | 757 | * provided by cfg80211. |
832 | */ | 758 | */ |
833 | static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | 759 | static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, |
834 | struct net_device *dev, | 760 | struct net_device *dev, |
@@ -836,43 +762,36 @@ static int mwifiex_cfg80211_set_bitrate_mask(struct wiphy *wiphy, | |||
836 | const struct cfg80211_bitrate_mask *mask) | 762 | const struct cfg80211_bitrate_mask *mask) |
837 | { | 763 | { |
838 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 764 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
839 | int index = 0, mode = 0, i; | 765 | u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; |
840 | struct mwifiex_adapter *adapter = priv->adapter; | 766 | enum ieee80211_band band; |
841 | 767 | ||
842 | /* Currently only 2.4GHz is supported */ | 768 | if (!priv->media_connected) { |
843 | for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { | 769 | dev_err(priv->adapter->dev, |
844 | /* | 770 | "Can not set Tx data rate in disconnected state\n"); |
845 | * Rates below 6 Mbps in the table are CCK rates; 802.11b | 771 | return -EINVAL; |
846 | * and from 6 they are OFDM; 802.11G | ||
847 | */ | ||
848 | if (mwifiex_rates[i].bitrate == 60) { | ||
849 | index = 1 << i; | ||
850 | break; | ||
851 | } | ||
852 | } | 772 | } |
853 | 773 | ||
854 | if (mask->control[IEEE80211_BAND_2GHZ].legacy < index) { | 774 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); |
855 | mode = BAND_B; | ||
856 | } else { | ||
857 | mode = BAND_G; | ||
858 | if (mask->control[IEEE80211_BAND_2GHZ].legacy % index) | ||
859 | mode |= BAND_B; | ||
860 | } | ||
861 | 775 | ||
862 | if (!((mode | adapter->fw_bands) & ~adapter->fw_bands)) { | 776 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); |
863 | adapter->config_bands = mode; | ||
864 | if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { | ||
865 | adapter->adhoc_start_band = mode; | ||
866 | adapter->adhoc_11n_enabled = false; | ||
867 | } | ||
868 | } | ||
869 | adapter->sec_chan_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
870 | adapter->channel_type = NL80211_CHAN_NO_HT; | ||
871 | 777 | ||
872 | wiphy_debug(wiphy, "info: device configured in 802.11%s%s mode\n", | 778 | /* Fill HR/DSSS rates. */ |
873 | (mode & BAND_B) ? "b" : "", (mode & BAND_G) ? "g" : ""); | 779 | if (band == IEEE80211_BAND_2GHZ) |
780 | bitmap_rates[0] = mask->control[band].legacy & 0x000f; | ||
874 | 781 | ||
875 | return 0; | 782 | /* Fill OFDM rates */ |
783 | if (band == IEEE80211_BAND_2GHZ) | ||
784 | bitmap_rates[1] = (mask->control[band].legacy & 0x0ff0) >> 4; | ||
785 | else | ||
786 | bitmap_rates[1] = mask->control[band].legacy; | ||
787 | |||
788 | /* Fill MCS rates */ | ||
789 | bitmap_rates[2] = mask->control[band].mcs[0]; | ||
790 | if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) | ||
791 | bitmap_rates[2] |= mask->control[band].mcs[1] << 8; | ||
792 | |||
793 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, | ||
794 | HostCmd_ACT_GEN_SET, 0, bitmap_rates); | ||
876 | } | 795 | } |
877 | 796 | ||
878 | /* | 797 | /* |
@@ -1007,6 +926,7 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1007 | { | 926 | { |
1008 | struct mwifiex_uap_bss_param *bss_cfg; | 927 | struct mwifiex_uap_bss_param *bss_cfg; |
1009 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 928 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
929 | u8 config_bands = 0; | ||
1010 | 930 | ||
1011 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) | 931 | if (priv->bss_type != MWIFIEX_BSS_TYPE_UAP) |
1012 | return -1; | 932 | return -1; |
@@ -1047,13 +967,25 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy, | |||
1047 | (u8)ieee80211_frequency_to_channel(params->channel->center_freq); | 967 | (u8)ieee80211_frequency_to_channel(params->channel->center_freq); |
1048 | bss_cfg->band_cfg = BAND_CONFIG_MANUAL; | 968 | bss_cfg->band_cfg = BAND_CONFIG_MANUAL; |
1049 | 969 | ||
1050 | if (mwifiex_set_rf_channel(priv, params->channel, | 970 | /* Set appropriate bands */ |
1051 | params->channel_type)) { | 971 | if (params->channel->band == IEEE80211_BAND_2GHZ) { |
1052 | kfree(bss_cfg); | 972 | if (params->channel_type == NL80211_CHAN_NO_HT) |
1053 | wiphy_err(wiphy, "Failed to set band config information!\n"); | 973 | config_bands = BAND_B | BAND_G; |
1054 | return -1; | 974 | else |
975 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
976 | } else { | ||
977 | if (params->channel_type == NL80211_CHAN_NO_HT) | ||
978 | config_bands = BAND_A; | ||
979 | else | ||
980 | config_bands = BAND_AN | BAND_A; | ||
1055 | } | 981 | } |
1056 | 982 | ||
983 | if (!((config_bands | priv->adapter->fw_bands) & | ||
984 | ~priv->adapter->fw_bands)) | ||
985 | priv->adapter->config_bands = config_bands; | ||
986 | |||
987 | mwifiex_send_domain_info_cmd_fw(wiphy); | ||
988 | |||
1057 | if (mwifiex_set_secure_params(priv, bss_cfg, params)) { | 989 | if (mwifiex_set_secure_params(priv, bss_cfg, params)) { |
1058 | kfree(bss_cfg); | 990 | kfree(bss_cfg); |
1059 | wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); | 991 | wiphy_err(wiphy, "Failed to parse secuirty parameters!\n"); |
@@ -1187,7 +1119,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1187 | struct cfg80211_ssid req_ssid; | 1119 | struct cfg80211_ssid req_ssid; |
1188 | int ret, auth_type = 0; | 1120 | int ret, auth_type = 0; |
1189 | struct cfg80211_bss *bss = NULL; | 1121 | struct cfg80211_bss *bss = NULL; |
1190 | u8 is_scanning_required = 0; | 1122 | u8 is_scanning_required = 0, config_bands = 0; |
1191 | 1123 | ||
1192 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); | 1124 | memset(&req_ssid, 0, sizeof(struct cfg80211_ssid)); |
1193 | 1125 | ||
@@ -1206,9 +1138,19 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, | |||
1206 | /* disconnect before try to associate */ | 1138 | /* disconnect before try to associate */ |
1207 | mwifiex_deauthenticate(priv, NULL); | 1139 | mwifiex_deauthenticate(priv, NULL); |
1208 | 1140 | ||
1209 | if (channel) | 1141 | if (channel) { |
1210 | ret = mwifiex_set_rf_channel(priv, channel, | 1142 | if (mode == NL80211_IFTYPE_STATION) { |
1211 | priv->adapter->channel_type); | 1143 | if (channel->band == IEEE80211_BAND_2GHZ) |
1144 | config_bands = BAND_B | BAND_G | BAND_GN; | ||
1145 | else | ||
1146 | config_bands = BAND_A | BAND_AN; | ||
1147 | |||
1148 | if (!((config_bands | priv->adapter->fw_bands) & | ||
1149 | ~priv->adapter->fw_bands)) | ||
1150 | priv->adapter->config_bands = config_bands; | ||
1151 | } | ||
1152 | mwifiex_send_domain_info_cmd_fw(priv->wdev->wiphy); | ||
1153 | } | ||
1212 | 1154 | ||
1213 | /* As this is new association, clear locally stored | 1155 | /* As this is new association, clear locally stored |
1214 | * keys and security related flags */ | 1156 | * keys and security related flags */ |
@@ -1373,6 +1315,76 @@ done: | |||
1373 | } | 1315 | } |
1374 | 1316 | ||
1375 | /* | 1317 | /* |
1318 | * This function sets following parameters for ibss network. | ||
1319 | * - channel | ||
1320 | * - start band | ||
1321 | * - 11n flag | ||
1322 | * - secondary channel offset | ||
1323 | */ | ||
1324 | static int mwifiex_set_ibss_params(struct mwifiex_private *priv, | ||
1325 | struct cfg80211_ibss_params *params) | ||
1326 | { | ||
1327 | struct wiphy *wiphy = priv->wdev->wiphy; | ||
1328 | struct mwifiex_adapter *adapter = priv->adapter; | ||
1329 | int index = 0, i; | ||
1330 | u8 config_bands = 0; | ||
1331 | |||
1332 | if (params->channel->band == IEEE80211_BAND_2GHZ) { | ||
1333 | if (!params->basic_rates) { | ||
1334 | config_bands = BAND_B | BAND_G; | ||
1335 | } else { | ||
1336 | for (i = 0; i < mwifiex_band_2ghz.n_bitrates; i++) { | ||
1337 | /* | ||
1338 | * Rates below 6 Mbps in the table are CCK | ||
1339 | * rates; 802.11b and from 6 they are OFDM; | ||
1340 | * 802.11G | ||
1341 | */ | ||
1342 | if (mwifiex_rates[i].bitrate == 60) { | ||
1343 | index = 1 << i; | ||
1344 | break; | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | if (params->basic_rates < index) { | ||
1349 | config_bands = BAND_B; | ||
1350 | } else { | ||
1351 | config_bands = BAND_G; | ||
1352 | if (params->basic_rates % index) | ||
1353 | config_bands |= BAND_B; | ||
1354 | } | ||
1355 | } | ||
1356 | |||
1357 | if (params->channel_type != NL80211_CHAN_NO_HT) | ||
1358 | config_bands |= BAND_GN; | ||
1359 | } else { | ||
1360 | if (params->channel_type == NL80211_CHAN_NO_HT) | ||
1361 | config_bands = BAND_A; | ||
1362 | else | ||
1363 | config_bands = BAND_AN | BAND_A; | ||
1364 | } | ||
1365 | |||
1366 | if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) { | ||
1367 | adapter->config_bands = config_bands; | ||
1368 | adapter->adhoc_start_band = config_bands; | ||
1369 | |||
1370 | if ((config_bands & BAND_GN) || (config_bands & BAND_AN)) | ||
1371 | adapter->adhoc_11n_enabled = true; | ||
1372 | else | ||
1373 | adapter->adhoc_11n_enabled = false; | ||
1374 | } | ||
1375 | |||
1376 | adapter->sec_chan_offset = | ||
1377 | mwifiex_chan_type_to_sec_chan_offset(params->channel_type); | ||
1378 | priv->adhoc_channel = | ||
1379 | ieee80211_frequency_to_channel(params->channel->center_freq); | ||
1380 | |||
1381 | wiphy_dbg(wiphy, "info: set ibss band %d, chan %d, chan offset %d\n", | ||
1382 | config_bands, priv->adhoc_channel, adapter->sec_chan_offset); | ||
1383 | |||
1384 | return 0; | ||
1385 | } | ||
1386 | |||
1387 | /* | ||
1376 | * CFG802.11 operation handler to join an IBSS. | 1388 | * CFG802.11 operation handler to join an IBSS. |
1377 | * | 1389 | * |
1378 | * This function does not work in any mode other than Ad-Hoc, or if | 1390 | * This function does not work in any mode other than Ad-Hoc, or if |
@@ -1394,6 +1406,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, | |||
1394 | wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", | 1406 | wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", |
1395 | (char *) params->ssid, params->bssid); | 1407 | (char *) params->ssid, params->bssid); |
1396 | 1408 | ||
1409 | mwifiex_set_ibss_params(priv, params); | ||
1410 | |||
1397 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, | 1411 | ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, |
1398 | params->bssid, priv->bss_mode, | 1412 | params->bssid, priv->bss_mode, |
1399 | params->channel, NULL, params->privacy); | 1413 | params->channel, NULL, params->privacy); |
@@ -1440,9 +1454,10 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
1440 | * it also informs the results. | 1454 | * it also informs the results. |
1441 | */ | 1455 | */ |
1442 | static int | 1456 | static int |
1443 | mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, | 1457 | mwifiex_cfg80211_scan(struct wiphy *wiphy, |
1444 | struct cfg80211_scan_request *request) | 1458 | struct cfg80211_scan_request *request) |
1445 | { | 1459 | { |
1460 | struct net_device *dev = request->wdev->netdev; | ||
1446 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1461 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); |
1447 | int i; | 1462 | int i; |
1448 | struct ieee80211_channel *chan; | 1463 | struct ieee80211_channel *chan; |
@@ -1576,11 +1591,11 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info, | |||
1576 | /* | 1591 | /* |
1577 | * create a new virtual interface with the given name | 1592 | * create a new virtual interface with the given name |
1578 | */ | 1593 | */ |
1579 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1594 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1580 | char *name, | 1595 | char *name, |
1581 | enum nl80211_iftype type, | 1596 | enum nl80211_iftype type, |
1582 | u32 *flags, | 1597 | u32 *flags, |
1583 | struct vif_params *params) | 1598 | struct vif_params *params) |
1584 | { | 1599 | { |
1585 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); | 1600 | struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); |
1586 | struct mwifiex_private *priv; | 1601 | struct mwifiex_private *priv; |
@@ -1701,16 +1716,16 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | |||
1701 | #ifdef CONFIG_DEBUG_FS | 1716 | #ifdef CONFIG_DEBUG_FS |
1702 | mwifiex_dev_debugfs_init(priv); | 1717 | mwifiex_dev_debugfs_init(priv); |
1703 | #endif | 1718 | #endif |
1704 | return dev; | 1719 | return wdev; |
1705 | } | 1720 | } |
1706 | EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); | 1721 | EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); |
1707 | 1722 | ||
1708 | /* | 1723 | /* |
1709 | * del_virtual_intf: remove the virtual interface determined by dev | 1724 | * del_virtual_intf: remove the virtual interface determined by dev |
1710 | */ | 1725 | */ |
1711 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) | 1726 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) |
1712 | { | 1727 | { |
1713 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); | 1728 | struct mwifiex_private *priv = mwifiex_netdev_get_priv(wdev->netdev); |
1714 | 1729 | ||
1715 | #ifdef CONFIG_DEBUG_FS | 1730 | #ifdef CONFIG_DEBUG_FS |
1716 | mwifiex_dev_debugfs_remove(priv); | 1731 | mwifiex_dev_debugfs_remove(priv); |
@@ -1722,11 +1737,11 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) | |||
1722 | if (netif_carrier_ok(priv->netdev)) | 1737 | if (netif_carrier_ok(priv->netdev)) |
1723 | netif_carrier_off(priv->netdev); | 1738 | netif_carrier_off(priv->netdev); |
1724 | 1739 | ||
1725 | if (dev->reg_state == NETREG_REGISTERED) | 1740 | if (wdev->netdev->reg_state == NETREG_REGISTERED) |
1726 | unregister_netdevice(dev); | 1741 | unregister_netdevice(wdev->netdev); |
1727 | 1742 | ||
1728 | if (dev->reg_state == NETREG_UNREGISTERED) | 1743 | if (wdev->netdev->reg_state == NETREG_UNREGISTERED) |
1729 | free_netdev(dev); | 1744 | free_netdev(wdev->netdev); |
1730 | 1745 | ||
1731 | /* Clear the priv in adapter */ | 1746 | /* Clear the priv in adapter */ |
1732 | priv->netdev = NULL; | 1747 | priv->netdev = NULL; |
@@ -1818,6 +1833,8 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) | |||
1818 | wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; | 1833 | wiphy->available_antennas_tx = BIT(adapter->number_of_antenna) - 1; |
1819 | wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; | 1834 | wiphy->available_antennas_rx = BIT(adapter->number_of_antenna) - 1; |
1820 | 1835 | ||
1836 | wiphy->features = NL80211_FEATURE_HT_IBSS; | ||
1837 | |||
1821 | /* Reserve space for mwifiex specific private data for BSS */ | 1838 | /* Reserve space for mwifiex specific private data for BSS */ |
1822 | wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); | 1839 | wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); |
1823 | 1840 | ||
diff --git a/drivers/net/wireless/mwifiex/cfp.c b/drivers/net/wireless/mwifiex/cfp.c index 560871b0e236..f69300f93f42 100644 --- a/drivers/net/wireless/mwifiex/cfp.c +++ b/drivers/net/wireless/mwifiex/cfp.c | |||
@@ -167,23 +167,6 @@ u32 mwifiex_index_to_data_rate(struct mwifiex_private *priv, u8 index, | |||
167 | } | 167 | } |
168 | 168 | ||
169 | /* | 169 | /* |
170 | * This function maps a data rate value into corresponding index in supported | ||
171 | * rates table. | ||
172 | */ | ||
173 | u8 mwifiex_data_rate_to_index(u32 rate) | ||
174 | { | ||
175 | u16 *ptr; | ||
176 | |||
177 | if (rate) { | ||
178 | ptr = memchr(mwifiex_data_rates, rate, | ||
179 | sizeof(mwifiex_data_rates)); | ||
180 | if (ptr) | ||
181 | return (u8) (ptr - mwifiex_data_rates); | ||
182 | } | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * This function returns the current active data rates. | 170 | * This function returns the current active data rates. |
188 | * | 171 | * |
189 | * The result may vary depending upon connection status. | 172 | * The result may vary depending upon connection status. |
@@ -277,20 +260,6 @@ mwifiex_is_rate_auto(struct mwifiex_private *priv) | |||
277 | } | 260 | } |
278 | 261 | ||
279 | /* | 262 | /* |
280 | * This function converts rate bitmap into rate index. | ||
281 | */ | ||
282 | int mwifiex_get_rate_index(u16 *rate_bitmap, int size) | ||
283 | { | ||
284 | int i; | ||
285 | |||
286 | for (i = 0; i < size * 8; i++) | ||
287 | if (rate_bitmap[i / 16] & (1 << (i % 16))) | ||
288 | return i; | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * This function gets the supported data rates. | 263 | * This function gets the supported data rates. |
295 | * | 264 | * |
296 | * The function works in both Ad-Hoc and infra mode by printing the | 265 | * The function works in both Ad-Hoc and infra mode by printing the |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index f918f66e5e27..070ef25f5186 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -41,16 +41,7 @@ | |||
41 | #define MWIFIEX_AMPDU_DEF_RXWINSIZE 16 | 41 | #define MWIFIEX_AMPDU_DEF_RXWINSIZE 16 |
42 | #define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff | 42 | #define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff |
43 | 43 | ||
44 | #define MWIFIEX_RATE_INDEX_HRDSSS0 0 | ||
45 | #define MWIFIEX_RATE_INDEX_HRDSSS3 3 | ||
46 | #define MWIFIEX_RATE_INDEX_OFDM0 4 | ||
47 | #define MWIFIEX_RATE_INDEX_OFDM7 11 | ||
48 | #define MWIFIEX_RATE_INDEX_MCS0 12 | ||
49 | |||
50 | #define MWIFIEX_RATE_BITMAP_OFDM0 16 | ||
51 | #define MWIFIEX_RATE_BITMAP_OFDM7 23 | ||
52 | #define MWIFIEX_RATE_BITMAP_MCS0 32 | 44 | #define MWIFIEX_RATE_BITMAP_MCS0 32 |
53 | #define MWIFIEX_RATE_BITMAP_MCS127 159 | ||
54 | 45 | ||
55 | #define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) | 46 | #define MWIFIEX_RX_DATA_BUF_SIZE (4 * 1024) |
56 | #define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) | 47 | #define MWIFIEX_RX_CMD_BUF_SIZE (2 * 1024) |
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 14e985d01dee..e831b440a24a 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -225,7 +225,6 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { | |||
225 | #define HostCmd_CMD_BBP_REG_ACCESS 0x001a | 225 | #define HostCmd_CMD_BBP_REG_ACCESS 0x001a |
226 | #define HostCmd_CMD_RF_REG_ACCESS 0x001b | 226 | #define HostCmd_CMD_RF_REG_ACCESS 0x001b |
227 | #define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad | 227 | #define HostCmd_CMD_PMIC_REG_ACCESS 0x00ad |
228 | #define HostCmd_CMD_802_11_RF_CHANNEL 0x001d | ||
229 | #define HostCmd_CMD_RF_TX_PWR 0x001e | 228 | #define HostCmd_CMD_RF_TX_PWR 0x001e |
230 | #define HostCmd_CMD_RF_ANTENNA 0x0020 | 229 | #define HostCmd_CMD_RF_ANTENNA 0x0020 |
231 | #define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024 | 230 | #define HostCmd_CMD_802_11_DEAUTHENTICATE 0x0024 |
@@ -1292,14 +1291,6 @@ struct host_cmd_tlv_channel_band { | |||
1292 | u8 channel; | 1291 | u8 channel; |
1293 | } __packed; | 1292 | } __packed; |
1294 | 1293 | ||
1295 | struct host_cmd_ds_802_11_rf_channel { | ||
1296 | __le16 action; | ||
1297 | __le16 current_channel; | ||
1298 | __le16 rf_type; | ||
1299 | __le16 reserved; | ||
1300 | u8 reserved_1[32]; | ||
1301 | } __packed; | ||
1302 | |||
1303 | struct host_cmd_ds_version_ext { | 1294 | struct host_cmd_ds_version_ext { |
1304 | u8 version_str_sel; | 1295 | u8 version_str_sel; |
1305 | char version_str[128]; | 1296 | char version_str[128]; |
@@ -1384,7 +1375,6 @@ struct host_cmd_ds_command { | |||
1384 | struct host_cmd_ds_802_11_rssi_info rssi_info; | 1375 | struct host_cmd_ds_802_11_rssi_info rssi_info; |
1385 | struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp; | 1376 | struct host_cmd_ds_802_11_rssi_info_rsp rssi_info_rsp; |
1386 | struct host_cmd_ds_802_11_snmp_mib smib; | 1377 | struct host_cmd_ds_802_11_snmp_mib smib; |
1387 | struct host_cmd_ds_802_11_rf_channel rf_channel; | ||
1388 | struct host_cmd_ds_tx_rate_query tx_rate; | 1378 | struct host_cmd_ds_tx_rate_query tx_rate; |
1389 | struct host_cmd_ds_tx_rate_cfg tx_rate_cfg; | 1379 | struct host_cmd_ds_tx_rate_cfg tx_rate_cfg; |
1390 | struct host_cmd_ds_txpwr_cfg txp_cfg; | 1380 | struct host_cmd_ds_txpwr_cfg txp_cfg; |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index b543a4d82ff3..21fdc6c02775 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -344,7 +344,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
344 | adapter->adhoc_awake_period = 0; | 344 | adapter->adhoc_awake_period = 0; |
345 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); | 345 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); |
346 | adapter->arp_filter_size = 0; | 346 | adapter->arp_filter_size = 0; |
347 | adapter->channel_type = NL80211_CHAN_HT20; | ||
348 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; | 347 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; |
349 | } | 348 | } |
350 | 349 | ||
diff --git a/drivers/net/wireless/mwifiex/ioctl.h b/drivers/net/wireless/mwifiex/ioctl.h index e121294cc1ac..50191539bb32 100644 --- a/drivers/net/wireless/mwifiex/ioctl.h +++ b/drivers/net/wireless/mwifiex/ioctl.h | |||
@@ -225,12 +225,6 @@ struct mwifiex_ds_encrypt_key { | |||
225 | u8 wapi_rxpn[WAPI_RXPN_LEN]; | 225 | u8 wapi_rxpn[WAPI_RXPN_LEN]; |
226 | }; | 226 | }; |
227 | 227 | ||
228 | struct mwifiex_rate_cfg { | ||
229 | u32 action; | ||
230 | u32 is_rate_auto; | ||
231 | u32 rate; | ||
232 | }; | ||
233 | |||
234 | struct mwifiex_power_cfg { | 228 | struct mwifiex_power_cfg { |
235 | u32 is_power_auto; | 229 | u32 is_power_auto; |
236 | u32 power_level; | 230 | u32 power_level; |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f0219efc8953..46803621d015 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -377,7 +377,7 @@ static void mwifiex_fw_dpc(const struct firmware *firmware, void *context) | |||
377 | goto done; | 377 | goto done; |
378 | 378 | ||
379 | err_add_intf: | 379 | err_add_intf: |
380 | mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); | 380 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); |
381 | rtnl_unlock(); | 381 | rtnl_unlock(); |
382 | err_init_fw: | 382 | err_init_fw: |
383 | pr_debug("info: %s: unregister device\n", __func__); | 383 | pr_debug("info: %s: unregister device\n", __func__); |
@@ -844,7 +844,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem) | |||
844 | 844 | ||
845 | rtnl_lock(); | 845 | rtnl_lock(); |
846 | if (priv->wdev && priv->netdev) | 846 | if (priv->wdev && priv->netdev) |
847 | mwifiex_del_virtual_intf(adapter->wiphy, priv->netdev); | 847 | mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev); |
848 | rtnl_unlock(); | 848 | rtnl_unlock(); |
849 | } | 849 | } |
850 | 850 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 9e636535cbf6..e7c2a82fd610 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -678,7 +678,6 @@ struct mwifiex_adapter { | |||
678 | u8 hw_dev_mcs_support; | 678 | u8 hw_dev_mcs_support; |
679 | u8 adhoc_11n_enabled; | 679 | u8 adhoc_11n_enabled; |
680 | u8 sec_chan_offset; | 680 | u8 sec_chan_offset; |
681 | enum nl80211_channel_type channel_type; | ||
682 | struct mwifiex_dbg dbg; | 681 | struct mwifiex_dbg dbg; |
683 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; | 682 | u8 arp_filter[ARP_FILTER_MAX_BUF_SIZE]; |
684 | u32 arp_filter_size; | 683 | u32 arp_filter_size; |
@@ -824,9 +823,7 @@ int mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv, u16 vsie_mask, | |||
824 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, | 823 | u32 mwifiex_get_active_data_rates(struct mwifiex_private *priv, |
825 | u8 *rates); | 824 | u8 *rates); |
826 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); | 825 | u32 mwifiex_get_supported_rates(struct mwifiex_private *priv, u8 *rates); |
827 | u8 mwifiex_data_rate_to_index(u32 rate); | ||
828 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); | 826 | u8 mwifiex_is_rate_auto(struct mwifiex_private *priv); |
829 | int mwifiex_get_rate_index(u16 *rateBitmap, int size); | ||
830 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; | 827 | extern u16 region_code_index[MWIFIEX_MAX_REGION_CODE]; |
831 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); | 828 | void mwifiex_save_curr_bcn(struct mwifiex_private *priv); |
832 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); | 829 | void mwifiex_free_curr_bcn(struct mwifiex_private *priv); |
@@ -945,16 +942,13 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
945 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); | 942 | int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); |
946 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); | 943 | int mwifiex_enable_hs(struct mwifiex_adapter *adapter); |
947 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); | 944 | int mwifiex_disable_auto_ds(struct mwifiex_private *priv); |
948 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 945 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, u32 *rate); |
949 | struct mwifiex_rate_cfg *rate); | ||
950 | int mwifiex_request_scan(struct mwifiex_private *priv, | 946 | int mwifiex_request_scan(struct mwifiex_private *priv, |
951 | struct cfg80211_ssid *req_ssid); | 947 | struct cfg80211_ssid *req_ssid); |
952 | int mwifiex_scan_networks(struct mwifiex_private *priv, | 948 | int mwifiex_scan_networks(struct mwifiex_private *priv, |
953 | const struct mwifiex_user_scan_cfg *user_scan_in); | 949 | const struct mwifiex_user_scan_cfg *user_scan_in); |
954 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); | 950 | int mwifiex_set_radio(struct mwifiex_private *priv, u8 option); |
955 | 951 | ||
956 | int mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel); | ||
957 | |||
958 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, | 952 | int mwifiex_set_encode(struct mwifiex_private *priv, const u8 *key, |
959 | int key_len, u8 key_index, const u8 *mac_addr, | 953 | int key_len, u8 key_index, const u8 *mac_addr, |
960 | int disable); | 954 | int disable); |
@@ -993,8 +987,6 @@ int mwifiex_set_tx_power(struct mwifiex_private *priv, | |||
993 | 987 | ||
994 | int mwifiex_main_process(struct mwifiex_adapter *); | 988 | int mwifiex_main_process(struct mwifiex_adapter *); |
995 | 989 | ||
996 | int mwifiex_bss_set_channel(struct mwifiex_private *, | ||
997 | struct mwifiex_chan_freq_power *cfp); | ||
998 | int mwifiex_get_bss_info(struct mwifiex_private *, | 990 | int mwifiex_get_bss_info(struct mwifiex_private *, |
999 | struct mwifiex_bss_info *); | 991 | struct mwifiex_bss_info *); |
1000 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, | 992 | int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, |
@@ -1005,10 +997,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, | |||
1005 | int mwifiex_check_network_compatibility(struct mwifiex_private *priv, | 997 | int mwifiex_check_network_compatibility(struct mwifiex_private *priv, |
1006 | struct mwifiex_bssdescriptor *bss_desc); | 998 | struct mwifiex_bssdescriptor *bss_desc); |
1007 | 999 | ||
1008 | struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, | 1000 | struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy, |
1009 | char *name, enum nl80211_iftype type, | 1001 | char *name, |
1010 | u32 *flags, struct vif_params *params); | 1002 | enum nl80211_iftype type, |
1011 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev); | 1003 | u32 *flags, |
1004 | struct vif_params *params); | ||
1005 | int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev); | ||
1012 | 1006 | ||
1013 | void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); | 1007 | void mwifiex_set_sys_config_invalid_data(struct mwifiex_uap_bss_param *config); |
1014 | 1008 | ||
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c index 225d4c776177..df3a33c530cf 100644 --- a/drivers/net/wireless/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/mwifiex/sta_cmd.c | |||
@@ -745,40 +745,6 @@ static int mwifiex_cmd_802_11d_domain_info(struct mwifiex_private *priv, | |||
745 | } | 745 | } |
746 | 746 | ||
747 | /* | 747 | /* |
748 | * This function prepares command to set/get RF channel. | ||
749 | * | ||
750 | * Preparation includes - | ||
751 | * - Setting command ID, action and proper size | ||
752 | * - Setting RF type and current RF channel (for SET only) | ||
753 | * - Ensuring correct endian-ness | ||
754 | */ | ||
755 | static int mwifiex_cmd_802_11_rf_channel(struct mwifiex_private *priv, | ||
756 | struct host_cmd_ds_command *cmd, | ||
757 | u16 cmd_action, u16 *channel) | ||
758 | { | ||
759 | struct host_cmd_ds_802_11_rf_channel *rf_chan = | ||
760 | &cmd->params.rf_channel; | ||
761 | uint16_t rf_type = le16_to_cpu(rf_chan->rf_type); | ||
762 | |||
763 | cmd->command = cpu_to_le16(HostCmd_CMD_802_11_RF_CHANNEL); | ||
764 | cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_rf_channel) | ||
765 | + S_DS_GEN); | ||
766 | |||
767 | if (cmd_action == HostCmd_ACT_GEN_SET) { | ||
768 | if ((priv->adapter->adhoc_start_band & BAND_A) || | ||
769 | (priv->adapter->adhoc_start_band & BAND_AN)) | ||
770 | rf_chan->rf_type = | ||
771 | cpu_to_le16(HostCmd_SCAN_RADIO_TYPE_A); | ||
772 | |||
773 | rf_type = le16_to_cpu(rf_chan->rf_type); | ||
774 | SET_SECONDARYCHAN(rf_type, priv->adapter->sec_chan_offset); | ||
775 | rf_chan->current_channel = cpu_to_le16(*channel); | ||
776 | } | ||
777 | rf_chan->action = cpu_to_le16(cmd_action); | ||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | /* | ||
782 | * This function prepares command to set/get IBSS coalescing status. | 748 | * This function prepares command to set/get IBSS coalescing status. |
783 | * | 749 | * |
784 | * Preparation includes - | 750 | * Preparation includes - |
@@ -1169,10 +1135,6 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, | |||
1169 | S_DS_GEN); | 1135 | S_DS_GEN); |
1170 | ret = 0; | 1136 | ret = 0; |
1171 | break; | 1137 | break; |
1172 | case HostCmd_CMD_802_11_RF_CHANNEL: | ||
1173 | ret = mwifiex_cmd_802_11_rf_channel(priv, cmd_ptr, cmd_action, | ||
1174 | data_buf); | ||
1175 | break; | ||
1176 | case HostCmd_CMD_FUNC_INIT: | 1138 | case HostCmd_CMD_FUNC_INIT: |
1177 | if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET) | 1139 | if (priv->adapter->hw_status == MWIFIEX_HW_STATUS_RESET) |
1178 | priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY; | 1140 | priv->adapter->hw_status = MWIFIEX_HW_STATUS_READY; |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 97715dfbdf58..0b09004ebb25 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -267,12 +267,10 @@ static int mwifiex_ret_get_log(struct mwifiex_private *priv, | |||
267 | * | 267 | * |
268 | * Based on the new rate bitmaps, the function re-evaluates if | 268 | * Based on the new rate bitmaps, the function re-evaluates if |
269 | * auto data rate has been activated. If not, it sends another | 269 | * auto data rate has been activated. If not, it sends another |
270 | * query to the firmware to get the current Tx data rate and updates | 270 | * query to the firmware to get the current Tx data rate. |
271 | * the driver value. | ||
272 | */ | 271 | */ |
273 | static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | 272 | static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, |
274 | struct host_cmd_ds_command *resp, | 273 | struct host_cmd_ds_command *resp) |
275 | struct mwifiex_rate_cfg *ds_rate) | ||
276 | { | 274 | { |
277 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; | 275 | struct host_cmd_ds_tx_rate_cfg *rate_cfg = &resp->params.tx_rate_cfg; |
278 | struct mwifiex_rate_scope *rate_scope; | 276 | struct mwifiex_rate_scope *rate_scope; |
@@ -280,7 +278,6 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
280 | u16 tlv, tlv_buf_len; | 278 | u16 tlv, tlv_buf_len; |
281 | u8 *tlv_buf; | 279 | u8 *tlv_buf; |
282 | u32 i; | 280 | u32 i; |
283 | int ret = 0; | ||
284 | 281 | ||
285 | tlv_buf = ((u8 *)rate_cfg) + | 282 | tlv_buf = ((u8 *)rate_cfg) + |
286 | sizeof(struct host_cmd_ds_tx_rate_cfg); | 283 | sizeof(struct host_cmd_ds_tx_rate_cfg); |
@@ -318,33 +315,11 @@ static int mwifiex_ret_tx_rate_cfg(struct mwifiex_private *priv, | |||
318 | if (priv->is_data_rate_auto) | 315 | if (priv->is_data_rate_auto) |
319 | priv->data_rate = 0; | 316 | priv->data_rate = 0; |
320 | else | 317 | else |
321 | ret = mwifiex_send_cmd_async(priv, | 318 | return mwifiex_send_cmd_async(priv, |
322 | HostCmd_CMD_802_11_TX_RATE_QUERY, | 319 | HostCmd_CMD_802_11_TX_RATE_QUERY, |
323 | HostCmd_ACT_GEN_GET, 0, NULL); | 320 | HostCmd_ACT_GEN_GET, 0, NULL); |
324 | |||
325 | if (!ds_rate) | ||
326 | return ret; | ||
327 | |||
328 | if (le16_to_cpu(rate_cfg->action) == HostCmd_ACT_GEN_GET) { | ||
329 | if (priv->is_data_rate_auto) { | ||
330 | ds_rate->is_rate_auto = 1; | ||
331 | return ret; | ||
332 | } | ||
333 | ds_rate->rate = mwifiex_get_rate_index(priv->bitmap_rates, | ||
334 | sizeof(priv->bitmap_rates)); | ||
335 | |||
336 | if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_OFDM0 && | ||
337 | ds_rate->rate <= MWIFIEX_RATE_BITMAP_OFDM7) | ||
338 | ds_rate->rate -= (MWIFIEX_RATE_BITMAP_OFDM0 - | ||
339 | MWIFIEX_RATE_INDEX_OFDM0); | ||
340 | |||
341 | if (ds_rate->rate >= MWIFIEX_RATE_BITMAP_MCS0 && | ||
342 | ds_rate->rate <= MWIFIEX_RATE_BITMAP_MCS127) | ||
343 | ds_rate->rate -= (MWIFIEX_RATE_BITMAP_MCS0 - | ||
344 | MWIFIEX_RATE_INDEX_MCS0); | ||
345 | } | ||
346 | 321 | ||
347 | return ret; | 322 | return 0; |
348 | } | 323 | } |
349 | 324 | ||
350 | /* | 325 | /* |
@@ -656,34 +631,6 @@ static int mwifiex_ret_802_11d_domain_info(struct mwifiex_private *priv, | |||
656 | } | 631 | } |
657 | 632 | ||
658 | /* | 633 | /* |
659 | * This function handles the command response of get RF channel. | ||
660 | * | ||
661 | * Handling includes changing the header fields into CPU format | ||
662 | * and saving the new channel in driver. | ||
663 | */ | ||
664 | static int mwifiex_ret_802_11_rf_channel(struct mwifiex_private *priv, | ||
665 | struct host_cmd_ds_command *resp, | ||
666 | u16 *data_buf) | ||
667 | { | ||
668 | struct host_cmd_ds_802_11_rf_channel *rf_channel = | ||
669 | &resp->params.rf_channel; | ||
670 | u16 new_channel = le16_to_cpu(rf_channel->current_channel); | ||
671 | |||
672 | if (priv->curr_bss_params.bss_descriptor.channel != new_channel) { | ||
673 | dev_dbg(priv->adapter->dev, "cmd: Channel Switch: %d to %d\n", | ||
674 | priv->curr_bss_params.bss_descriptor.channel, | ||
675 | new_channel); | ||
676 | /* Update the channel again */ | ||
677 | priv->curr_bss_params.bss_descriptor.channel = new_channel; | ||
678 | } | ||
679 | |||
680 | if (data_buf) | ||
681 | *data_buf = new_channel; | ||
682 | |||
683 | return 0; | ||
684 | } | ||
685 | |||
686 | /* | ||
687 | * This function handles the command response of get extended version. | 634 | * This function handles the command response of get extended version. |
688 | * | 635 | * |
689 | * Handling includes forming the extended version string and sending it | 636 | * Handling includes forming the extended version string and sending it |
@@ -878,7 +825,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, | |||
878 | ret = mwifiex_ret_mac_multicast_adr(priv, resp); | 825 | ret = mwifiex_ret_mac_multicast_adr(priv, resp); |
879 | break; | 826 | break; |
880 | case HostCmd_CMD_TX_RATE_CFG: | 827 | case HostCmd_CMD_TX_RATE_CFG: |
881 | ret = mwifiex_ret_tx_rate_cfg(priv, resp, data_buf); | 828 | ret = mwifiex_ret_tx_rate_cfg(priv, resp); |
882 | break; | 829 | break; |
883 | case HostCmd_CMD_802_11_SCAN: | 830 | case HostCmd_CMD_802_11_SCAN: |
884 | ret = mwifiex_ret_802_11_scan(priv, resp); | 831 | ret = mwifiex_ret_802_11_scan(priv, resp); |
@@ -929,9 +876,6 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, | |||
929 | case HostCmd_CMD_802_11_TX_RATE_QUERY: | 876 | case HostCmd_CMD_802_11_TX_RATE_QUERY: |
930 | ret = mwifiex_ret_802_11_tx_rate_query(priv, resp); | 877 | ret = mwifiex_ret_802_11_tx_rate_query(priv, resp); |
931 | break; | 878 | break; |
932 | case HostCmd_CMD_802_11_RF_CHANNEL: | ||
933 | ret = mwifiex_ret_802_11_rf_channel(priv, resp, data_buf); | ||
934 | break; | ||
935 | case HostCmd_CMD_VERSION_EXT: | 879 | case HostCmd_CMD_VERSION_EXT: |
936 | ret = mwifiex_ret_ver_ext(priv, resp, data_buf); | 880 | ret = mwifiex_ret_ver_ext(priv, resp, data_buf); |
937 | break; | 881 | break; |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index f2fd2423214f..fb2136089a22 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -497,297 +497,24 @@ int mwifiex_disable_auto_ds(struct mwifiex_private *priv) | |||
497 | EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); | 497 | EXPORT_SYMBOL_GPL(mwifiex_disable_auto_ds); |
498 | 498 | ||
499 | /* | 499 | /* |
500 | * IOCTL request handler to set/get active channel. | ||
501 | * | ||
502 | * This function performs validity checking on channel/frequency | ||
503 | * compatibility and returns failure if not valid. | ||
504 | */ | ||
505 | int mwifiex_bss_set_channel(struct mwifiex_private *priv, | ||
506 | struct mwifiex_chan_freq_power *chan) | ||
507 | { | ||
508 | struct mwifiex_adapter *adapter = priv->adapter; | ||
509 | struct mwifiex_chan_freq_power *cfp = NULL; | ||
510 | |||
511 | if (!chan) | ||
512 | return -1; | ||
513 | |||
514 | if (!chan->channel && !chan->freq) | ||
515 | return -1; | ||
516 | if (adapter->adhoc_start_band & BAND_AN) | ||
517 | adapter->adhoc_start_band = BAND_G | BAND_B | BAND_GN; | ||
518 | else if (adapter->adhoc_start_band & BAND_A) | ||
519 | adapter->adhoc_start_band = BAND_G | BAND_B; | ||
520 | if (chan->channel) { | ||
521 | if (chan->channel <= MAX_CHANNEL_BAND_BG) | ||
522 | cfp = mwifiex_get_cfp(priv, 0, (u16) chan->channel, 0); | ||
523 | if (!cfp) { | ||
524 | cfp = mwifiex_get_cfp(priv, BAND_A, | ||
525 | (u16) chan->channel, 0); | ||
526 | if (cfp) { | ||
527 | if (adapter->adhoc_11n_enabled) | ||
528 | adapter->adhoc_start_band = BAND_A | ||
529 | | BAND_AN; | ||
530 | else | ||
531 | adapter->adhoc_start_band = BAND_A; | ||
532 | } | ||
533 | } | ||
534 | } else { | ||
535 | if (chan->freq <= MAX_FREQUENCY_BAND_BG) | ||
536 | cfp = mwifiex_get_cfp(priv, 0, 0, chan->freq); | ||
537 | if (!cfp) { | ||
538 | cfp = mwifiex_get_cfp(priv, BAND_A, 0, chan->freq); | ||
539 | if (cfp) { | ||
540 | if (adapter->adhoc_11n_enabled) | ||
541 | adapter->adhoc_start_band = BAND_A | ||
542 | | BAND_AN; | ||
543 | else | ||
544 | adapter->adhoc_start_band = BAND_A; | ||
545 | } | ||
546 | } | ||
547 | } | ||
548 | if (!cfp || !cfp->channel) { | ||
549 | dev_err(adapter->dev, "invalid channel/freq\n"); | ||
550 | return -1; | ||
551 | } | ||
552 | priv->adhoc_channel = (u8) cfp->channel; | ||
553 | chan->channel = cfp->channel; | ||
554 | chan->freq = cfp->freq; | ||
555 | |||
556 | return 0; | ||
557 | } | ||
558 | |||
559 | /* | ||
560 | * IOCTL request handler to set/get Ad-Hoc channel. | ||
561 | * | ||
562 | * This function prepares the correct firmware command and | ||
563 | * issues it to set or get the ad-hoc channel. | ||
564 | */ | ||
565 | static int mwifiex_bss_ioctl_ibss_channel(struct mwifiex_private *priv, | ||
566 | u16 action, u16 *channel) | ||
567 | { | ||
568 | if (action == HostCmd_ACT_GEN_GET) { | ||
569 | if (!priv->media_connected) { | ||
570 | *channel = priv->adhoc_channel; | ||
571 | return 0; | ||
572 | } | ||
573 | } else { | ||
574 | priv->adhoc_channel = (u8) *channel; | ||
575 | } | ||
576 | |||
577 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_RF_CHANNEL, | ||
578 | action, 0, channel); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * IOCTL request handler to change Ad-Hoc channel. | ||
583 | * | ||
584 | * This function allocates the IOCTL request buffer, fills it | ||
585 | * with requisite parameters and calls the IOCTL handler. | ||
586 | * | ||
587 | * The function follows the following steps to perform the change - | ||
588 | * - Get current IBSS information | ||
589 | * - Get current channel | ||
590 | * - If no change is required, return | ||
591 | * - If not connected, change channel and return | ||
592 | * - If connected, | ||
593 | * - Disconnect | ||
594 | * - Change channel | ||
595 | * - Perform specific SSID scan with same SSID | ||
596 | * - Start/Join the IBSS | ||
597 | */ | ||
598 | int | ||
599 | mwifiex_drv_change_adhoc_chan(struct mwifiex_private *priv, u16 channel) | ||
600 | { | ||
601 | int ret; | ||
602 | struct mwifiex_bss_info bss_info; | ||
603 | struct mwifiex_ssid_bssid ssid_bssid; | ||
604 | u16 curr_chan = 0; | ||
605 | struct cfg80211_bss *bss = NULL; | ||
606 | struct ieee80211_channel *chan; | ||
607 | enum ieee80211_band band; | ||
608 | |||
609 | memset(&bss_info, 0, sizeof(bss_info)); | ||
610 | |||
611 | /* Get BSS information */ | ||
612 | if (mwifiex_get_bss_info(priv, &bss_info)) | ||
613 | return -1; | ||
614 | |||
615 | /* Get current channel */ | ||
616 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_GET, | ||
617 | &curr_chan); | ||
618 | |||
619 | if (curr_chan == channel) { | ||
620 | ret = 0; | ||
621 | goto done; | ||
622 | } | ||
623 | dev_dbg(priv->adapter->dev, "cmd: updating channel from %d to %d\n", | ||
624 | curr_chan, channel); | ||
625 | |||
626 | if (!bss_info.media_connected) { | ||
627 | ret = 0; | ||
628 | goto done; | ||
629 | } | ||
630 | |||
631 | /* Do disonnect */ | ||
632 | memset(&ssid_bssid, 0, ETH_ALEN); | ||
633 | ret = mwifiex_deauthenticate(priv, ssid_bssid.bssid); | ||
634 | |||
635 | ret = mwifiex_bss_ioctl_ibss_channel(priv, HostCmd_ACT_GEN_SET, | ||
636 | &channel); | ||
637 | |||
638 | /* Do specific SSID scanning */ | ||
639 | if (mwifiex_request_scan(priv, &bss_info.ssid)) { | ||
640 | ret = -1; | ||
641 | goto done; | ||
642 | } | ||
643 | |||
644 | band = mwifiex_band_to_radio_type(priv->curr_bss_params.band); | ||
645 | chan = __ieee80211_get_channel(priv->wdev->wiphy, | ||
646 | ieee80211_channel_to_frequency(channel, | ||
647 | band)); | ||
648 | |||
649 | /* Find the BSS we want using available scan results */ | ||
650 | bss = cfg80211_get_bss(priv->wdev->wiphy, chan, bss_info.bssid, | ||
651 | bss_info.ssid.ssid, bss_info.ssid.ssid_len, | ||
652 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | ||
653 | if (!bss) | ||
654 | wiphy_warn(priv->wdev->wiphy, "assoc: bss %pM not in scan results\n", | ||
655 | bss_info.bssid); | ||
656 | |||
657 | ret = mwifiex_bss_start(priv, bss, &bss_info.ssid); | ||
658 | done: | ||
659 | return ret; | ||
660 | } | ||
661 | |||
662 | /* | ||
663 | * IOCTL request handler to get rate. | ||
664 | * | ||
665 | * This function prepares the correct firmware command and | ||
666 | * issues it to get the current rate if it is connected, | ||
667 | * otherwise, the function returns the lowest supported rate | ||
668 | * for the band. | ||
669 | */ | ||
670 | static int mwifiex_rate_ioctl_get_rate_value(struct mwifiex_private *priv, | ||
671 | struct mwifiex_rate_cfg *rate_cfg) | ||
672 | { | ||
673 | rate_cfg->is_rate_auto = priv->is_data_rate_auto; | ||
674 | return mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, | ||
675 | HostCmd_ACT_GEN_GET, 0, NULL); | ||
676 | } | ||
677 | |||
678 | /* | ||
679 | * IOCTL request handler to set rate. | ||
680 | * | ||
681 | * This function prepares the correct firmware command and | ||
682 | * issues it to set the current rate. | ||
683 | * | ||
684 | * The function also performs validation checking on the supplied value. | ||
685 | */ | ||
686 | static int mwifiex_rate_ioctl_set_rate_value(struct mwifiex_private *priv, | ||
687 | struct mwifiex_rate_cfg *rate_cfg) | ||
688 | { | ||
689 | u8 rates[MWIFIEX_SUPPORTED_RATES]; | ||
690 | u8 *rate; | ||
691 | int rate_index, ret; | ||
692 | u16 bitmap_rates[MAX_BITMAP_RATES_SIZE]; | ||
693 | u32 i; | ||
694 | struct mwifiex_adapter *adapter = priv->adapter; | ||
695 | |||
696 | if (rate_cfg->is_rate_auto) { | ||
697 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); | ||
698 | /* Support all HR/DSSS rates */ | ||
699 | bitmap_rates[0] = 0x000F; | ||
700 | /* Support all OFDM rates */ | ||
701 | bitmap_rates[1] = 0x00FF; | ||
702 | /* Support all HT-MCSs rate */ | ||
703 | for (i = 0; i < ARRAY_SIZE(priv->bitmap_rates) - 3; i++) | ||
704 | bitmap_rates[i + 2] = 0xFFFF; | ||
705 | bitmap_rates[9] = 0x3FFF; | ||
706 | } else { | ||
707 | memset(rates, 0, sizeof(rates)); | ||
708 | mwifiex_get_active_data_rates(priv, rates); | ||
709 | rate = rates; | ||
710 | for (i = 0; (rate[i] && i < MWIFIEX_SUPPORTED_RATES); i++) { | ||
711 | dev_dbg(adapter->dev, "info: rate=%#x wanted=%#x\n", | ||
712 | rate[i], rate_cfg->rate); | ||
713 | if ((rate[i] & 0x7f) == (rate_cfg->rate & 0x7f)) | ||
714 | break; | ||
715 | } | ||
716 | if ((i == MWIFIEX_SUPPORTED_RATES) || !rate[i]) { | ||
717 | dev_err(adapter->dev, "fixed data rate %#x is out " | ||
718 | "of range\n", rate_cfg->rate); | ||
719 | return -1; | ||
720 | } | ||
721 | memset(bitmap_rates, 0, sizeof(bitmap_rates)); | ||
722 | |||
723 | rate_index = mwifiex_data_rate_to_index(rate_cfg->rate); | ||
724 | |||
725 | /* Only allow b/g rates to be set */ | ||
726 | if (rate_index >= MWIFIEX_RATE_INDEX_HRDSSS0 && | ||
727 | rate_index <= MWIFIEX_RATE_INDEX_HRDSSS3) { | ||
728 | bitmap_rates[0] = 1 << rate_index; | ||
729 | } else { | ||
730 | rate_index -= 1; /* There is a 0x00 in the table */ | ||
731 | if (rate_index >= MWIFIEX_RATE_INDEX_OFDM0 && | ||
732 | rate_index <= MWIFIEX_RATE_INDEX_OFDM7) | ||
733 | bitmap_rates[1] = 1 << (rate_index - | ||
734 | MWIFIEX_RATE_INDEX_OFDM0); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_TX_RATE_CFG, | ||
739 | HostCmd_ACT_GEN_SET, 0, bitmap_rates); | ||
740 | |||
741 | return ret; | ||
742 | } | ||
743 | |||
744 | /* | ||
745 | * IOCTL request handler to set/get rate. | ||
746 | * | ||
747 | * This function can be used to set/get either the rate value or the | ||
748 | * rate index. | ||
749 | */ | ||
750 | static int mwifiex_rate_ioctl_cfg(struct mwifiex_private *priv, | ||
751 | struct mwifiex_rate_cfg *rate_cfg) | ||
752 | { | ||
753 | int status; | ||
754 | |||
755 | if (!rate_cfg) | ||
756 | return -1; | ||
757 | |||
758 | if (rate_cfg->action == HostCmd_ACT_GEN_GET) | ||
759 | status = mwifiex_rate_ioctl_get_rate_value(priv, rate_cfg); | ||
760 | else | ||
761 | status = mwifiex_rate_ioctl_set_rate_value(priv, rate_cfg); | ||
762 | |||
763 | return status; | ||
764 | } | ||
765 | |||
766 | /* | ||
767 | * Sends IOCTL request to get the data rate. | 500 | * Sends IOCTL request to get the data rate. |
768 | * | 501 | * |
769 | * This function allocates the IOCTL request buffer, fills it | 502 | * This function allocates the IOCTL request buffer, fills it |
770 | * with requisite parameters and calls the IOCTL handler. | 503 | * with requisite parameters and calls the IOCTL handler. |
771 | */ | 504 | */ |
772 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, | 505 | int mwifiex_drv_get_data_rate(struct mwifiex_private *priv, u32 *rate) |
773 | struct mwifiex_rate_cfg *rate) | ||
774 | { | 506 | { |
775 | int ret; | 507 | int ret; |
776 | 508 | ||
777 | memset(rate, 0, sizeof(struct mwifiex_rate_cfg)); | 509 | ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_TX_RATE_QUERY, |
778 | rate->action = HostCmd_ACT_GEN_GET; | 510 | HostCmd_ACT_GEN_GET, 0, NULL); |
779 | ret = mwifiex_rate_ioctl_cfg(priv, rate); | ||
780 | 511 | ||
781 | if (!ret) { | 512 | if (!ret) { |
782 | if (rate->is_rate_auto) | 513 | if (priv->is_data_rate_auto) |
783 | rate->rate = mwifiex_index_to_data_rate(priv, | 514 | *rate = mwifiex_index_to_data_rate(priv, priv->tx_rate, |
784 | priv->tx_rate, | 515 | priv->tx_htinfo); |
785 | priv->tx_htinfo | ||
786 | ); | ||
787 | else | 516 | else |
788 | rate->rate = priv->data_rate; | 517 | *rate = priv->data_rate; |
789 | } else { | ||
790 | ret = -1; | ||
791 | } | 518 | } |
792 | 519 | ||
793 | return ret; | 520 | return ret; |
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index cf7bdc66f822..224e03ade145 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c | |||
@@ -1665,7 +1665,9 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1665 | 1665 | ||
1666 | info = IEEE80211_SKB_CB(skb); | 1666 | info = IEEE80211_SKB_CB(skb); |
1667 | if (ieee80211_is_data(wh->frame_control)) { | 1667 | if (ieee80211_is_data(wh->frame_control)) { |
1668 | sta = info->control.sta; | 1668 | rcu_read_lock(); |
1669 | sta = ieee80211_find_sta_by_ifaddr(hw, wh->addr1, | ||
1670 | wh->addr2); | ||
1669 | if (sta) { | 1671 | if (sta) { |
1670 | sta_info = MWL8K_STA(sta); | 1672 | sta_info = MWL8K_STA(sta); |
1671 | BUG_ON(sta_info == NULL); | 1673 | BUG_ON(sta_info == NULL); |
@@ -1682,6 +1684,7 @@ mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force) | |||
1682 | sta_info->is_ampdu_allowed = true; | 1684 | sta_info->is_ampdu_allowed = true; |
1683 | } | 1685 | } |
1684 | } | 1686 | } |
1687 | rcu_read_unlock(); | ||
1685 | } | 1688 | } |
1686 | 1689 | ||
1687 | ieee80211_tx_info_clear_status(info); | 1690 | ieee80211_tx_info_clear_status(info); |
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c index e15675585fb1..7b751fba7e1f 100644 --- a/drivers/net/wireless/orinoco/cfg.c +++ b/drivers/net/wireless/orinoco/cfg.c | |||
@@ -138,7 +138,7 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev, | |||
138 | return err; | 138 | return err; |
139 | } | 139 | } |
140 | 140 | ||
141 | static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev, | 141 | static int orinoco_scan(struct wiphy *wiphy, |
142 | struct cfg80211_scan_request *request) | 142 | struct cfg80211_scan_request *request) |
143 | { | 143 | { |
144 | struct orinoco_private *priv = wiphy_priv(wiphy); | 144 | struct orinoco_private *priv = wiphy_priv(wiphy); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index dfcd02ab6cae..241162e8111d 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -484,7 +484,7 @@ static int rndis_change_virtual_intf(struct wiphy *wiphy, | |||
484 | enum nl80211_iftype type, u32 *flags, | 484 | enum nl80211_iftype type, u32 *flags, |
485 | struct vif_params *params); | 485 | struct vif_params *params); |
486 | 486 | ||
487 | static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | 487 | static int rndis_scan(struct wiphy *wiphy, |
488 | struct cfg80211_scan_request *request); | 488 | struct cfg80211_scan_request *request); |
489 | 489 | ||
490 | static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); | 490 | static int rndis_set_wiphy_params(struct wiphy *wiphy, u32 changed); |
@@ -1941,9 +1941,10 @@ static int rndis_get_tx_power(struct wiphy *wiphy, int *dbm) | |||
1941 | } | 1941 | } |
1942 | 1942 | ||
1943 | #define SCAN_DELAY_JIFFIES (6 * HZ) | 1943 | #define SCAN_DELAY_JIFFIES (6 * HZ) |
1944 | static int rndis_scan(struct wiphy *wiphy, struct net_device *dev, | 1944 | static int rndis_scan(struct wiphy *wiphy, |
1945 | struct cfg80211_scan_request *request) | 1945 | struct cfg80211_scan_request *request) |
1946 | { | 1946 | { |
1947 | struct net_device *dev = request->wdev->netdev; | ||
1947 | struct usbnet *usbdev = netdev_priv(dev); | 1948 | struct usbnet *usbdev = netdev_priv(dev); |
1948 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); | 1949 | struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); |
1949 | int ret; | 1950 | int ret; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index e7361d913e8e..49a63e973934 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -102,7 +102,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev, | |||
102 | 102 | ||
103 | /* Update the AID, this is needed for dynamic PS support */ | 103 | /* Update the AID, this is needed for dynamic PS support */ |
104 | rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; | 104 | rt2x00dev->aid = bss_conf->assoc ? bss_conf->aid : 0; |
105 | rt2x00dev->last_beacon = bss_conf->last_tsf; | 105 | rt2x00dev->last_beacon = bss_conf->sync_tsf; |
106 | 106 | ||
107 | /* Update global beacon interval time, this is needed for PS support */ | 107 | /* Update global beacon interval time, this is needed for PS support */ |
108 | rt2x00dev->beacon_int = bss_conf->beacon_int; | 108 | rt2x00dev->beacon_int = bss_conf->beacon_int; |
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 58e1f7bb4df1..942e56b77b60 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
@@ -167,7 +167,7 @@ static const u8 tid_to_ac[] = { | |||
167 | 0, /* IEEE80211_AC_VO */ | 167 | 0, /* IEEE80211_AC_VO */ |
168 | }; | 168 | }; |
169 | 169 | ||
170 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid) | 170 | u8 rtl_tid_to_ac(u8 tid) |
171 | { | 171 | { |
172 | return tid_to_ac[tid]; | 172 | return tid_to_ac[tid]; |
173 | } | 173 | } |
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index 5a23a6d0f49d..f35af0fdaaf0 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h | |||
@@ -138,7 +138,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, | |||
138 | enum ieee80211_smps_mode smps); | 138 | enum ieee80211_smps_mode smps); |
139 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); | 139 | u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); |
140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); | 140 | void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); |
141 | u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid); | 141 | u8 rtl_tid_to_ac(u8 tid); |
142 | extern struct attribute_group rtl_attribute_group; | 142 | extern struct attribute_group rtl_attribute_group; |
143 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, | 143 | int rtlwifi_rate_mapping(struct ieee80211_hw *hw, |
144 | bool isht, u8 desc_rate, bool first_ampdu); | 144 | bool isht, u8 desc_rate, bool first_ampdu); |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 31138fdad1f7..80f75d3ba84a 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -480,7 +480,7 @@ static void _rtl_pci_tx_chk_waitq(struct ieee80211_hw *hw) | |||
480 | 480 | ||
481 | /* we juse use em for BE/BK/VI/VO */ | 481 | /* we juse use em for BE/BK/VI/VO */ |
482 | for (tid = 7; tid >= 0; tid--) { | 482 | for (tid = 7; tid >= 0; tid--) { |
483 | u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(hw, tid)]; | 483 | u8 hw_queue = ac_to_hwq[rtl_tid_to_ac(tid)]; |
484 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; | 484 | struct rtl8192_tx_ring *ring = &rtlpci->tx_ring[hw_queue]; |
485 | while (!mac->act_scanning && | 485 | while (!mac->act_scanning && |
486 | rtlpriv->psc.rfpwr_state == ERFON) { | 486 | rtlpriv->psc.rfpwr_state == ERFON) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 18380a7829f1..442031256bce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c | |||
@@ -3345,21 +3345,21 @@ void rtl92d_phy_config_macphymode_info(struct ieee80211_hw *hw) | |||
3345 | switch (rtlhal->macphymode) { | 3345 | switch (rtlhal->macphymode) { |
3346 | case DUALMAC_SINGLEPHY: | 3346 | case DUALMAC_SINGLEPHY: |
3347 | rtlphy->rf_type = RF_2T2R; | 3347 | rtlphy->rf_type = RF_2T2R; |
3348 | rtlhal->version |= CHIP_92D_SINGLEPHY; | 3348 | rtlhal->version |= RF_TYPE_2T2R; |
3349 | rtlhal->bandset = BAND_ON_BOTH; | 3349 | rtlhal->bandset = BAND_ON_BOTH; |
3350 | rtlhal->current_bandtype = BAND_ON_2_4G; | 3350 | rtlhal->current_bandtype = BAND_ON_2_4G; |
3351 | break; | 3351 | break; |
3352 | 3352 | ||
3353 | case SINGLEMAC_SINGLEPHY: | 3353 | case SINGLEMAC_SINGLEPHY: |
3354 | rtlphy->rf_type = RF_2T2R; | 3354 | rtlphy->rf_type = RF_2T2R; |
3355 | rtlhal->version |= CHIP_92D_SINGLEPHY; | 3355 | rtlhal->version |= RF_TYPE_2T2R; |
3356 | rtlhal->bandset = BAND_ON_BOTH; | 3356 | rtlhal->bandset = BAND_ON_BOTH; |
3357 | rtlhal->current_bandtype = BAND_ON_2_4G; | 3357 | rtlhal->current_bandtype = BAND_ON_2_4G; |
3358 | break; | 3358 | break; |
3359 | 3359 | ||
3360 | case DUALMAC_DUALPHY: | 3360 | case DUALMAC_DUALPHY: |
3361 | rtlphy->rf_type = RF_1T1R; | 3361 | rtlphy->rf_type = RF_1T1R; |
3362 | rtlhal->version &= (~CHIP_92D_SINGLEPHY); | 3362 | rtlhal->version &= RF_TYPE_1T1R; |
3363 | /* Now we let MAC0 run on 5G band. */ | 3363 | /* Now we let MAC0 run on 5G band. */ |
3364 | if (rtlhal->interfaceindex == 0) { | 3364 | if (rtlhal->interfaceindex == 0) { |
3365 | rtlhal->bandset = BAND_ON_5G; | 3365 | rtlhal->bandset = BAND_ON_5G; |
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index a6049d7d51b3..aa970fc18a21 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c | |||
@@ -131,15 +131,19 @@ static u32 _usb_read_sync(struct rtl_priv *rtlpriv, u32 addr, u16 len) | |||
131 | u8 request; | 131 | u8 request; |
132 | u16 wvalue; | 132 | u16 wvalue; |
133 | u16 index; | 133 | u16 index; |
134 | __le32 *data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; | 134 | __le32 *data; |
135 | unsigned long flags; | ||
135 | 136 | ||
137 | spin_lock_irqsave(&rtlpriv->locks.usb_lock, flags); | ||
138 | if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) | ||
139 | rtlpriv->usb_data_index = 0; | ||
140 | data = &rtlpriv->usb_data[rtlpriv->usb_data_index]; | ||
141 | spin_unlock_irqrestore(&rtlpriv->locks.usb_lock, flags); | ||
136 | request = REALTEK_USB_VENQT_CMD_REQ; | 142 | request = REALTEK_USB_VENQT_CMD_REQ; |
137 | index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ | 143 | index = REALTEK_USB_VENQT_CMD_IDX; /* n/a */ |
138 | 144 | ||
139 | wvalue = (u16)addr; | 145 | wvalue = (u16)addr; |
140 | _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); | 146 | _usbctrl_vendorreq_sync_read(udev, request, wvalue, index, data, len); |
141 | if (++rtlpriv->usb_data_index >= RTL_USB_MAX_RX_COUNT) | ||
142 | rtlpriv->usb_data_index = 0; | ||
143 | return le32_to_cpu(*data); | 147 | return le32_to_cpu(*data); |
144 | } | 148 | } |
145 | 149 | ||
@@ -951,6 +955,10 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, | |||
951 | GFP_KERNEL); | 955 | GFP_KERNEL); |
952 | if (!rtlpriv->usb_data) | 956 | if (!rtlpriv->usb_data) |
953 | return -ENOMEM; | 957 | return -ENOMEM; |
958 | |||
959 | /* this spin lock must be initialized early */ | ||
960 | spin_lock_init(&rtlpriv->locks.usb_lock); | ||
961 | |||
954 | rtlpriv->usb_data_index = 0; | 962 | rtlpriv->usb_data_index = 0; |
955 | init_completion(&rtlpriv->firmware_loading_complete); | 963 | init_completion(&rtlpriv->firmware_loading_complete); |
956 | SET_IEEE80211_DEV(hw, &intf->dev); | 964 | SET_IEEE80211_DEV(hw, &intf->dev); |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index bd816aef26dc..cdaa21f29710 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -1555,6 +1555,7 @@ struct rtl_locks { | |||
1555 | spinlock_t rf_ps_lock; | 1555 | spinlock_t rf_ps_lock; |
1556 | spinlock_t rf_lock; | 1556 | spinlock_t rf_lock; |
1557 | spinlock_t waitq_lock; | 1557 | spinlock_t waitq_lock; |
1558 | spinlock_t usb_lock; | ||
1558 | 1559 | ||
1559 | /*Dual mac*/ | 1560 | /*Dual mac*/ |
1560 | spinlock_t cck_and_rw_pagea_lock; | 1561 | spinlock_t cck_and_rw_pagea_lock; |
diff --git a/drivers/net/wireless/ti/wl12xx/cmd.c b/drivers/net/wireless/ti/wl12xx/cmd.c index 30be784a40d8..622206241e83 100644 --- a/drivers/net/wireless/ti/wl12xx/cmd.c +++ b/drivers/net/wireless/ti/wl12xx/cmd.c | |||
@@ -85,7 +85,11 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) | |||
85 | 85 | ||
86 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); | 86 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); |
87 | 87 | ||
88 | if (gp->tx_bip_fem_auto_detect) | 88 | /* If we started in PLT FEM_DETECT mode, force auto detect */ |
89 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
90 | gen_parms->general_params.tx_bip_fem_auto_detect = true; | ||
91 | |||
92 | if (gen_parms->general_params.tx_bip_fem_auto_detect) | ||
89 | answer = true; | 93 | answer = true; |
90 | 94 | ||
91 | /* Override the REF CLK from the NVS with the one from platform data */ | 95 | /* Override the REF CLK from the NVS with the one from platform data */ |
@@ -106,8 +110,17 @@ int wl1271_cmd_general_parms(struct wl1271 *wl) | |||
106 | goto out; | 110 | goto out; |
107 | } | 111 | } |
108 | 112 | ||
113 | /* If we are in calibrator based fem auto detect - save fem nr */ | ||
114 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
115 | wl->fem_manuf = gp->tx_bip_fem_manufacturer; | ||
116 | |||
109 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", | 117 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", |
110 | answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); | 118 | answer == false ? |
119 | "manual" : | ||
120 | wl->plt_mode == PLT_FEM_DETECT ? | ||
121 | "calibrator_fem_detect" : | ||
122 | "auto", | ||
123 | gp->tx_bip_fem_manufacturer); | ||
111 | 124 | ||
112 | out: | 125 | out: |
113 | kfree(gen_parms); | 126 | kfree(gen_parms); |
@@ -139,7 +152,11 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) | |||
139 | 152 | ||
140 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); | 153 | memcpy(&gen_parms->general_params, gp, sizeof(*gp)); |
141 | 154 | ||
142 | if (gp->tx_bip_fem_auto_detect) | 155 | /* If we started in PLT FEM_DETECT mode, force auto detect */ |
156 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
157 | gen_parms->general_params.tx_bip_fem_auto_detect = true; | ||
158 | |||
159 | if (gen_parms->general_params.tx_bip_fem_auto_detect) | ||
143 | answer = true; | 160 | answer = true; |
144 | 161 | ||
145 | /* Replace REF and TCXO CLKs with the ones from platform data */ | 162 | /* Replace REF and TCXO CLKs with the ones from platform data */ |
@@ -161,8 +178,17 @@ int wl128x_cmd_general_parms(struct wl1271 *wl) | |||
161 | goto out; | 178 | goto out; |
162 | } | 179 | } |
163 | 180 | ||
181 | /* If we are in calibrator based fem auto detect - save fem nr */ | ||
182 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
183 | wl->fem_manuf = gp->tx_bip_fem_manufacturer; | ||
184 | |||
164 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", | 185 | wl1271_debug(DEBUG_CMD, "FEM autodetect: %s, manufacturer: %d\n", |
165 | answer ? "auto" : "manual", gp->tx_bip_fem_manufacturer); | 186 | answer == false ? |
187 | "manual" : | ||
188 | wl->plt_mode == PLT_FEM_DETECT ? | ||
189 | "calibrator_fem_detect" : | ||
190 | "auto", | ||
191 | gp->tx_bip_fem_manufacturer); | ||
166 | 192 | ||
167 | out: | 193 | out: |
168 | kfree(gen_parms); | 194 | kfree(gen_parms); |
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c index 3d6c71b7a3c7..f429fc110cb0 100644 --- a/drivers/net/wireless/ti/wl12xx/main.c +++ b/drivers/net/wireless/ti/wl12xx/main.c | |||
@@ -1339,6 +1339,14 @@ static int wl12xx_hw_init(struct wl1271 *wl) | |||
1339 | ret = wl128x_cmd_general_parms(wl); | 1339 | ret = wl128x_cmd_general_parms(wl); |
1340 | if (ret < 0) | 1340 | if (ret < 0) |
1341 | goto out; | 1341 | goto out; |
1342 | |||
1343 | /* | ||
1344 | * If we are in calibrator based auto detect then we got the FEM nr | ||
1345 | * in wl->fem_manuf. No need to continue further | ||
1346 | */ | ||
1347 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
1348 | goto out; | ||
1349 | |||
1342 | ret = wl128x_cmd_radio_parms(wl); | 1350 | ret = wl128x_cmd_radio_parms(wl); |
1343 | if (ret < 0) | 1351 | if (ret < 0) |
1344 | goto out; | 1352 | goto out; |
@@ -1355,6 +1363,14 @@ static int wl12xx_hw_init(struct wl1271 *wl) | |||
1355 | ret = wl1271_cmd_general_parms(wl); | 1363 | ret = wl1271_cmd_general_parms(wl); |
1356 | if (ret < 0) | 1364 | if (ret < 0) |
1357 | goto out; | 1365 | goto out; |
1366 | |||
1367 | /* | ||
1368 | * If we are in calibrator based auto detect then we got the FEM nr | ||
1369 | * in wl->fem_manuf. No need to continue further | ||
1370 | */ | ||
1371 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
1372 | goto out; | ||
1373 | |||
1358 | ret = wl1271_cmd_radio_parms(wl); | 1374 | ret = wl1271_cmd_radio_parms(wl); |
1359 | if (ret < 0) | 1375 | if (ret < 0) |
1360 | goto out; | 1376 | goto out; |
@@ -1500,6 +1516,13 @@ static int wl12xx_plt_init(struct wl1271 *wl) | |||
1500 | if (ret < 0) | 1516 | if (ret < 0) |
1501 | goto out_irq_disable; | 1517 | goto out_irq_disable; |
1502 | 1518 | ||
1519 | /* | ||
1520 | * If we are in calibrator based auto detect then we got the FEM nr | ||
1521 | * in wl->fem_manuf. No need to continue further | ||
1522 | */ | ||
1523 | if (wl->plt_mode == PLT_FEM_DETECT) | ||
1524 | goto out; | ||
1525 | |||
1503 | ret = wl1271_acx_init_mem_config(wl); | 1526 | ret = wl1271_acx_init_mem_config(wl); |
1504 | if (ret < 0) | 1527 | if (ret < 0) |
1505 | goto out_irq_disable; | 1528 | goto out_irq_disable; |
diff --git a/drivers/net/wireless/ti/wl18xx/conf.h b/drivers/net/wireless/ti/wl18xx/conf.h index fac0b7e87e75..4d426cc20274 100644 --- a/drivers/net/wireless/ti/wl18xx/conf.h +++ b/drivers/net/wireless/ti/wl18xx/conf.h | |||
@@ -23,7 +23,7 @@ | |||
23 | #define __WL18XX_CONF_H__ | 23 | #define __WL18XX_CONF_H__ |
24 | 24 | ||
25 | #define WL18XX_CONF_MAGIC 0x10e100ca | 25 | #define WL18XX_CONF_MAGIC 0x10e100ca |
26 | #define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0002) | 26 | #define WL18XX_CONF_VERSION (WLCORE_CONF_VERSION | 0x0003) |
27 | #define WL18XX_CONF_MASK 0x0000ffff | 27 | #define WL18XX_CONF_MASK 0x0000ffff |
28 | #define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ | 28 | #define WL18XX_CONF_SIZE (WLCORE_CONF_SIZE + \ |
29 | sizeof(struct wl18xx_priv_conf)) | 29 | sizeof(struct wl18xx_priv_conf)) |
@@ -84,7 +84,26 @@ struct wl18xx_mac_and_phy_params { | |||
84 | u8 padding[1]; | 84 | u8 padding[1]; |
85 | } __packed; | 85 | } __packed; |
86 | 86 | ||
87 | enum wl18xx_ht_mode { | ||
88 | /* Default - use MIMO, fallback to SISO20 */ | ||
89 | HT_MODE_DEFAULT = 0, | ||
90 | |||
91 | /* Wide - use SISO40 */ | ||
92 | HT_MODE_WIDE = 1, | ||
93 | |||
94 | /* Use SISO20 */ | ||
95 | HT_MODE_SISO20 = 2, | ||
96 | }; | ||
97 | |||
98 | struct wl18xx_ht_settings { | ||
99 | /* DEFAULT / WIDE / SISO20 */ | ||
100 | u8 mode; | ||
101 | } __packed; | ||
102 | |||
87 | struct wl18xx_priv_conf { | 103 | struct wl18xx_priv_conf { |
104 | /* Module params structures */ | ||
105 | struct wl18xx_ht_settings ht; | ||
106 | |||
88 | /* this structure is copied wholesale to FW */ | 107 | /* this structure is copied wholesale to FW */ |
89 | struct wl18xx_mac_and_phy_params phy; | 108 | struct wl18xx_mac_and_phy_params phy; |
90 | } __packed; | 109 | } __packed; |
diff --git a/drivers/net/wireless/ti/wl18xx/io.c b/drivers/net/wireless/ti/wl18xx/io.c index 0c06ccfd1b8c..f0abf3ef2c95 100644 --- a/drivers/net/wireless/ti/wl18xx/io.c +++ b/drivers/net/wireless/ti/wl18xx/io.c | |||
@@ -54,7 +54,7 @@ out: | |||
54 | 54 | ||
55 | int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) | 55 | int wl18xx_top_reg_read(struct wl1271 *wl, int addr, u16 *out) |
56 | { | 56 | { |
57 | u32 val; | 57 | u32 val = 0; |
58 | int ret; | 58 | int ret; |
59 | 59 | ||
60 | if (WARN_ON(addr % 2)) | 60 | if (WARN_ON(addr % 2)) |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b378b34c4a6a..69042bb9a097 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -43,8 +43,8 @@ | |||
43 | 43 | ||
44 | #define WL18XX_RX_CHECKSUM_MASK 0x40 | 44 | #define WL18XX_RX_CHECKSUM_MASK 0x40 |
45 | 45 | ||
46 | static char *ht_mode_param = "default"; | 46 | static char *ht_mode_param = NULL; |
47 | static char *board_type_param = "hdk"; | 47 | static char *board_type_param = NULL; |
48 | static bool checksum_param = false; | 48 | static bool checksum_param = false; |
49 | static bool enable_11a_param = true; | 49 | static bool enable_11a_param = true; |
50 | static int num_rx_desc_param = -1; | 50 | static int num_rx_desc_param = -1; |
@@ -494,16 +494,20 @@ static struct wlcore_conf wl18xx_conf = { | |||
494 | }; | 494 | }; |
495 | 495 | ||
496 | static struct wl18xx_priv_conf wl18xx_default_priv_conf = { | 496 | static struct wl18xx_priv_conf wl18xx_default_priv_conf = { |
497 | .ht = { | ||
498 | .mode = HT_MODE_DEFAULT, | ||
499 | }, | ||
497 | .phy = { | 500 | .phy = { |
498 | .phy_standalone = 0x00, | 501 | .phy_standalone = 0x00, |
499 | .primary_clock_setting_time = 0x05, | 502 | .primary_clock_setting_time = 0x05, |
500 | .clock_valid_on_wake_up = 0x00, | 503 | .clock_valid_on_wake_up = 0x00, |
501 | .secondary_clock_setting_time = 0x05, | 504 | .secondary_clock_setting_time = 0x05, |
505 | .board_type = BOARD_TYPE_HDK_18XX, | ||
502 | .rdl = 0x01, | 506 | .rdl = 0x01, |
503 | .auto_detect = 0x00, | 507 | .auto_detect = 0x00, |
504 | .dedicated_fem = FEM_NONE, | 508 | .dedicated_fem = FEM_NONE, |
505 | .low_band_component = COMPONENT_2_WAY_SWITCH, | 509 | .low_band_component = COMPONENT_2_WAY_SWITCH, |
506 | .low_band_component_type = 0x05, | 510 | .low_band_component_type = 0x06, |
507 | .high_band_component = COMPONENT_2_WAY_SWITCH, | 511 | .high_band_component = COMPONENT_2_WAY_SWITCH, |
508 | .high_band_component_type = 0x09, | 512 | .high_band_component_type = 0x09, |
509 | .tcxo_ldo_voltage = 0x00, | 513 | .tcxo_ldo_voltage = 0x00, |
@@ -772,16 +776,24 @@ out: | |||
772 | static int wl18xx_set_mac_and_phy(struct wl1271 *wl) | 776 | static int wl18xx_set_mac_and_phy(struct wl1271 *wl) |
773 | { | 777 | { |
774 | struct wl18xx_priv *priv = wl->priv; | 778 | struct wl18xx_priv *priv = wl->priv; |
779 | struct wl18xx_mac_and_phy_params *params; | ||
775 | int ret; | 780 | int ret; |
776 | 781 | ||
782 | params = kmemdup(&priv->conf.phy, sizeof(*params), GFP_KERNEL); | ||
783 | if (!params) { | ||
784 | ret = -ENOMEM; | ||
785 | goto out; | ||
786 | } | ||
787 | |||
777 | ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); | 788 | ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); |
778 | if (ret < 0) | 789 | if (ret < 0) |
779 | goto out; | 790 | goto out; |
780 | 791 | ||
781 | ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, | 792 | ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, params, |
782 | sizeof(struct wl18xx_mac_and_phy_params), false); | 793 | sizeof(*params), false); |
783 | 794 | ||
784 | out: | 795 | out: |
796 | kfree(params); | ||
785 | return ret; | 797 | return ret; |
786 | } | 798 | } |
787 | 799 | ||
@@ -1001,6 +1013,13 @@ static void wl18xx_set_rx_csum(struct wl1271 *wl, | |||
1001 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1013 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1002 | } | 1014 | } |
1003 | 1015 | ||
1016 | static bool wl18xx_is_mimo_supported(struct wl1271 *wl) | ||
1017 | { | ||
1018 | struct wl18xx_priv *priv = wl->priv; | ||
1019 | |||
1020 | return priv->conf.phy.number_of_assembled_ant2_4 >= 2; | ||
1021 | } | ||
1022 | |||
1004 | /* | 1023 | /* |
1005 | * TODO: instead of having these two functions to get the rate mask, | 1024 | * TODO: instead of having these two functions to get the rate mask, |
1006 | * we should modify the wlvif->rate_set instead | 1025 | * we should modify the wlvif->rate_set instead |
@@ -1017,6 +1036,9 @@ static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, | |||
1017 | 1036 | ||
1018 | /* we don't support MIMO in wide-channel mode */ | 1037 | /* we don't support MIMO in wide-channel mode */ |
1019 | hw_rate_set &= ~CONF_TX_MIMO_RATES; | 1038 | hw_rate_set &= ~CONF_TX_MIMO_RATES; |
1039 | } else if (wl18xx_is_mimo_supported(wl)) { | ||
1040 | wl1271_debug(DEBUG_ACX, "using MIMO channel rate mask"); | ||
1041 | hw_rate_set |= CONF_TX_MIMO_RATES; | ||
1020 | } | 1042 | } |
1021 | 1043 | ||
1022 | return hw_rate_set; | 1044 | return hw_rate_set; |
@@ -1025,8 +1047,6 @@ static u32 wl18xx_sta_get_ap_rate_mask(struct wl1271 *wl, | |||
1025 | static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, | 1047 | static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, |
1026 | struct wl12xx_vif *wlvif) | 1048 | struct wl12xx_vif *wlvif) |
1027 | { | 1049 | { |
1028 | struct wl18xx_priv *priv = wl->priv; | ||
1029 | |||
1030 | if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || | 1050 | if (wlvif->channel_type == NL80211_CHAN_HT40MINUS || |
1031 | wlvif->channel_type == NL80211_CHAN_HT40PLUS) { | 1051 | wlvif->channel_type == NL80211_CHAN_HT40PLUS) { |
1032 | wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); | 1052 | wl1271_debug(DEBUG_ACX, "using wide channel rate mask"); |
@@ -1036,7 +1056,7 @@ static u32 wl18xx_ap_get_mimo_wide_rate_mask(struct wl1271 *wl, | |||
1036 | return 0; | 1056 | return 0; |
1037 | 1057 | ||
1038 | return CONF_TX_RATE_USE_WIDE_CHAN; | 1058 | return CONF_TX_RATE_USE_WIDE_CHAN; |
1039 | } else if (priv->conf.phy.number_of_assembled_ant2_4 >= 2 && | 1059 | } else if (wl18xx_is_mimo_supported(wl) && |
1040 | wlvif->band == IEEE80211_BAND_2GHZ) { | 1060 | wlvif->band == IEEE80211_BAND_2GHZ) { |
1041 | wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); | 1061 | wl1271_debug(DEBUG_ACX, "using MIMO rate mask"); |
1042 | /* | 1062 | /* |
@@ -1136,6 +1156,12 @@ static int wl18xx_plt_init(struct wl1271 *wl) | |||
1136 | { | 1156 | { |
1137 | int ret; | 1157 | int ret; |
1138 | 1158 | ||
1159 | /* calibrator based auto/fem detect not supported for 18xx */ | ||
1160 | if (wl->plt_mode == PLT_FEM_DETECT) { | ||
1161 | wl1271_error("wl18xx_plt_init: PLT FEM_DETECT not supported"); | ||
1162 | return -EINVAL; | ||
1163 | } | ||
1164 | |||
1139 | ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); | 1165 | ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); |
1140 | if (ret < 0) | 1166 | if (ret < 0) |
1141 | return ret; | 1167 | return ret; |
@@ -1383,27 +1409,44 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1383 | if (ret < 0) | 1409 | if (ret < 0) |
1384 | goto out_free; | 1410 | goto out_free; |
1385 | 1411 | ||
1386 | if (!strcmp(board_type_param, "fpga")) { | 1412 | /* If the module param is set, update it in conf */ |
1387 | priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX; | 1413 | if (board_type_param) { |
1388 | } else if (!strcmp(board_type_param, "hdk")) { | 1414 | if (!strcmp(board_type_param, "fpga")) { |
1389 | priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX; | 1415 | priv->conf.phy.board_type = BOARD_TYPE_FPGA_18XX; |
1390 | /* HACK! Just for now we hardcode HDK to 0x06 */ | 1416 | } else if (!strcmp(board_type_param, "hdk")) { |
1391 | priv->conf.phy.low_band_component_type = 0x06; | 1417 | priv->conf.phy.board_type = BOARD_TYPE_HDK_18XX; |
1392 | } else if (!strcmp(board_type_param, "dvp")) { | 1418 | } else if (!strcmp(board_type_param, "dvp")) { |
1393 | priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX; | 1419 | priv->conf.phy.board_type = BOARD_TYPE_DVP_18XX; |
1394 | } else if (!strcmp(board_type_param, "evb")) { | 1420 | } else if (!strcmp(board_type_param, "evb")) { |
1395 | priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX; | 1421 | priv->conf.phy.board_type = BOARD_TYPE_EVB_18XX; |
1396 | } else if (!strcmp(board_type_param, "com8")) { | 1422 | } else if (!strcmp(board_type_param, "com8")) { |
1397 | priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX; | 1423 | priv->conf.phy.board_type = BOARD_TYPE_COM8_18XX; |
1398 | /* HACK! Just for now we hardcode COM8 to 0x06 */ | 1424 | } else { |
1425 | wl1271_error("invalid board type '%s'", | ||
1426 | board_type_param); | ||
1427 | ret = -EINVAL; | ||
1428 | goto out_free; | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1432 | /* HACK! Just for now we hardcode COM8 and HDK to 0x06 */ | ||
1433 | switch (priv->conf.phy.board_type) { | ||
1434 | case BOARD_TYPE_HDK_18XX: | ||
1435 | case BOARD_TYPE_COM8_18XX: | ||
1399 | priv->conf.phy.low_band_component_type = 0x06; | 1436 | priv->conf.phy.low_band_component_type = 0x06; |
1400 | } else { | 1437 | break; |
1401 | wl1271_error("invalid board type '%s'", board_type_param); | 1438 | case BOARD_TYPE_FPGA_18XX: |
1439 | case BOARD_TYPE_DVP_18XX: | ||
1440 | case BOARD_TYPE_EVB_18XX: | ||
1441 | priv->conf.phy.low_band_component_type = 0x05; | ||
1442 | break; | ||
1443 | default: | ||
1444 | wl1271_error("invalid board type '%d'", | ||
1445 | priv->conf.phy.board_type); | ||
1402 | ret = -EINVAL; | 1446 | ret = -EINVAL; |
1403 | goto out_free; | 1447 | goto out_free; |
1404 | } | 1448 | } |
1405 | 1449 | ||
1406 | /* If the module param is set, update it in conf */ | ||
1407 | if (low_band_component_param != -1) | 1450 | if (low_band_component_param != -1) |
1408 | priv->conf.phy.low_band_component = low_band_component_param; | 1451 | priv->conf.phy.low_band_component = low_band_component_param; |
1409 | if (low_band_component_type_param != -1) | 1452 | if (low_band_component_type_param != -1) |
@@ -1424,12 +1467,26 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1424 | if (dc2dc_param != -1) | 1467 | if (dc2dc_param != -1) |
1425 | priv->conf.phy.external_pa_dc2dc = dc2dc_param; | 1468 | priv->conf.phy.external_pa_dc2dc = dc2dc_param; |
1426 | 1469 | ||
1427 | if (!strcmp(ht_mode_param, "default")) { | 1470 | if (ht_mode_param) { |
1471 | if (!strcmp(ht_mode_param, "default")) | ||
1472 | priv->conf.ht.mode = HT_MODE_DEFAULT; | ||
1473 | else if (!strcmp(ht_mode_param, "wide")) | ||
1474 | priv->conf.ht.mode = HT_MODE_WIDE; | ||
1475 | else if (!strcmp(ht_mode_param, "siso20")) | ||
1476 | priv->conf.ht.mode = HT_MODE_SISO20; | ||
1477 | else { | ||
1478 | wl1271_error("invalid ht_mode '%s'", ht_mode_param); | ||
1479 | ret = -EINVAL; | ||
1480 | goto out_free; | ||
1481 | } | ||
1482 | } | ||
1483 | |||
1484 | if (priv->conf.ht.mode == HT_MODE_DEFAULT) { | ||
1428 | /* | 1485 | /* |
1429 | * Only support mimo with multiple antennas. Fall back to | 1486 | * Only support mimo with multiple antennas. Fall back to |
1430 | * siso20. | 1487 | * siso20. |
1431 | */ | 1488 | */ |
1432 | if (priv->conf.phy.number_of_assembled_ant2_4 >= 2) | 1489 | if (wl18xx_is_mimo_supported(wl)) |
1433 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, | 1490 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, |
1434 | &wl18xx_mimo_ht_cap_2ghz); | 1491 | &wl18xx_mimo_ht_cap_2ghz); |
1435 | else | 1492 | else |
@@ -1439,20 +1496,16 @@ static int __devinit wl18xx_probe(struct platform_device *pdev) | |||
1439 | /* 5Ghz is always wide */ | 1496 | /* 5Ghz is always wide */ |
1440 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, | 1497 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, |
1441 | &wl18xx_siso40_ht_cap_5ghz); | 1498 | &wl18xx_siso40_ht_cap_5ghz); |
1442 | } else if (!strcmp(ht_mode_param, "wide")) { | 1499 | } else if (priv->conf.ht.mode == HT_MODE_WIDE) { |
1443 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, | 1500 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, |
1444 | &wl18xx_siso40_ht_cap_2ghz); | 1501 | &wl18xx_siso40_ht_cap_2ghz); |
1445 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, | 1502 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, |
1446 | &wl18xx_siso40_ht_cap_5ghz); | 1503 | &wl18xx_siso40_ht_cap_5ghz); |
1447 | } else if (!strcmp(ht_mode_param, "siso20")) { | 1504 | } else if (priv->conf.ht.mode == HT_MODE_SISO20) { |
1448 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, | 1505 | wlcore_set_ht_cap(wl, IEEE80211_BAND_2GHZ, |
1449 | &wl18xx_siso20_ht_cap); | 1506 | &wl18xx_siso20_ht_cap); |
1450 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, | 1507 | wlcore_set_ht_cap(wl, IEEE80211_BAND_5GHZ, |
1451 | &wl18xx_siso20_ht_cap); | 1508 | &wl18xx_siso20_ht_cap); |
1452 | } else { | ||
1453 | wl1271_error("invalid ht_mode '%s'", ht_mode_param); | ||
1454 | ret = -EINVAL; | ||
1455 | goto out_free; | ||
1456 | } | 1509 | } |
1457 | 1510 | ||
1458 | if (!checksum_param) { | 1511 | if (!checksum_param) { |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.c b/drivers/net/wireless/ti/wlcore/cmd.c index a23949cdaebc..20e1bd923832 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.c +++ b/drivers/net/wireless/ti/wlcore/cmd.c | |||
@@ -497,6 +497,7 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
497 | { | 497 | { |
498 | struct wl12xx_cmd_role_stop *cmd; | 498 | struct wl12xx_cmd_role_stop *cmd; |
499 | int ret; | 499 | int ret; |
500 | bool timeout = false; | ||
500 | 501 | ||
501 | if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) | 502 | if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)) |
502 | return -EINVAL; | 503 | return -EINVAL; |
@@ -519,6 +520,17 @@ int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif) | |||
519 | goto out_free; | 520 | goto out_free; |
520 | } | 521 | } |
521 | 522 | ||
523 | /* | ||
524 | * Sometimes the firmware doesn't send this event, so we just | ||
525 | * time out without failing. Queue recovery for other | ||
526 | * failures. | ||
527 | */ | ||
528 | ret = wl1271_cmd_wait_for_event_or_timeout(wl, | ||
529 | ROLE_STOP_COMPLETE_EVENT_ID, | ||
530 | &timeout); | ||
531 | if (ret) | ||
532 | wl12xx_queue_recovery_work(wl); | ||
533 | |||
522 | wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); | 534 | wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid); |
523 | 535 | ||
524 | out_free: | 536 | out_free: |
diff --git a/drivers/net/wireless/ti/wlcore/cmd.h b/drivers/net/wireless/ti/wlcore/cmd.h index d7d9f801e506..4ef0b095f0d6 100644 --- a/drivers/net/wireless/ti/wlcore/cmd.h +++ b/drivers/net/wireless/ti/wlcore/cmd.h | |||
@@ -192,7 +192,7 @@ enum cmd_templ { | |||
192 | #define WL1271_COMMAND_TIMEOUT 2000 | 192 | #define WL1271_COMMAND_TIMEOUT 2000 |
193 | #define WL1271_CMD_TEMPL_DFLT_SIZE 252 | 193 | #define WL1271_CMD_TEMPL_DFLT_SIZE 252 |
194 | #define WL1271_CMD_TEMPL_MAX_SIZE 512 | 194 | #define WL1271_CMD_TEMPL_MAX_SIZE 512 |
195 | #define WL1271_EVENT_TIMEOUT 1000 | 195 | #define WL1271_EVENT_TIMEOUT 1500 |
196 | 196 | ||
197 | struct wl1271_cmd_header { | 197 | struct wl1271_cmd_header { |
198 | __le16 id; | 198 | __le16 id; |
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c index 9f04b64dfa33..72548609f711 100644 --- a/drivers/net/wireless/ti/wlcore/main.c +++ b/drivers/net/wireless/ti/wlcore/main.c | |||
@@ -1064,10 +1064,17 @@ out: | |||
1064 | return ret; | 1064 | return ret; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | int wl1271_plt_start(struct wl1271 *wl) | 1067 | int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode) |
1068 | { | 1068 | { |
1069 | int retries = WL1271_BOOT_RETRIES; | 1069 | int retries = WL1271_BOOT_RETRIES; |
1070 | struct wiphy *wiphy = wl->hw->wiphy; | 1070 | struct wiphy *wiphy = wl->hw->wiphy; |
1071 | |||
1072 | static const char* const PLT_MODE[] = { | ||
1073 | "PLT_OFF", | ||
1074 | "PLT_ON", | ||
1075 | "PLT_FEM_DETECT" | ||
1076 | }; | ||
1077 | |||
1071 | int ret; | 1078 | int ret; |
1072 | 1079 | ||
1073 | mutex_lock(&wl->mutex); | 1080 | mutex_lock(&wl->mutex); |
@@ -1081,6 +1088,10 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1081 | goto out; | 1088 | goto out; |
1082 | } | 1089 | } |
1083 | 1090 | ||
1091 | /* Indicate to lower levels that we are now in PLT mode */ | ||
1092 | wl->plt = true; | ||
1093 | wl->plt_mode = plt_mode; | ||
1094 | |||
1084 | while (retries) { | 1095 | while (retries) { |
1085 | retries--; | 1096 | retries--; |
1086 | ret = wl12xx_chip_wakeup(wl, true); | 1097 | ret = wl12xx_chip_wakeup(wl, true); |
@@ -1091,9 +1102,9 @@ int wl1271_plt_start(struct wl1271 *wl) | |||
1091 | if (ret < 0) | 1102 | if (ret < 0) |
1092 | goto power_off; | 1103 | goto power_off; |
1093 | 1104 | ||
1094 | wl->plt = true; | ||
1095 | wl->state = WL1271_STATE_ON; | 1105 | wl->state = WL1271_STATE_ON; |
1096 | wl1271_notice("firmware booted in PLT mode (%s)", | 1106 | wl1271_notice("firmware booted in PLT mode %s (%s)", |
1107 | PLT_MODE[plt_mode], | ||
1097 | wl->chip.fw_ver_str); | 1108 | wl->chip.fw_ver_str); |
1098 | 1109 | ||
1099 | /* update hw/fw version info in wiphy struct */ | 1110 | /* update hw/fw version info in wiphy struct */ |
@@ -1107,6 +1118,9 @@ power_off: | |||
1107 | wl1271_power_off(wl); | 1118 | wl1271_power_off(wl); |
1108 | } | 1119 | } |
1109 | 1120 | ||
1121 | wl->plt = false; | ||
1122 | wl->plt_mode = PLT_OFF; | ||
1123 | |||
1110 | wl1271_error("firmware boot in PLT mode failed despite %d retries", | 1124 | wl1271_error("firmware boot in PLT mode failed despite %d retries", |
1111 | WL1271_BOOT_RETRIES); | 1125 | WL1271_BOOT_RETRIES); |
1112 | out: | 1126 | out: |
@@ -1159,6 +1173,7 @@ int wl1271_plt_stop(struct wl1271 *wl) | |||
1159 | wl->sleep_auth = WL1271_PSM_ILLEGAL; | 1173 | wl->sleep_auth = WL1271_PSM_ILLEGAL; |
1160 | wl->state = WL1271_STATE_OFF; | 1174 | wl->state = WL1271_STATE_OFF; |
1161 | wl->plt = false; | 1175 | wl->plt = false; |
1176 | wl->plt_mode = PLT_OFF; | ||
1162 | wl->rx_counter = 0; | 1177 | wl->rx_counter = 0; |
1163 | mutex_unlock(&wl->mutex); | 1178 | mutex_unlock(&wl->mutex); |
1164 | 1179 | ||
@@ -1585,6 +1600,12 @@ static int wl1271_configure_suspend_sta(struct wl1271 *wl, | |||
1585 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) | 1600 | if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) |
1586 | goto out; | 1601 | goto out; |
1587 | 1602 | ||
1603 | if ((wl->conf.conn.suspend_wake_up_event == | ||
1604 | wl->conf.conn.wake_up_event) && | ||
1605 | (wl->conf.conn.suspend_listen_interval == | ||
1606 | wl->conf.conn.listen_interval)) | ||
1607 | goto out; | ||
1608 | |||
1588 | ret = wl1271_ps_elp_wakeup(wl); | 1609 | ret = wl1271_ps_elp_wakeup(wl); |
1589 | if (ret < 0) | 1610 | if (ret < 0) |
1590 | goto out; | 1611 | goto out; |
@@ -1648,6 +1669,13 @@ static void wl1271_configure_resume(struct wl1271 *wl, | |||
1648 | if ((!is_ap) && (!is_sta)) | 1669 | if ((!is_ap) && (!is_sta)) |
1649 | return; | 1670 | return; |
1650 | 1671 | ||
1672 | if (is_sta && | ||
1673 | ((wl->conf.conn.suspend_wake_up_event == | ||
1674 | wl->conf.conn.wake_up_event) && | ||
1675 | (wl->conf.conn.suspend_listen_interval == | ||
1676 | wl->conf.conn.listen_interval))) | ||
1677 | return; | ||
1678 | |||
1651 | ret = wl1271_ps_elp_wakeup(wl); | 1679 | ret = wl1271_ps_elp_wakeup(wl); |
1652 | if (ret < 0) | 1680 | if (ret < 0) |
1653 | return; | 1681 | return; |
@@ -2364,7 +2392,14 @@ deinit: | |||
2364 | else | 2392 | else |
2365 | wl->sta_count--; | 2393 | wl->sta_count--; |
2366 | 2394 | ||
2367 | /* Last AP, have more stations. Configure according to STA. */ | 2395 | /* |
2396 | * Last AP, have more stations. Configure sleep auth according to STA. | ||
2397 | * Don't do thin on unintended recovery. | ||
2398 | */ | ||
2399 | if (test_bit(WL1271_FLAG_RECOVERY_IN_PROGRESS, &wl->flags) && | ||
2400 | !test_bit(WL1271_FLAG_INTENDED_FW_RECOVERY, &wl->flags)) | ||
2401 | goto unlock; | ||
2402 | |||
2368 | if (wl->ap_count == 0 && is_ap && wl->sta_count) { | 2403 | if (wl->ap_count == 0 && is_ap && wl->sta_count) { |
2369 | u8 sta_auth = wl->conf.conn.sta_sleep_auth; | 2404 | u8 sta_auth = wl->conf.conn.sta_sleep_auth; |
2370 | /* Configure for power according to debugfs */ | 2405 | /* Configure for power according to debugfs */ |
@@ -2378,6 +2413,7 @@ deinit: | |||
2378 | wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); | 2413 | wl1271_acx_sleep_auth(wl, WL1271_PSM_ELP); |
2379 | } | 2414 | } |
2380 | 2415 | ||
2416 | unlock: | ||
2381 | mutex_unlock(&wl->mutex); | 2417 | mutex_unlock(&wl->mutex); |
2382 | 2418 | ||
2383 | del_timer_sync(&wlvif->rx_streaming_timer); | 2419 | del_timer_sync(&wlvif->rx_streaming_timer); |
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c index d6f57e2c03cf..49e5ee1525c9 100644 --- a/drivers/net/wireless/ti/wlcore/testmode.c +++ b/drivers/net/wireless/ti/wlcore/testmode.c | |||
@@ -129,8 +129,12 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[]) | |||
129 | goto out_sleep; | 129 | goto out_sleep; |
130 | } | 130 | } |
131 | 131 | ||
132 | if (nla_put(skb, WL1271_TM_ATTR_DATA, buf_len, buf)) | 132 | if (nla_put(skb, WL1271_TM_ATTR_DATA, buf_len, buf)) { |
133 | goto nla_put_failure; | 133 | kfree_skb(skb); |
134 | ret = -EMSGSIZE; | ||
135 | goto out_sleep; | ||
136 | } | ||
137 | |||
134 | ret = cfg80211_testmode_reply(skb); | 138 | ret = cfg80211_testmode_reply(skb); |
135 | if (ret < 0) | 139 | if (ret < 0) |
136 | goto out_sleep; | 140 | goto out_sleep; |
@@ -142,11 +146,6 @@ out: | |||
142 | mutex_unlock(&wl->mutex); | 146 | mutex_unlock(&wl->mutex); |
143 | 147 | ||
144 | return ret; | 148 | return ret; |
145 | |||
146 | nla_put_failure: | ||
147 | kfree_skb(skb); | ||
148 | ret = -EMSGSIZE; | ||
149 | goto out_sleep; | ||
150 | } | 149 | } |
151 | 150 | ||
152 | static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) | 151 | static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) |
@@ -192,8 +191,12 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) | |||
192 | goto out_free; | 191 | goto out_free; |
193 | } | 192 | } |
194 | 193 | ||
195 | if (nla_put(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd)) | 194 | if (nla_put(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd)) { |
196 | goto nla_put_failure; | 195 | kfree_skb(skb); |
196 | ret = -EMSGSIZE; | ||
197 | goto out_free; | ||
198 | } | ||
199 | |||
197 | ret = cfg80211_testmode_reply(skb); | 200 | ret = cfg80211_testmode_reply(skb); |
198 | if (ret < 0) | 201 | if (ret < 0) |
199 | goto out_free; | 202 | goto out_free; |
@@ -206,11 +209,6 @@ out: | |||
206 | mutex_unlock(&wl->mutex); | 209 | mutex_unlock(&wl->mutex); |
207 | 210 | ||
208 | return ret; | 211 | return ret; |
209 | |||
210 | nla_put_failure: | ||
211 | kfree_skb(skb); | ||
212 | ret = -EMSGSIZE; | ||
213 | goto out_free; | ||
214 | } | 212 | } |
215 | 213 | ||
216 | static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) | 214 | static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) |
@@ -245,6 +243,43 @@ static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) | |||
245 | return 0; | 243 | return 0; |
246 | } | 244 | } |
247 | 245 | ||
246 | static int wl1271_tm_detect_fem(struct wl1271 *wl, struct nlattr *tb[]) | ||
247 | { | ||
248 | /* return FEM type */ | ||
249 | int ret, len; | ||
250 | struct sk_buff *skb; | ||
251 | |||
252 | ret = wl1271_plt_start(wl, PLT_FEM_DETECT); | ||
253 | if (ret < 0) | ||
254 | goto out; | ||
255 | |||
256 | mutex_lock(&wl->mutex); | ||
257 | |||
258 | len = nla_total_size(sizeof(wl->fem_manuf)); | ||
259 | skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); | ||
260 | if (!skb) { | ||
261 | ret = -ENOMEM; | ||
262 | goto out_mutex; | ||
263 | } | ||
264 | |||
265 | if (nla_put(skb, WL1271_TM_ATTR_DATA, sizeof(wl->fem_manuf), | ||
266 | &wl->fem_manuf)) { | ||
267 | kfree_skb(skb); | ||
268 | ret = -EMSGSIZE; | ||
269 | goto out_mutex; | ||
270 | } | ||
271 | |||
272 | ret = cfg80211_testmode_reply(skb); | ||
273 | |||
274 | out_mutex: | ||
275 | mutex_unlock(&wl->mutex); | ||
276 | |||
277 | /* We always stop plt after DETECT mode */ | ||
278 | wl1271_plt_stop(wl); | ||
279 | out: | ||
280 | return ret; | ||
281 | } | ||
282 | |||
248 | static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) | 283 | static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) |
249 | { | 284 | { |
250 | u32 val; | 285 | u32 val; |
@@ -258,11 +293,14 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[]) | |||
258 | val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]); | 293 | val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]); |
259 | 294 | ||
260 | switch (val) { | 295 | switch (val) { |
261 | case 0: | 296 | case PLT_OFF: |
262 | ret = wl1271_plt_stop(wl); | 297 | ret = wl1271_plt_stop(wl); |
263 | break; | 298 | break; |
264 | case 1: | 299 | case PLT_ON: |
265 | ret = wl1271_plt_start(wl); | 300 | ret = wl1271_plt_start(wl, PLT_ON); |
301 | break; | ||
302 | case PLT_FEM_DETECT: | ||
303 | ret = wl1271_tm_detect_fem(wl, tb); | ||
266 | break; | 304 | break; |
267 | default: | 305 | default: |
268 | ret = -EINVAL; | 306 | ret = -EINVAL; |
@@ -303,8 +341,12 @@ static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[]) | |||
303 | goto out; | 341 | goto out; |
304 | } | 342 | } |
305 | 343 | ||
306 | if (nla_put(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr)) | 344 | if (nla_put(skb, WL1271_TM_ATTR_DATA, ETH_ALEN, mac_addr)) { |
307 | goto nla_put_failure; | 345 | kfree_skb(skb); |
346 | ret = -EMSGSIZE; | ||
347 | goto out; | ||
348 | } | ||
349 | |||
308 | ret = cfg80211_testmode_reply(skb); | 350 | ret = cfg80211_testmode_reply(skb); |
309 | if (ret < 0) | 351 | if (ret < 0) |
310 | goto out; | 352 | goto out; |
@@ -312,11 +354,6 @@ static int wl12xx_tm_cmd_get_mac(struct wl1271 *wl, struct nlattr *tb[]) | |||
312 | out: | 354 | out: |
313 | mutex_unlock(&wl->mutex); | 355 | mutex_unlock(&wl->mutex); |
314 | return ret; | 356 | return ret; |
315 | |||
316 | nla_put_failure: | ||
317 | kfree_skb(skb); | ||
318 | ret = -EMSGSIZE; | ||
319 | goto out; | ||
320 | } | 357 | } |
321 | 358 | ||
322 | int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) | 359 | int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len) |
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c index 8038a5026933..f0081f746482 100644 --- a/drivers/net/wireless/ti/wlcore/tx.c +++ b/drivers/net/wireless/ti/wlcore/tx.c | |||
@@ -306,22 +306,24 @@ static void wl1271_tx_fill_hdr(struct wl1271 *wl, struct wl12xx_vif *wlvif, | |||
306 | rate_idx = 0; | 306 | rate_idx = 0; |
307 | else if (wlvif->bss_type != BSS_TYPE_AP_BSS) { | 307 | else if (wlvif->bss_type != BSS_TYPE_AP_BSS) { |
308 | /* | 308 | /* |
309 | * if the packets are destined for AP (have a STA entry) | 309 | * if the packets are data packets |
310 | * send them with AP rate policies (EAPOLs are an exception), | 310 | * send them with AP rate policies (EAPOLs are an exception), |
311 | * otherwise use default basic rates | 311 | * otherwise use default basic rates |
312 | */ | 312 | */ |
313 | if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE) | 313 | if (skb->protocol == cpu_to_be16(ETH_P_PAE)) |
314 | rate_idx = wlvif->sta.p2p_rate_idx; | ||
315 | else if (skb->protocol == cpu_to_be16(ETH_P_PAE)) | ||
316 | rate_idx = wlvif->sta.basic_rate_idx; | 314 | rate_idx = wlvif->sta.basic_rate_idx; |
317 | else if (control->control.sta) | 315 | else if (control->flags & IEEE80211_TX_CTL_NO_CCK_RATE) |
316 | rate_idx = wlvif->sta.p2p_rate_idx; | ||
317 | else if (ieee80211_is_data(frame_control)) | ||
318 | rate_idx = wlvif->sta.ap_rate_idx; | 318 | rate_idx = wlvif->sta.ap_rate_idx; |
319 | else | 319 | else |
320 | rate_idx = wlvif->sta.basic_rate_idx; | 320 | rate_idx = wlvif->sta.basic_rate_idx; |
321 | } else { | 321 | } else { |
322 | if (hlid == wlvif->ap.global_hlid) | 322 | if (hlid == wlvif->ap.global_hlid) |
323 | rate_idx = wlvif->ap.mgmt_rate_idx; | 323 | rate_idx = wlvif->ap.mgmt_rate_idx; |
324 | else if (hlid == wlvif->ap.bcast_hlid) | 324 | else if (hlid == wlvif->ap.bcast_hlid || |
325 | skb->protocol == cpu_to_be16(ETH_P_PAE)) | ||
326 | /* send AP bcast and EAPOLs using the min basic rate */ | ||
325 | rate_idx = wlvif->ap.bcast_rate_idx; | 327 | rate_idx = wlvif->ap.bcast_rate_idx; |
326 | else | 328 | else |
327 | rate_idx = wlvif->ap.ucast_rate_idx[ac]; | 329 | rate_idx = wlvif->ap.ucast_rate_idx[ac]; |
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h index 27ccc275a1c1..0ce7a8ebbd46 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore.h +++ b/drivers/net/wireless/ti/wlcore/wlcore.h | |||
@@ -156,6 +156,8 @@ struct wl1271 { | |||
156 | enum wl1271_state state; | 156 | enum wl1271_state state; |
157 | enum wl12xx_fw_type fw_type; | 157 | enum wl12xx_fw_type fw_type; |
158 | bool plt; | 158 | bool plt; |
159 | enum plt_mode plt_mode; | ||
160 | u8 fem_manuf; | ||
159 | u8 last_vif_count; | 161 | u8 last_vif_count; |
160 | struct mutex mutex; | 162 | struct mutex mutex; |
161 | 163 | ||
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h index 0187eef4fb07..c0505635bb00 100644 --- a/drivers/net/wireless/ti/wlcore/wlcore_i.h +++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h | |||
@@ -293,6 +293,12 @@ enum rx_filter_action { | |||
293 | FILTER_FW_HANDLE = 2 | 293 | FILTER_FW_HANDLE = 2 |
294 | }; | 294 | }; |
295 | 295 | ||
296 | enum plt_mode { | ||
297 | PLT_OFF = 0, | ||
298 | PLT_ON = 1, | ||
299 | PLT_FEM_DETECT = 2, | ||
300 | }; | ||
301 | |||
296 | struct wl12xx_rx_filter_field { | 302 | struct wl12xx_rx_filter_field { |
297 | __le16 offset; | 303 | __le16 offset; |
298 | u8 len; | 304 | u8 len; |
@@ -459,7 +465,7 @@ struct ieee80211_vif *wl12xx_wlvif_to_vif(struct wl12xx_vif *wlvif) | |||
459 | #define wl12xx_for_each_wlvif_ap(wl, wlvif) \ | 465 | #define wl12xx_for_each_wlvif_ap(wl, wlvif) \ |
460 | wl12xx_for_each_wlvif_bss_type(wl, wlvif, BSS_TYPE_AP_BSS) | 466 | wl12xx_for_each_wlvif_bss_type(wl, wlvif, BSS_TYPE_AP_BSS) |
461 | 467 | ||
462 | int wl1271_plt_start(struct wl1271 *wl); | 468 | int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode); |
463 | int wl1271_plt_stop(struct wl1271 *wl); | 469 | int wl1271_plt_stop(struct wl1271 *wl); |
464 | int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif); | 470 | int wl1271_recalc_rx_streaming(struct wl1271 *wl, struct wl12xx_vif *wlvif); |
465 | void wl12xx_queue_recovery_work(struct wl1271 *wl); | 471 | void wl12xx_queue_recovery_work(struct wl1271 *wl); |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 03b2f30d2ace..1954a4e305a3 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <linux/bcma/bcma_driver_chipcommon.h> | 7 | #include <linux/bcma/bcma_driver_chipcommon.h> |
8 | #include <linux/bcma/bcma_driver_pci.h> | 8 | #include <linux/bcma/bcma_driver_pci.h> |
9 | #include <linux/bcma/bcma_driver_mips.h> | 9 | #include <linux/bcma/bcma_driver_mips.h> |
10 | #include <linux/bcma/bcma_driver_gmac_cmn.h> | ||
10 | #include <linux/ssb/ssb.h> /* SPROM sharing */ | 11 | #include <linux/ssb/ssb.h> /* SPROM sharing */ |
11 | 12 | ||
12 | #include "bcma_regs.h" | 13 | #include "bcma_regs.h" |
@@ -252,6 +253,7 @@ struct bcma_bus { | |||
252 | struct bcma_drv_cc drv_cc; | 253 | struct bcma_drv_cc drv_cc; |
253 | struct bcma_drv_pci drv_pci; | 254 | struct bcma_drv_pci drv_pci; |
254 | struct bcma_drv_mips drv_mips; | 255 | struct bcma_drv_mips drv_mips; |
256 | struct bcma_drv_gmac_cmn drv_gmac_cmn; | ||
255 | 257 | ||
256 | /* We decided to share SPROM struct with SSB as long as we do not need | 258 | /* We decided to share SPROM struct with SSB as long as we do not need |
257 | * any hacks for BCMA. This simplifies drivers code. */ | 259 | * any hacks for BCMA. This simplifies drivers code. */ |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index fbd0d49dc4d2..3c80885fa829 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ | 24 | #define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */ |
25 | #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ | 25 | #define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */ |
26 | #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ | 26 | #define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */ |
27 | #define BCMA_CC_FLASHT_NFLASH 0x00000200 | 27 | #define BCMA_CC_FLASHT_NFLASH 0x00000200 /* NAND flash */ |
28 | #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ | 28 | #define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */ |
29 | #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ | 29 | #define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */ |
30 | #define BCMA_PLLTYPE_NONE 0x00000000 | 30 | #define BCMA_PLLTYPE_NONE 0x00000000 |
@@ -45,6 +45,7 @@ | |||
45 | #define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ | 45 | #define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */ |
46 | #define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ | 46 | #define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */ |
47 | #define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */ | 47 | #define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */ |
48 | #define BCMA_CC_CAP_NFLASH 0x80000000 /* NAND flash present (rev >= 35 or BCM4706?) */ | ||
48 | #define BCMA_CC_CORECTL 0x0008 | 49 | #define BCMA_CC_CORECTL 0x0008 |
49 | #define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ | 50 | #define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */ |
50 | #define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ | 51 | #define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ |
@@ -122,10 +123,58 @@ | |||
122 | #define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */ | 123 | #define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */ |
123 | #define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */ | 124 | #define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */ |
124 | #define BCMA_CC_FLASHCTL 0x0040 | 125 | #define BCMA_CC_FLASHCTL 0x0040 |
126 | /* Start/busy bit in flashcontrol */ | ||
127 | #define BCMA_CC_FLASHCTL_OPCODE 0x000000ff | ||
128 | #define BCMA_CC_FLASHCTL_ACTION 0x00000700 | ||
129 | #define BCMA_CC_FLASHCTL_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */ | ||
125 | #define BCMA_CC_FLASHCTL_START 0x80000000 | 130 | #define BCMA_CC_FLASHCTL_START 0x80000000 |
126 | #define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START | 131 | #define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START |
132 | /* Flashcontrol action + opcodes for ST flashes */ | ||
133 | #define BCMA_CC_FLASHCTL_ST_WREN 0x0006 /* Write Enable */ | ||
134 | #define BCMA_CC_FLASHCTL_ST_WRDIS 0x0004 /* Write Disable */ | ||
135 | #define BCMA_CC_FLASHCTL_ST_RDSR 0x0105 /* Read Status Register */ | ||
136 | #define BCMA_CC_FLASHCTL_ST_WRSR 0x0101 /* Write Status Register */ | ||
137 | #define BCMA_CC_FLASHCTL_ST_READ 0x0303 /* Read Data Bytes */ | ||
138 | #define BCMA_CC_FLASHCTL_ST_PP 0x0302 /* Page Program */ | ||
139 | #define BCMA_CC_FLASHCTL_ST_SE 0x02d8 /* Sector Erase */ | ||
140 | #define BCMA_CC_FLASHCTL_ST_BE 0x00c7 /* Bulk Erase */ | ||
141 | #define BCMA_CC_FLASHCTL_ST_DP 0x00b9 /* Deep Power-down */ | ||
142 | #define BCMA_CC_FLASHCTL_ST_RES 0x03ab /* Read Electronic Signature */ | ||
143 | #define BCMA_CC_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */ | ||
144 | #define BCMA_CC_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */ | ||
145 | /* Flashcontrol action + opcodes for Atmel flashes */ | ||
146 | #define BCMA_CC_FLASHCTL_AT_READ 0x07e8 | ||
147 | #define BCMA_CC_FLASHCTL_AT_PAGE_READ 0x07d2 | ||
148 | #define BCMA_CC_FLASHCTL_AT_STATUS 0x01d7 | ||
149 | #define BCMA_CC_FLASHCTL_AT_BUF1_WRITE 0x0384 | ||
150 | #define BCMA_CC_FLASHCTL_AT_BUF2_WRITE 0x0387 | ||
151 | #define BCMA_CC_FLASHCTL_AT_BUF1_ERASE_PROGRAM 0x0283 | ||
152 | #define BCMA_CC_FLASHCTL_AT_BUF2_ERASE_PROGRAM 0x0286 | ||
153 | #define BCMA_CC_FLASHCTL_AT_BUF1_PROGRAM 0x0288 | ||
154 | #define BCMA_CC_FLASHCTL_AT_BUF2_PROGRAM 0x0289 | ||
155 | #define BCMA_CC_FLASHCTL_AT_PAGE_ERASE 0x0281 | ||
156 | #define BCMA_CC_FLASHCTL_AT_BLOCK_ERASE 0x0250 | ||
157 | #define BCMA_CC_FLASHCTL_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 | ||
158 | #define BCMA_CC_FLASHCTL_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 | ||
159 | #define BCMA_CC_FLASHCTL_AT_BUF1_LOAD 0x0253 | ||
160 | #define BCMA_CC_FLASHCTL_AT_BUF2_LOAD 0x0255 | ||
161 | #define BCMA_CC_FLASHCTL_AT_BUF1_COMPARE 0x0260 | ||
162 | #define BCMA_CC_FLASHCTL_AT_BUF2_COMPARE 0x0261 | ||
163 | #define BCMA_CC_FLASHCTL_AT_BUF1_REPROGRAM 0x0258 | ||
164 | #define BCMA_CC_FLASHCTL_AT_BUF2_REPROGRAM 0x0259 | ||
127 | #define BCMA_CC_FLASHADDR 0x0044 | 165 | #define BCMA_CC_FLASHADDR 0x0044 |
128 | #define BCMA_CC_FLASHDATA 0x0048 | 166 | #define BCMA_CC_FLASHDATA 0x0048 |
167 | /* Status register bits for ST flashes */ | ||
168 | #define BCMA_CC_FLASHDATA_ST_WIP 0x01 /* Write In Progress */ | ||
169 | #define BCMA_CC_FLASHDATA_ST_WEL 0x02 /* Write Enable Latch */ | ||
170 | #define BCMA_CC_FLASHDATA_ST_BP_MASK 0x1c /* Block Protect */ | ||
171 | #define BCMA_CC_FLASHDATA_ST_BP_SHIFT 2 | ||
172 | #define BCMA_CC_FLASHDATA_ST_SRWD 0x80 /* Status Register Write Disable */ | ||
173 | /* Status register bits for Atmel flashes */ | ||
174 | #define BCMA_CC_FLASHDATA_AT_READY 0x80 | ||
175 | #define BCMA_CC_FLASHDATA_AT_MISMATCH 0x40 | ||
176 | #define BCMA_CC_FLASHDATA_AT_ID_MASK 0x38 | ||
177 | #define BCMA_CC_FLASHDATA_AT_ID_SHIFT 3 | ||
129 | #define BCMA_CC_BCAST_ADDR 0x0050 | 178 | #define BCMA_CC_BCAST_ADDR 0x0050 |
130 | #define BCMA_CC_BCAST_DATA 0x0054 | 179 | #define BCMA_CC_BCAST_DATA 0x0054 |
131 | #define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */ | 180 | #define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */ |
diff --git a/include/linux/bcma/bcma_driver_gmac_cmn.h b/include/linux/bcma/bcma_driver_gmac_cmn.h new file mode 100644 index 000000000000..def894b83b0d --- /dev/null +++ b/include/linux/bcma/bcma_driver_gmac_cmn.h | |||
@@ -0,0 +1,100 @@ | |||
1 | #ifndef LINUX_BCMA_DRIVER_GMAC_CMN_H_ | ||
2 | #define LINUX_BCMA_DRIVER_GMAC_CMN_H_ | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #define BCMA_GMAC_CMN_STAG0 0x000 | ||
7 | #define BCMA_GMAC_CMN_STAG1 0x004 | ||
8 | #define BCMA_GMAC_CMN_STAG2 0x008 | ||
9 | #define BCMA_GMAC_CMN_STAG3 0x00C | ||
10 | #define BCMA_GMAC_CMN_PARSER_CTL 0x020 | ||
11 | #define BCMA_GMAC_CMN_MIB_MAX_LEN 0x024 | ||
12 | #define BCMA_GMAC_CMN_PHY_ACCESS 0x100 | ||
13 | #define BCMA_GMAC_CMN_PA_DATA_MASK 0x0000ffff | ||
14 | #define BCMA_GMAC_CMN_PA_ADDR_MASK 0x001f0000 | ||
15 | #define BCMA_GMAC_CMN_PA_ADDR_SHIFT 16 | ||
16 | #define BCMA_GMAC_CMN_PA_REG_MASK 0x1f000000 | ||
17 | #define BCMA_GMAC_CMN_PA_REG_SHIFT 24 | ||
18 | #define BCMA_GMAC_CMN_PA_WRITE 0x20000000 | ||
19 | #define BCMA_GMAC_CMN_PA_START 0x40000000 | ||
20 | #define BCMA_GMAC_CMN_PHY_CTL 0x104 | ||
21 | #define BCMA_GMAC_CMN_PC_EPA_MASK 0x0000001f | ||
22 | #define BCMA_GMAC_CMN_PC_MCT_MASK 0x007f0000 | ||
23 | #define BCMA_GMAC_CMN_PC_MCT_SHIFT 16 | ||
24 | #define BCMA_GMAC_CMN_PC_MTE 0x00800000 | ||
25 | #define BCMA_GMAC_CMN_GMAC0_RGMII_CTL 0x110 | ||
26 | #define BCMA_GMAC_CMN_CFP_ACCESS 0x200 | ||
27 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA0 0x210 | ||
28 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA1 0x214 | ||
29 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA2 0x218 | ||
30 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA3 0x21C | ||
31 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA4 0x220 | ||
32 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA5 0x224 | ||
33 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA6 0x228 | ||
34 | #define BCMA_GMAC_CMN_CFP_TCAM_DATA7 0x22C | ||
35 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK0 0x230 | ||
36 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK1 0x234 | ||
37 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK2 0x238 | ||
38 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK3 0x23C | ||
39 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK4 0x240 | ||
40 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK5 0x244 | ||
41 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK6 0x248 | ||
42 | #define BCMA_GMAC_CMN_CFP_TCAM_MASK7 0x24C | ||
43 | #define BCMA_GMAC_CMN_CFP_ACTION_DATA 0x250 | ||
44 | #define BCMA_GMAC_CMN_TCAM_BIST_CTL 0x2A0 | ||
45 | #define BCMA_GMAC_CMN_TCAM_BIST_STATUS 0x2A4 | ||
46 | #define BCMA_GMAC_CMN_TCAM_CMP_STATUS 0x2A8 | ||
47 | #define BCMA_GMAC_CMN_TCAM_DISABLE 0x2AC | ||
48 | #define BCMA_GMAC_CMN_TCAM_TEST_CTL 0x2F0 | ||
49 | #define BCMA_GMAC_CMN_UDF_0_A3_A0 0x300 | ||
50 | #define BCMA_GMAC_CMN_UDF_0_A7_A4 0x304 | ||
51 | #define BCMA_GMAC_CMN_UDF_0_A8 0x308 | ||
52 | #define BCMA_GMAC_CMN_UDF_1_A3_A0 0x310 | ||
53 | #define BCMA_GMAC_CMN_UDF_1_A7_A4 0x314 | ||
54 | #define BCMA_GMAC_CMN_UDF_1_A8 0x318 | ||
55 | #define BCMA_GMAC_CMN_UDF_2_A3_A0 0x320 | ||
56 | #define BCMA_GMAC_CMN_UDF_2_A7_A4 0x324 | ||
57 | #define BCMA_GMAC_CMN_UDF_2_A8 0x328 | ||
58 | #define BCMA_GMAC_CMN_UDF_0_B3_B0 0x330 | ||
59 | #define BCMA_GMAC_CMN_UDF_0_B7_B4 0x334 | ||
60 | #define BCMA_GMAC_CMN_UDF_0_B8 0x338 | ||
61 | #define BCMA_GMAC_CMN_UDF_1_B3_B0 0x340 | ||
62 | #define BCMA_GMAC_CMN_UDF_1_B7_B4 0x344 | ||
63 | #define BCMA_GMAC_CMN_UDF_1_B8 0x348 | ||
64 | #define BCMA_GMAC_CMN_UDF_2_B3_B0 0x350 | ||
65 | #define BCMA_GMAC_CMN_UDF_2_B7_B4 0x354 | ||
66 | #define BCMA_GMAC_CMN_UDF_2_B8 0x358 | ||
67 | #define BCMA_GMAC_CMN_UDF_0_C3_C0 0x360 | ||
68 | #define BCMA_GMAC_CMN_UDF_0_C7_C4 0x364 | ||
69 | #define BCMA_GMAC_CMN_UDF_0_C8 0x368 | ||
70 | #define BCMA_GMAC_CMN_UDF_1_C3_C0 0x370 | ||
71 | #define BCMA_GMAC_CMN_UDF_1_C7_C4 0x374 | ||
72 | #define BCMA_GMAC_CMN_UDF_1_C8 0x378 | ||
73 | #define BCMA_GMAC_CMN_UDF_2_C3_C0 0x380 | ||
74 | #define BCMA_GMAC_CMN_UDF_2_C7_C4 0x384 | ||
75 | #define BCMA_GMAC_CMN_UDF_2_C8 0x388 | ||
76 | #define BCMA_GMAC_CMN_UDF_0_D3_D0 0x390 | ||
77 | #define BCMA_GMAC_CMN_UDF_0_D7_D4 0x394 | ||
78 | #define BCMA_GMAC_CMN_UDF_0_D11_D8 0x394 | ||
79 | |||
80 | struct bcma_drv_gmac_cmn { | ||
81 | struct bcma_device *core; | ||
82 | |||
83 | /* Drivers accessing BCMA_GMAC_CMN_PHY_ACCESS and | ||
84 | * BCMA_GMAC_CMN_PHY_CTL need to take that mutex first. */ | ||
85 | struct mutex phy_mutex; | ||
86 | }; | ||
87 | |||
88 | /* Register access */ | ||
89 | #define gmac_cmn_read16(gc, offset) bcma_read16((gc)->core, offset) | ||
90 | #define gmac_cmn_read32(gc, offset) bcma_read32((gc)->core, offset) | ||
91 | #define gmac_cmn_write16(gc, offset, val) bcma_write16((gc)->core, offset, val) | ||
92 | #define gmac_cmn_write32(gc, offset, val) bcma_write32((gc)->core, offset, val) | ||
93 | |||
94 | #ifdef CONFIG_BCMA_DRIVER_GMAC_CMN | ||
95 | extern void __devinit bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc); | ||
96 | #else | ||
97 | static inline void bcma_core_gmac_cmn_init(struct bcma_drv_gmac_cmn *gc) { } | ||
98 | #endif | ||
99 | |||
100 | #endif /* LINUX_BCMA_DRIVER_GMAC_CMN_H_ */ | ||
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h index db961a59247f..2f3878806403 100644 --- a/include/linux/nl80211.h +++ b/include/linux/nl80211.h | |||
@@ -771,6 +771,9 @@ enum nl80211_commands { | |||
771 | * @NL80211_ATTR_IFNAME: network interface name | 771 | * @NL80211_ATTR_IFNAME: network interface name |
772 | * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype | 772 | * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype |
773 | * | 773 | * |
774 | * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices | ||
775 | * that don't have a netdev (u64) | ||
776 | * | ||
774 | * @NL80211_ATTR_MAC: MAC address (various uses) | 777 | * @NL80211_ATTR_MAC: MAC address (various uses) |
775 | * | 778 | * |
776 | * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of | 779 | * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of |
@@ -1242,6 +1245,12 @@ enum nl80211_commands { | |||
1242 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds | 1245 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds |
1243 | * or 0 to disable background scan. | 1246 | * or 0 to disable background scan. |
1244 | * | 1247 | * |
1248 | * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from | ||
1249 | * userspace. If unset it is assumed the hint comes directly from | ||
1250 | * a user. If set code could specify exactly what type of source | ||
1251 | * was used to provide the hint. For the different types of | ||
1252 | * allowed user regulatory hints see nl80211_user_reg_hint_type. | ||
1253 | * | ||
1245 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1254 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1246 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1255 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1247 | */ | 1256 | */ |
@@ -1493,6 +1502,10 @@ enum nl80211_attrs { | |||
1493 | 1502 | ||
1494 | NL80211_ATTR_BG_SCAN_PERIOD, | 1503 | NL80211_ATTR_BG_SCAN_PERIOD, |
1495 | 1504 | ||
1505 | NL80211_ATTR_WDEV, | ||
1506 | |||
1507 | NL80211_ATTR_USER_REG_HINT_TYPE, | ||
1508 | |||
1496 | /* add attributes here, update the policy in nl80211.c */ | 1509 | /* add attributes here, update the policy in nl80211.c */ |
1497 | 1510 | ||
1498 | __NL80211_ATTR_AFTER_LAST, | 1511 | __NL80211_ATTR_AFTER_LAST, |
@@ -1545,6 +1558,8 @@ enum nl80211_attrs { | |||
1545 | /* default RSSI threshold for scan results if none specified. */ | 1558 | /* default RSSI threshold for scan results if none specified. */ |
1546 | #define NL80211_SCAN_RSSI_THOLD_OFF -300 | 1559 | #define NL80211_SCAN_RSSI_THOLD_OFF -300 |
1547 | 1560 | ||
1561 | #define NL80211_CQM_TXE_MAX_INTVL 1800 | ||
1562 | |||
1548 | /** | 1563 | /** |
1549 | * enum nl80211_iftype - (virtual) interface types | 1564 | * enum nl80211_iftype - (virtual) interface types |
1550 | * | 1565 | * |
@@ -2054,6 +2069,26 @@ enum nl80211_dfs_regions { | |||
2054 | }; | 2069 | }; |
2055 | 2070 | ||
2056 | /** | 2071 | /** |
2072 | * enum nl80211_user_reg_hint_type - type of user regulatory hint | ||
2073 | * | ||
2074 | * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always | ||
2075 | * assumed if the attribute is not set. | ||
2076 | * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular | ||
2077 | * base station. Device drivers that have been tested to work | ||
2078 | * properly to support this type of hint can enable these hints | ||
2079 | * by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature | ||
2080 | * capability on the struct wiphy. The wireless core will | ||
2081 | * ignore all cell base station hints until at least one device | ||
2082 | * present has been registered with the wireless core that | ||
2083 | * has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a | ||
2084 | * supported feature. | ||
2085 | */ | ||
2086 | enum nl80211_user_reg_hint_type { | ||
2087 | NL80211_USER_REG_HINT_USER = 0, | ||
2088 | NL80211_USER_REG_HINT_CELL_BASE = 1, | ||
2089 | }; | ||
2090 | |||
2091 | /** | ||
2057 | * enum nl80211_survey_info - survey information | 2092 | * enum nl80211_survey_info - survey information |
2058 | * | 2093 | * |
2059 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO | 2094 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO |
@@ -2584,6 +2619,17 @@ enum nl80211_ps_state { | |||
2584 | * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event | 2619 | * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event |
2585 | * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many | 2620 | * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many |
2586 | * consecutive packets were not acknowledged by the peer | 2621 | * consecutive packets were not acknowledged by the peer |
2622 | * @NL80211_ATTR_CQM_TXE_RATE: TX error rate in %. Minimum % of TX failures | ||
2623 | * during the given %NL80211_ATTR_CQM_TXE_INTVL before an | ||
2624 | * %NL80211_CMD_NOTIFY_CQM with reported %NL80211_ATTR_CQM_TXE_RATE and | ||
2625 | * %NL80211_ATTR_CQM_TXE_PKTS is generated. | ||
2626 | * @NL80211_ATTR_CQM_TXE_PKTS: number of attempted packets in a given | ||
2627 | * %NL80211_ATTR_CQM_TXE_INTVL before %NL80211_ATTR_CQM_TXE_RATE is | ||
2628 | * checked. | ||
2629 | * @NL80211_ATTR_CQM_TXE_INTVL: interval in seconds. Specifies the periodic | ||
2630 | * interval in which %NL80211_ATTR_CQM_TXE_PKTS and | ||
2631 | * %NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an | ||
2632 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. | ||
2587 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal | 2633 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal |
2588 | * @NL80211_ATTR_CQM_MAX: highest key attribute | 2634 | * @NL80211_ATTR_CQM_MAX: highest key attribute |
2589 | */ | 2635 | */ |
@@ -2593,6 +2639,9 @@ enum nl80211_attr_cqm { | |||
2593 | NL80211_ATTR_CQM_RSSI_HYST, | 2639 | NL80211_ATTR_CQM_RSSI_HYST, |
2594 | NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, | 2640 | NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, |
2595 | NL80211_ATTR_CQM_PKT_LOSS_EVENT, | 2641 | NL80211_ATTR_CQM_PKT_LOSS_EVENT, |
2642 | NL80211_ATTR_CQM_TXE_RATE, | ||
2643 | NL80211_ATTR_CQM_TXE_PKTS, | ||
2644 | NL80211_ATTR_CQM_TXE_INTVL, | ||
2596 | 2645 | ||
2597 | /* keep last */ | 2646 | /* keep last */ |
2598 | __NL80211_ATTR_CQM_AFTER_LAST, | 2647 | __NL80211_ATTR_CQM_AFTER_LAST, |
@@ -2942,11 +2991,15 @@ enum nl80211_ap_sme_features { | |||
2942 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. | 2991 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. |
2943 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up | 2992 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up |
2944 | * the connected inactive stations in AP mode. | 2993 | * the connected inactive stations in AP mode. |
2994 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested | ||
2995 | * to work properly to suppport receiving regulatory hints from | ||
2996 | * cellular base stations. | ||
2945 | */ | 2997 | */ |
2946 | enum nl80211_feature_flags { | 2998 | enum nl80211_feature_flags { |
2947 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 2999 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
2948 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 3000 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
2949 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3001 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
3002 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | ||
2950 | }; | 3003 | }; |
2951 | 3004 | ||
2952 | /** | 3005 | /** |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 2a6b0b8b7120..ccd723e0f783 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -139,11 +139,12 @@ enum { | |||
139 | #define HCIINQUIRY _IOR('H', 240, int) | 139 | #define HCIINQUIRY _IOR('H', 240, int) |
140 | 140 | ||
141 | /* HCI timeouts */ | 141 | /* HCI timeouts */ |
142 | #define HCI_DISCONN_TIMEOUT (2000) /* 2 seconds */ | 142 | #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ |
143 | #define HCI_PAIRING_TIMEOUT (60000) /* 60 seconds */ | 143 | #define HCI_PAIRING_TIMEOUT msecs_to_jiffies(60000) /* 60 seconds */ |
144 | #define HCI_INIT_TIMEOUT (10000) /* 10 seconds */ | 144 | #define HCI_INIT_TIMEOUT msecs_to_jiffies(10000) /* 10 seconds */ |
145 | #define HCI_CMD_TIMEOUT (1000) /* 1 seconds */ | 145 | #define HCI_CMD_TIMEOUT msecs_to_jiffies(1000) /* 1 second */ |
146 | #define HCI_ACL_TX_TIMEOUT (45000) /* 45 seconds */ | 146 | #define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ |
147 | #define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ | ||
147 | 148 | ||
148 | /* HCI data types */ | 149 | /* HCI data types */ |
149 | #define HCI_COMMAND_PKT 0x01 | 150 | #define HCI_COMMAND_PKT 0x01 |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 20fd57367ddc..475b8c04ba52 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -587,18 +587,24 @@ void hci_conn_put_device(struct hci_conn *conn); | |||
587 | 587 | ||
588 | static inline void hci_conn_hold(struct hci_conn *conn) | 588 | static inline void hci_conn_hold(struct hci_conn *conn) |
589 | { | 589 | { |
590 | BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), | ||
591 | atomic_read(&conn->refcnt) + 1); | ||
592 | |||
590 | atomic_inc(&conn->refcnt); | 593 | atomic_inc(&conn->refcnt); |
591 | cancel_delayed_work(&conn->disc_work); | 594 | cancel_delayed_work(&conn->disc_work); |
592 | } | 595 | } |
593 | 596 | ||
594 | static inline void hci_conn_put(struct hci_conn *conn) | 597 | static inline void hci_conn_put(struct hci_conn *conn) |
595 | { | 598 | { |
599 | BT_DBG("hcon %p refcnt %d -> %d", conn, atomic_read(&conn->refcnt), | ||
600 | atomic_read(&conn->refcnt) - 1); | ||
601 | |||
596 | if (atomic_dec_and_test(&conn->refcnt)) { | 602 | if (atomic_dec_and_test(&conn->refcnt)) { |
597 | unsigned long timeo; | 603 | unsigned long timeo; |
598 | if (conn->type == ACL_LINK || conn->type == LE_LINK) { | 604 | if (conn->type == ACL_LINK || conn->type == LE_LINK) { |
599 | del_timer(&conn->idle_timer); | 605 | del_timer(&conn->idle_timer); |
600 | if (conn->state == BT_CONNECTED) { | 606 | if (conn->state == BT_CONNECTED) { |
601 | timeo = msecs_to_jiffies(conn->disc_timeout); | 607 | timeo = conn->disc_timeout; |
602 | if (!conn->out) | 608 | if (!conn->out) |
603 | timeo *= 2; | 609 | timeo *= 2; |
604 | } else { | 610 | } else { |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index d80e3f0691b4..a7679f8913d2 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -464,6 +464,7 @@ struct l2cap_chan { | |||
464 | 464 | ||
465 | __u16 tx_win; | 465 | __u16 tx_win; |
466 | __u16 tx_win_max; | 466 | __u16 tx_win_max; |
467 | __u16 ack_win; | ||
467 | __u8 max_tx; | 468 | __u8 max_tx; |
468 | __u16 retrans_timeout; | 469 | __u16 retrans_timeout; |
469 | __u16 monitor_timeout; | 470 | __u16 monitor_timeout; |
@@ -672,11 +673,15 @@ enum { | |||
672 | 673 | ||
673 | static inline void l2cap_chan_hold(struct l2cap_chan *c) | 674 | static inline void l2cap_chan_hold(struct l2cap_chan *c) |
674 | { | 675 | { |
676 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt)); | ||
677 | |||
675 | atomic_inc(&c->refcnt); | 678 | atomic_inc(&c->refcnt); |
676 | } | 679 | } |
677 | 680 | ||
678 | static inline void l2cap_chan_put(struct l2cap_chan *c) | 681 | static inline void l2cap_chan_put(struct l2cap_chan *c) |
679 | { | 682 | { |
683 | BT_DBG("chan %p orig refcnt %d", c, atomic_read(&c->refcnt)); | ||
684 | |||
680 | if (atomic_dec_and_test(&c->refcnt)) | 685 | if (atomic_dec_and_test(&c->refcnt)) |
681 | kfree(c); | 686 | kfree(c); |
682 | } | 687 | } |
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 23fd0546fccb..4348ee8bda69 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h | |||
@@ -444,7 +444,7 @@ struct mgmt_ev_auth_failed { | |||
444 | struct mgmt_ev_device_found { | 444 | struct mgmt_ev_device_found { |
445 | struct mgmt_addr_info addr; | 445 | struct mgmt_addr_info addr; |
446 | __s8 rssi; | 446 | __s8 rssi; |
447 | __u8 flags[4]; | 447 | __le32 flags; |
448 | __le16 eir_len; | 448 | __le16 eir_len; |
449 | __u8 eir[0]; | 449 | __u8 eir[0]; |
450 | } __packed; | 450 | } __packed; |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 51f67a9003a9..493fa0c79005 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -999,7 +999,7 @@ struct cfg80211_ssid { | |||
999 | * @ie_len: length of ie in octets | 999 | * @ie_len: length of ie in octets |
1000 | * @rates: bitmap of rates to advertise for each band | 1000 | * @rates: bitmap of rates to advertise for each band |
1001 | * @wiphy: the wiphy this was for | 1001 | * @wiphy: the wiphy this was for |
1002 | * @dev: the interface | 1002 | * @wdev: the wireless device to scan for |
1003 | * @aborted: (internal) scan request was notified as aborted | 1003 | * @aborted: (internal) scan request was notified as aborted |
1004 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band | 1004 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band |
1005 | */ | 1005 | */ |
@@ -1012,9 +1012,10 @@ struct cfg80211_scan_request { | |||
1012 | 1012 | ||
1013 | u32 rates[IEEE80211_NUM_BANDS]; | 1013 | u32 rates[IEEE80211_NUM_BANDS]; |
1014 | 1014 | ||
1015 | struct wireless_dev *wdev; | ||
1016 | |||
1015 | /* internal */ | 1017 | /* internal */ |
1016 | struct wiphy *wiphy; | 1018 | struct wiphy *wiphy; |
1017 | struct net_device *dev; | ||
1018 | bool aborted; | 1019 | bool aborted; |
1019 | bool no_cck; | 1020 | bool no_cck; |
1020 | 1021 | ||
@@ -1435,10 +1436,10 @@ struct cfg80211_gtk_rekey_data { | |||
1435 | * | 1436 | * |
1436 | * @add_virtual_intf: create a new virtual interface with the given name, | 1437 | * @add_virtual_intf: create a new virtual interface with the given name, |
1437 | * must set the struct wireless_dev's iftype. Beware: You must create | 1438 | * must set the struct wireless_dev's iftype. Beware: You must create |
1438 | * the new netdev in the wiphy's network namespace! Returns the netdev, | 1439 | * the new netdev in the wiphy's network namespace! Returns the struct |
1439 | * or an ERR_PTR. | 1440 | * wireless_dev, or an ERR_PTR. |
1440 | * | 1441 | * |
1441 | * @del_virtual_intf: remove the virtual interface determined by ifindex. | 1442 | * @del_virtual_intf: remove the virtual interface |
1442 | * | 1443 | * |
1443 | * @change_virtual_intf: change type/configuration of virtual interface, | 1444 | * @change_virtual_intf: change type/configuration of virtual interface, |
1444 | * keep the struct wireless_dev's iftype updated. | 1445 | * keep the struct wireless_dev's iftype updated. |
@@ -1503,8 +1504,6 @@ struct cfg80211_gtk_rekey_data { | |||
1503 | * interfaces are active this callback should reject the configuration. | 1504 | * interfaces are active this callback should reject the configuration. |
1504 | * If no interfaces are active or the device is down, the channel should | 1505 | * If no interfaces are active or the device is down, the channel should |
1505 | * be stored for when a monitor interface becomes active. | 1506 | * be stored for when a monitor interface becomes active. |
1506 | * @set_monitor_enabled: Notify driver that there are only monitor | ||
1507 | * interfaces running. | ||
1508 | * | 1507 | * |
1509 | * @scan: Request to do a scan. If returning zero, the scan request is given | 1508 | * @scan: Request to do a scan. If returning zero, the scan request is given |
1510 | * the driver, and will be valid until passed to cfg80211_scan_done(). | 1509 | * the driver, and will be valid until passed to cfg80211_scan_done(). |
@@ -1574,6 +1573,8 @@ struct cfg80211_gtk_rekey_data { | |||
1574 | * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 | 1573 | * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 |
1575 | * allows the driver to adjust the dynamic ps timeout value. | 1574 | * allows the driver to adjust the dynamic ps timeout value. |
1576 | * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. | 1575 | * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. |
1576 | * @set_cqm_txe_config: Configure connection quality monitor TX error | ||
1577 | * thresholds. | ||
1577 | * @sched_scan_start: Tell the driver to start a scheduled scan. | 1578 | * @sched_scan_start: Tell the driver to start a scheduled scan. |
1578 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled | 1579 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled |
1579 | * scan. The driver_initiated flag specifies whether the driver | 1580 | * scan. The driver_initiated flag specifies whether the driver |
@@ -1611,18 +1612,23 @@ struct cfg80211_gtk_rekey_data { | |||
1611 | * @get_et_strings: Ethtool API to get a set of strings to describe stats | 1612 | * @get_et_strings: Ethtool API to get a set of strings to describe stats |
1612 | * and perhaps other supported types of ethtool data-sets. | 1613 | * and perhaps other supported types of ethtool data-sets. |
1613 | * See @ethtool_ops.get_strings | 1614 | * See @ethtool_ops.get_strings |
1615 | * | ||
1616 | * @get_channel: Get the current operating channel for the virtual interface. | ||
1617 | * For monitor interfaces, it should return %NULL unless there's a single | ||
1618 | * current monitoring channel. | ||
1614 | */ | 1619 | */ |
1615 | struct cfg80211_ops { | 1620 | struct cfg80211_ops { |
1616 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1621 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
1617 | int (*resume)(struct wiphy *wiphy); | 1622 | int (*resume)(struct wiphy *wiphy); |
1618 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); | 1623 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); |
1619 | 1624 | ||
1620 | struct net_device * (*add_virtual_intf)(struct wiphy *wiphy, | 1625 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, |
1621 | char *name, | 1626 | char *name, |
1622 | enum nl80211_iftype type, | 1627 | enum nl80211_iftype type, |
1623 | u32 *flags, | 1628 | u32 *flags, |
1624 | struct vif_params *params); | 1629 | struct vif_params *params); |
1625 | int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev); | 1630 | int (*del_virtual_intf)(struct wiphy *wiphy, |
1631 | struct wireless_dev *wdev); | ||
1626 | int (*change_virtual_intf)(struct wiphy *wiphy, | 1632 | int (*change_virtual_intf)(struct wiphy *wiphy, |
1627 | struct net_device *dev, | 1633 | struct net_device *dev, |
1628 | enum nl80211_iftype type, u32 *flags, | 1634 | enum nl80211_iftype type, u32 *flags, |
@@ -1699,7 +1705,7 @@ struct cfg80211_ops { | |||
1699 | struct ieee80211_channel *chan, | 1705 | struct ieee80211_channel *chan, |
1700 | enum nl80211_channel_type channel_type); | 1706 | enum nl80211_channel_type channel_type); |
1701 | 1707 | ||
1702 | int (*scan)(struct wiphy *wiphy, struct net_device *dev, | 1708 | int (*scan)(struct wiphy *wiphy, |
1703 | struct cfg80211_scan_request *request); | 1709 | struct cfg80211_scan_request *request); |
1704 | 1710 | ||
1705 | int (*auth)(struct wiphy *wiphy, struct net_device *dev, | 1711 | int (*auth)(struct wiphy *wiphy, struct net_device *dev, |
@@ -1753,23 +1759,23 @@ struct cfg80211_ops { | |||
1753 | int (*flush_pmksa)(struct wiphy *wiphy, struct net_device *netdev); | 1759 | int (*flush_pmksa)(struct wiphy *wiphy, struct net_device *netdev); |
1754 | 1760 | ||
1755 | int (*remain_on_channel)(struct wiphy *wiphy, | 1761 | int (*remain_on_channel)(struct wiphy *wiphy, |
1756 | struct net_device *dev, | 1762 | struct wireless_dev *wdev, |
1757 | struct ieee80211_channel *chan, | 1763 | struct ieee80211_channel *chan, |
1758 | enum nl80211_channel_type channel_type, | 1764 | enum nl80211_channel_type channel_type, |
1759 | unsigned int duration, | 1765 | unsigned int duration, |
1760 | u64 *cookie); | 1766 | u64 *cookie); |
1761 | int (*cancel_remain_on_channel)(struct wiphy *wiphy, | 1767 | int (*cancel_remain_on_channel)(struct wiphy *wiphy, |
1762 | struct net_device *dev, | 1768 | struct wireless_dev *wdev, |
1763 | u64 cookie); | 1769 | u64 cookie); |
1764 | 1770 | ||
1765 | int (*mgmt_tx)(struct wiphy *wiphy, struct net_device *dev, | 1771 | int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, |
1766 | struct ieee80211_channel *chan, bool offchan, | 1772 | struct ieee80211_channel *chan, bool offchan, |
1767 | enum nl80211_channel_type channel_type, | 1773 | enum nl80211_channel_type channel_type, |
1768 | bool channel_type_valid, unsigned int wait, | 1774 | bool channel_type_valid, unsigned int wait, |
1769 | const u8 *buf, size_t len, bool no_cck, | 1775 | const u8 *buf, size_t len, bool no_cck, |
1770 | bool dont_wait_for_ack, u64 *cookie); | 1776 | bool dont_wait_for_ack, u64 *cookie); |
1771 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, | 1777 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, |
1772 | struct net_device *dev, | 1778 | struct wireless_dev *wdev, |
1773 | u64 cookie); | 1779 | u64 cookie); |
1774 | 1780 | ||
1775 | int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, | 1781 | int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, |
@@ -1779,8 +1785,12 @@ struct cfg80211_ops { | |||
1779 | struct net_device *dev, | 1785 | struct net_device *dev, |
1780 | s32 rssi_thold, u32 rssi_hyst); | 1786 | s32 rssi_thold, u32 rssi_hyst); |
1781 | 1787 | ||
1788 | int (*set_cqm_txe_config)(struct wiphy *wiphy, | ||
1789 | struct net_device *dev, | ||
1790 | u32 rate, u32 pkts, u32 intvl); | ||
1791 | |||
1782 | void (*mgmt_frame_register)(struct wiphy *wiphy, | 1792 | void (*mgmt_frame_register)(struct wiphy *wiphy, |
1783 | struct net_device *dev, | 1793 | struct wireless_dev *wdev, |
1784 | u16 frame_type, bool reg); | 1794 | u16 frame_type, bool reg); |
1785 | 1795 | ||
1786 | int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); | 1796 | int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); |
@@ -1818,7 +1828,10 @@ struct cfg80211_ops { | |||
1818 | void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, | 1828 | void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, |
1819 | u32 sset, u8 *data); | 1829 | u32 sset, u8 *data); |
1820 | 1830 | ||
1821 | void (*set_monitor_enabled)(struct wiphy *wiphy, bool enabled); | 1831 | struct ieee80211_channel * |
1832 | (*get_channel)(struct wiphy *wiphy, | ||
1833 | struct wireless_dev *wdev, | ||
1834 | enum nl80211_channel_type *type); | ||
1822 | }; | 1835 | }; |
1823 | 1836 | ||
1824 | /* | 1837 | /* |
@@ -2341,17 +2354,25 @@ struct cfg80211_internal_bss; | |||
2341 | struct cfg80211_cached_keys; | 2354 | struct cfg80211_cached_keys; |
2342 | 2355 | ||
2343 | /** | 2356 | /** |
2344 | * struct wireless_dev - wireless per-netdev state | 2357 | * struct wireless_dev - wireless device state |
2358 | * | ||
2359 | * For netdevs, this structure must be allocated by the driver | ||
2360 | * that uses the ieee80211_ptr field in struct net_device (this | ||
2361 | * is intentional so it can be allocated along with the netdev.) | ||
2362 | * It need not be registered then as netdev registration will | ||
2363 | * be intercepted by cfg80211 to see the new wireless device. | ||
2345 | * | 2364 | * |
2346 | * This structure must be allocated by the driver/stack | 2365 | * For non-netdev uses, it must also be allocated by the driver |
2347 | * that uses the ieee80211_ptr field in struct net_device | 2366 | * in response to the cfg80211 callbacks that require it, as |
2348 | * (this is intentional so it can be allocated along with | 2367 | * there's no netdev registration in that case it may not be |
2349 | * the netdev.) | 2368 | * allocated outside of callback operations that return it. |
2350 | * | 2369 | * |
2351 | * @wiphy: pointer to hardware description | 2370 | * @wiphy: pointer to hardware description |
2352 | * @iftype: interface type | 2371 | * @iftype: interface type |
2353 | * @list: (private) Used to collect the interfaces | 2372 | * @list: (private) Used to collect the interfaces |
2354 | * @netdev: (private) Used to reference back to the netdev | 2373 | * @netdev: (private) Used to reference back to the netdev, may be %NULL |
2374 | * @identifier: (private) Identifier used in nl80211 to identify this | ||
2375 | * wireless device if it has no netdev | ||
2355 | * @current_bss: (private) Used by the internal configuration code | 2376 | * @current_bss: (private) Used by the internal configuration code |
2356 | * @channel: (private) Used by the internal configuration code to track | 2377 | * @channel: (private) Used by the internal configuration code to track |
2357 | * the user-set AP, monitor and WDS channel | 2378 | * the user-set AP, monitor and WDS channel |
@@ -2383,6 +2404,8 @@ struct wireless_dev { | |||
2383 | struct list_head list; | 2404 | struct list_head list; |
2384 | struct net_device *netdev; | 2405 | struct net_device *netdev; |
2385 | 2406 | ||
2407 | u32 identifier; | ||
2408 | |||
2386 | struct list_head mgmt_registrations; | 2409 | struct list_head mgmt_registrations; |
2387 | spinlock_t mgmt_registrations_lock; | 2410 | spinlock_t mgmt_registrations_lock; |
2388 | 2411 | ||
@@ -3269,7 +3292,7 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason, | |||
3269 | 3292 | ||
3270 | /** | 3293 | /** |
3271 | * cfg80211_ready_on_channel - notification of remain_on_channel start | 3294 | * cfg80211_ready_on_channel - notification of remain_on_channel start |
3272 | * @dev: network device | 3295 | * @wdev: wireless device |
3273 | * @cookie: the request cookie | 3296 | * @cookie: the request cookie |
3274 | * @chan: The current channel (from remain_on_channel request) | 3297 | * @chan: The current channel (from remain_on_channel request) |
3275 | * @channel_type: Channel type | 3298 | * @channel_type: Channel type |
@@ -3277,21 +3300,20 @@ void cfg80211_disconnected(struct net_device *dev, u16 reason, | |||
3277 | * channel | 3300 | * channel |
3278 | * @gfp: allocation flags | 3301 | * @gfp: allocation flags |
3279 | */ | 3302 | */ |
3280 | void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie, | 3303 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, |
3281 | struct ieee80211_channel *chan, | 3304 | struct ieee80211_channel *chan, |
3282 | enum nl80211_channel_type channel_type, | 3305 | enum nl80211_channel_type channel_type, |
3283 | unsigned int duration, gfp_t gfp); | 3306 | unsigned int duration, gfp_t gfp); |
3284 | 3307 | ||
3285 | /** | 3308 | /** |
3286 | * cfg80211_remain_on_channel_expired - remain_on_channel duration expired | 3309 | * cfg80211_remain_on_channel_expired - remain_on_channel duration expired |
3287 | * @dev: network device | 3310 | * @wdev: wireless device |
3288 | * @cookie: the request cookie | 3311 | * @cookie: the request cookie |
3289 | * @chan: The current channel (from remain_on_channel request) | 3312 | * @chan: The current channel (from remain_on_channel request) |
3290 | * @channel_type: Channel type | 3313 | * @channel_type: Channel type |
3291 | * @gfp: allocation flags | 3314 | * @gfp: allocation flags |
3292 | */ | 3315 | */ |
3293 | void cfg80211_remain_on_channel_expired(struct net_device *dev, | 3316 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, |
3294 | u64 cookie, | ||
3295 | struct ieee80211_channel *chan, | 3317 | struct ieee80211_channel *chan, |
3296 | enum nl80211_channel_type channel_type, | 3318 | enum nl80211_channel_type channel_type, |
3297 | gfp_t gfp); | 3319 | gfp_t gfp); |
@@ -3319,7 +3341,7 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | |||
3319 | 3341 | ||
3320 | /** | 3342 | /** |
3321 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame | 3343 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame |
3322 | * @dev: network device | 3344 | * @wdev: wireless device receiving the frame |
3323 | * @freq: Frequency on which the frame was received in MHz | 3345 | * @freq: Frequency on which the frame was received in MHz |
3324 | * @sig_dbm: signal strength in mBm, or 0 if unknown | 3346 | * @sig_dbm: signal strength in mBm, or 0 if unknown |
3325 | * @buf: Management frame (header + body) | 3347 | * @buf: Management frame (header + body) |
@@ -3334,12 +3356,12 @@ void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | |||
3334 | * This function is called whenever an Action frame is received for a station | 3356 | * This function is called whenever an Action frame is received for a station |
3335 | * mode interface, but is not processed in kernel. | 3357 | * mode interface, but is not processed in kernel. |
3336 | */ | 3358 | */ |
3337 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm, | 3359 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, |
3338 | const u8 *buf, size_t len, gfp_t gfp); | 3360 | const u8 *buf, size_t len, gfp_t gfp); |
3339 | 3361 | ||
3340 | /** | 3362 | /** |
3341 | * cfg80211_mgmt_tx_status - notification of TX status for management frame | 3363 | * cfg80211_mgmt_tx_status - notification of TX status for management frame |
3342 | * @dev: network device | 3364 | * @wdev: wireless device receiving the frame |
3343 | * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() | 3365 | * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() |
3344 | * @buf: Management frame (header + body) | 3366 | * @buf: Management frame (header + body) |
3345 | * @len: length of the frame data | 3367 | * @len: length of the frame data |
@@ -3350,7 +3372,7 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_dbm, | |||
3350 | * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the | 3372 | * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the |
3351 | * transmission attempt. | 3373 | * transmission attempt. |
3352 | */ | 3374 | */ |
3353 | void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, | 3375 | void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, |
3354 | const u8 *buf, size_t len, bool ack, gfp_t gfp); | 3376 | const u8 *buf, size_t len, bool ack, gfp_t gfp); |
3355 | 3377 | ||
3356 | 3378 | ||
@@ -3380,6 +3402,21 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, | |||
3380 | const u8 *peer, u32 num_packets, gfp_t gfp); | 3402 | const u8 *peer, u32 num_packets, gfp_t gfp); |
3381 | 3403 | ||
3382 | /** | 3404 | /** |
3405 | * cfg80211_cqm_txe_notify - TX error rate event | ||
3406 | * @dev: network device | ||
3407 | * @peer: peer's MAC address | ||
3408 | * @num_packets: how many packets were lost | ||
3409 | * @rate: % of packets which failed transmission | ||
3410 | * @intvl: interval (in s) over which the TX failure threshold was breached. | ||
3411 | * @gfp: context flags | ||
3412 | * | ||
3413 | * Notify userspace when configured % TX failures over number of packets in a | ||
3414 | * given interval is exceeded. | ||
3415 | */ | ||
3416 | void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, | ||
3417 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp); | ||
3418 | |||
3419 | /** | ||
3383 | * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying | 3420 | * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying |
3384 | * @dev: network device | 3421 | * @dev: network device |
3385 | * @bssid: BSSID of AP (to avoid races) | 3422 | * @bssid: BSSID of AP (to avoid races) |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e3fa90ce9ecb..bb86aa6f98dd 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -233,8 +233,10 @@ enum ieee80211_rssi_event { | |||
233 | * valid in station mode only while @assoc is true and if also | 233 | * valid in station mode only while @assoc is true and if also |
234 | * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf | 234 | * requested by %IEEE80211_HW_NEED_DTIM_PERIOD (cf. also hw conf |
235 | * @ps_dtim_period) | 235 | * @ps_dtim_period) |
236 | * @last_tsf: last beacon's/probe response's TSF timestamp (could be old | 236 | * @sync_tsf: last beacon's/probe response's TSF timestamp (could be old |
237 | * as it may have been received during scanning long ago) | 237 | * as it may have been received during scanning long ago) |
238 | * @sync_device_ts: the device timestamp corresponding to the sync_tsf, | ||
239 | * the driver/device can use this to calculate synchronisation | ||
238 | * @beacon_int: beacon interval | 240 | * @beacon_int: beacon interval |
239 | * @assoc_capability: capabilities taken from assoc resp | 241 | * @assoc_capability: capabilities taken from assoc resp |
240 | * @basic_rates: bitmap of basic rates, each bit stands for an | 242 | * @basic_rates: bitmap of basic rates, each bit stands for an |
@@ -281,7 +283,8 @@ struct ieee80211_bss_conf { | |||
281 | u8 dtim_period; | 283 | u8 dtim_period; |
282 | u16 beacon_int; | 284 | u16 beacon_int; |
283 | u16 assoc_capability; | 285 | u16 assoc_capability; |
284 | u64 last_tsf; | 286 | u64 sync_tsf; |
287 | u32 sync_device_ts; | ||
285 | u32 basic_rates; | 288 | u32 basic_rates; |
286 | int mcast_rate[IEEE80211_NUM_BANDS]; | 289 | int mcast_rate[IEEE80211_NUM_BANDS]; |
287 | u16 ht_operation_mode; | 290 | u16 ht_operation_mode; |
@@ -696,6 +699,8 @@ enum mac80211_rx_flags { | |||
696 | * | 699 | * |
697 | * @mactime: value in microseconds of the 64-bit Time Synchronization Function | 700 | * @mactime: value in microseconds of the 64-bit Time Synchronization Function |
698 | * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. | 701 | * (TSF) timer when the first data symbol (MPDU) arrived at the hardware. |
702 | * @device_timestamp: arbitrary timestamp for the device, mac80211 doesn't use | ||
703 | * it but can store it and pass it back to the driver for synchronisation | ||
699 | * @band: the active band when this frame was received | 704 | * @band: the active band when this frame was received |
700 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz | 705 | * @freq: frequency the radio was tuned to when receiving this frame, in MHz |
701 | * @signal: signal strength when receiving this frame, either in dBm, in dB or | 706 | * @signal: signal strength when receiving this frame, either in dBm, in dB or |
@@ -709,13 +714,14 @@ enum mac80211_rx_flags { | |||
709 | */ | 714 | */ |
710 | struct ieee80211_rx_status { | 715 | struct ieee80211_rx_status { |
711 | u64 mactime; | 716 | u64 mactime; |
712 | enum ieee80211_band band; | 717 | u32 device_timestamp; |
713 | int freq; | 718 | u16 flag; |
714 | int signal; | 719 | u16 freq; |
715 | int antenna; | 720 | u8 rate_idx; |
716 | int rate_idx; | 721 | u8 rx_flags; |
717 | int flag; | 722 | u8 band; |
718 | unsigned int rx_flags; | 723 | u8 antenna; |
724 | s8 signal; | ||
719 | }; | 725 | }; |
720 | 726 | ||
721 | /** | 727 | /** |
@@ -3592,22 +3598,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif, | |||
3592 | enum ieee80211_smps_mode smps_mode); | 3598 | enum ieee80211_smps_mode smps_mode); |
3593 | 3599 | ||
3594 | /** | 3600 | /** |
3595 | * ieee80211_key_removed - disable hw acceleration for key | ||
3596 | * @key_conf: The key hw acceleration should be disabled for | ||
3597 | * | ||
3598 | * This allows drivers to indicate that the given key has been | ||
3599 | * removed from hardware acceleration, due to a new key that | ||
3600 | * was added. Don't use this if the key can continue to be used | ||
3601 | * for TX, if the key restriction is on RX only it is permitted | ||
3602 | * to keep the key for TX only and not call this function. | ||
3603 | * | ||
3604 | * Due to locking constraints, it may only be called during | ||
3605 | * @set_key. This function must be allowed to sleep, and the | ||
3606 | * key it tries to disable may still be used until it returns. | ||
3607 | */ | ||
3608 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf); | ||
3609 | |||
3610 | /** | ||
3611 | * ieee80211_ready_on_channel - notification of remain-on-channel start | 3601 | * ieee80211_ready_on_channel - notification of remain-on-channel start |
3612 | * @hw: pointer as obtained from ieee80211_alloc_hw() | 3602 | * @hw: pointer as obtained from ieee80211_alloc_hw() |
3613 | */ | 3603 | */ |
diff --git a/include/net/regulatory.h b/include/net/regulatory.h index a5f79933e211..7dcaa2794fde 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h | |||
@@ -52,6 +52,10 @@ enum environment_cap { | |||
52 | * DFS master operation on a known DFS region (NL80211_DFS_*), | 52 | * DFS master operation on a known DFS region (NL80211_DFS_*), |
53 | * dfs_region represents that region. Drivers can use this and the | 53 | * dfs_region represents that region. Drivers can use this and the |
54 | * @alpha2 to adjust their device's DFS parameters as required. | 54 | * @alpha2 to adjust their device's DFS parameters as required. |
55 | * @user_reg_hint_type: if the @initiator was of type | ||
56 | * %NL80211_REGDOM_SET_BY_USER, this classifies the type | ||
57 | * of hint passed. This could be any of the %NL80211_USER_REG_HINT_* | ||
58 | * types. | ||
55 | * @intersect: indicates whether the wireless core should intersect | 59 | * @intersect: indicates whether the wireless core should intersect |
56 | * the requested regulatory domain with the presently set regulatory | 60 | * the requested regulatory domain with the presently set regulatory |
57 | * domain. | 61 | * domain. |
@@ -70,6 +74,7 @@ enum environment_cap { | |||
70 | struct regulatory_request { | 74 | struct regulatory_request { |
71 | int wiphy_idx; | 75 | int wiphy_idx; |
72 | enum nl80211_reg_initiator initiator; | 76 | enum nl80211_reg_initiator initiator; |
77 | enum nl80211_user_reg_hint_type user_reg_hint_type; | ||
73 | char alpha2[2]; | 78 | char alpha2[2]; |
74 | u8 dfs_region; | 79 | u8 dfs_region; |
75 | bool intersect; | 80 | bool intersect; |
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c index fb93250b3938..4ff0bf3ba9a5 100644 --- a/net/bluetooth/a2mp.c +++ b/net/bluetooth/a2mp.c | |||
@@ -501,7 +501,7 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn) | |||
501 | /* AMP Manager functions */ | 501 | /* AMP Manager functions */ |
502 | void amp_mgr_get(struct amp_mgr *mgr) | 502 | void amp_mgr_get(struct amp_mgr *mgr) |
503 | { | 503 | { |
504 | BT_DBG("mgr %p", mgr); | 504 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); |
505 | 505 | ||
506 | kref_get(&mgr->kref); | 506 | kref_get(&mgr->kref); |
507 | } | 507 | } |
@@ -517,7 +517,7 @@ static void amp_mgr_destroy(struct kref *kref) | |||
517 | 517 | ||
518 | int amp_mgr_put(struct amp_mgr *mgr) | 518 | int amp_mgr_put(struct amp_mgr *mgr) |
519 | { | 519 | { |
520 | BT_DBG("mgr %p", mgr); | 520 | BT_DBG("mgr %p orig refcnt %d", mgr, atomic_read(&mgr->kref.refcount)); |
521 | 521 | ||
522 | return kref_put(&mgr->kref, &_mgr_destroy); | 522 | return kref_put(&mgr->kref, &_mgr_destroy); |
523 | } | 523 | } |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 2fcced377e50..5ad7da217474 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -107,7 +107,7 @@ static void hci_acl_connect_cancel(struct hci_conn *conn) | |||
107 | { | 107 | { |
108 | struct hci_cp_create_conn_cancel cp; | 108 | struct hci_cp_create_conn_cancel cp; |
109 | 109 | ||
110 | BT_DBG("%p", conn); | 110 | BT_DBG("hcon %p", conn); |
111 | 111 | ||
112 | if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) | 112 | if (conn->hdev->hci_ver < BLUETOOTH_VER_1_2) |
113 | return; | 113 | return; |
@@ -120,7 +120,7 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | |||
120 | { | 120 | { |
121 | struct hci_cp_disconnect cp; | 121 | struct hci_cp_disconnect cp; |
122 | 122 | ||
123 | BT_DBG("%p", conn); | 123 | BT_DBG("hcon %p", conn); |
124 | 124 | ||
125 | conn->state = BT_DISCONN; | 125 | conn->state = BT_DISCONN; |
126 | 126 | ||
@@ -134,7 +134,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle) | |||
134 | struct hci_dev *hdev = conn->hdev; | 134 | struct hci_dev *hdev = conn->hdev; |
135 | struct hci_cp_add_sco cp; | 135 | struct hci_cp_add_sco cp; |
136 | 136 | ||
137 | BT_DBG("%p", conn); | 137 | BT_DBG("hcon %p", conn); |
138 | 138 | ||
139 | conn->state = BT_CONNECT; | 139 | conn->state = BT_CONNECT; |
140 | conn->out = true; | 140 | conn->out = true; |
@@ -152,7 +152,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle) | |||
152 | struct hci_dev *hdev = conn->hdev; | 152 | struct hci_dev *hdev = conn->hdev; |
153 | struct hci_cp_setup_sync_conn cp; | 153 | struct hci_cp_setup_sync_conn cp; |
154 | 154 | ||
155 | BT_DBG("%p", conn); | 155 | BT_DBG("hcon %p", conn); |
156 | 156 | ||
157 | conn->state = BT_CONNECT; | 157 | conn->state = BT_CONNECT; |
158 | conn->out = true; | 158 | conn->out = true; |
@@ -196,7 +196,7 @@ void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __u8 rand[8], | |||
196 | struct hci_dev *hdev = conn->hdev; | 196 | struct hci_dev *hdev = conn->hdev; |
197 | struct hci_cp_le_start_enc cp; | 197 | struct hci_cp_le_start_enc cp; |
198 | 198 | ||
199 | BT_DBG("%p", conn); | 199 | BT_DBG("hcon %p", conn); |
200 | 200 | ||
201 | memset(&cp, 0, sizeof(cp)); | 201 | memset(&cp, 0, sizeof(cp)); |
202 | 202 | ||
@@ -213,11 +213,11 @@ void hci_sco_setup(struct hci_conn *conn, __u8 status) | |||
213 | { | 213 | { |
214 | struct hci_conn *sco = conn->link; | 214 | struct hci_conn *sco = conn->link; |
215 | 215 | ||
216 | BT_DBG("%p", conn); | ||
217 | |||
218 | if (!sco) | 216 | if (!sco) |
219 | return; | 217 | return; |
220 | 218 | ||
219 | BT_DBG("hcon %p", conn); | ||
220 | |||
221 | if (!status) { | 221 | if (!status) { |
222 | if (lmp_esco_capable(conn->hdev)) | 222 | if (lmp_esco_capable(conn->hdev)) |
223 | hci_setup_sync(sco, conn->handle); | 223 | hci_setup_sync(sco, conn->handle); |
@@ -235,7 +235,7 @@ static void hci_conn_timeout(struct work_struct *work) | |||
235 | disc_work.work); | 235 | disc_work.work); |
236 | __u8 reason; | 236 | __u8 reason; |
237 | 237 | ||
238 | BT_DBG("conn %p state %s", conn, state_to_string(conn->state)); | 238 | BT_DBG("hcon %p state %s", conn, state_to_string(conn->state)); |
239 | 239 | ||
240 | if (atomic_read(&conn->refcnt)) | 240 | if (atomic_read(&conn->refcnt)) |
241 | return; | 241 | return; |
@@ -266,7 +266,7 @@ static void hci_conn_enter_sniff_mode(struct hci_conn *conn) | |||
266 | { | 266 | { |
267 | struct hci_dev *hdev = conn->hdev; | 267 | struct hci_dev *hdev = conn->hdev; |
268 | 268 | ||
269 | BT_DBG("conn %p mode %d", conn, conn->mode); | 269 | BT_DBG("hcon %p mode %d", conn, conn->mode); |
270 | 270 | ||
271 | if (test_bit(HCI_RAW, &hdev->flags)) | 271 | if (test_bit(HCI_RAW, &hdev->flags)) |
272 | return; | 272 | return; |
@@ -301,7 +301,7 @@ static void hci_conn_idle(unsigned long arg) | |||
301 | { | 301 | { |
302 | struct hci_conn *conn = (void *) arg; | 302 | struct hci_conn *conn = (void *) arg; |
303 | 303 | ||
304 | BT_DBG("conn %p mode %d", conn, conn->mode); | 304 | BT_DBG("hcon %p mode %d", conn, conn->mode); |
305 | 305 | ||
306 | hci_conn_enter_sniff_mode(conn); | 306 | hci_conn_enter_sniff_mode(conn); |
307 | } | 307 | } |
@@ -382,7 +382,7 @@ int hci_conn_del(struct hci_conn *conn) | |||
382 | { | 382 | { |
383 | struct hci_dev *hdev = conn->hdev; | 383 | struct hci_dev *hdev = conn->hdev; |
384 | 384 | ||
385 | BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle); | 385 | BT_DBG("%s hcon %p handle %d", hdev->name, conn, conn->handle); |
386 | 386 | ||
387 | del_timer(&conn->idle_timer); | 387 | del_timer(&conn->idle_timer); |
388 | 388 | ||
@@ -442,7 +442,8 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src) | |||
442 | 442 | ||
443 | list_for_each_entry(d, &hci_dev_list, list) { | 443 | list_for_each_entry(d, &hci_dev_list, list) { |
444 | if (!test_bit(HCI_UP, &d->flags) || | 444 | if (!test_bit(HCI_UP, &d->flags) || |
445 | test_bit(HCI_RAW, &d->flags)) | 445 | test_bit(HCI_RAW, &d->flags) || |
446 | d->dev_type != HCI_BREDR) | ||
446 | continue; | 447 | continue; |
447 | 448 | ||
448 | /* Simple routing: | 449 | /* Simple routing: |
@@ -557,7 +558,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, | |||
557 | /* Check link security requirement */ | 558 | /* Check link security requirement */ |
558 | int hci_conn_check_link_mode(struct hci_conn *conn) | 559 | int hci_conn_check_link_mode(struct hci_conn *conn) |
559 | { | 560 | { |
560 | BT_DBG("conn %p", conn); | 561 | BT_DBG("hcon %p", conn); |
561 | 562 | ||
562 | if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) | 563 | if (hci_conn_ssp_enabled(conn) && !(conn->link_mode & HCI_LM_ENCRYPT)) |
563 | return 0; | 564 | return 0; |
@@ -568,7 +569,7 @@ int hci_conn_check_link_mode(struct hci_conn *conn) | |||
568 | /* Authenticate remote device */ | 569 | /* Authenticate remote device */ |
569 | static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | 570 | static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
570 | { | 571 | { |
571 | BT_DBG("conn %p", conn); | 572 | BT_DBG("hcon %p", conn); |
572 | 573 | ||
573 | if (conn->pending_sec_level > sec_level) | 574 | if (conn->pending_sec_level > sec_level) |
574 | sec_level = conn->pending_sec_level; | 575 | sec_level = conn->pending_sec_level; |
@@ -602,7 +603,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
602 | /* Encrypt the the link */ | 603 | /* Encrypt the the link */ |
603 | static void hci_conn_encrypt(struct hci_conn *conn) | 604 | static void hci_conn_encrypt(struct hci_conn *conn) |
604 | { | 605 | { |
605 | BT_DBG("conn %p", conn); | 606 | BT_DBG("hcon %p", conn); |
606 | 607 | ||
607 | if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { | 608 | if (!test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) { |
608 | struct hci_cp_set_conn_encrypt cp; | 609 | struct hci_cp_set_conn_encrypt cp; |
@@ -616,7 +617,7 @@ static void hci_conn_encrypt(struct hci_conn *conn) | |||
616 | /* Enable security */ | 617 | /* Enable security */ |
617 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | 618 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) |
618 | { | 619 | { |
619 | BT_DBG("conn %p", conn); | 620 | BT_DBG("hcon %p", conn); |
620 | 621 | ||
621 | /* For sdp we don't need the link key. */ | 622 | /* For sdp we don't need the link key. */ |
622 | if (sec_level == BT_SECURITY_SDP) | 623 | if (sec_level == BT_SECURITY_SDP) |
@@ -669,7 +670,7 @@ EXPORT_SYMBOL(hci_conn_security); | |||
669 | /* Check secure link requirement */ | 670 | /* Check secure link requirement */ |
670 | int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) | 671 | int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level) |
671 | { | 672 | { |
672 | BT_DBG("conn %p", conn); | 673 | BT_DBG("hcon %p", conn); |
673 | 674 | ||
674 | if (sec_level != BT_SECURITY_HIGH) | 675 | if (sec_level != BT_SECURITY_HIGH) |
675 | return 1; /* Accept if non-secure is required */ | 676 | return 1; /* Accept if non-secure is required */ |
@@ -684,7 +685,7 @@ EXPORT_SYMBOL(hci_conn_check_secure); | |||
684 | /* Change link key */ | 685 | /* Change link key */ |
685 | int hci_conn_change_link_key(struct hci_conn *conn) | 686 | int hci_conn_change_link_key(struct hci_conn *conn) |
686 | { | 687 | { |
687 | BT_DBG("conn %p", conn); | 688 | BT_DBG("hcon %p", conn); |
688 | 689 | ||
689 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { | 690 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { |
690 | struct hci_cp_change_conn_link_key cp; | 691 | struct hci_cp_change_conn_link_key cp; |
@@ -699,7 +700,7 @@ int hci_conn_change_link_key(struct hci_conn *conn) | |||
699 | /* Switch role */ | 700 | /* Switch role */ |
700 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role) | 701 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role) |
701 | { | 702 | { |
702 | BT_DBG("conn %p", conn); | 703 | BT_DBG("hcon %p", conn); |
703 | 704 | ||
704 | if (!role && conn->link_mode & HCI_LM_MASTER) | 705 | if (!role && conn->link_mode & HCI_LM_MASTER) |
705 | return 1; | 706 | return 1; |
@@ -720,7 +721,7 @@ void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active) | |||
720 | { | 721 | { |
721 | struct hci_dev *hdev = conn->hdev; | 722 | struct hci_dev *hdev = conn->hdev; |
722 | 723 | ||
723 | BT_DBG("conn %p mode %d", conn, conn->mode); | 724 | BT_DBG("hcon %p mode %d", conn, conn->mode); |
724 | 725 | ||
725 | if (test_bit(HCI_RAW, &hdev->flags)) | 726 | if (test_bit(HCI_RAW, &hdev->flags)) |
726 | return; | 727 | return; |
@@ -894,7 +895,7 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) | |||
894 | struct hci_dev *hdev = conn->hdev; | 895 | struct hci_dev *hdev = conn->hdev; |
895 | struct hci_chan *chan; | 896 | struct hci_chan *chan; |
896 | 897 | ||
897 | BT_DBG("%s conn %p", hdev->name, conn); | 898 | BT_DBG("%s hcon %p", hdev->name, conn); |
898 | 899 | ||
899 | chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); | 900 | chan = kzalloc(sizeof(struct hci_chan), GFP_KERNEL); |
900 | if (!chan) | 901 | if (!chan) |
@@ -913,7 +914,7 @@ int hci_chan_del(struct hci_chan *chan) | |||
913 | struct hci_conn *conn = chan->conn; | 914 | struct hci_conn *conn = chan->conn; |
914 | struct hci_dev *hdev = conn->hdev; | 915 | struct hci_dev *hdev = conn->hdev; |
915 | 916 | ||
916 | BT_DBG("%s conn %p chan %p", hdev->name, conn, chan); | 917 | BT_DBG("%s hcon %p chan %p", hdev->name, conn, chan); |
917 | 918 | ||
918 | list_del_rcu(&chan->list); | 919 | list_del_rcu(&chan->list); |
919 | 920 | ||
@@ -929,7 +930,7 @@ void hci_chan_list_flush(struct hci_conn *conn) | |||
929 | { | 930 | { |
930 | struct hci_chan *chan, *n; | 931 | struct hci_chan *chan, *n; |
931 | 932 | ||
932 | BT_DBG("conn %p", conn); | 933 | BT_DBG("hcon %p", conn); |
933 | 934 | ||
934 | list_for_each_entry_safe(chan, n, &conn->chan_list, list) | 935 | list_for_each_entry_safe(chan, n, &conn->chan_list, list) |
935 | hci_chan_del(chan); | 936 | hci_chan_del(chan); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 08994ecc3b6a..d4de5db18d5a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -33,8 +33,6 @@ | |||
33 | #include <net/bluetooth/bluetooth.h> | 33 | #include <net/bluetooth/bluetooth.h> |
34 | #include <net/bluetooth/hci_core.h> | 34 | #include <net/bluetooth/hci_core.h> |
35 | 35 | ||
36 | #define AUTO_OFF_TIMEOUT 2000 | ||
37 | |||
38 | static void hci_rx_work(struct work_struct *work); | 36 | static void hci_rx_work(struct work_struct *work); |
39 | static void hci_cmd_work(struct work_struct *work); | 37 | static void hci_cmd_work(struct work_struct *work); |
40 | static void hci_tx_work(struct work_struct *work); | 38 | static void hci_tx_work(struct work_struct *work); |
@@ -61,7 +59,7 @@ static void hci_notify(struct hci_dev *hdev, int event) | |||
61 | 59 | ||
62 | void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) | 60 | void hci_req_complete(struct hci_dev *hdev, __u16 cmd, int result) |
63 | { | 61 | { |
64 | BT_DBG("%s command 0x%04x result 0x%2.2x", hdev->name, cmd, result); | 62 | BT_DBG("%s command 0x%4.4x result 0x%2.2x", hdev->name, cmd, result); |
65 | 63 | ||
66 | /* If this is the init phase check if the completed command matches | 64 | /* If this is the init phase check if the completed command matches |
67 | * the last init command, and if not just return. | 65 | * the last init command, and if not just return. |
@@ -188,12 +186,6 @@ static void bredr_init(struct hci_dev *hdev) | |||
188 | 186 | ||
189 | /* Mandatory initialization */ | 187 | /* Mandatory initialization */ |
190 | 188 | ||
191 | /* Reset */ | ||
192 | if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { | ||
193 | set_bit(HCI_RESET, &hdev->flags); | ||
194 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); | ||
195 | } | ||
196 | |||
197 | /* Read Local Supported Features */ | 189 | /* Read Local Supported Features */ |
198 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); | 190 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_FEATURES, 0, NULL); |
199 | 191 | ||
@@ -234,9 +226,6 @@ static void amp_init(struct hci_dev *hdev) | |||
234 | { | 226 | { |
235 | hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; | 227 | hdev->flow_ctl_mode = HCI_FLOW_CTL_MODE_BLOCK_BASED; |
236 | 228 | ||
237 | /* Reset */ | ||
238 | hci_send_cmd(hdev, HCI_OP_RESET, 0, NULL); | ||
239 | |||
240 | /* Read Local Version */ | 229 | /* Read Local Version */ |
241 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); | 230 | hci_send_cmd(hdev, HCI_OP_READ_LOCAL_VERSION, 0, NULL); |
242 | 231 | ||
@@ -262,6 +251,10 @@ static void hci_init_req(struct hci_dev *hdev, unsigned long opt) | |||
262 | } | 251 | } |
263 | skb_queue_purge(&hdev->driver_init); | 252 | skb_queue_purge(&hdev->driver_init); |
264 | 253 | ||
254 | /* Reset */ | ||
255 | if (!test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) | ||
256 | hci_reset_req(hdev, 0); | ||
257 | |||
265 | switch (hdev->dev_type) { | 258 | switch (hdev->dev_type) { |
266 | case HCI_BREDR: | 259 | case HCI_BREDR: |
267 | bredr_init(hdev); | 260 | bredr_init(hdev); |
@@ -690,12 +683,11 @@ int hci_dev_open(__u16 dev) | |||
690 | set_bit(HCI_INIT, &hdev->flags); | 683 | set_bit(HCI_INIT, &hdev->flags); |
691 | hdev->init_last_cmd = 0; | 684 | hdev->init_last_cmd = 0; |
692 | 685 | ||
693 | ret = __hci_request(hdev, hci_init_req, 0, | 686 | ret = __hci_request(hdev, hci_init_req, 0, HCI_INIT_TIMEOUT); |
694 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
695 | 687 | ||
696 | if (lmp_host_le_capable(hdev)) | 688 | if (lmp_host_le_capable(hdev)) |
697 | ret = __hci_request(hdev, hci_le_init_req, 0, | 689 | ret = __hci_request(hdev, hci_le_init_req, 0, |
698 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 690 | HCI_INIT_TIMEOUT); |
699 | 691 | ||
700 | clear_bit(HCI_INIT, &hdev->flags); | 692 | clear_bit(HCI_INIT, &hdev->flags); |
701 | } | 693 | } |
@@ -782,8 +774,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
782 | if (!test_bit(HCI_RAW, &hdev->flags) && | 774 | if (!test_bit(HCI_RAW, &hdev->flags) && |
783 | test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { | 775 | test_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks)) { |
784 | set_bit(HCI_INIT, &hdev->flags); | 776 | set_bit(HCI_INIT, &hdev->flags); |
785 | __hci_request(hdev, hci_reset_req, 0, | 777 | __hci_request(hdev, hci_reset_req, 0, HCI_CMD_TIMEOUT); |
786 | msecs_to_jiffies(250)); | ||
787 | clear_bit(HCI_INIT, &hdev->flags); | 778 | clear_bit(HCI_INIT, &hdev->flags); |
788 | } | 779 | } |
789 | 780 | ||
@@ -872,8 +863,7 @@ int hci_dev_reset(__u16 dev) | |||
872 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; | 863 | hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0; |
873 | 864 | ||
874 | if (!test_bit(HCI_RAW, &hdev->flags)) | 865 | if (!test_bit(HCI_RAW, &hdev->flags)) |
875 | ret = __hci_request(hdev, hci_reset_req, 0, | 866 | ret = __hci_request(hdev, hci_reset_req, 0, HCI_INIT_TIMEOUT); |
876 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | ||
877 | 867 | ||
878 | done: | 868 | done: |
879 | hci_req_unlock(hdev); | 869 | hci_req_unlock(hdev); |
@@ -913,7 +903,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
913 | switch (cmd) { | 903 | switch (cmd) { |
914 | case HCISETAUTH: | 904 | case HCISETAUTH: |
915 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, | 905 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, |
916 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 906 | HCI_INIT_TIMEOUT); |
917 | break; | 907 | break; |
918 | 908 | ||
919 | case HCISETENCRYPT: | 909 | case HCISETENCRYPT: |
@@ -925,23 +915,23 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg) | |||
925 | if (!test_bit(HCI_AUTH, &hdev->flags)) { | 915 | if (!test_bit(HCI_AUTH, &hdev->flags)) { |
926 | /* Auth must be enabled first */ | 916 | /* Auth must be enabled first */ |
927 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, | 917 | err = hci_request(hdev, hci_auth_req, dr.dev_opt, |
928 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 918 | HCI_INIT_TIMEOUT); |
929 | if (err) | 919 | if (err) |
930 | break; | 920 | break; |
931 | } | 921 | } |
932 | 922 | ||
933 | err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, | 923 | err = hci_request(hdev, hci_encrypt_req, dr.dev_opt, |
934 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 924 | HCI_INIT_TIMEOUT); |
935 | break; | 925 | break; |
936 | 926 | ||
937 | case HCISETSCAN: | 927 | case HCISETSCAN: |
938 | err = hci_request(hdev, hci_scan_req, dr.dev_opt, | 928 | err = hci_request(hdev, hci_scan_req, dr.dev_opt, |
939 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 929 | HCI_INIT_TIMEOUT); |
940 | break; | 930 | break; |
941 | 931 | ||
942 | case HCISETLINKPOL: | 932 | case HCISETLINKPOL: |
943 | err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, | 933 | err = hci_request(hdev, hci_linkpol_req, dr.dev_opt, |
944 | msecs_to_jiffies(HCI_INIT_TIMEOUT)); | 934 | HCI_INIT_TIMEOUT); |
945 | break; | 935 | break; |
946 | 936 | ||
947 | case HCISETLINKMODE: | 937 | case HCISETLINKMODE: |
@@ -1091,8 +1081,7 @@ static void hci_power_on(struct work_struct *work) | |||
1091 | return; | 1081 | return; |
1092 | 1082 | ||
1093 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | 1083 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) |
1094 | schedule_delayed_work(&hdev->power_off, | 1084 | schedule_delayed_work(&hdev->power_off, HCI_AUTO_OFF_TIMEOUT); |
1095 | msecs_to_jiffies(AUTO_OFF_TIMEOUT)); | ||
1096 | 1085 | ||
1097 | if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) | 1086 | if (test_and_clear_bit(HCI_SETUP, &hdev->dev_flags)) |
1098 | mgmt_index_added(hdev); | 1087 | mgmt_index_added(hdev); |
@@ -1369,11 +1358,19 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr) | |||
1369 | } | 1358 | } |
1370 | 1359 | ||
1371 | /* HCI command timer function */ | 1360 | /* HCI command timer function */ |
1372 | static void hci_cmd_timer(unsigned long arg) | 1361 | static void hci_cmd_timeout(unsigned long arg) |
1373 | { | 1362 | { |
1374 | struct hci_dev *hdev = (void *) arg; | 1363 | struct hci_dev *hdev = (void *) arg; |
1375 | 1364 | ||
1376 | BT_ERR("%s command tx timeout", hdev->name); | 1365 | if (hdev->sent_cmd) { |
1366 | struct hci_command_hdr *sent = (void *) hdev->sent_cmd->data; | ||
1367 | u16 opcode = __le16_to_cpu(sent->opcode); | ||
1368 | |||
1369 | BT_ERR("%s command 0x%4.4x tx timeout", hdev->name, opcode); | ||
1370 | } else { | ||
1371 | BT_ERR("%s command tx timeout", hdev->name); | ||
1372 | } | ||
1373 | |||
1377 | atomic_set(&hdev->cmd_cnt, 1); | 1374 | atomic_set(&hdev->cmd_cnt, 1); |
1378 | queue_work(hdev->workqueue, &hdev->cmd_work); | 1375 | queue_work(hdev->workqueue, &hdev->cmd_work); |
1379 | } | 1376 | } |
@@ -1671,7 +1668,7 @@ struct hci_dev *hci_alloc_dev(void) | |||
1671 | 1668 | ||
1672 | init_waitqueue_head(&hdev->req_wait_q); | 1669 | init_waitqueue_head(&hdev->req_wait_q); |
1673 | 1670 | ||
1674 | setup_timer(&hdev->cmd_timer, hci_cmd_timer, (unsigned long) hdev); | 1671 | setup_timer(&hdev->cmd_timer, hci_cmd_timeout, (unsigned long) hdev); |
1675 | 1672 | ||
1676 | hci_init_sysfs(hdev); | 1673 | hci_init_sysfs(hdev); |
1677 | discovery_init(hdev); | 1674 | discovery_init(hdev); |
@@ -1746,8 +1743,11 @@ int hci_register_dev(struct hci_dev *hdev) | |||
1746 | } | 1743 | } |
1747 | } | 1744 | } |
1748 | 1745 | ||
1749 | set_bit(HCI_AUTO_OFF, &hdev->dev_flags); | ||
1750 | set_bit(HCI_SETUP, &hdev->dev_flags); | 1746 | set_bit(HCI_SETUP, &hdev->dev_flags); |
1747 | |||
1748 | if (hdev->dev_type != HCI_AMP) | ||
1749 | set_bit(HCI_AUTO_OFF, &hdev->dev_flags); | ||
1750 | |||
1751 | schedule_work(&hdev->power_on); | 1751 | schedule_work(&hdev->power_on); |
1752 | 1752 | ||
1753 | hci_notify(hdev, HCI_DEV_REG); | 1753 | hci_notify(hdev, HCI_DEV_REG); |
@@ -2087,7 +2087,7 @@ int hci_send_cmd(struct hci_dev *hdev, __u16 opcode, __u32 plen, void *param) | |||
2087 | struct hci_command_hdr *hdr; | 2087 | struct hci_command_hdr *hdr; |
2088 | struct sk_buff *skb; | 2088 | struct sk_buff *skb; |
2089 | 2089 | ||
2090 | BT_DBG("%s opcode 0x%x plen %d", hdev->name, opcode, plen); | 2090 | BT_DBG("%s opcode 0x%4.4x plen %d", hdev->name, opcode, plen); |
2091 | 2091 | ||
2092 | skb = bt_skb_alloc(len, GFP_ATOMIC); | 2092 | skb = bt_skb_alloc(len, GFP_ATOMIC); |
2093 | if (!skb) { | 2093 | if (!skb) { |
@@ -2129,7 +2129,7 @@ void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode) | |||
2129 | if (hdr->opcode != cpu_to_le16(opcode)) | 2129 | if (hdr->opcode != cpu_to_le16(opcode)) |
2130 | return NULL; | 2130 | return NULL; |
2131 | 2131 | ||
2132 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 2132 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2133 | 2133 | ||
2134 | return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; | 2134 | return hdev->sent_cmd->data + HCI_COMMAND_HDR_SIZE; |
2135 | } | 2135 | } |
@@ -2199,7 +2199,7 @@ void hci_send_acl(struct hci_chan *chan, struct sk_buff *skb, __u16 flags) | |||
2199 | struct hci_conn *conn = chan->conn; | 2199 | struct hci_conn *conn = chan->conn; |
2200 | struct hci_dev *hdev = conn->hdev; | 2200 | struct hci_dev *hdev = conn->hdev; |
2201 | 2201 | ||
2202 | BT_DBG("%s chan %p flags 0x%x", hdev->name, chan, flags); | 2202 | BT_DBG("%s chan %p flags 0x%4.4x", hdev->name, chan, flags); |
2203 | 2203 | ||
2204 | skb->dev = (void *) hdev; | 2204 | skb->dev = (void *) hdev; |
2205 | 2205 | ||
@@ -2455,7 +2455,7 @@ static void __check_timeout(struct hci_dev *hdev, unsigned int cnt) | |||
2455 | /* ACL tx timeout must be longer than maximum | 2455 | /* ACL tx timeout must be longer than maximum |
2456 | * link supervision timeout (40.9 seconds) */ | 2456 | * link supervision timeout (40.9 seconds) */ |
2457 | if (!cnt && time_after(jiffies, hdev->acl_last_tx + | 2457 | if (!cnt && time_after(jiffies, hdev->acl_last_tx + |
2458 | msecs_to_jiffies(HCI_ACL_TX_TIMEOUT))) | 2458 | HCI_ACL_TX_TIMEOUT)) |
2459 | hci_link_tx_to(hdev, ACL_LINK); | 2459 | hci_link_tx_to(hdev, ACL_LINK); |
2460 | } | 2460 | } |
2461 | } | 2461 | } |
@@ -2699,7 +2699,7 @@ static void hci_acldata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2699 | flags = hci_flags(handle); | 2699 | flags = hci_flags(handle); |
2700 | handle = hci_handle(handle); | 2700 | handle = hci_handle(handle); |
2701 | 2701 | ||
2702 | BT_DBG("%s len %d handle 0x%x flags 0x%x", hdev->name, skb->len, | 2702 | BT_DBG("%s len %d handle 0x%4.4x flags 0x%4.4x", hdev->name, skb->len, |
2703 | handle, flags); | 2703 | handle, flags); |
2704 | 2704 | ||
2705 | hdev->stat.acl_rx++; | 2705 | hdev->stat.acl_rx++; |
@@ -2741,7 +2741,7 @@ static void hci_scodata_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2741 | 2741 | ||
2742 | handle = __le16_to_cpu(hdr->handle); | 2742 | handle = __le16_to_cpu(hdr->handle); |
2743 | 2743 | ||
2744 | BT_DBG("%s len %d handle 0x%x", hdev->name, skb->len, handle); | 2744 | BT_DBG("%s len %d handle 0x%4.4x", hdev->name, skb->len, handle); |
2745 | 2745 | ||
2746 | hdev->stat.sco_rx++; | 2746 | hdev->stat.sco_rx++; |
2747 | 2747 | ||
@@ -2821,7 +2821,8 @@ static void hci_cmd_work(struct work_struct *work) | |||
2821 | struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); | 2821 | struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_work); |
2822 | struct sk_buff *skb; | 2822 | struct sk_buff *skb; |
2823 | 2823 | ||
2824 | BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt)); | 2824 | BT_DBG("%s cmd_cnt %d cmd queued %d", hdev->name, |
2825 | atomic_read(&hdev->cmd_cnt), skb_queue_len(&hdev->cmd_q)); | ||
2825 | 2826 | ||
2826 | /* Send queued commands */ | 2827 | /* Send queued commands */ |
2827 | if (atomic_read(&hdev->cmd_cnt)) { | 2828 | if (atomic_read(&hdev->cmd_cnt)) { |
@@ -2839,7 +2840,7 @@ static void hci_cmd_work(struct work_struct *work) | |||
2839 | del_timer(&hdev->cmd_timer); | 2840 | del_timer(&hdev->cmd_timer); |
2840 | else | 2841 | else |
2841 | mod_timer(&hdev->cmd_timer, | 2842 | mod_timer(&hdev->cmd_timer, |
2842 | jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT)); | 2843 | jiffies + HCI_CMD_TIMEOUT); |
2843 | } else { | 2844 | } else { |
2844 | skb_queue_head(&hdev->cmd_q, skb); | 2845 | skb_queue_head(&hdev->cmd_q, skb); |
2845 | queue_work(hdev->workqueue, &hdev->cmd_work); | 2846 | queue_work(hdev->workqueue, &hdev->cmd_work); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 1ba929c05d0d..41ff978a33f9 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -36,7 +36,7 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
36 | { | 36 | { |
37 | __u8 status = *((__u8 *) skb->data); | 37 | __u8 status = *((__u8 *) skb->data); |
38 | 38 | ||
39 | BT_DBG("%s status 0x%x", hdev->name, status); | 39 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
40 | 40 | ||
41 | if (status) { | 41 | if (status) { |
42 | hci_dev_lock(hdev); | 42 | hci_dev_lock(hdev); |
@@ -60,7 +60,7 @@ static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
60 | { | 60 | { |
61 | __u8 status = *((__u8 *) skb->data); | 61 | __u8 status = *((__u8 *) skb->data); |
62 | 62 | ||
63 | BT_DBG("%s status 0x%x", hdev->name, status); | 63 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
64 | 64 | ||
65 | if (status) | 65 | if (status) |
66 | return; | 66 | return; |
@@ -72,7 +72,7 @@ static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb) | |||
72 | { | 72 | { |
73 | __u8 status = *((__u8 *) skb->data); | 73 | __u8 status = *((__u8 *) skb->data); |
74 | 74 | ||
75 | BT_DBG("%s status 0x%x", hdev->name, status); | 75 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
76 | 76 | ||
77 | if (status) | 77 | if (status) |
78 | return; | 78 | return; |
@@ -93,7 +93,7 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) | |||
93 | struct hci_rp_role_discovery *rp = (void *) skb->data; | 93 | struct hci_rp_role_discovery *rp = (void *) skb->data; |
94 | struct hci_conn *conn; | 94 | struct hci_conn *conn; |
95 | 95 | ||
96 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 96 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
97 | 97 | ||
98 | if (rp->status) | 98 | if (rp->status) |
99 | return; | 99 | return; |
@@ -116,7 +116,7 @@ static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | |||
116 | struct hci_rp_read_link_policy *rp = (void *) skb->data; | 116 | struct hci_rp_read_link_policy *rp = (void *) skb->data; |
117 | struct hci_conn *conn; | 117 | struct hci_conn *conn; |
118 | 118 | ||
119 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 119 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
120 | 120 | ||
121 | if (rp->status) | 121 | if (rp->status) |
122 | return; | 122 | return; |
@@ -136,7 +136,7 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | |||
136 | struct hci_conn *conn; | 136 | struct hci_conn *conn; |
137 | void *sent; | 137 | void *sent; |
138 | 138 | ||
139 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 139 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
140 | 140 | ||
141 | if (rp->status) | 141 | if (rp->status) |
142 | return; | 142 | return; |
@@ -159,7 +159,7 @@ static void hci_cc_read_def_link_policy(struct hci_dev *hdev, | |||
159 | { | 159 | { |
160 | struct hci_rp_read_def_link_policy *rp = (void *) skb->data; | 160 | struct hci_rp_read_def_link_policy *rp = (void *) skb->data; |
161 | 161 | ||
162 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 162 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
163 | 163 | ||
164 | if (rp->status) | 164 | if (rp->status) |
165 | return; | 165 | return; |
@@ -173,7 +173,7 @@ static void hci_cc_write_def_link_policy(struct hci_dev *hdev, | |||
173 | __u8 status = *((__u8 *) skb->data); | 173 | __u8 status = *((__u8 *) skb->data); |
174 | void *sent; | 174 | void *sent; |
175 | 175 | ||
176 | BT_DBG("%s status 0x%x", hdev->name, status); | 176 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
177 | 177 | ||
178 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); | 178 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); |
179 | if (!sent) | 179 | if (!sent) |
@@ -189,7 +189,7 @@ static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | |||
189 | { | 189 | { |
190 | __u8 status = *((__u8 *) skb->data); | 190 | __u8 status = *((__u8 *) skb->data); |
191 | 191 | ||
192 | BT_DBG("%s status 0x%x", hdev->name, status); | 192 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
193 | 193 | ||
194 | clear_bit(HCI_RESET, &hdev->flags); | 194 | clear_bit(HCI_RESET, &hdev->flags); |
195 | 195 | ||
@@ -207,7 +207,7 @@ static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
207 | __u8 status = *((__u8 *) skb->data); | 207 | __u8 status = *((__u8 *) skb->data); |
208 | void *sent; | 208 | void *sent; |
209 | 209 | ||
210 | BT_DBG("%s status 0x%x", hdev->name, status); | 210 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
211 | 211 | ||
212 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); | 212 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME); |
213 | if (!sent) | 213 | if (!sent) |
@@ -229,7 +229,7 @@ static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb) | |||
229 | { | 229 | { |
230 | struct hci_rp_read_local_name *rp = (void *) skb->data; | 230 | struct hci_rp_read_local_name *rp = (void *) skb->data; |
231 | 231 | ||
232 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 232 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
233 | 233 | ||
234 | if (rp->status) | 234 | if (rp->status) |
235 | return; | 235 | return; |
@@ -243,7 +243,7 @@ static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
243 | __u8 status = *((__u8 *) skb->data); | 243 | __u8 status = *((__u8 *) skb->data); |
244 | void *sent; | 244 | void *sent; |
245 | 245 | ||
246 | BT_DBG("%s status 0x%x", hdev->name, status); | 246 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
247 | 247 | ||
248 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); | 248 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE); |
249 | if (!sent) | 249 | if (!sent) |
@@ -269,7 +269,7 @@ static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
269 | __u8 status = *((__u8 *) skb->data); | 269 | __u8 status = *((__u8 *) skb->data); |
270 | void *sent; | 270 | void *sent; |
271 | 271 | ||
272 | BT_DBG("%s status 0x%x", hdev->name, status); | 272 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
273 | 273 | ||
274 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); | 274 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE); |
275 | if (!sent) | 275 | if (!sent) |
@@ -293,7 +293,7 @@ static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
293 | int old_pscan, old_iscan; | 293 | int old_pscan, old_iscan; |
294 | void *sent; | 294 | void *sent; |
295 | 295 | ||
296 | BT_DBG("%s status 0x%x", hdev->name, status); | 296 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
297 | 297 | ||
298 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); | 298 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE); |
299 | if (!sent) | 299 | if (!sent) |
@@ -340,7 +340,7 @@ static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) | |||
340 | { | 340 | { |
341 | struct hci_rp_read_class_of_dev *rp = (void *) skb->data; | 341 | struct hci_rp_read_class_of_dev *rp = (void *) skb->data; |
342 | 342 | ||
343 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 343 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
344 | 344 | ||
345 | if (rp->status) | 345 | if (rp->status) |
346 | return; | 346 | return; |
@@ -356,7 +356,7 @@ static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb) | |||
356 | __u8 status = *((__u8 *) skb->data); | 356 | __u8 status = *((__u8 *) skb->data); |
357 | void *sent; | 357 | void *sent; |
358 | 358 | ||
359 | BT_DBG("%s status 0x%x", hdev->name, status); | 359 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
360 | 360 | ||
361 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); | 361 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV); |
362 | if (!sent) | 362 | if (!sent) |
@@ -378,7 +378,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) | |||
378 | struct hci_rp_read_voice_setting *rp = (void *) skb->data; | 378 | struct hci_rp_read_voice_setting *rp = (void *) skb->data; |
379 | __u16 setting; | 379 | __u16 setting; |
380 | 380 | ||
381 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 381 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
382 | 382 | ||
383 | if (rp->status) | 383 | if (rp->status) |
384 | return; | 384 | return; |
@@ -390,7 +390,7 @@ static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb) | |||
390 | 390 | ||
391 | hdev->voice_setting = setting; | 391 | hdev->voice_setting = setting; |
392 | 392 | ||
393 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); | 393 | BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); |
394 | 394 | ||
395 | if (hdev->notify) | 395 | if (hdev->notify) |
396 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); | 396 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); |
@@ -403,7 +403,7 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, | |||
403 | __u16 setting; | 403 | __u16 setting; |
404 | void *sent; | 404 | void *sent; |
405 | 405 | ||
406 | BT_DBG("%s status 0x%x", hdev->name, status); | 406 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
407 | 407 | ||
408 | if (status) | 408 | if (status) |
409 | return; | 409 | return; |
@@ -419,7 +419,7 @@ static void hci_cc_write_voice_setting(struct hci_dev *hdev, | |||
419 | 419 | ||
420 | hdev->voice_setting = setting; | 420 | hdev->voice_setting = setting; |
421 | 421 | ||
422 | BT_DBG("%s voice setting 0x%04x", hdev->name, setting); | 422 | BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting); |
423 | 423 | ||
424 | if (hdev->notify) | 424 | if (hdev->notify) |
425 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); | 425 | hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING); |
@@ -429,7 +429,7 @@ static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | |||
429 | { | 429 | { |
430 | __u8 status = *((__u8 *) skb->data); | 430 | __u8 status = *((__u8 *) skb->data); |
431 | 431 | ||
432 | BT_DBG("%s status 0x%x", hdev->name, status); | 432 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
433 | 433 | ||
434 | hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); | 434 | hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status); |
435 | } | 435 | } |
@@ -439,7 +439,7 @@ static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb) | |||
439 | __u8 status = *((__u8 *) skb->data); | 439 | __u8 status = *((__u8 *) skb->data); |
440 | void *sent; | 440 | void *sent; |
441 | 441 | ||
442 | BT_DBG("%s status 0x%x", hdev->name, status); | 442 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
443 | 443 | ||
444 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); | 444 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE); |
445 | if (!sent) | 445 | if (!sent) |
@@ -597,7 +597,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
597 | { | 597 | { |
598 | struct hci_rp_read_local_version *rp = (void *) skb->data; | 598 | struct hci_rp_read_local_version *rp = (void *) skb->data; |
599 | 599 | ||
600 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 600 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
601 | 601 | ||
602 | if (rp->status) | 602 | if (rp->status) |
603 | goto done; | 603 | goto done; |
@@ -608,7 +608,7 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
608 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); | 608 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); |
609 | hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); | 609 | hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver); |
610 | 610 | ||
611 | BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, | 611 | BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name, |
612 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); | 612 | hdev->manufacturer, hdev->hci_ver, hdev->hci_rev); |
613 | 613 | ||
614 | if (test_bit(HCI_INIT, &hdev->flags)) | 614 | if (test_bit(HCI_INIT, &hdev->flags)) |
@@ -641,7 +641,7 @@ static void hci_cc_read_local_commands(struct hci_dev *hdev, | |||
641 | { | 641 | { |
642 | struct hci_rp_read_local_commands *rp = (void *) skb->data; | 642 | struct hci_rp_read_local_commands *rp = (void *) skb->data; |
643 | 643 | ||
644 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 644 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
645 | 645 | ||
646 | if (rp->status) | 646 | if (rp->status) |
647 | goto done; | 647 | goto done; |
@@ -660,7 +660,7 @@ static void hci_cc_read_local_features(struct hci_dev *hdev, | |||
660 | { | 660 | { |
661 | struct hci_rp_read_local_features *rp = (void *) skb->data; | 661 | struct hci_rp_read_local_features *rp = (void *) skb->data; |
662 | 662 | ||
663 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 663 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
664 | 664 | ||
665 | if (rp->status) | 665 | if (rp->status) |
666 | return; | 666 | return; |
@@ -732,7 +732,7 @@ static void hci_cc_read_local_ext_features(struct hci_dev *hdev, | |||
732 | { | 732 | { |
733 | struct hci_rp_read_local_ext_features *rp = (void *) skb->data; | 733 | struct hci_rp_read_local_ext_features *rp = (void *) skb->data; |
734 | 734 | ||
735 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 735 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
736 | 736 | ||
737 | if (rp->status) | 737 | if (rp->status) |
738 | goto done; | 738 | goto done; |
@@ -758,7 +758,7 @@ static void hci_cc_read_flow_control_mode(struct hci_dev *hdev, | |||
758 | { | 758 | { |
759 | struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; | 759 | struct hci_rp_read_flow_control_mode *rp = (void *) skb->data; |
760 | 760 | ||
761 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 761 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
762 | 762 | ||
763 | if (rp->status) | 763 | if (rp->status) |
764 | return; | 764 | return; |
@@ -772,7 +772,7 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb) | |||
772 | { | 772 | { |
773 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; | 773 | struct hci_rp_read_buffer_size *rp = (void *) skb->data; |
774 | 774 | ||
775 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 775 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
776 | 776 | ||
777 | if (rp->status) | 777 | if (rp->status) |
778 | return; | 778 | return; |
@@ -798,7 +798,7 @@ static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb) | |||
798 | { | 798 | { |
799 | struct hci_rp_read_bd_addr *rp = (void *) skb->data; | 799 | struct hci_rp_read_bd_addr *rp = (void *) skb->data; |
800 | 800 | ||
801 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 801 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
802 | 802 | ||
803 | if (!rp->status) | 803 | if (!rp->status) |
804 | bacpy(&hdev->bdaddr, &rp->bdaddr); | 804 | bacpy(&hdev->bdaddr, &rp->bdaddr); |
@@ -811,7 +811,7 @@ static void hci_cc_read_data_block_size(struct hci_dev *hdev, | |||
811 | { | 811 | { |
812 | struct hci_rp_read_data_block_size *rp = (void *) skb->data; | 812 | struct hci_rp_read_data_block_size *rp = (void *) skb->data; |
813 | 813 | ||
814 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 814 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
815 | 815 | ||
816 | if (rp->status) | 816 | if (rp->status) |
817 | return; | 817 | return; |
@@ -832,7 +832,7 @@ static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb) | |||
832 | { | 832 | { |
833 | __u8 status = *((__u8 *) skb->data); | 833 | __u8 status = *((__u8 *) skb->data); |
834 | 834 | ||
835 | BT_DBG("%s status 0x%x", hdev->name, status); | 835 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
836 | 836 | ||
837 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); | 837 | hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status); |
838 | } | 838 | } |
@@ -842,7 +842,7 @@ static void hci_cc_read_local_amp_info(struct hci_dev *hdev, | |||
842 | { | 842 | { |
843 | struct hci_rp_read_local_amp_info *rp = (void *) skb->data; | 843 | struct hci_rp_read_local_amp_info *rp = (void *) skb->data; |
844 | 844 | ||
845 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 845 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
846 | 846 | ||
847 | if (rp->status) | 847 | if (rp->status) |
848 | return; | 848 | return; |
@@ -866,7 +866,7 @@ static void hci_cc_delete_stored_link_key(struct hci_dev *hdev, | |||
866 | { | 866 | { |
867 | __u8 status = *((__u8 *) skb->data); | 867 | __u8 status = *((__u8 *) skb->data); |
868 | 868 | ||
869 | BT_DBG("%s status 0x%x", hdev->name, status); | 869 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
870 | 870 | ||
871 | hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status); | 871 | hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status); |
872 | } | 872 | } |
@@ -875,7 +875,7 @@ static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb) | |||
875 | { | 875 | { |
876 | __u8 status = *((__u8 *) skb->data); | 876 | __u8 status = *((__u8 *) skb->data); |
877 | 877 | ||
878 | BT_DBG("%s status 0x%x", hdev->name, status); | 878 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
879 | 879 | ||
880 | hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status); | 880 | hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status); |
881 | } | 881 | } |
@@ -885,7 +885,7 @@ static void hci_cc_write_inquiry_mode(struct hci_dev *hdev, | |||
885 | { | 885 | { |
886 | __u8 status = *((__u8 *) skb->data); | 886 | __u8 status = *((__u8 *) skb->data); |
887 | 887 | ||
888 | BT_DBG("%s status 0x%x", hdev->name, status); | 888 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
889 | 889 | ||
890 | hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status); | 890 | hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status); |
891 | } | 891 | } |
@@ -895,7 +895,7 @@ static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev, | |||
895 | { | 895 | { |
896 | struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; | 896 | struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data; |
897 | 897 | ||
898 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 898 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
899 | 899 | ||
900 | if (!rp->status) | 900 | if (!rp->status) |
901 | hdev->inq_tx_power = rp->tx_power; | 901 | hdev->inq_tx_power = rp->tx_power; |
@@ -907,7 +907,7 @@ static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb) | |||
907 | { | 907 | { |
908 | __u8 status = *((__u8 *) skb->data); | 908 | __u8 status = *((__u8 *) skb->data); |
909 | 909 | ||
910 | BT_DBG("%s status 0x%x", hdev->name, status); | 910 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
911 | 911 | ||
912 | hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status); | 912 | hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status); |
913 | } | 913 | } |
@@ -918,7 +918,7 @@ static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
918 | struct hci_cp_pin_code_reply *cp; | 918 | struct hci_cp_pin_code_reply *cp; |
919 | struct hci_conn *conn; | 919 | struct hci_conn *conn; |
920 | 920 | ||
921 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 921 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
922 | 922 | ||
923 | hci_dev_lock(hdev); | 923 | hci_dev_lock(hdev); |
924 | 924 | ||
@@ -944,7 +944,7 @@ static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
944 | { | 944 | { |
945 | struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; | 945 | struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data; |
946 | 946 | ||
947 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 947 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
948 | 948 | ||
949 | hci_dev_lock(hdev); | 949 | hci_dev_lock(hdev); |
950 | 950 | ||
@@ -960,7 +960,7 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev, | |||
960 | { | 960 | { |
961 | struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; | 961 | struct hci_rp_le_read_buffer_size *rp = (void *) skb->data; |
962 | 962 | ||
963 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 963 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
964 | 964 | ||
965 | if (rp->status) | 965 | if (rp->status) |
966 | return; | 966 | return; |
@@ -979,7 +979,7 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
979 | { | 979 | { |
980 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | 980 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; |
981 | 981 | ||
982 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 982 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
983 | 983 | ||
984 | hci_dev_lock(hdev); | 984 | hci_dev_lock(hdev); |
985 | 985 | ||
@@ -995,7 +995,7 @@ static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev, | |||
995 | { | 995 | { |
996 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | 996 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; |
997 | 997 | ||
998 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 998 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
999 | 999 | ||
1000 | hci_dev_lock(hdev); | 1000 | hci_dev_lock(hdev); |
1001 | 1001 | ||
@@ -1010,7 +1010,7 @@ static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
1010 | { | 1010 | { |
1011 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | 1011 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; |
1012 | 1012 | ||
1013 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 1013 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1014 | 1014 | ||
1015 | hci_dev_lock(hdev); | 1015 | hci_dev_lock(hdev); |
1016 | 1016 | ||
@@ -1026,7 +1026,7 @@ static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev, | |||
1026 | { | 1026 | { |
1027 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; | 1027 | struct hci_rp_user_confirm_reply *rp = (void *) skb->data; |
1028 | 1028 | ||
1029 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 1029 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1030 | 1030 | ||
1031 | hci_dev_lock(hdev); | 1031 | hci_dev_lock(hdev); |
1032 | 1032 | ||
@@ -1042,7 +1042,7 @@ static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev, | |||
1042 | { | 1042 | { |
1043 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; | 1043 | struct hci_rp_read_local_oob_data *rp = (void *) skb->data; |
1044 | 1044 | ||
1045 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 1045 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1046 | 1046 | ||
1047 | hci_dev_lock(hdev); | 1047 | hci_dev_lock(hdev); |
1048 | mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, | 1048 | mgmt_read_local_oob_data_reply_complete(hdev, rp->hash, |
@@ -1054,7 +1054,7 @@ static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | |||
1054 | { | 1054 | { |
1055 | __u8 status = *((__u8 *) skb->data); | 1055 | __u8 status = *((__u8 *) skb->data); |
1056 | 1056 | ||
1057 | BT_DBG("%s status 0x%x", hdev->name, status); | 1057 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1058 | 1058 | ||
1059 | hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); | 1059 | hci_req_complete(hdev, HCI_OP_LE_SET_SCAN_PARAM, status); |
1060 | 1060 | ||
@@ -1072,7 +1072,7 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
1072 | struct hci_cp_le_set_scan_enable *cp; | 1072 | struct hci_cp_le_set_scan_enable *cp; |
1073 | __u8 status = *((__u8 *) skb->data); | 1073 | __u8 status = *((__u8 *) skb->data); |
1074 | 1074 | ||
1075 | BT_DBG("%s status 0x%x", hdev->name, status); | 1075 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1076 | 1076 | ||
1077 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); | 1077 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE); |
1078 | if (!cp) | 1078 | if (!cp) |
@@ -1127,7 +1127,7 @@ static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
1127 | { | 1127 | { |
1128 | struct hci_rp_le_ltk_reply *rp = (void *) skb->data; | 1128 | struct hci_rp_le_ltk_reply *rp = (void *) skb->data; |
1129 | 1129 | ||
1130 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 1130 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1131 | 1131 | ||
1132 | if (rp->status) | 1132 | if (rp->status) |
1133 | return; | 1133 | return; |
@@ -1139,7 +1139,7 @@ static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb) | |||
1139 | { | 1139 | { |
1140 | struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; | 1140 | struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data; |
1141 | 1141 | ||
1142 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | 1142 | BT_DBG("%s status 0x%2.2x", hdev->name, rp->status); |
1143 | 1143 | ||
1144 | if (rp->status) | 1144 | if (rp->status) |
1145 | return; | 1145 | return; |
@@ -1153,7 +1153,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1153 | struct hci_cp_write_le_host_supported *sent; | 1153 | struct hci_cp_write_le_host_supported *sent; |
1154 | __u8 status = *((__u8 *) skb->data); | 1154 | __u8 status = *((__u8 *) skb->data); |
1155 | 1155 | ||
1156 | BT_DBG("%s status 0x%x", hdev->name, status); | 1156 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1157 | 1157 | ||
1158 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); | 1158 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED); |
1159 | if (!sent) | 1159 | if (!sent) |
@@ -1175,7 +1175,7 @@ static void hci_cc_write_le_host_supported(struct hci_dev *hdev, | |||
1175 | 1175 | ||
1176 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | 1176 | static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) |
1177 | { | 1177 | { |
1178 | BT_DBG("%s status 0x%x", hdev->name, status); | 1178 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1179 | 1179 | ||
1180 | if (status) { | 1180 | if (status) { |
1181 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1181 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
@@ -1199,7 +1199,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
1199 | struct hci_cp_create_conn *cp; | 1199 | struct hci_cp_create_conn *cp; |
1200 | struct hci_conn *conn; | 1200 | struct hci_conn *conn; |
1201 | 1201 | ||
1202 | BT_DBG("%s status 0x%x", hdev->name, status); | 1202 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1203 | 1203 | ||
1204 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); | 1204 | cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN); |
1205 | if (!cp) | 1205 | if (!cp) |
@@ -1209,7 +1209,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | |||
1209 | 1209 | ||
1210 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); | 1210 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr); |
1211 | 1211 | ||
1212 | BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn); | 1212 | BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn); |
1213 | 1213 | ||
1214 | if (status) { | 1214 | if (status) { |
1215 | if (conn && conn->state == BT_CONNECT) { | 1215 | if (conn && conn->state == BT_CONNECT) { |
@@ -1240,7 +1240,7 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) | |||
1240 | struct hci_conn *acl, *sco; | 1240 | struct hci_conn *acl, *sco; |
1241 | __u16 handle; | 1241 | __u16 handle; |
1242 | 1242 | ||
1243 | BT_DBG("%s status 0x%x", hdev->name, status); | 1243 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1244 | 1244 | ||
1245 | if (!status) | 1245 | if (!status) |
1246 | return; | 1246 | return; |
@@ -1251,7 +1251,7 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status) | |||
1251 | 1251 | ||
1252 | handle = __le16_to_cpu(cp->handle); | 1252 | handle = __le16_to_cpu(cp->handle); |
1253 | 1253 | ||
1254 | BT_DBG("%s handle %d", hdev->name, handle); | 1254 | BT_DBG("%s handle 0x%4.4x", hdev->name, handle); |
1255 | 1255 | ||
1256 | hci_dev_lock(hdev); | 1256 | hci_dev_lock(hdev); |
1257 | 1257 | ||
@@ -1274,7 +1274,7 @@ static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status) | |||
1274 | struct hci_cp_auth_requested *cp; | 1274 | struct hci_cp_auth_requested *cp; |
1275 | struct hci_conn *conn; | 1275 | struct hci_conn *conn; |
1276 | 1276 | ||
1277 | BT_DBG("%s status 0x%x", hdev->name, status); | 1277 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1278 | 1278 | ||
1279 | if (!status) | 1279 | if (!status) |
1280 | return; | 1280 | return; |
@@ -1301,7 +1301,7 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) | |||
1301 | struct hci_cp_set_conn_encrypt *cp; | 1301 | struct hci_cp_set_conn_encrypt *cp; |
1302 | struct hci_conn *conn; | 1302 | struct hci_conn *conn; |
1303 | 1303 | ||
1304 | BT_DBG("%s status 0x%x", hdev->name, status); | 1304 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1305 | 1305 | ||
1306 | if (!status) | 1306 | if (!status) |
1307 | return; | 1307 | return; |
@@ -1413,7 +1413,7 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) | |||
1413 | struct hci_cp_remote_name_req *cp; | 1413 | struct hci_cp_remote_name_req *cp; |
1414 | struct hci_conn *conn; | 1414 | struct hci_conn *conn; |
1415 | 1415 | ||
1416 | BT_DBG("%s status 0x%x", hdev->name, status); | 1416 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1417 | 1417 | ||
1418 | /* If successful wait for the name req complete event before | 1418 | /* If successful wait for the name req complete event before |
1419 | * checking for the need to do authentication */ | 1419 | * checking for the need to do authentication */ |
@@ -1452,7 +1452,7 @@ static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status) | |||
1452 | struct hci_cp_read_remote_features *cp; | 1452 | struct hci_cp_read_remote_features *cp; |
1453 | struct hci_conn *conn; | 1453 | struct hci_conn *conn; |
1454 | 1454 | ||
1455 | BT_DBG("%s status 0x%x", hdev->name, status); | 1455 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1456 | 1456 | ||
1457 | if (!status) | 1457 | if (!status) |
1458 | return; | 1458 | return; |
@@ -1479,7 +1479,7 @@ static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status) | |||
1479 | struct hci_cp_read_remote_ext_features *cp; | 1479 | struct hci_cp_read_remote_ext_features *cp; |
1480 | struct hci_conn *conn; | 1480 | struct hci_conn *conn; |
1481 | 1481 | ||
1482 | BT_DBG("%s status 0x%x", hdev->name, status); | 1482 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1483 | 1483 | ||
1484 | if (!status) | 1484 | if (!status) |
1485 | return; | 1485 | return; |
@@ -1507,7 +1507,7 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) | |||
1507 | struct hci_conn *acl, *sco; | 1507 | struct hci_conn *acl, *sco; |
1508 | __u16 handle; | 1508 | __u16 handle; |
1509 | 1509 | ||
1510 | BT_DBG("%s status 0x%x", hdev->name, status); | 1510 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1511 | 1511 | ||
1512 | if (!status) | 1512 | if (!status) |
1513 | return; | 1513 | return; |
@@ -1518,7 +1518,7 @@ static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status) | |||
1518 | 1518 | ||
1519 | handle = __le16_to_cpu(cp->handle); | 1519 | handle = __le16_to_cpu(cp->handle); |
1520 | 1520 | ||
1521 | BT_DBG("%s handle %d", hdev->name, handle); | 1521 | BT_DBG("%s handle 0x%4.4x", hdev->name, handle); |
1522 | 1522 | ||
1523 | hci_dev_lock(hdev); | 1523 | hci_dev_lock(hdev); |
1524 | 1524 | ||
@@ -1541,7 +1541,7 @@ static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status) | |||
1541 | struct hci_cp_sniff_mode *cp; | 1541 | struct hci_cp_sniff_mode *cp; |
1542 | struct hci_conn *conn; | 1542 | struct hci_conn *conn; |
1543 | 1543 | ||
1544 | BT_DBG("%s status 0x%x", hdev->name, status); | 1544 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1545 | 1545 | ||
1546 | if (!status) | 1546 | if (!status) |
1547 | return; | 1547 | return; |
@@ -1568,7 +1568,7 @@ static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status) | |||
1568 | struct hci_cp_exit_sniff_mode *cp; | 1568 | struct hci_cp_exit_sniff_mode *cp; |
1569 | struct hci_conn *conn; | 1569 | struct hci_conn *conn; |
1570 | 1570 | ||
1571 | BT_DBG("%s status 0x%x", hdev->name, status); | 1571 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1572 | 1572 | ||
1573 | if (!status) | 1573 | if (!status) |
1574 | return; | 1574 | return; |
@@ -1617,7 +1617,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | |||
1617 | struct hci_cp_le_create_conn *cp; | 1617 | struct hci_cp_le_create_conn *cp; |
1618 | struct hci_conn *conn; | 1618 | struct hci_conn *conn; |
1619 | 1619 | ||
1620 | BT_DBG("%s status 0x%x", hdev->name, status); | 1620 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1621 | 1621 | ||
1622 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); | 1622 | cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN); |
1623 | if (!cp) | 1623 | if (!cp) |
@@ -1655,7 +1655,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status) | |||
1655 | 1655 | ||
1656 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) | 1656 | static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status) |
1657 | { | 1657 | { |
1658 | BT_DBG("%s status 0x%x", hdev->name, status); | 1658 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1659 | } | 1659 | } |
1660 | 1660 | ||
1661 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1661 | static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) |
@@ -1664,7 +1664,7 @@ static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1664 | struct discovery_state *discov = &hdev->discovery; | 1664 | struct discovery_state *discov = &hdev->discovery; |
1665 | struct inquiry_entry *e; | 1665 | struct inquiry_entry *e; |
1666 | 1666 | ||
1667 | BT_DBG("%s status %d", hdev->name, status); | 1667 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
1668 | 1668 | ||
1669 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); | 1669 | hci_req_complete(hdev, HCI_OP_INQUIRY, status); |
1670 | 1670 | ||
@@ -1893,7 +1893,7 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1893 | struct hci_ev_disconn_complete *ev = (void *) skb->data; | 1893 | struct hci_ev_disconn_complete *ev = (void *) skb->data; |
1894 | struct hci_conn *conn; | 1894 | struct hci_conn *conn; |
1895 | 1895 | ||
1896 | BT_DBG("%s status %d", hdev->name, ev->status); | 1896 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
1897 | 1897 | ||
1898 | hci_dev_lock(hdev); | 1898 | hci_dev_lock(hdev); |
1899 | 1899 | ||
@@ -1930,7 +1930,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1930 | struct hci_ev_auth_complete *ev = (void *) skb->data; | 1930 | struct hci_ev_auth_complete *ev = (void *) skb->data; |
1931 | struct hci_conn *conn; | 1931 | struct hci_conn *conn; |
1932 | 1932 | ||
1933 | BT_DBG("%s status %d", hdev->name, ev->status); | 1933 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
1934 | 1934 | ||
1935 | hci_dev_lock(hdev); | 1935 | hci_dev_lock(hdev); |
1936 | 1936 | ||
@@ -2035,7 +2035,7 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2035 | struct hci_ev_encrypt_change *ev = (void *) skb->data; | 2035 | struct hci_ev_encrypt_change *ev = (void *) skb->data; |
2036 | struct hci_conn *conn; | 2036 | struct hci_conn *conn; |
2037 | 2037 | ||
2038 | BT_DBG("%s status %d", hdev->name, ev->status); | 2038 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2039 | 2039 | ||
2040 | hci_dev_lock(hdev); | 2040 | hci_dev_lock(hdev); |
2041 | 2041 | ||
@@ -2079,7 +2079,7 @@ static void hci_change_link_key_complete_evt(struct hci_dev *hdev, | |||
2079 | struct hci_ev_change_link_key_complete *ev = (void *) skb->data; | 2079 | struct hci_ev_change_link_key_complete *ev = (void *) skb->data; |
2080 | struct hci_conn *conn; | 2080 | struct hci_conn *conn; |
2081 | 2081 | ||
2082 | BT_DBG("%s status %d", hdev->name, ev->status); | 2082 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2083 | 2083 | ||
2084 | hci_dev_lock(hdev); | 2084 | hci_dev_lock(hdev); |
2085 | 2085 | ||
@@ -2102,7 +2102,7 @@ static void hci_remote_features_evt(struct hci_dev *hdev, | |||
2102 | struct hci_ev_remote_features *ev = (void *) skb->data; | 2102 | struct hci_ev_remote_features *ev = (void *) skb->data; |
2103 | struct hci_conn *conn; | 2103 | struct hci_conn *conn; |
2104 | 2104 | ||
2105 | BT_DBG("%s status %d", hdev->name, ev->status); | 2105 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2106 | 2106 | ||
2107 | hci_dev_lock(hdev); | 2107 | hci_dev_lock(hdev); |
2108 | 2108 | ||
@@ -2364,7 +2364,7 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2364 | break; | 2364 | break; |
2365 | 2365 | ||
2366 | default: | 2366 | default: |
2367 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 2367 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2368 | break; | 2368 | break; |
2369 | } | 2369 | } |
2370 | 2370 | ||
@@ -2445,7 +2445,7 @@ static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2445 | break; | 2445 | break; |
2446 | 2446 | ||
2447 | default: | 2447 | default: |
2448 | BT_DBG("%s opcode 0x%x", hdev->name, opcode); | 2448 | BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode); |
2449 | break; | 2449 | break; |
2450 | } | 2450 | } |
2451 | 2451 | ||
@@ -2464,7 +2464,7 @@ static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2464 | struct hci_ev_role_change *ev = (void *) skb->data; | 2464 | struct hci_ev_role_change *ev = (void *) skb->data; |
2465 | struct hci_conn *conn; | 2465 | struct hci_conn *conn; |
2466 | 2466 | ||
2467 | BT_DBG("%s status %d", hdev->name, ev->status); | 2467 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2468 | 2468 | ||
2469 | hci_dev_lock(hdev); | 2469 | hci_dev_lock(hdev); |
2470 | 2470 | ||
@@ -2605,7 +2605,7 @@ static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2605 | struct hci_ev_mode_change *ev = (void *) skb->data; | 2605 | struct hci_ev_mode_change *ev = (void *) skb->data; |
2606 | struct hci_conn *conn; | 2606 | struct hci_conn *conn; |
2607 | 2607 | ||
2608 | BT_DBG("%s status %d", hdev->name, ev->status); | 2608 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2609 | 2609 | ||
2610 | hci_dev_lock(hdev); | 2610 | hci_dev_lock(hdev); |
2611 | 2611 | ||
@@ -2763,7 +2763,7 @@ static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2763 | struct hci_ev_clock_offset *ev = (void *) skb->data; | 2763 | struct hci_ev_clock_offset *ev = (void *) skb->data; |
2764 | struct hci_conn *conn; | 2764 | struct hci_conn *conn; |
2765 | 2765 | ||
2766 | BT_DBG("%s status %d", hdev->name, ev->status); | 2766 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2767 | 2767 | ||
2768 | hci_dev_lock(hdev); | 2768 | hci_dev_lock(hdev); |
2769 | 2769 | ||
@@ -2786,7 +2786,7 @@ static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2786 | struct hci_ev_pkt_type_change *ev = (void *) skb->data; | 2786 | struct hci_ev_pkt_type_change *ev = (void *) skb->data; |
2787 | struct hci_conn *conn; | 2787 | struct hci_conn *conn; |
2788 | 2788 | ||
2789 | BT_DBG("%s status %d", hdev->name, ev->status); | 2789 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2790 | 2790 | ||
2791 | hci_dev_lock(hdev); | 2791 | hci_dev_lock(hdev); |
2792 | 2792 | ||
@@ -2930,7 +2930,7 @@ static void hci_sync_conn_complete_evt(struct hci_dev *hdev, | |||
2930 | struct hci_ev_sync_conn_complete *ev = (void *) skb->data; | 2930 | struct hci_ev_sync_conn_complete *ev = (void *) skb->data; |
2931 | struct hci_conn *conn; | 2931 | struct hci_conn *conn; |
2932 | 2932 | ||
2933 | BT_DBG("%s status %d", hdev->name, ev->status); | 2933 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2934 | 2934 | ||
2935 | hci_dev_lock(hdev); | 2935 | hci_dev_lock(hdev); |
2936 | 2936 | ||
@@ -2989,7 +2989,7 @@ static void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2989 | { | 2989 | { |
2990 | struct hci_ev_sniff_subrate *ev = (void *) skb->data; | 2990 | struct hci_ev_sniff_subrate *ev = (void *) skb->data; |
2991 | 2991 | ||
2992 | BT_DBG("%s status %d", hdev->name, ev->status); | 2992 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
2993 | } | 2993 | } |
2994 | 2994 | ||
2995 | static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, | 2995 | static void hci_extended_inquiry_result_evt(struct hci_dev *hdev, |
@@ -3046,7 +3046,7 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | |||
3046 | struct hci_ev_key_refresh_complete *ev = (void *) skb->data; | 3046 | struct hci_ev_key_refresh_complete *ev = (void *) skb->data; |
3047 | struct hci_conn *conn; | 3047 | struct hci_conn *conn; |
3048 | 3048 | ||
3049 | BT_DBG("%s status %u handle %u", hdev->name, ev->status, | 3049 | BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status, |
3050 | __le16_to_cpu(ev->handle)); | 3050 | __le16_to_cpu(ev->handle)); |
3051 | 3051 | ||
3052 | hci_dev_lock(hdev); | 3052 | hci_dev_lock(hdev); |
@@ -3346,7 +3346,7 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3346 | struct hci_ev_le_conn_complete *ev = (void *) skb->data; | 3346 | struct hci_ev_le_conn_complete *ev = (void *) skb->data; |
3347 | struct hci_conn *conn; | 3347 | struct hci_conn *conn; |
3348 | 3348 | ||
3349 | BT_DBG("%s status %d", hdev->name, ev->status); | 3349 | BT_DBG("%s status 0x%2.2x", hdev->name, ev->status); |
3350 | 3350 | ||
3351 | hci_dev_lock(hdev); | 3351 | hci_dev_lock(hdev); |
3352 | 3352 | ||
@@ -3421,7 +3421,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
3421 | struct hci_conn *conn; | 3421 | struct hci_conn *conn; |
3422 | struct smp_ltk *ltk; | 3422 | struct smp_ltk *ltk; |
3423 | 3423 | ||
3424 | BT_DBG("%s handle %d", hdev->name, __le16_to_cpu(ev->handle)); | 3424 | BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle)); |
3425 | 3425 | ||
3426 | hci_dev_lock(hdev); | 3426 | hci_dev_lock(hdev); |
3427 | 3427 | ||
@@ -3645,7 +3645,7 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
3645 | break; | 3645 | break; |
3646 | 3646 | ||
3647 | default: | 3647 | default: |
3648 | BT_DBG("%s event 0x%x", hdev->name, event); | 3648 | BT_DBG("%s event 0x%2.2x", hdev->name, event); |
3649 | break; | 3649 | break; |
3650 | } | 3650 | } |
3651 | 3651 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index d42dfdc83ebb..a8964db04bfb 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -431,6 +431,7 @@ void l2cap_chan_set_defaults(struct l2cap_chan *chan) | |||
431 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; | 431 | chan->max_tx = L2CAP_DEFAULT_MAX_TX; |
432 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; | 432 | chan->tx_win = L2CAP_DEFAULT_TX_WINDOW; |
433 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | 433 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; |
434 | chan->ack_win = L2CAP_DEFAULT_TX_WINDOW; | ||
434 | chan->sec_level = BT_SECURITY_LOW; | 435 | chan->sec_level = BT_SECURITY_LOW; |
435 | 436 | ||
436 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); | 437 | set_bit(FLAG_FORCE_ACTIVE, &chan->flags); |
@@ -1657,7 +1658,7 @@ static void l2cap_streaming_send(struct l2cap_chan *chan, | |||
1657 | 1658 | ||
1658 | l2cap_do_send(chan, skb); | 1659 | l2cap_do_send(chan, skb); |
1659 | 1660 | ||
1660 | BT_DBG("Sent txseq %d", (int)control->txseq); | 1661 | BT_DBG("Sent txseq %u", control->txseq); |
1661 | 1662 | ||
1662 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); | 1663 | chan->next_tx_seq = __next_seq(chan, chan->next_tx_seq); |
1663 | chan->frames_sent++; | 1664 | chan->frames_sent++; |
@@ -1722,11 +1723,11 @@ static int l2cap_ertm_send(struct l2cap_chan *chan) | |||
1722 | chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); | 1723 | chan->tx_send_head = skb_queue_next(&chan->tx_q, skb); |
1723 | 1724 | ||
1724 | l2cap_do_send(chan, tx_skb); | 1725 | l2cap_do_send(chan, tx_skb); |
1725 | BT_DBG("Sent txseq %d", (int)control->txseq); | 1726 | BT_DBG("Sent txseq %u", control->txseq); |
1726 | } | 1727 | } |
1727 | 1728 | ||
1728 | BT_DBG("Sent %d, %d unacked, %d in ERTM queue", sent, | 1729 | BT_DBG("Sent %d, %u unacked, %u in ERTM queue", sent, |
1729 | (int) chan->unacked_frames, skb_queue_len(&chan->tx_q)); | 1730 | chan->unacked_frames, skb_queue_len(&chan->tx_q)); |
1730 | 1731 | ||
1731 | return sent; | 1732 | return sent; |
1732 | } | 1733 | } |
@@ -1877,14 +1878,14 @@ static void l2cap_send_ack(struct l2cap_chan *chan) | |||
1877 | frames_to_ack = 0; | 1878 | frames_to_ack = 0; |
1878 | } | 1879 | } |
1879 | 1880 | ||
1880 | /* Ack now if the tx window is 3/4ths full. | 1881 | /* Ack now if the window is 3/4ths full. |
1881 | * Calculate without mul or div | 1882 | * Calculate without mul or div |
1882 | */ | 1883 | */ |
1883 | threshold = chan->tx_win; | 1884 | threshold = chan->ack_win; |
1884 | threshold += threshold << 1; | 1885 | threshold += threshold << 1; |
1885 | threshold >>= 2; | 1886 | threshold >>= 2; |
1886 | 1887 | ||
1887 | BT_DBG("frames_to_ack %d, threshold %d", (int)frames_to_ack, | 1888 | BT_DBG("frames_to_ack %u, threshold %d", frames_to_ack, |
1888 | threshold); | 1889 | threshold); |
1889 | 1890 | ||
1890 | if (frames_to_ack >= threshold) { | 1891 | if (frames_to_ack >= threshold) { |
@@ -1946,15 +1947,15 @@ static inline int l2cap_skbuff_fromiovec(struct l2cap_chan *chan, | |||
1946 | } | 1947 | } |
1947 | 1948 | ||
1948 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, | 1949 | static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, |
1949 | struct msghdr *msg, size_t len, | 1950 | struct msghdr *msg, size_t len, |
1950 | u32 priority) | 1951 | u32 priority) |
1951 | { | 1952 | { |
1952 | struct l2cap_conn *conn = chan->conn; | 1953 | struct l2cap_conn *conn = chan->conn; |
1953 | struct sk_buff *skb; | 1954 | struct sk_buff *skb; |
1954 | int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; | 1955 | int err, count, hlen = L2CAP_HDR_SIZE + L2CAP_PSMLEN_SIZE; |
1955 | struct l2cap_hdr *lh; | 1956 | struct l2cap_hdr *lh; |
1956 | 1957 | ||
1957 | BT_DBG("chan %p len %d priority %u", chan, (int)len, priority); | 1958 | BT_DBG("chan %p len %zu priority %u", chan, len, priority); |
1958 | 1959 | ||
1959 | count = min_t(unsigned int, (conn->mtu - hlen), len); | 1960 | count = min_t(unsigned int, (conn->mtu - hlen), len); |
1960 | 1961 | ||
@@ -1980,15 +1981,15 @@ static struct sk_buff *l2cap_create_connless_pdu(struct l2cap_chan *chan, | |||
1980 | } | 1981 | } |
1981 | 1982 | ||
1982 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, | 1983 | static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, |
1983 | struct msghdr *msg, size_t len, | 1984 | struct msghdr *msg, size_t len, |
1984 | u32 priority) | 1985 | u32 priority) |
1985 | { | 1986 | { |
1986 | struct l2cap_conn *conn = chan->conn; | 1987 | struct l2cap_conn *conn = chan->conn; |
1987 | struct sk_buff *skb; | 1988 | struct sk_buff *skb; |
1988 | int err, count; | 1989 | int err, count; |
1989 | struct l2cap_hdr *lh; | 1990 | struct l2cap_hdr *lh; |
1990 | 1991 | ||
1991 | BT_DBG("chan %p len %d", chan, (int)len); | 1992 | BT_DBG("chan %p len %zu", chan, len); |
1992 | 1993 | ||
1993 | count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); | 1994 | count = min_t(unsigned int, (conn->mtu - L2CAP_HDR_SIZE), len); |
1994 | 1995 | ||
@@ -2013,15 +2014,15 @@ static struct sk_buff *l2cap_create_basic_pdu(struct l2cap_chan *chan, | |||
2013 | } | 2014 | } |
2014 | 2015 | ||
2015 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, | 2016 | static struct sk_buff *l2cap_create_iframe_pdu(struct l2cap_chan *chan, |
2016 | struct msghdr *msg, size_t len, | 2017 | struct msghdr *msg, size_t len, |
2017 | u16 sdulen) | 2018 | u16 sdulen) |
2018 | { | 2019 | { |
2019 | struct l2cap_conn *conn = chan->conn; | 2020 | struct l2cap_conn *conn = chan->conn; |
2020 | struct sk_buff *skb; | 2021 | struct sk_buff *skb; |
2021 | int err, count, hlen; | 2022 | int err, count, hlen; |
2022 | struct l2cap_hdr *lh; | 2023 | struct l2cap_hdr *lh; |
2023 | 2024 | ||
2024 | BT_DBG("chan %p len %d", chan, (int)len); | 2025 | BT_DBG("chan %p len %zu", chan, len); |
2025 | 2026 | ||
2026 | if (!conn) | 2027 | if (!conn) |
2027 | return ERR_PTR(-ENOTCONN); | 2028 | return ERR_PTR(-ENOTCONN); |
@@ -2075,7 +2076,7 @@ static int l2cap_segment_sdu(struct l2cap_chan *chan, | |||
2075 | size_t pdu_len; | 2076 | size_t pdu_len; |
2076 | u8 sar; | 2077 | u8 sar; |
2077 | 2078 | ||
2078 | BT_DBG("chan %p, msg %p, len %d", chan, msg, (int)len); | 2079 | BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); |
2079 | 2080 | ||
2080 | /* It is critical that ERTM PDUs fit in a single HCI fragment, | 2081 | /* It is critical that ERTM PDUs fit in a single HCI fragment, |
2081 | * so fragmented skbs are not used. The HCI layer's handling | 2082 | * so fragmented skbs are not used. The HCI layer's handling |
@@ -2219,7 +2220,7 @@ static void l2cap_send_srej(struct l2cap_chan *chan, u16 txseq) | |||
2219 | struct l2cap_ctrl control; | 2220 | struct l2cap_ctrl control; |
2220 | u16 seq; | 2221 | u16 seq; |
2221 | 2222 | ||
2222 | BT_DBG("chan %p, txseq %d", chan, txseq); | 2223 | BT_DBG("chan %p, txseq %u", chan, txseq); |
2223 | 2224 | ||
2224 | memset(&control, 0, sizeof(control)); | 2225 | memset(&control, 0, sizeof(control)); |
2225 | control.sframe = 1; | 2226 | control.sframe = 1; |
@@ -2259,7 +2260,7 @@ static void l2cap_send_srej_list(struct l2cap_chan *chan, u16 txseq) | |||
2259 | u16 initial_head; | 2260 | u16 initial_head; |
2260 | u16 seq; | 2261 | u16 seq; |
2261 | 2262 | ||
2262 | BT_DBG("chan %p, txseq %d", chan, txseq); | 2263 | BT_DBG("chan %p, txseq %u", chan, txseq); |
2263 | 2264 | ||
2264 | memset(&control, 0, sizeof(control)); | 2265 | memset(&control, 0, sizeof(control)); |
2265 | control.sframe = 1; | 2266 | control.sframe = 1; |
@@ -2284,12 +2285,12 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) | |||
2284 | struct sk_buff *acked_skb; | 2285 | struct sk_buff *acked_skb; |
2285 | u16 ackseq; | 2286 | u16 ackseq; |
2286 | 2287 | ||
2287 | BT_DBG("chan %p, reqseq %d", chan, reqseq); | 2288 | BT_DBG("chan %p, reqseq %u", chan, reqseq); |
2288 | 2289 | ||
2289 | if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) | 2290 | if (chan->unacked_frames == 0 || reqseq == chan->expected_ack_seq) |
2290 | return; | 2291 | return; |
2291 | 2292 | ||
2292 | BT_DBG("expected_ack_seq %d, unacked_frames %d", | 2293 | BT_DBG("expected_ack_seq %u, unacked_frames %u", |
2293 | chan->expected_ack_seq, chan->unacked_frames); | 2294 | chan->expected_ack_seq, chan->unacked_frames); |
2294 | 2295 | ||
2295 | for (ackseq = chan->expected_ack_seq; ackseq != reqseq; | 2296 | for (ackseq = chan->expected_ack_seq; ackseq != reqseq; |
@@ -2308,7 +2309,7 @@ static void l2cap_process_reqseq(struct l2cap_chan *chan, u16 reqseq) | |||
2308 | if (chan->unacked_frames == 0) | 2309 | if (chan->unacked_frames == 0) |
2309 | __clear_retrans_timer(chan); | 2310 | __clear_retrans_timer(chan); |
2310 | 2311 | ||
2311 | BT_DBG("unacked_frames %d", (int) chan->unacked_frames); | 2312 | BT_DBG("unacked_frames %u", chan->unacked_frames); |
2312 | } | 2313 | } |
2313 | 2314 | ||
2314 | static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) | 2315 | static void l2cap_abort_rx_srej_sent(struct l2cap_chan *chan) |
@@ -2534,16 +2535,16 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb) | |||
2534 | } | 2535 | } |
2535 | 2536 | ||
2536 | /* ---- L2CAP signalling commands ---- */ | 2537 | /* ---- L2CAP signalling commands ---- */ |
2537 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, | 2538 | static struct sk_buff *l2cap_build_cmd(struct l2cap_conn *conn, u8 code, |
2538 | u8 code, u8 ident, u16 dlen, void *data) | 2539 | u8 ident, u16 dlen, void *data) |
2539 | { | 2540 | { |
2540 | struct sk_buff *skb, **frag; | 2541 | struct sk_buff *skb, **frag; |
2541 | struct l2cap_cmd_hdr *cmd; | 2542 | struct l2cap_cmd_hdr *cmd; |
2542 | struct l2cap_hdr *lh; | 2543 | struct l2cap_hdr *lh; |
2543 | int len, count; | 2544 | int len, count; |
2544 | 2545 | ||
2545 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %d", | 2546 | BT_DBG("conn %p, code 0x%2.2x, ident 0x%2.2x, len %u", |
2546 | conn, code, ident, dlen); | 2547 | conn, code, ident, dlen); |
2547 | 2548 | ||
2548 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; | 2549 | len = L2CAP_HDR_SIZE + L2CAP_CMD_HDR_SIZE + dlen; |
2549 | count = min_t(unsigned int, conn->mtu, len); | 2550 | count = min_t(unsigned int, conn->mtu, len); |
@@ -2626,7 +2627,7 @@ static inline int l2cap_get_conf_opt(void **ptr, int *type, int *olen, unsigned | |||
2626 | break; | 2627 | break; |
2627 | } | 2628 | } |
2628 | 2629 | ||
2629 | BT_DBG("type 0x%2.2x len %d val 0x%lx", *type, opt->len, *val); | 2630 | BT_DBG("type 0x%2.2x len %u val 0x%lx", *type, opt->len, *val); |
2630 | return len; | 2631 | return len; |
2631 | } | 2632 | } |
2632 | 2633 | ||
@@ -2634,7 +2635,7 @@ static void l2cap_add_conf_opt(void **ptr, u8 type, u8 len, unsigned long val) | |||
2634 | { | 2635 | { |
2635 | struct l2cap_conf_opt *opt = *ptr; | 2636 | struct l2cap_conf_opt *opt = *ptr; |
2636 | 2637 | ||
2637 | BT_DBG("type 0x%2.2x len %d val 0x%lx", type, len, val); | 2638 | BT_DBG("type 0x%2.2x len %u val 0x%lx", type, len, val); |
2638 | 2639 | ||
2639 | opt->type = type; | 2640 | opt->type = type; |
2640 | opt->len = len; | 2641 | opt->len = len; |
@@ -2786,6 +2787,7 @@ static inline void l2cap_txwin_setup(struct l2cap_chan *chan) | |||
2786 | L2CAP_DEFAULT_TX_WINDOW); | 2787 | L2CAP_DEFAULT_TX_WINDOW); |
2787 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; | 2788 | chan->tx_win_max = L2CAP_DEFAULT_TX_WINDOW; |
2788 | } | 2789 | } |
2790 | chan->ack_win = chan->tx_win; | ||
2789 | } | 2791 | } |
2790 | 2792 | ||
2791 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) | 2793 | static int l2cap_build_conf_req(struct l2cap_chan *chan, void *data) |
@@ -3175,10 +3177,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
3175 | break; | 3177 | break; |
3176 | 3178 | ||
3177 | case L2CAP_CONF_EWS: | 3179 | case L2CAP_CONF_EWS: |
3178 | chan->tx_win = min_t(u16, val, | 3180 | chan->ack_win = min_t(u16, val, chan->ack_win); |
3179 | L2CAP_DEFAULT_EXT_WINDOW); | ||
3180 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, | 3181 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EWS, 2, |
3181 | chan->tx_win); | 3182 | chan->tx_win); |
3182 | break; | 3183 | break; |
3183 | 3184 | ||
3184 | case L2CAP_CONF_EFS: | 3185 | case L2CAP_CONF_EFS: |
@@ -3207,6 +3208,9 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, voi | |||
3207 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 3208 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
3208 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 3209 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
3209 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 3210 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
3211 | if (!test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
3212 | chan->ack_win = min_t(u16, chan->ack_win, | ||
3213 | rfc.txwin_size); | ||
3210 | 3214 | ||
3211 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { | 3215 | if (test_bit(FLAG_EFS_ENABLE, &chan->flags)) { |
3212 | chan->local_msdu = le16_to_cpu(efs.msdu); | 3216 | chan->local_msdu = le16_to_cpu(efs.msdu); |
@@ -3268,7 +3272,17 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) | |||
3268 | { | 3272 | { |
3269 | int type, olen; | 3273 | int type, olen; |
3270 | unsigned long val; | 3274 | unsigned long val; |
3271 | struct l2cap_conf_rfc rfc; | 3275 | /* Use sane default values in case a misbehaving remote device |
3276 | * did not send an RFC or extended window size option. | ||
3277 | */ | ||
3278 | u16 txwin_ext = chan->ack_win; | ||
3279 | struct l2cap_conf_rfc rfc = { | ||
3280 | .mode = chan->mode, | ||
3281 | .retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO), | ||
3282 | .monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO), | ||
3283 | .max_pdu_size = cpu_to_le16(chan->imtu), | ||
3284 | .txwin_size = min_t(u16, chan->ack_win, L2CAP_DEFAULT_TX_WINDOW), | ||
3285 | }; | ||
3272 | 3286 | ||
3273 | BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); | 3287 | BT_DBG("chan %p, rsp %p, len %d", chan, rsp, len); |
3274 | 3288 | ||
@@ -3278,32 +3292,27 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) | |||
3278 | while (len >= L2CAP_CONF_OPT_SIZE) { | 3292 | while (len >= L2CAP_CONF_OPT_SIZE) { |
3279 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); | 3293 | len -= l2cap_get_conf_opt(&rsp, &type, &olen, &val); |
3280 | 3294 | ||
3281 | if (type != L2CAP_CONF_RFC) | 3295 | switch (type) { |
3282 | continue; | 3296 | case L2CAP_CONF_RFC: |
3283 | 3297 | if (olen == sizeof(rfc)) | |
3284 | if (olen != sizeof(rfc)) | 3298 | memcpy(&rfc, (void *)val, olen); |
3285 | break; | 3299 | break; |
3286 | 3300 | case L2CAP_CONF_EWS: | |
3287 | memcpy(&rfc, (void *)val, olen); | 3301 | txwin_ext = val; |
3288 | goto done; | 3302 | break; |
3303 | } | ||
3289 | } | 3304 | } |
3290 | 3305 | ||
3291 | /* Use sane default values in case a misbehaving remote device | ||
3292 | * did not send an RFC option. | ||
3293 | */ | ||
3294 | rfc.mode = chan->mode; | ||
3295 | rfc.retrans_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO); | ||
3296 | rfc.monitor_timeout = __constant_cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO); | ||
3297 | rfc.max_pdu_size = cpu_to_le16(chan->imtu); | ||
3298 | |||
3299 | BT_ERR("Expected RFC option was not found, using defaults"); | ||
3300 | |||
3301 | done: | ||
3302 | switch (rfc.mode) { | 3306 | switch (rfc.mode) { |
3303 | case L2CAP_MODE_ERTM: | 3307 | case L2CAP_MODE_ERTM: |
3304 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); | 3308 | chan->retrans_timeout = le16_to_cpu(rfc.retrans_timeout); |
3305 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); | 3309 | chan->monitor_timeout = le16_to_cpu(rfc.monitor_timeout); |
3306 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 3310 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
3311 | if (test_bit(FLAG_EXT_CTRL, &chan->flags)) | ||
3312 | chan->ack_win = min_t(u16, chan->ack_win, txwin_ext); | ||
3313 | else | ||
3314 | chan->ack_win = min_t(u16, chan->ack_win, | ||
3315 | rfc.txwin_size); | ||
3307 | break; | 3316 | break; |
3308 | case L2CAP_MODE_STREAMING: | 3317 | case L2CAP_MODE_STREAMING: |
3309 | chan->mps = le16_to_cpu(rfc.max_pdu_size); | 3318 | chan->mps = le16_to_cpu(rfc.max_pdu_size); |
@@ -3949,7 +3958,7 @@ static inline int l2cap_create_channel_req(struct l2cap_conn *conn, | |||
3949 | psm = le16_to_cpu(req->psm); | 3958 | psm = le16_to_cpu(req->psm); |
3950 | scid = le16_to_cpu(req->scid); | 3959 | scid = le16_to_cpu(req->scid); |
3951 | 3960 | ||
3952 | BT_DBG("psm %d, scid %d, amp_id %d", psm, scid, req->amp_id); | 3961 | BT_DBG("psm 0x%2.2x, scid 0x%4.4x, amp_id %d", psm, scid, req->amp_id); |
3953 | 3962 | ||
3954 | /* Placeholder: Always reject */ | 3963 | /* Placeholder: Always reject */ |
3955 | rsp.dcid = 0; | 3964 | rsp.dcid = 0; |
@@ -3972,11 +3981,11 @@ static inline int l2cap_create_channel_rsp(struct l2cap_conn *conn, | |||
3972 | } | 3981 | } |
3973 | 3982 | ||
3974 | static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, | 3983 | static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, |
3975 | u16 icid, u16 result) | 3984 | u16 icid, u16 result) |
3976 | { | 3985 | { |
3977 | struct l2cap_move_chan_rsp rsp; | 3986 | struct l2cap_move_chan_rsp rsp; |
3978 | 3987 | ||
3979 | BT_DBG("icid %d, result %d", icid, result); | 3988 | BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); |
3980 | 3989 | ||
3981 | rsp.icid = cpu_to_le16(icid); | 3990 | rsp.icid = cpu_to_le16(icid); |
3982 | rsp.result = cpu_to_le16(result); | 3991 | rsp.result = cpu_to_le16(result); |
@@ -3985,12 +3994,13 @@ static void l2cap_send_move_chan_rsp(struct l2cap_conn *conn, u8 ident, | |||
3985 | } | 3994 | } |
3986 | 3995 | ||
3987 | static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, | 3996 | static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, |
3988 | struct l2cap_chan *chan, u16 icid, u16 result) | 3997 | struct l2cap_chan *chan, |
3998 | u16 icid, u16 result) | ||
3989 | { | 3999 | { |
3990 | struct l2cap_move_chan_cfm cfm; | 4000 | struct l2cap_move_chan_cfm cfm; |
3991 | u8 ident; | 4001 | u8 ident; |
3992 | 4002 | ||
3993 | BT_DBG("icid %d, result %d", icid, result); | 4003 | BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); |
3994 | 4004 | ||
3995 | ident = l2cap_get_ident(conn); | 4005 | ident = l2cap_get_ident(conn); |
3996 | if (chan) | 4006 | if (chan) |
@@ -4003,18 +4013,19 @@ static void l2cap_send_move_chan_cfm(struct l2cap_conn *conn, | |||
4003 | } | 4013 | } |
4004 | 4014 | ||
4005 | static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, | 4015 | static void l2cap_send_move_chan_cfm_rsp(struct l2cap_conn *conn, u8 ident, |
4006 | u16 icid) | 4016 | u16 icid) |
4007 | { | 4017 | { |
4008 | struct l2cap_move_chan_cfm_rsp rsp; | 4018 | struct l2cap_move_chan_cfm_rsp rsp; |
4009 | 4019 | ||
4010 | BT_DBG("icid %d", icid); | 4020 | BT_DBG("icid 0x%4.4x", icid); |
4011 | 4021 | ||
4012 | rsp.icid = cpu_to_le16(icid); | 4022 | rsp.icid = cpu_to_le16(icid); |
4013 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); | 4023 | l2cap_send_cmd(conn, ident, L2CAP_MOVE_CHAN_CFM_RSP, sizeof(rsp), &rsp); |
4014 | } | 4024 | } |
4015 | 4025 | ||
4016 | static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | 4026 | static inline int l2cap_move_channel_req(struct l2cap_conn *conn, |
4017 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | 4027 | struct l2cap_cmd_hdr *cmd, |
4028 | u16 cmd_len, void *data) | ||
4018 | { | 4029 | { |
4019 | struct l2cap_move_chan_req *req = data; | 4030 | struct l2cap_move_chan_req *req = data; |
4020 | u16 icid = 0; | 4031 | u16 icid = 0; |
@@ -4025,7 +4036,7 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | |||
4025 | 4036 | ||
4026 | icid = le16_to_cpu(req->icid); | 4037 | icid = le16_to_cpu(req->icid); |
4027 | 4038 | ||
4028 | BT_DBG("icid %d, dest_amp_id %d", icid, req->dest_amp_id); | 4039 | BT_DBG("icid 0x%4.4x, dest_amp_id %d", icid, req->dest_amp_id); |
4029 | 4040 | ||
4030 | if (!enable_hs) | 4041 | if (!enable_hs) |
4031 | return -EINVAL; | 4042 | return -EINVAL; |
@@ -4037,7 +4048,8 @@ static inline int l2cap_move_channel_req(struct l2cap_conn *conn, | |||
4037 | } | 4048 | } |
4038 | 4049 | ||
4039 | static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, | 4050 | static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, |
4040 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | 4051 | struct l2cap_cmd_hdr *cmd, |
4052 | u16 cmd_len, void *data) | ||
4041 | { | 4053 | { |
4042 | struct l2cap_move_chan_rsp *rsp = data; | 4054 | struct l2cap_move_chan_rsp *rsp = data; |
4043 | u16 icid, result; | 4055 | u16 icid, result; |
@@ -4048,7 +4060,7 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, | |||
4048 | icid = le16_to_cpu(rsp->icid); | 4060 | icid = le16_to_cpu(rsp->icid); |
4049 | result = le16_to_cpu(rsp->result); | 4061 | result = le16_to_cpu(rsp->result); |
4050 | 4062 | ||
4051 | BT_DBG("icid %d, result %d", icid, result); | 4063 | BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); |
4052 | 4064 | ||
4053 | /* Placeholder: Always unconfirmed */ | 4065 | /* Placeholder: Always unconfirmed */ |
4054 | l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); | 4066 | l2cap_send_move_chan_cfm(conn, NULL, icid, L2CAP_MC_UNCONFIRMED); |
@@ -4057,7 +4069,8 @@ static inline int l2cap_move_channel_rsp(struct l2cap_conn *conn, | |||
4057 | } | 4069 | } |
4058 | 4070 | ||
4059 | static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, | 4071 | static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, |
4060 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | 4072 | struct l2cap_cmd_hdr *cmd, |
4073 | u16 cmd_len, void *data) | ||
4061 | { | 4074 | { |
4062 | struct l2cap_move_chan_cfm *cfm = data; | 4075 | struct l2cap_move_chan_cfm *cfm = data; |
4063 | u16 icid, result; | 4076 | u16 icid, result; |
@@ -4068,7 +4081,7 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, | |||
4068 | icid = le16_to_cpu(cfm->icid); | 4081 | icid = le16_to_cpu(cfm->icid); |
4069 | result = le16_to_cpu(cfm->result); | 4082 | result = le16_to_cpu(cfm->result); |
4070 | 4083 | ||
4071 | BT_DBG("icid %d, result %d", icid, result); | 4084 | BT_DBG("icid 0x%4.4x, result 0x%4.4x", icid, result); |
4072 | 4085 | ||
4073 | l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); | 4086 | l2cap_send_move_chan_cfm_rsp(conn, cmd->ident, icid); |
4074 | 4087 | ||
@@ -4076,7 +4089,8 @@ static inline int l2cap_move_channel_confirm(struct l2cap_conn *conn, | |||
4076 | } | 4089 | } |
4077 | 4090 | ||
4078 | static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, | 4091 | static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, |
4079 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, void *data) | 4092 | struct l2cap_cmd_hdr *cmd, |
4093 | u16 cmd_len, void *data) | ||
4080 | { | 4094 | { |
4081 | struct l2cap_move_chan_cfm_rsp *rsp = data; | 4095 | struct l2cap_move_chan_cfm_rsp *rsp = data; |
4082 | u16 icid; | 4096 | u16 icid; |
@@ -4086,7 +4100,7 @@ static inline int l2cap_move_channel_confirm_rsp(struct l2cap_conn *conn, | |||
4086 | 4100 | ||
4087 | icid = le16_to_cpu(rsp->icid); | 4101 | icid = le16_to_cpu(rsp->icid); |
4088 | 4102 | ||
4089 | BT_DBG("icid %d", icid); | 4103 | BT_DBG("icid 0x%4.4x", icid); |
4090 | 4104 | ||
4091 | return 0; | 4105 | return 0; |
4092 | } | 4106 | } |
@@ -5374,7 +5388,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
5374 | if (!conn) | 5388 | if (!conn) |
5375 | return 0; | 5389 | return 0; |
5376 | 5390 | ||
5377 | BT_DBG("conn %p", conn); | 5391 | BT_DBG("conn %p status 0x%2.2x encrypt %u", conn, status, encrypt); |
5378 | 5392 | ||
5379 | if (hcon->type == LE_LINK) { | 5393 | if (hcon->type == LE_LINK) { |
5380 | if (!status && encrypt) | 5394 | if (!status && encrypt) |
@@ -5387,7 +5401,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
5387 | list_for_each_entry(chan, &conn->chan_l, list) { | 5401 | list_for_each_entry(chan, &conn->chan_l, list) { |
5388 | l2cap_chan_lock(chan); | 5402 | l2cap_chan_lock(chan); |
5389 | 5403 | ||
5390 | BT_DBG("chan->scid %d", chan->scid); | 5404 | BT_DBG("chan %p scid 0x%4.4x state %s", chan, chan->scid, |
5405 | state_to_string(chan->state)); | ||
5391 | 5406 | ||
5392 | if (chan->scid == L2CAP_CID_LE_DATA) { | 5407 | if (chan->scid == L2CAP_CID_LE_DATA) { |
5393 | if (!status && encrypt) { | 5408 | if (!status && encrypt) { |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index a6e0f3d8da6c..ad6613d17ca6 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -210,7 +210,7 @@ static int cmd_status(struct sock *sk, u16 index, u16 cmd, u8 status) | |||
210 | 210 | ||
211 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); | 211 | BT_DBG("sock %p, index %u, cmd %u, status %u", sk, index, cmd, status); |
212 | 212 | ||
213 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_ATOMIC); | 213 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev), GFP_KERNEL); |
214 | if (!skb) | 214 | if (!skb) |
215 | return -ENOMEM; | 215 | return -ENOMEM; |
216 | 216 | ||
@@ -241,7 +241,7 @@ static int cmd_complete(struct sock *sk, u16 index, u16 cmd, u8 status, | |||
241 | 241 | ||
242 | BT_DBG("sock %p", sk); | 242 | BT_DBG("sock %p", sk); |
243 | 243 | ||
244 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_ATOMIC); | 244 | skb = alloc_skb(sizeof(*hdr) + sizeof(*ev) + rp_len, GFP_KERNEL); |
245 | if (!skb) | 245 | if (!skb) |
246 | return -ENOMEM; | 246 | return -ENOMEM; |
247 | 247 | ||
@@ -687,14 +687,14 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode, | |||
687 | { | 687 | { |
688 | struct pending_cmd *cmd; | 688 | struct pending_cmd *cmd; |
689 | 689 | ||
690 | cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC); | 690 | cmd = kmalloc(sizeof(*cmd), GFP_KERNEL); |
691 | if (!cmd) | 691 | if (!cmd) |
692 | return NULL; | 692 | return NULL; |
693 | 693 | ||
694 | cmd->opcode = opcode; | 694 | cmd->opcode = opcode; |
695 | cmd->index = hdev->id; | 695 | cmd->index = hdev->id; |
696 | 696 | ||
697 | cmd->param = kmalloc(len, GFP_ATOMIC); | 697 | cmd->param = kmalloc(len, GFP_KERNEL); |
698 | if (!cmd->param) { | 698 | if (!cmd->param) { |
699 | kfree(cmd); | 699 | kfree(cmd); |
700 | return NULL; | 700 | return NULL; |
@@ -812,7 +812,7 @@ static int mgmt_event(u16 event, struct hci_dev *hdev, void *data, u16 data_len, | |||
812 | struct sk_buff *skb; | 812 | struct sk_buff *skb; |
813 | struct mgmt_hdr *hdr; | 813 | struct mgmt_hdr *hdr; |
814 | 814 | ||
815 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC); | 815 | skb = alloc_skb(sizeof(*hdr) + data_len, GFP_KERNEL); |
816 | if (!skb) | 816 | if (!skb) |
817 | return -ENOMEM; | 817 | return -ENOMEM; |
818 | 818 | ||
@@ -1268,7 +1268,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len) | |||
1268 | goto failed; | 1268 | goto failed; |
1269 | } | 1269 | } |
1270 | 1270 | ||
1271 | uuid = kmalloc(sizeof(*uuid), GFP_ATOMIC); | 1271 | uuid = kmalloc(sizeof(*uuid), GFP_KERNEL); |
1272 | if (!uuid) { | 1272 | if (!uuid) { |
1273 | err = -ENOMEM; | 1273 | err = -ENOMEM; |
1274 | goto failed; | 1274 | goto failed; |
@@ -1611,7 +1611,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1611 | } | 1611 | } |
1612 | 1612 | ||
1613 | dc.handle = cpu_to_le16(conn->handle); | 1613 | dc.handle = cpu_to_le16(conn->handle); |
1614 | dc.reason = 0x13; /* Remote User Terminated Connection */ | 1614 | dc.reason = HCI_ERROR_REMOTE_USER_TERM; |
1615 | 1615 | ||
1616 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); | 1616 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); |
1617 | if (err < 0) | 1617 | if (err < 0) |
@@ -1667,7 +1667,7 @@ static int get_connections(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1667 | } | 1667 | } |
1668 | 1668 | ||
1669 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); | 1669 | rp_len = sizeof(*rp) + (i * sizeof(struct mgmt_addr_info)); |
1670 | rp = kmalloc(rp_len, GFP_ATOMIC); | 1670 | rp = kmalloc(rp_len, GFP_KERNEL); |
1671 | if (!rp) { | 1671 | if (!rp) { |
1672 | err = -ENOMEM; | 1672 | err = -ENOMEM; |
1673 | goto unlock; | 1673 | goto unlock; |
@@ -1778,29 +1778,6 @@ failed: | |||
1778 | return err; | 1778 | return err; |
1779 | } | 1779 | } |
1780 | 1780 | ||
1781 | static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev, | ||
1782 | void *data, u16 len) | ||
1783 | { | ||
1784 | struct mgmt_cp_pin_code_neg_reply *cp = data; | ||
1785 | int err; | ||
1786 | |||
1787 | BT_DBG(""); | ||
1788 | |||
1789 | hci_dev_lock(hdev); | ||
1790 | |||
1791 | if (!hdev_is_powered(hdev)) { | ||
1792 | err = cmd_status(sk, hdev->id, MGMT_OP_PIN_CODE_NEG_REPLY, | ||
1793 | MGMT_STATUS_NOT_POWERED); | ||
1794 | goto failed; | ||
1795 | } | ||
1796 | |||
1797 | err = send_pin_code_neg_reply(sk, hdev, cp); | ||
1798 | |||
1799 | failed: | ||
1800 | hci_dev_unlock(hdev); | ||
1801 | return err; | ||
1802 | } | ||
1803 | |||
1804 | static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, | 1781 | static int set_io_capability(struct sock *sk, struct hci_dev *hdev, void *data, |
1805 | u16 len) | 1782 | u16 len) |
1806 | { | 1783 | { |
@@ -2083,6 +2060,18 @@ done: | |||
2083 | return err; | 2060 | return err; |
2084 | } | 2061 | } |
2085 | 2062 | ||
2063 | static int pin_code_neg_reply(struct sock *sk, struct hci_dev *hdev, | ||
2064 | void *data, u16 len) | ||
2065 | { | ||
2066 | struct mgmt_cp_pin_code_neg_reply *cp = data; | ||
2067 | |||
2068 | BT_DBG(""); | ||
2069 | |||
2070 | return user_pairing_resp(sk, hdev, &cp->addr.bdaddr, cp->addr.type, | ||
2071 | MGMT_OP_PIN_CODE_NEG_REPLY, | ||
2072 | HCI_OP_PIN_CODE_NEG_REPLY, 0); | ||
2073 | } | ||
2074 | |||
2086 | static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data, | 2075 | static int user_confirm_reply(struct sock *sk, struct hci_dev *hdev, void *data, |
2087 | u16 len) | 2076 | u16 len) |
2088 | { | 2077 | { |
@@ -2607,8 +2596,8 @@ static int set_fast_connectable(struct sock *sk, struct hci_dev *hdev, | |||
2607 | if (cp->val) { | 2596 | if (cp->val) { |
2608 | type = PAGE_SCAN_TYPE_INTERLACED; | 2597 | type = PAGE_SCAN_TYPE_INTERLACED; |
2609 | 2598 | ||
2610 | /* 22.5 msec page scan interval */ | 2599 | /* 160 msec page scan interval */ |
2611 | acp.interval = __constant_cpu_to_le16(0x0024); | 2600 | acp.interval = __constant_cpu_to_le16(0x0100); |
2612 | } else { | 2601 | } else { |
2613 | type = PAGE_SCAN_TYPE_STANDARD; /* default */ | 2602 | type = PAGE_SCAN_TYPE_STANDARD; /* default */ |
2614 | 2603 | ||
@@ -3546,9 +3535,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
3546 | ev->addr.type = link_to_bdaddr(link_type, addr_type); | 3535 | ev->addr.type = link_to_bdaddr(link_type, addr_type); |
3547 | ev->rssi = rssi; | 3536 | ev->rssi = rssi; |
3548 | if (cfm_name) | 3537 | if (cfm_name) |
3549 | ev->flags[0] |= MGMT_DEV_FOUND_CONFIRM_NAME; | 3538 | ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_CONFIRM_NAME); |
3550 | if (!ssp) | 3539 | if (!ssp) |
3551 | ev->flags[0] |= MGMT_DEV_FOUND_LEGACY_PAIRING; | 3540 | ev->flags |= cpu_to_le32(MGMT_DEV_FOUND_LEGACY_PAIRING); |
3552 | 3541 | ||
3553 | if (eir_len > 0) | 3542 | if (eir_len > 0) |
3554 | memcpy(ev->eir, eir, eir_len); | 3543 | memcpy(ev->eir, eir, eir_len); |
@@ -3558,7 +3547,6 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
3558 | dev_class, 3); | 3547 | dev_class, 3); |
3559 | 3548 | ||
3560 | ev->eir_len = cpu_to_le16(eir_len); | 3549 | ev->eir_len = cpu_to_le16(eir_len); |
3561 | |||
3562 | ev_size = sizeof(*ev) + eir_len; | 3550 | ev_size = sizeof(*ev) + eir_len; |
3563 | 3551 | ||
3564 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); | 3552 | return mgmt_event(MGMT_EV_DEVICE_FOUND, hdev, ev, ev_size, NULL); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 5cc1bf7d8033..d0deb3edae21 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -135,7 +135,8 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) | |||
135 | bar->control = cpu_to_le16(bar_control); | 135 | bar->control = cpu_to_le16(bar_control); |
136 | bar->start_seq_num = cpu_to_le16(ssn); | 136 | bar->start_seq_num = cpu_to_le16(ssn); |
137 | 137 | ||
138 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 138 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | |
139 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
139 | ieee80211_tx_skb_tid(sdata, skb, tid); | 140 | ieee80211_tx_skb_tid(sdata, skb, tid); |
140 | } | 141 | } |
141 | EXPORT_SYMBOL(ieee80211_send_bar); | 142 | EXPORT_SYMBOL(ieee80211_send_bar); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ccbe2413142a..d41974aacf51 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -20,31 +20,31 @@ | |||
20 | #include "rate.h" | 20 | #include "rate.h" |
21 | #include "mesh.h" | 21 | #include "mesh.h" |
22 | 22 | ||
23 | static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, | 23 | static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name, |
24 | enum nl80211_iftype type, | 24 | enum nl80211_iftype type, |
25 | u32 *flags, | 25 | u32 *flags, |
26 | struct vif_params *params) | 26 | struct vif_params *params) |
27 | { | 27 | { |
28 | struct ieee80211_local *local = wiphy_priv(wiphy); | 28 | struct ieee80211_local *local = wiphy_priv(wiphy); |
29 | struct net_device *dev; | 29 | struct wireless_dev *wdev; |
30 | struct ieee80211_sub_if_data *sdata; | 30 | struct ieee80211_sub_if_data *sdata; |
31 | int err; | 31 | int err; |
32 | 32 | ||
33 | err = ieee80211_if_add(local, name, &dev, type, params); | 33 | err = ieee80211_if_add(local, name, &wdev, type, params); |
34 | if (err) | 34 | if (err) |
35 | return ERR_PTR(err); | 35 | return ERR_PTR(err); |
36 | 36 | ||
37 | if (type == NL80211_IFTYPE_MONITOR && flags) { | 37 | if (type == NL80211_IFTYPE_MONITOR && flags) { |
38 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 38 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
39 | sdata->u.mntr_flags = *flags; | 39 | sdata->u.mntr_flags = *flags; |
40 | } | 40 | } |
41 | 41 | ||
42 | return dev; | 42 | return wdev; |
43 | } | 43 | } |
44 | 44 | ||
45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) | 45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) |
46 | { | 46 | { |
47 | ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); | 47 | ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev)); |
48 | 48 | ||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
@@ -917,6 +917,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
917 | 917 | ||
918 | kfree_rcu(old, rcu_head); | 918 | kfree_rcu(old, rcu_head); |
919 | 919 | ||
920 | sta_info_flush(sdata->local, sdata); | ||
920 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 921 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
921 | 922 | ||
922 | return 0; | 923 | return 0; |
@@ -1741,6 +1742,8 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1741 | return -EINVAL; | 1742 | return -EINVAL; |
1742 | } | 1743 | } |
1743 | 1744 | ||
1745 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | ||
1746 | |||
1744 | return 0; | 1747 | return 0; |
1745 | } | 1748 | } |
1746 | 1749 | ||
@@ -1761,10 +1764,11 @@ static int ieee80211_resume(struct wiphy *wiphy) | |||
1761 | #endif | 1764 | #endif |
1762 | 1765 | ||
1763 | static int ieee80211_scan(struct wiphy *wiphy, | 1766 | static int ieee80211_scan(struct wiphy *wiphy, |
1764 | struct net_device *dev, | ||
1765 | struct cfg80211_scan_request *req) | 1767 | struct cfg80211_scan_request *req) |
1766 | { | 1768 | { |
1767 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1769 | struct ieee80211_sub_if_data *sdata; |
1770 | |||
1771 | sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev); | ||
1768 | 1772 | ||
1769 | switch (ieee80211_vif_type_p2p(&sdata->vif)) { | 1773 | switch (ieee80211_vif_type_p2p(&sdata->vif)) { |
1770 | case NL80211_IFTYPE_STATION: | 1774 | case NL80211_IFTYPE_STATION: |
@@ -2297,13 +2301,13 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2297 | } | 2301 | } |
2298 | 2302 | ||
2299 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, | 2303 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, |
2300 | struct net_device *dev, | 2304 | struct wireless_dev *wdev, |
2301 | struct ieee80211_channel *chan, | 2305 | struct ieee80211_channel *chan, |
2302 | enum nl80211_channel_type channel_type, | 2306 | enum nl80211_channel_type channel_type, |
2303 | unsigned int duration, | 2307 | unsigned int duration, |
2304 | u64 *cookie) | 2308 | u64 *cookie) |
2305 | { | 2309 | { |
2306 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2310 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2307 | struct ieee80211_local *local = sdata->local; | 2311 | struct ieee80211_local *local = sdata->local; |
2308 | int ret; | 2312 | int ret; |
2309 | 2313 | ||
@@ -2390,23 +2394,23 @@ static int ieee80211_cancel_roc(struct ieee80211_local *local, | |||
2390 | } | 2394 | } |
2391 | 2395 | ||
2392 | static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, | 2396 | static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, |
2393 | struct net_device *dev, | 2397 | struct wireless_dev *wdev, |
2394 | u64 cookie) | 2398 | u64 cookie) |
2395 | { | 2399 | { |
2396 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2400 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2397 | struct ieee80211_local *local = sdata->local; | 2401 | struct ieee80211_local *local = sdata->local; |
2398 | 2402 | ||
2399 | return ieee80211_cancel_roc(local, cookie, false); | 2403 | return ieee80211_cancel_roc(local, cookie, false); |
2400 | } | 2404 | } |
2401 | 2405 | ||
2402 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | 2406 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
2403 | struct ieee80211_channel *chan, bool offchan, | 2407 | struct ieee80211_channel *chan, bool offchan, |
2404 | enum nl80211_channel_type channel_type, | 2408 | enum nl80211_channel_type channel_type, |
2405 | bool channel_type_valid, unsigned int wait, | 2409 | bool channel_type_valid, unsigned int wait, |
2406 | const u8 *buf, size_t len, bool no_cck, | 2410 | const u8 *buf, size_t len, bool no_cck, |
2407 | bool dont_wait_for_ack, u64 *cookie) | 2411 | bool dont_wait_for_ack, u64 *cookie) |
2408 | { | 2412 | { |
2409 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2413 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2410 | struct ieee80211_local *local = sdata->local; | 2414 | struct ieee80211_local *local = sdata->local; |
2411 | struct sk_buff *skb; | 2415 | struct sk_buff *skb; |
2412 | struct sta_info *sta; | 2416 | struct sta_info *sta; |
@@ -2490,6 +2494,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2490 | skb->dev = sdata->dev; | 2494 | skb->dev = sdata->dev; |
2491 | 2495 | ||
2492 | if (!need_offchan) { | 2496 | if (!need_offchan) { |
2497 | *cookie = (unsigned long) skb; | ||
2493 | ieee80211_tx_skb(sdata, skb); | 2498 | ieee80211_tx_skb(sdata, skb); |
2494 | ret = 0; | 2499 | ret = 0; |
2495 | goto out_unlock; | 2500 | goto out_unlock; |
@@ -2511,21 +2516,20 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2511 | } | 2516 | } |
2512 | 2517 | ||
2513 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | 2518 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, |
2514 | struct net_device *dev, | 2519 | struct wireless_dev *wdev, |
2515 | u64 cookie) | 2520 | u64 cookie) |
2516 | { | 2521 | { |
2517 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2522 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2518 | struct ieee80211_local *local = sdata->local; | ||
2519 | 2523 | ||
2520 | return ieee80211_cancel_roc(local, cookie, true); | 2524 | return ieee80211_cancel_roc(local, cookie, true); |
2521 | } | 2525 | } |
2522 | 2526 | ||
2523 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | 2527 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, |
2524 | struct net_device *dev, | 2528 | struct wireless_dev *wdev, |
2525 | u16 frame_type, bool reg) | 2529 | u16 frame_type, bool reg) |
2526 | { | 2530 | { |
2527 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2531 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2528 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2532 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2529 | 2533 | ||
2530 | switch (frame_type) { | 2534 | switch (frame_type) { |
2531 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: | 2535 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: |
@@ -2980,14 +2984,14 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
2980 | return 0; | 2984 | return 0; |
2981 | } | 2985 | } |
2982 | 2986 | ||
2983 | static void ieee80211_set_monitor_enabled(struct wiphy *wiphy, bool enabled) | 2987 | static struct ieee80211_channel * |
2988 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, | ||
2989 | enum nl80211_channel_type *type) | ||
2984 | { | 2990 | { |
2985 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2991 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2986 | 2992 | ||
2987 | if (enabled) | 2993 | *type = local->_oper_channel_type; |
2988 | WARN_ON(ieee80211_add_virtual_monitor(local)); | 2994 | return local->oper_channel; |
2989 | else | ||
2990 | ieee80211_del_virtual_monitor(local); | ||
2991 | } | 2995 | } |
2992 | 2996 | ||
2993 | #ifdef CONFIG_PM | 2997 | #ifdef CONFIG_PM |
@@ -3064,11 +3068,11 @@ struct cfg80211_ops mac80211_config_ops = { | |||
3064 | .tdls_mgmt = ieee80211_tdls_mgmt, | 3068 | .tdls_mgmt = ieee80211_tdls_mgmt, |
3065 | .probe_client = ieee80211_probe_client, | 3069 | .probe_client = ieee80211_probe_client, |
3066 | .set_noack_map = ieee80211_set_noack_map, | 3070 | .set_noack_map = ieee80211_set_noack_map, |
3067 | .set_monitor_enabled = ieee80211_set_monitor_enabled, | ||
3068 | #ifdef CONFIG_PM | 3071 | #ifdef CONFIG_PM |
3069 | .set_wakeup = ieee80211_set_wakeup, | 3072 | .set_wakeup = ieee80211_set_wakeup, |
3070 | #endif | 3073 | #endif |
3071 | .get_et_sset_count = ieee80211_get_et_sset_count, | 3074 | .get_et_sset_count = ieee80211_get_et_sset_count, |
3072 | .get_et_stats = ieee80211_get_et_stats, | 3075 | .get_et_stats = ieee80211_get_et_stats, |
3073 | .get_et_strings = ieee80211_get_et_strings, | 3076 | .get_et_strings = ieee80211_get_et_strings, |
3077 | .get_channel = ieee80211_cfg_get_channel, | ||
3074 | }; | 3078 | }; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 778e5916d7c3..b8dfb440c8ef 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -325,8 +325,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
325 | local->rx_handlers_drop_defrag); | 325 | local->rx_handlers_drop_defrag); |
326 | DEBUGFS_STATS_ADD(rx_handlers_drop_short, | 326 | DEBUGFS_STATS_ADD(rx_handlers_drop_short, |
327 | local->rx_handlers_drop_short); | 327 | local->rx_handlers_drop_short); |
328 | DEBUGFS_STATS_ADD(rx_handlers_drop_passive_scan, | ||
329 | local->rx_handlers_drop_passive_scan); | ||
330 | DEBUGFS_STATS_ADD(tx_expand_skb_head, | 328 | DEBUGFS_STATS_ADD(tx_expand_skb_head, |
331 | local->tx_expand_skb_head); | 329 | local->tx_expand_skb_head); |
332 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, | 330 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e0423f8c0ce1..bb61f7718c4c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -85,6 +85,8 @@ struct ieee80211_bss { | |||
85 | size_t ssid_len; | 85 | size_t ssid_len; |
86 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 86 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
87 | 87 | ||
88 | u32 device_ts; | ||
89 | |||
88 | u8 dtim_period; | 90 | u8 dtim_period; |
89 | 91 | ||
90 | bool wmm_used; | 92 | bool wmm_used; |
@@ -207,7 +209,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
207 | * enum ieee80211_packet_rx_flags - packet RX flags | 209 | * enum ieee80211_packet_rx_flags - packet RX flags |
208 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed | 210 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed |
209 | * (incl. multicast frames) | 211 | * (incl. multicast frames) |
210 | * @IEEE80211_RX_IN_SCAN: received while scanning | ||
211 | * @IEEE80211_RX_FRAGMENTED: fragmented frame | 212 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
212 | * @IEEE80211_RX_AMSDU: a-MSDU packet | 213 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
213 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | 214 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed |
@@ -217,7 +218,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
217 | * @rx_flags field of &struct ieee80211_rx_status. | 218 | * @rx_flags field of &struct ieee80211_rx_status. |
218 | */ | 219 | */ |
219 | enum ieee80211_packet_rx_flags { | 220 | enum ieee80211_packet_rx_flags { |
220 | IEEE80211_RX_IN_SCAN = BIT(0), | ||
221 | IEEE80211_RX_RA_MATCH = BIT(1), | 221 | IEEE80211_RX_RA_MATCH = BIT(1), |
222 | IEEE80211_RX_FRAGMENTED = BIT(2), | 222 | IEEE80211_RX_FRAGMENTED = BIT(2), |
223 | IEEE80211_RX_AMSDU = BIT(3), | 223 | IEEE80211_RX_AMSDU = BIT(3), |
@@ -965,14 +965,14 @@ struct ieee80211_local { | |||
965 | int scan_channel_idx; | 965 | int scan_channel_idx; |
966 | int scan_ies_len; | 966 | int scan_ies_len; |
967 | 967 | ||
968 | bool sched_scanning; | ||
969 | struct ieee80211_sched_scan_ies sched_scan_ies; | 968 | struct ieee80211_sched_scan_ies sched_scan_ies; |
970 | struct work_struct sched_scan_stopped_work; | 969 | struct work_struct sched_scan_stopped_work; |
970 | struct ieee80211_sub_if_data __rcu *sched_scan_sdata; | ||
971 | 971 | ||
972 | unsigned long leave_oper_channel_time; | 972 | unsigned long leave_oper_channel_time; |
973 | enum mac80211_scan_state next_scan_state; | 973 | enum mac80211_scan_state next_scan_state; |
974 | struct delayed_work scan_work; | 974 | struct delayed_work scan_work; |
975 | struct ieee80211_sub_if_data *scan_sdata; | 975 | struct ieee80211_sub_if_data __rcu *scan_sdata; |
976 | enum nl80211_channel_type _oper_channel_type; | 976 | enum nl80211_channel_type _oper_channel_type; |
977 | struct ieee80211_channel *oper_channel, *csa_channel; | 977 | struct ieee80211_channel *oper_channel, *csa_channel; |
978 | 978 | ||
@@ -1014,7 +1014,6 @@ struct ieee80211_local { | |||
1014 | unsigned int rx_handlers_drop_nullfunc; | 1014 | unsigned int rx_handlers_drop_nullfunc; |
1015 | unsigned int rx_handlers_drop_defrag; | 1015 | unsigned int rx_handlers_drop_defrag; |
1016 | unsigned int rx_handlers_drop_short; | 1016 | unsigned int rx_handlers_drop_short; |
1017 | unsigned int rx_handlers_drop_passive_scan; | ||
1018 | unsigned int tx_expand_skb_head; | 1017 | unsigned int tx_expand_skb_head; |
1019 | unsigned int tx_expand_skb_head_cloned; | 1018 | unsigned int tx_expand_skb_head_cloned; |
1020 | unsigned int rx_expand_skb_head; | 1019 | unsigned int rx_expand_skb_head; |
@@ -1091,6 +1090,12 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | |||
1091 | return netdev_priv(dev); | 1090 | return netdev_priv(dev); |
1092 | } | 1091 | } |
1093 | 1092 | ||
1093 | static inline struct ieee80211_sub_if_data * | ||
1094 | IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev) | ||
1095 | { | ||
1096 | return container_of(wdev, struct ieee80211_sub_if_data, wdev); | ||
1097 | } | ||
1098 | |||
1094 | /* this struct represents 802.11n's RA/TID combination */ | 1099 | /* this struct represents 802.11n's RA/TID combination */ |
1095 | struct ieee80211_ra_tid { | 1100 | struct ieee80211_ra_tid { |
1096 | u8 ra[ETH_ALEN]; | 1101 | u8 ra[ETH_ALEN]; |
@@ -1241,8 +1246,7 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
1241 | struct cfg80211_scan_request *req); | 1246 | struct cfg80211_scan_request *req); |
1242 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 1247 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
1243 | void ieee80211_run_deferred_scan(struct ieee80211_local *local); | 1248 | void ieee80211_run_deferred_scan(struct ieee80211_local *local); |
1244 | ieee80211_rx_result | 1249 | void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb); |
1245 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | ||
1246 | 1250 | ||
1247 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); | 1251 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); |
1248 | struct ieee80211_bss * | 1252 | struct ieee80211_bss * |
@@ -1278,7 +1282,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | |||
1278 | int ieee80211_iface_init(void); | 1282 | int ieee80211_iface_init(void); |
1279 | void ieee80211_iface_exit(void); | 1283 | void ieee80211_iface_exit(void); |
1280 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1284 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1281 | struct net_device **new_dev, enum nl80211_iftype type, | 1285 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1282 | struct vif_params *params); | 1286 | struct vif_params *params); |
1283 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 1287 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
1284 | enum nl80211_iftype type); | 1288 | enum nl80211_iftype type); |
@@ -1487,10 +1491,6 @@ int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, | |||
1487 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, | 1491 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, |
1488 | struct sk_buff *skb, bool need_basic); | 1492 | struct sk_buff *skb, bool need_basic); |
1489 | 1493 | ||
1490 | /* virtual monitor */ | ||
1491 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local); | ||
1492 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local); | ||
1493 | |||
1494 | /* channel management */ | 1494 | /* channel management */ |
1495 | enum ieee80211_chan_mode { | 1495 | enum ieee80211_chan_mode { |
1496 | CHAN_MODE_UNDEFINED, | 1496 | CHAN_MODE_UNDEFINED, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index fbef7a1ada7a..bfb57dcc1538 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -112,10 +112,11 @@ static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | if (local->scan_sdata && | 115 | sdata = rcu_dereference_protected(local->scan_sdata, |
116 | !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | 116 | lockdep_is_held(&local->mtx)); |
117 | if (sdata && !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
117 | scanning = true; | 118 | scanning = true; |
118 | local->scan_sdata->vif.bss_conf.idle = false; | 119 | sdata->vif.bss_conf.idle = false; |
119 | } | 120 | } |
120 | 121 | ||
121 | list_for_each_entry(sdata, &local->interfaces, list) { | 122 | list_for_each_entry(sdata, &local->interfaces, list) { |
@@ -330,20 +331,24 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) | |||
330 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; | 331 | sdata->vif.cab_queue = IEEE80211_INVAL_HW_QUEUE; |
331 | } | 332 | } |
332 | 333 | ||
333 | int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 334 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) |
334 | { | 335 | { |
335 | struct ieee80211_sub_if_data *sdata; | 336 | struct ieee80211_sub_if_data *sdata; |
336 | int ret; | 337 | int ret = 0; |
337 | 338 | ||
338 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 339 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
339 | return 0; | 340 | return 0; |
340 | 341 | ||
342 | mutex_lock(&local->iflist_mtx); | ||
343 | |||
341 | if (local->monitor_sdata) | 344 | if (local->monitor_sdata) |
342 | return 0; | 345 | goto out_unlock; |
343 | 346 | ||
344 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); | 347 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); |
345 | if (!sdata) | 348 | if (!sdata) { |
346 | return -ENOMEM; | 349 | ret = -ENOMEM; |
350 | goto out_unlock; | ||
351 | } | ||
347 | 352 | ||
348 | /* set up data */ | 353 | /* set up data */ |
349 | sdata->local = local; | 354 | sdata->local = local; |
@@ -357,31 +362,34 @@ int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
357 | if (WARN_ON(ret)) { | 362 | if (WARN_ON(ret)) { |
358 | /* ok .. stupid driver, it asked for this! */ | 363 | /* ok .. stupid driver, it asked for this! */ |
359 | kfree(sdata); | 364 | kfree(sdata); |
360 | return ret; | 365 | goto out_unlock; |
361 | } | 366 | } |
362 | 367 | ||
363 | ret = ieee80211_check_queues(sdata); | 368 | ret = ieee80211_check_queues(sdata); |
364 | if (ret) { | 369 | if (ret) { |
365 | kfree(sdata); | 370 | kfree(sdata); |
366 | return ret; | 371 | goto out_unlock; |
367 | } | 372 | } |
368 | 373 | ||
369 | rcu_assign_pointer(local->monitor_sdata, sdata); | 374 | rcu_assign_pointer(local->monitor_sdata, sdata); |
370 | 375 | out_unlock: | |
371 | return 0; | 376 | mutex_unlock(&local->iflist_mtx); |
377 | return ret; | ||
372 | } | 378 | } |
373 | 379 | ||
374 | void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 380 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) |
375 | { | 381 | { |
376 | struct ieee80211_sub_if_data *sdata; | 382 | struct ieee80211_sub_if_data *sdata; |
377 | 383 | ||
378 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 384 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
379 | return; | 385 | return; |
380 | 386 | ||
381 | sdata = rtnl_dereference(local->monitor_sdata); | 387 | mutex_lock(&local->iflist_mtx); |
382 | 388 | ||
389 | sdata = rcu_dereference_protected(local->monitor_sdata, | ||
390 | lockdep_is_held(&local->iflist_mtx)); | ||
383 | if (!sdata) | 391 | if (!sdata) |
384 | return; | 392 | goto out_unlock; |
385 | 393 | ||
386 | rcu_assign_pointer(local->monitor_sdata, NULL); | 394 | rcu_assign_pointer(local->monitor_sdata, NULL); |
387 | synchronize_net(); | 395 | synchronize_net(); |
@@ -389,6 +397,8 @@ void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
389 | drv_remove_interface(local, sdata); | 397 | drv_remove_interface(local, sdata); |
390 | 398 | ||
391 | kfree(sdata); | 399 | kfree(sdata); |
400 | out_unlock: | ||
401 | mutex_unlock(&local->iflist_mtx); | ||
392 | } | 402 | } |
393 | 403 | ||
394 | /* | 404 | /* |
@@ -487,6 +497,12 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
487 | break; | 497 | break; |
488 | } | 498 | } |
489 | 499 | ||
500 | if (local->monitors == 0 && local->open_count == 0) { | ||
501 | res = ieee80211_add_virtual_monitor(local); | ||
502 | if (res) | ||
503 | goto err_stop; | ||
504 | } | ||
505 | |||
490 | /* must be before the call to ieee80211_configure_filter */ | 506 | /* must be before the call to ieee80211_configure_filter */ |
491 | local->monitors++; | 507 | local->monitors++; |
492 | if (local->monitors == 1) { | 508 | if (local->monitors == 1) { |
@@ -501,6 +517,8 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up) | |||
501 | break; | 517 | break; |
502 | default: | 518 | default: |
503 | if (coming_up) { | 519 | if (coming_up) { |
520 | ieee80211_del_virtual_monitor(local); | ||
521 | |||
504 | res = drv_add_interface(local, sdata); | 522 | res = drv_add_interface(local, sdata); |
505 | if (res) | 523 | if (res) |
506 | goto err_stop; | 524 | goto err_stop; |
@@ -628,7 +646,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
628 | 646 | ||
629 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | 647 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); |
630 | 648 | ||
631 | if (local->scan_sdata == sdata) | 649 | if (rcu_access_pointer(local->scan_sdata) == sdata) |
632 | ieee80211_scan_cancel(local); | 650 | ieee80211_scan_cancel(local); |
633 | 651 | ||
634 | /* | 652 | /* |
@@ -735,6 +753,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
735 | if (local->monitors == 0) { | 753 | if (local->monitors == 0) { |
736 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; | 754 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; |
737 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; | 755 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
756 | ieee80211_del_virtual_monitor(local); | ||
738 | } | 757 | } |
739 | 758 | ||
740 | ieee80211_adjust_monitor_flags(sdata, -1); | 759 | ieee80211_adjust_monitor_flags(sdata, -1); |
@@ -808,6 +827,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
808 | } | 827 | } |
809 | } | 828 | } |
810 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 829 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
830 | |||
831 | if (local->monitors == local->open_count && local->monitors > 0) | ||
832 | ieee80211_add_virtual_monitor(local); | ||
811 | } | 833 | } |
812 | 834 | ||
813 | static int ieee80211_stop(struct net_device *dev) | 835 | static int ieee80211_stop(struct net_device *dev) |
@@ -1373,7 +1395,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1373 | } | 1395 | } |
1374 | 1396 | ||
1375 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1397 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1376 | struct net_device **new_dev, enum nl80211_iftype type, | 1398 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1377 | struct vif_params *params) | 1399 | struct vif_params *params) |
1378 | { | 1400 | { |
1379 | struct net_device *ndev; | 1401 | struct net_device *ndev; |
@@ -1463,8 +1485,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1463 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 1485 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
1464 | mutex_unlock(&local->iflist_mtx); | 1486 | mutex_unlock(&local->iflist_mtx); |
1465 | 1487 | ||
1466 | if (new_dev) | 1488 | if (new_wdev) |
1467 | *new_dev = ndev; | 1489 | *new_wdev = &sdata->wdev; |
1468 | 1490 | ||
1469 | return 0; | 1491 | return 0; |
1470 | 1492 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index b3b7e526e245..7ae678ba5d67 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -194,26 +194,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
194 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 194 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
195 | } | 195 | } |
196 | 196 | ||
197 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | ||
198 | { | ||
199 | struct ieee80211_key *key; | ||
200 | |||
201 | key = container_of(key_conf, struct ieee80211_key, conf); | ||
202 | |||
203 | might_sleep(); | ||
204 | assert_key_lock(key->local); | ||
205 | |||
206 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
207 | |||
208 | /* | ||
209 | * Flush TX path to avoid attempts to use this key | ||
210 | * after this function returns. Until then, drivers | ||
211 | * must be prepared to handle the key. | ||
212 | */ | ||
213 | synchronize_rcu(); | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(ieee80211_key_removed); | ||
216 | |||
217 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, | 197 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, |
218 | int idx, bool uni, bool multi) | 198 | int idx, bool uni, bool multi) |
219 | { | 199 | { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c794101f8987..c26e231c733a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -322,7 +322,8 @@ static void ieee80211_restart_work(struct work_struct *work) | |||
322 | 322 | ||
323 | mutex_lock(&local->mtx); | 323 | mutex_lock(&local->mtx); |
324 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 324 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
325 | local->sched_scanning, | 325 | rcu_dereference_protected(local->sched_scan_sdata, |
326 | lockdep_is_held(&local->mtx)), | ||
326 | "%s called with hardware scan in progress\n", __func__); | 327 | "%s called with hardware scan in progress\n", __func__); |
327 | mutex_unlock(&local->mtx); | 328 | mutex_unlock(&local->mtx); |
328 | 329 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f49f14f8ba82..cef0c9e79aba 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1108,7 +1108,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | /* MLME */ | 1110 | /* MLME */ |
1111 | static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | 1111 | static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, |
1112 | struct ieee80211_sub_if_data *sdata, | 1112 | struct ieee80211_sub_if_data *sdata, |
1113 | u8 *wmm_param, size_t wmm_param_len) | 1113 | u8 *wmm_param, size_t wmm_param_len) |
1114 | { | 1114 | { |
@@ -1119,23 +1119,23 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1119 | u8 *pos, uapsd_queues = 0; | 1119 | u8 *pos, uapsd_queues = 0; |
1120 | 1120 | ||
1121 | if (!local->ops->conf_tx) | 1121 | if (!local->ops->conf_tx) |
1122 | return; | 1122 | return false; |
1123 | 1123 | ||
1124 | if (local->hw.queues < IEEE80211_NUM_ACS) | 1124 | if (local->hw.queues < IEEE80211_NUM_ACS) |
1125 | return; | 1125 | return false; |
1126 | 1126 | ||
1127 | if (!wmm_param) | 1127 | if (!wmm_param) |
1128 | return; | 1128 | return false; |
1129 | 1129 | ||
1130 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 1130 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
1131 | return; | 1131 | return false; |
1132 | 1132 | ||
1133 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | 1133 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) |
1134 | uapsd_queues = ifmgd->uapsd_queues; | 1134 | uapsd_queues = ifmgd->uapsd_queues; |
1135 | 1135 | ||
1136 | count = wmm_param[6] & 0x0f; | 1136 | count = wmm_param[6] & 0x0f; |
1137 | if (count == ifmgd->wmm_last_param_set) | 1137 | if (count == ifmgd->wmm_last_param_set) |
1138 | return; | 1138 | return false; |
1139 | ifmgd->wmm_last_param_set = count; | 1139 | ifmgd->wmm_last_param_set = count; |
1140 | 1140 | ||
1141 | pos = wmm_param + 8; | 1141 | pos = wmm_param + 8; |
@@ -1202,6 +1202,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1202 | 1202 | ||
1203 | /* enable WMM or activate new settings */ | 1203 | /* enable WMM or activate new settings */ |
1204 | sdata->vif.bss_conf.qos = true; | 1204 | sdata->vif.bss_conf.qos = true; |
1205 | return true; | ||
1205 | } | 1206 | } |
1206 | 1207 | ||
1207 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | 1208 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) |
@@ -1268,11 +1269,6 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1268 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 1269 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1269 | 1270 | ||
1270 | bss_info_changed |= BSS_CHANGED_ASSOC; | 1271 | bss_info_changed |= BSS_CHANGED_ASSOC; |
1271 | /* set timing information */ | ||
1272 | bss_conf->beacon_int = cbss->beacon_interval; | ||
1273 | bss_conf->last_tsf = cbss->tsf; | ||
1274 | |||
1275 | bss_info_changed |= BSS_CHANGED_BEACON_INT; | ||
1276 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 1272 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
1277 | bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); | 1273 | bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); |
1278 | 1274 | ||
@@ -1364,6 +1360,17 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1364 | } | 1360 | } |
1365 | mutex_unlock(&local->sta_mtx); | 1361 | mutex_unlock(&local->sta_mtx); |
1366 | 1362 | ||
1363 | /* | ||
1364 | * if we want to get out of ps before disassoc (why?) we have | ||
1365 | * to do it before sending disassoc, as otherwise the null-packet | ||
1366 | * won't be valid. | ||
1367 | */ | ||
1368 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1369 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
1370 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
1371 | } | ||
1372 | local->ps_sdata = NULL; | ||
1373 | |||
1367 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ | 1374 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ |
1368 | if (tx) | 1375 | if (tx) |
1369 | drv_flush(local, false); | 1376 | drv_flush(local, false); |
@@ -1399,12 +1406,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1399 | del_timer_sync(&local->dynamic_ps_timer); | 1406 | del_timer_sync(&local->dynamic_ps_timer); |
1400 | cancel_work_sync(&local->dynamic_ps_enable_work); | 1407 | cancel_work_sync(&local->dynamic_ps_enable_work); |
1401 | 1408 | ||
1402 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1403 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
1404 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
1405 | } | ||
1406 | local->ps_sdata = NULL; | ||
1407 | |||
1408 | /* Disable ARP filtering */ | 1409 | /* Disable ARP filtering */ |
1409 | if (sdata->vif.bss_conf.arp_filter_enabled) { | 1410 | if (sdata->vif.bss_conf.arp_filter_enabled) { |
1410 | sdata->vif.bss_conf.arp_filter_enabled = false; | 1411 | sdata->vif.bss_conf.arp_filter_enabled = false; |
@@ -2435,14 +2436,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2435 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, | 2436 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, |
2436 | ifmgd->aid); | 2437 | ifmgd->aid); |
2437 | 2438 | ||
2438 | if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) { | ||
2439 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, | ||
2440 | true); | ||
2441 | |||
2442 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | ||
2443 | elems.wmm_param_len); | ||
2444 | } | ||
2445 | |||
2446 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { | 2439 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { |
2447 | if (directed_tim) { | 2440 | if (directed_tim) { |
2448 | if (local->hw.conf.dynamic_ps_timeout > 0) { | 2441 | if (local->hw.conf.dynamic_ps_timeout > 0) { |
@@ -2473,6 +2466,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2473 | ifmgd->beacon_crc = ncrc; | 2466 | ifmgd->beacon_crc = ncrc; |
2474 | ifmgd->beacon_crc_valid = true; | 2467 | ifmgd->beacon_crc_valid = true; |
2475 | 2468 | ||
2469 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, | ||
2470 | true); | ||
2471 | |||
2472 | if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | ||
2473 | elems.wmm_param_len)) | ||
2474 | changed |= BSS_CHANGED_QOS; | ||
2475 | |||
2476 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2476 | if (elems.erp_info && elems.erp_info_len >= 1) { |
2477 | erp_valid = true; | 2477 | erp_valid = true; |
2478 | erp_value = elems.erp_info[0]; | 2478 | erp_value = elems.erp_info[0]; |
@@ -2974,7 +2974,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
2974 | /* scan finished notification */ | 2974 | /* scan finished notification */ |
2975 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) | 2975 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) |
2976 | { | 2976 | { |
2977 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 2977 | struct ieee80211_sub_if_data *sdata; |
2978 | 2978 | ||
2979 | /* Restart STA timers */ | 2979 | /* Restart STA timers */ |
2980 | rcu_read_lock(); | 2980 | rcu_read_lock(); |
@@ -3132,9 +3132,15 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3132 | 3132 | ||
3133 | memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); | 3133 | memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); |
3134 | 3134 | ||
3135 | /* tell driver about BSSID and basic rates */ | 3135 | /* set timing information */ |
3136 | sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; | ||
3137 | sdata->vif.bss_conf.sync_tsf = cbss->tsf; | ||
3138 | sdata->vif.bss_conf.sync_device_ts = bss->device_ts; | ||
3139 | |||
3140 | /* tell driver about BSSID, basic rates and timing */ | ||
3136 | ieee80211_bss_info_change_notify(sdata, | 3141 | ieee80211_bss_info_change_notify(sdata, |
3137 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); | 3142 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES | |
3143 | BSS_CHANGED_BEACON_INT); | ||
3138 | 3144 | ||
3139 | if (assoc) | 3145 | if (assoc) |
3140 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | 3146 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); |
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index b0fb6a2b89ad..635c3250c668 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -191,7 +191,7 @@ void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) | |||
191 | roc->frame = NULL; | 191 | roc->frame = NULL; |
192 | } | 192 | } |
193 | } else { | 193 | } else { |
194 | cfg80211_ready_on_channel(roc->sdata->dev, (unsigned long)roc, | 194 | cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, |
195 | roc->chan, roc->chan_type, | 195 | roc->chan, roc->chan_type, |
196 | roc->req_duration, GFP_KERNEL); | 196 | roc->req_duration, GFP_KERNEL); |
197 | } | 197 | } |
@@ -299,7 +299,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) | |||
299 | 299 | ||
300 | /* was never transmitted */ | 300 | /* was never transmitted */ |
301 | if (roc->frame) { | 301 | if (roc->frame) { |
302 | cfg80211_mgmt_tx_status(roc->sdata->dev, | 302 | cfg80211_mgmt_tx_status(&roc->sdata->wdev, |
303 | (unsigned long)roc->frame, | 303 | (unsigned long)roc->frame, |
304 | roc->frame->data, roc->frame->len, | 304 | roc->frame->data, roc->frame->len, |
305 | false, GFP_KERNEL); | 305 | false, GFP_KERNEL); |
@@ -307,7 +307,7 @@ void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) | |||
307 | } | 307 | } |
308 | 308 | ||
309 | if (!roc->mgmt_tx_cookie) | 309 | if (!roc->mgmt_tx_cookie) |
310 | cfg80211_remain_on_channel_expired(roc->sdata->dev, | 310 | cfg80211_remain_on_channel_expired(&roc->sdata->wdev, |
311 | (unsigned long)roc, | 311 | (unsigned long)roc, |
312 | roc->chan, roc->chan_type, | 312 | roc->chan, roc->chan_type, |
313 | GFP_KERNEL); | 313 | GFP_KERNEL); |
@@ -324,6 +324,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
324 | container_of(work, struct ieee80211_roc_work, work.work); | 324 | container_of(work, struct ieee80211_roc_work, work.work); |
325 | struct ieee80211_sub_if_data *sdata = roc->sdata; | 325 | struct ieee80211_sub_if_data *sdata = roc->sdata; |
326 | struct ieee80211_local *local = sdata->local; | 326 | struct ieee80211_local *local = sdata->local; |
327 | bool started; | ||
327 | 328 | ||
328 | mutex_lock(&local->mtx); | 329 | mutex_lock(&local->mtx); |
329 | 330 | ||
@@ -366,9 +367,10 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
366 | /* finish this ROC */ | 367 | /* finish this ROC */ |
367 | finish: | 368 | finish: |
368 | list_del(&roc->list); | 369 | list_del(&roc->list); |
370 | started = roc->started; | ||
369 | ieee80211_roc_notify_destroy(roc); | 371 | ieee80211_roc_notify_destroy(roc); |
370 | 372 | ||
371 | if (roc->started) { | 373 | if (started) { |
372 | drv_flush(local, false); | 374 | drv_flush(local, false); |
373 | 375 | ||
374 | local->tmp_channel = NULL; | 376 | local->tmp_channel = NULL; |
@@ -379,7 +381,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) | |||
379 | 381 | ||
380 | ieee80211_recalc_idle(local); | 382 | ieee80211_recalc_idle(local); |
381 | 383 | ||
382 | if (roc->started) | 384 | if (started) |
383 | ieee80211_start_next_roc(local); | 385 | ieee80211_start_next_roc(local); |
384 | } | 386 | } |
385 | 387 | ||
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index f9e51ef8dfa2..fb1d4aa65e8c 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -626,8 +626,12 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
626 | 626 | ||
627 | #ifdef CONFIG_MAC80211_DEBUGFS | 627 | #ifdef CONFIG_MAC80211_DEBUGFS |
628 | /* use fixed index if set */ | 628 | /* use fixed index if set */ |
629 | if (mp->fixed_rate_idx != -1) | 629 | if (mp->fixed_rate_idx != -1) { |
630 | sample_idx = mp->fixed_rate_idx; | 630 | mi->max_tp_rate = mp->fixed_rate_idx; |
631 | mi->max_tp_rate2 = mp->fixed_rate_idx; | ||
632 | mi->max_prob_rate = mp->fixed_rate_idx; | ||
633 | sample_idx = -1; | ||
634 | } | ||
631 | #endif | 635 | #endif |
632 | 636 | ||
633 | if (sample_idx >= 0) { | 637 | if (sample_idx >= 0) { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 67edd69e8421..0cb4edee6af5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -413,29 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) | |||
413 | 413 | ||
414 | /* rx handlers */ | 414 | /* rx handlers */ |
415 | 415 | ||
416 | static ieee80211_rx_result debug_noinline | ||
417 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | ||
418 | { | ||
419 | struct ieee80211_local *local = rx->local; | ||
420 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
421 | struct sk_buff *skb = rx->skb; | ||
422 | |||
423 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | ||
424 | !local->sched_scanning)) | ||
425 | return RX_CONTINUE; | ||
426 | |||
427 | if (test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
428 | test_bit(SCAN_SW_SCANNING, &local->scanning) || | ||
429 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
430 | local->sched_scanning) | ||
431 | return ieee80211_scan_rx(rx->sdata, skb); | ||
432 | |||
433 | /* scanning finished during invoking of handlers */ | ||
434 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | ||
435 | return RX_DROP_UNUSABLE; | ||
436 | } | ||
437 | |||
438 | |||
439 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) | 416 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) |
440 | { | 417 | { |
441 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 418 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -2404,7 +2381,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2404 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 2381 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
2405 | sig = status->signal; | 2382 | sig = status->signal; |
2406 | 2383 | ||
2407 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, | 2384 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, |
2408 | rx->skb->data, rx->skb->len, | 2385 | rx->skb->data, rx->skb->len, |
2409 | GFP_ATOMIC)) { | 2386 | GFP_ATOMIC)) { |
2410 | if (rx->sta) | 2387 | if (rx->sta) |
@@ -2695,7 +2672,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) | |||
2695 | goto rxh_next; \ | 2672 | goto rxh_next; \ |
2696 | } while (0); | 2673 | } while (0); |
2697 | 2674 | ||
2698 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2699 | CALL_RXH(ieee80211_rx_h_check) | 2675 | CALL_RXH(ieee80211_rx_h_check) |
2700 | 2676 | ||
2701 | ieee80211_rx_reorder_ampdu(rx); | 2677 | ieee80211_rx_reorder_ampdu(rx); |
@@ -2765,11 +2741,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2765 | return 0; | 2741 | return 0; |
2766 | if (ieee80211_is_beacon(hdr->frame_control)) { | 2742 | if (ieee80211_is_beacon(hdr->frame_control)) { |
2767 | return 1; | 2743 | return 1; |
2768 | } | 2744 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2769 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2745 | return 0; |
2770 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) | ||
2771 | return 0; | ||
2772 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
2773 | } else if (!multicast && | 2746 | } else if (!multicast && |
2774 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 2747 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
2775 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2748 | if (!(sdata->dev->flags & IFF_PROMISC)) |
@@ -2807,11 +2780,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2807 | * and location updates. Note that mac80211 | 2780 | * and location updates. Note that mac80211 |
2808 | * itself never looks at these frames. | 2781 | * itself never looks at these frames. |
2809 | */ | 2782 | */ |
2810 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2783 | if (ieee80211_is_public_action(hdr, skb->len)) |
2811 | ieee80211_is_public_action(hdr, skb->len)) | ||
2812 | return 1; | 2784 | return 1; |
2813 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2785 | if (!ieee80211_is_beacon(hdr->frame_control)) |
2814 | !ieee80211_is_beacon(hdr->frame_control)) | ||
2815 | return 0; | 2786 | return 0; |
2816 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 2787 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2817 | } | 2788 | } |
@@ -2877,7 +2848,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2877 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2848 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2878 | struct sk_buff *skb) | 2849 | struct sk_buff *skb) |
2879 | { | 2850 | { |
2880 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2881 | struct ieee80211_local *local = hw_to_local(hw); | 2851 | struct ieee80211_local *local = hw_to_local(hw); |
2882 | struct ieee80211_sub_if_data *sdata; | 2852 | struct ieee80211_sub_if_data *sdata; |
2883 | struct ieee80211_hdr *hdr; | 2853 | struct ieee80211_hdr *hdr; |
@@ -2895,11 +2865,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2895 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 2865 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
2896 | local->dot11ReceivedFragmentCount++; | 2866 | local->dot11ReceivedFragmentCount++; |
2897 | 2867 | ||
2898 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
2899 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
2900 | test_bit(SCAN_SW_SCANNING, &local->scanning))) | ||
2901 | status->rx_flags |= IEEE80211_RX_IN_SCAN; | ||
2902 | |||
2903 | if (ieee80211_is_mgmt(fc)) | 2868 | if (ieee80211_is_mgmt(fc)) |
2904 | err = skb_linearize(skb); | 2869 | err = skb_linearize(skb); |
2905 | else | 2870 | else |
@@ -2914,6 +2879,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2914 | ieee80211_parse_qos(&rx); | 2879 | ieee80211_parse_qos(&rx); |
2915 | ieee80211_verify_alignment(&rx); | 2880 | ieee80211_verify_alignment(&rx); |
2916 | 2881 | ||
2882 | if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) || | ||
2883 | ieee80211_is_beacon(hdr->frame_control))) | ||
2884 | ieee80211_scan_rx(local, skb); | ||
2885 | |||
2917 | if (ieee80211_is_data(fc)) { | 2886 | if (ieee80211_is_data(fc)) { |
2918 | prev_sta = NULL; | 2887 | prev_sta = NULL; |
2919 | 2888 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 267b2940fadd..bcaee5d12839 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -83,13 +83,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
83 | 83 | ||
84 | cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, | 84 | cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, |
85 | mgmt, len, signal, GFP_ATOMIC); | 85 | mgmt, len, signal, GFP_ATOMIC); |
86 | |||
87 | if (!cbss) | 86 | if (!cbss) |
88 | return NULL; | 87 | return NULL; |
89 | 88 | ||
90 | cbss->free_priv = ieee80211_rx_bss_free; | 89 | cbss->free_priv = ieee80211_rx_bss_free; |
91 | bss = (void *)cbss->priv; | 90 | bss = (void *)cbss->priv; |
92 | 91 | ||
92 | bss->device_ts = rx_status->device_timestamp; | ||
93 | |||
93 | if (elems->parse_error) { | 94 | if (elems->parse_error) { |
94 | if (beacon) | 95 | if (beacon) |
95 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; | 96 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; |
@@ -164,52 +165,47 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
164 | return bss; | 165 | return bss; |
165 | } | 166 | } |
166 | 167 | ||
167 | ieee80211_rx_result | 168 | void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) |
168 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | ||
169 | { | 169 | { |
170 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); | 170 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); |
171 | struct ieee80211_mgmt *mgmt; | 171 | struct ieee80211_sub_if_data *sdata1, *sdata2; |
172 | struct ieee80211_mgmt *mgmt = (void *)skb->data; | ||
172 | struct ieee80211_bss *bss; | 173 | struct ieee80211_bss *bss; |
173 | u8 *elements; | 174 | u8 *elements; |
174 | struct ieee80211_channel *channel; | 175 | struct ieee80211_channel *channel; |
175 | size_t baselen; | 176 | size_t baselen; |
176 | int freq; | 177 | int freq; |
177 | __le16 fc; | 178 | bool beacon; |
178 | bool presp, beacon = false; | ||
179 | struct ieee802_11_elems elems; | 179 | struct ieee802_11_elems elems; |
180 | 180 | ||
181 | if (skb->len < 2) | 181 | if (skb->len < 24 || |
182 | return RX_DROP_UNUSABLE; | 182 | (!ieee80211_is_probe_resp(mgmt->frame_control) && |
183 | 183 | !ieee80211_is_beacon(mgmt->frame_control))) | |
184 | mgmt = (struct ieee80211_mgmt *) skb->data; | 184 | return; |
185 | fc = mgmt->frame_control; | ||
186 | 185 | ||
187 | if (ieee80211_is_ctl(fc)) | 186 | sdata1 = rcu_dereference(local->scan_sdata); |
188 | return RX_CONTINUE; | 187 | sdata2 = rcu_dereference(local->sched_scan_sdata); |
189 | 188 | ||
190 | if (skb->len < 24) | 189 | if (likely(!sdata1 && !sdata2)) |
191 | return RX_CONTINUE; | 190 | return; |
192 | 191 | ||
193 | presp = ieee80211_is_probe_resp(fc); | 192 | if (ieee80211_is_probe_resp(mgmt->frame_control)) { |
194 | if (presp) { | ||
195 | /* ignore ProbeResp to foreign address */ | 193 | /* ignore ProbeResp to foreign address */ |
196 | if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) | 194 | if ((!sdata1 || !ether_addr_equal(mgmt->da, sdata1->vif.addr)) && |
197 | return RX_DROP_MONITOR; | 195 | (!sdata2 || !ether_addr_equal(mgmt->da, sdata2->vif.addr))) |
196 | return; | ||
198 | 197 | ||
199 | presp = true; | ||
200 | elements = mgmt->u.probe_resp.variable; | 198 | elements = mgmt->u.probe_resp.variable; |
201 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | 199 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); |
200 | beacon = false; | ||
202 | } else { | 201 | } else { |
203 | beacon = ieee80211_is_beacon(fc); | ||
204 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); | 202 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); |
205 | elements = mgmt->u.beacon.variable; | 203 | elements = mgmt->u.beacon.variable; |
204 | beacon = true; | ||
206 | } | 205 | } |
207 | 206 | ||
208 | if (!presp && !beacon) | ||
209 | return RX_CONTINUE; | ||
210 | |||
211 | if (baselen > skb->len) | 207 | if (baselen > skb->len) |
212 | return RX_DROP_MONITOR; | 208 | return; |
213 | 209 | ||
214 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); | 210 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); |
215 | 211 | ||
@@ -219,22 +215,16 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
219 | else | 215 | else |
220 | freq = rx_status->freq; | 216 | freq = rx_status->freq; |
221 | 217 | ||
222 | channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq); | 218 | channel = ieee80211_get_channel(local->hw.wiphy, freq); |
223 | 219 | ||
224 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 220 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
225 | return RX_DROP_MONITOR; | 221 | return; |
226 | 222 | ||
227 | bss = ieee80211_bss_info_update(sdata->local, rx_status, | 223 | bss = ieee80211_bss_info_update(local, rx_status, |
228 | mgmt, skb->len, &elems, | 224 | mgmt, skb->len, &elems, |
229 | channel, beacon); | 225 | channel, beacon); |
230 | if (bss) | 226 | if (bss) |
231 | ieee80211_rx_bss_put(sdata->local, bss); | 227 | ieee80211_rx_bss_put(local, bss); |
232 | |||
233 | if (channel == sdata->local->oper_channel) | ||
234 | return RX_CONTINUE; | ||
235 | |||
236 | dev_kfree_skb(skb); | ||
237 | return RX_QUEUED; | ||
238 | } | 228 | } |
239 | 229 | ||
240 | /* return false if no more work */ | 230 | /* return false if no more work */ |
@@ -292,7 +282,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
292 | return; | 282 | return; |
293 | 283 | ||
294 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { | 284 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { |
295 | int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); | 285 | int rc; |
286 | |||
287 | rc = drv_hw_scan(local, | ||
288 | rcu_dereference_protected(local->scan_sdata, | ||
289 | lockdep_is_held(&local->mtx)), | ||
290 | local->hw_scan_req); | ||
291 | |||
296 | if (rc == 0) | 292 | if (rc == 0) |
297 | return; | 293 | return; |
298 | } | 294 | } |
@@ -393,7 +389,10 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local) | |||
393 | if (!local->scan_req || local->scanning) | 389 | if (!local->scan_req || local->scanning) |
394 | return; | 390 | return; |
395 | 391 | ||
396 | if (!ieee80211_can_scan(local, local->scan_sdata)) | 392 | if (!ieee80211_can_scan(local, |
393 | rcu_dereference_protected( | ||
394 | local->scan_sdata, | ||
395 | lockdep_is_held(&local->mtx)))) | ||
397 | return; | 396 | return; |
398 | 397 | ||
399 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, | 398 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, |
@@ -404,9 +403,12 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
404 | unsigned long *next_delay) | 403 | unsigned long *next_delay) |
405 | { | 404 | { |
406 | int i; | 405 | int i; |
407 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 406 | struct ieee80211_sub_if_data *sdata; |
408 | enum ieee80211_band band = local->hw.conf.channel->band; | 407 | enum ieee80211_band band = local->hw.conf.channel->band; |
409 | 408 | ||
409 | sdata = rcu_dereference_protected(local->scan_sdata, | ||
410 | lockdep_is_held(&local->mtx));; | ||
411 | |||
410 | for (i = 0; i < local->scan_req->n_ssids; i++) | 412 | for (i = 0; i < local->scan_req->n_ssids; i++) |
411 | ieee80211_send_probe_req( | 413 | ieee80211_send_probe_req( |
412 | sdata, NULL, | 414 | sdata, NULL, |
@@ -438,7 +440,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
438 | if (!ieee80211_can_scan(local, sdata)) { | 440 | if (!ieee80211_can_scan(local, sdata)) { |
439 | /* wait for the work to finish/time out */ | 441 | /* wait for the work to finish/time out */ |
440 | local->scan_req = req; | 442 | local->scan_req = req; |
441 | local->scan_sdata = sdata; | 443 | rcu_assign_pointer(local->scan_sdata, sdata); |
442 | return 0; | 444 | return 0; |
443 | } | 445 | } |
444 | 446 | ||
@@ -472,7 +474,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
472 | } | 474 | } |
473 | 475 | ||
474 | local->scan_req = req; | 476 | local->scan_req = req; |
475 | local->scan_sdata = sdata; | 477 | rcu_assign_pointer(local->scan_sdata, sdata); |
476 | 478 | ||
477 | if (local->ops->hw_scan) { | 479 | if (local->ops->hw_scan) { |
478 | __set_bit(SCAN_HW_SCANNING, &local->scanning); | 480 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
@@ -532,7 +534,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
532 | ieee80211_recalc_idle(local); | 534 | ieee80211_recalc_idle(local); |
533 | 535 | ||
534 | local->scan_req = NULL; | 536 | local->scan_req = NULL; |
535 | local->scan_sdata = NULL; | 537 | rcu_assign_pointer(local->scan_sdata, NULL); |
536 | } | 538 | } |
537 | 539 | ||
538 | return rc; | 540 | return rc; |
@@ -719,7 +721,8 @@ void ieee80211_scan_work(struct work_struct *work) | |||
719 | 721 | ||
720 | mutex_lock(&local->mtx); | 722 | mutex_lock(&local->mtx); |
721 | 723 | ||
722 | sdata = local->scan_sdata; | 724 | sdata = rcu_dereference_protected(local->scan_sdata, |
725 | lockdep_is_held(&local->mtx)); | ||
723 | 726 | ||
724 | /* When scanning on-channel, the first-callback means completed. */ | 727 | /* When scanning on-channel, the first-callback means completed. */ |
725 | if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { | 728 | if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { |
@@ -740,7 +743,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
740 | int rc; | 743 | int rc; |
741 | 744 | ||
742 | local->scan_req = NULL; | 745 | local->scan_req = NULL; |
743 | local->scan_sdata = NULL; | 746 | rcu_assign_pointer(local->scan_sdata, NULL); |
744 | 747 | ||
745 | rc = __ieee80211_start_scan(sdata, req); | 748 | rc = __ieee80211_start_scan(sdata, req); |
746 | if (rc) { | 749 | if (rc) { |
@@ -892,7 +895,9 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
892 | 895 | ||
893 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { | 896 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
894 | if (local->ops->cancel_hw_scan) | 897 | if (local->ops->cancel_hw_scan) |
895 | drv_cancel_hw_scan(local, local->scan_sdata); | 898 | drv_cancel_hw_scan(local, |
899 | rcu_dereference_protected(local->scan_sdata, | ||
900 | lockdep_is_held(&local->mtx))); | ||
896 | goto out; | 901 | goto out; |
897 | } | 902 | } |
898 | 903 | ||
@@ -914,9 +919,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
914 | struct ieee80211_local *local = sdata->local; | 919 | struct ieee80211_local *local = sdata->local; |
915 | int ret, i; | 920 | int ret, i; |
916 | 921 | ||
917 | mutex_lock(&sdata->local->mtx); | 922 | mutex_lock(&local->mtx); |
918 | 923 | ||
919 | if (local->sched_scanning) { | 924 | if (rcu_access_pointer(local->sched_scan_sdata)) { |
920 | ret = -EBUSY; | 925 | ret = -EBUSY; |
921 | goto out; | 926 | goto out; |
922 | } | 927 | } |
@@ -927,6 +932,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
927 | } | 932 | } |
928 | 933 | ||
929 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 934 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
935 | if (!local->hw.wiphy->bands[i]) | ||
936 | continue; | ||
937 | |||
930 | local->sched_scan_ies.ie[i] = kzalloc(2 + | 938 | local->sched_scan_ies.ie[i] = kzalloc(2 + |
931 | IEEE80211_MAX_SSID_LEN + | 939 | IEEE80211_MAX_SSID_LEN + |
932 | local->scan_ies_len + | 940 | local->scan_ies_len + |
@@ -947,7 +955,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
947 | ret = drv_sched_scan_start(local, sdata, req, | 955 | ret = drv_sched_scan_start(local, sdata, req, |
948 | &local->sched_scan_ies); | 956 | &local->sched_scan_ies); |
949 | if (ret == 0) { | 957 | if (ret == 0) { |
950 | local->sched_scanning = true; | 958 | rcu_assign_pointer(local->sched_scan_sdata, sdata); |
951 | goto out; | 959 | goto out; |
952 | } | 960 | } |
953 | 961 | ||
@@ -955,7 +963,7 @@ out_free: | |||
955 | while (i > 0) | 963 | while (i > 0) |
956 | kfree(local->sched_scan_ies.ie[--i]); | 964 | kfree(local->sched_scan_ies.ie[--i]); |
957 | out: | 965 | out: |
958 | mutex_unlock(&sdata->local->mtx); | 966 | mutex_unlock(&local->mtx); |
959 | return ret; | 967 | return ret; |
960 | } | 968 | } |
961 | 969 | ||
@@ -964,22 +972,22 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) | |||
964 | struct ieee80211_local *local = sdata->local; | 972 | struct ieee80211_local *local = sdata->local; |
965 | int ret = 0, i; | 973 | int ret = 0, i; |
966 | 974 | ||
967 | mutex_lock(&sdata->local->mtx); | 975 | mutex_lock(&local->mtx); |
968 | 976 | ||
969 | if (!local->ops->sched_scan_stop) { | 977 | if (!local->ops->sched_scan_stop) { |
970 | ret = -ENOTSUPP; | 978 | ret = -ENOTSUPP; |
971 | goto out; | 979 | goto out; |
972 | } | 980 | } |
973 | 981 | ||
974 | if (local->sched_scanning) { | 982 | if (rcu_access_pointer(local->sched_scan_sdata)) { |
975 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 983 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
976 | kfree(local->sched_scan_ies.ie[i]); | 984 | kfree(local->sched_scan_ies.ie[i]); |
977 | 985 | ||
978 | drv_sched_scan_stop(local, sdata); | 986 | drv_sched_scan_stop(local, sdata); |
979 | local->sched_scanning = false; | 987 | rcu_assign_pointer(local->sched_scan_sdata, NULL); |
980 | } | 988 | } |
981 | out: | 989 | out: |
982 | mutex_unlock(&sdata->local->mtx); | 990 | mutex_unlock(&local->mtx); |
983 | 991 | ||
984 | return ret; | 992 | return ret; |
985 | } | 993 | } |
@@ -1003,7 +1011,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work) | |||
1003 | 1011 | ||
1004 | mutex_lock(&local->mtx); | 1012 | mutex_lock(&local->mtx); |
1005 | 1013 | ||
1006 | if (!local->sched_scanning) { | 1014 | if (!rcu_access_pointer(local->sched_scan_sdata)) { |
1007 | mutex_unlock(&local->mtx); | 1015 | mutex_unlock(&local->mtx); |
1008 | return; | 1016 | return; |
1009 | } | 1017 | } |
@@ -1011,7 +1019,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work) | |||
1011 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 1019 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
1012 | kfree(local->sched_scan_ies.ie[i]); | 1020 | kfree(local->sched_scan_ies.ie[i]); |
1013 | 1021 | ||
1014 | local->sched_scanning = false; | 1022 | rcu_assign_pointer(local->sched_scan_sdata, NULL); |
1015 | 1023 | ||
1016 | mutex_unlock(&local->mtx); | 1024 | mutex_unlock(&local->mtx); |
1017 | 1025 | ||
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 2ed2f27fe8a7..8cd72914cdaf 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -519,14 +519,19 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
519 | u64 cookie = (unsigned long)skb; | 519 | u64 cookie = (unsigned long)skb; |
520 | acked = info->flags & IEEE80211_TX_STAT_ACK; | 520 | acked = info->flags & IEEE80211_TX_STAT_ACK; |
521 | 521 | ||
522 | /* | ||
523 | * TODO: When we have non-netdev frame TX, | ||
524 | * we cannot use skb->dev->ieee80211_ptr | ||
525 | */ | ||
526 | |||
522 | if (ieee80211_is_nullfunc(hdr->frame_control) || | 527 | if (ieee80211_is_nullfunc(hdr->frame_control) || |
523 | ieee80211_is_qos_nullfunc(hdr->frame_control)) | 528 | ieee80211_is_qos_nullfunc(hdr->frame_control)) |
524 | cfg80211_probe_status(skb->dev, hdr->addr1, | 529 | cfg80211_probe_status(skb->dev, hdr->addr1, |
525 | cookie, acked, GFP_ATOMIC); | 530 | cookie, acked, GFP_ATOMIC); |
526 | else | 531 | else |
527 | cfg80211_mgmt_tx_status( | 532 | cfg80211_mgmt_tx_status( |
528 | skb->dev, cookie, skb->data, skb->len, | 533 | skb->dev->ieee80211_ptr, cookie, skb->data, |
529 | acked, GFP_ATOMIC); | 534 | skb->len, acked, GFP_ATOMIC); |
530 | } | 535 | } |
531 | 536 | ||
532 | if (unlikely(info->ack_frame_id)) { | 537 | if (unlikely(info->ack_frame_id)) { |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index e1e9d10ec2e7..c6d33b55b2df 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -306,7 +306,8 @@ TRACE_EVENT(drv_bss_info_changed, | |||
306 | __field(u8, dtimper) | 306 | __field(u8, dtimper) |
307 | __field(u16, bcnint) | 307 | __field(u16, bcnint) |
308 | __field(u16, assoc_cap) | 308 | __field(u16, assoc_cap) |
309 | __field(u64, timestamp) | 309 | __field(u64, sync_tsf) |
310 | __field(u32, sync_device_ts) | ||
310 | __field(u32, basic_rates) | 311 | __field(u32, basic_rates) |
311 | __field(u32, changed) | 312 | __field(u32, changed) |
312 | __field(bool, enable_beacon) | 313 | __field(bool, enable_beacon) |
@@ -325,7 +326,8 @@ TRACE_EVENT(drv_bss_info_changed, | |||
325 | __entry->dtimper = info->dtim_period; | 326 | __entry->dtimper = info->dtim_period; |
326 | __entry->bcnint = info->beacon_int; | 327 | __entry->bcnint = info->beacon_int; |
327 | __entry->assoc_cap = info->assoc_capability; | 328 | __entry->assoc_cap = info->assoc_capability; |
328 | __entry->timestamp = info->last_tsf; | 329 | __entry->sync_tsf = info->sync_tsf; |
330 | __entry->sync_device_ts = info->sync_device_ts; | ||
329 | __entry->basic_rates = info->basic_rates; | 331 | __entry->basic_rates = info->basic_rates; |
330 | __entry->enable_beacon = info->enable_beacon; | 332 | __entry->enable_beacon = info->enable_beacon; |
331 | __entry->ht_operation_mode = info->ht_operation_mode; | 333 | __entry->ht_operation_mode = info->ht_operation_mode; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c9d2175d15c1..acf712ffb5e6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -523,7 +523,7 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | |||
523 | static ieee80211_tx_result debug_noinline | 523 | static ieee80211_tx_result debug_noinline |
524 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 524 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
525 | { | 525 | { |
526 | struct ieee80211_key *key = NULL; | 526 | struct ieee80211_key *key; |
527 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 527 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
529 | 529 | ||
@@ -542,16 +542,23 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
542 | else if (!is_multicast_ether_addr(hdr->addr1) && | 542 | else if (!is_multicast_ether_addr(hdr->addr1) && |
543 | (key = rcu_dereference(tx->sdata->default_unicast_key))) | 543 | (key = rcu_dereference(tx->sdata->default_unicast_key))) |
544 | tx->key = key; | 544 | tx->key = key; |
545 | else if (tx->sdata->drop_unencrypted && | 545 | else if (info->flags & IEEE80211_TX_CTL_INJECTED) |
546 | (tx->skb->protocol != tx->sdata->control_port_protocol) && | 546 | tx->key = NULL; |
547 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 547 | else if (!tx->sdata->drop_unencrypted) |
548 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 548 | tx->key = NULL; |
549 | (ieee80211_is_action(hdr->frame_control) && | 549 | else if (tx->skb->protocol == tx->sdata->control_port_protocol) |
550 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) { | 550 | tx->key = NULL; |
551 | else if (ieee80211_is_robust_mgmt_frame(hdr) && | ||
552 | !(ieee80211_is_action(hdr->frame_control) && | ||
553 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP))) | ||
554 | tx->key = NULL; | ||
555 | else if (ieee80211_is_mgmt(hdr->frame_control) && | ||
556 | !ieee80211_is_robust_mgmt_frame(hdr)) | ||
557 | tx->key = NULL; | ||
558 | else { | ||
551 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 559 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
552 | return TX_DROP; | 560 | return TX_DROP; |
553 | } else | 561 | } |
554 | tx->key = NULL; | ||
555 | 562 | ||
556 | if (tx->key) { | 563 | if (tx->key) { |
557 | bool skip_hw = false; | 564 | bool skip_hw = false; |
@@ -1817,6 +1824,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1817 | /* RA TA mDA mSA AE:DA SA */ | 1824 | /* RA TA mDA mSA AE:DA SA */ |
1818 | mesh_da = mppath->mpp; | 1825 | mesh_da = mppath->mpp; |
1819 | is_mesh_mcast = 0; | 1826 | is_mesh_mcast = 0; |
1827 | } else if (mpath) { | ||
1828 | mesh_da = mpath->dst; | ||
1829 | is_mesh_mcast = 0; | ||
1820 | } else { | 1830 | } else { |
1821 | /* DA TA mSA AE:SA */ | 1831 | /* DA TA mSA AE:SA */ |
1822 | mesh_da = bcast; | 1832 | mesh_da = bcast; |
@@ -2714,7 +2724,7 @@ EXPORT_SYMBOL(ieee80211_get_buffered_bc); | |||
2714 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, | 2724 | void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata, |
2715 | struct sk_buff *skb, int tid) | 2725 | struct sk_buff *skb, int tid) |
2716 | { | 2726 | { |
2717 | int ac = ieee802_1d_to_ac[tid]; | 2727 | int ac = ieee802_1d_to_ac[tid & 7]; |
2718 | 2728 | ||
2719 | skb_set_mac_header(skb, 0); | 2729 | skb_set_mac_header(skb, 0); |
2720 | skb_set_network_header(skb, 0); | 2730 | skb_set_network_header(skb, 0); |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 64493a7bef1a..39b82fee4904 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -529,6 +529,11 @@ void ieee80211_iterate_active_interfaces( | |||
529 | &sdata->vif); | 529 | &sdata->vif); |
530 | } | 530 | } |
531 | 531 | ||
532 | sdata = rcu_dereference_protected(local->monitor_sdata, | ||
533 | lockdep_is_held(&local->iflist_mtx)); | ||
534 | if (sdata) | ||
535 | iterator(data, sdata->vif.addr, &sdata->vif); | ||
536 | |||
532 | mutex_unlock(&local->iflist_mtx); | 537 | mutex_unlock(&local->iflist_mtx); |
533 | } | 538 | } |
534 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); | 539 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); |
@@ -557,6 +562,10 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
557 | &sdata->vif); | 562 | &sdata->vif); |
558 | } | 563 | } |
559 | 564 | ||
565 | sdata = rcu_dereference(local->monitor_sdata); | ||
566 | if (sdata) | ||
567 | iterator(data, sdata->vif.addr, &sdata->vif); | ||
568 | |||
560 | rcu_read_unlock(); | 569 | rcu_read_unlock(); |
561 | } | 570 | } |
562 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 571 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |
@@ -999,6 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
999 | int ext_rates_len; | 1008 | int ext_rates_len; |
1000 | 1009 | ||
1001 | sband = local->hw.wiphy->bands[band]; | 1010 | sband = local->hw.wiphy->bands[band]; |
1011 | if (WARN_ON_ONCE(!sband)) | ||
1012 | return 0; | ||
1002 | 1013 | ||
1003 | pos = buffer; | 1014 | pos = buffer; |
1004 | 1015 | ||
diff --git a/net/nfc/hci/core.c b/net/nfc/hci/core.c index 36717cebfbb6..1ac7b3fac6c9 100644 --- a/net/nfc/hci/core.c +++ b/net/nfc/hci/core.c | |||
@@ -187,6 +187,7 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) | |||
187 | struct nfc_target *targets; | 187 | struct nfc_target *targets; |
188 | struct sk_buff *atqa_skb = NULL; | 188 | struct sk_buff *atqa_skb = NULL; |
189 | struct sk_buff *sak_skb = NULL; | 189 | struct sk_buff *sak_skb = NULL; |
190 | struct sk_buff *uid_skb = NULL; | ||
190 | int r; | 191 | int r; |
191 | 192 | ||
192 | pr_debug("from gate %d\n", gate); | 193 | pr_debug("from gate %d\n", gate); |
@@ -222,6 +223,19 @@ static int nfc_hci_target_discovered(struct nfc_hci_dev *hdev, u8 gate) | |||
222 | targets->sens_res = be16_to_cpu(*(u16 *)atqa_skb->data); | 223 | targets->sens_res = be16_to_cpu(*(u16 *)atqa_skb->data); |
223 | targets->sel_res = sak_skb->data[0]; | 224 | targets->sel_res = sak_skb->data[0]; |
224 | 225 | ||
226 | r = nfc_hci_get_param(hdev, NFC_HCI_RF_READER_A_GATE, | ||
227 | NFC_HCI_RF_READER_A_UID, &uid_skb); | ||
228 | if (r < 0) | ||
229 | goto exit; | ||
230 | |||
231 | if (uid_skb->len == 0 || uid_skb->len > NFC_NFCID1_MAXSIZE) { | ||
232 | r = -EPROTO; | ||
233 | goto exit; | ||
234 | } | ||
235 | |||
236 | memcpy(targets->nfcid1, uid_skb->data, uid_skb->len); | ||
237 | targets->nfcid1_len = uid_skb->len; | ||
238 | |||
225 | if (hdev->ops->complete_target_discovered) { | 239 | if (hdev->ops->complete_target_discovered) { |
226 | r = hdev->ops->complete_target_discovered(hdev, gate, | 240 | r = hdev->ops->complete_target_discovered(hdev, gate, |
227 | targets); | 241 | targets); |
@@ -257,6 +271,7 @@ exit: | |||
257 | kfree(targets); | 271 | kfree(targets); |
258 | kfree_skb(atqa_skb); | 272 | kfree_skb(atqa_skb); |
259 | kfree_skb(sak_skb); | 273 | kfree_skb(sak_skb); |
274 | kfree_skb(uid_skb); | ||
260 | 275 | ||
261 | return r; | 276 | return r; |
262 | } | 277 | } |
@@ -695,13 +710,12 @@ EXPORT_SYMBOL(nfc_hci_register_device); | |||
695 | 710 | ||
696 | void nfc_hci_unregister_device(struct nfc_hci_dev *hdev) | 711 | void nfc_hci_unregister_device(struct nfc_hci_dev *hdev) |
697 | { | 712 | { |
698 | struct hci_msg *msg; | 713 | struct hci_msg *msg, *n; |
699 | 714 | ||
700 | skb_queue_purge(&hdev->rx_hcp_frags); | 715 | skb_queue_purge(&hdev->rx_hcp_frags); |
701 | skb_queue_purge(&hdev->msg_rx_queue); | 716 | skb_queue_purge(&hdev->msg_rx_queue); |
702 | 717 | ||
703 | while ((msg = list_first_entry(&hdev->msg_tx_queue, struct hci_msg, | 718 | list_for_each_entry_safe(msg, n, &hdev->msg_tx_queue, msg_l) { |
704 | msg_l)) != NULL) { | ||
705 | list_del(&msg->msg_l); | 719 | list_del(&msg->msg_l); |
706 | skb_queue_purge(&msg->msg_frags); | 720 | skb_queue_purge(&msg->msg_frags); |
707 | kfree(msg); | 721 | kfree(msg); |
diff --git a/net/nfc/hci/hcp.c b/net/nfc/hci/hcp.c index 7212cf2c5785..f4dad1a89740 100644 --- a/net/nfc/hci/hcp.c +++ b/net/nfc/hci/hcp.c | |||
@@ -105,7 +105,7 @@ int nfc_hci_hcp_message_tx(struct nfc_hci_dev *hdev, u8 pipe, | |||
105 | } | 105 | } |
106 | 106 | ||
107 | mutex_lock(&hdev->msg_tx_mutex); | 107 | mutex_lock(&hdev->msg_tx_mutex); |
108 | list_add_tail(&hdev->msg_tx_queue, &cmd->msg_l); | 108 | list_add_tail(&cmd->msg_l, &hdev->msg_tx_queue); |
109 | mutex_unlock(&hdev->msg_tx_mutex); | 109 | mutex_unlock(&hdev->msg_tx_mutex); |
110 | 110 | ||
111 | queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work); | 111 | queue_work(hdev->msg_tx_wq, &hdev->msg_tx_work); |
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 5bb4da680427..f81efe13985a 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ | 28 | #define pr_fmt(fmt) KBUILD_MODNAME ": %s: " fmt, __func__ |
29 | 29 | ||
30 | #include <linux/module.h> | ||
30 | #include <linux/types.h> | 31 | #include <linux/types.h> |
31 | #include <linux/workqueue.h> | 32 | #include <linux/workqueue.h> |
32 | #include <linux/completion.h> | 33 | #include <linux/completion.h> |
@@ -880,3 +881,5 @@ static void nci_cmd_work(struct work_struct *work) | |||
880 | jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); | 881 | jiffies + msecs_to_jiffies(NCI_CMD_TIMEOUT)); |
881 | } | 882 | } |
882 | } | 883 | } |
884 | |||
885 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig index 4d2b1ec6516f..fe4adb12b3ef 100644 --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig | |||
@@ -74,6 +74,27 @@ config CFG80211_REG_DEBUG | |||
74 | 74 | ||
75 | If unsure, say N. | 75 | If unsure, say N. |
76 | 76 | ||
77 | config CFG80211_CERTIFICATION_ONUS | ||
78 | bool "cfg80211 certification onus" | ||
79 | depends on CFG80211 && EXPERT | ||
80 | default n | ||
81 | ---help--- | ||
82 | You should disable this option unless you are both capable | ||
83 | and willing to ensure your system will remain regulatory | ||
84 | compliant with the features available under this option. | ||
85 | Some options may still be under heavy development and | ||
86 | for whatever reason regulatory compliance has not or | ||
87 | cannot yet be verified. Regulatory verification may at | ||
88 | times only be possible until you have the final system | ||
89 | in place. | ||
90 | |||
91 | This option should only be enabled by system integrators | ||
92 | or distributions that have done work necessary to ensure | ||
93 | regulatory certification on the system with the enabled | ||
94 | features. Alternatively you can enable this option if | ||
95 | you are a wireless researcher and are working in a controlled | ||
96 | and approved environment by your local regulatory agency. | ||
97 | |||
77 | config CFG80211_DEFAULT_PS | 98 | config CFG80211_DEFAULT_PS |
78 | bool "enable powersave by default" | 99 | bool "enable powersave by default" |
79 | depends on CFG80211 | 100 | depends on CFG80211 |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 434c56b92c3c..d355f67d0cdd 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -82,7 +82,6 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, | |||
82 | int freq, enum nl80211_channel_type chantype) | 82 | int freq, enum nl80211_channel_type chantype) |
83 | { | 83 | { |
84 | struct ieee80211_channel *chan; | 84 | struct ieee80211_channel *chan; |
85 | int err; | ||
86 | 85 | ||
87 | if (!rdev->ops->set_monitor_channel) | 86 | if (!rdev->ops->set_monitor_channel) |
88 | return -EOPNOTSUPP; | 87 | return -EOPNOTSUPP; |
@@ -93,25 +92,17 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev, | |||
93 | if (!chan) | 92 | if (!chan) |
94 | return -EINVAL; | 93 | return -EINVAL; |
95 | 94 | ||
96 | err = rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); | 95 | return rdev->ops->set_monitor_channel(&rdev->wiphy, chan, chantype); |
97 | if (!err) { | ||
98 | rdev->monitor_channel = chan; | ||
99 | rdev->monitor_channel_type = chantype; | ||
100 | } | ||
101 | |||
102 | return err; | ||
103 | } | 96 | } |
104 | 97 | ||
105 | void | 98 | void |
106 | cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, | 99 | cfg80211_get_chan_state(struct wireless_dev *wdev, |
107 | struct wireless_dev *wdev, | ||
108 | struct ieee80211_channel **chan, | 100 | struct ieee80211_channel **chan, |
109 | enum cfg80211_chan_mode *chanmode) | 101 | enum cfg80211_chan_mode *chanmode) |
110 | { | 102 | { |
111 | *chan = NULL; | 103 | *chan = NULL; |
112 | *chanmode = CHAN_MODE_UNDEFINED; | 104 | *chanmode = CHAN_MODE_UNDEFINED; |
113 | 105 | ||
114 | ASSERT_RDEV_LOCK(rdev); | ||
115 | ASSERT_WDEV_LOCK(wdev); | 106 | ASSERT_WDEV_LOCK(wdev); |
116 | 107 | ||
117 | if (!netif_running(wdev->netdev)) | 108 | if (!netif_running(wdev->netdev)) |
@@ -136,9 +127,16 @@ cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, | |||
136 | break; | 127 | break; |
137 | case NL80211_IFTYPE_AP: | 128 | case NL80211_IFTYPE_AP: |
138 | case NL80211_IFTYPE_P2P_GO: | 129 | case NL80211_IFTYPE_P2P_GO: |
130 | if (wdev->beacon_interval) { | ||
131 | *chan = wdev->channel; | ||
132 | *chanmode = CHAN_MODE_SHARED; | ||
133 | } | ||
134 | return; | ||
139 | case NL80211_IFTYPE_MESH_POINT: | 135 | case NL80211_IFTYPE_MESH_POINT: |
140 | *chan = wdev->channel; | 136 | if (wdev->mesh_id_len) { |
141 | *chanmode = CHAN_MODE_SHARED; | 137 | *chan = wdev->channel; |
138 | *chanmode = CHAN_MODE_SHARED; | ||
139 | } | ||
142 | return; | 140 | return; |
143 | case NL80211_IFTYPE_MONITOR: | 141 | case NL80211_IFTYPE_MONITOR: |
144 | case NL80211_IFTYPE_AP_VLAN: | 142 | case NL80211_IFTYPE_AP_VLAN: |
diff --git a/net/wireless/core.c b/net/wireless/core.c index eb60410ae588..31b40cc4a9c3 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -176,7 +176,9 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, | |||
176 | if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) | 176 | if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK)) |
177 | return -EOPNOTSUPP; | 177 | return -EOPNOTSUPP; |
178 | 178 | ||
179 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 179 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
180 | if (!wdev->netdev) | ||
181 | continue; | ||
180 | wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; | 182 | wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; |
181 | err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); | 183 | err = dev_change_net_namespace(wdev->netdev, net, "wlan%d"); |
182 | if (err) | 184 | if (err) |
@@ -188,8 +190,10 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, | |||
188 | /* failed -- clean up to old netns */ | 190 | /* failed -- clean up to old netns */ |
189 | net = wiphy_net(&rdev->wiphy); | 191 | net = wiphy_net(&rdev->wiphy); |
190 | 192 | ||
191 | list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list, | 193 | list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list, |
192 | list) { | 194 | list) { |
195 | if (!wdev->netdev) | ||
196 | continue; | ||
193 | wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; | 197 | wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL; |
194 | err = dev_change_net_namespace(wdev->netdev, net, | 198 | err = dev_change_net_namespace(wdev->netdev, net, |
195 | "wlan%d"); | 199 | "wlan%d"); |
@@ -226,8 +230,9 @@ static int cfg80211_rfkill_set_block(void *data, bool blocked) | |||
226 | rtnl_lock(); | 230 | rtnl_lock(); |
227 | mutex_lock(&rdev->devlist_mtx); | 231 | mutex_lock(&rdev->devlist_mtx); |
228 | 232 | ||
229 | list_for_each_entry(wdev, &rdev->netdev_list, list) | 233 | list_for_each_entry(wdev, &rdev->wdev_list, list) |
230 | dev_close(wdev->netdev); | 234 | if (wdev->netdev) |
235 | dev_close(wdev->netdev); | ||
231 | 236 | ||
232 | mutex_unlock(&rdev->devlist_mtx); | 237 | mutex_unlock(&rdev->devlist_mtx); |
233 | rtnl_unlock(); | 238 | rtnl_unlock(); |
@@ -304,7 +309,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
304 | mutex_init(&rdev->mtx); | 309 | mutex_init(&rdev->mtx); |
305 | mutex_init(&rdev->devlist_mtx); | 310 | mutex_init(&rdev->devlist_mtx); |
306 | mutex_init(&rdev->sched_scan_mtx); | 311 | mutex_init(&rdev->sched_scan_mtx); |
307 | INIT_LIST_HEAD(&rdev->netdev_list); | 312 | INIT_LIST_HEAD(&rdev->wdev_list); |
308 | spin_lock_init(&rdev->bss_lock); | 313 | spin_lock_init(&rdev->bss_lock); |
309 | INIT_LIST_HEAD(&rdev->bss_list); | 314 | INIT_LIST_HEAD(&rdev->bss_list); |
310 | INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); | 315 | INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done); |
@@ -537,7 +542,7 @@ int wiphy_register(struct wiphy *wiphy) | |||
537 | } | 542 | } |
538 | 543 | ||
539 | /* set up regulatory info */ | 544 | /* set up regulatory info */ |
540 | regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE); | 545 | wiphy_regulatory_register(wiphy); |
541 | 546 | ||
542 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); | 547 | list_add_rcu(&rdev->list, &cfg80211_rdev_list); |
543 | cfg80211_rdev_list_generation++; | 548 | cfg80211_rdev_list_generation++; |
@@ -622,7 +627,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
622 | __count == 0; })); | 627 | __count == 0; })); |
623 | 628 | ||
624 | mutex_lock(&rdev->devlist_mtx); | 629 | mutex_lock(&rdev->devlist_mtx); |
625 | BUG_ON(!list_empty(&rdev->netdev_list)); | 630 | BUG_ON(!list_empty(&rdev->wdev_list)); |
626 | mutex_unlock(&rdev->devlist_mtx); | 631 | mutex_unlock(&rdev->devlist_mtx); |
627 | 632 | ||
628 | /* | 633 | /* |
@@ -647,9 +652,11 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
647 | /* nothing */ | 652 | /* nothing */ |
648 | cfg80211_unlock_rdev(rdev); | 653 | cfg80211_unlock_rdev(rdev); |
649 | 654 | ||
650 | /* If this device got a regulatory hint tell core its | 655 | /* |
651 | * free to listen now to a new shiny device regulatory hint */ | 656 | * If this device got a regulatory hint tell core its |
652 | reg_device_remove(wiphy); | 657 | * free to listen now to a new shiny device regulatory hint |
658 | */ | ||
659 | wiphy_regulatory_deregister(wiphy); | ||
653 | 660 | ||
654 | cfg80211_rdev_list_generation++; | 661 | cfg80211_rdev_list_generation++; |
655 | device_del(&rdev->wiphy.dev); | 662 | device_del(&rdev->wiphy.dev); |
@@ -703,7 +710,7 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
703 | 710 | ||
704 | cfg80211_lock_rdev(rdev); | 711 | cfg80211_lock_rdev(rdev); |
705 | 712 | ||
706 | if (WARN_ON(rdev->scan_req && rdev->scan_req->dev == wdev->netdev)) { | 713 | if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { |
707 | rdev->scan_req->aborted = true; | 714 | rdev->scan_req->aborted = true; |
708 | ___cfg80211_scan_done(rdev, true); | 715 | ___cfg80211_scan_done(rdev, true); |
709 | } | 716 | } |
@@ -731,59 +738,14 @@ static struct device_type wiphy_type = { | |||
731 | .name = "wlan", | 738 | .name = "wlan", |
732 | }; | 739 | }; |
733 | 740 | ||
734 | static struct ieee80211_channel * | ||
735 | cfg80211_get_any_chan(struct cfg80211_registered_device *rdev) | ||
736 | { | ||
737 | struct ieee80211_supported_band *sband; | ||
738 | int i; | ||
739 | |||
740 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | ||
741 | sband = rdev->wiphy.bands[i]; | ||
742 | if (sband && sband->n_channels > 0) | ||
743 | return &sband->channels[0]; | ||
744 | } | ||
745 | |||
746 | return NULL; | ||
747 | } | ||
748 | |||
749 | static void cfg80211_init_mon_chan(struct cfg80211_registered_device *rdev) | ||
750 | { | ||
751 | struct ieee80211_channel *chan; | ||
752 | |||
753 | chan = cfg80211_get_any_chan(rdev); | ||
754 | if (WARN_ON(!chan)) | ||
755 | return; | ||
756 | |||
757 | mutex_lock(&rdev->devlist_mtx); | ||
758 | WARN_ON(cfg80211_set_monitor_channel(rdev, chan->center_freq, | ||
759 | NL80211_CHAN_NO_HT)); | ||
760 | mutex_unlock(&rdev->devlist_mtx); | ||
761 | } | ||
762 | |||
763 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, | 741 | void cfg80211_update_iface_num(struct cfg80211_registered_device *rdev, |
764 | enum nl80211_iftype iftype, int num) | 742 | enum nl80211_iftype iftype, int num) |
765 | { | 743 | { |
766 | bool has_monitors_only_old = cfg80211_has_monitors_only(rdev); | ||
767 | bool has_monitors_only_new; | ||
768 | |||
769 | ASSERT_RTNL(); | 744 | ASSERT_RTNL(); |
770 | 745 | ||
771 | rdev->num_running_ifaces += num; | 746 | rdev->num_running_ifaces += num; |
772 | if (iftype == NL80211_IFTYPE_MONITOR) | 747 | if (iftype == NL80211_IFTYPE_MONITOR) |
773 | rdev->num_running_monitor_ifaces += num; | 748 | rdev->num_running_monitor_ifaces += num; |
774 | |||
775 | has_monitors_only_new = cfg80211_has_monitors_only(rdev); | ||
776 | if (has_monitors_only_new != has_monitors_only_old) { | ||
777 | rdev->ops->set_monitor_enabled(&rdev->wiphy, | ||
778 | has_monitors_only_new); | ||
779 | |||
780 | if (!has_monitors_only_new) { | ||
781 | rdev->monitor_channel = NULL; | ||
782 | rdev->monitor_channel_type = NL80211_CHAN_NO_HT; | ||
783 | } else { | ||
784 | cfg80211_init_mon_chan(rdev); | ||
785 | } | ||
786 | } | ||
787 | } | 749 | } |
788 | 750 | ||
789 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | 751 | static int cfg80211_netdev_notifier_call(struct notifier_block *nb, |
@@ -820,7 +782,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
820 | spin_lock_init(&wdev->mgmt_registrations_lock); | 782 | spin_lock_init(&wdev->mgmt_registrations_lock); |
821 | 783 | ||
822 | mutex_lock(&rdev->devlist_mtx); | 784 | mutex_lock(&rdev->devlist_mtx); |
823 | list_add_rcu(&wdev->list, &rdev->netdev_list); | 785 | wdev->identifier = ++rdev->wdev_id; |
786 | list_add_rcu(&wdev->list, &rdev->wdev_list); | ||
824 | rdev->devlist_generation++; | 787 | rdev->devlist_generation++; |
825 | /* can only change netns with wiphy */ | 788 | /* can only change netns with wiphy */ |
826 | dev->features |= NETIF_F_NETNS_LOCAL; | 789 | dev->features |= NETIF_F_NETNS_LOCAL; |
@@ -905,6 +868,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
905 | mutex_unlock(&rdev->devlist_mtx); | 868 | mutex_unlock(&rdev->devlist_mtx); |
906 | dev_put(dev); | 869 | dev_put(dev); |
907 | } | 870 | } |
871 | cfg80211_update_iface_num(rdev, wdev->iftype, 1); | ||
908 | cfg80211_lock_rdev(rdev); | 872 | cfg80211_lock_rdev(rdev); |
909 | mutex_lock(&rdev->devlist_mtx); | 873 | mutex_lock(&rdev->devlist_mtx); |
910 | wdev_lock(wdev); | 874 | wdev_lock(wdev); |
@@ -999,7 +963,6 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
999 | mutex_unlock(&rdev->devlist_mtx); | 963 | mutex_unlock(&rdev->devlist_mtx); |
1000 | if (ret) | 964 | if (ret) |
1001 | return notifier_from_errno(ret); | 965 | return notifier_from_errno(ret); |
1002 | cfg80211_update_iface_num(rdev, wdev->iftype, 1); | ||
1003 | break; | 966 | break; |
1004 | } | 967 | } |
1005 | 968 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index 377dc394f48c..5206c6844fd7 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -47,11 +47,11 @@ struct cfg80211_registered_device { | |||
47 | /* wiphy index, internal only */ | 47 | /* wiphy index, internal only */ |
48 | int wiphy_idx; | 48 | int wiphy_idx; |
49 | 49 | ||
50 | /* associate netdev list */ | 50 | /* associated wireless interfaces */ |
51 | struct mutex devlist_mtx; | 51 | struct mutex devlist_mtx; |
52 | /* protected by devlist_mtx or RCU */ | 52 | /* protected by devlist_mtx or RCU */ |
53 | struct list_head netdev_list; | 53 | struct list_head wdev_list; |
54 | int devlist_generation; | 54 | int devlist_generation, wdev_id; |
55 | int opencount; /* also protected by devlist_mtx */ | 55 | int opencount; /* also protected by devlist_mtx */ |
56 | wait_queue_head_t dev_wait; | 56 | wait_queue_head_t dev_wait; |
57 | 57 | ||
@@ -61,9 +61,6 @@ struct cfg80211_registered_device { | |||
61 | int num_running_ifaces; | 61 | int num_running_ifaces; |
62 | int num_running_monitor_ifaces; | 62 | int num_running_monitor_ifaces; |
63 | 63 | ||
64 | struct ieee80211_channel *monitor_channel; | ||
65 | enum nl80211_channel_type monitor_channel_type; | ||
66 | |||
67 | /* BSSes/scanning */ | 64 | /* BSSes/scanning */ |
68 | spinlock_t bss_lock; | 65 | spinlock_t bss_lock; |
69 | struct list_head bss_list; | 66 | struct list_head bss_list; |
@@ -372,7 +369,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
372 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); | 369 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid); |
373 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); | 370 | void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev); |
374 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | 371 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, |
375 | struct net_device *dev, | 372 | struct wireless_dev *wdev, |
376 | struct ieee80211_channel *chan, bool offchan, | 373 | struct ieee80211_channel *chan, bool offchan, |
377 | enum nl80211_channel_type channel_type, | 374 | enum nl80211_channel_type channel_type, |
378 | bool channel_type_valid, unsigned int wait, | 375 | bool channel_type_valid, unsigned int wait, |
@@ -463,8 +460,7 @@ cfg80211_can_use_chan(struct cfg80211_registered_device *rdev, | |||
463 | } | 460 | } |
464 | 461 | ||
465 | void | 462 | void |
466 | cfg80211_get_chan_state(struct cfg80211_registered_device *rdev, | 463 | cfg80211_get_chan_state(struct wireless_dev *wdev, |
467 | struct wireless_dev *wdev, | ||
468 | struct ieee80211_channel **chan, | 464 | struct ieee80211_channel **chan, |
469 | enum cfg80211_chan_mode *chanmode); | 465 | enum cfg80211_chan_mode *chanmode); |
470 | 466 | ||
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index d4fece3bb18a..1cdb1d5e6b0f 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -567,29 +567,28 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev, | |||
567 | } | 567 | } |
568 | } | 568 | } |
569 | 569 | ||
570 | void cfg80211_ready_on_channel(struct net_device *dev, u64 cookie, | 570 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, |
571 | struct ieee80211_channel *chan, | 571 | struct ieee80211_channel *chan, |
572 | enum nl80211_channel_type channel_type, | 572 | enum nl80211_channel_type channel_type, |
573 | unsigned int duration, gfp_t gfp) | 573 | unsigned int duration, gfp_t gfp) |
574 | { | 574 | { |
575 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 575 | struct wiphy *wiphy = wdev->wiphy; |
576 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 576 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
577 | 577 | ||
578 | nl80211_send_remain_on_channel(rdev, dev, cookie, chan, channel_type, | 578 | nl80211_send_remain_on_channel(rdev, wdev, cookie, chan, channel_type, |
579 | duration, gfp); | 579 | duration, gfp); |
580 | } | 580 | } |
581 | EXPORT_SYMBOL(cfg80211_ready_on_channel); | 581 | EXPORT_SYMBOL(cfg80211_ready_on_channel); |
582 | 582 | ||
583 | void cfg80211_remain_on_channel_expired(struct net_device *dev, | 583 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, |
584 | u64 cookie, | ||
585 | struct ieee80211_channel *chan, | 584 | struct ieee80211_channel *chan, |
586 | enum nl80211_channel_type channel_type, | 585 | enum nl80211_channel_type channel_type, |
587 | gfp_t gfp) | 586 | gfp_t gfp) |
588 | { | 587 | { |
589 | struct wiphy *wiphy = dev->ieee80211_ptr->wiphy; | 588 | struct wiphy *wiphy = wdev->wiphy; |
590 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 589 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
591 | 590 | ||
592 | nl80211_send_remain_on_channel_cancel(rdev, dev, cookie, chan, | 591 | nl80211_send_remain_on_channel_cancel(rdev, wdev, cookie, chan, |
593 | channel_type, gfp); | 592 | channel_type, gfp); |
594 | } | 593 | } |
595 | EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); | 594 | EXPORT_SYMBOL(cfg80211_remain_on_channel_expired); |
@@ -678,8 +677,7 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid, | |||
678 | list_add(&nreg->list, &wdev->mgmt_registrations); | 677 | list_add(&nreg->list, &wdev->mgmt_registrations); |
679 | 678 | ||
680 | if (rdev->ops->mgmt_frame_register) | 679 | if (rdev->ops->mgmt_frame_register) |
681 | rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, | 680 | rdev->ops->mgmt_frame_register(wiphy, wdev, frame_type, true); |
682 | frame_type, true); | ||
683 | 681 | ||
684 | out: | 682 | out: |
685 | spin_unlock_bh(&wdev->mgmt_registrations_lock); | 683 | spin_unlock_bh(&wdev->mgmt_registrations_lock); |
@@ -702,7 +700,7 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | |||
702 | if (rdev->ops->mgmt_frame_register) { | 700 | if (rdev->ops->mgmt_frame_register) { |
703 | u16 frame_type = le16_to_cpu(reg->frame_type); | 701 | u16 frame_type = le16_to_cpu(reg->frame_type); |
704 | 702 | ||
705 | rdev->ops->mgmt_frame_register(wiphy, wdev->netdev, | 703 | rdev->ops->mgmt_frame_register(wiphy, wdev, |
706 | frame_type, false); | 704 | frame_type, false); |
707 | } | 705 | } |
708 | 706 | ||
@@ -731,14 +729,14 @@ void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev) | |||
731 | } | 729 | } |
732 | 730 | ||
733 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | 731 | int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, |
734 | struct net_device *dev, | 732 | struct wireless_dev *wdev, |
735 | struct ieee80211_channel *chan, bool offchan, | 733 | struct ieee80211_channel *chan, bool offchan, |
736 | enum nl80211_channel_type channel_type, | 734 | enum nl80211_channel_type channel_type, |
737 | bool channel_type_valid, unsigned int wait, | 735 | bool channel_type_valid, unsigned int wait, |
738 | const u8 *buf, size_t len, bool no_cck, | 736 | const u8 *buf, size_t len, bool no_cck, |
739 | bool dont_wait_for_ack, u64 *cookie) | 737 | bool dont_wait_for_ack, u64 *cookie) |
740 | { | 738 | { |
741 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 739 | struct net_device *dev = wdev->netdev; |
742 | const struct ieee80211_mgmt *mgmt; | 740 | const struct ieee80211_mgmt *mgmt; |
743 | u16 stype; | 741 | u16 stype; |
744 | 742 | ||
@@ -825,16 +823,15 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, | |||
825 | return -EINVAL; | 823 | return -EINVAL; |
826 | 824 | ||
827 | /* Transmit the Action frame as requested by user space */ | 825 | /* Transmit the Action frame as requested by user space */ |
828 | return rdev->ops->mgmt_tx(&rdev->wiphy, dev, chan, offchan, | 826 | return rdev->ops->mgmt_tx(&rdev->wiphy, wdev, chan, offchan, |
829 | channel_type, channel_type_valid, | 827 | channel_type, channel_type_valid, |
830 | wait, buf, len, no_cck, dont_wait_for_ack, | 828 | wait, buf, len, no_cck, dont_wait_for_ack, |
831 | cookie); | 829 | cookie); |
832 | } | 830 | } |
833 | 831 | ||
834 | bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm, | 832 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, |
835 | const u8 *buf, size_t len, gfp_t gfp) | 833 | const u8 *buf, size_t len, gfp_t gfp) |
836 | { | 834 | { |
837 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
838 | struct wiphy *wiphy = wdev->wiphy; | 835 | struct wiphy *wiphy = wdev->wiphy; |
839 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 836 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
840 | struct cfg80211_mgmt_registration *reg; | 837 | struct cfg80211_mgmt_registration *reg; |
@@ -871,7 +868,7 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm, | |||
871 | /* found match! */ | 868 | /* found match! */ |
872 | 869 | ||
873 | /* Indicate the received Action frame to user space */ | 870 | /* Indicate the received Action frame to user space */ |
874 | if (nl80211_send_mgmt(rdev, dev, reg->nlpid, | 871 | if (nl80211_send_mgmt(rdev, wdev, reg->nlpid, |
875 | freq, sig_mbm, | 872 | freq, sig_mbm, |
876 | buf, len, gfp)) | 873 | buf, len, gfp)) |
877 | continue; | 874 | continue; |
@@ -886,15 +883,14 @@ bool cfg80211_rx_mgmt(struct net_device *dev, int freq, int sig_mbm, | |||
886 | } | 883 | } |
887 | EXPORT_SYMBOL(cfg80211_rx_mgmt); | 884 | EXPORT_SYMBOL(cfg80211_rx_mgmt); |
888 | 885 | ||
889 | void cfg80211_mgmt_tx_status(struct net_device *dev, u64 cookie, | 886 | void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, |
890 | const u8 *buf, size_t len, bool ack, gfp_t gfp) | 887 | const u8 *buf, size_t len, bool ack, gfp_t gfp) |
891 | { | 888 | { |
892 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
893 | struct wiphy *wiphy = wdev->wiphy; | 889 | struct wiphy *wiphy = wdev->wiphy; |
894 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 890 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
895 | 891 | ||
896 | /* Indicate TX status of the Action frame to user space */ | 892 | /* Indicate TX status of the Action frame to user space */ |
897 | nl80211_send_mgmt_tx_status(rdev, dev, cookie, buf, len, ack, gfp); | 893 | nl80211_send_mgmt_tx_status(rdev, wdev, cookie, buf, len, ack, gfp); |
898 | } | 894 | } |
899 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); | 895 | EXPORT_SYMBOL(cfg80211_mgmt_tx_status); |
900 | 896 | ||
@@ -923,6 +919,19 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev, | |||
923 | } | 919 | } |
924 | EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); | 920 | EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify); |
925 | 921 | ||
922 | void cfg80211_cqm_txe_notify(struct net_device *dev, | ||
923 | const u8 *peer, u32 num_packets, | ||
924 | u32 rate, u32 intvl, gfp_t gfp) | ||
925 | { | ||
926 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
927 | struct wiphy *wiphy = wdev->wiphy; | ||
928 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | ||
929 | |||
930 | nl80211_send_cqm_txe_notify(rdev, dev, peer, num_packets, | ||
931 | rate, intvl, gfp); | ||
932 | } | ||
933 | EXPORT_SYMBOL(cfg80211_cqm_txe_notify); | ||
934 | |||
926 | void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | 935 | void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, |
927 | const u8 *replay_ctr, gfp_t gfp) | 936 | const u8 *replay_ctr, gfp_t gfp) |
928 | { | 937 | { |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 0249cea53852..97026f3b215a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -46,28 +46,60 @@ static struct genl_family nl80211_fam = { | |||
46 | .post_doit = nl80211_post_doit, | 46 | .post_doit = nl80211_post_doit, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* internal helper: get rdev and dev */ | 49 | /* returns ERR_PTR values */ |
50 | static int get_rdev_dev_by_ifindex(struct net *netns, struct nlattr **attrs, | 50 | static struct wireless_dev * |
51 | struct cfg80211_registered_device **rdev, | 51 | __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) |
52 | struct net_device **dev) | ||
53 | { | 52 | { |
54 | int ifindex; | 53 | struct cfg80211_registered_device *rdev; |
54 | struct wireless_dev *result = NULL; | ||
55 | bool have_ifidx = attrs[NL80211_ATTR_IFINDEX]; | ||
56 | bool have_wdev_id = attrs[NL80211_ATTR_WDEV]; | ||
57 | u64 wdev_id; | ||
58 | int wiphy_idx = -1; | ||
59 | int ifidx = -1; | ||
55 | 60 | ||
56 | if (!attrs[NL80211_ATTR_IFINDEX]) | 61 | assert_cfg80211_lock(); |
57 | return -EINVAL; | ||
58 | 62 | ||
59 | ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); | 63 | if (!have_ifidx && !have_wdev_id) |
60 | *dev = dev_get_by_index(netns, ifindex); | 64 | return ERR_PTR(-EINVAL); |
61 | if (!*dev) | ||
62 | return -ENODEV; | ||
63 | 65 | ||
64 | *rdev = cfg80211_get_dev_from_ifindex(netns, ifindex); | 66 | if (have_ifidx) |
65 | if (IS_ERR(*rdev)) { | 67 | ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
66 | dev_put(*dev); | 68 | if (have_wdev_id) { |
67 | return PTR_ERR(*rdev); | 69 | wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); |
70 | wiphy_idx = wdev_id >> 32; | ||
68 | } | 71 | } |
69 | 72 | ||
70 | return 0; | 73 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
74 | struct wireless_dev *wdev; | ||
75 | |||
76 | if (wiphy_net(&rdev->wiphy) != netns) | ||
77 | continue; | ||
78 | |||
79 | if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) | ||
80 | continue; | ||
81 | |||
82 | mutex_lock(&rdev->devlist_mtx); | ||
83 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | ||
84 | if (have_ifidx && wdev->netdev && | ||
85 | wdev->netdev->ifindex == ifidx) { | ||
86 | result = wdev; | ||
87 | break; | ||
88 | } | ||
89 | if (have_wdev_id && wdev->identifier == (u32)wdev_id) { | ||
90 | result = wdev; | ||
91 | break; | ||
92 | } | ||
93 | } | ||
94 | mutex_unlock(&rdev->devlist_mtx); | ||
95 | |||
96 | if (result) | ||
97 | break; | ||
98 | } | ||
99 | |||
100 | if (result) | ||
101 | return result; | ||
102 | return ERR_PTR(-ENODEV); | ||
71 | } | 103 | } |
72 | 104 | ||
73 | static struct cfg80211_registered_device * | 105 | static struct cfg80211_registered_device * |
@@ -79,13 +111,40 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) | |||
79 | assert_cfg80211_lock(); | 111 | assert_cfg80211_lock(); |
80 | 112 | ||
81 | if (!attrs[NL80211_ATTR_WIPHY] && | 113 | if (!attrs[NL80211_ATTR_WIPHY] && |
82 | !attrs[NL80211_ATTR_IFINDEX]) | 114 | !attrs[NL80211_ATTR_IFINDEX] && |
115 | !attrs[NL80211_ATTR_WDEV]) | ||
83 | return ERR_PTR(-EINVAL); | 116 | return ERR_PTR(-EINVAL); |
84 | 117 | ||
85 | if (attrs[NL80211_ATTR_WIPHY]) | 118 | if (attrs[NL80211_ATTR_WIPHY]) |
86 | rdev = cfg80211_rdev_by_wiphy_idx( | 119 | rdev = cfg80211_rdev_by_wiphy_idx( |
87 | nla_get_u32(attrs[NL80211_ATTR_WIPHY])); | 120 | nla_get_u32(attrs[NL80211_ATTR_WIPHY])); |
88 | 121 | ||
122 | if (attrs[NL80211_ATTR_WDEV]) { | ||
123 | u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); | ||
124 | struct wireless_dev *wdev; | ||
125 | bool found = false; | ||
126 | |||
127 | tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); | ||
128 | if (tmp) { | ||
129 | /* make sure wdev exists */ | ||
130 | mutex_lock(&tmp->devlist_mtx); | ||
131 | list_for_each_entry(wdev, &tmp->wdev_list, list) { | ||
132 | if (wdev->identifier != (u32)wdev_id) | ||
133 | continue; | ||
134 | found = true; | ||
135 | break; | ||
136 | } | ||
137 | mutex_unlock(&tmp->devlist_mtx); | ||
138 | |||
139 | if (!found) | ||
140 | tmp = NULL; | ||
141 | |||
142 | if (rdev && tmp != rdev) | ||
143 | return ERR_PTR(-EINVAL); | ||
144 | rdev = tmp; | ||
145 | } | ||
146 | } | ||
147 | |||
89 | if (attrs[NL80211_ATTR_IFINDEX]) { | 148 | if (attrs[NL80211_ATTR_IFINDEX]) { |
90 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); | 149 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
91 | netdev = dev_get_by_index(netns, ifindex); | 150 | netdev = dev_get_by_index(netns, ifindex); |
@@ -294,6 +353,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
294 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, | 353 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, |
295 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, | 354 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, |
296 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | 355 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, |
356 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, | ||
357 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, | ||
297 | }; | 358 | }; |
298 | 359 | ||
299 | /* policy for the key attributes */ | 360 | /* policy for the key attributes */ |
@@ -1668,32 +1729,48 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1668 | return result; | 1729 | return result; |
1669 | } | 1730 | } |
1670 | 1731 | ||
1732 | static inline u64 wdev_id(struct wireless_dev *wdev) | ||
1733 | { | ||
1734 | return (u64)wdev->identifier | | ||
1735 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); | ||
1736 | } | ||
1671 | 1737 | ||
1672 | static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 1738 | static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags, |
1673 | struct cfg80211_registered_device *rdev, | 1739 | struct cfg80211_registered_device *rdev, |
1674 | struct net_device *dev) | 1740 | struct wireless_dev *wdev) |
1675 | { | 1741 | { |
1742 | struct net_device *dev = wdev->netdev; | ||
1676 | void *hdr; | 1743 | void *hdr; |
1677 | 1744 | ||
1678 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); | 1745 | hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_INTERFACE); |
1679 | if (!hdr) | 1746 | if (!hdr) |
1680 | return -1; | 1747 | return -1; |
1681 | 1748 | ||
1682 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 1749 | if (dev && |
1683 | nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 1750 | (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
1684 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || | 1751 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name) || |
1685 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, | 1752 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dev->dev_addr))) |
1686 | dev->ieee80211_ptr->iftype) || | 1753 | goto nla_put_failure; |
1754 | |||
1755 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | ||
1756 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || | ||
1757 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || | ||
1687 | nla_put_u32(msg, NL80211_ATTR_GENERATION, | 1758 | nla_put_u32(msg, NL80211_ATTR_GENERATION, |
1688 | rdev->devlist_generation ^ | 1759 | rdev->devlist_generation ^ |
1689 | (cfg80211_rdev_list_generation << 2))) | 1760 | (cfg80211_rdev_list_generation << 2))) |
1690 | goto nla_put_failure; | 1761 | goto nla_put_failure; |
1691 | 1762 | ||
1692 | if (rdev->monitor_channel) { | 1763 | if (rdev->ops->get_channel) { |
1693 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, | 1764 | struct ieee80211_channel *chan; |
1694 | rdev->monitor_channel->center_freq) || | 1765 | enum nl80211_channel_type channel_type; |
1695 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, | 1766 | |
1696 | rdev->monitor_channel_type)) | 1767 | chan = rdev->ops->get_channel(&rdev->wiphy, wdev, |
1768 | &channel_type); | ||
1769 | if (chan && | ||
1770 | (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, | ||
1771 | chan->center_freq) || | ||
1772 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, | ||
1773 | channel_type))) | ||
1697 | goto nla_put_failure; | 1774 | goto nla_put_failure; |
1698 | } | 1775 | } |
1699 | 1776 | ||
@@ -1724,14 +1801,14 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * | |||
1724 | if_idx = 0; | 1801 | if_idx = 0; |
1725 | 1802 | ||
1726 | mutex_lock(&rdev->devlist_mtx); | 1803 | mutex_lock(&rdev->devlist_mtx); |
1727 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 1804 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
1728 | if (if_idx < if_start) { | 1805 | if (if_idx < if_start) { |
1729 | if_idx++; | 1806 | if_idx++; |
1730 | continue; | 1807 | continue; |
1731 | } | 1808 | } |
1732 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, | 1809 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid, |
1733 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1810 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1734 | rdev, wdev->netdev) < 0) { | 1811 | rdev, wdev) < 0) { |
1735 | mutex_unlock(&rdev->devlist_mtx); | 1812 | mutex_unlock(&rdev->devlist_mtx); |
1736 | goto out; | 1813 | goto out; |
1737 | } | 1814 | } |
@@ -1754,14 +1831,14 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | |||
1754 | { | 1831 | { |
1755 | struct sk_buff *msg; | 1832 | struct sk_buff *msg; |
1756 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1833 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1757 | struct net_device *netdev = info->user_ptr[1]; | 1834 | struct wireless_dev *wdev = info->user_ptr[1]; |
1758 | 1835 | ||
1759 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1836 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
1760 | if (!msg) | 1837 | if (!msg) |
1761 | return -ENOMEM; | 1838 | return -ENOMEM; |
1762 | 1839 | ||
1763 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, | 1840 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, |
1764 | dev, netdev) < 0) { | 1841 | dev, wdev) < 0) { |
1765 | nlmsg_free(msg); | 1842 | nlmsg_free(msg); |
1766 | return -ENOBUFS; | 1843 | return -ENOBUFS; |
1767 | } | 1844 | } |
@@ -1901,7 +1978,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1901 | { | 1978 | { |
1902 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1979 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1903 | struct vif_params params; | 1980 | struct vif_params params; |
1904 | struct net_device *dev; | 1981 | struct wireless_dev *wdev; |
1982 | struct sk_buff *msg; | ||
1905 | int err; | 1983 | int err; |
1906 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 1984 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
1907 | u32 flags; | 1985 | u32 flags; |
@@ -1928,19 +2006,23 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1928 | return err; | 2006 | return err; |
1929 | } | 2007 | } |
1930 | 2008 | ||
2009 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
2010 | if (!msg) | ||
2011 | return -ENOMEM; | ||
2012 | |||
1931 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2013 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
1932 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2014 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
1933 | &flags); | 2015 | &flags); |
1934 | dev = rdev->ops->add_virtual_intf(&rdev->wiphy, | 2016 | wdev = rdev->ops->add_virtual_intf(&rdev->wiphy, |
1935 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2017 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
1936 | type, err ? NULL : &flags, ¶ms); | 2018 | type, err ? NULL : &flags, ¶ms); |
1937 | if (IS_ERR(dev)) | 2019 | if (IS_ERR(wdev)) { |
1938 | return PTR_ERR(dev); | 2020 | nlmsg_free(msg); |
2021 | return PTR_ERR(wdev); | ||
2022 | } | ||
1939 | 2023 | ||
1940 | if (type == NL80211_IFTYPE_MESH_POINT && | 2024 | if (type == NL80211_IFTYPE_MESH_POINT && |
1941 | info->attrs[NL80211_ATTR_MESH_ID]) { | 2025 | info->attrs[NL80211_ATTR_MESH_ID]) { |
1942 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
1943 | |||
1944 | wdev_lock(wdev); | 2026 | wdev_lock(wdev); |
1945 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2027 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
1946 | IEEE80211_MAX_MESH_ID_LEN); | 2028 | IEEE80211_MAX_MESH_ID_LEN); |
@@ -1951,18 +2033,34 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
1951 | wdev_unlock(wdev); | 2033 | wdev_unlock(wdev); |
1952 | } | 2034 | } |
1953 | 2035 | ||
1954 | return 0; | 2036 | if (nl80211_send_iface(msg, info->snd_pid, info->snd_seq, 0, |
2037 | rdev, wdev) < 0) { | ||
2038 | nlmsg_free(msg); | ||
2039 | return -ENOBUFS; | ||
2040 | } | ||
2041 | |||
2042 | return genlmsg_reply(msg, info); | ||
1955 | } | 2043 | } |
1956 | 2044 | ||
1957 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 2045 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |
1958 | { | 2046 | { |
1959 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2047 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1960 | struct net_device *dev = info->user_ptr[1]; | 2048 | struct wireless_dev *wdev = info->user_ptr[1]; |
1961 | 2049 | ||
1962 | if (!rdev->ops->del_virtual_intf) | 2050 | if (!rdev->ops->del_virtual_intf) |
1963 | return -EOPNOTSUPP; | 2051 | return -EOPNOTSUPP; |
1964 | 2052 | ||
1965 | return rdev->ops->del_virtual_intf(&rdev->wiphy, dev); | 2053 | /* |
2054 | * If we remove a wireless device without a netdev then clear | ||
2055 | * user_ptr[1] so that nl80211_post_doit won't dereference it | ||
2056 | * to check if it needs to do dev_put(). Otherwise it crashes | ||
2057 | * since the wdev has been freed, unlike with a netdev where | ||
2058 | * we need the dev_put() for the netdev to really be freed. | ||
2059 | */ | ||
2060 | if (!wdev->netdev) | ||
2061 | info->user_ptr[1] = NULL; | ||
2062 | |||
2063 | return rdev->ops->del_virtual_intf(&rdev->wiphy, wdev); | ||
1966 | } | 2064 | } |
1967 | 2065 | ||
1968 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | 2066 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) |
@@ -2350,7 +2448,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, | |||
2350 | 2448 | ||
2351 | mutex_lock(&rdev->devlist_mtx); | 2449 | mutex_lock(&rdev->devlist_mtx); |
2352 | 2450 | ||
2353 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 2451 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
2354 | if (wdev->iftype != NL80211_IFTYPE_AP && | 2452 | if (wdev->iftype != NL80211_IFTYPE_AP && |
2355 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | 2453 | wdev->iftype != NL80211_IFTYPE_P2P_GO) |
2356 | continue; | 2454 | continue; |
@@ -3485,6 +3583,7 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
3485 | { | 3583 | { |
3486 | int r; | 3584 | int r; |
3487 | char *data = NULL; | 3585 | char *data = NULL; |
3586 | enum nl80211_user_reg_hint_type user_reg_hint_type; | ||
3488 | 3587 | ||
3489 | /* | 3588 | /* |
3490 | * You should only get this when cfg80211 hasn't yet initialized | 3589 | * You should only get this when cfg80211 hasn't yet initialized |
@@ -3504,7 +3603,21 @@ static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | |||
3504 | 3603 | ||
3505 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | 3604 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); |
3506 | 3605 | ||
3507 | r = regulatory_hint_user(data); | 3606 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) |
3607 | user_reg_hint_type = | ||
3608 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); | ||
3609 | else | ||
3610 | user_reg_hint_type = NL80211_USER_REG_HINT_USER; | ||
3611 | |||
3612 | switch (user_reg_hint_type) { | ||
3613 | case NL80211_USER_REG_HINT_USER: | ||
3614 | case NL80211_USER_REG_HINT_CELL_BASE: | ||
3615 | break; | ||
3616 | default: | ||
3617 | return -EINVAL; | ||
3618 | } | ||
3619 | |||
3620 | r = regulatory_hint_user(data, user_reg_hint_type); | ||
3508 | 3621 | ||
3509 | return r; | 3622 | return r; |
3510 | } | 3623 | } |
@@ -3874,6 +3987,11 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | |||
3874 | cfg80211_regdomain->dfs_region))) | 3987 | cfg80211_regdomain->dfs_region))) |
3875 | goto nla_put_failure; | 3988 | goto nla_put_failure; |
3876 | 3989 | ||
3990 | if (reg_last_request_cell_base() && | ||
3991 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | ||
3992 | NL80211_USER_REG_HINT_CELL_BASE)) | ||
3993 | goto nla_put_failure; | ||
3994 | |||
3877 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); | 3995 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); |
3878 | if (!nl_reg_rules) | 3996 | if (!nl_reg_rules) |
3879 | goto nla_put_failure; | 3997 | goto nla_put_failure; |
@@ -4039,7 +4157,7 @@ static int validate_scan_freqs(struct nlattr *freqs) | |||
4039 | static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | 4157 | static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) |
4040 | { | 4158 | { |
4041 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4159 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4042 | struct net_device *dev = info->user_ptr[1]; | 4160 | struct wireless_dev *wdev = info->user_ptr[1]; |
4043 | struct cfg80211_scan_request *request; | 4161 | struct cfg80211_scan_request *request; |
4044 | struct nlattr *attr; | 4162 | struct nlattr *attr; |
4045 | struct wiphy *wiphy; | 4163 | struct wiphy *wiphy; |
@@ -4199,15 +4317,16 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
4199 | request->no_cck = | 4317 | request->no_cck = |
4200 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | 4318 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); |
4201 | 4319 | ||
4202 | request->dev = dev; | 4320 | request->wdev = wdev; |
4203 | request->wiphy = &rdev->wiphy; | 4321 | request->wiphy = &rdev->wiphy; |
4204 | 4322 | ||
4205 | rdev->scan_req = request; | 4323 | rdev->scan_req = request; |
4206 | err = rdev->ops->scan(&rdev->wiphy, dev, request); | 4324 | err = rdev->ops->scan(&rdev->wiphy, request); |
4207 | 4325 | ||
4208 | if (!err) { | 4326 | if (!err) { |
4209 | nl80211_send_scan_start(rdev, dev); | 4327 | nl80211_send_scan_start(rdev, wdev); |
4210 | dev_hold(dev); | 4328 | if (wdev->netdev) |
4329 | dev_hold(wdev->netdev); | ||
4211 | } else { | 4330 | } else { |
4212 | out_free: | 4331 | out_free: |
4213 | rdev->scan_req = NULL; | 4332 | rdev->scan_req = NULL; |
@@ -5685,7 +5804,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, | |||
5685 | struct genl_info *info) | 5804 | struct genl_info *info) |
5686 | { | 5805 | { |
5687 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5806 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5688 | struct net_device *dev = info->user_ptr[1]; | 5807 | struct wireless_dev *wdev = info->user_ptr[1]; |
5689 | struct ieee80211_channel *chan; | 5808 | struct ieee80211_channel *chan; |
5690 | struct sk_buff *msg; | 5809 | struct sk_buff *msg; |
5691 | void *hdr; | 5810 | void *hdr; |
@@ -5733,7 +5852,7 @@ static int nl80211_remain_on_channel(struct sk_buff *skb, | |||
5733 | goto free_msg; | 5852 | goto free_msg; |
5734 | } | 5853 | } |
5735 | 5854 | ||
5736 | err = rdev->ops->remain_on_channel(&rdev->wiphy, dev, chan, | 5855 | err = rdev->ops->remain_on_channel(&rdev->wiphy, wdev, chan, |
5737 | channel_type, duration, &cookie); | 5856 | channel_type, duration, &cookie); |
5738 | 5857 | ||
5739 | if (err) | 5858 | if (err) |
@@ -5757,7 +5876,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, | |||
5757 | struct genl_info *info) | 5876 | struct genl_info *info) |
5758 | { | 5877 | { |
5759 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5878 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5760 | struct net_device *dev = info->user_ptr[1]; | 5879 | struct wireless_dev *wdev = info->user_ptr[1]; |
5761 | u64 cookie; | 5880 | u64 cookie; |
5762 | 5881 | ||
5763 | if (!info->attrs[NL80211_ATTR_COOKIE]) | 5882 | if (!info->attrs[NL80211_ATTR_COOKIE]) |
@@ -5768,7 +5887,7 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, | |||
5768 | 5887 | ||
5769 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 5888 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
5770 | 5889 | ||
5771 | return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, dev, cookie); | 5890 | return rdev->ops->cancel_remain_on_channel(&rdev->wiphy, wdev, cookie); |
5772 | } | 5891 | } |
5773 | 5892 | ||
5774 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, | 5893 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, |
@@ -5917,7 +6036,7 @@ static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, | |||
5917 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | 6036 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) |
5918 | { | 6037 | { |
5919 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6038 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5920 | struct net_device *dev = info->user_ptr[1]; | 6039 | struct wireless_dev *wdev = info->user_ptr[1]; |
5921 | u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; | 6040 | u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; |
5922 | 6041 | ||
5923 | if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) | 6042 | if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) |
@@ -5926,21 +6045,24 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5926 | if (info->attrs[NL80211_ATTR_FRAME_TYPE]) | 6045 | if (info->attrs[NL80211_ATTR_FRAME_TYPE]) |
5927 | frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); | 6046 | frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); |
5928 | 6047 | ||
5929 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 6048 | switch (wdev->iftype) { |
5930 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && | 6049 | case NL80211_IFTYPE_STATION: |
5931 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && | 6050 | case NL80211_IFTYPE_ADHOC: |
5932 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 6051 | case NL80211_IFTYPE_P2P_CLIENT: |
5933 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 6052 | case NL80211_IFTYPE_AP: |
5934 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | 6053 | case NL80211_IFTYPE_AP_VLAN: |
5935 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 6054 | case NL80211_IFTYPE_MESH_POINT: |
6055 | case NL80211_IFTYPE_P2P_GO: | ||
6056 | break; | ||
6057 | default: | ||
5936 | return -EOPNOTSUPP; | 6058 | return -EOPNOTSUPP; |
6059 | } | ||
5937 | 6060 | ||
5938 | /* not much point in registering if we can't reply */ | 6061 | /* not much point in registering if we can't reply */ |
5939 | if (!rdev->ops->mgmt_tx) | 6062 | if (!rdev->ops->mgmt_tx) |
5940 | return -EOPNOTSUPP; | 6063 | return -EOPNOTSUPP; |
5941 | 6064 | ||
5942 | return cfg80211_mlme_register_mgmt(dev->ieee80211_ptr, info->snd_pid, | 6065 | return cfg80211_mlme_register_mgmt(wdev, info->snd_pid, frame_type, |
5943 | frame_type, | ||
5944 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), | 6066 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), |
5945 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); | 6067 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); |
5946 | } | 6068 | } |
@@ -5948,7 +6070,7 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5948 | static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | 6070 | static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) |
5949 | { | 6071 | { |
5950 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6072 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5951 | struct net_device *dev = info->user_ptr[1]; | 6073 | struct wireless_dev *wdev = info->user_ptr[1]; |
5952 | struct ieee80211_channel *chan; | 6074 | struct ieee80211_channel *chan; |
5953 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; | 6075 | enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; |
5954 | bool channel_type_valid = false; | 6076 | bool channel_type_valid = false; |
@@ -5969,14 +6091,18 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
5969 | if (!rdev->ops->mgmt_tx) | 6091 | if (!rdev->ops->mgmt_tx) |
5970 | return -EOPNOTSUPP; | 6092 | return -EOPNOTSUPP; |
5971 | 6093 | ||
5972 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 6094 | switch (wdev->iftype) { |
5973 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && | 6095 | case NL80211_IFTYPE_STATION: |
5974 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && | 6096 | case NL80211_IFTYPE_ADHOC: |
5975 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 6097 | case NL80211_IFTYPE_P2P_CLIENT: |
5976 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 6098 | case NL80211_IFTYPE_AP: |
5977 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | 6099 | case NL80211_IFTYPE_AP_VLAN: |
5978 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 6100 | case NL80211_IFTYPE_MESH_POINT: |
6101 | case NL80211_IFTYPE_P2P_GO: | ||
6102 | break; | ||
6103 | default: | ||
5979 | return -EOPNOTSUPP; | 6104 | return -EOPNOTSUPP; |
6105 | } | ||
5980 | 6106 | ||
5981 | if (info->attrs[NL80211_ATTR_DURATION]) { | 6107 | if (info->attrs[NL80211_ATTR_DURATION]) { |
5982 | if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) | 6108 | if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) |
@@ -6025,7 +6151,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6025 | } | 6151 | } |
6026 | } | 6152 | } |
6027 | 6153 | ||
6028 | err = cfg80211_mlme_mgmt_tx(rdev, dev, chan, offchan, channel_type, | 6154 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, channel_type, |
6029 | channel_type_valid, wait, | 6155 | channel_type_valid, wait, |
6030 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 6156 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
6031 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 6157 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
@@ -6053,7 +6179,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | |||
6053 | static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info) | 6179 | static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info) |
6054 | { | 6180 | { |
6055 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6181 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6056 | struct net_device *dev = info->user_ptr[1]; | 6182 | struct wireless_dev *wdev = info->user_ptr[1]; |
6057 | u64 cookie; | 6183 | u64 cookie; |
6058 | 6184 | ||
6059 | if (!info->attrs[NL80211_ATTR_COOKIE]) | 6185 | if (!info->attrs[NL80211_ATTR_COOKIE]) |
@@ -6062,17 +6188,21 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in | |||
6062 | if (!rdev->ops->mgmt_tx_cancel_wait) | 6188 | if (!rdev->ops->mgmt_tx_cancel_wait) |
6063 | return -EOPNOTSUPP; | 6189 | return -EOPNOTSUPP; |
6064 | 6190 | ||
6065 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 6191 | switch (wdev->iftype) { |
6066 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && | 6192 | case NL80211_IFTYPE_STATION: |
6067 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT && | 6193 | case NL80211_IFTYPE_ADHOC: |
6068 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 6194 | case NL80211_IFTYPE_P2P_CLIENT: |
6069 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 6195 | case NL80211_IFTYPE_AP: |
6070 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 6196 | case NL80211_IFTYPE_AP_VLAN: |
6197 | case NL80211_IFTYPE_P2P_GO: | ||
6198 | break; | ||
6199 | default: | ||
6071 | return -EOPNOTSUPP; | 6200 | return -EOPNOTSUPP; |
6201 | } | ||
6072 | 6202 | ||
6073 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 6203 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
6074 | 6204 | ||
6075 | return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, dev, cookie); | 6205 | return rdev->ops->mgmt_tx_cancel_wait(&rdev->wiphy, wdev, cookie); |
6076 | } | 6206 | } |
6077 | 6207 | ||
6078 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | 6208 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) |
@@ -6158,8 +6288,35 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = { | |||
6158 | [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, | 6288 | [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, |
6159 | [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, | 6289 | [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, |
6160 | [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, | 6290 | [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, |
6291 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, | ||
6292 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, | ||
6293 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, | ||
6161 | }; | 6294 | }; |
6162 | 6295 | ||
6296 | static int nl80211_set_cqm_txe(struct genl_info *info, | ||
6297 | u32 rate, u32 pkts, u32 intvl) | ||
6298 | { | ||
6299 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
6300 | struct wireless_dev *wdev; | ||
6301 | struct net_device *dev = info->user_ptr[1]; | ||
6302 | |||
6303 | if ((rate < 0 || rate > 100) || | ||
6304 | (intvl < 0 || intvl > NL80211_CQM_TXE_MAX_INTVL)) | ||
6305 | return -EINVAL; | ||
6306 | |||
6307 | wdev = dev->ieee80211_ptr; | ||
6308 | |||
6309 | if (!rdev->ops->set_cqm_txe_config) | ||
6310 | return -EOPNOTSUPP; | ||
6311 | |||
6312 | if (wdev->iftype != NL80211_IFTYPE_STATION && | ||
6313 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | ||
6314 | return -EOPNOTSUPP; | ||
6315 | |||
6316 | return rdev->ops->set_cqm_txe_config(wdev->wiphy, dev, | ||
6317 | rate, pkts, intvl); | ||
6318 | } | ||
6319 | |||
6163 | static int nl80211_set_cqm_rssi(struct genl_info *info, | 6320 | static int nl80211_set_cqm_rssi(struct genl_info *info, |
6164 | s32 threshold, u32 hysteresis) | 6321 | s32 threshold, u32 hysteresis) |
6165 | { | 6322 | { |
@@ -6207,6 +6364,14 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | |||
6207 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); | 6364 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); |
6208 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); | 6365 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); |
6209 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); | 6366 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); |
6367 | } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | ||
6368 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | ||
6369 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | ||
6370 | u32 rate, pkts, intvl; | ||
6371 | rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | ||
6372 | pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | ||
6373 | intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | ||
6374 | err = nl80211_set_cqm_txe(info, rate, pkts, intvl); | ||
6210 | } else | 6375 | } else |
6211 | err = -EINVAL; | 6376 | err = -EINVAL; |
6212 | 6377 | ||
@@ -6363,8 +6528,8 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6363 | { | 6528 | { |
6364 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6529 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6365 | struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; | 6530 | struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; |
6366 | struct cfg80211_wowlan no_triggers = {}; | ||
6367 | struct cfg80211_wowlan new_triggers = {}; | 6531 | struct cfg80211_wowlan new_triggers = {}; |
6532 | struct cfg80211_wowlan *ntrig; | ||
6368 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; | 6533 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; |
6369 | int err, i; | 6534 | int err, i; |
6370 | bool prev_enabled = rdev->wowlan; | 6535 | bool prev_enabled = rdev->wowlan; |
@@ -6372,8 +6537,11 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6372 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) | 6537 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) |
6373 | return -EOPNOTSUPP; | 6538 | return -EOPNOTSUPP; |
6374 | 6539 | ||
6375 | if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) | 6540 | if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { |
6376 | goto no_triggers; | 6541 | cfg80211_rdev_free_wowlan(rdev); |
6542 | rdev->wowlan = NULL; | ||
6543 | goto set_wakeup; | ||
6544 | } | ||
6377 | 6545 | ||
6378 | err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, | 6546 | err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, |
6379 | nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), | 6547 | nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), |
@@ -6484,22 +6652,15 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
6484 | } | 6652 | } |
6485 | } | 6653 | } |
6486 | 6654 | ||
6487 | if (memcmp(&new_triggers, &no_triggers, sizeof(new_triggers))) { | 6655 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); |
6488 | struct cfg80211_wowlan *ntrig; | 6656 | if (!ntrig) { |
6489 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), | 6657 | err = -ENOMEM; |
6490 | GFP_KERNEL); | 6658 | goto error; |
6491 | if (!ntrig) { | ||
6492 | err = -ENOMEM; | ||
6493 | goto error; | ||
6494 | } | ||
6495 | cfg80211_rdev_free_wowlan(rdev); | ||
6496 | rdev->wowlan = ntrig; | ||
6497 | } else { | ||
6498 | no_triggers: | ||
6499 | cfg80211_rdev_free_wowlan(rdev); | ||
6500 | rdev->wowlan = NULL; | ||
6501 | } | 6659 | } |
6660 | cfg80211_rdev_free_wowlan(rdev); | ||
6661 | rdev->wowlan = ntrig; | ||
6502 | 6662 | ||
6663 | set_wakeup: | ||
6503 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) | 6664 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) |
6504 | rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan); | 6665 | rdev->ops->set_wakeup(&rdev->wiphy, rdev->wowlan); |
6505 | 6666 | ||
@@ -6655,13 +6816,17 @@ static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | |||
6655 | #define NL80211_FLAG_CHECK_NETDEV_UP 0x08 | 6816 | #define NL80211_FLAG_CHECK_NETDEV_UP 0x08 |
6656 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ | 6817 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ |
6657 | NL80211_FLAG_CHECK_NETDEV_UP) | 6818 | NL80211_FLAG_CHECK_NETDEV_UP) |
6819 | #define NL80211_FLAG_NEED_WDEV 0x10 | ||
6820 | /* If a netdev is associated, it must be UP */ | ||
6821 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | ||
6822 | NL80211_FLAG_CHECK_NETDEV_UP) | ||
6658 | 6823 | ||
6659 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 6824 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, |
6660 | struct genl_info *info) | 6825 | struct genl_info *info) |
6661 | { | 6826 | { |
6662 | struct cfg80211_registered_device *rdev; | 6827 | struct cfg80211_registered_device *rdev; |
6828 | struct wireless_dev *wdev; | ||
6663 | struct net_device *dev; | 6829 | struct net_device *dev; |
6664 | int err; | ||
6665 | bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; | 6830 | bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; |
6666 | 6831 | ||
6667 | if (rtnl) | 6832 | if (rtnl) |
@@ -6675,24 +6840,51 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | |||
6675 | return PTR_ERR(rdev); | 6840 | return PTR_ERR(rdev); |
6676 | } | 6841 | } |
6677 | info->user_ptr[0] = rdev; | 6842 | info->user_ptr[0] = rdev; |
6678 | } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { | 6843 | } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || |
6679 | err = get_rdev_dev_by_ifindex(genl_info_net(info), info->attrs, | 6844 | ops->internal_flags & NL80211_FLAG_NEED_WDEV) { |
6680 | &rdev, &dev); | 6845 | mutex_lock(&cfg80211_mutex); |
6681 | if (err) { | 6846 | wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), |
6847 | info->attrs); | ||
6848 | if (IS_ERR(wdev)) { | ||
6849 | mutex_unlock(&cfg80211_mutex); | ||
6682 | if (rtnl) | 6850 | if (rtnl) |
6683 | rtnl_unlock(); | 6851 | rtnl_unlock(); |
6684 | return err; | 6852 | return PTR_ERR(wdev); |
6685 | } | 6853 | } |
6686 | if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && | 6854 | |
6687 | !netif_running(dev)) { | 6855 | dev = wdev->netdev; |
6688 | cfg80211_unlock_rdev(rdev); | 6856 | rdev = wiphy_to_dev(wdev->wiphy); |
6689 | dev_put(dev); | 6857 | |
6690 | if (rtnl) | 6858 | if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { |
6691 | rtnl_unlock(); | 6859 | if (!dev) { |
6692 | return -ENETDOWN; | 6860 | mutex_unlock(&cfg80211_mutex); |
6861 | if (rtnl) | ||
6862 | rtnl_unlock(); | ||
6863 | return -EINVAL; | ||
6864 | } | ||
6865 | |||
6866 | info->user_ptr[1] = dev; | ||
6867 | } else { | ||
6868 | info->user_ptr[1] = wdev; | ||
6693 | } | 6869 | } |
6870 | |||
6871 | if (dev) { | ||
6872 | if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && | ||
6873 | !netif_running(dev)) { | ||
6874 | mutex_unlock(&cfg80211_mutex); | ||
6875 | if (rtnl) | ||
6876 | rtnl_unlock(); | ||
6877 | return -ENETDOWN; | ||
6878 | } | ||
6879 | |||
6880 | dev_hold(dev); | ||
6881 | } | ||
6882 | |||
6883 | cfg80211_lock_rdev(rdev); | ||
6884 | |||
6885 | mutex_unlock(&cfg80211_mutex); | ||
6886 | |||
6694 | info->user_ptr[0] = rdev; | 6887 | info->user_ptr[0] = rdev; |
6695 | info->user_ptr[1] = dev; | ||
6696 | } | 6888 | } |
6697 | 6889 | ||
6698 | return 0; | 6890 | return 0; |
@@ -6703,8 +6895,16 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | |||
6703 | { | 6895 | { |
6704 | if (info->user_ptr[0]) | 6896 | if (info->user_ptr[0]) |
6705 | cfg80211_unlock_rdev(info->user_ptr[0]); | 6897 | cfg80211_unlock_rdev(info->user_ptr[0]); |
6706 | if (info->user_ptr[1]) | 6898 | if (info->user_ptr[1]) { |
6707 | dev_put(info->user_ptr[1]); | 6899 | if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { |
6900 | struct wireless_dev *wdev = info->user_ptr[1]; | ||
6901 | |||
6902 | if (wdev->netdev) | ||
6903 | dev_put(wdev->netdev); | ||
6904 | } else { | ||
6905 | dev_put(info->user_ptr[1]); | ||
6906 | } | ||
6907 | } | ||
6708 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) | 6908 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) |
6709 | rtnl_unlock(); | 6909 | rtnl_unlock(); |
6710 | } | 6910 | } |
@@ -6731,7 +6931,7 @@ static struct genl_ops nl80211_ops[] = { | |||
6731 | .dumpit = nl80211_dump_interface, | 6931 | .dumpit = nl80211_dump_interface, |
6732 | .policy = nl80211_policy, | 6932 | .policy = nl80211_policy, |
6733 | /* can be retrieved by unprivileged users */ | 6933 | /* can be retrieved by unprivileged users */ |
6734 | .internal_flags = NL80211_FLAG_NEED_NETDEV, | 6934 | .internal_flags = NL80211_FLAG_NEED_WDEV, |
6735 | }, | 6935 | }, |
6736 | { | 6936 | { |
6737 | .cmd = NL80211_CMD_SET_INTERFACE, | 6937 | .cmd = NL80211_CMD_SET_INTERFACE, |
@@ -6754,7 +6954,7 @@ static struct genl_ops nl80211_ops[] = { | |||
6754 | .doit = nl80211_del_interface, | 6954 | .doit = nl80211_del_interface, |
6755 | .policy = nl80211_policy, | 6955 | .policy = nl80211_policy, |
6756 | .flags = GENL_ADMIN_PERM, | 6956 | .flags = GENL_ADMIN_PERM, |
6757 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 6957 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
6758 | NL80211_FLAG_NEED_RTNL, | 6958 | NL80211_FLAG_NEED_RTNL, |
6759 | }, | 6959 | }, |
6760 | { | 6960 | { |
@@ -6925,7 +7125,7 @@ static struct genl_ops nl80211_ops[] = { | |||
6925 | .doit = nl80211_trigger_scan, | 7125 | .doit = nl80211_trigger_scan, |
6926 | .policy = nl80211_policy, | 7126 | .policy = nl80211_policy, |
6927 | .flags = GENL_ADMIN_PERM, | 7127 | .flags = GENL_ADMIN_PERM, |
6928 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7128 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
6929 | NL80211_FLAG_NEED_RTNL, | 7129 | NL80211_FLAG_NEED_RTNL, |
6930 | }, | 7130 | }, |
6931 | { | 7131 | { |
@@ -7066,7 +7266,7 @@ static struct genl_ops nl80211_ops[] = { | |||
7066 | .doit = nl80211_remain_on_channel, | 7266 | .doit = nl80211_remain_on_channel, |
7067 | .policy = nl80211_policy, | 7267 | .policy = nl80211_policy, |
7068 | .flags = GENL_ADMIN_PERM, | 7268 | .flags = GENL_ADMIN_PERM, |
7069 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7269 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7070 | NL80211_FLAG_NEED_RTNL, | 7270 | NL80211_FLAG_NEED_RTNL, |
7071 | }, | 7271 | }, |
7072 | { | 7272 | { |
@@ -7074,7 +7274,7 @@ static struct genl_ops nl80211_ops[] = { | |||
7074 | .doit = nl80211_cancel_remain_on_channel, | 7274 | .doit = nl80211_cancel_remain_on_channel, |
7075 | .policy = nl80211_policy, | 7275 | .policy = nl80211_policy, |
7076 | .flags = GENL_ADMIN_PERM, | 7276 | .flags = GENL_ADMIN_PERM, |
7077 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7277 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7078 | NL80211_FLAG_NEED_RTNL, | 7278 | NL80211_FLAG_NEED_RTNL, |
7079 | }, | 7279 | }, |
7080 | { | 7280 | { |
@@ -7090,7 +7290,7 @@ static struct genl_ops nl80211_ops[] = { | |||
7090 | .doit = nl80211_register_mgmt, | 7290 | .doit = nl80211_register_mgmt, |
7091 | .policy = nl80211_policy, | 7291 | .policy = nl80211_policy, |
7092 | .flags = GENL_ADMIN_PERM, | 7292 | .flags = GENL_ADMIN_PERM, |
7093 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7293 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
7094 | NL80211_FLAG_NEED_RTNL, | 7294 | NL80211_FLAG_NEED_RTNL, |
7095 | }, | 7295 | }, |
7096 | { | 7296 | { |
@@ -7098,7 +7298,7 @@ static struct genl_ops nl80211_ops[] = { | |||
7098 | .doit = nl80211_tx_mgmt, | 7298 | .doit = nl80211_tx_mgmt, |
7099 | .policy = nl80211_policy, | 7299 | .policy = nl80211_policy, |
7100 | .flags = GENL_ADMIN_PERM, | 7300 | .flags = GENL_ADMIN_PERM, |
7101 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7301 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7102 | NL80211_FLAG_NEED_RTNL, | 7302 | NL80211_FLAG_NEED_RTNL, |
7103 | }, | 7303 | }, |
7104 | { | 7304 | { |
@@ -7106,7 +7306,7 @@ static struct genl_ops nl80211_ops[] = { | |||
7106 | .doit = nl80211_tx_mgmt_cancel_wait, | 7306 | .doit = nl80211_tx_mgmt_cancel_wait, |
7107 | .policy = nl80211_policy, | 7307 | .policy = nl80211_policy, |
7108 | .flags = GENL_ADMIN_PERM, | 7308 | .flags = GENL_ADMIN_PERM, |
7109 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7309 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7110 | NL80211_FLAG_NEED_RTNL, | 7310 | NL80211_FLAG_NEED_RTNL, |
7111 | }, | 7311 | }, |
7112 | { | 7312 | { |
@@ -7317,7 +7517,7 @@ static int nl80211_add_scan_req(struct sk_buff *msg, | |||
7317 | 7517 | ||
7318 | static int nl80211_send_scan_msg(struct sk_buff *msg, | 7518 | static int nl80211_send_scan_msg(struct sk_buff *msg, |
7319 | struct cfg80211_registered_device *rdev, | 7519 | struct cfg80211_registered_device *rdev, |
7320 | struct net_device *netdev, | 7520 | struct wireless_dev *wdev, |
7321 | u32 pid, u32 seq, int flags, | 7521 | u32 pid, u32 seq, int flags, |
7322 | u32 cmd) | 7522 | u32 cmd) |
7323 | { | 7523 | { |
@@ -7328,7 +7528,9 @@ static int nl80211_send_scan_msg(struct sk_buff *msg, | |||
7328 | return -1; | 7528 | return -1; |
7329 | 7529 | ||
7330 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 7530 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
7331 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) | 7531 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
7532 | wdev->netdev->ifindex)) || | ||
7533 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) | ||
7332 | goto nla_put_failure; | 7534 | goto nla_put_failure; |
7333 | 7535 | ||
7334 | /* ignore errors and send incomplete event anyway */ | 7536 | /* ignore errors and send incomplete event anyway */ |
@@ -7365,7 +7567,7 @@ nl80211_send_sched_scan_msg(struct sk_buff *msg, | |||
7365 | } | 7567 | } |
7366 | 7568 | ||
7367 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 7569 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
7368 | struct net_device *netdev) | 7570 | struct wireless_dev *wdev) |
7369 | { | 7571 | { |
7370 | struct sk_buff *msg; | 7572 | struct sk_buff *msg; |
7371 | 7573 | ||
@@ -7373,7 +7575,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | |||
7373 | if (!msg) | 7575 | if (!msg) |
7374 | return; | 7576 | return; |
7375 | 7577 | ||
7376 | if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0, | 7578 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7377 | NL80211_CMD_TRIGGER_SCAN) < 0) { | 7579 | NL80211_CMD_TRIGGER_SCAN) < 0) { |
7378 | nlmsg_free(msg); | 7580 | nlmsg_free(msg); |
7379 | return; | 7581 | return; |
@@ -7384,7 +7586,7 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | |||
7384 | } | 7586 | } |
7385 | 7587 | ||
7386 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 7588 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, |
7387 | struct net_device *netdev) | 7589 | struct wireless_dev *wdev) |
7388 | { | 7590 | { |
7389 | struct sk_buff *msg; | 7591 | struct sk_buff *msg; |
7390 | 7592 | ||
@@ -7392,7 +7594,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | |||
7392 | if (!msg) | 7594 | if (!msg) |
7393 | return; | 7595 | return; |
7394 | 7596 | ||
7395 | if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0, | 7597 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7396 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | 7598 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { |
7397 | nlmsg_free(msg); | 7599 | nlmsg_free(msg); |
7398 | return; | 7600 | return; |
@@ -7403,7 +7605,7 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | |||
7403 | } | 7605 | } |
7404 | 7606 | ||
7405 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 7607 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, |
7406 | struct net_device *netdev) | 7608 | struct wireless_dev *wdev) |
7407 | { | 7609 | { |
7408 | struct sk_buff *msg; | 7610 | struct sk_buff *msg; |
7409 | 7611 | ||
@@ -7411,7 +7613,7 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | |||
7411 | if (!msg) | 7613 | if (!msg) |
7412 | return; | 7614 | return; |
7413 | 7615 | ||
7414 | if (nl80211_send_scan_msg(msg, rdev, netdev, 0, 0, 0, | 7616 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7415 | NL80211_CMD_SCAN_ABORTED) < 0) { | 7617 | NL80211_CMD_SCAN_ABORTED) < 0) { |
7416 | nlmsg_free(msg); | 7618 | nlmsg_free(msg); |
7417 | return; | 7619 | return; |
@@ -7934,7 +8136,7 @@ nla_put_failure: | |||
7934 | 8136 | ||
7935 | static void nl80211_send_remain_on_chan_event( | 8137 | static void nl80211_send_remain_on_chan_event( |
7936 | int cmd, struct cfg80211_registered_device *rdev, | 8138 | int cmd, struct cfg80211_registered_device *rdev, |
7937 | struct net_device *netdev, u64 cookie, | 8139 | struct wireless_dev *wdev, u64 cookie, |
7938 | struct ieee80211_channel *chan, | 8140 | struct ieee80211_channel *chan, |
7939 | enum nl80211_channel_type channel_type, | 8141 | enum nl80211_channel_type channel_type, |
7940 | unsigned int duration, gfp_t gfp) | 8142 | unsigned int duration, gfp_t gfp) |
@@ -7953,7 +8155,9 @@ static void nl80211_send_remain_on_chan_event( | |||
7953 | } | 8155 | } |
7954 | 8156 | ||
7955 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8157 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
7956 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8158 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8159 | wdev->netdev->ifindex)) || | ||
8160 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || | ||
7957 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || | 8161 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || |
7958 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) || | 8162 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, channel_type) || |
7959 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) | 8163 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) |
@@ -7975,23 +8179,24 @@ static void nl80211_send_remain_on_chan_event( | |||
7975 | } | 8179 | } |
7976 | 8180 | ||
7977 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, | 8181 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, |
7978 | struct net_device *netdev, u64 cookie, | 8182 | struct wireless_dev *wdev, u64 cookie, |
7979 | struct ieee80211_channel *chan, | 8183 | struct ieee80211_channel *chan, |
7980 | enum nl80211_channel_type channel_type, | 8184 | enum nl80211_channel_type channel_type, |
7981 | unsigned int duration, gfp_t gfp) | 8185 | unsigned int duration, gfp_t gfp) |
7982 | { | 8186 | { |
7983 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, | 8187 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, |
7984 | rdev, netdev, cookie, chan, | 8188 | rdev, wdev, cookie, chan, |
7985 | channel_type, duration, gfp); | 8189 | channel_type, duration, gfp); |
7986 | } | 8190 | } |
7987 | 8191 | ||
7988 | void nl80211_send_remain_on_channel_cancel( | 8192 | void nl80211_send_remain_on_channel_cancel( |
7989 | struct cfg80211_registered_device *rdev, struct net_device *netdev, | 8193 | struct cfg80211_registered_device *rdev, |
8194 | struct wireless_dev *wdev, | ||
7990 | u64 cookie, struct ieee80211_channel *chan, | 8195 | u64 cookie, struct ieee80211_channel *chan, |
7991 | enum nl80211_channel_type channel_type, gfp_t gfp) | 8196 | enum nl80211_channel_type channel_type, gfp_t gfp) |
7992 | { | 8197 | { |
7993 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, | 8198 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, |
7994 | rdev, netdev, cookie, chan, | 8199 | rdev, wdev, cookie, chan, |
7995 | channel_type, 0, gfp); | 8200 | channel_type, 0, gfp); |
7996 | } | 8201 | } |
7997 | 8202 | ||
@@ -8105,10 +8310,11 @@ bool nl80211_unexpected_4addr_frame(struct net_device *dev, | |||
8105 | } | 8310 | } |
8106 | 8311 | ||
8107 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 8312 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
8108 | struct net_device *netdev, u32 nlpid, | 8313 | struct wireless_dev *wdev, u32 nlpid, |
8109 | int freq, int sig_dbm, | 8314 | int freq, int sig_dbm, |
8110 | const u8 *buf, size_t len, gfp_t gfp) | 8315 | const u8 *buf, size_t len, gfp_t gfp) |
8111 | { | 8316 | { |
8317 | struct net_device *netdev = wdev->netdev; | ||
8112 | struct sk_buff *msg; | 8318 | struct sk_buff *msg; |
8113 | void *hdr; | 8319 | void *hdr; |
8114 | 8320 | ||
@@ -8123,7 +8329,8 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
8123 | } | 8329 | } |
8124 | 8330 | ||
8125 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8331 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8126 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8332 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8333 | netdev->ifindex)) || | ||
8127 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || | 8334 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || |
8128 | (sig_dbm && | 8335 | (sig_dbm && |
8129 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || | 8336 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || |
@@ -8141,10 +8348,11 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | |||
8141 | } | 8348 | } |
8142 | 8349 | ||
8143 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | 8350 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, |
8144 | struct net_device *netdev, u64 cookie, | 8351 | struct wireless_dev *wdev, u64 cookie, |
8145 | const u8 *buf, size_t len, bool ack, | 8352 | const u8 *buf, size_t len, bool ack, |
8146 | gfp_t gfp) | 8353 | gfp_t gfp) |
8147 | { | 8354 | { |
8355 | struct net_device *netdev = wdev->netdev; | ||
8148 | struct sk_buff *msg; | 8356 | struct sk_buff *msg; |
8149 | void *hdr; | 8357 | void *hdr; |
8150 | 8358 | ||
@@ -8159,7 +8367,8 @@ void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | |||
8159 | } | 8367 | } |
8160 | 8368 | ||
8161 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8369 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8162 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8370 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8371 | netdev->ifindex)) || | ||
8163 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || | 8372 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || |
8164 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || | 8373 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || |
8165 | (ack && nla_put_flag(msg, NL80211_ATTR_ACK))) | 8374 | (ack && nla_put_flag(msg, NL80211_ATTR_ACK))) |
@@ -8343,6 +8552,56 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, | |||
8343 | } | 8552 | } |
8344 | 8553 | ||
8345 | void | 8554 | void |
8555 | nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev, | ||
8556 | struct net_device *netdev, const u8 *peer, | ||
8557 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp) | ||
8558 | { | ||
8559 | struct sk_buff *msg; | ||
8560 | struct nlattr *pinfoattr; | ||
8561 | void *hdr; | ||
8562 | |||
8563 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | ||
8564 | if (!msg) | ||
8565 | return; | ||
8566 | |||
8567 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); | ||
8568 | if (!hdr) { | ||
8569 | nlmsg_free(msg); | ||
8570 | return; | ||
8571 | } | ||
8572 | |||
8573 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | ||
8574 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | ||
8575 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) | ||
8576 | goto nla_put_failure; | ||
8577 | |||
8578 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); | ||
8579 | if (!pinfoattr) | ||
8580 | goto nla_put_failure; | ||
8581 | |||
8582 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets)) | ||
8583 | goto nla_put_failure; | ||
8584 | |||
8585 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate)) | ||
8586 | goto nla_put_failure; | ||
8587 | |||
8588 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl)) | ||
8589 | goto nla_put_failure; | ||
8590 | |||
8591 | nla_nest_end(msg, pinfoattr); | ||
8592 | |||
8593 | genlmsg_end(msg, hdr); | ||
8594 | |||
8595 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | ||
8596 | nl80211_mlme_mcgrp.id, gfp); | ||
8597 | return; | ||
8598 | |||
8599 | nla_put_failure: | ||
8600 | genlmsg_cancel(msg, hdr); | ||
8601 | nlmsg_free(msg); | ||
8602 | } | ||
8603 | |||
8604 | void | ||
8346 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 8605 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, |
8347 | struct net_device *netdev, const u8 *peer, | 8606 | struct net_device *netdev, const u8 *peer, |
8348 | u32 num_packets, gfp_t gfp) | 8607 | u32 num_packets, gfp_t gfp) |
@@ -8483,7 +8742,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb, | |||
8483 | rcu_read_lock(); | 8742 | rcu_read_lock(); |
8484 | 8743 | ||
8485 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 8744 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
8486 | list_for_each_entry_rcu(wdev, &rdev->netdev_list, list) | 8745 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) |
8487 | cfg80211_mlme_unregister_socket(wdev, notify->pid); | 8746 | cfg80211_mlme_unregister_socket(wdev, notify->pid); |
8488 | if (rdev->ap_beacons_nlpid == notify->pid) | 8747 | if (rdev->ap_beacons_nlpid == notify->pid) |
8489 | rdev->ap_beacons_nlpid = 0; | 8748 | rdev->ap_beacons_nlpid = 0; |
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 01a1122c3b33..9f2616fffb40 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -7,11 +7,11 @@ int nl80211_init(void); | |||
7 | void nl80211_exit(void); | 7 | void nl80211_exit(void); |
8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); | 8 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev); |
9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 9 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
10 | struct net_device *netdev); | 10 | struct wireless_dev *wdev); |
11 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 11 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, |
12 | struct net_device *netdev); | 12 | struct wireless_dev *wdev); |
13 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 13 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, |
14 | struct net_device *netdev); | 14 | struct wireless_dev *wdev); |
15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 15 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, |
16 | struct net_device *netdev, u32 cmd); | 16 | struct net_device *netdev, u32 cmd); |
17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 17 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
@@ -74,13 +74,13 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | |||
74 | gfp_t gfp); | 74 | gfp_t gfp); |
75 | 75 | ||
76 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, | 76 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, |
77 | struct net_device *netdev, | 77 | struct wireless_dev *wdev, u64 cookie, |
78 | u64 cookie, | ||
79 | struct ieee80211_channel *chan, | 78 | struct ieee80211_channel *chan, |
80 | enum nl80211_channel_type channel_type, | 79 | enum nl80211_channel_type channel_type, |
81 | unsigned int duration, gfp_t gfp); | 80 | unsigned int duration, gfp_t gfp); |
82 | void nl80211_send_remain_on_channel_cancel( | 81 | void nl80211_send_remain_on_channel_cancel( |
83 | struct cfg80211_registered_device *rdev, struct net_device *netdev, | 82 | struct cfg80211_registered_device *rdev, |
83 | struct wireless_dev *wdev, | ||
84 | u64 cookie, struct ieee80211_channel *chan, | 84 | u64 cookie, struct ieee80211_channel *chan, |
85 | enum nl80211_channel_type channel_type, gfp_t gfp); | 85 | enum nl80211_channel_type channel_type, gfp_t gfp); |
86 | 86 | ||
@@ -92,11 +92,11 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | |||
92 | gfp_t gfp); | 92 | gfp_t gfp); |
93 | 93 | ||
94 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 94 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
95 | struct net_device *netdev, u32 nlpid, | 95 | struct wireless_dev *wdev, u32 nlpid, |
96 | int freq, int sig_dbm, | 96 | int freq, int sig_dbm, |
97 | const u8 *buf, size_t len, gfp_t gfp); | 97 | const u8 *buf, size_t len, gfp_t gfp); |
98 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | 98 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, |
99 | struct net_device *netdev, u64 cookie, | 99 | struct wireless_dev *wdev, u64 cookie, |
100 | const u8 *buf, size_t len, bool ack, | 100 | const u8 *buf, size_t len, bool ack, |
101 | gfp_t gfp); | 101 | gfp_t gfp); |
102 | 102 | ||
@@ -110,6 +110,11 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | |||
110 | struct net_device *netdev, const u8 *peer, | 110 | struct net_device *netdev, const u8 *peer, |
111 | u32 num_packets, gfp_t gfp); | 111 | u32 num_packets, gfp_t gfp); |
112 | 112 | ||
113 | void | ||
114 | nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev, | ||
115 | struct net_device *netdev, const u8 *peer, | ||
116 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp); | ||
117 | |||
113 | void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | 118 | void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, |
114 | struct net_device *netdev, const u8 *bssid, | 119 | struct net_device *netdev, const u8 *bssid, |
115 | const u8 *replay_ctr, gfp_t gfp); | 120 | const u8 *replay_ctr, gfp_t gfp); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b2b32229b607..2303ee73b50a 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -97,9 +97,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain; | |||
97 | * - cfg80211_world_regdom | 97 | * - cfg80211_world_regdom |
98 | * - cfg80211_regdom | 98 | * - cfg80211_regdom |
99 | * - last_request | 99 | * - last_request |
100 | * - reg_num_devs_support_basehint | ||
100 | */ | 101 | */ |
101 | static DEFINE_MUTEX(reg_mutex); | 102 | static DEFINE_MUTEX(reg_mutex); |
102 | 103 | ||
104 | /* | ||
105 | * Number of devices that registered to the core | ||
106 | * that support cellular base station regulatory hints | ||
107 | */ | ||
108 | static int reg_num_devs_support_basehint; | ||
109 | |||
103 | static inline void assert_reg_lock(void) | 110 | static inline void assert_reg_lock(void) |
104 | { | 111 | { |
105 | lockdep_assert_held(®_mutex); | 112 | lockdep_assert_held(®_mutex); |
@@ -911,6 +918,61 @@ static void handle_band(struct wiphy *wiphy, | |||
911 | handle_channel(wiphy, initiator, band, i); | 918 | handle_channel(wiphy, initiator, band, i); |
912 | } | 919 | } |
913 | 920 | ||
921 | static bool reg_request_cell_base(struct regulatory_request *request) | ||
922 | { | ||
923 | if (request->initiator != NL80211_REGDOM_SET_BY_USER) | ||
924 | return false; | ||
925 | if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE) | ||
926 | return false; | ||
927 | return true; | ||
928 | } | ||
929 | |||
930 | bool reg_last_request_cell_base(void) | ||
931 | { | ||
932 | bool val; | ||
933 | assert_cfg80211_lock(); | ||
934 | |||
935 | mutex_lock(®_mutex); | ||
936 | val = reg_request_cell_base(last_request); | ||
937 | mutex_unlock(®_mutex); | ||
938 | return val; | ||
939 | } | ||
940 | |||
941 | #ifdef CONFIG_CFG80211_CERTIFICATION_ONUS | ||
942 | |||
943 | /* Core specific check */ | ||
944 | static int reg_ignore_cell_hint(struct regulatory_request *pending_request) | ||
945 | { | ||
946 | if (!reg_num_devs_support_basehint) | ||
947 | return -EOPNOTSUPP; | ||
948 | |||
949 | if (reg_request_cell_base(last_request)) { | ||
950 | if (!regdom_changes(pending_request->alpha2)) | ||
951 | return -EALREADY; | ||
952 | return 0; | ||
953 | } | ||
954 | return 0; | ||
955 | } | ||
956 | |||
957 | /* Device specific check */ | ||
958 | static bool reg_dev_ignore_cell_hint(struct wiphy *wiphy) | ||
959 | { | ||
960 | if (!(wiphy->features & NL80211_FEATURE_CELL_BASE_REG_HINTS)) | ||
961 | return true; | ||
962 | return false; | ||
963 | } | ||
964 | #else | ||
965 | static int reg_ignore_cell_hint(struct regulatory_request *pending_request) | ||
966 | { | ||
967 | return -EOPNOTSUPP; | ||
968 | } | ||
969 | static int reg_dev_ignore_cell_hint(struct wiphy *wiphy) | ||
970 | { | ||
971 | return true; | ||
972 | } | ||
973 | #endif | ||
974 | |||
975 | |||
914 | static bool ignore_reg_update(struct wiphy *wiphy, | 976 | static bool ignore_reg_update(struct wiphy *wiphy, |
915 | enum nl80211_reg_initiator initiator) | 977 | enum nl80211_reg_initiator initiator) |
916 | { | 978 | { |
@@ -944,6 +1006,9 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
944 | return true; | 1006 | return true; |
945 | } | 1007 | } |
946 | 1008 | ||
1009 | if (reg_request_cell_base(last_request)) | ||
1010 | return reg_dev_ignore_cell_hint(wiphy); | ||
1011 | |||
947 | return false; | 1012 | return false; |
948 | } | 1013 | } |
949 | 1014 | ||
@@ -1169,14 +1234,6 @@ static void wiphy_update_regulatory(struct wiphy *wiphy, | |||
1169 | wiphy->reg_notifier(wiphy, last_request); | 1234 | wiphy->reg_notifier(wiphy, last_request); |
1170 | } | 1235 | } |
1171 | 1236 | ||
1172 | void regulatory_update(struct wiphy *wiphy, | ||
1173 | enum nl80211_reg_initiator setby) | ||
1174 | { | ||
1175 | mutex_lock(®_mutex); | ||
1176 | wiphy_update_regulatory(wiphy, setby); | ||
1177 | mutex_unlock(®_mutex); | ||
1178 | } | ||
1179 | |||
1180 | static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) | 1237 | static void update_all_wiphy_regulatory(enum nl80211_reg_initiator initiator) |
1181 | { | 1238 | { |
1182 | struct cfg80211_registered_device *rdev; | 1239 | struct cfg80211_registered_device *rdev; |
@@ -1307,6 +1364,13 @@ static int ignore_request(struct wiphy *wiphy, | |||
1307 | return 0; | 1364 | return 0; |
1308 | case NL80211_REGDOM_SET_BY_COUNTRY_IE: | 1365 | case NL80211_REGDOM_SET_BY_COUNTRY_IE: |
1309 | 1366 | ||
1367 | if (reg_request_cell_base(last_request)) { | ||
1368 | /* Trust a Cell base station over the AP's country IE */ | ||
1369 | if (regdom_changes(pending_request->alpha2)) | ||
1370 | return -EOPNOTSUPP; | ||
1371 | return -EALREADY; | ||
1372 | } | ||
1373 | |||
1310 | last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); | 1374 | last_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); |
1311 | 1375 | ||
1312 | if (unlikely(!is_an_alpha2(pending_request->alpha2))) | 1376 | if (unlikely(!is_an_alpha2(pending_request->alpha2))) |
@@ -1351,6 +1415,12 @@ static int ignore_request(struct wiphy *wiphy, | |||
1351 | 1415 | ||
1352 | return REG_INTERSECT; | 1416 | return REG_INTERSECT; |
1353 | case NL80211_REGDOM_SET_BY_USER: | 1417 | case NL80211_REGDOM_SET_BY_USER: |
1418 | if (reg_request_cell_base(pending_request)) | ||
1419 | return reg_ignore_cell_hint(pending_request); | ||
1420 | |||
1421 | if (reg_request_cell_base(last_request)) | ||
1422 | return -EOPNOTSUPP; | ||
1423 | |||
1354 | if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) | 1424 | if (last_request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) |
1355 | return REG_INTERSECT; | 1425 | return REG_INTERSECT; |
1356 | /* | 1426 | /* |
@@ -1640,7 +1710,8 @@ static int regulatory_hint_core(const char *alpha2) | |||
1640 | } | 1710 | } |
1641 | 1711 | ||
1642 | /* User hints */ | 1712 | /* User hints */ |
1643 | int regulatory_hint_user(const char *alpha2) | 1713 | int regulatory_hint_user(const char *alpha2, |
1714 | enum nl80211_user_reg_hint_type user_reg_hint_type) | ||
1644 | { | 1715 | { |
1645 | struct regulatory_request *request; | 1716 | struct regulatory_request *request; |
1646 | 1717 | ||
@@ -1654,6 +1725,7 @@ int regulatory_hint_user(const char *alpha2) | |||
1654 | request->alpha2[0] = alpha2[0]; | 1725 | request->alpha2[0] = alpha2[0]; |
1655 | request->alpha2[1] = alpha2[1]; | 1726 | request->alpha2[1] = alpha2[1]; |
1656 | request->initiator = NL80211_REGDOM_SET_BY_USER; | 1727 | request->initiator = NL80211_REGDOM_SET_BY_USER; |
1728 | request->user_reg_hint_type = user_reg_hint_type; | ||
1657 | 1729 | ||
1658 | queue_regulatory_request(request); | 1730 | queue_regulatory_request(request); |
1659 | 1731 | ||
@@ -1906,7 +1978,7 @@ static void restore_regulatory_settings(bool reset_user) | |||
1906 | * settings, user regulatory settings takes precedence. | 1978 | * settings, user regulatory settings takes precedence. |
1907 | */ | 1979 | */ |
1908 | if (is_an_alpha2(alpha2)) | 1980 | if (is_an_alpha2(alpha2)) |
1909 | regulatory_hint_user(user_alpha2); | 1981 | regulatory_hint_user(user_alpha2, NL80211_USER_REG_HINT_USER); |
1910 | 1982 | ||
1911 | if (list_empty(&tmp_reg_req_list)) | 1983 | if (list_empty(&tmp_reg_req_list)) |
1912 | return; | 1984 | return; |
@@ -2081,9 +2153,16 @@ static void print_regdomain(const struct ieee80211_regdomain *rd) | |||
2081 | else { | 2153 | else { |
2082 | if (is_unknown_alpha2(rd->alpha2)) | 2154 | if (is_unknown_alpha2(rd->alpha2)) |
2083 | pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n"); | 2155 | pr_info("Regulatory domain changed to driver built-in settings (unknown country)\n"); |
2084 | else | 2156 | else { |
2085 | pr_info("Regulatory domain changed to country: %c%c\n", | 2157 | if (reg_request_cell_base(last_request)) |
2086 | rd->alpha2[0], rd->alpha2[1]); | 2158 | pr_info("Regulatory domain changed " |
2159 | "to country: %c%c by Cell Station\n", | ||
2160 | rd->alpha2[0], rd->alpha2[1]); | ||
2161 | else | ||
2162 | pr_info("Regulatory domain changed " | ||
2163 | "to country: %c%c\n", | ||
2164 | rd->alpha2[0], rd->alpha2[1]); | ||
2165 | } | ||
2087 | } | 2166 | } |
2088 | print_dfs_region(rd->dfs_region); | 2167 | print_dfs_region(rd->dfs_region); |
2089 | print_rd_rules(rd); | 2168 | print_rd_rules(rd); |
@@ -2128,7 +2207,7 @@ static int __set_regdom(const struct ieee80211_regdomain *rd) | |||
2128 | * checking if the alpha2 changes if CRDA was already called | 2207 | * checking if the alpha2 changes if CRDA was already called |
2129 | */ | 2208 | */ |
2130 | if (!regdom_changes(rd->alpha2)) | 2209 | if (!regdom_changes(rd->alpha2)) |
2131 | return -EINVAL; | 2210 | return -EALREADY; |
2132 | } | 2211 | } |
2133 | 2212 | ||
2134 | /* | 2213 | /* |
@@ -2248,6 +2327,9 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
2248 | /* Note that this doesn't update the wiphys, this is done below */ | 2327 | /* Note that this doesn't update the wiphys, this is done below */ |
2249 | r = __set_regdom(rd); | 2328 | r = __set_regdom(rd); |
2250 | if (r) { | 2329 | if (r) { |
2330 | if (r == -EALREADY) | ||
2331 | reg_set_request_processed(); | ||
2332 | |||
2251 | kfree(rd); | 2333 | kfree(rd); |
2252 | mutex_unlock(®_mutex); | 2334 | mutex_unlock(®_mutex); |
2253 | return r; | 2335 | return r; |
@@ -2290,8 +2372,22 @@ int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
2290 | } | 2372 | } |
2291 | #endif /* CONFIG_HOTPLUG */ | 2373 | #endif /* CONFIG_HOTPLUG */ |
2292 | 2374 | ||
2375 | void wiphy_regulatory_register(struct wiphy *wiphy) | ||
2376 | { | ||
2377 | assert_cfg80211_lock(); | ||
2378 | |||
2379 | mutex_lock(®_mutex); | ||
2380 | |||
2381 | if (!reg_dev_ignore_cell_hint(wiphy)) | ||
2382 | reg_num_devs_support_basehint++; | ||
2383 | |||
2384 | wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE); | ||
2385 | |||
2386 | mutex_unlock(®_mutex); | ||
2387 | } | ||
2388 | |||
2293 | /* Caller must hold cfg80211_mutex */ | 2389 | /* Caller must hold cfg80211_mutex */ |
2294 | void reg_device_remove(struct wiphy *wiphy) | 2390 | void wiphy_regulatory_deregister(struct wiphy *wiphy) |
2295 | { | 2391 | { |
2296 | struct wiphy *request_wiphy = NULL; | 2392 | struct wiphy *request_wiphy = NULL; |
2297 | 2393 | ||
@@ -2299,6 +2395,9 @@ void reg_device_remove(struct wiphy *wiphy) | |||
2299 | 2395 | ||
2300 | mutex_lock(®_mutex); | 2396 | mutex_lock(®_mutex); |
2301 | 2397 | ||
2398 | if (!reg_dev_ignore_cell_hint(wiphy)) | ||
2399 | reg_num_devs_support_basehint--; | ||
2400 | |||
2302 | kfree(wiphy->regd); | 2401 | kfree(wiphy->regd); |
2303 | 2402 | ||
2304 | if (last_request) | 2403 | if (last_request) |
@@ -2364,7 +2463,8 @@ int __init regulatory_init(void) | |||
2364 | * as a user hint. | 2463 | * as a user hint. |
2365 | */ | 2464 | */ |
2366 | if (!is_world_regdom(ieee80211_regdom)) | 2465 | if (!is_world_regdom(ieee80211_regdom)) |
2367 | regulatory_hint_user(ieee80211_regdom); | 2466 | regulatory_hint_user(ieee80211_regdom, |
2467 | NL80211_USER_REG_HINT_USER); | ||
2368 | 2468 | ||
2369 | return 0; | 2469 | return 0; |
2370 | } | 2470 | } |
diff --git a/net/wireless/reg.h b/net/wireless/reg.h index e2aaaf525a22..f023c8a31c60 100644 --- a/net/wireless/reg.h +++ b/net/wireless/reg.h | |||
@@ -22,17 +22,19 @@ bool is_world_regdom(const char *alpha2); | |||
22 | bool reg_is_valid_request(const char *alpha2); | 22 | bool reg_is_valid_request(const char *alpha2); |
23 | bool reg_supported_dfs_region(u8 dfs_region); | 23 | bool reg_supported_dfs_region(u8 dfs_region); |
24 | 24 | ||
25 | int regulatory_hint_user(const char *alpha2); | 25 | int regulatory_hint_user(const char *alpha2, |
26 | enum nl80211_user_reg_hint_type user_reg_hint_type); | ||
26 | 27 | ||
27 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env); | 28 | int reg_device_uevent(struct device *dev, struct kobj_uevent_env *env); |
28 | void reg_device_remove(struct wiphy *wiphy); | 29 | void wiphy_regulatory_register(struct wiphy *wiphy); |
30 | void wiphy_regulatory_deregister(struct wiphy *wiphy); | ||
29 | 31 | ||
30 | int __init regulatory_init(void); | 32 | int __init regulatory_init(void); |
31 | void regulatory_exit(void); | 33 | void regulatory_exit(void); |
32 | 34 | ||
33 | int set_regdom(const struct ieee80211_regdomain *rd); | 35 | int set_regdom(const struct ieee80211_regdomain *rd); |
34 | 36 | ||
35 | void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby); | 37 | bool reg_last_request_cell_base(void); |
36 | 38 | ||
37 | /** | 39 | /** |
38 | * regulatory_hint_found_beacon - hints a beacon was found on a channel | 40 | * regulatory_hint_found_beacon - hints a beacon was found on a channel |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index af2b1caa37fa..848523a2b22f 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -23,7 +23,7 @@ | |||
23 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) | 23 | void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) |
24 | { | 24 | { |
25 | struct cfg80211_scan_request *request; | 25 | struct cfg80211_scan_request *request; |
26 | struct net_device *dev; | 26 | struct wireless_dev *wdev; |
27 | #ifdef CONFIG_CFG80211_WEXT | 27 | #ifdef CONFIG_CFG80211_WEXT |
28 | union iwreq_data wrqu; | 28 | union iwreq_data wrqu; |
29 | #endif | 29 | #endif |
@@ -35,29 +35,31 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak) | |||
35 | if (!request) | 35 | if (!request) |
36 | return; | 36 | return; |
37 | 37 | ||
38 | dev = request->dev; | 38 | wdev = request->wdev; |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * This must be before sending the other events! | 41 | * This must be before sending the other events! |
42 | * Otherwise, wpa_supplicant gets completely confused with | 42 | * Otherwise, wpa_supplicant gets completely confused with |
43 | * wext events. | 43 | * wext events. |
44 | */ | 44 | */ |
45 | cfg80211_sme_scan_done(dev); | 45 | if (wdev->netdev) |
46 | cfg80211_sme_scan_done(wdev->netdev); | ||
46 | 47 | ||
47 | if (request->aborted) | 48 | if (request->aborted) |
48 | nl80211_send_scan_aborted(rdev, dev); | 49 | nl80211_send_scan_aborted(rdev, wdev); |
49 | else | 50 | else |
50 | nl80211_send_scan_done(rdev, dev); | 51 | nl80211_send_scan_done(rdev, wdev); |
51 | 52 | ||
52 | #ifdef CONFIG_CFG80211_WEXT | 53 | #ifdef CONFIG_CFG80211_WEXT |
53 | if (!request->aborted) { | 54 | if (wdev->netdev && !request->aborted) { |
54 | memset(&wrqu, 0, sizeof(wrqu)); | 55 | memset(&wrqu, 0, sizeof(wrqu)); |
55 | 56 | ||
56 | wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); | 57 | wireless_send_event(wdev->netdev, SIOCGIWSCAN, &wrqu, NULL); |
57 | } | 58 | } |
58 | #endif | 59 | #endif |
59 | 60 | ||
60 | dev_put(dev); | 61 | if (wdev->netdev) |
62 | dev_put(wdev->netdev); | ||
61 | 63 | ||
62 | rdev->scan_req = NULL; | 64 | rdev->scan_req = NULL; |
63 | 65 | ||
@@ -955,7 +957,7 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
955 | } | 957 | } |
956 | 958 | ||
957 | creq->wiphy = wiphy; | 959 | creq->wiphy = wiphy; |
958 | creq->dev = dev; | 960 | creq->wdev = dev->ieee80211_ptr; |
959 | /* SSIDs come after channels */ | 961 | /* SSIDs come after channels */ |
960 | creq->ssids = (void *)&creq->channels[n_channels]; | 962 | creq->ssids = (void *)&creq->channels[n_channels]; |
961 | creq->n_channels = n_channels; | 963 | creq->n_channels = n_channels; |
@@ -1024,12 +1026,12 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
1024 | creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; | 1026 | creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; |
1025 | 1027 | ||
1026 | rdev->scan_req = creq; | 1028 | rdev->scan_req = creq; |
1027 | err = rdev->ops->scan(wiphy, dev, creq); | 1029 | err = rdev->ops->scan(wiphy, creq); |
1028 | if (err) { | 1030 | if (err) { |
1029 | rdev->scan_req = NULL; | 1031 | rdev->scan_req = NULL; |
1030 | /* creq will be freed below */ | 1032 | /* creq will be freed below */ |
1031 | } else { | 1033 | } else { |
1032 | nl80211_send_scan_start(rdev, dev); | 1034 | nl80211_send_scan_start(rdev, dev->ieee80211_ptr); |
1033 | /* creq now owned by driver */ | 1035 | /* creq now owned by driver */ |
1034 | creq = NULL; | 1036 | creq = NULL; |
1035 | dev_hold(dev); | 1037 | dev_hold(dev); |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index f7e937ff8978..6f39cb808302 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -51,7 +51,7 @@ static bool cfg80211_is_all_idle(void) | |||
51 | */ | 51 | */ |
52 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 52 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
53 | cfg80211_lock_rdev(rdev); | 53 | cfg80211_lock_rdev(rdev); |
54 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 54 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
55 | wdev_lock(wdev); | 55 | wdev_lock(wdev); |
56 | if (wdev->sme_state != CFG80211_SME_IDLE) | 56 | if (wdev->sme_state != CFG80211_SME_IDLE) |
57 | is_all_idle = false; | 57 | is_all_idle = false; |
@@ -136,15 +136,15 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev) | |||
136 | wdev->conn->params.ssid_len); | 136 | wdev->conn->params.ssid_len); |
137 | request->ssids[0].ssid_len = wdev->conn->params.ssid_len; | 137 | request->ssids[0].ssid_len = wdev->conn->params.ssid_len; |
138 | 138 | ||
139 | request->dev = wdev->netdev; | 139 | request->wdev = wdev; |
140 | request->wiphy = &rdev->wiphy; | 140 | request->wiphy = &rdev->wiphy; |
141 | 141 | ||
142 | rdev->scan_req = request; | 142 | rdev->scan_req = request; |
143 | 143 | ||
144 | err = rdev->ops->scan(wdev->wiphy, wdev->netdev, request); | 144 | err = rdev->ops->scan(wdev->wiphy, request); |
145 | if (!err) { | 145 | if (!err) { |
146 | wdev->conn->state = CFG80211_CONN_SCANNING; | 146 | wdev->conn->state = CFG80211_CONN_SCANNING; |
147 | nl80211_send_scan_start(rdev, wdev->netdev); | 147 | nl80211_send_scan_start(rdev, wdev); |
148 | dev_hold(wdev->netdev); | 148 | dev_hold(wdev->netdev); |
149 | } else { | 149 | } else { |
150 | rdev->scan_req = NULL; | 150 | rdev->scan_req = NULL; |
@@ -221,7 +221,7 @@ void cfg80211_conn_work(struct work_struct *work) | |||
221 | cfg80211_lock_rdev(rdev); | 221 | cfg80211_lock_rdev(rdev); |
222 | mutex_lock(&rdev->devlist_mtx); | 222 | mutex_lock(&rdev->devlist_mtx); |
223 | 223 | ||
224 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 224 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
225 | wdev_lock(wdev); | 225 | wdev_lock(wdev); |
226 | if (!netif_running(wdev->netdev)) { | 226 | if (!netif_running(wdev->netdev)) { |
227 | wdev_unlock(wdev); | 227 | wdev_unlock(wdev); |
diff --git a/net/wireless/util.c b/net/wireless/util.c index e31f1dba79ec..26f8cd30f712 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -793,7 +793,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev) | |||
793 | 793 | ||
794 | mutex_lock(&rdev->devlist_mtx); | 794 | mutex_lock(&rdev->devlist_mtx); |
795 | 795 | ||
796 | list_for_each_entry(wdev, &rdev->netdev_list, list) | 796 | list_for_each_entry(wdev, &rdev->wdev_list, list) |
797 | cfg80211_process_wdev_events(wdev); | 797 | cfg80211_process_wdev_events(wdev); |
798 | 798 | ||
799 | mutex_unlock(&rdev->devlist_mtx); | 799 | mutex_unlock(&rdev->devlist_mtx); |
@@ -994,7 +994,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | |||
994 | 994 | ||
995 | mutex_lock(&rdev->devlist_mtx); | 995 | mutex_lock(&rdev->devlist_mtx); |
996 | 996 | ||
997 | list_for_each_entry(wdev, &rdev->netdev_list, list) { | 997 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
998 | if (!wdev->beacon_interval) | 998 | if (!wdev->beacon_interval) |
999 | continue; | 999 | continue; |
1000 | if (wdev->beacon_interval != beacon_int) { | 1000 | if (wdev->beacon_interval != beacon_int) { |
@@ -1050,7 +1050,7 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1050 | break; | 1050 | break; |
1051 | } | 1051 | } |
1052 | 1052 | ||
1053 | list_for_each_entry(wdev_iter, &rdev->netdev_list, list) { | 1053 | list_for_each_entry(wdev_iter, &rdev->wdev_list, list) { |
1054 | if (wdev_iter == wdev) | 1054 | if (wdev_iter == wdev) |
1055 | continue; | 1055 | continue; |
1056 | if (!netif_running(wdev_iter->netdev)) | 1056 | if (!netif_running(wdev_iter->netdev)) |
@@ -1059,7 +1059,16 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | |||
1059 | if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) | 1059 | if (rdev->wiphy.software_iftypes & BIT(wdev_iter->iftype)) |
1060 | continue; | 1060 | continue; |
1061 | 1061 | ||
1062 | cfg80211_get_chan_state(rdev, wdev_iter, &ch, &chmode); | 1062 | /* |
1063 | * We may be holding the "wdev" mutex, but now need to lock | ||
1064 | * wdev_iter. This is OK because once we get here wdev_iter | ||
1065 | * is not wdev (tested above), but we need to use the nested | ||
1066 | * locking for lockdep. | ||
1067 | */ | ||
1068 | mutex_lock_nested(&wdev_iter->mtx, 1); | ||
1069 | __acquire(wdev_iter->mtx); | ||
1070 | cfg80211_get_chan_state(wdev_iter, &ch, &chmode); | ||
1071 | wdev_unlock(wdev_iter); | ||
1063 | 1072 | ||
1064 | switch (chmode) { | 1073 | switch (chmode) { |
1065 | case CHAN_MODE_UNDEFINED: | 1074 | case CHAN_MODE_UNDEFINED: |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 7df42f541873..494379eb464f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -827,6 +827,8 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
827 | { | 827 | { |
828 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 828 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
829 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 829 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
830 | struct ieee80211_channel *chan; | ||
831 | enum nl80211_channel_type channel_type; | ||
830 | 832 | ||
831 | switch (wdev->iftype) { | 833 | switch (wdev->iftype) { |
832 | case NL80211_IFTYPE_STATION: | 834 | case NL80211_IFTYPE_STATION: |
@@ -834,10 +836,13 @@ static int cfg80211_wext_giwfreq(struct net_device *dev, | |||
834 | case NL80211_IFTYPE_ADHOC: | 836 | case NL80211_IFTYPE_ADHOC: |
835 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); | 837 | return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); |
836 | case NL80211_IFTYPE_MONITOR: | 838 | case NL80211_IFTYPE_MONITOR: |
837 | if (!rdev->monitor_channel) | 839 | if (!rdev->ops->get_channel) |
838 | return -EINVAL; | 840 | return -EINVAL; |
839 | 841 | ||
840 | freq->m = rdev->monitor_channel->center_freq; | 842 | chan = rdev->ops->get_channel(wdev->wiphy, wdev, &channel_type); |
843 | if (!chan) | ||
844 | return -EINVAL; | ||
845 | freq->m = chan->center_freq; | ||
841 | freq->e = 6; | 846 | freq->e = 6; |
842 | return 0; | 847 | return 0; |
843 | default: | 848 | default: |