diff options
| author | John W. Linville <linville@tuxdriver.com> | 2011-06-08 13:44:21 -0400 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2011-06-08 13:44:21 -0400 |
| commit | c0c33addcba2ce753b4e2746db99feaae2f82a85 (patch) | |
| tree | dab480183ac0e64bfe9250e1f294705d1a424c78 | |
| parent | ffbc03bc75b39c7bd412e7cc6d2185c11b0ffedd (diff) | |
| parent | 931749bf78b969c54de9bbc67cf29b13a40bb73b (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
133 files changed, 3173 insertions, 1293 deletions
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig index 353781b5b78b..83e9adf46441 100644 --- a/drivers/bcma/Kconfig +++ b/drivers/bcma/Kconfig | |||
| @@ -13,6 +13,11 @@ config BCMA | |||
| 13 | Bus driver for Broadcom specific Advanced Microcontroller Bus | 13 | Bus driver for Broadcom specific Advanced Microcontroller Bus |
| 14 | Architecture. | 14 | Architecture. |
| 15 | 15 | ||
| 16 | # Support for Block-I/O. SELECT this from the driver that needs it. | ||
| 17 | config BCMA_BLOCKIO | ||
| 18 | bool | ||
| 19 | depends on BCMA | ||
| 20 | |||
| 16 | config BCMA_HOST_PCI_POSSIBLE | 21 | config BCMA_HOST_PCI_POSSIBLE |
| 17 | bool | 22 | bool |
| 18 | depends on BCMA && PCI = y | 23 | depends on BCMA && PCI = y |
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile index 0d56245bcb79..cde0182bd1dc 100644 --- a/drivers/bcma/Makefile +++ b/drivers/bcma/Makefile | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | bcma-y += main.o scan.o core.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-y += driver_pci.o | 3 | bcma-y += driver_pci.o |
| 4 | bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o | 4 | bcma-$(CONFIG_BCMA_HOST_PCI) += host_pci.o |
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 2f72e9c585fd..12a75ab3dd23 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
| @@ -19,6 +19,9 @@ extern void bcma_bus_unregister(struct bcma_bus *bus); | |||
| 19 | /* scan.c */ | 19 | /* scan.c */ |
| 20 | int bcma_bus_scan(struct bcma_bus *bus); | 20 | int bcma_bus_scan(struct bcma_bus *bus); |
| 21 | 21 | ||
| 22 | /* sprom.c */ | ||
| 23 | int bcma_sprom_get(struct bcma_bus *bus); | ||
| 24 | |||
| 22 | #ifdef CONFIG_BCMA_HOST_PCI | 25 | #ifdef CONFIG_BCMA_HOST_PCI |
| 23 | /* host_pci.c */ | 26 | /* host_pci.c */ |
| 24 | extern int __init bcma_host_pci_init(void); | 27 | extern int __init bcma_host_pci_init(void); |
diff --git a/drivers/bcma/driver_pci.c b/drivers/bcma/driver_pci.c index e757e4e3c7e2..789d68b4858b 100644 --- a/drivers/bcma/driver_pci.c +++ b/drivers/bcma/driver_pci.c | |||
| @@ -161,3 +161,26 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc) | |||
| 161 | { | 161 | { |
| 162 | bcma_pcicore_serdes_workaround(pc); | 162 | bcma_pcicore_serdes_workaround(pc); |
| 163 | } | 163 | } |
| 164 | |||
| 165 | int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core, | ||
| 166 | bool enable) | ||
| 167 | { | ||
| 168 | struct pci_dev *pdev = pc->core->bus->host_pci; | ||
| 169 | u32 coremask, tmp; | ||
| 170 | int err; | ||
| 171 | |||
| 172 | err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp); | ||
| 173 | if (err) | ||
| 174 | goto out; | ||
| 175 | |||
| 176 | coremask = BIT(core->core_index) << 8; | ||
| 177 | if (enable) | ||
| 178 | tmp |= coremask; | ||
| 179 | else | ||
| 180 | tmp &= ~coremask; | ||
| 181 | |||
| 182 | err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp); | ||
| 183 | |||
| 184 | out: | ||
| 185 | return err; | ||
| 186 | } | ||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index 471a04013fe0..2a526bc3342f 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
| @@ -65,6 +65,54 @@ static void bcma_host_pci_write32(struct bcma_device *core, u16 offset, | |||
| 65 | iowrite32(value, core->bus->mmio + offset); | 65 | iowrite32(value, core->bus->mmio + offset); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | #ifdef CONFIG_BCMA_BLOCKIO | ||
| 69 | void bcma_host_pci_block_read(struct bcma_device *core, void *buffer, | ||
| 70 | size_t count, u16 offset, u8 reg_width) | ||
| 71 | { | ||
| 72 | void __iomem *addr = core->bus->mmio + offset; | ||
| 73 | if (core->bus->mapped_core != core) | ||
| 74 | bcma_host_pci_switch_core(core); | ||
| 75 | switch (reg_width) { | ||
| 76 | case sizeof(u8): | ||
| 77 | ioread8_rep(addr, buffer, count); | ||
| 78 | break; | ||
| 79 | case sizeof(u16): | ||
| 80 | WARN_ON(count & 1); | ||
| 81 | ioread16_rep(addr, buffer, count >> 1); | ||
| 82 | break; | ||
| 83 | case sizeof(u32): | ||
| 84 | WARN_ON(count & 3); | ||
| 85 | ioread32_rep(addr, buffer, count >> 2); | ||
| 86 | break; | ||
| 87 | default: | ||
| 88 | WARN_ON(1); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer, | ||
| 93 | size_t count, u16 offset, u8 reg_width) | ||
| 94 | { | ||
| 95 | void __iomem *addr = core->bus->mmio + offset; | ||
| 96 | if (core->bus->mapped_core != core) | ||
| 97 | bcma_host_pci_switch_core(core); | ||
| 98 | switch (reg_width) { | ||
| 99 | case sizeof(u8): | ||
| 100 | iowrite8_rep(addr, buffer, count); | ||
| 101 | break; | ||
| 102 | case sizeof(u16): | ||
| 103 | WARN_ON(count & 1); | ||
| 104 | iowrite16_rep(addr, buffer, count >> 1); | ||
| 105 | break; | ||
| 106 | case sizeof(u32): | ||
| 107 | WARN_ON(count & 3); | ||
| 108 | iowrite32_rep(addr, buffer, count >> 2); | ||
| 109 | break; | ||
| 110 | default: | ||
| 111 | WARN_ON(1); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | #endif | ||
| 115 | |||
| 68 | static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) | 116 | static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset) |
| 69 | { | 117 | { |
| 70 | if (core->bus->mapped_core != core) | 118 | if (core->bus->mapped_core != core) |
| @@ -87,6 +135,10 @@ const struct bcma_host_ops bcma_host_pci_ops = { | |||
| 87 | .write8 = bcma_host_pci_write8, | 135 | .write8 = bcma_host_pci_write8, |
| 88 | .write16 = bcma_host_pci_write16, | 136 | .write16 = bcma_host_pci_write16, |
| 89 | .write32 = bcma_host_pci_write32, | 137 | .write32 = bcma_host_pci_write32, |
| 138 | #ifdef CONFIG_BCMA_BLOCKIO | ||
| 139 | .block_read = bcma_host_pci_block_read, | ||
| 140 | .block_write = bcma_host_pci_block_write, | ||
| 141 | #endif | ||
| 90 | .aread32 = bcma_host_pci_aread32, | 142 | .aread32 = bcma_host_pci_aread32, |
| 91 | .awrite32 = bcma_host_pci_awrite32, | 143 | .awrite32 = bcma_host_pci_awrite32, |
| 92 | }; | 144 | }; |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index be52344ed19d..11e96dc6011a 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
| @@ -89,6 +89,8 @@ static int bcma_register_cores(struct bcma_bus *bus) | |||
| 89 | switch (bus->hosttype) { | 89 | switch (bus->hosttype) { |
| 90 | case BCMA_HOSTTYPE_PCI: | 90 | case BCMA_HOSTTYPE_PCI: |
| 91 | core->dev.parent = &bus->host_pci->dev; | 91 | core->dev.parent = &bus->host_pci->dev; |
| 92 | core->dma_dev = &bus->host_pci->dev; | ||
| 93 | core->irq = bus->host_pci->irq; | ||
| 92 | break; | 94 | break; |
| 93 | case BCMA_HOSTTYPE_NONE: | 95 | case BCMA_HOSTTYPE_NONE: |
| 94 | case BCMA_HOSTTYPE_SDIO: | 96 | case BCMA_HOSTTYPE_SDIO: |
| @@ -144,6 +146,13 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
| 144 | bcma_core_pci_init(&bus->drv_pci); | 146 | bcma_core_pci_init(&bus->drv_pci); |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 149 | /* Try to get SPROM */ | ||
| 150 | err = bcma_sprom_get(bus); | ||
| 151 | if (err) { | ||
| 152 | pr_err("Failed to get SPROM: %d\n", err); | ||
| 153 | return -ENOENT; | ||
| 154 | } | ||
| 155 | |||
| 147 | /* Register found cores */ | 156 | /* Register found cores */ |
| 148 | bcma_register_cores(bus); | 157 | bcma_register_cores(bus); |
| 149 | 158 | ||
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c new file mode 100644 index 000000000000..ffbb0e32e921 --- /dev/null +++ b/drivers/bcma/sprom.c | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | /* | ||
| 2 | * Broadcom specific AMBA | ||
| 3 | * SPROM reading | ||
| 4 | * | ||
| 5 | * Licensed under the GNU/GPL. See COPYING for details. | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include "bcma_private.h" | ||
| 9 | |||
| 10 | #include <linux/bcma/bcma.h> | ||
| 11 | #include <linux/bcma/bcma_regs.h> | ||
| 12 | #include <linux/pci.h> | ||
| 13 | #include <linux/io.h> | ||
| 14 | #include <linux/dma-mapping.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | |||
| 17 | #define SPOFF(offset) ((offset) / sizeof(u16)) | ||
| 18 | |||
| 19 | /************************************************** | ||
| 20 | * R/W ops. | ||
| 21 | **************************************************/ | ||
| 22 | |||
| 23 | static void bcma_sprom_read(struct bcma_bus *bus, u16 *sprom) | ||
| 24 | { | ||
| 25 | int i; | ||
| 26 | for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++) | ||
| 27 | sprom[i] = bcma_read16(bus->drv_cc.core, | ||
| 28 | BCMA_CC_SPROM + (i * 2)); | ||
| 29 | } | ||
| 30 | |||
| 31 | /************************************************** | ||
| 32 | * Validation. | ||
| 33 | **************************************************/ | ||
| 34 | |||
| 35 | static inline u8 bcma_crc8(u8 crc, u8 data) | ||
| 36 | { | ||
| 37 | /* Polynomial: x^8 + x^7 + x^6 + x^4 + x^2 + 1 */ | ||
| 38 | static const u8 t[] = { | ||
| 39 | 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, | ||
| 40 | 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, | ||
| 41 | 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, | ||
| 42 | 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, | ||
| 43 | 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, | ||
| 44 | 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, | ||
| 45 | 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, | ||
| 46 | 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, | ||
| 47 | 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, | ||
| 48 | 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, | ||
| 49 | 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, | ||
| 50 | 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, | ||
| 51 | 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, | ||
| 52 | 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, | ||
| 53 | 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, | ||
| 54 | 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, | ||
| 55 | 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, | ||
| 56 | 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, | ||
| 57 | 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, | ||
| 58 | 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, | ||
| 59 | 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, | ||
| 60 | 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, | ||
| 61 | 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, | ||
| 62 | 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, | ||
| 63 | 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, | ||
| 64 | 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, | ||
| 65 | 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, | ||
| 66 | 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, | ||
| 67 | 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, | ||
| 68 | 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, | ||
| 69 | 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, | ||
| 70 | 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F, | ||
| 71 | }; | ||
| 72 | return t[crc ^ data]; | ||
| 73 | } | ||
| 74 | |||
| 75 | static u8 bcma_sprom_crc(const u16 *sprom) | ||
| 76 | { | ||
| 77 | int word; | ||
| 78 | u8 crc = 0xFF; | ||
| 79 | |||
| 80 | for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) { | ||
| 81 | crc = bcma_crc8(crc, sprom[word] & 0x00FF); | ||
| 82 | crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8); | ||
| 83 | } | ||
| 84 | crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF); | ||
| 85 | crc ^= 0xFF; | ||
| 86 | |||
| 87 | return crc; | ||
| 88 | } | ||
| 89 | |||
| 90 | static int bcma_sprom_check_crc(const u16 *sprom) | ||
| 91 | { | ||
| 92 | u8 crc; | ||
| 93 | u8 expected_crc; | ||
| 94 | u16 tmp; | ||
| 95 | |||
| 96 | crc = bcma_sprom_crc(sprom); | ||
| 97 | tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC; | ||
| 98 | expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT; | ||
| 99 | if (crc != expected_crc) | ||
| 100 | return -EPROTO; | ||
| 101 | |||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | static int bcma_sprom_valid(const u16 *sprom) | ||
| 106 | { | ||
| 107 | u16 revision; | ||
| 108 | int err; | ||
| 109 | |||
| 110 | err = bcma_sprom_check_crc(sprom); | ||
| 111 | if (err) | ||
| 112 | return err; | ||
| 113 | |||
| 114 | revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; | ||
| 115 | if (revision != 8) { | ||
| 116 | pr_err("Unsupported SPROM revision: %d\n", revision); | ||
| 117 | return -ENOENT; | ||
| 118 | } | ||
| 119 | |||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | |||
| 123 | /************************************************** | ||
| 124 | * SPROM extraction. | ||
| 125 | **************************************************/ | ||
| 126 | |||
| 127 | static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) | ||
| 128 | { | ||
| 129 | u16 v; | ||
| 130 | int i; | ||
| 131 | |||
| 132 | for (i = 0; i < 3; i++) { | ||
| 133 | v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i]; | ||
| 134 | *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | int bcma_sprom_get(struct bcma_bus *bus) | ||
| 139 | { | ||
| 140 | u16 *sprom; | ||
| 141 | int err = 0; | ||
| 142 | |||
| 143 | if (!bus->drv_cc.core) | ||
| 144 | return -EOPNOTSUPP; | ||
| 145 | |||
| 146 | sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16), | ||
| 147 | GFP_KERNEL); | ||
| 148 | if (!sprom) | ||
| 149 | return -ENOMEM; | ||
| 150 | |||
| 151 | bcma_sprom_read(bus, sprom); | ||
| 152 | |||
| 153 | err = bcma_sprom_valid(sprom); | ||
| 154 | if (err) | ||
| 155 | goto out; | ||
| 156 | |||
| 157 | bcma_sprom_extract_r8(bus, sprom); | ||
| 158 | |||
| 159 | out: | ||
| 160 | kfree(sprom); | ||
| 161 | return err; | ||
| 162 | } | ||
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 7cf4317a2a84..17c4b56c3874 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
| @@ -161,6 +161,7 @@ struct ath_common { | |||
| 161 | const struct ath_bus_ops *bus_ops; | 161 | const struct ath_bus_ops *bus_ops; |
| 162 | 162 | ||
| 163 | bool btcoex_enabled; | 163 | bool btcoex_enabled; |
| 164 | bool disable_ani; | ||
| 164 | }; | 165 | }; |
| 165 | 166 | ||
| 166 | struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, | 167 | struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 22047628ccfa..b6c5d3715b96 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
| @@ -72,6 +72,11 @@ static int modparam_all_channels; | |||
| 72 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); | 72 | module_param_named(all_channels, modparam_all_channels, bool, S_IRUGO); |
| 73 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); | 73 | MODULE_PARM_DESC(all_channels, "Expose all channels the device can use."); |
| 74 | 74 | ||
| 75 | static int modparam_fastchanswitch; | ||
| 76 | module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); | ||
| 77 | MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); | ||
| 78 | |||
| 79 | |||
| 75 | /* Module info */ | 80 | /* Module info */ |
| 76 | MODULE_AUTHOR("Jiri Slaby"); | 81 | MODULE_AUTHOR("Jiri Slaby"); |
| 77 | MODULE_AUTHOR("Nick Kossifidis"); | 82 | MODULE_AUTHOR("Nick Kossifidis"); |
| @@ -2686,6 +2691,7 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | |||
| 2686 | struct ath5k_hw *ah = sc->ah; | 2691 | struct ath5k_hw *ah = sc->ah; |
| 2687 | struct ath_common *common = ath5k_hw_common(ah); | 2692 | struct ath_common *common = ath5k_hw_common(ah); |
| 2688 | int ret, ani_mode; | 2693 | int ret, ani_mode; |
| 2694 | bool fast; | ||
| 2689 | 2695 | ||
| 2690 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2696 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
| 2691 | 2697 | ||
| @@ -2705,7 +2711,10 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan, | |||
| 2705 | ath5k_drain_tx_buffs(sc); | 2711 | ath5k_drain_tx_buffs(sc); |
| 2706 | if (chan) | 2712 | if (chan) |
| 2707 | sc->curchan = chan; | 2713 | sc->curchan = chan; |
| 2708 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, chan != NULL, | 2714 | |
| 2715 | fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; | ||
| 2716 | |||
| 2717 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, fast, | ||
| 2709 | skip_pcu); | 2718 | skip_pcu); |
| 2710 | if (ret) { | 2719 | if (ret) { |
| 2711 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); | 2720 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index 3510de2cf622..126a4eab35f3 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
| @@ -1124,8 +1124,11 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
| 1124 | /* Non fatal, can happen eg. | 1124 | /* Non fatal, can happen eg. |
| 1125 | * on mode change */ | 1125 | * on mode change */ |
| 1126 | ret = 0; | 1126 | ret = 0; |
| 1127 | } else | 1127 | } else { |
| 1128 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET, | ||
| 1129 | "fast chan change successful\n"); | ||
| 1128 | return 0; | 1130 | return 0; |
| 1131 | } | ||
| 1129 | } | 1132 | } |
| 1130 | 1133 | ||
| 1131 | /* | 1134 | /* |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 077e8a6983fa..45b262fe2c25 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
| @@ -28,11 +28,6 @@ static void ar9002_hw_set_desc_link(void *ds, u32 ds_link) | |||
| 28 | ((struct ath_desc*) ds)->ds_link = ds_link; | 28 | ((struct ath_desc*) ds)->ds_link = ds_link; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link) | ||
| 32 | { | ||
| 33 | *ds_link = &((struct ath_desc *)ds)->ds_link; | ||
| 34 | } | ||
| 35 | |||
| 36 | static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | 31 | static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) |
| 37 | { | 32 | { |
| 38 | u32 isr = 0; | 33 | u32 isr = 0; |
| @@ -437,7 +432,6 @@ void ar9002_hw_attach_mac_ops(struct ath_hw *ah) | |||
| 437 | 432 | ||
| 438 | ops->rx_enable = ar9002_hw_rx_enable; | 433 | ops->rx_enable = ar9002_hw_rx_enable; |
| 439 | ops->set_desc_link = ar9002_hw_set_desc_link; | 434 | ops->set_desc_link = ar9002_hw_set_desc_link; |
| 440 | ops->get_desc_link = ar9002_hw_get_desc_link; | ||
| 441 | ops->get_isr = ar9002_hw_get_isr; | 435 | ops->get_isr = ar9002_hw_get_isr; |
| 442 | ops->fill_txdesc = ar9002_hw_fill_txdesc; | 436 | ops->fill_txdesc = ar9002_hw_fill_txdesc; |
| 443 | ops->proc_txdesc = ar9002_hw_proc_txdesc; | 437 | ops->proc_txdesc = ar9002_hw_proc_txdesc; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 10d71f7d3fc2..04e6be04acf9 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
| @@ -43,13 +43,6 @@ static void ar9003_hw_set_desc_link(void *ds, u32 ds_link) | |||
| 43 | ads->ctl10 |= ar9003_calc_ptr_chksum(ads); | 43 | ads->ctl10 |= ar9003_calc_ptr_chksum(ads); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link) | ||
| 47 | { | ||
| 48 | struct ar9003_txc *ads = ds; | ||
| 49 | |||
| 50 | *ds_link = &ads->link; | ||
| 51 | } | ||
| 52 | |||
| 53 | static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | 46 | static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) |
| 54 | { | 47 | { |
| 55 | u32 isr = 0; | 48 | u32 isr = 0; |
| @@ -498,7 +491,6 @@ void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | |||
| 498 | 491 | ||
| 499 | ops->rx_enable = ar9003_hw_rx_enable; | 492 | ops->rx_enable = ar9003_hw_rx_enable; |
| 500 | ops->set_desc_link = ar9003_hw_set_desc_link; | 493 | ops->set_desc_link = ar9003_hw_set_desc_link; |
| 501 | ops->get_desc_link = ar9003_hw_get_desc_link; | ||
| 502 | ops->get_isr = ar9003_hw_get_isr; | 494 | ops->get_isr = ar9003_hw_get_isr; |
| 503 | ops->fill_txdesc = ar9003_hw_fill_txdesc; | 495 | ops->fill_txdesc = ar9003_hw_fill_txdesc; |
| 504 | ops->proc_txdesc = ar9003_hw_proc_txdesc; | 496 | ops->proc_txdesc = ar9003_hw_proc_txdesc; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index e4d6a87ec538..2e7f0f2567eb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c | |||
| @@ -46,11 +46,10 @@ EXPORT_SYMBOL(ar9003_paprd_enable); | |||
| 46 | 46 | ||
| 47 | static int ar9003_get_training_power_2g(struct ath_hw *ah) | 47 | static int ar9003_get_training_power_2g(struct ath_hw *ah) |
| 48 | { | 48 | { |
| 49 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | 49 | struct ath9k_channel *chan = ah->curchan; |
| 50 | struct ar9300_modal_eep_header *hdr = &eep->modalHeader2G; | ||
| 51 | unsigned int power, scale, delta; | 50 | unsigned int power, scale, delta; |
| 52 | 51 | ||
| 53 | scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), AR9300_PAPRD_SCALE_1); | 52 | scale = ar9003_get_paprd_scale_factor(ah, chan); |
| 54 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, | 53 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, |
| 55 | AR_PHY_POWERTX_RATE5_POWERTXHT20_0); | 54 | AR_PHY_POWERTX_RATE5_POWERTXHT20_0); |
| 56 | 55 | ||
| @@ -67,20 +66,10 @@ static int ar9003_get_training_power_2g(struct ath_hw *ah) | |||
| 67 | static int ar9003_get_training_power_5g(struct ath_hw *ah) | 66 | static int ar9003_get_training_power_5g(struct ath_hw *ah) |
| 68 | { | 67 | { |
| 69 | struct ath_common *common = ath9k_hw_common(ah); | 68 | struct ath_common *common = ath9k_hw_common(ah); |
| 70 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
| 71 | struct ar9300_modal_eep_header *hdr = &eep->modalHeader5G; | ||
| 72 | struct ath9k_channel *chan = ah->curchan; | 69 | struct ath9k_channel *chan = ah->curchan; |
| 73 | unsigned int power, scale, delta; | 70 | unsigned int power, scale, delta; |
| 74 | 71 | ||
| 75 | if (chan->channel >= 5700) | 72 | scale = ar9003_get_paprd_scale_factor(ah, chan); |
| 76 | scale = MS(le32_to_cpu(hdr->papdRateMaskHt20), | ||
| 77 | AR9300_PAPRD_SCALE_1); | ||
| 78 | else if (chan->channel >= 5400) | ||
| 79 | scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), | ||
| 80 | AR9300_PAPRD_SCALE_2); | ||
| 81 | else | ||
| 82 | scale = MS(le32_to_cpu(hdr->papdRateMaskHt40), | ||
| 83 | AR9300_PAPRD_SCALE_1); | ||
| 84 | 73 | ||
| 85 | if (IS_CHAN_HT40(chan)) | 74 | if (IS_CHAN_HT40(chan)) |
| 86 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8, | 75 | power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE8, |
| @@ -119,15 +108,16 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) | |||
| 119 | else | 108 | else |
| 120 | training_power = ar9003_get_training_power_5g(ah); | 109 | training_power = ar9003_get_training_power_5g(ah); |
| 121 | 110 | ||
| 111 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
| 112 | "Training power: %d, Target power: %d\n", | ||
| 113 | training_power, ah->paprd_target_power); | ||
| 114 | |||
| 122 | if (training_power < 0) { | 115 | if (training_power < 0) { |
| 123 | ath_dbg(common, ATH_DBG_CALIBRATE, | 116 | ath_dbg(common, ATH_DBG_CALIBRATE, |
| 124 | "PAPRD target power delta out of range"); | 117 | "PAPRD target power delta out of range"); |
| 125 | return -ERANGE; | 118 | return -ERANGE; |
| 126 | } | 119 | } |
| 127 | ah->paprd_training_power = training_power; | 120 | ah->paprd_training_power = training_power; |
| 128 | ath_dbg(common, ATH_DBG_CALIBRATE, | ||
| 129 | "Training power: %d, Target power: %d\n", | ||
| 130 | ah->paprd_training_power, ah->paprd_target_power); | ||
| 131 | 121 | ||
| 132 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, | 122 | REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, |
| 133 | ah->paprd_ratemask); | 123 | ah->paprd_ratemask); |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index e99dfe6065bf..57933db57633 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
| @@ -180,7 +180,7 @@ enum ATH_AGGR_STATUS { | |||
| 180 | struct ath_txq { | 180 | struct ath_txq { |
| 181 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ | 181 | int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */ |
| 182 | u32 axq_qnum; /* ath9k hardware queue number */ | 182 | u32 axq_qnum; /* ath9k hardware queue number */ |
| 183 | u32 *axq_link; | 183 | void *axq_link; |
| 184 | struct list_head axq_q; | 184 | struct list_head axq_q; |
| 185 | spinlock_t axq_lock; | 185 | spinlock_t axq_lock; |
| 186 | u32 axq_depth; | 186 | u32 axq_depth; |
| @@ -189,7 +189,6 @@ struct ath_txq { | |||
| 189 | bool axq_tx_inprogress; | 189 | bool axq_tx_inprogress; |
| 190 | struct list_head axq_acq; | 190 | struct list_head axq_acq; |
| 191 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; | 191 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; |
| 192 | struct list_head txq_fifo_pending; | ||
| 193 | u8 txq_headidx; | 192 | u8 txq_headidx; |
| 194 | u8 txq_tailidx; | 193 | u8 txq_tailidx; |
| 195 | int pending_frames; | 194 | int pending_frames; |
| @@ -429,6 +428,7 @@ void ath_hw_check(struct work_struct *work); | |||
| 429 | void ath_hw_pll_work(struct work_struct *work); | 428 | void ath_hw_pll_work(struct work_struct *work); |
| 430 | void ath_paprd_calibrate(struct work_struct *work); | 429 | void ath_paprd_calibrate(struct work_struct *work); |
| 431 | void ath_ani_calibrate(unsigned long data); | 430 | void ath_ani_calibrate(unsigned long data); |
| 431 | void ath_start_ani(struct ath_common *common); | ||
| 432 | 432 | ||
| 433 | /**********/ | 433 | /**********/ |
| 434 | /* BTCOEX */ | 434 | /* BTCOEX */ |
| @@ -670,12 +670,8 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 670 | const struct ath_bus_ops *bus_ops); | 670 | const struct ath_bus_ops *bus_ops); |
| 671 | void ath9k_deinit_device(struct ath_softc *sc); | 671 | void ath9k_deinit_device(struct ath_softc *sc); |
| 672 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); | 672 | void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); |
| 673 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | ||
| 674 | struct ath9k_channel *hchan); | ||
| 675 | 673 | ||
| 676 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); | ||
| 677 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); | 674 | void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); |
| 678 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode); | ||
| 679 | bool ath9k_uses_beacons(int type); | 675 | bool ath9k_uses_beacons(int type); |
| 680 | 676 | ||
| 681 | #ifdef CONFIG_ATH9K_PCI | 677 | #ifdef CONFIG_ATH9K_PCI |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index d4d8ceced89b..0174cdb65a83 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
| @@ -496,7 +496,7 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
| 496 | u32 nexttbtt, intval; | 496 | u32 nexttbtt, intval; |
| 497 | 497 | ||
| 498 | /* NB: the beacon interval is kept internally in TU's */ | 498 | /* NB: the beacon interval is kept internally in TU's */ |
| 499 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); | 499 | intval = TU_TO_USEC(conf->beacon_interval); |
| 500 | intval /= ATH_BCBUF; /* for staggered beacons */ | 500 | intval /= ATH_BCBUF; /* for staggered beacons */ |
| 501 | nexttbtt = intval; | 501 | nexttbtt = intval; |
| 502 | 502 | ||
| @@ -543,7 +543,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
| 543 | } | 543 | } |
| 544 | 544 | ||
| 545 | memset(&bs, 0, sizeof(bs)); | 545 | memset(&bs, 0, sizeof(bs)); |
| 546 | intval = conf->beacon_interval & ATH9K_BEACON_PERIOD; | 546 | intval = conf->beacon_interval; |
| 547 | 547 | ||
| 548 | /* | 548 | /* |
| 549 | * Setup dtim and cfp parameters according to | 549 | * Setup dtim and cfp parameters according to |
| @@ -652,22 +652,13 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
| 652 | { | 652 | { |
| 653 | struct ath_hw *ah = sc->sc_ah; | 653 | struct ath_hw *ah = sc->sc_ah; |
| 654 | struct ath_common *common = ath9k_hw_common(ah); | 654 | struct ath_common *common = ath9k_hw_common(ah); |
| 655 | u32 tsf, delta, intval, nexttbtt; | 655 | u32 tsf, intval, nexttbtt; |
| 656 | 656 | ||
| 657 | ath9k_reset_beacon_status(sc); | 657 | ath9k_reset_beacon_status(sc); |
| 658 | 658 | ||
| 659 | tsf = ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE); | 659 | intval = TU_TO_USEC(conf->beacon_interval); |
| 660 | intval = TU_TO_USEC(conf->beacon_interval & ATH9K_BEACON_PERIOD); | 660 | tsf = roundup(ath9k_hw_gettsf32(ah) + TU_TO_USEC(FUDGE), intval); |
| 661 | 661 | nexttbtt = tsf + intval; | |
| 662 | if (!sc->beacon.bc_tstamp) | ||
| 663 | nexttbtt = tsf + intval; | ||
| 664 | else { | ||
| 665 | if (tsf > sc->beacon.bc_tstamp) | ||
| 666 | delta = (tsf - sc->beacon.bc_tstamp); | ||
| 667 | else | ||
| 668 | delta = (tsf + 1 + (~0U - sc->beacon.bc_tstamp)); | ||
| 669 | nexttbtt = tsf + intval - (delta % intval); | ||
| 670 | } | ||
| 671 | 662 | ||
| 672 | ath_dbg(common, ATH_DBG_BEACON, | 663 | ath_dbg(common, ATH_DBG_BEACON, |
| 673 | "IBSS nexttbtt %u intval %u (%u)\n", | 664 | "IBSS nexttbtt %u intval %u (%u)\n", |
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d55ffd7d4bd2..22d3a26e684d 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
| @@ -176,6 +176,56 @@ static const struct file_operations fops_rx_chainmask = { | |||
| 176 | .llseek = default_llseek, | 176 | .llseek = default_llseek, |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | static ssize_t read_file_disable_ani(struct file *file, char __user *user_buf, | ||
| 180 | size_t count, loff_t *ppos) | ||
| 181 | { | ||
| 182 | struct ath_softc *sc = file->private_data; | ||
| 183 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
| 184 | char buf[32]; | ||
| 185 | unsigned int len; | ||
| 186 | |||
| 187 | len = sprintf(buf, "%d\n", common->disable_ani); | ||
| 188 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
| 189 | } | ||
| 190 | |||
| 191 | static ssize_t write_file_disable_ani(struct file *file, | ||
| 192 | const char __user *user_buf, | ||
| 193 | size_t count, loff_t *ppos) | ||
| 194 | { | ||
| 195 | struct ath_softc *sc = file->private_data; | ||
| 196 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
| 197 | unsigned long disable_ani; | ||
| 198 | char buf[32]; | ||
| 199 | ssize_t len; | ||
| 200 | |||
| 201 | len = min(count, sizeof(buf) - 1); | ||
| 202 | if (copy_from_user(buf, user_buf, len)) | ||
| 203 | return -EFAULT; | ||
| 204 | |||
| 205 | buf[len] = '\0'; | ||
| 206 | if (strict_strtoul(buf, 0, &disable_ani)) | ||
| 207 | return -EINVAL; | ||
| 208 | |||
| 209 | common->disable_ani = !!disable_ani; | ||
| 210 | |||
| 211 | if (disable_ani) { | ||
| 212 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
| 213 | del_timer_sync(&common->ani.timer); | ||
| 214 | } else { | ||
| 215 | sc->sc_flags |= SC_OP_ANI_RUN; | ||
| 216 | ath_start_ani(common); | ||
| 217 | } | ||
| 218 | |||
| 219 | return count; | ||
| 220 | } | ||
| 221 | |||
| 222 | static const struct file_operations fops_disable_ani = { | ||
| 223 | .read = read_file_disable_ani, | ||
| 224 | .write = write_file_disable_ani, | ||
| 225 | .open = ath9k_debugfs_open, | ||
| 226 | .owner = THIS_MODULE, | ||
| 227 | .llseek = default_llseek, | ||
| 228 | }; | ||
| 179 | 229 | ||
| 180 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | 230 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, |
| 181 | size_t count, loff_t *ppos) | 231 | size_t count, loff_t *ppos) |
| @@ -550,6 +600,7 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
| 550 | 600 | ||
| 551 | PR("MPDUs Queued: ", queued); | 601 | PR("MPDUs Queued: ", queued); |
| 552 | PR("MPDUs Completed: ", completed); | 602 | PR("MPDUs Completed: ", completed); |
| 603 | PR("MPDUs XRetried: ", xretries); | ||
| 553 | PR("Aggregates: ", a_aggr); | 604 | PR("Aggregates: ", a_aggr); |
| 554 | PR("AMPDUs Queued HW:", a_queued_hw); | 605 | PR("AMPDUs Queued HW:", a_queued_hw); |
| 555 | PR("AMPDUs Queued SW:", a_queued_sw); | 606 | PR("AMPDUs Queued SW:", a_queued_sw); |
| @@ -587,7 +638,6 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
| 587 | 638 | ||
| 588 | PRQLE("axq_q empty: ", axq_q); | 639 | PRQLE("axq_q empty: ", axq_q); |
| 589 | PRQLE("axq_acq empty: ", axq_acq); | 640 | PRQLE("axq_acq empty: ", axq_acq); |
| 590 | PRQLE("txq_fifo_pending: ", txq_fifo_pending); | ||
| 591 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { | 641 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) { |
| 592 | snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); | 642 | snprintf(tmp, sizeof(tmp) - 1, "txq_fifo[%i] empty: ", i); |
| 593 | PRQLE(tmp, txq_fifo[i]); | 643 | PRQLE(tmp, txq_fifo[i]); |
| @@ -807,7 +857,10 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_buf *bf, | |||
| 807 | else | 857 | else |
| 808 | TX_STAT_INC(qnum, a_completed); | 858 | TX_STAT_INC(qnum, a_completed); |
| 809 | } else { | 859 | } else { |
| 810 | TX_STAT_INC(qnum, completed); | 860 | if (bf_isxretried(bf)) |
| 861 | TX_STAT_INC(qnum, xretries); | ||
| 862 | else | ||
| 863 | TX_STAT_INC(qnum, completed); | ||
| 811 | } | 864 | } |
| 812 | 865 | ||
| 813 | if (ts->ts_status & ATH9K_TXERR_FIFO) | 866 | if (ts->ts_status & ATH9K_TXERR_FIFO) |
| @@ -1160,6 +1213,8 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
| 1160 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask); | 1213 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask); |
| 1161 | debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, | 1214 | debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, |
| 1162 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask); | 1215 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask); |
| 1216 | debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, | ||
| 1217 | sc->debug.debugfs_phy, sc, &fops_disable_ani); | ||
| 1163 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1218 | debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
| 1164 | sc, &fops_regidx); | 1219 | sc, &fops_regidx); |
| 1165 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | 1220 | debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 8ce6ad80f4e2..4a04510e1111 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
| @@ -116,6 +116,7 @@ struct ath_tx_stats { | |||
| 116 | u32 tx_bytes_all; | 116 | u32 tx_bytes_all; |
| 117 | u32 queued; | 117 | u32 queued; |
| 118 | u32 completed; | 118 | u32 completed; |
| 119 | u32 xretries; | ||
| 119 | u32 a_aggr; | 120 | u32 a_aggr; |
| 120 | u32 a_queued_hw; | 121 | u32 a_queued_hw; |
| 121 | u32 a_queued_sw; | 122 | u32 a_queued_sw; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index aa6a73118706..57fe22b24247 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
| @@ -79,7 +79,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | |||
| 79 | 79 | ||
| 80 | memset(&bs, 0, sizeof(bs)); | 80 | memset(&bs, 0, sizeof(bs)); |
| 81 | 81 | ||
| 82 | intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; | 82 | intval = bss_conf->beacon_interval; |
| 83 | bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); | 83 | bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); |
| 84 | 84 | ||
| 85 | /* | 85 | /* |
| @@ -194,7 +194,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
| 194 | u8 cmd_rsp; | 194 | u8 cmd_rsp; |
| 195 | u64 tsf; | 195 | u64 tsf; |
| 196 | 196 | ||
| 197 | intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; | 197 | intval = bss_conf->beacon_interval; |
| 198 | intval /= ATH9K_HTC_MAX_BCN_VIF; | 198 | intval /= ATH9K_HTC_MAX_BCN_VIF; |
| 199 | nexttbtt = intval; | 199 | nexttbtt = intval; |
| 200 | 200 | ||
| @@ -250,7 +250,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
| 250 | u8 cmd_rsp; | 250 | u8 cmd_rsp; |
| 251 | u64 tsf; | 251 | u64 tsf; |
| 252 | 252 | ||
| 253 | intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; | 253 | intval = bss_conf->beacon_interval; |
| 254 | nexttbtt = intval; | 254 | nexttbtt = intval; |
| 255 | 255 | ||
| 256 | /* | 256 | /* |
| @@ -427,7 +427,7 @@ static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv, | |||
| 427 | u16 intval; | 427 | u16 intval; |
| 428 | int slot; | 428 | int slot; |
| 429 | 429 | ||
| 430 | intval = priv->cur_beacon_conf.beacon_interval & ATH9K_BEACON_PERIOD; | 430 | intval = priv->cur_beacon_conf.beacon_interval; |
| 431 | 431 | ||
| 432 | tsf = be64_to_cpu(swba->tsf); | 432 | tsf = be64_to_cpu(swba->tsf); |
| 433 | tsftu = TSF_TO_TU(tsf >> 32, tsf); | 433 | tsftu = TSF_TO_TU(tsf >> 32, tsf); |
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 2f3e07263fcb..cb29e8875386 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
| @@ -39,11 +39,6 @@ static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds, | |||
| 39 | ath9k_hw_ops(ah)->set_desc_link(ds, link); | 39 | ath9k_hw_ops(ah)->set_desc_link(ds, link); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds, | ||
| 43 | u32 **link) | ||
| 44 | { | ||
| 45 | ath9k_hw_ops(ah)->get_desc_link(ds, link); | ||
| 46 | } | ||
| 47 | static inline bool ath9k_hw_calibrate(struct ath_hw *ah, | 42 | static inline bool ath9k_hw_calibrate(struct ath_hw *ah, |
| 48 | struct ath9k_channel *chan, | 43 | struct ath9k_channel *chan, |
| 49 | u8 rxchainmask, | 44 | u8 rxchainmask, |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 1be7c8bbef84..6de2655e07dd 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
| @@ -1785,16 +1785,16 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
| 1785 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); | 1785 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); |
| 1786 | 1786 | ||
| 1787 | REG_WRITE(ah, AR_BEACON_PERIOD, | 1787 | REG_WRITE(ah, AR_BEACON_PERIOD, |
| 1788 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); | 1788 | TU_TO_USEC(bs->bs_intval)); |
| 1789 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, | 1789 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, |
| 1790 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); | 1790 | TU_TO_USEC(bs->bs_intval)); |
| 1791 | 1791 | ||
| 1792 | REGWRITE_BUFFER_FLUSH(ah); | 1792 | REGWRITE_BUFFER_FLUSH(ah); |
| 1793 | 1793 | ||
| 1794 | REG_RMW_FIELD(ah, AR_RSSI_THR, | 1794 | REG_RMW_FIELD(ah, AR_RSSI_THR, |
| 1795 | AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); | 1795 | AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); |
| 1796 | 1796 | ||
| 1797 | beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD; | 1797 | beaconintval = bs->bs_intval; |
| 1798 | 1798 | ||
| 1799 | if (bs->bs_sleepduration > beaconintval) | 1799 | if (bs->bs_sleepduration > beaconintval) |
| 1800 | beaconintval = bs->bs_sleepduration; | 1800 | beaconintval = bs->bs_sleepduration; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 4b157c53d1a8..6a6fb5439831 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
| @@ -403,7 +403,6 @@ struct ath9k_beacon_state { | |||
| 403 | u32 bs_nexttbtt; | 403 | u32 bs_nexttbtt; |
| 404 | u32 bs_nextdtim; | 404 | u32 bs_nextdtim; |
| 405 | u32 bs_intval; | 405 | u32 bs_intval; |
| 406 | #define ATH9K_BEACON_PERIOD 0x0000ffff | ||
| 407 | #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ | 406 | #define ATH9K_TSFOOR_THRESHOLD 0x00004240 /* 16k us */ |
| 408 | u32 bs_dtimperiod; | 407 | u32 bs_dtimperiod; |
| 409 | u16 bs_cfpperiod; | 408 | u16 bs_cfpperiod; |
| @@ -603,7 +602,6 @@ struct ath_hw_ops { | |||
| 603 | int power_off); | 602 | int power_off); |
| 604 | void (*rx_enable)(struct ath_hw *ah); | 603 | void (*rx_enable)(struct ath_hw *ah); |
| 605 | void (*set_desc_link)(void *ds, u32 link); | 604 | void (*set_desc_link)(void *ds, u32 link); |
| 606 | void (*get_desc_link)(void *ds, u32 **link); | ||
| 607 | bool (*calibrate)(struct ath_hw *ah, | 605 | bool (*calibrate)(struct ath_hw *ah, |
| 608 | struct ath9k_channel *chan, | 606 | struct ath9k_channel *chan, |
| 609 | u8 rxchainmask, | 607 | u8 rxchainmask, |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 45c585a337e9..d4b166cfdf60 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
| @@ -519,7 +519,6 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
| 519 | { | 519 | { |
| 520 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 520 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 521 | int i = 0; | 521 | int i = 0; |
| 522 | |||
| 523 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); | 522 | setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc); |
| 524 | 523 | ||
| 525 | sc->config.txpowlimit = ATH_TXPOWER_MAX; | 524 | sc->config.txpowlimit = ATH_TXPOWER_MAX; |
| @@ -585,6 +584,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 585 | common->priv = sc; | 584 | common->priv = sc; |
| 586 | common->debug_mask = ath9k_debug; | 585 | common->debug_mask = ath9k_debug; |
| 587 | common->btcoex_enabled = ath9k_btcoex_enable == 1; | 586 | common->btcoex_enabled = ath9k_btcoex_enable == 1; |
| 587 | common->disable_ani = false; | ||
| 588 | spin_lock_init(&common->cc_lock); | 588 | spin_lock_init(&common->cc_lock); |
| 589 | 589 | ||
| 590 | spin_lock_init(&sc->sc_serial_rw); | 590 | spin_lock_init(&sc->sc_serial_rw); |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 2ca351fe6d3c..7f945333e2d8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
| @@ -62,14 +62,12 @@ static bool ath9k_has_pending_frames(struct ath_softc *sc, struct ath_txq *txq) | |||
| 62 | 62 | ||
| 63 | if (txq->axq_depth || !list_empty(&txq->axq_acq)) | 63 | if (txq->axq_depth || !list_empty(&txq->axq_acq)) |
| 64 | pending = true; | 64 | pending = true; |
| 65 | else if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
| 66 | pending = !list_empty(&txq->txq_fifo_pending); | ||
| 67 | 65 | ||
| 68 | spin_unlock_bh(&txq->axq_lock); | 66 | spin_unlock_bh(&txq->axq_lock); |
| 69 | return pending; | 67 | return pending; |
| 70 | } | 68 | } |
| 71 | 69 | ||
| 72 | bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) | 70 | static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) |
| 73 | { | 71 | { |
| 74 | unsigned long flags; | 72 | unsigned long flags; |
| 75 | bool ret; | 73 | bool ret; |
| @@ -136,7 +134,7 @@ void ath9k_ps_restore(struct ath_softc *sc) | |||
| 136 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | 134 | spin_unlock_irqrestore(&sc->sc_pm_lock, flags); |
| 137 | } | 135 | } |
| 138 | 136 | ||
| 139 | static void ath_start_ani(struct ath_common *common) | 137 | void ath_start_ani(struct ath_common *common) |
| 140 | { | 138 | { |
| 141 | struct ath_hw *ah = common->ah; | 139 | struct ath_hw *ah = common->ah; |
| 142 | unsigned long timestamp = jiffies_to_msecs(jiffies); | 140 | unsigned long timestamp = jiffies_to_msecs(jiffies); |
| @@ -219,7 +217,7 @@ static int ath_update_survey_stats(struct ath_softc *sc) | |||
| 219 | * by reseting the chip. To accomplish this we must first cleanup any pending | 217 | * by reseting the chip. To accomplish this we must first cleanup any pending |
| 220 | * DMA, then restart stuff. | 218 | * DMA, then restart stuff. |
| 221 | */ | 219 | */ |
| 222 | int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | 220 | static int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, |
| 223 | struct ath9k_channel *hchan) | 221 | struct ath9k_channel *hchan) |
| 224 | { | 222 | { |
| 225 | struct ath_hw *ah = sc->sc_ah; | 223 | struct ath_hw *ah = sc->sc_ah; |
| @@ -302,7 +300,8 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
| 302 | ath_set_beacon(sc); | 300 | ath_set_beacon(sc); |
| 303 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); | 301 | ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); |
| 304 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); | 302 | ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/2); |
| 305 | ath_start_ani(common); | 303 | if (!common->disable_ani) |
| 304 | ath_start_ani(common); | ||
| 306 | } | 305 | } |
| 307 | 306 | ||
| 308 | ps_restore: | 307 | ps_restore: |
| @@ -394,12 +393,14 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 394 | if (!caldata) | 393 | if (!caldata) |
| 395 | return; | 394 | return; |
| 396 | 395 | ||
| 396 | ath9k_ps_wakeup(sc); | ||
| 397 | |||
| 397 | if (ar9003_paprd_init_table(ah) < 0) | 398 | if (ar9003_paprd_init_table(ah) < 0) |
| 398 | return; | 399 | goto fail_paprd; |
| 399 | 400 | ||
| 400 | skb = alloc_skb(len, GFP_KERNEL); | 401 | skb = alloc_skb(len, GFP_KERNEL); |
| 401 | if (!skb) | 402 | if (!skb) |
| 402 | return; | 403 | goto fail_paprd; |
| 403 | 404 | ||
| 404 | skb_put(skb, len); | 405 | skb_put(skb, len); |
| 405 | memset(skb->data, 0, len); | 406 | memset(skb->data, 0, len); |
| @@ -411,7 +412,6 @@ void ath_paprd_calibrate(struct work_struct *work) | |||
| 411 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); | 412 | memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); |
| 412 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); | 413 | memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); |
| 413 | 414 | ||
| 414 | ath9k_ps_wakeup(sc); | ||
| 415 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | 415 | for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { |
| 416 | if (!(common->tx_chainmask & BIT(chain))) | 416 | if (!(common->tx_chainmask & BIT(chain))) |
| 417 | continue; | 417 | continue; |
| @@ -515,24 +515,19 @@ void ath_ani_calibrate(unsigned long data) | |||
| 515 | common->ani.checkani_timer = timestamp; | 515 | common->ani.checkani_timer = timestamp; |
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | /* Skip all processing if there's nothing to do. */ | 518 | /* Call ANI routine if necessary */ |
| 519 | if (longcal || shortcal || aniflag) { | 519 | if (aniflag) { |
| 520 | /* Call ANI routine if necessary */ | 520 | spin_lock_irqsave(&common->cc_lock, flags); |
| 521 | if (aniflag) { | 521 | ath9k_hw_ani_monitor(ah, ah->curchan); |
| 522 | spin_lock_irqsave(&common->cc_lock, flags); | 522 | ath_update_survey_stats(sc); |
| 523 | ath9k_hw_ani_monitor(ah, ah->curchan); | 523 | spin_unlock_irqrestore(&common->cc_lock, flags); |
| 524 | ath_update_survey_stats(sc); | 524 | } |
| 525 | spin_unlock_irqrestore(&common->cc_lock, flags); | ||
| 526 | } | ||
| 527 | 525 | ||
| 528 | /* Perform calibration if necessary */ | 526 | /* Perform calibration if necessary */ |
| 529 | if (longcal || shortcal) { | 527 | if (longcal || shortcal) { |
| 530 | common->ani.caldone = | 528 | common->ani.caldone = |
| 531 | ath9k_hw_calibrate(ah, | 529 | ath9k_hw_calibrate(ah, ah->curchan, |
| 532 | ah->curchan, | 530 | common->rx_chainmask, longcal); |
| 533 | common->rx_chainmask, | ||
| 534 | longcal); | ||
| 535 | } | ||
| 536 | } | 531 | } |
| 537 | 532 | ||
| 538 | ath9k_ps_restore(sc); | 533 | ath9k_ps_restore(sc); |
| @@ -868,7 +863,7 @@ chip_reset: | |||
| 868 | #undef SCHED_INTR | 863 | #undef SCHED_INTR |
| 869 | } | 864 | } |
| 870 | 865 | ||
| 871 | void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | 866 | static void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) |
| 872 | { | 867 | { |
| 873 | struct ath_hw *ah = sc->sc_ah; | 868 | struct ath_hw *ah = sc->sc_ah; |
| 874 | struct ath_common *common = ath9k_hw_common(ah); | 869 | struct ath_common *common = ath9k_hw_common(ah); |
| @@ -974,6 +969,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 974 | sc->hw_busy_count = 0; | 969 | sc->hw_busy_count = 0; |
| 975 | 970 | ||
| 976 | /* Stop ANI */ | 971 | /* Stop ANI */ |
| 972 | |||
| 977 | del_timer_sync(&common->ani.timer); | 973 | del_timer_sync(&common->ani.timer); |
| 978 | 974 | ||
| 979 | ath9k_ps_wakeup(sc); | 975 | ath9k_ps_wakeup(sc); |
| @@ -1023,7 +1019,9 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
| 1023 | spin_unlock_bh(&sc->sc_pcu_lock); | 1019 | spin_unlock_bh(&sc->sc_pcu_lock); |
| 1024 | 1020 | ||
| 1025 | /* Start ANI */ | 1021 | /* Start ANI */ |
| 1026 | ath_start_ani(common); | 1022 | if (!common->disable_ani) |
| 1023 | ath_start_ani(common); | ||
| 1024 | |||
| 1027 | ath9k_ps_restore(sc); | 1025 | ath9k_ps_restore(sc); |
| 1028 | 1026 | ||
| 1029 | return r; | 1027 | return r; |
| @@ -1412,10 +1410,14 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw, | |||
| 1412 | ath9k_hw_set_interrupts(ah, ah->imask); | 1410 | ath9k_hw_set_interrupts(ah, ah->imask); |
| 1413 | 1411 | ||
| 1414 | /* Set up ANI */ | 1412 | /* Set up ANI */ |
| 1415 | if ((iter_data.naps + iter_data.nadhocs) > 0) { | 1413 | if (iter_data.naps > 0) { |
| 1416 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1414 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
| 1417 | sc->sc_flags |= SC_OP_ANI_RUN; | 1415 | |
| 1418 | ath_start_ani(common); | 1416 | if (!common->disable_ani) { |
| 1417 | sc->sc_flags |= SC_OP_ANI_RUN; | ||
| 1418 | ath_start_ani(common); | ||
| 1419 | } | ||
| 1420 | |||
| 1419 | } else { | 1421 | } else { |
| 1420 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 1422 | sc->sc_flags &= ~SC_OP_ANI_RUN; |
| 1421 | del_timer_sync(&common->ani.timer); | 1423 | del_timer_sync(&common->ani.timer); |
| @@ -1952,50 +1954,38 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
| 1952 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1954 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
| 1953 | struct ath_vif *avp = (void *)vif->drv_priv; | 1955 | struct ath_vif *avp = (void *)vif->drv_priv; |
| 1954 | 1956 | ||
| 1955 | switch (sc->sc_ah->opmode) { | 1957 | /* |
| 1956 | case NL80211_IFTYPE_ADHOC: | 1958 | * Skip iteration if primary station vif's bss info |
| 1957 | /* There can be only one vif available */ | 1959 | * was not changed |
| 1960 | */ | ||
| 1961 | if (sc->sc_flags & SC_OP_PRIM_STA_VIF) | ||
| 1962 | return; | ||
| 1963 | |||
| 1964 | if (bss_conf->assoc) { | ||
| 1965 | sc->sc_flags |= SC_OP_PRIM_STA_VIF; | ||
| 1966 | avp->primary_sta_vif = true; | ||
| 1958 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1967 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
| 1959 | common->curaid = bss_conf->aid; | 1968 | common->curaid = bss_conf->aid; |
| 1960 | ath9k_hw_write_associd(sc->sc_ah); | 1969 | ath9k_hw_write_associd(sc->sc_ah); |
| 1961 | /* configure beacon */ | 1970 | ath_dbg(common, ATH_DBG_CONFIG, |
| 1962 | if (bss_conf->enable_beacon) | ||
| 1963 | ath_beacon_config(sc, vif); | ||
| 1964 | break; | ||
| 1965 | case NL80211_IFTYPE_STATION: | ||
| 1966 | /* | ||
| 1967 | * Skip iteration if primary station vif's bss info | ||
| 1968 | * was not changed | ||
| 1969 | */ | ||
| 1970 | if (sc->sc_flags & SC_OP_PRIM_STA_VIF) | ||
| 1971 | break; | ||
| 1972 | |||
| 1973 | if (bss_conf->assoc) { | ||
| 1974 | sc->sc_flags |= SC_OP_PRIM_STA_VIF; | ||
| 1975 | avp->primary_sta_vif = true; | ||
| 1976 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
| 1977 | common->curaid = bss_conf->aid; | ||
| 1978 | ath9k_hw_write_associd(sc->sc_ah); | ||
| 1979 | ath_dbg(common, ATH_DBG_CONFIG, | ||
| 1980 | "Bss Info ASSOC %d, bssid: %pM\n", | 1971 | "Bss Info ASSOC %d, bssid: %pM\n", |
| 1981 | bss_conf->aid, common->curbssid); | 1972 | bss_conf->aid, common->curbssid); |
| 1982 | ath_beacon_config(sc, vif); | 1973 | ath_beacon_config(sc, vif); |
| 1983 | /* | 1974 | /* |
| 1984 | * Request a re-configuration of Beacon related timers | 1975 | * Request a re-configuration of Beacon related timers |
| 1985 | * on the receipt of the first Beacon frame (i.e., | 1976 | * on the receipt of the first Beacon frame (i.e., |
| 1986 | * after time sync with the AP). | 1977 | * after time sync with the AP). |
| 1987 | */ | 1978 | */ |
| 1988 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | 1979 | sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; |
| 1989 | /* Reset rssi stats */ | 1980 | /* Reset rssi stats */ |
| 1990 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | 1981 | sc->last_rssi = ATH_RSSI_DUMMY_MARKER; |
| 1991 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | 1982 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; |
| 1992 | 1983 | ||
| 1984 | if (!common->disable_ani) { | ||
| 1993 | sc->sc_flags |= SC_OP_ANI_RUN; | 1985 | sc->sc_flags |= SC_OP_ANI_RUN; |
| 1994 | ath_start_ani(common); | 1986 | ath_start_ani(common); |
| 1995 | } | 1987 | } |
| 1996 | break; | 1988 | |
| 1997 | default: | ||
| 1998 | break; | ||
| 1999 | } | 1989 | } |
| 2000 | } | 1990 | } |
| 2001 | 1991 | ||
| @@ -2005,6 +1995,9 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
| 2005 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | 1995 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; |
| 2006 | struct ath_vif *avp = (void *)vif->drv_priv; | 1996 | struct ath_vif *avp = (void *)vif->drv_priv; |
| 2007 | 1997 | ||
| 1998 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | ||
| 1999 | return; | ||
| 2000 | |||
| 2008 | /* Reconfigure bss info */ | 2001 | /* Reconfigure bss info */ |
| 2009 | if (avp->primary_sta_vif && !bss_conf->assoc) { | 2002 | if (avp->primary_sta_vif && !bss_conf->assoc) { |
| 2010 | ath_dbg(common, ATH_DBG_CONFIG, | 2003 | ath_dbg(common, ATH_DBG_CONFIG, |
| @@ -2023,8 +2016,7 @@ static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
| 2023 | * None of station vifs are associated. | 2016 | * None of station vifs are associated. |
| 2024 | * Clear bssid & aid | 2017 | * Clear bssid & aid |
| 2025 | */ | 2018 | */ |
| 2026 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 2019 | if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { |
| 2027 | !(sc->sc_flags & SC_OP_PRIM_STA_VIF)) { | ||
| 2028 | ath9k_hw_write_associd(sc->sc_ah); | 2020 | ath9k_hw_write_associd(sc->sc_ah); |
| 2029 | /* Stop ANI */ | 2021 | /* Stop ANI */ |
| 2030 | sc->sc_flags &= ~SC_OP_ANI_RUN; | 2022 | sc->sc_flags &= ~SC_OP_ANI_RUN; |
| @@ -2054,6 +2046,26 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
| 2054 | common->curbssid, common->curaid); | 2046 | common->curbssid, common->curaid); |
| 2055 | } | 2047 | } |
| 2056 | 2048 | ||
| 2049 | if (changed & BSS_CHANGED_IBSS) { | ||
| 2050 | /* There can be only one vif available */ | ||
| 2051 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
| 2052 | common->curaid = bss_conf->aid; | ||
| 2053 | ath9k_hw_write_associd(sc->sc_ah); | ||
| 2054 | |||
| 2055 | if (bss_conf->ibss_joined) { | ||
| 2056 | sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||
| 2057 | |||
| 2058 | if (!common->disable_ani) { | ||
| 2059 | sc->sc_flags |= SC_OP_ANI_RUN; | ||
| 2060 | ath_start_ani(common); | ||
| 2061 | } | ||
| 2062 | |||
| 2063 | } else { | ||
| 2064 | sc->sc_flags &= ~SC_OP_ANI_RUN; | ||
| 2065 | del_timer_sync(&common->ani.timer); | ||
| 2066 | } | ||
| 2067 | } | ||
| 2068 | |||
| 2057 | /* Enable transmission of beacons (AP, IBSS, MESH) */ | 2069 | /* Enable transmission of beacons (AP, IBSS, MESH) */ |
| 2058 | if ((changed & BSS_CHANGED_BEACON) || | 2070 | if ((changed & BSS_CHANGED_BEACON) || |
| 2059 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { | 2071 | ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon)) { |
| @@ -2334,7 +2346,7 @@ static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | |||
| 2334 | return false; | 2346 | return false; |
| 2335 | } | 2347 | } |
| 2336 | 2348 | ||
| 2337 | int ath9k_tx_last_beacon(struct ieee80211_hw *hw) | 2349 | static int ath9k_tx_last_beacon(struct ieee80211_hw *hw) |
| 2338 | { | 2350 | { |
| 2339 | struct ath_softc *sc = hw->priv; | 2351 | struct ath_softc *sc = hw->priv; |
| 2340 | struct ath_hw *ah = sc->sc_ah; | 2352 | struct ath_hw *ah = sc->sc_ah; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3779b8977d47..ec012b4317af 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
| @@ -53,7 +53,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
| 53 | struct ath_txq *txq, struct list_head *bf_q, | 53 | struct ath_txq *txq, struct list_head *bf_q, |
| 54 | struct ath_tx_status *ts, int txok, int sendbar); | 54 | struct ath_tx_status *ts, int txok, int sendbar); |
| 55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 55 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
| 56 | struct list_head *head); | 56 | struct list_head *head, bool internal); |
| 57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); | 57 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len); |
| 58 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, | 58 | static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, |
| 59 | struct ath_tx_status *ts, int nframes, int nbad, | 59 | struct ath_tx_status *ts, int nframes, int nbad, |
| @@ -377,8 +377,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 377 | bf_next = bf->bf_next; | 377 | bf_next = bf->bf_next; |
| 378 | 378 | ||
| 379 | bf->bf_state.bf_type |= BUF_XRETRY; | 379 | bf->bf_state.bf_type |= BUF_XRETRY; |
| 380 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) || | 380 | if (!bf->bf_stale || bf_next != NULL) |
| 381 | !bf->bf_stale || bf_next != NULL) | ||
| 382 | list_move_tail(&bf->list, &bf_head); | 381 | list_move_tail(&bf->list, &bf_head); |
| 383 | 382 | ||
| 384 | ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); | 383 | ath_tx_rc_status(sc, bf, ts, 1, 1, 0, false); |
| @@ -463,20 +462,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 463 | } | 462 | } |
| 464 | } | 463 | } |
| 465 | 464 | ||
| 466 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | 465 | /* |
| 467 | bf_next == NULL) { | 466 | * Make sure the last desc is reclaimed if it |
| 468 | /* | 467 | * not a holding desc. |
| 469 | * Make sure the last desc is reclaimed if it | 468 | */ |
| 470 | * not a holding desc. | 469 | if (!bf_last->bf_stale || bf_next != NULL) |
| 471 | */ | ||
| 472 | if (!bf_last->bf_stale) | ||
| 473 | list_move_tail(&bf->list, &bf_head); | ||
| 474 | else | ||
| 475 | INIT_LIST_HEAD(&bf_head); | ||
| 476 | } else { | ||
| 477 | BUG_ON(list_empty(bf_q)); | ||
| 478 | list_move_tail(&bf->list, &bf_head); | 470 | list_move_tail(&bf->list, &bf_head); |
| 479 | } | 471 | else |
| 472 | INIT_LIST_HEAD(&bf_head); | ||
| 480 | 473 | ||
| 481 | if (!txpending || (tid->state & AGGR_CLEANUP)) { | 474 | if (!txpending || (tid->state & AGGR_CLEANUP)) { |
| 482 | /* | 475 | /* |
| @@ -837,7 +830,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 837 | bf->bf_state.bf_type &= ~BUF_AGGR; | 830 | bf->bf_state.bf_type &= ~BUF_AGGR; |
| 838 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); | 831 | ath9k_hw_clr11n_aggr(sc->sc_ah, bf->bf_desc); |
| 839 | ath_buf_set_rate(sc, bf, fi->framelen); | 832 | ath_buf_set_rate(sc, bf, fi->framelen); |
| 840 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 833 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); |
| 841 | continue; | 834 | continue; |
| 842 | } | 835 | } |
| 843 | 836 | ||
| @@ -849,7 +842,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
| 849 | /* anchor last desc of aggregate */ | 842 | /* anchor last desc of aggregate */ |
| 850 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); | 843 | ath9k_hw_set11n_aggr_last(sc->sc_ah, bf->bf_lastbf->bf_desc); |
| 851 | 844 | ||
| 852 | ath_tx_txqaddbuf(sc, txq, &bf_q); | 845 | ath_tx_txqaddbuf(sc, txq, &bf_q, false); |
| 853 | TX_STAT_INC(txq->axq_qnum, a_aggr); | 846 | TX_STAT_INC(txq->axq_qnum, a_aggr); |
| 854 | 847 | ||
| 855 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && | 848 | } while (txq->axq_ampdu_depth < ATH_AGGR_MIN_QDEPTH && |
| @@ -1085,7 +1078,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
| 1085 | txq->txq_headidx = txq->txq_tailidx = 0; | 1078 | txq->txq_headidx = txq->txq_tailidx = 0; |
| 1086 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) | 1079 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) |
| 1087 | INIT_LIST_HEAD(&txq->txq_fifo[i]); | 1080 | INIT_LIST_HEAD(&txq->txq_fifo[i]); |
| 1088 | INIT_LIST_HEAD(&txq->txq_fifo_pending); | ||
| 1089 | } | 1081 | } |
| 1090 | return &sc->tx.txq[axq_qnum]; | 1082 | return &sc->tx.txq[axq_qnum]; |
| 1091 | } | 1083 | } |
| @@ -1155,13 +1147,8 @@ static bool bf_is_ampdu_not_probing(struct ath_buf *bf) | |||
| 1155 | return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); | 1147 | return bf_isampdu(bf) && !(info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE); |
| 1156 | } | 1148 | } |
| 1157 | 1149 | ||
| 1158 | /* | 1150 | static void ath_drain_txq_list(struct ath_softc *sc, struct ath_txq *txq, |
| 1159 | * Drain a given TX queue (could be Beacon or Data) | 1151 | struct list_head *list, bool retry_tx) |
| 1160 | * | ||
| 1161 | * This assumes output has been stopped and | ||
| 1162 | * we do not need to block ath_tx_tasklet. | ||
| 1163 | */ | ||
| 1164 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | ||
| 1165 | { | 1152 | { |
| 1166 | struct ath_buf *bf, *lastbf; | 1153 | struct ath_buf *bf, *lastbf; |
| 1167 | struct list_head bf_head; | 1154 | struct list_head bf_head; |
| @@ -1170,93 +1157,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
| 1170 | memset(&ts, 0, sizeof(ts)); | 1157 | memset(&ts, 0, sizeof(ts)); |
| 1171 | INIT_LIST_HEAD(&bf_head); | 1158 | INIT_LIST_HEAD(&bf_head); |
| 1172 | 1159 | ||
| 1173 | for (;;) { | 1160 | while (!list_empty(list)) { |
| 1174 | spin_lock_bh(&txq->axq_lock); | 1161 | bf = list_first_entry(list, struct ath_buf, list); |
| 1175 | 1162 | ||
| 1176 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1163 | if (bf->bf_stale) { |
| 1177 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 1164 | list_del(&bf->list); |
| 1178 | txq->txq_headidx = txq->txq_tailidx = 0; | ||
| 1179 | spin_unlock_bh(&txq->axq_lock); | ||
| 1180 | break; | ||
| 1181 | } else { | ||
| 1182 | bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], | ||
| 1183 | struct ath_buf, list); | ||
| 1184 | } | ||
| 1185 | } else { | ||
| 1186 | if (list_empty(&txq->axq_q)) { | ||
| 1187 | txq->axq_link = NULL; | ||
| 1188 | spin_unlock_bh(&txq->axq_lock); | ||
| 1189 | break; | ||
| 1190 | } | ||
| 1191 | bf = list_first_entry(&txq->axq_q, struct ath_buf, | ||
| 1192 | list); | ||
| 1193 | |||
| 1194 | if (bf->bf_stale) { | ||
| 1195 | list_del(&bf->list); | ||
| 1196 | spin_unlock_bh(&txq->axq_lock); | ||
| 1197 | 1165 | ||
| 1198 | ath_tx_return_buffer(sc, bf); | 1166 | ath_tx_return_buffer(sc, bf); |
| 1199 | continue; | 1167 | continue; |
| 1200 | } | ||
| 1201 | } | 1168 | } |
| 1202 | 1169 | ||
| 1203 | lastbf = bf->bf_lastbf; | 1170 | lastbf = bf->bf_lastbf; |
| 1204 | 1171 | list_cut_position(&bf_head, list, &lastbf->list); | |
| 1205 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
| 1206 | list_cut_position(&bf_head, | ||
| 1207 | &txq->txq_fifo[txq->txq_tailidx], | ||
| 1208 | &lastbf->list); | ||
| 1209 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | ||
| 1210 | } else { | ||
| 1211 | /* remove ath_buf's of the same mpdu from txq */ | ||
| 1212 | list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); | ||
| 1213 | } | ||
| 1214 | 1172 | ||
| 1215 | txq->axq_depth--; | 1173 | txq->axq_depth--; |
| 1216 | if (bf_is_ampdu_not_probing(bf)) | 1174 | if (bf_is_ampdu_not_probing(bf)) |
| 1217 | txq->axq_ampdu_depth--; | 1175 | txq->axq_ampdu_depth--; |
| 1218 | spin_unlock_bh(&txq->axq_lock); | ||
| 1219 | 1176 | ||
| 1177 | spin_unlock_bh(&txq->axq_lock); | ||
| 1220 | if (bf_isampdu(bf)) | 1178 | if (bf_isampdu(bf)) |
| 1221 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, | 1179 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0, |
| 1222 | retry_tx); | 1180 | retry_tx); |
| 1223 | else | 1181 | else |
| 1224 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); | 1182 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
| 1183 | spin_lock_bh(&txq->axq_lock); | ||
| 1225 | } | 1184 | } |
| 1185 | } | ||
| 1226 | 1186 | ||
| 1187 | /* | ||
| 1188 | * Drain a given TX queue (could be Beacon or Data) | ||
| 1189 | * | ||
| 1190 | * This assumes output has been stopped and | ||
| 1191 | * we do not need to block ath_tx_tasklet. | ||
| 1192 | */ | ||
| 1193 | void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | ||
| 1194 | { | ||
| 1227 | spin_lock_bh(&txq->axq_lock); | 1195 | spin_lock_bh(&txq->axq_lock); |
| 1228 | txq->axq_tx_inprogress = false; | ||
| 1229 | spin_unlock_bh(&txq->axq_lock); | ||
| 1230 | |||
| 1231 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1196 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
| 1232 | spin_lock_bh(&txq->axq_lock); | 1197 | int idx = txq->txq_tailidx; |
| 1233 | while (!list_empty(&txq->txq_fifo_pending)) { | ||
| 1234 | bf = list_first_entry(&txq->txq_fifo_pending, | ||
| 1235 | struct ath_buf, list); | ||
| 1236 | list_cut_position(&bf_head, | ||
| 1237 | &txq->txq_fifo_pending, | ||
| 1238 | &bf->bf_lastbf->list); | ||
| 1239 | spin_unlock_bh(&txq->axq_lock); | ||
| 1240 | 1198 | ||
| 1241 | if (bf_isampdu(bf)) | 1199 | while (!list_empty(&txq->txq_fifo[idx])) { |
| 1242 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, | 1200 | ath_drain_txq_list(sc, txq, &txq->txq_fifo[idx], |
| 1243 | &ts, 0, retry_tx); | 1201 | retry_tx); |
| 1244 | else | 1202 | |
| 1245 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | 1203 | INCR(idx, ATH_TXFIFO_DEPTH); |
| 1246 | &ts, 0, 0); | ||
| 1247 | spin_lock_bh(&txq->axq_lock); | ||
| 1248 | } | 1204 | } |
| 1249 | spin_unlock_bh(&txq->axq_lock); | 1205 | txq->txq_tailidx = idx; |
| 1250 | } | 1206 | } |
| 1251 | 1207 | ||
| 1208 | txq->axq_link = NULL; | ||
| 1209 | txq->axq_tx_inprogress = false; | ||
| 1210 | ath_drain_txq_list(sc, txq, &txq->axq_q, retry_tx); | ||
| 1211 | |||
| 1252 | /* flush any pending frames if aggregation is enabled */ | 1212 | /* flush any pending frames if aggregation is enabled */ |
| 1253 | if (sc->sc_flags & SC_OP_TXAGGR) { | 1213 | if ((sc->sc_flags & SC_OP_TXAGGR) && !retry_tx) |
| 1254 | if (!retry_tx) { | 1214 | ath_txq_drain_pending_buffers(sc, txq); |
| 1255 | spin_lock_bh(&txq->axq_lock); | 1215 | |
| 1256 | ath_txq_drain_pending_buffers(sc, txq); | 1216 | spin_unlock_bh(&txq->axq_lock); |
| 1257 | spin_unlock_bh(&txq->axq_lock); | ||
| 1258 | } | ||
| 1259 | } | ||
| 1260 | } | 1217 | } |
| 1261 | 1218 | ||
| 1262 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1219 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
| @@ -1370,11 +1327,13 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
| 1370 | * assume the descriptors are already chained together by caller. | 1327 | * assume the descriptors are already chained together by caller. |
| 1371 | */ | 1328 | */ |
| 1372 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 1329 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
| 1373 | struct list_head *head) | 1330 | struct list_head *head, bool internal) |
| 1374 | { | 1331 | { |
| 1375 | struct ath_hw *ah = sc->sc_ah; | 1332 | struct ath_hw *ah = sc->sc_ah; |
| 1376 | struct ath_common *common = ath9k_hw_common(ah); | 1333 | struct ath_common *common = ath9k_hw_common(ah); |
| 1377 | struct ath_buf *bf; | 1334 | struct ath_buf *bf, *bf_last; |
| 1335 | bool puttxbuf = false; | ||
| 1336 | bool edma; | ||
| 1378 | 1337 | ||
| 1379 | /* | 1338 | /* |
| 1380 | * Insert the frame on the outbound list and | 1339 | * Insert the frame on the outbound list and |
| @@ -1384,51 +1343,49 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
| 1384 | if (list_empty(head)) | 1343 | if (list_empty(head)) |
| 1385 | return; | 1344 | return; |
| 1386 | 1345 | ||
| 1346 | edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | ||
| 1387 | bf = list_first_entry(head, struct ath_buf, list); | 1347 | bf = list_first_entry(head, struct ath_buf, list); |
| 1348 | bf_last = list_entry(head->prev, struct ath_buf, list); | ||
| 1388 | 1349 | ||
| 1389 | ath_dbg(common, ATH_DBG_QUEUE, | 1350 | ath_dbg(common, ATH_DBG_QUEUE, |
| 1390 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1351 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
| 1391 | 1352 | ||
| 1392 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 1353 | if (edma && list_empty(&txq->txq_fifo[txq->txq_headidx])) { |
| 1393 | if (txq->axq_depth >= ATH_TXFIFO_DEPTH) { | 1354 | list_splice_tail_init(head, &txq->txq_fifo[txq->txq_headidx]); |
| 1394 | list_splice_tail_init(head, &txq->txq_fifo_pending); | ||
| 1395 | return; | ||
| 1396 | } | ||
| 1397 | if (!list_empty(&txq->txq_fifo[txq->txq_headidx])) | ||
| 1398 | ath_dbg(common, ATH_DBG_XMIT, | ||
| 1399 | "Initializing tx fifo %d which is non-empty\n", | ||
| 1400 | txq->txq_headidx); | ||
| 1401 | INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]); | ||
| 1402 | list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]); | ||
| 1403 | INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); | 1355 | INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); |
| 1404 | TX_STAT_INC(txq->axq_qnum, puttxbuf); | 1356 | puttxbuf = true; |
| 1405 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
| 1406 | ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", | ||
| 1407 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | ||
| 1408 | } else { | 1357 | } else { |
| 1409 | list_splice_tail_init(head, &txq->axq_q); | 1358 | list_splice_tail_init(head, &txq->axq_q); |
| 1410 | 1359 | ||
| 1411 | if (txq->axq_link == NULL) { | 1360 | if (txq->axq_link) { |
| 1412 | TX_STAT_INC(txq->axq_qnum, puttxbuf); | 1361 | ath9k_hw_set_desc_link(ah, txq->axq_link, bf->bf_daddr); |
| 1413 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
| 1414 | ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", | ||
| 1415 | txq->axq_qnum, ito64(bf->bf_daddr), | ||
| 1416 | bf->bf_desc); | ||
| 1417 | } else { | ||
| 1418 | *txq->axq_link = bf->bf_daddr; | ||
| 1419 | ath_dbg(common, ATH_DBG_XMIT, | 1362 | ath_dbg(common, ATH_DBG_XMIT, |
| 1420 | "link[%u] (%p)=%llx (%p)\n", | 1363 | "link[%u] (%p)=%llx (%p)\n", |
| 1421 | txq->axq_qnum, txq->axq_link, | 1364 | txq->axq_qnum, txq->axq_link, |
| 1422 | ito64(bf->bf_daddr), bf->bf_desc); | 1365 | ito64(bf->bf_daddr), bf->bf_desc); |
| 1423 | } | 1366 | } else if (!edma) |
| 1424 | ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, | 1367 | puttxbuf = true; |
| 1425 | &txq->axq_link); | 1368 | |
| 1369 | txq->axq_link = bf_last->bf_desc; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | if (puttxbuf) { | ||
| 1373 | TX_STAT_INC(txq->axq_qnum, puttxbuf); | ||
| 1374 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | ||
| 1375 | ath_dbg(common, ATH_DBG_XMIT, "TXDP[%u] = %llx (%p)\n", | ||
| 1376 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | if (!edma) { | ||
| 1426 | TX_STAT_INC(txq->axq_qnum, txstart); | 1380 | TX_STAT_INC(txq->axq_qnum, txstart); |
| 1427 | ath9k_hw_txstart(ah, txq->axq_qnum); | 1381 | ath9k_hw_txstart(ah, txq->axq_qnum); |
| 1428 | } | 1382 | } |
| 1429 | txq->axq_depth++; | 1383 | |
| 1430 | if (bf_is_ampdu_not_probing(bf)) | 1384 | if (!internal) { |
| 1431 | txq->axq_ampdu_depth++; | 1385 | txq->axq_depth++; |
| 1386 | if (bf_is_ampdu_not_probing(bf)) | ||
| 1387 | txq->axq_ampdu_depth++; | ||
| 1388 | } | ||
| 1432 | } | 1389 | } |
| 1433 | 1390 | ||
| 1434 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | 1391 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, |
| @@ -1470,7 +1427,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
| 1470 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); | 1427 | TX_STAT_INC(txctl->txq->axq_qnum, a_queued_hw); |
| 1471 | bf->bf_lastbf = bf; | 1428 | bf->bf_lastbf = bf; |
| 1472 | ath_buf_set_rate(sc, bf, fi->framelen); | 1429 | ath_buf_set_rate(sc, bf, fi->framelen); |
| 1473 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head); | 1430 | ath_tx_txqaddbuf(sc, txctl->txq, &bf_head, false); |
| 1474 | } | 1431 | } |
| 1475 | 1432 | ||
| 1476 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 1433 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, |
| @@ -1490,7 +1447,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
| 1490 | bf->bf_lastbf = bf; | 1447 | bf->bf_lastbf = bf; |
| 1491 | fi = get_frame_info(bf->bf_mpdu); | 1448 | fi = get_frame_info(bf->bf_mpdu); |
| 1492 | ath_buf_set_rate(sc, bf, fi->framelen); | 1449 | ath_buf_set_rate(sc, bf, fi->framelen); |
| 1493 | ath_tx_txqaddbuf(sc, txq, bf_head); | 1450 | ath_tx_txqaddbuf(sc, txq, bf_head, false); |
| 1494 | TX_STAT_INC(txq->axq_qnum, queued); | 1451 | TX_STAT_INC(txq->axq_qnum, queued); |
| 1495 | } | 1452 | } |
| 1496 | 1453 | ||
| @@ -2077,6 +2034,38 @@ static void ath_tx_rc_status(struct ath_softc *sc, struct ath_buf *bf, | |||
| 2077 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; | 2034 | tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; |
| 2078 | } | 2035 | } |
| 2079 | 2036 | ||
| 2037 | static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | ||
| 2038 | struct ath_tx_status *ts, struct ath_buf *bf, | ||
| 2039 | struct list_head *bf_head) | ||
| 2040 | { | ||
| 2041 | int txok; | ||
| 2042 | |||
| 2043 | txq->axq_depth--; | ||
| 2044 | txok = !(ts->ts_status & ATH9K_TXERR_MASK); | ||
| 2045 | txq->axq_tx_inprogress = false; | ||
| 2046 | if (bf_is_ampdu_not_probing(bf)) | ||
| 2047 | txq->axq_ampdu_depth--; | ||
| 2048 | |||
| 2049 | spin_unlock_bh(&txq->axq_lock); | ||
| 2050 | |||
| 2051 | if (!bf_isampdu(bf)) { | ||
| 2052 | /* | ||
| 2053 | * This frame is sent out as a single frame. | ||
| 2054 | * Use hardware retry status for this frame. | ||
| 2055 | */ | ||
| 2056 | if (ts->ts_status & ATH9K_TXERR_XRETRY) | ||
| 2057 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
| 2058 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok, true); | ||
| 2059 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok, 0); | ||
| 2060 | } else | ||
| 2061 | ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok, true); | ||
| 2062 | |||
| 2063 | spin_lock_bh(&txq->axq_lock); | ||
| 2064 | |||
| 2065 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
| 2066 | ath_txq_schedule(sc, txq); | ||
| 2067 | } | ||
| 2068 | |||
| 2080 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | 2069 | static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) |
| 2081 | { | 2070 | { |
| 2082 | struct ath_hw *ah = sc->sc_ah; | 2071 | struct ath_hw *ah = sc->sc_ah; |
| @@ -2085,20 +2074,18 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2085 | struct list_head bf_head; | 2074 | struct list_head bf_head; |
| 2086 | struct ath_desc *ds; | 2075 | struct ath_desc *ds; |
| 2087 | struct ath_tx_status ts; | 2076 | struct ath_tx_status ts; |
| 2088 | int txok; | ||
| 2089 | int status; | 2077 | int status; |
| 2090 | 2078 | ||
| 2091 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", | 2079 | ath_dbg(common, ATH_DBG_QUEUE, "tx queue %d (%x), link %p\n", |
| 2092 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), | 2080 | txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum), |
| 2093 | txq->axq_link); | 2081 | txq->axq_link); |
| 2094 | 2082 | ||
| 2083 | spin_lock_bh(&txq->axq_lock); | ||
| 2095 | for (;;) { | 2084 | for (;;) { |
| 2096 | spin_lock_bh(&txq->axq_lock); | ||
| 2097 | if (list_empty(&txq->axq_q)) { | 2085 | if (list_empty(&txq->axq_q)) { |
| 2098 | txq->axq_link = NULL; | 2086 | txq->axq_link = NULL; |
| 2099 | if (sc->sc_flags & SC_OP_TXAGGR) | 2087 | if (sc->sc_flags & SC_OP_TXAGGR) |
| 2100 | ath_txq_schedule(sc, txq); | 2088 | ath_txq_schedule(sc, txq); |
| 2101 | spin_unlock_bh(&txq->axq_lock); | ||
| 2102 | break; | 2089 | break; |
| 2103 | } | 2090 | } |
| 2104 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | 2091 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); |
| @@ -2114,13 +2101,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2114 | bf_held = NULL; | 2101 | bf_held = NULL; |
| 2115 | if (bf->bf_stale) { | 2102 | if (bf->bf_stale) { |
| 2116 | bf_held = bf; | 2103 | bf_held = bf; |
| 2117 | if (list_is_last(&bf_held->list, &txq->axq_q)) { | 2104 | if (list_is_last(&bf_held->list, &txq->axq_q)) |
| 2118 | spin_unlock_bh(&txq->axq_lock); | ||
| 2119 | break; | 2105 | break; |
| 2120 | } else { | 2106 | |
| 2121 | bf = list_entry(bf_held->list.next, | 2107 | bf = list_entry(bf_held->list.next, struct ath_buf, |
| 2122 | struct ath_buf, list); | 2108 | list); |
| 2123 | } | ||
| 2124 | } | 2109 | } |
| 2125 | 2110 | ||
| 2126 | lastbf = bf->bf_lastbf; | 2111 | lastbf = bf->bf_lastbf; |
| @@ -2128,10 +2113,9 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2128 | 2113 | ||
| 2129 | memset(&ts, 0, sizeof(ts)); | 2114 | memset(&ts, 0, sizeof(ts)); |
| 2130 | status = ath9k_hw_txprocdesc(ah, ds, &ts); | 2115 | status = ath9k_hw_txprocdesc(ah, ds, &ts); |
| 2131 | if (status == -EINPROGRESS) { | 2116 | if (status == -EINPROGRESS) |
| 2132 | spin_unlock_bh(&txq->axq_lock); | ||
| 2133 | break; | 2117 | break; |
| 2134 | } | 2118 | |
| 2135 | TX_STAT_INC(txq->axq_qnum, txprocdesc); | 2119 | TX_STAT_INC(txq->axq_qnum, txprocdesc); |
| 2136 | 2120 | ||
| 2137 | /* | 2121 | /* |
| @@ -2145,42 +2129,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 2145 | list_cut_position(&bf_head, | 2129 | list_cut_position(&bf_head, |
| 2146 | &txq->axq_q, lastbf->list.prev); | 2130 | &txq->axq_q, lastbf->list.prev); |
| 2147 | 2131 | ||
| 2148 | txq->axq_depth--; | 2132 | if (bf_held) { |
| 2149 | txok = !(ts.ts_status & ATH9K_TXERR_MASK); | ||
| 2150 | txq->axq_tx_inprogress = false; | ||
| 2151 | if (bf_held) | ||
| 2152 | list_del(&bf_held->list); | 2133 | list_del(&bf_held->list); |
| 2153 | |||
| 2154 | if (bf_is_ampdu_not_probing(bf)) | ||
| 2155 | txq->axq_ampdu_depth--; | ||
| 2156 | |||
| 2157 | spin_unlock_bh(&txq->axq_lock); | ||
| 2158 | |||
| 2159 | if (bf_held) | ||
| 2160 | ath_tx_return_buffer(sc, bf_held); | 2134 | ath_tx_return_buffer(sc, bf_held); |
| 2161 | |||
| 2162 | if (!bf_isampdu(bf)) { | ||
| 2163 | /* | ||
| 2164 | * This frame is sent out as a single frame. | ||
| 2165 | * Use hardware retry status for this frame. | ||
| 2166 | */ | ||
| 2167 | if (ts.ts_status & ATH9K_TXERR_XRETRY) | ||
| 2168 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
| 2169 | ath_tx_rc_status(sc, bf, &ts, 1, txok ? 0 : 1, txok, true); | ||
| 2170 | } | 2135 | } |
| 2171 | 2136 | ||
| 2172 | if (bf_isampdu(bf)) | 2137 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); |
| 2173 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok, | ||
| 2174 | true); | ||
| 2175 | else | ||
| 2176 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); | ||
| 2177 | |||
| 2178 | spin_lock_bh(&txq->axq_lock); | ||
| 2179 | |||
| 2180 | if (sc->sc_flags & SC_OP_TXAGGR) | ||
| 2181 | ath_txq_schedule(sc, txq); | ||
| 2182 | spin_unlock_bh(&txq->axq_lock); | ||
| 2183 | } | 2138 | } |
| 2139 | spin_unlock_bh(&txq->axq_lock); | ||
| 2184 | } | 2140 | } |
| 2185 | 2141 | ||
| 2186 | static void ath_tx_complete_poll_work(struct work_struct *work) | 2142 | static void ath_tx_complete_poll_work(struct work_struct *work) |
| @@ -2237,17 +2193,16 @@ void ath_tx_tasklet(struct ath_softc *sc) | |||
| 2237 | 2193 | ||
| 2238 | void ath_tx_edma_tasklet(struct ath_softc *sc) | 2194 | void ath_tx_edma_tasklet(struct ath_softc *sc) |
| 2239 | { | 2195 | { |
| 2240 | struct ath_tx_status txs; | 2196 | struct ath_tx_status ts; |
| 2241 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2197 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
| 2242 | struct ath_hw *ah = sc->sc_ah; | 2198 | struct ath_hw *ah = sc->sc_ah; |
| 2243 | struct ath_txq *txq; | 2199 | struct ath_txq *txq; |
| 2244 | struct ath_buf *bf, *lastbf; | 2200 | struct ath_buf *bf, *lastbf; |
| 2245 | struct list_head bf_head; | 2201 | struct list_head bf_head; |
| 2246 | int status; | 2202 | int status; |
| 2247 | int txok; | ||
| 2248 | 2203 | ||
| 2249 | for (;;) { | 2204 | for (;;) { |
| 2250 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | 2205 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&ts); |
| 2251 | if (status == -EINPROGRESS) | 2206 | if (status == -EINPROGRESS) |
| 2252 | break; | 2207 | break; |
| 2253 | if (status == -EIO) { | 2208 | if (status == -EIO) { |
| @@ -2257,12 +2212,13 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2257 | } | 2212 | } |
| 2258 | 2213 | ||
| 2259 | /* Skip beacon completions */ | 2214 | /* Skip beacon completions */ |
| 2260 | if (txs.qid == sc->beacon.beaconq) | 2215 | if (ts.qid == sc->beacon.beaconq) |
| 2261 | continue; | 2216 | continue; |
| 2262 | 2217 | ||
| 2263 | txq = &sc->tx.txq[txs.qid]; | 2218 | txq = &sc->tx.txq[ts.qid]; |
| 2264 | 2219 | ||
| 2265 | spin_lock_bh(&txq->axq_lock); | 2220 | spin_lock_bh(&txq->axq_lock); |
| 2221 | |||
| 2266 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | 2222 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
| 2267 | spin_unlock_bh(&txq->axq_lock); | 2223 | spin_unlock_bh(&txq->axq_lock); |
| 2268 | return; | 2224 | return; |
| @@ -2275,41 +2231,21 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
| 2275 | INIT_LIST_HEAD(&bf_head); | 2231 | INIT_LIST_HEAD(&bf_head); |
| 2276 | list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], | 2232 | list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], |
| 2277 | &lastbf->list); | 2233 | &lastbf->list); |
| 2278 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | ||
| 2279 | txq->axq_depth--; | ||
| 2280 | txq->axq_tx_inprogress = false; | ||
| 2281 | if (bf_is_ampdu_not_probing(bf)) | ||
| 2282 | txq->axq_ampdu_depth--; | ||
| 2283 | spin_unlock_bh(&txq->axq_lock); | ||
| 2284 | 2234 | ||
| 2285 | txok = !(txs.ts_status & ATH9K_TXERR_MASK); | 2235 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
| 2286 | 2236 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | |
| 2287 | if (!bf_isampdu(bf)) { | ||
| 2288 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | ||
| 2289 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
| 2290 | ath_tx_rc_status(sc, bf, &txs, 1, txok ? 0 : 1, txok, true); | ||
| 2291 | } | ||
| 2292 | |||
| 2293 | if (bf_isampdu(bf)) | ||
| 2294 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, | ||
| 2295 | txok, true); | ||
| 2296 | else | ||
| 2297 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | ||
| 2298 | &txs, txok, 0); | ||
| 2299 | 2237 | ||
| 2300 | spin_lock_bh(&txq->axq_lock); | 2238 | if (!list_empty(&txq->axq_q)) { |
| 2239 | struct list_head bf_q; | ||
| 2301 | 2240 | ||
| 2302 | if (!list_empty(&txq->txq_fifo_pending)) { | 2241 | INIT_LIST_HEAD(&bf_q); |
| 2303 | INIT_LIST_HEAD(&bf_head); | 2242 | txq->axq_link = NULL; |
| 2304 | bf = list_first_entry(&txq->txq_fifo_pending, | 2243 | list_splice_tail_init(&txq->axq_q, &bf_q); |
| 2305 | struct ath_buf, list); | 2244 | ath_tx_txqaddbuf(sc, txq, &bf_q, true); |
| 2306 | list_cut_position(&bf_head, | 2245 | } |
| 2307 | &txq->txq_fifo_pending, | 2246 | } |
| 2308 | &bf->bf_lastbf->list); | ||
| 2309 | ath_tx_txqaddbuf(sc, txq, &bf_head); | ||
| 2310 | } else if (sc->sc_flags & SC_OP_TXAGGR) | ||
| 2311 | ath_txq_schedule(sc, txq); | ||
| 2312 | 2247 | ||
| 2248 | ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); | ||
| 2313 | spin_unlock_bh(&txq->axq_lock); | 2249 | spin_unlock_bh(&txq->axq_lock); |
| 2314 | } | 2250 | } |
| 2315 | } | 2251 | } |
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index 480595f04411..fe26bf448fdb 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig | |||
| @@ -26,6 +26,11 @@ config B43 | |||
| 26 | This driver can be built as a module (recommended) that will be called "b43". | 26 | This driver can be built as a module (recommended) that will be called "b43". |
| 27 | If unsure, say M. | 27 | If unsure, say M. |
| 28 | 28 | ||
| 29 | config B43_BCMA | ||
| 30 | bool "Support for BCMA bus" | ||
| 31 | depends on B43 && BCMA && BROKEN | ||
| 32 | default y | ||
| 33 | |||
| 29 | # Auto-select SSB PCI-HOST support, if possible | 34 | # Auto-select SSB PCI-HOST support, if possible |
| 30 | config B43_PCI_AUTOSELECT | 35 | config B43_PCI_AUTOSELECT |
| 31 | bool | 36 | bool |
diff --git a/drivers/net/wireless/b43/Makefile b/drivers/net/wireless/b43/Makefile index cef334a8c669..95f7c001fda1 100644 --- a/drivers/net/wireless/b43/Makefile +++ b/drivers/net/wireless/b43/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | b43-y += main.o | 1 | b43-y += main.o |
| 2 | b43-y += bus.o | ||
| 2 | b43-y += tables.o | 3 | b43-y += tables.o |
| 3 | b43-$(CONFIG_B43_PHY_N) += tables_nphy.o | 4 | b43-$(CONFIG_B43_PHY_N) += tables_nphy.o |
| 4 | b43-$(CONFIG_B43_PHY_N) += radio_2055.o | 5 | b43-$(CONFIG_B43_PHY_N) += radio_2055.o |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 25a78cfb7d15..1cb2ddee9dcf 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
| @@ -5,12 +5,14 @@ | |||
| 5 | #include <linux/spinlock.h> | 5 | #include <linux/spinlock.h> |
| 6 | #include <linux/interrupt.h> | 6 | #include <linux/interrupt.h> |
| 7 | #include <linux/hw_random.h> | 7 | #include <linux/hw_random.h> |
| 8 | #include <linux/bcma/bcma.h> | ||
| 8 | #include <linux/ssb/ssb.h> | 9 | #include <linux/ssb/ssb.h> |
| 9 | #include <net/mac80211.h> | 10 | #include <net/mac80211.h> |
| 10 | 11 | ||
| 11 | #include "debugfs.h" | 12 | #include "debugfs.h" |
| 12 | #include "leds.h" | 13 | #include "leds.h" |
| 13 | #include "rfkill.h" | 14 | #include "rfkill.h" |
| 15 | #include "bus.h" | ||
| 14 | #include "lo.h" | 16 | #include "lo.h" |
| 15 | #include "phy_common.h" | 17 | #include "phy_common.h" |
| 16 | 18 | ||
| @@ -414,6 +416,17 @@ enum { | |||
| 414 | #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ | 416 | #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ |
| 415 | #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ | 417 | #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ |
| 416 | 418 | ||
| 419 | /* BCMA 802.11 core specific IO Control (BCMA_IOCTL) flags */ | ||
| 420 | #define B43_BCMA_IOCTL_PHY_CLKEN 0x00000004 /* PHY Clock Enable */ | ||
| 421 | #define B43_BCMA_IOCTL_PHY_RESET 0x00000008 /* PHY Reset */ | ||
| 422 | #define B43_BCMA_IOCTL_MACPHYCLKEN 0x00000010 /* MAC PHY Clock Control Enable */ | ||
| 423 | #define B43_BCMA_IOCTL_PLLREFSEL 0x00000020 /* PLL Frequency Reference Select */ | ||
| 424 | #define B43_BCMA_IOCTL_PHY_BW 0x000000C0 /* PHY band width and clock speed mask (N-PHY+ only?) */ | ||
| 425 | #define B43_BCMA_IOCTL_PHY_BW_10MHZ 0x00000000 /* 10 MHz bandwidth, 40 MHz PHY */ | ||
| 426 | #define B43_BCMA_IOCTL_PHY_BW_20MHZ 0x00000040 /* 20 MHz bandwidth, 80 MHz PHY */ | ||
| 427 | #define B43_BCMA_IOCTL_PHY_BW_40MHZ 0x00000080 /* 40 MHz bandwidth, 160 MHz PHY */ | ||
| 428 | #define B43_BCMA_IOCTL_GMODE 0x00002000 /* G Mode Enable */ | ||
| 429 | |||
| 417 | /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ | 430 | /* 802.11 core specific TM State Low (SSB_TMSLOW) flags */ |
| 418 | #define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ | 431 | #define B43_TMSLOW_GMODE 0x20000000 /* G Mode Enable */ |
| 419 | #define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */ | 432 | #define B43_TMSLOW_PHY_BANDWIDTH 0x00C00000 /* PHY band width and clock speed mask (N-PHY only) */ |
| @@ -707,7 +720,8 @@ enum { | |||
| 707 | 720 | ||
| 708 | /* Data structure for one wireless device (802.11 core) */ | 721 | /* Data structure for one wireless device (802.11 core) */ |
| 709 | struct b43_wldev { | 722 | struct b43_wldev { |
| 710 | struct ssb_device *sdev; | 723 | struct ssb_device *sdev; /* TODO: remove when b43_bus_dev is ready */ |
| 724 | struct b43_bus_dev *dev; | ||
| 711 | struct b43_wl *wl; | 725 | struct b43_wl *wl; |
| 712 | 726 | ||
| 713 | /* The device initialization status. | 727 | /* The device initialization status. |
| @@ -879,36 +893,59 @@ static inline enum ieee80211_band b43_current_band(struct b43_wl *wl) | |||
| 879 | return wl->hw->conf.channel->band; | 893 | return wl->hw->conf.channel->band; |
| 880 | } | 894 | } |
| 881 | 895 | ||
| 896 | static inline int b43_bus_may_powerdown(struct b43_wldev *wldev) | ||
| 897 | { | ||
| 898 | return wldev->dev->bus_may_powerdown(wldev->dev); | ||
| 899 | } | ||
| 900 | static inline int b43_bus_powerup(struct b43_wldev *wldev, bool dynamic_pctl) | ||
| 901 | { | ||
| 902 | return wldev->dev->bus_powerup(wldev->dev, dynamic_pctl); | ||
| 903 | } | ||
| 904 | static inline int b43_device_is_enabled(struct b43_wldev *wldev) | ||
| 905 | { | ||
| 906 | return wldev->dev->device_is_enabled(wldev->dev); | ||
| 907 | } | ||
| 908 | static inline void b43_device_enable(struct b43_wldev *wldev, | ||
| 909 | u32 core_specific_flags) | ||
| 910 | { | ||
| 911 | wldev->dev->device_enable(wldev->dev, core_specific_flags); | ||
| 912 | } | ||
| 913 | static inline void b43_device_disable(struct b43_wldev *wldev, | ||
| 914 | u32 core_specific_flags) | ||
| 915 | { | ||
| 916 | wldev->dev->device_disable(wldev->dev, core_specific_flags); | ||
| 917 | } | ||
| 918 | |||
| 882 | static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) | 919 | static inline u16 b43_read16(struct b43_wldev *dev, u16 offset) |
| 883 | { | 920 | { |
| 884 | return ssb_read16(dev->sdev, offset); | 921 | return dev->dev->read16(dev->dev, offset); |
| 885 | } | 922 | } |
| 886 | 923 | ||
| 887 | static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) | 924 | static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) |
| 888 | { | 925 | { |
| 889 | ssb_write16(dev->sdev, offset, value); | 926 | dev->dev->write16(dev->dev, offset, value); |
| 890 | } | 927 | } |
| 891 | 928 | ||
| 892 | static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) | 929 | static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) |
| 893 | { | 930 | { |
| 894 | return ssb_read32(dev->sdev, offset); | 931 | return dev->dev->read32(dev->dev, offset); |
| 895 | } | 932 | } |
| 896 | 933 | ||
| 897 | static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) | 934 | static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) |
| 898 | { | 935 | { |
| 899 | ssb_write32(dev->sdev, offset, value); | 936 | dev->dev->write32(dev->dev, offset, value); |
| 900 | } | 937 | } |
| 901 | 938 | ||
| 902 | static inline void b43_block_read(struct b43_wldev *dev, void *buffer, | 939 | static inline void b43_block_read(struct b43_wldev *dev, void *buffer, |
| 903 | size_t count, u16 offset, u8 reg_width) | 940 | size_t count, u16 offset, u8 reg_width) |
| 904 | { | 941 | { |
| 905 | ssb_block_read(dev->sdev, buffer, count, offset, reg_width); | 942 | dev->dev->block_read(dev->dev, buffer, count, offset, reg_width); |
| 906 | } | 943 | } |
| 907 | 944 | ||
| 908 | static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, | 945 | static inline void b43_block_write(struct b43_wldev *dev, const void *buffer, |
| 909 | size_t count, u16 offset, u8 reg_width) | 946 | size_t count, u16 offset, u8 reg_width) |
| 910 | { | 947 | { |
| 911 | ssb_block_write(dev->sdev, buffer, count, offset, reg_width); | 948 | dev->dev->block_write(dev->dev, buffer, count, offset, reg_width); |
| 912 | } | 949 | } |
| 913 | 950 | ||
| 914 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) | 951 | static inline bool b43_using_pio_transfers(struct b43_wldev *dev) |
diff --git a/drivers/net/wireless/b43/bus.c b/drivers/net/wireless/b43/bus.c new file mode 100644 index 000000000000..6c63aecd6ab4 --- /dev/null +++ b/drivers/net/wireless/b43/bus.c | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /* | ||
| 2 | |||
| 3 | Broadcom B43 wireless driver | ||
| 4 | Bus abstraction layer | ||
| 5 | |||
| 6 | This program is free software; you can redistribute it and/or modify | ||
| 7 | it under the terms of the GNU General Public License as published by | ||
| 8 | the Free Software Foundation; either version 2 of the License, or | ||
| 9 | (at your option) any later version. | ||
| 10 | |||
| 11 | This program is distributed in the hope that it will be useful, | ||
| 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | GNU General Public License for more details. | ||
| 15 | |||
| 16 | You should have received a copy of the GNU General Public License | ||
| 17 | along with this program; see the file COPYING. If not, write to | ||
| 18 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
| 19 | Boston, MA 02110-1301, USA. | ||
| 20 | |||
| 21 | */ | ||
| 22 | |||
| 23 | #include "b43.h" | ||
| 24 | #include "bus.h" | ||
| 25 | |||
| 26 | |||
| 27 | /* SSB */ | ||
| 28 | |||
| 29 | static inline int b43_bus_ssb_bus_may_powerdown(struct b43_bus_dev *dev) | ||
| 30 | { | ||
| 31 | return ssb_bus_may_powerdown(dev->sdev->bus); | ||
| 32 | } | ||
| 33 | static inline int b43_bus_ssb_bus_powerup(struct b43_bus_dev *dev, | ||
| 34 | bool dynamic_pctl) | ||
| 35 | { | ||
| 36 | return ssb_bus_powerup(dev->sdev->bus, dynamic_pctl); | ||
| 37 | } | ||
| 38 | static inline int b43_bus_ssb_device_is_enabled(struct b43_bus_dev *dev) | ||
| 39 | { | ||
| 40 | return ssb_device_is_enabled(dev->sdev); | ||
| 41 | } | ||
| 42 | static inline void b43_bus_ssb_device_enable(struct b43_bus_dev *dev, | ||
| 43 | u32 core_specific_flags) | ||
| 44 | { | ||
| 45 | ssb_device_enable(dev->sdev, core_specific_flags); | ||
| 46 | } | ||
| 47 | static inline void b43_bus_ssb_device_disable(struct b43_bus_dev *dev, | ||
| 48 | u32 core_specific_flags) | ||
| 49 | { | ||
| 50 | ssb_device_disable(dev->sdev, core_specific_flags); | ||
| 51 | } | ||
| 52 | |||
| 53 | static inline u16 b43_bus_ssb_read16(struct b43_bus_dev *dev, u16 offset) | ||
| 54 | { | ||
| 55 | return ssb_read16(dev->sdev, offset); | ||
| 56 | } | ||
| 57 | static inline u32 b43_bus_ssb_read32(struct b43_bus_dev *dev, u16 offset) | ||
| 58 | { | ||
| 59 | return ssb_read32(dev->sdev, offset); | ||
| 60 | } | ||
| 61 | static inline | ||
| 62 | void b43_bus_ssb_write16(struct b43_bus_dev *dev, u16 offset, u16 value) | ||
| 63 | { | ||
| 64 | ssb_write16(dev->sdev, offset, value); | ||
| 65 | } | ||
| 66 | static inline | ||
| 67 | void b43_bus_ssb_write32(struct b43_bus_dev *dev, u16 offset, u32 value) | ||
| 68 | { | ||
| 69 | ssb_write32(dev->sdev, offset, value); | ||
| 70 | } | ||
| 71 | static inline | ||
| 72 | void b43_bus_ssb_block_read(struct b43_bus_dev *dev, void *buffer, | ||
| 73 | size_t count, u16 offset, u8 reg_width) | ||
| 74 | { | ||
| 75 | ssb_block_read(dev->sdev, buffer, count, offset, reg_width); | ||
| 76 | } | ||
| 77 | static inline | ||
| 78 | void b43_bus_ssb_block_write(struct b43_bus_dev *dev, const void *buffer, | ||
| 79 | size_t count, u16 offset, u8 reg_width) | ||
| 80 | { | ||
| 81 | ssb_block_write(dev->sdev, buffer, count, offset, reg_width); | ||
| 82 | } | ||
| 83 | |||
| 84 | struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev) | ||
| 85 | { | ||
| 86 | struct b43_bus_dev *dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
| 87 | |||
| 88 | dev->bus_type = B43_BUS_SSB; | ||
| 89 | dev->sdev = sdev; | ||
| 90 | |||
| 91 | dev->bus_may_powerdown = b43_bus_ssb_bus_may_powerdown; | ||
| 92 | dev->bus_powerup = b43_bus_ssb_bus_powerup; | ||
| 93 | dev->device_is_enabled = b43_bus_ssb_device_is_enabled; | ||
| 94 | dev->device_enable = b43_bus_ssb_device_enable; | ||
| 95 | dev->device_disable = b43_bus_ssb_device_disable; | ||
| 96 | |||
| 97 | dev->read16 = b43_bus_ssb_read16; | ||
| 98 | dev->read32 = b43_bus_ssb_read32; | ||
| 99 | dev->write16 = b43_bus_ssb_write16; | ||
| 100 | dev->write32 = b43_bus_ssb_write32; | ||
| 101 | dev->block_read = b43_bus_ssb_block_read; | ||
| 102 | dev->block_write = b43_bus_ssb_block_write; | ||
| 103 | |||
| 104 | dev->dev = sdev->dev; | ||
| 105 | dev->dma_dev = sdev->dma_dev; | ||
| 106 | dev->irq = sdev->irq; | ||
| 107 | |||
| 108 | dev->board_vendor = sdev->bus->boardinfo.vendor; | ||
| 109 | dev->board_type = sdev->bus->boardinfo.type; | ||
| 110 | dev->board_rev = sdev->bus->boardinfo.rev; | ||
| 111 | |||
| 112 | dev->chip_id = sdev->bus->chip_id; | ||
| 113 | dev->chip_rev = sdev->bus->chip_rev; | ||
| 114 | dev->chip_pkg = sdev->bus->chip_package; | ||
| 115 | |||
| 116 | dev->bus_sprom = &sdev->bus->sprom; | ||
| 117 | |||
| 118 | dev->core_id = sdev->id.coreid; | ||
| 119 | dev->core_rev = sdev->id.revision; | ||
| 120 | |||
| 121 | return dev; | ||
| 122 | } | ||
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h new file mode 100644 index 000000000000..79a5ab4270c3 --- /dev/null +++ b/drivers/net/wireless/b43/bus.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | #ifndef B43_BUS_H_ | ||
| 2 | #define B43_BUS_H_ | ||
| 3 | |||
| 4 | enum b43_bus_type { | ||
| 5 | B43_BUS_SSB, | ||
| 6 | }; | ||
| 7 | |||
| 8 | struct b43_bus_dev { | ||
| 9 | enum b43_bus_type bus_type; | ||
| 10 | union { | ||
| 11 | struct ssb_device *sdev; | ||
| 12 | }; | ||
| 13 | |||
| 14 | int (*bus_may_powerdown)(struct b43_bus_dev *dev); | ||
| 15 | int (*bus_powerup)(struct b43_bus_dev *dev, bool dynamic_pctl); | ||
| 16 | int (*device_is_enabled)(struct b43_bus_dev *dev); | ||
| 17 | void (*device_enable)(struct b43_bus_dev *dev, | ||
| 18 | u32 core_specific_flags); | ||
| 19 | void (*device_disable)(struct b43_bus_dev *dev, | ||
| 20 | u32 core_specific_flags); | ||
| 21 | |||
| 22 | u16 (*read16)(struct b43_bus_dev *dev, u16 offset); | ||
| 23 | u32 (*read32)(struct b43_bus_dev *dev, u16 offset); | ||
| 24 | void (*write16)(struct b43_bus_dev *dev, u16 offset, u16 value); | ||
| 25 | void (*write32)(struct b43_bus_dev *dev, u16 offset, u32 value); | ||
| 26 | void (*block_read)(struct b43_bus_dev *dev, void *buffer, | ||
| 27 | size_t count, u16 offset, u8 reg_width); | ||
| 28 | void (*block_write)(struct b43_bus_dev *dev, const void *buffer, | ||
| 29 | size_t count, u16 offset, u8 reg_width); | ||
| 30 | |||
| 31 | struct device *dev; | ||
| 32 | struct device *dma_dev; | ||
| 33 | unsigned int irq; | ||
| 34 | |||
| 35 | u16 board_vendor; | ||
| 36 | u16 board_type; | ||
| 37 | u16 board_rev; | ||
| 38 | |||
| 39 | u16 chip_id; | ||
| 40 | u8 chip_rev; | ||
| 41 | u8 chip_pkg; | ||
| 42 | |||
| 43 | struct ssb_sprom *bus_sprom; | ||
| 44 | |||
| 45 | u16 core_id; | ||
| 46 | u8 core_rev; | ||
| 47 | }; | ||
| 48 | |||
| 49 | static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev) | ||
| 50 | { | ||
| 51 | return (dev->bus_type == B43_BUS_SSB && | ||
| 52 | dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA); | ||
| 53 | } | ||
| 54 | static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) | ||
| 55 | { | ||
| 56 | return (dev->bus_type == B43_BUS_SSB && | ||
| 57 | dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); | ||
| 58 | } | ||
| 59 | |||
| 60 | struct b43_bus_dev *b43_bus_dev_ssb_init(struct ssb_device *sdev); | ||
| 61 | |||
| 62 | #endif /* B43_BUS_H_ */ | ||
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 47d44bcff37d..d02cf8300e3e 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
| @@ -333,10 +333,10 @@ static inline | |||
| 333 | dma_addr_t dmaaddr; | 333 | dma_addr_t dmaaddr; |
| 334 | 334 | ||
| 335 | if (tx) { | 335 | if (tx) { |
| 336 | dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, | 336 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, |
| 337 | buf, len, DMA_TO_DEVICE); | 337 | buf, len, DMA_TO_DEVICE); |
| 338 | } else { | 338 | } else { |
| 339 | dmaaddr = dma_map_single(ring->dev->sdev->dma_dev, | 339 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, |
| 340 | buf, len, DMA_FROM_DEVICE); | 340 | buf, len, DMA_FROM_DEVICE); |
| 341 | } | 341 | } |
| 342 | 342 | ||
| @@ -348,10 +348,10 @@ static inline | |||
| 348 | dma_addr_t addr, size_t len, int tx) | 348 | dma_addr_t addr, size_t len, int tx) |
| 349 | { | 349 | { |
| 350 | if (tx) { | 350 | if (tx) { |
| 351 | dma_unmap_single(ring->dev->sdev->dma_dev, | 351 | dma_unmap_single(ring->dev->dev->dma_dev, |
| 352 | addr, len, DMA_TO_DEVICE); | 352 | addr, len, DMA_TO_DEVICE); |
| 353 | } else { | 353 | } else { |
| 354 | dma_unmap_single(ring->dev->sdev->dma_dev, | 354 | dma_unmap_single(ring->dev->dev->dma_dev, |
| 355 | addr, len, DMA_FROM_DEVICE); | 355 | addr, len, DMA_FROM_DEVICE); |
| 356 | } | 356 | } |
| 357 | } | 357 | } |
| @@ -361,7 +361,7 @@ static inline | |||
| 361 | dma_addr_t addr, size_t len) | 361 | dma_addr_t addr, size_t len) |
| 362 | { | 362 | { |
| 363 | B43_WARN_ON(ring->tx); | 363 | B43_WARN_ON(ring->tx); |
| 364 | dma_sync_single_for_cpu(ring->dev->sdev->dma_dev, | 364 | dma_sync_single_for_cpu(ring->dev->dev->dma_dev, |
| 365 | addr, len, DMA_FROM_DEVICE); | 365 | addr, len, DMA_FROM_DEVICE); |
| 366 | } | 366 | } |
| 367 | 367 | ||
| @@ -370,7 +370,7 @@ static inline | |||
| 370 | dma_addr_t addr, size_t len) | 370 | dma_addr_t addr, size_t len) |
| 371 | { | 371 | { |
| 372 | B43_WARN_ON(ring->tx); | 372 | B43_WARN_ON(ring->tx); |
| 373 | dma_sync_single_for_device(ring->dev->sdev->dma_dev, | 373 | dma_sync_single_for_device(ring->dev->dev->dma_dev, |
| 374 | addr, len, DMA_FROM_DEVICE); | 374 | addr, len, DMA_FROM_DEVICE); |
| 375 | } | 375 | } |
| 376 | 376 | ||
| @@ -401,7 +401,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
| 401 | */ | 401 | */ |
| 402 | if (ring->type == B43_DMA_64BIT) | 402 | if (ring->type == B43_DMA_64BIT) |
| 403 | flags |= GFP_DMA; | 403 | flags |= GFP_DMA; |
| 404 | ring->descbase = dma_alloc_coherent(ring->dev->sdev->dma_dev, | 404 | ring->descbase = dma_alloc_coherent(ring->dev->dev->dma_dev, |
| 405 | B43_DMA_RINGMEMSIZE, | 405 | B43_DMA_RINGMEMSIZE, |
| 406 | &(ring->dmabase), flags); | 406 | &(ring->dmabase), flags); |
| 407 | if (!ring->descbase) { | 407 | if (!ring->descbase) { |
| @@ -415,7 +415,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
| 415 | 415 | ||
| 416 | static void free_ringmemory(struct b43_dmaring *ring) | 416 | static void free_ringmemory(struct b43_dmaring *ring) |
| 417 | { | 417 | { |
| 418 | dma_free_coherent(ring->dev->sdev->dma_dev, B43_DMA_RINGMEMSIZE, | 418 | dma_free_coherent(ring->dev->dev->dma_dev, B43_DMA_RINGMEMSIZE, |
| 419 | ring->descbase, ring->dmabase); | 419 | ring->descbase, ring->dmabase); |
| 420 | } | 420 | } |
| 421 | 421 | ||
| @@ -523,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
| 523 | dma_addr_t addr, | 523 | dma_addr_t addr, |
| 524 | size_t buffersize, bool dma_to_device) | 524 | size_t buffersize, bool dma_to_device) |
| 525 | { | 525 | { |
| 526 | if (unlikely(dma_mapping_error(ring->dev->sdev->dma_dev, addr))) | 526 | if (unlikely(dma_mapping_error(ring->dev->dev->dma_dev, addr))) |
| 527 | return 1; | 527 | return 1; |
| 528 | 528 | ||
| 529 | switch (ring->type) { | 529 | switch (ring->type) { |
| @@ -757,14 +757,14 @@ static void dmacontroller_cleanup(struct b43_dmaring *ring) | |||
| 757 | 757 | ||
| 758 | static void free_all_descbuffers(struct b43_dmaring *ring) | 758 | static void free_all_descbuffers(struct b43_dmaring *ring) |
| 759 | { | 759 | { |
| 760 | struct b43_dmadesc_generic *desc; | ||
| 761 | struct b43_dmadesc_meta *meta; | 760 | struct b43_dmadesc_meta *meta; |
| 762 | int i; | 761 | int i; |
| 763 | 762 | ||
| 764 | if (!ring->used_slots) | 763 | if (!ring->used_slots) |
| 765 | return; | 764 | return; |
| 766 | for (i = 0; i < ring->nr_slots; i++) { | 765 | for (i = 0; i < ring->nr_slots; i++) { |
| 767 | desc = ring->ops->idx2desc(ring, i, &meta); | 766 | /* get meta - ignore returned value */ |
| 767 | ring->ops->idx2desc(ring, i, &meta); | ||
| 768 | 768 | ||
| 769 | if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { | 769 | if (!meta->skb || b43_dma_ptr_is_poisoned(meta->skb)) { |
| 770 | B43_WARN_ON(!ring->tx); | 770 | B43_WARN_ON(!ring->tx); |
| @@ -869,7 +869,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
| 869 | goto err_kfree_meta; | 869 | goto err_kfree_meta; |
| 870 | 870 | ||
| 871 | /* test for ability to dma to txhdr_cache */ | 871 | /* test for ability to dma to txhdr_cache */ |
| 872 | dma_test = dma_map_single(dev->sdev->dma_dev, | 872 | dma_test = dma_map_single(dev->dev->dma_dev, |
| 873 | ring->txhdr_cache, | 873 | ring->txhdr_cache, |
| 874 | b43_txhdr_size(dev), | 874 | b43_txhdr_size(dev), |
| 875 | DMA_TO_DEVICE); | 875 | DMA_TO_DEVICE); |
| @@ -884,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
| 884 | if (!ring->txhdr_cache) | 884 | if (!ring->txhdr_cache) |
| 885 | goto err_kfree_meta; | 885 | goto err_kfree_meta; |
| 886 | 886 | ||
| 887 | dma_test = dma_map_single(dev->sdev->dma_dev, | 887 | dma_test = dma_map_single(dev->dev->dma_dev, |
| 888 | ring->txhdr_cache, | 888 | ring->txhdr_cache, |
| 889 | b43_txhdr_size(dev), | 889 | b43_txhdr_size(dev), |
| 890 | DMA_TO_DEVICE); | 890 | DMA_TO_DEVICE); |
| @@ -898,7 +898,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
| 898 | } | 898 | } |
| 899 | } | 899 | } |
| 900 | 900 | ||
| 901 | dma_unmap_single(dev->sdev->dma_dev, | 901 | dma_unmap_single(dev->dev->dma_dev, |
| 902 | dma_test, b43_txhdr_size(dev), | 902 | dma_test, b43_txhdr_size(dev), |
| 903 | DMA_TO_DEVICE); | 903 | DMA_TO_DEVICE); |
| 904 | } | 904 | } |
| @@ -1013,9 +1013,9 @@ static int b43_dma_set_mask(struct b43_wldev *dev, u64 mask) | |||
| 1013 | /* Try to set the DMA mask. If it fails, try falling back to a | 1013 | /* Try to set the DMA mask. If it fails, try falling back to a |
| 1014 | * lower mask, as we can always also support a lower one. */ | 1014 | * lower mask, as we can always also support a lower one. */ |
| 1015 | while (1) { | 1015 | while (1) { |
| 1016 | err = dma_set_mask(dev->sdev->dma_dev, mask); | 1016 | err = dma_set_mask(dev->dev->dma_dev, mask); |
| 1017 | if (!err) { | 1017 | if (!err) { |
| 1018 | err = dma_set_coherent_mask(dev->sdev->dma_dev, mask); | 1018 | err = dma_set_coherent_mask(dev->dev->dma_dev, mask); |
| 1019 | if (!err) | 1019 | if (!err) |
| 1020 | break; | 1020 | break; |
| 1021 | } | 1021 | } |
| @@ -1085,7 +1085,7 @@ int b43_dma_init(struct b43_wldev *dev) | |||
| 1085 | goto err_destroy_mcast; | 1085 | goto err_destroy_mcast; |
| 1086 | 1086 | ||
| 1087 | /* No support for the TX status DMA ring. */ | 1087 | /* No support for the TX status DMA ring. */ |
| 1088 | B43_WARN_ON(dev->sdev->id.revision < 5); | 1088 | B43_WARN_ON(dev->dev->core_rev < 5); |
| 1089 | 1089 | ||
| 1090 | b43dbg(dev->wl, "%u-bit DMA initialized\n", | 1090 | b43dbg(dev->wl, "%u-bit DMA initialized\n", |
| 1091 | (unsigned int)type); | 1091 | (unsigned int)type); |
| @@ -1388,7 +1388,6 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
| 1388 | { | 1388 | { |
| 1389 | const struct b43_dma_ops *ops; | 1389 | const struct b43_dma_ops *ops; |
| 1390 | struct b43_dmaring *ring; | 1390 | struct b43_dmaring *ring; |
| 1391 | struct b43_dmadesc_generic *desc; | ||
| 1392 | struct b43_dmadesc_meta *meta; | 1391 | struct b43_dmadesc_meta *meta; |
| 1393 | int slot, firstused; | 1392 | int slot, firstused; |
| 1394 | bool frame_succeed; | 1393 | bool frame_succeed; |
| @@ -1416,7 +1415,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev, | |||
| 1416 | ops = ring->ops; | 1415 | ops = ring->ops; |
| 1417 | while (1) { | 1416 | while (1) { |
| 1418 | B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); | 1417 | B43_WARN_ON(slot < 0 || slot >= ring->nr_slots); |
| 1419 | desc = ops->idx2desc(ring, slot, &meta); | 1418 | /* get meta - ignore returned value */ |
| 1419 | ops->idx2desc(ring, slot, &meta); | ||
| 1420 | 1420 | ||
| 1421 | if (b43_dma_ptr_is_poisoned(meta->skb)) { | 1421 | if (b43_dma_ptr_is_poisoned(meta->skb)) { |
| 1422 | b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " | 1422 | b43dbg(dev->wl, "Poisoned TX slot %d (first=%d) " |
diff --git a/drivers/net/wireless/b43/leds.c b/drivers/net/wireless/b43/leds.c index 0cafafe368af..b56ed41fc1bd 100644 --- a/drivers/net/wireless/b43/leds.c +++ b/drivers/net/wireless/b43/leds.c | |||
| @@ -138,7 +138,7 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led, | |||
| 138 | led->led_dev.default_trigger = default_trigger; | 138 | led->led_dev.default_trigger = default_trigger; |
| 139 | led->led_dev.brightness_set = b43_led_brightness_set; | 139 | led->led_dev.brightness_set = b43_led_brightness_set; |
| 140 | 140 | ||
| 141 | err = led_classdev_register(dev->sdev->dev, &led->led_dev); | 141 | err = led_classdev_register(dev->dev->dev, &led->led_dev); |
| 142 | if (err) { | 142 | if (err) { |
| 143 | b43warn(dev->wl, "LEDs: Failed to register %s\n", name); | 143 | b43warn(dev->wl, "LEDs: Failed to register %s\n", name); |
| 144 | led->wl = NULL; | 144 | led->wl = NULL; |
| @@ -215,13 +215,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, | |||
| 215 | enum b43_led_behaviour *behaviour, | 215 | enum b43_led_behaviour *behaviour, |
| 216 | bool *activelow) | 216 | bool *activelow) |
| 217 | { | 217 | { |
| 218 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 219 | u8 sprom[4]; | 218 | u8 sprom[4]; |
| 220 | 219 | ||
| 221 | sprom[0] = bus->sprom.gpio0; | 220 | sprom[0] = dev->dev->bus_sprom->gpio0; |
| 222 | sprom[1] = bus->sprom.gpio1; | 221 | sprom[1] = dev->dev->bus_sprom->gpio1; |
| 223 | sprom[2] = bus->sprom.gpio2; | 222 | sprom[2] = dev->dev->bus_sprom->gpio2; |
| 224 | sprom[3] = bus->sprom.gpio3; | 223 | sprom[3] = dev->dev->bus_sprom->gpio3; |
| 225 | 224 | ||
| 226 | if (sprom[led_index] == 0xFF) { | 225 | if (sprom[led_index] == 0xFF) { |
| 227 | /* There is no LED information in the SPROM | 226 | /* There is no LED information in the SPROM |
| @@ -231,12 +230,12 @@ static void b43_led_get_sprominfo(struct b43_wldev *dev, | |||
| 231 | case 0: | 230 | case 0: |
| 232 | *behaviour = B43_LED_ACTIVITY; | 231 | *behaviour = B43_LED_ACTIVITY; |
| 233 | *activelow = 1; | 232 | *activelow = 1; |
| 234 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ) | 233 | if (dev->dev->board_vendor == PCI_VENDOR_ID_COMPAQ) |
| 235 | *behaviour = B43_LED_RADIO_ALL; | 234 | *behaviour = B43_LED_RADIO_ALL; |
| 236 | break; | 235 | break; |
| 237 | case 1: | 236 | case 1: |
| 238 | *behaviour = B43_LED_RADIO_B; | 237 | *behaviour = B43_LED_RADIO_B; |
| 239 | if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK) | 238 | if (dev->dev->board_vendor == PCI_VENDOR_ID_ASUSTEK) |
| 240 | *behaviour = B43_LED_ASSOC; | 239 | *behaviour = B43_LED_ASSOC; |
| 241 | break; | 240 | break; |
| 242 | case 2: | 241 | case 2: |
diff --git a/drivers/net/wireless/b43/lo.c b/drivers/net/wireless/b43/lo.c index 2ef7d4b38540..a3dc8bb8ca95 100644 --- a/drivers/net/wireless/b43/lo.c +++ b/drivers/net/wireless/b43/lo.c | |||
| @@ -98,7 +98,7 @@ static u16 lo_measure_feedthrough(struct b43_wldev *dev, | |||
| 98 | rfover |= pga; | 98 | rfover |= pga; |
| 99 | rfover |= lna; | 99 | rfover |= lna; |
| 100 | rfover |= trsw_rx; | 100 | rfover |= trsw_rx; |
| 101 | if ((dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) | 101 | if ((dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) |
| 102 | && phy->rev > 6) | 102 | && phy->rev > 6) |
| 103 | rfover |= B43_PHY_RFOVERVAL_EXTLNA; | 103 | rfover |= B43_PHY_RFOVERVAL_EXTLNA; |
| 104 | 104 | ||
| @@ -301,14 +301,12 @@ static void lo_measure_gain_values(struct b43_wldev *dev, | |||
| 301 | max_rx_gain = 0; | 301 | max_rx_gain = 0; |
| 302 | 302 | ||
| 303 | if (has_loopback_gain(phy)) { | 303 | if (has_loopback_gain(phy)) { |
| 304 | int trsw_rx = 0; | ||
| 305 | int trsw_rx_gain; | 304 | int trsw_rx_gain; |
| 306 | 305 | ||
| 307 | if (use_trsw_rx) { | 306 | if (use_trsw_rx) { |
| 308 | trsw_rx_gain = gphy->trsw_rx_gain / 2; | 307 | trsw_rx_gain = gphy->trsw_rx_gain / 2; |
| 309 | if (max_rx_gain >= trsw_rx_gain) { | 308 | if (max_rx_gain >= trsw_rx_gain) { |
| 310 | trsw_rx_gain = max_rx_gain - trsw_rx_gain; | 309 | trsw_rx_gain = max_rx_gain - trsw_rx_gain; |
| 311 | trsw_rx = 0x20; | ||
| 312 | } | 310 | } |
| 313 | } else | 311 | } else |
| 314 | trsw_rx_gain = max_rx_gain; | 312 | trsw_rx_gain = max_rx_gain; |
| @@ -387,7 +385,7 @@ struct lo_g_saved_values { | |||
| 387 | static void lo_measure_setup(struct b43_wldev *dev, | 385 | static void lo_measure_setup(struct b43_wldev *dev, |
| 388 | struct lo_g_saved_values *sav) | 386 | struct lo_g_saved_values *sav) |
| 389 | { | 387 | { |
| 390 | struct ssb_sprom *sprom = &dev->sdev->bus->sprom; | 388 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 391 | struct b43_phy *phy = &dev->phy; | 389 | struct b43_phy *phy = &dev->phy; |
| 392 | struct b43_phy_g *gphy = phy->g; | 390 | struct b43_phy_g *gphy = phy->g; |
| 393 | struct b43_txpower_lo_control *lo = gphy->lo_control; | 391 | struct b43_txpower_lo_control *lo = gphy->lo_control; |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index d74bc5ff8e13..cae31463ead9 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
| @@ -113,6 +113,16 @@ static int b43_modparam_pio = B43_PIO_DEFAULT; | |||
| 113 | module_param_named(pio, b43_modparam_pio, int, 0644); | 113 | module_param_named(pio, b43_modparam_pio, int, 0644); |
| 114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); | 114 | MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); |
| 115 | 115 | ||
| 116 | #ifdef CONFIG_B43_BCMA | ||
| 117 | static const struct bcma_device_id b43_bcma_tbl[] = { | ||
| 118 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), | ||
| 119 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), | ||
| 120 | BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), | ||
| 121 | BCMA_CORETABLE_END | ||
| 122 | }; | ||
| 123 | MODULE_DEVICE_TABLE(bcma, b43_bcma_tbl); | ||
| 124 | #endif | ||
| 125 | |||
| 116 | static const struct ssb_device_id b43_ssb_tbl[] = { | 126 | static const struct ssb_device_id b43_ssb_tbl[] = { |
| 117 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), | 127 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 5), |
| 118 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), | 128 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 6), |
| @@ -548,7 +558,7 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) | |||
| 548 | { | 558 | { |
| 549 | u32 low, high; | 559 | u32 low, high; |
| 550 | 560 | ||
| 551 | B43_WARN_ON(dev->sdev->id.revision < 3); | 561 | B43_WARN_ON(dev->dev->core_rev < 3); |
| 552 | 562 | ||
| 553 | /* The hardware guarantees us an atomic read, if we | 563 | /* The hardware guarantees us an atomic read, if we |
| 554 | * read the low register first. */ | 564 | * read the low register first. */ |
| @@ -586,7 +596,7 @@ static void b43_tsf_write_locked(struct b43_wldev *dev, u64 tsf) | |||
| 586 | { | 596 | { |
| 587 | u32 low, high; | 597 | u32 low, high; |
| 588 | 598 | ||
| 589 | B43_WARN_ON(dev->sdev->id.revision < 3); | 599 | B43_WARN_ON(dev->dev->core_rev < 3); |
| 590 | 600 | ||
| 591 | low = tsf; | 601 | low = tsf; |
| 592 | high = (tsf >> 32); | 602 | high = (tsf >> 32); |
| @@ -714,7 +724,7 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) | |||
| 714 | b43_ram_write(dev, i * 4, buffer[i]); | 724 | b43_ram_write(dev, i * 4, buffer[i]); |
| 715 | 725 | ||
| 716 | b43_write16(dev, 0x0568, 0x0000); | 726 | b43_write16(dev, 0x0568, 0x0000); |
| 717 | if (dev->sdev->id.revision < 11) | 727 | if (dev->dev->core_rev < 11) |
| 718 | b43_write16(dev, 0x07C0, 0x0000); | 728 | b43_write16(dev, 0x07C0, 0x0000); |
| 719 | else | 729 | else |
| 720 | b43_write16(dev, 0x07C0, 0x0100); | 730 | b43_write16(dev, 0x07C0, 0x0100); |
| @@ -1132,7 +1142,7 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
| 1132 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 1142 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
| 1133 | /* Commit write */ | 1143 | /* Commit write */ |
| 1134 | b43_read32(dev, B43_MMIO_MACCTL); | 1144 | b43_read32(dev, B43_MMIO_MACCTL); |
| 1135 | if (awake && dev->sdev->id.revision >= 5) { | 1145 | if (awake && dev->dev->core_rev >= 5) { |
| 1136 | /* Wait for the microcode to wake up. */ | 1146 | /* Wait for the microcode to wake up. */ |
| 1137 | for (i = 0; i < 100; i++) { | 1147 | for (i = 0; i < 100; i++) { |
| 1138 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, | 1148 | ucstat = b43_shm_read16(dev, B43_SHM_SHARED, |
| @@ -1144,35 +1154,39 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
| 1144 | } | 1154 | } |
| 1145 | } | 1155 | } |
| 1146 | 1156 | ||
| 1147 | static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, u32 flags) | 1157 | static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) |
| 1148 | { | 1158 | { |
| 1159 | struct ssb_device *sdev = dev->dev->sdev; | ||
| 1149 | u32 tmslow; | 1160 | u32 tmslow; |
| 1161 | u32 flags = 0; | ||
| 1150 | 1162 | ||
| 1163 | if (gmode) | ||
| 1164 | flags |= B43_TMSLOW_GMODE; | ||
| 1151 | flags |= B43_TMSLOW_PHYCLKEN; | 1165 | flags |= B43_TMSLOW_PHYCLKEN; |
| 1152 | flags |= B43_TMSLOW_PHYRESET; | 1166 | flags |= B43_TMSLOW_PHYRESET; |
| 1153 | if (dev->phy.type == B43_PHYTYPE_N) | 1167 | if (dev->phy.type == B43_PHYTYPE_N) |
| 1154 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ | 1168 | flags |= B43_TMSLOW_PHY_BANDWIDTH_20MHZ; /* Make 20 MHz def */ |
| 1155 | ssb_device_enable(dev->sdev, flags); | 1169 | b43_device_enable(dev, flags); |
| 1156 | msleep(2); /* Wait for the PLL to turn on. */ | 1170 | msleep(2); /* Wait for the PLL to turn on. */ |
| 1157 | 1171 | ||
| 1158 | /* Now take the PHY out of Reset again */ | 1172 | /* Now take the PHY out of Reset again */ |
| 1159 | tmslow = ssb_read32(dev->sdev, SSB_TMSLOW); | 1173 | tmslow = ssb_read32(sdev, SSB_TMSLOW); |
| 1160 | tmslow |= SSB_TMSLOW_FGC; | 1174 | tmslow |= SSB_TMSLOW_FGC; |
| 1161 | tmslow &= ~B43_TMSLOW_PHYRESET; | 1175 | tmslow &= ~B43_TMSLOW_PHYRESET; |
| 1162 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); | 1176 | ssb_write32(sdev, SSB_TMSLOW, tmslow); |
| 1163 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ | 1177 | ssb_read32(sdev, SSB_TMSLOW); /* flush */ |
| 1164 | msleep(1); | 1178 | msleep(1); |
| 1165 | tmslow &= ~SSB_TMSLOW_FGC; | 1179 | tmslow &= ~SSB_TMSLOW_FGC; |
| 1166 | ssb_write32(dev->sdev, SSB_TMSLOW, tmslow); | 1180 | ssb_write32(sdev, SSB_TMSLOW, tmslow); |
| 1167 | ssb_read32(dev->sdev, SSB_TMSLOW); /* flush */ | 1181 | ssb_read32(sdev, SSB_TMSLOW); /* flush */ |
| 1168 | msleep(1); | 1182 | msleep(1); |
| 1169 | } | 1183 | } |
| 1170 | 1184 | ||
| 1171 | void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | 1185 | void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) |
| 1172 | { | 1186 | { |
| 1173 | u32 macctl; | 1187 | u32 macctl; |
| 1174 | 1188 | ||
| 1175 | b43_ssb_wireless_core_reset(dev, flags); | 1189 | b43_ssb_wireless_core_reset(dev, gmode); |
| 1176 | 1190 | ||
| 1177 | /* Turn Analog ON, but only if we already know the PHY-type. | 1191 | /* Turn Analog ON, but only if we already know the PHY-type. |
| 1178 | * This protects against very early setup where we don't know the | 1192 | * This protects against very early setup where we don't know the |
| @@ -1183,7 +1197,7 @@ void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags) | |||
| 1183 | 1197 | ||
| 1184 | macctl = b43_read32(dev, B43_MMIO_MACCTL); | 1198 | macctl = b43_read32(dev, B43_MMIO_MACCTL); |
| 1185 | macctl &= ~B43_MACCTL_GMODE; | 1199 | macctl &= ~B43_MACCTL_GMODE; |
| 1186 | if (flags & B43_TMSLOW_GMODE) | 1200 | if (gmode) |
| 1187 | macctl |= B43_MACCTL_GMODE; | 1201 | macctl |= B43_MACCTL_GMODE; |
| 1188 | macctl |= B43_MACCTL_IHR_ENABLED; | 1202 | macctl |= B43_MACCTL_IHR_ENABLED; |
| 1189 | b43_write32(dev, B43_MMIO_MACCTL, macctl); | 1203 | b43_write32(dev, B43_MMIO_MACCTL, macctl); |
| @@ -1221,7 +1235,7 @@ static void drain_txstatus_queue(struct b43_wldev *dev) | |||
| 1221 | { | 1235 | { |
| 1222 | u32 dummy; | 1236 | u32 dummy; |
| 1223 | 1237 | ||
| 1224 | if (dev->sdev->id.revision < 5) | 1238 | if (dev->dev->core_rev < 5) |
| 1225 | return; | 1239 | return; |
| 1226 | /* Read all entries from the microcode TXstatus FIFO | 1240 | /* Read all entries from the microcode TXstatus FIFO |
| 1227 | * and throw them away. | 1241 | * and throw them away. |
| @@ -1427,9 +1441,9 @@ u8 b43_ieee80211_antenna_sanitize(struct b43_wldev *dev, | |||
| 1427 | 1441 | ||
| 1428 | /* Get the mask of available antennas. */ | 1442 | /* Get the mask of available antennas. */ |
| 1429 | if (dev->phy.gmode) | 1443 | if (dev->phy.gmode) |
| 1430 | antenna_mask = dev->sdev->bus->sprom.ant_available_bg; | 1444 | antenna_mask = dev->dev->bus_sprom->ant_available_bg; |
| 1431 | else | 1445 | else |
| 1432 | antenna_mask = dev->sdev->bus->sprom.ant_available_a; | 1446 | antenna_mask = dev->dev->bus_sprom->ant_available_a; |
| 1433 | 1447 | ||
| 1434 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { | 1448 | if (!(antenna_mask & (1 << (antenna_nr - 1)))) { |
| 1435 | /* This antenna is not available. Fall back to default. */ | 1449 | /* This antenna is not available. Fall back to default. */ |
| @@ -1644,7 +1658,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work) | |||
| 1644 | mutex_lock(&wl->mutex); | 1658 | mutex_lock(&wl->mutex); |
| 1645 | dev = wl->current_dev; | 1659 | dev = wl->current_dev; |
| 1646 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { | 1660 | if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { |
| 1647 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 1661 | if (b43_bus_host_is_sdio(dev->dev)) { |
| 1648 | /* wl->mutex is enough. */ | 1662 | /* wl->mutex is enough. */ |
| 1649 | b43_do_beacon_update_trigger_work(dev); | 1663 | b43_do_beacon_update_trigger_work(dev); |
| 1650 | mmiowb(); | 1664 | mmiowb(); |
| @@ -1689,7 +1703,7 @@ static void b43_update_templates(struct b43_wl *wl) | |||
| 1689 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1703 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) |
| 1690 | { | 1704 | { |
| 1691 | b43_time_lock(dev); | 1705 | b43_time_lock(dev); |
| 1692 | if (dev->sdev->id.revision >= 3) { | 1706 | if (dev->dev->core_rev >= 3) { |
| 1693 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); | 1707 | b43_write32(dev, B43_MMIO_TSF_CFP_REP, (beacon_int << 16)); |
| 1694 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); | 1708 | b43_write32(dev, B43_MMIO_TSF_CFP_START, (beacon_int << 10)); |
| 1695 | } else { | 1709 | } else { |
| @@ -2063,7 +2077,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx, | |||
| 2063 | B43_WARN_ON(1); | 2077 | B43_WARN_ON(1); |
| 2064 | return -ENOSYS; | 2078 | return -ENOSYS; |
| 2065 | } | 2079 | } |
| 2066 | err = request_firmware(&blob, ctx->fwname, ctx->dev->sdev->dev); | 2080 | err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); |
| 2067 | if (err == -ENOENT) { | 2081 | if (err == -ENOENT) { |
| 2068 | snprintf(ctx->errors[ctx->req_type], | 2082 | snprintf(ctx->errors[ctx->req_type], |
| 2069 | sizeof(ctx->errors[ctx->req_type]), | 2083 | sizeof(ctx->errors[ctx->req_type]), |
| @@ -2113,7 +2127,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
| 2113 | { | 2127 | { |
| 2114 | struct b43_wldev *dev = ctx->dev; | 2128 | struct b43_wldev *dev = ctx->dev; |
| 2115 | struct b43_firmware *fw = &ctx->dev->fw; | 2129 | struct b43_firmware *fw = &ctx->dev->fw; |
| 2116 | const u8 rev = ctx->dev->sdev->id.revision; | 2130 | const u8 rev = ctx->dev->dev->core_rev; |
| 2117 | const char *filename; | 2131 | const char *filename; |
| 2118 | u32 tmshigh; | 2132 | u32 tmshigh; |
| 2119 | int err; | 2133 | int err; |
| @@ -2157,7 +2171,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
| 2157 | switch (dev->phy.type) { | 2171 | switch (dev->phy.type) { |
| 2158 | case B43_PHYTYPE_A: | 2172 | case B43_PHYTYPE_A: |
| 2159 | if ((rev >= 5) && (rev <= 10)) { | 2173 | if ((rev >= 5) && (rev <= 10)) { |
| 2160 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 2174 | tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); |
| 2161 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2175 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
| 2162 | filename = "a0g1initvals5"; | 2176 | filename = "a0g1initvals5"; |
| 2163 | else | 2177 | else |
| @@ -2202,7 +2216,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx) | |||
| 2202 | switch (dev->phy.type) { | 2216 | switch (dev->phy.type) { |
| 2203 | case B43_PHYTYPE_A: | 2217 | case B43_PHYTYPE_A: |
| 2204 | if ((rev >= 5) && (rev <= 10)) { | 2218 | if ((rev >= 5) && (rev <= 10)) { |
| 2205 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 2219 | tmshigh = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); |
| 2206 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) | 2220 | if (tmshigh & B43_TMSHIGH_HAVE_2GHZ_PHY) |
| 2207 | filename = "a0g1bsinitvals5"; | 2221 | filename = "a0g1bsinitvals5"; |
| 2208 | else | 2222 | else |
| @@ -2448,7 +2462,7 @@ static int b43_upload_microcode(struct b43_wldev *dev) | |||
| 2448 | 2462 | ||
| 2449 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", | 2463 | snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "%u.%u", |
| 2450 | dev->fw.rev, dev->fw.patch); | 2464 | dev->fw.rev, dev->fw.patch); |
| 2451 | wiphy->hw_version = dev->sdev->id.coreid; | 2465 | wiphy->hw_version = dev->dev->core_id; |
| 2452 | 2466 | ||
| 2453 | if (b43_is_old_txhdr_format(dev)) { | 2467 | if (b43_is_old_txhdr_format(dev)) { |
| 2454 | /* We're over the deadline, but we keep support for old fw | 2468 | /* We're over the deadline, but we keep support for old fw |
| @@ -2566,7 +2580,7 @@ out: | |||
| 2566 | */ | 2580 | */ |
| 2567 | static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) | 2581 | static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) |
| 2568 | { | 2582 | { |
| 2569 | struct ssb_bus *bus = dev->sdev->bus; | 2583 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 2570 | 2584 | ||
| 2571 | #ifdef CONFIG_SSB_DRIVER_PCICORE | 2585 | #ifdef CONFIG_SSB_DRIVER_PCICORE |
| 2572 | return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); | 2586 | return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); |
| @@ -2588,7 +2602,7 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
| 2588 | 2602 | ||
| 2589 | mask = 0x0000001F; | 2603 | mask = 0x0000001F; |
| 2590 | set = 0x0000000F; | 2604 | set = 0x0000000F; |
| 2591 | if (dev->sdev->bus->chip_id == 0x4301) { | 2605 | if (dev->dev->chip_id == 0x4301) { |
| 2592 | mask |= 0x0060; | 2606 | mask |= 0x0060; |
| 2593 | set |= 0x0060; | 2607 | set |= 0x0060; |
| 2594 | } | 2608 | } |
| @@ -2599,14 +2613,14 @@ static int b43_gpio_init(struct b43_wldev *dev) | |||
| 2599 | mask |= 0x0180; | 2613 | mask |= 0x0180; |
| 2600 | set |= 0x0180; | 2614 | set |= 0x0180; |
| 2601 | } | 2615 | } |
| 2602 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) { | 2616 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) { |
| 2603 | b43_write16(dev, B43_MMIO_GPIO_MASK, | 2617 | b43_write16(dev, B43_MMIO_GPIO_MASK, |
| 2604 | b43_read16(dev, B43_MMIO_GPIO_MASK) | 2618 | b43_read16(dev, B43_MMIO_GPIO_MASK) |
| 2605 | | 0x0200); | 2619 | | 0x0200); |
| 2606 | mask |= 0x0200; | 2620 | mask |= 0x0200; |
| 2607 | set |= 0x0200; | 2621 | set |= 0x0200; |
| 2608 | } | 2622 | } |
| 2609 | if (dev->sdev->id.revision >= 2) | 2623 | if (dev->dev->core_rev >= 2) |
| 2610 | mask |= 0x0010; /* FIXME: This is redundant. */ | 2624 | mask |= 0x0010; /* FIXME: This is redundant. */ |
| 2611 | 2625 | ||
| 2612 | gpiodev = b43_ssb_gpio_dev(dev); | 2626 | gpiodev = b43_ssb_gpio_dev(dev); |
| @@ -2741,15 +2755,15 @@ static void b43_adjust_opmode(struct b43_wldev *dev) | |||
| 2741 | /* Workaround: On old hardware the HW-MAC-address-filter | 2755 | /* Workaround: On old hardware the HW-MAC-address-filter |
| 2742 | * doesn't work properly, so always run promisc in filter | 2756 | * doesn't work properly, so always run promisc in filter |
| 2743 | * it in software. */ | 2757 | * it in software. */ |
| 2744 | if (dev->sdev->id.revision <= 4) | 2758 | if (dev->dev->core_rev <= 4) |
| 2745 | ctl |= B43_MACCTL_PROMISC; | 2759 | ctl |= B43_MACCTL_PROMISC; |
| 2746 | 2760 | ||
| 2747 | b43_write32(dev, B43_MMIO_MACCTL, ctl); | 2761 | b43_write32(dev, B43_MMIO_MACCTL, ctl); |
| 2748 | 2762 | ||
| 2749 | cfp_pretbtt = 2; | 2763 | cfp_pretbtt = 2; |
| 2750 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { | 2764 | if ((ctl & B43_MACCTL_INFRA) && !(ctl & B43_MACCTL_AP)) { |
| 2751 | if (dev->sdev->bus->chip_id == 0x4306 && | 2765 | if (dev->dev->chip_id == 0x4306 && |
| 2752 | dev->sdev->bus->chip_rev == 3) | 2766 | dev->dev->chip_rev == 3) |
| 2753 | cfp_pretbtt = 100; | 2767 | cfp_pretbtt = 100; |
| 2754 | else | 2768 | else |
| 2755 | cfp_pretbtt = 50; | 2769 | cfp_pretbtt = 50; |
| @@ -2907,7 +2921,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
| 2907 | b43_write16(dev, 0x005E, value16); | 2921 | b43_write16(dev, 0x005E, value16); |
| 2908 | } | 2922 | } |
| 2909 | b43_write32(dev, 0x0100, 0x01000000); | 2923 | b43_write32(dev, 0x0100, 0x01000000); |
| 2910 | if (dev->sdev->id.revision < 5) | 2924 | if (dev->dev->core_rev < 5) |
| 2911 | b43_write32(dev, 0x010C, 0x01000000); | 2925 | b43_write32(dev, 0x010C, 0x01000000); |
| 2912 | 2926 | ||
| 2913 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) | 2927 | b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) |
| @@ -2922,7 +2936,7 @@ static int b43_chip_init(struct b43_wldev *dev) | |||
| 2922 | /* Initially set the wireless operation mode. */ | 2936 | /* Initially set the wireless operation mode. */ |
| 2923 | b43_adjust_opmode(dev); | 2937 | b43_adjust_opmode(dev); |
| 2924 | 2938 | ||
| 2925 | if (dev->sdev->id.revision < 3) { | 2939 | if (dev->dev->core_rev < 3) { |
| 2926 | b43_write16(dev, 0x060E, 0x0000); | 2940 | b43_write16(dev, 0x060E, 0x0000); |
| 2927 | b43_write16(dev, 0x0610, 0x8000); | 2941 | b43_write16(dev, 0x0610, 0x8000); |
| 2928 | b43_write16(dev, 0x0604, 0x0000); | 2942 | b43_write16(dev, 0x0604, 0x0000); |
| @@ -3105,7 +3119,7 @@ static int b43_validate_chipaccess(struct b43_wldev *dev) | |||
| 3105 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); | 3119 | b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0); |
| 3106 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); | 3120 | b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4); |
| 3107 | 3121 | ||
| 3108 | if ((dev->sdev->id.revision >= 3) && (dev->sdev->id.revision <= 10)) { | 3122 | if ((dev->dev->core_rev >= 3) && (dev->dev->core_rev <= 10)) { |
| 3109 | /* The 32bit register shadows the two 16bit registers | 3123 | /* The 32bit register shadows the two 16bit registers |
| 3110 | * with update sideeffects. Validate this. */ | 3124 | * with update sideeffects. Validate this. */ |
| 3111 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); | 3125 | b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA); |
| @@ -3954,7 +3968,7 @@ redo: | |||
| 3954 | 3968 | ||
| 3955 | /* Disable interrupts on the device. */ | 3969 | /* Disable interrupts on the device. */ |
| 3956 | b43_set_status(dev, B43_STAT_INITIALIZED); | 3970 | b43_set_status(dev, B43_STAT_INITIALIZED); |
| 3957 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 3971 | if (b43_bus_host_is_sdio(dev->dev)) { |
| 3958 | /* wl->mutex is locked. That is enough. */ | 3972 | /* wl->mutex is locked. That is enough. */ |
| 3959 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); | 3973 | b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); |
| 3960 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ | 3974 | b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */ |
| @@ -3967,11 +3981,11 @@ redo: | |||
| 3967 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ | 3981 | /* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */ |
| 3968 | orig_dev = dev; | 3982 | orig_dev = dev; |
| 3969 | mutex_unlock(&wl->mutex); | 3983 | mutex_unlock(&wl->mutex); |
| 3970 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 3984 | if (b43_bus_host_is_sdio(dev->dev)) { |
| 3971 | b43_sdio_free_irq(dev); | 3985 | b43_sdio_free_irq(dev); |
| 3972 | } else { | 3986 | } else { |
| 3973 | synchronize_irq(dev->sdev->irq); | 3987 | synchronize_irq(dev->dev->irq); |
| 3974 | free_irq(dev->sdev->irq, dev); | 3988 | free_irq(dev->dev->irq, dev); |
| 3975 | } | 3989 | } |
| 3976 | mutex_lock(&wl->mutex); | 3990 | mutex_lock(&wl->mutex); |
| 3977 | dev = wl->current_dev; | 3991 | dev = wl->current_dev; |
| @@ -4004,19 +4018,19 @@ static int b43_wireless_core_start(struct b43_wldev *dev) | |||
| 4004 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); | 4018 | B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); |
| 4005 | 4019 | ||
| 4006 | drain_txstatus_queue(dev); | 4020 | drain_txstatus_queue(dev); |
| 4007 | if (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) { | 4021 | if (b43_bus_host_is_sdio(dev->dev)) { |
| 4008 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); | 4022 | err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler); |
| 4009 | if (err) { | 4023 | if (err) { |
| 4010 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); | 4024 | b43err(dev->wl, "Cannot request SDIO IRQ\n"); |
| 4011 | goto out; | 4025 | goto out; |
| 4012 | } | 4026 | } |
| 4013 | } else { | 4027 | } else { |
| 4014 | err = request_threaded_irq(dev->sdev->irq, b43_interrupt_handler, | 4028 | err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler, |
| 4015 | b43_interrupt_thread_handler, | 4029 | b43_interrupt_thread_handler, |
| 4016 | IRQF_SHARED, KBUILD_MODNAME, dev); | 4030 | IRQF_SHARED, KBUILD_MODNAME, dev); |
| 4017 | if (err) { | 4031 | if (err) { |
| 4018 | b43err(dev->wl, "Cannot request IRQ-%d\n", | 4032 | b43err(dev->wl, "Cannot request IRQ-%d\n", |
| 4019 | dev->sdev->irq); | 4033 | dev->dev->irq); |
| 4020 | goto out; | 4034 | goto out; |
| 4021 | } | 4035 | } |
| 4022 | } | 4036 | } |
| @@ -4096,10 +4110,10 @@ static int b43_phy_versioning(struct b43_wldev *dev) | |||
| 4096 | analog_type, phy_type, phy_rev); | 4110 | analog_type, phy_type, phy_rev); |
| 4097 | 4111 | ||
| 4098 | /* Get RADIO versioning */ | 4112 | /* Get RADIO versioning */ |
| 4099 | if (dev->sdev->bus->chip_id == 0x4317) { | 4113 | if (dev->dev->chip_id == 0x4317) { |
| 4100 | if (dev->sdev->bus->chip_rev == 0) | 4114 | if (dev->dev->chip_rev == 0) |
| 4101 | tmp = 0x3205017F; | 4115 | tmp = 0x3205017F; |
| 4102 | else if (dev->sdev->bus->chip_rev == 1) | 4116 | else if (dev->dev->chip_rev == 1) |
| 4103 | tmp = 0x4205017F; | 4117 | tmp = 0x4205017F; |
| 4104 | else | 4118 | else |
| 4105 | tmp = 0x5205017F; | 4119 | tmp = 0x5205017F; |
| @@ -4204,7 +4218,7 @@ static void setup_struct_wldev_for_init(struct b43_wldev *dev) | |||
| 4204 | 4218 | ||
| 4205 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) | 4219 | static void b43_bluetooth_coext_enable(struct b43_wldev *dev) |
| 4206 | { | 4220 | { |
| 4207 | struct ssb_sprom *sprom = &dev->sdev->bus->sprom; | 4221 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 4208 | u64 hf; | 4222 | u64 hf; |
| 4209 | 4223 | ||
| 4210 | if (!modparam_btcoex) | 4224 | if (!modparam_btcoex) |
| @@ -4231,16 +4245,21 @@ static void b43_bluetooth_coext_disable(struct b43_wldev *dev) | |||
| 4231 | 4245 | ||
| 4232 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) | 4246 | static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev) |
| 4233 | { | 4247 | { |
| 4234 | struct ssb_bus *bus = dev->sdev->bus; | 4248 | struct ssb_bus *bus; |
| 4235 | u32 tmp; | 4249 | u32 tmp; |
| 4236 | 4250 | ||
| 4251 | if (dev->dev->bus_type != B43_BUS_SSB) | ||
| 4252 | return; | ||
| 4253 | |||
| 4254 | bus = dev->dev->sdev->bus; | ||
| 4255 | |||
| 4237 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || | 4256 | if ((bus->chip_id == 0x4311 && bus->chip_rev == 2) || |
| 4238 | (bus->chip_id == 0x4312)) { | 4257 | (bus->chip_id == 0x4312)) { |
| 4239 | tmp = ssb_read32(dev->sdev, SSB_IMCFGLO); | 4258 | tmp = ssb_read32(dev->dev->sdev, SSB_IMCFGLO); |
| 4240 | tmp &= ~SSB_IMCFGLO_REQTO; | 4259 | tmp &= ~SSB_IMCFGLO_REQTO; |
| 4241 | tmp &= ~SSB_IMCFGLO_SERTO; | 4260 | tmp &= ~SSB_IMCFGLO_SERTO; |
| 4242 | tmp |= 0x3; | 4261 | tmp |= 0x3; |
| 4243 | ssb_write32(dev->sdev, SSB_IMCFGLO, tmp); | 4262 | ssb_write32(dev->dev->sdev, SSB_IMCFGLO, tmp); |
| 4244 | ssb_commit_settings(bus); | 4263 | ssb_commit_settings(bus); |
| 4245 | } | 4264 | } |
| 4246 | } | 4265 | } |
| @@ -4310,29 +4329,26 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) | |||
| 4310 | dev->wl->current_beacon = NULL; | 4329 | dev->wl->current_beacon = NULL; |
| 4311 | } | 4330 | } |
| 4312 | 4331 | ||
| 4313 | ssb_device_disable(dev->sdev, 0); | 4332 | b43_device_disable(dev, 0); |
| 4314 | ssb_bus_may_powerdown(dev->sdev->bus); | 4333 | b43_bus_may_powerdown(dev); |
| 4315 | } | 4334 | } |
| 4316 | 4335 | ||
| 4317 | /* Initialize a wireless core */ | 4336 | /* Initialize a wireless core */ |
| 4318 | static int b43_wireless_core_init(struct b43_wldev *dev) | 4337 | static int b43_wireless_core_init(struct b43_wldev *dev) |
| 4319 | { | 4338 | { |
| 4320 | struct ssb_bus *bus = dev->sdev->bus; | 4339 | struct ssb_bus *bus = dev->sdev->bus; |
| 4321 | struct ssb_sprom *sprom = &bus->sprom; | 4340 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 4322 | struct b43_phy *phy = &dev->phy; | 4341 | struct b43_phy *phy = &dev->phy; |
| 4323 | int err; | 4342 | int err; |
| 4324 | u64 hf; | 4343 | u64 hf; |
| 4325 | u32 tmp; | ||
| 4326 | 4344 | ||
| 4327 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); | 4345 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); |
| 4328 | 4346 | ||
| 4329 | err = ssb_bus_powerup(bus, 0); | 4347 | err = b43_bus_powerup(dev, 0); |
| 4330 | if (err) | 4348 | if (err) |
| 4331 | goto out; | 4349 | goto out; |
| 4332 | if (!ssb_device_is_enabled(dev->sdev)) { | 4350 | if (!b43_device_is_enabled(dev)) |
| 4333 | tmp = phy->gmode ? B43_TMSLOW_GMODE : 0; | 4351 | b43_wireless_core_reset(dev, phy->gmode); |
| 4334 | b43_wireless_core_reset(dev, tmp); | ||
| 4335 | } | ||
| 4336 | 4352 | ||
| 4337 | /* Reset all data structures. */ | 4353 | /* Reset all data structures. */ |
| 4338 | setup_struct_wldev_for_init(dev); | 4354 | setup_struct_wldev_for_init(dev); |
| @@ -4352,7 +4368,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
| 4352 | if (err) | 4368 | if (err) |
| 4353 | goto err_busdown; | 4369 | goto err_busdown; |
| 4354 | b43_shm_write16(dev, B43_SHM_SHARED, | 4370 | b43_shm_write16(dev, B43_SHM_SHARED, |
| 4355 | B43_SHM_SH_WLCOREREV, dev->sdev->id.revision); | 4371 | B43_SHM_SH_WLCOREREV, dev->dev->core_rev); |
| 4356 | hf = b43_hf_read(dev); | 4372 | hf = b43_hf_read(dev); |
| 4357 | if (phy->type == B43_PHYTYPE_G) { | 4373 | if (phy->type == B43_PHYTYPE_G) { |
| 4358 | hf |= B43_HF_SYMW; | 4374 | hf |= B43_HF_SYMW; |
| @@ -4399,8 +4415,8 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
| 4399 | /* Maximum Contention Window */ | 4415 | /* Maximum Contention Window */ |
| 4400 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); | 4416 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); |
| 4401 | 4417 | ||
| 4402 | if ((dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA) || | 4418 | if (b43_bus_host_is_pcmcia(dev->dev) || |
| 4403 | (dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO) || | 4419 | b43_bus_host_is_sdio(dev->dev) || |
| 4404 | dev->use_pio) { | 4420 | dev->use_pio) { |
| 4405 | dev->__using_pio_transfers = 1; | 4421 | dev->__using_pio_transfers = 1; |
| 4406 | err = b43_pio_init(dev); | 4422 | err = b43_pio_init(dev); |
| @@ -4414,7 +4430,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
| 4414 | b43_set_synth_pu_delay(dev, 1); | 4430 | b43_set_synth_pu_delay(dev, 1); |
| 4415 | b43_bluetooth_coext_enable(dev); | 4431 | b43_bluetooth_coext_enable(dev); |
| 4416 | 4432 | ||
| 4417 | ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); | 4433 | b43_bus_powerup(dev, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)); |
| 4418 | b43_upload_card_macaddress(dev); | 4434 | b43_upload_card_macaddress(dev); |
| 4419 | b43_security_init(dev); | 4435 | b43_security_init(dev); |
| 4420 | 4436 | ||
| @@ -4431,7 +4447,7 @@ out: | |||
| 4431 | err_chip_exit: | 4447 | err_chip_exit: |
| 4432 | b43_chip_exit(dev); | 4448 | b43_chip_exit(dev); |
| 4433 | err_busdown: | 4449 | err_busdown: |
| 4434 | ssb_bus_may_powerdown(bus); | 4450 | b43_bus_may_powerdown(dev); |
| 4435 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); | 4451 | B43_WARN_ON(b43_status(dev) != B43_STAT_UNINIT); |
| 4436 | return err; | 4452 | return err; |
| 4437 | } | 4453 | } |
| @@ -4741,7 +4757,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
| 4741 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; | 4757 | struct pci_dev *pdev = (bus->bustype == SSB_BUSTYPE_PCI) ? bus->host_pci : NULL; |
| 4742 | int err; | 4758 | int err; |
| 4743 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; | 4759 | bool have_2ghz_phy = 0, have_5ghz_phy = 0; |
| 4744 | u32 tmp; | ||
| 4745 | 4760 | ||
| 4746 | /* Do NOT do any device initialization here. | 4761 | /* Do NOT do any device initialization here. |
| 4747 | * Do it in wireless_core_init() instead. | 4762 | * Do it in wireless_core_init() instead. |
| @@ -4750,13 +4765,13 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
| 4750 | * that in core_init(), too. | 4765 | * that in core_init(), too. |
| 4751 | */ | 4766 | */ |
| 4752 | 4767 | ||
| 4753 | err = ssb_bus_powerup(bus, 0); | 4768 | err = b43_bus_powerup(dev, 0); |
| 4754 | if (err) { | 4769 | if (err) { |
| 4755 | b43err(wl, "Bus powerup failed\n"); | 4770 | b43err(wl, "Bus powerup failed\n"); |
| 4756 | goto out; | 4771 | goto out; |
| 4757 | } | 4772 | } |
| 4758 | /* Get the PHY type. */ | 4773 | /* Get the PHY type. */ |
| 4759 | if (dev->sdev->id.revision >= 5) { | 4774 | if (dev->dev->core_rev >= 5) { |
| 4760 | u32 tmshigh; | 4775 | u32 tmshigh; |
| 4761 | 4776 | ||
| 4762 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); | 4777 | tmshigh = ssb_read32(dev->sdev, SSB_TMSHIGH); |
| @@ -4767,8 +4782,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
| 4767 | 4782 | ||
| 4768 | dev->phy.gmode = have_2ghz_phy; | 4783 | dev->phy.gmode = have_2ghz_phy; |
| 4769 | dev->phy.radio_on = 1; | 4784 | dev->phy.radio_on = 1; |
| 4770 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 4785 | b43_wireless_core_reset(dev, dev->phy.gmode); |
| 4771 | b43_wireless_core_reset(dev, tmp); | ||
| 4772 | 4786 | ||
| 4773 | err = b43_phy_versioning(dev); | 4787 | err = b43_phy_versioning(dev); |
| 4774 | if (err) | 4788 | if (err) |
| @@ -4816,8 +4830,7 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
| 4816 | goto err_powerdown; | 4830 | goto err_powerdown; |
| 4817 | 4831 | ||
| 4818 | dev->phy.gmode = have_2ghz_phy; | 4832 | dev->phy.gmode = have_2ghz_phy; |
| 4819 | tmp = dev->phy.gmode ? B43_TMSLOW_GMODE : 0; | 4833 | b43_wireless_core_reset(dev, dev->phy.gmode); |
| 4820 | b43_wireless_core_reset(dev, tmp); | ||
| 4821 | 4834 | ||
| 4822 | err = b43_validate_chipaccess(dev); | 4835 | err = b43_validate_chipaccess(dev); |
| 4823 | if (err) | 4836 | if (err) |
| @@ -4832,8 +4845,8 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) | |||
| 4832 | INIT_WORK(&dev->restart_work, b43_chip_reset); | 4845 | INIT_WORK(&dev->restart_work, b43_chip_reset); |
| 4833 | 4846 | ||
| 4834 | dev->phy.ops->switch_analog(dev, 0); | 4847 | dev->phy.ops->switch_analog(dev, 0); |
| 4835 | ssb_device_disable(dev->sdev, 0); | 4848 | b43_device_disable(dev, 0); |
| 4836 | ssb_bus_may_powerdown(bus); | 4849 | b43_bus_may_powerdown(dev); |
| 4837 | 4850 | ||
| 4838 | out: | 4851 | out: |
| 4839 | return err; | 4852 | return err; |
| @@ -4841,11 +4854,11 @@ out: | |||
| 4841 | err_phy_free: | 4854 | err_phy_free: |
| 4842 | b43_phy_free(dev); | 4855 | b43_phy_free(dev); |
| 4843 | err_powerdown: | 4856 | err_powerdown: |
| 4844 | ssb_bus_may_powerdown(bus); | 4857 | b43_bus_may_powerdown(dev); |
| 4845 | return err; | 4858 | return err; |
| 4846 | } | 4859 | } |
| 4847 | 4860 | ||
| 4848 | static void b43_one_core_detach(struct ssb_device *dev) | 4861 | static void b43_one_core_detach(struct b43_bus_dev *dev) |
| 4849 | { | 4862 | { |
| 4850 | struct b43_wldev *wldev; | 4863 | struct b43_wldev *wldev; |
| 4851 | struct b43_wl *wl; | 4864 | struct b43_wl *wl; |
| @@ -4853,17 +4866,17 @@ static void b43_one_core_detach(struct ssb_device *dev) | |||
| 4853 | /* Do not cancel ieee80211-workqueue based work here. | 4866 | /* Do not cancel ieee80211-workqueue based work here. |
| 4854 | * See comment in b43_remove(). */ | 4867 | * See comment in b43_remove(). */ |
| 4855 | 4868 | ||
| 4856 | wldev = ssb_get_drvdata(dev); | 4869 | wldev = ssb_get_drvdata(dev->sdev); |
| 4857 | wl = wldev->wl; | 4870 | wl = wldev->wl; |
| 4858 | b43_debugfs_remove_device(wldev); | 4871 | b43_debugfs_remove_device(wldev); |
| 4859 | b43_wireless_core_detach(wldev); | 4872 | b43_wireless_core_detach(wldev); |
| 4860 | list_del(&wldev->list); | 4873 | list_del(&wldev->list); |
| 4861 | wl->nr_devs--; | 4874 | wl->nr_devs--; |
| 4862 | ssb_set_drvdata(dev, NULL); | 4875 | ssb_set_drvdata(dev->sdev, NULL); |
| 4863 | kfree(wldev); | 4876 | kfree(wldev); |
| 4864 | } | 4877 | } |
| 4865 | 4878 | ||
| 4866 | static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | 4879 | static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl) |
| 4867 | { | 4880 | { |
| 4868 | struct b43_wldev *wldev; | 4881 | struct b43_wldev *wldev; |
| 4869 | int err = -ENOMEM; | 4882 | int err = -ENOMEM; |
| @@ -4873,7 +4886,8 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
| 4873 | goto out; | 4886 | goto out; |
| 4874 | 4887 | ||
| 4875 | wldev->use_pio = b43_modparam_pio; | 4888 | wldev->use_pio = b43_modparam_pio; |
| 4876 | wldev->sdev = dev; | 4889 | wldev->dev = dev; |
| 4890 | wldev->sdev = dev->sdev; /* TODO: Remove when not needed */ | ||
| 4877 | wldev->wl = wl; | 4891 | wldev->wl = wl; |
| 4878 | b43_set_status(wldev, B43_STAT_UNINIT); | 4892 | b43_set_status(wldev, B43_STAT_UNINIT); |
| 4879 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; | 4893 | wldev->bad_frames_preempt = modparam_bad_frames_preempt; |
| @@ -4885,7 +4899,7 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl) | |||
| 4885 | 4899 | ||
| 4886 | list_add(&wldev->list, &wl->devlist); | 4900 | list_add(&wldev->list, &wl->devlist); |
| 4887 | wl->nr_devs++; | 4901 | wl->nr_devs++; |
| 4888 | ssb_set_drvdata(dev, wldev); | 4902 | ssb_set_drvdata(dev->sdev, wldev); |
| 4889 | b43_debugfs_add_device(wldev); | 4903 | b43_debugfs_add_device(wldev); |
| 4890 | 4904 | ||
| 4891 | out: | 4905 | out: |
| @@ -4926,11 +4940,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus) | |||
| 4926 | } | 4940 | } |
| 4927 | } | 4941 | } |
| 4928 | 4942 | ||
| 4929 | static void b43_wireless_exit(struct ssb_device *dev, struct b43_wl *wl) | 4943 | static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl) |
| 4930 | { | 4944 | { |
| 4931 | struct ieee80211_hw *hw = wl->hw; | 4945 | struct ieee80211_hw *hw = wl->hw; |
| 4932 | 4946 | ||
| 4933 | ssb_set_devtypedata(dev, NULL); | 4947 | ssb_set_devtypedata(dev->sdev, NULL); |
| 4934 | ieee80211_free_hw(hw); | 4948 | ieee80211_free_hw(hw); |
| 4935 | } | 4949 | } |
| 4936 | 4950 | ||
| @@ -4982,24 +4996,48 @@ static struct b43_wl *b43_wireless_init(struct ssb_device *dev) | |||
| 4982 | return wl; | 4996 | return wl; |
| 4983 | } | 4997 | } |
| 4984 | 4998 | ||
| 4985 | static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | 4999 | #ifdef CONFIG_B43_BCMA |
| 5000 | static int b43_bcma_probe(struct bcma_device *core) | ||
| 5001 | { | ||
| 5002 | b43err(NULL, "BCMA is not supported yet!"); | ||
| 5003 | return -EOPNOTSUPP; | ||
| 5004 | } | ||
| 5005 | |||
| 5006 | static void b43_bcma_remove(struct bcma_device *core) | ||
| 5007 | { | ||
| 5008 | /* TODO */ | ||
| 5009 | } | ||
| 5010 | |||
| 5011 | static struct bcma_driver b43_bcma_driver = { | ||
| 5012 | .name = KBUILD_MODNAME, | ||
| 5013 | .id_table = b43_bcma_tbl, | ||
| 5014 | .probe = b43_bcma_probe, | ||
| 5015 | .remove = b43_bcma_remove, | ||
| 5016 | }; | ||
| 5017 | #endif | ||
| 5018 | |||
| 5019 | static | ||
| 5020 | int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id) | ||
| 4986 | { | 5021 | { |
| 5022 | struct b43_bus_dev *dev; | ||
| 4987 | struct b43_wl *wl; | 5023 | struct b43_wl *wl; |
| 4988 | int err; | 5024 | int err; |
| 4989 | int first = 0; | 5025 | int first = 0; |
| 4990 | 5026 | ||
| 4991 | wl = ssb_get_devtypedata(dev); | 5027 | dev = b43_bus_dev_ssb_init(sdev); |
| 5028 | |||
| 5029 | wl = ssb_get_devtypedata(sdev); | ||
| 4992 | if (!wl) { | 5030 | if (!wl) { |
| 4993 | /* Probing the first core. Must setup common struct b43_wl */ | 5031 | /* Probing the first core. Must setup common struct b43_wl */ |
| 4994 | first = 1; | 5032 | first = 1; |
| 4995 | b43_sprom_fixup(dev->bus); | 5033 | b43_sprom_fixup(sdev->bus); |
| 4996 | wl = b43_wireless_init(dev); | 5034 | wl = b43_wireless_init(sdev); |
| 4997 | if (IS_ERR(wl)) { | 5035 | if (IS_ERR(wl)) { |
| 4998 | err = PTR_ERR(wl); | 5036 | err = PTR_ERR(wl); |
| 4999 | goto out; | 5037 | goto out; |
| 5000 | } | 5038 | } |
| 5001 | ssb_set_devtypedata(dev, wl); | 5039 | ssb_set_devtypedata(sdev, wl); |
| 5002 | B43_WARN_ON(ssb_get_devtypedata(dev) != wl); | 5040 | B43_WARN_ON(ssb_get_devtypedata(sdev) != wl); |
| 5003 | } | 5041 | } |
| 5004 | err = b43_one_core_attach(dev, wl); | 5042 | err = b43_one_core_attach(dev, wl); |
| 5005 | if (err) | 5043 | if (err) |
| @@ -5023,10 +5061,10 @@ static int b43_ssb_probe(struct ssb_device *dev, const struct ssb_device_id *id) | |||
| 5023 | return err; | 5061 | return err; |
| 5024 | } | 5062 | } |
| 5025 | 5063 | ||
| 5026 | static void b43_ssb_remove(struct ssb_device *dev) | 5064 | static void b43_ssb_remove(struct ssb_device *sdev) |
| 5027 | { | 5065 | { |
| 5028 | struct b43_wl *wl = ssb_get_devtypedata(dev); | 5066 | struct b43_wl *wl = ssb_get_devtypedata(sdev); |
| 5029 | struct b43_wldev *wldev = ssb_get_drvdata(dev); | 5067 | struct b43_wldev *wldev = ssb_get_drvdata(sdev); |
| 5030 | 5068 | ||
| 5031 | /* We must cancel any work here before unregistering from ieee80211, | 5069 | /* We must cancel any work here before unregistering from ieee80211, |
| 5032 | * as the ieee80211 unreg will destroy the workqueue. */ | 5070 | * as the ieee80211 unreg will destroy the workqueue. */ |
| @@ -5042,14 +5080,14 @@ static void b43_ssb_remove(struct ssb_device *dev) | |||
| 5042 | ieee80211_unregister_hw(wl->hw); | 5080 | ieee80211_unregister_hw(wl->hw); |
| 5043 | } | 5081 | } |
| 5044 | 5082 | ||
| 5045 | b43_one_core_detach(dev); | 5083 | b43_one_core_detach(wldev->dev); |
| 5046 | 5084 | ||
| 5047 | if (list_empty(&wl->devlist)) { | 5085 | if (list_empty(&wl->devlist)) { |
| 5048 | b43_leds_unregister(wl); | 5086 | b43_leds_unregister(wl); |
| 5049 | /* Last core on the chip unregistered. | 5087 | /* Last core on the chip unregistered. |
| 5050 | * We can destroy common struct b43_wl. | 5088 | * We can destroy common struct b43_wl. |
| 5051 | */ | 5089 | */ |
| 5052 | b43_wireless_exit(dev, wl); | 5090 | b43_wireless_exit(wldev->dev, wl); |
| 5053 | } | 5091 | } |
| 5054 | } | 5092 | } |
| 5055 | 5093 | ||
| @@ -5108,14 +5146,23 @@ static int __init b43_init(void) | |||
| 5108 | err = b43_sdio_init(); | 5146 | err = b43_sdio_init(); |
| 5109 | if (err) | 5147 | if (err) |
| 5110 | goto err_pcmcia_exit; | 5148 | goto err_pcmcia_exit; |
| 5111 | err = ssb_driver_register(&b43_ssb_driver); | 5149 | #ifdef CONFIG_B43_BCMA |
| 5150 | err = bcma_driver_register(&b43_bcma_driver); | ||
| 5112 | if (err) | 5151 | if (err) |
| 5113 | goto err_sdio_exit; | 5152 | goto err_sdio_exit; |
| 5153 | #endif | ||
| 5154 | err = ssb_driver_register(&b43_ssb_driver); | ||
| 5155 | if (err) | ||
| 5156 | goto err_bcma_driver_exit; | ||
| 5114 | b43_print_driverinfo(); | 5157 | b43_print_driverinfo(); |
| 5115 | 5158 | ||
| 5116 | return err; | 5159 | return err; |
| 5117 | 5160 | ||
| 5161 | err_bcma_driver_exit: | ||
| 5162 | #ifdef CONFIG_B43_BCMA | ||
| 5163 | bcma_driver_unregister(&b43_bcma_driver); | ||
| 5118 | err_sdio_exit: | 5164 | err_sdio_exit: |
| 5165 | #endif | ||
| 5119 | b43_sdio_exit(); | 5166 | b43_sdio_exit(); |
| 5120 | err_pcmcia_exit: | 5167 | err_pcmcia_exit: |
| 5121 | b43_pcmcia_exit(); | 5168 | b43_pcmcia_exit(); |
| @@ -5127,6 +5174,9 @@ err_dfs_exit: | |||
| 5127 | static void __exit b43_exit(void) | 5174 | static void __exit b43_exit(void) |
| 5128 | { | 5175 | { |
| 5129 | ssb_driver_unregister(&b43_ssb_driver); | 5176 | ssb_driver_unregister(&b43_ssb_driver); |
| 5177 | #ifdef CONFIG_B43_BCMA | ||
| 5178 | bcma_driver_unregister(&b43_bcma_driver); | ||
| 5179 | #endif | ||
| 5130 | b43_sdio_exit(); | 5180 | b43_sdio_exit(); |
| 5131 | b43_pcmcia_exit(); | 5181 | b43_pcmcia_exit(); |
| 5132 | b43_debugfs_exit(); | 5182 | b43_debugfs_exit(); |
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index a0d327f13183..e4ebce9be592 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
| @@ -121,7 +121,7 @@ void b43_hf_write(struct b43_wldev *dev, u64 value); | |||
| 121 | 121 | ||
| 122 | void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on); | 122 | void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on); |
| 123 | 123 | ||
| 124 | void b43_wireless_core_reset(struct b43_wldev *dev, u32 flags); | 124 | void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode); |
| 125 | 125 | ||
| 126 | void b43_controller_restart(struct b43_wldev *dev, const char *reason); | 126 | void b43_controller_restart(struct b43_wldev *dev, const char *reason); |
| 127 | 127 | ||
diff --git a/drivers/net/wireless/b43/phy_a.c b/drivers/net/wireless/b43/phy_a.c index b01c8ced57c3..73ace5552bad 100644 --- a/drivers/net/wireless/b43/phy_a.c +++ b/drivers/net/wireless/b43/phy_a.c | |||
| @@ -265,7 +265,6 @@ static void hardware_pctl_init_aphy(struct b43_wldev *dev) | |||
| 265 | 265 | ||
| 266 | void b43_phy_inita(struct b43_wldev *dev) | 266 | void b43_phy_inita(struct b43_wldev *dev) |
| 267 | { | 267 | { |
| 268 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 269 | struct b43_phy *phy = &dev->phy; | 268 | struct b43_phy *phy = &dev->phy; |
| 270 | 269 | ||
| 271 | /* This lowlevel A-PHY init is also called from G-PHY init. | 270 | /* This lowlevel A-PHY init is also called from G-PHY init. |
| @@ -296,9 +295,9 @@ void b43_phy_inita(struct b43_wldev *dev) | |||
| 296 | 295 | ||
| 297 | b43_radio_init2060(dev); | 296 | b43_radio_init2060(dev); |
| 298 | 297 | ||
| 299 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | 298 | if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && |
| 300 | ((bus->boardinfo.type == SSB_BOARD_BU4306) || | 299 | ((dev->dev->board_type == SSB_BOARD_BU4306) || |
| 301 | (bus->boardinfo.type == SSB_BOARD_BU4309))) { | 300 | (dev->dev->board_type == SSB_BOARD_BU4309))) { |
| 302 | ; //TODO: A PHY LO | 301 | ; //TODO: A PHY LO |
| 303 | } | 302 | } |
| 304 | 303 | ||
| @@ -311,7 +310,7 @@ void b43_phy_inita(struct b43_wldev *dev) | |||
| 311 | } | 310 | } |
| 312 | 311 | ||
| 313 | if ((phy->type == B43_PHYTYPE_G) && | 312 | if ((phy->type == B43_PHYTYPE_G) && |
| 314 | (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL)) { | 313 | (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL)) { |
| 315 | b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); | 314 | b43_phy_maskset(dev, B43_PHY_OFDM(0x6E), 0xE000, 0x3CF); |
| 316 | } | 315 | } |
| 317 | } | 316 | } |
| @@ -323,17 +322,17 @@ static int b43_aphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
| 323 | struct b43_phy_a *aphy = phy->a; | 322 | struct b43_phy_a *aphy = phy->a; |
| 324 | s16 pab0, pab1, pab2; | 323 | s16 pab0, pab1, pab2; |
| 325 | 324 | ||
| 326 | pab0 = (s16) (dev->sdev->bus->sprom.pa1b0); | 325 | pab0 = (s16) (dev->dev->bus_sprom->pa1b0); |
| 327 | pab1 = (s16) (dev->sdev->bus->sprom.pa1b1); | 326 | pab1 = (s16) (dev->dev->bus_sprom->pa1b1); |
| 328 | pab2 = (s16) (dev->sdev->bus->sprom.pa1b2); | 327 | pab2 = (s16) (dev->dev->bus_sprom->pa1b2); |
| 329 | 328 | ||
| 330 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && | 329 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && |
| 331 | pab0 != -1 && pab1 != -1 && pab2 != -1) { | 330 | pab0 != -1 && pab1 != -1 && pab2 != -1) { |
| 332 | /* The pabX values are set in SPROM. Use them. */ | 331 | /* The pabX values are set in SPROM. Use them. */ |
| 333 | if ((s8) dev->sdev->bus->sprom.itssi_a != 0 && | 332 | if ((s8) dev->dev->bus_sprom->itssi_a != 0 && |
| 334 | (s8) dev->sdev->bus->sprom.itssi_a != -1) | 333 | (s8) dev->dev->bus_sprom->itssi_a != -1) |
| 335 | aphy->tgt_idle_tssi = | 334 | aphy->tgt_idle_tssi = |
| 336 | (s8) (dev->sdev->bus->sprom.itssi_a); | 335 | (s8) (dev->dev->bus_sprom->itssi_a); |
| 337 | else | 336 | else |
| 338 | aphy->tgt_idle_tssi = 62; | 337 | aphy->tgt_idle_tssi = 62; |
| 339 | aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, | 338 | aphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, |
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c index e46b2f4f0920..425af28ea4e5 100644 --- a/drivers/net/wireless/b43/phy_common.c +++ b/drivers/net/wireless/b43/phy_common.c | |||
| @@ -168,7 +168,7 @@ void b43_phy_lock(struct b43_wldev *dev) | |||
| 168 | B43_WARN_ON(dev->phy.phy_locked); | 168 | B43_WARN_ON(dev->phy.phy_locked); |
| 169 | dev->phy.phy_locked = 1; | 169 | dev->phy.phy_locked = 1; |
| 170 | #endif | 170 | #endif |
| 171 | B43_WARN_ON(dev->sdev->id.revision < 3); | 171 | B43_WARN_ON(dev->dev->core_rev < 3); |
| 172 | 172 | ||
| 173 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) | 173 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) |
| 174 | b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); | 174 | b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); |
| @@ -180,7 +180,7 @@ void b43_phy_unlock(struct b43_wldev *dev) | |||
| 180 | B43_WARN_ON(!dev->phy.phy_locked); | 180 | B43_WARN_ON(!dev->phy.phy_locked); |
| 181 | dev->phy.phy_locked = 0; | 181 | dev->phy.phy_locked = 0; |
| 182 | #endif | 182 | #endif |
| 183 | B43_WARN_ON(dev->sdev->id.revision < 3); | 183 | B43_WARN_ON(dev->dev->core_rev < 3); |
| 184 | 184 | ||
| 185 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) | 185 | if (!b43_is_mode(dev->wl, NL80211_IFTYPE_AP)) |
| 186 | b43_power_saving_ctl_bits(dev, 0); | 186 | b43_power_saving_ctl_bits(dev, 0); |
| @@ -368,8 +368,8 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags) | |||
| 368 | /* The next check will be needed in two seconds, or later. */ | 368 | /* The next check will be needed in two seconds, or later. */ |
| 369 | phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); | 369 | phy->next_txpwr_check_time = round_jiffies(now + (HZ * 2)); |
| 370 | 370 | ||
| 371 | if ((dev->sdev->bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | 371 | if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && |
| 372 | (dev->sdev->bus->boardinfo.type == SSB_BOARD_BU4306)) | 372 | (dev->dev->board_type == SSB_BOARD_BU4306)) |
| 373 | return; /* No software txpower adjustment needed */ | 373 | return; /* No software txpower adjustment needed */ |
| 374 | 374 | ||
| 375 | result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); | 375 | result = phy->ops->recalc_txpower(dev, !!(flags & B43_TXPWR_IGNORE_TSSI)); |
diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 1758a282f913..83532d19347f 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c | |||
| @@ -718,7 +718,7 @@ static void b43_calc_nrssi_threshold(struct b43_wldev *dev) | |||
| 718 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | 718 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); |
| 719 | 719 | ||
| 720 | if (!phy->gmode || | 720 | if (!phy->gmode || |
| 721 | !(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { | 721 | !(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) { |
| 722 | tmp16 = b43_nrssi_hw_read(dev, 0x20); | 722 | tmp16 = b43_nrssi_hw_read(dev, 0x20); |
| 723 | if (tmp16 >= 0x20) | 723 | if (tmp16 >= 0x20) |
| 724 | tmp16 -= 0x40; | 724 | tmp16 -= 0x40; |
| @@ -1114,7 +1114,7 @@ static u16 radio2050_rfover_val(struct b43_wldev *dev, | |||
| 1114 | { | 1114 | { |
| 1115 | struct b43_phy *phy = &dev->phy; | 1115 | struct b43_phy *phy = &dev->phy; |
| 1116 | struct b43_phy_g *gphy = phy->g; | 1116 | struct b43_phy_g *gphy = phy->g; |
| 1117 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); | 1117 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 1118 | 1118 | ||
| 1119 | if (!phy->gmode) | 1119 | if (!phy->gmode) |
| 1120 | return 0; | 1120 | return 0; |
| @@ -1491,7 +1491,6 @@ static u16 b43_radio_init2050(struct b43_wldev *dev) | |||
| 1491 | 1491 | ||
| 1492 | static void b43_phy_initb5(struct b43_wldev *dev) | 1492 | static void b43_phy_initb5(struct b43_wldev *dev) |
| 1493 | { | 1493 | { |
| 1494 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 1495 | struct b43_phy *phy = &dev->phy; | 1494 | struct b43_phy *phy = &dev->phy; |
| 1496 | struct b43_phy_g *gphy = phy->g; | 1495 | struct b43_phy_g *gphy = phy->g; |
| 1497 | u16 offset, value; | 1496 | u16 offset, value; |
| @@ -1500,8 +1499,8 @@ static void b43_phy_initb5(struct b43_wldev *dev) | |||
| 1500 | if (phy->analog == 1) { | 1499 | if (phy->analog == 1) { |
| 1501 | b43_radio_set(dev, 0x007A, 0x0050); | 1500 | b43_radio_set(dev, 0x007A, 0x0050); |
| 1502 | } | 1501 | } |
| 1503 | if ((bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM) && | 1502 | if ((dev->dev->board_vendor != SSB_BOARDVENDOR_BCM) && |
| 1504 | (bus->boardinfo.type != SSB_BOARD_BU4306)) { | 1503 | (dev->dev->board_type != SSB_BOARD_BU4306)) { |
| 1505 | value = 0x2120; | 1504 | value = 0x2120; |
| 1506 | for (offset = 0x00A8; offset < 0x00C7; offset++) { | 1505 | for (offset = 0x00A8; offset < 0x00C7; offset++) { |
| 1507 | b43_phy_write(dev, offset, value); | 1506 | b43_phy_write(dev, offset, value); |
| @@ -1620,7 +1619,7 @@ static void b43_phy_initb6(struct b43_wldev *dev) | |||
| 1620 | b43_radio_write16(dev, 0x5A, 0x88); | 1619 | b43_radio_write16(dev, 0x5A, 0x88); |
| 1621 | b43_radio_write16(dev, 0x5B, 0x6B); | 1620 | b43_radio_write16(dev, 0x5B, 0x6B); |
| 1622 | b43_radio_write16(dev, 0x5C, 0x0F); | 1621 | b43_radio_write16(dev, 0x5C, 0x0F); |
| 1623 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_ALTIQ) { | 1622 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_ALTIQ) { |
| 1624 | b43_radio_write16(dev, 0x5D, 0xFA); | 1623 | b43_radio_write16(dev, 0x5D, 0xFA); |
| 1625 | b43_radio_write16(dev, 0x5E, 0xD8); | 1624 | b43_radio_write16(dev, 0x5E, 0xD8); |
| 1626 | } else { | 1625 | } else { |
| @@ -1787,7 +1786,7 @@ static void b43_calc_loopback_gain(struct b43_wldev *dev) | |||
| 1787 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); | 1786 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0100); |
| 1788 | b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); | 1787 | b43_phy_mask(dev, B43_PHY_RFOVERVAL, 0xCFFF); |
| 1789 | 1788 | ||
| 1790 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_EXTLNA) { | 1789 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_EXTLNA) { |
| 1791 | if (phy->rev >= 7) { | 1790 | if (phy->rev >= 7) { |
| 1792 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); | 1791 | b43_phy_set(dev, B43_PHY_RFOVER, 0x0800); |
| 1793 | b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); | 1792 | b43_phy_set(dev, B43_PHY_RFOVERVAL, 0x8000); |
| @@ -1922,7 +1921,6 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) | |||
| 1922 | /* Initialize B/G PHY power control */ | 1921 | /* Initialize B/G PHY power control */ |
| 1923 | static void b43_phy_init_pctl(struct b43_wldev *dev) | 1922 | static void b43_phy_init_pctl(struct b43_wldev *dev) |
| 1924 | { | 1923 | { |
| 1925 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 1926 | struct b43_phy *phy = &dev->phy; | 1924 | struct b43_phy *phy = &dev->phy; |
| 1927 | struct b43_phy_g *gphy = phy->g; | 1925 | struct b43_phy_g *gphy = phy->g; |
| 1928 | struct b43_rfatt old_rfatt; | 1926 | struct b43_rfatt old_rfatt; |
| @@ -1931,8 +1929,8 @@ static void b43_phy_init_pctl(struct b43_wldev *dev) | |||
| 1931 | 1929 | ||
| 1932 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | 1930 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); |
| 1933 | 1931 | ||
| 1934 | if ((bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM) && | 1932 | if ((dev->dev->board_vendor == SSB_BOARDVENDOR_BCM) && |
| 1935 | (bus->boardinfo.type == SSB_BOARD_BU4306)) | 1933 | (dev->dev->board_type == SSB_BOARD_BU4306)) |
| 1936 | return; | 1934 | return; |
| 1937 | 1935 | ||
| 1938 | b43_phy_write(dev, 0x0028, 0x8018); | 1936 | b43_phy_write(dev, 0x0028, 0x8018); |
| @@ -2053,7 +2051,7 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
| 2053 | if (phy->rev >= 6) { | 2051 | if (phy->rev >= 6) { |
| 2054 | b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); | 2052 | b43_phy_maskset(dev, B43_PHY_CCK(0x36), 0x0FFF, (gphy->lo_control->tx_bias << 12)); |
| 2055 | } | 2053 | } |
| 2056 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) | 2054 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) |
| 2057 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); | 2055 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x8075); |
| 2058 | else | 2056 | else |
| 2059 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); | 2057 | b43_phy_write(dev, B43_PHY_CCK(0x2E), 0x807F); |
| @@ -2066,7 +2064,7 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
| 2066 | b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); | 2064 | b43_phy_write(dev, B43_PHY_LO_MASK, 0x8078); |
| 2067 | } | 2065 | } |
| 2068 | 2066 | ||
| 2069 | if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) { | 2067 | if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) { |
| 2070 | /* The specs state to update the NRSSI LT with | 2068 | /* The specs state to update the NRSSI LT with |
| 2071 | * the value 0x7FFFFFFF here. I think that is some weird | 2069 | * the value 0x7FFFFFFF here. I think that is some weird |
| 2072 | * compiler optimization in the original driver. | 2070 | * compiler optimization in the original driver. |
| @@ -2088,8 +2086,8 @@ static void b43_phy_initg(struct b43_wldev *dev) | |||
| 2088 | /* FIXME: The spec says in the following if, the 0 should be replaced | 2086 | /* FIXME: The spec says in the following if, the 0 should be replaced |
| 2089 | 'if OFDM may not be used in the current locale' | 2087 | 'if OFDM may not be used in the current locale' |
| 2090 | but OFDM is legal everywhere */ | 2088 | but OFDM is legal everywhere */ |
| 2091 | if ((dev->sdev->bus->chip_id == 0x4306 | 2089 | if ((dev->dev->chip_id == 0x4306 |
| 2092 | && dev->sdev->bus->chip_package == 2) || 0) { | 2090 | && dev->dev->chip_pkg == 2) || 0) { |
| 2093 | b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); | 2091 | b43_phy_mask(dev, B43_PHY_CRS0, 0xBFFF); |
| 2094 | b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); | 2092 | b43_phy_mask(dev, B43_PHY_OFDM(0xC3), 0x7FFF); |
| 2095 | } | 2093 | } |
| @@ -2105,7 +2103,7 @@ void b43_gphy_channel_switch(struct b43_wldev *dev, | |||
| 2105 | b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); | 2103 | b43_write16(dev, B43_MMIO_CHANNEL, channel2freq_bg(channel)); |
| 2106 | 2104 | ||
| 2107 | if (channel == 14) { | 2105 | if (channel == 14) { |
| 2108 | if (dev->sdev->bus->sprom.country_code == | 2106 | if (dev->dev->bus_sprom->country_code == |
| 2109 | SSB_SPROM1CCODE_JAPAN) | 2107 | SSB_SPROM1CCODE_JAPAN) |
| 2110 | b43_hf_write(dev, | 2108 | b43_hf_write(dev, |
| 2111 | b43_hf_read(dev) & ~B43_HF_ACPR); | 2109 | b43_hf_read(dev) & ~B43_HF_ACPR); |
| @@ -2136,17 +2134,17 @@ static void default_baseband_attenuation(struct b43_wldev *dev, | |||
| 2136 | static void default_radio_attenuation(struct b43_wldev *dev, | 2134 | static void default_radio_attenuation(struct b43_wldev *dev, |
| 2137 | struct b43_rfatt *rf) | 2135 | struct b43_rfatt *rf) |
| 2138 | { | 2136 | { |
| 2139 | struct ssb_bus *bus = dev->sdev->bus; | 2137 | struct b43_bus_dev *bdev = dev->dev; |
| 2140 | struct b43_phy *phy = &dev->phy; | 2138 | struct b43_phy *phy = &dev->phy; |
| 2141 | 2139 | ||
| 2142 | rf->with_padmix = 0; | 2140 | rf->with_padmix = 0; |
| 2143 | 2141 | ||
| 2144 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && | 2142 | if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && |
| 2145 | bus->boardinfo.type == SSB_BOARD_BCM4309G) { | 2143 | dev->dev->board_type == SSB_BOARD_BCM4309G) { |
| 2146 | if (bus->boardinfo.rev < 0x43) { | 2144 | if (dev->dev->board_rev < 0x43) { |
| 2147 | rf->att = 2; | 2145 | rf->att = 2; |
| 2148 | return; | 2146 | return; |
| 2149 | } else if (bus->boardinfo.rev < 0x51) { | 2147 | } else if (dev->dev->board_rev < 0x51) { |
| 2150 | rf->att = 3; | 2148 | rf->att = 3; |
| 2151 | return; | 2149 | return; |
| 2152 | } | 2150 | } |
| @@ -2172,21 +2170,21 @@ static void default_radio_attenuation(struct b43_wldev *dev, | |||
| 2172 | return; | 2170 | return; |
| 2173 | case 1: | 2171 | case 1: |
| 2174 | if (phy->type == B43_PHYTYPE_G) { | 2172 | if (phy->type == B43_PHYTYPE_G) { |
| 2175 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM | 2173 | if (bdev->board_vendor == SSB_BOARDVENDOR_BCM |
| 2176 | && bus->boardinfo.type == SSB_BOARD_BCM4309G | 2174 | && bdev->board_type == SSB_BOARD_BCM4309G |
| 2177 | && bus->boardinfo.rev >= 30) | 2175 | && bdev->board_rev >= 30) |
| 2178 | rf->att = 3; | 2176 | rf->att = 3; |
| 2179 | else if (bus->boardinfo.vendor == | 2177 | else if (bdev->board_vendor == |
| 2180 | SSB_BOARDVENDOR_BCM | 2178 | SSB_BOARDVENDOR_BCM |
| 2181 | && bus->boardinfo.type == | 2179 | && bdev->board_type == |
| 2182 | SSB_BOARD_BU4306) | 2180 | SSB_BOARD_BU4306) |
| 2183 | rf->att = 3; | 2181 | rf->att = 3; |
| 2184 | else | 2182 | else |
| 2185 | rf->att = 1; | 2183 | rf->att = 1; |
| 2186 | } else { | 2184 | } else { |
| 2187 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM | 2185 | if (bdev->board_vendor == SSB_BOARDVENDOR_BCM |
| 2188 | && bus->boardinfo.type == SSB_BOARD_BCM4309G | 2186 | && bdev->board_type == SSB_BOARD_BCM4309G |
| 2189 | && bus->boardinfo.rev >= 30) | 2187 | && bdev->board_rev >= 30) |
| 2190 | rf->att = 7; | 2188 | rf->att = 7; |
| 2191 | else | 2189 | else |
| 2192 | rf->att = 6; | 2190 | rf->att = 6; |
| @@ -2194,16 +2192,16 @@ static void default_radio_attenuation(struct b43_wldev *dev, | |||
| 2194 | return; | 2192 | return; |
| 2195 | case 2: | 2193 | case 2: |
| 2196 | if (phy->type == B43_PHYTYPE_G) { | 2194 | if (phy->type == B43_PHYTYPE_G) { |
| 2197 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM | 2195 | if (bdev->board_vendor == SSB_BOARDVENDOR_BCM |
| 2198 | && bus->boardinfo.type == SSB_BOARD_BCM4309G | 2196 | && bdev->board_type == SSB_BOARD_BCM4309G |
| 2199 | && bus->boardinfo.rev >= 30) | 2197 | && bdev->board_rev >= 30) |
| 2200 | rf->att = 3; | 2198 | rf->att = 3; |
| 2201 | else if (bus->boardinfo.vendor == | 2199 | else if (bdev->board_vendor == |
| 2202 | SSB_BOARDVENDOR_BCM | 2200 | SSB_BOARDVENDOR_BCM |
| 2203 | && bus->boardinfo.type == | 2201 | && bdev->board_type == |
| 2204 | SSB_BOARD_BU4306) | 2202 | SSB_BOARD_BU4306) |
| 2205 | rf->att = 5; | 2203 | rf->att = 5; |
| 2206 | else if (bus->chip_id == 0x4320) | 2204 | else if (bdev->chip_id == 0x4320) |
| 2207 | rf->att = 4; | 2205 | rf->att = 4; |
| 2208 | else | 2206 | else |
| 2209 | rf->att = 3; | 2207 | rf->att = 3; |
| @@ -2384,11 +2382,11 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
| 2384 | struct b43_phy_g *gphy = phy->g; | 2382 | struct b43_phy_g *gphy = phy->g; |
| 2385 | s16 pab0, pab1, pab2; | 2383 | s16 pab0, pab1, pab2; |
| 2386 | 2384 | ||
| 2387 | pab0 = (s16) (dev->sdev->bus->sprom.pa0b0); | 2385 | pab0 = (s16) (dev->dev->bus_sprom->pa0b0); |
| 2388 | pab1 = (s16) (dev->sdev->bus->sprom.pa0b1); | 2386 | pab1 = (s16) (dev->dev->bus_sprom->pa0b1); |
| 2389 | pab2 = (s16) (dev->sdev->bus->sprom.pa0b2); | 2387 | pab2 = (s16) (dev->dev->bus_sprom->pa0b2); |
| 2390 | 2388 | ||
| 2391 | B43_WARN_ON((dev->sdev->bus->chip_id == 0x4301) && | 2389 | B43_WARN_ON((dev->dev->chip_id == 0x4301) && |
| 2392 | (phy->radio_ver != 0x2050)); /* Not supported anymore */ | 2390 | (phy->radio_ver != 0x2050)); /* Not supported anymore */ |
| 2393 | 2391 | ||
| 2394 | gphy->dyn_tssi_tbl = 0; | 2392 | gphy->dyn_tssi_tbl = 0; |
| @@ -2396,10 +2394,10 @@ static int b43_gphy_init_tssi2dbm_table(struct b43_wldev *dev) | |||
| 2396 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && | 2394 | if (pab0 != 0 && pab1 != 0 && pab2 != 0 && |
| 2397 | pab0 != -1 && pab1 != -1 && pab2 != -1) { | 2395 | pab0 != -1 && pab1 != -1 && pab2 != -1) { |
| 2398 | /* The pabX values are set in SPROM. Use them. */ | 2396 | /* The pabX values are set in SPROM. Use them. */ |
| 2399 | if ((s8) dev->sdev->bus->sprom.itssi_bg != 0 && | 2397 | if ((s8) dev->dev->bus_sprom->itssi_bg != 0 && |
| 2400 | (s8) dev->sdev->bus->sprom.itssi_bg != -1) { | 2398 | (s8) dev->dev->bus_sprom->itssi_bg != -1) { |
| 2401 | gphy->tgt_idle_tssi = | 2399 | gphy->tgt_idle_tssi = |
| 2402 | (s8) (dev->sdev->bus->sprom.itssi_bg); | 2400 | (s8) (dev->dev->bus_sprom->itssi_bg); |
| 2403 | } else | 2401 | } else |
| 2404 | gphy->tgt_idle_tssi = 62; | 2402 | gphy->tgt_idle_tssi = 62; |
| 2405 | gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, | 2403 | gphy->tssi2dbm = b43_generate_dyn_tssi2dbm_tab(dev, pab0, |
| @@ -2537,7 +2535,7 @@ static int b43_gphy_op_prepare_hardware(struct b43_wldev *dev) | |||
| 2537 | b43_wireless_core_reset(dev, 0); | 2535 | b43_wireless_core_reset(dev, 0); |
| 2538 | b43_phy_initg(dev); | 2536 | b43_phy_initg(dev); |
| 2539 | phy->gmode = 1; | 2537 | phy->gmode = 1; |
| 2540 | b43_wireless_core_reset(dev, B43_TMSLOW_GMODE); | 2538 | b43_wireless_core_reset(dev, 1); |
| 2541 | } | 2539 | } |
| 2542 | 2540 | ||
| 2543 | return 0; | 2541 | return 0; |
| @@ -2840,7 +2838,7 @@ static void b43_gphy_op_adjust_txpower(struct b43_wldev *dev) | |||
| 2840 | B43_TXCTL_TXMIX; | 2838 | B43_TXCTL_TXMIX; |
| 2841 | rfatt += 2; | 2839 | rfatt += 2; |
| 2842 | bbatt += 2; | 2840 | bbatt += 2; |
| 2843 | } else if (dev->sdev->bus->sprom. | 2841 | } else if (dev->dev->bus_sprom-> |
| 2844 | boardflags_lo & | 2842 | boardflags_lo & |
| 2845 | B43_BFL_PACTRL) { | 2843 | B43_BFL_PACTRL) { |
| 2846 | bbatt += 4 * (rfatt - 2); | 2844 | bbatt += 4 * (rfatt - 2); |
| @@ -2914,14 +2912,14 @@ static enum b43_txpwr_result b43_gphy_op_recalc_txpower(struct b43_wldev *dev, | |||
| 2914 | estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); | 2912 | estimated_pwr = b43_gphy_estimate_power_out(dev, average_tssi); |
| 2915 | 2913 | ||
| 2916 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); | 2914 | B43_WARN_ON(phy->type != B43_PHYTYPE_G); |
| 2917 | max_pwr = dev->sdev->bus->sprom.maxpwr_bg; | 2915 | max_pwr = dev->dev->bus_sprom->maxpwr_bg; |
| 2918 | if (dev->sdev->bus->sprom.boardflags_lo & B43_BFL_PACTRL) | 2916 | if (dev->dev->bus_sprom->boardflags_lo & B43_BFL_PACTRL) |
| 2919 | max_pwr -= 3; /* minus 0.75 */ | 2917 | max_pwr -= 3; /* minus 0.75 */ |
| 2920 | if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { | 2918 | if (unlikely(max_pwr >= INT_TO_Q52(30/*dBm*/))) { |
| 2921 | b43warn(dev->wl, | 2919 | b43warn(dev->wl, |
| 2922 | "Invalid max-TX-power value in SPROM.\n"); | 2920 | "Invalid max-TX-power value in SPROM.\n"); |
| 2923 | max_pwr = INT_TO_Q52(20); /* fake it */ | 2921 | max_pwr = INT_TO_Q52(20); /* fake it */ |
| 2924 | dev->sdev->bus->sprom.maxpwr_bg = max_pwr; | 2922 | dev->dev->bus_sprom->maxpwr_bg = max_pwr; |
| 2925 | } | 2923 | } |
| 2926 | 2924 | ||
| 2927 | /* Get desired power (in Q5.2) */ | 2925 | /* Get desired power (in Q5.2) */ |
| @@ -3014,7 +3012,7 @@ static void b43_gphy_op_pwork_60sec(struct b43_wldev *dev) | |||
| 3014 | { | 3012 | { |
| 3015 | struct b43_phy *phy = &dev->phy; | 3013 | struct b43_phy *phy = &dev->phy; |
| 3016 | 3014 | ||
| 3017 | if (!(dev->sdev->bus->sprom.boardflags_lo & B43_BFL_RSSI)) | 3015 | if (!(dev->dev->bus_sprom->boardflags_lo & B43_BFL_RSSI)) |
| 3018 | return; | 3016 | return; |
| 3019 | 3017 | ||
| 3020 | b43_mac_suspend(dev); | 3018 | b43_mac_suspend(dev); |
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c index 012c8da2f944..daec1d9e4a18 100644 --- a/drivers/net/wireless/b43/phy_lp.c +++ b/drivers/net/wireless/b43/phy_lp.c | |||
| @@ -85,39 +85,39 @@ static void b43_lpphy_op_free(struct b43_wldev *dev) | |||
| 85 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */ | 85 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */ |
| 86 | static void lpphy_read_band_sprom(struct b43_wldev *dev) | 86 | static void lpphy_read_band_sprom(struct b43_wldev *dev) |
| 87 | { | 87 | { |
| 88 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
| 88 | struct b43_phy_lp *lpphy = dev->phy.lp; | 89 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 89 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 90 | u16 cckpo, maxpwr; | 90 | u16 cckpo, maxpwr; |
| 91 | u32 ofdmpo; | 91 | u32 ofdmpo; |
| 92 | int i; | 92 | int i; |
| 93 | 93 | ||
| 94 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { | 94 | if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { |
| 95 | lpphy->tx_isolation_med_band = bus->sprom.tri2g; | 95 | lpphy->tx_isolation_med_band = sprom->tri2g; |
| 96 | lpphy->bx_arch = bus->sprom.bxa2g; | 96 | lpphy->bx_arch = sprom->bxa2g; |
| 97 | lpphy->rx_pwr_offset = bus->sprom.rxpo2g; | 97 | lpphy->rx_pwr_offset = sprom->rxpo2g; |
| 98 | lpphy->rssi_vf = bus->sprom.rssismf2g; | 98 | lpphy->rssi_vf = sprom->rssismf2g; |
| 99 | lpphy->rssi_vc = bus->sprom.rssismc2g; | 99 | lpphy->rssi_vc = sprom->rssismc2g; |
| 100 | lpphy->rssi_gs = bus->sprom.rssisav2g; | 100 | lpphy->rssi_gs = sprom->rssisav2g; |
| 101 | lpphy->txpa[0] = bus->sprom.pa0b0; | 101 | lpphy->txpa[0] = sprom->pa0b0; |
| 102 | lpphy->txpa[1] = bus->sprom.pa0b1; | 102 | lpphy->txpa[1] = sprom->pa0b1; |
| 103 | lpphy->txpa[2] = bus->sprom.pa0b2; | 103 | lpphy->txpa[2] = sprom->pa0b2; |
| 104 | maxpwr = bus->sprom.maxpwr_bg; | 104 | maxpwr = sprom->maxpwr_bg; |
| 105 | lpphy->max_tx_pwr_med_band = maxpwr; | 105 | lpphy->max_tx_pwr_med_band = maxpwr; |
| 106 | cckpo = bus->sprom.cck2gpo; | 106 | cckpo = sprom->cck2gpo; |
| 107 | /* | 107 | /* |
| 108 | * We don't read SPROM's opo as specs say. On rev8 SPROMs | 108 | * We don't read SPROM's opo as specs say. On rev8 SPROMs |
| 109 | * opo == ofdm2gpo and we don't know any SSB with LP-PHY | 109 | * opo == ofdm2gpo and we don't know any SSB with LP-PHY |
| 110 | * and SPROM rev below 8. | 110 | * and SPROM rev below 8. |
| 111 | */ | 111 | */ |
| 112 | B43_WARN_ON(bus->sprom.revision < 8); | 112 | B43_WARN_ON(sprom->revision < 8); |
| 113 | ofdmpo = bus->sprom.ofdm2gpo; | 113 | ofdmpo = sprom->ofdm2gpo; |
| 114 | if (cckpo) { | 114 | if (cckpo) { |
| 115 | for (i = 0; i < 4; i++) { | 115 | for (i = 0; i < 4; i++) { |
| 116 | lpphy->tx_max_rate[i] = | 116 | lpphy->tx_max_rate[i] = |
| 117 | maxpwr - (ofdmpo & 0xF) * 2; | 117 | maxpwr - (ofdmpo & 0xF) * 2; |
| 118 | ofdmpo >>= 4; | 118 | ofdmpo >>= 4; |
| 119 | } | 119 | } |
| 120 | ofdmpo = bus->sprom.ofdm2gpo; | 120 | ofdmpo = sprom->ofdm2gpo; |
| 121 | for (i = 4; i < 15; i++) { | 121 | for (i = 4; i < 15; i++) { |
| 122 | lpphy->tx_max_rate[i] = | 122 | lpphy->tx_max_rate[i] = |
| 123 | maxpwr - (ofdmpo & 0xF) * 2; | 123 | maxpwr - (ofdmpo & 0xF) * 2; |
| @@ -131,39 +131,39 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev) | |||
| 131 | lpphy->tx_max_rate[i] = maxpwr - ofdmpo; | 131 | lpphy->tx_max_rate[i] = maxpwr - ofdmpo; |
| 132 | } | 132 | } |
| 133 | } else { /* 5GHz */ | 133 | } else { /* 5GHz */ |
| 134 | lpphy->tx_isolation_low_band = bus->sprom.tri5gl; | 134 | lpphy->tx_isolation_low_band = sprom->tri5gl; |
| 135 | lpphy->tx_isolation_med_band = bus->sprom.tri5g; | 135 | lpphy->tx_isolation_med_band = sprom->tri5g; |
| 136 | lpphy->tx_isolation_hi_band = bus->sprom.tri5gh; | 136 | lpphy->tx_isolation_hi_band = sprom->tri5gh; |
| 137 | lpphy->bx_arch = bus->sprom.bxa5g; | 137 | lpphy->bx_arch = sprom->bxa5g; |
| 138 | lpphy->rx_pwr_offset = bus->sprom.rxpo5g; | 138 | lpphy->rx_pwr_offset = sprom->rxpo5g; |
| 139 | lpphy->rssi_vf = bus->sprom.rssismf5g; | 139 | lpphy->rssi_vf = sprom->rssismf5g; |
| 140 | lpphy->rssi_vc = bus->sprom.rssismc5g; | 140 | lpphy->rssi_vc = sprom->rssismc5g; |
| 141 | lpphy->rssi_gs = bus->sprom.rssisav5g; | 141 | lpphy->rssi_gs = sprom->rssisav5g; |
| 142 | lpphy->txpa[0] = bus->sprom.pa1b0; | 142 | lpphy->txpa[0] = sprom->pa1b0; |
| 143 | lpphy->txpa[1] = bus->sprom.pa1b1; | 143 | lpphy->txpa[1] = sprom->pa1b1; |
| 144 | lpphy->txpa[2] = bus->sprom.pa1b2; | 144 | lpphy->txpa[2] = sprom->pa1b2; |
| 145 | lpphy->txpal[0] = bus->sprom.pa1lob0; | 145 | lpphy->txpal[0] = sprom->pa1lob0; |
| 146 | lpphy->txpal[1] = bus->sprom.pa1lob1; | 146 | lpphy->txpal[1] = sprom->pa1lob1; |
| 147 | lpphy->txpal[2] = bus->sprom.pa1lob2; | 147 | lpphy->txpal[2] = sprom->pa1lob2; |
| 148 | lpphy->txpah[0] = bus->sprom.pa1hib0; | 148 | lpphy->txpah[0] = sprom->pa1hib0; |
| 149 | lpphy->txpah[1] = bus->sprom.pa1hib1; | 149 | lpphy->txpah[1] = sprom->pa1hib1; |
| 150 | lpphy->txpah[2] = bus->sprom.pa1hib2; | 150 | lpphy->txpah[2] = sprom->pa1hib2; |
| 151 | maxpwr = bus->sprom.maxpwr_al; | 151 | maxpwr = sprom->maxpwr_al; |
| 152 | ofdmpo = bus->sprom.ofdm5glpo; | 152 | ofdmpo = sprom->ofdm5glpo; |
| 153 | lpphy->max_tx_pwr_low_band = maxpwr; | 153 | lpphy->max_tx_pwr_low_band = maxpwr; |
| 154 | for (i = 4; i < 12; i++) { | 154 | for (i = 4; i < 12; i++) { |
| 155 | lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2; | 155 | lpphy->tx_max_ratel[i] = maxpwr - (ofdmpo & 0xF) * 2; |
| 156 | ofdmpo >>= 4; | 156 | ofdmpo >>= 4; |
| 157 | } | 157 | } |
| 158 | maxpwr = bus->sprom.maxpwr_a; | 158 | maxpwr = sprom->maxpwr_a; |
| 159 | ofdmpo = bus->sprom.ofdm5gpo; | 159 | ofdmpo = sprom->ofdm5gpo; |
| 160 | lpphy->max_tx_pwr_med_band = maxpwr; | 160 | lpphy->max_tx_pwr_med_band = maxpwr; |
| 161 | for (i = 4; i < 12; i++) { | 161 | for (i = 4; i < 12; i++) { |
| 162 | lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; | 162 | lpphy->tx_max_rate[i] = maxpwr - (ofdmpo & 0xF) * 2; |
| 163 | ofdmpo >>= 4; | 163 | ofdmpo >>= 4; |
| 164 | } | 164 | } |
| 165 | maxpwr = bus->sprom.maxpwr_ah; | 165 | maxpwr = sprom->maxpwr_ah; |
| 166 | ofdmpo = bus->sprom.ofdm5ghpo; | 166 | ofdmpo = sprom->ofdm5ghpo; |
| 167 | lpphy->max_tx_pwr_hi_band = maxpwr; | 167 | lpphy->max_tx_pwr_hi_band = maxpwr; |
| 168 | for (i = 4; i < 12; i++) { | 168 | for (i = 4; i < 12; i++) { |
| 169 | lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2; | 169 | lpphy->tx_max_rateh[i] = maxpwr - (ofdmpo & 0xF) * 2; |
| @@ -214,7 +214,8 @@ static void lpphy_table_init(struct b43_wldev *dev) | |||
| 214 | 214 | ||
| 215 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | 215 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) |
| 216 | { | 216 | { |
| 217 | struct ssb_bus *bus = dev->sdev->bus; | 217 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 218 | struct ssb_sprom *sprom = dev->dev->bus_sprom; | ||
| 218 | struct b43_phy_lp *lpphy = dev->phy.lp; | 219 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 219 | u16 tmp, tmp2; | 220 | u16 tmp, tmp2; |
| 220 | 221 | ||
| @@ -242,9 +243,9 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 242 | b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00); | 243 | b43_phy_maskset(dev, B43_LPPHY_CRS_ED_THRESH, 0x00FF, 0xAD00); |
| 243 | b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, | 244 | b43_phy_maskset(dev, B43_LPPHY_INPUT_PWRDB, |
| 244 | 0xFF00, lpphy->rx_pwr_offset); | 245 | 0xFF00, lpphy->rx_pwr_offset); |
| 245 | if ((bus->sprom.boardflags_lo & B43_BFL_FEM) && | 246 | if ((sprom->boardflags_lo & B43_BFL_FEM) && |
| 246 | ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | 247 | ((b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || |
| 247 | (bus->sprom.boardflags_hi & B43_BFH_PAREF))) { | 248 | (sprom->boardflags_hi & B43_BFH_PAREF))) { |
| 248 | ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28); | 249 | ssb_pmu_set_ldo_voltage(&bus->chipco, LDO_PAREF, 0x28); |
| 249 | ssb_pmu_set_ldo_paref(&bus->chipco, true); | 250 | ssb_pmu_set_ldo_paref(&bus->chipco, true); |
| 250 | if (dev->phy.rev == 0) { | 251 | if (dev->phy.rev == 0) { |
| @@ -260,7 +261,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 260 | } | 261 | } |
| 261 | tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000; | 262 | tmp = lpphy->rssi_vf | lpphy->rssi_vc << 4 | 0xA000; |
| 262 | b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp); | 263 | b43_phy_write(dev, B43_LPPHY_AFE_RSSI_CTL_0, tmp); |
| 263 | if (bus->sprom.boardflags_hi & B43_BFH_RSSIINV) | 264 | if (sprom->boardflags_hi & B43_BFH_RSSIINV) |
| 264 | b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA); | 265 | b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x0AAA); |
| 265 | else | 266 | else |
| 266 | b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA); | 267 | b43_phy_maskset(dev, B43_LPPHY_AFE_RSSI_CTL_1, 0xF000, 0x02AA); |
| @@ -268,7 +269,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 268 | b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL, | 269 | b43_phy_maskset(dev, B43_LPPHY_RX_RADIO_CTL, |
| 269 | 0xFFF9, (lpphy->bx_arch << 1)); | 270 | 0xFFF9, (lpphy->bx_arch << 1)); |
| 270 | if (dev->phy.rev == 1 && | 271 | if (dev->phy.rev == 1 && |
| 271 | (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) { | 272 | (sprom->boardflags_hi & B43_BFH_FEM_BT)) { |
| 272 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A); | 273 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A); |
| 273 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900); | 274 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900); |
| 274 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A); | 275 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A); |
| @@ -286,8 +287,8 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 286 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); | 287 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A); |
| 287 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); | 288 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00); |
| 288 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || | 289 | } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ || |
| 289 | (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) && | 290 | (dev->dev->board_type == 0x048A) || ((dev->phy.rev == 0) && |
| 290 | (bus->sprom.boardflags_lo & B43_BFL_FEM))) { | 291 | (sprom->boardflags_lo & B43_BFL_FEM))) { |
| 291 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); | 292 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001); |
| 292 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); | 293 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400); |
| 293 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); | 294 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001); |
| @@ -297,7 +298,7 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 297 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002); | 298 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002); |
| 298 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00); | 299 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00); |
| 299 | } else if (dev->phy.rev == 1 || | 300 | } else if (dev->phy.rev == 1 || |
| 300 | (bus->sprom.boardflags_lo & B43_BFL_FEM)) { | 301 | (sprom->boardflags_lo & B43_BFL_FEM)) { |
| 301 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004); | 302 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004); |
| 302 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800); | 303 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800); |
| 303 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004); | 304 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004); |
| @@ -316,15 +317,15 @@ static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | |||
| 316 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006); | 317 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006); |
| 317 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700); | 318 | b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700); |
| 318 | } | 319 | } |
| 319 | if (dev->phy.rev == 1 && (bus->sprom.boardflags_hi & B43_BFH_PAREF)) { | 320 | if (dev->phy.rev == 1 && (sprom->boardflags_hi & B43_BFH_PAREF)) { |
| 320 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1); | 321 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1); |
| 321 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2); | 322 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2); |
| 322 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3); | 323 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3); |
| 323 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4); | 324 | b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4); |
| 324 | } | 325 | } |
| 325 | if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) && | 326 | if ((sprom->boardflags_hi & B43_BFH_FEM_BT) && |
| 326 | (bus->chip_id == 0x5354) && | 327 | (dev->dev->chip_id == 0x5354) && |
| 327 | (bus->chip_package == SSB_CHIPPACK_BCM4712S)) { | 328 | (dev->dev->chip_pkg == SSB_CHIPPACK_BCM4712S)) { |
| 328 | b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); | 329 | b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006); |
| 329 | b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005); | 330 | b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005); |
| 330 | b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF); | 331 | b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF); |
| @@ -412,7 +413,6 @@ static void lpphy_restore_dig_flt_state(struct b43_wldev *dev) | |||
| 412 | 413 | ||
| 413 | static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | 414 | static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) |
| 414 | { | 415 | { |
| 415 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 416 | struct b43_phy_lp *lpphy = dev->phy.lp; | 416 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 417 | 417 | ||
| 418 | b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); | 418 | b43_phy_write(dev, B43_LPPHY_AFE_DAC_CTL, 0x50); |
| @@ -432,7 +432,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | |||
| 432 | b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000); | 432 | b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x4000); |
| 433 | b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000); | 433 | b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, ~0x2000); |
| 434 | b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1); | 434 | b43_phy_set(dev, B43_PHY_OFDM(0x10A), 0x1); |
| 435 | if (bus->boardinfo.rev >= 0x18) { | 435 | if (dev->dev->board_rev >= 0x18) { |
| 436 | b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC); | 436 | b43_lptab_write(dev, B43_LPTAB32(17, 65), 0xEC); |
| 437 | b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14); | 437 | b43_phy_maskset(dev, B43_PHY_OFDM(0x10A), 0xFF01, 0x14); |
| 438 | } else { | 438 | } else { |
| @@ -449,7 +449,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | |||
| 449 | b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0); | 449 | b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFC1F, 0xA0); |
| 450 | b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300); | 450 | b43_phy_maskset(dev, B43_LPPHY_GAINDIRECTMISMATCH, 0xE0FF, 0x300); |
| 451 | b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00); | 451 | b43_phy_maskset(dev, B43_LPPHY_HIGAINDB, 0x00FF, 0x2A00); |
| 452 | if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { | 452 | if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { |
| 453 | b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100); | 453 | b43_phy_maskset(dev, B43_LPPHY_LOWGAINDB, 0x00FF, 0x2100); |
| 454 | b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA); | 454 | b43_phy_maskset(dev, B43_LPPHY_VERYLOWGAINDB, 0xFF00, 0xA); |
| 455 | } else { | 455 | } else { |
| @@ -467,7 +467,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | |||
| 467 | b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12); | 467 | b43_phy_maskset(dev, B43_LPPHY_CLIPCTRTHRESH, 0xFFE0, 0x12); |
| 468 | b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000); | 468 | b43_phy_maskset(dev, B43_LPPHY_GAINMISMATCH, 0x0FFF, 0x9000); |
| 469 | 469 | ||
| 470 | if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { | 470 | if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { |
| 471 | b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0); | 471 | b43_lptab_write(dev, B43_LPTAB16(0x08, 0x14), 0); |
| 472 | b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40); | 472 | b43_lptab_write(dev, B43_LPTAB16(0x08, 0x12), 0x40); |
| 473 | } | 473 | } |
| @@ -492,7 +492,7 @@ static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | |||
| 492 | 0x2000 | ((u16)lpphy->rssi_gs << 10) | | 492 | 0x2000 | ((u16)lpphy->rssi_gs << 10) | |
| 493 | ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf); | 493 | ((u16)lpphy->rssi_vc << 4) | lpphy->rssi_vf); |
| 494 | 494 | ||
| 495 | if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { | 495 | if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { |
| 496 | b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C); | 496 | b43_phy_set(dev, B43_LPPHY_AFE_ADC_CTL_0, 0x1C); |
| 497 | b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800); | 497 | b43_phy_maskset(dev, B43_LPPHY_AFE_CTL, 0x00FF, 0x8800); |
| 498 | b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400); | 498 | b43_phy_maskset(dev, B43_LPPHY_AFE_ADC_CTL_1, 0xFC3C, 0x0400); |
| @@ -519,7 +519,7 @@ struct b2062_freqdata { | |||
| 519 | static void lpphy_2062_init(struct b43_wldev *dev) | 519 | static void lpphy_2062_init(struct b43_wldev *dev) |
| 520 | { | 520 | { |
| 521 | struct b43_phy_lp *lpphy = dev->phy.lp; | 521 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 522 | struct ssb_bus *bus = dev->sdev->bus; | 522 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 523 | u32 crystalfreq, tmp, ref; | 523 | u32 crystalfreq, tmp, ref; |
| 524 | unsigned int i; | 524 | unsigned int i; |
| 525 | const struct b2062_freqdata *fd = NULL; | 525 | const struct b2062_freqdata *fd = NULL; |
| @@ -697,7 +697,7 @@ static void lpphy_radio_init(struct b43_wldev *dev) | |||
| 697 | lpphy_sync_stx(dev); | 697 | lpphy_sync_stx(dev); |
| 698 | b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); | 698 | b43_phy_write(dev, B43_PHY_OFDM(0xF0), 0x5F80); |
| 699 | b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); | 699 | b43_phy_write(dev, B43_PHY_OFDM(0xF1), 0); |
| 700 | if (dev->sdev->bus->chip_id == 0x4325) { | 700 | if (dev->dev->chip_id == 0x4325) { |
| 701 | // TODO SSB PMU recalibration | 701 | // TODO SSB PMU recalibration |
| 702 | } | 702 | } |
| 703 | } | 703 | } |
| @@ -1289,7 +1289,7 @@ finish: | |||
| 1289 | 1289 | ||
| 1290 | static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) | 1290 | static void lpphy_rev2plus_rc_calib(struct b43_wldev *dev) |
| 1291 | { | 1291 | { |
| 1292 | struct ssb_bus *bus = dev->sdev->bus; | 1292 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 1293 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 1293 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
| 1294 | u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; | 1294 | u8 tmp = b43_radio_read(dev, B2063_RX_BB_SP8) & 0xFF; |
| 1295 | int i; | 1295 | int i; |
| @@ -1840,7 +1840,6 @@ static void lpphy_papd_cal(struct b43_wldev *dev, struct lpphy_tx_gains gains, | |||
| 1840 | static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) | 1840 | static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) |
| 1841 | { | 1841 | { |
| 1842 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1842 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 1843 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 1844 | struct lpphy_tx_gains gains, oldgains; | 1843 | struct lpphy_tx_gains gains, oldgains; |
| 1845 | int old_txpctl, old_afe_ovr, old_rf, old_bbmult; | 1844 | int old_txpctl, old_afe_ovr, old_rf, old_bbmult; |
| 1846 | 1845 | ||
| @@ -1854,7 +1853,7 @@ static void lpphy_papd_cal_txpwr(struct b43_wldev *dev) | |||
| 1854 | 1853 | ||
| 1855 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); | 1854 | lpphy_set_tx_power_control(dev, B43_LPPHY_TXPCTL_OFF); |
| 1856 | 1855 | ||
| 1857 | if (bus->chip_id == 0x4325 && bus->chip_rev == 0) | 1856 | if (dev->dev->chip_id == 0x4325 && dev->dev->chip_rev == 0) |
| 1858 | lpphy_papd_cal(dev, gains, 0, 1, 30); | 1857 | lpphy_papd_cal(dev, gains, 0, 1, 30); |
| 1859 | else | 1858 | else |
| 1860 | lpphy_papd_cal(dev, gains, 0, 1, 65); | 1859 | lpphy_papd_cal(dev, gains, 0, 1, 65); |
| @@ -1870,7 +1869,6 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, | |||
| 1870 | bool rx, bool pa, struct lpphy_tx_gains *gains) | 1869 | bool rx, bool pa, struct lpphy_tx_gains *gains) |
| 1871 | { | 1870 | { |
| 1872 | struct b43_phy_lp *lpphy = dev->phy.lp; | 1871 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 1873 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 1874 | const struct lpphy_rx_iq_comp *iqcomp = NULL; | 1872 | const struct lpphy_rx_iq_comp *iqcomp = NULL; |
| 1875 | struct lpphy_tx_gains nogains, oldgains; | 1873 | struct lpphy_tx_gains nogains, oldgains; |
| 1876 | u16 tmp; | 1874 | u16 tmp; |
| @@ -1879,7 +1877,7 @@ static int lpphy_rx_iq_cal(struct b43_wldev *dev, bool noise, bool tx, | |||
| 1879 | memset(&nogains, 0, sizeof(nogains)); | 1877 | memset(&nogains, 0, sizeof(nogains)); |
| 1880 | memset(&oldgains, 0, sizeof(oldgains)); | 1878 | memset(&oldgains, 0, sizeof(oldgains)); |
| 1881 | 1879 | ||
| 1882 | if (bus->chip_id == 0x5354) { | 1880 | if (dev->dev->chip_id == 0x5354) { |
| 1883 | for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { | 1881 | for (i = 0; i < ARRAY_SIZE(lpphy_5354_iq_table); i++) { |
| 1884 | if (lpphy_5354_iq_table[i].chan == lpphy->channel) { | 1882 | if (lpphy_5354_iq_table[i].chan == lpphy->channel) { |
| 1885 | iqcomp = &lpphy_5354_iq_table[i]; | 1883 | iqcomp = &lpphy_5354_iq_table[i]; |
| @@ -2408,11 +2406,9 @@ static const struct b206x_channel b2063_chantbl[] = { | |||
| 2408 | 2406 | ||
| 2409 | static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) | 2407 | static void lpphy_b2062_reset_pll_bias(struct b43_wldev *dev) |
| 2410 | { | 2408 | { |
| 2411 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 2412 | |||
| 2413 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); | 2409 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 0xFF); |
| 2414 | udelay(20); | 2410 | udelay(20); |
| 2415 | if (bus->chip_id == 0x5354) { | 2411 | if (dev->dev->chip_id == 0x5354) { |
| 2416 | b43_radio_write(dev, B2062_N_COMM1, 4); | 2412 | b43_radio_write(dev, B2062_N_COMM1, 4); |
| 2417 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4); | 2413 | b43_radio_write(dev, B2062_S_RFPLL_CTL2, 4); |
| 2418 | } else { | 2414 | } else { |
| @@ -2432,7 +2428,7 @@ static int lpphy_b2062_tune(struct b43_wldev *dev, | |||
| 2432 | unsigned int channel) | 2428 | unsigned int channel) |
| 2433 | { | 2429 | { |
| 2434 | struct b43_phy_lp *lpphy = dev->phy.lp; | 2430 | struct b43_phy_lp *lpphy = dev->phy.lp; |
| 2435 | struct ssb_bus *bus = dev->sdev->bus; | 2431 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 2436 | const struct b206x_channel *chandata = NULL; | 2432 | const struct b206x_channel *chandata = NULL; |
| 2437 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 2433 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
| 2438 | u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; | 2434 | u32 tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; |
| @@ -2522,7 +2518,7 @@ static void lpphy_b2063_vco_calib(struct b43_wldev *dev) | |||
| 2522 | static int lpphy_b2063_tune(struct b43_wldev *dev, | 2518 | static int lpphy_b2063_tune(struct b43_wldev *dev, |
| 2523 | unsigned int channel) | 2519 | unsigned int channel) |
| 2524 | { | 2520 | { |
| 2525 | struct ssb_bus *bus = dev->sdev->bus; | 2521 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 2526 | 2522 | ||
| 2527 | static const struct b206x_channel *chandata = NULL; | 2523 | static const struct b206x_channel *chandata = NULL; |
| 2528 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; | 2524 | u32 crystal_freq = bus->chipco.pmu.crystalfreq * 1000; |
| @@ -2670,6 +2666,11 @@ static int b43_lpphy_op_init(struct b43_wldev *dev) | |||
| 2670 | { | 2666 | { |
| 2671 | int err; | 2667 | int err; |
| 2672 | 2668 | ||
| 2669 | if (dev->dev->bus_type != B43_BUS_SSB) { | ||
| 2670 | b43err(dev->wl, "LP-PHY is supported only on SSB!\n"); | ||
| 2671 | return -EOPNOTSUPP; | ||
| 2672 | } | ||
| 2673 | |||
| 2673 | lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? | 2674 | lpphy_read_band_sprom(dev); //FIXME should this be in prepare_structs? |
| 2674 | lpphy_baseband_init(dev); | 2675 | lpphy_baseband_init(dev); |
| 2675 | lpphy_radio_init(dev); | 2676 | lpphy_radio_init(dev); |
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 05960ddde24e..ad14f3b428c5 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
| @@ -299,7 +299,7 @@ static void b43_nphy_tx_power_ctrl(struct b43_wldev *dev, bool enable) | |||
| 299 | static void b43_nphy_tx_power_fix(struct b43_wldev *dev) | 299 | static void b43_nphy_tx_power_fix(struct b43_wldev *dev) |
| 300 | { | 300 | { |
| 301 | struct b43_phy_n *nphy = dev->phy.n; | 301 | struct b43_phy_n *nphy = dev->phy.n; |
| 302 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); | 302 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 303 | 303 | ||
| 304 | u8 txpi[2], bbmult, i; | 304 | u8 txpi[2], bbmult, i; |
| 305 | u16 tmp, radio_gain, dac_gain; | 305 | u16 tmp, radio_gain, dac_gain; |
| @@ -423,16 +423,15 @@ static void b43_radio_init2055_pre(struct b43_wldev *dev) | |||
| 423 | static void b43_radio_init2055_post(struct b43_wldev *dev) | 423 | static void b43_radio_init2055_post(struct b43_wldev *dev) |
| 424 | { | 424 | { |
| 425 | struct b43_phy_n *nphy = dev->phy.n; | 425 | struct b43_phy_n *nphy = dev->phy.n; |
| 426 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); | 426 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 427 | struct ssb_boardinfo *binfo = &(dev->sdev->bus->boardinfo); | ||
| 428 | int i; | 427 | int i; |
| 429 | u16 val; | 428 | u16 val; |
| 430 | bool workaround = false; | 429 | bool workaround = false; |
| 431 | 430 | ||
| 432 | if (sprom->revision < 4) | 431 | if (sprom->revision < 4) |
| 433 | workaround = (binfo->vendor != PCI_VENDOR_ID_BROADCOM && | 432 | workaround = (dev->dev->board_vendor != PCI_VENDOR_ID_BROADCOM |
| 434 | binfo->type == 0x46D && | 433 | && dev->dev->board_type == 0x46D |
| 435 | binfo->rev >= 0x41); | 434 | && dev->dev->board_rev >= 0x41); |
| 436 | else | 435 | else |
| 437 | workaround = | 436 | workaround = |
| 438 | !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); | 437 | !(sprom->boardflags2_lo & B43_BFL2_RXBB_INT_REG_DIS); |
| @@ -983,7 +982,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | |||
| 983 | { | 982 | { |
| 984 | u16 tmp; | 983 | u16 tmp; |
| 985 | 984 | ||
| 986 | if (dev->sdev->id.revision == 16) | 985 | if (dev->dev->core_rev == 16) |
| 987 | b43_mac_suspend(dev); | 986 | b43_mac_suspend(dev); |
| 988 | 987 | ||
| 989 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); | 988 | tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL); |
| @@ -993,7 +992,7 @@ static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val) | |||
| 993 | tmp |= (val & mask); | 992 | tmp |= (val & mask); |
| 994 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); | 993 | b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp); |
| 995 | 994 | ||
| 996 | if (dev->sdev->id.revision == 16) | 995 | if (dev->dev->core_rev == 16) |
| 997 | b43_mac_enable(dev); | 996 | b43_mac_enable(dev); |
| 998 | 997 | ||
| 999 | return tmp; | 998 | return tmp; |
| @@ -1168,7 +1167,7 @@ static void b43_nphy_adjust_lna_gain_table(struct b43_wldev *dev) | |||
| 1168 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | 1167 | static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) |
| 1169 | { | 1168 | { |
| 1170 | struct b43_phy_n *nphy = dev->phy.n; | 1169 | struct b43_phy_n *nphy = dev->phy.n; |
| 1171 | struct ssb_sprom *sprom = &(dev->sdev->bus->sprom); | 1170 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 1172 | 1171 | ||
| 1173 | /* PHY rev 0, 1, 2 */ | 1172 | /* PHY rev 0, 1, 2 */ |
| 1174 | u8 i, j; | 1173 | u8 i, j; |
| @@ -1373,7 +1372,7 @@ static void b43_nphy_gain_ctrl_workarounds(struct b43_wldev *dev) | |||
| 1373 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ | 1372 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/Workarounds */ |
| 1374 | static void b43_nphy_workarounds(struct b43_wldev *dev) | 1373 | static void b43_nphy_workarounds(struct b43_wldev *dev) |
| 1375 | { | 1374 | { |
| 1376 | struct ssb_bus *bus = dev->sdev->bus; | 1375 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 1377 | struct b43_phy *phy = &dev->phy; | 1376 | struct b43_phy *phy = &dev->phy; |
| 1378 | struct b43_phy_n *nphy = phy->n; | 1377 | struct b43_phy_n *nphy = phy->n; |
| 1379 | 1378 | ||
| @@ -1443,9 +1442,9 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) | |||
| 1443 | 1442 | ||
| 1444 | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ | 1443 | /* N PHY WAR TX Chain Update with hw_phytxchain as argument */ |
| 1445 | 1444 | ||
| 1446 | if ((bus->sprom.boardflags2_lo & B43_BFL2_APLL_WAR && | 1445 | if ((sprom->boardflags2_lo & B43_BFL2_APLL_WAR && |
| 1447 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || | 1446 | b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) || |
| 1448 | (bus->sprom.boardflags2_lo & B43_BFL2_GPLL_WAR && | 1447 | (sprom->boardflags2_lo & B43_BFL2_GPLL_WAR && |
| 1449 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) | 1448 | b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) |
| 1450 | tmp32 = 0x00088888; | 1449 | tmp32 = 0x00088888; |
| 1451 | else | 1450 | else |
| @@ -1503,8 +1502,8 @@ static void b43_nphy_workarounds(struct b43_wldev *dev) | |||
| 1503 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | 1502 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); |
| 1504 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | 1503 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); |
| 1505 | 1504 | ||
| 1506 | if (bus->sprom.boardflags2_lo & 0x100 && | 1505 | if (sprom->boardflags2_lo & 0x100 && |
| 1507 | bus->boardinfo.type == 0x8B) { | 1506 | dev->dev->board_type == 0x8B) { |
| 1508 | delays1[0] = 0x1; | 1507 | delays1[0] = 0x1; |
| 1509 | delays1[5] = 0x14; | 1508 | delays1[5] = 0x14; |
| 1510 | } | 1509 | } |
| @@ -3586,7 +3585,7 @@ static void b43_nphy_set_rx_core_state(struct b43_wldev *dev, u8 mask) | |||
| 3586 | */ | 3585 | */ |
| 3587 | int b43_phy_initn(struct b43_wldev *dev) | 3586 | int b43_phy_initn(struct b43_wldev *dev) |
| 3588 | { | 3587 | { |
| 3589 | struct ssb_bus *bus = dev->sdev->bus; | 3588 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 3590 | struct b43_phy *phy = &dev->phy; | 3589 | struct b43_phy *phy = &dev->phy; |
| 3591 | struct b43_phy_n *nphy = phy->n; | 3590 | struct b43_phy_n *nphy = phy->n; |
| 3592 | u8 tx_pwr_state; | 3591 | u8 tx_pwr_state; |
| @@ -3599,7 +3598,7 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
| 3599 | bool do_cal = false; | 3598 | bool do_cal = false; |
| 3600 | 3599 | ||
| 3601 | if ((dev->phy.rev >= 3) && | 3600 | if ((dev->phy.rev >= 3) && |
| 3602 | (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && | 3601 | (sprom->boardflags_lo & B43_BFL_EXTLNA) && |
| 3603 | (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { | 3602 | (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) { |
| 3604 | chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); | 3603 | chipco_set32(&dev->sdev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40); |
| 3605 | } | 3604 | } |
| @@ -3639,9 +3638,9 @@ int b43_phy_initn(struct b43_wldev *dev) | |||
| 3639 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); | 3638 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); |
| 3640 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); | 3639 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); |
| 3641 | 3640 | ||
| 3642 | if (bus->sprom.boardflags2_lo & 0x100 || | 3641 | if (sprom->boardflags2_lo & 0x100 || |
| 3643 | (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE && | 3642 | (dev->dev->board_vendor == PCI_VENDOR_ID_APPLE && |
| 3644 | bus->boardinfo.type == 0x8B)) | 3643 | dev->dev->board_type == 0x8B)) |
| 3645 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); | 3644 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0); |
| 3646 | else | 3645 | else |
| 3647 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); | 3646 | b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8); |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 72ab94df7569..44da620d9cc2 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
| @@ -111,7 +111,7 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, | |||
| 111 | B43_MMIO_PIO11_BASE5, | 111 | B43_MMIO_PIO11_BASE5, |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | if (dev->sdev->id.revision >= 11) { | 114 | if (dev->dev->core_rev >= 11) { |
| 115 | B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); | 115 | B43_WARN_ON(index >= ARRAY_SIZE(bases_rev11)); |
| 116 | return bases_rev11[index]; | 116 | return bases_rev11[index]; |
| 117 | } | 117 | } |
| @@ -121,14 +121,14 @@ static u16 index_to_pioqueue_base(struct b43_wldev *dev, | |||
| 121 | 121 | ||
| 122 | static u16 pio_txqueue_offset(struct b43_wldev *dev) | 122 | static u16 pio_txqueue_offset(struct b43_wldev *dev) |
| 123 | { | 123 | { |
| 124 | if (dev->sdev->id.revision >= 11) | 124 | if (dev->dev->core_rev >= 11) |
| 125 | return 0x18; | 125 | return 0x18; |
| 126 | return 0; | 126 | return 0; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static u16 pio_rxqueue_offset(struct b43_wldev *dev) | 129 | static u16 pio_rxqueue_offset(struct b43_wldev *dev) |
| 130 | { | 130 | { |
| 131 | if (dev->sdev->id.revision >= 11) | 131 | if (dev->dev->core_rev >= 11) |
| 132 | return 0x38; | 132 | return 0x38; |
| 133 | return 8; | 133 | return 8; |
| 134 | } | 134 | } |
| @@ -144,7 +144,7 @@ static struct b43_pio_txqueue *b43_setup_pioqueue_tx(struct b43_wldev *dev, | |||
| 144 | if (!q) | 144 | if (!q) |
| 145 | return NULL; | 145 | return NULL; |
| 146 | q->dev = dev; | 146 | q->dev = dev; |
| 147 | q->rev = dev->sdev->id.revision; | 147 | q->rev = dev->dev->core_rev; |
| 148 | q->mmio_base = index_to_pioqueue_base(dev, index) + | 148 | q->mmio_base = index_to_pioqueue_base(dev, index) + |
| 149 | pio_txqueue_offset(dev); | 149 | pio_txqueue_offset(dev); |
| 150 | q->index = index; | 150 | q->index = index; |
| @@ -178,7 +178,7 @@ static struct b43_pio_rxqueue *b43_setup_pioqueue_rx(struct b43_wldev *dev, | |||
| 178 | if (!q) | 178 | if (!q) |
| 179 | return NULL; | 179 | return NULL; |
| 180 | q->dev = dev; | 180 | q->dev = dev; |
| 181 | q->rev = dev->sdev->id.revision; | 181 | q->rev = dev->dev->core_rev; |
| 182 | q->mmio_base = index_to_pioqueue_base(dev, index) + | 182 | q->mmio_base = index_to_pioqueue_base(dev, index) + |
| 183 | pio_rxqueue_offset(dev); | 183 | pio_rxqueue_offset(dev); |
| 184 | 184 | ||
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index a617efe38289..59c3afe047af 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
| @@ -37,17 +37,16 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) | |||
| 37 | { | 37 | { |
| 38 | struct b43_wl *wl = hw_to_b43_wl(hw); | 38 | struct b43_wl *wl = hw_to_b43_wl(hw); |
| 39 | struct b43_wldev *dev = wl->current_dev; | 39 | struct b43_wldev *dev = wl->current_dev; |
| 40 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 41 | bool enabled; | 40 | bool enabled; |
| 42 | bool brought_up = false; | 41 | bool brought_up = false; |
| 43 | 42 | ||
| 44 | mutex_lock(&wl->mutex); | 43 | mutex_lock(&wl->mutex); |
| 45 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { | 44 | if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED)) { |
| 46 | if (ssb_bus_powerup(bus, 0)) { | 45 | if (b43_bus_powerup(dev, 0)) { |
| 47 | mutex_unlock(&wl->mutex); | 46 | mutex_unlock(&wl->mutex); |
| 48 | return; | 47 | return; |
| 49 | } | 48 | } |
| 50 | ssb_device_enable(dev->sdev, 0); | 49 | b43_device_enable(dev, 0); |
| 51 | brought_up = true; | 50 | brought_up = true; |
| 52 | } | 51 | } |
| 53 | 52 | ||
| @@ -63,8 +62,8 @@ void b43_rfkill_poll(struct ieee80211_hw *hw) | |||
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | if (brought_up) { | 64 | if (brought_up) { |
| 66 | ssb_device_disable(dev->sdev, 0); | 65 | b43_device_disable(dev, 0); |
| 67 | ssb_bus_may_powerdown(bus); | 66 | b43_bus_may_powerdown(dev); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | mutex_unlock(&wl->mutex); | 69 | mutex_unlock(&wl->mutex); |
diff --git a/drivers/net/wireless/b43/sdio.c b/drivers/net/wireless/b43/sdio.c index 808e25b79703..e6c733d37c94 100644 --- a/drivers/net/wireless/b43/sdio.c +++ b/drivers/net/wireless/b43/sdio.c | |||
| @@ -66,7 +66,7 @@ static void b43_sdio_interrupt_dispatcher(struct sdio_func *func) | |||
| 66 | int b43_sdio_request_irq(struct b43_wldev *dev, | 66 | int b43_sdio_request_irq(struct b43_wldev *dev, |
| 67 | void (*handler)(struct b43_wldev *dev)) | 67 | void (*handler)(struct b43_wldev *dev)) |
| 68 | { | 68 | { |
| 69 | struct ssb_bus *bus = dev->sdev->bus; | 69 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 70 | struct sdio_func *func = bus->host_sdio; | 70 | struct sdio_func *func = bus->host_sdio; |
| 71 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 71 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
| 72 | int err; | 72 | int err; |
| @@ -82,7 +82,7 @@ int b43_sdio_request_irq(struct b43_wldev *dev, | |||
| 82 | 82 | ||
| 83 | void b43_sdio_free_irq(struct b43_wldev *dev) | 83 | void b43_sdio_free_irq(struct b43_wldev *dev) |
| 84 | { | 84 | { |
| 85 | struct ssb_bus *bus = dev->sdev->bus; | 85 | struct ssb_bus *bus = dev->dev->sdev->bus; |
| 86 | struct sdio_func *func = bus->host_sdio; | 86 | struct sdio_func *func = bus->host_sdio; |
| 87 | struct b43_sdio *sdio = sdio_get_drvdata(func); | 87 | struct b43_sdio *sdio = sdio_get_drvdata(func); |
| 88 | 88 | ||
diff --git a/drivers/net/wireless/b43/sysfs.c b/drivers/net/wireless/b43/sysfs.c index 57af619725c3..f1ae4e05a32c 100644 --- a/drivers/net/wireless/b43/sysfs.c +++ b/drivers/net/wireless/b43/sysfs.c | |||
| @@ -140,7 +140,7 @@ static DEVICE_ATTR(interference, 0644, | |||
| 140 | 140 | ||
| 141 | int b43_sysfs_register(struct b43_wldev *wldev) | 141 | int b43_sysfs_register(struct b43_wldev *wldev) |
| 142 | { | 142 | { |
| 143 | struct device *dev = wldev->sdev->dev; | 143 | struct device *dev = wldev->dev->dev; |
| 144 | 144 | ||
| 145 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); | 145 | B43_WARN_ON(b43_status(wldev) != B43_STAT_INITIALIZED); |
| 146 | 146 | ||
| @@ -149,7 +149,7 @@ int b43_sysfs_register(struct b43_wldev *wldev) | |||
| 149 | 149 | ||
| 150 | void b43_sysfs_unregister(struct b43_wldev *wldev) | 150 | void b43_sysfs_unregister(struct b43_wldev *wldev) |
| 151 | { | 151 | { |
| 152 | struct device *dev = wldev->sdev->dev; | 152 | struct device *dev = wldev->dev->dev; |
| 153 | 153 | ||
| 154 | device_remove_file(dev, &dev_attr_interference); | 154 | device_remove_file(dev, &dev_attr_interference); |
| 155 | } | 155 | } |
diff --git a/drivers/net/wireless/b43/tables_lpphy.c b/drivers/net/wireless/b43/tables_lpphy.c index 59df3c64af63..6748c5a196e9 100644 --- a/drivers/net/wireless/b43/tables_lpphy.c +++ b/drivers/net/wireless/b43/tables_lpphy.c | |||
| @@ -2304,7 +2304,6 @@ void lpphy_rev0_1_table_init(struct b43_wldev *dev) | |||
| 2304 | 2304 | ||
| 2305 | void lpphy_rev2plus_table_init(struct b43_wldev *dev) | 2305 | void lpphy_rev2plus_table_init(struct b43_wldev *dev) |
| 2306 | { | 2306 | { |
| 2307 | struct ssb_bus *bus = dev->sdev->bus; | ||
| 2308 | int i; | 2307 | int i; |
| 2309 | 2308 | ||
| 2310 | B43_WARN_ON(dev->phy.rev < 2); | 2309 | B43_WARN_ON(dev->phy.rev < 2); |
| @@ -2341,7 +2340,7 @@ void lpphy_rev2plus_table_init(struct b43_wldev *dev) | |||
| 2341 | b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0), | 2340 | b43_lptab_write_bulk(dev, B43_LPTAB32(10, 0), |
| 2342 | ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table); | 2341 | ARRAY_SIZE(lpphy_papd_mult_table), lpphy_papd_mult_table); |
| 2343 | 2342 | ||
| 2344 | if ((bus->chip_id == 0x4325) && (bus->chip_rev == 0)) { | 2343 | if ((dev->dev->chip_id == 0x4325) && (dev->dev->chip_rev == 0)) { |
| 2345 | b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0), | 2344 | b43_lptab_write_bulk(dev, B43_LPTAB32(13, 0), |
| 2346 | ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table); | 2345 | ARRAY_SIZE(lpphy_a0_gain_idx_table), lpphy_a0_gain_idx_table); |
| 2347 | b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0), | 2346 | b43_lptab_write_bulk(dev, B43_LPTAB16(14, 0), |
| @@ -2416,12 +2415,12 @@ void lpphy_write_gain_table_bulk(struct b43_wldev *dev, int offset, int count, | |||
| 2416 | 2415 | ||
| 2417 | void lpphy_init_tx_gain_table(struct b43_wldev *dev) | 2416 | void lpphy_init_tx_gain_table(struct b43_wldev *dev) |
| 2418 | { | 2417 | { |
| 2419 | struct ssb_bus *bus = dev->sdev->bus; | 2418 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 2420 | 2419 | ||
| 2421 | switch (dev->phy.rev) { | 2420 | switch (dev->phy.rev) { |
| 2422 | case 0: | 2421 | case 0: |
| 2423 | if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || | 2422 | if ((sprom->boardflags_hi & B43_BFH_NOPA) || |
| 2424 | (bus->sprom.boardflags_lo & B43_BFL_HGPA)) | 2423 | (sprom->boardflags_lo & B43_BFL_HGPA)) |
| 2425 | lpphy_write_gain_table_bulk(dev, 0, 128, | 2424 | lpphy_write_gain_table_bulk(dev, 0, 128, |
| 2426 | lpphy_rev0_nopa_tx_gain_table); | 2425 | lpphy_rev0_nopa_tx_gain_table); |
| 2427 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 2426 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
| @@ -2432,8 +2431,8 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) | |||
| 2432 | lpphy_rev0_5ghz_tx_gain_table); | 2431 | lpphy_rev0_5ghz_tx_gain_table); |
| 2433 | break; | 2432 | break; |
| 2434 | case 1: | 2433 | case 1: |
| 2435 | if ((bus->sprom.boardflags_hi & B43_BFH_NOPA) || | 2434 | if ((sprom->boardflags_hi & B43_BFH_NOPA) || |
| 2436 | (bus->sprom.boardflags_lo & B43_BFL_HGPA)) | 2435 | (sprom->boardflags_lo & B43_BFL_HGPA)) |
| 2437 | lpphy_write_gain_table_bulk(dev, 0, 128, | 2436 | lpphy_write_gain_table_bulk(dev, 0, 128, |
| 2438 | lpphy_rev1_nopa_tx_gain_table); | 2437 | lpphy_rev1_nopa_tx_gain_table); |
| 2439 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 2438 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
| @@ -2444,7 +2443,7 @@ void lpphy_init_tx_gain_table(struct b43_wldev *dev) | |||
| 2444 | lpphy_rev1_5ghz_tx_gain_table); | 2443 | lpphy_rev1_5ghz_tx_gain_table); |
| 2445 | break; | 2444 | break; |
| 2446 | default: | 2445 | default: |
| 2447 | if (bus->sprom.boardflags_hi & B43_BFH_NOPA) | 2446 | if (sprom->boardflags_hi & B43_BFH_NOPA) |
| 2448 | lpphy_write_gain_table_bulk(dev, 0, 128, | 2447 | lpphy_write_gain_table_bulk(dev, 0, 128, |
| 2449 | lpphy_rev2_nopa_tx_gain_table); | 2448 | lpphy_rev2_nopa_tx_gain_table); |
| 2450 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) | 2449 | else if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) |
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c index 8f4db448ec33..5d00d0eaf2e7 100644 --- a/drivers/net/wireless/b43/wa.c +++ b/drivers/net/wireless/b43/wa.c | |||
| @@ -458,17 +458,15 @@ static void b43_wa_rssi_adc(struct b43_wldev *dev) | |||
| 458 | 458 | ||
| 459 | static void b43_wa_boards_a(struct b43_wldev *dev) | 459 | static void b43_wa_boards_a(struct b43_wldev *dev) |
| 460 | { | 460 | { |
| 461 | struct ssb_bus *bus = dev->sdev->bus; | 461 | if (dev->dev->board_vendor == SSB_BOARDVENDOR_BCM && |
| 462 | 462 | dev->dev->board_type == SSB_BOARD_BU4306 && | |
| 463 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && | 463 | dev->dev->board_rev < 0x30) { |
| 464 | bus->boardinfo.type == SSB_BOARD_BU4306 && | ||
| 465 | bus->boardinfo.rev < 0x30) { | ||
| 466 | b43_phy_write(dev, 0x0010, 0xE000); | 464 | b43_phy_write(dev, 0x0010, 0xE000); |
| 467 | b43_phy_write(dev, 0x0013, 0x0140); | 465 | b43_phy_write(dev, 0x0013, 0x0140); |
| 468 | b43_phy_write(dev, 0x0014, 0x0280); | 466 | b43_phy_write(dev, 0x0014, 0x0280); |
| 469 | } else { | 467 | } else { |
| 470 | if (bus->boardinfo.type == SSB_BOARD_MP4318 && | 468 | if (dev->dev->board_type == SSB_BOARD_MP4318 && |
| 471 | bus->boardinfo.rev < 0x20) { | 469 | dev->dev->board_rev < 0x20) { |
| 472 | b43_phy_write(dev, 0x0013, 0x0210); | 470 | b43_phy_write(dev, 0x0013, 0x0210); |
| 473 | b43_phy_write(dev, 0x0014, 0x0840); | 471 | b43_phy_write(dev, 0x0014, 0x0840); |
| 474 | } else { | 472 | } else { |
| @@ -486,19 +484,19 @@ static void b43_wa_boards_a(struct b43_wldev *dev) | |||
| 486 | 484 | ||
| 487 | static void b43_wa_boards_g(struct b43_wldev *dev) | 485 | static void b43_wa_boards_g(struct b43_wldev *dev) |
| 488 | { | 486 | { |
| 489 | struct ssb_bus *bus = dev->sdev->bus; | 487 | struct ssb_sprom *sprom = dev->dev->bus_sprom; |
| 490 | struct b43_phy *phy = &dev->phy; | 488 | struct b43_phy *phy = &dev->phy; |
| 491 | 489 | ||
| 492 | if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || | 490 | if (dev->dev->board_vendor != SSB_BOARDVENDOR_BCM || |
| 493 | bus->boardinfo.type != SSB_BOARD_BU4306 || | 491 | dev->dev->board_type != SSB_BOARD_BU4306 || |
| 494 | bus->boardinfo.rev != 0x17) { | 492 | dev->dev->board_rev != 0x17) { |
| 495 | if (phy->rev < 2) { | 493 | if (phy->rev < 2) { |
| 496 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); | 494 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); |
| 497 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); | 495 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); |
| 498 | } else { | 496 | } else { |
| 499 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); | 497 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); |
| 500 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); | 498 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); |
| 501 | if ((bus->sprom.boardflags_lo & B43_BFL_EXTLNA) && | 499 | if ((sprom->boardflags_lo & B43_BFL_EXTLNA) && |
| 502 | (phy->rev >= 7)) { | 500 | (phy->rev >= 7)) { |
| 503 | b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF); | 501 | b43_phy_mask(dev, B43_PHY_EXTG(0x11), 0xF7FF); |
| 504 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); | 502 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); |
| @@ -510,7 +508,7 @@ static void b43_wa_boards_g(struct b43_wldev *dev) | |||
| 510 | } | 508 | } |
| 511 | } | 509 | } |
| 512 | } | 510 | } |
| 513 | if (bus->sprom.boardflags_lo & B43_BFL_FEM) { | 511 | if (sprom->boardflags_lo & B43_BFL_FEM) { |
| 514 | b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); | 512 | b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); |
| 515 | b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); | 513 | b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); |
| 516 | } | 514 | } |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index c8f99aebe01f..488b898418a3 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
| @@ -547,7 +547,7 @@ static s8 b43_rssi_postprocess(struct b43_wldev *dev, | |||
| 547 | else | 547 | else |
| 548 | tmp -= 3; | 548 | tmp -= 3; |
| 549 | } else { | 549 | } else { |
| 550 | if (dev->sdev->bus->sprom. | 550 | if (dev->dev->bus_sprom-> |
| 551 | boardflags_lo & B43_BFL_RSSI) { | 551 | boardflags_lo & B43_BFL_RSSI) { |
| 552 | if (in_rssi > 63) | 552 | if (in_rssi > 63) |
| 553 | in_rssi = 63; | 553 | in_rssi = 63; |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index e03e01d0bc35..c33934ad6cd2 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
| @@ -817,14 +817,13 @@ static void dmacontroller_cleanup(struct b43legacy_dmaring *ring) | |||
| 817 | 817 | ||
| 818 | static void free_all_descbuffers(struct b43legacy_dmaring *ring) | 818 | static void free_all_descbuffers(struct b43legacy_dmaring *ring) |
| 819 | { | 819 | { |
| 820 | struct b43legacy_dmadesc_generic *desc; | ||
| 821 | struct b43legacy_dmadesc_meta *meta; | 820 | struct b43legacy_dmadesc_meta *meta; |
| 822 | int i; | 821 | int i; |
| 823 | 822 | ||
| 824 | if (!ring->used_slots) | 823 | if (!ring->used_slots) |
| 825 | return; | 824 | return; |
| 826 | for (i = 0; i < ring->nr_slots; i++) { | 825 | for (i = 0; i < ring->nr_slots; i++) { |
| 827 | desc = ring->ops->idx2desc(ring, i, &meta); | 826 | ring->ops->idx2desc(ring, i, &meta); |
| 828 | 827 | ||
| 829 | if (!meta->skb) { | 828 | if (!meta->skb) { |
| 830 | B43legacy_WARN_ON(!ring->tx); | 829 | B43legacy_WARN_ON(!ring->tx); |
| @@ -1371,10 +1370,8 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, | |||
| 1371 | struct sk_buff *skb) | 1370 | struct sk_buff *skb) |
| 1372 | { | 1371 | { |
| 1373 | struct b43legacy_dmaring *ring; | 1372 | struct b43legacy_dmaring *ring; |
| 1374 | struct ieee80211_hdr *hdr; | ||
| 1375 | int err = 0; | 1373 | int err = 0; |
| 1376 | unsigned long flags; | 1374 | unsigned long flags; |
| 1377 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 1378 | 1375 | ||
| 1379 | ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); | 1376 | ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); |
| 1380 | spin_lock_irqsave(&ring->lock, flags); | 1377 | spin_lock_irqsave(&ring->lock, flags); |
| @@ -1401,8 +1398,6 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev, | |||
| 1401 | 1398 | ||
| 1402 | /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing | 1399 | /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing |
| 1403 | * into the skb data or cb now. */ | 1400 | * into the skb data or cb now. */ |
| 1404 | hdr = NULL; | ||
| 1405 | info = NULL; | ||
| 1406 | err = dma_tx_fragment(ring, &skb); | 1401 | err = dma_tx_fragment(ring, &skb); |
| 1407 | if (unlikely(err == -ENOKEY)) { | 1402 | if (unlikely(err == -ENOKEY)) { |
| 1408 | /* Drop this packet, as we don't have the encryption key | 1403 | /* Drop this packet, as we don't have the encryption key |
| @@ -1435,7 +1430,6 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
| 1435 | { | 1430 | { |
| 1436 | const struct b43legacy_dma_ops *ops; | 1431 | const struct b43legacy_dma_ops *ops; |
| 1437 | struct b43legacy_dmaring *ring; | 1432 | struct b43legacy_dmaring *ring; |
| 1438 | struct b43legacy_dmadesc_generic *desc; | ||
| 1439 | struct b43legacy_dmadesc_meta *meta; | 1433 | struct b43legacy_dmadesc_meta *meta; |
| 1440 | int retry_limit; | 1434 | int retry_limit; |
| 1441 | int slot; | 1435 | int slot; |
| @@ -1450,7 +1444,7 @@ void b43legacy_dma_handle_txstatus(struct b43legacy_wldev *dev, | |||
| 1450 | ops = ring->ops; | 1444 | ops = ring->ops; |
| 1451 | while (1) { | 1445 | while (1) { |
| 1452 | B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); | 1446 | B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots)); |
| 1453 | desc = ops->idx2desc(ring, slot, &meta); | 1447 | ops->idx2desc(ring, slot, &meta); |
| 1454 | 1448 | ||
| 1455 | if (meta->skb) | 1449 | if (meta->skb) |
| 1456 | unmap_descbuffer(ring, meta->dmaaddr, | 1450 | unmap_descbuffer(ring, meta->dmaaddr, |
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c index 60107b8e4c93..d6db6c17da4f 100644 --- a/drivers/net/wireless/b43legacy/main.c +++ b/drivers/net/wireless/b43legacy/main.c | |||
| @@ -1564,10 +1564,10 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev) | |||
| 1564 | struct b43legacy_firmware *fw = &dev->fw; | 1564 | struct b43legacy_firmware *fw = &dev->fw; |
| 1565 | const u8 rev = dev->dev->id.revision; | 1565 | const u8 rev = dev->dev->id.revision; |
| 1566 | const char *filename; | 1566 | const char *filename; |
| 1567 | u32 tmshigh; | ||
| 1568 | int err; | 1567 | int err; |
| 1569 | 1568 | ||
| 1570 | tmshigh = ssb_read32(dev->dev, SSB_TMSHIGH); | 1569 | /* do dummy read */ |
| 1570 | ssb_read32(dev->dev, SSB_TMSHIGH); | ||
| 1571 | if (!fw->ucode) { | 1571 | if (!fw->ucode) { |
| 1572 | if (rev == 2) | 1572 | if (rev == 2) |
| 1573 | filename = "ucode2"; | 1573 | filename = "ucode2"; |
| @@ -2634,11 +2634,9 @@ static int b43legacy_op_dev_config(struct ieee80211_hw *hw, | |||
| 2634 | unsigned long flags; | 2634 | unsigned long flags; |
| 2635 | unsigned int new_phymode = 0xFFFF; | 2635 | unsigned int new_phymode = 0xFFFF; |
| 2636 | int antenna_tx; | 2636 | int antenna_tx; |
| 2637 | int antenna_rx; | ||
| 2638 | int err = 0; | 2637 | int err = 0; |
| 2639 | 2638 | ||
| 2640 | antenna_tx = B43legacy_ANTENNA_DEFAULT; | 2639 | antenna_tx = B43legacy_ANTENNA_DEFAULT; |
| 2641 | antenna_rx = B43legacy_ANTENNA_DEFAULT; | ||
| 2642 | 2640 | ||
| 2643 | mutex_lock(&wl->mutex); | 2641 | mutex_lock(&wl->mutex); |
| 2644 | dev = wl->current_dev; | 2642 | dev = wl->current_dev; |
| @@ -2775,14 +2773,12 @@ static void b43legacy_op_bss_info_changed(struct ieee80211_hw *hw, | |||
| 2775 | { | 2773 | { |
| 2776 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); | 2774 | struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw); |
| 2777 | struct b43legacy_wldev *dev; | 2775 | struct b43legacy_wldev *dev; |
| 2778 | struct b43legacy_phy *phy; | ||
| 2779 | unsigned long flags; | 2776 | unsigned long flags; |
| 2780 | 2777 | ||
| 2781 | mutex_lock(&wl->mutex); | 2778 | mutex_lock(&wl->mutex); |
| 2782 | B43legacy_WARN_ON(wl->vif != vif); | 2779 | B43legacy_WARN_ON(wl->vif != vif); |
| 2783 | 2780 | ||
| 2784 | dev = wl->current_dev; | 2781 | dev = wl->current_dev; |
| 2785 | phy = &dev->phy; | ||
| 2786 | 2782 | ||
| 2787 | /* Disable IRQs while reconfiguring the device. | 2783 | /* Disable IRQs while reconfiguring the device. |
| 2788 | * This makes it possible to drop the spinlock throughout | 2784 | * This makes it possible to drop the spinlock throughout |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 3a95541708a6..6c174f38ca3c 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
| @@ -321,11 +321,9 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev, | |||
| 321 | struct ieee80211_hdr *hdr; | 321 | struct ieee80211_hdr *hdr; |
| 322 | int rts_rate; | 322 | int rts_rate; |
| 323 | int rts_rate_fb; | 323 | int rts_rate_fb; |
| 324 | int rts_rate_ofdm; | ||
| 325 | int rts_rate_fb_ofdm; | 324 | int rts_rate_fb_ofdm; |
| 326 | 325 | ||
| 327 | rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value; | 326 | rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value; |
| 328 | rts_rate_ofdm = b43legacy_is_ofdm_rate(rts_rate); | ||
| 329 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); | 327 | rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate); |
| 330 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); | 328 | rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb); |
| 331 | if (rts_rate_fb_ofdm) | 329 | if (rts_rate_fb_ofdm) |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c index 24d149909ba3..9b65153bdd01 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965-rs.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965-rs.c | |||
| @@ -2275,6 +2275,9 @@ iwl4965_rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta, | |||
| 2275 | if (rate_control_send_low(sta, priv_sta, txrc)) | 2275 | if (rate_control_send_low(sta, priv_sta, txrc)) |
| 2276 | return; | 2276 | return; |
| 2277 | 2277 | ||
| 2278 | if (!lq_sta) | ||
| 2279 | return; | ||
| 2280 | |||
| 2278 | rate_idx = lq_sta->last_txrate_idx; | 2281 | rate_idx = lq_sta->last_txrate_idx; |
| 2279 | 2282 | ||
| 2280 | if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { | 2283 | if (lq_sta->last_rate_n_flags & RATE_MCS_HT_MSK) { |
diff --git a/drivers/net/wireless/iwlegacy/iwl-4965.c b/drivers/net/wireless/iwlegacy/iwl-4965.c index f9db25bb35c3..3a022bcf615c 100644 --- a/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/drivers/net/wireless/iwlegacy/iwl-4965.c | |||
| @@ -496,7 +496,7 @@ static s32 iwl4965_get_tx_atten_grp(u16 channel) | |||
| 496 | channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) | 496 | channel <= CALIB_IWL_TX_ATTEN_GR4_LCH) |
| 497 | return CALIB_CH_GROUP_4; | 497 | return CALIB_CH_GROUP_4; |
| 498 | 498 | ||
| 499 | return -1; | 499 | return -EINVAL; |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) | 502 | static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) |
| @@ -915,7 +915,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, | |||
| 915 | if (txatten_grp < 0) { | 915 | if (txatten_grp < 0) { |
| 916 | IWL_ERR(priv, "Can't find txatten group for channel %d.\n", | 916 | IWL_ERR(priv, "Can't find txatten group for channel %d.\n", |
| 917 | channel); | 917 | channel); |
| 918 | return -EINVAL; | 918 | return txatten_grp; |
| 919 | } | 919 | } |
| 920 | 920 | ||
| 921 | IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", | 921 | IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n", |
| @@ -1185,8 +1185,6 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv, | |||
| 1185 | 1185 | ||
| 1186 | ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, | 1186 | ret = iwl_legacy_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, |
| 1187 | sizeof(rxon_assoc), &rxon_assoc, NULL); | 1187 | sizeof(rxon_assoc), &rxon_assoc, NULL); |
| 1188 | if (ret) | ||
| 1189 | return ret; | ||
| 1190 | 1188 | ||
| 1191 | return ret; | 1189 | return ret; |
| 1192 | } | 1190 | } |
| @@ -1237,7 +1235,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c | |||
| 1237 | 1235 | ||
| 1238 | memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); | 1236 | memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); |
| 1239 | iwl_legacy_print_rx_config_cmd(priv, ctx); | 1237 | iwl_legacy_print_rx_config_cmd(priv, ctx); |
| 1240 | return 0; | 1238 | goto set_tx_power; |
| 1241 | } | 1239 | } |
| 1242 | 1240 | ||
| 1243 | /* If we are currently associated and the new config requires | 1241 | /* If we are currently associated and the new config requires |
| @@ -1317,6 +1315,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c | |||
| 1317 | 1315 | ||
| 1318 | iwl4965_init_sensitivity(priv); | 1316 | iwl4965_init_sensitivity(priv); |
| 1319 | 1317 | ||
| 1318 | set_tx_power: | ||
| 1320 | /* If we issue a new RXON command which required a tune then we must | 1319 | /* If we issue a new RXON command which required a tune then we must |
| 1321 | * send a new TXPOWER command or we won't be able to Tx any frames */ | 1320 | * send a new TXPOWER command or we won't be able to Tx any frames */ |
| 1322 | ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); | 1321 | ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); |
diff --git a/drivers/net/wireless/iwlegacy/iwl-eeprom.c b/drivers/net/wireless/iwlegacy/iwl-eeprom.c index cb346d1a9ffa..5bf3f49b74ab 100644 --- a/drivers/net/wireless/iwlegacy/iwl-eeprom.c +++ b/drivers/net/wireless/iwlegacy/iwl-eeprom.c | |||
| @@ -316,7 +316,6 @@ static void iwl_legacy_init_band_reference(const struct iwl_priv *priv, | |||
| 316 | break; | 316 | break; |
| 317 | default: | 317 | default: |
| 318 | BUG(); | 318 | BUG(); |
| 319 | return; | ||
| 320 | } | 319 | } |
| 321 | } | 320 | } |
| 322 | 321 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 61d4a11f566b..7aa240e6ba1c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
| @@ -174,7 +174,6 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
| 174 | .rx_handler_setup = iwlagn_rx_handler_setup, | 174 | .rx_handler_setup = iwlagn_rx_handler_setup, |
| 175 | .setup_deferred_work = iwlagn_setup_deferred_work, | 175 | .setup_deferred_work = iwlagn_setup_deferred_work, |
| 176 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 176 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 177 | .send_tx_power = iwlagn_send_tx_power, | ||
| 178 | .update_chain_flags = iwl_update_chain_flags, | 177 | .update_chain_flags = iwl_update_chain_flags, |
| 179 | .apm_ops = { | 178 | .apm_ops = { |
| 180 | .init = iwl_apm_init, | 179 | .init = iwl_apm_init, |
| @@ -223,6 +222,7 @@ static struct iwl_base_params iwl1000_base_params = { | |||
| 223 | static struct iwl_ht_params iwl1000_ht_params = { | 222 | static struct iwl_ht_params iwl1000_ht_params = { |
| 224 | .ht_greenfield_support = true, | 223 | .ht_greenfield_support = true, |
| 225 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | 224 | .use_rts_for_aggregation = true, /* use rts/cts protection */ |
| 225 | .smps_mode = IEEE80211_SMPS_STATIC, | ||
| 226 | }; | 226 | }; |
| 227 | 227 | ||
| 228 | #define IWL_DEVICE_1000 \ | 228 | #define IWL_DEVICE_1000 \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 86feec86d130..5484ab712da8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
| @@ -177,88 +177,13 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | |||
| 177 | return 0; | 177 | return 0; |
| 178 | } | 178 | } |
| 179 | 179 | ||
| 180 | static int iwl2030_hw_channel_switch(struct iwl_priv *priv, | ||
| 181 | struct ieee80211_channel_switch *ch_switch) | ||
| 182 | { | ||
| 183 | /* | ||
| 184 | * MULTI-FIXME | ||
| 185 | * See iwl_mac_channel_switch. | ||
| 186 | */ | ||
| 187 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
| 188 | struct iwl6000_channel_switch_cmd cmd; | ||
| 189 | const struct iwl_channel_info *ch_info; | ||
| 190 | u32 switch_time_in_usec, ucode_switch_time; | ||
| 191 | u16 ch; | ||
| 192 | u32 tsf_low; | ||
| 193 | u8 switch_count; | ||
| 194 | u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval); | ||
| 195 | struct ieee80211_vif *vif = ctx->vif; | ||
| 196 | struct iwl_host_cmd hcmd = { | ||
| 197 | .id = REPLY_CHANNEL_SWITCH, | ||
| 198 | .len = { sizeof(cmd), }, | ||
| 199 | .flags = CMD_SYNC, | ||
| 200 | .data = { &cmd, }, | ||
| 201 | }; | ||
| 202 | |||
| 203 | cmd.band = priv->band == IEEE80211_BAND_2GHZ; | ||
| 204 | ch = ch_switch->channel->hw_value; | ||
| 205 | IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", | ||
| 206 | ctx->active.channel, ch); | ||
| 207 | cmd.channel = cpu_to_le16(ch); | ||
| 208 | cmd.rxon_flags = ctx->staging.flags; | ||
| 209 | cmd.rxon_filter_flags = ctx->staging.filter_flags; | ||
| 210 | switch_count = ch_switch->count; | ||
| 211 | tsf_low = ch_switch->timestamp & 0x0ffffffff; | ||
| 212 | /* | ||
| 213 | * calculate the ucode channel switch time | ||
| 214 | * adding TSF as one of the factor for when to switch | ||
| 215 | */ | ||
| 216 | if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) { | ||
| 217 | if (switch_count > ((priv->ucode_beacon_time - tsf_low) / | ||
| 218 | beacon_interval)) { | ||
| 219 | switch_count -= (priv->ucode_beacon_time - | ||
| 220 | tsf_low) / beacon_interval; | ||
| 221 | } else | ||
| 222 | switch_count = 0; | ||
| 223 | } | ||
| 224 | if (switch_count <= 1) | ||
| 225 | cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time); | ||
| 226 | else { | ||
| 227 | switch_time_in_usec = | ||
| 228 | vif->bss_conf.beacon_int * switch_count * TIME_UNIT; | ||
| 229 | ucode_switch_time = iwl_usecs_to_beacons(priv, | ||
| 230 | switch_time_in_usec, | ||
| 231 | beacon_interval); | ||
| 232 | cmd.switch_time = iwl_add_beacon_time(priv, | ||
| 233 | priv->ucode_beacon_time, | ||
| 234 | ucode_switch_time, | ||
| 235 | beacon_interval); | ||
| 236 | } | ||
| 237 | IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n", | ||
| 238 | cmd.switch_time); | ||
| 239 | ch_info = iwl_get_channel_info(priv, priv->band, ch); | ||
| 240 | if (ch_info) | ||
| 241 | cmd.expect_beacon = is_channel_radar(ch_info); | ||
| 242 | else { | ||
| 243 | IWL_ERR(priv, "invalid channel switch from %u to %u\n", | ||
| 244 | ctx->active.channel, ch); | ||
| 245 | return -EFAULT; | ||
| 246 | } | ||
| 247 | priv->switch_rxon.channel = cmd.channel; | ||
| 248 | priv->switch_rxon.switch_in_progress = true; | ||
| 249 | |||
| 250 | return iwl_send_cmd_sync(priv, &hcmd); | ||
| 251 | } | ||
| 252 | |||
| 253 | static struct iwl_lib_ops iwl2000_lib = { | 180 | static struct iwl_lib_ops iwl2000_lib = { |
| 254 | .set_hw_params = iwl2000_hw_set_hw_params, | 181 | .set_hw_params = iwl2000_hw_set_hw_params, |
| 255 | .rx_handler_setup = iwlagn_rx_handler_setup, | 182 | .rx_handler_setup = iwlagn_rx_handler_setup, |
| 256 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 183 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
| 257 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 184 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
| 258 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 185 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 259 | .send_tx_power = iwlagn_send_tx_power, | ||
| 260 | .update_chain_flags = iwl_update_chain_flags, | 186 | .update_chain_flags = iwl_update_chain_flags, |
| 261 | .set_channel_switch = iwl2030_hw_channel_switch, | ||
| 262 | .apm_ops = { | 187 | .apm_ops = { |
| 263 | .init = iwl_apm_init, | 188 | .init = iwl_apm_init, |
| 264 | .config = iwl2000_nic_config, | 189 | .config = iwl2000_nic_config, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index a70b8cfafda1..4353a658de25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
| @@ -331,8 +331,6 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | |||
| 331 | ctx->active.channel, ch); | 331 | ctx->active.channel, ch); |
| 332 | return -EFAULT; | 332 | return -EFAULT; |
| 333 | } | 333 | } |
| 334 | priv->switch_rxon.channel = cmd.channel; | ||
| 335 | priv->switch_rxon.switch_in_progress = true; | ||
| 336 | 334 | ||
| 337 | return iwl_send_cmd_sync(priv, &hcmd); | 335 | return iwl_send_cmd_sync(priv, &hcmd); |
| 338 | } | 336 | } |
| @@ -342,7 +340,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
| 342 | .rx_handler_setup = iwlagn_rx_handler_setup, | 340 | .rx_handler_setup = iwlagn_rx_handler_setup, |
| 343 | .setup_deferred_work = iwlagn_setup_deferred_work, | 341 | .setup_deferred_work = iwlagn_setup_deferred_work, |
| 344 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 342 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 345 | .send_tx_power = iwlagn_send_tx_power, | ||
| 346 | .update_chain_flags = iwl_update_chain_flags, | 343 | .update_chain_flags = iwl_update_chain_flags, |
| 347 | .set_channel_switch = iwl5000_hw_channel_switch, | 344 | .set_channel_switch = iwl5000_hw_channel_switch, |
| 348 | .apm_ops = { | 345 | .apm_ops = { |
| @@ -373,7 +370,6 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
| 373 | .rx_handler_setup = iwlagn_rx_handler_setup, | 370 | .rx_handler_setup = iwlagn_rx_handler_setup, |
| 374 | .setup_deferred_work = iwlagn_setup_deferred_work, | 371 | .setup_deferred_work = iwlagn_setup_deferred_work, |
| 375 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 372 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 376 | .send_tx_power = iwlagn_send_tx_power, | ||
| 377 | .update_chain_flags = iwl_update_chain_flags, | 373 | .update_chain_flags = iwl_update_chain_flags, |
| 378 | .set_channel_switch = iwl5000_hw_channel_switch, | 374 | .set_channel_switch = iwl5000_hw_channel_switch, |
| 379 | .apm_ops = { | 375 | .apm_ops = { |
| @@ -425,7 +421,6 @@ static struct iwl_base_params iwl5000_base_params = { | |||
| 425 | }; | 421 | }; |
| 426 | static struct iwl_ht_params iwl5000_ht_params = { | 422 | static struct iwl_ht_params iwl5000_ht_params = { |
| 427 | .ht_greenfield_support = true, | 423 | .ht_greenfield_support = true, |
| 428 | .use_rts_for_aggregation = true, /* use rts/cts protection */ | ||
| 429 | }; | 424 | }; |
| 430 | 425 | ||
| 431 | #define IWL_DEVICE_5000 \ | 426 | #define IWL_DEVICE_5000 \ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index fda6fe08cf91..6e5ce4478490 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
| @@ -270,8 +270,6 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | |||
| 270 | ctx->active.channel, ch); | 270 | ctx->active.channel, ch); |
| 271 | return -EFAULT; | 271 | return -EFAULT; |
| 272 | } | 272 | } |
| 273 | priv->switch_rxon.channel = cmd.channel; | ||
| 274 | priv->switch_rxon.switch_in_progress = true; | ||
| 275 | 273 | ||
| 276 | return iwl_send_cmd_sync(priv, &hcmd); | 274 | return iwl_send_cmd_sync(priv, &hcmd); |
| 277 | } | 275 | } |
| @@ -281,7 +279,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
| 281 | .rx_handler_setup = iwlagn_rx_handler_setup, | 279 | .rx_handler_setup = iwlagn_rx_handler_setup, |
| 282 | .setup_deferred_work = iwlagn_setup_deferred_work, | 280 | .setup_deferred_work = iwlagn_setup_deferred_work, |
| 283 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 281 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 284 | .send_tx_power = iwlagn_send_tx_power, | ||
| 285 | .update_chain_flags = iwl_update_chain_flags, | 282 | .update_chain_flags = iwl_update_chain_flags, |
| 286 | .set_channel_switch = iwl6000_hw_channel_switch, | 283 | .set_channel_switch = iwl6000_hw_channel_switch, |
| 287 | .apm_ops = { | 284 | .apm_ops = { |
| @@ -314,7 +311,6 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
| 314 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, | 311 | .setup_deferred_work = iwlagn_bt_setup_deferred_work, |
| 315 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, | 312 | .cancel_deferred_work = iwlagn_bt_cancel_deferred_work, |
| 316 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, | 313 | .is_valid_rtc_data_addr = iwlagn_hw_valid_rtc_data_addr, |
| 317 | .send_tx_power = iwlagn_send_tx_power, | ||
| 318 | .update_chain_flags = iwl_update_chain_flags, | 314 | .update_chain_flags = iwl_update_chain_flags, |
| 319 | .set_channel_switch = iwl6000_hw_channel_switch, | 315 | .set_channel_switch = iwl6000_hw_channel_switch, |
| 320 | .apm_ops = { | 316 | .apm_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c index b12c72d63ccb..23eee0ca5b35 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c | |||
| @@ -163,17 +163,9 @@ static void iwlagn_tx_cmd_protection(struct iwl_priv *priv, | |||
| 163 | __le16 fc, __le32 *tx_flags) | 163 | __le16 fc, __le32 *tx_flags) |
| 164 | { | 164 | { |
| 165 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || | 165 | if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS || |
| 166 | info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { | 166 | info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT || |
| 167 | info->flags & IEEE80211_TX_CTL_AMPDU) | ||
| 167 | *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; | 168 | *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; |
| 168 | return; | ||
| 169 | } | ||
| 170 | |||
| 171 | if (priv->cfg->ht_params && | ||
| 172 | priv->cfg->ht_params->use_rts_for_aggregation && | ||
| 173 | info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
| 174 | *tx_flags |= TX_CMD_FLG_PROT_REQUIRE_MSK; | ||
| 175 | return; | ||
| 176 | } | ||
| 177 | } | 169 | } |
| 178 | 170 | ||
| 179 | /* Calc max signal level (dBm) among 3 possible receivers */ | 171 | /* Calc max signal level (dBm) among 3 possible receivers */ |
| @@ -310,7 +302,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| 310 | } | 302 | } |
| 311 | 303 | ||
| 312 | struct iwl_hcmd_ops iwlagn_hcmd = { | 304 | struct iwl_hcmd_ops iwlagn_hcmd = { |
| 313 | .commit_rxon = iwlagn_commit_rxon, | ||
| 314 | .set_rxon_chain = iwlagn_set_rxon_chain, | 305 | .set_rxon_chain = iwlagn_set_rxon_chain, |
| 315 | .set_tx_ant = iwlagn_send_tx_ant_config, | 306 | .set_tx_ant = iwlagn_send_tx_ant_config, |
| 316 | .send_bt_config = iwl_send_bt_config, | 307 | .send_bt_config = iwl_send_bt_config, |
| @@ -318,7 +309,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = { | |||
| 318 | }; | 309 | }; |
| 319 | 310 | ||
| 320 | struct iwl_hcmd_ops iwlagn_bt_hcmd = { | 311 | struct iwl_hcmd_ops iwlagn_bt_hcmd = { |
| 321 | .commit_rxon = iwlagn_commit_rxon, | ||
| 322 | .set_rxon_chain = iwlagn_set_rxon_chain, | 312 | .set_rxon_chain = iwlagn_set_rxon_chain, |
| 323 | .set_tx_ant = iwlagn_send_tx_ant_config, | 313 | .set_tx_ant = iwlagn_send_tx_ant_config, |
| 324 | .send_bt_config = iwlagn_send_advance_bt_config, | 314 | .send_bt_config = iwlagn_send_advance_bt_config, |
| @@ -332,5 +322,4 @@ struct iwl_hcmd_utils_ops iwlagn_hcmd_utils = { | |||
| 332 | .tx_cmd_protection = iwlagn_tx_cmd_protection, | 322 | .tx_cmd_protection = iwlagn_tx_cmd_protection, |
| 333 | .calc_rssi = iwlagn_calc_rssi, | 323 | .calc_rssi = iwlagn_calc_rssi, |
| 334 | .request_scan = iwlagn_request_scan, | 324 | .request_scan = iwlagn_request_scan, |
| 335 | .post_scan = iwlagn_post_scan, | ||
| 336 | }; | 325 | }; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index f803fb62f8bc..677f73c4c1e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
| @@ -408,9 +408,9 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv, | |||
| 408 | unsigned long flags; | 408 | unsigned long flags; |
| 409 | 409 | ||
| 410 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { | 410 | if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { |
| 411 | IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " | 411 | IWL_ERR(priv, "%s: Read index for DMA queue txq_id (%d) " |
| 412 | "is out of range [0-%d] %d %d\n", txq_id, | 412 | "index %d is out of range [0-%d] %d %d\n", __func__, |
| 413 | index, txq->q.n_bd, txq->q.write_ptr, | 413 | txq_id, index, txq->q.n_bd, txq->q.write_ptr, |
| 414 | txq->q.read_ptr); | 414 | txq->q.read_ptr); |
| 415 | return; | 415 | return; |
| 416 | } | 416 | } |
| @@ -1797,6 +1797,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) | |||
| 1797 | priv->cfg->ops->lib->update_chain_flags(priv); | 1797 | priv->cfg->ops->lib->update_chain_flags(priv); |
| 1798 | 1798 | ||
| 1799 | if (smps_request != -1) { | 1799 | if (smps_request != -1) { |
| 1800 | priv->current_ht_config.smps = smps_request; | ||
| 1800 | for_each_context(priv, ctx) { | 1801 | for_each_context(priv, ctx) { |
| 1801 | if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) | 1802 | if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) |
| 1802 | ieee80211_request_smps(ctx->vif, smps_request); | 1803 | ieee80211_request_smps(ctx->vif, smps_request); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 592b0cfcf717..85e082830c1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
| @@ -426,7 +426,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
| 426 | ieee80211_stop_tx_ba_session(sta, tid); | 426 | ieee80211_stop_tx_ba_session(sta, tid); |
| 427 | } | 427 | } |
| 428 | } else { | 428 | } else { |
| 429 | IWL_ERR(priv, "Aggregation not enabled for tid %d " | 429 | IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d " |
| 430 | "because load = %u\n", tid, load); | 430 | "because load = %u\n", tid, load); |
| 431 | } | 431 | } |
| 432 | return ret; | 432 | return ret; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index a95ad84c5377..a7c66c4e5f2a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | |||
| @@ -81,6 +81,21 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
| 81 | return ret; | 81 | return ret; |
| 82 | } | 82 | } |
| 83 | 83 | ||
| 84 | static int iwlagn_disconn_pan(struct iwl_priv *priv, | ||
| 85 | struct iwl_rxon_context *ctx, | ||
| 86 | struct iwl_rxon_cmd *send) | ||
| 87 | { | ||
| 88 | __le32 old_filter = send->filter_flags; | ||
| 89 | int ret; | ||
| 90 | |||
| 91 | send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||
| 92 | ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send); | ||
| 93 | |||
| 94 | send->filter_flags = old_filter; | ||
| 95 | |||
| 96 | return ret; | ||
| 97 | } | ||
| 98 | |||
| 84 | static void iwlagn_update_qos(struct iwl_priv *priv, | 99 | static void iwlagn_update_qos(struct iwl_priv *priv, |
| 85 | struct iwl_rxon_context *ctx) | 100 | struct iwl_rxon_context *ctx) |
| 86 | { | 101 | { |
| @@ -163,9 +178,6 @@ static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | |||
| 163 | 178 | ||
| 164 | ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, | 179 | ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, |
| 165 | sizeof(rxon_assoc), &rxon_assoc, NULL); | 180 | sizeof(rxon_assoc), &rxon_assoc, NULL); |
| 166 | if (ret) | ||
| 167 | return ret; | ||
| 168 | |||
| 169 | return ret; | 181 | return ret; |
| 170 | } | 182 | } |
| 171 | 183 | ||
| @@ -175,10 +187,21 @@ static int iwlagn_rxon_disconn(struct iwl_priv *priv, | |||
| 175 | int ret; | 187 | int ret; |
| 176 | struct iwl_rxon_cmd *active = (void *)&ctx->active; | 188 | struct iwl_rxon_cmd *active = (void *)&ctx->active; |
| 177 | 189 | ||
| 178 | if (ctx->ctxid == IWL_RXON_CTX_BSS) | 190 | if (ctx->ctxid == IWL_RXON_CTX_BSS) { |
| 179 | ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); | 191 | ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); |
| 180 | else | 192 | } else { |
| 181 | ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); | 193 | ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); |
| 194 | if (ret) | ||
| 195 | return ret; | ||
| 196 | if (ctx->vif) { | ||
| 197 | ret = iwl_send_rxon_timing(priv, ctx); | ||
| 198 | if (ret) { | ||
| 199 | IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | ||
| 200 | return ret; | ||
| 201 | } | ||
| 202 | ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging); | ||
| 203 | } | ||
| 204 | } | ||
| 182 | if (ret) | 205 | if (ret) |
| 183 | return ret; | 206 | return ret; |
| 184 | 207 | ||
| @@ -205,10 +228,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
| 205 | struct iwl_rxon_cmd *active = (void *)&ctx->active; | 228 | struct iwl_rxon_cmd *active = (void *)&ctx->active; |
| 206 | 229 | ||
| 207 | /* RXON timing must be before associated RXON */ | 230 | /* RXON timing must be before associated RXON */ |
| 208 | ret = iwl_send_rxon_timing(priv, ctx); | 231 | if (ctx->ctxid == IWL_RXON_CTX_BSS) { |
| 209 | if (ret) { | 232 | ret = iwl_send_rxon_timing(priv, ctx); |
| 210 | IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | 233 | if (ret) { |
| 211 | return ret; | 234 | IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); |
| 235 | return ret; | ||
| 236 | } | ||
| 212 | } | 237 | } |
| 213 | /* QoS info may be cleared by previous un-assoc RXON */ | 238 | /* QoS info may be cleared by previous un-assoc RXON */ |
| 214 | iwlagn_update_qos(priv, ctx); | 239 | iwlagn_update_qos(priv, ctx); |
| @@ -263,6 +288,12 @@ static int iwlagn_rxon_connect(struct iwl_priv *priv, | |||
| 263 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | 288 | IWL_ERR(priv, "Error sending TX power (%d)\n", ret); |
| 264 | return ret; | 289 | return ret; |
| 265 | } | 290 | } |
| 291 | |||
| 292 | if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) && | ||
| 293 | priv->cfg->ht_params->smps_mode) | ||
| 294 | ieee80211_request_smps(ctx->vif, | ||
| 295 | priv->cfg->ht_params->smps_mode); | ||
| 296 | |||
| 266 | return 0; | 297 | return 0; |
| 267 | } | 298 | } |
| 268 | 299 | ||
| @@ -325,6 +356,14 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 325 | return 0; | 356 | return 0; |
| 326 | } | 357 | } |
| 327 | 358 | ||
| 359 | /* | ||
| 360 | * force CTS-to-self frames protection if RTS-CTS is not preferred | ||
| 361 | * one aggregation protection method | ||
| 362 | */ | ||
| 363 | if (!(priv->cfg->ht_params && | ||
| 364 | priv->cfg->ht_params->use_rts_for_aggregation)) | ||
| 365 | ctx->staging.flags |= RXON_FLG_SELF_CTS_EN; | ||
| 366 | |||
| 328 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || | 367 | if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) || |
| 329 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) | 368 | !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK)) |
| 330 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; | 369 | ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK; |
| @@ -342,10 +381,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 342 | * receive commit_rxon request | 381 | * receive commit_rxon request |
| 343 | * abort any previous channel switch if still in process | 382 | * abort any previous channel switch if still in process |
| 344 | */ | 383 | */ |
| 345 | if (priv->switch_rxon.switch_in_progress && | 384 | if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) && |
| 346 | (priv->switch_rxon.channel != ctx->staging.channel)) { | 385 | (priv->switch_channel != ctx->staging.channel)) { |
| 347 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", | 386 | IWL_DEBUG_11H(priv, "abort channel switch on %d\n", |
| 348 | le16_to_cpu(priv->switch_rxon.channel)); | 387 | le16_to_cpu(priv->switch_channel)); |
| 349 | iwl_chswitch_done(priv, false); | 388 | iwl_chswitch_done(priv, false); |
| 350 | } | 389 | } |
| 351 | 390 | ||
| @@ -362,13 +401,16 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 362 | } | 401 | } |
| 363 | 402 | ||
| 364 | memcpy(active, &ctx->staging, sizeof(*active)); | 403 | memcpy(active, &ctx->staging, sizeof(*active)); |
| 365 | return 0; | 404 | /* |
| 366 | } | 405 | * We do not commit tx power settings while channel changing, |
| 406 | * do it now if after settings changed. | ||
| 407 | */ | ||
| 408 | iwl_set_tx_power(priv, priv->tx_power_next, false); | ||
| 367 | 409 | ||
| 368 | if (priv->cfg->ops->hcmd->set_pan_params) { | 410 | /* make sure we are in the right PS state */ |
| 369 | ret = priv->cfg->ops->hcmd->set_pan_params(priv); | 411 | iwl_power_update_mode(priv, true); |
| 370 | if (ret) | 412 | |
| 371 | return ret; | 413 | return 0; |
| 372 | } | 414 | } |
| 373 | 415 | ||
| 374 | iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); | 416 | iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); |
| @@ -392,6 +434,12 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 392 | if (ret) | 434 | if (ret) |
| 393 | return ret; | 435 | return ret; |
| 394 | 436 | ||
| 437 | if (priv->cfg->ops->hcmd->set_pan_params) { | ||
| 438 | ret = priv->cfg->ops->hcmd->set_pan_params(priv); | ||
| 439 | if (ret) | ||
| 440 | return ret; | ||
| 441 | } | ||
| 442 | |||
| 395 | if (new_assoc) | 443 | if (new_assoc) |
| 396 | return iwlagn_rxon_connect(priv, ctx); | 444 | return iwlagn_rxon_connect(priv, ctx); |
| 397 | 445 | ||
| @@ -757,6 +805,13 @@ void iwlagn_post_scan(struct iwl_priv *priv) | |||
| 757 | struct iwl_rxon_context *ctx; | 805 | struct iwl_rxon_context *ctx; |
| 758 | 806 | ||
| 759 | /* | 807 | /* |
| 808 | * We do not commit power settings while scan is pending, | ||
| 809 | * do it now if the settings changed. | ||
| 810 | */ | ||
| 811 | iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); | ||
| 812 | iwl_set_tx_power(priv, priv->tx_power_next, false); | ||
| 813 | |||
| 814 | /* | ||
| 760 | * Since setting the RXON may have been deferred while | 815 | * Since setting the RXON may have been deferred while |
| 761 | * performing the scan, fire one off if needed | 816 | * performing the scan, fire one off if needed |
| 762 | */ | 817 | */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index 4974cd7837cb..8bd48f61a9f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c | |||
| @@ -1033,8 +1033,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif, | |||
| 1033 | if (unlikely(tx_fifo < 0)) | 1033 | if (unlikely(tx_fifo < 0)) |
| 1034 | return tx_fifo; | 1034 | return tx_fifo; |
| 1035 | 1035 | ||
| 1036 | IWL_WARN(priv, "%s on ra = %pM tid = %d\n", | 1036 | IWL_DEBUG_HT(priv, "TX AGG request on ra = %pM tid = %d\n", |
| 1037 | __func__, sta->addr, tid); | 1037 | sta->addr, tid); |
| 1038 | 1038 | ||
| 1039 | sta_id = iwl_sta_id(sta); | 1039 | sta_id = iwl_sta_id(sta); |
| 1040 | if (sta_id == IWL_INVALID_STATION) { | 1040 | if (sta_id == IWL_INVALID_STATION) { |
| @@ -1236,9 +1236,9 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
| 1236 | struct ieee80211_hdr *hdr; | 1236 | struct ieee80211_hdr *hdr; |
| 1237 | 1237 | ||
| 1238 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { | 1238 | if ((index >= q->n_bd) || (iwl_queue_used(q, index) == 0)) { |
| 1239 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " | 1239 | IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), " |
| 1240 | "is out of range [0-%d] %d %d.\n", txq_id, | 1240 | "index %d is out of range [0-%d] %d %d.\n", __func__, |
| 1241 | index, q->n_bd, q->write_ptr, q->read_ptr); | 1241 | txq_id, index, q->n_bd, q->write_ptr, q->read_ptr); |
| 1242 | return 0; | 1242 | return 0; |
| 1243 | } | 1243 | } |
| 1244 | 1244 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index a662adcb2adb..099c2795ec0b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
| @@ -97,7 +97,7 @@ void iwl_update_chain_flags(struct iwl_priv *priv) | |||
| 97 | for_each_context(priv, ctx) { | 97 | for_each_context(priv, ctx) { |
| 98 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); | 98 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); |
| 99 | if (ctx->active.rx_chain != ctx->staging.rx_chain) | 99 | if (ctx->active.rx_chain != ctx->staging.rx_chain) |
| 100 | iwlcore_commit_rxon(priv, ctx); | 100 | iwlagn_commit_rxon(priv, ctx); |
| 101 | } | 101 | } |
| 102 | } | 102 | } |
| 103 | } | 103 | } |
| @@ -274,7 +274,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work) | |||
| 274 | for_each_context(priv, ctx) { | 274 | for_each_context(priv, ctx) { |
| 275 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 275 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
| 276 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); | 276 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); |
| 277 | iwlcore_commit_rxon(priv, ctx); | 277 | iwlagn_commit_rxon(priv, ctx); |
| 278 | } | 278 | } |
| 279 | 279 | ||
| 280 | priv->cfg->ops->hcmd->send_bt_config(priv); | 280 | priv->cfg->ops->hcmd->send_bt_config(priv); |
| @@ -2056,7 +2056,7 @@ int iwl_alive_start(struct iwl_priv *priv) | |||
| 2056 | set_bit(STATUS_READY, &priv->status); | 2056 | set_bit(STATUS_READY, &priv->status); |
| 2057 | 2057 | ||
| 2058 | /* Configure the adapter for unassociated operation */ | 2058 | /* Configure the adapter for unassociated operation */ |
| 2059 | ret = iwlcore_commit_rxon(priv, ctx); | 2059 | ret = iwlagn_commit_rxon(priv, ctx); |
| 2060 | if (ret) | 2060 | if (ret) |
| 2061 | return ret; | 2061 | return ret; |
| 2062 | 2062 | ||
| @@ -2420,6 +2420,77 @@ unlock: | |||
| 2420 | * | 2420 | * |
| 2421 | *****************************************************************************/ | 2421 | *****************************************************************************/ |
| 2422 | 2422 | ||
| 2423 | static const struct ieee80211_iface_limit iwlagn_sta_ap_limits[] = { | ||
| 2424 | { | ||
| 2425 | .max = 1, | ||
| 2426 | .types = BIT(NL80211_IFTYPE_STATION), | ||
| 2427 | }, | ||
| 2428 | { | ||
| 2429 | .max = 1, | ||
| 2430 | .types = BIT(NL80211_IFTYPE_AP), | ||
| 2431 | }, | ||
| 2432 | }; | ||
| 2433 | |||
| 2434 | static const struct ieee80211_iface_limit iwlagn_2sta_limits[] = { | ||
| 2435 | { | ||
| 2436 | .max = 2, | ||
| 2437 | .types = BIT(NL80211_IFTYPE_STATION), | ||
| 2438 | }, | ||
| 2439 | }; | ||
| 2440 | |||
| 2441 | static const struct ieee80211_iface_limit iwlagn_p2p_sta_go_limits[] = { | ||
| 2442 | { | ||
| 2443 | .max = 1, | ||
| 2444 | .types = BIT(NL80211_IFTYPE_STATION), | ||
| 2445 | }, | ||
| 2446 | { | ||
| 2447 | .max = 1, | ||
| 2448 | .types = BIT(NL80211_IFTYPE_P2P_GO) | | ||
| 2449 | BIT(NL80211_IFTYPE_AP), | ||
| 2450 | }, | ||
| 2451 | }; | ||
| 2452 | |||
| 2453 | static const struct ieee80211_iface_limit iwlagn_p2p_2sta_limits[] = { | ||
| 2454 | { | ||
| 2455 | .max = 2, | ||
| 2456 | .types = BIT(NL80211_IFTYPE_STATION), | ||
| 2457 | }, | ||
| 2458 | { | ||
| 2459 | .max = 1, | ||
| 2460 | .types = BIT(NL80211_IFTYPE_P2P_CLIENT), | ||
| 2461 | }, | ||
| 2462 | }; | ||
| 2463 | |||
| 2464 | static const struct ieee80211_iface_combination | ||
| 2465 | iwlagn_iface_combinations_dualmode[] = { | ||
| 2466 | { .num_different_channels = 1, | ||
| 2467 | .max_interfaces = 2, | ||
| 2468 | .beacon_int_infra_match = true, | ||
| 2469 | .limits = iwlagn_sta_ap_limits, | ||
| 2470 | .n_limits = ARRAY_SIZE(iwlagn_sta_ap_limits), | ||
| 2471 | }, | ||
| 2472 | { .num_different_channels = 1, | ||
| 2473 | .max_interfaces = 2, | ||
| 2474 | .limits = iwlagn_2sta_limits, | ||
| 2475 | .n_limits = ARRAY_SIZE(iwlagn_2sta_limits), | ||
| 2476 | }, | ||
| 2477 | }; | ||
| 2478 | |||
| 2479 | static const struct ieee80211_iface_combination | ||
| 2480 | iwlagn_iface_combinations_p2p[] = { | ||
| 2481 | { .num_different_channels = 1, | ||
| 2482 | .max_interfaces = 2, | ||
| 2483 | .beacon_int_infra_match = true, | ||
| 2484 | .limits = iwlagn_p2p_sta_go_limits, | ||
| 2485 | .n_limits = ARRAY_SIZE(iwlagn_p2p_sta_go_limits), | ||
| 2486 | }, | ||
| 2487 | { .num_different_channels = 1, | ||
| 2488 | .max_interfaces = 2, | ||
| 2489 | .limits = iwlagn_p2p_2sta_limits, | ||
| 2490 | .n_limits = ARRAY_SIZE(iwlagn_p2p_2sta_limits), | ||
| 2491 | }, | ||
| 2492 | }; | ||
| 2493 | |||
| 2423 | /* | 2494 | /* |
| 2424 | * Not a mac80211 entry point function, but it fits in with all the | 2495 | * Not a mac80211 entry point function, but it fits in with all the |
| 2425 | * other mac80211 functions grouped here. | 2496 | * other mac80211 functions grouped here. |
| @@ -2460,6 +2531,18 @@ static int iwl_mac_setup_register(struct iwl_priv *priv, | |||
| 2460 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; | 2531 | hw->wiphy->interface_modes |= ctx->exclusive_interface_modes; |
| 2461 | } | 2532 | } |
| 2462 | 2533 | ||
| 2534 | BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||
| 2535 | |||
| 2536 | if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_P2P_CLIENT)) { | ||
| 2537 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_p2p; | ||
| 2538 | hw->wiphy->n_iface_combinations = | ||
| 2539 | ARRAY_SIZE(iwlagn_iface_combinations_p2p); | ||
| 2540 | } else if (hw->wiphy->interface_modes & BIT(NL80211_IFTYPE_AP)) { | ||
| 2541 | hw->wiphy->iface_combinations = iwlagn_iface_combinations_dualmode; | ||
| 2542 | hw->wiphy->n_iface_combinations = | ||
| 2543 | ARRAY_SIZE(iwlagn_iface_combinations_dualmode); | ||
| 2544 | } | ||
| 2545 | |||
| 2463 | hw->wiphy->max_remain_on_channel_duration = 1000; | 2546 | hw->wiphy->max_remain_on_channel_duration = 1000; |
| 2464 | 2547 | ||
| 2465 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | | 2548 | hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | |
| @@ -2711,12 +2794,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 2711 | ret = 0; | 2794 | ret = 0; |
| 2712 | if (priv->cfg->ht_params && | 2795 | if (priv->cfg->ht_params && |
| 2713 | priv->cfg->ht_params->use_rts_for_aggregation) { | 2796 | priv->cfg->ht_params->use_rts_for_aggregation) { |
| 2714 | struct iwl_station_priv *sta_priv = | ||
| 2715 | (void *) sta->drv_priv; | ||
| 2716 | /* | 2797 | /* |
| 2717 | * switch off RTS/CTS if it was previously enabled | 2798 | * switch off RTS/CTS if it was previously enabled |
| 2718 | */ | 2799 | */ |
| 2719 | |||
| 2720 | sta_priv->lq_sta.lq.general_params.flags &= | 2800 | sta_priv->lq_sta.lq.general_params.flags &= |
| 2721 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; | 2801 | ~LINK_QUAL_FLAGS_SET_STA_TLC_RTS_MSK; |
| 2722 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | 2802 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), |
| @@ -2764,6 +2844,9 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, | |||
| 2764 | 2844 | ||
| 2765 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), | 2845 | iwl_send_lq_cmd(priv, iwl_rxon_ctx_from_vif(vif), |
| 2766 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); | 2846 | &sta_priv->lq_sta.lq, CMD_ASYNC, false); |
| 2847 | |||
| 2848 | IWL_INFO(priv, "Tx aggregation enabled on ra = %pM tid = %d\n", | ||
| 2849 | sta->addr, tid); | ||
| 2767 | ret = 0; | 2850 | ret = 0; |
| 2768 | break; | 2851 | break; |
| 2769 | } | 2852 | } |
| @@ -2833,7 +2916,6 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 2833 | */ | 2916 | */ |
| 2834 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 2917 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 2835 | u16 ch; | 2918 | u16 ch; |
| 2836 | unsigned long flags = 0; | ||
| 2837 | 2919 | ||
| 2838 | IWL_DEBUG_MAC80211(priv, "enter\n"); | 2920 | IWL_DEBUG_MAC80211(priv, "enter\n"); |
| 2839 | 2921 | ||
| @@ -2843,73 +2925,73 @@ static void iwlagn_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 2843 | goto out; | 2925 | goto out; |
| 2844 | 2926 | ||
| 2845 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | 2927 | if (test_bit(STATUS_EXIT_PENDING, &priv->status) || |
| 2846 | test_bit(STATUS_SCANNING, &priv->status)) | 2928 | test_bit(STATUS_SCANNING, &priv->status) || |
| 2929 | test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) | ||
| 2847 | goto out; | 2930 | goto out; |
| 2848 | 2931 | ||
| 2849 | if (!iwl_is_associated_ctx(ctx)) | 2932 | if (!iwl_is_associated_ctx(ctx)) |
| 2850 | goto out; | 2933 | goto out; |
| 2851 | 2934 | ||
| 2852 | /* channel switch in progress */ | 2935 | if (!priv->cfg->ops->lib->set_channel_switch) |
| 2853 | if (priv->switch_rxon.switch_in_progress == true) | ||
| 2854 | goto out; | 2936 | goto out; |
| 2855 | 2937 | ||
| 2856 | if (priv->cfg->ops->lib->set_channel_switch) { | 2938 | ch = channel->hw_value; |
| 2939 | if (le16_to_cpu(ctx->active.channel) == ch) | ||
| 2940 | goto out; | ||
| 2857 | 2941 | ||
| 2858 | ch = channel->hw_value; | 2942 | ch_info = iwl_get_channel_info(priv, channel->band, ch); |
| 2859 | if (le16_to_cpu(ctx->active.channel) != ch) { | 2943 | if (!is_channel_valid(ch_info)) { |
| 2860 | ch_info = iwl_get_channel_info(priv, | 2944 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); |
| 2861 | channel->band, | 2945 | goto out; |
| 2862 | ch); | 2946 | } |
| 2863 | if (!is_channel_valid(ch_info)) { | ||
| 2864 | IWL_DEBUG_MAC80211(priv, "invalid channel\n"); | ||
| 2865 | goto out; | ||
| 2866 | } | ||
| 2867 | spin_lock_irqsave(&priv->lock, flags); | ||
| 2868 | |||
| 2869 | priv->current_ht_config.smps = conf->smps_mode; | ||
| 2870 | |||
| 2871 | /* Configure HT40 channels */ | ||
| 2872 | ctx->ht.enabled = conf_is_ht(conf); | ||
| 2873 | if (ctx->ht.enabled) { | ||
| 2874 | if (conf_is_ht40_minus(conf)) { | ||
| 2875 | ctx->ht.extension_chan_offset = | ||
| 2876 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; | ||
| 2877 | ctx->ht.is_40mhz = true; | ||
| 2878 | } else if (conf_is_ht40_plus(conf)) { | ||
| 2879 | ctx->ht.extension_chan_offset = | ||
| 2880 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 2881 | ctx->ht.is_40mhz = true; | ||
| 2882 | } else { | ||
| 2883 | ctx->ht.extension_chan_offset = | ||
| 2884 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 2885 | ctx->ht.is_40mhz = false; | ||
| 2886 | } | ||
| 2887 | } else | ||
| 2888 | ctx->ht.is_40mhz = false; | ||
| 2889 | 2947 | ||
| 2890 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | 2948 | spin_lock_irq(&priv->lock); |
| 2891 | ctx->staging.flags = 0; | ||
| 2892 | 2949 | ||
| 2893 | iwl_set_rxon_channel(priv, channel, ctx); | 2950 | priv->current_ht_config.smps = conf->smps_mode; |
| 2894 | iwl_set_rxon_ht(priv, ht_conf); | ||
| 2895 | iwl_set_flags_for_band(priv, ctx, channel->band, | ||
| 2896 | ctx->vif); | ||
| 2897 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 2898 | 2951 | ||
| 2899 | iwl_set_rate(priv); | 2952 | /* Configure HT40 channels */ |
| 2900 | /* | 2953 | ctx->ht.enabled = conf_is_ht(conf); |
| 2901 | * at this point, staging_rxon has the | 2954 | if (ctx->ht.enabled) { |
| 2902 | * configuration for channel switch | 2955 | if (conf_is_ht40_minus(conf)) { |
| 2903 | */ | 2956 | ctx->ht.extension_chan_offset = |
| 2904 | if (priv->cfg->ops->lib->set_channel_switch(priv, | 2957 | IEEE80211_HT_PARAM_CHA_SEC_BELOW; |
| 2905 | ch_switch)) | 2958 | ctx->ht.is_40mhz = true; |
| 2906 | priv->switch_rxon.switch_in_progress = false; | 2959 | } else if (conf_is_ht40_plus(conf)) { |
| 2960 | ctx->ht.extension_chan_offset = | ||
| 2961 | IEEE80211_HT_PARAM_CHA_SEC_ABOVE; | ||
| 2962 | ctx->ht.is_40mhz = true; | ||
| 2963 | } else { | ||
| 2964 | ctx->ht.extension_chan_offset = | ||
| 2965 | IEEE80211_HT_PARAM_CHA_SEC_NONE; | ||
| 2966 | ctx->ht.is_40mhz = false; | ||
| 2907 | } | 2967 | } |
| 2968 | } else | ||
| 2969 | ctx->ht.is_40mhz = false; | ||
| 2970 | |||
| 2971 | if ((le16_to_cpu(ctx->staging.channel) != ch)) | ||
| 2972 | ctx->staging.flags = 0; | ||
| 2973 | |||
| 2974 | iwl_set_rxon_channel(priv, channel, ctx); | ||
| 2975 | iwl_set_rxon_ht(priv, ht_conf); | ||
| 2976 | iwl_set_flags_for_band(priv, ctx, channel->band, ctx->vif); | ||
| 2977 | |||
| 2978 | spin_unlock_irq(&priv->lock); | ||
| 2979 | |||
| 2980 | iwl_set_rate(priv); | ||
| 2981 | /* | ||
| 2982 | * at this point, staging_rxon has the | ||
| 2983 | * configuration for channel switch | ||
| 2984 | */ | ||
| 2985 | set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | ||
| 2986 | priv->switch_channel = cpu_to_le16(ch); | ||
| 2987 | if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) { | ||
| 2988 | clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status); | ||
| 2989 | priv->switch_channel = 0; | ||
| 2990 | ieee80211_chswitch_done(ctx->vif, false); | ||
| 2908 | } | 2991 | } |
| 2992 | |||
| 2909 | out: | 2993 | out: |
| 2910 | mutex_unlock(&priv->mutex); | 2994 | mutex_unlock(&priv->mutex); |
| 2911 | if (!priv->switch_rxon.switch_in_progress) | ||
| 2912 | ieee80211_chswitch_done(ctx->vif, false); | ||
| 2913 | IWL_DEBUG_MAC80211(priv, "leave\n"); | 2995 | IWL_DEBUG_MAC80211(priv, "leave\n"); |
| 2914 | } | 2996 | } |
| 2915 | 2997 | ||
| @@ -3018,7 +3100,7 @@ static void iwlagn_disable_roc(struct iwl_priv *priv) | |||
| 3018 | 3100 | ||
| 3019 | priv->_agn.hw_roc_channel = NULL; | 3101 | priv->_agn.hw_roc_channel = NULL; |
| 3020 | 3102 | ||
| 3021 | iwlcore_commit_rxon(priv, ctx); | 3103 | iwlagn_commit_rxon(priv, ctx); |
| 3022 | 3104 | ||
| 3023 | ctx->is_active = false; | 3105 | ctx->is_active = false; |
| 3024 | } | 3106 | } |
| @@ -3061,7 +3143,7 @@ static int iwl_mac_remain_on_channel(struct ieee80211_hw *hw, | |||
| 3061 | priv->_agn.hw_roc_channel = channel; | 3143 | priv->_agn.hw_roc_channel = channel; |
| 3062 | priv->_agn.hw_roc_chantype = channel_type; | 3144 | priv->_agn.hw_roc_chantype = channel_type; |
| 3063 | priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); | 3145 | priv->_agn.hw_roc_duration = DIV_ROUND_UP(duration * 1000, 1024); |
| 3064 | iwlcore_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); | 3146 | iwlagn_commit_rxon(priv, &priv->contexts[IWL_RXON_CTX_PAN]); |
| 3065 | queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, | 3147 | queue_delayed_work(priv->workqueue, &priv->_agn.hw_roc_work, |
| 3066 | msecs_to_jiffies(duration + 20)); | 3148 | msecs_to_jiffies(duration + 20)); |
| 3067 | 3149 | ||
| @@ -3618,8 +3700,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 3618 | destroy_workqueue(priv->workqueue); | 3700 | destroy_workqueue(priv->workqueue); |
| 3619 | priv->workqueue = NULL; | 3701 | priv->workqueue = NULL; |
| 3620 | free_irq(priv->pci_dev->irq, priv); | 3702 | free_irq(priv->pci_dev->irq, priv); |
| 3621 | iwl_free_isr_ict(priv); | ||
| 3622 | out_disable_msi: | 3703 | out_disable_msi: |
| 3704 | iwl_free_isr_ict(priv); | ||
| 3623 | pci_disable_msi(priv->pci_dev); | 3705 | pci_disable_msi(priv->pci_dev); |
| 3624 | iwl_uninit_drv(priv); | 3706 | iwl_uninit_drv(priv); |
| 3625 | out_free_eeprom: | 3707 | out_free_eeprom: |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 4653deada05b..5416b12cd931 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
| @@ -843,12 +843,8 @@ void iwl_chswitch_done(struct iwl_priv *priv, bool is_success) | |||
| 843 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | 843 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) |
| 844 | return; | 844 | return; |
| 845 | 845 | ||
| 846 | if (priv->switch_rxon.switch_in_progress) { | 846 | if (test_and_clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
| 847 | ieee80211_chswitch_done(ctx->vif, is_success); | 847 | ieee80211_chswitch_done(ctx->vif, is_success); |
| 848 | mutex_lock(&priv->mutex); | ||
| 849 | priv->switch_rxon.switch_in_progress = false; | ||
| 850 | mutex_unlock(&priv->mutex); | ||
| 851 | } | ||
| 852 | } | 848 | } |
| 853 | 849 | ||
| 854 | #ifdef CONFIG_IWLWIFI_DEBUG | 850 | #ifdef CONFIG_IWLWIFI_DEBUG |
| @@ -1131,9 +1127,6 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
| 1131 | if (priv->tx_power_user_lmt == tx_power && !force) | 1127 | if (priv->tx_power_user_lmt == tx_power && !force) |
| 1132 | return 0; | 1128 | return 0; |
| 1133 | 1129 | ||
| 1134 | if (!priv->cfg->ops->lib->send_tx_power) | ||
| 1135 | return -EOPNOTSUPP; | ||
| 1136 | |||
| 1137 | if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { | 1130 | if (tx_power < IWLAGN_TX_POWER_TARGET_POWER_MIN) { |
| 1138 | IWL_WARN(priv, | 1131 | IWL_WARN(priv, |
| 1139 | "Requested user TXPOWER %d below lower limit %d.\n", | 1132 | "Requested user TXPOWER %d below lower limit %d.\n", |
| @@ -1167,7 +1160,7 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) | |||
| 1167 | prev_tx_power = priv->tx_power_user_lmt; | 1160 | prev_tx_power = priv->tx_power_user_lmt; |
| 1168 | priv->tx_power_user_lmt = tx_power; | 1161 | priv->tx_power_user_lmt = tx_power; |
| 1169 | 1162 | ||
| 1170 | ret = priv->cfg->ops->lib->send_tx_power(priv); | 1163 | ret = iwlagn_send_tx_power(priv); |
| 1171 | 1164 | ||
| 1172 | /* if fail to set tx_power, restore the orig. tx power */ | 1165 | /* if fail to set tx_power, restore the orig. tx power */ |
| 1173 | if (ret) { | 1166 | if (ret) { |
| @@ -1282,7 +1275,7 @@ static int iwl_set_mode(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 1282 | if (priv->cfg->ops->hcmd->set_rxon_chain) | 1275 | if (priv->cfg->ops->hcmd->set_rxon_chain) |
| 1283 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); | 1276 | priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx); |
| 1284 | 1277 | ||
| 1285 | return iwlcore_commit_rxon(priv, ctx); | 1278 | return iwlagn_commit_rxon(priv, ctx); |
| 1286 | } | 1279 | } |
| 1287 | 1280 | ||
| 1288 | static int iwl_setup_interface(struct iwl_priv *priv, | 1281 | static int iwl_setup_interface(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 3bb76f6ea410..05ea88aa76e3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
| @@ -90,7 +90,6 @@ struct iwl_cmd; | |||
| 90 | #define IWL_CMD(x) case x: return #x | 90 | #define IWL_CMD(x) case x: return #x |
| 91 | 91 | ||
| 92 | struct iwl_hcmd_ops { | 92 | struct iwl_hcmd_ops { |
| 93 | int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||
| 94 | void (*set_rxon_chain)(struct iwl_priv *priv, | 93 | void (*set_rxon_chain)(struct iwl_priv *priv, |
| 95 | struct iwl_rxon_context *ctx); | 94 | struct iwl_rxon_context *ctx); |
| 96 | int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); | 95 | int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); |
| @@ -112,7 +111,6 @@ struct iwl_hcmd_utils_ops { | |||
| 112 | int (*calc_rssi)(struct iwl_priv *priv, | 111 | int (*calc_rssi)(struct iwl_priv *priv, |
| 113 | struct iwl_rx_phy_res *rx_resp); | 112 | struct iwl_rx_phy_res *rx_resp); |
| 114 | int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); | 113 | int (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif); |
| 115 | void (*post_scan)(struct iwl_priv *priv); | ||
| 116 | }; | 114 | }; |
| 117 | 115 | ||
| 118 | struct iwl_apm_ops { | 116 | struct iwl_apm_ops { |
| @@ -141,7 +139,6 @@ struct iwl_lib_ops { | |||
| 141 | struct iwl_apm_ops apm_ops; | 139 | struct iwl_apm_ops apm_ops; |
| 142 | 140 | ||
| 143 | /* power */ | 141 | /* power */ |
| 144 | int (*send_tx_power) (struct iwl_priv *priv); | ||
| 145 | void (*update_chain_flags)(struct iwl_priv *priv); | 142 | void (*update_chain_flags)(struct iwl_priv *priv); |
| 146 | 143 | ||
| 147 | /* eeprom operations (as defined in iwl-eeprom.h) */ | 144 | /* eeprom operations (as defined in iwl-eeprom.h) */ |
| @@ -225,7 +222,7 @@ struct iwl_base_params { | |||
| 225 | * @ampdu_factor: Maximum A-MPDU length factor | 222 | * @ampdu_factor: Maximum A-MPDU length factor |
| 226 | * @ampdu_density: Minimum A-MPDU spacing | 223 | * @ampdu_density: Minimum A-MPDU spacing |
| 227 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode | 224 | * @bt_sco_disable: uCode should not response to BT in SCO/ESCO mode |
| 228 | */ | 225 | */ |
| 229 | struct iwl_bt_params { | 226 | struct iwl_bt_params { |
| 230 | bool advanced_bt_coexist; | 227 | bool advanced_bt_coexist; |
| 231 | u8 bt_init_traffic_load; | 228 | u8 bt_init_traffic_load; |
| @@ -238,10 +235,11 @@ struct iwl_bt_params { | |||
| 238 | }; | 235 | }; |
| 239 | /* | 236 | /* |
| 240 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 237 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
| 241 | */ | 238 | */ |
| 242 | struct iwl_ht_params { | 239 | struct iwl_ht_params { |
| 243 | const bool ht_greenfield_support; /* if used set to true */ | 240 | const bool ht_greenfield_support; /* if used set to true */ |
| 244 | bool use_rts_for_aggregation; | 241 | bool use_rts_for_aggregation; |
| 242 | enum ieee80211_smps_mode smps_mode; | ||
| 245 | }; | 243 | }; |
| 246 | 244 | ||
| 247 | /** | 245 | /** |
| @@ -560,6 +558,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
| 560 | #define STATUS_POWER_PMI 16 | 558 | #define STATUS_POWER_PMI 16 |
| 561 | #define STATUS_FW_ERROR 17 | 559 | #define STATUS_FW_ERROR 17 |
| 562 | #define STATUS_DEVICE_ENABLED 18 | 560 | #define STATUS_DEVICE_ENABLED 18 |
| 561 | #define STATUS_CHANNEL_SWITCH_PENDING 19 | ||
| 563 | 562 | ||
| 564 | 563 | ||
| 565 | static inline int iwl_is_ready(struct iwl_priv *priv) | 564 | static inline int iwl_is_ready(struct iwl_priv *priv) |
| @@ -612,11 +611,7 @@ void iwl_apm_stop(struct iwl_priv *priv); | |||
| 612 | int iwl_apm_init(struct iwl_priv *priv); | 611 | int iwl_apm_init(struct iwl_priv *priv); |
| 613 | 612 | ||
| 614 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | 613 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
| 615 | static inline int iwlcore_commit_rxon(struct iwl_priv *priv, | 614 | |
| 616 | struct iwl_rxon_context *ctx) | ||
| 617 | { | ||
| 618 | return priv->cfg->ops->hcmd->commit_rxon(priv, ctx); | ||
| 619 | } | ||
| 620 | static inline const struct ieee80211_supported_band *iwl_get_hw_mode( | 615 | static inline const struct ieee80211_supported_band *iwl_get_hw_mode( |
| 621 | struct iwl_priv *priv, enum ieee80211_band band) | 616 | struct iwl_priv *priv, enum ieee80211_band band) |
| 622 | { | 617 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 1f4797d9848d..7ad98d868954 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
| @@ -983,17 +983,6 @@ struct traffic_stats { | |||
| 983 | }; | 983 | }; |
| 984 | 984 | ||
| 985 | /* | 985 | /* |
| 986 | * iwl_switch_rxon: "channel switch" structure | ||
| 987 | * | ||
| 988 | * @ switch_in_progress: channel switch in progress | ||
| 989 | * @ channel: new channel | ||
| 990 | */ | ||
| 991 | struct iwl_switch_rxon { | ||
| 992 | bool switch_in_progress; | ||
| 993 | __le16 channel; | ||
| 994 | }; | ||
| 995 | |||
| 996 | /* | ||
| 997 | * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds | 986 | * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds |
| 998 | * to perform continuous uCode event logging operation if enabled | 987 | * to perform continuous uCode event logging operation if enabled |
| 999 | */ | 988 | */ |
| @@ -1288,7 +1277,7 @@ struct iwl_priv { | |||
| 1288 | 1277 | ||
| 1289 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; | 1278 | struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX]; |
| 1290 | 1279 | ||
| 1291 | struct iwl_switch_rxon switch_rxon; | 1280 | __le16 switch_channel; |
| 1292 | 1281 | ||
| 1293 | struct { | 1282 | struct { |
| 1294 | u32 error_event_table; | 1283 | u32 error_event_table; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 0053e9ea9021..b774517aa9fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
| @@ -250,19 +250,19 @@ static void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 250 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 250 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
| 251 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; | 251 | struct iwl_rxon_cmd *rxon = (void *)&ctx->active; |
| 252 | 252 | ||
| 253 | if (priv->switch_rxon.switch_in_progress) { | 253 | if (!test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status)) |
| 254 | if (!le32_to_cpu(csa->status) && | 254 | return; |
| 255 | (csa->channel == priv->switch_rxon.channel)) { | 255 | |
| 256 | rxon->channel = csa->channel; | 256 | if (!le32_to_cpu(csa->status) && csa->channel == priv->switch_channel) { |
| 257 | ctx->staging.channel = csa->channel; | 257 | rxon->channel = csa->channel; |
| 258 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", | 258 | ctx->staging.channel = csa->channel; |
| 259 | le16_to_cpu(csa->channel)); | 259 | IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", |
| 260 | iwl_chswitch_done(priv, true); | ||
| 261 | } else { | ||
| 262 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
| 263 | le16_to_cpu(csa->channel)); | 260 | le16_to_cpu(csa->channel)); |
| 264 | iwl_chswitch_done(priv, false); | 261 | iwl_chswitch_done(priv, true); |
| 265 | } | 262 | } else { |
| 263 | IWL_ERR(priv, "CSA notif (fail) : channel %d\n", | ||
| 264 | le16_to_cpu(csa->channel)); | ||
| 265 | iwl_chswitch_done(priv, false); | ||
| 266 | } | 266 | } |
| 267 | } | 267 | } |
| 268 | 268 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index d60d630cb93a..438eecd87335 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include "iwl-sta.h" | 36 | #include "iwl-sta.h" |
| 37 | #include "iwl-io.h" | 37 | #include "iwl-io.h" |
| 38 | #include "iwl-helpers.h" | 38 | #include "iwl-helpers.h" |
| 39 | #include "iwl-agn.h" | ||
| 39 | 40 | ||
| 40 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after | 41 | /* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after |
| 41 | * sending probe req. This should be set long enough to hear probe responses | 42 | * sending probe req. This should be set long enough to hear probe responses |
| @@ -600,14 +601,7 @@ out_settings: | |||
| 600 | if (!iwl_is_ready_rf(priv)) | 601 | if (!iwl_is_ready_rf(priv)) |
| 601 | goto out; | 602 | goto out; |
| 602 | 603 | ||
| 603 | /* | 604 | iwlagn_post_scan(priv); |
| 604 | * We do not commit power settings while scan is pending, | ||
| 605 | * do it now if the settings changed. | ||
| 606 | */ | ||
| 607 | iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false); | ||
| 608 | iwl_set_tx_power(priv, priv->tx_power_next, false); | ||
| 609 | |||
| 610 | priv->cfg->ops->utils->post_scan(priv); | ||
| 611 | 605 | ||
| 612 | out: | 606 | out: |
| 613 | mutex_unlock(&priv->mutex); | 607 | mutex_unlock(&priv->mutex); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 686e176b5ebd..1084fe0e8a86 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
| @@ -753,9 +753,9 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id, int idx) | |||
| 753 | int nfreed = 0; | 753 | int nfreed = 0; |
| 754 | 754 | ||
| 755 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { | 755 | if ((idx >= q->n_bd) || (iwl_queue_used(q, idx) == 0)) { |
| 756 | IWL_ERR(priv, "Read index for DMA queue txq id (%d), index %d, " | 756 | IWL_ERR(priv, "%s: Read index for DMA queue txq id (%d), " |
| 757 | "is out of range [0-%d] %d %d.\n", txq_id, | 757 | "index %d is out of range [0-%d] %d %d.\n", __func__, |
| 758 | idx, q->n_bd, q->write_ptr, q->read_ptr); | 758 | txq_id, idx, q->n_bd, q->write_ptr, q->read_ptr); |
| 759 | return; | 759 | return; |
| 760 | } | 760 | } |
| 761 | 761 | ||
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index a7b5cb0c2753..224e9853c480 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
| @@ -907,7 +907,7 @@ static void if_sdio_interrupt(struct sdio_func *func) | |||
| 907 | card = sdio_get_drvdata(func); | 907 | card = sdio_get_drvdata(func); |
| 908 | 908 | ||
| 909 | cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret); | 909 | cause = sdio_readb(card->func, IF_SDIO_H_INT_STATUS, &ret); |
| 910 | if (ret) | 910 | if (ret || !cause) |
| 911 | goto out; | 911 | goto out; |
| 912 | 912 | ||
| 913 | lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause); | 913 | lbs_deb_sdio("interrupt: 0x%X\n", (unsigned)cause); |
| @@ -1008,10 +1008,6 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 1008 | if (ret) | 1008 | if (ret) |
| 1009 | goto release; | 1009 | goto release; |
| 1010 | 1010 | ||
| 1011 | ret = sdio_claim_irq(func, if_sdio_interrupt); | ||
| 1012 | if (ret) | ||
| 1013 | goto disable; | ||
| 1014 | |||
| 1015 | /* For 1-bit transfers to the 8686 model, we need to enable the | 1011 | /* For 1-bit transfers to the 8686 model, we need to enable the |
| 1016 | * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 | 1012 | * interrupt flag in the CCCR register. Set the MMC_QUIRK_LENIENT_FN0 |
| 1017 | * bit to allow access to non-vendor registers. */ | 1013 | * bit to allow access to non-vendor registers. */ |
| @@ -1083,6 +1079,21 @@ static int if_sdio_probe(struct sdio_func *func, | |||
| 1083 | card->rx_unit = 0; | 1079 | card->rx_unit = 0; |
| 1084 | 1080 | ||
| 1085 | /* | 1081 | /* |
| 1082 | * Set up the interrupt handler late. | ||
| 1083 | * | ||
| 1084 | * If we set it up earlier, the (buggy) hardware generates a spurious | ||
| 1085 | * interrupt, even before the interrupt has been enabled, with | ||
| 1086 | * CCCR_INTx = 0. | ||
| 1087 | * | ||
| 1088 | * We register the interrupt handler late so that we can handle any | ||
| 1089 | * spurious interrupts, and also to avoid generation of that known | ||
| 1090 | * spurious interrupt in the first place. | ||
| 1091 | */ | ||
| 1092 | ret = sdio_claim_irq(func, if_sdio_interrupt); | ||
| 1093 | if (ret) | ||
| 1094 | goto disable; | ||
| 1095 | |||
| 1096 | /* | ||
| 1086 | * Enable interrupts now that everything is set up | 1097 | * Enable interrupts now that everything is set up |
| 1087 | */ | 1098 | */ |
| 1088 | sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); | 1099 | sdio_writeb(func, 0x0f, IF_SDIO_H_INT_MASK, &ret); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 9d4a40ee16c4..7e1fa9671277 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 | 2 | * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 |
| 3 | * Copyright (c) 2008, Jouni Malinen <j@w1.fi> | 3 | * Copyright (c) 2008, Jouni Malinen <j@w1.fi> |
| 4 | * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com> | ||
| 4 | * | 5 | * |
| 5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
| @@ -25,11 +26,17 @@ | |||
| 25 | #include <linux/rtnetlink.h> | 26 | #include <linux/rtnetlink.h> |
| 26 | #include <linux/etherdevice.h> | 27 | #include <linux/etherdevice.h> |
| 27 | #include <linux/debugfs.h> | 28 | #include <linux/debugfs.h> |
| 29 | #include <net/genetlink.h> | ||
| 30 | #include "mac80211_hwsim.h" | ||
| 31 | |||
| 32 | #define WARN_QUEUE 100 | ||
| 33 | #define MAX_QUEUE 200 | ||
| 28 | 34 | ||
| 29 | MODULE_AUTHOR("Jouni Malinen"); | 35 | MODULE_AUTHOR("Jouni Malinen"); |
| 30 | MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); | 36 | MODULE_DESCRIPTION("Software simulator of 802.11 radio(s) for mac80211"); |
| 31 | MODULE_LICENSE("GPL"); | 37 | MODULE_LICENSE("GPL"); |
| 32 | 38 | ||
| 39 | int wmediumd_pid; | ||
| 33 | static int radios = 2; | 40 | static int radios = 2; |
| 34 | module_param(radios, int, 0444); | 41 | module_param(radios, int, 0444); |
| 35 | MODULE_PARM_DESC(radios, "Number of simulated radios"); | 42 | MODULE_PARM_DESC(radios, "Number of simulated radios"); |
| @@ -302,6 +309,7 @@ struct mac80211_hwsim_data { | |||
| 302 | struct dentry *debugfs; | 309 | struct dentry *debugfs; |
| 303 | struct dentry *debugfs_ps; | 310 | struct dentry *debugfs_ps; |
| 304 | 311 | ||
| 312 | struct sk_buff_head pending; /* packets pending */ | ||
| 305 | /* | 313 | /* |
| 306 | * Only radios in the same group can communicate together (the | 314 | * Only radios in the same group can communicate together (the |
| 307 | * channel has to match too). Each bit represents a group. A | 315 | * channel has to match too). Each bit represents a group. A |
| @@ -322,6 +330,32 @@ struct hwsim_radiotap_hdr { | |||
| 322 | __le16 rt_chbitmask; | 330 | __le16 rt_chbitmask; |
| 323 | } __packed; | 331 | } __packed; |
| 324 | 332 | ||
| 333 | /* MAC80211_HWSIM netlinf family */ | ||
| 334 | static struct genl_family hwsim_genl_family = { | ||
| 335 | .id = GENL_ID_GENERATE, | ||
| 336 | .hdrsize = 0, | ||
| 337 | .name = "MAC80211_HWSIM", | ||
| 338 | .version = 1, | ||
| 339 | .maxattr = HWSIM_ATTR_MAX, | ||
| 340 | }; | ||
| 341 | |||
| 342 | /* MAC80211_HWSIM netlink policy */ | ||
| 343 | |||
| 344 | static struct nla_policy hwsim_genl_policy[HWSIM_ATTR_MAX + 1] = { | ||
| 345 | [HWSIM_ATTR_ADDR_RECEIVER] = { .type = NLA_UNSPEC, | ||
| 346 | .len = 6*sizeof(u8) }, | ||
| 347 | [HWSIM_ATTR_ADDR_TRANSMITTER] = { .type = NLA_UNSPEC, | ||
| 348 | .len = 6*sizeof(u8) }, | ||
| 349 | [HWSIM_ATTR_FRAME] = { .type = NLA_BINARY, | ||
| 350 | .len = IEEE80211_MAX_DATA_LEN }, | ||
| 351 | [HWSIM_ATTR_FLAGS] = { .type = NLA_U32 }, | ||
| 352 | [HWSIM_ATTR_RX_RATE] = { .type = NLA_U32 }, | ||
| 353 | [HWSIM_ATTR_SIGNAL] = { .type = NLA_U32 }, | ||
| 354 | [HWSIM_ATTR_TX_INFO] = { .type = NLA_UNSPEC, | ||
| 355 | .len = IEEE80211_TX_MAX_RATES*sizeof( | ||
| 356 | struct hwsim_tx_rate)}, | ||
| 357 | [HWSIM_ATTR_COOKIE] = { .type = NLA_U64 }, | ||
| 358 | }; | ||
| 325 | 359 | ||
| 326 | static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, | 360 | static netdev_tx_t hwsim_mon_xmit(struct sk_buff *skb, |
| 327 | struct net_device *dev) | 361 | struct net_device *dev) |
| @@ -478,9 +512,89 @@ static bool mac80211_hwsim_addr_match(struct mac80211_hwsim_data *data, | |||
| 478 | return md.ret; | 512 | return md.ret; |
| 479 | } | 513 | } |
| 480 | 514 | ||
| 515 | static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw, | ||
| 516 | struct sk_buff *my_skb, | ||
| 517 | int dst_pid) | ||
| 518 | { | ||
| 519 | struct sk_buff *skb; | ||
| 520 | struct mac80211_hwsim_data *data = hw->priv; | ||
| 521 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) my_skb->data; | ||
| 522 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(my_skb); | ||
| 523 | void *msg_head; | ||
| 524 | unsigned int hwsim_flags = 0; | ||
| 525 | int i; | ||
| 526 | struct hwsim_tx_rate tx_attempts[IEEE80211_TX_MAX_RATES]; | ||
| 527 | |||
| 528 | if (data->idle) { | ||
| 529 | wiphy_debug(hw->wiphy, "Trying to TX when idle - reject\n"); | ||
| 530 | dev_kfree_skb(my_skb); | ||
| 531 | return; | ||
| 532 | } | ||
| 533 | |||
| 534 | if (data->ps != PS_DISABLED) | ||
| 535 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); | ||
| 536 | /* If the queue contains MAX_QUEUE skb's drop some */ | ||
| 537 | if (skb_queue_len(&data->pending) >= MAX_QUEUE) { | ||
| 538 | /* Droping until WARN_QUEUE level */ | ||
| 539 | while (skb_queue_len(&data->pending) >= WARN_QUEUE) | ||
| 540 | skb_dequeue(&data->pending); | ||
| 541 | } | ||
| 542 | |||
| 543 | skb = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); | ||
| 544 | if (skb == NULL) | ||
| 545 | goto nla_put_failure; | ||
| 546 | |||
| 547 | msg_head = genlmsg_put(skb, 0, 0, &hwsim_genl_family, 0, | ||
| 548 | HWSIM_CMD_FRAME); | ||
| 549 | if (msg_head == NULL) { | ||
| 550 | printk(KERN_DEBUG "mac80211_hwsim: problem with msg_head\n"); | ||
| 551 | goto nla_put_failure; | ||
| 552 | } | ||
| 553 | |||
| 554 | NLA_PUT(skb, HWSIM_ATTR_ADDR_TRANSMITTER, | ||
| 555 | sizeof(struct mac_address), data->addresses[1].addr); | ||
| 481 | 556 | ||
| 482 | static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | 557 | /* We get the skb->data */ |
| 483 | struct sk_buff *skb) | 558 | NLA_PUT(skb, HWSIM_ATTR_FRAME, my_skb->len, my_skb->data); |
| 559 | |||
| 560 | /* We get the flags for this transmission, and we translate them to | ||
| 561 | wmediumd flags */ | ||
| 562 | |||
| 563 | if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) | ||
| 564 | hwsim_flags |= HWSIM_TX_CTL_REQ_TX_STATUS; | ||
| 565 | |||
| 566 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) | ||
| 567 | hwsim_flags |= HWSIM_TX_CTL_NO_ACK; | ||
| 568 | |||
| 569 | NLA_PUT_U32(skb, HWSIM_ATTR_FLAGS, hwsim_flags); | ||
| 570 | |||
| 571 | /* We get the tx control (rate and retries) info*/ | ||
| 572 | |||
| 573 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
| 574 | tx_attempts[i].idx = info->status.rates[i].idx; | ||
| 575 | tx_attempts[i].count = info->status.rates[i].count; | ||
| 576 | } | ||
| 577 | |||
| 578 | NLA_PUT(skb, HWSIM_ATTR_TX_INFO, | ||
| 579 | sizeof(struct hwsim_tx_rate)*IEEE80211_TX_MAX_RATES, | ||
| 580 | tx_attempts); | ||
| 581 | |||
| 582 | /* We create a cookie to identify this skb */ | ||
| 583 | NLA_PUT_U64(skb, HWSIM_ATTR_COOKIE, (unsigned long) my_skb); | ||
| 584 | |||
| 585 | genlmsg_end(skb, msg_head); | ||
| 586 | genlmsg_unicast(&init_net, skb, dst_pid); | ||
| 587 | |||
| 588 | /* Enqueue the packet */ | ||
| 589 | skb_queue_tail(&data->pending, my_skb); | ||
| 590 | return; | ||
| 591 | |||
| 592 | nla_put_failure: | ||
| 593 | printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); | ||
| 594 | } | ||
| 595 | |||
| 596 | static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw, | ||
| 597 | struct sk_buff *skb) | ||
| 484 | { | 598 | { |
| 485 | struct mac80211_hwsim_data *data = hw->priv, *data2; | 599 | struct mac80211_hwsim_data *data = hw->priv, *data2; |
| 486 | bool ack = false; | 600 | bool ack = false; |
| @@ -540,11 +654,11 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw, | |||
| 540 | return ack; | 654 | return ack; |
| 541 | } | 655 | } |
| 542 | 656 | ||
| 543 | |||
| 544 | static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 657 | static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
| 545 | { | 658 | { |
| 546 | bool ack; | 659 | bool ack; |
| 547 | struct ieee80211_tx_info *txi; | 660 | struct ieee80211_tx_info *txi; |
| 661 | int _pid; | ||
| 548 | 662 | ||
| 549 | mac80211_hwsim_monitor_rx(hw, skb); | 663 | mac80211_hwsim_monitor_rx(hw, skb); |
| 550 | 664 | ||
| @@ -554,7 +668,15 @@ static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 554 | return; | 668 | return; |
| 555 | } | 669 | } |
| 556 | 670 | ||
| 557 | ack = mac80211_hwsim_tx_frame(hw, skb); | 671 | /* wmediumd mode check */ |
| 672 | _pid = wmediumd_pid; | ||
| 673 | |||
| 674 | if (_pid) | ||
| 675 | return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); | ||
| 676 | |||
| 677 | /* NO wmediumd detected, perfect medium simulation */ | ||
| 678 | ack = mac80211_hwsim_tx_frame_no_nl(hw, skb); | ||
| 679 | |||
| 558 | if (ack && skb->len >= 16) { | 680 | if (ack && skb->len >= 16) { |
| 559 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 681 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
| 560 | mac80211_hwsim_monitor_ack(hw, hdr->addr2); | 682 | mac80211_hwsim_monitor_ack(hw, hdr->addr2); |
| @@ -635,6 +757,7 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
| 635 | struct ieee80211_hw *hw = arg; | 757 | struct ieee80211_hw *hw = arg; |
| 636 | struct sk_buff *skb; | 758 | struct sk_buff *skb; |
| 637 | struct ieee80211_tx_info *info; | 759 | struct ieee80211_tx_info *info; |
| 760 | int _pid; | ||
| 638 | 761 | ||
| 639 | hwsim_check_magic(vif); | 762 | hwsim_check_magic(vif); |
| 640 | 763 | ||
| @@ -649,7 +772,14 @@ static void mac80211_hwsim_beacon_tx(void *arg, u8 *mac, | |||
| 649 | info = IEEE80211_SKB_CB(skb); | 772 | info = IEEE80211_SKB_CB(skb); |
| 650 | 773 | ||
| 651 | mac80211_hwsim_monitor_rx(hw, skb); | 774 | mac80211_hwsim_monitor_rx(hw, skb); |
| 652 | mac80211_hwsim_tx_frame(hw, skb); | 775 | |
| 776 | /* wmediumd mode check */ | ||
| 777 | _pid = wmediumd_pid; | ||
| 778 | |||
| 779 | if (_pid) | ||
| 780 | return mac80211_hwsim_tx_frame_nl(hw, skb, _pid); | ||
| 781 | |||
| 782 | mac80211_hwsim_tx_frame_no_nl(hw, skb); | ||
| 653 | dev_kfree_skb(skb); | 783 | dev_kfree_skb(skb); |
| 654 | } | 784 | } |
| 655 | 785 | ||
| @@ -966,12 +1096,7 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw, | |||
| 966 | 1096 | ||
| 967 | static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) | 1097 | static void mac80211_hwsim_flush(struct ieee80211_hw *hw, bool drop) |
| 968 | { | 1098 | { |
| 969 | /* | 1099 | /* Not implemented, queues only on kernel side */ |
| 970 | * In this special case, there's nothing we need to | ||
| 971 | * do because hwsim does transmission synchronously. | ||
| 972 | * In the future, when it does transmissions via | ||
| 973 | * userspace, we may need to do something. | ||
| 974 | */ | ||
| 975 | } | 1100 | } |
| 976 | 1101 | ||
| 977 | struct hw_scan_done { | 1102 | struct hw_scan_done { |
| @@ -1119,6 +1244,7 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) | |||
| 1119 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; | 1244 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; |
| 1120 | struct sk_buff *skb; | 1245 | struct sk_buff *skb; |
| 1121 | struct ieee80211_pspoll *pspoll; | 1246 | struct ieee80211_pspoll *pspoll; |
| 1247 | int _pid; | ||
| 1122 | 1248 | ||
| 1123 | if (!vp->assoc) | 1249 | if (!vp->assoc) |
| 1124 | return; | 1250 | return; |
| @@ -1137,8 +1263,15 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif) | |||
| 1137 | pspoll->aid = cpu_to_le16(0xc000 | vp->aid); | 1263 | pspoll->aid = cpu_to_le16(0xc000 | vp->aid); |
| 1138 | memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); | 1264 | memcpy(pspoll->bssid, vp->bssid, ETH_ALEN); |
| 1139 | memcpy(pspoll->ta, mac, ETH_ALEN); | 1265 | memcpy(pspoll->ta, mac, ETH_ALEN); |
| 1140 | if (!mac80211_hwsim_tx_frame(data->hw, skb)) | 1266 | |
| 1141 | printk(KERN_DEBUG "%s: PS-Poll frame not ack'ed\n", __func__); | 1267 | /* wmediumd mode check */ |
| 1268 | _pid = wmediumd_pid; | ||
| 1269 | |||
| 1270 | if (_pid) | ||
| 1271 | return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid); | ||
| 1272 | |||
| 1273 | if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) | ||
| 1274 | printk(KERN_DEBUG "%s: PS-poll frame not ack'ed\n", __func__); | ||
| 1142 | dev_kfree_skb(skb); | 1275 | dev_kfree_skb(skb); |
| 1143 | } | 1276 | } |
| 1144 | 1277 | ||
| @@ -1149,6 +1282,7 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | |||
| 1149 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; | 1282 | struct hwsim_vif_priv *vp = (void *)vif->drv_priv; |
| 1150 | struct sk_buff *skb; | 1283 | struct sk_buff *skb; |
| 1151 | struct ieee80211_hdr *hdr; | 1284 | struct ieee80211_hdr *hdr; |
| 1285 | int _pid; | ||
| 1152 | 1286 | ||
| 1153 | if (!vp->assoc) | 1287 | if (!vp->assoc) |
| 1154 | return; | 1288 | return; |
| @@ -1168,7 +1302,14 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac, | |||
| 1168 | memcpy(hdr->addr1, vp->bssid, ETH_ALEN); | 1302 | memcpy(hdr->addr1, vp->bssid, ETH_ALEN); |
| 1169 | memcpy(hdr->addr2, mac, ETH_ALEN); | 1303 | memcpy(hdr->addr2, mac, ETH_ALEN); |
| 1170 | memcpy(hdr->addr3, vp->bssid, ETH_ALEN); | 1304 | memcpy(hdr->addr3, vp->bssid, ETH_ALEN); |
| 1171 | if (!mac80211_hwsim_tx_frame(data->hw, skb)) | 1305 | |
| 1306 | /* wmediumd mode check */ | ||
| 1307 | _pid = wmediumd_pid; | ||
| 1308 | |||
| 1309 | if (_pid) | ||
| 1310 | return mac80211_hwsim_tx_frame_nl(data->hw, skb, _pid); | ||
| 1311 | |||
| 1312 | if (!mac80211_hwsim_tx_frame_no_nl(data->hw, skb)) | ||
| 1172 | printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); | 1313 | printk(KERN_DEBUG "%s: nullfunc frame not ack'ed\n", __func__); |
| 1173 | dev_kfree_skb(skb); | 1314 | dev_kfree_skb(skb); |
| 1174 | } | 1315 | } |
| @@ -1248,6 +1389,273 @@ DEFINE_SIMPLE_ATTRIBUTE(hwsim_fops_group, | |||
| 1248 | hwsim_fops_group_read, hwsim_fops_group_write, | 1389 | hwsim_fops_group_read, hwsim_fops_group_write, |
| 1249 | "%llx\n"); | 1390 | "%llx\n"); |
| 1250 | 1391 | ||
| 1392 | struct mac80211_hwsim_data *get_hwsim_data_ref_from_addr( | ||
| 1393 | struct mac_address *addr) | ||
| 1394 | { | ||
| 1395 | struct mac80211_hwsim_data *data; | ||
| 1396 | bool _found = false; | ||
| 1397 | |||
| 1398 | spin_lock_bh(&hwsim_radio_lock); | ||
| 1399 | list_for_each_entry(data, &hwsim_radios, list) { | ||
| 1400 | if (memcmp(data->addresses[1].addr, addr, | ||
| 1401 | sizeof(struct mac_address)) == 0) { | ||
| 1402 | _found = true; | ||
| 1403 | break; | ||
| 1404 | } | ||
| 1405 | } | ||
| 1406 | spin_unlock_bh(&hwsim_radio_lock); | ||
| 1407 | |||
| 1408 | if (!_found) | ||
| 1409 | return NULL; | ||
| 1410 | |||
| 1411 | return data; | ||
| 1412 | } | ||
| 1413 | |||
| 1414 | static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2, | ||
| 1415 | struct genl_info *info) | ||
| 1416 | { | ||
| 1417 | |||
| 1418 | struct ieee80211_hdr *hdr; | ||
| 1419 | struct mac80211_hwsim_data *data2; | ||
| 1420 | struct ieee80211_tx_info *txi; | ||
| 1421 | struct hwsim_tx_rate *tx_attempts; | ||
| 1422 | struct sk_buff __user *ret_skb; | ||
| 1423 | struct sk_buff *skb, *tmp; | ||
| 1424 | struct mac_address *src; | ||
| 1425 | unsigned int hwsim_flags; | ||
| 1426 | |||
| 1427 | int i; | ||
| 1428 | bool found = false; | ||
| 1429 | |||
| 1430 | if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] || | ||
| 1431 | !info->attrs[HWSIM_ATTR_FLAGS] || | ||
| 1432 | !info->attrs[HWSIM_ATTR_COOKIE] || | ||
| 1433 | !info->attrs[HWSIM_ATTR_TX_INFO]) | ||
| 1434 | goto out; | ||
| 1435 | |||
| 1436 | src = (struct mac_address *)nla_data( | ||
| 1437 | info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER]); | ||
| 1438 | hwsim_flags = nla_get_u32(info->attrs[HWSIM_ATTR_FLAGS]); | ||
| 1439 | |||
| 1440 | ret_skb = (struct sk_buff __user *) | ||
| 1441 | (unsigned long) nla_get_u64(info->attrs[HWSIM_ATTR_COOKIE]); | ||
| 1442 | |||
| 1443 | data2 = get_hwsim_data_ref_from_addr(src); | ||
| 1444 | |||
| 1445 | if (data2 == NULL) | ||
| 1446 | goto out; | ||
| 1447 | |||
| 1448 | /* look for the skb matching the cookie passed back from user */ | ||
| 1449 | skb_queue_walk_safe(&data2->pending, skb, tmp) { | ||
| 1450 | if (skb == ret_skb) { | ||
| 1451 | skb_unlink(skb, &data2->pending); | ||
| 1452 | found = true; | ||
| 1453 | break; | ||
| 1454 | } | ||
| 1455 | } | ||
| 1456 | |||
| 1457 | /* not found */ | ||
| 1458 | if (!found) | ||
| 1459 | goto out; | ||
| 1460 | |||
| 1461 | /* Tx info received because the frame was broadcasted on user space, | ||
| 1462 | so we get all the necessary info: tx attempts and skb control buff */ | ||
| 1463 | |||
| 1464 | tx_attempts = (struct hwsim_tx_rate *)nla_data( | ||
| 1465 | info->attrs[HWSIM_ATTR_TX_INFO]); | ||
| 1466 | |||
| 1467 | /* now send back TX status */ | ||
| 1468 | txi = IEEE80211_SKB_CB(skb); | ||
| 1469 | |||
| 1470 | if (txi->control.vif) | ||
| 1471 | hwsim_check_magic(txi->control.vif); | ||
| 1472 | if (txi->control.sta) | ||
| 1473 | hwsim_check_sta_magic(txi->control.sta); | ||
| 1474 | |||
| 1475 | ieee80211_tx_info_clear_status(txi); | ||
| 1476 | |||
| 1477 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
| 1478 | txi->status.rates[i].idx = tx_attempts[i].idx; | ||
| 1479 | txi->status.rates[i].count = tx_attempts[i].count; | ||
| 1480 | /*txi->status.rates[i].flags = 0;*/ | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | txi->status.ack_signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); | ||
| 1484 | |||
| 1485 | if (!(hwsim_flags & HWSIM_TX_CTL_NO_ACK) && | ||
| 1486 | (hwsim_flags & HWSIM_TX_STAT_ACK)) { | ||
| 1487 | if (skb->len >= 16) { | ||
| 1488 | hdr = (struct ieee80211_hdr *) skb->data; | ||
| 1489 | mac80211_hwsim_monitor_ack(data2->hw, hdr->addr2); | ||
| 1490 | } | ||
| 1491 | } | ||
| 1492 | ieee80211_tx_status_irqsafe(data2->hw, skb); | ||
| 1493 | return 0; | ||
| 1494 | out: | ||
| 1495 | return -EINVAL; | ||
| 1496 | |||
| 1497 | } | ||
| 1498 | |||
| 1499 | static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2, | ||
| 1500 | struct genl_info *info) | ||
| 1501 | { | ||
| 1502 | |||
| 1503 | struct mac80211_hwsim_data *data2; | ||
| 1504 | struct ieee80211_rx_status rx_status; | ||
| 1505 | struct mac_address *dst; | ||
| 1506 | int frame_data_len; | ||
| 1507 | char *frame_data; | ||
| 1508 | struct sk_buff *skb = NULL; | ||
| 1509 | |||
| 1510 | if (!info->attrs[HWSIM_ATTR_ADDR_RECEIVER] || | ||
| 1511 | !info->attrs[HWSIM_ATTR_FRAME] || | ||
| 1512 | !info->attrs[HWSIM_ATTR_RX_RATE] || | ||
| 1513 | !info->attrs[HWSIM_ATTR_SIGNAL]) | ||
| 1514 | goto out; | ||
| 1515 | |||
| 1516 | dst = (struct mac_address *)nla_data( | ||
| 1517 | info->attrs[HWSIM_ATTR_ADDR_RECEIVER]); | ||
| 1518 | |||
| 1519 | frame_data_len = nla_len(info->attrs[HWSIM_ATTR_FRAME]); | ||
| 1520 | frame_data = (char *)nla_data(info->attrs[HWSIM_ATTR_FRAME]); | ||
| 1521 | |||
| 1522 | /* Allocate new skb here */ | ||
| 1523 | skb = alloc_skb(frame_data_len, GFP_KERNEL); | ||
| 1524 | if (skb == NULL) | ||
| 1525 | goto err; | ||
| 1526 | |||
| 1527 | if (frame_data_len <= IEEE80211_MAX_DATA_LEN) { | ||
| 1528 | /* Copy the data */ | ||
| 1529 | memcpy(skb_put(skb, frame_data_len), frame_data, | ||
| 1530 | frame_data_len); | ||
| 1531 | } else | ||
| 1532 | goto err; | ||
| 1533 | |||
| 1534 | data2 = get_hwsim_data_ref_from_addr(dst); | ||
| 1535 | |||
| 1536 | if (data2 == NULL) | ||
| 1537 | goto out; | ||
| 1538 | |||
| 1539 | /* check if radio is configured properly */ | ||
| 1540 | |||
| 1541 | if (data2->idle || !data2->started || !data2->channel) | ||
| 1542 | goto out; | ||
| 1543 | |||
| 1544 | /*A frame is received from user space*/ | ||
| 1545 | memset(&rx_status, 0, sizeof(rx_status)); | ||
| 1546 | rx_status.freq = data2->channel->center_freq; | ||
| 1547 | rx_status.band = data2->channel->band; | ||
| 1548 | rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]); | ||
| 1549 | rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]); | ||
| 1550 | |||
| 1551 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); | ||
| 1552 | ieee80211_rx_irqsafe(data2->hw, skb); | ||
| 1553 | |||
| 1554 | return 0; | ||
| 1555 | err: | ||
| 1556 | printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); | ||
| 1557 | goto out; | ||
| 1558 | out: | ||
| 1559 | dev_kfree_skb(skb); | ||
| 1560 | return -EINVAL; | ||
| 1561 | } | ||
| 1562 | |||
| 1563 | static int hwsim_register_received_nl(struct sk_buff *skb_2, | ||
| 1564 | struct genl_info *info) | ||
| 1565 | { | ||
| 1566 | if (info == NULL) | ||
| 1567 | goto out; | ||
| 1568 | |||
| 1569 | wmediumd_pid = info->snd_pid; | ||
| 1570 | |||
| 1571 | printk(KERN_DEBUG "mac80211_hwsim: received a REGISTER, " | ||
| 1572 | "switching to wmediumd mode with pid %d\n", info->snd_pid); | ||
| 1573 | |||
| 1574 | return 0; | ||
| 1575 | out: | ||
| 1576 | printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); | ||
| 1577 | return -EINVAL; | ||
| 1578 | } | ||
| 1579 | |||
| 1580 | /* Generic Netlink operations array */ | ||
| 1581 | static struct genl_ops hwsim_ops[] = { | ||
| 1582 | { | ||
| 1583 | .cmd = HWSIM_CMD_REGISTER, | ||
| 1584 | .policy = hwsim_genl_policy, | ||
| 1585 | .doit = hwsim_register_received_nl, | ||
| 1586 | .flags = GENL_ADMIN_PERM, | ||
| 1587 | }, | ||
| 1588 | { | ||
| 1589 | .cmd = HWSIM_CMD_FRAME, | ||
| 1590 | .policy = hwsim_genl_policy, | ||
| 1591 | .doit = hwsim_cloned_frame_received_nl, | ||
| 1592 | }, | ||
| 1593 | { | ||
| 1594 | .cmd = HWSIM_CMD_TX_INFO_FRAME, | ||
| 1595 | .policy = hwsim_genl_policy, | ||
| 1596 | .doit = hwsim_tx_info_frame_received_nl, | ||
| 1597 | }, | ||
| 1598 | }; | ||
| 1599 | |||
| 1600 | static int mac80211_hwsim_netlink_notify(struct notifier_block *nb, | ||
| 1601 | unsigned long state, | ||
| 1602 | void *_notify) | ||
| 1603 | { | ||
| 1604 | struct netlink_notify *notify = _notify; | ||
| 1605 | |||
| 1606 | if (state != NETLINK_URELEASE) | ||
| 1607 | return NOTIFY_DONE; | ||
| 1608 | |||
| 1609 | if (notify->pid == wmediumd_pid) { | ||
| 1610 | printk(KERN_INFO "mac80211_hwsim: wmediumd released netlink" | ||
| 1611 | " socket, switching to perfect channel medium\n"); | ||
| 1612 | wmediumd_pid = 0; | ||
| 1613 | } | ||
| 1614 | return NOTIFY_DONE; | ||
| 1615 | |||
| 1616 | } | ||
| 1617 | |||
| 1618 | static struct notifier_block hwsim_netlink_notifier = { | ||
| 1619 | .notifier_call = mac80211_hwsim_netlink_notify, | ||
| 1620 | }; | ||
| 1621 | |||
| 1622 | static int hwsim_init_netlink(void) | ||
| 1623 | { | ||
| 1624 | int rc; | ||
| 1625 | printk(KERN_INFO "mac80211_hwsim: initializing netlink\n"); | ||
| 1626 | |||
| 1627 | wmediumd_pid = 0; | ||
| 1628 | |||
| 1629 | rc = genl_register_family_with_ops(&hwsim_genl_family, | ||
| 1630 | hwsim_ops, ARRAY_SIZE(hwsim_ops)); | ||
| 1631 | if (rc) | ||
| 1632 | goto failure; | ||
| 1633 | |||
| 1634 | rc = netlink_register_notifier(&hwsim_netlink_notifier); | ||
| 1635 | if (rc) | ||
| 1636 | goto failure; | ||
| 1637 | |||
| 1638 | return 0; | ||
| 1639 | |||
| 1640 | failure: | ||
| 1641 | printk(KERN_DEBUG "mac80211_hwsim: error occured in %s\n", __func__); | ||
| 1642 | return -EINVAL; | ||
| 1643 | } | ||
| 1644 | |||
| 1645 | static void hwsim_exit_netlink(void) | ||
| 1646 | { | ||
| 1647 | int ret; | ||
| 1648 | |||
| 1649 | printk(KERN_INFO "mac80211_hwsim: closing netlink\n"); | ||
| 1650 | /* unregister the notifier */ | ||
| 1651 | netlink_unregister_notifier(&hwsim_netlink_notifier); | ||
| 1652 | /* unregister the family */ | ||
| 1653 | ret = genl_unregister_family(&hwsim_genl_family); | ||
| 1654 | if (ret) | ||
| 1655 | printk(KERN_DEBUG "mac80211_hwsim: " | ||
| 1656 | "unregister family %i\n", ret); | ||
| 1657 | } | ||
| 1658 | |||
| 1251 | static int __init init_mac80211_hwsim(void) | 1659 | static int __init init_mac80211_hwsim(void) |
| 1252 | { | 1660 | { |
| 1253 | int i, err = 0; | 1661 | int i, err = 0; |
| @@ -1298,6 +1706,7 @@ static int __init init_mac80211_hwsim(void) | |||
| 1298 | goto failed_drvdata; | 1706 | goto failed_drvdata; |
| 1299 | } | 1707 | } |
| 1300 | data->dev->driver = &mac80211_hwsim_driver; | 1708 | data->dev->driver = &mac80211_hwsim_driver; |
| 1709 | skb_queue_head_init(&data->pending); | ||
| 1301 | 1710 | ||
| 1302 | SET_IEEE80211_DEV(hw, data->dev); | 1711 | SET_IEEE80211_DEV(hw, data->dev); |
| 1303 | addr[3] = i >> 8; | 1712 | addr[3] = i >> 8; |
| @@ -1379,6 +1788,10 @@ static int __init init_mac80211_hwsim(void) | |||
| 1379 | data->group = 1; | 1788 | data->group = 1; |
| 1380 | mutex_init(&data->mutex); | 1789 | mutex_init(&data->mutex); |
| 1381 | 1790 | ||
| 1791 | /* Enable frame retransmissions for lossy channels */ | ||
| 1792 | hw->max_rates = 4; | ||
| 1793 | hw->max_rate_tries = 11; | ||
| 1794 | |||
| 1382 | /* Work to be done prior to ieee80211_register_hw() */ | 1795 | /* Work to be done prior to ieee80211_register_hw() */ |
| 1383 | switch (regtest) { | 1796 | switch (regtest) { |
| 1384 | case HWSIM_REGTEST_DISABLED: | 1797 | case HWSIM_REGTEST_DISABLED: |
| @@ -1515,12 +1928,29 @@ static int __init init_mac80211_hwsim(void) | |||
| 1515 | if (hwsim_mon == NULL) | 1928 | if (hwsim_mon == NULL) |
| 1516 | goto failed; | 1929 | goto failed; |
| 1517 | 1930 | ||
| 1518 | err = register_netdev(hwsim_mon); | 1931 | rtnl_lock(); |
| 1932 | |||
| 1933 | err = dev_alloc_name(hwsim_mon, hwsim_mon->name); | ||
| 1519 | if (err < 0) | 1934 | if (err < 0) |
| 1520 | goto failed_mon; | 1935 | goto failed_mon; |
| 1521 | 1936 | ||
| 1937 | |||
| 1938 | err = register_netdevice(hwsim_mon); | ||
| 1939 | if (err < 0) | ||
| 1940 | goto failed_mon; | ||
| 1941 | |||
| 1942 | rtnl_unlock(); | ||
| 1943 | |||
| 1944 | err = hwsim_init_netlink(); | ||
| 1945 | if (err < 0) | ||
| 1946 | goto failed_nl; | ||
| 1947 | |||
| 1522 | return 0; | 1948 | return 0; |
| 1523 | 1949 | ||
| 1950 | failed_nl: | ||
| 1951 | printk(KERN_DEBUG "mac_80211_hwsim: failed initializing netlink\n"); | ||
| 1952 | return err; | ||
| 1953 | |||
| 1524 | failed_mon: | 1954 | failed_mon: |
| 1525 | rtnl_unlock(); | 1955 | rtnl_unlock(); |
| 1526 | free_netdev(hwsim_mon); | 1956 | free_netdev(hwsim_mon); |
| @@ -1541,6 +1971,8 @@ static void __exit exit_mac80211_hwsim(void) | |||
| 1541 | { | 1971 | { |
| 1542 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); | 1972 | printk(KERN_DEBUG "mac80211_hwsim: unregister radios\n"); |
| 1543 | 1973 | ||
| 1974 | hwsim_exit_netlink(); | ||
| 1975 | |||
| 1544 | mac80211_hwsim_free(); | 1976 | mac80211_hwsim_free(); |
| 1545 | unregister_netdev(hwsim_mon); | 1977 | unregister_netdev(hwsim_mon); |
| 1546 | } | 1978 | } |
diff --git a/drivers/net/wireless/mac80211_hwsim.h b/drivers/net/wireless/mac80211_hwsim.h new file mode 100644 index 000000000000..afaad5a443b6 --- /dev/null +++ b/drivers/net/wireless/mac80211_hwsim.h | |||
| @@ -0,0 +1,133 @@ | |||
| 1 | /* | ||
| 2 | * mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211 | ||
| 3 | * Copyright (c) 2008, Jouni Malinen <j@w1.fi> | ||
| 4 | * Copyright (c) 2011, Javier Lopez <jlopex@gmail.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #ifndef __MAC80211_HWSIM_H | ||
| 12 | #define __MAC80211_HWSIM_H | ||
| 13 | |||
| 14 | /** | ||
| 15 | * enum hwsim_tx_control_flags - flags to describe transmission info/status | ||
| 16 | * | ||
| 17 | * These flags are used to give the wmediumd extra information in order to | ||
| 18 | * modify its behavior for each frame | ||
| 19 | * | ||
| 20 | * @HWSIM_TX_CTL_REQ_TX_STATUS: require TX status callback for this frame. | ||
| 21 | * @HWSIM_TX_CTL_NO_ACK: tell the wmediumd not to wait for an ack | ||
| 22 | * @HWSIM_TX_STAT_ACK: Frame was acknowledged | ||
| 23 | * | ||
| 24 | */ | ||
| 25 | enum hwsim_tx_control_flags { | ||
| 26 | HWSIM_TX_CTL_REQ_TX_STATUS = BIT(0), | ||
| 27 | HWSIM_TX_CTL_NO_ACK = BIT(1), | ||
| 28 | HWSIM_TX_STAT_ACK = BIT(2), | ||
| 29 | }; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * DOC: Frame transmission/registration support | ||
| 33 | * | ||
| 34 | * Frame transmission and registration support exists to allow userspace | ||
| 35 | * entities such as wmediumd to receive and process all broadcasted | ||
| 36 | * frames from a mac80211_hwsim radio device. | ||
| 37 | * | ||
| 38 | * This allow user space applications to decide if the frame should be | ||
| 39 | * dropped or not and implement a wireless medium simulator at user space. | ||
| 40 | * | ||
| 41 | * Registration is done by sending a register message to the driver and | ||
| 42 | * will be automatically unregistered if the user application doesn't | ||
| 43 | * responds to sent frames. | ||
| 44 | * Once registered the user application has to take responsibility of | ||
| 45 | * broadcasting the frames to all listening mac80211_hwsim radio | ||
| 46 | * interfaces. | ||
| 47 | * | ||
| 48 | * For more technical details, see the corresponding command descriptions | ||
| 49 | * below. | ||
| 50 | */ | ||
| 51 | |||
| 52 | /** | ||
| 53 | * enum hwsim_commands - supported hwsim commands | ||
| 54 | * | ||
| 55 | * @HWSIM_CMD_UNSPEC: unspecified command to catch errors | ||
| 56 | * | ||
| 57 | * @HWSIM_CMD_REGISTER: request to register and received all broadcasted | ||
| 58 | * frames by any mac80211_hwsim radio device. | ||
| 59 | * @HWSIM_CMD_FRAME: send/receive a broadcasted frame from/to kernel/user | ||
| 60 | * space, uses: | ||
| 61 | * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_ADDR_RECEIVER, | ||
| 62 | * %HWSIM_ATTR_FRAME, %HWSIM_ATTR_FLAGS, %HWSIM_ATTR_RX_RATE, | ||
| 63 | * %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE | ||
| 64 | * @HWSIM_CMD_TX_INFO_FRAME: Transmission info report from user space to | ||
| 65 | * kernel, uses: | ||
| 66 | * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS, | ||
| 67 | * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE | ||
| 68 | * @__HWSIM_CMD_MAX: enum limit | ||
| 69 | */ | ||
| 70 | enum { | ||
| 71 | HWSIM_CMD_UNSPEC, | ||
| 72 | HWSIM_CMD_REGISTER, | ||
| 73 | HWSIM_CMD_FRAME, | ||
| 74 | HWSIM_CMD_TX_INFO_FRAME, | ||
| 75 | __HWSIM_CMD_MAX, | ||
| 76 | }; | ||
| 77 | #define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1) | ||
| 78 | |||
| 79 | /** | ||
| 80 | * enum hwsim_attrs - hwsim netlink attributes | ||
| 81 | * | ||
| 82 | * @HWSIM_ATTR_UNSPEC: unspecified attribute to catch errors | ||
| 83 | * | ||
| 84 | * @HWSIM_ATTR_ADDR_RECEIVER: MAC address of the radio device that | ||
| 85 | * the frame is broadcasted to | ||
| 86 | * @HWSIM_ATTR_ADDR_TRANSMITTER: MAC address of the radio device that | ||
| 87 | * the frame was broadcasted from | ||
| 88 | * @HWSIM_ATTR_FRAME: Data array | ||
| 89 | * @HWSIM_ATTR_FLAGS: mac80211 transmission flags, used to process | ||
| 90 | properly the frame at user space | ||
| 91 | * @HWSIM_ATTR_RX_RATE: estimated rx rate index for this frame at user | ||
| 92 | space | ||
| 93 | * @HWSIM_ATTR_SIGNAL: estimated RX signal for this frame at user | ||
| 94 | space | ||
| 95 | * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array | ||
| 96 | * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame | ||
| 97 | * @__HWSIM_ATTR_MAX: enum limit | ||
| 98 | */ | ||
| 99 | |||
| 100 | |||
| 101 | enum { | ||
| 102 | HWSIM_ATTR_UNSPEC, | ||
| 103 | HWSIM_ATTR_ADDR_RECEIVER, | ||
| 104 | HWSIM_ATTR_ADDR_TRANSMITTER, | ||
| 105 | HWSIM_ATTR_FRAME, | ||
| 106 | HWSIM_ATTR_FLAGS, | ||
| 107 | HWSIM_ATTR_RX_RATE, | ||
| 108 | HWSIM_ATTR_SIGNAL, | ||
| 109 | HWSIM_ATTR_TX_INFO, | ||
| 110 | HWSIM_ATTR_COOKIE, | ||
| 111 | __HWSIM_ATTR_MAX, | ||
| 112 | }; | ||
| 113 | #define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1) | ||
| 114 | |||
| 115 | /** | ||
| 116 | * struct hwsim_tx_rate - rate selection/status | ||
| 117 | * | ||
| 118 | * @idx: rate index to attempt to send with | ||
| 119 | * @count: number of tries in this rate before going to the next rate | ||
| 120 | * | ||
| 121 | * A value of -1 for @idx indicates an invalid rate and, if used | ||
| 122 | * in an array of retry rates, that no more rates should be tried. | ||
| 123 | * | ||
| 124 | * When used for transmit status reporting, the driver should | ||
| 125 | * always report the rate and number of retries used. | ||
| 126 | * | ||
| 127 | */ | ||
| 128 | struct hwsim_tx_rate { | ||
| 129 | s8 idx; | ||
| 130 | u8 count; | ||
| 131 | } __packed; | ||
| 132 | |||
| 133 | #endif /* __MAC80211_HWSIM_H */ | ||
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index f807447e4d99..1a453a605b3f 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c | |||
| @@ -164,12 +164,13 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 164 | struct mwifiex_tx_param tx_param; | 164 | struct mwifiex_tx_param tx_param; |
| 165 | struct txpd *ptx_pd = NULL; | 165 | struct txpd *ptx_pd = NULL; |
| 166 | 166 | ||
| 167 | if (skb_queue_empty(&pra_list->skb_head)) { | 167 | skb_src = skb_peek(&pra_list->skb_head); |
| 168 | if (!skb_src) { | ||
| 168 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 169 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
| 169 | ra_list_flags); | 170 | ra_list_flags); |
| 170 | return 0; | 171 | return 0; |
| 171 | } | 172 | } |
| 172 | skb_src = skb_peek(&pra_list->skb_head); | 173 | |
| 173 | tx_info_src = MWIFIEX_SKB_TXCB(skb_src); | 174 | tx_info_src = MWIFIEX_SKB_TXCB(skb_src); |
| 174 | skb_aggr = dev_alloc_skb(adapter->tx_buf_size); | 175 | skb_aggr = dev_alloc_skb(adapter->tx_buf_size); |
| 175 | if (!skb_aggr) { | 176 | if (!skb_aggr) { |
| @@ -184,17 +185,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 184 | tx_info_aggr->bss_index = tx_info_src->bss_index; | 185 | tx_info_aggr->bss_index = tx_info_src->bss_index; |
| 185 | skb_aggr->priority = skb_src->priority; | 186 | skb_aggr->priority = skb_src->priority; |
| 186 | 187 | ||
| 187 | while (skb_src && ((skb_headroom(skb_aggr) + skb_src->len | 188 | do { |
| 188 | + LLC_SNAP_LEN) | 189 | /* Check if AMSDU can accommodate this MSDU */ |
| 189 | <= adapter->tx_buf_size)) { | 190 | if (skb_tailroom(skb_aggr) < (skb_src->len + LLC_SNAP_LEN)) |
| 191 | break; | ||
| 190 | 192 | ||
| 191 | if (!skb_queue_empty(&pra_list->skb_head)) | 193 | skb_src = skb_dequeue(&pra_list->skb_head); |
| 192 | skb_src = skb_dequeue(&pra_list->skb_head); | ||
| 193 | else | ||
| 194 | skb_src = NULL; | ||
| 195 | 194 | ||
| 196 | if (skb_src) | 195 | pra_list->total_pkts_size -= skb_src->len; |
| 197 | pra_list->total_pkts_size -= skb_src->len; | 196 | pra_list->total_pkts--; |
| 198 | 197 | ||
| 199 | atomic_dec(&priv->wmm.tx_pkts_queued); | 198 | atomic_dec(&priv->wmm.tx_pkts_queued); |
| 200 | 199 | ||
| @@ -212,11 +211,15 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 212 | return -1; | 211 | return -1; |
| 213 | } | 212 | } |
| 214 | 213 | ||
| 215 | if (!skb_queue_empty(&pra_list->skb_head)) | 214 | if (skb_tailroom(skb_aggr) < pad) { |
| 216 | skb_src = skb_peek(&pra_list->skb_head); | 215 | pad = 0; |
| 217 | else | 216 | break; |
| 218 | skb_src = NULL; | 217 | } |
| 219 | } | 218 | skb_put(skb_aggr, pad); |
| 219 | |||
| 220 | skb_src = skb_peek(&pra_list->skb_head); | ||
| 221 | |||
| 222 | } while (skb_src); | ||
| 220 | 223 | ||
| 221 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); | 224 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, ra_list_flags); |
| 222 | 225 | ||
| @@ -230,11 +233,19 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 230 | 233 | ||
| 231 | skb_push(skb_aggr, headroom); | 234 | skb_push(skb_aggr, headroom); |
| 232 | 235 | ||
| 233 | tx_param.next_pkt_len = ((pra_list->total_pkts_size) ? | 236 | /* |
| 234 | (((pra_list->total_pkts_size) > | 237 | * Padding per MSDU will affect the length of next |
| 235 | adapter->tx_buf_size) ? adapter-> | 238 | * packet and hence the exact length of next packet |
| 236 | tx_buf_size : pra_list->total_pkts_size + | 239 | * is uncertain here. |
| 237 | LLC_SNAP_LEN + sizeof(struct txpd)) : 0); | 240 | * |
| 241 | * Also, aggregation of transmission buffer, while | ||
| 242 | * downloading the data to the card, wont gain much | ||
| 243 | * on the AMSDU packets as the AMSDU packets utilizes | ||
| 244 | * the transmission buffer space to the maximum | ||
| 245 | * (adapter->tx_buf_size). | ||
| 246 | */ | ||
| 247 | tx_param.next_pkt_len = 0; | ||
| 248 | |||
| 238 | ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, | 249 | ret = adapter->if_ops.host_to_card(adapter, MWIFIEX_TYPE_DATA, |
| 239 | skb_aggr->data, | 250 | skb_aggr->data, |
| 240 | skb_aggr->len, &tx_param); | 251 | skb_aggr->len, &tx_param); |
| @@ -258,6 +269,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, | |||
| 258 | skb_queue_tail(&pra_list->skb_head, skb_aggr); | 269 | skb_queue_tail(&pra_list->skb_head, skb_aggr); |
| 259 | 270 | ||
| 260 | pra_list->total_pkts_size += skb_aggr->len; | 271 | pra_list->total_pkts_size += skb_aggr->len; |
| 272 | pra_list->total_pkts++; | ||
| 261 | 273 | ||
| 262 | atomic_inc(&priv->wmm.tx_pkts_queued); | 274 | atomic_inc(&priv->wmm.tx_pkts_queued); |
| 263 | 275 | ||
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index f0582259c935..4f43443036f4 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
| @@ -35,8 +35,6 @@ static struct mwifiex_bss_attr mwifiex_bss_sta[] = { | |||
| 35 | 35 | ||
| 36 | static int drv_mode = DRV_MODE_STA; | 36 | static int drv_mode = DRV_MODE_STA; |
| 37 | 37 | ||
| 38 | static char fw_name[32] = DEFAULT_FW_NAME; | ||
| 39 | |||
| 40 | /* Supported drv_mode table */ | 38 | /* Supported drv_mode table */ |
| 41 | static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { | 39 | static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = { |
| 42 | { | 40 | { |
| @@ -384,20 +382,8 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter) | |||
| 384 | 382 | ||
| 385 | memset(&fw, 0, sizeof(struct mwifiex_fw_image)); | 383 | memset(&fw, 0, sizeof(struct mwifiex_fw_image)); |
| 386 | 384 | ||
| 387 | switch (adapter->revision_id) { | 385 | err = request_firmware(&adapter->firmware, adapter->fw_name, |
| 388 | case SD8787_W0: | 386 | adapter->dev); |
| 389 | case SD8787_W1: | ||
| 390 | strcpy(fw_name, SD8787_W1_FW_NAME); | ||
| 391 | break; | ||
| 392 | case SD8787_A0: | ||
| 393 | case SD8787_A1: | ||
| 394 | strcpy(fw_name, SD8787_AX_FW_NAME); | ||
| 395 | break; | ||
| 396 | default: | ||
| 397 | break; | ||
| 398 | } | ||
| 399 | |||
| 400 | err = request_firmware(&adapter->firmware, fw_name, adapter->dev); | ||
| 401 | if (err < 0) { | 387 | if (err < 0) { |
| 402 | dev_err(adapter->dev, "request_firmware() returned" | 388 | dev_err(adapter->dev, "request_firmware() returned" |
| 403 | " error code %#x\n", err); | 389 | " error code %#x\n", err); |
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 8316b3cd92cd..57b183af72d7 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
| @@ -48,15 +48,6 @@ enum { | |||
| 48 | 48 | ||
| 49 | #define DRV_MODE_STA 0x1 | 49 | #define DRV_MODE_STA 0x1 |
| 50 | 50 | ||
| 51 | #define SD8787_W0 0x30 | ||
| 52 | #define SD8787_W1 0x31 | ||
| 53 | #define SD8787_A0 0x40 | ||
| 54 | #define SD8787_A1 0x41 | ||
| 55 | |||
| 56 | #define DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" | ||
| 57 | #define SD8787_W1_FW_NAME "mrvl/sd8787_uapsta_w1.bin" | ||
| 58 | #define SD8787_AX_FW_NAME "mrvl/sd8787_uapsta.bin" | ||
| 59 | |||
| 60 | struct mwifiex_drv_mode { | 51 | struct mwifiex_drv_mode { |
| 61 | u16 drv_mode; | 52 | u16 drv_mode; |
| 62 | u16 intf_num; | 53 | u16 intf_num; |
| @@ -190,6 +181,7 @@ struct mwifiex_ra_list_tbl { | |||
| 190 | struct sk_buff_head skb_head; | 181 | struct sk_buff_head skb_head; |
| 191 | u8 ra[ETH_ALEN]; | 182 | u8 ra[ETH_ALEN]; |
| 192 | u32 total_pkts_size; | 183 | u32 total_pkts_size; |
| 184 | u32 total_pkts; | ||
| 193 | u32 is_11n_enabled; | 185 | u32 is_11n_enabled; |
| 194 | }; | 186 | }; |
| 195 | 187 | ||
| @@ -576,10 +568,10 @@ struct mwifiex_adapter { | |||
| 576 | u8 priv_num; | 568 | u8 priv_num; |
| 577 | struct mwifiex_drv_mode *drv_mode; | 569 | struct mwifiex_drv_mode *drv_mode; |
| 578 | const struct firmware *firmware; | 570 | const struct firmware *firmware; |
| 571 | char fw_name[32]; | ||
| 579 | struct device *dev; | 572 | struct device *dev; |
| 580 | bool surprise_removed; | 573 | bool surprise_removed; |
| 581 | u32 fw_release_number; | 574 | u32 fw_release_number; |
| 582 | u32 revision_id; | ||
| 583 | u16 init_wait_q_woken; | 575 | u16 init_wait_q_woken; |
| 584 | wait_queue_head_t init_wait_q; | 576 | wait_queue_head_t init_wait_q; |
| 585 | void *card; | 577 | void *card; |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d425dbd91d19..4327b6d099c8 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
| @@ -1531,6 +1531,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) | |||
| 1531 | sdio_set_drvdata(func, card); | 1531 | sdio_set_drvdata(func, card); |
| 1532 | 1532 | ||
| 1533 | adapter->dev = &func->dev; | 1533 | adapter->dev = &func->dev; |
| 1534 | strcpy(adapter->fw_name, SD8787_DEFAULT_FW_NAME); | ||
| 1534 | 1535 | ||
| 1535 | return 0; | 1536 | return 0; |
| 1536 | 1537 | ||
| @@ -1552,7 +1553,6 @@ disable_func: | |||
| 1552 | * the first interrupt got from bootloader | 1553 | * the first interrupt got from bootloader |
| 1553 | * - Disable host interrupt mask register | 1554 | * - Disable host interrupt mask register |
| 1554 | * - Get SDIO port | 1555 | * - Get SDIO port |
| 1555 | * - Get revision ID | ||
| 1556 | * - Initialize SDIO variables in card | 1556 | * - Initialize SDIO variables in card |
| 1557 | * - Allocate MP registers | 1557 | * - Allocate MP registers |
| 1558 | * - Allocate MPA Tx and Rx buffers | 1558 | * - Allocate MPA Tx and Rx buffers |
| @@ -1576,10 +1576,6 @@ static int mwifiex_init_sdio(struct mwifiex_adapter *adapter) | |||
| 1576 | /* Get SDIO ioport */ | 1576 | /* Get SDIO ioport */ |
| 1577 | mwifiex_init_sdio_ioport(adapter); | 1577 | mwifiex_init_sdio_ioport(adapter); |
| 1578 | 1578 | ||
| 1579 | /* Get revision ID */ | ||
| 1580 | #define REV_ID_REG 0x5c | ||
| 1581 | mwifiex_read_reg(adapter, REV_ID_REG, &adapter->revision_id); | ||
| 1582 | |||
| 1583 | /* Initialize SDIO variables in card */ | 1579 | /* Initialize SDIO variables in card */ |
| 1584 | card->mp_rd_bitmap = 0; | 1580 | card->mp_rd_bitmap = 0; |
| 1585 | card->mp_wr_bitmap = 0; | 1581 | card->mp_wr_bitmap = 0; |
| @@ -1751,4 +1747,4 @@ MODULE_AUTHOR("Marvell International Ltd."); | |||
| 1751 | MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); | 1747 | MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); |
| 1752 | MODULE_VERSION(SDIO_VERSION); | 1748 | MODULE_VERSION(SDIO_VERSION); |
| 1753 | MODULE_LICENSE("GPL v2"); | 1749 | MODULE_LICENSE("GPL v2"); |
| 1754 | MODULE_FIRMWARE("sd8787.bin"); | 1750 | MODULE_FIRMWARE("mrvl/sd8787_uapsta.bin"); |
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h index 4e97e90aa399..c925376fcaae 100644 --- a/drivers/net/wireless/mwifiex/sdio.h +++ b/drivers/net/wireless/mwifiex/sdio.h | |||
| @@ -28,6 +28,8 @@ | |||
| 28 | 28 | ||
| 29 | #include "main.h" | 29 | #include "main.h" |
| 30 | 30 | ||
| 31 | #define SD8787_DEFAULT_FW_NAME "mrvl/sd8787_uapsta.bin" | ||
| 32 | |||
| 31 | #define BLOCK_MODE 1 | 33 | #define BLOCK_MODE 1 |
| 32 | #define BYTE_MODE 0 | 34 | #define BYTE_MODE 0 |
| 33 | 35 | ||
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 91634daec306..67b2d0b78c71 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c | |||
| @@ -121,6 +121,7 @@ mwifiex_wmm_allocate_ralist_node(struct mwifiex_adapter *adapter, u8 *ra) | |||
| 121 | memcpy(ra_list->ra, ra, ETH_ALEN); | 121 | memcpy(ra_list->ra, ra, ETH_ALEN); |
| 122 | 122 | ||
| 123 | ra_list->total_pkts_size = 0; | 123 | ra_list->total_pkts_size = 0; |
| 124 | ra_list->total_pkts = 0; | ||
| 124 | 125 | ||
| 125 | dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); | 126 | dev_dbg(adapter->dev, "info: allocated ra_list %p\n", ra_list); |
| 126 | 127 | ||
| @@ -645,6 +646,7 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, | |||
| 645 | skb_queue_tail(&ra_list->skb_head, skb); | 646 | skb_queue_tail(&ra_list->skb_head, skb); |
| 646 | 647 | ||
| 647 | ra_list->total_pkts_size += skb->len; | 648 | ra_list->total_pkts_size += skb->len; |
| 649 | ra_list->total_pkts++; | ||
| 648 | 650 | ||
| 649 | atomic_inc(&priv->wmm.tx_pkts_queued); | 651 | atomic_inc(&priv->wmm.tx_pkts_queued); |
| 650 | 652 | ||
| @@ -971,28 +973,6 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter, | |||
| 971 | } | 973 | } |
| 972 | 974 | ||
| 973 | /* | 975 | /* |
| 974 | * This function gets the number of packets in the Tx queue of a | ||
| 975 | * particular RA list. | ||
| 976 | */ | ||
| 977 | static int | ||
| 978 | mwifiex_num_pkts_in_txq(struct mwifiex_private *priv, | ||
| 979 | struct mwifiex_ra_list_tbl *ptr, int max_buf_size) | ||
| 980 | { | ||
| 981 | int count = 0, total_size = 0; | ||
| 982 | struct sk_buff *skb, *tmp; | ||
| 983 | |||
| 984 | skb_queue_walk_safe(&ptr->skb_head, skb, tmp) { | ||
| 985 | total_size += skb->len; | ||
| 986 | if (total_size < max_buf_size) | ||
| 987 | ++count; | ||
| 988 | else | ||
| 989 | break; | ||
| 990 | } | ||
| 991 | |||
| 992 | return count; | ||
| 993 | } | ||
| 994 | |||
| 995 | /* | ||
| 996 | * This function sends a single packet to firmware for transmission. | 976 | * This function sends a single packet to firmware for transmission. |
| 997 | */ | 977 | */ |
| 998 | static void | 978 | static void |
| @@ -1019,6 +999,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
| 1019 | dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); | 999 | dev_dbg(adapter->dev, "data: dequeuing the packet %p %p\n", ptr, skb); |
| 1020 | 1000 | ||
| 1021 | ptr->total_pkts_size -= skb->len; | 1001 | ptr->total_pkts_size -= skb->len; |
| 1002 | ptr->total_pkts--; | ||
| 1022 | 1003 | ||
| 1023 | if (!skb_queue_empty(&ptr->skb_head)) | 1004 | if (!skb_queue_empty(&ptr->skb_head)) |
| 1024 | skb_next = skb_peek(&ptr->skb_head); | 1005 | skb_next = skb_peek(&ptr->skb_head); |
| @@ -1044,6 +1025,7 @@ mwifiex_send_single_packet(struct mwifiex_private *priv, | |||
| 1044 | skb_queue_tail(&ptr->skb_head, skb); | 1025 | skb_queue_tail(&ptr->skb_head, skb); |
| 1045 | 1026 | ||
| 1046 | ptr->total_pkts_size += skb->len; | 1027 | ptr->total_pkts_size += skb->len; |
| 1028 | ptr->total_pkts++; | ||
| 1047 | tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; | 1029 | tx_info->flags |= MWIFIEX_BUF_FLAG_REQUEUED_PKT; |
| 1048 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, | 1030 | spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, |
| 1049 | ra_list_flags); | 1031 | ra_list_flags); |
| @@ -1231,9 +1213,9 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter) | |||
| 1231 | } | 1213 | } |
| 1232 | /* Minimum number of AMSDU */ | 1214 | /* Minimum number of AMSDU */ |
| 1233 | #define MIN_NUM_AMSDU 2 | 1215 | #define MIN_NUM_AMSDU 2 |
| 1216 | |||
| 1234 | if (mwifiex_is_amsdu_allowed(priv, tid) && | 1217 | if (mwifiex_is_amsdu_allowed(priv, tid) && |
| 1235 | (mwifiex_num_pkts_in_txq(priv, ptr, adapter->tx_buf_size) >= | 1218 | (ptr->total_pkts >= MIN_NUM_AMSDU)) |
| 1236 | MIN_NUM_AMSDU)) | ||
| 1237 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, | 1219 | mwifiex_11n_aggregate_pkt(priv, ptr, INTF_HEADER_LEN, |
| 1238 | ptr_index, flags); | 1220 | ptr_index, flags); |
| 1239 | /* ra_list_spinlock has been freed in | 1221 | /* ra_list_spinlock has been freed in |
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index b2f8b8fd4d2d..a0a7854facc0 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig | |||
| @@ -83,14 +83,12 @@ config RT2800PCI_RT33XX | |||
| 83 | config RT2800PCI_RT35XX | 83 | config RT2800PCI_RT35XX |
| 84 | bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" | 84 | bool "rt2800pci - Include support for rt35xx devices (EXPERIMENTAL)" |
| 85 | depends on EXPERIMENTAL | 85 | depends on EXPERIMENTAL |
| 86 | default n | 86 | default y |
| 87 | ---help--- | 87 | ---help--- |
| 88 | This adds support for rt35xx wireless chipset family to the | 88 | This adds support for rt35xx wireless chipset family to the |
| 89 | rt2800pci driver. | 89 | rt2800pci driver. |
| 90 | Supported chips: RT3060, RT3062, RT3562, RT3592 | 90 | Supported chips: RT3060, RT3062, RT3562, RT3592 |
| 91 | 91 | ||
| 92 | Support for these devices is non-functional at the moment and is | ||
| 93 | intended for testers and developers. | ||
| 94 | 92 | ||
| 95 | config RT2800PCI_RT53XX | 93 | config RT2800PCI_RT53XX |
| 96 | bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)" | 94 | bool "rt2800pci - Include support for rt53xx devices (EXPERIMENTAL)" |
| @@ -154,15 +152,12 @@ config RT2800USB_RT33XX | |||
| 154 | config RT2800USB_RT35XX | 152 | config RT2800USB_RT35XX |
| 155 | bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" | 153 | bool "rt2800usb - Include support for rt35xx devices (EXPERIMENTAL)" |
| 156 | depends on EXPERIMENTAL | 154 | depends on EXPERIMENTAL |
| 157 | default n | 155 | default y |
| 158 | ---help--- | 156 | ---help--- |
| 159 | This adds support for rt35xx wireless chipset family to the | 157 | This adds support for rt35xx wireless chipset family to the |
| 160 | rt2800usb driver. | 158 | rt2800usb driver. |
| 161 | Supported chips: RT3572 | 159 | Supported chips: RT3572 |
| 162 | 160 | ||
| 163 | Support for these devices is non-functional at the moment and is | ||
| 164 | intended for testers and developers. | ||
| 165 | |||
| 166 | config RT2800USB_RT53XX | 161 | config RT2800USB_RT53XX |
| 167 | bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" | 162 | bool "rt2800usb - Include support for rt53xx devices (EXPERIMENTAL)" |
| 168 | depends on EXPERIMENTAL | 163 | depends on EXPERIMENTAL |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index f67bc9b31b28..c69a7d71f4ca 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
| @@ -1740,6 +1740,7 @@ struct mac_iveiv_entry { | |||
| 1740 | /* | 1740 | /* |
| 1741 | * BBP 3: RX Antenna | 1741 | * BBP 3: RX Antenna |
| 1742 | */ | 1742 | */ |
| 1743 | #define BBP3_RX_ADC FIELD8(0x03) | ||
| 1743 | #define BBP3_RX_ANTENNA FIELD8(0x18) | 1744 | #define BBP3_RX_ANTENNA FIELD8(0x18) |
| 1744 | #define BBP3_HT40_MINUS FIELD8(0x20) | 1745 | #define BBP3_HT40_MINUS FIELD8(0x20) |
| 1745 | 1746 | ||
| @@ -1783,6 +1784,8 @@ struct mac_iveiv_entry { | |||
| 1783 | #define RFCSR1_TX0_PD FIELD8(0x08) | 1784 | #define RFCSR1_TX0_PD FIELD8(0x08) |
| 1784 | #define RFCSR1_RX1_PD FIELD8(0x10) | 1785 | #define RFCSR1_RX1_PD FIELD8(0x10) |
| 1785 | #define RFCSR1_TX1_PD FIELD8(0x20) | 1786 | #define RFCSR1_TX1_PD FIELD8(0x20) |
| 1787 | #define RFCSR1_RX2_PD FIELD8(0x40) | ||
| 1788 | #define RFCSR1_TX2_PD FIELD8(0x80) | ||
| 1786 | 1789 | ||
| 1787 | /* | 1790 | /* |
| 1788 | * RFCSR 2: | 1791 | * RFCSR 2: |
| @@ -1790,15 +1793,25 @@ struct mac_iveiv_entry { | |||
| 1790 | #define RFCSR2_RESCAL_EN FIELD8(0x80) | 1793 | #define RFCSR2_RESCAL_EN FIELD8(0x80) |
| 1791 | 1794 | ||
| 1792 | /* | 1795 | /* |
| 1796 | * FRCSR 5: | ||
| 1797 | */ | ||
| 1798 | #define RFCSR5_R1 FIELD8(0x0c) | ||
| 1799 | |||
| 1800 | /* | ||
| 1793 | * RFCSR 6: | 1801 | * RFCSR 6: |
| 1794 | */ | 1802 | */ |
| 1795 | #define RFCSR6_R1 FIELD8(0x03) | 1803 | #define RFCSR6_R1 FIELD8(0x03) |
| 1796 | #define RFCSR6_R2 FIELD8(0x40) | 1804 | #define RFCSR6_R2 FIELD8(0x40) |
| 1805 | #define RFCSR6_TXDIV FIELD8(0x0c) | ||
| 1797 | 1806 | ||
| 1798 | /* | 1807 | /* |
| 1799 | * RFCSR 7: | 1808 | * RFCSR 7: |
| 1800 | */ | 1809 | */ |
| 1801 | #define RFCSR7_RF_TUNING FIELD8(0x01) | 1810 | #define RFCSR7_RF_TUNING FIELD8(0x01) |
| 1811 | #define RFCSR7_R02 FIELD8(0x07) | ||
| 1812 | #define RFCSR7_R3 FIELD8(0x08) | ||
| 1813 | #define RFCSR7_R45 FIELD8(0x30) | ||
| 1814 | #define RFCSR7_R67 FIELD8(0xc0) | ||
| 1802 | 1815 | ||
| 1803 | /* | 1816 | /* |
| 1804 | * RFCSR 11: | 1817 | * RFCSR 11: |
| @@ -1809,11 +1822,13 @@ struct mac_iveiv_entry { | |||
| 1809 | * RFCSR 12: | 1822 | * RFCSR 12: |
| 1810 | */ | 1823 | */ |
| 1811 | #define RFCSR12_TX_POWER FIELD8(0x1f) | 1824 | #define RFCSR12_TX_POWER FIELD8(0x1f) |
| 1825 | #define RFCSR12_DR0 FIELD8(0xe0) | ||
| 1812 | 1826 | ||
| 1813 | /* | 1827 | /* |
| 1814 | * RFCSR 13: | 1828 | * RFCSR 13: |
| 1815 | */ | 1829 | */ |
| 1816 | #define RFCSR13_TX_POWER FIELD8(0x1f) | 1830 | #define RFCSR13_TX_POWER FIELD8(0x1f) |
| 1831 | #define RFCSR13_DR0 FIELD8(0xe0) | ||
| 1817 | 1832 | ||
| 1818 | /* | 1833 | /* |
| 1819 | * RFCSR 15: | 1834 | * RFCSR 15: |
| @@ -2256,6 +2271,7 @@ struct mac_iveiv_entry { | |||
| 2256 | #define MCU_ANT_SELECT 0X73 | 2271 | #define MCU_ANT_SELECT 0X73 |
| 2257 | #define MCU_BBP_SIGNAL 0x80 | 2272 | #define MCU_BBP_SIGNAL 0x80 |
| 2258 | #define MCU_POWER_SAVE 0x83 | 2273 | #define MCU_POWER_SAVE 0x83 |
| 2274 | #define MCU_BAND_SELECT 0x91 | ||
| 2259 | 2275 | ||
| 2260 | /* | 2276 | /* |
| 2261 | * MCU mailbox tokens | 2277 | * MCU mailbox tokens |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 8f92dfcb08df..84ab7d1acb6a 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
| @@ -401,7 +401,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
| 401 | return -EBUSY; | 401 | return -EBUSY; |
| 402 | 402 | ||
| 403 | if (rt2x00_is_pci(rt2x00dev)) { | 403 | if (rt2x00_is_pci(rt2x00dev)) { |
| 404 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 404 | if (rt2x00_rt(rt2x00dev, RT3572) || |
| 405 | rt2x00_rt(rt2x00dev, RT5390)) { | ||
| 405 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); | 406 | rt2800_register_read(rt2x00dev, AUX_CTRL, ®); |
| 406 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 407 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
| 407 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 408 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
| @@ -600,49 +601,6 @@ void rt2800_process_rxwi(struct queue_entry *entry, | |||
| 600 | } | 601 | } |
| 601 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 602 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
| 602 | 603 | ||
| 603 | static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
| 604 | { | ||
| 605 | __le32 *txwi; | ||
| 606 | u32 word; | ||
| 607 | int wcid, ack, pid; | ||
| 608 | int tx_wcid, tx_ack, tx_pid; | ||
| 609 | |||
| 610 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
| 611 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
| 612 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
| 613 | |||
| 614 | /* | ||
| 615 | * This frames has returned with an IO error, | ||
| 616 | * so the status report is not intended for this | ||
| 617 | * frame. | ||
| 618 | */ | ||
| 619 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | ||
| 620 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
| 621 | return false; | ||
| 622 | } | ||
| 623 | |||
| 624 | /* | ||
| 625 | * Validate if this TX status report is intended for | ||
| 626 | * this entry by comparing the WCID/ACK/PID fields. | ||
| 627 | */ | ||
| 628 | txwi = rt2800_drv_get_txwi(entry); | ||
| 629 | |||
| 630 | rt2x00_desc_read(txwi, 1, &word); | ||
| 631 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
| 632 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
| 633 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
| 634 | |||
| 635 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | ||
| 636 | WARNING(entry->queue->rt2x00dev, | ||
| 637 | "TX status report missed for queue %d entry %d\n", | ||
| 638 | entry->queue->qid, entry->entry_idx); | ||
| 639 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
| 640 | return false; | ||
| 641 | } | ||
| 642 | |||
| 643 | return true; | ||
| 644 | } | ||
| 645 | |||
| 646 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status) | 604 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status) |
| 647 | { | 605 | { |
| 648 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 606 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| @@ -725,45 +683,6 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status) | |||
| 725 | } | 683 | } |
| 726 | EXPORT_SYMBOL_GPL(rt2800_txdone_entry); | 684 | EXPORT_SYMBOL_GPL(rt2800_txdone_entry); |
| 727 | 685 | ||
| 728 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev) | ||
| 729 | { | ||
| 730 | struct data_queue *queue; | ||
| 731 | struct queue_entry *entry; | ||
| 732 | u32 reg; | ||
| 733 | u8 qid; | ||
| 734 | |||
| 735 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { | ||
| 736 | |||
| 737 | /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus | ||
| 738 | * qid is guaranteed to be one of the TX QIDs | ||
| 739 | */ | ||
| 740 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); | ||
| 741 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | ||
| 742 | if (unlikely(!queue)) { | ||
| 743 | WARNING(rt2x00dev, "Got TX status for an unavailable " | ||
| 744 | "queue %u, dropping\n", qid); | ||
| 745 | continue; | ||
| 746 | } | ||
| 747 | |||
| 748 | /* | ||
| 749 | * Inside each queue, we process each entry in a chronological | ||
| 750 | * order. We first check that the queue is not empty. | ||
| 751 | */ | ||
| 752 | entry = NULL; | ||
| 753 | while (!rt2x00queue_empty(queue)) { | ||
| 754 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
| 755 | if (rt2800_txdone_entry_check(entry, reg)) | ||
| 756 | break; | ||
| 757 | } | ||
| 758 | |||
| 759 | if (!entry || rt2x00queue_empty(queue)) | ||
| 760 | break; | ||
| 761 | |||
| 762 | rt2800_txdone_entry(entry, reg); | ||
| 763 | } | ||
| 764 | } | ||
| 765 | EXPORT_SYMBOL_GPL(rt2800_txdone); | ||
| 766 | |||
| 767 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | 686 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) |
| 768 | { | 687 | { |
| 769 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 688 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
| @@ -1433,6 +1352,40 @@ void rt2800_config_erp(struct rt2x00_dev *rt2x00dev, struct rt2x00lib_erp *erp, | |||
| 1433 | } | 1352 | } |
| 1434 | EXPORT_SYMBOL_GPL(rt2800_config_erp); | 1353 | EXPORT_SYMBOL_GPL(rt2800_config_erp); |
| 1435 | 1354 | ||
| 1355 | static void rt2800_config_3572bt_ant(struct rt2x00_dev *rt2x00dev) | ||
| 1356 | { | ||
| 1357 | u32 reg; | ||
| 1358 | u16 eeprom; | ||
| 1359 | u8 led_ctrl, led_g_mode, led_r_mode; | ||
| 1360 | |||
| 1361 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | ||
| 1362 | if (rt2x00dev->curr_band == IEEE80211_BAND_5GHZ) { | ||
| 1363 | rt2x00_set_field32(®, GPIO_SWITCH_0, 1); | ||
| 1364 | rt2x00_set_field32(®, GPIO_SWITCH_1, 1); | ||
| 1365 | } else { | ||
| 1366 | rt2x00_set_field32(®, GPIO_SWITCH_0, 0); | ||
| 1367 | rt2x00_set_field32(®, GPIO_SWITCH_1, 0); | ||
| 1368 | } | ||
| 1369 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | ||
| 1370 | |||
| 1371 | rt2800_register_read(rt2x00dev, LED_CFG, ®); | ||
| 1372 | led_g_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 3 : 0; | ||
| 1373 | led_r_mode = rt2x00_get_field32(reg, LED_CFG_LED_POLAR) ? 0 : 3; | ||
| 1374 | if (led_g_mode != rt2x00_get_field32(reg, LED_CFG_G_LED_MODE) || | ||
| 1375 | led_r_mode != rt2x00_get_field32(reg, LED_CFG_R_LED_MODE)) { | ||
| 1376 | rt2x00_eeprom_read(rt2x00dev, EEPROM_FREQ, &eeprom); | ||
| 1377 | led_ctrl = rt2x00_get_field16(eeprom, EEPROM_FREQ_LED_MODE); | ||
| 1378 | if (led_ctrl == 0 || led_ctrl > 0x40) { | ||
| 1379 | rt2x00_set_field32(®, LED_CFG_G_LED_MODE, led_g_mode); | ||
| 1380 | rt2x00_set_field32(®, LED_CFG_R_LED_MODE, led_r_mode); | ||
| 1381 | rt2800_register_write(rt2x00dev, LED_CFG, reg); | ||
| 1382 | } else { | ||
| 1383 | rt2800_mcu_request(rt2x00dev, MCU_BAND_SELECT, 0xff, | ||
| 1384 | (led_g_mode << 2) | led_r_mode, 1); | ||
| 1385 | } | ||
| 1386 | } | ||
| 1387 | } | ||
| 1388 | |||
| 1436 | static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, | 1389 | static void rt2800_set_ant_diversity(struct rt2x00_dev *rt2x00dev, |
| 1437 | enum antenna ant) | 1390 | enum antenna ant) |
| 1438 | { | 1391 | { |
| @@ -1463,6 +1416,10 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
| 1463 | rt2800_bbp_read(rt2x00dev, 1, &r1); | 1416 | rt2800_bbp_read(rt2x00dev, 1, &r1); |
| 1464 | rt2800_bbp_read(rt2x00dev, 3, &r3); | 1417 | rt2800_bbp_read(rt2x00dev, 3, &r3); |
| 1465 | 1418 | ||
| 1419 | if (rt2x00_rt(rt2x00dev, RT3572) && | ||
| 1420 | test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) | ||
| 1421 | rt2800_config_3572bt_ant(rt2x00dev); | ||
| 1422 | |||
| 1466 | /* | 1423 | /* |
| 1467 | * Configure the TX antenna. | 1424 | * Configure the TX antenna. |
| 1468 | */ | 1425 | */ |
| @@ -1471,7 +1428,11 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
| 1471 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); | 1428 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); |
| 1472 | break; | 1429 | break; |
| 1473 | case 2: | 1430 | case 2: |
| 1474 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); | 1431 | if (rt2x00_rt(rt2x00dev, RT3572) && |
| 1432 | test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) | ||
| 1433 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 1); | ||
| 1434 | else | ||
| 1435 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 2); | ||
| 1475 | break; | 1436 | break; |
| 1476 | case 3: | 1437 | case 3: |
| 1477 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); | 1438 | rt2x00_set_field8(&r1, BBP1_TX_ANTENNA, 0); |
| @@ -1496,7 +1457,15 @@ void rt2800_config_ant(struct rt2x00_dev *rt2x00dev, struct antenna_setup *ant) | |||
| 1496 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); | 1457 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 0); |
| 1497 | break; | 1458 | break; |
| 1498 | case 2: | 1459 | case 2: |
| 1499 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1); | 1460 | if (rt2x00_rt(rt2x00dev, RT3572) && |
| 1461 | test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { | ||
| 1462 | rt2x00_set_field8(&r3, BBP3_RX_ADC, 1); | ||
| 1463 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, | ||
| 1464 | rt2x00dev->curr_band == IEEE80211_BAND_5GHZ); | ||
| 1465 | rt2800_set_ant_diversity(rt2x00dev, ANTENNA_B); | ||
| 1466 | } else { | ||
| 1467 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 1); | ||
| 1468 | } | ||
| 1500 | break; | 1469 | break; |
| 1501 | case 3: | 1470 | case 3: |
| 1502 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2); | 1471 | rt2x00_set_field8(&r3, BBP3_RX_ANTENNA, 2); |
| @@ -1630,6 +1599,161 @@ static void rt2800_config_channel_rf3xxx(struct rt2x00_dev *rt2x00dev, | |||
| 1630 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); | 1599 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); |
| 1631 | } | 1600 | } |
| 1632 | 1601 | ||
| 1602 | static void rt2800_config_channel_rf3052(struct rt2x00_dev *rt2x00dev, | ||
| 1603 | struct ieee80211_conf *conf, | ||
| 1604 | struct rf_channel *rf, | ||
| 1605 | struct channel_info *info) | ||
| 1606 | { | ||
| 1607 | u8 rfcsr; | ||
| 1608 | u32 reg; | ||
| 1609 | |||
| 1610 | if (rf->channel <= 14) { | ||
| 1611 | rt2800_bbp_write(rt2x00dev, 25, 0x15); | ||
| 1612 | rt2800_bbp_write(rt2x00dev, 26, 0x85); | ||
| 1613 | } else { | ||
| 1614 | rt2800_bbp_write(rt2x00dev, 25, 0x09); | ||
| 1615 | rt2800_bbp_write(rt2x00dev, 26, 0xff); | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | rt2800_rfcsr_write(rt2x00dev, 2, rf->rf1); | ||
| 1619 | rt2800_rfcsr_write(rt2x00dev, 3, rf->rf3); | ||
| 1620 | |||
| 1621 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 1622 | rt2x00_set_field8(&rfcsr, RFCSR6_R1, rf->rf2); | ||
| 1623 | if (rf->channel <= 14) | ||
| 1624 | rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 2); | ||
| 1625 | else | ||
| 1626 | rt2x00_set_field8(&rfcsr, RFCSR6_TXDIV, 1); | ||
| 1627 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 1628 | |||
| 1629 | rt2800_rfcsr_read(rt2x00dev, 5, &rfcsr); | ||
| 1630 | if (rf->channel <= 14) | ||
| 1631 | rt2x00_set_field8(&rfcsr, RFCSR5_R1, 1); | ||
| 1632 | else | ||
| 1633 | rt2x00_set_field8(&rfcsr, RFCSR5_R1, 2); | ||
| 1634 | rt2800_rfcsr_write(rt2x00dev, 5, rfcsr); | ||
| 1635 | |||
| 1636 | rt2800_rfcsr_read(rt2x00dev, 12, &rfcsr); | ||
| 1637 | if (rf->channel <= 14) { | ||
| 1638 | rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 3); | ||
| 1639 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | ||
| 1640 | (info->default_power1 & 0x3) | | ||
| 1641 | ((info->default_power1 & 0xC) << 1)); | ||
| 1642 | } else { | ||
| 1643 | rt2x00_set_field8(&rfcsr, RFCSR12_DR0, 7); | ||
| 1644 | rt2x00_set_field8(&rfcsr, RFCSR12_TX_POWER, | ||
| 1645 | (info->default_power1 & 0x3) | | ||
| 1646 | ((info->default_power1 & 0xC) << 1)); | ||
| 1647 | } | ||
| 1648 | rt2800_rfcsr_write(rt2x00dev, 12, rfcsr); | ||
| 1649 | |||
| 1650 | rt2800_rfcsr_read(rt2x00dev, 13, &rfcsr); | ||
| 1651 | if (rf->channel <= 14) { | ||
| 1652 | rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 3); | ||
| 1653 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | ||
| 1654 | (info->default_power2 & 0x3) | | ||
| 1655 | ((info->default_power2 & 0xC) << 1)); | ||
| 1656 | } else { | ||
| 1657 | rt2x00_set_field8(&rfcsr, RFCSR13_DR0, 7); | ||
| 1658 | rt2x00_set_field8(&rfcsr, RFCSR13_TX_POWER, | ||
| 1659 | (info->default_power2 & 0x3) | | ||
| 1660 | ((info->default_power2 & 0xC) << 1)); | ||
| 1661 | } | ||
| 1662 | rt2800_rfcsr_write(rt2x00dev, 13, rfcsr); | ||
| 1663 | |||
| 1664 | rt2800_rfcsr_read(rt2x00dev, 1, &rfcsr); | ||
| 1665 | rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); | ||
| 1666 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); | ||
| 1667 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); | ||
| 1668 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); | ||
| 1669 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); | ||
| 1670 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) { | ||
| 1671 | if (rf->channel <= 14) { | ||
| 1672 | rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); | ||
| 1673 | rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); | ||
| 1674 | } | ||
| 1675 | rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); | ||
| 1676 | rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); | ||
| 1677 | } else { | ||
| 1678 | switch (rt2x00dev->default_ant.tx_chain_num) { | ||
| 1679 | case 1: | ||
| 1680 | rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); | ||
| 1681 | case 2: | ||
| 1682 | rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); | ||
| 1683 | break; | ||
| 1684 | } | ||
| 1685 | |||
| 1686 | switch (rt2x00dev->default_ant.rx_chain_num) { | ||
| 1687 | case 1: | ||
| 1688 | rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); | ||
| 1689 | case 2: | ||
| 1690 | rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); | ||
| 1691 | break; | ||
| 1692 | } | ||
| 1693 | } | ||
| 1694 | rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); | ||
| 1695 | |||
| 1696 | rt2800_rfcsr_read(rt2x00dev, 23, &rfcsr); | ||
| 1697 | rt2x00_set_field8(&rfcsr, RFCSR23_FREQ_OFFSET, rt2x00dev->freq_offset); | ||
| 1698 | rt2800_rfcsr_write(rt2x00dev, 23, rfcsr); | ||
| 1699 | |||
| 1700 | rt2800_rfcsr_write(rt2x00dev, 24, | ||
| 1701 | rt2x00dev->calibration[conf_is_ht40(conf)]); | ||
| 1702 | rt2800_rfcsr_write(rt2x00dev, 31, | ||
| 1703 | rt2x00dev->calibration[conf_is_ht40(conf)]); | ||
| 1704 | |||
| 1705 | if (rf->channel <= 14) { | ||
| 1706 | rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); | ||
| 1707 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); | ||
| 1708 | rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); | ||
| 1709 | rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); | ||
| 1710 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
| 1711 | rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); | ||
| 1712 | rt2800_rfcsr_write(rt2x00dev, 17, 0x23); | ||
| 1713 | rt2800_rfcsr_write(rt2x00dev, 19, 0x93); | ||
| 1714 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); | ||
| 1715 | rt2800_rfcsr_write(rt2x00dev, 25, 0x15); | ||
| 1716 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
| 1717 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
| 1718 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); | ||
| 1719 | } else { | ||
| 1720 | rt2800_rfcsr_write(rt2x00dev, 7, 0x14); | ||
| 1721 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc0); | ||
| 1722 | rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); | ||
| 1723 | rt2800_rfcsr_write(rt2x00dev, 11, 0x00); | ||
| 1724 | rt2800_rfcsr_write(rt2x00dev, 15, 0x43); | ||
| 1725 | rt2800_rfcsr_write(rt2x00dev, 16, 0x7a); | ||
| 1726 | rt2800_rfcsr_write(rt2x00dev, 17, 0x23); | ||
| 1727 | if (rf->channel <= 64) { | ||
| 1728 | rt2800_rfcsr_write(rt2x00dev, 19, 0xb7); | ||
| 1729 | rt2800_rfcsr_write(rt2x00dev, 20, 0xf6); | ||
| 1730 | rt2800_rfcsr_write(rt2x00dev, 25, 0x3d); | ||
| 1731 | } else if (rf->channel <= 128) { | ||
| 1732 | rt2800_rfcsr_write(rt2x00dev, 19, 0x74); | ||
| 1733 | rt2800_rfcsr_write(rt2x00dev, 20, 0xf4); | ||
| 1734 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
| 1735 | } else { | ||
| 1736 | rt2800_rfcsr_write(rt2x00dev, 19, 0x72); | ||
| 1737 | rt2800_rfcsr_write(rt2x00dev, 20, 0xf3); | ||
| 1738 | rt2800_rfcsr_write(rt2x00dev, 25, 0x01); | ||
| 1739 | } | ||
| 1740 | rt2800_rfcsr_write(rt2x00dev, 26, 0x87); | ||
| 1741 | rt2800_rfcsr_write(rt2x00dev, 27, 0x01); | ||
| 1742 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9f); | ||
| 1743 | } | ||
| 1744 | |||
| 1745 | rt2800_register_read(rt2x00dev, GPIO_CTRL_CFG, ®); | ||
| 1746 | rt2x00_set_field32(®, GPIO_CTRL_CFG_GPIOD_BIT7, 0); | ||
| 1747 | if (rf->channel <= 14) | ||
| 1748 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 1); | ||
| 1749 | else | ||
| 1750 | rt2x00_set_field32(®, GPIO_CTRL_CFG_BIT7, 0); | ||
| 1751 | rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg); | ||
| 1752 | |||
| 1753 | rt2800_rfcsr_read(rt2x00dev, 7, &rfcsr); | ||
| 1754 | rt2x00_set_field8(&rfcsr, RFCSR7_RF_TUNING, 1); | ||
| 1755 | rt2800_rfcsr_write(rt2x00dev, 7, rfcsr); | ||
| 1756 | } | ||
| 1633 | 1757 | ||
| 1634 | #define RT5390_POWER_BOUND 0x27 | 1758 | #define RT5390_POWER_BOUND 0x27 |
| 1635 | #define RT5390_FREQ_OFFSET_BOUND 0x5f | 1759 | #define RT5390_FREQ_OFFSET_BOUND 0x5f |
| @@ -1748,9 +1872,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 1748 | rt2x00_rf(rt2x00dev, RF3020) || | 1872 | rt2x00_rf(rt2x00dev, RF3020) || |
| 1749 | rt2x00_rf(rt2x00dev, RF3021) || | 1873 | rt2x00_rf(rt2x00dev, RF3021) || |
| 1750 | rt2x00_rf(rt2x00dev, RF3022) || | 1874 | rt2x00_rf(rt2x00dev, RF3022) || |
| 1751 | rt2x00_rf(rt2x00dev, RF3052) || | ||
| 1752 | rt2x00_rf(rt2x00dev, RF3320)) | 1875 | rt2x00_rf(rt2x00dev, RF3320)) |
| 1753 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); | 1876 | rt2800_config_channel_rf3xxx(rt2x00dev, conf, rf, info); |
| 1877 | else if (rt2x00_rf(rt2x00dev, RF3052)) | ||
| 1878 | rt2800_config_channel_rf3052(rt2x00dev, conf, rf, info); | ||
| 1754 | else if (rt2x00_rf(rt2x00dev, RF5370) || | 1879 | else if (rt2x00_rf(rt2x00dev, RF5370) || |
| 1755 | rt2x00_rf(rt2x00dev, RF5390)) | 1880 | rt2x00_rf(rt2x00dev, RF5390)) |
| 1756 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); | 1881 | rt2800_config_channel_rf53xx(rt2x00dev, conf, rf, info); |
| @@ -1777,7 +1902,10 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 1777 | } | 1902 | } |
| 1778 | } | 1903 | } |
| 1779 | } else { | 1904 | } else { |
| 1780 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | 1905 | if (rt2x00_rt(rt2x00dev, RT3572)) |
| 1906 | rt2800_bbp_write(rt2x00dev, 82, 0x94); | ||
| 1907 | else | ||
| 1908 | rt2800_bbp_write(rt2x00dev, 82, 0xf2); | ||
| 1781 | 1909 | ||
| 1782 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) | 1910 | if (test_bit(CAPABILITY_EXTERNAL_LNA_A, &rt2x00dev->cap_flags)) |
| 1783 | rt2800_bbp_write(rt2x00dev, 75, 0x46); | 1911 | rt2800_bbp_write(rt2x00dev, 75, 0x46); |
| @@ -1791,12 +1919,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 1791 | rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); | 1919 | rt2x00_set_field32(®, TX_BAND_CFG_BG, rf->channel <= 14); |
| 1792 | rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); | 1920 | rt2800_register_write(rt2x00dev, TX_BAND_CFG, reg); |
| 1793 | 1921 | ||
| 1922 | if (rt2x00_rt(rt2x00dev, RT3572)) | ||
| 1923 | rt2800_rfcsr_write(rt2x00dev, 8, 0); | ||
| 1924 | |||
| 1794 | tx_pin = 0; | 1925 | tx_pin = 0; |
| 1795 | 1926 | ||
| 1796 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1927 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
| 1797 | if (rt2x00dev->default_ant.tx_chain_num == 2) { | 1928 | if (rt2x00dev->default_ant.tx_chain_num == 2) { |
| 1798 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 1); | 1929 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, |
| 1799 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 1); | 1930 | rf->channel > 14); |
| 1931 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, | ||
| 1932 | rf->channel <= 14); | ||
| 1800 | } | 1933 | } |
| 1801 | 1934 | ||
| 1802 | /* Turn on unused PA or LNA when not using 1T or 1R */ | 1935 | /* Turn on unused PA or LNA when not using 1T or 1R */ |
| @@ -1809,11 +1942,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, | |||
| 1809 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); | 1942 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); |
| 1810 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); | 1943 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); |
| 1811 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); | 1944 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); |
| 1812 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, rf->channel <= 14); | 1945 | if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags)) |
| 1946 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1); | ||
| 1947 | else | ||
| 1948 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, | ||
| 1949 | rf->channel <= 14); | ||
| 1813 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); | 1950 | rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14); |
| 1814 | 1951 | ||
| 1815 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); | 1952 | rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); |
| 1816 | 1953 | ||
| 1954 | if (rt2x00_rt(rt2x00dev, RT3572)) | ||
| 1955 | rt2800_rfcsr_write(rt2x00dev, 8, 0x80); | ||
| 1956 | |||
| 1817 | rt2800_bbp_read(rt2x00dev, 4, &bbp); | 1957 | rt2800_bbp_read(rt2x00dev, 4, &bbp); |
| 1818 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); | 1958 | rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); |
| 1819 | rt2800_bbp_write(rt2x00dev, 4, bbp); | 1959 | rt2800_bbp_write(rt2x00dev, 4, bbp); |
| @@ -2413,6 +2553,9 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 2413 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 2553 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
| 2414 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | 2554 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); |
| 2415 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); | 2555 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000030); |
| 2556 | } else if (rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 2557 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | ||
| 2558 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | ||
| 2416 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { | 2559 | } else if (rt2x00_rt(rt2x00dev, RT5390)) { |
| 2417 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); | 2560 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); |
| 2418 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 2561 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
| @@ -2799,6 +2942,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
| 2799 | } | 2942 | } |
| 2800 | 2943 | ||
| 2801 | if (rt2800_is_305x_soc(rt2x00dev) || | 2944 | if (rt2800_is_305x_soc(rt2x00dev) || |
| 2945 | rt2x00_rt(rt2x00dev, RT3572) || | ||
| 2802 | rt2x00_rt(rt2x00dev, RT5390)) | 2946 | rt2x00_rt(rt2x00dev, RT5390)) |
| 2803 | rt2800_bbp_write(rt2x00dev, 31, 0x08); | 2947 | rt2800_bbp_write(rt2x00dev, 31, 0x08); |
| 2804 | 2948 | ||
| @@ -2828,6 +2972,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
| 2828 | rt2x00_rt(rt2x00dev, RT3071) || | 2972 | rt2x00_rt(rt2x00dev, RT3071) || |
| 2829 | rt2x00_rt(rt2x00dev, RT3090) || | 2973 | rt2x00_rt(rt2x00dev, RT3090) || |
| 2830 | rt2x00_rt(rt2x00dev, RT3390) || | 2974 | rt2x00_rt(rt2x00dev, RT3390) || |
| 2975 | rt2x00_rt(rt2x00dev, RT3572) || | ||
| 2831 | rt2x00_rt(rt2x00dev, RT5390)) { | 2976 | rt2x00_rt(rt2x00dev, RT5390)) { |
| 2832 | rt2800_bbp_write(rt2x00dev, 79, 0x13); | 2977 | rt2800_bbp_write(rt2x00dev, 79, 0x13); |
| 2833 | rt2800_bbp_write(rt2x00dev, 80, 0x05); | 2978 | rt2800_bbp_write(rt2x00dev, 80, 0x05); |
| @@ -2868,6 +3013,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
| 2868 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || | 3013 | rt2x00_rt_rev_gte(rt2x00dev, RT3071, REV_RT3071E) || |
| 2869 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || | 3014 | rt2x00_rt_rev_gte(rt2x00dev, RT3090, REV_RT3090E) || |
| 2870 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || | 3015 | rt2x00_rt_rev_gte(rt2x00dev, RT3390, REV_RT3390E) || |
| 3016 | rt2x00_rt(rt2x00dev, RT3572) || | ||
| 2871 | rt2x00_rt(rt2x00dev, RT5390) || | 3017 | rt2x00_rt(rt2x00dev, RT5390) || |
| 2872 | rt2800_is_305x_soc(rt2x00dev)) | 3018 | rt2800_is_305x_soc(rt2x00dev)) |
| 2873 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); | 3019 | rt2800_bbp_write(rt2x00dev, 103, 0xc0); |
| @@ -2895,6 +3041,7 @@ static int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
| 2895 | if (rt2x00_rt(rt2x00dev, RT3071) || | 3041 | if (rt2x00_rt(rt2x00dev, RT3071) || |
| 2896 | rt2x00_rt(rt2x00dev, RT3090) || | 3042 | rt2x00_rt(rt2x00dev, RT3090) || |
| 2897 | rt2x00_rt(rt2x00dev, RT3390) || | 3043 | rt2x00_rt(rt2x00dev, RT3390) || |
| 3044 | rt2x00_rt(rt2x00dev, RT3572) || | ||
| 2898 | rt2x00_rt(rt2x00dev, RT5390)) { | 3045 | rt2x00_rt(rt2x00dev, RT5390)) { |
| 2899 | rt2800_bbp_read(rt2x00dev, 138, &value); | 3046 | rt2800_bbp_read(rt2x00dev, 138, &value); |
| 2900 | 3047 | ||
| @@ -3031,6 +3178,7 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 3031 | !rt2x00_rt(rt2x00dev, RT3071) && | 3178 | !rt2x00_rt(rt2x00dev, RT3071) && |
| 3032 | !rt2x00_rt(rt2x00dev, RT3090) && | 3179 | !rt2x00_rt(rt2x00dev, RT3090) && |
| 3033 | !rt2x00_rt(rt2x00dev, RT3390) && | 3180 | !rt2x00_rt(rt2x00dev, RT3390) && |
| 3181 | !rt2x00_rt(rt2x00dev, RT3572) && | ||
| 3034 | !rt2x00_rt(rt2x00dev, RT5390) && | 3182 | !rt2x00_rt(rt2x00dev, RT5390) && |
| 3035 | !rt2800_is_305x_soc(rt2x00dev)) | 3183 | !rt2800_is_305x_soc(rt2x00dev)) |
| 3036 | return 0; | 3184 | return 0; |
| @@ -3109,6 +3257,38 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 3109 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); | 3257 | rt2800_rfcsr_write(rt2x00dev, 29, 0x8f); |
| 3110 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); | 3258 | rt2800_rfcsr_write(rt2x00dev, 30, 0x20); |
| 3111 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); | 3259 | rt2800_rfcsr_write(rt2x00dev, 31, 0x0f); |
| 3260 | } else if (rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 3261 | rt2800_rfcsr_write(rt2x00dev, 0, 0x70); | ||
| 3262 | rt2800_rfcsr_write(rt2x00dev, 1, 0x81); | ||
| 3263 | rt2800_rfcsr_write(rt2x00dev, 2, 0xf1); | ||
| 3264 | rt2800_rfcsr_write(rt2x00dev, 3, 0x02); | ||
| 3265 | rt2800_rfcsr_write(rt2x00dev, 4, 0x4c); | ||
| 3266 | rt2800_rfcsr_write(rt2x00dev, 5, 0x05); | ||
| 3267 | rt2800_rfcsr_write(rt2x00dev, 6, 0x4a); | ||
| 3268 | rt2800_rfcsr_write(rt2x00dev, 7, 0xd8); | ||
| 3269 | rt2800_rfcsr_write(rt2x00dev, 9, 0xc3); | ||
| 3270 | rt2800_rfcsr_write(rt2x00dev, 10, 0xf1); | ||
| 3271 | rt2800_rfcsr_write(rt2x00dev, 11, 0xb9); | ||
| 3272 | rt2800_rfcsr_write(rt2x00dev, 12, 0x70); | ||
| 3273 | rt2800_rfcsr_write(rt2x00dev, 13, 0x65); | ||
| 3274 | rt2800_rfcsr_write(rt2x00dev, 14, 0xa0); | ||
| 3275 | rt2800_rfcsr_write(rt2x00dev, 15, 0x53); | ||
| 3276 | rt2800_rfcsr_write(rt2x00dev, 16, 0x4c); | ||
| 3277 | rt2800_rfcsr_write(rt2x00dev, 17, 0x23); | ||
| 3278 | rt2800_rfcsr_write(rt2x00dev, 18, 0xac); | ||
| 3279 | rt2800_rfcsr_write(rt2x00dev, 19, 0x93); | ||
| 3280 | rt2800_rfcsr_write(rt2x00dev, 20, 0xb3); | ||
| 3281 | rt2800_rfcsr_write(rt2x00dev, 21, 0xd0); | ||
| 3282 | rt2800_rfcsr_write(rt2x00dev, 22, 0x00); | ||
| 3283 | rt2800_rfcsr_write(rt2x00dev, 23, 0x3c); | ||
| 3284 | rt2800_rfcsr_write(rt2x00dev, 24, 0x16); | ||
| 3285 | rt2800_rfcsr_write(rt2x00dev, 25, 0x15); | ||
| 3286 | rt2800_rfcsr_write(rt2x00dev, 26, 0x85); | ||
| 3287 | rt2800_rfcsr_write(rt2x00dev, 27, 0x00); | ||
| 3288 | rt2800_rfcsr_write(rt2x00dev, 28, 0x00); | ||
| 3289 | rt2800_rfcsr_write(rt2x00dev, 29, 0x9b); | ||
| 3290 | rt2800_rfcsr_write(rt2x00dev, 30, 0x09); | ||
| 3291 | rt2800_rfcsr_write(rt2x00dev, 31, 0x10); | ||
| 3112 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | 3292 | } else if (rt2800_is_305x_soc(rt2x00dev)) { |
| 3113 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); | 3293 | rt2800_rfcsr_write(rt2x00dev, 0, 0x50); |
| 3114 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); | 3294 | rt2800_rfcsr_write(rt2x00dev, 1, 0x01); |
| @@ -3258,6 +3438,19 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 3258 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); | 3438 | rt2800_register_read(rt2x00dev, GPIO_SWITCH, ®); |
| 3259 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); | 3439 | rt2x00_set_field32(®, GPIO_SWITCH_5, 0); |
| 3260 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); | 3440 | rt2800_register_write(rt2x00dev, GPIO_SWITCH, reg); |
| 3441 | } else if (rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 3442 | rt2800_rfcsr_read(rt2x00dev, 6, &rfcsr); | ||
| 3443 | rt2x00_set_field8(&rfcsr, RFCSR6_R2, 1); | ||
| 3444 | rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); | ||
| 3445 | |||
| 3446 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 3447 | rt2x00_set_field32(®, LDO_CFG0_LDO_CORE_VLEVEL, 3); | ||
| 3448 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 3449 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 3450 | msleep(1); | ||
| 3451 | rt2800_register_read(rt2x00dev, LDO_CFG0, ®); | ||
| 3452 | rt2x00_set_field32(®, LDO_CFG0_BGSEL, 1); | ||
| 3453 | rt2800_register_write(rt2x00dev, LDO_CFG0, reg); | ||
| 3261 | } | 3454 | } |
| 3262 | 3455 | ||
| 3263 | /* | 3456 | /* |
| @@ -3270,7 +3463,8 @@ static int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
| 3270 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); | 3463 | rt2800_init_rx_filter(rt2x00dev, true, 0x27, 0x19); |
| 3271 | } else if (rt2x00_rt(rt2x00dev, RT3071) || | 3464 | } else if (rt2x00_rt(rt2x00dev, RT3071) || |
| 3272 | rt2x00_rt(rt2x00dev, RT3090) || | 3465 | rt2x00_rt(rt2x00dev, RT3090) || |
| 3273 | rt2x00_rt(rt2x00dev, RT3390)) { | 3466 | rt2x00_rt(rt2x00dev, RT3390) || |
| 3467 | rt2x00_rt(rt2x00dev, RT3572)) { | ||
| 3274 | rt2x00dev->calibration[0] = | 3468 | rt2x00dev->calibration[0] = |
| 3275 | rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); | 3469 | rt2800_init_rx_filter(rt2x00dev, false, 0x07, 0x13); |
| 3276 | rt2x00dev->calibration[1] = | 3470 | rt2x00dev->calibration[1] = |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index f2d15941c71a..69deb3148ae7 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
| @@ -152,7 +152,6 @@ void rt2800_write_tx_data(struct queue_entry *entry, | |||
| 152 | struct txentry_desc *txdesc); | 152 | struct txentry_desc *txdesc); |
| 153 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); | 153 | void rt2800_process_rxwi(struct queue_entry *entry, struct rxdone_entry_desc *txdesc); |
| 154 | 154 | ||
| 155 | void rt2800_txdone(struct rt2x00_dev *rt2x00dev); | ||
| 156 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status); | 155 | void rt2800_txdone_entry(struct queue_entry *entry, u32 status); |
| 157 | 156 | ||
| 158 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); | 157 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 3ac0943b9789..9ccc53733bae 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
| @@ -501,7 +501,9 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
| 501 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | 501 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); |
| 502 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | 502 | rt2x00pci_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); |
| 503 | 503 | ||
| 504 | if (rt2x00_rt(rt2x00dev, RT5390)) { | 504 | if (rt2x00_is_pcie(rt2x00dev) && |
| 505 | (rt2x00_rt(rt2x00dev, RT3572) || | ||
| 506 | rt2x00_rt(rt2x00dev, RT5390))) { | ||
| 505 | rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); | 507 | rt2x00pci_register_read(rt2x00dev, AUX_CTRL, ®); |
| 506 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); | 508 | rt2x00_set_field32(®, AUX_CTRL_FORCE_PCIE_CLK, 1); |
| 507 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); | 509 | rt2x00_set_field32(®, AUX_CTRL_WAKE_PCIE_EN, 1); |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index ba82c972703a..6e9229830a29 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
| @@ -457,6 +457,87 @@ static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | |||
| 457 | /* | 457 | /* |
| 458 | * TX control handlers | 458 | * TX control handlers |
| 459 | */ | 459 | */ |
| 460 | static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) | ||
| 461 | { | ||
| 462 | __le32 *txwi; | ||
| 463 | u32 word; | ||
| 464 | int wcid, ack, pid; | ||
| 465 | int tx_wcid, tx_ack, tx_pid; | ||
| 466 | |||
| 467 | wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); | ||
| 468 | ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); | ||
| 469 | pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); | ||
| 470 | |||
| 471 | /* | ||
| 472 | * This frames has returned with an IO error, | ||
| 473 | * so the status report is not intended for this | ||
| 474 | * frame. | ||
| 475 | */ | ||
| 476 | if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) { | ||
| 477 | rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); | ||
| 478 | return false; | ||
| 479 | } | ||
| 480 | |||
| 481 | /* | ||
| 482 | * Validate if this TX status report is intended for | ||
| 483 | * this entry by comparing the WCID/ACK/PID fields. | ||
| 484 | */ | ||
| 485 | txwi = rt2800usb_get_txwi(entry); | ||
| 486 | |||
| 487 | rt2x00_desc_read(txwi, 1, &word); | ||
| 488 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | ||
| 489 | tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); | ||
| 490 | tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); | ||
| 491 | |||
| 492 | if ((wcid != tx_wcid) || (ack != tx_ack) || (pid != tx_pid)) { | ||
| 493 | WARNING(entry->queue->rt2x00dev, | ||
| 494 | "TX status report missed for queue %d entry %d\n", | ||
| 495 | entry->queue->qid, entry->entry_idx); | ||
| 496 | rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); | ||
| 497 | return false; | ||
| 498 | } | ||
| 499 | |||
| 500 | return true; | ||
| 501 | } | ||
| 502 | |||
| 503 | static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) | ||
| 504 | { | ||
| 505 | struct data_queue *queue; | ||
| 506 | struct queue_entry *entry; | ||
| 507 | u32 reg; | ||
| 508 | u8 qid; | ||
| 509 | |||
| 510 | while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { | ||
| 511 | |||
| 512 | /* TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus | ||
| 513 | * qid is guaranteed to be one of the TX QIDs | ||
| 514 | */ | ||
| 515 | qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); | ||
| 516 | queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); | ||
| 517 | if (unlikely(!queue)) { | ||
| 518 | WARNING(rt2x00dev, "Got TX status for an unavailable " | ||
| 519 | "queue %u, dropping\n", qid); | ||
| 520 | continue; | ||
| 521 | } | ||
| 522 | |||
| 523 | /* | ||
| 524 | * Inside each queue, we process each entry in a chronological | ||
| 525 | * order. We first check that the queue is not empty. | ||
| 526 | */ | ||
| 527 | entry = NULL; | ||
| 528 | while (!rt2x00queue_empty(queue)) { | ||
| 529 | entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | ||
| 530 | if (rt2800usb_txdone_entry_check(entry, reg)) | ||
| 531 | break; | ||
| 532 | } | ||
| 533 | |||
| 534 | if (!entry || rt2x00queue_empty(queue)) | ||
| 535 | break; | ||
| 536 | |||
| 537 | rt2800_txdone_entry(entry, reg); | ||
| 538 | } | ||
| 539 | } | ||
| 540 | |||
| 460 | static void rt2800usb_work_txdone(struct work_struct *work) | 541 | static void rt2800usb_work_txdone(struct work_struct *work) |
| 461 | { | 542 | { |
| 462 | struct rt2x00_dev *rt2x00dev = | 543 | struct rt2x00_dev *rt2x00dev = |
| @@ -464,7 +545,7 @@ static void rt2800usb_work_txdone(struct work_struct *work) | |||
| 464 | struct data_queue *queue; | 545 | struct data_queue *queue; |
| 465 | struct queue_entry *entry; | 546 | struct queue_entry *entry; |
| 466 | 547 | ||
| 467 | rt2800_txdone(rt2x00dev); | 548 | rt2800usb_txdone(rt2x00dev); |
| 468 | 549 | ||
| 469 | /* | 550 | /* |
| 470 | * Process any trailing TX status reports for IO failures, | 551 | * Process any trailing TX status reports for IO failures, |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 555180d8f4aa..b704e5b183d0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
| @@ -250,7 +250,8 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
| 250 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) | 250 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) |
| 251 | rt2x00link_reset_tuner(rt2x00dev, false); | 251 | rt2x00link_reset_tuner(rt2x00dev, false); |
| 252 | 252 | ||
| 253 | if (test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && | 253 | if (test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) && |
| 254 | test_bit(REQUIRE_PS_AUTOWAKE, &rt2x00dev->cap_flags) && | ||
| 254 | (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && | 255 | (ieee80211_flags & IEEE80211_CONF_CHANGE_PS) && |
| 255 | (conf->flags & IEEE80211_CONF_PS)) { | 256 | (conf->flags & IEEE80211_CONF_PS)) { |
| 256 | beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; | 257 | beacon_diff = (long)jiffies - (long)rt2x00dev->last_beacon; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index c018d67aab8e..939821b4af2f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
| @@ -146,6 +146,9 @@ static void rt2x00lib_autowakeup(struct work_struct *work) | |||
| 146 | struct rt2x00_dev *rt2x00dev = | 146 | struct rt2x00_dev *rt2x00dev = |
| 147 | container_of(work, struct rt2x00_dev, autowakeup_work.work); | 147 | container_of(work, struct rt2x00_dev, autowakeup_work.work); |
| 148 | 148 | ||
| 149 | if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) | ||
| 150 | return; | ||
| 151 | |||
| 149 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) | 152 | if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_AWAKE)) |
| 150 | ERROR(rt2x00dev, "Device failed to wakeup.\n"); | 153 | ERROR(rt2x00dev, "Device failed to wakeup.\n"); |
| 151 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); | 154 | clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); |
| @@ -1160,6 +1163,7 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) | |||
| 1160 | * Stop all work. | 1163 | * Stop all work. |
| 1161 | */ | 1164 | */ |
| 1162 | cancel_work_sync(&rt2x00dev->intf_work); | 1165 | cancel_work_sync(&rt2x00dev->intf_work); |
| 1166 | cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); | ||
| 1163 | if (rt2x00_is_usb(rt2x00dev)) { | 1167 | if (rt2x00_is_usb(rt2x00dev)) { |
| 1164 | del_timer_sync(&rt2x00dev->txstatus_timer); | 1168 | del_timer_sync(&rt2x00dev->txstatus_timer); |
| 1165 | cancel_work_sync(&rt2x00dev->rxdone_work); | 1169 | cancel_work_sync(&rt2x00dev->rxdone_work); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index ab8c16f8bcaf..c7fc9def6bcf 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
| @@ -206,7 +206,6 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
| 206 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 206 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
| 207 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 207 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; |
| 208 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | 208 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); |
| 209 | unsigned long irqflags; | ||
| 210 | 209 | ||
| 211 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) | 210 | if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)) |
| 212 | return; | 211 | return; |
| @@ -227,14 +226,14 @@ static void rt2x00queue_create_tx_descriptor_seq(struct queue_entry *entry, | |||
| 227 | * sequence counting per-frame, since those will override the | 226 | * sequence counting per-frame, since those will override the |
| 228 | * sequence counter given by mac80211. | 227 | * sequence counter given by mac80211. |
| 229 | */ | 228 | */ |
| 230 | spin_lock_irqsave(&intf->seqlock, irqflags); | 229 | spin_lock(&intf->seqlock); |
| 231 | 230 | ||
| 232 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) | 231 | if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags)) |
| 233 | intf->seqno += 0x10; | 232 | intf->seqno += 0x10; |
| 234 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 233 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
| 235 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); | 234 | hdr->seq_ctrl |= cpu_to_le16(intf->seqno); |
| 236 | 235 | ||
| 237 | spin_unlock_irqrestore(&intf->seqlock, irqflags); | 236 | spin_unlock(&intf->seqlock); |
| 238 | 237 | ||
| 239 | } | 238 | } |
| 240 | 239 | ||
diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index ccb6da38fe22..fb5e43bd7c3c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c | |||
| @@ -888,7 +888,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, | |||
| 888 | { | 888 | { |
| 889 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 889 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 890 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 890 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 891 | struct rtl_tid_data *tid_data; | ||
| 892 | struct rtl_sta_info *sta_entry = NULL; | 891 | struct rtl_sta_info *sta_entry = NULL; |
| 893 | 892 | ||
| 894 | if (sta == NULL) | 893 | if (sta == NULL) |
| @@ -906,7 +905,6 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, | |||
| 906 | return -EINVAL; | 905 | return -EINVAL; |
| 907 | 906 | ||
| 908 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; | 907 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
| 909 | tid_data = &sta_entry->tids[tid]; | ||
| 910 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; | 908 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP; |
| 911 | 909 | ||
| 912 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); | 910 | ieee80211_stop_tx_ba_cb_irqsafe(mac->vif, sta->addr, tid); |
| @@ -918,7 +916,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, | |||
| 918 | struct ieee80211_sta *sta, u16 tid) | 916 | struct ieee80211_sta *sta, u16 tid) |
| 919 | { | 917 | { |
| 920 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 918 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 921 | struct rtl_tid_data *tid_data; | ||
| 922 | struct rtl_sta_info *sta_entry = NULL; | 919 | struct rtl_sta_info *sta_entry = NULL; |
| 923 | 920 | ||
| 924 | if (sta == NULL) | 921 | if (sta == NULL) |
| @@ -936,7 +933,6 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, | |||
| 936 | return -EINVAL; | 933 | return -EINVAL; |
| 937 | 934 | ||
| 938 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; | 935 | sta_entry = (struct rtl_sta_info *)sta->drv_priv; |
| 939 | tid_data = &sta_entry->tids[tid]; | ||
| 940 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; | 936 | sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL; |
| 941 | 937 | ||
| 942 | return 0; | 938 | return 0; |
diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 50de6f5d8a56..0b562322f138 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c | |||
| @@ -925,7 +925,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
| 925 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 925 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 926 | struct pgpkt_struct target_pkt; | 926 | struct pgpkt_struct target_pkt; |
| 927 | u8 write_state = PG_STATE_HEADER; | 927 | u8 write_state = PG_STATE_HEADER; |
| 928 | int continual = true, dataempty = true, result = true; | 928 | int continual = true, result = true; |
| 929 | u16 efuse_addr = 0; | 929 | u16 efuse_addr = 0; |
| 930 | u8 efuse_data; | 930 | u8 efuse_data; |
| 931 | u8 target_word_cnts = 0; | 931 | u8 target_word_cnts = 0; |
| @@ -953,7 +953,6 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, | |||
| 953 | (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { | 953 | (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { |
| 954 | 954 | ||
| 955 | if (write_state == PG_STATE_HEADER) { | 955 | if (write_state == PG_STATE_HEADER) { |
| 956 | dataempty = true; | ||
| 957 | badworden = 0x0F; | 956 | badworden = 0x0F; |
| 958 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, | 957 | RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, |
| 959 | ("efuse PG_STATE_HEADER\n")); | 958 | ("efuse PG_STATE_HEADER\n")); |
| @@ -1176,13 +1175,12 @@ static u16 efuse_get_current_size(struct ieee80211_hw *hw) | |||
| 1176 | { | 1175 | { |
| 1177 | int continual = true; | 1176 | int continual = true; |
| 1178 | u16 efuse_addr = 0; | 1177 | u16 efuse_addr = 0; |
| 1179 | u8 hoffset, hworden; | 1178 | u8 hworden; |
| 1180 | u8 efuse_data, word_cnts; | 1179 | u8 efuse_data, word_cnts; |
| 1181 | 1180 | ||
| 1182 | while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) | 1181 | while (continual && efuse_one_byte_read(hw, efuse_addr, &efuse_data) |
| 1183 | && (efuse_addr < EFUSE_MAX_SIZE)) { | 1182 | && (efuse_addr < EFUSE_MAX_SIZE)) { |
| 1184 | if (efuse_data != 0xFF) { | 1183 | if (efuse_data != 0xFF) { |
| 1185 | hoffset = (efuse_data >> 4) & 0x0F; | ||
| 1186 | hworden = efuse_data & 0x0F; | 1184 | hworden = efuse_data & 0x0F; |
| 1187 | word_cnts = efuse_calculate_word_cnts(hworden); | 1185 | word_cnts = efuse_calculate_word_cnts(hworden); |
| 1188 | efuse_addr = efuse_addr + (word_cnts * 2) + 1; | 1186 | efuse_addr = efuse_addr + (word_cnts * 2) + 1; |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 89100e7c553b..fc44005b0d53 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
| @@ -622,7 +622,7 @@ tx_status_ok: | |||
| 622 | if (((rtlpriv->link_info.num_rx_inperiod + | 622 | if (((rtlpriv->link_info.num_rx_inperiod + |
| 623 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 623 | rtlpriv->link_info.num_tx_inperiod) > 8) || |
| 624 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | 624 | (rtlpriv->link_info.num_rx_inperiod > 2)) { |
| 625 | rtl_lps_leave(hw); | 625 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); |
| 626 | } | 626 | } |
| 627 | } | 627 | } |
| 628 | 628 | ||
| @@ -644,22 +644,23 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
| 644 | .noise = -98, | 644 | .noise = -98, |
| 645 | .rate = 0, | 645 | .rate = 0, |
| 646 | }; | 646 | }; |
| 647 | int index = rtlpci->rx_ring[rx_queue_idx].idx; | ||
| 647 | 648 | ||
| 648 | /*RX NORMAL PKT */ | 649 | /*RX NORMAL PKT */ |
| 649 | while (count--) { | 650 | while (count--) { |
| 650 | /*rx descriptor */ | 651 | /*rx descriptor */ |
| 651 | struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[ | 652 | struct rtl_rx_desc *pdesc = &rtlpci->rx_ring[rx_queue_idx].desc[ |
| 652 | rtlpci->rx_ring[rx_queue_idx].idx]; | 653 | index]; |
| 653 | /*rx pkt */ | 654 | /*rx pkt */ |
| 654 | struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ | 655 | struct sk_buff *skb = rtlpci->rx_ring[rx_queue_idx].rx_buf[ |
| 655 | rtlpci->rx_ring[rx_queue_idx].idx]; | 656 | index]; |
| 656 | 657 | ||
| 657 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, | 658 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, |
| 658 | false, HW_DESC_OWN); | 659 | false, HW_DESC_OWN); |
| 659 | 660 | ||
| 660 | if (own) { | 661 | if (own) { |
| 661 | /*wait data to be filled by hardware */ | 662 | /*wait data to be filled by hardware */ |
| 662 | return; | 663 | break; |
| 663 | } else { | 664 | } else { |
| 664 | struct ieee80211_hdr *hdr; | 665 | struct ieee80211_hdr *hdr; |
| 665 | __le16 fc; | 666 | __le16 fc; |
| @@ -700,7 +701,7 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
| 700 | rtlpci->rxbuffersize, | 701 | rtlpci->rxbuffersize, |
| 701 | PCI_DMA_FROMDEVICE); | 702 | PCI_DMA_FROMDEVICE); |
| 702 | 703 | ||
| 703 | if (!stats.crc || !stats.hwerror) { | 704 | if (!stats.crc && !stats.hwerror) { |
| 704 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, | 705 | memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, |
| 705 | sizeof(rx_status)); | 706 | sizeof(rx_status)); |
| 706 | 707 | ||
| @@ -765,15 +766,12 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) | |||
| 765 | if (((rtlpriv->link_info.num_rx_inperiod + | 766 | if (((rtlpriv->link_info.num_rx_inperiod + |
| 766 | rtlpriv->link_info.num_tx_inperiod) > 8) || | 767 | rtlpriv->link_info.num_tx_inperiod) > 8) || |
| 767 | (rtlpriv->link_info.num_rx_inperiod > 2)) { | 768 | (rtlpriv->link_info.num_rx_inperiod > 2)) { |
| 768 | rtl_lps_leave(hw); | 769 | tasklet_schedule(&rtlpriv->works.ips_leave_tasklet); |
| 769 | } | 770 | } |
| 770 | 771 | ||
| 771 | skb = new_skb; | 772 | skb = new_skb; |
| 772 | 773 | ||
| 773 | rtlpci->rx_ring[rx_queue_idx].rx_buf[rtlpci-> | 774 | rtlpci->rx_ring[rx_queue_idx].rx_buf[index] = skb; |
| 774 | rx_ring | ||
| 775 | [rx_queue_idx]. | ||
| 776 | idx] = skb; | ||
| 777 | *((dma_addr_t *) skb->cb) = | 775 | *((dma_addr_t *) skb->cb) = |
| 778 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), | 776 | pci_map_single(rtlpci->pdev, skb_tail_pointer(skb), |
| 779 | rtlpci->rxbuffersize, | 777 | rtlpci->rxbuffersize, |
| @@ -786,23 +784,22 @@ done: | |||
| 786 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, | 784 | rtlpriv->cfg->ops->set_desc((u8 *) pdesc, false, |
| 787 | HW_DESC_RXBUFF_ADDR, | 785 | HW_DESC_RXBUFF_ADDR, |
| 788 | (u8 *)&bufferaddress); | 786 | (u8 *)&bufferaddress); |
| 789 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, | ||
| 790 | (u8 *)&tmp_one); | ||
| 791 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, | 787 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, |
| 792 | HW_DESC_RXPKT_LEN, | 788 | HW_DESC_RXPKT_LEN, |
| 793 | (u8 *)&rtlpci->rxbuffersize); | 789 | (u8 *)&rtlpci->rxbuffersize); |
| 794 | 790 | ||
| 795 | if (rtlpci->rx_ring[rx_queue_idx].idx == | 791 | if (index == rtlpci->rxringcount - 1) |
| 796 | rtlpci->rxringcount - 1) | ||
| 797 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, | 792 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, |
| 798 | HW_DESC_RXERO, | 793 | HW_DESC_RXERO, |
| 799 | (u8 *)&tmp_one); | 794 | (u8 *)&tmp_one); |
| 800 | 795 | ||
| 801 | rtlpci->rx_ring[rx_queue_idx].idx = | 796 | rtlpriv->cfg->ops->set_desc((u8 *)pdesc, false, HW_DESC_RXOWN, |
| 802 | (rtlpci->rx_ring[rx_queue_idx].idx + 1) % | 797 | (u8 *)&tmp_one); |
| 803 | rtlpci->rxringcount; | 798 | |
| 799 | index = (index + 1) % rtlpci->rxringcount; | ||
| 804 | } | 800 | } |
| 805 | 801 | ||
| 802 | rtlpci->rx_ring[rx_queue_idx].idx = index; | ||
| 806 | } | 803 | } |
| 807 | 804 | ||
| 808 | static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) | 805 | static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) |
| @@ -940,6 +937,11 @@ static void _rtl_pci_irq_tasklet(struct ieee80211_hw *hw) | |||
| 940 | _rtl_pci_tx_chk_waitq(hw); | 937 | _rtl_pci_tx_chk_waitq(hw); |
| 941 | } | 938 | } |
| 942 | 939 | ||
| 940 | static void _rtl_pci_ips_leave_tasklet(struct ieee80211_hw *hw) | ||
| 941 | { | ||
| 942 | rtl_lps_leave(hw); | ||
| 943 | } | ||
| 944 | |||
| 943 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) | 945 | static void _rtl_pci_prepare_bcn_tasklet(struct ieee80211_hw *hw) |
| 944 | { | 946 | { |
| 945 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 947 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| @@ -1038,6 +1040,9 @@ static void _rtl_pci_init_struct(struct ieee80211_hw *hw, | |||
| 1038 | tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, | 1040 | tasklet_init(&rtlpriv->works.irq_prepare_bcn_tasklet, |
| 1039 | (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, | 1041 | (void (*)(unsigned long))_rtl_pci_prepare_bcn_tasklet, |
| 1040 | (unsigned long)hw); | 1042 | (unsigned long)hw); |
| 1043 | tasklet_init(&rtlpriv->works.ips_leave_tasklet, | ||
| 1044 | (void (*)(unsigned long))_rtl_pci_ips_leave_tasklet, | ||
| 1045 | (unsigned long)hw); | ||
| 1041 | } | 1046 | } |
| 1042 | 1047 | ||
| 1043 | static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, | 1048 | static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, |
| @@ -1507,6 +1512,7 @@ static void rtl_pci_deinit(struct ieee80211_hw *hw) | |||
| 1507 | 1512 | ||
| 1508 | synchronize_irq(rtlpci->pdev->irq); | 1513 | synchronize_irq(rtlpci->pdev->irq); |
| 1509 | tasklet_kill(&rtlpriv->works.irq_tasklet); | 1514 | tasklet_kill(&rtlpriv->works.irq_tasklet); |
| 1515 | tasklet_kill(&rtlpriv->works.ips_leave_tasklet); | ||
| 1510 | 1516 | ||
| 1511 | flush_workqueue(rtlpriv->works.rtl_wq); | 1517 | flush_workqueue(rtlpriv->works.rtl_wq); |
| 1512 | destroy_workqueue(rtlpriv->works.rtl_wq); | 1518 | destroy_workqueue(rtlpriv->works.rtl_wq); |
| @@ -1581,6 +1587,7 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) | |||
| 1581 | set_hal_stop(rtlhal); | 1587 | set_hal_stop(rtlhal); |
| 1582 | 1588 | ||
| 1583 | rtlpriv->cfg->ops->disable_interrupt(hw); | 1589 | rtlpriv->cfg->ops->disable_interrupt(hw); |
| 1590 | tasklet_kill(&rtlpriv->works.ips_leave_tasklet); | ||
| 1584 | 1591 | ||
| 1585 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); | 1592 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); |
| 1586 | while (ppsc->rfchange_inprogress) { | 1593 | while (ppsc->rfchange_inprogress) { |
diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 39b0297ce925..d14c13d02177 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c | |||
| @@ -68,6 +68,7 @@ bool rtl_ps_disable_nic(struct ieee80211_hw *hw) | |||
| 68 | 68 | ||
| 69 | /*<2> Disable Interrupt */ | 69 | /*<2> Disable Interrupt */ |
| 70 | rtlpriv->cfg->ops->disable_interrupt(hw); | 70 | rtlpriv->cfg->ops->disable_interrupt(hw); |
| 71 | tasklet_kill(&rtlpriv->works.irq_tasklet); | ||
| 71 | 72 | ||
| 72 | /*<3> Disable Adapter */ | 73 | /*<3> Disable Adapter */ |
| 73 | rtlpriv->cfg->ops->hw_disable(hw); | 74 | rtlpriv->cfg->ops->hw_disable(hw); |
| @@ -82,10 +83,8 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | |||
| 82 | { | 83 | { |
| 83 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 84 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 84 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 85 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 85 | enum rf_pwrstate rtstate; | ||
| 86 | bool actionallowed = false; | 86 | bool actionallowed = false; |
| 87 | u16 rfwait_cnt = 0; | 87 | u16 rfwait_cnt = 0; |
| 88 | unsigned long flag; | ||
| 89 | 88 | ||
| 90 | /*protect_or_not = true; */ | 89 | /*protect_or_not = true; */ |
| 91 | 90 | ||
| @@ -98,10 +97,9 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | |||
| 98 | *should wait to be executed. | 97 | *should wait to be executed. |
| 99 | */ | 98 | */ |
| 100 | while (true) { | 99 | while (true) { |
| 101 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 100 | spin_lock(&rtlpriv->locks.rf_ps_lock); |
| 102 | if (ppsc->rfchange_inprogress) { | 101 | if (ppsc->rfchange_inprogress) { |
| 103 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, | 102 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
| 104 | flag); | ||
| 105 | 103 | ||
| 106 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 104 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
| 107 | ("RF Change in progress!" | 105 | ("RF Change in progress!" |
| @@ -122,15 +120,12 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, | |||
| 122 | } | 120 | } |
| 123 | } else { | 121 | } else { |
| 124 | ppsc->rfchange_inprogress = true; | 122 | ppsc->rfchange_inprogress = true; |
| 125 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, | 123 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
| 126 | flag); | ||
| 127 | break; | 124 | break; |
| 128 | } | 125 | } |
| 129 | } | 126 | } |
| 130 | 127 | ||
| 131 | no_protect: | 128 | no_protect: |
| 132 | rtstate = ppsc->rfpwr_state; | ||
| 133 | |||
| 134 | switch (state_toset) { | 129 | switch (state_toset) { |
| 135 | case ERFON: | 130 | case ERFON: |
| 136 | ppsc->rfoff_reason &= (~changesource); | 131 | ppsc->rfoff_reason &= (~changesource); |
| @@ -173,9 +168,9 @@ no_protect: | |||
| 173 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); | 168 | rtlpriv->cfg->ops->set_rf_power_state(hw, state_toset); |
| 174 | 169 | ||
| 175 | if (!protect_or_not) { | 170 | if (!protect_or_not) { |
| 176 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 171 | spin_lock(&rtlpriv->locks.rf_ps_lock); |
| 177 | ppsc->rfchange_inprogress = false; | 172 | ppsc->rfchange_inprogress = false; |
| 178 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 173 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
| 179 | } | 174 | } |
| 180 | 175 | ||
| 181 | return actionallowed; | 176 | return actionallowed; |
| @@ -289,12 +284,11 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
| 289 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 284 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 290 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 285 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 291 | enum rf_pwrstate rtstate; | 286 | enum rf_pwrstate rtstate; |
| 292 | unsigned long flags; | ||
| 293 | 287 | ||
| 294 | if (mac->opmode != NL80211_IFTYPE_STATION) | 288 | if (mac->opmode != NL80211_IFTYPE_STATION) |
| 295 | return; | 289 | return; |
| 296 | 290 | ||
| 297 | spin_lock_irqsave(&rtlpriv->locks.ips_lock, flags); | 291 | spin_lock(&rtlpriv->locks.ips_lock); |
| 298 | 292 | ||
| 299 | if (ppsc->inactiveps) { | 293 | if (ppsc->inactiveps) { |
| 300 | rtstate = ppsc->rfpwr_state; | 294 | rtstate = ppsc->rfpwr_state; |
| @@ -310,7 +304,7 @@ void rtl_ips_nic_on(struct ieee80211_hw *hw) | |||
| 310 | } | 304 | } |
| 311 | } | 305 | } |
| 312 | 306 | ||
| 313 | spin_unlock_irqrestore(&rtlpriv->locks.ips_lock, flags); | 307 | spin_unlock(&rtlpriv->locks.ips_lock); |
| 314 | } | 308 | } |
| 315 | 309 | ||
| 316 | /*for FW LPS*/ | 310 | /*for FW LPS*/ |
| @@ -428,7 +422,6 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
| 428 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 422 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 429 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 423 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 430 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 424 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 431 | unsigned long flag; | ||
| 432 | 425 | ||
| 433 | if (!ppsc->fwctrl_lps) | 426 | if (!ppsc->fwctrl_lps) |
| 434 | return; | 427 | return; |
| @@ -449,7 +442,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
| 449 | if (mac->link_state != MAC80211_LINKED) | 442 | if (mac->link_state != MAC80211_LINKED) |
| 450 | return; | 443 | return; |
| 451 | 444 | ||
| 452 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 445 | spin_lock(&rtlpriv->locks.lps_lock); |
| 453 | 446 | ||
| 454 | /* Idle for a while if we connect to AP a while ago. */ | 447 | /* Idle for a while if we connect to AP a while ago. */ |
| 455 | if (mac->cnt_after_linked >= 2) { | 448 | if (mac->cnt_after_linked >= 2) { |
| @@ -461,7 +454,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) | |||
| 461 | } | 454 | } |
| 462 | } | 455 | } |
| 463 | 456 | ||
| 464 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 457 | spin_unlock(&rtlpriv->locks.lps_lock); |
| 465 | } | 458 | } |
| 466 | 459 | ||
| 467 | /*Leave the leisure power save mode.*/ | 460 | /*Leave the leisure power save mode.*/ |
| @@ -470,9 +463,8 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
| 470 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 463 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 471 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 464 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 472 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 465 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 473 | unsigned long flag; | ||
| 474 | 466 | ||
| 475 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 467 | spin_lock(&rtlpriv->locks.lps_lock); |
| 476 | 468 | ||
| 477 | if (ppsc->fwctrl_lps) { | 469 | if (ppsc->fwctrl_lps) { |
| 478 | if (ppsc->dot11_psmode != EACTIVE) { | 470 | if (ppsc->dot11_psmode != EACTIVE) { |
| @@ -493,7 +485,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) | |||
| 493 | rtl_lps_set_psmode(hw, EACTIVE); | 485 | rtl_lps_set_psmode(hw, EACTIVE); |
| 494 | } | 486 | } |
| 495 | } | 487 | } |
| 496 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 488 | spin_unlock(&rtlpriv->locks.lps_lock); |
| 497 | } | 489 | } |
| 498 | 490 | ||
| 499 | /* For sw LPS*/ | 491 | /* For sw LPS*/ |
| @@ -582,7 +574,6 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
| 582 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 574 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 583 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 575 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 584 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 576 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 585 | unsigned long flag; | ||
| 586 | 577 | ||
| 587 | if (!rtlpriv->psc.swctrl_lps) | 578 | if (!rtlpriv->psc.swctrl_lps) |
| 588 | return; | 579 | return; |
| @@ -595,9 +586,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw) | |||
| 595 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); | 586 | RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM); |
| 596 | } | 587 | } |
| 597 | 588 | ||
| 598 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 589 | spin_lock(&rtlpriv->locks.lps_lock); |
| 599 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); | 590 | rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS, false); |
| 600 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 591 | spin_unlock(&rtlpriv->locks.lps_lock); |
| 601 | } | 592 | } |
| 602 | 593 | ||
| 603 | void rtl_swlps_rfon_wq_callback(void *data) | 594 | void rtl_swlps_rfon_wq_callback(void *data) |
| @@ -614,7 +605,6 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
| 614 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 605 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 615 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 606 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 616 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 607 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 617 | unsigned long flag; | ||
| 618 | u8 sleep_intv; | 608 | u8 sleep_intv; |
| 619 | 609 | ||
| 620 | if (!rtlpriv->psc.sw_ps_enabled) | 610 | if (!rtlpriv->psc.sw_ps_enabled) |
| @@ -631,16 +621,16 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) | |||
| 631 | if (rtlpriv->link_info.busytraffic) | 621 | if (rtlpriv->link_info.busytraffic) |
| 632 | return; | 622 | return; |
| 633 | 623 | ||
| 634 | spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); | 624 | spin_lock(&rtlpriv->locks.rf_ps_lock); |
| 635 | if (rtlpriv->psc.rfchange_inprogress) { | 625 | if (rtlpriv->psc.rfchange_inprogress) { |
| 636 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 626 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
| 637 | return; | 627 | return; |
| 638 | } | 628 | } |
| 639 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 629 | spin_unlock(&rtlpriv->locks.rf_ps_lock); |
| 640 | 630 | ||
| 641 | spin_lock_irqsave(&rtlpriv->locks.lps_lock, flag); | 631 | spin_lock(&rtlpriv->locks.lps_lock); |
| 642 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); | 632 | rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS, false); |
| 643 | spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag); | 633 | spin_unlock(&rtlpriv->locks.lps_lock); |
| 644 | 634 | ||
| 645 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && | 635 | if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM && |
| 646 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { | 636 | !RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) { |
diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 8f6718f163e5..9fedb1f70919 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c | |||
| @@ -303,22 +303,6 @@ static void _rtl_reg_apply_world_flags(struct wiphy *wiphy, | |||
| 303 | return; | 303 | return; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | static void _rtl_dump_channel_map(struct wiphy *wiphy) | ||
| 307 | { | ||
| 308 | enum ieee80211_band band; | ||
| 309 | struct ieee80211_supported_band *sband; | ||
| 310 | struct ieee80211_channel *ch; | ||
| 311 | unsigned int i; | ||
| 312 | |||
| 313 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
| 314 | if (!wiphy->bands[band]) | ||
| 315 | continue; | ||
| 316 | sband = wiphy->bands[band]; | ||
| 317 | for (i = 0; i < sband->n_channels; i++) | ||
| 318 | ch = &sband->channels[i]; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | static int _rtl_reg_notifier_apply(struct wiphy *wiphy, | 306 | static int _rtl_reg_notifier_apply(struct wiphy *wiphy, |
| 323 | struct regulatory_request *request, | 307 | struct regulatory_request *request, |
| 324 | struct rtl_regulatory *reg) | 308 | struct rtl_regulatory *reg) |
| @@ -336,8 +320,6 @@ static int _rtl_reg_notifier_apply(struct wiphy *wiphy, | |||
| 336 | break; | 320 | break; |
| 337 | } | 321 | } |
| 338 | 322 | ||
| 339 | _rtl_dump_channel_map(wiphy); | ||
| 340 | |||
| 341 | return 0; | 323 | return 0; |
| 342 | } | 324 | } |
| 343 | 325 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 50303e1adff1..f9f2370e9256 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | |||
| @@ -546,7 +546,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | |||
| 546 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 546 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| 547 | struct rtl8192_tx_ring *ring; | 547 | struct rtl8192_tx_ring *ring; |
| 548 | struct rtl_tx_desc *pdesc; | 548 | struct rtl_tx_desc *pdesc; |
| 549 | u8 own; | ||
| 550 | unsigned long flags; | 549 | unsigned long flags; |
| 551 | struct sk_buff *pskb = NULL; | 550 | struct sk_buff *pskb = NULL; |
| 552 | 551 | ||
| @@ -559,7 +558,6 @@ static bool _rtl92c_cmd_send_packet(struct ieee80211_hw *hw, | |||
| 559 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); | 558 | spin_lock_irqsave(&rtlpriv->locks.irq_th_lock, flags); |
| 560 | 559 | ||
| 561 | pdesc = &ring->desc[0]; | 560 | pdesc = &ring->desc[0]; |
| 562 | own = (u8) rtlpriv->cfg->ops->get_desc((u8 *) pdesc, true, HW_DESC_OWN); | ||
| 563 | 561 | ||
| 564 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); | 562 | rtlpriv->cfg->ops->fill_tx_cmddesc(hw, (u8 *) pdesc, 1, 1, skb); |
| 565 | 563 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index d2cc81586a6a..3b11642d3f7d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
| @@ -1253,10 +1253,9 @@ static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | |||
| 1253 | 1253 | ||
| 1254 | const u32 retrycount = 2; | 1254 | const u32 retrycount = 2; |
| 1255 | 1255 | ||
| 1256 | u32 bbvalue; | ||
| 1257 | |||
| 1258 | if (t == 0) { | 1256 | if (t == 0) { |
| 1259 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | 1257 | /* dummy read */ |
| 1258 | rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
| 1260 | 1259 | ||
| 1261 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | 1260 | _rtl92c_phy_save_adda_registers(hw, adda_reg, |
| 1262 | rtlphy->adda_backup, 16); | 1261 | rtlphy->adda_backup, 16); |
| @@ -1762,8 +1761,7 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) | |||
| 1762 | long result[4][8]; | 1761 | long result[4][8]; |
| 1763 | u8 i, final_candidate; | 1762 | u8 i, final_candidate; |
| 1764 | bool patha_ok, pathb_ok; | 1763 | bool patha_ok, pathb_ok; |
| 1765 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | 1764 | long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0; |
| 1766 | reg_ecc, reg_tmp = 0; | ||
| 1767 | bool is12simular, is13simular, is23simular; | 1765 | bool is12simular, is13simular, is23simular; |
| 1768 | bool start_conttx = false, singletone = false; | 1766 | bool start_conttx = false, singletone = false; |
| 1769 | u32 iqk_bb_reg[10] = { | 1767 | u32 iqk_bb_reg[10] = { |
| @@ -1841,21 +1839,17 @@ void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) | |||
| 1841 | reg_e94 = result[i][0]; | 1839 | reg_e94 = result[i][0]; |
| 1842 | reg_e9c = result[i][1]; | 1840 | reg_e9c = result[i][1]; |
| 1843 | reg_ea4 = result[i][2]; | 1841 | reg_ea4 = result[i][2]; |
| 1844 | reg_eac = result[i][3]; | ||
| 1845 | reg_eb4 = result[i][4]; | 1842 | reg_eb4 = result[i][4]; |
| 1846 | reg_ebc = result[i][5]; | 1843 | reg_ebc = result[i][5]; |
| 1847 | reg_ec4 = result[i][6]; | 1844 | reg_ec4 = result[i][6]; |
| 1848 | reg_ecc = result[i][7]; | ||
| 1849 | } | 1845 | } |
| 1850 | if (final_candidate != 0xff) { | 1846 | if (final_candidate != 0xff) { |
| 1851 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | 1847 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; |
| 1852 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | 1848 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; |
| 1853 | reg_ea4 = result[final_candidate][2]; | 1849 | reg_ea4 = result[final_candidate][2]; |
| 1854 | reg_eac = result[final_candidate][3]; | ||
| 1855 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | 1850 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; |
| 1856 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | 1851 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; |
| 1857 | reg_ec4 = result[final_candidate][6]; | 1852 | reg_ec4 = result[final_candidate][6]; |
| 1858 | reg_ecc = result[final_candidate][7]; | ||
| 1859 | patha_ok = pathb_ok = true; | 1853 | patha_ok = pathb_ok = true; |
| 1860 | } else { | 1854 | } else { |
| 1861 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | 1855 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index defb4370cf74..944f55e9d316 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | |||
| @@ -763,11 +763,9 @@ static void _rtl92ce_hw_configure(struct ieee80211_hw *hw) | |||
| 763 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 763 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 764 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); | 764 | struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); |
| 765 | u8 reg_bw_opmode; | 765 | u8 reg_bw_opmode; |
| 766 | u32 reg_ratr, reg_prsr; | 766 | u32 reg_prsr; |
| 767 | 767 | ||
| 768 | reg_bw_opmode = BW_OPMODE_20MHZ; | 768 | reg_bw_opmode = BW_OPMODE_20MHZ; |
| 769 | reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | | ||
| 770 | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; | ||
| 771 | reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; | 769 | reg_prsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; |
| 772 | 770 | ||
| 773 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); | 771 | rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); |
| @@ -1196,6 +1194,7 @@ void rtl92ce_disable_interrupt(struct ieee80211_hw *hw) | |||
| 1196 | rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); | 1194 | rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); |
| 1197 | rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); | 1195 | rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); |
| 1198 | rtlpci->irq_enabled = false; | 1196 | rtlpci->irq_enabled = false; |
| 1197 | synchronize_irq(rtlpci->pdev->irq); | ||
| 1199 | } | 1198 | } |
| 1200 | 1199 | ||
| 1201 | static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) | 1200 | static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) |
| @@ -1969,7 +1968,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
| 1969 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1968 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1970 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 1969 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 1971 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 1970 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| 1972 | enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; | 1971 | enum rf_pwrstate e_rfpowerstate_toset; |
| 1973 | u8 u1tmp; | 1972 | u8 u1tmp; |
| 1974 | bool actuallyset = false; | 1973 | bool actuallyset = false; |
| 1975 | unsigned long flag; | 1974 | unsigned long flag; |
| @@ -1989,8 +1988,6 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
| 1989 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 1988 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); |
| 1990 | } | 1989 | } |
| 1991 | 1990 | ||
| 1992 | cur_rfstate = ppsc->rfpwr_state; | ||
| 1993 | |||
| 1994 | rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, | 1991 | rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, |
| 1995 | REG_MAC_PINMUX_CFG)&~(BIT(3))); | 1992 | REG_MAC_PINMUX_CFG)&~(BIT(3))); |
| 1996 | 1993 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index abe0fcc75368..592a10ac5929 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
| @@ -46,13 +46,12 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | |||
| 46 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 46 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 47 | u32 original_value, readback_value, bitshift; | 47 | u32 original_value, readback_value, bitshift; |
| 48 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 48 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 49 | unsigned long flags; | ||
| 50 | 49 | ||
| 51 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | 50 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " |
| 52 | "rfpath(%#x), bitmask(%#x)\n", | 51 | "rfpath(%#x), bitmask(%#x)\n", |
| 53 | regaddr, rfpath, bitmask)); | 52 | regaddr, rfpath, bitmask)); |
| 54 | 53 | ||
| 55 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | 54 | spin_lock(&rtlpriv->locks.rf_lock); |
| 56 | 55 | ||
| 57 | if (rtlphy->rf_mode != RF_OP_BY_FW) { | 56 | if (rtlphy->rf_mode != RF_OP_BY_FW) { |
| 58 | original_value = _rtl92c_phy_rf_serial_read(hw, | 57 | original_value = _rtl92c_phy_rf_serial_read(hw, |
| @@ -65,7 +64,7 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | |||
| 65 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | 64 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); |
| 66 | readback_value = (original_value & bitmask) >> bitshift; | 65 | readback_value = (original_value & bitmask) >> bitshift; |
| 67 | 66 | ||
| 68 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | 67 | spin_unlock(&rtlpriv->locks.rf_lock); |
| 69 | 68 | ||
| 70 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | 69 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
| 71 | ("regaddr(%#x), rfpath(%#x), " | 70 | ("regaddr(%#x), rfpath(%#x), " |
| @@ -120,13 +119,12 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, | |||
| 120 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 119 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 121 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 120 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 122 | u32 original_value, bitshift; | 121 | u32 original_value, bitshift; |
| 123 | unsigned long flags; | ||
| 124 | 122 | ||
| 125 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, | 123 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
| 126 | ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", | 124 | ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", |
| 127 | regaddr, bitmask, data, rfpath)); | 125 | regaddr, bitmask, data, rfpath)); |
| 128 | 126 | ||
| 129 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | 127 | spin_lock(&rtlpriv->locks.rf_lock); |
| 130 | 128 | ||
| 131 | if (rtlphy->rf_mode != RF_OP_BY_FW) { | 129 | if (rtlphy->rf_mode != RF_OP_BY_FW) { |
| 132 | if (bitmask != RFREG_OFFSET_MASK) { | 130 | if (bitmask != RFREG_OFFSET_MASK) { |
| @@ -153,7 +151,7 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, | |||
| 153 | _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); | 151 | _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); |
| 154 | } | 152 | } |
| 155 | 153 | ||
| 156 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | 154 | spin_unlock(&rtlpriv->locks.rf_lock); |
| 157 | 155 | ||
| 158 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | 156 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " |
| 159 | "bitmask(%#x), data(%#x), " | 157 | "bitmask(%#x), data(%#x), " |
| @@ -281,7 +279,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
| 281 | { | 279 | { |
| 282 | 280 | ||
| 283 | int i; | 281 | int i; |
| 284 | bool rtstatus = true; | ||
| 285 | u32 *radioa_array_table; | 282 | u32 *radioa_array_table; |
| 286 | u32 *radiob_array_table; | 283 | u32 *radiob_array_table; |
| 287 | u16 radioa_arraylen, radiob_arraylen; | 284 | u16 radioa_arraylen, radiob_arraylen; |
| @@ -308,7 +305,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
| 308 | ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); | 305 | ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); |
| 309 | } | 306 | } |
| 310 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); | 307 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); |
| 311 | rtstatus = true; | ||
| 312 | switch (rfpath) { | 308 | switch (rfpath) { |
| 313 | case RF90_PATH_A: | 309 | case RF90_PATH_A: |
| 314 | for (i = 0; i < radioa_arraylen; i = i + 2) { | 310 | for (i = 0; i < radioa_arraylen; i = i + 2) { |
| @@ -521,7 +517,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 521 | u8 i, queue_id; | 517 | u8 i, queue_id; |
| 522 | struct rtl8192_tx_ring *ring = NULL; | 518 | struct rtl8192_tx_ring *ring = NULL; |
| 523 | 519 | ||
| 524 | ppsc->set_rfpowerstate_inprogress = true; | ||
| 525 | switch (rfpwr_state) { | 520 | switch (rfpwr_state) { |
| 526 | case ERFON:{ | 521 | case ERFON:{ |
| 527 | if ((ppsc->rfpwr_state == ERFOFF) && | 522 | if ((ppsc->rfpwr_state == ERFOFF) && |
| @@ -617,7 +612,6 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 617 | } | 612 | } |
| 618 | if (bresult) | 613 | if (bresult) |
| 619 | ppsc->rfpwr_state = rfpwr_state; | 614 | ppsc->rfpwr_state = rfpwr_state; |
| 620 | ppsc->set_rfpowerstate_inprogress = false; | ||
| 621 | return bresult; | 615 | return bresult; |
| 622 | } | 616 | } |
| 623 | 617 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 54b2bd53d36a..2492cc234c03 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | |||
| @@ -592,7 +592,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 592 | struct ieee80211_hdr *hdr; | 592 | struct ieee80211_hdr *hdr; |
| 593 | u8 *tmp_buf; | 593 | u8 *tmp_buf; |
| 594 | u8 *praddr; | 594 | u8 *praddr; |
| 595 | u8 *psaddr; | ||
| 596 | __le16 fc; | 595 | __le16 fc; |
| 597 | u16 type, c_fc; | 596 | u16 type, c_fc; |
| 598 | bool packet_matchbssid, packet_toself, packet_beacon; | 597 | bool packet_matchbssid, packet_toself, packet_beacon; |
| @@ -604,7 +603,6 @@ static void _rtl92ce_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 604 | c_fc = le16_to_cpu(fc); | 603 | c_fc = le16_to_cpu(fc); |
| 605 | type = WLAN_FC_GET_TYPE(fc); | 604 | type = WLAN_FC_GET_TYPE(fc); |
| 606 | praddr = hdr->addr1; | 605 | praddr = hdr->addr1; |
| 607 | psaddr = hdr->addr2; | ||
| 608 | 606 | ||
| 609 | packet_matchbssid = | 607 | packet_matchbssid = |
| 610 | ((IEEE80211_FTYPE_CTL != type) && | 608 | ((IEEE80211_FTYPE_CTL != type) && |
| @@ -932,6 +930,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | |||
| 932 | if (istx == true) { | 930 | if (istx == true) { |
| 933 | switch (desc_name) { | 931 | switch (desc_name) { |
| 934 | case HW_DESC_OWN: | 932 | case HW_DESC_OWN: |
| 933 | wmb(); | ||
| 935 | SET_TX_DESC_OWN(pdesc, 1); | 934 | SET_TX_DESC_OWN(pdesc, 1); |
| 936 | break; | 935 | break; |
| 937 | case HW_DESC_TX_NEXTDESC_ADDR: | 936 | case HW_DESC_TX_NEXTDESC_ADDR: |
| @@ -945,6 +944,7 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | |||
| 945 | } else { | 944 | } else { |
| 946 | switch (desc_name) { | 945 | switch (desc_name) { |
| 947 | case HW_DESC_RXOWN: | 946 | case HW_DESC_RXOWN: |
| 947 | wmb(); | ||
| 948 | SET_RX_DESC_OWN(pdesc, 1); | 948 | SET_RX_DESC_OWN(pdesc, 1); |
| 949 | break; | 949 | break; |
| 950 | case HW_DESC_RXBUFF_ADDR: | 950 | case HW_DESC_RXBUFF_ADDR: |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index f8514cba17b6..4e057df6f488 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | |||
| @@ -1113,7 +1113,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 1113 | struct ieee80211_hdr *hdr; | 1113 | struct ieee80211_hdr *hdr; |
| 1114 | u8 *tmp_buf; | 1114 | u8 *tmp_buf; |
| 1115 | u8 *praddr; | 1115 | u8 *praddr; |
| 1116 | u8 *psaddr; | ||
| 1117 | __le16 fc; | 1116 | __le16 fc; |
| 1118 | u16 type, cpu_fc; | 1117 | u16 type, cpu_fc; |
| 1119 | bool packet_matchbssid, packet_toself, packet_beacon; | 1118 | bool packet_matchbssid, packet_toself, packet_beacon; |
| @@ -1124,7 +1123,6 @@ void rtl92c_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 1124 | cpu_fc = le16_to_cpu(fc); | 1123 | cpu_fc = le16_to_cpu(fc); |
| 1125 | type = WLAN_FC_GET_TYPE(fc); | 1124 | type = WLAN_FC_GET_TYPE(fc); |
| 1126 | praddr = hdr->addr1; | 1125 | praddr = hdr->addr1; |
| 1127 | psaddr = hdr->addr2; | ||
| 1128 | packet_matchbssid = | 1126 | packet_matchbssid = |
| 1129 | ((IEEE80211_FTYPE_CTL != type) && | 1127 | ((IEEE80211_FTYPE_CTL != type) && |
| 1130 | (!compare_ether_addr(mac->bssid, | 1128 | (!compare_ether_addr(mac->bssid, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index 9a3d0239e27e..72852900df84 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | |||
| @@ -470,7 +470,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 470 | u8 i, queue_id; | 470 | u8 i, queue_id; |
| 471 | struct rtl8192_tx_ring *ring = NULL; | 471 | struct rtl8192_tx_ring *ring = NULL; |
| 472 | 472 | ||
| 473 | ppsc->set_rfpowerstate_inprogress = true; | ||
| 474 | switch (rfpwr_state) { | 473 | switch (rfpwr_state) { |
| 475 | case ERFON: | 474 | case ERFON: |
| 476 | if ((ppsc->rfpwr_state == ERFOFF) && | 475 | if ((ppsc->rfpwr_state == ERFOFF) && |
| @@ -590,7 +589,6 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 590 | } | 589 | } |
| 591 | if (bresult) | 590 | if (bresult) |
| 592 | ppsc->rfpwr_state = rfpwr_state; | 591 | ppsc->rfpwr_state = rfpwr_state; |
| 593 | ppsc->set_rfpowerstate_inprogress = false; | ||
| 594 | return bresult; | 592 | return bresult; |
| 595 | } | 593 | } |
| 596 | 594 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index da86db86fa4a..609c7ec7e66a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c | |||
| @@ -222,7 +222,6 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) | |||
| 222 | u32 low_rssi_thresh = 0; | 222 | u32 low_rssi_thresh = 0; |
| 223 | u32 middle_rssi_thresh = 0; | 223 | u32 middle_rssi_thresh = 0; |
| 224 | u32 high_rssi_thresh = 0; | 224 | u32 high_rssi_thresh = 0; |
| 225 | u8 rssi_level; | ||
| 226 | struct ieee80211_sta *sta = NULL; | 225 | struct ieee80211_sta *sta = NULL; |
| 227 | 226 | ||
| 228 | if (is_hal_stop(rtlhal)) | 227 | if (is_hal_stop(rtlhal)) |
| @@ -272,18 +271,14 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) | |||
| 272 | if (rtlpriv->dm.undecorated_smoothed_pwdb > | 271 | if (rtlpriv->dm.undecorated_smoothed_pwdb > |
| 273 | (long)high_rssi_thresh) { | 272 | (long)high_rssi_thresh) { |
| 274 | ra->ratr_state = DM_RATR_STA_HIGH; | 273 | ra->ratr_state = DM_RATR_STA_HIGH; |
| 275 | rssi_level = 1; | ||
| 276 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | 274 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > |
| 277 | (long)middle_rssi_thresh) { | 275 | (long)middle_rssi_thresh) { |
| 278 | ra->ratr_state = DM_RATR_STA_LOW; | 276 | ra->ratr_state = DM_RATR_STA_LOW; |
| 279 | rssi_level = 3; | ||
| 280 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > | 277 | } else if (rtlpriv->dm.undecorated_smoothed_pwdb > |
| 281 | (long)low_rssi_thresh) { | 278 | (long)low_rssi_thresh) { |
| 282 | ra->ratr_state = DM_RATR_STA_LOW; | 279 | ra->ratr_state = DM_RATR_STA_LOW; |
| 283 | rssi_level = 5; | ||
| 284 | } else { | 280 | } else { |
| 285 | ra->ratr_state = DM_RATR_STA_ULTRALOW; | 281 | ra->ratr_state = DM_RATR_STA_ULTRALOW; |
| 286 | rssi_level = 6; | ||
| 287 | } | 282 | } |
| 288 | 283 | ||
| 289 | if (ra->pre_ratr_state != ra->ratr_state) { | 284 | if (ra->pre_ratr_state != ra->ratr_state) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 3b5af0113d7f..6f91a148c222 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c | |||
| @@ -358,7 +358,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) | |||
| 358 | struct fw_priv *pfw_priv = NULL; | 358 | struct fw_priv *pfw_priv = NULL; |
| 359 | u8 *puc_mappedfile = NULL; | 359 | u8 *puc_mappedfile = NULL; |
| 360 | u32 ul_filelength = 0; | 360 | u32 ul_filelength = 0; |
| 361 | u32 file_length = 0; | ||
| 362 | u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; | 361 | u8 fwhdr_size = RT_8192S_FIRMWARE_HDR_SIZE; |
| 363 | u8 fwstatus = FW_STATUS_INIT; | 362 | u8 fwstatus = FW_STATUS_INIT; |
| 364 | bool rtstatus = true; | 363 | bool rtstatus = true; |
| @@ -370,7 +369,6 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) | |||
| 370 | firmware->fwstatus = FW_STATUS_INIT; | 369 | firmware->fwstatus = FW_STATUS_INIT; |
| 371 | 370 | ||
| 372 | puc_mappedfile = firmware->sz_fw_tmpbuffer; | 371 | puc_mappedfile = firmware->sz_fw_tmpbuffer; |
| 373 | file_length = firmware->sz_fw_tmpbufferlen; | ||
| 374 | 372 | ||
| 375 | /* 1. Retrieve FW header. */ | 373 | /* 1. Retrieve FW header. */ |
| 376 | firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; | 374 | firmware->pfwheader = (struct fw_hdr *) puc_mappedfile; |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 2e9005d0454b..35dd12d0dcf3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c | |||
| @@ -884,12 +884,10 @@ static void _rtl92se_hw_configure(struct ieee80211_hw *hw) | |||
| 884 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | 884 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
| 885 | 885 | ||
| 886 | u8 reg_bw_opmode = 0; | 886 | u8 reg_bw_opmode = 0; |
| 887 | u32 reg_ratr = 0, reg_rrsr = 0; | 887 | u32 reg_rrsr = 0; |
| 888 | u8 regtmp = 0; | 888 | u8 regtmp = 0; |
| 889 | 889 | ||
| 890 | reg_bw_opmode = BW_OPMODE_20MHZ; | 890 | reg_bw_opmode = BW_OPMODE_20MHZ; |
| 891 | reg_ratr = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | | ||
| 892 | RATE_ALL_OFDM_2SS; | ||
| 893 | reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; | 891 | reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; |
| 894 | 892 | ||
| 895 | regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); | 893 | regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); |
| @@ -1122,14 +1120,12 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, | |||
| 1122 | { | 1120 | { |
| 1123 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 1121 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 1124 | u8 bt_msr = rtl_read_byte(rtlpriv, MSR); | 1122 | u8 bt_msr = rtl_read_byte(rtlpriv, MSR); |
| 1125 | enum led_ctl_mode ledaction = LED_CTL_NO_LINK; | ||
| 1126 | u32 temp; | 1123 | u32 temp; |
| 1127 | bt_msr &= ~MSR_LINK_MASK; | 1124 | bt_msr &= ~MSR_LINK_MASK; |
| 1128 | 1125 | ||
| 1129 | switch (type) { | 1126 | switch (type) { |
| 1130 | case NL80211_IFTYPE_UNSPECIFIED: | 1127 | case NL80211_IFTYPE_UNSPECIFIED: |
| 1131 | bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); | 1128 | bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); |
| 1132 | ledaction = LED_CTL_LINK; | ||
| 1133 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 1129 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
| 1134 | ("Set Network type to NO LINK!\n")); | 1130 | ("Set Network type to NO LINK!\n")); |
| 1135 | break; | 1131 | break; |
| @@ -1140,7 +1136,6 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, | |||
| 1140 | break; | 1136 | break; |
| 1141 | case NL80211_IFTYPE_STATION: | 1137 | case NL80211_IFTYPE_STATION: |
| 1142 | bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); | 1138 | bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); |
| 1143 | ledaction = LED_CTL_LINK; | ||
| 1144 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 1139 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
| 1145 | ("Set Network type to STA!\n")); | 1140 | ("Set Network type to STA!\n")); |
| 1146 | break; | 1141 | break; |
| @@ -1231,6 +1226,7 @@ void rtl92se_disable_interrupt(struct ieee80211_hw *hw) | |||
| 1231 | rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); | 1226 | rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); |
| 1232 | 1227 | ||
| 1233 | rtlpci->irq_enabled = false; | 1228 | rtlpci->irq_enabled = false; |
| 1229 | synchronize_irq(rtlpci->pdev->irq); | ||
| 1234 | } | 1230 | } |
| 1235 | 1231 | ||
| 1236 | 1232 | ||
| @@ -2271,7 +2267,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
| 2271 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 2267 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 2272 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); | 2268 | struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); |
| 2273 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); | 2269 | struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); |
| 2274 | enum rf_pwrstate rfpwr_toset, cur_rfstate; | 2270 | enum rf_pwrstate rfpwr_toset /*, cur_rfstate */; |
| 2275 | unsigned long flag = 0; | 2271 | unsigned long flag = 0; |
| 2276 | bool actuallyset = false; | 2272 | bool actuallyset = false; |
| 2277 | bool turnonbypowerdomain = false; | 2273 | bool turnonbypowerdomain = false; |
| @@ -2292,7 +2288,7 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) | |||
| 2292 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); | 2288 | spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); |
| 2293 | } | 2289 | } |
| 2294 | 2290 | ||
| 2295 | cur_rfstate = ppsc->rfpwr_state; | 2291 | /* cur_rfstate = ppsc->rfpwr_state;*/ |
| 2296 | 2292 | ||
| 2297 | /* because after _rtl92s_phy_set_rfhalt, all power | 2293 | /* because after _rtl92s_phy_set_rfhalt, all power |
| 2298 | * closed, so we must open some power for GPIO check, | 2294 | * closed, so we must open some power for GPIO check, |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index 63b45e60a95e..7ee2daccd7d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c | |||
| @@ -180,19 +180,18 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | |||
| 180 | { | 180 | { |
| 181 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 181 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 182 | u32 original_value, readback_value, bitshift; | 182 | u32 original_value, readback_value, bitshift; |
| 183 | unsigned long flags; | ||
| 184 | 183 | ||
| 185 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " | 184 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " |
| 186 | "bitmask(%#x)\n", regaddr, rfpath, bitmask)); | 185 | "bitmask(%#x)\n", regaddr, rfpath, bitmask)); |
| 187 | 186 | ||
| 188 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | 187 | spin_lock(&rtlpriv->locks.rf_lock); |
| 189 | 188 | ||
| 190 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); | 189 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); |
| 191 | 190 | ||
| 192 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); | 191 | bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); |
| 193 | readback_value = (original_value & bitmask) >> bitshift; | 192 | readback_value = (original_value & bitmask) >> bitshift; |
| 194 | 193 | ||
| 195 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | 194 | spin_unlock(&rtlpriv->locks.rf_lock); |
| 196 | 195 | ||
| 197 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " | 196 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " |
| 198 | "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, | 197 | "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, |
| @@ -207,7 +206,6 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | |||
| 207 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 206 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
| 208 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 207 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 209 | u32 original_value, bitshift; | 208 | u32 original_value, bitshift; |
| 210 | unsigned long flags; | ||
| 211 | 209 | ||
| 212 | if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) | 210 | if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) |
| 213 | return; | 211 | return; |
| @@ -215,7 +213,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | |||
| 215 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | 213 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," |
| 216 | " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); | 214 | " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); |
| 217 | 215 | ||
| 218 | spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); | 216 | spin_lock(&rtlpriv->locks.rf_lock); |
| 219 | 217 | ||
| 220 | if (bitmask != RFREG_OFFSET_MASK) { | 218 | if (bitmask != RFREG_OFFSET_MASK) { |
| 221 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, | 219 | original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, |
| @@ -226,7 +224,7 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, | |||
| 226 | 224 | ||
| 227 | _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); | 225 | _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); |
| 228 | 226 | ||
| 229 | spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); | 227 | spin_unlock(&rtlpriv->locks.rf_lock); |
| 230 | 228 | ||
| 231 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " | 229 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " |
| 232 | "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); | 230 | "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); |
| @@ -263,7 +261,6 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, | |||
| 263 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | 261 | struct rtl_phy *rtlphy = &(rtlpriv->phy); |
| 264 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 262 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
| 265 | u8 reg_bw_opmode; | 263 | u8 reg_bw_opmode; |
| 266 | u8 reg_prsr_rsc; | ||
| 267 | 264 | ||
| 268 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", | 265 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", |
| 269 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? | 266 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? |
| @@ -277,7 +274,8 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, | |||
| 277 | rtlphy->set_bwmode_inprogress = true; | 274 | rtlphy->set_bwmode_inprogress = true; |
| 278 | 275 | ||
| 279 | reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); | 276 | reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); |
| 280 | reg_prsr_rsc = rtl_read_byte(rtlpriv, RRSR + 2); | 277 | /* dummy read */ |
| 278 | rtl_read_byte(rtlpriv, RRSR + 2); | ||
| 281 | 279 | ||
| 282 | switch (rtlphy->current_chan_bw) { | 280 | switch (rtlphy->current_chan_bw) { |
| 283 | case HT_CHANNEL_WIDTH_20: | 281 | case HT_CHANNEL_WIDTH_20: |
| @@ -546,8 +544,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 546 | if (rfpwr_state == ppsc->rfpwr_state) | 544 | if (rfpwr_state == ppsc->rfpwr_state) |
| 547 | return false; | 545 | return false; |
| 548 | 546 | ||
| 549 | ppsc->set_rfpowerstate_inprogress = true; | ||
| 550 | |||
| 551 | switch (rfpwr_state) { | 547 | switch (rfpwr_state) { |
| 552 | case ERFON:{ | 548 | case ERFON:{ |
| 553 | if ((ppsc->rfpwr_state == ERFOFF) && | 549 | if ((ppsc->rfpwr_state == ERFOFF) && |
| @@ -659,8 +655,6 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, | |||
| 659 | if (bresult) | 655 | if (bresult) |
| 660 | ppsc->rfpwr_state = rfpwr_state; | 656 | ppsc->rfpwr_state = rfpwr_state; |
| 661 | 657 | ||
| 662 | ppsc->set_rfpowerstate_inprogress = false; | ||
| 663 | |||
| 664 | return bresult; | 658 | return bresult; |
| 665 | } | 659 | } |
| 666 | 660 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 5cf442373d46..d509cf6a1e4d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
| @@ -581,7 +581,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 581 | struct ieee80211_hdr *hdr; | 581 | struct ieee80211_hdr *hdr; |
| 582 | u8 *tmp_buf; | 582 | u8 *tmp_buf; |
| 583 | u8 *praddr; | 583 | u8 *praddr; |
| 584 | u8 *psaddr; | ||
| 585 | __le16 fc; | 584 | __le16 fc; |
| 586 | u16 type, cfc; | 585 | u16 type, cfc; |
| 587 | bool packet_matchbssid, packet_toself, packet_beacon; | 586 | bool packet_matchbssid, packet_toself, packet_beacon; |
| @@ -593,7 +592,6 @@ static void _rtl92se_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
| 593 | cfc = le16_to_cpu(fc); | 592 | cfc = le16_to_cpu(fc); |
| 594 | type = WLAN_FC_GET_TYPE(fc); | 593 | type = WLAN_FC_GET_TYPE(fc); |
| 595 | praddr = hdr->addr1; | 594 | praddr = hdr->addr1; |
| 596 | psaddr = hdr->addr2; | ||
| 597 | 595 | ||
| 598 | packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && | 596 | packet_matchbssid = ((IEEE80211_FTYPE_CTL != type) && |
| 599 | (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? | 597 | (!compare_ether_addr(mac->bssid, (cfc & IEEE80211_FCTL_TODS) ? |
| @@ -875,6 +873,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | |||
| 875 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); | 873 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); |
| 876 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | 874 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); |
| 877 | 875 | ||
| 876 | wmb(); | ||
| 878 | SET_TX_DESC_OWN(pdesc, 1); | 877 | SET_TX_DESC_OWN(pdesc, 1); |
| 879 | } else { /* H2C Command Desc format (Host TXCMD) */ | 878 | } else { /* H2C Command Desc format (Host TXCMD) */ |
| 880 | /* 92SE must set as 1 for firmware download HW DMA error */ | 879 | /* 92SE must set as 1 for firmware download HW DMA error */ |
| @@ -893,6 +892,7 @@ void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, | |||
| 893 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); | 892 | SET_TX_DESC_TX_BUFFER_SIZE(pdesc, (u16)(skb->len)); |
| 894 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); | 893 | SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); |
| 895 | 894 | ||
| 895 | wmb(); | ||
| 896 | SET_TX_DESC_OWN(pdesc, 1); | 896 | SET_TX_DESC_OWN(pdesc, 1); |
| 897 | 897 | ||
| 898 | } | 898 | } |
| @@ -903,6 +903,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | |||
| 903 | if (istx == true) { | 903 | if (istx == true) { |
| 904 | switch (desc_name) { | 904 | switch (desc_name) { |
| 905 | case HW_DESC_OWN: | 905 | case HW_DESC_OWN: |
| 906 | wmb(); | ||
| 906 | SET_TX_DESC_OWN(pdesc, 1); | 907 | SET_TX_DESC_OWN(pdesc, 1); |
| 907 | break; | 908 | break; |
| 908 | case HW_DESC_TX_NEXTDESC_ADDR: | 909 | case HW_DESC_TX_NEXTDESC_ADDR: |
| @@ -916,6 +917,7 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) | |||
| 916 | } else { | 917 | } else { |
| 917 | switch (desc_name) { | 918 | switch (desc_name) { |
| 918 | case HW_DESC_RXOWN: | 919 | case HW_DESC_RXOWN: |
| 920 | wmb(); | ||
| 919 | SET_RX_STATUS_DESC_OWN(pdesc, 1); | 921 | SET_RX_STATUS_DESC_OWN(pdesc, 1); |
| 920 | break; | 922 | break; |
| 921 | case HW_DESC_RXBUFF_ADDR: | 923 | case HW_DESC_RXBUFF_ADDR: |
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 693395ee98f9..9d003e0864f5 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
| @@ -1188,7 +1188,6 @@ struct rtl_efuse { | |||
| 1188 | 1188 | ||
| 1189 | struct rtl_ps_ctl { | 1189 | struct rtl_ps_ctl { |
| 1190 | bool pwrdomain_protect; | 1190 | bool pwrdomain_protect; |
| 1191 | bool set_rfpowerstate_inprogress; | ||
| 1192 | bool in_powersavemode; | 1191 | bool in_powersavemode; |
| 1193 | bool rfchange_inprogress; | 1192 | bool rfchange_inprogress; |
| 1194 | bool swrf_processing; | 1193 | bool swrf_processing; |
| @@ -1536,6 +1535,7 @@ struct rtl_works { | |||
| 1536 | /* For SW LPS */ | 1535 | /* For SW LPS */ |
| 1537 | struct delayed_work ps_work; | 1536 | struct delayed_work ps_work; |
| 1538 | struct delayed_work ps_rfon_wq; | 1537 | struct delayed_work ps_rfon_wq; |
| 1538 | struct tasklet_struct ips_leave_tasklet; | ||
| 1539 | }; | 1539 | }; |
| 1540 | 1540 | ||
| 1541 | struct rtl_debug { | 1541 | struct rtl_debug { |
diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c index b07f8b7e5f11..7ccec07a600c 100644 --- a/drivers/net/wireless/wl12xx/boot.c +++ b/drivers/net/wireless/wl12xx/boot.c | |||
| @@ -485,7 +485,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl) | |||
| 485 | if (wl->bss_type == BSS_TYPE_AP_BSS) | 485 | if (wl->bss_type == BSS_TYPE_AP_BSS) |
| 486 | wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; | 486 | wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID; |
| 487 | else | 487 | else |
| 488 | wl->event_mask |= DUMMY_PACKET_EVENT_ID; | 488 | wl->event_mask |= DUMMY_PACKET_EVENT_ID | |
| 489 | BA_SESSION_RX_CONSTRAINT_EVENT_ID; | ||
| 489 | 490 | ||
| 490 | ret = wl1271_event_unmask(wl); | 491 | ret = wl1271_event_unmask(wl); |
| 491 | if (ret < 0) { | 492 | if (ret < 0) { |
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index c3c554cd6580..94bbd00ec31b 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
| @@ -168,6 +168,21 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl, | |||
| 168 | wl->last_rssi_event = event; | 168 | wl->last_rssi_event = event; |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed) | ||
| 172 | { | ||
| 173 | /* Convert the value to bool */ | ||
| 174 | wl->ba_allowed = !!ba_allowed; | ||
| 175 | |||
| 176 | /* | ||
| 177 | * Return in case: | ||
| 178 | * there are not BA open or the event indication is to allowed BA | ||
| 179 | */ | ||
| 180 | if ((!wl->ba_rx_bitmap) || (wl->ba_allowed)) | ||
| 181 | return; | ||
| 182 | |||
| 183 | ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid); | ||
| 184 | } | ||
| 185 | |||
| 171 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) | 186 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) |
| 172 | { | 187 | { |
| 173 | wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); | 188 | wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); |
| @@ -252,6 +267,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
| 252 | wl1271_event_rssi_trigger(wl, mbox); | 267 | wl1271_event_rssi_trigger(wl, mbox); |
| 253 | } | 268 | } |
| 254 | 269 | ||
| 270 | if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) { | ||
| 271 | wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. " | ||
| 272 | "ba_allowed = 0x%x", mbox->ba_allowed); | ||
| 273 | |||
| 274 | if (wl->vif) | ||
| 275 | wl1271_stop_ba_event(wl, mbox->ba_allowed); | ||
| 276 | } | ||
| 277 | |||
| 255 | if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) { | 278 | if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) { |
| 256 | wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); | 279 | wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); |
| 257 | if (wl->vif) | 280 | if (wl->vif) |
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h index b6cf06e565a4..ce99adf4256e 100644 --- a/drivers/net/wireless/wl12xx/event.h +++ b/drivers/net/wireless/wl12xx/event.h | |||
| @@ -71,7 +71,7 @@ enum { | |||
| 71 | HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), | 71 | HEALTH_CHECK_REPLY_EVENT_ID = BIT(27), |
| 72 | PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), | 72 | PERIODIC_SCAN_COMPLETE_EVENT_ID = BIT(28), |
| 73 | PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), | 73 | PERIODIC_SCAN_REPORT_EVENT_ID = BIT(29), |
| 74 | BA_SESSION_TEAR_DOWN_EVENT_ID = BIT(30), | 74 | BA_SESSION_RX_CONSTRAINT_EVENT_ID = BIT(30), |
| 75 | EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, | 75 | EVENT_MBOX_ALL_EVENT_ID = 0x7fffffff, |
| 76 | }; | 76 | }; |
| 77 | 77 | ||
| @@ -122,7 +122,20 @@ struct event_mailbox { | |||
| 122 | __le16 sta_aging_status; | 122 | __le16 sta_aging_status; |
| 123 | __le16 sta_tx_retry_exceeded; | 123 | __le16 sta_tx_retry_exceeded; |
| 124 | 124 | ||
| 125 | u8 reserved_5[24]; | 125 | /* |
| 126 | * Bitmap, Each bit set represents the Role ID for which this constraint | ||
| 127 | * is set. Range: 0 - FF, FF means ANY role | ||
| 128 | */ | ||
| 129 | u8 ba_role_id; | ||
| 130 | /* | ||
| 131 | * Bitmap, Each bit set represents the Link ID for which this constraint | ||
| 132 | * is set. Not applicable if ba_role_id is set to ANY role (FF). | ||
| 133 | * Range: 0 - FFFF, FFFF means ANY link in that role | ||
| 134 | */ | ||
| 135 | u8 ba_link_id; | ||
| 136 | u8 ba_allowed; | ||
| 137 | |||
| 138 | u8 reserved_5[21]; | ||
| 126 | } __packed; | 139 | } __packed; |
| 127 | 140 | ||
| 128 | int wl1271_event_unmask(struct wl1271 *wl); | 141 | int wl1271_event_unmask(struct wl1271 *wl); |
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c index a8f4f156c055..f5c2c9e6f84b 100644 --- a/drivers/net/wireless/wl12xx/init.c +++ b/drivers/net/wireless/wl12xx/init.c | |||
| @@ -541,6 +541,7 @@ static int wl1271_set_ba_policies(struct wl1271 *wl) | |||
| 541 | 541 | ||
| 542 | /* Reset the BA RX indicators */ | 542 | /* Reset the BA RX indicators */ |
| 543 | wl->ba_rx_bitmap = 0; | 543 | wl->ba_rx_bitmap = 0; |
| 544 | wl->ba_allowed = true; | ||
| 544 | 545 | ||
| 545 | /* validate that FW support BA */ | 546 | /* validate that FW support BA */ |
| 546 | wl1271_check_ba_support(wl); | 547 | wl1271_check_ba_support(wl); |
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index e6497dc669df..f37f0b873c73 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c | |||
| @@ -3354,9 +3354,12 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw, | |||
| 3354 | if (ret < 0) | 3354 | if (ret < 0) |
| 3355 | goto out; | 3355 | goto out; |
| 3356 | 3356 | ||
| 3357 | wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d", | ||
| 3358 | tid, action); | ||
| 3359 | |||
| 3357 | switch (action) { | 3360 | switch (action) { |
| 3358 | case IEEE80211_AMPDU_RX_START: | 3361 | case IEEE80211_AMPDU_RX_START: |
| 3359 | if (wl->ba_support) { | 3362 | if ((wl->ba_support) && (wl->ba_allowed)) { |
| 3360 | ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn, | 3363 | ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn, |
| 3361 | true); | 3364 | true); |
| 3362 | if (!ret) | 3365 | if (!ret) |
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index fbe8f46d1232..3bc794a1ee75 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h | |||
| @@ -564,6 +564,7 @@ struct wl1271 { | |||
| 564 | /* RX BA constraint value */ | 564 | /* RX BA constraint value */ |
| 565 | bool ba_support; | 565 | bool ba_support; |
| 566 | u8 ba_rx_bitmap; | 566 | u8 ba_rx_bitmap; |
| 567 | bool ba_allowed; | ||
| 567 | 568 | ||
| 568 | int tcxo_clock; | 569 | int tcxo_clock; |
| 569 | 570 | ||
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 82feb348c8bb..2a20dabec76d 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
| @@ -539,10 +539,12 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
| 539 | if (!pc->hostmode) | 539 | if (!pc->hostmode) |
| 540 | ssb_pcicore_init_clientmode(pc); | 540 | ssb_pcicore_init_clientmode(pc); |
| 541 | 541 | ||
| 542 | /* Additional always once-executed workarounds */ | 542 | /* Additional PCIe always once-executed workarounds */ |
| 543 | ssb_pcicore_serdes_workaround(pc); | 543 | if (dev->id.coreid == SSB_DEV_PCIE) { |
| 544 | /* TODO: ASPM */ | 544 | ssb_pcicore_serdes_workaround(pc); |
| 545 | /* TODO: Clock Request Update */ | 545 | /* TODO: ASPM */ |
| 546 | /* TODO: Clock Request Update */ | ||
| 547 | } | ||
| 546 | } | 548 | } |
| 547 | 549 | ||
| 548 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) | 550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 08763e4e848f..6ff080eac0b2 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | 6 | ||
| 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/ssb/ssb.h> /* SPROM sharing */ | ||
| 9 | 10 | ||
| 10 | #include "bcma_regs.h" | 11 | #include "bcma_regs.h" |
| 11 | 12 | ||
| @@ -31,6 +32,12 @@ struct bcma_host_ops { | |||
| 31 | void (*write8)(struct bcma_device *core, u16 offset, u8 value); | 32 | void (*write8)(struct bcma_device *core, u16 offset, u8 value); |
| 32 | void (*write16)(struct bcma_device *core, u16 offset, u16 value); | 33 | void (*write16)(struct bcma_device *core, u16 offset, u16 value); |
| 33 | void (*write32)(struct bcma_device *core, u16 offset, u32 value); | 34 | void (*write32)(struct bcma_device *core, u16 offset, u32 value); |
| 35 | #ifdef CONFIG_BCMA_BLOCKIO | ||
| 36 | void (*block_read)(struct bcma_device *core, void *buffer, | ||
| 37 | size_t count, u16 offset, u8 reg_width); | ||
| 38 | void (*block_write)(struct bcma_device *core, const void *buffer, | ||
| 39 | size_t count, u16 offset, u8 reg_width); | ||
| 40 | #endif | ||
| 34 | /* Agent ops */ | 41 | /* Agent ops */ |
| 35 | u32 (*aread32)(struct bcma_device *core, u16 offset); | 42 | u32 (*aread32)(struct bcma_device *core, u16 offset); |
| 36 | void (*awrite32)(struct bcma_device *core, u16 offset, u32 value); | 43 | void (*awrite32)(struct bcma_device *core, u16 offset, u32 value); |
| @@ -117,6 +124,8 @@ struct bcma_device { | |||
| 117 | struct bcma_device_id id; | 124 | struct bcma_device_id id; |
| 118 | 125 | ||
| 119 | struct device dev; | 126 | struct device dev; |
| 127 | struct device *dma_dev; | ||
| 128 | unsigned int irq; | ||
| 120 | bool dev_registered; | 129 | bool dev_registered; |
| 121 | 130 | ||
| 122 | u8 core_index; | 131 | u8 core_index; |
| @@ -179,6 +188,10 @@ struct bcma_bus { | |||
| 179 | 188 | ||
| 180 | struct bcma_drv_cc drv_cc; | 189 | struct bcma_drv_cc drv_cc; |
| 181 | struct bcma_drv_pci drv_pci; | 190 | struct bcma_drv_pci drv_pci; |
| 191 | |||
| 192 | /* We decided to share SPROM struct with SSB as long as we do not need | ||
| 193 | * any hacks for BCMA. This simplifies drivers code. */ | ||
| 194 | struct ssb_sprom sprom; | ||
| 182 | }; | 195 | }; |
| 183 | 196 | ||
| 184 | extern inline u32 bcma_read8(struct bcma_device *core, u16 offset) | 197 | extern inline u32 bcma_read8(struct bcma_device *core, u16 offset) |
| @@ -208,6 +221,18 @@ void bcma_write32(struct bcma_device *core, u16 offset, u32 value) | |||
| 208 | { | 221 | { |
| 209 | core->bus->ops->write32(core, offset, value); | 222 | core->bus->ops->write32(core, offset, value); |
| 210 | } | 223 | } |
| 224 | #ifdef CONFIG_BCMA_BLOCKIO | ||
| 225 | extern inline void bcma_block_read(struct bcma_device *core, void *buffer, | ||
| 226 | size_t count, u16 offset, u8 reg_width) | ||
| 227 | { | ||
| 228 | core->bus->ops->block_read(core, buffer, count, offset, reg_width); | ||
| 229 | } | ||
| 230 | extern inline void bcma_block_write(struct bcma_device *core, const void *buffer, | ||
| 231 | size_t count, u16 offset, u8 reg_width) | ||
| 232 | { | ||
| 233 | core->bus->ops->block_write(core, buffer, count, offset, reg_width); | ||
| 234 | } | ||
| 235 | #endif | ||
| 211 | extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset) | 236 | extern inline u32 bcma_aread32(struct bcma_device *core, u16 offset) |
| 212 | { | 237 | { |
| 213 | return core->bus->ops->aread32(core, offset); | 238 | return core->bus->ops->aread32(core, offset); |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 083c3b6cd5ce..9c5b69fc985a 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
| @@ -244,6 +244,7 @@ | |||
| 244 | #define BCMA_CC_REGCTL_DATA 0x065C | 244 | #define BCMA_CC_REGCTL_DATA 0x065C |
| 245 | #define BCMA_CC_PLLCTL_ADDR 0x0660 | 245 | #define BCMA_CC_PLLCTL_ADDR 0x0660 |
| 246 | #define BCMA_CC_PLLCTL_DATA 0x0664 | 246 | #define BCMA_CC_PLLCTL_DATA 0x0664 |
| 247 | #define BCMA_CC_SPROM 0x0830 /* SPROM beginning */ | ||
| 247 | 248 | ||
| 248 | /* Data for the PMU, if available. | 249 | /* Data for the PMU, if available. |
| 249 | * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) | 250 | * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) |
diff --git a/include/linux/cordic.h b/include/linux/cordic.h new file mode 100644 index 000000000000..f932093e20c2 --- /dev/null +++ b/include/linux/cordic.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #ifndef __CORDIC_H_ | ||
| 17 | #define __CORDIC_H_ | ||
| 18 | |||
| 19 | #include <linux/types.h> | ||
| 20 | |||
| 21 | /** | ||
| 22 | * struct cordic_iq - i/q coordinate. | ||
| 23 | * | ||
| 24 | * @i: real part of coordinate (in phase). | ||
| 25 | * @q: imaginary part of coordinate (quadrature). | ||
| 26 | */ | ||
| 27 | struct cordic_iq { | ||
| 28 | s32 i; | ||
| 29 | s32 q; | ||
| 30 | }; | ||
| 31 | |||
| 32 | /** | ||
| 33 | * cordic_calc_iq() - calculates the i/q coordinate for given angle. | ||
| 34 | * | ||
| 35 | * @theta: angle in degrees for which i/q coordinate is to be calculated. | ||
| 36 | * @coord: function output parameter holding the i/q coordinate. | ||
| 37 | * | ||
| 38 | * The function calculates the i/q coordinate for a given angle using | ||
| 39 | * cordic algorithm. The coordinate consists of a real (i) and an | ||
| 40 | * imaginary (q) part. The real part is essentially the cosine of the | ||
| 41 | * angle and the imaginary part is the sine of the angle. The returned | ||
| 42 | * values are scaled by 2^16 for precision. The range for theta is | ||
| 43 | * for -180 degrees to +180 degrees. Passed values outside this range are | ||
| 44 | * converted before doing the actual calculation. | ||
| 45 | */ | ||
| 46 | struct cordic_iq cordic_calc_iq(s32 theta); | ||
| 47 | |||
| 48 | #endif /* __CORDIC_H_ */ | ||
diff --git a/include/linux/crc8.h b/include/linux/crc8.h new file mode 100644 index 000000000000..13c8dabb0441 --- /dev/null +++ b/include/linux/crc8.h | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #ifndef __CRC8_H_ | ||
| 17 | #define __CRC8_H_ | ||
| 18 | |||
| 19 | #include <linux/types.h> | ||
| 20 | |||
| 21 | /* see usage of this value in crc8() description */ | ||
| 22 | #define CRC8_INIT_VALUE 0xFF | ||
| 23 | |||
| 24 | /* | ||
| 25 | * Return value of crc8() indicating valid message+crc. This is true | ||
| 26 | * if a CRC is inverted before transmission. The CRC computed over the | ||
| 27 | * whole received bitstream is _table[x], where x is the bit pattern | ||
| 28 | * of the modification (almost always 0xff). | ||
| 29 | */ | ||
| 30 | #define CRC8_GOOD_VALUE(_table) (_table[0xFF]) | ||
| 31 | |||
| 32 | /* required table size for crc8 algorithm */ | ||
| 33 | #define CRC8_TABLE_SIZE 256 | ||
| 34 | |||
| 35 | /* helper macro assuring right table size is used */ | ||
| 36 | #define DECLARE_CRC8_TABLE(_table) \ | ||
| 37 | static u8 _table[CRC8_TABLE_SIZE] | ||
| 38 | |||
| 39 | /** | ||
| 40 | * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. | ||
| 41 | * | ||
| 42 | * @table: table to be filled. | ||
| 43 | * @polynomial: polynomial for which table is to be filled. | ||
| 44 | * | ||
| 45 | * This function fills the provided table according the polynomial provided for | ||
| 46 | * regular bit order (lsb first). Polynomials in CRC algorithms are typically | ||
| 47 | * represented as shown below. | ||
| 48 | * | ||
| 49 | * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 | ||
| 50 | * | ||
| 51 | * For lsb first direction x^7 maps to the lsb. So the polynomial is as below. | ||
| 52 | * | ||
| 53 | * - lsb first: poly = 10101011(1) = 0xAB | ||
| 54 | */ | ||
| 55 | void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); | ||
| 56 | |||
| 57 | /** | ||
| 58 | * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. | ||
| 59 | * | ||
| 60 | * @table: table to be filled. | ||
| 61 | * @polynomial: polynomial for which table is to be filled. | ||
| 62 | * | ||
| 63 | * This function fills the provided table according the polynomial provided for | ||
| 64 | * reverse bit order (msb first). Polynomials in CRC algorithms are typically | ||
| 65 | * represented as shown below. | ||
| 66 | * | ||
| 67 | * poly = x^8 + x^7 + x^6 + x^4 + x^2 + 1 | ||
| 68 | * | ||
| 69 | * For msb first direction x^7 maps to the msb. So the polynomial is as below. | ||
| 70 | * | ||
| 71 | * - msb first: poly = (1)11010101 = 0xD5 | ||
| 72 | */ | ||
| 73 | void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial); | ||
| 74 | |||
| 75 | /** | ||
| 76 | * crc8() - calculate a crc8 over the given input data. | ||
| 77 | * | ||
| 78 | * @table: crc table used for calculation. | ||
| 79 | * @pdata: pointer to data buffer. | ||
| 80 | * @nbytes: number of bytes in data buffer. | ||
| 81 | * @crc: previous returned crc8 value. | ||
| 82 | * | ||
| 83 | * The CRC8 is calculated using the polynomial given in crc8_populate_msb() | ||
| 84 | * or crc8_populate_lsb(). | ||
| 85 | * | ||
| 86 | * The caller provides the initial value (either %CRC8_INIT_VALUE | ||
| 87 | * or the previous returned value) to allow for processing of | ||
| 88 | * discontiguous blocks of data. When generating the CRC the | ||
| 89 | * caller is responsible for complementing the final return value | ||
| 90 | * and inserting it into the byte stream. When validating a byte | ||
| 91 | * stream (including CRC8), a final return value of %CRC8_GOOD_VALUE | ||
| 92 | * indicates the byte stream data can be considered valid. | ||
| 93 | * | ||
| 94 | * Reference: | ||
| 95 | * "A Painless Guide to CRC Error Detection Algorithms", ver 3, Aug 1993 | ||
| 96 | * Williams, Ross N., ross<at>ross.net | ||
| 97 | * (see URL http://www.ross.net/crc/download/crc_v3.txt). | ||
| 98 | */ | ||
| 99 | u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc); | ||
| 100 | |||
| 101 | #endif /* __CRC8_H_ */ | ||
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0589f554788a..6cb2543a2ee1 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
| @@ -1284,6 +1284,12 @@ struct cfg80211_wowlan { | |||
| 1284 | * frame on another channel | 1284 | * frame on another channel |
| 1285 | * | 1285 | * |
| 1286 | * @testmode_cmd: run a test mode command | 1286 | * @testmode_cmd: run a test mode command |
| 1287 | * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be | ||
| 1288 | * used by the function, but 0 and 1 must not be touched. Additionally, | ||
| 1289 | * return error codes other than -ENOBUFS and -ENOENT will terminate the | ||
| 1290 | * dump and return to userspace with an error, so be careful. If any data | ||
| 1291 | * was passed in from userspace then the data/len arguments will be present | ||
| 1292 | * and point to the data contained in %NL80211_ATTR_TESTDATA. | ||
| 1287 | * | 1293 | * |
| 1288 | * @set_bitrate_mask: set the bitrate mask configuration | 1294 | * @set_bitrate_mask: set the bitrate mask configuration |
| 1289 | * | 1295 | * |
| @@ -1433,6 +1439,9 @@ struct cfg80211_ops { | |||
| 1433 | 1439 | ||
| 1434 | #ifdef CONFIG_NL80211_TESTMODE | 1440 | #ifdef CONFIG_NL80211_TESTMODE |
| 1435 | int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); | 1441 | int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); |
| 1442 | int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, | ||
| 1443 | struct netlink_callback *cb, | ||
| 1444 | void *data, int len); | ||
| 1436 | #endif | 1445 | #endif |
| 1437 | 1446 | ||
| 1438 | int (*set_bitrate_mask)(struct wiphy *wiphy, | 1447 | int (*set_bitrate_mask)(struct wiphy *wiphy, |
| @@ -2849,8 +2858,10 @@ struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | |||
| 2849 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); | 2858 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); |
| 2850 | 2859 | ||
| 2851 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), | 2860 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), |
| 2861 | #define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), | ||
| 2852 | #else | 2862 | #else |
| 2853 | #define CFG80211_TESTMODE_CMD(cmd) | 2863 | #define CFG80211_TESTMODE_CMD(cmd) |
| 2864 | #define CFG80211_TESTMODE_DUMP(cmd) | ||
| 2854 | #endif | 2865 | #endif |
| 2855 | 2866 | ||
| 2856 | /** | 2867 | /** |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index e6d6a66a8f71..3b31ec95dd8e 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
| @@ -1816,6 +1816,7 @@ enum ieee80211_ampdu_mlme_action { | |||
| 1816 | * | 1816 | * |
| 1817 | * @testmode_cmd: Implement a cfg80211 test mode command. | 1817 | * @testmode_cmd: Implement a cfg80211 test mode command. |
| 1818 | * The callback can sleep. | 1818 | * The callback can sleep. |
| 1819 | * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep. | ||
| 1819 | * | 1820 | * |
| 1820 | * @flush: Flush all pending frames from the hardware queue, making sure | 1821 | * @flush: Flush all pending frames from the hardware queue, making sure |
| 1821 | * that the hardware queues are empty. If the parameter @drop is set | 1822 | * that the hardware queues are empty. If the parameter @drop is set |
| @@ -1936,6 +1937,9 @@ struct ieee80211_ops { | |||
| 1936 | void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); | 1937 | void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); |
| 1937 | #ifdef CONFIG_NL80211_TESTMODE | 1938 | #ifdef CONFIG_NL80211_TESTMODE |
| 1938 | int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); | 1939 | int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); |
| 1940 | int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
| 1941 | struct netlink_callback *cb, | ||
| 1942 | void *data, int len); | ||
| 1939 | #endif | 1943 | #endif |
| 1940 | void (*flush)(struct ieee80211_hw *hw, bool drop); | 1944 | void (*flush)(struct ieee80211_hw *hw, bool drop); |
| 1941 | void (*channel_switch)(struct ieee80211_hw *hw, | 1945 | void (*channel_switch)(struct ieee80211_hw *hw, |
| @@ -2965,6 +2969,23 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw); | |||
| 2965 | */ | 2969 | */ |
| 2966 | void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw); | 2970 | void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw); |
| 2967 | 2971 | ||
| 2972 | /** | ||
| 2973 | * ieee80211_stop_rx_ba_session - callback to stop existing BA sessions | ||
| 2974 | * | ||
| 2975 | * in order not to harm the system performance and user experience, the device | ||
| 2976 | * may request not to allow any rx ba session and tear down existing rx ba | ||
| 2977 | * sessions based on system constraints such as periodic BT activity that needs | ||
| 2978 | * to limit wlan activity (eg.sco or a2dp)." | ||
| 2979 | * in such cases, the intention is to limit the duration of the rx ppdu and | ||
| 2980 | * therefore prevent the peer device to use a-mpdu aggregation. | ||
| 2981 | * | ||
| 2982 | * @vif: &struct ieee80211_vif pointer from the add_interface callback. | ||
| 2983 | * @ba_rx_bitmap: Bit map of open rx ba per tid | ||
| 2984 | * @addr: & to bssid mac address | ||
| 2985 | */ | ||
| 2986 | void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, | ||
| 2987 | const u8 *addr); | ||
| 2988 | |||
| 2968 | /* Rate control API */ | 2989 | /* Rate control API */ |
| 2969 | 2990 | ||
| 2970 | /** | 2991 | /** |
diff --git a/lib/Kconfig b/lib/Kconfig index 830181cc7a83..32f3e5ae2be5 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
| @@ -79,6 +79,13 @@ config LIBCRC32C | |||
| 79 | require M here. See Castagnoli93. | 79 | require M here. See Castagnoli93. |
| 80 | Module will be libcrc32c. | 80 | Module will be libcrc32c. |
| 81 | 81 | ||
| 82 | config CRC8 | ||
| 83 | tristate "CRC8 function" | ||
| 84 | help | ||
| 85 | This option provides CRC8 function. Drivers may select this | ||
| 86 | when they need to do cyclic redundancy check according CRC8 | ||
| 87 | algorithm. Module will be called crc8. | ||
| 88 | |||
| 82 | config AUDIT_GENERIC | 89 | config AUDIT_GENERIC |
| 83 | bool | 90 | bool |
| 84 | depends on AUDIT && !AUDIT_ARCH | 91 | depends on AUDIT && !AUDIT_ARCH |
| @@ -262,4 +269,11 @@ config AVERAGE | |||
| 262 | 269 | ||
| 263 | If unsure, say N. | 270 | If unsure, say N. |
| 264 | 271 | ||
| 272 | config CORDIC | ||
| 273 | tristate "Cordic function" | ||
| 274 | help | ||
| 275 | The option provides arithmetic function using cordic algorithm | ||
| 276 | so its calculations are in fixed point. Modules can select this | ||
| 277 | when they require this function. Module will be called cordic. | ||
| 278 | |||
| 265 | endmenu | 279 | endmenu |
diff --git a/lib/Makefile b/lib/Makefile index 6b597fdb1898..892f4e282ea1 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -61,6 +61,7 @@ obj-$(CONFIG_CRC_ITU_T) += crc-itu-t.o | |||
| 61 | obj-$(CONFIG_CRC32) += crc32.o | 61 | obj-$(CONFIG_CRC32) += crc32.o |
| 62 | obj-$(CONFIG_CRC7) += crc7.o | 62 | obj-$(CONFIG_CRC7) += crc7.o |
| 63 | obj-$(CONFIG_LIBCRC32C) += libcrc32c.o | 63 | obj-$(CONFIG_LIBCRC32C) += libcrc32c.o |
| 64 | obj-$(CONFIG_CRC8) += crc8.o | ||
| 64 | obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o | 65 | obj-$(CONFIG_GENERIC_ALLOCATOR) += genalloc.o |
| 65 | 66 | ||
| 66 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ | 67 | obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate/ |
| @@ -112,6 +113,8 @@ obj-$(CONFIG_AVERAGE) += average.o | |||
| 112 | 113 | ||
| 113 | obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o | 114 | obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o |
| 114 | 115 | ||
| 116 | obj-$(CONFIG_CORDIC) += cordic.o | ||
| 117 | |||
| 115 | hostprogs-y := gen_crc32table | 118 | hostprogs-y := gen_crc32table |
| 116 | clean-files := crc32table.h | 119 | clean-files := crc32table.h |
| 117 | 120 | ||
diff --git a/lib/cordic.c b/lib/cordic.c new file mode 100644 index 000000000000..aa27a88d7e04 --- /dev/null +++ b/lib/cordic.c | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/cordic.h> | ||
| 18 | |||
| 19 | #define CORDIC_ANGLE_GEN 39797 | ||
| 20 | #define CORDIC_PRECISION_SHIFT 16 | ||
| 21 | #define CORDIC_NUM_ITER (CORDIC_PRECISION_SHIFT + 2) | ||
| 22 | |||
| 23 | #define FIXED(X) ((s32)((X) << CORDIC_PRECISION_SHIFT)) | ||
| 24 | #define FLOAT(X) (((X) >= 0) \ | ||
| 25 | ? ((((X) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1) \ | ||
| 26 | : -((((-(X)) >> (CORDIC_PRECISION_SHIFT - 1)) + 1) >> 1)) | ||
| 27 | |||
| 28 | static const s32 arctan_table[] = { | ||
| 29 | 2949120, | ||
| 30 | 1740967, | ||
| 31 | 919879, | ||
| 32 | 466945, | ||
| 33 | 234379, | ||
| 34 | 117304, | ||
| 35 | 58666, | ||
| 36 | 29335, | ||
| 37 | 14668, | ||
| 38 | 7334, | ||
| 39 | 3667, | ||
| 40 | 1833, | ||
| 41 | 917, | ||
| 42 | 458, | ||
| 43 | 229, | ||
| 44 | 115, | ||
| 45 | 57, | ||
| 46 | 29 | ||
| 47 | }; | ||
| 48 | |||
| 49 | /* | ||
| 50 | * cordic_calc_iq() - calculates the i/q coordinate for given angle | ||
| 51 | * | ||
| 52 | * theta: angle in degrees for which i/q coordinate is to be calculated | ||
| 53 | * coord: function output parameter holding the i/q coordinate | ||
| 54 | */ | ||
| 55 | struct cordic_iq cordic_calc_iq(s32 theta) | ||
| 56 | { | ||
| 57 | struct cordic_iq coord; | ||
| 58 | s32 angle, valtmp; | ||
| 59 | unsigned iter; | ||
| 60 | int signx = 1; | ||
| 61 | int signtheta; | ||
| 62 | |||
| 63 | coord.i = CORDIC_ANGLE_GEN; | ||
| 64 | coord.q = 0; | ||
| 65 | angle = 0; | ||
| 66 | |||
| 67 | theta = FIXED(theta); | ||
| 68 | signtheta = (theta < 0) ? -1 : 1; | ||
| 69 | theta = ((theta + FIXED(180) * signtheta) % FIXED(360)) - | ||
| 70 | FIXED(180) * signtheta; | ||
| 71 | |||
| 72 | if (FLOAT(theta) > 90) { | ||
| 73 | theta -= FIXED(180); | ||
| 74 | signx = -1; | ||
| 75 | } else if (FLOAT(theta) < -90) { | ||
| 76 | theta += FIXED(180); | ||
| 77 | signx = -1; | ||
| 78 | } | ||
| 79 | |||
| 80 | for (iter = 0; iter < CORDIC_NUM_ITER; iter++) { | ||
| 81 | if (theta > angle) { | ||
| 82 | valtmp = coord.i - (coord.q >> iter); | ||
| 83 | coord.q += (coord.i >> iter); | ||
| 84 | angle += arctan_table[iter]; | ||
| 85 | } else { | ||
| 86 | valtmp = coord.i + (coord.q >> iter); | ||
| 87 | coord.q -= (coord.i >> iter); | ||
| 88 | angle -= arctan_table[iter]; | ||
| 89 | } | ||
| 90 | coord.i = valtmp; | ||
| 91 | } | ||
| 92 | |||
| 93 | coord.i *= signx; | ||
| 94 | coord.q *= signx; | ||
| 95 | return coord; | ||
| 96 | } | ||
| 97 | EXPORT_SYMBOL(cordic_calc_iq); | ||
| 98 | |||
| 99 | MODULE_DESCRIPTION("Cordic functions"); | ||
| 100 | MODULE_AUTHOR("Broadcom Corporation"); | ||
| 101 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/lib/crc8.c b/lib/crc8.c new file mode 100644 index 000000000000..87b59cafdb83 --- /dev/null +++ b/lib/crc8.c | |||
| @@ -0,0 +1,86 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 2011 Broadcom Corporation | ||
| 3 | * | ||
| 4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 5 | * purpose with or without fee is hereby granted, provided that the above | ||
| 6 | * copyright notice and this permission notice appear in all copies. | ||
| 7 | * | ||
| 8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 15 | */ | ||
| 16 | |||
| 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/crc8.h> | ||
| 21 | #include <linux/printk.h> | ||
| 22 | |||
| 23 | /* | ||
| 24 | * crc8_populate_msb - fill crc table for given polynomial in reverse bit order. | ||
| 25 | * | ||
| 26 | * table: table to be filled. | ||
| 27 | * polynomial: polynomial for which table is to be filled. | ||
| 28 | */ | ||
| 29 | void crc8_populate_msb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) | ||
| 30 | { | ||
| 31 | int i, j; | ||
| 32 | const u8 msbit = 0x80; | ||
| 33 | u8 t = msbit; | ||
| 34 | |||
| 35 | table[0] = 0; | ||
| 36 | |||
| 37 | for (i = 1; i < CRC8_TABLE_SIZE; i *= 2) { | ||
| 38 | t = (t << 1) ^ (t & msbit ? polynomial : 0); | ||
| 39 | for (j = 0; j < i; j++) | ||
| 40 | table[i+j] = table[j] ^ t; | ||
| 41 | } | ||
| 42 | } | ||
| 43 | EXPORT_SYMBOL(crc8_populate_msb); | ||
| 44 | |||
| 45 | /* | ||
| 46 | * crc8_populate_lsb - fill crc table for given polynomial in regular bit order. | ||
| 47 | * | ||
| 48 | * table: table to be filled. | ||
| 49 | * polynomial: polynomial for which table is to be filled. | ||
| 50 | */ | ||
| 51 | void crc8_populate_lsb(u8 table[CRC8_TABLE_SIZE], u8 polynomial) | ||
| 52 | { | ||
| 53 | int i, j; | ||
| 54 | u8 t = 1; | ||
| 55 | |||
| 56 | table[0] = 0; | ||
| 57 | |||
| 58 | for (i = (CRC8_TABLE_SIZE >> 1); i; i >>= 1) { | ||
| 59 | t = (t >> 1) ^ (t & 1 ? polynomial : 0); | ||
| 60 | for (j = 0; j < CRC8_TABLE_SIZE; j += 2*i) | ||
| 61 | table[i+j] = table[j] ^ t; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | EXPORT_SYMBOL(crc8_populate_lsb); | ||
| 65 | |||
| 66 | /* | ||
| 67 | * crc8 - calculate a crc8 over the given input data. | ||
| 68 | * | ||
| 69 | * table: crc table used for calculation. | ||
| 70 | * pdata: pointer to data buffer. | ||
| 71 | * nbytes: number of bytes in data buffer. | ||
| 72 | * crc: previous returned crc8 value. | ||
| 73 | */ | ||
| 74 | u8 crc8(const u8 table[CRC8_TABLE_SIZE], u8 *pdata, size_t nbytes, u8 crc) | ||
| 75 | { | ||
| 76 | /* loop over the buffer data */ | ||
| 77 | while (nbytes-- > 0) | ||
| 78 | crc = table[(crc ^ *pdata++) & 0xff]; | ||
| 79 | |||
| 80 | return crc; | ||
| 81 | } | ||
| 82 | EXPORT_SYMBOL(crc8); | ||
| 83 | |||
| 84 | MODULE_DESCRIPTION("CRC8 (by Williams, Ross N.) function"); | ||
| 85 | MODULE_AUTHOR("Broadcom Corporation"); | ||
| 86 | MODULE_LICENSE("Dual BSD/GPL"); | ||
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index 9c0d76cdca92..89b0b2ca6db6 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
| @@ -100,6 +100,21 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
| 100 | mutex_unlock(&sta->ampdu_mlme.mtx); | 100 | mutex_unlock(&sta->ampdu_mlme.mtx); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, | ||
| 104 | const u8 *addr) | ||
| 105 | { | ||
| 106 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
| 107 | struct sta_info *sta = sta_info_get(sdata, addr); | ||
| 108 | int i; | ||
| 109 | |||
| 110 | for (i = 0; i < STA_TID_NUM; i++) | ||
| 111 | if (ba_rx_bitmap & BIT(i)) | ||
| 112 | set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested); | ||
| 113 | |||
| 114 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL(ieee80211_stop_rx_ba_session); | ||
| 117 | |||
| 103 | /* | 118 | /* |
| 104 | * After accepting the AddBA Request we activated a timer, | 119 | * After accepting the AddBA Request we activated a timer, |
| 105 | * resetting it after each frame that arrives from the originator. | 120 | * resetting it after each frame that arrives from the originator. |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index be70c70d3f5b..6e56c6ee7ccd 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
| @@ -1554,6 +1554,19 @@ static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) | |||
| 1554 | 1554 | ||
| 1555 | return local->ops->testmode_cmd(&local->hw, data, len); | 1555 | return local->ops->testmode_cmd(&local->hw, data, len); |
| 1556 | } | 1556 | } |
| 1557 | |||
| 1558 | static int ieee80211_testmode_dump(struct wiphy *wiphy, | ||
| 1559 | struct sk_buff *skb, | ||
| 1560 | struct netlink_callback *cb, | ||
| 1561 | void *data, int len) | ||
| 1562 | { | ||
| 1563 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
| 1564 | |||
| 1565 | if (!local->ops->testmode_dump) | ||
| 1566 | return -EOPNOTSUPP; | ||
| 1567 | |||
| 1568 | return local->ops->testmode_dump(&local->hw, skb, cb, data, len); | ||
| 1569 | } | ||
| 1557 | #endif | 1570 | #endif |
| 1558 | 1571 | ||
| 1559 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | 1572 | int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, |
| @@ -2134,6 +2147,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
| 2134 | .set_wds_peer = ieee80211_set_wds_peer, | 2147 | .set_wds_peer = ieee80211_set_wds_peer, |
| 2135 | .rfkill_poll = ieee80211_rfkill_poll, | 2148 | .rfkill_poll = ieee80211_rfkill_poll, |
| 2136 | CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) | 2149 | CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) |
| 2150 | CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump) | ||
| 2137 | .set_power_mgmt = ieee80211_set_power_mgmt, | 2151 | .set_power_mgmt = ieee80211_set_power_mgmt, |
| 2138 | .set_bitrate_mask = ieee80211_set_bitrate_mask, | 2152 | .set_bitrate_mask = ieee80211_set_bitrate_mask, |
| 2139 | .remain_on_channel = ieee80211_remain_on_channel, | 2153 | .remain_on_channel = ieee80211_remain_on_channel, |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 591add22bcc0..7cfc286946c0 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -140,6 +140,12 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
| 140 | sta, tid, WLAN_BACK_RECIPIENT, | 140 | sta, tid, WLAN_BACK_RECIPIENT, |
| 141 | WLAN_REASON_QSTA_TIMEOUT, true); | 141 | WLAN_REASON_QSTA_TIMEOUT, true); |
| 142 | 142 | ||
| 143 | if (test_and_clear_bit(tid, | ||
| 144 | sta->ampdu_mlme.tid_rx_stop_requested)) | ||
| 145 | ___ieee80211_stop_rx_ba_session( | ||
| 146 | sta, tid, WLAN_BACK_RECIPIENT, | ||
| 147 | WLAN_REASON_UNSPECIFIED, true); | ||
| 148 | |||
| 143 | tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; | 149 | tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; |
| 144 | if (tid_tx) { | 150 | if (tid_tx) { |
| 145 | /* | 151 | /* |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 2025af52b195..090b0ec1e056 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -775,9 +775,6 @@ struct ieee80211_local { | |||
| 775 | 775 | ||
| 776 | int tx_headroom; /* required headroom for hardware/radiotap */ | 776 | int tx_headroom; /* required headroom for hardware/radiotap */ |
| 777 | 777 | ||
| 778 | /* count for keys needing tailroom space allocation */ | ||
| 779 | int crypto_tx_tailroom_needed_cnt; | ||
| 780 | |||
| 781 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 778 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
| 782 | * added to skb_queue will be processed, but frames in | 779 | * added to skb_queue will be processed, but frames in |
| 783 | * skb_queue_unreliable may be dropped if the total length of these | 780 | * skb_queue_unreliable may be dropped if the total length of these |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 49d4f869e0bc..dee30aea9ab3 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1145,6 +1145,10 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
| 1145 | + IEEE80211_ENCRYPT_HEADROOM; | 1145 | + IEEE80211_ENCRYPT_HEADROOM; |
| 1146 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; | 1146 | ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; |
| 1147 | 1147 | ||
| 1148 | ret = dev_alloc_name(ndev, ndev->name); | ||
| 1149 | if (ret < 0) | ||
| 1150 | goto fail; | ||
| 1151 | |||
| 1148 | ieee80211_assign_perm_addr(local, ndev, type); | 1152 | ieee80211_assign_perm_addr(local, ndev, type); |
| 1149 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); | 1153 | memcpy(ndev->dev_addr, ndev->perm_addr, ETH_ALEN); |
| 1150 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); | 1154 | SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 31afd712930d..f825e2f0a57e 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
| @@ -101,11 +101,6 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
| 101 | 101 | ||
| 102 | if (!ret) { | 102 | if (!ret) { |
| 103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; | 103 | key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 104 | |||
| 105 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
| 106 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
| 107 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
| 108 | |||
| 109 | return 0; | 104 | return 0; |
| 110 | } | 105 | } |
| 111 | 106 | ||
| @@ -161,10 +156,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
| 161 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); | 156 | key->conf.keyidx, sta ? sta->addr : bcast_addr, ret); |
| 162 | 157 | ||
| 163 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 158 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
| 164 | |||
| 165 | if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || | ||
| 166 | (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV))) | ||
| 167 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
| 168 | } | 159 | } |
| 169 | 160 | ||
| 170 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | 161 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) |
| @@ -403,10 +394,8 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
| 403 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 394 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
| 404 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | 395 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) |
| 405 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 396 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
| 406 | if (key->local) { | 397 | if (key->local) |
| 407 | ieee80211_debugfs_key_remove(key); | 398 | ieee80211_debugfs_key_remove(key); |
| 408 | key->local->crypto_tx_tailroom_needed_cnt--; | ||
| 409 | } | ||
| 410 | 399 | ||
| 411 | kfree(key); | 400 | kfree(key); |
| 412 | } | 401 | } |
| @@ -468,8 +457,6 @@ int ieee80211_key_link(struct ieee80211_key *key, | |||
| 468 | 457 | ||
| 469 | ieee80211_debugfs_key_add(key); | 458 | ieee80211_debugfs_key_add(key); |
| 470 | 459 | ||
| 471 | key->local->crypto_tx_tailroom_needed_cnt++; | ||
| 472 | |||
| 473 | ret = ieee80211_key_enable_hw_accel(key); | 460 | ret = ieee80211_key_enable_hw_accel(key); |
| 474 | 461 | ||
| 475 | mutex_unlock(&sdata->local->key_mtx); | 462 | mutex_unlock(&sdata->local->key_mtx); |
| @@ -511,12 +498,8 @@ void ieee80211_enable_keys(struct ieee80211_sub_if_data *sdata) | |||
| 511 | 498 | ||
| 512 | mutex_lock(&sdata->local->key_mtx); | 499 | mutex_lock(&sdata->local->key_mtx); |
| 513 | 500 | ||
| 514 | sdata->local->crypto_tx_tailroom_needed_cnt = 0; | 501 | list_for_each_entry(key, &sdata->key_list, list) |
| 515 | |||
| 516 | list_for_each_entry(key, &sdata->key_list, list) { | ||
| 517 | sdata->local->crypto_tx_tailroom_needed_cnt++; | ||
| 518 | ieee80211_key_enable_hw_accel(key); | 502 | ieee80211_key_enable_hw_accel(key); |
| 519 | } | ||
| 520 | 503 | ||
| 521 | mutex_unlock(&sdata->local->key_mtx); | 504 | mutex_unlock(&sdata->local->key_mtx); |
| 522 | } | 505 | } |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 8adac67395f7..58a89554b788 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
| @@ -532,12 +532,21 @@ minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) | |||
| 532 | mp->hw = hw; | 532 | mp->hw = hw; |
| 533 | mp->update_interval = 100; | 533 | mp->update_interval = 100; |
| 534 | 534 | ||
| 535 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
| 536 | mp->fixed_rate_idx = (u32) -1; | ||
| 537 | mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx", | ||
| 538 | S_IRUGO | S_IWUGO, debugfsdir, &mp->fixed_rate_idx); | ||
| 539 | #endif | ||
| 540 | |||
| 535 | return mp; | 541 | return mp; |
| 536 | } | 542 | } |
| 537 | 543 | ||
| 538 | static void | 544 | static void |
| 539 | minstrel_free(void *priv) | 545 | minstrel_free(void *priv) |
| 540 | { | 546 | { |
| 547 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
| 548 | debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate); | ||
| 549 | #endif | ||
| 541 | kfree(priv); | 550 | kfree(priv); |
| 542 | } | 551 | } |
| 543 | 552 | ||
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 0f5a83370aa6..5d278eccaef0 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
| @@ -78,6 +78,18 @@ struct minstrel_priv { | |||
| 78 | unsigned int update_interval; | 78 | unsigned int update_interval; |
| 79 | unsigned int lookaround_rate; | 79 | unsigned int lookaround_rate; |
| 80 | unsigned int lookaround_rate_mrr; | 80 | unsigned int lookaround_rate_mrr; |
| 81 | |||
| 82 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
| 83 | /* | ||
| 84 | * enable fixed rate processing per RC | ||
| 85 | * - write static index to debugfs:ieee80211/phyX/rc/fixed_rate_idx | ||
| 86 | * - write -1 to enable RC processing again | ||
| 87 | * - setting will be applied on next update | ||
| 88 | */ | ||
| 89 | u32 fixed_rate_idx; | ||
| 90 | struct dentry *dbg_fixed_rate; | ||
| 91 | #endif | ||
| 92 | |||
| 81 | }; | 93 | }; |
| 82 | 94 | ||
| 83 | struct minstrel_debugfs_info { | 95 | struct minstrel_debugfs_info { |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 333b5118be6d..66a1eeb279c6 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
| @@ -609,6 +609,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
| 609 | 609 | ||
| 610 | info->flags |= mi->tx_flags; | 610 | info->flags |= mi->tx_flags; |
| 611 | sample_idx = minstrel_get_sample_rate(mp, mi); | 611 | sample_idx = minstrel_get_sample_rate(mp, mi); |
| 612 | |||
| 613 | #ifdef CONFIG_MAC80211_DEBUGFS | ||
| 614 | /* use fixed index if set */ | ||
| 615 | if (mp->fixed_rate_idx != -1) | ||
| 616 | sample_idx = mp->fixed_rate_idx; | ||
| 617 | #endif | ||
| 618 | |||
| 612 | if (sample_idx >= 0) { | 619 | if (sample_idx >= 0) { |
| 613 | sample = true; | 620 | sample = true; |
| 614 | minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, | 621 | minstrel_ht_set_rate(mp, mi, &ar[0], sample_idx, |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index c6ae8718bd57..a06d64ebc177 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -158,6 +158,8 @@ struct tid_ampdu_rx { | |||
| 158 | * @work: work struct for starting/stopping aggregation | 158 | * @work: work struct for starting/stopping aggregation |
| 159 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the | 159 | * @tid_rx_timer_expired: bitmap indicating on which TIDs the |
| 160 | * RX timer expired until the work for it runs | 160 | * RX timer expired until the work for it runs |
| 161 | * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the | ||
| 162 | * driver requested to close until the work for it runs | ||
| 161 | * @mtx: mutex to protect all TX data (except non-NULL assignments | 163 | * @mtx: mutex to protect all TX data (except non-NULL assignments |
| 162 | * to tid_tx[idx], which are protected by the sta spinlock) | 164 | * to tid_tx[idx], which are protected by the sta spinlock) |
| 163 | */ | 165 | */ |
| @@ -166,6 +168,7 @@ struct sta_ampdu_mlme { | |||
| 166 | /* rx */ | 168 | /* rx */ |
| 167 | struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM]; | 169 | struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM]; |
| 168 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; | 170 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)]; |
| 171 | unsigned long tid_rx_stop_requested[BITS_TO_LONGS(STA_TID_NUM)]; | ||
| 169 | /* tx */ | 172 | /* tx */ |
| 170 | struct work_struct work; | 173 | struct work_struct work; |
| 171 | struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM]; | 174 | struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM]; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 64e0f7587e6d..3104c844b544 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -1480,7 +1480,12 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
| 1480 | { | 1480 | { |
| 1481 | int tail_need = 0; | 1481 | int tail_need = 0; |
| 1482 | 1482 | ||
| 1483 | if (may_encrypt && local->crypto_tx_tailroom_needed_cnt) { | 1483 | /* |
| 1484 | * This could be optimised, devices that do full hardware | ||
| 1485 | * crypto (including TKIP MMIC) need no tailroom... But we | ||
| 1486 | * have no drivers for such devices currently. | ||
| 1487 | */ | ||
| 1488 | if (may_encrypt) { | ||
| 1484 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | 1489 | tail_need = IEEE80211_ENCRYPT_TAILROOM; |
| 1485 | tail_need -= skb_tailroom(skb); | 1490 | tail_need -= skb_tailroom(skb); |
| 1486 | tail_need = max_t(int, tail_need, 0); | 1491 | tail_need = max_t(int, tail_need, 0); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 88a565f130a5..70cbc8ca371e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -3754,10 +3754,6 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq, | |||
| 3754 | void *hdr; | 3754 | void *hdr; |
| 3755 | struct nlattr *infoattr; | 3755 | struct nlattr *infoattr; |
| 3756 | 3756 | ||
| 3757 | /* Survey without a channel doesn't make sense */ | ||
| 3758 | if (!survey->channel) | ||
| 3759 | return -EINVAL; | ||
| 3760 | |||
| 3761 | hdr = nl80211hdr_put(msg, pid, seq, flags, | 3757 | hdr = nl80211hdr_put(msg, pid, seq, flags, |
| 3762 | NL80211_CMD_NEW_SURVEY_RESULTS); | 3758 | NL80211_CMD_NEW_SURVEY_RESULTS); |
| 3763 | if (!hdr) | 3759 | if (!hdr) |
| @@ -3820,6 +3816,8 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
| 3820 | } | 3816 | } |
| 3821 | 3817 | ||
| 3822 | while (1) { | 3818 | while (1) { |
| 3819 | struct ieee80211_channel *chan; | ||
| 3820 | |||
| 3823 | res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, | 3821 | res = dev->ops->dump_survey(&dev->wiphy, netdev, survey_idx, |
| 3824 | &survey); | 3822 | &survey); |
| 3825 | if (res == -ENOENT) | 3823 | if (res == -ENOENT) |
| @@ -3827,6 +3825,19 @@ static int nl80211_dump_survey(struct sk_buff *skb, | |||
| 3827 | if (res) | 3825 | if (res) |
| 3828 | goto out_err; | 3826 | goto out_err; |
| 3829 | 3827 | ||
| 3828 | /* Survey without a channel doesn't make sense */ | ||
| 3829 | if (!survey.channel) { | ||
| 3830 | res = -EINVAL; | ||
| 3831 | goto out; | ||
| 3832 | } | ||
| 3833 | |||
| 3834 | chan = ieee80211_get_channel(&dev->wiphy, | ||
| 3835 | survey.channel->center_freq); | ||
| 3836 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | ||
| 3837 | survey_idx++; | ||
| 3838 | continue; | ||
| 3839 | } | ||
| 3840 | |||
| 3830 | if (nl80211_send_survey(skb, | 3841 | if (nl80211_send_survey(skb, |
| 3831 | NETLINK_CB(cb->skb).pid, | 3842 | NETLINK_CB(cb->skb).pid, |
| 3832 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3843 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
| @@ -4361,6 +4372,93 @@ static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | |||
| 4361 | return err; | 4372 | return err; |
| 4362 | } | 4373 | } |
| 4363 | 4374 | ||
| 4375 | static int nl80211_testmode_dump(struct sk_buff *skb, | ||
| 4376 | struct netlink_callback *cb) | ||
| 4377 | { | ||
| 4378 | struct cfg80211_registered_device *dev; | ||
| 4379 | int err; | ||
| 4380 | long phy_idx; | ||
| 4381 | void *data = NULL; | ||
| 4382 | int data_len = 0; | ||
| 4383 | |||
| 4384 | if (cb->args[0]) { | ||
| 4385 | /* | ||
| 4386 | * 0 is a valid index, but not valid for args[0], | ||
| 4387 | * so we need to offset by 1. | ||
| 4388 | */ | ||
| 4389 | phy_idx = cb->args[0] - 1; | ||
| 4390 | } else { | ||
| 4391 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | ||
| 4392 | nl80211_fam.attrbuf, nl80211_fam.maxattr, | ||
| 4393 | nl80211_policy); | ||
| 4394 | if (err) | ||
| 4395 | return err; | ||
| 4396 | if (!nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]) | ||
| 4397 | return -EINVAL; | ||
| 4398 | phy_idx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_WIPHY]); | ||
| 4399 | if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) | ||
| 4400 | cb->args[1] = | ||
| 4401 | (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; | ||
| 4402 | } | ||
| 4403 | |||
| 4404 | if (cb->args[1]) { | ||
| 4405 | data = nla_data((void *)cb->args[1]); | ||
| 4406 | data_len = nla_len((void *)cb->args[1]); | ||
| 4407 | } | ||
| 4408 | |||
| 4409 | mutex_lock(&cfg80211_mutex); | ||
| 4410 | dev = cfg80211_rdev_by_wiphy_idx(phy_idx); | ||
| 4411 | if (!dev) { | ||
| 4412 | mutex_unlock(&cfg80211_mutex); | ||
| 4413 | return -ENOENT; | ||
| 4414 | } | ||
| 4415 | cfg80211_lock_rdev(dev); | ||
| 4416 | mutex_unlock(&cfg80211_mutex); | ||
| 4417 | |||
| 4418 | if (!dev->ops->testmode_dump) { | ||
| 4419 | err = -EOPNOTSUPP; | ||
| 4420 | goto out_err; | ||
| 4421 | } | ||
| 4422 | |||
| 4423 | while (1) { | ||
| 4424 | void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).pid, | ||
| 4425 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | ||
| 4426 | NL80211_CMD_TESTMODE); | ||
| 4427 | struct nlattr *tmdata; | ||
| 4428 | |||
| 4429 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, dev->wiphy_idx) < 0) { | ||
| 4430 | genlmsg_cancel(skb, hdr); | ||
| 4431 | break; | ||
| 4432 | } | ||
| 4433 | |||
| 4434 | tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA); | ||
| 4435 | if (!tmdata) { | ||
| 4436 | genlmsg_cancel(skb, hdr); | ||
| 4437 | break; | ||
| 4438 | } | ||
| 4439 | err = dev->ops->testmode_dump(&dev->wiphy, skb, cb, | ||
| 4440 | data, data_len); | ||
| 4441 | nla_nest_end(skb, tmdata); | ||
| 4442 | |||
| 4443 | if (err == -ENOBUFS || err == -ENOENT) { | ||
| 4444 | genlmsg_cancel(skb, hdr); | ||
| 4445 | break; | ||
| 4446 | } else if (err) { | ||
| 4447 | genlmsg_cancel(skb, hdr); | ||
| 4448 | goto out_err; | ||
| 4449 | } | ||
| 4450 | |||
| 4451 | genlmsg_end(skb, hdr); | ||
| 4452 | } | ||
| 4453 | |||
| 4454 | err = skb->len; | ||
| 4455 | /* see above */ | ||
| 4456 | cb->args[0] = phy_idx + 1; | ||
| 4457 | out_err: | ||
| 4458 | cfg80211_unlock_rdev(dev); | ||
| 4459 | return err; | ||
| 4460 | } | ||
| 4461 | |||
| 4364 | static struct sk_buff * | 4462 | static struct sk_buff * |
| 4365 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, | 4463 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, |
| 4366 | int approxlen, u32 pid, u32 seq, gfp_t gfp) | 4464 | int approxlen, u32 pid, u32 seq, gfp_t gfp) |
| @@ -5658,6 +5756,7 @@ static struct genl_ops nl80211_ops[] = { | |||
| 5658 | { | 5756 | { |
| 5659 | .cmd = NL80211_CMD_TESTMODE, | 5757 | .cmd = NL80211_CMD_TESTMODE, |
| 5660 | .doit = nl80211_testmode_do, | 5758 | .doit = nl80211_testmode_do, |
| 5759 | .dumpit = nl80211_testmode_dump, | ||
| 5661 | .policy = nl80211_policy, | 5760 | .policy = nl80211_policy, |
| 5662 | .flags = GENL_ADMIN_PERM, | 5761 | .flags = GENL_ADMIN_PERM, |
| 5663 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 5762 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
