diff options
208 files changed, 20669 insertions, 2381 deletions
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index ad439c273003..c00585d915bc 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -211,6 +211,10 @@ static void __init bcm47xx_register_bcma(void) | |||
211 | 211 | ||
212 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); | 212 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); |
213 | if (err) | 213 | if (err) |
214 | panic("Failed to register BCMA bus (err %d)", err); | ||
215 | |||
216 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
217 | if (err) | ||
214 | panic("Failed to initialize BCMA bus (err %d)", err); | 218 | panic("Failed to initialize BCMA bus (err %d)", err); |
215 | 219 | ||
216 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); | 220 | bcm47xx_fill_bcma_boardinfo(&bcm47xx_bus.bcma.bus.boardinfo, NULL); |
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile index 91290f7f61b8..838b4b9d352f 100644 --- a/drivers/bcma/Makefile +++ b/drivers/bcma/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | bcma-y += main.o scan.o core.o sprom.o | 1 | bcma-y += main.o scan.o core.o sprom.o |
2 | bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o | 2 | bcma-y += driver_chipcommon.o driver_chipcommon_pmu.o |
3 | bcma-y += driver_chipcommon_b.o | ||
3 | bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o | 4 | bcma-$(CONFIG_BCMA_SFLASH) += driver_chipcommon_sflash.o |
4 | bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o | 5 | bcma-$(CONFIG_BCMA_NFLASH) += driver_chipcommon_nflash.o |
5 | bcma-y += driver_pci.o | 6 | bcma-y += driver_pci.o |
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h index 09b632ad0fe2..b40be43c6f31 100644 --- a/drivers/bcma/bcma_private.h +++ b/drivers/bcma/bcma_private.h | |||
@@ -50,6 +50,10 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc); | |||
50 | extern struct platform_device bcma_pflash_dev; | 50 | extern struct platform_device bcma_pflash_dev; |
51 | #endif /* CONFIG_BCMA_DRIVER_MIPS */ | 51 | #endif /* CONFIG_BCMA_DRIVER_MIPS */ |
52 | 52 | ||
53 | /* driver_chipcommon_b.c */ | ||
54 | int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb); | ||
55 | void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb); | ||
56 | |||
53 | /* driver_chipcommon_pmu.c */ | 57 | /* driver_chipcommon_pmu.c */ |
54 | u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); | 58 | u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc); |
55 | u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); | 59 | u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc); |
diff --git a/drivers/bcma/driver_chipcommon_b.c b/drivers/bcma/driver_chipcommon_b.c new file mode 100644 index 000000000000..c20b5f4ff290 --- /dev/null +++ b/drivers/bcma/driver_chipcommon_b.c | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * Broadcom specific AMBA | ||
3 | * ChipCommon B Unit driver | ||
4 | * | ||
5 | * Copyright 2014, Hauke Mehrtens <hauke@hauke-m.de> | ||
6 | * | ||
7 | * Licensed under the GNU/GPL. See COPYING for details. | ||
8 | */ | ||
9 | |||
10 | #include "bcma_private.h" | ||
11 | #include <linux/export.h> | ||
12 | #include <linux/bcma/bcma.h> | ||
13 | |||
14 | static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask, | ||
15 | u32 value, int timeout) | ||
16 | { | ||
17 | unsigned long deadline = jiffies + timeout; | ||
18 | u32 val; | ||
19 | |||
20 | do { | ||
21 | val = readl(addr); | ||
22 | if ((val & mask) == value) | ||
23 | return true; | ||
24 | cpu_relax(); | ||
25 | udelay(10); | ||
26 | } while (!time_after_eq(jiffies, deadline)); | ||
27 | |||
28 | bcma_err(bus, "Timeout waiting for register %p\n", addr); | ||
29 | |||
30 | return false; | ||
31 | } | ||
32 | |||
33 | void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value) | ||
34 | { | ||
35 | struct bcma_bus *bus = ccb->core->bus; | ||
36 | |||
37 | writel(offset, ccb->mii + 0x00); | ||
38 | bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100); | ||
39 | writel(value, ccb->mii + 0x04); | ||
40 | bcma_wait_reg(bus, ccb->mii + 0x00, 0x0100, 0x0000, 100); | ||
41 | } | ||
42 | EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write); | ||
43 | |||
44 | int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb) | ||
45 | { | ||
46 | if (ccb->setup_done) | ||
47 | return 0; | ||
48 | |||
49 | ccb->setup_done = 1; | ||
50 | ccb->mii = ioremap_nocache(ccb->core->addr_s[1], BCMA_CORE_SIZE); | ||
51 | if (!ccb->mii) | ||
52 | return -ENOMEM; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb) | ||
58 | { | ||
59 | if (ccb->mii) | ||
60 | iounmap(ccb->mii); | ||
61 | } | ||
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c index f032ed6dd459..1e5ac0a79696 100644 --- a/drivers/bcma/host_pci.c +++ b/drivers/bcma/host_pci.c | |||
@@ -208,6 +208,9 @@ static int bcma_host_pci_probe(struct pci_dev *dev, | |||
208 | bus->boardinfo.vendor = bus->host_pci->subsystem_vendor; | 208 | bus->boardinfo.vendor = bus->host_pci->subsystem_vendor; |
209 | bus->boardinfo.type = bus->host_pci->subsystem_device; | 209 | bus->boardinfo.type = bus->host_pci->subsystem_device; |
210 | 210 | ||
211 | /* Initialize struct, detect chip */ | ||
212 | bcma_init_bus(bus); | ||
213 | |||
211 | /* Register */ | 214 | /* Register */ |
212 | err = bcma_bus_register(bus); | 215 | err = bcma_bus_register(bus); |
213 | if (err) | 216 | if (err) |
diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c index 1edd7e064621..718e054dd727 100644 --- a/drivers/bcma/host_soc.c +++ b/drivers/bcma/host_soc.c | |||
@@ -165,7 +165,6 @@ static const struct bcma_host_ops bcma_host_soc_ops = { | |||
165 | int __init bcma_host_soc_register(struct bcma_soc *soc) | 165 | int __init bcma_host_soc_register(struct bcma_soc *soc) |
166 | { | 166 | { |
167 | struct bcma_bus *bus = &soc->bus; | 167 | struct bcma_bus *bus = &soc->bus; |
168 | int err; | ||
169 | 168 | ||
170 | /* iomap only first core. We have to read some register on this core | 169 | /* iomap only first core. We have to read some register on this core |
171 | * to scan the bus. | 170 | * to scan the bus. |
@@ -178,7 +177,18 @@ int __init bcma_host_soc_register(struct bcma_soc *soc) | |||
178 | bus->hosttype = BCMA_HOSTTYPE_SOC; | 177 | bus->hosttype = BCMA_HOSTTYPE_SOC; |
179 | bus->ops = &bcma_host_soc_ops; | 178 | bus->ops = &bcma_host_soc_ops; |
180 | 179 | ||
181 | /* Register */ | 180 | /* Initialize struct, detect chip */ |
181 | bcma_init_bus(bus); | ||
182 | |||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | int __init bcma_host_soc_init(struct bcma_soc *soc) | ||
187 | { | ||
188 | struct bcma_bus *bus = &soc->bus; | ||
189 | int err; | ||
190 | |||
191 | /* Scan bus and initialize it */ | ||
182 | err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); | 192 | err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips); |
183 | if (err) | 193 | if (err) |
184 | iounmap(bus->mmio); | 194 | iounmap(bus->mmio); |
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 0ff8d58831ef..c421403cab43 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c | |||
@@ -120,16 +120,60 @@ static void bcma_release_core_dev(struct device *dev) | |||
120 | kfree(core); | 120 | kfree(core); |
121 | } | 121 | } |
122 | 122 | ||
123 | static int bcma_register_cores(struct bcma_bus *bus) | 123 | static bool bcma_is_core_needed_early(u16 core_id) |
124 | { | ||
125 | switch (core_id) { | ||
126 | case BCMA_CORE_NS_NAND: | ||
127 | case BCMA_CORE_NS_QSPI: | ||
128 | return true; | ||
129 | } | ||
130 | |||
131 | return false; | ||
132 | } | ||
133 | |||
134 | static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) | ||
135 | { | ||
136 | int err; | ||
137 | |||
138 | core->dev.release = bcma_release_core_dev; | ||
139 | core->dev.bus = &bcma_bus_type; | ||
140 | dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); | ||
141 | |||
142 | switch (bus->hosttype) { | ||
143 | case BCMA_HOSTTYPE_PCI: | ||
144 | core->dev.parent = &bus->host_pci->dev; | ||
145 | core->dma_dev = &bus->host_pci->dev; | ||
146 | core->irq = bus->host_pci->irq; | ||
147 | break; | ||
148 | case BCMA_HOSTTYPE_SOC: | ||
149 | core->dev.dma_mask = &core->dev.coherent_dma_mask; | ||
150 | core->dma_dev = &core->dev; | ||
151 | break; | ||
152 | case BCMA_HOSTTYPE_SDIO: | ||
153 | break; | ||
154 | } | ||
155 | |||
156 | err = device_register(&core->dev); | ||
157 | if (err) { | ||
158 | bcma_err(bus, "Could not register dev for core 0x%03X\n", | ||
159 | core->id.id); | ||
160 | put_device(&core->dev); | ||
161 | return; | ||
162 | } | ||
163 | core->dev_registered = true; | ||
164 | } | ||
165 | |||
166 | static int bcma_register_devices(struct bcma_bus *bus) | ||
124 | { | 167 | { |
125 | struct bcma_device *core; | 168 | struct bcma_device *core; |
126 | int err, dev_id = 0; | 169 | int err; |
127 | 170 | ||
128 | list_for_each_entry(core, &bus->cores, list) { | 171 | list_for_each_entry(core, &bus->cores, list) { |
129 | /* We support that cores ourself */ | 172 | /* We support that cores ourself */ |
130 | switch (core->id.id) { | 173 | switch (core->id.id) { |
131 | case BCMA_CORE_4706_CHIPCOMMON: | 174 | case BCMA_CORE_4706_CHIPCOMMON: |
132 | case BCMA_CORE_CHIPCOMMON: | 175 | case BCMA_CORE_CHIPCOMMON: |
176 | case BCMA_CORE_NS_CHIPCOMMON_B: | ||
133 | case BCMA_CORE_PCI: | 177 | case BCMA_CORE_PCI: |
134 | case BCMA_CORE_PCIE: | 178 | case BCMA_CORE_PCIE: |
135 | case BCMA_CORE_PCIE2: | 179 | case BCMA_CORE_PCIE2: |
@@ -138,39 +182,16 @@ static int bcma_register_cores(struct bcma_bus *bus) | |||
138 | continue; | 182 | continue; |
139 | } | 183 | } |
140 | 184 | ||
185 | /* Early cores were already registered */ | ||
186 | if (bcma_is_core_needed_early(core->id.id)) | ||
187 | continue; | ||
188 | |||
141 | /* Only first GMAC core on BCM4706 is connected and working */ | 189 | /* Only first GMAC core on BCM4706 is connected and working */ |
142 | if (core->id.id == BCMA_CORE_4706_MAC_GBIT && | 190 | if (core->id.id == BCMA_CORE_4706_MAC_GBIT && |
143 | core->core_unit > 0) | 191 | core->core_unit > 0) |
144 | continue; | 192 | continue; |
145 | 193 | ||
146 | core->dev.release = bcma_release_core_dev; | 194 | bcma_register_core(bus, core); |
147 | core->dev.bus = &bcma_bus_type; | ||
148 | dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id); | ||
149 | |||
150 | switch (bus->hosttype) { | ||
151 | case BCMA_HOSTTYPE_PCI: | ||
152 | core->dev.parent = &bus->host_pci->dev; | ||
153 | core->dma_dev = &bus->host_pci->dev; | ||
154 | core->irq = bus->host_pci->irq; | ||
155 | break; | ||
156 | case BCMA_HOSTTYPE_SOC: | ||
157 | core->dev.dma_mask = &core->dev.coherent_dma_mask; | ||
158 | core->dma_dev = &core->dev; | ||
159 | break; | ||
160 | case BCMA_HOSTTYPE_SDIO: | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | err = device_register(&core->dev); | ||
165 | if (err) { | ||
166 | bcma_err(bus, | ||
167 | "Could not register dev for core 0x%03X\n", | ||
168 | core->id.id); | ||
169 | put_device(&core->dev); | ||
170 | continue; | ||
171 | } | ||
172 | core->dev_registered = true; | ||
173 | dev_id++; | ||
174 | } | 195 | } |
175 | 196 | ||
176 | #ifdef CONFIG_BCMA_DRIVER_MIPS | 197 | #ifdef CONFIG_BCMA_DRIVER_MIPS |
@@ -247,6 +268,12 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
247 | bcma_core_chipcommon_early_init(&bus->drv_cc); | 268 | bcma_core_chipcommon_early_init(&bus->drv_cc); |
248 | } | 269 | } |
249 | 270 | ||
271 | /* Cores providing flash access go before SPROM init */ | ||
272 | list_for_each_entry(core, &bus->cores, list) { | ||
273 | if (bcma_is_core_needed_early(core->id.id)) | ||
274 | bcma_register_core(bus, core); | ||
275 | } | ||
276 | |||
250 | /* Try to get SPROM */ | 277 | /* Try to get SPROM */ |
251 | err = bcma_sprom_get(bus); | 278 | err = bcma_sprom_get(bus); |
252 | if (err == -ENOENT) { | 279 | if (err == -ENOENT) { |
@@ -261,6 +288,13 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
261 | bcma_core_chipcommon_init(&bus->drv_cc); | 288 | bcma_core_chipcommon_init(&bus->drv_cc); |
262 | } | 289 | } |
263 | 290 | ||
291 | /* Init CC core */ | ||
292 | core = bcma_find_core(bus, BCMA_CORE_NS_CHIPCOMMON_B); | ||
293 | if (core) { | ||
294 | bus->drv_cc_b.core = core; | ||
295 | bcma_core_chipcommon_b_init(&bus->drv_cc_b); | ||
296 | } | ||
297 | |||
264 | /* Init MIPS core */ | 298 | /* Init MIPS core */ |
265 | core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); | 299 | core = bcma_find_core(bus, BCMA_CORE_MIPS_74K); |
266 | if (core) { | 300 | if (core) { |
@@ -297,7 +331,7 @@ int bcma_bus_register(struct bcma_bus *bus) | |||
297 | } | 331 | } |
298 | 332 | ||
299 | /* Register found cores */ | 333 | /* Register found cores */ |
300 | bcma_register_cores(bus); | 334 | bcma_register_devices(bus); |
301 | 335 | ||
302 | bcma_info(bus, "Bus registered\n"); | 336 | bcma_info(bus, "Bus registered\n"); |
303 | 337 | ||
@@ -315,6 +349,8 @@ void bcma_bus_unregister(struct bcma_bus *bus) | |||
315 | else if (err) | 349 | else if (err) |
316 | bcma_err(bus, "Can not unregister GPIO driver: %i\n", err); | 350 | bcma_err(bus, "Can not unregister GPIO driver: %i\n", err); |
317 | 351 | ||
352 | bcma_core_chipcommon_b_free(&bus->drv_cc_b); | ||
353 | |||
318 | cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); | 354 | cores[0] = bcma_find_core(bus, BCMA_CORE_MIPS_74K); |
319 | cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); | 355 | cores[1] = bcma_find_core(bus, BCMA_CORE_PCIE); |
320 | cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); | 356 | cores[2] = bcma_find_core(bus, BCMA_CORE_4706_MAC_GBIT_COMMON); |
@@ -334,8 +370,6 @@ int __init bcma_bus_early_register(struct bcma_bus *bus, | |||
334 | struct bcma_device *core; | 370 | struct bcma_device *core; |
335 | struct bcma_device_id match; | 371 | struct bcma_device_id match; |
336 | 372 | ||
337 | bcma_init_bus(bus); | ||
338 | |||
339 | match.manuf = BCMA_MANUF_BCM; | 373 | match.manuf = BCMA_MANUF_BCM; |
340 | match.id = bcma_cc_core_id(bus); | 374 | match.id = bcma_cc_core_id(bus); |
341 | match.class = BCMA_CL_SIM; | 375 | match.class = BCMA_CL_SIM; |
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c index e9bd77249a4c..b3a403c136fb 100644 --- a/drivers/bcma/scan.c +++ b/drivers/bcma/scan.c | |||
@@ -276,7 +276,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
276 | struct bcma_device *core) | 276 | struct bcma_device *core) |
277 | { | 277 | { |
278 | u32 tmp; | 278 | u32 tmp; |
279 | u8 i, j; | 279 | u8 i, j, k; |
280 | s32 cia, cib; | 280 | s32 cia, cib; |
281 | u8 ports[2], wrappers[2]; | 281 | u8 ports[2], wrappers[2]; |
282 | 282 | ||
@@ -314,6 +314,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
314 | /* Some specific cores don't need wrappers */ | 314 | /* Some specific cores don't need wrappers */ |
315 | switch (core->id.id) { | 315 | switch (core->id.id) { |
316 | case BCMA_CORE_4706_MAC_GBIT_COMMON: | 316 | case BCMA_CORE_4706_MAC_GBIT_COMMON: |
317 | case BCMA_CORE_NS_CHIPCOMMON_B: | ||
317 | /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ | 318 | /* Not used yet: case BCMA_CORE_OOB_ROUTER: */ |
318 | break; | 319 | break; |
319 | default: | 320 | default: |
@@ -367,6 +368,7 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
367 | core->addr = tmp; | 368 | core->addr = tmp; |
368 | 369 | ||
369 | /* get & parse slave ports */ | 370 | /* get & parse slave ports */ |
371 | k = 0; | ||
370 | for (i = 0; i < ports[1]; i++) { | 372 | for (i = 0; i < ports[1]; i++) { |
371 | for (j = 0; ; j++) { | 373 | for (j = 0; ; j++) { |
372 | tmp = bcma_erom_get_addr_desc(bus, eromptr, | 374 | tmp = bcma_erom_get_addr_desc(bus, eromptr, |
@@ -376,9 +378,9 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr, | |||
376 | /* pr_debug("erom: slave port %d " | 378 | /* pr_debug("erom: slave port %d " |
377 | * "has %d descriptors\n", i, j); */ | 379 | * "has %d descriptors\n", i, j); */ |
378 | break; | 380 | break; |
379 | } else { | 381 | } else if (k < ARRAY_SIZE(core->addr_s)) { |
380 | if (i == 0 && j == 0) | 382 | core->addr_s[k] = tmp; |
381 | core->addr1 = tmp; | 383 | k++; |
382 | } | 384 | } |
383 | } | 385 | } |
384 | } | 386 | } |
@@ -438,9 +440,6 @@ void bcma_init_bus(struct bcma_bus *bus) | |||
438 | s32 tmp; | 440 | s32 tmp; |
439 | struct bcma_chipinfo *chipinfo = &(bus->chipinfo); | 441 | struct bcma_chipinfo *chipinfo = &(bus->chipinfo); |
440 | 442 | ||
441 | if (bus->init_done) | ||
442 | return; | ||
443 | |||
444 | INIT_LIST_HEAD(&bus->cores); | 443 | INIT_LIST_HEAD(&bus->cores); |
445 | bus->nr_cores = 0; | 444 | bus->nr_cores = 0; |
446 | 445 | ||
@@ -452,8 +451,6 @@ void bcma_init_bus(struct bcma_bus *bus) | |||
452 | chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; | 451 | chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT; |
453 | bcma_info(bus, "Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n", | 452 | bcma_info(bus, "Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n", |
454 | chipinfo->id, chipinfo->rev, chipinfo->pkg); | 453 | chipinfo->id, chipinfo->rev, chipinfo->pkg); |
455 | |||
456 | bus->init_done = true; | ||
457 | } | 454 | } |
458 | 455 | ||
459 | int bcma_bus_scan(struct bcma_bus *bus) | 456 | int bcma_bus_scan(struct bcma_bus *bus) |
@@ -463,8 +460,6 @@ int bcma_bus_scan(struct bcma_bus *bus) | |||
463 | 460 | ||
464 | int err, core_num = 0; | 461 | int err, core_num = 0; |
465 | 462 | ||
466 | bcma_init_bus(bus); | ||
467 | |||
468 | erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); | 463 | erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM); |
469 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) { | 464 | if (bus->hosttype == BCMA_HOSTTYPE_SOC) { |
470 | eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); | 465 | eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE); |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 0527b29c3954..a79d657c0845 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -331,6 +331,9 @@ static void btusb_intr_complete(struct urb *urb) | |||
331 | BT_ERR("%s corrupted event packet", hdev->name); | 331 | BT_ERR("%s corrupted event packet", hdev->name); |
332 | hdev->stat.err_rx++; | 332 | hdev->stat.err_rx++; |
333 | } | 333 | } |
334 | } else if (urb->status == -ENOENT) { | ||
335 | /* Avoid suspend failed when usb_kill_urb */ | ||
336 | return; | ||
334 | } | 337 | } |
335 | 338 | ||
336 | if (!test_bit(BTUSB_INTR_RUNNING, &data->flags)) | 339 | if (!test_bit(BTUSB_INTR_RUNNING, &data->flags)) |
@@ -419,6 +422,9 @@ static void btusb_bulk_complete(struct urb *urb) | |||
419 | BT_ERR("%s corrupted ACL packet", hdev->name); | 422 | BT_ERR("%s corrupted ACL packet", hdev->name); |
420 | hdev->stat.err_rx++; | 423 | hdev->stat.err_rx++; |
421 | } | 424 | } |
425 | } else if (urb->status == -ENOENT) { | ||
426 | /* Avoid suspend failed when usb_kill_urb */ | ||
427 | return; | ||
422 | } | 428 | } |
423 | 429 | ||
424 | if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) | 430 | if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) |
@@ -513,6 +519,9 @@ static void btusb_isoc_complete(struct urb *urb) | |||
513 | hdev->stat.err_rx++; | 519 | hdev->stat.err_rx++; |
514 | } | 520 | } |
515 | } | 521 | } |
522 | } else if (urb->status == -ENOENT) { | ||
523 | /* Avoid suspend failed when usb_kill_urb */ | ||
524 | return; | ||
516 | } | 525 | } |
517 | 526 | ||
518 | if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags)) | 527 | if (!test_bit(BTUSB_ISOC_RUNNING, &data->flags)) |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index c1a4ade32772..a3b6e27d9121 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -234,6 +234,7 @@ void ath_printk(const char *level, const struct ath_common *common, | |||
234 | * AR9462. | 234 | * AR9462. |
235 | * @ATH_DBG_DFS: radar datection | 235 | * @ATH_DBG_DFS: radar datection |
236 | * @ATH_DBG_WOW: Wake on Wireless | 236 | * @ATH_DBG_WOW: Wake on Wireless |
237 | * @ATH_DBG_DYNACK: dynack handling | ||
237 | * @ATH_DBG_ANY: enable all debugging | 238 | * @ATH_DBG_ANY: enable all debugging |
238 | * | 239 | * |
239 | * The debug level is used to control the amount and type of debugging output | 240 | * The debug level is used to control the amount and type of debugging output |
@@ -262,6 +263,7 @@ enum ATH_DEBUG { | |||
262 | ATH_DBG_DFS = 0x00010000, | 263 | ATH_DBG_DFS = 0x00010000, |
263 | ATH_DBG_WOW = 0x00020000, | 264 | ATH_DBG_WOW = 0x00020000, |
264 | ATH_DBG_CHAN_CTX = 0x00040000, | 265 | ATH_DBG_CHAN_CTX = 0x00040000, |
266 | ATH_DBG_DYNACK = 0x00080000, | ||
265 | ATH_DBG_ANY = 0xffffffff | 267 | ATH_DBG_ANY = 0xffffffff |
266 | }; | 268 | }; |
267 | 269 | ||
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index b858c8288196..1f35bd1ef563 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
@@ -4838,7 +4838,6 @@ int ath10k_mac_register(struct ath10k *ar) | |||
4838 | IEEE80211_HW_MFP_CAPABLE | | 4838 | IEEE80211_HW_MFP_CAPABLE | |
4839 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 4839 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
4840 | IEEE80211_HW_HAS_RATE_CONTROL | | 4840 | IEEE80211_HW_HAS_RATE_CONTROL | |
4841 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | | ||
4842 | IEEE80211_HW_AP_LINK_PS | | 4841 | IEEE80211_HW_AP_LINK_PS | |
4843 | IEEE80211_HW_SPECTRUM_MGMT; | 4842 | IEEE80211_HW_SPECTRUM_MGMT; |
4844 | 4843 | ||
@@ -4846,8 +4845,10 @@ int ath10k_mac_register(struct ath10k *ar) | |||
4846 | * bytes is used for padding/alignment if necessary. */ | 4845 | * bytes is used for padding/alignment if necessary. */ |
4847 | ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; | 4846 | ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; |
4848 | 4847 | ||
4848 | ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS; | ||
4849 | |||
4849 | if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) | 4850 | if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) |
4850 | ar->hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; | 4851 | ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS; |
4851 | 4852 | ||
4852 | if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) { | 4853 | if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) { |
4853 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | 4854 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index b65c38fdaa4b..ab2709a43768 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -704,7 +704,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey) | |||
704 | * reset. | 704 | * reset. |
705 | */ | 705 | */ |
706 | static void | 706 | static void |
707 | ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | 707 | ath5k_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) |
708 | { | 708 | { |
709 | struct ath5k_hw *ah = hw->priv; | 709 | struct ath5k_hw *ah = hw->priv; |
710 | 710 | ||
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index b8f570ed39ad..896e63281b3b 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -92,6 +92,15 @@ config ATH9K_DFS_CERTIFIED | |||
92 | developed. At this point enabling this option won't do anything | 92 | developed. At this point enabling this option won't do anything |
93 | except increase code size. | 93 | except increase code size. |
94 | 94 | ||
95 | config ATH9K_DYNACK | ||
96 | bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)" | ||
97 | depends on ATH9K | ||
98 | default n | ||
99 | ---help--- | ||
100 | This option enables ath9k dynamic ACK timeout estimation algorithm | ||
101 | based on ACK frame RX timestamp, TX frame timestamp and frame | ||
102 | duration | ||
103 | |||
95 | config ATH9K_TX99 | 104 | config ATH9K_TX99 |
96 | bool "Atheros ath9k TX99 testing support" | 105 | bool "Atheros ath9k TX99 testing support" |
97 | depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS | 106 | depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS |
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 6b4020a57984..73704c1be736 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -49,6 +49,9 @@ ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o | |||
49 | 49 | ||
50 | ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ | 50 | ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ |
51 | ar9003_mci.o | 51 | ar9003_mci.o |
52 | |||
53 | ath9k_hw-$(CONFIG_ATH9K_DYNACK) += dynack.o | ||
54 | |||
52 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | 55 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o |
53 | 56 | ||
54 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o | 57 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o |
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c index 59af9f9712da..669cb3747208 100644 --- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -381,6 +381,13 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
381 | ts->evm1 = ads->AR_TxEVM1; | 381 | ts->evm1 = ads->AR_TxEVM1; |
382 | ts->evm2 = ads->AR_TxEVM2; | 382 | ts->evm2 = ads->AR_TxEVM2; |
383 | 383 | ||
384 | status = ACCESS_ONCE(ads->ds_ctl4); | ||
385 | ts->duration[0] = MS(status, AR_PacketDur0); | ||
386 | ts->duration[1] = MS(status, AR_PacketDur1); | ||
387 | status = ACCESS_ONCE(ads->ds_ctl5); | ||
388 | ts->duration[2] = MS(status, AR_PacketDur2); | ||
389 | ts->duration[3] = MS(status, AR_PacketDur3); | ||
390 | |||
384 | return 0; | 391 | return 0; |
385 | } | 392 | } |
386 | 393 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 71e38e85aa99..e5f7c11fa144 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -355,9 +355,11 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
355 | struct ath_tx_status *ts) | 355 | struct ath_tx_status *ts) |
356 | { | 356 | { |
357 | struct ar9003_txs *ads; | 357 | struct ar9003_txs *ads; |
358 | struct ar9003_txc *adc; | ||
358 | u32 status; | 359 | u32 status; |
359 | 360 | ||
360 | ads = &ah->ts_ring[ah->ts_tail]; | 361 | ads = &ah->ts_ring[ah->ts_tail]; |
362 | adc = (struct ar9003_txc *)ads; | ||
361 | 363 | ||
362 | status = ACCESS_ONCE(ads->status8); | 364 | status = ACCESS_ONCE(ads->status8); |
363 | if ((status & AR_TxDone) == 0) | 365 | if ((status & AR_TxDone) == 0) |
@@ -426,6 +428,13 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | |||
426 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); | 428 | ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); |
427 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); | 429 | ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); |
428 | 430 | ||
431 | status = ACCESS_ONCE(adc->ctl15); | ||
432 | ts->duration[0] = MS(status, AR_PacketDur0); | ||
433 | ts->duration[1] = MS(status, AR_PacketDur1); | ||
434 | status = ACCESS_ONCE(adc->ctl16); | ||
435 | ts->duration[2] = MS(status, AR_PacketDur2); | ||
436 | ts->duration[3] = MS(status, AR_PacketDur3); | ||
437 | |||
429 | memset(ads, 0, sizeof(*ads)); | 438 | memset(ads, 0, sizeof(*ads)); |
430 | 439 | ||
431 | return 0; | 440 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index c690601f7276..8cd116efe3ea 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -274,6 +274,9 @@ struct ath_node { | |||
274 | struct ath_rx_rate_stats rx_rate_stats; | 274 | struct ath_rx_rate_stats rx_rate_stats; |
275 | #endif | 275 | #endif |
276 | u8 key_idx[4]; | 276 | u8 key_idx[4]; |
277 | |||
278 | u32 ackto; | ||
279 | struct list_head list; | ||
277 | }; | 280 | }; |
278 | 281 | ||
279 | struct ath_tx_control { | 282 | struct ath_tx_control { |
@@ -314,7 +317,6 @@ struct ath_rx { | |||
314 | bool discard_next; | 317 | bool discard_next; |
315 | u32 *rxlink; | 318 | u32 *rxlink; |
316 | u32 num_pkts; | 319 | u32 num_pkts; |
317 | unsigned int rxfilter; | ||
318 | struct list_head rxbuf; | 320 | struct list_head rxbuf; |
319 | struct ath_descdma rxdma; | 321 | struct ath_descdma rxdma; |
320 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; | 322 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; |
@@ -350,6 +352,9 @@ struct ath_chanctx { | |||
350 | bool active; | 352 | bool active; |
351 | bool assigned; | 353 | bool assigned; |
352 | bool switch_after_beacon; | 354 | bool switch_after_beacon; |
355 | |||
356 | short nvifs; | ||
357 | unsigned int rxfilter; | ||
353 | }; | 358 | }; |
354 | 359 | ||
355 | enum ath_chanctx_event { | 360 | enum ath_chanctx_event { |
@@ -376,6 +381,9 @@ enum ath_chanctx_state { | |||
376 | struct ath_chanctx_sched { | 381 | struct ath_chanctx_sched { |
377 | bool beacon_pending; | 382 | bool beacon_pending; |
378 | bool offchannel_pending; | 383 | bool offchannel_pending; |
384 | bool wait_switch; | ||
385 | bool force_noa_update; | ||
386 | bool extend_absence; | ||
379 | enum ath_chanctx_state state; | 387 | enum ath_chanctx_state state; |
380 | u8 beacon_miss; | 388 | u8 beacon_miss; |
381 | 389 | ||
@@ -449,7 +457,7 @@ void ath9k_p2p_ps_timer(void *priv); | |||
449 | void ath9k_chanctx_wake_queues(struct ath_softc *sc); | 457 | void ath9k_chanctx_wake_queues(struct ath_softc *sc); |
450 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); | 458 | void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); |
451 | 459 | ||
452 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, | 460 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, |
453 | enum ath_chanctx_event ev); | 461 | enum ath_chanctx_event ev); |
454 | void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, | 462 | void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, |
455 | enum ath_chanctx_event ev); | 463 | enum ath_chanctx_event ev); |
@@ -478,7 +486,7 @@ static inline void ath9k_offchannel_init(struct ath_softc *sc) | |||
478 | static inline void ath9k_deinit_channel_context(struct ath_softc *sc) | 486 | static inline void ath9k_deinit_channel_context(struct ath_softc *sc) |
479 | { | 487 | { |
480 | } | 488 | } |
481 | static inline void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, | 489 | static inline void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, |
482 | enum ath_chanctx_event ev) | 490 | enum ath_chanctx_event ev) |
483 | { | 491 | { |
484 | } | 492 | } |
@@ -527,7 +535,7 @@ static inline void ath_chanctx_check_active(struct ath_softc *sc, | |||
527 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ | 535 | #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ |
528 | 536 | ||
529 | int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); | 537 | int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); |
530 | int ath_startrecv(struct ath_softc *sc); | 538 | void ath_startrecv(struct ath_softc *sc); |
531 | bool ath_stoprecv(struct ath_softc *sc); | 539 | bool ath_stoprecv(struct ath_softc *sc); |
532 | u32 ath_calcrxfilter(struct ath_softc *sc); | 540 | u32 ath_calcrxfilter(struct ath_softc *sc); |
533 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 541 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
@@ -572,6 +580,8 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
572 | /* VIFs */ | 580 | /* VIFs */ |
573 | /********/ | 581 | /********/ |
574 | 582 | ||
583 | #define P2P_DEFAULT_CTWIN 10 | ||
584 | |||
575 | struct ath_vif { | 585 | struct ath_vif { |
576 | struct list_head list; | 586 | struct list_head list; |
577 | 587 | ||
@@ -590,8 +600,10 @@ struct ath_vif { | |||
590 | u32 offchannel_start; | 600 | u32 offchannel_start; |
591 | u32 offchannel_duration; | 601 | u32 offchannel_duration; |
592 | 602 | ||
593 | u32 periodic_noa_start; | 603 | /* These are used for both periodic and one-shot */ |
594 | u32 periodic_noa_duration; | 604 | u32 noa_start; |
605 | u32 noa_duration; | ||
606 | bool periodic_noa; | ||
595 | }; | 607 | }; |
596 | 608 | ||
597 | struct ath9k_vif_iter_data { | 609 | struct ath9k_vif_iter_data { |
@@ -960,7 +972,6 @@ struct ath_softc { | |||
960 | bool ps_enabled; | 972 | bool ps_enabled; |
961 | bool ps_idle; | 973 | bool ps_idle; |
962 | short nbcnvifs; | 974 | short nbcnvifs; |
963 | short nvifs; | ||
964 | unsigned long ps_usecount; | 975 | unsigned long ps_usecount; |
965 | 976 | ||
966 | struct ath_rx rx; | 977 | struct ath_rx rx; |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b2f56d8b9043..a6af855ef6ed 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -183,7 +183,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw, | |||
183 | spin_unlock_bh(&cabq->axq_lock); | 183 | spin_unlock_bh(&cabq->axq_lock); |
184 | 184 | ||
185 | if (skb && cabq_depth) { | 185 | if (skb && cabq_depth) { |
186 | if (sc->nvifs > 1) { | 186 | if (sc->cur_chan->nvifs > 1) { |
187 | ath_dbg(common, BEACON, | 187 | ath_dbg(common, BEACON, |
188 | "Flushing previous cabq traffic\n"); | 188 | "Flushing previous cabq traffic\n"); |
189 | ath_draintxq(sc, cabq); | 189 | ath_draintxq(sc, cabq); |
@@ -514,6 +514,18 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc, | |||
514 | struct ieee80211_vif *vif) | 514 | struct ieee80211_vif *vif) |
515 | { | 515 | { |
516 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 516 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
517 | struct ath_vif *avp = (void *)vif->drv_priv; | ||
518 | |||
519 | if (ath9k_is_chanctx_enabled()) { | ||
520 | /* | ||
521 | * If the VIF is not present in the current channel context, | ||
522 | * then we can't do the usual opmode checks. Allow the | ||
523 | * beacon config for the VIF to be updated in this case and | ||
524 | * return immediately. | ||
525 | */ | ||
526 | if (sc->cur_chan != avp->chanctx) | ||
527 | return true; | ||
528 | } | ||
517 | 529 | ||
518 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { | 530 | if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { |
519 | if ((vif->type != NL80211_IFTYPE_AP) || | 531 | if ((vif->type != NL80211_IFTYPE_AP) || |
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c index 409f912a67c7..77c99eb55834 100644 --- a/drivers/net/wireless/ath/ath9k/channel.c +++ b/drivers/net/wireless/ath/ath9k/channel.c | |||
@@ -83,8 +83,6 @@ static int ath_set_channel(struct ath_softc *sc) | |||
83 | if (hw->conf.radar_enabled) { | 83 | if (hw->conf.radar_enabled) { |
84 | u32 rxfilter; | 84 | u32 rxfilter; |
85 | 85 | ||
86 | /* set HW specific DFS configuration */ | ||
87 | ath9k_hw_set_radar_params(ah); | ||
88 | rxfilter = ath9k_hw_getrxfilter(ah); | 86 | rxfilter = ath9k_hw_getrxfilter(ah); |
89 | rxfilter |= ATH9K_RX_FILTER_PHYRADAR | | 87 | rxfilter |= ATH9K_RX_FILTER_PHYRADAR | |
90 | ATH9K_RX_FILTER_PHYERR; | 88 | ATH9K_RX_FILTER_PHYERR; |
@@ -262,6 +260,9 @@ static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc) | |||
262 | cur = sc->cur_chan; | 260 | cur = sc->cur_chan; |
263 | prev = ath_chanctx_get_next(sc, cur); | 261 | prev = ath_chanctx_get_next(sc, cur); |
264 | 262 | ||
263 | if (!prev->switch_after_beacon) | ||
264 | return; | ||
265 | |||
265 | getrawmonotonic(&ts); | 266 | getrawmonotonic(&ts); |
266 | cur_tsf = (u32) cur->tsf_val + | 267 | cur_tsf = (u32) cur->tsf_val + |
267 | ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts); | 268 | ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts); |
@@ -310,7 +311,6 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
310 | struct ath_chanctx *ctx; | 311 | struct ath_chanctx *ctx; |
311 | u32 tsf_time; | 312 | u32 tsf_time; |
312 | u32 beacon_int; | 313 | u32 beacon_int; |
313 | bool noa_changed = false; | ||
314 | 314 | ||
315 | if (vif) | 315 | if (vif) |
316 | avp = (struct ath_vif *) vif->drv_priv; | 316 | avp = (struct ath_vif *) vif->drv_priv; |
@@ -333,7 +333,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
333 | break; | 333 | break; |
334 | } | 334 | } |
335 | 335 | ||
336 | if (sc->sched.offchannel_pending) { | 336 | if (sc->sched.offchannel_pending && !sc->sched.wait_switch) { |
337 | sc->sched.offchannel_pending = false; | 337 | sc->sched.offchannel_pending = false; |
338 | sc->next_chan = &sc->offchannel.chan; | 338 | sc->next_chan = &sc->offchannel.chan; |
339 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; | 339 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; |
@@ -372,44 +372,91 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
372 | sc->sched.switch_start_time = tsf_time; | 372 | sc->sched.switch_start_time = tsf_time; |
373 | sc->cur_chan->last_beacon = sc->sched.next_tbtt; | 373 | sc->cur_chan->last_beacon = sc->sched.next_tbtt; |
374 | 374 | ||
375 | /* Prevent wrap-around issues */ | 375 | /* |
376 | if (avp->periodic_noa_duration && | 376 | * If an offchannel switch is scheduled to happen after |
377 | tsf_time - avp->periodic_noa_start > BIT(30)) | 377 | * a beacon transmission, update the NoA with one-shot |
378 | avp->periodic_noa_duration = 0; | 378 | * values and increment the index. |
379 | 379 | */ | |
380 | if (ctx->active && !avp->periodic_noa_duration) { | 380 | if (sc->next_chan == &sc->offchannel.chan) { |
381 | avp->periodic_noa_start = tsf_time; | 381 | avp->noa_index++; |
382 | avp->periodic_noa_duration = | 382 | avp->offchannel_start = tsf_time; |
383 | TU_TO_USEC(cur_conf->beacon_interval) / 2 - | 383 | avp->offchannel_duration = sc->sched.offchannel_duration; |
384 | sc->sched.channel_switch_time; | 384 | |
385 | noa_changed = true; | 385 | ath_dbg(common, CHAN_CTX, |
386 | } else if (!ctx->active && avp->periodic_noa_duration) { | 386 | "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n", |
387 | avp->periodic_noa_duration = 0; | 387 | avp->offchannel_duration, |
388 | noa_changed = true; | 388 | avp->offchannel_start, |
389 | avp->noa_index); | ||
390 | |||
391 | /* | ||
392 | * When multiple contexts are active, the NoA | ||
393 | * has to be recalculated and advertised after | ||
394 | * an offchannel operation. | ||
395 | */ | ||
396 | if (ctx->active && avp->noa_duration) | ||
397 | avp->noa_duration = 0; | ||
398 | |||
399 | break; | ||
400 | } | ||
401 | |||
402 | /* | ||
403 | * Clear the extend_absence flag if it had been | ||
404 | * set during the previous beacon transmission, | ||
405 | * since we need to revert to the normal NoA | ||
406 | * schedule. | ||
407 | */ | ||
408 | if (ctx->active && sc->sched.extend_absence) { | ||
409 | avp->noa_duration = 0; | ||
410 | sc->sched.extend_absence = false; | ||
389 | } | 411 | } |
390 | 412 | ||
391 | /* If at least two consecutive beacons were missed on the STA | 413 | /* If at least two consecutive beacons were missed on the STA |
392 | * chanctx, stay on the STA channel for one extra beacon period, | 414 | * chanctx, stay on the STA channel for one extra beacon period, |
393 | * to resync the timer properly. | 415 | * to resync the timer properly. |
394 | */ | 416 | */ |
395 | if (ctx->active && sc->sched.beacon_miss >= 2) | 417 | if (ctx->active && sc->sched.beacon_miss >= 2) { |
396 | sc->sched.offchannel_duration = 3 * beacon_int / 2; | 418 | avp->noa_duration = 0; |
397 | 419 | sc->sched.extend_absence = true; | |
398 | if (sc->sched.offchannel_duration) { | ||
399 | noa_changed = true; | ||
400 | avp->offchannel_start = tsf_time; | ||
401 | avp->offchannel_duration = | ||
402 | sc->sched.offchannel_duration; | ||
403 | } | 420 | } |
404 | 421 | ||
405 | if (noa_changed) | 422 | /* Prevent wrap-around issues */ |
423 | if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30)) | ||
424 | avp->noa_duration = 0; | ||
425 | |||
426 | /* | ||
427 | * If multiple contexts are active, start periodic | ||
428 | * NoA and increment the index for the first | ||
429 | * announcement. | ||
430 | */ | ||
431 | if (ctx->active && | ||
432 | (!avp->noa_duration || sc->sched.force_noa_update)) { | ||
406 | avp->noa_index++; | 433 | avp->noa_index++; |
434 | avp->noa_start = tsf_time; | ||
435 | |||
436 | if (sc->sched.extend_absence) | ||
437 | avp->noa_duration = (3 * beacon_int / 2) + | ||
438 | sc->sched.channel_switch_time; | ||
439 | else | ||
440 | avp->noa_duration = | ||
441 | TU_TO_USEC(cur_conf->beacon_interval) / 2 + | ||
442 | sc->sched.channel_switch_time; | ||
443 | |||
444 | if (test_bit(ATH_OP_SCANNING, &common->op_flags) || | ||
445 | sc->sched.extend_absence) | ||
446 | avp->periodic_noa = false; | ||
447 | else | ||
448 | avp->periodic_noa = true; | ||
407 | 449 | ||
408 | ath_dbg(common, CHAN_CTX, | 450 | ath_dbg(common, CHAN_CTX, |
409 | "periodic_noa_duration: %d, periodic_noa_start: %d, noa_index: %d\n", | 451 | "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n", |
410 | avp->periodic_noa_duration, | 452 | avp->noa_duration, |
411 | avp->periodic_noa_start, | 453 | avp->noa_start, |
412 | avp->noa_index); | 454 | avp->noa_index, |
455 | avp->periodic_noa); | ||
456 | } | ||
457 | |||
458 | if (ctx->active && sc->sched.force_noa_update) | ||
459 | sc->sched.force_noa_update = false; | ||
413 | 460 | ||
414 | break; | 461 | break; |
415 | case ATH_CHANCTX_EVENT_BEACON_SENT: | 462 | case ATH_CHANCTX_EVENT_BEACON_SENT: |
@@ -490,9 +537,11 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif, | |||
490 | "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n"); | 537 | "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n"); |
491 | 538 | ||
492 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; | 539 | sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; |
540 | sc->sched.wait_switch = false; | ||
493 | 541 | ||
494 | tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; | 542 | tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; |
495 | if (sc->sched.beacon_miss >= 2) { | 543 | |
544 | if (sc->sched.extend_absence) { | ||
496 | sc->sched.beacon_miss = 0; | 545 | sc->sched.beacon_miss = 0; |
497 | tsf_time *= 3; | 546 | tsf_time *= 3; |
498 | } | 547 | } |
@@ -560,10 +609,9 @@ void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, | |||
560 | ath_chanctx_event(sc, NULL, ev); | 609 | ath_chanctx_event(sc, NULL, ev); |
561 | } | 610 | } |
562 | 611 | ||
563 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, | 612 | void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, |
564 | enum ath_chanctx_event ev) | 613 | enum ath_chanctx_event ev) |
565 | { | 614 | { |
566 | sc->sched.next_tbtt = ts; | ||
567 | ath_chanctx_event(sc, NULL, ev); | 615 | ath_chanctx_event(sc, NULL, ev); |
568 | } | 616 | } |
569 | 617 | ||
@@ -587,8 +635,18 @@ static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, | |||
587 | 635 | ||
588 | if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && | 636 | if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && |
589 | (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { | 637 | (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { |
638 | if (chandef) | ||
639 | ctx->chandef = *chandef; | ||
640 | |||
590 | sc->sched.offchannel_pending = true; | 641 | sc->sched.offchannel_pending = true; |
642 | sc->sched.wait_switch = true; | ||
643 | sc->sched.offchannel_duration = | ||
644 | jiffies_to_usecs(sc->offchannel.duration) + | ||
645 | sc->sched.channel_switch_time; | ||
646 | |||
591 | spin_unlock_bh(&sc->chan_lock); | 647 | spin_unlock_bh(&sc->chan_lock); |
648 | ath_dbg(common, CHAN_CTX, | ||
649 | "Set offchannel_pending to true\n"); | ||
592 | return; | 650 | return; |
593 | } | 651 | } |
594 | 652 | ||
@@ -601,7 +659,7 @@ static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx, | |||
601 | 659 | ||
602 | if (sc->next_chan == &sc->offchannel.chan) { | 660 | if (sc->next_chan == &sc->offchannel.chan) { |
603 | sc->sched.offchannel_duration = | 661 | sc->sched.offchannel_duration = |
604 | TU_TO_USEC(sc->offchannel.duration) + | 662 | jiffies_to_usecs(sc->offchannel.duration) + |
605 | sc->sched.channel_switch_time; | 663 | sc->sched.channel_switch_time; |
606 | 664 | ||
607 | if (chandef) { | 665 | if (chandef) { |
@@ -688,7 +746,8 @@ void ath_offchannel_next(struct ath_softc *sc) | |||
688 | } else if (sc->offchannel.roc_vif) { | 746 | } else if (sc->offchannel.roc_vif) { |
689 | vif = sc->offchannel.roc_vif; | 747 | vif = sc->offchannel.roc_vif; |
690 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; | 748 | sc->offchannel.chan.txpower = vif->bss_conf.txpower; |
691 | sc->offchannel.duration = sc->offchannel.roc_duration; | 749 | sc->offchannel.duration = |
750 | msecs_to_jiffies(sc->offchannel.roc_duration); | ||
692 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; | 751 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; |
693 | ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); | 752 | ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); |
694 | } else { | 753 | } else { |
@@ -724,6 +783,10 @@ void ath_scan_complete(struct ath_softc *sc, bool abort) | |||
724 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; | 783 | sc->offchannel.state = ATH_OFFCHANNEL_IDLE; |
725 | ieee80211_scan_completed(sc->hw, abort); | 784 | ieee80211_scan_completed(sc->hw, abort); |
726 | clear_bit(ATH_OP_SCANNING, &common->op_flags); | 785 | clear_bit(ATH_OP_SCANNING, &common->op_flags); |
786 | spin_lock_bh(&sc->chan_lock); | ||
787 | if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags)) | ||
788 | sc->sched.force_noa_update = true; | ||
789 | spin_unlock_bh(&sc->chan_lock); | ||
727 | ath_offchannel_next(sc); | 790 | ath_offchannel_next(sc); |
728 | ath9k_ps_restore(sc); | 791 | ath9k_ps_restore(sc); |
729 | } | 792 | } |
@@ -959,8 +1022,8 @@ static void ath_offchannel_channel_change(struct ath_softc *sc) | |||
959 | break; | 1022 | break; |
960 | 1023 | ||
961 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT; | 1024 | sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT; |
962 | mod_timer(&sc->offchannel.timer, jiffies + | 1025 | mod_timer(&sc->offchannel.timer, |
963 | msecs_to_jiffies(sc->offchannel.duration)); | 1026 | jiffies + sc->offchannel.duration); |
964 | ieee80211_ready_on_channel(sc->hw); | 1027 | ieee80211_ready_on_channel(sc->hw); |
965 | break; | 1028 | break; |
966 | case ATH_OFFCHANNEL_ROC_DONE: | 1029 | case ATH_OFFCHANNEL_ROC_DONE: |
@@ -1022,7 +1085,10 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force) | |||
1022 | sc->cur_chan = sc->next_chan; | 1085 | sc->cur_chan = sc->next_chan; |
1023 | sc->cur_chan->stopped = false; | 1086 | sc->cur_chan->stopped = false; |
1024 | sc->next_chan = NULL; | 1087 | sc->next_chan = NULL; |
1025 | sc->sched.offchannel_duration = 0; | 1088 | |
1089 | if (!sc->sched.offchannel_pending) | ||
1090 | sc->sched.offchannel_duration = 0; | ||
1091 | |||
1026 | if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE) | 1092 | if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE) |
1027 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; | 1093 | sc->sched.state = ATH_CHANCTX_STATE_IDLE; |
1028 | 1094 | ||
@@ -1165,6 +1231,30 @@ static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
1165 | ath9k_update_p2p_ps_timer(sc, avp); | 1231 | ath9k_update_p2p_ps_timer(sc, avp); |
1166 | } | 1232 | } |
1167 | 1233 | ||
1234 | static u8 ath9k_get_ctwin(struct ath_softc *sc, struct ath_vif *avp) | ||
1235 | { | ||
1236 | struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon; | ||
1237 | u8 switch_time, ctwin; | ||
1238 | |||
1239 | /* | ||
1240 | * Channel switch in multi-channel mode is deferred | ||
1241 | * by a quarter beacon interval when handling | ||
1242 | * ATH_CHANCTX_EVENT_BEACON_PREPARE, so the P2P-GO | ||
1243 | * interface is guaranteed to be discoverable | ||
1244 | * for that duration after a TBTT. | ||
1245 | */ | ||
1246 | switch_time = cur_conf->beacon_interval / 4; | ||
1247 | |||
1248 | ctwin = avp->vif->bss_conf.p2p_noa_attr.oppps_ctwindow; | ||
1249 | if (ctwin && (ctwin < switch_time)) | ||
1250 | return ctwin; | ||
1251 | |||
1252 | if (switch_time < P2P_DEFAULT_CTWIN) | ||
1253 | return 0; | ||
1254 | |||
1255 | return P2P_DEFAULT_CTWIN; | ||
1256 | } | ||
1257 | |||
1168 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | 1258 | void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, |
1169 | struct sk_buff *skb) | 1259 | struct sk_buff *skb) |
1170 | { | 1260 | { |
@@ -1182,10 +1272,10 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | |||
1182 | int noa_len, noa_desc, i = 0; | 1272 | int noa_len, noa_desc, i = 0; |
1183 | u8 *hdr; | 1273 | u8 *hdr; |
1184 | 1274 | ||
1185 | if (!avp->offchannel_duration && !avp->periodic_noa_duration) | 1275 | if (!avp->offchannel_duration && !avp->noa_duration) |
1186 | return; | 1276 | return; |
1187 | 1277 | ||
1188 | noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration; | 1278 | noa_desc = !!avp->offchannel_duration + !!avp->noa_duration; |
1189 | noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc; | 1279 | noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc; |
1190 | 1280 | ||
1191 | hdr = skb_put(skb, sizeof(noa_ie_hdr)); | 1281 | hdr = skb_put(skb, sizeof(noa_ie_hdr)); |
@@ -1197,13 +1287,19 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, | |||
1197 | memset(noa, 0, noa_len); | 1287 | memset(noa, 0, noa_len); |
1198 | 1288 | ||
1199 | noa->index = avp->noa_index; | 1289 | noa->index = avp->noa_index; |
1200 | if (avp->periodic_noa_duration) { | 1290 | noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp); |
1201 | u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval); | 1291 | |
1292 | if (avp->noa_duration) { | ||
1293 | if (avp->periodic_noa) { | ||
1294 | u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval); | ||
1295 | noa->desc[i].count = 255; | ||
1296 | noa->desc[i].interval = cpu_to_le32(interval); | ||
1297 | } else { | ||
1298 | noa->desc[i].count = 1; | ||
1299 | } | ||
1202 | 1300 | ||
1203 | noa->desc[i].count = 255; | 1301 | noa->desc[i].start_time = cpu_to_le32(avp->noa_start); |
1204 | noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start); | 1302 | noa->desc[i].duration = cpu_to_le32(avp->noa_duration); |
1205 | noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration); | ||
1206 | noa->desc[i].interval = cpu_to_le32(interval); | ||
1207 | i++; | 1303 | i++; |
1208 | } | 1304 | } |
1209 | 1305 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index d2279365be6f..46f20a309b5f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -838,7 +838,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf, | |||
838 | iter_data.nmeshes, iter_data.nwds); | 838 | iter_data.nmeshes, iter_data.nwds); |
839 | len += scnprintf(buf + len, sizeof(buf) - len, | 839 | len += scnprintf(buf + len, sizeof(buf) - len, |
840 | " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", | 840 | " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", |
841 | iter_data.nadhocs, sc->nvifs, sc->nbcnvifs); | 841 | iter_data.nadhocs, sc->cur_chan->nvifs, sc->nbcnvifs); |
842 | } | 842 | } |
843 | 843 | ||
844 | if (len > sizeof(buf)) | 844 | if (len > sizeof(buf)) |
@@ -1169,6 +1169,29 @@ static const struct file_operations fops_btcoex = { | |||
1169 | }; | 1169 | }; |
1170 | #endif | 1170 | #endif |
1171 | 1171 | ||
1172 | #ifdef CONFIG_ATH9K_DYNACK | ||
1173 | static ssize_t read_file_ackto(struct file *file, char __user *user_buf, | ||
1174 | size_t count, loff_t *ppos) | ||
1175 | { | ||
1176 | struct ath_softc *sc = file->private_data; | ||
1177 | struct ath_hw *ah = sc->sc_ah; | ||
1178 | char buf[32]; | ||
1179 | unsigned int len; | ||
1180 | |||
1181 | len = sprintf(buf, "%u %c\n", ah->dynack.ackto, | ||
1182 | (ah->dynack.enabled) ? 'A' : 'S'); | ||
1183 | |||
1184 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
1185 | } | ||
1186 | |||
1187 | static const struct file_operations fops_ackto = { | ||
1188 | .read = read_file_ackto, | ||
1189 | .open = simple_open, | ||
1190 | .owner = THIS_MODULE, | ||
1191 | .llseek = default_llseek, | ||
1192 | }; | ||
1193 | #endif | ||
1194 | |||
1172 | /* Ethtool support for get-stats */ | 1195 | /* Ethtool support for get-stats */ |
1173 | 1196 | ||
1174 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" | 1197 | #define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" |
@@ -1374,5 +1397,10 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
1374 | &fops_btcoex); | 1397 | &fops_btcoex); |
1375 | #endif | 1398 | #endif |
1376 | 1399 | ||
1400 | #ifdef CONFIG_ATH9K_DYNACK | ||
1401 | debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, | ||
1402 | sc, &fops_ackto); | ||
1403 | #endif | ||
1404 | |||
1377 | return 0; | 1405 | return 0; |
1378 | } | 1406 | } |
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c new file mode 100644 index 000000000000..6ae8e0bc9e1f --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/dynack.c | |||
@@ -0,0 +1,351 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath9k.h" | ||
18 | #include "hw.h" | ||
19 | #include "dynack.h" | ||
20 | |||
21 | #define COMPUTE_TO (5 * HZ) | ||
22 | #define LATEACK_DELAY (10 * HZ) | ||
23 | #define LATEACK_TO 256 | ||
24 | #define MAX_DELAY 300 | ||
25 | #define EWMA_LEVEL 96 | ||
26 | #define EWMA_DIV 128 | ||
27 | |||
28 | /** | ||
29 | * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation | ||
30 | * | ||
31 | */ | ||
32 | static inline u32 ath_dynack_ewma(u32 old, u32 new) | ||
33 | { | ||
34 | return (new * (EWMA_DIV - EWMA_LEVEL) + old * EWMA_LEVEL) / EWMA_DIV; | ||
35 | } | ||
36 | |||
37 | /** | ||
38 | * ath_dynack_get_sifs - get sifs time based on phy used | ||
39 | * @ah: ath hw | ||
40 | * @phy: phy used | ||
41 | * | ||
42 | */ | ||
43 | static inline u32 ath_dynack_get_sifs(struct ath_hw *ah, int phy) | ||
44 | { | ||
45 | u32 sifs = CCK_SIFS_TIME; | ||
46 | |||
47 | if (phy == WLAN_RC_PHY_OFDM) { | ||
48 | if (IS_CHAN_QUARTER_RATE(ah->curchan)) | ||
49 | sifs = OFDM_SIFS_TIME_QUARTER; | ||
50 | else if (IS_CHAN_HALF_RATE(ah->curchan)) | ||
51 | sifs = OFDM_SIFS_TIME_HALF; | ||
52 | else | ||
53 | sifs = OFDM_SIFS_TIME; | ||
54 | } | ||
55 | return sifs; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * ath_dynack_bssidmask - filter out ACK frames based on BSSID mask | ||
60 | * @ah: ath hw | ||
61 | * @mac: receiver address | ||
62 | */ | ||
63 | static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) | ||
64 | { | ||
65 | int i; | ||
66 | struct ath_common *common = ath9k_hw_common(ah); | ||
67 | |||
68 | for (i = 0; i < ETH_ALEN; i++) { | ||
69 | if ((common->macaddr[i] & common->bssidmask[i]) != | ||
70 | (mac[i] & common->bssidmask[i])) | ||
71 | return false; | ||
72 | } | ||
73 | |||
74 | return true; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout | ||
79 | * @ah: ath hw | ||
80 | * | ||
81 | * should be called while holding qlock | ||
82 | */ | ||
83 | static void ath_dynack_compute_ackto(struct ath_hw *ah) | ||
84 | { | ||
85 | struct ath_node *an; | ||
86 | u32 to = 0; | ||
87 | struct ath_dynack *da = &ah->dynack; | ||
88 | struct ath_common *common = ath9k_hw_common(ah); | ||
89 | |||
90 | list_for_each_entry(an, &da->nodes, list) | ||
91 | if (an->ackto > to) | ||
92 | to = an->ackto; | ||
93 | |||
94 | if (to && da->ackto != to) { | ||
95 | u32 slottime; | ||
96 | |||
97 | slottime = (to - 3) / 2; | ||
98 | da->ackto = to; | ||
99 | ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n", | ||
100 | da->ackto, slottime); | ||
101 | ath9k_hw_setslottime(ah, slottime); | ||
102 | ath9k_hw_set_ack_timeout(ah, da->ackto); | ||
103 | ath9k_hw_set_cts_timeout(ah, da->ackto); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | /** | ||
108 | * ath_dynack_compute_to - compute STA ACK timeout | ||
109 | * @ah: ath hw | ||
110 | * | ||
111 | * should be called while holding qlock | ||
112 | */ | ||
113 | static void ath_dynack_compute_to(struct ath_hw *ah) | ||
114 | { | ||
115 | u32 ackto, ack_ts; | ||
116 | u8 *dst, *src; | ||
117 | struct ieee80211_sta *sta; | ||
118 | struct ath_node *an; | ||
119 | struct ts_info *st_ts; | ||
120 | struct ath_dynack *da = &ah->dynack; | ||
121 | |||
122 | rcu_read_lock(); | ||
123 | |||
124 | while (da->st_rbf.h_rb != da->st_rbf.t_rb && | ||
125 | da->ack_rbf.h_rb != da->ack_rbf.t_rb) { | ||
126 | ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb]; | ||
127 | st_ts = &da->st_rbf.ts[da->st_rbf.h_rb]; | ||
128 | dst = da->st_rbf.addr[da->st_rbf.h_rb].h_dest; | ||
129 | src = da->st_rbf.addr[da->st_rbf.h_rb].h_src; | ||
130 | |||
131 | ath_dbg(ath9k_hw_common(ah), DYNACK, | ||
132 | "ack_ts %u st_ts %u st_dur %u [%u-%u]\n", | ||
133 | ack_ts, st_ts->tstamp, st_ts->dur, | ||
134 | da->ack_rbf.h_rb, da->st_rbf.h_rb); | ||
135 | |||
136 | if (ack_ts > st_ts->tstamp + st_ts->dur) { | ||
137 | ackto = ack_ts - st_ts->tstamp - st_ts->dur; | ||
138 | |||
139 | if (ackto < MAX_DELAY) { | ||
140 | sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst, | ||
141 | src); | ||
142 | if (sta) { | ||
143 | an = (struct ath_node *)sta->drv_priv; | ||
144 | an->ackto = ath_dynack_ewma(an->ackto, | ||
145 | ackto); | ||
146 | ath_dbg(ath9k_hw_common(ah), DYNACK, | ||
147 | "%pM to %u\n", dst, an->ackto); | ||
148 | if (time_is_before_jiffies(da->lto)) { | ||
149 | ath_dynack_compute_ackto(ah); | ||
150 | da->lto = jiffies + COMPUTE_TO; | ||
151 | } | ||
152 | } | ||
153 | INCR(da->ack_rbf.h_rb, ATH_DYN_BUF); | ||
154 | } | ||
155 | INCR(da->st_rbf.h_rb, ATH_DYN_BUF); | ||
156 | } else { | ||
157 | INCR(da->ack_rbf.h_rb, ATH_DYN_BUF); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | rcu_read_unlock(); | ||
162 | } | ||
163 | |||
164 | /** | ||
165 | * ath_dynack_sample_tx_ts - status timestamp sampling method | ||
166 | * @ah: ath hw | ||
167 | * @skb: socket buffer | ||
168 | * @ts: tx status info | ||
169 | * | ||
170 | */ | ||
171 | void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | ||
172 | struct ath_tx_status *ts) | ||
173 | { | ||
174 | u8 ridx; | ||
175 | struct ieee80211_hdr *hdr; | ||
176 | struct ath_dynack *da = &ah->dynack; | ||
177 | struct ath_common *common = ath9k_hw_common(ah); | ||
178 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
179 | |||
180 | if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled) | ||
181 | return; | ||
182 | |||
183 | spin_lock_bh(&da->qlock); | ||
184 | |||
185 | hdr = (struct ieee80211_hdr *)skb->data; | ||
186 | |||
187 | /* late ACK */ | ||
188 | if (ts->ts_status & ATH9K_TXERR_XRETRY) { | ||
189 | if (ieee80211_is_assoc_req(hdr->frame_control) || | ||
190 | ieee80211_is_assoc_resp(hdr->frame_control)) { | ||
191 | ath_dbg(common, DYNACK, "late ack\n"); | ||
192 | ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2); | ||
193 | ath9k_hw_set_ack_timeout(ah, LATEACK_TO); | ||
194 | ath9k_hw_set_cts_timeout(ah, LATEACK_TO); | ||
195 | da->lto = jiffies + LATEACK_DELAY; | ||
196 | } | ||
197 | |||
198 | spin_unlock_bh(&da->qlock); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | ridx = ts->ts_rateindex; | ||
203 | |||
204 | da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp; | ||
205 | da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration[ts->ts_rateindex]; | ||
206 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1); | ||
207 | ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2); | ||
208 | |||
209 | if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) { | ||
210 | u32 phy, sifs; | ||
211 | const struct ieee80211_rate *rate; | ||
212 | struct ieee80211_tx_rate *rates = info->status.rates; | ||
213 | |||
214 | rate = &common->sbands[info->band].bitrates[rates[ridx].idx]; | ||
215 | if (info->band == IEEE80211_BAND_2GHZ && | ||
216 | !(rate->flags & IEEE80211_RATE_ERP_G)) | ||
217 | phy = WLAN_RC_PHY_CCK; | ||
218 | else | ||
219 | phy = WLAN_RC_PHY_OFDM; | ||
220 | |||
221 | sifs = ath_dynack_get_sifs(ah, phy); | ||
222 | da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs; | ||
223 | } | ||
224 | |||
225 | ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n", | ||
226 | hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp, | ||
227 | da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb, | ||
228 | (da->st_rbf.t_rb + 1) % ATH_DYN_BUF); | ||
229 | |||
230 | INCR(da->st_rbf.t_rb, ATH_DYN_BUF); | ||
231 | if (da->st_rbf.t_rb == da->st_rbf.h_rb) | ||
232 | INCR(da->st_rbf.h_rb, ATH_DYN_BUF); | ||
233 | |||
234 | ath_dynack_compute_to(ah); | ||
235 | |||
236 | spin_unlock_bh(&da->qlock); | ||
237 | } | ||
238 | EXPORT_SYMBOL(ath_dynack_sample_tx_ts); | ||
239 | |||
240 | /** | ||
241 | * ath_dynack_sample_ack_ts - ACK timestamp sampling method | ||
242 | * @ah: ath hw | ||
243 | * @skb: socket buffer | ||
244 | * @ts: rx timestamp | ||
245 | * | ||
246 | */ | ||
247 | void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, | ||
248 | u32 ts) | ||
249 | { | ||
250 | struct ath_dynack *da = &ah->dynack; | ||
251 | struct ath_common *common = ath9k_hw_common(ah); | ||
252 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | ||
253 | |||
254 | if (!ath_dynack_bssidmask(ah, hdr->addr1) || !da->enabled) | ||
255 | return; | ||
256 | |||
257 | spin_lock_bh(&da->qlock); | ||
258 | da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts; | ||
259 | |||
260 | ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n", | ||
261 | da->ack_rbf.tstamp[da->ack_rbf.t_rb], | ||
262 | da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF); | ||
263 | |||
264 | INCR(da->ack_rbf.t_rb, ATH_DYN_BUF); | ||
265 | if (da->ack_rbf.t_rb == da->ack_rbf.h_rb) | ||
266 | INCR(da->ack_rbf.h_rb, ATH_DYN_BUF); | ||
267 | |||
268 | ath_dynack_compute_to(ah); | ||
269 | |||
270 | spin_unlock_bh(&da->qlock); | ||
271 | } | ||
272 | EXPORT_SYMBOL(ath_dynack_sample_ack_ts); | ||
273 | |||
274 | /** | ||
275 | * ath_dynack_node_init - init ath_node related info | ||
276 | * @ah: ath hw | ||
277 | * @an: ath node | ||
278 | * | ||
279 | */ | ||
280 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an) | ||
281 | { | ||
282 | /* ackto = slottime + sifs + air delay */ | ||
283 | u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; | ||
284 | struct ath_dynack *da = &ah->dynack; | ||
285 | |||
286 | an->ackto = ackto; | ||
287 | |||
288 | spin_lock(&da->qlock); | ||
289 | list_add_tail(&an->list, &da->nodes); | ||
290 | spin_unlock(&da->qlock); | ||
291 | } | ||
292 | EXPORT_SYMBOL(ath_dynack_node_init); | ||
293 | |||
294 | /** | ||
295 | * ath_dynack_node_deinit - deinit ath_node related info | ||
296 | * @ah: ath hw | ||
297 | * @an: ath node | ||
298 | * | ||
299 | */ | ||
300 | void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an) | ||
301 | { | ||
302 | struct ath_dynack *da = &ah->dynack; | ||
303 | |||
304 | spin_lock(&da->qlock); | ||
305 | list_del(&an->list); | ||
306 | spin_unlock(&da->qlock); | ||
307 | } | ||
308 | EXPORT_SYMBOL(ath_dynack_node_deinit); | ||
309 | |||
310 | /** | ||
311 | * ath_dynack_reset - reset dynack processing | ||
312 | * @ah: ath hw | ||
313 | * | ||
314 | */ | ||
315 | void ath_dynack_reset(struct ath_hw *ah) | ||
316 | { | ||
317 | /* ackto = slottime + sifs + air delay */ | ||
318 | u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; | ||
319 | struct ath_dynack *da = &ah->dynack; | ||
320 | |||
321 | da->lto = jiffies; | ||
322 | da->ackto = ackto; | ||
323 | |||
324 | da->st_rbf.t_rb = 0; | ||
325 | da->st_rbf.h_rb = 0; | ||
326 | da->ack_rbf.t_rb = 0; | ||
327 | da->ack_rbf.h_rb = 0; | ||
328 | |||
329 | /* init acktimeout */ | ||
330 | ath9k_hw_setslottime(ah, (ackto - 3) / 2); | ||
331 | ath9k_hw_set_ack_timeout(ah, ackto); | ||
332 | ath9k_hw_set_cts_timeout(ah, ackto); | ||
333 | } | ||
334 | EXPORT_SYMBOL(ath_dynack_reset); | ||
335 | |||
336 | /** | ||
337 | * ath_dynack_init - init dynack data structure | ||
338 | * @ah: ath hw | ||
339 | * | ||
340 | */ | ||
341 | void ath_dynack_init(struct ath_hw *ah) | ||
342 | { | ||
343 | struct ath_dynack *da = &ah->dynack; | ||
344 | |||
345 | memset(da, 0, sizeof(struct ath_dynack)); | ||
346 | |||
347 | spin_lock_init(&da->qlock); | ||
348 | INIT_LIST_HEAD(&da->nodes); | ||
349 | |||
350 | ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION; | ||
351 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/dynack.h b/drivers/net/wireless/ath/ath9k/dynack.h new file mode 100644 index 000000000000..6d7bef976742 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/dynack.h | |||
@@ -0,0 +1,103 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014, Lorenzo Bianconi <lorenzo.bianconi83@gmail.com> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef DYNACK_H | ||
18 | #define DYNACK_H | ||
19 | |||
20 | #define ATH_DYN_BUF 64 | ||
21 | |||
22 | struct ath_hw; | ||
23 | struct ath_node; | ||
24 | |||
25 | /** | ||
26 | * struct ath_dyn_rxbuf - ACK frame ring buffer | ||
27 | * @h_rb: ring buffer head | ||
28 | * @t_rb: ring buffer tail | ||
29 | * @tstamp: ACK RX timestamp buffer | ||
30 | */ | ||
31 | struct ath_dyn_rxbuf { | ||
32 | u16 h_rb, t_rb; | ||
33 | u32 tstamp[ATH_DYN_BUF]; | ||
34 | }; | ||
35 | |||
36 | struct ts_info { | ||
37 | u32 tstamp; | ||
38 | u32 dur; | ||
39 | }; | ||
40 | |||
41 | struct haddr_pair { | ||
42 | u8 h_dest[ETH_ALEN]; | ||
43 | u8 h_src[ETH_ALEN]; | ||
44 | }; | ||
45 | |||
46 | /** | ||
47 | * struct ath_dyn_txbuf - tx frame ring buffer | ||
48 | * @h_rb: ring buffer head | ||
49 | * @t_rb: ring buffer tail | ||
50 | * @addr: dest/src address pair for a given TX frame | ||
51 | * @ts: TX frame timestamp buffer | ||
52 | */ | ||
53 | struct ath_dyn_txbuf { | ||
54 | u16 h_rb, t_rb; | ||
55 | struct haddr_pair addr[ATH_DYN_BUF]; | ||
56 | struct ts_info ts[ATH_DYN_BUF]; | ||
57 | }; | ||
58 | |||
59 | /** | ||
60 | * struct ath_dynack - dynack processing info | ||
61 | * @enabled: enable dyn ack processing | ||
62 | * @ackto: current ACK timeout | ||
63 | * @lto: last ACK timeout computation | ||
64 | * @nodes: ath_node linked list | ||
65 | * @qlock: ts queue spinlock | ||
66 | * @ack_rbf: ACK ts ring buffer | ||
67 | * @st_rbf: status ts ring buffer | ||
68 | */ | ||
69 | struct ath_dynack { | ||
70 | bool enabled; | ||
71 | int ackto; | ||
72 | unsigned long lto; | ||
73 | |||
74 | struct list_head nodes; | ||
75 | |||
76 | /* protect timestamp queue access */ | ||
77 | spinlock_t qlock; | ||
78 | struct ath_dyn_rxbuf ack_rbf; | ||
79 | struct ath_dyn_txbuf st_rbf; | ||
80 | }; | ||
81 | |||
82 | #if defined(CONFIG_ATH9K_DYNACK) | ||
83 | void ath_dynack_reset(struct ath_hw *ah); | ||
84 | void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an); | ||
85 | void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an); | ||
86 | void ath_dynack_init(struct ath_hw *ah); | ||
87 | void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, u32 ts); | ||
88 | void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb, | ||
89 | struct ath_tx_status *ts); | ||
90 | #else | ||
91 | static inline void ath_dynack_init(struct ath_hw *ah) {} | ||
92 | static inline void ath_dynack_node_init(struct ath_hw *ah, | ||
93 | struct ath_node *an) {} | ||
94 | static inline void ath_dynack_node_deinit(struct ath_hw *ah, | ||
95 | struct ath_node *an) {} | ||
96 | static inline void ath_dynack_sample_ack_ts(struct ath_hw *ah, | ||
97 | struct sk_buff *skb, u32 ts) {} | ||
98 | static inline void ath_dynack_sample_tx_ts(struct ath_hw *ah, | ||
99 | struct sk_buff *skb, | ||
100 | struct ath_tx_status *ts) {} | ||
101 | #endif | ||
102 | |||
103 | #endif /* DYNACK_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 5627917c5ff7..994fff1ff519 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1722,7 +1722,7 @@ static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | |||
1722 | } | 1722 | } |
1723 | 1723 | ||
1724 | static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, | 1724 | static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, |
1725 | u8 coverage_class) | 1725 | s16 coverage_class) |
1726 | { | 1726 | { |
1727 | struct ath9k_htc_priv *priv = hw->priv; | 1727 | struct ath9k_htc_priv *priv = hw->priv; |
1728 | 1728 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 69bbea1184d2..3aed729e4d5e 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -647,6 +647,8 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
647 | return ret; | 647 | return ret; |
648 | } | 648 | } |
649 | 649 | ||
650 | ath_dynack_init(ah); | ||
651 | |||
650 | return 0; | 652 | return 0; |
651 | } | 653 | } |
652 | EXPORT_SYMBOL(ath9k_hw_init); | 654 | EXPORT_SYMBOL(ath9k_hw_init); |
@@ -935,21 +937,21 @@ static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us) | |||
935 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val); | 937 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val); |
936 | } | 938 | } |
937 | 939 | ||
938 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | 940 | void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
939 | { | 941 | { |
940 | u32 val = ath9k_hw_mac_to_clks(ah, us); | 942 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
941 | val = min(val, (u32) 0xFFFF); | 943 | val = min(val, (u32) 0xFFFF); |
942 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); | 944 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); |
943 | } | 945 | } |
944 | 946 | ||
945 | static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) | 947 | void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) |
946 | { | 948 | { |
947 | u32 val = ath9k_hw_mac_to_clks(ah, us); | 949 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
948 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); | 950 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); |
949 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); | 951 | REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); |
950 | } | 952 | } |
951 | 953 | ||
952 | static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) | 954 | void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) |
953 | { | 955 | { |
954 | u32 val = ath9k_hw_mac_to_clks(ah, us); | 956 | u32 val = ath9k_hw_mac_to_clks(ah, us); |
955 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); | 957 | val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); |
@@ -1053,6 +1055,14 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah) | |||
1053 | ctstimeout += 48 - sifstime - ah->slottime; | 1055 | ctstimeout += 48 - sifstime - ah->slottime; |
1054 | } | 1056 | } |
1055 | 1057 | ||
1058 | if (ah->dynack.enabled) { | ||
1059 | acktimeout = ah->dynack.ackto; | ||
1060 | ctstimeout = acktimeout; | ||
1061 | slottime = (acktimeout - 3) / 2; | ||
1062 | } else { | ||
1063 | ah->dynack.ackto = acktimeout; | ||
1064 | } | ||
1065 | |||
1056 | ath9k_hw_set_sifs_time(ah, sifstime); | 1066 | ath9k_hw_set_sifs_time(ah, sifstime); |
1057 | ath9k_hw_setslottime(ah, slottime); | 1067 | ath9k_hw_setslottime(ah, slottime); |
1058 | ath9k_hw_set_ack_timeout(ah, acktimeout); | 1068 | ath9k_hw_set_ack_timeout(ah, acktimeout); |
@@ -1954,6 +1964,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1954 | if (AR_SREV_9565(ah) && common->bt_ant_diversity) | 1964 | if (AR_SREV_9565(ah) && common->bt_ant_diversity) |
1955 | REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); | 1965 | REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); |
1956 | 1966 | ||
1967 | if (ah->hw->conf.radar_enabled) { | ||
1968 | /* set HW specific DFS configuration */ | ||
1969 | ah->radar_conf.ext_channel = IS_CHAN_HT40(chan); | ||
1970 | ath9k_hw_set_radar_params(ah); | ||
1971 | } | ||
1972 | |||
1957 | return 0; | 1973 | return 0; |
1958 | } | 1974 | } |
1959 | EXPORT_SYMBOL(ath9k_hw_reset); | 1975 | EXPORT_SYMBOL(ath9k_hw_reset); |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 51b4ebe04c04..b9eef3362fbb 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "reg.h" | 29 | #include "reg.h" |
30 | #include "phy.h" | 30 | #include "phy.h" |
31 | #include "btcoex.h" | 31 | #include "btcoex.h" |
32 | #include "dynack.h" | ||
32 | 33 | ||
33 | #include "../regd.h" | 34 | #include "../regd.h" |
34 | 35 | ||
@@ -924,6 +925,8 @@ struct ath_hw { | |||
924 | int (*external_reset)(void); | 925 | int (*external_reset)(void); |
925 | 926 | ||
926 | const struct firmware *eeprom_blob; | 927 | const struct firmware *eeprom_blob; |
928 | |||
929 | struct ath_dynack dynack; | ||
927 | }; | 930 | }; |
928 | 931 | ||
929 | struct ath_bus_ops { | 932 | struct ath_bus_ops { |
@@ -1080,6 +1083,10 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan); | |||
1080 | void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); | 1083 | void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); |
1081 | void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); | 1084 | void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); |
1082 | 1085 | ||
1086 | void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us); | ||
1087 | void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us); | ||
1088 | void ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | ||
1089 | |||
1083 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 1090 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
1084 | static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | 1091 | static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) |
1085 | { | 1092 | { |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index ca10a8b3a381..156a944134dc 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -763,8 +763,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
763 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) | 763 | if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) |
764 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 764 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
765 | 765 | ||
766 | hw->wiphy->features |= (NL80211_FEATURE_ACTIVE_MONITOR | | 766 | hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | |
767 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE); | 767 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | |
768 | NL80211_FEATURE_P2P_GO_CTWIN; | ||
768 | 769 | ||
769 | if (!config_enabled(CONFIG_ATH9K_TX99)) { | 770 | if (!config_enabled(CONFIG_ATH9K_TX99)) { |
770 | hw->wiphy->interface_modes = | 771 | hw->wiphy->interface_modes = |
@@ -810,7 +811,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
810 | /* allow 4 queues per channel context + | 811 | /* allow 4 queues per channel context + |
811 | * 1 cab queue + 1 offchannel tx queue | 812 | * 1 cab queue + 1 offchannel tx queue |
812 | */ | 813 | */ |
813 | hw->queues = 10; | 814 | hw->queues = ATH9K_NUM_TX_QUEUES; |
814 | /* last queue for offchannel */ | 815 | /* last queue for offchannel */ |
815 | hw->offchannel_tx_hw_queue = hw->queues - 1; | 816 | hw->offchannel_tx_hw_queue = hw->queues - 1; |
816 | hw->max_rates = 4; | 817 | hw->max_rates = 4; |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 6c56cafa5ca4..cd05a7791073 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -121,6 +121,7 @@ struct ath_tx_status { | |||
121 | u32 evm0; | 121 | u32 evm0; |
122 | u32 evm1; | 122 | u32 evm1; |
123 | u32 evm2; | 123 | u32 evm2; |
124 | u32 duration[4]; | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | struct ath_rx_status { | 127 | struct ath_rx_status { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4a8c9b80b08e..fbf23ac61c97 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -224,16 +224,11 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start) | |||
224 | struct ath_common *common = ath9k_hw_common(ah); | 224 | struct ath_common *common = ath9k_hw_common(ah); |
225 | unsigned long flags; | 225 | unsigned long flags; |
226 | 226 | ||
227 | if (ath_startrecv(sc) != 0) { | 227 | ath9k_calculate_summary_state(sc, sc->cur_chan); |
228 | ath_err(common, "Unable to restart recv logic\n"); | 228 | ath_startrecv(sc); |
229 | return false; | ||
230 | } | ||
231 | |||
232 | ath9k_cmn_update_txpow(ah, sc->curtxpow, | 229 | ath9k_cmn_update_txpow(ah, sc->curtxpow, |
233 | sc->cur_chan->txpower, &sc->curtxpow); | 230 | sc->cur_chan->txpower, &sc->curtxpow); |
234 | |||
235 | clear_bit(ATH_OP_HW_RESET, &common->op_flags); | 231 | clear_bit(ATH_OP_HW_RESET, &common->op_flags); |
236 | ath9k_calculate_summary_state(sc, sc->cur_chan); | ||
237 | 232 | ||
238 | if (!sc->cur_chan->offchannel && start) { | 233 | if (!sc->cur_chan->offchannel && start) { |
239 | /* restore per chanctx TSF timer */ | 234 | /* restore per chanctx TSF timer */ |
@@ -350,12 +345,16 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
350 | memset(&an->key_idx, 0, sizeof(an->key_idx)); | 345 | memset(&an->key_idx, 0, sizeof(an->key_idx)); |
351 | 346 | ||
352 | ath_tx_node_init(sc, an); | 347 | ath_tx_node_init(sc, an); |
348 | |||
349 | ath_dynack_node_init(sc->sc_ah, an); | ||
353 | } | 350 | } |
354 | 351 | ||
355 | static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) | 352 | static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) |
356 | { | 353 | { |
357 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 354 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
358 | ath_tx_node_cleanup(sc, an); | 355 | ath_tx_node_cleanup(sc, an); |
356 | |||
357 | ath_dynack_node_deinit(sc->sc_ah, an); | ||
359 | } | 358 | } |
360 | 359 | ||
361 | void ath9k_tasklet(unsigned long data) | 360 | void ath9k_tasklet(unsigned long data) |
@@ -916,8 +915,6 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, | |||
916 | switch (vif->type) { | 915 | switch (vif->type) { |
917 | case NL80211_IFTYPE_AP: | 916 | case NL80211_IFTYPE_AP: |
918 | iter_data->naps++; | 917 | iter_data->naps++; |
919 | if (vif->bss_conf.enable_beacon) | ||
920 | iter_data->beacons = true; | ||
921 | break; | 918 | break; |
922 | case NL80211_IFTYPE_STATION: | 919 | case NL80211_IFTYPE_STATION: |
923 | iter_data->nstations++; | 920 | iter_data->nstations++; |
@@ -960,21 +957,6 @@ void ath9k_calculate_iter_data(struct ath_softc *sc, | |||
960 | 957 | ||
961 | list_for_each_entry(avp, &ctx->vifs, list) | 958 | list_for_each_entry(avp, &ctx->vifs, list) |
962 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); | 959 | ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); |
963 | |||
964 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
965 | if (ctx == &sc->offchannel.chan) { | ||
966 | struct ieee80211_vif *vif; | ||
967 | |||
968 | if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START) | ||
969 | vif = sc->offchannel.scan_vif; | ||
970 | else | ||
971 | vif = sc->offchannel.roc_vif; | ||
972 | |||
973 | if (vif) | ||
974 | ath9k_vif_iter(iter_data, vif->addr, vif); | ||
975 | iter_data->beacons = false; | ||
976 | } | ||
977 | #endif | ||
978 | } | 960 | } |
979 | 961 | ||
980 | static void ath9k_set_assoc_state(struct ath_softc *sc, | 962 | static void ath9k_set_assoc_state(struct ath_softc *sc, |
@@ -985,13 +967,6 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, | |||
985 | unsigned long flags; | 967 | unsigned long flags; |
986 | 968 | ||
987 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | 969 | set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
988 | /* Set the AID, BSSID and do beacon-sync only when | ||
989 | * the HW opmode is STATION. | ||
990 | * | ||
991 | * But the primary bit is set above in any case. | ||
992 | */ | ||
993 | if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) | ||
994 | return; | ||
995 | 970 | ||
996 | ether_addr_copy(common->curbssid, bss_conf->bssid); | 971 | ether_addr_copy(common->curbssid, bss_conf->bssid); |
997 | common->curaid = bss_conf->aid; | 972 | common->curaid = bss_conf->aid; |
@@ -1014,6 +989,43 @@ static void ath9k_set_assoc_state(struct ath_softc *sc, | |||
1014 | vif->addr, common->curbssid); | 989 | vif->addr, common->curbssid); |
1015 | } | 990 | } |
1016 | 991 | ||
992 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
993 | static void ath9k_set_offchannel_state(struct ath_softc *sc) | ||
994 | { | ||
995 | struct ath_hw *ah = sc->sc_ah; | ||
996 | struct ath_common *common = ath9k_hw_common(ah); | ||
997 | struct ieee80211_vif *vif = NULL; | ||
998 | |||
999 | ath9k_ps_wakeup(sc); | ||
1000 | |||
1001 | if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START) | ||
1002 | vif = sc->offchannel.scan_vif; | ||
1003 | else | ||
1004 | vif = sc->offchannel.roc_vif; | ||
1005 | |||
1006 | if (WARN_ON(!vif)) | ||
1007 | goto exit; | ||
1008 | |||
1009 | eth_zero_addr(common->curbssid); | ||
1010 | eth_broadcast_addr(common->bssidmask); | ||
1011 | ether_addr_copy(common->macaddr, vif->addr); | ||
1012 | common->curaid = 0; | ||
1013 | ah->opmode = vif->type; | ||
1014 | ah->imask &= ~ATH9K_INT_SWBA; | ||
1015 | ah->imask &= ~ATH9K_INT_TSFOOR; | ||
1016 | ah->slottime = ATH9K_SLOT_TIME_9; | ||
1017 | |||
1018 | ath_hw_setbssidmask(common); | ||
1019 | ath9k_hw_setopmode(ah); | ||
1020 | ath9k_hw_write_associd(sc->sc_ah); | ||
1021 | ath9k_hw_set_interrupts(ah); | ||
1022 | ath9k_hw_init_global_settings(ah); | ||
1023 | |||
1024 | exit: | ||
1025 | ath9k_ps_restore(sc); | ||
1026 | } | ||
1027 | #endif | ||
1028 | |||
1017 | /* Called with sc->mutex held. */ | 1029 | /* Called with sc->mutex held. */ |
1018 | void ath9k_calculate_summary_state(struct ath_softc *sc, | 1030 | void ath9k_calculate_summary_state(struct ath_softc *sc, |
1019 | struct ath_chanctx *ctx) | 1031 | struct ath_chanctx *ctx) |
@@ -1021,12 +1033,18 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1021 | struct ath_hw *ah = sc->sc_ah; | 1033 | struct ath_hw *ah = sc->sc_ah; |
1022 | struct ath_common *common = ath9k_hw_common(ah); | 1034 | struct ath_common *common = ath9k_hw_common(ah); |
1023 | struct ath9k_vif_iter_data iter_data; | 1035 | struct ath9k_vif_iter_data iter_data; |
1036 | struct ath_beacon_config *cur_conf; | ||
1024 | 1037 | ||
1025 | ath_chanctx_check_active(sc, ctx); | 1038 | ath_chanctx_check_active(sc, ctx); |
1026 | 1039 | ||
1027 | if (ctx != sc->cur_chan) | 1040 | if (ctx != sc->cur_chan) |
1028 | return; | 1041 | return; |
1029 | 1042 | ||
1043 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
1044 | if (ctx == &sc->offchannel.chan) | ||
1045 | return ath9k_set_offchannel_state(sc); | ||
1046 | #endif | ||
1047 | |||
1030 | ath9k_ps_wakeup(sc); | 1048 | ath9k_ps_wakeup(sc); |
1031 | ath9k_calculate_iter_data(sc, ctx, &iter_data); | 1049 | ath9k_calculate_iter_data(sc, ctx, &iter_data); |
1032 | 1050 | ||
@@ -1037,8 +1055,11 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1037 | ath_hw_setbssidmask(common); | 1055 | ath_hw_setbssidmask(common); |
1038 | 1056 | ||
1039 | if (iter_data.naps > 0) { | 1057 | if (iter_data.naps > 0) { |
1058 | cur_conf = &ctx->beacon; | ||
1040 | ath9k_hw_set_tsfadjust(ah, true); | 1059 | ath9k_hw_set_tsfadjust(ah, true); |
1041 | ah->opmode = NL80211_IFTYPE_AP; | 1060 | ah->opmode = NL80211_IFTYPE_AP; |
1061 | if (cur_conf->enable_beacon) | ||
1062 | iter_data.beacons = true; | ||
1042 | } else { | 1063 | } else { |
1043 | ath9k_hw_set_tsfadjust(ah, false); | 1064 | ath9k_hw_set_tsfadjust(ah, false); |
1044 | 1065 | ||
@@ -1067,13 +1088,11 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1067 | if (ah->opmode == NL80211_IFTYPE_STATION) { | 1088 | if (ah->opmode == NL80211_IFTYPE_STATION) { |
1068 | bool changed = (iter_data.primary_sta != ctx->primary_sta); | 1089 | bool changed = (iter_data.primary_sta != ctx->primary_sta); |
1069 | 1090 | ||
1070 | iter_data.beacons = true; | ||
1071 | if (iter_data.primary_sta) { | 1091 | if (iter_data.primary_sta) { |
1092 | iter_data.beacons = true; | ||
1072 | ath9k_set_assoc_state(sc, iter_data.primary_sta, | 1093 | ath9k_set_assoc_state(sc, iter_data.primary_sta, |
1073 | changed); | 1094 | changed); |
1074 | if (!ctx->primary_sta || | 1095 | ctx->primary_sta = iter_data.primary_sta; |
1075 | !ctx->primary_sta->bss_conf.assoc) | ||
1076 | ctx->primary_sta = iter_data.primary_sta; | ||
1077 | } else { | 1096 | } else { |
1078 | ctx->primary_sta = NULL; | 1097 | ctx->primary_sta = NULL; |
1079 | memset(common->curbssid, 0, ETH_ALEN); | 1098 | memset(common->curbssid, 0, ETH_ALEN); |
@@ -1102,11 +1121,23 @@ void ath9k_calculate_summary_state(struct ath_softc *sc, | |||
1102 | else | 1121 | else |
1103 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); | 1122 | clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); |
1104 | 1123 | ||
1105 | ctx->primary_sta = iter_data.primary_sta; | ||
1106 | |||
1107 | ath9k_ps_restore(sc); | 1124 | ath9k_ps_restore(sc); |
1108 | } | 1125 | } |
1109 | 1126 | ||
1127 | static void ath9k_assign_hw_queues(struct ieee80211_hw *hw, | ||
1128 | struct ieee80211_vif *vif) | ||
1129 | { | ||
1130 | int i; | ||
1131 | |||
1132 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | ||
1133 | vif->hw_queue[i] = i; | ||
1134 | |||
1135 | if (vif->type == NL80211_IFTYPE_AP) | ||
1136 | vif->cab_queue = hw->queues - 2; | ||
1137 | else | ||
1138 | vif->cab_queue = IEEE80211_INVAL_HW_QUEUE; | ||
1139 | } | ||
1140 | |||
1110 | static int ath9k_add_interface(struct ieee80211_hw *hw, | 1141 | static int ath9k_add_interface(struct ieee80211_hw *hw, |
1111 | struct ieee80211_vif *vif) | 1142 | struct ieee80211_vif *vif) |
1112 | { | 1143 | { |
@@ -1115,12 +1146,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1115 | struct ath_common *common = ath9k_hw_common(ah); | 1146 | struct ath_common *common = ath9k_hw_common(ah); |
1116 | struct ath_vif *avp = (void *)vif->drv_priv; | 1147 | struct ath_vif *avp = (void *)vif->drv_priv; |
1117 | struct ath_node *an = &avp->mcast_node; | 1148 | struct ath_node *an = &avp->mcast_node; |
1118 | int i; | ||
1119 | 1149 | ||
1120 | mutex_lock(&sc->mutex); | 1150 | mutex_lock(&sc->mutex); |
1121 | 1151 | ||
1122 | if (config_enabled(CONFIG_ATH9K_TX99)) { | 1152 | if (config_enabled(CONFIG_ATH9K_TX99)) { |
1123 | if (sc->nvifs >= 1) { | 1153 | if (sc->cur_chan->nvifs >= 1) { |
1124 | mutex_unlock(&sc->mutex); | 1154 | mutex_unlock(&sc->mutex); |
1125 | return -EOPNOTSUPP; | 1155 | return -EOPNOTSUPP; |
1126 | } | 1156 | } |
@@ -1128,7 +1158,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1128 | } | 1158 | } |
1129 | 1159 | ||
1130 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); | 1160 | ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); |
1131 | sc->nvifs++; | 1161 | sc->cur_chan->nvifs++; |
1132 | 1162 | ||
1133 | if (ath9k_uses_beacons(vif->type)) | 1163 | if (ath9k_uses_beacons(vif->type)) |
1134 | ath9k_beacon_assign_slot(sc, vif); | 1164 | ath9k_beacon_assign_slot(sc, vif); |
@@ -1138,12 +1168,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1138 | avp->chanctx = sc->cur_chan; | 1168 | avp->chanctx = sc->cur_chan; |
1139 | list_add_tail(&avp->list, &avp->chanctx->vifs); | 1169 | list_add_tail(&avp->list, &avp->chanctx->vifs); |
1140 | } | 1170 | } |
1141 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 1171 | |
1142 | vif->hw_queue[i] = i; | 1172 | ath9k_assign_hw_queues(hw, vif); |
1143 | if (vif->type == NL80211_IFTYPE_AP) | ||
1144 | vif->cab_queue = hw->queues - 2; | ||
1145 | else | ||
1146 | vif->cab_queue = IEEE80211_INVAL_HW_QUEUE; | ||
1147 | 1173 | ||
1148 | an->sc = sc; | 1174 | an->sc = sc; |
1149 | an->sta = NULL; | 1175 | an->sta = NULL; |
@@ -1163,7 +1189,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1163 | struct ath_softc *sc = hw->priv; | 1189 | struct ath_softc *sc = hw->priv; |
1164 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1190 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1165 | struct ath_vif *avp = (void *)vif->drv_priv; | 1191 | struct ath_vif *avp = (void *)vif->drv_priv; |
1166 | int i; | ||
1167 | 1192 | ||
1168 | mutex_lock(&sc->mutex); | 1193 | mutex_lock(&sc->mutex); |
1169 | 1194 | ||
@@ -1183,14 +1208,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, | |||
1183 | if (ath9k_uses_beacons(vif->type)) | 1208 | if (ath9k_uses_beacons(vif->type)) |
1184 | ath9k_beacon_assign_slot(sc, vif); | 1209 | ath9k_beacon_assign_slot(sc, vif); |
1185 | 1210 | ||
1186 | for (i = 0; i < IEEE80211_NUM_ACS; i++) | 1211 | ath9k_assign_hw_queues(hw, vif); |
1187 | vif->hw_queue[i] = i; | ||
1188 | |||
1189 | if (vif->type == NL80211_IFTYPE_AP) | ||
1190 | vif->cab_queue = hw->queues - 2; | ||
1191 | else | ||
1192 | vif->cab_queue = IEEE80211_INVAL_HW_QUEUE; | ||
1193 | |||
1194 | ath9k_calculate_summary_state(sc, avp->chanctx); | 1212 | ath9k_calculate_summary_state(sc, avp->chanctx); |
1195 | 1213 | ||
1196 | mutex_unlock(&sc->mutex); | 1214 | mutex_unlock(&sc->mutex); |
@@ -1210,7 +1228,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1210 | 1228 | ||
1211 | ath9k_p2p_remove_vif(sc, vif); | 1229 | ath9k_p2p_remove_vif(sc, vif); |
1212 | 1230 | ||
1213 | sc->nvifs--; | 1231 | sc->cur_chan->nvifs--; |
1214 | sc->tx99_vif = NULL; | 1232 | sc->tx99_vif = NULL; |
1215 | if (!ath9k_is_chanctx_enabled()) | 1233 | if (!ath9k_is_chanctx_enabled()) |
1216 | list_del(&avp->list); | 1234 | list_del(&avp->list); |
@@ -1430,7 +1448,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1430 | changed_flags &= SUPPORTED_FILTERS; | 1448 | changed_flags &= SUPPORTED_FILTERS; |
1431 | *total_flags &= SUPPORTED_FILTERS; | 1449 | *total_flags &= SUPPORTED_FILTERS; |
1432 | 1450 | ||
1433 | sc->rx.rxfilter = *total_flags; | 1451 | spin_lock_bh(&sc->chan_lock); |
1452 | sc->cur_chan->rxfilter = *total_flags; | ||
1453 | spin_unlock_bh(&sc->chan_lock); | ||
1454 | |||
1434 | ath9k_ps_wakeup(sc); | 1455 | ath9k_ps_wakeup(sc); |
1435 | rfilt = ath_calcrxfilter(sc); | 1456 | rfilt = ath_calcrxfilter(sc); |
1436 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 1457 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
@@ -1695,9 +1716,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw, | |||
1695 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || | 1716 | if ((changed & BSS_CHANGED_BEACON_ENABLED) || |
1696 | (changed & BSS_CHANGED_BEACON_INT) || | 1717 | (changed & BSS_CHANGED_BEACON_INT) || |
1697 | (changed & BSS_CHANGED_BEACON_INFO)) { | 1718 | (changed & BSS_CHANGED_BEACON_INFO)) { |
1719 | ath9k_beacon_config(sc, vif, changed); | ||
1698 | if (changed & BSS_CHANGED_BEACON_ENABLED) | 1720 | if (changed & BSS_CHANGED_BEACON_ENABLED) |
1699 | ath9k_calculate_summary_state(sc, avp->chanctx); | 1721 | ath9k_calculate_summary_state(sc, avp->chanctx); |
1700 | ath9k_beacon_config(sc, vif, changed); | ||
1701 | } | 1722 | } |
1702 | 1723 | ||
1703 | if ((avp->chanctx == sc->cur_chan) && | 1724 | if ((avp->chanctx == sc->cur_chan) && |
@@ -1859,7 +1880,22 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | |||
1859 | return 0; | 1880 | return 0; |
1860 | } | 1881 | } |
1861 | 1882 | ||
1862 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | 1883 | static void ath9k_enable_dynack(struct ath_softc *sc) |
1884 | { | ||
1885 | #ifdef CONFIG_ATH9K_DYNACK | ||
1886 | u32 rfilt; | ||
1887 | struct ath_hw *ah = sc->sc_ah; | ||
1888 | |||
1889 | ath_dynack_reset(ah); | ||
1890 | |||
1891 | ah->dynack.enabled = true; | ||
1892 | rfilt = ath_calcrxfilter(sc); | ||
1893 | ath9k_hw_setrxfilter(ah, rfilt); | ||
1894 | #endif | ||
1895 | } | ||
1896 | |||
1897 | static void ath9k_set_coverage_class(struct ieee80211_hw *hw, | ||
1898 | s16 coverage_class) | ||
1863 | { | 1899 | { |
1864 | struct ath_softc *sc = hw->priv; | 1900 | struct ath_softc *sc = hw->priv; |
1865 | struct ath_hw *ah = sc->sc_ah; | 1901 | struct ath_hw *ah = sc->sc_ah; |
@@ -1868,11 +1904,22 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) | |||
1868 | return; | 1904 | return; |
1869 | 1905 | ||
1870 | mutex_lock(&sc->mutex); | 1906 | mutex_lock(&sc->mutex); |
1871 | ah->coverage_class = coverage_class; | ||
1872 | 1907 | ||
1873 | ath9k_ps_wakeup(sc); | 1908 | if (coverage_class >= 0) { |
1874 | ath9k_hw_init_global_settings(ah); | 1909 | ah->coverage_class = coverage_class; |
1875 | ath9k_ps_restore(sc); | 1910 | if (ah->dynack.enabled) { |
1911 | u32 rfilt; | ||
1912 | |||
1913 | ah->dynack.enabled = false; | ||
1914 | rfilt = ath_calcrxfilter(sc); | ||
1915 | ath9k_hw_setrxfilter(ah, rfilt); | ||
1916 | } | ||
1917 | ath9k_ps_wakeup(sc); | ||
1918 | ath9k_hw_init_global_settings(ah); | ||
1919 | ath9k_ps_restore(sc); | ||
1920 | } else if (!ah->dynack.enabled) { | ||
1921 | ath9k_enable_dynack(sc); | ||
1922 | } | ||
1876 | 1923 | ||
1877 | mutex_unlock(&sc->mutex); | 1924 | mutex_unlock(&sc->mutex); |
1878 | } | 1925 | } |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 2aaf233ee5d6..6914e21816e4 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -387,7 +387,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
387 | if (sc->hw->conf.radar_enabled) | 387 | if (sc->hw->conf.radar_enabled) |
388 | rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; | 388 | rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; |
389 | 389 | ||
390 | if (sc->rx.rxfilter & FIF_PROBE_REQ) | 390 | spin_lock_bh(&sc->chan_lock); |
391 | |||
392 | if (sc->cur_chan->rxfilter & FIF_PROBE_REQ) | ||
391 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | 393 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; |
392 | 394 | ||
393 | /* | 395 | /* |
@@ -398,24 +400,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
398 | if (sc->sc_ah->is_monitoring) | 400 | if (sc->sc_ah->is_monitoring) |
399 | rfilt |= ATH9K_RX_FILTER_PROM; | 401 | rfilt |= ATH9K_RX_FILTER_PROM; |
400 | 402 | ||
401 | if (sc->rx.rxfilter & FIF_CONTROL) | 403 | if ((sc->cur_chan->rxfilter & FIF_CONTROL) || |
404 | sc->sc_ah->dynack.enabled) | ||
402 | rfilt |= ATH9K_RX_FILTER_CONTROL; | 405 | rfilt |= ATH9K_RX_FILTER_CONTROL; |
403 | 406 | ||
404 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 407 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && |
405 | (sc->nvifs <= 1) && | 408 | (sc->cur_chan->nvifs <= 1) && |
406 | !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) | 409 | !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC)) |
407 | rfilt |= ATH9K_RX_FILTER_MYBEACON; | 410 | rfilt |= ATH9K_RX_FILTER_MYBEACON; |
408 | else | 411 | else |
409 | rfilt |= ATH9K_RX_FILTER_BEACON; | 412 | rfilt |= ATH9K_RX_FILTER_BEACON; |
410 | 413 | ||
411 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 414 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
412 | (sc->rx.rxfilter & FIF_PSPOLL)) | 415 | (sc->cur_chan->rxfilter & FIF_PSPOLL)) |
413 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 416 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
414 | 417 | ||
415 | if (conf_is_ht(&sc->hw->conf)) | 418 | if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT) |
416 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; | 419 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; |
417 | 420 | ||
418 | if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { | 421 | if (sc->cur_chan->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) { |
419 | /* This is needed for older chips */ | 422 | /* This is needed for older chips */ |
420 | if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) | 423 | if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) |
421 | rfilt |= ATH9K_RX_FILTER_PROM; | 424 | rfilt |= ATH9K_RX_FILTER_PROM; |
@@ -429,18 +432,20 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
429 | test_bit(ATH_OP_SCANNING, &common->op_flags)) | 432 | test_bit(ATH_OP_SCANNING, &common->op_flags)) |
430 | rfilt |= ATH9K_RX_FILTER_BEACON; | 433 | rfilt |= ATH9K_RX_FILTER_BEACON; |
431 | 434 | ||
435 | spin_unlock_bh(&sc->chan_lock); | ||
436 | |||
432 | return rfilt; | 437 | return rfilt; |
433 | 438 | ||
434 | } | 439 | } |
435 | 440 | ||
436 | int ath_startrecv(struct ath_softc *sc) | 441 | void ath_startrecv(struct ath_softc *sc) |
437 | { | 442 | { |
438 | struct ath_hw *ah = sc->sc_ah; | 443 | struct ath_hw *ah = sc->sc_ah; |
439 | struct ath_rxbuf *bf, *tbf; | 444 | struct ath_rxbuf *bf, *tbf; |
440 | 445 | ||
441 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | 446 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
442 | ath_edma_start_recv(sc); | 447 | ath_edma_start_recv(sc); |
443 | return 0; | 448 | return; |
444 | } | 449 | } |
445 | 450 | ||
446 | if (list_empty(&sc->rx.rxbuf)) | 451 | if (list_empty(&sc->rx.rxbuf)) |
@@ -463,8 +468,6 @@ int ath_startrecv(struct ath_softc *sc) | |||
463 | start_recv: | 468 | start_recv: |
464 | ath_opmode_init(sc); | 469 | ath_opmode_init(sc); |
465 | ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel); | 470 | ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel); |
466 | |||
467 | return 0; | ||
468 | } | 471 | } |
469 | 472 | ||
470 | static void ath_flushrecv(struct ath_softc *sc) | 473 | static void ath_flushrecv(struct ath_softc *sc) |
@@ -535,6 +538,7 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb) | |||
535 | static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | 538 | static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) |
536 | { | 539 | { |
537 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 540 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
541 | bool skip_beacon = false; | ||
538 | 542 | ||
539 | if (skb->len < 24 + 8 + 2 + 2) | 543 | if (skb->len < 24 + 8 + 2 + 2) |
540 | return; | 544 | return; |
@@ -545,7 +549,16 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) | |||
545 | sc->ps_flags &= ~PS_BEACON_SYNC; | 549 | sc->ps_flags &= ~PS_BEACON_SYNC; |
546 | ath_dbg(common, PS, | 550 | ath_dbg(common, PS, |
547 | "Reconfigure beacon timers based on synchronized timestamp\n"); | 551 | "Reconfigure beacon timers based on synchronized timestamp\n"); |
548 | if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) | 552 | |
553 | #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT | ||
554 | if (ath9k_is_chanctx_enabled()) { | ||
555 | if (sc->cur_chan == &sc->offchannel.chan) | ||
556 | skip_beacon = true; | ||
557 | } | ||
558 | #endif | ||
559 | |||
560 | if (!skip_beacon && | ||
561 | !(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) | ||
549 | ath9k_set_beacon(sc); | 562 | ath9k_set_beacon(sc); |
550 | 563 | ||
551 | ath9k_p2p_beacon_sync(sc); | 564 | ath9k_p2p_beacon_sync(sc); |
@@ -867,8 +880,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
867 | * everything but the rate is checked here, the rate check is done | 880 | * everything but the rate is checked here, the rate check is done |
868 | * separately to avoid doing two lookups for a rate for each frame. | 881 | * separately to avoid doing two lookups for a rate for each frame. |
869 | */ | 882 | */ |
870 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, sc->rx.rxfilter)) | 883 | spin_lock_bh(&sc->chan_lock); |
884 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, | ||
885 | sc->cur_chan->rxfilter)) { | ||
886 | spin_unlock_bh(&sc->chan_lock); | ||
871 | return -EINVAL; | 887 | return -EINVAL; |
888 | } | ||
889 | spin_unlock_bh(&sc->chan_lock); | ||
872 | 890 | ||
873 | if (ath_is_mybeacon(common, hdr)) { | 891 | if (ath_is_mybeacon(common, hdr)) { |
874 | RX_STAT_INC(rx_beacons); | 892 | RX_STAT_INC(rx_beacons); |
@@ -894,7 +912,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
894 | 912 | ||
895 | if (ath9k_is_chanctx_enabled()) { | 913 | if (ath9k_is_chanctx_enabled()) { |
896 | if (rx_stats->is_mybeacon) | 914 | if (rx_stats->is_mybeacon) |
897 | ath_chanctx_beacon_recv_ev(sc, rx_stats->rs_tstamp, | 915 | ath_chanctx_beacon_recv_ev(sc, |
898 | ATH_CHANCTX_EVENT_BEACON_RECEIVED); | 916 | ATH_CHANCTX_EVENT_BEACON_RECEIVED); |
899 | } | 917 | } |
900 | 918 | ||
@@ -992,6 +1010,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
992 | unsigned long flags; | 1010 | unsigned long flags; |
993 | dma_addr_t new_buf_addr; | 1011 | dma_addr_t new_buf_addr; |
994 | unsigned int budget = 512; | 1012 | unsigned int budget = 512; |
1013 | struct ieee80211_hdr *hdr; | ||
995 | 1014 | ||
996 | if (edma) | 1015 | if (edma) |
997 | dma_type = DMA_BIDIRECTIONAL; | 1016 | dma_type = DMA_BIDIRECTIONAL; |
@@ -1121,6 +1140,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1121 | ath9k_apply_ampdu_details(sc, &rs, rxs); | 1140 | ath9k_apply_ampdu_details(sc, &rs, rxs); |
1122 | ath_debug_rate_stats(sc, &rs, skb); | 1141 | ath_debug_rate_stats(sc, &rs, skb); |
1123 | 1142 | ||
1143 | hdr = (struct ieee80211_hdr *)skb->data; | ||
1144 | if (ieee80211_is_ack(hdr->frame_control)) | ||
1145 | ath_dynack_sample_ack_ts(sc->sc_ah, skb, rs.rs_tstamp); | ||
1146 | |||
1124 | ieee80211_rx(hw, skb); | 1147 | ieee80211_rx(hw, skb); |
1125 | 1148 | ||
1126 | requeue_drop_frag: | 1149 | requeue_drop_frag: |
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c index 23972924c774..8a69d08ec55c 100644 --- a/drivers/net/wireless/ath/ath9k/tx99.c +++ b/drivers/net/wireless/ath/ath9k/tx99.c | |||
@@ -174,7 +174,7 @@ static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, | |||
174 | ssize_t len; | 174 | ssize_t len; |
175 | int r; | 175 | int r; |
176 | 176 | ||
177 | if (sc->nvifs > 1) | 177 | if (sc->cur_chan->nvifs > 1) |
178 | return -EOPNOTSUPP; | 178 | return -EOPNOTSUPP; |
179 | 179 | ||
180 | len = min(count, sizeof(buf) - 1); | 180 | len = min(count, sizeof(buf) - 1); |
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index 33531d9a4d50..5f30e580d942 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c | |||
@@ -232,7 +232,7 @@ int ath9k_suspend(struct ieee80211_hw *hw, | |||
232 | goto fail_wow; | 232 | goto fail_wow; |
233 | } | 233 | } |
234 | 234 | ||
235 | if (sc->nvifs > 1) { | 235 | if (sc->cur_chan->nvifs > 1) { |
236 | ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); | 236 | ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); |
237 | ret = 1; | 237 | ret = 1; |
238 | goto fail_wow; | 238 | goto fail_wow; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 281986613fb2..93ad31be0ada 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -587,6 +587,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
587 | memcpy(tx_info->control.rates, rates, sizeof(rates)); | 587 | memcpy(tx_info->control.rates, rates, sizeof(rates)); |
588 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok); | 588 | ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok); |
589 | rc_update = false; | 589 | rc_update = false; |
590 | if (bf == bf->bf_lastbf) | ||
591 | ath_dynack_sample_tx_ts(sc->sc_ah, | ||
592 | bf->bf_mpdu, | ||
593 | ts); | ||
590 | } | 594 | } |
591 | 595 | ||
592 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, | 596 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
@@ -687,6 +691,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq, | |||
687 | memcpy(info->control.rates, bf->rates, | 691 | memcpy(info->control.rates, bf->rates, |
688 | sizeof(info->control.rates)); | 692 | sizeof(info->control.rates)); |
689 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); | 693 | ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); |
694 | ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts); | ||
690 | } | 695 | } |
691 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); | 696 | ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); |
692 | } else | 697 | } else |
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig index ce8c0381825e..481680a3aa55 100644 --- a/drivers/net/wireless/ath/wil6210/Kconfig +++ b/drivers/net/wireless/ath/wil6210/Kconfig | |||
@@ -39,3 +39,12 @@ config WIL6210_TRACING | |||
39 | option if you are interested in debugging the driver. | 39 | option if you are interested in debugging the driver. |
40 | 40 | ||
41 | If unsure, say Y to make it easier to debug problems. | 41 | If unsure, say Y to make it easier to debug problems. |
42 | |||
43 | config WIL6210_PLATFORM_MSM | ||
44 | bool "wil6210 MSM platform specific support" | ||
45 | depends on WIL6210 | ||
46 | depends on ARCH_MSM | ||
47 | default y | ||
48 | ---help--- | ||
49 | Say Y here to enable wil6210 driver support for MSM | ||
50 | platform specific features | ||
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile index c7a3465fd02a..a471d74ae409 100644 --- a/drivers/net/wireless/ath/wil6210/Makefile +++ b/drivers/net/wireless/ath/wil6210/Makefile | |||
@@ -10,7 +10,10 @@ wil6210-y += interrupt.o | |||
10 | wil6210-y += txrx.o | 10 | wil6210-y += txrx.o |
11 | wil6210-y += debug.o | 11 | wil6210-y += debug.o |
12 | wil6210-y += rx_reorder.o | 12 | wil6210-y += rx_reorder.o |
13 | wil6210-y += fw.o | ||
13 | wil6210-$(CONFIG_WIL6210_TRACING) += trace.o | 14 | wil6210-$(CONFIG_WIL6210_TRACING) += trace.o |
15 | wil6210-y += wil_platform.o | ||
16 | wil6210-$(CONFIG_WIL6210_PLATFORM_MSM) += wil_platform_msm.o | ||
14 | 17 | ||
15 | # for tracing framework to find trace.h | 18 | # for tracing framework to find trace.h |
16 | CFLAGS_trace.o := -I$(src) | 19 | CFLAGS_trace.o := -I$(src) |
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c index a00f31881df9..f3a31e8c2535 100644 --- a/drivers/net/wireless/ath/wil6210/cfg80211.c +++ b/drivers/net/wireless/ath/wil6210/cfg80211.c | |||
@@ -296,6 +296,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
296 | n = min(request->n_channels, 4U); | 296 | n = min(request->n_channels, 4U); |
297 | for (i = 0; i < n; i++) { | 297 | for (i = 0; i < n; i++) { |
298 | int ch = request->channels[i]->hw_value; | 298 | int ch = request->channels[i]->hw_value; |
299 | |||
299 | if (ch == 0) { | 300 | if (ch == 0) { |
300 | wil_err(wil, | 301 | wil_err(wil, |
301 | "Scan requested for unknown frequency %dMhz\n", | 302 | "Scan requested for unknown frequency %dMhz\n", |
@@ -308,9 +309,23 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
308 | request->channels[i]->center_freq); | 309 | request->channels[i]->center_freq); |
309 | } | 310 | } |
310 | 311 | ||
312 | if (request->ie_len) | ||
313 | print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET, | ||
314 | request->ie, request->ie_len); | ||
315 | else | ||
316 | wil_dbg_misc(wil, "Scan has no IE's\n"); | ||
317 | |||
318 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len, | ||
319 | request->ie); | ||
320 | if (rc) { | ||
321 | wil_err(wil, "Aborting scan, set_ie failed: %d\n", rc); | ||
322 | goto out; | ||
323 | } | ||
324 | |||
311 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + | 325 | rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + |
312 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); | 326 | cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); |
313 | 327 | ||
328 | out: | ||
314 | if (rc) { | 329 | if (rc) { |
315 | del_timer_sync(&wil->scan_timer); | 330 | del_timer_sync(&wil->scan_timer); |
316 | wil->scan_request = NULL; | 331 | wil->scan_request = NULL; |
@@ -319,6 +334,22 @@ static int wil_cfg80211_scan(struct wiphy *wiphy, | |||
319 | return rc; | 334 | return rc; |
320 | } | 335 | } |
321 | 336 | ||
337 | static void wil_print_connect_params(struct wil6210_priv *wil, | ||
338 | struct cfg80211_connect_params *sme) | ||
339 | { | ||
340 | wil_info(wil, "Connecting to:\n"); | ||
341 | if (sme->channel) { | ||
342 | wil_info(wil, " Channel: %d freq %d\n", | ||
343 | sme->channel->hw_value, sme->channel->center_freq); | ||
344 | } | ||
345 | if (sme->bssid) | ||
346 | wil_info(wil, " BSSID: %pM\n", sme->bssid); | ||
347 | if (sme->ssid) | ||
348 | print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET, | ||
349 | 16, 1, sme->ssid, sme->ssid_len, true); | ||
350 | wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open"); | ||
351 | } | ||
352 | |||
322 | static int wil_cfg80211_connect(struct wiphy *wiphy, | 353 | static int wil_cfg80211_connect(struct wiphy *wiphy, |
323 | struct net_device *ndev, | 354 | struct net_device *ndev, |
324 | struct cfg80211_connect_params *sme) | 355 | struct cfg80211_connect_params *sme) |
@@ -335,6 +366,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
335 | test_bit(wil_status_fwconnected, &wil->status)) | 366 | test_bit(wil_status_fwconnected, &wil->status)) |
336 | return -EALREADY; | 367 | return -EALREADY; |
337 | 368 | ||
369 | wil_print_connect_params(wil, sme); | ||
370 | |||
338 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, | 371 | bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, |
339 | sme->ssid, sme->ssid_len, | 372 | sme->ssid, sme->ssid_len, |
340 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); | 373 | WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); |
@@ -360,22 +393,22 @@ static int wil_cfg80211_connect(struct wiphy *wiphy, | |||
360 | sme->ie_len); | 393 | sme->ie_len); |
361 | goto out; | 394 | goto out; |
362 | } | 395 | } |
363 | /* | 396 | /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */ |
364 | * For secure assoc, send: | ||
365 | * (1) WMI_DELETE_CIPHER_KEY_CMD | ||
366 | * (2) WMI_SET_APPIE_CMD | ||
367 | */ | ||
368 | rc = wmi_del_cipher_key(wil, 0, bss->bssid); | 397 | rc = wmi_del_cipher_key(wil, 0, bss->bssid); |
369 | if (rc) { | 398 | if (rc) { |
370 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n"); | 399 | wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n"); |
371 | goto out; | 400 | goto out; |
372 | } | 401 | } |
373 | /* WMI_SET_APPIE_CMD */ | 402 | } |
374 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); | 403 | |
375 | if (rc) { | 404 | /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info |
376 | wil_err(wil, "WMI_SET_APPIE_CMD failed\n"); | 405 | * elements. Send it also in case it's empty, to erase previously set |
377 | goto out; | 406 | * ies in FW. |
378 | } | 407 | */ |
408 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); | ||
409 | if (rc) { | ||
410 | wil_err(wil, "WMI_SET_APPIE_CMD failed\n"); | ||
411 | goto out; | ||
379 | } | 412 | } |
380 | 413 | ||
381 | /* WMI_CONNECT_CMD */ | 414 | /* WMI_CONNECT_CMD */ |
@@ -621,6 +654,45 @@ static int wil_fix_bcon(struct wil6210_priv *wil, | |||
621 | return rc; | 654 | return rc; |
622 | } | 655 | } |
623 | 656 | ||
657 | static int wil_cfg80211_change_beacon(struct wiphy *wiphy, | ||
658 | struct net_device *ndev, | ||
659 | struct cfg80211_beacon_data *bcon) | ||
660 | { | ||
661 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | ||
662 | int rc; | ||
663 | |||
664 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
665 | |||
666 | if (wil_fix_bcon(wil, bcon)) { | ||
667 | wil_dbg_misc(wil, "Fixed bcon\n"); | ||
668 | wil_print_bcon_data(bcon); | ||
669 | } | ||
670 | |||
671 | /* FW do not form regular beacon, so bcon IE's are not set | ||
672 | * For the DMG bcon, when it will be supported, bcon IE's will | ||
673 | * be reused; add something like: | ||
674 | * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len, | ||
675 | * bcon->beacon_ies); | ||
676 | */ | ||
677 | rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP, | ||
678 | bcon->proberesp_ies_len, | ||
679 | bcon->proberesp_ies); | ||
680 | if (rc) { | ||
681 | wil_err(wil, "set_ie(PROBE_RESP) failed\n"); | ||
682 | return rc; | ||
683 | } | ||
684 | |||
685 | rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP, | ||
686 | bcon->assocresp_ies_len, | ||
687 | bcon->assocresp_ies); | ||
688 | if (rc) { | ||
689 | wil_err(wil, "set_ie(ASSOC_RESP) failed\n"); | ||
690 | return rc; | ||
691 | } | ||
692 | |||
693 | return 0; | ||
694 | } | ||
695 | |||
624 | static int wil_cfg80211_start_ap(struct wiphy *wiphy, | 696 | static int wil_cfg80211_start_ap(struct wiphy *wiphy, |
625 | struct net_device *ndev, | 697 | struct net_device *ndev, |
626 | struct cfg80211_ap_settings *info) | 698 | struct cfg80211_ap_settings *info) |
@@ -658,12 +730,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
658 | 730 | ||
659 | mutex_lock(&wil->mutex); | 731 | mutex_lock(&wil->mutex); |
660 | 732 | ||
661 | rc = wil_reset(wil); | 733 | __wil_down(wil); |
662 | if (rc) | 734 | rc = __wil_up(wil); |
663 | goto out; | ||
664 | |||
665 | /* Rx VRING. */ | ||
666 | rc = wil_rx_init(wil); | ||
667 | if (rc) | 735 | if (rc) |
668 | goto out; | 736 | goto out; |
669 | 737 | ||
@@ -671,9 +739,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
671 | if (rc) | 739 | if (rc) |
672 | goto out; | 740 | goto out; |
673 | 741 | ||
674 | /* MAC address - pre-requisite for other commands */ | ||
675 | wmi_set_mac_address(wil, ndev->dev_addr); | ||
676 | |||
677 | /* IE's */ | 742 | /* IE's */ |
678 | /* bcon 'head IE's are not relevant for 60g band */ | 743 | /* bcon 'head IE's are not relevant for 60g band */ |
679 | /* | 744 | /* |
@@ -695,7 +760,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy, | |||
695 | if (rc) | 760 | if (rc) |
696 | goto out; | 761 | goto out; |
697 | 762 | ||
698 | |||
699 | netif_carrier_on(ndev); | 763 | netif_carrier_on(ndev); |
700 | 764 | ||
701 | out: | 765 | out: |
@@ -706,7 +770,7 @@ out: | |||
706 | static int wil_cfg80211_stop_ap(struct wiphy *wiphy, | 770 | static int wil_cfg80211_stop_ap(struct wiphy *wiphy, |
707 | struct net_device *ndev) | 771 | struct net_device *ndev) |
708 | { | 772 | { |
709 | int rc = 0; | 773 | int rc, rc1; |
710 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); | 774 | struct wil6210_priv *wil = wiphy_to_wil(wiphy); |
711 | 775 | ||
712 | wil_dbg_misc(wil, "%s()\n", __func__); | 776 | wil_dbg_misc(wil, "%s()\n", __func__); |
@@ -715,8 +779,12 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy, | |||
715 | 779 | ||
716 | rc = wmi_pcp_stop(wil); | 780 | rc = wmi_pcp_stop(wil); |
717 | 781 | ||
782 | __wil_down(wil); | ||
783 | rc1 = __wil_up(wil); | ||
784 | |||
718 | mutex_unlock(&wil->mutex); | 785 | mutex_unlock(&wil->mutex); |
719 | return rc; | 786 | |
787 | return min(rc, rc1); | ||
720 | } | 788 | } |
721 | 789 | ||
722 | static int wil_cfg80211_del_station(struct wiphy *wiphy, | 790 | static int wil_cfg80211_del_station(struct wiphy *wiphy, |
@@ -746,6 +814,7 @@ static struct cfg80211_ops wil_cfg80211_ops = { | |||
746 | .del_key = wil_cfg80211_del_key, | 814 | .del_key = wil_cfg80211_del_key, |
747 | .set_default_key = wil_cfg80211_set_default_key, | 815 | .set_default_key = wil_cfg80211_set_default_key, |
748 | /* AP mode */ | 816 | /* AP mode */ |
817 | .change_beacon = wil_cfg80211_change_beacon, | ||
749 | .start_ap = wil_cfg80211_start_ap, | 818 | .start_ap = wil_cfg80211_start_ap, |
750 | .stop_ap = wil_cfg80211_stop_ap, | 819 | .stop_ap = wil_cfg80211_stop_ap, |
751 | .del_station = wil_cfg80211_del_station, | 820 | .del_station = wil_cfg80211_del_station, |
@@ -755,6 +824,7 @@ static void wil_wiphy_init(struct wiphy *wiphy) | |||
755 | { | 824 | { |
756 | /* TODO: set real value */ | 825 | /* TODO: set real value */ |
757 | wiphy->max_scan_ssids = 10; | 826 | wiphy->max_scan_ssids = 10; |
827 | wiphy->max_scan_ie_len = WMI_MAX_IE_LEN; | ||
758 | wiphy->max_num_pmkids = 0 /* TODO: */; | 828 | wiphy->max_num_pmkids = 0 /* TODO: */; |
759 | wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | | 829 | wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
760 | BIT(NL80211_IFTYPE_AP) | | 830 | BIT(NL80211_IFTYPE_AP) | |
@@ -764,8 +834,8 @@ static void wil_wiphy_init(struct wiphy *wiphy) | |||
764 | */ | 834 | */ |
765 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | | 835 | wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | |
766 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; | 836 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; |
767 | dev_warn(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", | 837 | dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", |
768 | __func__, wiphy->flags); | 838 | __func__, wiphy->flags); |
769 | wiphy->probe_resp_offload = | 839 | wiphy->probe_resp_offload = |
770 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | | 840 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | |
771 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | | 841 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | |
@@ -786,7 +856,9 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev) | |||
786 | int rc = 0; | 856 | int rc = 0; |
787 | struct wireless_dev *wdev; | 857 | struct wireless_dev *wdev; |
788 | 858 | ||
789 | wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); | 859 | dev_dbg(dev, "%s()\n", __func__); |
860 | |||
861 | wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); | ||
790 | if (!wdev) | 862 | if (!wdev) |
791 | return ERR_PTR(-ENOMEM); | 863 | return ERR_PTR(-ENOMEM); |
792 | 864 | ||
@@ -818,6 +890,8 @@ void wil_wdev_free(struct wil6210_priv *wil) | |||
818 | { | 890 | { |
819 | struct wireless_dev *wdev = wil_to_wdev(wil); | 891 | struct wireless_dev *wdev = wil_to_wdev(wil); |
820 | 892 | ||
893 | dev_dbg(wil_to_dev(wil), "%s()\n", __func__); | ||
894 | |||
821 | if (!wdev) | 895 | if (!wdev) |
822 | return; | 896 | return; |
823 | 897 | ||
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c index 9eeabf4a5879..8d99021d27a8 100644 --- a/drivers/net/wireless/ath/wil6210/debug.c +++ b/drivers/net/wireless/ath/wil6210/debug.c | |||
@@ -17,43 +17,37 @@ | |||
17 | #include "wil6210.h" | 17 | #include "wil6210.h" |
18 | #include "trace.h" | 18 | #include "trace.h" |
19 | 19 | ||
20 | int wil_err(struct wil6210_priv *wil, const char *fmt, ...) | 20 | void wil_err(struct wil6210_priv *wil, const char *fmt, ...) |
21 | { | 21 | { |
22 | struct net_device *ndev = wil_to_ndev(wil); | 22 | struct net_device *ndev = wil_to_ndev(wil); |
23 | struct va_format vaf = { | 23 | struct va_format vaf = { |
24 | .fmt = fmt, | 24 | .fmt = fmt, |
25 | }; | 25 | }; |
26 | va_list args; | 26 | va_list args; |
27 | int ret; | ||
28 | 27 | ||
29 | va_start(args, fmt); | 28 | va_start(args, fmt); |
30 | vaf.va = &args; | 29 | vaf.va = &args; |
31 | ret = netdev_err(ndev, "%pV", &vaf); | 30 | netdev_err(ndev, "%pV", &vaf); |
32 | trace_wil6210_log_err(&vaf); | 31 | trace_wil6210_log_err(&vaf); |
33 | va_end(args); | 32 | va_end(args); |
34 | |||
35 | return ret; | ||
36 | } | 33 | } |
37 | 34 | ||
38 | int wil_info(struct wil6210_priv *wil, const char *fmt, ...) | 35 | void wil_info(struct wil6210_priv *wil, const char *fmt, ...) |
39 | { | 36 | { |
40 | struct net_device *ndev = wil_to_ndev(wil); | 37 | struct net_device *ndev = wil_to_ndev(wil); |
41 | struct va_format vaf = { | 38 | struct va_format vaf = { |
42 | .fmt = fmt, | 39 | .fmt = fmt, |
43 | }; | 40 | }; |
44 | va_list args; | 41 | va_list args; |
45 | int ret; | ||
46 | 42 | ||
47 | va_start(args, fmt); | 43 | va_start(args, fmt); |
48 | vaf.va = &args; | 44 | vaf.va = &args; |
49 | ret = netdev_info(ndev, "%pV", &vaf); | 45 | netdev_info(ndev, "%pV", &vaf); |
50 | trace_wil6210_log_info(&vaf); | 46 | trace_wil6210_log_info(&vaf); |
51 | va_end(args); | 47 | va_end(args); |
52 | |||
53 | return ret; | ||
54 | } | 48 | } |
55 | 49 | ||
56 | int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...) | 50 | void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...) |
57 | { | 51 | { |
58 | struct va_format vaf = { | 52 | struct va_format vaf = { |
59 | .fmt = fmt, | 53 | .fmt = fmt, |
@@ -64,6 +58,4 @@ int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...) | |||
64 | vaf.va = &args; | 58 | vaf.va = &args; |
65 | trace_wil6210_log_dbg(&vaf); | 59 | trace_wil6210_log_dbg(&vaf); |
66 | va_end(args); | 60 | va_end(args); |
67 | |||
68 | return 0; | ||
69 | } | 61 | } |
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c index b1c6a7293390..eb2204e5fdd4 100644 --- a/drivers/net/wireless/ath/wil6210/debugfs.c +++ b/drivers/net/wireless/ath/wil6210/debugfs.c | |||
@@ -61,20 +61,22 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil, | |||
61 | if (x) | 61 | if (x) |
62 | seq_printf(s, "0x%08x\n", ioread32(x)); | 62 | seq_printf(s, "0x%08x\n", ioread32(x)); |
63 | else | 63 | else |
64 | seq_printf(s, "???\n"); | 64 | seq_puts(s, "???\n"); |
65 | 65 | ||
66 | if (vring->va && (vring->size < 1025)) { | 66 | if (vring->va && (vring->size < 1025)) { |
67 | uint i; | 67 | uint i; |
68 | |||
68 | for (i = 0; i < vring->size; i++) { | 69 | for (i = 0; i < vring->size; i++) { |
69 | volatile struct vring_tx_desc *d = &vring->va[i].tx; | 70 | volatile struct vring_tx_desc *d = &vring->va[i].tx; |
71 | |||
70 | if ((i % 64) == 0 && (i != 0)) | 72 | if ((i % 64) == 0 && (i != 0)) |
71 | seq_printf(s, "\n"); | 73 | seq_puts(s, "\n"); |
72 | seq_printf(s, "%c", (d->dma.status & BIT(0)) ? | 74 | seq_printf(s, "%c", (d->dma.status & BIT(0)) ? |
73 | _s : (vring->ctx[i].skb ? _h : 'h')); | 75 | _s : (vring->ctx[i].skb ? _h : 'h')); |
74 | } | 76 | } |
75 | seq_printf(s, "\n"); | 77 | seq_puts(s, "\n"); |
76 | } | 78 | } |
77 | seq_printf(s, "}\n"); | 79 | seq_puts(s, "}\n"); |
78 | } | 80 | } |
79 | 81 | ||
80 | static int wil_vring_debugfs_show(struct seq_file *s, void *data) | 82 | static int wil_vring_debugfs_show(struct seq_file *s, void *data) |
@@ -85,7 +87,7 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data) | |||
85 | wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_'); | 87 | wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_'); |
86 | 88 | ||
87 | for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { | 89 | for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { |
88 | struct vring *vring = &(wil->vring_tx[i]); | 90 | struct vring *vring = &wil->vring_tx[i]; |
89 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; | 91 | struct vring_tx_data *txdata = &wil->vring_tx_data[i]; |
90 | 92 | ||
91 | if (vring->va) { | 93 | if (vring->va) { |
@@ -163,7 +165,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, | |||
163 | if (!wmi_addr(wil, r.base) || | 165 | if (!wmi_addr(wil, r.base) || |
164 | !wmi_addr(wil, r.tail) || | 166 | !wmi_addr(wil, r.tail) || |
165 | !wmi_addr(wil, r.head)) { | 167 | !wmi_addr(wil, r.head)) { |
166 | seq_printf(s, " ??? pointers are garbage?\n"); | 168 | seq_puts(s, " ??? pointers are garbage?\n"); |
167 | goto out; | 169 | goto out; |
168 | } | 170 | } |
169 | 171 | ||
@@ -182,6 +184,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, | |||
182 | le32_to_cpu(d.addr)); | 184 | le32_to_cpu(d.addr)); |
183 | if (0 == wmi_read_hdr(wil, d.addr, &hdr)) { | 185 | if (0 == wmi_read_hdr(wil, d.addr, &hdr)) { |
184 | u16 len = le16_to_cpu(hdr.len); | 186 | u16 len = le16_to_cpu(hdr.len); |
187 | |||
185 | seq_printf(s, " -> %04x %04x %04x %02x\n", | 188 | seq_printf(s, " -> %04x %04x %04x %02x\n", |
186 | le16_to_cpu(hdr.seq), len, | 189 | le16_to_cpu(hdr.seq), len, |
187 | le16_to_cpu(hdr.type), hdr.flags); | 190 | le16_to_cpu(hdr.type), hdr.flags); |
@@ -199,6 +202,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, | |||
199 | wil_memcpy_fromio_32(databuf, src, len); | 202 | wil_memcpy_fromio_32(databuf, src, len); |
200 | while (n < len) { | 203 | while (n < len) { |
201 | int l = min(len - n, 16); | 204 | int l = min(len - n, 16); |
205 | |||
202 | hex_dump_to_buffer(databuf + n, l, | 206 | hex_dump_to_buffer(databuf + n, l, |
203 | 16, 1, printbuf, | 207 | 16, 1, printbuf, |
204 | sizeof(printbuf), | 208 | sizeof(printbuf), |
@@ -208,11 +212,11 @@ static void wil_print_ring(struct seq_file *s, const char *prefix, | |||
208 | } | 212 | } |
209 | } | 213 | } |
210 | } else { | 214 | } else { |
211 | seq_printf(s, "\n"); | 215 | seq_puts(s, "\n"); |
212 | } | 216 | } |
213 | } | 217 | } |
214 | out: | 218 | out: |
215 | seq_printf(s, "}\n"); | 219 | seq_puts(s, "}\n"); |
216 | } | 220 | } |
217 | 221 | ||
218 | static int wil_mbox_debugfs_show(struct seq_file *s, void *data) | 222 | static int wil_mbox_debugfs_show(struct seq_file *s, void *data) |
@@ -271,11 +275,13 @@ static int wil_debugfs_ulong_set(void *data, u64 val) | |||
271 | *(ulong *)data = val; | 275 | *(ulong *)data = val; |
272 | return 0; | 276 | return 0; |
273 | } | 277 | } |
278 | |||
274 | static int wil_debugfs_ulong_get(void *data, u64 *val) | 279 | static int wil_debugfs_ulong_get(void *data, u64 *val) |
275 | { | 280 | { |
276 | *val = *(ulong *)data; | 281 | *val = *(ulong *)data; |
277 | return 0; | 282 | return 0; |
278 | } | 283 | } |
284 | |||
279 | DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get, | 285 | DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get, |
280 | wil_debugfs_ulong_set, "%llu\n"); | 286 | wil_debugfs_ulong_set, "%llu\n"); |
281 | 287 | ||
@@ -302,7 +308,7 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, | |||
302 | int i; | 308 | int i; |
303 | 309 | ||
304 | for (i = 0; tbl[i].name; i++) { | 310 | for (i = 0; tbl[i].name; i++) { |
305 | struct dentry *f = NULL; | 311 | struct dentry *f; |
306 | 312 | ||
307 | switch (tbl[i].type) { | 313 | switch (tbl[i].type) { |
308 | case doff_u32: | 314 | case doff_u32: |
@@ -322,6 +328,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil, | |||
322 | tbl[i].mode, dbg, | 328 | tbl[i].mode, dbg, |
323 | base + tbl[i].off); | 329 | base + tbl[i].off); |
324 | break; | 330 | break; |
331 | default: | ||
332 | f = ERR_PTR(-EINVAL); | ||
325 | } | 333 | } |
326 | if (IS_ERR_OR_NULL(f)) | 334 | if (IS_ERR_OR_NULL(f)) |
327 | wil_err(wil, "Create file \"%s\": err %ld\n", | 335 | wil_err(wil, "Create file \"%s\": err %ld\n", |
@@ -339,6 +347,7 @@ static const struct dbg_off isr_off[] = { | |||
339 | {"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32}, | 347 | {"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32}, |
340 | {}, | 348 | {}, |
341 | }; | 349 | }; |
350 | |||
342 | static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, | 351 | static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, |
343 | const char *name, | 352 | const char *name, |
344 | struct dentry *parent, u32 off) | 353 | struct dentry *parent, u32 off) |
@@ -422,7 +431,7 @@ static const struct file_operations fops_memread = { | |||
422 | }; | 431 | }; |
423 | 432 | ||
424 | static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, | 433 | static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, |
425 | size_t count, loff_t *ppos) | 434 | size_t count, loff_t *ppos) |
426 | { | 435 | { |
427 | enum { max_count = 4096 }; | 436 | enum { max_count = 4096 }; |
428 | struct debugfs_blob_wrapper *blob = file->private_data; | 437 | struct debugfs_blob_wrapper *blob = file->private_data; |
@@ -474,6 +483,7 @@ struct dentry *wil_debugfs_create_ioblob(const char *name, | |||
474 | { | 483 | { |
475 | return debugfs_create_file(name, mode, parent, blob, &fops_ioblob); | 484 | return debugfs_create_file(name, mode, parent, blob, &fops_ioblob); |
476 | } | 485 | } |
486 | |||
477 | /*---reset---*/ | 487 | /*---reset---*/ |
478 | static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, | 488 | static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, |
479 | size_t len, loff_t *ppos) | 489 | size_t len, loff_t *ppos) |
@@ -499,6 +509,7 @@ static const struct file_operations fops_reset = { | |||
499 | .write = wil_write_file_reset, | 509 | .write = wil_write_file_reset, |
500 | .open = simple_open, | 510 | .open = simple_open, |
501 | }; | 511 | }; |
512 | |||
502 | /*---write channel 1..4 to rxon for it, 0 to rxoff---*/ | 513 | /*---write channel 1..4 to rxon for it, 0 to rxoff---*/ |
503 | static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, | 514 | static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, |
504 | size_t len, loff_t *ppos) | 515 | size_t len, loff_t *ppos) |
@@ -509,6 +520,7 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, | |||
509 | bool on; | 520 | bool on; |
510 | 521 | ||
511 | char *kbuf = kmalloc(len + 1, GFP_KERNEL); | 522 | char *kbuf = kmalloc(len + 1, GFP_KERNEL); |
523 | |||
512 | if (!kbuf) | 524 | if (!kbuf) |
513 | return -ENOMEM; | 525 | return -ENOMEM; |
514 | if (copy_from_user(kbuf, buf, len)) { | 526 | if (copy_from_user(kbuf, buf, len)) { |
@@ -545,6 +557,7 @@ static const struct file_operations fops_rxon = { | |||
545 | .write = wil_write_file_rxon, | 557 | .write = wil_write_file_rxon, |
546 | .open = simple_open, | 558 | .open = simple_open, |
547 | }; | 559 | }; |
560 | |||
548 | /*---tx_mgmt---*/ | 561 | /*---tx_mgmt---*/ |
549 | /* Write mgmt frame to this file to send it */ | 562 | /* Write mgmt frame to this file to send it */ |
550 | static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, | 563 | static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, |
@@ -555,8 +568,8 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, | |||
555 | struct wireless_dev *wdev = wil_to_wdev(wil); | 568 | struct wireless_dev *wdev = wil_to_wdev(wil); |
556 | struct cfg80211_mgmt_tx_params params; | 569 | struct cfg80211_mgmt_tx_params params; |
557 | int rc; | 570 | int rc; |
558 | |||
559 | void *frame = kmalloc(len, GFP_KERNEL); | 571 | void *frame = kmalloc(len, GFP_KERNEL); |
572 | |||
560 | if (!frame) | 573 | if (!frame) |
561 | return -ENOMEM; | 574 | return -ENOMEM; |
562 | 575 | ||
@@ -625,8 +638,10 @@ static void wil_seq_hexdump(struct seq_file *s, void *p, int len, | |||
625 | { | 638 | { |
626 | char printbuf[16 * 3 + 2]; | 639 | char printbuf[16 * 3 + 2]; |
627 | int i = 0; | 640 | int i = 0; |
641 | |||
628 | while (i < len) { | 642 | while (i < len) { |
629 | int l = min(len - i, 16); | 643 | int l = min(len - i, 16); |
644 | |||
630 | hex_dump_to_buffer(p + i, l, 16, 1, printbuf, | 645 | hex_dump_to_buffer(p + i, l, 16, 1, printbuf, |
631 | sizeof(printbuf), false); | 646 | sizeof(printbuf), false); |
632 | seq_printf(s, "%s%s\n", prefix, printbuf); | 647 | seq_printf(s, "%s%s\n", prefix, printbuf); |
@@ -664,10 +679,8 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) | |||
664 | struct wil6210_priv *wil = s->private; | 679 | struct wil6210_priv *wil = s->private; |
665 | struct vring *vring; | 680 | struct vring *vring; |
666 | bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS); | 681 | bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS); |
667 | if (tx) | 682 | |
668 | vring = &(wil->vring_tx[dbg_vring_index]); | 683 | vring = tx ? &wil->vring_tx[dbg_vring_index] : &wil->vring_rx; |
669 | else | ||
670 | vring = &wil->vring_rx; | ||
671 | 684 | ||
672 | if (!vring->va) { | 685 | if (!vring->va) { |
673 | if (tx) | 686 | if (tx) |
@@ -682,7 +695,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) | |||
682 | * only field used, .dma.length, is the same | 695 | * only field used, .dma.length, is the same |
683 | */ | 696 | */ |
684 | volatile struct vring_tx_desc *d = | 697 | volatile struct vring_tx_desc *d = |
685 | &(vring->va[dbg_txdesc_index].tx); | 698 | &vring->va[dbg_txdesc_index].tx; |
686 | volatile u32 *u = (volatile u32 *)d; | 699 | volatile u32 *u = (volatile u32 *)d; |
687 | struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb; | 700 | struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb; |
688 | 701 | ||
@@ -702,7 +715,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data) | |||
702 | wil_seq_print_skb(s, skb); | 715 | wil_seq_print_skb(s, skb); |
703 | kfree_skb(skb); | 716 | kfree_skb(skb); |
704 | } | 717 | } |
705 | seq_printf(s, "}\n"); | 718 | seq_puts(s, "}\n"); |
706 | } else { | 719 | } else { |
707 | if (tx) | 720 | if (tx) |
708 | seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n", | 721 | seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n", |
@@ -816,6 +829,7 @@ static const struct file_operations fops_bf = { | |||
816 | .read = seq_read, | 829 | .read = seq_read, |
817 | .llseek = seq_lseek, | 830 | .llseek = seq_lseek, |
818 | }; | 831 | }; |
832 | |||
819 | /*---------SSID------------*/ | 833 | /*---------SSID------------*/ |
820 | static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf, | 834 | static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf, |
821 | size_t count, loff_t *ppos) | 835 | size_t count, loff_t *ppos) |
@@ -878,10 +892,10 @@ static int wil_temp_debugfs_show(struct seq_file *s, void *data) | |||
878 | { | 892 | { |
879 | struct wil6210_priv *wil = s->private; | 893 | struct wil6210_priv *wil = s->private; |
880 | u32 t_m, t_r; | 894 | u32 t_m, t_r; |
881 | |||
882 | int rc = wmi_get_temperature(wil, &t_m, &t_r); | 895 | int rc = wmi_get_temperature(wil, &t_m, &t_r); |
896 | |||
883 | if (rc) { | 897 | if (rc) { |
884 | seq_printf(s, "Failed\n"); | 898 | seq_puts(s, "Failed\n"); |
885 | return 0; | 899 | return 0; |
886 | } | 900 | } |
887 | 901 | ||
@@ -937,6 +951,7 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data) | |||
937 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 951 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
938 | struct wil_sta_info *p = &wil->sta[i]; | 952 | struct wil_sta_info *p = &wil->sta[i]; |
939 | char *status = "unknown"; | 953 | char *status = "unknown"; |
954 | |||
940 | switch (p->status) { | 955 | switch (p->status) { |
941 | case wil_sta_unused: | 956 | case wil_sta_unused: |
942 | status = "unused "; | 957 | status = "unused "; |
@@ -997,7 +1012,6 @@ static int wil_info_debugfs_show(struct seq_file *s, void *data) | |||
997 | rxf_old = rxf; | 1012 | rxf_old = rxf; |
998 | txf_old = txf; | 1013 | txf_old = txf; |
999 | 1014 | ||
1000 | |||
1001 | #define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \ | 1015 | #define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \ |
1002 | " " __stringify(x) : "" | 1016 | " " __stringify(x) : "" |
1003 | 1017 | ||
@@ -1032,6 +1046,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r) | |||
1032 | { | 1046 | { |
1033 | int i; | 1047 | int i; |
1034 | u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; | 1048 | u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; |
1049 | |||
1035 | seq_printf(s, "0x%03x [", r->head_seq_num); | 1050 | seq_printf(s, "0x%03x [", r->head_seq_num); |
1036 | for (i = 0; i < r->buf_size; i++) { | 1051 | for (i = 0; i < r->buf_size; i++) { |
1037 | if (i == index) | 1052 | if (i == index) |
@@ -1046,10 +1061,12 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) | |||
1046 | { | 1061 | { |
1047 | struct wil6210_priv *wil = s->private; | 1062 | struct wil6210_priv *wil = s->private; |
1048 | int i, tid; | 1063 | int i, tid; |
1064 | unsigned long flags; | ||
1049 | 1065 | ||
1050 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { | 1066 | for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { |
1051 | struct wil_sta_info *p = &wil->sta[i]; | 1067 | struct wil_sta_info *p = &wil->sta[i]; |
1052 | char *status = "unknown"; | 1068 | char *status = "unknown"; |
1069 | |||
1053 | switch (p->status) { | 1070 | switch (p->status) { |
1054 | case wil_sta_unused: | 1071 | case wil_sta_unused: |
1055 | status = "unused "; | 1072 | status = "unused "; |
@@ -1065,13 +1082,16 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data) | |||
1065 | (p->data_port_open ? " data_port_open" : "")); | 1082 | (p->data_port_open ? " data_port_open" : "")); |
1066 | 1083 | ||
1067 | if (p->status == wil_sta_connected) { | 1084 | if (p->status == wil_sta_connected) { |
1085 | spin_lock_irqsave(&p->tid_rx_lock, flags); | ||
1068 | for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { | 1086 | for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { |
1069 | struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; | 1087 | struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; |
1088 | |||
1070 | if (r) { | 1089 | if (r) { |
1071 | seq_printf(s, "[%2d] ", tid); | 1090 | seq_printf(s, "[%2d] ", tid); |
1072 | wil_print_rxtid(s, r); | 1091 | wil_print_rxtid(s, r); |
1073 | } | 1092 | } |
1074 | } | 1093 | } |
1094 | spin_unlock_irqrestore(&p->tid_rx_lock, flags); | ||
1075 | } | 1095 | } |
1076 | } | 1096 | } |
1077 | 1097 | ||
diff --git a/drivers/net/wireless/ath/wil6210/fw.c b/drivers/net/wireless/ath/wil6210/fw.c new file mode 100644 index 000000000000..8c6f3b041f77 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/fw.c | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #include <linux/firmware.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/crc32.h> | ||
20 | #include "wil6210.h" | ||
21 | #include "fw.h" | ||
22 | |||
23 | MODULE_FIRMWARE(WIL_FW_NAME); | ||
24 | |||
25 | /* target operations */ | ||
26 | /* register read */ | ||
27 | #define R(a) ioread32(wil->csr + HOSTADDR(a)) | ||
28 | /* register write. wmb() to make sure it is completed */ | ||
29 | #define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) | ||
30 | /* register set = read, OR, write */ | ||
31 | #define S(a, v) W(a, R(a) | v) | ||
32 | /* register clear = read, AND with inverted, write */ | ||
33 | #define C(a, v) W(a, R(a) & ~v) | ||
34 | |||
35 | static | ||
36 | void wil_memset_toio_32(volatile void __iomem *dst, u32 val, | ||
37 | size_t count) | ||
38 | { | ||
39 | volatile u32 __iomem *d = dst; | ||
40 | |||
41 | for (count += 4; count > 4; count -= 4) | ||
42 | __raw_writel(val, d++); | ||
43 | } | ||
44 | |||
45 | #include "fw_inc.c" | ||
diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h new file mode 100644 index 000000000000..7a2c6c129ad5 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/fw.h | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #define WIL_FW_SIGNATURE (0x36323130) /* '0126' */ | ||
18 | #define WIL_FW_FMT_VERSION (1) /* format version driver supports */ | ||
19 | |||
20 | enum wil_fw_record_type { | ||
21 | wil_fw_type_comment = 1, | ||
22 | wil_fw_type_data = 2, | ||
23 | wil_fw_type_fill = 3, | ||
24 | wil_fw_type_action = 4, | ||
25 | wil_fw_type_verify = 5, | ||
26 | wil_fw_type_file_header = 6, | ||
27 | wil_fw_type_direct_write = 7, | ||
28 | wil_fw_type_gateway_data = 8, | ||
29 | wil_fw_type_gateway_data4 = 9, | ||
30 | }; | ||
31 | |||
32 | struct wil_fw_record_head { | ||
33 | __le16 type; /* enum wil_fw_record_type */ | ||
34 | __le16 flags; /* to be defined */ | ||
35 | __le32 size; /* whole record, bytes after head */ | ||
36 | } __packed; | ||
37 | |||
38 | /* data block. write starting from @addr | ||
39 | * data_size inferred from the @head.size. For this case, | ||
40 | * data_size = @head.size - offsetof(struct wil_fw_record_data, data) | ||
41 | */ | ||
42 | struct wil_fw_record_data { /* type == wil_fw_type_data */ | ||
43 | __le32 addr; | ||
44 | __le32 data[0]; /* [data_size], see above */ | ||
45 | } __packed; | ||
46 | |||
47 | /* fill with constant @value, @size bytes starting from @addr */ | ||
48 | struct wil_fw_record_fill { /* type == wil_fw_type_fill */ | ||
49 | __le32 addr; | ||
50 | __le32 value; | ||
51 | __le32 size; | ||
52 | } __packed; | ||
53 | |||
54 | /* free-form comment | ||
55 | * for informational purpose, data_size is @head.size from record header | ||
56 | */ | ||
57 | struct wil_fw_record_comment { /* type == wil_fw_type_comment */ | ||
58 | u8 data[0]; /* free-form data [data_size], see above */ | ||
59 | } __packed; | ||
60 | |||
61 | /* perform action | ||
62 | * data_size = @head.size - offsetof(struct wil_fw_record_action, data) | ||
63 | */ | ||
64 | struct wil_fw_record_action { /* type == wil_fw_type_action */ | ||
65 | __le32 action; /* action to perform: reset, wait for fw ready etc. */ | ||
66 | __le32 data[0]; /* action specific, [data_size], see above */ | ||
67 | } __packed; | ||
68 | |||
69 | /* data block for struct wil_fw_record_direct_write */ | ||
70 | struct wil_fw_data_dwrite { | ||
71 | __le32 addr; | ||
72 | __le32 value; | ||
73 | __le32 mask; | ||
74 | } __packed; | ||
75 | |||
76 | /* write @value to the @addr, | ||
77 | * preserve original bits accordingly to the @mask | ||
78 | * data_size is @head.size where @head is record header | ||
79 | */ | ||
80 | struct wil_fw_record_direct_write { /* type == wil_fw_type_direct_write */ | ||
81 | struct wil_fw_data_dwrite data[0]; | ||
82 | } __packed; | ||
83 | |||
84 | /* verify condition: [@addr] & @mask == @value | ||
85 | * if condition not met, firmware download fails | ||
86 | */ | ||
87 | struct wil_fw_record_verify { /* type == wil_fw_verify */ | ||
88 | __le32 addr; /* read from this address */ | ||
89 | __le32 value; /* reference value */ | ||
90 | __le32 mask; /* mask for verification */ | ||
91 | } __packed; | ||
92 | |||
93 | /* file header | ||
94 | * First record of every file | ||
95 | */ | ||
96 | struct wil_fw_record_file_header { | ||
97 | __le32 signature ; /* Wilocity signature */ | ||
98 | __le32 reserved; | ||
99 | __le32 crc; /* crc32 of the following data */ | ||
100 | __le32 version; /* format version */ | ||
101 | __le32 data_len; /* total data in file, including this record */ | ||
102 | u8 comment[32]; /* short description */ | ||
103 | } __packed; | ||
104 | |||
105 | /* 1-dword gateway */ | ||
106 | /* data block for the struct wil_fw_record_gateway_data */ | ||
107 | struct wil_fw_data_gw { | ||
108 | __le32 addr; | ||
109 | __le32 value; | ||
110 | } __packed; | ||
111 | |||
112 | /* gateway write block. | ||
113 | * write starting address and values from the data buffer | ||
114 | * through the gateway | ||
115 | * data_size inferred from the @head.size. For this case, | ||
116 | * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data, data) | ||
117 | */ | ||
118 | struct wil_fw_record_gateway_data { /* type == wil_fw_type_gateway_data */ | ||
119 | __le32 gateway_addr_addr; | ||
120 | __le32 gateway_value_addr; | ||
121 | __le32 gateway_cmd_addr; | ||
122 | __le32 gateway_ctrl_address; | ||
123 | #define WIL_FW_GW_CTL_BUSY BIT(29) /* gateway busy performing operation */ | ||
124 | #define WIL_FW_GW_CTL_RUN BIT(30) /* start gateway operation */ | ||
125 | __le32 command; | ||
126 | struct wil_fw_data_gw data[0]; /* total size [data_size], see above */ | ||
127 | } __packed; | ||
128 | |||
129 | /* 4-dword gateway */ | ||
130 | /* data block for the struct wil_fw_record_gateway_data4 */ | ||
131 | struct wil_fw_data_gw4 { | ||
132 | __le32 addr; | ||
133 | __le32 value[4]; | ||
134 | } __packed; | ||
135 | |||
136 | /* gateway write block. | ||
137 | * write starting address and values from the data buffer | ||
138 | * through the gateway | ||
139 | * data_size inferred from the @head.size. For this case, | ||
140 | * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data4, data) | ||
141 | */ | ||
142 | struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */ | ||
143 | __le32 gateway_addr_addr; | ||
144 | __le32 gateway_value_addr[4]; | ||
145 | __le32 gateway_cmd_addr; | ||
146 | __le32 gateway_ctrl_address; /* same logic as for 1-dword gw */ | ||
147 | __le32 command; | ||
148 | struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */ | ||
149 | } __packed; | ||
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c new file mode 100644 index 000000000000..44cb71f5ea5b --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/fw_inc.c | |||
@@ -0,0 +1,495 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /* Algorithmic part of the firmware download. | ||
18 | * To be included in the container file providing framework | ||
19 | */ | ||
20 | |||
21 | #define wil_err_fw(wil, fmt, arg...) wil_err(wil, "ERR[ FW ]" fmt, ##arg) | ||
22 | #define wil_dbg_fw(wil, fmt, arg...) wil_dbg(wil, "DBG[ FW ]" fmt, ##arg) | ||
23 | #define wil_hex_dump_fw(prefix_str, prefix_type, rowsize, \ | ||
24 | groupsize, buf, len, ascii) \ | ||
25 | print_hex_dump_debug("DBG[ FW ]" prefix_str, \ | ||
26 | prefix_type, rowsize, \ | ||
27 | groupsize, buf, len, ascii) | ||
28 | |||
29 | #define FW_ADDR_CHECK(ioaddr, val, msg) do { \ | ||
30 | ioaddr = wmi_buffer(wil, val); \ | ||
31 | if (!ioaddr) { \ | ||
32 | wil_err_fw(wil, "bad " msg ": 0x%08x\n", \ | ||
33 | le32_to_cpu(val)); \ | ||
34 | return -EINVAL; \ | ||
35 | } \ | ||
36 | } while (0) | ||
37 | |||
38 | /** | ||
39 | * wil_fw_verify - verify firmware file validity | ||
40 | * | ||
41 | * perform various checks for the firmware file header. | ||
42 | * records are not validated. | ||
43 | * | ||
44 | * Return file size or negative error | ||
45 | */ | ||
46 | static int wil_fw_verify(struct wil6210_priv *wil, const u8 *data, size_t size) | ||
47 | { | ||
48 | const struct wil_fw_record_head *hdr = (const void *)data; | ||
49 | struct wil_fw_record_file_header fh; | ||
50 | const struct wil_fw_record_file_header *fh_; | ||
51 | u32 crc; | ||
52 | u32 dlen; | ||
53 | |||
54 | if (size % 4) { | ||
55 | wil_err_fw(wil, "image size not aligned: %zu\n", size); | ||
56 | return -EINVAL; | ||
57 | } | ||
58 | /* have enough data for the file header? */ | ||
59 | if (size < sizeof(*hdr) + sizeof(fh)) { | ||
60 | wil_err_fw(wil, "file too short: %zu bytes\n", size); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | /* start with the file header? */ | ||
65 | if (le16_to_cpu(hdr->type) != wil_fw_type_file_header) { | ||
66 | wil_err_fw(wil, "no file header\n"); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | |||
70 | /* data_len */ | ||
71 | fh_ = (struct wil_fw_record_file_header *)&hdr[1]; | ||
72 | dlen = le32_to_cpu(fh_->data_len); | ||
73 | if (dlen % 4) { | ||
74 | wil_err_fw(wil, "data length not aligned: %lu\n", (ulong)dlen); | ||
75 | return -EINVAL; | ||
76 | } | ||
77 | if (size < dlen) { | ||
78 | wil_err_fw(wil, "file truncated at %zu/%lu\n", | ||
79 | size, (ulong)dlen); | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | if (dlen < sizeof(*hdr) + sizeof(fh)) { | ||
83 | wil_err_fw(wil, "data length too short: %lu\n", (ulong)dlen); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | /* signature */ | ||
88 | if (le32_to_cpu(fh_->signature) != WIL_FW_SIGNATURE) { | ||
89 | wil_err_fw(wil, "bad header signature: 0x%08x\n", | ||
90 | le32_to_cpu(fh_->signature)); | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | |||
94 | /* version */ | ||
95 | if (le32_to_cpu(fh_->version) > WIL_FW_FMT_VERSION) { | ||
96 | wil_err_fw(wil, "unsupported header version: %d\n", | ||
97 | le32_to_cpu(fh_->version)); | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | |||
101 | /* checksum. ~crc32(~0, data, size) when fh.crc set to 0*/ | ||
102 | fh = *fh_; | ||
103 | fh.crc = 0; | ||
104 | |||
105 | crc = crc32_le(~0, (unsigned char const *)hdr, sizeof(*hdr)); | ||
106 | crc = crc32_le(crc, (unsigned char const *)&fh, sizeof(fh)); | ||
107 | crc = crc32_le(crc, (unsigned char const *)&fh_[1], | ||
108 | dlen - sizeof(*hdr) - sizeof(fh)); | ||
109 | crc = ~crc; | ||
110 | |||
111 | if (crc != le32_to_cpu(fh_->crc)) { | ||
112 | wil_err_fw(wil, "checksum mismatch:" | ||
113 | " calculated for %lu bytes 0x%08x != 0x%08x\n", | ||
114 | (ulong)dlen, crc, le32_to_cpu(fh_->crc)); | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | |||
118 | return (int)dlen; | ||
119 | } | ||
120 | |||
121 | static int fw_handle_comment(struct wil6210_priv *wil, const void *data, | ||
122 | size_t size) | ||
123 | { | ||
124 | wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int fw_handle_data(struct wil6210_priv *wil, const void *data, | ||
130 | size_t size) | ||
131 | { | ||
132 | const struct wil_fw_record_data *d = data; | ||
133 | void __iomem *dst; | ||
134 | size_t s = size - sizeof(*d); | ||
135 | |||
136 | if (size < sizeof(*d) + sizeof(u32)) { | ||
137 | wil_err_fw(wil, "data record too short: %zu\n", size); | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | |||
141 | FW_ADDR_CHECK(dst, d->addr, "address"); | ||
142 | wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr), | ||
143 | s); | ||
144 | wil_memcpy_toio_32(dst, d->data, s); | ||
145 | wmb(); /* finish before processing next record */ | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int fw_handle_fill(struct wil6210_priv *wil, const void *data, | ||
151 | size_t size) | ||
152 | { | ||
153 | const struct wil_fw_record_fill *d = data; | ||
154 | void __iomem *dst; | ||
155 | u32 v; | ||
156 | size_t s = (size_t)le32_to_cpu(d->size); | ||
157 | |||
158 | if (size != sizeof(*d)) { | ||
159 | wil_err_fw(wil, "bad size for fill record: %zu\n", size); | ||
160 | return -EINVAL; | ||
161 | } | ||
162 | |||
163 | if (s < sizeof(u32)) { | ||
164 | wil_err_fw(wil, "fill size too short: %zu\n", s); | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
168 | if (s % sizeof(u32)) { | ||
169 | wil_err_fw(wil, "fill size not aligned: %zu\n", s); | ||
170 | return -EINVAL; | ||
171 | } | ||
172 | |||
173 | FW_ADDR_CHECK(dst, d->addr, "address"); | ||
174 | |||
175 | v = le32_to_cpu(d->value); | ||
176 | wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n", | ||
177 | le32_to_cpu(d->addr), v, s); | ||
178 | wil_memset_toio_32(dst, v, s); | ||
179 | wmb(); /* finish before processing next record */ | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | static int fw_handle_file_header(struct wil6210_priv *wil, const void *data, | ||
185 | size_t size) | ||
186 | { | ||
187 | const struct wil_fw_record_file_header *d = data; | ||
188 | |||
189 | if (size != sizeof(*d)) { | ||
190 | wil_err_fw(wil, "file header length incorrect: %zu\n", size); | ||
191 | return -EINVAL; | ||
192 | } | ||
193 | |||
194 | wil_dbg_fw(wil, "new file, ver. %d, %i bytes\n", | ||
195 | d->version, d->data_len); | ||
196 | wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment, | ||
197 | sizeof(d->comment), true); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data, | ||
203 | size_t size) | ||
204 | { | ||
205 | const struct wil_fw_record_direct_write *d = data; | ||
206 | const struct wil_fw_data_dwrite *block = d->data; | ||
207 | int n, i; | ||
208 | |||
209 | if (size % sizeof(*block)) { | ||
210 | wil_err_fw(wil, "record size not aligned on %zu: %zu\n", | ||
211 | sizeof(*block), size); | ||
212 | return -EINVAL; | ||
213 | } | ||
214 | n = size / sizeof(*block); | ||
215 | |||
216 | for (i = 0; i < n; i++) { | ||
217 | void __iomem *dst; | ||
218 | u32 m = le32_to_cpu(block[i].mask); | ||
219 | u32 v = le32_to_cpu(block[i].value); | ||
220 | u32 x, y; | ||
221 | |||
222 | FW_ADDR_CHECK(dst, block[i].addr, "address"); | ||
223 | |||
224 | x = ioread32(dst); | ||
225 | y = (x & m) | (v & ~m); | ||
226 | wil_dbg_fw(wil, "write [0x%08x] <== 0x%08x " | ||
227 | "(old 0x%08x val 0x%08x mask 0x%08x)\n", | ||
228 | le32_to_cpu(block[i].addr), y, x, v, m); | ||
229 | iowrite32(y, dst); | ||
230 | wmb(); /* finish before processing next record */ | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int gw_write(struct wil6210_priv *wil, void __iomem *gwa_addr, | ||
237 | void __iomem *gwa_cmd, void __iomem *gwa_ctl, u32 gw_cmd, | ||
238 | u32 a) | ||
239 | { | ||
240 | unsigned delay = 0; | ||
241 | |||
242 | iowrite32(a, gwa_addr); | ||
243 | iowrite32(gw_cmd, gwa_cmd); | ||
244 | wmb(); /* finish before activate gw */ | ||
245 | |||
246 | iowrite32(WIL_FW_GW_CTL_RUN, gwa_ctl); /* activate gw */ | ||
247 | do { | ||
248 | udelay(1); /* typical time is few usec */ | ||
249 | if (delay++ > 100) { | ||
250 | wil_err_fw(wil, "gw timeout\n"); | ||
251 | return -EINVAL; | ||
252 | } | ||
253 | } while (ioread32(gwa_ctl) & WIL_FW_GW_CTL_BUSY); /* gw done? */ | ||
254 | |||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data, | ||
259 | size_t size) | ||
260 | { | ||
261 | const struct wil_fw_record_gateway_data *d = data; | ||
262 | const struct wil_fw_data_gw *block = d->data; | ||
263 | void __iomem *gwa_addr; | ||
264 | void __iomem *gwa_val; | ||
265 | void __iomem *gwa_cmd; | ||
266 | void __iomem *gwa_ctl; | ||
267 | u32 gw_cmd; | ||
268 | int n, i; | ||
269 | |||
270 | if (size < sizeof(*d) + sizeof(*block)) { | ||
271 | wil_err_fw(wil, "gateway record too short: %zu\n", size); | ||
272 | return -EINVAL; | ||
273 | } | ||
274 | |||
275 | if ((size - sizeof(*d)) % sizeof(*block)) { | ||
276 | wil_err_fw(wil, "gateway record data size" | ||
277 | " not aligned on %zu: %zu\n", | ||
278 | sizeof(*block), size - sizeof(*d)); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | n = (size - sizeof(*d)) / sizeof(*block); | ||
282 | |||
283 | gw_cmd = le32_to_cpu(d->command); | ||
284 | |||
285 | wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n", | ||
286 | n, gw_cmd); | ||
287 | |||
288 | FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); | ||
289 | FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr"); | ||
290 | FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); | ||
291 | FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); | ||
292 | |||
293 | wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x" | ||
294 | " cmd 0x%08x ctl 0x%08x\n", | ||
295 | le32_to_cpu(d->gateway_addr_addr), | ||
296 | le32_to_cpu(d->gateway_value_addr), | ||
297 | le32_to_cpu(d->gateway_cmd_addr), | ||
298 | le32_to_cpu(d->gateway_ctrl_address)); | ||
299 | |||
300 | for (i = 0; i < n; i++) { | ||
301 | int rc; | ||
302 | u32 a = le32_to_cpu(block[i].addr); | ||
303 | u32 v = le32_to_cpu(block[i].value); | ||
304 | |||
305 | wil_dbg_fw(wil, " gw write[%3d] [0x%08x] <== 0x%08x\n", | ||
306 | i, a, v); | ||
307 | |||
308 | iowrite32(v, gwa_val); | ||
309 | rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a); | ||
310 | if (rc) | ||
311 | return rc; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data, | ||
318 | size_t size) | ||
319 | { | ||
320 | const struct wil_fw_record_gateway_data4 *d = data; | ||
321 | const struct wil_fw_data_gw4 *block = d->data; | ||
322 | void __iomem *gwa_addr; | ||
323 | void __iomem *gwa_val[ARRAY_SIZE(block->value)]; | ||
324 | void __iomem *gwa_cmd; | ||
325 | void __iomem *gwa_ctl; | ||
326 | u32 gw_cmd; | ||
327 | int n, i, k; | ||
328 | |||
329 | if (size < sizeof(*d) + sizeof(*block)) { | ||
330 | wil_err_fw(wil, "gateway4 record too short: %zu\n", size); | ||
331 | return -EINVAL; | ||
332 | } | ||
333 | |||
334 | if ((size - sizeof(*d)) % sizeof(*block)) { | ||
335 | wil_err_fw(wil, "gateway4 record data size" | ||
336 | " not aligned on %zu: %zu\n", | ||
337 | sizeof(*block), size - sizeof(*d)); | ||
338 | return -EINVAL; | ||
339 | } | ||
340 | n = (size - sizeof(*d)) / sizeof(*block); | ||
341 | |||
342 | gw_cmd = le32_to_cpu(d->command); | ||
343 | |||
344 | wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n", | ||
345 | n, gw_cmd); | ||
346 | |||
347 | FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr"); | ||
348 | for (k = 0; k < ARRAY_SIZE(block->value); k++) | ||
349 | FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k], | ||
350 | "gateway_value_addr"); | ||
351 | FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr"); | ||
352 | FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address"); | ||
353 | |||
354 | wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n", | ||
355 | le32_to_cpu(d->gateway_addr_addr), | ||
356 | le32_to_cpu(d->gateway_cmd_addr), | ||
357 | le32_to_cpu(d->gateway_ctrl_address)); | ||
358 | wil_hex_dump_fw("val addresses: ", DUMP_PREFIX_NONE, 16, 4, | ||
359 | d->gateway_value_addr, sizeof(d->gateway_value_addr), | ||
360 | false); | ||
361 | |||
362 | for (i = 0; i < n; i++) { | ||
363 | int rc; | ||
364 | u32 a = le32_to_cpu(block[i].addr); | ||
365 | u32 v[ARRAY_SIZE(block->value)]; | ||
366 | |||
367 | for (k = 0; k < ARRAY_SIZE(block->value); k++) | ||
368 | v[k] = le32_to_cpu(block[i].value[k]); | ||
369 | |||
370 | wil_dbg_fw(wil, " gw4 write[%3d] [0x%08x] <==\n", i, a); | ||
371 | wil_hex_dump_fw(" val ", DUMP_PREFIX_NONE, 16, 4, v, | ||
372 | sizeof(v), false); | ||
373 | |||
374 | for (k = 0; k < ARRAY_SIZE(block->value); k++) | ||
375 | iowrite32(v[k], gwa_val[k]); | ||
376 | rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a); | ||
377 | if (rc) | ||
378 | return rc; | ||
379 | } | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static const struct { | ||
385 | int type; | ||
386 | int (*handler)(struct wil6210_priv *wil, const void *data, size_t size); | ||
387 | } wil_fw_handlers[] = { | ||
388 | {wil_fw_type_comment, fw_handle_comment}, | ||
389 | {wil_fw_type_data, fw_handle_data}, | ||
390 | {wil_fw_type_fill, fw_handle_fill}, | ||
391 | /* wil_fw_type_action */ | ||
392 | /* wil_fw_type_verify */ | ||
393 | {wil_fw_type_file_header, fw_handle_file_header}, | ||
394 | {wil_fw_type_direct_write, fw_handle_direct_write}, | ||
395 | {wil_fw_type_gateway_data, fw_handle_gateway_data}, | ||
396 | {wil_fw_type_gateway_data4, fw_handle_gateway_data4}, | ||
397 | }; | ||
398 | |||
399 | static int wil_fw_handle_record(struct wil6210_priv *wil, int type, | ||
400 | const void *data, size_t size) | ||
401 | { | ||
402 | int i; | ||
403 | |||
404 | for (i = 0; i < ARRAY_SIZE(wil_fw_handlers); i++) { | ||
405 | if (wil_fw_handlers[i].type == type) | ||
406 | return wil_fw_handlers[i].handler(wil, data, size); | ||
407 | } | ||
408 | |||
409 | wil_err_fw(wil, "unknown record type: %d\n", type); | ||
410 | return -EINVAL; | ||
411 | } | ||
412 | |||
413 | /** | ||
414 | * wil_fw_load - load FW into device | ||
415 | * | ||
416 | * Load the FW and uCode code and data to the corresponding device | ||
417 | * memory regions | ||
418 | * | ||
419 | * Return error code | ||
420 | */ | ||
421 | static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size) | ||
422 | { | ||
423 | int rc = 0; | ||
424 | const struct wil_fw_record_head *hdr; | ||
425 | size_t s, hdr_sz; | ||
426 | |||
427 | for (hdr = data;; hdr = (const void *)hdr + s, size -= s) { | ||
428 | if (size < sizeof(*hdr)) | ||
429 | break; | ||
430 | hdr_sz = le32_to_cpu(hdr->size); | ||
431 | s = sizeof(*hdr) + hdr_sz; | ||
432 | if (s > size) | ||
433 | break; | ||
434 | if (hdr_sz % 4) { | ||
435 | wil_err_fw(wil, "unaligned record size: %zu\n", | ||
436 | hdr_sz); | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | rc = wil_fw_handle_record(wil, le16_to_cpu(hdr->type), | ||
440 | &hdr[1], hdr_sz); | ||
441 | if (rc) | ||
442 | return rc; | ||
443 | } | ||
444 | if (size) { | ||
445 | wil_err_fw(wil, "unprocessed bytes: %zu\n", size); | ||
446 | if (size >= sizeof(*hdr)) { | ||
447 | wil_err_fw(wil, "Stop at offset %ld" | ||
448 | " record type %d [%zd bytes]\n", | ||
449 | (const void *)hdr - data, | ||
450 | le16_to_cpu(hdr->type), hdr_sz); | ||
451 | } | ||
452 | return -EINVAL; | ||
453 | } | ||
454 | /* Mark FW as loaded from host */ | ||
455 | S(RGF_USER_USAGE_6, 1); | ||
456 | |||
457 | return rc; | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * wil_request_firmware - Request firmware and load to device | ||
462 | * | ||
463 | * Request firmware image from the file and load it to device | ||
464 | * | ||
465 | * Return error code | ||
466 | */ | ||
467 | int wil_request_firmware(struct wil6210_priv *wil, const char *name) | ||
468 | { | ||
469 | int rc, rc1; | ||
470 | const struct firmware *fw; | ||
471 | size_t sz; | ||
472 | const void *d; | ||
473 | |||
474 | rc = request_firmware(&fw, name, wil_to_pcie_dev(wil)); | ||
475 | if (rc) { | ||
476 | wil_err_fw(wil, "Failed to load firmware %s\n", name); | ||
477 | return rc; | ||
478 | } | ||
479 | wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size); | ||
480 | |||
481 | for (sz = fw->size, d = fw->data; sz; sz -= rc1, d += rc1) { | ||
482 | rc1 = wil_fw_verify(wil, d, sz); | ||
483 | if (rc1 < 0) { | ||
484 | rc = rc1; | ||
485 | goto out; | ||
486 | } | ||
487 | rc = wil_fw_load(wil, d, rc1); | ||
488 | if (rc < 0) | ||
489 | goto out; | ||
490 | } | ||
491 | |||
492 | out: | ||
493 | release_firmware(fw); | ||
494 | return rc; | ||
495 | } | ||
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c index 98bfbb6390b7..7269bac111b9 100644 --- a/drivers/net/wireless/ath/wil6210/interrupt.c +++ b/drivers/net/wireless/ath/wil6210/interrupt.c | |||
@@ -135,7 +135,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil) | |||
135 | HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); | 135 | HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); |
136 | } | 136 | } |
137 | 137 | ||
138 | void wil6210_disable_irq(struct wil6210_priv *wil) | 138 | void wil_mask_irq(struct wil6210_priv *wil) |
139 | { | 139 | { |
140 | wil_dbg_irq(wil, "%s()\n", __func__); | 140 | wil_dbg_irq(wil, "%s()\n", __func__); |
141 | 141 | ||
@@ -145,7 +145,7 @@ void wil6210_disable_irq(struct wil6210_priv *wil) | |||
145 | wil6210_mask_irq_pseudo(wil); | 145 | wil6210_mask_irq_pseudo(wil); |
146 | } | 146 | } |
147 | 147 | ||
148 | void wil6210_enable_irq(struct wil6210_priv *wil) | 148 | void wil_unmask_irq(struct wil6210_priv *wil) |
149 | { | 149 | { |
150 | wil_dbg_irq(wil, "%s()\n", __func__); | 150 | wil_dbg_irq(wil, "%s()\n", __func__); |
151 | 151 | ||
@@ -196,8 +196,13 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie) | |||
196 | wil_dbg_irq(wil, "RX done\n"); | 196 | wil_dbg_irq(wil, "RX done\n"); |
197 | isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; | 197 | isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; |
198 | if (test_bit(wil_status_reset_done, &wil->status)) { | 198 | if (test_bit(wil_status_reset_done, &wil->status)) { |
199 | wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); | 199 | if (test_bit(wil_status_napi_en, &wil->status)) { |
200 | napi_schedule(&wil->napi_rx); | 200 | wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); |
201 | napi_schedule(&wil->napi_rx); | ||
202 | } else { | ||
203 | wil_err(wil, "Got Rx interrupt while " | ||
204 | "stopping interface\n"); | ||
205 | } | ||
201 | } else { | 206 | } else { |
202 | wil_err(wil, "Got Rx interrupt while in reset\n"); | 207 | wil_err(wil, "Got Rx interrupt while in reset\n"); |
203 | } | 208 | } |
@@ -506,7 +511,8 @@ free0: | |||
506 | 511 | ||
507 | return rc; | 512 | return rc; |
508 | } | 513 | } |
509 | /* can't use wil_ioread32_and_clear because ICC value is not ser yet */ | 514 | |
515 | /* can't use wil_ioread32_and_clear because ICC value is not set yet */ | ||
510 | static inline void wil_clear32(void __iomem *addr) | 516 | static inline void wil_clear32(void __iomem *addr) |
511 | { | 517 | { |
512 | u32 x = ioread32(addr); | 518 | u32 x = ioread32(addr); |
@@ -522,11 +528,15 @@ void wil6210_clear_irq(struct wil6210_priv *wil) | |||
522 | offsetof(struct RGF_ICR, ICR)); | 528 | offsetof(struct RGF_ICR, ICR)); |
523 | wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + | 529 | wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + |
524 | offsetof(struct RGF_ICR, ICR)); | 530 | offsetof(struct RGF_ICR, ICR)); |
531 | wmb(); /* make sure write completed */ | ||
525 | } | 532 | } |
526 | 533 | ||
527 | int wil6210_init_irq(struct wil6210_priv *wil, int irq) | 534 | int wil6210_init_irq(struct wil6210_priv *wil, int irq) |
528 | { | 535 | { |
529 | int rc; | 536 | int rc; |
537 | |||
538 | wil_dbg_misc(wil, "%s() n_msi=%d\n", __func__, wil->n_msi); | ||
539 | |||
530 | if (wil->n_msi == 3) | 540 | if (wil->n_msi == 3) |
531 | rc = wil6210_request_3msi(wil, irq); | 541 | rc = wil6210_request_3msi(wil, irq); |
532 | else | 542 | else |
@@ -534,17 +544,14 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq) | |||
534 | wil6210_thread_irq, | 544 | wil6210_thread_irq, |
535 | wil->n_msi ? 0 : IRQF_SHARED, | 545 | wil->n_msi ? 0 : IRQF_SHARED, |
536 | WIL_NAME, wil); | 546 | WIL_NAME, wil); |
537 | if (rc) | 547 | return rc; |
538 | return rc; | ||
539 | |||
540 | wil6210_enable_irq(wil); | ||
541 | |||
542 | return 0; | ||
543 | } | 548 | } |
544 | 549 | ||
545 | void wil6210_fini_irq(struct wil6210_priv *wil, int irq) | 550 | void wil6210_fini_irq(struct wil6210_priv *wil, int irq) |
546 | { | 551 | { |
547 | wil6210_disable_irq(wil); | 552 | wil_dbg_misc(wil, "%s()\n", __func__); |
553 | |||
554 | wil_mask_irq(wil); | ||
548 | free_irq(irq, wil); | 555 | free_irq(irq, wil); |
549 | if (wil->n_msi == 3) { | 556 | if (wil->n_msi == 3) { |
550 | free_irq(irq + 1, wil); | 557 | free_irq(irq + 1, wil); |
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c index b69d90f0716f..21667e0c3d14 100644 --- a/drivers/net/wireless/ath/wil6210/main.c +++ b/drivers/net/wireless/ath/wil6210/main.c | |||
@@ -20,11 +20,19 @@ | |||
20 | 20 | ||
21 | #include "wil6210.h" | 21 | #include "wil6210.h" |
22 | #include "txrx.h" | 22 | #include "txrx.h" |
23 | #include "wmi.h" | ||
24 | |||
25 | #define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000 | ||
26 | #define WAIT_FOR_DISCONNECT_INTERVAL_MS 10 | ||
23 | 27 | ||
24 | static bool no_fw_recovery; | 28 | static bool no_fw_recovery; |
25 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); | 29 | module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); |
26 | MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); | 30 | MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); |
27 | 31 | ||
32 | static bool no_fw_load = true; | ||
33 | module_param(no_fw_load, bool, S_IRUGO | S_IWUSR); | ||
34 | MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash."); | ||
35 | |||
28 | #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ | 36 | #define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ |
29 | #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ | 37 | #define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ |
30 | 38 | ||
@@ -67,6 +75,7 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) | |||
67 | struct net_device *ndev = wil_to_ndev(wil); | 75 | struct net_device *ndev = wil_to_ndev(wil); |
68 | struct wireless_dev *wdev = wil->wdev; | 76 | struct wireless_dev *wdev = wil->wdev; |
69 | struct wil_sta_info *sta = &wil->sta[cid]; | 77 | struct wil_sta_info *sta = &wil->sta[cid]; |
78 | |||
70 | wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, | 79 | wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, |
71 | sta->status); | 80 | sta->status); |
72 | 81 | ||
@@ -86,9 +95,16 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid) | |||
86 | } | 95 | } |
87 | 96 | ||
88 | for (i = 0; i < WIL_STA_TID_NUM; i++) { | 97 | for (i = 0; i < WIL_STA_TID_NUM; i++) { |
89 | struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; | 98 | struct wil_tid_ampdu_rx *r; |
99 | unsigned long flags; | ||
100 | |||
101 | spin_lock_irqsave(&sta->tid_rx_lock, flags); | ||
102 | |||
103 | r = sta->tid_rx[i]; | ||
90 | sta->tid_rx[i] = NULL; | 104 | sta->tid_rx[i] = NULL; |
91 | wil_tid_ampdu_rx_free(wil, r); | 105 | wil_tid_ampdu_rx_free(wil, r); |
106 | |||
107 | spin_unlock_irqrestore(&sta->tid_rx_lock, flags); | ||
92 | } | 108 | } |
93 | for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { | 109 | for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { |
94 | if (wil->vring2cid_tid[i][0] == cid) | 110 | if (wil->vring2cid_tid[i][0] == cid) |
@@ -205,10 +221,8 @@ static void wil_fw_error_worker(struct work_struct *work) | |||
205 | case NL80211_IFTYPE_MONITOR: | 221 | case NL80211_IFTYPE_MONITOR: |
206 | wil_info(wil, "fw error recovery started (try %d)...\n", | 222 | wil_info(wil, "fw error recovery started (try %d)...\n", |
207 | wil->recovery_count); | 223 | wil->recovery_count); |
208 | wil_reset(wil); | 224 | __wil_down(wil); |
209 | 225 | __wil_up(wil); | |
210 | /* need to re-allocate Rx ring after reset */ | ||
211 | wil_rx_init(wil); | ||
212 | break; | 226 | break; |
213 | case NL80211_IFTYPE_AP: | 227 | case NL80211_IFTYPE_AP: |
214 | case NL80211_IFTYPE_P2P_GO: | 228 | case NL80211_IFTYPE_P2P_GO: |
@@ -223,6 +237,7 @@ static void wil_fw_error_worker(struct work_struct *work) | |||
223 | static int wil_find_free_vring(struct wil6210_priv *wil) | 237 | static int wil_find_free_vring(struct wil6210_priv *wil) |
224 | { | 238 | { |
225 | int i; | 239 | int i; |
240 | |||
226 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { | 241 | for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { |
227 | if (!wil->vring_tx[i].va) | 242 | if (!wil->vring_tx[i].va) |
228 | return i; | 243 | return i; |
@@ -257,14 +272,19 @@ static void wil_connect_worker(struct work_struct *work) | |||
257 | 272 | ||
258 | int wil_priv_init(struct wil6210_priv *wil) | 273 | int wil_priv_init(struct wil6210_priv *wil) |
259 | { | 274 | { |
275 | uint i; | ||
276 | |||
260 | wil_dbg_misc(wil, "%s()\n", __func__); | 277 | wil_dbg_misc(wil, "%s()\n", __func__); |
261 | 278 | ||
262 | memset(wil->sta, 0, sizeof(wil->sta)); | 279 | memset(wil->sta, 0, sizeof(wil->sta)); |
280 | for (i = 0; i < WIL6210_MAX_CID; i++) | ||
281 | spin_lock_init(&wil->sta[i].tid_rx_lock); | ||
263 | 282 | ||
264 | mutex_init(&wil->mutex); | 283 | mutex_init(&wil->mutex); |
265 | mutex_init(&wil->wmi_mutex); | 284 | mutex_init(&wil->wmi_mutex); |
266 | 285 | ||
267 | init_completion(&wil->wmi_ready); | 286 | init_completion(&wil->wmi_ready); |
287 | init_completion(&wil->wmi_call); | ||
268 | 288 | ||
269 | wil->pending_connect_cid = -1; | 289 | wil->pending_connect_cid = -1; |
270 | setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); | 290 | setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); |
@@ -295,12 +315,16 @@ int wil_priv_init(struct wil6210_priv *wil) | |||
295 | 315 | ||
296 | void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) | 316 | void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) |
297 | { | 317 | { |
318 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
319 | |||
298 | del_timer_sync(&wil->connect_timer); | 320 | del_timer_sync(&wil->connect_timer); |
299 | _wil6210_disconnect(wil, bssid); | 321 | _wil6210_disconnect(wil, bssid); |
300 | } | 322 | } |
301 | 323 | ||
302 | void wil_priv_deinit(struct wil6210_priv *wil) | 324 | void wil_priv_deinit(struct wil6210_priv *wil) |
303 | { | 325 | { |
326 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
327 | |||
304 | del_timer_sync(&wil->scan_timer); | 328 | del_timer_sync(&wil->scan_timer); |
305 | cancel_work_sync(&wil->disconnect_worker); | 329 | cancel_work_sync(&wil->disconnect_worker); |
306 | cancel_work_sync(&wil->fw_error_worker); | 330 | cancel_work_sync(&wil->fw_error_worker); |
@@ -312,6 +336,28 @@ void wil_priv_deinit(struct wil6210_priv *wil) | |||
312 | destroy_workqueue(wil->wmi_wq); | 336 | destroy_workqueue(wil->wmi_wq); |
313 | } | 337 | } |
314 | 338 | ||
339 | /* target operations */ | ||
340 | /* register read */ | ||
341 | #define R(a) ioread32(wil->csr + HOSTADDR(a)) | ||
342 | /* register write. wmb() to make sure it is completed */ | ||
343 | #define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0) | ||
344 | /* register set = read, OR, write */ | ||
345 | #define S(a, v) W(a, R(a) | v) | ||
346 | /* register clear = read, AND with inverted, write */ | ||
347 | #define C(a, v) W(a, R(a) & ~v) | ||
348 | |||
349 | static inline void wil_halt_cpu(struct wil6210_priv *wil) | ||
350 | { | ||
351 | W(RGF_USER_USER_CPU_0, BIT_USER_USER_CPU_MAN_RST); | ||
352 | W(RGF_USER_MAC_CPU_0, BIT_USER_MAC_CPU_MAN_RST); | ||
353 | } | ||
354 | |||
355 | static inline void wil_release_cpu(struct wil6210_priv *wil) | ||
356 | { | ||
357 | /* Start CPU */ | ||
358 | W(RGF_USER_USER_CPU_0, 1); | ||
359 | } | ||
360 | |||
315 | static int wil_target_reset(struct wil6210_priv *wil) | 361 | static int wil_target_reset(struct wil6210_priv *wil) |
316 | { | 362 | { |
317 | int delay = 0; | 363 | int delay = 0; |
@@ -321,60 +367,41 @@ static int wil_target_reset(struct wil6210_priv *wil) | |||
321 | 367 | ||
322 | wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name); | 368 | wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name); |
323 | 369 | ||
324 | /* register read */ | ||
325 | #define R(a) ioread32(wil->csr + HOSTADDR(a)) | ||
326 | /* register write */ | ||
327 | #define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a)) | ||
328 | /* register set = read, OR, write */ | ||
329 | #define S(a, v) W(a, R(a) | v) | ||
330 | /* register clear = read, AND with inverted, write */ | ||
331 | #define C(a, v) W(a, R(a) & ~v) | ||
332 | |||
333 | wmb(); /* If host reorder writes here -> race in NIC */ | ||
334 | W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ | ||
335 | wil->hw_version = R(RGF_USER_FW_REV_ID); | 370 | wil->hw_version = R(RGF_USER_FW_REV_ID); |
336 | rev_id = wil->hw_version & 0xff; | 371 | rev_id = wil->hw_version & 0xff; |
337 | 372 | ||
338 | /* Clear MAC link up */ | 373 | /* Clear MAC link up */ |
339 | S(RGF_HP_CTRL, BIT(15)); | 374 | S(RGF_HP_CTRL, BIT(15)); |
340 | /* hpal_perst_from_pad_src_n_mask */ | 375 | S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_HPAL_PERST_FROM_PAD); |
341 | S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); | 376 | S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_CAR_PERST_RST); |
342 | /* car_perst_rst_src_n_mask */ | 377 | |
343 | S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); | 378 | wil_halt_cpu(wil); |
344 | wmb(); /* order is important here */ | 379 | C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); /* 40 MHz */ |
345 | 380 | ||
346 | if (is_sparrow) { | 381 | if (is_sparrow) { |
347 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); | 382 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); |
348 | wmb(); /* order is important here */ | 383 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf); |
349 | } | 384 | } |
350 | 385 | ||
351 | W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */ | ||
352 | wmb(); /* If host reorder writes here -> race in NIC */ | ||
353 | W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */ | ||
354 | wmb(); /* order is important here */ | ||
355 | |||
356 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); | 386 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); |
357 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); | 387 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); |
358 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000B0 : 0x00000170); | 388 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000f0 : 0x00000170); |
359 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); | 389 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00); |
360 | wmb(); /* order is important here */ | ||
361 | 390 | ||
362 | if (is_sparrow) { | 391 | if (is_sparrow) { |
363 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); | 392 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); |
364 | wmb(); /* order is important here */ | 393 | W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0); |
365 | } | 394 | } |
366 | 395 | ||
367 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); | 396 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); |
368 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); | 397 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); |
369 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); | 398 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); |
370 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); | 399 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); |
371 | wmb(); /* order is important here */ | ||
372 | 400 | ||
373 | if (is_sparrow) { | 401 | if (is_sparrow) { |
374 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); | 402 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); |
375 | /* reset A2 PCIE AHB */ | 403 | /* reset A2 PCIE AHB */ |
376 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); | 404 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); |
377 | |||
378 | } else { | 405 | } else { |
379 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); | 406 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); |
380 | if (rev_id == 1) { | 407 | if (rev_id == 1) { |
@@ -384,12 +411,10 @@ static int wil_target_reset(struct wil6210_priv *wil) | |||
384 | W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8)); | 411 | W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8)); |
385 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); | 412 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); |
386 | } | 413 | } |
387 | |||
388 | } | 414 | } |
389 | 415 | ||
390 | /* TODO: check order here!!! Erez code is different */ | 416 | /* TODO: check order here!!! Erez code is different */ |
391 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); | 417 | W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); |
392 | wmb(); /* order is important here */ | ||
393 | 418 | ||
394 | /* wait until device ready. typical time is 200..250 msec */ | 419 | /* wait until device ready. typical time is 200..250 msec */ |
395 | do { | 420 | do { |
@@ -407,16 +432,15 @@ static int wil_target_reset(struct wil6210_priv *wil) | |||
407 | W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); | 432 | W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); |
408 | 433 | ||
409 | C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); | 434 | C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); |
410 | wmb(); /* order is important here */ | ||
411 | 435 | ||
412 | wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); | 436 | wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); |
413 | return 0; | 437 | return 0; |
438 | } | ||
414 | 439 | ||
415 | #undef R | 440 | #undef R |
416 | #undef W | 441 | #undef W |
417 | #undef S | 442 | #undef S |
418 | #undef C | 443 | #undef C |
419 | } | ||
420 | 444 | ||
421 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) | 445 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) |
422 | { | 446 | { |
@@ -431,6 +455,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil) | |||
431 | { | 455 | { |
432 | ulong to = msecs_to_jiffies(1000); | 456 | ulong to = msecs_to_jiffies(1000); |
433 | ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); | 457 | ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); |
458 | |||
434 | if (0 == left) { | 459 | if (0 == left) { |
435 | wil_err(wil, "Firmware not ready\n"); | 460 | wil_err(wil, "Firmware not ready\n"); |
436 | return -ETIME; | 461 | return -ETIME; |
@@ -450,15 +475,15 @@ int wil_reset(struct wil6210_priv *wil) | |||
450 | { | 475 | { |
451 | int rc; | 476 | int rc; |
452 | 477 | ||
478 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
479 | |||
453 | WARN_ON(!mutex_is_locked(&wil->mutex)); | 480 | WARN_ON(!mutex_is_locked(&wil->mutex)); |
481 | WARN_ON(test_bit(wil_status_napi_en, &wil->status)); | ||
454 | 482 | ||
455 | cancel_work_sync(&wil->disconnect_worker); | 483 | cancel_work_sync(&wil->disconnect_worker); |
456 | wil6210_disconnect(wil, NULL); | 484 | wil6210_disconnect(wil, NULL); |
457 | 485 | ||
458 | wil->status = 0; /* prevent NAPI from being scheduled */ | 486 | wil->status = 0; /* prevent NAPI from being scheduled */ |
459 | if (test_bit(wil_status_napi_en, &wil->status)) { | ||
460 | napi_synchronize(&wil->napi_rx); | ||
461 | } | ||
462 | 487 | ||
463 | if (wil->scan_request) { | 488 | if (wil->scan_request) { |
464 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", | 489 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", |
@@ -468,7 +493,7 @@ int wil_reset(struct wil6210_priv *wil) | |||
468 | wil->scan_request = NULL; | 493 | wil->scan_request = NULL; |
469 | } | 494 | } |
470 | 495 | ||
471 | wil6210_disable_irq(wil); | 496 | wil_mask_irq(wil); |
472 | 497 | ||
473 | wmi_event_flush(wil); | 498 | wmi_event_flush(wil); |
474 | 499 | ||
@@ -480,13 +505,38 @@ int wil_reset(struct wil6210_priv *wil) | |||
480 | if (rc) | 505 | if (rc) |
481 | return rc; | 506 | return rc; |
482 | 507 | ||
508 | if (!no_fw_load) { | ||
509 | wil_info(wil, "Use firmware <%s>\n", WIL_FW_NAME); | ||
510 | wil_halt_cpu(wil); | ||
511 | /* Loading f/w from the file */ | ||
512 | rc = wil_request_firmware(wil, WIL_FW_NAME); | ||
513 | if (rc) | ||
514 | return rc; | ||
515 | |||
516 | /* clear any interrupts which on-card-firmware may have set */ | ||
517 | wil6210_clear_irq(wil); | ||
518 | { /* CAF_ICR - clear and mask */ | ||
519 | u32 a = HOSTADDR(RGF_CAF_ICR) + | ||
520 | offsetof(struct RGF_ICR, ICR); | ||
521 | u32 m = HOSTADDR(RGF_CAF_ICR) + | ||
522 | offsetof(struct RGF_ICR, IMV); | ||
523 | u32 icr = ioread32(wil->csr + a); | ||
524 | |||
525 | iowrite32(icr, wil->csr + a); /* W1C */ | ||
526 | iowrite32(~0, wil->csr + m); | ||
527 | wmb(); /* wait for completion */ | ||
528 | } | ||
529 | wil_release_cpu(wil); | ||
530 | } else { | ||
531 | wil_info(wil, "Use firmware from on-card flash\n"); | ||
532 | } | ||
483 | 533 | ||
484 | /* init after reset */ | 534 | /* init after reset */ |
485 | wil->pending_connect_cid = -1; | 535 | wil->pending_connect_cid = -1; |
486 | reinit_completion(&wil->wmi_ready); | 536 | reinit_completion(&wil->wmi_ready); |
537 | reinit_completion(&wil->wmi_call); | ||
487 | 538 | ||
488 | /* TODO: release MAC reset */ | 539 | wil_unmask_irq(wil); |
489 | wil6210_enable_irq(wil); | ||
490 | 540 | ||
491 | /* we just started MAC, wait for FW ready */ | 541 | /* we just started MAC, wait for FW ready */ |
492 | rc = wil_wait_for_fw_ready(wil); | 542 | rc = wil_wait_for_fw_ready(wil); |
@@ -522,7 +572,7 @@ void wil_link_off(struct wil6210_priv *wil) | |||
522 | netif_carrier_off(ndev); | 572 | netif_carrier_off(ndev); |
523 | } | 573 | } |
524 | 574 | ||
525 | static int __wil_up(struct wil6210_priv *wil) | 575 | int __wil_up(struct wil6210_priv *wil) |
526 | { | 576 | { |
527 | struct net_device *ndev = wil_to_ndev(wil); | 577 | struct net_device *ndev = wil_to_ndev(wil); |
528 | struct wireless_dev *wdev = wil->wdev; | 578 | struct wireless_dev *wdev = wil->wdev; |
@@ -568,11 +618,15 @@ static int __wil_up(struct wil6210_priv *wil) | |||
568 | /* MAC address - pre-requisite for other commands */ | 618 | /* MAC address - pre-requisite for other commands */ |
569 | wmi_set_mac_address(wil, ndev->dev_addr); | 619 | wmi_set_mac_address(wil, ndev->dev_addr); |
570 | 620 | ||
571 | 621 | wil_dbg_misc(wil, "NAPI enable\n"); | |
572 | napi_enable(&wil->napi_rx); | 622 | napi_enable(&wil->napi_rx); |
573 | napi_enable(&wil->napi_tx); | 623 | napi_enable(&wil->napi_tx); |
574 | set_bit(wil_status_napi_en, &wil->status); | 624 | set_bit(wil_status_napi_en, &wil->status); |
575 | 625 | ||
626 | if (wil->platform_ops.bus_request) | ||
627 | wil->platform_ops.bus_request(wil->platform_handle, | ||
628 | WIL_MAX_BUS_REQUEST_KBPS); | ||
629 | |||
576 | return 0; | 630 | return 0; |
577 | } | 631 | } |
578 | 632 | ||
@@ -580,6 +634,8 @@ int wil_up(struct wil6210_priv *wil) | |||
580 | { | 634 | { |
581 | int rc; | 635 | int rc; |
582 | 636 | ||
637 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
638 | |||
583 | mutex_lock(&wil->mutex); | 639 | mutex_lock(&wil->mutex); |
584 | rc = __wil_up(wil); | 640 | rc = __wil_up(wil); |
585 | mutex_unlock(&wil->mutex); | 641 | mutex_unlock(&wil->mutex); |
@@ -587,13 +643,23 @@ int wil_up(struct wil6210_priv *wil) | |||
587 | return rc; | 643 | return rc; |
588 | } | 644 | } |
589 | 645 | ||
590 | static int __wil_down(struct wil6210_priv *wil) | 646 | int __wil_down(struct wil6210_priv *wil) |
591 | { | 647 | { |
648 | int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS / | ||
649 | WAIT_FOR_DISCONNECT_INTERVAL_MS; | ||
650 | |||
592 | WARN_ON(!mutex_is_locked(&wil->mutex)); | 651 | WARN_ON(!mutex_is_locked(&wil->mutex)); |
593 | 652 | ||
594 | clear_bit(wil_status_napi_en, &wil->status); | 653 | if (wil->platform_ops.bus_request) |
595 | napi_disable(&wil->napi_rx); | 654 | wil->platform_ops.bus_request(wil->platform_handle, 0); |
596 | napi_disable(&wil->napi_tx); | 655 | |
656 | wil_disable_irq(wil); | ||
657 | if (test_and_clear_bit(wil_status_napi_en, &wil->status)) { | ||
658 | napi_disable(&wil->napi_rx); | ||
659 | napi_disable(&wil->napi_tx); | ||
660 | wil_dbg_misc(wil, "NAPI disable\n"); | ||
661 | } | ||
662 | wil_enable_irq(wil); | ||
597 | 663 | ||
598 | if (wil->scan_request) { | 664 | if (wil->scan_request) { |
599 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", | 665 | wil_dbg_misc(wil, "Abort scan_request 0x%p\n", |
@@ -603,7 +669,24 @@ static int __wil_down(struct wil6210_priv *wil) | |||
603 | wil->scan_request = NULL; | 669 | wil->scan_request = NULL; |
604 | } | 670 | } |
605 | 671 | ||
606 | wil6210_disconnect(wil, NULL); | 672 | if (test_bit(wil_status_fwconnected, &wil->status) || |
673 | test_bit(wil_status_fwconnecting, &wil->status)) | ||
674 | wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0); | ||
675 | |||
676 | /* make sure wil is idle (not connected) */ | ||
677 | mutex_unlock(&wil->mutex); | ||
678 | while (iter--) { | ||
679 | int idle = !test_bit(wil_status_fwconnected, &wil->status) && | ||
680 | !test_bit(wil_status_fwconnecting, &wil->status); | ||
681 | if (idle) | ||
682 | break; | ||
683 | msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS); | ||
684 | } | ||
685 | mutex_lock(&wil->mutex); | ||
686 | |||
687 | if (!iter) | ||
688 | wil_err(wil, "timeout waiting for idle FW/HW\n"); | ||
689 | |||
607 | wil_rx_fini(wil); | 690 | wil_rx_fini(wil); |
608 | 691 | ||
609 | return 0; | 692 | return 0; |
@@ -613,6 +696,8 @@ int wil_down(struct wil6210_priv *wil) | |||
613 | { | 696 | { |
614 | int rc; | 697 | int rc; |
615 | 698 | ||
699 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
700 | |||
616 | mutex_lock(&wil->mutex); | 701 | mutex_lock(&wil->mutex); |
617 | rc = __wil_down(wil); | 702 | rc = __wil_down(wil); |
618 | mutex_unlock(&wil->mutex); | 703 | mutex_unlock(&wil->mutex); |
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c index a44c2b61be08..1c0c77d9a14f 100644 --- a/drivers/net/wireless/ath/wil6210/netdev.c +++ b/drivers/net/wireless/ath/wil6210/netdev.c | |||
@@ -17,11 +17,14 @@ | |||
17 | #include <linux/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
18 | 18 | ||
19 | #include "wil6210.h" | 19 | #include "wil6210.h" |
20 | #include "txrx.h" | ||
20 | 21 | ||
21 | static int wil_open(struct net_device *ndev) | 22 | static int wil_open(struct net_device *ndev) |
22 | { | 23 | { |
23 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 24 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
24 | 25 | ||
26 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
27 | |||
25 | return wil_up(wil); | 28 | return wil_up(wil); |
26 | } | 29 | } |
27 | 30 | ||
@@ -29,6 +32,8 @@ static int wil_stop(struct net_device *ndev) | |||
29 | { | 32 | { |
30 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 33 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
31 | 34 | ||
35 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
36 | |||
32 | return wil_down(wil); | 37 | return wil_down(wil); |
33 | } | 38 | } |
34 | 39 | ||
@@ -36,8 +41,10 @@ static int wil_change_mtu(struct net_device *ndev, int new_mtu) | |||
36 | { | 41 | { |
37 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 42 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
38 | 43 | ||
39 | if (new_mtu < 68 || new_mtu > IEEE80211_MAX_DATA_LEN_DMG) | 44 | if (new_mtu < 68 || new_mtu > (TX_BUF_LEN - ETH_HLEN)) { |
45 | wil_err(wil, "invalid MTU %d\n", new_mtu); | ||
40 | return -EINVAL; | 46 | return -EINVAL; |
47 | } | ||
41 | 48 | ||
42 | wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu); | 49 | wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu); |
43 | ndev->mtu = new_mtu; | 50 | ndev->mtu = new_mtu; |
@@ -121,6 +128,8 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr) | |||
121 | wil->csr = csr; | 128 | wil->csr = csr; |
122 | wil->wdev = wdev; | 129 | wil->wdev = wdev; |
123 | 130 | ||
131 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
132 | |||
124 | rc = wil_priv_init(wil); | 133 | rc = wil_priv_init(wil); |
125 | if (rc) { | 134 | if (rc) { |
126 | dev_err(dev, "wil_priv_init failed\n"); | 135 | dev_err(dev, "wil_priv_init failed\n"); |
@@ -169,6 +178,8 @@ void wil_if_free(struct wil6210_priv *wil) | |||
169 | { | 178 | { |
170 | struct net_device *ndev = wil_to_ndev(wil); | 179 | struct net_device *ndev = wil_to_ndev(wil); |
171 | 180 | ||
181 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
182 | |||
172 | if (!ndev) | 183 | if (!ndev) |
173 | return; | 184 | return; |
174 | 185 | ||
@@ -185,6 +196,8 @@ int wil_if_add(struct wil6210_priv *wil) | |||
185 | struct net_device *ndev = wil_to_ndev(wil); | 196 | struct net_device *ndev = wil_to_ndev(wil); |
186 | int rc; | 197 | int rc; |
187 | 198 | ||
199 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
200 | |||
188 | rc = register_netdev(ndev); | 201 | rc = register_netdev(ndev); |
189 | if (rc < 0) { | 202 | if (rc < 0) { |
190 | dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); | 203 | dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); |
@@ -200,5 +213,7 @@ void wil_if_remove(struct wil6210_priv *wil) | |||
200 | { | 213 | { |
201 | struct net_device *ndev = wil_to_ndev(wil); | 214 | struct net_device *ndev = wil_to_ndev(wil); |
202 | 215 | ||
216 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
217 | |||
203 | unregister_netdev(ndev); | 218 | unregister_netdev(ndev); |
204 | } | 219 | } |
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c index 38dcbea49d44..66626a8ee728 100644 --- a/drivers/net/wireless/ath/wil6210/pcie_bus.c +++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/moduleparam.h> | 19 | #include <linux/moduleparam.h> |
20 | #include <linux/interrupt.h> | ||
20 | 21 | ||
21 | #include "wil6210.h" | 22 | #include "wil6210.h" |
22 | 23 | ||
@@ -30,6 +31,28 @@ static bool debug_fw; /* = false; */ | |||
30 | module_param(debug_fw, bool, S_IRUGO); | 31 | module_param(debug_fw, bool, S_IRUGO); |
31 | MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug"); | 32 | MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug"); |
32 | 33 | ||
34 | void wil_disable_irq(struct wil6210_priv *wil) | ||
35 | { | ||
36 | int irq = wil->pdev->irq; | ||
37 | |||
38 | disable_irq(irq); | ||
39 | if (wil->n_msi == 3) { | ||
40 | disable_irq(irq + 1); | ||
41 | disable_irq(irq + 2); | ||
42 | } | ||
43 | } | ||
44 | |||
45 | void wil_enable_irq(struct wil6210_priv *wil) | ||
46 | { | ||
47 | int irq = wil->pdev->irq; | ||
48 | |||
49 | enable_irq(irq); | ||
50 | if (wil->n_msi == 3) { | ||
51 | enable_irq(irq + 1); | ||
52 | enable_irq(irq + 2); | ||
53 | } | ||
54 | } | ||
55 | |||
33 | /* Bus ops */ | 56 | /* Bus ops */ |
34 | static int wil_if_pcie_enable(struct wil6210_priv *wil) | 57 | static int wil_if_pcie_enable(struct wil6210_priv *wil) |
35 | { | 58 | { |
@@ -41,6 +64,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil) | |||
41 | */ | 64 | */ |
42 | int msi_only = pdev->msi_enabled; | 65 | int msi_only = pdev->msi_enabled; |
43 | 66 | ||
67 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
68 | |||
44 | pdev->msi_enabled = 0; | 69 | pdev->msi_enabled = 0; |
45 | 70 | ||
46 | pci_set_master(pdev); | 71 | pci_set_master(pdev); |
@@ -107,6 +132,8 @@ static int wil_if_pcie_disable(struct wil6210_priv *wil) | |||
107 | { | 132 | { |
108 | struct pci_dev *pdev = wil->pdev; | 133 | struct pci_dev *pdev = wil->pdev; |
109 | 134 | ||
135 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
136 | |||
110 | pci_clear_master(pdev); | 137 | pci_clear_master(pdev); |
111 | /* disable and release IRQ */ | 138 | /* disable and release IRQ */ |
112 | wil6210_fini_irq(wil, pdev->irq); | 139 | wil6210_fini_irq(wil, pdev->irq); |
@@ -180,6 +207,10 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
180 | wil->board = board; | 207 | wil->board = board; |
181 | 208 | ||
182 | wil6210_clear_irq(wil); | 209 | wil6210_clear_irq(wil); |
210 | |||
211 | wil->platform_handle = | ||
212 | wil_platform_init(&pdev->dev, &wil->platform_ops); | ||
213 | |||
183 | /* FW should raise IRQ when ready */ | 214 | /* FW should raise IRQ when ready */ |
184 | rc = wil_if_pcie_enable(wil); | 215 | rc = wil_if_pcie_enable(wil); |
185 | if (rc) { | 216 | if (rc) { |
@@ -204,6 +235,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
204 | bus_disable: | 235 | bus_disable: |
205 | wil_if_pcie_disable(wil); | 236 | wil_if_pcie_disable(wil); |
206 | if_free: | 237 | if_free: |
238 | if (wil->platform_ops.uninit) | ||
239 | wil->platform_ops.uninit(wil->platform_handle); | ||
207 | wil_if_free(wil); | 240 | wil_if_free(wil); |
208 | err_iounmap: | 241 | err_iounmap: |
209 | pci_iounmap(pdev, csr); | 242 | pci_iounmap(pdev, csr); |
@@ -220,9 +253,13 @@ static void wil_pcie_remove(struct pci_dev *pdev) | |||
220 | struct wil6210_priv *wil = pci_get_drvdata(pdev); | 253 | struct wil6210_priv *wil = pci_get_drvdata(pdev); |
221 | void __iomem *csr = wil->csr; | 254 | void __iomem *csr = wil->csr; |
222 | 255 | ||
256 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
257 | |||
223 | wil6210_debugfs_remove(wil); | 258 | wil6210_debugfs_remove(wil); |
224 | wil_if_pcie_disable(wil); | ||
225 | wil_if_remove(wil); | 259 | wil_if_remove(wil); |
260 | wil_if_pcie_disable(wil); | ||
261 | if (wil->platform_ops.uninit) | ||
262 | wil->platform_ops.uninit(wil->platform_handle); | ||
226 | wil_if_free(wil); | 263 | wil_if_free(wil); |
227 | pci_iounmap(pdev, csr); | 264 | pci_iounmap(pdev, csr); |
228 | pci_release_region(pdev, 0); | 265 | pci_release_region(pdev, 0); |
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c index 97c6a24716a1..489cb73d139b 100644 --- a/drivers/net/wireless/ath/wil6210/rx_reorder.c +++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c | |||
@@ -98,22 +98,25 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) | |||
98 | int mid = wil_rxdesc_mid(d); | 98 | int mid = wil_rxdesc_mid(d); |
99 | u16 seq = wil_rxdesc_seq(d); | 99 | u16 seq = wil_rxdesc_seq(d); |
100 | struct wil_sta_info *sta = &wil->sta[cid]; | 100 | struct wil_sta_info *sta = &wil->sta[cid]; |
101 | struct wil_tid_ampdu_rx *r = sta->tid_rx[tid]; | 101 | struct wil_tid_ampdu_rx *r; |
102 | u16 hseq; | 102 | u16 hseq; |
103 | int index; | 103 | int index; |
104 | unsigned long flags; | ||
104 | 105 | ||
105 | wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n", | 106 | wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n", |
106 | mid, cid, tid, seq); | 107 | mid, cid, tid, seq); |
107 | 108 | ||
109 | spin_lock_irqsave(&sta->tid_rx_lock, flags); | ||
110 | |||
111 | r = sta->tid_rx[tid]; | ||
108 | if (!r) { | 112 | if (!r) { |
113 | spin_unlock_irqrestore(&sta->tid_rx_lock, flags); | ||
109 | wil_netif_rx_any(skb, ndev); | 114 | wil_netif_rx_any(skb, ndev); |
110 | return; | 115 | return; |
111 | } | 116 | } |
112 | 117 | ||
113 | hseq = r->head_seq_num; | 118 | hseq = r->head_seq_num; |
114 | 119 | ||
115 | spin_lock(&r->reorder_lock); | ||
116 | |||
117 | /** Due to the race between WMI events, where BACK establishment | 120 | /** Due to the race between WMI events, where BACK establishment |
118 | * reported, and data Rx, few packets may be pass up before reorder | 121 | * reported, and data Rx, few packets may be pass up before reorder |
119 | * buffer get allocated. Catch up by pretending SSN is what we | 122 | * buffer get allocated. Catch up by pretending SSN is what we |
@@ -176,13 +179,14 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb) | |||
176 | wil_reorder_release(wil, r); | 179 | wil_reorder_release(wil, r); |
177 | 180 | ||
178 | out: | 181 | out: |
179 | spin_unlock(&r->reorder_lock); | 182 | spin_unlock_irqrestore(&sta->tid_rx_lock, flags); |
180 | } | 183 | } |
181 | 184 | ||
182 | struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, | 185 | struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, |
183 | int size, u16 ssn) | 186 | int size, u16 ssn) |
184 | { | 187 | { |
185 | struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL); | 188 | struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL); |
189 | |||
186 | if (!r) | 190 | if (!r) |
187 | return NULL; | 191 | return NULL; |
188 | 192 | ||
@@ -197,7 +201,6 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, | |||
197 | return NULL; | 201 | return NULL; |
198 | } | 202 | } |
199 | 203 | ||
200 | spin_lock_init(&r->reorder_lock); | ||
201 | r->ssn = ssn; | 204 | r->ssn = ssn; |
202 | r->head_seq_num = ssn; | 205 | r->head_seq_num = ssn; |
203 | r->buf_size = size; | 206 | r->buf_size = size; |
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c index 9bd920d272bb..2936ef0c18cb 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.c +++ b/drivers/net/wireless/ath/wil6210/txrx.c | |||
@@ -52,6 +52,7 @@ static inline int wil_vring_is_full(struct vring *vring) | |||
52 | { | 52 | { |
53 | return wil_vring_next_tail(vring) == vring->swhead; | 53 | return wil_vring_next_tail(vring) == vring->swhead; |
54 | } | 54 | } |
55 | |||
55 | /* | 56 | /* |
56 | * Available space in Tx Vring | 57 | * Available space in Tx Vring |
57 | */ | 58 | */ |
@@ -86,6 +87,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | |||
86 | size_t sz = vring->size * sizeof(vring->va[0]); | 87 | size_t sz = vring->size * sizeof(vring->va[0]); |
87 | uint i; | 88 | uint i; |
88 | 89 | ||
90 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
91 | |||
89 | BUILD_BUG_ON(sizeof(vring->va[0]) != 32); | 92 | BUILD_BUG_ON(sizeof(vring->va[0]) != 32); |
90 | 93 | ||
91 | vring->swhead = 0; | 94 | vring->swhead = 0; |
@@ -110,7 +113,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring) | |||
110 | * we can use any | 113 | * we can use any |
111 | */ | 114 | */ |
112 | for (i = 0; i < vring->size; i++) { | 115 | for (i = 0; i < vring->size; i++) { |
113 | volatile struct vring_tx_desc *_d = &(vring->va[i].tx); | 116 | volatile struct vring_tx_desc *_d = &vring->va[i].tx; |
117 | |||
114 | _d->dma.status = TX_DMA_STATUS_DU; | 118 | _d->dma.status = TX_DMA_STATUS_DU; |
115 | } | 119 | } |
116 | 120 | ||
@@ -125,6 +129,7 @@ static void wil_txdesc_unmap(struct device *dev, struct vring_tx_desc *d, | |||
125 | { | 129 | { |
126 | dma_addr_t pa = wil_desc_addr(&d->dma.addr); | 130 | dma_addr_t pa = wil_desc_addr(&d->dma.addr); |
127 | u16 dmalen = le16_to_cpu(d->dma.length); | 131 | u16 dmalen = le16_to_cpu(d->dma.length); |
132 | |||
128 | switch (ctx->mapped_as) { | 133 | switch (ctx->mapped_as) { |
129 | case wil_mapped_as_single: | 134 | case wil_mapped_as_single: |
130 | dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); | 135 | dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); |
@@ -143,6 +148,18 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring, | |||
143 | struct device *dev = wil_to_dev(wil); | 148 | struct device *dev = wil_to_dev(wil); |
144 | size_t sz = vring->size * sizeof(vring->va[0]); | 149 | size_t sz = vring->size * sizeof(vring->va[0]); |
145 | 150 | ||
151 | if (tx) { | ||
152 | int vring_index = vring - wil->vring_tx; | ||
153 | |||
154 | wil_dbg_misc(wil, "free Tx vring %d [%d] 0x%p:%pad 0x%p\n", | ||
155 | vring_index, vring->size, vring->va, | ||
156 | &vring->pa, vring->ctx); | ||
157 | } else { | ||
158 | wil_dbg_misc(wil, "free Rx vring [%d] 0x%p:%pad 0x%p\n", | ||
159 | vring->size, vring->va, | ||
160 | &vring->pa, vring->ctx); | ||
161 | } | ||
162 | |||
146 | while (!wil_vring_is_empty(vring)) { | 163 | while (!wil_vring_is_empty(vring)) { |
147 | dma_addr_t pa; | 164 | dma_addr_t pa; |
148 | u16 dmalen; | 165 | u16 dmalen; |
@@ -191,11 +208,12 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring, | |||
191 | struct device *dev = wil_to_dev(wil); | 208 | struct device *dev = wil_to_dev(wil); |
192 | unsigned int sz = RX_BUF_LEN; | 209 | unsigned int sz = RX_BUF_LEN; |
193 | struct vring_rx_desc dd, *d = ⅆ | 210 | struct vring_rx_desc dd, *d = ⅆ |
194 | volatile struct vring_rx_desc *_d = &(vring->va[i].rx); | 211 | volatile struct vring_rx_desc *_d = &vring->va[i].rx; |
195 | dma_addr_t pa; | 212 | dma_addr_t pa; |
196 | 213 | ||
197 | /* TODO align */ | 214 | /* TODO align */ |
198 | struct sk_buff *skb = dev_alloc_skb(sz + headroom); | 215 | struct sk_buff *skb = dev_alloc_skb(sz + headroom); |
216 | |||
199 | if (unlikely(!skb)) | 217 | if (unlikely(!skb)) |
200 | return -ENOMEM; | 218 | return -ENOMEM; |
201 | 219 | ||
@@ -274,9 +292,11 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, | |||
274 | */ | 292 | */ |
275 | int len = min_t(int, 8 + sizeof(phy_data), | 293 | int len = min_t(int, 8 + sizeof(phy_data), |
276 | wil_rxdesc_phy_length(d)); | 294 | wil_rxdesc_phy_length(d)); |
295 | |||
277 | if (len > 8) { | 296 | if (len > 8) { |
278 | void *p = skb_tail_pointer(skb); | 297 | void *p = skb_tail_pointer(skb); |
279 | void *pa = PTR_ALIGN(p, 8); | 298 | void *pa = PTR_ALIGN(p, 8); |
299 | |||
280 | if (skb_tailroom(skb) >= len + (pa - p)) { | 300 | if (skb_tailroom(skb) >= len + (pa - p)) { |
281 | phy_length = len - 8; | 301 | phy_length = len - 8; |
282 | memcpy(phy_data, pa, phy_length); | 302 | memcpy(phy_data, pa, phy_length); |
@@ -372,13 +392,12 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil, | |||
372 | int cid; | 392 | int cid; |
373 | struct wil_net_stats *stats; | 393 | struct wil_net_stats *stats; |
374 | 394 | ||
375 | |||
376 | BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); | 395 | BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); |
377 | 396 | ||
378 | if (wil_vring_is_empty(vring)) | 397 | if (wil_vring_is_empty(vring)) |
379 | return NULL; | 398 | return NULL; |
380 | 399 | ||
381 | _d = &(vring->va[vring->swhead].rx); | 400 | _d = &vring->va[vring->swhead].rx; |
382 | if (!(_d->dma.status & RX_DMA_STATUS_DU)) { | 401 | if (!(_d->dma.status & RX_DMA_STATUS_DU)) { |
383 | /* it is not error, we just reached end of Rx done area */ | 402 | /* it is not error, we just reached end of Rx done area */ |
384 | return NULL; | 403 | return NULL; |
@@ -532,7 +551,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | |||
532 | [GRO_NORMAL] = "GRO_NORMAL", | 551 | [GRO_NORMAL] = "GRO_NORMAL", |
533 | [GRO_DROP] = "GRO_DROP", | 552 | [GRO_DROP] = "GRO_DROP", |
534 | }; | 553 | }; |
535 | wil_dbg_txrx(wil, "Rx complete %d bytes => %s,\n", | 554 | wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n", |
536 | len, gro_res_str[rc]); | 555 | len, gro_res_str[rc]); |
537 | } | 556 | } |
538 | } | 557 | } |
@@ -573,7 +592,6 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota) | |||
573 | else | 592 | else |
574 | wil_netif_rx_any(skb, ndev); | 593 | wil_netif_rx_any(skb, ndev); |
575 | } | 594 | } |
576 | |||
577 | } | 595 | } |
578 | wil_rx_refill(wil, v->size); | 596 | wil_rx_refill(wil, v->size); |
579 | } | 597 | } |
@@ -583,6 +601,8 @@ int wil_rx_init(struct wil6210_priv *wil) | |||
583 | struct vring *vring = &wil->vring_rx; | 601 | struct vring *vring = &wil->vring_rx; |
584 | int rc; | 602 | int rc; |
585 | 603 | ||
604 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
605 | |||
586 | if (vring->va) { | 606 | if (vring->va) { |
587 | wil_err(wil, "Rx ring already allocated\n"); | 607 | wil_err(wil, "Rx ring already allocated\n"); |
588 | return -EINVAL; | 608 | return -EINVAL; |
@@ -612,6 +632,8 @@ void wil_rx_fini(struct wil6210_priv *wil) | |||
612 | { | 632 | { |
613 | struct vring *vring = &wil->vring_rx; | 633 | struct vring *vring = &wil->vring_rx; |
614 | 634 | ||
635 | wil_dbg_misc(wil, "%s()\n", __func__); | ||
636 | |||
615 | if (vring->va) | 637 | if (vring->va) |
616 | wil_vring_free(wil, vring, 0); | 638 | wil_vring_free(wil, vring, 0); |
617 | } | 639 | } |
@@ -646,6 +668,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | |||
646 | struct vring *vring = &wil->vring_tx[id]; | 668 | struct vring *vring = &wil->vring_tx[id]; |
647 | struct vring_tx_data *txdata = &wil->vring_tx_data[id]; | 669 | struct vring_tx_data *txdata = &wil->vring_tx_data[id]; |
648 | 670 | ||
671 | wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__, | ||
672 | cmd.vring_cfg.tx_sw_ring.max_mpdu_size); | ||
673 | |||
649 | if (vring->va) { | 674 | if (vring->va) { |
650 | wil_err(wil, "Tx ring [%d] already allocated\n", id); | 675 | wil_err(wil, "Tx ring [%d] already allocated\n", id); |
651 | rc = -EINVAL; | 676 | rc = -EINVAL; |
@@ -695,6 +720,8 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id) | |||
695 | if (!vring->va) | 720 | if (!vring->va) |
696 | return; | 721 | return; |
697 | 722 | ||
723 | wil_dbg_misc(wil, "%s() id=%d\n", __func__, id); | ||
724 | |||
698 | /* make sure NAPI won't touch this vring */ | 725 | /* make sure NAPI won't touch this vring */ |
699 | wil->vring_tx_data[id].enabled = 0; | 726 | wil->vring_tx_data[id].enabled = 0; |
700 | if (test_bit(wil_status_napi_en, &wil->status)) | 727 | if (test_bit(wil_status_napi_en, &wil->status)) |
@@ -721,6 +748,7 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, | |||
721 | for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) { | 748 | for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) { |
722 | if (wil->vring2cid_tid[i][0] == cid) { | 749 | if (wil->vring2cid_tid[i][0] == cid) { |
723 | struct vring *v = &wil->vring_tx[i]; | 750 | struct vring *v = &wil->vring_tx[i]; |
751 | |||
724 | wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n", | 752 | wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n", |
725 | __func__, eth->h_dest, i); | 753 | __func__, eth->h_dest, i); |
726 | if (v->va) { | 754 | if (v->va) { |
@@ -740,6 +768,7 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil, | |||
740 | { | 768 | { |
741 | struct ethhdr *eth = (void *)skb->data; | 769 | struct ethhdr *eth = (void *)skb->data; |
742 | int cid = wil->vring2cid_tid[vring_index][0]; | 770 | int cid = wil->vring2cid_tid[vring_index][0]; |
771 | |||
743 | memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN); | 772 | memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN); |
744 | } | 773 | } |
745 | 774 | ||
@@ -750,7 +779,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
750 | * duplicate skb and send it to other active vrings | 779 | * duplicate skb and send it to other active vrings |
751 | */ | 780 | */ |
752 | static struct vring *wil_tx_bcast(struct wil6210_priv *wil, | 781 | static struct vring *wil_tx_bcast(struct wil6210_priv *wil, |
753 | struct sk_buff *skb) | 782 | struct sk_buff *skb) |
754 | { | 783 | { |
755 | struct vring *v, *v2; | 784 | struct vring *v, *v2; |
756 | struct sk_buff *skb2; | 785 | struct sk_buff *skb2; |
@@ -833,8 +862,8 @@ void wil_tx_desc_set_nr_frags(struct vring_tx_desc *d, int nr_frags) | |||
833 | } | 862 | } |
834 | 863 | ||
835 | static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, | 864 | static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, |
836 | struct vring_tx_desc *d, | 865 | struct vring_tx_desc *d, |
837 | struct sk_buff *skb) | 866 | struct sk_buff *skb) |
838 | { | 867 | { |
839 | int protocol; | 868 | int protocol; |
840 | 869 | ||
@@ -902,10 +931,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
902 | 1 + nr_frags); | 931 | 1 + nr_frags); |
903 | return -ENOMEM; | 932 | return -ENOMEM; |
904 | } | 933 | } |
905 | _d = &(vring->va[i].tx); | 934 | _d = &vring->va[i].tx; |
906 | 935 | ||
907 | pa = dma_map_single(dev, skb->data, | 936 | pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); |
908 | skb_headlen(skb), DMA_TO_DEVICE); | ||
909 | 937 | ||
910 | wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb), | 938 | wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb), |
911 | skb->data, &pa); | 939 | skb->data, &pa); |
@@ -934,10 +962,11 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
934 | const struct skb_frag_struct *frag = | 962 | const struct skb_frag_struct *frag = |
935 | &skb_shinfo(skb)->frags[f]; | 963 | &skb_shinfo(skb)->frags[f]; |
936 | int len = skb_frag_size(frag); | 964 | int len = skb_frag_size(frag); |
965 | |||
937 | i = (swhead + f + 1) % vring->size; | 966 | i = (swhead + f + 1) % vring->size; |
938 | _d = &(vring->va[i].tx); | 967 | _d = &vring->va[i].tx; |
939 | pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), | 968 | pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), |
940 | DMA_TO_DEVICE); | 969 | DMA_TO_DEVICE); |
941 | if (unlikely(dma_mapping_error(dev, pa))) | 970 | if (unlikely(dma_mapping_error(dev, pa))) |
942 | goto dma_error; | 971 | goto dma_error; |
943 | vring->ctx[i].mapped_as = wil_mapped_as_page; | 972 | vring->ctx[i].mapped_as = wil_mapped_as_page; |
@@ -982,7 +1011,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
982 | 1011 | ||
983 | i = (swhead + f) % vring->size; | 1012 | i = (swhead + f) % vring->size; |
984 | ctx = &vring->ctx[i]; | 1013 | ctx = &vring->ctx[i]; |
985 | _d = &(vring->va[i].tx); | 1014 | _d = &vring->va[i].tx; |
986 | *d = *_d; | 1015 | *d = *_d; |
987 | _d->dma.status = TX_DMA_STATUS_DU; | 1016 | _d->dma.status = TX_DMA_STATUS_DU; |
988 | wil_txdesc_unmap(dev, d, ctx); | 1017 | wil_txdesc_unmap(dev, d, ctx); |
@@ -996,7 +1025,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | |||
996 | return -EINVAL; | 1025 | return -EINVAL; |
997 | } | 1026 | } |
998 | 1027 | ||
999 | |||
1000 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 1028 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
1001 | { | 1029 | { |
1002 | struct wil6210_priv *wil = ndev_to_wil(ndev); | 1030 | struct wil6210_priv *wil = ndev_to_wil(ndev); |
@@ -1024,15 +1052,15 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
1024 | pr_once_fw = false; | 1052 | pr_once_fw = false; |
1025 | 1053 | ||
1026 | /* find vring */ | 1054 | /* find vring */ |
1027 | if (is_unicast_ether_addr(eth->h_dest)) { | 1055 | if (is_unicast_ether_addr(eth->h_dest)) |
1028 | vring = wil_find_tx_vring(wil, skb); | 1056 | vring = wil_find_tx_vring(wil, skb); |
1029 | } else { | 1057 | else |
1030 | vring = wil_tx_bcast(wil, skb); | 1058 | vring = wil_tx_bcast(wil, skb); |
1031 | } | ||
1032 | if (!vring) { | 1059 | if (!vring) { |
1033 | wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); | 1060 | wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); |
1034 | goto drop; | 1061 | goto drop; |
1035 | } | 1062 | } |
1063 | |||
1036 | /* set up vring entry */ | 1064 | /* set up vring entry */ |
1037 | rc = wil_tx_vring(wil, vring, skb); | 1065 | rc = wil_tx_vring(wil, vring, skb); |
1038 | 1066 | ||
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h index a1ac4f87d47b..de046716d2b7 100644 --- a/drivers/net/wireless/ath/wil6210/txrx.h +++ b/drivers/net/wireless/ath/wil6210/txrx.h | |||
@@ -20,9 +20,9 @@ | |||
20 | #define BUF_SW_OWNED (1) | 20 | #define BUF_SW_OWNED (1) |
21 | #define BUF_HW_OWNED (0) | 21 | #define BUF_HW_OWNED (0) |
22 | 22 | ||
23 | /* size of max. Rx packet */ | 23 | /* size of max. Tx/Rx buffers, as supported by FW */ |
24 | #define RX_BUF_LEN (2048) | 24 | #define RX_BUF_LEN (2242) |
25 | #define TX_BUF_LEN (2048) | 25 | #define TX_BUF_LEN (2242) |
26 | /* how many bytes to reserve for rtap header? */ | 26 | /* how many bytes to reserve for rtap header? */ |
27 | #define WIL6210_RTAP_SIZE (128) | 27 | #define WIL6210_RTAP_SIZE (128) |
28 | 28 | ||
@@ -237,7 +237,6 @@ struct vring_tx_mac { | |||
237 | #define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2 | 237 | #define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2 |
238 | #define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 /* L4 type: 0-UDP, 2-TCP */ | 238 | #define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 /* L4 type: 0-UDP, 2-TCP */ |
239 | 239 | ||
240 | |||
241 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_POS 0 | 240 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_POS 0 |
242 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_LEN 7 | 241 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_LEN 7 |
243 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_MSK 0x7F /* MAC hdr len */ | 242 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_MSK 0x7F /* MAC hdr len */ |
@@ -246,7 +245,6 @@ struct vring_tx_mac { | |||
246 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_LEN 1 | 245 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_LEN 1 |
247 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_MSK 0x80 /* 1-IPv4, 0-IPv6 */ | 246 | #define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_MSK 0x80 /* 1-IPv4, 0-IPv6 */ |
248 | 247 | ||
249 | |||
250 | #define TX_DMA_STATUS_DU BIT(0) | 248 | #define TX_DMA_STATUS_DU BIT(0) |
251 | 249 | ||
252 | struct vring_tx_dma { | 250 | struct vring_tx_dma { |
@@ -347,7 +345,6 @@ struct vring_rx_mac { | |||
347 | #define RX_DMA_ERROR_L3_ERR BIT(4) | 345 | #define RX_DMA_ERROR_L3_ERR BIT(4) |
348 | #define RX_DMA_ERROR_L4_ERR BIT(5) | 346 | #define RX_DMA_ERROR_L4_ERR BIT(5) |
349 | 347 | ||
350 | |||
351 | /* Status field */ | 348 | /* Status field */ |
352 | #define RX_DMA_STATUS_DU BIT(0) | 349 | #define RX_DMA_STATUS_DU BIT(0) |
353 | #define RX_DMA_STATUS_ERROR BIT(2) | 350 | #define RX_DMA_STATUS_ERROR BIT(2) |
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h index f8718fe547c4..41aa79327584 100644 --- a/drivers/net/wireless/ath/wil6210/wil6210.h +++ b/drivers/net/wireless/ath/wil6210/wil6210.h | |||
@@ -21,8 +21,13 @@ | |||
21 | #include <linux/wireless.h> | 21 | #include <linux/wireless.h> |
22 | #include <net/cfg80211.h> | 22 | #include <net/cfg80211.h> |
23 | #include <linux/timex.h> | 23 | #include <linux/timex.h> |
24 | #include "wil_platform.h" | ||
25 | |||
24 | 26 | ||
25 | #define WIL_NAME "wil6210" | 27 | #define WIL_NAME "wil6210" |
28 | #define WIL_FW_NAME "wil6210.fw" | ||
29 | |||
30 | #define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */ | ||
26 | 31 | ||
27 | struct wil_board { | 32 | struct wil_board { |
28 | int board; | 33 | int board; |
@@ -86,22 +91,29 @@ struct RGF_ICR { | |||
86 | 91 | ||
87 | /* registers - FW addresses */ | 92 | /* registers - FW addresses */ |
88 | #define RGF_USER_USAGE_1 (0x880004) | 93 | #define RGF_USER_USAGE_1 (0x880004) |
94 | #define RGF_USER_USAGE_6 (0x880018) | ||
89 | #define RGF_USER_HW_MACHINE_STATE (0x8801dc) | 95 | #define RGF_USER_HW_MACHINE_STATE (0x8801dc) |
90 | #define HW_MACHINE_BOOT_DONE (0x3fffffd) | 96 | #define HW_MACHINE_BOOT_DONE (0x3fffffd) |
91 | #define RGF_USER_USER_CPU_0 (0x8801e0) | 97 | #define RGF_USER_USER_CPU_0 (0x8801e0) |
98 | #define BIT_USER_USER_CPU_MAN_RST BIT(1) /* user_cpu_man_rst */ | ||
92 | #define RGF_USER_MAC_CPU_0 (0x8801fc) | 99 | #define RGF_USER_MAC_CPU_0 (0x8801fc) |
100 | #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */ | ||
93 | #define RGF_USER_USER_SCRATCH_PAD (0x8802bc) | 101 | #define RGF_USER_USER_SCRATCH_PAD (0x8802bc) |
94 | #define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */ | 102 | #define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */ |
95 | #define RGF_USER_CLKS_CTL_0 (0x880abc) | 103 | #define RGF_USER_CLKS_CTL_0 (0x880abc) |
104 | #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */ | ||
96 | #define BIT_USER_CLKS_RST_PWGD BIT(11) /* reset on "power good" */ | 105 | #define BIT_USER_CLKS_RST_PWGD BIT(11) /* reset on "power good" */ |
97 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04) | 106 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04) |
98 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08) | 107 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08) |
99 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c) | 108 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c) |
100 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10) | 109 | #define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10) |
101 | #define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14) | 110 | #define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14) |
111 | #define BIT_HPAL_PERST_FROM_PAD BIT(6) | ||
112 | #define BIT_CAR_PERST_RST BIT(7) | ||
102 | #define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */ | 113 | #define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */ |
103 | #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) | 114 | #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) |
104 | #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18) | 115 | #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18) |
116 | #define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c) | ||
105 | 117 | ||
106 | #define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ | 118 | #define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ |
107 | #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) | 119 | #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) |
@@ -136,6 +148,8 @@ struct RGF_ICR { | |||
136 | /* MAC timer, usec, for packet lifetime */ | 148 | /* MAC timer, usec, for packet lifetime */ |
137 | #define RGF_MAC_MTRL_COUNTER_0 (0x886aa8) | 149 | #define RGF_MAC_MTRL_COUNTER_0 (0x886aa8) |
138 | 150 | ||
151 | #define RGF_CAF_ICR (0x88946c) /* struct RGF_ICR */ | ||
152 | |||
139 | /* popular locations */ | 153 | /* popular locations */ |
140 | #define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) | 154 | #define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) |
141 | #define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ | 155 | #define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ |
@@ -154,6 +168,7 @@ struct fw_map { | |||
154 | u32 host; /* PCI/Host address - BAR0 + 0x880000 */ | 168 | u32 host; /* PCI/Host address - BAR0 + 0x880000 */ |
155 | const char *name; /* for debugfs */ | 169 | const char *name; /* for debugfs */ |
156 | }; | 170 | }; |
171 | |||
157 | /* array size should be in sync with actual definition in the wmi.c */ | 172 | /* array size should be in sync with actual definition in the wmi.c */ |
158 | extern const struct fw_map fw_mapping[7]; | 173 | extern const struct fw_map fw_mapping[7]; |
159 | 174 | ||
@@ -303,18 +318,12 @@ struct pci_dev; | |||
303 | * @timeout: reset timer value (in TUs). | 318 | * @timeout: reset timer value (in TUs). |
304 | * @dialog_token: dialog token for aggregation session | 319 | * @dialog_token: dialog token for aggregation session |
305 | * @rcu_head: RCU head used for freeing this struct | 320 | * @rcu_head: RCU head used for freeing this struct |
306 | * @reorder_lock: serializes access to reorder buffer, see below. | ||
307 | * | 321 | * |
308 | * This structure's lifetime is managed by RCU, assignments to | 322 | * This structure's lifetime is managed by RCU, assignments to |
309 | * the array holding it must hold the aggregation mutex. | 323 | * the array holding it must hold the aggregation mutex. |
310 | * | 324 | * |
311 | * The @reorder_lock is used to protect the members of this | ||
312 | * struct, except for @timeout, @buf_size and @dialog_token, | ||
313 | * which are constant across the lifetime of the struct (the | ||
314 | * dialog token being used only for debugging). | ||
315 | */ | 325 | */ |
316 | struct wil_tid_ampdu_rx { | 326 | struct wil_tid_ampdu_rx { |
317 | spinlock_t reorder_lock; /* see above */ | ||
318 | struct sk_buff **reorder_buf; | 327 | struct sk_buff **reorder_buf; |
319 | unsigned long *reorder_time; | 328 | unsigned long *reorder_time; |
320 | struct timer_list session_timer; | 329 | struct timer_list session_timer; |
@@ -363,6 +372,7 @@ struct wil_sta_info { | |||
363 | bool data_port_open; /* can send any data, not only EAPOL */ | 372 | bool data_port_open; /* can send any data, not only EAPOL */ |
364 | /* Rx BACK */ | 373 | /* Rx BACK */ |
365 | struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM]; | 374 | struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM]; |
375 | spinlock_t tid_rx_lock; /* guarding tid_rx array */ | ||
366 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)]; | 376 | unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)]; |
367 | unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)]; | 377 | unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)]; |
368 | }; | 378 | }; |
@@ -389,6 +399,7 @@ struct wil6210_priv { | |||
389 | struct mutex wmi_mutex; | 399 | struct mutex wmi_mutex; |
390 | struct wil6210_mbox_ctl mbox_ctl; | 400 | struct wil6210_mbox_ctl mbox_ctl; |
391 | struct completion wmi_ready; | 401 | struct completion wmi_ready; |
402 | struct completion wmi_call; | ||
392 | u16 wmi_seq; | 403 | u16 wmi_seq; |
393 | u16 reply_id; /**< wait for this WMI event */ | 404 | u16 reply_id; /**< wait for this WMI event */ |
394 | void *reply_buf; | 405 | void *reply_buf; |
@@ -426,6 +437,9 @@ struct wil6210_priv { | |||
426 | /* debugfs */ | 437 | /* debugfs */ |
427 | struct dentry *debug; | 438 | struct dentry *debug; |
428 | struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)]; | 439 | struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)]; |
440 | |||
441 | void *platform_handle; | ||
442 | struct wil_platform_ops platform_ops; | ||
429 | }; | 443 | }; |
430 | 444 | ||
431 | #define wil_to_wiphy(i) (i->wdev->wiphy) | 445 | #define wil_to_wiphy(i) (i->wdev->wiphy) |
@@ -435,10 +449,11 @@ struct wil6210_priv { | |||
435 | #define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) | 449 | #define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) |
436 | #define wil_to_ndev(i) (wil_to_wdev(i)->netdev) | 450 | #define wil_to_ndev(i) (wil_to_wdev(i)->netdev) |
437 | #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) | 451 | #define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) |
452 | #define wil_to_pcie_dev(i) (&i->pdev->dev) | ||
438 | 453 | ||
439 | int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); | 454 | void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); |
440 | int wil_err(struct wil6210_priv *wil, const char *fmt, ...); | 455 | void wil_err(struct wil6210_priv *wil, const char *fmt, ...); |
441 | int wil_info(struct wil6210_priv *wil, const char *fmt, ...); | 456 | void wil_info(struct wil6210_priv *wil, const char *fmt, ...); |
442 | #define wil_dbg(wil, fmt, arg...) do { \ | 457 | #define wil_dbg(wil, fmt, arg...) do { \ |
443 | netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ | 458 | netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ |
444 | wil_dbg_trace(wil, fmt, ##arg); \ | 459 | wil_dbg_trace(wil, fmt, ##arg); \ |
@@ -449,6 +464,7 @@ int wil_info(struct wil6210_priv *wil, const char *fmt, ...); | |||
449 | #define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) | 464 | #define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) |
450 | #define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg) | 465 | #define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg) |
451 | 466 | ||
467 | #if defined(CONFIG_DYNAMIC_DEBUG) | ||
452 | #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ | 468 | #define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ |
453 | groupsize, buf, len, ascii) \ | 469 | groupsize, buf, len, ascii) \ |
454 | print_hex_dump_debug("DBG[TXRX]" prefix_str,\ | 470 | print_hex_dump_debug("DBG[TXRX]" prefix_str,\ |
@@ -460,6 +476,19 @@ int wil_info(struct wil6210_priv *wil, const char *fmt, ...); | |||
460 | print_hex_dump_debug("DBG[ WMI]" prefix_str,\ | 476 | print_hex_dump_debug("DBG[ WMI]" prefix_str,\ |
461 | prefix_type, rowsize, \ | 477 | prefix_type, rowsize, \ |
462 | groupsize, buf, len, ascii) | 478 | groupsize, buf, len, ascii) |
479 | #else /* defined(CONFIG_DYNAMIC_DEBUG) */ | ||
480 | static inline | ||
481 | void wil_hex_dump_txrx(const char *prefix_str, int prefix_type, int rowsize, | ||
482 | int groupsize, const void *buf, size_t len, bool ascii) | ||
483 | { | ||
484 | } | ||
485 | |||
486 | static inline | ||
487 | void wil_hex_dump_wmi(const char *prefix_str, int prefix_type, int rowsize, | ||
488 | int groupsize, const void *buf, size_t len, bool ascii) | ||
489 | { | ||
490 | } | ||
491 | #endif /* defined(CONFIG_DYNAMIC_DEBUG) */ | ||
463 | 492 | ||
464 | void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, | 493 | void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, |
465 | size_t count); | 494 | size_t count); |
@@ -477,7 +506,9 @@ void wil_fw_error_recovery(struct wil6210_priv *wil); | |||
477 | void wil_link_on(struct wil6210_priv *wil); | 506 | void wil_link_on(struct wil6210_priv *wil); |
478 | void wil_link_off(struct wil6210_priv *wil); | 507 | void wil_link_off(struct wil6210_priv *wil); |
479 | int wil_up(struct wil6210_priv *wil); | 508 | int wil_up(struct wil6210_priv *wil); |
509 | int __wil_up(struct wil6210_priv *wil); | ||
480 | int wil_down(struct wil6210_priv *wil); | 510 | int wil_down(struct wil6210_priv *wil); |
511 | int __wil_down(struct wil6210_priv *wil); | ||
481 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); | 512 | void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); |
482 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); | 513 | int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); |
483 | 514 | ||
@@ -510,8 +541,10 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason); | |||
510 | void wil6210_clear_irq(struct wil6210_priv *wil); | 541 | void wil6210_clear_irq(struct wil6210_priv *wil); |
511 | int wil6210_init_irq(struct wil6210_priv *wil, int irq); | 542 | int wil6210_init_irq(struct wil6210_priv *wil, int irq); |
512 | void wil6210_fini_irq(struct wil6210_priv *wil, int irq); | 543 | void wil6210_fini_irq(struct wil6210_priv *wil, int irq); |
513 | void wil6210_disable_irq(struct wil6210_priv *wil); | 544 | void wil_mask_irq(struct wil6210_priv *wil); |
514 | void wil6210_enable_irq(struct wil6210_priv *wil); | 545 | void wil_unmask_irq(struct wil6210_priv *wil); |
546 | void wil_disable_irq(struct wil6210_priv *wil); | ||
547 | void wil_enable_irq(struct wil6210_priv *wil); | ||
515 | int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | 548 | int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
516 | struct cfg80211_mgmt_tx_params *params, | 549 | struct cfg80211_mgmt_tx_params *params, |
517 | u64 *cookie); | 550 | u64 *cookie); |
@@ -547,4 +580,5 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil); | |||
547 | 580 | ||
548 | int wil_iftype_nl2wmi(enum nl80211_iftype type); | 581 | int wil_iftype_nl2wmi(enum nl80211_iftype type); |
549 | 582 | ||
583 | int wil_request_firmware(struct wil6210_priv *wil, const char *name); | ||
550 | #endif /* __WIL6210_H__ */ | 584 | #endif /* __WIL6210_H__ */ |
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.c b/drivers/net/wireless/ath/wil6210/wil_platform.c new file mode 100644 index 000000000000..8f1d78f8a74d --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/wil_platform.c | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "linux/device.h" | ||
18 | #include "wil_platform.h" | ||
19 | |||
20 | #ifdef CONFIG_WIL6210_PLATFORM_MSM | ||
21 | #include "wil_platform_msm.h" | ||
22 | #endif | ||
23 | |||
24 | /** | ||
25 | * wil_platform_init() - wil6210 platform module init | ||
26 | * | ||
27 | * The function must be called before all other functions in this module. | ||
28 | * It returns a handle which is used with the rest of the API | ||
29 | * | ||
30 | */ | ||
31 | void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops) | ||
32 | { | ||
33 | void *handle = NULL; | ||
34 | |||
35 | if (!ops) { | ||
36 | dev_err(dev, "Invalid parameter. Cannot init platform module\n"); | ||
37 | return NULL; | ||
38 | } | ||
39 | |||
40 | #ifdef CONFIG_WIL6210_PLATFORM_MSM | ||
41 | handle = wil_platform_msm_init(dev, ops); | ||
42 | if (handle) | ||
43 | return handle; | ||
44 | #endif | ||
45 | |||
46 | /* other platform specific init functions should be called here */ | ||
47 | |||
48 | return handle; | ||
49 | } | ||
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h b/drivers/net/wireless/ath/wil6210/wil_platform.h new file mode 100644 index 000000000000..158c73b049a9 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/wil_platform.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef __WIL_PLATFORM_H__ | ||
18 | #define __WIL_PLATFORM_H__ | ||
19 | |||
20 | struct device; | ||
21 | |||
22 | /** | ||
23 | * struct wil_platform_ops - wil platform module callbacks | ||
24 | */ | ||
25 | struct wil_platform_ops { | ||
26 | int (*bus_request)(void *handle, uint32_t kbps /* KBytes/Sec */); | ||
27 | int (*suspend)(void *handle); | ||
28 | int (*resume)(void *handle); | ||
29 | void (*uninit)(void *handle); | ||
30 | }; | ||
31 | |||
32 | void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops); | ||
33 | |||
34 | #endif /* __WIL_PLATFORM_H__ */ | ||
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.c b/drivers/net/wireless/ath/wil6210/wil_platform_msm.c new file mode 100644 index 000000000000..b354a743240d --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/wil_platform_msm.c | |||
@@ -0,0 +1,257 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include <linux/of.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/msm-bus.h> | ||
20 | |||
21 | #include "wil_platform.h" | ||
22 | #include "wil_platform_msm.h" | ||
23 | |||
24 | /** | ||
25 | * struct wil_platform_msm - wil6210 msm platform module info | ||
26 | * | ||
27 | * @dev: device object | ||
28 | * @msm_bus_handle: handle for using msm_bus API | ||
29 | * @pdata: bus scale info retrieved from DT | ||
30 | */ | ||
31 | struct wil_platform_msm { | ||
32 | struct device *dev; | ||
33 | uint32_t msm_bus_handle; | ||
34 | struct msm_bus_scale_pdata *pdata; | ||
35 | }; | ||
36 | |||
37 | #define KBTOB(a) (a * 1000ULL) | ||
38 | |||
39 | /** | ||
40 | * wil_platform_get_pdata() - Generate bus client data from device tree | ||
41 | * provided by clients. | ||
42 | * | ||
43 | * dev: device object | ||
44 | * of_node: Device tree node to extract information from | ||
45 | * | ||
46 | * The function returns a valid pointer to the allocated bus-scale-pdata | ||
47 | * if the vectors were correctly read from the client's device node. | ||
48 | * Any error in reading or parsing the device node will return NULL | ||
49 | * to the caller. | ||
50 | */ | ||
51 | static struct msm_bus_scale_pdata *wil_platform_get_pdata( | ||
52 | struct device *dev, | ||
53 | struct device_node *of_node) | ||
54 | { | ||
55 | struct msm_bus_scale_pdata *pdata; | ||
56 | struct msm_bus_paths *usecase; | ||
57 | int i, j, ret, len; | ||
58 | unsigned int num_usecases, num_paths, mem_size; | ||
59 | const uint32_t *vec_arr; | ||
60 | struct msm_bus_vectors *vectors; | ||
61 | |||
62 | /* first read num_usecases and num_paths so we can calculate | ||
63 | * amount of memory to allocate | ||
64 | */ | ||
65 | ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases", | ||
66 | &num_usecases); | ||
67 | if (ret) { | ||
68 | dev_err(dev, "Error: num-usecases not found\n"); | ||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths", | ||
73 | &num_paths); | ||
74 | if (ret) { | ||
75 | dev_err(dev, "Error: num_paths not found\n"); | ||
76 | return NULL; | ||
77 | } | ||
78 | |||
79 | /* pdata memory layout: | ||
80 | * msm_bus_scale_pdata | ||
81 | * msm_bus_paths[num_usecases] | ||
82 | * msm_bus_vectors[num_usecases][num_paths] | ||
83 | */ | ||
84 | mem_size = sizeof(struct msm_bus_scale_pdata) + | ||
85 | sizeof(struct msm_bus_paths) * num_usecases + | ||
86 | sizeof(struct msm_bus_vectors) * num_usecases * num_paths; | ||
87 | |||
88 | pdata = kzalloc(mem_size, GFP_KERNEL); | ||
89 | if (!pdata) | ||
90 | return NULL; | ||
91 | |||
92 | ret = of_property_read_string(of_node, "qcom,msm-bus,name", | ||
93 | &pdata->name); | ||
94 | if (ret) { | ||
95 | dev_err(dev, "Error: Client name not found\n"); | ||
96 | goto err; | ||
97 | } | ||
98 | |||
99 | if (of_property_read_bool(of_node, "qcom,msm-bus,active-only")) { | ||
100 | pdata->active_only = 1; | ||
101 | } else { | ||
102 | dev_info(dev, "active_only flag absent.\n"); | ||
103 | dev_info(dev, "Using dual context by default\n"); | ||
104 | } | ||
105 | |||
106 | pdata->num_usecases = num_usecases; | ||
107 | pdata->usecase = (struct msm_bus_paths *)(pdata + 1); | ||
108 | |||
109 | vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len); | ||
110 | if (vec_arr == NULL) { | ||
111 | dev_err(dev, "Error: Vector array not found\n"); | ||
112 | goto err; | ||
113 | } | ||
114 | |||
115 | if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) { | ||
116 | dev_err(dev, "Error: Length-error on getting vectors\n"); | ||
117 | goto err; | ||
118 | } | ||
119 | |||
120 | vectors = (struct msm_bus_vectors *)(pdata->usecase + num_usecases); | ||
121 | for (i = 0; i < num_usecases; i++) { | ||
122 | usecase = &pdata->usecase[i]; | ||
123 | usecase->num_paths = num_paths; | ||
124 | usecase->vectors = &vectors[i]; | ||
125 | |||
126 | for (j = 0; j < num_paths; j++) { | ||
127 | int index = ((i * num_paths) + j) * 4; | ||
128 | |||
129 | usecase->vectors[j].src = be32_to_cpu(vec_arr[index]); | ||
130 | usecase->vectors[j].dst = | ||
131 | be32_to_cpu(vec_arr[index + 1]); | ||
132 | usecase->vectors[j].ab = (uint64_t) | ||
133 | KBTOB(be32_to_cpu(vec_arr[index + 2])); | ||
134 | usecase->vectors[j].ib = (uint64_t) | ||
135 | KBTOB(be32_to_cpu(vec_arr[index + 3])); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | return pdata; | ||
140 | |||
141 | err: | ||
142 | kfree(pdata); | ||
143 | |||
144 | return NULL; | ||
145 | } | ||
146 | |||
147 | /* wil_platform API (callbacks) */ | ||
148 | |||
149 | static int wil_platform_bus_request(void *handle, | ||
150 | uint32_t kbps /* KBytes/Sec */) | ||
151 | { | ||
152 | int rc, i; | ||
153 | struct wil_platform_msm *msm = (struct wil_platform_msm *)handle; | ||
154 | int vote = 0; /* vote 0 in case requested kbps cannot be satisfied */ | ||
155 | struct msm_bus_paths *usecase; | ||
156 | uint32_t usecase_kbps; | ||
157 | uint32_t min_kbps = ~0; | ||
158 | |||
159 | /* find the lowest usecase that is bigger than requested kbps */ | ||
160 | for (i = 0; i < msm->pdata->num_usecases; i++) { | ||
161 | usecase = &msm->pdata->usecase[i]; | ||
162 | /* assume we have single path (vectors[0]). If we ever | ||
163 | * have multiple paths, need to define the behavior */ | ||
164 | usecase_kbps = div64_u64(usecase->vectors[0].ib, 1000); | ||
165 | if (usecase_kbps >= kbps && usecase_kbps < min_kbps) { | ||
166 | min_kbps = usecase_kbps; | ||
167 | vote = i; | ||
168 | } | ||
169 | } | ||
170 | |||
171 | rc = msm_bus_scale_client_update_request(msm->msm_bus_handle, vote); | ||
172 | if (rc) | ||
173 | dev_err(msm->dev, "Failed msm_bus voting. kbps=%d vote=%d, rc=%d\n", | ||
174 | kbps, vote, rc); | ||
175 | else | ||
176 | /* TOOD: remove */ | ||
177 | dev_info(msm->dev, "msm_bus_scale_client_update_request succeeded. kbps=%d vote=%d\n", | ||
178 | kbps, vote); | ||
179 | |||
180 | return rc; | ||
181 | } | ||
182 | |||
183 | static void wil_platform_uninit(void *handle) | ||
184 | { | ||
185 | struct wil_platform_msm *msm = (struct wil_platform_msm *)handle; | ||
186 | |||
187 | dev_info(msm->dev, "wil_platform_uninit\n"); | ||
188 | |||
189 | if (msm->msm_bus_handle) | ||
190 | msm_bus_scale_unregister_client(msm->msm_bus_handle); | ||
191 | |||
192 | kfree(msm->pdata); | ||
193 | kfree(msm); | ||
194 | } | ||
195 | |||
196 | static int wil_platform_msm_bus_register(struct wil_platform_msm *msm, | ||
197 | struct device_node *node) | ||
198 | { | ||
199 | msm->pdata = wil_platform_get_pdata(msm->dev, node); | ||
200 | if (!msm->pdata) { | ||
201 | dev_err(msm->dev, "Failed getting DT info\n"); | ||
202 | return -EINVAL; | ||
203 | } | ||
204 | |||
205 | msm->msm_bus_handle = msm_bus_scale_register_client(msm->pdata); | ||
206 | if (!msm->msm_bus_handle) { | ||
207 | dev_err(msm->dev, "Failed msm_bus registration\n"); | ||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | dev_info(msm->dev, "msm_bus registration succeeded! handle 0x%x\n", | ||
212 | msm->msm_bus_handle); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | /** | ||
218 | * wil_platform_msm_init() - wil6210 msm platform module init | ||
219 | * | ||
220 | * The function must be called before all other functions in this module. | ||
221 | * It returns a handle which is used with the rest of the API | ||
222 | * | ||
223 | */ | ||
224 | void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops) | ||
225 | { | ||
226 | struct device_node *of_node; | ||
227 | struct wil_platform_msm *msm; | ||
228 | int rc; | ||
229 | |||
230 | of_node = of_find_compatible_node(NULL, NULL, "qcom,wil6210"); | ||
231 | if (!of_node) { | ||
232 | /* this could mean non-msm platform */ | ||
233 | dev_err(dev, "DT node not found\n"); | ||
234 | return NULL; | ||
235 | } | ||
236 | |||
237 | msm = kzalloc(sizeof(*msm), GFP_KERNEL); | ||
238 | if (!msm) | ||
239 | return NULL; | ||
240 | |||
241 | msm->dev = dev; | ||
242 | |||
243 | /* register with msm_bus module for scaling requests */ | ||
244 | rc = wil_platform_msm_bus_register(msm, of_node); | ||
245 | if (rc) | ||
246 | goto cleanup; | ||
247 | |||
248 | memset(ops, 0, sizeof(*ops)); | ||
249 | ops->bus_request = wil_platform_bus_request; | ||
250 | ops->uninit = wil_platform_uninit; | ||
251 | |||
252 | return (void *)msm; | ||
253 | |||
254 | cleanup: | ||
255 | kfree(msm); | ||
256 | return NULL; | ||
257 | } | ||
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.h b/drivers/net/wireless/ath/wil6210/wil_platform_msm.h new file mode 100644 index 000000000000..2f2229edb498 --- /dev/null +++ b/drivers/net/wireless/ath/wil6210/wil_platform_msm.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Qualcomm Atheros, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef __WIL_PLATFORM__MSM_H__ | ||
18 | #define __WIL_PLATFORM_MSM_H__ | ||
19 | |||
20 | #include "wil_platform.h" | ||
21 | |||
22 | void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops); | ||
23 | |||
24 | #endif /* __WIL_PLATFORM__MSM_H__ */ | ||
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c index b1aaaee997d5..bd781c7adf2a 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.c +++ b/drivers/net/wireless/ath/wil6210/wmi.c | |||
@@ -157,6 +157,7 @@ int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr, | |||
157 | struct wil6210_mbox_hdr *hdr) | 157 | struct wil6210_mbox_hdr *hdr) |
158 | { | 158 | { |
159 | void __iomem *src = wmi_buffer(wil, ptr); | 159 | void __iomem *src = wmi_buffer(wil, ptr); |
160 | |||
160 | if (!src) | 161 | if (!src) |
161 | return -EINVAL; | 162 | return -EINVAL; |
162 | 163 | ||
@@ -278,6 +279,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len) | |||
278 | struct net_device *ndev = wil_to_ndev(wil); | 279 | struct net_device *ndev = wil_to_ndev(wil); |
279 | struct wireless_dev *wdev = wil->wdev; | 280 | struct wireless_dev *wdev = wil->wdev; |
280 | struct wmi_ready_event *evt = d; | 281 | struct wmi_ready_event *evt = d; |
282 | |||
281 | wil->fw_version = le32_to_cpu(evt->sw_version); | 283 | wil->fw_version = le32_to_cpu(evt->sw_version); |
282 | wil->n_mids = evt->numof_additional_mids; | 284 | wil->n_mids = evt->numof_additional_mids; |
283 | 285 | ||
@@ -298,7 +300,7 @@ static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d, | |||
298 | wil_dbg_wmi(wil, "WMI: got FW ready event\n"); | 300 | wil_dbg_wmi(wil, "WMI: got FW ready event\n"); |
299 | 301 | ||
300 | set_bit(wil_status_fwready, &wil->status); | 302 | set_bit(wil_status_fwready, &wil->status); |
301 | /* reuse wmi_ready for the firmware ready indication */ | 303 | /* let the reset sequence continue */ |
302 | complete(&wil->wmi_ready); | 304 | complete(&wil->wmi_ready); |
303 | } | 305 | } |
304 | 306 | ||
@@ -595,27 +597,40 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d, | |||
595 | return; | 597 | return; |
596 | } | 598 | } |
597 | 599 | ||
600 | mutex_lock(&wil->mutex); | ||
601 | |||
598 | cid = wil->vring2cid_tid[evt->ringid][0]; | 602 | cid = wil->vring2cid_tid[evt->ringid][0]; |
599 | if (cid >= WIL6210_MAX_CID) { | 603 | if (cid >= WIL6210_MAX_CID) { |
600 | wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid); | 604 | wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid); |
601 | return; | 605 | goto out; |
602 | } | 606 | } |
603 | 607 | ||
604 | sta = &wil->sta[cid]; | 608 | sta = &wil->sta[cid]; |
605 | if (sta->status == wil_sta_unused) { | 609 | if (sta->status == wil_sta_unused) { |
606 | wil_err(wil, "CID %d unused\n", cid); | 610 | wil_err(wil, "CID %d unused\n", cid); |
607 | return; | 611 | goto out; |
608 | } | 612 | } |
609 | 613 | ||
610 | wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); | 614 | wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); |
611 | for (i = 0; i < WIL_STA_TID_NUM; i++) { | 615 | for (i = 0; i < WIL_STA_TID_NUM; i++) { |
612 | struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; | 616 | struct wil_tid_ampdu_rx *r; |
617 | unsigned long flags; | ||
618 | |||
619 | spin_lock_irqsave(&sta->tid_rx_lock, flags); | ||
620 | |||
621 | r = sta->tid_rx[i]; | ||
613 | sta->tid_rx[i] = NULL; | 622 | sta->tid_rx[i] = NULL; |
614 | wil_tid_ampdu_rx_free(wil, r); | 623 | wil_tid_ampdu_rx_free(wil, r); |
624 | |||
625 | spin_unlock_irqrestore(&sta->tid_rx_lock, flags); | ||
626 | |||
615 | if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) | 627 | if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) |
616 | sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, | 628 | sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, |
617 | evt->agg_wsize, 0); | 629 | evt->agg_wsize, 0); |
618 | } | 630 | } |
631 | |||
632 | out: | ||
633 | mutex_unlock(&wil->mutex); | ||
619 | } | 634 | } |
620 | 635 | ||
621 | static const struct { | 636 | static const struct { |
@@ -653,7 +668,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil) | |||
653 | unsigned n; | 668 | unsigned n; |
654 | 669 | ||
655 | if (!test_bit(wil_status_reset_done, &wil->status)) { | 670 | if (!test_bit(wil_status_reset_done, &wil->status)) { |
656 | wil_err(wil, "Reset not completed\n"); | 671 | wil_err(wil, "Reset in progress. Cannot handle WMI event\n"); |
657 | return; | 672 | return; |
658 | } | 673 | } |
659 | 674 | ||
@@ -708,6 +723,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil) | |||
708 | struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi; | 723 | struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi; |
709 | u16 id = le16_to_cpu(wmi->id); | 724 | u16 id = le16_to_cpu(wmi->id); |
710 | u32 tstamp = le32_to_cpu(wmi->timestamp); | 725 | u32 tstamp = le32_to_cpu(wmi->timestamp); |
726 | |||
711 | wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n", | 727 | wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n", |
712 | id, wmi->mid, tstamp); | 728 | id, wmi->mid, tstamp); |
713 | trace_wil6210_wmi_event(wmi, &wmi[1], | 729 | trace_wil6210_wmi_event(wmi, &wmi[1], |
@@ -748,8 +764,8 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len, | |||
748 | wil->reply_id = reply_id; | 764 | wil->reply_id = reply_id; |
749 | wil->reply_buf = reply; | 765 | wil->reply_buf = reply; |
750 | wil->reply_size = reply_size; | 766 | wil->reply_size = reply_size; |
751 | remain = wait_for_completion_timeout(&wil->wmi_ready, | 767 | remain = wait_for_completion_timeout(&wil->wmi_call, |
752 | msecs_to_jiffies(to_msec)); | 768 | msecs_to_jiffies(to_msec)); |
753 | if (0 == remain) { | 769 | if (0 == remain) { |
754 | wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", | 770 | wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", |
755 | cmdid, reply_id, to_msec); | 771 | cmdid, reply_id, to_msec); |
@@ -953,8 +969,11 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie) | |||
953 | int rc; | 969 | int rc; |
954 | u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; | 970 | u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; |
955 | struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); | 971 | struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); |
972 | |||
956 | if (!cmd) | 973 | if (!cmd) |
957 | return -ENOMEM; | 974 | return -ENOMEM; |
975 | if (!ie) | ||
976 | ie_len = 0; | ||
958 | 977 | ||
959 | cmd->mgmt_frm_type = type; | 978 | cmd->mgmt_frm_type = type; |
960 | /* BUG: FW API define ieLen as u8. Will fix FW */ | 979 | /* BUG: FW API define ieLen as u8. Will fix FW */ |
@@ -1128,6 +1147,9 @@ static void wmi_event_handle(struct wil6210_priv *wil, | |||
1128 | struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]); | 1147 | struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]); |
1129 | void *evt_data = (void *)(&wmi[1]); | 1148 | void *evt_data = (void *)(&wmi[1]); |
1130 | u16 id = le16_to_cpu(wmi->id); | 1149 | u16 id = le16_to_cpu(wmi->id); |
1150 | |||
1151 | wil_dbg_wmi(wil, "Handle WMI 0x%04x (reply_id 0x%04x)\n", | ||
1152 | id, wil->reply_id); | ||
1131 | /* check if someone waits for this event */ | 1153 | /* check if someone waits for this event */ |
1132 | if (wil->reply_id && wil->reply_id == id) { | 1154 | if (wil->reply_id && wil->reply_id == id) { |
1133 | if (wil->reply_buf) { | 1155 | if (wil->reply_buf) { |
@@ -1138,7 +1160,7 @@ static void wmi_event_handle(struct wil6210_priv *wil, | |||
1138 | len - sizeof(*wmi)); | 1160 | len - sizeof(*wmi)); |
1139 | } | 1161 | } |
1140 | wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id); | 1162 | wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id); |
1141 | complete(&wil->wmi_ready); | 1163 | complete(&wil->wmi_call); |
1142 | return; | 1164 | return; |
1143 | } | 1165 | } |
1144 | /* unsolicited event */ | 1166 | /* unsolicited event */ |
@@ -1184,9 +1206,11 @@ void wmi_event_worker(struct work_struct *work) | |||
1184 | struct pending_wmi_event *evt; | 1206 | struct pending_wmi_event *evt; |
1185 | struct list_head *lh; | 1207 | struct list_head *lh; |
1186 | 1208 | ||
1209 | wil_dbg_wmi(wil, "Start %s\n", __func__); | ||
1187 | while ((lh = next_wmi_ev(wil)) != NULL) { | 1210 | while ((lh = next_wmi_ev(wil)) != NULL) { |
1188 | evt = list_entry(lh, struct pending_wmi_event, list); | 1211 | evt = list_entry(lh, struct pending_wmi_event, list); |
1189 | wmi_event_handle(wil, &evt->event.hdr); | 1212 | wmi_event_handle(wil, &evt->event.hdr); |
1190 | kfree(evt); | 1213 | kfree(evt); |
1191 | } | 1214 | } |
1215 | wil_dbg_wmi(wil, "Finished %s\n", __func__); | ||
1192 | } | 1216 | } |
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h index 061618cee9f6..27b97432d1c2 100644 --- a/drivers/net/wireless/ath/wil6210/wmi.h +++ b/drivers/net/wireless/ath/wil6210/wmi.h | |||
@@ -179,7 +179,6 @@ enum wmi_crypto_type { | |||
179 | WMI_CRYPT_AES_GCMP = 0x20, | 179 | WMI_CRYPT_AES_GCMP = 0x20, |
180 | }; | 180 | }; |
181 | 181 | ||
182 | |||
183 | enum wmi_connect_ctrl_flag_bits { | 182 | enum wmi_connect_ctrl_flag_bits { |
184 | WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, | 183 | WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, |
185 | WMI_CONNECT_SEND_REASSOC = 0x0002, | 184 | WMI_CONNECT_SEND_REASSOC = 0x0002, |
@@ -219,7 +218,6 @@ struct wmi_disconnect_sta_cmd { | |||
219 | __le16 disconnect_reason; | 218 | __le16 disconnect_reason; |
220 | } __packed; | 219 | } __packed; |
221 | 220 | ||
222 | |||
223 | /* | 221 | /* |
224 | * WMI_SET_PMK_CMDID | 222 | * WMI_SET_PMK_CMDID |
225 | */ | 223 | */ |
@@ -234,7 +232,6 @@ struct wmi_set_pmk_cmd { | |||
234 | u8 pmk[WMI_PMK_LEN]; | 232 | u8 pmk[WMI_PMK_LEN]; |
235 | } __packed; | 233 | } __packed; |
236 | 234 | ||
237 | |||
238 | /* | 235 | /* |
239 | * WMI_SET_PASSPHRASE_CMDID | 236 | * WMI_SET_PASSPHRASE_CMDID |
240 | */ | 237 | */ |
@@ -273,7 +270,6 @@ struct wmi_delete_cipher_key_cmd { | |||
273 | u8 mac[WMI_MAC_LEN]; | 270 | u8 mac[WMI_MAC_LEN]; |
274 | } __packed; | 271 | } __packed; |
275 | 272 | ||
276 | |||
277 | /* | 273 | /* |
278 | * WMI_START_SCAN_CMDID | 274 | * WMI_START_SCAN_CMDID |
279 | * | 275 | * |
@@ -325,7 +321,6 @@ struct wmi_probed_ssid_cmd { | |||
325 | u8 ssid[WMI_MAX_SSID_LEN]; | 321 | u8 ssid[WMI_MAX_SSID_LEN]; |
326 | } __packed; | 322 | } __packed; |
327 | 323 | ||
328 | |||
329 | /* | 324 | /* |
330 | * WMI_SET_APPIE_CMDID | 325 | * WMI_SET_APPIE_CMDID |
331 | * Add Application specified IE to a management frame | 326 | * Add Application specified IE to a management frame |
@@ -351,7 +346,6 @@ struct wmi_set_appie_cmd { | |||
351 | u8 ie_info[0]; | 346 | u8 ie_info[0]; |
352 | } __packed; | 347 | } __packed; |
353 | 348 | ||
354 | |||
355 | /* | 349 | /* |
356 | * WMI_PXMT_RANGE_CFG_CMDID | 350 | * WMI_PXMT_RANGE_CFG_CMDID |
357 | */ | 351 | */ |
@@ -380,7 +374,6 @@ struct wmi_rf_mgmt_cmd { | |||
380 | __le32 rf_mgmt_type; | 374 | __le32 rf_mgmt_type; |
381 | } __packed; | 375 | } __packed; |
382 | 376 | ||
383 | |||
384 | /* | 377 | /* |
385 | * WMI_RF_RX_TEST_CMDID | 378 | * WMI_RF_RX_TEST_CMDID |
386 | */ | 379 | */ |
@@ -426,7 +419,6 @@ struct wmi_bcon_ctrl_cmd { | |||
426 | u8 disable_sec; | 419 | u8 disable_sec; |
427 | } __packed; | 420 | } __packed; |
428 | 421 | ||
429 | |||
430 | /******* P2P ***********/ | 422 | /******* P2P ***********/ |
431 | 423 | ||
432 | /* | 424 | /* |
@@ -797,7 +789,6 @@ struct wmi_temp_sense_cmd { | |||
797 | __le32 measure_marlon_r_en; | 789 | __le32 measure_marlon_r_en; |
798 | } __packed; | 790 | } __packed; |
799 | 791 | ||
800 | |||
801 | /* | 792 | /* |
802 | * WMI Events | 793 | * WMI Events |
803 | */ | 794 | */ |
@@ -887,7 +878,6 @@ enum wmi_event_id { | |||
887 | * Events data structures | 878 | * Events data structures |
888 | */ | 879 | */ |
889 | 880 | ||
890 | |||
891 | enum wmi_fw_status { | 881 | enum wmi_fw_status { |
892 | WMI_FW_STATUS_SUCCESS, | 882 | WMI_FW_STATUS_SUCCESS, |
893 | WMI_FW_STATUS_FAILURE, | 883 | WMI_FW_STATUS_FAILURE, |
@@ -1038,8 +1028,8 @@ struct wmi_disconnect_event { | |||
1038 | __le16 protocol_reason_status; /* reason code, see 802.11 spec. */ | 1028 | __le16 protocol_reason_status; /* reason code, see 802.11 spec. */ |
1039 | u8 bssid[WMI_MAC_LEN]; /* set if known */ | 1029 | u8 bssid[WMI_MAC_LEN]; /* set if known */ |
1040 | u8 disconnect_reason; /* see wmi_disconnect_reason */ | 1030 | u8 disconnect_reason; /* see wmi_disconnect_reason */ |
1041 | u8 assoc_resp_len; /* not in use */ | 1031 | u8 assoc_resp_len; /* not used */ |
1042 | u8 assoc_info[0]; /* not in use */ | 1032 | u8 assoc_info[0]; /* not used */ |
1043 | } __packed; | 1033 | } __packed; |
1044 | 1034 | ||
1045 | /* | 1035 | /* |
@@ -1081,7 +1071,6 @@ struct wmi_delba_event { | |||
1081 | __le16 reason; | 1071 | __le16 reason; |
1082 | } __packed; | 1072 | } __packed; |
1083 | 1073 | ||
1084 | |||
1085 | /* | 1074 | /* |
1086 | * WMI_VRING_CFG_DONE_EVENTID | 1075 | * WMI_VRING_CFG_DONE_EVENTID |
1087 | */ | 1076 | */ |
@@ -1147,7 +1136,6 @@ struct wmi_data_port_open_event { | |||
1147 | u8 reserved[3]; | 1136 | u8 reserved[3]; |
1148 | } __packed; | 1137 | } __packed; |
1149 | 1138 | ||
1150 | |||
1151 | /* | 1139 | /* |
1152 | * WMI_GET_PCP_CHANNEL_EVENTID | 1140 | * WMI_GET_PCP_CHANNEL_EVENTID |
1153 | */ | 1141 | */ |
@@ -1156,7 +1144,6 @@ struct wmi_get_pcp_channel_event { | |||
1156 | u8 reserved[3]; | 1144 | u8 reserved[3]; |
1157 | } __packed; | 1145 | } __packed; |
1158 | 1146 | ||
1159 | |||
1160 | /* | 1147 | /* |
1161 | * WMI_PORT_ALLOCATED_EVENTID | 1148 | * WMI_PORT_ALLOCATED_EVENTID |
1162 | */ | 1149 | */ |
@@ -1260,7 +1247,6 @@ struct wmi_rx_mgmt_info { | |||
1260 | u8 channel; /* From Radio MNGR */ | 1247 | u8 channel; /* From Radio MNGR */ |
1261 | } __packed; | 1248 | } __packed; |
1262 | 1249 | ||
1263 | |||
1264 | /* | 1250 | /* |
1265 | * WMI_TX_MGMT_PACKET_EVENTID | 1251 | * WMI_TX_MGMT_PACKET_EVENTID |
1266 | */ | 1252 | */ |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 95a943326420..bb12586cd7cd 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #define B43_MMIO_RAM_DATA 0x134 | 45 | #define B43_MMIO_RAM_DATA 0x134 |
46 | #define B43_MMIO_PS_STATUS 0x140 | 46 | #define B43_MMIO_PS_STATUS 0x140 |
47 | #define B43_MMIO_RADIO_HWENABLED_HI 0x158 | 47 | #define B43_MMIO_RADIO_HWENABLED_HI 0x158 |
48 | #define B43_MMIO_MAC_HW_CAP 0x15C /* MAC capabilities (corerev >= 13) */ | ||
48 | #define B43_MMIO_SHM_CONTROL 0x160 | 49 | #define B43_MMIO_SHM_CONTROL 0x160 |
49 | #define B43_MMIO_SHM_DATA 0x164 | 50 | #define B43_MMIO_SHM_DATA 0x164 |
50 | #define B43_MMIO_SHM_DATA_UNALIGNED 0x166 | 51 | #define B43_MMIO_SHM_DATA_UNALIGNED 0x166 |
@@ -253,6 +254,8 @@ enum { | |||
253 | #define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ | 254 | #define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ |
254 | #define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ | 255 | #define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ |
255 | #define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ | 256 | #define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ |
257 | #define B43_SHM_SH_MACHW_L 0x00C0 /* Location where the ucode expects the MAC capabilities */ | ||
258 | #define B43_SHM_SH_MACHW_H 0x00C2 /* Location where the ucode expects the MAC capabilities */ | ||
256 | #define B43_SHM_SH_HOSTF5 0x00D4 /* Hostflags 5 for ucode options */ | 259 | #define B43_SHM_SH_HOSTF5 0x00D4 /* Hostflags 5 for ucode options */ |
257 | #define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ | 260 | #define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ |
258 | /* TSSI information */ | 261 | /* TSSI information */ |
@@ -297,6 +300,7 @@ enum { | |||
297 | #define B43_SHM_SH_LFFBLIM 0x0046 /* Long frame fallback retry limit */ | 300 | #define B43_SHM_SH_LFFBLIM 0x0046 /* Long frame fallback retry limit */ |
298 | #define B43_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word (see PHY TX control) */ | 301 | #define B43_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word (see PHY TX control) */ |
299 | #define B43_SHM_SH_EXTNPHYCTL 0x00B0 /* Extended bytes for beacon PHY control (N) */ | 302 | #define B43_SHM_SH_EXTNPHYCTL 0x00B0 /* Extended bytes for beacon PHY control (N) */ |
303 | #define B43_SHM_SH_BCN_LI 0x00B6 /* beacon listen interval */ | ||
300 | /* SHM_SHARED ACK/CTS control */ | 304 | /* SHM_SHARED ACK/CTS control */ |
301 | #define B43_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word (see PHY TX control) */ | 305 | #define B43_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word (see PHY TX control) */ |
302 | /* SHM_SHARED probe response variables */ | 306 | /* SHM_SHARED probe response variables */ |
@@ -476,6 +480,11 @@ enum { | |||
476 | #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ | 480 | #define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ |
477 | #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ | 481 | #define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ |
478 | 482 | ||
483 | /* B43_MMIO_PSM_PHY_HDR bits */ | ||
484 | #define B43_PSM_HDR_MAC_PHY_RESET 0x00000001 | ||
485 | #define B43_PSM_HDR_MAC_PHY_CLOCK_EN 0x00000002 | ||
486 | #define B43_PSM_HDR_MAC_PHY_FORCE_CLK 0x00000004 | ||
487 | |||
479 | /* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */ | 488 | /* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */ |
480 | #define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100 | 489 | #define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100 |
481 | #define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200 | 490 | #define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200 |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 66ff718cc412..5d4173ee55bc 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -1204,6 +1204,36 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags) | |||
1204 | } | 1204 | } |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | /* http://bcm-v4.sipsolutions.net/802.11/PHY/BmacCorePllReset */ | ||
1208 | void b43_wireless_core_phy_pll_reset(struct b43_wldev *dev) | ||
1209 | { | ||
1210 | struct bcma_drv_cc *bcma_cc __maybe_unused; | ||
1211 | struct ssb_chipcommon *ssb_cc __maybe_unused; | ||
1212 | |||
1213 | switch (dev->dev->bus_type) { | ||
1214 | #ifdef CONFIG_B43_BCMA | ||
1215 | case B43_BUS_BCMA: | ||
1216 | bcma_cc = &dev->dev->bdev->bus->drv_cc; | ||
1217 | |||
1218 | bcma_cc_write32(bcma_cc, BCMA_CC_CHIPCTL_ADDR, 0); | ||
1219 | bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); | ||
1220 | bcma_cc_set32(bcma_cc, BCMA_CC_CHIPCTL_DATA, 0x4); | ||
1221 | bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); | ||
1222 | break; | ||
1223 | #endif | ||
1224 | #ifdef CONFIG_B43_SSB | ||
1225 | case B43_BUS_SSB: | ||
1226 | ssb_cc = &dev->dev->sdev->bus->chipco; | ||
1227 | |||
1228 | chipco_write32(ssb_cc, SSB_CHIPCO_CHIPCTL_ADDR, 0); | ||
1229 | chipco_mask32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, ~0x4); | ||
1230 | chipco_set32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, 0x4); | ||
1231 | chipco_mask32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, ~0x4); | ||
1232 | break; | ||
1233 | #endif | ||
1234 | } | ||
1235 | } | ||
1236 | |||
1207 | #ifdef CONFIG_B43_BCMA | 1237 | #ifdef CONFIG_B43_BCMA |
1208 | static void b43_bcma_phy_reset(struct b43_wldev *dev) | 1238 | static void b43_bcma_phy_reset(struct b43_wldev *dev) |
1209 | { | 1239 | { |
@@ -2985,7 +3015,22 @@ void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode) | |||
2985 | { | 3015 | { |
2986 | u16 chip_id = dev->dev->chip_id; | 3016 | u16 chip_id = dev->dev->chip_id; |
2987 | 3017 | ||
2988 | if (chip_id == BCMA_CHIP_ID_BCM43131 || | 3018 | if (chip_id == BCMA_CHIP_ID_BCM4331) { |
3019 | switch (spurmode) { | ||
3020 | case 2: /* 168 Mhz: 2^26/168 = 0x61862 */ | ||
3021 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x1862); | ||
3022 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6); | ||
3023 | break; | ||
3024 | case 1: /* 164 Mhz: 2^26/164 = 0x63e70 */ | ||
3025 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x3e70); | ||
3026 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6); | ||
3027 | break; | ||
3028 | default: /* 160 Mhz: 2^26/160 = 0x66666 */ | ||
3029 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x6666); | ||
3030 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6); | ||
3031 | break; | ||
3032 | } | ||
3033 | } else if (chip_id == BCMA_CHIP_ID_BCM43131 || | ||
2989 | chip_id == BCMA_CHIP_ID_BCM43217 || | 3034 | chip_id == BCMA_CHIP_ID_BCM43217 || |
2990 | chip_id == BCMA_CHIP_ID_BCM43222 || | 3035 | chip_id == BCMA_CHIP_ID_BCM43222 || |
2991 | chip_id == BCMA_CHIP_ID_BCM43224 || | 3036 | chip_id == BCMA_CHIP_ID_BCM43224 || |
@@ -3106,6 +3151,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev) | |||
3106 | case B43_PHYTYPE_HT: | 3151 | case B43_PHYTYPE_HT: |
3107 | case B43_PHYTYPE_LCN: | 3152 | case B43_PHYTYPE_LCN: |
3108 | b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); | 3153 | b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); |
3154 | b43_rate_memory_write(dev, B43_OFDM_RATE_9MB, 1); | ||
3109 | b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); | 3155 | b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); |
3110 | b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); | 3156 | b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); |
3111 | b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1); | 3157 | b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1); |
@@ -3884,6 +3930,12 @@ static int b43_switch_band(struct b43_wldev *dev, | |||
3884 | return 0; | 3930 | return 0; |
3885 | } | 3931 | } |
3886 | 3932 | ||
3933 | static void b43_set_beacon_listen_interval(struct b43_wldev *dev, u16 interval) | ||
3934 | { | ||
3935 | interval = min_t(u16, interval, (u16)0xFF); | ||
3936 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BCN_LI, interval); | ||
3937 | } | ||
3938 | |||
3887 | /* Write the short and long frame retry limit values. */ | 3939 | /* Write the short and long frame retry limit values. */ |
3888 | static void b43_set_retry_limits(struct b43_wldev *dev, | 3940 | static void b43_set_retry_limits(struct b43_wldev *dev, |
3889 | unsigned int short_retry, | 3941 | unsigned int short_retry, |
@@ -3912,6 +3964,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed) | |||
3912 | mutex_lock(&wl->mutex); | 3964 | mutex_lock(&wl->mutex); |
3913 | b43_mac_suspend(dev); | 3965 | b43_mac_suspend(dev); |
3914 | 3966 | ||
3967 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) | ||
3968 | b43_set_beacon_listen_interval(dev, conf->listen_interval); | ||
3969 | |||
3915 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 3970 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
3916 | phy->chandef = &conf->chandef; | 3971 | phy->chandef = &conf->chandef; |
3917 | phy->channel = conf->chandef.chan->hw_value; | 3972 | phy->channel = conf->chandef.chan->hw_value; |
@@ -4812,6 +4867,16 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4812 | hf &= ~B43_HF_SKCFPUP; | 4867 | hf &= ~B43_HF_SKCFPUP; |
4813 | b43_hf_write(dev, hf); | 4868 | b43_hf_write(dev, hf); |
4814 | 4869 | ||
4870 | /* tell the ucode MAC capabilities */ | ||
4871 | if (dev->dev->core_rev >= 13) { | ||
4872 | u32 mac_hw_cap = b43_read32(dev, B43_MMIO_MAC_HW_CAP); | ||
4873 | |||
4874 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MACHW_L, | ||
4875 | mac_hw_cap & 0xffff); | ||
4876 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MACHW_H, | ||
4877 | (mac_hw_cap >> 16) & 0xffff); | ||
4878 | } | ||
4879 | |||
4815 | b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT, | 4880 | b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT, |
4816 | B43_DEFAULT_LONG_RETRY_LIMIT); | 4881 | B43_DEFAULT_LONG_RETRY_LIMIT); |
4817 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3); | 4882 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3); |
@@ -4834,6 +4899,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev) | |||
4834 | /* Maximum Contention Window */ | 4899 | /* Maximum Contention Window */ |
4835 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); | 4900 | b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); |
4836 | 4901 | ||
4902 | /* write phytype and phyvers */ | ||
4903 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PHYTYPE, phy->type); | ||
4904 | b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PHYVER, phy->rev); | ||
4905 | |||
4837 | if (b43_bus_host_is_pcmcia(dev->dev) || | 4906 | if (b43_bus_host_is_pcmcia(dev->dev) || |
4838 | b43_bus_host_is_sdio(dev->dev)) { | 4907 | b43_bus_host_is_sdio(dev->dev)) { |
4839 | dev->__using_pio_transfers = true; | 4908 | dev->__using_pio_transfers = true; |
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index 9f22e4b4c132..c46430cc725c 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -96,6 +96,8 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason); | |||
96 | #define B43_PS_ASLEEP (1 << 3) /* Force device asleep */ | 96 | #define B43_PS_ASLEEP (1 << 3) /* Force device asleep */ |
97 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags); | 97 | void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags); |
98 | 98 | ||
99 | void b43_wireless_core_phy_pll_reset(struct b43_wldev *dev); | ||
100 | |||
99 | void b43_mac_suspend(struct b43_wldev *dev); | 101 | void b43_mac_suspend(struct b43_wldev *dev); |
100 | void b43_mac_enable(struct b43_wldev *dev); | 102 | void b43_mac_enable(struct b43_wldev *dev); |
101 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on); | 103 | void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on); |
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c index c4dc8b020f60..bd68945965d6 100644 --- a/drivers/net/wireless/b43/phy_ht.c +++ b/drivers/net/wireless/b43/phy_ht.c | |||
@@ -81,80 +81,104 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev, | |||
81 | udelay(50); | 81 | udelay(50); |
82 | 82 | ||
83 | /* Calibration */ | 83 | /* Calibration */ |
84 | b43_radio_mask(dev, 0x2b, ~0x1); | 84 | b43_radio_mask(dev, R2059_RFPLL_MISC_EN, ~0x1); |
85 | b43_radio_mask(dev, 0x2e, ~0x4); | 85 | b43_radio_mask(dev, R2059_RFPLL_MISC_CAL_RESETN, ~0x4); |
86 | b43_radio_set(dev, 0x2e, 0x4); | 86 | b43_radio_set(dev, R2059_RFPLL_MISC_CAL_RESETN, 0x4); |
87 | b43_radio_set(dev, 0x2b, 0x1); | 87 | b43_radio_set(dev, R2059_RFPLL_MISC_EN, 0x1); |
88 | 88 | ||
89 | udelay(300); | 89 | udelay(300); |
90 | } | 90 | } |
91 | 91 | ||
92 | static void b43_radio_2059_init(struct b43_wldev *dev) | 92 | /* Calibrate resistors in LPF of PLL? */ |
93 | static void b43_radio_2059_rcal(struct b43_wldev *dev) | ||
94 | { | ||
95 | /* Enable */ | ||
96 | b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x1); | ||
97 | usleep_range(10, 20); | ||
98 | |||
99 | b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1); | ||
100 | b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2); | ||
101 | |||
102 | /* Start */ | ||
103 | b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x2); | ||
104 | usleep_range(100, 200); | ||
105 | |||
106 | /* Stop */ | ||
107 | b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x2); | ||
108 | |||
109 | if (!b43_radio_wait_value(dev, R2059_C3 | R2059_RCAL_STATUS, 1, 1, 100, | ||
110 | 1000000)) | ||
111 | b43err(dev->wl, "Radio 0x2059 rcal timeout\n"); | ||
112 | |||
113 | /* Disable */ | ||
114 | b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x1); | ||
115 | |||
116 | b43_radio_set(dev, 0xa, 0x60); | ||
117 | } | ||
118 | |||
119 | /* Calibrate the internal RC oscillator? */ | ||
120 | static void b43_radio_2057_rccal(struct b43_wldev *dev) | ||
93 | { | 121 | { |
94 | const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 }; | ||
95 | const u16 radio_values[3][2] = { | 122 | const u16 radio_values[3][2] = { |
96 | { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, | 123 | { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, |
97 | }; | 124 | }; |
98 | u16 i, j; | 125 | int i; |
99 | 126 | ||
100 | b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); | 127 | for (i = 0; i < 3; i++) { |
101 | b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); | 128 | b43_radio_write(dev, R2059_RCCAL_MASTER, radio_values[i][0]); |
129 | b43_radio_write(dev, R2059_RCCAL_X1, 0x6E); | ||
130 | b43_radio_write(dev, R2059_RCCAL_TRC0, radio_values[i][1]); | ||
102 | 131 | ||
103 | for (i = 0; i < ARRAY_SIZE(routing); i++) | 132 | /* Start */ |
104 | b43_radio_set(dev, routing[i] | 0x146, 0x3); | 133 | b43_radio_write(dev, R2059_RCCAL_START_R1_Q1_P1, 0x55); |
105 | 134 | ||
106 | b43_radio_set(dev, 0x2e, 0x0078); | 135 | /* Wait */ |
107 | b43_radio_set(dev, 0xc0, 0x0080); | 136 | if (!b43_radio_wait_value(dev, R2059_RCCAL_DONE_OSCCAP, 2, 2, |
108 | msleep(2); | 137 | 500, 5000000)) |
109 | b43_radio_mask(dev, 0x2e, ~0x0078); | 138 | b43err(dev->wl, "Radio 0x2059 rccal timeout\n"); |
110 | b43_radio_mask(dev, 0xc0, ~0x0080); | ||
111 | 139 | ||
112 | if (1) { /* FIXME */ | 140 | /* Stop */ |
113 | b43_radio_set(dev, R2059_C3 | 0x4, 0x1); | 141 | b43_radio_write(dev, R2059_RCCAL_START_R1_Q1_P1, 0x15); |
114 | udelay(10); | 142 | } |
115 | b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1); | ||
116 | b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2); | ||
117 | 143 | ||
118 | b43_radio_set(dev, R2059_C3 | 0x4, 0x2); | 144 | b43_radio_mask(dev, R2059_RCCAL_MASTER, ~0x1); |
119 | udelay(100); | 145 | } |
120 | b43_radio_mask(dev, R2059_C3 | 0x4, ~0x2); | ||
121 | 146 | ||
122 | for (i = 0; i < 10000; i++) { | 147 | static void b43_radio_2059_init_pre(struct b43_wldev *dev) |
123 | if (b43_radio_read(dev, R2059_C3 | 0x145) & 1) { | 148 | { |
124 | i = 0; | 149 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD, ~B43_PHY_HT_RF_CTL_CMD_CHIP0_PU); |
125 | break; | 150 | b43_phy_set(dev, B43_PHY_HT_RF_CTL_CMD, B43_PHY_HT_RF_CTL_CMD_FORCE); |
126 | } | 151 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD, ~B43_PHY_HT_RF_CTL_CMD_FORCE); |
127 | udelay(100); | 152 | b43_phy_set(dev, B43_PHY_HT_RF_CTL_CMD, B43_PHY_HT_RF_CTL_CMD_CHIP0_PU); |
128 | } | 153 | } |
129 | if (i) | ||
130 | b43err(dev->wl, "radio 0x945 timeout\n"); | ||
131 | |||
132 | b43_radio_mask(dev, R2059_C3 | 0x4, ~0x1); | ||
133 | b43_radio_set(dev, 0xa, 0x60); | ||
134 | |||
135 | for (i = 0; i < 3; i++) { | ||
136 | b43_radio_write(dev, 0x17F, radio_values[i][0]); | ||
137 | b43_radio_write(dev, 0x13D, 0x6E); | ||
138 | b43_radio_write(dev, 0x13E, radio_values[i][1]); | ||
139 | b43_radio_write(dev, 0x13C, 0x55); | ||
140 | |||
141 | for (j = 0; j < 10000; j++) { | ||
142 | if (b43_radio_read(dev, 0x140) & 2) { | ||
143 | j = 0; | ||
144 | break; | ||
145 | } | ||
146 | udelay(500); | ||
147 | } | ||
148 | if (j) | ||
149 | b43err(dev->wl, "radio 0x140 timeout\n"); | ||
150 | 154 | ||
151 | b43_radio_write(dev, 0x13C, 0x15); | 155 | static void b43_radio_2059_init(struct b43_wldev *dev) |
152 | } | 156 | { |
157 | const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 }; | ||
158 | int i; | ||
159 | |||
160 | /* Prepare (reset?) radio */ | ||
161 | b43_radio_2059_init_pre(dev); | ||
162 | |||
163 | r2059_upload_inittabs(dev); | ||
164 | |||
165 | for (i = 0; i < ARRAY_SIZE(routing); i++) | ||
166 | b43_radio_set(dev, routing[i] | 0x146, 0x3); | ||
167 | |||
168 | /* Post init starts below */ | ||
169 | |||
170 | b43_radio_set(dev, R2059_RFPLL_MISC_CAL_RESETN, 0x0078); | ||
171 | b43_radio_set(dev, R2059_XTAL_CONFIG2, 0x0080); | ||
172 | msleep(2); | ||
173 | b43_radio_mask(dev, R2059_RFPLL_MISC_CAL_RESETN, ~0x0078); | ||
174 | b43_radio_mask(dev, R2059_XTAL_CONFIG2, ~0x0080); | ||
153 | 175 | ||
154 | b43_radio_mask(dev, 0x17F, ~0x1); | 176 | if (1) { /* FIXME */ |
177 | b43_radio_2059_rcal(dev); | ||
178 | b43_radio_2057_rccal(dev); | ||
155 | } | 179 | } |
156 | 180 | ||
157 | b43_radio_mask(dev, 0x11, ~0x0008); | 181 | b43_radio_mask(dev, R2059_RFPLL_MASTER, ~0x0008); |
158 | } | 182 | } |
159 | 183 | ||
160 | /************************************************** | 184 | /************************************************** |
@@ -297,6 +321,26 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev) | |||
297 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); | 321 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); |
298 | } | 322 | } |
299 | 323 | ||
324 | static void b43_phy_ht_bphy_reset(struct b43_wldev *dev, bool reset) | ||
325 | { | ||
326 | u16 tmp; | ||
327 | |||
328 | tmp = b43_read16(dev, B43_MMIO_PSM_PHY_HDR); | ||
329 | b43_write16(dev, B43_MMIO_PSM_PHY_HDR, | ||
330 | tmp | B43_PSM_HDR_MAC_PHY_FORCE_CLK); | ||
331 | |||
332 | /* Put BPHY in or take it out of the reset */ | ||
333 | if (reset) | ||
334 | b43_phy_set(dev, B43_PHY_B_BBCFG, | ||
335 | B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX); | ||
336 | else | ||
337 | b43_phy_mask(dev, B43_PHY_B_BBCFG, | ||
338 | (u16)~(B43_PHY_B_BBCFG_RSTCCA | | ||
339 | B43_PHY_B_BBCFG_RSTRX)); | ||
340 | |||
341 | b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp); | ||
342 | } | ||
343 | |||
300 | /************************************************** | 344 | /************************************************** |
301 | * Samples | 345 | * Samples |
302 | **************************************************/ | 346 | **************************************************/ |
@@ -704,7 +748,6 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, | |||
704 | { | 748 | { |
705 | struct bcma_device *core = dev->dev->bdev; | 749 | struct bcma_device *core = dev->dev->bdev; |
706 | int spuravoid = 0; | 750 | int spuravoid = 0; |
707 | u16 tmp; | ||
708 | 751 | ||
709 | /* Check for 13 and 14 is just a guess, we don't have enough logs. */ | 752 | /* Check for 13 and 14 is just a guess, we don't have enough logs. */ |
710 | if (new_channel->hw_value == 13 || new_channel->hw_value == 14) | 753 | if (new_channel->hw_value == 13 || new_channel->hw_value == 14) |
@@ -717,22 +760,9 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev, | |||
717 | B43_BCMA_CLKCTLST_80211_PLL_ST | | 760 | B43_BCMA_CLKCTLST_80211_PLL_ST | |
718 | B43_BCMA_CLKCTLST_PHY_PLL_ST, false); | 761 | B43_BCMA_CLKCTLST_PHY_PLL_ST, false); |
719 | 762 | ||
720 | /* Values has been taken from wlc_bmac_switch_macfreq comments */ | 763 | b43_mac_switch_freq(dev, spuravoid); |
721 | switch (spuravoid) { | ||
722 | case 2: /* 126MHz */ | ||
723 | tmp = 0x2082; | ||
724 | break; | ||
725 | case 1: /* 123MHz */ | ||
726 | tmp = 0x5341; | ||
727 | break; | ||
728 | default: /* 120MHz */ | ||
729 | tmp = 0x8889; | ||
730 | } | ||
731 | |||
732 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp); | ||
733 | b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8); | ||
734 | 764 | ||
735 | /* TODO: reset PLL */ | 765 | b43_wireless_core_phy_pll_reset(dev); |
736 | 766 | ||
737 | if (spuravoid) | 767 | if (spuravoid) |
738 | b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX); | 768 | b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX); |
@@ -747,13 +777,19 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev, | |||
747 | const struct b43_phy_ht_channeltab_e_phy *e, | 777 | const struct b43_phy_ht_channeltab_e_phy *e, |
748 | struct ieee80211_channel *new_channel) | 778 | struct ieee80211_channel *new_channel) |
749 | { | 779 | { |
750 | bool old_band_5ghz; | 780 | if (new_channel->band == IEEE80211_BAND_5GHZ) { |
781 | /* Switch to 2 GHz for a moment to access B-PHY regs */ | ||
782 | b43_phy_mask(dev, B43_PHY_HT_BANDCTL, ~B43_PHY_HT_BANDCTL_5GHZ); | ||
783 | |||
784 | b43_phy_ht_bphy_reset(dev, true); | ||
751 | 785 | ||
752 | old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ | 786 | /* Switch to 5 GHz */ |
753 | if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { | 787 | b43_phy_set(dev, B43_PHY_HT_BANDCTL, B43_PHY_HT_BANDCTL_5GHZ); |
754 | /* TODO */ | 788 | } else { |
755 | } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { | 789 | /* Switch to 2 GHz */ |
756 | /* TODO */ | 790 | b43_phy_mask(dev, B43_PHY_HT_BANDCTL, ~B43_PHY_HT_BANDCTL_5GHZ); |
791 | |||
792 | b43_phy_ht_bphy_reset(dev, false); | ||
757 | } | 793 | } |
758 | 794 | ||
759 | b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); | 795 | b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); |
@@ -1002,19 +1038,10 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev, | |||
1002 | if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) | 1038 | if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) |
1003 | b43err(dev->wl, "MAC not suspended\n"); | 1039 | b43err(dev->wl, "MAC not suspended\n"); |
1004 | 1040 | ||
1005 | /* In the following PHY ops we copy wl's dummy behaviour. | ||
1006 | * TODO: Find out if reads (currently hidden in masks/masksets) are | ||
1007 | * needed and replace following ops with just writes or w&r. | ||
1008 | * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can | ||
1009 | * cause delayed (!) machine lock up. */ | ||
1010 | if (blocked) { | 1041 | if (blocked) { |
1011 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); | 1042 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD, |
1043 | ~B43_PHY_HT_RF_CTL_CMD_CHIP0_PU); | ||
1012 | } else { | 1044 | } else { |
1013 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); | ||
1014 | b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x1); | ||
1015 | b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); | ||
1016 | b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x2); | ||
1017 | |||
1018 | if (dev->phy.radio_ver == 0x2059) | 1045 | if (dev->phy.radio_ver == 0x2059) |
1019 | b43_radio_2059_init(dev); | 1046 | b43_radio_2059_init(dev); |
1020 | else | 1047 | else |
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h index 6cae370d1018..c086f56ce478 100644 --- a/drivers/net/wireless/b43/phy_ht.h +++ b/drivers/net/wireless/b43/phy_ht.h | |||
@@ -81,7 +81,9 @@ | |||
81 | #define B43_PHY_HT_RF_SEQ_STATUS B43_PHY_EXTG(0x004) | 81 | #define B43_PHY_HT_RF_SEQ_STATUS B43_PHY_EXTG(0x004) |
82 | /* Values for the status are the same as for the trigger */ | 82 | /* Values for the status are the same as for the trigger */ |
83 | 83 | ||
84 | #define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) | 84 | #define B43_PHY_HT_RF_CTL_CMD 0x810 |
85 | #define B43_PHY_HT_RF_CTL_CMD_FORCE 0x0001 | ||
86 | #define B43_PHY_HT_RF_CTL_CMD_CHIP0_PU 0x0002 | ||
85 | 87 | ||
86 | #define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c) | 88 | #define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c) |
87 | #define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c) | 89 | #define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c) |
@@ -104,6 +106,9 @@ | |||
104 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 | 106 | #define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 |
105 | #define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169) | 107 | #define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169) |
106 | 108 | ||
109 | #define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001) | ||
110 | #define B43_PHY_B_BBCFG_RSTCCA 0x4000 /* Reset CCA */ | ||
111 | #define B43_PHY_B_BBCFG_RSTRX 0x8000 /* Reset RX */ | ||
107 | #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) | 112 | #define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) |
108 | 113 | ||
109 | 114 | ||
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index cf625d8732a7..9f0bcf3b8414 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c | |||
@@ -6369,7 +6369,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev, | |||
6369 | b43_mac_switch_freq(dev, spuravoid); | 6369 | b43_mac_switch_freq(dev, spuravoid); |
6370 | 6370 | ||
6371 | if (dev->phy.rev == 3 || dev->phy.rev == 4) | 6371 | if (dev->phy.rev == 3 || dev->phy.rev == 4) |
6372 | ; /* TODO: reset PLL */ | 6372 | b43_wireless_core_phy_pll_reset(dev); |
6373 | 6373 | ||
6374 | if (spuravoid) | 6374 | if (spuravoid) |
6375 | b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX); | 6375 | b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX); |
diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c index 38e31d857e3e..a3cf9efd7e21 100644 --- a/drivers/net/wireless/b43/radio_2059.c +++ b/drivers/net/wireless/b43/radio_2059.c | |||
@@ -25,6 +25,13 @@ | |||
25 | #include "b43.h" | 25 | #include "b43.h" |
26 | #include "radio_2059.h" | 26 | #include "radio_2059.h" |
27 | 27 | ||
28 | /* Extracted from MMIO dump of 6.30.223.141 */ | ||
29 | static u16 r2059_phy_rev1_init[][2] = { | ||
30 | { 0x051, 0x70 }, { 0x05a, 0x03 }, { 0x079, 0x01 }, { 0x082, 0x70 }, | ||
31 | { 0x083, 0x00 }, { 0x084, 0x70 }, { 0x09a, 0x7f }, { 0x0b6, 0x10 }, | ||
32 | { 0x188, 0x05 }, | ||
33 | }; | ||
34 | |||
28 | #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ | 35 | #define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ |
29 | r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ | 36 | r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ |
30 | r20) \ | 37 | r20) \ |
@@ -58,73 +65,87 @@ | |||
58 | .phy_regs.bw5 = r4, \ | 65 | .phy_regs.bw5 = r4, \ |
59 | .phy_regs.bw6 = r5 | 66 | .phy_regs.bw6 = r5 |
60 | 67 | ||
68 | /* Extracted from MMIO dump of 6.30.223.141 | ||
69 | * TODO: Values for channels 12 & 13 are outdated (from some old 5.x driver)! | ||
70 | */ | ||
61 | static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = { | 71 | static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = { |
62 | { .freq = 2412, | 72 | { |
63 | RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, | 73 | .freq = 2412, |
64 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, | 74 | RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, |
65 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 75 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, |
66 | PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), | 76 | 0x00, 0x00, 0x00, 0xd0, 0x00), |
67 | }, | 77 | PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), |
68 | { .freq = 2417, | 78 | }, |
69 | RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, | 79 | { |
70 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, | 80 | .freq = 2417, |
71 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 81 | RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, |
72 | PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), | 82 | 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73, |
73 | }, | 83 | 0x00, 0x00, 0x00, 0xd0, 0x00), |
74 | { .freq = 2422, | 84 | PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), |
75 | RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, | 85 | }, |
76 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, | 86 | { |
77 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 87 | .freq = 2422, |
78 | PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), | 88 | RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, |
79 | }, | 89 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, |
80 | { .freq = 2427, | 90 | 0x00, 0x00, 0x00, 0xd0, 0x00), |
81 | RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, | 91 | PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), |
82 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, | 92 | }, |
83 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 93 | { |
84 | PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), | 94 | .freq = 2427, |
85 | }, | 95 | RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, |
86 | { .freq = 2432, | 96 | 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73, |
87 | RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, | 97 | 0x00, 0x00, 0x00, 0xa0, 0x00), |
88 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, | 98 | PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), |
89 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 99 | }, |
90 | PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), | 100 | { |
91 | }, | 101 | .freq = 2432, |
92 | { .freq = 2437, | 102 | RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, |
93 | RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, | 103 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, |
94 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, | 104 | 0x00, 0x00, 0x00, 0xa0, 0x00), |
95 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 105 | PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), |
96 | PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), | 106 | }, |
97 | }, | 107 | { |
98 | { .freq = 2442, | 108 | .freq = 2437, |
99 | RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, | 109 | RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, |
100 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 110 | 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73, |
101 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 111 | 0x00, 0x00, 0x00, 0xa0, 0x00), |
102 | PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), | 112 | PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), |
103 | }, | 113 | }, |
104 | { .freq = 2447, | 114 | { |
105 | RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, | 115 | .freq = 2442, |
106 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 116 | RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, |
107 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 117 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, |
108 | PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), | 118 | 0x00, 0x00, 0x00, 0x80, 0x00), |
109 | }, | 119 | PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), |
110 | { .freq = 2452, | 120 | }, |
111 | RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, | 121 | { |
112 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, | 122 | .freq = 2447, |
113 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 123 | RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, |
114 | PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), | 124 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, |
115 | }, | 125 | 0x00, 0x00, 0x00, 0x80, 0x00), |
116 | { .freq = 2457, | 126 | PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), |
117 | RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, | 127 | }, |
118 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, | 128 | { |
119 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 129 | .freq = 2452, |
120 | PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), | 130 | RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, |
121 | }, | 131 | 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73, |
122 | { .freq = 2462, | 132 | 0x00, 0x00, 0x00, 0x80, 0x00), |
123 | RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, | 133 | PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), |
124 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, | 134 | }, |
125 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 135 | { |
126 | PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), | 136 | .freq = 2457, |
127 | }, | 137 | RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, |
138 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, | ||
139 | 0x00, 0x00, 0x00, 0x60, 0x00), | ||
140 | PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), | ||
141 | }, | ||
142 | { | ||
143 | .freq = 2462, | ||
144 | RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, | ||
145 | 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73, | ||
146 | 0x00, 0x00, 0x00, 0x60, 0x00), | ||
147 | PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), | ||
148 | }, | ||
128 | { .freq = 2467, | 149 | { .freq = 2467, |
129 | RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, | 150 | RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, |
130 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, | 151 | 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, |
@@ -137,8 +158,196 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi | |||
137 | 0x00, 0x00, 0x00, 0xf0, 0x00), | 158 | 0x00, 0x00, 0x00, 0xf0, 0x00), |
138 | PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), | 159 | PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), |
139 | }, | 160 | }, |
161 | { | ||
162 | .freq = 5180, | ||
163 | RADIOREGS(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06, | ||
164 | 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, | ||
165 | 0x0f, 0x4f, 0xa3, 0x00, 0xfc), | ||
166 | PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb), | ||
167 | }, | ||
168 | { | ||
169 | .freq = 5200, | ||
170 | RADIOREGS(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08, | ||
171 | 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, | ||
172 | 0x0f, 0x4f, 0x93, 0x00, 0xfb), | ||
173 | PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9), | ||
174 | }, | ||
175 | { | ||
176 | .freq = 5220, | ||
177 | RADIOREGS(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a, | ||
178 | 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, | ||
179 | 0x0f, 0x4f, 0x93, 0x00, 0xea), | ||
180 | PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7), | ||
181 | }, | ||
182 | { | ||
183 | .freq = 5240, | ||
184 | RADIOREGS(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c, | ||
185 | 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00, | ||
186 | 0x0f, 0x4f, 0x93, 0x00, 0xda), | ||
187 | PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5), | ||
188 | }, | ||
189 | { | ||
190 | .freq = 5260, | ||
191 | RADIOREGS(0xd9, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0e, | ||
192 | 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00, | ||
193 | 0x0f, 0x4f, 0x93, 0x00, 0xca), | ||
194 | PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3), | ||
195 | }, | ||
196 | { | ||
197 | .freq = 5280, | ||
198 | RADIOREGS(0xe0, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x10, | ||
199 | 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00, | ||
200 | 0x0f, 0x4f, 0x93, 0x00, 0xb9), | ||
201 | PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1), | ||
202 | }, | ||
203 | { | ||
204 | .freq = 5300, | ||
205 | RADIOREGS(0xe6, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x12, | ||
206 | 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00, | ||
207 | 0x0f, 0x4c, 0x83, 0x00, 0xb8), | ||
208 | PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0), | ||
209 | }, | ||
210 | { | ||
211 | .freq = 5320, | ||
212 | RADIOREGS(0xed, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x14, | ||
213 | 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00, | ||
214 | 0x0f, 0x4c, 0x83, 0x00, 0xa8), | ||
215 | PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee), | ||
216 | }, | ||
217 | { | ||
218 | .freq = 5500, | ||
219 | RADIOREGS(0x29, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x26, | ||
220 | 0x02, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00, | ||
221 | 0x0a, 0x46, 0x43, 0x00, 0x75), | ||
222 | PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd), | ||
223 | }, | ||
224 | { | ||
225 | .freq = 5520, | ||
226 | RADIOREGS(0x30, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x28, | ||
227 | 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, | ||
228 | 0x0a, 0x46, 0x43, 0x00, 0x75), | ||
229 | PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc), | ||
230 | }, | ||
231 | { | ||
232 | .freq = 5540, | ||
233 | RADIOREGS(0x36, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2a, | ||
234 | 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, | ||
235 | 0x0a, 0x46, 0x43, 0x00, 0x75), | ||
236 | PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da), | ||
237 | }, | ||
238 | { | ||
239 | .freq = 5560, | ||
240 | RADIOREGS(0x3d, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2c, | ||
241 | 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, | ||
242 | 0x0a, 0x46, 0x43, 0x00, 0x75), | ||
243 | PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8), | ||
244 | }, | ||
245 | { | ||
246 | .freq = 5580, | ||
247 | RADIOREGS(0x44, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2e, | ||
248 | 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, | ||
249 | 0x0a, 0x46, 0x43, 0x00, 0x74), | ||
250 | PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7), | ||
251 | }, | ||
252 | { | ||
253 | .freq = 5600, | ||
254 | RADIOREGS(0x4a, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x30, | ||
255 | 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, | ||
256 | 0x09, 0x44, 0x23, 0x00, 0x54), | ||
257 | PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5), | ||
258 | }, | ||
259 | { | ||
260 | .freq = 5620, | ||
261 | RADIOREGS(0x51, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x32, | ||
262 | 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||
263 | 0x09, 0x44, 0x23, 0x00, 0x54), | ||
264 | PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3), | ||
265 | }, | ||
266 | { | ||
267 | .freq = 5640, | ||
268 | RADIOREGS(0x58, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x34, | ||
269 | 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||
270 | 0x09, 0x44, 0x23, 0x00, 0x43), | ||
271 | PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2), | ||
272 | }, | ||
273 | { | ||
274 | .freq = 5660, | ||
275 | RADIOREGS(0x5e, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x36, | ||
276 | 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||
277 | 0x09, 0x43, 0x23, 0x00, 0x43), | ||
278 | PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0), | ||
279 | }, | ||
280 | { | ||
281 | .freq = 5680, | ||
282 | RADIOREGS(0x65, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x38, | ||
283 | 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||
284 | 0x09, 0x42, 0x23, 0x00, 0x43), | ||
285 | PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce), | ||
286 | }, | ||
287 | { | ||
288 | .freq = 5700, | ||
289 | RADIOREGS(0x6c, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x3a, | ||
290 | 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, | ||
291 | 0x08, 0x42, 0x13, 0x00, 0x32), | ||
292 | PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd), | ||
293 | }, | ||
294 | { | ||
295 | .freq = 5745, | ||
296 | RADIOREGS(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d, | ||
297 | 0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, | ||
298 | 0x08, 0x42, 0x13, 0x00, 0x21), | ||
299 | PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9), | ||
300 | }, | ||
301 | { | ||
302 | .freq = 5765, | ||
303 | RADIOREGS(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81, | ||
304 | 0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00, | ||
305 | 0x08, 0x42, 0x13, 0x00, 0x11), | ||
306 | PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8), | ||
307 | }, | ||
308 | { | ||
309 | .freq = 5785, | ||
310 | RADIOREGS(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85, | ||
311 | 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, | ||
312 | 0x08, 0x42, 0x13, 0x00, 0x00), | ||
313 | PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6), | ||
314 | }, | ||
315 | { | ||
316 | .freq = 5805, | ||
317 | RADIOREGS(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89, | ||
318 | 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, | ||
319 | 0x06, 0x41, 0x03, 0x00, 0x00), | ||
320 | PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4), | ||
321 | }, | ||
322 | { | ||
323 | .freq = 5825, | ||
324 | RADIOREGS(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d, | ||
325 | 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00, | ||
326 | 0x06, 0x41, 0x03, 0x00, 0x00), | ||
327 | PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3), | ||
328 | }, | ||
140 | }; | 329 | }; |
141 | 330 | ||
331 | void r2059_upload_inittabs(struct b43_wldev *dev) | ||
332 | { | ||
333 | struct b43_phy *phy = &dev->phy; | ||
334 | u16 *table = NULL; | ||
335 | u16 size, i; | ||
336 | |||
337 | switch (phy->rev) { | ||
338 | case 1: | ||
339 | table = r2059_phy_rev1_init[0]; | ||
340 | size = ARRAY_SIZE(r2059_phy_rev1_init); | ||
341 | break; | ||
342 | default: | ||
343 | B43_WARN_ON(1); | ||
344 | return; | ||
345 | } | ||
346 | |||
347 | for (i = 0; i < size; i++, table += 2) | ||
348 | b43_radio_write(dev, R2059_ALL | table[0], table[1]); | ||
349 | } | ||
350 | |||
142 | const struct b43_phy_ht_channeltab_e_radio2059 | 351 | const struct b43_phy_ht_channeltab_e_radio2059 |
143 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) | 352 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) |
144 | { | 353 | { |
diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h index 40a82d7f510c..9e22fb60588b 100644 --- a/drivers/net/wireless/b43/radio_2059.h +++ b/drivers/net/wireless/b43/radio_2059.h | |||
@@ -10,6 +10,18 @@ | |||
10 | #define R2059_C3 0x800 | 10 | #define R2059_C3 0x800 |
11 | #define R2059_ALL 0xC00 | 11 | #define R2059_ALL 0xC00 |
12 | 12 | ||
13 | #define R2059_RCAL_CONFIG 0x004 | ||
14 | #define R2059_RFPLL_MASTER 0x011 | ||
15 | #define R2059_RFPLL_MISC_EN 0x02b | ||
16 | #define R2059_RFPLL_MISC_CAL_RESETN 0x02e | ||
17 | #define R2059_XTAL_CONFIG2 0x0c0 | ||
18 | #define R2059_RCCAL_START_R1_Q1_P1 0x13c | ||
19 | #define R2059_RCCAL_X1 0x13d | ||
20 | #define R2059_RCCAL_TRC0 0x13e | ||
21 | #define R2059_RCCAL_DONE_OSCCAP 0x140 | ||
22 | #define R2059_RCAL_STATUS 0x145 | ||
23 | #define R2059_RCCAL_MASTER 0x17f | ||
24 | |||
13 | /* Values for various registers uploaded on channel switching */ | 25 | /* Values for various registers uploaded on channel switching */ |
14 | struct b43_phy_ht_channeltab_e_radio2059 { | 26 | struct b43_phy_ht_channeltab_e_radio2059 { |
15 | /* The channel frequency in MHz */ | 27 | /* The channel frequency in MHz */ |
@@ -40,6 +52,8 @@ struct b43_phy_ht_channeltab_e_radio2059 { | |||
40 | struct b43_phy_ht_channeltab_e_phy phy_regs; | 52 | struct b43_phy_ht_channeltab_e_phy phy_regs; |
41 | }; | 53 | }; |
42 | 54 | ||
55 | void r2059_upload_inittabs(struct b43_wldev *dev); | ||
56 | |||
43 | const struct b43_phy_ht_channeltab_e_radio2059 | 57 | const struct b43_phy_ht_channeltab_e_radio2059 |
44 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); | 58 | *b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); |
45 | 59 | ||
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h index 98d90747836a..ba6115308068 100644 --- a/drivers/net/wireless/b43/xmit.h +++ b/drivers/net/wireless/b43/xmit.h | |||
@@ -97,9 +97,13 @@ struct b43_tx_legacy_rate_phy_ctl_entry { | |||
97 | }; | 97 | }; |
98 | 98 | ||
99 | /* MAC TX control */ | 99 | /* MAC TX control */ |
100 | #define B43_TXH_MAC_RTS_FB_SHORTPRMBL 0x80000000 /* RTS fallback preamble */ | ||
101 | #define B43_TXH_MAC_RTS_SHORTPRMBL 0x40000000 /* RTS main rate preamble */ | ||
102 | #define B43_TXH_MAC_FB_SHORTPRMBL 0x20000000 /* Main fallback preamble */ | ||
100 | #define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ | 103 | #define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ |
101 | #define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ | 104 | #define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ |
102 | #define B43_TXH_MAC_KEYIDX_SHIFT 20 | 105 | #define B43_TXH_MAC_KEYIDX_SHIFT 20 |
106 | #define B43_TXH_MAC_ALT_TXPWR 0x00080000 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */ | ||
103 | #define B43_TXH_MAC_KEYALG 0x00070000 /* Security key algorithm */ | 107 | #define B43_TXH_MAC_KEYALG 0x00070000 /* Security key algorithm */ |
104 | #define B43_TXH_MAC_KEYALG_SHIFT 16 | 108 | #define B43_TXH_MAC_KEYALG_SHIFT 16 |
105 | #define B43_TXH_MAC_AMIC 0x00008000 /* AMIC */ | 109 | #define B43_TXH_MAC_AMIC 0x00008000 /* AMIC */ |
@@ -126,25 +130,25 @@ struct b43_tx_legacy_rate_phy_ctl_entry { | |||
126 | #define B43_TXH_EFT_FB 0x03 /* Data frame fallback encoding */ | 130 | #define B43_TXH_EFT_FB 0x03 /* Data frame fallback encoding */ |
127 | #define B43_TXH_EFT_FB_CCK 0x00 /* CCK */ | 131 | #define B43_TXH_EFT_FB_CCK 0x00 /* CCK */ |
128 | #define B43_TXH_EFT_FB_OFDM 0x01 /* OFDM */ | 132 | #define B43_TXH_EFT_FB_OFDM 0x01 /* OFDM */ |
129 | #define B43_TXH_EFT_FB_EWC 0x02 /* EWC */ | 133 | #define B43_TXH_EFT_FB_HT 0x02 /* HT */ |
130 | #define B43_TXH_EFT_FB_N 0x03 /* N */ | 134 | #define B43_TXH_EFT_FB_VHT 0x03 /* VHT */ |
131 | #define B43_TXH_EFT_RTS 0x0C /* RTS/CTS encoding */ | 135 | #define B43_TXH_EFT_RTS 0x0C /* RTS/CTS encoding */ |
132 | #define B43_TXH_EFT_RTS_CCK 0x00 /* CCK */ | 136 | #define B43_TXH_EFT_RTS_CCK 0x00 /* CCK */ |
133 | #define B43_TXH_EFT_RTS_OFDM 0x04 /* OFDM */ | 137 | #define B43_TXH_EFT_RTS_OFDM 0x04 /* OFDM */ |
134 | #define B43_TXH_EFT_RTS_EWC 0x08 /* EWC */ | 138 | #define B43_TXH_EFT_RTS_HT 0x08 /* HT */ |
135 | #define B43_TXH_EFT_RTS_N 0x0C /* N */ | 139 | #define B43_TXH_EFT_RTS_VHT 0x0C /* VHT */ |
136 | #define B43_TXH_EFT_RTSFB 0x30 /* RTS/CTS fallback encoding */ | 140 | #define B43_TXH_EFT_RTSFB 0x30 /* RTS/CTS fallback encoding */ |
137 | #define B43_TXH_EFT_RTSFB_CCK 0x00 /* CCK */ | 141 | #define B43_TXH_EFT_RTSFB_CCK 0x00 /* CCK */ |
138 | #define B43_TXH_EFT_RTSFB_OFDM 0x10 /* OFDM */ | 142 | #define B43_TXH_EFT_RTSFB_OFDM 0x10 /* OFDM */ |
139 | #define B43_TXH_EFT_RTSFB_EWC 0x20 /* EWC */ | 143 | #define B43_TXH_EFT_RTSFB_HT 0x20 /* HT */ |
140 | #define B43_TXH_EFT_RTSFB_N 0x30 /* N */ | 144 | #define B43_TXH_EFT_RTSFB_VHT 0x30 /* VHT */ |
141 | 145 | ||
142 | /* PHY TX control word */ | 146 | /* PHY TX control word */ |
143 | #define B43_TXH_PHY_ENC 0x0003 /* Data frame encoding */ | 147 | #define B43_TXH_PHY_ENC 0x0003 /* Data frame encoding */ |
144 | #define B43_TXH_PHY_ENC_CCK 0x0000 /* CCK */ | 148 | #define B43_TXH_PHY_ENC_CCK 0x0000 /* CCK */ |
145 | #define B43_TXH_PHY_ENC_OFDM 0x0001 /* OFDM */ | 149 | #define B43_TXH_PHY_ENC_OFDM 0x0001 /* OFDM */ |
146 | #define B43_TXH_PHY_ENC_EWC 0x0002 /* EWC */ | 150 | #define B43_TXH_PHY_ENC_HT 0x0002 /* HT */ |
147 | #define B43_TXH_PHY_ENC_N 0x0003 /* N */ | 151 | #define B43_TXH_PHY_ENC_VHT 0x0003 /* VHT */ |
148 | #define B43_TXH_PHY_SHORTPRMBL 0x0010 /* Use short preamble */ | 152 | #define B43_TXH_PHY_SHORTPRMBL 0x0010 /* Use short preamble */ |
149 | #define B43_TXH_PHY_ANT 0x03C0 /* Antenna selection */ | 153 | #define B43_TXH_PHY_ANT 0x03C0 /* Antenna selection */ |
150 | #define B43_TXH_PHY_ANT0 0x0000 /* Use antenna 0 */ | 154 | #define B43_TXH_PHY_ANT0 0x0000 /* Use antenna 0 */ |
@@ -162,7 +166,7 @@ struct b43_tx_legacy_rate_phy_ctl_entry { | |||
162 | #define B43_TXH_PHY1_BW_20 0x0002 /* 20 MHz */ | 166 | #define B43_TXH_PHY1_BW_20 0x0002 /* 20 MHz */ |
163 | #define B43_TXH_PHY1_BW_20U 0x0003 /* 20 MHz upper */ | 167 | #define B43_TXH_PHY1_BW_20U 0x0003 /* 20 MHz upper */ |
164 | #define B43_TXH_PHY1_BW_40 0x0004 /* 40 MHz */ | 168 | #define B43_TXH_PHY1_BW_40 0x0004 /* 40 MHz */ |
165 | #define B43_TXH_PHY1_BW_40DUP 0x0005 /* 50 MHz duplicate */ | 169 | #define B43_TXH_PHY1_BW_40DUP 0x0005 /* 40 MHz duplicate */ |
166 | #define B43_TXH_PHY1_MODE 0x0038 /* Mode */ | 170 | #define B43_TXH_PHY1_MODE 0x0038 /* Mode */ |
167 | #define B43_TXH_PHY1_MODE_SISO 0x0000 /* SISO */ | 171 | #define B43_TXH_PHY1_MODE_SISO 0x0000 /* SISO */ |
168 | #define B43_TXH_PHY1_MODE_CDD 0x0008 /* CDD */ | 172 | #define B43_TXH_PHY1_MODE_CDD 0x0008 /* CDD */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 4fb9635d3919..796f5f9d5d5a 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -746,7 +746,7 @@ dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring, | |||
746 | /* !! may be called with core in reset */ | 746 | /* !! may be called with core in reset */ |
747 | void dma_detach(struct dma_pub *pub) | 747 | void dma_detach(struct dma_pub *pub) |
748 | { | 748 | { |
749 | struct dma_info *di = (struct dma_info *)pub; | 749 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
750 | 750 | ||
751 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 751 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
752 | 752 | ||
@@ -842,7 +842,7 @@ static void _dma_rxenable(struct dma_info *di) | |||
842 | 842 | ||
843 | void dma_rxinit(struct dma_pub *pub) | 843 | void dma_rxinit(struct dma_pub *pub) |
844 | { | 844 | { |
845 | struct dma_info *di = (struct dma_info *)pub; | 845 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
846 | 846 | ||
847 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 847 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
848 | 848 | ||
@@ -924,7 +924,7 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) | |||
924 | */ | 924 | */ |
925 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | 925 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) |
926 | { | 926 | { |
927 | struct dma_info *di = (struct dma_info *)pub; | 927 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
928 | struct sk_buff_head dma_frames; | 928 | struct sk_buff_head dma_frames; |
929 | struct sk_buff *p, *next; | 929 | struct sk_buff *p, *next; |
930 | uint len; | 930 | uint len; |
@@ -1022,7 +1022,7 @@ static bool dma64_txidle(struct dma_info *di) | |||
1022 | */ | 1022 | */ |
1023 | bool dma_rxfill(struct dma_pub *pub) | 1023 | bool dma_rxfill(struct dma_pub *pub) |
1024 | { | 1024 | { |
1025 | struct dma_info *di = (struct dma_info *)pub; | 1025 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1026 | struct sk_buff *p; | 1026 | struct sk_buff *p; |
1027 | u16 rxin, rxout; | 1027 | u16 rxin, rxout; |
1028 | u32 flags = 0; | 1028 | u32 flags = 0; |
@@ -1106,7 +1106,7 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1106 | 1106 | ||
1107 | void dma_rxreclaim(struct dma_pub *pub) | 1107 | void dma_rxreclaim(struct dma_pub *pub) |
1108 | { | 1108 | { |
1109 | struct dma_info *di = (struct dma_info *)pub; | 1109 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1110 | struct sk_buff *p; | 1110 | struct sk_buff *p; |
1111 | 1111 | ||
1112 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 1112 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
@@ -1126,7 +1126,7 @@ void dma_counterreset(struct dma_pub *pub) | |||
1126 | /* get the address of the var in order to change later */ | 1126 | /* get the address of the var in order to change later */ |
1127 | unsigned long dma_getvar(struct dma_pub *pub, const char *name) | 1127 | unsigned long dma_getvar(struct dma_pub *pub, const char *name) |
1128 | { | 1128 | { |
1129 | struct dma_info *di = (struct dma_info *)pub; | 1129 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1130 | 1130 | ||
1131 | if (!strcmp(name, "&txavail")) | 1131 | if (!strcmp(name, "&txavail")) |
1132 | return (unsigned long)&(di->dma.txavail); | 1132 | return (unsigned long)&(di->dma.txavail); |
@@ -1137,7 +1137,7 @@ unsigned long dma_getvar(struct dma_pub *pub, const char *name) | |||
1137 | 1137 | ||
1138 | void dma_txinit(struct dma_pub *pub) | 1138 | void dma_txinit(struct dma_pub *pub) |
1139 | { | 1139 | { |
1140 | struct dma_info *di = (struct dma_info *)pub; | 1140 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1141 | u32 control = D64_XC_XE; | 1141 | u32 control = D64_XC_XE; |
1142 | 1142 | ||
1143 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 1143 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
@@ -1170,7 +1170,7 @@ void dma_txinit(struct dma_pub *pub) | |||
1170 | 1170 | ||
1171 | void dma_txsuspend(struct dma_pub *pub) | 1171 | void dma_txsuspend(struct dma_pub *pub) |
1172 | { | 1172 | { |
1173 | struct dma_info *di = (struct dma_info *)pub; | 1173 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1174 | 1174 | ||
1175 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 1175 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1176 | 1176 | ||
@@ -1182,7 +1182,7 @@ void dma_txsuspend(struct dma_pub *pub) | |||
1182 | 1182 | ||
1183 | void dma_txresume(struct dma_pub *pub) | 1183 | void dma_txresume(struct dma_pub *pub) |
1184 | { | 1184 | { |
1185 | struct dma_info *di = (struct dma_info *)pub; | 1185 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1186 | 1186 | ||
1187 | brcms_dbg_dma(di->core, "%s:\n", di->name); | 1187 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1188 | 1188 | ||
@@ -1194,7 +1194,7 @@ void dma_txresume(struct dma_pub *pub) | |||
1194 | 1194 | ||
1195 | bool dma_txsuspended(struct dma_pub *pub) | 1195 | bool dma_txsuspended(struct dma_pub *pub) |
1196 | { | 1196 | { |
1197 | struct dma_info *di = (struct dma_info *)pub; | 1197 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1198 | 1198 | ||
1199 | return (di->ntxd == 0) || | 1199 | return (di->ntxd == 0) || |
1200 | ((bcma_read32(di->core, | 1200 | ((bcma_read32(di->core, |
@@ -1204,7 +1204,7 @@ bool dma_txsuspended(struct dma_pub *pub) | |||
1204 | 1204 | ||
1205 | void dma_txreclaim(struct dma_pub *pub, enum txd_range range) | 1205 | void dma_txreclaim(struct dma_pub *pub, enum txd_range range) |
1206 | { | 1206 | { |
1207 | struct dma_info *di = (struct dma_info *)pub; | 1207 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1208 | struct sk_buff *p; | 1208 | struct sk_buff *p; |
1209 | 1209 | ||
1210 | brcms_dbg_dma(di->core, "%s: %s\n", | 1210 | brcms_dbg_dma(di->core, "%s: %s\n", |
@@ -1225,7 +1225,7 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) | |||
1225 | 1225 | ||
1226 | bool dma_txreset(struct dma_pub *pub) | 1226 | bool dma_txreset(struct dma_pub *pub) |
1227 | { | 1227 | { |
1228 | struct dma_info *di = (struct dma_info *)pub; | 1228 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1229 | u32 status; | 1229 | u32 status; |
1230 | 1230 | ||
1231 | if (di->ntxd == 0) | 1231 | if (di->ntxd == 0) |
@@ -1252,7 +1252,7 @@ bool dma_txreset(struct dma_pub *pub) | |||
1252 | 1252 | ||
1253 | bool dma_rxreset(struct dma_pub *pub) | 1253 | bool dma_rxreset(struct dma_pub *pub) |
1254 | { | 1254 | { |
1255 | struct dma_info *di = (struct dma_info *)pub; | 1255 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1256 | u32 status; | 1256 | u32 status; |
1257 | 1257 | ||
1258 | if (di->nrxd == 0) | 1258 | if (di->nrxd == 0) |
@@ -1377,7 +1377,7 @@ static void dma_update_txavail(struct dma_info *di) | |||
1377 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, | 1377 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, |
1378 | struct sk_buff *p) | 1378 | struct sk_buff *p) |
1379 | { | 1379 | { |
1380 | struct dma_info *di = (struct dma_info *)pub; | 1380 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1381 | struct brcms_ampdu_session *session = &di->ampdu_session; | 1381 | struct brcms_ampdu_session *session = &di->ampdu_session; |
1382 | struct ieee80211_tx_info *tx_info; | 1382 | struct ieee80211_tx_info *tx_info; |
1383 | bool is_ampdu; | 1383 | bool is_ampdu; |
@@ -1427,7 +1427,7 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, | |||
1427 | 1427 | ||
1428 | void dma_txflush(struct dma_pub *pub) | 1428 | void dma_txflush(struct dma_pub *pub) |
1429 | { | 1429 | { |
1430 | struct dma_info *di = (struct dma_info *)pub; | 1430 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1431 | struct brcms_ampdu_session *session = &di->ampdu_session; | 1431 | struct brcms_ampdu_session *session = &di->ampdu_session; |
1432 | 1432 | ||
1433 | if (!skb_queue_empty(&session->skb_list)) | 1433 | if (!skb_queue_empty(&session->skb_list)) |
@@ -1436,7 +1436,7 @@ void dma_txflush(struct dma_pub *pub) | |||
1436 | 1436 | ||
1437 | int dma_txpending(struct dma_pub *pub) | 1437 | int dma_txpending(struct dma_pub *pub) |
1438 | { | 1438 | { |
1439 | struct dma_info *di = (struct dma_info *)pub; | 1439 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1440 | return ntxdactive(di, di->txin, di->txout); | 1440 | return ntxdactive(di, di->txin, di->txout); |
1441 | } | 1441 | } |
1442 | 1442 | ||
@@ -1446,7 +1446,7 @@ int dma_txpending(struct dma_pub *pub) | |||
1446 | */ | 1446 | */ |
1447 | void dma_kick_tx(struct dma_pub *pub) | 1447 | void dma_kick_tx(struct dma_pub *pub) |
1448 | { | 1448 | { |
1449 | struct dma_info *di = (struct dma_info *)pub; | 1449 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1450 | struct brcms_ampdu_session *session = &di->ampdu_session; | 1450 | struct brcms_ampdu_session *session = &di->ampdu_session; |
1451 | 1451 | ||
1452 | if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) | 1452 | if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) |
@@ -1465,7 +1465,7 @@ void dma_kick_tx(struct dma_pub *pub) | |||
1465 | */ | 1465 | */ |
1466 | struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | 1466 | struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) |
1467 | { | 1467 | { |
1468 | struct dma_info *di = (struct dma_info *)pub; | 1468 | struct dma_info *di = container_of(pub, struct dma_info, dma); |
1469 | u16 start, end, i; | 1469 | u16 start, end, i; |
1470 | u16 active_desc; | 1470 | u16 active_desc; |
1471 | struct sk_buff *txp; | 1471 | struct sk_buff *txp; |
@@ -1547,7 +1547,7 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | |||
1547 | void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) | 1547 | void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) |
1548 | (void *pkt, void *arg_a), void *arg_a) | 1548 | (void *pkt, void *arg_a), void *arg_a) |
1549 | { | 1549 | { |
1550 | struct dma_info *di = (struct dma_info *) dmah; | 1550 | struct dma_info *di = container_of(dmah, struct dma_info, dma); |
1551 | uint i = di->txin; | 1551 | uint i = di->txin; |
1552 | uint end = di->txout; | 1552 | uint end = di->txout; |
1553 | struct sk_buff *skb; | 1553 | struct sk_buff *skb; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c index 57ecc05802e9..941b1e41f366 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c | |||
@@ -128,19 +128,19 @@ static const u8 ofdm_rate_lookup[] = { | |||
128 | 128 | ||
129 | void wlc_phyreg_enter(struct brcms_phy_pub *pih) | 129 | void wlc_phyreg_enter(struct brcms_phy_pub *pih) |
130 | { | 130 | { |
131 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 131 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
132 | wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); | 132 | wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); |
133 | } | 133 | } |
134 | 134 | ||
135 | void wlc_phyreg_exit(struct brcms_phy_pub *pih) | 135 | void wlc_phyreg_exit(struct brcms_phy_pub *pih) |
136 | { | 136 | { |
137 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 137 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
138 | wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); | 138 | wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); |
139 | } | 139 | } |
140 | 140 | ||
141 | void wlc_radioreg_enter(struct brcms_phy_pub *pih) | 141 | void wlc_radioreg_enter(struct brcms_phy_pub *pih) |
142 | { | 142 | { |
143 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 143 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
144 | wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); | 144 | wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); |
145 | 145 | ||
146 | udelay(10); | 146 | udelay(10); |
@@ -148,7 +148,7 @@ void wlc_radioreg_enter(struct brcms_phy_pub *pih) | |||
148 | 148 | ||
149 | void wlc_radioreg_exit(struct brcms_phy_pub *pih) | 149 | void wlc_radioreg_exit(struct brcms_phy_pub *pih) |
150 | { | 150 | { |
151 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 151 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
152 | 152 | ||
153 | (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion)); | 153 | (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion)); |
154 | pi->phy_wreg = 0; | 154 | pi->phy_wreg = 0; |
@@ -586,7 +586,7 @@ err: | |||
586 | 586 | ||
587 | void wlc_phy_detach(struct brcms_phy_pub *pih) | 587 | void wlc_phy_detach(struct brcms_phy_pub *pih) |
588 | { | 588 | { |
589 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 589 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
590 | 590 | ||
591 | if (pih) { | 591 | if (pih) { |
592 | if (--pi->refcnt) | 592 | if (--pi->refcnt) |
@@ -613,7 +613,7 @@ bool | |||
613 | wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev, | 613 | wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev, |
614 | u16 *radioid, u16 *radiover) | 614 | u16 *radioid, u16 *radiover) |
615 | { | 615 | { |
616 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 616 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
617 | *phytype = (u16) pi->pubpi.phy_type; | 617 | *phytype = (u16) pi->pubpi.phy_type; |
618 | *phyrev = (u16) pi->pubpi.phy_rev; | 618 | *phyrev = (u16) pi->pubpi.phy_rev; |
619 | *radioid = pi->pubpi.radioid; | 619 | *radioid = pi->pubpi.radioid; |
@@ -624,19 +624,19 @@ wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev, | |||
624 | 624 | ||
625 | bool wlc_phy_get_encore(struct brcms_phy_pub *pih) | 625 | bool wlc_phy_get_encore(struct brcms_phy_pub *pih) |
626 | { | 626 | { |
627 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 627 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
628 | return pi->pubpi.abgphy_encore; | 628 | return pi->pubpi.abgphy_encore; |
629 | } | 629 | } |
630 | 630 | ||
631 | u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih) | 631 | u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih) |
632 | { | 632 | { |
633 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 633 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
634 | return pi->pubpi.coreflags; | 634 | return pi->pubpi.coreflags; |
635 | } | 635 | } |
636 | 636 | ||
637 | void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) | 637 | void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) |
638 | { | 638 | { |
639 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 639 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
640 | 640 | ||
641 | if (ISNPHY(pi)) { | 641 | if (ISNPHY(pi)) { |
642 | if (on) { | 642 | if (on) { |
@@ -673,7 +673,7 @@ void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) | |||
673 | 673 | ||
674 | u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih) | 674 | u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih) |
675 | { | 675 | { |
676 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 676 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
677 | 677 | ||
678 | u32 phy_bw_clkbits = 0; | 678 | u32 phy_bw_clkbits = 0; |
679 | 679 | ||
@@ -698,14 +698,14 @@ u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih) | |||
698 | 698 | ||
699 | void wlc_phy_por_inform(struct brcms_phy_pub *ppi) | 699 | void wlc_phy_por_inform(struct brcms_phy_pub *ppi) |
700 | { | 700 | { |
701 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 701 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
702 | 702 | ||
703 | pi->phy_init_por = true; | 703 | pi->phy_init_por = true; |
704 | } | 704 | } |
705 | 705 | ||
706 | void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock) | 706 | void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock) |
707 | { | 707 | { |
708 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 708 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
709 | 709 | ||
710 | pi->edcrs_threshold_lock = lock; | 710 | pi->edcrs_threshold_lock = lock; |
711 | 711 | ||
@@ -717,14 +717,14 @@ void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock) | |||
717 | 717 | ||
718 | void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal) | 718 | void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal) |
719 | { | 719 | { |
720 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 720 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
721 | 721 | ||
722 | pi->do_initcal = initcal; | 722 | pi->do_initcal = initcal; |
723 | } | 723 | } |
724 | 724 | ||
725 | void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate) | 725 | void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate) |
726 | { | 726 | { |
727 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 727 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
728 | 728 | ||
729 | if (!pi || !pi->sh) | 729 | if (!pi || !pi->sh) |
730 | return; | 730 | return; |
@@ -734,7 +734,7 @@ void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate) | |||
734 | 734 | ||
735 | void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate) | 735 | void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate) |
736 | { | 736 | { |
737 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 737 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
738 | 738 | ||
739 | if (!pi || !pi->sh) | 739 | if (!pi || !pi->sh) |
740 | return; | 740 | return; |
@@ -746,7 +746,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec) | |||
746 | { | 746 | { |
747 | u32 mc; | 747 | u32 mc; |
748 | void (*phy_init)(struct brcms_phy *) = NULL; | 748 | void (*phy_init)(struct brcms_phy *) = NULL; |
749 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 749 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
750 | 750 | ||
751 | if (pi->init_in_progress) | 751 | if (pi->init_in_progress) |
752 | return; | 752 | return; |
@@ -798,7 +798,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec) | |||
798 | 798 | ||
799 | void wlc_phy_cal_init(struct brcms_phy_pub *pih) | 799 | void wlc_phy_cal_init(struct brcms_phy_pub *pih) |
800 | { | 800 | { |
801 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 801 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
802 | void (*cal_init)(struct brcms_phy *) = NULL; | 802 | void (*cal_init)(struct brcms_phy *) = NULL; |
803 | 803 | ||
804 | if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & | 804 | if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & |
@@ -816,7 +816,7 @@ void wlc_phy_cal_init(struct brcms_phy_pub *pih) | |||
816 | 816 | ||
817 | int wlc_phy_down(struct brcms_phy_pub *pih) | 817 | int wlc_phy_down(struct brcms_phy_pub *pih) |
818 | { | 818 | { |
819 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 819 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
820 | int callbacks = 0; | 820 | int callbacks = 0; |
821 | 821 | ||
822 | if (pi->phycal_timer | 822 | if (pi->phycal_timer |
@@ -1070,7 +1070,7 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) | |||
1070 | 1070 | ||
1071 | void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set) | 1071 | void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set) |
1072 | { | 1072 | { |
1073 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1073 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1074 | 1074 | ||
1075 | if (set) | 1075 | if (set) |
1076 | mboolset(pi->measure_hold, id); | 1076 | mboolset(pi->measure_hold, id); |
@@ -1082,7 +1082,7 @@ void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set) | |||
1082 | 1082 | ||
1083 | void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags) | 1083 | void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags) |
1084 | { | 1084 | { |
1085 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1085 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1086 | 1086 | ||
1087 | if (mute) | 1087 | if (mute) |
1088 | mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); | 1088 | mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); |
@@ -1096,7 +1096,7 @@ void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags) | |||
1096 | 1096 | ||
1097 | void wlc_phy_clear_tssi(struct brcms_phy_pub *pih) | 1097 | void wlc_phy_clear_tssi(struct brcms_phy_pub *pih) |
1098 | { | 1098 | { |
1099 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1099 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1100 | 1100 | ||
1101 | if (ISNPHY(pi)) { | 1101 | if (ISNPHY(pi)) { |
1102 | return; | 1102 | return; |
@@ -1115,7 +1115,7 @@ static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi) | |||
1115 | 1115 | ||
1116 | void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) | 1116 | void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) |
1117 | { | 1117 | { |
1118 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1118 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1119 | (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); | 1119 | (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); |
1120 | 1120 | ||
1121 | if (ISNPHY(pi)) { | 1121 | if (ISNPHY(pi)) { |
@@ -1149,35 +1149,35 @@ void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) | |||
1149 | 1149 | ||
1150 | u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi) | 1150 | u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi) |
1151 | { | 1151 | { |
1152 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1152 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1153 | 1153 | ||
1154 | return pi->bw; | 1154 | return pi->bw; |
1155 | } | 1155 | } |
1156 | 1156 | ||
1157 | void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw) | 1157 | void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw) |
1158 | { | 1158 | { |
1159 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1159 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1160 | 1160 | ||
1161 | pi->bw = bw; | 1161 | pi->bw = bw; |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch) | 1164 | void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch) |
1165 | { | 1165 | { |
1166 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1166 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1167 | pi->radio_chanspec = newch; | 1167 | pi->radio_chanspec = newch; |
1168 | 1168 | ||
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) | 1171 | u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) |
1172 | { | 1172 | { |
1173 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1173 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1174 | 1174 | ||
1175 | return pi->radio_chanspec; | 1175 | return pi->radio_chanspec; |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec) | 1178 | void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec) |
1179 | { | 1179 | { |
1180 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1180 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1181 | u16 m_cur_channel; | 1181 | u16 m_cur_channel; |
1182 | void (*chanspec_set)(struct brcms_phy *, u16) = NULL; | 1182 | void (*chanspec_set)(struct brcms_phy *, u16) = NULL; |
1183 | m_cur_channel = CHSPEC_CHANNEL(chanspec); | 1183 | m_cur_channel = CHSPEC_CHANNEL(chanspec); |
@@ -1226,7 +1226,7 @@ int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec) | |||
1226 | void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, | 1226 | void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, |
1227 | bool wide_filter) | 1227 | bool wide_filter) |
1228 | { | 1228 | { |
1229 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1229 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1230 | 1230 | ||
1231 | pi->channel_14_wide_filter = wide_filter; | 1231 | pi->channel_14_wide_filter = wide_filter; |
1232 | 1232 | ||
@@ -1246,7 +1246,7 @@ void | |||
1246 | wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, | 1246 | wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, |
1247 | struct brcms_chanvec *channels) | 1247 | struct brcms_chanvec *channels) |
1248 | { | 1248 | { |
1249 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1249 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1250 | uint i; | 1250 | uint i; |
1251 | uint channel; | 1251 | uint channel; |
1252 | 1252 | ||
@@ -1267,7 +1267,7 @@ wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, | |||
1267 | 1267 | ||
1268 | u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) | 1268 | u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) |
1269 | { | 1269 | { |
1270 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1270 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1271 | uint i; | 1271 | uint i; |
1272 | uint channel; | 1272 | uint channel; |
1273 | u16 chspec; | 1273 | u16 chspec; |
@@ -1311,7 +1311,7 @@ u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) | |||
1311 | 1311 | ||
1312 | int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override) | 1312 | int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override) |
1313 | { | 1313 | { |
1314 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1314 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1315 | 1315 | ||
1316 | *qdbm = pi->tx_user_target[0]; | 1316 | *qdbm = pi->tx_user_target[0]; |
1317 | if (override != NULL) | 1317 | if (override != NULL) |
@@ -1323,7 +1323,7 @@ void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, | |||
1323 | struct txpwr_limits *txpwr) | 1323 | struct txpwr_limits *txpwr) |
1324 | { | 1324 | { |
1325 | bool mac_enabled = false; | 1325 | bool mac_enabled = false; |
1326 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1326 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1327 | 1327 | ||
1328 | memcpy(&pi->tx_user_target[TXP_FIRST_CCK], | 1328 | memcpy(&pi->tx_user_target[TXP_FIRST_CCK], |
1329 | &txpwr->cck[0], BRCMS_NUM_RATES_CCK); | 1329 | &txpwr->cck[0], BRCMS_NUM_RATES_CCK); |
@@ -1371,7 +1371,7 @@ void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi, | |||
1371 | 1371 | ||
1372 | int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override) | 1372 | int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override) |
1373 | { | 1373 | { |
1374 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1374 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1375 | int i; | 1375 | int i; |
1376 | 1376 | ||
1377 | if (qdbm > 127) | 1377 | if (qdbm > 127) |
@@ -1407,7 +1407,7 @@ void | |||
1407 | wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr, | 1407 | wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr, |
1408 | u8 *max_pwr, int txp_rate_idx) | 1408 | u8 *max_pwr, int txp_rate_idx) |
1409 | { | 1409 | { |
1410 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1410 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1411 | uint i; | 1411 | uint i; |
1412 | 1412 | ||
1413 | *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR; | 1413 | *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR; |
@@ -1456,7 +1456,7 @@ void | |||
1456 | wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, | 1456 | wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, |
1457 | u8 *max_txpwr, u8 *min_txpwr) | 1457 | u8 *max_txpwr, u8 *min_txpwr) |
1458 | { | 1458 | { |
1459 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1459 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1460 | u8 tx_pwr_max = 0; | 1460 | u8 tx_pwr_max = 0; |
1461 | u8 tx_pwr_min = 255; | 1461 | u8 tx_pwr_min = 255; |
1462 | u8 max_num_rate; | 1462 | u8 max_num_rate; |
@@ -1493,14 +1493,14 @@ wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit, | |||
1493 | 1493 | ||
1494 | u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi) | 1494 | u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi) |
1495 | { | 1495 | { |
1496 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1496 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1497 | 1497 | ||
1498 | return pi->tx_power_min; | 1498 | return pi->tx_power_min; |
1499 | } | 1499 | } |
1500 | 1500 | ||
1501 | u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi) | 1501 | u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi) |
1502 | { | 1502 | { |
1503 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1503 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1504 | 1504 | ||
1505 | return pi->tx_power_max; | 1505 | return pi->tx_power_max; |
1506 | } | 1506 | } |
@@ -1812,21 +1812,21 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, | |||
1812 | 1812 | ||
1813 | void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent) | 1813 | void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent) |
1814 | { | 1814 | { |
1815 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1815 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1816 | 1816 | ||
1817 | pi->txpwr_percent = txpwr_percent; | 1817 | pi->txpwr_percent = txpwr_percent; |
1818 | } | 1818 | } |
1819 | 1819 | ||
1820 | void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap) | 1820 | void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap) |
1821 | { | 1821 | { |
1822 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1822 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1823 | 1823 | ||
1824 | pi->sh->machwcap = machwcap; | 1824 | pi->sh->machwcap = machwcap; |
1825 | } | 1825 | } |
1826 | 1826 | ||
1827 | void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end) | 1827 | void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end) |
1828 | { | 1828 | { |
1829 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1829 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1830 | u16 rxc; | 1830 | u16 rxc; |
1831 | rxc = 0; | 1831 | rxc = 0; |
1832 | 1832 | ||
@@ -1857,7 +1857,7 @@ void | |||
1857 | wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, | 1857 | wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, |
1858 | u16 chanspec) | 1858 | u16 chanspec) |
1859 | { | 1859 | { |
1860 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1860 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1861 | 1861 | ||
1862 | wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); | 1862 | wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); |
1863 | 1863 | ||
@@ -1881,14 +1881,14 @@ wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, | |||
1881 | 1881 | ||
1882 | void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war) | 1882 | void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war) |
1883 | { | 1883 | { |
1884 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1884 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1885 | 1885 | ||
1886 | pi->ofdm_rateset_war = war; | 1886 | pi->ofdm_rateset_war = war; |
1887 | } | 1887 | } |
1888 | 1888 | ||
1889 | void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt) | 1889 | void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt) |
1890 | { | 1890 | { |
1891 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 1891 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
1892 | 1892 | ||
1893 | pi->bf_preempt_4306 = bf_preempt; | 1893 | pi->bf_preempt_4306 = bf_preempt; |
1894 | } | 1894 | } |
@@ -1945,7 +1945,7 @@ void wlc_phy_txpower_update_shm(struct brcms_phy *pi) | |||
1945 | 1945 | ||
1946 | bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) | 1946 | bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) |
1947 | { | 1947 | { |
1948 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1948 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1949 | 1949 | ||
1950 | if (ISNPHY(pi)) | 1950 | if (ISNPHY(pi)) |
1951 | return pi->nphy_txpwrctrl; | 1951 | return pi->nphy_txpwrctrl; |
@@ -1955,7 +1955,7 @@ bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) | |||
1955 | 1955 | ||
1956 | void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl) | 1956 | void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl) |
1957 | { | 1957 | { |
1958 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 1958 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
1959 | bool suspend; | 1959 | bool suspend; |
1960 | 1960 | ||
1961 | if (!pi->hwpwrctrl_capable) | 1961 | if (!pi->hwpwrctrl_capable) |
@@ -2038,7 +2038,7 @@ void | |||
2038 | wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, | 2038 | wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, |
2039 | uint channel) | 2039 | uint channel) |
2040 | { | 2040 | { |
2041 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2041 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2042 | uint rate, num_rates; | 2042 | uint rate, num_rates; |
2043 | u8 min_pwr, max_pwr; | 2043 | u8 min_pwr, max_pwr; |
2044 | 2044 | ||
@@ -2136,21 +2136,21 @@ wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, | |||
2136 | 2136 | ||
2137 | void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type) | 2137 | void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type) |
2138 | { | 2138 | { |
2139 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2139 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2140 | 2140 | ||
2141 | pi->antsel_type = antsel_type; | 2141 | pi->antsel_type = antsel_type; |
2142 | } | 2142 | } |
2143 | 2143 | ||
2144 | bool wlc_phy_test_ison(struct brcms_phy_pub *ppi) | 2144 | bool wlc_phy_test_ison(struct brcms_phy_pub *ppi) |
2145 | { | 2145 | { |
2146 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2146 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2147 | 2147 | ||
2148 | return pi->phytest_on; | 2148 | return pi->phytest_on; |
2149 | } | 2149 | } |
2150 | 2150 | ||
2151 | void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val) | 2151 | void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val) |
2152 | { | 2152 | { |
2153 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2153 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2154 | bool suspend; | 2154 | bool suspend; |
2155 | 2155 | ||
2156 | pi->sh->rx_antdiv = val; | 2156 | pi->sh->rx_antdiv = val; |
@@ -2283,7 +2283,7 @@ static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi) | |||
2283 | 2283 | ||
2284 | void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) | 2284 | void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) |
2285 | { | 2285 | { |
2286 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2286 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2287 | u16 jssi_aux; | 2287 | u16 jssi_aux; |
2288 | u8 channel = 0; | 2288 | u8 channel = 0; |
2289 | s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; | 2289 | s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; |
@@ -2339,7 +2339,7 @@ void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) | |||
2339 | static void | 2339 | static void |
2340 | wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) | 2340 | wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) |
2341 | { | 2341 | { |
2342 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2342 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2343 | s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; | 2343 | s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; |
2344 | bool sampling_in_progress = (pi->phynoise_state != 0); | 2344 | bool sampling_in_progress = (pi->phynoise_state != 0); |
2345 | bool wait_for_intr = true; | 2345 | bool wait_for_intr = true; |
@@ -2531,7 +2531,7 @@ int wlc_phy_rssi_compute(struct brcms_phy_pub *pih, | |||
2531 | { | 2531 | { |
2532 | int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK; | 2532 | int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK; |
2533 | uint radioid = pih->radioid; | 2533 | uint radioid = pih->radioid; |
2534 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2534 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2535 | 2535 | ||
2536 | if ((pi->sh->corerev >= 11) | 2536 | if ((pi->sh->corerev >= 11) |
2537 | && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) { | 2537 | && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) { |
@@ -2591,7 +2591,7 @@ void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag) | |||
2591 | 2591 | ||
2592 | void wlc_phy_watchdog(struct brcms_phy_pub *pih) | 2592 | void wlc_phy_watchdog(struct brcms_phy_pub *pih) |
2593 | { | 2593 | { |
2594 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2594 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2595 | bool delay_phy_cal = false; | 2595 | bool delay_phy_cal = false; |
2596 | pi->sh->now++; | 2596 | pi->sh->now++; |
2597 | 2597 | ||
@@ -2651,7 +2651,7 @@ void wlc_phy_watchdog(struct brcms_phy_pub *pih) | |||
2651 | 2651 | ||
2652 | void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi) | 2652 | void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi) |
2653 | { | 2653 | { |
2654 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2654 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2655 | uint i; | 2655 | uint i; |
2656 | uint k; | 2656 | uint k; |
2657 | 2657 | ||
@@ -2711,7 +2711,7 @@ void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason) | |||
2711 | s16 nphy_currtemp = 0; | 2711 | s16 nphy_currtemp = 0; |
2712 | s16 delta_temp = 0; | 2712 | s16 delta_temp = 0; |
2713 | bool do_periodic_cal = true; | 2713 | bool do_periodic_cal = true; |
2714 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2714 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2715 | 2715 | ||
2716 | if (!ISNPHY(pi)) | 2716 | if (!ISNPHY(pi)) |
2717 | return; | 2717 | return; |
@@ -2804,7 +2804,7 @@ u8 wlc_phy_nbits(s32 value) | |||
2804 | 2804 | ||
2805 | void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) | 2805 | void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) |
2806 | { | 2806 | { |
2807 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2807 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2808 | 2808 | ||
2809 | pi->sh->hw_phytxchain = txchain; | 2809 | pi->sh->hw_phytxchain = txchain; |
2810 | pi->sh->hw_phyrxchain = rxchain; | 2810 | pi->sh->hw_phyrxchain = rxchain; |
@@ -2815,7 +2815,7 @@ void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) | |||
2815 | 2815 | ||
2816 | void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) | 2816 | void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) |
2817 | { | 2817 | { |
2818 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2818 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2819 | 2819 | ||
2820 | pi->sh->phytxchain = txchain; | 2820 | pi->sh->phytxchain = txchain; |
2821 | 2821 | ||
@@ -2827,7 +2827,7 @@ void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) | |||
2827 | 2827 | ||
2828 | void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain) | 2828 | void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain) |
2829 | { | 2829 | { |
2830 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2830 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2831 | 2831 | ||
2832 | *txchain = pi->sh->phytxchain; | 2832 | *txchain = pi->sh->phytxchain; |
2833 | *rxchain = pi->sh->phyrxchain; | 2833 | *rxchain = pi->sh->phyrxchain; |
@@ -2837,7 +2837,7 @@ u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih) | |||
2837 | { | 2837 | { |
2838 | s16 nphy_currtemp; | 2838 | s16 nphy_currtemp; |
2839 | u8 active_bitmap; | 2839 | u8 active_bitmap; |
2840 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2840 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2841 | 2841 | ||
2842 | active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; | 2842 | active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; |
2843 | 2843 | ||
@@ -2867,7 +2867,7 @@ u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih) | |||
2867 | 2867 | ||
2868 | s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec) | 2868 | s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec) |
2869 | { | 2869 | { |
2870 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 2870 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
2871 | u8 siso_mcs_id, cdd_mcs_id; | 2871 | u8 siso_mcs_id, cdd_mcs_id; |
2872 | 2872 | ||
2873 | siso_mcs_id = | 2873 | siso_mcs_id = |
@@ -2944,7 +2944,7 @@ s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec) | |||
2944 | 2944 | ||
2945 | bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi) | 2945 | bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi) |
2946 | { | 2946 | { |
2947 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2947 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2948 | 2948 | ||
2949 | if (ISNPHY(pi)) | 2949 | if (ISNPHY(pi)) |
2950 | return wlc_phy_n_txpower_ipa_ison(pi); | 2950 | return wlc_phy_n_txpower_ipa_ison(pi); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c index b2d6d6da3daf..5f1366234a0d 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c | |||
@@ -2865,7 +2865,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) | |||
2865 | { | 2865 | { |
2866 | bool suspend, tx_gain_override_old; | 2866 | bool suspend, tx_gain_override_old; |
2867 | struct lcnphy_txgains old_gains; | 2867 | struct lcnphy_txgains old_gains; |
2868 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 2868 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
2869 | u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, | 2869 | u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, |
2870 | idleTssi0_regvalue_2C; | 2870 | idleTssi0_regvalue_2C; |
2871 | u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); | 2871 | u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); |
@@ -3084,7 +3084,7 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) | |||
3084 | s32 a1, b0, b1; | 3084 | s32 a1, b0, b1; |
3085 | s32 tssi, pwr, maxtargetpwr, mintargetpwr; | 3085 | s32 tssi, pwr, maxtargetpwr, mintargetpwr; |
3086 | bool suspend; | 3086 | bool suspend; |
3087 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 3087 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
3088 | 3088 | ||
3089 | suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & | 3089 | suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & |
3090 | MCTL_EN_MAC)); | 3090 | MCTL_EN_MAC)); |
@@ -4348,7 +4348,7 @@ void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi) | |||
4348 | { | 4348 | { |
4349 | s8 index; | 4349 | s8 index; |
4350 | u16 index2; | 4350 | u16 index2; |
4351 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 4351 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
4352 | struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; | 4352 | struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; |
4353 | u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); | 4353 | u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); |
4354 | if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && | 4354 | if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index 93869e89aa3d..084f18f4f950 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c | |||
@@ -14121,7 +14121,7 @@ static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = { | |||
14121 | 14121 | ||
14122 | bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) | 14122 | bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) |
14123 | { | 14123 | { |
14124 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 14124 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
14125 | u32 phybist0, phybist1, phybist2, phybist3, phybist4; | 14125 | u32 phybist0, phybist1, phybist2, phybist3, phybist4; |
14126 | 14126 | ||
14127 | if (NREV_GE(pi->pubpi.phy_rev, 16)) | 14127 | if (NREV_GE(pi->pubpi.phy_rev, 16)) |
@@ -19734,7 +19734,7 @@ void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask) | |||
19734 | u16 regval; | 19734 | u16 regval; |
19735 | u16 tbl_buf[16]; | 19735 | u16 tbl_buf[16]; |
19736 | uint i; | 19736 | uint i; |
19737 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 19737 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
19738 | u16 tbl_opcode; | 19738 | u16 tbl_opcode; |
19739 | bool suspend; | 19739 | bool suspend; |
19740 | 19740 | ||
@@ -19812,7 +19812,7 @@ void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask) | |||
19812 | u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) | 19812 | u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) |
19813 | { | 19813 | { |
19814 | u16 regval, rxen_bits; | 19814 | u16 regval, rxen_bits; |
19815 | struct brcms_phy *pi = (struct brcms_phy *) pih; | 19815 | struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro); |
19816 | 19816 | ||
19817 | regval = read_phy_reg(pi, 0xa2); | 19817 | regval = read_phy_reg(pi, 0xa2); |
19818 | rxen_bits = (regval >> 4) & 0xf; | 19818 | rxen_bits = (regval >> 4) & 0xf; |
@@ -21342,7 +21342,7 @@ void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec) | |||
21342 | 21342 | ||
21343 | void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) | 21343 | void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) |
21344 | { | 21344 | { |
21345 | struct brcms_phy *pi = (struct brcms_phy *) ppi; | 21345 | struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro); |
21346 | u16 mask = 0xfc00; | 21346 | u16 mask = 0xfc00; |
21347 | u32 mc = 0; | 21347 | u32 mc = 0; |
21348 | 21348 | ||
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c index 4e5c0f8c9496..8efd17c52f65 100644 --- a/drivers/net/wireless/hostap/hostap_proc.c +++ b/drivers/net/wireless/hostap/hostap_proc.c | |||
@@ -186,11 +186,9 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v) | |||
186 | bss->ssid[i] : '_'); | 186 | bss->ssid[i] : '_'); |
187 | 187 | ||
188 | seq_putc(m, '\t'); | 188 | seq_putc(m, '\t'); |
189 | for (i = 0; i < bss->ssid_len; i++) | 189 | seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid); |
190 | seq_printf(m, "%02x", bss->ssid[i]); | ||
191 | seq_putc(m, '\t'); | 190 | seq_putc(m, '\t'); |
192 | for (i = 0; i < bss->wpa_ie_len; i++) | 191 | seq_printf(m, "%*phN", (int)bss->wpa_ie_len, bss->wpa_ie); |
193 | seq_printf(m, "%02x", bss->wpa_ie[i]); | ||
194 | seq_putc(m, '\n'); | 192 | seq_putc(m, '\n'); |
195 | return 0; | 193 | return 0; |
196 | } | 194 | } |
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c index 3dcbe2cd2b28..26fec54dcd03 100644 --- a/drivers/net/wireless/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/iwlegacy/4965-mac.c | |||
@@ -4633,7 +4633,7 @@ il4965_store_tx_power(struct device *d, struct device_attribute *attr, | |||
4633 | else { | 4633 | else { |
4634 | ret = il_set_tx_power(il, val, false); | 4634 | ret = il_set_tx_power(il, val, false); |
4635 | if (ret) | 4635 | if (ret) |
4636 | IL_ERR("failed setting tx power (0x%d).\n", ret); | 4636 | IL_ERR("failed setting tx power (0x%08x).\n", ret); |
4637 | else | 4637 | else |
4638 | ret = count; | 4638 | ret = count; |
4639 | } | 4639 | } |
@@ -5757,9 +5757,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length) | |||
5757 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | | 5757 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | |
5758 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; | 5758 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS; |
5759 | if (il->cfg->sku & IL_SKU_N) | 5759 | if (il->cfg->sku & IL_SKU_N) |
5760 | hw->flags |= | 5760 | hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS | |
5761 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 5761 | NL80211_FEATURE_STATIC_SMPS; |
5762 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
5763 | 5762 | ||
5764 | hw->sta_data_size = sizeof(struct il_station_priv); | 5763 | hw->sta_data_size = sizeof(struct il_station_priv); |
5765 | hw->vif_data_size = sizeof(struct il_vif_priv); | 5764 | hw->vif_data_size = sizeof(struct il_vif_priv); |
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index afb98f4fdaf3..2364a3c09b9e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -125,8 +125,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, | |||
125 | */ | 125 | */ |
126 | 126 | ||
127 | if (priv->nvm_data->sku_cap_11n_enable) | 127 | if (priv->nvm_data->sku_cap_11n_enable) |
128 | hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | 128 | hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS | |
129 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | 129 | NL80211_FEATURE_STATIC_SMPS; |
130 | 130 | ||
131 | /* | 131 | /* |
132 | * Enable 11w if advertised by firmware and software crypto | 132 | * Enable 11w if advertised by firmware and software crypto |
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c index 8e99dffa88e8..b04b8858c690 100644 --- a/drivers/net/wireless/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/iwlwifi/iwl-7000.c | |||
@@ -131,7 +131,8 @@ static const struct iwl_ht_params iwl7000_ht_params = { | |||
131 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 131 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
132 | .base_params = &iwl7000_base_params, \ | 132 | .base_params = &iwl7000_base_params, \ |
133 | .led_mode = IWL_LED_RF_STATE, \ | 133 | .led_mode = IWL_LED_RF_STATE, \ |
134 | .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000 | 134 | .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \ |
135 | .non_shared_ant = ANT_A | ||
135 | 136 | ||
136 | 137 | ||
137 | const struct iwl_cfg iwl7260_2ac_cfg = { | 138 | const struct iwl_cfg iwl7260_2ac_cfg = { |
@@ -220,6 +221,12 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = { | |||
220 | {0}, | 221 | {0}, |
221 | }; | 222 | }; |
222 | 223 | ||
224 | static const struct iwl_ht_params iwl7265_ht_params = { | ||
225 | .stbc = true, | ||
226 | .ldpc = true, | ||
227 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | ||
228 | }; | ||
229 | |||
223 | const struct iwl_cfg iwl3165_2ac_cfg = { | 230 | const struct iwl_cfg iwl3165_2ac_cfg = { |
224 | .name = "Intel(R) Dual Band Wireless AC 3165", | 231 | .name = "Intel(R) Dual Band Wireless AC 3165", |
225 | .fw_name_pre = IWL3165_FW_PRE, | 232 | .fw_name_pre = IWL3165_FW_PRE, |
@@ -234,7 +241,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = { | |||
234 | .name = "Intel(R) Dual Band Wireless AC 7265", | 241 | .name = "Intel(R) Dual Band Wireless AC 7265", |
235 | .fw_name_pre = IWL7265_FW_PRE, | 242 | .fw_name_pre = IWL7265_FW_PRE, |
236 | IWL_DEVICE_7000, | 243 | IWL_DEVICE_7000, |
237 | .ht_params = &iwl7000_ht_params, | 244 | .ht_params = &iwl7265_ht_params, |
238 | .nvm_ver = IWL7265_NVM_VERSION, | 245 | .nvm_ver = IWL7265_NVM_VERSION, |
239 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 246 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
240 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 247 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
@@ -244,7 +251,7 @@ const struct iwl_cfg iwl7265_2n_cfg = { | |||
244 | .name = "Intel(R) Dual Band Wireless N 7265", | 251 | .name = "Intel(R) Dual Band Wireless N 7265", |
245 | .fw_name_pre = IWL7265_FW_PRE, | 252 | .fw_name_pre = IWL7265_FW_PRE, |
246 | IWL_DEVICE_7000, | 253 | IWL_DEVICE_7000, |
247 | .ht_params = &iwl7000_ht_params, | 254 | .ht_params = &iwl7265_ht_params, |
248 | .nvm_ver = IWL7265_NVM_VERSION, | 255 | .nvm_ver = IWL7265_NVM_VERSION, |
249 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 256 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
250 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 257 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
@@ -254,7 +261,7 @@ const struct iwl_cfg iwl7265_n_cfg = { | |||
254 | .name = "Intel(R) Wireless N 7265", | 261 | .name = "Intel(R) Wireless N 7265", |
255 | .fw_name_pre = IWL7265_FW_PRE, | 262 | .fw_name_pre = IWL7265_FW_PRE, |
256 | IWL_DEVICE_7000, | 263 | IWL_DEVICE_7000, |
257 | .ht_params = &iwl7000_ht_params, | 264 | .ht_params = &iwl7265_ht_params, |
258 | .nvm_ver = IWL7265_NVM_VERSION, | 265 | .nvm_ver = IWL7265_NVM_VERSION, |
259 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, | 266 | .nvm_calib_ver = IWL7265_TX_POWER_VERSION, |
260 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, | 267 | .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c index 23a67bfc086f..4ae8ba6ccfff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/iwlwifi/iwl-8000.c | |||
@@ -103,6 +103,7 @@ static const struct iwl_base_params iwl8000_base_params = { | |||
103 | }; | 103 | }; |
104 | 104 | ||
105 | static const struct iwl_ht_params iwl8000_ht_params = { | 105 | static const struct iwl_ht_params iwl8000_ht_params = { |
106 | .ldpc = true, | ||
106 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), | 107 | .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), |
107 | }; | 108 | }; |
108 | 109 | ||
@@ -115,7 +116,17 @@ static const struct iwl_ht_params iwl8000_ht_params = { | |||
115 | .max_data_size = IWL60_RTC_DATA_SIZE, \ | 116 | .max_data_size = IWL60_RTC_DATA_SIZE, \ |
116 | .base_params = &iwl8000_base_params, \ | 117 | .base_params = &iwl8000_base_params, \ |
117 | .led_mode = IWL_LED_RF_STATE, \ | 118 | .led_mode = IWL_LED_RF_STATE, \ |
118 | .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000 | 119 | .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \ |
120 | .non_shared_ant = ANT_A | ||
121 | |||
122 | const struct iwl_cfg iwl8260_2n_cfg = { | ||
123 | .name = "Intel(R) Dual Band Wireless N 8260", | ||
124 | .fw_name_pre = IWL8000_FW_PRE, | ||
125 | IWL_DEVICE_8000, | ||
126 | .ht_params = &iwl8000_ht_params, | ||
127 | .nvm_ver = IWL8000_NVM_VERSION, | ||
128 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, | ||
129 | }; | ||
119 | 130 | ||
120 | const struct iwl_cfg iwl8260_2ac_cfg = { | 131 | const struct iwl_cfg iwl8260_2ac_cfg = { |
121 | .name = "Intel(R) Dual Band Wireless AC 8260", | 132 | .name = "Intel(R) Dual Band Wireless AC 8260", |
@@ -135,6 +146,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = { | |||
135 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, | 146 | .nvm_calib_ver = IWL8000_TX_POWER_VERSION, |
136 | .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, | 147 | .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, |
137 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, | 148 | .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, |
149 | .disable_dummy_notification = true, | ||
138 | }; | 150 | }; |
139 | 151 | ||
140 | MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK)); | 152 | MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h index 3d7cc37420ae..2ef83a39ff10 100644 --- a/drivers/net/wireless/iwlwifi/iwl-config.h +++ b/drivers/net/wireless/iwlwifi/iwl-config.h | |||
@@ -171,6 +171,7 @@ struct iwl_base_params { | |||
171 | 171 | ||
172 | /* | 172 | /* |
173 | * @stbc: support Tx STBC and 1*SS Rx STBC | 173 | * @stbc: support Tx STBC and 1*SS Rx STBC |
174 | * @ldpc: support Tx/Rx with LDPC | ||
174 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic | 175 | * @use_rts_for_aggregation: use rts/cts protection for HT traffic |
175 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 | 176 | * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 |
176 | */ | 177 | */ |
@@ -178,6 +179,7 @@ struct iwl_ht_params { | |||
178 | enum ieee80211_smps_mode smps_mode; | 179 | enum ieee80211_smps_mode smps_mode; |
179 | const bool ht_greenfield_support; /* if used set to true */ | 180 | const bool ht_greenfield_support; /* if used set to true */ |
180 | const bool stbc; | 181 | const bool stbc; |
182 | const bool ldpc; | ||
181 | bool use_rts_for_aggregation; | 183 | bool use_rts_for_aggregation; |
182 | u8 ht40_bands; | 184 | u8 ht40_bands; |
183 | }; | 185 | }; |
@@ -228,6 +230,7 @@ struct iwl_pwr_tx_backoff { | |||
228 | * @max_data_size: The maximal length of the fw data section | 230 | * @max_data_size: The maximal length of the fw data section |
229 | * @valid_tx_ant: valid transmit antenna | 231 | * @valid_tx_ant: valid transmit antenna |
230 | * @valid_rx_ant: valid receive antenna | 232 | * @valid_rx_ant: valid receive antenna |
233 | * @non_shared_ant: the antenna that is for WiFi only | ||
231 | * @nvm_ver: NVM version | 234 | * @nvm_ver: NVM version |
232 | * @nvm_calib_ver: NVM calibration version | 235 | * @nvm_calib_ver: NVM calibration version |
233 | * @lib: pointer to the lib ops | 236 | * @lib: pointer to the lib ops |
@@ -260,6 +263,7 @@ struct iwl_cfg { | |||
260 | const u32 max_inst_size; | 263 | const u32 max_inst_size; |
261 | u8 valid_tx_ant; | 264 | u8 valid_tx_ant; |
262 | u8 valid_rx_ant; | 265 | u8 valid_rx_ant; |
266 | u8 non_shared_ant; | ||
263 | bool bt_shared_single_ant; | 267 | bool bt_shared_single_ant; |
264 | u16 nvm_ver; | 268 | u16 nvm_ver; |
265 | u16 nvm_calib_ver; | 269 | u16 nvm_calib_ver; |
@@ -280,6 +284,7 @@ struct iwl_cfg { | |||
280 | bool no_power_up_nic_in_init; | 284 | bool no_power_up_nic_in_init; |
281 | const char *default_nvm_file; | 285 | const char *default_nvm_file; |
282 | unsigned int max_rx_agg_size; | 286 | unsigned int max_rx_agg_size; |
287 | bool disable_dummy_notification; | ||
283 | }; | 288 | }; |
284 | 289 | ||
285 | /* | 290 | /* |
@@ -341,6 +346,7 @@ extern const struct iwl_cfg iwl3165_2ac_cfg; | |||
341 | extern const struct iwl_cfg iwl7265_2ac_cfg; | 346 | extern const struct iwl_cfg iwl7265_2ac_cfg; |
342 | extern const struct iwl_cfg iwl7265_2n_cfg; | 347 | extern const struct iwl_cfg iwl7265_2n_cfg; |
343 | extern const struct iwl_cfg iwl7265_n_cfg; | 348 | extern const struct iwl_cfg iwl7265_n_cfg; |
349 | extern const struct iwl_cfg iwl8260_2n_cfg; | ||
344 | extern const struct iwl_cfg iwl8260_2ac_cfg; | 350 | extern const struct iwl_cfg iwl8260_2ac_cfg; |
345 | extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; | 351 | extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; |
346 | #endif /* CONFIG_IWLMVM */ | 352 | #endif /* CONFIG_IWLMVM */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 23d059af6476..3f6f015285e5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h | |||
@@ -295,6 +295,16 @@ | |||
295 | #define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) | 295 | #define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) |
296 | #define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) | 296 | #define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) |
297 | 297 | ||
298 | |||
299 | /** | ||
300 | * hw_rev values | ||
301 | */ | ||
302 | enum { | ||
303 | SILICON_A_STEP = 0, | ||
304 | SILICON_B_STEP, | ||
305 | }; | ||
306 | |||
307 | |||
298 | #define CSR_HW_REV_TYPE_MSK (0x000FFF0) | 308 | #define CSR_HW_REV_TYPE_MSK (0x000FFF0) |
299 | #define CSR_HW_REV_TYPE_5300 (0x0000020) | 309 | #define CSR_HW_REV_TYPE_5300 (0x0000020) |
300 | #define CSR_HW_REV_TYPE_5350 (0x0000030) | 310 | #define CSR_HW_REV_TYPE_5350 (0x0000030) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index aefd94cb6e91..ed673baedfd7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c | |||
@@ -1363,7 +1363,7 @@ MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)") | |||
1363 | module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, | 1363 | module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, |
1364 | int, S_IRUGO); | 1364 | int, S_IRUGO); |
1365 | MODULE_PARM_DESC(antenna_coupling, | 1365 | MODULE_PARM_DESC(antenna_coupling, |
1366 | "specify antenna coupling in dB (defualt: 0 dB)"); | 1366 | "specify antenna coupling in dB (default: 0 dB)"); |
1367 | 1367 | ||
1368 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); | 1368 | module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); |
1369 | MODULE_PARM_DESC(wd_disable, | 1369 | MODULE_PARM_DESC(wd_disable, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c index 07ff7e0028ee..74b796dc4242 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c | |||
@@ -758,6 +758,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, | |||
758 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | 758 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; |
759 | } | 759 | } |
760 | 760 | ||
761 | if (cfg->ht_params->ldpc) | ||
762 | ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
763 | |||
761 | if (iwlwifi_mod_params.amsdu_size_8K) | 764 | if (iwlwifi_mod_params.amsdu_size_8K) |
762 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | 765 | ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; |
763 | 766 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h index f68cba4e0444..62c46eb8b99c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/iwlwifi/iwl-fw.h | |||
@@ -127,6 +127,7 @@ enum iwl_ucode_tlv_flag { | |||
127 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. | 127 | * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. |
128 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. | 128 | * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. |
129 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. | 129 | * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. |
130 | * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif. | ||
130 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time | 131 | * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time |
131 | * longer than the passive one, which is essential for fragmented scan. | 132 | * longer than the passive one, which is essential for fragmented scan. |
132 | */ | 133 | */ |
@@ -137,6 +138,7 @@ enum iwl_ucode_tlv_api { | |||
137 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), | 138 | IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), |
138 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), | 139 | IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), |
139 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), | 140 | IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), |
141 | IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7), | ||
140 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), | 142 | IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), |
141 | }; | 143 | }; |
142 | 144 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 5eef4ae7333b..7a2cbf6f90db 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c | |||
@@ -193,7 +193,7 @@ void iwl_force_nmi(struct iwl_trans *trans) | |||
193 | * DEVICE_SET_NMI_8000B_REG - is used. | 193 | * DEVICE_SET_NMI_8000B_REG - is used. |
194 | */ | 194 | */ |
195 | if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || | 195 | if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || |
196 | ((trans->hw_rev & 0xc) == 0x0)) | 196 | (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP)) |
197 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL); | 197 | iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL); |
198 | else | 198 | else |
199 | iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, | 199 | iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c index 40718f814f8d..c302e7468559 100644 --- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c | |||
@@ -334,6 +334,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg, | |||
334 | 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | | 334 | 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | |
335 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; | 335 | 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; |
336 | 336 | ||
337 | if (cfg->ht_params->ldpc) | ||
338 | vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC; | ||
339 | |||
337 | if (num_tx_ants > 1) | 340 | if (num_tx_ants > 1) |
338 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; | 341 | vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; |
339 | else | 342 | else |
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index c89985a58803..9eb85249e89c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h | |||
@@ -377,6 +377,7 @@ enum iwl_trans_status { | |||
377 | * if unset 4k will be the RX buffer size | 377 | * if unset 4k will be the RX buffer size |
378 | * @bc_table_dword: set to true if the BC table expects the byte count to be | 378 | * @bc_table_dword: set to true if the BC table expects the byte count to be |
379 | * in DWORD (as opposed to bytes) | 379 | * in DWORD (as opposed to bytes) |
380 | * @scd_set_active: should the transport configure the SCD for HCMD queue | ||
380 | * @queue_watchdog_timeout: time (in ms) after which queues | 381 | * @queue_watchdog_timeout: time (in ms) after which queues |
381 | * are considered stuck and will trigger device restart | 382 | * are considered stuck and will trigger device restart |
382 | * @command_names: array of command names, must be 256 entries | 383 | * @command_names: array of command names, must be 256 entries |
@@ -392,6 +393,7 @@ struct iwl_trans_config { | |||
392 | 393 | ||
393 | bool rx_buf_size_8k; | 394 | bool rx_buf_size_8k; |
394 | bool bc_table_dword; | 395 | bool bc_table_dword; |
396 | bool scd_set_active; | ||
395 | unsigned int queue_watchdog_timeout; | 397 | unsigned int queue_watchdog_timeout; |
396 | const char *const *command_names; | 398 | const char *const *command_names; |
397 | }; | 399 | }; |
@@ -826,12 +828,6 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, | |||
826 | iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); | 828 | iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); |
827 | } | 829 | } |
828 | 830 | ||
829 | static inline void | ||
830 | iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn) | ||
831 | { | ||
832 | iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL); | ||
833 | } | ||
834 | |||
835 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, | 831 | static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, |
836 | u32 txq_bm) | 832 | u32 txq_bm) |
837 | { | 833 | { |
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile index a28235913c2c..2d7c3ea3c4f8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/Makefile +++ b/drivers/net/wireless/iwlwifi/mvm/Makefile | |||
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o | |||
3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o | 3 | iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o |
4 | iwlmvm-y += scan.o time-event.o rs.o | 4 | iwlmvm-y += scan.o time-event.o rs.o |
5 | iwlmvm-y += power.o coex.o coex_legacy.o | 5 | iwlmvm-y += power.o coex.o coex_legacy.o |
6 | iwlmvm-y += tt.o offloading.o | 6 | iwlmvm-y += tt.o offloading.o tdls.o |
7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o | 7 | iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o |
8 | iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o | 8 | iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o |
9 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o | 9 | iwlmvm-$(CONFIG_PM_SLEEP) += d3.o |
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c index 6e8f3e2aef74..8df2021f9856 100644 --- a/drivers/net/wireless/iwlwifi/mvm/coex.c +++ b/drivers/net/wireless/iwlwifi/mvm/coex.c | |||
@@ -1146,6 +1146,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm, | |||
1146 | 1146 | ||
1147 | bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm) | 1147 | bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm) |
1148 | { | 1148 | { |
1149 | /* there is no other antenna, shared antenna is always available */ | ||
1150 | if (mvm->cfg->bt_shared_single_ant) | ||
1151 | return true; | ||
1152 | |||
1149 | if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) | 1153 | if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) |
1150 | return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm); | 1154 | return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm); |
1151 | 1155 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h index dd00e8f7f765..a355788b1166 100644 --- a/drivers/net/wireless/iwlwifi/mvm/constants.h +++ b/drivers/net/wireless/iwlwifi/mvm/constants.h | |||
@@ -65,12 +65,18 @@ | |||
65 | #ifndef __MVM_CONSTANTS_H | 65 | #ifndef __MVM_CONSTANTS_H |
66 | #define __MVM_CONSTANTS_H | 66 | #define __MVM_CONSTANTS_H |
67 | 67 | ||
68 | #include <linux/ieee80211.h> | ||
69 | |||
68 | #define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC) | 70 | #define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC) |
69 | #define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) | 71 | #define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) |
70 | #define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) | 72 | #define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) |
71 | #define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) | 73 | #define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) |
72 | #define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) | 74 | #define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) |
73 | #define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) | 75 | #define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) |
76 | #define IWL_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ | ||
77 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ | ||
78 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ | ||
79 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) | ||
74 | #define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 | 80 | #define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 |
75 | #define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 | 81 | #define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 |
76 | #define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 | 82 | #define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 |
@@ -86,5 +92,7 @@ | |||
86 | #define IWL_MVM_BT_COEX_SYNC2SCO 1 | 92 | #define IWL_MVM_BT_COEX_SYNC2SCO 1 |
87 | #define IWL_MVM_BT_COEX_CORUNNING 1 | 93 | #define IWL_MVM_BT_COEX_CORUNNING 1 |
88 | #define IWL_MVM_BT_COEX_MPLUT 1 | 94 | #define IWL_MVM_BT_COEX_MPLUT 1 |
95 | #define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0 | ||
96 | #define IWL_MVM_QUOTA_THRESHOLD 8 | ||
89 | 97 | ||
90 | #endif /* __MVM_CONSTANTS_H */ | 98 | #endif /* __MVM_CONSTANTS_H */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c index d98ee109c5e9..95eb9a5ef693 100644 --- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c | |||
@@ -288,6 +288,9 @@ static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm, | |||
288 | { | 288 | { |
289 | int temperature; | 289 | int temperature; |
290 | 290 | ||
291 | if (!mvm->ucode_loaded && !mvm->temperature_test) | ||
292 | return -EIO; | ||
293 | |||
291 | if (kstrtoint(buf, 10, &temperature)) | 294 | if (kstrtoint(buf, 10, &temperature)) |
292 | return -EINVAL; | 295 | return -EINVAL; |
293 | /* not a legal temperature */ | 296 | /* not a legal temperature */ |
@@ -1256,6 +1259,18 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file, | |||
1256 | PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); | 1259 | PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); |
1257 | PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); | 1260 | PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); |
1258 | PRINT_MVM_REF(IWL_MVM_REF_USER); | 1261 | PRINT_MVM_REF(IWL_MVM_REF_USER); |
1262 | PRINT_MVM_REF(IWL_MVM_REF_TX); | ||
1263 | PRINT_MVM_REF(IWL_MVM_REF_TX_AGG); | ||
1264 | PRINT_MVM_REF(IWL_MVM_REF_ADD_IF); | ||
1265 | PRINT_MVM_REF(IWL_MVM_REF_START_AP); | ||
1266 | PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED); | ||
1267 | PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX); | ||
1268 | PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS); | ||
1269 | PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL); | ||
1270 | PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ); | ||
1271 | PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE); | ||
1272 | PRINT_MVM_REF(IWL_MVM_REF_NMI); | ||
1273 | PRINT_MVM_REF(IWL_MVM_REF_TM_CMD); | ||
1259 | PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); | 1274 | PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); |
1260 | 1275 | ||
1261 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); | 1276 | return simple_read_from_buffer(user_buf, count, ppos, buf, pos); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h index 541b844c6b5d..a2c662808a88 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h | |||
@@ -205,6 +205,10 @@ enum { | |||
205 | REPLY_SF_CFG_CMD = 0xd1, | 205 | REPLY_SF_CFG_CMD = 0xd1, |
206 | REPLY_BEACON_FILTERING_CMD = 0xd2, | 206 | REPLY_BEACON_FILTERING_CMD = 0xd2, |
207 | 207 | ||
208 | /* DTS measurements */ | ||
209 | CMD_DTS_MEASUREMENT_TRIGGER = 0xdc, | ||
210 | DTS_MEASUREMENT_NOTIFICATION = 0xdd, | ||
211 | |||
208 | REPLY_DEBUG_CMD = 0xf0, | 212 | REPLY_DEBUG_CMD = 0xf0, |
209 | DEBUG_LOG_MSG = 0xf7, | 213 | DEBUG_LOG_MSG = 0xf7, |
210 | 214 | ||
@@ -550,7 +554,7 @@ enum iwl_time_event_type { | |||
550 | TE_WIDI_TX_SYNC, | 554 | TE_WIDI_TX_SYNC, |
551 | 555 | ||
552 | /* Channel Switch NoA */ | 556 | /* Channel Switch NoA */ |
553 | TE_P2P_GO_CSA_NOA, | 557 | TE_CHANNEL_SWITCH_PERIOD, |
554 | 558 | ||
555 | TE_MAX | 559 | TE_MAX |
556 | }; /* MAC_EVENT_TYPE_API_E_VER_1 */ | 560 | }; /* MAC_EVENT_TYPE_API_E_VER_1 */ |
@@ -1601,6 +1605,8 @@ enum iwl_sf_scenario { | |||
1601 | 1605 | ||
1602 | #define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */ | 1606 | #define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */ |
1603 | 1607 | ||
1608 | #define SF_CFG_DUMMY_NOTIF_OFF BIT(16) | ||
1609 | |||
1604 | /** | 1610 | /** |
1605 | * Smart Fifo configuration command. | 1611 | * Smart Fifo configuration command. |
1606 | * @state: smart fifo state, types listed in enum %iwl_sf_sate. | 1612 | * @state: smart fifo state, types listed in enum %iwl_sf_sate. |
@@ -1616,4 +1622,32 @@ struct iwl_sf_cfg_cmd { | |||
1616 | __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES]; | 1622 | __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES]; |
1617 | } __packed; /* SF_CFG_API_S_VER_2 */ | 1623 | } __packed; /* SF_CFG_API_S_VER_2 */ |
1618 | 1624 | ||
1625 | /* DTS measurements */ | ||
1626 | |||
1627 | enum iwl_dts_measurement_flags { | ||
1628 | DTS_TRIGGER_CMD_FLAGS_TEMP = BIT(0), | ||
1629 | DTS_TRIGGER_CMD_FLAGS_VOLT = BIT(1), | ||
1630 | }; | ||
1631 | |||
1632 | /** | ||
1633 | * iwl_dts_measurement_cmd - request DTS temperature and/or voltage measurements | ||
1634 | * | ||
1635 | * @flags: indicates which measurements we want as specified in &enum | ||
1636 | * iwl_dts_measurement_flags | ||
1637 | */ | ||
1638 | struct iwl_dts_measurement_cmd { | ||
1639 | __le32 flags; | ||
1640 | } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_CMD_S */ | ||
1641 | |||
1642 | /** | ||
1643 | * iwl_dts_measurement_notif - notification received with the measurements | ||
1644 | * | ||
1645 | * @temp: the measured temperature | ||
1646 | * @voltage: the measured voltage | ||
1647 | */ | ||
1648 | struct iwl_dts_measurement_notif { | ||
1649 | __le32 temp; | ||
1650 | __le32 voltage; | ||
1651 | } __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */ | ||
1652 | |||
1619 | #endif /* __fw_api_h__ */ | 1653 | #endif /* __fw_api_h__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 21d606028ca6..23fd711a67e4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c | |||
@@ -454,6 +454,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
454 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) | 454 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) |
455 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); | 455 | RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); |
456 | 456 | ||
457 | /* reset quota debouncing buffer - 0xff will yield invalid data */ | ||
458 | memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd)); | ||
459 | |||
457 | /* Add auxiliary station for scanning */ | 460 | /* Add auxiliary station for scanning */ |
458 | ret = iwl_mvm_add_aux_sta(mvm); | 461 | ret = iwl_mvm_add_aux_sta(mvm); |
459 | if (ret) | 462 | if (ret) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c index 158aed501473..834267145929 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c | |||
@@ -1234,13 +1234,13 @@ static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm, | |||
1234 | !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) { | 1234 | !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) { |
1235 | u32 rel_time = (c + 1) * | 1235 | u32 rel_time = (c + 1) * |
1236 | csa_vif->bss_conf.beacon_int - | 1236 | csa_vif->bss_conf.beacon_int - |
1237 | IWL_MVM_CHANNEL_SWITCH_TIME; | 1237 | IWL_MVM_CHANNEL_SWITCH_TIME_GO; |
1238 | u32 apply_time = gp2 + rel_time * 1024; | 1238 | u32 apply_time = gp2 + rel_time * 1024; |
1239 | 1239 | ||
1240 | iwl_mvm_schedule_csa_noa(mvm, csa_vif, | 1240 | iwl_mvm_schedule_csa_period(mvm, csa_vif, |
1241 | IWL_MVM_CHANNEL_SWITCH_TIME - | 1241 | IWL_MVM_CHANNEL_SWITCH_TIME_GO - |
1242 | IWL_MVM_CHANNEL_SWITCH_MARGIN, | 1242 | IWL_MVM_CHANNEL_SWITCH_MARGIN, |
1243 | apply_time); | 1243 | apply_time); |
1244 | } | 1244 | } |
1245 | } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) { | 1245 | } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) { |
1246 | /* we don't have CSA NoA scheduled yet, switch now */ | 1246 | /* we don't have CSA NoA scheduled yet, switch now */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index 069bb8e81c36..4c2121094a0b 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -303,9 +303,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
303 | IEEE80211_HW_AMPDU_AGGREGATION | | 303 | IEEE80211_HW_AMPDU_AGGREGATION | |
304 | IEEE80211_HW_TIMING_BEACON_ONLY | | 304 | IEEE80211_HW_TIMING_BEACON_ONLY | |
305 | IEEE80211_HW_CONNECTION_MONITOR | | 305 | IEEE80211_HW_CONNECTION_MONITOR | |
306 | IEEE80211_HW_CHANCTX_STA_CSA | | 306 | IEEE80211_HW_CHANCTX_STA_CSA; |
307 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
308 | IEEE80211_HW_SUPPORTS_STATIC_SMPS; | ||
309 | 307 | ||
310 | hw->queues = mvm->first_agg_queue; | 308 | hw->queues = mvm->first_agg_queue; |
311 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; | 309 | hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; |
@@ -327,7 +325,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
327 | IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 && | 325 | IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 && |
328 | !iwlwifi_mod_params.uapsd_disable) { | 326 | !iwlwifi_mod_params.uapsd_disable) { |
329 | hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; | 327 | hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; |
330 | hw->uapsd_queues = IWL_UAPSD_AC_INFO; | 328 | hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; |
331 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; | 329 | hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; |
332 | } | 330 | } |
333 | 331 | ||
@@ -409,7 +407,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) | |||
409 | 407 | ||
410 | hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | | 408 | hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | |
411 | NL80211_FEATURE_LOW_PRIORITY_SCAN | | 409 | NL80211_FEATURE_LOW_PRIORITY_SCAN | |
412 | NL80211_FEATURE_P2P_GO_OPPPS; | 410 | NL80211_FEATURE_P2P_GO_OPPPS | |
411 | NL80211_FEATURE_DYNAMIC_SMPS | | ||
412 | NL80211_FEATURE_STATIC_SMPS; | ||
413 | 413 | ||
414 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 414 | mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
415 | 415 | ||
@@ -670,8 +670,9 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac, | |||
670 | } | 670 | } |
671 | 671 | ||
672 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 672 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
673 | static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | 673 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) |
674 | { | 674 | { |
675 | static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL }; | ||
675 | struct iwl_fw_error_dump_file *dump_file; | 676 | struct iwl_fw_error_dump_file *dump_file; |
676 | struct iwl_fw_error_dump_data *dump_data; | 677 | struct iwl_fw_error_dump_data *dump_data; |
677 | struct iwl_fw_error_dump_info *dump_info; | 678 | struct iwl_fw_error_dump_info *dump_info; |
@@ -763,20 +764,16 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) | |||
763 | file_len += fw_error_dump->trans_ptr->len; | 764 | file_len += fw_error_dump->trans_ptr->len; |
764 | dump_file->file_len = cpu_to_le32(file_len); | 765 | dump_file->file_len = cpu_to_le32(file_len); |
765 | mvm->fw_error_dump = fw_error_dump; | 766 | mvm->fw_error_dump = fw_error_dump; |
767 | |||
768 | /* notify the userspace about the error we had */ | ||
769 | kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env); | ||
766 | } | 770 | } |
767 | #endif | 771 | #endif |
768 | 772 | ||
769 | static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | 773 | static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) |
770 | { | 774 | { |
771 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
772 | static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL }; | ||
773 | |||
774 | iwl_mvm_fw_error_dump(mvm); | 775 | iwl_mvm_fw_error_dump(mvm); |
775 | 776 | ||
776 | /* notify the userspace about the error we had */ | ||
777 | kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env); | ||
778 | #endif | ||
779 | |||
780 | iwl_trans_stop_device(mvm->trans); | 777 | iwl_trans_stop_device(mvm->trans); |
781 | 778 | ||
782 | mvm->scan_status = IWL_MVM_SCAN_NONE; | 779 | mvm->scan_status = IWL_MVM_SCAN_NONE; |
@@ -815,12 +812,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) | |||
815 | mvm->rx_ba_sessions = 0; | 812 | mvm->rx_ba_sessions = 0; |
816 | } | 813 | } |
817 | 814 | ||
818 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) | 815 | int __iwl_mvm_mac_start(struct iwl_mvm *mvm) |
819 | { | 816 | { |
820 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
821 | int ret; | 817 | int ret; |
822 | 818 | ||
823 | mutex_lock(&mvm->mutex); | 819 | lockdep_assert_held(&mvm->mutex); |
824 | 820 | ||
825 | /* Clean up some internal and mac80211 state on restart */ | 821 | /* Clean up some internal and mac80211 state on restart */ |
826 | if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) | 822 | if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) |
@@ -837,6 +833,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw) | |||
837 | iwl_mvm_d0i3_enable_tx(mvm, NULL); | 833 | iwl_mvm_d0i3_enable_tx(mvm, NULL); |
838 | } | 834 | } |
839 | 835 | ||
836 | return ret; | ||
837 | } | ||
838 | |||
839 | static int iwl_mvm_mac_start(struct ieee80211_hw *hw) | ||
840 | { | ||
841 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
842 | int ret; | ||
843 | |||
844 | mutex_lock(&mvm->mutex); | ||
845 | ret = __iwl_mvm_mac_start(mvm); | ||
840 | mutex_unlock(&mvm->mutex); | 846 | mutex_unlock(&mvm->mutex); |
841 | 847 | ||
842 | return ret; | 848 | return ret; |
@@ -862,14 +868,9 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw) | |||
862 | mutex_unlock(&mvm->mutex); | 868 | mutex_unlock(&mvm->mutex); |
863 | } | 869 | } |
864 | 870 | ||
865 | static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | 871 | void __iwl_mvm_mac_stop(struct iwl_mvm *mvm) |
866 | { | 872 | { |
867 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 873 | lockdep_assert_held(&mvm->mutex); |
868 | |||
869 | flush_work(&mvm->d0i3_exit_work); | ||
870 | flush_work(&mvm->async_handlers_wk); | ||
871 | |||
872 | mutex_lock(&mvm->mutex); | ||
873 | 874 | ||
874 | /* disallow low power states when the FW is down */ | 875 | /* disallow low power states when the FW is down */ |
875 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); | 876 | iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); |
@@ -890,6 +891,19 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | |||
890 | /* the fw is stopped, the aux sta is dead: clean up driver state */ | 891 | /* the fw is stopped, the aux sta is dead: clean up driver state */ |
891 | iwl_mvm_del_aux_sta(mvm); | 892 | iwl_mvm_del_aux_sta(mvm); |
892 | 893 | ||
894 | mvm->ucode_loaded = false; | ||
895 | } | ||
896 | |||
897 | static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) | ||
898 | { | ||
899 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
900 | |||
901 | flush_work(&mvm->d0i3_exit_work); | ||
902 | flush_work(&mvm->async_handlers_wk); | ||
903 | flush_work(&mvm->fw_error_dump_wk); | ||
904 | |||
905 | mutex_lock(&mvm->mutex); | ||
906 | __iwl_mvm_mac_stop(mvm); | ||
893 | mutex_unlock(&mvm->mutex); | 907 | mutex_unlock(&mvm->mutex); |
894 | 908 | ||
895 | /* | 909 | /* |
@@ -1198,14 +1212,15 @@ static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw, | |||
1198 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 1212 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
1199 | struct iwl_mcast_filter_cmd *cmd; | 1213 | struct iwl_mcast_filter_cmd *cmd; |
1200 | struct netdev_hw_addr *addr; | 1214 | struct netdev_hw_addr *addr; |
1201 | int addr_count = netdev_hw_addr_list_count(mc_list); | 1215 | int addr_count; |
1202 | bool pass_all = false; | 1216 | bool pass_all; |
1203 | int len; | 1217 | int len; |
1204 | 1218 | ||
1205 | if (addr_count > MAX_MCAST_FILTERING_ADDRESSES) { | 1219 | addr_count = netdev_hw_addr_list_count(mc_list); |
1206 | pass_all = true; | 1220 | pass_all = addr_count > MAX_MCAST_FILTERING_ADDRESSES || |
1221 | IWL_MVM_FW_MCAST_FILTER_PASS_ALL; | ||
1222 | if (pass_all) | ||
1207 | addr_count = 0; | 1223 | addr_count = 0; |
1208 | } | ||
1209 | 1224 | ||
1210 | len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4); | 1225 | len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4); |
1211 | cmd = kzalloc(len, GFP_ATOMIC); | 1226 | cmd = kzalloc(len, GFP_ATOMIC); |
@@ -1405,28 +1420,6 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm, | |||
1405 | } | 1420 | } |
1406 | #endif | 1421 | #endif |
1407 | 1422 | ||
1408 | static void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm) | ||
1409 | { | ||
1410 | struct ieee80211_sta *sta; | ||
1411 | struct iwl_mvm_sta *mvmsta; | ||
1412 | int i; | ||
1413 | |||
1414 | lockdep_assert_held(&mvm->mutex); | ||
1415 | |||
1416 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { | ||
1417 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], | ||
1418 | lockdep_is_held(&mvm->mutex)); | ||
1419 | if (!sta || IS_ERR(sta) || !sta->tdls) | ||
1420 | continue; | ||
1421 | |||
1422 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
1423 | ieee80211_tdls_oper_request(mvmsta->vif, sta->addr, | ||
1424 | NL80211_TDLS_TEARDOWN, | ||
1425 | WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, | ||
1426 | GFP_KERNEL); | ||
1427 | } | ||
1428 | } | ||
1429 | |||
1430 | static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, | 1423 | static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, |
1431 | struct ieee80211_vif *vif, | 1424 | struct ieee80211_vif *vif, |
1432 | struct ieee80211_bss_conf *bss_conf, | 1425 | struct ieee80211_bss_conf *bss_conf, |
@@ -1724,7 +1717,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm, | |||
1724 | return; | 1717 | return; |
1725 | 1718 | ||
1726 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | | 1719 | if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | |
1727 | BSS_CHANGED_BANDWIDTH) && | 1720 | BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS) && |
1728 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL)) | 1721 | iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL)) |
1729 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); | 1722 | IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); |
1730 | 1723 | ||
@@ -1955,48 +1948,6 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw, | |||
1955 | mutex_unlock(&mvm->mutex); | 1948 | mutex_unlock(&mvm->mutex); |
1956 | } | 1949 | } |
1957 | 1950 | ||
1958 | int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
1959 | { | ||
1960 | struct ieee80211_sta *sta; | ||
1961 | struct iwl_mvm_sta *mvmsta; | ||
1962 | int count = 0; | ||
1963 | int i; | ||
1964 | |||
1965 | lockdep_assert_held(&mvm->mutex); | ||
1966 | |||
1967 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { | ||
1968 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], | ||
1969 | lockdep_is_held(&mvm->mutex)); | ||
1970 | if (!sta || IS_ERR(sta) || !sta->tdls) | ||
1971 | continue; | ||
1972 | |||
1973 | if (vif) { | ||
1974 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
1975 | if (mvmsta->vif != vif) | ||
1976 | continue; | ||
1977 | } | ||
1978 | |||
1979 | count++; | ||
1980 | } | ||
1981 | |||
1982 | return count; | ||
1983 | } | ||
1984 | |||
1985 | static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, | ||
1986 | struct ieee80211_vif *vif, | ||
1987 | bool sta_added) | ||
1988 | { | ||
1989 | int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif); | ||
1990 | |||
1991 | /* | ||
1992 | * Disable ps when the first TDLS sta is added and re-enable it | ||
1993 | * when the last TDLS sta is removed | ||
1994 | */ | ||
1995 | if ((tdls_sta_cnt == 1 && sta_added) || | ||
1996 | (tdls_sta_cnt == 0 && !sta_added)) | ||
1997 | iwl_mvm_power_update_mac(mvm); | ||
1998 | } | ||
1999 | |||
2000 | static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, | 1951 | static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, |
2001 | struct ieee80211_vif *vif, | 1952 | struct ieee80211_vif *vif, |
2002 | struct ieee80211_sta *sta, | 1953 | struct ieee80211_sta *sta, |
@@ -2170,27 +2121,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw, | |||
2170 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); | 2121 | iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); |
2171 | } | 2122 | } |
2172 | 2123 | ||
2173 | static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, | ||
2174 | struct ieee80211_vif *vif) | ||
2175 | { | ||
2176 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
2177 | u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int; | ||
2178 | |||
2179 | /* | ||
2180 | * iwl_mvm_protect_session() reads directly from the device | ||
2181 | * (the system time), so make sure it is available. | ||
2182 | */ | ||
2183 | if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS)) | ||
2184 | return; | ||
2185 | |||
2186 | mutex_lock(&mvm->mutex); | ||
2187 | /* Protect the session to hear the TDLS setup response on the channel */ | ||
2188 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); | ||
2189 | mutex_unlock(&mvm->mutex); | ||
2190 | |||
2191 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); | ||
2192 | } | ||
2193 | |||
2194 | static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, | 2124 | static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, |
2195 | struct ieee80211_vif *vif, | 2125 | struct ieee80211_vif *vif, |
2196 | struct cfg80211_sched_scan_request *req, | 2126 | struct cfg80211_sched_scan_request *req, |
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index e292de96e09a..552995810f9e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h | |||
@@ -87,11 +87,11 @@ | |||
87 | /* A TimeUnit is 1024 microsecond */ | 87 | /* A TimeUnit is 1024 microsecond */ |
88 | #define MSEC_TO_TU(_msec) (_msec*1000/1024) | 88 | #define MSEC_TO_TU(_msec) (_msec*1000/1024) |
89 | 89 | ||
90 | /* | 90 | /* This value represents the number of TUs before CSA "beacon 0" TBTT |
91 | * The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0" | 91 | * when the CSA time-event needs to be scheduled to start. It must be |
92 | * TBTT. This value should be big enough to ensure that we switch in time. | 92 | * big enough to ensure that we switch in time. |
93 | */ | 93 | */ |
94 | #define IWL_MVM_CHANNEL_SWITCH_TIME 40 | 94 | #define IWL_MVM_CHANNEL_SWITCH_TIME_GO 40 |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * This value (in TUs) is used to fine tune the CSA NoA end time which should | 97 | * This value (in TUs) is used to fine tune the CSA NoA end time which should |
@@ -180,10 +180,6 @@ enum iwl_power_scheme { | |||
180 | }; | 180 | }; |
181 | 181 | ||
182 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 | 182 | #define IWL_CONN_MAX_LISTEN_INTERVAL 10 |
183 | #define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\ | ||
184 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\ | ||
185 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\ | ||
186 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) | ||
187 | #define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2 | 183 | #define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2 |
188 | 184 | ||
189 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 185 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
@@ -274,6 +270,8 @@ enum iwl_mvm_ref_type { | |||
274 | IWL_MVM_REF_TM_CMD, | 270 | IWL_MVM_REF_TM_CMD, |
275 | IWL_MVM_REF_EXIT_WORK, | 271 | IWL_MVM_REF_EXIT_WORK, |
276 | 272 | ||
273 | /* update debugfs.c when changing this */ | ||
274 | |||
277 | IWL_MVM_REF_COUNT, | 275 | IWL_MVM_REF_COUNT, |
278 | }; | 276 | }; |
279 | 277 | ||
@@ -649,6 +647,7 @@ struct iwl_mvm { | |||
649 | 647 | ||
650 | /* -1 for always, 0 for never, >0 for that many times */ | 648 | /* -1 for always, 0 for never, >0 for that many times */ |
651 | s8 restart_fw; | 649 | s8 restart_fw; |
650 | struct work_struct fw_error_dump_wk; | ||
652 | struct iwl_mvm_dump_ptrs *fw_error_dump; | 651 | struct iwl_mvm_dump_ptrs *fw_error_dump; |
653 | 652 | ||
654 | #ifdef CONFIG_IWLWIFI_LEDS | 653 | #ifdef CONFIG_IWLWIFI_LEDS |
@@ -709,6 +708,8 @@ struct iwl_mvm { | |||
709 | */ | 708 | */ |
710 | bool temperature_test; /* Debug test temperature is enabled */ | 709 | bool temperature_test; /* Debug test temperature is enabled */ |
711 | 710 | ||
711 | struct iwl_time_quota_cmd last_quota_cmd; | ||
712 | |||
712 | #ifdef CONFIG_NL80211_TESTMODE | 713 | #ifdef CONFIG_NL80211_TESTMODE |
713 | u32 noa_duration; | 714 | u32 noa_duration; |
714 | struct ieee80211_vif *noa_vif; | 715 | struct ieee80211_vif *noa_vif; |
@@ -788,6 +789,9 @@ struct iwl_rate_info { | |||
788 | u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ | 789 | u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ |
789 | }; | 790 | }; |
790 | 791 | ||
792 | void __iwl_mvm_mac_stop(struct iwl_mvm *mvm); | ||
793 | int __iwl_mvm_mac_start(struct iwl_mvm *mvm); | ||
794 | |||
791 | /****************** | 795 | /****************** |
792 | * MVM Methods | 796 | * MVM Methods |
793 | ******************/ | 797 | ******************/ |
@@ -1153,7 +1157,17 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1153 | 1157 | ||
1154 | /* TDLS */ | 1158 | /* TDLS */ |
1155 | int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif); | 1159 | int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
1160 | void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm); | ||
1161 | void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
1162 | bool sta_added); | ||
1163 | void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, | ||
1164 | struct ieee80211_vif *vif); | ||
1156 | 1165 | ||
1157 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); | 1166 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); |
1167 | #ifdef CONFIG_IWLWIFI_DEBUGFS | ||
1168 | void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm); | ||
1169 | #else | ||
1170 | static inline void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) {} | ||
1171 | #endif | ||
1158 | 1172 | ||
1159 | #endif /* __IWL_MVM_H__ */ | 1173 | #endif /* __IWL_MVM_H__ */ |
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c index 4fafd4bd89f4..af074563e770 100644 --- a/drivers/net/wireless/iwlwifi/mvm/nvm.c +++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c | |||
@@ -64,6 +64,7 @@ | |||
64 | *****************************************************************************/ | 64 | *****************************************************************************/ |
65 | #include <linux/firmware.h> | 65 | #include <linux/firmware.h> |
66 | #include "iwl-trans.h" | 66 | #include "iwl-trans.h" |
67 | #include "iwl-csr.h" | ||
67 | #include "mvm.h" | 68 | #include "mvm.h" |
68 | #include "iwl-eeprom-parse.h" | 69 | #include "iwl-eeprom-parse.h" |
69 | #include "iwl-eeprom-read.h" | 70 | #include "iwl-eeprom-read.h" |
@@ -349,7 +350,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm) | |||
349 | /* Maximal size depends on HW family and step */ | 350 | /* Maximal size depends on HW family and step */ |
350 | if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) | 351 | if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) |
351 | max_section_size = IWL_MAX_NVM_SECTION_SIZE; | 352 | max_section_size = IWL_MAX_NVM_SECTION_SIZE; |
352 | else if ((mvm->trans->hw_rev & 0xc) == 0) /* Family 8000 A-step */ | 353 | else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP) |
353 | max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; | 354 | max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; |
354 | else /* Family 8000 B-step */ | 355 | else /* Family 8000 B-step */ |
355 | max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; | 356 | max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index 87f278cc9b2c..f887779717d5 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c | |||
@@ -332,6 +332,8 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = { | |||
332 | CMD(BCAST_FILTER_CMD), | 332 | CMD(BCAST_FILTER_CMD), |
333 | CMD(REPLY_SF_CFG_CMD), | 333 | CMD(REPLY_SF_CFG_CMD), |
334 | CMD(REPLY_BEACON_FILTERING_CMD), | 334 | CMD(REPLY_BEACON_FILTERING_CMD), |
335 | CMD(CMD_DTS_MEASUREMENT_TRIGGER), | ||
336 | CMD(DTS_MEASUREMENT_NOTIFICATION), | ||
335 | CMD(REPLY_THERMAL_MNG_BACKOFF), | 337 | CMD(REPLY_THERMAL_MNG_BACKOFF), |
336 | CMD(MAC_PM_POWER_TABLE), | 338 | CMD(MAC_PM_POWER_TABLE), |
337 | CMD(BT_COEX_CI), | 339 | CMD(BT_COEX_CI), |
@@ -364,6 +366,8 @@ static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg) | |||
364 | return 0; | 366 | return 0; |
365 | } | 367 | } |
366 | 368 | ||
369 | static void iwl_mvm_fw_error_dump_wk(struct work_struct *work); | ||
370 | |||
367 | static struct iwl_op_mode * | 371 | static struct iwl_op_mode * |
368 | iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | 372 | iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, |
369 | const struct iwl_fw *fw, struct dentry *dbgfs_dir) | 373 | const struct iwl_fw *fw, struct dentry *dbgfs_dir) |
@@ -431,6 +435,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
431 | INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); | 435 | INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); |
432 | INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); | 436 | INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); |
433 | INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); | 437 | INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); |
438 | INIT_WORK(&mvm->fw_error_dump_wk, iwl_mvm_fw_error_dump_wk); | ||
434 | 439 | ||
435 | spin_lock_init(&mvm->d0i3_tx_lock); | 440 | spin_lock_init(&mvm->d0i3_tx_lock); |
436 | spin_lock_init(&mvm->refs_lock); | 441 | spin_lock_init(&mvm->refs_lock); |
@@ -460,6 +465,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
460 | 465 | ||
461 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; | 466 | trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; |
462 | trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; | 467 | trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; |
468 | trans_cfg.scd_set_active = true; | ||
463 | 469 | ||
464 | snprintf(mvm->hw->wiphy->fw_version, | 470 | snprintf(mvm->hw->wiphy->fw_version, |
465 | sizeof(mvm->hw->wiphy->fw_version), | 471 | sizeof(mvm->hw->wiphy->fw_version), |
@@ -781,6 +787,16 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk) | |||
781 | module_put(THIS_MODULE); | 787 | module_put(THIS_MODULE); |
782 | } | 788 | } |
783 | 789 | ||
790 | static void iwl_mvm_fw_error_dump_wk(struct work_struct *work) | ||
791 | { | ||
792 | struct iwl_mvm *mvm = | ||
793 | container_of(work, struct iwl_mvm, fw_error_dump_wk); | ||
794 | |||
795 | mutex_lock(&mvm->mutex); | ||
796 | iwl_mvm_fw_error_dump(mvm); | ||
797 | mutex_unlock(&mvm->mutex); | ||
798 | } | ||
799 | |||
784 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) | 800 | void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) |
785 | { | 801 | { |
786 | iwl_abort_notification_waits(&mvm->notif_wait); | 802 | iwl_abort_notification_waits(&mvm->notif_wait); |
@@ -846,6 +862,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) | |||
846 | if (fw_error && mvm->restart_fw > 0) | 862 | if (fw_error && mvm->restart_fw > 0) |
847 | mvm->restart_fw--; | 863 | mvm->restart_fw--; |
848 | ieee80211_restart_hw(mvm->hw); | 864 | ieee80211_restart_hw(mvm->hw); |
865 | } else if (fw_error) { | ||
866 | schedule_work(&mvm->fw_error_dump_wk); | ||
849 | } | 867 | } |
850 | } | 868 | } |
851 | 869 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c index 5a29c193b72a..5b85b0cc7a2a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/power.c +++ b/drivers/net/wireless/iwlwifi/mvm/power.c | |||
@@ -286,12 +286,28 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm, | |||
286 | return true; | 286 | return true; |
287 | } | 287 | } |
288 | 288 | ||
289 | static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif) | ||
290 | { | ||
291 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
292 | struct ieee80211_channel *chan; | ||
293 | bool radar_detect = false; | ||
294 | |||
295 | rcu_read_lock(); | ||
296 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
297 | WARN_ON(!chanctx_conf); | ||
298 | if (chanctx_conf) { | ||
299 | chan = chanctx_conf->def.chan; | ||
300 | radar_detect = chan->flags & IEEE80211_CHAN_RADAR; | ||
301 | } | ||
302 | rcu_read_unlock(); | ||
303 | |||
304 | return radar_detect; | ||
305 | } | ||
306 | |||
289 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | 307 | static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, |
290 | struct ieee80211_vif *vif, | 308 | struct ieee80211_vif *vif, |
291 | struct iwl_mac_power_cmd *cmd) | 309 | struct iwl_mac_power_cmd *cmd) |
292 | { | 310 | { |
293 | struct ieee80211_chanctx_conf *chanctx_conf; | ||
294 | struct ieee80211_channel *chan; | ||
295 | int dtimper, dtimper_msec; | 311 | int dtimper, dtimper_msec; |
296 | int keep_alive; | 312 | int keep_alive; |
297 | bool radar_detect = false; | 313 | bool radar_detect = false; |
@@ -320,7 +336,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
320 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); | 336 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); |
321 | 337 | ||
322 | if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) || | 338 | if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) || |
323 | !mvmvif->pm_enabled) | 339 | !mvmvif->pm_enabled || iwl_mvm_tdls_sta_count(mvm, vif)) |
324 | return; | 340 | return; |
325 | 341 | ||
326 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); | 342 | cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); |
@@ -333,14 +349,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, | |||
333 | } | 349 | } |
334 | 350 | ||
335 | /* Check if radar detection is required on current channel */ | 351 | /* Check if radar detection is required on current channel */ |
336 | rcu_read_lock(); | 352 | radar_detect = iwl_mvm_power_is_radar(vif); |
337 | chanctx_conf = rcu_dereference(vif->chanctx_conf); | ||
338 | WARN_ON(!chanctx_conf); | ||
339 | if (chanctx_conf) { | ||
340 | chan = chanctx_conf->def.chan; | ||
341 | radar_detect = chan->flags & IEEE80211_CHAN_RADAR; | ||
342 | } | ||
343 | rcu_read_unlock(); | ||
344 | 353 | ||
345 | /* Check skip over DTIM conditions */ | 354 | /* Check skip over DTIM conditions */ |
346 | if (!radar_detect && (dtimper <= 10) && | 355 | if (!radar_detect && (dtimper <= 10) && |
@@ -501,8 +510,6 @@ struct iwl_power_vifs { | |||
501 | bool bss_active; | 510 | bool bss_active; |
502 | bool ap_active; | 511 | bool ap_active; |
503 | bool monitor_active; | 512 | bool monitor_active; |
504 | bool bss_tdls; | ||
505 | bool p2p_tdls; | ||
506 | }; | 513 | }; |
507 | 514 | ||
508 | static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, | 515 | static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, |
@@ -557,8 +564,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac, | |||
557 | /* only a single MAC of the same type */ | 564 | /* only a single MAC of the same type */ |
558 | WARN_ON(power_iterator->p2p_vif); | 565 | WARN_ON(power_iterator->p2p_vif); |
559 | power_iterator->p2p_vif = vif; | 566 | power_iterator->p2p_vif = vif; |
560 | power_iterator->p2p_tdls = | ||
561 | !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif); | ||
562 | if (mvmvif->phy_ctxt) | 567 | if (mvmvif->phy_ctxt) |
563 | if (mvmvif->phy_ctxt->id < MAX_PHYS) | 568 | if (mvmvif->phy_ctxt->id < MAX_PHYS) |
564 | power_iterator->p2p_active = true; | 569 | power_iterator->p2p_active = true; |
@@ -568,8 +573,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac, | |||
568 | /* only a single MAC of the same type */ | 573 | /* only a single MAC of the same type */ |
569 | WARN_ON(power_iterator->bss_vif); | 574 | WARN_ON(power_iterator->bss_vif); |
570 | power_iterator->bss_vif = vif; | 575 | power_iterator->bss_vif = vif; |
571 | power_iterator->bss_tdls = | ||
572 | !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif); | ||
573 | if (mvmvif->phy_ctxt) | 576 | if (mvmvif->phy_ctxt) |
574 | if (mvmvif->phy_ctxt->id < MAX_PHYS) | 577 | if (mvmvif->phy_ctxt->id < MAX_PHYS) |
575 | power_iterator->bss_active = true; | 578 | power_iterator->bss_active = true; |
@@ -612,15 +615,13 @@ static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm, | |||
612 | ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif); | 615 | ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif); |
613 | 616 | ||
614 | /* enable PM on bss if bss stand alone */ | 617 | /* enable PM on bss if bss stand alone */ |
615 | if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active && | 618 | if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) { |
616 | !vifs->bss_tdls) { | ||
617 | bss_mvmvif->pm_enabled = true; | 619 | bss_mvmvif->pm_enabled = true; |
618 | return; | 620 | return; |
619 | } | 621 | } |
620 | 622 | ||
621 | /* enable PM on p2p if p2p stand alone */ | 623 | /* enable PM on p2p if p2p stand alone */ |
622 | if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active && | 624 | if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) { |
623 | !vifs->p2p_tdls) { | ||
624 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM) | 625 | if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM) |
625 | p2p_mvmvif->pm_enabled = true; | 626 | p2p_mvmvif->pm_enabled = true; |
626 | return; | 627 | return; |
@@ -961,17 +962,22 @@ int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm, | |||
961 | 962 | ||
962 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); | 963 | iwl_mvm_power_build_cmd(mvm, vif, &cmd); |
963 | if (enable) { | 964 | if (enable) { |
964 | /* configure skip over dtim up to 300 msec */ | 965 | /* configure skip over dtim up to 306TU - 314 msec */ |
965 | int dtimper = vif->bss_conf.dtim_period ?: 1; | 966 | int dtimper = vif->bss_conf.dtim_period ?: 1; |
966 | int dtimper_msec = dtimper * vif->bss_conf.beacon_int; | 967 | int dtimper_tu = dtimper * vif->bss_conf.beacon_int; |
968 | bool radar_detect = iwl_mvm_power_is_radar(vif); | ||
967 | 969 | ||
968 | if (WARN_ON(!dtimper_msec)) | 970 | if (WARN_ON(!dtimper_tu)) |
969 | return 0; | 971 | return 0; |
970 | 972 | ||
971 | cmd.skip_dtim_periods = 300 / dtimper_msec; | 973 | /* Check skip over DTIM conditions */ |
972 | if (cmd.skip_dtim_periods) | 974 | /* TODO: check that multicast wake lock is off */ |
973 | cmd.flags |= | 975 | if (!radar_detect && (dtimper < 10)) { |
974 | cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); | 976 | cmd.skip_dtim_periods = 306 / dtimper_tu; |
977 | if (cmd.skip_dtim_periods) | ||
978 | cmd.flags |= cpu_to_le16( | ||
979 | POWER_FLAGS_SKIP_OVER_DTIM_MSK); | ||
980 | } | ||
975 | } | 981 | } |
976 | iwl_mvm_power_log(mvm, &cmd); | 982 | iwl_mvm_power_log(mvm, &cmd); |
977 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 983 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c index 5fd502db03d1..dbb2594390e9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/quota.c +++ b/drivers/net/wireless/iwlwifi/mvm/quota.c | |||
@@ -175,12 +175,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
175 | struct ieee80211_vif *disabled_vif) | 175 | struct ieee80211_vif *disabled_vif) |
176 | { | 176 | { |
177 | struct iwl_time_quota_cmd cmd = {}; | 177 | struct iwl_time_quota_cmd cmd = {}; |
178 | int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat; | 178 | int i, idx, err, num_active_macs, quota, quota_rem, n_non_lowlat; |
179 | struct iwl_mvm_quota_iterator_data data = { | 179 | struct iwl_mvm_quota_iterator_data data = { |
180 | .n_interfaces = {}, | 180 | .n_interfaces = {}, |
181 | .colors = { -1, -1, -1, -1 }, | 181 | .colors = { -1, -1, -1, -1 }, |
182 | .disabled_vif = disabled_vif, | 182 | .disabled_vif = disabled_vif, |
183 | }; | 183 | }; |
184 | struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd; | ||
185 | bool send = false; | ||
184 | 186 | ||
185 | lockdep_assert_held(&mvm->mutex); | 187 | lockdep_assert_held(&mvm->mutex); |
186 | 188 | ||
@@ -293,15 +295,33 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm, | |||
293 | 295 | ||
294 | /* check that we have non-zero quota for all valid bindings */ | 296 | /* check that we have non-zero quota for all valid bindings */ |
295 | for (i = 0; i < MAX_BINDINGS; i++) { | 297 | for (i = 0; i < MAX_BINDINGS; i++) { |
298 | if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color) | ||
299 | send = true; | ||
300 | if (cmd.quotas[i].max_duration != last->quotas[i].max_duration) | ||
301 | send = true; | ||
302 | if (abs((int)le32_to_cpu(cmd.quotas[i].quota) - | ||
303 | (int)le32_to_cpu(last->quotas[i].quota)) | ||
304 | > IWL_MVM_QUOTA_THRESHOLD) | ||
305 | send = true; | ||
296 | if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID)) | 306 | if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID)) |
297 | continue; | 307 | continue; |
298 | WARN_ONCE(cmd.quotas[i].quota == 0, | 308 | WARN_ONCE(cmd.quotas[i].quota == 0, |
299 | "zero quota on binding %d\n", i); | 309 | "zero quota on binding %d\n", i); |
300 | } | 310 | } |
301 | 311 | ||
302 | ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, | 312 | if (!send) { |
303 | sizeof(cmd), &cmd); | 313 | /* don't send a practically unchanged command, the firmware has |
304 | if (ret) | 314 | * to re-initialize a lot of state and that can have an adverse |
305 | IWL_ERR(mvm, "Failed to send quota: %d\n", ret); | 315 | * impact on it |
306 | return ret; | 316 | */ |
317 | return 0; | ||
318 | } | ||
319 | |||
320 | err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd); | ||
321 | |||
322 | if (err) | ||
323 | IWL_ERR(mvm, "Failed to send quota: %d\n", err); | ||
324 | else | ||
325 | mvm->last_quota_cmd = cmd; | ||
326 | return err; | ||
307 | } | 327 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c index 17002cf437db..f77dfe4df074 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/iwlwifi/mvm/rs.c | |||
@@ -505,10 +505,10 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type) | |||
505 | static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, | 505 | static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, |
506 | const char *prefix) | 506 | const char *prefix) |
507 | { | 507 | { |
508 | IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n", | 508 | IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d\n", |
509 | prefix, rs_pretty_lq_type(rate->type), | 509 | prefix, rs_pretty_lq_type(rate->type), |
510 | rate->index, rs_pretty_ant(rate->ant), | 510 | rate->index, rs_pretty_ant(rate->ant), |
511 | rate->bw, rate->sgi); | 511 | rate->bw, rate->sgi, rate->ldpc); |
512 | } | 512 | } |
513 | 513 | ||
514 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) | 514 | static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) |
@@ -672,8 +672,10 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta, | |||
672 | return -EINVAL; | 672 | return -EINVAL; |
673 | 673 | ||
674 | if (tbl->column != RS_COLUMN_INVALID) { | 674 | if (tbl->column != RS_COLUMN_INVALID) { |
675 | lq_sta->tx_stats[tbl->column][scale_index].total += attempts; | 675 | struct lq_sta_pers *pers = &lq_sta->pers; |
676 | lq_sta->tx_stats[tbl->column][scale_index].success += successes; | 676 | |
677 | pers->tx_stats[tbl->column][scale_index].total += attempts; | ||
678 | pers->tx_stats[tbl->column][scale_index].success += successes; | ||
677 | } | 679 | } |
678 | 680 | ||
679 | /* Select window for current tx bit rate */ | 681 | /* Select window for current tx bit rate */ |
@@ -742,6 +744,8 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm, | |||
742 | ucode_rate |= rate->bw; | 744 | ucode_rate |= rate->bw; |
743 | if (rate->sgi) | 745 | if (rate->sgi) |
744 | ucode_rate |= RATE_MCS_SGI_MSK; | 746 | ucode_rate |= RATE_MCS_SGI_MSK; |
747 | if (rate->ldpc) | ||
748 | ucode_rate |= RATE_MCS_LDPC_MSK; | ||
745 | 749 | ||
746 | return ucode_rate; | 750 | return ucode_rate; |
747 | } | 751 | } |
@@ -779,6 +783,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, | |||
779 | /* HT or VHT */ | 783 | /* HT or VHT */ |
780 | if (ucode_rate & RATE_MCS_SGI_MSK) | 784 | if (ucode_rate & RATE_MCS_SGI_MSK) |
781 | rate->sgi = true; | 785 | rate->sgi = true; |
786 | if (ucode_rate & RATE_MCS_LDPC_MSK) | ||
787 | rate->ldpc = true; | ||
782 | 788 | ||
783 | rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; | 789 | rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; |
784 | 790 | ||
@@ -965,13 +971,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta, | |||
965 | rate->index > IWL_RATE_MCS_9_INDEX); | 971 | rate->index > IWL_RATE_MCS_9_INDEX); |
966 | 972 | ||
967 | rate->index = rs_ht_to_legacy[rate->index]; | 973 | rate->index = rs_ht_to_legacy[rate->index]; |
974 | rate->ldpc = false; | ||
968 | } else { | 975 | } else { |
969 | /* Downgrade to SISO with same MCS if in MIMO */ | 976 | /* Downgrade to SISO with same MCS if in MIMO */ |
970 | rate->type = is_vht_mimo2(rate) ? | 977 | rate->type = is_vht_mimo2(rate) ? |
971 | LQ_VHT_SISO : LQ_HT_SISO; | 978 | LQ_VHT_SISO : LQ_HT_SISO; |
972 | } | 979 | } |
973 | 980 | ||
974 | |||
975 | if (num_of_ant(rate->ant) > 1) | 981 | if (num_of_ant(rate->ant) > 1) |
976 | rate->ant = first_antenna(mvm->fw->valid_tx_ant); | 982 | rate->ant = first_antenna(mvm->fw->valid_tx_ant); |
977 | 983 | ||
@@ -1621,6 +1627,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, | |||
1621 | } | 1627 | } |
1622 | 1628 | ||
1623 | rate->bw = rs_bw_from_sta_bw(sta); | 1629 | rate->bw = rs_bw_from_sta_bw(sta); |
1630 | rate->ldpc = lq_sta->ldpc; | ||
1624 | search_tbl->column = col_id; | 1631 | search_tbl->column = col_id; |
1625 | rs_set_expected_tpt_table(lq_sta, search_tbl); | 1632 | rs_set_expected_tpt_table(lq_sta, search_tbl); |
1626 | 1633 | ||
@@ -2031,18 +2038,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
2031 | return; | 2038 | return; |
2032 | } | 2039 | } |
2033 | 2040 | ||
2034 | /* force user max rate if set by user */ | 2041 | /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ |
2035 | if ((lq_sta->max_rate_idx != -1) && | ||
2036 | (lq_sta->max_rate_idx < index)) { | ||
2037 | index = lq_sta->max_rate_idx; | ||
2038 | update_lq = 1; | ||
2039 | window = &(tbl->win[index]); | ||
2040 | IWL_DEBUG_RATE(mvm, | ||
2041 | "Forcing user max rate %d\n", | ||
2042 | index); | ||
2043 | goto lq_update; | ||
2044 | } | ||
2045 | |||
2046 | window = &(tbl->win[index]); | 2042 | window = &(tbl->win[index]); |
2047 | 2043 | ||
2048 | /* | 2044 | /* |
@@ -2130,10 +2126,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, | |||
2130 | low = high_low & 0xff; | 2126 | low = high_low & 0xff; |
2131 | high = (high_low >> 8) & 0xff; | 2127 | high = (high_low >> 8) & 0xff; |
2132 | 2128 | ||
2133 | /* If user set max rate, dont allow higher than user constrain */ | 2129 | /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ |
2134 | if ((lq_sta->max_rate_idx != -1) && | ||
2135 | (lq_sta->max_rate_idx < high)) | ||
2136 | high = IWL_RATE_INVALID; | ||
2137 | 2130 | ||
2138 | sr = window->success_ratio; | 2131 | sr = window->success_ratio; |
2139 | 2132 | ||
@@ -2342,6 +2335,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, | |||
2342 | rate->index = i; | 2335 | rate->index = i; |
2343 | rate->ant = first_antenna(valid_tx_ant); | 2336 | rate->ant = first_antenna(valid_tx_ant); |
2344 | rate->sgi = false; | 2337 | rate->sgi = false; |
2338 | rate->ldpc = false; | ||
2345 | rate->bw = RATE_MCS_CHAN_WIDTH_20; | 2339 | rate->bw = RATE_MCS_CHAN_WIDTH_20; |
2346 | if (band == IEEE80211_BAND_5GHZ) | 2340 | if (band == IEEE80211_BAND_5GHZ) |
2347 | rate->type = LQ_LEGACY_A; | 2341 | rate->type = LQ_LEGACY_A; |
@@ -2364,23 +2358,13 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta, | |||
2364 | struct ieee80211_tx_rate_control *txrc) | 2358 | struct ieee80211_tx_rate_control *txrc) |
2365 | { | 2359 | { |
2366 | struct sk_buff *skb = txrc->skb; | 2360 | struct sk_buff *skb = txrc->skb; |
2367 | struct ieee80211_supported_band *sband = txrc->sband; | ||
2368 | struct iwl_op_mode *op_mode __maybe_unused = | 2361 | struct iwl_op_mode *op_mode __maybe_unused = |
2369 | (struct iwl_op_mode *)mvm_r; | 2362 | (struct iwl_op_mode *)mvm_r; |
2370 | struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); | 2363 | struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); |
2371 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 2364 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
2372 | struct iwl_lq_sta *lq_sta = mvm_sta; | 2365 | struct iwl_lq_sta *lq_sta = mvm_sta; |
2373 | 2366 | ||
2374 | /* Get max rate if user set max rate */ | 2367 | /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */ |
2375 | if (lq_sta) { | ||
2376 | lq_sta->max_rate_idx = txrc->max_rate_idx; | ||
2377 | if ((sband->band == IEEE80211_BAND_5GHZ) && | ||
2378 | (lq_sta->max_rate_idx != -1)) | ||
2379 | lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE; | ||
2380 | if ((lq_sta->max_rate_idx < 0) || | ||
2381 | (lq_sta->max_rate_idx >= IWL_RATE_COUNT)) | ||
2382 | lq_sta->max_rate_idx = -1; | ||
2383 | } | ||
2384 | 2368 | ||
2385 | /* Treat uninitialized rate scaling data same as non-existing. */ | 2369 | /* Treat uninitialized rate scaling data same as non-existing. */ |
2386 | if (lq_sta && !lq_sta->pers.drv) { | 2370 | if (lq_sta && !lq_sta->pers.drv) { |
@@ -2581,7 +2565,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2581 | * previous packets? Need to have IEEE 802.1X auth succeed immediately | 2565 | * previous packets? Need to have IEEE 802.1X auth succeed immediately |
2582 | * after assoc.. */ | 2566 | * after assoc.. */ |
2583 | 2567 | ||
2584 | lq_sta->max_rate_idx = -1; | ||
2585 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; | 2568 | lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; |
2586 | lq_sta->band = sband->band; | 2569 | lq_sta->band = sband->band; |
2587 | /* | 2570 | /* |
@@ -2610,9 +2593,16 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2610 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; | 2593 | lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; |
2611 | 2594 | ||
2612 | lq_sta->is_vht = false; | 2595 | lq_sta->is_vht = false; |
2596 | if (mvm->cfg->ht_params->ldpc && | ||
2597 | (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)) | ||
2598 | lq_sta->ldpc = true; | ||
2613 | } else { | 2599 | } else { |
2614 | rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); | 2600 | rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); |
2615 | lq_sta->is_vht = true; | 2601 | lq_sta->is_vht = true; |
2602 | |||
2603 | if (mvm->cfg->ht_params->ldpc && | ||
2604 | (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC)) | ||
2605 | lq_sta->ldpc = true; | ||
2616 | } | 2606 | } |
2617 | 2607 | ||
2618 | lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, | 2608 | lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, |
@@ -2622,11 +2612,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, | |||
2622 | lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, | 2612 | lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, |
2623 | BITS_PER_LONG); | 2613 | BITS_PER_LONG); |
2624 | 2614 | ||
2625 | IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n", | 2615 | IWL_DEBUG_RATE(mvm, |
2616 | "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d\n", | ||
2626 | lq_sta->active_legacy_rate, | 2617 | lq_sta->active_legacy_rate, |
2627 | lq_sta->active_siso_rate, | 2618 | lq_sta->active_siso_rate, |
2628 | lq_sta->active_mimo2_rate, | 2619 | lq_sta->active_mimo2_rate, |
2629 | lq_sta->is_vht); | 2620 | lq_sta->is_vht, lq_sta->ldpc); |
2630 | IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", | 2621 | IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", |
2631 | lq_sta->max_legacy_rate_idx, | 2622 | lq_sta->max_legacy_rate_idx, |
2632 | lq_sta->max_siso_rate_idx, | 2623 | lq_sta->max_siso_rate_idx, |
@@ -3032,8 +3023,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file, | |||
3032 | (is_ht20(rate)) ? "20MHz" : | 3023 | (is_ht20(rate)) ? "20MHz" : |
3033 | (is_ht40(rate)) ? "40MHz" : | 3024 | (is_ht40(rate)) ? "40MHz" : |
3034 | (is_ht80(rate)) ? "80Mhz" : "BAD BW"); | 3025 | (is_ht80(rate)) ? "80Mhz" : "BAD BW"); |
3035 | desc += sprintf(buff+desc, " %s %s\n", | 3026 | desc += sprintf(buff+desc, " %s %s %s\n", |
3036 | (rate->sgi) ? "SGI" : "NGI", | 3027 | (rate->sgi) ? "SGI" : "NGI", |
3028 | (rate->ldpc) ? "LDPC" : "BCC", | ||
3037 | (lq_sta->is_agg) ? "AGG on" : ""); | 3029 | (lq_sta->is_agg) ? "AGG on" : ""); |
3038 | } | 3030 | } |
3039 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", | 3031 | desc += sprintf(buff+desc, "last tx rate=0x%X\n", |
@@ -3181,7 +3173,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file, | |||
3181 | "%s,", column_name[col]); | 3173 | "%s,", column_name[col]); |
3182 | 3174 | ||
3183 | for (rate = 0; rate < IWL_RATE_COUNT; rate++) { | 3175 | for (rate = 0; rate < IWL_RATE_COUNT; rate++) { |
3184 | stats = &(lq_sta->tx_stats[col][rate]); | 3176 | stats = &(lq_sta->pers.tx_stats[col][rate]); |
3185 | pos += scnprintf(pos, endpos - pos, | 3177 | pos += scnprintf(pos, endpos - pos, |
3186 | "%llu/%llu,", | 3178 | "%llu/%llu,", |
3187 | stats->success, | 3179 | stats->success, |
@@ -3200,7 +3192,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_write(struct file *file, | |||
3200 | size_t count, loff_t *ppos) | 3192 | size_t count, loff_t *ppos) |
3201 | { | 3193 | { |
3202 | struct iwl_lq_sta *lq_sta = file->private_data; | 3194 | struct iwl_lq_sta *lq_sta = file->private_data; |
3203 | memset(lq_sta->tx_stats, 0, sizeof(lq_sta->tx_stats)); | 3195 | memset(lq_sta->pers.tx_stats, 0, sizeof(lq_sta->pers.tx_stats)); |
3204 | 3196 | ||
3205 | return count; | 3197 | return count; |
3206 | } | 3198 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h index f27b9d687a25..95c4b960fd71 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rs.h +++ b/drivers/net/wireless/iwlwifi/mvm/rs.h | |||
@@ -207,6 +207,7 @@ struct rs_rate { | |||
207 | u8 ant; | 207 | u8 ant; |
208 | u32 bw; | 208 | u32 bw; |
209 | bool sgi; | 209 | bool sgi; |
210 | bool ldpc; | ||
210 | }; | 211 | }; |
211 | 212 | ||
212 | 213 | ||
@@ -329,10 +330,9 @@ struct iwl_lq_sta { | |||
329 | */ | 330 | */ |
330 | u64 last_tx; | 331 | u64 last_tx; |
331 | bool is_vht; | 332 | bool is_vht; |
333 | bool ldpc; /* LDPC Rx is supported by the STA */ | ||
332 | enum ieee80211_band band; | 334 | enum ieee80211_band band; |
333 | 335 | ||
334 | struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; | ||
335 | |||
336 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ | 336 | /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ |
337 | unsigned long active_legacy_rate; | 337 | unsigned long active_legacy_rate; |
338 | unsigned long active_siso_rate; | 338 | unsigned long active_siso_rate; |
@@ -343,7 +343,6 @@ struct iwl_lq_sta { | |||
343 | u8 max_siso_rate_idx; | 343 | u8 max_siso_rate_idx; |
344 | u8 max_mimo2_rate_idx; | 344 | u8 max_mimo2_rate_idx; |
345 | 345 | ||
346 | s8 max_rate_idx; /* Max rate set by user */ | ||
347 | u8 missed_rate_counter; | 346 | u8 missed_rate_counter; |
348 | 347 | ||
349 | struct iwl_lq_cmd lq; | 348 | struct iwl_lq_cmd lq; |
@@ -361,11 +360,14 @@ struct iwl_lq_sta { | |||
361 | int tpc_reduce; | 360 | int tpc_reduce; |
362 | 361 | ||
363 | /* persistent fields - initialized only once - keep last! */ | 362 | /* persistent fields - initialized only once - keep last! */ |
364 | struct { | 363 | struct lq_sta_pers { |
365 | #ifdef CONFIG_MAC80211_DEBUGFS | 364 | #ifdef CONFIG_MAC80211_DEBUGFS |
366 | u32 dbg_fixed_rate; | 365 | u32 dbg_fixed_rate; |
367 | u8 dbg_fixed_txp_reduction; | 366 | u8 dbg_fixed_txp_reduction; |
368 | #endif | 367 | #endif |
368 | u8 chains; | ||
369 | s8 chain_signal[IEEE80211_MAX_CHAINS]; | ||
370 | struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT]; | ||
369 | struct iwl_mvm *drv; | 371 | struct iwl_mvm *drv; |
370 | } pers; | 372 | } pers; |
371 | }; | 373 | }; |
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c index bf9c63dc4a7d..09545f23b24f 100644 --- a/drivers/net/wireless/iwlwifi/mvm/scan.c +++ b/drivers/net/wireless/iwlwifi/mvm/scan.c | |||
@@ -160,8 +160,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid, | |||
160 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) | 160 | static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) |
161 | { | 161 | { |
162 | if (band == IEEE80211_BAND_2GHZ) | 162 | if (band == IEEE80211_BAND_2GHZ) |
163 | return 30 + 3 * (n_ssids + 1); | 163 | return 20 + 3 * (n_ssids + 1); |
164 | return 20 + 2 * (n_ssids + 1); | 164 | return 10 + 2 * (n_ssids + 1); |
165 | } | 165 | } |
166 | 166 | ||
167 | static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) | 167 | static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c index f88410c7cbfb..7eb78e2c240a 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sf.c +++ b/drivers/net/wireless/iwlwifi/mvm/sf.c | |||
@@ -179,6 +179,10 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id, | |||
179 | struct ieee80211_sta *sta; | 179 | struct ieee80211_sta *sta; |
180 | int ret = 0; | 180 | int ret = 0; |
181 | 181 | ||
182 | if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF && | ||
183 | mvm->cfg->disable_dummy_notification) | ||
184 | sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF); | ||
185 | |||
182 | /* | 186 | /* |
183 | * If an associated AP sta changed its antenna configuration, the state | 187 | * If an associated AP sta changed its antenna configuration, the state |
184 | * will remain FULL_ON but SF parameters need to be reconsidered. | 188 | * will remain FULL_ON but SF parameters need to be reconsidered. |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index dd9f3a4347f6..666f16b4bed9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -948,8 +948,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
948 | } | 948 | } |
949 | 949 | ||
950 | tid_data->ssn = 0xffff; | 950 | tid_data->ssn = 0xffff; |
951 | tid_data->state = IWL_AGG_OFF; | ||
952 | mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE; | ||
953 | spin_unlock_bh(&mvmsta->lock); | ||
954 | |||
955 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
956 | |||
957 | iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); | ||
958 | |||
951 | iwl_trans_txq_disable(mvm->trans, txq_id, true); | 959 | iwl_trans_txq_disable(mvm->trans, txq_id, true); |
952 | /* fall through */ | 960 | return 0; |
953 | case IWL_AGG_STARTING: | 961 | case IWL_AGG_STARTING: |
954 | case IWL_EMPTYING_HW_QUEUE_ADDBA: | 962 | case IWL_EMPTYING_HW_QUEUE_ADDBA: |
955 | /* | 963 | /* |
@@ -1003,6 +1011,8 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
1003 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) | 1011 | if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) |
1004 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); | 1012 | IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); |
1005 | 1013 | ||
1014 | iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false); | ||
1015 | |||
1006 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); | 1016 | iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); |
1007 | } | 1017 | } |
1008 | 1018 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c new file mode 100644 index 000000000000..66c82df2d0a1 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * This file is provided under a dual BSD/GPLv2 license. When using or | ||
4 | * redistributing this file, you may do so under either license. | ||
5 | * | ||
6 | * GPL LICENSE SUMMARY | ||
7 | * | ||
8 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of version 2 of the GNU General Public License as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||
22 | * USA | ||
23 | * | ||
24 | * The full GNU General Public License is included in this distribution | ||
25 | * in the file called COPYING. | ||
26 | * | ||
27 | * Contact Information: | ||
28 | * Intel Linux Wireless <ilw@linux.intel.com> | ||
29 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
30 | * | ||
31 | * BSD LICENSE | ||
32 | * | ||
33 | * Copyright(c) 2014 Intel Mobile Communications GmbH | ||
34 | * All rights reserved. | ||
35 | * | ||
36 | * Redistribution and use in source and binary forms, with or without | ||
37 | * modification, are permitted provided that the following conditions | ||
38 | * are met: | ||
39 | * | ||
40 | * * Redistributions of source code must retain the above copyright | ||
41 | * notice, this list of conditions and the following disclaimer. | ||
42 | * * Redistributions in binary form must reproduce the above copyright | ||
43 | * notice, this list of conditions and the following disclaimer in | ||
44 | * the documentation and/or other materials provided with the | ||
45 | * distribution. | ||
46 | * * Neither the name Intel Corporation nor the names of its | ||
47 | * contributors may be used to endorse or promote products derived | ||
48 | * from this software without specific prior written permission. | ||
49 | * | ||
50 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
51 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
52 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
53 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
54 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
55 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
56 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
57 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
58 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
59 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
60 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
61 | * | ||
62 | *****************************************************************************/ | ||
63 | |||
64 | #include "mvm.h" | ||
65 | #include "time-event.h" | ||
66 | |||
67 | void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm) | ||
68 | { | ||
69 | struct ieee80211_sta *sta; | ||
70 | struct iwl_mvm_sta *mvmsta; | ||
71 | int i; | ||
72 | |||
73 | lockdep_assert_held(&mvm->mutex); | ||
74 | |||
75 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { | ||
76 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], | ||
77 | lockdep_is_held(&mvm->mutex)); | ||
78 | if (!sta || IS_ERR(sta) || !sta->tdls) | ||
79 | continue; | ||
80 | |||
81 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
82 | ieee80211_tdls_oper_request(mvmsta->vif, sta->addr, | ||
83 | NL80211_TDLS_TEARDOWN, | ||
84 | WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED, | ||
85 | GFP_KERNEL); | ||
86 | } | ||
87 | } | ||
88 | |||
89 | int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
90 | { | ||
91 | struct ieee80211_sta *sta; | ||
92 | struct iwl_mvm_sta *mvmsta; | ||
93 | int count = 0; | ||
94 | int i; | ||
95 | |||
96 | lockdep_assert_held(&mvm->mutex); | ||
97 | |||
98 | for (i = 0; i < IWL_MVM_STATION_COUNT; i++) { | ||
99 | sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], | ||
100 | lockdep_is_held(&mvm->mutex)); | ||
101 | if (!sta || IS_ERR(sta) || !sta->tdls) | ||
102 | continue; | ||
103 | |||
104 | if (vif) { | ||
105 | mvmsta = iwl_mvm_sta_from_mac80211(sta); | ||
106 | if (mvmsta->vif != vif) | ||
107 | continue; | ||
108 | } | ||
109 | |||
110 | count++; | ||
111 | } | ||
112 | |||
113 | return count; | ||
114 | } | ||
115 | |||
116 | void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | ||
117 | bool sta_added) | ||
118 | { | ||
119 | int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif); | ||
120 | |||
121 | /* | ||
122 | * Disable ps when the first TDLS sta is added and re-enable it | ||
123 | * when the last TDLS sta is removed | ||
124 | */ | ||
125 | if ((tdls_sta_cnt == 1 && sta_added) || | ||
126 | (tdls_sta_cnt == 0 && !sta_added)) | ||
127 | iwl_mvm_power_update_mac(mvm); | ||
128 | } | ||
129 | |||
130 | void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw, | ||
131 | struct ieee80211_vif *vif) | ||
132 | { | ||
133 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | ||
134 | u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int; | ||
135 | |||
136 | /* | ||
137 | * iwl_mvm_protect_session() reads directly from the device | ||
138 | * (the system time), so make sure it is available. | ||
139 | */ | ||
140 | if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS)) | ||
141 | return; | ||
142 | |||
143 | mutex_lock(&mvm->mutex); | ||
144 | /* Protect the session to hear the TDLS setup response on the channel */ | ||
145 | iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true); | ||
146 | mutex_unlock(&mvm->mutex); | ||
147 | |||
148 | iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS); | ||
149 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c index 447d3b1003df..b7f9e61d14e2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.c +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c | |||
@@ -700,9 +700,9 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm) | |||
700 | iwl_mvm_roc_finished(mvm); | 700 | iwl_mvm_roc_finished(mvm); |
701 | } | 701 | } |
702 | 702 | ||
703 | int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm, | 703 | int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, |
704 | struct ieee80211_vif *vif, | 704 | struct ieee80211_vif *vif, |
705 | u32 duration, u32 apply_time) | 705 | u32 duration, u32 apply_time) |
706 | { | 706 | { |
707 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 707 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
708 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; | 708 | struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; |
@@ -711,14 +711,14 @@ int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm, | |||
711 | lockdep_assert_held(&mvm->mutex); | 711 | lockdep_assert_held(&mvm->mutex); |
712 | 712 | ||
713 | if (te_data->running) { | 713 | if (te_data->running) { |
714 | IWL_DEBUG_TE(mvm, "CS NOA is already scheduled\n"); | 714 | IWL_DEBUG_TE(mvm, "CS period is already scheduled\n"); |
715 | return -EBUSY; | 715 | return -EBUSY; |
716 | } | 716 | } |
717 | 717 | ||
718 | time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); | 718 | time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); |
719 | time_cmd.id_and_color = | 719 | time_cmd.id_and_color = |
720 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); | 720 | cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); |
721 | time_cmd.id = cpu_to_le32(TE_P2P_GO_CSA_NOA); | 721 | time_cmd.id = cpu_to_le32(TE_CHANNEL_SWITCH_PERIOD); |
722 | time_cmd.apply_time = cpu_to_le32(apply_time); | 722 | time_cmd.apply_time = cpu_to_le32(apply_time); |
723 | time_cmd.max_frags = TE_V2_FRAG_NONE; | 723 | time_cmd.max_frags = TE_V2_FRAG_NONE; |
724 | time_cmd.duration = cpu_to_le32(duration); | 724 | time_cmd.duration = cpu_to_le32(duration); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h index bee3b2446b35..b350e47e19da 100644 --- a/drivers/net/wireless/iwlwifi/mvm/time-event.h +++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h | |||
@@ -219,7 +219,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm, | |||
219 | void iwl_mvm_roc_done_wk(struct work_struct *wk); | 219 | void iwl_mvm_roc_done_wk(struct work_struct *wk); |
220 | 220 | ||
221 | /** | 221 | /** |
222 | * iwl_mvm_schedule_csa_noa - request NoA for channel switch | 222 | * iwl_mvm_schedule_csa_period - request channel switch absence period |
223 | * @mvm: the mvm component | 223 | * @mvm: the mvm component |
224 | * @vif: the virtual interface for which the channel switch is issued | 224 | * @vif: the virtual interface for which the channel switch is issued |
225 | * @duration: the duration of the NoA in TU. | 225 | * @duration: the duration of the NoA in TU. |
@@ -228,9 +228,9 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk); | |||
228 | * This function is used to schedule NoA time event and is used to perform | 228 | * This function is used to schedule NoA time event and is used to perform |
229 | * the channel switch flow. | 229 | * the channel switch flow. |
230 | */ | 230 | */ |
231 | int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm, | 231 | int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm, |
232 | struct ieee80211_vif *vif, | 232 | struct ieee80211_vif *vif, |
233 | u32 duration, u32 apply_time); | 233 | u32 duration, u32 apply_time); |
234 | 234 | ||
235 | /** | 235 | /** |
236 | * iwl_mvm_te_scheduled - check if the fw received the TE cmd | 236 | * iwl_mvm_te_scheduled - check if the fw received the TE cmd |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c index c3e1fe4282f1..c750ca7b8269 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tt.c +++ b/drivers/net/wireless/iwlwifi/mvm/tt.c | |||
@@ -69,275 +69,99 @@ | |||
69 | #include "iwl-csr.h" | 69 | #include "iwl-csr.h" |
70 | #include "iwl-prph.h" | 70 | #include "iwl-prph.h" |
71 | 71 | ||
72 | #define OTP_DTS_DIODE_DEVIATION 96 /*in words*/ | 72 | #define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ |
73 | /* VBG - Voltage Band Gap error data (temperature offset) */ | ||
74 | #define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2) | ||
75 | #define MEAS_VBG_MIN_VAL 2300 | ||
76 | #define MEAS_VBG_MAX_VAL 3000 | ||
77 | #define MEAS_VBG_DEFAULT_VAL 2700 | ||
78 | #define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE) | ||
79 | #define MIN_TEMPERATURE 0 | ||
80 | #define MAX_TEMPERATURE 125 | ||
81 | #define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1) | ||
82 | #define PTAT_DIGITAL_VALUE_MIN_VALUE 0 | ||
83 | #define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF | ||
84 | #define DTS_VREFS_NUM 5 | ||
85 | static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags) | ||
86 | { | ||
87 | return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >> | ||
88 | DTS_DIODE_REG_FLAGS_VREFS_ID_POS; | ||
89 | } | ||
90 | 73 | ||
91 | #define CALC_VREFS_MIN_DIFF 43 | 74 | static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) |
92 | #define CALC_VREFS_MAX_DIFF 51 | ||
93 | #define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF) | ||
94 | #define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF | ||
95 | #define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23 | ||
96 | |||
97 | /* | ||
98 | * @digital_value: The diode's digital-value sampled (temperature/voltage) | ||
99 | * @vref_low: The lower voltage-reference (the vref just below the diode's | ||
100 | * sampled digital-value) | ||
101 | * @vref_high: The higher voltage-reference (the vref just above the diode's | ||
102 | * sampled digital-value) | ||
103 | * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref) | ||
104 | * bits[6:2]: Reserved. | ||
105 | * bits[7:7]: Indicates completion of at least 1 successful sample | ||
106 | * since last DTS reset. | ||
107 | */ | ||
108 | struct iwl_mvm_dts_diode_bits { | ||
109 | u8 digital_value; | ||
110 | u8 vref_low; | ||
111 | u8 vref_high; | ||
112 | u8 flags; | ||
113 | } __packed; | ||
114 | |||
115 | union dts_diode_results { | ||
116 | u32 reg_value; | ||
117 | struct iwl_mvm_dts_diode_bits bits; | ||
118 | } __packed; | ||
119 | |||
120 | static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm) | ||
121 | { | 75 | { |
122 | struct iwl_nvm_section calib_sec; | 76 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; |
123 | const __le16 *calib; | ||
124 | u16 vbg; | ||
125 | |||
126 | /* TODO: move parsing to NVM code */ | ||
127 | calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION]; | ||
128 | calib = (__le16 *)calib_sec.data; | ||
129 | 77 | ||
130 | vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]); | 78 | if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) |
79 | return; | ||
131 | 80 | ||
132 | if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL) | 81 | IWL_ERR(mvm, "Enter CT Kill\n"); |
133 | vbg = MEAS_VBG_DEFAULT_VAL; | 82 | iwl_mvm_set_hw_ctkill_state(mvm, true); |
134 | 83 | ||
135 | return vbg; | 84 | /* Don't schedule an exit work if we're in test mode, since |
85 | * the temperature will not change unless we manually set it | ||
86 | * again (or disable testing). | ||
87 | */ | ||
88 | if (!mvm->temperature_test) | ||
89 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | ||
90 | round_jiffies_relative(duration * HZ)); | ||
136 | } | 91 | } |
137 | 92 | ||
138 | static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm) | 93 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) |
139 | { | 94 | { |
140 | const u8 *calib; | 95 | if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) |
141 | u8 ptat, pa1, pa2, median; | 96 | return; |
142 | |||
143 | /* TODO: move parsing to NVM code */ | ||
144 | calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data; | ||
145 | ptat = calib[OTP_DTS_DIODE_DEVIATION * 2]; | ||
146 | pa1 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 1]; | ||
147 | pa2 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 2]; | ||
148 | |||
149 | /* get the median: */ | ||
150 | if (ptat > pa1) { | ||
151 | if (ptat > pa2) | ||
152 | median = (pa1 > pa2) ? pa1 : pa2; | ||
153 | else | ||
154 | median = ptat; | ||
155 | } else { | ||
156 | if (pa1 > pa2) | ||
157 | median = (ptat > pa2) ? ptat : pa2; | ||
158 | else | ||
159 | median = pa1; | ||
160 | } | ||
161 | 97 | ||
162 | return ptat - median; | 98 | IWL_ERR(mvm, "Exit CT Kill\n"); |
99 | iwl_mvm_set_hw_ctkill_state(mvm, false); | ||
163 | } | 100 | } |
164 | 101 | ||
165 | static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value) | 102 | static bool iwl_mvm_temp_notif(struct iwl_notif_wait_data *notif_wait, |
103 | struct iwl_rx_packet *pkt, void *data) | ||
166 | { | 104 | { |
167 | /* Calibrate the PTAT digital value, based on PTAT deviation data: */ | 105 | struct iwl_mvm *mvm = |
168 | s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm); | 106 | container_of(notif_wait, struct iwl_mvm, notif_wait); |
107 | int *temp = data; | ||
108 | struct iwl_dts_measurement_notif *notif; | ||
109 | int len = iwl_rx_packet_payload_len(pkt); | ||
110 | |||
111 | if (WARN_ON_ONCE(len != sizeof(*notif))) { | ||
112 | IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n"); | ||
113 | return true; | ||
114 | } | ||
169 | 115 | ||
170 | if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE) | 116 | notif = (void *)pkt->data; |
171 | new_val = PTAT_DIGITAL_VALUE_MAX_VALUE; | ||
172 | else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE) | ||
173 | new_val = PTAT_DIGITAL_VALUE_MIN_VALUE; | ||
174 | 117 | ||
175 | return new_val; | 118 | *temp = le32_to_cpu(notif->temp); |
176 | } | ||
177 | 119 | ||
178 | static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm, | 120 | /* shouldn't be negative, but since it's s32, make sure it isn't */ |
179 | union dts_diode_results *avg_ptat) | 121 | if (WARN_ON_ONCE(*temp < 0)) |
180 | { | 122 | *temp = 0; |
181 | u8 vrefs_results[DTS_VREFS_NUM]; | ||
182 | u8 low_vref_index = 0, flags; | ||
183 | u32 reg; | ||
184 | |||
185 | reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG); | ||
186 | memcpy(vrefs_results, ®, sizeof(reg)); | ||
187 | reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG); | ||
188 | vrefs_results[4] = reg & 0xff; | ||
189 | |||
190 | if (avg_ptat->bits.digital_value < vrefs_results[0] || | ||
191 | avg_ptat->bits.digital_value > vrefs_results[4]) | ||
192 | return false; | ||
193 | |||
194 | if (avg_ptat->bits.digital_value > vrefs_results[3]) | ||
195 | low_vref_index = 3; | ||
196 | else if (avg_ptat->bits.digital_value > vrefs_results[2]) | ||
197 | low_vref_index = 2; | ||
198 | else if (avg_ptat->bits.digital_value > vrefs_results[1]) | ||
199 | low_vref_index = 1; | ||
200 | |||
201 | avg_ptat->bits.vref_low = vrefs_results[low_vref_index]; | ||
202 | avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1]; | ||
203 | flags = avg_ptat->bits.flags; | ||
204 | avg_ptat->bits.flags = | ||
205 | (flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) | | ||
206 | (low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID); | ||
207 | return true; | ||
208 | } | ||
209 | 123 | ||
210 | /* | 124 | IWL_DEBUG_TEMP(mvm, "DTS_MEASUREMENT_NOTIFICATION - %d\n", *temp); |
211 | * return true it the results are valid, and false otherwise. | 125 | return true; |
212 | */ | ||
213 | static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm, | ||
214 | union dts_diode_results *avg_ptat) | ||
215 | { | ||
216 | u32 reg; | ||
217 | u8 tmp; | ||
218 | |||
219 | /* fill the diode value and pass_once with avg-reg results */ | ||
220 | reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG); | ||
221 | reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE; | ||
222 | avg_ptat->reg_value = reg; | ||
223 | |||
224 | /* calibrate the PTAT digital value */ | ||
225 | tmp = avg_ptat->bits.digital_value; | ||
226 | tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp); | ||
227 | avg_ptat->bits.digital_value = tmp; | ||
228 | |||
229 | /* | ||
230 | * fill vrefs fields, based on the avgVrefs results | ||
231 | * and the diode value | ||
232 | */ | ||
233 | return dts_get_adjacent_vrefs(mvm, avg_ptat) && | ||
234 | DTS_DIODE_VALID(avg_ptat->bits.flags); | ||
235 | } | 126 | } |
236 | 127 | ||
237 | static s32 calculate_nic_temperature(union dts_diode_results avg_ptat, | 128 | static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm) |
238 | u16 volt_band_gap) | ||
239 | { | 129 | { |
240 | u32 tmp_result; | 130 | struct iwl_dts_measurement_cmd cmd = { |
241 | u8 vrefs_diff; | 131 | .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP), |
242 | /* | ||
243 | * For temperature calculation (at the end, shift right by 23) | ||
244 | * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) } | ||
245 | * (D2-D1) == 43 44 45 46 47 48 49 50 51 | ||
246 | */ | ||
247 | static const u16 calc_lut[CALC_LUT_SIZE] = { | ||
248 | 2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828, | ||
249 | }; | 132 | }; |
250 | 133 | ||
251 | /* | 134 | return iwl_mvm_send_cmd_pdu(mvm, CMD_DTS_MEASUREMENT_TRIGGER, 0, |
252 | * The diff between the high and low voltage-references is assumed | 135 | sizeof(cmd), &cmd); |
253 | * to be strictly be in range of [60,68] | ||
254 | */ | ||
255 | vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low; | ||
256 | |||
257 | if (vrefs_diff < CALC_VREFS_MIN_DIFF || | ||
258 | vrefs_diff > CALC_VREFS_MAX_DIFF) | ||
259 | return TEMPERATURE_ERROR; | ||
260 | |||
261 | /* calculate the result: */ | ||
262 | tmp_result = | ||
263 | vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9); | ||
264 | tmp_result += avg_ptat.bits.digital_value; | ||
265 | tmp_result -= avg_ptat.bits.vref_high; | ||
266 | |||
267 | /* multiply by the LUT value (based on the diff) */ | ||
268 | tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET]; | ||
269 | |||
270 | /* | ||
271 | * Get the BandGap (the voltage refereces source) error data | ||
272 | * (temperature offset) | ||
273 | */ | ||
274 | tmp_result *= volt_band_gap; | ||
275 | |||
276 | /* | ||
277 | * here, tmp_result value can be up to 32-bits. We want to right-shift | ||
278 | * it *without* sign-extend. | ||
279 | */ | ||
280 | tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET; | ||
281 | |||
282 | /* | ||
283 | * at this point, tmp_result should be in the range: | ||
284 | * 200 <= tmp_result <= 365 | ||
285 | */ | ||
286 | return (s16)tmp_result - 240; | ||
287 | } | ||
288 | |||
289 | static s32 check_nic_temperature(struct iwl_mvm *mvm) | ||
290 | { | ||
291 | u16 volt_band_gap; | ||
292 | union dts_diode_results avg_ptat; | ||
293 | |||
294 | volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm); | ||
295 | |||
296 | /* disable DTS */ | ||
297 | iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0); | ||
298 | |||
299 | /* SV initialization */ | ||
300 | iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1); | ||
301 | iwl_write_prph(mvm->trans, DTSC_CFG_MODE, | ||
302 | DTSC_CFG_MODE_PERIODIC); | ||
303 | |||
304 | /* wait for results */ | ||
305 | msleep(100); | ||
306 | if (!dts_read_ptat_avg_results(mvm, &avg_ptat)) | ||
307 | return TEMPERATURE_ERROR; | ||
308 | |||
309 | /* disable DTS */ | ||
310 | iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0); | ||
311 | |||
312 | return calculate_nic_temperature(avg_ptat, volt_band_gap); | ||
313 | } | 136 | } |
314 | 137 | ||
315 | static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) | 138 | static int iwl_mvm_get_temp(struct iwl_mvm *mvm) |
316 | { | 139 | { |
317 | u32 duration = mvm->thermal_throttle.params->ct_kill_duration; | 140 | struct iwl_notification_wait wait_temp_notif; |
141 | static const u8 temp_notif[] = { DTS_MEASUREMENT_NOTIFICATION }; | ||
142 | int ret, temp; | ||
318 | 143 | ||
319 | if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | 144 | lockdep_assert_held(&mvm->mutex); |
320 | return; | ||
321 | 145 | ||
322 | IWL_ERR(mvm, "Enter CT Kill\n"); | 146 | iwl_init_notification_wait(&mvm->notif_wait, &wait_temp_notif, |
323 | iwl_mvm_set_hw_ctkill_state(mvm, true); | 147 | temp_notif, ARRAY_SIZE(temp_notif), |
148 | iwl_mvm_temp_notif, &temp); | ||
324 | 149 | ||
325 | /* Don't schedule an exit work if we're in test mode, since | 150 | ret = iwl_mvm_get_temp_cmd(mvm); |
326 | * the temperature will not change unless we manually set it | 151 | if (ret) { |
327 | * again (or disable testing). | 152 | IWL_ERR(mvm, "Failed to get the temperature (err=%d)\n", ret); |
328 | */ | 153 | iwl_remove_notification(&mvm->notif_wait, &wait_temp_notif); |
329 | if (!mvm->temperature_test) | 154 | return ret; |
330 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | 155 | } |
331 | round_jiffies_relative(duration * HZ)); | ||
332 | } | ||
333 | 156 | ||
334 | static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) | 157 | ret = iwl_wait_notification(&mvm->notif_wait, &wait_temp_notif, |
335 | { | 158 | IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT); |
336 | if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) | 159 | if (ret) { |
337 | return; | 160 | IWL_ERR(mvm, "Getting the temperature timed out\n"); |
161 | return ret; | ||
162 | } | ||
338 | 163 | ||
339 | IWL_ERR(mvm, "Exit CT Kill\n"); | 164 | return temp; |
340 | iwl_mvm_set_hw_ctkill_state(mvm, false); | ||
341 | } | 165 | } |
342 | 166 | ||
343 | static void check_exit_ctkill(struct work_struct *work) | 167 | static void check_exit_ctkill(struct work_struct *work) |
@@ -352,28 +176,36 @@ static void check_exit_ctkill(struct work_struct *work) | |||
352 | 176 | ||
353 | duration = tt->params->ct_kill_duration; | 177 | duration = tt->params->ct_kill_duration; |
354 | 178 | ||
179 | mutex_lock(&mvm->mutex); | ||
180 | |||
181 | if (__iwl_mvm_mac_start(mvm)) | ||
182 | goto reschedule; | ||
183 | |||
355 | /* make sure the device is available for direct read/writes */ | 184 | /* make sure the device is available for direct read/writes */ |
356 | if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) | 185 | if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) { |
186 | __iwl_mvm_mac_stop(mvm); | ||
357 | goto reschedule; | 187 | goto reschedule; |
188 | } | ||
358 | 189 | ||
359 | iwl_trans_start_hw(mvm->trans); | 190 | temp = iwl_mvm_get_temp(mvm); |
360 | temp = check_nic_temperature(mvm); | ||
361 | iwl_trans_stop_device(mvm->trans); | ||
362 | 191 | ||
363 | iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL); | 192 | iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL); |
364 | 193 | ||
365 | if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) { | 194 | __iwl_mvm_mac_stop(mvm); |
366 | IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n"); | 195 | |
196 | if (temp < 0) | ||
367 | goto reschedule; | 197 | goto reschedule; |
368 | } | 198 | |
369 | IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp); | 199 | IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp); |
370 | 200 | ||
371 | if (temp <= tt->params->ct_kill_exit) { | 201 | if (temp <= tt->params->ct_kill_exit) { |
202 | mutex_unlock(&mvm->mutex); | ||
372 | iwl_mvm_exit_ctkill(mvm); | 203 | iwl_mvm_exit_ctkill(mvm); |
373 | return; | 204 | return; |
374 | } | 205 | } |
375 | 206 | ||
376 | reschedule: | 207 | reschedule: |
208 | mutex_unlock(&mvm->mutex); | ||
377 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, | 209 | schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, |
378 | round_jiffies(duration * HZ)); | 210 | round_jiffies(duration * HZ)); |
379 | } | 211 | } |
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index ed0919465e0e..c67296efa04d 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c | |||
@@ -213,7 +213,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, | |||
213 | 213 | ||
214 | if (info->band == IEEE80211_BAND_2GHZ && | 214 | if (info->band == IEEE80211_BAND_2GHZ && |
215 | !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) | 215 | !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) |
216 | rate_flags = BIT(ANT_A) << RATE_MCS_ANT_POS; | 216 | rate_flags = BIT(mvm->cfg->non_shared_ant) << RATE_MCS_ANT_POS; |
217 | else | 217 | else |
218 | rate_flags = | 218 | rate_flags = |
219 | BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; | 219 | BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c index b9d5049e52da..ca68c3ccf633 100644 --- a/drivers/net/wireless/iwlwifi/pcie/drv.c +++ b/drivers/net/wireless/iwlwifi/pcie/drv.c | |||
@@ -405,6 +405,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = { | |||
405 | 405 | ||
406 | /* 8000 Series */ | 406 | /* 8000 Series */ |
407 | {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, | 407 | {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, |
408 | {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, | ||
408 | {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, | 409 | {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, |
409 | #endif /* CONFIG_IWLMVM */ | 410 | #endif /* CONFIG_IWLMVM */ |
410 | 411 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index a4fedc4a7448..1aea6b66c594 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h | |||
@@ -257,6 +257,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) | |||
257 | * @cmd_queue - command queue number | 257 | * @cmd_queue - command queue number |
258 | * @rx_buf_size_8k: 8 kB RX buffer size | 258 | * @rx_buf_size_8k: 8 kB RX buffer size |
259 | * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) | 259 | * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) |
260 | * @scd_set_active: should the transport configure the SCD for HCMD queue | ||
260 | * @rx_page_order: page order for receive buffer size | 261 | * @rx_page_order: page order for receive buffer size |
261 | * @wd_timeout: queue watchdog timeout (jiffies) | 262 | * @wd_timeout: queue watchdog timeout (jiffies) |
262 | * @reg_lock: protect hw register access | 263 | * @reg_lock: protect hw register access |
@@ -306,6 +307,7 @@ struct iwl_trans_pcie { | |||
306 | 307 | ||
307 | bool rx_buf_size_8k; | 308 | bool rx_buf_size_8k; |
308 | bool bc_table_dword; | 309 | bool bc_table_dword; |
310 | bool scd_set_active; | ||
309 | u32 rx_page_order; | 311 | u32 rx_page_order; |
310 | 312 | ||
311 | const char *const *command_names; | 313 | const char *const *command_names; |
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 702f47fb16fe..7b7e2f223fb2 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c | |||
@@ -640,7 +640,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, | |||
640 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); | 640 | err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); |
641 | 641 | ||
642 | if (reclaim) { | 642 | if (reclaim) { |
643 | kfree(txq->entries[cmd_index].free_buf); | 643 | kzfree(txq->entries[cmd_index].free_buf); |
644 | txq->entries[cmd_index].free_buf = NULL; | 644 | txq->entries[cmd_index].free_buf = NULL; |
645 | } | 645 | } |
646 | 646 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 3076e0e9a490..ae99240dcde4 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -1171,6 +1171,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans, | |||
1171 | 1171 | ||
1172 | trans_pcie->command_names = trans_cfg->command_names; | 1172 | trans_pcie->command_names = trans_cfg->command_names; |
1173 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; | 1173 | trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; |
1174 | trans_pcie->scd_set_active = trans_cfg->scd_set_active; | ||
1174 | 1175 | ||
1175 | /* Initialize NAPI here - it should be before registering to mac80211 | 1176 | /* Initialize NAPI here - it should be before registering to mac80211 |
1176 | * in the opmode but after the HW struct is allocated. | 1177 | * in the opmode but after the HW struct is allocated. |
@@ -2189,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, | |||
2189 | */ | 2190 | */ |
2190 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) | 2191 | if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) |
2191 | trans->hw_rev = (trans->hw_rev & 0xfff0) | | 2192 | trans->hw_rev = (trans->hw_rev & 0xfff0) | |
2192 | ((trans->hw_rev << 2) & 0xc); | 2193 | (CSR_HW_REV_STEP(trans->hw_rev << 2)); |
2193 | 2194 | ||
2194 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; | 2195 | trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; |
2195 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), | 2196 | snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), |
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index a6336b4aa3a4..eb8e2984c5e9 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -620,8 +620,8 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) | |||
620 | /* De-alloc array of command/tx buffers */ | 620 | /* De-alloc array of command/tx buffers */ |
621 | if (txq_id == trans_pcie->cmd_queue) | 621 | if (txq_id == trans_pcie->cmd_queue) |
622 | for (i = 0; i < txq->q.n_window; i++) { | 622 | for (i = 0; i < txq->q.n_window; i++) { |
623 | kfree(txq->entries[i].cmd); | 623 | kzfree(txq->entries[i].cmd); |
624 | kfree(txq->entries[i].free_buf); | 624 | kzfree(txq->entries[i].free_buf); |
625 | } | 625 | } |
626 | 626 | ||
627 | /* De-alloc circular buffer of TFDs */ | 627 | /* De-alloc circular buffer of TFDs */ |
@@ -1080,7 +1080,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, | |||
1080 | fifo = cfg->fifo; | 1080 | fifo = cfg->fifo; |
1081 | 1081 | ||
1082 | /* Disable the scheduler prior configuring the cmd queue */ | 1082 | /* Disable the scheduler prior configuring the cmd queue */ |
1083 | if (txq_id == trans_pcie->cmd_queue) | 1083 | if (txq_id == trans_pcie->cmd_queue && |
1084 | trans_pcie->scd_set_active) | ||
1084 | iwl_scd_enable_set_active(trans, 0); | 1085 | iwl_scd_enable_set_active(trans, 0); |
1085 | 1086 | ||
1086 | /* Stop this Tx queue before configuring it */ | 1087 | /* Stop this Tx queue before configuring it */ |
@@ -1142,7 +1143,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn, | |||
1142 | SCD_QUEUE_STTS_REG_MSK); | 1143 | SCD_QUEUE_STTS_REG_MSK); |
1143 | 1144 | ||
1144 | /* enable the scheduler for this queue (only) */ | 1145 | /* enable the scheduler for this queue (only) */ |
1145 | if (txq_id == trans_pcie->cmd_queue) | 1146 | if (txq_id == trans_pcie->cmd_queue && |
1147 | trans_pcie->scd_set_active) | ||
1146 | iwl_scd_enable_set_active(trans, BIT(txq_id)); | 1148 | iwl_scd_enable_set_active(trans, BIT(txq_id)); |
1147 | } | 1149 | } |
1148 | 1150 | ||
@@ -1407,7 +1409,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, | |||
1407 | 1409 | ||
1408 | out_meta->flags = cmd->flags; | 1410 | out_meta->flags = cmd->flags; |
1409 | if (WARN_ON_ONCE(txq->entries[idx].free_buf)) | 1411 | if (WARN_ON_ONCE(txq->entries[idx].free_buf)) |
1410 | kfree(txq->entries[idx].free_buf); | 1412 | kzfree(txq->entries[idx].free_buf); |
1411 | txq->entries[idx].free_buf = dup_buf; | 1413 | txq->entries[idx].free_buf = dup_buf; |
1412 | 1414 | ||
1413 | trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); | 1415 | trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 1326f6121835..babbdc1ce741 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -2045,8 +2045,6 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
2045 | 2045 | ||
2046 | hw->flags = IEEE80211_HW_MFP_CAPABLE | | 2046 | hw->flags = IEEE80211_HW_MFP_CAPABLE | |
2047 | IEEE80211_HW_SIGNAL_DBM | | 2047 | IEEE80211_HW_SIGNAL_DBM | |
2048 | IEEE80211_HW_SUPPORTS_STATIC_SMPS | | ||
2049 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | | ||
2050 | IEEE80211_HW_AMPDU_AGGREGATION | | 2048 | IEEE80211_HW_AMPDU_AGGREGATION | |
2051 | IEEE80211_HW_WANT_MONITOR_VIF | | 2049 | IEEE80211_HW_WANT_MONITOR_VIF | |
2052 | IEEE80211_HW_QUEUE_CONTROL | | 2050 | IEEE80211_HW_QUEUE_CONTROL | |
@@ -2059,8 +2057,10 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2, | |||
2059 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | | 2057 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | |
2060 | WIPHY_FLAG_AP_UAPSD | | 2058 | WIPHY_FLAG_AP_UAPSD | |
2061 | WIPHY_FLAG_HAS_CHANNEL_SWITCH; | 2059 | WIPHY_FLAG_HAS_CHANNEL_SWITCH; |
2062 | hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; | 2060 | hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR | |
2063 | hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; | 2061 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE | |
2062 | NL80211_FEATURE_STATIC_SMPS | | ||
2063 | NL80211_FEATURE_DYNAMIC_SMPS; | ||
2064 | 2064 | ||
2065 | /* ask mac80211 to reserve space for magic */ | 2065 | /* ask mac80211 to reserve space for magic */ |
2066 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); | 2066 | hw->vif_data_size = sizeof(struct hwsim_vif_priv); |
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c index 06a2c215ef5e..40057079ffb9 100644 --- a/drivers/net/wireless/mwifiex/11n_rxreorder.c +++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c | |||
@@ -183,6 +183,15 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, | |||
183 | if (!tbl) | 183 | if (!tbl) |
184 | return; | 184 | return; |
185 | 185 | ||
186 | spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags); | ||
187 | priv->adapter->rx_locked = true; | ||
188 | if (priv->adapter->rx_processing) { | ||
189 | spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); | ||
190 | flush_workqueue(priv->adapter->rx_workqueue); | ||
191 | } else { | ||
192 | spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); | ||
193 | } | ||
194 | |||
186 | start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1); | 195 | start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1); |
187 | mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win); | 196 | mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win); |
188 | 197 | ||
@@ -194,6 +203,11 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, | |||
194 | 203 | ||
195 | kfree(tbl->rx_reorder_ptr); | 204 | kfree(tbl->rx_reorder_ptr); |
196 | kfree(tbl); | 205 | kfree(tbl); |
206 | |||
207 | spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags); | ||
208 | priv->adapter->rx_locked = false; | ||
209 | spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); | ||
210 | |||
197 | } | 211 | } |
198 | 212 | ||
199 | /* | 213 | /* |
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c4723b0f5757..0dd672954ad1 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c | |||
@@ -1936,13 +1936,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
1936 | 1936 | ||
1937 | wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); | 1937 | wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); |
1938 | 1938 | ||
1939 | if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && | ||
1940 | atomic_read(&priv->wmm.tx_pkts_queued) >= | ||
1941 | MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) { | ||
1942 | dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n"); | ||
1943 | return -EBUSY; | ||
1944 | } | ||
1945 | |||
1946 | /* Block scan request if scan operation or scan cleanup when interface | 1939 | /* Block scan request if scan operation or scan cleanup when interface |
1947 | * is disabled is in process | 1940 | * is disabled is in process |
1948 | */ | 1941 | */ |
@@ -1981,7 +1974,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
1981 | user_scan_cfg->chan_list[i].chan_number = chan->hw_value; | 1974 | user_scan_cfg->chan_list[i].chan_number = chan->hw_value; |
1982 | user_scan_cfg->chan_list[i].radio_type = chan->band; | 1975 | user_scan_cfg->chan_list[i].radio_type = chan->band; |
1983 | 1976 | ||
1984 | if (chan->flags & IEEE80211_CHAN_NO_IR) | 1977 | if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids) |
1985 | user_scan_cfg->chan_list[i].scan_type = | 1978 | user_scan_cfg->chan_list[i].scan_type = |
1986 | MWIFIEX_SCAN_TYPE_PASSIVE; | 1979 | MWIFIEX_SCAN_TYPE_PASSIVE; |
1987 | else | 1980 | else |
@@ -1991,6 +1984,11 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, | |||
1991 | user_scan_cfg->chan_list[i].scan_time = 0; | 1984 | user_scan_cfg->chan_list[i].scan_time = 0; |
1992 | } | 1985 | } |
1993 | 1986 | ||
1987 | if (priv->adapter->scan_chan_gap_enabled && | ||
1988 | mwifiex_is_any_intf_active(priv)) | ||
1989 | user_scan_cfg->scan_chan_gap = | ||
1990 | priv->adapter->scan_chan_gap_time; | ||
1991 | |||
1994 | ret = mwifiex_scan_networks(priv, user_scan_cfg); | 1992 | ret = mwifiex_scan_networks(priv, user_scan_cfg); |
1995 | kfree(user_scan_cfg); | 1993 | kfree(user_scan_cfg); |
1996 | if (ret) { | 1994 | if (ret) { |
@@ -2915,7 +2913,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) | |||
2915 | 2913 | ||
2916 | wiphy->features |= NL80211_FEATURE_HT_IBSS | | 2914 | wiphy->features |= NL80211_FEATURE_HT_IBSS | |
2917 | NL80211_FEATURE_INACTIVITY_TIMER | | 2915 | NL80211_FEATURE_INACTIVITY_TIMER | |
2918 | NL80211_FEATURE_LOW_PRIORITY_SCAN | | ||
2919 | NL80211_FEATURE_NEED_OBSS_SCAN; | 2916 | NL80211_FEATURE_NEED_OBSS_SCAN; |
2920 | 2917 | ||
2921 | /* Reserve space for mwifiex specific private data for BSS */ | 2918 | /* Reserve space for mwifiex specific private data for BSS */ |
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 985f6c2654fb..85597200badc 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c | |||
@@ -1508,6 +1508,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1508 | } | 1508 | } |
1509 | 1509 | ||
1510 | adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); | 1510 | adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); |
1511 | adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff; | ||
1511 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); | 1512 | adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); |
1512 | 1513 | ||
1513 | if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { | 1514 | if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { |
@@ -1612,5 +1613,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, | |||
1612 | adapter->if_ops.update_mp_end_port(adapter, | 1613 | adapter->if_ops.update_mp_end_port(adapter, |
1613 | le16_to_cpu(hw_spec->mp_end_port)); | 1614 | le16_to_cpu(hw_spec->mp_end_port)); |
1614 | 1615 | ||
1616 | if (adapter->fw_api_ver == MWIFIEX_FW_V15) | ||
1617 | adapter->scan_chan_gap_enabled = true; | ||
1618 | |||
1615 | return 0; | 1619 | return 0; |
1616 | } | 1620 | } |
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index 0e03fe39fc35..e0d00a7f0ec3 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h | |||
@@ -48,8 +48,8 @@ | |||
48 | #define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16 | 48 | #define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16 |
49 | #define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64 | 49 | #define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64 |
50 | #define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64 | 50 | #define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64 |
51 | #define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 48 | 51 | #define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 64 |
52 | #define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 32 | 52 | #define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 64 |
53 | 53 | ||
54 | #define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff | 54 | #define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff |
55 | 55 | ||
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h index 6a703ea18800..1eb61739071f 100644 --- a/drivers/net/wireless/mwifiex/fw.h +++ b/drivers/net/wireless/mwifiex/fw.h | |||
@@ -170,7 +170,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { | |||
170 | #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) | 170 | #define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) |
171 | #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) | 171 | #define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) |
172 | #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) | 172 | #define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) |
173 | #define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) | 173 | #define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197) |
174 | #define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) | ||
174 | 175 | ||
175 | #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 | 176 | #define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 |
176 | 177 | ||
@@ -653,6 +654,12 @@ struct mwifiex_ie_types_num_probes { | |||
653 | __le16 num_probes; | 654 | __le16 num_probes; |
654 | } __packed; | 655 | } __packed; |
655 | 656 | ||
657 | struct mwifiex_ie_types_scan_chan_gap { | ||
658 | struct mwifiex_ie_types_header header; | ||
659 | /* time gap in TUs to be used between two consecutive channels scan */ | ||
660 | __le16 chan_gap; | ||
661 | } __packed; | ||
662 | |||
656 | struct mwifiex_ie_types_wildcard_ssid_params { | 663 | struct mwifiex_ie_types_wildcard_ssid_params { |
657 | struct mwifiex_ie_types_header header; | 664 | struct mwifiex_ie_types_header header; |
658 | u8 max_ssid_length; | 665 | u8 max_ssid_length; |
@@ -1249,6 +1256,7 @@ struct mwifiex_user_scan_cfg { | |||
1249 | u8 num_ssids; | 1256 | u8 num_ssids; |
1250 | /* Variable number (fixed maximum) of channels to scan up */ | 1257 | /* Variable number (fixed maximum) of channels to scan up */ |
1251 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; | 1258 | struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; |
1259 | u16 scan_chan_gap; | ||
1252 | } __packed; | 1260 | } __packed; |
1253 | 1261 | ||
1254 | struct ie_body { | 1262 | struct ie_body { |
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index 80bda8087508..f7c97cf3840b 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c | |||
@@ -212,6 +212,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
212 | adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME; | 212 | adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME; |
213 | adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; | 213 | adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; |
214 | adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; | 214 | adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; |
215 | adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME; | ||
215 | 216 | ||
216 | adapter->scan_probes = 1; | 217 | adapter->scan_probes = 1; |
217 | 218 | ||
@@ -280,7 +281,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter) | |||
280 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); | 281 | memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); |
281 | adapter->arp_filter_size = 0; | 282 | adapter->arp_filter_size = 0; |
282 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; | 283 | adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; |
283 | adapter->empty_tx_q_cnt = 0; | ||
284 | adapter->ext_scan = true; | 284 | adapter->ext_scan = true; |
285 | adapter->key_api_major_ver = 0; | 285 | adapter->key_api_major_ver = 0; |
286 | adapter->key_api_minor_ver = 0; | 286 | adapter->key_api_minor_ver = 0; |
@@ -447,8 +447,11 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter) | |||
447 | spin_lock_init(&adapter->cmd_free_q_lock); | 447 | spin_lock_init(&adapter->cmd_free_q_lock); |
448 | spin_lock_init(&adapter->cmd_pending_q_lock); | 448 | spin_lock_init(&adapter->cmd_pending_q_lock); |
449 | spin_lock_init(&adapter->scan_pending_q_lock); | 449 | spin_lock_init(&adapter->scan_pending_q_lock); |
450 | spin_lock_init(&adapter->rx_q_lock); | ||
451 | spin_lock_init(&adapter->rx_proc_lock); | ||
450 | 452 | ||
451 | skb_queue_head_init(&adapter->usb_rx_data_q); | 453 | skb_queue_head_init(&adapter->usb_rx_data_q); |
454 | skb_queue_head_init(&adapter->rx_data_q); | ||
452 | 455 | ||
453 | for (i = 0; i < adapter->priv_num; ++i) { | 456 | for (i = 0; i < adapter->priv_num; ++i) { |
454 | INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); | 457 | INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); |
@@ -614,6 +617,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) | |||
614 | int ret = -EINPROGRESS; | 617 | int ret = -EINPROGRESS; |
615 | struct mwifiex_private *priv; | 618 | struct mwifiex_private *priv; |
616 | s32 i; | 619 | s32 i; |
620 | unsigned long flags; | ||
617 | struct sk_buff *skb; | 621 | struct sk_buff *skb; |
618 | 622 | ||
619 | /* mwifiex already shutdown */ | 623 | /* mwifiex already shutdown */ |
@@ -648,6 +652,21 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) | |||
648 | } | 652 | } |
649 | } | 653 | } |
650 | 654 | ||
655 | spin_lock_irqsave(&adapter->rx_proc_lock, flags); | ||
656 | |||
657 | while ((skb = skb_dequeue(&adapter->rx_data_q))) { | ||
658 | struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); | ||
659 | |||
660 | atomic_dec(&adapter->rx_pending); | ||
661 | priv = adapter->priv[rx_info->bss_num]; | ||
662 | if (priv) | ||
663 | priv->stats.rx_dropped++; | ||
664 | |||
665 | dev_kfree_skb_any(skb); | ||
666 | } | ||
667 | |||
668 | spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); | ||
669 | |||
651 | spin_lock(&adapter->mwifiex_lock); | 670 | spin_lock(&adapter->mwifiex_lock); |
652 | 671 | ||
653 | if (adapter->if_ops.data_complete) { | 672 | if (adapter->if_ops.data_complete) { |
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index dfa37eadc4db..b522f7c36901 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c | |||
@@ -28,91 +28,6 @@ const char driver_version[] = "mwifiex " VERSION " (%s) "; | |||
28 | static char *cal_data_cfg; | 28 | static char *cal_data_cfg; |
29 | module_param(cal_data_cfg, charp, 0); | 29 | module_param(cal_data_cfg, charp, 0); |
30 | 30 | ||
31 | static void scan_delay_timer_fn(unsigned long data) | ||
32 | { | ||
33 | struct mwifiex_private *priv = (struct mwifiex_private *)data; | ||
34 | struct mwifiex_adapter *adapter = priv->adapter; | ||
35 | struct cmd_ctrl_node *cmd_node, *tmp_node; | ||
36 | spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock; | ||
37 | unsigned long flags; | ||
38 | |||
39 | if (adapter->surprise_removed) | ||
40 | return; | ||
41 | |||
42 | if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT || | ||
43 | !adapter->scan_processing) { | ||
44 | /* | ||
45 | * Abort scan operation by cancelling all pending scan | ||
46 | * commands | ||
47 | */ | ||
48 | spin_lock_irqsave(scan_q_lock, flags); | ||
49 | list_for_each_entry_safe(cmd_node, tmp_node, | ||
50 | &adapter->scan_pending_q, list) { | ||
51 | list_del(&cmd_node->list); | ||
52 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); | ||
53 | } | ||
54 | spin_unlock_irqrestore(scan_q_lock, flags); | ||
55 | |||
56 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | ||
57 | adapter->scan_processing = false; | ||
58 | adapter->scan_delay_cnt = 0; | ||
59 | adapter->empty_tx_q_cnt = 0; | ||
60 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | ||
61 | |||
62 | if (priv->scan_request) { | ||
63 | dev_dbg(adapter->dev, "info: aborting scan\n"); | ||
64 | cfg80211_scan_done(priv->scan_request, 1); | ||
65 | priv->scan_request = NULL; | ||
66 | } else { | ||
67 | priv->scan_aborting = false; | ||
68 | dev_dbg(adapter->dev, "info: scan already aborted\n"); | ||
69 | } | ||
70 | goto done; | ||
71 | } | ||
72 | |||
73 | if (!atomic_read(&priv->adapter->is_tx_received)) { | ||
74 | adapter->empty_tx_q_cnt++; | ||
75 | if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) { | ||
76 | /* | ||
77 | * No Tx traffic for 200msec. Get scan command from | ||
78 | * scan pending queue and put to cmd pending queue to | ||
79 | * resume scan operation | ||
80 | */ | ||
81 | adapter->scan_delay_cnt = 0; | ||
82 | adapter->empty_tx_q_cnt = 0; | ||
83 | spin_lock_irqsave(scan_q_lock, flags); | ||
84 | |||
85 | if (list_empty(&adapter->scan_pending_q)) { | ||
86 | spin_unlock_irqrestore(scan_q_lock, flags); | ||
87 | goto done; | ||
88 | } | ||
89 | |||
90 | cmd_node = list_first_entry(&adapter->scan_pending_q, | ||
91 | struct cmd_ctrl_node, list); | ||
92 | list_del(&cmd_node->list); | ||
93 | spin_unlock_irqrestore(scan_q_lock, flags); | ||
94 | |||
95 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, | ||
96 | true); | ||
97 | queue_work(adapter->workqueue, &adapter->main_work); | ||
98 | goto done; | ||
99 | } | ||
100 | } else { | ||
101 | adapter->empty_tx_q_cnt = 0; | ||
102 | } | ||
103 | |||
104 | /* Delay scan operation further by 20msec */ | ||
105 | mod_timer(&priv->scan_delay_timer, jiffies + | ||
106 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); | ||
107 | adapter->scan_delay_cnt++; | ||
108 | |||
109 | done: | ||
110 | if (atomic_read(&priv->adapter->is_tx_received)) | ||
111 | atomic_set(&priv->adapter->is_tx_received, false); | ||
112 | |||
113 | return; | ||
114 | } | ||
115 | |||
116 | /* | 31 | /* |
117 | * This function registers the device and performs all the necessary | 32 | * This function registers the device and performs all the necessary |
118 | * initializations. | 33 | * initializations. |
@@ -160,10 +75,6 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, | |||
160 | 75 | ||
161 | adapter->priv[i]->adapter = adapter; | 76 | adapter->priv[i]->adapter = adapter; |
162 | adapter->priv_num++; | 77 | adapter->priv_num++; |
163 | |||
164 | setup_timer(&adapter->priv[i]->scan_delay_timer, | ||
165 | scan_delay_timer_fn, | ||
166 | (unsigned long)adapter->priv[i]); | ||
167 | } | 78 | } |
168 | mwifiex_init_lock_list(adapter); | 79 | mwifiex_init_lock_list(adapter); |
169 | 80 | ||
@@ -207,7 +118,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter) | |||
207 | for (i = 0; i < adapter->priv_num; i++) { | 118 | for (i = 0; i < adapter->priv_num; i++) { |
208 | if (adapter->priv[i]) { | 119 | if (adapter->priv[i]) { |
209 | mwifiex_free_curr_bcn(adapter->priv[i]); | 120 | mwifiex_free_curr_bcn(adapter->priv[i]); |
210 | del_timer_sync(&adapter->priv[i]->scan_delay_timer); | ||
211 | kfree(adapter->priv[i]); | 121 | kfree(adapter->priv[i]); |
212 | } | 122 | } |
213 | } | 123 | } |
@@ -216,6 +126,42 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter) | |||
216 | return 0; | 126 | return 0; |
217 | } | 127 | } |
218 | 128 | ||
129 | static int mwifiex_process_rx(struct mwifiex_adapter *adapter) | ||
130 | { | ||
131 | unsigned long flags; | ||
132 | struct sk_buff *skb; | ||
133 | bool delay_main_work = adapter->delay_main_work; | ||
134 | |||
135 | spin_lock_irqsave(&adapter->rx_proc_lock, flags); | ||
136 | if (adapter->rx_processing || adapter->rx_locked) { | ||
137 | spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); | ||
138 | goto exit_rx_proc; | ||
139 | } else { | ||
140 | adapter->rx_processing = true; | ||
141 | spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); | ||
142 | } | ||
143 | |||
144 | /* Check for Rx data */ | ||
145 | while ((skb = skb_dequeue(&adapter->rx_data_q))) { | ||
146 | atomic_dec(&adapter->rx_pending); | ||
147 | if (adapter->delay_main_work && | ||
148 | (atomic_dec_return(&adapter->rx_pending) < | ||
149 | LOW_RX_PENDING)) { | ||
150 | adapter->delay_main_work = false; | ||
151 | queue_work(adapter->rx_workqueue, &adapter->rx_work); | ||
152 | } | ||
153 | mwifiex_handle_rx_packet(adapter, skb); | ||
154 | } | ||
155 | spin_lock_irqsave(&adapter->rx_proc_lock, flags); | ||
156 | adapter->rx_processing = false; | ||
157 | spin_unlock_irqrestore(&adapter->rx_proc_lock, flags); | ||
158 | |||
159 | if (delay_main_work) | ||
160 | queue_work(adapter->workqueue, &adapter->main_work); | ||
161 | exit_rx_proc: | ||
162 | return 0; | ||
163 | } | ||
164 | |||
219 | /* | 165 | /* |
220 | * The main process. | 166 | * The main process. |
221 | * | 167 | * |
@@ -253,6 +199,19 @@ process_start: | |||
253 | (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) | 199 | (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) |
254 | break; | 200 | break; |
255 | 201 | ||
202 | /* If we process interrupts first, it would increase RX pending | ||
203 | * even further. Avoid this by checking if rx_pending has | ||
204 | * crossed high threshold and schedule rx work queue | ||
205 | * and then process interrupts | ||
206 | */ | ||
207 | if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING) { | ||
208 | adapter->delay_main_work = true; | ||
209 | if (!adapter->rx_processing) | ||
210 | queue_work(adapter->rx_workqueue, | ||
211 | &adapter->rx_work); | ||
212 | break; | ||
213 | } | ||
214 | |||
256 | /* Handle pending interrupt if any */ | 215 | /* Handle pending interrupt if any */ |
257 | if (adapter->int_status) { | 216 | if (adapter->int_status) { |
258 | if (adapter->hs_activated) | 217 | if (adapter->hs_activated) |
@@ -261,6 +220,9 @@ process_start: | |||
261 | adapter->if_ops.process_int_status(adapter); | 220 | adapter->if_ops.process_int_status(adapter); |
262 | } | 221 | } |
263 | 222 | ||
223 | if (adapter->rx_work_enabled && adapter->data_received) | ||
224 | queue_work(adapter->rx_workqueue, &adapter->rx_work); | ||
225 | |||
264 | /* Need to wake up the card ? */ | 226 | /* Need to wake up the card ? */ |
265 | if ((adapter->ps_state == PS_STATE_SLEEP) && | 227 | if ((adapter->ps_state == PS_STATE_SLEEP) && |
266 | (adapter->pm_wakeup_card_req && | 228 | (adapter->pm_wakeup_card_req && |
@@ -273,6 +235,7 @@ process_start: | |||
273 | } | 235 | } |
274 | 236 | ||
275 | if (IS_CARD_RX_RCVD(adapter)) { | 237 | if (IS_CARD_RX_RCVD(adapter)) { |
238 | adapter->data_received = false; | ||
276 | adapter->pm_wakeup_fw_try = false; | 239 | adapter->pm_wakeup_fw_try = false; |
277 | if (adapter->ps_state == PS_STATE_SLEEP) | 240 | if (adapter->ps_state == PS_STATE_SLEEP) |
278 | adapter->ps_state = PS_STATE_AWAKE; | 241 | adapter->ps_state = PS_STATE_AWAKE; |
@@ -284,8 +247,8 @@ process_start: | |||
284 | adapter->tx_lock_flag) | 247 | adapter->tx_lock_flag) |
285 | break; | 248 | break; |
286 | 249 | ||
287 | if ((adapter->scan_processing && | 250 | if ((!adapter->scan_chan_gap_enabled && |
288 | !adapter->scan_delay_cnt) || adapter->data_sent || | 251 | adapter->scan_processing) || adapter->data_sent || |
289 | mwifiex_wmm_lists_empty(adapter)) { | 252 | mwifiex_wmm_lists_empty(adapter)) { |
290 | if (adapter->cmd_sent || adapter->curr_cmd || | 253 | if (adapter->cmd_sent || adapter->curr_cmd || |
291 | (!is_command_pending(adapter))) | 254 | (!is_command_pending(adapter))) |
@@ -339,7 +302,8 @@ process_start: | |||
339 | } | 302 | } |
340 | } | 303 | } |
341 | 304 | ||
342 | if ((!adapter->scan_processing || adapter->scan_delay_cnt) && | 305 | if ((adapter->scan_chan_gap_enabled || |
306 | !adapter->scan_processing) && | ||
343 | !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { | 307 | !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { |
344 | mwifiex_wmm_process_tx(adapter); | 308 | mwifiex_wmm_process_tx(adapter); |
345 | if (adapter->hs_activated) { | 309 | if (adapter->hs_activated) { |
@@ -407,6 +371,12 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter) | |||
407 | flush_workqueue(adapter->workqueue); | 371 | flush_workqueue(adapter->workqueue); |
408 | destroy_workqueue(adapter->workqueue); | 372 | destroy_workqueue(adapter->workqueue); |
409 | adapter->workqueue = NULL; | 373 | adapter->workqueue = NULL; |
374 | |||
375 | if (adapter->rx_workqueue) { | ||
376 | flush_workqueue(adapter->rx_workqueue); | ||
377 | destroy_workqueue(adapter->rx_workqueue); | ||
378 | adapter->rx_workqueue = NULL; | ||
379 | } | ||
410 | } | 380 | } |
411 | 381 | ||
412 | /* | 382 | /* |
@@ -598,9 +568,6 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb) | |||
598 | atomic_inc(&priv->adapter->tx_pending); | 568 | atomic_inc(&priv->adapter->tx_pending); |
599 | mwifiex_wmm_add_buf_txqueue(priv, skb); | 569 | mwifiex_wmm_add_buf_txqueue(priv, skb); |
600 | 570 | ||
601 | if (priv->adapter->scan_delay_cnt) | ||
602 | atomic_set(&priv->adapter->is_tx_received, true); | ||
603 | |||
604 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); | 571 | queue_work(priv->adapter->workqueue, &priv->adapter->main_work); |
605 | 572 | ||
606 | return 0; | 573 | return 0; |
@@ -824,6 +791,21 @@ int is_command_pending(struct mwifiex_adapter *adapter) | |||
824 | } | 791 | } |
825 | 792 | ||
826 | /* | 793 | /* |
794 | * This is the RX work queue function. | ||
795 | * | ||
796 | * It handles the RX operations. | ||
797 | */ | ||
798 | static void mwifiex_rx_work_queue(struct work_struct *work) | ||
799 | { | ||
800 | struct mwifiex_adapter *adapter = | ||
801 | container_of(work, struct mwifiex_adapter, rx_work); | ||
802 | |||
803 | if (adapter->surprise_removed) | ||
804 | return; | ||
805 | mwifiex_process_rx(adapter); | ||
806 | } | ||
807 | |||
808 | /* | ||
827 | * This is the main work queue function. | 809 | * This is the main work queue function. |
828 | * | 810 | * |
829 | * It handles the main process, which in turn handles the complete | 811 | * It handles the main process, which in turn handles the complete |
@@ -879,6 +861,11 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
879 | adapter->cmd_wait_q.status = 0; | 861 | adapter->cmd_wait_q.status = 0; |
880 | adapter->scan_wait_q_woken = false; | 862 | adapter->scan_wait_q_woken = false; |
881 | 863 | ||
864 | if (num_possible_cpus() > 1) { | ||
865 | adapter->rx_work_enabled = true; | ||
866 | pr_notice("rx work enabled, cpus %d\n", num_possible_cpus()); | ||
867 | } | ||
868 | |||
882 | adapter->workqueue = | 869 | adapter->workqueue = |
883 | alloc_workqueue("MWIFIEX_WORK_QUEUE", | 870 | alloc_workqueue("MWIFIEX_WORK_QUEUE", |
884 | WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); | 871 | WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); |
@@ -886,6 +873,18 @@ mwifiex_add_card(void *card, struct semaphore *sem, | |||
886 | goto err_kmalloc; | 873 | goto err_kmalloc; |
887 | 874 | ||
888 | INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); | 875 | INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); |
876 | |||
877 | if (adapter->rx_work_enabled) { | ||
878 | adapter->rx_workqueue = alloc_workqueue("MWIFIEX_RX_WORK_QUEUE", | ||
879 | WQ_HIGHPRI | | ||
880 | WQ_MEM_RECLAIM | | ||
881 | WQ_UNBOUND, 1); | ||
882 | if (!adapter->rx_workqueue) | ||
883 | goto err_kmalloc; | ||
884 | |||
885 | INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue); | ||
886 | } | ||
887 | |||
889 | if (adapter->if_ops.iface_work) | 888 | if (adapter->if_ops.iface_work) |
890 | INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work); | 889 | INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work); |
891 | 890 | ||
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 54399631599a..1a999999b391 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h | |||
@@ -58,6 +58,9 @@ enum { | |||
58 | #define MAX_TX_PENDING 100 | 58 | #define MAX_TX_PENDING 100 |
59 | #define LOW_TX_PENDING 80 | 59 | #define LOW_TX_PENDING 80 |
60 | 60 | ||
61 | #define HIGH_RX_PENDING 50 | ||
62 | #define LOW_RX_PENDING 20 | ||
63 | |||
61 | #define MWIFIEX_UPLD_SIZE (2312) | 64 | #define MWIFIEX_UPLD_SIZE (2312) |
62 | 65 | ||
63 | #define MAX_EVENT_SIZE 2048 | 66 | #define MAX_EVENT_SIZE 2048 |
@@ -84,17 +87,12 @@ enum { | |||
84 | #define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110 | 87 | #define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110 |
85 | #define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30 | 88 | #define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30 |
86 | #define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30 | 89 | #define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30 |
90 | #define MWIFIEX_DEF_SCAN_CHAN_GAP_TIME 50 | ||
87 | 91 | ||
88 | #define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) | 92 | #define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) |
89 | 93 | ||
90 | #define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) | 94 | #define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) |
91 | 95 | ||
92 | #define MWIFIEX_MAX_SCAN_DELAY_CNT 50 | ||
93 | #define MWIFIEX_MAX_EMPTY_TX_Q_CNT 10 | ||
94 | #define MWIFIEX_SCAN_DELAY_MSEC 20 | ||
95 | |||
96 | #define MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN 2 | ||
97 | |||
98 | #define RSN_GTK_OUI_OFFSET 2 | 96 | #define RSN_GTK_OUI_OFFSET 2 |
99 | 97 | ||
100 | #define MWIFIEX_OUI_NOT_PRESENT 0 | 98 | #define MWIFIEX_OUI_NOT_PRESENT 0 |
@@ -547,7 +545,6 @@ struct mwifiex_private { | |||
547 | u8 nick_name[16]; | 545 | u8 nick_name[16]; |
548 | u16 current_key_index; | 546 | u16 current_key_index; |
549 | struct semaphore async_sem; | 547 | struct semaphore async_sem; |
550 | u8 report_scan_result; | ||
551 | struct cfg80211_scan_request *scan_request; | 548 | struct cfg80211_scan_request *scan_request; |
552 | u8 cfg_bssid[6]; | 549 | u8 cfg_bssid[6]; |
553 | struct wps wps; | 550 | struct wps wps; |
@@ -561,7 +558,6 @@ struct mwifiex_private { | |||
561 | u16 proberesp_idx; | 558 | u16 proberesp_idx; |
562 | u16 assocresp_idx; | 559 | u16 assocresp_idx; |
563 | u16 rsn_idx; | 560 | u16 rsn_idx; |
564 | struct timer_list scan_delay_timer; | ||
565 | u8 ap_11n_enabled; | 561 | u8 ap_11n_enabled; |
566 | u8 ap_11ac_enabled; | 562 | u8 ap_11ac_enabled; |
567 | u32 mgmt_frame_mask; | 563 | u32 mgmt_frame_mask; |
@@ -721,6 +717,12 @@ struct mwifiex_adapter { | |||
721 | atomic_t cmd_pending; | 717 | atomic_t cmd_pending; |
722 | struct workqueue_struct *workqueue; | 718 | struct workqueue_struct *workqueue; |
723 | struct work_struct main_work; | 719 | struct work_struct main_work; |
720 | struct workqueue_struct *rx_workqueue; | ||
721 | struct work_struct rx_work; | ||
722 | bool rx_work_enabled; | ||
723 | bool rx_processing; | ||
724 | bool delay_main_work; | ||
725 | bool rx_locked; | ||
724 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; | 726 | struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; |
725 | /* spin lock for init/shutdown */ | 727 | /* spin lock for init/shutdown */ |
726 | spinlock_t mwifiex_lock; | 728 | spinlock_t mwifiex_lock; |
@@ -761,6 +763,10 @@ struct mwifiex_adapter { | |||
761 | struct list_head scan_pending_q; | 763 | struct list_head scan_pending_q; |
762 | /* spin lock for scan_pending_q */ | 764 | /* spin lock for scan_pending_q */ |
763 | spinlock_t scan_pending_q_lock; | 765 | spinlock_t scan_pending_q_lock; |
766 | /* spin lock for RX queue */ | ||
767 | spinlock_t rx_q_lock; | ||
768 | /* spin lock for RX processing routine */ | ||
769 | spinlock_t rx_proc_lock; | ||
764 | struct sk_buff_head usb_rx_data_q; | 770 | struct sk_buff_head usb_rx_data_q; |
765 | u32 scan_processing; | 771 | u32 scan_processing; |
766 | u16 region_code; | 772 | u16 region_code; |
@@ -770,6 +776,7 @@ struct mwifiex_adapter { | |||
770 | u16 specific_scan_time; | 776 | u16 specific_scan_time; |
771 | u16 active_scan_time; | 777 | u16 active_scan_time; |
772 | u16 passive_scan_time; | 778 | u16 passive_scan_time; |
779 | u16 scan_chan_gap_time; | ||
773 | u8 fw_bands; | 780 | u8 fw_bands; |
774 | u8 adhoc_start_band; | 781 | u8 adhoc_start_band; |
775 | u8 config_bands; | 782 | u8 config_bands; |
@@ -815,8 +822,6 @@ struct mwifiex_adapter { | |||
815 | spinlock_t queue_lock; /* lock for tx queues */ | 822 | spinlock_t queue_lock; /* lock for tx queues */ |
816 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; | 823 | u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; |
817 | u16 max_mgmt_ie_index; | 824 | u16 max_mgmt_ie_index; |
818 | u8 scan_delay_cnt; | ||
819 | u8 empty_tx_q_cnt; | ||
820 | const struct firmware *cal_data; | 825 | const struct firmware *cal_data; |
821 | struct device_node *dt_node; | 826 | struct device_node *dt_node; |
822 | 827 | ||
@@ -828,7 +833,6 @@ struct mwifiex_adapter { | |||
828 | u32 usr_dot_11ac_dev_cap_a; | 833 | u32 usr_dot_11ac_dev_cap_a; |
829 | u32 usr_dot_11ac_mcs_support; | 834 | u32 usr_dot_11ac_mcs_support; |
830 | 835 | ||
831 | atomic_t is_tx_received; | ||
832 | atomic_t pending_bridged_pkts; | 836 | atomic_t pending_bridged_pkts; |
833 | struct semaphore *card_sem; | 837 | struct semaphore *card_sem; |
834 | bool ext_scan; | 838 | bool ext_scan; |
@@ -839,6 +843,8 @@ struct mwifiex_adapter { | |||
839 | struct memory_type_mapping *mem_type_mapping_tbl; | 843 | struct memory_type_mapping *mem_type_mapping_tbl; |
840 | u8 num_mem_types; | 844 | u8 num_mem_types; |
841 | u8 curr_mem_idx; | 845 | u8 curr_mem_idx; |
846 | bool scan_chan_gap_enabled; | ||
847 | struct sk_buff_head rx_data_q; | ||
842 | }; | 848 | }; |
843 | 849 | ||
844 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); | 850 | int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); |
@@ -1139,6 +1145,25 @@ mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv) | |||
1139 | return priv->csa_chan; | 1145 | return priv->csa_chan; |
1140 | } | 1146 | } |
1141 | 1147 | ||
1148 | static inline u8 mwifiex_is_any_intf_active(struct mwifiex_private *priv) | ||
1149 | { | ||
1150 | struct mwifiex_private *priv_num; | ||
1151 | int i; | ||
1152 | |||
1153 | for (i = 0; i < priv->adapter->priv_num; i++) { | ||
1154 | priv_num = priv->adapter->priv[i]; | ||
1155 | if (priv_num) { | ||
1156 | if ((GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_UAP && | ||
1157 | priv_num->bss_started) || | ||
1158 | (GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_STA && | ||
1159 | priv_num->media_connected)) | ||
1160 | return 1; | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | return 0; | ||
1165 | } | ||
1166 | |||
1142 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, | 1167 | int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, |
1143 | u32 func_init_shutdown); | 1168 | u32 func_init_shutdown); |
1144 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); | 1169 | int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); |
@@ -1274,6 +1299,7 @@ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv); | |||
1274 | bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); | 1299 | bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); |
1275 | u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, | 1300 | u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, |
1276 | u32 pri_chan, u8 chan_bw); | 1301 | u32 pri_chan, u8 chan_bw); |
1302 | int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter); | ||
1277 | 1303 | ||
1278 | #ifdef CONFIG_DEBUG_FS | 1304 | #ifdef CONFIG_DEBUG_FS |
1279 | void mwifiex_debugfs_init(void); | 1305 | void mwifiex_debugfs_init(void); |
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index ff0545888dd0..1504b16e248e 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c | |||
@@ -1233,6 +1233,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
1233 | struct sk_buff *skb_tmp = NULL; | 1233 | struct sk_buff *skb_tmp = NULL; |
1234 | struct mwifiex_pcie_buf_desc *desc; | 1234 | struct mwifiex_pcie_buf_desc *desc; |
1235 | struct mwifiex_pfu_buf_desc *desc2; | 1235 | struct mwifiex_pfu_buf_desc *desc2; |
1236 | unsigned long flags; | ||
1236 | 1237 | ||
1237 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) | 1238 | if (!mwifiex_pcie_ok_to_access_hw(adapter)) |
1238 | mwifiex_pm_wakeup_card(adapter); | 1239 | mwifiex_pm_wakeup_card(adapter); |
@@ -1271,12 +1272,29 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) | |||
1271 | */ | 1272 | */ |
1272 | pkt_len = *((__le16 *)skb_data->data); | 1273 | pkt_len = *((__le16 *)skb_data->data); |
1273 | rx_len = le16_to_cpu(pkt_len); | 1274 | rx_len = le16_to_cpu(pkt_len); |
1274 | skb_put(skb_data, rx_len); | 1275 | if (WARN_ON(rx_len <= INTF_HEADER_LEN || |
1275 | dev_dbg(adapter->dev, | 1276 | rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) { |
1276 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", | 1277 | dev_err(adapter->dev, |
1277 | card->rxbd_rdptr, wrptr, rx_len); | 1278 | "Invalid RX len %d, Rd=%#x, Wr=%#x\n", |
1278 | skb_pull(skb_data, INTF_HEADER_LEN); | 1279 | rx_len, card->rxbd_rdptr, wrptr); |
1279 | mwifiex_handle_rx_packet(adapter, skb_data); | 1280 | dev_kfree_skb_any(skb_data); |
1281 | } else { | ||
1282 | skb_put(skb_data, rx_len); | ||
1283 | dev_dbg(adapter->dev, | ||
1284 | "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", | ||
1285 | card->rxbd_rdptr, wrptr, rx_len); | ||
1286 | skb_pull(skb_data, INTF_HEADER_LEN); | ||
1287 | if (adapter->rx_work_enabled) { | ||
1288 | spin_lock_irqsave(&adapter->rx_q_lock, flags); | ||
1289 | skb_queue_tail(&adapter->rx_data_q, skb_data); | ||
1290 | spin_unlock_irqrestore(&adapter->rx_q_lock, | ||
1291 | flags); | ||
1292 | adapter->data_received = true; | ||
1293 | atomic_inc(&adapter->rx_pending); | ||
1294 | } else { | ||
1295 | mwifiex_handle_rx_packet(adapter, skb_data); | ||
1296 | } | ||
1297 | } | ||
1280 | 1298 | ||
1281 | skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); | 1299 | skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); |
1282 | if (!skb_tmp) { | 1300 | if (!skb_tmp) { |
@@ -1718,6 +1736,13 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) | |||
1718 | buffer is released. This is just to make things simpler, | 1736 | buffer is released. This is just to make things simpler, |
1719 | we need to find a better method of managing these buffers. | 1737 | we need to find a better method of managing these buffers. |
1720 | */ | 1738 | */ |
1739 | } else { | ||
1740 | if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, | ||
1741 | CPU_INTR_EVENT_DONE)) { | ||
1742 | dev_warn(adapter->dev, | ||
1743 | "Write register failed\n"); | ||
1744 | return -1; | ||
1745 | } | ||
1721 | } | 1746 | } |
1722 | 1747 | ||
1723 | return 0; | 1748 | return 0; |
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index a1a8fd3bc1be..200e8b0cb582 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h | |||
@@ -40,8 +40,8 @@ | |||
40 | #define MWIFIEX_TXBD_MASK 0x3F | 40 | #define MWIFIEX_TXBD_MASK 0x3F |
41 | #define MWIFIEX_RXBD_MASK 0x3F | 41 | #define MWIFIEX_RXBD_MASK 0x3F |
42 | 42 | ||
43 | #define MWIFIEX_MAX_EVT_BD 0x04 | 43 | #define MWIFIEX_MAX_EVT_BD 0x08 |
44 | #define MWIFIEX_EVTBD_MASK 0x07 | 44 | #define MWIFIEX_EVTBD_MASK 0x0f |
45 | 45 | ||
46 | /* PCIE INTERNAL REGISTERS */ | 46 | /* PCIE INTERNAL REGISTERS */ |
47 | #define PCIE_SCRATCH_0_REG 0xC10 | 47 | #define PCIE_SCRATCH_0_REG 0xC10 |
@@ -69,6 +69,7 @@ | |||
69 | #define CPU_INTR_DOOR_BELL BIT(1) | 69 | #define CPU_INTR_DOOR_BELL BIT(1) |
70 | #define CPU_INTR_SLEEP_CFM_DONE BIT(2) | 70 | #define CPU_INTR_SLEEP_CFM_DONE BIT(2) |
71 | #define CPU_INTR_RESET BIT(3) | 71 | #define CPU_INTR_RESET BIT(3) |
72 | #define CPU_INTR_EVENT_DONE BIT(5) | ||
72 | 73 | ||
73 | #define HOST_INTR_DNLD_DONE BIT(0) | 74 | #define HOST_INTR_DNLD_DONE BIT(0) |
74 | #define HOST_INTR_UPLD_RDY BIT(1) | 75 | #define HOST_INTR_UPLD_RDY BIT(1) |
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 195ef0ca343f..c09ebeee6ddf 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -799,6 +799,7 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
799 | { | 799 | { |
800 | struct mwifiex_adapter *adapter = priv->adapter; | 800 | struct mwifiex_adapter *adapter = priv->adapter; |
801 | struct mwifiex_ie_types_num_probes *num_probes_tlv; | 801 | struct mwifiex_ie_types_num_probes *num_probes_tlv; |
802 | struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv; | ||
802 | struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; | 803 | struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; |
803 | struct mwifiex_ie_types_bssid_list *bssid_tlv; | 804 | struct mwifiex_ie_types_bssid_list *bssid_tlv; |
804 | u8 *tlv_pos; | 805 | u8 *tlv_pos; |
@@ -939,6 +940,22 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
939 | else | 940 | else |
940 | *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; | 941 | *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; |
941 | 942 | ||
943 | if (user_scan_in->scan_chan_gap) { | ||
944 | *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN; | ||
945 | dev_dbg(adapter->dev, "info: scan: channel gap = %d\n", | ||
946 | user_scan_in->scan_chan_gap); | ||
947 | |||
948 | chan_gap_tlv = (void *)tlv_pos; | ||
949 | chan_gap_tlv->header.type = | ||
950 | cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP); | ||
951 | chan_gap_tlv->header.len = | ||
952 | cpu_to_le16(sizeof(chan_gap_tlv->chan_gap)); | ||
953 | chan_gap_tlv->chan_gap = | ||
954 | cpu_to_le16((user_scan_in->scan_chan_gap)); | ||
955 | |||
956 | tlv_pos += sizeof(struct mwifiex_ie_types_scan_chan_gap); | ||
957 | } | ||
958 | |||
942 | /* If the input config or adapter has the number of Probes set, | 959 | /* If the input config or adapter has the number of Probes set, |
943 | add tlv */ | 960 | add tlv */ |
944 | if (num_probes) { | 961 | if (num_probes) { |
@@ -1050,12 +1067,6 @@ mwifiex_config_scan(struct mwifiex_private *priv, | |||
1050 | *filtered_scan); | 1067 | *filtered_scan); |
1051 | } | 1068 | } |
1052 | 1069 | ||
1053 | /* | ||
1054 | * In associated state we will reduce the number of channels scanned per | ||
1055 | * scan command to 1 to avoid any traffic delay/loss. | ||
1056 | */ | ||
1057 | if (priv->media_connected) | ||
1058 | *max_chan_per_scan = 1; | ||
1059 | } | 1070 | } |
1060 | 1071 | ||
1061 | /* | 1072 | /* |
@@ -1755,7 +1766,7 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv) | |||
1755 | static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) | 1766 | static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) |
1756 | { | 1767 | { |
1757 | struct mwifiex_adapter *adapter = priv->adapter; | 1768 | struct mwifiex_adapter *adapter = priv->adapter; |
1758 | struct cmd_ctrl_node *cmd_node; | 1769 | struct cmd_ctrl_node *cmd_node, *tmp_node; |
1759 | unsigned long flags; | 1770 | unsigned long flags; |
1760 | 1771 | ||
1761 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1772 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
@@ -1768,9 +1779,6 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) | |||
1768 | if (!adapter->ext_scan) | 1779 | if (!adapter->ext_scan) |
1769 | mwifiex_complete_scan(priv); | 1780 | mwifiex_complete_scan(priv); |
1770 | 1781 | ||
1771 | if (priv->report_scan_result) | ||
1772 | priv->report_scan_result = false; | ||
1773 | |||
1774 | if (priv->scan_request) { | 1782 | if (priv->scan_request) { |
1775 | dev_dbg(adapter->dev, "info: notifying scan done\n"); | 1783 | dev_dbg(adapter->dev, "info: notifying scan done\n"); |
1776 | cfg80211_scan_done(priv->scan_request, 0); | 1784 | cfg80211_scan_done(priv->scan_request, 0); |
@@ -1779,37 +1787,36 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) | |||
1779 | priv->scan_aborting = false; | 1787 | priv->scan_aborting = false; |
1780 | dev_dbg(adapter->dev, "info: scan already aborted\n"); | 1788 | dev_dbg(adapter->dev, "info: scan already aborted\n"); |
1781 | } | 1789 | } |
1782 | } else { | 1790 | } else if ((priv->scan_aborting && !priv->scan_request) || |
1783 | if ((priv->scan_aborting && !priv->scan_request) || | 1791 | priv->scan_block) { |
1784 | priv->scan_block) { | 1792 | list_for_each_entry_safe(cmd_node, tmp_node, |
1785 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1793 | &adapter->scan_pending_q, list) { |
1786 | flags); | ||
1787 | adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT; | ||
1788 | mod_timer(&priv->scan_delay_timer, jiffies); | ||
1789 | dev_dbg(priv->adapter->dev, | ||
1790 | "info: %s: triggerring scan abort\n", __func__); | ||
1791 | } else if (!mwifiex_wmm_lists_empty(adapter) && | ||
1792 | (priv->scan_request && (priv->scan_request->flags & | ||
1793 | NL80211_SCAN_FLAG_LOW_PRIORITY))) { | ||
1794 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | ||
1795 | flags); | ||
1796 | adapter->scan_delay_cnt = 1; | ||
1797 | mod_timer(&priv->scan_delay_timer, jiffies + | ||
1798 | msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC)); | ||
1799 | dev_dbg(priv->adapter->dev, | ||
1800 | "info: %s: deferring scan\n", __func__); | ||
1801 | } else { | ||
1802 | /* Get scan command from scan_pending_q and put to | ||
1803 | * cmd_pending_q | ||
1804 | */ | ||
1805 | cmd_node = list_first_entry(&adapter->scan_pending_q, | ||
1806 | struct cmd_ctrl_node, list); | ||
1807 | list_del(&cmd_node->list); | 1794 | list_del(&cmd_node->list); |
1808 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, | 1795 | mwifiex_insert_cmd_to_free_q(adapter, cmd_node); |
1809 | flags); | ||
1810 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, | ||
1811 | true); | ||
1812 | } | 1796 | } |
1797 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | ||
1798 | |||
1799 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | ||
1800 | adapter->scan_processing = false; | ||
1801 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | ||
1802 | |||
1803 | if (priv->scan_request) { | ||
1804 | dev_dbg(adapter->dev, "info: aborting scan\n"); | ||
1805 | cfg80211_scan_done(priv->scan_request, 1); | ||
1806 | priv->scan_request = NULL; | ||
1807 | } else { | ||
1808 | priv->scan_aborting = false; | ||
1809 | dev_dbg(adapter->dev, "info: scan already aborted\n"); | ||
1810 | } | ||
1811 | } else { | ||
1812 | /* Get scan command from scan_pending_q and put to | ||
1813 | * cmd_pending_q | ||
1814 | */ | ||
1815 | cmd_node = list_first_entry(&adapter->scan_pending_q, | ||
1816 | struct cmd_ctrl_node, list); | ||
1817 | list_del(&cmd_node->list); | ||
1818 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | ||
1819 | mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); | ||
1813 | } | 1820 | } |
1814 | 1821 | ||
1815 | return; | 1822 | return; |
@@ -1971,9 +1978,34 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv, | |||
1971 | /* This function handles the command response of extended scan */ | 1978 | /* This function handles the command response of extended scan */ |
1972 | int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) | 1979 | int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) |
1973 | { | 1980 | { |
1981 | struct mwifiex_adapter *adapter = priv->adapter; | ||
1982 | struct host_cmd_ds_command *cmd_ptr; | ||
1983 | struct cmd_ctrl_node *cmd_node; | ||
1984 | unsigned long cmd_flags, scan_flags; | ||
1985 | bool complete_scan = false; | ||
1986 | |||
1974 | dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); | 1987 | dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); |
1975 | 1988 | ||
1976 | mwifiex_complete_scan(priv); | 1989 | spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags); |
1990 | spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags); | ||
1991 | if (list_empty(&adapter->scan_pending_q)) { | ||
1992 | complete_scan = true; | ||
1993 | list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) { | ||
1994 | cmd_ptr = (void *)cmd_node->cmd_skb->data; | ||
1995 | if (le16_to_cpu(cmd_ptr->command) == | ||
1996 | HostCmd_CMD_802_11_SCAN_EXT) { | ||
1997 | dev_dbg(priv->adapter->dev, | ||
1998 | "Scan pending in command pending list"); | ||
1999 | complete_scan = false; | ||
2000 | break; | ||
2001 | } | ||
2002 | } | ||
2003 | } | ||
2004 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_flags); | ||
2005 | spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_flags); | ||
2006 | |||
2007 | if (complete_scan) | ||
2008 | mwifiex_complete_scan(priv); | ||
1977 | 2009 | ||
1978 | return 0; | 2010 | return 0; |
1979 | } | 2011 | } |
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 1770fa3fc1e6..ea8fc587e90f 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -622,22 +622,15 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port) | |||
622 | 622 | ||
623 | dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap); | 623 | dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap); |
624 | 624 | ||
625 | if (card->supports_sdio_new_mode && | 625 | if (!(wr_bitmap & card->mp_data_port_mask)) { |
626 | !(wr_bitmap & reg->data_port_mask)) { | ||
627 | adapter->data_sent = true; | 626 | adapter->data_sent = true; |
628 | return -EBUSY; | 627 | return -EBUSY; |
629 | } else if (!card->supports_sdio_new_mode && | ||
630 | !(wr_bitmap & card->mp_data_port_mask)) { | ||
631 | return -1; | ||
632 | } | 628 | } |
633 | 629 | ||
634 | if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { | 630 | if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { |
635 | card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port)); | 631 | card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port)); |
636 | *port = card->curr_wr_port; | 632 | *port = card->curr_wr_port; |
637 | if (((card->supports_sdio_new_mode) && | 633 | if (++card->curr_wr_port == card->mp_end_port) |
638 | (++card->curr_wr_port == card->max_ports)) || | ||
639 | ((!card->supports_sdio_new_mode) && | ||
640 | (++card->curr_wr_port == card->mp_end_port))) | ||
641 | card->curr_wr_port = reg->start_wr_port; | 634 | card->curr_wr_port = reg->start_wr_port; |
642 | } else { | 635 | } else { |
643 | adapter->data_sent = true; | 636 | adapter->data_sent = true; |
@@ -1046,6 +1039,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, | |||
1046 | struct sk_buff *skb, u32 upld_typ) | 1039 | struct sk_buff *skb, u32 upld_typ) |
1047 | { | 1040 | { |
1048 | u8 *cmd_buf; | 1041 | u8 *cmd_buf; |
1042 | unsigned long flags; | ||
1049 | __le16 *curr_ptr = (__le16 *)skb->data; | 1043 | __le16 *curr_ptr = (__le16 *)skb->data; |
1050 | u16 pkt_len = le16_to_cpu(*curr_ptr); | 1044 | u16 pkt_len = le16_to_cpu(*curr_ptr); |
1051 | 1045 | ||
@@ -1055,7 +1049,15 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter, | |||
1055 | switch (upld_typ) { | 1049 | switch (upld_typ) { |
1056 | case MWIFIEX_TYPE_DATA: | 1050 | case MWIFIEX_TYPE_DATA: |
1057 | dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); | 1051 | dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); |
1058 | mwifiex_handle_rx_packet(adapter, skb); | 1052 | if (adapter->rx_work_enabled) { |
1053 | spin_lock_irqsave(&adapter->rx_q_lock, flags); | ||
1054 | skb_queue_tail(&adapter->rx_data_q, skb); | ||
1055 | spin_unlock_irqrestore(&adapter->rx_q_lock, flags); | ||
1056 | adapter->data_received = true; | ||
1057 | atomic_inc(&adapter->rx_pending); | ||
1058 | } else { | ||
1059 | mwifiex_handle_rx_packet(adapter, skb); | ||
1060 | } | ||
1059 | break; | 1061 | break; |
1060 | 1062 | ||
1061 | case MWIFIEX_TYPE_CMD: | 1063 | case MWIFIEX_TYPE_CMD: |
@@ -1527,8 +1529,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1527 | __func__); | 1529 | __func__); |
1528 | 1530 | ||
1529 | if (MP_TX_AGGR_IN_PROGRESS(card)) { | 1531 | if (MP_TX_AGGR_IN_PROGRESS(card)) { |
1530 | if (!mp_tx_aggr_port_limit_reached(card) && | 1532 | if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { |
1531 | MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) { | ||
1532 | f_precopy_cur_buf = 1; | 1533 | f_precopy_cur_buf = 1; |
1533 | 1534 | ||
1534 | if (!(card->mp_wr_bitmap & | 1535 | if (!(card->mp_wr_bitmap & |
@@ -1540,8 +1541,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1540 | /* No room in Aggr buf, send it */ | 1541 | /* No room in Aggr buf, send it */ |
1541 | f_send_aggr_buf = 1; | 1542 | f_send_aggr_buf = 1; |
1542 | 1543 | ||
1543 | if (mp_tx_aggr_port_limit_reached(card) || | 1544 | if (!(card->mp_wr_bitmap & |
1544 | !(card->mp_wr_bitmap & | ||
1545 | (1 << card->curr_wr_port))) | 1545 | (1 << card->curr_wr_port))) |
1546 | f_send_cur_buf = 1; | 1546 | f_send_cur_buf = 1; |
1547 | else | 1547 | else |
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c index 62866b0f0830..4aad44685f8d 100644 --- a/drivers/net/wireless/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c | |||
@@ -85,8 +85,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv, | |||
85 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); | 85 | spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); |
86 | adapter->scan_processing = false; | 86 | adapter->scan_processing = false; |
87 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); | 87 | spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); |
88 | if (priv->report_scan_result) | ||
89 | priv->report_scan_result = false; | ||
90 | break; | 88 | break; |
91 | 89 | ||
92 | case HostCmd_CMD_MAC_CONTROL: | 90 | case HostCmd_CMD_MAC_CONTROL: |
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index b95a29b868d1..92f3eb839866 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c | |||
@@ -287,10 +287,13 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, | |||
287 | return -1; | 287 | return -1; |
288 | 288 | ||
289 | if (mwifiex_band_to_radio_type(bss_desc->bss_band) == | 289 | if (mwifiex_band_to_radio_type(bss_desc->bss_band) == |
290 | HostCmd_SCAN_RADIO_TYPE_BG) | 290 | HostCmd_SCAN_RADIO_TYPE_BG) { |
291 | config_bands = BAND_B | BAND_G | BAND_GN; | 291 | config_bands = BAND_B | BAND_G | BAND_GN; |
292 | else | 292 | } else { |
293 | config_bands = BAND_A | BAND_AN | BAND_AAC; | 293 | config_bands = BAND_A | BAND_AN; |
294 | if (adapter->fw_bands & BAND_AAC) | ||
295 | config_bands |= BAND_AAC; | ||
296 | } | ||
294 | 297 | ||
295 | if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) | 298 | if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) |
296 | adapter->config_bands = config_bands; | 299 | adapter->config_bands = config_bands; |
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c index 4c5fd953893d..e2949077f5b5 100644 --- a/drivers/net/wireless/mwifiex/tdls.c +++ b/drivers/net/wireless/mwifiex/tdls.c | |||
@@ -871,7 +871,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv, | |||
871 | break; | 871 | break; |
872 | case WLAN_EID_RSN: | 872 | case WLAN_EID_RSN: |
873 | memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, | 873 | memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, |
874 | sizeof(struct ieee_types_header) + pos[1]); | 874 | sizeof(struct ieee_types_header) + |
875 | min_t(u8, pos[1], IEEE_MAX_IE_SIZE - | ||
876 | sizeof(struct ieee_types_header))); | ||
875 | break; | 877 | break; |
876 | case WLAN_EID_QOS_CAPA: | 878 | case WLAN_EID_QOS_CAPA: |
877 | sta_ptr->tdls_cap.qos_info = pos[2]; | 879 | sta_ptr->tdls_cap.qos_info = pos[2]; |
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index 7be3a4839640..97aeff0edb84 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c | |||
@@ -696,7 +696,8 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif, | |||
696 | WARN(total, "tx flush timeout, unresponsive firmware"); | 696 | WARN(total, "tx flush timeout, unresponsive firmware"); |
697 | } | 697 | } |
698 | 698 | ||
699 | static void p54_set_coverage_class(struct ieee80211_hw *dev, u8 coverage_class) | 699 | static void p54_set_coverage_class(struct ieee80211_hw *dev, |
700 | s16 coverage_class) | ||
700 | { | 701 | { |
701 | struct p54_common *priv = dev->priv; | 702 | struct p54_common *priv = dev->priv; |
702 | 703 | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h index d76684eb24d0..39b9a3309cfd 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h | |||
@@ -37,7 +37,13 @@ | |||
37 | 37 | ||
38 | #include "halbtcoutsrc.h" | 38 | #include "halbtcoutsrc.h" |
39 | 39 | ||
40 | #include "halbtc8192e2ant.h" | ||
41 | #include "halbtc8723b1ant.h" | ||
40 | #include "halbtc8723b2ant.h" | 42 | #include "halbtc8723b2ant.h" |
43 | #include "halbtc8821a2ant.h" | ||
44 | #include "halbtc8821a1ant.h" | ||
45 | |||
46 | #define GetDefaultAdapter(padapter) padapter | ||
41 | 47 | ||
42 | #define BIT0 0x00000001 | 48 | #define BIT0 0x00000001 |
43 | #define BIT1 0x00000002 | 49 | #define BIT1 0x00000002 |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c new file mode 100644 index 000000000000..53261d6f8578 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c | |||
@@ -0,0 +1,3849 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | /************************************************************** | ||
26 | * Description: | ||
27 | * | ||
28 | * This file is for RTL8192E Co-exist mechanism | ||
29 | * | ||
30 | * History | ||
31 | * 2012/11/15 Cosa first check in. | ||
32 | * | ||
33 | **************************************************************/ | ||
34 | |||
35 | /************************************************************** | ||
36 | * include files | ||
37 | **************************************************************/ | ||
38 | #include "halbt_precomp.h" | ||
39 | /************************************************************** | ||
40 | * Global variables, these are static variables | ||
41 | **************************************************************/ | ||
42 | static struct coex_dm_8192e_2ant glcoex_dm_8192e_2ant; | ||
43 | static struct coex_dm_8192e_2ant *coex_dm = &glcoex_dm_8192e_2ant; | ||
44 | static struct coex_sta_8192e_2ant glcoex_sta_8192e_2ant; | ||
45 | static struct coex_sta_8192e_2ant *coex_sta = &glcoex_sta_8192e_2ant; | ||
46 | |||
47 | static const char *const GLBtInfoSrc8192e2Ant[] = { | ||
48 | "BT Info[wifi fw]", | ||
49 | "BT Info[bt rsp]", | ||
50 | "BT Info[bt auto report]", | ||
51 | }; | ||
52 | |||
53 | static u32 glcoex_ver_date_8192e_2ant = 20130902; | ||
54 | static u32 glcoex_ver_8192e_2ant = 0x34; | ||
55 | |||
56 | /************************************************************** | ||
57 | * local function proto type if needed | ||
58 | **************************************************************/ | ||
59 | /************************************************************** | ||
60 | * local function start with halbtc8192e2ant_ | ||
61 | **************************************************************/ | ||
62 | static u8 halbtc8192e2ant_btrssi_state(u8 level_num, u8 rssi_thresh, | ||
63 | u8 rssi_thresh1) | ||
64 | { | ||
65 | int btrssi = 0; | ||
66 | u8 btrssi_state = coex_sta->pre_bt_rssi_state; | ||
67 | |||
68 | btrssi = coex_sta->bt_rssi; | ||
69 | |||
70 | if (level_num == 2) { | ||
71 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
72 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
73 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
74 | "BT Rssi pre state = LOW\n"); | ||
75 | if (btrssi >= (rssi_thresh + | ||
76 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
77 | btrssi_state = BTC_RSSI_STATE_HIGH; | ||
78 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
79 | "BT Rssi state switch to High\n"); | ||
80 | } else { | ||
81 | btrssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
82 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
83 | "BT Rssi state stay at Low\n"); | ||
84 | } | ||
85 | } else { | ||
86 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
87 | "BT Rssi pre state = HIGH\n"); | ||
88 | if (btrssi < rssi_thresh) { | ||
89 | btrssi_state = BTC_RSSI_STATE_LOW; | ||
90 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
91 | "BT Rssi state switch to Low\n"); | ||
92 | } else { | ||
93 | btrssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
94 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
95 | "BT Rssi state stay at High\n"); | ||
96 | } | ||
97 | } | ||
98 | } else if (level_num == 3) { | ||
99 | if (rssi_thresh > rssi_thresh1) { | ||
100 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
101 | "BT Rssi thresh error!!\n"); | ||
102 | return coex_sta->pre_bt_rssi_state; | ||
103 | } | ||
104 | |||
105 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
106 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
107 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
108 | "BT Rssi pre state = LOW\n"); | ||
109 | if (btrssi >= (rssi_thresh + | ||
110 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
111 | btrssi_state = BTC_RSSI_STATE_MEDIUM; | ||
112 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
113 | "BT Rssi state switch to Medium\n"); | ||
114 | } else { | ||
115 | btrssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
116 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
117 | "BT Rssi state stay at Low\n"); | ||
118 | } | ||
119 | } else if ((coex_sta->pre_bt_rssi_state == | ||
120 | BTC_RSSI_STATE_MEDIUM) || | ||
121 | (coex_sta->pre_bt_rssi_state == | ||
122 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
123 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
124 | "[BTCoex], BT Rssi pre state = MEDIUM\n"); | ||
125 | if (btrssi >= (rssi_thresh1 + | ||
126 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
127 | btrssi_state = BTC_RSSI_STATE_HIGH; | ||
128 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
129 | "BT Rssi state switch to High\n"); | ||
130 | } else if (btrssi < rssi_thresh) { | ||
131 | btrssi_state = BTC_RSSI_STATE_LOW; | ||
132 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
133 | "BT Rssi state switch to Low\n"); | ||
134 | } else { | ||
135 | btrssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
136 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
137 | "BT Rssi state stay at Medium\n"); | ||
138 | } | ||
139 | } else { | ||
140 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
141 | "BT Rssi pre state = HIGH\n"); | ||
142 | if (btrssi < rssi_thresh1) { | ||
143 | btrssi_state = BTC_RSSI_STATE_MEDIUM; | ||
144 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
145 | "BT Rssi state switch to Medium\n"); | ||
146 | } else { | ||
147 | btrssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
148 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
149 | "BT Rssi state stay at High\n"); | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | coex_sta->pre_bt_rssi_state = btrssi_state; | ||
155 | |||
156 | return btrssi_state; | ||
157 | } | ||
158 | |||
159 | static u8 halbtc8192e2ant_wifirssi_state(struct btc_coexist *btcoexist, | ||
160 | u8 index, u8 level_num, u8 rssi_thresh, | ||
161 | u8 rssi_thresh1) | ||
162 | { | ||
163 | int wifirssi = 0; | ||
164 | u8 wifirssi_state = coex_sta->pre_wifi_rssi_state[index]; | ||
165 | |||
166 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi); | ||
167 | |||
168 | if (level_num == 2) { | ||
169 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
170 | BTC_RSSI_STATE_LOW) || | ||
171 | (coex_sta->pre_wifi_rssi_state[index] == | ||
172 | BTC_RSSI_STATE_STAY_LOW)) { | ||
173 | if (wifirssi >= (rssi_thresh + | ||
174 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
175 | wifirssi_state = BTC_RSSI_STATE_HIGH; | ||
176 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
177 | ALGO_WIFI_RSSI_STATE, | ||
178 | "wifi RSSI state switch to High\n"); | ||
179 | } else { | ||
180 | wifirssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
181 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
182 | ALGO_WIFI_RSSI_STATE, | ||
183 | "wifi RSSI state stay at Low\n"); | ||
184 | } | ||
185 | } else { | ||
186 | if (wifirssi < rssi_thresh) { | ||
187 | wifirssi_state = BTC_RSSI_STATE_LOW; | ||
188 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
189 | ALGO_WIFI_RSSI_STATE, | ||
190 | "wifi RSSI state switch to Low\n"); | ||
191 | } else { | ||
192 | wifirssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
193 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
194 | ALGO_WIFI_RSSI_STATE, | ||
195 | "wifi RSSI state stay at High\n"); | ||
196 | } | ||
197 | } | ||
198 | } else if (level_num == 3) { | ||
199 | if (rssi_thresh > rssi_thresh1) { | ||
200 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, | ||
201 | "wifi RSSI thresh error!!\n"); | ||
202 | return coex_sta->pre_wifi_rssi_state[index]; | ||
203 | } | ||
204 | |||
205 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
206 | BTC_RSSI_STATE_LOW) || | ||
207 | (coex_sta->pre_wifi_rssi_state[index] == | ||
208 | BTC_RSSI_STATE_STAY_LOW)) { | ||
209 | if (wifirssi >= (rssi_thresh + | ||
210 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
211 | wifirssi_state = BTC_RSSI_STATE_MEDIUM; | ||
212 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
213 | ALGO_WIFI_RSSI_STATE, | ||
214 | "wifi RSSI state switch to Medium\n"); | ||
215 | } else { | ||
216 | wifirssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
217 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
218 | ALGO_WIFI_RSSI_STATE, | ||
219 | "wifi RSSI state stay at Low\n"); | ||
220 | } | ||
221 | } else if ((coex_sta->pre_wifi_rssi_state[index] == | ||
222 | BTC_RSSI_STATE_MEDIUM) || | ||
223 | (coex_sta->pre_wifi_rssi_state[index] == | ||
224 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
225 | if (wifirssi >= (rssi_thresh1 + | ||
226 | BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) { | ||
227 | wifirssi_state = BTC_RSSI_STATE_HIGH; | ||
228 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
229 | ALGO_WIFI_RSSI_STATE, | ||
230 | "wifi RSSI state switch to High\n"); | ||
231 | } else if (wifirssi < rssi_thresh) { | ||
232 | wifirssi_state = BTC_RSSI_STATE_LOW; | ||
233 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
234 | ALGO_WIFI_RSSI_STATE, | ||
235 | "wifi RSSI state switch to Low\n"); | ||
236 | } else { | ||
237 | wifirssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
238 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
239 | ALGO_WIFI_RSSI_STATE, | ||
240 | "wifi RSSI state stay at Medium\n"); | ||
241 | } | ||
242 | } else { | ||
243 | if (wifirssi < rssi_thresh1) { | ||
244 | wifirssi_state = BTC_RSSI_STATE_MEDIUM; | ||
245 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
246 | ALGO_WIFI_RSSI_STATE, | ||
247 | "wifi RSSI state switch to Medium\n"); | ||
248 | } else { | ||
249 | wifirssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
250 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
251 | ALGO_WIFI_RSSI_STATE, | ||
252 | "wifi RSSI state stay at High\n"); | ||
253 | } | ||
254 | } | ||
255 | } | ||
256 | |||
257 | coex_sta->pre_wifi_rssi_state[index] = wifirssi_state; | ||
258 | |||
259 | return wifirssi_state; | ||
260 | } | ||
261 | |||
262 | static void btc8192e2ant_monitor_bt_enable_dis(struct btc_coexist *btcoexist) | ||
263 | { | ||
264 | static bool pre_bt_disabled; | ||
265 | static u32 bt_disable_cnt; | ||
266 | bool bt_active = true, bt_disabled = false; | ||
267 | |||
268 | /* This function check if bt is disabled */ | ||
269 | |||
270 | if (coex_sta->high_priority_tx == 0 && | ||
271 | coex_sta->high_priority_rx == 0 && | ||
272 | coex_sta->low_priority_tx == 0 && | ||
273 | coex_sta->low_priority_rx == 0) | ||
274 | bt_active = false; | ||
275 | |||
276 | if (coex_sta->high_priority_tx == 0xffff && | ||
277 | coex_sta->high_priority_rx == 0xffff && | ||
278 | coex_sta->low_priority_tx == 0xffff && | ||
279 | coex_sta->low_priority_rx == 0xffff) | ||
280 | bt_active = false; | ||
281 | |||
282 | if (bt_active) { | ||
283 | bt_disable_cnt = 0; | ||
284 | bt_disabled = false; | ||
285 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
286 | &bt_disabled); | ||
287 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
288 | "[BTCoex], BT is enabled !!\n"); | ||
289 | } else { | ||
290 | bt_disable_cnt++; | ||
291 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
292 | "[BTCoex], bt all counters = 0, %d times!!\n", | ||
293 | bt_disable_cnt); | ||
294 | if (bt_disable_cnt >= 2) { | ||
295 | bt_disabled = true; | ||
296 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
297 | &bt_disabled); | ||
298 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
299 | "[BTCoex], BT is disabled !!\n"); | ||
300 | } | ||
301 | } | ||
302 | if (pre_bt_disabled != bt_disabled) { | ||
303 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
304 | "[BTCoex], BT is from %s to %s!!\n", | ||
305 | (pre_bt_disabled ? "disabled" : "enabled"), | ||
306 | (bt_disabled ? "disabled" : "enabled")); | ||
307 | pre_bt_disabled = bt_disabled; | ||
308 | } | ||
309 | } | ||
310 | |||
311 | static u32 halbtc8192e2ant_decidera_mask(struct btc_coexist *btcoexist, | ||
312 | u8 sstype, u32 ra_masktype) | ||
313 | { | ||
314 | u32 disra_mask = 0x0; | ||
315 | |||
316 | switch (ra_masktype) { | ||
317 | case 0: /* normal mode */ | ||
318 | if (sstype == 2) | ||
319 | disra_mask = 0x0; /* enable 2ss */ | ||
320 | else | ||
321 | disra_mask = 0xfff00000;/* disable 2ss */ | ||
322 | break; | ||
323 | case 1: /* disable cck 1/2 */ | ||
324 | if (sstype == 2) | ||
325 | disra_mask = 0x00000003;/* enable 2ss */ | ||
326 | else | ||
327 | disra_mask = 0xfff00003;/* disable 2ss */ | ||
328 | break; | ||
329 | case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */ | ||
330 | if (sstype == 2) | ||
331 | disra_mask = 0x0001f1f7;/* enable 2ss */ | ||
332 | else | ||
333 | disra_mask = 0xfff1f1f7;/* disable 2ss */ | ||
334 | break; | ||
335 | default: | ||
336 | break; | ||
337 | } | ||
338 | |||
339 | return disra_mask; | ||
340 | } | ||
341 | |||
342 | static void halbtc8192e2ant_Updatera_mask(struct btc_coexist *btcoexist, | ||
343 | bool force_exec, u32 dis_ratemask) | ||
344 | { | ||
345 | coex_dm->curra_mask = dis_ratemask; | ||
346 | |||
347 | if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask)) | ||
348 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask, | ||
349 | &coex_dm->curra_mask); | ||
350 | coex_dm->prera_mask = coex_dm->curra_mask; | ||
351 | } | ||
352 | |||
353 | static void btc8192e2ant_autorate_fallback_retry(struct btc_coexist *btcoexist, | ||
354 | bool force_exec, u8 type) | ||
355 | { | ||
356 | bool wifi_under_bmode = false; | ||
357 | |||
358 | coex_dm->cur_arfrtype = type; | ||
359 | |||
360 | if (force_exec || (coex_dm->pre_arfrtype != coex_dm->cur_arfrtype)) { | ||
361 | switch (coex_dm->cur_arfrtype) { | ||
362 | case 0: /* normal mode */ | ||
363 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
364 | coex_dm->backup_arfr_cnt1); | ||
365 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
366 | coex_dm->backup_arfr_cnt2); | ||
367 | break; | ||
368 | case 1: | ||
369 | btcoexist->btc_get(btcoexist, | ||
370 | BTC_GET_BL_WIFI_UNDER_B_MODE, | ||
371 | &wifi_under_bmode); | ||
372 | if (wifi_under_bmode) { | ||
373 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
374 | 0x0); | ||
375 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
376 | 0x01010101); | ||
377 | } else { | ||
378 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
379 | 0x0); | ||
380 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
381 | 0x04030201); | ||
382 | } | ||
383 | break; | ||
384 | default: | ||
385 | break; | ||
386 | } | ||
387 | } | ||
388 | |||
389 | coex_dm->pre_arfrtype = coex_dm->cur_arfrtype; | ||
390 | } | ||
391 | |||
392 | static void halbtc8192e2ant_retrylimit(struct btc_coexist *btcoexist, | ||
393 | bool force_exec, u8 type) | ||
394 | { | ||
395 | coex_dm->cur_retrylimit_type = type; | ||
396 | |||
397 | if (force_exec || (coex_dm->pre_retrylimit_type != | ||
398 | coex_dm->cur_retrylimit_type)) { | ||
399 | switch (coex_dm->cur_retrylimit_type) { | ||
400 | case 0: /* normal mode */ | ||
401 | btcoexist->btc_write_2byte(btcoexist, 0x42a, | ||
402 | coex_dm->backup_retrylimit); | ||
403 | break; | ||
404 | case 1: /* retry limit = 8 */ | ||
405 | btcoexist->btc_write_2byte(btcoexist, 0x42a, | ||
406 | 0x0808); | ||
407 | break; | ||
408 | default: | ||
409 | break; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | coex_dm->pre_retrylimit_type = coex_dm->cur_retrylimit_type; | ||
414 | } | ||
415 | |||
416 | static void halbtc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist, | ||
417 | bool force_exec, u8 type) | ||
418 | { | ||
419 | coex_dm->cur_ampdutime_type = type; | ||
420 | |||
421 | if (force_exec || (coex_dm->pre_ampdutime_type != | ||
422 | coex_dm->cur_ampdutime_type)) { | ||
423 | switch (coex_dm->cur_ampdutime_type) { | ||
424 | case 0: /* normal mode */ | ||
425 | btcoexist->btc_write_1byte(btcoexist, 0x456, | ||
426 | coex_dm->backup_ampdu_maxtime); | ||
427 | break; | ||
428 | case 1: /* AMPDU timw = 0x38 * 32us */ | ||
429 | btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); | ||
430 | break; | ||
431 | default: | ||
432 | break; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | coex_dm->pre_ampdutime_type = coex_dm->cur_ampdutime_type; | ||
437 | } | ||
438 | |||
439 | static void halbtc8192e2ant_limited_tx(struct btc_coexist *btcoexist, | ||
440 | bool force_exec, u8 ra_masktype, | ||
441 | u8 arfr_type, u8 retrylimit_type, | ||
442 | u8 ampdutime_type) | ||
443 | { | ||
444 | u32 disra_mask = 0x0; | ||
445 | |||
446 | coex_dm->curra_masktype = ra_masktype; | ||
447 | disra_mask = halbtc8192e2ant_decidera_mask(btcoexist, | ||
448 | coex_dm->cur_sstype, | ||
449 | ra_masktype); | ||
450 | halbtc8192e2ant_Updatera_mask(btcoexist, force_exec, disra_mask); | ||
451 | btc8192e2ant_autorate_fallback_retry(btcoexist, force_exec, arfr_type); | ||
452 | halbtc8192e2ant_retrylimit(btcoexist, force_exec, retrylimit_type); | ||
453 | halbtc8192e2ant_ampdu_maxtime(btcoexist, force_exec, ampdutime_type); | ||
454 | } | ||
455 | |||
456 | static void halbtc8192e2ant_limited_rx(struct btc_coexist *btcoexist, | ||
457 | bool force_exec, bool rej_ap_agg_pkt, | ||
458 | bool bt_ctrl_agg_buf_size, | ||
459 | u8 agg_buf_size) | ||
460 | { | ||
461 | bool reject_rx_agg = rej_ap_agg_pkt; | ||
462 | bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; | ||
463 | u8 rx_agg_size = agg_buf_size; | ||
464 | |||
465 | /********************************************* | ||
466 | * Rx Aggregation related setting | ||
467 | *********************************************/ | ||
468 | btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, | ||
469 | &reject_rx_agg); | ||
470 | /* decide BT control aggregation buf size or not */ | ||
471 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, | ||
472 | &bt_ctrl_rx_agg_size); | ||
473 | /* aggregation buf size, only work | ||
474 | * when BT control Rx aggregation size. | ||
475 | */ | ||
476 | btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); | ||
477 | /* real update aggregation setting */ | ||
478 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); | ||
479 | } | ||
480 | |||
481 | static void halbtc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) | ||
482 | { | ||
483 | u32 reg_hp_txrx, reg_lp_txrx, u32tmp; | ||
484 | u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; | ||
485 | |||
486 | reg_hp_txrx = 0x770; | ||
487 | reg_lp_txrx = 0x774; | ||
488 | |||
489 | u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); | ||
490 | reg_hp_tx = u32tmp & MASKLWORD; | ||
491 | reg_hp_rx = (u32tmp & MASKHWORD)>>16; | ||
492 | |||
493 | u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); | ||
494 | reg_lp_tx = u32tmp & MASKLWORD; | ||
495 | reg_lp_rx = (u32tmp & MASKHWORD)>>16; | ||
496 | |||
497 | coex_sta->high_priority_tx = reg_hp_tx; | ||
498 | coex_sta->high_priority_rx = reg_hp_rx; | ||
499 | coex_sta->low_priority_tx = reg_lp_tx; | ||
500 | coex_sta->low_priority_rx = reg_lp_rx; | ||
501 | |||
502 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
503 | "[BTCoex] High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", | ||
504 | reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); | ||
505 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
506 | "[BTCoex] Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", | ||
507 | reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); | ||
508 | |||
509 | /* reset counter */ | ||
510 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
511 | } | ||
512 | |||
513 | static void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist) | ||
514 | { | ||
515 | u8 h2c_parameter[1] = {0}; | ||
516 | |||
517 | coex_sta->c2h_bt_info_req_sent = true; | ||
518 | |||
519 | h2c_parameter[0] |= BIT0; /* trigger */ | ||
520 | |||
521 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
522 | "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", | ||
523 | h2c_parameter[0]); | ||
524 | |||
525 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | ||
526 | } | ||
527 | |||
528 | static void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist) | ||
529 | { | ||
530 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
531 | bool bt_hson = false; | ||
532 | |||
533 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson); | ||
534 | |||
535 | bt_link_info->bt_link_exist = coex_sta->bt_link_exist; | ||
536 | bt_link_info->sco_exist = coex_sta->sco_exist; | ||
537 | bt_link_info->a2dp_exist = coex_sta->a2dp_exist; | ||
538 | bt_link_info->pan_exist = coex_sta->pan_exist; | ||
539 | bt_link_info->hid_exist = coex_sta->hid_exist; | ||
540 | |||
541 | /* work around for HS mode. */ | ||
542 | if (bt_hson) { | ||
543 | bt_link_info->pan_exist = true; | ||
544 | bt_link_info->bt_link_exist = true; | ||
545 | } | ||
546 | |||
547 | /* check if Sco only */ | ||
548 | if (bt_link_info->sco_exist && | ||
549 | !bt_link_info->a2dp_exist && | ||
550 | !bt_link_info->pan_exist && | ||
551 | !bt_link_info->hid_exist) | ||
552 | bt_link_info->sco_only = true; | ||
553 | else | ||
554 | bt_link_info->sco_only = false; | ||
555 | |||
556 | /* check if A2dp only */ | ||
557 | if (!bt_link_info->sco_exist && | ||
558 | bt_link_info->a2dp_exist && | ||
559 | !bt_link_info->pan_exist && | ||
560 | !bt_link_info->hid_exist) | ||
561 | bt_link_info->a2dp_only = true; | ||
562 | else | ||
563 | bt_link_info->a2dp_only = false; | ||
564 | |||
565 | /* check if Pan only */ | ||
566 | if (!bt_link_info->sco_exist && | ||
567 | !bt_link_info->a2dp_exist && | ||
568 | bt_link_info->pan_exist && | ||
569 | !bt_link_info->hid_exist) | ||
570 | bt_link_info->pan_only = true; | ||
571 | else | ||
572 | bt_link_info->pan_only = false; | ||
573 | |||
574 | /* check if Hid only */ | ||
575 | if (!bt_link_info->sco_exist && | ||
576 | !bt_link_info->a2dp_exist && | ||
577 | !bt_link_info->pan_exist && | ||
578 | bt_link_info->hid_exist) | ||
579 | bt_link_info->hid_only = true; | ||
580 | else | ||
581 | bt_link_info->hid_only = false; | ||
582 | } | ||
583 | |||
584 | static u8 halbtc8192e2ant_action_algorithm(struct btc_coexist *btcoexist) | ||
585 | { | ||
586 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
587 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
588 | bool bt_hson = false; | ||
589 | u8 algorithm = BT_8192E_2ANT_COEX_ALGO_UNDEFINED; | ||
590 | u8 numdiffprofile = 0; | ||
591 | |||
592 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson); | ||
593 | |||
594 | if (!bt_link_info->bt_link_exist) { | ||
595 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
596 | "No BT link exists!!!\n"); | ||
597 | return algorithm; | ||
598 | } | ||
599 | |||
600 | if (bt_link_info->sco_exist) | ||
601 | numdiffprofile++; | ||
602 | if (bt_link_info->hid_exist) | ||
603 | numdiffprofile++; | ||
604 | if (bt_link_info->pan_exist) | ||
605 | numdiffprofile++; | ||
606 | if (bt_link_info->a2dp_exist) | ||
607 | numdiffprofile++; | ||
608 | |||
609 | if (numdiffprofile == 1) { | ||
610 | if (bt_link_info->sco_exist) { | ||
611 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
612 | "SCO only\n"); | ||
613 | algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; | ||
614 | } else { | ||
615 | if (bt_link_info->hid_exist) { | ||
616 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
617 | "HID only\n"); | ||
618 | algorithm = BT_8192E_2ANT_COEX_ALGO_HID; | ||
619 | } else if (bt_link_info->a2dp_exist) { | ||
620 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
621 | "A2DP only\n"); | ||
622 | algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP; | ||
623 | } else if (bt_link_info->pan_exist) { | ||
624 | if (bt_hson) { | ||
625 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
626 | "PAN(HS) only\n"); | ||
627 | algorithm = | ||
628 | BT_8192E_2ANT_COEX_ALGO_PANHS; | ||
629 | } else { | ||
630 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
631 | "PAN(EDR) only\n"); | ||
632 | algorithm = | ||
633 | BT_8192E_2ANT_COEX_ALGO_PANEDR; | ||
634 | } | ||
635 | } | ||
636 | } | ||
637 | } else if (numdiffprofile == 2) { | ||
638 | if (bt_link_info->sco_exist) { | ||
639 | if (bt_link_info->hid_exist) { | ||
640 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
641 | "SCO + HID\n"); | ||
642 | algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; | ||
643 | } else if (bt_link_info->a2dp_exist) { | ||
644 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
645 | "SCO + A2DP ==> SCO\n"); | ||
646 | algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; | ||
647 | } else if (bt_link_info->pan_exist) { | ||
648 | if (bt_hson) { | ||
649 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
650 | "SCO + PAN(HS)\n"); | ||
651 | algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; | ||
652 | } else { | ||
653 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
654 | "SCO + PAN(EDR)\n"); | ||
655 | algorithm = | ||
656 | BT_8192E_2ANT_COEX_ALGO_SCO_PAN; | ||
657 | } | ||
658 | } | ||
659 | } else { | ||
660 | if (bt_link_info->hid_exist && | ||
661 | bt_link_info->a2dp_exist) { | ||
662 | if (stack_info->num_of_hid >= 2) { | ||
663 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
664 | "HID*2 + A2DP\n"); | ||
665 | algorithm = | ||
666 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
667 | } else { | ||
668 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
669 | "HID + A2DP\n"); | ||
670 | algorithm = | ||
671 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP; | ||
672 | } | ||
673 | } else if (bt_link_info->hid_exist && | ||
674 | bt_link_info->pan_exist) { | ||
675 | if (bt_hson) { | ||
676 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
677 | "HID + PAN(HS)\n"); | ||
678 | algorithm = BT_8192E_2ANT_COEX_ALGO_HID; | ||
679 | } else { | ||
680 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
681 | "HID + PAN(EDR)\n"); | ||
682 | algorithm = | ||
683 | BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; | ||
684 | } | ||
685 | } else if (bt_link_info->pan_exist && | ||
686 | bt_link_info->a2dp_exist) { | ||
687 | if (bt_hson) { | ||
688 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
689 | "A2DP + PAN(HS)\n"); | ||
690 | algorithm = | ||
691 | BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS; | ||
692 | } else { | ||
693 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
694 | "A2DP + PAN(EDR)\n"); | ||
695 | algorithm = | ||
696 | BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP; | ||
697 | } | ||
698 | } | ||
699 | } | ||
700 | } else if (numdiffprofile == 3) { | ||
701 | if (bt_link_info->sco_exist) { | ||
702 | if (bt_link_info->hid_exist && | ||
703 | bt_link_info->a2dp_exist) { | ||
704 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
705 | "SCO + HID + A2DP ==> HID\n"); | ||
706 | algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; | ||
707 | } else if (bt_link_info->hid_exist && | ||
708 | bt_link_info->pan_exist) { | ||
709 | if (bt_hson) { | ||
710 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
711 | "SCO + HID + PAN(HS)\n"); | ||
712 | algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; | ||
713 | } else { | ||
714 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
715 | "SCO + HID + PAN(EDR)\n"); | ||
716 | algorithm = | ||
717 | BT_8192E_2ANT_COEX_ALGO_SCO_PAN; | ||
718 | } | ||
719 | } else if (bt_link_info->pan_exist && | ||
720 | bt_link_info->a2dp_exist) { | ||
721 | if (bt_hson) { | ||
722 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
723 | "SCO + A2DP + PAN(HS)\n"); | ||
724 | algorithm = BT_8192E_2ANT_COEX_ALGO_SCO; | ||
725 | } else { | ||
726 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
727 | "SCO + A2DP + PAN(EDR)\n"); | ||
728 | algorithm = | ||
729 | BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; | ||
730 | } | ||
731 | } | ||
732 | } else { | ||
733 | if (bt_link_info->hid_exist && | ||
734 | bt_link_info->pan_exist && | ||
735 | bt_link_info->a2dp_exist) { | ||
736 | if (bt_hson) { | ||
737 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
738 | "HID + A2DP + PAN(HS)\n"); | ||
739 | algorithm = | ||
740 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP; | ||
741 | } else { | ||
742 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
743 | "HID + A2DP + PAN(EDR)\n"); | ||
744 | algorithm = | ||
745 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
746 | } | ||
747 | } | ||
748 | } | ||
749 | } else if (numdiffprofile >= 3) { | ||
750 | if (bt_link_info->sco_exist) { | ||
751 | if (bt_link_info->hid_exist && | ||
752 | bt_link_info->pan_exist && | ||
753 | bt_link_info->a2dp_exist) { | ||
754 | if (bt_hson) { | ||
755 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
756 | "ErrorSCO+HID+A2DP+PAN(HS)\n"); | ||
757 | |||
758 | } else { | ||
759 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
760 | "SCO+HID+A2DP+PAN(EDR)\n"); | ||
761 | algorithm = | ||
762 | BT_8192E_2ANT_COEX_ALGO_PANEDR_HID; | ||
763 | } | ||
764 | } | ||
765 | } | ||
766 | } | ||
767 | |||
768 | return algorithm; | ||
769 | } | ||
770 | |||
771 | static void halbtc8192e2ant_setfw_dac_swinglevel(struct btc_coexist *btcoexist, | ||
772 | u8 dac_swinglvl) | ||
773 | { | ||
774 | u8 h2c_parameter[1] = {0}; | ||
775 | |||
776 | /* There are several type of dacswing | ||
777 | * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 | ||
778 | */ | ||
779 | h2c_parameter[0] = dac_swinglvl; | ||
780 | |||
781 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
782 | "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swinglvl); | ||
783 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
784 | "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]); | ||
785 | |||
786 | btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); | ||
787 | } | ||
788 | |||
789 | static void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist, | ||
790 | u8 dec_btpwr_lvl) | ||
791 | { | ||
792 | u8 h2c_parameter[1] = {0}; | ||
793 | |||
794 | h2c_parameter[0] = dec_btpwr_lvl; | ||
795 | |||
796 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
797 | "[BTCoex] decrease Bt Power level = %d, FW write 0x62 = 0x%x\n", | ||
798 | dec_btpwr_lvl, h2c_parameter[0]); | ||
799 | |||
800 | btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); | ||
801 | } | ||
802 | |||
803 | static void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist, | ||
804 | bool force_exec, u8 dec_btpwr_lvl) | ||
805 | { | ||
806 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
807 | "[BTCoex], %s Dec BT power level = %d\n", | ||
808 | (force_exec ? "force to" : ""), dec_btpwr_lvl); | ||
809 | coex_dm->cur_dec_bt_pwr = dec_btpwr_lvl; | ||
810 | |||
811 | if (!force_exec) { | ||
812 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
813 | "[BTCoex], preBtDecPwrLvl=%d, curBtDecPwrLvl=%d\n", | ||
814 | coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr); | ||
815 | } | ||
816 | halbtc8192e2ant_set_fwdec_btpwr(btcoexist, coex_dm->cur_dec_bt_pwr); | ||
817 | |||
818 | coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr; | ||
819 | } | ||
820 | |||
821 | static void halbtc8192e2ant_set_bt_autoreport(struct btc_coexist *btcoexist, | ||
822 | bool enable_autoreport) | ||
823 | { | ||
824 | u8 h2c_parameter[1] = {0}; | ||
825 | |||
826 | h2c_parameter[0] = 0; | ||
827 | |||
828 | if (enable_autoreport) | ||
829 | h2c_parameter[0] |= BIT0; | ||
830 | |||
831 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
832 | "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n", | ||
833 | (enable_autoreport ? "Enabled!!" : "Disabled!!"), | ||
834 | h2c_parameter[0]); | ||
835 | |||
836 | btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); | ||
837 | } | ||
838 | |||
839 | static void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist, | ||
840 | bool force_exec, | ||
841 | bool enable_autoreport) | ||
842 | { | ||
843 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
844 | "[BTCoex], %s BT Auto report = %s\n", | ||
845 | (force_exec ? "force to" : ""), | ||
846 | ((enable_autoreport) ? "Enabled" : "Disabled")); | ||
847 | coex_dm->cur_bt_auto_report = enable_autoreport; | ||
848 | |||
849 | if (!force_exec) { | ||
850 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
851 | "[BTCoex] bPreBtAutoReport=%d, bCurBtAutoReport=%d\n", | ||
852 | coex_dm->pre_bt_auto_report, | ||
853 | coex_dm->cur_bt_auto_report); | ||
854 | |||
855 | if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) | ||
856 | return; | ||
857 | } | ||
858 | halbtc8192e2ant_set_bt_autoreport(btcoexist, | ||
859 | coex_dm->cur_bt_auto_report); | ||
860 | |||
861 | coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; | ||
862 | } | ||
863 | |||
864 | static void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist, | ||
865 | bool force_exec, u8 fw_dac_swinglvl) | ||
866 | { | ||
867 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
868 | "[BTCoex], %s set FW Dac Swing level = %d\n", | ||
869 | (force_exec ? "force to" : ""), fw_dac_swinglvl); | ||
870 | coex_dm->cur_fw_dac_swing_lvl = fw_dac_swinglvl; | ||
871 | |||
872 | if (!force_exec) { | ||
873 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
874 | "[BTCoex] preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n", | ||
875 | coex_dm->pre_fw_dac_swing_lvl, | ||
876 | coex_dm->cur_fw_dac_swing_lvl); | ||
877 | |||
878 | if (coex_dm->pre_fw_dac_swing_lvl == | ||
879 | coex_dm->cur_fw_dac_swing_lvl) | ||
880 | return; | ||
881 | } | ||
882 | |||
883 | halbtc8192e2ant_setfw_dac_swinglevel(btcoexist, | ||
884 | coex_dm->cur_fw_dac_swing_lvl); | ||
885 | |||
886 | coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; | ||
887 | } | ||
888 | |||
889 | static void btc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist, | ||
890 | bool rx_rf_shrink_on) | ||
891 | { | ||
892 | if (rx_rf_shrink_on) { | ||
893 | /* Shrink RF Rx LPF corner */ | ||
894 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
895 | "[BTCoex], Shrink RF Rx LPF corner!!\n"); | ||
896 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, | ||
897 | 0xfffff, 0xffffc); | ||
898 | } else { | ||
899 | /* Resume RF Rx LPF corner | ||
900 | * After initialized, we can use coex_dm->btRf0x1eBackup | ||
901 | */ | ||
902 | if (btcoexist->initilized) { | ||
903 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
904 | "[BTCoex], Resume RF Rx LPF corner!!\n"); | ||
905 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, | ||
906 | 0xfffff, | ||
907 | coex_dm->bt_rf0x1e_backup); | ||
908 | } | ||
909 | } | ||
910 | } | ||
911 | |||
912 | static void halbtc8192e2ant_rf_shrink(struct btc_coexist *btcoexist, | ||
913 | bool force_exec, bool rx_rf_shrink_on) | ||
914 | { | ||
915 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
916 | "[BTCoex], %s turn Rx RF Shrink = %s\n", | ||
917 | (force_exec ? "force to" : ""), | ||
918 | ((rx_rf_shrink_on) ? "ON" : "OFF")); | ||
919 | coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on; | ||
920 | |||
921 | if (!force_exec) { | ||
922 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
923 | "[BTCoex]bPreRfRxLpfShrink=%d,bCurRfRxLpfShrink=%d\n", | ||
924 | coex_dm->pre_rf_rx_lpf_shrink, | ||
925 | coex_dm->cur_rf_rx_lpf_shrink); | ||
926 | |||
927 | if (coex_dm->pre_rf_rx_lpf_shrink == | ||
928 | coex_dm->cur_rf_rx_lpf_shrink) | ||
929 | return; | ||
930 | } | ||
931 | btc8192e2ant_set_sw_rf_rx_lpf_corner(btcoexist, | ||
932 | coex_dm->cur_rf_rx_lpf_shrink); | ||
933 | |||
934 | coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink; | ||
935 | } | ||
936 | |||
937 | static void halbtc8192e2ant_set_dac_swingreg(struct btc_coexist *btcoexist, | ||
938 | u32 level) | ||
939 | { | ||
940 | u8 val = (u8)level; | ||
941 | |||
942 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
943 | "[BTCoex], Write SwDacSwing = 0x%x\n", level); | ||
944 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val); | ||
945 | } | ||
946 | |||
947 | static void btc8192e2ant_setsw_full_swing(struct btc_coexist *btcoexist, | ||
948 | bool sw_dac_swingon, | ||
949 | u32 sw_dac_swinglvl) | ||
950 | { | ||
951 | if (sw_dac_swingon) | ||
952 | halbtc8192e2ant_set_dac_swingreg(btcoexist, sw_dac_swinglvl); | ||
953 | else | ||
954 | halbtc8192e2ant_set_dac_swingreg(btcoexist, 0x18); | ||
955 | } | ||
956 | |||
957 | static void halbtc8192e2ant_DacSwing(struct btc_coexist *btcoexist, | ||
958 | bool force_exec, bool dac_swingon, | ||
959 | u32 dac_swinglvl) | ||
960 | { | ||
961 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
962 | "[BTCoex], %s turn DacSwing=%s, dac_swinglvl = 0x%x\n", | ||
963 | (force_exec ? "force to" : ""), | ||
964 | ((dac_swingon) ? "ON" : "OFF"), dac_swinglvl); | ||
965 | coex_dm->cur_dac_swing_on = dac_swingon; | ||
966 | coex_dm->cur_dac_swing_lvl = dac_swinglvl; | ||
967 | |||
968 | if (!force_exec) { | ||
969 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
970 | "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl = 0x%x, ", | ||
971 | coex_dm->pre_dac_swing_on, | ||
972 | coex_dm->pre_dac_swing_lvl); | ||
973 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
974 | "bCurDacSwingOn=%d, curDacSwingLvl = 0x%x\n", | ||
975 | coex_dm->cur_dac_swing_on, | ||
976 | coex_dm->cur_dac_swing_lvl); | ||
977 | |||
978 | if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && | ||
979 | (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl)) | ||
980 | return; | ||
981 | } | ||
982 | mdelay(30); | ||
983 | btc8192e2ant_setsw_full_swing(btcoexist, dac_swingon, dac_swinglvl); | ||
984 | |||
985 | coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; | ||
986 | coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; | ||
987 | } | ||
988 | |||
989 | static void halbtc8192e2ant_set_agc_table(struct btc_coexist *btcoexist, | ||
990 | bool agc_table_en) | ||
991 | { | ||
992 | /* BB AGC Gain Table */ | ||
993 | if (agc_table_en) { | ||
994 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
995 | "[BTCoex], BB Agc Table On!\n"); | ||
996 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x0a1A0001); | ||
997 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x091B0001); | ||
998 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x081C0001); | ||
999 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x071D0001); | ||
1000 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x061E0001); | ||
1001 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x051F0001); | ||
1002 | } else { | ||
1003 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
1004 | "[BTCoex], BB Agc Table Off!\n"); | ||
1005 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001); | ||
1006 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001); | ||
1007 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001); | ||
1008 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001); | ||
1009 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001); | ||
1010 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001); | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | static void halbtc8192e2ant_AgcTable(struct btc_coexist *btcoexist, | ||
1015 | bool force_exec, bool agc_table_en) | ||
1016 | { | ||
1017 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
1018 | "[BTCoex], %s %s Agc Table\n", | ||
1019 | (force_exec ? "force to" : ""), | ||
1020 | ((agc_table_en) ? "Enable" : "Disable")); | ||
1021 | coex_dm->cur_agc_table_en = agc_table_en; | ||
1022 | |||
1023 | if (!force_exec) { | ||
1024 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1025 | "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n", | ||
1026 | coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en); | ||
1027 | |||
1028 | if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en) | ||
1029 | return; | ||
1030 | } | ||
1031 | halbtc8192e2ant_set_agc_table(btcoexist, agc_table_en); | ||
1032 | |||
1033 | coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en; | ||
1034 | } | ||
1035 | |||
1036 | static void halbtc8192e2ant_set_coex_table(struct btc_coexist *btcoexist, | ||
1037 | u32 val0x6c0, u32 val0x6c4, | ||
1038 | u32 val0x6c8, u8 val0x6cc) | ||
1039 | { | ||
1040 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
1041 | "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); | ||
1042 | btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); | ||
1043 | |||
1044 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
1045 | "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); | ||
1046 | btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); | ||
1047 | |||
1048 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
1049 | "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); | ||
1050 | btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); | ||
1051 | |||
1052 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
1053 | "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); | ||
1054 | btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); | ||
1055 | } | ||
1056 | |||
1057 | static void halbtc8192e2ant_coex_table(struct btc_coexist *btcoexist, | ||
1058 | bool force_exec, | ||
1059 | u32 val0x6c0, u32 val0x6c4, | ||
1060 | u32 val0x6c8, u8 val0x6cc) | ||
1061 | { | ||
1062 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
1063 | "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, ", | ||
1064 | (force_exec ? "force to" : ""), val0x6c0); | ||
1065 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
1066 | "0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", | ||
1067 | val0x6c4, val0x6c8, val0x6cc); | ||
1068 | coex_dm->cur_val0x6c0 = val0x6c0; | ||
1069 | coex_dm->cur_val0x6c4 = val0x6c4; | ||
1070 | coex_dm->cur_val0x6c8 = val0x6c8; | ||
1071 | coex_dm->cur_val0x6cc = val0x6cc; | ||
1072 | |||
1073 | if (!force_exec) { | ||
1074 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1075 | "[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c4 = 0x%x, ", | ||
1076 | coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4); | ||
1077 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1078 | "preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", | ||
1079 | coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc); | ||
1080 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1081 | "[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c4 = 0x%x,\n", | ||
1082 | coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4); | ||
1083 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1084 | "curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", | ||
1085 | coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc); | ||
1086 | |||
1087 | if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && | ||
1088 | (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && | ||
1089 | (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && | ||
1090 | (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) | ||
1091 | return; | ||
1092 | } | ||
1093 | halbtc8192e2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, | ||
1094 | val0x6c8, val0x6cc); | ||
1095 | |||
1096 | coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; | ||
1097 | coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; | ||
1098 | coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; | ||
1099 | coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; | ||
1100 | } | ||
1101 | |||
1102 | static void btc8192e2ant_coex_tbl_w_type(struct btc_coexist *btcoexist, | ||
1103 | bool force_exec, u8 type) | ||
1104 | { | ||
1105 | switch (type) { | ||
1106 | case 0: | ||
1107 | halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
1108 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
1109 | break; | ||
1110 | case 1: | ||
1111 | halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, | ||
1112 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
1113 | break; | ||
1114 | case 2: | ||
1115 | halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
1116 | 0x5ffb5ffb, 0xffffff, 0x3); | ||
1117 | break; | ||
1118 | case 3: | ||
1119 | halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff, | ||
1120 | 0x5fdb5fdb, 0xffffff, 0x3); | ||
1121 | break; | ||
1122 | case 4: | ||
1123 | halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff, | ||
1124 | 0x5ffb5ffb, 0xffffff, 0x3); | ||
1125 | break; | ||
1126 | default: | ||
1127 | break; | ||
1128 | } | ||
1129 | } | ||
1130 | |||
1131 | static void halbtc8192e2ant_set_fw_ignore_wlanact(struct btc_coexist *btcoexist, | ||
1132 | bool enable) | ||
1133 | { | ||
1134 | u8 h2c_parameter[1] = {0}; | ||
1135 | |||
1136 | if (enable) | ||
1137 | h2c_parameter[0] |= BIT0; /* function enable */ | ||
1138 | |||
1139 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
1140 | "[BTCoex]set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", | ||
1141 | h2c_parameter[0]); | ||
1142 | |||
1143 | btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); | ||
1144 | } | ||
1145 | |||
1146 | static void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist, | ||
1147 | bool force_exec, bool enable) | ||
1148 | { | ||
1149 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1150 | "[BTCoex], %s turn Ignore WlanAct %s\n", | ||
1151 | (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); | ||
1152 | coex_dm->cur_ignore_wlan_act = enable; | ||
1153 | |||
1154 | if (!force_exec) { | ||
1155 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1156 | "[BTCoex], bPreIgnoreWlanAct = %d ", | ||
1157 | coex_dm->pre_ignore_wlan_act); | ||
1158 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1159 | "bCurIgnoreWlanAct = %d!!\n", | ||
1160 | coex_dm->cur_ignore_wlan_act); | ||
1161 | |||
1162 | if (coex_dm->pre_ignore_wlan_act == | ||
1163 | coex_dm->cur_ignore_wlan_act) | ||
1164 | return; | ||
1165 | } | ||
1166 | halbtc8192e2ant_set_fw_ignore_wlanact(btcoexist, enable); | ||
1167 | |||
1168 | coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; | ||
1169 | } | ||
1170 | |||
1171 | static void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1, | ||
1172 | u8 byte2, u8 byte3, u8 byte4, u8 byte5) | ||
1173 | { | ||
1174 | u8 h2c_parameter[5] = {0}; | ||
1175 | |||
1176 | h2c_parameter[0] = byte1; | ||
1177 | h2c_parameter[1] = byte2; | ||
1178 | h2c_parameter[2] = byte3; | ||
1179 | h2c_parameter[3] = byte4; | ||
1180 | h2c_parameter[4] = byte5; | ||
1181 | |||
1182 | coex_dm->ps_tdma_para[0] = byte1; | ||
1183 | coex_dm->ps_tdma_para[1] = byte2; | ||
1184 | coex_dm->ps_tdma_para[2] = byte3; | ||
1185 | coex_dm->ps_tdma_para[3] = byte4; | ||
1186 | coex_dm->ps_tdma_para[4] = byte5; | ||
1187 | |||
1188 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
1189 | "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n", | ||
1190 | h2c_parameter[0], | ||
1191 | h2c_parameter[1] << 24 | h2c_parameter[2] << 16 | | ||
1192 | h2c_parameter[3] << 8 | h2c_parameter[4]); | ||
1193 | |||
1194 | btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); | ||
1195 | } | ||
1196 | |||
1197 | static void btc8192e2ant_sw_mec1(struct btc_coexist *btcoexist, | ||
1198 | bool shrink_rx_lpf, bool low_penalty_ra, | ||
1199 | bool limited_dig, bool btlan_constrain) | ||
1200 | { | ||
1201 | halbtc8192e2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf); | ||
1202 | } | ||
1203 | |||
1204 | static void btc8192e2ant_sw_mec2(struct btc_coexist *btcoexist, | ||
1205 | bool agc_table_shift, bool adc_backoff, | ||
1206 | bool sw_dac_swing, u32 dac_swinglvl) | ||
1207 | { | ||
1208 | halbtc8192e2ant_AgcTable(btcoexist, NORMAL_EXEC, agc_table_shift); | ||
1209 | halbtc8192e2ant_DacSwing(btcoexist, NORMAL_EXEC, sw_dac_swing, | ||
1210 | dac_swinglvl); | ||
1211 | } | ||
1212 | |||
1213 | static void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist, | ||
1214 | bool force_exec, bool turn_on, u8 type) | ||
1215 | { | ||
1216 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1217 | "[BTCoex], %s turn %s PS TDMA, type=%d\n", | ||
1218 | (force_exec ? "force to" : ""), | ||
1219 | (turn_on ? "ON" : "OFF"), type); | ||
1220 | coex_dm->cur_ps_tdma_on = turn_on; | ||
1221 | coex_dm->cur_ps_tdma = type; | ||
1222 | |||
1223 | if (!force_exec) { | ||
1224 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1225 | "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n", | ||
1226 | coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); | ||
1227 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1228 | "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n", | ||
1229 | coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); | ||
1230 | |||
1231 | if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && | ||
1232 | (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) | ||
1233 | return; | ||
1234 | } | ||
1235 | if (turn_on) { | ||
1236 | switch (type) { | ||
1237 | case 1: | ||
1238 | default: | ||
1239 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, | ||
1240 | 0x1a, 0xe1, 0x90); | ||
1241 | break; | ||
1242 | case 2: | ||
1243 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12, | ||
1244 | 0x12, 0xe1, 0x90); | ||
1245 | break; | ||
1246 | case 3: | ||
1247 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c, | ||
1248 | 0x3, 0xf1, 0x90); | ||
1249 | break; | ||
1250 | case 4: | ||
1251 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10, | ||
1252 | 0x3, 0xf1, 0x90); | ||
1253 | break; | ||
1254 | case 5: | ||
1255 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, | ||
1256 | 0x1a, 0x60, 0x90); | ||
1257 | break; | ||
1258 | case 6: | ||
1259 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12, | ||
1260 | 0x12, 0x60, 0x90); | ||
1261 | break; | ||
1262 | case 7: | ||
1263 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c, | ||
1264 | 0x3, 0x70, 0x90); | ||
1265 | break; | ||
1266 | case 8: | ||
1267 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xa3, 0x10, | ||
1268 | 0x3, 0x70, 0x90); | ||
1269 | break; | ||
1270 | case 9: | ||
1271 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, | ||
1272 | 0x1a, 0xe1, 0x10); | ||
1273 | break; | ||
1274 | case 10: | ||
1275 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12, | ||
1276 | 0x12, 0xe1, 0x10); | ||
1277 | break; | ||
1278 | case 11: | ||
1279 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c, | ||
1280 | 0x3, 0xf1, 0x10); | ||
1281 | break; | ||
1282 | case 12: | ||
1283 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10, | ||
1284 | 0x3, 0xf1, 0x10); | ||
1285 | break; | ||
1286 | case 13: | ||
1287 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, | ||
1288 | 0x1a, 0xe0, 0x10); | ||
1289 | break; | ||
1290 | case 14: | ||
1291 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12, | ||
1292 | 0x12, 0xe0, 0x10); | ||
1293 | break; | ||
1294 | case 15: | ||
1295 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c, | ||
1296 | 0x3, 0xf0, 0x10); | ||
1297 | break; | ||
1298 | case 16: | ||
1299 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12, | ||
1300 | 0x3, 0xf0, 0x10); | ||
1301 | break; | ||
1302 | case 17: | ||
1303 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0x61, 0x20, | ||
1304 | 0x03, 0x10, 0x10); | ||
1305 | break; | ||
1306 | case 18: | ||
1307 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x5, | ||
1308 | 0x5, 0xe1, 0x90); | ||
1309 | break; | ||
1310 | case 19: | ||
1311 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25, | ||
1312 | 0x25, 0xe1, 0x90); | ||
1313 | break; | ||
1314 | case 20: | ||
1315 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25, | ||
1316 | 0x25, 0x60, 0x90); | ||
1317 | break; | ||
1318 | case 21: | ||
1319 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x15, | ||
1320 | 0x03, 0x70, 0x90); | ||
1321 | break; | ||
1322 | case 71: | ||
1323 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, | ||
1324 | 0x1a, 0xe1, 0x90); | ||
1325 | break; | ||
1326 | } | ||
1327 | } else { | ||
1328 | /* disable PS tdma */ | ||
1329 | switch (type) { | ||
1330 | default: | ||
1331 | case 0: | ||
1332 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0x8, 0x0, 0x0, | ||
1333 | 0x0, 0x0); | ||
1334 | btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4); | ||
1335 | break; | ||
1336 | case 1: | ||
1337 | halbtc8192e2ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1338 | 0x8, 0x0); | ||
1339 | mdelay(5); | ||
1340 | btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20); | ||
1341 | break; | ||
1342 | } | ||
1343 | } | ||
1344 | |||
1345 | /* update pre state */ | ||
1346 | coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; | ||
1347 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; | ||
1348 | } | ||
1349 | |||
1350 | static void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist, | ||
1351 | u8 sstype) | ||
1352 | { | ||
1353 | u8 mimops = BTC_MIMO_PS_DYNAMIC; | ||
1354 | u32 disra_mask = 0x0; | ||
1355 | |||
1356 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1357 | "[BTCoex], REAL set SS Type = %d\n", sstype); | ||
1358 | |||
1359 | disra_mask = halbtc8192e2ant_decidera_mask(btcoexist, sstype, | ||
1360 | coex_dm->curra_masktype); | ||
1361 | halbtc8192e2ant_Updatera_mask(btcoexist, FORCE_EXEC, disra_mask); | ||
1362 | |||
1363 | if (sstype == 1) { | ||
1364 | halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); | ||
1365 | /* switch ofdm path */ | ||
1366 | btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x11); | ||
1367 | btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x1); | ||
1368 | btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81111111); | ||
1369 | /* switch cck patch */ | ||
1370 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x1); | ||
1371 | btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x81); | ||
1372 | mimops = BTC_MIMO_PS_STATIC; | ||
1373 | } else if (sstype == 2) { | ||
1374 | halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); | ||
1375 | btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x33); | ||
1376 | btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x3); | ||
1377 | btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81121313); | ||
1378 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x0); | ||
1379 | btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x41); | ||
1380 | mimops = BTC_MIMO_PS_DYNAMIC; | ||
1381 | } | ||
1382 | /* set rx 1ss or 2ss */ | ||
1383 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops); | ||
1384 | } | ||
1385 | |||
1386 | static void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist, | ||
1387 | bool force_exec, u8 new_sstype) | ||
1388 | { | ||
1389 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1390 | "[BTCoex], %s Switch SS Type = %d\n", | ||
1391 | (force_exec ? "force to" : ""), new_sstype); | ||
1392 | coex_dm->cur_sstype = new_sstype; | ||
1393 | |||
1394 | if (!force_exec) { | ||
1395 | if (coex_dm->pre_sstype == coex_dm->cur_sstype) | ||
1396 | return; | ||
1397 | } | ||
1398 | halbtc8192e2ant_set_switch_sstype(btcoexist, coex_dm->cur_sstype); | ||
1399 | |||
1400 | coex_dm->pre_sstype = coex_dm->cur_sstype; | ||
1401 | } | ||
1402 | |||
1403 | static void halbtc8192e2ant_coex_alloff(struct btc_coexist *btcoexist) | ||
1404 | { | ||
1405 | /* fw all off */ | ||
1406 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
1407 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
1408 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
1409 | |||
1410 | /* sw all off */ | ||
1411 | btc8192e2ant_sw_mec1(btcoexist, false, false, false, false); | ||
1412 | btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18); | ||
1413 | |||
1414 | /* hw all off */ | ||
1415 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 0); | ||
1416 | } | ||
1417 | |||
1418 | static void halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
1419 | { | ||
1420 | /* force to reset coex mechanism */ | ||
1421 | |||
1422 | halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); | ||
1423 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, FORCE_EXEC, 6); | ||
1424 | halbtc8192e2ant_dec_btpwr(btcoexist, FORCE_EXEC, 0); | ||
1425 | |||
1426 | btc8192e2ant_coex_tbl_w_type(btcoexist, FORCE_EXEC, 0); | ||
1427 | halbtc8192e2ant_switch_sstype(btcoexist, FORCE_EXEC, 2); | ||
1428 | |||
1429 | btc8192e2ant_sw_mec1(btcoexist, false, false, false, false); | ||
1430 | btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18); | ||
1431 | } | ||
1432 | |||
1433 | static void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist) | ||
1434 | { | ||
1435 | bool low_pwr_disable = true; | ||
1436 | |||
1437 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1438 | &low_pwr_disable); | ||
1439 | |||
1440 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
1441 | |||
1442 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
1443 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | ||
1444 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
1445 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
1446 | |||
1447 | btc8192e2ant_sw_mec1(btcoexist, false, false, false, false); | ||
1448 | btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18); | ||
1449 | } | ||
1450 | |||
1451 | static bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist) | ||
1452 | { | ||
1453 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1454 | bool common = false, wifi_connected = false, wifi_busy = false; | ||
1455 | bool bt_hson = false, low_pwr_disable = false; | ||
1456 | |||
1457 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson); | ||
1458 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1459 | &wifi_connected); | ||
1460 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1461 | |||
1462 | if (bt_link_info->sco_exist || bt_link_info->hid_exist) | ||
1463 | halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 0, 0, 0); | ||
1464 | else | ||
1465 | halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
1466 | |||
1467 | if (!wifi_connected) { | ||
1468 | low_pwr_disable = false; | ||
1469 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1470 | &low_pwr_disable); | ||
1471 | |||
1472 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1473 | "[BTCoex], Wifi non-connected idle!!\n"); | ||
1474 | |||
1475 | if ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
1476 | coex_dm->bt_status) || | ||
1477 | (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == | ||
1478 | coex_dm->bt_status)) { | ||
1479 | halbtc8192e2ant_switch_sstype(btcoexist, | ||
1480 | NORMAL_EXEC, 2); | ||
1481 | btc8192e2ant_coex_tbl_w_type(btcoexist, | ||
1482 | NORMAL_EXEC, 1); | ||
1483 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1484 | false, 0); | ||
1485 | } else { | ||
1486 | halbtc8192e2ant_switch_sstype(btcoexist, | ||
1487 | NORMAL_EXEC, 1); | ||
1488 | btc8192e2ant_coex_tbl_w_type(btcoexist, | ||
1489 | NORMAL_EXEC, 0); | ||
1490 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1491 | false, 1); | ||
1492 | } | ||
1493 | |||
1494 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
1495 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
1496 | |||
1497 | btc8192e2ant_sw_mec1(btcoexist, false, false, false, false); | ||
1498 | btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18); | ||
1499 | |||
1500 | common = true; | ||
1501 | } else { | ||
1502 | if (BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
1503 | coex_dm->bt_status) { | ||
1504 | low_pwr_disable = false; | ||
1505 | btcoexist->btc_set(btcoexist, | ||
1506 | BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1507 | &low_pwr_disable); | ||
1508 | |||
1509 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1510 | "Wifi connected + BT non connected-idle!!\n"); | ||
1511 | |||
1512 | halbtc8192e2ant_switch_sstype(btcoexist, | ||
1513 | NORMAL_EXEC, 2); | ||
1514 | btc8192e2ant_coex_tbl_w_type(btcoexist, | ||
1515 | NORMAL_EXEC, 1); | ||
1516 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1517 | false, 0); | ||
1518 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, | ||
1519 | NORMAL_EXEC, 6); | ||
1520 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
1521 | |||
1522 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
1523 | false, false); | ||
1524 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
1525 | false, 0x18); | ||
1526 | |||
1527 | common = true; | ||
1528 | } else if (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == | ||
1529 | coex_dm->bt_status) { | ||
1530 | low_pwr_disable = true; | ||
1531 | btcoexist->btc_set(btcoexist, | ||
1532 | BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1533 | &low_pwr_disable); | ||
1534 | |||
1535 | if (bt_hson) | ||
1536 | return false; | ||
1537 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1538 | "Wifi connected + BT connected-idle!!\n"); | ||
1539 | |||
1540 | halbtc8192e2ant_switch_sstype(btcoexist, | ||
1541 | NORMAL_EXEC, 2); | ||
1542 | btc8192e2ant_coex_tbl_w_type(btcoexist, | ||
1543 | NORMAL_EXEC, 1); | ||
1544 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1545 | false, 0); | ||
1546 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, | ||
1547 | NORMAL_EXEC, 6); | ||
1548 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
1549 | |||
1550 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
1551 | false, false); | ||
1552 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
1553 | false, 0x18); | ||
1554 | |||
1555 | common = true; | ||
1556 | } else { | ||
1557 | low_pwr_disable = true; | ||
1558 | btcoexist->btc_set(btcoexist, | ||
1559 | BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1560 | &low_pwr_disable); | ||
1561 | |||
1562 | if (wifi_busy) { | ||
1563 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1564 | "Wifi Connected-Busy + BT Busy!!\n"); | ||
1565 | common = false; | ||
1566 | } else { | ||
1567 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1568 | "Wifi Connected-Idle + BT Busy!!\n"); | ||
1569 | |||
1570 | halbtc8192e2ant_switch_sstype(btcoexist, | ||
1571 | NORMAL_EXEC, 1); | ||
1572 | btc8192e2ant_coex_tbl_w_type(btcoexist, | ||
1573 | NORMAL_EXEC, 2); | ||
1574 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1575 | true, 21); | ||
1576 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, | ||
1577 | NORMAL_EXEC, 6); | ||
1578 | halbtc8192e2ant_dec_btpwr(btcoexist, | ||
1579 | NORMAL_EXEC, 0); | ||
1580 | btc8192e2ant_sw_mec1(btcoexist, false, | ||
1581 | false, false, false); | ||
1582 | btc8192e2ant_sw_mec2(btcoexist, false, | ||
1583 | false, false, 0x18); | ||
1584 | common = true; | ||
1585 | } | ||
1586 | } | ||
1587 | } | ||
1588 | return common; | ||
1589 | } | ||
1590 | |||
1591 | static void btc8192e_int1(struct btc_coexist *btcoexist, bool tx_pause, | ||
1592 | int result) | ||
1593 | { | ||
1594 | if (tx_pause) { | ||
1595 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1596 | ALGO_TRACE_FW_DETAIL, | ||
1597 | "[BTCoex], TxPause = 1\n"); | ||
1598 | |||
1599 | if (coex_dm->cur_ps_tdma == 71) { | ||
1600 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1601 | true, 5); | ||
1602 | coex_dm->tdma_adj_type = 5; | ||
1603 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1604 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1605 | true, 5); | ||
1606 | coex_dm->tdma_adj_type = 5; | ||
1607 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1608 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1609 | true, 6); | ||
1610 | coex_dm->tdma_adj_type = 6; | ||
1611 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1612 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1613 | true, 7); | ||
1614 | coex_dm->tdma_adj_type = 7; | ||
1615 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
1616 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1617 | true, 8); | ||
1618 | coex_dm->tdma_adj_type = 8; | ||
1619 | } | ||
1620 | if (coex_dm->cur_ps_tdma == 9) { | ||
1621 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1622 | true, 13); | ||
1623 | coex_dm->tdma_adj_type = 13; | ||
1624 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1625 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1626 | true, 14); | ||
1627 | coex_dm->tdma_adj_type = 14; | ||
1628 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1629 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1630 | true, 15); | ||
1631 | coex_dm->tdma_adj_type = 15; | ||
1632 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1633 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1634 | true, 16); | ||
1635 | coex_dm->tdma_adj_type = 16; | ||
1636 | } | ||
1637 | |||
1638 | if (result == -1) { | ||
1639 | if (coex_dm->cur_ps_tdma == 5) { | ||
1640 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1641 | true, 6); | ||
1642 | coex_dm->tdma_adj_type = 6; | ||
1643 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1644 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1645 | true, 7); | ||
1646 | coex_dm->tdma_adj_type = 7; | ||
1647 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1648 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1649 | true, 8); | ||
1650 | coex_dm->tdma_adj_type = 8; | ||
1651 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
1652 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1653 | true, 14); | ||
1654 | coex_dm->tdma_adj_type = 14; | ||
1655 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1656 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1657 | true, 15); | ||
1658 | coex_dm->tdma_adj_type = 15; | ||
1659 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1660 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1661 | true, 16); | ||
1662 | coex_dm->tdma_adj_type = 16; | ||
1663 | } | ||
1664 | } else if (result == 1) { | ||
1665 | if (coex_dm->cur_ps_tdma == 8) { | ||
1666 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1667 | true, 7); | ||
1668 | coex_dm->tdma_adj_type = 7; | ||
1669 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1670 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1671 | true, 6); | ||
1672 | coex_dm->tdma_adj_type = 6; | ||
1673 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1674 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1675 | true, 5); | ||
1676 | coex_dm->tdma_adj_type = 5; | ||
1677 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1678 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1679 | true, 15); | ||
1680 | coex_dm->tdma_adj_type = 15; | ||
1681 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1682 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1683 | true, 14); | ||
1684 | coex_dm->tdma_adj_type = 14; | ||
1685 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1686 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1687 | true, 13); | ||
1688 | coex_dm->tdma_adj_type = 13; | ||
1689 | } | ||
1690 | } | ||
1691 | } else { | ||
1692 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1693 | ALGO_TRACE_FW_DETAIL, | ||
1694 | "[BTCoex], TxPause = 0\n"); | ||
1695 | if (coex_dm->cur_ps_tdma == 5) { | ||
1696 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1697 | true, 71); | ||
1698 | coex_dm->tdma_adj_type = 71; | ||
1699 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1700 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1701 | true, 2); | ||
1702 | coex_dm->tdma_adj_type = 2; | ||
1703 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1704 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1705 | true, 3); | ||
1706 | coex_dm->tdma_adj_type = 3; | ||
1707 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
1708 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1709 | true, 4); | ||
1710 | coex_dm->tdma_adj_type = 4; | ||
1711 | } | ||
1712 | if (coex_dm->cur_ps_tdma == 13) { | ||
1713 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1714 | true, 9); | ||
1715 | coex_dm->tdma_adj_type = 9; | ||
1716 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1717 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1718 | true, 10); | ||
1719 | coex_dm->tdma_adj_type = 10; | ||
1720 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1721 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1722 | true, 11); | ||
1723 | coex_dm->tdma_adj_type = 11; | ||
1724 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1725 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1726 | true, 12); | ||
1727 | coex_dm->tdma_adj_type = 12; | ||
1728 | } | ||
1729 | |||
1730 | if (result == -1) { | ||
1731 | if (coex_dm->cur_ps_tdma == 71) { | ||
1732 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1733 | true, 1); | ||
1734 | coex_dm->tdma_adj_type = 1; | ||
1735 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1736 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1737 | true, 2); | ||
1738 | coex_dm->tdma_adj_type = 2; | ||
1739 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1740 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1741 | true, 3); | ||
1742 | coex_dm->tdma_adj_type = 3; | ||
1743 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1744 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1745 | true, 4); | ||
1746 | coex_dm->tdma_adj_type = 4; | ||
1747 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1748 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1749 | true, 10); | ||
1750 | coex_dm->tdma_adj_type = 10; | ||
1751 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1752 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1753 | true, 11); | ||
1754 | coex_dm->tdma_adj_type = 11; | ||
1755 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1756 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1757 | true, 12); | ||
1758 | coex_dm->tdma_adj_type = 12; | ||
1759 | } | ||
1760 | } else if (result == 1) { | ||
1761 | if (coex_dm->cur_ps_tdma == 4) { | ||
1762 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1763 | true, 3); | ||
1764 | coex_dm->tdma_adj_type = 3; | ||
1765 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1766 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1767 | true, 2); | ||
1768 | coex_dm->tdma_adj_type = 2; | ||
1769 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1770 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1771 | true, 1); | ||
1772 | coex_dm->tdma_adj_type = 1; | ||
1773 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1774 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1775 | true, 71); | ||
1776 | coex_dm->tdma_adj_type = 71; | ||
1777 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1778 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1779 | true, 11); | ||
1780 | coex_dm->tdma_adj_type = 11; | ||
1781 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1782 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1783 | true, 10); | ||
1784 | coex_dm->tdma_adj_type = 10; | ||
1785 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1786 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1787 | true, 9); | ||
1788 | coex_dm->tdma_adj_type = 9; | ||
1789 | } | ||
1790 | } | ||
1791 | } | ||
1792 | } | ||
1793 | |||
1794 | static void btc8192e_int2(struct btc_coexist *btcoexist, bool tx_pause, | ||
1795 | int result) | ||
1796 | { | ||
1797 | if (tx_pause) { | ||
1798 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1799 | ALGO_TRACE_FW_DETAIL, | ||
1800 | "[BTCoex], TxPause = 1\n"); | ||
1801 | if (coex_dm->cur_ps_tdma == 1) { | ||
1802 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1803 | true, 6); | ||
1804 | coex_dm->tdma_adj_type = 6; | ||
1805 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1806 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1807 | true, 6); | ||
1808 | coex_dm->tdma_adj_type = 6; | ||
1809 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1810 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1811 | true, 7); | ||
1812 | coex_dm->tdma_adj_type = 7; | ||
1813 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
1814 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1815 | true, 8); | ||
1816 | coex_dm->tdma_adj_type = 8; | ||
1817 | } | ||
1818 | if (coex_dm->cur_ps_tdma == 9) { | ||
1819 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1820 | true, 14); | ||
1821 | coex_dm->tdma_adj_type = 14; | ||
1822 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1823 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1824 | true, 14); | ||
1825 | coex_dm->tdma_adj_type = 14; | ||
1826 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1827 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1828 | true, 15); | ||
1829 | coex_dm->tdma_adj_type = 15; | ||
1830 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1831 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1832 | true, 16); | ||
1833 | coex_dm->tdma_adj_type = 16; | ||
1834 | } | ||
1835 | if (result == -1) { | ||
1836 | if (coex_dm->cur_ps_tdma == 5) { | ||
1837 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1838 | true, 6); | ||
1839 | coex_dm->tdma_adj_type = 6; | ||
1840 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1841 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1842 | true, 7); | ||
1843 | coex_dm->tdma_adj_type = 7; | ||
1844 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1845 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1846 | true, 8); | ||
1847 | coex_dm->tdma_adj_type = 8; | ||
1848 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
1849 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1850 | true, 14); | ||
1851 | coex_dm->tdma_adj_type = 14; | ||
1852 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1853 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1854 | true, 15); | ||
1855 | coex_dm->tdma_adj_type = 15; | ||
1856 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1857 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1858 | true, 16); | ||
1859 | coex_dm->tdma_adj_type = 16; | ||
1860 | } | ||
1861 | } else if (result == 1) { | ||
1862 | if (coex_dm->cur_ps_tdma == 8) { | ||
1863 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1864 | true, 7); | ||
1865 | coex_dm->tdma_adj_type = 7; | ||
1866 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1867 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1868 | true, 6); | ||
1869 | coex_dm->tdma_adj_type = 6; | ||
1870 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1871 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1872 | true, 6); | ||
1873 | coex_dm->tdma_adj_type = 6; | ||
1874 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1875 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1876 | true, 15); | ||
1877 | coex_dm->tdma_adj_type = 15; | ||
1878 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1879 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1880 | true, 14); | ||
1881 | coex_dm->tdma_adj_type = 14; | ||
1882 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1883 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1884 | true, 14); | ||
1885 | coex_dm->tdma_adj_type = 14; | ||
1886 | } | ||
1887 | } | ||
1888 | } else { | ||
1889 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1890 | ALGO_TRACE_FW_DETAIL, | ||
1891 | "[BTCoex], TxPause = 0\n"); | ||
1892 | if (coex_dm->cur_ps_tdma == 5) { | ||
1893 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1894 | true, 2); | ||
1895 | coex_dm->tdma_adj_type = 2; | ||
1896 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1897 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1898 | true, 2); | ||
1899 | coex_dm->tdma_adj_type = 2; | ||
1900 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1901 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1902 | true, 3); | ||
1903 | coex_dm->tdma_adj_type = 3; | ||
1904 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
1905 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1906 | true, 4); | ||
1907 | coex_dm->tdma_adj_type = 4; | ||
1908 | } | ||
1909 | if (coex_dm->cur_ps_tdma == 13) { | ||
1910 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1911 | true, 10); | ||
1912 | coex_dm->tdma_adj_type = 10; | ||
1913 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1914 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1915 | true, 10); | ||
1916 | coex_dm->tdma_adj_type = 10; | ||
1917 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1918 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1919 | true, 11); | ||
1920 | coex_dm->tdma_adj_type = 11; | ||
1921 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1922 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1923 | true, 12); | ||
1924 | coex_dm->tdma_adj_type = 12; | ||
1925 | } | ||
1926 | if (result == -1) { | ||
1927 | if (coex_dm->cur_ps_tdma == 1) { | ||
1928 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1929 | true, 2); | ||
1930 | coex_dm->tdma_adj_type = 2; | ||
1931 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1932 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1933 | true, 3); | ||
1934 | coex_dm->tdma_adj_type = 3; | ||
1935 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1936 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1937 | true, 4); | ||
1938 | coex_dm->tdma_adj_type = 4; | ||
1939 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1940 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1941 | true, 10); | ||
1942 | coex_dm->tdma_adj_type = 10; | ||
1943 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1944 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1945 | true, 11); | ||
1946 | coex_dm->tdma_adj_type = 11; | ||
1947 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1948 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1949 | true, 12); | ||
1950 | coex_dm->tdma_adj_type = 12; | ||
1951 | } | ||
1952 | } else if (result == 1) { | ||
1953 | if (coex_dm->cur_ps_tdma == 4) { | ||
1954 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1955 | true, 3); | ||
1956 | coex_dm->tdma_adj_type = 3; | ||
1957 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1958 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1959 | true, 2); | ||
1960 | coex_dm->tdma_adj_type = 2; | ||
1961 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1962 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1963 | true, 2); | ||
1964 | coex_dm->tdma_adj_type = 2; | ||
1965 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1966 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1967 | true, 11); | ||
1968 | coex_dm->tdma_adj_type = 11; | ||
1969 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1970 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1971 | true, 10); | ||
1972 | coex_dm->tdma_adj_type = 10; | ||
1973 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1974 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1975 | true, 10); | ||
1976 | coex_dm->tdma_adj_type = 10; | ||
1977 | } | ||
1978 | } | ||
1979 | } | ||
1980 | } | ||
1981 | |||
1982 | static void btc8192e_int3(struct btc_coexist *btcoexist, bool tx_pause, | ||
1983 | int result) | ||
1984 | { | ||
1985 | if (tx_pause) { | ||
1986 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1987 | ALGO_TRACE_FW_DETAIL, | ||
1988 | "[BTCoex], TxPause = 1\n"); | ||
1989 | if (coex_dm->cur_ps_tdma == 1) { | ||
1990 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1991 | true, 7); | ||
1992 | coex_dm->tdma_adj_type = 7; | ||
1993 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1994 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1995 | true, 7); | ||
1996 | coex_dm->tdma_adj_type = 7; | ||
1997 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1998 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1999 | true, 7); | ||
2000 | coex_dm->tdma_adj_type = 7; | ||
2001 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
2002 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2003 | true, 8); | ||
2004 | coex_dm->tdma_adj_type = 8; | ||
2005 | } | ||
2006 | if (coex_dm->cur_ps_tdma == 9) { | ||
2007 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2008 | true, 15); | ||
2009 | coex_dm->tdma_adj_type = 15; | ||
2010 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
2011 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2012 | true, 15); | ||
2013 | coex_dm->tdma_adj_type = 15; | ||
2014 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
2015 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2016 | true, 15); | ||
2017 | coex_dm->tdma_adj_type = 15; | ||
2018 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
2019 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2020 | true, 16); | ||
2021 | coex_dm->tdma_adj_type = 16; | ||
2022 | } | ||
2023 | if (result == -1) { | ||
2024 | if (coex_dm->cur_ps_tdma == 5) { | ||
2025 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2026 | true, 7); | ||
2027 | coex_dm->tdma_adj_type = 7; | ||
2028 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
2029 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2030 | true, 7); | ||
2031 | coex_dm->tdma_adj_type = 7; | ||
2032 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
2033 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2034 | true, 8); | ||
2035 | coex_dm->tdma_adj_type = 8; | ||
2036 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
2037 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2038 | true, 15); | ||
2039 | coex_dm->tdma_adj_type = 15; | ||
2040 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
2041 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2042 | true, 15); | ||
2043 | coex_dm->tdma_adj_type = 15; | ||
2044 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
2045 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2046 | true, 16); | ||
2047 | coex_dm->tdma_adj_type = 16; | ||
2048 | } | ||
2049 | } else if (result == 1) { | ||
2050 | if (coex_dm->cur_ps_tdma == 8) { | ||
2051 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2052 | true, 7); | ||
2053 | coex_dm->tdma_adj_type = 7; | ||
2054 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
2055 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2056 | true, 7); | ||
2057 | coex_dm->tdma_adj_type = 7; | ||
2058 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
2059 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2060 | true, 7); | ||
2061 | coex_dm->tdma_adj_type = 7; | ||
2062 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
2063 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2064 | true, 15); | ||
2065 | coex_dm->tdma_adj_type = 15; | ||
2066 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
2067 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2068 | true, 15); | ||
2069 | coex_dm->tdma_adj_type = 15; | ||
2070 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
2071 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2072 | true, 15); | ||
2073 | coex_dm->tdma_adj_type = 15; | ||
2074 | } | ||
2075 | } | ||
2076 | } else { | ||
2077 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2078 | ALGO_TRACE_FW_DETAIL, | ||
2079 | "[BTCoex], TxPause = 0\n"); | ||
2080 | if (coex_dm->cur_ps_tdma == 5) { | ||
2081 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2082 | true, 3); | ||
2083 | coex_dm->tdma_adj_type = 3; | ||
2084 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
2085 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2086 | true, 3); | ||
2087 | coex_dm->tdma_adj_type = 3; | ||
2088 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
2089 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2090 | true, 3); | ||
2091 | coex_dm->tdma_adj_type = 3; | ||
2092 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
2093 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2094 | true, 4); | ||
2095 | coex_dm->tdma_adj_type = 4; | ||
2096 | } | ||
2097 | if (coex_dm->cur_ps_tdma == 13) { | ||
2098 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2099 | true, 11); | ||
2100 | coex_dm->tdma_adj_type = 11; | ||
2101 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
2102 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2103 | true, 11); | ||
2104 | coex_dm->tdma_adj_type = 11; | ||
2105 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
2106 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2107 | true, 11); | ||
2108 | coex_dm->tdma_adj_type = 11; | ||
2109 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
2110 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2111 | true, 12); | ||
2112 | coex_dm->tdma_adj_type = 12; | ||
2113 | } | ||
2114 | if (result == -1) { | ||
2115 | if (coex_dm->cur_ps_tdma == 1) { | ||
2116 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2117 | true, 3); | ||
2118 | coex_dm->tdma_adj_type = 3; | ||
2119 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
2120 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2121 | true, 3); | ||
2122 | coex_dm->tdma_adj_type = 3; | ||
2123 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
2124 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2125 | true, 4); | ||
2126 | coex_dm->tdma_adj_type = 4; | ||
2127 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
2128 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2129 | true, 11); | ||
2130 | coex_dm->tdma_adj_type = 11; | ||
2131 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
2132 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2133 | true, 11); | ||
2134 | coex_dm->tdma_adj_type = 11; | ||
2135 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
2136 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2137 | true, 12); | ||
2138 | coex_dm->tdma_adj_type = 12; | ||
2139 | } | ||
2140 | } else if (result == 1) { | ||
2141 | if (coex_dm->cur_ps_tdma == 4) { | ||
2142 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2143 | true, 3); | ||
2144 | coex_dm->tdma_adj_type = 3; | ||
2145 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
2146 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2147 | true, 3); | ||
2148 | coex_dm->tdma_adj_type = 3; | ||
2149 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
2150 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2151 | true, 3); | ||
2152 | coex_dm->tdma_adj_type = 3; | ||
2153 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
2154 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2155 | true, 11); | ||
2156 | coex_dm->tdma_adj_type = 11; | ||
2157 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
2158 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2159 | true, 11); | ||
2160 | coex_dm->tdma_adj_type = 11; | ||
2161 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
2162 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2163 | true, 11); | ||
2164 | coex_dm->tdma_adj_type = 11; | ||
2165 | } | ||
2166 | } | ||
2167 | } | ||
2168 | } | ||
2169 | |||
2170 | static void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist, | ||
2171 | bool sco_hid, bool tx_pause, | ||
2172 | u8 max_interval) | ||
2173 | { | ||
2174 | static int up, dn, m, n, wait_cnt; | ||
2175 | /* 0: no change, +1: increase WiFi duration, | ||
2176 | * -1: decrease WiFi duration | ||
2177 | */ | ||
2178 | int result; | ||
2179 | u8 retry_cnt = 0; | ||
2180 | |||
2181 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
2182 | "[BTCoex], TdmaDurationAdjust()\n"); | ||
2183 | |||
2184 | if (!coex_dm->auto_tdma_adjust) { | ||
2185 | coex_dm->auto_tdma_adjust = true; | ||
2186 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2187 | "[BTCoex], first run TdmaDurationAdjust()!!\n"); | ||
2188 | if (sco_hid) { | ||
2189 | if (tx_pause) { | ||
2190 | if (max_interval == 1) { | ||
2191 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2192 | NORMAL_EXEC, | ||
2193 | true, 13); | ||
2194 | coex_dm->tdma_adj_type = 13; | ||
2195 | } else if (max_interval == 2) { | ||
2196 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2197 | NORMAL_EXEC, | ||
2198 | true, 14); | ||
2199 | coex_dm->tdma_adj_type = 14; | ||
2200 | } else if (max_interval == 3) { | ||
2201 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2202 | NORMAL_EXEC, | ||
2203 | true, 15); | ||
2204 | coex_dm->tdma_adj_type = 15; | ||
2205 | } else { | ||
2206 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2207 | NORMAL_EXEC, | ||
2208 | true, 15); | ||
2209 | coex_dm->tdma_adj_type = 15; | ||
2210 | } | ||
2211 | } else { | ||
2212 | if (max_interval == 1) { | ||
2213 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2214 | NORMAL_EXEC, | ||
2215 | true, 9); | ||
2216 | coex_dm->tdma_adj_type = 9; | ||
2217 | } else if (max_interval == 2) { | ||
2218 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2219 | NORMAL_EXEC, | ||
2220 | true, 10); | ||
2221 | coex_dm->tdma_adj_type = 10; | ||
2222 | } else if (max_interval == 3) { | ||
2223 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2224 | NORMAL_EXEC, | ||
2225 | true, 11); | ||
2226 | coex_dm->tdma_adj_type = 11; | ||
2227 | } else { | ||
2228 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2229 | NORMAL_EXEC, | ||
2230 | true, 11); | ||
2231 | coex_dm->tdma_adj_type = 11; | ||
2232 | } | ||
2233 | } | ||
2234 | } else { | ||
2235 | if (tx_pause) { | ||
2236 | if (max_interval == 1) { | ||
2237 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2238 | NORMAL_EXEC, | ||
2239 | true, 5); | ||
2240 | coex_dm->tdma_adj_type = 5; | ||
2241 | } else if (max_interval == 2) { | ||
2242 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2243 | NORMAL_EXEC, | ||
2244 | true, 6); | ||
2245 | coex_dm->tdma_adj_type = 6; | ||
2246 | } else if (max_interval == 3) { | ||
2247 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2248 | NORMAL_EXEC, | ||
2249 | true, 7); | ||
2250 | coex_dm->tdma_adj_type = 7; | ||
2251 | } else { | ||
2252 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2253 | NORMAL_EXEC, | ||
2254 | true, 7); | ||
2255 | coex_dm->tdma_adj_type = 7; | ||
2256 | } | ||
2257 | } else { | ||
2258 | if (max_interval == 1) { | ||
2259 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2260 | NORMAL_EXEC, | ||
2261 | true, 1); | ||
2262 | coex_dm->tdma_adj_type = 1; | ||
2263 | } else if (max_interval == 2) { | ||
2264 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2265 | NORMAL_EXEC, | ||
2266 | true, 2); | ||
2267 | coex_dm->tdma_adj_type = 2; | ||
2268 | } else if (max_interval == 3) { | ||
2269 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2270 | NORMAL_EXEC, | ||
2271 | true, 3); | ||
2272 | coex_dm->tdma_adj_type = 3; | ||
2273 | } else { | ||
2274 | halbtc8192e2ant_ps_tdma(btcoexist, | ||
2275 | NORMAL_EXEC, | ||
2276 | true, 3); | ||
2277 | coex_dm->tdma_adj_type = 3; | ||
2278 | } | ||
2279 | } | ||
2280 | } | ||
2281 | |||
2282 | up = 0; | ||
2283 | dn = 0; | ||
2284 | m = 1; | ||
2285 | n = 3; | ||
2286 | result = 0; | ||
2287 | wait_cnt = 0; | ||
2288 | } else { | ||
2289 | /* accquire the BT TRx retry count from BT_Info byte2 */ | ||
2290 | retry_cnt = coex_sta->bt_retry_cnt; | ||
2291 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2292 | "[BTCoex], retry_cnt = %d\n", retry_cnt); | ||
2293 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2294 | "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_cnt=%d\n", | ||
2295 | up, dn, m, n, wait_cnt); | ||
2296 | result = 0; | ||
2297 | wait_cnt++; | ||
2298 | /* no retry in the last 2-second duration */ | ||
2299 | if (retry_cnt == 0) { | ||
2300 | up++; | ||
2301 | dn--; | ||
2302 | |||
2303 | if (dn <= 0) | ||
2304 | dn = 0; | ||
2305 | |||
2306 | if (up >= n) { | ||
2307 | wait_cnt = 0; | ||
2308 | n = 3; | ||
2309 | up = 0; | ||
2310 | dn = 0; | ||
2311 | result = 1; | ||
2312 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2313 | ALGO_TRACE_FW_DETAIL, | ||
2314 | "[BTCoex]Increase wifi duration!!\n"); | ||
2315 | } | ||
2316 | } else if (retry_cnt <= 3) { | ||
2317 | up--; | ||
2318 | dn++; | ||
2319 | |||
2320 | if (up <= 0) | ||
2321 | up = 0; | ||
2322 | |||
2323 | if (dn == 2) { | ||
2324 | if (wait_cnt <= 2) | ||
2325 | m++; | ||
2326 | else | ||
2327 | m = 1; | ||
2328 | |||
2329 | if (m >= 20) | ||
2330 | m = 20; | ||
2331 | |||
2332 | n = 3 * m; | ||
2333 | up = 0; | ||
2334 | dn = 0; | ||
2335 | wait_cnt = 0; | ||
2336 | result = -1; | ||
2337 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2338 | ALGO_TRACE_FW_DETAIL, | ||
2339 | "Reduce wifi duration for retry<3\n"); | ||
2340 | } | ||
2341 | } else { | ||
2342 | if (wait_cnt == 1) | ||
2343 | m++; | ||
2344 | else | ||
2345 | m = 1; | ||
2346 | |||
2347 | if (m >= 20) | ||
2348 | m = 20; | ||
2349 | |||
2350 | n = 3*m; | ||
2351 | up = 0; | ||
2352 | dn = 0; | ||
2353 | wait_cnt = 0; | ||
2354 | result = -1; | ||
2355 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2356 | "Decrease wifi duration for retryCounter>3!!\n"); | ||
2357 | } | ||
2358 | |||
2359 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2360 | "[BTCoex], max Interval = %d\n", max_interval); | ||
2361 | if (max_interval == 1) | ||
2362 | btc8192e_int1(btcoexist, tx_pause, result); | ||
2363 | else if (max_interval == 2) | ||
2364 | btc8192e_int2(btcoexist, tx_pause, result); | ||
2365 | else if (max_interval == 3) | ||
2366 | btc8192e_int3(btcoexist, tx_pause, result); | ||
2367 | } | ||
2368 | |||
2369 | /* if current PsTdma not match with | ||
2370 | * the recorded one (when scan, dhcp...), | ||
2371 | * then we have to adjust it back to the previous record one. | ||
2372 | */ | ||
2373 | if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) { | ||
2374 | bool scan = false, link = false, roam = false; | ||
2375 | |||
2376 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2377 | "[BTCoex], PsTdma type dismatch!!!, "); | ||
2378 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2379 | "curPsTdma=%d, recordPsTdma=%d\n", | ||
2380 | coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type); | ||
2381 | |||
2382 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2383 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2384 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2385 | |||
2386 | if (!scan && !link && !roam) | ||
2387 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2388 | true, | ||
2389 | coex_dm->tdma_adj_type); | ||
2390 | else | ||
2391 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2392 | ALGO_TRACE_FW_DETAIL, | ||
2393 | "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"); | ||
2394 | } | ||
2395 | } | ||
2396 | |||
2397 | /* SCO only or SCO+PAN(HS) */ | ||
2398 | static void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist) | ||
2399 | { | ||
2400 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
2401 | u32 wifi_bw; | ||
2402 | |||
2403 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2404 | |||
2405 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2406 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2407 | |||
2408 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2409 | |||
2410 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 4); | ||
2411 | |||
2412 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2413 | |||
2414 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2415 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2416 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2417 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); | ||
2418 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2419 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2420 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2421 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); | ||
2422 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2423 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2424 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2425 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); | ||
2426 | } | ||
2427 | |||
2428 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2429 | |||
2430 | /* sw mechanism */ | ||
2431 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2432 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2433 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2434 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2435 | false, false); | ||
2436 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2437 | false, 0x6); | ||
2438 | } else { | ||
2439 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2440 | false, false); | ||
2441 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2442 | false, 0x6); | ||
2443 | } | ||
2444 | } else { | ||
2445 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2446 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2447 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2448 | false, false); | ||
2449 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2450 | false, 0x6); | ||
2451 | } else { | ||
2452 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2453 | false, false); | ||
2454 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2455 | false, 0x6); | ||
2456 | } | ||
2457 | } | ||
2458 | } | ||
2459 | |||
2460 | static void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist) | ||
2461 | { | ||
2462 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
2463 | u32 wifi_bw; | ||
2464 | |||
2465 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2466 | |||
2467 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2468 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2469 | |||
2470 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2471 | |||
2472 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 4); | ||
2473 | |||
2474 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2475 | |||
2476 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2477 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2478 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2479 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); | ||
2480 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2481 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2482 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2483 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); | ||
2484 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2485 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2486 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2487 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); | ||
2488 | } | ||
2489 | |||
2490 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2491 | |||
2492 | /* sw mechanism */ | ||
2493 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2494 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2495 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2496 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2497 | false, false); | ||
2498 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2499 | false, 0x6); | ||
2500 | } else { | ||
2501 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2502 | false, false); | ||
2503 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2504 | false, 0x6); | ||
2505 | } | ||
2506 | } else { | ||
2507 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2508 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2509 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2510 | false, false); | ||
2511 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2512 | false, 0x6); | ||
2513 | } else { | ||
2514 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2515 | false, false); | ||
2516 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2517 | false, 0x6); | ||
2518 | } | ||
2519 | } | ||
2520 | } | ||
2521 | |||
2522 | static void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist) | ||
2523 | { | ||
2524 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2525 | u32 wifi_bw; | ||
2526 | |||
2527 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2528 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2529 | |||
2530 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2531 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2532 | |||
2533 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2534 | |||
2535 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2536 | |||
2537 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3); | ||
2538 | |||
2539 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2540 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2541 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2542 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); | ||
2543 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2544 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2545 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2546 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); | ||
2547 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2548 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2549 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2550 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); | ||
2551 | } | ||
2552 | |||
2553 | /* sw mechanism */ | ||
2554 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2555 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2556 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2557 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2558 | false, false); | ||
2559 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2560 | false, 0x18); | ||
2561 | } else { | ||
2562 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2563 | false, false); | ||
2564 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2565 | false, 0x18); | ||
2566 | } | ||
2567 | } else { | ||
2568 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2569 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2570 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2571 | false, false); | ||
2572 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2573 | false, 0x18); | ||
2574 | } else { | ||
2575 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2576 | false, false); | ||
2577 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2578 | false, 0x18); | ||
2579 | } | ||
2580 | } | ||
2581 | } | ||
2582 | |||
2583 | /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ | ||
2584 | static void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist) | ||
2585 | { | ||
2586 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2587 | u32 wifi_bw; | ||
2588 | bool long_dist = false; | ||
2589 | |||
2590 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2591 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2592 | |||
2593 | if ((btrssi_state == BTC_RSSI_STATE_LOW || | ||
2594 | btrssi_state == BTC_RSSI_STATE_STAY_LOW) && | ||
2595 | (wifirssi_state == BTC_RSSI_STATE_LOW || | ||
2596 | wifirssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2597 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2598 | "[BTCoex], A2dp, wifi/bt rssi both LOW!!\n"); | ||
2599 | long_dist = true; | ||
2600 | } | ||
2601 | if (long_dist) { | ||
2602 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 2); | ||
2603 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true, | ||
2604 | 0x4); | ||
2605 | } else { | ||
2606 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2607 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, | ||
2608 | 0x8); | ||
2609 | } | ||
2610 | |||
2611 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2612 | |||
2613 | if (long_dist) | ||
2614 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 0); | ||
2615 | else | ||
2616 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
2617 | |||
2618 | if (long_dist) { | ||
2619 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 17); | ||
2620 | coex_dm->auto_tdma_adjust = false; | ||
2621 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2622 | } else { | ||
2623 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2624 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2625 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2626 | true, 1); | ||
2627 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2628 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2629 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2630 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2631 | false, 1); | ||
2632 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2633 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2634 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2635 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2636 | false, 1); | ||
2637 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2638 | } | ||
2639 | } | ||
2640 | |||
2641 | /* sw mechanism */ | ||
2642 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2643 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2644 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2645 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2646 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2647 | false, false); | ||
2648 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2649 | false, 0x18); | ||
2650 | } else { | ||
2651 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2652 | false, false); | ||
2653 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2654 | false, 0x18); | ||
2655 | } | ||
2656 | } else { | ||
2657 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2658 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2659 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2660 | false, false); | ||
2661 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2662 | false, 0x18); | ||
2663 | } else { | ||
2664 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2665 | false, false); | ||
2666 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2667 | false, 0x18); | ||
2668 | } | ||
2669 | } | ||
2670 | } | ||
2671 | |||
2672 | static void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) | ||
2673 | { | ||
2674 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2675 | u32 wifi_bw; | ||
2676 | |||
2677 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2678 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2679 | |||
2680 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2681 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2682 | |||
2683 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2684 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
2685 | |||
2686 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2687 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2688 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 2); | ||
2689 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2690 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2691 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2692 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2693 | false, 2); | ||
2694 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2695 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2696 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2697 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2698 | false, 2); | ||
2699 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2700 | } | ||
2701 | |||
2702 | /* sw mechanism */ | ||
2703 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2704 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2705 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2706 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2707 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2708 | false, false); | ||
2709 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2710 | true, 0x6); | ||
2711 | } else { | ||
2712 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2713 | false, false); | ||
2714 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2715 | true, 0x6); | ||
2716 | } | ||
2717 | } else { | ||
2718 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2719 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2720 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2721 | false, false); | ||
2722 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2723 | true, 0x6); | ||
2724 | } else { | ||
2725 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2726 | false, false); | ||
2727 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2728 | true, 0x6); | ||
2729 | } | ||
2730 | } | ||
2731 | } | ||
2732 | |||
2733 | static void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist) | ||
2734 | { | ||
2735 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2736 | u32 wifi_bw; | ||
2737 | |||
2738 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2739 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2740 | |||
2741 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2742 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2743 | |||
2744 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2745 | |||
2746 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
2747 | |||
2748 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2749 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2750 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2751 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
2752 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2753 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2754 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2755 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); | ||
2756 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2757 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2758 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2759 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1); | ||
2760 | } | ||
2761 | |||
2762 | /* sw mechanism */ | ||
2763 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2764 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2765 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2766 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2767 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2768 | false, false); | ||
2769 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2770 | false, 0x18); | ||
2771 | } else { | ||
2772 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2773 | false, false); | ||
2774 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2775 | false, 0x18); | ||
2776 | } | ||
2777 | } else { | ||
2778 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2779 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2780 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2781 | false, false); | ||
2782 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2783 | false, 0x18); | ||
2784 | } else { | ||
2785 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2786 | false, false); | ||
2787 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2788 | false, 0x18); | ||
2789 | } | ||
2790 | } | ||
2791 | } | ||
2792 | |||
2793 | /* PAN(HS) only */ | ||
2794 | static void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist) | ||
2795 | { | ||
2796 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2797 | u32 wifi_bw; | ||
2798 | |||
2799 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2800 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2801 | |||
2802 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2803 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2804 | |||
2805 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2806 | |||
2807 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
2808 | |||
2809 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2810 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2811 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2812 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2813 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2814 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2815 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2816 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2817 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2818 | } | ||
2819 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
2820 | |||
2821 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2822 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2823 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2824 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2825 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2826 | false, false); | ||
2827 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2828 | false, 0x18); | ||
2829 | } else { | ||
2830 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2831 | false, false); | ||
2832 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2833 | false, 0x18); | ||
2834 | } | ||
2835 | } else { | ||
2836 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2837 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2838 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2839 | false, false); | ||
2840 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2841 | false, 0x18); | ||
2842 | } else { | ||
2843 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2844 | false, false); | ||
2845 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2846 | false, 0x18); | ||
2847 | } | ||
2848 | } | ||
2849 | } | ||
2850 | |||
2851 | /* PAN(EDR)+A2DP */ | ||
2852 | static void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) | ||
2853 | { | ||
2854 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2855 | u32 wifi_bw; | ||
2856 | |||
2857 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2858 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2859 | |||
2860 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2861 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2862 | |||
2863 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2864 | |||
2865 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2); | ||
2866 | |||
2867 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2868 | |||
2869 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2870 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2871 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2872 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 3); | ||
2873 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2874 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2875 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2876 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2877 | false, 3); | ||
2878 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2879 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2880 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2881 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, | ||
2882 | false, 3); | ||
2883 | } | ||
2884 | |||
2885 | /* sw mechanism */ | ||
2886 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2887 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2888 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2889 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2890 | false, false); | ||
2891 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2892 | false, 0x18); | ||
2893 | } else { | ||
2894 | btc8192e2ant_sw_mec1(btcoexist, true, false, | ||
2895 | false, false); | ||
2896 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2897 | false, 0x18); | ||
2898 | } | ||
2899 | } else { | ||
2900 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2901 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2902 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2903 | false, false); | ||
2904 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2905 | false, 0x18); | ||
2906 | } else { | ||
2907 | btc8192e2ant_sw_mec1(btcoexist, false, false, | ||
2908 | false, false); | ||
2909 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2910 | false, 0x18); | ||
2911 | } | ||
2912 | } | ||
2913 | } | ||
2914 | |||
2915 | static void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) | ||
2916 | { | ||
2917 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2918 | u32 wifi_bw; | ||
2919 | |||
2920 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2921 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2922 | |||
2923 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2924 | |||
2925 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2926 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2927 | |||
2928 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2929 | |||
2930 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3); | ||
2931 | |||
2932 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2933 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2934 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2935 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); | ||
2936 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
2937 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
2938 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
2939 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2940 | true, 10); | ||
2941 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
2942 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2943 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
2944 | halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2945 | true, 10); | ||
2946 | } | ||
2947 | |||
2948 | /* sw mechanism */ | ||
2949 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2950 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2951 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2952 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2953 | false, false); | ||
2954 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2955 | false, 0x18); | ||
2956 | } else { | ||
2957 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
2958 | false, false); | ||
2959 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2960 | false, 0x18); | ||
2961 | } | ||
2962 | } else { | ||
2963 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
2964 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2965 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2966 | false, false); | ||
2967 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
2968 | false, 0x18); | ||
2969 | } else { | ||
2970 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
2971 | false, false); | ||
2972 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
2973 | false, 0x18); | ||
2974 | } | ||
2975 | } | ||
2976 | } | ||
2977 | |||
2978 | /* HID+A2DP+PAN(EDR) */ | ||
2979 | static void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) | ||
2980 | { | ||
2981 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
2982 | u32 wifi_bw; | ||
2983 | |||
2984 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
2985 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
2986 | |||
2987 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
2988 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
2989 | |||
2990 | halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6); | ||
2991 | |||
2992 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2993 | |||
2994 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3); | ||
2995 | |||
2996 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
2997 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
2998 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
2999 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 3); | ||
3000 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
3001 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
3002 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
3003 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3); | ||
3004 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
3005 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3006 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
3007 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3); | ||
3008 | } | ||
3009 | |||
3010 | /* sw mechanism */ | ||
3011 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
3012 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
3013 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3014 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
3015 | false, false); | ||
3016 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
3017 | false, 0x18); | ||
3018 | } else { | ||
3019 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
3020 | false, false); | ||
3021 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
3022 | false, 0x18); | ||
3023 | } | ||
3024 | } else { | ||
3025 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
3026 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3027 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
3028 | false, false); | ||
3029 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
3030 | false, 0x18); | ||
3031 | } else { | ||
3032 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
3033 | false, false); | ||
3034 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
3035 | false, 0x18); | ||
3036 | } | ||
3037 | } | ||
3038 | } | ||
3039 | |||
3040 | static void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist) | ||
3041 | { | ||
3042 | u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH; | ||
3043 | u32 wifi_bw; | ||
3044 | |||
3045 | wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0); | ||
3046 | btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42); | ||
3047 | |||
3048 | halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1); | ||
3049 | halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8); | ||
3050 | |||
3051 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3052 | |||
3053 | btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3); | ||
3054 | |||
3055 | if ((btrssi_state == BTC_RSSI_STATE_LOW) || | ||
3056 | (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
3057 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0); | ||
3058 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 2); | ||
3059 | } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) || | ||
3060 | (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
3061 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2); | ||
3062 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2); | ||
3063 | } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) || | ||
3064 | (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3065 | halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4); | ||
3066 | halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2); | ||
3067 | } | ||
3068 | |||
3069 | /* sw mechanism */ | ||
3070 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
3071 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
3072 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3073 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
3074 | false, false); | ||
3075 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
3076 | false, 0x18); | ||
3077 | } else { | ||
3078 | btc8192e2ant_sw_mec1(btcoexist, true, true, | ||
3079 | false, false); | ||
3080 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
3081 | false, 0x18); | ||
3082 | } | ||
3083 | } else { | ||
3084 | if ((wifirssi_state == BTC_RSSI_STATE_HIGH) || | ||
3085 | (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3086 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
3087 | false, false); | ||
3088 | btc8192e2ant_sw_mec2(btcoexist, true, false, | ||
3089 | false, 0x18); | ||
3090 | } else { | ||
3091 | btc8192e2ant_sw_mec1(btcoexist, false, true, | ||
3092 | false, false); | ||
3093 | btc8192e2ant_sw_mec2(btcoexist, false, false, | ||
3094 | false, 0x18); | ||
3095 | } | ||
3096 | } | ||
3097 | } | ||
3098 | |||
3099 | static void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | ||
3100 | { | ||
3101 | u8 algorithm = 0; | ||
3102 | |||
3103 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3104 | "[BTCoex], RunCoexistMechanism()===>\n"); | ||
3105 | |||
3106 | if (btcoexist->manual_control) { | ||
3107 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3108 | "[BTCoex], return for Manual CTRL <===\n"); | ||
3109 | return; | ||
3110 | } | ||
3111 | |||
3112 | if (coex_sta->under_ips) { | ||
3113 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3114 | "[BTCoex], wifi is under IPS !!!\n"); | ||
3115 | return; | ||
3116 | } | ||
3117 | |||
3118 | algorithm = halbtc8192e2ant_action_algorithm(btcoexist); | ||
3119 | if (coex_sta->c2h_bt_inquiry_page && | ||
3120 | (BT_8192E_2ANT_COEX_ALGO_PANHS != algorithm)) { | ||
3121 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3122 | "[BTCoex], BT is under inquiry/page scan !!\n"); | ||
3123 | halbtc8192e2ant_action_bt_inquiry(btcoexist); | ||
3124 | return; | ||
3125 | } | ||
3126 | |||
3127 | coex_dm->cur_algorithm = algorithm; | ||
3128 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3129 | "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm); | ||
3130 | |||
3131 | if (halbtc8192e2ant_is_common_action(btcoexist)) { | ||
3132 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3133 | "[BTCoex], Action 2-Ant common.\n"); | ||
3134 | coex_dm->auto_tdma_adjust = false; | ||
3135 | } else { | ||
3136 | if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { | ||
3137 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3138 | "[BTCoex] preAlgorithm=%d, curAlgorithm=%d\n", | ||
3139 | coex_dm->pre_algorithm, | ||
3140 | coex_dm->cur_algorithm); | ||
3141 | coex_dm->auto_tdma_adjust = false; | ||
3142 | } | ||
3143 | switch (coex_dm->cur_algorithm) { | ||
3144 | case BT_8192E_2ANT_COEX_ALGO_SCO: | ||
3145 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3146 | "Action 2-Ant, algorithm = SCO.\n"); | ||
3147 | halbtc8192e2ant_action_sco(btcoexist); | ||
3148 | break; | ||
3149 | case BT_8192E_2ANT_COEX_ALGO_SCO_PAN: | ||
3150 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3151 | "Action 2-Ant, algorithm = SCO+PAN(EDR).\n"); | ||
3152 | halbtc8192e2ant_action_sco_pan(btcoexist); | ||
3153 | break; | ||
3154 | case BT_8192E_2ANT_COEX_ALGO_HID: | ||
3155 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3156 | "Action 2-Ant, algorithm = HID.\n"); | ||
3157 | halbtc8192e2ant_action_hid(btcoexist); | ||
3158 | break; | ||
3159 | case BT_8192E_2ANT_COEX_ALGO_A2DP: | ||
3160 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3161 | "Action 2-Ant, algorithm = A2DP.\n"); | ||
3162 | halbtc8192e2ant_action_a2dp(btcoexist); | ||
3163 | break; | ||
3164 | case BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS: | ||
3165 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3166 | "Action 2-Ant, algorithm = A2DP+PAN(HS).\n"); | ||
3167 | halbtc8192e2ant_action_a2dp_pan_hs(btcoexist); | ||
3168 | break; | ||
3169 | case BT_8192E_2ANT_COEX_ALGO_PANEDR: | ||
3170 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3171 | "Action 2-Ant, algorithm = PAN(EDR).\n"); | ||
3172 | halbtc8192e2ant_action_pan_edr(btcoexist); | ||
3173 | break; | ||
3174 | case BT_8192E_2ANT_COEX_ALGO_PANHS: | ||
3175 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3176 | "Action 2-Ant, algorithm = HS mode.\n"); | ||
3177 | halbtc8192e2ant_action_pan_hs(btcoexist); | ||
3178 | break; | ||
3179 | case BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP: | ||
3180 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3181 | "Action 2-Ant, algorithm = PAN+A2DP.\n"); | ||
3182 | halbtc8192e2ant_action_pan_edr_a2dp(btcoexist); | ||
3183 | break; | ||
3184 | case BT_8192E_2ANT_COEX_ALGO_PANEDR_HID: | ||
3185 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3186 | "Action 2-Ant, algorithm = PAN(EDR)+HID.\n"); | ||
3187 | halbtc8192e2ant_action_pan_edr_hid(btcoexist); | ||
3188 | break; | ||
3189 | case BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
3190 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3191 | "Action 2-Ant, algorithm = HID+A2DP+PAN.\n"); | ||
3192 | btc8192e2ant_action_hid_a2dp_pan_edr(btcoexist); | ||
3193 | break; | ||
3194 | case BT_8192E_2ANT_COEX_ALGO_HID_A2DP: | ||
3195 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3196 | "Action 2-Ant, algorithm = HID+A2DP.\n"); | ||
3197 | halbtc8192e2ant_action_hid_a2dp(btcoexist); | ||
3198 | break; | ||
3199 | default: | ||
3200 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3201 | "Action 2-Ant, algorithm = unknown!!\n"); | ||
3202 | /* halbtc8192e2ant_coex_alloff(btcoexist); */ | ||
3203 | break; | ||
3204 | } | ||
3205 | coex_dm->pre_algorithm = coex_dm->cur_algorithm; | ||
3206 | } | ||
3207 | } | ||
3208 | |||
3209 | static void halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist, | ||
3210 | bool backup) | ||
3211 | { | ||
3212 | u16 u16tmp = 0; | ||
3213 | u8 u8tmp = 0; | ||
3214 | |||
3215 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3216 | "[BTCoex], 2Ant Init HW Config!!\n"); | ||
3217 | |||
3218 | if (backup) { | ||
3219 | /* backup rf 0x1e value */ | ||
3220 | coex_dm->bt_rf0x1e_backup = | ||
3221 | btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, | ||
3222 | 0x1e, 0xfffff); | ||
3223 | |||
3224 | coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist, | ||
3225 | 0x430); | ||
3226 | coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist, | ||
3227 | 0x434); | ||
3228 | coex_dm->backup_retrylimit = btcoexist->btc_read_2byte( | ||
3229 | btcoexist, | ||
3230 | 0x42a); | ||
3231 | coex_dm->backup_ampdu_maxtime = btcoexist->btc_read_1byte( | ||
3232 | btcoexist, | ||
3233 | 0x456); | ||
3234 | } | ||
3235 | |||
3236 | /* antenna sw ctrl to bt */ | ||
3237 | btcoexist->btc_write_1byte(btcoexist, 0x4f, 0x6); | ||
3238 | btcoexist->btc_write_1byte(btcoexist, 0x944, 0x24); | ||
3239 | btcoexist->btc_write_4byte(btcoexist, 0x930, 0x700700); | ||
3240 | btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20); | ||
3241 | if (btcoexist->chip_interface == BTC_INTF_USB) | ||
3242 | btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30430004); | ||
3243 | else | ||
3244 | btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30030004); | ||
3245 | |||
3246 | btc8192e2ant_coex_tbl_w_type(btcoexist, FORCE_EXEC, 0); | ||
3247 | |||
3248 | /* antenna switch control parameter */ | ||
3249 | btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555); | ||
3250 | |||
3251 | /* coex parameters */ | ||
3252 | btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); | ||
3253 | /* 0x790[5:0] = 0x5 */ | ||
3254 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); | ||
3255 | u8tmp &= 0xc0; | ||
3256 | u8tmp |= 0x5; | ||
3257 | btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); | ||
3258 | |||
3259 | /* enable counter statistics */ | ||
3260 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); | ||
3261 | |||
3262 | /* enable PTA */ | ||
3263 | btcoexist->btc_write_1byte(btcoexist, 0x40, 0x20); | ||
3264 | /* enable mailbox interface */ | ||
3265 | u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x40); | ||
3266 | u16tmp |= BIT9; | ||
3267 | btcoexist->btc_write_2byte(btcoexist, 0x40, u16tmp); | ||
3268 | |||
3269 | /* enable PTA I2C mailbox */ | ||
3270 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x101); | ||
3271 | u8tmp |= BIT4; | ||
3272 | btcoexist->btc_write_1byte(btcoexist, 0x101, u8tmp); | ||
3273 | |||
3274 | /* enable bt clock when wifi is disabled. */ | ||
3275 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x93); | ||
3276 | u8tmp |= BIT0; | ||
3277 | btcoexist->btc_write_1byte(btcoexist, 0x93, u8tmp); | ||
3278 | /* enable bt clock when suspend. */ | ||
3279 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x7); | ||
3280 | u8tmp |= BIT0; | ||
3281 | btcoexist->btc_write_1byte(btcoexist, 0x7, u8tmp); | ||
3282 | } | ||
3283 | |||
3284 | /************************************************************* | ||
3285 | * work around function start with wa_halbtc8192e2ant_ | ||
3286 | *************************************************************/ | ||
3287 | |||
3288 | /************************************************************ | ||
3289 | * extern function start with EXhalbtc8192e2ant_ | ||
3290 | ************************************************************/ | ||
3291 | |||
3292 | void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist) | ||
3293 | { | ||
3294 | halbtc8192e2ant_init_hwconfig(btcoexist, true); | ||
3295 | } | ||
3296 | |||
3297 | void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
3298 | { | ||
3299 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3300 | "[BTCoex], Coex Mechanism Init!!\n"); | ||
3301 | halbtc8192e2ant_init_coex_dm(btcoexist); | ||
3302 | } | ||
3303 | |||
3304 | void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist) | ||
3305 | { | ||
3306 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
3307 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
3308 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
3309 | u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; | ||
3310 | u16 u16tmp[4]; | ||
3311 | u32 u32tmp[4]; | ||
3312 | bool roam = false, scan = false, link = false, wifi_under_5g = false; | ||
3313 | bool bt_hson = false, wifi_busy = false; | ||
3314 | int wifirssi = 0, bt_hs_rssi = 0; | ||
3315 | u32 wifi_bw, wifi_traffic_dir; | ||
3316 | u8 wifi_dot11_chnl, wifi_hs_chnl; | ||
3317 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
3318 | |||
3319 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3320 | "\r\n ============[BT Coexist info]============"); | ||
3321 | |||
3322 | if (btcoexist->manual_control) { | ||
3323 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3324 | "\r\n ===========[Under Manual Control]==========="); | ||
3325 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3326 | "\r\n =========================================="); | ||
3327 | } | ||
3328 | |||
3329 | if (!board_info->bt_exist) { | ||
3330 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!"); | ||
3331 | return; | ||
3332 | } | ||
3333 | |||
3334 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3335 | "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", | ||
3336 | board_info->pg_ant_num, board_info->btdm_ant_num); | ||
3337 | |||
3338 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d", | ||
3339 | "BT stack/ hci ext ver", | ||
3340 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
3341 | stack_info->hci_version); | ||
3342 | |||
3343 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); | ||
3344 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
3345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3346 | "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", | ||
3347 | "CoexVer/ FwVer/ PatchVer", | ||
3348 | glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant, | ||
3349 | fw_ver, bt_patch_ver, bt_patch_ver); | ||
3350 | |||
3351 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson); | ||
3352 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, | ||
3353 | &wifi_dot11_chnl); | ||
3354 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); | ||
3355 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)", | ||
3356 | "Dot11 channel / HsMode(HsChnl)", | ||
3357 | wifi_dot11_chnl, bt_hson, wifi_hs_chnl); | ||
3358 | |||
3359 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ", | ||
3360 | "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], | ||
3361 | coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); | ||
3362 | |||
3363 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi); | ||
3364 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); | ||
3365 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
3366 | "Wifi rssi/ HS rssi", wifirssi, bt_hs_rssi); | ||
3367 | |||
3368 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
3369 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
3370 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
3371 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ", | ||
3372 | "Wifi link/ roam/ scan", link, roam, scan); | ||
3373 | |||
3374 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
3375 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3376 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
3377 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, | ||
3378 | &wifi_traffic_dir); | ||
3379 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ", | ||
3380 | "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), | ||
3381 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : | ||
3382 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), | ||
3383 | ((!wifi_busy) ? "idle" : | ||
3384 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? | ||
3385 | "uplink" : "downlink"))); | ||
3386 | |||
3387 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ", | ||
3388 | "BT [status/ rssi/ retryCnt]", | ||
3389 | ((btcoexist->bt_info.bt_disabled) ? ("disabled") : | ||
3390 | ((coex_sta->c2h_bt_inquiry_page) ? | ||
3391 | ("inquiry/page scan") : | ||
3392 | ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
3393 | coex_dm->bt_status) ? "non-connected idle" : | ||
3394 | ((BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE == | ||
3395 | coex_dm->bt_status) ? "connected-idle" : "busy")))), | ||
3396 | coex_sta->bt_rssi, coex_sta->bt_retry_cnt); | ||
3397 | |||
3398 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d", | ||
3399 | "SCO/HID/PAN/A2DP", stack_info->sco_exist, | ||
3400 | stack_info->hid_exist, stack_info->pan_exist, | ||
3401 | stack_info->a2dp_exist); | ||
3402 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); | ||
3403 | |||
3404 | bt_info_ext = coex_sta->bt_info_ext; | ||
3405 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s", | ||
3406 | "BT Info A2DP rate", | ||
3407 | (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); | ||
3408 | |||
3409 | for (i = 0; i < BT_INFO_SRC_8192E_2ANT_MAX; i++) { | ||
3410 | if (coex_sta->bt_info_c2h_cnt[i]) { | ||
3411 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3412 | "\r\n %-35s = %02x %02x %02x %02x ", | ||
3413 | GLBtInfoSrc8192e2Ant[i], | ||
3414 | coex_sta->bt_info_c2h[i][0], | ||
3415 | coex_sta->bt_info_c2h[i][1], | ||
3416 | coex_sta->bt_info_c2h[i][2], | ||
3417 | coex_sta->bt_info_c2h[i][3]); | ||
3418 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3419 | "%02x %02x %02x(%d)", | ||
3420 | coex_sta->bt_info_c2h[i][4], | ||
3421 | coex_sta->bt_info_c2h[i][5], | ||
3422 | coex_sta->bt_info_c2h[i][6], | ||
3423 | coex_sta->bt_info_c2h_cnt[i]); | ||
3424 | } | ||
3425 | } | ||
3426 | |||
3427 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s", | ||
3428 | "PS state, IPS/LPS", | ||
3429 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), | ||
3430 | ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); | ||
3431 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); | ||
3432 | |||
3433 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "SS Type", | ||
3434 | coex_dm->cur_sstype); | ||
3435 | |||
3436 | /* Sw mechanism */ | ||
3437 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
3438 | "============[Sw mechanism]============"); | ||
3439 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ", | ||
3440 | "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, | ||
3441 | coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); | ||
3442 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ", | ||
3443 | "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", | ||
3444 | coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, | ||
3445 | coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); | ||
3446 | |||
3447 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "Rate Mask", | ||
3448 | btcoexist->bt_info.ra_mask); | ||
3449 | |||
3450 | /* Fw mechanism */ | ||
3451 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
3452 | "============[Fw mechanism]============"); | ||
3453 | |||
3454 | ps_tdma_case = coex_dm->cur_ps_tdma; | ||
3455 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3456 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", | ||
3457 | "PS TDMA", coex_dm->ps_tdma_para[0], | ||
3458 | coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], | ||
3459 | coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], | ||
3460 | ps_tdma_case, coex_dm->auto_tdma_adjust); | ||
3461 | |||
3462 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ", | ||
3463 | "DecBtPwr/ IgnWlanAct", | ||
3464 | coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act); | ||
3465 | |||
3466 | /* Hw setting */ | ||
3467 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
3468 | "============[Hw setting]============"); | ||
3469 | |||
3470 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", | ||
3471 | "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); | ||
3472 | |||
3473 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
3474 | "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, | ||
3475 | coex_dm->backup_arfr_cnt2, coex_dm->backup_retrylimit, | ||
3476 | coex_dm->backup_ampdu_maxtime); | ||
3477 | |||
3478 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); | ||
3479 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); | ||
3480 | u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); | ||
3481 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); | ||
3482 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
3483 | "0x430/0x434/0x42a/0x456", | ||
3484 | u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); | ||
3485 | |||
3486 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc04); | ||
3487 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xd04); | ||
3488 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x90c); | ||
3489 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
3490 | "0xc04/ 0xd04/ 0x90c", u32tmp[0], u32tmp[1], u32tmp[2]); | ||
3491 | |||
3492 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); | ||
3493 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0x778", | ||
3494 | u8tmp[0]); | ||
3495 | |||
3496 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c); | ||
3497 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930); | ||
3498 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3499 | "0x92c/ 0x930", (u8tmp[0]), u32tmp[0]); | ||
3500 | |||
3501 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); | ||
3502 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f); | ||
3503 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3504 | "0x40/ 0x4f", u8tmp[0], u8tmp[1]); | ||
3505 | |||
3506 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); | ||
3507 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); | ||
3508 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3509 | "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); | ||
3510 | |||
3511 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); | ||
3512 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0xc50(dig)", | ||
3513 | u32tmp[0]); | ||
3514 | |||
3515 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); | ||
3516 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); | ||
3517 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); | ||
3518 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); | ||
3519 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3520 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", | ||
3521 | "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", | ||
3522 | u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); | ||
3523 | |||
3524 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
3525 | "0x770(hp rx[31:16]/tx[15:0])", | ||
3526 | coex_sta->high_priority_rx, coex_sta->high_priority_tx); | ||
3527 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
3528 | "0x774(lp rx[31:16]/tx[15:0])", | ||
3529 | coex_sta->low_priority_rx, coex_sta->low_priority_tx); | ||
3530 | #if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 1) | ||
3531 | halbtc8192e2ant_monitor_bt_ctr(btcoexist); | ||
3532 | #endif | ||
3533 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS); | ||
3534 | } | ||
3535 | |||
3536 | void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | ||
3537 | { | ||
3538 | if (BTC_IPS_ENTER == type) { | ||
3539 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3540 | "[BTCoex], IPS ENTER notify\n"); | ||
3541 | coex_sta->under_ips = true; | ||
3542 | halbtc8192e2ant_coex_alloff(btcoexist); | ||
3543 | } else if (BTC_IPS_LEAVE == type) { | ||
3544 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3545 | "[BTCoex], IPS LEAVE notify\n"); | ||
3546 | coex_sta->under_ips = false; | ||
3547 | } | ||
3548 | } | ||
3549 | |||
3550 | void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | ||
3551 | { | ||
3552 | if (BTC_LPS_ENABLE == type) { | ||
3553 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3554 | "[BTCoex], LPS ENABLE notify\n"); | ||
3555 | coex_sta->under_lps = true; | ||
3556 | } else if (BTC_LPS_DISABLE == type) { | ||
3557 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3558 | "[BTCoex], LPS DISABLE notify\n"); | ||
3559 | coex_sta->under_lps = false; | ||
3560 | } | ||
3561 | } | ||
3562 | |||
3563 | void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | ||
3564 | { | ||
3565 | if (BTC_SCAN_START == type) | ||
3566 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3567 | "[BTCoex], SCAN START notify\n"); | ||
3568 | else if (BTC_SCAN_FINISH == type) | ||
3569 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3570 | "[BTCoex], SCAN FINISH notify\n"); | ||
3571 | } | ||
3572 | |||
3573 | void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | ||
3574 | { | ||
3575 | if (BTC_ASSOCIATE_START == type) | ||
3576 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3577 | "[BTCoex], CONNECT START notify\n"); | ||
3578 | else if (BTC_ASSOCIATE_FINISH == type) | ||
3579 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3580 | "[BTCoex], CONNECT FINISH notify\n"); | ||
3581 | } | ||
3582 | |||
3583 | void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist, | ||
3584 | u8 type) | ||
3585 | { | ||
3586 | u8 h2c_parameter[3] = {0}; | ||
3587 | u32 wifi_bw; | ||
3588 | u8 wifi_center_chnl; | ||
3589 | |||
3590 | if (btcoexist->manual_control || | ||
3591 | btcoexist->stop_coex_dm || | ||
3592 | btcoexist->bt_info.bt_disabled) | ||
3593 | return; | ||
3594 | |||
3595 | if (BTC_MEDIA_CONNECT == type) | ||
3596 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3597 | "[BTCoex], MEDIA connect notify\n"); | ||
3598 | else | ||
3599 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3600 | "[BTCoex], MEDIA disconnect notify\n"); | ||
3601 | |||
3602 | /* only 2.4G we need to inform bt the chnl mask */ | ||
3603 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, | ||
3604 | &wifi_center_chnl); | ||
3605 | if ((BTC_MEDIA_CONNECT == type) && | ||
3606 | (wifi_center_chnl <= 14)) { | ||
3607 | h2c_parameter[0] = 0x1; | ||
3608 | h2c_parameter[1] = wifi_center_chnl; | ||
3609 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3610 | if (BTC_WIFI_BW_HT40 == wifi_bw) | ||
3611 | h2c_parameter[2] = 0x30; | ||
3612 | else | ||
3613 | h2c_parameter[2] = 0x20; | ||
3614 | } | ||
3615 | |||
3616 | coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; | ||
3617 | coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; | ||
3618 | coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; | ||
3619 | |||
3620 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
3621 | "[BTCoex], FW write 0x66 = 0x%x\n", | ||
3622 | h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | | ||
3623 | h2c_parameter[2]); | ||
3624 | |||
3625 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); | ||
3626 | } | ||
3627 | |||
3628 | void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
3629 | u8 type) | ||
3630 | { | ||
3631 | if (type == BTC_PACKET_DHCP) | ||
3632 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3633 | "[BTCoex], DHCP Packet notify\n"); | ||
3634 | } | ||
3635 | |||
3636 | void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
3637 | u8 *tmp_buf, u8 length) | ||
3638 | { | ||
3639 | u8 bt_info = 0; | ||
3640 | u8 i, rsp_source = 0; | ||
3641 | bool bt_busy = false, limited_dig = false; | ||
3642 | bool wifi_connected = false; | ||
3643 | |||
3644 | coex_sta->c2h_bt_info_req_sent = false; | ||
3645 | |||
3646 | rsp_source = tmp_buf[0] & 0xf; | ||
3647 | if (rsp_source >= BT_INFO_SRC_8192E_2ANT_MAX) | ||
3648 | rsp_source = BT_INFO_SRC_8192E_2ANT_WIFI_FW; | ||
3649 | coex_sta->bt_info_c2h_cnt[rsp_source]++; | ||
3650 | |||
3651 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3652 | "[BTCoex], Bt info[%d], length=%d, hex data = [", | ||
3653 | rsp_source, length); | ||
3654 | for (i = 0; i < length; i++) { | ||
3655 | coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; | ||
3656 | if (i == 1) | ||
3657 | bt_info = tmp_buf[i]; | ||
3658 | if (i == length-1) | ||
3659 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3660 | "0x%02x]\n", tmp_buf[i]); | ||
3661 | else | ||
3662 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3663 | "0x%02x, ", tmp_buf[i]); | ||
3664 | } | ||
3665 | |||
3666 | if (BT_INFO_SRC_8192E_2ANT_WIFI_FW != rsp_source) { | ||
3667 | coex_sta->bt_retry_cnt = /* [3:0] */ | ||
3668 | coex_sta->bt_info_c2h[rsp_source][2] & 0xf; | ||
3669 | |||
3670 | coex_sta->bt_rssi = | ||
3671 | coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; | ||
3672 | |||
3673 | coex_sta->bt_info_ext = | ||
3674 | coex_sta->bt_info_c2h[rsp_source][4]; | ||
3675 | |||
3676 | /* Here we need to resend some wifi info to BT | ||
3677 | * because bt is reset and loss of the info. | ||
3678 | */ | ||
3679 | if ((coex_sta->bt_info_ext & BIT1)) { | ||
3680 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3681 | "bit1, send wifi BW&Chnl to BT!!\n"); | ||
3682 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
3683 | &wifi_connected); | ||
3684 | if (wifi_connected) | ||
3685 | ex_halbtc8192e2ant_media_status_notify( | ||
3686 | btcoexist, | ||
3687 | BTC_MEDIA_CONNECT); | ||
3688 | else | ||
3689 | ex_halbtc8192e2ant_media_status_notify( | ||
3690 | btcoexist, | ||
3691 | BTC_MEDIA_DISCONNECT); | ||
3692 | } | ||
3693 | |||
3694 | if ((coex_sta->bt_info_ext & BIT3)) { | ||
3695 | if (!btcoexist->manual_control && | ||
3696 | !btcoexist->stop_coex_dm) { | ||
3697 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3698 | "bit3, BT NOT ignore Wlan active!\n"); | ||
3699 | halbtc8192e2ant_IgnoreWlanAct(btcoexist, | ||
3700 | FORCE_EXEC, | ||
3701 | false); | ||
3702 | } | ||
3703 | } else { | ||
3704 | /* BT already NOT ignore Wlan active, | ||
3705 | * do nothing here. | ||
3706 | */ | ||
3707 | } | ||
3708 | |||
3709 | #if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 0) | ||
3710 | if ((coex_sta->bt_info_ext & BIT4)) { | ||
3711 | /* BT auto report already enabled, do nothing */ | ||
3712 | } else { | ||
3713 | halbtc8192e2ant_bt_autoreport(btcoexist, FORCE_EXEC, | ||
3714 | true); | ||
3715 | } | ||
3716 | #endif | ||
3717 | } | ||
3718 | |||
3719 | /* check BIT2 first ==> check if bt is under inquiry or page scan */ | ||
3720 | if (bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE) | ||
3721 | coex_sta->c2h_bt_inquiry_page = true; | ||
3722 | else | ||
3723 | coex_sta->c2h_bt_inquiry_page = false; | ||
3724 | |||
3725 | /* set link exist status */ | ||
3726 | if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) { | ||
3727 | coex_sta->bt_link_exist = false; | ||
3728 | coex_sta->pan_exist = false; | ||
3729 | coex_sta->a2dp_exist = false; | ||
3730 | coex_sta->hid_exist = false; | ||
3731 | coex_sta->sco_exist = false; | ||
3732 | } else {/* connection exists */ | ||
3733 | coex_sta->bt_link_exist = true; | ||
3734 | if (bt_info & BT_INFO_8192E_2ANT_B_FTP) | ||
3735 | coex_sta->pan_exist = true; | ||
3736 | else | ||
3737 | coex_sta->pan_exist = false; | ||
3738 | if (bt_info & BT_INFO_8192E_2ANT_B_A2DP) | ||
3739 | coex_sta->a2dp_exist = true; | ||
3740 | else | ||
3741 | coex_sta->a2dp_exist = false; | ||
3742 | if (bt_info & BT_INFO_8192E_2ANT_B_HID) | ||
3743 | coex_sta->hid_exist = true; | ||
3744 | else | ||
3745 | coex_sta->hid_exist = false; | ||
3746 | if (bt_info & BT_INFO_8192E_2ANT_B_SCO_ESCO) | ||
3747 | coex_sta->sco_exist = true; | ||
3748 | else | ||
3749 | coex_sta->sco_exist = false; | ||
3750 | } | ||
3751 | |||
3752 | halbtc8192e2ant_update_btlink_info(btcoexist); | ||
3753 | |||
3754 | if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) { | ||
3755 | coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE; | ||
3756 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3757 | "[BTCoex], BT Non-Connected idle!!!\n"); | ||
3758 | } else if (bt_info == BT_INFO_8192E_2ANT_B_CONNECTION) { | ||
3759 | coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE; | ||
3760 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3761 | "[BTCoex], bt_infoNotify(), BT Connected-idle!!!\n"); | ||
3762 | } else if ((bt_info&BT_INFO_8192E_2ANT_B_SCO_ESCO) || | ||
3763 | (bt_info&BT_INFO_8192E_2ANT_B_SCO_BUSY)) { | ||
3764 | coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_SCO_BUSY; | ||
3765 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3766 | "[BTCoex], bt_infoNotify(), BT SCO busy!!!\n"); | ||
3767 | } else if (bt_info&BT_INFO_8192E_2ANT_B_ACL_BUSY) { | ||
3768 | coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_ACL_BUSY; | ||
3769 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3770 | "[BTCoex], bt_infoNotify(), BT ACL busy!!!\n"); | ||
3771 | } else { | ||
3772 | coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_MAX; | ||
3773 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3774 | "[BTCoex]bt_infoNotify(), BT Non-Defined state!!!\n"); | ||
3775 | } | ||
3776 | |||
3777 | if ((BT_8192E_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || | ||
3778 | (BT_8192E_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
3779 | (BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { | ||
3780 | bt_busy = true; | ||
3781 | limited_dig = true; | ||
3782 | } else { | ||
3783 | bt_busy = false; | ||
3784 | limited_dig = false; | ||
3785 | } | ||
3786 | |||
3787 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); | ||
3788 | |||
3789 | coex_dm->limited_dig = limited_dig; | ||
3790 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); | ||
3791 | |||
3792 | halbtc8192e2ant_run_coexist_mechanism(btcoexist); | ||
3793 | } | ||
3794 | |||
3795 | void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist, | ||
3796 | u8 type) | ||
3797 | { | ||
3798 | } | ||
3799 | |||
3800 | void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist) | ||
3801 | { | ||
3802 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); | ||
3803 | |||
3804 | halbtc8192e2ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, true); | ||
3805 | ex_halbtc8192e2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); | ||
3806 | } | ||
3807 | |||
3808 | void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist) | ||
3809 | { | ||
3810 | static u8 dis_ver_info_cnt; | ||
3811 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
3812 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
3813 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
3814 | |||
3815 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3816 | "=======================Periodical=======================\n"); | ||
3817 | if (dis_ver_info_cnt <= 5) { | ||
3818 | dis_ver_info_cnt += 1; | ||
3819 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3820 | "************************************************\n"); | ||
3821 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3822 | "Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", | ||
3823 | board_info->pg_ant_num, board_info->btdm_ant_num, | ||
3824 | board_info->btdm_ant_pos); | ||
3825 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3826 | "BT stack/ hci ext ver = %s / %d\n", | ||
3827 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
3828 | stack_info->hci_version); | ||
3829 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, | ||
3830 | &bt_patch_ver); | ||
3831 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
3832 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3833 | "CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", | ||
3834 | glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant, | ||
3835 | fw_ver, bt_patch_ver, bt_patch_ver); | ||
3836 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3837 | "************************************************\n"); | ||
3838 | } | ||
3839 | |||
3840 | #if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 0) | ||
3841 | halbtc8192e2ant_querybt_info(btcoexist); | ||
3842 | halbtc8192e2ant_monitor_bt_ctr(btcoexist); | ||
3843 | btc8192e2ant_monitor_bt_enable_dis(btcoexist); | ||
3844 | #else | ||
3845 | if (halbtc8192e2ant_iswifi_status_changed(btcoexist) || | ||
3846 | coex_dm->auto_tdma_adjust) | ||
3847 | halbtc8192e2ant_run_coexist_mechanism(btcoexist); | ||
3848 | #endif | ||
3849 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h new file mode 100644 index 000000000000..75e1f7d0db06 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h | |||
@@ -0,0 +1,185 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | /***************************************************************** | ||
26 | * The following is for 8192E 2Ant BT Co-exist definition | ||
27 | *****************************************************************/ | ||
28 | #define BT_AUTO_REPORT_ONLY_8192E_2ANT 0 | ||
29 | |||
30 | #define BT_INFO_8192E_2ANT_B_FTP BIT7 | ||
31 | #define BT_INFO_8192E_2ANT_B_A2DP BIT6 | ||
32 | #define BT_INFO_8192E_2ANT_B_HID BIT5 | ||
33 | #define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4 | ||
34 | #define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3 | ||
35 | #define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2 | ||
36 | #define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1 | ||
37 | #define BT_INFO_8192E_2ANT_B_CONNECTION BIT0 | ||
38 | |||
39 | #define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2 | ||
40 | |||
41 | enum bt_info_src_8192e_2ant { | ||
42 | BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0, | ||
43 | BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1, | ||
44 | BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2, | ||
45 | BT_INFO_SRC_8192E_2ANT_MAX | ||
46 | }; | ||
47 | |||
48 | enum bt_8192e_2ant_bt_status { | ||
49 | BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, | ||
50 | BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1, | ||
51 | BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2, | ||
52 | BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3, | ||
53 | BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4, | ||
54 | BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, | ||
55 | BT_8192E_2ANT_BT_STATUS_MAX | ||
56 | }; | ||
57 | |||
58 | enum bt_8192e_2ant_coex_algo { | ||
59 | BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0, | ||
60 | BT_8192E_2ANT_COEX_ALGO_SCO = 0x1, | ||
61 | BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2, | ||
62 | BT_8192E_2ANT_COEX_ALGO_HID = 0x3, | ||
63 | BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4, | ||
64 | BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5, | ||
65 | BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6, | ||
66 | BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7, | ||
67 | BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8, | ||
68 | BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9, | ||
69 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa, | ||
70 | BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb, | ||
71 | BT_8192E_2ANT_COEX_ALGO_MAX = 0xc | ||
72 | }; | ||
73 | |||
74 | struct coex_dm_8192e_2ant { | ||
75 | /* fw mechanism */ | ||
76 | u8 pre_dec_bt_pwr; | ||
77 | u8 cur_dec_bt_pwr; | ||
78 | u8 pre_fw_dac_swing_lvl; | ||
79 | u8 cur_fw_dac_swing_lvl; | ||
80 | bool cur_ignore_wlan_act; | ||
81 | bool pre_ignore_wlan_act; | ||
82 | u8 pre_ps_tdma; | ||
83 | u8 cur_ps_tdma; | ||
84 | u8 ps_tdma_para[5]; | ||
85 | u8 tdma_adj_type; | ||
86 | bool reset_tdma_adjust; | ||
87 | bool auto_tdma_adjust; | ||
88 | bool pre_ps_tdma_on; | ||
89 | bool cur_ps_tdma_on; | ||
90 | bool pre_bt_auto_report; | ||
91 | bool cur_bt_auto_report; | ||
92 | |||
93 | /* sw mechanism */ | ||
94 | bool pre_rf_rx_lpf_shrink; | ||
95 | bool cur_rf_rx_lpf_shrink; | ||
96 | u32 bt_rf0x1e_backup; | ||
97 | bool pre_low_penalty_ra; | ||
98 | bool cur_low_penalty_ra; | ||
99 | bool pre_dac_swing_on; | ||
100 | u32 pre_dac_swing_lvl; | ||
101 | bool cur_dac_swing_on; | ||
102 | u32 cur_dac_swing_lvl; | ||
103 | bool pre_adc_back_off; | ||
104 | bool cur_adc_back_off; | ||
105 | bool pre_agc_table_en; | ||
106 | bool cur_agc_table_en; | ||
107 | u32 pre_val0x6c0; | ||
108 | u32 cur_val0x6c0; | ||
109 | u32 pre_val0x6c4; | ||
110 | u32 cur_val0x6c4; | ||
111 | u32 pre_val0x6c8; | ||
112 | u32 cur_val0x6c8; | ||
113 | u8 pre_val0x6cc; | ||
114 | u8 cur_val0x6cc; | ||
115 | bool limited_dig; | ||
116 | |||
117 | u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */ | ||
118 | u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */ | ||
119 | u16 backup_retrylimit; | ||
120 | u8 backup_ampdu_maxtime; | ||
121 | |||
122 | /* algorithm related */ | ||
123 | u8 pre_algorithm; | ||
124 | u8 cur_algorithm; | ||
125 | u8 bt_status; | ||
126 | u8 wifi_chnl_info[3]; | ||
127 | |||
128 | u8 pre_sstype; | ||
129 | u8 cur_sstype; | ||
130 | |||
131 | u32 prera_mask; | ||
132 | u32 curra_mask; | ||
133 | u8 curra_masktype; | ||
134 | u8 pre_arfrtype; | ||
135 | u8 cur_arfrtype; | ||
136 | u8 pre_retrylimit_type; | ||
137 | u8 cur_retrylimit_type; | ||
138 | u8 pre_ampdutime_type; | ||
139 | u8 cur_ampdutime_type; | ||
140 | }; | ||
141 | |||
142 | struct coex_sta_8192e_2ant { | ||
143 | bool bt_link_exist; | ||
144 | bool sco_exist; | ||
145 | bool a2dp_exist; | ||
146 | bool hid_exist; | ||
147 | bool pan_exist; | ||
148 | |||
149 | bool under_lps; | ||
150 | bool under_ips; | ||
151 | u32 high_priority_tx; | ||
152 | u32 high_priority_rx; | ||
153 | u32 low_priority_tx; | ||
154 | u32 low_priority_rx; | ||
155 | u8 bt_rssi; | ||
156 | u8 pre_bt_rssi_state; | ||
157 | u8 pre_wifi_rssi_state[4]; | ||
158 | bool c2h_bt_info_req_sent; | ||
159 | u8 bt_info_c2h[BT_INFO_SRC_8192E_2ANT_MAX][10]; | ||
160 | u32 bt_info_c2h_cnt[BT_INFO_SRC_8192E_2ANT_MAX]; | ||
161 | bool c2h_bt_inquiry_page; | ||
162 | u8 bt_retry_cnt; | ||
163 | u8 bt_info_ext; | ||
164 | }; | ||
165 | |||
166 | /**************************************************************** | ||
167 | * The following is interface which will notify coex module. | ||
168 | ****************************************************************/ | ||
169 | void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist); | ||
170 | void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist); | ||
171 | void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); | ||
172 | void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); | ||
173 | void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); | ||
174 | void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); | ||
175 | void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist, | ||
176 | u8 type); | ||
177 | void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
178 | u8 type); | ||
179 | void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
180 | u8 *tmpbuf, u8 length); | ||
181 | void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist, | ||
182 | u8 type); | ||
183 | void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist); | ||
184 | void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist); | ||
185 | void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist); | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c new file mode 100644 index 000000000000..c4acd403e5f6 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c | |||
@@ -0,0 +1,3170 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | /*************************************************************** | ||
27 | * Description: | ||
28 | * | ||
29 | * This file is for RTL8723B Co-exist mechanism | ||
30 | * | ||
31 | * History | ||
32 | * 2012/11/15 Cosa first check in. | ||
33 | * | ||
34 | ***************************************************************/ | ||
35 | |||
36 | /*************************************************************** | ||
37 | * include files | ||
38 | ***************************************************************/ | ||
39 | #include "halbt_precomp.h" | ||
40 | /*************************************************************** | ||
41 | * Global variables, these are static variables | ||
42 | ***************************************************************/ | ||
43 | static struct coex_dm_8723b_1ant glcoex_dm_8723b_1ant; | ||
44 | static struct coex_dm_8723b_1ant *coex_dm = &glcoex_dm_8723b_1ant; | ||
45 | static struct coex_sta_8723b_1ant glcoex_sta_8723b_1ant; | ||
46 | static struct coex_sta_8723b_1ant *coex_sta = &glcoex_sta_8723b_1ant; | ||
47 | |||
48 | static const char *const GLBtInfoSrc8723b1Ant[] = { | ||
49 | "BT Info[wifi fw]", | ||
50 | "BT Info[bt rsp]", | ||
51 | "BT Info[bt auto report]", | ||
52 | }; | ||
53 | |||
54 | static u32 glcoex_ver_date_8723b_1ant = 20130918; | ||
55 | static u32 glcoex_ver_8723b_1ant = 0x47; | ||
56 | |||
57 | /*************************************************************** | ||
58 | * local function proto type if needed | ||
59 | ***************************************************************/ | ||
60 | /*************************************************************** | ||
61 | * local function start with halbtc8723b1ant_ | ||
62 | ***************************************************************/ | ||
63 | static u8 halbtc8723b1ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, | ||
64 | u8 rssi_thresh1) | ||
65 | { | ||
66 | s32 bt_rssi = 0; | ||
67 | u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; | ||
68 | |||
69 | bt_rssi = coex_sta->bt_rssi; | ||
70 | |||
71 | if (level_num == 2) { | ||
72 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
73 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
74 | if (bt_rssi >= rssi_thresh + | ||
75 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
76 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
77 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
78 | "[BTCoex], BT Rssi state switch to High\n"); | ||
79 | } else { | ||
80 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
81 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
82 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
83 | } | ||
84 | } else { | ||
85 | if (bt_rssi < rssi_thresh) { | ||
86 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
87 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
88 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
89 | } else { | ||
90 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
91 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
92 | "[BTCoex], BT Rssi state stay at High\n"); | ||
93 | } | ||
94 | } | ||
95 | } else if (level_num == 3) { | ||
96 | if (rssi_thresh > rssi_thresh1) { | ||
97 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
98 | "[BTCoex], BT Rssi thresh error!!\n"); | ||
99 | return coex_sta->pre_bt_rssi_state; | ||
100 | } | ||
101 | |||
102 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
103 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
104 | if (bt_rssi >= rssi_thresh + | ||
105 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
106 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
107 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
108 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
109 | } else { | ||
110 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
111 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
112 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
113 | } | ||
114 | } else if ((coex_sta->pre_bt_rssi_state == | ||
115 | BTC_RSSI_STATE_MEDIUM) || | ||
116 | (coex_sta->pre_bt_rssi_state == | ||
117 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
118 | if (bt_rssi >= rssi_thresh1 + | ||
119 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
120 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
121 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
122 | "[BTCoex], BT Rssi state switch to High\n"); | ||
123 | } else if (bt_rssi < rssi_thresh) { | ||
124 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
125 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
126 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
127 | } else { | ||
128 | bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
129 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
130 | "[BTCoex], BT Rssi state stay at Medium\n"); | ||
131 | } | ||
132 | } else { | ||
133 | if (bt_rssi < rssi_thresh1) { | ||
134 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
135 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
136 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
137 | } else { | ||
138 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
139 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
140 | "[BTCoex], BT Rssi state stay at High\n"); | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | |||
145 | coex_sta->pre_bt_rssi_state = bt_rssi_state; | ||
146 | |||
147 | return bt_rssi_state; | ||
148 | } | ||
149 | |||
150 | static u8 halbtc8723b1ant_wifi_rssi_state(struct btc_coexist *btcoexist, | ||
151 | u8 index, u8 level_num, | ||
152 | u8 rssi_thresh, u8 rssi_thresh1) | ||
153 | { | ||
154 | s32 wifi_rssi = 0; | ||
155 | u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; | ||
156 | |||
157 | btcoexist->btc_get(btcoexist, | ||
158 | BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
159 | |||
160 | if (level_num == 2) { | ||
161 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
162 | BTC_RSSI_STATE_LOW) || | ||
163 | (coex_sta->pre_wifi_rssi_state[index] == | ||
164 | BTC_RSSI_STATE_STAY_LOW)) { | ||
165 | if (wifi_rssi >= rssi_thresh + | ||
166 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
167 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
168 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
169 | ALGO_WIFI_RSSI_STATE, | ||
170 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
171 | } else { | ||
172 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
173 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
174 | ALGO_WIFI_RSSI_STATE, | ||
175 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
176 | } | ||
177 | } else { | ||
178 | if (wifi_rssi < rssi_thresh) { | ||
179 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
180 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
181 | ALGO_WIFI_RSSI_STATE, | ||
182 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
183 | } else { | ||
184 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
185 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
186 | ALGO_WIFI_RSSI_STATE, | ||
187 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
188 | } | ||
189 | } | ||
190 | } else if (level_num == 3) { | ||
191 | if (rssi_thresh > rssi_thresh1) { | ||
192 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, | ||
193 | "[BTCoex], wifi RSSI thresh error!!\n"); | ||
194 | return coex_sta->pre_wifi_rssi_state[index]; | ||
195 | } | ||
196 | |||
197 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
198 | BTC_RSSI_STATE_LOW) || | ||
199 | (coex_sta->pre_wifi_rssi_state[index] == | ||
200 | BTC_RSSI_STATE_STAY_LOW)) { | ||
201 | if (wifi_rssi >= rssi_thresh + | ||
202 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
203 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
204 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
205 | ALGO_WIFI_RSSI_STATE, | ||
206 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
207 | } else { | ||
208 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
209 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
210 | ALGO_WIFI_RSSI_STATE, | ||
211 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
212 | } | ||
213 | } else if ((coex_sta->pre_wifi_rssi_state[index] == | ||
214 | BTC_RSSI_STATE_MEDIUM) || | ||
215 | (coex_sta->pre_wifi_rssi_state[index] == | ||
216 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
217 | if (wifi_rssi >= rssi_thresh1 + | ||
218 | BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) { | ||
219 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
220 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
221 | ALGO_WIFI_RSSI_STATE, | ||
222 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
223 | } else if (wifi_rssi < rssi_thresh) { | ||
224 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
225 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
226 | ALGO_WIFI_RSSI_STATE, | ||
227 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
228 | } else { | ||
229 | wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
230 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
231 | ALGO_WIFI_RSSI_STATE, | ||
232 | "[BTCoex], wifi RSSI state stay at Medium\n"); | ||
233 | } | ||
234 | } else { | ||
235 | if (wifi_rssi < rssi_thresh1) { | ||
236 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
237 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
238 | ALGO_WIFI_RSSI_STATE, | ||
239 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
240 | } else { | ||
241 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
242 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
243 | ALGO_WIFI_RSSI_STATE, | ||
244 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | |||
249 | coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; | ||
250 | |||
251 | return wifi_rssi_state; | ||
252 | } | ||
253 | |||
254 | static void halbtc8723b1ant_updatera_mask(struct btc_coexist *btcoexist, | ||
255 | bool force_exec, u32 dis_rate_mask) | ||
256 | { | ||
257 | coex_dm->curra_mask = dis_rate_mask; | ||
258 | |||
259 | if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask)) | ||
260 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask, | ||
261 | &coex_dm->curra_mask); | ||
262 | |||
263 | coex_dm->prera_mask = coex_dm->curra_mask; | ||
264 | } | ||
265 | |||
266 | static void btc8723b1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist, | ||
267 | bool force_exec, u8 type) | ||
268 | { | ||
269 | bool wifi_under_bmode = false; | ||
270 | |||
271 | coex_dm->cur_arfr_type = type; | ||
272 | |||
273 | if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { | ||
274 | switch (coex_dm->cur_arfr_type) { | ||
275 | case 0: /* normal mode */ | ||
276 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
277 | coex_dm->backup_arfr_cnt1); | ||
278 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
279 | coex_dm->backup_arfr_cnt2); | ||
280 | break; | ||
281 | case 1: | ||
282 | btcoexist->btc_get(btcoexist, | ||
283 | BTC_GET_BL_WIFI_UNDER_B_MODE, | ||
284 | &wifi_under_bmode); | ||
285 | if (wifi_under_bmode) { | ||
286 | btcoexist->btc_write_4byte(btcoexist, | ||
287 | 0x430, 0x0); | ||
288 | btcoexist->btc_write_4byte(btcoexist, | ||
289 | 0x434, 0x01010101); | ||
290 | } else { | ||
291 | btcoexist->btc_write_4byte(btcoexist, | ||
292 | 0x430, 0x0); | ||
293 | btcoexist->btc_write_4byte(btcoexist, | ||
294 | 0x434, 0x04030201); | ||
295 | } | ||
296 | break; | ||
297 | default: | ||
298 | break; | ||
299 | } | ||
300 | } | ||
301 | |||
302 | coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; | ||
303 | } | ||
304 | |||
305 | static void halbtc8723b1ant_retry_limit(struct btc_coexist *btcoexist, | ||
306 | bool force_exec, u8 type) | ||
307 | { | ||
308 | coex_dm->cur_retry_limit_type = type; | ||
309 | |||
310 | if (force_exec || (coex_dm->pre_retry_limit_type != | ||
311 | coex_dm->cur_retry_limit_type)) { | ||
312 | switch (coex_dm->cur_retry_limit_type) { | ||
313 | case 0: /* normal mode */ | ||
314 | btcoexist->btc_write_2byte(btcoexist, 0x42a, | ||
315 | coex_dm->backup_retry_limit); | ||
316 | break; | ||
317 | case 1: /* retry limit = 8 */ | ||
318 | btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); | ||
319 | break; | ||
320 | default: | ||
321 | break; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; | ||
326 | } | ||
327 | |||
328 | static void halbtc8723b1ant_ampdu_maxtime(struct btc_coexist *btcoexist, | ||
329 | bool force_exec, u8 type) | ||
330 | { | ||
331 | coex_dm->cur_ampdu_time_type = type; | ||
332 | |||
333 | if (force_exec || (coex_dm->pre_ampdu_time_type != | ||
334 | coex_dm->cur_ampdu_time_type)) { | ||
335 | switch (coex_dm->cur_ampdu_time_type) { | ||
336 | case 0: /* normal mode */ | ||
337 | btcoexist->btc_write_1byte(btcoexist, 0x456, | ||
338 | coex_dm->backup_ampdu_max_time); | ||
339 | break; | ||
340 | case 1: /* AMPDU timw = 0x38 * 32us */ | ||
341 | btcoexist->btc_write_1byte(btcoexist, | ||
342 | 0x456, 0x38); | ||
343 | break; | ||
344 | default: | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; | ||
350 | } | ||
351 | |||
352 | static void halbtc8723b1ant_limited_tx(struct btc_coexist *btcoexist, | ||
353 | bool force_exec, u8 ra_masktype, | ||
354 | u8 arfr_type, u8 retry_limit_type, | ||
355 | u8 ampdu_time_type) | ||
356 | { | ||
357 | switch (ra_masktype) { | ||
358 | case 0: /* normal mode */ | ||
359 | halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 0x0); | ||
360 | break; | ||
361 | case 1: /* disable cck 1/2 */ | ||
362 | halbtc8723b1ant_updatera_mask(btcoexist, force_exec, | ||
363 | 0x00000003); | ||
364 | break; | ||
365 | /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4*/ | ||
366 | case 2: | ||
367 | halbtc8723b1ant_updatera_mask(btcoexist, force_exec, | ||
368 | 0x0001f1f7); | ||
369 | break; | ||
370 | default: | ||
371 | break; | ||
372 | } | ||
373 | |||
374 | btc8723b1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type); | ||
375 | halbtc8723b1ant_retry_limit(btcoexist, force_exec, retry_limit_type); | ||
376 | halbtc8723b1ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type); | ||
377 | } | ||
378 | |||
379 | static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist, | ||
380 | bool force_exec, bool rej_ap_agg_pkt, | ||
381 | bool bt_ctrl_agg_buf_size, | ||
382 | u8 agg_buf_size) | ||
383 | { | ||
384 | bool reject_rx_agg = rej_ap_agg_pkt; | ||
385 | bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; | ||
386 | u8 rxaggsize = agg_buf_size; | ||
387 | |||
388 | /********************************************** | ||
389 | * Rx Aggregation related setting | ||
390 | **********************************************/ | ||
391 | btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, | ||
392 | &reject_rx_agg); | ||
393 | /* decide BT control aggregation buf size or not */ | ||
394 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, | ||
395 | &bt_ctrl_rx_agg_size); | ||
396 | /* aggregation buf size, only work | ||
397 | * when BT control Rx aggregation size. | ||
398 | */ | ||
399 | btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxaggsize); | ||
400 | /* real update aggregation setting */ | ||
401 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); | ||
402 | } | ||
403 | |||
404 | static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) | ||
405 | { | ||
406 | u32 reg_hp_txrx, reg_lp_txrx, u32tmp; | ||
407 | u32 reg_hp_tx = 0, reg_hp_rx = 0; | ||
408 | u32 reg_lp_tx = 0, reg_lp_rx = 0; | ||
409 | |||
410 | reg_hp_txrx = 0x770; | ||
411 | reg_lp_txrx = 0x774; | ||
412 | |||
413 | u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); | ||
414 | reg_hp_tx = u32tmp & MASKLWORD; | ||
415 | reg_hp_rx = (u32tmp & MASKHWORD) >> 16; | ||
416 | |||
417 | u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); | ||
418 | reg_lp_tx = u32tmp & MASKLWORD; | ||
419 | reg_lp_rx = (u32tmp & MASKHWORD) >> 16; | ||
420 | |||
421 | coex_sta->high_priority_tx = reg_hp_tx; | ||
422 | coex_sta->high_priority_rx = reg_hp_rx; | ||
423 | coex_sta->low_priority_tx = reg_lp_tx; | ||
424 | coex_sta->low_priority_rx = reg_lp_rx; | ||
425 | |||
426 | /* reset counter */ | ||
427 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
428 | } | ||
429 | |||
430 | static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist) | ||
431 | { | ||
432 | u8 h2c_parameter[1] = {0}; | ||
433 | |||
434 | coex_sta->c2h_bt_info_req_sent = true; | ||
435 | |||
436 | h2c_parameter[0] |= BIT0; /* trigger*/ | ||
437 | |||
438 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
439 | "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", | ||
440 | h2c_parameter[0]); | ||
441 | |||
442 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | ||
443 | } | ||
444 | |||
445 | static bool btc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist) | ||
446 | { | ||
447 | static bool pre_wifi_busy; | ||
448 | static bool pre_under_4way, pre_bt_hs_on; | ||
449 | bool wifi_busy = false, under_4way = false, bt_hs_on = false; | ||
450 | bool wifi_connected = false; | ||
451 | |||
452 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
453 | &wifi_connected); | ||
454 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
455 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
456 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, | ||
457 | &under_4way); | ||
458 | |||
459 | if (wifi_connected) { | ||
460 | if (wifi_busy != pre_wifi_busy) { | ||
461 | pre_wifi_busy = wifi_busy; | ||
462 | return true; | ||
463 | } | ||
464 | if (under_4way != pre_under_4way) { | ||
465 | pre_under_4way = under_4way; | ||
466 | return true; | ||
467 | } | ||
468 | if (bt_hs_on != pre_bt_hs_on) { | ||
469 | pre_bt_hs_on = bt_hs_on; | ||
470 | return true; | ||
471 | } | ||
472 | } | ||
473 | |||
474 | return false; | ||
475 | } | ||
476 | |||
477 | static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist) | ||
478 | { | ||
479 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
480 | bool bt_hs_on = false; | ||
481 | |||
482 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
483 | |||
484 | bt_link_info->bt_link_exist = coex_sta->bt_link_exist; | ||
485 | bt_link_info->sco_exist = coex_sta->sco_exist; | ||
486 | bt_link_info->a2dp_exist = coex_sta->a2dp_exist; | ||
487 | bt_link_info->pan_exist = coex_sta->pan_exist; | ||
488 | bt_link_info->hid_exist = coex_sta->hid_exist; | ||
489 | |||
490 | /* work around for HS mode. */ | ||
491 | if (bt_hs_on) { | ||
492 | bt_link_info->pan_exist = true; | ||
493 | bt_link_info->bt_link_exist = true; | ||
494 | } | ||
495 | |||
496 | /* check if Sco only */ | ||
497 | if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist && | ||
498 | !bt_link_info->pan_exist && !bt_link_info->hid_exist) | ||
499 | bt_link_info->sco_only = true; | ||
500 | else | ||
501 | bt_link_info->sco_only = false; | ||
502 | |||
503 | /* check if A2dp only */ | ||
504 | if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist && | ||
505 | !bt_link_info->pan_exist && !bt_link_info->hid_exist) | ||
506 | bt_link_info->a2dp_only = true; | ||
507 | else | ||
508 | bt_link_info->a2dp_only = false; | ||
509 | |||
510 | /* check if Pan only */ | ||
511 | if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && | ||
512 | bt_link_info->pan_exist && !bt_link_info->hid_exist) | ||
513 | bt_link_info->pan_only = true; | ||
514 | else | ||
515 | bt_link_info->pan_only = false; | ||
516 | |||
517 | /* check if Hid only */ | ||
518 | if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist && | ||
519 | !bt_link_info->pan_exist && bt_link_info->hid_exist) | ||
520 | bt_link_info->hid_only = true; | ||
521 | else | ||
522 | bt_link_info->hid_only = false; | ||
523 | } | ||
524 | |||
525 | static u8 halbtc8723b1ant_action_algorithm(struct btc_coexist *btcoexist) | ||
526 | { | ||
527 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
528 | bool bt_hs_on = false; | ||
529 | u8 algorithm = BT_8723B_1ANT_COEX_ALGO_UNDEFINED; | ||
530 | u8 numdiffprofile = 0; | ||
531 | |||
532 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
533 | |||
534 | if (!bt_link_info->bt_link_exist) { | ||
535 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
536 | "[BTCoex], No BT link exists!!!\n"); | ||
537 | return algorithm; | ||
538 | } | ||
539 | |||
540 | if (bt_link_info->sco_exist) | ||
541 | numdiffprofile++; | ||
542 | if (bt_link_info->hid_exist) | ||
543 | numdiffprofile++; | ||
544 | if (bt_link_info->pan_exist) | ||
545 | numdiffprofile++; | ||
546 | if (bt_link_info->a2dp_exist) | ||
547 | numdiffprofile++; | ||
548 | |||
549 | if (numdiffprofile == 1) { | ||
550 | if (bt_link_info->sco_exist) { | ||
551 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
552 | "[BTCoex], BT Profile = SCO only\n"); | ||
553 | algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; | ||
554 | } else { | ||
555 | if (bt_link_info->hid_exist) { | ||
556 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
557 | "[BTCoex], BT Profile = HID only\n"); | ||
558 | algorithm = BT_8723B_1ANT_COEX_ALGO_HID; | ||
559 | } else if (bt_link_info->a2dp_exist) { | ||
560 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
561 | "[BTCoex], BT Profile = A2DP only\n"); | ||
562 | algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP; | ||
563 | } else if (bt_link_info->pan_exist) { | ||
564 | if (bt_hs_on) { | ||
565 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
566 | "[BTCoex], BT Profile = PAN(HS) only\n"); | ||
567 | algorithm = | ||
568 | BT_8723B_1ANT_COEX_ALGO_PANHS; | ||
569 | } else { | ||
570 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
571 | "[BTCoex], BT Profile = PAN(EDR) only\n"); | ||
572 | algorithm = | ||
573 | BT_8723B_1ANT_COEX_ALGO_PANEDR; | ||
574 | } | ||
575 | } | ||
576 | } | ||
577 | } else if (numdiffprofile == 2) { | ||
578 | if (bt_link_info->sco_exist) { | ||
579 | if (bt_link_info->hid_exist) { | ||
580 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
581 | "[BTCoex], BT Profile = SCO + HID\n"); | ||
582 | algorithm = BT_8723B_1ANT_COEX_ALGO_HID; | ||
583 | } else if (bt_link_info->a2dp_exist) { | ||
584 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
585 | "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n"); | ||
586 | algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; | ||
587 | } else if (bt_link_info->pan_exist) { | ||
588 | if (bt_hs_on) { | ||
589 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
590 | "[BTCoex], BT Profile = SCO + PAN(HS)\n"); | ||
591 | algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; | ||
592 | } else { | ||
593 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
594 | "[BTCoex], BT Profile = SCO + PAN(EDR)\n"); | ||
595 | algorithm = | ||
596 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; | ||
597 | } | ||
598 | } | ||
599 | } else { | ||
600 | if (bt_link_info->hid_exist && | ||
601 | bt_link_info->a2dp_exist) { | ||
602 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
603 | "[BTCoex], BT Profile = HID + A2DP\n"); | ||
604 | algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP; | ||
605 | } else if (bt_link_info->hid_exist && | ||
606 | bt_link_info->pan_exist) { | ||
607 | if (bt_hs_on) { | ||
608 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
609 | "[BTCoex], BT Profile = HID + PAN(HS)\n"); | ||
610 | algorithm = | ||
611 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP; | ||
612 | } else { | ||
613 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
614 | "[BTCoex], BT Profile = HID + PAN(EDR)\n"); | ||
615 | algorithm = | ||
616 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; | ||
617 | } | ||
618 | } else if (bt_link_info->pan_exist && | ||
619 | bt_link_info->a2dp_exist) { | ||
620 | if (bt_hs_on) { | ||
621 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
622 | "[BTCoex], BT Profile = A2DP + PAN(HS)\n"); | ||
623 | algorithm = | ||
624 | BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS; | ||
625 | } else { | ||
626 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
627 | "[BTCoex], BT Profile = A2DP + PAN(EDR)\n"); | ||
628 | algorithm = | ||
629 | BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP; | ||
630 | } | ||
631 | } | ||
632 | } | ||
633 | } else if (numdiffprofile == 3) { | ||
634 | if (bt_link_info->sco_exist) { | ||
635 | if (bt_link_info->hid_exist && | ||
636 | bt_link_info->a2dp_exist) { | ||
637 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
638 | "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n"); | ||
639 | algorithm = BT_8723B_1ANT_COEX_ALGO_HID; | ||
640 | } else if (bt_link_info->hid_exist && | ||
641 | bt_link_info->pan_exist) { | ||
642 | if (bt_hs_on) { | ||
643 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
644 | "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n"); | ||
645 | algorithm = | ||
646 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP; | ||
647 | } else { | ||
648 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
649 | "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n"); | ||
650 | algorithm = | ||
651 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; | ||
652 | } | ||
653 | } else if (bt_link_info->pan_exist && | ||
654 | bt_link_info->a2dp_exist) { | ||
655 | if (bt_hs_on) { | ||
656 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
657 | "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n"); | ||
658 | algorithm = BT_8723B_1ANT_COEX_ALGO_SCO; | ||
659 | } else { | ||
660 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
661 | "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n"); | ||
662 | algorithm = | ||
663 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; | ||
664 | } | ||
665 | } | ||
666 | } else { | ||
667 | if (bt_link_info->hid_exist && | ||
668 | bt_link_info->pan_exist && | ||
669 | bt_link_info->a2dp_exist) { | ||
670 | if (bt_hs_on) { | ||
671 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
672 | "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n"); | ||
673 | algorithm = | ||
674 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP; | ||
675 | } else { | ||
676 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
677 | "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n"); | ||
678 | algorithm = | ||
679 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
680 | } | ||
681 | } | ||
682 | } | ||
683 | } else if (numdiffprofile >= 3) { | ||
684 | if (bt_link_info->sco_exist) { | ||
685 | if (bt_link_info->hid_exist && | ||
686 | bt_link_info->pan_exist && | ||
687 | bt_link_info->a2dp_exist) { | ||
688 | if (bt_hs_on) { | ||
689 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
690 | "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n"); | ||
691 | } else { | ||
692 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
693 | "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); | ||
694 | algorithm = | ||
695 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID; | ||
696 | } | ||
697 | } | ||
698 | } | ||
699 | } | ||
700 | |||
701 | return algorithm; | ||
702 | } | ||
703 | |||
704 | static void btc8723b1ant_set_sw_pen_tx_rate_adapt(struct btc_coexist *btcoexist, | ||
705 | bool low_penalty_ra) | ||
706 | { | ||
707 | u8 h2c_parameter[6] = {0}; | ||
708 | |||
709 | h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */ | ||
710 | |||
711 | if (low_penalty_ra) { | ||
712 | h2c_parameter[1] |= BIT0; | ||
713 | /*normal rate except MCS7/6/5, OFDM54/48/36 */ | ||
714 | h2c_parameter[2] = 0x00; | ||
715 | h2c_parameter[3] = 0xf7; /*MCS7 or OFDM54 */ | ||
716 | h2c_parameter[4] = 0xf8; /*MCS6 or OFDM48 */ | ||
717 | h2c_parameter[5] = 0xf9; /*MCS5 or OFDM36 */ | ||
718 | } | ||
719 | |||
720 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
721 | "[BTCoex], set WiFi Low-Penalty Retry: %s", | ||
722 | (low_penalty_ra ? "ON!!" : "OFF!!")); | ||
723 | |||
724 | btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); | ||
725 | } | ||
726 | |||
727 | static void halbtc8723b1ant_low_penalty_ra(struct btc_coexist *btcoexist, | ||
728 | bool force_exec, bool low_penalty_ra) | ||
729 | { | ||
730 | coex_dm->cur_low_penalty_ra = low_penalty_ra; | ||
731 | |||
732 | if (!force_exec) { | ||
733 | if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) | ||
734 | return; | ||
735 | } | ||
736 | btc8723b1ant_set_sw_pen_tx_rate_adapt(btcoexist, | ||
737 | coex_dm->cur_low_penalty_ra); | ||
738 | |||
739 | coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; | ||
740 | } | ||
741 | |||
742 | static void halbtc8723b1ant_set_coex_table(struct btc_coexist *btcoexist, | ||
743 | u32 val0x6c0, u32 val0x6c4, | ||
744 | u32 val0x6c8, u8 val0x6cc) | ||
745 | { | ||
746 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
747 | "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); | ||
748 | btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); | ||
749 | |||
750 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
751 | "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); | ||
752 | btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); | ||
753 | |||
754 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
755 | "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); | ||
756 | btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); | ||
757 | |||
758 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
759 | "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); | ||
760 | btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); | ||
761 | } | ||
762 | |||
763 | static void halbtc8723b1ant_coex_table(struct btc_coexist *btcoexist, | ||
764 | bool force_exec, u32 val0x6c0, | ||
765 | u32 val0x6c4, u32 val0x6c8, | ||
766 | u8 val0x6cc) | ||
767 | { | ||
768 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
769 | "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6cc = 0x%x\n", | ||
770 | (force_exec ? "force to" : ""), | ||
771 | val0x6c0, val0x6c4, val0x6cc); | ||
772 | coex_dm->cur_val0x6c0 = val0x6c0; | ||
773 | coex_dm->cur_val0x6c4 = val0x6c4; | ||
774 | coex_dm->cur_val0x6c8 = val0x6c8; | ||
775 | coex_dm->cur_val0x6cc = val0x6cc; | ||
776 | |||
777 | if (!force_exec) { | ||
778 | if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && | ||
779 | (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && | ||
780 | (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && | ||
781 | (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) | ||
782 | return; | ||
783 | } | ||
784 | halbtc8723b1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, | ||
785 | val0x6c8, val0x6cc); | ||
786 | |||
787 | coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; | ||
788 | coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; | ||
789 | coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; | ||
790 | coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; | ||
791 | } | ||
792 | |||
793 | static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist, | ||
794 | bool force_exec, u8 type) | ||
795 | { | ||
796 | switch (type) { | ||
797 | case 0: | ||
798 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
799 | 0x55555555, 0xffffff, 0x3); | ||
800 | break; | ||
801 | case 1: | ||
802 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
803 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
804 | break; | ||
805 | case 2: | ||
806 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, | ||
807 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
808 | break; | ||
809 | case 3: | ||
810 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
811 | 0xaaaaaaaa, 0xffffff, 0x3); | ||
812 | break; | ||
813 | case 4: | ||
814 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
815 | 0x5aaa5aaa, 0xffffff, 0x3); | ||
816 | break; | ||
817 | case 5: | ||
818 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, | ||
819 | 0xaaaa5a5a, 0xffffff, 0x3); | ||
820 | break; | ||
821 | case 6: | ||
822 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
823 | 0xaaaa5a5a, 0xffffff, 0x3); | ||
824 | break; | ||
825 | case 7: | ||
826 | halbtc8723b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa, | ||
827 | 0xaaaaaaaa, 0xffffff, 0x3); | ||
828 | break; | ||
829 | default: | ||
830 | break; | ||
831 | } | ||
832 | } | ||
833 | |||
834 | static void halbtc8723b1ant_SetFwIgnoreWlanAct(struct btc_coexist *btcoexist, | ||
835 | bool enable) | ||
836 | { | ||
837 | u8 h2c_parameter[1] = {0}; | ||
838 | |||
839 | if (enable) | ||
840 | h2c_parameter[0] |= BIT0; /* function enable */ | ||
841 | |||
842 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
843 | "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", | ||
844 | h2c_parameter[0]); | ||
845 | |||
846 | btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); | ||
847 | } | ||
848 | |||
849 | static void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist, | ||
850 | bool force_exec, bool enable) | ||
851 | { | ||
852 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
853 | "[BTCoex], %s turn Ignore WlanAct %s\n", | ||
854 | (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); | ||
855 | coex_dm->cur_ignore_wlan_act = enable; | ||
856 | |||
857 | if (!force_exec) { | ||
858 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
859 | "[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n", | ||
860 | coex_dm->pre_ignore_wlan_act, | ||
861 | coex_dm->cur_ignore_wlan_act); | ||
862 | |||
863 | if (coex_dm->pre_ignore_wlan_act == | ||
864 | coex_dm->cur_ignore_wlan_act) | ||
865 | return; | ||
866 | } | ||
867 | halbtc8723b1ant_SetFwIgnoreWlanAct(btcoexist, enable); | ||
868 | |||
869 | coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; | ||
870 | } | ||
871 | |||
872 | static void halbtc8723b1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, | ||
873 | u8 byte1, u8 byte2, u8 byte3, | ||
874 | u8 byte4, u8 byte5) | ||
875 | { | ||
876 | u8 h2c_parameter[5] = {0}; | ||
877 | u8 real_byte1 = byte1, real_byte5 = byte5; | ||
878 | bool ap_enable = false; | ||
879 | |||
880 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, | ||
881 | &ap_enable); | ||
882 | |||
883 | if (ap_enable) { | ||
884 | if ((byte1 & BIT4) && !(byte1 & BIT5)) { | ||
885 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
886 | "[BTCoex], FW for 1Ant AP mode\n"); | ||
887 | real_byte1 &= ~BIT4; | ||
888 | real_byte1 |= BIT5; | ||
889 | |||
890 | real_byte5 |= BIT5; | ||
891 | real_byte5 &= ~BIT6; | ||
892 | } | ||
893 | } | ||
894 | |||
895 | h2c_parameter[0] = real_byte1; | ||
896 | h2c_parameter[1] = byte2; | ||
897 | h2c_parameter[2] = byte3; | ||
898 | h2c_parameter[3] = byte4; | ||
899 | h2c_parameter[4] = real_byte5; | ||
900 | |||
901 | coex_dm->ps_tdma_para[0] = real_byte1; | ||
902 | coex_dm->ps_tdma_para[1] = byte2; | ||
903 | coex_dm->ps_tdma_para[2] = byte3; | ||
904 | coex_dm->ps_tdma_para[3] = byte4; | ||
905 | coex_dm->ps_tdma_para[4] = real_byte5; | ||
906 | |||
907 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
908 | "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", | ||
909 | h2c_parameter[0], | ||
910 | h2c_parameter[1] << 24 | | ||
911 | h2c_parameter[2] << 16 | | ||
912 | h2c_parameter[3] << 8 | | ||
913 | h2c_parameter[4]); | ||
914 | |||
915 | btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); | ||
916 | } | ||
917 | |||
918 | static void halbtc8723b1ant_set_lps_rpwm(struct btc_coexist *btcoexist, | ||
919 | u8 lps_val, u8 rpwm_val) | ||
920 | { | ||
921 | u8 lps = lps_val; | ||
922 | u8 rpwm = rpwm_val; | ||
923 | |||
924 | btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); | ||
925 | btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); | ||
926 | } | ||
927 | |||
928 | static void halbtc8723b1ant_LpsRpwm(struct btc_coexist *btcoexist, | ||
929 | bool force_exec, | ||
930 | u8 lps_val, u8 rpwm_val) | ||
931 | { | ||
932 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
933 | "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n", | ||
934 | (force_exec ? "force to" : ""), lps_val, rpwm_val); | ||
935 | coex_dm->cur_lps = lps_val; | ||
936 | coex_dm->cur_rpwm = rpwm_val; | ||
937 | |||
938 | if (!force_exec) { | ||
939 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
940 | "[BTCoex], LPS-RxBeaconMode = 0x%x , LPS-RPWM = 0x%x!!\n", | ||
941 | coex_dm->cur_lps, coex_dm->cur_rpwm); | ||
942 | |||
943 | if ((coex_dm->pre_lps == coex_dm->cur_lps) && | ||
944 | (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) { | ||
945 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
946 | "[BTCoex], LPS-RPWM_Last = 0x%x , LPS-RPWM_Now = 0x%x!!\n", | ||
947 | coex_dm->pre_rpwm, coex_dm->cur_rpwm); | ||
948 | |||
949 | return; | ||
950 | } | ||
951 | } | ||
952 | halbtc8723b1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); | ||
953 | |||
954 | coex_dm->pre_lps = coex_dm->cur_lps; | ||
955 | coex_dm->pre_rpwm = coex_dm->cur_rpwm; | ||
956 | } | ||
957 | |||
958 | static void halbtc8723b1ant_sw_mechanism(struct btc_coexist *btcoexist, | ||
959 | bool low_penalty_ra) | ||
960 | { | ||
961 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
962 | "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra); | ||
963 | |||
964 | halbtc8723b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); | ||
965 | } | ||
966 | |||
967 | static void halbtc8723b1ant_SetAntPath(struct btc_coexist *btcoexist, | ||
968 | u8 ant_pos_type, bool init_hw_cfg, | ||
969 | bool wifi_off) | ||
970 | { | ||
971 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
972 | u32 fw_ver = 0, u32tmp = 0; | ||
973 | bool pg_ext_switch = false; | ||
974 | bool use_ext_switch = false; | ||
975 | u8 h2c_parameter[2] = {0}; | ||
976 | |||
977 | btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch); | ||
978 | /* [31:16] = fw ver, [15:0] = fw sub ver */ | ||
979 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
980 | |||
981 | if ((fw_ver < 0xc0000) || pg_ext_switch) | ||
982 | use_ext_switch = true; | ||
983 | |||
984 | if (init_hw_cfg) { | ||
985 | /*BT select s0/s1 is controlled by WiFi */ | ||
986 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); | ||
987 | |||
988 | /*Force GNT_BT to Normal */ | ||
989 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); | ||
990 | } else if (wifi_off) { | ||
991 | /*Force GNT_BT to High */ | ||
992 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3); | ||
993 | /*BT select s0/s1 is controlled by BT */ | ||
994 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0); | ||
995 | |||
996 | /* 0x4c[24:23] = 00, Set Antenna control by BT_RFE_CTRL | ||
997 | * BT Vendor 0xac = 0xf002 | ||
998 | */ | ||
999 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
1000 | u32tmp &= ~BIT23; | ||
1001 | u32tmp &= ~BIT24; | ||
1002 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); | ||
1003 | } | ||
1004 | |||
1005 | if (use_ext_switch) { | ||
1006 | if (init_hw_cfg) { | ||
1007 | /* 0x4c[23] = 0, 0x4c[24] = 1 | ||
1008 | * Antenna control by WL/BT | ||
1009 | */ | ||
1010 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
1011 | u32tmp &= ~BIT23; | ||
1012 | u32tmp |= BIT24; | ||
1013 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); | ||
1014 | |||
1015 | if (board_info->btdm_ant_pos == | ||
1016 | BTC_ANTENNA_AT_MAIN_PORT) { | ||
1017 | /* Main Ant to BT for IPS case 0x4c[23] = 1 */ | ||
1018 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1019 | 0x64, 0x1, | ||
1020 | 0x1); | ||
1021 | |||
1022 | /*tell firmware "no antenna inverse"*/ | ||
1023 | h2c_parameter[0] = 0; | ||
1024 | h2c_parameter[1] = 1; /*ext switch type*/ | ||
1025 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1026 | h2c_parameter); | ||
1027 | } else { | ||
1028 | /*Aux Ant to BT for IPS case 0x4c[23] = 1 */ | ||
1029 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1030 | 0x64, 0x1, | ||
1031 | 0x0); | ||
1032 | |||
1033 | /*tell firmware "antenna inverse"*/ | ||
1034 | h2c_parameter[0] = 1; | ||
1035 | h2c_parameter[1] = 1; /*ext switch type*/ | ||
1036 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1037 | h2c_parameter); | ||
1038 | } | ||
1039 | } | ||
1040 | |||
1041 | /* fixed internal switch first*/ | ||
1042 | /* fixed internal switch S1->WiFi, S0->BT*/ | ||
1043 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) | ||
1044 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); | ||
1045 | else/* fixed internal switch S0->WiFi, S1->BT*/ | ||
1046 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); | ||
1047 | |||
1048 | /* ext switch setting */ | ||
1049 | switch (ant_pos_type) { | ||
1050 | case BTC_ANT_PATH_WIFI: | ||
1051 | if (board_info->btdm_ant_pos == | ||
1052 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1053 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1054 | 0x92c, 0x3, | ||
1055 | 0x1); | ||
1056 | else | ||
1057 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1058 | 0x92c, 0x3, | ||
1059 | 0x2); | ||
1060 | break; | ||
1061 | case BTC_ANT_PATH_BT: | ||
1062 | if (board_info->btdm_ant_pos == | ||
1063 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1064 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1065 | 0x92c, 0x3, | ||
1066 | 0x2); | ||
1067 | else | ||
1068 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1069 | 0x92c, 0x3, | ||
1070 | 0x1); | ||
1071 | break; | ||
1072 | default: | ||
1073 | case BTC_ANT_PATH_PTA: | ||
1074 | if (board_info->btdm_ant_pos == | ||
1075 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1076 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1077 | 0x92c, 0x3, | ||
1078 | 0x1); | ||
1079 | else | ||
1080 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1081 | 0x92c, 0x3, | ||
1082 | 0x2); | ||
1083 | break; | ||
1084 | } | ||
1085 | |||
1086 | } else { | ||
1087 | if (init_hw_cfg) { | ||
1088 | /* 0x4c[23] = 1, 0x4c[24] = 0 Antenna control by 0x64*/ | ||
1089 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
1090 | u32tmp |= BIT23; | ||
1091 | u32tmp &= ~BIT24; | ||
1092 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); | ||
1093 | |||
1094 | if (board_info->btdm_ant_pos == | ||
1095 | BTC_ANTENNA_AT_MAIN_PORT) { | ||
1096 | /*Main Ant to WiFi for IPS case 0x4c[23] = 1*/ | ||
1097 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1098 | 0x64, 0x1, | ||
1099 | 0x0); | ||
1100 | |||
1101 | /*tell firmware "no antenna inverse"*/ | ||
1102 | h2c_parameter[0] = 0; | ||
1103 | h2c_parameter[1] = 0; /*internal switch type*/ | ||
1104 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1105 | h2c_parameter); | ||
1106 | } else { | ||
1107 | /*Aux Ant to BT for IPS case 0x4c[23] = 1*/ | ||
1108 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1109 | 0x64, 0x1, | ||
1110 | 0x1); | ||
1111 | |||
1112 | /*tell firmware "antenna inverse"*/ | ||
1113 | h2c_parameter[0] = 1; | ||
1114 | h2c_parameter[1] = 0; /*internal switch type*/ | ||
1115 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1116 | h2c_parameter); | ||
1117 | } | ||
1118 | } | ||
1119 | |||
1120 | /* fixed external switch first*/ | ||
1121 | /*Main->WiFi, Aux->BT*/ | ||
1122 | if (board_info->btdm_ant_pos == | ||
1123 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1124 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, | ||
1125 | 0x3, 0x1); | ||
1126 | else/*Main->BT, Aux->WiFi */ | ||
1127 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, | ||
1128 | 0x3, 0x2); | ||
1129 | |||
1130 | /* internal switch setting*/ | ||
1131 | switch (ant_pos_type) { | ||
1132 | case BTC_ANT_PATH_WIFI: | ||
1133 | if (board_info->btdm_ant_pos == | ||
1134 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1135 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1136 | 0x0); | ||
1137 | else | ||
1138 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1139 | 0x280); | ||
1140 | break; | ||
1141 | case BTC_ANT_PATH_BT: | ||
1142 | if (board_info->btdm_ant_pos == | ||
1143 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1144 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1145 | 0x280); | ||
1146 | else | ||
1147 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1148 | 0x0); | ||
1149 | break; | ||
1150 | default: | ||
1151 | case BTC_ANT_PATH_PTA: | ||
1152 | if (board_info->btdm_ant_pos == | ||
1153 | BTC_ANTENNA_AT_MAIN_PORT) | ||
1154 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1155 | 0x200); | ||
1156 | else | ||
1157 | btcoexist->btc_write_2byte(btcoexist, 0x948, | ||
1158 | 0x80); | ||
1159 | break; | ||
1160 | } | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist, | ||
1165 | bool force_exec, bool turn_on, u8 type) | ||
1166 | { | ||
1167 | bool wifi_busy = false; | ||
1168 | u8 rssi_adjust_val = 0; | ||
1169 | |||
1170 | coex_dm->cur_ps_tdma_on = turn_on; | ||
1171 | coex_dm->cur_ps_tdma = type; | ||
1172 | |||
1173 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1174 | |||
1175 | if (!force_exec) { | ||
1176 | if (coex_dm->cur_ps_tdma_on) | ||
1177 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1178 | "[BTCoex], ******** TDMA(on, %d) *********\n", | ||
1179 | coex_dm->cur_ps_tdma); | ||
1180 | else | ||
1181 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1182 | "[BTCoex], ******** TDMA(off, %d) ********\n", | ||
1183 | coex_dm->cur_ps_tdma); | ||
1184 | |||
1185 | if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && | ||
1186 | (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) | ||
1187 | return; | ||
1188 | } | ||
1189 | if (turn_on) { | ||
1190 | switch (type) { | ||
1191 | default: | ||
1192 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a, | ||
1193 | 0x1a, 0x0, 0x50); | ||
1194 | break; | ||
1195 | case 1: | ||
1196 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a, | ||
1197 | 0x03, 0x10, 0x50); | ||
1198 | |||
1199 | rssi_adjust_val = 11; | ||
1200 | break; | ||
1201 | case 2: | ||
1202 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b, | ||
1203 | 0x03, 0x10, 0x50); | ||
1204 | rssi_adjust_val = 14; | ||
1205 | break; | ||
1206 | case 3: | ||
1207 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d, | ||
1208 | 0x1d, 0x0, 0x52); | ||
1209 | break; | ||
1210 | case 4: | ||
1211 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, | ||
1212 | 0x3, 0x14, 0x0); | ||
1213 | rssi_adjust_val = 17; | ||
1214 | break; | ||
1215 | case 5: | ||
1216 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15, | ||
1217 | 0x3, 0x11, 0x10); | ||
1218 | break; | ||
1219 | case 6: | ||
1220 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20, | ||
1221 | 0x3, 0x11, 0x13); | ||
1222 | break; | ||
1223 | case 7: | ||
1224 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc, | ||
1225 | 0x5, 0x0, 0x0); | ||
1226 | break; | ||
1227 | case 8: | ||
1228 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, | ||
1229 | 0x3, 0x10, 0x0); | ||
1230 | break; | ||
1231 | case 9: | ||
1232 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21, | ||
1233 | 0x3, 0x10, 0x50); | ||
1234 | rssi_adjust_val = 18; | ||
1235 | break; | ||
1236 | case 10: | ||
1237 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, | ||
1238 | 0xa, 0x0, 0x40); | ||
1239 | break; | ||
1240 | case 11: | ||
1241 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15, | ||
1242 | 0x03, 0x10, 0x50); | ||
1243 | rssi_adjust_val = 20; | ||
1244 | break; | ||
1245 | case 12: | ||
1246 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a, | ||
1247 | 0x0a, 0x0, 0x50); | ||
1248 | break; | ||
1249 | case 13: | ||
1250 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15, | ||
1251 | 0x15, 0x0, 0x50); | ||
1252 | break; | ||
1253 | case 14: | ||
1254 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21, | ||
1255 | 0x3, 0x10, 0x52); | ||
1256 | break; | ||
1257 | case 15: | ||
1258 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa, | ||
1259 | 0x3, 0x8, 0x0); | ||
1260 | break; | ||
1261 | case 16: | ||
1262 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15, | ||
1263 | 0x3, 0x10, 0x0); | ||
1264 | rssi_adjust_val = 18; | ||
1265 | break; | ||
1266 | case 18: | ||
1267 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25, | ||
1268 | 0x3, 0x10, 0x0); | ||
1269 | rssi_adjust_val = 14; | ||
1270 | break; | ||
1271 | case 20: | ||
1272 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35, | ||
1273 | 0x03, 0x11, 0x10); | ||
1274 | break; | ||
1275 | case 21: | ||
1276 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, | ||
1277 | 0x03, 0x11, 0x11); | ||
1278 | break; | ||
1279 | case 22: | ||
1280 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25, | ||
1281 | 0x03, 0x11, 0x10); | ||
1282 | break; | ||
1283 | case 23: | ||
1284 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, | ||
1285 | 0x3, 0x31, 0x18); | ||
1286 | rssi_adjust_val = 22; | ||
1287 | break; | ||
1288 | case 24: | ||
1289 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15, | ||
1290 | 0x3, 0x31, 0x18); | ||
1291 | rssi_adjust_val = 22; | ||
1292 | break; | ||
1293 | case 25: | ||
1294 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, | ||
1295 | 0x3, 0x31, 0x18); | ||
1296 | rssi_adjust_val = 22; | ||
1297 | break; | ||
1298 | case 26: | ||
1299 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa, | ||
1300 | 0x3, 0x31, 0x18); | ||
1301 | rssi_adjust_val = 22; | ||
1302 | break; | ||
1303 | case 27: | ||
1304 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25, | ||
1305 | 0x3, 0x31, 0x98); | ||
1306 | rssi_adjust_val = 22; | ||
1307 | break; | ||
1308 | case 28: | ||
1309 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25, | ||
1310 | 0x3, 0x31, 0x0); | ||
1311 | break; | ||
1312 | case 29: | ||
1313 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a, | ||
1314 | 0x1a, 0x1, 0x10); | ||
1315 | break; | ||
1316 | case 30: | ||
1317 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14, | ||
1318 | 0x3, 0x10, 0x50); | ||
1319 | break; | ||
1320 | case 31: | ||
1321 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a, | ||
1322 | 0x1a, 0, 0x58); | ||
1323 | break; | ||
1324 | case 32: | ||
1325 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0xa, | ||
1326 | 0x3, 0x10, 0x0); | ||
1327 | break; | ||
1328 | case 33: | ||
1329 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25, | ||
1330 | 0x3, 0x30, 0x90); | ||
1331 | break; | ||
1332 | case 34: | ||
1333 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a, | ||
1334 | 0x1a, 0x0, 0x10); | ||
1335 | break; | ||
1336 | case 35: | ||
1337 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a, | ||
1338 | 0x1a, 0x0, 0x10); | ||
1339 | break; | ||
1340 | case 36: | ||
1341 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12, | ||
1342 | 0x3, 0x14, 0x50); | ||
1343 | break; | ||
1344 | /* SoftAP only with no sta associated,BT disable , | ||
1345 | * TDMA mode for power saving | ||
1346 | * here softap mode screen off will cost 70-80mA for phone | ||
1347 | */ | ||
1348 | case 40: | ||
1349 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18, | ||
1350 | 0x00, 0x10, 0x24); | ||
1351 | break; | ||
1352 | } | ||
1353 | } else { | ||
1354 | switch (type) { | ||
1355 | case 8: /*PTA Control */ | ||
1356 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, | ||
1357 | 0x0, 0x0, 0x0); | ||
1358 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA, | ||
1359 | false, false); | ||
1360 | break; | ||
1361 | case 0: | ||
1362 | default: /*Software control, Antenna at BT side */ | ||
1363 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, | ||
1364 | 0x0, 0x0, 0x0); | ||
1365 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, | ||
1366 | false, false); | ||
1367 | break; | ||
1368 | case 9: /*Software control, Antenna at WiFi side */ | ||
1369 | halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, | ||
1370 | 0x0, 0x0, 0x0); | ||
1371 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_WIFI, | ||
1372 | false, false); | ||
1373 | break; | ||
1374 | } | ||
1375 | } | ||
1376 | rssi_adjust_val = 0; | ||
1377 | btcoexist->btc_set(btcoexist, | ||
1378 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, | ||
1379 | &rssi_adjust_val); | ||
1380 | |||
1381 | /* update pre state */ | ||
1382 | coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; | ||
1383 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; | ||
1384 | } | ||
1385 | |||
1386 | static bool halbtc8723b1ant_is_common_action(struct btc_coexist *btcoexist) | ||
1387 | { | ||
1388 | bool commom = false, wifi_connected = false; | ||
1389 | bool wifi_busy = false; | ||
1390 | |||
1391 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1392 | &wifi_connected); | ||
1393 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1394 | |||
1395 | if (!wifi_connected && | ||
1396 | BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) { | ||
1397 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1398 | "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n"); | ||
1399 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1400 | commom = true; | ||
1401 | } else if (wifi_connected && | ||
1402 | (BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
1403 | coex_dm->bt_status)) { | ||
1404 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1405 | "[BTCoex], Wifi connected + BT non connected-idle!!\n"); | ||
1406 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1407 | commom = true; | ||
1408 | } else if (!wifi_connected && | ||
1409 | (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
1410 | coex_dm->bt_status)) { | ||
1411 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1412 | "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n"); | ||
1413 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1414 | commom = true; | ||
1415 | } else if (wifi_connected && | ||
1416 | (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
1417 | coex_dm->bt_status)) { | ||
1418 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1419 | "[BTCoex], Wifi connected + BT connected-idle!!\n"); | ||
1420 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1421 | commom = true; | ||
1422 | } else if (!wifi_connected && | ||
1423 | (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE != | ||
1424 | coex_dm->bt_status)) { | ||
1425 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1426 | ("[BTCoex], Wifi non connected-idle + BT Busy!!\n")); | ||
1427 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1428 | commom = true; | ||
1429 | } else { | ||
1430 | if (wifi_busy) | ||
1431 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1432 | "[BTCoex], Wifi Connected-Busy + BT Busy!!\n"); | ||
1433 | else | ||
1434 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1435 | "[BTCoex], Wifi Connected-Idle + BT Busy!!\n"); | ||
1436 | |||
1437 | commom = false; | ||
1438 | } | ||
1439 | |||
1440 | return commom; | ||
1441 | } | ||
1442 | |||
1443 | static void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist, | ||
1444 | u8 wifi_status) | ||
1445 | { | ||
1446 | static s32 up, dn, m, n, wait_count; | ||
1447 | /* 0: no change, +1: increase WiFi duration, | ||
1448 | * -1: decrease WiFi duration | ||
1449 | */ | ||
1450 | s32 result; | ||
1451 | u8 retry_count = 0, bt_info_ext; | ||
1452 | bool wifi_busy = false; | ||
1453 | |||
1454 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1455 | "[BTCoex], TdmaDurationAdjustForAcl()\n"); | ||
1456 | |||
1457 | if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifi_status) | ||
1458 | wifi_busy = true; | ||
1459 | else | ||
1460 | wifi_busy = false; | ||
1461 | |||
1462 | if ((BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == | ||
1463 | wifi_status) || | ||
1464 | (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifi_status) || | ||
1465 | (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifi_status)) { | ||
1466 | if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && | ||
1467 | coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) { | ||
1468 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1469 | true, 9); | ||
1470 | coex_dm->tdma_adj_type = 9; | ||
1471 | |||
1472 | up = 0; | ||
1473 | dn = 0; | ||
1474 | m = 1; | ||
1475 | n = 3; | ||
1476 | result = 0; | ||
1477 | wait_count = 0; | ||
1478 | } | ||
1479 | return; | ||
1480 | } | ||
1481 | |||
1482 | if (!coex_dm->auto_tdma_adjust) { | ||
1483 | coex_dm->auto_tdma_adjust = true; | ||
1484 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1485 | "[BTCoex], first run TdmaDurationAdjust()!!\n"); | ||
1486 | |||
1487 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); | ||
1488 | coex_dm->tdma_adj_type = 2; | ||
1489 | |||
1490 | up = 0; | ||
1491 | dn = 0; | ||
1492 | m = 1; | ||
1493 | n = 3; | ||
1494 | result = 0; | ||
1495 | wait_count = 0; | ||
1496 | } else { | ||
1497 | /*accquire the BT TRx retry count from BT_Info byte2 */ | ||
1498 | retry_count = coex_sta->bt_retry_cnt; | ||
1499 | bt_info_ext = coex_sta->bt_info_ext; | ||
1500 | result = 0; | ||
1501 | wait_count++; | ||
1502 | /* no retry in the last 2-second duration */ | ||
1503 | if (retry_count == 0) { | ||
1504 | up++; | ||
1505 | dn--; | ||
1506 | |||
1507 | if (dn <= 0) | ||
1508 | dn = 0; | ||
1509 | |||
1510 | if (up >= n) { | ||
1511 | wait_count = 0; | ||
1512 | n = 3; | ||
1513 | up = 0; | ||
1514 | dn = 0; | ||
1515 | result = 1; | ||
1516 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1517 | ALGO_TRACE_FW_DETAIL, | ||
1518 | "[BTCoex], Increase wifi duration!!\n"); | ||
1519 | } | ||
1520 | } else if (retry_count <= 3) { | ||
1521 | up--; | ||
1522 | dn++; | ||
1523 | |||
1524 | if (up <= 0) | ||
1525 | up = 0; | ||
1526 | |||
1527 | if (dn == 2) { | ||
1528 | if (wait_count <= 2) | ||
1529 | m++; | ||
1530 | else | ||
1531 | m = 1; | ||
1532 | |||
1533 | if (m >= 20) | ||
1534 | m = 20; | ||
1535 | |||
1536 | n = 3 * m; | ||
1537 | up = 0; | ||
1538 | dn = 0; | ||
1539 | wait_count = 0; | ||
1540 | result = -1; | ||
1541 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1542 | ALGO_TRACE_FW_DETAIL, | ||
1543 | "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); | ||
1544 | } | ||
1545 | } else { | ||
1546 | if (wait_count == 1) | ||
1547 | m++; | ||
1548 | else | ||
1549 | m = 1; | ||
1550 | |||
1551 | if (m >= 20) | ||
1552 | m = 20; | ||
1553 | |||
1554 | n = 3 * m; | ||
1555 | up = 0; | ||
1556 | dn = 0; | ||
1557 | wait_count = 0; | ||
1558 | result = -1; | ||
1559 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1560 | "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); | ||
1561 | } | ||
1562 | |||
1563 | if (result == -1) { | ||
1564 | if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && | ||
1565 | ((coex_dm->cur_ps_tdma == 1) || | ||
1566 | (coex_dm->cur_ps_tdma == 2))) { | ||
1567 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1568 | true, 9); | ||
1569 | coex_dm->tdma_adj_type = 9; | ||
1570 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1571 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1572 | true, 2); | ||
1573 | coex_dm->tdma_adj_type = 2; | ||
1574 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1575 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1576 | true, 9); | ||
1577 | coex_dm->tdma_adj_type = 9; | ||
1578 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1579 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1580 | true, 11); | ||
1581 | coex_dm->tdma_adj_type = 11; | ||
1582 | } | ||
1583 | } else if (result == 1) { | ||
1584 | if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && | ||
1585 | ((coex_dm->cur_ps_tdma == 1) || | ||
1586 | (coex_dm->cur_ps_tdma == 2))) { | ||
1587 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1588 | true, 9); | ||
1589 | coex_dm->tdma_adj_type = 9; | ||
1590 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1591 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1592 | true, 9); | ||
1593 | coex_dm->tdma_adj_type = 9; | ||
1594 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1595 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1596 | true, 2); | ||
1597 | coex_dm->tdma_adj_type = 2; | ||
1598 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1599 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1600 | true, 1); | ||
1601 | coex_dm->tdma_adj_type = 1; | ||
1602 | } | ||
1603 | } else { /*no change */ | ||
1604 | /*if busy / idle change */ | ||
1605 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1606 | "[BTCoex],********* TDMA(on, %d) ********\n", | ||
1607 | coex_dm->cur_ps_tdma); | ||
1608 | } | ||
1609 | |||
1610 | if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 && | ||
1611 | coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) { | ||
1612 | /* recover to previous adjust type */ | ||
1613 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, | ||
1614 | coex_dm->tdma_adj_type); | ||
1615 | } | ||
1616 | } | ||
1617 | } | ||
1618 | |||
1619 | static void btc8723b1ant_pstdmachkpwrsave(struct btc_coexist *btcoexist, | ||
1620 | bool new_ps_state) | ||
1621 | { | ||
1622 | u8 lps_mode = 0x0; | ||
1623 | |||
1624 | btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode); | ||
1625 | |||
1626 | if (lps_mode) { /* already under LPS state */ | ||
1627 | if (new_ps_state) { | ||
1628 | /* keep state under LPS, do nothing. */ | ||
1629 | } else { | ||
1630 | /* will leave LPS state, turn off psTdma first */ | ||
1631 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1632 | false, 0); | ||
1633 | } | ||
1634 | } else { /* NO PS state */ | ||
1635 | if (new_ps_state) { | ||
1636 | /* will enter LPS state, turn off psTdma first */ | ||
1637 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1638 | false, 0); | ||
1639 | } else { | ||
1640 | /* keep state under NO PS state, do nothing. */ | ||
1641 | } | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist, | ||
1646 | u8 ps_type, u8 lps_val, | ||
1647 | u8 rpwm_val) | ||
1648 | { | ||
1649 | bool low_pwr_disable = false; | ||
1650 | |||
1651 | switch (ps_type) { | ||
1652 | case BTC_PS_WIFI_NATIVE: | ||
1653 | /* recover to original 32k low power setting */ | ||
1654 | low_pwr_disable = false; | ||
1655 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1656 | &low_pwr_disable); | ||
1657 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); | ||
1658 | break; | ||
1659 | case BTC_PS_LPS_ON: | ||
1660 | btc8723b1ant_pstdmachkpwrsave(btcoexist, true); | ||
1661 | halbtc8723b1ant_LpsRpwm(btcoexist, NORMAL_EXEC, lps_val, | ||
1662 | rpwm_val); | ||
1663 | /* when coex force to enter LPS, do not enter 32k low power. */ | ||
1664 | low_pwr_disable = true; | ||
1665 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1666 | &low_pwr_disable); | ||
1667 | /* power save must executed before psTdma. */ | ||
1668 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); | ||
1669 | break; | ||
1670 | case BTC_PS_LPS_OFF: | ||
1671 | btc8723b1ant_pstdmachkpwrsave(btcoexist, false); | ||
1672 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); | ||
1673 | break; | ||
1674 | default: | ||
1675 | break; | ||
1676 | } | ||
1677 | } | ||
1678 | |||
1679 | /*************************************************** | ||
1680 | * | ||
1681 | * Software Coex Mechanism start | ||
1682 | * | ||
1683 | ***************************************************/ | ||
1684 | /* SCO only or SCO+PAN(HS) */ | ||
1685 | static void halbtc8723b1ant_action_sco(struct btc_coexist *btcoexist) | ||
1686 | { | ||
1687 | halbtc8723b1ant_sw_mechanism(btcoexist, true); | ||
1688 | } | ||
1689 | |||
1690 | static void halbtc8723b1ant_action_hid(struct btc_coexist *btcoexist) | ||
1691 | { | ||
1692 | halbtc8723b1ant_sw_mechanism(btcoexist, true); | ||
1693 | } | ||
1694 | |||
1695 | /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ | ||
1696 | static void halbtc8723b1ant_action_a2dp(struct btc_coexist *btcoexist) | ||
1697 | { | ||
1698 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1699 | } | ||
1700 | |||
1701 | static void halbtc8723b1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) | ||
1702 | { | ||
1703 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1704 | } | ||
1705 | |||
1706 | static void halbtc8723b1ant_action_pan_edr(struct btc_coexist *btcoexist) | ||
1707 | { | ||
1708 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1709 | } | ||
1710 | |||
1711 | /* PAN(HS) only */ | ||
1712 | static void halbtc8723b1ant_action_pan_hs(struct btc_coexist *btcoexist) | ||
1713 | { | ||
1714 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1715 | } | ||
1716 | |||
1717 | /*PAN(EDR)+A2DP */ | ||
1718 | static void halbtc8723b1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) | ||
1719 | { | ||
1720 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
1721 | } | ||
1722 | |||
1723 | static void halbtc8723b1ant_action_pan_edr_hid(struct btc_coexist *btcoexist) | ||
1724 | { | ||
1725 | halbtc8723b1ant_sw_mechanism(btcoexist, true); | ||
1726 | } | ||
1727 | |||
1728 | /* HID+A2DP+PAN(EDR) */ | ||
1729 | static void btc8723b1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) | ||
1730 | { | ||
1731 | halbtc8723b1ant_sw_mechanism(btcoexist, true); | ||
1732 | } | ||
1733 | |||
1734 | static void halbtc8723b1ant_action_hid_a2dp(struct btc_coexist *btcoexist) | ||
1735 | { | ||
1736 | halbtc8723b1ant_sw_mechanism(btcoexist, true); | ||
1737 | } | ||
1738 | |||
1739 | /***************************************************** | ||
1740 | * | ||
1741 | * Non-Software Coex Mechanism start | ||
1742 | * | ||
1743 | *****************************************************/ | ||
1744 | static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist) | ||
1745 | { | ||
1746 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1747 | 0x0, 0x0); | ||
1748 | |||
1749 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
1750 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
1751 | } | ||
1752 | |||
1753 | static void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist) | ||
1754 | { | ||
1755 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
1756 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
1757 | } | ||
1758 | |||
1759 | static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist) | ||
1760 | { | ||
1761 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1762 | bool wifi_connected = false, ap_enable = false; | ||
1763 | |||
1764 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, | ||
1765 | &ap_enable); | ||
1766 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1767 | &wifi_connected); | ||
1768 | |||
1769 | if (!wifi_connected) { | ||
1770 | halbtc8723b1ant_power_save_state(btcoexist, | ||
1771 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1772 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
1773 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
1774 | } else if (bt_link_info->sco_exist || bt_link_info->hid_only) { | ||
1775 | /* SCO/HID-only busy */ | ||
1776 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1777 | 0x0, 0x0); | ||
1778 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); | ||
1779 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1780 | } else { | ||
1781 | if (ap_enable) | ||
1782 | halbtc8723b1ant_power_save_state(btcoexist, | ||
1783 | BTC_PS_WIFI_NATIVE, | ||
1784 | 0x0, 0x0); | ||
1785 | else | ||
1786 | halbtc8723b1ant_power_save_state(btcoexist, | ||
1787 | BTC_PS_LPS_ON, | ||
1788 | 0x50, 0x4); | ||
1789 | |||
1790 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30); | ||
1791 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1792 | } | ||
1793 | } | ||
1794 | |||
1795 | static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, | ||
1796 | u8 wifi_status) | ||
1797 | { | ||
1798 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1799 | bool wifi_connected = false; | ||
1800 | |||
1801 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1802 | &wifi_connected); | ||
1803 | |||
1804 | /* tdma and coex table */ | ||
1805 | |||
1806 | if (bt_link_info->sco_exist) { | ||
1807 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
1808 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
1809 | } else { /* HID */ | ||
1810 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6); | ||
1811 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5); | ||
1812 | } | ||
1813 | } | ||
1814 | |||
1815 | static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy( | ||
1816 | struct btc_coexist *btcoexist, | ||
1817 | u8 wifi_status) | ||
1818 | { | ||
1819 | u8 bt_rssi_state; | ||
1820 | |||
1821 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1822 | |||
1823 | bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 28, 0); | ||
1824 | |||
1825 | if (bt_link_info->hid_only) { /*HID */ | ||
1826 | btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status); | ||
1827 | coex_dm->auto_tdma_adjust = false; | ||
1828 | return; | ||
1829 | } else if (bt_link_info->a2dp_only) { /*A2DP */ | ||
1830 | if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifi_status) { | ||
1831 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1832 | false, 8); | ||
1833 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1834 | NORMAL_EXEC, 2); | ||
1835 | coex_dm->auto_tdma_adjust = false; | ||
1836 | } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
1837 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
1838 | btc8723b1ant_tdma_dur_adj_for_acl(btcoexist, | ||
1839 | wifi_status); | ||
1840 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1841 | NORMAL_EXEC, 1); | ||
1842 | } else { /*for low BT RSSI */ | ||
1843 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1844 | true, 11); | ||
1845 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1846 | NORMAL_EXEC, 1); | ||
1847 | coex_dm->auto_tdma_adjust = false; | ||
1848 | } | ||
1849 | } else if (bt_link_info->hid_exist && | ||
1850 | bt_link_info->a2dp_exist) { /*HID+A2DP */ | ||
1851 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
1852 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
1853 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1854 | true, 14); | ||
1855 | coex_dm->auto_tdma_adjust = false; | ||
1856 | } else { /*for low BT RSSI*/ | ||
1857 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1858 | true, 14); | ||
1859 | coex_dm->auto_tdma_adjust = false; | ||
1860 | } | ||
1861 | |||
1862 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6); | ||
1863 | /*PAN(OPP,FTP), HID+PAN(OPP,FTP) */ | ||
1864 | } else if (bt_link_info->pan_only || | ||
1865 | (bt_link_info->hid_exist && bt_link_info->pan_exist)) { | ||
1866 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | ||
1867 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6); | ||
1868 | coex_dm->auto_tdma_adjust = false; | ||
1869 | /*A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP)*/ | ||
1870 | } else if ((bt_link_info->a2dp_exist && bt_link_info->pan_exist) || | ||
1871 | (bt_link_info->hid_exist && bt_link_info->a2dp_exist && | ||
1872 | bt_link_info->pan_exist)) { | ||
1873 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); | ||
1874 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1875 | coex_dm->auto_tdma_adjust = false; | ||
1876 | } else { | ||
1877 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); | ||
1878 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1879 | coex_dm->auto_tdma_adjust = false; | ||
1880 | } | ||
1881 | } | ||
1882 | |||
1883 | static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist) | ||
1884 | { | ||
1885 | /* power save state */ | ||
1886 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1887 | 0x0, 0x0); | ||
1888 | |||
1889 | /* tdma and coex table */ | ||
1890 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
1891 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); | ||
1892 | } | ||
1893 | |||
1894 | static void btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoex) | ||
1895 | { | ||
1896 | struct btc_bt_link_info *bt_link_info = &btcoex->bt_link_info; | ||
1897 | |||
1898 | halbtc8723b1ant_power_save_state(btcoex, BTC_PS_WIFI_NATIVE, | ||
1899 | 0x0, 0x0); | ||
1900 | |||
1901 | /* tdma and coex table */ | ||
1902 | if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1903 | if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) { | ||
1904 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, | ||
1905 | true, 22); | ||
1906 | halbtc8723b1ant_coex_table_with_type(btcoex, | ||
1907 | NORMAL_EXEC, 1); | ||
1908 | } else if (bt_link_info->pan_only) { | ||
1909 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, | ||
1910 | true, 20); | ||
1911 | halbtc8723b1ant_coex_table_with_type(btcoex, | ||
1912 | NORMAL_EXEC, 2); | ||
1913 | } else { | ||
1914 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, | ||
1915 | true, 20); | ||
1916 | halbtc8723b1ant_coex_table_with_type(btcoex, | ||
1917 | NORMAL_EXEC, 1); | ||
1918 | } | ||
1919 | } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
1920 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
1921 | coex_dm->bt_status)){ | ||
1922 | btc8723b1ant_act_bt_sco_hid_only_busy(btcoex, | ||
1923 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); | ||
1924 | } else { | ||
1925 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 8); | ||
1926 | halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 2); | ||
1927 | } | ||
1928 | } | ||
1929 | |||
1930 | static void btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoex) | ||
1931 | { | ||
1932 | struct btc_bt_link_info *bt_link_info = &btcoex->bt_link_info; | ||
1933 | |||
1934 | halbtc8723b1ant_power_save_state(btcoex, BTC_PS_WIFI_NATIVE, | ||
1935 | 0x0, 0x0); | ||
1936 | |||
1937 | if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) || | ||
1938 | (bt_link_info->sco_exist) || (bt_link_info->hid_only) || | ||
1939 | (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) { | ||
1940 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 8); | ||
1941 | halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 7); | ||
1942 | } else { | ||
1943 | halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, true, 20); | ||
1944 | halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 1); | ||
1945 | } | ||
1946 | } | ||
1947 | |||
1948 | static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist) | ||
1949 | { | ||
1950 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1951 | |||
1952 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1953 | 0x0, 0x0); | ||
1954 | |||
1955 | /* tdma and coex table */ | ||
1956 | if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1957 | if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) { | ||
1958 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1959 | true, 22); | ||
1960 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1961 | NORMAL_EXEC, 1); | ||
1962 | } else if (bt_link_info->pan_only) { | ||
1963 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1964 | true, 20); | ||
1965 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1966 | NORMAL_EXEC, 2); | ||
1967 | } else { | ||
1968 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1969 | true, 20); | ||
1970 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
1971 | NORMAL_EXEC, 1); | ||
1972 | } | ||
1973 | } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
1974 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
1975 | coex_dm->bt_status)) { | ||
1976 | btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
1977 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN); | ||
1978 | } else { | ||
1979 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
1980 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
1981 | } | ||
1982 | } | ||
1983 | |||
1984 | static void halbtc8723b1ant_action_wifi_connected_special_packet( | ||
1985 | struct btc_coexist *btcoexist) | ||
1986 | { | ||
1987 | bool hs_connecting = false; | ||
1988 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1989 | |||
1990 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting); | ||
1991 | |||
1992 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1993 | 0x0, 0x0); | ||
1994 | |||
1995 | /* tdma and coex table */ | ||
1996 | if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) || | ||
1997 | (bt_link_info->sco_exist) || (bt_link_info->hid_only) || | ||
1998 | (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) { | ||
1999 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
2000 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7); | ||
2001 | } else { | ||
2002 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); | ||
2003 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
2004 | } | ||
2005 | } | ||
2006 | |||
2007 | static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist) | ||
2008 | { | ||
2009 | bool wifi_busy = false; | ||
2010 | bool scan = false, link = false, roam = false; | ||
2011 | bool under_4way = false, ap_enable = false; | ||
2012 | |||
2013 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2014 | "[BTCoex], CoexForWifiConnect()===>\n"); | ||
2015 | |||
2016 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, | ||
2017 | &under_4way); | ||
2018 | if (under_4way) { | ||
2019 | halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); | ||
2020 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2021 | "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); | ||
2022 | return; | ||
2023 | } | ||
2024 | |||
2025 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2026 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2027 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2028 | |||
2029 | if (scan || link || roam) { | ||
2030 | if (scan) | ||
2031 | btc8723b1ant_action_wifi_conn_scan(btcoexist); | ||
2032 | else | ||
2033 | halbtc8723b1ant_action_wifi_connected_special_packet( | ||
2034 | btcoexist); | ||
2035 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2036 | "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); | ||
2037 | return; | ||
2038 | } | ||
2039 | |||
2040 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, | ||
2041 | &ap_enable); | ||
2042 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
2043 | /* power save state */ | ||
2044 | if (!ap_enable && | ||
2045 | BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status && | ||
2046 | !btcoexist->bt_link_info.hid_only) { | ||
2047 | if (!wifi_busy && btcoexist->bt_link_info.a2dp_only) | ||
2048 | halbtc8723b1ant_power_save_state(btcoexist, | ||
2049 | BTC_PS_WIFI_NATIVE, | ||
2050 | 0x0, 0x0); | ||
2051 | else | ||
2052 | halbtc8723b1ant_power_save_state(btcoexist, | ||
2053 | BTC_PS_LPS_ON, | ||
2054 | 0x50, 0x4); | ||
2055 | } else { | ||
2056 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
2057 | 0x0, 0x0); | ||
2058 | } | ||
2059 | /* tdma and coex table */ | ||
2060 | if (!wifi_busy) { | ||
2061 | if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
2062 | halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist, | ||
2063 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); | ||
2064 | } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == | ||
2065 | coex_dm->bt_status) || | ||
2066 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
2067 | coex_dm->bt_status)) { | ||
2068 | btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
2069 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE); | ||
2070 | } else { | ||
2071 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2072 | false, 8); | ||
2073 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
2074 | NORMAL_EXEC, 2); | ||
2075 | } | ||
2076 | } else { | ||
2077 | if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
2078 | halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist, | ||
2079 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); | ||
2080 | } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == | ||
2081 | coex_dm->bt_status) || | ||
2082 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
2083 | coex_dm->bt_status)) { | ||
2084 | btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
2085 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY); | ||
2086 | } else { | ||
2087 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2088 | false, 8); | ||
2089 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
2090 | NORMAL_EXEC, 2); | ||
2091 | } | ||
2092 | } | ||
2093 | } | ||
2094 | |||
2095 | static void btc8723b1ant_run_sw_coex_mech(struct btc_coexist *btcoexist) | ||
2096 | { | ||
2097 | u8 algorithm = 0; | ||
2098 | |||
2099 | algorithm = halbtc8723b1ant_action_algorithm(btcoexist); | ||
2100 | coex_dm->cur_algorithm = algorithm; | ||
2101 | |||
2102 | if (!halbtc8723b1ant_is_common_action(btcoexist)) { | ||
2103 | switch (coex_dm->cur_algorithm) { | ||
2104 | case BT_8723B_1ANT_COEX_ALGO_SCO: | ||
2105 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2106 | "[BTCoex], Action algorithm = SCO.\n"); | ||
2107 | halbtc8723b1ant_action_sco(btcoexist); | ||
2108 | break; | ||
2109 | case BT_8723B_1ANT_COEX_ALGO_HID: | ||
2110 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2111 | "[BTCoex], Action algorithm = HID.\n"); | ||
2112 | halbtc8723b1ant_action_hid(btcoexist); | ||
2113 | break; | ||
2114 | case BT_8723B_1ANT_COEX_ALGO_A2DP: | ||
2115 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2116 | "[BTCoex], Action algorithm = A2DP.\n"); | ||
2117 | halbtc8723b1ant_action_a2dp(btcoexist); | ||
2118 | break; | ||
2119 | case BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS: | ||
2120 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2121 | "[BTCoex], Action algorithm = A2DP+PAN(HS).\n"); | ||
2122 | halbtc8723b1ant_action_a2dp_pan_hs(btcoexist); | ||
2123 | break; | ||
2124 | case BT_8723B_1ANT_COEX_ALGO_PANEDR: | ||
2125 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2126 | "[BTCoex], Action algorithm = PAN(EDR).\n"); | ||
2127 | halbtc8723b1ant_action_pan_edr(btcoexist); | ||
2128 | break; | ||
2129 | case BT_8723B_1ANT_COEX_ALGO_PANHS: | ||
2130 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2131 | "[BTCoex], Action algorithm = HS mode.\n"); | ||
2132 | halbtc8723b1ant_action_pan_hs(btcoexist); | ||
2133 | break; | ||
2134 | case BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP: | ||
2135 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2136 | "[BTCoex], Action algorithm = PAN+A2DP.\n"); | ||
2137 | halbtc8723b1ant_action_pan_edr_a2dp(btcoexist); | ||
2138 | break; | ||
2139 | case BT_8723B_1ANT_COEX_ALGO_PANEDR_HID: | ||
2140 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2141 | "[BTCoex], Action algorithm = PAN(EDR)+HID.\n"); | ||
2142 | halbtc8723b1ant_action_pan_edr_hid(btcoexist); | ||
2143 | break; | ||
2144 | case BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
2145 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2146 | "[BTCoex], Action algorithm = HID+A2DP+PAN.\n"); | ||
2147 | btc8723b1ant_action_hid_a2dp_pan_edr(btcoexist); | ||
2148 | break; | ||
2149 | case BT_8723B_1ANT_COEX_ALGO_HID_A2DP: | ||
2150 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2151 | "[BTCoex], Action algorithm = HID+A2DP.\n"); | ||
2152 | halbtc8723b1ant_action_hid_a2dp(btcoexist); | ||
2153 | break; | ||
2154 | default: | ||
2155 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2156 | "[BTCoex], Action algorithm = coexist All Off!!\n"); | ||
2157 | break; | ||
2158 | } | ||
2159 | coex_dm->pre_algorithm = coex_dm->cur_algorithm; | ||
2160 | } | ||
2161 | } | ||
2162 | |||
2163 | static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | ||
2164 | { | ||
2165 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
2166 | bool wifi_connected = false, bt_hs_on = false; | ||
2167 | bool increase_scan_dev_num = false; | ||
2168 | bool bt_ctrl_agg_buf_size = false; | ||
2169 | u8 agg_buf_size = 5; | ||
2170 | u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
2171 | u32 wifi_link_status = 0; | ||
2172 | u32 num_of_wifi_link = 0; | ||
2173 | |||
2174 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2175 | "[BTCoex], RunCoexistMechanism()===>\n"); | ||
2176 | |||
2177 | if (btcoexist->manual_control) { | ||
2178 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2179 | "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); | ||
2180 | return; | ||
2181 | } | ||
2182 | |||
2183 | if (btcoexist->stop_coex_dm) { | ||
2184 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2185 | "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); | ||
2186 | return; | ||
2187 | } | ||
2188 | |||
2189 | if (coex_sta->under_ips) { | ||
2190 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2191 | "[BTCoex], wifi is under IPS !!!\n"); | ||
2192 | return; | ||
2193 | } | ||
2194 | |||
2195 | if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || | ||
2196 | (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
2197 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) { | ||
2198 | increase_scan_dev_num = true; | ||
2199 | } | ||
2200 | |||
2201 | btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, | ||
2202 | &increase_scan_dev_num); | ||
2203 | |||
2204 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
2205 | &wifi_connected); | ||
2206 | |||
2207 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, | ||
2208 | &wifi_link_status); | ||
2209 | num_of_wifi_link = wifi_link_status >> 16; | ||
2210 | if (num_of_wifi_link >= 2) { | ||
2211 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2212 | halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2213 | bt_ctrl_agg_buf_size, | ||
2214 | agg_buf_size); | ||
2215 | halbtc8723b1ant_action_wifi_multiport(btcoexist); | ||
2216 | return; | ||
2217 | } | ||
2218 | |||
2219 | if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) { | ||
2220 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2221 | } else { | ||
2222 | if (wifi_connected) { | ||
2223 | wifi_rssi_state = | ||
2224 | halbtc8723b1ant_wifi_rssi_state(btcoexist, | ||
2225 | 1, 2, 30, 0); | ||
2226 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2227 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2228 | halbtc8723b1ant_limited_tx(btcoexist, | ||
2229 | NORMAL_EXEC, | ||
2230 | 1, 1, 1, 1); | ||
2231 | } else { | ||
2232 | halbtc8723b1ant_limited_tx(btcoexist, | ||
2233 | NORMAL_EXEC, | ||
2234 | 1, 1, 1, 1); | ||
2235 | } | ||
2236 | } else { | ||
2237 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, | ||
2238 | 0, 0, 0, 0); | ||
2239 | } | ||
2240 | } | ||
2241 | |||
2242 | if (bt_link_info->sco_exist) { | ||
2243 | bt_ctrl_agg_buf_size = true; | ||
2244 | agg_buf_size = 0x3; | ||
2245 | } else if (bt_link_info->hid_exist) { | ||
2246 | bt_ctrl_agg_buf_size = true; | ||
2247 | agg_buf_size = 0x5; | ||
2248 | } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) { | ||
2249 | bt_ctrl_agg_buf_size = true; | ||
2250 | agg_buf_size = 0x8; | ||
2251 | } | ||
2252 | halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2253 | bt_ctrl_agg_buf_size, agg_buf_size); | ||
2254 | |||
2255 | btc8723b1ant_run_sw_coex_mech(btcoexist); | ||
2256 | |||
2257 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2258 | |||
2259 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2260 | halbtc8723b1ant_action_bt_inquiry(btcoexist); | ||
2261 | return; | ||
2262 | } else if (bt_hs_on) { | ||
2263 | halbtc8723b1ant_action_hs(btcoexist); | ||
2264 | return; | ||
2265 | } | ||
2266 | |||
2267 | if (!wifi_connected) { | ||
2268 | bool scan = false, link = false, roam = false; | ||
2269 | |||
2270 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2271 | "[BTCoex], wifi is non connected-idle !!!\n"); | ||
2272 | |||
2273 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2274 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2275 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2276 | |||
2277 | if (scan || link || roam) { | ||
2278 | if (scan) | ||
2279 | btc8723b1ant_action_wifi_not_conn_scan( | ||
2280 | btcoexist); | ||
2281 | else | ||
2282 | btc8723b1ant_act_wifi_not_conn_asso_auth( | ||
2283 | btcoexist); | ||
2284 | } else { | ||
2285 | btc8723b1ant_action_wifi_not_conn(btcoexist); | ||
2286 | } | ||
2287 | } else { /* wifi LPS/Busy */ | ||
2288 | halbtc8723b1ant_action_wifi_connected(btcoexist); | ||
2289 | } | ||
2290 | } | ||
2291 | |||
2292 | static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
2293 | { | ||
2294 | /* sw all off */ | ||
2295 | halbtc8723b1ant_sw_mechanism(btcoexist, false); | ||
2296 | |||
2297 | halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); | ||
2298 | halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); | ||
2299 | } | ||
2300 | |||
2301 | static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist, | ||
2302 | bool backup) | ||
2303 | { | ||
2304 | u32 u32tmp = 0; | ||
2305 | u8 u8tmp = 0; | ||
2306 | u32 cnt_bt_cal_chk = 0; | ||
2307 | |||
2308 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2309 | "[BTCoex], 1Ant Init HW Config!!\n"); | ||
2310 | |||
2311 | if (backup) {/* backup rf 0x1e value */ | ||
2312 | coex_dm->backup_arfr_cnt1 = | ||
2313 | btcoexist->btc_read_4byte(btcoexist, 0x430); | ||
2314 | coex_dm->backup_arfr_cnt2 = | ||
2315 | btcoexist->btc_read_4byte(btcoexist, 0x434); | ||
2316 | coex_dm->backup_retry_limit = | ||
2317 | btcoexist->btc_read_2byte(btcoexist, 0x42a); | ||
2318 | coex_dm->backup_ampdu_max_time = | ||
2319 | btcoexist->btc_read_1byte(btcoexist, 0x456); | ||
2320 | } | ||
2321 | |||
2322 | /* WiFi goto standby while GNT_BT 0-->1 */ | ||
2323 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780); | ||
2324 | /* BT goto standby while GNT_BT 1-->0 */ | ||
2325 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x500); | ||
2326 | |||
2327 | btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); | ||
2328 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); | ||
2329 | btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); | ||
2330 | |||
2331 | /* BT calibration check */ | ||
2332 | while (cnt_bt_cal_chk <= 20) { | ||
2333 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x49d); | ||
2334 | cnt_bt_cal_chk++; | ||
2335 | if (u32tmp & BIT0) { | ||
2336 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2337 | "[BTCoex], ########### BT calibration(cnt=%d) ###########\n", | ||
2338 | cnt_bt_cal_chk); | ||
2339 | mdelay(50); | ||
2340 | } else { | ||
2341 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2342 | "[BTCoex], ********** BT NOT calibration (cnt=%d)**********\n", | ||
2343 | cnt_bt_cal_chk); | ||
2344 | break; | ||
2345 | } | ||
2346 | } | ||
2347 | |||
2348 | /* 0x790[5:0] = 0x5 */ | ||
2349 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); | ||
2350 | u8tmp &= 0xc0; | ||
2351 | u8tmp |= 0x5; | ||
2352 | btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); | ||
2353 | |||
2354 | /* Enable counter statistics */ | ||
2355 | /*0x76e[3] =1, WLAN_Act control by PTA */ | ||
2356 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
2357 | btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1); | ||
2358 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); | ||
2359 | |||
2360 | /*Antenna config */ | ||
2361 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA, true, false); | ||
2362 | /* PTA parameter */ | ||
2363 | halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); | ||
2364 | } | ||
2365 | |||
2366 | static void halbtc8723b1ant_wifi_off_hw_cfg(struct btc_coexist *btcoexist) | ||
2367 | { | ||
2368 | /* set wlan_act to low */ | ||
2369 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); | ||
2370 | } | ||
2371 | |||
2372 | /************************************************************** | ||
2373 | * work around function start with wa_halbtc8723b1ant_ | ||
2374 | **************************************************************/ | ||
2375 | /************************************************************** | ||
2376 | * extern function start with EXhalbtc8723b1ant_ | ||
2377 | **************************************************************/ | ||
2378 | |||
2379 | void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist) | ||
2380 | { | ||
2381 | halbtc8723b1ant_init_hw_config(btcoexist, true); | ||
2382 | } | ||
2383 | |||
2384 | void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
2385 | { | ||
2386 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2387 | "[BTCoex], Coex Mechanism Init!!\n"); | ||
2388 | |||
2389 | btcoexist->stop_coex_dm = false; | ||
2390 | |||
2391 | halbtc8723b1ant_init_coex_dm(btcoexist); | ||
2392 | |||
2393 | halbtc8723b1ant_query_bt_info(btcoexist); | ||
2394 | } | ||
2395 | |||
2396 | void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist) | ||
2397 | { | ||
2398 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
2399 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
2400 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
2401 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
2402 | u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0; | ||
2403 | u16 u16tmp[4]; | ||
2404 | u32 u32tmp[4]; | ||
2405 | bool roam = false, scan = false; | ||
2406 | bool link = false, wifi_under_5g = false; | ||
2407 | bool bt_hs_on = false, wifi_busy = false; | ||
2408 | s32 wifi_rssi = 0, bt_hs_rssi = 0; | ||
2409 | u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck, wifi_link_status; | ||
2410 | u8 wifi_dot11_chnl, wifi_hs_chnl; | ||
2411 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
2412 | |||
2413 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2414 | "\r\n ============[BT Coexist info]============"); | ||
2415 | |||
2416 | if (btcoexist->manual_control) { | ||
2417 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2418 | "\r\n ============[Under Manual Control]=========="); | ||
2419 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2420 | "\r\n =========================================="); | ||
2421 | } | ||
2422 | if (btcoexist->stop_coex_dm) { | ||
2423 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2424 | "\r\n ============[Coex is STOPPED]============"); | ||
2425 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2426 | "\r\n =========================================="); | ||
2427 | } | ||
2428 | |||
2429 | if (!board_info->bt_exist) { | ||
2430 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!"); | ||
2431 | return; | ||
2432 | } | ||
2433 | |||
2434 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d", | ||
2435 | "Ant PG Num/ Ant Mech/ Ant Pos:", | ||
2436 | board_info->pg_ant_num, board_info->btdm_ant_num, | ||
2437 | board_info->btdm_ant_pos); | ||
2438 | |||
2439 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d", | ||
2440 | "BT stack/ hci ext ver", | ||
2441 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
2442 | stack_info->hci_version); | ||
2443 | |||
2444 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); | ||
2445 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
2446 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2447 | "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", | ||
2448 | "CoexVer/ FwVer/ PatchVer", | ||
2449 | glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant, | ||
2450 | fw_ver, bt_patch_ver, bt_patch_ver); | ||
2451 | |||
2452 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2453 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, | ||
2454 | &wifi_dot11_chnl); | ||
2455 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); | ||
2456 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)", | ||
2457 | "Dot11 channel / HsChnl(HsMode)", | ||
2458 | wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); | ||
2459 | |||
2460 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ", | ||
2461 | "H2C Wifi inform bt chnl Info", | ||
2462 | coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1], | ||
2463 | coex_dm->wifi_chnl_info[2]); | ||
2464 | |||
2465 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
2466 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); | ||
2467 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
2468 | "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); | ||
2469 | |||
2470 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2471 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2472 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2473 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ", | ||
2474 | "Wifi link/ roam/ scan", link, roam, scan); | ||
2475 | |||
2476 | btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G, | ||
2477 | &wifi_under_5g); | ||
2478 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2479 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
2480 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, | ||
2481 | &wifi_traffic_dir); | ||
2482 | |||
2483 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ", | ||
2484 | "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), | ||
2485 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : | ||
2486 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), | ||
2487 | ((!wifi_busy) ? "idle" : | ||
2488 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? | ||
2489 | "uplink" : "downlink"))); | ||
2490 | |||
2491 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, | ||
2492 | &wifi_link_status); | ||
2493 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d/ %d/ %d", | ||
2494 | "sta/vwifi/hs/p2pGo/p2pGc", | ||
2495 | ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0), | ||
2496 | ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0), | ||
2497 | ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0), | ||
2498 | ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0), | ||
2499 | ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0)); | ||
2500 | |||
2501 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ", | ||
2502 | "BT [status/ rssi/ retryCnt]", | ||
2503 | ((btcoexist->bt_info.bt_disabled) ? ("disabled") : | ||
2504 | ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : | ||
2505 | ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
2506 | coex_dm->bt_status) ? | ||
2507 | "non-connected idle" : | ||
2508 | ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
2509 | coex_dm->bt_status) ? | ||
2510 | "connected-idle" : "busy")))), | ||
2511 | coex_sta->bt_rssi, coex_sta->bt_retry_cnt); | ||
2512 | |||
2513 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2514 | "\r\n %-35s = %d / %d / %d / %d", | ||
2515 | "SCO/HID/PAN/A2DP", bt_link_info->sco_exist, | ||
2516 | bt_link_info->hid_exist, bt_link_info->pan_exist, | ||
2517 | bt_link_info->a2dp_exist); | ||
2518 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); | ||
2519 | |||
2520 | bt_info_ext = coex_sta->bt_info_ext; | ||
2521 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s", | ||
2522 | "BT Info A2DP rate", | ||
2523 | (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate"); | ||
2524 | |||
2525 | for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) { | ||
2526 | if (coex_sta->bt_info_c2h_cnt[i]) { | ||
2527 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2528 | "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", | ||
2529 | GLBtInfoSrc8723b1Ant[i], | ||
2530 | coex_sta->bt_info_c2h[i][0], | ||
2531 | coex_sta->bt_info_c2h[i][1], | ||
2532 | coex_sta->bt_info_c2h[i][2], | ||
2533 | coex_sta->bt_info_c2h[i][3], | ||
2534 | coex_sta->bt_info_c2h[i][4], | ||
2535 | coex_sta->bt_info_c2h[i][5], | ||
2536 | coex_sta->bt_info_c2h[i][6], | ||
2537 | coex_sta->bt_info_c2h_cnt[i]); | ||
2538 | } | ||
2539 | } | ||
2540 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2541 | "\r\n %-35s = %s/%s, (0x%x/0x%x)", | ||
2542 | "PS state, IPS/LPS, (lps/rpwm)", | ||
2543 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), | ||
2544 | ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")), | ||
2545 | btcoexist->bt_info.lps_val, | ||
2546 | btcoexist->bt_info.rpwm_val); | ||
2547 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); | ||
2548 | |||
2549 | if (!btcoexist->manual_control) { | ||
2550 | /* Sw mechanism */ | ||
2551 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
2552 | "============[Sw mechanism]============"); | ||
2553 | |||
2554 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/", | ||
2555 | "SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra); | ||
2556 | |||
2557 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/ %s/ %d ", | ||
2558 | "DelBA/ BtCtrlAgg/ AggSize", | ||
2559 | (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), | ||
2560 | (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), | ||
2561 | btcoexist->bt_info.agg_buf_size); | ||
2562 | |||
2563 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", | ||
2564 | "Rate Mask", btcoexist->bt_info.ra_mask); | ||
2565 | |||
2566 | /* Fw mechanism */ | ||
2567 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
2568 | "============[Fw mechanism]============"); | ||
2569 | |||
2570 | pstdmacase = coex_dm->cur_ps_tdma; | ||
2571 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2572 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", | ||
2573 | "PS TDMA", coex_dm->ps_tdma_para[0], | ||
2574 | coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], | ||
2575 | coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], | ||
2576 | pstdmacase, coex_dm->auto_tdma_adjust); | ||
2577 | |||
2578 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d ", | ||
2579 | "IgnWlanAct", coex_dm->cur_ignore_wlan_act); | ||
2580 | |||
2581 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", | ||
2582 | "Latest error condition(should be 0)", | ||
2583 | coex_dm->error_condition); | ||
2584 | } | ||
2585 | |||
2586 | /* Hw setting */ | ||
2587 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
2588 | "============[Hw setting]============"); | ||
2589 | |||
2590 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
2591 | "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1, | ||
2592 | coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit, | ||
2593 | coex_dm->backup_ampdu_max_time); | ||
2594 | |||
2595 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); | ||
2596 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); | ||
2597 | u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); | ||
2598 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); | ||
2599 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
2600 | "0x430/0x434/0x42a/0x456", | ||
2601 | u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]); | ||
2602 | |||
2603 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); | ||
2604 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc); | ||
2605 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880); | ||
2606 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2607 | "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0], | ||
2608 | (u32tmp[1] & 0x3e000000) >> 25); | ||
2609 | |||
2610 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); | ||
2611 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); | ||
2612 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); | ||
2613 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2614 | "0x948/ 0x67[5] / 0x765", | ||
2615 | u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]); | ||
2616 | |||
2617 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); | ||
2618 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); | ||
2619 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); | ||
2620 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2621 | "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", | ||
2622 | u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3); | ||
2623 | |||
2624 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); | ||
2625 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); | ||
2626 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
2627 | u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); | ||
2628 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2629 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", | ||
2630 | "0x38[11]/0x40/0x4c[24:23]/0x64[0]", | ||
2631 | ((u8tmp[0] & 0x8)>>3), u8tmp[1], | ||
2632 | ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1); | ||
2633 | |||
2634 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); | ||
2635 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); | ||
2636 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
2637 | "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); | ||
2638 | |||
2639 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); | ||
2640 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); | ||
2641 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
2642 | "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]); | ||
2643 | |||
2644 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); | ||
2645 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); | ||
2646 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8); | ||
2647 | u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0); | ||
2648 | |||
2649 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); | ||
2650 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); | ||
2651 | |||
2652 | fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) + | ||
2653 | ((u32tmp[1] & 0xffff0000) >> 16) + | ||
2654 | (u32tmp[1] & 0xffff) + | ||
2655 | (u32tmp[2] & 0xffff) + | ||
2656 | ((u32tmp[3] & 0xffff0000) >> 16) + | ||
2657 | (u32tmp[3] & 0xffff); | ||
2658 | fa_cck = (u8tmp[0] << 8) + u8tmp[1]; | ||
2659 | |||
2660 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2661 | "OFDM-CCA/OFDM-FA/CCK-FA", | ||
2662 | u32tmp[0] & 0xffff, fa_ofdm, fa_cck); | ||
2663 | |||
2664 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); | ||
2665 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); | ||
2666 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); | ||
2667 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2668 | "0x6c0/0x6c4/0x6c8(coexTable)", | ||
2669 | u32tmp[0], u32tmp[1], u32tmp[2]); | ||
2670 | |||
2671 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
2672 | "0x770(high-pri rx/tx)", coex_sta->high_priority_rx, | ||
2673 | coex_sta->high_priority_tx); | ||
2674 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
2675 | "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, | ||
2676 | coex_sta->low_priority_tx); | ||
2677 | #if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 1) | ||
2678 | halbtc8723b1ant_monitor_bt_ctr(btcoexist); | ||
2679 | #endif | ||
2680 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS); | ||
2681 | } | ||
2682 | |||
2683 | void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | ||
2684 | { | ||
2685 | if (btcoexist->manual_control || btcoexist->stop_coex_dm) | ||
2686 | return; | ||
2687 | |||
2688 | if (BTC_IPS_ENTER == type) { | ||
2689 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2690 | "[BTCoex], IPS ENTER notify\n"); | ||
2691 | coex_sta->under_ips = true; | ||
2692 | |||
2693 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, | ||
2694 | false, true); | ||
2695 | /* set PTA control */ | ||
2696 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); | ||
2697 | halbtc8723b1ant_coex_table_with_type(btcoexist, | ||
2698 | NORMAL_EXEC, 0); | ||
2699 | halbtc8723b1ant_wifi_off_hw_cfg(btcoexist); | ||
2700 | } else if (BTC_IPS_LEAVE == type) { | ||
2701 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2702 | "[BTCoex], IPS LEAVE notify\n"); | ||
2703 | coex_sta->under_ips = false; | ||
2704 | |||
2705 | halbtc8723b1ant_init_hw_config(btcoexist, false); | ||
2706 | halbtc8723b1ant_init_coex_dm(btcoexist); | ||
2707 | halbtc8723b1ant_query_bt_info(btcoexist); | ||
2708 | } | ||
2709 | } | ||
2710 | |||
2711 | void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | ||
2712 | { | ||
2713 | if (btcoexist->manual_control || btcoexist->stop_coex_dm) | ||
2714 | return; | ||
2715 | |||
2716 | if (BTC_LPS_ENABLE == type) { | ||
2717 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2718 | "[BTCoex], LPS ENABLE notify\n"); | ||
2719 | coex_sta->under_lps = true; | ||
2720 | } else if (BTC_LPS_DISABLE == type) { | ||
2721 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2722 | "[BTCoex], LPS DISABLE notify\n"); | ||
2723 | coex_sta->under_lps = false; | ||
2724 | } | ||
2725 | } | ||
2726 | |||
2727 | void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | ||
2728 | { | ||
2729 | bool wifi_connected = false, bt_hs_on = false; | ||
2730 | u32 wifi_link_status = 0; | ||
2731 | u32 num_of_wifi_link = 0; | ||
2732 | bool bt_ctrl_agg_buf_size = false; | ||
2733 | u8 agg_buf_size = 5; | ||
2734 | |||
2735 | if (btcoexist->manual_control || btcoexist->stop_coex_dm || | ||
2736 | btcoexist->bt_info.bt_disabled) | ||
2737 | return; | ||
2738 | |||
2739 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2740 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
2741 | &wifi_connected); | ||
2742 | |||
2743 | halbtc8723b1ant_query_bt_info(btcoexist); | ||
2744 | |||
2745 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, | ||
2746 | &wifi_link_status); | ||
2747 | num_of_wifi_link = wifi_link_status >> 16; | ||
2748 | if (num_of_wifi_link >= 2) { | ||
2749 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2750 | halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2751 | bt_ctrl_agg_buf_size, agg_buf_size); | ||
2752 | halbtc8723b1ant_action_wifi_multiport(btcoexist); | ||
2753 | return; | ||
2754 | } | ||
2755 | |||
2756 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2757 | halbtc8723b1ant_action_bt_inquiry(btcoexist); | ||
2758 | return; | ||
2759 | } else if (bt_hs_on) { | ||
2760 | halbtc8723b1ant_action_hs(btcoexist); | ||
2761 | return; | ||
2762 | } | ||
2763 | |||
2764 | if (BTC_SCAN_START == type) { | ||
2765 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2766 | "[BTCoex], SCAN START notify\n"); | ||
2767 | if (!wifi_connected) /* non-connected scan */ | ||
2768 | btc8723b1ant_action_wifi_not_conn_scan(btcoexist); | ||
2769 | else /* wifi is connected */ | ||
2770 | btc8723b1ant_action_wifi_conn_scan(btcoexist); | ||
2771 | } else if (BTC_SCAN_FINISH == type) { | ||
2772 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2773 | "[BTCoex], SCAN FINISH notify\n"); | ||
2774 | if (!wifi_connected) /* non-connected scan */ | ||
2775 | btc8723b1ant_action_wifi_not_conn(btcoexist); | ||
2776 | else | ||
2777 | halbtc8723b1ant_action_wifi_connected(btcoexist); | ||
2778 | } | ||
2779 | } | ||
2780 | |||
2781 | void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | ||
2782 | { | ||
2783 | bool wifi_connected = false, bt_hs_on = false; | ||
2784 | u32 wifi_link_status = 0; | ||
2785 | u32 num_of_wifi_link = 0; | ||
2786 | bool bt_ctrl_agg_buf_size = false; | ||
2787 | u8 agg_buf_size = 5; | ||
2788 | |||
2789 | if (btcoexist->manual_control || btcoexist->stop_coex_dm || | ||
2790 | btcoexist->bt_info.bt_disabled) | ||
2791 | return; | ||
2792 | |||
2793 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, | ||
2794 | &wifi_link_status); | ||
2795 | num_of_wifi_link = wifi_link_status>>16; | ||
2796 | if (num_of_wifi_link >= 2) { | ||
2797 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2798 | halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2799 | bt_ctrl_agg_buf_size, agg_buf_size); | ||
2800 | halbtc8723b1ant_action_wifi_multiport(btcoexist); | ||
2801 | return; | ||
2802 | } | ||
2803 | |||
2804 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2805 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2806 | halbtc8723b1ant_action_bt_inquiry(btcoexist); | ||
2807 | return; | ||
2808 | } else if (bt_hs_on) { | ||
2809 | halbtc8723b1ant_action_hs(btcoexist); | ||
2810 | return; | ||
2811 | } | ||
2812 | |||
2813 | if (BTC_ASSOCIATE_START == type) { | ||
2814 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2815 | "[BTCoex], CONNECT START notify\n"); | ||
2816 | btc8723b1ant_act_wifi_not_conn_asso_auth(btcoexist); | ||
2817 | } else if (BTC_ASSOCIATE_FINISH == type) { | ||
2818 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2819 | "[BTCoex], CONNECT FINISH notify\n"); | ||
2820 | |||
2821 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
2822 | &wifi_connected); | ||
2823 | if (!wifi_connected) /* non-connected scan */ | ||
2824 | btc8723b1ant_action_wifi_not_conn(btcoexist); | ||
2825 | else | ||
2826 | halbtc8723b1ant_action_wifi_connected(btcoexist); | ||
2827 | } | ||
2828 | } | ||
2829 | |||
2830 | void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, | ||
2831 | u8 type) | ||
2832 | { | ||
2833 | u8 h2c_parameter[3] = {0}; | ||
2834 | u32 wifi_bw; | ||
2835 | u8 wifiCentralChnl; | ||
2836 | |||
2837 | if (btcoexist->manual_control || btcoexist->stop_coex_dm || | ||
2838 | btcoexist->bt_info.bt_disabled) | ||
2839 | return; | ||
2840 | |||
2841 | if (BTC_MEDIA_CONNECT == type) | ||
2842 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2843 | "[BTCoex], MEDIA connect notify\n"); | ||
2844 | else | ||
2845 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2846 | "[BTCoex], MEDIA disconnect notify\n"); | ||
2847 | |||
2848 | /* only 2.4G we need to inform bt the chnl mask */ | ||
2849 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, | ||
2850 | &wifiCentralChnl); | ||
2851 | |||
2852 | if ((BTC_MEDIA_CONNECT == type) && | ||
2853 | (wifiCentralChnl <= 14)) { | ||
2854 | h2c_parameter[0] = 0x0; | ||
2855 | h2c_parameter[1] = wifiCentralChnl; | ||
2856 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2857 | if (BTC_WIFI_BW_HT40 == wifi_bw) | ||
2858 | h2c_parameter[2] = 0x30; | ||
2859 | else | ||
2860 | h2c_parameter[2] = 0x20; | ||
2861 | } | ||
2862 | |||
2863 | coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; | ||
2864 | coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; | ||
2865 | coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; | ||
2866 | |||
2867 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
2868 | "[BTCoex], FW write 0x66 = 0x%x\n", | ||
2869 | h2c_parameter[0] << 16 | h2c_parameter[1] << 8 | | ||
2870 | h2c_parameter[2]); | ||
2871 | |||
2872 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); | ||
2873 | } | ||
2874 | |||
2875 | void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
2876 | u8 type) | ||
2877 | { | ||
2878 | bool bt_hs_on = false; | ||
2879 | u32 wifi_link_status = 0; | ||
2880 | u32 num_of_wifi_link = 0; | ||
2881 | bool bt_ctrl_agg_buf_size = false; | ||
2882 | u8 agg_buf_size = 5; | ||
2883 | |||
2884 | if (btcoexist->manual_control || btcoexist->stop_coex_dm || | ||
2885 | btcoexist->bt_info.bt_disabled) | ||
2886 | return; | ||
2887 | |||
2888 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS, | ||
2889 | &wifi_link_status); | ||
2890 | num_of_wifi_link = wifi_link_status >> 16; | ||
2891 | if (num_of_wifi_link >= 2) { | ||
2892 | halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2893 | halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2894 | bt_ctrl_agg_buf_size, agg_buf_size); | ||
2895 | halbtc8723b1ant_action_wifi_multiport(btcoexist); | ||
2896 | return; | ||
2897 | } | ||
2898 | |||
2899 | coex_sta->special_pkt_period_cnt = 0; | ||
2900 | |||
2901 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2902 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2903 | halbtc8723b1ant_action_bt_inquiry(btcoexist); | ||
2904 | return; | ||
2905 | } else if (bt_hs_on) { | ||
2906 | halbtc8723b1ant_action_hs(btcoexist); | ||
2907 | return; | ||
2908 | } | ||
2909 | |||
2910 | if (BTC_PACKET_DHCP == type || | ||
2911 | BTC_PACKET_EAPOL == type) { | ||
2912 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2913 | "[BTCoex], special Packet(%d) notify\n", type); | ||
2914 | halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist); | ||
2915 | } | ||
2916 | } | ||
2917 | |||
2918 | void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
2919 | u8 *tmp_buf, u8 length) | ||
2920 | { | ||
2921 | u8 bt_info = 0; | ||
2922 | u8 i, rsp_source = 0; | ||
2923 | bool wifi_connected = false; | ||
2924 | bool bt_busy = false; | ||
2925 | |||
2926 | coex_sta->c2h_bt_info_req_sent = false; | ||
2927 | |||
2928 | rsp_source = tmp_buf[0] & 0xf; | ||
2929 | if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX) | ||
2930 | rsp_source = BT_INFO_SRC_8723B_1ANT_WIFI_FW; | ||
2931 | coex_sta->bt_info_c2h_cnt[rsp_source]++; | ||
2932 | |||
2933 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2934 | "[BTCoex], Bt info[%d], length=%d, hex data = [", | ||
2935 | rsp_source, length); | ||
2936 | for (i = 0; i < length; i++) { | ||
2937 | coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; | ||
2938 | if (i == 1) | ||
2939 | bt_info = tmp_buf[i]; | ||
2940 | if (i == length - 1) | ||
2941 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2942 | "0x%02x]\n", tmp_buf[i]); | ||
2943 | else | ||
2944 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2945 | "0x%02x, ", tmp_buf[i]); | ||
2946 | } | ||
2947 | |||
2948 | if (BT_INFO_SRC_8723B_1ANT_WIFI_FW != rsp_source) { | ||
2949 | coex_sta->bt_retry_cnt = /* [3:0] */ | ||
2950 | coex_sta->bt_info_c2h[rsp_source][2] & 0xf; | ||
2951 | |||
2952 | coex_sta->bt_rssi = | ||
2953 | coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10; | ||
2954 | |||
2955 | coex_sta->bt_info_ext = | ||
2956 | coex_sta->bt_info_c2h[rsp_source][4]; | ||
2957 | |||
2958 | /* Here we need to resend some wifi info to BT | ||
2959 | * because bt is reset and loss of the info. | ||
2960 | */ | ||
2961 | if (coex_sta->bt_info_ext & BIT1) { | ||
2962 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2963 | "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); | ||
2964 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
2965 | &wifi_connected); | ||
2966 | if (wifi_connected) | ||
2967 | ex_halbtc8723b1ant_media_status_notify(btcoexist, | ||
2968 | BTC_MEDIA_CONNECT); | ||
2969 | else | ||
2970 | ex_halbtc8723b1ant_media_status_notify(btcoexist, | ||
2971 | BTC_MEDIA_DISCONNECT); | ||
2972 | } | ||
2973 | |||
2974 | if (coex_sta->bt_info_ext & BIT3) { | ||
2975 | if (!btcoexist->manual_control && | ||
2976 | !btcoexist->stop_coex_dm) { | ||
2977 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2978 | "[BTCoex], BT ext info bit3 check, set BT NOT ignore Wlan active!!\n"); | ||
2979 | halbtc8723b1ant_ignore_wlan_act(btcoexist, | ||
2980 | FORCE_EXEC, | ||
2981 | false); | ||
2982 | } | ||
2983 | } else { | ||
2984 | /* BT already NOT ignore Wlan active, do nothing here.*/ | ||
2985 | } | ||
2986 | #if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0) | ||
2987 | if (coex_sta->bt_info_ext & BIT4) { | ||
2988 | /* BT auto report already enabled, do nothing */ | ||
2989 | } else { | ||
2990 | halbtc8723b1ant_bt_auto_report(btcoexist, FORCE_EXEC, | ||
2991 | true); | ||
2992 | } | ||
2993 | #endif | ||
2994 | } | ||
2995 | |||
2996 | /* check BIT2 first ==> check if bt is under inquiry or page scan */ | ||
2997 | if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE) | ||
2998 | coex_sta->c2h_bt_inquiry_page = true; | ||
2999 | else | ||
3000 | coex_sta->c2h_bt_inquiry_page = false; | ||
3001 | |||
3002 | /* set link exist status */ | ||
3003 | if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) { | ||
3004 | coex_sta->bt_link_exist = false; | ||
3005 | coex_sta->pan_exist = false; | ||
3006 | coex_sta->a2dp_exist = false; | ||
3007 | coex_sta->hid_exist = false; | ||
3008 | coex_sta->sco_exist = false; | ||
3009 | } else { /* connection exists */ | ||
3010 | coex_sta->bt_link_exist = true; | ||
3011 | if (bt_info & BT_INFO_8723B_1ANT_B_FTP) | ||
3012 | coex_sta->pan_exist = true; | ||
3013 | else | ||
3014 | coex_sta->pan_exist = false; | ||
3015 | if (bt_info & BT_INFO_8723B_1ANT_B_A2DP) | ||
3016 | coex_sta->a2dp_exist = true; | ||
3017 | else | ||
3018 | coex_sta->a2dp_exist = false; | ||
3019 | if (bt_info & BT_INFO_8723B_1ANT_B_HID) | ||
3020 | coex_sta->hid_exist = true; | ||
3021 | else | ||
3022 | coex_sta->hid_exist = false; | ||
3023 | if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) | ||
3024 | coex_sta->sco_exist = true; | ||
3025 | else | ||
3026 | coex_sta->sco_exist = false; | ||
3027 | } | ||
3028 | |||
3029 | halbtc8723b1ant_update_bt_link_info(btcoexist); | ||
3030 | |||
3031 | if (!(bt_info&BT_INFO_8723B_1ANT_B_CONNECTION)) { | ||
3032 | coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE; | ||
3033 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3034 | "[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n"); | ||
3035 | /* connection exists but no busy */ | ||
3036 | } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) { | ||
3037 | coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE; | ||
3038 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3039 | "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); | ||
3040 | } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) || | ||
3041 | (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) { | ||
3042 | coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY; | ||
3043 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3044 | "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); | ||
3045 | } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) { | ||
3046 | if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) | ||
3047 | coex_dm->auto_tdma_adjust = false; | ||
3048 | |||
3049 | coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY; | ||
3050 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3051 | "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); | ||
3052 | } else { | ||
3053 | coex_dm->bt_status = | ||
3054 | BT_8723B_1ANT_BT_STATUS_MAX; | ||
3055 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3056 | "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n"); | ||
3057 | } | ||
3058 | |||
3059 | if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || | ||
3060 | (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
3061 | (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) | ||
3062 | bt_busy = true; | ||
3063 | else | ||
3064 | bt_busy = false; | ||
3065 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); | ||
3066 | |||
3067 | halbtc8723b1ant_run_coexist_mechanism(btcoexist); | ||
3068 | } | ||
3069 | |||
3070 | void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist) | ||
3071 | { | ||
3072 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); | ||
3073 | |||
3074 | btcoexist->stop_coex_dm = true; | ||
3075 | |||
3076 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, false, true); | ||
3077 | |||
3078 | halbtc8723b1ant_wifi_off_hw_cfg(btcoexist); | ||
3079 | halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | ||
3080 | |||
3081 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
3082 | 0x0, 0x0); | ||
3083 | halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); | ||
3084 | |||
3085 | ex_halbtc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); | ||
3086 | } | ||
3087 | |||
3088 | void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) | ||
3089 | { | ||
3090 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Pnp notify\n"); | ||
3091 | |||
3092 | if (BTC_WIFI_PNP_SLEEP == pnp_state) { | ||
3093 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3094 | "[BTCoex], Pnp notify to SLEEP\n"); | ||
3095 | btcoexist->stop_coex_dm = true; | ||
3096 | halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, false, | ||
3097 | true); | ||
3098 | halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
3099 | 0x0, 0x0); | ||
3100 | halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0); | ||
3101 | halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2); | ||
3102 | halbtc8723b1ant_wifi_off_hw_cfg(btcoexist); | ||
3103 | } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { | ||
3104 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3105 | "[BTCoex], Pnp notify to WAKE UP\n"); | ||
3106 | btcoexist->stop_coex_dm = false; | ||
3107 | halbtc8723b1ant_init_hw_config(btcoexist, false); | ||
3108 | halbtc8723b1ant_init_coex_dm(btcoexist); | ||
3109 | halbtc8723b1ant_query_bt_info(btcoexist); | ||
3110 | } | ||
3111 | } | ||
3112 | |||
3113 | void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist) | ||
3114 | { | ||
3115 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3116 | "[BTCoex], *****************Coex DM Reset****************\n"); | ||
3117 | |||
3118 | halbtc8723b1ant_init_hw_config(btcoexist, false); | ||
3119 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | ||
3120 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x0); | ||
3121 | halbtc8723b1ant_init_coex_dm(btcoexist); | ||
3122 | } | ||
3123 | |||
3124 | void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist) | ||
3125 | { | ||
3126 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
3127 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
3128 | static u8 dis_ver_info_cnt; | ||
3129 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
3130 | |||
3131 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3132 | "[BTCoex], ==========================Periodical===========================\n"); | ||
3133 | |||
3134 | if (dis_ver_info_cnt <= 5) { | ||
3135 | dis_ver_info_cnt += 1; | ||
3136 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3137 | "[BTCoex], ****************************************************************\n"); | ||
3138 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3139 | "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", | ||
3140 | board_info->pg_ant_num, board_info->btdm_ant_num, | ||
3141 | board_info->btdm_ant_pos); | ||
3142 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3143 | "[BTCoex], BT stack/ hci ext ver = %s / %d\n", | ||
3144 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
3145 | stack_info->hci_version); | ||
3146 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, | ||
3147 | &bt_patch_ver); | ||
3148 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
3149 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3150 | "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", | ||
3151 | glcoex_ver_date_8723b_1ant, | ||
3152 | glcoex_ver_8723b_1ant, fw_ver, | ||
3153 | bt_patch_ver, bt_patch_ver); | ||
3154 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3155 | "[BTCoex], ****************************************************************\n"); | ||
3156 | } | ||
3157 | |||
3158 | #if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0) | ||
3159 | halbtc8723b1ant_query_bt_info(btcoexist); | ||
3160 | halbtc8723b1ant_monitor_bt_ctr(btcoexist); | ||
3161 | halbtc8723b1ant_monitor_bt_enable_disable(btcoexist); | ||
3162 | #else | ||
3163 | if (btc8723b1ant_is_wifi_status_changed(btcoexist) || | ||
3164 | coex_dm->auto_tdma_adjust) { | ||
3165 | halbtc8723b1ant_run_coexist_mechanism(btcoexist); | ||
3166 | } | ||
3167 | |||
3168 | coex_sta->special_pkt_period_cnt++; | ||
3169 | #endif | ||
3170 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h new file mode 100644 index 000000000000..75f8094b7a34 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h | |||
@@ -0,0 +1,184 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | /********************************************************************** | ||
26 | * The following is for 8723B 1ANT BT Co-exist definition | ||
27 | **********************************************************************/ | ||
28 | #define BT_AUTO_REPORT_ONLY_8723B_1ANT 1 | ||
29 | |||
30 | #define BT_INFO_8723B_1ANT_B_FTP BIT7 | ||
31 | #define BT_INFO_8723B_1ANT_B_A2DP BIT6 | ||
32 | #define BT_INFO_8723B_1ANT_B_HID BIT5 | ||
33 | #define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT4 | ||
34 | #define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT3 | ||
35 | #define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT2 | ||
36 | #define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT1 | ||
37 | #define BT_INFO_8723B_1ANT_B_CONNECTION BIT0 | ||
38 | |||
39 | #define BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ | ||
40 | (((_BT_INFO_EXT_&BIT0)) ? true : false) | ||
41 | |||
42 | #define BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT 2 | ||
43 | |||
44 | enum _BT_INFO_SRC_8723B_1ANT { | ||
45 | BT_INFO_SRC_8723B_1ANT_WIFI_FW = 0x0, | ||
46 | BT_INFO_SRC_8723B_1ANT_BT_RSP = 0x1, | ||
47 | BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND = 0x2, | ||
48 | BT_INFO_SRC_8723B_1ANT_MAX | ||
49 | }; | ||
50 | |||
51 | enum _BT_8723B_1ANT_BT_STATUS { | ||
52 | BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, | ||
53 | BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, | ||
54 | BT_8723B_1ANT_BT_STATUS_INQ_PAGE = 0x2, | ||
55 | BT_8723B_1ANT_BT_STATUS_ACL_BUSY = 0x3, | ||
56 | BT_8723B_1ANT_BT_STATUS_SCO_BUSY = 0x4, | ||
57 | BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, | ||
58 | BT_8723B_1ANT_BT_STATUS_MAX | ||
59 | }; | ||
60 | |||
61 | enum _BT_8723B_1ANT_WIFI_STATUS { | ||
62 | BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, | ||
63 | BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, | ||
64 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, | ||
65 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, | ||
66 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, | ||
67 | BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, | ||
68 | BT_8723B_1ANT_WIFI_STATUS_MAX | ||
69 | }; | ||
70 | |||
71 | enum _BT_8723B_1ANT_COEX_ALGO { | ||
72 | BT_8723B_1ANT_COEX_ALGO_UNDEFINED = 0x0, | ||
73 | BT_8723B_1ANT_COEX_ALGO_SCO = 0x1, | ||
74 | BT_8723B_1ANT_COEX_ALGO_HID = 0x2, | ||
75 | BT_8723B_1ANT_COEX_ALGO_A2DP = 0x3, | ||
76 | BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, | ||
77 | BT_8723B_1ANT_COEX_ALGO_PANEDR = 0x5, | ||
78 | BT_8723B_1ANT_COEX_ALGO_PANHS = 0x6, | ||
79 | BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, | ||
80 | BT_8723B_1ANT_COEX_ALGO_PANEDR_HID = 0x8, | ||
81 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, | ||
82 | BT_8723B_1ANT_COEX_ALGO_HID_A2DP = 0xa, | ||
83 | BT_8723B_1ANT_COEX_ALGO_MAX = 0xb, | ||
84 | }; | ||
85 | |||
86 | struct coex_dm_8723b_1ant { | ||
87 | /* fw mechanism */ | ||
88 | bool cur_ignore_wlan_act; | ||
89 | bool pre_ignore_wlan_act; | ||
90 | u8 pre_ps_tdma; | ||
91 | u8 cur_ps_tdma; | ||
92 | u8 ps_tdma_para[5]; | ||
93 | u8 tdma_adj_type; | ||
94 | bool auto_tdma_adjust; | ||
95 | bool pre_ps_tdma_on; | ||
96 | bool cur_ps_tdma_on; | ||
97 | bool pre_bt_auto_report; | ||
98 | bool cur_bt_auto_report; | ||
99 | u8 pre_lps; | ||
100 | u8 cur_lps; | ||
101 | u8 pre_rpwm; | ||
102 | u8 cur_rpwm; | ||
103 | |||
104 | /* sw mechanism */ | ||
105 | bool pre_low_penalty_ra; | ||
106 | bool cur_low_penalty_ra; | ||
107 | u32 pre_val0x6c0; | ||
108 | u32 cur_val0x6c0; | ||
109 | u32 pre_val0x6c4; | ||
110 | u32 cur_val0x6c4; | ||
111 | u32 pre_val0x6c8; | ||
112 | u32 cur_val0x6c8; | ||
113 | u8 pre_val0x6cc; | ||
114 | u8 cur_val0x6cc; | ||
115 | bool limited_dig; | ||
116 | |||
117 | u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */ | ||
118 | u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */ | ||
119 | u16 backup_retry_limit; | ||
120 | u8 backup_ampdu_max_time; | ||
121 | |||
122 | /* algorithm related */ | ||
123 | u8 pre_algorithm; | ||
124 | u8 cur_algorithm; | ||
125 | u8 bt_status; | ||
126 | u8 wifi_chnl_info[3]; | ||
127 | |||
128 | u32 prera_mask; | ||
129 | u32 curra_mask; | ||
130 | u8 pre_arfr_type; | ||
131 | u8 cur_arfr_type; | ||
132 | u8 pre_retry_limit_type; | ||
133 | u8 cur_retry_limit_type; | ||
134 | u8 pre_ampdu_time_type; | ||
135 | u8 cur_ampdu_time_type; | ||
136 | |||
137 | u8 error_condition; | ||
138 | }; | ||
139 | |||
140 | struct coex_sta_8723b_1ant { | ||
141 | bool bt_link_exist; | ||
142 | bool sco_exist; | ||
143 | bool a2dp_exist; | ||
144 | bool hid_exist; | ||
145 | bool pan_exist; | ||
146 | |||
147 | bool under_lps; | ||
148 | bool under_ips; | ||
149 | u32 special_pkt_period_cnt; | ||
150 | u32 high_priority_tx; | ||
151 | u32 high_priority_rx; | ||
152 | u32 low_priority_tx; | ||
153 | u32 low_priority_rx; | ||
154 | u8 bt_rssi; | ||
155 | u8 pre_bt_rssi_state; | ||
156 | u8 pre_wifi_rssi_state[4]; | ||
157 | bool c2h_bt_info_req_sent; | ||
158 | u8 bt_info_c2h[BT_INFO_SRC_8723B_1ANT_MAX][10]; | ||
159 | u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_1ANT_MAX]; | ||
160 | bool c2h_bt_inquiry_page; | ||
161 | u8 bt_retry_cnt; | ||
162 | u8 bt_info_ext; | ||
163 | }; | ||
164 | |||
165 | /************************************************************************* | ||
166 | * The following is interface which will notify coex module. | ||
167 | *************************************************************************/ | ||
168 | void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist); | ||
169 | void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist); | ||
170 | void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type); | ||
171 | void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type); | ||
172 | void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type); | ||
173 | void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type); | ||
174 | void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist, | ||
175 | u8 type); | ||
176 | void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
177 | u8 type); | ||
178 | void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
179 | u8 *tmpbuf, u8 length); | ||
180 | void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist); | ||
181 | void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate); | ||
182 | void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist); | ||
183 | void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist); | ||
184 | void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist); | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c index d916ab9f3c38..cefe26991421 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c | |||
@@ -49,8 +49,8 @@ static const char *const glbt_info_src_8723b_2ant[] = { | |||
49 | "BT Info[bt auto report]", | 49 | "BT Info[bt auto report]", |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static u32 glcoex_ver_date_8723b_2ant = 20130731; | 52 | static u32 glcoex_ver_date_8723b_2ant = 20131113; |
53 | static u32 glcoex_ver_8723b_2ant = 0x3b; | 53 | static u32 glcoex_ver_8723b_2ant = 0x3f; |
54 | 54 | ||
55 | /************************************************************** | 55 | /************************************************************** |
56 | * local function proto type if needed | 56 | * local function proto type if needed |
@@ -303,6 +303,21 @@ static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) | |||
303 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | 303 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); |
304 | } | 304 | } |
305 | 305 | ||
306 | static void btc8723b2ant_query_bt_info(struct btc_coexist *btcoexist) | ||
307 | { | ||
308 | u8 h2c_parameter[1] = {0}; | ||
309 | |||
310 | coex_sta->c2h_bt_info_req_sent = true; | ||
311 | |||
312 | h2c_parameter[0] |= BIT0; /* trigger */ | ||
313 | |||
314 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
315 | "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", | ||
316 | h2c_parameter[0]); | ||
317 | |||
318 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | ||
319 | } | ||
320 | |||
306 | static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) | 321 | static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) |
307 | { | 322 | { |
308 | static bool pre_wifi_busy; | 323 | static bool pre_wifi_busy; |
@@ -604,7 +619,7 @@ static bool btc8723b_need_dec_pwr(struct btc_coexist *btcoexist) | |||
604 | if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) | 619 | if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) |
605 | return false; | 620 | return false; |
606 | 621 | ||
607 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 622 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
608 | 623 | ||
609 | if (wifi_connected) { | 624 | if (wifi_connected) { |
610 | if (bt_hs_on) { | 625 | if (bt_hs_on) { |
@@ -824,7 +839,6 @@ static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex, | |||
824 | btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); | 839 | btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); |
825 | } | 840 | } |
826 | 841 | ||
827 | |||
828 | static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, | 842 | static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, |
829 | bool force_exec, bool dac_swing_on, | 843 | bool force_exec, bool dac_swing_on, |
830 | u32 dac_swing_lvl) | 844 | u32 dac_swing_lvl) |
@@ -884,7 +898,6 @@ static void btc8723b2ant_set_agc_table(struct btc_coexist *btcoexist, | |||
884 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001); | 898 | btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001); |
885 | } | 899 | } |
886 | 900 | ||
887 | |||
888 | /* RF Gain */ | 901 | /* RF Gain */ |
889 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); | 902 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); |
890 | if (agc_table_en) { | 903 | if (agc_table_en) { |
@@ -1160,8 +1173,87 @@ static void btc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist, | |||
1160 | dac_swing_lvl); | 1173 | dac_swing_lvl); |
1161 | } | 1174 | } |
1162 | 1175 | ||
1176 | static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist, | ||
1177 | u8 antpos_type, bool init_hwcfg, | ||
1178 | bool wifi_off) | ||
1179 | { | ||
1180 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
1181 | u32 fw_ver = 0, u32tmp = 0; | ||
1182 | bool pg_ext_switch = false; | ||
1183 | bool use_ext_switch = false; | ||
1184 | u8 h2c_parameter[2] = {0}; | ||
1185 | |||
1186 | btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch); | ||
1187 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
1188 | |||
1189 | if ((fw_ver < 0xc0000) || pg_ext_switch) | ||
1190 | use_ext_switch = true; | ||
1191 | |||
1192 | if (init_hwcfg) { | ||
1193 | /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */ | ||
1194 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
1195 | u32tmp &= ~BIT23; | ||
1196 | u32tmp |= BIT24; | ||
1197 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); | ||
1198 | |||
1199 | btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); | ||
1200 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); | ||
1201 | btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); | ||
1202 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); | ||
1203 | |||
1204 | /* Force GNT_BT to low */ | ||
1205 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); | ||
1206 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); | ||
1207 | |||
1208 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { | ||
1209 | /* tell firmware "no antenna inverse" */ | ||
1210 | h2c_parameter[0] = 0; | ||
1211 | h2c_parameter[1] = 1; /* ext switch type */ | ||
1212 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1213 | h2c_parameter); | ||
1214 | } else { | ||
1215 | /* tell firmware "antenna inverse" */ | ||
1216 | h2c_parameter[0] = 1; | ||
1217 | h2c_parameter[1] = 1; /* ext switch type */ | ||
1218 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1219 | h2c_parameter); | ||
1220 | } | ||
1221 | } | ||
1222 | |||
1223 | /* ext switch setting */ | ||
1224 | if (use_ext_switch) { | ||
1225 | /* fixed internal switch S1->WiFi, S0->BT */ | ||
1226 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); | ||
1227 | switch (antpos_type) { | ||
1228 | case BTC_ANT_WIFI_AT_MAIN: | ||
1229 | /* ext switch main at wifi */ | ||
1230 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, | ||
1231 | 0x3, 0x1); | ||
1232 | break; | ||
1233 | case BTC_ANT_WIFI_AT_AUX: | ||
1234 | /* ext switch aux at wifi */ | ||
1235 | btcoexist->btc_write_1byte_bitmask(btcoexist, | ||
1236 | 0x92c, 0x3, 0x2); | ||
1237 | break; | ||
1238 | } | ||
1239 | } else { /* internal switch */ | ||
1240 | /* fixed ext switch */ | ||
1241 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1); | ||
1242 | switch (antpos_type) { | ||
1243 | case BTC_ANT_WIFI_AT_MAIN: | ||
1244 | /* fixed internal switch S1->WiFi, S0->BT */ | ||
1245 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); | ||
1246 | break; | ||
1247 | case BTC_ANT_WIFI_AT_AUX: | ||
1248 | /* fixed internal switch S0->WiFi, S1->BT */ | ||
1249 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); | ||
1250 | break; | ||
1251 | } | ||
1252 | } | ||
1253 | } | ||
1254 | |||
1163 | static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, | 1255 | static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, |
1164 | bool turn_on, u8 type) | 1256 | bool turn_on, u8 type) |
1165 | { | 1257 | { |
1166 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | 1258 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, |
1167 | "[BTCoex], %s turn %s PS TDMA, type=%d\n", | 1259 | "[BTCoex], %s turn %s PS TDMA, type=%d\n", |
@@ -1351,7 +1443,8 @@ static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist) | |||
1351 | coex_dm->need_recover_0x948 = true; | 1443 | coex_dm->need_recover_0x948 = true; |
1352 | coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948); | 1444 | coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948); |
1353 | 1445 | ||
1354 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); | 1446 | btc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_AUX, |
1447 | false, false); | ||
1355 | } | 1448 | } |
1356 | 1449 | ||
1357 | static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) | 1450 | static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) |
@@ -1520,7 +1613,9 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause, | |||
1520 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 1613 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1521 | true, 8); | 1614 | true, 8); |
1522 | coex_dm->tdma_adj_type = 8; | 1615 | coex_dm->tdma_adj_type = 8; |
1523 | } else if (coex_dm->cur_ps_tdma == 9) { | 1616 | } |
1617 | |||
1618 | if (coex_dm->cur_ps_tdma == 9) { | ||
1524 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 1619 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1525 | true, 13); | 1620 | true, 13); |
1526 | coex_dm->tdma_adj_type = 13; | 1621 | coex_dm->tdma_adj_type = 13; |
@@ -1607,7 +1702,9 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause, | |||
1607 | } else if (coex_dm->cur_ps_tdma == 8) { | 1702 | } else if (coex_dm->cur_ps_tdma == 8) { |
1608 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); | 1703 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); |
1609 | coex_dm->tdma_adj_type = 4; | 1704 | coex_dm->tdma_adj_type = 4; |
1610 | } else if (coex_dm->cur_ps_tdma == 13) { | 1705 | } |
1706 | |||
1707 | if (coex_dm->cur_ps_tdma == 13) { | ||
1611 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); | 1708 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); |
1612 | coex_dm->tdma_adj_type = 9; | 1709 | coex_dm->tdma_adj_type = 9; |
1613 | } else if (coex_dm->cur_ps_tdma == 14) { | 1710 | } else if (coex_dm->cur_ps_tdma == 14) { |
@@ -1652,23 +1749,34 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause, | |||
1652 | coex_dm->tdma_adj_type = 12; | 1749 | coex_dm->tdma_adj_type = 12; |
1653 | } | 1750 | } |
1654 | } else if (result == 1) { | 1751 | } else if (result == 1) { |
1655 | int tmp = coex_dm->cur_ps_tdma; | 1752 | if (coex_dm->cur_ps_tdma == 4) { |
1656 | switch (tmp) { | 1753 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1657 | case 4: | 1754 | true, 3); |
1658 | case 3: | 1755 | coex_dm->tdma_adj_type = 3; |
1659 | case 2: | 1756 | } else if (coex_dm->cur_ps_tdma == 3) { |
1660 | case 12: | 1757 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1661 | case 11: | 1758 | true, 2); |
1662 | case 10: | 1759 | coex_dm->tdma_adj_type = 2; |
1663 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 1760 | } else if (coex_dm->cur_ps_tdma == 2) { |
1664 | true, tmp - 1); | 1761 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1665 | coex_dm->tdma_adj_type = tmp - 1; | 1762 | true, 1); |
1666 | break; | 1763 | coex_dm->tdma_adj_type = 1; |
1667 | case 1: | 1764 | } else if (coex_dm->cur_ps_tdma == 1) { |
1668 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 1765 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1669 | true, 71); | 1766 | true, 71); |
1670 | coex_dm->tdma_adj_type = 71; | 1767 | coex_dm->tdma_adj_type = 71; |
1671 | break; | 1768 | } else if (coex_dm->cur_ps_tdma == 12) { |
1769 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1770 | true, 11); | ||
1771 | coex_dm->tdma_adj_type = 11; | ||
1772 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1773 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1774 | true, 10); | ||
1775 | coex_dm->tdma_adj_type = 10; | ||
1776 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1777 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1778 | true, 9); | ||
1779 | coex_dm->tdma_adj_type = 9; | ||
1672 | } | 1780 | } |
1673 | } | 1781 | } |
1674 | } | 1782 | } |
@@ -1694,7 +1802,8 @@ static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause, | |||
1694 | } else if (coex_dm->cur_ps_tdma == 4) { | 1802 | } else if (coex_dm->cur_ps_tdma == 4) { |
1695 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); | 1803 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); |
1696 | coex_dm->tdma_adj_type = 8; | 1804 | coex_dm->tdma_adj_type = 8; |
1697 | } else if (coex_dm->cur_ps_tdma == 9) { | 1805 | } |
1806 | if (coex_dm->cur_ps_tdma == 9) { | ||
1698 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); | 1807 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); |
1699 | coex_dm->tdma_adj_type = 14; | 1808 | coex_dm->tdma_adj_type = 14; |
1700 | } else if (coex_dm->cur_ps_tdma == 10) { | 1809 | } else if (coex_dm->cur_ps_tdma == 10) { |
@@ -1776,7 +1885,8 @@ static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause, | |||
1776 | } else if (coex_dm->cur_ps_tdma == 8) { | 1885 | } else if (coex_dm->cur_ps_tdma == 8) { |
1777 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); | 1886 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); |
1778 | coex_dm->tdma_adj_type = 4; | 1887 | coex_dm->tdma_adj_type = 4; |
1779 | } else if (coex_dm->cur_ps_tdma == 13) { | 1888 | } |
1889 | if (coex_dm->cur_ps_tdma == 13) { | ||
1780 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); | 1890 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); |
1781 | coex_dm->tdma_adj_type = 10; | 1891 | coex_dm->tdma_adj_type = 10; |
1782 | } else if (coex_dm->cur_ps_tdma == 14) { | 1892 | } else if (coex_dm->cur_ps_tdma == 14) { |
@@ -1865,7 +1975,8 @@ static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause, | |||
1865 | } else if (coex_dm->cur_ps_tdma == 4) { | 1975 | } else if (coex_dm->cur_ps_tdma == 4) { |
1866 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); | 1976 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); |
1867 | coex_dm->tdma_adj_type = 8; | 1977 | coex_dm->tdma_adj_type = 8; |
1868 | } else if (coex_dm->cur_ps_tdma == 9) { | 1978 | } |
1979 | if (coex_dm->cur_ps_tdma == 9) { | ||
1869 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); | 1980 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); |
1870 | coex_dm->tdma_adj_type = 15; | 1981 | coex_dm->tdma_adj_type = 15; |
1871 | } else if (coex_dm->cur_ps_tdma == 10) { | 1982 | } else if (coex_dm->cur_ps_tdma == 10) { |
@@ -1935,101 +2046,80 @@ static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause, | |||
1935 | BTC_PRINT(BTC_MSG_ALGORITHM, | 2046 | BTC_PRINT(BTC_MSG_ALGORITHM, |
1936 | ALGO_TRACE_FW_DETAIL, | 2047 | ALGO_TRACE_FW_DETAIL, |
1937 | "[BTCoex], TxPause = 0\n"); | 2048 | "[BTCoex], TxPause = 0\n"); |
1938 | switch (coex_dm->cur_ps_tdma) { | 2049 | if (coex_dm->cur_ps_tdma == 5) { |
1939 | case 5: | ||
1940 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | 2050 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); |
1941 | coex_dm->tdma_adj_type = 3; | 2051 | coex_dm->tdma_adj_type = 3; |
1942 | break; | 2052 | } else if (coex_dm->cur_ps_tdma == 6) { |
1943 | case 6: | ||
1944 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | 2053 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); |
1945 | coex_dm->tdma_adj_type = 3; | 2054 | coex_dm->tdma_adj_type = 3; |
1946 | break; | 2055 | } else if (coex_dm->cur_ps_tdma == 7) { |
1947 | case 7: | ||
1948 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | 2056 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); |
1949 | coex_dm->tdma_adj_type = 3; | 2057 | coex_dm->tdma_adj_type = 3; |
1950 | break; | 2058 | } else if (coex_dm->cur_ps_tdma == 8) { |
1951 | case 8: | ||
1952 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); | 2059 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); |
1953 | coex_dm->tdma_adj_type = 4; | 2060 | coex_dm->tdma_adj_type = 4; |
1954 | break; | 2061 | } |
1955 | case 13: | 2062 | if (coex_dm->cur_ps_tdma == 13) { |
1956 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); | 2063 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); |
1957 | coex_dm->tdma_adj_type = 11; | 2064 | coex_dm->tdma_adj_type = 11; |
1958 | break; | 2065 | } else if (coex_dm->cur_ps_tdma == 14) { |
1959 | case 14: | ||
1960 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); | 2066 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); |
1961 | coex_dm->tdma_adj_type = 11; | 2067 | coex_dm->tdma_adj_type = 11; |
1962 | break; | 2068 | } else if (coex_dm->cur_ps_tdma == 15) { |
1963 | case 15: | ||
1964 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); | 2069 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); |
1965 | coex_dm->tdma_adj_type = 11; | 2070 | coex_dm->tdma_adj_type = 11; |
1966 | break; | 2071 | } else if (coex_dm->cur_ps_tdma == 16) { |
1967 | case 16: | ||
1968 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); | 2072 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); |
1969 | coex_dm->tdma_adj_type = 12; | 2073 | coex_dm->tdma_adj_type = 12; |
1970 | break; | ||
1971 | } | 2074 | } |
1972 | if (result == -1) { | 2075 | if (result == -1) { |
1973 | switch (coex_dm->cur_ps_tdma) { | 2076 | if (coex_dm->cur_ps_tdma == 1) { |
1974 | case 1: | ||
1975 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2077 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1976 | true, 3); | 2078 | true, 3); |
1977 | coex_dm->tdma_adj_type = 3; | 2079 | coex_dm->tdma_adj_type = 3; |
1978 | break; | 2080 | } else if (coex_dm->cur_ps_tdma == 2) { |
1979 | case 2: | ||
1980 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2081 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1981 | true, 3); | 2082 | true, 3); |
1982 | coex_dm->tdma_adj_type = 3; | 2083 | coex_dm->tdma_adj_type = 3; |
1983 | break; | 2084 | } else if (coex_dm->cur_ps_tdma == 3) { |
1984 | case 3: | ||
1985 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2085 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1986 | true, 4); | 2086 | true, 4); |
1987 | coex_dm->tdma_adj_type = 4; | 2087 | coex_dm->tdma_adj_type = 4; |
1988 | break; | 2088 | } else if (coex_dm->cur_ps_tdma == 9) { |
1989 | case 9: | ||
1990 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2089 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1991 | true, 11); | 2090 | true, 11); |
1992 | coex_dm->tdma_adj_type = 11; | 2091 | coex_dm->tdma_adj_type = 11; |
1993 | break; | 2092 | } else if (coex_dm->cur_ps_tdma == 10) { |
1994 | case 10: | ||
1995 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2093 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
1996 | true, 11); | 2094 | true, 11); |
1997 | coex_dm->tdma_adj_type = 11; | 2095 | coex_dm->tdma_adj_type = 11; |
1998 | break; | 2096 | } else if (coex_dm->cur_ps_tdma == 11) { |
1999 | case 11: | ||
2000 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2097 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2001 | true, 12); | 2098 | true, 12); |
2002 | coex_dm->tdma_adj_type = 12; | 2099 | coex_dm->tdma_adj_type = 12; |
2003 | break; | ||
2004 | } | 2100 | } |
2005 | } else if (result == 1) { | 2101 | } else if (result == 1) { |
2006 | switch (coex_dm->cur_ps_tdma) { | 2102 | if (coex_dm->cur_ps_tdma == 4) { |
2007 | case 4: | ||
2008 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2103 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2009 | true, 3); | 2104 | true, 3); |
2010 | coex_dm->tdma_adj_type = 3; | 2105 | coex_dm->tdma_adj_type = 3; |
2011 | break; | 2106 | } else if (coex_dm->cur_ps_tdma == 3) { |
2012 | case 3: | ||
2013 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2107 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2014 | true, 3); | 2108 | true, 3); |
2015 | coex_dm->tdma_adj_type = 3; | 2109 | coex_dm->tdma_adj_type = 3; |
2016 | break; | 2110 | } else if (coex_dm->cur_ps_tdma == 2) { |
2017 | case 2: | ||
2018 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2111 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2019 | true, 3); | 2112 | true, 3); |
2020 | coex_dm->tdma_adj_type = 3; | 2113 | coex_dm->tdma_adj_type = 3; |
2021 | break; | 2114 | } else if (coex_dm->cur_ps_tdma == 12) { |
2022 | case 12: | ||
2023 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2115 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2024 | true, 11); | 2116 | true, 11); |
2025 | coex_dm->tdma_adj_type = 11; | 2117 | coex_dm->tdma_adj_type = 11; |
2026 | break; | 2118 | } else if (coex_dm->cur_ps_tdma == 11) { |
2027 | case 11: | ||
2028 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2119 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2029 | true, 11); | 2120 | true, 11); |
2030 | coex_dm->tdma_adj_type = 11; | 2121 | coex_dm->tdma_adj_type = 11; |
2031 | break; | 2122 | } else if (coex_dm->cur_ps_tdma == 10) { |
2032 | case 10: | ||
2033 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, | 2123 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, |
2034 | true, 11); | 2124 | true, 11); |
2035 | coex_dm->tdma_adj_type = 11; | 2125 | coex_dm->tdma_adj_type = 11; |
@@ -2328,7 +2418,7 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist) | |||
2328 | 2418 | ||
2329 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2419 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2330 | 0, 2, 15, 0); | 2420 | 0, 2, 15, 0); |
2331 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2421 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2332 | 2422 | ||
2333 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2423 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2334 | 2424 | ||
@@ -2385,12 +2475,43 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist) | |||
2385 | /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ | 2475 | /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ |
2386 | static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) | 2476 | static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) |
2387 | { | 2477 | { |
2388 | u8 wifi_rssi_state, bt_rssi_state; | 2478 | u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state; |
2389 | u32 wifi_bw; | 2479 | u32 wifi_bw; |
2480 | u8 ap_num = 0; | ||
2390 | 2481 | ||
2391 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2482 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2392 | 0, 2, 15, 0); | 2483 | 0, 2, 15, 0); |
2393 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2484 | wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist, |
2485 | 1, 2, 40, 0); | ||
2486 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); | ||
2487 | |||
2488 | btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); | ||
2489 | |||
2490 | /* define the office environment */ | ||
2491 | /* driver don't know AP num in Linux, so we will never enter this if */ | ||
2492 | if (ap_num >= 10 && BTC_RSSI_HIGH(wifi_rssi_state1)) { | ||
2493 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, | ||
2494 | 0x0); | ||
2495 | btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2496 | btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2497 | btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0); | ||
2498 | btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
2499 | |||
2500 | /* sw mechanism */ | ||
2501 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2502 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2503 | btc8723b2ant_sw_mechanism1(btcoexist, true, false, | ||
2504 | false, false); | ||
2505 | btc8723b2ant_sw_mechanism2(btcoexist, true, false, | ||
2506 | true, 0x18); | ||
2507 | } else { | ||
2508 | btc8723b2ant_sw_mechanism1(btcoexist, false, false, | ||
2509 | false, false); | ||
2510 | btc8723b2ant_sw_mechanism2(btcoexist, true, false, | ||
2511 | true, 0x18); | ||
2512 | } | ||
2513 | return; | ||
2514 | } | ||
2394 | 2515 | ||
2395 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2516 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2396 | 2517 | ||
@@ -2501,7 +2622,7 @@ static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist) | |||
2501 | 2622 | ||
2502 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2623 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2503 | 0, 2, 15, 0); | 2624 | 0, 2, 15, 0); |
2504 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2625 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2505 | 2626 | ||
2506 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2627 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2507 | 2628 | ||
@@ -2612,7 +2733,7 @@ static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) | |||
2612 | 2733 | ||
2613 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2734 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2614 | 0, 2, 15, 0); | 2735 | 0, 2, 15, 0); |
2615 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2736 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2616 | 2737 | ||
2617 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2738 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2618 | 2739 | ||
@@ -2676,7 +2797,7 @@ static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) | |||
2676 | 2797 | ||
2677 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2798 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2678 | 0, 2, 15, 0); | 2799 | 0, 2, 15, 0); |
2679 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2800 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2680 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | 2801 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); |
2681 | 2802 | ||
2682 | if (btc8723b_need_dec_pwr(btcoexist)) | 2803 | if (btc8723b_need_dec_pwr(btcoexist)) |
@@ -2746,7 +2867,7 @@ static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) | |||
2746 | 2867 | ||
2747 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2868 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2748 | 0, 2, 15, 0); | 2869 | 0, 2, 15, 0); |
2749 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2870 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2750 | 2871 | ||
2751 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2872 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2752 | 2873 | ||
@@ -2809,8 +2930,8 @@ static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist) | |||
2809 | u32 wifi_bw; | 2930 | u32 wifi_bw; |
2810 | 2931 | ||
2811 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, | 2932 | wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, |
2812 | 0, 2, 15, 0); | 2933 | 0, 2, 15, 0); |
2813 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); | 2934 | bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0); |
2814 | 2935 | ||
2815 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); | 2936 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); |
2816 | 2937 | ||
@@ -2982,7 +3103,15 @@ static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | |||
2982 | } | 3103 | } |
2983 | } | 3104 | } |
2984 | 3105 | ||
2985 | 3106 | static void btc8723b2ant_wifioff_hwcfg(struct btc_coexist *btcoexist) | |
3107 | { | ||
3108 | /* set wlan_act to low */ | ||
3109 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4); | ||
3110 | /* Force GNT_BT to High */ | ||
3111 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3); | ||
3112 | /* BT select s0/s1 is controlled by BT */ | ||
3113 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0); | ||
3114 | } | ||
2986 | 3115 | ||
2987 | /********************************************************************* | 3116 | /********************************************************************* |
2988 | * work around function start with wa_btc8723b2ant_ | 3117 | * work around function start with wa_btc8723b2ant_ |
@@ -2990,98 +3119,24 @@ static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | |||
2990 | /********************************************************************* | 3119 | /********************************************************************* |
2991 | * extern function start with EXbtc8723b2ant_ | 3120 | * extern function start with EXbtc8723b2ant_ |
2992 | *********************************************************************/ | 3121 | *********************************************************************/ |
2993 | void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) | 3122 | void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) |
2994 | { | 3123 | { |
2995 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
2996 | u32 u32tmp = 0, fw_ver; | ||
2997 | u8 u8tmp = 0; | 3124 | u8 u8tmp = 0; |
2998 | u8 h2c_parameter[2] = {0}; | ||
2999 | |||
3000 | 3125 | ||
3001 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | 3126 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, |
3002 | "[BTCoex], 2Ant Init HW Config!!\n"); | 3127 | "[BTCoex], 2Ant Init HW Config!!\n"); |
3128 | coex_dm->bt_rf0x1e_backup = | ||
3129 | btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff); | ||
3003 | 3130 | ||
3004 | /* backup rf 0x1e value */ | 3131 | /* 0x790[5:0] = 0x5 */ |
3005 | coex_dm->bt_rf0x1e_backup = btcoexist->btc_get_rf_reg(btcoexist, | ||
3006 | BTC_RF_A, 0x1e, | ||
3007 | 0xfffff); | ||
3008 | |||
3009 | /* 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT */ | ||
3010 | u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
3011 | u32tmp &= ~BIT23; | ||
3012 | u32tmp |= BIT24; | ||
3013 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp); | ||
3014 | |||
3015 | btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff); | ||
3016 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3); | ||
3017 | btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77); | ||
3018 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1); | ||
3019 | |||
3020 | /* Antenna switch control parameter */ | ||
3021 | /* btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);*/ | ||
3022 | |||
3023 | /*Force GNT_BT to low*/ | ||
3024 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0); | ||
3025 | btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0); | ||
3026 | |||
3027 | /* 0x790[5:0]=0x5 */ | ||
3028 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); | 3132 | u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); |
3029 | u8tmp &= 0xc0; | 3133 | u8tmp &= 0xc0; |
3030 | u8tmp |= 0x5; | 3134 | u8tmp |= 0x5; |
3031 | btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); | 3135 | btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); |
3032 | 3136 | ||
3033 | 3137 | /*Antenna config */ | |
3034 | /*Antenna config */ | 3138 | btc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN, |
3035 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | 3139 | true, false); |
3036 | |||
3037 | /*ext switch for fw ver < 0xc */ | ||
3038 | if (fw_ver < 0xc00) { | ||
3039 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { | ||
3040 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, | ||
3041 | 0x3, 0x1); | ||
3042 | /*Main Ant to BT for IPS case 0x4c[23]=1*/ | ||
3043 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, | ||
3044 | 0x1); | ||
3045 | |||
3046 | /*tell firmware "no antenna inverse"*/ | ||
3047 | h2c_parameter[0] = 0; | ||
3048 | h2c_parameter[1] = 1; /* ext switch type */ | ||
3049 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
3050 | h2c_parameter); | ||
3051 | } else { | ||
3052 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, | ||
3053 | 0x3, 0x2); | ||
3054 | /*Aux Ant to BT for IPS case 0x4c[23]=1*/ | ||
3055 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, | ||
3056 | 0x0); | ||
3057 | |||
3058 | /*tell firmware "antenna inverse"*/ | ||
3059 | h2c_parameter[0] = 1; | ||
3060 | h2c_parameter[1] = 1; /*ext switch type*/ | ||
3061 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
3062 | h2c_parameter); | ||
3063 | } | ||
3064 | } else { | ||
3065 | /*ext switch always at s1 (if exist) */ | ||
3066 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1); | ||
3067 | /*Main Ant to BT for IPS case 0x4c[23]=1*/ | ||
3068 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x1); | ||
3069 | |||
3070 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { | ||
3071 | /*tell firmware "no antenna inverse"*/ | ||
3072 | h2c_parameter[0] = 0; | ||
3073 | h2c_parameter[1] = 0; /*ext switch type*/ | ||
3074 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
3075 | h2c_parameter); | ||
3076 | } else { | ||
3077 | /*tell firmware "antenna inverse"*/ | ||
3078 | h2c_parameter[0] = 1; | ||
3079 | h2c_parameter[1] = 0; /*ext switch type*/ | ||
3080 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
3081 | h2c_parameter); | ||
3082 | } | ||
3083 | } | ||
3084 | |||
3085 | /* PTA parameter */ | 3140 | /* PTA parameter */ |
3086 | btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0); | 3141 | btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0); |
3087 | 3142 | ||
@@ -3092,19 +3147,19 @@ void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) | |||
3092 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); | 3147 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); |
3093 | } | 3148 | } |
3094 | 3149 | ||
3095 | void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) | 3150 | void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) |
3096 | { | 3151 | { |
3097 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | 3152 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, |
3098 | "[BTCoex], Coex Mechanism Init!!\n"); | 3153 | "[BTCoex], Coex Mechanism Init!!\n"); |
3099 | btc8723b2ant_init_coex_dm(btcoexist); | 3154 | btc8723b2ant_init_coex_dm(btcoexist); |
3100 | } | 3155 | } |
3101 | 3156 | ||
3102 | void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) | 3157 | void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) |
3103 | { | 3158 | { |
3104 | struct btc_board_info *board_info = &btcoexist->board_info; | 3159 | struct btc_board_info *board_info = &btcoexist->board_info; |
3105 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | 3160 | struct btc_stack_info *stack_info = &btcoexist->stack_info; |
3106 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | 3161 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; |
3107 | u8 *cli_buf = btcoexist->cli_buf; | 3162 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
3108 | u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; | 3163 | u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; |
3109 | u32 u32tmp[4]; | 3164 | u32 u32tmp[4]; |
3110 | bool roam = false, scan = false; | 3165 | bool roam = false, scan = false; |
@@ -3114,106 +3169,93 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) | |||
3114 | u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; | 3169 | u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; |
3115 | u8 wifi_dot11_chnl, wifi_hs_chnl; | 3170 | u8 wifi_dot11_chnl, wifi_hs_chnl; |
3116 | u32 fw_ver = 0, bt_patch_ver = 0; | 3171 | u32 fw_ver = 0, bt_patch_ver = 0; |
3172 | u8 ap_num = 0; | ||
3117 | 3173 | ||
3118 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3174 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3119 | "\r\n ============[BT Coexist info]============"); | 3175 | "\r\n ============[BT Coexist info]============"); |
3120 | CL_PRINTF(cli_buf); | ||
3121 | 3176 | ||
3122 | if (btcoexist->manual_control) { | 3177 | if (btcoexist->manual_control) { |
3123 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3178 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3124 | "\r\n ==========[Under Manual Control]============"); | 3179 | "\r\n ==========[Under Manual Control]============"); |
3125 | CL_PRINTF(cli_buf); | 3180 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3126 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | ||
3127 | "\r\n =========================================="); | 3181 | "\r\n =========================================="); |
3128 | CL_PRINTF(cli_buf); | ||
3129 | } | 3182 | } |
3130 | 3183 | ||
3131 | if (!board_info->bt_exist) { | 3184 | if (!board_info->bt_exist) { |
3132 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!"); | 3185 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!"); |
3133 | CL_PRINTF(cli_buf); | ||
3134 | return; | 3186 | return; |
3135 | } | 3187 | } |
3136 | 3188 | ||
3137 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", | 3189 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ", |
3138 | "Ant PG number/ Ant mechanism:", | 3190 | "Ant PG number/ Ant mechanism:", |
3139 | board_info->pg_ant_num, board_info->btdm_ant_num); | 3191 | board_info->pg_ant_num, board_info->btdm_ant_num); |
3140 | CL_PRINTF(cli_buf); | ||
3141 | 3192 | ||
3142 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", | 3193 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d", |
3143 | "BT stack/ hci ext ver", | 3194 | "BT stack/ hci ext ver", |
3144 | ((stack_info->profile_notified) ? "Yes" : "No"), | 3195 | ((stack_info->profile_notified) ? "Yes" : "No"), |
3145 | stack_info->hci_version); | 3196 | stack_info->hci_version); |
3146 | CL_PRINTF(cli_buf); | ||
3147 | 3197 | ||
3148 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); | 3198 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); |
3149 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | 3199 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); |
3150 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3200 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3151 | "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", | 3201 | "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", |
3152 | "CoexVer/ FwVer/ PatchVer", | 3202 | "CoexVer/ FwVer/ PatchVer", |
3153 | glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, | 3203 | glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, |
3154 | fw_ver, bt_patch_ver, bt_patch_ver); | 3204 | fw_ver, bt_patch_ver, bt_patch_ver); |
3155 | CL_PRINTF(cli_buf); | ||
3156 | 3205 | ||
3157 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | 3206 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); |
3158 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, | 3207 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, |
3159 | &wifi_dot11_chnl); | 3208 | &wifi_dot11_chnl); |
3160 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); | 3209 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); |
3161 | 3210 | ||
3162 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", | 3211 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)", |
3163 | "Dot11 channel / HsChnl(HsMode)", | 3212 | "Dot11 channel / HsChnl(HsMode)", |
3164 | wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); | 3213 | wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); |
3165 | CL_PRINTF(cli_buf); | ||
3166 | 3214 | ||
3167 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", | 3215 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ", |
3168 | "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], | 3216 | "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], |
3169 | coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); | 3217 | coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); |
3170 | CL_PRINTF(cli_buf); | ||
3171 | 3218 | ||
3172 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | 3219 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); |
3173 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); | 3220 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); |
3174 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", | 3221 | btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num); |
3175 | "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); | 3222 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d", |
3176 | CL_PRINTF(cli_buf); | 3223 | "Wifi rssi/ HS rssi/ AP#", wifi_rssi, bt_hs_rssi, ap_num); |
3177 | 3224 | ||
3178 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | 3225 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); |
3179 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | 3226 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); |
3180 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | 3227 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); |
3181 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", | 3228 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ", |
3182 | "Wifi link/ roam/ scan", link, roam, scan); | 3229 | "Wifi link/ roam/ scan", link, roam, scan); |
3183 | CL_PRINTF(cli_buf); | ||
3184 | 3230 | ||
3185 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | 3231 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); |
3186 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | 3232 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); |
3187 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | 3233 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); |
3188 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, | 3234 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, |
3189 | &wifi_traffic_dir); | 3235 | &wifi_traffic_dir); |
3190 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", | 3236 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ", |
3191 | "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), | 3237 | "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), |
3192 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : | 3238 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : |
3193 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), | 3239 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), |
3194 | ((!wifi_busy) ? "idle" : | 3240 | ((!wifi_busy) ? "idle" : |
3195 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? | 3241 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? |
3196 | "uplink" : "downlink"))); | 3242 | "uplink" : "downlink"))); |
3197 | CL_PRINTF(cli_buf); | ||
3198 | 3243 | ||
3199 | CL_PRINTF(cli_buf); | ||
3200 | 3244 | ||
3201 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", | 3245 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d", |
3202 | "SCO/HID/PAN/A2DP", | 3246 | "SCO/HID/PAN/A2DP", |
3203 | bt_link_info->sco_exist, bt_link_info->hid_exist, | 3247 | bt_link_info->sco_exist, bt_link_info->hid_exist, |
3204 | bt_link_info->pan_exist, bt_link_info->a2dp_exist); | 3248 | bt_link_info->pan_exist, bt_link_info->a2dp_exist); |
3205 | CL_PRINTF(cli_buf); | ||
3206 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); | 3249 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); |
3207 | 3250 | ||
3208 | bt_info_ext = coex_sta->bt_info_ext; | 3251 | bt_info_ext = coex_sta->bt_info_ext; |
3209 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", | 3252 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s", |
3210 | "BT Info A2DP rate", | 3253 | "BT Info A2DP rate", |
3211 | (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); | 3254 | (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); |
3212 | CL_PRINTF(cli_buf); | ||
3213 | 3255 | ||
3214 | for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { | 3256 | for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { |
3215 | if (coex_sta->bt_info_c2h_cnt[i]) { | 3257 | if (coex_sta->bt_info_c2h_cnt[i]) { |
3216 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3258 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3217 | "\r\n %-35s = %02x %02x %02x " | 3259 | "\r\n %-35s = %02x %02x %02x " |
3218 | "%02x %02x %02x %02x(%d)", | 3260 | "%02x %02x %02x %02x(%d)", |
3219 | glbt_info_src_8723b_2ant[i], | 3261 | glbt_info_src_8723b_2ant[i], |
@@ -3225,105 +3267,88 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) | |||
3225 | coex_sta->bt_info_c2h[i][5], | 3267 | coex_sta->bt_info_c2h[i][5], |
3226 | coex_sta->bt_info_c2h[i][6], | 3268 | coex_sta->bt_info_c2h[i][6], |
3227 | coex_sta->bt_info_c2h_cnt[i]); | 3269 | coex_sta->bt_info_c2h_cnt[i]); |
3228 | CL_PRINTF(cli_buf); | ||
3229 | } | 3270 | } |
3230 | } | 3271 | } |
3231 | 3272 | ||
3232 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", | 3273 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s", |
3233 | "PS state, IPS/LPS", | 3274 | "PS state, IPS/LPS", |
3234 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), | 3275 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), |
3235 | ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); | 3276 | ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); |
3236 | CL_PRINTF(cli_buf); | ||
3237 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); | 3277 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); |
3238 | 3278 | ||
3239 | /* Sw mechanism */ | 3279 | /* Sw mechanism */ |
3240 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3280 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3241 | "\r\n %-35s", "============[Sw mechanism]============"); | 3281 | "\r\n %-35s", "============[Sw mechanism]============"); |
3242 | CL_PRINTF(cli_buf); | 3282 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ", |
3243 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", | ||
3244 | "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, | 3283 | "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, |
3245 | coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); | 3284 | coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); |
3246 | CL_PRINTF(cli_buf); | 3285 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ", |
3247 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", | ||
3248 | "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", | 3286 | "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", |
3249 | coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, | 3287 | coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, |
3250 | coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); | 3288 | coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); |
3251 | CL_PRINTF(cli_buf); | ||
3252 | 3289 | ||
3253 | /* Fw mechanism */ | 3290 | /* Fw mechanism */ |
3254 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", | 3291 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", |
3255 | "============[Fw mechanism]============"); | 3292 | "============[Fw mechanism]============"); |
3256 | CL_PRINTF(cli_buf); | ||
3257 | 3293 | ||
3258 | ps_tdma_case = coex_dm->cur_ps_tdma; | 3294 | ps_tdma_case = coex_dm->cur_ps_tdma; |
3259 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3295 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3260 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", | 3296 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", |
3261 | "PS TDMA", coex_dm->ps_tdma_para[0], | 3297 | "PS TDMA", coex_dm->ps_tdma_para[0], |
3262 | coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], | 3298 | coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], |
3263 | coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], | 3299 | coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], |
3264 | ps_tdma_case, coex_dm->auto_tdma_adjust); | 3300 | ps_tdma_case, coex_dm->auto_tdma_adjust); |
3265 | CL_PRINTF(cli_buf); | ||
3266 | 3301 | ||
3267 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", | 3302 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ", |
3268 | "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr, | 3303 | "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr, |
3269 | coex_dm->cur_ignore_wlan_act); | 3304 | coex_dm->cur_ignore_wlan_act); |
3270 | CL_PRINTF(cli_buf); | ||
3271 | 3305 | ||
3272 | /* Hw setting */ | 3306 | /* Hw setting */ |
3273 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", | 3307 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", |
3274 | "============[Hw setting]============"); | 3308 | "============[Hw setting]============"); |
3275 | CL_PRINTF(cli_buf); | ||
3276 | 3309 | ||
3277 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", | 3310 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", |
3278 | "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); | 3311 | "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); |
3279 | CL_PRINTF(cli_buf); | ||
3280 | 3312 | ||
3281 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); | 3313 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); |
3282 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); | 3314 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); |
3283 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", | 3315 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", |
3284 | "0x778/0x880[29:25]", u8tmp[0], | 3316 | "0x778/0x880[29:25]", u8tmp[0], |
3285 | (u32tmp[0]&0x3e000000) >> 25); | 3317 | (u32tmp[0]&0x3e000000) >> 25); |
3286 | CL_PRINTF(cli_buf); | ||
3287 | 3318 | ||
3288 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); | 3319 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); |
3289 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); | 3320 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); |
3290 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); | 3321 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); |
3291 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | 3322 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", |
3292 | "0x948/ 0x67[5] / 0x765", | 3323 | "0x948/ 0x67[5] / 0x765", |
3293 | u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]); | 3324 | u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]); |
3294 | CL_PRINTF(cli_buf); | ||
3295 | 3325 | ||
3296 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); | 3326 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); |
3297 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); | 3327 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); |
3298 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); | 3328 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); |
3299 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | 3329 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", |
3300 | "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", | 3330 | "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", |
3301 | u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3); | 3331 | u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3); |
3302 | CL_PRINTF(cli_buf); | ||
3303 | |||
3304 | 3332 | ||
3305 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); | 3333 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); |
3306 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); | 3334 | u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); |
3307 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); | 3335 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); |
3308 | u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); | 3336 | u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); |
3309 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3337 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3310 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", | 3338 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", |
3311 | "0x38[11]/0x40/0x4c[24:23]/0x64[0]", | 3339 | "0x38[11]/0x40/0x4c[24:23]/0x64[0]", |
3312 | ((u8tmp[0] & 0x8)>>3), u8tmp[1], | 3340 | ((u8tmp[0] & 0x8)>>3), u8tmp[1], |
3313 | ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1); | 3341 | ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1); |
3314 | CL_PRINTF(cli_buf); | ||
3315 | 3342 | ||
3316 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); | 3343 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); |
3317 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); | 3344 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); |
3318 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", | 3345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", |
3319 | "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); | 3346 | "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); |
3320 | CL_PRINTF(cli_buf); | ||
3321 | 3347 | ||
3322 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); | 3348 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); |
3323 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); | 3349 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); |
3324 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", | 3350 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", |
3325 | "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]); | 3351 | "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]); |
3326 | CL_PRINTF(cli_buf); | ||
3327 | 3352 | ||
3328 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); | 3353 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); |
3329 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); | 3354 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); |
@@ -3341,29 +3366,25 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) | |||
3341 | (u32tmp[3] & 0xffff); | 3366 | (u32tmp[3] & 0xffff); |
3342 | fa_cck = (u8tmp[0] << 8) + u8tmp[1]; | 3367 | fa_cck = (u8tmp[0] << 8) + u8tmp[1]; |
3343 | 3368 | ||
3344 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | 3369 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", |
3345 | "OFDM-CCA/OFDM-FA/CCK-FA", | 3370 | "OFDM-CCA/OFDM-FA/CCK-FA", |
3346 | u32tmp[0]&0xffff, fa_ofdm, fa_cck); | 3371 | u32tmp[0]&0xffff, fa_ofdm, fa_cck); |
3347 | CL_PRINTF(cli_buf); | ||
3348 | 3372 | ||
3349 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); | 3373 | u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); |
3350 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); | 3374 | u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); |
3351 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); | 3375 | u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); |
3352 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); | 3376 | u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); |
3353 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, | 3377 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, |
3354 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", | 3378 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", |
3355 | "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", | 3379 | "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", |
3356 | u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); | 3380 | u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); |
3357 | CL_PRINTF(cli_buf); | ||
3358 | 3381 | ||
3359 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", | 3382 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", |
3360 | "0x770(high-pri rx/tx)", | 3383 | "0x770(high-pri rx/tx)", |
3361 | coex_sta->high_priority_rx, coex_sta->high_priority_tx); | 3384 | coex_sta->high_priority_rx, coex_sta->high_priority_tx); |
3362 | CL_PRINTF(cli_buf); | 3385 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", |
3363 | CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", | ||
3364 | "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, | 3386 | "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, |
3365 | coex_sta->low_priority_tx); | 3387 | coex_sta->low_priority_tx); |
3366 | CL_PRINTF(cli_buf); | ||
3367 | #if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) | 3388 | #if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) |
3368 | btc8723b2ant_monitor_bt_ctr(btcoexist); | 3389 | btc8723b2ant_monitor_bt_ctr(btcoexist); |
3369 | #endif | 3390 | #endif |
@@ -3371,22 +3392,26 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) | |||
3371 | BTC_DBG_DISP_COEX_STATISTICS); | 3392 | BTC_DBG_DISP_COEX_STATISTICS); |
3372 | } | 3393 | } |
3373 | 3394 | ||
3374 | 3395 | void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | |
3375 | void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | ||
3376 | { | 3396 | { |
3377 | if (BTC_IPS_ENTER == type) { | 3397 | if (BTC_IPS_ENTER == type) { |
3378 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3398 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
3379 | "[BTCoex], IPS ENTER notify\n"); | 3399 | "[BTCoex], IPS ENTER notify\n"); |
3380 | coex_sta->under_ips = true; | 3400 | coex_sta->under_ips = true; |
3401 | btc8723b2ant_wifioff_hwcfg(btcoexist); | ||
3402 | btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | ||
3381 | btc8723b2ant_coex_alloff(btcoexist); | 3403 | btc8723b2ant_coex_alloff(btcoexist); |
3382 | } else if (BTC_IPS_LEAVE == type) { | 3404 | } else if (BTC_IPS_LEAVE == type) { |
3383 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3405 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
3384 | "[BTCoex], IPS LEAVE notify\n"); | 3406 | "[BTCoex], IPS LEAVE notify\n"); |
3385 | coex_sta->under_ips = false; | 3407 | coex_sta->under_ips = false; |
3408 | ex_btc8723b2ant_init_hwconfig(btcoexist); | ||
3409 | btc8723b2ant_init_coex_dm(btcoexist); | ||
3410 | btc8723b2ant_query_bt_info(btcoexist); | ||
3386 | } | 3411 | } |
3387 | } | 3412 | } |
3388 | 3413 | ||
3389 | void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | 3414 | void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) |
3390 | { | 3415 | { |
3391 | if (BTC_LPS_ENABLE == type) { | 3416 | if (BTC_LPS_ENABLE == type) { |
3392 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3417 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
@@ -3399,7 +3424,7 @@ void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | |||
3399 | } | 3424 | } |
3400 | } | 3425 | } |
3401 | 3426 | ||
3402 | void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | 3427 | void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) |
3403 | { | 3428 | { |
3404 | if (BTC_SCAN_START == type) | 3429 | if (BTC_SCAN_START == type) |
3405 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3430 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
@@ -3409,7 +3434,7 @@ void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | |||
3409 | "[BTCoex], SCAN FINISH notify\n"); | 3434 | "[BTCoex], SCAN FINISH notify\n"); |
3410 | } | 3435 | } |
3411 | 3436 | ||
3412 | void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | 3437 | void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) |
3413 | { | 3438 | { |
3414 | if (BTC_ASSOCIATE_START == type) | 3439 | if (BTC_ASSOCIATE_START == type) |
3415 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3440 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
@@ -3419,8 +3444,8 @@ void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | |||
3419 | "[BTCoex], CONNECT FINISH notify\n"); | 3444 | "[BTCoex], CONNECT FINISH notify\n"); |
3420 | } | 3445 | } |
3421 | 3446 | ||
3422 | void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, | 3447 | void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist, |
3423 | u8 type) | 3448 | u8 type) |
3424 | { | 3449 | { |
3425 | u8 h2c_parameter[3] = {0}; | 3450 | u8 h2c_parameter[3] = {0}; |
3426 | u32 wifi_bw; | 3451 | u32 wifi_bw; |
@@ -3460,16 +3485,16 @@ void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, | |||
3460 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); | 3485 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); |
3461 | } | 3486 | } |
3462 | 3487 | ||
3463 | void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, | 3488 | void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, |
3464 | u8 type) | 3489 | u8 type) |
3465 | { | 3490 | { |
3466 | if (type == BTC_PACKET_DHCP) | 3491 | if (type == BTC_PACKET_DHCP) |
3467 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | 3492 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, |
3468 | "[BTCoex], DHCP Packet notify\n"); | 3493 | "[BTCoex], DHCP Packet notify\n"); |
3469 | } | 3494 | } |
3470 | 3495 | ||
3471 | void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | 3496 | void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, |
3472 | u8 *tmpbuf, u8 length) | 3497 | u8 *tmpbuf, u8 length) |
3473 | { | 3498 | { |
3474 | u8 bt_info = 0; | 3499 | u8 bt_info = 0; |
3475 | u8 i, rsp_source = 0; | 3500 | u8 i, rsp_source = 0; |
@@ -3516,7 +3541,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | |||
3516 | coex_sta->bt_info_c2h[rsp_source][4]; | 3541 | coex_sta->bt_info_c2h[rsp_source][4]; |
3517 | 3542 | ||
3518 | /* Here we need to resend some wifi info to BT | 3543 | /* Here we need to resend some wifi info to BT |
3519 | * because bt is reset and loss of the info. | 3544 | because bt is reset and loss of the info. |
3520 | */ | 3545 | */ |
3521 | if ((coex_sta->bt_info_ext & BIT1)) { | 3546 | if ((coex_sta->bt_info_ext & BIT1)) { |
3522 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | 3547 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, |
@@ -3525,11 +3550,13 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | |||
3525 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | 3550 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, |
3526 | &wifi_connected); | 3551 | &wifi_connected); |
3527 | if (wifi_connected) | 3552 | if (wifi_connected) |
3528 | btc8723b_med_stat_notify(btcoexist, | 3553 | ex_btc8723b2ant_media_status_notify( |
3529 | BTC_MEDIA_CONNECT); | 3554 | btcoexist, |
3555 | BTC_MEDIA_CONNECT); | ||
3530 | else | 3556 | else |
3531 | btc8723b_med_stat_notify(btcoexist, | 3557 | ex_btc8723b2ant_media_status_notify( |
3532 | BTC_MEDIA_DISCONNECT); | 3558 | btcoexist, |
3559 | BTC_MEDIA_DISCONNECT); | ||
3533 | } | 3560 | } |
3534 | 3561 | ||
3535 | if ((coex_sta->bt_info_ext & BIT3)) { | 3562 | if ((coex_sta->bt_info_ext & BIT3)) { |
@@ -3564,7 +3591,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | |||
3564 | coex_sta->a2dp_exist = false; | 3591 | coex_sta->a2dp_exist = false; |
3565 | coex_sta->hid_exist = false; | 3592 | coex_sta->hid_exist = false; |
3566 | coex_sta->sco_exist = false; | 3593 | coex_sta->sco_exist = false; |
3567 | } else { /* connection exists */ | 3594 | } else { /* connection exists */ |
3568 | coex_sta->bt_link_exist = true; | 3595 | coex_sta->bt_link_exist = true; |
3569 | if (bt_info & BT_INFO_8723B_2ANT_B_FTP) | 3596 | if (bt_info & BT_INFO_8723B_2ANT_B_FTP) |
3570 | coex_sta->pan_exist = true; | 3597 | coex_sta->pan_exist = true; |
@@ -3601,7 +3628,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | |||
3601 | coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; | 3628 | coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; |
3602 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | 3629 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, |
3603 | "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); | 3630 | "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); |
3604 | } else if (bt_info & BT_INFO_8723B_2ANT_B_ACL_BUSY) { | 3631 | } else if (bt_info&BT_INFO_8723B_2ANT_B_ACL_BUSY) { |
3605 | coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; | 3632 | coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; |
3606 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | 3633 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, |
3607 | "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); | 3634 | "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); |
@@ -3630,26 +3657,16 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | |||
3630 | btc8723b2ant_run_coexist_mechanism(btcoexist); | 3657 | btc8723b2ant_run_coexist_mechanism(btcoexist); |
3631 | } | 3658 | } |
3632 | 3659 | ||
3633 | void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, | 3660 | void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist) |
3634 | u8 type) | ||
3635 | { | ||
3636 | if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type) | ||
3637 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3638 | "[BTCoex],StackOP Inquiry/page/pair start notify\n"); | ||
3639 | else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type) | ||
3640 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3641 | "[BTCoex],StackOP Inquiry/page/pair finish notify\n"); | ||
3642 | } | ||
3643 | |||
3644 | void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist) | ||
3645 | { | 3661 | { |
3646 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); | 3662 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); |
3647 | 3663 | ||
3664 | btc8723b2ant_wifioff_hwcfg(btcoexist); | ||
3648 | btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | 3665 | btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); |
3649 | btc8723b_med_stat_notify(btcoexist, BTC_MEDIA_DISCONNECT); | 3666 | ex_btc8723b2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); |
3650 | } | 3667 | } |
3651 | 3668 | ||
3652 | void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist) | 3669 | void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist) |
3653 | { | 3670 | { |
3654 | struct btc_board_info *board_info = &btcoexist->board_info; | 3671 | struct btc_board_info *board_info = &btcoexist->board_info; |
3655 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | 3672 | struct btc_stack_info *stack_info = &btcoexist->stack_info; |
@@ -3677,8 +3694,7 @@ void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist) | |||
3677 | &bt_patch_ver); | 3694 | &bt_patch_ver); |
3678 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | 3695 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); |
3679 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | 3696 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, |
3680 | "[BTCoex], CoexVer/ FwVer/ PatchVer = " | 3697 | "[BTCoex], CoexVer/ fw_ver/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", |
3681 | "%d_%x/ 0x%x/ 0x%x(%d)\n", | ||
3682 | glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, | 3698 | glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, |
3683 | fw_ver, bt_patch_ver, bt_patch_ver); | 3699 | fw_ver, bt_patch_ver, bt_patch_ver); |
3684 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | 3700 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h index e0ad8e545f82..567f354caf95 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h | |||
@@ -153,21 +153,20 @@ struct coex_sta_8723b_2ant { | |||
153 | /********************************************************************* | 153 | /********************************************************************* |
154 | * The following is interface which will notify coex module. | 154 | * The following is interface which will notify coex module. |
155 | *********************************************************************/ | 155 | *********************************************************************/ |
156 | void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); | 156 | void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); |
157 | void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); | 157 | void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); |
158 | void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); | 158 | void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); |
159 | void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); | 159 | void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); |
160 | void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); | 160 | void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); |
161 | void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); | 161 | void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); |
162 | void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, u8 type); | 162 | void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist, |
163 | void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, | 163 | u8 type); |
164 | u8 type); | 164 | void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, |
165 | void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, | 165 | u8 type); |
166 | u8 *tmpbuf, u8 length); | 166 | void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, |
167 | void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, | 167 | u8 *tmpbuf, u8 length); |
168 | u8 type); | 168 | void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist); |
169 | void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist); | 169 | void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist); |
170 | void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist); | 170 | void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist); |
171 | void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist); | ||
172 | 171 | ||
173 | #endif | 172 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c new file mode 100644 index 000000000000..b72e5377bdbc --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c | |||
@@ -0,0 +1,2970 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | /*============================================================ | ||
27 | * Description: | ||
28 | * | ||
29 | * This file is for RTL8821A Co-exist mechanism | ||
30 | * | ||
31 | * History | ||
32 | * 2012/11/15 Cosa first check in. | ||
33 | * | ||
34 | *============================================================ | ||
35 | */ | ||
36 | /*============================================================ | ||
37 | * include files | ||
38 | *============================================================ | ||
39 | */ | ||
40 | #include "halbt_precomp.h" | ||
41 | /*============================================================ | ||
42 | * Global variables, these are static variables | ||
43 | *============================================================ | ||
44 | */ | ||
45 | static struct coex_dm_8821a_1ant glcoex_dm_8821a_1ant; | ||
46 | static struct coex_dm_8821a_1ant *coex_dm = &glcoex_dm_8821a_1ant; | ||
47 | static struct coex_sta_8821a_1ant glcoex_sta_8821a_1ant; | ||
48 | static struct coex_sta_8821a_1ant *coex_sta = &glcoex_sta_8821a_1ant; | ||
49 | |||
50 | static const char *const glbt_info_src_8821a_1ant[] = { | ||
51 | "BT Info[wifi fw]", | ||
52 | "BT Info[bt rsp]", | ||
53 | "BT Info[bt auto report]", | ||
54 | }; | ||
55 | |||
56 | static u32 glcoex_ver_date_8821a_1ant = 20130816; | ||
57 | static u32 glcoex_ver_8821a_1ant = 0x41; | ||
58 | |||
59 | /*============================================================ | ||
60 | * local function proto type if needed | ||
61 | * | ||
62 | * local function start with halbtc8821a1ant_ | ||
63 | *============================================================ | ||
64 | */ | ||
65 | static u8 halbtc8821a1ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, | ||
66 | u8 rssi_thresh1) | ||
67 | { | ||
68 | long bt_rssi = 0; | ||
69 | u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; | ||
70 | |||
71 | bt_rssi = coex_sta->bt_rssi; | ||
72 | |||
73 | if (level_num == 2) { | ||
74 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
75 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
76 | if (bt_rssi >= (rssi_thresh + | ||
77 | BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
78 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
79 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
80 | "[BTCoex], BT Rssi state switch to High\n"); | ||
81 | } else { | ||
82 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
83 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
84 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
85 | } | ||
86 | } else { | ||
87 | if (bt_rssi < rssi_thresh) { | ||
88 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
89 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
90 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
91 | } else { | ||
92 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
93 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
94 | "[BTCoex], BT Rssi state stay at High\n"); | ||
95 | } | ||
96 | } | ||
97 | } else if (level_num == 3) { | ||
98 | if (rssi_thresh > rssi_thresh1) { | ||
99 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
100 | "[BTCoex], BT Rssi thresh error!!\n"); | ||
101 | return coex_sta->pre_bt_rssi_state; | ||
102 | } | ||
103 | |||
104 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
105 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
106 | if (bt_rssi >= (rssi_thresh + | ||
107 | BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
108 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
109 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
110 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
111 | } else { | ||
112 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
113 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
114 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
115 | } | ||
116 | } else if ((coex_sta->pre_bt_rssi_state == | ||
117 | BTC_RSSI_STATE_MEDIUM) || | ||
118 | (coex_sta->pre_bt_rssi_state == | ||
119 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
120 | if (bt_rssi >= (rssi_thresh1 + | ||
121 | BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
122 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
123 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
124 | "[BTCoex], BT Rssi state switch to High\n"); | ||
125 | } else if (bt_rssi < rssi_thresh) { | ||
126 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
127 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
128 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
129 | } else { | ||
130 | bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
131 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
132 | "[BTCoex], BT Rssi state stay at Medium\n"); | ||
133 | } | ||
134 | } else { | ||
135 | if (bt_rssi < rssi_thresh1) { | ||
136 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
137 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
138 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
139 | } else { | ||
140 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
141 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
142 | "[BTCoex], BT Rssi state stay at High\n"); | ||
143 | } | ||
144 | } | ||
145 | } | ||
146 | coex_sta->pre_bt_rssi_state = bt_rssi_state; | ||
147 | |||
148 | return bt_rssi_state; | ||
149 | } | ||
150 | |||
151 | static u8 halbtc8821a1ant_WifiRssiState(struct btc_coexist *btcoexist, | ||
152 | u8 index, u8 level_num, u8 rssi_thresh, | ||
153 | u8 rssi_thresh1) | ||
154 | { | ||
155 | long wifi_rssi = 0; | ||
156 | u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; | ||
157 | |||
158 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
159 | |||
160 | if (level_num == 2) { | ||
161 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
162 | BTC_RSSI_STATE_LOW) || | ||
163 | (coex_sta->pre_wifi_rssi_state[index] == | ||
164 | BTC_RSSI_STATE_STAY_LOW)) { | ||
165 | if (wifi_rssi >= | ||
166 | (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
167 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
168 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
169 | ALGO_WIFI_RSSI_STATE, | ||
170 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
171 | } else { | ||
172 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
173 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
174 | ALGO_WIFI_RSSI_STATE, | ||
175 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
176 | } | ||
177 | } else { | ||
178 | if (wifi_rssi < rssi_thresh) { | ||
179 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
180 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
181 | ALGO_WIFI_RSSI_STATE, | ||
182 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
183 | } else { | ||
184 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
185 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
186 | ALGO_WIFI_RSSI_STATE, | ||
187 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
188 | } | ||
189 | } | ||
190 | } else if (level_num == 3) { | ||
191 | if (rssi_thresh > rssi_thresh1) { | ||
192 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, | ||
193 | "[BTCoex], wifi RSSI thresh error!!\n"); | ||
194 | return coex_sta->pre_wifi_rssi_state[index]; | ||
195 | } | ||
196 | |||
197 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
198 | BTC_RSSI_STATE_LOW) || | ||
199 | (coex_sta->pre_wifi_rssi_state[index] == | ||
200 | BTC_RSSI_STATE_STAY_LOW)) { | ||
201 | if (wifi_rssi >= | ||
202 | (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
203 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
204 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
205 | ALGO_WIFI_RSSI_STATE, | ||
206 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
207 | } else { | ||
208 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
209 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
210 | ALGO_WIFI_RSSI_STATE, | ||
211 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
212 | } | ||
213 | } else if ((coex_sta->pre_wifi_rssi_state[index] == | ||
214 | BTC_RSSI_STATE_MEDIUM) || | ||
215 | (coex_sta->pre_wifi_rssi_state[index] == | ||
216 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
217 | if (wifi_rssi >= | ||
218 | (rssi_thresh1 + | ||
219 | BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) { | ||
220 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
221 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
222 | ALGO_WIFI_RSSI_STATE, | ||
223 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
224 | } else if (wifi_rssi < rssi_thresh) { | ||
225 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
226 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
227 | ALGO_WIFI_RSSI_STATE, | ||
228 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
229 | } else { | ||
230 | wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
231 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
232 | ALGO_WIFI_RSSI_STATE, | ||
233 | "[BTCoex], wifi RSSI state stay at Medium\n"); | ||
234 | } | ||
235 | } else { | ||
236 | if (wifi_rssi < rssi_thresh1) { | ||
237 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
238 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
239 | ALGO_WIFI_RSSI_STATE, | ||
240 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
241 | } else { | ||
242 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
243 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
244 | ALGO_WIFI_RSSI_STATE, | ||
245 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; | ||
250 | |||
251 | return wifi_rssi_state; | ||
252 | } | ||
253 | |||
254 | static void halbtc8821a1ant_update_ra_mask(struct btc_coexist *btcoexist, | ||
255 | bool force_exec, u32 dis_rate_mask) | ||
256 | { | ||
257 | coex_dm->cur_ra_mask = dis_rate_mask; | ||
258 | |||
259 | if (force_exec || | ||
260 | (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) { | ||
261 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask, | ||
262 | &coex_dm->cur_ra_mask); | ||
263 | } | ||
264 | coex_dm->pre_ra_mask = coex_dm->cur_ra_mask; | ||
265 | } | ||
266 | |||
267 | static void btc8821a1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist, | ||
268 | bool force_exec, u8 type) | ||
269 | { | ||
270 | bool wifi_under_b_mode = false; | ||
271 | |||
272 | coex_dm->cur_arfr_type = type; | ||
273 | |||
274 | if (force_exec || | ||
275 | (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) { | ||
276 | switch (coex_dm->cur_arfr_type) { | ||
277 | case 0: /* normal mode*/ | ||
278 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
279 | coex_dm->backup_arfr_cnt1); | ||
280 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
281 | coex_dm->backup_arfr_cnt2); | ||
282 | break; | ||
283 | case 1: | ||
284 | btcoexist->btc_get(btcoexist, | ||
285 | BTC_GET_BL_WIFI_UNDER_B_MODE, | ||
286 | &wifi_under_b_mode); | ||
287 | if (wifi_under_b_mode) { | ||
288 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
289 | 0x0); | ||
290 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
291 | 0x01010101); | ||
292 | } else { | ||
293 | btcoexist->btc_write_4byte(btcoexist, 0x430, | ||
294 | 0x0); | ||
295 | btcoexist->btc_write_4byte(btcoexist, 0x434, | ||
296 | 0x04030201); | ||
297 | } | ||
298 | break; | ||
299 | default: | ||
300 | break; | ||
301 | } | ||
302 | } | ||
303 | |||
304 | coex_dm->pre_arfr_type = coex_dm->cur_arfr_type; | ||
305 | } | ||
306 | |||
307 | static void halbtc8821a1ant_retry_limit(struct btc_coexist *btcoexist, | ||
308 | bool force_exec, u8 type) | ||
309 | { | ||
310 | coex_dm->cur_retry_limit_type = type; | ||
311 | |||
312 | if (force_exec || | ||
313 | (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) { | ||
314 | switch (coex_dm->cur_retry_limit_type) { | ||
315 | case 0: /* normal mode*/ | ||
316 | btcoexist->btc_write_2byte(btcoexist, 0x42a, | ||
317 | coex_dm->backup_retry_limit); | ||
318 | break; | ||
319 | case 1: /* retry limit = 8*/ | ||
320 | btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808); | ||
321 | break; | ||
322 | default: | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type; | ||
327 | } | ||
328 | |||
329 | static void halbtc8821a1ant_ampdu_max_time(struct btc_coexist *btcoexist, | ||
330 | bool force_exec, u8 type) | ||
331 | { | ||
332 | coex_dm->cur_ampdu_time_type = type; | ||
333 | |||
334 | if (force_exec || | ||
335 | (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) { | ||
336 | switch (coex_dm->cur_ampdu_time_type) { | ||
337 | case 0: /* normal mode*/ | ||
338 | btcoexist->btc_write_1byte(btcoexist, 0x456, | ||
339 | coex_dm->backup_ampdu_max_time); | ||
340 | break; | ||
341 | case 1: /* AMPDU timw = 0x38 * 32us*/ | ||
342 | btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38); | ||
343 | break; | ||
344 | default: | ||
345 | break; | ||
346 | } | ||
347 | } | ||
348 | |||
349 | coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type; | ||
350 | } | ||
351 | |||
352 | static void halbtc8821a1ant_limited_tx(struct btc_coexist *btcoexist, | ||
353 | bool force_exec, u8 ra_mask_type, | ||
354 | u8 arfr_type, u8 retry_limit_type, | ||
355 | u8 ampdu_time_type) | ||
356 | { | ||
357 | switch (ra_mask_type) { | ||
358 | case 0: /* normal mode*/ | ||
359 | halbtc8821a1ant_update_ra_mask(btcoexist, force_exec, 0x0); | ||
360 | break; | ||
361 | case 1: /* disable cck 1/2*/ | ||
362 | halbtc8821a1ant_update_ra_mask(btcoexist, force_exec, | ||
363 | 0x00000003); | ||
364 | break; | ||
365 | case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4*/ | ||
366 | halbtc8821a1ant_update_ra_mask(btcoexist, force_exec, | ||
367 | 0x0001f1f7); | ||
368 | break; | ||
369 | default: | ||
370 | break; | ||
371 | } | ||
372 | |||
373 | btc8821a1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type); | ||
374 | halbtc8821a1ant_retry_limit(btcoexist, force_exec, retry_limit_type); | ||
375 | halbtc8821a1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type); | ||
376 | } | ||
377 | |||
378 | static void halbtc8821a1ant_limited_rx(struct btc_coexist *btcoexist, | ||
379 | bool force_exec, bool rej_ap_agg_pkt, | ||
380 | bool bt_ctrl_agg_buf_size, | ||
381 | u8 agg_buf_size) | ||
382 | { | ||
383 | bool reject_rx_agg = rej_ap_agg_pkt; | ||
384 | bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size; | ||
385 | u8 rx_agg_size = agg_buf_size; | ||
386 | |||
387 | /*============================================*/ | ||
388 | /* Rx Aggregation related setting*/ | ||
389 | /*============================================*/ | ||
390 | btcoexist->btc_set(btcoexist, | ||
391 | BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg); | ||
392 | /* decide BT control aggregation buf size or not*/ | ||
393 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, | ||
394 | &bt_ctrl_rx_agg_size); | ||
395 | /* aggregation buf size, only work when BT control Rx agg size.*/ | ||
396 | btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size); | ||
397 | /* real update aggregation setting*/ | ||
398 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL); | ||
399 | } | ||
400 | |||
401 | static void halbtc8821a1ant_monitor_bt_ctr(struct btc_coexist *btcoexist) | ||
402 | { | ||
403 | u32 reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp; | ||
404 | u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; | ||
405 | |||
406 | reg_hp_tx_rx = 0x770; | ||
407 | reg_lp_tx_rx = 0x774; | ||
408 | |||
409 | u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx); | ||
410 | reg_hp_tx = u4_tmp & MASKLWORD; | ||
411 | reg_hp_rx = (u4_tmp & MASKHWORD)>>16; | ||
412 | |||
413 | u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx); | ||
414 | reg_lp_tx = u4_tmp & MASKLWORD; | ||
415 | reg_lp_rx = (u4_tmp & MASKHWORD)>>16; | ||
416 | |||
417 | coex_sta->high_priority_tx = reg_hp_tx; | ||
418 | coex_sta->high_priority_rx = reg_hp_rx; | ||
419 | coex_sta->low_priority_tx = reg_lp_tx; | ||
420 | coex_sta->low_priority_rx = reg_lp_rx; | ||
421 | |||
422 | /* reset counter*/ | ||
423 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
424 | } | ||
425 | |||
426 | static void halbtc8821a1ant_query_bt_info(struct btc_coexist *btcoexist) | ||
427 | { | ||
428 | u8 h2c_parameter[1] = {0}; | ||
429 | |||
430 | coex_sta->c2h_bt_info_req_sent = true; | ||
431 | |||
432 | h2c_parameter[0] |= BIT0; /* trigger*/ | ||
433 | |||
434 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
435 | "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", | ||
436 | h2c_parameter[0]); | ||
437 | |||
438 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | ||
439 | } | ||
440 | |||
441 | static void halbtc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist) | ||
442 | { | ||
443 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
444 | bool bt_hs_on = false; | ||
445 | |||
446 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
447 | |||
448 | bt_link_info->bt_link_exist = coex_sta->bt_link_exist; | ||
449 | bt_link_info->sco_exist = coex_sta->sco_exist; | ||
450 | bt_link_info->a2dp_exist = coex_sta->a2dp_exist; | ||
451 | bt_link_info->pan_exist = coex_sta->pan_exist; | ||
452 | bt_link_info->hid_exist = coex_sta->hid_exist; | ||
453 | |||
454 | /* work around for HS mode.*/ | ||
455 | if (bt_hs_on) { | ||
456 | bt_link_info->pan_exist = true; | ||
457 | bt_link_info->bt_link_exist = true; | ||
458 | } | ||
459 | |||
460 | /* check if Sco only*/ | ||
461 | if (bt_link_info->sco_exist && | ||
462 | !bt_link_info->a2dp_exist && | ||
463 | !bt_link_info->pan_exist && | ||
464 | !bt_link_info->hid_exist) | ||
465 | bt_link_info->sco_only = true; | ||
466 | else | ||
467 | bt_link_info->sco_only = false; | ||
468 | |||
469 | /* check if A2dp only*/ | ||
470 | if (!bt_link_info->sco_exist && | ||
471 | bt_link_info->a2dp_exist && | ||
472 | !bt_link_info->pan_exist && | ||
473 | !bt_link_info->hid_exist) | ||
474 | bt_link_info->a2dp_only = true; | ||
475 | else | ||
476 | bt_link_info->a2dp_only = false; | ||
477 | |||
478 | /* check if Pan only*/ | ||
479 | if (!bt_link_info->sco_exist && | ||
480 | !bt_link_info->a2dp_exist && | ||
481 | bt_link_info->pan_exist && | ||
482 | !bt_link_info->hid_exist) | ||
483 | bt_link_info->pan_only = true; | ||
484 | else | ||
485 | bt_link_info->pan_only = false; | ||
486 | |||
487 | /* check if Hid only*/ | ||
488 | if (!bt_link_info->sco_exist && | ||
489 | !bt_link_info->a2dp_exist && | ||
490 | !bt_link_info->pan_exist && | ||
491 | bt_link_info->hid_exist) | ||
492 | bt_link_info->hid_only = true; | ||
493 | else | ||
494 | bt_link_info->hid_only = false; | ||
495 | } | ||
496 | |||
497 | static u8 halbtc8821a1ant_action_algorithm(struct btc_coexist *btcoexist) | ||
498 | { | ||
499 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
500 | bool bt_hs_on = false; | ||
501 | u8 algorithm = BT_8821A_1ANT_COEX_ALGO_UNDEFINED; | ||
502 | u8 num_of_diff_profile = 0; | ||
503 | |||
504 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
505 | |||
506 | if (!bt_link_info->bt_link_exist) { | ||
507 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
508 | "[BTCoex], No BT link exists!!!\n"); | ||
509 | return algorithm; | ||
510 | } | ||
511 | |||
512 | if (bt_link_info->sco_exist) | ||
513 | num_of_diff_profile++; | ||
514 | if (bt_link_info->hid_exist) | ||
515 | num_of_diff_profile++; | ||
516 | if (bt_link_info->pan_exist) | ||
517 | num_of_diff_profile++; | ||
518 | if (bt_link_info->a2dp_exist) | ||
519 | num_of_diff_profile++; | ||
520 | |||
521 | if (num_of_diff_profile == 1) { | ||
522 | if (bt_link_info->sco_exist) { | ||
523 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
524 | "[BTCoex], BT Profile = SCO only\n"); | ||
525 | algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; | ||
526 | } else { | ||
527 | if (bt_link_info->hid_exist) { | ||
528 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
529 | "[BTCoex], BT Profile = HID only\n"); | ||
530 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID; | ||
531 | } else if (bt_link_info->a2dp_exist) { | ||
532 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
533 | "[BTCoex], BT Profile = A2DP only\n"); | ||
534 | algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP; | ||
535 | } else if (bt_link_info->pan_exist) { | ||
536 | if (bt_hs_on) { | ||
537 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
538 | "[BTCoex], BT Profile = PAN(HS) only\n"); | ||
539 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS; | ||
540 | } else { | ||
541 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
542 | "[BTCoex], BT Profile = PAN(EDR) only\n"); | ||
543 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR; | ||
544 | } | ||
545 | } | ||
546 | } | ||
547 | } else if (num_of_diff_profile == 2) { | ||
548 | if (bt_link_info->sco_exist) { | ||
549 | if (bt_link_info->hid_exist) { | ||
550 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
551 | "[BTCoex], BT Profile = SCO + HID\n"); | ||
552 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID; | ||
553 | } else if (bt_link_info->a2dp_exist) { | ||
554 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
555 | "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n"); | ||
556 | algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; | ||
557 | } else if (bt_link_info->pan_exist) { | ||
558 | if (bt_hs_on) { | ||
559 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
560 | "[BTCoex], BT Profile = SCO + PAN(HS)\n"); | ||
561 | algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; | ||
562 | } else { | ||
563 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
564 | "[BTCoex], BT Profile = SCO + PAN(EDR)\n"); | ||
565 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; | ||
566 | } | ||
567 | } | ||
568 | } else { | ||
569 | if (bt_link_info->hid_exist && | ||
570 | bt_link_info->a2dp_exist) { | ||
571 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
572 | "[BTCoex], BT Profile = HID + A2DP\n"); | ||
573 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; | ||
574 | } else if (bt_link_info->hid_exist && | ||
575 | bt_link_info->pan_exist) { | ||
576 | if (bt_hs_on) { | ||
577 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
578 | "[BTCoex], BT Profile = HID + PAN(HS)\n"); | ||
579 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; | ||
580 | } else { | ||
581 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
582 | "[BTCoex], BT Profile = HID + PAN(EDR)\n"); | ||
583 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; | ||
584 | } | ||
585 | } else if (bt_link_info->pan_exist && | ||
586 | bt_link_info->a2dp_exist) { | ||
587 | if (bt_hs_on) { | ||
588 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
589 | "[BTCoex], BT Profile = A2DP + PAN(HS)\n"); | ||
590 | algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS; | ||
591 | } else { | ||
592 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
593 | "[BTCoex], BT Profile = A2DP + PAN(EDR)\n"); | ||
594 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP; | ||
595 | } | ||
596 | } | ||
597 | } | ||
598 | } else if (num_of_diff_profile == 3) { | ||
599 | if (bt_link_info->sco_exist) { | ||
600 | if (bt_link_info->hid_exist && | ||
601 | bt_link_info->a2dp_exist) { | ||
602 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
603 | "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n"); | ||
604 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID; | ||
605 | } else if (bt_link_info->hid_exist && | ||
606 | bt_link_info->pan_exist) { | ||
607 | if (bt_hs_on) { | ||
608 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
609 | "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n"); | ||
610 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; | ||
611 | } else { | ||
612 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
613 | "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n"); | ||
614 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; | ||
615 | } | ||
616 | } else if (bt_link_info->pan_exist && | ||
617 | bt_link_info->a2dp_exist) { | ||
618 | if (bt_hs_on) { | ||
619 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
620 | "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n"); | ||
621 | algorithm = BT_8821A_1ANT_COEX_ALGO_SCO; | ||
622 | } else { | ||
623 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
624 | "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n"); | ||
625 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; | ||
626 | } | ||
627 | } | ||
628 | } else { | ||
629 | if (bt_link_info->hid_exist && | ||
630 | bt_link_info->pan_exist && | ||
631 | bt_link_info->a2dp_exist) { | ||
632 | if (bt_hs_on) { | ||
633 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
634 | "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n"); | ||
635 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP; | ||
636 | } else { | ||
637 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
638 | "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n"); | ||
639 | algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
640 | } | ||
641 | } | ||
642 | } | ||
643 | } else if (num_of_diff_profile >= 3) { | ||
644 | if (bt_link_info->sco_exist) { | ||
645 | if (bt_link_info->hid_exist && | ||
646 | bt_link_info->pan_exist && | ||
647 | bt_link_info->a2dp_exist) { | ||
648 | if (bt_hs_on) { | ||
649 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
650 | "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n"); | ||
651 | |||
652 | } else { | ||
653 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
654 | "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); | ||
655 | algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID; | ||
656 | } | ||
657 | } | ||
658 | } | ||
659 | } | ||
660 | return algorithm; | ||
661 | } | ||
662 | |||
663 | static void halbtc8821a1ant_set_bt_auto_report(struct btc_coexist *btcoexist, | ||
664 | bool enable_auto_report) | ||
665 | { | ||
666 | u8 h2c_parameter[1] = {0}; | ||
667 | |||
668 | h2c_parameter[0] = 0; | ||
669 | |||
670 | if (enable_auto_report) | ||
671 | h2c_parameter[0] |= BIT0; | ||
672 | |||
673 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
674 | "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n", | ||
675 | (enable_auto_report ? "Enabled!!" : "Disabled!!"), | ||
676 | h2c_parameter[0]); | ||
677 | |||
678 | btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); | ||
679 | } | ||
680 | |||
681 | static void halbtc8821a1ant_bt_auto_report(struct btc_coexist *btcoexist, | ||
682 | bool force_exec, | ||
683 | bool enable_auto_report) | ||
684 | { | ||
685 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
686 | ALGO_TRACE_FW, "[BTCoex], %s BT Auto report = %s\n", | ||
687 | (force_exec ? "force to" : ""), ((enable_auto_report) ? | ||
688 | "Enabled" : "Disabled")); | ||
689 | coex_dm->cur_bt_auto_report = enable_auto_report; | ||
690 | |||
691 | if (!force_exec) { | ||
692 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
693 | "[BTCoex], pre_bt_auto_report = %d, cur_bt_auto_report = %d\n", | ||
694 | coex_dm->pre_bt_auto_report, | ||
695 | coex_dm->cur_bt_auto_report); | ||
696 | |||
697 | if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) | ||
698 | return; | ||
699 | } | ||
700 | halbtc8821a1ant_set_bt_auto_report(btcoexist, coex_dm->cur_bt_auto_report); | ||
701 | |||
702 | coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; | ||
703 | } | ||
704 | |||
705 | static void btc8821a1ant_set_sw_pen_tx_rate(struct btc_coexist *btcoexist, | ||
706 | bool low_penalty_ra) | ||
707 | { | ||
708 | u8 h2c_parameter[6] = {0}; | ||
709 | |||
710 | h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty*/ | ||
711 | |||
712 | if (low_penalty_ra) { | ||
713 | h2c_parameter[1] |= BIT0; | ||
714 | /*normal rate except MCS7/6/5, OFDM54/48/36*/ | ||
715 | h2c_parameter[2] = 0x00; | ||
716 | h2c_parameter[3] = 0xf7; /*MCS7 or OFDM54*/ | ||
717 | h2c_parameter[4] = 0xf8; /*MCS6 or OFDM48*/ | ||
718 | h2c_parameter[5] = 0xf9; /*MCS5 or OFDM36*/ | ||
719 | } | ||
720 | |||
721 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
722 | "[BTCoex], set WiFi Low-Penalty Retry: %s", | ||
723 | (low_penalty_ra ? "ON!!" : "OFF!!")); | ||
724 | |||
725 | btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); | ||
726 | } | ||
727 | |||
728 | static void halbtc8821a1ant_low_penalty_ra(struct btc_coexist *btcoexist, | ||
729 | bool force_exec, bool low_penalty_ra) | ||
730 | { | ||
731 | coex_dm->cur_low_penalty_ra = low_penalty_ra; | ||
732 | |||
733 | if (!force_exec) { | ||
734 | if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) | ||
735 | return; | ||
736 | } | ||
737 | btc8821a1ant_set_sw_pen_tx_rate(btcoexist, coex_dm->cur_low_penalty_ra); | ||
738 | |||
739 | coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; | ||
740 | } | ||
741 | |||
742 | static void halbtc8821a1ant_set_coex_table(struct btc_coexist *btcoexist, | ||
743 | u32 val0x6c0, u32 val0x6c4, | ||
744 | u32 val0x6c8, u8 val0x6cc) | ||
745 | { | ||
746 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
747 | "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); | ||
748 | btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); | ||
749 | |||
750 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
751 | "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); | ||
752 | btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); | ||
753 | |||
754 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
755 | "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); | ||
756 | btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); | ||
757 | |||
758 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
759 | "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); | ||
760 | btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); | ||
761 | } | ||
762 | |||
763 | static void halbtc8821a1ant_coex_table(struct btc_coexist *btcoexist, | ||
764 | bool force_exec, u32 val0x6c0, | ||
765 | u32 val0x6c4, u32 val0x6c8, u8 val0x6cc) | ||
766 | { | ||
767 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
768 | "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", | ||
769 | (force_exec ? "force to" : ""), val0x6c0, val0x6c4, | ||
770 | val0x6c8, val0x6cc); | ||
771 | coex_dm->cur_val_0x6c0 = val0x6c0; | ||
772 | coex_dm->cur_val_0x6c4 = val0x6c4; | ||
773 | coex_dm->cur_val_0x6c8 = val0x6c8; | ||
774 | coex_dm->cur_val_0x6cc = val0x6cc; | ||
775 | |||
776 | if (!force_exec) { | ||
777 | if ((coex_dm->pre_val_0x6c0 == coex_dm->cur_val_0x6c0) && | ||
778 | (coex_dm->pre_val_0x6c4 == coex_dm->cur_val_0x6c4) && | ||
779 | (coex_dm->pre_val_0x6c8 == coex_dm->cur_val_0x6c8) && | ||
780 | (coex_dm->pre_val_0x6cc == coex_dm->cur_val_0x6cc)) | ||
781 | return; | ||
782 | } | ||
783 | halbtc8821a1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, | ||
784 | val0x6c8, val0x6cc); | ||
785 | |||
786 | coex_dm->pre_val_0x6c0 = coex_dm->cur_val_0x6c0; | ||
787 | coex_dm->pre_val_0x6c4 = coex_dm->cur_val_0x6c4; | ||
788 | coex_dm->pre_val_0x6c8 = coex_dm->cur_val_0x6c8; | ||
789 | coex_dm->pre_val_0x6cc = coex_dm->cur_val_0x6cc; | ||
790 | } | ||
791 | |||
792 | static void halbtc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist, | ||
793 | bool force_exec, u8 type) | ||
794 | { | ||
795 | switch (type) { | ||
796 | case 0: | ||
797 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
798 | 0x55555555, 0xffffff, 0x3); | ||
799 | break; | ||
800 | case 1: | ||
801 | halbtc8821a1ant_coex_table(btcoexist, force_exec, | ||
802 | 0x55555555, 0x5a5a5a5a, | ||
803 | 0xffffff, 0x3); | ||
804 | break; | ||
805 | case 2: | ||
806 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a, | ||
807 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
808 | break; | ||
809 | case 3: | ||
810 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555, | ||
811 | 0xaaaaaaaa, 0xffffff, 0x3); | ||
812 | break; | ||
813 | case 4: | ||
814 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0xffffffff, | ||
815 | 0xffffffff, 0xffffff, 0x3); | ||
816 | break; | ||
817 | case 5: | ||
818 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5fff5fff, | ||
819 | 0x5fff5fff, 0xffffff, 0x3); | ||
820 | break; | ||
821 | case 6: | ||
822 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55ff55ff, | ||
823 | 0x5a5a5a5a, 0xffffff, 0x3); | ||
824 | break; | ||
825 | case 7: | ||
826 | halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5afa5afa, | ||
827 | 0x5afa5afa, 0xffffff, 0x3); | ||
828 | break; | ||
829 | default: | ||
830 | break; | ||
831 | } | ||
832 | } | ||
833 | |||
834 | static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist, | ||
835 | bool enable) | ||
836 | { | ||
837 | u8 h2c_parameter[1] = {0}; | ||
838 | |||
839 | if (enable) | ||
840 | h2c_parameter[0] |= BIT0; /* function enable*/ | ||
841 | |||
842 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
843 | "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", | ||
844 | h2c_parameter[0]); | ||
845 | |||
846 | btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter); | ||
847 | } | ||
848 | |||
849 | static void halbtc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist, | ||
850 | bool force_exec, bool enable) | ||
851 | { | ||
852 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
853 | "[BTCoex], %s turn Ignore WlanAct %s\n", | ||
854 | (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); | ||
855 | coex_dm->cur_ignore_wlan_act = enable; | ||
856 | |||
857 | if (!force_exec) { | ||
858 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
859 | "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n", | ||
860 | coex_dm->pre_ignore_wlan_act, | ||
861 | coex_dm->cur_ignore_wlan_act); | ||
862 | |||
863 | if (coex_dm->pre_ignore_wlan_act == | ||
864 | coex_dm->cur_ignore_wlan_act) | ||
865 | return; | ||
866 | } | ||
867 | btc8821a1ant_set_fw_ignore_wlan_act(btcoexist, enable); | ||
868 | |||
869 | coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; | ||
870 | } | ||
871 | |||
872 | static void halbtc8821a1ant_set_fw_pstdma(struct btc_coexist *btcoexist, | ||
873 | u8 byte1, u8 byte2, u8 byte3, | ||
874 | u8 byte4, u8 byte5) | ||
875 | { | ||
876 | u8 h2c_parameter[5] = {0}; | ||
877 | |||
878 | h2c_parameter[0] = byte1; | ||
879 | h2c_parameter[1] = byte2; | ||
880 | h2c_parameter[2] = byte3; | ||
881 | h2c_parameter[3] = byte4; | ||
882 | h2c_parameter[4] = byte5; | ||
883 | |||
884 | coex_dm->ps_tdma_para[0] = byte1; | ||
885 | coex_dm->ps_tdma_para[1] = byte2; | ||
886 | coex_dm->ps_tdma_para[2] = byte3; | ||
887 | coex_dm->ps_tdma_para[3] = byte4; | ||
888 | coex_dm->ps_tdma_para[4] = byte5; | ||
889 | |||
890 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
891 | "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n", | ||
892 | h2c_parameter[0], | ||
893 | h2c_parameter[1]<<24 | | ||
894 | h2c_parameter[2]<<16 | | ||
895 | h2c_parameter[3]<<8 | | ||
896 | h2c_parameter[4]); | ||
897 | btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); | ||
898 | } | ||
899 | |||
900 | static void halbtc8821a1ant_set_lps_rpwm(struct btc_coexist *btcoexist, | ||
901 | u8 lps_val, u8 rpwm_val) | ||
902 | { | ||
903 | u8 lps = lps_val; | ||
904 | u8 rpwm = rpwm_val; | ||
905 | |||
906 | btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps); | ||
907 | btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm); | ||
908 | } | ||
909 | |||
910 | static void halbtc8821a1ant_lps_rpwm(struct btc_coexist *btcoexist, | ||
911 | bool force_exec, u8 lps_val, u8 rpwm_val) | ||
912 | { | ||
913 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
914 | "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n", | ||
915 | (force_exec ? "force to" : ""), lps_val, rpwm_val); | ||
916 | coex_dm->cur_lps = lps_val; | ||
917 | coex_dm->cur_rpwm = rpwm_val; | ||
918 | |||
919 | if (!force_exec) { | ||
920 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
921 | "[BTCoex], LPS-RxBeaconMode = 0x%x, LPS-RPWM = 0x%x!!\n", | ||
922 | coex_dm->cur_lps, coex_dm->cur_rpwm); | ||
923 | |||
924 | if ((coex_dm->pre_lps == coex_dm->cur_lps) && | ||
925 | (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) { | ||
926 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
927 | "[BTCoex], LPS-RPWM_Last = 0x%x, LPS-RPWM_Now = 0x%x!!\n", | ||
928 | coex_dm->pre_rpwm, coex_dm->cur_rpwm); | ||
929 | |||
930 | return; | ||
931 | } | ||
932 | } | ||
933 | halbtc8821a1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val); | ||
934 | |||
935 | coex_dm->pre_lps = coex_dm->cur_lps; | ||
936 | coex_dm->pre_rpwm = coex_dm->cur_rpwm; | ||
937 | } | ||
938 | |||
939 | static void halbtc8821a1ant_sw_mechanism(struct btc_coexist *btcoexist, | ||
940 | bool low_penalty_ra) | ||
941 | { | ||
942 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
943 | "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra); | ||
944 | |||
945 | halbtc8821a1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra); | ||
946 | } | ||
947 | |||
948 | static void halbtc8821a1ant_set_ant_path(struct btc_coexist *btcoexist, | ||
949 | u8 ant_pos_type, bool init_hw_cfg, | ||
950 | bool wifi_off) | ||
951 | { | ||
952 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
953 | u32 u4_tmp = 0; | ||
954 | u8 h2c_parameter[2] = {0}; | ||
955 | |||
956 | if (init_hw_cfg) { | ||
957 | /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT*/ | ||
958 | u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
959 | u4_tmp &= ~BIT23; | ||
960 | u4_tmp |= BIT24; | ||
961 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp); | ||
962 | |||
963 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x975, 0x3, 0x3); | ||
964 | btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77); | ||
965 | |||
966 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { | ||
967 | /*tell firmware "antenna inverse" ==> | ||
968 | * WRONG firmware antenna control code.==>need fw to fix | ||
969 | */ | ||
970 | h2c_parameter[0] = 1; | ||
971 | h2c_parameter[1] = 1; | ||
972 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
973 | h2c_parameter); | ||
974 | /*Main Ant to BT for IPS case 0x4c[23] = 1*/ | ||
975 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, | ||
976 | 0x1, 0x1); | ||
977 | } else { | ||
978 | /*tell firmware "no antenna inverse" ==> | ||
979 | * WRONG firmware antenna control code.==>need fw to fix | ||
980 | */ | ||
981 | h2c_parameter[0] = 0; | ||
982 | h2c_parameter[1] = 1; | ||
983 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
984 | h2c_parameter); | ||
985 | /*Aux Ant to BT for IPS case 0x4c[23] = 1*/ | ||
986 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, | ||
987 | 0x1, 0x0); | ||
988 | } | ||
989 | } else if (wifi_off) { | ||
990 | /* 0x4c[24:23] = 00, Set Antenna control | ||
991 | * by BT_RFE_CTRL BT Vendor 0xac = 0xf002 | ||
992 | */ | ||
993 | u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
994 | u4_tmp &= ~BIT23; | ||
995 | u4_tmp &= ~BIT24; | ||
996 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp); | ||
997 | } | ||
998 | |||
999 | /* ext switch setting*/ | ||
1000 | switch (ant_pos_type) { | ||
1001 | case BTC_ANT_PATH_WIFI: | ||
1002 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) | ||
1003 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1004 | 0x30, 0x1); | ||
1005 | else | ||
1006 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1007 | 0x30, 0x2); | ||
1008 | break; | ||
1009 | case BTC_ANT_PATH_BT: | ||
1010 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) | ||
1011 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1012 | 0x30, 0x2); | ||
1013 | else | ||
1014 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1015 | 0x30, 0x1); | ||
1016 | break; | ||
1017 | default: | ||
1018 | case BTC_ANT_PATH_PTA: | ||
1019 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) | ||
1020 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1021 | 0x30, 0x1); | ||
1022 | else | ||
1023 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, | ||
1024 | 0x30, 0x2); | ||
1025 | break; | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | static void halbtc8821a1ant_ps_tdma(struct btc_coexist *btcoexist, | ||
1030 | bool force_exec, bool turn_on, u8 type) | ||
1031 | { | ||
1032 | u8 rssi_adjust_val = 0; | ||
1033 | |||
1034 | coex_dm->cur_ps_tdma_on = turn_on; | ||
1035 | coex_dm->cur_ps_tdma = type; | ||
1036 | |||
1037 | if (!force_exec) { | ||
1038 | if (coex_dm->cur_ps_tdma_on) { | ||
1039 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1040 | "[BTCoex], ********** TDMA(on, %d) **********\n", | ||
1041 | coex_dm->cur_ps_tdma); | ||
1042 | } else { | ||
1043 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1044 | "[BTCoex], ********** TDMA(off, %d) **********\n", | ||
1045 | coex_dm->cur_ps_tdma); | ||
1046 | } | ||
1047 | if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && | ||
1048 | (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) | ||
1049 | return; | ||
1050 | } | ||
1051 | if (turn_on) { | ||
1052 | switch (type) { | ||
1053 | default: | ||
1054 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x1a, | ||
1055 | 0x1a, 0x0, 0x50); | ||
1056 | break; | ||
1057 | case 1: | ||
1058 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x3a, | ||
1059 | 0x03, 0x10, 0x50); | ||
1060 | rssi_adjust_val = 11; | ||
1061 | break; | ||
1062 | case 2: | ||
1063 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x2b, | ||
1064 | 0x03, 0x10, 0x50); | ||
1065 | rssi_adjust_val = 14; | ||
1066 | break; | ||
1067 | case 3: | ||
1068 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x1d, | ||
1069 | 0x1d, 0x0, 0x10); | ||
1070 | break; | ||
1071 | case 4: | ||
1072 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x15, | ||
1073 | 0x3, 0x14, 0x0); | ||
1074 | rssi_adjust_val = 17; | ||
1075 | break; | ||
1076 | case 5: | ||
1077 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x15, | ||
1078 | 0x3, 0x11, 0x10); | ||
1079 | break; | ||
1080 | case 6: | ||
1081 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa, | ||
1082 | 0x3, 0x0, 0x0); | ||
1083 | break; | ||
1084 | case 7: | ||
1085 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xc, | ||
1086 | 0x5, 0x0, 0x0); | ||
1087 | break; | ||
1088 | case 8: | ||
1089 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x25, | ||
1090 | 0x3, 0x10, 0x0); | ||
1091 | break; | ||
1092 | case 9: | ||
1093 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x21, | ||
1094 | 0x3, 0x10, 0x50); | ||
1095 | rssi_adjust_val = 18; | ||
1096 | break; | ||
1097 | case 10: | ||
1098 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa, | ||
1099 | 0xa, 0x0, 0x40); | ||
1100 | break; | ||
1101 | case 11: | ||
1102 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x14, | ||
1103 | 0x03, 0x10, 0x10); | ||
1104 | rssi_adjust_val = 20; | ||
1105 | break; | ||
1106 | case 12: | ||
1107 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x0a, | ||
1108 | 0x0a, 0x0, 0x50); | ||
1109 | break; | ||
1110 | case 13: | ||
1111 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x18, | ||
1112 | 0x18, 0x0, 0x10); | ||
1113 | break; | ||
1114 | case 14: | ||
1115 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x21, | ||
1116 | 0x3, 0x10, 0x10); | ||
1117 | break; | ||
1118 | case 15: | ||
1119 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa, | ||
1120 | 0x3, 0x8, 0x0); | ||
1121 | break; | ||
1122 | case 16: | ||
1123 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x15, | ||
1124 | 0x3, 0x10, 0x0); | ||
1125 | rssi_adjust_val = 18; | ||
1126 | break; | ||
1127 | case 18: | ||
1128 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x25, | ||
1129 | 0x3, 0x10, 0x0); | ||
1130 | rssi_adjust_val = 14; | ||
1131 | break; | ||
1132 | case 20: | ||
1133 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x35, | ||
1134 | 0x03, 0x11, 0x10); | ||
1135 | break; | ||
1136 | case 21: | ||
1137 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x15, | ||
1138 | 0x03, 0x11, 0x10); | ||
1139 | break; | ||
1140 | case 22: | ||
1141 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x25, | ||
1142 | 0x03, 0x11, 0x10); | ||
1143 | break; | ||
1144 | case 23: | ||
1145 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x25, | ||
1146 | 0x3, 0x31, 0x18); | ||
1147 | rssi_adjust_val = 22; | ||
1148 | break; | ||
1149 | case 24: | ||
1150 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x15, | ||
1151 | 0x3, 0x31, 0x18); | ||
1152 | rssi_adjust_val = 22; | ||
1153 | break; | ||
1154 | case 25: | ||
1155 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0xa, | ||
1156 | 0x3, 0x31, 0x18); | ||
1157 | rssi_adjust_val = 22; | ||
1158 | break; | ||
1159 | case 26: | ||
1160 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0xa, | ||
1161 | 0x3, 0x31, 0x18); | ||
1162 | rssi_adjust_val = 22; | ||
1163 | break; | ||
1164 | case 27: | ||
1165 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x25, | ||
1166 | 0x3, 0x31, 0x98); | ||
1167 | rssi_adjust_val = 22; | ||
1168 | break; | ||
1169 | case 28: | ||
1170 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x69, 0x25, | ||
1171 | 0x3, 0x31, 0x0); | ||
1172 | break; | ||
1173 | case 29: | ||
1174 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xab, 0x1a, | ||
1175 | 0x1a, 0x1, 0x10); | ||
1176 | break; | ||
1177 | case 30: | ||
1178 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x14, | ||
1179 | 0x3, 0x10, 0x50); | ||
1180 | break; | ||
1181 | case 31: | ||
1182 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xd3, 0x1a, | ||
1183 | 0x1a, 0, 0x58); | ||
1184 | break; | ||
1185 | case 32: | ||
1186 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0xa, | ||
1187 | 0x3, 0x10, 0x0); | ||
1188 | break; | ||
1189 | case 33: | ||
1190 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xa3, 0x25, | ||
1191 | 0x3, 0x30, 0x90); | ||
1192 | break; | ||
1193 | case 34: | ||
1194 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x53, 0x1a, | ||
1195 | 0x1a, 0x0, 0x10); | ||
1196 | break; | ||
1197 | case 35: | ||
1198 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x63, 0x1a, | ||
1199 | 0x1a, 0x0, 0x10); | ||
1200 | break; | ||
1201 | case 36: | ||
1202 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xd3, 0x12, | ||
1203 | 0x3, 0x14, 0x50); | ||
1204 | break; | ||
1205 | } | ||
1206 | } else { | ||
1207 | /* disable PS tdma*/ | ||
1208 | switch (type) { | ||
1209 | case 8: /*PTA Control*/ | ||
1210 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x8, 0x0, 0x0, | ||
1211 | 0x0, 0x0); | ||
1212 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, | ||
1213 | false, false); | ||
1214 | break; | ||
1215 | case 0: | ||
1216 | default: /*Software control, Antenna at BT side*/ | ||
1217 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1218 | 0x0, 0x0); | ||
1219 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, | ||
1220 | false, false); | ||
1221 | break; | ||
1222 | case 9: /*Software control, Antenna at WiFi side*/ | ||
1223 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1224 | 0x0, 0x0); | ||
1225 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI, | ||
1226 | false, false); | ||
1227 | break; | ||
1228 | case 10: /* under 5G*/ | ||
1229 | halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1230 | 0x8, 0x0); | ||
1231 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, | ||
1232 | false, false); | ||
1233 | break; | ||
1234 | } | ||
1235 | } | ||
1236 | rssi_adjust_val = 0; | ||
1237 | btcoexist->btc_set(btcoexist, | ||
1238 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val); | ||
1239 | |||
1240 | /* update pre state*/ | ||
1241 | coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; | ||
1242 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; | ||
1243 | } | ||
1244 | |||
1245 | static bool halbtc8821a1ant_is_common_action(struct btc_coexist *btcoexist) | ||
1246 | { | ||
1247 | bool common = false, wifi_connected = false, wifi_busy = false; | ||
1248 | |||
1249 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1250 | &wifi_connected); | ||
1251 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1252 | |||
1253 | if (!wifi_connected && | ||
1254 | BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
1255 | coex_dm->bt_status) { | ||
1256 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1257 | "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n"); | ||
1258 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1259 | |||
1260 | common = true; | ||
1261 | } else if (wifi_connected && | ||
1262 | (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
1263 | coex_dm->bt_status)) { | ||
1264 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1265 | "[BTCoex], Wifi connected + BT non connected-idle!!\n"); | ||
1266 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1267 | |||
1268 | common = true; | ||
1269 | } else if (!wifi_connected && | ||
1270 | (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
1271 | coex_dm->bt_status)) { | ||
1272 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1273 | "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n"); | ||
1274 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1275 | |||
1276 | common = true; | ||
1277 | } else if (wifi_connected && | ||
1278 | (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
1279 | coex_dm->bt_status)) { | ||
1280 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1281 | "[BTCoex], Wifi connected + BT connected-idle!!\n"); | ||
1282 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1283 | |||
1284 | common = true; | ||
1285 | } else if (!wifi_connected && | ||
1286 | (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE != | ||
1287 | coex_dm->bt_status)) { | ||
1288 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1289 | "[BTCoex], Wifi non connected-idle + BT Busy!!\n"); | ||
1290 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1291 | |||
1292 | common = true; | ||
1293 | } else { | ||
1294 | if (wifi_busy) { | ||
1295 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1296 | "[BTCoex], Wifi Connected-Busy + BT Busy!!\n"); | ||
1297 | } else { | ||
1298 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1299 | "[BTCoex], Wifi Connected-Idle + BT Busy!!\n"); | ||
1300 | } | ||
1301 | |||
1302 | common = false; | ||
1303 | } | ||
1304 | |||
1305 | return common; | ||
1306 | } | ||
1307 | |||
1308 | static void btc8821a1ant_tdma_dur_adj(struct btc_coexist *btcoexist, | ||
1309 | u8 wifi_status) | ||
1310 | { | ||
1311 | static long up, dn, m, n, wait_count; | ||
1312 | /*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/ | ||
1313 | long result; | ||
1314 | u8 retry_count = 0, bt_info_ext; | ||
1315 | |||
1316 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1317 | "[BTCoex], TdmaDurationAdjustForAcl()\n"); | ||
1318 | |||
1319 | if ((BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == | ||
1320 | wifi_status) || | ||
1321 | (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN == | ||
1322 | wifi_status) || | ||
1323 | (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == | ||
1324 | wifi_status)) { | ||
1325 | if (coex_dm->cur_ps_tdma != 1 && | ||
1326 | coex_dm->cur_ps_tdma != 2 && | ||
1327 | coex_dm->cur_ps_tdma != 3 && | ||
1328 | coex_dm->cur_ps_tdma != 9) { | ||
1329 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1330 | true, 9); | ||
1331 | coex_dm->tdma_adj_type = 9; | ||
1332 | |||
1333 | up = 0; | ||
1334 | dn = 0; | ||
1335 | m = 1; | ||
1336 | n = 3; | ||
1337 | result = 0; | ||
1338 | wait_count = 0; | ||
1339 | } | ||
1340 | return; | ||
1341 | } | ||
1342 | |||
1343 | if (!coex_dm->auto_tdma_adjust) { | ||
1344 | coex_dm->auto_tdma_adjust = true; | ||
1345 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1346 | "[BTCoex], first run TdmaDurationAdjust()!!\n"); | ||
1347 | |||
1348 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2); | ||
1349 | coex_dm->tdma_adj_type = 2; | ||
1350 | /*============*/ | ||
1351 | up = 0; | ||
1352 | dn = 0; | ||
1353 | m = 1; | ||
1354 | n = 3; | ||
1355 | result = 0; | ||
1356 | wait_count = 0; | ||
1357 | } else { | ||
1358 | /*accquire the BT TRx retry count from BT_Info byte2*/ | ||
1359 | retry_count = coex_sta->bt_retry_cnt; | ||
1360 | bt_info_ext = coex_sta->bt_info_ext; | ||
1361 | result = 0; | ||
1362 | wait_count++; | ||
1363 | |||
1364 | if (retry_count == 0) { | ||
1365 | /* no retry in the last 2-second duration*/ | ||
1366 | up++; | ||
1367 | dn--; | ||
1368 | |||
1369 | if (dn <= 0) | ||
1370 | dn = 0; | ||
1371 | |||
1372 | if (up >= n) { | ||
1373 | /* if (retry count == 0) for 2*n seconds , | ||
1374 | * make WiFi duration wider | ||
1375 | */ | ||
1376 | wait_count = 0; | ||
1377 | n = 3; | ||
1378 | up = 0; | ||
1379 | dn = 0; | ||
1380 | result = 1; | ||
1381 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1382 | ALGO_TRACE_FW_DETAIL, | ||
1383 | "[BTCoex], Increase wifi duration!!\n"); | ||
1384 | } | ||
1385 | } else if (retry_count <= 3) { | ||
1386 | /* <=3 retry in the last 2-second duration*/ | ||
1387 | up--; | ||
1388 | dn++; | ||
1389 | |||
1390 | if (up <= 0) | ||
1391 | up = 0; | ||
1392 | |||
1393 | if (dn == 2) { | ||
1394 | /* if retry count< 3 for 2*2 seconds, | ||
1395 | * shrink wifi duration | ||
1396 | */ | ||
1397 | if (wait_count <= 2) | ||
1398 | m++; /* avoid bounce in two levels */ | ||
1399 | else | ||
1400 | m = 1; | ||
1401 | |||
1402 | if (m >= 20) { | ||
1403 | /* m max value is 20, max time is 120 s, | ||
1404 | * recheck if adjust WiFi duration. | ||
1405 | */ | ||
1406 | m = 20; | ||
1407 | } | ||
1408 | n = 3*m; | ||
1409 | up = 0; | ||
1410 | dn = 0; | ||
1411 | wait_count = 0; | ||
1412 | result = -1; | ||
1413 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
1414 | ALGO_TRACE_FW_DETAIL, | ||
1415 | "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); | ||
1416 | } | ||
1417 | } else { | ||
1418 | /* retry count > 3, if retry count > 3 happens once, | ||
1419 | * shrink WiFi duration | ||
1420 | */ | ||
1421 | if (wait_count == 1) | ||
1422 | m++; /* avoid bounce in two levels */ | ||
1423 | else | ||
1424 | m = 1; | ||
1425 | /* m max value is 20, max time is 120 second, | ||
1426 | * recheck if adjust WiFi duration. | ||
1427 | */ | ||
1428 | if (m >= 20) | ||
1429 | m = 20; | ||
1430 | |||
1431 | n = 3*m; | ||
1432 | up = 0; | ||
1433 | dn = 0; | ||
1434 | wait_count = 0; | ||
1435 | result = -1; | ||
1436 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1437 | "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); | ||
1438 | } | ||
1439 | |||
1440 | if (result == -1) { | ||
1441 | if ((BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && | ||
1442 | ((coex_dm->cur_ps_tdma == 1) || | ||
1443 | (coex_dm->cur_ps_tdma == 2))) { | ||
1444 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1445 | true, 9); | ||
1446 | coex_dm->tdma_adj_type = 9; | ||
1447 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1448 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1449 | true, 2); | ||
1450 | coex_dm->tdma_adj_type = 2; | ||
1451 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1452 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1453 | true, 9); | ||
1454 | coex_dm->tdma_adj_type = 9; | ||
1455 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1456 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1457 | true, 11); | ||
1458 | coex_dm->tdma_adj_type = 11; | ||
1459 | } | ||
1460 | } else if (result == 1) { | ||
1461 | if ((BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) && | ||
1462 | ((coex_dm->cur_ps_tdma == 1) || | ||
1463 | (coex_dm->cur_ps_tdma == 2))) { | ||
1464 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1465 | true, 9); | ||
1466 | coex_dm->tdma_adj_type = 9; | ||
1467 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1468 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1469 | true, 9); | ||
1470 | coex_dm->tdma_adj_type = 9; | ||
1471 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1472 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1473 | true, 2); | ||
1474 | coex_dm->tdma_adj_type = 2; | ||
1475 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1476 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1477 | true, 1); | ||
1478 | coex_dm->tdma_adj_type = 1; | ||
1479 | } | ||
1480 | } else { | ||
1481 | /*no change*/ | ||
1482 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1483 | "[BTCoex], ********** TDMA(on, %d) **********\n", | ||
1484 | coex_dm->cur_ps_tdma); | ||
1485 | } | ||
1486 | |||
1487 | if (coex_dm->cur_ps_tdma != 1 && | ||
1488 | coex_dm->cur_ps_tdma != 2 && | ||
1489 | coex_dm->cur_ps_tdma != 9 && | ||
1490 | coex_dm->cur_ps_tdma != 11) { | ||
1491 | /* recover to previous adjust type*/ | ||
1492 | halbtc8821a1ant_ps_tdma(btcoexist, | ||
1493 | NORMAL_EXEC, true, | ||
1494 | coex_dm->tdma_adj_type); | ||
1495 | } | ||
1496 | } | ||
1497 | } | ||
1498 | |||
1499 | static void btc8821a1ant_ps_tdma_check_for_pwr_save(struct btc_coexist *btcoex, | ||
1500 | bool new_ps_state) | ||
1501 | { | ||
1502 | u8 lps_mode = 0x0; | ||
1503 | |||
1504 | btcoex->btc_get(btcoex, BTC_GET_U1_LPS_MODE, &lps_mode); | ||
1505 | |||
1506 | if (lps_mode) { | ||
1507 | /* already under LPS state*/ | ||
1508 | if (new_ps_state) { | ||
1509 | /* keep state under LPS, do nothing.*/ | ||
1510 | } else { | ||
1511 | /* will leave LPS state, turn off psTdma first*/ | ||
1512 | halbtc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0); | ||
1513 | } | ||
1514 | } else { | ||
1515 | /* NO PS state*/ | ||
1516 | if (new_ps_state) { | ||
1517 | /* will enter LPS state, turn off psTdma first*/ | ||
1518 | halbtc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0); | ||
1519 | } else { | ||
1520 | /* keep state under NO PS state, do nothing.*/ | ||
1521 | } | ||
1522 | } | ||
1523 | } | ||
1524 | |||
1525 | static void halbtc8821a1ant_power_save_state(struct btc_coexist *btcoexist, | ||
1526 | u8 ps_type, u8 lps_val, | ||
1527 | u8 rpwm_val) | ||
1528 | { | ||
1529 | bool low_pwr_disable = false; | ||
1530 | |||
1531 | switch (ps_type) { | ||
1532 | case BTC_PS_WIFI_NATIVE: | ||
1533 | /* recover to original 32k low power setting*/ | ||
1534 | low_pwr_disable = false; | ||
1535 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1536 | &low_pwr_disable); | ||
1537 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL); | ||
1538 | break; | ||
1539 | case BTC_PS_LPS_ON: | ||
1540 | btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, | ||
1541 | true); | ||
1542 | halbtc8821a1ant_lps_rpwm(btcoexist, | ||
1543 | NORMAL_EXEC, lps_val, rpwm_val); | ||
1544 | /* when coex force to enter LPS, do not enter 32k low power.*/ | ||
1545 | low_pwr_disable = true; | ||
1546 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1547 | &low_pwr_disable); | ||
1548 | /* power save must executed before psTdma.*/ | ||
1549 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL); | ||
1550 | break; | ||
1551 | case BTC_PS_LPS_OFF: | ||
1552 | btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, false); | ||
1553 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL); | ||
1554 | break; | ||
1555 | default: | ||
1556 | break; | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | static void halbtc8821a1ant_coex_under_5g(struct btc_coexist *btcoexist) | ||
1561 | { | ||
1562 | halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1563 | 0x0, 0x0); | ||
1564 | halbtc8821a1ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true); | ||
1565 | |||
1566 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 10); | ||
1567 | |||
1568 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); | ||
1569 | |||
1570 | halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
1571 | |||
1572 | halbtc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 5); | ||
1573 | } | ||
1574 | |||
1575 | static void halbtc8821a1ant_action_wifi_only(struct btc_coexist *btcoexist) | ||
1576 | { | ||
1577 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); | ||
1578 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9); | ||
1579 | } | ||
1580 | |||
1581 | static void btc8821a1ant_mon_bt_en_dis(struct btc_coexist *btcoexist) | ||
1582 | { | ||
1583 | static bool pre_bt_disabled; | ||
1584 | static u32 bt_disable_cnt; | ||
1585 | bool bt_active = true, bt_disabled = false; | ||
1586 | |||
1587 | /* This function check if bt is disabled*/ | ||
1588 | |||
1589 | if (coex_sta->high_priority_tx == 0 && | ||
1590 | coex_sta->high_priority_rx == 0 && | ||
1591 | coex_sta->low_priority_tx == 0 && | ||
1592 | coex_sta->low_priority_rx == 0) { | ||
1593 | bt_active = false; | ||
1594 | } | ||
1595 | if (coex_sta->high_priority_tx == 0xffff && | ||
1596 | coex_sta->high_priority_rx == 0xffff && | ||
1597 | coex_sta->low_priority_tx == 0xffff && | ||
1598 | coex_sta->low_priority_rx == 0xffff) { | ||
1599 | bt_active = false; | ||
1600 | } | ||
1601 | if (bt_active) { | ||
1602 | bt_disable_cnt = 0; | ||
1603 | bt_disabled = false; | ||
1604 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
1605 | &bt_disabled); | ||
1606 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
1607 | "[BTCoex], BT is enabled !!\n"); | ||
1608 | } else { | ||
1609 | bt_disable_cnt++; | ||
1610 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
1611 | "[BTCoex], bt all counters = 0, %d times!!\n", | ||
1612 | bt_disable_cnt); | ||
1613 | if (bt_disable_cnt >= 2) { | ||
1614 | bt_disabled = true; | ||
1615 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
1616 | &bt_disabled); | ||
1617 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
1618 | "[BTCoex], BT is disabled !!\n"); | ||
1619 | halbtc8821a1ant_action_wifi_only(btcoexist); | ||
1620 | } | ||
1621 | } | ||
1622 | if (pre_bt_disabled != bt_disabled) { | ||
1623 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
1624 | "[BTCoex], BT is from %s to %s!!\n", | ||
1625 | (pre_bt_disabled ? "disabled" : "enabled"), | ||
1626 | (bt_disabled ? "disabled" : "enabled")); | ||
1627 | pre_bt_disabled = bt_disabled; | ||
1628 | if (bt_disabled) { | ||
1629 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, | ||
1630 | NULL); | ||
1631 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, | ||
1632 | NULL); | ||
1633 | } | ||
1634 | } | ||
1635 | } | ||
1636 | |||
1637 | /*=============================================*/ | ||
1638 | /**/ | ||
1639 | /* Software Coex Mechanism start*/ | ||
1640 | /**/ | ||
1641 | /*=============================================*/ | ||
1642 | |||
1643 | /* SCO only or SCO+PAN(HS)*/ | ||
1644 | static void halbtc8821a1ant_action_sco(struct btc_coexist *btcoexist) | ||
1645 | { | ||
1646 | halbtc8821a1ant_sw_mechanism(btcoexist, true); | ||
1647 | } | ||
1648 | |||
1649 | static void halbtc8821a1ant_action_hid(struct btc_coexist *btcoexist) | ||
1650 | { | ||
1651 | halbtc8821a1ant_sw_mechanism(btcoexist, true); | ||
1652 | } | ||
1653 | |||
1654 | /*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ | ||
1655 | static void halbtc8821a1ant_action_a2dp(struct btc_coexist *btcoexist) | ||
1656 | { | ||
1657 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1658 | } | ||
1659 | |||
1660 | static void halbtc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) | ||
1661 | { | ||
1662 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1663 | } | ||
1664 | |||
1665 | static void halbtc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist) | ||
1666 | { | ||
1667 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1668 | } | ||
1669 | |||
1670 | /*PAN(HS) only*/ | ||
1671 | static void halbtc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist) | ||
1672 | { | ||
1673 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1674 | } | ||
1675 | |||
1676 | /*PAN(EDR)+A2DP*/ | ||
1677 | static void halbtc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) | ||
1678 | { | ||
1679 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
1680 | } | ||
1681 | |||
1682 | static void halbtc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist) | ||
1683 | { | ||
1684 | halbtc8821a1ant_sw_mechanism(btcoexist, true); | ||
1685 | } | ||
1686 | |||
1687 | /* HID+A2DP+PAN(EDR)*/ | ||
1688 | static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) | ||
1689 | { | ||
1690 | halbtc8821a1ant_sw_mechanism(btcoexist, true); | ||
1691 | } | ||
1692 | |||
1693 | static void halbtc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist) | ||
1694 | { | ||
1695 | halbtc8821a1ant_sw_mechanism(btcoexist, true); | ||
1696 | } | ||
1697 | |||
1698 | /*=============================================*/ | ||
1699 | /**/ | ||
1700 | /* Non-Software Coex Mechanism start*/ | ||
1701 | /**/ | ||
1702 | /*=============================================*/ | ||
1703 | |||
1704 | static void halbtc8821a1ant_action_hs(struct btc_coexist *btcoexist) | ||
1705 | { | ||
1706 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
1707 | halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2); | ||
1708 | } | ||
1709 | |||
1710 | static void halbtc8821a1ant_action_bt_inquiry(struct btc_coexist *btcoexist) | ||
1711 | { | ||
1712 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1713 | bool wifi_connected = false; | ||
1714 | |||
1715 | btcoexist->btc_get(btcoexist, | ||
1716 | BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); | ||
1717 | |||
1718 | if (!wifi_connected) { | ||
1719 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1720 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1721 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
1722 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1723 | } else if ((bt_link_info->sco_exist) || | ||
1724 | (bt_link_info->hid_only)) { | ||
1725 | /* SCO/HID-only busy*/ | ||
1726 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1727 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1728 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32); | ||
1729 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1730 | } else { | ||
1731 | halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_LPS_ON, | ||
1732 | 0x50, 0x4); | ||
1733 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30); | ||
1734 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1735 | } | ||
1736 | } | ||
1737 | |||
1738 | static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist, | ||
1739 | u8 wifi_status) { | ||
1740 | /* tdma and coex table*/ | ||
1741 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
1742 | |||
1743 | if (BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == | ||
1744 | wifi_status) | ||
1745 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1746 | else | ||
1747 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1748 | } | ||
1749 | |||
1750 | static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist, | ||
1751 | u8 wifi_status) | ||
1752 | { | ||
1753 | u8 bt_rssi_state; | ||
1754 | |||
1755 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1756 | |||
1757 | bt_rssi_state = halbtc8821a1ant_bt_rssi_state(2, 28, 0); | ||
1758 | |||
1759 | if (bt_link_info->hid_only) { | ||
1760 | /*HID*/ | ||
1761 | btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
1762 | wifi_status); | ||
1763 | coex_dm->auto_tdma_adjust = false; | ||
1764 | return; | ||
1765 | } else if (bt_link_info->a2dp_only) { | ||
1766 | /*A2DP*/ | ||
1767 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
1768 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
1769 | btc8821a1ant_tdma_dur_adj(btcoexist, wifi_status); | ||
1770 | } else { | ||
1771 | /*for low BT RSSI*/ | ||
1772 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1773 | true, 11); | ||
1774 | coex_dm->auto_tdma_adjust = false; | ||
1775 | } | ||
1776 | |||
1777 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1778 | } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) { | ||
1779 | /*HID+A2DP*/ | ||
1780 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
1781 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
1782 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1783 | true, 14); | ||
1784 | coex_dm->auto_tdma_adjust = false; | ||
1785 | } else { | ||
1786 | /*for low BT RSSI*/ | ||
1787 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1788 | true, 11); | ||
1789 | coex_dm->auto_tdma_adjust = false; | ||
1790 | } | ||
1791 | |||
1792 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1793 | } else if ((bt_link_info->pan_only) || | ||
1794 | (bt_link_info->hid_exist && bt_link_info->pan_exist)) { | ||
1795 | /*PAN(OPP, FTP), HID+PAN(OPP, FTP)*/ | ||
1796 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | ||
1797 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1798 | coex_dm->auto_tdma_adjust = false; | ||
1799 | } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) || | ||
1800 | (bt_link_info->hid_exist && bt_link_info->a2dp_exist && | ||
1801 | bt_link_info->pan_exist)) { | ||
1802 | /*A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP)*/ | ||
1803 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13); | ||
1804 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1805 | coex_dm->auto_tdma_adjust = false; | ||
1806 | } else { | ||
1807 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); | ||
1808 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1809 | coex_dm->auto_tdma_adjust = false; | ||
1810 | } | ||
1811 | } | ||
1812 | |||
1813 | static void halbtc8821a1ant_action_wifi_not_connected( | ||
1814 | struct btc_coexist *btcoexist) | ||
1815 | { | ||
1816 | /* power save state*/ | ||
1817 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1818 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1819 | |||
1820 | /* tdma and coex table*/ | ||
1821 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
1822 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0); | ||
1823 | } | ||
1824 | |||
1825 | static void btc8821a1ant_act_wifi_not_conn_scan(struct btc_coexist *btcoexist) | ||
1826 | { | ||
1827 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1828 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1829 | |||
1830 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22); | ||
1831 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1832 | } | ||
1833 | |||
1834 | static void halbtc8821a1ant_action_wifi_connected_scan( | ||
1835 | struct btc_coexist *btcoexist) { | ||
1836 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1837 | |||
1838 | /* power save state*/ | ||
1839 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1840 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
1841 | |||
1842 | /* tdma and coex table*/ | ||
1843 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1844 | if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) { | ||
1845 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1846 | true, 22); | ||
1847 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
1848 | NORMAL_EXEC, 1); | ||
1849 | } else { | ||
1850 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); | ||
1851 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1852 | } | ||
1853 | } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY == | ||
1854 | coex_dm->bt_status) || | ||
1855 | (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
1856 | coex_dm->bt_status)) { | ||
1857 | btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
1858 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN); | ||
1859 | } else { | ||
1860 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); | ||
1861 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1862 | } | ||
1863 | } | ||
1864 | |||
1865 | static void btc8821a1ant_act_wifi_conn_sp_pkt(struct btc_coexist *btcoexist) | ||
1866 | { | ||
1867 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
1868 | bool hs_connecting = false; | ||
1869 | |||
1870 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting); | ||
1871 | |||
1872 | halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
1873 | 0x0, 0x0); | ||
1874 | |||
1875 | /* tdma and coex table*/ | ||
1876 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1877 | if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) { | ||
1878 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1879 | true, 22); | ||
1880 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
1881 | NORMAL_EXEC, 1); | ||
1882 | } else { | ||
1883 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1884 | true, 20); | ||
1885 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
1886 | NORMAL_EXEC, 1); | ||
1887 | } | ||
1888 | } else { | ||
1889 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20); | ||
1890 | halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | static void halbtc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist) | ||
1895 | { | ||
1896 | bool wifi_busy = false; | ||
1897 | bool scan = false, link = false, roam = false; | ||
1898 | bool under_4way = false; | ||
1899 | |||
1900 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1901 | "[BTCoex], CoexForWifiConnect()===>\n"); | ||
1902 | |||
1903 | btcoexist->btc_get(btcoexist, | ||
1904 | BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way); | ||
1905 | if (under_4way) { | ||
1906 | btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); | ||
1907 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1908 | "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"); | ||
1909 | return; | ||
1910 | } | ||
1911 | |||
1912 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
1913 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
1914 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
1915 | if (scan || link || roam) { | ||
1916 | halbtc8821a1ant_action_wifi_connected_scan(btcoexist); | ||
1917 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1918 | "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"); | ||
1919 | return; | ||
1920 | } | ||
1921 | |||
1922 | /* power save state*/ | ||
1923 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == | ||
1924 | coex_dm->bt_status && !btcoexist->bt_link_info.hid_only) | ||
1925 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1926 | BTC_PS_LPS_ON, 0x50, 0x4); | ||
1927 | else | ||
1928 | halbtc8821a1ant_power_save_state(btcoexist, | ||
1929 | BTC_PS_WIFI_NATIVE, | ||
1930 | 0x0, 0x0); | ||
1931 | |||
1932 | /* tdma and coex table*/ | ||
1933 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1934 | if (!wifi_busy) { | ||
1935 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1936 | btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist, | ||
1937 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); | ||
1938 | } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY == | ||
1939 | coex_dm->bt_status) || | ||
1940 | (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
1941 | coex_dm->bt_status)) { | ||
1942 | btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
1943 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE); | ||
1944 | } else { | ||
1945 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1946 | true, 5); | ||
1947 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
1948 | NORMAL_EXEC, 2); | ||
1949 | } | ||
1950 | } else { | ||
1951 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) { | ||
1952 | btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist, | ||
1953 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); | ||
1954 | } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY == | ||
1955 | coex_dm->bt_status) || | ||
1956 | (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == | ||
1957 | coex_dm->bt_status)) { | ||
1958 | btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist, | ||
1959 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY); | ||
1960 | } else { | ||
1961 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1962 | true, 5); | ||
1963 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
1964 | NORMAL_EXEC, 2); | ||
1965 | } | ||
1966 | } | ||
1967 | } | ||
1968 | |||
1969 | static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist) | ||
1970 | { | ||
1971 | u8 algorithm = 0; | ||
1972 | |||
1973 | algorithm = halbtc8821a1ant_action_algorithm(btcoexist); | ||
1974 | coex_dm->cur_algorithm = algorithm; | ||
1975 | |||
1976 | if (!halbtc8821a1ant_is_common_action(btcoexist)) { | ||
1977 | switch (coex_dm->cur_algorithm) { | ||
1978 | case BT_8821A_1ANT_COEX_ALGO_SCO: | ||
1979 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1980 | "[BTCoex], Action algorithm = SCO.\n"); | ||
1981 | halbtc8821a1ant_action_sco(btcoexist); | ||
1982 | break; | ||
1983 | case BT_8821A_1ANT_COEX_ALGO_HID: | ||
1984 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1985 | "[BTCoex], Action algorithm = HID.\n"); | ||
1986 | halbtc8821a1ant_action_hid(btcoexist); | ||
1987 | break; | ||
1988 | case BT_8821A_1ANT_COEX_ALGO_A2DP: | ||
1989 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1990 | "[BTCoex], Action algorithm = A2DP.\n"); | ||
1991 | halbtc8821a1ant_action_a2dp(btcoexist); | ||
1992 | break; | ||
1993 | case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS: | ||
1994 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1995 | "[BTCoex], Action algorithm = A2DP+PAN(HS).\n"); | ||
1996 | halbtc8821a1ant_action_a2dp_pan_hs(btcoexist); | ||
1997 | break; | ||
1998 | case BT_8821A_1ANT_COEX_ALGO_PANEDR: | ||
1999 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2000 | "[BTCoex], Action algorithm = PAN(EDR).\n"); | ||
2001 | halbtc8821a1ant_action_pan_edr(btcoexist); | ||
2002 | break; | ||
2003 | case BT_8821A_1ANT_COEX_ALGO_PANHS: | ||
2004 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2005 | "[BTCoex], Action algorithm = HS mode.\n"); | ||
2006 | halbtc8821a1ant_action_pan_hs(btcoexist); | ||
2007 | break; | ||
2008 | case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP: | ||
2009 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2010 | "[BTCoex], Action algorithm = PAN+A2DP.\n"); | ||
2011 | halbtc8821a1ant_action_pan_edr_a2dp(btcoexist); | ||
2012 | break; | ||
2013 | case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID: | ||
2014 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2015 | "[BTCoex], Action algorithm = PAN(EDR)+HID.\n"); | ||
2016 | halbtc8821a1ant_action_pan_edr_hid(btcoexist); | ||
2017 | break; | ||
2018 | case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
2019 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2020 | "[BTCoex], Action algorithm = HID+A2DP+PAN.\n"); | ||
2021 | btc8821a1ant_action_hid_a2dp_pan_edr(btcoexist); | ||
2022 | break; | ||
2023 | case BT_8821A_1ANT_COEX_ALGO_HID_A2DP: | ||
2024 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2025 | "[BTCoex], Action algorithm = HID+A2DP.\n"); | ||
2026 | halbtc8821a1ant_action_hid_a2dp(btcoexist); | ||
2027 | break; | ||
2028 | default: | ||
2029 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2030 | "[BTCoex], Action algorithm = coexist All Off!!\n"); | ||
2031 | /*halbtc8821a1ant_coex_all_off(btcoexist);*/ | ||
2032 | break; | ||
2033 | } | ||
2034 | coex_dm->pre_algorithm = coex_dm->cur_algorithm; | ||
2035 | } | ||
2036 | } | ||
2037 | |||
2038 | static void halbtc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | ||
2039 | { | ||
2040 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
2041 | bool wifi_connected = false, bt_hs_on = false; | ||
2042 | bool increase_scan_dev_num = false; | ||
2043 | bool bt_ctrl_agg_buf_size = false; | ||
2044 | u8 agg_buf_size = 5; | ||
2045 | u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
2046 | bool wifi_under_5g = false; | ||
2047 | |||
2048 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2049 | "[BTCoex], RunCoexistMechanism()===>\n"); | ||
2050 | |||
2051 | if (btcoexist->manual_control) { | ||
2052 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2053 | "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"); | ||
2054 | return; | ||
2055 | } | ||
2056 | |||
2057 | if (btcoexist->stop_coex_dm) { | ||
2058 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2059 | "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"); | ||
2060 | return; | ||
2061 | } | ||
2062 | |||
2063 | if (coex_sta->under_ips) { | ||
2064 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2065 | "[BTCoex], wifi is under IPS !!!\n"); | ||
2066 | return; | ||
2067 | } | ||
2068 | |||
2069 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
2070 | if (wifi_under_5g) { | ||
2071 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2072 | "[BTCoex], RunCoexistMechanism(), return for 5G <===\n"); | ||
2073 | halbtc8821a1ant_coex_under_5g(btcoexist); | ||
2074 | return; | ||
2075 | } | ||
2076 | |||
2077 | if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || | ||
2078 | (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
2079 | (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) | ||
2080 | increase_scan_dev_num = true; | ||
2081 | |||
2082 | btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM, | ||
2083 | &increase_scan_dev_num); | ||
2084 | |||
2085 | btcoexist->btc_get(btcoexist, | ||
2086 | BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); | ||
2087 | |||
2088 | if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) { | ||
2089 | halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0); | ||
2090 | } else { | ||
2091 | if (wifi_connected) { | ||
2092 | wifi_rssi_state = | ||
2093 | halbtc8821a1ant_WifiRssiState(btcoexist, 1, 2, | ||
2094 | 30, 0); | ||
2095 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2096 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2097 | halbtc8821a1ant_limited_tx(btcoexist, | ||
2098 | NORMAL_EXEC, 1, 1, | ||
2099 | 1, 1); | ||
2100 | } else { | ||
2101 | halbtc8821a1ant_limited_tx(btcoexist, | ||
2102 | NORMAL_EXEC, 1, 1, | ||
2103 | 1, 1); | ||
2104 | } | ||
2105 | } else { | ||
2106 | halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, | ||
2107 | 0, 0, 0, 0); | ||
2108 | } | ||
2109 | } | ||
2110 | |||
2111 | if (bt_link_info->sco_exist) { | ||
2112 | bt_ctrl_agg_buf_size = true; | ||
2113 | agg_buf_size = 0x3; | ||
2114 | } else if (bt_link_info->hid_exist) { | ||
2115 | bt_ctrl_agg_buf_size = true; | ||
2116 | agg_buf_size = 0x5; | ||
2117 | } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) { | ||
2118 | bt_ctrl_agg_buf_size = true; | ||
2119 | agg_buf_size = 0x8; | ||
2120 | } | ||
2121 | halbtc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, | ||
2122 | bt_ctrl_agg_buf_size, agg_buf_size); | ||
2123 | |||
2124 | btc8821a1ant_run_sw_coex_mech(btcoexist); | ||
2125 | |||
2126 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2127 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2128 | halbtc8821a1ant_action_bt_inquiry(btcoexist); | ||
2129 | return; | ||
2130 | } else if (bt_hs_on) { | ||
2131 | halbtc8821a1ant_action_hs(btcoexist); | ||
2132 | return; | ||
2133 | } | ||
2134 | |||
2135 | if (!wifi_connected) { | ||
2136 | bool scan = false, link = false, roam = false; | ||
2137 | |||
2138 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2139 | "[BTCoex], wifi is non connected-idle !!!\n"); | ||
2140 | |||
2141 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2142 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2143 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2144 | |||
2145 | if (scan || link || roam) | ||
2146 | btc8821a1ant_act_wifi_not_conn_scan(btcoexist); | ||
2147 | else | ||
2148 | halbtc8821a1ant_action_wifi_not_connected(btcoexist); | ||
2149 | } else { | ||
2150 | /* wifi LPS/Busy*/ | ||
2151 | halbtc8821a1ant_action_wifi_connected(btcoexist); | ||
2152 | } | ||
2153 | } | ||
2154 | |||
2155 | static void halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
2156 | { | ||
2157 | /* force to reset coex mechanism*/ | ||
2158 | /* sw all off*/ | ||
2159 | halbtc8821a1ant_sw_mechanism(btcoexist, false); | ||
2160 | |||
2161 | halbtc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8); | ||
2162 | halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); | ||
2163 | } | ||
2164 | |||
2165 | static void halbtc8821a1ant_init_hw_config(struct btc_coexist *btcoexist, | ||
2166 | bool back_up) | ||
2167 | { | ||
2168 | u8 u1_tmp = 0; | ||
2169 | bool wifi_under_5g = false; | ||
2170 | |||
2171 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2172 | "[BTCoex], 1Ant Init HW Config!!\n"); | ||
2173 | |||
2174 | if (back_up) { | ||
2175 | coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist, | ||
2176 | 0x430); | ||
2177 | coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist, | ||
2178 | 0x434); | ||
2179 | coex_dm->backup_retry_limit = | ||
2180 | btcoexist->btc_read_2byte(btcoexist, 0x42a); | ||
2181 | coex_dm->backup_ampdu_max_time = | ||
2182 | btcoexist->btc_read_1byte(btcoexist, 0x456); | ||
2183 | } | ||
2184 | |||
2185 | /* 0x790[5:0] = 0x5*/ | ||
2186 | u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); | ||
2187 | u1_tmp &= 0xc0; | ||
2188 | u1_tmp |= 0x5; | ||
2189 | btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp); | ||
2190 | |||
2191 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
2192 | |||
2193 | /*Antenna config*/ | ||
2194 | if (wifi_under_5g) | ||
2195 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, | ||
2196 | true, false); | ||
2197 | else | ||
2198 | halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA, | ||
2199 | true, false); | ||
2200 | /* PTA parameter*/ | ||
2201 | halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0); | ||
2202 | |||
2203 | /* Enable counter statistics*/ | ||
2204 | /*0x76e[3] =1, WLAN_Act control by PTA*/ | ||
2205 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
2206 | btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); | ||
2207 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); | ||
2208 | } | ||
2209 | |||
2210 | /*============================================================*/ | ||
2211 | /* work around function start with wa_halbtc8821a1ant_*/ | ||
2212 | /*============================================================*/ | ||
2213 | /*============================================================*/ | ||
2214 | /* extern function start with EXhalbtc8821a1ant_*/ | ||
2215 | /*============================================================*/ | ||
2216 | void ex_halbtc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist) | ||
2217 | { | ||
2218 | halbtc8821a1ant_init_hw_config(btcoexist, true); | ||
2219 | } | ||
2220 | |||
2221 | void ex_halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
2222 | { | ||
2223 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2224 | "[BTCoex], Coex Mechanism Init!!\n"); | ||
2225 | |||
2226 | btcoexist->stop_coex_dm = false; | ||
2227 | |||
2228 | halbtc8821a1ant_init_coex_dm(btcoexist); | ||
2229 | |||
2230 | halbtc8821a1ant_query_bt_info(btcoexist); | ||
2231 | } | ||
2232 | |||
2233 | void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist) | ||
2234 | { | ||
2235 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
2236 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
2237 | struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; | ||
2238 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
2239 | u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0; | ||
2240 | u16 u2_tmp[4]; | ||
2241 | u32 u4_tmp[4]; | ||
2242 | bool roam = false, scan = false, link = false, wifi_under_5g = false; | ||
2243 | bool bt_hs_on = false, wifi_busy = false; | ||
2244 | long wifi_rssi = 0, bt_hs_rssi = 0; | ||
2245 | u32 wifi_bw, wifi_traffic_dir; | ||
2246 | u8 wifi_dot11_chnl, wifi_hs_chnl; | ||
2247 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
2248 | |||
2249 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2250 | "\r\n ============[BT Coexist info]============"); | ||
2251 | |||
2252 | if (btcoexist->manual_control) { | ||
2253 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2254 | "\r\n ============[Under Manual Control]============"); | ||
2255 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2256 | "\r\n =========================================="); | ||
2257 | } | ||
2258 | if (btcoexist->stop_coex_dm) { | ||
2259 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2260 | "\r\n ============[Coex is STOPPED]============"); | ||
2261 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2262 | "\r\n =========================================="); | ||
2263 | } | ||
2264 | |||
2265 | if (!board_info->bt_exist) { | ||
2266 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!"); | ||
2267 | return; | ||
2268 | } | ||
2269 | |||
2270 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2271 | "\r\n %-35s = %d/ %d/ %d", | ||
2272 | "Ant PG Num/ Ant Mech/ Ant Pos:", | ||
2273 | board_info->pg_ant_num, | ||
2274 | board_info->btdm_ant_num, | ||
2275 | board_info->btdm_ant_pos); | ||
2276 | |||
2277 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2278 | "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", | ||
2279 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
2280 | stack_info->hci_version); | ||
2281 | |||
2282 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, | ||
2283 | &bt_patch_ver); | ||
2284 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
2285 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2286 | "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", | ||
2287 | "CoexVer/ FwVer/ PatchVer", | ||
2288 | glcoex_ver_date_8821a_1ant, | ||
2289 | glcoex_ver_8821a_1ant, | ||
2290 | fw_ver, bt_patch_ver, | ||
2291 | bt_patch_ver); | ||
2292 | |||
2293 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, | ||
2294 | &bt_hs_on); | ||
2295 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, | ||
2296 | &wifi_dot11_chnl); | ||
2297 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, | ||
2298 | &wifi_hs_chnl); | ||
2299 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2300 | "\r\n %-35s = %d / %d(%d)", | ||
2301 | "Dot11 channel / HsChnl(HsMode)", | ||
2302 | wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); | ||
2303 | |||
2304 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2305 | "\r\n %-35s = %02x %02x %02x ", | ||
2306 | "H2C Wifi inform bt chnl Info", | ||
2307 | coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1], | ||
2308 | coex_dm->wifi_chnl_info[2]); | ||
2309 | |||
2310 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
2311 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); | ||
2312 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2313 | "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", | ||
2314 | (int)wifi_rssi, (int)bt_hs_rssi); | ||
2315 | |||
2316 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2317 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2318 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2319 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2320 | "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan", | ||
2321 | link, roam, scan); | ||
2322 | |||
2323 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, | ||
2324 | &wifi_under_5g); | ||
2325 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, | ||
2326 | &wifi_bw); | ||
2327 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, | ||
2328 | &wifi_busy); | ||
2329 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, | ||
2330 | &wifi_traffic_dir); | ||
2331 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2332 | "\r\n %-35s = %s / %s/ %s ", "Wifi status", | ||
2333 | (wifi_under_5g ? "5G" : "2.4G"), | ||
2334 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : | ||
2335 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), | ||
2336 | ((!wifi_busy) ? "idle" : | ||
2337 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? | ||
2338 | "uplink" : "downlink"))); | ||
2339 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2340 | "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", | ||
2341 | ((btcoexist->bt_info.bt_disabled) ? ("disabled") : | ||
2342 | ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : | ||
2343 | ((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == | ||
2344 | coex_dm->bt_status) ? | ||
2345 | "non-connected idle" : | ||
2346 | ((BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE == | ||
2347 | coex_dm->bt_status) ? | ||
2348 | "connected-idle" : "busy")))), | ||
2349 | coex_sta->bt_rssi, coex_sta->bt_retry_cnt); | ||
2350 | |||
2351 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2352 | "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", | ||
2353 | bt_link_info->sco_exist, | ||
2354 | bt_link_info->hid_exist, | ||
2355 | bt_link_info->pan_exist, | ||
2356 | bt_link_info->a2dp_exist); | ||
2357 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); | ||
2358 | |||
2359 | bt_info_ext = coex_sta->bt_info_ext; | ||
2360 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2361 | "\r\n %-35s = %s", | ||
2362 | "BT Info A2DP rate", | ||
2363 | (bt_info_ext&BIT0) ? | ||
2364 | "Basic rate" : "EDR rate"); | ||
2365 | |||
2366 | for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) { | ||
2367 | if (coex_sta->bt_info_c2h_cnt[i]) { | ||
2368 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2369 | "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", | ||
2370 | glbt_info_src_8821a_1ant[i], | ||
2371 | coex_sta->bt_info_c2h[i][0], | ||
2372 | coex_sta->bt_info_c2h[i][1], | ||
2373 | coex_sta->bt_info_c2h[i][2], | ||
2374 | coex_sta->bt_info_c2h[i][3], | ||
2375 | coex_sta->bt_info_c2h[i][4], | ||
2376 | coex_sta->bt_info_c2h[i][5], | ||
2377 | coex_sta->bt_info_c2h[i][6], | ||
2378 | coex_sta->bt_info_c2h_cnt[i]); | ||
2379 | } | ||
2380 | } | ||
2381 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2382 | "\r\n %-35s = %s/%s, (0x%x/0x%x)", | ||
2383 | "PS state, IPS/LPS, (lps/rpwm)", | ||
2384 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), | ||
2385 | ((coex_sta->under_Lps ? "LPS ON" : "LPS OFF")), | ||
2386 | btcoexist->bt_info.lps_val, | ||
2387 | btcoexist->bt_info.rpwm_val); | ||
2388 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); | ||
2389 | |||
2390 | if (!btcoexist->manual_control) { | ||
2391 | /* Sw mechanism*/ | ||
2392 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2393 | "\r\n %-35s", "============[Sw mechanism]============"); | ||
2394 | |||
2395 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2396 | "\r\n %-35s = %d", "SM[LowPenaltyRA]", | ||
2397 | coex_dm->cur_low_penalty_ra); | ||
2398 | |||
2399 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2400 | "\r\n %-35s = %s/ %s/ %d ", | ||
2401 | "DelBA/ BtCtrlAgg/ AggSize", | ||
2402 | (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"), | ||
2403 | (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"), | ||
2404 | btcoexist->bt_info.agg_buf_size); | ||
2405 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2406 | "\r\n %-35s = 0x%x ", "Rate Mask", | ||
2407 | btcoexist->bt_info.ra_mask); | ||
2408 | |||
2409 | /* Fw mechanism*/ | ||
2410 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
2411 | "============[Fw mechanism]============"); | ||
2412 | |||
2413 | ps_tdma_case = coex_dm->cur_ps_tdma; | ||
2414 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2415 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", | ||
2416 | "PS TDMA", | ||
2417 | coex_dm->ps_tdma_para[0], | ||
2418 | coex_dm->ps_tdma_para[1], | ||
2419 | coex_dm->ps_tdma_para[2], | ||
2420 | coex_dm->ps_tdma_para[3], | ||
2421 | coex_dm->ps_tdma_para[4], | ||
2422 | ps_tdma_case, | ||
2423 | coex_dm->auto_tdma_adjust); | ||
2424 | |||
2425 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2426 | "\r\n %-35s = 0x%x ", | ||
2427 | "Latest error condition(should be 0)", | ||
2428 | coex_dm->error_condition); | ||
2429 | |||
2430 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2431 | "\r\n %-35s = %d ", "IgnWlanAct", | ||
2432 | coex_dm->cur_ignore_wlan_act); | ||
2433 | } | ||
2434 | |||
2435 | /* Hw setting*/ | ||
2436 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2437 | "\r\n %-35s", "============[Hw setting]============"); | ||
2438 | |||
2439 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2440 | "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
2441 | "backup ARFR1/ARFR2/RL/AMaxTime", | ||
2442 | coex_dm->backup_arfr_cnt1, | ||
2443 | coex_dm->backup_arfr_cnt2, | ||
2444 | coex_dm->backup_retry_limit, | ||
2445 | coex_dm->backup_ampdu_max_time); | ||
2446 | |||
2447 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430); | ||
2448 | u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434); | ||
2449 | u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a); | ||
2450 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456); | ||
2451 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2452 | "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x", | ||
2453 | "0x430/0x434/0x42a/0x456", | ||
2454 | u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]); | ||
2455 | |||
2456 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); | ||
2457 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58); | ||
2458 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2459 | "\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]", | ||
2460 | u1_tmp[0], (u4_tmp[0]&0x3e000000) >> 25); | ||
2461 | |||
2462 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db); | ||
2463 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2464 | "\r\n %-35s = 0x%x", "0x8db[6:5]", | ||
2465 | ((u1_tmp[0]&0x60)>>5)); | ||
2466 | |||
2467 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975); | ||
2468 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4); | ||
2469 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2470 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2471 | "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]", | ||
2472 | (u4_tmp[0] & 0x30000000)>>28, | ||
2473 | u4_tmp[0] & 0xff, | ||
2474 | u1_tmp[0] & 0x3); | ||
2475 | |||
2476 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); | ||
2477 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
2478 | u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64); | ||
2479 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2480 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
2481 | "0x40/0x4c[24:23]/0x64[0]", | ||
2482 | u1_tmp[0], ((u4_tmp[0]&0x01800000)>>23), u1_tmp[1]&0x1); | ||
2483 | |||
2484 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); | ||
2485 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); | ||
2486 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2487 | "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", | ||
2488 | u4_tmp[0], u1_tmp[0]); | ||
2489 | |||
2490 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); | ||
2491 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2492 | "\r\n %-35s = 0x%x", "0xc50(dig)", | ||
2493 | u4_tmp[0]&0xff); | ||
2494 | |||
2495 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48); | ||
2496 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d); | ||
2497 | u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); | ||
2498 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2499 | "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA", | ||
2500 | u4_tmp[0], (u1_tmp[0]<<8) + u1_tmp[1]); | ||
2501 | |||
2502 | u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); | ||
2503 | u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); | ||
2504 | u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); | ||
2505 | u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); | ||
2506 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2507 | "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", | ||
2508 | "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", | ||
2509 | u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]); | ||
2510 | |||
2511 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2512 | "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)", | ||
2513 | coex_sta->high_priority_rx, coex_sta->high_priority_tx); | ||
2514 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
2515 | "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)", | ||
2516 | coex_sta->low_priority_rx, coex_sta->low_priority_tx); | ||
2517 | #if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 1) | ||
2518 | halbtc8821a1ant_monitor_bt_ctr(btcoexist); | ||
2519 | #endif | ||
2520 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS); | ||
2521 | } | ||
2522 | |||
2523 | void ex_halbtc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | ||
2524 | { | ||
2525 | if (btcoexist->manual_control || btcoexist->stop_coex_dm) | ||
2526 | return; | ||
2527 | |||
2528 | if (BTC_IPS_ENTER == type) { | ||
2529 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2530 | "[BTCoex], IPS ENTER notify\n"); | ||
2531 | coex_sta->under_ips = true; | ||
2532 | halbtc8821a1ant_set_ant_path(btcoexist, | ||
2533 | BTC_ANT_PATH_BT, false, true); | ||
2534 | /*set PTA control*/ | ||
2535 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8); | ||
2536 | halbtc8821a1ant_coex_table_with_type(btcoexist, | ||
2537 | NORMAL_EXEC, 0); | ||
2538 | } else if (BTC_IPS_LEAVE == type) { | ||
2539 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2540 | "[BTCoex], IPS LEAVE notify\n"); | ||
2541 | coex_sta->under_ips = false; | ||
2542 | |||
2543 | halbtc8821a1ant_run_coexist_mechanism(btcoexist); | ||
2544 | } | ||
2545 | } | ||
2546 | |||
2547 | void ex_halbtc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | ||
2548 | { | ||
2549 | if (btcoexist->manual_control || btcoexist->stop_coex_dm) | ||
2550 | return; | ||
2551 | |||
2552 | if (BTC_LPS_ENABLE == type) { | ||
2553 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2554 | "[BTCoex], LPS ENABLE notify\n"); | ||
2555 | coex_sta->under_Lps = true; | ||
2556 | } else if (BTC_LPS_DISABLE == type) { | ||
2557 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2558 | "[BTCoex], LPS DISABLE notify\n"); | ||
2559 | coex_sta->under_Lps = false; | ||
2560 | } | ||
2561 | } | ||
2562 | |||
2563 | void ex_halbtc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | ||
2564 | { | ||
2565 | bool wifi_connected = false, bt_hs_on = false; | ||
2566 | |||
2567 | if (btcoexist->manual_control || | ||
2568 | btcoexist->stop_coex_dm || | ||
2569 | btcoexist->bt_info.bt_disabled) | ||
2570 | return; | ||
2571 | |||
2572 | btcoexist->btc_get(btcoexist, | ||
2573 | BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2574 | btcoexist->btc_get(btcoexist, | ||
2575 | BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); | ||
2576 | |||
2577 | halbtc8821a1ant_query_bt_info(btcoexist); | ||
2578 | |||
2579 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2580 | halbtc8821a1ant_action_bt_inquiry(btcoexist); | ||
2581 | return; | ||
2582 | } else if (bt_hs_on) { | ||
2583 | halbtc8821a1ant_action_hs(btcoexist); | ||
2584 | return; | ||
2585 | } | ||
2586 | |||
2587 | if (BTC_SCAN_START == type) { | ||
2588 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2589 | "[BTCoex], SCAN START notify\n"); | ||
2590 | if (!wifi_connected) { | ||
2591 | /* non-connected scan*/ | ||
2592 | btc8821a1ant_act_wifi_not_conn_scan(btcoexist); | ||
2593 | } else { | ||
2594 | /* wifi is connected*/ | ||
2595 | halbtc8821a1ant_action_wifi_connected_scan(btcoexist); | ||
2596 | } | ||
2597 | } else if (BTC_SCAN_FINISH == type) { | ||
2598 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2599 | "[BTCoex], SCAN FINISH notify\n"); | ||
2600 | if (!wifi_connected) { | ||
2601 | /* non-connected scan*/ | ||
2602 | halbtc8821a1ant_action_wifi_not_connected(btcoexist); | ||
2603 | } else { | ||
2604 | halbtc8821a1ant_action_wifi_connected(btcoexist); | ||
2605 | } | ||
2606 | } | ||
2607 | } | ||
2608 | |||
2609 | void ex_halbtc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | ||
2610 | { | ||
2611 | bool wifi_connected = false, bt_hs_on = false; | ||
2612 | |||
2613 | if (btcoexist->manual_control || | ||
2614 | btcoexist->stop_coex_dm || | ||
2615 | btcoexist->bt_info.bt_disabled) | ||
2616 | return; | ||
2617 | |||
2618 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2619 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2620 | halbtc8821a1ant_action_bt_inquiry(btcoexist); | ||
2621 | return; | ||
2622 | } else if (bt_hs_on) { | ||
2623 | halbtc8821a1ant_action_hs(btcoexist); | ||
2624 | return; | ||
2625 | } | ||
2626 | |||
2627 | if (BTC_ASSOCIATE_START == type) { | ||
2628 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2629 | "[BTCoex], CONNECT START notify\n"); | ||
2630 | btc8821a1ant_act_wifi_not_conn_scan(btcoexist); | ||
2631 | } else if (BTC_ASSOCIATE_FINISH == type) { | ||
2632 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2633 | "[BTCoex], CONNECT FINISH notify\n"); | ||
2634 | |||
2635 | btcoexist->btc_get(btcoexist, | ||
2636 | BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); | ||
2637 | if (!wifi_connected) { | ||
2638 | /* non-connected scan*/ | ||
2639 | halbtc8821a1ant_action_wifi_not_connected(btcoexist); | ||
2640 | } else { | ||
2641 | halbtc8821a1ant_action_wifi_connected(btcoexist); | ||
2642 | } | ||
2643 | } | ||
2644 | } | ||
2645 | |||
2646 | void ex_halbtc8821a1ant_media_status_notify(struct btc_coexist *btcoexist, | ||
2647 | u8 type) | ||
2648 | { | ||
2649 | u8 h2c_parameter[3] = {0}; | ||
2650 | u32 wifi_bw; | ||
2651 | u8 wifi_central_chnl; | ||
2652 | |||
2653 | if (btcoexist->manual_control || | ||
2654 | btcoexist->stop_coex_dm || | ||
2655 | btcoexist->bt_info.bt_disabled) | ||
2656 | return; | ||
2657 | |||
2658 | if (BTC_MEDIA_CONNECT == type) { | ||
2659 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2660 | "[BTCoex], MEDIA connect notify\n"); | ||
2661 | } else { | ||
2662 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2663 | "[BTCoex], MEDIA disconnect notify\n"); | ||
2664 | } | ||
2665 | |||
2666 | /* only 2.4G we need to inform bt the chnl mask*/ | ||
2667 | btcoexist->btc_get(btcoexist, | ||
2668 | BTC_GET_U1_WIFI_CENTRAL_CHNL, | ||
2669 | &wifi_central_chnl); | ||
2670 | if ((BTC_MEDIA_CONNECT == type) && | ||
2671 | (wifi_central_chnl <= 14)) { | ||
2672 | /*h2c_parameter[0] = 0x1;*/ | ||
2673 | h2c_parameter[0] = 0x0; | ||
2674 | h2c_parameter[1] = wifi_central_chnl; | ||
2675 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2676 | if (BTC_WIFI_BW_HT40 == wifi_bw) | ||
2677 | h2c_parameter[2] = 0x30; | ||
2678 | else | ||
2679 | h2c_parameter[2] = 0x20; | ||
2680 | } | ||
2681 | |||
2682 | coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; | ||
2683 | coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; | ||
2684 | coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; | ||
2685 | |||
2686 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
2687 | "[BTCoex], FW write 0x66 = 0x%x\n", | ||
2688 | h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]); | ||
2689 | |||
2690 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); | ||
2691 | } | ||
2692 | |||
2693 | void ex_halbtc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
2694 | u8 type) | ||
2695 | { | ||
2696 | bool bt_hs_on = false; | ||
2697 | |||
2698 | if (btcoexist->manual_control || | ||
2699 | btcoexist->stop_coex_dm || | ||
2700 | btcoexist->bt_info.bt_disabled) | ||
2701 | return; | ||
2702 | |||
2703 | coex_sta->special_pkt_period_cnt = 0; | ||
2704 | |||
2705 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
2706 | if (coex_sta->c2h_bt_inquiry_page) { | ||
2707 | halbtc8821a1ant_action_bt_inquiry(btcoexist); | ||
2708 | return; | ||
2709 | } else if (bt_hs_on) { | ||
2710 | halbtc8821a1ant_action_hs(btcoexist); | ||
2711 | return; | ||
2712 | } | ||
2713 | |||
2714 | if (BTC_PACKET_DHCP == type || | ||
2715 | BTC_PACKET_EAPOL == type) { | ||
2716 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2717 | "[BTCoex], special Packet(%d) notify\n", type); | ||
2718 | btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist); | ||
2719 | } | ||
2720 | } | ||
2721 | |||
2722 | void ex_halbtc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
2723 | u8 *tmp_buf, u8 length) | ||
2724 | { | ||
2725 | u8 bt_info = 0; | ||
2726 | u8 i, rsp_source = 0; | ||
2727 | bool wifi_connected = false; | ||
2728 | bool bt_busy = false; | ||
2729 | bool wifi_under_5g = false; | ||
2730 | |||
2731 | coex_sta->c2h_bt_info_req_sent = false; | ||
2732 | |||
2733 | btcoexist->btc_get(btcoexist, | ||
2734 | BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
2735 | |||
2736 | rsp_source = tmp_buf[0]&0xf; | ||
2737 | if (rsp_source >= BT_INFO_SRC_8821A_1ANT_MAX) | ||
2738 | rsp_source = BT_INFO_SRC_8821A_1ANT_WIFI_FW; | ||
2739 | coex_sta->bt_info_c2h_cnt[rsp_source]++; | ||
2740 | |||
2741 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2742 | "[BTCoex], Bt info[%d], length = %d, hex data = [", | ||
2743 | rsp_source, length); | ||
2744 | for (i = 0; i < length; i++) { | ||
2745 | coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; | ||
2746 | if (i == 1) | ||
2747 | bt_info = tmp_buf[i]; | ||
2748 | if (i == length-1) { | ||
2749 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2750 | "0x%02x]\n", tmp_buf[i]); | ||
2751 | } else { | ||
2752 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2753 | "0x%02x, ", tmp_buf[i]); | ||
2754 | } | ||
2755 | } | ||
2756 | |||
2757 | if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) { | ||
2758 | coex_sta->bt_retry_cnt = /* [3:0]*/ | ||
2759 | coex_sta->bt_info_c2h[rsp_source][2]&0xf; | ||
2760 | |||
2761 | coex_sta->bt_rssi = | ||
2762 | coex_sta->bt_info_c2h[rsp_source][3]*2+10; | ||
2763 | |||
2764 | coex_sta->bt_info_ext = | ||
2765 | coex_sta->bt_info_c2h[rsp_source][4]; | ||
2766 | |||
2767 | /* Here we need to resend some wifi info to BT*/ | ||
2768 | /* because bt is reset and loss of the info.*/ | ||
2769 | if (coex_sta->bt_info_ext & BIT1) { | ||
2770 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2771 | "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"); | ||
2772 | btcoexist->btc_get(btcoexist, | ||
2773 | BTC_GET_BL_WIFI_CONNECTED, | ||
2774 | &wifi_connected); | ||
2775 | if (wifi_connected) { | ||
2776 | ex_halbtc8821a1ant_media_status_notify(btcoexist, | ||
2777 | BTC_MEDIA_CONNECT); | ||
2778 | } else { | ||
2779 | ex_halbtc8821a1ant_media_status_notify(btcoexist, | ||
2780 | BTC_MEDIA_DISCONNECT); | ||
2781 | } | ||
2782 | } | ||
2783 | |||
2784 | if ((coex_sta->bt_info_ext & BIT3) && !wifi_under_5g) { | ||
2785 | if (!btcoexist->manual_control && | ||
2786 | !btcoexist->stop_coex_dm) { | ||
2787 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2788 | "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"); | ||
2789 | halbtc8821a1ant_ignore_wlan_act(btcoexist, | ||
2790 | FORCE_EXEC, | ||
2791 | false); | ||
2792 | } | ||
2793 | } | ||
2794 | #if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 0) | ||
2795 | if (!(coex_sta->bt_info_ext & BIT4)) { | ||
2796 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2797 | "[BTCoex], BT ext info bit4 check, set BT to enable Auto Report!!\n"); | ||
2798 | halbtc8821a1ant_bt_auto_report(btcoexist, | ||
2799 | FORCE_EXEC, true); | ||
2800 | } | ||
2801 | #endif | ||
2802 | } | ||
2803 | |||
2804 | /* check BIT2 first ==> check if bt is under inquiry or page scan*/ | ||
2805 | if (bt_info & BT_INFO_8821A_1ANT_B_INQ_PAGE) | ||
2806 | coex_sta->c2h_bt_inquiry_page = true; | ||
2807 | else | ||
2808 | coex_sta->c2h_bt_inquiry_page = false; | ||
2809 | |||
2810 | /* set link exist status*/ | ||
2811 | if (!(bt_info&BT_INFO_8821A_1ANT_B_CONNECTION)) { | ||
2812 | coex_sta->bt_link_exist = false; | ||
2813 | coex_sta->pan_exist = false; | ||
2814 | coex_sta->a2dp_exist = false; | ||
2815 | coex_sta->hid_exist = false; | ||
2816 | coex_sta->sco_exist = false; | ||
2817 | } else { | ||
2818 | /* connection exists*/ | ||
2819 | coex_sta->bt_link_exist = true; | ||
2820 | if (bt_info & BT_INFO_8821A_1ANT_B_FTP) | ||
2821 | coex_sta->pan_exist = true; | ||
2822 | else | ||
2823 | coex_sta->pan_exist = false; | ||
2824 | if (bt_info & BT_INFO_8821A_1ANT_B_A2DP) | ||
2825 | coex_sta->a2dp_exist = true; | ||
2826 | else | ||
2827 | coex_sta->a2dp_exist = false; | ||
2828 | if (bt_info & BT_INFO_8821A_1ANT_B_HID) | ||
2829 | coex_sta->hid_exist = true; | ||
2830 | else | ||
2831 | coex_sta->hid_exist = false; | ||
2832 | if (bt_info & BT_INFO_8821A_1ANT_B_SCO_ESCO) | ||
2833 | coex_sta->sco_exist = true; | ||
2834 | else | ||
2835 | coex_sta->sco_exist = false; | ||
2836 | } | ||
2837 | |||
2838 | halbtc8821a1ant_update_bt_link_info(btcoexist); | ||
2839 | |||
2840 | if (!(bt_info&BT_INFO_8821A_1ANT_B_CONNECTION)) { | ||
2841 | coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE; | ||
2842 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2843 | "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n"); | ||
2844 | } else if (bt_info == BT_INFO_8821A_1ANT_B_CONNECTION) { | ||
2845 | /* connection exists but no busy*/ | ||
2846 | coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE; | ||
2847 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2848 | "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n"); | ||
2849 | } else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) || | ||
2850 | (bt_info&BT_INFO_8821A_1ANT_B_SCO_BUSY)) { | ||
2851 | coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY; | ||
2852 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2853 | "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); | ||
2854 | } else if (bt_info&BT_INFO_8821A_1ANT_B_ACL_BUSY) { | ||
2855 | if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status) | ||
2856 | coex_dm->auto_tdma_adjust = false; | ||
2857 | coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY; | ||
2858 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2859 | "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); | ||
2860 | } else { | ||
2861 | coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_MAX; | ||
2862 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2863 | "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n"); | ||
2864 | } | ||
2865 | |||
2866 | if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) || | ||
2867 | (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) || | ||
2868 | (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) | ||
2869 | bt_busy = true; | ||
2870 | else | ||
2871 | bt_busy = false; | ||
2872 | btcoexist->btc_set(btcoexist, | ||
2873 | BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); | ||
2874 | |||
2875 | halbtc8821a1ant_run_coexist_mechanism(btcoexist); | ||
2876 | } | ||
2877 | |||
2878 | void ex_halbtc8821a1ant_halt_notify(struct btc_coexist *btcoexist) | ||
2879 | { | ||
2880 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2881 | "[BTCoex], Halt notify\n"); | ||
2882 | |||
2883 | btcoexist->stop_coex_dm = true; | ||
2884 | |||
2885 | halbtc8821a1ant_set_ant_path(btcoexist, | ||
2886 | BTC_ANT_PATH_BT, false, true); | ||
2887 | halbtc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | ||
2888 | |||
2889 | halbtc8821a1ant_power_save_state(btcoexist, | ||
2890 | BTC_PS_WIFI_NATIVE, 0x0, 0x0); | ||
2891 | halbtc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0); | ||
2892 | |||
2893 | ex_halbtc8821a1ant_media_status_notify(btcoexist, | ||
2894 | BTC_MEDIA_DISCONNECT); | ||
2895 | } | ||
2896 | |||
2897 | void ex_halbtc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) | ||
2898 | { | ||
2899 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2900 | "[BTCoex], Pnp notify\n"); | ||
2901 | |||
2902 | if (BTC_WIFI_PNP_SLEEP == pnp_state) { | ||
2903 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2904 | "[BTCoex], Pnp notify to SLEEP\n"); | ||
2905 | btcoexist->stop_coex_dm = true; | ||
2906 | halbtc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | ||
2907 | halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, | ||
2908 | 0x0, 0x0); | ||
2909 | halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9); | ||
2910 | } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) { | ||
2911 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
2912 | "[BTCoex], Pnp notify to WAKE UP\n"); | ||
2913 | btcoexist->stop_coex_dm = false; | ||
2914 | halbtc8821a1ant_init_hw_config(btcoexist, false); | ||
2915 | halbtc8821a1ant_init_coex_dm(btcoexist); | ||
2916 | halbtc8821a1ant_query_bt_info(btcoexist); | ||
2917 | } | ||
2918 | } | ||
2919 | |||
2920 | void | ||
2921 | ex_halbtc8821a1ant_periodical( | ||
2922 | struct btc_coexist *btcoexist) { | ||
2923 | static u8 dis_ver_info_cnt; | ||
2924 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
2925 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
2926 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
2927 | |||
2928 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
2929 | "[BTCoex], ==========================Periodical===========================\n"); | ||
2930 | |||
2931 | if (dis_ver_info_cnt <= 5) { | ||
2932 | dis_ver_info_cnt += 1; | ||
2933 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2934 | "[BTCoex], ****************************************************************\n"); | ||
2935 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2936 | "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", | ||
2937 | board_info->pg_ant_num, | ||
2938 | board_info->btdm_ant_num, | ||
2939 | board_info->btdm_ant_pos); | ||
2940 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2941 | "[BTCoex], BT stack/ hci ext ver = %s / %d\n", | ||
2942 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
2943 | stack_info->hci_version); | ||
2944 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, | ||
2945 | &bt_patch_ver); | ||
2946 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
2947 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2948 | "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", | ||
2949 | glcoex_ver_date_8821a_1ant, | ||
2950 | glcoex_ver_8821a_1ant, | ||
2951 | fw_ver, bt_patch_ver, | ||
2952 | bt_patch_ver); | ||
2953 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
2954 | "[BTCoex], ****************************************************************\n"); | ||
2955 | } | ||
2956 | |||
2957 | #if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 0) | ||
2958 | halbtc8821a1ant_query_bt_info(btcoexist); | ||
2959 | halbtc8821a1ant_monitor_bt_ctr(btcoexist); | ||
2960 | btc8821a1ant_mon_bt_en_dis(btcoexist); | ||
2961 | #else | ||
2962 | if (halbtc8821a1ant_Is_wifi_status_changed(btcoexist) || | ||
2963 | coex_dm->auto_tdma_adjust) { | ||
2964 | if (coex_sta->special_pkt_period_cnt > 2) | ||
2965 | halbtc8821a1ant_run_coexist_mechanism(btcoexist); | ||
2966 | } | ||
2967 | |||
2968 | coex_sta->special_pkt_period_cnt++; | ||
2969 | #endif | ||
2970 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h new file mode 100644 index 000000000000..20e904890fc2 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h | |||
@@ -0,0 +1,188 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | /*=========================================== | ||
27 | * The following is for 8821A 1ANT BT Co-exist definition | ||
28 | *=========================================== | ||
29 | */ | ||
30 | #define BT_AUTO_REPORT_ONLY_8821A_1ANT 0 | ||
31 | |||
32 | #define BT_INFO_8821A_1ANT_B_FTP BIT7 | ||
33 | #define BT_INFO_8821A_1ANT_B_A2DP BIT6 | ||
34 | #define BT_INFO_8821A_1ANT_B_HID BIT5 | ||
35 | #define BT_INFO_8821A_1ANT_B_SCO_BUSY BIT4 | ||
36 | #define BT_INFO_8821A_1ANT_B_ACL_BUSY BIT3 | ||
37 | #define BT_INFO_8821A_1ANT_B_INQ_PAGE BIT2 | ||
38 | #define BT_INFO_8821A_1ANT_B_SCO_ESCO BIT1 | ||
39 | #define BT_INFO_8821A_1ANT_B_CONNECTION BIT0 | ||
40 | |||
41 | #define BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \ | ||
42 | (((_BT_INFO_EXT_&BIT0)) ? true : false) | ||
43 | |||
44 | #define BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT 2 | ||
45 | |||
46 | enum _BT_INFO_SRC_8821A_1ANT { | ||
47 | BT_INFO_SRC_8821A_1ANT_WIFI_FW = 0x0, | ||
48 | BT_INFO_SRC_8821A_1ANT_BT_RSP = 0x1, | ||
49 | BT_INFO_SRC_8821A_1ANT_BT_ACTIVE_SEND = 0x2, | ||
50 | BT_INFO_SRC_8821A_1ANT_MAX | ||
51 | }; | ||
52 | |||
53 | enum _BT_8821A_1ANT_BT_STATUS { | ||
54 | BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0, | ||
55 | BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1, | ||
56 | BT_8821A_1ANT_BT_STATUS_INQ_PAGE = 0x2, | ||
57 | BT_8821A_1ANT_BT_STATUS_ACL_BUSY = 0x3, | ||
58 | BT_8821A_1ANT_BT_STATUS_SCO_BUSY = 0x4, | ||
59 | BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5, | ||
60 | BT_8821A_1ANT_BT_STATUS_MAX | ||
61 | }; | ||
62 | |||
63 | enum _BT_8821A_1ANT_WIFI_STATUS { | ||
64 | BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0, | ||
65 | BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1, | ||
66 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2, | ||
67 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3, | ||
68 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4, | ||
69 | BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5, | ||
70 | BT_8821A_1ANT_WIFI_STATUS_MAX | ||
71 | }; | ||
72 | |||
73 | enum BT_8821A_1ANT_COEX_ALGO { | ||
74 | BT_8821A_1ANT_COEX_ALGO_UNDEFINED = 0x0, | ||
75 | BT_8821A_1ANT_COEX_ALGO_SCO = 0x1, | ||
76 | BT_8821A_1ANT_COEX_ALGO_HID = 0x2, | ||
77 | BT_8821A_1ANT_COEX_ALGO_A2DP = 0x3, | ||
78 | BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4, | ||
79 | BT_8821A_1ANT_COEX_ALGO_PANEDR = 0x5, | ||
80 | BT_8821A_1ANT_COEX_ALGO_PANHS = 0x6, | ||
81 | BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7, | ||
82 | BT_8821A_1ANT_COEX_ALGO_PANEDR_HID = 0x8, | ||
83 | BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, | ||
84 | BT_8821A_1ANT_COEX_ALGO_HID_A2DP = 0xa, | ||
85 | BT_8821A_1ANT_COEX_ALGO_MAX = 0xb, | ||
86 | }; | ||
87 | |||
88 | struct coex_dm_8821a_1ant { | ||
89 | /* fw mechanism */ | ||
90 | bool cur_ignore_wlan_act; | ||
91 | bool pre_ignore_wlan_act; | ||
92 | u8 pre_ps_tdma; | ||
93 | u8 cur_ps_tdma; | ||
94 | u8 ps_tdma_para[5]; | ||
95 | u8 tdma_adj_type; | ||
96 | bool auto_tdma_adjust; | ||
97 | bool pre_ps_tdma_on; | ||
98 | bool cur_ps_tdma_on; | ||
99 | bool pre_bt_auto_report; | ||
100 | bool cur_bt_auto_report; | ||
101 | u8 pre_lps; | ||
102 | u8 cur_lps; | ||
103 | u8 pre_rpwm; | ||
104 | u8 cur_rpwm; | ||
105 | |||
106 | /* sw mechanism */ | ||
107 | bool pre_low_penalty_ra; | ||
108 | bool cur_low_penalty_ra; | ||
109 | u32 pre_val_0x6c0; | ||
110 | u32 cur_val_0x6c0; | ||
111 | u32 pre_val_0x6c4; | ||
112 | u32 cur_val_0x6c4; | ||
113 | u32 pre_val_0x6c8; | ||
114 | u32 cur_val_0x6c8; | ||
115 | u8 pre_val_0x6cc; | ||
116 | u8 cur_val_0x6cc; | ||
117 | /* Auto Rate Fallback Retry cnt */ | ||
118 | u32 backup_arfr_cnt1; | ||
119 | /* Auto Rate Fallback Retry cnt */ | ||
120 | u32 backup_arfr_cnt2; | ||
121 | u16 backup_retry_limit; | ||
122 | u8 backup_ampdu_max_time; | ||
123 | |||
124 | /* algorithm related */ | ||
125 | u8 pre_algorithm; | ||
126 | u8 cur_algorithm; | ||
127 | u8 bt_status; | ||
128 | u8 wifi_chnl_info[3]; | ||
129 | |||
130 | u32 pre_ra_mask; | ||
131 | u32 cur_ra_mask; | ||
132 | u8 pre_arfr_type; | ||
133 | u8 cur_arfr_type; | ||
134 | u8 pre_retry_limit_type; | ||
135 | u8 cur_retry_limit_type; | ||
136 | u8 pre_ampdu_time_type; | ||
137 | u8 cur_ampdu_time_type; | ||
138 | |||
139 | u8 error_condition; | ||
140 | }; | ||
141 | |||
142 | struct coex_sta_8821a_1ant { | ||
143 | bool bt_link_exist; | ||
144 | bool sco_exist; | ||
145 | bool a2dp_exist; | ||
146 | bool hid_exist; | ||
147 | bool pan_exist; | ||
148 | |||
149 | bool under_Lps; | ||
150 | bool under_ips; | ||
151 | u32 special_pkt_period_cnt; | ||
152 | u32 high_priority_tx; | ||
153 | u32 high_priority_rx; | ||
154 | u32 low_priority_tx; | ||
155 | u32 low_priority_rx; | ||
156 | u8 bt_rssi; | ||
157 | u8 pre_bt_rssi_state; | ||
158 | u8 pre_wifi_rssi_state[4]; | ||
159 | bool c2h_bt_info_req_sent; | ||
160 | u8 bt_info_c2h[BT_INFO_SRC_8821A_1ANT_MAX][10]; | ||
161 | u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_1ANT_MAX]; | ||
162 | bool c2h_bt_inquiry_page; | ||
163 | u8 bt_retry_cnt; | ||
164 | u8 bt_info_ext; | ||
165 | }; | ||
166 | |||
167 | /*=========================================== | ||
168 | * The following is interface which will notify coex module. | ||
169 | *=========================================== | ||
170 | */ | ||
171 | void ex_halbtc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist); | ||
172 | void ex_halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist); | ||
173 | void ex_halbtc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type); | ||
174 | void ex_halbtc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type); | ||
175 | void ex_halbtc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type); | ||
176 | void ex_halbtc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type); | ||
177 | void ex_halbtc8821a1ant_media_status_notify(struct btc_coexist *btcoexist, | ||
178 | u8 type); | ||
179 | void ex_halbtc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
180 | u8 type); | ||
181 | void ex_halbtc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
182 | u8 *tmpbuf, u8 length); | ||
183 | void ex_halbtc8821a1ant_halt_notify(struct btc_coexist *btcoexist); | ||
184 | void ex_halbtc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate); | ||
185 | void ex_halbtc8821a1ant_periodical(struct btc_coexist *btcoexist); | ||
186 | void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist); | ||
187 | void ex_halbtc8821a1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code, | ||
188 | u8 op_len, u8 *data); | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c new file mode 100644 index 000000000000..cf819f02ed23 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c | |||
@@ -0,0 +1,3879 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | /*============================================================ | ||
27 | * Description: | ||
28 | * | ||
29 | * This file is for RTL8821A Co-exist mechanism | ||
30 | * | ||
31 | * History | ||
32 | * 2012/08/22 Cosa first check in. | ||
33 | * 2012/11/14 Cosa Revise for 8821A 2Ant out sourcing. | ||
34 | * | ||
35 | *============================================================ | ||
36 | */ | ||
37 | |||
38 | /*============================================================ | ||
39 | * include files | ||
40 | *============================================================ | ||
41 | */ | ||
42 | #include "halbt_precomp.h" | ||
43 | /*============================================================ | ||
44 | * Global variables, these are static variables | ||
45 | *============================================================ | ||
46 | */ | ||
47 | static struct coex_dm_8821a_2ant glcoex_dm_8821a_2ant; | ||
48 | static struct coex_dm_8821a_2ant *coex_dm = &glcoex_dm_8821a_2ant; | ||
49 | static struct coex_sta_8821a_2ant glcoex_sta_8821a_2ant; | ||
50 | static struct coex_sta_8821a_2ant *coex_sta = &glcoex_sta_8821a_2ant; | ||
51 | |||
52 | static const char *const glbt_info_src_8821a_2ant[] = { | ||
53 | "BT Info[wifi fw]", | ||
54 | "BT Info[bt rsp]", | ||
55 | "BT Info[bt auto report]", | ||
56 | }; | ||
57 | |||
58 | static u32 glcoex_ver_date_8821a_2ant = 20130618; | ||
59 | static u32 glcoex_ver_8821a_2ant = 0x5050; | ||
60 | |||
61 | /*============================================================ | ||
62 | * local function proto type if needed | ||
63 | *============================================================ | ||
64 | *============================================================ | ||
65 | * local function start with halbtc8821a2ant_ | ||
66 | *============================================================ | ||
67 | */ | ||
68 | static u8 halbtc8821a2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh, | ||
69 | u8 rssi_thresh1) | ||
70 | { | ||
71 | long bt_rssi = 0; | ||
72 | u8 bt_rssi_state = coex_sta->pre_bt_rssi_state; | ||
73 | |||
74 | bt_rssi = coex_sta->bt_rssi; | ||
75 | |||
76 | if (level_num == 2) { | ||
77 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
78 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
79 | long tmp = rssi_thresh + | ||
80 | BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT; | ||
81 | if (bt_rssi >= tmp) { | ||
82 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
83 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
84 | "[BTCoex], BT Rssi state switch to High\n"); | ||
85 | } else { | ||
86 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
87 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
88 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
89 | } | ||
90 | } else { | ||
91 | if (bt_rssi < rssi_thresh) { | ||
92 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
93 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
94 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
95 | } else { | ||
96 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
97 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
98 | "[BTCoex], BT Rssi state stay at High\n"); | ||
99 | } | ||
100 | } | ||
101 | } else if (level_num == 3) { | ||
102 | if (rssi_thresh > rssi_thresh1) { | ||
103 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
104 | "[BTCoex], BT Rssi thresh error!!\n"); | ||
105 | return coex_sta->pre_bt_rssi_state; | ||
106 | } | ||
107 | |||
108 | if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) || | ||
109 | (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) { | ||
110 | if (bt_rssi >= | ||
111 | (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { | ||
112 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
113 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
114 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
115 | } else { | ||
116 | bt_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
117 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
118 | "[BTCoex], BT Rssi state stay at Low\n"); | ||
119 | } | ||
120 | } else if ((coex_sta->pre_bt_rssi_state == | ||
121 | BTC_RSSI_STATE_MEDIUM) || | ||
122 | (coex_sta->pre_bt_rssi_state == | ||
123 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
124 | if (bt_rssi >= | ||
125 | (rssi_thresh1 + | ||
126 | BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { | ||
127 | bt_rssi_state = BTC_RSSI_STATE_HIGH; | ||
128 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
129 | "[BTCoex], BT Rssi state switch to High\n"); | ||
130 | } else if (bt_rssi < rssi_thresh) { | ||
131 | bt_rssi_state = BTC_RSSI_STATE_LOW; | ||
132 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
133 | "[BTCoex], BT Rssi state switch to Low\n"); | ||
134 | } else { | ||
135 | bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
136 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
137 | "[BTCoex], BT Rssi state stay at Medium\n"); | ||
138 | } | ||
139 | } else { | ||
140 | if (bt_rssi < rssi_thresh1) { | ||
141 | bt_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
142 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
143 | "[BTCoex], BT Rssi state switch to Medium\n"); | ||
144 | } else { | ||
145 | bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
146 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, | ||
147 | "[BTCoex], BT Rssi state stay at High\n"); | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
152 | coex_sta->pre_bt_rssi_state = bt_rssi_state; | ||
153 | |||
154 | return bt_rssi_state; | ||
155 | } | ||
156 | |||
157 | static u8 halbtc8821a2ant_wifi_rssi_state(struct btc_coexist *btcoexist, | ||
158 | u8 index, u8 level_num, | ||
159 | u8 rssi_thresh, u8 rssi_thresh1) | ||
160 | { | ||
161 | long wifi_rssi = 0; | ||
162 | u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index]; | ||
163 | |||
164 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
165 | |||
166 | if (level_num == 2) { | ||
167 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
168 | BTC_RSSI_STATE_LOW) || | ||
169 | (coex_sta->pre_wifi_rssi_state[index] == | ||
170 | BTC_RSSI_STATE_STAY_LOW)) { | ||
171 | if (wifi_rssi >= | ||
172 | (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { | ||
173 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
174 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
175 | ALGO_WIFI_RSSI_STATE, | ||
176 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
177 | } else { | ||
178 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
179 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
180 | ALGO_WIFI_RSSI_STATE, | ||
181 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
182 | } | ||
183 | } else { | ||
184 | if (wifi_rssi < rssi_thresh) { | ||
185 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
186 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
187 | ALGO_WIFI_RSSI_STATE, | ||
188 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
189 | } else { | ||
190 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
191 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
192 | ALGO_WIFI_RSSI_STATE, | ||
193 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
194 | } | ||
195 | } | ||
196 | } else if (level_num == 3) { | ||
197 | if (rssi_thresh > rssi_thresh1) { | ||
198 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, | ||
199 | "[BTCoex], wifi RSSI thresh error!!\n"); | ||
200 | return coex_sta->pre_wifi_rssi_state[index]; | ||
201 | } | ||
202 | |||
203 | if ((coex_sta->pre_wifi_rssi_state[index] == | ||
204 | BTC_RSSI_STATE_LOW) || | ||
205 | (coex_sta->pre_wifi_rssi_state[index] == | ||
206 | BTC_RSSI_STATE_STAY_LOW)) { | ||
207 | if (wifi_rssi >= | ||
208 | (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { | ||
209 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
210 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
211 | ALGO_WIFI_RSSI_STATE, | ||
212 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
213 | } else { | ||
214 | wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW; | ||
215 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
216 | ALGO_WIFI_RSSI_STATE, | ||
217 | "[BTCoex], wifi RSSI state stay at Low\n"); | ||
218 | } | ||
219 | } else if ((coex_sta->pre_wifi_rssi_state[index] == | ||
220 | BTC_RSSI_STATE_MEDIUM) || | ||
221 | (coex_sta->pre_wifi_rssi_state[index] == | ||
222 | BTC_RSSI_STATE_STAY_MEDIUM)) { | ||
223 | if (wifi_rssi >= (rssi_thresh1 + | ||
224 | BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) { | ||
225 | wifi_rssi_state = BTC_RSSI_STATE_HIGH; | ||
226 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
227 | ALGO_WIFI_RSSI_STATE, | ||
228 | "[BTCoex], wifi RSSI state switch to High\n"); | ||
229 | } else if (wifi_rssi < rssi_thresh) { | ||
230 | wifi_rssi_state = BTC_RSSI_STATE_LOW; | ||
231 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
232 | ALGO_WIFI_RSSI_STATE, | ||
233 | "[BTCoex], wifi RSSI state switch to Low\n"); | ||
234 | } else { | ||
235 | wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM; | ||
236 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
237 | ALGO_WIFI_RSSI_STATE, | ||
238 | "[BTCoex], wifi RSSI state stay at Medium\n"); | ||
239 | } | ||
240 | } else { | ||
241 | if (wifi_rssi < rssi_thresh1) { | ||
242 | wifi_rssi_state = BTC_RSSI_STATE_MEDIUM; | ||
243 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
244 | ALGO_WIFI_RSSI_STATE, | ||
245 | "[BTCoex], wifi RSSI state switch to Medium\n"); | ||
246 | } else { | ||
247 | wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH; | ||
248 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
249 | ALGO_WIFI_RSSI_STATE, | ||
250 | "[BTCoex], wifi RSSI state stay at High\n"); | ||
251 | } | ||
252 | } | ||
253 | } | ||
254 | coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state; | ||
255 | |||
256 | return wifi_rssi_state; | ||
257 | } | ||
258 | |||
259 | static void btc8821a2ant_mon_bt_en_dis(struct btc_coexist *btcoexist) | ||
260 | { | ||
261 | static bool pre_bt_disabled; | ||
262 | static u32 bt_disable_cnt; | ||
263 | bool bt_active = true, bt_disabled = false; | ||
264 | |||
265 | /* This function check if bt is disabled*/ | ||
266 | |||
267 | if (coex_sta->high_priority_tx == 0 && | ||
268 | coex_sta->high_priority_rx == 0 && | ||
269 | coex_sta->low_priority_tx == 0 && | ||
270 | coex_sta->low_priority_rx == 0) | ||
271 | bt_active = false; | ||
272 | if (coex_sta->high_priority_tx == 0xffff && | ||
273 | coex_sta->high_priority_rx == 0xffff && | ||
274 | coex_sta->low_priority_tx == 0xffff && | ||
275 | coex_sta->low_priority_rx == 0xffff) | ||
276 | bt_active = false; | ||
277 | if (bt_active) { | ||
278 | bt_disable_cnt = 0; | ||
279 | bt_disabled = false; | ||
280 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
281 | &bt_disabled); | ||
282 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
283 | "[BTCoex], BT is enabled !!\n"); | ||
284 | } else { | ||
285 | bt_disable_cnt++; | ||
286 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
287 | "[BTCoex], bt all counters = 0, %d times!!\n", | ||
288 | bt_disable_cnt); | ||
289 | if (bt_disable_cnt >= 2) { | ||
290 | bt_disabled = true; | ||
291 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, | ||
292 | &bt_disabled); | ||
293 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
294 | "[BTCoex], BT is disabled !!\n"); | ||
295 | } | ||
296 | } | ||
297 | if (pre_bt_disabled != bt_disabled) { | ||
298 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
299 | "[BTCoex], BT is from %s to %s!!\n", | ||
300 | (pre_bt_disabled ? "disabled" : "enabled"), | ||
301 | (bt_disabled ? "disabled" : "enabled")); | ||
302 | pre_bt_disabled = bt_disabled; | ||
303 | } | ||
304 | } | ||
305 | |||
306 | static void halbtc8821a2ant_monitor_bt_ctr(struct btc_coexist *btcoexist) | ||
307 | { | ||
308 | u32 reg_hp_txrx, reg_lp_txrx, u4tmp; | ||
309 | u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0; | ||
310 | |||
311 | reg_hp_txrx = 0x770; | ||
312 | reg_lp_txrx = 0x774; | ||
313 | |||
314 | u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx); | ||
315 | reg_hp_tx = u4tmp & MASKLWORD; | ||
316 | reg_hp_rx = (u4tmp & MASKHWORD)>>16; | ||
317 | |||
318 | u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx); | ||
319 | reg_lp_tx = u4tmp & MASKLWORD; | ||
320 | reg_lp_rx = (u4tmp & MASKHWORD)>>16; | ||
321 | |||
322 | coex_sta->high_priority_tx = reg_hp_tx; | ||
323 | coex_sta->high_priority_rx = reg_hp_rx; | ||
324 | coex_sta->low_priority_tx = reg_lp_tx; | ||
325 | coex_sta->low_priority_rx = reg_lp_rx; | ||
326 | |||
327 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
328 | "[BTCoex], High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", | ||
329 | reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx); | ||
330 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, | ||
331 | "[BTCoex], Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n", | ||
332 | reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx); | ||
333 | |||
334 | /* reset counter */ | ||
335 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
336 | } | ||
337 | |||
338 | static void halbtc8821a2ant_query_bt_info(struct btc_coexist *btcoexist) | ||
339 | { | ||
340 | u8 h2c_parameter[1] = {0}; | ||
341 | |||
342 | coex_sta->c2h_bt_info_req_sent = true; | ||
343 | |||
344 | h2c_parameter[0] |= BIT0; /* trigger */ | ||
345 | |||
346 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
347 | "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n", | ||
348 | h2c_parameter[0]); | ||
349 | |||
350 | btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter); | ||
351 | } | ||
352 | |||
353 | static u8 halbtc8821a2ant_action_algorithm(struct btc_coexist *btcoexist) | ||
354 | { | ||
355 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
356 | bool bt_hs_on = false; | ||
357 | u8 algorithm = BT_8821A_2ANT_COEX_ALGO_UNDEFINED; | ||
358 | u8 num_of_diff_profile = 0; | ||
359 | |||
360 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
361 | |||
362 | /*for win-8 stack HID report error*/ | ||
363 | /* sync BTInfo with BT firmware and stack */ | ||
364 | if (!stack_info->hid_exist) | ||
365 | stack_info->hid_exist = coex_sta->hid_exist; | ||
366 | /* when stack HID report error, here we use the info from bt fw. */ | ||
367 | if (!stack_info->bt_link_exist) | ||
368 | stack_info->bt_link_exist = coex_sta->bt_link_exist; | ||
369 | |||
370 | if (!coex_sta->bt_link_exist) { | ||
371 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
372 | "[BTCoex], No profile exists!!!\n"); | ||
373 | return algorithm; | ||
374 | } | ||
375 | |||
376 | if (coex_sta->sco_exist) | ||
377 | num_of_diff_profile++; | ||
378 | if (coex_sta->hid_exist) | ||
379 | num_of_diff_profile++; | ||
380 | if (coex_sta->pan_exist) | ||
381 | num_of_diff_profile++; | ||
382 | if (coex_sta->a2dp_exist) | ||
383 | num_of_diff_profile++; | ||
384 | |||
385 | if (num_of_diff_profile == 1) { | ||
386 | if (coex_sta->sco_exist) { | ||
387 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
388 | "[BTCoex], SCO only\n"); | ||
389 | algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; | ||
390 | } else { | ||
391 | if (coex_sta->hid_exist) { | ||
392 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
393 | "[BTCoex], HID only\n"); | ||
394 | algorithm = BT_8821A_2ANT_COEX_ALGO_HID; | ||
395 | } else if (coex_sta->a2dp_exist) { | ||
396 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
397 | "[BTCoex], A2DP only\n"); | ||
398 | algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP; | ||
399 | } else if (coex_sta->pan_exist) { | ||
400 | if (bt_hs_on) { | ||
401 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
402 | "[BTCoex], PAN(HS) only\n"); | ||
403 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANHS; | ||
404 | } else { | ||
405 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
406 | "[BTCoex], PAN(EDR) only\n"); | ||
407 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR; | ||
408 | } | ||
409 | } | ||
410 | } | ||
411 | } else if (num_of_diff_profile == 2) { | ||
412 | if (coex_sta->sco_exist) { | ||
413 | if (coex_sta->hid_exist) { | ||
414 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
415 | "[BTCoex], SCO + HID\n"); | ||
416 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
417 | } else if (coex_sta->a2dp_exist) { | ||
418 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
419 | "[BTCoex], SCO + A2DP ==> SCO\n"); | ||
420 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
421 | } else if (coex_sta->pan_exist) { | ||
422 | if (bt_hs_on) { | ||
423 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
424 | "[BTCoex], SCO + PAN(HS)\n"); | ||
425 | algorithm = BT_8821A_2ANT_COEX_ALGO_SCO; | ||
426 | } else { | ||
427 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
428 | "[BTCoex], SCO + PAN(EDR)\n"); | ||
429 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
430 | } | ||
431 | } | ||
432 | } else { | ||
433 | if (coex_sta->hid_exist && | ||
434 | coex_sta->a2dp_exist) { | ||
435 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
436 | "[BTCoex], HID + A2DP\n"); | ||
437 | algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP; | ||
438 | } else if (coex_sta->hid_exist && | ||
439 | coex_sta->pan_exist) { | ||
440 | if (bt_hs_on) { | ||
441 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
442 | "[BTCoex], HID + PAN(HS)\n"); | ||
443 | algorithm = BT_8821A_2ANT_COEX_ALGO_HID; | ||
444 | } else { | ||
445 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
446 | "[BTCoex], HID + PAN(EDR)\n"); | ||
447 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
448 | } | ||
449 | } else if (coex_sta->pan_exist && | ||
450 | coex_sta->a2dp_exist) { | ||
451 | if (bt_hs_on) { | ||
452 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
453 | "[BTCoex], A2DP + PAN(HS)\n"); | ||
454 | algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS; | ||
455 | } else { | ||
456 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
457 | "[BTCoex], A2DP + PAN(EDR)\n"); | ||
458 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP; | ||
459 | } | ||
460 | } | ||
461 | } | ||
462 | } else if (num_of_diff_profile == 3) { | ||
463 | if (coex_sta->sco_exist) { | ||
464 | if (coex_sta->hid_exist && | ||
465 | coex_sta->a2dp_exist) { | ||
466 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
467 | "[BTCoex], SCO + HID + A2DP ==> HID\n"); | ||
468 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
469 | } else if (coex_sta->hid_exist && | ||
470 | coex_sta->pan_exist) { | ||
471 | if (bt_hs_on) { | ||
472 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
473 | "[BTCoex], SCO + HID + PAN(HS)\n"); | ||
474 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
475 | } else { | ||
476 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
477 | "[BTCoex], SCO + HID + PAN(EDR)\n"); | ||
478 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
479 | } | ||
480 | } else if (coex_sta->pan_exist && | ||
481 | coex_sta->a2dp_exist) { | ||
482 | if (bt_hs_on) { | ||
483 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
484 | "[BTCoex], SCO + A2DP + PAN(HS)\n"); | ||
485 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
486 | } else { | ||
487 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
488 | "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"); | ||
489 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
490 | } | ||
491 | } | ||
492 | } else { | ||
493 | if (coex_sta->hid_exist && | ||
494 | coex_sta->pan_exist && | ||
495 | coex_sta->a2dp_exist) { | ||
496 | if (bt_hs_on) { | ||
497 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
498 | "[BTCoex], HID + A2DP + PAN(HS)\n"); | ||
499 | algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP; | ||
500 | } else { | ||
501 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
502 | "[BTCoex], HID + A2DP + PAN(EDR)\n"); | ||
503 | algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR; | ||
504 | } | ||
505 | } | ||
506 | } | ||
507 | } else if (num_of_diff_profile >= 3) { | ||
508 | if (coex_sta->sco_exist) { | ||
509 | if (coex_sta->hid_exist && | ||
510 | coex_sta->pan_exist && | ||
511 | coex_sta->a2dp_exist) { | ||
512 | if (bt_hs_on) { | ||
513 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
514 | "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"); | ||
515 | |||
516 | } else { | ||
517 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
518 | "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"); | ||
519 | algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID; | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | } | ||
524 | return algorithm; | ||
525 | } | ||
526 | |||
527 | static bool halbtc8821a2ant_need_to_dec_bt_pwr(struct btc_coexist *btcoexist) | ||
528 | { | ||
529 | bool ret = false; | ||
530 | bool bt_hs_on = false, wifi_connected = false; | ||
531 | long bt_hs_rssi = 0; | ||
532 | u8 bt_rssi_state; | ||
533 | |||
534 | if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on)) | ||
535 | return false; | ||
536 | if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
537 | &wifi_connected)) | ||
538 | return false; | ||
539 | if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) | ||
540 | return false; | ||
541 | |||
542 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
543 | |||
544 | if (wifi_connected) { | ||
545 | if (bt_hs_on) { | ||
546 | if (bt_hs_rssi > 37) { | ||
547 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
548 | "[BTCoex], Need to decrease bt power for HS mode!!\n"); | ||
549 | ret = true; | ||
550 | } | ||
551 | } else { | ||
552 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
553 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
554 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
555 | "[BTCoex], Need to decrease bt power for Wifi is connected!!\n"); | ||
556 | ret = true; | ||
557 | } | ||
558 | } | ||
559 | } | ||
560 | return ret; | ||
561 | } | ||
562 | |||
563 | static void btc8821a2ant_set_fw_dac_swing_lev(struct btc_coexist *btcoexist, | ||
564 | u8 dac_swing_lvl) | ||
565 | { | ||
566 | u8 h2c_parameter[1] = {0}; | ||
567 | |||
568 | /* There are several type of dacswing | ||
569 | * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 | ||
570 | */ | ||
571 | h2c_parameter[0] = dac_swing_lvl; | ||
572 | |||
573 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
574 | "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl); | ||
575 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
576 | "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]); | ||
577 | |||
578 | btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter); | ||
579 | } | ||
580 | |||
581 | static void halbtc8821a2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist, | ||
582 | bool dec_bt_pwr) | ||
583 | { | ||
584 | u8 h2c_parameter[1] = {0}; | ||
585 | |||
586 | h2c_parameter[0] = 0; | ||
587 | |||
588 | if (dec_bt_pwr) | ||
589 | h2c_parameter[0] |= BIT1; | ||
590 | |||
591 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
592 | "[BTCoex], decrease Bt Power : %s, FW write 0x62 = 0x%x\n", | ||
593 | (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]); | ||
594 | |||
595 | btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter); | ||
596 | } | ||
597 | |||
598 | static void halbtc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist, | ||
599 | bool force_exec, bool dec_bt_pwr) | ||
600 | { | ||
601 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
602 | "[BTCoex], %s Dec BT power = %s\n", | ||
603 | (force_exec ? "force to" : ""), | ||
604 | ((dec_bt_pwr) ? "ON" : "OFF")); | ||
605 | coex_dm->cur_dec_bt_pwr = dec_bt_pwr; | ||
606 | |||
607 | if (!force_exec) { | ||
608 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
609 | "[BTCoex], pre_dec_bt_pwr = %d, cur_dec_bt_pwr = %d\n", | ||
610 | coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr); | ||
611 | |||
612 | if (coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr) | ||
613 | return; | ||
614 | } | ||
615 | halbtc8821a2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr); | ||
616 | |||
617 | coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr; | ||
618 | } | ||
619 | |||
620 | static void btc8821a2ant_set_fw_bt_lna_constr(struct btc_coexist *btcoexist, | ||
621 | bool bt_lna_cons_on) | ||
622 | { | ||
623 | u8 h2c_parameter[2] = {0}; | ||
624 | |||
625 | h2c_parameter[0] = 0x3; /* opCode, 0x3 = BT_SET_LNA_CONSTRAIN */ | ||
626 | |||
627 | if (bt_lna_cons_on) | ||
628 | h2c_parameter[1] |= BIT0; | ||
629 | |||
630 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
631 | "[BTCoex], set BT LNA Constrain: %s, FW write 0x69 = 0x%x\n", | ||
632 | (bt_lna_cons_on ? "ON!!" : "OFF!!"), | ||
633 | h2c_parameter[0]<<8|h2c_parameter[1]); | ||
634 | |||
635 | btcoexist->btc_fill_h2c(btcoexist, 0x69, 2, h2c_parameter); | ||
636 | } | ||
637 | |||
638 | static void btc8821a2_set_bt_lna_const(struct btc_coexist *btcoexist, | ||
639 | bool force_exec, bool bt_lna_cons_on) | ||
640 | { | ||
641 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
642 | "[BTCoex], %s BT Constrain = %s\n", | ||
643 | (force_exec ? "force" : ""), | ||
644 | ((bt_lna_cons_on) ? "ON" : "OFF")); | ||
645 | coex_dm->cur_bt_lna_constrain = bt_lna_cons_on; | ||
646 | |||
647 | if (!force_exec) { | ||
648 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
649 | "[BTCoex], pre_bt_lna_constrain = %d,cur_bt_lna_constrain = %d\n", | ||
650 | coex_dm->pre_bt_lna_constrain, | ||
651 | coex_dm->cur_bt_lna_constrain); | ||
652 | |||
653 | if (coex_dm->pre_bt_lna_constrain == | ||
654 | coex_dm->cur_bt_lna_constrain) | ||
655 | return; | ||
656 | } | ||
657 | btc8821a2ant_set_fw_bt_lna_constr(btcoexist, | ||
658 | coex_dm->cur_bt_lna_constrain); | ||
659 | |||
660 | coex_dm->pre_bt_lna_constrain = coex_dm->cur_bt_lna_constrain; | ||
661 | } | ||
662 | |||
663 | static void halbtc8821a2ant_set_fw_bt_psd_mode(struct btc_coexist *btcoexist, | ||
664 | u8 bt_psd_mode) | ||
665 | { | ||
666 | u8 h2c_parameter[2] = {0}; | ||
667 | |||
668 | h2c_parameter[0] = 0x2; /* opCode, 0x2 = BT_SET_PSD_MODE */ | ||
669 | |||
670 | h2c_parameter[1] = bt_psd_mode; | ||
671 | |||
672 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
673 | "[BTCoex], set BT PSD mode = 0x%x, FW write 0x69 = 0x%x\n", | ||
674 | h2c_parameter[1], | ||
675 | h2c_parameter[0]<<8|h2c_parameter[1]); | ||
676 | |||
677 | btcoexist->btc_fill_h2c(btcoexist, 0x69, 2, h2c_parameter); | ||
678 | } | ||
679 | |||
680 | static void halbtc8821a2ant_set_bt_psd_mode(struct btc_coexist *btcoexist, | ||
681 | bool force_exec, u8 bt_psd_mode) | ||
682 | { | ||
683 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
684 | "[BTCoex], %s BT PSD mode = 0x%x\n", | ||
685 | (force_exec ? "force" : ""), bt_psd_mode); | ||
686 | coex_dm->cur_bt_psd_mode = bt_psd_mode; | ||
687 | |||
688 | if (!force_exec) { | ||
689 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
690 | "[BTCoex], pre_bt_psd_mode = 0x%x, cur_bt_psd_mode = 0x%x\n", | ||
691 | coex_dm->pre_bt_psd_mode, coex_dm->cur_bt_psd_mode); | ||
692 | |||
693 | if (coex_dm->pre_bt_psd_mode == coex_dm->cur_bt_psd_mode) | ||
694 | return; | ||
695 | } | ||
696 | halbtc8821a2ant_set_fw_bt_psd_mode(btcoexist, | ||
697 | coex_dm->cur_bt_psd_mode); | ||
698 | |||
699 | coex_dm->pre_bt_psd_mode = coex_dm->cur_bt_psd_mode; | ||
700 | } | ||
701 | |||
702 | static void halbtc8821a2ant_set_bt_auto_report(struct btc_coexist *btcoexist, | ||
703 | bool enable_auto_report) | ||
704 | { | ||
705 | u8 h2c_parameter[1] = {0}; | ||
706 | |||
707 | h2c_parameter[0] = 0; | ||
708 | |||
709 | if (enable_auto_report) | ||
710 | h2c_parameter[0] |= BIT0; | ||
711 | |||
712 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
713 | "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n", | ||
714 | (enable_auto_report ? "Enabled!!" : "Disabled!!"), | ||
715 | h2c_parameter[0]); | ||
716 | |||
717 | btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter); | ||
718 | } | ||
719 | |||
720 | static void halbtc8821a2ant_bt_auto_report(struct btc_coexist *btcoexist, | ||
721 | bool force_exec, | ||
722 | bool enable_auto_report) | ||
723 | { | ||
724 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
725 | "[BTCoex], %s BT Auto report = %s\n", | ||
726 | (force_exec ? "force to" : ""), | ||
727 | ((enable_auto_report) ? "Enabled" : "Disabled")); | ||
728 | coex_dm->cur_bt_auto_report = enable_auto_report; | ||
729 | |||
730 | if (!force_exec) { | ||
731 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
732 | "[BTCoex], pre_bt_auto_report = %d, cur_bt_auto_report = %d\n", | ||
733 | coex_dm->pre_bt_auto_report, | ||
734 | coex_dm->cur_bt_auto_report); | ||
735 | |||
736 | if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report) | ||
737 | return; | ||
738 | } | ||
739 | halbtc8821a2ant_set_bt_auto_report(btcoexist, | ||
740 | coex_dm->cur_bt_auto_report); | ||
741 | |||
742 | coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report; | ||
743 | } | ||
744 | |||
745 | static void halbtc8821a2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist, | ||
746 | bool force_exec, | ||
747 | u8 fw_dac_swing_lvl) | ||
748 | { | ||
749 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
750 | "[BTCoex], %s set FW Dac Swing level = %d\n", | ||
751 | (force_exec ? "force to" : ""), fw_dac_swing_lvl); | ||
752 | coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl; | ||
753 | |||
754 | if (!force_exec) { | ||
755 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
756 | "[BTCoex], pre_fw_dac_swing_lvl = %d, cur_fw_dac_swing_lvl = %d\n", | ||
757 | coex_dm->pre_fw_dac_swing_lvl, | ||
758 | coex_dm->cur_fw_dac_swing_lvl); | ||
759 | |||
760 | if (coex_dm->pre_fw_dac_swing_lvl == | ||
761 | coex_dm->cur_fw_dac_swing_lvl) | ||
762 | return; | ||
763 | } | ||
764 | |||
765 | btc8821a2ant_set_fw_dac_swing_lev(btcoexist, | ||
766 | coex_dm->cur_fw_dac_swing_lvl); | ||
767 | |||
768 | coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl; | ||
769 | } | ||
770 | |||
771 | static void btc8821a2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist, | ||
772 | bool rx_rf_shrink_on) | ||
773 | { | ||
774 | if (rx_rf_shrink_on) { | ||
775 | /* Shrink RF Rx LPF corner */ | ||
776 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
777 | "[BTCoex], Shrink RF Rx LPF corner!!\n"); | ||
778 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, | ||
779 | 0xfffff, 0xffffc); | ||
780 | } else { | ||
781 | /* Resume RF Rx LPF corner | ||
782 | * After initialized, we can use coex_dm->bt_rf0x1e_backup | ||
783 | */ | ||
784 | if (btcoexist->initilized) { | ||
785 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
786 | "[BTCoex], Resume RF Rx LPF corner!!\n"); | ||
787 | btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, | ||
788 | 0x1e, 0xfffff, | ||
789 | coex_dm->bt_rf0x1e_backup); | ||
790 | } | ||
791 | } | ||
792 | } | ||
793 | |||
794 | static void halbtc8821a2ant_RfShrink(struct btc_coexist *btcoexist, | ||
795 | bool force_exec, bool rx_rf_shrink_on) | ||
796 | { | ||
797 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
798 | "[BTCoex], %s turn Rx RF Shrink = %s\n", | ||
799 | (force_exec ? "force to" : ""), | ||
800 | ((rx_rf_shrink_on) ? "ON" : "OFF")); | ||
801 | coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on; | ||
802 | |||
803 | if (!force_exec) { | ||
804 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
805 | "[BTCoex], pre_rf_rx_lpf_shrink = %d, cur_rf_rx_lpf_shrink = %d\n", | ||
806 | coex_dm->pre_rf_rx_lpf_shrink, | ||
807 | coex_dm->cur_rf_rx_lpf_shrink); | ||
808 | |||
809 | if (coex_dm->pre_rf_rx_lpf_shrink == | ||
810 | coex_dm->cur_rf_rx_lpf_shrink) | ||
811 | return; | ||
812 | } | ||
813 | btc8821a2ant_set_sw_rf_rx_lpf_corner(btcoexist, | ||
814 | coex_dm->cur_rf_rx_lpf_shrink); | ||
815 | |||
816 | coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink; | ||
817 | } | ||
818 | |||
819 | static void btc8821a2ant_SetSwPenTxRateAdapt(struct btc_coexist *btcoexist, | ||
820 | bool low_penalty_ra) | ||
821 | { | ||
822 | u8 h2c_parameter[6] = {0}; | ||
823 | |||
824 | h2c_parameter[0] = 0x6; /* opCode, 0x6 = Retry_Penalty */ | ||
825 | |||
826 | if (low_penalty_ra) { | ||
827 | h2c_parameter[1] |= BIT0; | ||
828 | /*normal rate except MCS7/6/5, OFDM54/48/36 */ | ||
829 | h2c_parameter[2] = 0x00; | ||
830 | /*MCS7 or OFDM54 */ | ||
831 | h2c_parameter[3] = 0xf7; | ||
832 | /*MCS6 or OFDM48 */ | ||
833 | h2c_parameter[4] = 0xf8; | ||
834 | /*MCS5 or OFDM36 */ | ||
835 | h2c_parameter[5] = 0xf9; | ||
836 | } | ||
837 | |||
838 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
839 | "[BTCoex], set WiFi Low-Penalty Retry: %s", | ||
840 | (low_penalty_ra ? "ON!!" : "OFF!!")); | ||
841 | |||
842 | btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter); | ||
843 | } | ||
844 | |||
845 | static void halbtc8821a2ant_low_penalty_ra(struct btc_coexist *btcoexist, | ||
846 | bool force_exec, bool low_penalty_ra) | ||
847 | { | ||
848 | /*return;*/ | ||
849 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
850 | "[BTCoex], %s turn LowPenaltyRA = %s\n", | ||
851 | (force_exec ? "force to" : ""), | ||
852 | ((low_penalty_ra) ? "ON" : "OFF")); | ||
853 | coex_dm->cur_low_penalty_ra = low_penalty_ra; | ||
854 | |||
855 | if (!force_exec) { | ||
856 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
857 | "[BTCoex], pre_low_penalty_ra = %d, cur_low_penalty_ra = %d\n", | ||
858 | coex_dm->pre_low_penalty_ra, | ||
859 | coex_dm->cur_low_penalty_ra); | ||
860 | |||
861 | if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra) | ||
862 | return; | ||
863 | } | ||
864 | btc8821a2ant_SetSwPenTxRateAdapt(btcoexist, | ||
865 | coex_dm->cur_low_penalty_ra); | ||
866 | |||
867 | coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra; | ||
868 | } | ||
869 | |||
870 | static void halbtc8821a2ant_set_dac_swing_reg(struct btc_coexist *btcoexist, | ||
871 | u32 level) | ||
872 | { | ||
873 | u8 val = (u8)level; | ||
874 | |||
875 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
876 | "[BTCoex], Write SwDacSwing = 0x%x\n", level); | ||
877 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc5b, 0x3e, val); | ||
878 | } | ||
879 | |||
880 | static void btc8821a2ant_set_sw_full_dac_swing(struct btc_coexist *btcoexist, | ||
881 | bool sw_dac_swing_on, | ||
882 | u32 sw_dac_swing_lvl) | ||
883 | { | ||
884 | if (sw_dac_swing_on) | ||
885 | halbtc8821a2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl); | ||
886 | else | ||
887 | halbtc8821a2ant_set_dac_swing_reg(btcoexist, 0x18); | ||
888 | } | ||
889 | |||
890 | static void halbtc8821a2ant_dac_swing(struct btc_coexist *btcoexist, | ||
891 | bool force_exec, bool dac_swing_on, | ||
892 | u32 dac_swing_lvl) | ||
893 | { | ||
894 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
895 | "[BTCoex], %s turn DacSwing = %s, dac_swing_lvl = 0x%x\n", | ||
896 | (force_exec ? "force to" : ""), | ||
897 | ((dac_swing_on) ? "ON" : "OFF"), | ||
898 | dac_swing_lvl); | ||
899 | coex_dm->cur_dac_swing_on = dac_swing_on; | ||
900 | coex_dm->cur_dac_swing_lvl = dac_swing_lvl; | ||
901 | |||
902 | if (!force_exec) { | ||
903 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
904 | "[BTCoex], pre_dac_swing_on = %d, pre_dac_swing_lvl = 0x%x, cur_dac_swing_on = %d, cur_dac_swing_lvl = 0x%x\n", | ||
905 | coex_dm->pre_dac_swing_on, | ||
906 | coex_dm->pre_dac_swing_lvl, | ||
907 | coex_dm->cur_dac_swing_on, | ||
908 | coex_dm->cur_dac_swing_lvl); | ||
909 | |||
910 | if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) && | ||
911 | (coex_dm->pre_dac_swing_lvl == | ||
912 | coex_dm->cur_dac_swing_lvl)) | ||
913 | return; | ||
914 | } | ||
915 | mdelay(30); | ||
916 | btc8821a2ant_set_sw_full_dac_swing(btcoexist, dac_swing_on, | ||
917 | dac_swing_lvl); | ||
918 | |||
919 | coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on; | ||
920 | coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl; | ||
921 | } | ||
922 | |||
923 | static void halbtc8821a2ant_set_adc_back_off(struct btc_coexist *btcoexist, | ||
924 | bool adc_back_off) | ||
925 | { | ||
926 | if (adc_back_off) { | ||
927 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
928 | "[BTCoex], BB BackOff Level On!\n"); | ||
929 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x3); | ||
930 | } else { | ||
931 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
932 | "[BTCoex], BB BackOff Level Off!\n"); | ||
933 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x1); | ||
934 | } | ||
935 | } | ||
936 | |||
937 | static void halbtc8821a2ant_adc_back_off(struct btc_coexist *btcoexist, | ||
938 | bool force_exec, bool adc_back_off) | ||
939 | { | ||
940 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
941 | "[BTCoex], %s turn AdcBackOff = %s\n", | ||
942 | (force_exec ? "force to" : ""), | ||
943 | ((adc_back_off) ? "ON" : "OFF")); | ||
944 | coex_dm->cur_adc_back_off = adc_back_off; | ||
945 | |||
946 | if (!force_exec) { | ||
947 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
948 | "[BTCoex], pre_adc_back_off = %d, cur_adc_back_off = %d\n", | ||
949 | coex_dm->pre_adc_back_off, coex_dm->cur_adc_back_off); | ||
950 | |||
951 | if (coex_dm->pre_adc_back_off == coex_dm->cur_adc_back_off) | ||
952 | return; | ||
953 | } | ||
954 | halbtc8821a2ant_set_adc_back_off(btcoexist, coex_dm->cur_adc_back_off); | ||
955 | |||
956 | coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off; | ||
957 | } | ||
958 | |||
959 | static void halbtc8821a2ant_set_coex_table(struct btc_coexist *btcoexist, | ||
960 | u32 val0x6c0, u32 val0x6c4, | ||
961 | u32 val0x6c8, u8 val0x6cc) | ||
962 | { | ||
963 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
964 | "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0); | ||
965 | btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0); | ||
966 | |||
967 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
968 | "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4); | ||
969 | btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4); | ||
970 | |||
971 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
972 | "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8); | ||
973 | btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8); | ||
974 | |||
975 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, | ||
976 | "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc); | ||
977 | btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc); | ||
978 | } | ||
979 | |||
980 | static void halbtc8821a2ant_coex_table(struct btc_coexist *btcoexist, | ||
981 | bool force_exec, u32 val0x6c0, | ||
982 | u32 val0x6c4, u32 val0x6c8, u8 val0x6cc) | ||
983 | { | ||
984 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, | ||
985 | "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n", | ||
986 | (force_exec ? "force to" : ""), | ||
987 | val0x6c0, val0x6c4, val0x6c8, val0x6cc); | ||
988 | coex_dm->cur_val0x6c0 = val0x6c0; | ||
989 | coex_dm->cur_val0x6c4 = val0x6c4; | ||
990 | coex_dm->cur_val0x6c8 = val0x6c8; | ||
991 | coex_dm->cur_val0x6cc = val0x6cc; | ||
992 | |||
993 | if (!force_exec) { | ||
994 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
995 | "[BTCoex], pre_val0x6c0 = 0x%x, pre_val0x6c4 = 0x%x, pre_val0x6c8 = 0x%x, pre_val0x6cc = 0x%x !!\n", | ||
996 | coex_dm->pre_val0x6c0, | ||
997 | coex_dm->pre_val0x6c4, | ||
998 | coex_dm->pre_val0x6c8, | ||
999 | coex_dm->pre_val0x6cc); | ||
1000 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, | ||
1001 | "[BTCoex], cur_val0x6c0 = 0x%x, cur_val0x6c4 = 0x%x, cur_val0x6c8 = 0x%x, cur_val0x6cc = 0x%x !!\n", | ||
1002 | coex_dm->cur_val0x6c0, | ||
1003 | coex_dm->cur_val0x6c4, | ||
1004 | coex_dm->cur_val0x6c8, | ||
1005 | coex_dm->cur_val0x6cc); | ||
1006 | |||
1007 | if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) && | ||
1008 | (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) && | ||
1009 | (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) && | ||
1010 | (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc)) | ||
1011 | return; | ||
1012 | } | ||
1013 | halbtc8821a2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8, | ||
1014 | val0x6cc); | ||
1015 | |||
1016 | coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0; | ||
1017 | coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4; | ||
1018 | coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8; | ||
1019 | coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc; | ||
1020 | } | ||
1021 | |||
1022 | static void halbtc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex, | ||
1023 | bool enable) | ||
1024 | { | ||
1025 | u8 h2c_parameter[1] = {0}; | ||
1026 | |||
1027 | if (enable) | ||
1028 | h2c_parameter[0] |= BIT0;/* function enable */ | ||
1029 | |||
1030 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
1031 | "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n", | ||
1032 | h2c_parameter[0]); | ||
1033 | |||
1034 | btcoex->btc_fill_h2c(btcoex, 0x63, 1, h2c_parameter); | ||
1035 | } | ||
1036 | |||
1037 | static void halbtc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist, | ||
1038 | bool force_exec, bool enable) | ||
1039 | { | ||
1040 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1041 | "[BTCoex], %s turn Ignore WlanAct %s\n", | ||
1042 | (force_exec ? "force to" : ""), (enable ? "ON" : "OFF")); | ||
1043 | coex_dm->cur_ignore_wlan_act = enable; | ||
1044 | |||
1045 | if (!force_exec) { | ||
1046 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1047 | "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n", | ||
1048 | coex_dm->pre_ignore_wlan_act, | ||
1049 | coex_dm->cur_ignore_wlan_act); | ||
1050 | |||
1051 | if (coex_dm->pre_ignore_wlan_act == | ||
1052 | coex_dm->cur_ignore_wlan_act) | ||
1053 | return; | ||
1054 | } | ||
1055 | halbtc8821a2ant_set_fw_ignore_wlan_act(btcoexist, enable); | ||
1056 | |||
1057 | coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act; | ||
1058 | } | ||
1059 | |||
1060 | static void halbtc8821a2ant_set_fw_pstdma(struct btc_coexist *btcoexist, | ||
1061 | u8 byte1, u8 byte2, u8 byte3, | ||
1062 | u8 byte4, u8 byte5) | ||
1063 | { | ||
1064 | u8 h2c_parameter[5]; | ||
1065 | |||
1066 | h2c_parameter[0] = byte1; | ||
1067 | h2c_parameter[1] = byte2; | ||
1068 | h2c_parameter[2] = byte3; | ||
1069 | h2c_parameter[3] = byte4; | ||
1070 | h2c_parameter[4] = byte5; | ||
1071 | |||
1072 | coex_dm->ps_tdma_para[0] = byte1; | ||
1073 | coex_dm->ps_tdma_para[1] = byte2; | ||
1074 | coex_dm->ps_tdma_para[2] = byte3; | ||
1075 | coex_dm->ps_tdma_para[3] = byte4; | ||
1076 | coex_dm->ps_tdma_para[4] = byte5; | ||
1077 | |||
1078 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
1079 | "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n", | ||
1080 | h2c_parameter[0], | ||
1081 | h2c_parameter[1]<<24| | ||
1082 | h2c_parameter[2]<<16| | ||
1083 | h2c_parameter[3]<<8| | ||
1084 | h2c_parameter[4]); | ||
1085 | |||
1086 | btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter); | ||
1087 | } | ||
1088 | |||
1089 | static void btc8821a2ant_sw_mech1(struct btc_coexist *btcoexist, | ||
1090 | bool shrink_rx_lpf, | ||
1091 | bool low_penalty_ra, bool limited_dig, | ||
1092 | bool bt_lna_constrain) | ||
1093 | { | ||
1094 | u32 wifi_bw; | ||
1095 | |||
1096 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
1097 | |||
1098 | if (BTC_WIFI_BW_HT40 != wifi_bw) { | ||
1099 | /*only shrink RF Rx LPF for HT40*/ | ||
1100 | if (shrink_rx_lpf) | ||
1101 | shrink_rx_lpf = false; | ||
1102 | } | ||
1103 | |||
1104 | halbtc8821a2ant_RfShrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf); | ||
1105 | halbtc8821a2ant_low_penalty_ra(btcoexist, | ||
1106 | NORMAL_EXEC, low_penalty_ra); | ||
1107 | |||
1108 | /* no limited DIG | ||
1109 | * btc8821a2_set_bt_lna_const(btcoexist, | ||
1110 | NORMAL_EXEC, bBTLNAConstrain); | ||
1111 | */ | ||
1112 | } | ||
1113 | |||
1114 | static void btc8821a2ant_sw_mech2(struct btc_coexist *btcoexist, | ||
1115 | bool agc_table_shift, | ||
1116 | bool adc_back_off, bool sw_dac_swing, | ||
1117 | u32 dac_swing_lvl) | ||
1118 | { | ||
1119 | /* halbtc8821a2ant_AgcTable(btcoexist, NORMAL_EXEC, bAGCTableShift); */ | ||
1120 | halbtc8821a2ant_adc_back_off(btcoexist, NORMAL_EXEC, adc_back_off); | ||
1121 | halbtc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing, | ||
1122 | sw_dac_swing); | ||
1123 | } | ||
1124 | |||
1125 | static void halbtc8821a2ant_set_ant_path(struct btc_coexist *btcoexist, | ||
1126 | u8 ant_pos_type, bool init_hw_cfg, | ||
1127 | bool wifi_off) | ||
1128 | { | ||
1129 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
1130 | u32 u4tmp = 0; | ||
1131 | u8 h2c_parameter[2] = {0}; | ||
1132 | |||
1133 | if (init_hw_cfg) { | ||
1134 | /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */ | ||
1135 | u4tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
1136 | u4tmp &= ~BIT23; | ||
1137 | u4tmp |= BIT24; | ||
1138 | btcoexist->btc_write_4byte(btcoexist, 0x4c, u4tmp); | ||
1139 | |||
1140 | btcoexist->btc_write_4byte(btcoexist, 0x974, 0x3ff); | ||
1141 | btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77); | ||
1142 | |||
1143 | if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) { | ||
1144 | /* tell firmware "antenna inverse" ==> | ||
1145 | * WRONG firmware antenna control code. | ||
1146 | * ==>need fw to fix | ||
1147 | */ | ||
1148 | h2c_parameter[0] = 1; | ||
1149 | h2c_parameter[1] = 1; | ||
1150 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1151 | h2c_parameter); | ||
1152 | } else { | ||
1153 | /* tell firmware "no antenna inverse" | ||
1154 | * ==> WRONG firmware antenna control code. | ||
1155 | * ==>need fw to fix | ||
1156 | */ | ||
1157 | h2c_parameter[0] = 0; | ||
1158 | h2c_parameter[1] = 1; | ||
1159 | btcoexist->btc_fill_h2c(btcoexist, 0x65, 2, | ||
1160 | h2c_parameter); | ||
1161 | } | ||
1162 | } | ||
1163 | |||
1164 | /* ext switch setting */ | ||
1165 | switch (ant_pos_type) { | ||
1166 | case BTC_ANT_WIFI_AT_MAIN: | ||
1167 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x1); | ||
1168 | break; | ||
1169 | case BTC_ANT_WIFI_AT_AUX: | ||
1170 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x2); | ||
1171 | break; | ||
1172 | } | ||
1173 | } | ||
1174 | |||
1175 | static void halbtc8821a2ant_ps_tdma(struct btc_coexist *btcoexist, | ||
1176 | bool force_exec, bool turn_on, u8 type) | ||
1177 | { | ||
1178 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
1179 | "[BTCoex], %s turn %s PS TDMA, type = %d\n", | ||
1180 | (force_exec ? "force to" : ""), (turn_on ? "ON" : "OFF"), | ||
1181 | type); | ||
1182 | coex_dm->cur_ps_tdma_on = turn_on; | ||
1183 | coex_dm->cur_ps_tdma = type; | ||
1184 | |||
1185 | if (!force_exec) { | ||
1186 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1187 | "[BTCoex], pre_ps_tdma_on = %d, cur_ps_tdma_on = %d!!\n", | ||
1188 | coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on); | ||
1189 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1190 | "[BTCoex], pre_ps_tdma = %d, cur_ps_tdma = %d!!\n", | ||
1191 | coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma); | ||
1192 | |||
1193 | if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) && | ||
1194 | (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma)) | ||
1195 | return; | ||
1196 | } | ||
1197 | if (turn_on) { | ||
1198 | switch (type) { | ||
1199 | case 1: | ||
1200 | default: | ||
1201 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a, | ||
1202 | 0x1a, 0xe1, 0x90); | ||
1203 | break; | ||
1204 | case 2: | ||
1205 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12, | ||
1206 | 0x12, 0xe1, 0x90); | ||
1207 | break; | ||
1208 | case 3: | ||
1209 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1c, | ||
1210 | 0x3, 0xf1, 0x90); | ||
1211 | break; | ||
1212 | case 4: | ||
1213 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x10, | ||
1214 | 0x03, 0xf1, 0x90); | ||
1215 | break; | ||
1216 | case 5: | ||
1217 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a, | ||
1218 | 0x1a, 0x60, 0x90); | ||
1219 | break; | ||
1220 | case 6: | ||
1221 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12, | ||
1222 | 0x12, 0x60, 0x90); | ||
1223 | break; | ||
1224 | case 7: | ||
1225 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1c, | ||
1226 | 0x3, 0x70, 0x90); | ||
1227 | break; | ||
1228 | case 8: | ||
1229 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xa3, 0x10, | ||
1230 | 0x3, 0x70, 0x90); | ||
1231 | break; | ||
1232 | case 9: | ||
1233 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a, | ||
1234 | 0x1a, 0xe1, 0x90); | ||
1235 | break; | ||
1236 | case 10: | ||
1237 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12, | ||
1238 | 0x12, 0xe1, 0x90); | ||
1239 | break; | ||
1240 | case 11: | ||
1241 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0xa, | ||
1242 | 0xa, 0xe1, 0x90); | ||
1243 | break; | ||
1244 | case 12: | ||
1245 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5, | ||
1246 | 0x5, 0xe1, 0x90); | ||
1247 | break; | ||
1248 | case 13: | ||
1249 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a, | ||
1250 | 0x1a, 0x60, 0x90); | ||
1251 | break; | ||
1252 | case 14: | ||
1253 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, | ||
1254 | 0x12, 0x12, 0x60, 0x90); | ||
1255 | break; | ||
1256 | case 15: | ||
1257 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0xa, | ||
1258 | 0xa, 0x60, 0x90); | ||
1259 | break; | ||
1260 | case 16: | ||
1261 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5, | ||
1262 | 0x5, 0x60, 0x90); | ||
1263 | break; | ||
1264 | case 17: | ||
1265 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xa3, 0x2f, | ||
1266 | 0x2f, 0x60, 0x90); | ||
1267 | break; | ||
1268 | case 18: | ||
1269 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5, | ||
1270 | 0x5, 0xe1, 0x90); | ||
1271 | break; | ||
1272 | case 19: | ||
1273 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x25, | ||
1274 | 0x25, 0xe1, 0x90); | ||
1275 | break; | ||
1276 | case 20: | ||
1277 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x25, | ||
1278 | 0x25, 0x60, 0x90); | ||
1279 | break; | ||
1280 | case 21: | ||
1281 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x15, | ||
1282 | 0x03, 0x70, 0x90); | ||
1283 | break; | ||
1284 | case 71: | ||
1285 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a, | ||
1286 | 0x1a, 0xe1, 0x90); | ||
1287 | break; | ||
1288 | } | ||
1289 | } else { | ||
1290 | /* disable PS tdma */ | ||
1291 | switch (type) { | ||
1292 | case 0: | ||
1293 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1294 | 0x40, 0x0); | ||
1295 | break; | ||
1296 | case 1: | ||
1297 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1298 | 0x48, 0x0); | ||
1299 | break; | ||
1300 | default: | ||
1301 | halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0, | ||
1302 | 0x40, 0x0); | ||
1303 | break; | ||
1304 | } | ||
1305 | } | ||
1306 | |||
1307 | /* update pre state */ | ||
1308 | coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on; | ||
1309 | coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma; | ||
1310 | } | ||
1311 | |||
1312 | static void halbtc8821a2ant_coex_all_off(struct btc_coexist *btcoexist) | ||
1313 | { | ||
1314 | /* fw all off */ | ||
1315 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
1316 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1317 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1318 | |||
1319 | /* sw all off */ | ||
1320 | btc8821a2ant_sw_mech1(btcoexist, false, false, false, false); | ||
1321 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1322 | |||
1323 | /* hw all off */ | ||
1324 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, | ||
1325 | 0x55555555, 0x55555555, 0xffff, 0x3); | ||
1326 | } | ||
1327 | |||
1328 | static void halbtc8821a2ant_coex_under_5g(struct btc_coexist *btcoexist) | ||
1329 | { | ||
1330 | halbtc8821a2ant_coex_all_off(btcoexist); | ||
1331 | } | ||
1332 | |||
1333 | static void halbtc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist) | ||
1334 | { | ||
1335 | /* force to reset coex mechanism */ | ||
1336 | halbtc8821a2ant_coex_table(btcoexist, FORCE_EXEC, 0x55555555, | ||
1337 | 0x55555555, 0xffff, 0x3); | ||
1338 | |||
1339 | halbtc8821a2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1); | ||
1340 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6); | ||
1341 | halbtc8821a2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false); | ||
1342 | |||
1343 | btc8821a2ant_sw_mech1(btcoexist, false, false, false, false); | ||
1344 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1345 | } | ||
1346 | |||
1347 | static void halbtc8821a2ant_bt_inquiry_page(struct btc_coexist *btcoexist) | ||
1348 | { | ||
1349 | bool low_pwr_disable = true; | ||
1350 | |||
1351 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1352 | &low_pwr_disable); | ||
1353 | |||
1354 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
1355 | 0x5afa5afa, 0xffff, 0x3); | ||
1356 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); | ||
1357 | } | ||
1358 | |||
1359 | static bool halbtc8821a2ant_is_common_action(struct btc_coexist *btcoexist) | ||
1360 | { | ||
1361 | bool common = false, wifi_connected = false, wifi_busy = false; | ||
1362 | bool low_pwr_disable = false; | ||
1363 | |||
1364 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, | ||
1365 | &wifi_connected); | ||
1366 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
1367 | |||
1368 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
1369 | 0x5afa5afa, 0xffff, 0x3); | ||
1370 | |||
1371 | if (!wifi_connected && | ||
1372 | BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status) { | ||
1373 | low_pwr_disable = false; | ||
1374 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1375 | &low_pwr_disable); | ||
1376 | |||
1377 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1378 | "[BTCoex], Wifi IPS + BT IPS!!\n"); | ||
1379 | |||
1380 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
1381 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1382 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1383 | |||
1384 | btc8821a2ant_sw_mech1(btcoexist, false, false, false, false); | ||
1385 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1386 | |||
1387 | common = true; | ||
1388 | } else if (wifi_connected && | ||
1389 | (BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)) { | ||
1390 | low_pwr_disable = false; | ||
1391 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1392 | &low_pwr_disable); | ||
1393 | |||
1394 | if (wifi_busy) { | ||
1395 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1396 | "[BTCoex], Wifi Busy + BT IPS!!\n"); | ||
1397 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1398 | false, 1); | ||
1399 | } else { | ||
1400 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1401 | "[BTCoex], Wifi LPS + BT IPS!!\n"); | ||
1402 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1403 | false, 1); | ||
1404 | } | ||
1405 | |||
1406 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1407 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1408 | |||
1409 | btc8821a2ant_sw_mech1(btcoexist, false, false, false, false); | ||
1410 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1411 | |||
1412 | common = true; | ||
1413 | } else if (!wifi_connected && | ||
1414 | (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) { | ||
1415 | low_pwr_disable = true; | ||
1416 | btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1417 | &low_pwr_disable); | ||
1418 | |||
1419 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1420 | "[BTCoex], Wifi IPS + BT LPS!!\n"); | ||
1421 | |||
1422 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
1423 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1424 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1425 | |||
1426 | btc8821a2ant_sw_mech1(btcoexist, false, false, false, false); | ||
1427 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1428 | common = true; | ||
1429 | } else if (wifi_connected && | ||
1430 | (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) { | ||
1431 | low_pwr_disable = true; | ||
1432 | btcoexist->btc_set(btcoexist, | ||
1433 | BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable); | ||
1434 | |||
1435 | if (wifi_busy) { | ||
1436 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1437 | "[BTCoex], Wifi Busy + BT LPS!!\n"); | ||
1438 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1439 | false, 1); | ||
1440 | } else { | ||
1441 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1442 | "[BTCoex], Wifi LPS + BT LPS!!\n"); | ||
1443 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1444 | false, 1); | ||
1445 | } | ||
1446 | |||
1447 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1448 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1449 | |||
1450 | btc8821a2ant_sw_mech1(btcoexist, true, true, true, true); | ||
1451 | btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18); | ||
1452 | |||
1453 | common = true; | ||
1454 | } else if (!wifi_connected && | ||
1455 | (BT_8821A_2ANT_BT_STATUS_NON_IDLE == | ||
1456 | coex_dm->bt_status)) { | ||
1457 | low_pwr_disable = false; | ||
1458 | btcoexist->btc_set(btcoexist, | ||
1459 | BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable); | ||
1460 | |||
1461 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1462 | "[BTCoex], Wifi IPS + BT Busy!!\n"); | ||
1463 | |||
1464 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
1465 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
1466 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
1467 | |||
1468 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
1469 | false, false); | ||
1470 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
1471 | false, 0x18); | ||
1472 | |||
1473 | common = true; | ||
1474 | } else { | ||
1475 | low_pwr_disable = true; | ||
1476 | btcoexist->btc_set(btcoexist, | ||
1477 | BTC_SET_ACT_DISABLE_LOW_POWER, | ||
1478 | &low_pwr_disable); | ||
1479 | |||
1480 | if (wifi_busy) { | ||
1481 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1482 | "[BTCoex], Wifi Busy + BT Busy!!\n"); | ||
1483 | common = false; | ||
1484 | } else { | ||
1485 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
1486 | "[BTCoex], Wifi LPS + BT Busy!!\n"); | ||
1487 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
1488 | NORMAL_EXEC, true, 21); | ||
1489 | |||
1490 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
1491 | halbtc8821a2ant_dec_bt_pwr(btcoexist, | ||
1492 | NORMAL_EXEC, true); | ||
1493 | else | ||
1494 | halbtc8821a2ant_dec_bt_pwr(btcoexist, | ||
1495 | NORMAL_EXEC, false); | ||
1496 | |||
1497 | common = true; | ||
1498 | } | ||
1499 | btc8821a2ant_sw_mech1(btcoexist, true, true, true, true); | ||
1500 | } | ||
1501 | return common; | ||
1502 | } | ||
1503 | |||
1504 | static void btc8821a2_int1(struct btc_coexist *btcoexist, bool tx_pause, | ||
1505 | int result) | ||
1506 | { | ||
1507 | if (tx_pause) { | ||
1508 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1509 | "[BTCoex], TxPause = 1\n"); | ||
1510 | |||
1511 | if (coex_dm->cur_ps_tdma == 71) { | ||
1512 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1513 | true, 5); | ||
1514 | coex_dm->tdma_adj_type = 5; | ||
1515 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1516 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1517 | true, 5); | ||
1518 | coex_dm->tdma_adj_type = 5; | ||
1519 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1520 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1521 | true, 6); | ||
1522 | coex_dm->tdma_adj_type = 6; | ||
1523 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1524 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1525 | true, 7); | ||
1526 | coex_dm->tdma_adj_type = 7; | ||
1527 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
1528 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1529 | true, 8); | ||
1530 | coex_dm->tdma_adj_type = 8; | ||
1531 | } | ||
1532 | if (coex_dm->cur_ps_tdma == 9) { | ||
1533 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1534 | true, 13); | ||
1535 | coex_dm->tdma_adj_type = 13; | ||
1536 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1537 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1538 | true, 14); | ||
1539 | coex_dm->tdma_adj_type = 14; | ||
1540 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1541 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1542 | true, 15); | ||
1543 | coex_dm->tdma_adj_type = 15; | ||
1544 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1545 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1546 | true, 16); | ||
1547 | coex_dm->tdma_adj_type = 16; | ||
1548 | } | ||
1549 | |||
1550 | if (result == -1) { | ||
1551 | if (coex_dm->cur_ps_tdma == 5) { | ||
1552 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1553 | true, 6); | ||
1554 | coex_dm->tdma_adj_type = 6; | ||
1555 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1556 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1557 | true, 7); | ||
1558 | coex_dm->tdma_adj_type = 7; | ||
1559 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1560 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1561 | true, 8); | ||
1562 | coex_dm->tdma_adj_type = 8; | ||
1563 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
1564 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1565 | true, 14); | ||
1566 | coex_dm->tdma_adj_type = 14; | ||
1567 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1568 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1569 | true, 15); | ||
1570 | coex_dm->tdma_adj_type = 15; | ||
1571 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1572 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1573 | true, 16); | ||
1574 | coex_dm->tdma_adj_type = 16; | ||
1575 | } | ||
1576 | } else if (result == 1) { | ||
1577 | if (coex_dm->cur_ps_tdma == 8) { | ||
1578 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1579 | true, 7); | ||
1580 | coex_dm->tdma_adj_type = 7; | ||
1581 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1582 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1583 | true, 6); | ||
1584 | coex_dm->tdma_adj_type = 6; | ||
1585 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1586 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1587 | true, 5); | ||
1588 | coex_dm->tdma_adj_type = 5; | ||
1589 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1590 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1591 | true, 15); | ||
1592 | coex_dm->tdma_adj_type = 15; | ||
1593 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1594 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1595 | true, 14); | ||
1596 | coex_dm->tdma_adj_type = 14; | ||
1597 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1598 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1599 | true, 13); | ||
1600 | coex_dm->tdma_adj_type = 13; | ||
1601 | } | ||
1602 | } | ||
1603 | } else { | ||
1604 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1605 | "[BTCoex], TxPause = 0\n"); | ||
1606 | if (coex_dm->cur_ps_tdma == 5) { | ||
1607 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1608 | true, 71); | ||
1609 | coex_dm->tdma_adj_type = 71; | ||
1610 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1611 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1612 | true, 2); | ||
1613 | coex_dm->tdma_adj_type = 2; | ||
1614 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1615 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1616 | true, 3); | ||
1617 | coex_dm->tdma_adj_type = 3; | ||
1618 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
1619 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1620 | true, 4); | ||
1621 | coex_dm->tdma_adj_type = 4; | ||
1622 | } | ||
1623 | if (coex_dm->cur_ps_tdma == 13) { | ||
1624 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1625 | true, 9); | ||
1626 | coex_dm->tdma_adj_type = 9; | ||
1627 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1628 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1629 | true, 10); | ||
1630 | coex_dm->tdma_adj_type = 10; | ||
1631 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1632 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1633 | true, 11); | ||
1634 | coex_dm->tdma_adj_type = 11; | ||
1635 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1636 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1637 | true, 12); | ||
1638 | coex_dm->tdma_adj_type = 12; | ||
1639 | } | ||
1640 | |||
1641 | if (result == -1) { | ||
1642 | if (coex_dm->cur_ps_tdma == 71) { | ||
1643 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1644 | true, 1); | ||
1645 | coex_dm->tdma_adj_type = 1; | ||
1646 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1647 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1648 | true, 2); | ||
1649 | coex_dm->tdma_adj_type = 2; | ||
1650 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1651 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1652 | true, 3); | ||
1653 | coex_dm->tdma_adj_type = 3; | ||
1654 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1655 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1656 | true, 4); | ||
1657 | coex_dm->tdma_adj_type = 4; | ||
1658 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1659 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1660 | true, 10); | ||
1661 | coex_dm->tdma_adj_type = 10; | ||
1662 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1663 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1664 | true, 11); | ||
1665 | coex_dm->tdma_adj_type = 11; | ||
1666 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1667 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1668 | true, 12); | ||
1669 | coex_dm->tdma_adj_type = 12; | ||
1670 | } | ||
1671 | } else if (result == 1) { | ||
1672 | if (coex_dm->cur_ps_tdma == 4) { | ||
1673 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1674 | true, 3); | ||
1675 | coex_dm->tdma_adj_type = 3; | ||
1676 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1677 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1678 | true, 2); | ||
1679 | coex_dm->tdma_adj_type = 2; | ||
1680 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1681 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1682 | true, 1); | ||
1683 | coex_dm->tdma_adj_type = 1; | ||
1684 | } else if (coex_dm->cur_ps_tdma == 1) { | ||
1685 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1686 | true, 71); | ||
1687 | coex_dm->tdma_adj_type = 71; | ||
1688 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1689 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1690 | true, 11); | ||
1691 | coex_dm->tdma_adj_type = 11; | ||
1692 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1693 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1694 | true, 10); | ||
1695 | coex_dm->tdma_adj_type = 10; | ||
1696 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1697 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1698 | true, 9); | ||
1699 | coex_dm->tdma_adj_type = 9; | ||
1700 | } | ||
1701 | } | ||
1702 | } | ||
1703 | } | ||
1704 | |||
1705 | static void btc8821a2_int2(struct btc_coexist *btcoexist, bool tx_pause, | ||
1706 | int result) | ||
1707 | { | ||
1708 | if (tx_pause) { | ||
1709 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1710 | "[BTCoex], TxPause = 1\n"); | ||
1711 | if (coex_dm->cur_ps_tdma == 1) { | ||
1712 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1713 | true, 6); | ||
1714 | coex_dm->tdma_adj_type = 6; | ||
1715 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1716 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1717 | true, 6); | ||
1718 | coex_dm->tdma_adj_type = 6; | ||
1719 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1720 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1721 | true, 7); | ||
1722 | coex_dm->tdma_adj_type = 7; | ||
1723 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
1724 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1725 | true, 8); | ||
1726 | coex_dm->tdma_adj_type = 8; | ||
1727 | } | ||
1728 | if (coex_dm->cur_ps_tdma == 9) { | ||
1729 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1730 | true, 14); | ||
1731 | coex_dm->tdma_adj_type = 14; | ||
1732 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1733 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1734 | true, 14); | ||
1735 | coex_dm->tdma_adj_type = 14; | ||
1736 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1737 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1738 | true, 15); | ||
1739 | coex_dm->tdma_adj_type = 15; | ||
1740 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1741 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1742 | true, 16); | ||
1743 | coex_dm->tdma_adj_type = 16; | ||
1744 | } | ||
1745 | if (result == -1) { | ||
1746 | if (coex_dm->cur_ps_tdma == 5) { | ||
1747 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1748 | true, 6); | ||
1749 | coex_dm->tdma_adj_type = 6; | ||
1750 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1751 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1752 | true, 7); | ||
1753 | coex_dm->tdma_adj_type = 7; | ||
1754 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1755 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1756 | true, 8); | ||
1757 | coex_dm->tdma_adj_type = 8; | ||
1758 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
1759 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1760 | true, 14); | ||
1761 | coex_dm->tdma_adj_type = 14; | ||
1762 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1763 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1764 | true, 15); | ||
1765 | coex_dm->tdma_adj_type = 15; | ||
1766 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1767 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1768 | true, 16); | ||
1769 | coex_dm->tdma_adj_type = 16; | ||
1770 | } | ||
1771 | } else if (result == 1) { | ||
1772 | if (coex_dm->cur_ps_tdma == 8) { | ||
1773 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1774 | true, 7); | ||
1775 | coex_dm->tdma_adj_type = 7; | ||
1776 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1777 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1778 | true, 6); | ||
1779 | coex_dm->tdma_adj_type = 6; | ||
1780 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1781 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1782 | true, 6); | ||
1783 | coex_dm->tdma_adj_type = 6; | ||
1784 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1785 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1786 | true, 15); | ||
1787 | coex_dm->tdma_adj_type = 15; | ||
1788 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1789 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1790 | true, 14); | ||
1791 | coex_dm->tdma_adj_type = 14; | ||
1792 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1793 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1794 | true, 14); | ||
1795 | coex_dm->tdma_adj_type = 14; | ||
1796 | } | ||
1797 | } | ||
1798 | } else { | ||
1799 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1800 | "[BTCoex], TxPause = 0\n"); | ||
1801 | if (coex_dm->cur_ps_tdma == 5) { | ||
1802 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1803 | true, 2); | ||
1804 | coex_dm->tdma_adj_type = 2; | ||
1805 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1806 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1807 | true, 2); | ||
1808 | coex_dm->tdma_adj_type = 2; | ||
1809 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1810 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1811 | true, 3); | ||
1812 | coex_dm->tdma_adj_type = 3; | ||
1813 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
1814 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1815 | true, 4); | ||
1816 | coex_dm->tdma_adj_type = 4; | ||
1817 | } | ||
1818 | if (coex_dm->cur_ps_tdma == 13) { | ||
1819 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1820 | true, 10); | ||
1821 | coex_dm->tdma_adj_type = 10; | ||
1822 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1823 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1824 | true, 10); | ||
1825 | coex_dm->tdma_adj_type = 10; | ||
1826 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1827 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1828 | true, 11); | ||
1829 | coex_dm->tdma_adj_type = 11; | ||
1830 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1831 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1832 | true, 12); | ||
1833 | coex_dm->tdma_adj_type = 12; | ||
1834 | } | ||
1835 | if (result == -1) { | ||
1836 | if (coex_dm->cur_ps_tdma == 1) { | ||
1837 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1838 | true, 2); | ||
1839 | coex_dm->tdma_adj_type = 2; | ||
1840 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1841 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1842 | true, 3); | ||
1843 | coex_dm->tdma_adj_type = 3; | ||
1844 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1845 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1846 | true, 4); | ||
1847 | coex_dm->tdma_adj_type = 4; | ||
1848 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
1849 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1850 | true, 10); | ||
1851 | coex_dm->tdma_adj_type = 10; | ||
1852 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1853 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1854 | true, 11); | ||
1855 | coex_dm->tdma_adj_type = 11; | ||
1856 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1857 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1858 | true, 12); | ||
1859 | coex_dm->tdma_adj_type = 12; | ||
1860 | } | ||
1861 | } else if (result == 1) { | ||
1862 | if (coex_dm->cur_ps_tdma == 4) { | ||
1863 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1864 | true, 3); | ||
1865 | coex_dm->tdma_adj_type = 3; | ||
1866 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1867 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1868 | true, 2); | ||
1869 | coex_dm->tdma_adj_type = 2; | ||
1870 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1871 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1872 | true, 2); | ||
1873 | coex_dm->tdma_adj_type = 2; | ||
1874 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1875 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1876 | true, 11); | ||
1877 | coex_dm->tdma_adj_type = 11; | ||
1878 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1879 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1880 | true, 10); | ||
1881 | coex_dm->tdma_adj_type = 10; | ||
1882 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1883 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1884 | true, 10); | ||
1885 | coex_dm->tdma_adj_type = 10; | ||
1886 | } | ||
1887 | } | ||
1888 | } | ||
1889 | } | ||
1890 | |||
1891 | static void btc8821a2_int3(struct btc_coexist *btcoexist, bool tx_pause, | ||
1892 | int result) | ||
1893 | { | ||
1894 | if (tx_pause) { | ||
1895 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1896 | "[BTCoex], TxPause = 1\n"); | ||
1897 | if (coex_dm->cur_ps_tdma == 1) { | ||
1898 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1899 | true, 7); | ||
1900 | coex_dm->tdma_adj_type = 7; | ||
1901 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
1902 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1903 | true, 7); | ||
1904 | coex_dm->tdma_adj_type = 7; | ||
1905 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
1906 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1907 | true, 7); | ||
1908 | coex_dm->tdma_adj_type = 7; | ||
1909 | } else if (coex_dm->cur_ps_tdma == 4) { | ||
1910 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1911 | true, 8); | ||
1912 | coex_dm->tdma_adj_type = 8; | ||
1913 | } | ||
1914 | if (coex_dm->cur_ps_tdma == 9) { | ||
1915 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1916 | true, 15); | ||
1917 | coex_dm->tdma_adj_type = 15; | ||
1918 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
1919 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1920 | true, 15); | ||
1921 | coex_dm->tdma_adj_type = 15; | ||
1922 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
1923 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1924 | true, 15); | ||
1925 | coex_dm->tdma_adj_type = 15; | ||
1926 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
1927 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1928 | true, 16); | ||
1929 | coex_dm->tdma_adj_type = 16; | ||
1930 | } | ||
1931 | if (result == -1) { | ||
1932 | if (coex_dm->cur_ps_tdma == 5) { | ||
1933 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1934 | true, 7); | ||
1935 | coex_dm->tdma_adj_type = 7; | ||
1936 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1937 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1938 | true, 7); | ||
1939 | coex_dm->tdma_adj_type = 7; | ||
1940 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1941 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1942 | true, 8); | ||
1943 | coex_dm->tdma_adj_type = 8; | ||
1944 | } else if (coex_dm->cur_ps_tdma == 13) { | ||
1945 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1946 | true, 15); | ||
1947 | coex_dm->tdma_adj_type = 15; | ||
1948 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1949 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1950 | true, 15); | ||
1951 | coex_dm->tdma_adj_type = 15; | ||
1952 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1953 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1954 | true, 16); | ||
1955 | coex_dm->tdma_adj_type = 16; | ||
1956 | } | ||
1957 | } else if (result == 1) { | ||
1958 | if (coex_dm->cur_ps_tdma == 8) { | ||
1959 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1960 | true, 7); | ||
1961 | coex_dm->tdma_adj_type = 7; | ||
1962 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1963 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1964 | true, 7); | ||
1965 | coex_dm->tdma_adj_type = 7; | ||
1966 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1967 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1968 | true, 7); | ||
1969 | coex_dm->tdma_adj_type = 7; | ||
1970 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
1971 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1972 | true, 15); | ||
1973 | coex_dm->tdma_adj_type = 15; | ||
1974 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
1975 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1976 | true, 15); | ||
1977 | coex_dm->tdma_adj_type = 15; | ||
1978 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
1979 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1980 | true, 15); | ||
1981 | coex_dm->tdma_adj_type = 15; | ||
1982 | } | ||
1983 | } | ||
1984 | } else { | ||
1985 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
1986 | "[BTCoex], TxPause = 0\n"); | ||
1987 | if (coex_dm->cur_ps_tdma == 5) { | ||
1988 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1989 | true, 3); | ||
1990 | coex_dm->tdma_adj_type = 3; | ||
1991 | } else if (coex_dm->cur_ps_tdma == 6) { | ||
1992 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1993 | true, 3); | ||
1994 | coex_dm->tdma_adj_type = 3; | ||
1995 | } else if (coex_dm->cur_ps_tdma == 7) { | ||
1996 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
1997 | true, 3); | ||
1998 | coex_dm->tdma_adj_type = 3; | ||
1999 | } else if (coex_dm->cur_ps_tdma == 8) { | ||
2000 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2001 | true, 4); | ||
2002 | coex_dm->tdma_adj_type = 4; | ||
2003 | } | ||
2004 | if (coex_dm->cur_ps_tdma == 13) { | ||
2005 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2006 | true, 11); | ||
2007 | coex_dm->tdma_adj_type = 11; | ||
2008 | } else if (coex_dm->cur_ps_tdma == 14) { | ||
2009 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2010 | true, 11); | ||
2011 | coex_dm->tdma_adj_type = 11; | ||
2012 | } else if (coex_dm->cur_ps_tdma == 15) { | ||
2013 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2014 | true, 11); | ||
2015 | coex_dm->tdma_adj_type = 11; | ||
2016 | } else if (coex_dm->cur_ps_tdma == 16) { | ||
2017 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2018 | true, 12); | ||
2019 | coex_dm->tdma_adj_type = 12; | ||
2020 | } | ||
2021 | if (result == -1) { | ||
2022 | if (coex_dm->cur_ps_tdma == 1) { | ||
2023 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2024 | true, 3); | ||
2025 | coex_dm->tdma_adj_type = 3; | ||
2026 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
2027 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2028 | true, 3); | ||
2029 | coex_dm->tdma_adj_type = 3; | ||
2030 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
2031 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2032 | true, 4); | ||
2033 | coex_dm->tdma_adj_type = 4; | ||
2034 | } else if (coex_dm->cur_ps_tdma == 9) { | ||
2035 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2036 | true, 11); | ||
2037 | coex_dm->tdma_adj_type = 11; | ||
2038 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
2039 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2040 | true, 11); | ||
2041 | coex_dm->tdma_adj_type = 11; | ||
2042 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
2043 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2044 | true, 12); | ||
2045 | coex_dm->tdma_adj_type = 12; | ||
2046 | } | ||
2047 | } else if (result == 1) { | ||
2048 | if (coex_dm->cur_ps_tdma == 4) { | ||
2049 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2050 | true, 3); | ||
2051 | coex_dm->tdma_adj_type = 3; | ||
2052 | } else if (coex_dm->cur_ps_tdma == 3) { | ||
2053 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2054 | true, 3); | ||
2055 | coex_dm->tdma_adj_type = 3; | ||
2056 | } else if (coex_dm->cur_ps_tdma == 2) { | ||
2057 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2058 | true, 3); | ||
2059 | coex_dm->tdma_adj_type = 3; | ||
2060 | } else if (coex_dm->cur_ps_tdma == 12) { | ||
2061 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2062 | true, 11); | ||
2063 | coex_dm->tdma_adj_type = 11; | ||
2064 | } else if (coex_dm->cur_ps_tdma == 11) { | ||
2065 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2066 | true, 11); | ||
2067 | coex_dm->tdma_adj_type = 11; | ||
2068 | } else if (coex_dm->cur_ps_tdma == 10) { | ||
2069 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2070 | true, 11); | ||
2071 | coex_dm->tdma_adj_type = 11; | ||
2072 | } | ||
2073 | } | ||
2074 | } | ||
2075 | } | ||
2076 | |||
2077 | static void btc8821a2ant_tdma_dur_adj(struct btc_coexist *btcoexist, | ||
2078 | bool sco_hid, bool tx_pause, | ||
2079 | u8 max_interval) | ||
2080 | { | ||
2081 | static long up, dn, m, n, wait_count; | ||
2082 | /* 0: no change, +1: increase WiFi duration, | ||
2083 | * -1: decrease WiFi duration | ||
2084 | */ | ||
2085 | int result; | ||
2086 | u8 retry_count = 0; | ||
2087 | |||
2088 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, | ||
2089 | "[BTCoex], TdmaDurationAdjust()\n"); | ||
2090 | |||
2091 | if (coex_dm->reset_tdma_adjust) { | ||
2092 | coex_dm->reset_tdma_adjust = false; | ||
2093 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2094 | "[BTCoex], first run TdmaDurationAdjust()!!\n"); | ||
2095 | if (sco_hid) { | ||
2096 | if (tx_pause) { | ||
2097 | if (max_interval == 1) { | ||
2098 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2099 | NORMAL_EXEC, | ||
2100 | true, 13); | ||
2101 | coex_dm->tdma_adj_type = 13; | ||
2102 | } else if (max_interval == 2) { | ||
2103 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2104 | NORMAL_EXEC, | ||
2105 | true, 14); | ||
2106 | coex_dm->tdma_adj_type = 14; | ||
2107 | } else if (max_interval == 3) { | ||
2108 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2109 | NORMAL_EXEC, | ||
2110 | true, 15); | ||
2111 | coex_dm->tdma_adj_type = 15; | ||
2112 | } else { | ||
2113 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2114 | NORMAL_EXEC, | ||
2115 | true, 15); | ||
2116 | coex_dm->tdma_adj_type = 15; | ||
2117 | } | ||
2118 | } else { | ||
2119 | if (max_interval == 1) { | ||
2120 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2121 | NORMAL_EXEC, | ||
2122 | true, 9); | ||
2123 | coex_dm->tdma_adj_type = 9; | ||
2124 | } else if (max_interval == 2) { | ||
2125 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2126 | NORMAL_EXEC, | ||
2127 | true, 10); | ||
2128 | coex_dm->tdma_adj_type = 10; | ||
2129 | } else if (max_interval == 3) { | ||
2130 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2131 | NORMAL_EXEC, | ||
2132 | true, 11); | ||
2133 | coex_dm->tdma_adj_type = 11; | ||
2134 | } else { | ||
2135 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2136 | NORMAL_EXEC, | ||
2137 | true, 11); | ||
2138 | coex_dm->tdma_adj_type = 11; | ||
2139 | } | ||
2140 | } | ||
2141 | } else { | ||
2142 | if (tx_pause) { | ||
2143 | if (max_interval == 1) { | ||
2144 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2145 | NORMAL_EXEC, | ||
2146 | true, 5); | ||
2147 | coex_dm->tdma_adj_type = 5; | ||
2148 | } else if (max_interval == 2) { | ||
2149 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2150 | NORMAL_EXEC, | ||
2151 | true, 6); | ||
2152 | coex_dm->tdma_adj_type = 6; | ||
2153 | } else if (max_interval == 3) { | ||
2154 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2155 | NORMAL_EXEC, | ||
2156 | true, 7); | ||
2157 | coex_dm->tdma_adj_type = 7; | ||
2158 | } else { | ||
2159 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2160 | NORMAL_EXEC, | ||
2161 | true, 7); | ||
2162 | coex_dm->tdma_adj_type = 7; | ||
2163 | } | ||
2164 | } else { | ||
2165 | if (max_interval == 1) { | ||
2166 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2167 | NORMAL_EXEC, | ||
2168 | true, 1); | ||
2169 | coex_dm->tdma_adj_type = 1; | ||
2170 | } else if (max_interval == 2) { | ||
2171 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2172 | NORMAL_EXEC, | ||
2173 | true, 2); | ||
2174 | coex_dm->tdma_adj_type = 2; | ||
2175 | } else if (max_interval == 3) { | ||
2176 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2177 | NORMAL_EXEC, | ||
2178 | true, 3); | ||
2179 | coex_dm->tdma_adj_type = 3; | ||
2180 | } else { | ||
2181 | halbtc8821a2ant_ps_tdma(btcoexist, | ||
2182 | NORMAL_EXEC, | ||
2183 | true, 3); | ||
2184 | coex_dm->tdma_adj_type = 3; | ||
2185 | } | ||
2186 | } | ||
2187 | } | ||
2188 | |||
2189 | up = 0; | ||
2190 | dn = 0; | ||
2191 | m = 1; | ||
2192 | n = 3; | ||
2193 | result = 0; | ||
2194 | wait_count = 0; | ||
2195 | } else { | ||
2196 | /* accquire the BT TRx retry count from BT_Info byte2 */ | ||
2197 | retry_count = coex_sta->bt_retry_cnt; | ||
2198 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2199 | "[BTCoex], retry_count = %d\n", retry_count); | ||
2200 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2201 | "[BTCoex], up = %d, dn = %d, m = %d, n = %d, wait_count = %d\n", | ||
2202 | (int)up, (int)dn, (int)m, (int)n, (int)wait_count); | ||
2203 | result = 0; | ||
2204 | wait_count++; | ||
2205 | |||
2206 | if (retry_count == 0) { | ||
2207 | /* no retry in the last 2-second duration */ | ||
2208 | up++; | ||
2209 | dn--; | ||
2210 | |||
2211 | if (dn <= 0) | ||
2212 | dn = 0; | ||
2213 | |||
2214 | if (up >= n) { | ||
2215 | /* if (retry count == 0) for 2*n seconds, | ||
2216 | * make WiFi duration wider | ||
2217 | */ | ||
2218 | wait_count = 0; | ||
2219 | n = 3; | ||
2220 | up = 0; | ||
2221 | dn = 0; | ||
2222 | result = 1; | ||
2223 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2224 | ALGO_TRACE_FW_DETAIL, | ||
2225 | "[BTCoex], Increase wifi duration!!\n"); | ||
2226 | } | ||
2227 | } else if (retry_count <= 3) { | ||
2228 | /* <=3 retry in the last 2-second duration */ | ||
2229 | up--; | ||
2230 | dn++; | ||
2231 | |||
2232 | if (up <= 0) | ||
2233 | up = 0; | ||
2234 | |||
2235 | if (dn == 2) { | ||
2236 | /* if retry count< 3 for 2*2 seconds, | ||
2237 | * shrink wifi duration | ||
2238 | */ | ||
2239 | if (wait_count <= 2) | ||
2240 | m++; /* avoid bounce in two levels */ | ||
2241 | else | ||
2242 | m = 1; | ||
2243 | /* m max value is 20, max time is 120 second, | ||
2244 | * recheck if adjust WiFi duration. | ||
2245 | */ | ||
2246 | if (m >= 20) | ||
2247 | m = 20; | ||
2248 | |||
2249 | n = 3*m; | ||
2250 | up = 0; | ||
2251 | dn = 0; | ||
2252 | wait_count = 0; | ||
2253 | result = -1; | ||
2254 | BTC_PRINT(BTC_MSG_ALGORITHM, | ||
2255 | ALGO_TRACE_FW_DETAIL, | ||
2256 | "[BTCoex], Decrease wifi duration for retryCounter<3!!\n"); | ||
2257 | } | ||
2258 | } else { | ||
2259 | /* retry count > 3, if retry count > 3 happens once, | ||
2260 | * shrink WiFi duration | ||
2261 | */ | ||
2262 | if (wait_count == 1) | ||
2263 | m++; /* avoid bounce in two levels */ | ||
2264 | else | ||
2265 | m = 1; | ||
2266 | /* m max value is 20, max time is 120 second, | ||
2267 | * recheck if adjust WiFi duration. | ||
2268 | */ | ||
2269 | if (m >= 20) | ||
2270 | m = 20; | ||
2271 | |||
2272 | n = 3*m; | ||
2273 | up = 0; | ||
2274 | dn = 0; | ||
2275 | wait_count = 0; | ||
2276 | result = -1; | ||
2277 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2278 | "[BTCoex], Decrease wifi duration for retryCounter>3!!\n"); | ||
2279 | } | ||
2280 | |||
2281 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2282 | "[BTCoex], max Interval = %d\n", max_interval); | ||
2283 | if (max_interval == 1) | ||
2284 | btc8821a2_int1(btcoexist, tx_pause, result); | ||
2285 | else if (max_interval == 2) | ||
2286 | btc8821a2_int2(btcoexist, tx_pause, result); | ||
2287 | else if (max_interval == 3) | ||
2288 | btc8821a2_int3(btcoexist, tx_pause, result); | ||
2289 | } | ||
2290 | |||
2291 | /* if current PsTdma not match with the recorded one | ||
2292 | * (when scan, dhcp...), then we have to adjust it back to | ||
2293 | * the previous recorded one. | ||
2294 | */ | ||
2295 | if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) { | ||
2296 | bool scan = false, link = false, roam = false; | ||
2297 | |||
2298 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2299 | "[BTCoex], PsTdma type dismatch!!!, cur_ps_tdma = %d, recordPsTdma = %d\n", | ||
2300 | coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type); | ||
2301 | |||
2302 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
2303 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
2304 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
2305 | |||
2306 | if (!scan && !link && !roam) { | ||
2307 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, | ||
2308 | coex_dm->tdma_adj_type); | ||
2309 | } else { | ||
2310 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, | ||
2311 | "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"); | ||
2312 | } | ||
2313 | } | ||
2314 | |||
2315 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0x6); | ||
2316 | } | ||
2317 | |||
2318 | /* SCO only or SCO+PAN(HS)*/ | ||
2319 | static void halbtc8821a2ant_action_sco(struct btc_coexist *btcoexist) | ||
2320 | { | ||
2321 | u8 wifi_rssi_state, bt_rssi_state; | ||
2322 | u32 wifi_bw; | ||
2323 | |||
2324 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2325 | 15, 0); | ||
2326 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2327 | |||
2328 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4); | ||
2329 | |||
2330 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2331 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2332 | else | ||
2333 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2334 | |||
2335 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2336 | |||
2337 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2338 | /* for SCO quality at 11b/g mode */ | ||
2339 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, | ||
2340 | 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3); | ||
2341 | } else { | ||
2342 | /* for SCO quality & wifi performance balance at 11n mode */ | ||
2343 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, | ||
2344 | 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3); | ||
2345 | } | ||
2346 | |||
2347 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2348 | /* fw mechanism | ||
2349 | * halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
2350 | */ | ||
2351 | |||
2352 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2353 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2354 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2355 | false, 0); /*for voice quality*/ | ||
2356 | } else { | ||
2357 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2358 | false, 0); /*for voice quality*/ | ||
2359 | } | ||
2360 | |||
2361 | /* sw mechanism */ | ||
2362 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2363 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2364 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2365 | false, false); | ||
2366 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2367 | false, 0x18); | ||
2368 | } else { | ||
2369 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2370 | false, false); | ||
2371 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2372 | false, 0x18); | ||
2373 | } | ||
2374 | } else { | ||
2375 | /* fw mechanism | ||
2376 | * halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5); | ||
2377 | */ | ||
2378 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2379 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2380 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2381 | false, 0); /*for voice quality*/ | ||
2382 | } else { | ||
2383 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2384 | false, 0); /*for voice quality*/ | ||
2385 | } | ||
2386 | |||
2387 | /* sw mechanism */ | ||
2388 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2389 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2390 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2391 | false, false); | ||
2392 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2393 | false, 0x18); | ||
2394 | } else { | ||
2395 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2396 | false, false); | ||
2397 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2398 | false, 0x18); | ||
2399 | } | ||
2400 | } | ||
2401 | } | ||
2402 | |||
2403 | static void halbtc8821a2ant_action_hid(struct btc_coexist *btcoexist) | ||
2404 | { | ||
2405 | u8 wifi_rssi_state, bt_rssi_state; | ||
2406 | u32 wifi_bw; | ||
2407 | |||
2408 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, | ||
2409 | 0, 2, 15, 0); | ||
2410 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2411 | |||
2412 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2413 | |||
2414 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2415 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2416 | else | ||
2417 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2418 | |||
2419 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2420 | |||
2421 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2422 | /* for HID at 11b/g mode */ | ||
2423 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2424 | 0x5a5a5a5a, 0xffff, 0x3); | ||
2425 | } else { | ||
2426 | /* for HID quality & wifi performance balance at 11n mode */ | ||
2427 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2428 | 0x5aea5aea, 0xffff, 0x3); | ||
2429 | } | ||
2430 | |||
2431 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2432 | /* fw mechanism */ | ||
2433 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2434 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2435 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2436 | true, 9); | ||
2437 | } else { | ||
2438 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2439 | true, 13); | ||
2440 | } | ||
2441 | |||
2442 | /* sw mechanism */ | ||
2443 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2444 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2445 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2446 | false, false); | ||
2447 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2448 | false, 0x18); | ||
2449 | } else { | ||
2450 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2451 | false, false); | ||
2452 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2453 | false, 0x18); | ||
2454 | } | ||
2455 | } else { | ||
2456 | /* fw mechanism */ | ||
2457 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2458 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2459 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2460 | true, 9); | ||
2461 | } else { | ||
2462 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2463 | true, 13); | ||
2464 | } | ||
2465 | |||
2466 | /* sw mechanism */ | ||
2467 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2468 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2469 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2470 | false, false); | ||
2471 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2472 | false, 0x18); | ||
2473 | } else { | ||
2474 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2475 | false, false); | ||
2476 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2477 | false, 0x18); | ||
2478 | } | ||
2479 | } | ||
2480 | } | ||
2481 | |||
2482 | /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */ | ||
2483 | static void halbtc8821a2ant_action_a2dp(struct btc_coexist *btcoexist) | ||
2484 | { | ||
2485 | u8 wifi_rssi_state, bt_rssi_state; | ||
2486 | u32 wifi_bw; | ||
2487 | |||
2488 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2489 | 15, 0); | ||
2490 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2491 | |||
2492 | /* fw dac swing is called in btc8821a2ant_tdma_dur_adj() | ||
2493 | * halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2494 | */ | ||
2495 | |||
2496 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2497 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2498 | else | ||
2499 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2500 | |||
2501 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2502 | |||
2503 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2504 | /* fw mechanism */ | ||
2505 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2506 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2507 | btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1); | ||
2508 | } else { | ||
2509 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1); | ||
2510 | } | ||
2511 | |||
2512 | /* sw mechanism */ | ||
2513 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2514 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2515 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2516 | false, false); | ||
2517 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2518 | false, 0x18); | ||
2519 | } else { | ||
2520 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2521 | false, false); | ||
2522 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2523 | false, 0x18); | ||
2524 | } | ||
2525 | } else { | ||
2526 | /* fw mechanism */ | ||
2527 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2528 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2529 | btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1); | ||
2530 | } else { | ||
2531 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1); | ||
2532 | } | ||
2533 | |||
2534 | /* sw mechanism */ | ||
2535 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2536 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2537 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2538 | false, false); | ||
2539 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2540 | false, 0x18); | ||
2541 | } else { | ||
2542 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2543 | false, false); | ||
2544 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2545 | false, 0x18); | ||
2546 | } | ||
2547 | } | ||
2548 | } | ||
2549 | |||
2550 | static void halbtc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist) | ||
2551 | { | ||
2552 | u8 wifi_rssi_state, bt_rssi_state, bt_info_ext; | ||
2553 | u32 wifi_bw; | ||
2554 | |||
2555 | bt_info_ext = coex_sta->bt_info_ext; | ||
2556 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2557 | 15, 0); | ||
2558 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2559 | |||
2560 | /*fw dac swing is called in btc8821a2ant_tdma_dur_adj() | ||
2561 | *halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2562 | */ | ||
2563 | |||
2564 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2565 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2566 | else | ||
2567 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2568 | |||
2569 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2570 | |||
2571 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2572 | /* fw mechanism */ | ||
2573 | if (bt_info_ext&BIT0) { | ||
2574 | /*a2dp basic rate*/ | ||
2575 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2); | ||
2576 | } else { | ||
2577 | /*a2dp edr rate*/ | ||
2578 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1); | ||
2579 | } | ||
2580 | |||
2581 | /* sw mechanism */ | ||
2582 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2583 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2584 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2585 | false, false); | ||
2586 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2587 | false, 0x18); | ||
2588 | } else { | ||
2589 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2590 | false, false); | ||
2591 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2592 | false, 0x18); | ||
2593 | } | ||
2594 | } else { | ||
2595 | /* fw mechanism */ | ||
2596 | if (bt_info_ext&BIT0) { | ||
2597 | /* a2dp basic rate */ | ||
2598 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2); | ||
2599 | } else { | ||
2600 | /* a2dp edr rate */ | ||
2601 | btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1); | ||
2602 | } | ||
2603 | |||
2604 | /* sw mechanism */ | ||
2605 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2606 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2607 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2608 | false, false); | ||
2609 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2610 | false, 0x18); | ||
2611 | } else { | ||
2612 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2613 | false, false); | ||
2614 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2615 | false, 0x18); | ||
2616 | } | ||
2617 | } | ||
2618 | } | ||
2619 | |||
2620 | static void halbtc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist) | ||
2621 | { | ||
2622 | u8 wifi_rssi_state, bt_rssi_state; | ||
2623 | u32 wifi_bw; | ||
2624 | |||
2625 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2626 | 15, 0); | ||
2627 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2628 | |||
2629 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2630 | |||
2631 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2632 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2633 | else | ||
2634 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2635 | |||
2636 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2637 | |||
2638 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2639 | /* for HID at 11b/g mode */ | ||
2640 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2641 | 0x5aff5aff, 0xffff, 0x3); | ||
2642 | } else { | ||
2643 | /* for HID quality & wifi performance balance at 11n mode */ | ||
2644 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2645 | 0x5aff5aff, 0xffff, 0x3); | ||
2646 | } | ||
2647 | |||
2648 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2649 | /* fw mechanism */ | ||
2650 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2651 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2652 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2653 | true, 1); | ||
2654 | } else { | ||
2655 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2656 | true, 5); | ||
2657 | } | ||
2658 | |||
2659 | /* sw mechanism */ | ||
2660 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2661 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2662 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2663 | false, false); | ||
2664 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2665 | false, 0x18); | ||
2666 | } else { | ||
2667 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2668 | false, false); | ||
2669 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2670 | false, 0x18); | ||
2671 | } | ||
2672 | } else { | ||
2673 | /* fw mechanism */ | ||
2674 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2675 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2676 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2677 | true, 1); | ||
2678 | } else { | ||
2679 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2680 | true, 5); | ||
2681 | } | ||
2682 | |||
2683 | /* sw mechanism */ | ||
2684 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2685 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2686 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2687 | false, false); | ||
2688 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2689 | false, 0x18); | ||
2690 | } else { | ||
2691 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2692 | false, false); | ||
2693 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2694 | false, 0x18); | ||
2695 | } | ||
2696 | } | ||
2697 | } | ||
2698 | |||
2699 | /* PAN(HS) only */ | ||
2700 | static void halbtc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist) | ||
2701 | { | ||
2702 | u8 wifi_rssi_state, bt_rssi_state; | ||
2703 | u32 wifi_bw; | ||
2704 | |||
2705 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, | ||
2706 | 0, 2, 15, 0); | ||
2707 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2708 | |||
2709 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2710 | |||
2711 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2712 | |||
2713 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2714 | /* fw mechanism */ | ||
2715 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2716 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2717 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, | ||
2718 | true); | ||
2719 | } else { | ||
2720 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, | ||
2721 | false); | ||
2722 | } | ||
2723 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1); | ||
2724 | |||
2725 | /* sw mechanism */ | ||
2726 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2727 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2728 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2729 | false, false); | ||
2730 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2731 | false, 0x18); | ||
2732 | } else { | ||
2733 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2734 | false, false); | ||
2735 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2736 | false, 0x18); | ||
2737 | } | ||
2738 | } else { | ||
2739 | /* fw mechanism */ | ||
2740 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2741 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2742 | halbtc8821a2ant_dec_bt_pwr(btcoexist, | ||
2743 | NORMAL_EXEC, true); | ||
2744 | } else { | ||
2745 | halbtc8821a2ant_dec_bt_pwr(btcoexist, | ||
2746 | NORMAL_EXEC, false); | ||
2747 | } | ||
2748 | |||
2749 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2750 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2751 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2752 | false, 1); | ||
2753 | } else { | ||
2754 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2755 | false, 1); | ||
2756 | } | ||
2757 | |||
2758 | /* sw mechanism */ | ||
2759 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2760 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2761 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2762 | false, false); | ||
2763 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2764 | false, 0x18); | ||
2765 | } else { | ||
2766 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2767 | false, false); | ||
2768 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2769 | false, 0x18); | ||
2770 | } | ||
2771 | } | ||
2772 | } | ||
2773 | |||
2774 | /* PAN(EDR)+A2DP */ | ||
2775 | static void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist) | ||
2776 | { | ||
2777 | u8 wifi_rssi_state, bt_rssi_state, bt_info_ext; | ||
2778 | u32 wifi_bw; | ||
2779 | |||
2780 | bt_info_ext = coex_sta->bt_info_ext; | ||
2781 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2782 | 15, 0); | ||
2783 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2784 | |||
2785 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2786 | |||
2787 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2788 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2789 | else | ||
2790 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2791 | |||
2792 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2793 | |||
2794 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2795 | /* for HID at 11b/g mode */ | ||
2796 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2797 | 0x5afa5afa, 0xffff, 0x3); | ||
2798 | } else { | ||
2799 | /* for HID quality & wifi performance balance at 11n mode */ | ||
2800 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2801 | 0x5afa5afa, 0xffff, 0x3); | ||
2802 | } | ||
2803 | |||
2804 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2805 | /* fw mechanism */ | ||
2806 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2807 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2808 | if (bt_info_ext&BIT0) { | ||
2809 | /* a2dp basic rate */ | ||
2810 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2811 | false, 3); | ||
2812 | } else { | ||
2813 | /* a2dp edr rate */ | ||
2814 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2815 | false, 3); | ||
2816 | } | ||
2817 | } else { | ||
2818 | if (bt_info_ext&BIT0) { | ||
2819 | /* a2dp basic rate */ | ||
2820 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2821 | true, 3); | ||
2822 | } else { | ||
2823 | /* a2dp edr rate */ | ||
2824 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2825 | true, 3); | ||
2826 | } | ||
2827 | } | ||
2828 | |||
2829 | /* sw mechanism */ | ||
2830 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2831 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2832 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2833 | false, false); | ||
2834 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2835 | false, 0x18); | ||
2836 | } else { | ||
2837 | btc8821a2ant_sw_mech1(btcoexist, true, false, | ||
2838 | false, false); | ||
2839 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2840 | false, 0x18); | ||
2841 | }; | ||
2842 | } else { | ||
2843 | /* fw mechanism */ | ||
2844 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2845 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2846 | if (bt_info_ext&BIT0) { | ||
2847 | /* a2dp basic rate */ | ||
2848 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2849 | false, 3); | ||
2850 | } else { | ||
2851 | /* a2dp edr rate */ | ||
2852 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2853 | false, 3); | ||
2854 | } | ||
2855 | } else { | ||
2856 | if (bt_info_ext&BIT0) { | ||
2857 | /* a2dp basic rate */ | ||
2858 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2859 | true, 3); | ||
2860 | } else { | ||
2861 | /* a2dp edr rate */ | ||
2862 | btc8821a2ant_tdma_dur_adj(btcoexist, false, | ||
2863 | true, 3); | ||
2864 | } | ||
2865 | } | ||
2866 | |||
2867 | /* sw mechanism */ | ||
2868 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2869 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2870 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2871 | false, false); | ||
2872 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2873 | false, 0x18); | ||
2874 | } else { | ||
2875 | btc8821a2ant_sw_mech1(btcoexist, false, false, | ||
2876 | false, false); | ||
2877 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2878 | false, 0x18); | ||
2879 | } | ||
2880 | } | ||
2881 | } | ||
2882 | |||
2883 | static void halbtc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist) | ||
2884 | { | ||
2885 | u8 wifi_rssi_state, bt_rssi_state; | ||
2886 | u32 wifi_bw; | ||
2887 | |||
2888 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
2889 | 15, 0); | ||
2890 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2891 | |||
2892 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2893 | |||
2894 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2895 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2896 | else | ||
2897 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2898 | |||
2899 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2900 | |||
2901 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2902 | /* for HID at 11b/g mode */ | ||
2903 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2904 | 0x5a5f5a5f, 0xffff, 0x3); | ||
2905 | } else { | ||
2906 | /* for HID quality & wifi performance balance at 11n mode */ | ||
2907 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2908 | 0x5a5f5a5f, 0xffff, 0x3); | ||
2909 | } | ||
2910 | |||
2911 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2912 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 3); | ||
2913 | /* fw mechanism */ | ||
2914 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2915 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2916 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2917 | true, 10); | ||
2918 | } else { | ||
2919 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2920 | true, 14); | ||
2921 | } | ||
2922 | |||
2923 | /* sw mechanism */ | ||
2924 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2925 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2926 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2927 | false, false); | ||
2928 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2929 | false, 0x18); | ||
2930 | } else { | ||
2931 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
2932 | false, false); | ||
2933 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2934 | false, 0x18); | ||
2935 | } | ||
2936 | } else { | ||
2937 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2938 | /* fw mechanism */ | ||
2939 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2940 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2941 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2942 | true, 10); | ||
2943 | } else { | ||
2944 | halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, | ||
2945 | true, 14); | ||
2946 | } | ||
2947 | |||
2948 | /* sw mechanism */ | ||
2949 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2950 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2951 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2952 | false, false); | ||
2953 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
2954 | false, 0x18); | ||
2955 | } else { | ||
2956 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
2957 | false, false); | ||
2958 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
2959 | false, 0x18); | ||
2960 | } | ||
2961 | } | ||
2962 | } | ||
2963 | |||
2964 | /* HID+A2DP+PAN(EDR) */ | ||
2965 | static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist) | ||
2966 | { | ||
2967 | u8 wifi_rssi_state, bt_rssi_state, bt_info_ext; | ||
2968 | u32 wifi_bw; | ||
2969 | |||
2970 | bt_info_ext = coex_sta->bt_info_ext; | ||
2971 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, | ||
2972 | 0, 2, 15, 0); | ||
2973 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
2974 | |||
2975 | halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6); | ||
2976 | |||
2977 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
2978 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
2979 | else | ||
2980 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
2981 | |||
2982 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
2983 | |||
2984 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
2985 | /* for HID at 11b/g mode */ | ||
2986 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2987 | 0x5a5a5a5a, 0xffff, 0x3); | ||
2988 | } else { | ||
2989 | /* for HID quality & wifi performance balance at 11n mode */ | ||
2990 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
2991 | 0x5a5a5a5a, 0xffff, 0x3); | ||
2992 | } | ||
2993 | |||
2994 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
2995 | /* fw mechanism */ | ||
2996 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
2997 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
2998 | if (bt_info_ext&BIT0) { | ||
2999 | /* a2dp basic rate */ | ||
3000 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3001 | true, 3); | ||
3002 | } else { | ||
3003 | /* a2dp edr rate */ | ||
3004 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3005 | true, 3); | ||
3006 | } | ||
3007 | } else { | ||
3008 | if (bt_info_ext&BIT0) { | ||
3009 | /* a2dp basic rate */ | ||
3010 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3011 | true, 3); | ||
3012 | } else { | ||
3013 | /* a2dp edr rate */ | ||
3014 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3015 | true, 3); | ||
3016 | } | ||
3017 | } | ||
3018 | |||
3019 | /* sw mechanism */ | ||
3020 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3021 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3022 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
3023 | false, false); | ||
3024 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
3025 | false, 0x18); | ||
3026 | } else { | ||
3027 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
3028 | false, false); | ||
3029 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
3030 | false, 0x18); | ||
3031 | } | ||
3032 | } else { | ||
3033 | /* fw mechanism */ | ||
3034 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3035 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3036 | if (bt_info_ext&BIT0) { | ||
3037 | /* a2dp basic rate */ | ||
3038 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3039 | false, 3); | ||
3040 | } else { | ||
3041 | /* a2dp edr rate */ | ||
3042 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3043 | false, 3); | ||
3044 | } | ||
3045 | } else { | ||
3046 | if (bt_info_ext&BIT0) { | ||
3047 | /* a2dp basic rate */ | ||
3048 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3049 | true, 3); | ||
3050 | } else { | ||
3051 | /* a2dp edr rate */ | ||
3052 | btc8821a2ant_tdma_dur_adj(btcoexist, true, | ||
3053 | true, 3); | ||
3054 | } | ||
3055 | } | ||
3056 | |||
3057 | /* sw mechanism */ | ||
3058 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3059 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3060 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
3061 | false, false); | ||
3062 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
3063 | false, 0x18); | ||
3064 | } else { | ||
3065 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
3066 | false, false); | ||
3067 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
3068 | false, 0x18); | ||
3069 | } | ||
3070 | } | ||
3071 | } | ||
3072 | |||
3073 | static void halbtc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist) | ||
3074 | { | ||
3075 | u8 wifi_rssi_state, bt_rssi_state, bt_info_ext; | ||
3076 | u32 wifi_bw; | ||
3077 | |||
3078 | bt_info_ext = coex_sta->bt_info_ext; | ||
3079 | wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, | ||
3080 | 15, 0); | ||
3081 | bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0); | ||
3082 | |||
3083 | if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist)) | ||
3084 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true); | ||
3085 | else | ||
3086 | halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false); | ||
3087 | |||
3088 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3089 | |||
3090 | if (BTC_WIFI_BW_LEGACY == wifi_bw) { | ||
3091 | /* for HID at 11b/g mode */ | ||
3092 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
3093 | 0x5f5b5f5b, 0xffffff, 0x3); | ||
3094 | } else { | ||
3095 | /*for HID quality & wifi performance balance at 11n mode*/ | ||
3096 | halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff, | ||
3097 | 0x5f5b5f5b, 0xffffff, 0x3); | ||
3098 | } | ||
3099 | |||
3100 | if (BTC_WIFI_BW_HT40 == wifi_bw) { | ||
3101 | /* fw mechanism */ | ||
3102 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3103 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3104 | if (bt_info_ext&BIT0) { | ||
3105 | /* a2dp basic rate */ | ||
3106 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3107 | true, true, 2); | ||
3108 | } else { | ||
3109 | /* a2dp edr rate */ | ||
3110 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3111 | true, true, 2); | ||
3112 | } | ||
3113 | } else { | ||
3114 | if (bt_info_ext&BIT0) { | ||
3115 | /* a2dp basic rate */ | ||
3116 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3117 | true, true, 2); | ||
3118 | } else { | ||
3119 | /* a2dp edr rate */ | ||
3120 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3121 | true, true, 2); | ||
3122 | } | ||
3123 | } | ||
3124 | |||
3125 | /* sw mechanism */ | ||
3126 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3127 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3128 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
3129 | false, false); | ||
3130 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
3131 | false, 0x18); | ||
3132 | } else { | ||
3133 | btc8821a2ant_sw_mech1(btcoexist, true, true, | ||
3134 | false, false); | ||
3135 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
3136 | false, 0x18); | ||
3137 | } | ||
3138 | } else { | ||
3139 | /* fw mechanism */ | ||
3140 | if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3141 | (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3142 | if (bt_info_ext&BIT0) { | ||
3143 | /* a2dp basic rate */ | ||
3144 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3145 | true, true, 2); | ||
3146 | |||
3147 | } else { | ||
3148 | /* a2dp edr rate */ | ||
3149 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3150 | true, true, 2); | ||
3151 | } | ||
3152 | } else { | ||
3153 | if (bt_info_ext&BIT0) { | ||
3154 | /*a2dp basic rate*/ | ||
3155 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3156 | true, true, 2); | ||
3157 | } else { | ||
3158 | /*a2dp edr rate*/ | ||
3159 | btc8821a2ant_tdma_dur_adj(btcoexist, | ||
3160 | true, true, 2); | ||
3161 | } | ||
3162 | } | ||
3163 | |||
3164 | /* sw mechanism */ | ||
3165 | if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) || | ||
3166 | (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) { | ||
3167 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
3168 | false, false); | ||
3169 | btc8821a2ant_sw_mech2(btcoexist, true, false, | ||
3170 | false, 0x18); | ||
3171 | } else { | ||
3172 | btc8821a2ant_sw_mech1(btcoexist, false, true, | ||
3173 | false, false); | ||
3174 | btc8821a2ant_sw_mech2(btcoexist, false, false, | ||
3175 | false, 0x18); | ||
3176 | } | ||
3177 | } | ||
3178 | } | ||
3179 | |||
3180 | static void halbtc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist) | ||
3181 | { | ||
3182 | bool wifi_under_5g = false; | ||
3183 | u8 algorithm = 0; | ||
3184 | |||
3185 | if (btcoexist->manual_control) { | ||
3186 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3187 | "[BTCoex], Manual control!!!\n"); | ||
3188 | return; | ||
3189 | } | ||
3190 | |||
3191 | btcoexist->btc_get(btcoexist, | ||
3192 | BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
3193 | |||
3194 | if (wifi_under_5g) { | ||
3195 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3196 | "[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n"); | ||
3197 | halbtc8821a2ant_coex_under_5g(btcoexist); | ||
3198 | return; | ||
3199 | } | ||
3200 | |||
3201 | algorithm = halbtc8821a2ant_action_algorithm(btcoexist); | ||
3202 | if (coex_sta->c2h_bt_inquiry_page && | ||
3203 | (BT_8821A_2ANT_COEX_ALGO_PANHS != algorithm)) { | ||
3204 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3205 | "[BTCoex], BT is under inquiry/page scan !!\n"); | ||
3206 | halbtc8821a2ant_bt_inquiry_page(btcoexist); | ||
3207 | return; | ||
3208 | } | ||
3209 | |||
3210 | coex_dm->cur_algorithm = algorithm; | ||
3211 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3212 | "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm); | ||
3213 | |||
3214 | if (halbtc8821a2ant_is_common_action(btcoexist)) { | ||
3215 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3216 | "[BTCoex], Action 2-Ant common.\n"); | ||
3217 | coex_dm->reset_tdma_adjust = true; | ||
3218 | } else { | ||
3219 | if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) { | ||
3220 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3221 | "[BTCoex], pre_algorithm = %d, cur_algorithm = %d\n", | ||
3222 | coex_dm->pre_algorithm, coex_dm->cur_algorithm); | ||
3223 | coex_dm->reset_tdma_adjust = true; | ||
3224 | } | ||
3225 | switch (coex_dm->cur_algorithm) { | ||
3226 | case BT_8821A_2ANT_COEX_ALGO_SCO: | ||
3227 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3228 | "[BTCoex], Action 2-Ant, algorithm = SCO.\n"); | ||
3229 | halbtc8821a2ant_action_sco(btcoexist); | ||
3230 | break; | ||
3231 | case BT_8821A_2ANT_COEX_ALGO_HID: | ||
3232 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3233 | "[BTCoex], Action 2-Ant, algorithm = HID.\n"); | ||
3234 | halbtc8821a2ant_action_hid(btcoexist); | ||
3235 | break; | ||
3236 | case BT_8821A_2ANT_COEX_ALGO_A2DP: | ||
3237 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3238 | "[BTCoex], Action 2-Ant, algorithm = A2DP.\n"); | ||
3239 | halbtc8821a2ant_action_a2dp(btcoexist); | ||
3240 | break; | ||
3241 | case BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS: | ||
3242 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3243 | "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n"); | ||
3244 | halbtc8821a2ant_action_a2dp_pan_hs(btcoexist); | ||
3245 | break; | ||
3246 | case BT_8821A_2ANT_COEX_ALGO_PANEDR: | ||
3247 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3248 | "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n"); | ||
3249 | halbtc8821a2ant_action_pan_edr(btcoexist); | ||
3250 | break; | ||
3251 | case BT_8821A_2ANT_COEX_ALGO_PANHS: | ||
3252 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3253 | "[BTCoex], Action 2-Ant, algorithm = HS mode.\n"); | ||
3254 | halbtc8821a2ant_action_pan_hs(btcoexist); | ||
3255 | break; | ||
3256 | case BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP: | ||
3257 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3258 | "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n"); | ||
3259 | halbtc8821a2ant_action_pan_edr_a2dp(btcoexist); | ||
3260 | break; | ||
3261 | case BT_8821A_2ANT_COEX_ALGO_PANEDR_HID: | ||
3262 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3263 | "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n"); | ||
3264 | halbtc8821a2ant_action_pan_edr_hid(btcoexist); | ||
3265 | break; | ||
3266 | case BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR: | ||
3267 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3268 | "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n"); | ||
3269 | btc8821a2ant_act_hid_a2dp_pan_edr(btcoexist); | ||
3270 | break; | ||
3271 | case BT_8821A_2ANT_COEX_ALGO_HID_A2DP: | ||
3272 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3273 | "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n"); | ||
3274 | halbtc8821a2ant_action_hid_a2dp(btcoexist); | ||
3275 | break; | ||
3276 | default: | ||
3277 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3278 | "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n"); | ||
3279 | halbtc8821a2ant_coex_all_off(btcoexist); | ||
3280 | break; | ||
3281 | } | ||
3282 | coex_dm->pre_algorithm = coex_dm->cur_algorithm; | ||
3283 | } | ||
3284 | } | ||
3285 | |||
3286 | /*============================================================ | ||
3287 | *work around function start with wa_halbtc8821a2ant_ | ||
3288 | *============================================================ | ||
3289 | *============================================================ | ||
3290 | * extern function start with EXhalbtc8821a2ant_ | ||
3291 | *============================================================ | ||
3292 | */ | ||
3293 | void ex_halbtc8821a2ant_init_hwconfig(struct btc_coexist *btcoexist) | ||
3294 | { | ||
3295 | u8 u1tmp = 0; | ||
3296 | |||
3297 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3298 | "[BTCoex], 2Ant Init HW Config!!\n"); | ||
3299 | |||
3300 | /* backup rf 0x1e value */ | ||
3301 | coex_dm->bt_rf0x1e_backup = | ||
3302 | btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff); | ||
3303 | |||
3304 | /* 0x790[5:0] = 0x5 */ | ||
3305 | u1tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); | ||
3306 | u1tmp &= 0xc0; | ||
3307 | u1tmp |= 0x5; | ||
3308 | btcoexist->btc_write_1byte(btcoexist, 0x790, u1tmp); | ||
3309 | |||
3310 | /*Antenna config */ | ||
3311 | halbtc8821a2ant_set_ant_path(btcoexist, | ||
3312 | BTC_ANT_WIFI_AT_MAIN, true, false); | ||
3313 | |||
3314 | /* PTA parameter */ | ||
3315 | halbtc8821a2ant_coex_table(btcoexist, | ||
3316 | FORCE_EXEC, 0x55555555, 0x55555555, | ||
3317 | 0xffff, 0x3); | ||
3318 | |||
3319 | /* Enable counter statistics */ | ||
3320 | /*0x76e[3] = 1, WLAN_Act control by PTA*/ | ||
3321 | btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); | ||
3322 | btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3); | ||
3323 | btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); | ||
3324 | } | ||
3325 | |||
3326 | void | ||
3327 | ex_halbtc8821a2ant_init_coex_dm( | ||
3328 | struct btc_coexist *btcoexist | ||
3329 | ) | ||
3330 | { | ||
3331 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3332 | "[BTCoex], Coex Mechanism Init!!\n"); | ||
3333 | |||
3334 | halbtc8821a2ant_init_coex_dm(btcoexist); | ||
3335 | } | ||
3336 | |||
3337 | void | ||
3338 | ex_halbtc8821a2ant_display_coex_info( | ||
3339 | struct btc_coexist *btcoexist | ||
3340 | ) | ||
3341 | { | ||
3342 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
3343 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
3344 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
3345 | u8 u1tmp[4], i, bt_info_ext, ps_tdma_case = 0; | ||
3346 | u32 u4tmp[4]; | ||
3347 | bool roam = false, scan = false, link = false, wifi_under_5g = false; | ||
3348 | bool bt_hs_on = false, wifi_busy = false; | ||
3349 | long wifi_rssi = 0, bt_hs_rssi = 0; | ||
3350 | u32 wifi_bw, wifi_traffic_dir; | ||
3351 | u8 wifi_dot_11_chnl, wifi_hs_chnl; | ||
3352 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
3353 | |||
3354 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3355 | "\r\n ============[BT Coexist info]============"); | ||
3356 | |||
3357 | if (!board_info->bt_exist) { | ||
3358 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!"); | ||
3359 | return; | ||
3360 | } | ||
3361 | |||
3362 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3363 | "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", | ||
3364 | board_info->pg_ant_num, board_info->btdm_ant_num); | ||
3365 | |||
3366 | if (btcoexist->manual_control) { | ||
3367 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3368 | "\r\n %-35s", "[Action Manual control]!!"); | ||
3369 | } | ||
3370 | |||
3371 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3372 | "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", | ||
3373 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
3374 | stack_info->hci_version); | ||
3375 | |||
3376 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); | ||
3377 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
3378 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3379 | "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", | ||
3380 | "CoexVer/ FwVer/ PatchVer", | ||
3381 | glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant, | ||
3382 | fw_ver, bt_patch_ver, bt_patch_ver); | ||
3383 | |||
3384 | btcoexist->btc_get(btcoexist, | ||
3385 | BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
3386 | btcoexist->btc_get(btcoexist, | ||
3387 | BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_dot_11_chnl); | ||
3388 | btcoexist->btc_get(btcoexist, | ||
3389 | BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); | ||
3390 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3391 | "\r\n %-35s = %d / %d(%d)", | ||
3392 | "Dot11 channel / HsMode(HsChnl)", | ||
3393 | wifi_dot_11_chnl, bt_hs_on, wifi_hs_chnl); | ||
3394 | |||
3395 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3396 | "\r\n %-35s = %02x %02x %02x ", | ||
3397 | "H2C Wifi inform bt chnl Info", | ||
3398 | coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1], | ||
3399 | coex_dm->wifi_chnl_info[2]); | ||
3400 | |||
3401 | btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); | ||
3402 | btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); | ||
3403 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3404 | "\r\n %-35s = %ld/ %ld", "Wifi rssi/ HS rssi", | ||
3405 | wifi_rssi, bt_hs_rssi); | ||
3406 | |||
3407 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); | ||
3408 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); | ||
3409 | btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); | ||
3410 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3411 | "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan", | ||
3412 | link, roam, scan); | ||
3413 | |||
3414 | btcoexist->btc_get(btcoexist, | ||
3415 | BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); | ||
3416 | btcoexist->btc_get(btcoexist, | ||
3417 | BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3418 | btcoexist->btc_get(btcoexist, | ||
3419 | BTC_GET_BL_WIFI_BUSY, &wifi_busy); | ||
3420 | btcoexist->btc_get(btcoexist, | ||
3421 | BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifi_traffic_dir); | ||
3422 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3423 | "\r\n %-35s = %s / %s/ %s ", "Wifi status", | ||
3424 | (wifi_under_5g ? "5G" : "2.4G"), | ||
3425 | ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : | ||
3426 | (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), | ||
3427 | ((!wifi_busy) ? "idle" : | ||
3428 | ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? | ||
3429 | "uplink" : "downlink"))); | ||
3430 | |||
3431 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3432 | "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", | ||
3433 | ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") : | ||
3434 | ((BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status) | ||
3435 | ? "idle" : ((BT_8821A_2ANT_BT_STATUS_CON_IDLE == | ||
3436 | coex_dm->bt_status) ? "connected-idle" : "busy"))), | ||
3437 | coex_sta->bt_rssi, coex_sta->bt_retry_cnt); | ||
3438 | |||
3439 | if (stack_info->profile_notified) { | ||
3440 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3441 | "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", | ||
3442 | stack_info->sco_exist, stack_info->hid_exist, | ||
3443 | stack_info->pan_exist, stack_info->a2dp_exist); | ||
3444 | |||
3445 | btcoexist->btc_disp_dbg_msg(btcoexist, | ||
3446 | BTC_DBG_DISP_BT_LINK_INFO); | ||
3447 | } | ||
3448 | |||
3449 | bt_info_ext = coex_sta->bt_info_ext; | ||
3450 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s", | ||
3451 | "BT Info A2DP rate", | ||
3452 | (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); | ||
3453 | |||
3454 | for (i = 0; i < BT_INFO_SRC_8821A_2ANT_MAX; i++) { | ||
3455 | if (coex_sta->bt_info_c2h_cnt[i]) { | ||
3456 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3457 | "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", | ||
3458 | glbt_info_src_8821a_2ant[i], | ||
3459 | coex_sta->bt_info_c2h[i][0], | ||
3460 | coex_sta->bt_info_c2h[i][1], | ||
3461 | coex_sta->bt_info_c2h[i][2], | ||
3462 | coex_sta->bt_info_c2h[i][3], | ||
3463 | coex_sta->bt_info_c2h[i][4], | ||
3464 | coex_sta->bt_info_c2h[i][5], | ||
3465 | coex_sta->bt_info_c2h[i][6], | ||
3466 | coex_sta->bt_info_c2h_cnt[i]); | ||
3467 | } | ||
3468 | } | ||
3469 | |||
3470 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s", | ||
3471 | "PS state, IPS/LPS", | ||
3472 | ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), | ||
3473 | ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); | ||
3474 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); | ||
3475 | |||
3476 | /* Sw mechanism*/ | ||
3477 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
3478 | "============[Sw mechanism]============"); | ||
3479 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3480 | "\r\n %-35s = %d/ %d/ %d/ %d ", | ||
3481 | "SM1[ShRf/ LpRA/ LimDig/ btLna]", | ||
3482 | coex_dm->cur_rf_rx_lpf_shrink, coex_dm->cur_low_penalty_ra, | ||
3483 | coex_dm->limited_dig, coex_dm->cur_bt_lna_constrain); | ||
3484 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3485 | "\r\n %-35s = %d/ %d/ %d(0x%x) ", | ||
3486 | "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", | ||
3487 | coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, | ||
3488 | coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); | ||
3489 | |||
3490 | /* Fw mechanism*/ | ||
3491 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s", | ||
3492 | "============[Fw mechanism]============"); | ||
3493 | |||
3494 | if (!btcoexist->manual_control) { | ||
3495 | ps_tdma_case = coex_dm->cur_ps_tdma; | ||
3496 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3497 | "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", | ||
3498 | "PS TDMA", | ||
3499 | coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1], | ||
3500 | coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3], | ||
3501 | coex_dm->ps_tdma_para[4], ps_tdma_case); | ||
3502 | |||
3503 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3504 | "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", | ||
3505 | coex_dm->cur_dec_bt_pwr, | ||
3506 | coex_dm->cur_ignore_wlan_act); | ||
3507 | } | ||
3508 | |||
3509 | /* Hw setting*/ | ||
3510 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3511 | "\r\n %-35s", "============[Hw setting]============"); | ||
3512 | |||
3513 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, | ||
3514 | "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", | ||
3515 | coex_dm->bt_rf0x1e_backup); | ||
3516 | |||
3517 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); | ||
3518 | u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); | ||
3519 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x ", | ||
3520 | "0x778 (W_Act)/ 0x6cc (CoTab Sel)", | ||
3521 | u1tmp[0], u1tmp[1]); | ||
3522 | |||
3523 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db); | ||
3524 | u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xc5b); | ||
3525 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3526 | "0x8db(ADC)/0xc5b[29:25](DAC)", | ||
3527 | ((u1tmp[0]&0x60)>>5), ((u1tmp[1]&0x3e)>>1)); | ||
3528 | |||
3529 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4); | ||
3530 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3531 | "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)", | ||
3532 | u4tmp[0]&0xff, ((u4tmp[0]&0x30000000)>>28)); | ||
3533 | |||
3534 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40); | ||
3535 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); | ||
3536 | u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x974); | ||
3537 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
3538 | "0x40/ 0x4c[24:23]/ 0x974", | ||
3539 | u1tmp[0], ((u4tmp[0]&0x01800000)>>23), u4tmp[1]); | ||
3540 | |||
3541 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); | ||
3542 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); | ||
3543 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3544 | "0x550(bcn ctrl)/0x522", | ||
3545 | u4tmp[0], u1tmp[0]); | ||
3546 | |||
3547 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); | ||
3548 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa0a); | ||
3549 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3550 | "0xc50(DIG)/0xa0a(CCK-TH)", | ||
3551 | u4tmp[0], u1tmp[0]); | ||
3552 | |||
3553 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48); | ||
3554 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b); | ||
3555 | u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c); | ||
3556 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x", | ||
3557 | "OFDM-FA/ CCK-FA", | ||
3558 | u4tmp[0], (u1tmp[0]<<8) + u1tmp[1]); | ||
3559 | |||
3560 | u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); | ||
3561 | u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); | ||
3562 | u4tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); | ||
3563 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", | ||
3564 | "0x6c0/0x6c4/0x6c8", | ||
3565 | u4tmp[0], u4tmp[1], u4tmp[2]); | ||
3566 | |||
3567 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
3568 | "0x770 (hi-pri Rx/Tx)", | ||
3569 | coex_sta->high_priority_rx, coex_sta->high_priority_tx); | ||
3570 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d", | ||
3571 | "0x774(low-pri Rx/Tx)", | ||
3572 | coex_sta->low_priority_rx, coex_sta->low_priority_tx); | ||
3573 | |||
3574 | /* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang*/ | ||
3575 | u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x41b); | ||
3576 | RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", | ||
3577 | "0x41b (mgntQ hang chk == 0xf)", | ||
3578 | u1tmp[0]); | ||
3579 | |||
3580 | btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS); | ||
3581 | } | ||
3582 | |||
3583 | void ex_halbtc8821a2ant_ips_notify(struct btc_coexist *btcoexist, u8 type) | ||
3584 | { | ||
3585 | if (BTC_IPS_ENTER == type) { | ||
3586 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3587 | "[BTCoex], IPS ENTER notify\n"); | ||
3588 | coex_sta->under_ips = true; | ||
3589 | halbtc8821a2ant_coex_all_off(btcoexist); | ||
3590 | } else if (BTC_IPS_LEAVE == type) { | ||
3591 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3592 | "[BTCoex], IPS LEAVE notify\n"); | ||
3593 | coex_sta->under_ips = false; | ||
3594 | /*halbtc8821a2ant_init_coex_dm(btcoexist);*/ | ||
3595 | } | ||
3596 | } | ||
3597 | |||
3598 | void ex_halbtc8821a2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) | ||
3599 | { | ||
3600 | if (BTC_LPS_ENABLE == type) { | ||
3601 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3602 | "[BTCoex], LPS ENABLE notify\n"); | ||
3603 | coex_sta->under_lps = true; | ||
3604 | } else if (BTC_LPS_DISABLE == type) { | ||
3605 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3606 | "[BTCoex], LPS DISABLE notify\n"); | ||
3607 | coex_sta->under_lps = false; | ||
3608 | } | ||
3609 | } | ||
3610 | |||
3611 | void ex_halbtc8821a2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) | ||
3612 | { | ||
3613 | if (BTC_SCAN_START == type) { | ||
3614 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3615 | "[BTCoex], SCAN START notify\n"); | ||
3616 | } else if (BTC_SCAN_FINISH == type) { | ||
3617 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3618 | "[BTCoex], SCAN FINISH notify\n"); | ||
3619 | } | ||
3620 | } | ||
3621 | |||
3622 | void ex_halbtc8821a2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) | ||
3623 | { | ||
3624 | if (BTC_ASSOCIATE_START == type) { | ||
3625 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3626 | "[BTCoex], CONNECT START notify\n"); | ||
3627 | } else if (BTC_ASSOCIATE_FINISH == type) { | ||
3628 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3629 | "[BTCoex], CONNECT FINISH notify\n"); | ||
3630 | } | ||
3631 | } | ||
3632 | |||
3633 | void ex_halbtc8821a2ant_media_status_notify(struct btc_coexist *btcoexist, | ||
3634 | u8 type) | ||
3635 | { | ||
3636 | u8 h2c_parameter[3] = {0}; | ||
3637 | u32 wifi_bw; | ||
3638 | u8 wifi_central_chnl; | ||
3639 | |||
3640 | if (BTC_MEDIA_CONNECT == type) { | ||
3641 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3642 | "[BTCoex], MEDIA connect notify\n"); | ||
3643 | } else { | ||
3644 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3645 | "[BTCoex], MEDIA disconnect notify\n"); | ||
3646 | } | ||
3647 | |||
3648 | /* only 2.4G we need to inform bt the chnl mask*/ | ||
3649 | btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, | ||
3650 | &wifi_central_chnl); | ||
3651 | if ((BTC_MEDIA_CONNECT == type) && | ||
3652 | (wifi_central_chnl <= 14)) { | ||
3653 | h2c_parameter[0] = 0x1; | ||
3654 | h2c_parameter[1] = wifi_central_chnl; | ||
3655 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); | ||
3656 | if (BTC_WIFI_BW_HT40 == wifi_bw) | ||
3657 | h2c_parameter[2] = 0x30; | ||
3658 | else | ||
3659 | h2c_parameter[2] = 0x20; | ||
3660 | } | ||
3661 | |||
3662 | coex_dm->wifi_chnl_info[0] = h2c_parameter[0]; | ||
3663 | coex_dm->wifi_chnl_info[1] = h2c_parameter[1]; | ||
3664 | coex_dm->wifi_chnl_info[2] = h2c_parameter[2]; | ||
3665 | |||
3666 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, | ||
3667 | "[BTCoex], FW write 0x66 = 0x%x\n", | ||
3668 | h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]); | ||
3669 | |||
3670 | btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); | ||
3671 | } | ||
3672 | |||
3673 | void ex_halbtc8821a2ant_special_packet_notify(struct btc_coexist *btcoexist, | ||
3674 | u8 type) { | ||
3675 | if (type == BTC_PACKET_DHCP) { | ||
3676 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3677 | "[BTCoex], DHCP Packet notify\n"); | ||
3678 | } | ||
3679 | } | ||
3680 | |||
3681 | void ex_halbtc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist, | ||
3682 | u8 *tmp_buf, u8 length) | ||
3683 | { | ||
3684 | u8 bt_info = 0; | ||
3685 | u8 i, rsp_source = 0; | ||
3686 | static u32 set_bt_lna_cnt, set_bt_psd_mode; | ||
3687 | bool bt_busy = false, limited_dig = false; | ||
3688 | bool wifi_connected = false, bt_hs_on = false; | ||
3689 | |||
3690 | coex_sta->c2h_bt_info_req_sent = false; | ||
3691 | |||
3692 | rsp_source = tmp_buf[0]&0xf; | ||
3693 | if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX) | ||
3694 | rsp_source = BT_INFO_SRC_8821A_2ANT_WIFI_FW; | ||
3695 | coex_sta->bt_info_c2h_cnt[rsp_source]++; | ||
3696 | |||
3697 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3698 | "[BTCoex], Bt info[%d], length = %d, hex data = [", | ||
3699 | rsp_source, length); | ||
3700 | for (i = 0; i < length; i++) { | ||
3701 | coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i]; | ||
3702 | if (i == 1) | ||
3703 | bt_info = tmp_buf[i]; | ||
3704 | if (i == length-1) { | ||
3705 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3706 | "0x%02x]\n", tmp_buf[i]); | ||
3707 | } else { | ||
3708 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3709 | "0x%02x, ", tmp_buf[i]); | ||
3710 | } | ||
3711 | } | ||
3712 | |||
3713 | if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) { | ||
3714 | coex_sta->bt_retry_cnt = /* [3:0]*/ | ||
3715 | coex_sta->bt_info_c2h[rsp_source][2]&0xf; | ||
3716 | |||
3717 | coex_sta->bt_rssi = | ||
3718 | coex_sta->bt_info_c2h[rsp_source][3]*2+10; | ||
3719 | |||
3720 | coex_sta->bt_info_ext = | ||
3721 | coex_sta->bt_info_c2h[rsp_source][4]; | ||
3722 | |||
3723 | /* Here we need to resend some wifi info to BT*/ | ||
3724 | /* because bt is reset and loss of the info.*/ | ||
3725 | if ((coex_sta->bt_info_ext & BIT1)) { | ||
3726 | btcoexist->btc_get(btcoexist, | ||
3727 | BTC_GET_BL_WIFI_CONNECTED, &wifi_connected); | ||
3728 | if (wifi_connected) { | ||
3729 | ex_halbtc8821a2ant_media_status_notify(btcoexist, | ||
3730 | BTC_MEDIA_CONNECT); | ||
3731 | } else { | ||
3732 | ex_halbtc8821a2ant_media_status_notify(btcoexist, | ||
3733 | BTC_MEDIA_DISCONNECT); | ||
3734 | } | ||
3735 | |||
3736 | set_bt_psd_mode = 0; | ||
3737 | } | ||
3738 | if (set_bt_psd_mode <= 3) { | ||
3739 | halbtc8821a2ant_set_bt_psd_mode(btcoexist, FORCE_EXEC, | ||
3740 | 0x0); /*fix CH-BW mode*/ | ||
3741 | set_bt_psd_mode++; | ||
3742 | } | ||
3743 | |||
3744 | if (coex_dm->cur_bt_lna_constrain) { | ||
3745 | if (!(coex_sta->bt_info_ext & BIT2)) { | ||
3746 | if (set_bt_lna_cnt <= 3) { | ||
3747 | btc8821a2_set_bt_lna_const(btcoexist, | ||
3748 | FORCE_EXEC, | ||
3749 | true); | ||
3750 | set_bt_lna_cnt++; | ||
3751 | } | ||
3752 | } | ||
3753 | } else { | ||
3754 | set_bt_lna_cnt = 0; | ||
3755 | } | ||
3756 | |||
3757 | if ((coex_sta->bt_info_ext & BIT3)) { | ||
3758 | halbtc8821a2ant_ignore_wlan_act(btcoexist, | ||
3759 | FORCE_EXEC, false); | ||
3760 | } else { | ||
3761 | /* BT already NOT ignore Wlan active, do nothing here.*/ | ||
3762 | } | ||
3763 | |||
3764 | if ((coex_sta->bt_info_ext & BIT4)) { | ||
3765 | /* BT auto report already enabled, do nothing*/ | ||
3766 | } else { | ||
3767 | halbtc8821a2ant_bt_auto_report(btcoexist, | ||
3768 | FORCE_EXEC, true); | ||
3769 | } | ||
3770 | } | ||
3771 | |||
3772 | btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); | ||
3773 | /* check BIT2 first ==> check if bt is under inquiry or page scan*/ | ||
3774 | if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) { | ||
3775 | coex_sta->c2h_bt_inquiry_page = true; | ||
3776 | coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE; | ||
3777 | } else { | ||
3778 | coex_sta->c2h_bt_inquiry_page = false; | ||
3779 | if (bt_info == 0x1) { | ||
3780 | /* connection exists but not busy*/ | ||
3781 | coex_sta->bt_link_exist = true; | ||
3782 | coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE; | ||
3783 | } else if (bt_info & BT_INFO_8821A_2ANT_B_CONNECTION) { | ||
3784 | /* connection exists and some link is busy*/ | ||
3785 | coex_sta->bt_link_exist = true; | ||
3786 | if (bt_info & BT_INFO_8821A_2ANT_B_FTP) | ||
3787 | coex_sta->pan_exist = true; | ||
3788 | else | ||
3789 | coex_sta->pan_exist = false; | ||
3790 | if (bt_info & BT_INFO_8821A_2ANT_B_A2DP) | ||
3791 | coex_sta->a2dp_exist = true; | ||
3792 | else | ||
3793 | coex_sta->a2dp_exist = false; | ||
3794 | if (bt_info & BT_INFO_8821A_2ANT_B_HID) | ||
3795 | coex_sta->hid_exist = true; | ||
3796 | else | ||
3797 | coex_sta->hid_exist = false; | ||
3798 | if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO) | ||
3799 | coex_sta->sco_exist = true; | ||
3800 | else | ||
3801 | coex_sta->sco_exist = false; | ||
3802 | coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE; | ||
3803 | } else { | ||
3804 | coex_sta->bt_link_exist = false; | ||
3805 | coex_sta->pan_exist = false; | ||
3806 | coex_sta->a2dp_exist = false; | ||
3807 | coex_sta->hid_exist = false; | ||
3808 | coex_sta->sco_exist = false; | ||
3809 | coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE; | ||
3810 | } | ||
3811 | |||
3812 | if (bt_hs_on) | ||
3813 | coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE; | ||
3814 | } | ||
3815 | |||
3816 | if (BT_8821A_2ANT_BT_STATUS_NON_IDLE == coex_dm->bt_status) | ||
3817 | bt_busy = true; | ||
3818 | else | ||
3819 | bt_busy = false; | ||
3820 | btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy); | ||
3821 | |||
3822 | if (BT_8821A_2ANT_BT_STATUS_IDLE != coex_dm->bt_status) | ||
3823 | limited_dig = true; | ||
3824 | else | ||
3825 | limited_dig = false; | ||
3826 | coex_dm->limited_dig = limited_dig; | ||
3827 | btcoexist->btc_set(btcoexist, | ||
3828 | BTC_SET_BL_BT_LIMITED_DIG, &limited_dig); | ||
3829 | |||
3830 | halbtc8821a2ant_run_coexist_mechanism(btcoexist); | ||
3831 | } | ||
3832 | |||
3833 | void ex_halbtc8821a2ant_halt_notify(struct btc_coexist *btcoexist) | ||
3834 | { | ||
3835 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, | ||
3836 | "[BTCoex], Halt notify\n"); | ||
3837 | |||
3838 | halbtc8821a2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); | ||
3839 | ex_halbtc8821a2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT); | ||
3840 | } | ||
3841 | |||
3842 | void ex_halbtc8821a2ant_periodical(struct btc_coexist *btcoexist) | ||
3843 | { | ||
3844 | static u8 dis_ver_info_cnt; | ||
3845 | u32 fw_ver = 0, bt_patch_ver = 0; | ||
3846 | struct btc_board_info *board_info = &btcoexist->board_info; | ||
3847 | struct btc_stack_info *stack_info = &btcoexist->stack_info; | ||
3848 | |||
3849 | BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, | ||
3850 | "[BTCoex], ==========================Periodical===========================\n"); | ||
3851 | |||
3852 | if (dis_ver_info_cnt <= 5) { | ||
3853 | dis_ver_info_cnt += 1; | ||
3854 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3855 | "[BTCoex], ****************************************************************\n"); | ||
3856 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3857 | "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", | ||
3858 | board_info->pg_ant_num, | ||
3859 | board_info->btdm_ant_num, | ||
3860 | board_info->btdm_ant_pos); | ||
3861 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3862 | "[BTCoex], BT stack/ hci ext ver = %s / %d\n", | ||
3863 | ((stack_info->profile_notified) ? "Yes" : "No"), | ||
3864 | stack_info->hci_version); | ||
3865 | btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, | ||
3866 | &bt_patch_ver); | ||
3867 | btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); | ||
3868 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3869 | "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", | ||
3870 | glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant, | ||
3871 | fw_ver, bt_patch_ver, bt_patch_ver); | ||
3872 | BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, | ||
3873 | "[BTCoex], ****************************************************************\n"); | ||
3874 | } | ||
3875 | |||
3876 | halbtc8821a2ant_query_bt_info(btcoexist); | ||
3877 | halbtc8821a2ant_monitor_bt_ctr(btcoexist); | ||
3878 | btc8821a2ant_mon_bt_en_dis(btcoexist); | ||
3879 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h new file mode 100644 index 000000000000..b4cf1f53d510 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h | |||
@@ -0,0 +1,205 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2012 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * The full GNU General Public License is included in this distribution in the | ||
15 | * file called LICENSE. | ||
16 | * | ||
17 | * Contact Information: | ||
18 | * wlanfae <wlanfae@realtek.com> | ||
19 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
20 | * Hsinchu 300, Taiwan. | ||
21 | * | ||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
23 | * | ||
24 | *****************************************************************************/ | ||
25 | |||
26 | /*=========================================== | ||
27 | * The following is for 8821A 2Ant BT Co-exist definition | ||
28 | *=========================================== | ||
29 | */ | ||
30 | #define BT_INFO_8821A_2ANT_B_FTP BIT7 | ||
31 | #define BT_INFO_8821A_2ANT_B_A2DP BIT6 | ||
32 | #define BT_INFO_8821A_2ANT_B_HID BIT5 | ||
33 | #define BT_INFO_8821A_2ANT_B_SCO_BUSY BIT4 | ||
34 | #define BT_INFO_8821A_2ANT_B_ACL_BUSY BIT3 | ||
35 | #define BT_INFO_8821A_2ANT_B_INQ_PAGE BIT2 | ||
36 | #define BT_INFO_8821A_2ANT_B_SCO_ESCO BIT1 | ||
37 | #define BT_INFO_8821A_2ANT_B_CONNECTION BIT0 | ||
38 | |||
39 | #define BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT 2 | ||
40 | |||
41 | enum _BT_INFO_SRC_8821A_2ANT { | ||
42 | BT_INFO_SRC_8821A_2ANT_WIFI_FW = 0x0, | ||
43 | BT_INFO_SRC_8821A_2ANT_BT_RSP = 0x1, | ||
44 | BT_INFO_SRC_8821A_2ANT_BT_ACTIVE_SEND = 0x2, | ||
45 | BT_INFO_SRC_8821A_2ANT_MAX | ||
46 | }; | ||
47 | |||
48 | enum _BT_8821A_2ANT_BT_STATUS { | ||
49 | BT_8821A_2ANT_BT_STATUS_IDLE = 0x0, | ||
50 | BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1, | ||
51 | BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2, | ||
52 | BT_8821A_2ANT_BT_STATUS_MAX | ||
53 | }; | ||
54 | |||
55 | enum _BT_8821A_2ANT_COEX_ALGO { | ||
56 | BT_8821A_2ANT_COEX_ALGO_UNDEFINED = 0x0, | ||
57 | BT_8821A_2ANT_COEX_ALGO_SCO = 0x1, | ||
58 | BT_8821A_2ANT_COEX_ALGO_HID = 0x2, | ||
59 | BT_8821A_2ANT_COEX_ALGO_A2DP = 0x3, | ||
60 | BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS = 0x4, | ||
61 | BT_8821A_2ANT_COEX_ALGO_PANEDR = 0x5, | ||
62 | BT_8821A_2ANT_COEX_ALGO_PANHS = 0x6, | ||
63 | BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7, | ||
64 | BT_8821A_2ANT_COEX_ALGO_PANEDR_HID = 0x8, | ||
65 | BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9, | ||
66 | BT_8821A_2ANT_COEX_ALGO_HID_A2DP = 0xa, | ||
67 | BT_8821A_2ANT_COEX_ALGO_MAX = 0xb, | ||
68 | }; | ||
69 | |||
70 | struct coex_dm_8821a_2ant { | ||
71 | /* fw mechanism */ | ||
72 | bool pre_dec_bt_pwr; | ||
73 | bool cur_dec_bt_pwr; | ||
74 | bool pre_bt_lna_constrain; | ||
75 | bool cur_bt_lna_constrain; | ||
76 | u8 pre_bt_psd_mode; | ||
77 | u8 cur_bt_psd_mode; | ||
78 | u8 pre_fw_dac_swing_lvl; | ||
79 | u8 cur_fw_dac_swing_lvl; | ||
80 | bool cur_ignore_wlan_act; | ||
81 | bool pre_ignore_wlan_act; | ||
82 | u8 pre_ps_tdma; | ||
83 | u8 cur_ps_tdma; | ||
84 | u8 ps_tdma_para[5]; | ||
85 | u8 tdma_adj_type; | ||
86 | bool reset_tdma_adjust; | ||
87 | bool pre_ps_tdma_on; | ||
88 | bool cur_ps_tdma_on; | ||
89 | bool pre_bt_auto_report; | ||
90 | bool cur_bt_auto_report; | ||
91 | |||
92 | /* sw mechanism */ | ||
93 | bool pre_rf_rx_lpf_shrink; | ||
94 | bool cur_rf_rx_lpf_shrink; | ||
95 | u32 bt_rf0x1e_backup; | ||
96 | bool pre_low_penalty_ra; | ||
97 | bool cur_low_penalty_ra; | ||
98 | bool pre_dac_swing_on; | ||
99 | u32 pre_dac_swing_lvl; | ||
100 | bool cur_dac_swing_on; | ||
101 | u32 cur_dac_swing_lvl; | ||
102 | bool pre_adc_back_off; | ||
103 | bool cur_adc_back_off; | ||
104 | bool pre_agc_table_en; | ||
105 | bool cur_agc_table_en; | ||
106 | u32 pre_val0x6c0; | ||
107 | u32 cur_val0x6c0; | ||
108 | u32 pre_val0x6c4; | ||
109 | u32 cur_val0x6c4; | ||
110 | u32 pre_val0x6c8; | ||
111 | u32 cur_val0x6c8; | ||
112 | u8 pre_val0x6cc; | ||
113 | u8 cur_val0x6cc; | ||
114 | bool limited_dig; | ||
115 | |||
116 | /* algorithm related */ | ||
117 | u8 pre_algorithm; | ||
118 | u8 cur_algorithm; | ||
119 | u8 bt_status; | ||
120 | u8 wifi_chnl_info[3]; | ||
121 | }; | ||
122 | |||
123 | struct coex_sta_8821a_2ant { | ||
124 | bool bt_link_exist; | ||
125 | bool sco_exist; | ||
126 | bool a2dp_exist; | ||
127 | bool hid_exist; | ||
128 | bool pan_exist; | ||
129 | bool under_lps; | ||
130 | bool under_ips; | ||
131 | u32 high_priority_tx; | ||
132 | u32 high_priority_rx; | ||
133 | u32 low_priority_tx; | ||
134 | u32 low_priority_rx; | ||
135 | u8 bt_rssi; | ||
136 | u8 pre_bt_rssi_state; | ||
137 | u8 pre_wifi_rssi_state[4]; | ||
138 | bool c2h_bt_info_req_sent; | ||
139 | u8 bt_info_c2h[BT_INFO_SRC_8821A_2ANT_MAX][10]; | ||
140 | u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_2ANT_MAX]; | ||
141 | bool c2h_bt_inquiry_page; | ||
142 | u8 bt_retry_cnt; | ||
143 | u8 bt_info_ext; | ||
144 | }; | ||
145 | |||
146 | /*=========================================== | ||
147 | * The following is interface which will notify coex module. | ||
148 | *=========================================== | ||
149 | */ | ||
150 | void | ||
151 | ex_halbtc8821a2ant_init_hwconfig( | ||
152 | struct btc_coexist *btcoexist | ||
153 | ); | ||
154 | void | ||
155 | ex_halbtc8821a2ant_init_coex_dm( | ||
156 | struct btc_coexist *btcoexist | ||
157 | ); | ||
158 | void | ||
159 | ex_halbtc8821a2ant_ips_notify( | ||
160 | struct btc_coexist *btcoexist, | ||
161 | u8 type | ||
162 | ); | ||
163 | void | ||
164 | ex_halbtc8821a2ant_lps_notify( | ||
165 | struct btc_coexist *btcoexist, | ||
166 | u8 type | ||
167 | ); | ||
168 | void | ||
169 | ex_halbtc8821a2ant_scan_notify( | ||
170 | struct btc_coexist *btcoexist, | ||
171 | u8 type | ||
172 | ); | ||
173 | void | ||
174 | ex_halbtc8821a2ant_connect_notify( | ||
175 | struct btc_coexist *btcoexist, | ||
176 | u8 type | ||
177 | ); | ||
178 | void | ||
179 | ex_halbtc8821a2ant_media_status_notify( | ||
180 | struct btc_coexist *btcoexist, | ||
181 | u8 type | ||
182 | ); | ||
183 | void | ||
184 | ex_halbtc8821a2ant_special_packet_notify( | ||
185 | struct btc_coexist *btcoexist, | ||
186 | u8 type | ||
187 | ); | ||
188 | void | ||
189 | ex_halbtc8821a2ant_bt_info_notify( | ||
190 | struct btc_coexist *btcoexist, | ||
191 | u8 *tmp_buf, | ||
192 | u8 length | ||
193 | ); | ||
194 | void | ||
195 | ex_halbtc8821a2ant_halt_notify( | ||
196 | struct btc_coexist *btcoexist | ||
197 | ); | ||
198 | void | ||
199 | ex_halbtc8821a2ant_periodical( | ||
200 | struct btc_coexist *btcoexist | ||
201 | ); | ||
202 | void | ||
203 | ex_halbtc8821a2ant_display_coex_info( | ||
204 | struct btc_coexist *btcoexist | ||
205 | ); | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c index d4bd550f505c..fcf7459b5d66 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c | |||
@@ -32,7 +32,6 @@ | |||
32 | struct btc_coexist gl_bt_coexist; | 32 | struct btc_coexist gl_bt_coexist; |
33 | 33 | ||
34 | u32 btc_dbg_type[BTC_MSG_MAX]; | 34 | u32 btc_dbg_type[BTC_MSG_MAX]; |
35 | static u8 btc_dbg_buf[100]; | ||
36 | 35 | ||
37 | /*************************************************** | 36 | /*************************************************** |
38 | * Debug related function | 37 | * Debug related function |
@@ -389,7 +388,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) | |||
389 | btcoexist->bt_info.reject_agg_pkt = *bool_tmp; | 388 | btcoexist->bt_info.reject_agg_pkt = *bool_tmp; |
390 | break; | 389 | break; |
391 | case BTC_SET_BL_BT_CTRL_AGG_SIZE: | 390 | case BTC_SET_BL_BT_CTRL_AGG_SIZE: |
392 | btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp; | 391 | btcoexist->bt_info.bt_ctrl_buf_size = *bool_tmp; |
393 | break; | 392 | break; |
394 | case BTC_SET_BL_INC_SCAN_DEV_NUM: | 393 | case BTC_SET_BL_INC_SCAN_DEV_NUM: |
395 | btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; | 394 | btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; |
@@ -417,10 +416,10 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf) | |||
417 | /* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */ | 416 | /* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */ |
418 | break; | 417 | break; |
419 | case BTC_SET_U1_1ANT_LPS: | 418 | case BTC_SET_U1_1ANT_LPS: |
420 | btcoexist->bt_info.lps_1ant = *u8_tmp; | 419 | btcoexist->bt_info.lps_val = *u8_tmp; |
421 | break; | 420 | break; |
422 | case BTC_SET_U1_1ANT_RPWM: | 421 | case BTC_SET_U1_1ANT_RPWM: |
423 | btcoexist->bt_info.rpwm_1ant = *u8_tmp; | 422 | btcoexist->bt_info.rpwm_val = *u8_tmp; |
424 | break; | 423 | break; |
425 | /* the following are some action which will be triggered */ | 424 | /* the following are some action which will be triggered */ |
426 | case BTC_SET_ACT_LEAVE_LPS: | 425 | case BTC_SET_ACT_LEAVE_LPS: |
@@ -497,7 +496,7 @@ static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr) | |||
497 | return rtl_read_dword(rtlpriv, reg_addr); | 496 | return rtl_read_dword(rtlpriv, reg_addr); |
498 | } | 497 | } |
499 | 498 | ||
500 | static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data) | 499 | static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data) |
501 | { | 500 | { |
502 | struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; | 501 | struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; |
503 | struct rtl_priv *rtlpriv = btcoexist->adapter; | 502 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
@@ -506,7 +505,7 @@ static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data) | |||
506 | } | 505 | } |
507 | 506 | ||
508 | static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, | 507 | static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, |
509 | u32 bit_mask, u8 data) | 508 | u8 bit_mask, u8 data) |
510 | { | 509 | { |
511 | struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; | 510 | struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; |
512 | struct rtl_priv *rtlpriv = btcoexist->adapter; | 511 | struct rtl_priv *rtlpriv = btcoexist->adapter; |
@@ -652,9 +651,7 @@ bool exhalbtc_initlize_variables(struct rtl_priv *adapter) | |||
652 | btcoexist->btc_get = halbtc_get; | 651 | btcoexist->btc_get = halbtc_get; |
653 | btcoexist->btc_set = halbtc_set; | 652 | btcoexist->btc_set = halbtc_set; |
654 | 653 | ||
655 | btcoexist->cli_buf = &btc_dbg_buf[0]; | 654 | btcoexist->bt_info.bt_ctrl_buf_size = false; |
656 | |||
657 | btcoexist->bt_info.b_bt_ctrl_buf_size = false; | ||
658 | btcoexist->bt_info.agg_buf_size = 5; | 655 | btcoexist->bt_info.agg_buf_size = 5; |
659 | 656 | ||
660 | btcoexist->bt_info.increase_scan_dev_num = false; | 657 | btcoexist->bt_info.increase_scan_dev_num = false; |
@@ -672,7 +669,7 @@ void exhalbtc_init_hw_config(struct btc_coexist *btcoexist) | |||
672 | btcoexist->statistics.cnt_init_hw_config++; | 669 | btcoexist->statistics.cnt_init_hw_config++; |
673 | 670 | ||
674 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 671 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
675 | ex_halbtc8723b2ant_init_hwconfig(btcoexist); | 672 | ex_btc8723b2ant_init_hwconfig(btcoexist); |
676 | } | 673 | } |
677 | 674 | ||
678 | void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) | 675 | void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) |
@@ -686,7 +683,7 @@ void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) | |||
686 | btcoexist->statistics.cnt_init_coex_dm++; | 683 | btcoexist->statistics.cnt_init_coex_dm++; |
687 | 684 | ||
688 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 685 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
689 | ex_halbtc8723b2ant_init_coex_dm(btcoexist); | 686 | ex_btc8723b2ant_init_coex_dm(btcoexist); |
690 | 687 | ||
691 | btcoexist->initilized = true; | 688 | btcoexist->initilized = true; |
692 | } | 689 | } |
@@ -711,7 +708,7 @@ void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type) | |||
711 | halbtc_leave_low_power(); | 708 | halbtc_leave_low_power(); |
712 | 709 | ||
713 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 710 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
714 | ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type); | 711 | ex_btc8723b2ant_ips_notify(btcoexist, ips_type); |
715 | 712 | ||
716 | halbtc_nomal_low_power(); | 713 | halbtc_nomal_low_power(); |
717 | } | 714 | } |
@@ -734,7 +731,7 @@ void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type) | |||
734 | lps_type = BTC_LPS_ENABLE; | 731 | lps_type = BTC_LPS_ENABLE; |
735 | 732 | ||
736 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 733 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
737 | ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type); | 734 | ex_btc8723b2ant_lps_notify(btcoexist, lps_type); |
738 | } | 735 | } |
739 | 736 | ||
740 | void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) | 737 | void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) |
@@ -757,7 +754,7 @@ void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) | |||
757 | halbtc_leave_low_power(); | 754 | halbtc_leave_low_power(); |
758 | 755 | ||
759 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 756 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
760 | ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type); | 757 | ex_btc8723b2ant_scan_notify(btcoexist, scan_type); |
761 | 758 | ||
762 | halbtc_nomal_low_power(); | 759 | halbtc_nomal_low_power(); |
763 | } | 760 | } |
@@ -782,14 +779,12 @@ void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action) | |||
782 | halbtc_leave_low_power(); | 779 | halbtc_leave_low_power(); |
783 | 780 | ||
784 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 781 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
785 | ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type); | 782 | ex_btc8723b2ant_connect_notify(btcoexist, asso_type); |
786 | } | 783 | } |
787 | 784 | ||
788 | void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, | 785 | void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, |
789 | enum _RT_MEDIA_STATUS media_status) | 786 | enum rt_media_status media_status) |
790 | { | 787 | { |
791 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
792 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
793 | u8 status; | 788 | u8 status; |
794 | 789 | ||
795 | if (!halbtc_is_bt_coexist_available(btcoexist)) | 790 | if (!halbtc_is_bt_coexist_available(btcoexist)) |
@@ -805,9 +800,6 @@ void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, | |||
805 | 800 | ||
806 | halbtc_leave_low_power(); | 801 | halbtc_leave_low_power(); |
807 | 802 | ||
808 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | ||
809 | btc8723b_med_stat_notify(btcoexist, status); | ||
810 | |||
811 | halbtc_nomal_low_power(); | 803 | halbtc_nomal_low_power(); |
812 | } | 804 | } |
813 | 805 | ||
@@ -828,8 +820,8 @@ void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type) | |||
828 | halbtc_leave_low_power(); | 820 | halbtc_leave_low_power(); |
829 | 821 | ||
830 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 822 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
831 | ex_halbtc8723b2ant_special_packet_notify(btcoexist, | 823 | ex_btc8723b2ant_special_packet_notify(btcoexist, |
832 | packet_type); | 824 | packet_type); |
833 | 825 | ||
834 | halbtc_nomal_low_power(); | 826 | halbtc_nomal_low_power(); |
835 | } | 827 | } |
@@ -844,13 +836,11 @@ void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, | |||
844 | btcoexist->statistics.cnt_bt_info_notify++; | 836 | btcoexist->statistics.cnt_bt_info_notify++; |
845 | 837 | ||
846 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 838 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
847 | ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length); | 839 | ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length); |
848 | } | 840 | } |
849 | 841 | ||
850 | void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) | 842 | void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) |
851 | { | 843 | { |
852 | struct rtl_priv *rtlpriv = btcoexist->adapter; | ||
853 | struct rtl_hal *rtlhal = rtl_hal(rtlpriv); | ||
854 | u8 stack_op_type; | 844 | u8 stack_op_type; |
855 | 845 | ||
856 | if (!halbtc_is_bt_coexist_available(btcoexist)) | 846 | if (!halbtc_is_bt_coexist_available(btcoexist)) |
@@ -863,10 +853,6 @@ void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) | |||
863 | 853 | ||
864 | halbtc_leave_low_power(); | 854 | halbtc_leave_low_power(); |
865 | 855 | ||
866 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | ||
867 | ex_halbtc8723b2ant_stack_operation_notify(btcoexist, | ||
868 | stack_op_type); | ||
869 | |||
870 | halbtc_nomal_low_power(); | 856 | halbtc_nomal_low_power(); |
871 | } | 857 | } |
872 | 858 | ||
@@ -878,7 +864,7 @@ void exhalbtc_halt_notify(struct btc_coexist *btcoexist) | |||
878 | return; | 864 | return; |
879 | 865 | ||
880 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 866 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
881 | ex_halbtc8723b2ant_halt_notify(btcoexist); | 867 | ex_btc8723b2ant_halt_notify(btcoexist); |
882 | } | 868 | } |
883 | 869 | ||
884 | void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) | 870 | void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) |
@@ -898,7 +884,7 @@ void exhalbtc_periodical(struct btc_coexist *btcoexist) | |||
898 | halbtc_leave_low_power(); | 884 | halbtc_leave_low_power(); |
899 | 885 | ||
900 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 886 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
901 | ex_halbtc8723b2ant_periodical(btcoexist); | 887 | ex_btc8723b2ant_periodical(btcoexist); |
902 | 888 | ||
903 | halbtc_nomal_low_power(); | 889 | halbtc_nomal_low_power(); |
904 | } | 890 | } |
@@ -997,5 +983,5 @@ void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist) | |||
997 | return; | 983 | return; |
998 | 984 | ||
999 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) | 985 | if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) |
1000 | ex_halbtc8723b2ant_display_coex_info(btcoexist); | 986 | ex_btc8723b2ant_display_coex_info(btcoexist); |
1001 | } | 987 | } |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h index 049f4c8d98a8..1345545f66bc 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h +++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h | |||
@@ -55,9 +55,16 @@ | |||
55 | #define BTC_RATE_DISABLE 0 | 55 | #define BTC_RATE_DISABLE 0 |
56 | #define BTC_RATE_ENABLE 1 | 56 | #define BTC_RATE_ENABLE 1 |
57 | 57 | ||
58 | /* single Antenna definition */ | ||
58 | #define BTC_ANT_PATH_WIFI 0 | 59 | #define BTC_ANT_PATH_WIFI 0 |
59 | #define BTC_ANT_PATH_BT 1 | 60 | #define BTC_ANT_PATH_BT 1 |
60 | #define BTC_ANT_PATH_PTA 2 | 61 | #define BTC_ANT_PATH_PTA 2 |
62 | /* dual Antenna definition */ | ||
63 | #define BTC_ANT_WIFI_AT_MAIN 0 | ||
64 | #define BTC_ANT_WIFI_AT_AUX 1 | ||
65 | /* coupler Antenna definition */ | ||
66 | #define BTC_ANT_WIFI_AT_CPL_MAIN 0 | ||
67 | #define BTC_ANT_WIFI_AT_CPL_AUX 1 | ||
61 | 68 | ||
62 | enum btc_chip_interface { | 69 | enum btc_chip_interface { |
63 | BTC_INTF_UNKNOWN = 0, | 70 | BTC_INTF_UNKNOWN = 0, |
@@ -68,7 +75,7 @@ enum btc_chip_interface { | |||
68 | BTC_INTF_MAX | 75 | BTC_INTF_MAX |
69 | }; | 76 | }; |
70 | 77 | ||
71 | enum BTC_CHIP_TYPE { | 78 | enum btc_chip_type { |
72 | BTC_CHIP_UNDEF = 0, | 79 | BTC_CHIP_UNDEF = 0, |
73 | BTC_CHIP_CSR_BC4 = 1, | 80 | BTC_CHIP_CSR_BC4 = 1, |
74 | BTC_CHIP_CSR_BC8 = 2, | 81 | BTC_CHIP_CSR_BC8 = 2, |
@@ -78,11 +85,12 @@ enum BTC_CHIP_TYPE { | |||
78 | BTC_CHIP_MAX | 85 | BTC_CHIP_MAX |
79 | }; | 86 | }; |
80 | 87 | ||
81 | enum BTC_MSG_TYPE { | 88 | enum btc_msg_type { |
82 | BTC_MSG_INTERFACE = 0x0, | 89 | BTC_MSG_INTERFACE = 0x0, |
83 | BTC_MSG_ALGORITHM = 0x1, | 90 | BTC_MSG_ALGORITHM = 0x1, |
84 | BTC_MSG_MAX | 91 | BTC_MSG_MAX |
85 | }; | 92 | }; |
93 | |||
86 | extern u32 btc_dbg_type[]; | 94 | extern u32 btc_dbg_type[]; |
87 | 95 | ||
88 | /* following is for BTC_MSG_INTERFACE */ | 96 | /* following is for BTC_MSG_INTERFACE */ |
@@ -101,20 +109,12 @@ extern u32 btc_dbg_type[]; | |||
101 | #define ALGO_TRACE_SW_DETAIL BIT8 | 109 | #define ALGO_TRACE_SW_DETAIL BIT8 |
102 | #define ALGO_TRACE_SW_EXEC BIT9 | 110 | #define ALGO_TRACE_SW_EXEC BIT9 |
103 | 111 | ||
104 | #define BT_COEX_ANT_TYPE_PG 0 | 112 | /* following is for wifi link status */ |
105 | #define BT_COEX_ANT_TYPE_ANTDIV 1 | 113 | #define WIFI_STA_CONNECTED BIT0 |
106 | #define BT_COEX_ANT_TYPE_DETECTED 2 | 114 | #define WIFI_AP_CONNECTED BIT1 |
107 | #define BTC_MIMO_PS_STATIC 0 | 115 | #define WIFI_HS_CONNECTED BIT2 |
108 | #define BTC_MIMO_PS_DYNAMIC 1 | 116 | #define WIFI_P2P_GO_CONNECTED BIT3 |
109 | #define BTC_RATE_DISABLE 0 | 117 | #define WIFI_P2P_GC_CONNECTED BIT4 |
110 | #define BTC_RATE_ENABLE 1 | ||
111 | #define BTC_ANT_PATH_WIFI 0 | ||
112 | #define BTC_ANT_PATH_BT 1 | ||
113 | #define BTC_ANT_PATH_PTA 2 | ||
114 | |||
115 | |||
116 | #define CL_SPRINTF snprintf | ||
117 | #define CL_PRINTF(buf) printk("%s", buf) | ||
118 | 118 | ||
119 | #define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \ | 119 | #define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \ |
120 | do { \ | 120 | do { \ |
@@ -123,46 +123,15 @@ extern u32 btc_dbg_type[]; | |||
123 | } \ | 123 | } \ |
124 | } while (0) | 124 | } while (0) |
125 | 125 | ||
126 | #define BTC_PRINT_F(dbgtype, dbgflag, printstr, ...) \ | 126 | #define BTC_RSSI_HIGH(_rssi_) \ |
127 | do { \ | 127 | ((_rssi_ == BTC_RSSI_STATE_HIGH || \ |
128 | if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ | 128 | _rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? true : false) |
129 | pr_info("%s: ", __func__); \ | 129 | #define BTC_RSSI_MEDIUM(_rssi_) \ |
130 | printk(printstr, ##__VA_ARGS__); \ | 130 | ((_rssi_ == BTC_RSSI_STATE_MEDIUM || \ |
131 | } \ | 131 | _rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? true : false) |
132 | } while (0) | 132 | #define BTC_RSSI_LOW(_rssi_) \ |
133 | 133 | ((_rssi_ == BTC_RSSI_STATE_LOW || \ | |
134 | #define BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr) \ | 134 | _rssi_ == BTC_RSSI_STATE_STAY_LOW) ? true : false) |
135 | do { \ | ||
136 | if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \ | ||
137 | int __i; \ | ||
138 | u8 *__ptr = (u8 *)_ptr; \ | ||
139 | printk printstr; \ | ||
140 | for (__i = 0; __i < 6; __i++) \ | ||
141 | printk("%02X%s", __ptr[__i], (__i == 5) ? \ | ||
142 | "" : "-"); \ | ||
143 | pr_info("\n"); \ | ||
144 | } \ | ||
145 | } while (0) | ||
146 | |||
147 | #define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \ | ||
148 | do { \ | ||
149 | if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \ | ||
150 | int __i; \ | ||
151 | u8 *__ptr = (u8 *)_hexdata; \ | ||
152 | printk(_titlestring); \ | ||
153 | for (__i = 0; __i < (int)_hexdatalen; __i++) { \ | ||
154 | printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \ | ||
155 | == 0) ? " " : " ");\ | ||
156 | if (((__i + 1) % 16) == 0) \ | ||
157 | printk("\n"); \ | ||
158 | } \ | ||
159 | pr_debug("\n"); \ | ||
160 | } \ | ||
161 | } while (0) | ||
162 | |||
163 | #define BTC_ANT_PATH_WIFI 0 | ||
164 | #define BTC_ANT_PATH_BT 1 | ||
165 | #define BTC_ANT_PATH_PTA 2 | ||
166 | 135 | ||
167 | enum btc_power_save_type { | 136 | enum btc_power_save_type { |
168 | BTC_PS_WIFI_NATIVE = 0, | 137 | BTC_PS_WIFI_NATIVE = 0, |
@@ -224,7 +193,6 @@ enum btc_wifi_pnp { | |||
224 | BTC_WIFI_PNP_MAX | 193 | BTC_WIFI_PNP_MAX |
225 | }; | 194 | }; |
226 | 195 | ||
227 | |||
228 | enum btc_get_type { | 196 | enum btc_get_type { |
229 | /* type bool */ | 197 | /* type bool */ |
230 | BTC_GET_BL_HS_OPERATION, | 198 | BTC_GET_BL_HS_OPERATION, |
@@ -253,6 +221,7 @@ enum btc_get_type { | |||
253 | BTC_GET_U4_WIFI_BW, | 221 | BTC_GET_U4_WIFI_BW, |
254 | BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, | 222 | BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, |
255 | BTC_GET_U4_WIFI_FW_VER, | 223 | BTC_GET_U4_WIFI_FW_VER, |
224 | BTC_GET_U4_WIFI_LINK_STATUS, | ||
256 | BTC_GET_U4_BT_PATCH_VER, | 225 | BTC_GET_U4_BT_PATCH_VER, |
257 | 226 | ||
258 | /* type u1Byte */ | 227 | /* type u1Byte */ |
@@ -260,6 +229,7 @@ enum btc_get_type { | |||
260 | BTC_GET_U1_WIFI_CENTRAL_CHNL, | 229 | BTC_GET_U1_WIFI_CENTRAL_CHNL, |
261 | BTC_GET_U1_WIFI_HS_CHNL, | 230 | BTC_GET_U1_WIFI_HS_CHNL, |
262 | BTC_GET_U1_MAC_PHY_MODE, | 231 | BTC_GET_U1_MAC_PHY_MODE, |
232 | BTC_GET_U1_AP_NUM, | ||
263 | 233 | ||
264 | /* for 1Ant */ | 234 | /* for 1Ant */ |
265 | BTC_GET_U1_LPS_MODE, | 235 | BTC_GET_U1_LPS_MODE, |
@@ -270,7 +240,6 @@ enum btc_get_type { | |||
270 | BTC_GET_MAX | 240 | BTC_GET_MAX |
271 | }; | 241 | }; |
272 | 242 | ||
273 | |||
274 | enum btc_set_type { | 243 | enum btc_set_type { |
275 | /* type bool */ | 244 | /* type bool */ |
276 | BTC_SET_BL_BT_DISABLE, | 245 | BTC_SET_BL_BT_DISABLE, |
@@ -283,7 +252,6 @@ enum btc_set_type { | |||
283 | 252 | ||
284 | /* type u1Byte */ | 253 | /* type u1Byte */ |
285 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, | 254 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, |
286 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, | ||
287 | BTC_SET_UI_SCAN_SIG_COMPENSATION, | 255 | BTC_SET_UI_SCAN_SIG_COMPENSATION, |
288 | BTC_SET_U1_AGG_BUF_SIZE, | 256 | BTC_SET_U1_AGG_BUF_SIZE, |
289 | 257 | ||
@@ -295,6 +263,9 @@ enum btc_set_type { | |||
295 | /* type bool */ | 263 | /* type bool */ |
296 | BTC_SET_BL_BT_SCO_BUSY, | 264 | BTC_SET_BL_BT_SCO_BUSY, |
297 | /* type u1Byte */ | 265 | /* type u1Byte */ |
266 | BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, | ||
267 | BTC_SET_U1_LPS_VAL, | ||
268 | BTC_SET_U1_RPWM_VAL, | ||
298 | BTC_SET_U1_1ANT_LPS, | 269 | BTC_SET_U1_1ANT_LPS, |
299 | BTC_SET_U1_1ANT_RPWM, | 270 | BTC_SET_U1_1ANT_RPWM, |
300 | /* type trigger some action */ | 271 | /* type trigger some action */ |
@@ -358,6 +329,20 @@ enum btc_notify_type_special_packet { | |||
358 | BTC_PACKET_MAX | 329 | BTC_PACKET_MAX |
359 | }; | 330 | }; |
360 | 331 | ||
332 | enum hci_ext_bt_operation { | ||
333 | HCI_BT_OP_NONE = 0x0, | ||
334 | HCI_BT_OP_INQUIRY_START = 0x1, | ||
335 | HCI_BT_OP_INQUIRY_FINISH = 0x2, | ||
336 | HCI_BT_OP_PAGING_START = 0x3, | ||
337 | HCI_BT_OP_PAGING_SUCCESS = 0x4, | ||
338 | HCI_BT_OP_PAGING_UNSUCCESS = 0x5, | ||
339 | HCI_BT_OP_PAIRING_START = 0x6, | ||
340 | HCI_BT_OP_PAIRING_FINISH = 0x7, | ||
341 | HCI_BT_OP_BT_DEV_ENABLE = 0x8, | ||
342 | HCI_BT_OP_BT_DEV_DISABLE = 0x9, | ||
343 | HCI_BT_OP_MAX | ||
344 | }; | ||
345 | |||
361 | enum btc_notify_type_stack_operation { | 346 | enum btc_notify_type_stack_operation { |
362 | BTC_STACK_OP_NONE = 0x0, | 347 | BTC_STACK_OP_NONE = 0x0, |
363 | BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, | 348 | BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, |
@@ -365,17 +350,16 @@ enum btc_notify_type_stack_operation { | |||
365 | BTC_STACK_OP_MAX | 350 | BTC_STACK_OP_MAX |
366 | }; | 351 | }; |
367 | 352 | ||
368 | |||
369 | typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr); | 353 | typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr); |
370 | 354 | ||
371 | typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr); | 355 | typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr); |
372 | 356 | ||
373 | typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr); | 357 | typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr); |
374 | 358 | ||
375 | typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data); | 359 | typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u32 data); |
376 | 360 | ||
377 | typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr, | 361 | typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr, |
378 | u32 bit_mask, u8 data1b); | 362 | u8 bit_mask, u8 data1b); |
379 | 363 | ||
380 | typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data); | 364 | typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data); |
381 | 365 | ||
@@ -413,20 +397,22 @@ struct btc_bt_info { | |||
413 | u8 agg_buf_size; | 397 | u8 agg_buf_size; |
414 | bool limited_dig; | 398 | bool limited_dig; |
415 | bool reject_agg_pkt; | 399 | bool reject_agg_pkt; |
416 | bool b_bt_ctrl_buf_size; | 400 | bool bt_ctrl_buf_size; |
417 | bool increase_scan_dev_num; | 401 | bool increase_scan_dev_num; |
418 | u16 bt_hci_ver; | 402 | u16 bt_hci_ver; |
419 | u16 bt_real_fw_ver; | 403 | u16 bt_real_fw_ver; |
420 | u8 bt_fw_ver; | 404 | u8 bt_fw_ver; |
421 | 405 | ||
406 | bool bt_disable_low_pwr; | ||
407 | |||
422 | /* the following is for 1Ant solution */ | 408 | /* the following is for 1Ant solution */ |
423 | bool bt_ctrl_lps; | 409 | bool bt_ctrl_lps; |
424 | bool bt_pwr_save_mode; | 410 | bool bt_pwr_save_mode; |
425 | bool bt_lps_on; | 411 | bool bt_lps_on; |
426 | bool force_to_roam; | 412 | bool force_to_roam; |
427 | u8 force_exec_pwr_cmd_cnt; | 413 | u8 force_exec_pwr_cmd_cnt; |
428 | u8 lps_1ant; | 414 | u8 lps_val; |
429 | u8 rpwm_1ant; | 415 | u8 rpwm_val; |
430 | u32 ra_mask; | 416 | u32 ra_mask; |
431 | }; | 417 | }; |
432 | 418 | ||
@@ -457,6 +443,7 @@ struct btc_statistics { | |||
457 | u32 cnt_special_packet_notify; | 443 | u32 cnt_special_packet_notify; |
458 | u32 cnt_bt_info_notify; | 444 | u32 cnt_bt_info_notify; |
459 | u32 cnt_periodical; | 445 | u32 cnt_periodical; |
446 | u32 cnt_coex_dm_switch; | ||
460 | u32 cnt_stack_operation_notify; | 447 | u32 cnt_stack_operation_notify; |
461 | u32 cnt_dbg_ctrl; | 448 | u32 cnt_dbg_ctrl; |
462 | }; | 449 | }; |
@@ -493,7 +480,6 @@ struct btc_coexist { | |||
493 | bool initilized; | 480 | bool initilized; |
494 | bool stop_coex_dm; | 481 | bool stop_coex_dm; |
495 | bool manual_control; | 482 | bool manual_control; |
496 | u8 *cli_buf; | ||
497 | struct btc_statistics statistics; | 483 | struct btc_statistics statistics; |
498 | u8 pwr_mode_val[10]; | 484 | u8 pwr_mode_val[10]; |
499 | 485 | ||
@@ -509,7 +495,6 @@ struct btc_coexist { | |||
509 | bfp_btc_set_bb_reg btc_set_bb_reg; | 495 | bfp_btc_set_bb_reg btc_set_bb_reg; |
510 | bfp_btc_get_bb_reg btc_get_bb_reg; | 496 | bfp_btc_get_bb_reg btc_get_bb_reg; |
511 | 497 | ||
512 | |||
513 | bfp_btc_set_rf_reg btc_set_rf_reg; | 498 | bfp_btc_set_rf_reg btc_set_rf_reg; |
514 | bfp_btc_get_rf_reg btc_get_rf_reg; | 499 | bfp_btc_get_rf_reg btc_get_rf_reg; |
515 | 500 | ||
@@ -533,13 +518,14 @@ void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type); | |||
533 | void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); | 518 | void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); |
534 | void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); | 519 | void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); |
535 | void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, | 520 | void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, |
536 | enum _RT_MEDIA_STATUS media_status); | 521 | enum rt_media_status media_status); |
537 | void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); | 522 | void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); |
538 | void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, | 523 | void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, |
539 | u8 length); | 524 | u8 length); |
540 | void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type); | 525 | void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type); |
541 | void exhalbtc_halt_notify(struct btc_coexist *btcoexist); | 526 | void exhalbtc_halt_notify(struct btc_coexist *btcoexist); |
542 | void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); | 527 | void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); |
528 | void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist); | ||
543 | void exhalbtc_periodical(struct btc_coexist *btcoexist); | 529 | void exhalbtc_periodical(struct btc_coexist *btcoexist); |
544 | void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len, | 530 | void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len, |
545 | u8 *data); | 531 | u8 *data); |
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c index 0ab94fe4cbbe..b9b0cb7af8ea 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c | |||
@@ -22,19 +22,19 @@ | |||
22 | * Larry Finger <Larry.Finger@lwfinger.net> | 22 | * Larry Finger <Larry.Finger@lwfinger.net> |
23 | * | 23 | * |
24 | *****************************************************************************/ | 24 | *****************************************************************************/ |
25 | |||
26 | #include "../wifi.h" | 25 | #include "../wifi.h" |
27 | #include "rtl_btc.h" | ||
28 | #include "halbt_precomp.h" | ||
29 | |||
30 | #include <linux/vmalloc.h> | 26 | #include <linux/vmalloc.h> |
31 | #include <linux/module.h> | 27 | #include <linux/module.h> |
32 | 28 | ||
29 | #include "rtl_btc.h" | ||
30 | #include "halbt_precomp.h" | ||
31 | |||
33 | static struct rtl_btc_ops rtl_btc_operation = { | 32 | static struct rtl_btc_ops rtl_btc_operation = { |
34 | .btc_init_variables = rtl_btc_init_variables, | 33 | .btc_init_variables = rtl_btc_init_variables, |
35 | .btc_init_hal_vars = rtl_btc_init_hal_vars, | 34 | .btc_init_hal_vars = rtl_btc_init_hal_vars, |
36 | .btc_init_hw_config = rtl_btc_init_hw_config, | 35 | .btc_init_hw_config = rtl_btc_init_hw_config, |
37 | .btc_ips_notify = rtl_btc_ips_notify, | 36 | .btc_ips_notify = rtl_btc_ips_notify, |
37 | .btc_lps_notify = rtl_btc_lps_notify, | ||
38 | .btc_scan_notify = rtl_btc_scan_notify, | 38 | .btc_scan_notify = rtl_btc_scan_notify, |
39 | .btc_connect_notify = rtl_btc_connect_notify, | 39 | .btc_connect_notify = rtl_btc_connect_notify, |
40 | .btc_mediastatus_notify = rtl_btc_mediastatus_notify, | 40 | .btc_mediastatus_notify = rtl_btc_mediastatus_notify, |
@@ -44,6 +44,7 @@ static struct rtl_btc_ops rtl_btc_operation = { | |||
44 | .btc_is_limited_dig = rtl_btc_is_limited_dig, | 44 | .btc_is_limited_dig = rtl_btc_is_limited_dig, |
45 | .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, | 45 | .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, |
46 | .btc_is_bt_disabled = rtl_btc_is_bt_disabled, | 46 | .btc_is_bt_disabled = rtl_btc_is_bt_disabled, |
47 | .btc_special_packet_notify = rtl_btc_special_packet_notify, | ||
47 | }; | 48 | }; |
48 | 49 | ||
49 | void rtl_btc_init_variables(struct rtl_priv *rtlpriv) | 50 | void rtl_btc_init_variables(struct rtl_priv *rtlpriv) |
@@ -85,6 +86,11 @@ void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type) | |||
85 | exhalbtc_ips_notify(&gl_bt_coexist, type); | 86 | exhalbtc_ips_notify(&gl_bt_coexist, type); |
86 | } | 87 | } |
87 | 88 | ||
89 | void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type) | ||
90 | { | ||
91 | exhalbtc_lps_notify(&gl_bt_coexist, type); | ||
92 | } | ||
93 | |||
88 | void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) | 94 | void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) |
89 | { | 95 | { |
90 | exhalbtc_scan_notify(&gl_bt_coexist, scantype); | 96 | exhalbtc_scan_notify(&gl_bt_coexist, scantype); |
@@ -96,13 +102,14 @@ void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action) | |||
96 | } | 102 | } |
97 | 103 | ||
98 | void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, | 104 | void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, |
99 | enum _RT_MEDIA_STATUS mstatus) | 105 | enum rt_media_status mstatus) |
100 | { | 106 | { |
101 | exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); | 107 | exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); |
102 | } | 108 | } |
103 | 109 | ||
104 | void rtl_btc_periodical(struct rtl_priv *rtlpriv) | 110 | void rtl_btc_periodical(struct rtl_priv *rtlpriv) |
105 | { | 111 | { |
112 | /*rtl_bt_dm_monitor();*/ | ||
106 | exhalbtc_periodical(&gl_bt_coexist); | 113 | exhalbtc_periodical(&gl_bt_coexist); |
107 | } | 114 | } |
108 | 115 | ||
@@ -150,12 +157,18 @@ bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv) | |||
150 | 157 | ||
151 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) | 158 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) |
152 | { | 159 | { |
160 | /* It seems 'bt_disabled' is never be initialized or set. */ | ||
153 | if (gl_bt_coexist.bt_info.bt_disabled) | 161 | if (gl_bt_coexist.bt_info.bt_disabled) |
154 | return true; | 162 | return true; |
155 | else | 163 | else |
156 | return false; | 164 | return false; |
157 | } | 165 | } |
158 | 166 | ||
167 | void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type) | ||
168 | { | ||
169 | return exhalbtc_special_packet_notify(&gl_bt_coexist, pkt_type); | ||
170 | } | ||
171 | |||
159 | struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) | 172 | struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) |
160 | { | 173 | { |
161 | return &rtl_btc_operation; | 174 | return &rtl_btc_operation; |
@@ -174,11 +187,11 @@ u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv) | |||
174 | return num; | 187 | return num; |
175 | } | 188 | } |
176 | 189 | ||
177 | enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) | 190 | enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw) |
178 | { | 191 | { |
179 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 192 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
180 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 193 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
181 | enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; | 194 | enum rt_media_status m_status = RT_MEDIA_DISCONNECT; |
182 | 195 | ||
183 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; | 196 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; |
184 | 197 | ||
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h index 805b22cc8fc8..ccd5a0f91e3b 100644 --- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h +++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h | |||
@@ -31,22 +31,24 @@ void rtl_btc_init_variables(struct rtl_priv *rtlpriv); | |||
31 | void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); | 31 | void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); |
32 | void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); | 32 | void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); |
33 | void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); | 33 | void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); |
34 | void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type); | ||
34 | void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); | 35 | void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); |
35 | void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); | 36 | void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); |
36 | void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, | 37 | void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, |
37 | enum _RT_MEDIA_STATUS mstatus); | 38 | enum rt_media_status mstatus); |
38 | void rtl_btc_periodical(struct rtl_priv *rtlpriv); | 39 | void rtl_btc_periodical(struct rtl_priv *rtlpriv); |
39 | void rtl_btc_halt_notify(void); | 40 | void rtl_btc_halt_notify(void); |
40 | void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); | 41 | void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); |
41 | bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); | 42 | bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); |
42 | bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); | 43 | bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); |
43 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); | 44 | bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); |
45 | void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type); | ||
44 | 46 | ||
45 | struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); | 47 | struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); |
46 | 48 | ||
47 | u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); | 49 | u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); |
48 | u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); | 50 | u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); |
49 | u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); | 51 | u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); |
50 | enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw); | 52 | enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw); |
51 | 53 | ||
52 | #endif | 54 | #endif |
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 67d1ee6edcad..74a8ba4b8844 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -646,7 +646,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) | |||
646 | == 2) { | 646 | == 2) { |
647 | 647 | ||
648 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, | 648 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
649 | "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n", | 649 | "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n", |
650 | prio, ring->idx, | 650 | prio, ring->idx, |
651 | skb_queue_len(&ring->queue)); | 651 | skb_queue_len(&ring->queue)); |
652 | 652 | ||
@@ -1469,7 +1469,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1469 | 1469 | ||
1470 | if ((own == 1) && (hw_queue != BEACON_QUEUE)) { | 1470 | if ((own == 1) && (hw_queue != BEACON_QUEUE)) { |
1471 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | 1471 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
1472 | "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", | 1472 | "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", |
1473 | hw_queue, ring->idx, idx, | 1473 | hw_queue, ring->idx, idx, |
1474 | skb_queue_len(&ring->queue)); | 1474 | skb_queue_len(&ring->queue)); |
1475 | 1475 | ||
@@ -1511,7 +1511,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, | |||
1511 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && | 1511 | if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && |
1512 | hw_queue != BEACON_QUEUE) { | 1512 | hw_queue != BEACON_QUEUE) { |
1513 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, | 1513 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
1514 | "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", | 1514 | "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n", |
1515 | hw_queue, ring->idx, idx, | 1515 | hw_queue, ring->idx, idx, |
1516 | skb_queue_len(&ring->queue)); | 1516 | skb_queue_len(&ring->queue)); |
1517 | 1517 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 592125a5f19c..1961b8e28dc1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c | |||
@@ -677,7 +677,7 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, | |||
677 | 677 | ||
678 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; | 678 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; |
679 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | 679 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, |
680 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", | 680 | "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", |
681 | rtlphy->pwrgroup_cnt, index, | 681 | rtlphy->pwrgroup_cnt, index, |
682 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); | 682 | rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); |
683 | if (index == 13) | 683 | if (index == 13) |
@@ -2531,7 +2531,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, | |||
2531 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ | 2531 | if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ |
2532 | u4tmp = curveindex_5g[channel-1]; | 2532 | u4tmp = curveindex_5g[channel-1]; |
2533 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | 2533 | RTPRINT(rtlpriv, FINIT, INIT_IQK, |
2534 | "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp); | 2534 | "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); |
2535 | if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && | 2535 | if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && |
2536 | rtlpriv->rtlhal.interfaceindex == 1) { | 2536 | rtlpriv->rtlhal.interfaceindex == 1) { |
2537 | bneed_powerdown_radio = | 2537 | bneed_powerdown_radio = |
@@ -2550,7 +2550,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, | |||
2550 | } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { | 2550 | } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { |
2551 | u4tmp = curveindex_2g[channel-1]; | 2551 | u4tmp = curveindex_2g[channel-1]; |
2552 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | 2552 | RTPRINT(rtlpriv, FINIT, INIT_IQK, |
2553 | "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp); | 2553 | "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); |
2554 | if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && | 2554 | if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && |
2555 | rtlpriv->rtlhal.interfaceindex == 0) { | 2555 | rtlpriv->rtlhal.interfaceindex == 0) { |
2556 | bneed_powerdown_radio = | 2556 | bneed_powerdown_radio = |
@@ -2562,7 +2562,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, | |||
2562 | } | 2562 | } |
2563 | rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); | 2563 | rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); |
2564 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | 2564 | RTPRINT(rtlpriv, FINIT, INIT_IQK, |
2565 | "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", | 2565 | "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", |
2566 | rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); | 2566 | rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); |
2567 | if (bneed_powerdown_radio) | 2567 | if (bneed_powerdown_radio) |
2568 | _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); | 2568 | _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); |
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c index 5d534df8d90c..f76c50f5ab80 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c +++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c | |||
@@ -56,11 +56,11 @@ void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw) | |||
56 | } | 56 | } |
57 | } | 57 | } |
58 | 58 | ||
59 | static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) | 59 | static enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw) |
60 | { | 60 | { |
61 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 61 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
62 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | 62 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); |
63 | enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; | 63 | enum rt_media_status m_status = RT_MEDIA_DISCONNECT; |
64 | 64 | ||
65 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; | 65 | u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; |
66 | 66 | ||
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 407a7936d364..541b077ae867 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h | |||
@@ -170,6 +170,11 @@ enum rf_tx_num { | |||
170 | RF_TX_NUM_NONIMPLEMENT, | 170 | RF_TX_NUM_NONIMPLEMENT, |
171 | }; | 171 | }; |
172 | 172 | ||
173 | #define PACKET_NORMAL 0 | ||
174 | #define PACKET_DHCP 1 | ||
175 | #define PACKET_ARP 2 | ||
176 | #define PACKET_EAPOL 3 | ||
177 | |||
173 | struct txpower_info_2g { | 178 | struct txpower_info_2g { |
174 | u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; | 179 | u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; |
175 | u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; | 180 | u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; |
@@ -234,8 +239,9 @@ enum hardware_type { | |||
234 | HARDWARE_TYPE_RTL8192DU, | 239 | HARDWARE_TYPE_RTL8192DU, |
235 | HARDWARE_TYPE_RTL8723AE, | 240 | HARDWARE_TYPE_RTL8723AE, |
236 | HARDWARE_TYPE_RTL8723U, | 241 | HARDWARE_TYPE_RTL8723U, |
237 | HARDWARE_TYPE_RTL8723BE, | ||
238 | HARDWARE_TYPE_RTL8188EE, | 242 | HARDWARE_TYPE_RTL8188EE, |
243 | HARDWARE_TYPE_RTL8723BE, | ||
244 | HARDWARE_TYPE_RTL8192EE, | ||
239 | HARDWARE_TYPE_RTL8821AE, | 245 | HARDWARE_TYPE_RTL8821AE, |
240 | HARDWARE_TYPE_RTL8812AE, | 246 | HARDWARE_TYPE_RTL8812AE, |
241 | 247 | ||
@@ -428,7 +434,7 @@ enum hw_variables { | |||
428 | HW_VAR_DATA_FILTER, | 434 | HW_VAR_DATA_FILTER, |
429 | }; | 435 | }; |
430 | 436 | ||
431 | enum _RT_MEDIA_STATUS { | 437 | enum rt_media_status { |
432 | RT_MEDIA_DISCONNECT = 0, | 438 | RT_MEDIA_DISCONNECT = 0, |
433 | RT_MEDIA_CONNECT = 1 | 439 | RT_MEDIA_CONNECT = 1 |
434 | }; | 440 | }; |
@@ -2312,10 +2318,11 @@ struct rtl_btc_ops { | |||
2312 | void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv); | 2318 | void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv); |
2313 | void (*btc_init_hw_config) (struct rtl_priv *rtlpriv); | 2319 | void (*btc_init_hw_config) (struct rtl_priv *rtlpriv); |
2314 | void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type); | 2320 | void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type); |
2321 | void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type); | ||
2315 | void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype); | 2322 | void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype); |
2316 | void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action); | 2323 | void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action); |
2317 | void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv, | 2324 | void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv, |
2318 | enum _RT_MEDIA_STATUS mstatus); | 2325 | enum rt_media_status mstatus); |
2319 | void (*btc_periodical) (struct rtl_priv *rtlpriv); | 2326 | void (*btc_periodical) (struct rtl_priv *rtlpriv); |
2320 | void (*btc_halt_notify) (void); | 2327 | void (*btc_halt_notify) (void); |
2321 | void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv, | 2328 | void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv, |
@@ -2323,6 +2330,8 @@ struct rtl_btc_ops { | |||
2323 | bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv); | 2330 | bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv); |
2324 | bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv); | 2331 | bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv); |
2325 | bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv); | 2332 | bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv); |
2333 | void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv, | ||
2334 | u8 pkt_type); | ||
2326 | }; | 2335 | }; |
2327 | 2336 | ||
2328 | struct proxim { | 2337 | struct proxim { |
diff --git a/drivers/usb/host/bcma-hcd.c b/drivers/usb/host/bcma-hcd.c index 205f4a336583..cd6d0afb6b8f 100644 --- a/drivers/usb/host/bcma-hcd.c +++ b/drivers/usb/host/bcma-hcd.c | |||
@@ -237,7 +237,7 @@ static int bcma_hcd_probe(struct bcma_device *dev) | |||
237 | bcma_hcd_init_chip(dev); | 237 | bcma_hcd_init_chip(dev); |
238 | 238 | ||
239 | /* In AI chips EHCI is addrspace 0, OHCI is 1 */ | 239 | /* In AI chips EHCI is addrspace 0, OHCI is 1 */ |
240 | ohci_addr = dev->addr1; | 240 | ohci_addr = dev->addr_s[0]; |
241 | if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749) | 241 | if ((chipinfo->id == 0x5357 || chipinfo->id == 0x4749) |
242 | && chipinfo->rev == 0) | 242 | && chipinfo->rev == 0) |
243 | ohci_addr = 0x18009000; | 243 | ohci_addr = 0x18009000; |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 0272e49135d0..634597917670 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
@@ -267,7 +267,7 @@ struct bcma_device { | |||
267 | u8 core_unit; | 267 | u8 core_unit; |
268 | 268 | ||
269 | u32 addr; | 269 | u32 addr; |
270 | u32 addr1; | 270 | u32 addr_s[8]; |
271 | u32 wrap; | 271 | u32 wrap; |
272 | 272 | ||
273 | void __iomem *io_addr; | 273 | void __iomem *io_addr; |
@@ -332,10 +332,10 @@ struct bcma_bus { | |||
332 | struct bcma_device *mapped_core; | 332 | struct bcma_device *mapped_core; |
333 | struct list_head cores; | 333 | struct list_head cores; |
334 | u8 nr_cores; | 334 | u8 nr_cores; |
335 | u8 init_done:1; | ||
336 | u8 num; | 335 | u8 num; |
337 | 336 | ||
338 | struct bcma_drv_cc drv_cc; | 337 | struct bcma_drv_cc drv_cc; |
338 | struct bcma_drv_cc_b drv_cc_b; | ||
339 | struct bcma_drv_pci drv_pci[2]; | 339 | struct bcma_drv_pci drv_pci[2]; |
340 | struct bcma_drv_pcie2 drv_pcie2; | 340 | struct bcma_drv_pcie2 drv_pcie2; |
341 | struct bcma_drv_mips drv_mips; | 341 | struct bcma_drv_mips drv_mips; |
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 63d105cd14a3..db6fa217f98b 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -644,6 +644,12 @@ struct bcma_drv_cc { | |||
644 | #endif | 644 | #endif |
645 | }; | 645 | }; |
646 | 646 | ||
647 | struct bcma_drv_cc_b { | ||
648 | struct bcma_device *core; | ||
649 | u8 setup_done:1; | ||
650 | void __iomem *mii; | ||
651 | }; | ||
652 | |||
647 | /* Register access */ | 653 | /* Register access */ |
648 | #define bcma_cc_read32(cc, offset) \ | 654 | #define bcma_cc_read32(cc, offset) \ |
649 | bcma_read32((cc)->core, offset) | 655 | bcma_read32((cc)->core, offset) |
@@ -699,4 +705,6 @@ extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid); | |||
699 | 705 | ||
700 | extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc); | 706 | extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc); |
701 | 707 | ||
708 | void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value); | ||
709 | |||
702 | #endif /* LINUX_BCMA_DRIVER_CC_H_ */ | 710 | #endif /* LINUX_BCMA_DRIVER_CC_H_ */ |
diff --git a/include/linux/bcma/bcma_soc.h b/include/linux/bcma/bcma_soc.h index 4203c5593b9f..f24d245f8394 100644 --- a/include/linux/bcma/bcma_soc.h +++ b/include/linux/bcma/bcma_soc.h | |||
@@ -10,6 +10,7 @@ struct bcma_soc { | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | int __init bcma_host_soc_register(struct bcma_soc *soc); | 12 | int __init bcma_host_soc_register(struct bcma_soc *soc); |
13 | int __init bcma_host_soc_init(struct bcma_soc *soc); | ||
13 | 14 | ||
14 | int bcma_bus_register(struct bcma_bus *bus); | 15 | int bcma_bus_register(struct bcma_bus *bus); |
15 | 16 | ||
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h index 8018c915ee63..b1be39c76931 100644 --- a/include/linux/ieee80211.h +++ b/include/linux/ieee80211.h | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> | 6 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> |
7 | * Copyright (c) 2005, Devicescape Software, Inc. | 7 | * Copyright (c) 2005, Devicescape Software, Inc. |
8 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
@@ -165,8 +166,12 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2) | |||
165 | 166 | ||
166 | #define IEEE80211_MAX_MESH_ID_LEN 32 | 167 | #define IEEE80211_MAX_MESH_ID_LEN 32 |
167 | 168 | ||
169 | #define IEEE80211_FIRST_TSPEC_TSID 8 | ||
168 | #define IEEE80211_NUM_TIDS 16 | 170 | #define IEEE80211_NUM_TIDS 16 |
169 | 171 | ||
172 | /* number of user priorities 802.11 uses */ | ||
173 | #define IEEE80211_NUM_UPS 8 | ||
174 | |||
170 | #define IEEE80211_QOS_CTL_LEN 2 | 175 | #define IEEE80211_QOS_CTL_LEN 2 |
171 | /* 1d tag mask */ | 176 | /* 1d tag mask */ |
172 | #define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 | 177 | #define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 |
@@ -1823,7 +1828,8 @@ enum ieee80211_eid { | |||
1823 | WLAN_EID_DMG_TSPEC = 146, | 1828 | WLAN_EID_DMG_TSPEC = 146, |
1824 | WLAN_EID_DMG_AT = 147, | 1829 | WLAN_EID_DMG_AT = 147, |
1825 | WLAN_EID_DMG_CAP = 148, | 1830 | WLAN_EID_DMG_CAP = 148, |
1826 | /* 149-150 reserved for Cisco */ | 1831 | /* 149 reserved for Cisco */ |
1832 | WLAN_EID_CISCO_VENDOR_SPECIFIC = 150, | ||
1827 | WLAN_EID_DMG_OPERATION = 151, | 1833 | WLAN_EID_DMG_OPERATION = 151, |
1828 | WLAN_EID_DMG_BSS_PARAM_CHANGE = 152, | 1834 | WLAN_EID_DMG_BSS_PARAM_CHANGE = 152, |
1829 | WLAN_EID_DMG_BEAM_REFINEMENT = 153, | 1835 | WLAN_EID_DMG_BEAM_REFINEMENT = 153, |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index b0ded1333865..206b92bfeebb 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -539,7 +539,6 @@ enum { | |||
539 | HCI_CONN_RSWITCH_PEND, | 539 | HCI_CONN_RSWITCH_PEND, |
540 | HCI_CONN_MODE_CHANGE_PEND, | 540 | HCI_CONN_MODE_CHANGE_PEND, |
541 | HCI_CONN_SCO_SETUP_PEND, | 541 | HCI_CONN_SCO_SETUP_PEND, |
542 | HCI_CONN_LE_SMP_PEND, | ||
543 | HCI_CONN_MGMT_CONNECTED, | 542 | HCI_CONN_MGMT_CONNECTED, |
544 | HCI_CONN_SSP_ENABLED, | 543 | HCI_CONN_SSP_ENABLED, |
545 | HCI_CONN_SC_ENABLED, | 544 | HCI_CONN_SC_ENABLED, |
@@ -553,6 +552,7 @@ enum { | |||
553 | HCI_CONN_FIPS, | 552 | HCI_CONN_FIPS, |
554 | HCI_CONN_STK_ENCRYPT, | 553 | HCI_CONN_STK_ENCRYPT, |
555 | HCI_CONN_AUTH_INITIATOR, | 554 | HCI_CONN_AUTH_INITIATOR, |
555 | HCI_CONN_DROP, | ||
556 | }; | 556 | }; |
557 | 557 | ||
558 | static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) | 558 | static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) |
@@ -702,7 +702,7 @@ static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, | |||
702 | return NULL; | 702 | return NULL; |
703 | } | 703 | } |
704 | 704 | ||
705 | void hci_disconnect(struct hci_conn *conn, __u8 reason); | 705 | int hci_disconnect(struct hci_conn *conn, __u8 reason); |
706 | bool hci_setup_sync(struct hci_conn *conn, __u16 handle); | 706 | bool hci_setup_sync(struct hci_conn *conn, __u16 handle); |
707 | void hci_sco_setup(struct hci_conn *conn, __u8 status); | 707 | void hci_sco_setup(struct hci_conn *conn, __u8 status); |
708 | 708 | ||
@@ -756,9 +756,10 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status); | |||
756 | * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). | 756 | * _get()/_drop() in it, but require the caller to have a valid ref (FIXME). |
757 | */ | 757 | */ |
758 | 758 | ||
759 | static inline void hci_conn_get(struct hci_conn *conn) | 759 | static inline struct hci_conn *hci_conn_get(struct hci_conn *conn) |
760 | { | 760 | { |
761 | get_device(&conn->dev); | 761 | get_device(&conn->dev); |
762 | return conn; | ||
762 | } | 763 | } |
763 | 764 | ||
764 | static inline void hci_conn_put(struct hci_conn *conn) | 765 | static inline void hci_conn_put(struct hci_conn *conn) |
@@ -790,7 +791,7 @@ static inline void hci_conn_drop(struct hci_conn *conn) | |||
790 | if (!conn->out) | 791 | if (!conn->out) |
791 | timeo *= 2; | 792 | timeo *= 2; |
792 | } else { | 793 | } else { |
793 | timeo = msecs_to_jiffies(10); | 794 | timeo = 0; |
794 | } | 795 | } |
795 | break; | 796 | break; |
796 | 797 | ||
@@ -799,7 +800,7 @@ static inline void hci_conn_drop(struct hci_conn *conn) | |||
799 | break; | 800 | break; |
800 | 801 | ||
801 | default: | 802 | default: |
802 | timeo = msecs_to_jiffies(10); | 803 | timeo = 0; |
803 | break; | 804 | break; |
804 | } | 805 | } |
805 | 806 | ||
@@ -1341,8 +1342,7 @@ int mgmt_user_passkey_neg_reply_complete(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
1341 | int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, | 1342 | int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, |
1342 | u8 link_type, u8 addr_type, u32 passkey, | 1343 | u8 link_type, u8 addr_type, u32 passkey, |
1343 | u8 entered); | 1344 | u8 entered); |
1344 | void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 1345 | void mgmt_auth_failed(struct hci_conn *conn, u8 status); |
1345 | u8 addr_type, u8 status); | ||
1346 | void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); | 1346 | void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status); |
1347 | void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); | 1347 | void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); |
1348 | void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); | 1348 | void mgmt_sc_enable_complete(struct hci_dev *hdev, u8 enable, u8 status); |
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index cedda399f9c0..ead99f032f7a 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h | |||
@@ -625,9 +625,6 @@ struct l2cap_conn { | |||
625 | 625 | ||
626 | struct delayed_work info_timer; | 626 | struct delayed_work info_timer; |
627 | 627 | ||
628 | int disconn_err; | ||
629 | struct work_struct disconn_work; | ||
630 | |||
631 | struct sk_buff *rx_skb; | 628 | struct sk_buff *rx_skb; |
632 | __u32 rx_len; | 629 | __u32 rx_len; |
633 | __u8 tx_ident; | 630 | __u8 tx_ident; |
@@ -636,6 +633,8 @@ struct l2cap_conn { | |||
636 | struct sk_buff_head pending_rx; | 633 | struct sk_buff_head pending_rx; |
637 | struct work_struct pending_rx_work; | 634 | struct work_struct pending_rx_work; |
638 | 635 | ||
636 | struct work_struct id_addr_update_work; | ||
637 | |||
639 | __u8 disc_reason; | 638 | __u8 disc_reason; |
640 | 639 | ||
641 | struct l2cap_chan *smp; | 640 | struct l2cap_chan *smp; |
@@ -711,6 +710,7 @@ enum { | |||
711 | FLAG_DEFER_SETUP, | 710 | FLAG_DEFER_SETUP, |
712 | FLAG_LE_CONN_REQ_SENT, | 711 | FLAG_LE_CONN_REQ_SENT, |
713 | FLAG_PENDING_SECURITY, | 712 | FLAG_PENDING_SECURITY, |
713 | FLAG_HOLD_HCI_CONN, | ||
714 | }; | 714 | }; |
715 | 715 | ||
716 | enum { | 716 | enum { |
@@ -939,15 +939,13 @@ int l2cap_ertm_init(struct l2cap_chan *chan); | |||
939 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); | 939 | void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); |
940 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); | 940 | void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan); |
941 | void l2cap_chan_del(struct l2cap_chan *chan, int err); | 941 | void l2cap_chan_del(struct l2cap_chan *chan, int err); |
942 | void l2cap_conn_update_id_addr(struct hci_conn *hcon); | ||
943 | void l2cap_send_conn_req(struct l2cap_chan *chan); | 942 | void l2cap_send_conn_req(struct l2cap_chan *chan); |
944 | void l2cap_move_start(struct l2cap_chan *chan); | 943 | void l2cap_move_start(struct l2cap_chan *chan); |
945 | void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, | 944 | void l2cap_logical_cfm(struct l2cap_chan *chan, struct hci_chan *hchan, |
946 | u8 status); | 945 | u8 status); |
947 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); | 946 | void __l2cap_physical_cfm(struct l2cap_chan *chan, int result); |
948 | 947 | ||
949 | void l2cap_conn_shutdown(struct l2cap_conn *conn, int err); | 948 | struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn); |
950 | void l2cap_conn_get(struct l2cap_conn *conn); | ||
951 | void l2cap_conn_put(struct l2cap_conn *conn); | 949 | void l2cap_conn_put(struct l2cap_conn *conn); |
952 | 950 | ||
953 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); | 951 | int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user); |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index ab21299c8f4d..a2ddcf2398fd 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -4,6 +4,7 @@ | |||
4 | * 802.11 device and configuration interface | 4 | * 802.11 device and configuration interface |
5 | * | 5 | * |
6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -663,6 +664,7 @@ struct cfg80211_acl_data { | |||
663 | * @crypto: crypto settings | 664 | * @crypto: crypto settings |
664 | * @privacy: the BSS uses privacy | 665 | * @privacy: the BSS uses privacy |
665 | * @auth_type: Authentication type (algorithm) | 666 | * @auth_type: Authentication type (algorithm) |
667 | * @smps_mode: SMPS mode | ||
666 | * @inactivity_timeout: time in seconds to determine station's inactivity. | 668 | * @inactivity_timeout: time in seconds to determine station's inactivity. |
667 | * @p2p_ctwindow: P2P CT Window | 669 | * @p2p_ctwindow: P2P CT Window |
668 | * @p2p_opp_ps: P2P opportunistic PS | 670 | * @p2p_opp_ps: P2P opportunistic PS |
@@ -681,6 +683,7 @@ struct cfg80211_ap_settings { | |||
681 | struct cfg80211_crypto_settings crypto; | 683 | struct cfg80211_crypto_settings crypto; |
682 | bool privacy; | 684 | bool privacy; |
683 | enum nl80211_auth_type auth_type; | 685 | enum nl80211_auth_type auth_type; |
686 | enum nl80211_smps_mode smps_mode; | ||
684 | int inactivity_timeout; | 687 | int inactivity_timeout; |
685 | u8 p2p_ctwindow; | 688 | u8 p2p_ctwindow; |
686 | bool p2p_opp_ps; | 689 | bool p2p_opp_ps; |
@@ -1607,10 +1610,12 @@ struct cfg80211_auth_request { | |||
1607 | * | 1610 | * |
1608 | * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) | 1611 | * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) |
1609 | * @ASSOC_REQ_DISABLE_VHT: Disable VHT | 1612 | * @ASSOC_REQ_DISABLE_VHT: Disable VHT |
1613 | * @ASSOC_REQ_USE_RRM: Declare RRM capability in this association | ||
1610 | */ | 1614 | */ |
1611 | enum cfg80211_assoc_req_flags { | 1615 | enum cfg80211_assoc_req_flags { |
1612 | ASSOC_REQ_DISABLE_HT = BIT(0), | 1616 | ASSOC_REQ_DISABLE_HT = BIT(0), |
1613 | ASSOC_REQ_DISABLE_VHT = BIT(1), | 1617 | ASSOC_REQ_DISABLE_VHT = BIT(1), |
1618 | ASSOC_REQ_USE_RRM = BIT(2), | ||
1614 | }; | 1619 | }; |
1615 | 1620 | ||
1616 | /** | 1621 | /** |
@@ -1802,6 +1807,7 @@ struct cfg80211_connect_params { | |||
1802 | * @WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed | 1807 | * @WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed |
1803 | * @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed | 1808 | * @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed |
1804 | * @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed | 1809 | * @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed |
1810 | * @WIPHY_PARAM_DYN_ACK: dynack has been enabled | ||
1805 | */ | 1811 | */ |
1806 | enum wiphy_params_flags { | 1812 | enum wiphy_params_flags { |
1807 | WIPHY_PARAM_RETRY_SHORT = 1 << 0, | 1813 | WIPHY_PARAM_RETRY_SHORT = 1 << 0, |
@@ -1809,6 +1815,7 @@ enum wiphy_params_flags { | |||
1809 | WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, | 1815 | WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, |
1810 | WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, | 1816 | WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, |
1811 | WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, | 1817 | WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, |
1818 | WIPHY_PARAM_DYN_ACK = 1 << 5, | ||
1812 | }; | 1819 | }; |
1813 | 1820 | ||
1814 | /* | 1821 | /* |
@@ -1975,14 +1982,12 @@ struct cfg80211_wowlan_wakeup { | |||
1975 | 1982 | ||
1976 | /** | 1983 | /** |
1977 | * struct cfg80211_gtk_rekey_data - rekey data | 1984 | * struct cfg80211_gtk_rekey_data - rekey data |
1978 | * @kek: key encryption key | 1985 | * @kek: key encryption key (NL80211_KEK_LEN bytes) |
1979 | * @kck: key confirmation key | 1986 | * @kck: key confirmation key (NL80211_KCK_LEN bytes) |
1980 | * @replay_ctr: replay counter | 1987 | * @replay_ctr: replay counter (NL80211_REPLAY_CTR_LEN bytes) |
1981 | */ | 1988 | */ |
1982 | struct cfg80211_gtk_rekey_data { | 1989 | struct cfg80211_gtk_rekey_data { |
1983 | u8 kek[NL80211_KEK_LEN]; | 1990 | const u8 *kek, *kck, *replay_ctr; |
1984 | u8 kck[NL80211_KCK_LEN]; | ||
1985 | u8 replay_ctr[NL80211_REPLAY_CTR_LEN]; | ||
1986 | }; | 1991 | }; |
1987 | 1992 | ||
1988 | /** | 1993 | /** |
@@ -2315,6 +2320,17 @@ struct cfg80211_qos_map { | |||
2315 | * @set_ap_chanwidth: Set the AP (including P2P GO) mode channel width for the | 2320 | * @set_ap_chanwidth: Set the AP (including P2P GO) mode channel width for the |
2316 | * given interface This is used e.g. for dynamic HT 20/40 MHz channel width | 2321 | * given interface This is used e.g. for dynamic HT 20/40 MHz channel width |
2317 | * changes during the lifetime of the BSS. | 2322 | * changes during the lifetime of the BSS. |
2323 | * | ||
2324 | * @add_tx_ts: validate (if admitted_time is 0) or add a TX TS to the device | ||
2325 | * with the given parameters; action frame exchange has been handled by | ||
2326 | * userspace so this just has to modify the TX path to take the TS into | ||
2327 | * account. | ||
2328 | * If the admitted time is 0 just validate the parameters to make sure | ||
2329 | * the session can be created at all; it is valid to just always return | ||
2330 | * success for that but that may result in inefficient behaviour (handshake | ||
2331 | * with the peer followed by immediate teardown when the addition is later | ||
2332 | * rejected) | ||
2333 | * @del_tx_ts: remove an existing TX TS | ||
2318 | */ | 2334 | */ |
2319 | struct cfg80211_ops { | 2335 | struct cfg80211_ops { |
2320 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 2336 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
@@ -2555,6 +2571,12 @@ struct cfg80211_ops { | |||
2555 | 2571 | ||
2556 | int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, | 2572 | int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, |
2557 | struct cfg80211_chan_def *chandef); | 2573 | struct cfg80211_chan_def *chandef); |
2574 | |||
2575 | int (*add_tx_ts)(struct wiphy *wiphy, struct net_device *dev, | ||
2576 | u8 tsid, const u8 *peer, u8 user_prio, | ||
2577 | u16 admitted_time); | ||
2578 | int (*del_tx_ts)(struct wiphy *wiphy, struct net_device *dev, | ||
2579 | u8 tsid, const u8 *peer); | ||
2558 | }; | 2580 | }; |
2559 | 2581 | ||
2560 | /* | 2582 | /* |
@@ -2601,9 +2623,13 @@ struct cfg80211_ops { | |||
2601 | * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. | 2623 | * @WIPHY_FLAG_SUPPORTS_5_10_MHZ: Device supports 5 MHz and 10 MHz channels. |
2602 | * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in | 2624 | * @WIPHY_FLAG_HAS_CHANNEL_SWITCH: Device supports channel switch in |
2603 | * beaconing mode (AP, IBSS, Mesh, ...). | 2625 | * beaconing mode (AP, IBSS, Mesh, ...). |
2626 | * @WIPHY_FLAG_SUPPORTS_WMM_ADMISSION: the device supports setting up WMM | ||
2627 | * TSPEC sessions (TID aka TSID 0-7) with the NL80211_CMD_ADD_TX_TS | ||
2628 | * command. Standard IEEE 802.11 TSPEC setup is not yet supported, it | ||
2629 | * needs to be able to handle Block-Ack agreements and other things. | ||
2604 | */ | 2630 | */ |
2605 | enum wiphy_flags { | 2631 | enum wiphy_flags { |
2606 | /* use hole at 0 */ | 2632 | WIPHY_FLAG_SUPPORTS_WMM_ADMISSION = BIT(0), |
2607 | /* use hole at 1 */ | 2633 | /* use hole at 1 */ |
2608 | /* use hole at 2 */ | 2634 | /* use hole at 2 */ |
2609 | WIPHY_FLAG_NETNS_OK = BIT(3), | 2635 | WIPHY_FLAG_NETNS_OK = BIT(3), |
@@ -3920,6 +3946,7 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr); | |||
3920 | * moves to cfg80211 in this call | 3946 | * moves to cfg80211 in this call |
3921 | * @buf: authentication frame (header + body) | 3947 | * @buf: authentication frame (header + body) |
3922 | * @len: length of the frame data | 3948 | * @len: length of the frame data |
3949 | * @uapsd_queues: bitmap of ACs configured to uapsd. -1 if n/a. | ||
3923 | * | 3950 | * |
3924 | * After being asked to associate via cfg80211_ops::assoc() the driver must | 3951 | * After being asked to associate via cfg80211_ops::assoc() the driver must |
3925 | * call either this function or cfg80211_auth_timeout(). | 3952 | * call either this function or cfg80211_auth_timeout(). |
@@ -3928,7 +3955,8 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr); | |||
3928 | */ | 3955 | */ |
3929 | void cfg80211_rx_assoc_resp(struct net_device *dev, | 3956 | void cfg80211_rx_assoc_resp(struct net_device *dev, |
3930 | struct cfg80211_bss *bss, | 3957 | struct cfg80211_bss *bss, |
3931 | const u8 *buf, size_t len); | 3958 | const u8 *buf, size_t len, |
3959 | int uapsd_queues); | ||
3932 | 3960 | ||
3933 | /** | 3961 | /** |
3934 | * cfg80211_assoc_timeout - notification of timed out association | 3962 | * cfg80211_assoc_timeout - notification of timed out association |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c9b2bec8db47..0ad1f47d2dc7 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright 2002-2005, Devicescape Software, Inc. | 4 | * Copyright 2002-2005, Devicescape Software, Inc. |
5 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 5 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
6 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
@@ -1536,16 +1537,6 @@ struct ieee80211_tx_control { | |||
1536 | * @IEEE80211_HW_MFP_CAPABLE: | 1537 | * @IEEE80211_HW_MFP_CAPABLE: |
1537 | * Hardware supports management frame protection (MFP, IEEE 802.11w). | 1538 | * Hardware supports management frame protection (MFP, IEEE 802.11w). |
1538 | * | 1539 | * |
1539 | * @IEEE80211_HW_SUPPORTS_STATIC_SMPS: | ||
1540 | * Hardware supports static spatial multiplexing powersave, | ||
1541 | * ie. can turn off all but one chain even on HT connections | ||
1542 | * that should be using more chains. | ||
1543 | * | ||
1544 | * @IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS: | ||
1545 | * Hardware supports dynamic spatial multiplexing powersave, | ||
1546 | * ie. can turn off all but one chain and then wake the rest | ||
1547 | * up as required after, for example, rts/cts handshake. | ||
1548 | * | ||
1549 | * @IEEE80211_HW_SUPPORTS_UAPSD: | 1540 | * @IEEE80211_HW_SUPPORTS_UAPSD: |
1550 | * Hardware supports Unscheduled Automatic Power Save Delivery | 1541 | * Hardware supports Unscheduled Automatic Power Save Delivery |
1551 | * (U-APSD) in managed mode. The mode is configured with | 1542 | * (U-APSD) in managed mode. The mode is configured with |
@@ -1631,8 +1622,7 @@ enum ieee80211_hw_flags { | |||
1631 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, | 1622 | IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, |
1632 | IEEE80211_HW_MFP_CAPABLE = 1<<13, | 1623 | IEEE80211_HW_MFP_CAPABLE = 1<<13, |
1633 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, | 1624 | IEEE80211_HW_WANT_MONITOR_VIF = 1<<14, |
1634 | IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, | 1625 | /* free slots */ |
1635 | IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, | ||
1636 | IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, | 1626 | IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, |
1637 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, | 1627 | IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, |
1638 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, | 1628 | IEEE80211_HW_CONNECTION_MONITOR = 1<<19, |
@@ -2672,7 +2662,9 @@ enum ieee80211_roc_type { | |||
2672 | * | 2662 | * |
2673 | * @set_coverage_class: Set slot time for given coverage class as specified | 2663 | * @set_coverage_class: Set slot time for given coverage class as specified |
2674 | * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout | 2664 | * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout |
2675 | * accordingly. This callback is not required and may sleep. | 2665 | * accordingly; coverage class equals to -1 to enable ACK timeout |
2666 | * estimation algorithm (dynack). To disable dynack set valid value for | ||
2667 | * coverage class. This callback is not required and may sleep. | ||
2676 | * | 2668 | * |
2677 | * @testmode_cmd: Implement a cfg80211 test mode command. The passed @vif may | 2669 | * @testmode_cmd: Implement a cfg80211 test mode command. The passed @vif may |
2678 | * be %NULL. The callback can sleep. | 2670 | * be %NULL. The callback can sleep. |
@@ -2956,7 +2948,7 @@ struct ieee80211_ops { | |||
2956 | int (*get_survey)(struct ieee80211_hw *hw, int idx, | 2948 | int (*get_survey)(struct ieee80211_hw *hw, int idx, |
2957 | struct survey_info *survey); | 2949 | struct survey_info *survey); |
2958 | void (*rfkill_poll)(struct ieee80211_hw *hw); | 2950 | void (*rfkill_poll)(struct ieee80211_hw *hw); |
2959 | void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class); | 2951 | void (*set_coverage_class)(struct ieee80211_hw *hw, s16 coverage_class); |
2960 | #ifdef CONFIG_NL80211_TESTMODE | 2952 | #ifdef CONFIG_NL80211_TESTMODE |
2961 | int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2953 | int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2962 | void *data, int len); | 2954 | void *data, int len); |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index d097568da690..4b28dc07bcb1 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -722,6 +722,22 @@ | |||
722 | * QoS mapping is relevant for IP packets, it is only valid during an | 722 | * QoS mapping is relevant for IP packets, it is only valid during an |
723 | * association. This is cleared on disassociation and AP restart. | 723 | * association. This is cleared on disassociation and AP restart. |
724 | * | 724 | * |
725 | * @NL80211_CMD_ADD_TX_TS: Ask the kernel to add a traffic stream for the given | ||
726 | * %NL80211_ATTR_TSID and %NL80211_ATTR_MAC with %NL80211_ATTR_USER_PRIO | ||
727 | * and %NL80211_ATTR_ADMITTED_TIME parameters. | ||
728 | * Note that the action frame handshake with the AP shall be handled by | ||
729 | * userspace via the normal management RX/TX framework, this only sets | ||
730 | * up the TX TS in the driver/device. | ||
731 | * If the admitted time attribute is not added then the request just checks | ||
732 | * if a subsequent setup could be successful, the intent is to use this to | ||
733 | * avoid setting up a session with the AP when local restrictions would | ||
734 | * make that impossible. However, the subsequent "real" setup may still | ||
735 | * fail even if the check was successful. | ||
736 | * @NL80211_CMD_DEL_TX_TS: Remove an existing TS with the %NL80211_ATTR_TSID | ||
737 | * and %NL80211_ATTR_MAC parameters. It isn't necessary to call this | ||
738 | * before removing a station entry entirely, or before disassociating | ||
739 | * or similar, cleanup will happen in the driver/device in this case. | ||
740 | * | ||
725 | * @NL80211_CMD_MAX: highest used command number | 741 | * @NL80211_CMD_MAX: highest used command number |
726 | * @__NL80211_CMD_AFTER_LAST: internal use | 742 | * @__NL80211_CMD_AFTER_LAST: internal use |
727 | */ | 743 | */ |
@@ -893,6 +909,9 @@ enum nl80211_commands { | |||
893 | 909 | ||
894 | NL80211_CMD_SET_QOS_MAP, | 910 | NL80211_CMD_SET_QOS_MAP, |
895 | 911 | ||
912 | NL80211_CMD_ADD_TX_TS, | ||
913 | NL80211_CMD_DEL_TX_TS, | ||
914 | |||
896 | /* add new commands above here */ | 915 | /* add new commands above here */ |
897 | 916 | ||
898 | /* used to define NL80211_CMD_MAX below */ | 917 | /* used to define NL80211_CMD_MAX below */ |
@@ -1594,6 +1613,31 @@ enum nl80211_commands { | |||
1594 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is | 1613 | * @NL80211_ATTR_TDLS_INITIATOR: flag attribute indicating the current end is |
1595 | * the TDLS link initiator. | 1614 | * the TDLS link initiator. |
1596 | * | 1615 | * |
1616 | * @NL80211_ATTR_USE_RRM: flag for indicating whether the current connection | ||
1617 | * shall support Radio Resource Measurements (11k). This attribute can be | ||
1618 | * used with %NL80211_CMD_ASSOCIATE and %NL80211_CMD_CONNECT requests. | ||
1619 | * User space applications are expected to use this flag only if the | ||
1620 | * underlying device supports these minimal RRM features: | ||
1621 | * %NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES, | ||
1622 | * %NL80211_FEATURE_QUIET, | ||
1623 | * If this flag is used, driver must add the Power Capabilities IE to the | ||
1624 | * association request. In addition, it must also set the RRM capability | ||
1625 | * flag in the association request's Capability Info field. | ||
1626 | * | ||
1627 | * @NL80211_ATTR_WIPHY_DYN_ACK: flag attribute used to enable ACK timeout | ||
1628 | * estimation algorithm (dynack). In order to activate dynack | ||
1629 | * %NL80211_FEATURE_ACKTO_ESTIMATION feature flag must be set by lower | ||
1630 | * drivers to indicate dynack capability. Dynack is automatically disabled | ||
1631 | * setting valid value for coverage class. | ||
1632 | * | ||
1633 | * @NL80211_ATTR_TSID: a TSID value (u8 attribute) | ||
1634 | * @NL80211_ATTR_USER_PRIO: user priority value (u8 attribute) | ||
1635 | * @NL80211_ATTR_ADMITTED_TIME: admitted time in units of 32 microseconds | ||
1636 | * (per second) (u16 attribute) | ||
1637 | * | ||
1638 | * @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see | ||
1639 | * &enum nl80211_smps_mode. | ||
1640 | * | ||
1597 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1641 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1598 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1642 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1599 | */ | 1643 | */ |
@@ -1936,6 +1980,16 @@ enum nl80211_attrs { | |||
1936 | 1980 | ||
1937 | NL80211_ATTR_TDLS_INITIATOR, | 1981 | NL80211_ATTR_TDLS_INITIATOR, |
1938 | 1982 | ||
1983 | NL80211_ATTR_USE_RRM, | ||
1984 | |||
1985 | NL80211_ATTR_WIPHY_DYN_ACK, | ||
1986 | |||
1987 | NL80211_ATTR_TSID, | ||
1988 | NL80211_ATTR_USER_PRIO, | ||
1989 | NL80211_ATTR_ADMITTED_TIME, | ||
1990 | |||
1991 | NL80211_ATTR_SMPS_MODE, | ||
1992 | |||
1939 | /* add attributes here, update the policy in nl80211.c */ | 1993 | /* add attributes here, update the policy in nl80211.c */ |
1940 | 1994 | ||
1941 | __NL80211_ATTR_AFTER_LAST, | 1995 | __NL80211_ATTR_AFTER_LAST, |
@@ -3968,6 +4022,26 @@ enum nl80211_ap_sme_features { | |||
3968 | * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic | 4022 | * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic |
3969 | * channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the | 4023 | * channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the |
3970 | * lifetime of a BSS. | 4024 | * lifetime of a BSS. |
4025 | * @NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES: This device adds a DS Parameter | ||
4026 | * Set IE to probe requests. | ||
4027 | * @NL80211_FEATURE_WFA_TPC_IE_IN_PROBES: This device adds a WFA TPC Report IE | ||
4028 | * to probe requests. | ||
4029 | * @NL80211_FEATURE_QUIET: This device, in client mode, supports Quiet Period | ||
4030 | * requests sent to it by an AP. | ||
4031 | * @NL80211_FEATURE_TX_POWER_INSERTION: This device is capable of inserting the | ||
4032 | * current tx power value into the TPC Report IE in the spectrum | ||
4033 | * management TPC Report action frame, and in the Radio Measurement Link | ||
4034 | * Measurement Report action frame. | ||
4035 | * @NL80211_FEATURE_ACKTO_ESTIMATION: This driver supports dynamic ACK timeout | ||
4036 | * estimation (dynack). %NL80211_ATTR_WIPHY_DYN_ACK flag attribute is used | ||
4037 | * to enable dynack. | ||
4038 | * @NL80211_FEATURE_STATIC_SMPS: Device supports static spatial | ||
4039 | * multiplexing powersave, ie. can turn off all but one chain | ||
4040 | * even on HT connections that should be using more chains. | ||
4041 | * @NL80211_FEATURE_DYNAMIC_SMPS: Device supports dynamic spatial | ||
4042 | * multiplexing powersave, ie. can turn off all but one chain | ||
4043 | * and then wake the rest up as required after, for example, | ||
4044 | * rts/cts handshake. | ||
3971 | */ | 4045 | */ |
3972 | enum nl80211_feature_flags { | 4046 | enum nl80211_feature_flags { |
3973 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 4047 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
@@ -3989,6 +4063,13 @@ enum nl80211_feature_flags { | |||
3989 | NL80211_FEATURE_USERSPACE_MPM = 1 << 16, | 4063 | NL80211_FEATURE_USERSPACE_MPM = 1 << 16, |
3990 | NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17, | 4064 | NL80211_FEATURE_ACTIVE_MONITOR = 1 << 17, |
3991 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18, | 4065 | NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE = 1 << 18, |
4066 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES = 1 << 19, | ||
4067 | NL80211_FEATURE_WFA_TPC_IE_IN_PROBES = 1 << 20, | ||
4068 | NL80211_FEATURE_QUIET = 1 << 21, | ||
4069 | NL80211_FEATURE_TX_POWER_INSERTION = 1 << 22, | ||
4070 | NL80211_FEATURE_ACKTO_ESTIMATION = 1 << 23, | ||
4071 | NL80211_FEATURE_STATIC_SMPS = 1 << 24, | ||
4072 | NL80211_FEATURE_DYNAMIC_SMPS = 1 << 25, | ||
3992 | }; | 4073 | }; |
3993 | 4074 | ||
3994 | /** | 4075 | /** |
@@ -4063,6 +4144,25 @@ enum nl80211_acl_policy { | |||
4063 | }; | 4144 | }; |
4064 | 4145 | ||
4065 | /** | 4146 | /** |
4147 | * enum nl80211_smps_mode - SMPS mode | ||
4148 | * | ||
4149 | * Requested SMPS mode (for AP mode) | ||
4150 | * | ||
4151 | * @NL80211_SMPS_OFF: SMPS off (use all antennas). | ||
4152 | * @NL80211_SMPS_STATIC: static SMPS (use a single antenna) | ||
4153 | * @NL80211_SMPS_DYNAMIC: dynamic smps (start with a single antenna and | ||
4154 | * turn on other antennas after CTS/RTS). | ||
4155 | */ | ||
4156 | enum nl80211_smps_mode { | ||
4157 | NL80211_SMPS_OFF, | ||
4158 | NL80211_SMPS_STATIC, | ||
4159 | NL80211_SMPS_DYNAMIC, | ||
4160 | |||
4161 | __NL80211_SMPS_AFTER_LAST, | ||
4162 | NL80211_SMPS_MAX = __NL80211_SMPS_AFTER_LAST - 1 | ||
4163 | }; | ||
4164 | |||
4165 | /** | ||
4066 | * enum nl80211_radar_event - type of radar event for DFS operation | 4166 | * enum nl80211_radar_event - type of radar event for DFS operation |
4067 | * | 4167 | * |
4068 | * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace | 4168 | * Type of event to be used with NL80211_ATTR_RADAR_EVENT to inform userspace |
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c index 35ebe79c87b0..0920cb6ed572 100644 --- a/net/bluetooth/6lowpan.c +++ b/net/bluetooth/6lowpan.c | |||
@@ -39,6 +39,7 @@ static struct dentry *lowpan_control_debugfs; | |||
39 | 39 | ||
40 | struct skb_cb { | 40 | struct skb_cb { |
41 | struct in6_addr addr; | 41 | struct in6_addr addr; |
42 | struct in6_addr gw; | ||
42 | struct l2cap_chan *chan; | 43 | struct l2cap_chan *chan; |
43 | int status; | 44 | int status; |
44 | }; | 45 | }; |
@@ -158,6 +159,54 @@ static inline struct lowpan_peer *peer_lookup_conn(struct lowpan_dev *dev, | |||
158 | return NULL; | 159 | return NULL; |
159 | } | 160 | } |
160 | 161 | ||
162 | static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_dev *dev, | ||
163 | struct in6_addr *daddr, | ||
164 | struct sk_buff *skb) | ||
165 | { | ||
166 | struct lowpan_peer *peer, *tmp; | ||
167 | struct in6_addr *nexthop; | ||
168 | struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); | ||
169 | int count = atomic_read(&dev->peer_count); | ||
170 | |||
171 | BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt); | ||
172 | |||
173 | /* If we have multiple 6lowpan peers, then check where we should | ||
174 | * send the packet. If only one peer exists, then we can send the | ||
175 | * packet right away. | ||
176 | */ | ||
177 | if (count == 1) | ||
178 | return list_first_entry(&dev->peers, struct lowpan_peer, | ||
179 | list); | ||
180 | |||
181 | if (!rt) { | ||
182 | nexthop = &lowpan_cb(skb)->gw; | ||
183 | |||
184 | if (ipv6_addr_any(nexthop)) | ||
185 | return NULL; | ||
186 | } else { | ||
187 | nexthop = rt6_nexthop(rt); | ||
188 | |||
189 | /* We need to remember the address because it is needed | ||
190 | * by bt_xmit() when sending the packet. In bt_xmit(), the | ||
191 | * destination routing info is not set. | ||
192 | */ | ||
193 | memcpy(&lowpan_cb(skb)->gw, nexthop, sizeof(struct in6_addr)); | ||
194 | } | ||
195 | |||
196 | BT_DBG("gw %pI6c", nexthop); | ||
197 | |||
198 | list_for_each_entry_safe(peer, tmp, &dev->peers, list) { | ||
199 | BT_DBG("dst addr %pMR dst type %d ip %pI6c", | ||
200 | &peer->chan->dst, peer->chan->dst_type, | ||
201 | &peer->peer_addr); | ||
202 | |||
203 | if (!ipv6_addr_cmp(&peer->peer_addr, nexthop)) | ||
204 | return peer; | ||
205 | } | ||
206 | |||
207 | return NULL; | ||
208 | } | ||
209 | |||
161 | static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) | 210 | static struct lowpan_peer *lookup_peer(struct l2cap_conn *conn) |
162 | { | 211 | { |
163 | struct lowpan_dev *entry, *tmp; | 212 | struct lowpan_dev *entry, *tmp; |
@@ -415,8 +464,18 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev, | |||
415 | read_unlock_irqrestore(&devices_lock, flags); | 464 | read_unlock_irqrestore(&devices_lock, flags); |
416 | 465 | ||
417 | if (!peer) { | 466 | if (!peer) { |
418 | BT_DBG("no such peer %pMR found", &addr); | 467 | /* The packet might be sent to 6lowpan interface |
419 | return -ENOENT; | 468 | * because of routing (either via default route |
469 | * or user set route) so get peer according to | ||
470 | * the destination address. | ||
471 | */ | ||
472 | read_lock_irqsave(&devices_lock, flags); | ||
473 | peer = peer_lookup_dst(dev, &hdr->daddr, skb); | ||
474 | read_unlock_irqrestore(&devices_lock, flags); | ||
475 | if (!peer) { | ||
476 | BT_DBG("no such peer %pMR found", &addr); | ||
477 | return -ENOENT; | ||
478 | } | ||
420 | } | 479 | } |
421 | 480 | ||
422 | daddr = peer->eui64_addr; | 481 | daddr = peer->eui64_addr; |
@@ -520,6 +579,8 @@ static netdev_tx_t bt_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
520 | 579 | ||
521 | read_lock_irqsave(&devices_lock, flags); | 580 | read_lock_irqsave(&devices_lock, flags); |
522 | peer = peer_lookup_ba(dev, &addr, addr_type); | 581 | peer = peer_lookup_ba(dev, &addr, addr_type); |
582 | if (!peer) | ||
583 | peer = peer_lookup_dst(dev, &lowpan_cb(skb)->addr, skb); | ||
523 | read_unlock_irqrestore(&devices_lock, flags); | 584 | read_unlock_irqrestore(&devices_lock, flags); |
524 | 585 | ||
525 | BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p", | 586 | BT_DBG("xmit %s to %pMR type %d IP %pI6c peer %p", |
@@ -671,6 +732,14 @@ static struct l2cap_chan *chan_open(struct l2cap_chan *pchan) | |||
671 | return chan; | 732 | return chan; |
672 | } | 733 | } |
673 | 734 | ||
735 | static void set_ip_addr_bits(u8 addr_type, u8 *addr) | ||
736 | { | ||
737 | if (addr_type == BDADDR_LE_PUBLIC) | ||
738 | *addr |= 0x02; | ||
739 | else | ||
740 | *addr &= ~0x02; | ||
741 | } | ||
742 | |||
674 | static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, | 743 | static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, |
675 | struct lowpan_dev *dev) | 744 | struct lowpan_dev *dev) |
676 | { | 745 | { |
@@ -693,6 +762,11 @@ static struct l2cap_chan *add_peer_chan(struct l2cap_chan *chan, | |||
693 | memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, | 762 | memcpy(&peer->eui64_addr, (u8 *)&peer->peer_addr.s6_addr + 8, |
694 | EUI64_ADDR_LEN); | 763 | EUI64_ADDR_LEN); |
695 | 764 | ||
765 | /* IPv6 address needs to have the U/L bit set properly so toggle | ||
766 | * it back here. | ||
767 | */ | ||
768 | set_ip_addr_bits(chan->dst_type, (u8 *)&peer->peer_addr.s6_addr + 8); | ||
769 | |||
696 | write_lock_irqsave(&devices_lock, flags); | 770 | write_lock_irqsave(&devices_lock, flags); |
697 | INIT_LIST_HEAD(&peer->list); | 771 | INIT_LIST_HEAD(&peer->list); |
698 | peer_add(dev, peer); | 772 | peer_add(dev, peer); |
@@ -890,7 +964,7 @@ static void chan_resume_cb(struct l2cap_chan *chan) | |||
890 | 964 | ||
891 | static long chan_get_sndtimeo_cb(struct l2cap_chan *chan) | 965 | static long chan_get_sndtimeo_cb(struct l2cap_chan *chan) |
892 | { | 966 | { |
893 | return msecs_to_jiffies(1000); | 967 | return L2CAP_CONN_TIMEOUT; |
894 | } | 968 | } |
895 | 969 | ||
896 | static const struct l2cap_ops bt_6lowpan_chan_ops = { | 970 | static const struct l2cap_ops bt_6lowpan_chan_ops = { |
diff --git a/net/bluetooth/amp.c b/net/bluetooth/amp.c index 016cdb66df6c..2640d78f30b8 100644 --- a/net/bluetooth/amp.c +++ b/net/bluetooth/amp.c | |||
@@ -149,15 +149,14 @@ static int hmac_sha256(u8 *key, u8 ksize, char *plaintext, u8 psize, u8 *output) | |||
149 | if (ret) { | 149 | if (ret) { |
150 | BT_DBG("crypto_ahash_setkey failed: err %d", ret); | 150 | BT_DBG("crypto_ahash_setkey failed: err %d", ret); |
151 | } else { | 151 | } else { |
152 | struct { | 152 | char desc[sizeof(struct shash_desc) + |
153 | struct shash_desc shash; | 153 | crypto_shash_descsize(tfm)] CRYPTO_MINALIGN_ATTR; |
154 | char ctx[crypto_shash_descsize(tfm)]; | 154 | struct shash_desc *shash = (struct shash_desc *)desc; |
155 | } desc; | ||
156 | 155 | ||
157 | desc.shash.tfm = tfm; | 156 | shash->tfm = tfm; |
158 | desc.shash.flags = CRYPTO_TFM_REQ_MAY_SLEEP; | 157 | shash->flags = CRYPTO_TFM_REQ_MAY_SLEEP; |
159 | 158 | ||
160 | ret = crypto_shash_digest(&desc.shash, plaintext, psize, | 159 | ret = crypto_shash_digest(shash, plaintext, psize, |
161 | output); | 160 | output); |
162 | } | 161 | } |
163 | 162 | ||
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index faff6247ac8f..e3d7ae9e2edd 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -122,17 +122,30 @@ static void hci_reject_sco(struct hci_conn *conn) | |||
122 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); | 122 | hci_send_cmd(conn->hdev, HCI_OP_REJECT_SYNC_CONN_REQ, sizeof(cp), &cp); |
123 | } | 123 | } |
124 | 124 | ||
125 | void hci_disconnect(struct hci_conn *conn, __u8 reason) | 125 | int hci_disconnect(struct hci_conn *conn, __u8 reason) |
126 | { | 126 | { |
127 | struct hci_cp_disconnect cp; | 127 | struct hci_cp_disconnect cp; |
128 | 128 | ||
129 | BT_DBG("hcon %p", conn); | 129 | BT_DBG("hcon %p", conn); |
130 | 130 | ||
131 | /* When we are master of an established connection and it enters | ||
132 | * the disconnect timeout, then go ahead and try to read the | ||
133 | * current clock offset. Processing of the result is done | ||
134 | * within the event handling and hci_clock_offset_evt function. | ||
135 | */ | ||
136 | if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { | ||
137 | struct hci_dev *hdev = conn->hdev; | ||
138 | struct hci_cp_read_clock_offset cp; | ||
139 | |||
140 | cp.handle = cpu_to_le16(conn->handle); | ||
141 | hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, sizeof(cp), &cp); | ||
142 | } | ||
143 | |||
131 | conn->state = BT_DISCONN; | 144 | conn->state = BT_DISCONN; |
132 | 145 | ||
133 | cp.handle = cpu_to_le16(conn->handle); | 146 | cp.handle = cpu_to_le16(conn->handle); |
134 | cp.reason = reason; | 147 | cp.reason = reason; |
135 | hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); | 148 | return hci_send_cmd(conn->hdev, HCI_OP_DISCONNECT, sizeof(cp), &cp); |
136 | } | 149 | } |
137 | 150 | ||
138 | static void hci_amp_disconn(struct hci_conn *conn) | 151 | static void hci_amp_disconn(struct hci_conn *conn) |
@@ -325,25 +338,6 @@ static void hci_conn_timeout(struct work_struct *work) | |||
325 | hci_amp_disconn(conn); | 338 | hci_amp_disconn(conn); |
326 | } else { | 339 | } else { |
327 | __u8 reason = hci_proto_disconn_ind(conn); | 340 | __u8 reason = hci_proto_disconn_ind(conn); |
328 | |||
329 | /* When we are master of an established connection | ||
330 | * and it enters the disconnect timeout, then go | ||
331 | * ahead and try to read the current clock offset. | ||
332 | * | ||
333 | * Processing of the result is done within the | ||
334 | * event handling and hci_clock_offset_evt function. | ||
335 | */ | ||
336 | if (conn->type == ACL_LINK && | ||
337 | conn->role == HCI_ROLE_MASTER) { | ||
338 | struct hci_dev *hdev = conn->hdev; | ||
339 | struct hci_cp_read_clock_offset cp; | ||
340 | |||
341 | cp.handle = cpu_to_le16(conn->handle); | ||
342 | |||
343 | hci_send_cmd(hdev, HCI_OP_READ_CLOCK_OFFSET, | ||
344 | sizeof(cp), &cp); | ||
345 | } | ||
346 | |||
347 | hci_disconnect(conn, reason); | 341 | hci_disconnect(conn, reason); |
348 | } | 342 | } |
349 | break; | 343 | break; |
@@ -595,6 +589,7 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) | |||
595 | conn->dst_type); | 589 | conn->dst_type); |
596 | if (params && params->conn) { | 590 | if (params && params->conn) { |
597 | hci_conn_drop(params->conn); | 591 | hci_conn_drop(params->conn); |
592 | hci_conn_put(params->conn); | ||
598 | params->conn = NULL; | 593 | params->conn = NULL; |
599 | } | 594 | } |
600 | 595 | ||
@@ -1290,11 +1285,16 @@ struct hci_chan *hci_chan_create(struct hci_conn *conn) | |||
1290 | 1285 | ||
1291 | BT_DBG("%s hcon %p", hdev->name, conn); | 1286 | BT_DBG("%s hcon %p", hdev->name, conn); |
1292 | 1287 | ||
1288 | if (test_bit(HCI_CONN_DROP, &conn->flags)) { | ||
1289 | BT_DBG("Refusing to create new hci_chan"); | ||
1290 | return NULL; | ||
1291 | } | ||
1292 | |||
1293 | chan = kzalloc(sizeof(*chan), GFP_KERNEL); | 1293 | chan = kzalloc(sizeof(*chan), GFP_KERNEL); |
1294 | if (!chan) | 1294 | if (!chan) |
1295 | return NULL; | 1295 | return NULL; |
1296 | 1296 | ||
1297 | chan->conn = conn; | 1297 | chan->conn = hci_conn_get(conn); |
1298 | skb_queue_head_init(&chan->data_q); | 1298 | skb_queue_head_init(&chan->data_q); |
1299 | chan->state = BT_CONNECTED; | 1299 | chan->state = BT_CONNECTED; |
1300 | 1300 | ||
@@ -1314,7 +1314,10 @@ void hci_chan_del(struct hci_chan *chan) | |||
1314 | 1314 | ||
1315 | synchronize_rcu(); | 1315 | synchronize_rcu(); |
1316 | 1316 | ||
1317 | hci_conn_drop(conn); | 1317 | /* Prevent new hci_chan's to be created for this hci_conn */ |
1318 | set_bit(HCI_CONN_DROP, &conn->flags); | ||
1319 | |||
1320 | hci_conn_put(conn); | ||
1318 | 1321 | ||
1319 | skb_queue_purge(&chan->data_q); | 1322 | skb_queue_purge(&chan->data_q); |
1320 | kfree(chan); | 1323 | kfree(chan); |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 9b7145959a49..067526d9680d 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -2541,6 +2541,7 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev) | |||
2541 | list_for_each_entry(p, &hdev->le_conn_params, list) { | 2541 | list_for_each_entry(p, &hdev->le_conn_params, list) { |
2542 | if (p->conn) { | 2542 | if (p->conn) { |
2543 | hci_conn_drop(p->conn); | 2543 | hci_conn_drop(p->conn); |
2544 | hci_conn_put(p->conn); | ||
2544 | p->conn = NULL; | 2545 | p->conn = NULL; |
2545 | } | 2546 | } |
2546 | list_del_init(&p->action); | 2547 | list_del_init(&p->action); |
@@ -3725,6 +3726,18 @@ int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type, | |||
3725 | return 0; | 3726 | return 0; |
3726 | } | 3727 | } |
3727 | 3728 | ||
3729 | static void hci_conn_params_free(struct hci_conn_params *params) | ||
3730 | { | ||
3731 | if (params->conn) { | ||
3732 | hci_conn_drop(params->conn); | ||
3733 | hci_conn_put(params->conn); | ||
3734 | } | ||
3735 | |||
3736 | list_del(¶ms->action); | ||
3737 | list_del(¶ms->list); | ||
3738 | kfree(params); | ||
3739 | } | ||
3740 | |||
3728 | /* This function requires the caller holds hdev->lock */ | 3741 | /* This function requires the caller holds hdev->lock */ |
3729 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) | 3742 | void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) |
3730 | { | 3743 | { |
@@ -3734,12 +3747,7 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type) | |||
3734 | if (!params) | 3747 | if (!params) |
3735 | return; | 3748 | return; |
3736 | 3749 | ||
3737 | if (params->conn) | 3750 | hci_conn_params_free(params); |
3738 | hci_conn_drop(params->conn); | ||
3739 | |||
3740 | list_del(¶ms->action); | ||
3741 | list_del(¶ms->list); | ||
3742 | kfree(params); | ||
3743 | 3751 | ||
3744 | hci_update_background_scan(hdev); | 3752 | hci_update_background_scan(hdev); |
3745 | 3753 | ||
@@ -3766,13 +3774,8 @@ void hci_conn_params_clear_all(struct hci_dev *hdev) | |||
3766 | { | 3774 | { |
3767 | struct hci_conn_params *params, *tmp; | 3775 | struct hci_conn_params *params, *tmp; |
3768 | 3776 | ||
3769 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) { | 3777 | list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) |
3770 | if (params->conn) | 3778 | hci_conn_params_free(params); |
3771 | hci_conn_drop(params->conn); | ||
3772 | list_del(¶ms->action); | ||
3773 | list_del(¶ms->list); | ||
3774 | kfree(params); | ||
3775 | } | ||
3776 | 3779 | ||
3777 | hci_update_background_scan(hdev); | 3780 | hci_update_background_scan(hdev); |
3778 | 3781 | ||
@@ -3869,6 +3872,7 @@ static void set_random_addr(struct hci_request *req, bdaddr_t *rpa) | |||
3869 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || | 3872 | if (test_bit(HCI_LE_ADV, &hdev->dev_flags) || |
3870 | hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { | 3873 | hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT)) { |
3871 | BT_DBG("Deferring random address update"); | 3874 | BT_DBG("Deferring random address update"); |
3875 | set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); | ||
3872 | return; | 3876 | return; |
3873 | } | 3877 | } |
3874 | 3878 | ||
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 3a99f30a3317..8b0a2a6de419 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -2320,8 +2320,7 @@ static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2320 | conn->sec_level = conn->pending_sec_level; | 2320 | conn->sec_level = conn->pending_sec_level; |
2321 | } | 2321 | } |
2322 | } else { | 2322 | } else { |
2323 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 2323 | mgmt_auth_failed(conn, ev->status); |
2324 | ev->status); | ||
2325 | } | 2324 | } |
2326 | 2325 | ||
2327 | clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); | 2326 | clear_bit(HCI_CONN_AUTH_PEND, &conn->flags); |
@@ -2439,6 +2438,12 @@ static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2439 | } | 2438 | } |
2440 | } | 2439 | } |
2441 | 2440 | ||
2441 | /* We should disregard the current RPA and generate a new one | ||
2442 | * whenever the encryption procedure fails. | ||
2443 | */ | ||
2444 | if (ev->status && conn->type == LE_LINK) | ||
2445 | set_bit(HCI_RPA_EXPIRED, &hdev->dev_flags); | ||
2446 | |||
2442 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | 2447 | clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); |
2443 | 2448 | ||
2444 | if (ev->status && conn->state == BT_CONNECTED) { | 2449 | if (ev->status && conn->state == BT_CONNECTED) { |
@@ -3900,8 +3905,7 @@ static void hci_simple_pair_complete_evt(struct hci_dev *hdev, | |||
3900 | * event gets always produced as initiator and is also mapped to | 3905 | * event gets always produced as initiator and is also mapped to |
3901 | * the mgmt_auth_failed event */ | 3906 | * the mgmt_auth_failed event */ |
3902 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) | 3907 | if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status) |
3903 | mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type, | 3908 | mgmt_auth_failed(conn, ev->status); |
3904 | ev->status); | ||
3905 | 3909 | ||
3906 | hci_conn_drop(conn); | 3910 | hci_conn_drop(conn); |
3907 | 3911 | ||
@@ -4193,16 +4197,16 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4193 | conn->dst_type = irk->addr_type; | 4197 | conn->dst_type = irk->addr_type; |
4194 | } | 4198 | } |
4195 | 4199 | ||
4196 | if (conn->dst_type == ADDR_LE_DEV_PUBLIC) | ||
4197 | addr_type = BDADDR_LE_PUBLIC; | ||
4198 | else | ||
4199 | addr_type = BDADDR_LE_RANDOM; | ||
4200 | |||
4201 | if (ev->status) { | 4200 | if (ev->status) { |
4202 | hci_le_conn_failed(conn, ev->status); | 4201 | hci_le_conn_failed(conn, ev->status); |
4203 | goto unlock; | 4202 | goto unlock; |
4204 | } | 4203 | } |
4205 | 4204 | ||
4205 | if (conn->dst_type == ADDR_LE_DEV_PUBLIC) | ||
4206 | addr_type = BDADDR_LE_PUBLIC; | ||
4207 | else | ||
4208 | addr_type = BDADDR_LE_RANDOM; | ||
4209 | |||
4206 | /* Drop the connection if the device is blocked */ | 4210 | /* Drop the connection if the device is blocked */ |
4207 | if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { | 4211 | if (hci_bdaddr_list_lookup(&hdev->blacklist, &conn->dst, addr_type)) { |
4208 | hci_conn_drop(conn); | 4212 | hci_conn_drop(conn); |
@@ -4225,11 +4229,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4225 | 4229 | ||
4226 | hci_proto_connect_cfm(conn, ev->status); | 4230 | hci_proto_connect_cfm(conn, ev->status); |
4227 | 4231 | ||
4228 | params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type); | 4232 | params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst, |
4233 | conn->dst_type); | ||
4229 | if (params) { | 4234 | if (params) { |
4230 | list_del_init(¶ms->action); | 4235 | list_del_init(¶ms->action); |
4231 | if (params->conn) { | 4236 | if (params->conn) { |
4232 | hci_conn_drop(params->conn); | 4237 | hci_conn_drop(params->conn); |
4238 | hci_conn_put(params->conn); | ||
4233 | params->conn = NULL; | 4239 | params->conn = NULL; |
4234 | } | 4240 | } |
4235 | } | 4241 | } |
@@ -4321,7 +4327,7 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr, | |||
4321 | * the parameters get removed and keep the reference | 4327 | * the parameters get removed and keep the reference |
4322 | * count consistent once the connection is established. | 4328 | * count consistent once the connection is established. |
4323 | */ | 4329 | */ |
4324 | params->conn = conn; | 4330 | params->conn = hci_conn_get(conn); |
4325 | return; | 4331 | return; |
4326 | } | 4332 | } |
4327 | 4333 | ||
@@ -4506,10 +4512,7 @@ static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
4506 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); | 4512 | memcpy(cp.ltk, ltk->val, sizeof(ltk->val)); |
4507 | cp.handle = cpu_to_le16(conn->handle); | 4513 | cp.handle = cpu_to_le16(conn->handle); |
4508 | 4514 | ||
4509 | if (ltk->authenticated) | 4515 | conn->pending_sec_level = smp_ltk_sec_level(ltk); |
4510 | conn->pending_sec_level = BT_SECURITY_HIGH; | ||
4511 | else | ||
4512 | conn->pending_sec_level = BT_SECURITY_MEDIUM; | ||
4513 | 4516 | ||
4514 | conn->enc_key_size = ltk->enc_size; | 4517 | conn->enc_key_size = ltk->enc_size; |
4515 | 4518 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 6c7ecf116e74..1b7d605706aa 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -915,7 +915,7 @@ static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, | |||
915 | 915 | ||
916 | /* connection management */ | 916 | /* connection management */ |
917 | bacpy(&session->bdaddr, bdaddr); | 917 | bacpy(&session->bdaddr, bdaddr); |
918 | session->conn = conn; | 918 | session->conn = l2cap_conn_get(conn); |
919 | session->user.probe = hidp_session_probe; | 919 | session->user.probe = hidp_session_probe; |
920 | session->user.remove = hidp_session_remove; | 920 | session->user.remove = hidp_session_remove; |
921 | session->ctrl_sock = ctrl_sock; | 921 | session->ctrl_sock = ctrl_sock; |
@@ -941,13 +941,13 @@ static int hidp_session_new(struct hidp_session **out, const bdaddr_t *bdaddr, | |||
941 | if (ret) | 941 | if (ret) |
942 | goto err_free; | 942 | goto err_free; |
943 | 943 | ||
944 | l2cap_conn_get(session->conn); | ||
945 | get_file(session->intr_sock->file); | 944 | get_file(session->intr_sock->file); |
946 | get_file(session->ctrl_sock->file); | 945 | get_file(session->ctrl_sock->file); |
947 | *out = session; | 946 | *out = session; |
948 | return 0; | 947 | return 0; |
949 | 948 | ||
950 | err_free: | 949 | err_free: |
950 | l2cap_conn_put(session->conn); | ||
951 | kfree(session); | 951 | kfree(session); |
952 | return ret; | 952 | return ret; |
953 | } | 953 | } |
@@ -1327,10 +1327,8 @@ int hidp_connection_add(struct hidp_connadd_req *req, | |||
1327 | 1327 | ||
1328 | conn = NULL; | 1328 | conn = NULL; |
1329 | l2cap_chan_lock(chan); | 1329 | l2cap_chan_lock(chan); |
1330 | if (chan->conn) { | 1330 | if (chan->conn) |
1331 | l2cap_conn_get(chan->conn); | 1331 | conn = l2cap_conn_get(chan->conn); |
1332 | conn = chan->conn; | ||
1333 | } | ||
1334 | l2cap_chan_unlock(chan); | 1332 | l2cap_chan_unlock(chan); |
1335 | 1333 | ||
1336 | if (!conn) | 1334 | if (!conn) |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4a90438d99df..8d53fc57faba 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -546,7 +546,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
546 | 546 | ||
547 | l2cap_chan_hold(chan); | 547 | l2cap_chan_hold(chan); |
548 | 548 | ||
549 | hci_conn_hold(conn->hcon); | 549 | /* Only keep a reference for fixed channels if they requested it */ |
550 | if (chan->chan_type != L2CAP_CHAN_FIXED || | ||
551 | test_bit(FLAG_HOLD_HCI_CONN, &chan->flags)) | ||
552 | hci_conn_hold(conn->hcon); | ||
550 | 553 | ||
551 | list_add(&chan->list, &conn->chan_l); | 554 | list_add(&chan->list, &conn->chan_l); |
552 | } | 555 | } |
@@ -577,7 +580,12 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
577 | 580 | ||
578 | chan->conn = NULL; | 581 | chan->conn = NULL; |
579 | 582 | ||
580 | if (chan->scid != L2CAP_CID_A2MP) | 583 | /* Reference was only held for non-fixed channels or |
584 | * fixed channels that explicitly requested it using the | ||
585 | * FLAG_HOLD_HCI_CONN flag. | ||
586 | */ | ||
587 | if (chan->chan_type != L2CAP_CHAN_FIXED || | ||
588 | test_bit(FLAG_HOLD_HCI_CONN, &chan->flags)) | ||
581 | hci_conn_drop(conn->hcon); | 589 | hci_conn_drop(conn->hcon); |
582 | 590 | ||
583 | if (mgr && mgr->bredr_chan == chan) | 591 | if (mgr && mgr->bredr_chan == chan) |
@@ -623,9 +631,11 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err) | |||
623 | } | 631 | } |
624 | EXPORT_SYMBOL_GPL(l2cap_chan_del); | 632 | EXPORT_SYMBOL_GPL(l2cap_chan_del); |
625 | 633 | ||
626 | void l2cap_conn_update_id_addr(struct hci_conn *hcon) | 634 | static void l2cap_conn_update_id_addr(struct work_struct *work) |
627 | { | 635 | { |
628 | struct l2cap_conn *conn = hcon->l2cap_data; | 636 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, |
637 | id_addr_update_work); | ||
638 | struct hci_conn *hcon = conn->hcon; | ||
629 | struct l2cap_chan *chan; | 639 | struct l2cap_chan *chan; |
630 | 640 | ||
631 | mutex_lock(&conn->chan_lock); | 641 | mutex_lock(&conn->chan_lock); |
@@ -1273,6 +1283,24 @@ static void l2cap_start_connection(struct l2cap_chan *chan) | |||
1273 | } | 1283 | } |
1274 | } | 1284 | } |
1275 | 1285 | ||
1286 | static void l2cap_request_info(struct l2cap_conn *conn) | ||
1287 | { | ||
1288 | struct l2cap_info_req req; | ||
1289 | |||
1290 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) | ||
1291 | return; | ||
1292 | |||
1293 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | ||
1294 | |||
1295 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | ||
1296 | conn->info_ident = l2cap_get_ident(conn); | ||
1297 | |||
1298 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | ||
1299 | |||
1300 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, | ||
1301 | sizeof(req), &req); | ||
1302 | } | ||
1303 | |||
1276 | static void l2cap_do_start(struct l2cap_chan *chan) | 1304 | static void l2cap_do_start(struct l2cap_chan *chan) |
1277 | { | 1305 | { |
1278 | struct l2cap_conn *conn = chan->conn; | 1306 | struct l2cap_conn *conn = chan->conn; |
@@ -1282,26 +1310,17 @@ static void l2cap_do_start(struct l2cap_chan *chan) | |||
1282 | return; | 1310 | return; |
1283 | } | 1311 | } |
1284 | 1312 | ||
1285 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) { | 1313 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)) { |
1286 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) | 1314 | l2cap_request_info(conn); |
1287 | return; | 1315 | return; |
1288 | 1316 | } | |
1289 | if (l2cap_chan_check_security(chan, true) && | ||
1290 | __l2cap_no_conn_pending(chan)) { | ||
1291 | l2cap_start_connection(chan); | ||
1292 | } | ||
1293 | } else { | ||
1294 | struct l2cap_info_req req; | ||
1295 | req.type = cpu_to_le16(L2CAP_IT_FEAT_MASK); | ||
1296 | |||
1297 | conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_SENT; | ||
1298 | conn->info_ident = l2cap_get_ident(conn); | ||
1299 | 1317 | ||
1300 | schedule_delayed_work(&conn->info_timer, L2CAP_INFO_TIMEOUT); | 1318 | if (!(conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)) |
1319 | return; | ||
1301 | 1320 | ||
1302 | l2cap_send_cmd(conn, conn->info_ident, L2CAP_INFO_REQ, | 1321 | if (l2cap_chan_check_security(chan, true) && |
1303 | sizeof(req), &req); | 1322 | __l2cap_no_conn_pending(chan)) |
1304 | } | 1323 | l2cap_start_connection(chan); |
1305 | } | 1324 | } |
1306 | 1325 | ||
1307 | static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) | 1326 | static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask) |
@@ -1360,6 +1379,7 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
1360 | l2cap_chan_lock(chan); | 1379 | l2cap_chan_lock(chan); |
1361 | 1380 | ||
1362 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1381 | if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
1382 | l2cap_chan_ready(chan); | ||
1363 | l2cap_chan_unlock(chan); | 1383 | l2cap_chan_unlock(chan); |
1364 | continue; | 1384 | continue; |
1365 | } | 1385 | } |
@@ -1464,6 +1484,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1464 | 1484 | ||
1465 | BT_DBG("conn %p", conn); | 1485 | BT_DBG("conn %p", conn); |
1466 | 1486 | ||
1487 | if (hcon->type == ACL_LINK) | ||
1488 | l2cap_request_info(conn); | ||
1489 | |||
1467 | mutex_lock(&conn->chan_lock); | 1490 | mutex_lock(&conn->chan_lock); |
1468 | 1491 | ||
1469 | list_for_each_entry(chan, &conn->chan_l, list) { | 1492 | list_for_each_entry(chan, &conn->chan_l, list) { |
@@ -1478,8 +1501,8 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1478 | if (hcon->type == LE_LINK) { | 1501 | if (hcon->type == LE_LINK) { |
1479 | l2cap_le_start(chan); | 1502 | l2cap_le_start(chan); |
1480 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { | 1503 | } else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) { |
1481 | l2cap_chan_ready(chan); | 1504 | if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) |
1482 | 1505 | l2cap_chan_ready(chan); | |
1483 | } else if (chan->state == BT_CONNECT) { | 1506 | } else if (chan->state == BT_CONNECT) { |
1484 | l2cap_do_start(chan); | 1507 | l2cap_do_start(chan); |
1485 | } | 1508 | } |
@@ -1627,11 +1650,14 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1627 | if (work_pending(&conn->pending_rx_work)) | 1650 | if (work_pending(&conn->pending_rx_work)) |
1628 | cancel_work_sync(&conn->pending_rx_work); | 1651 | cancel_work_sync(&conn->pending_rx_work); |
1629 | 1652 | ||
1630 | if (work_pending(&conn->disconn_work)) | 1653 | if (work_pending(&conn->id_addr_update_work)) |
1631 | cancel_work_sync(&conn->disconn_work); | 1654 | cancel_work_sync(&conn->id_addr_update_work); |
1632 | 1655 | ||
1633 | l2cap_unregister_all_users(conn); | 1656 | l2cap_unregister_all_users(conn); |
1634 | 1657 | ||
1658 | /* Force the connection to be immediately dropped */ | ||
1659 | hcon->disc_timeout = 0; | ||
1660 | |||
1635 | mutex_lock(&conn->chan_lock); | 1661 | mutex_lock(&conn->chan_lock); |
1636 | 1662 | ||
1637 | /* Kill channels */ | 1663 | /* Kill channels */ |
@@ -1659,26 +1685,6 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err) | |||
1659 | l2cap_conn_put(conn); | 1685 | l2cap_conn_put(conn); |
1660 | } | 1686 | } |
1661 | 1687 | ||
1662 | static void disconn_work(struct work_struct *work) | ||
1663 | { | ||
1664 | struct l2cap_conn *conn = container_of(work, struct l2cap_conn, | ||
1665 | disconn_work); | ||
1666 | |||
1667 | BT_DBG("conn %p", conn); | ||
1668 | |||
1669 | l2cap_conn_del(conn->hcon, conn->disconn_err); | ||
1670 | } | ||
1671 | |||
1672 | void l2cap_conn_shutdown(struct l2cap_conn *conn, int err) | ||
1673 | { | ||
1674 | struct hci_dev *hdev = conn->hcon->hdev; | ||
1675 | |||
1676 | BT_DBG("conn %p err %d", conn, err); | ||
1677 | |||
1678 | conn->disconn_err = err; | ||
1679 | queue_work(hdev->workqueue, &conn->disconn_work); | ||
1680 | } | ||
1681 | |||
1682 | static void l2cap_conn_free(struct kref *ref) | 1688 | static void l2cap_conn_free(struct kref *ref) |
1683 | { | 1689 | { |
1684 | struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); | 1690 | struct l2cap_conn *conn = container_of(ref, struct l2cap_conn, ref); |
@@ -1687,9 +1693,10 @@ static void l2cap_conn_free(struct kref *ref) | |||
1687 | kfree(conn); | 1693 | kfree(conn); |
1688 | } | 1694 | } |
1689 | 1695 | ||
1690 | void l2cap_conn_get(struct l2cap_conn *conn) | 1696 | struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn) |
1691 | { | 1697 | { |
1692 | kref_get(&conn->ref); | 1698 | kref_get(&conn->ref); |
1699 | return conn; | ||
1693 | } | 1700 | } |
1694 | EXPORT_SYMBOL(l2cap_conn_get); | 1701 | EXPORT_SYMBOL(l2cap_conn_get); |
1695 | 1702 | ||
@@ -2358,12 +2365,8 @@ static int l2cap_segment_le_sdu(struct l2cap_chan *chan, | |||
2358 | 2365 | ||
2359 | BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); | 2366 | BT_DBG("chan %p, msg %p, len %zu", chan, msg, len); |
2360 | 2367 | ||
2361 | pdu_len = chan->conn->mtu - L2CAP_HDR_SIZE; | ||
2362 | |||
2363 | pdu_len = min_t(size_t, pdu_len, chan->remote_mps); | ||
2364 | |||
2365 | sdu_len = len; | 2368 | sdu_len = len; |
2366 | pdu_len -= L2CAP_SDULEN_SIZE; | 2369 | pdu_len = chan->remote_mps - L2CAP_SDULEN_SIZE; |
2367 | 2370 | ||
2368 | while (len > 0) { | 2371 | while (len > 0) { |
2369 | if (len <= pdu_len) | 2372 | if (len <= pdu_len) |
@@ -5428,6 +5431,11 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn, | |||
5428 | 5431 | ||
5429 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { | 5432 | if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) { |
5430 | l2cap_state_change(chan, BT_CONNECT2); | 5433 | l2cap_state_change(chan, BT_CONNECT2); |
5434 | /* The following result value is actually not defined | ||
5435 | * for LE CoC but we use it to let the function know | ||
5436 | * that it should bail out after doing its cleanup | ||
5437 | * instead of sending a response. | ||
5438 | */ | ||
5431 | result = L2CAP_CR_PEND; | 5439 | result = L2CAP_CR_PEND; |
5432 | chan->ops->defer(chan); | 5440 | chan->ops->defer(chan); |
5433 | } else { | 5441 | } else { |
@@ -6904,8 +6912,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) | |||
6904 | 6912 | ||
6905 | kref_init(&conn->ref); | 6913 | kref_init(&conn->ref); |
6906 | hcon->l2cap_data = conn; | 6914 | hcon->l2cap_data = conn; |
6907 | conn->hcon = hcon; | 6915 | conn->hcon = hci_conn_get(hcon); |
6908 | hci_conn_get(conn->hcon); | ||
6909 | conn->hchan = hchan; | 6916 | conn->hchan = hchan; |
6910 | 6917 | ||
6911 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); | 6918 | BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan); |
@@ -6936,10 +6943,9 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon) | |||
6936 | 6943 | ||
6937 | INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); | 6944 | INIT_DELAYED_WORK(&conn->info_timer, l2cap_info_timeout); |
6938 | 6945 | ||
6939 | INIT_WORK(&conn->disconn_work, disconn_work); | ||
6940 | |||
6941 | skb_queue_head_init(&conn->pending_rx); | 6946 | skb_queue_head_init(&conn->pending_rx); |
6942 | INIT_WORK(&conn->pending_rx_work, process_pending_rx); | 6947 | INIT_WORK(&conn->pending_rx_work, process_pending_rx); |
6948 | INIT_WORK(&conn->id_addr_update_work, l2cap_conn_update_id_addr); | ||
6943 | 6949 | ||
6944 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; | 6950 | conn->disc_reason = HCI_ERROR_REMOTE_USER_TERM; |
6945 | 6951 | ||
@@ -7082,9 +7088,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
7082 | bacpy(&chan->src, &hcon->src); | 7088 | bacpy(&chan->src, &hcon->src); |
7083 | chan->src_type = bdaddr_type(hcon, hcon->src_type); | 7089 | chan->src_type = bdaddr_type(hcon, hcon->src_type); |
7084 | 7090 | ||
7085 | l2cap_chan_unlock(chan); | ||
7086 | l2cap_chan_add(conn, chan); | 7091 | l2cap_chan_add(conn, chan); |
7087 | l2cap_chan_lock(chan); | ||
7088 | 7092 | ||
7089 | /* l2cap_chan_add takes its own ref so we can drop this one */ | 7093 | /* l2cap_chan_add takes its own ref so we can drop this one */ |
7090 | hci_conn_drop(hcon); | 7094 | hci_conn_drop(hcon); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index ed06f88e6f10..31f106e61ca2 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -146,6 +146,14 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) | |||
146 | case L2CAP_CHAN_RAW: | 146 | case L2CAP_CHAN_RAW: |
147 | chan->sec_level = BT_SECURITY_SDP; | 147 | chan->sec_level = BT_SECURITY_SDP; |
148 | break; | 148 | break; |
149 | case L2CAP_CHAN_FIXED: | ||
150 | /* Fixed channels default to the L2CAP core not holding a | ||
151 | * hci_conn reference for them. For fixed channels mapping to | ||
152 | * L2CAP sockets we do want to hold a reference so set the | ||
153 | * appropriate flag to request it. | ||
154 | */ | ||
155 | set_bit(FLAG_HOLD_HCI_CONN, &chan->flags); | ||
156 | break; | ||
149 | } | 157 | } |
150 | 158 | ||
151 | bacpy(&chan->src, &la.l2_bdaddr); | 159 | bacpy(&chan->src, &la.l2_bdaddr); |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index c2457435a670..efb71b022ab6 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2788,7 +2788,6 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2788 | { | 2788 | { |
2789 | struct mgmt_cp_disconnect *cp = data; | 2789 | struct mgmt_cp_disconnect *cp = data; |
2790 | struct mgmt_rp_disconnect rp; | 2790 | struct mgmt_rp_disconnect rp; |
2791 | struct hci_cp_disconnect dc; | ||
2792 | struct pending_cmd *cmd; | 2791 | struct pending_cmd *cmd; |
2793 | struct hci_conn *conn; | 2792 | struct hci_conn *conn; |
2794 | int err; | 2793 | int err; |
@@ -2836,10 +2835,7 @@ static int disconnect(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2836 | goto failed; | 2835 | goto failed; |
2837 | } | 2836 | } |
2838 | 2837 | ||
2839 | dc.handle = cpu_to_le16(conn->handle); | 2838 | err = hci_disconnect(conn, HCI_ERROR_REMOTE_USER_TERM); |
2840 | dc.reason = HCI_ERROR_REMOTE_USER_TERM; | ||
2841 | |||
2842 | err = hci_send_cmd(hdev, HCI_OP_DISCONNECT, sizeof(dc), &dc); | ||
2843 | if (err < 0) | 2839 | if (err < 0) |
2844 | mgmt_pending_remove(cmd); | 2840 | mgmt_pending_remove(cmd); |
2845 | 2841 | ||
@@ -3063,6 +3059,7 @@ static void pairing_complete(struct pending_cmd *cmd, u8 status) | |||
3063 | conn->disconn_cfm_cb = NULL; | 3059 | conn->disconn_cfm_cb = NULL; |
3064 | 3060 | ||
3065 | hci_conn_drop(conn); | 3061 | hci_conn_drop(conn); |
3062 | hci_conn_put(conn); | ||
3066 | 3063 | ||
3067 | mgmt_pending_remove(cmd); | 3064 | mgmt_pending_remove(cmd); |
3068 | } | 3065 | } |
@@ -3212,7 +3209,7 @@ static int pair_device(struct sock *sk, struct hci_dev *hdev, void *data, | |||
3212 | } | 3209 | } |
3213 | 3210 | ||
3214 | conn->io_capability = cp->io_cap; | 3211 | conn->io_capability = cp->io_cap; |
3215 | cmd->user_data = conn; | 3212 | cmd->user_data = hci_conn_get(conn); |
3216 | 3213 | ||
3217 | if ((conn->state == BT_CONNECTED || conn->state == BT_CONFIG) && | 3214 | if ((conn->state == BT_CONNECTED || conn->state == BT_CONFIG) && |
3218 | hci_conn_security(conn, sec_level, auth_type, true)) | 3215 | hci_conn_security(conn, sec_level, auth_type, true)) |
@@ -4914,6 +4911,7 @@ static void get_conn_info_complete(struct pending_cmd *cmd, void *data) | |||
4914 | match->mgmt_status, &rp, sizeof(rp)); | 4911 | match->mgmt_status, &rp, sizeof(rp)); |
4915 | 4912 | ||
4916 | hci_conn_drop(conn); | 4913 | hci_conn_drop(conn); |
4914 | hci_conn_put(conn); | ||
4917 | 4915 | ||
4918 | mgmt_pending_remove(cmd); | 4916 | mgmt_pending_remove(cmd); |
4919 | } | 4917 | } |
@@ -5070,7 +5068,7 @@ static int get_conn_info(struct sock *sk, struct hci_dev *hdev, void *data, | |||
5070 | } | 5068 | } |
5071 | 5069 | ||
5072 | hci_conn_hold(conn); | 5070 | hci_conn_hold(conn); |
5073 | cmd->user_data = conn; | 5071 | cmd->user_data = hci_conn_get(conn); |
5074 | 5072 | ||
5075 | conn->conn_info_timestamp = jiffies; | 5073 | conn->conn_info_timestamp = jiffies; |
5076 | } else { | 5074 | } else { |
@@ -5134,8 +5132,10 @@ send_rsp: | |||
5134 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), | 5132 | cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(status), |
5135 | &rp, sizeof(rp)); | 5133 | &rp, sizeof(rp)); |
5136 | mgmt_pending_remove(cmd); | 5134 | mgmt_pending_remove(cmd); |
5137 | if (conn) | 5135 | if (conn) { |
5138 | hci_conn_drop(conn); | 5136 | hci_conn_drop(conn); |
5137 | hci_conn_put(conn); | ||
5138 | } | ||
5139 | 5139 | ||
5140 | unlock: | 5140 | unlock: |
5141 | hci_dev_unlock(hdev); | 5141 | hci_dev_unlock(hdev); |
@@ -5198,7 +5198,7 @@ static int get_clock_info(struct sock *sk, struct hci_dev *hdev, void *data, | |||
5198 | 5198 | ||
5199 | if (conn) { | 5199 | if (conn) { |
5200 | hci_conn_hold(conn); | 5200 | hci_conn_hold(conn); |
5201 | cmd->user_data = conn; | 5201 | cmd->user_data = hci_conn_get(conn); |
5202 | 5202 | ||
5203 | hci_cp.handle = cpu_to_le16(conn->handle); | 5203 | hci_cp.handle = cpu_to_le16(conn->handle); |
5204 | hci_cp.which = 0x01; /* Piconet clock */ | 5204 | hci_cp.which = 0x01; /* Piconet clock */ |
@@ -6485,16 +6485,23 @@ int mgmt_user_passkey_notify(struct hci_dev *hdev, bdaddr_t *bdaddr, | |||
6485 | return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL); | 6485 | return mgmt_event(MGMT_EV_PASSKEY_NOTIFY, hdev, &ev, sizeof(ev), NULL); |
6486 | } | 6486 | } |
6487 | 6487 | ||
6488 | void mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | 6488 | void mgmt_auth_failed(struct hci_conn *conn, u8 hci_status) |
6489 | u8 addr_type, u8 status) | ||
6490 | { | 6489 | { |
6491 | struct mgmt_ev_auth_failed ev; | 6490 | struct mgmt_ev_auth_failed ev; |
6491 | struct pending_cmd *cmd; | ||
6492 | u8 status = mgmt_status(hci_status); | ||
6492 | 6493 | ||
6493 | bacpy(&ev.addr.bdaddr, bdaddr); | 6494 | bacpy(&ev.addr.bdaddr, &conn->dst); |
6494 | ev.addr.type = link_to_bdaddr(link_type, addr_type); | 6495 | ev.addr.type = link_to_bdaddr(conn->type, conn->dst_type); |
6495 | ev.status = mgmt_status(status); | 6496 | ev.status = status; |
6497 | |||
6498 | cmd = find_pairing(conn); | ||
6496 | 6499 | ||
6497 | mgmt_event(MGMT_EV_AUTH_FAILED, hdev, &ev, sizeof(ev), NULL); | 6500 | mgmt_event(MGMT_EV_AUTH_FAILED, conn->hdev, &ev, sizeof(ev), |
6501 | cmd ? cmd->sk : NULL); | ||
6502 | |||
6503 | if (cmd) | ||
6504 | pairing_complete(cmd, status); | ||
6498 | } | 6505 | } |
6499 | 6506 | ||
6500 | void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) | 6507 | void mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 07ca4ce0943b..51fc7db2d84e 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -31,9 +31,12 @@ | |||
31 | 31 | ||
32 | #include "smp.h" | 32 | #include "smp.h" |
33 | 33 | ||
34 | #define SMP_ALLOW_CMD(smp, code) set_bit(code, &smp->allow_cmd) | ||
35 | |||
34 | #define SMP_TIMEOUT msecs_to_jiffies(30000) | 36 | #define SMP_TIMEOUT msecs_to_jiffies(30000) |
35 | 37 | ||
36 | #define AUTH_REQ_MASK 0x07 | 38 | #define AUTH_REQ_MASK 0x07 |
39 | #define KEY_DIST_MASK 0x07 | ||
37 | 40 | ||
38 | enum { | 41 | enum { |
39 | SMP_FLAG_TK_VALID, | 42 | SMP_FLAG_TK_VALID, |
@@ -46,7 +49,7 @@ enum { | |||
46 | struct smp_chan { | 49 | struct smp_chan { |
47 | struct l2cap_conn *conn; | 50 | struct l2cap_conn *conn; |
48 | struct delayed_work security_timer; | 51 | struct delayed_work security_timer; |
49 | struct work_struct distribute_work; | 52 | unsigned long allow_cmd; /* Bitmask of allowed commands */ |
50 | 53 | ||
51 | u8 preq[7]; /* SMP Pairing Request */ | 54 | u8 preq[7]; /* SMP Pairing Request */ |
52 | u8 prsp[7]; /* SMP Pairing Response */ | 55 | u8 prsp[7]; /* SMP Pairing Response */ |
@@ -282,8 +285,7 @@ static void smp_send_cmd(struct l2cap_conn *conn, u8 code, u16 len, void *data) | |||
282 | smp = chan->data; | 285 | smp = chan->data; |
283 | 286 | ||
284 | cancel_delayed_work_sync(&smp->security_timer); | 287 | cancel_delayed_work_sync(&smp->security_timer); |
285 | if (test_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | 288 | schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); |
286 | schedule_delayed_work(&smp->security_timer, SMP_TIMEOUT); | ||
287 | } | 289 | } |
288 | 290 | ||
289 | static __u8 authreq_to_seclevel(__u8 authreq) | 291 | static __u8 authreq_to_seclevel(__u8 authreq) |
@@ -375,15 +377,6 @@ static void smp_chan_destroy(struct l2cap_conn *conn) | |||
375 | BUG_ON(!smp); | 377 | BUG_ON(!smp); |
376 | 378 | ||
377 | cancel_delayed_work_sync(&smp->security_timer); | 379 | cancel_delayed_work_sync(&smp->security_timer); |
378 | /* In case the timeout freed the SMP context */ | ||
379 | if (!chan->data) | ||
380 | return; | ||
381 | |||
382 | if (work_pending(&smp->distribute_work)) { | ||
383 | cancel_work_sync(&smp->distribute_work); | ||
384 | if (!chan->data) | ||
385 | return; | ||
386 | } | ||
387 | 380 | ||
388 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); | 381 | complete = test_bit(SMP_FLAG_COMPLETE, &smp->flags); |
389 | mgmt_smp_complete(conn->hcon, complete); | 382 | mgmt_smp_complete(conn->hcon, complete); |
@@ -420,22 +413,15 @@ static void smp_failure(struct l2cap_conn *conn, u8 reason) | |||
420 | { | 413 | { |
421 | struct hci_conn *hcon = conn->hcon; | 414 | struct hci_conn *hcon = conn->hcon; |
422 | struct l2cap_chan *chan = conn->smp; | 415 | struct l2cap_chan *chan = conn->smp; |
423 | struct smp_chan *smp; | ||
424 | 416 | ||
425 | if (reason) | 417 | if (reason) |
426 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), | 418 | smp_send_cmd(conn, SMP_CMD_PAIRING_FAIL, sizeof(reason), |
427 | &reason); | 419 | &reason); |
428 | 420 | ||
429 | clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags); | 421 | clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags); |
430 | mgmt_auth_failed(hcon->hdev, &hcon->dst, hcon->type, hcon->dst_type, | 422 | mgmt_auth_failed(hcon, HCI_ERROR_AUTH_FAILURE); |
431 | HCI_ERROR_AUTH_FAILURE); | ||
432 | 423 | ||
433 | if (!chan->data) | 424 | if (chan->data) |
434 | return; | ||
435 | |||
436 | smp = chan->data; | ||
437 | |||
438 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | ||
439 | smp_chan_destroy(conn); | 425 | smp_chan_destroy(conn); |
440 | } | 426 | } |
441 | 427 | ||
@@ -569,6 +555,11 @@ static u8 smp_confirm(struct smp_chan *smp) | |||
569 | 555 | ||
570 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); | 556 | smp_send_cmd(smp->conn, SMP_CMD_PAIRING_CONFIRM, sizeof(cp), &cp); |
571 | 557 | ||
558 | if (conn->hcon->out) | ||
559 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); | ||
560 | else | ||
561 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); | ||
562 | |||
572 | return 0; | 563 | return 0; |
573 | } | 564 | } |
574 | 565 | ||
@@ -658,7 +649,7 @@ static void smp_notify_keys(struct l2cap_conn *conn) | |||
658 | */ | 649 | */ |
659 | bacpy(&hcon->dst, &smp->remote_irk->bdaddr); | 650 | bacpy(&hcon->dst, &smp->remote_irk->bdaddr); |
660 | hcon->dst_type = smp->remote_irk->addr_type; | 651 | hcon->dst_type = smp->remote_irk->addr_type; |
661 | l2cap_conn_update_id_addr(hcon); | 652 | queue_work(hdev->workqueue, &conn->id_addr_update_work); |
662 | 653 | ||
663 | /* When receiving an indentity resolving key for | 654 | /* When receiving an indentity resolving key for |
664 | * a remote device that does not use a resolvable | 655 | * a remote device that does not use a resolvable |
@@ -707,10 +698,22 @@ static void smp_notify_keys(struct l2cap_conn *conn) | |||
707 | } | 698 | } |
708 | } | 699 | } |
709 | 700 | ||
710 | static void smp_distribute_keys(struct work_struct *work) | 701 | static void smp_allow_key_dist(struct smp_chan *smp) |
702 | { | ||
703 | /* Allow the first expected phase 3 PDU. The rest of the PDUs | ||
704 | * will be allowed in each PDU handler to ensure we receive | ||
705 | * them in the correct order. | ||
706 | */ | ||
707 | if (smp->remote_key_dist & SMP_DIST_ENC_KEY) | ||
708 | SMP_ALLOW_CMD(smp, SMP_CMD_ENCRYPT_INFO); | ||
709 | else if (smp->remote_key_dist & SMP_DIST_ID_KEY) | ||
710 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); | ||
711 | else if (smp->remote_key_dist & SMP_DIST_SIGN) | ||
712 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | ||
713 | } | ||
714 | |||
715 | static void smp_distribute_keys(struct smp_chan *smp) | ||
711 | { | 716 | { |
712 | struct smp_chan *smp = container_of(work, struct smp_chan, | ||
713 | distribute_work); | ||
714 | struct smp_cmd_pairing *req, *rsp; | 717 | struct smp_cmd_pairing *req, *rsp; |
715 | struct l2cap_conn *conn = smp->conn; | 718 | struct l2cap_conn *conn = smp->conn; |
716 | struct hci_conn *hcon = conn->hcon; | 719 | struct hci_conn *hcon = conn->hcon; |
@@ -719,14 +722,13 @@ static void smp_distribute_keys(struct work_struct *work) | |||
719 | 722 | ||
720 | BT_DBG("conn %p", conn); | 723 | BT_DBG("conn %p", conn); |
721 | 724 | ||
722 | if (!test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | ||
723 | return; | ||
724 | |||
725 | rsp = (void *) &smp->prsp[1]; | 725 | rsp = (void *) &smp->prsp[1]; |
726 | 726 | ||
727 | /* The responder sends its keys first */ | 727 | /* The responder sends its keys first */ |
728 | if (hcon->out && (smp->remote_key_dist & 0x07)) | 728 | if (hcon->out && (smp->remote_key_dist & KEY_DIST_MASK)) { |
729 | smp_allow_key_dist(smp); | ||
729 | return; | 730 | return; |
731 | } | ||
730 | 732 | ||
731 | req = (void *) &smp->preq[1]; | 733 | req = (void *) &smp->preq[1]; |
732 | 734 | ||
@@ -811,10 +813,11 @@ static void smp_distribute_keys(struct work_struct *work) | |||
811 | } | 813 | } |
812 | 814 | ||
813 | /* If there are still keys to be received wait for them */ | 815 | /* If there are still keys to be received wait for them */ |
814 | if ((smp->remote_key_dist & 0x07)) | 816 | if (smp->remote_key_dist & KEY_DIST_MASK) { |
817 | smp_allow_key_dist(smp); | ||
815 | return; | 818 | return; |
819 | } | ||
816 | 820 | ||
817 | clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags); | ||
818 | set_bit(SMP_FLAG_COMPLETE, &smp->flags); | 821 | set_bit(SMP_FLAG_COMPLETE, &smp->flags); |
819 | smp_notify_keys(conn); | 822 | smp_notify_keys(conn); |
820 | 823 | ||
@@ -829,7 +832,7 @@ static void smp_timeout(struct work_struct *work) | |||
829 | 832 | ||
830 | BT_DBG("conn %p", conn); | 833 | BT_DBG("conn %p", conn); |
831 | 834 | ||
832 | l2cap_conn_shutdown(conn, ETIMEDOUT); | 835 | hci_disconnect(conn->hcon, HCI_ERROR_REMOTE_USER_TERM); |
833 | } | 836 | } |
834 | 837 | ||
835 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | 838 | static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) |
@@ -838,23 +841,21 @@ static struct smp_chan *smp_chan_create(struct l2cap_conn *conn) | |||
838 | struct smp_chan *smp; | 841 | struct smp_chan *smp; |
839 | 842 | ||
840 | smp = kzalloc(sizeof(*smp), GFP_ATOMIC); | 843 | smp = kzalloc(sizeof(*smp), GFP_ATOMIC); |
841 | if (!smp) { | 844 | if (!smp) |
842 | clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); | ||
843 | return NULL; | 845 | return NULL; |
844 | } | ||
845 | 846 | ||
846 | smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); | 847 | smp->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0, CRYPTO_ALG_ASYNC); |
847 | if (IS_ERR(smp->tfm_aes)) { | 848 | if (IS_ERR(smp->tfm_aes)) { |
848 | BT_ERR("Unable to create ECB crypto context"); | 849 | BT_ERR("Unable to create ECB crypto context"); |
849 | kfree(smp); | 850 | kfree(smp); |
850 | clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags); | ||
851 | return NULL; | 851 | return NULL; |
852 | } | 852 | } |
853 | 853 | ||
854 | smp->conn = conn; | 854 | smp->conn = conn; |
855 | chan->data = smp; | 855 | chan->data = smp; |
856 | 856 | ||
857 | INIT_WORK(&smp->distribute_work, smp_distribute_keys); | 857 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_FAIL); |
858 | |||
858 | INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); | 859 | INIT_DELAYED_WORK(&smp->security_timer, smp_timeout); |
859 | 860 | ||
860 | hci_conn_hold(conn->hcon); | 861 | hci_conn_hold(conn->hcon); |
@@ -868,16 +869,23 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
868 | struct l2cap_chan *chan; | 869 | struct l2cap_chan *chan; |
869 | struct smp_chan *smp; | 870 | struct smp_chan *smp; |
870 | u32 value; | 871 | u32 value; |
872 | int err; | ||
871 | 873 | ||
872 | BT_DBG(""); | 874 | BT_DBG(""); |
873 | 875 | ||
874 | if (!conn || !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 876 | if (!conn) |
875 | return -ENOTCONN; | 877 | return -ENOTCONN; |
876 | 878 | ||
877 | chan = conn->smp; | 879 | chan = conn->smp; |
878 | if (!chan) | 880 | if (!chan) |
879 | return -ENOTCONN; | 881 | return -ENOTCONN; |
880 | 882 | ||
883 | l2cap_chan_lock(chan); | ||
884 | if (!chan->data) { | ||
885 | err = -ENOTCONN; | ||
886 | goto unlock; | ||
887 | } | ||
888 | |||
881 | smp = chan->data; | 889 | smp = chan->data; |
882 | 890 | ||
883 | switch (mgmt_op) { | 891 | switch (mgmt_op) { |
@@ -893,12 +901,16 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
893 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: | 901 | case MGMT_OP_USER_PASSKEY_NEG_REPLY: |
894 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: | 902 | case MGMT_OP_USER_CONFIRM_NEG_REPLY: |
895 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); | 903 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); |
896 | return 0; | 904 | err = 0; |
905 | goto unlock; | ||
897 | default: | 906 | default: |
898 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); | 907 | smp_failure(conn, SMP_PASSKEY_ENTRY_FAILED); |
899 | return -EOPNOTSUPP; | 908 | err = -EOPNOTSUPP; |
909 | goto unlock; | ||
900 | } | 910 | } |
901 | 911 | ||
912 | err = 0; | ||
913 | |||
902 | /* If it is our turn to send Pairing Confirm, do so now */ | 914 | /* If it is our turn to send Pairing Confirm, do so now */ |
903 | if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { | 915 | if (test_bit(SMP_FLAG_CFM_PENDING, &smp->flags)) { |
904 | u8 rsp = smp_confirm(smp); | 916 | u8 rsp = smp_confirm(smp); |
@@ -906,12 +918,15 @@ int smp_user_confirm_reply(struct hci_conn *hcon, u16 mgmt_op, __le32 passkey) | |||
906 | smp_failure(conn, rsp); | 918 | smp_failure(conn, rsp); |
907 | } | 919 | } |
908 | 920 | ||
909 | return 0; | 921 | unlock: |
922 | l2cap_chan_unlock(chan); | ||
923 | return err; | ||
910 | } | 924 | } |
911 | 925 | ||
912 | static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | 926 | static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) |
913 | { | 927 | { |
914 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; | 928 | struct smp_cmd_pairing rsp, *req = (void *) skb->data; |
929 | struct l2cap_chan *chan = conn->smp; | ||
915 | struct hci_dev *hdev = conn->hcon->hdev; | 930 | struct hci_dev *hdev = conn->hcon->hdev; |
916 | struct smp_chan *smp; | 931 | struct smp_chan *smp; |
917 | u8 key_size, auth, sec_level; | 932 | u8 key_size, auth, sec_level; |
@@ -925,28 +940,30 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
925 | if (conn->hcon->role != HCI_ROLE_SLAVE) | 940 | if (conn->hcon->role != HCI_ROLE_SLAVE) |
926 | return SMP_CMD_NOTSUPP; | 941 | return SMP_CMD_NOTSUPP; |
927 | 942 | ||
928 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) { | 943 | if (!chan->data) |
929 | smp = smp_chan_create(conn); | 944 | smp = smp_chan_create(conn); |
930 | } else { | 945 | else |
931 | struct l2cap_chan *chan = conn->smp; | ||
932 | smp = chan->data; | 946 | smp = chan->data; |
933 | } | ||
934 | 947 | ||
935 | if (!smp) | 948 | if (!smp) |
936 | return SMP_UNSPECIFIED; | 949 | return SMP_UNSPECIFIED; |
937 | 950 | ||
951 | /* We didn't start the pairing, so match remote */ | ||
952 | auth = req->auth_req & AUTH_REQ_MASK; | ||
953 | |||
938 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && | 954 | if (!test_bit(HCI_BONDABLE, &hdev->dev_flags) && |
939 | (req->auth_req & SMP_AUTH_BONDING)) | 955 | (auth & SMP_AUTH_BONDING)) |
940 | return SMP_PAIRING_NOTSUPP; | 956 | return SMP_PAIRING_NOTSUPP; |
941 | 957 | ||
942 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 958 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
943 | memcpy(&smp->preq[1], req, sizeof(*req)); | 959 | memcpy(&smp->preq[1], req, sizeof(*req)); |
944 | skb_pull(skb, sizeof(*req)); | 960 | skb_pull(skb, sizeof(*req)); |
945 | 961 | ||
946 | /* We didn't start the pairing, so match remote */ | 962 | if (conn->hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) |
947 | auth = req->auth_req; | 963 | sec_level = BT_SECURITY_MEDIUM; |
964 | else | ||
965 | sec_level = authreq_to_seclevel(auth); | ||
948 | 966 | ||
949 | sec_level = authreq_to_seclevel(auth); | ||
950 | if (sec_level > conn->hcon->pending_sec_level) | 967 | if (sec_level > conn->hcon->pending_sec_level) |
951 | conn->hcon->pending_sec_level = sec_level; | 968 | conn->hcon->pending_sec_level = sec_level; |
952 | 969 | ||
@@ -972,6 +989,7 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
972 | memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); | 989 | memcpy(&smp->prsp[1], &rsp, sizeof(rsp)); |
973 | 990 | ||
974 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); | 991 | smp_send_cmd(conn, SMP_CMD_PAIRING_RSP, sizeof(rsp), &rsp); |
992 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_CONFIRM); | ||
975 | 993 | ||
976 | /* Request setup of TK */ | 994 | /* Request setup of TK */ |
977 | ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); | 995 | ret = tk_request(conn, 0, auth, rsp.io_capability, req->io_capability); |
@@ -986,7 +1004,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
986 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; | 1004 | struct smp_cmd_pairing *req, *rsp = (void *) skb->data; |
987 | struct l2cap_chan *chan = conn->smp; | 1005 | struct l2cap_chan *chan = conn->smp; |
988 | struct smp_chan *smp = chan->data; | 1006 | struct smp_chan *smp = chan->data; |
989 | u8 key_size, auth = SMP_AUTH_NONE; | 1007 | u8 key_size, auth; |
990 | int ret; | 1008 | int ret; |
991 | 1009 | ||
992 | BT_DBG("conn %p", conn); | 1010 | BT_DBG("conn %p", conn); |
@@ -1005,6 +1023,8 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1005 | if (check_enc_key_size(conn, key_size)) | 1023 | if (check_enc_key_size(conn, key_size)) |
1006 | return SMP_ENC_KEY_SIZE; | 1024 | return SMP_ENC_KEY_SIZE; |
1007 | 1025 | ||
1026 | auth = rsp->auth_req & AUTH_REQ_MASK; | ||
1027 | |||
1008 | /* If we need MITM check that it can be acheived */ | 1028 | /* If we need MITM check that it can be acheived */ |
1009 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { | 1029 | if (conn->hcon->pending_sec_level >= BT_SECURITY_HIGH) { |
1010 | u8 method; | 1030 | u8 method; |
@@ -1025,11 +1045,7 @@ static u8 smp_cmd_pairing_rsp(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1025 | */ | 1045 | */ |
1026 | smp->remote_key_dist &= rsp->resp_key_dist; | 1046 | smp->remote_key_dist &= rsp->resp_key_dist; |
1027 | 1047 | ||
1028 | if ((req->auth_req & SMP_AUTH_BONDING) && | 1048 | auth |= req->auth_req; |
1029 | (rsp->auth_req & SMP_AUTH_BONDING)) | ||
1030 | auth = SMP_AUTH_BONDING; | ||
1031 | |||
1032 | auth |= (req->auth_req | rsp->auth_req) & SMP_AUTH_MITM; | ||
1033 | 1049 | ||
1034 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); | 1050 | ret = tk_request(conn, 0, auth, req->io_capability, rsp->io_capability); |
1035 | if (ret) | 1051 | if (ret) |
@@ -1057,10 +1073,14 @@ static u8 smp_cmd_pairing_confirm(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1057 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); | 1073 | memcpy(smp->pcnf, skb->data, sizeof(smp->pcnf)); |
1058 | skb_pull(skb, sizeof(smp->pcnf)); | 1074 | skb_pull(skb, sizeof(smp->pcnf)); |
1059 | 1075 | ||
1060 | if (conn->hcon->out) | 1076 | if (conn->hcon->out) { |
1061 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), | 1077 | smp_send_cmd(conn, SMP_CMD_PAIRING_RANDOM, sizeof(smp->prnd), |
1062 | smp->prnd); | 1078 | smp->prnd); |
1063 | else if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) | 1079 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RANDOM); |
1080 | return 0; | ||
1081 | } | ||
1082 | |||
1083 | if (test_bit(SMP_FLAG_TK_VALID, &smp->flags)) | ||
1064 | return smp_confirm(smp); | 1084 | return smp_confirm(smp); |
1065 | else | 1085 | else |
1066 | set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); | 1086 | set_bit(SMP_FLAG_CFM_PENDING, &smp->flags); |
@@ -1094,7 +1114,7 @@ static bool smp_ltk_encrypt(struct l2cap_conn *conn, u8 sec_level) | |||
1094 | if (!key) | 1114 | if (!key) |
1095 | return false; | 1115 | return false; |
1096 | 1116 | ||
1097 | if (sec_level > BT_SECURITY_MEDIUM && !key->authenticated) | 1117 | if (smp_ltk_sec_level(key) < sec_level) |
1098 | return false; | 1118 | return false; |
1099 | 1119 | ||
1100 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) | 1120 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->flags)) |
@@ -1137,7 +1157,7 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1137 | struct smp_cmd_pairing cp; | 1157 | struct smp_cmd_pairing cp; |
1138 | struct hci_conn *hcon = conn->hcon; | 1158 | struct hci_conn *hcon = conn->hcon; |
1139 | struct smp_chan *smp; | 1159 | struct smp_chan *smp; |
1140 | u8 sec_level; | 1160 | u8 sec_level, auth; |
1141 | 1161 | ||
1142 | BT_DBG("conn %p", conn); | 1162 | BT_DBG("conn %p", conn); |
1143 | 1163 | ||
@@ -1147,7 +1167,13 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1147 | if (hcon->role != HCI_ROLE_MASTER) | 1167 | if (hcon->role != HCI_ROLE_MASTER) |
1148 | return SMP_CMD_NOTSUPP; | 1168 | return SMP_CMD_NOTSUPP; |
1149 | 1169 | ||
1150 | sec_level = authreq_to_seclevel(rp->auth_req); | 1170 | auth = rp->auth_req & AUTH_REQ_MASK; |
1171 | |||
1172 | if (hcon->io_capability == HCI_IO_NO_INPUT_OUTPUT) | ||
1173 | sec_level = BT_SECURITY_MEDIUM; | ||
1174 | else | ||
1175 | sec_level = authreq_to_seclevel(auth); | ||
1176 | |||
1151 | if (smp_sufficient_security(hcon, sec_level)) | 1177 | if (smp_sufficient_security(hcon, sec_level)) |
1152 | return 0; | 1178 | return 0; |
1153 | 1179 | ||
@@ -1157,26 +1183,24 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1157 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) | 1183 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
1158 | return 0; | 1184 | return 0; |
1159 | 1185 | ||
1160 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | ||
1161 | return 0; | ||
1162 | |||
1163 | smp = smp_chan_create(conn); | 1186 | smp = smp_chan_create(conn); |
1164 | if (!smp) | 1187 | if (!smp) |
1165 | return SMP_UNSPECIFIED; | 1188 | return SMP_UNSPECIFIED; |
1166 | 1189 | ||
1167 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && | 1190 | if (!test_bit(HCI_BONDABLE, &hcon->hdev->dev_flags) && |
1168 | (rp->auth_req & SMP_AUTH_BONDING)) | 1191 | (auth & SMP_AUTH_BONDING)) |
1169 | return SMP_PAIRING_NOTSUPP; | 1192 | return SMP_PAIRING_NOTSUPP; |
1170 | 1193 | ||
1171 | skb_pull(skb, sizeof(*rp)); | 1194 | skb_pull(skb, sizeof(*rp)); |
1172 | 1195 | ||
1173 | memset(&cp, 0, sizeof(cp)); | 1196 | memset(&cp, 0, sizeof(cp)); |
1174 | build_pairing_cmd(conn, &cp, NULL, rp->auth_req); | 1197 | build_pairing_cmd(conn, &cp, NULL, auth); |
1175 | 1198 | ||
1176 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 1199 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
1177 | memcpy(&smp->preq[1], &cp, sizeof(cp)); | 1200 | memcpy(&smp->preq[1], &cp, sizeof(cp)); |
1178 | 1201 | ||
1179 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | 1202 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); |
1203 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); | ||
1180 | 1204 | ||
1181 | return 0; | 1205 | return 0; |
1182 | } | 1206 | } |
@@ -1184,8 +1208,10 @@ static u8 smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1184 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | 1208 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) |
1185 | { | 1209 | { |
1186 | struct l2cap_conn *conn = hcon->l2cap_data; | 1210 | struct l2cap_conn *conn = hcon->l2cap_data; |
1211 | struct l2cap_chan *chan; | ||
1187 | struct smp_chan *smp; | 1212 | struct smp_chan *smp; |
1188 | __u8 authreq; | 1213 | __u8 authreq; |
1214 | int ret; | ||
1189 | 1215 | ||
1190 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 1216 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
1191 | 1217 | ||
@@ -1193,6 +1219,8 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
1193 | if (!conn) | 1219 | if (!conn) |
1194 | return 1; | 1220 | return 1; |
1195 | 1221 | ||
1222 | chan = conn->smp; | ||
1223 | |||
1196 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) | 1224 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) |
1197 | return 1; | 1225 | return 1; |
1198 | 1226 | ||
@@ -1206,12 +1234,19 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
1206 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) | 1234 | if (smp_ltk_encrypt(conn, hcon->pending_sec_level)) |
1207 | return 0; | 1235 | return 0; |
1208 | 1236 | ||
1209 | if (test_and_set_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) | 1237 | l2cap_chan_lock(chan); |
1210 | return 0; | 1238 | |
1239 | /* If SMP is already in progress ignore this request */ | ||
1240 | if (chan->data) { | ||
1241 | ret = 0; | ||
1242 | goto unlock; | ||
1243 | } | ||
1211 | 1244 | ||
1212 | smp = smp_chan_create(conn); | 1245 | smp = smp_chan_create(conn); |
1213 | if (!smp) | 1246 | if (!smp) { |
1214 | return 1; | 1247 | ret = 1; |
1248 | goto unlock; | ||
1249 | } | ||
1215 | 1250 | ||
1216 | authreq = seclevel_to_authreq(sec_level); | 1251 | authreq = seclevel_to_authreq(sec_level); |
1217 | 1252 | ||
@@ -1230,15 +1265,20 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
1230 | memcpy(&smp->preq[1], &cp, sizeof(cp)); | 1265 | memcpy(&smp->preq[1], &cp, sizeof(cp)); |
1231 | 1266 | ||
1232 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); | 1267 | smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); |
1268 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_RSP); | ||
1233 | } else { | 1269 | } else { |
1234 | struct smp_cmd_security_req cp; | 1270 | struct smp_cmd_security_req cp; |
1235 | cp.auth_req = authreq; | 1271 | cp.auth_req = authreq; |
1236 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); | 1272 | smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); |
1273 | SMP_ALLOW_CMD(smp, SMP_CMD_PAIRING_REQ); | ||
1237 | } | 1274 | } |
1238 | 1275 | ||
1239 | set_bit(SMP_FLAG_INITIATOR, &smp->flags); | 1276 | set_bit(SMP_FLAG_INITIATOR, &smp->flags); |
1277 | ret = 0; | ||
1240 | 1278 | ||
1241 | return 0; | 1279 | unlock: |
1280 | l2cap_chan_unlock(chan); | ||
1281 | return ret; | ||
1242 | } | 1282 | } |
1243 | 1283 | ||
1244 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | 1284 | static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) |
@@ -1252,9 +1292,7 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1252 | if (skb->len < sizeof(*rp)) | 1292 | if (skb->len < sizeof(*rp)) |
1253 | return SMP_INVALID_PARAMS; | 1293 | return SMP_INVALID_PARAMS; |
1254 | 1294 | ||
1255 | /* Ignore this PDU if it wasn't requested */ | 1295 | SMP_ALLOW_CMD(smp, SMP_CMD_MASTER_IDENT); |
1256 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) | ||
1257 | return 0; | ||
1258 | 1296 | ||
1259 | skb_pull(skb, sizeof(*rp)); | 1297 | skb_pull(skb, sizeof(*rp)); |
1260 | 1298 | ||
@@ -1278,13 +1316,14 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1278 | if (skb->len < sizeof(*rp)) | 1316 | if (skb->len < sizeof(*rp)) |
1279 | return SMP_INVALID_PARAMS; | 1317 | return SMP_INVALID_PARAMS; |
1280 | 1318 | ||
1281 | /* Ignore this PDU if it wasn't requested */ | ||
1282 | if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY)) | ||
1283 | return 0; | ||
1284 | |||
1285 | /* Mark the information as received */ | 1319 | /* Mark the information as received */ |
1286 | smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; | 1320 | smp->remote_key_dist &= ~SMP_DIST_ENC_KEY; |
1287 | 1321 | ||
1322 | if (smp->remote_key_dist & SMP_DIST_ID_KEY) | ||
1323 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_INFO); | ||
1324 | else if (smp->remote_key_dist & SMP_DIST_SIGN) | ||
1325 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | ||
1326 | |||
1288 | skb_pull(skb, sizeof(*rp)); | 1327 | skb_pull(skb, sizeof(*rp)); |
1289 | 1328 | ||
1290 | hci_dev_lock(hdev); | 1329 | hci_dev_lock(hdev); |
@@ -1293,8 +1332,8 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1293 | authenticated, smp->tk, smp->enc_key_size, | 1332 | authenticated, smp->tk, smp->enc_key_size, |
1294 | rp->ediv, rp->rand); | 1333 | rp->ediv, rp->rand); |
1295 | smp->ltk = ltk; | 1334 | smp->ltk = ltk; |
1296 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | 1335 | if (!(smp->remote_key_dist & KEY_DIST_MASK)) |
1297 | queue_work(hdev->workqueue, &smp->distribute_work); | 1336 | smp_distribute_keys(smp); |
1298 | hci_dev_unlock(hdev); | 1337 | hci_dev_unlock(hdev); |
1299 | 1338 | ||
1300 | return 0; | 1339 | return 0; |
@@ -1311,9 +1350,7 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1311 | if (skb->len < sizeof(*info)) | 1350 | if (skb->len < sizeof(*info)) |
1312 | return SMP_INVALID_PARAMS; | 1351 | return SMP_INVALID_PARAMS; |
1313 | 1352 | ||
1314 | /* Ignore this PDU if it wasn't requested */ | 1353 | SMP_ALLOW_CMD(smp, SMP_CMD_IDENT_ADDR_INFO); |
1315 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | ||
1316 | return 0; | ||
1317 | 1354 | ||
1318 | skb_pull(skb, sizeof(*info)); | 1355 | skb_pull(skb, sizeof(*info)); |
1319 | 1356 | ||
@@ -1329,7 +1366,6 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1329 | struct l2cap_chan *chan = conn->smp; | 1366 | struct l2cap_chan *chan = conn->smp; |
1330 | struct smp_chan *smp = chan->data; | 1367 | struct smp_chan *smp = chan->data; |
1331 | struct hci_conn *hcon = conn->hcon; | 1368 | struct hci_conn *hcon = conn->hcon; |
1332 | struct hci_dev *hdev = hcon->hdev; | ||
1333 | bdaddr_t rpa; | 1369 | bdaddr_t rpa; |
1334 | 1370 | ||
1335 | BT_DBG(""); | 1371 | BT_DBG(""); |
@@ -1337,13 +1373,12 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1337 | if (skb->len < sizeof(*info)) | 1373 | if (skb->len < sizeof(*info)) |
1338 | return SMP_INVALID_PARAMS; | 1374 | return SMP_INVALID_PARAMS; |
1339 | 1375 | ||
1340 | /* Ignore this PDU if it wasn't requested */ | ||
1341 | if (!(smp->remote_key_dist & SMP_DIST_ID_KEY)) | ||
1342 | return 0; | ||
1343 | |||
1344 | /* Mark the information as received */ | 1376 | /* Mark the information as received */ |
1345 | smp->remote_key_dist &= ~SMP_DIST_ID_KEY; | 1377 | smp->remote_key_dist &= ~SMP_DIST_ID_KEY; |
1346 | 1378 | ||
1379 | if (smp->remote_key_dist & SMP_DIST_SIGN) | ||
1380 | SMP_ALLOW_CMD(smp, SMP_CMD_SIGN_INFO); | ||
1381 | |||
1347 | skb_pull(skb, sizeof(*info)); | 1382 | skb_pull(skb, sizeof(*info)); |
1348 | 1383 | ||
1349 | hci_dev_lock(hcon->hdev); | 1384 | hci_dev_lock(hcon->hdev); |
@@ -1372,7 +1407,8 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn, | |||
1372 | smp->id_addr_type, smp->irk, &rpa); | 1407 | smp->id_addr_type, smp->irk, &rpa); |
1373 | 1408 | ||
1374 | distribute: | 1409 | distribute: |
1375 | queue_work(hdev->workqueue, &smp->distribute_work); | 1410 | if (!(smp->remote_key_dist & KEY_DIST_MASK)) |
1411 | smp_distribute_keys(smp); | ||
1376 | 1412 | ||
1377 | hci_dev_unlock(hcon->hdev); | 1413 | hci_dev_unlock(hcon->hdev); |
1378 | 1414 | ||
@@ -1392,10 +1428,6 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1392 | if (skb->len < sizeof(*rp)) | 1428 | if (skb->len < sizeof(*rp)) |
1393 | return SMP_INVALID_PARAMS; | 1429 | return SMP_INVALID_PARAMS; |
1394 | 1430 | ||
1395 | /* Ignore this PDU if it wasn't requested */ | ||
1396 | if (!(smp->remote_key_dist & SMP_DIST_SIGN)) | ||
1397 | return 0; | ||
1398 | |||
1399 | /* Mark the information as received */ | 1431 | /* Mark the information as received */ |
1400 | smp->remote_key_dist &= ~SMP_DIST_SIGN; | 1432 | smp->remote_key_dist &= ~SMP_DIST_SIGN; |
1401 | 1433 | ||
@@ -1408,7 +1440,7 @@ static int smp_cmd_sign_info(struct l2cap_conn *conn, struct sk_buff *skb) | |||
1408 | memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); | 1440 | memcpy(csrk->val, rp->csrk, sizeof(csrk->val)); |
1409 | } | 1441 | } |
1410 | smp->csrk = csrk; | 1442 | smp->csrk = csrk; |
1411 | queue_work(hdev->workqueue, &smp->distribute_work); | 1443 | smp_distribute_keys(smp); |
1412 | hci_dev_unlock(hdev); | 1444 | hci_dev_unlock(hdev); |
1413 | 1445 | ||
1414 | return 0; | 1446 | return 0; |
@@ -1418,6 +1450,7 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1418 | { | 1450 | { |
1419 | struct l2cap_conn *conn = chan->conn; | 1451 | struct l2cap_conn *conn = chan->conn; |
1420 | struct hci_conn *hcon = conn->hcon; | 1452 | struct hci_conn *hcon = conn->hcon; |
1453 | struct smp_chan *smp; | ||
1421 | __u8 code, reason; | 1454 | __u8 code, reason; |
1422 | int err = 0; | 1455 | int err = 0; |
1423 | 1456 | ||
@@ -1430,7 +1463,6 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1430 | return -EILSEQ; | 1463 | return -EILSEQ; |
1431 | 1464 | ||
1432 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { | 1465 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) { |
1433 | err = -EOPNOTSUPP; | ||
1434 | reason = SMP_PAIRING_NOTSUPP; | 1466 | reason = SMP_PAIRING_NOTSUPP; |
1435 | goto done; | 1467 | goto done; |
1436 | } | 1468 | } |
@@ -1438,19 +1470,19 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1438 | code = skb->data[0]; | 1470 | code = skb->data[0]; |
1439 | skb_pull(skb, sizeof(code)); | 1471 | skb_pull(skb, sizeof(code)); |
1440 | 1472 | ||
1441 | /* | 1473 | smp = chan->data; |
1442 | * The SMP context must be initialized for all other PDUs except | 1474 | |
1443 | * pairing and security requests. If we get any other PDU when | 1475 | if (code > SMP_CMD_MAX) |
1444 | * not initialized simply disconnect (done if this function | 1476 | goto drop; |
1445 | * returns an error). | 1477 | |
1478 | if (smp && !test_and_clear_bit(code, &smp->allow_cmd)) | ||
1479 | goto drop; | ||
1480 | |||
1481 | /* If we don't have a context the only allowed commands are | ||
1482 | * pairing request and security request. | ||
1446 | */ | 1483 | */ |
1447 | if (code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ && | 1484 | if (!smp && code != SMP_CMD_PAIRING_REQ && code != SMP_CMD_SECURITY_REQ) |
1448 | !test_bit(HCI_CONN_LE_SMP_PEND, &hcon->flags)) { | 1485 | goto drop; |
1449 | BT_ERR("Unexpected SMP command 0x%02x. Disconnecting.", code); | ||
1450 | reason = SMP_CMD_NOTSUPP; | ||
1451 | err = -EOPNOTSUPP; | ||
1452 | goto done; | ||
1453 | } | ||
1454 | 1486 | ||
1455 | switch (code) { | 1487 | switch (code) { |
1456 | case SMP_CMD_PAIRING_REQ: | 1488 | case SMP_CMD_PAIRING_REQ: |
@@ -1459,7 +1491,6 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1459 | 1491 | ||
1460 | case SMP_CMD_PAIRING_FAIL: | 1492 | case SMP_CMD_PAIRING_FAIL: |
1461 | smp_failure(conn, 0); | 1493 | smp_failure(conn, 0); |
1462 | reason = 0; | ||
1463 | err = -EPERM; | 1494 | err = -EPERM; |
1464 | break; | 1495 | break; |
1465 | 1496 | ||
@@ -1501,18 +1532,24 @@ static int smp_sig_channel(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1501 | 1532 | ||
1502 | default: | 1533 | default: |
1503 | BT_DBG("Unknown command code 0x%2.2x", code); | 1534 | BT_DBG("Unknown command code 0x%2.2x", code); |
1504 | |||
1505 | reason = SMP_CMD_NOTSUPP; | 1535 | reason = SMP_CMD_NOTSUPP; |
1506 | err = -EOPNOTSUPP; | ||
1507 | goto done; | 1536 | goto done; |
1508 | } | 1537 | } |
1509 | 1538 | ||
1510 | done: | 1539 | done: |
1511 | if (reason) | 1540 | if (!err) { |
1512 | smp_failure(conn, reason); | 1541 | if (reason) |
1513 | if (!err) | 1542 | smp_failure(conn, reason); |
1514 | kfree_skb(skb); | 1543 | kfree_skb(skb); |
1544 | } | ||
1545 | |||
1515 | return err; | 1546 | return err; |
1547 | |||
1548 | drop: | ||
1549 | BT_ERR("%s unexpected SMP command 0x%02x from %pMR", hcon->hdev->name, | ||
1550 | code, &hcon->dst); | ||
1551 | kfree_skb(skb); | ||
1552 | return 0; | ||
1516 | } | 1553 | } |
1517 | 1554 | ||
1518 | static void smp_teardown_cb(struct l2cap_chan *chan, int err) | 1555 | static void smp_teardown_cb(struct l2cap_chan *chan, int err) |
@@ -1521,7 +1558,7 @@ static void smp_teardown_cb(struct l2cap_chan *chan, int err) | |||
1521 | 1558 | ||
1522 | BT_DBG("chan %p", chan); | 1559 | BT_DBG("chan %p", chan); |
1523 | 1560 | ||
1524 | if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | 1561 | if (chan->data) |
1525 | smp_chan_destroy(conn); | 1562 | smp_chan_destroy(conn); |
1526 | 1563 | ||
1527 | conn->smp = NULL; | 1564 | conn->smp = NULL; |
@@ -1533,17 +1570,18 @@ static void smp_resume_cb(struct l2cap_chan *chan) | |||
1533 | struct smp_chan *smp = chan->data; | 1570 | struct smp_chan *smp = chan->data; |
1534 | struct l2cap_conn *conn = chan->conn; | 1571 | struct l2cap_conn *conn = chan->conn; |
1535 | struct hci_conn *hcon = conn->hcon; | 1572 | struct hci_conn *hcon = conn->hcon; |
1536 | struct hci_dev *hdev = hcon->hdev; | ||
1537 | 1573 | ||
1538 | BT_DBG("chan %p", chan); | 1574 | BT_DBG("chan %p", chan); |
1539 | 1575 | ||
1540 | if (!smp) | 1576 | if (!smp) |
1541 | return; | 1577 | return; |
1542 | 1578 | ||
1579 | if (!test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) | ||
1580 | return; | ||
1581 | |||
1543 | cancel_delayed_work(&smp->security_timer); | 1582 | cancel_delayed_work(&smp->security_timer); |
1544 | 1583 | ||
1545 | if (test_bit(HCI_CONN_ENCRYPT, &hcon->flags)) | 1584 | smp_distribute_keys(smp); |
1546 | queue_work(hdev->workqueue, &smp->distribute_work); | ||
1547 | } | 1585 | } |
1548 | 1586 | ||
1549 | static void smp_ready_cb(struct l2cap_chan *chan) | 1587 | static void smp_ready_cb(struct l2cap_chan *chan) |
@@ -1569,7 +1607,7 @@ static int smp_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb) | |||
1569 | if (smp) | 1607 | if (smp) |
1570 | cancel_delayed_work_sync(&smp->security_timer); | 1608 | cancel_delayed_work_sync(&smp->security_timer); |
1571 | 1609 | ||
1572 | l2cap_conn_shutdown(chan->conn, -err); | 1610 | hci_disconnect(chan->conn->hcon, HCI_ERROR_AUTH_FAILURE); |
1573 | } | 1611 | } |
1574 | 1612 | ||
1575 | return err; | 1613 | return err; |
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h index cf1094617c69..86a683a8b491 100644 --- a/net/bluetooth/smp.h +++ b/net/bluetooth/smp.h | |||
@@ -102,6 +102,8 @@ struct smp_cmd_security_req { | |||
102 | __u8 auth_req; | 102 | __u8 auth_req; |
103 | } __packed; | 103 | } __packed; |
104 | 104 | ||
105 | #define SMP_CMD_MAX 0x0b | ||
106 | |||
105 | #define SMP_PASSKEY_ENTRY_FAILED 0x01 | 107 | #define SMP_PASSKEY_ENTRY_FAILED 0x01 |
106 | #define SMP_OOB_NOT_AVAIL 0x02 | 108 | #define SMP_OOB_NOT_AVAIL 0x02 |
107 | #define SMP_AUTH_REQUIREMENTS 0x03 | 109 | #define SMP_AUTH_REQUIREMENTS 0x03 |
@@ -123,6 +125,14 @@ enum { | |||
123 | SMP_LTK_SLAVE, | 125 | SMP_LTK_SLAVE, |
124 | }; | 126 | }; |
125 | 127 | ||
128 | static inline u8 smp_ltk_sec_level(struct smp_ltk *key) | ||
129 | { | ||
130 | if (key->authenticated) | ||
131 | return BT_SECURITY_HIGH; | ||
132 | |||
133 | return BT_SECURITY_MEDIUM; | ||
134 | } | ||
135 | |||
126 | /* SMP Commands */ | 136 | /* SMP Commands */ |
127 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); | 137 | bool smp_sufficient_security(struct hci_conn *hcon, u8 sec_level); |
128 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); | 138 | int smp_conn_security(struct hci_conn *hcon, __u8 sec_level); |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index f0e84bc48038..a48bad468880 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -227,7 +227,7 @@ static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *d | |||
227 | void __ieee80211_start_rx_ba_session(struct sta_info *sta, | 227 | void __ieee80211_start_rx_ba_session(struct sta_info *sta, |
228 | u8 dialog_token, u16 timeout, | 228 | u8 dialog_token, u16 timeout, |
229 | u16 start_seq_num, u16 ba_policy, u16 tid, | 229 | u16 start_seq_num, u16 ba_policy, u16 tid, |
230 | u16 buf_size, bool tx) | 230 | u16 buf_size, bool tx, bool auto_seq) |
231 | { | 231 | { |
232 | struct ieee80211_local *local = sta->sdata->local; | 232 | struct ieee80211_local *local = sta->sdata->local; |
233 | struct tid_ampdu_rx *tid_agg_rx; | 233 | struct tid_ampdu_rx *tid_agg_rx; |
@@ -326,6 +326,7 @@ void __ieee80211_start_rx_ba_session(struct sta_info *sta, | |||
326 | tid_agg_rx->buf_size = buf_size; | 326 | tid_agg_rx->buf_size = buf_size; |
327 | tid_agg_rx->timeout = timeout; | 327 | tid_agg_rx->timeout = timeout; |
328 | tid_agg_rx->stored_mpdu_num = 0; | 328 | tid_agg_rx->stored_mpdu_num = 0; |
329 | tid_agg_rx->auto_seq = auto_seq; | ||
329 | status = WLAN_STATUS_SUCCESS; | 330 | status = WLAN_STATUS_SUCCESS; |
330 | 331 | ||
331 | /* activate it for RX */ | 332 | /* activate it for RX */ |
@@ -367,7 +368,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
367 | 368 | ||
368 | __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, | 369 | __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, |
369 | start_seq_num, ba_policy, tid, | 370 | start_seq_num, ba_policy, tid, |
370 | buf_size, true); | 371 | buf_size, true, false); |
371 | } | 372 | } |
372 | 373 | ||
373 | void ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, | 374 | void ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 4d8989b87960..fb6a1502b6df 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * mac80211 configuration hooks for cfg80211 | 2 | * mac80211 configuration hooks for cfg80211 |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | * | 6 | * |
6 | * This file is GPLv2 as found in COPYING. | 7 | * This file is GPLv2 as found in COPYING. |
7 | */ | 8 | */ |
@@ -682,8 +683,19 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
682 | if (old) | 683 | if (old) |
683 | return -EALREADY; | 684 | return -EALREADY; |
684 | 685 | ||
685 | /* TODO: make hostapd tell us what it wants */ | 686 | switch (params->smps_mode) { |
686 | sdata->smps_mode = IEEE80211_SMPS_OFF; | 687 | case NL80211_SMPS_OFF: |
688 | sdata->smps_mode = IEEE80211_SMPS_OFF; | ||
689 | break; | ||
690 | case NL80211_SMPS_STATIC: | ||
691 | sdata->smps_mode = IEEE80211_SMPS_STATIC; | ||
692 | break; | ||
693 | case NL80211_SMPS_DYNAMIC: | ||
694 | sdata->smps_mode = IEEE80211_SMPS_DYNAMIC; | ||
695 | break; | ||
696 | default: | ||
697 | return -EINVAL; | ||
698 | } | ||
687 | sdata->needed_rx_chains = sdata->local->rx_chains; | 699 | sdata->needed_rx_chains = sdata->local->rx_chains; |
688 | 700 | ||
689 | mutex_lock(&local->mtx); | 701 | mutex_lock(&local->mtx); |
@@ -1977,8 +1989,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) | |||
1977 | return err; | 1989 | return err; |
1978 | } | 1990 | } |
1979 | 1991 | ||
1980 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) { | 1992 | if ((changed & WIPHY_PARAM_COVERAGE_CLASS) || |
1981 | err = drv_set_coverage_class(local, wiphy->coverage_class); | 1993 | (changed & WIPHY_PARAM_DYN_ACK)) { |
1994 | s16 coverage_class; | ||
1995 | |||
1996 | coverage_class = changed & WIPHY_PARAM_COVERAGE_CLASS ? | ||
1997 | wiphy->coverage_class : -1; | ||
1998 | err = drv_set_coverage_class(local, coverage_class); | ||
1982 | 1999 | ||
1983 | if (err) | 2000 | if (err) |
1984 | return err; | 2001 | return err; |
@@ -2351,6 +2368,58 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
2351 | return 0; | 2368 | return 0; |
2352 | } | 2369 | } |
2353 | 2370 | ||
2371 | static bool ieee80211_coalesce_started_roc(struct ieee80211_local *local, | ||
2372 | struct ieee80211_roc_work *new_roc, | ||
2373 | struct ieee80211_roc_work *cur_roc) | ||
2374 | { | ||
2375 | unsigned long j = jiffies; | ||
2376 | unsigned long cur_roc_end = cur_roc->hw_start_time + | ||
2377 | msecs_to_jiffies(cur_roc->duration); | ||
2378 | struct ieee80211_roc_work *next_roc; | ||
2379 | int new_dur; | ||
2380 | |||
2381 | if (WARN_ON(!cur_roc->started || !cur_roc->hw_begun)) | ||
2382 | return false; | ||
2383 | |||
2384 | if (time_after(j + IEEE80211_ROC_MIN_LEFT, cur_roc_end)) | ||
2385 | return false; | ||
2386 | |||
2387 | ieee80211_handle_roc_started(new_roc); | ||
2388 | |||
2389 | new_dur = new_roc->duration - jiffies_to_msecs(cur_roc_end - j); | ||
2390 | |||
2391 | /* cur_roc is long enough - add new_roc to the dependents list. */ | ||
2392 | if (new_dur <= 0) { | ||
2393 | list_add_tail(&new_roc->list, &cur_roc->dependents); | ||
2394 | return true; | ||
2395 | } | ||
2396 | |||
2397 | new_roc->duration = new_dur; | ||
2398 | |||
2399 | /* | ||
2400 | * if cur_roc was already coalesced before, we might | ||
2401 | * want to extend the next roc instead of adding | ||
2402 | * a new one. | ||
2403 | */ | ||
2404 | next_roc = list_entry(cur_roc->list.next, | ||
2405 | struct ieee80211_roc_work, list); | ||
2406 | if (&next_roc->list != &local->roc_list && | ||
2407 | next_roc->chan == new_roc->chan && | ||
2408 | next_roc->sdata == new_roc->sdata && | ||
2409 | !WARN_ON(next_roc->started)) { | ||
2410 | list_add_tail(&new_roc->list, &next_roc->dependents); | ||
2411 | next_roc->duration = max(next_roc->duration, | ||
2412 | new_roc->duration); | ||
2413 | next_roc->type = max(next_roc->type, new_roc->type); | ||
2414 | return true; | ||
2415 | } | ||
2416 | |||
2417 | /* add right after cur_roc */ | ||
2418 | list_add(&new_roc->list, &cur_roc->list); | ||
2419 | |||
2420 | return true; | ||
2421 | } | ||
2422 | |||
2354 | static int ieee80211_start_roc_work(struct ieee80211_local *local, | 2423 | static int ieee80211_start_roc_work(struct ieee80211_local *local, |
2355 | struct ieee80211_sub_if_data *sdata, | 2424 | struct ieee80211_sub_if_data *sdata, |
2356 | struct ieee80211_channel *channel, | 2425 | struct ieee80211_channel *channel, |
@@ -2456,8 +2525,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2456 | 2525 | ||
2457 | /* If it has already started, it's more difficult ... */ | 2526 | /* If it has already started, it's more difficult ... */ |
2458 | if (local->ops->remain_on_channel) { | 2527 | if (local->ops->remain_on_channel) { |
2459 | unsigned long j = jiffies; | ||
2460 | |||
2461 | /* | 2528 | /* |
2462 | * In the offloaded ROC case, if it hasn't begun, add | 2529 | * In the offloaded ROC case, if it hasn't begun, add |
2463 | * this new one to the dependent list to be handled | 2530 | * this new one to the dependent list to be handled |
@@ -2480,28 +2547,8 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local, | |||
2480 | break; | 2547 | break; |
2481 | } | 2548 | } |
2482 | 2549 | ||
2483 | if (time_before(j + IEEE80211_ROC_MIN_LEFT, | 2550 | if (ieee80211_coalesce_started_roc(local, roc, tmp)) |
2484 | tmp->hw_start_time + | ||
2485 | msecs_to_jiffies(tmp->duration))) { | ||
2486 | int new_dur; | ||
2487 | |||
2488 | ieee80211_handle_roc_started(roc); | ||
2489 | |||
2490 | new_dur = roc->duration - | ||
2491 | jiffies_to_msecs(tmp->hw_start_time + | ||
2492 | msecs_to_jiffies( | ||
2493 | tmp->duration) - | ||
2494 | j); | ||
2495 | |||
2496 | if (new_dur > 0) { | ||
2497 | /* add right after tmp */ | ||
2498 | list_add(&roc->list, &tmp->list); | ||
2499 | } else { | ||
2500 | list_add_tail(&roc->list, | ||
2501 | &tmp->dependents); | ||
2502 | } | ||
2503 | queued = true; | 2551 | queued = true; |
2504 | } | ||
2505 | } else if (del_timer_sync(&tmp->work.timer)) { | 2552 | } else if (del_timer_sync(&tmp->work.timer)) { |
2506 | unsigned long new_end; | 2553 | unsigned long new_end; |
2507 | 2554 | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 0e963bc1ceac..54a189f0393e 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * mac80211 debugfs for wireless PHYs | 3 | * mac80211 debugfs for wireless PHYs |
4 | * | 4 | * |
5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * GPLv2 | 8 | * GPLv2 |
8 | * | 9 | * |
@@ -302,11 +303,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, | |||
302 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); | 303 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); |
303 | if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) | 304 | if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) |
304 | sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); | 305 | sf += scnprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); |
305 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) | ||
306 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n"); | ||
307 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) | ||
308 | sf += scnprintf(buf + sf, mxln - sf, | ||
309 | "SUPPORTS_DYNAMIC_SMPS\n"); | ||
310 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) | 306 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) |
311 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); | 307 | sf += scnprintf(buf + sf, mxln - sf, "SUPPORTS_UAPSD\n"); |
312 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 308 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index e205ebabfa50..c68896adfa96 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -226,12 +226,12 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, | |||
226 | struct ieee80211_local *local = sdata->local; | 226 | struct ieee80211_local *local = sdata->local; |
227 | int err; | 227 | int err; |
228 | 228 | ||
229 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) && | 229 | if (!(local->hw.wiphy->features & NL80211_FEATURE_STATIC_SMPS) && |
230 | smps_mode == IEEE80211_SMPS_STATIC) | 230 | smps_mode == IEEE80211_SMPS_STATIC) |
231 | return -EINVAL; | 231 | return -EINVAL; |
232 | 232 | ||
233 | /* auto should be dynamic if in PS mode */ | 233 | /* auto should be dynamic if in PS mode */ |
234 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) && | 234 | if (!(local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS) && |
235 | (smps_mode == IEEE80211_SMPS_DYNAMIC || | 235 | (smps_mode == IEEE80211_SMPS_DYNAMIC || |
236 | smps_mode == IEEE80211_SMPS_AUTOMATIC)) | 236 | smps_mode == IEEE80211_SMPS_AUTOMATIC)) |
237 | return -EINVAL; | 237 | return -EINVAL; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 33eb4a43a2f3..bafe48916229 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright 2003-2005 Devicescape Software, Inc. | 2 | * Copyright 2003-2005 Devicescape Software, Inc. |
3 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> | 3 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> |
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 11423958116a..196d48c68134 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -450,7 +450,7 @@ static inline int drv_set_rts_threshold(struct ieee80211_local *local, | |||
450 | } | 450 | } |
451 | 451 | ||
452 | static inline int drv_set_coverage_class(struct ieee80211_local *local, | 452 | static inline int drv_set_coverage_class(struct ieee80211_local *local, |
453 | u8 value) | 453 | s16 value) |
454 | { | 454 | { |
455 | int ret = 0; | 455 | int ret = 0; |
456 | might_sleep(); | 456 | might_sleep(); |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 5f9654d31a8d..56b53571c807 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 6 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
7 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 7 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
8 | * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> | 8 | * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> |
9 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ffb20e5e6cf3..c2aaec4dfcf0 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -354,6 +355,7 @@ enum ieee80211_sta_flags { | |||
354 | IEEE80211_STA_DISABLE_80P80MHZ = BIT(12), | 355 | IEEE80211_STA_DISABLE_80P80MHZ = BIT(12), |
355 | IEEE80211_STA_DISABLE_160MHZ = BIT(13), | 356 | IEEE80211_STA_DISABLE_160MHZ = BIT(13), |
356 | IEEE80211_STA_DISABLE_WMM = BIT(14), | 357 | IEEE80211_STA_DISABLE_WMM = BIT(14), |
358 | IEEE80211_STA_ENABLE_RRM = BIT(15), | ||
357 | }; | 359 | }; |
358 | 360 | ||
359 | struct ieee80211_mgd_auth_data { | 361 | struct ieee80211_mgd_auth_data { |
@@ -1367,6 +1369,7 @@ struct ieee802_11_elems { | |||
1367 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; | 1369 | const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie; |
1368 | const u8 *country_elem; | 1370 | const u8 *country_elem; |
1369 | const u8 *pwr_constr_elem; | 1371 | const u8 *pwr_constr_elem; |
1372 | const u8 *cisco_dtpc_elem; | ||
1370 | const struct ieee80211_timeout_interval_ie *timeout_int; | 1373 | const struct ieee80211_timeout_interval_ie *timeout_int; |
1371 | const u8 *opmode_notif; | 1374 | const u8 *opmode_notif; |
1372 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; | 1375 | const struct ieee80211_sec_chan_offs_ie *sec_chan_offs; |
@@ -1587,7 +1590,7 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
1587 | void __ieee80211_start_rx_ba_session(struct sta_info *sta, | 1590 | void __ieee80211_start_rx_ba_session(struct sta_info *sta, |
1588 | u8 dialog_token, u16 timeout, | 1591 | u8 dialog_token, u16 timeout, |
1589 | u16 start_seq_num, u16 ba_policy, u16 tid, | 1592 | u16 start_seq_num, u16 ba_policy, u16 tid, |
1590 | u16 buf_size, bool tx); | 1593 | u16 buf_size, bool tx, bool auto_seq); |
1591 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, | 1594 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, |
1592 | enum ieee80211_agg_stop_reason reason); | 1595 | enum ieee80211_agg_stop_reason reason); |
1593 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | 1596 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, |
@@ -1917,7 +1920,7 @@ int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
1917 | size_t extra_ies_len); | 1920 | size_t extra_ies_len); |
1918 | int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | 1921 | int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, |
1919 | const u8 *peer, enum nl80211_tdls_operation oper); | 1922 | const u8 *peer, enum nl80211_tdls_operation oper); |
1920 | 1923 | void ieee80211_tdls_peer_del_work(struct work_struct *wk); | |
1921 | 1924 | ||
1922 | extern const struct ethtool_ops ieee80211_ethtool_ops; | 1925 | extern const struct ethtool_ops ieee80211_ethtool_ops; |
1923 | 1926 | ||
@@ -1928,4 +1931,3 @@ extern const struct ethtool_ops ieee80211_ethtool_ops; | |||
1928 | #endif | 1931 | #endif |
1929 | 1932 | ||
1930 | #endif /* IEEE80211_I_H */ | 1933 | #endif /* IEEE80211_I_H */ |
1931 | void ieee80211_tdls_peer_del_work(struct work_struct *wk); | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index f75e5f132c5a..af237223a8cd 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright 2005-2006, Devicescape Software, Inc. | 5 | * Copyright 2005-2006, Devicescape Software, Inc. |
6 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> | 6 | * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> |
7 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> | 7 | * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> |
8 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -1172,19 +1173,11 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
1172 | rx_agg = (void *)&skb->cb; | 1173 | rx_agg = (void *)&skb->cb; |
1173 | mutex_lock(&local->sta_mtx); | 1174 | mutex_lock(&local->sta_mtx); |
1174 | sta = sta_info_get_bss(sdata, rx_agg->addr); | 1175 | sta = sta_info_get_bss(sdata, rx_agg->addr); |
1175 | if (sta) { | 1176 | if (sta) |
1176 | u16 last_seq; | ||
1177 | |||
1178 | last_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu( | ||
1179 | sta->last_seq_ctrl[rx_agg->tid])); | ||
1180 | |||
1181 | __ieee80211_start_rx_ba_session(sta, | 1177 | __ieee80211_start_rx_ba_session(sta, |
1182 | 0, 0, | 1178 | 0, 0, 0, 1, rx_agg->tid, |
1183 | ieee80211_sn_inc(last_seq), | ||
1184 | 1, rx_agg->tid, | ||
1185 | IEEE80211_MAX_AMPDU_BUF, | 1179 | IEEE80211_MAX_AMPDU_BUF, |
1186 | false); | 1180 | false, true); |
1187 | } | ||
1188 | mutex_unlock(&local->sta_mtx); | 1181 | mutex_unlock(&local->sta_mtx); |
1189 | } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) { | 1182 | } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) { |
1190 | rx_agg = (void *)&skb->cb; | 1183 | rx_agg = (void *)&skb->cb; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 6429d0e1d4a1..4712150dc210 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -421,7 +422,7 @@ static void ieee80211_key_free_common(struct ieee80211_key *key) | |||
421 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 422 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
422 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) | 423 | if (key->conf.cipher == WLAN_CIPHER_SUITE_AES_CMAC) |
423 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 424 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
424 | kfree(key); | 425 | kzfree(key); |
425 | } | 426 | } |
426 | 427 | ||
427 | static void __ieee80211_key_destroy(struct ieee80211_key *key, | 428 | static void __ieee80211_key_destroy(struct ieee80211_key *key, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index e0ab4320a078..0de7c93bf62b 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * 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 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 8a73de6a5f5b..2de88704278b 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -5,6 +5,7 @@ | |||
5 | * Copyright 2005, Devicescape Software, Inc. | 5 | * Copyright 2005, Devicescape Software, Inc. |
6 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 6 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
7 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 7 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
8 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
@@ -172,7 +173,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
172 | 173 | ||
173 | if (!(ht_cap->cap_info & | 174 | if (!(ht_cap->cap_info & |
174 | cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) { | 175 | cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) { |
175 | ret = IEEE80211_STA_DISABLE_40MHZ | IEEE80211_STA_DISABLE_VHT; | 176 | ret = IEEE80211_STA_DISABLE_40MHZ; |
176 | goto out; | 177 | goto out; |
177 | } | 178 | } |
178 | 179 | ||
@@ -672,6 +673,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
672 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | 673 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) |
673 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 674 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
674 | 675 | ||
676 | if (ifmgd->flags & IEEE80211_STA_ENABLE_RRM) | ||
677 | capab |= WLAN_CAPABILITY_RADIO_MEASURE; | ||
678 | |||
675 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | 679 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); |
676 | memset(mgmt, 0, 24); | 680 | memset(mgmt, 0, 24); |
677 | memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN); | 681 | memcpy(mgmt->da, assoc_data->bss->bssid, ETH_ALEN); |
@@ -737,16 +741,17 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
737 | } | 741 | } |
738 | } | 742 | } |
739 | 743 | ||
740 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { | 744 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT || |
741 | /* 1. power capabilities */ | 745 | capab & WLAN_CAPABILITY_RADIO_MEASURE) { |
742 | pos = skb_put(skb, 4); | 746 | pos = skb_put(skb, 4); |
743 | *pos++ = WLAN_EID_PWR_CAPABILITY; | 747 | *pos++ = WLAN_EID_PWR_CAPABILITY; |
744 | *pos++ = 2; | 748 | *pos++ = 2; |
745 | *pos++ = 0; /* min tx power */ | 749 | *pos++ = 0; /* min tx power */ |
746 | /* max tx power */ | 750 | /* max tx power */ |
747 | *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def); | 751 | *pos++ = ieee80211_chandef_max_power(&chanctx_conf->def); |
752 | } | ||
748 | 753 | ||
749 | /* 2. supported channels */ | 754 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { |
750 | /* TODO: get this in reg domain format */ | 755 | /* TODO: get this in reg domain format */ |
751 | pos = skb_put(skb, 2 * sband->n_channels + 2); | 756 | pos = skb_put(skb, 2 * sband->n_channels + 2); |
752 | *pos++ = WLAN_EID_SUPPORTED_CHANNELS; | 757 | *pos++ = WLAN_EID_SUPPORTED_CHANNELS; |
@@ -1166,19 +1171,21 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1166 | TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); | 1171 | TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval)); |
1167 | } | 1172 | } |
1168 | 1173 | ||
1169 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | 1174 | static bool |
1170 | struct ieee80211_channel *channel, | 1175 | ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata, |
1171 | const u8 *country_ie, u8 country_ie_len, | 1176 | struct ieee80211_channel *channel, |
1172 | const u8 *pwr_constr_elem) | 1177 | const u8 *country_ie, u8 country_ie_len, |
1178 | const u8 *pwr_constr_elem, | ||
1179 | int *chan_pwr, int *pwr_reduction) | ||
1173 | { | 1180 | { |
1174 | struct ieee80211_country_ie_triplet *triplet; | 1181 | struct ieee80211_country_ie_triplet *triplet; |
1175 | int chan = ieee80211_frequency_to_channel(channel->center_freq); | 1182 | int chan = ieee80211_frequency_to_channel(channel->center_freq); |
1176 | int i, chan_pwr, chan_increment, new_ap_level; | 1183 | int i, chan_increment; |
1177 | bool have_chan_pwr = false; | 1184 | bool have_chan_pwr = false; |
1178 | 1185 | ||
1179 | /* Invalid IE */ | 1186 | /* Invalid IE */ |
1180 | if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) | 1187 | if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN) |
1181 | return 0; | 1188 | return false; |
1182 | 1189 | ||
1183 | triplet = (void *)(country_ie + 3); | 1190 | triplet = (void *)(country_ie + 3); |
1184 | country_ie_len -= 3; | 1191 | country_ie_len -= 3; |
@@ -1206,7 +1213,7 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | |||
1206 | for (i = 0; i < triplet->chans.num_channels; i++) { | 1213 | for (i = 0; i < triplet->chans.num_channels; i++) { |
1207 | if (first_channel + i * chan_increment == chan) { | 1214 | if (first_channel + i * chan_increment == chan) { |
1208 | have_chan_pwr = true; | 1215 | have_chan_pwr = true; |
1209 | chan_pwr = triplet->chans.max_power; | 1216 | *chan_pwr = triplet->chans.max_power; |
1210 | break; | 1217 | break; |
1211 | } | 1218 | } |
1212 | } | 1219 | } |
@@ -1218,18 +1225,76 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | |||
1218 | country_ie_len -= 3; | 1225 | country_ie_len -= 3; |
1219 | } | 1226 | } |
1220 | 1227 | ||
1221 | if (!have_chan_pwr) | 1228 | if (have_chan_pwr) |
1229 | *pwr_reduction = *pwr_constr_elem; | ||
1230 | return have_chan_pwr; | ||
1231 | } | ||
1232 | |||
1233 | static void ieee80211_find_cisco_dtpc(struct ieee80211_sub_if_data *sdata, | ||
1234 | struct ieee80211_channel *channel, | ||
1235 | const u8 *cisco_dtpc_ie, | ||
1236 | int *pwr_level) | ||
1237 | { | ||
1238 | /* From practical testing, the first data byte of the DTPC element | ||
1239 | * seems to contain the requested dBm level, and the CLI on Cisco | ||
1240 | * APs clearly state the range is -127 to 127 dBm, which indicates | ||
1241 | * a signed byte, although it seemingly never actually goes negative. | ||
1242 | * The other byte seems to always be zero. | ||
1243 | */ | ||
1244 | *pwr_level = (__s8)cisco_dtpc_ie[4]; | ||
1245 | } | ||
1246 | |||
1247 | static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata, | ||
1248 | struct ieee80211_channel *channel, | ||
1249 | struct ieee80211_mgmt *mgmt, | ||
1250 | const u8 *country_ie, u8 country_ie_len, | ||
1251 | const u8 *pwr_constr_ie, | ||
1252 | const u8 *cisco_dtpc_ie) | ||
1253 | { | ||
1254 | bool has_80211h_pwr = false, has_cisco_pwr = false; | ||
1255 | int chan_pwr = 0, pwr_reduction_80211h = 0; | ||
1256 | int pwr_level_cisco, pwr_level_80211h; | ||
1257 | int new_ap_level; | ||
1258 | |||
1259 | if (country_ie && pwr_constr_ie && | ||
1260 | mgmt->u.probe_resp.capab_info & | ||
1261 | cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) { | ||
1262 | has_80211h_pwr = ieee80211_find_80211h_pwr_constr( | ||
1263 | sdata, channel, country_ie, country_ie_len, | ||
1264 | pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h); | ||
1265 | pwr_level_80211h = | ||
1266 | max_t(int, 0, chan_pwr - pwr_reduction_80211h); | ||
1267 | } | ||
1268 | |||
1269 | if (cisco_dtpc_ie) { | ||
1270 | ieee80211_find_cisco_dtpc( | ||
1271 | sdata, channel, cisco_dtpc_ie, &pwr_level_cisco); | ||
1272 | has_cisco_pwr = true; | ||
1273 | } | ||
1274 | |||
1275 | if (!has_80211h_pwr && !has_cisco_pwr) | ||
1222 | return 0; | 1276 | return 0; |
1223 | 1277 | ||
1224 | new_ap_level = max_t(int, 0, chan_pwr - *pwr_constr_elem); | 1278 | /* If we have both 802.11h and Cisco DTPC, apply both limits |
1279 | * by picking the smallest of the two power levels advertised. | ||
1280 | */ | ||
1281 | if (has_80211h_pwr && | ||
1282 | (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) { | ||
1283 | sdata_info(sdata, | ||
1284 | "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", | ||
1285 | pwr_level_80211h, chan_pwr, pwr_reduction_80211h, | ||
1286 | sdata->u.mgd.bssid); | ||
1287 | new_ap_level = pwr_level_80211h; | ||
1288 | } else { /* has_cisco_pwr is always true here. */ | ||
1289 | sdata_info(sdata, | ||
1290 | "Limiting TX power to %d dBm as advertised by %pM\n", | ||
1291 | pwr_level_cisco, sdata->u.mgd.bssid); | ||
1292 | new_ap_level = pwr_level_cisco; | ||
1293 | } | ||
1225 | 1294 | ||
1226 | if (sdata->ap_power_level == new_ap_level) | 1295 | if (sdata->ap_power_level == new_ap_level) |
1227 | return 0; | 1296 | return 0; |
1228 | 1297 | ||
1229 | sdata_info(sdata, | ||
1230 | "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n", | ||
1231 | new_ap_level, chan_pwr, *pwr_constr_elem, | ||
1232 | sdata->u.mgd.bssid); | ||
1233 | sdata->ap_power_level = new_ap_level; | 1298 | sdata->ap_power_level = new_ap_level; |
1234 | if (__ieee80211_recalc_txpower(sdata)) | 1299 | if (__ieee80211_recalc_txpower(sdata)) |
1235 | return BSS_CHANGED_TXPOWER; | 1300 | return BSS_CHANGED_TXPOWER; |
@@ -2752,6 +2817,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2752 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; | 2817 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; |
2753 | u16 capab_info, status_code, aid; | 2818 | u16 capab_info, status_code, aid; |
2754 | struct ieee802_11_elems elems; | 2819 | struct ieee802_11_elems elems; |
2820 | int ac, uapsd_queues = -1; | ||
2755 | u8 *pos; | 2821 | u8 *pos; |
2756 | bool reassoc; | 2822 | bool reassoc; |
2757 | struct cfg80211_bss *bss; | 2823 | struct cfg80211_bss *bss; |
@@ -2821,9 +2887,15 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2821 | * is set can cause the interface to go idle | 2887 | * is set can cause the interface to go idle |
2822 | */ | 2888 | */ |
2823 | ieee80211_destroy_assoc_data(sdata, true); | 2889 | ieee80211_destroy_assoc_data(sdata, true); |
2890 | |||
2891 | /* get uapsd queues configuration */ | ||
2892 | uapsd_queues = 0; | ||
2893 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) | ||
2894 | if (sdata->tx_conf[ac].uapsd) | ||
2895 | uapsd_queues |= BIT(ac); | ||
2824 | } | 2896 | } |
2825 | 2897 | ||
2826 | cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len); | 2898 | cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len, uapsd_queues); |
2827 | } | 2899 | } |
2828 | 2900 | ||
2829 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2901 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -2893,7 +2965,9 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2893 | /* | 2965 | /* |
2894 | * This is the canonical list of information elements we care about, | 2966 | * This is the canonical list of information elements we care about, |
2895 | * the filter code also gives us all changes to the Microsoft OUI | 2967 | * the filter code also gives us all changes to the Microsoft OUI |
2896 | * (00:50:F2) vendor IE which is used for WMM which we need to track. | 2968 | * (00:50:F2) vendor IE which is used for WMM which we need to track, |
2969 | * as well as the DTPC IE (part of the Cisco OUI) used for signaling | ||
2970 | * changes to requested client power. | ||
2897 | * | 2971 | * |
2898 | * We implement beacon filtering in software since that means we can | 2972 | * We implement beacon filtering in software since that means we can |
2899 | * avoid processing the frame here and in cfg80211, and userspace | 2973 | * avoid processing the frame here and in cfg80211, and userspace |
@@ -3199,13 +3273,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3199 | rx_status->band, true); | 3273 | rx_status->band, true); |
3200 | mutex_unlock(&local->sta_mtx); | 3274 | mutex_unlock(&local->sta_mtx); |
3201 | 3275 | ||
3202 | if (elems.country_elem && elems.pwr_constr_elem && | 3276 | changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt, |
3203 | mgmt->u.probe_resp.capab_info & | 3277 | elems.country_elem, |
3204 | cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT)) | 3278 | elems.country_elem_len, |
3205 | changed |= ieee80211_handle_pwr_constr(sdata, chan, | 3279 | elems.pwr_constr_elem, |
3206 | elems.country_elem, | 3280 | elems.cisco_dtpc_elem); |
3207 | elems.country_elem_len, | ||
3208 | elems.pwr_constr_elem); | ||
3209 | 3281 | ||
3210 | ieee80211_bss_info_change_notify(sdata, changed); | 3282 | ieee80211_bss_info_change_notify(sdata, changed); |
3211 | } | 3283 | } |
@@ -3733,7 +3805,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
3733 | ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; | 3805 | ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; |
3734 | ifmgd->p2p_noa_index = -1; | 3806 | ifmgd->p2p_noa_index = -1; |
3735 | 3807 | ||
3736 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) | 3808 | if (sdata->local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS) |
3737 | ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; | 3809 | ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; |
3738 | else | 3810 | else |
3739 | ifmgd->req_smps = IEEE80211_SMPS_OFF; | 3811 | ifmgd->req_smps = IEEE80211_SMPS_OFF; |
@@ -4408,6 +4480,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4408 | ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED; | 4480 | ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED; |
4409 | } | 4481 | } |
4410 | 4482 | ||
4483 | if (req->flags & ASSOC_REQ_USE_RRM) | ||
4484 | ifmgd->flags |= IEEE80211_STA_ENABLE_RRM; | ||
4485 | else | ||
4486 | ifmgd->flags &= ~IEEE80211_STA_ENABLE_RRM; | ||
4487 | |||
4411 | if (req->crypto.control_port) | 4488 | if (req->crypto.control_port) |
4412 | ifmgd->flags |= IEEE80211_STA_CONTROL_PORT; | 4489 | ifmgd->flags |= IEEE80211_STA_CONTROL_PORT; |
4413 | else | 4490 | else |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 1c1469c36dca..2baa7ed8789d 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -75,7 +75,7 @@ minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list) | |||
75 | { | 75 | { |
76 | int j = MAX_THR_RATES; | 76 | int j = MAX_THR_RATES; |
77 | 77 | ||
78 | while (j > 0 && mi->r[i].cur_tp > mi->r[tp_list[j - 1]].cur_tp) | 78 | while (j > 0 && mi->r[i].stats.cur_tp > mi->r[tp_list[j - 1]].stats.cur_tp) |
79 | j--; | 79 | j--; |
80 | if (j < MAX_THR_RATES - 1) | 80 | if (j < MAX_THR_RATES - 1) |
81 | memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); | 81 | memmove(&tp_list[j + 1], &tp_list[j], MAX_THR_RATES - (j + 1)); |
@@ -92,7 +92,7 @@ minstrel_set_rate(struct minstrel_sta_info *mi, struct ieee80211_sta_rates *rate | |||
92 | ratetbl->rate[offset].idx = r->rix; | 92 | ratetbl->rate[offset].idx = r->rix; |
93 | ratetbl->rate[offset].count = r->adjusted_retry_count; | 93 | ratetbl->rate[offset].count = r->adjusted_retry_count; |
94 | ratetbl->rate[offset].count_cts = r->retry_count_cts; | 94 | ratetbl->rate[offset].count_cts = r->retry_count_cts; |
95 | ratetbl->rate[offset].count_rts = r->retry_count_rtscts; | 95 | ratetbl->rate[offset].count_rts = r->stats.retry_count_rtscts; |
96 | } | 96 | } |
97 | 97 | ||
98 | static void | 98 | static void |
@@ -140,44 +140,46 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
140 | 140 | ||
141 | for (i = 0; i < mi->n_rates; i++) { | 141 | for (i = 0; i < mi->n_rates; i++) { |
142 | struct minstrel_rate *mr = &mi->r[i]; | 142 | struct minstrel_rate *mr = &mi->r[i]; |
143 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; | ||
143 | 144 | ||
144 | usecs = mr->perfect_tx_time; | 145 | usecs = mr->perfect_tx_time; |
145 | if (!usecs) | 146 | if (!usecs) |
146 | usecs = 1000000; | 147 | usecs = 1000000; |
147 | 148 | ||
148 | if (unlikely(mr->attempts > 0)) { | 149 | if (unlikely(mrs->attempts > 0)) { |
149 | mr->sample_skipped = 0; | 150 | mrs->sample_skipped = 0; |
150 | mr->cur_prob = MINSTREL_FRAC(mr->success, mr->attempts); | 151 | mrs->cur_prob = MINSTREL_FRAC(mrs->success, |
151 | mr->succ_hist += mr->success; | 152 | mrs->attempts); |
152 | mr->att_hist += mr->attempts; | 153 | mrs->succ_hist += mrs->success; |
153 | mr->probability = minstrel_ewma(mr->probability, | 154 | mrs->att_hist += mrs->attempts; |
154 | mr->cur_prob, | 155 | mrs->probability = minstrel_ewma(mrs->probability, |
155 | EWMA_LEVEL); | 156 | mrs->cur_prob, |
157 | EWMA_LEVEL); | ||
156 | } else | 158 | } else |
157 | mr->sample_skipped++; | 159 | mrs->sample_skipped++; |
158 | 160 | ||
159 | mr->last_success = mr->success; | 161 | mrs->last_success = mrs->success; |
160 | mr->last_attempts = mr->attempts; | 162 | mrs->last_attempts = mrs->attempts; |
161 | mr->success = 0; | 163 | mrs->success = 0; |
162 | mr->attempts = 0; | 164 | mrs->attempts = 0; |
163 | 165 | ||
164 | /* Update throughput per rate, reset thr. below 10% success */ | 166 | /* Update throughput per rate, reset thr. below 10% success */ |
165 | if (mr->probability < MINSTREL_FRAC(10, 100)) | 167 | if (mrs->probability < MINSTREL_FRAC(10, 100)) |
166 | mr->cur_tp = 0; | 168 | mrs->cur_tp = 0; |
167 | else | 169 | else |
168 | mr->cur_tp = mr->probability * (1000000 / usecs); | 170 | mrs->cur_tp = mrs->probability * (1000000 / usecs); |
169 | 171 | ||
170 | /* Sample less often below the 10% chance of success. | 172 | /* Sample less often below the 10% chance of success. |
171 | * Sample less often above the 95% chance of success. */ | 173 | * Sample less often above the 95% chance of success. */ |
172 | if (mr->probability > MINSTREL_FRAC(95, 100) || | 174 | if (mrs->probability > MINSTREL_FRAC(95, 100) || |
173 | mr->probability < MINSTREL_FRAC(10, 100)) { | 175 | mrs->probability < MINSTREL_FRAC(10, 100)) { |
174 | mr->adjusted_retry_count = mr->retry_count >> 1; | 176 | mr->adjusted_retry_count = mrs->retry_count >> 1; |
175 | if (mr->adjusted_retry_count > 2) | 177 | if (mr->adjusted_retry_count > 2) |
176 | mr->adjusted_retry_count = 2; | 178 | mr->adjusted_retry_count = 2; |
177 | mr->sample_limit = 4; | 179 | mr->sample_limit = 4; |
178 | } else { | 180 | } else { |
179 | mr->sample_limit = -1; | 181 | mr->sample_limit = -1; |
180 | mr->adjusted_retry_count = mr->retry_count; | 182 | mr->adjusted_retry_count = mrs->retry_count; |
181 | } | 183 | } |
182 | if (!mr->adjusted_retry_count) | 184 | if (!mr->adjusted_retry_count) |
183 | mr->adjusted_retry_count = 2; | 185 | mr->adjusted_retry_count = 2; |
@@ -190,11 +192,11 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) | |||
190 | * choose the maximum throughput rate as max_prob_rate | 192 | * choose the maximum throughput rate as max_prob_rate |
191 | * (2) if all success probabilities < 95%, the rate with | 193 | * (2) if all success probabilities < 95%, the rate with |
192 | * highest success probability is choosen as max_prob_rate */ | 194 | * highest success probability is choosen as max_prob_rate */ |
193 | if (mr->probability >= MINSTREL_FRAC(95, 100)) { | 195 | if (mrs->probability >= MINSTREL_FRAC(95, 100)) { |
194 | if (mr->cur_tp >= mi->r[tmp_prob_rate].cur_tp) | 196 | if (mrs->cur_tp >= mi->r[tmp_prob_rate].stats.cur_tp) |
195 | tmp_prob_rate = i; | 197 | tmp_prob_rate = i; |
196 | } else { | 198 | } else { |
197 | if (mr->probability >= mi->r[tmp_prob_rate].probability) | 199 | if (mrs->probability >= mi->r[tmp_prob_rate].stats.probability) |
198 | tmp_prob_rate = i; | 200 | tmp_prob_rate = i; |
199 | } | 201 | } |
200 | } | 202 | } |
@@ -240,14 +242,14 @@ minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
240 | if (ndx < 0) | 242 | if (ndx < 0) |
241 | continue; | 243 | continue; |
242 | 244 | ||
243 | mi->r[ndx].attempts += ar[i].count; | 245 | mi->r[ndx].stats.attempts += ar[i].count; |
244 | 246 | ||
245 | if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) | 247 | if ((i != IEEE80211_TX_MAX_RATES - 1) && (ar[i + 1].idx < 0)) |
246 | mi->r[ndx].success += success; | 248 | mi->r[ndx].stats.success += success; |
247 | } | 249 | } |
248 | 250 | ||
249 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0)) | 251 | if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0)) |
250 | mi->sample_count++; | 252 | mi->sample_packets++; |
251 | 253 | ||
252 | if (mi->sample_deferred > 0) | 254 | if (mi->sample_deferred > 0) |
253 | mi->sample_deferred--; | 255 | mi->sample_deferred--; |
@@ -265,7 +267,7 @@ minstrel_get_retry_count(struct minstrel_rate *mr, | |||
265 | unsigned int retry = mr->adjusted_retry_count; | 267 | unsigned int retry = mr->adjusted_retry_count; |
266 | 268 | ||
267 | if (info->control.use_rts) | 269 | if (info->control.use_rts) |
268 | retry = max(2U, min(mr->retry_count_rtscts, retry)); | 270 | retry = max(2U, min(mr->stats.retry_count_rtscts, retry)); |
269 | else if (info->control.use_cts_prot) | 271 | else if (info->control.use_cts_prot) |
270 | retry = max(2U, min(mr->retry_count_cts, retry)); | 272 | retry = max(2U, min(mr->retry_count_cts, retry)); |
271 | return retry; | 273 | return retry; |
@@ -317,15 +319,15 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
317 | sampling_ratio = mp->lookaround_rate; | 319 | sampling_ratio = mp->lookaround_rate; |
318 | 320 | ||
319 | /* increase sum packet counter */ | 321 | /* increase sum packet counter */ |
320 | mi->packet_count++; | 322 | mi->total_packets++; |
321 | 323 | ||
322 | #ifdef CONFIG_MAC80211_DEBUGFS | 324 | #ifdef CONFIG_MAC80211_DEBUGFS |
323 | if (mp->fixed_rate_idx != -1) | 325 | if (mp->fixed_rate_idx != -1) |
324 | return; | 326 | return; |
325 | #endif | 327 | #endif |
326 | 328 | ||
327 | delta = (mi->packet_count * sampling_ratio / 100) - | 329 | delta = (mi->total_packets * sampling_ratio / 100) - |
328 | (mi->sample_count + mi->sample_deferred / 2); | 330 | (mi->sample_packets + mi->sample_deferred / 2); |
329 | 331 | ||
330 | /* delta < 0: no sampling required */ | 332 | /* delta < 0: no sampling required */ |
331 | prev_sample = mi->prev_sample; | 333 | prev_sample = mi->prev_sample; |
@@ -333,10 +335,10 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
333 | if (delta < 0 || (!mrr_capable && prev_sample)) | 335 | if (delta < 0 || (!mrr_capable && prev_sample)) |
334 | return; | 336 | return; |
335 | 337 | ||
336 | if (mi->packet_count >= 10000) { | 338 | if (mi->total_packets >= 10000) { |
337 | mi->sample_deferred = 0; | 339 | mi->sample_deferred = 0; |
338 | mi->sample_count = 0; | 340 | mi->sample_packets = 0; |
339 | mi->packet_count = 0; | 341 | mi->total_packets = 0; |
340 | } else if (delta > mi->n_rates * 2) { | 342 | } else if (delta > mi->n_rates * 2) { |
341 | /* With multi-rate retry, not every planned sample | 343 | /* With multi-rate retry, not every planned sample |
342 | * attempt actually gets used, due to the way the retry | 344 | * attempt actually gets used, due to the way the retry |
@@ -347,7 +349,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
347 | * starts getting worse, minstrel would start bursting | 349 | * starts getting worse, minstrel would start bursting |
348 | * out lots of sampling frames, which would result | 350 | * out lots of sampling frames, which would result |
349 | * in a large throughput loss. */ | 351 | * in a large throughput loss. */ |
350 | mi->sample_count += (delta - mi->n_rates * 2); | 352 | mi->sample_packets += (delta - mi->n_rates * 2); |
351 | } | 353 | } |
352 | 354 | ||
353 | /* get next random rate sample */ | 355 | /* get next random rate sample */ |
@@ -361,7 +363,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
361 | */ | 363 | */ |
362 | if (mrr_capable && | 364 | if (mrr_capable && |
363 | msr->perfect_tx_time > mr->perfect_tx_time && | 365 | msr->perfect_tx_time > mr->perfect_tx_time && |
364 | msr->sample_skipped < 20) { | 366 | msr->stats.sample_skipped < 20) { |
365 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark | 367 | /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark |
366 | * packets that have the sampling rate deferred to the | 368 | * packets that have the sampling rate deferred to the |
367 | * second MRR stage. Increase the sample counter only | 369 | * second MRR stage. Increase the sample counter only |
@@ -375,7 +377,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
375 | if (!msr->sample_limit != 0) | 377 | if (!msr->sample_limit != 0) |
376 | return; | 378 | return; |
377 | 379 | ||
378 | mi->sample_count++; | 380 | mi->sample_packets++; |
379 | if (msr->sample_limit > 0) | 381 | if (msr->sample_limit > 0) |
380 | msr->sample_limit--; | 382 | msr->sample_limit--; |
381 | } | 383 | } |
@@ -384,7 +386,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
384 | * has a probability of >95%, we shouldn't be attempting | 386 | * has a probability of >95%, we shouldn't be attempting |
385 | * to use it, as this only wastes precious airtime */ | 387 | * to use it, as this only wastes precious airtime */ |
386 | if (!mrr_capable && | 388 | if (!mrr_capable && |
387 | (mi->r[ndx].probability > MINSTREL_FRAC(95, 100))) | 389 | (mi->r[ndx].stats.probability > MINSTREL_FRAC(95, 100))) |
388 | return; | 390 | return; |
389 | 391 | ||
390 | mi->prev_sample = true; | 392 | mi->prev_sample = true; |
@@ -459,6 +461,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
459 | 461 | ||
460 | for (i = 0; i < sband->n_bitrates; i++) { | 462 | for (i = 0; i < sband->n_bitrates; i++) { |
461 | struct minstrel_rate *mr = &mi->r[n]; | 463 | struct minstrel_rate *mr = &mi->r[n]; |
464 | struct minstrel_rate_stats *mrs = &mi->r[n].stats; | ||
462 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; | 465 | unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0; |
463 | unsigned int tx_time_single; | 466 | unsigned int tx_time_single; |
464 | unsigned int cw = mp->cw_min; | 467 | unsigned int cw = mp->cw_min; |
@@ -471,6 +474,7 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
471 | 474 | ||
472 | n++; | 475 | n++; |
473 | memset(mr, 0, sizeof(*mr)); | 476 | memset(mr, 0, sizeof(*mr)); |
477 | memset(mrs, 0, sizeof(*mrs)); | ||
474 | 478 | ||
475 | mr->rix = i; | 479 | mr->rix = i; |
476 | shift = ieee80211_chandef_get_shift(chandef); | 480 | shift = ieee80211_chandef_get_shift(chandef); |
@@ -482,9 +486,9 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
482 | /* calculate maximum number of retransmissions before | 486 | /* calculate maximum number of retransmissions before |
483 | * fallback (based on maximum segment size) */ | 487 | * fallback (based on maximum segment size) */ |
484 | mr->sample_limit = -1; | 488 | mr->sample_limit = -1; |
485 | mr->retry_count = 1; | 489 | mrs->retry_count = 1; |
486 | mr->retry_count_cts = 1; | 490 | mr->retry_count_cts = 1; |
487 | mr->retry_count_rtscts = 1; | 491 | mrs->retry_count_rtscts = 1; |
488 | tx_time = mr->perfect_tx_time + mi->sp_ack_dur; | 492 | tx_time = mr->perfect_tx_time + mi->sp_ack_dur; |
489 | do { | 493 | do { |
490 | /* add one retransmission */ | 494 | /* add one retransmission */ |
@@ -501,13 +505,13 @@ minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband, | |||
501 | (mr->retry_count_cts < mp->max_retry)) | 505 | (mr->retry_count_cts < mp->max_retry)) |
502 | mr->retry_count_cts++; | 506 | mr->retry_count_cts++; |
503 | if ((tx_time_rtscts < mp->segment_size) && | 507 | if ((tx_time_rtscts < mp->segment_size) && |
504 | (mr->retry_count_rtscts < mp->max_retry)) | 508 | (mrs->retry_count_rtscts < mp->max_retry)) |
505 | mr->retry_count_rtscts++; | 509 | mrs->retry_count_rtscts++; |
506 | } while ((tx_time < mp->segment_size) && | 510 | } while ((tx_time < mp->segment_size) && |
507 | (++mr->retry_count < mp->max_retry)); | 511 | (++mr->stats.retry_count < mp->max_retry)); |
508 | mr->adjusted_retry_count = mr->retry_count; | 512 | mr->adjusted_retry_count = mrs->retry_count; |
509 | if (!(sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)) | 513 | if (!(sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)) |
510 | mr->retry_count_cts = mr->retry_count; | 514 | mr->retry_count_cts = mrs->retry_count; |
511 | } | 515 | } |
512 | 516 | ||
513 | for (i = n; i < sband->n_bitrates; i++) { | 517 | for (i = n; i < sband->n_bitrates; i++) { |
@@ -665,7 +669,7 @@ static u32 minstrel_get_expected_throughput(void *priv_sta) | |||
665 | /* convert pkt per sec in kbps (1200 is the average pkt size used for | 669 | /* convert pkt per sec in kbps (1200 is the average pkt size used for |
666 | * computing cur_tp | 670 | * computing cur_tp |
667 | */ | 671 | */ |
668 | return MINSTREL_TRUNC(mi->r[idx].cur_tp) * 1200 * 8 / 1024; | 672 | return MINSTREL_TRUNC(mi->r[idx].stats.cur_tp) * 1200 * 8 / 1024; |
669 | } | 673 | } |
670 | 674 | ||
671 | const struct rate_control_ops mac80211_minstrel = { | 675 | const struct rate_control_ops mac80211_minstrel = { |
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h index 046d1bd598a8..97eca86a4af0 100644 --- a/net/mac80211/rc80211_minstrel.h +++ b/net/mac80211/rc80211_minstrel.h | |||
@@ -31,6 +31,27 @@ minstrel_ewma(int old, int new, int weight) | |||
31 | return (new * (EWMA_DIV - weight) + old * weight) / EWMA_DIV; | 31 | return (new * (EWMA_DIV - weight) + old * weight) / EWMA_DIV; |
32 | } | 32 | } |
33 | 33 | ||
34 | struct minstrel_rate_stats { | ||
35 | /* current / last sampling period attempts/success counters */ | ||
36 | unsigned int attempts, last_attempts; | ||
37 | unsigned int success, last_success; | ||
38 | |||
39 | /* total attempts/success counters */ | ||
40 | u64 att_hist, succ_hist; | ||
41 | |||
42 | /* current throughput */ | ||
43 | unsigned int cur_tp; | ||
44 | |||
45 | /* packet delivery probabilities */ | ||
46 | unsigned int cur_prob, probability; | ||
47 | |||
48 | /* maximum retry counts */ | ||
49 | unsigned int retry_count; | ||
50 | unsigned int retry_count_rtscts; | ||
51 | |||
52 | u8 sample_skipped; | ||
53 | bool retry_updated; | ||
54 | }; | ||
34 | 55 | ||
35 | struct minstrel_rate { | 56 | struct minstrel_rate { |
36 | int bitrate; | 57 | int bitrate; |
@@ -40,26 +61,10 @@ struct minstrel_rate { | |||
40 | unsigned int ack_time; | 61 | unsigned int ack_time; |
41 | 62 | ||
42 | int sample_limit; | 63 | int sample_limit; |
43 | unsigned int retry_count; | ||
44 | unsigned int retry_count_cts; | 64 | unsigned int retry_count_cts; |
45 | unsigned int retry_count_rtscts; | ||
46 | unsigned int adjusted_retry_count; | 65 | unsigned int adjusted_retry_count; |
47 | 66 | ||
48 | u32 success; | 67 | struct minstrel_rate_stats stats; |
49 | u32 attempts; | ||
50 | u32 last_attempts; | ||
51 | u32 last_success; | ||
52 | u8 sample_skipped; | ||
53 | |||
54 | /* parts per thousand */ | ||
55 | u32 cur_prob; | ||
56 | u32 probability; | ||
57 | |||
58 | /* per-rate throughput */ | ||
59 | u32 cur_tp; | ||
60 | |||
61 | u64 succ_hist; | ||
62 | u64 att_hist; | ||
63 | }; | 68 | }; |
64 | 69 | ||
65 | struct minstrel_sta_info { | 70 | struct minstrel_sta_info { |
@@ -73,8 +78,8 @@ struct minstrel_sta_info { | |||
73 | 78 | ||
74 | u8 max_tp_rate[MAX_THR_RATES]; | 79 | u8 max_tp_rate[MAX_THR_RATES]; |
75 | u8 max_prob_rate; | 80 | u8 max_prob_rate; |
76 | unsigned int packet_count; | 81 | unsigned int total_packets; |
77 | unsigned int sample_count; | 82 | unsigned int sample_packets; |
78 | int sample_deferred; | 83 | int sample_deferred; |
79 | 84 | ||
80 | unsigned int sample_row; | 85 | unsigned int sample_row; |
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c index fd0b9ca1570e..edde723f9f00 100644 --- a/net/mac80211/rc80211_minstrel_debugfs.c +++ b/net/mac80211/rc80211_minstrel_debugfs.c | |||
@@ -72,6 +72,7 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
72 | "this succ/attempt success attempts\n"); | 72 | "this succ/attempt success attempts\n"); |
73 | for (i = 0; i < mi->n_rates; i++) { | 73 | for (i = 0; i < mi->n_rates; i++) { |
74 | struct minstrel_rate *mr = &mi->r[i]; | 74 | struct minstrel_rate *mr = &mi->r[i]; |
75 | struct minstrel_rate_stats *mrs = &mi->r[i].stats; | ||
75 | 76 | ||
76 | *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; | 77 | *(p++) = (i == mi->max_tp_rate[0]) ? 'A' : ' '; |
77 | *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; | 78 | *(p++) = (i == mi->max_tp_rate[1]) ? 'B' : ' '; |
@@ -81,24 +82,24 @@ minstrel_stats_open(struct inode *inode, struct file *file) | |||
81 | p += sprintf(p, "%3u%s", mr->bitrate / 2, | 82 | p += sprintf(p, "%3u%s", mr->bitrate / 2, |
82 | (mr->bitrate & 1 ? ".5" : " ")); | 83 | (mr->bitrate & 1 ? ".5" : " ")); |
83 | 84 | ||
84 | tp = MINSTREL_TRUNC(mr->cur_tp / 10); | 85 | tp = MINSTREL_TRUNC(mrs->cur_tp / 10); |
85 | prob = MINSTREL_TRUNC(mr->cur_prob * 1000); | 86 | prob = MINSTREL_TRUNC(mrs->cur_prob * 1000); |
86 | eprob = MINSTREL_TRUNC(mr->probability * 1000); | 87 | eprob = MINSTREL_TRUNC(mrs->probability * 1000); |
87 | 88 | ||
88 | p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " | 89 | p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u " |
89 | " %3u(%3u) %8llu %8llu\n", | 90 | " %3u(%3u) %8llu %8llu\n", |
90 | tp / 10, tp % 10, | 91 | tp / 10, tp % 10, |
91 | eprob / 10, eprob % 10, | 92 | eprob / 10, eprob % 10, |
92 | prob / 10, prob % 10, | 93 | prob / 10, prob % 10, |
93 | mr->last_success, | 94 | mrs->last_success, |
94 | mr->last_attempts, | 95 | mrs->last_attempts, |
95 | (unsigned long long)mr->succ_hist, | 96 | (unsigned long long)mrs->succ_hist, |
96 | (unsigned long long)mr->att_hist); | 97 | (unsigned long long)mrs->att_hist); |
97 | } | 98 | } |
98 | p += sprintf(p, "\nTotal packet count:: ideal %d " | 99 | p += sprintf(p, "\nTotal packet count:: ideal %d " |
99 | "lookaround %d\n\n", | 100 | "lookaround %d\n\n", |
100 | mi->packet_count - mi->sample_count, | 101 | mi->total_packets - mi->sample_packets, |
101 | mi->sample_count); | 102 | mi->sample_packets); |
102 | ms->len = p - ms->buf; | 103 | ms->len = p - ms->buf; |
103 | 104 | ||
104 | return 0; | 105 | return 0; |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index 85c1e74b7714..df90ce2db00c 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -135,7 +135,7 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi); | |||
135 | static int | 135 | static int |
136 | minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) | 136 | minstrel_ht_get_group_idx(struct ieee80211_tx_rate *rate) |
137 | { | 137 | { |
138 | return GROUP_IDX((rate->idx / 8) + 1, | 138 | return GROUP_IDX((rate->idx / MCS_GROUP_RATES) + 1, |
139 | !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), | 139 | !!(rate->flags & IEEE80211_TX_RC_SHORT_GI), |
140 | !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); | 140 | !!(rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)); |
141 | } | 141 | } |
@@ -233,12 +233,151 @@ minstrel_ht_calc_tp(struct minstrel_ht_sta *mi, int group, int rate) | |||
233 | } | 233 | } |
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Find & sort topmost throughput rates | ||
237 | * | ||
238 | * If multiple rates provide equal throughput the sorting is based on their | ||
239 | * current success probability. Higher success probability is preferred among | ||
240 | * MCS groups, CCK rates do not provide aggregation and are therefore at last. | ||
241 | */ | ||
242 | static void | ||
243 | minstrel_ht_sort_best_tp_rates(struct minstrel_ht_sta *mi, u8 index, | ||
244 | u8 *tp_list) | ||
245 | { | ||
246 | int cur_group, cur_idx, cur_thr, cur_prob; | ||
247 | int tmp_group, tmp_idx, tmp_thr, tmp_prob; | ||
248 | int j = MAX_THR_RATES; | ||
249 | |||
250 | cur_group = index / MCS_GROUP_RATES; | ||
251 | cur_idx = index % MCS_GROUP_RATES; | ||
252 | cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp; | ||
253 | cur_prob = mi->groups[cur_group].rates[cur_idx].probability; | ||
254 | |||
255 | tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; | ||
256 | tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; | ||
257 | tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
258 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; | ||
259 | |||
260 | while (j > 0 && (cur_thr > tmp_thr || | ||
261 | (cur_thr == tmp_thr && cur_prob > tmp_prob))) { | ||
262 | j--; | ||
263 | tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; | ||
264 | tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; | ||
265 | tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
266 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; | ||
267 | } | ||
268 | |||
269 | if (j < MAX_THR_RATES - 1) { | ||
270 | memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) * | ||
271 | (MAX_THR_RATES - (j + 1)))); | ||
272 | } | ||
273 | if (j < MAX_THR_RATES) | ||
274 | tp_list[j] = index; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Find and set the topmost probability rate per sta and per group | ||
279 | */ | ||
280 | static void | ||
281 | minstrel_ht_set_best_prob_rate(struct minstrel_ht_sta *mi, u8 index) | ||
282 | { | ||
283 | struct minstrel_mcs_group_data *mg; | ||
284 | struct minstrel_rate_stats *mr; | ||
285 | int tmp_group, tmp_idx, tmp_tp, tmp_prob, max_tp_group; | ||
286 | |||
287 | mg = &mi->groups[index / MCS_GROUP_RATES]; | ||
288 | mr = &mg->rates[index % MCS_GROUP_RATES]; | ||
289 | |||
290 | tmp_group = mi->max_prob_rate / MCS_GROUP_RATES; | ||
291 | tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES; | ||
292 | tmp_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
293 | tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability; | ||
294 | |||
295 | /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from | ||
296 | * MCS_GROUP as well as CCK_GROUP rates do not allow aggregation */ | ||
297 | max_tp_group = mi->max_tp_rate[0] / MCS_GROUP_RATES; | ||
298 | if((index / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) && | ||
299 | (max_tp_group != MINSTREL_CCK_GROUP)) | ||
300 | return; | ||
301 | |||
302 | if (mr->probability > MINSTREL_FRAC(75, 100)) { | ||
303 | if (mr->cur_tp > tmp_tp) | ||
304 | mi->max_prob_rate = index; | ||
305 | if (mr->cur_tp > mg->rates[mg->max_group_prob_rate].cur_tp) | ||
306 | mg->max_group_prob_rate = index; | ||
307 | } else { | ||
308 | if (mr->probability > tmp_prob) | ||
309 | mi->max_prob_rate = index; | ||
310 | if (mr->probability > mg->rates[mg->max_group_prob_rate].probability) | ||
311 | mg->max_group_prob_rate = index; | ||
312 | } | ||
313 | } | ||
314 | |||
315 | |||
316 | /* | ||
317 | * Assign new rate set per sta and use CCK rates only if the fastest | ||
318 | * rate (max_tp_rate[0]) is from CCK group. This prohibits such sorted | ||
319 | * rate sets where MCS and CCK rates are mixed, because CCK rates can | ||
320 | * not use aggregation. | ||
321 | */ | ||
322 | static void | ||
323 | minstrel_ht_assign_best_tp_rates(struct minstrel_ht_sta *mi, | ||
324 | u8 tmp_mcs_tp_rate[MAX_THR_RATES], | ||
325 | u8 tmp_cck_tp_rate[MAX_THR_RATES]) | ||
326 | { | ||
327 | unsigned int tmp_group, tmp_idx, tmp_cck_tp, tmp_mcs_tp; | ||
328 | int i; | ||
329 | |||
330 | tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES; | ||
331 | tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES; | ||
332 | tmp_cck_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
333 | |||
334 | tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES; | ||
335 | tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES; | ||
336 | tmp_mcs_tp = mi->groups[tmp_group].rates[tmp_idx].cur_tp; | ||
337 | |||
338 | if (tmp_cck_tp > tmp_mcs_tp) { | ||
339 | for(i = 0; i < MAX_THR_RATES; i++) { | ||
340 | minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], | ||
341 | tmp_mcs_tp_rate); | ||
342 | } | ||
343 | } | ||
344 | |||
345 | } | ||
346 | |||
347 | /* | ||
348 | * Try to increase robustness of max_prob rate by decrease number of | ||
349 | * streams if possible. | ||
350 | */ | ||
351 | static inline void | ||
352 | minstrel_ht_prob_rate_reduce_streams(struct minstrel_ht_sta *mi) | ||
353 | { | ||
354 | struct minstrel_mcs_group_data *mg; | ||
355 | struct minstrel_rate_stats *mr; | ||
356 | int tmp_max_streams, group; | ||
357 | int tmp_tp = 0; | ||
358 | |||
359 | tmp_max_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / | ||
360 | MCS_GROUP_RATES].streams; | ||
361 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { | ||
362 | mg = &mi->groups[group]; | ||
363 | if (!mg->supported || group == MINSTREL_CCK_GROUP) | ||
364 | continue; | ||
365 | mr = minstrel_get_ratestats(mi, mg->max_group_prob_rate); | ||
366 | if (tmp_tp < mr->cur_tp && | ||
367 | (minstrel_mcs_groups[group].streams < tmp_max_streams)) { | ||
368 | mi->max_prob_rate = mg->max_group_prob_rate; | ||
369 | tmp_tp = mr->cur_tp; | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | /* | ||
236 | * Update rate statistics and select new primary rates | 375 | * Update rate statistics and select new primary rates |
237 | * | 376 | * |
238 | * Rules for rate selection: | 377 | * Rules for rate selection: |
239 | * - max_prob_rate must use only one stream, as a tradeoff between delivery | 378 | * - max_prob_rate must use only one stream, as a tradeoff between delivery |
240 | * probability and throughput during strong fluctuations | 379 | * probability and throughput during strong fluctuations |
241 | * - as long as the max prob rate has a probability of more than 3/4, pick | 380 | * - as long as the max prob rate has a probability of more than 75%, pick |
242 | * higher throughput rates, even if the probablity is a bit lower | 381 | * higher throughput rates, even if the probablity is a bit lower |
243 | */ | 382 | */ |
244 | static void | 383 | static void |
@@ -246,9 +385,9 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
246 | { | 385 | { |
247 | struct minstrel_mcs_group_data *mg; | 386 | struct minstrel_mcs_group_data *mg; |
248 | struct minstrel_rate_stats *mr; | 387 | struct minstrel_rate_stats *mr; |
249 | int cur_prob, cur_prob_tp, cur_tp, cur_tp2; | 388 | int group, i, j; |
250 | int group, i, index; | 389 | u8 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; |
251 | bool mi_rates_valid = false; | 390 | u8 tmp_cck_tp_rate[MAX_THR_RATES], index; |
252 | 391 | ||
253 | if (mi->ampdu_packets > 0) { | 392 | if (mi->ampdu_packets > 0) { |
254 | mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, | 393 | mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, |
@@ -260,13 +399,14 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
260 | mi->sample_slow = 0; | 399 | mi->sample_slow = 0; |
261 | mi->sample_count = 0; | 400 | mi->sample_count = 0; |
262 | 401 | ||
263 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { | 402 | /* Initialize global rate indexes */ |
264 | bool mg_rates_valid = false; | 403 | for(j = 0; j < MAX_THR_RATES; j++){ |
404 | tmp_mcs_tp_rate[j] = 0; | ||
405 | tmp_cck_tp_rate[j] = 0; | ||
406 | } | ||
265 | 407 | ||
266 | cur_prob = 0; | 408 | /* Find best rate sets within all MCS groups*/ |
267 | cur_prob_tp = 0; | 409 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { |
268 | cur_tp = 0; | ||
269 | cur_tp2 = 0; | ||
270 | 410 | ||
271 | mg = &mi->groups[group]; | 411 | mg = &mi->groups[group]; |
272 | if (!mg->supported) | 412 | if (!mg->supported) |
@@ -274,24 +414,16 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
274 | 414 | ||
275 | mi->sample_count++; | 415 | mi->sample_count++; |
276 | 416 | ||
417 | /* (re)Initialize group rate indexes */ | ||
418 | for(j = 0; j < MAX_THR_RATES; j++) | ||
419 | tmp_group_tp_rate[j] = group; | ||
420 | |||
277 | for (i = 0; i < MCS_GROUP_RATES; i++) { | 421 | for (i = 0; i < MCS_GROUP_RATES; i++) { |
278 | if (!(mg->supported & BIT(i))) | 422 | if (!(mg->supported & BIT(i))) |
279 | continue; | 423 | continue; |
280 | 424 | ||
281 | index = MCS_GROUP_RATES * group + i; | 425 | index = MCS_GROUP_RATES * group + i; |
282 | 426 | ||
283 | /* initialize rates selections starting indexes */ | ||
284 | if (!mg_rates_valid) { | ||
285 | mg->max_tp_rate = mg->max_tp_rate2 = | ||
286 | mg->max_prob_rate = i; | ||
287 | if (!mi_rates_valid) { | ||
288 | mi->max_tp_rate = mi->max_tp_rate2 = | ||
289 | mi->max_prob_rate = index; | ||
290 | mi_rates_valid = true; | ||
291 | } | ||
292 | mg_rates_valid = true; | ||
293 | } | ||
294 | |||
295 | mr = &mg->rates[i]; | 427 | mr = &mg->rates[i]; |
296 | mr->retry_updated = false; | 428 | mr->retry_updated = false; |
297 | minstrel_calc_rate_ewma(mr); | 429 | minstrel_calc_rate_ewma(mr); |
@@ -300,82 +432,47 @@ minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
300 | if (!mr->cur_tp) | 432 | if (!mr->cur_tp) |
301 | continue; | 433 | continue; |
302 | 434 | ||
303 | if ((mr->cur_tp > cur_prob_tp && mr->probability > | 435 | /* Find max throughput rate set */ |
304 | MINSTREL_FRAC(3, 4)) || mr->probability > cur_prob) { | 436 | if (group != MINSTREL_CCK_GROUP) { |
305 | mg->max_prob_rate = index; | 437 | minstrel_ht_sort_best_tp_rates(mi, index, |
306 | cur_prob = mr->probability; | 438 | tmp_mcs_tp_rate); |
307 | cur_prob_tp = mr->cur_tp; | 439 | } else if (group == MINSTREL_CCK_GROUP) { |
308 | } | 440 | minstrel_ht_sort_best_tp_rates(mi, index, |
309 | 441 | tmp_cck_tp_rate); | |
310 | if (mr->cur_tp > cur_tp) { | ||
311 | swap(index, mg->max_tp_rate); | ||
312 | cur_tp = mr->cur_tp; | ||
313 | mr = minstrel_get_ratestats(mi, index); | ||
314 | } | ||
315 | |||
316 | if (index >= mg->max_tp_rate) | ||
317 | continue; | ||
318 | |||
319 | if (mr->cur_tp > cur_tp2) { | ||
320 | mg->max_tp_rate2 = index; | ||
321 | cur_tp2 = mr->cur_tp; | ||
322 | } | 442 | } |
323 | } | ||
324 | } | ||
325 | 443 | ||
326 | /* try to sample all available rates during each interval */ | 444 | /* Find max throughput rate set within a group */ |
327 | mi->sample_count *= 8; | 445 | minstrel_ht_sort_best_tp_rates(mi, index, |
446 | tmp_group_tp_rate); | ||
328 | 447 | ||
329 | cur_prob = 0; | 448 | /* Find max probability rate per group and global */ |
330 | cur_prob_tp = 0; | 449 | minstrel_ht_set_best_prob_rate(mi, index); |
331 | cur_tp = 0; | ||
332 | cur_tp2 = 0; | ||
333 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { | ||
334 | mg = &mi->groups[group]; | ||
335 | if (!mg->supported) | ||
336 | continue; | ||
337 | |||
338 | mr = minstrel_get_ratestats(mi, mg->max_tp_rate); | ||
339 | if (cur_tp < mr->cur_tp) { | ||
340 | mi->max_tp_rate2 = mi->max_tp_rate; | ||
341 | cur_tp2 = cur_tp; | ||
342 | mi->max_tp_rate = mg->max_tp_rate; | ||
343 | cur_tp = mr->cur_tp; | ||
344 | mi->max_prob_streams = minstrel_mcs_groups[group].streams - 1; | ||
345 | } | 450 | } |
346 | 451 | ||
347 | mr = minstrel_get_ratestats(mi, mg->max_tp_rate2); | 452 | memcpy(mg->max_group_tp_rate, tmp_group_tp_rate, |
348 | if (cur_tp2 < mr->cur_tp) { | 453 | sizeof(mg->max_group_tp_rate)); |
349 | mi->max_tp_rate2 = mg->max_tp_rate2; | ||
350 | cur_tp2 = mr->cur_tp; | ||
351 | } | ||
352 | } | 454 | } |
353 | 455 | ||
354 | if (mi->max_prob_streams < 1) | 456 | /* Assign new rate set per sta */ |
355 | mi->max_prob_streams = 1; | 457 | minstrel_ht_assign_best_tp_rates(mi, tmp_mcs_tp_rate, tmp_cck_tp_rate); |
458 | memcpy(mi->max_tp_rate, tmp_mcs_tp_rate, sizeof(mi->max_tp_rate)); | ||
356 | 459 | ||
357 | for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { | 460 | /* Try to increase robustness of max_prob_rate*/ |
358 | mg = &mi->groups[group]; | 461 | minstrel_ht_prob_rate_reduce_streams(mi); |
359 | if (!mg->supported) | 462 | |
360 | continue; | 463 | /* try to sample all available rates during each interval */ |
361 | mr = minstrel_get_ratestats(mi, mg->max_prob_rate); | 464 | mi->sample_count *= 8; |
362 | if (cur_prob_tp < mr->cur_tp && | ||
363 | minstrel_mcs_groups[group].streams <= mi->max_prob_streams) { | ||
364 | mi->max_prob_rate = mg->max_prob_rate; | ||
365 | cur_prob = mr->cur_prob; | ||
366 | cur_prob_tp = mr->cur_tp; | ||
367 | } | ||
368 | } | ||
369 | 465 | ||
370 | #ifdef CONFIG_MAC80211_DEBUGFS | 466 | #ifdef CONFIG_MAC80211_DEBUGFS |
371 | /* use fixed index if set */ | 467 | /* use fixed index if set */ |
372 | if (mp->fixed_rate_idx != -1) { | 468 | if (mp->fixed_rate_idx != -1) { |
373 | mi->max_tp_rate = mp->fixed_rate_idx; | 469 | for (i = 0; i < 4; i++) |
374 | mi->max_tp_rate2 = mp->fixed_rate_idx; | 470 | mi->max_tp_rate[i] = mp->fixed_rate_idx; |
375 | mi->max_prob_rate = mp->fixed_rate_idx; | 471 | mi->max_prob_rate = mp->fixed_rate_idx; |
376 | } | 472 | } |
377 | #endif | 473 | #endif |
378 | 474 | ||
475 | /* Reset update timer */ | ||
379 | mi->stats_update = jiffies; | 476 | mi->stats_update = jiffies; |
380 | } | 477 | } |
381 | 478 | ||
@@ -420,8 +517,7 @@ minstrel_next_sample_idx(struct minstrel_ht_sta *mi) | |||
420 | } | 517 | } |
421 | 518 | ||
422 | static void | 519 | static void |
423 | minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, | 520 | minstrel_downgrade_rate(struct minstrel_ht_sta *mi, u8 *idx, bool primary) |
424 | bool primary) | ||
425 | { | 521 | { |
426 | int group, orig_group; | 522 | int group, orig_group; |
427 | 523 | ||
@@ -437,9 +533,9 @@ minstrel_downgrade_rate(struct minstrel_ht_sta *mi, unsigned int *idx, | |||
437 | continue; | 533 | continue; |
438 | 534 | ||
439 | if (primary) | 535 | if (primary) |
440 | *idx = mi->groups[group].max_tp_rate; | 536 | *idx = mi->groups[group].max_group_tp_rate[0]; |
441 | else | 537 | else |
442 | *idx = mi->groups[group].max_tp_rate2; | 538 | *idx = mi->groups[group].max_group_tp_rate[1]; |
443 | break; | 539 | break; |
444 | } | 540 | } |
445 | } | 541 | } |
@@ -524,19 +620,19 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
524 | * check for sudden death of spatial multiplexing, | 620 | * check for sudden death of spatial multiplexing, |
525 | * downgrade to a lower number of streams if necessary. | 621 | * downgrade to a lower number of streams if necessary. |
526 | */ | 622 | */ |
527 | rate = minstrel_get_ratestats(mi, mi->max_tp_rate); | 623 | rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); |
528 | if (rate->attempts > 30 && | 624 | if (rate->attempts > 30 && |
529 | MINSTREL_FRAC(rate->success, rate->attempts) < | 625 | MINSTREL_FRAC(rate->success, rate->attempts) < |
530 | MINSTREL_FRAC(20, 100)) { | 626 | MINSTREL_FRAC(20, 100)) { |
531 | minstrel_downgrade_rate(mi, &mi->max_tp_rate, true); | 627 | minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); |
532 | update = true; | 628 | update = true; |
533 | } | 629 | } |
534 | 630 | ||
535 | rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate2); | 631 | rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); |
536 | if (rate2->attempts > 30 && | 632 | if (rate2->attempts > 30 && |
537 | MINSTREL_FRAC(rate2->success, rate2->attempts) < | 633 | MINSTREL_FRAC(rate2->success, rate2->attempts) < |
538 | MINSTREL_FRAC(20, 100)) { | 634 | MINSTREL_FRAC(20, 100)) { |
539 | minstrel_downgrade_rate(mi, &mi->max_tp_rate2, false); | 635 | minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); |
540 | update = true; | 636 | update = true; |
541 | } | 637 | } |
542 | 638 | ||
@@ -661,12 +757,12 @@ minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
661 | if (!rates) | 757 | if (!rates) |
662 | return; | 758 | return; |
663 | 759 | ||
664 | /* Start with max_tp_rate */ | 760 | /* Start with max_tp_rate[0] */ |
665 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate); | 761 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); |
666 | 762 | ||
667 | if (mp->hw->max_rates >= 3) { | 763 | if (mp->hw->max_rates >= 3) { |
668 | /* At least 3 tx rates supported, use max_tp_rate2 next */ | 764 | /* At least 3 tx rates supported, use max_tp_rate[1] next */ |
669 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate2); | 765 | minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[1]); |
670 | } | 766 | } |
671 | 767 | ||
672 | if (mp->hw->max_rates >= 2) { | 768 | if (mp->hw->max_rates >= 2) { |
@@ -691,7 +787,7 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
691 | { | 787 | { |
692 | struct minstrel_rate_stats *mr; | 788 | struct minstrel_rate_stats *mr; |
693 | struct minstrel_mcs_group_data *mg; | 789 | struct minstrel_mcs_group_data *mg; |
694 | unsigned int sample_dur, sample_group; | 790 | unsigned int sample_dur, sample_group, cur_max_tp_streams; |
695 | int sample_idx = 0; | 791 | int sample_idx = 0; |
696 | 792 | ||
697 | if (mi->sample_wait > 0) { | 793 | if (mi->sample_wait > 0) { |
@@ -718,8 +814,8 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
718 | * to the frame. Hence, don't use sampling for the currently | 814 | * to the frame. Hence, don't use sampling for the currently |
719 | * used rates. | 815 | * used rates. |
720 | */ | 816 | */ |
721 | if (sample_idx == mi->max_tp_rate || | 817 | if (sample_idx == mi->max_tp_rate[0] || |
722 | sample_idx == mi->max_tp_rate2 || | 818 | sample_idx == mi->max_tp_rate[1] || |
723 | sample_idx == mi->max_prob_rate) | 819 | sample_idx == mi->max_prob_rate) |
724 | return -1; | 820 | return -1; |
725 | 821 | ||
@@ -734,9 +830,12 @@ minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) | |||
734 | * Make sure that lower rates get sampled only occasionally, | 830 | * Make sure that lower rates get sampled only occasionally, |
735 | * if the link is working perfectly. | 831 | * if the link is working perfectly. |
736 | */ | 832 | */ |
833 | |||
834 | cur_max_tp_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / | ||
835 | MCS_GROUP_RATES].streams; | ||
737 | sample_dur = minstrel_get_duration(sample_idx); | 836 | sample_dur = minstrel_get_duration(sample_idx); |
738 | if (sample_dur >= minstrel_get_duration(mi->max_tp_rate2) && | 837 | if (sample_dur >= minstrel_get_duration(mi->max_tp_rate[1]) && |
739 | (mi->max_prob_streams < | 838 | (cur_max_tp_streams - 1 < |
740 | minstrel_mcs_groups[sample_group].streams || | 839 | minstrel_mcs_groups[sample_group].streams || |
741 | sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { | 840 | sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { |
742 | if (mr->sample_skipped < 20) | 841 | if (mr->sample_skipped < 20) |
@@ -1041,8 +1140,8 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta) | |||
1041 | if (!msp->is_ht) | 1140 | if (!msp->is_ht) |
1042 | return mac80211_minstrel.get_expected_throughput(priv_sta); | 1141 | return mac80211_minstrel.get_expected_throughput(priv_sta); |
1043 | 1142 | ||
1044 | i = mi->max_tp_rate / MCS_GROUP_RATES; | 1143 | i = mi->max_tp_rate[0] / MCS_GROUP_RATES; |
1045 | j = mi->max_tp_rate % MCS_GROUP_RATES; | 1144 | j = mi->max_tp_rate[0] % MCS_GROUP_RATES; |
1046 | 1145 | ||
1047 | /* convert cur_tp from pkt per second in kbps */ | 1146 | /* convert cur_tp from pkt per second in kbps */ |
1048 | return mi->groups[i].rates[j].cur_tp * AVG_PKT_SIZE * 8 / 1024; | 1147 | return mi->groups[i].rates[j].cur_tp * AVG_PKT_SIZE * 8 / 1024; |
diff --git a/net/mac80211/rc80211_minstrel_ht.h b/net/mac80211/rc80211_minstrel_ht.h index d655586773ac..01570e0e014b 100644 --- a/net/mac80211/rc80211_minstrel_ht.h +++ b/net/mac80211/rc80211_minstrel_ht.h | |||
@@ -26,28 +26,6 @@ struct mcs_group { | |||
26 | 26 | ||
27 | extern const struct mcs_group minstrel_mcs_groups[]; | 27 | extern const struct mcs_group minstrel_mcs_groups[]; |
28 | 28 | ||
29 | struct minstrel_rate_stats { | ||
30 | /* current / last sampling period attempts/success counters */ | ||
31 | unsigned int attempts, last_attempts; | ||
32 | unsigned int success, last_success; | ||
33 | |||
34 | /* total attempts/success counters */ | ||
35 | u64 att_hist, succ_hist; | ||
36 | |||
37 | /* current throughput */ | ||
38 | unsigned int cur_tp; | ||
39 | |||
40 | /* packet delivery probabilities */ | ||
41 | unsigned int cur_prob, probability; | ||
42 | |||
43 | /* maximum retry counts */ | ||
44 | unsigned int retry_count; | ||
45 | unsigned int retry_count_rtscts; | ||
46 | |||
47 | bool retry_updated; | ||
48 | u8 sample_skipped; | ||
49 | }; | ||
50 | |||
51 | struct minstrel_mcs_group_data { | 29 | struct minstrel_mcs_group_data { |
52 | u8 index; | 30 | u8 index; |
53 | u8 column; | 31 | u8 column; |
@@ -55,10 +33,9 @@ struct minstrel_mcs_group_data { | |||
55 | /* bitfield of supported MCS rates of this group */ | 33 | /* bitfield of supported MCS rates of this group */ |
56 | u8 supported; | 34 | u8 supported; |
57 | 35 | ||
58 | /* selected primary rates */ | 36 | /* sorted rate set within a MCS group*/ |
59 | unsigned int max_tp_rate; | 37 | u8 max_group_tp_rate[MAX_THR_RATES]; |
60 | unsigned int max_tp_rate2; | 38 | u8 max_group_prob_rate; |
61 | unsigned int max_prob_rate; | ||
62 | 39 | ||
63 | /* MCS rate statistics */ | 40 | /* MCS rate statistics */ |
64 | struct minstrel_rate_stats rates[MCS_GROUP_RATES]; | 41 | struct minstrel_rate_stats rates[MCS_GROUP_RATES]; |
@@ -74,15 +51,9 @@ struct minstrel_ht_sta { | |||
74 | /* ampdu length (EWMA) */ | 51 | /* ampdu length (EWMA) */ |
75 | unsigned int avg_ampdu_len; | 52 | unsigned int avg_ampdu_len; |
76 | 53 | ||
77 | /* best throughput rate */ | 54 | /* overall sorted rate set */ |
78 | unsigned int max_tp_rate; | 55 | u8 max_tp_rate[MAX_THR_RATES]; |
79 | 56 | u8 max_prob_rate; | |
80 | /* second best throughput rate */ | ||
81 | unsigned int max_tp_rate2; | ||
82 | |||
83 | /* best probability rate */ | ||
84 | unsigned int max_prob_rate; | ||
85 | unsigned int max_prob_streams; | ||
86 | 57 | ||
87 | /* time of last status update */ | 58 | /* time of last status update */ |
88 | unsigned long stats_update; | 59 | unsigned long stats_update; |
diff --git a/net/mac80211/rc80211_minstrel_ht_debugfs.c b/net/mac80211/rc80211_minstrel_ht_debugfs.c index 3e7d793de0c3..a72ad46f2a04 100644 --- a/net/mac80211/rc80211_minstrel_ht_debugfs.c +++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c | |||
@@ -46,8 +46,10 @@ minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) | |||
46 | else | 46 | else |
47 | p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); | 47 | p += sprintf(p, "HT%c0/%cGI ", htmode, gimode); |
48 | 48 | ||
49 | *(p++) = (idx == mi->max_tp_rate) ? 'T' : ' '; | 49 | *(p++) = (idx == mi->max_tp_rate[0]) ? 'A' : ' '; |
50 | *(p++) = (idx == mi->max_tp_rate2) ? 't' : ' '; | 50 | *(p++) = (idx == mi->max_tp_rate[1]) ? 'B' : ' '; |
51 | *(p++) = (idx == mi->max_tp_rate[2]) ? 'C' : ' '; | ||
52 | *(p++) = (idx == mi->max_tp_rate[3]) ? 'D' : ' '; | ||
51 | *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; | 53 | *(p++) = (idx == mi->max_prob_rate) ? 'P' : ' '; |
52 | 54 | ||
53 | if (i == max_mcs) { | 55 | if (i == max_mcs) { |
@@ -100,8 +102,8 @@ minstrel_ht_stats_open(struct inode *inode, struct file *file) | |||
100 | 102 | ||
101 | file->private_data = ms; | 103 | file->private_data = ms; |
102 | p = ms->buf; | 104 | p = ms->buf; |
103 | p += sprintf(p, "type rate throughput ewma prob this prob " | 105 | p += sprintf(p, "type rate throughput ewma prob " |
104 | "retry this succ/attempt success attempts\n"); | 106 | "this prob retry this succ/attempt success attempts\n"); |
105 | 107 | ||
106 | p = minstrel_ht_stats_dump(mi, max_mcs, p); | 108 | p = minstrel_ht_stats_dump(mi, max_mcs, p); |
107 | for (i = 0; i < max_mcs; i++) | 109 | for (i = 0; i < max_mcs; i++) |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a8d862f9183c..b04ca4049c95 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -835,6 +836,16 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata | |||
835 | 836 | ||
836 | spin_lock(&tid_agg_rx->reorder_lock); | 837 | spin_lock(&tid_agg_rx->reorder_lock); |
837 | 838 | ||
839 | /* | ||
840 | * Offloaded BA sessions have no known starting sequence number so pick | ||
841 | * one from first Rxed frame for this tid after BA was started. | ||
842 | */ | ||
843 | if (unlikely(tid_agg_rx->auto_seq)) { | ||
844 | tid_agg_rx->auto_seq = false; | ||
845 | tid_agg_rx->ssn = mpdu_seq_num; | ||
846 | tid_agg_rx->head_seq_num = mpdu_seq_num; | ||
847 | } | ||
848 | |||
838 | buf_size = tid_agg_rx->buf_size; | 849 | buf_size = tid_agg_rx->buf_size; |
839 | head_seq_num = tid_agg_rx->head_seq_num; | 850 | head_seq_num = tid_agg_rx->head_seq_num; |
840 | 851 | ||
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index a9bb6eb8c3e0..af0d094b2f2f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright 2005, Devicescape Software, Inc. | 6 | * Copyright 2005, Devicescape Software, Inc. |
7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
9 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 4dd3badab259..de494df3bab8 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 3 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
4 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
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 |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 89c40d5c0633..42f68cb8957e 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2002-2005, Devicescape Software, Inc. | 2 | * Copyright 2002-2005, Devicescape Software, Inc. |
3 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
@@ -167,6 +168,8 @@ struct tid_ampdu_tx { | |||
167 | * @dialog_token: dialog token for aggregation session | 168 | * @dialog_token: dialog token for aggregation session |
168 | * @rcu_head: RCU head used for freeing this struct | 169 | * @rcu_head: RCU head used for freeing this struct |
169 | * @reorder_lock: serializes access to reorder buffer, see below. | 170 | * @reorder_lock: serializes access to reorder buffer, see below. |
171 | * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and | ||
172 | * and ssn. | ||
170 | * | 173 | * |
171 | * This structure's lifetime is managed by RCU, assignments to | 174 | * This structure's lifetime is managed by RCU, assignments to |
172 | * the array holding it must hold the aggregation mutex. | 175 | * the array holding it must hold the aggregation mutex. |
@@ -190,6 +193,7 @@ struct tid_ampdu_rx { | |||
190 | u16 buf_size; | 193 | u16 buf_size; |
191 | u16 timeout; | 194 | u16 timeout; |
192 | u8 dialog_token; | 195 | u8 dialog_token; |
196 | bool auto_seq; | ||
193 | }; | 197 | }; |
194 | 198 | ||
195 | /** | 199 | /** |
@@ -446,6 +450,9 @@ struct sta_info { | |||
446 | enum ieee80211_smps_mode known_smps_mode; | 450 | enum ieee80211_smps_mode known_smps_mode; |
447 | const struct ieee80211_cipher_scheme *cipher_scheme; | 451 | const struct ieee80211_cipher_scheme *cipher_scheme; |
448 | 452 | ||
453 | /* TDLS timeout data */ | ||
454 | unsigned long last_tdls_pkt_time; | ||
455 | |||
449 | /* keep last! */ | 456 | /* keep last! */ |
450 | struct ieee80211_sta sta; | 457 | struct ieee80211_sta sta; |
451 | }; | 458 | }; |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index aa06dcad336e..89290e33dafe 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -537,6 +538,8 @@ static void ieee80211_tx_latency_end_msrmnt(struct ieee80211_local *local, | |||
537 | * - current throughput (higher value for higher tpt)? | 538 | * - current throughput (higher value for higher tpt)? |
538 | */ | 539 | */ |
539 | #define STA_LOST_PKT_THRESHOLD 50 | 540 | #define STA_LOST_PKT_THRESHOLD 50 |
541 | #define STA_LOST_TDLS_PKT_THRESHOLD 10 | ||
542 | #define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */ | ||
540 | 543 | ||
541 | static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) | 544 | static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) |
542 | { | 545 | { |
@@ -547,7 +550,20 @@ static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb) | |||
547 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) | 550 | !(info->flags & IEEE80211_TX_STAT_AMPDU)) |
548 | return; | 551 | return; |
549 | 552 | ||
550 | if (++sta->lost_packets < STA_LOST_PKT_THRESHOLD) | 553 | sta->lost_packets++; |
554 | if (!sta->sta.tdls && sta->lost_packets < STA_LOST_PKT_THRESHOLD) | ||
555 | return; | ||
556 | |||
557 | /* | ||
558 | * If we're in TDLS mode, make sure that all STA_LOST_TDLS_PKT_THRESHOLD | ||
559 | * of the last packets were lost, and that no ACK was received in the | ||
560 | * last STA_LOST_TDLS_PKT_TIME ms, before triggering the CQM packet-loss | ||
561 | * mechanism. | ||
562 | */ | ||
563 | if (sta->sta.tdls && | ||
564 | (sta->lost_packets < STA_LOST_TDLS_PKT_THRESHOLD || | ||
565 | time_before(jiffies, | ||
566 | sta->last_tdls_pkt_time + STA_LOST_TDLS_PKT_TIME))) | ||
551 | return; | 567 | return; |
552 | 568 | ||
553 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, | 569 | cfg80211_cqm_pktloss_notify(sta->sdata->dev, sta->sta.addr, |
@@ -694,6 +710,10 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
694 | if (info->flags & IEEE80211_TX_STAT_ACK) { | 710 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
695 | if (sta->lost_packets) | 711 | if (sta->lost_packets) |
696 | sta->lost_packets = 0; | 712 | sta->lost_packets = 0; |
713 | |||
714 | /* Track when last TDLS packet was ACKed */ | ||
715 | if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH)) | ||
716 | sta->last_tdls_pkt_time = jiffies; | ||
697 | } else { | 717 | } else { |
698 | ieee80211_lost_packet(sta, skb); | 718 | ieee80211_lost_packet(sta, skb); |
699 | } | 719 | } |
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index f2cb3b6c1871..4ea25dec0698 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2014, Intel Corporation | 5 | * Copyright 2014, Intel Corporation |
6 | * Copyright 2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This file is GPLv2 as found in COPYING. | 8 | * This file is GPLv2 as found in COPYING. |
8 | */ | 9 | */ |
@@ -411,6 +412,9 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
411 | tf->ether_type = cpu_to_be16(ETH_P_TDLS); | 412 | tf->ether_type = cpu_to_be16(ETH_P_TDLS); |
412 | tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; | 413 | tf->payload_type = WLAN_TDLS_SNAP_RFTYPE; |
413 | 414 | ||
415 | /* network header is after the ethernet header */ | ||
416 | skb_set_network_header(skb, ETH_HLEN); | ||
417 | |||
414 | switch (action_code) { | 418 | switch (action_code) { |
415 | case WLAN_TDLS_SETUP_REQUEST: | 419 | case WLAN_TDLS_SETUP_REQUEST: |
416 | tf->category = WLAN_CATEGORY_TDLS; | 420 | tf->category = WLAN_CATEGORY_TDLS; |
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h index 02ac535d1274..38fae7ebe984 100644 --- a/net/mac80211/trace.h +++ b/net/mac80211/trace.h | |||
@@ -672,13 +672,13 @@ DEFINE_EVENT(local_u32_evt, drv_set_rts_threshold, | |||
672 | ); | 672 | ); |
673 | 673 | ||
674 | TRACE_EVENT(drv_set_coverage_class, | 674 | TRACE_EVENT(drv_set_coverage_class, |
675 | TP_PROTO(struct ieee80211_local *local, u8 value), | 675 | TP_PROTO(struct ieee80211_local *local, s16 value), |
676 | 676 | ||
677 | TP_ARGS(local, value), | 677 | TP_ARGS(local, value), |
678 | 678 | ||
679 | TP_STRUCT__entry( | 679 | TP_STRUCT__entry( |
680 | LOCAL_ENTRY | 680 | LOCAL_ENTRY |
681 | __field(u8, value) | 681 | __field(s16, value) |
682 | ), | 682 | ), |
683 | 683 | ||
684 | TP_fast_assign( | 684 | TP_fast_assign( |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index cf7141452b0f..900632a250ec 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -1788,9 +1789,8 @@ static void ieee80211_tx_latency_start_msrmnt(struct ieee80211_local *local, | |||
1788 | * @skb: packet to be sent | 1789 | * @skb: packet to be sent |
1789 | * @dev: incoming interface | 1790 | * @dev: incoming interface |
1790 | * | 1791 | * |
1791 | * Returns: 0 on success (and frees skb in this case) or 1 on failure (skb will | 1792 | * Returns: NETDEV_TX_OK both on success and on failure. On failure skb will |
1792 | * not be freed, and caller is responsible for either retrying later or freeing | 1793 | * be freed. |
1793 | * skb). | ||
1794 | * | 1794 | * |
1795 | * This function takes in an Ethernet header and encapsulates it with suitable | 1795 | * This function takes in an Ethernet header and encapsulates it with suitable |
1796 | * IEEE 802.11 header based on which interface the packet is coming in. The | 1796 | * IEEE 802.11 header based on which interface the packet is coming in. The |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 725af7a468d2..3c61060a4d2b 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 5 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
@@ -1014,6 +1015,31 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action, | |||
1014 | } | 1015 | } |
1015 | elems->pwr_constr_elem = pos; | 1016 | elems->pwr_constr_elem = pos; |
1016 | break; | 1017 | break; |
1018 | case WLAN_EID_CISCO_VENDOR_SPECIFIC: | ||
1019 | /* Lots of different options exist, but we only care | ||
1020 | * about the Dynamic Transmit Power Control element. | ||
1021 | * First check for the Cisco OUI, then for the DTPC | ||
1022 | * tag (0x00). | ||
1023 | */ | ||
1024 | if (elen < 4) { | ||
1025 | elem_parse_failed = true; | ||
1026 | break; | ||
1027 | } | ||
1028 | |||
1029 | if (pos[0] != 0x00 || pos[1] != 0x40 || | ||
1030 | pos[2] != 0x96 || pos[3] != 0x00) | ||
1031 | break; | ||
1032 | |||
1033 | if (elen != 6) { | ||
1034 | elem_parse_failed = true; | ||
1035 | break; | ||
1036 | } | ||
1037 | |||
1038 | if (calc_crc) | ||
1039 | crc = crc32_be(crc, pos - 2, elen + 2); | ||
1040 | |||
1041 | elems->cisco_dtpc_elem = pos; | ||
1042 | break; | ||
1017 | case WLAN_EID_TIMEOUT_INTERVAL: | 1043 | case WLAN_EID_TIMEOUT_INTERVAL: |
1018 | if (elen >= sizeof(struct ieee80211_timeout_interval_ie)) | 1044 | if (elen >= sizeof(struct ieee80211_timeout_interval_ie)) |
1019 | elems->timeout_int = (void *)pos; | 1045 | elems->timeout_int = (void *)pos; |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 6459946f0b74..3b873989992c 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -1,5 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright 2004, Instant802 Networks, Inc. | 2 | * Copyright 2004, Instant802 Networks, Inc. |
3 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index f7d4ca4c46e0..983527a4c1ab 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -64,8 +64,11 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
64 | if (!info->control.hw_key) | 64 | if (!info->control.hw_key) |
65 | tail += IEEE80211_TKIP_ICV_LEN; | 65 | tail += IEEE80211_TKIP_ICV_LEN; |
66 | 66 | ||
67 | if (WARN_ON(skb_tailroom(skb) < tail || | 67 | if (WARN(skb_tailroom(skb) < tail || |
68 | skb_headroom(skb) < IEEE80211_TKIP_IV_LEN)) | 68 | skb_headroom(skb) < IEEE80211_TKIP_IV_LEN, |
69 | "mmic: not enough head/tail (%d/%d,%d/%d)\n", | ||
70 | skb_headroom(skb), IEEE80211_TKIP_IV_LEN, | ||
71 | skb_tailroom(skb), tail)) | ||
69 | return TX_DROP; | 72 | return TX_DROP; |
70 | 73 | ||
71 | key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]; | 74 | key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]; |
diff --git a/net/wireless/chan.c b/net/wireless/chan.c index 992b34070bcb..72d81e2154d5 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * any point in time. | 4 | * any point in time. |
5 | * | 5 | * |
6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2009 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | #include <linux/export.h> | 10 | #include <linux/export.h> |
diff --git a/net/wireless/core.c b/net/wireless/core.c index c6620aa679e0..f52a4cd7017c 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * This is the linux wireless configuration interface. | 2 | * This is the linux wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
@@ -1005,7 +1006,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
1005 | rdev->devlist_generation++; | 1006 | rdev->devlist_generation++; |
1006 | cfg80211_mlme_purge_registrations(wdev); | 1007 | cfg80211_mlme_purge_registrations(wdev); |
1007 | #ifdef CONFIG_CFG80211_WEXT | 1008 | #ifdef CONFIG_CFG80211_WEXT |
1008 | kfree(wdev->wext.keys); | 1009 | kzfree(wdev->wext.keys); |
1009 | #endif | 1010 | #endif |
1010 | } | 1011 | } |
1011 | /* | 1012 | /* |
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c index 8f345da3ea5f..e24fc585c883 100644 --- a/net/wireless/ibss.c +++ b/net/wireless/ibss.c | |||
@@ -115,7 +115,7 @@ static int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, | |||
115 | } | 115 | } |
116 | 116 | ||
117 | if (WARN_ON(wdev->connect_keys)) | 117 | if (WARN_ON(wdev->connect_keys)) |
118 | kfree(wdev->connect_keys); | 118 | kzfree(wdev->connect_keys); |
119 | wdev->connect_keys = connkeys; | 119 | wdev->connect_keys = connkeys; |
120 | 120 | ||
121 | wdev->ibss_fixed = params->channel_fixed; | 121 | wdev->ibss_fixed = params->channel_fixed; |
@@ -161,7 +161,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) | |||
161 | 161 | ||
162 | ASSERT_WDEV_LOCK(wdev); | 162 | ASSERT_WDEV_LOCK(wdev); |
163 | 163 | ||
164 | kfree(wdev->connect_keys); | 164 | kzfree(wdev->connect_keys); |
165 | wdev->connect_keys = NULL; | 165 | wdev->connect_keys = NULL; |
166 | 166 | ||
167 | rdev_set_qos_map(rdev, dev, NULL); | 167 | rdev_set_qos_map(rdev, dev, NULL); |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 369fc334fdad..2c52b59e43f3 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -19,7 +19,7 @@ | |||
19 | 19 | ||
20 | 20 | ||
21 | void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | 21 | void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, |
22 | const u8 *buf, size_t len) | 22 | const u8 *buf, size_t len, int uapsd_queues) |
23 | { | 23 | { |
24 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 24 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
25 | struct wiphy *wiphy = wdev->wiphy; | 25 | struct wiphy *wiphy = wdev->wiphy; |
@@ -43,7 +43,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, | |||
43 | return; | 43 | return; |
44 | } | 44 | } |
45 | 45 | ||
46 | nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); | 46 | nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL, uapsd_queues); |
47 | /* update current_bss etc., consumes the bss reference */ | 47 | /* update current_bss etc., consumes the bss reference */ |
48 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, | 48 | __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs, |
49 | status_code, | 49 | status_code, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 233c54e45092..cb9f5a44ffad 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * This is the new netlink-based wireless configuration interface. | 2 | * This is the new netlink-based wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | 7 | ||
7 | #include <linux/if.h> | 8 | #include <linux/if.h> |
@@ -225,6 +226,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
225 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, | 226 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, |
226 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, | 227 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, |
227 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, | 228 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, |
229 | [NL80211_ATTR_WIPHY_DYN_ACK] = { .type = NLA_FLAG }, | ||
228 | 230 | ||
229 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 231 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
230 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 232 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
@@ -388,6 +390,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
388 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, | 390 | [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 }, |
389 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, | 391 | [NL80211_ATTR_IFACE_SOCKET_OWNER] = { .type = NLA_FLAG }, |
390 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, | 392 | [NL80211_ATTR_CSA_C_OFFSETS_TX] = { .type = NLA_BINARY }, |
393 | [NL80211_ATTR_USE_RRM] = { .type = NLA_FLAG }, | ||
394 | [NL80211_ATTR_TSID] = { .type = NLA_U8 }, | ||
395 | [NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 }, | ||
396 | [NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 }, | ||
397 | [NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 }, | ||
391 | }; | 398 | }; |
392 | 399 | ||
393 | /* policy for the key attributes */ | 400 | /* policy for the key attributes */ |
@@ -1507,6 +1514,9 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev, | |||
1507 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) | 1514 | if (rdev->wiphy.flags & WIPHY_FLAG_HAS_CHANNEL_SWITCH) |
1508 | CMD(channel_switch, CHANNEL_SWITCH); | 1515 | CMD(channel_switch, CHANNEL_SWITCH); |
1509 | CMD(set_qos_map, SET_QOS_MAP); | 1516 | CMD(set_qos_map, SET_QOS_MAP); |
1517 | if (rdev->wiphy.flags & | ||
1518 | WIPHY_FLAG_SUPPORTS_WMM_ADMISSION) | ||
1519 | CMD(add_tx_ts, ADD_TX_TS); | ||
1510 | } | 1520 | } |
1511 | /* add into the if now */ | 1521 | /* add into the if now */ |
1512 | #undef CMD | 1522 | #undef CMD |
@@ -2237,11 +2247,21 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
2237 | } | 2247 | } |
2238 | 2248 | ||
2239 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { | 2249 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { |
2250 | if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) | ||
2251 | return -EINVAL; | ||
2252 | |||
2240 | coverage_class = nla_get_u8( | 2253 | coverage_class = nla_get_u8( |
2241 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); | 2254 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); |
2242 | changed |= WIPHY_PARAM_COVERAGE_CLASS; | 2255 | changed |= WIPHY_PARAM_COVERAGE_CLASS; |
2243 | } | 2256 | } |
2244 | 2257 | ||
2258 | if (info->attrs[NL80211_ATTR_WIPHY_DYN_ACK]) { | ||
2259 | if (!(rdev->wiphy.features & NL80211_FEATURE_ACKTO_ESTIMATION)) | ||
2260 | return -EOPNOTSUPP; | ||
2261 | |||
2262 | changed |= WIPHY_PARAM_DYN_ACK; | ||
2263 | } | ||
2264 | |||
2245 | if (changed) { | 2265 | if (changed) { |
2246 | u8 old_retry_short, old_retry_long; | 2266 | u8 old_retry_short, old_retry_long; |
2247 | u32 old_frag_threshold, old_rts_threshold; | 2267 | u32 old_frag_threshold, old_rts_threshold; |
@@ -3326,6 +3346,29 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | |||
3326 | return PTR_ERR(params.acl); | 3346 | return PTR_ERR(params.acl); |
3327 | } | 3347 | } |
3328 | 3348 | ||
3349 | if (info->attrs[NL80211_ATTR_SMPS_MODE]) { | ||
3350 | params.smps_mode = | ||
3351 | nla_get_u8(info->attrs[NL80211_ATTR_SMPS_MODE]); | ||
3352 | switch (params.smps_mode) { | ||
3353 | case NL80211_SMPS_OFF: | ||
3354 | break; | ||
3355 | case NL80211_SMPS_STATIC: | ||
3356 | if (!(rdev->wiphy.features & | ||
3357 | NL80211_FEATURE_STATIC_SMPS)) | ||
3358 | return -EINVAL; | ||
3359 | break; | ||
3360 | case NL80211_SMPS_DYNAMIC: | ||
3361 | if (!(rdev->wiphy.features & | ||
3362 | NL80211_FEATURE_DYNAMIC_SMPS)) | ||
3363 | return -EINVAL; | ||
3364 | break; | ||
3365 | default: | ||
3366 | return -EINVAL; | ||
3367 | } | ||
3368 | } else { | ||
3369 | params.smps_mode = NL80211_SMPS_OFF; | ||
3370 | } | ||
3371 | |||
3329 | wdev_lock(wdev); | 3372 | wdev_lock(wdev); |
3330 | err = rdev_start_ap(rdev, dev, ¶ms); | 3373 | err = rdev_start_ap(rdev, dev, ¶ms); |
3331 | if (!err) { | 3374 | if (!err) { |
@@ -6583,6 +6626,14 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | |||
6583 | sizeof(req.vht_capa)); | 6626 | sizeof(req.vht_capa)); |
6584 | } | 6627 | } |
6585 | 6628 | ||
6629 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { | ||
6630 | if (!(rdev->wiphy.features & | ||
6631 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || | ||
6632 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) | ||
6633 | return -EINVAL; | ||
6634 | req.flags |= ASSOC_REQ_USE_RRM; | ||
6635 | } | ||
6636 | |||
6586 | err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); | 6637 | err = nl80211_crypto_settings(rdev, info, &req.crypto, 1); |
6587 | if (!err) { | 6638 | if (!err) { |
6588 | wdev_lock(dev->ieee80211_ptr); | 6639 | wdev_lock(dev->ieee80211_ptr); |
@@ -6845,7 +6896,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
6845 | 6896 | ||
6846 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 6897 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
6847 | if (err) | 6898 | if (err) |
6848 | kfree(connkeys); | 6899 | kzfree(connkeys); |
6849 | return err; | 6900 | return err; |
6850 | } | 6901 | } |
6851 | 6902 | ||
@@ -7217,7 +7268,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7217 | 7268 | ||
7218 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | 7269 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { |
7219 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { | 7270 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { |
7220 | kfree(connkeys); | 7271 | kzfree(connkeys); |
7221 | return -EINVAL; | 7272 | return -EINVAL; |
7222 | } | 7273 | } |
7223 | memcpy(&connect.ht_capa, | 7274 | memcpy(&connect.ht_capa, |
@@ -7235,7 +7286,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7235 | 7286 | ||
7236 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) { | 7287 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) { |
7237 | if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) { | 7288 | if (!info->attrs[NL80211_ATTR_VHT_CAPABILITY_MASK]) { |
7238 | kfree(connkeys); | 7289 | kzfree(connkeys); |
7239 | return -EINVAL; | 7290 | return -EINVAL; |
7240 | } | 7291 | } |
7241 | memcpy(&connect.vht_capa, | 7292 | memcpy(&connect.vht_capa, |
@@ -7243,11 +7294,19 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | |||
7243 | sizeof(connect.vht_capa)); | 7294 | sizeof(connect.vht_capa)); |
7244 | } | 7295 | } |
7245 | 7296 | ||
7297 | if (nla_get_flag(info->attrs[NL80211_ATTR_USE_RRM])) { | ||
7298 | if (!(rdev->wiphy.features & | ||
7299 | NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES) || | ||
7300 | !(rdev->wiphy.features & NL80211_FEATURE_QUIET)) | ||
7301 | return -EINVAL; | ||
7302 | connect.flags |= ASSOC_REQ_USE_RRM; | ||
7303 | } | ||
7304 | |||
7246 | wdev_lock(dev->ieee80211_ptr); | 7305 | wdev_lock(dev->ieee80211_ptr); |
7247 | err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL); | 7306 | err = cfg80211_connect(rdev, dev, &connect, connkeys, NULL); |
7248 | wdev_unlock(dev->ieee80211_ptr); | 7307 | wdev_unlock(dev->ieee80211_ptr); |
7249 | if (err) | 7308 | if (err) |
7250 | kfree(connkeys); | 7309 | kzfree(connkeys); |
7251 | return err; | 7310 | return err; |
7252 | } | 7311 | } |
7253 | 7312 | ||
@@ -8933,13 +8992,9 @@ static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | |||
8933 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) | 8992 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) |
8934 | return -ERANGE; | 8993 | return -ERANGE; |
8935 | 8994 | ||
8936 | memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]), | 8995 | rekey_data.kek = nla_data(tb[NL80211_REKEY_DATA_KEK]); |
8937 | NL80211_KEK_LEN); | 8996 | rekey_data.kck = nla_data(tb[NL80211_REKEY_DATA_KCK]); |
8938 | memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]), | 8997 | rekey_data.replay_ctr = nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]); |
8939 | NL80211_KCK_LEN); | ||
8940 | memcpy(rekey_data.replay_ctr, | ||
8941 | nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]), | ||
8942 | NL80211_REPLAY_CTR_LEN); | ||
8943 | 8998 | ||
8944 | wdev_lock(wdev); | 8999 | wdev_lock(wdev); |
8945 | if (!wdev->current_bss) { | 9000 | if (!wdev->current_bss) { |
@@ -9371,6 +9426,93 @@ static int nl80211_set_qos_map(struct sk_buff *skb, | |||
9371 | return ret; | 9426 | return ret; |
9372 | } | 9427 | } |
9373 | 9428 | ||
9429 | static int nl80211_add_tx_ts(struct sk_buff *skb, struct genl_info *info) | ||
9430 | { | ||
9431 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
9432 | struct net_device *dev = info->user_ptr[1]; | ||
9433 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
9434 | const u8 *peer; | ||
9435 | u8 tsid, up; | ||
9436 | u16 admitted_time = 0; | ||
9437 | int err; | ||
9438 | |||
9439 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | ||
9440 | return -EOPNOTSUPP; | ||
9441 | |||
9442 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC] || | ||
9443 | !info->attrs[NL80211_ATTR_USER_PRIO]) | ||
9444 | return -EINVAL; | ||
9445 | |||
9446 | tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]); | ||
9447 | if (tsid >= IEEE80211_NUM_TIDS) | ||
9448 | return -EINVAL; | ||
9449 | |||
9450 | up = nla_get_u8(info->attrs[NL80211_ATTR_USER_PRIO]); | ||
9451 | if (up >= IEEE80211_NUM_UPS) | ||
9452 | return -EINVAL; | ||
9453 | |||
9454 | /* WMM uses TIDs 0-7 even for TSPEC */ | ||
9455 | if (tsid < IEEE80211_FIRST_TSPEC_TSID) { | ||
9456 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_WMM_ADMISSION)) | ||
9457 | return -EINVAL; | ||
9458 | } else { | ||
9459 | /* TODO: handle 802.11 TSPEC/admission control | ||
9460 | * need more attributes for that (e.g. BA session requirement) | ||
9461 | */ | ||
9462 | return -EINVAL; | ||
9463 | } | ||
9464 | |||
9465 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
9466 | |||
9467 | if (info->attrs[NL80211_ATTR_ADMITTED_TIME]) { | ||
9468 | admitted_time = | ||
9469 | nla_get_u16(info->attrs[NL80211_ATTR_ADMITTED_TIME]); | ||
9470 | if (!admitted_time) | ||
9471 | return -EINVAL; | ||
9472 | } | ||
9473 | |||
9474 | wdev_lock(wdev); | ||
9475 | switch (wdev->iftype) { | ||
9476 | case NL80211_IFTYPE_STATION: | ||
9477 | case NL80211_IFTYPE_P2P_CLIENT: | ||
9478 | if (wdev->current_bss) | ||
9479 | break; | ||
9480 | err = -ENOTCONN; | ||
9481 | goto out; | ||
9482 | default: | ||
9483 | err = -EOPNOTSUPP; | ||
9484 | goto out; | ||
9485 | } | ||
9486 | |||
9487 | err = rdev_add_tx_ts(rdev, dev, tsid, peer, up, admitted_time); | ||
9488 | |||
9489 | out: | ||
9490 | wdev_unlock(wdev); | ||
9491 | return err; | ||
9492 | } | ||
9493 | |||
9494 | static int nl80211_del_tx_ts(struct sk_buff *skb, struct genl_info *info) | ||
9495 | { | ||
9496 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | ||
9497 | struct net_device *dev = info->user_ptr[1]; | ||
9498 | struct wireless_dev *wdev = dev->ieee80211_ptr; | ||
9499 | const u8 *peer; | ||
9500 | u8 tsid; | ||
9501 | int err; | ||
9502 | |||
9503 | if (!info->attrs[NL80211_ATTR_TSID] || !info->attrs[NL80211_ATTR_MAC]) | ||
9504 | return -EINVAL; | ||
9505 | |||
9506 | tsid = nla_get_u8(info->attrs[NL80211_ATTR_TSID]); | ||
9507 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | ||
9508 | |||
9509 | wdev_lock(wdev); | ||
9510 | err = rdev_del_tx_ts(rdev, dev, tsid, peer); | ||
9511 | wdev_unlock(wdev); | ||
9512 | |||
9513 | return err; | ||
9514 | } | ||
9515 | |||
9374 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 9516 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
9375 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 9517 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
9376 | #define NL80211_FLAG_NEED_RTNL 0x04 | 9518 | #define NL80211_FLAG_NEED_RTNL 0x04 |
@@ -9381,6 +9523,7 @@ static int nl80211_set_qos_map(struct sk_buff *skb, | |||
9381 | /* If a netdev is associated, it must be UP, P2P must be started */ | 9523 | /* If a netdev is associated, it must be UP, P2P must be started */ |
9382 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | 9524 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
9383 | NL80211_FLAG_CHECK_NETDEV_UP) | 9525 | NL80211_FLAG_CHECK_NETDEV_UP) |
9526 | #define NL80211_FLAG_CLEAR_SKB 0x20 | ||
9384 | 9527 | ||
9385 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, | 9528 | static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb, |
9386 | struct genl_info *info) | 9529 | struct genl_info *info) |
@@ -9464,8 +9607,20 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb, | |||
9464 | dev_put(info->user_ptr[1]); | 9607 | dev_put(info->user_ptr[1]); |
9465 | } | 9608 | } |
9466 | } | 9609 | } |
9610 | |||
9467 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) | 9611 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) |
9468 | rtnl_unlock(); | 9612 | rtnl_unlock(); |
9613 | |||
9614 | /* If needed, clear the netlink message payload from the SKB | ||
9615 | * as it might contain key data that shouldn't stick around on | ||
9616 | * the heap after the SKB is freed. The netlink message header | ||
9617 | * is still needed for further processing, so leave it intact. | ||
9618 | */ | ||
9619 | if (ops->internal_flags & NL80211_FLAG_CLEAR_SKB) { | ||
9620 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | ||
9621 | |||
9622 | memset(nlmsg_data(nlh), 0, nlmsg_len(nlh)); | ||
9623 | } | ||
9469 | } | 9624 | } |
9470 | 9625 | ||
9471 | static const struct genl_ops nl80211_ops[] = { | 9626 | static const struct genl_ops nl80211_ops[] = { |
@@ -9533,7 +9688,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9533 | .policy = nl80211_policy, | 9688 | .policy = nl80211_policy, |
9534 | .flags = GENL_ADMIN_PERM, | 9689 | .flags = GENL_ADMIN_PERM, |
9535 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9690 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9536 | NL80211_FLAG_NEED_RTNL, | 9691 | NL80211_FLAG_NEED_RTNL | |
9692 | NL80211_FLAG_CLEAR_SKB, | ||
9537 | }, | 9693 | }, |
9538 | { | 9694 | { |
9539 | .cmd = NL80211_CMD_NEW_KEY, | 9695 | .cmd = NL80211_CMD_NEW_KEY, |
@@ -9541,7 +9697,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9541 | .policy = nl80211_policy, | 9697 | .policy = nl80211_policy, |
9542 | .flags = GENL_ADMIN_PERM, | 9698 | .flags = GENL_ADMIN_PERM, |
9543 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9699 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9544 | NL80211_FLAG_NEED_RTNL, | 9700 | NL80211_FLAG_NEED_RTNL | |
9701 | NL80211_FLAG_CLEAR_SKB, | ||
9545 | }, | 9702 | }, |
9546 | { | 9703 | { |
9547 | .cmd = NL80211_CMD_DEL_KEY, | 9704 | .cmd = NL80211_CMD_DEL_KEY, |
@@ -9719,7 +9876,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9719 | .policy = nl80211_policy, | 9876 | .policy = nl80211_policy, |
9720 | .flags = GENL_ADMIN_PERM, | 9877 | .flags = GENL_ADMIN_PERM, |
9721 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 9878 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9722 | NL80211_FLAG_NEED_RTNL, | 9879 | NL80211_FLAG_NEED_RTNL | |
9880 | NL80211_FLAG_CLEAR_SKB, | ||
9723 | }, | 9881 | }, |
9724 | { | 9882 | { |
9725 | .cmd = NL80211_CMD_ASSOCIATE, | 9883 | .cmd = NL80211_CMD_ASSOCIATE, |
@@ -9953,7 +10111,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
9953 | .policy = nl80211_policy, | 10111 | .policy = nl80211_policy, |
9954 | .flags = GENL_ADMIN_PERM, | 10112 | .flags = GENL_ADMIN_PERM, |
9955 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 10113 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
9956 | NL80211_FLAG_NEED_RTNL, | 10114 | NL80211_FLAG_NEED_RTNL | |
10115 | NL80211_FLAG_CLEAR_SKB, | ||
9957 | }, | 10116 | }, |
9958 | { | 10117 | { |
9959 | .cmd = NL80211_CMD_TDLS_MGMT, | 10118 | .cmd = NL80211_CMD_TDLS_MGMT, |
@@ -10111,6 +10270,22 @@ static const struct genl_ops nl80211_ops[] = { | |||
10111 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 10270 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
10112 | NL80211_FLAG_NEED_RTNL, | 10271 | NL80211_FLAG_NEED_RTNL, |
10113 | }, | 10272 | }, |
10273 | { | ||
10274 | .cmd = NL80211_CMD_ADD_TX_TS, | ||
10275 | .doit = nl80211_add_tx_ts, | ||
10276 | .policy = nl80211_policy, | ||
10277 | .flags = GENL_ADMIN_PERM, | ||
10278 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10279 | NL80211_FLAG_NEED_RTNL, | ||
10280 | }, | ||
10281 | { | ||
10282 | .cmd = NL80211_CMD_DEL_TX_TS, | ||
10283 | .doit = nl80211_del_tx_ts, | ||
10284 | .policy = nl80211_policy, | ||
10285 | .flags = GENL_ADMIN_PERM, | ||
10286 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | ||
10287 | NL80211_FLAG_NEED_RTNL, | ||
10288 | }, | ||
10114 | }; | 10289 | }; |
10115 | 10290 | ||
10116 | /* notification functions */ | 10291 | /* notification functions */ |
@@ -10379,7 +10554,8 @@ nla_put_failure: | |||
10379 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | 10554 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, |
10380 | struct net_device *netdev, | 10555 | struct net_device *netdev, |
10381 | const u8 *buf, size_t len, | 10556 | const u8 *buf, size_t len, |
10382 | enum nl80211_commands cmd, gfp_t gfp) | 10557 | enum nl80211_commands cmd, gfp_t gfp, |
10558 | int uapsd_queues) | ||
10383 | { | 10559 | { |
10384 | struct sk_buff *msg; | 10560 | struct sk_buff *msg; |
10385 | void *hdr; | 10561 | void *hdr; |
@@ -10399,6 +10575,19 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | |||
10399 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) | 10575 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) |
10400 | goto nla_put_failure; | 10576 | goto nla_put_failure; |
10401 | 10577 | ||
10578 | if (uapsd_queues >= 0) { | ||
10579 | struct nlattr *nla_wmm = | ||
10580 | nla_nest_start(msg, NL80211_ATTR_STA_WME); | ||
10581 | if (!nla_wmm) | ||
10582 | goto nla_put_failure; | ||
10583 | |||
10584 | if (nla_put_u8(msg, NL80211_STA_WME_UAPSD_QUEUES, | ||
10585 | uapsd_queues)) | ||
10586 | goto nla_put_failure; | ||
10587 | |||
10588 | nla_nest_end(msg, nla_wmm); | ||
10589 | } | ||
10590 | |||
10402 | genlmsg_end(msg, hdr); | 10591 | genlmsg_end(msg, hdr); |
10403 | 10592 | ||
10404 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, | 10593 | genlmsg_multicast_netns(&nl80211_fam, wiphy_net(&rdev->wiphy), msg, 0, |
@@ -10415,15 +10604,15 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | |||
10415 | size_t len, gfp_t gfp) | 10604 | size_t len, gfp_t gfp) |
10416 | { | 10605 | { |
10417 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10606 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10418 | NL80211_CMD_AUTHENTICATE, gfp); | 10607 | NL80211_CMD_AUTHENTICATE, gfp, -1); |
10419 | } | 10608 | } |
10420 | 10609 | ||
10421 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, | 10610 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, |
10422 | struct net_device *netdev, const u8 *buf, | 10611 | struct net_device *netdev, const u8 *buf, |
10423 | size_t len, gfp_t gfp) | 10612 | size_t len, gfp_t gfp, int uapsd_queues) |
10424 | { | 10613 | { |
10425 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10614 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10426 | NL80211_CMD_ASSOCIATE, gfp); | 10615 | NL80211_CMD_ASSOCIATE, gfp, uapsd_queues); |
10427 | } | 10616 | } |
10428 | 10617 | ||
10429 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | 10618 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, |
@@ -10431,7 +10620,7 @@ void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | |||
10431 | size_t len, gfp_t gfp) | 10620 | size_t len, gfp_t gfp) |
10432 | { | 10621 | { |
10433 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10622 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10434 | NL80211_CMD_DEAUTHENTICATE, gfp); | 10623 | NL80211_CMD_DEAUTHENTICATE, gfp, -1); |
10435 | } | 10624 | } |
10436 | 10625 | ||
10437 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | 10626 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, |
@@ -10439,7 +10628,7 @@ void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | |||
10439 | size_t len, gfp_t gfp) | 10628 | size_t len, gfp_t gfp) |
10440 | { | 10629 | { |
10441 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 10630 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
10442 | NL80211_CMD_DISASSOCIATE, gfp); | 10631 | NL80211_CMD_DISASSOCIATE, gfp, -1); |
10443 | } | 10632 | } |
10444 | 10633 | ||
10445 | void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, | 10634 | void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, |
@@ -10460,7 +10649,7 @@ void cfg80211_rx_unprot_mlme_mgmt(struct net_device *dev, const u8 *buf, | |||
10460 | cmd = NL80211_CMD_UNPROT_DISASSOCIATE; | 10649 | cmd = NL80211_CMD_UNPROT_DISASSOCIATE; |
10461 | 10650 | ||
10462 | trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); | 10651 | trace_cfg80211_rx_unprot_mlme_mgmt(dev, buf, len); |
10463 | nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC); | 10652 | nl80211_send_mlme_event(rdev, dev, buf, len, cmd, GFP_ATOMIC, -1); |
10464 | } | 10653 | } |
10465 | EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); | 10654 | EXPORT_SYMBOL(cfg80211_rx_unprot_mlme_mgmt); |
10466 | 10655 | ||
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h index 49c9a482dd12..7ad70d6f0cc6 100644 --- a/net/wireless/nl80211.h +++ b/net/wireless/nl80211.h | |||
@@ -23,7 +23,8 @@ void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | |||
23 | const u8 *buf, size_t len, gfp_t gfp); | 23 | const u8 *buf, size_t len, gfp_t gfp); |
24 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, | 24 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, |
25 | struct net_device *netdev, | 25 | struct net_device *netdev, |
26 | const u8 *buf, size_t len, gfp_t gfp); | 26 | const u8 *buf, size_t len, gfp_t gfp, |
27 | int uapsd_queues); | ||
27 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | 28 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, |
28 | struct net_device *netdev, | 29 | struct net_device *netdev, |
29 | const u8 *buf, size_t len, gfp_t gfp); | 30 | const u8 *buf, size_t len, gfp_t gfp); |
diff --git a/net/wireless/rdev-ops.h b/net/wireless/rdev-ops.h index 56c2240c30ce..f6d457d6a558 100644 --- a/net/wireless/rdev-ops.h +++ b/net/wireless/rdev-ops.h | |||
@@ -915,4 +915,35 @@ rdev_set_ap_chanwidth(struct cfg80211_registered_device *rdev, | |||
915 | return ret; | 915 | return ret; |
916 | } | 916 | } |
917 | 917 | ||
918 | static inline int | ||
919 | rdev_add_tx_ts(struct cfg80211_registered_device *rdev, | ||
920 | struct net_device *dev, u8 tsid, const u8 *peer, | ||
921 | u8 user_prio, u16 admitted_time) | ||
922 | { | ||
923 | int ret = -EOPNOTSUPP; | ||
924 | |||
925 | trace_rdev_add_tx_ts(&rdev->wiphy, dev, tsid, peer, | ||
926 | user_prio, admitted_time); | ||
927 | if (rdev->ops->add_tx_ts) | ||
928 | ret = rdev->ops->add_tx_ts(&rdev->wiphy, dev, tsid, peer, | ||
929 | user_prio, admitted_time); | ||
930 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
931 | |||
932 | return ret; | ||
933 | } | ||
934 | |||
935 | static inline int | ||
936 | rdev_del_tx_ts(struct cfg80211_registered_device *rdev, | ||
937 | struct net_device *dev, u8 tsid, const u8 *peer) | ||
938 | { | ||
939 | int ret = -EOPNOTSUPP; | ||
940 | |||
941 | trace_rdev_del_tx_ts(&rdev->wiphy, dev, tsid, peer); | ||
942 | if (rdev->ops->del_tx_ts) | ||
943 | ret = rdev->ops->del_tx_ts(&rdev->wiphy, dev, tsid, peer); | ||
944 | trace_rdev_return_int(&rdev->wiphy, ret); | ||
945 | |||
946 | return ret; | ||
947 | } | ||
948 | |||
918 | #endif /* __CFG80211_RDEV_OPS */ | 949 | #endif /* __CFG80211_RDEV_OPS */ |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1afdf45db38f..b725a31a4751 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * Copyright 2005-2006, Devicescape Software, Inc. | 3 | * Copyright 2005-2006, Devicescape Software, Inc. |
4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> | 5 | * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com> |
6 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
6 | * | 7 | * |
7 | * Permission to use, copy, modify, and/or distribute this software for any | 8 | * Permission to use, copy, modify, and/or distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | 9 | * purpose with or without fee is hereby granted, provided that the above |
@@ -798,6 +799,57 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
798 | return 0; | 799 | return 0; |
799 | } | 800 | } |
800 | 801 | ||
802 | /* check whether old rule contains new rule */ | ||
803 | static bool rule_contains(struct ieee80211_reg_rule *r1, | ||
804 | struct ieee80211_reg_rule *r2) | ||
805 | { | ||
806 | /* for simplicity, currently consider only same flags */ | ||
807 | if (r1->flags != r2->flags) | ||
808 | return false; | ||
809 | |||
810 | /* verify r1 is more restrictive */ | ||
811 | if ((r1->power_rule.max_antenna_gain > | ||
812 | r2->power_rule.max_antenna_gain) || | ||
813 | r1->power_rule.max_eirp > r2->power_rule.max_eirp) | ||
814 | return false; | ||
815 | |||
816 | /* make sure r2's range is contained within r1 */ | ||
817 | if (r1->freq_range.start_freq_khz > r2->freq_range.start_freq_khz || | ||
818 | r1->freq_range.end_freq_khz < r2->freq_range.end_freq_khz) | ||
819 | return false; | ||
820 | |||
821 | /* and finally verify that r1.max_bw >= r2.max_bw */ | ||
822 | if (r1->freq_range.max_bandwidth_khz < | ||
823 | r2->freq_range.max_bandwidth_khz) | ||
824 | return false; | ||
825 | |||
826 | return true; | ||
827 | } | ||
828 | |||
829 | /* add or extend current rules. do nothing if rule is already contained */ | ||
830 | static void add_rule(struct ieee80211_reg_rule *rule, | ||
831 | struct ieee80211_reg_rule *reg_rules, u32 *n_rules) | ||
832 | { | ||
833 | struct ieee80211_reg_rule *tmp_rule; | ||
834 | int i; | ||
835 | |||
836 | for (i = 0; i < *n_rules; i++) { | ||
837 | tmp_rule = ®_rules[i]; | ||
838 | /* rule is already contained - do nothing */ | ||
839 | if (rule_contains(tmp_rule, rule)) | ||
840 | return; | ||
841 | |||
842 | /* extend rule if possible */ | ||
843 | if (rule_contains(rule, tmp_rule)) { | ||
844 | memcpy(tmp_rule, rule, sizeof(*rule)); | ||
845 | return; | ||
846 | } | ||
847 | } | ||
848 | |||
849 | memcpy(®_rules[*n_rules], rule, sizeof(*rule)); | ||
850 | (*n_rules)++; | ||
851 | } | ||
852 | |||
801 | /** | 853 | /** |
802 | * regdom_intersect - do the intersection between two regulatory domains | 854 | * regdom_intersect - do the intersection between two regulatory domains |
803 | * @rd1: first regulatory domain | 855 | * @rd1: first regulatory domain |
@@ -817,12 +869,10 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
817 | { | 869 | { |
818 | int r, size_of_regd; | 870 | int r, size_of_regd; |
819 | unsigned int x, y; | 871 | unsigned int x, y; |
820 | unsigned int num_rules = 0, rule_idx = 0; | 872 | unsigned int num_rules = 0; |
821 | const struct ieee80211_reg_rule *rule1, *rule2; | 873 | const struct ieee80211_reg_rule *rule1, *rule2; |
822 | struct ieee80211_reg_rule *intersected_rule; | 874 | struct ieee80211_reg_rule intersected_rule; |
823 | struct ieee80211_regdomain *rd; | 875 | struct ieee80211_regdomain *rd; |
824 | /* This is just a dummy holder to help us count */ | ||
825 | struct ieee80211_reg_rule dummy_rule; | ||
826 | 876 | ||
827 | if (!rd1 || !rd2) | 877 | if (!rd1 || !rd2) |
828 | return NULL; | 878 | return NULL; |
@@ -840,7 +890,7 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
840 | for (y = 0; y < rd2->n_reg_rules; y++) { | 890 | for (y = 0; y < rd2->n_reg_rules; y++) { |
841 | rule2 = &rd2->reg_rules[y]; | 891 | rule2 = &rd2->reg_rules[y]; |
842 | if (!reg_rules_intersect(rd1, rd2, rule1, rule2, | 892 | if (!reg_rules_intersect(rd1, rd2, rule1, rule2, |
843 | &dummy_rule)) | 893 | &intersected_rule)) |
844 | num_rules++; | 894 | num_rules++; |
845 | } | 895 | } |
846 | } | 896 | } |
@@ -855,34 +905,24 @@ regdom_intersect(const struct ieee80211_regdomain *rd1, | |||
855 | if (!rd) | 905 | if (!rd) |
856 | return NULL; | 906 | return NULL; |
857 | 907 | ||
858 | for (x = 0; x < rd1->n_reg_rules && rule_idx < num_rules; x++) { | 908 | for (x = 0; x < rd1->n_reg_rules; x++) { |
859 | rule1 = &rd1->reg_rules[x]; | 909 | rule1 = &rd1->reg_rules[x]; |
860 | for (y = 0; y < rd2->n_reg_rules && rule_idx < num_rules; y++) { | 910 | for (y = 0; y < rd2->n_reg_rules; y++) { |
861 | rule2 = &rd2->reg_rules[y]; | 911 | rule2 = &rd2->reg_rules[y]; |
862 | /* | ||
863 | * This time around instead of using the stack lets | ||
864 | * write to the target rule directly saving ourselves | ||
865 | * a memcpy() | ||
866 | */ | ||
867 | intersected_rule = &rd->reg_rules[rule_idx]; | ||
868 | r = reg_rules_intersect(rd1, rd2, rule1, rule2, | 912 | r = reg_rules_intersect(rd1, rd2, rule1, rule2, |
869 | intersected_rule); | 913 | &intersected_rule); |
870 | /* | 914 | /* |
871 | * No need to memset here the intersected rule here as | 915 | * No need to memset here the intersected rule here as |
872 | * we're not using the stack anymore | 916 | * we're not using the stack anymore |
873 | */ | 917 | */ |
874 | if (r) | 918 | if (r) |
875 | continue; | 919 | continue; |
876 | rule_idx++; | ||
877 | } | ||
878 | } | ||
879 | 920 | ||
880 | if (rule_idx != num_rules) { | 921 | add_rule(&intersected_rule, rd->reg_rules, |
881 | kfree(rd); | 922 | &rd->n_reg_rules); |
882 | return NULL; | 923 | } |
883 | } | 924 | } |
884 | 925 | ||
885 | rd->n_reg_rules = num_rules; | ||
886 | rd->alpha2[0] = '9'; | 926 | rd->alpha2[0] = '9'; |
887 | rd->alpha2[1] = '8'; | 927 | rd->alpha2[1] = '8'; |
888 | rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region, | 928 | rd->dfs_region = reg_intersect_dfs_region(rd1->dfs_region, |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 620a4b40d466..bda39f149810 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * cfg80211 scan result handling | 2 | * cfg80211 scan result handling |
3 | * | 3 | * |
4 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2008 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
7 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 8bbeeb302216..dc1668ff543b 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -641,7 +641,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | |||
641 | } | 641 | } |
642 | 642 | ||
643 | if (status != WLAN_STATUS_SUCCESS) { | 643 | if (status != WLAN_STATUS_SUCCESS) { |
644 | kfree(wdev->connect_keys); | 644 | kzfree(wdev->connect_keys); |
645 | wdev->connect_keys = NULL; | 645 | wdev->connect_keys = NULL; |
646 | wdev->ssid_len = 0; | 646 | wdev->ssid_len = 0; |
647 | if (bss) { | 647 | if (bss) { |
@@ -918,7 +918,7 @@ int cfg80211_connect(struct cfg80211_registered_device *rdev, | |||
918 | ASSERT_WDEV_LOCK(wdev); | 918 | ASSERT_WDEV_LOCK(wdev); |
919 | 919 | ||
920 | if (WARN_ON(wdev->connect_keys)) { | 920 | if (WARN_ON(wdev->connect_keys)) { |
921 | kfree(wdev->connect_keys); | 921 | kzfree(wdev->connect_keys); |
922 | wdev->connect_keys = NULL; | 922 | wdev->connect_keys = NULL; |
923 | } | 923 | } |
924 | 924 | ||
@@ -978,7 +978,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev, | |||
978 | 978 | ||
979 | ASSERT_WDEV_LOCK(wdev); | 979 | ASSERT_WDEV_LOCK(wdev); |
980 | 980 | ||
981 | kfree(wdev->connect_keys); | 981 | kzfree(wdev->connect_keys); |
982 | wdev->connect_keys = NULL; | 982 | wdev->connect_keys = NULL; |
983 | 983 | ||
984 | if (wdev->conn) | 984 | if (wdev->conn) |
diff --git a/net/wireless/trace.h b/net/wireless/trace.h index 0c524cd76c83..625a6e6d1168 100644 --- a/net/wireless/trace.h +++ b/net/wireless/trace.h | |||
@@ -1896,6 +1896,51 @@ TRACE_EVENT(rdev_set_ap_chanwidth, | |||
1896 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) | 1896 | WIPHY_PR_ARG, NETDEV_PR_ARG, CHAN_DEF_PR_ARG) |
1897 | ); | 1897 | ); |
1898 | 1898 | ||
1899 | TRACE_EVENT(rdev_add_tx_ts, | ||
1900 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1901 | u8 tsid, const u8 *peer, u8 user_prio, u16 admitted_time), | ||
1902 | TP_ARGS(wiphy, netdev, tsid, peer, user_prio, admitted_time), | ||
1903 | TP_STRUCT__entry( | ||
1904 | WIPHY_ENTRY | ||
1905 | NETDEV_ENTRY | ||
1906 | MAC_ENTRY(peer) | ||
1907 | __field(u8, tsid) | ||
1908 | __field(u8, user_prio) | ||
1909 | __field(u16, admitted_time) | ||
1910 | ), | ||
1911 | TP_fast_assign( | ||
1912 | WIPHY_ASSIGN; | ||
1913 | NETDEV_ASSIGN; | ||
1914 | MAC_ASSIGN(peer, peer); | ||
1915 | __entry->tsid = tsid; | ||
1916 | __entry->user_prio = user_prio; | ||
1917 | __entry->admitted_time = admitted_time; | ||
1918 | ), | ||
1919 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", TSID %d, UP %d, time %d", | ||
1920 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), | ||
1921 | __entry->tsid, __entry->user_prio, __entry->admitted_time) | ||
1922 | ); | ||
1923 | |||
1924 | TRACE_EVENT(rdev_del_tx_ts, | ||
1925 | TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, | ||
1926 | u8 tsid, const u8 *peer), | ||
1927 | TP_ARGS(wiphy, netdev, tsid, peer), | ||
1928 | TP_STRUCT__entry( | ||
1929 | WIPHY_ENTRY | ||
1930 | NETDEV_ENTRY | ||
1931 | MAC_ENTRY(peer) | ||
1932 | __field(u8, tsid) | ||
1933 | ), | ||
1934 | TP_fast_assign( | ||
1935 | WIPHY_ASSIGN; | ||
1936 | NETDEV_ASSIGN; | ||
1937 | MAC_ASSIGN(peer, peer); | ||
1938 | __entry->tsid = tsid; | ||
1939 | ), | ||
1940 | TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", TSID %d", | ||
1941 | WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer), __entry->tsid) | ||
1942 | ); | ||
1943 | |||
1899 | /************************************************************* | 1944 | /************************************************************* |
1900 | * cfg80211 exported functions traces * | 1945 | * cfg80211 exported functions traces * |
1901 | *************************************************************/ | 1946 | *************************************************************/ |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 728f1c0dc70d..5e233a577d0f 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Wireless utility functions | 2 | * Wireless utility functions |
3 | * | 3 | * |
4 | * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2007-2009 Johannes Berg <johannes@sipsolutions.net> |
5 | * Copyright 2013-2014 Intel Mobile Communications GmbH | ||
5 | */ | 6 | */ |
6 | #include <linux/export.h> | 7 | #include <linux/export.h> |
7 | #include <linux/bitops.h> | 8 | #include <linux/bitops.h> |
@@ -796,7 +797,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
796 | netdev_err(dev, "failed to set mgtdef %d\n", i); | 797 | netdev_err(dev, "failed to set mgtdef %d\n", i); |
797 | } | 798 | } |
798 | 799 | ||
799 | kfree(wdev->connect_keys); | 800 | kzfree(wdev->connect_keys); |
800 | wdev->connect_keys = NULL; | 801 | wdev->connect_keys = NULL; |
801 | } | 802 | } |
802 | 803 | ||
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 11120bb14162..0f47948c572f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -496,6 +496,8 @@ static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev, | |||
496 | err = 0; | 496 | err = 0; |
497 | if (!err) { | 497 | if (!err) { |
498 | if (!addr) { | 498 | if (!addr) { |
499 | memset(wdev->wext.keys->data[idx], 0, | ||
500 | sizeof(wdev->wext.keys->data[idx])); | ||
499 | wdev->wext.keys->params[idx].key_len = 0; | 501 | wdev->wext.keys->params[idx].key_len = 0; |
500 | wdev->wext.keys->params[idx].cipher = 0; | 502 | wdev->wext.keys->params[idx].cipher = 0; |
501 | } | 503 | } |
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c index c7e5c8eb4f24..368611c05739 100644 --- a/net/wireless/wext-sme.c +++ b/net/wireless/wext-sme.c | |||
@@ -57,7 +57,7 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | |||
57 | err = cfg80211_connect(rdev, wdev->netdev, | 57 | err = cfg80211_connect(rdev, wdev->netdev, |
58 | &wdev->wext.connect, ck, prev_bssid); | 58 | &wdev->wext.connect, ck, prev_bssid); |
59 | if (err) | 59 | if (err) |
60 | kfree(ck); | 60 | kzfree(ck); |
61 | 61 | ||
62 | return err; | 62 | return err; |
63 | } | 63 | } |