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: |
