diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211')
37 files changed, 2745 insertions, 3938 deletions
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig index c9d811eb6556..1d92d874ebb6 100644 --- a/drivers/net/wireless/brcm80211/Kconfig +++ b/drivers/net/wireless/brcm80211/Kconfig | |||
@@ -55,13 +55,16 @@ config BRCMFMAC_USB | |||
55 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to | 55 | IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to |
56 | use the driver for an USB wireless card. | 56 | use the driver for an USB wireless card. |
57 | 57 | ||
58 | config BRCMISCAN | 58 | config BRCM_TRACING |
59 | bool "Broadcom I-Scan (OBSOLETE)" | 59 | bool "Broadcom device tracing" |
60 | depends on BRCMFMAC | 60 | depends on BRCMSMAC || BRCMFMAC |
61 | ---help--- | 61 | ---help--- |
62 | This option enables the I-Scan method. By default fullmac uses the | 62 | If you say Y here, the Broadcom wireless drivers will register |
63 | new E-Scan method which uses less memory in firmware and gives no | 63 | with ftrace to dump event information into the trace ringbuffer. |
64 | limitation on the number of scan results. | 64 | Tracing can be enabled at runtime to aid in debugging wireless |
65 | issues. This option adds a small amount of overhead when tracing | ||
66 | is disabled. If unsure, say Y to allow developers to better help | ||
67 | you when wireless problems occur. | ||
65 | 68 | ||
66 | config BRCMDBG | 69 | config BRCMDBG |
67 | bool "Broadcom driver debug functions" | 70 | bool "Broadcom driver debug functions" |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/Makefile b/drivers/net/wireless/brcm80211/brcmfmac/Makefile index fe80b637c519..1a6661a9f008 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmfmac/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_BRCMFMAC) += brcmfmac.o | |||
25 | brcmfmac-objs += \ | 25 | brcmfmac-objs += \ |
26 | wl_cfg80211.o \ | 26 | wl_cfg80211.o \ |
27 | fwil.o \ | 27 | fwil.o \ |
28 | fweh.o \ | ||
28 | dhd_cdc.o \ | 29 | dhd_cdc.o \ |
29 | dhd_common.o \ | 30 | dhd_common.o \ |
30 | dhd_linux.o | 31 | dhd_linux.o |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 3b2c4c20e7fc..334ddab4a8c5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | |||
@@ -42,7 +42,8 @@ | |||
42 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 42 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB |
43 | static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) | 43 | static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) |
44 | { | 44 | { |
45 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(dev_id); | 45 | struct brcmf_bus *bus_if = dev_get_drvdata(dev_id); |
46 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | ||
46 | 47 | ||
47 | brcmf_dbg(INTR, "oob intr triggered\n"); | 48 | brcmf_dbg(INTR, "oob intr triggered\n"); |
48 | 49 | ||
@@ -71,7 +72,7 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
71 | brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); | 72 | brcmf_dbg(ERROR, "requesting irq %d\n", sdiodev->irq); |
72 | ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, | 73 | ret = request_irq(sdiodev->irq, brcmf_sdio_irqhandler, |
73 | sdiodev->irq_flags, "brcmf_oob_intr", | 74 | sdiodev->irq_flags, "brcmf_oob_intr", |
74 | &sdiodev->func[1]->card->dev); | 75 | &sdiodev->func[1]->dev); |
75 | if (ret != 0) | 76 | if (ret != 0) |
76 | return ret; | 77 | return ret; |
77 | spin_lock_init(&sdiodev->irq_en_lock); | 78 | spin_lock_init(&sdiodev->irq_en_lock); |
@@ -84,6 +85,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
84 | return ret; | 85 | return ret; |
85 | sdiodev->irq_wake = true; | 86 | sdiodev->irq_wake = true; |
86 | 87 | ||
88 | sdio_claim_host(sdiodev->func[1]); | ||
89 | |||
87 | /* must configure SDIO_CCCR_IENx to enable irq */ | 90 | /* must configure SDIO_CCCR_IENx to enable irq */ |
88 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); | 91 | data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret); |
89 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; | 92 | data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1; |
@@ -95,6 +98,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev) | |||
95 | data |= SDIO_SEPINT_ACT_HI; | 98 | data |= SDIO_SEPINT_ACT_HI; |
96 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); | 99 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); |
97 | 100 | ||
101 | sdio_release_host(sdiodev->func[1]); | ||
102 | |||
98 | return 0; | 103 | return 0; |
99 | } | 104 | } |
100 | 105 | ||
@@ -102,14 +107,16 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
102 | { | 107 | { |
103 | brcmf_dbg(TRACE, "Entering\n"); | 108 | brcmf_dbg(TRACE, "Entering\n"); |
104 | 109 | ||
110 | sdio_claim_host(sdiodev->func[1]); | ||
105 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); | 111 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); |
106 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); | 112 | brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); |
113 | sdio_release_host(sdiodev->func[1]); | ||
107 | 114 | ||
108 | if (sdiodev->irq_wake) { | 115 | if (sdiodev->irq_wake) { |
109 | disable_irq_wake(sdiodev->irq); | 116 | disable_irq_wake(sdiodev->irq); |
110 | sdiodev->irq_wake = false; | 117 | sdiodev->irq_wake = false; |
111 | } | 118 | } |
112 | free_irq(sdiodev->irq, &sdiodev->func[1]->card->dev); | 119 | free_irq(sdiodev->irq, &sdiodev->func[1]->dev); |
113 | sdiodev->irq_en = false; | 120 | sdiodev->irq_en = false; |
114 | 121 | ||
115 | return 0; | 122 | return 0; |
@@ -117,7 +124,8 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev) | |||
117 | #else /* CONFIG_BRCMFMAC_SDIO_OOB */ | 124 | #else /* CONFIG_BRCMFMAC_SDIO_OOB */ |
118 | static void brcmf_sdio_irqhandler(struct sdio_func *func) | 125 | static void brcmf_sdio_irqhandler(struct sdio_func *func) |
119 | { | 126 | { |
120 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 127 | struct brcmf_bus *bus_if = dev_get_drvdata(&func->dev); |
128 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | ||
121 | 129 | ||
122 | brcmf_dbg(INTR, "ib intr triggered\n"); | 130 | brcmf_dbg(INTR, "ib intr triggered\n"); |
123 | 131 | ||
@@ -249,9 +257,7 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | |||
249 | int retval; | 257 | int retval; |
250 | 258 | ||
251 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); | 259 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); |
252 | sdio_claim_host(sdiodev->func[1]); | ||
253 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); | 260 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); |
254 | sdio_release_host(sdiodev->func[1]); | ||
255 | brcmf_dbg(INFO, "data:0x%02x\n", data); | 261 | brcmf_dbg(INFO, "data:0x%02x\n", data); |
256 | 262 | ||
257 | if (ret) | 263 | if (ret) |
@@ -266,9 +272,7 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) | |||
266 | int retval; | 272 | int retval; |
267 | 273 | ||
268 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); | 274 | brcmf_dbg(INFO, "addr:0x%08x\n", addr); |
269 | sdio_claim_host(sdiodev->func[1]); | ||
270 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); | 275 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); |
271 | sdio_release_host(sdiodev->func[1]); | ||
272 | brcmf_dbg(INFO, "data:0x%08x\n", data); | 276 | brcmf_dbg(INFO, "data:0x%08x\n", data); |
273 | 277 | ||
274 | if (ret) | 278 | if (ret) |
@@ -283,9 +287,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
283 | int retval; | 287 | int retval; |
284 | 288 | ||
285 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); | 289 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); |
286 | sdio_claim_host(sdiodev->func[1]); | ||
287 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); | 290 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); |
288 | sdio_release_host(sdiodev->func[1]); | ||
289 | 291 | ||
290 | if (ret) | 292 | if (ret) |
291 | *ret = retval; | 293 | *ret = retval; |
@@ -297,9 +299,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, | |||
297 | int retval; | 299 | int retval; |
298 | 300 | ||
299 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); | 301 | brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); |
300 | sdio_claim_host(sdiodev->func[1]); | ||
301 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); | 302 | retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); |
302 | sdio_release_host(sdiodev->func[1]); | ||
303 | 303 | ||
304 | if (ret) | 304 | if (ret) |
305 | *ret = retval; | 305 | *ret = retval; |
@@ -364,8 +364,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
364 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", | 364 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", |
365 | fn, addr, pkt->len); | 365 | fn, addr, pkt->len); |
366 | 366 | ||
367 | sdio_claim_host(sdiodev->func[1]); | ||
368 | |||
369 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 367 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
370 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 368 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); |
371 | if (err) | 369 | if (err) |
@@ -376,8 +374,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
376 | fn, addr, pkt); | 374 | fn, addr, pkt); |
377 | 375 | ||
378 | done: | 376 | done: |
379 | sdio_release_host(sdiodev->func[1]); | ||
380 | |||
381 | return err; | 377 | return err; |
382 | } | 378 | } |
383 | 379 | ||
@@ -391,8 +387,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
391 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", | 387 | brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", |
392 | fn, addr, pktq->qlen); | 388 | fn, addr, pktq->qlen); |
393 | 389 | ||
394 | sdio_claim_host(sdiodev->func[1]); | ||
395 | |||
396 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; | 390 | width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; |
397 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); | 391 | err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); |
398 | if (err) | 392 | if (err) |
@@ -403,8 +397,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
403 | pktq); | 397 | pktq); |
404 | 398 | ||
405 | done: | 399 | done: |
406 | sdio_release_host(sdiodev->func[1]); | ||
407 | |||
408 | return err; | 400 | return err; |
409 | } | 401 | } |
410 | 402 | ||
@@ -446,8 +438,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
446 | if (flags & SDIO_REQ_ASYNC) | 438 | if (flags & SDIO_REQ_ASYNC) |
447 | return -ENOTSUPP; | 439 | return -ENOTSUPP; |
448 | 440 | ||
449 | sdio_claim_host(sdiodev->func[1]); | ||
450 | |||
451 | if (bar0 != sdiodev->sbwad) { | 441 | if (bar0 != sdiodev->sbwad) { |
452 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); | 442 | err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); |
453 | if (err) | 443 | if (err) |
@@ -467,8 +457,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, | |||
467 | addr, pkt); | 457 | addr, pkt); |
468 | 458 | ||
469 | done: | 459 | done: |
470 | sdio_release_host(sdiodev->func[1]); | ||
471 | |||
472 | return err; | 460 | return err; |
473 | } | 461 | } |
474 | 462 | ||
@@ -510,10 +498,8 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) | |||
510 | brcmf_dbg(TRACE, "Enter\n"); | 498 | brcmf_dbg(TRACE, "Enter\n"); |
511 | 499 | ||
512 | /* issue abort cmd52 command through F0 */ | 500 | /* issue abort cmd52 command through F0 */ |
513 | sdio_claim_host(sdiodev->func[1]); | ||
514 | brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, | 501 | brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, |
515 | SDIO_CCCR_ABORT, &t_func); | 502 | SDIO_CCCR_ABORT, &t_func); |
516 | sdio_release_host(sdiodev->func[1]); | ||
517 | 503 | ||
518 | brcmf_dbg(TRACE, "Exit\n"); | 504 | brcmf_dbg(TRACE, "Exit\n"); |
519 | return 0; | 505 | return 0; |
@@ -530,9 +516,6 @@ int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) | |||
530 | 516 | ||
531 | regs = SI_ENUM_BASE; | 517 | regs = SI_ENUM_BASE; |
532 | 518 | ||
533 | /* Report the BAR, to fix if needed */ | ||
534 | sdiodev->sbwad = SI_ENUM_BASE; | ||
535 | |||
536 | /* try to attach to the target device */ | 519 | /* try to attach to the target device */ |
537 | sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); | 520 | sdiodev->bus = brcmf_sdbrcm_probe(regs, sdiodev); |
538 | if (!sdiodev->bus) { | 521 | if (!sdiodev->bus) { |
@@ -551,6 +534,8 @@ EXPORT_SYMBOL(brcmf_sdio_probe); | |||
551 | 534 | ||
552 | int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) | 535 | int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) |
553 | { | 536 | { |
537 | sdiodev->bus_if->state = BRCMF_BUS_DOWN; | ||
538 | |||
554 | if (sdiodev->bus) { | 539 | if (sdiodev->bus) { |
555 | brcmf_sdbrcm_disconnect(sdiodev->bus); | 540 | brcmf_sdbrcm_disconnect(sdiodev->bus); |
556 | sdiodev->bus = NULL; | 541 | sdiodev->bus = NULL; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index c3247d5b3c22..a80050223710 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | |||
@@ -372,9 +372,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) | |||
372 | } | 372 | } |
373 | 373 | ||
374 | /* Enable Function 1 */ | 374 | /* Enable Function 1 */ |
375 | sdio_claim_host(sdiodev->func[1]); | ||
376 | err_ret = sdio_enable_func(sdiodev->func[1]); | 375 | err_ret = sdio_enable_func(sdiodev->func[1]); |
377 | sdio_release_host(sdiodev->func[1]); | ||
378 | if (err_ret) | 376 | if (err_ret) |
379 | brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); | 377 | brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); |
380 | 378 | ||
@@ -393,16 +391,14 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) | |||
393 | sdiodev->num_funcs = 2; | 391 | sdiodev->num_funcs = 2; |
394 | 392 | ||
395 | sdio_claim_host(sdiodev->func[1]); | 393 | sdio_claim_host(sdiodev->func[1]); |
394 | |||
396 | err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); | 395 | err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE); |
397 | sdio_release_host(sdiodev->func[1]); | ||
398 | if (err_ret) { | 396 | if (err_ret) { |
399 | brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); | 397 | brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); |
400 | goto out; | 398 | goto out; |
401 | } | 399 | } |
402 | 400 | ||
403 | sdio_claim_host(sdiodev->func[2]); | ||
404 | err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); | 401 | err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE); |
405 | sdio_release_host(sdiodev->func[2]); | ||
406 | if (err_ret) { | 402 | if (err_ret) { |
407 | brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); | 403 | brcmf_dbg(ERROR, "Failed to set F2 blocksize\n"); |
408 | goto out; | 404 | goto out; |
@@ -411,6 +407,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) | |||
411 | brcmf_sdioh_enablefuncs(sdiodev); | 407 | brcmf_sdioh_enablefuncs(sdiodev); |
412 | 408 | ||
413 | out: | 409 | out: |
410 | sdio_release_host(sdiodev->func[1]); | ||
414 | brcmf_dbg(TRACE, "Done\n"); | 411 | brcmf_dbg(TRACE, "Done\n"); |
415 | return err_ret; | 412 | return err_ret; |
416 | } | 413 | } |
@@ -459,95 +456,106 @@ static inline int brcmf_sdio_getintrcfg(struct brcmf_sdio_dev *sdiodev) | |||
459 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ | 456 | #endif /* CONFIG_BRCMFMAC_SDIO_OOB */ |
460 | 457 | ||
461 | static int brcmf_ops_sdio_probe(struct sdio_func *func, | 458 | static int brcmf_ops_sdio_probe(struct sdio_func *func, |
462 | const struct sdio_device_id *id) | 459 | const struct sdio_device_id *id) |
463 | { | 460 | { |
464 | int ret = 0; | 461 | int err; |
465 | struct brcmf_sdio_dev *sdiodev; | 462 | struct brcmf_sdio_dev *sdiodev; |
466 | struct brcmf_bus *bus_if; | 463 | struct brcmf_bus *bus_if; |
467 | 464 | ||
468 | brcmf_dbg(TRACE, "Enter\n"); | 465 | brcmf_dbg(TRACE, "Enter\n"); |
469 | brcmf_dbg(TRACE, "func->class=%x\n", func->class); | 466 | brcmf_dbg(TRACE, "Class=%x\n", func->class); |
470 | brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); | 467 | brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); |
471 | brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); | 468 | brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); |
472 | brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); | 469 | brcmf_dbg(TRACE, "Function#: %d\n", func->num); |
473 | 470 | ||
474 | if (func->num == 1) { | 471 | /* Consume func num 1 but dont do anything with it. */ |
475 | if (dev_get_drvdata(&func->card->dev)) { | 472 | if (func->num == 1) |
476 | brcmf_dbg(ERROR, "card private drvdata occupied\n"); | 473 | return 0; |
477 | return -ENXIO; | 474 | |
478 | } | 475 | /* Ignore anything but func 2 */ |
479 | bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); | 476 | if (func->num != 2) |
480 | if (!bus_if) | 477 | return -ENODEV; |
481 | return -ENOMEM; | 478 | |
482 | sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); | 479 | bus_if = kzalloc(sizeof(struct brcmf_bus), GFP_KERNEL); |
483 | if (!sdiodev) { | 480 | if (!bus_if) |
484 | kfree(bus_if); | 481 | return -ENOMEM; |
485 | return -ENOMEM; | 482 | sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); |
486 | } | 483 | if (!sdiodev) { |
487 | sdiodev->func[0] = func; | 484 | kfree(bus_if); |
488 | sdiodev->func[1] = func; | 485 | return -ENOMEM; |
489 | sdiodev->bus_if = bus_if; | ||
490 | bus_if->bus_priv.sdio = sdiodev; | ||
491 | bus_if->type = SDIO_BUS; | ||
492 | bus_if->align = BRCMF_SDALIGN; | ||
493 | dev_set_drvdata(&func->card->dev, sdiodev); | ||
494 | |||
495 | atomic_set(&sdiodev->suspend, false); | ||
496 | init_waitqueue_head(&sdiodev->request_byte_wait); | ||
497 | init_waitqueue_head(&sdiodev->request_word_wait); | ||
498 | init_waitqueue_head(&sdiodev->request_chain_wait); | ||
499 | init_waitqueue_head(&sdiodev->request_buffer_wait); | ||
500 | } | 486 | } |
501 | 487 | ||
502 | if (func->num == 2) { | 488 | sdiodev->func[0] = func->card->sdio_func[0]; |
503 | sdiodev = dev_get_drvdata(&func->card->dev); | 489 | sdiodev->func[1] = func->card->sdio_func[0]; |
504 | if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) | 490 | sdiodev->func[2] = func; |
505 | return -ENODEV; | ||
506 | |||
507 | ret = brcmf_sdio_getintrcfg(sdiodev); | ||
508 | if (ret) | ||
509 | return ret; | ||
510 | sdiodev->func[2] = func; | ||
511 | 491 | ||
512 | bus_if = sdiodev->bus_if; | 492 | sdiodev->bus_if = bus_if; |
513 | sdiodev->dev = &func->dev; | 493 | bus_if->bus_priv.sdio = sdiodev; |
514 | dev_set_drvdata(&func->dev, bus_if); | 494 | bus_if->align = BRCMF_SDALIGN; |
495 | dev_set_drvdata(&func->dev, bus_if); | ||
496 | dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); | ||
497 | sdiodev->dev = &sdiodev->func[1]->dev; | ||
515 | 498 | ||
516 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); | 499 | atomic_set(&sdiodev->suspend, false); |
517 | ret = brcmf_sdio_probe(sdiodev); | 500 | init_waitqueue_head(&sdiodev->request_byte_wait); |
501 | init_waitqueue_head(&sdiodev->request_word_wait); | ||
502 | init_waitqueue_head(&sdiodev->request_chain_wait); | ||
503 | init_waitqueue_head(&sdiodev->request_buffer_wait); | ||
504 | err = brcmf_sdio_getintrcfg(sdiodev); | ||
505 | if (err) | ||
506 | goto fail; | ||
507 | |||
508 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); | ||
509 | err = brcmf_sdio_probe(sdiodev); | ||
510 | if (err) { | ||
511 | brcmf_dbg(ERROR, "F2 error, probe failed %d...\n", err); | ||
512 | goto fail; | ||
518 | } | 513 | } |
514 | brcmf_dbg(TRACE, "F2 init completed...\n"); | ||
515 | return 0; | ||
519 | 516 | ||
520 | return ret; | 517 | fail: |
518 | dev_set_drvdata(&func->dev, NULL); | ||
519 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); | ||
520 | kfree(sdiodev); | ||
521 | kfree(bus_if); | ||
522 | return err; | ||
521 | } | 523 | } |
522 | 524 | ||
523 | static void brcmf_ops_sdio_remove(struct sdio_func *func) | 525 | static void brcmf_ops_sdio_remove(struct sdio_func *func) |
524 | { | 526 | { |
525 | struct brcmf_bus *bus_if; | 527 | struct brcmf_bus *bus_if; |
526 | struct brcmf_sdio_dev *sdiodev; | 528 | struct brcmf_sdio_dev *sdiodev; |
529 | |||
527 | brcmf_dbg(TRACE, "Enter\n"); | 530 | brcmf_dbg(TRACE, "Enter\n"); |
528 | brcmf_dbg(INFO, "func->class=%x\n", func->class); | 531 | brcmf_dbg(TRACE, "sdio vendor ID: 0x%04x\n", func->vendor); |
529 | brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); | 532 | brcmf_dbg(TRACE, "sdio device ID: 0x%04x\n", func->device); |
530 | brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); | 533 | brcmf_dbg(TRACE, "Function: %d\n", func->num); |
531 | brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num); | ||
532 | 534 | ||
533 | if (func->num == 2) { | 535 | if (func->num != 1 && func->num != 2) |
534 | bus_if = dev_get_drvdata(&func->dev); | 536 | return; |
537 | |||
538 | bus_if = dev_get_drvdata(&func->dev); | ||
539 | if (bus_if) { | ||
535 | sdiodev = bus_if->bus_priv.sdio; | 540 | sdiodev = bus_if->bus_priv.sdio; |
536 | brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); | ||
537 | brcmf_sdio_remove(sdiodev); | 541 | brcmf_sdio_remove(sdiodev); |
538 | dev_set_drvdata(&func->card->dev, NULL); | 542 | |
539 | dev_set_drvdata(&func->dev, NULL); | 543 | dev_set_drvdata(&sdiodev->func[1]->dev, NULL); |
544 | dev_set_drvdata(&sdiodev->func[2]->dev, NULL); | ||
545 | |||
540 | kfree(bus_if); | 546 | kfree(bus_if); |
541 | kfree(sdiodev); | 547 | kfree(sdiodev); |
542 | } | 548 | } |
549 | |||
550 | brcmf_dbg(TRACE, "Exit\n"); | ||
543 | } | 551 | } |
544 | 552 | ||
545 | #ifdef CONFIG_PM_SLEEP | 553 | #ifdef CONFIG_PM_SLEEP |
546 | static int brcmf_sdio_suspend(struct device *dev) | 554 | static int brcmf_sdio_suspend(struct device *dev) |
547 | { | 555 | { |
548 | mmc_pm_flag_t sdio_flags; | 556 | mmc_pm_flag_t sdio_flags; |
549 | struct sdio_func *func = dev_to_sdio_func(dev); | 557 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
550 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 558 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
551 | int ret = 0; | 559 | int ret = 0; |
552 | 560 | ||
553 | brcmf_dbg(TRACE, "\n"); | 561 | brcmf_dbg(TRACE, "\n"); |
@@ -573,8 +581,8 @@ static int brcmf_sdio_suspend(struct device *dev) | |||
573 | 581 | ||
574 | static int brcmf_sdio_resume(struct device *dev) | 582 | static int brcmf_sdio_resume(struct device *dev) |
575 | { | 583 | { |
576 | struct sdio_func *func = dev_to_sdio_func(dev); | 584 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
577 | struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); | 585 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
578 | 586 | ||
579 | brcmf_sdio_wdtmr_enable(sdiodev, true); | 587 | brcmf_sdio_wdtmr_enable(sdiodev, true); |
580 | atomic_set(&sdiodev->suspend, false); | 588 | atomic_set(&sdiodev->suspend, false); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index 8704daa2758f..24bc4e3e162b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h | |||
@@ -23,6 +23,8 @@ | |||
23 | 23 | ||
24 | #define BRCMF_VERSION_STR "4.218.248.5" | 24 | #define BRCMF_VERSION_STR "4.218.248.5" |
25 | 25 | ||
26 | #include "fweh.h" | ||
27 | |||
26 | /******************************************************************************* | 28 | /******************************************************************************* |
27 | * IO codes that are interpreted by dongle firmware | 29 | * IO codes that are interpreted by dongle firmware |
28 | ******************************************************************************/ | 30 | ******************************************************************************/ |
@@ -38,8 +40,11 @@ | |||
38 | #define BRCMF_C_GET_SSID 25 | 40 | #define BRCMF_C_GET_SSID 25 |
39 | #define BRCMF_C_SET_SSID 26 | 41 | #define BRCMF_C_SET_SSID 26 |
40 | #define BRCMF_C_GET_CHANNEL 29 | 42 | #define BRCMF_C_GET_CHANNEL 29 |
43 | #define BRCMF_C_SET_CHANNEL 30 | ||
41 | #define BRCMF_C_GET_SRL 31 | 44 | #define BRCMF_C_GET_SRL 31 |
45 | #define BRCMF_C_SET_SRL 32 | ||
42 | #define BRCMF_C_GET_LRL 33 | 46 | #define BRCMF_C_GET_LRL 33 |
47 | #define BRCMF_C_SET_LRL 34 | ||
43 | #define BRCMF_C_GET_RADIO 37 | 48 | #define BRCMF_C_GET_RADIO 37 |
44 | #define BRCMF_C_SET_RADIO 38 | 49 | #define BRCMF_C_SET_RADIO 38 |
45 | #define BRCMF_C_GET_PHYTYPE 39 | 50 | #define BRCMF_C_GET_PHYTYPE 39 |
@@ -58,6 +63,7 @@ | |||
58 | #define BRCMF_C_SET_COUNTRY 84 | 63 | #define BRCMF_C_SET_COUNTRY 84 |
59 | #define BRCMF_C_GET_PM 85 | 64 | #define BRCMF_C_GET_PM 85 |
60 | #define BRCMF_C_SET_PM 86 | 65 | #define BRCMF_C_SET_PM 86 |
66 | #define BRCMF_C_GET_CURR_RATESET 114 | ||
61 | #define BRCMF_C_GET_AP 117 | 67 | #define BRCMF_C_GET_AP 117 |
62 | #define BRCMF_C_SET_AP 118 | 68 | #define BRCMF_C_SET_AP 118 |
63 | #define BRCMF_C_GET_RSSI 127 | 69 | #define BRCMF_C_GET_RSSI 127 |
@@ -65,6 +71,7 @@ | |||
65 | #define BRCMF_C_SET_WSEC 134 | 71 | #define BRCMF_C_SET_WSEC 134 |
66 | #define BRCMF_C_GET_PHY_NOISE 135 | 72 | #define BRCMF_C_GET_PHY_NOISE 135 |
67 | #define BRCMF_C_GET_BSS_INFO 136 | 73 | #define BRCMF_C_GET_BSS_INFO 136 |
74 | #define BRCMF_C_GET_PHYLIST 180 | ||
68 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 | 75 | #define BRCMF_C_SET_SCAN_CHANNEL_TIME 185 |
69 | #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 | 76 | #define BRCMF_C_SET_SCAN_UNASSOC_TIME 187 |
70 | #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 | 77 | #define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201 |
@@ -100,29 +107,8 @@ | |||
100 | #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff | 107 | #define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff |
101 | #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 | 108 | #define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16 |
102 | 109 | ||
103 | #define BRCMF_SCAN_ACTION_START 1 | ||
104 | #define BRCMF_SCAN_ACTION_CONTINUE 2 | ||
105 | #define WL_SCAN_ACTION_ABORT 3 | ||
106 | |||
107 | #define BRCMF_ISCAN_REQ_VERSION 1 | ||
108 | |||
109 | /* brcmf_iscan_results status values */ | ||
110 | #define BRCMF_SCAN_RESULTS_SUCCESS 0 | ||
111 | #define BRCMF_SCAN_RESULTS_PARTIAL 1 | ||
112 | #define BRCMF_SCAN_RESULTS_PENDING 2 | ||
113 | #define BRCMF_SCAN_RESULTS_ABORTED 3 | ||
114 | #define BRCMF_SCAN_RESULTS_NO_MEM 4 | ||
115 | |||
116 | /* Indicates this key is using soft encrypt */ | ||
117 | #define WL_SOFT_KEY (1 << 0) | ||
118 | /* primary (ie tx) key */ | 110 | /* primary (ie tx) key */ |
119 | #define BRCMF_PRIMARY_KEY (1 << 1) | 111 | #define BRCMF_PRIMARY_KEY (1 << 1) |
120 | /* Reserved for backward compat */ | ||
121 | #define WL_KF_RES_4 (1 << 4) | ||
122 | /* Reserved for backward compat */ | ||
123 | #define WL_KF_RES_5 (1 << 5) | ||
124 | /* Indicates a group key for a IBSS PEER */ | ||
125 | #define WL_IBSS_PEER_GROUP_KEY (1 << 6) | ||
126 | 112 | ||
127 | /* For supporting multiple interfaces */ | 113 | /* For supporting multiple interfaces */ |
128 | #define BRCMF_MAX_IFS 16 | 114 | #define BRCMF_MAX_IFS 16 |
@@ -130,10 +116,6 @@ | |||
130 | #define DOT11_BSSTYPE_ANY 2 | 116 | #define DOT11_BSSTYPE_ANY 2 |
131 | #define DOT11_MAX_DEFAULT_KEYS 4 | 117 | #define DOT11_MAX_DEFAULT_KEYS 4 |
132 | 118 | ||
133 | #define BRCMF_EVENT_MSG_LINK 0x01 | ||
134 | #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | ||
135 | #define BRCMF_EVENT_MSG_GROUP 0x04 | ||
136 | |||
137 | #define BRCMF_ESCAN_REQ_VERSION 1 | 119 | #define BRCMF_ESCAN_REQ_VERSION 1 |
138 | 120 | ||
139 | #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 | 121 | #define WLC_BSS_RSSI_ON_CHANNEL 0x0002 |
@@ -141,108 +123,6 @@ | |||
141 | #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ | 123 | #define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */ |
142 | #define BRCMF_STA_ASSOC 0x10 /* Associated */ | 124 | #define BRCMF_STA_ASSOC 0x10 /* Associated */ |
143 | 125 | ||
144 | struct brcmf_event_msg { | ||
145 | __be16 version; | ||
146 | __be16 flags; | ||
147 | __be32 event_type; | ||
148 | __be32 status; | ||
149 | __be32 reason; | ||
150 | __be32 auth_type; | ||
151 | __be32 datalen; | ||
152 | u8 addr[ETH_ALEN]; | ||
153 | char ifname[IFNAMSIZ]; | ||
154 | u8 ifidx; | ||
155 | u8 bsscfgidx; | ||
156 | } __packed; | ||
157 | |||
158 | struct brcm_ethhdr { | ||
159 | u16 subtype; | ||
160 | u16 length; | ||
161 | u8 version; | ||
162 | u8 oui[3]; | ||
163 | u16 usr_subtype; | ||
164 | } __packed; | ||
165 | |||
166 | struct brcmf_event { | ||
167 | struct ethhdr eth; | ||
168 | struct brcm_ethhdr hdr; | ||
169 | struct brcmf_event_msg msg; | ||
170 | } __packed; | ||
171 | |||
172 | /* event codes sent by the dongle to this driver */ | ||
173 | #define BRCMF_E_SET_SSID 0 | ||
174 | #define BRCMF_E_JOIN 1 | ||
175 | #define BRCMF_E_START 2 | ||
176 | #define BRCMF_E_AUTH 3 | ||
177 | #define BRCMF_E_AUTH_IND 4 | ||
178 | #define BRCMF_E_DEAUTH 5 | ||
179 | #define BRCMF_E_DEAUTH_IND 6 | ||
180 | #define BRCMF_E_ASSOC 7 | ||
181 | #define BRCMF_E_ASSOC_IND 8 | ||
182 | #define BRCMF_E_REASSOC 9 | ||
183 | #define BRCMF_E_REASSOC_IND 10 | ||
184 | #define BRCMF_E_DISASSOC 11 | ||
185 | #define BRCMF_E_DISASSOC_IND 12 | ||
186 | #define BRCMF_E_QUIET_START 13 | ||
187 | #define BRCMF_E_QUIET_END 14 | ||
188 | #define BRCMF_E_BEACON_RX 15 | ||
189 | #define BRCMF_E_LINK 16 | ||
190 | #define BRCMF_E_MIC_ERROR 17 | ||
191 | #define BRCMF_E_NDIS_LINK 18 | ||
192 | #define BRCMF_E_ROAM 19 | ||
193 | #define BRCMF_E_TXFAIL 20 | ||
194 | #define BRCMF_E_PMKID_CACHE 21 | ||
195 | #define BRCMF_E_RETROGRADE_TSF 22 | ||
196 | #define BRCMF_E_PRUNE 23 | ||
197 | #define BRCMF_E_AUTOAUTH 24 | ||
198 | #define BRCMF_E_EAPOL_MSG 25 | ||
199 | #define BRCMF_E_SCAN_COMPLETE 26 | ||
200 | #define BRCMF_E_ADDTS_IND 27 | ||
201 | #define BRCMF_E_DELTS_IND 28 | ||
202 | #define BRCMF_E_BCNSENT_IND 29 | ||
203 | #define BRCMF_E_BCNRX_MSG 30 | ||
204 | #define BRCMF_E_BCNLOST_MSG 31 | ||
205 | #define BRCMF_E_ROAM_PREP 32 | ||
206 | #define BRCMF_E_PFN_NET_FOUND 33 | ||
207 | #define BRCMF_E_PFN_NET_LOST 34 | ||
208 | #define BRCMF_E_RESET_COMPLETE 35 | ||
209 | #define BRCMF_E_JOIN_START 36 | ||
210 | #define BRCMF_E_ROAM_START 37 | ||
211 | #define BRCMF_E_ASSOC_START 38 | ||
212 | #define BRCMF_E_IBSS_ASSOC 39 | ||
213 | #define BRCMF_E_RADIO 40 | ||
214 | #define BRCMF_E_PSM_WATCHDOG 41 | ||
215 | #define BRCMF_E_PROBREQ_MSG 44 | ||
216 | #define BRCMF_E_SCAN_CONFIRM_IND 45 | ||
217 | #define BRCMF_E_PSK_SUP 46 | ||
218 | #define BRCMF_E_COUNTRY_CODE_CHANGED 47 | ||
219 | #define BRCMF_E_EXCEEDED_MEDIUM_TIME 48 | ||
220 | #define BRCMF_E_ICV_ERROR 49 | ||
221 | #define BRCMF_E_UNICAST_DECODE_ERROR 50 | ||
222 | #define BRCMF_E_MULTICAST_DECODE_ERROR 51 | ||
223 | #define BRCMF_E_TRACE 52 | ||
224 | #define BRCMF_E_IF 54 | ||
225 | #define BRCMF_E_RSSI 56 | ||
226 | #define BRCMF_E_PFN_SCAN_COMPLETE 57 | ||
227 | #define BRCMF_E_EXTLOG_MSG 58 | ||
228 | #define BRCMF_E_ACTION_FRAME 59 | ||
229 | #define BRCMF_E_ACTION_FRAME_COMPLETE 60 | ||
230 | #define BRCMF_E_PRE_ASSOC_IND 61 | ||
231 | #define BRCMF_E_PRE_REASSOC_IND 62 | ||
232 | #define BRCMF_E_CHANNEL_ADOPTED 63 | ||
233 | #define BRCMF_E_AP_STARTED 64 | ||
234 | #define BRCMF_E_DFS_AP_STOP 65 | ||
235 | #define BRCMF_E_DFS_AP_RESUME 66 | ||
236 | #define BRCMF_E_RESERVED1 67 | ||
237 | #define BRCMF_E_RESERVED2 68 | ||
238 | #define BRCMF_E_ESCAN_RESULT 69 | ||
239 | #define BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE 70 | ||
240 | #define BRCMF_E_DCS_REQUEST 73 | ||
241 | |||
242 | #define BRCMF_E_FIFO_CREDIT_MAP 74 | ||
243 | |||
244 | #define BRCMF_E_LAST 75 | ||
245 | |||
246 | #define BRCMF_E_STATUS_SUCCESS 0 | 126 | #define BRCMF_E_STATUS_SUCCESS 0 |
247 | #define BRCMF_E_STATUS_FAIL 1 | 127 | #define BRCMF_E_STATUS_FAIL 1 |
248 | #define BRCMF_E_STATUS_TIMEOUT 2 | 128 | #define BRCMF_E_STATUS_TIMEOUT 2 |
@@ -403,7 +283,7 @@ struct brcm_rateset_le { | |||
403 | /* # rates in this set */ | 283 | /* # rates in this set */ |
404 | __le32 count; | 284 | __le32 count; |
405 | /* rates in 500kbps units w/hi bit set if basic */ | 285 | /* rates in 500kbps units w/hi bit set if basic */ |
406 | u8 rates[WL_NUMRATES]; | 286 | u8 rates[BRCMF_MAXRATES_IN_SET]; |
407 | }; | 287 | }; |
408 | 288 | ||
409 | struct brcmf_ssid { | 289 | struct brcmf_ssid { |
@@ -452,14 +332,6 @@ struct brcmf_scan_params_le { | |||
452 | __le16 channel_list[1]; /* list of chanspecs */ | 332 | __le16 channel_list[1]; /* list of chanspecs */ |
453 | }; | 333 | }; |
454 | 334 | ||
455 | /* incremental scan struct */ | ||
456 | struct brcmf_iscan_params_le { | ||
457 | __le32 version; | ||
458 | __le16 action; | ||
459 | __le16 scan_duration; | ||
460 | struct brcmf_scan_params_le params_le; | ||
461 | }; | ||
462 | |||
463 | struct brcmf_scan_results { | 335 | struct brcmf_scan_results { |
464 | u32 buflen; | 336 | u32 buflen; |
465 | u32 version; | 337 | u32 version; |
@@ -467,12 +339,6 @@ struct brcmf_scan_results { | |||
467 | struct brcmf_bss_info_le bss_info_le[]; | 339 | struct brcmf_bss_info_le bss_info_le[]; |
468 | }; | 340 | }; |
469 | 341 | ||
470 | struct brcmf_scan_results_le { | ||
471 | __le32 buflen; | ||
472 | __le32 version; | ||
473 | __le32 count; | ||
474 | }; | ||
475 | |||
476 | struct brcmf_escan_params_le { | 342 | struct brcmf_escan_params_le { |
477 | __le32 version; | 343 | __le32 version; |
478 | __le16 action; | 344 | __le16 action; |
@@ -508,23 +374,6 @@ struct brcmf_join_params { | |||
508 | struct brcmf_assoc_params_le params_le; | 374 | struct brcmf_assoc_params_le params_le; |
509 | }; | 375 | }; |
510 | 376 | ||
511 | /* incremental scan results struct */ | ||
512 | struct brcmf_iscan_results { | ||
513 | union { | ||
514 | u32 status; | ||
515 | __le32 status_le; | ||
516 | }; | ||
517 | union { | ||
518 | struct brcmf_scan_results results; | ||
519 | struct brcmf_scan_results_le results_le; | ||
520 | }; | ||
521 | }; | ||
522 | |||
523 | /* size of brcmf_iscan_results not including variable length array */ | ||
524 | #define BRCMF_ISCAN_RESULTS_FIXED_SIZE \ | ||
525 | (sizeof(struct brcmf_scan_results) + \ | ||
526 | offsetof(struct brcmf_iscan_results, results)) | ||
527 | |||
528 | struct brcmf_wsec_key { | 377 | struct brcmf_wsec_key { |
529 | u32 index; /* key index */ | 378 | u32 index; /* key index */ |
530 | u32 len; /* key length */ | 379 | u32 len; /* key length */ |
@@ -661,10 +510,11 @@ struct brcmf_pub { | |||
661 | struct mutex proto_block; | 510 | struct mutex proto_block; |
662 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; | 511 | unsigned char proto_buf[BRCMF_DCMD_MAXLEN]; |
663 | 512 | ||
664 | struct work_struct setmacaddr_work; | ||
665 | struct work_struct multicast_work; | ||
666 | u8 macvalue[ETH_ALEN]; | 513 | u8 macvalue[ETH_ALEN]; |
667 | atomic_t pend_8021x_cnt; | 514 | atomic_t pend_8021x_cnt; |
515 | wait_queue_head_t pend_8021x_wait; | ||
516 | |||
517 | struct brcmf_fweh_info fweh; | ||
668 | #ifdef DEBUG | 518 | #ifdef DEBUG |
669 | struct dentry *dbgfs_dir; | 519 | struct dentry *dbgfs_dir; |
670 | #endif | 520 | #endif |
@@ -701,6 +551,8 @@ struct brcmf_if { | |||
701 | struct brcmf_cfg80211_vif *vif; | 551 | struct brcmf_cfg80211_vif *vif; |
702 | struct net_device *ndev; | 552 | struct net_device *ndev; |
703 | struct net_device_stats stats; | 553 | struct net_device_stats stats; |
554 | struct work_struct setmacaddr_work; | ||
555 | struct work_struct multicast_work; | ||
704 | int idx; | 556 | int idx; |
705 | s32 bssidx; | 557 | s32 bssidx; |
706 | u8 mac_addr[ETH_ALEN]; | 558 | u8 mac_addr[ETH_ALEN]; |
@@ -714,9 +566,6 @@ static inline s32 brcmf_ndev_bssidx(struct net_device *ndev) | |||
714 | 566 | ||
715 | extern const struct bcmevent_name bcmevent_names[]; | 567 | extern const struct bcmevent_name bcmevent_names[]; |
716 | 568 | ||
717 | extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, | ||
718 | char *buf, uint len); | ||
719 | |||
720 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); | 569 | extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); |
721 | 570 | ||
722 | /* Return pointer to interface name */ | 571 | /* Return pointer to interface name */ |
@@ -728,14 +577,9 @@ extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, | |||
728 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, | 577 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, |
729 | void *buf, uint len); | 578 | void *buf, uint len); |
730 | 579 | ||
731 | extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); | ||
732 | extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, | ||
733 | void *pktdata, struct brcmf_event_msg *, | ||
734 | void **data_ptr); | ||
735 | |||
736 | extern int brcmf_net_attach(struct brcmf_if *ifp); | 580 | extern int brcmf_net_attach(struct brcmf_if *ifp); |
737 | extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | 581 | extern struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, |
738 | char *name, u8 *mac_addr); | 582 | s32 bssidx, char *name, u8 *mac_addr); |
739 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); | 583 | extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); |
740 | 584 | ||
741 | #endif /* _BRCMF_H_ */ | 585 | #endif /* _BRCMF_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h index 265580f5b270..b8f248797f62 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h | |||
@@ -45,7 +45,6 @@ struct brcmf_bus_dcmd { | |||
45 | 45 | ||
46 | /* interface structure between common and bus layer */ | 46 | /* interface structure between common and bus layer */ |
47 | struct brcmf_bus { | 47 | struct brcmf_bus { |
48 | u8 type; /* bus type */ | ||
49 | union { | 48 | union { |
50 | struct brcmf_sdio_dev *sdio; | 49 | struct brcmf_sdio_dev *sdio; |
51 | struct brcmf_usbdev *usb; | 50 | struct brcmf_usbdev *usb; |
@@ -85,7 +84,7 @@ extern bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | |||
85 | struct sk_buff *pkt, int prec); | 84 | struct sk_buff *pkt, int prec); |
86 | 85 | ||
87 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ | 86 | /* Receive frame for delivery to OS. Callee disposes of rxp. */ |
88 | extern void brcmf_rx_frame(struct device *dev, int ifidx, | 87 | extern void brcmf_rx_frame(struct device *dev, u8 ifidx, |
89 | struct sk_buff_head *rxlist); | 88 | struct sk_buff_head *rxlist); |
90 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, | 89 | static inline void brcmf_rx_packet(struct device *dev, int ifidx, |
91 | struct sk_buff *pkt) | 90 | struct sk_buff *pkt) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index b9d8a5adfd43..87536d38a4ca 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | |||
@@ -23,8 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/sched.h> | ||
27 | #include <defs.h> | ||
28 | 26 | ||
29 | #include <brcmu_utils.h> | 27 | #include <brcmu_utils.h> |
30 | #include <brcmu_wifi.h> | 28 | #include <brcmu_wifi.h> |
@@ -277,76 +275,6 @@ done: | |||
277 | return ret; | 275 | return ret; |
278 | } | 276 | } |
279 | 277 | ||
280 | int | ||
281 | brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd, | ||
282 | int len) | ||
283 | { | ||
284 | struct brcmf_proto *prot = drvr->prot; | ||
285 | int ret = -1; | ||
286 | |||
287 | if (drvr->bus_if->state == BRCMF_BUS_DOWN) { | ||
288 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | ||
289 | return ret; | ||
290 | } | ||
291 | mutex_lock(&drvr->proto_block); | ||
292 | |||
293 | brcmf_dbg(TRACE, "Enter\n"); | ||
294 | |||
295 | if (len > BRCMF_DCMD_MAXLEN) | ||
296 | goto done; | ||
297 | |||
298 | if (prot->pending == true) { | ||
299 | brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n", | ||
300 | dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd, | ||
301 | (unsigned long)prot->lastcmd); | ||
302 | if (dcmd->cmd == BRCMF_C_SET_VAR || | ||
303 | dcmd->cmd == BRCMF_C_GET_VAR) | ||
304 | brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf); | ||
305 | |||
306 | goto done; | ||
307 | } | ||
308 | |||
309 | prot->pending = true; | ||
310 | prot->lastcmd = dcmd->cmd; | ||
311 | if (dcmd->set) | ||
312 | ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd, | ||
313 | dcmd->buf, len); | ||
314 | else { | ||
315 | ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd, | ||
316 | dcmd->buf, len); | ||
317 | if (ret > 0) | ||
318 | dcmd->used = ret - | ||
319 | sizeof(struct brcmf_proto_cdc_dcmd); | ||
320 | } | ||
321 | |||
322 | if (ret >= 0) | ||
323 | ret = 0; | ||
324 | else { | ||
325 | struct brcmf_proto_cdc_dcmd *msg = &prot->msg; | ||
326 | /* len == needed when set/query fails from dongle */ | ||
327 | dcmd->needed = le32_to_cpu(msg->len); | ||
328 | } | ||
329 | |||
330 | /* Intercept the wme_dp dongle cmd here */ | ||
331 | if (!ret && dcmd->cmd == BRCMF_C_SET_VAR && | ||
332 | !strcmp(dcmd->buf, "wme_dp")) { | ||
333 | int slen; | ||
334 | __le32 val = 0; | ||
335 | |||
336 | slen = strlen("wme_dp") + 1; | ||
337 | if (len >= (int)(slen + sizeof(int))) | ||
338 | memcpy(&val, (char *)dcmd->buf + slen, sizeof(int)); | ||
339 | drvr->wme_dp = (u8) le32_to_cpu(val); | ||
340 | } | ||
341 | |||
342 | prot->pending = false; | ||
343 | |||
344 | done: | ||
345 | mutex_unlock(&drvr->proto_block); | ||
346 | |||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | static bool pkt_sum_needed(struct sk_buff *skb) | 278 | static bool pkt_sum_needed(struct sk_buff *skb) |
351 | { | 279 | { |
352 | return skb->ip_summed == CHECKSUM_PARTIAL; | 280 | return skb->ip_summed == CHECKSUM_PARTIAL; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 866b66995bb0..eee7175f1515 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c | |||
@@ -18,10 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
20 | #include <linux/string.h> | 20 | #include <linux/string.h> |
21 | #include <linux/sched.h> | ||
22 | #include <linux/netdevice.h> | 21 | #include <linux/netdevice.h> |
23 | #include <asm/unaligned.h> | ||
24 | #include <defs.h> | ||
25 | #include <brcmu_wifi.h> | 22 | #include <brcmu_wifi.h> |
26 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
27 | #include "dhd.h" | 24 | #include "dhd.h" |
@@ -30,9 +27,6 @@ | |||
30 | #include "dhd_dbg.h" | 27 | #include "dhd_dbg.h" |
31 | #include "fwil.h" | 28 | #include "fwil.h" |
32 | 29 | ||
33 | #define BRCM_OUI "\x00\x10\x18" | ||
34 | #define DOT11_OUI_LEN 3 | ||
35 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | ||
36 | #define PKTFILTER_BUF_SIZE 128 | 30 | #define PKTFILTER_BUF_SIZE 128 |
37 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ | 31 | #define BRCMF_ARPOL_MODE 0xb /* agent|snoop|peer_autoreply */ |
38 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 | 32 | #define BRCMF_DEFAULT_BCN_TIMEOUT 3 |
@@ -40,12 +34,6 @@ | |||
40 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 | 34 | #define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 |
41 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" | 35 | #define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" |
42 | 36 | ||
43 | #define MSGTRACE_VERSION 1 | ||
44 | |||
45 | #define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u) | ||
46 | #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ | ||
47 | offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) | ||
48 | |||
49 | #ifdef DEBUG | 37 | #ifdef DEBUG |
50 | static const char brcmf_version[] = | 38 | static const char brcmf_version[] = |
51 | "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " | 39 | "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " |
@@ -55,43 +43,6 @@ static const char brcmf_version[] = | |||
55 | "Dongle Host Driver, version " BRCMF_VERSION_STR; | 43 | "Dongle Host Driver, version " BRCMF_VERSION_STR; |
56 | #endif | 44 | #endif |
57 | 45 | ||
58 | /* Message trace header */ | ||
59 | struct msgtrace_hdr { | ||
60 | u8 version; | ||
61 | u8 spare; | ||
62 | __be16 len; /* Len of the trace */ | ||
63 | __be32 seqnum; /* Sequence number of message. Useful | ||
64 | * if the messsage has been lost | ||
65 | * because of DMA error or a bus reset | ||
66 | * (ex: SDIO Func2) | ||
67 | */ | ||
68 | __be32 discarded_bytes; /* Number of discarded bytes because of | ||
69 | trace overflow */ | ||
70 | __be32 discarded_printf; /* Number of discarded printf | ||
71 | because of trace overflow */ | ||
72 | } __packed; | ||
73 | |||
74 | |||
75 | uint | ||
76 | brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) | ||
77 | { | ||
78 | uint len; | ||
79 | |||
80 | len = strlen(name) + 1; | ||
81 | |||
82 | if ((len + datalen) > buflen) | ||
83 | return 0; | ||
84 | |||
85 | strncpy(buf, name, buflen); | ||
86 | |||
87 | /* append data onto the end of the name string */ | ||
88 | if (data && datalen) { | ||
89 | memcpy(&buf[len], data, datalen); | ||
90 | len += datalen; | ||
91 | } | ||
92 | |||
93 | return len; | ||
94 | } | ||
95 | 46 | ||
96 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | 47 | bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, |
97 | struct sk_buff *pkt, int prec) | 48 | struct sk_buff *pkt, int prec) |
@@ -143,405 +94,6 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, | |||
143 | return p != NULL; | 94 | return p != NULL; |
144 | } | 95 | } |
145 | 96 | ||
146 | #ifdef DEBUG | ||
147 | static void | ||
148 | brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) | ||
149 | { | ||
150 | uint i, status, reason; | ||
151 | bool group = false, flush_txq = false, link = false; | ||
152 | char *auth_str, *event_name; | ||
153 | unsigned char *buf; | ||
154 | char err_msg[256], eabuf[ETHER_ADDR_STR_LEN]; | ||
155 | static struct { | ||
156 | uint event; | ||
157 | char *event_name; | ||
158 | } event_names[] = { | ||
159 | { | ||
160 | BRCMF_E_SET_SSID, "SET_SSID"}, { | ||
161 | BRCMF_E_JOIN, "JOIN"}, { | ||
162 | BRCMF_E_START, "START"}, { | ||
163 | BRCMF_E_AUTH, "AUTH"}, { | ||
164 | BRCMF_E_AUTH_IND, "AUTH_IND"}, { | ||
165 | BRCMF_E_DEAUTH, "DEAUTH"}, { | ||
166 | BRCMF_E_DEAUTH_IND, "DEAUTH_IND"}, { | ||
167 | BRCMF_E_ASSOC, "ASSOC"}, { | ||
168 | BRCMF_E_ASSOC_IND, "ASSOC_IND"}, { | ||
169 | BRCMF_E_REASSOC, "REASSOC"}, { | ||
170 | BRCMF_E_REASSOC_IND, "REASSOC_IND"}, { | ||
171 | BRCMF_E_DISASSOC, "DISASSOC"}, { | ||
172 | BRCMF_E_DISASSOC_IND, "DISASSOC_IND"}, { | ||
173 | BRCMF_E_QUIET_START, "START_QUIET"}, { | ||
174 | BRCMF_E_QUIET_END, "END_QUIET"}, { | ||
175 | BRCMF_E_BEACON_RX, "BEACON_RX"}, { | ||
176 | BRCMF_E_LINK, "LINK"}, { | ||
177 | BRCMF_E_MIC_ERROR, "MIC_ERROR"}, { | ||
178 | BRCMF_E_NDIS_LINK, "NDIS_LINK"}, { | ||
179 | BRCMF_E_ROAM, "ROAM"}, { | ||
180 | BRCMF_E_TXFAIL, "TXFAIL"}, { | ||
181 | BRCMF_E_PMKID_CACHE, "PMKID_CACHE"}, { | ||
182 | BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF"}, { | ||
183 | BRCMF_E_PRUNE, "PRUNE"}, { | ||
184 | BRCMF_E_AUTOAUTH, "AUTOAUTH"}, { | ||
185 | BRCMF_E_EAPOL_MSG, "EAPOL_MSG"}, { | ||
186 | BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE"}, { | ||
187 | BRCMF_E_ADDTS_IND, "ADDTS_IND"}, { | ||
188 | BRCMF_E_DELTS_IND, "DELTS_IND"}, { | ||
189 | BRCMF_E_BCNSENT_IND, "BCNSENT_IND"}, { | ||
190 | BRCMF_E_BCNRX_MSG, "BCNRX_MSG"}, { | ||
191 | BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG"}, { | ||
192 | BRCMF_E_ROAM_PREP, "ROAM_PREP"}, { | ||
193 | BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND"}, { | ||
194 | BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST"}, { | ||
195 | BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE"}, { | ||
196 | BRCMF_E_JOIN_START, "JOIN_START"}, { | ||
197 | BRCMF_E_ROAM_START, "ROAM_START"}, { | ||
198 | BRCMF_E_ASSOC_START, "ASSOC_START"}, { | ||
199 | BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC"}, { | ||
200 | BRCMF_E_RADIO, "RADIO"}, { | ||
201 | BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG"}, { | ||
202 | BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG"}, { | ||
203 | BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND"}, { | ||
204 | BRCMF_E_PSK_SUP, "PSK_SUP"}, { | ||
205 | BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED"}, { | ||
206 | BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME"}, { | ||
207 | BRCMF_E_ICV_ERROR, "ICV_ERROR"}, { | ||
208 | BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR"}, { | ||
209 | BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR"}, { | ||
210 | BRCMF_E_TRACE, "TRACE"}, { | ||
211 | BRCMF_E_ACTION_FRAME, "ACTION FRAME"}, { | ||
212 | BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { | ||
213 | BRCMF_E_IF, "IF"}, { | ||
214 | BRCMF_E_RSSI, "RSSI"}, { | ||
215 | BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, { | ||
216 | BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"} | ||
217 | }; | ||
218 | uint event_type, flags, auth_type, datalen; | ||
219 | static u32 seqnum_prev; | ||
220 | struct msgtrace_hdr hdr; | ||
221 | u32 nblost; | ||
222 | char *s, *p; | ||
223 | |||
224 | event_type = be32_to_cpu(event->event_type); | ||
225 | flags = be16_to_cpu(event->flags); | ||
226 | status = be32_to_cpu(event->status); | ||
227 | reason = be32_to_cpu(event->reason); | ||
228 | auth_type = be32_to_cpu(event->auth_type); | ||
229 | datalen = be32_to_cpu(event->datalen); | ||
230 | /* debug dump of event messages */ | ||
231 | sprintf(eabuf, "%pM", event->addr); | ||
232 | |||
233 | event_name = "UNKNOWN"; | ||
234 | for (i = 0; i < ARRAY_SIZE(event_names); i++) { | ||
235 | if (event_names[i].event == event_type) | ||
236 | event_name = event_names[i].event_name; | ||
237 | } | ||
238 | |||
239 | brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type); | ||
240 | brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", | ||
241 | flags, status, reason, auth_type, eabuf); | ||
242 | |||
243 | if (flags & BRCMF_EVENT_MSG_LINK) | ||
244 | link = true; | ||
245 | if (flags & BRCMF_EVENT_MSG_GROUP) | ||
246 | group = true; | ||
247 | if (flags & BRCMF_EVENT_MSG_FLUSHTXQ) | ||
248 | flush_txq = true; | ||
249 | |||
250 | switch (event_type) { | ||
251 | case BRCMF_E_START: | ||
252 | case BRCMF_E_DEAUTH: | ||
253 | case BRCMF_E_DISASSOC: | ||
254 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
255 | break; | ||
256 | |||
257 | case BRCMF_E_ASSOC_IND: | ||
258 | case BRCMF_E_REASSOC_IND: | ||
259 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
260 | break; | ||
261 | |||
262 | case BRCMF_E_ASSOC: | ||
263 | case BRCMF_E_REASSOC: | ||
264 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
265 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n", | ||
266 | event_name, eabuf); | ||
267 | else if (status == BRCMF_E_STATUS_TIMEOUT) | ||
268 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n", | ||
269 | event_name, eabuf); | ||
270 | else if (status == BRCMF_E_STATUS_FAIL) | ||
271 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n", | ||
272 | event_name, eabuf, (int)reason); | ||
273 | else | ||
274 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n", | ||
275 | event_name, eabuf, (int)status); | ||
276 | break; | ||
277 | |||
278 | case BRCMF_E_DEAUTH_IND: | ||
279 | case BRCMF_E_DISASSOC_IND: | ||
280 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n", | ||
281 | event_name, eabuf, (int)reason); | ||
282 | break; | ||
283 | |||
284 | case BRCMF_E_AUTH: | ||
285 | case BRCMF_E_AUTH_IND: | ||
286 | if (auth_type == WLAN_AUTH_OPEN) | ||
287 | auth_str = "Open System"; | ||
288 | else if (auth_type == WLAN_AUTH_SHARED_KEY) | ||
289 | auth_str = "Shared Key"; | ||
290 | else { | ||
291 | sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); | ||
292 | auth_str = err_msg; | ||
293 | } | ||
294 | if (event_type == BRCMF_E_AUTH_IND) | ||
295 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n", | ||
296 | event_name, eabuf, auth_str); | ||
297 | else if (status == BRCMF_E_STATUS_SUCCESS) | ||
298 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n", | ||
299 | event_name, eabuf, auth_str); | ||
300 | else if (status == BRCMF_E_STATUS_TIMEOUT) | ||
301 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n", | ||
302 | event_name, eabuf, auth_str); | ||
303 | else if (status == BRCMF_E_STATUS_FAIL) { | ||
304 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", | ||
305 | event_name, eabuf, auth_str, (int)reason); | ||
306 | } | ||
307 | |||
308 | break; | ||
309 | |||
310 | case BRCMF_E_JOIN: | ||
311 | case BRCMF_E_ROAM: | ||
312 | case BRCMF_E_SET_SSID: | ||
313 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
314 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", | ||
315 | event_name, eabuf); | ||
316 | else if (status == BRCMF_E_STATUS_FAIL) | ||
317 | brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name); | ||
318 | else if (status == BRCMF_E_STATUS_NO_NETWORKS) | ||
319 | brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n", | ||
320 | event_name); | ||
321 | else | ||
322 | brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n", | ||
323 | event_name, (int)status); | ||
324 | break; | ||
325 | |||
326 | case BRCMF_E_BEACON_RX: | ||
327 | if (status == BRCMF_E_STATUS_SUCCESS) | ||
328 | brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name); | ||
329 | else if (status == BRCMF_E_STATUS_FAIL) | ||
330 | brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name); | ||
331 | else | ||
332 | brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n", | ||
333 | event_name, status); | ||
334 | break; | ||
335 | |||
336 | case BRCMF_E_LINK: | ||
337 | brcmf_dbg(EVENT, "MACEVENT: %s %s\n", | ||
338 | event_name, link ? "UP" : "DOWN"); | ||
339 | break; | ||
340 | |||
341 | case BRCMF_E_MIC_ERROR: | ||
342 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n", | ||
343 | event_name, eabuf, group, flush_txq); | ||
344 | break; | ||
345 | |||
346 | case BRCMF_E_ICV_ERROR: | ||
347 | case BRCMF_E_UNICAST_DECODE_ERROR: | ||
348 | case BRCMF_E_MULTICAST_DECODE_ERROR: | ||
349 | brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); | ||
350 | break; | ||
351 | |||
352 | case BRCMF_E_TXFAIL: | ||
353 | brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf); | ||
354 | break; | ||
355 | |||
356 | case BRCMF_E_SCAN_COMPLETE: | ||
357 | case BRCMF_E_PMKID_CACHE: | ||
358 | brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); | ||
359 | break; | ||
360 | |||
361 | case BRCMF_E_ESCAN_RESULT: | ||
362 | brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); | ||
363 | datalen = 0; | ||
364 | break; | ||
365 | |||
366 | case BRCMF_E_PFN_NET_FOUND: | ||
367 | case BRCMF_E_PFN_NET_LOST: | ||
368 | case BRCMF_E_PFN_SCAN_COMPLETE: | ||
369 | brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name); | ||
370 | break; | ||
371 | |||
372 | case BRCMF_E_PSK_SUP: | ||
373 | case BRCMF_E_PRUNE: | ||
374 | brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n", | ||
375 | event_name, (int)status, (int)reason); | ||
376 | break; | ||
377 | |||
378 | case BRCMF_E_TRACE: | ||
379 | buf = (unsigned char *) event_data; | ||
380 | memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); | ||
381 | |||
382 | if (hdr.version != MSGTRACE_VERSION) { | ||
383 | brcmf_dbg(ERROR, | ||
384 | "MACEVENT: %s [unsupported version --> brcmf" | ||
385 | " version:%d dongle version:%d]\n", | ||
386 | event_name, MSGTRACE_VERSION, hdr.version); | ||
387 | /* Reset datalen to avoid display below */ | ||
388 | datalen = 0; | ||
389 | break; | ||
390 | } | ||
391 | |||
392 | /* There are 2 bytes available at the end of data */ | ||
393 | *(buf + sizeof(struct msgtrace_hdr) | ||
394 | + be16_to_cpu(hdr.len)) = '\0'; | ||
395 | |||
396 | if (be32_to_cpu(hdr.discarded_bytes) | ||
397 | || be32_to_cpu(hdr.discarded_printf)) | ||
398 | brcmf_dbg(ERROR, | ||
399 | "WLC_E_TRACE: [Discarded traces in dongle -->" | ||
400 | " discarded_bytes %d discarded_printf %d]\n", | ||
401 | be32_to_cpu(hdr.discarded_bytes), | ||
402 | be32_to_cpu(hdr.discarded_printf)); | ||
403 | |||
404 | nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; | ||
405 | if (nblost > 0) | ||
406 | brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum " | ||
407 | " %d nblost %d\n", be32_to_cpu(hdr.seqnum), | ||
408 | nblost); | ||
409 | seqnum_prev = be32_to_cpu(hdr.seqnum); | ||
410 | |||
411 | /* Display the trace buffer. Advance from \n to \n to | ||
412 | * avoid display big | ||
413 | * printf (issue with Linux printk ) | ||
414 | */ | ||
415 | p = (char *)&buf[sizeof(struct msgtrace_hdr)]; | ||
416 | while ((s = strstr(p, "\n")) != NULL) { | ||
417 | *s = '\0'; | ||
418 | pr_debug("%s\n", p); | ||
419 | p = s + 1; | ||
420 | } | ||
421 | pr_debug("%s\n", p); | ||
422 | |||
423 | /* Reset datalen to avoid display below */ | ||
424 | datalen = 0; | ||
425 | break; | ||
426 | |||
427 | case BRCMF_E_RSSI: | ||
428 | brcmf_dbg(EVENT, "MACEVENT: %s %d\n", | ||
429 | event_name, be32_to_cpu(*((__be32 *)event_data))); | ||
430 | break; | ||
431 | |||
432 | default: | ||
433 | brcmf_dbg(EVENT, | ||
434 | "MACEVENT: %s %d, MAC %s, status %d, reason %d, " | ||
435 | "auth %d\n", event_name, event_type, eabuf, | ||
436 | (int)status, (int)reason, (int)auth_type); | ||
437 | break; | ||
438 | } | ||
439 | |||
440 | /* show any appended data */ | ||
441 | brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data"); | ||
442 | } | ||
443 | #endif /* DEBUG */ | ||
444 | |||
445 | int | ||
446 | brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, | ||
447 | struct brcmf_event_msg *event, void **data_ptr) | ||
448 | { | ||
449 | /* check whether packet is a BRCM event pkt */ | ||
450 | struct brcmf_event *pvt_data = (struct brcmf_event *) pktdata; | ||
451 | struct brcmf_if_event *ifevent; | ||
452 | struct brcmf_if *ifp; | ||
453 | char *event_data; | ||
454 | u32 type, status; | ||
455 | u16 flags; | ||
456 | int evlen; | ||
457 | |||
458 | if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { | ||
459 | brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); | ||
460 | return -EBADE; | ||
461 | } | ||
462 | |||
463 | /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ | ||
464 | if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != | ||
465 | BCMILCP_BCM_SUBTYPE_EVENT) { | ||
466 | brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); | ||
467 | return -EBADE; | ||
468 | } | ||
469 | |||
470 | *data_ptr = &pvt_data[1]; | ||
471 | event_data = *data_ptr; | ||
472 | |||
473 | /* memcpy since BRCM event pkt may be unaligned. */ | ||
474 | memcpy(event, &pvt_data->msg, sizeof(struct brcmf_event_msg)); | ||
475 | |||
476 | type = get_unaligned_be32(&event->event_type); | ||
477 | flags = get_unaligned_be16(&event->flags); | ||
478 | status = get_unaligned_be32(&event->status); | ||
479 | evlen = get_unaligned_be32(&event->datalen) + | ||
480 | sizeof(struct brcmf_event); | ||
481 | |||
482 | switch (type) { | ||
483 | case BRCMF_E_IF: | ||
484 | ifevent = (struct brcmf_if_event *) event_data; | ||
485 | brcmf_dbg(TRACE, "if event\n"); | ||
486 | |||
487 | if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { | ||
488 | if (ifevent->action == BRCMF_E_IF_ADD) { | ||
489 | ifp = brcmf_add_if(drvr->dev, ifevent->ifidx, | ||
490 | ifevent->bssidx, | ||
491 | event->ifname, | ||
492 | pvt_data->eth.h_dest); | ||
493 | if (IS_ERR(ifp)) | ||
494 | return PTR_ERR(ifp); | ||
495 | brcmf_net_attach(ifp); | ||
496 | } else { | ||
497 | brcmf_del_if(drvr, ifevent->ifidx); | ||
498 | } | ||
499 | } else { | ||
500 | brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", | ||
501 | ifevent->ifidx, event->ifname); | ||
502 | } | ||
503 | |||
504 | /* send up the if event: btamp user needs it */ | ||
505 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); | ||
506 | break; | ||
507 | |||
508 | /* These are what external supplicant/authenticator wants */ | ||
509 | case BRCMF_E_LINK: | ||
510 | case BRCMF_E_ASSOC_IND: | ||
511 | case BRCMF_E_REASSOC_IND: | ||
512 | case BRCMF_E_DISASSOC_IND: | ||
513 | case BRCMF_E_MIC_ERROR: | ||
514 | default: | ||
515 | /* Fall through: this should get _everything_ */ | ||
516 | |||
517 | *ifidx = brcmf_ifname2idx(drvr, event->ifname); | ||
518 | brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", | ||
519 | type, flags, status); | ||
520 | |||
521 | /* put it back to BRCMF_E_NDIS_LINK */ | ||
522 | if (type == BRCMF_E_NDIS_LINK) { | ||
523 | u32 temp1; | ||
524 | __be32 temp2; | ||
525 | |||
526 | temp1 = get_unaligned_be32(&event->event_type); | ||
527 | brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", | ||
528 | temp1); | ||
529 | |||
530 | temp2 = cpu_to_be32(BRCMF_E_NDIS_LINK); | ||
531 | memcpy((void *)(&pvt_data->msg.event_type), &temp2, | ||
532 | sizeof(pvt_data->msg.event_type)); | ||
533 | } | ||
534 | break; | ||
535 | } | ||
536 | |||
537 | #ifdef DEBUG | ||
538 | if (BRCMF_EVENT_ON()) | ||
539 | brcmf_c_show_host_event(event, event_data); | ||
540 | #endif /* DEBUG */ | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | /* Convert user's input in hex pattern to byte-size mask */ | 97 | /* Convert user's input in hex pattern to byte-size mask */ |
546 | static int brcmf_c_pattern_atoh(char *src, char *dst) | 98 | static int brcmf_c_pattern_atoh(char *src, char *dst) |
547 | { | 99 | { |
@@ -686,8 +238,8 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg) | |||
686 | } | 238 | } |
687 | 239 | ||
688 | pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); | 240 | pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size); |
689 | buf_len = sizeof(*pkt_filter); | 241 | buf_len = offsetof(struct brcmf_pkt_filter_le, |
690 | buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern); | 242 | u.pattern.mask_and_pattern); |
691 | buf_len += mask_size + pattern_size; | 243 | buf_len += mask_size + pattern_size; |
692 | 244 | ||
693 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, | 245 | err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter, |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c index 862d2acb7a16..7e58e8ce9aba 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c | |||
@@ -14,18 +14,12 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | #include <linux/debugfs.h> | 16 | #include <linux/debugfs.h> |
17 | #include <linux/if_ether.h> | ||
18 | #include <linux/if.h> | ||
19 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
20 | #include <linux/ieee80211.h> | ||
21 | #include <linux/module.h> | 18 | #include <linux/module.h> |
22 | #include <linux/netdevice.h> | ||
23 | 19 | ||
24 | #include <defs.h> | ||
25 | #include <brcmu_wifi.h> | 20 | #include <brcmu_wifi.h> |
26 | #include <brcmu_utils.h> | 21 | #include <brcmu_utils.h> |
27 | #include "dhd.h" | 22 | #include "dhd.h" |
28 | #include "dhd_bus.h" | ||
29 | #include "dhd_dbg.h" | 23 | #include "dhd_dbg.h" |
30 | 24 | ||
31 | static struct dentry *root_folder; | 25 | static struct dentry *root_folder; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index eefa6c2560cc..a0e18a1ceb4b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | |||
@@ -27,11 +27,11 @@ | |||
27 | #define BRCMF_HDRS_VAL 0x0040 | 27 | #define BRCMF_HDRS_VAL 0x0040 |
28 | #define BRCMF_BYTES_VAL 0x0080 | 28 | #define BRCMF_BYTES_VAL 0x0080 |
29 | #define BRCMF_INTR_VAL 0x0100 | 29 | #define BRCMF_INTR_VAL 0x0100 |
30 | #define BRCMF_GLOM_VAL 0x0400 | 30 | #define BRCMF_GLOM_VAL 0x0200 |
31 | #define BRCMF_EVENT_VAL 0x0800 | 31 | #define BRCMF_EVENT_VAL 0x0400 |
32 | #define BRCMF_BTA_VAL 0x1000 | 32 | #define BRCMF_BTA_VAL 0x0800 |
33 | #define BRCMF_ISCAN_VAL 0x2000 | 33 | #define BRCMF_FIL_VAL 0x1000 |
34 | #define BRCMF_FIL_VAL 0x4000 | 34 | #define BRCMF_USB_VAL 0x2000 |
35 | 35 | ||
36 | #if defined(DEBUG) | 36 | #if defined(DEBUG) |
37 | 37 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 297652339fda..b6c86b046c15 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | |||
@@ -16,27 +16,11 @@ | |||
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
18 | 18 | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/kthread.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/etherdevice.h> | 20 | #include <linux/etherdevice.h> |
26 | #include <linux/mmc/sdio_func.h> | ||
27 | #include <linux/random.h> | ||
28 | #include <linux/spinlock.h> | ||
29 | #include <linux/ethtool.h> | ||
30 | #include <linux/fcntl.h> | ||
31 | #include <linux/fs.h> | ||
32 | #include <linux/uaccess.h> | ||
33 | #include <linux/hardirq.h> | ||
34 | #include <linux/mutex.h> | ||
35 | #include <linux/wait.h> | ||
36 | #include <linux/module.h> | 21 | #include <linux/module.h> |
37 | #include <net/cfg80211.h> | 22 | #include <net/cfg80211.h> |
38 | #include <net/rtnetlink.h> | 23 | #include <net/rtnetlink.h> |
39 | #include <defs.h> | ||
40 | #include <brcmu_utils.h> | 24 | #include <brcmu_utils.h> |
41 | #include <brcmu_wifi.h> | 25 | #include <brcmu_wifi.h> |
42 | 26 | ||
@@ -45,35 +29,19 @@ | |||
45 | #include "dhd_proto.h" | 29 | #include "dhd_proto.h" |
46 | #include "dhd_dbg.h" | 30 | #include "dhd_dbg.h" |
47 | #include "wl_cfg80211.h" | 31 | #include "wl_cfg80211.h" |
32 | #include "fwil.h" | ||
48 | 33 | ||
49 | MODULE_AUTHOR("Broadcom Corporation"); | 34 | MODULE_AUTHOR("Broadcom Corporation"); |
50 | MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); | 35 | MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); |
51 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); | 36 | MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards"); |
52 | MODULE_LICENSE("Dual BSD/GPL"); | 37 | MODULE_LICENSE("Dual BSD/GPL"); |
53 | 38 | ||
39 | #define MAX_WAIT_FOR_8021X_TX 50 /* msecs */ | ||
54 | 40 | ||
55 | /* Error bits */ | 41 | /* Error bits */ |
56 | int brcmf_msg_level = BRCMF_ERROR_VAL; | 42 | int brcmf_msg_level = BRCMF_ERROR_VAL; |
57 | module_param(brcmf_msg_level, int, 0); | 43 | module_param(brcmf_msg_level, int, 0); |
58 | 44 | ||
59 | int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name) | ||
60 | { | ||
61 | int i = BRCMF_MAX_IFS; | ||
62 | struct brcmf_if *ifp; | ||
63 | |||
64 | if (name == NULL || *name == '\0') | ||
65 | return 0; | ||
66 | |||
67 | while (--i > 0) { | ||
68 | ifp = drvr->iflist[i]; | ||
69 | if (ifp && !strncmp(ifp->ndev->name, name, IFNAMSIZ)) | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); | ||
74 | |||
75 | return i; /* default - the primary interface */ | ||
76 | } | ||
77 | 45 | ||
78 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | 46 | char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) |
79 | { | 47 | { |
@@ -95,38 +63,33 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) | |||
95 | 63 | ||
96 | static void _brcmf_set_multicast_list(struct work_struct *work) | 64 | static void _brcmf_set_multicast_list(struct work_struct *work) |
97 | { | 65 | { |
66 | struct brcmf_if *ifp; | ||
98 | struct net_device *ndev; | 67 | struct net_device *ndev; |
99 | struct netdev_hw_addr *ha; | 68 | struct netdev_hw_addr *ha; |
100 | u32 dcmd_value, cnt; | 69 | u32 cmd_value, cnt; |
101 | __le32 cnt_le; | 70 | __le32 cnt_le; |
102 | __le32 dcmd_le_value; | ||
103 | |||
104 | struct brcmf_dcmd dcmd; | ||
105 | char *buf, *bufp; | 71 | char *buf, *bufp; |
106 | uint buflen; | 72 | u32 buflen; |
107 | int ret; | 73 | s32 err; |
108 | 74 | ||
109 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, | 75 | brcmf_dbg(TRACE, "enter\n"); |
110 | multicast_work); | ||
111 | 76 | ||
112 | ndev = drvr->iflist[0]->ndev; | 77 | ifp = container_of(work, struct brcmf_if, multicast_work); |
113 | cnt = netdev_mc_count(ndev); | 78 | ndev = ifp->ndev; |
114 | 79 | ||
115 | /* Determine initial value of allmulti flag */ | 80 | /* Determine initial value of allmulti flag */ |
116 | dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; | 81 | cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false; |
117 | 82 | ||
118 | /* Send down the multicast list first. */ | 83 | /* Send down the multicast list first. */ |
119 | 84 | cnt = netdev_mc_count(ndev); | |
120 | buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); | 85 | buflen = sizeof(cnt) + (cnt * ETH_ALEN); |
121 | bufp = buf = kmalloc(buflen, GFP_ATOMIC); | 86 | buf = kmalloc(buflen, GFP_ATOMIC); |
122 | if (!bufp) | 87 | if (!buf) |
123 | return; | 88 | return; |
124 | 89 | bufp = buf; | |
125 | strcpy(bufp, "mcast_list"); | ||
126 | bufp += strlen("mcast_list") + 1; | ||
127 | 90 | ||
128 | cnt_le = cpu_to_le32(cnt); | 91 | cnt_le = cpu_to_le32(cnt); |
129 | memcpy(bufp, &cnt_le, sizeof(cnt)); | 92 | memcpy(bufp, &cnt_le, sizeof(cnt_le)); |
130 | bufp += sizeof(cnt_le); | 93 | bufp += sizeof(cnt_le); |
131 | 94 | ||
132 | netdev_for_each_mc_addr(ha, ndev) { | 95 | netdev_for_each_mc_addr(ha, ndev) { |
@@ -137,129 +100,66 @@ static void _brcmf_set_multicast_list(struct work_struct *work) | |||
137 | cnt--; | 100 | cnt--; |
138 | } | 101 | } |
139 | 102 | ||
140 | memset(&dcmd, 0, sizeof(dcmd)); | 103 | err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); |
141 | dcmd.cmd = BRCMF_C_SET_VAR; | 104 | if (err < 0) { |
142 | dcmd.buf = buf; | 105 | brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err); |
143 | dcmd.len = buflen; | 106 | cmd_value = cnt ? true : cmd_value; |
144 | dcmd.set = true; | ||
145 | |||
146 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
147 | if (ret < 0) { | ||
148 | brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", | ||
149 | brcmf_ifname(drvr, 0), cnt); | ||
150 | dcmd_value = cnt ? true : dcmd_value; | ||
151 | } | 107 | } |
152 | 108 | ||
153 | kfree(buf); | 109 | kfree(buf); |
154 | 110 | ||
155 | /* Now send the allmulti setting. This is based on the setting in the | 111 | /* |
112 | * Now send the allmulti setting. This is based on the setting in the | ||
156 | * net_device flags, but might be modified above to be turned on if we | 113 | * net_device flags, but might be modified above to be turned on if we |
157 | * were trying to set some addresses and dongle rejected it... | 114 | * were trying to set some addresses and dongle rejected it... |
158 | */ | 115 | */ |
159 | 116 | err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); | |
160 | buflen = sizeof("allmulti") + sizeof(dcmd_value); | 117 | if (err < 0) |
161 | buf = kmalloc(buflen, GFP_ATOMIC); | 118 | brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err); |
162 | if (!buf) | 119 | |
163 | return; | 120 | /*Finally, pick up the PROMISC flag */ |
164 | 121 | cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; | |
165 | dcmd_le_value = cpu_to_le32(dcmd_value); | 122 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); |
166 | 123 | if (err < 0) | |
167 | if (!brcmf_c_mkiovar | 124 | brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n", |
168 | ("allmulti", (void *)&dcmd_le_value, | 125 | err); |
169 | sizeof(dcmd_le_value), buf, buflen)) { | ||
170 | brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", | ||
171 | brcmf_ifname(drvr, 0), | ||
172 | (int)sizeof(dcmd_value), buflen); | ||
173 | kfree(buf); | ||
174 | return; | ||
175 | } | ||
176 | |||
177 | memset(&dcmd, 0, sizeof(dcmd)); | ||
178 | dcmd.cmd = BRCMF_C_SET_VAR; | ||
179 | dcmd.buf = buf; | ||
180 | dcmd.len = buflen; | ||
181 | dcmd.set = true; | ||
182 | |||
183 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
184 | if (ret < 0) { | ||
185 | brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", | ||
186 | brcmf_ifname(drvr, 0), | ||
187 | le32_to_cpu(dcmd_le_value)); | ||
188 | } | ||
189 | |||
190 | kfree(buf); | ||
191 | |||
192 | /* Finally, pick up the PROMISC flag as well, like the NIC | ||
193 | driver does */ | ||
194 | |||
195 | dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false; | ||
196 | dcmd_le_value = cpu_to_le32(dcmd_value); | ||
197 | |||
198 | memset(&dcmd, 0, sizeof(dcmd)); | ||
199 | dcmd.cmd = BRCMF_C_SET_PROMISC; | ||
200 | dcmd.buf = &dcmd_le_value; | ||
201 | dcmd.len = sizeof(dcmd_le_value); | ||
202 | dcmd.set = true; | ||
203 | |||
204 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | ||
205 | if (ret < 0) { | ||
206 | brcmf_dbg(ERROR, "%s: set promisc %d failed\n", | ||
207 | brcmf_ifname(drvr, 0), | ||
208 | le32_to_cpu(dcmd_le_value)); | ||
209 | } | ||
210 | } | 126 | } |
211 | 127 | ||
212 | static void | 128 | static void |
213 | _brcmf_set_mac_address(struct work_struct *work) | 129 | _brcmf_set_mac_address(struct work_struct *work) |
214 | { | 130 | { |
215 | char buf[32]; | 131 | struct brcmf_if *ifp; |
216 | struct brcmf_dcmd dcmd; | 132 | s32 err; |
217 | int ret; | ||
218 | |||
219 | struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, | ||
220 | setmacaddr_work); | ||
221 | 133 | ||
222 | brcmf_dbg(TRACE, "enter\n"); | 134 | brcmf_dbg(TRACE, "enter\n"); |
223 | if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue, | ||
224 | ETH_ALEN, buf, 32)) { | ||
225 | brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", | ||
226 | brcmf_ifname(drvr, 0)); | ||
227 | return; | ||
228 | } | ||
229 | memset(&dcmd, 0, sizeof(dcmd)); | ||
230 | dcmd.cmd = BRCMF_C_SET_VAR; | ||
231 | dcmd.buf = buf; | ||
232 | dcmd.len = 32; | ||
233 | dcmd.set = true; | ||
234 | 135 | ||
235 | ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len); | 136 | ifp = container_of(work, struct brcmf_if, setmacaddr_work); |
236 | if (ret < 0) | 137 | err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, |
237 | brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", | 138 | ETH_ALEN); |
238 | brcmf_ifname(drvr, 0)); | 139 | if (err < 0) { |
239 | else | 140 | brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err); |
240 | memcpy(drvr->iflist[0]->ndev->dev_addr, | 141 | } else { |
241 | drvr->macvalue, ETH_ALEN); | 142 | brcmf_dbg(TRACE, "MAC address updated to %pM\n", |
242 | 143 | ifp->mac_addr); | |
243 | return; | 144 | memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); |
145 | } | ||
244 | } | 146 | } |
245 | 147 | ||
246 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) | 148 | static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) |
247 | { | 149 | { |
248 | struct brcmf_if *ifp = netdev_priv(ndev); | 150 | struct brcmf_if *ifp = netdev_priv(ndev); |
249 | struct brcmf_pub *drvr = ifp->drvr; | ||
250 | struct sockaddr *sa = (struct sockaddr *)addr; | 151 | struct sockaddr *sa = (struct sockaddr *)addr; |
251 | 152 | ||
252 | memcpy(&drvr->macvalue, sa->sa_data, ETH_ALEN); | 153 | memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); |
253 | schedule_work(&drvr->setmacaddr_work); | 154 | schedule_work(&ifp->setmacaddr_work); |
254 | return 0; | 155 | return 0; |
255 | } | 156 | } |
256 | 157 | ||
257 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) | 158 | static void brcmf_netdev_set_multicast_list(struct net_device *ndev) |
258 | { | 159 | { |
259 | struct brcmf_if *ifp = netdev_priv(ndev); | 160 | struct brcmf_if *ifp = netdev_priv(ndev); |
260 | struct brcmf_pub *drvr = ifp->drvr; | ||
261 | 161 | ||
262 | schedule_work(&drvr->multicast_work); | 162 | schedule_work(&ifp->multicast_work); |
263 | } | 163 | } |
264 | 164 | ||
265 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | 165 | static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
@@ -272,7 +172,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) | |||
272 | 172 | ||
273 | /* Reject if down */ | 173 | /* Reject if down */ |
274 | if (!drvr->bus_if->drvr_up || | 174 | if (!drvr->bus_if->drvr_up || |
275 | (drvr->bus_if->state == BRCMF_BUS_DOWN)) { | 175 | (drvr->bus_if->state != BRCMF_BUS_DATA)) { |
276 | brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", | 176 | brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n", |
277 | drvr->bus_if->drvr_up, | 177 | drvr->bus_if->drvr_up, |
278 | drvr->bus_if->state); | 178 | drvr->bus_if->state); |
@@ -350,32 +250,13 @@ void brcmf_txflowblock(struct device *dev, bool state) | |||
350 | } | 250 | } |
351 | } | 251 | } |
352 | 252 | ||
353 | static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, | 253 | void brcmf_rx_frame(struct device *dev, u8 ifidx, |
354 | void *pktdata, struct brcmf_event_msg *event, | ||
355 | void **data) | ||
356 | { | ||
357 | int bcmerror = 0; | ||
358 | |||
359 | bcmerror = brcmf_c_host_event(drvr, ifidx, pktdata, event, data); | ||
360 | if (bcmerror != 0) | ||
361 | return bcmerror; | ||
362 | |||
363 | if (drvr->iflist[*ifidx]->ndev) | ||
364 | brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev, | ||
365 | event, *data); | ||
366 | |||
367 | return bcmerror; | ||
368 | } | ||
369 | |||
370 | void brcmf_rx_frame(struct device *dev, int ifidx, | ||
371 | struct sk_buff_head *skb_list) | 254 | struct sk_buff_head *skb_list) |
372 | { | 255 | { |
373 | unsigned char *eth; | 256 | unsigned char *eth; |
374 | uint len; | 257 | uint len; |
375 | void *data; | ||
376 | struct sk_buff *skb, *pnext; | 258 | struct sk_buff *skb, *pnext; |
377 | struct brcmf_if *ifp; | 259 | struct brcmf_if *ifp; |
378 | struct brcmf_event_msg event; | ||
379 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 260 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
380 | struct brcmf_pub *drvr = bus_if->drvr; | 261 | struct brcmf_pub *drvr = bus_if->drvr; |
381 | 262 | ||
@@ -422,10 +303,7 @@ void brcmf_rx_frame(struct device *dev, int ifidx, | |||
422 | skb_pull(skb, ETH_HLEN); | 303 | skb_pull(skb, ETH_HLEN); |
423 | 304 | ||
424 | /* Process special event packets and then discard them */ | 305 | /* Process special event packets and then discard them */ |
425 | if (ntohs(skb->protocol) == ETH_P_LINK_CTL) | 306 | brcmf_fweh_process_skb(drvr, skb, &ifidx); |
426 | brcmf_host_event(drvr, &ifidx, | ||
427 | skb_mac_header(skb), | ||
428 | &event, &data); | ||
429 | 307 | ||
430 | if (drvr->iflist[ifidx]) { | 308 | if (drvr->iflist[ifidx]) { |
431 | ifp = drvr->iflist[ifidx]; | 309 | ifp = drvr->iflist[ifidx]; |
@@ -461,9 +339,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success) | |||
461 | eh = (struct ethhdr *)(txp->data); | 339 | eh = (struct ethhdr *)(txp->data); |
462 | type = ntohs(eh->h_proto); | 340 | type = ntohs(eh->h_proto); |
463 | 341 | ||
464 | if (type == ETH_P_PAE) | 342 | if (type == ETH_P_PAE) { |
465 | atomic_dec(&drvr->pend_8021x_cnt); | 343 | atomic_dec(&drvr->pend_8021x_cnt); |
466 | 344 | if (waitqueue_active(&drvr->pend_8021x_wait)) | |
345 | wake_up(&drvr->pend_8021x_wait); | ||
346 | } | ||
467 | } | 347 | } |
468 | 348 | ||
469 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | 349 | static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) |
@@ -487,83 +367,26 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) | |||
487 | return &ifp->stats; | 367 | return &ifp->stats; |
488 | } | 368 | } |
489 | 369 | ||
490 | /* Retrieve current toe component enables, which are kept | 370 | /* |
491 | as a bitmap in toe_ol iovar */ | 371 | * Set current toe component enables in toe_ol iovar, |
492 | static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol) | 372 | * and set toe global enable iovar |
493 | { | 373 | */ |
494 | struct brcmf_dcmd dcmd; | 374 | static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol) |
495 | __le32 toe_le; | ||
496 | char buf[32]; | ||
497 | int ret; | ||
498 | |||
499 | memset(&dcmd, 0, sizeof(dcmd)); | ||
500 | |||
501 | dcmd.cmd = BRCMF_C_GET_VAR; | ||
502 | dcmd.buf = buf; | ||
503 | dcmd.len = (uint) sizeof(buf); | ||
504 | dcmd.set = false; | ||
505 | |||
506 | strcpy(buf, "toe_ol"); | ||
507 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
508 | if (ret < 0) { | ||
509 | /* Check for older dongle image that doesn't support toe_ol */ | ||
510 | if (ret == -EIO) { | ||
511 | brcmf_dbg(ERROR, "%s: toe not supported by device\n", | ||
512 | brcmf_ifname(drvr, ifidx)); | ||
513 | return -EOPNOTSUPP; | ||
514 | } | ||
515 | |||
516 | brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", | ||
517 | brcmf_ifname(drvr, ifidx), ret); | ||
518 | return ret; | ||
519 | } | ||
520 | |||
521 | memcpy(&toe_le, buf, sizeof(u32)); | ||
522 | *toe_ol = le32_to_cpu(toe_le); | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | /* Set current toe component enables in toe_ol iovar, | ||
527 | and set toe global enable iovar */ | ||
528 | static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol) | ||
529 | { | 375 | { |
530 | struct brcmf_dcmd dcmd; | 376 | s32 err; |
531 | char buf[32]; | ||
532 | int ret; | ||
533 | __le32 toe_le = cpu_to_le32(toe_ol); | ||
534 | |||
535 | memset(&dcmd, 0, sizeof(dcmd)); | ||
536 | 377 | ||
537 | dcmd.cmd = BRCMF_C_SET_VAR; | 378 | err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol); |
538 | dcmd.buf = buf; | 379 | if (err < 0) { |
539 | dcmd.len = (uint) sizeof(buf); | 380 | brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err); |
540 | dcmd.set = true; | 381 | return err; |
541 | |||
542 | /* Set toe_ol as requested */ | ||
543 | strcpy(buf, "toe_ol"); | ||
544 | memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32)); | ||
545 | |||
546 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
547 | if (ret < 0) { | ||
548 | brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", | ||
549 | brcmf_ifname(drvr, ifidx), ret); | ||
550 | return ret; | ||
551 | } | 382 | } |
552 | 383 | ||
553 | /* Enable toe globally only if any components are enabled. */ | 384 | err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0)); |
554 | toe_le = cpu_to_le32(toe_ol != 0); | 385 | if (err < 0) |
386 | brcmf_dbg(ERROR, "Setting toe failed, %d\n", err); | ||
555 | 387 | ||
556 | strcpy(buf, "toe"); | 388 | return err; |
557 | memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32)); | ||
558 | 389 | ||
559 | ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len); | ||
560 | if (ret < 0) { | ||
561 | brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", | ||
562 | brcmf_ifname(drvr, ifidx), ret); | ||
563 | return ret; | ||
564 | } | ||
565 | |||
566 | return 0; | ||
567 | } | 390 | } |
568 | 391 | ||
569 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, | 392 | static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, |
@@ -581,8 +404,9 @@ static const struct ethtool_ops brcmf_ethtool_ops = { | |||
581 | .get_drvinfo = brcmf_ethtool_get_drvinfo, | 404 | .get_drvinfo = brcmf_ethtool_get_drvinfo, |
582 | }; | 405 | }; |
583 | 406 | ||
584 | static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | 407 | static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr) |
585 | { | 408 | { |
409 | struct brcmf_pub *drvr = ifp->drvr; | ||
586 | struct ethtool_drvinfo info; | 410 | struct ethtool_drvinfo info; |
587 | char drvname[sizeof(info.driver)]; | 411 | char drvname[sizeof(info.driver)]; |
588 | u32 cmd; | 412 | u32 cmd; |
@@ -633,7 +457,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
633 | /* Get toe offload components from dongle */ | 457 | /* Get toe offload components from dongle */ |
634 | case ETHTOOL_GRXCSUM: | 458 | case ETHTOOL_GRXCSUM: |
635 | case ETHTOOL_GTXCSUM: | 459 | case ETHTOOL_GTXCSUM: |
636 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); | 460 | ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); |
637 | if (ret < 0) | 461 | if (ret < 0) |
638 | return ret; | 462 | return ret; |
639 | 463 | ||
@@ -654,7 +478,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
654 | return -EFAULT; | 478 | return -EFAULT; |
655 | 479 | ||
656 | /* Read the current settings, update and write back */ | 480 | /* Read the current settings, update and write back */ |
657 | ret = brcmf_toe_get(drvr, 0, &toe_cmpnt); | 481 | ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt); |
658 | if (ret < 0) | 482 | if (ret < 0) |
659 | return ret; | 483 | return ret; |
660 | 484 | ||
@@ -666,18 +490,16 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) | |||
666 | else | 490 | else |
667 | toe_cmpnt &= ~csum_dir; | 491 | toe_cmpnt &= ~csum_dir; |
668 | 492 | ||
669 | ret = brcmf_toe_set(drvr, 0, toe_cmpnt); | 493 | ret = brcmf_toe_set(ifp, toe_cmpnt); |
670 | if (ret < 0) | 494 | if (ret < 0) |
671 | return ret; | 495 | return ret; |
672 | 496 | ||
673 | /* If setting TX checksum mode, tell Linux the new mode */ | 497 | /* If setting TX checksum mode, tell Linux the new mode */ |
674 | if (cmd == ETHTOOL_STXCSUM) { | 498 | if (cmd == ETHTOOL_STXCSUM) { |
675 | if (edata.data) | 499 | if (edata.data) |
676 | drvr->iflist[0]->ndev->features |= | 500 | ifp->ndev->features |= NETIF_F_IP_CSUM; |
677 | NETIF_F_IP_CSUM; | ||
678 | else | 501 | else |
679 | drvr->iflist[0]->ndev->features &= | 502 | ifp->ndev->features &= ~NETIF_F_IP_CSUM; |
680 | ~NETIF_F_IP_CSUM; | ||
681 | } | 503 | } |
682 | 504 | ||
683 | break; | 505 | break; |
@@ -701,7 +523,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr, | |||
701 | return -1; | 523 | return -1; |
702 | 524 | ||
703 | if (cmd == SIOCETHTOOL) | 525 | if (cmd == SIOCETHTOOL) |
704 | return brcmf_ethtool(drvr, ifr->ifr_data); | 526 | return brcmf_ethtool(ifp, ifr->ifr_data); |
705 | 527 | ||
706 | return -EOPNOTSUPP; | 528 | return -EOPNOTSUPP; |
707 | } | 529 | } |
@@ -712,10 +534,12 @@ static int brcmf_netdev_stop(struct net_device *ndev) | |||
712 | struct brcmf_pub *drvr = ifp->drvr; | 534 | struct brcmf_pub *drvr = ifp->drvr; |
713 | 535 | ||
714 | brcmf_dbg(TRACE, "Enter\n"); | 536 | brcmf_dbg(TRACE, "Enter\n"); |
715 | brcmf_cfg80211_down(drvr->config); | 537 | |
716 | if (drvr->bus_if->drvr_up == 0) | 538 | if (drvr->bus_if->drvr_up == 0) |
717 | return 0; | 539 | return 0; |
718 | 540 | ||
541 | brcmf_cfg80211_down(ndev); | ||
542 | |||
719 | /* Set state and stop OS transmissions */ | 543 | /* Set state and stop OS transmissions */ |
720 | drvr->bus_if->drvr_up = false; | 544 | drvr->bus_if->drvr_up = false; |
721 | netif_stop_queue(ndev); | 545 | netif_stop_queue(ndev); |
@@ -730,38 +554,35 @@ static int brcmf_netdev_open(struct net_device *ndev) | |||
730 | struct brcmf_bus *bus_if = drvr->bus_if; | 554 | struct brcmf_bus *bus_if = drvr->bus_if; |
731 | u32 toe_ol; | 555 | u32 toe_ol; |
732 | s32 ret = 0; | 556 | s32 ret = 0; |
733 | uint up = 0; | ||
734 | 557 | ||
735 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); | 558 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); |
736 | 559 | ||
737 | if (ifp->idx == 0) { /* do it only for primary eth0 */ | 560 | /* If bus is not ready, can't continue */ |
738 | /* If bus is not ready, can't continue */ | 561 | if (bus_if->state != BRCMF_BUS_DATA) { |
739 | if (bus_if->state != BRCMF_BUS_DATA) { | 562 | brcmf_dbg(ERROR, "failed bus is not ready\n"); |
740 | brcmf_dbg(ERROR, "failed bus is not ready\n"); | 563 | return -EAGAIN; |
741 | return -EAGAIN; | 564 | } |
742 | } | ||
743 | 565 | ||
744 | atomic_set(&drvr->pend_8021x_cnt, 0); | 566 | atomic_set(&drvr->pend_8021x_cnt, 0); |
745 | 567 | ||
746 | memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); | 568 | memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN); |
747 | 569 | ||
748 | /* Get current TOE mode from dongle */ | 570 | /* Get current TOE mode from dongle */ |
749 | if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0 | 571 | if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0 |
750 | && (toe_ol & TOE_TX_CSUM_OL) != 0) | 572 | && (toe_ol & TOE_TX_CSUM_OL) != 0) |
751 | drvr->iflist[ifp->idx]->ndev->features |= | 573 | drvr->iflist[ifp->idx]->ndev->features |= |
752 | NETIF_F_IP_CSUM; | 574 | NETIF_F_IP_CSUM; |
753 | else | 575 | else |
754 | drvr->iflist[ifp->idx]->ndev->features &= | 576 | drvr->iflist[ifp->idx]->ndev->features &= |
755 | ~NETIF_F_IP_CSUM; | 577 | ~NETIF_F_IP_CSUM; |
756 | } | ||
757 | 578 | ||
758 | /* make sure RF is ready for work */ | 579 | /* make sure RF is ready for work */ |
759 | brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up)); | 580 | brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0); |
760 | 581 | ||
761 | /* Allow transmit calls */ | 582 | /* Allow transmit calls */ |
762 | netif_start_queue(ndev); | 583 | netif_start_queue(ndev); |
763 | drvr->bus_if->drvr_up = true; | 584 | drvr->bus_if->drvr_up = true; |
764 | if (brcmf_cfg80211_up(drvr->config)) { | 585 | if (brcmf_cfg80211_up(ndev)) { |
765 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); | 586 | brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); |
766 | return -1; | 587 | return -1; |
767 | } | 588 | } |
@@ -779,39 +600,38 @@ static const struct net_device_ops brcmf_netdev_ops_pri = { | |||
779 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | 600 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list |
780 | }; | 601 | }; |
781 | 602 | ||
603 | static const struct net_device_ops brcmf_netdev_ops_virt = { | ||
604 | .ndo_open = brcmf_cfg80211_up, | ||
605 | .ndo_stop = brcmf_cfg80211_down, | ||
606 | .ndo_get_stats = brcmf_netdev_get_stats, | ||
607 | .ndo_do_ioctl = brcmf_netdev_ioctl_entry, | ||
608 | .ndo_start_xmit = brcmf_netdev_start_xmit, | ||
609 | .ndo_set_mac_address = brcmf_netdev_set_mac_address, | ||
610 | .ndo_set_rx_mode = brcmf_netdev_set_multicast_list | ||
611 | }; | ||
612 | |||
782 | int brcmf_net_attach(struct brcmf_if *ifp) | 613 | int brcmf_net_attach(struct brcmf_if *ifp) |
783 | { | 614 | { |
784 | struct brcmf_pub *drvr = ifp->drvr; | 615 | struct brcmf_pub *drvr = ifp->drvr; |
785 | struct net_device *ndev; | 616 | struct net_device *ndev; |
786 | u8 temp_addr[ETH_ALEN]; | ||
787 | |||
788 | brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx); | ||
789 | 617 | ||
790 | ndev = drvr->iflist[ifp->idx]->ndev; | 618 | brcmf_dbg(TRACE, "ifidx %d mac %pM\n", ifp->idx, ifp->mac_addr); |
791 | ndev->netdev_ops = &brcmf_netdev_ops_pri; | 619 | ndev = ifp->ndev; |
792 | 620 | ||
793 | /* | 621 | /* set appropriate operations */ |
794 | * determine mac address to use | 622 | if (!ifp->idx) |
795 | */ | 623 | ndev->netdev_ops = &brcmf_netdev_ops_pri; |
796 | if (is_valid_ether_addr(ifp->mac_addr)) | ||
797 | memcpy(temp_addr, ifp->mac_addr, ETH_ALEN); | ||
798 | else | 624 | else |
799 | memcpy(temp_addr, drvr->mac, ETH_ALEN); | 625 | ndev->netdev_ops = &brcmf_netdev_ops_virt; |
800 | |||
801 | if (ifp->idx == 1) { | ||
802 | brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); | ||
803 | /* ACCESSPOINT INTERFACE CASE */ | ||
804 | temp_addr[0] |= 0X02; /* set bit 2 , | ||
805 | - Locally Administered address */ | ||
806 | 626 | ||
807 | } | ||
808 | ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; | 627 | ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; |
809 | ndev->ethtool_ops = &brcmf_ethtool_ops; | 628 | ndev->ethtool_ops = &brcmf_ethtool_ops; |
810 | 629 | ||
811 | drvr->rxsz = ndev->mtu + ndev->hard_header_len + | 630 | drvr->rxsz = ndev->mtu + ndev->hard_header_len + |
812 | drvr->hdrlen; | 631 | drvr->hdrlen; |
813 | 632 | ||
814 | memcpy(ndev->dev_addr, temp_addr, ETH_ALEN); | 633 | /* set the mac address */ |
634 | memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); | ||
815 | 635 | ||
816 | if (register_netdev(ndev) != 0) { | 636 | if (register_netdev(ndev) != 0) { |
817 | brcmf_dbg(ERROR, "couldn't register the net device\n"); | 637 | brcmf_dbg(ERROR, "couldn't register the net device\n"); |
@@ -824,17 +644,15 @@ int brcmf_net_attach(struct brcmf_if *ifp) | |||
824 | 644 | ||
825 | fail: | 645 | fail: |
826 | ndev->netdev_ops = NULL; | 646 | ndev->netdev_ops = NULL; |
827 | free_netdev(ndev); | ||
828 | return -EBADE; | 647 | return -EBADE; |
829 | } | 648 | } |
830 | 649 | ||
831 | struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | 650 | struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, int ifidx, s32 bssidx, |
832 | char *name, u8 *mac_addr) | 651 | char *name, u8 *addr_mask) |
833 | { | 652 | { |
834 | struct brcmf_if *ifp; | 653 | struct brcmf_if *ifp; |
835 | struct net_device *ndev; | 654 | struct net_device *ndev; |
836 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 655 | int i; |
837 | struct brcmf_pub *drvr = bus_if->drvr; | ||
838 | 656 | ||
839 | brcmf_dbg(TRACE, "idx %d\n", ifidx); | 657 | brcmf_dbg(TRACE, "idx %d\n", ifidx); |
840 | 658 | ||
@@ -844,12 +662,17 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | |||
844 | * in case we missed the BRCMF_E_IF_DEL event. | 662 | * in case we missed the BRCMF_E_IF_DEL event. |
845 | */ | 663 | */ |
846 | if (ifp) { | 664 | if (ifp) { |
847 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", | 665 | brcmf_dbg(ERROR, "ERROR: netdev:%s already exists\n", |
848 | ifp->ndev->name); | 666 | ifp->ndev->name); |
849 | netif_stop_queue(ifp->ndev); | 667 | if (ifidx) { |
850 | unregister_netdev(ifp->ndev); | 668 | netif_stop_queue(ifp->ndev); |
851 | free_netdev(ifp->ndev); | 669 | unregister_netdev(ifp->ndev); |
852 | drvr->iflist[ifidx] = NULL; | 670 | free_netdev(ifp->ndev); |
671 | drvr->iflist[ifidx] = NULL; | ||
672 | } else { | ||
673 | brcmf_dbg(ERROR, "ignore IF event\n"); | ||
674 | return ERR_PTR(-EINVAL); | ||
675 | } | ||
853 | } | 676 | } |
854 | 677 | ||
855 | /* Allocate netdev, including space for private structure */ | 678 | /* Allocate netdev, including space for private structure */ |
@@ -865,11 +688,16 @@ struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, | |||
865 | drvr->iflist[ifidx] = ifp; | 688 | drvr->iflist[ifidx] = ifp; |
866 | ifp->idx = ifidx; | 689 | ifp->idx = ifidx; |
867 | ifp->bssidx = bssidx; | 690 | ifp->bssidx = bssidx; |
868 | if (mac_addr != NULL) | ||
869 | memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); | ||
870 | 691 | ||
871 | brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", | 692 | INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); |
872 | current->pid, ifp->ndev->name); | 693 | INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); |
694 | |||
695 | if (addr_mask != NULL) | ||
696 | for (i = 0; i < ETH_ALEN; i++) | ||
697 | ifp->mac_addr[i] = drvr->mac[i] ^ addr_mask[i]; | ||
698 | |||
699 | brcmf_dbg(TRACE, " ==== pid:%x, if:%s (%pM) created ===\n", | ||
700 | current->pid, ifp->ndev->name, ifp->mac_addr); | ||
873 | 701 | ||
874 | return ifp; | 702 | return ifp; |
875 | } | 703 | } |
@@ -896,6 +724,9 @@ void brcmf_del_if(struct brcmf_pub *drvr, int ifidx) | |||
896 | netif_stop_queue(ifp->ndev); | 724 | netif_stop_queue(ifp->ndev); |
897 | } | 725 | } |
898 | 726 | ||
727 | cancel_work_sync(&ifp->setmacaddr_work); | ||
728 | cancel_work_sync(&ifp->multicast_work); | ||
729 | |||
899 | unregister_netdev(ifp->ndev); | 730 | unregister_netdev(ifp->ndev); |
900 | drvr->iflist[ifidx] = NULL; | 731 | drvr->iflist[ifidx] = NULL; |
901 | if (ifidx == 0) | 732 | if (ifidx == 0) |
@@ -934,11 +765,13 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev) | |||
934 | goto fail; | 765 | goto fail; |
935 | } | 766 | } |
936 | 767 | ||
937 | INIT_WORK(&drvr->setmacaddr_work, _brcmf_set_mac_address); | 768 | /* attach firmware event handler */ |
938 | INIT_WORK(&drvr->multicast_work, _brcmf_set_multicast_list); | 769 | brcmf_fweh_attach(drvr); |
939 | 770 | ||
940 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); | 771 | INIT_LIST_HEAD(&drvr->bus_if->dcmd_list); |
941 | 772 | ||
773 | init_waitqueue_head(&drvr->pend_8021x_wait); | ||
774 | |||
942 | return ret; | 775 | return ret; |
943 | 776 | ||
944 | fail: | 777 | fail: |
@@ -964,7 +797,7 @@ int brcmf_bus_start(struct device *dev) | |||
964 | } | 797 | } |
965 | 798 | ||
966 | /* add primary networking interface */ | 799 | /* add primary networking interface */ |
967 | ifp = brcmf_add_if(dev, 0, 0, "wlan%d", NULL); | 800 | ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL); |
968 | if (IS_ERR(ifp)) | 801 | if (IS_ERR(ifp)) |
969 | return PTR_ERR(ifp); | 802 | return PTR_ERR(ifp); |
970 | 803 | ||
@@ -974,15 +807,25 @@ int brcmf_bus_start(struct device *dev) | |||
974 | /* Bus is ready, do any initialization */ | 807 | /* Bus is ready, do any initialization */ |
975 | ret = brcmf_c_preinit_dcmds(ifp); | 808 | ret = brcmf_c_preinit_dcmds(ifp); |
976 | if (ret < 0) | 809 | if (ret < 0) |
977 | return ret; | 810 | goto fail; |
978 | 811 | ||
979 | drvr->config = brcmf_cfg80211_attach(drvr); | 812 | drvr->config = brcmf_cfg80211_attach(drvr); |
980 | if (drvr->config == NULL) | 813 | if (drvr->config == NULL) { |
981 | return -ENOMEM; | 814 | ret = -ENOMEM; |
815 | goto fail; | ||
816 | } | ||
817 | |||
818 | ret = brcmf_fweh_activate_events(ifp); | ||
819 | if (ret < 0) | ||
820 | goto fail; | ||
982 | 821 | ||
983 | ret = brcmf_net_attach(ifp); | 822 | ret = brcmf_net_attach(ifp); |
823 | fail: | ||
984 | if (ret < 0) { | 824 | if (ret < 0) { |
985 | brcmf_dbg(ERROR, "brcmf_net_attach failed"); | 825 | brcmf_dbg(ERROR, "failed: %d\n", ret); |
826 | if (drvr->config) | ||
827 | brcmf_cfg80211_detach(drvr->config); | ||
828 | free_netdev(drvr->iflist[0]->ndev); | ||
986 | drvr->iflist[0] = NULL; | 829 | drvr->iflist[0] = NULL; |
987 | return ret; | 830 | return ret; |
988 | } | 831 | } |
@@ -1011,6 +854,11 @@ void brcmf_detach(struct device *dev) | |||
1011 | 854 | ||
1012 | brcmf_dbg(TRACE, "Enter\n"); | 855 | brcmf_dbg(TRACE, "Enter\n"); |
1013 | 856 | ||
857 | if (drvr == NULL) | ||
858 | return; | ||
859 | |||
860 | /* stop firmware event handling */ | ||
861 | brcmf_fweh_detach(drvr); | ||
1014 | 862 | ||
1015 | /* make sure primary interface removed last */ | 863 | /* make sure primary interface removed last */ |
1016 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) | 864 | for (i = BRCMF_MAX_IFS-1; i > -1; i--) |
@@ -1020,8 +868,6 @@ void brcmf_detach(struct device *dev) | |||
1020 | brcmf_bus_detach(drvr); | 868 | brcmf_bus_detach(drvr); |
1021 | 869 | ||
1022 | if (drvr->prot) { | 870 | if (drvr->prot) { |
1023 | cancel_work_sync(&drvr->setmacaddr_work); | ||
1024 | cancel_work_sync(&drvr->multicast_work); | ||
1025 | brcmf_proto_detach(drvr); | 871 | brcmf_proto_detach(drvr); |
1026 | } | 872 | } |
1027 | 873 | ||
@@ -1035,26 +881,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr) | |||
1035 | return atomic_read(&drvr->pend_8021x_cnt); | 881 | return atomic_read(&drvr->pend_8021x_cnt); |
1036 | } | 882 | } |
1037 | 883 | ||
1038 | #define MAX_WAIT_FOR_8021X_TX 10 | ||
1039 | |||
1040 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) | 884 | int brcmf_netdev_wait_pend8021x(struct net_device *ndev) |
1041 | { | 885 | { |
1042 | struct brcmf_if *ifp = netdev_priv(ndev); | 886 | struct brcmf_if *ifp = netdev_priv(ndev); |
1043 | struct brcmf_pub *drvr = ifp->drvr; | 887 | struct brcmf_pub *drvr = ifp->drvr; |
1044 | int timeout = 10 * HZ / 1000; | 888 | int err; |
1045 | int ntimes = MAX_WAIT_FOR_8021X_TX; | 889 | |
1046 | int pend = brcmf_get_pend_8021x_cnt(drvr); | 890 | err = wait_event_timeout(drvr->pend_8021x_wait, |
1047 | 891 | !brcmf_get_pend_8021x_cnt(drvr), | |
1048 | while (ntimes && pend) { | 892 | msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX)); |
1049 | if (pend) { | 893 | |
1050 | set_current_state(TASK_INTERRUPTIBLE); | 894 | WARN_ON(!err); |
1051 | schedule_timeout(timeout); | 895 | |
1052 | set_current_state(TASK_RUNNING); | 896 | return !err; |
1053 | ntimes--; | ||
1054 | } | ||
1055 | pend = brcmf_get_pend_8021x_cnt(drvr); | ||
1056 | } | ||
1057 | return pend; | ||
1058 | } | 897 | } |
1059 | 898 | ||
1060 | static void brcmf_driver_init(struct work_struct *work) | 899 | static void brcmf_driver_init(struct work_struct *work) |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h index 7fe6779b90cf..48fa70302192 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h | |||
@@ -36,14 +36,7 @@ extern void brcmf_proto_stop(struct brcmf_pub *drvr); | |||
36 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, | 36 | extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, |
37 | struct sk_buff *txp); | 37 | struct sk_buff *txp); |
38 | 38 | ||
39 | /* Use protocol to issue command to dongle */ | ||
40 | extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, | ||
41 | struct brcmf_dcmd *dcmd, int len); | ||
42 | |||
43 | /* Sets dongle media info (drv_version, mac address). */ | 39 | /* Sets dongle media info (drv_version, mac address). */ |
44 | extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); | 40 | extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); |
45 | 41 | ||
46 | extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, | ||
47 | uint cmd, void *buf, uint len); | ||
48 | |||
49 | #endif /* _BRCMF_PROTO_H_ */ | 42 | #endif /* _BRCMF_PROTO_H_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 415f2be36375..45725454714d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -533,9 +533,11 @@ struct brcmf_sdio { | |||
533 | u8 *rxbuf; /* Buffer for receiving control packets */ | 533 | u8 *rxbuf; /* Buffer for receiving control packets */ |
534 | uint rxblen; /* Allocated length of rxbuf */ | 534 | uint rxblen; /* Allocated length of rxbuf */ |
535 | u8 *rxctl; /* Aligned pointer into rxbuf */ | 535 | u8 *rxctl; /* Aligned pointer into rxbuf */ |
536 | u8 *rxctl_orig; /* pointer for freeing rxctl */ | ||
536 | u8 *databuf; /* Buffer for receiving big glom packet */ | 537 | u8 *databuf; /* Buffer for receiving big glom packet */ |
537 | u8 *dataptr; /* Aligned pointer into databuf */ | 538 | u8 *dataptr; /* Aligned pointer into databuf */ |
538 | uint rxlen; /* Length of valid data in buffer */ | 539 | uint rxlen; /* Length of valid data in buffer */ |
540 | spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */ | ||
539 | 541 | ||
540 | u8 sdpcm_ver; /* Bus protocol reported by dongle */ | 542 | u8 sdpcm_ver; /* Bus protocol reported by dongle */ |
541 | 543 | ||
@@ -582,8 +584,6 @@ struct brcmf_sdio { | |||
582 | struct list_head dpc_tsklst; | 584 | struct list_head dpc_tsklst; |
583 | spinlock_t dpc_tl_lock; | 585 | spinlock_t dpc_tl_lock; |
584 | 586 | ||
585 | struct semaphore sdsem; | ||
586 | |||
587 | const struct firmware *firmware; | 587 | const struct firmware *firmware; |
588 | u32 fw_ptr; | 588 | u32 fw_ptr; |
589 | 589 | ||
@@ -1037,9 +1037,9 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus) | |||
1037 | } | 1037 | } |
1038 | } | 1038 | } |
1039 | 1039 | ||
1040 | static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | 1040 | static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, |
1041 | struct brcmf_sdio_read *rd, | 1041 | struct brcmf_sdio_read *rd, |
1042 | enum brcmf_sdio_frmtype type) | 1042 | enum brcmf_sdio_frmtype type) |
1043 | { | 1043 | { |
1044 | u16 len, checksum; | 1044 | u16 len, checksum; |
1045 | u8 rx_seq, fc, tx_seq_max; | 1045 | u8 rx_seq, fc, tx_seq_max; |
@@ -1054,26 +1054,26 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1054 | /* All zero means no more to read */ | 1054 | /* All zero means no more to read */ |
1055 | if (!(len | checksum)) { | 1055 | if (!(len | checksum)) { |
1056 | bus->rxpending = false; | 1056 | bus->rxpending = false; |
1057 | return false; | 1057 | return -ENODATA; |
1058 | } | 1058 | } |
1059 | if ((u16)(~(len ^ checksum))) { | 1059 | if ((u16)(~(len ^ checksum))) { |
1060 | brcmf_dbg(ERROR, "HW header checksum error\n"); | 1060 | brcmf_dbg(ERROR, "HW header checksum error\n"); |
1061 | bus->sdcnt.rx_badhdr++; | 1061 | bus->sdcnt.rx_badhdr++; |
1062 | brcmf_sdbrcm_rxfail(bus, false, false); | 1062 | brcmf_sdbrcm_rxfail(bus, false, false); |
1063 | return false; | 1063 | return -EIO; |
1064 | } | 1064 | } |
1065 | if (len < SDPCM_HDRLEN) { | 1065 | if (len < SDPCM_HDRLEN) { |
1066 | brcmf_dbg(ERROR, "HW header length error\n"); | 1066 | brcmf_dbg(ERROR, "HW header length error\n"); |
1067 | return false; | 1067 | return -EPROTO; |
1068 | } | 1068 | } |
1069 | if (type == BRCMF_SDIO_FT_SUPER && | 1069 | if (type == BRCMF_SDIO_FT_SUPER && |
1070 | (roundup(len, bus->blocksize) != rd->len)) { | 1070 | (roundup(len, bus->blocksize) != rd->len)) { |
1071 | brcmf_dbg(ERROR, "HW superframe header length error\n"); | 1071 | brcmf_dbg(ERROR, "HW superframe header length error\n"); |
1072 | return false; | 1072 | return -EPROTO; |
1073 | } | 1073 | } |
1074 | if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { | 1074 | if (type == BRCMF_SDIO_FT_SUB && len > rd->len) { |
1075 | brcmf_dbg(ERROR, "HW subframe header length error\n"); | 1075 | brcmf_dbg(ERROR, "HW subframe header length error\n"); |
1076 | return false; | 1076 | return -EPROTO; |
1077 | } | 1077 | } |
1078 | rd->len = len; | 1078 | rd->len = len; |
1079 | 1079 | ||
@@ -1091,7 +1091,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1091 | SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { | 1091 | SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) { |
1092 | brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); | 1092 | brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n"); |
1093 | rd->len = 0; | 1093 | rd->len = 0; |
1094 | return false; | 1094 | return -EINVAL; |
1095 | } | 1095 | } |
1096 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); | 1096 | rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]); |
1097 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); | 1097 | rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]); |
@@ -1102,18 +1102,18 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1102 | bus->sdcnt.rx_toolong++; | 1102 | bus->sdcnt.rx_toolong++; |
1103 | brcmf_sdbrcm_rxfail(bus, false, false); | 1103 | brcmf_sdbrcm_rxfail(bus, false, false); |
1104 | rd->len = 0; | 1104 | rd->len = 0; |
1105 | return false; | 1105 | return -EPROTO; |
1106 | } | 1106 | } |
1107 | if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { | 1107 | if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) { |
1108 | brcmf_dbg(ERROR, "Wrong channel for superframe\n"); | 1108 | brcmf_dbg(ERROR, "Wrong channel for superframe\n"); |
1109 | rd->len = 0; | 1109 | rd->len = 0; |
1110 | return false; | 1110 | return -EINVAL; |
1111 | } | 1111 | } |
1112 | if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && | 1112 | if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL && |
1113 | rd->channel != SDPCM_EVENT_CHANNEL) { | 1113 | rd->channel != SDPCM_EVENT_CHANNEL) { |
1114 | brcmf_dbg(ERROR, "Wrong channel for subframe\n"); | 1114 | brcmf_dbg(ERROR, "Wrong channel for subframe\n"); |
1115 | rd->len = 0; | 1115 | rd->len = 0; |
1116 | return false; | 1116 | return -EINVAL; |
1117 | } | 1117 | } |
1118 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); | 1118 | rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]); |
1119 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { | 1119 | if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) { |
@@ -1121,7 +1121,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1121 | bus->sdcnt.rx_badhdr++; | 1121 | bus->sdcnt.rx_badhdr++; |
1122 | brcmf_sdbrcm_rxfail(bus, false, false); | 1122 | brcmf_sdbrcm_rxfail(bus, false, false); |
1123 | rd->len = 0; | 1123 | rd->len = 0; |
1124 | return false; | 1124 | return -ENXIO; |
1125 | } | 1125 | } |
1126 | if (rd->seq_num != rx_seq) { | 1126 | if (rd->seq_num != rx_seq) { |
1127 | brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", | 1127 | brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n", |
@@ -1131,7 +1131,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1131 | } | 1131 | } |
1132 | /* no need to check the reset for subframe */ | 1132 | /* no need to check the reset for subframe */ |
1133 | if (type == BRCMF_SDIO_FT_SUB) | 1133 | if (type == BRCMF_SDIO_FT_SUB) |
1134 | return true; | 1134 | return 0; |
1135 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; | 1135 | rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; |
1136 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { | 1136 | if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) { |
1137 | /* only warm for NON glom packet */ | 1137 | /* only warm for NON glom packet */ |
@@ -1155,7 +1155,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, | |||
1155 | } | 1155 | } |
1156 | bus->tx_max = tx_seq_max; | 1156 | bus->tx_max = tx_seq_max; |
1157 | 1157 | ||
1158 | return true; | 1158 | return 0; |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | 1161 | static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) |
@@ -1272,6 +1272,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1272 | * read directly into the chained packet, or allocate a large | 1272 | * read directly into the chained packet, or allocate a large |
1273 | * packet and and copy into the chain. | 1273 | * packet and and copy into the chain. |
1274 | */ | 1274 | */ |
1275 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1275 | if (usechain) { | 1276 | if (usechain) { |
1276 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, | 1277 | errcode = brcmf_sdcard_recv_chain(bus->sdiodev, |
1277 | bus->sdiodev->sbwad, | 1278 | bus->sdiodev->sbwad, |
@@ -1293,6 +1294,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1293 | dlen); | 1294 | dlen); |
1294 | errcode = -1; | 1295 | errcode = -1; |
1295 | } | 1296 | } |
1297 | sdio_release_host(bus->sdiodev->func[1]); | ||
1296 | bus->sdcnt.f2rxdata++; | 1298 | bus->sdcnt.f2rxdata++; |
1297 | 1299 | ||
1298 | /* On failure, kill the superframe, allow a couple retries */ | 1300 | /* On failure, kill the superframe, allow a couple retries */ |
@@ -1301,6 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1301 | dlen, errcode); | 1303 | dlen, errcode); |
1302 | bus->sdiodev->bus_if->dstats.rx_errors++; | 1304 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1303 | 1305 | ||
1306 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1304 | if (bus->glomerr++ < 3) { | 1307 | if (bus->glomerr++ < 3) { |
1305 | brcmf_sdbrcm_rxfail(bus, true, true); | 1308 | brcmf_sdbrcm_rxfail(bus, true, true); |
1306 | } else { | 1309 | } else { |
@@ -1309,6 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1309 | bus->sdcnt.rxglomfail++; | 1312 | bus->sdcnt.rxglomfail++; |
1310 | brcmf_sdbrcm_free_glom(bus); | 1313 | brcmf_sdbrcm_free_glom(bus); |
1311 | } | 1314 | } |
1315 | sdio_release_host(bus->sdiodev->func[1]); | ||
1312 | return 0; | 1316 | return 0; |
1313 | } | 1317 | } |
1314 | 1318 | ||
@@ -1318,8 +1322,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1318 | 1322 | ||
1319 | rd_new.seq_num = rxseq; | 1323 | rd_new.seq_num = rxseq; |
1320 | rd_new.len = dlen; | 1324 | rd_new.len = dlen; |
1321 | errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, | 1325 | sdio_claim_host(bus->sdiodev->func[1]); |
1322 | BRCMF_SDIO_FT_SUPER); | 1326 | errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new, |
1327 | BRCMF_SDIO_FT_SUPER); | ||
1328 | sdio_release_host(bus->sdiodev->func[1]); | ||
1323 | bus->cur_read.len = rd_new.len_nxtfrm << 4; | 1329 | bus->cur_read.len = rd_new.len_nxtfrm << 4; |
1324 | 1330 | ||
1325 | /* Remove superframe header, remember offset */ | 1331 | /* Remove superframe header, remember offset */ |
@@ -1335,9 +1341,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1335 | 1341 | ||
1336 | rd_new.len = pnext->len; | 1342 | rd_new.len = pnext->len; |
1337 | rd_new.seq_num = rxseq++; | 1343 | rd_new.seq_num = rxseq++; |
1338 | errcode = -!brcmf_sdio_hdparser(bus, pnext->data, | 1344 | sdio_claim_host(bus->sdiodev->func[1]); |
1339 | &rd_new, | 1345 | errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new, |
1340 | BRCMF_SDIO_FT_SUB); | 1346 | BRCMF_SDIO_FT_SUB); |
1347 | sdio_release_host(bus->sdiodev->func[1]); | ||
1341 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), | 1348 | brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), |
1342 | pnext->data, 32, "subframe:\n"); | 1349 | pnext->data, 32, "subframe:\n"); |
1343 | 1350 | ||
@@ -1347,6 +1354,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1347 | if (errcode) { | 1354 | if (errcode) { |
1348 | /* Terminate frame on error, request | 1355 | /* Terminate frame on error, request |
1349 | a couple retries */ | 1356 | a couple retries */ |
1357 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1350 | if (bus->glomerr++ < 3) { | 1358 | if (bus->glomerr++ < 3) { |
1351 | /* Restore superframe header space */ | 1359 | /* Restore superframe header space */ |
1352 | skb_push(pfirst, sfdoff); | 1360 | skb_push(pfirst, sfdoff); |
@@ -1357,6 +1365,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1357 | bus->sdcnt.rxglomfail++; | 1365 | bus->sdcnt.rxglomfail++; |
1358 | brcmf_sdbrcm_free_glom(bus); | 1366 | brcmf_sdbrcm_free_glom(bus); |
1359 | } | 1367 | } |
1368 | sdio_release_host(bus->sdiodev->func[1]); | ||
1360 | bus->cur_read.len = 0; | 1369 | bus->cur_read.len = 0; |
1361 | return 0; | 1370 | return 0; |
1362 | } | 1371 | } |
@@ -1397,11 +1406,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) | |||
1397 | pfirst->prev); | 1406 | pfirst->prev); |
1398 | } | 1407 | } |
1399 | /* sent any remaining packets up */ | 1408 | /* sent any remaining packets up */ |
1400 | if (bus->glom.qlen) { | 1409 | if (bus->glom.qlen) |
1401 | up(&bus->sdsem); | ||
1402 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); | 1410 | brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom); |
1403 | down(&bus->sdsem); | ||
1404 | } | ||
1405 | 1411 | ||
1406 | bus->sdcnt.rxglomframes++; | 1412 | bus->sdcnt.rxglomframes++; |
1407 | bus->sdcnt.rxglompkts += bus->glom.qlen; | 1413 | bus->sdcnt.rxglompkts += bus->glom.qlen; |
@@ -1442,21 +1448,24 @@ static void | |||
1442 | brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | 1448 | brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) |
1443 | { | 1449 | { |
1444 | uint rdlen, pad; | 1450 | uint rdlen, pad; |
1445 | 1451 | u8 *buf = NULL, *rbuf; | |
1446 | int sdret; | 1452 | int sdret; |
1447 | 1453 | ||
1448 | brcmf_dbg(TRACE, "Enter\n"); | 1454 | brcmf_dbg(TRACE, "Enter\n"); |
1449 | 1455 | ||
1450 | /* Set rxctl for frame (w/optional alignment) */ | 1456 | if (bus->rxblen) |
1451 | bus->rxctl = bus->rxbuf; | 1457 | buf = vzalloc(bus->rxblen); |
1452 | bus->rxctl += BRCMF_FIRSTREAD; | 1458 | if (!buf) { |
1453 | pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN); | 1459 | brcmf_dbg(ERROR, "no memory for control frame\n"); |
1460 | goto done; | ||
1461 | } | ||
1462 | rbuf = bus->rxbuf; | ||
1463 | pad = ((unsigned long)rbuf % BRCMF_SDALIGN); | ||
1454 | if (pad) | 1464 | if (pad) |
1455 | bus->rxctl += (BRCMF_SDALIGN - pad); | 1465 | rbuf += (BRCMF_SDALIGN - pad); |
1456 | bus->rxctl -= BRCMF_FIRSTREAD; | ||
1457 | 1466 | ||
1458 | /* Copy the already-read portion over */ | 1467 | /* Copy the already-read portion over */ |
1459 | memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD); | 1468 | memcpy(buf, hdr, BRCMF_FIRSTREAD); |
1460 | if (len <= BRCMF_FIRSTREAD) | 1469 | if (len <= BRCMF_FIRSTREAD) |
1461 | goto gotpkt; | 1470 | goto gotpkt; |
1462 | 1471 | ||
@@ -1493,11 +1502,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1493 | goto done; | 1502 | goto done; |
1494 | } | 1503 | } |
1495 | 1504 | ||
1496 | /* Read remainder of frame body into the rxctl buffer */ | 1505 | /* Read remain of frame body */ |
1497 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, | 1506 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, |
1498 | bus->sdiodev->sbwad, | 1507 | bus->sdiodev->sbwad, |
1499 | SDIO_FUNC_2, | 1508 | SDIO_FUNC_2, |
1500 | F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen); | 1509 | F2SYNC, rbuf, rdlen); |
1501 | bus->sdcnt.f2rxdata++; | 1510 | bus->sdcnt.f2rxdata++; |
1502 | 1511 | ||
1503 | /* Control frame failures need retransmission */ | 1512 | /* Control frame failures need retransmission */ |
@@ -1507,16 +1516,26 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) | |||
1507 | bus->sdcnt.rxc_errors++; | 1516 | bus->sdcnt.rxc_errors++; |
1508 | brcmf_sdbrcm_rxfail(bus, true, true); | 1517 | brcmf_sdbrcm_rxfail(bus, true, true); |
1509 | goto done; | 1518 | goto done; |
1510 | } | 1519 | } else |
1520 | memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen); | ||
1511 | 1521 | ||
1512 | gotpkt: | 1522 | gotpkt: |
1513 | 1523 | ||
1514 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), | 1524 | brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), |
1515 | bus->rxctl, len, "RxCtrl:\n"); | 1525 | buf, len, "RxCtrl:\n"); |
1516 | 1526 | ||
1517 | /* Point to valid data and indicate its length */ | 1527 | /* Point to valid data and indicate its length */ |
1518 | bus->rxctl += doff; | 1528 | spin_lock_bh(&bus->rxctl_lock); |
1529 | if (bus->rxctl) { | ||
1530 | brcmf_dbg(ERROR, "last control frame is being processed.\n"); | ||
1531 | spin_unlock_bh(&bus->rxctl_lock); | ||
1532 | vfree(buf); | ||
1533 | goto done; | ||
1534 | } | ||
1535 | bus->rxctl = buf + doff; | ||
1536 | bus->rxctl_orig = buf; | ||
1519 | bus->rxlen = len - doff; | 1537 | bus->rxlen = len - doff; |
1538 | spin_unlock_bh(&bus->rxctl_lock); | ||
1520 | 1539 | ||
1521 | done: | 1540 | done: |
1522 | /* Awake any waiters */ | 1541 | /* Awake any waiters */ |
@@ -1571,6 +1590,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1571 | 1590 | ||
1572 | rd->len_left = rd->len; | 1591 | rd->len_left = rd->len; |
1573 | /* read header first for unknow frame length */ | 1592 | /* read header first for unknow frame length */ |
1593 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1574 | if (!rd->len) { | 1594 | if (!rd->len) { |
1575 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, | 1595 | sdret = brcmf_sdcard_recv_buf(bus->sdiodev, |
1576 | bus->sdiodev->sbwad, | 1596 | bus->sdiodev->sbwad, |
@@ -1583,6 +1603,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1583 | sdret); | 1603 | sdret); |
1584 | bus->sdcnt.rx_hdrfail++; | 1604 | bus->sdcnt.rx_hdrfail++; |
1585 | brcmf_sdbrcm_rxfail(bus, true, true); | 1605 | brcmf_sdbrcm_rxfail(bus, true, true); |
1606 | sdio_release_host(bus->sdiodev->func[1]); | ||
1586 | continue; | 1607 | continue; |
1587 | } | 1608 | } |
1588 | 1609 | ||
@@ -1590,8 +1611,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1590 | bus->rxhdr, SDPCM_HDRLEN, | 1611 | bus->rxhdr, SDPCM_HDRLEN, |
1591 | "RxHdr:\n"); | 1612 | "RxHdr:\n"); |
1592 | 1613 | ||
1593 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd, | 1614 | if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd, |
1594 | BRCMF_SDIO_FT_NORMAL)) { | 1615 | BRCMF_SDIO_FT_NORMAL)) { |
1616 | sdio_release_host(bus->sdiodev->func[1]); | ||
1595 | if (!bus->rxpending) | 1617 | if (!bus->rxpending) |
1596 | break; | 1618 | break; |
1597 | else | 1619 | else |
@@ -1607,6 +1629,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1607 | rd->len_nxtfrm = 0; | 1629 | rd->len_nxtfrm = 0; |
1608 | /* treat all packet as event if we don't know */ | 1630 | /* treat all packet as event if we don't know */ |
1609 | rd->channel = SDPCM_EVENT_CHANNEL; | 1631 | rd->channel = SDPCM_EVENT_CHANNEL; |
1632 | sdio_release_host(bus->sdiodev->func[1]); | ||
1610 | continue; | 1633 | continue; |
1611 | } | 1634 | } |
1612 | rd->len_left = rd->len > BRCMF_FIRSTREAD ? | 1635 | rd->len_left = rd->len > BRCMF_FIRSTREAD ? |
@@ -1624,6 +1647,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1624 | bus->sdiodev->bus_if->dstats.rx_dropped++; | 1647 | bus->sdiodev->bus_if->dstats.rx_dropped++; |
1625 | brcmf_sdbrcm_rxfail(bus, false, | 1648 | brcmf_sdbrcm_rxfail(bus, false, |
1626 | RETRYCHAN(rd->channel)); | 1649 | RETRYCHAN(rd->channel)); |
1650 | sdio_release_host(bus->sdiodev->func[1]); | ||
1627 | continue; | 1651 | continue; |
1628 | } | 1652 | } |
1629 | skb_pull(pkt, head_read); | 1653 | skb_pull(pkt, head_read); |
@@ -1632,14 +1656,17 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1632 | sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, | 1656 | sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, |
1633 | SDIO_FUNC_2, F2SYNC, pkt); | 1657 | SDIO_FUNC_2, F2SYNC, pkt); |
1634 | bus->sdcnt.f2rxdata++; | 1658 | bus->sdcnt.f2rxdata++; |
1659 | sdio_release_host(bus->sdiodev->func[1]); | ||
1635 | 1660 | ||
1636 | if (sdret < 0) { | 1661 | if (sdret < 0) { |
1637 | brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", | 1662 | brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n", |
1638 | rd->len, rd->channel, sdret); | 1663 | rd->len, rd->channel, sdret); |
1639 | brcmu_pkt_buf_free_skb(pkt); | 1664 | brcmu_pkt_buf_free_skb(pkt); |
1640 | bus->sdiodev->bus_if->dstats.rx_errors++; | 1665 | bus->sdiodev->bus_if->dstats.rx_errors++; |
1666 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1641 | brcmf_sdbrcm_rxfail(bus, true, | 1667 | brcmf_sdbrcm_rxfail(bus, true, |
1642 | RETRYCHAN(rd->channel)); | 1668 | RETRYCHAN(rd->channel)); |
1669 | sdio_release_host(bus->sdiodev->func[1]); | ||
1643 | continue; | 1670 | continue; |
1644 | } | 1671 | } |
1645 | 1672 | ||
@@ -1650,8 +1677,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1650 | } else { | 1677 | } else { |
1651 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); | 1678 | memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN); |
1652 | rd_new.seq_num = rd->seq_num; | 1679 | rd_new.seq_num = rd->seq_num; |
1653 | if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, | 1680 | sdio_claim_host(bus->sdiodev->func[1]); |
1654 | BRCMF_SDIO_FT_NORMAL)) { | 1681 | if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new, |
1682 | BRCMF_SDIO_FT_NORMAL)) { | ||
1655 | rd->len = 0; | 1683 | rd->len = 0; |
1656 | brcmu_pkt_buf_free_skb(pkt); | 1684 | brcmu_pkt_buf_free_skb(pkt); |
1657 | } | 1685 | } |
@@ -1662,9 +1690,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1662 | roundup(rd_new.len, 16) >> 4); | 1690 | roundup(rd_new.len, 16) >> 4); |
1663 | rd->len = 0; | 1691 | rd->len = 0; |
1664 | brcmf_sdbrcm_rxfail(bus, true, true); | 1692 | brcmf_sdbrcm_rxfail(bus, true, true); |
1693 | sdio_release_host(bus->sdiodev->func[1]); | ||
1665 | brcmu_pkt_buf_free_skb(pkt); | 1694 | brcmu_pkt_buf_free_skb(pkt); |
1666 | continue; | 1695 | continue; |
1667 | } | 1696 | } |
1697 | sdio_release_host(bus->sdiodev->func[1]); | ||
1668 | rd->len_nxtfrm = rd_new.len_nxtfrm; | 1698 | rd->len_nxtfrm = rd_new.len_nxtfrm; |
1669 | rd->channel = rd_new.channel; | 1699 | rd->channel = rd_new.channel; |
1670 | rd->dat_offset = rd_new.dat_offset; | 1700 | rd->dat_offset = rd_new.dat_offset; |
@@ -1680,7 +1710,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1680 | rd_new.seq_num); | 1710 | rd_new.seq_num); |
1681 | /* Force retry w/normal header read */ | 1711 | /* Force retry w/normal header read */ |
1682 | rd->len = 0; | 1712 | rd->len = 0; |
1713 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1683 | brcmf_sdbrcm_rxfail(bus, false, true); | 1714 | brcmf_sdbrcm_rxfail(bus, false, true); |
1715 | sdio_release_host(bus->sdiodev->func[1]); | ||
1684 | brcmu_pkt_buf_free_skb(pkt); | 1716 | brcmu_pkt_buf_free_skb(pkt); |
1685 | continue; | 1717 | continue; |
1686 | } | 1718 | } |
@@ -1703,7 +1735,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1703 | } else { | 1735 | } else { |
1704 | brcmf_dbg(ERROR, "%s: glom superframe w/o " | 1736 | brcmf_dbg(ERROR, "%s: glom superframe w/o " |
1705 | "descriptor!\n", __func__); | 1737 | "descriptor!\n", __func__); |
1738 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1706 | brcmf_sdbrcm_rxfail(bus, false, false); | 1739 | brcmf_sdbrcm_rxfail(bus, false, false); |
1740 | sdio_release_host(bus->sdiodev->func[1]); | ||
1707 | } | 1741 | } |
1708 | /* prepare the descriptor for the next read */ | 1742 | /* prepare the descriptor for the next read */ |
1709 | rd->len = rd->len_nxtfrm << 4; | 1743 | rd->len = rd->len_nxtfrm << 4; |
@@ -1734,10 +1768,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1734 | continue; | 1768 | continue; |
1735 | } | 1769 | } |
1736 | 1770 | ||
1737 | /* Unlock during rx call */ | ||
1738 | up(&bus->sdsem); | ||
1739 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); | 1771 | brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); |
1740 | down(&bus->sdsem); | ||
1741 | } | 1772 | } |
1742 | 1773 | ||
1743 | rxcount = maxframes - rxleft; | 1774 | rxcount = maxframes - rxleft; |
@@ -1755,15 +1786,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes) | |||
1755 | } | 1786 | } |
1756 | 1787 | ||
1757 | static void | 1788 | static void |
1758 | brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar) | ||
1759 | { | ||
1760 | up(&bus->sdsem); | ||
1761 | wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2); | ||
1762 | down(&bus->sdsem); | ||
1763 | return; | ||
1764 | } | ||
1765 | |||
1766 | static void | ||
1767 | brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) | 1789 | brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) |
1768 | { | 1790 | { |
1769 | if (waitqueue_active(&bus->ctrl_wait)) | 1791 | if (waitqueue_active(&bus->ctrl_wait)) |
@@ -1864,6 +1886,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
1864 | if (len & (ALIGNMENT - 1)) | 1886 | if (len & (ALIGNMENT - 1)) |
1865 | len = roundup(len, ALIGNMENT); | 1887 | len = roundup(len, ALIGNMENT); |
1866 | 1888 | ||
1889 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1867 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, | 1890 | ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad, |
1868 | SDIO_FUNC_2, F2SYNC, pkt); | 1891 | SDIO_FUNC_2, F2SYNC, pkt); |
1869 | bus->sdcnt.f2txdata++; | 1892 | bus->sdcnt.f2txdata++; |
@@ -1891,15 +1914,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, | |||
1891 | } | 1914 | } |
1892 | 1915 | ||
1893 | } | 1916 | } |
1917 | sdio_release_host(bus->sdiodev->func[1]); | ||
1894 | if (ret == 0) | 1918 | if (ret == 0) |
1895 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | 1919 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; |
1896 | 1920 | ||
1897 | done: | 1921 | done: |
1898 | /* restore pkt buffer pointer before calling tx complete routine */ | 1922 | /* restore pkt buffer pointer before calling tx complete routine */ |
1899 | skb_pull(pkt, SDPCM_HDRLEN + pad); | 1923 | skb_pull(pkt, SDPCM_HDRLEN + pad); |
1900 | up(&bus->sdsem); | ||
1901 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); | 1924 | brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0); |
1902 | down(&bus->sdsem); | ||
1903 | 1925 | ||
1904 | if (free_pkt) | 1926 | if (free_pkt) |
1905 | brcmu_pkt_buf_free_skb(pkt); | 1927 | brcmu_pkt_buf_free_skb(pkt); |
@@ -1940,9 +1962,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes) | |||
1940 | /* In poll mode, need to check for other events */ | 1962 | /* In poll mode, need to check for other events */ |
1941 | if (!bus->intr && cnt) { | 1963 | if (!bus->intr && cnt) { |
1942 | /* Check device status, signal pending interrupt */ | 1964 | /* Check device status, signal pending interrupt */ |
1965 | sdio_claim_host(bus->sdiodev->func[1]); | ||
1943 | ret = r_sdreg32(bus, &intstatus, | 1966 | ret = r_sdreg32(bus, &intstatus, |
1944 | offsetof(struct sdpcmd_regs, | 1967 | offsetof(struct sdpcmd_regs, |
1945 | intstatus)); | 1968 | intstatus)); |
1969 | sdio_release_host(bus->sdiodev->func[1]); | ||
1946 | bus->sdcnt.f2txdata++; | 1970 | bus->sdcnt.f2txdata++; |
1947 | if (ret != 0) | 1971 | if (ret != 0) |
1948 | break; | 1972 | break; |
@@ -1979,7 +2003,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
1979 | bus->watchdog_tsk = NULL; | 2003 | bus->watchdog_tsk = NULL; |
1980 | } | 2004 | } |
1981 | 2005 | ||
1982 | down(&bus->sdsem); | 2006 | sdio_claim_host(bus->sdiodev->func[1]); |
1983 | 2007 | ||
1984 | /* Enable clock for device interrupts */ | 2008 | /* Enable clock for device interrupts */ |
1985 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2009 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
@@ -2013,6 +2037,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2013 | 2037 | ||
2014 | /* Turn off the backplane clock (only) */ | 2038 | /* Turn off the backplane clock (only) */ |
2015 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | 2039 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); |
2040 | sdio_release_host(bus->sdiodev->func[1]); | ||
2016 | 2041 | ||
2017 | /* Clear the data packet queues */ | 2042 | /* Clear the data packet queues */ |
2018 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); | 2043 | brcmu_pktq_flush(&bus->txq, true, NULL, NULL); |
@@ -2023,14 +2048,14 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev) | |||
2023 | brcmf_sdbrcm_free_glom(bus); | 2048 | brcmf_sdbrcm_free_glom(bus); |
2024 | 2049 | ||
2025 | /* Clear rx control and wake any waiters */ | 2050 | /* Clear rx control and wake any waiters */ |
2051 | spin_lock_bh(&bus->rxctl_lock); | ||
2026 | bus->rxlen = 0; | 2052 | bus->rxlen = 0; |
2053 | spin_unlock_bh(&bus->rxctl_lock); | ||
2027 | brcmf_sdbrcm_dcmd_resp_wake(bus); | 2054 | brcmf_sdbrcm_dcmd_resp_wake(bus); |
2028 | 2055 | ||
2029 | /* Reset some F2 state stuff */ | 2056 | /* Reset some F2 state stuff */ |
2030 | bus->rxskip = false; | 2057 | bus->rxskip = false; |
2031 | bus->tx_seq = bus->rx_seq = 0; | 2058 | bus->tx_seq = bus->rx_seq = 0; |
2032 | |||
2033 | up(&bus->sdsem); | ||
2034 | } | 2059 | } |
2035 | 2060 | ||
2036 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB | 2061 | #ifdef CONFIG_BRCMFMAC_SDIO_OOB |
@@ -2114,7 +2139,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2114 | 2139 | ||
2115 | brcmf_dbg(TRACE, "Enter\n"); | 2140 | brcmf_dbg(TRACE, "Enter\n"); |
2116 | 2141 | ||
2117 | down(&bus->sdsem); | 2142 | sdio_claim_host(bus->sdiodev->func[1]); |
2118 | 2143 | ||
2119 | /* If waiting for HTAVAIL, check status */ | 2144 | /* If waiting for HTAVAIL, check status */ |
2120 | if (bus->clkstate == CLK_PENDING) { | 2145 | if (bus->clkstate == CLK_PENDING) { |
@@ -2168,9 +2193,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2168 | /* Pending interrupt indicates new device status */ | 2193 | /* Pending interrupt indicates new device status */ |
2169 | if (atomic_read(&bus->ipend) > 0) { | 2194 | if (atomic_read(&bus->ipend) > 0) { |
2170 | atomic_set(&bus->ipend, 0); | 2195 | atomic_set(&bus->ipend, 0); |
2171 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2172 | err = brcmf_sdio_intr_rstatus(bus); | 2196 | err = brcmf_sdio_intr_rstatus(bus); |
2173 | sdio_release_host(bus->sdiodev->func[1]); | ||
2174 | } | 2197 | } |
2175 | 2198 | ||
2176 | /* Start with leftover status bits */ | 2199 | /* Start with leftover status bits */ |
@@ -2199,6 +2222,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2199 | intstatus |= brcmf_sdbrcm_hostmail(bus); | 2222 | intstatus |= brcmf_sdbrcm_hostmail(bus); |
2200 | } | 2223 | } |
2201 | 2224 | ||
2225 | sdio_release_host(bus->sdiodev->func[1]); | ||
2226 | |||
2202 | /* Generally don't ask for these, can get CRC errors... */ | 2227 | /* Generally don't ask for these, can get CRC errors... */ |
2203 | if (intstatus & I_WR_OOSYNC) { | 2228 | if (intstatus & I_WR_OOSYNC) { |
2204 | brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); | 2229 | brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); |
@@ -2245,6 +2270,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2245 | (bus->clkstate == CLK_AVAIL)) { | 2270 | (bus->clkstate == CLK_AVAIL)) { |
2246 | int i; | 2271 | int i; |
2247 | 2272 | ||
2273 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2248 | err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, | 2274 | err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, |
2249 | SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, | 2275 | SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, |
2250 | (u32) bus->ctrl_frame_len); | 2276 | (u32) bus->ctrl_frame_len); |
@@ -2278,6 +2304,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2278 | } else { | 2304 | } else { |
2279 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; | 2305 | bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; |
2280 | } | 2306 | } |
2307 | sdio_release_host(bus->sdiodev->func[1]); | ||
2281 | bus->ctrl_frame_stat = false; | 2308 | bus->ctrl_frame_stat = false; |
2282 | brcmf_sdbrcm_wait_event_wakeup(bus); | 2309 | brcmf_sdbrcm_wait_event_wakeup(bus); |
2283 | } | 2310 | } |
@@ -2307,10 +2334,10 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) | |||
2307 | if ((bus->clkstate != CLK_PENDING) | 2334 | if ((bus->clkstate != CLK_PENDING) |
2308 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { | 2335 | && bus->idletime == BRCMF_IDLE_IMMEDIATE) { |
2309 | bus->activity = false; | 2336 | bus->activity = false; |
2337 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2310 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 2338 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
2339 | sdio_release_host(bus->sdiodev->func[1]); | ||
2311 | } | 2340 | } |
2312 | |||
2313 | up(&bus->sdsem); | ||
2314 | } | 2341 | } |
2315 | 2342 | ||
2316 | static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) | 2343 | static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) |
@@ -2601,11 +2628,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2601 | 2628 | ||
2602 | /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ | 2629 | /* precondition: IS_ALIGNED((unsigned long)frame, 2) */ |
2603 | 2630 | ||
2604 | /* Need to lock here to protect txseq and SDIO tx calls */ | ||
2605 | down(&bus->sdsem); | ||
2606 | |||
2607 | /* Make sure backplane clock is on */ | 2631 | /* Make sure backplane clock is on */ |
2632 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2608 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 2633 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
2634 | sdio_release_host(bus->sdiodev->func[1]); | ||
2609 | 2635 | ||
2610 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ | 2636 | /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ |
2611 | *(__le16 *) frame = cpu_to_le16((u16) msglen); | 2637 | *(__le16 *) frame = cpu_to_le16((u16) msglen); |
@@ -2628,7 +2654,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2628 | bus->ctrl_frame_buf = frame; | 2654 | bus->ctrl_frame_buf = frame; |
2629 | bus->ctrl_frame_len = len; | 2655 | bus->ctrl_frame_len = len; |
2630 | 2656 | ||
2631 | brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); | 2657 | wait_event_interruptible_timeout(bus->ctrl_wait, |
2658 | !bus->ctrl_frame_stat, | ||
2659 | msecs_to_jiffies(2000)); | ||
2632 | 2660 | ||
2633 | if (!bus->ctrl_frame_stat) { | 2661 | if (!bus->ctrl_frame_stat) { |
2634 | brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); | 2662 | brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); |
@@ -2647,7 +2675,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2647 | frame, min_t(u16, len, 16), "TxHdr:\n"); | 2675 | frame, min_t(u16, len, 16), "TxHdr:\n"); |
2648 | 2676 | ||
2649 | do { | 2677 | do { |
2678 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2650 | ret = brcmf_tx_frame(bus, frame, len); | 2679 | ret = brcmf_tx_frame(bus, frame, len); |
2680 | sdio_release_host(bus->sdiodev->func[1]); | ||
2651 | } while (ret < 0 && retries++ < TXRETRIES); | 2681 | } while (ret < 0 && retries++ < TXRETRIES); |
2652 | } | 2682 | } |
2653 | 2683 | ||
@@ -2657,13 +2687,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2657 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); | 2687 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); |
2658 | 2688 | ||
2659 | bus->activity = false; | 2689 | bus->activity = false; |
2690 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2660 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); | 2691 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); |
2692 | sdio_release_host(bus->sdiodev->func[1]); | ||
2661 | } else { | 2693 | } else { |
2662 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); | 2694 | spin_unlock_irqrestore(&bus->dpc_tl_lock, flags); |
2663 | } | 2695 | } |
2664 | 2696 | ||
2665 | up(&bus->sdsem); | ||
2666 | |||
2667 | if (ret) | 2697 | if (ret) |
2668 | bus->sdcnt.tx_ctlerrs++; | 2698 | bus->sdcnt.tx_ctlerrs++; |
2669 | else | 2699 | else |
@@ -2693,8 +2723,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
2693 | * Read last word in socram to determine | 2723 | * Read last word in socram to determine |
2694 | * address of sdpcm_shared structure | 2724 | * address of sdpcm_shared structure |
2695 | */ | 2725 | */ |
2726 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2696 | rv = brcmf_sdbrcm_membytes(bus, false, shaddr, | 2727 | rv = brcmf_sdbrcm_membytes(bus, false, shaddr, |
2697 | (u8 *)&addr_le, 4); | 2728 | (u8 *)&addr_le, 4); |
2729 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2698 | if (rv < 0) | 2730 | if (rv < 0) |
2699 | return rv; | 2731 | return rv; |
2700 | 2732 | ||
@@ -2713,8 +2745,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
2713 | } | 2745 | } |
2714 | 2746 | ||
2715 | /* Read hndrte_shared structure */ | 2747 | /* Read hndrte_shared structure */ |
2748 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2716 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, | 2749 | rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, |
2717 | sizeof(struct sdpcm_shared_le)); | 2750 | sizeof(struct sdpcm_shared_le)); |
2751 | sdio_release_host(bus->sdiodev->func[1]); | ||
2718 | if (rv < 0) | 2752 | if (rv < 0) |
2719 | return rv; | 2753 | return rv; |
2720 | 2754 | ||
@@ -2817,12 +2851,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh, | |||
2817 | if ((sh->flags & SDPCM_SHARED_TRAP) == 0) | 2851 | if ((sh->flags & SDPCM_SHARED_TRAP) == 0) |
2818 | return 0; | 2852 | return 0; |
2819 | 2853 | ||
2854 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2820 | error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, | 2855 | error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, |
2821 | sizeof(struct brcmf_trap_info)); | 2856 | sizeof(struct brcmf_trap_info)); |
2822 | if (error < 0) | 2857 | if (error < 0) |
2823 | return error; | 2858 | return error; |
2824 | 2859 | ||
2825 | nbytes = brcmf_sdio_dump_console(bus, sh, data, count); | 2860 | nbytes = brcmf_sdio_dump_console(bus, sh, data, count); |
2861 | sdio_release_host(bus->sdiodev->func[1]); | ||
2826 | if (nbytes < 0) | 2862 | if (nbytes < 0) |
2827 | return nbytes; | 2863 | return nbytes; |
2828 | 2864 | ||
@@ -2868,6 +2904,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, | |||
2868 | return 0; | 2904 | return 0; |
2869 | } | 2905 | } |
2870 | 2906 | ||
2907 | sdio_claim_host(bus->sdiodev->func[1]); | ||
2871 | if (sh->assert_file_addr != 0) { | 2908 | if (sh->assert_file_addr != 0) { |
2872 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, | 2909 | error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, |
2873 | (u8 *)file, 80); | 2910 | (u8 *)file, 80); |
@@ -2880,6 +2917,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus, | |||
2880 | if (error < 0) | 2917 | if (error < 0) |
2881 | return error; | 2918 | return error; |
2882 | } | 2919 | } |
2920 | sdio_release_host(bus->sdiodev->func[1]); | ||
2883 | 2921 | ||
2884 | res = scnprintf(buf, sizeof(buf), | 2922 | res = scnprintf(buf, sizeof(buf), |
2885 | "dongle assert: %s:%d: assert(%s)\n", | 2923 | "dongle assert: %s:%d: assert(%s)\n", |
@@ -2892,9 +2930,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus) | |||
2892 | int error; | 2930 | int error; |
2893 | struct sdpcm_shared sh; | 2931 | struct sdpcm_shared sh; |
2894 | 2932 | ||
2895 | down(&bus->sdsem); | ||
2896 | error = brcmf_sdio_readshared(bus, &sh); | 2933 | error = brcmf_sdio_readshared(bus, &sh); |
2897 | up(&bus->sdsem); | ||
2898 | 2934 | ||
2899 | if (error < 0) | 2935 | if (error < 0) |
2900 | return error; | 2936 | return error; |
@@ -2921,7 +2957,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, | |||
2921 | if (pos != 0) | 2957 | if (pos != 0) |
2922 | return 0; | 2958 | return 0; |
2923 | 2959 | ||
2924 | down(&bus->sdsem); | ||
2925 | error = brcmf_sdio_readshared(bus, &sh); | 2960 | error = brcmf_sdio_readshared(bus, &sh); |
2926 | if (error < 0) | 2961 | if (error < 0) |
2927 | goto done; | 2962 | goto done; |
@@ -2938,7 +2973,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data, | |||
2938 | error += nbytes; | 2973 | error += nbytes; |
2939 | *ppos += error; | 2974 | *ppos += error; |
2940 | done: | 2975 | done: |
2941 | up(&bus->sdsem); | ||
2942 | return error; | 2976 | return error; |
2943 | } | 2977 | } |
2944 | 2978 | ||
@@ -2989,6 +3023,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2989 | int timeleft; | 3023 | int timeleft; |
2990 | uint rxlen = 0; | 3024 | uint rxlen = 0; |
2991 | bool pending; | 3025 | bool pending; |
3026 | u8 *buf; | ||
2992 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); | 3027 | struct brcmf_bus *bus_if = dev_get_drvdata(dev); |
2993 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; | 3028 | struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; |
2994 | struct brcmf_sdio *bus = sdiodev->bus; | 3029 | struct brcmf_sdio *bus = sdiodev->bus; |
@@ -2998,11 +3033,15 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen) | |||
2998 | /* Wait until control frame is available */ | 3033 | /* Wait until control frame is available */ |
2999 | timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); | 3034 | timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending); |
3000 | 3035 | ||
3001 | down(&bus->sdsem); | 3036 | spin_lock_bh(&bus->rxctl_lock); |
3002 | rxlen = bus->rxlen; | 3037 | rxlen = bus->rxlen; |
3003 | memcpy(msg, bus->rxctl, min(msglen, rxlen)); | 3038 | memcpy(msg, bus->rxctl, min(msglen, rxlen)); |
3039 | bus->rxctl = NULL; | ||
3040 | buf = bus->rxctl_orig; | ||
3041 | bus->rxctl_orig = NULL; | ||
3004 | bus->rxlen = 0; | 3042 | bus->rxlen = 0; |
3005 | up(&bus->sdsem); | 3043 | spin_unlock_bh(&bus->rxctl_lock); |
3044 | vfree(buf); | ||
3006 | 3045 | ||
3007 | if (rxlen) { | 3046 | if (rxlen) { |
3008 | brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", | 3047 | brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", |
@@ -3338,13 +3377,16 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus) | |||
3338 | { | 3377 | { |
3339 | bool ret; | 3378 | bool ret; |
3340 | 3379 | ||
3341 | /* Download the firmware */ | 3380 | sdio_claim_host(bus->sdiodev->func[1]); |
3381 | |||
3342 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3382 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3343 | 3383 | ||
3344 | ret = _brcmf_sdbrcm_download_firmware(bus) == 0; | 3384 | ret = _brcmf_sdbrcm_download_firmware(bus) == 0; |
3345 | 3385 | ||
3346 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); | 3386 | brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); |
3347 | 3387 | ||
3388 | sdio_release_host(bus->sdiodev->func[1]); | ||
3389 | |||
3348 | return ret; | 3390 | return ret; |
3349 | } | 3391 | } |
3350 | 3392 | ||
@@ -3373,7 +3415,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3373 | bus->sdcnt.tickcnt = 0; | 3415 | bus->sdcnt.tickcnt = 0; |
3374 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3416 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
3375 | 3417 | ||
3376 | down(&bus->sdsem); | 3418 | sdio_claim_host(bus->sdiodev->func[1]); |
3377 | 3419 | ||
3378 | /* Make sure backplane clock is on, needed to generate F2 interrupt */ | 3420 | /* Make sure backplane clock is on, needed to generate F2 interrupt */ |
3379 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3421 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
@@ -3442,7 +3484,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev) | |||
3442 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3484 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3443 | 3485 | ||
3444 | exit: | 3486 | exit: |
3445 | up(&bus->sdsem); | 3487 | sdio_release_host(bus->sdiodev->func[1]); |
3446 | 3488 | ||
3447 | return ret; | 3489 | return ret; |
3448 | } | 3490 | } |
@@ -3489,8 +3531,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3489 | 3531 | ||
3490 | brcmf_dbg(TIMER, "Enter\n"); | 3532 | brcmf_dbg(TIMER, "Enter\n"); |
3491 | 3533 | ||
3492 | down(&bus->sdsem); | ||
3493 | |||
3494 | /* Poll period: check device if appropriate. */ | 3534 | /* Poll period: check device if appropriate. */ |
3495 | if (bus->poll && (++bus->polltick >= bus->pollrate)) { | 3535 | if (bus->poll && (++bus->polltick >= bus->pollrate)) { |
3496 | u32 intstatus = 0; | 3536 | u32 intstatus = 0; |
@@ -3507,9 +3547,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3507 | u8 devpend; | 3547 | u8 devpend; |
3508 | spin_unlock_irqrestore(&bus->dpc_tl_lock, | 3548 | spin_unlock_irqrestore(&bus->dpc_tl_lock, |
3509 | flags); | 3549 | flags); |
3550 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3510 | devpend = brcmf_sdio_regrb(bus->sdiodev, | 3551 | devpend = brcmf_sdio_regrb(bus->sdiodev, |
3511 | SDIO_CCCR_INTx, | 3552 | SDIO_CCCR_INTx, |
3512 | NULL); | 3553 | NULL); |
3554 | sdio_release_host(bus->sdiodev->func[1]); | ||
3513 | intstatus = | 3555 | intstatus = |
3514 | devpend & (INTR_STATUS_FUNC1 | | 3556 | devpend & (INTR_STATUS_FUNC1 | |
3515 | INTR_STATUS_FUNC2); | 3557 | INTR_STATUS_FUNC2); |
@@ -3534,16 +3576,18 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3534 | } | 3576 | } |
3535 | #ifdef DEBUG | 3577 | #ifdef DEBUG |
3536 | /* Poll for console output periodically */ | 3578 | /* Poll for console output periodically */ |
3537 | if (bus_if->state == BRCMF_BUS_DATA && | 3579 | if (bus_if && bus_if->state == BRCMF_BUS_DATA && |
3538 | bus->console_interval != 0) { | 3580 | bus->console_interval != 0) { |
3539 | bus->console.count += BRCMF_WD_POLL_MS; | 3581 | bus->console.count += BRCMF_WD_POLL_MS; |
3540 | if (bus->console.count >= bus->console_interval) { | 3582 | if (bus->console.count >= bus->console_interval) { |
3541 | bus->console.count -= bus->console_interval; | 3583 | bus->console.count -= bus->console_interval; |
3584 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3542 | /* Make sure backplane clock is on */ | 3585 | /* Make sure backplane clock is on */ |
3543 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3586 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3544 | if (brcmf_sdbrcm_readconsole(bus) < 0) | 3587 | if (brcmf_sdbrcm_readconsole(bus) < 0) |
3545 | /* stop on error */ | 3588 | /* stop on error */ |
3546 | bus->console_interval = 0; | 3589 | bus->console_interval = 0; |
3590 | sdio_release_host(bus->sdiodev->func[1]); | ||
3547 | } | 3591 | } |
3548 | } | 3592 | } |
3549 | #endif /* DEBUG */ | 3593 | #endif /* DEBUG */ |
@@ -3556,13 +3600,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) | |||
3556 | bus->activity = false; | 3600 | bus->activity = false; |
3557 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); | 3601 | brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS); |
3558 | } else { | 3602 | } else { |
3603 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3559 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3604 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3605 | sdio_release_host(bus->sdiodev->func[1]); | ||
3560 | } | 3606 | } |
3561 | } | 3607 | } |
3562 | } | 3608 | } |
3563 | 3609 | ||
3564 | up(&bus->sdsem); | ||
3565 | |||
3566 | return (atomic_read(&bus->ipend) > 0); | 3610 | return (atomic_read(&bus->ipend) > 0); |
3567 | } | 3611 | } |
3568 | 3612 | ||
@@ -3657,6 +3701,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3657 | 3701 | ||
3658 | bus->alp_only = true; | 3702 | bus->alp_only = true; |
3659 | 3703 | ||
3704 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3705 | |||
3660 | pr_debug("F1 signature read @0x18000000=0x%4x\n", | 3706 | pr_debug("F1 signature read @0x18000000=0x%4x\n", |
3661 | brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); | 3707 | brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); |
3662 | 3708 | ||
@@ -3704,6 +3750,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3704 | reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); | 3750 | reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL); |
3705 | brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); | 3751 | brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL); |
3706 | 3752 | ||
3753 | sdio_release_host(bus->sdiodev->func[1]); | ||
3754 | |||
3707 | brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); | 3755 | brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); |
3708 | 3756 | ||
3709 | /* Locate an appropriately-aligned portion of hdrbuf */ | 3757 | /* Locate an appropriately-aligned portion of hdrbuf */ |
@@ -3719,6 +3767,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) | |||
3719 | return true; | 3767 | return true; |
3720 | 3768 | ||
3721 | fail: | 3769 | fail: |
3770 | sdio_release_host(bus->sdiodev->func[1]); | ||
3722 | return false; | 3771 | return false; |
3723 | } | 3772 | } |
3724 | 3773 | ||
@@ -3726,6 +3775,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3726 | { | 3775 | { |
3727 | brcmf_dbg(TRACE, "Enter\n"); | 3776 | brcmf_dbg(TRACE, "Enter\n"); |
3728 | 3777 | ||
3778 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3779 | |||
3729 | /* Disable F2 to clear any intermediate frame state on the dongle */ | 3780 | /* Disable F2 to clear any intermediate frame state on the dongle */ |
3730 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, | 3781 | brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx, |
3731 | SDIO_FUNC_ENABLE_1, NULL); | 3782 | SDIO_FUNC_ENABLE_1, NULL); |
@@ -3736,6 +3787,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus) | |||
3736 | /* Done with backplane-dependent accesses, can drop clock... */ | 3787 | /* Done with backplane-dependent accesses, can drop clock... */ |
3737 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); | 3788 | brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); |
3738 | 3789 | ||
3790 | sdio_release_host(bus->sdiodev->func[1]); | ||
3791 | |||
3739 | /* ...and initialize clock/power states */ | 3792 | /* ...and initialize clock/power states */ |
3740 | bus->clkstate = CLK_SDONLY; | 3793 | bus->clkstate = CLK_SDONLY; |
3741 | bus->idletime = BRCMF_IDLE_INTERVAL; | 3794 | bus->idletime = BRCMF_IDLE_INTERVAL; |
@@ -3791,8 +3844,10 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus) | |||
3791 | brcmf_dbg(TRACE, "Enter\n"); | 3844 | brcmf_dbg(TRACE, "Enter\n"); |
3792 | 3845 | ||
3793 | if (bus->ci) { | 3846 | if (bus->ci) { |
3847 | sdio_claim_host(bus->sdiodev->func[1]); | ||
3794 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); | 3848 | brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); |
3795 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); | 3849 | brcmf_sdbrcm_clkctl(bus, CLK_NONE, false); |
3850 | sdio_release_host(bus->sdiodev->func[1]); | ||
3796 | brcmf_sdio_chip_detach(&bus->ci); | 3851 | brcmf_sdio_chip_detach(&bus->ci); |
3797 | if (bus->vars && bus->varsz) | 3852 | if (bus->vars && bus->varsz) |
3798 | kfree(bus->vars); | 3853 | kfree(bus->vars); |
@@ -3812,7 +3867,8 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus) | |||
3812 | brcmf_sdio_intr_unregister(bus->sdiodev); | 3867 | brcmf_sdio_intr_unregister(bus->sdiodev); |
3813 | 3868 | ||
3814 | cancel_work_sync(&bus->datawork); | 3869 | cancel_work_sync(&bus->datawork); |
3815 | destroy_workqueue(bus->brcmf_wq); | 3870 | if (bus->brcmf_wq) |
3871 | destroy_workqueue(bus->brcmf_wq); | ||
3816 | 3872 | ||
3817 | if (bus->sdiodev->bus_if->drvr) { | 3873 | if (bus->sdiodev->bus_if->drvr) { |
3818 | brcmf_detach(bus->sdiodev->dev); | 3874 | brcmf_detach(bus->sdiodev->dev); |
@@ -3854,31 +3910,29 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3854 | bus->txminmax = BRCMF_TXMINMAX; | 3910 | bus->txminmax = BRCMF_TXMINMAX; |
3855 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; | 3911 | bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; |
3856 | 3912 | ||
3913 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3914 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3915 | if (bus->brcmf_wq == NULL) { | ||
3916 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3917 | goto fail; | ||
3918 | } | ||
3919 | |||
3857 | /* attempt to attach to the dongle */ | 3920 | /* attempt to attach to the dongle */ |
3858 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { | 3921 | if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { |
3859 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); | 3922 | brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); |
3860 | goto fail; | 3923 | goto fail; |
3861 | } | 3924 | } |
3862 | 3925 | ||
3926 | spin_lock_init(&bus->rxctl_lock); | ||
3863 | spin_lock_init(&bus->txqlock); | 3927 | spin_lock_init(&bus->txqlock); |
3864 | init_waitqueue_head(&bus->ctrl_wait); | 3928 | init_waitqueue_head(&bus->ctrl_wait); |
3865 | init_waitqueue_head(&bus->dcmd_resp_wait); | 3929 | init_waitqueue_head(&bus->dcmd_resp_wait); |
3866 | 3930 | ||
3867 | bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq"); | ||
3868 | if (bus->brcmf_wq == NULL) { | ||
3869 | brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n"); | ||
3870 | goto fail; | ||
3871 | } | ||
3872 | INIT_WORK(&bus->datawork, brcmf_sdio_dataworker); | ||
3873 | |||
3874 | /* Set up the watchdog timer */ | 3931 | /* Set up the watchdog timer */ |
3875 | init_timer(&bus->timer); | 3932 | init_timer(&bus->timer); |
3876 | bus->timer.data = (unsigned long)bus; | 3933 | bus->timer.data = (unsigned long)bus; |
3877 | bus->timer.function = brcmf_sdbrcm_watchdog; | 3934 | bus->timer.function = brcmf_sdbrcm_watchdog; |
3878 | 3935 | ||
3879 | /* Initialize thread based operation and lock */ | ||
3880 | sema_init(&bus->sdsem, 1); | ||
3881 | |||
3882 | /* Initialize watchdog thread */ | 3936 | /* Initialize watchdog thread */ |
3883 | init_completion(&bus->watchdog_wait); | 3937 | init_completion(&bus->watchdog_wait); |
3884 | bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, | 3938 | bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, |
@@ -3941,10 +3995,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) | |||
3941 | /* if firmware path present try to download and bring up bus */ | 3995 | /* if firmware path present try to download and bring up bus */ |
3942 | ret = brcmf_bus_start(bus->sdiodev->dev); | 3996 | ret = brcmf_bus_start(bus->sdiodev->dev); |
3943 | if (ret != 0) { | 3997 | if (ret != 0) { |
3944 | if (ret == -ENOLINK) { | 3998 | brcmf_dbg(ERROR, "dongle is not responding\n"); |
3945 | brcmf_dbg(ERROR, "dongle is not responding\n"); | 3999 | goto fail; |
3946 | goto fail; | ||
3947 | } | ||
3948 | } | 4000 | } |
3949 | 4001 | ||
3950 | return bus; | 4002 | return bus; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c new file mode 100644 index 000000000000..fa8fc4433417 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c | |||
@@ -0,0 +1,509 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #include <linux/netdevice.h> | ||
17 | |||
18 | #include "brcmu_wifi.h" | ||
19 | #include "brcmu_utils.h" | ||
20 | |||
21 | #include "dhd.h" | ||
22 | #include "dhd_dbg.h" | ||
23 | #include "fweh.h" | ||
24 | #include "fwil.h" | ||
25 | |||
26 | /** | ||
27 | * struct brcm_ethhdr - broadcom specific ether header. | ||
28 | * | ||
29 | * @subtype: subtype for this packet. | ||
30 | * @length: TODO: length of appended data. | ||
31 | * @version: version indication. | ||
32 | * @oui: OUI of this packet. | ||
33 | * @usr_subtype: subtype for this OUI. | ||
34 | */ | ||
35 | struct brcm_ethhdr { | ||
36 | __be16 subtype; | ||
37 | __be16 length; | ||
38 | u8 version; | ||
39 | u8 oui[3]; | ||
40 | __be16 usr_subtype; | ||
41 | } __packed; | ||
42 | |||
43 | struct brcmf_event_msg_be { | ||
44 | __be16 version; | ||
45 | __be16 flags; | ||
46 | __be32 event_type; | ||
47 | __be32 status; | ||
48 | __be32 reason; | ||
49 | __be32 auth_type; | ||
50 | __be32 datalen; | ||
51 | u8 addr[ETH_ALEN]; | ||
52 | char ifname[IFNAMSIZ]; | ||
53 | u8 ifidx; | ||
54 | u8 bsscfgidx; | ||
55 | } __packed; | ||
56 | |||
57 | /** | ||
58 | * struct brcmf_event - contents of broadcom event packet. | ||
59 | * | ||
60 | * @eth: standard ether header. | ||
61 | * @hdr: broadcom specific ether header. | ||
62 | * @msg: common part of the actual event message. | ||
63 | */ | ||
64 | struct brcmf_event { | ||
65 | struct ethhdr eth; | ||
66 | struct brcm_ethhdr hdr; | ||
67 | struct brcmf_event_msg_be msg; | ||
68 | } __packed; | ||
69 | |||
70 | /** | ||
71 | * struct brcmf_fweh_queue_item - event item on event queue. | ||
72 | * | ||
73 | * @q: list element for queuing. | ||
74 | * @code: event code. | ||
75 | * @ifidx: interface index related to this event. | ||
76 | * @ifaddr: ethernet address for interface. | ||
77 | * @emsg: common parameters of the firmware event message. | ||
78 | * @data: event specific data part of the firmware event. | ||
79 | */ | ||
80 | struct brcmf_fweh_queue_item { | ||
81 | struct list_head q; | ||
82 | enum brcmf_fweh_event_code code; | ||
83 | u8 ifidx; | ||
84 | u8 ifaddr[ETH_ALEN]; | ||
85 | struct brcmf_event_msg_be emsg; | ||
86 | u8 data[0]; | ||
87 | }; | ||
88 | |||
89 | /** | ||
90 | * struct brcmf_fweh_event_name - code, name mapping entry. | ||
91 | */ | ||
92 | struct brcmf_fweh_event_name { | ||
93 | enum brcmf_fweh_event_code code; | ||
94 | const char *name; | ||
95 | }; | ||
96 | |||
97 | #ifdef DEBUG | ||
98 | /* array for mapping code to event name */ | ||
99 | static struct brcmf_fweh_event_name fweh_event_names[] = { | ||
100 | { BRCMF_E_SET_SSID, "SET_SSID" }, | ||
101 | { BRCMF_E_JOIN, "JOIN" }, | ||
102 | { BRCMF_E_START, "START" }, | ||
103 | { BRCMF_E_AUTH, "AUTH" }, | ||
104 | { BRCMF_E_AUTH_IND, "AUTH_IND" }, | ||
105 | { BRCMF_E_DEAUTH, "DEAUTH" }, | ||
106 | { BRCMF_E_DEAUTH_IND, "DEAUTH_IND" }, | ||
107 | { BRCMF_E_ASSOC, "ASSOC" }, | ||
108 | { BRCMF_E_ASSOC_IND, "ASSOC_IND" }, | ||
109 | { BRCMF_E_REASSOC, "REASSOC" }, | ||
110 | { BRCMF_E_REASSOC_IND, "REASSOC_IND" }, | ||
111 | { BRCMF_E_DISASSOC, "DISASSOC" }, | ||
112 | { BRCMF_E_DISASSOC_IND, "DISASSOC_IND" }, | ||
113 | { BRCMF_E_QUIET_START, "START_QUIET" }, | ||
114 | { BRCMF_E_QUIET_END, "END_QUIET" }, | ||
115 | { BRCMF_E_BEACON_RX, "BEACON_RX" }, | ||
116 | { BRCMF_E_LINK, "LINK" }, | ||
117 | { BRCMF_E_MIC_ERROR, "MIC_ERROR" }, | ||
118 | { BRCMF_E_NDIS_LINK, "NDIS_LINK" }, | ||
119 | { BRCMF_E_ROAM, "ROAM" }, | ||
120 | { BRCMF_E_TXFAIL, "TXFAIL" }, | ||
121 | { BRCMF_E_PMKID_CACHE, "PMKID_CACHE" }, | ||
122 | { BRCMF_E_RETROGRADE_TSF, "RETROGRADE_TSF" }, | ||
123 | { BRCMF_E_PRUNE, "PRUNE" }, | ||
124 | { BRCMF_E_AUTOAUTH, "AUTOAUTH" }, | ||
125 | { BRCMF_E_EAPOL_MSG, "EAPOL_MSG" }, | ||
126 | { BRCMF_E_SCAN_COMPLETE, "SCAN_COMPLETE" }, | ||
127 | { BRCMF_E_ADDTS_IND, "ADDTS_IND" }, | ||
128 | { BRCMF_E_DELTS_IND, "DELTS_IND" }, | ||
129 | { BRCMF_E_BCNSENT_IND, "BCNSENT_IND" }, | ||
130 | { BRCMF_E_BCNRX_MSG, "BCNRX_MSG" }, | ||
131 | { BRCMF_E_BCNLOST_MSG, "BCNLOST_MSG" }, | ||
132 | { BRCMF_E_ROAM_PREP, "ROAM_PREP" }, | ||
133 | { BRCMF_E_PFN_NET_FOUND, "PNO_NET_FOUND" }, | ||
134 | { BRCMF_E_PFN_NET_LOST, "PNO_NET_LOST" }, | ||
135 | { BRCMF_E_RESET_COMPLETE, "RESET_COMPLETE" }, | ||
136 | { BRCMF_E_JOIN_START, "JOIN_START" }, | ||
137 | { BRCMF_E_ROAM_START, "ROAM_START" }, | ||
138 | { BRCMF_E_ASSOC_START, "ASSOC_START" }, | ||
139 | { BRCMF_E_IBSS_ASSOC, "IBSS_ASSOC" }, | ||
140 | { BRCMF_E_RADIO, "RADIO" }, | ||
141 | { BRCMF_E_PSM_WATCHDOG, "PSM_WATCHDOG" }, | ||
142 | { BRCMF_E_PROBREQ_MSG, "PROBREQ_MSG" }, | ||
143 | { BRCMF_E_SCAN_CONFIRM_IND, "SCAN_CONFIRM_IND" }, | ||
144 | { BRCMF_E_PSK_SUP, "PSK_SUP" }, | ||
145 | { BRCMF_E_COUNTRY_CODE_CHANGED, "COUNTRY_CODE_CHANGED" }, | ||
146 | { BRCMF_E_EXCEEDED_MEDIUM_TIME, "EXCEEDED_MEDIUM_TIME" }, | ||
147 | { BRCMF_E_ICV_ERROR, "ICV_ERROR" }, | ||
148 | { BRCMF_E_UNICAST_DECODE_ERROR, "UNICAST_DECODE_ERROR" }, | ||
149 | { BRCMF_E_MULTICAST_DECODE_ERROR, "MULTICAST_DECODE_ERROR" }, | ||
150 | { BRCMF_E_TRACE, "TRACE" }, | ||
151 | { BRCMF_E_IF, "IF" }, | ||
152 | { BRCMF_E_RSSI, "RSSI" }, | ||
153 | { BRCMF_E_PFN_SCAN_COMPLETE, "PFN_SCAN_COMPLETE" }, | ||
154 | { BRCMF_E_EXTLOG_MSG, "EXTLOG_MSG" }, | ||
155 | { BRCMF_E_ACTION_FRAME, "ACTION_FRAME" }, | ||
156 | { BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION_FRAME_COMPLETE" }, | ||
157 | { BRCMF_E_PRE_ASSOC_IND, "PRE_ASSOC_IND" }, | ||
158 | { BRCMF_E_PRE_REASSOC_IND, "PRE_REASSOC_IND" }, | ||
159 | { BRCMF_E_CHANNEL_ADOPTED, "CHANNEL_ADOPTED" }, | ||
160 | { BRCMF_E_AP_STARTED, "AP_STARTED" }, | ||
161 | { BRCMF_E_DFS_AP_STOP, "DFS_AP_STOP" }, | ||
162 | { BRCMF_E_DFS_AP_RESUME, "DFS_AP_RESUME" }, | ||
163 | { BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT" }, | ||
164 | { BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE, "ACTION_FRM_OFF_CHAN_CMPLT" }, | ||
165 | { BRCMF_E_DCS_REQUEST, "DCS_REQUEST" }, | ||
166 | { BRCMF_E_FIFO_CREDIT_MAP, "FIFO_CREDIT_MAP"} | ||
167 | }; | ||
168 | |||
169 | /** | ||
170 | * brcmf_fweh_event_name() - returns name for given event code. | ||
171 | * | ||
172 | * @code: code to lookup. | ||
173 | */ | ||
174 | static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) | ||
175 | { | ||
176 | int i; | ||
177 | for (i = 0; i < ARRAY_SIZE(fweh_event_names); i++) { | ||
178 | if (fweh_event_names[i].code == code) | ||
179 | return fweh_event_names[i].name; | ||
180 | } | ||
181 | return "unknown"; | ||
182 | } | ||
183 | #else | ||
184 | static const char *brcmf_fweh_event_name(enum brcmf_fweh_event_code code) | ||
185 | { | ||
186 | return "nodebug"; | ||
187 | } | ||
188 | #endif | ||
189 | |||
190 | /** | ||
191 | * brcmf_fweh_queue_event() - create and queue event. | ||
192 | * | ||
193 | * @fweh: firmware event handling info. | ||
194 | * @event: event queue entry. | ||
195 | */ | ||
196 | static void brcmf_fweh_queue_event(struct brcmf_fweh_info *fweh, | ||
197 | struct brcmf_fweh_queue_item *event) | ||
198 | { | ||
199 | ulong flags; | ||
200 | |||
201 | spin_lock_irqsave(&fweh->evt_q_lock, flags); | ||
202 | list_add_tail(&event->q, &fweh->event_q); | ||
203 | spin_unlock_irqrestore(&fweh->evt_q_lock, flags); | ||
204 | schedule_work(&fweh->event_work); | ||
205 | } | ||
206 | |||
207 | static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, | ||
208 | enum brcmf_fweh_event_code code, | ||
209 | struct brcmf_event_msg *emsg, | ||
210 | void *data) | ||
211 | { | ||
212 | struct brcmf_fweh_info *fweh; | ||
213 | int err = -EINVAL; | ||
214 | |||
215 | if (ifp) { | ||
216 | fweh = &ifp->drvr->fweh; | ||
217 | |||
218 | /* handle the event if valid interface and handler */ | ||
219 | if (ifp->ndev && fweh->evt_handler[code]) | ||
220 | err = fweh->evt_handler[code](ifp, emsg, data); | ||
221 | else | ||
222 | brcmf_dbg(ERROR, "unhandled event %d ignored\n", code); | ||
223 | } else { | ||
224 | brcmf_dbg(ERROR, "no interface object\n"); | ||
225 | } | ||
226 | return err; | ||
227 | } | ||
228 | |||
229 | /** | ||
230 | * brcmf_fweh_handle_if_event() - handle IF event. | ||
231 | * | ||
232 | * @drvr: driver information object. | ||
233 | * @item: queue entry. | ||
234 | * @ifpp: interface object (may change upon ADD action). | ||
235 | */ | ||
236 | static void brcmf_fweh_handle_if_event(struct brcmf_pub *drvr, | ||
237 | struct brcmf_event_msg *emsg, | ||
238 | void *data) | ||
239 | { | ||
240 | struct brcmf_if_event *ifevent = data; | ||
241 | struct brcmf_if *ifp; | ||
242 | int err = 0; | ||
243 | |||
244 | brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u\n", | ||
245 | ifevent->action, ifevent->ifidx, | ||
246 | ifevent->bssidx, ifevent->flags); | ||
247 | |||
248 | if (ifevent->ifidx >= BRCMF_MAX_IFS) { | ||
249 | brcmf_dbg(ERROR, "invalid interface index: %u\n", | ||
250 | ifevent->ifidx); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | ifp = drvr->iflist[ifevent->ifidx]; | ||
255 | |||
256 | if (ifevent->action == BRCMF_E_IF_ADD) { | ||
257 | brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname, | ||
258 | emsg->addr); | ||
259 | ifp = brcmf_add_if(drvr, ifevent->ifidx, ifevent->bssidx, | ||
260 | emsg->ifname, emsg->addr); | ||
261 | if (IS_ERR(ifp)) | ||
262 | return; | ||
263 | |||
264 | if (!drvr->fweh.evt_handler[BRCMF_E_IF]) | ||
265 | err = brcmf_net_attach(ifp); | ||
266 | } | ||
267 | |||
268 | err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); | ||
269 | |||
270 | if (ifevent->action == BRCMF_E_IF_DEL) | ||
271 | brcmf_del_if(drvr, ifevent->ifidx); | ||
272 | } | ||
273 | |||
274 | /** | ||
275 | * brcmf_fweh_dequeue_event() - get event from the queue. | ||
276 | * | ||
277 | * @fweh: firmware event handling info. | ||
278 | */ | ||
279 | static struct brcmf_fweh_queue_item * | ||
280 | brcmf_fweh_dequeue_event(struct brcmf_fweh_info *fweh) | ||
281 | { | ||
282 | struct brcmf_fweh_queue_item *event = NULL; | ||
283 | ulong flags; | ||
284 | |||
285 | spin_lock_irqsave(&fweh->evt_q_lock, flags); | ||
286 | if (!list_empty(&fweh->event_q)) { | ||
287 | event = list_first_entry(&fweh->event_q, | ||
288 | struct brcmf_fweh_queue_item, q); | ||
289 | list_del(&event->q); | ||
290 | } | ||
291 | spin_unlock_irqrestore(&fweh->evt_q_lock, flags); | ||
292 | |||
293 | return event; | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * brcmf_fweh_event_worker() - firmware event worker. | ||
298 | * | ||
299 | * @work: worker object. | ||
300 | */ | ||
301 | static void brcmf_fweh_event_worker(struct work_struct *work) | ||
302 | { | ||
303 | struct brcmf_pub *drvr; | ||
304 | struct brcmf_if *ifp; | ||
305 | struct brcmf_fweh_info *fweh; | ||
306 | struct brcmf_fweh_queue_item *event; | ||
307 | int err = 0; | ||
308 | struct brcmf_event_msg_be *emsg_be; | ||
309 | struct brcmf_event_msg emsg; | ||
310 | |||
311 | fweh = container_of(work, struct brcmf_fweh_info, event_work); | ||
312 | drvr = container_of(fweh, struct brcmf_pub, fweh); | ||
313 | |||
314 | while ((event = brcmf_fweh_dequeue_event(fweh))) { | ||
315 | ifp = drvr->iflist[event->ifidx]; | ||
316 | |||
317 | brcmf_dbg(EVENT, "event %s (%u) ifidx %u bsscfg %u addr %pM:\n", | ||
318 | brcmf_fweh_event_name(event->code), event->code, | ||
319 | event->emsg.ifidx, event->emsg.bsscfgidx, | ||
320 | event->emsg.addr); | ||
321 | |||
322 | /* convert event message */ | ||
323 | emsg_be = &event->emsg; | ||
324 | emsg.version = be16_to_cpu(emsg_be->version); | ||
325 | emsg.flags = be16_to_cpu(emsg_be->flags); | ||
326 | emsg.event_code = event->code; | ||
327 | emsg.status = be32_to_cpu(emsg_be->status); | ||
328 | emsg.reason = be32_to_cpu(emsg_be->reason); | ||
329 | emsg.auth_type = be32_to_cpu(emsg_be->auth_type); | ||
330 | emsg.datalen = be32_to_cpu(emsg_be->datalen); | ||
331 | memcpy(emsg.addr, emsg_be->addr, ETH_ALEN); | ||
332 | memcpy(emsg.ifname, emsg_be->ifname, sizeof(emsg.ifname)); | ||
333 | emsg.ifidx = emsg_be->ifidx; | ||
334 | emsg.bsscfgidx = emsg_be->bsscfgidx; | ||
335 | |||
336 | brcmf_dbg(EVENT, " version %u flags %u status %u reason %u\n", | ||
337 | emsg.version, emsg.flags, emsg.status, emsg.reason); | ||
338 | brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, | ||
339 | min_t(u32, emsg.datalen, 64), | ||
340 | "appended:"); | ||
341 | |||
342 | /* special handling of interface event */ | ||
343 | if (event->code == BRCMF_E_IF) { | ||
344 | brcmf_fweh_handle_if_event(drvr, &emsg, event->data); | ||
345 | goto event_free; | ||
346 | } | ||
347 | |||
348 | err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, | ||
349 | event->data); | ||
350 | if (err) { | ||
351 | brcmf_dbg(ERROR, "event handler failed (%d)\n", | ||
352 | event->code); | ||
353 | err = 0; | ||
354 | } | ||
355 | event_free: | ||
356 | kfree(event); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /** | ||
361 | * brcmf_fweh_attach() - initialize firmware event handling. | ||
362 | * | ||
363 | * @drvr: driver information object. | ||
364 | */ | ||
365 | void brcmf_fweh_attach(struct brcmf_pub *drvr) | ||
366 | { | ||
367 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
368 | INIT_WORK(&fweh->event_work, brcmf_fweh_event_worker); | ||
369 | spin_lock_init(&fweh->evt_q_lock); | ||
370 | INIT_LIST_HEAD(&fweh->event_q); | ||
371 | } | ||
372 | |||
373 | /** | ||
374 | * brcmf_fweh_detach() - cleanup firmware event handling. | ||
375 | * | ||
376 | * @drvr: driver information object. | ||
377 | */ | ||
378 | void brcmf_fweh_detach(struct brcmf_pub *drvr) | ||
379 | { | ||
380 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
381 | struct brcmf_if *ifp = drvr->iflist[0]; | ||
382 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
383 | |||
384 | if (ifp) { | ||
385 | /* clear all events */ | ||
386 | memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); | ||
387 | (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||
388 | eventmask, | ||
389 | BRCMF_EVENTING_MASK_LEN); | ||
390 | } | ||
391 | /* cancel the worker */ | ||
392 | cancel_work_sync(&fweh->event_work); | ||
393 | WARN_ON(!list_empty(&fweh->event_q)); | ||
394 | memset(fweh->evt_handler, 0, sizeof(fweh->evt_handler)); | ||
395 | } | ||
396 | |||
397 | /** | ||
398 | * brcmf_fweh_register() - register handler for given event code. | ||
399 | * | ||
400 | * @drvr: driver information object. | ||
401 | * @code: event code. | ||
402 | * @handler: handler for the given event code. | ||
403 | */ | ||
404 | int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, | ||
405 | brcmf_fweh_handler_t handler) | ||
406 | { | ||
407 | if (drvr->fweh.evt_handler[code]) { | ||
408 | brcmf_dbg(ERROR, "event code %d already registered\n", code); | ||
409 | return -ENOSPC; | ||
410 | } | ||
411 | drvr->fweh.evt_handler[code] = handler; | ||
412 | brcmf_dbg(TRACE, "event handler registered for %s\n", | ||
413 | brcmf_fweh_event_name(code)); | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | /** | ||
418 | * brcmf_fweh_unregister() - remove handler for given code. | ||
419 | * | ||
420 | * @drvr: driver information object. | ||
421 | * @code: event code. | ||
422 | */ | ||
423 | void brcmf_fweh_unregister(struct brcmf_pub *drvr, | ||
424 | enum brcmf_fweh_event_code code) | ||
425 | { | ||
426 | brcmf_dbg(TRACE, "event handler cleared for %s\n", | ||
427 | brcmf_fweh_event_name(code)); | ||
428 | drvr->fweh.evt_handler[code] = NULL; | ||
429 | } | ||
430 | |||
431 | /** | ||
432 | * brcmf_fweh_activate_events() - enables firmware events registered. | ||
433 | * | ||
434 | * @ifp: primary interface object. | ||
435 | */ | ||
436 | int brcmf_fweh_activate_events(struct brcmf_if *ifp) | ||
437 | { | ||
438 | int i, err; | ||
439 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
440 | |||
441 | for (i = 0; i < BRCMF_E_LAST; i++) { | ||
442 | if (ifp->drvr->fweh.evt_handler[i]) { | ||
443 | brcmf_dbg(EVENT, "enable event %s\n", | ||
444 | brcmf_fweh_event_name(i)); | ||
445 | setbit(eventmask, i); | ||
446 | } | ||
447 | } | ||
448 | |||
449 | /* want to handle IF event as well */ | ||
450 | brcmf_dbg(EVENT, "enable event IF\n"); | ||
451 | setbit(eventmask, BRCMF_E_IF); | ||
452 | |||
453 | err = brcmf_fil_iovar_data_set(ifp, "event_msgs", | ||
454 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
455 | if (err) | ||
456 | brcmf_dbg(ERROR, "Set event_msgs error (%d)\n", err); | ||
457 | |||
458 | return err; | ||
459 | } | ||
460 | |||
461 | /** | ||
462 | * brcmf_fweh_process_event() - process skb as firmware event. | ||
463 | * | ||
464 | * @drvr: driver information object. | ||
465 | * @event_packet: event packet to process. | ||
466 | * @ifidx: index of the firmware interface (may change). | ||
467 | * | ||
468 | * If the packet buffer contains a firmware event message it will | ||
469 | * dispatch the event to a registered handler (using worker). | ||
470 | */ | ||
471 | void brcmf_fweh_process_event(struct brcmf_pub *drvr, | ||
472 | struct brcmf_event *event_packet, u8 *ifidx) | ||
473 | { | ||
474 | enum brcmf_fweh_event_code code; | ||
475 | struct brcmf_fweh_info *fweh = &drvr->fweh; | ||
476 | struct brcmf_fweh_queue_item *event; | ||
477 | gfp_t alloc_flag = GFP_KERNEL; | ||
478 | void *data; | ||
479 | u32 datalen; | ||
480 | |||
481 | /* get event info */ | ||
482 | code = get_unaligned_be32(&event_packet->msg.event_type); | ||
483 | datalen = get_unaligned_be32(&event_packet->msg.datalen); | ||
484 | *ifidx = event_packet->msg.ifidx; | ||
485 | data = &event_packet[1]; | ||
486 | |||
487 | if (code >= BRCMF_E_LAST) | ||
488 | return; | ||
489 | |||
490 | if (code != BRCMF_E_IF && !fweh->evt_handler[code]) | ||
491 | return; | ||
492 | |||
493 | if (in_interrupt()) | ||
494 | alloc_flag = GFP_ATOMIC; | ||
495 | |||
496 | event = kzalloc(sizeof(*event) + datalen, alloc_flag); | ||
497 | if (!event) | ||
498 | return; | ||
499 | |||
500 | event->code = code; | ||
501 | event->ifidx = *ifidx; | ||
502 | |||
503 | /* use memcpy to get aligned event message */ | ||
504 | memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); | ||
505 | memcpy(event->data, data, datalen); | ||
506 | memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); | ||
507 | |||
508 | brcmf_fweh_queue_event(fweh, event); | ||
509 | } | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h new file mode 100644 index 000000000000..b39246a630df --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h | |||
@@ -0,0 +1,207 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2012 Broadcom Corporation | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
11 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
13 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | |||
18 | #ifndef FWEH_H_ | ||
19 | #define FWEH_H_ | ||
20 | |||
21 | #include <asm/unaligned.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/if_ether.h> | ||
24 | #include <linux/if.h> | ||
25 | |||
26 | /* formward declarations */ | ||
27 | struct brcmf_pub; | ||
28 | struct brcmf_if; | ||
29 | struct brcmf_cfg80211_info; | ||
30 | struct brcmf_event; | ||
31 | |||
32 | /* firmware event codes sent by the dongle */ | ||
33 | enum brcmf_fweh_event_code { | ||
34 | BRCMF_E_SET_SSID = 0, | ||
35 | BRCMF_E_JOIN = 1, | ||
36 | BRCMF_E_START = 2, | ||
37 | BRCMF_E_AUTH = 3, | ||
38 | BRCMF_E_AUTH_IND = 4, | ||
39 | BRCMF_E_DEAUTH = 5, | ||
40 | BRCMF_E_DEAUTH_IND = 6, | ||
41 | BRCMF_E_ASSOC = 7, | ||
42 | BRCMF_E_ASSOC_IND = 8, | ||
43 | BRCMF_E_REASSOC = 9, | ||
44 | BRCMF_E_REASSOC_IND = 10, | ||
45 | BRCMF_E_DISASSOC = 11, | ||
46 | BRCMF_E_DISASSOC_IND = 12, | ||
47 | BRCMF_E_QUIET_START = 13, | ||
48 | BRCMF_E_QUIET_END = 14, | ||
49 | BRCMF_E_BEACON_RX = 15, | ||
50 | BRCMF_E_LINK = 16, | ||
51 | BRCMF_E_MIC_ERROR = 17, | ||
52 | BRCMF_E_NDIS_LINK = 18, | ||
53 | BRCMF_E_ROAM = 19, | ||
54 | BRCMF_E_TXFAIL = 20, | ||
55 | BRCMF_E_PMKID_CACHE = 21, | ||
56 | BRCMF_E_RETROGRADE_TSF = 22, | ||
57 | BRCMF_E_PRUNE = 23, | ||
58 | BRCMF_E_AUTOAUTH = 24, | ||
59 | BRCMF_E_EAPOL_MSG = 25, | ||
60 | BRCMF_E_SCAN_COMPLETE = 26, | ||
61 | BRCMF_E_ADDTS_IND = 27, | ||
62 | BRCMF_E_DELTS_IND = 28, | ||
63 | BRCMF_E_BCNSENT_IND = 29, | ||
64 | BRCMF_E_BCNRX_MSG = 30, | ||
65 | BRCMF_E_BCNLOST_MSG = 31, | ||
66 | BRCMF_E_ROAM_PREP = 32, | ||
67 | BRCMF_E_PFN_NET_FOUND = 33, | ||
68 | BRCMF_E_PFN_NET_LOST = 34, | ||
69 | BRCMF_E_RESET_COMPLETE = 35, | ||
70 | BRCMF_E_JOIN_START = 36, | ||
71 | BRCMF_E_ROAM_START = 37, | ||
72 | BRCMF_E_ASSOC_START = 38, | ||
73 | BRCMF_E_IBSS_ASSOC = 39, | ||
74 | BRCMF_E_RADIO = 40, | ||
75 | BRCMF_E_PSM_WATCHDOG = 41, | ||
76 | BRCMF_E_PROBREQ_MSG = 44, | ||
77 | BRCMF_E_SCAN_CONFIRM_IND = 45, | ||
78 | BRCMF_E_PSK_SUP = 46, | ||
79 | BRCMF_E_COUNTRY_CODE_CHANGED = 47, | ||
80 | BRCMF_E_EXCEEDED_MEDIUM_TIME = 48, | ||
81 | BRCMF_E_ICV_ERROR = 49, | ||
82 | BRCMF_E_UNICAST_DECODE_ERROR = 50, | ||
83 | BRCMF_E_MULTICAST_DECODE_ERROR = 51, | ||
84 | BRCMF_E_TRACE = 52, | ||
85 | BRCMF_E_IF = 54, | ||
86 | BRCMF_E_RSSI = 56, | ||
87 | BRCMF_E_PFN_SCAN_COMPLETE = 57, | ||
88 | BRCMF_E_EXTLOG_MSG = 58, | ||
89 | BRCMF_E_ACTION_FRAME = 59, | ||
90 | BRCMF_E_ACTION_FRAME_COMPLETE = 60, | ||
91 | BRCMF_E_PRE_ASSOC_IND = 61, | ||
92 | BRCMF_E_PRE_REASSOC_IND = 62, | ||
93 | BRCMF_E_CHANNEL_ADOPTED = 63, | ||
94 | BRCMF_E_AP_STARTED = 64, | ||
95 | BRCMF_E_DFS_AP_STOP = 65, | ||
96 | BRCMF_E_DFS_AP_RESUME = 66, | ||
97 | BRCMF_E_ESCAN_RESULT = 69, | ||
98 | BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE = 70, | ||
99 | BRCMF_E_DCS_REQUEST = 73, | ||
100 | BRCMF_E_FIFO_CREDIT_MAP = 74, | ||
101 | BRCMF_E_LAST | ||
102 | }; | ||
103 | |||
104 | /* flags field values in struct brcmf_event_msg */ | ||
105 | #define BRCMF_EVENT_MSG_LINK 0x01 | ||
106 | #define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 | ||
107 | #define BRCMF_EVENT_MSG_GROUP 0x04 | ||
108 | |||
109 | /** | ||
110 | * definitions for event packet validation. | ||
111 | */ | ||
112 | #define BRCMF_EVENT_OUI_OFFSET 19 | ||
113 | #define BRCM_OUI "\x00\x10\x18" | ||
114 | #define DOT11_OUI_LEN 3 | ||
115 | #define BCMILCP_BCM_SUBTYPE_EVENT 1 | ||
116 | |||
117 | |||
118 | /** | ||
119 | * struct brcmf_event_msg - firmware event message. | ||
120 | * | ||
121 | * @version: version information. | ||
122 | * @flags: event flags. | ||
123 | * @event_code: firmware event code. | ||
124 | * @status: status information. | ||
125 | * @reason: reason code. | ||
126 | * @auth_type: authentication type. | ||
127 | * @datalen: lenght of event data buffer. | ||
128 | * @addr: ether address. | ||
129 | * @ifname: interface name. | ||
130 | * @ifidx: interface index. | ||
131 | * @bsscfgidx: bsscfg index. | ||
132 | */ | ||
133 | struct brcmf_event_msg { | ||
134 | u16 version; | ||
135 | u16 flags; | ||
136 | u32 event_code; | ||
137 | u32 status; | ||
138 | u32 reason; | ||
139 | s32 auth_type; | ||
140 | u32 datalen; | ||
141 | u8 addr[ETH_ALEN]; | ||
142 | char ifname[IFNAMSIZ]; | ||
143 | u8 ifidx; | ||
144 | u8 bsscfgidx; | ||
145 | }; | ||
146 | |||
147 | typedef int (*brcmf_fweh_handler_t)(struct brcmf_if *ifp, | ||
148 | const struct brcmf_event_msg *evtmsg, | ||
149 | void *data); | ||
150 | |||
151 | /** | ||
152 | * struct brcmf_fweh_info - firmware event handling information. | ||
153 | * | ||
154 | * @event_work: event worker. | ||
155 | * @evt_q_lock: lock for event queue protection. | ||
156 | * @event_q: event queue. | ||
157 | * @evt_handler: registered event handlers. | ||
158 | */ | ||
159 | struct brcmf_fweh_info { | ||
160 | struct work_struct event_work; | ||
161 | struct spinlock evt_q_lock; | ||
162 | struct list_head event_q; | ||
163 | int (*evt_handler[BRCMF_E_LAST])(struct brcmf_if *ifp, | ||
164 | const struct brcmf_event_msg *evtmsg, | ||
165 | void *data); | ||
166 | }; | ||
167 | |||
168 | void brcmf_fweh_attach(struct brcmf_pub *drvr); | ||
169 | void brcmf_fweh_detach(struct brcmf_pub *drvr); | ||
170 | int brcmf_fweh_register(struct brcmf_pub *drvr, enum brcmf_fweh_event_code code, | ||
171 | int (*handler)(struct brcmf_if *ifp, | ||
172 | const struct brcmf_event_msg *evtmsg, | ||
173 | void *data)); | ||
174 | void brcmf_fweh_unregister(struct brcmf_pub *drvr, | ||
175 | enum brcmf_fweh_event_code code); | ||
176 | int brcmf_fweh_activate_events(struct brcmf_if *ifp); | ||
177 | void brcmf_fweh_process_event(struct brcmf_pub *drvr, | ||
178 | struct brcmf_event *event_packet, u8 *ifidx); | ||
179 | |||
180 | static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, | ||
181 | struct sk_buff *skb, u8 *ifidx) | ||
182 | { | ||
183 | struct brcmf_event *event_packet; | ||
184 | u8 *data; | ||
185 | u16 usr_stype; | ||
186 | |||
187 | /* only process events when protocol matches */ | ||
188 | if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) | ||
189 | return; | ||
190 | |||
191 | /* check for BRCM oui match */ | ||
192 | event_packet = (struct brcmf_event *)skb_mac_header(skb); | ||
193 | data = (u8 *)event_packet; | ||
194 | data += BRCMF_EVENT_OUI_OFFSET; | ||
195 | if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) | ||
196 | return; | ||
197 | |||
198 | /* final match on usr_subtype */ | ||
199 | data += DOT11_OUI_LEN; | ||
200 | usr_stype = get_unaligned_be16(data); | ||
201 | if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) | ||
202 | return; | ||
203 | |||
204 | brcmf_fweh_process_event(drvr, event_packet, ifidx); | ||
205 | } | ||
206 | |||
207 | #endif /* FWEH_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c index 4b272c3d237c..51a14505197a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/netdevice.h> | 22 | #include <linux/netdevice.h> |
23 | #include <defs.h> | ||
24 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
25 | #include <brcmu_wifi.h> | 24 | #include <brcmu_wifi.h> |
26 | #include "dhd.h" | 25 | #include "dhd.h" |
@@ -29,13 +28,16 @@ | |||
29 | #include "fwil.h" | 28 | #include "fwil.h" |
30 | 29 | ||
31 | 30 | ||
31 | #define MAX_HEX_DUMP_LEN 64 | ||
32 | |||
33 | |||
32 | static s32 | 34 | static s32 |
33 | brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) | 35 | brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) |
34 | { | 36 | { |
35 | struct brcmf_pub *drvr = ifp->drvr; | 37 | struct brcmf_pub *drvr = ifp->drvr; |
36 | s32 err; | 38 | s32 err; |
37 | 39 | ||
38 | if (drvr->bus_if->state == BRCMF_BUS_DOWN) { | 40 | if (drvr->bus_if->state != BRCMF_BUS_DATA) { |
39 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); | 41 | brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); |
40 | return -EIO; | 42 | return -EIO; |
41 | } | 43 | } |
@@ -64,7 +66,8 @@ brcmf_fil_cmd_data_set(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | |||
64 | mutex_lock(&ifp->drvr->proto_block); | 66 | mutex_lock(&ifp->drvr->proto_block); |
65 | 67 | ||
66 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | 68 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); |
67 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 69 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
70 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
68 | 71 | ||
69 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); | 72 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, true); |
70 | mutex_unlock(&ifp->drvr->proto_block); | 73 | mutex_unlock(&ifp->drvr->proto_block); |
@@ -81,7 +84,8 @@ brcmf_fil_cmd_data_get(struct brcmf_if *ifp, u32 cmd, void *data, u32 len) | |||
81 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); | 84 | err = brcmf_fil_cmd_data(ifp, cmd, data, len, false); |
82 | 85 | ||
83 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); | 86 | brcmf_dbg(FIL, "cmd=%d, len=%d\n", cmd, len); |
84 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 87 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
88 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
85 | 89 | ||
86 | mutex_unlock(&ifp->drvr->proto_block); | 90 | mutex_unlock(&ifp->drvr->proto_block); |
87 | 91 | ||
@@ -147,7 +151,8 @@ brcmf_fil_iovar_data_set(struct brcmf_if *ifp, char *name, void *data, | |||
147 | mutex_lock(&drvr->proto_block); | 151 | mutex_lock(&drvr->proto_block); |
148 | 152 | ||
149 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | 153 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); |
150 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 154 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
155 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
151 | 156 | ||
152 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, | 157 | buflen = brcmf_create_iovar(name, data, len, drvr->proto_buf, |
153 | sizeof(drvr->proto_buf)); | 158 | sizeof(drvr->proto_buf)); |
@@ -186,7 +191,8 @@ brcmf_fil_iovar_data_get(struct brcmf_if *ifp, char *name, void *data, | |||
186 | } | 191 | } |
187 | 192 | ||
188 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); | 193 | brcmf_dbg(FIL, "name=%s, len=%d\n", name, len); |
189 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 194 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
195 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
190 | 196 | ||
191 | mutex_unlock(&drvr->proto_block); | 197 | mutex_unlock(&drvr->proto_block); |
192 | return err; | 198 | return err; |
@@ -268,7 +274,8 @@ brcmf_fil_bsscfg_data_set(struct brcmf_if *ifp, char *name, | |||
268 | mutex_lock(&drvr->proto_block); | 274 | mutex_lock(&drvr->proto_block); |
269 | 275 | ||
270 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | 276 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); |
271 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 277 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
278 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
272 | 279 | ||
273 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, | 280 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, |
274 | drvr->proto_buf, sizeof(drvr->proto_buf)); | 281 | drvr->proto_buf, sizeof(drvr->proto_buf)); |
@@ -294,7 +301,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, | |||
294 | 301 | ||
295 | mutex_lock(&drvr->proto_block); | 302 | mutex_lock(&drvr->proto_block); |
296 | 303 | ||
297 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len, | 304 | buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len, |
298 | drvr->proto_buf, sizeof(drvr->proto_buf)); | 305 | drvr->proto_buf, sizeof(drvr->proto_buf)); |
299 | if (buflen) { | 306 | if (buflen) { |
300 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, | 307 | err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf, |
@@ -306,7 +313,8 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name, | |||
306 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); | 313 | brcmf_dbg(ERROR, "Creating bsscfg failed\n"); |
307 | } | 314 | } |
308 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); | 315 | brcmf_dbg(FIL, "bssidx=%d, name=%s, len=%d\n", ifp->bssidx, name, len); |
309 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, len, "data"); | 316 | brcmf_dbg_hex_dump(BRCMF_FIL_ON(), data, |
317 | min_t(uint, len, MAX_HEX_DUMP_LEN), "data"); | ||
310 | 318 | ||
311 | mutex_unlock(&drvr->proto_block); | 319 | mutex_unlock(&drvr->proto_block); |
312 | return err; | 320 | return err; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c index 484a6e4f23a2..39a5baa92f21 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c | |||
@@ -14,24 +14,12 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
20 | #include <linux/kthread.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/netdevice.h> | ||
24 | #include <linux/spinlock.h> | ||
25 | #include <linux/ethtool.h> | ||
26 | #include <linux/fcntl.h> | ||
27 | #include <linux/fs.h> | ||
28 | #include <linux/uaccess.h> | ||
29 | #include <linux/firmware.h> | 19 | #include <linux/firmware.h> |
30 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
31 | #include <linux/vmalloc.h> | 21 | #include <linux/vmalloc.h> |
32 | #include <net/cfg80211.h> | ||
33 | 22 | ||
34 | #include <defs.h> | ||
35 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
36 | #include <brcmu_wifi.h> | 24 | #include <brcmu_wifi.h> |
37 | #include <dhd_bus.h> | 25 | #include <dhd_bus.h> |
@@ -42,13 +30,11 @@ | |||
42 | 30 | ||
43 | #define IOCTL_RESP_TIMEOUT 2000 | 31 | #define IOCTL_RESP_TIMEOUT 2000 |
44 | 32 | ||
45 | #define BRCMF_USB_DLIMAGE_SPINWAIT 100 /* in unit of ms */ | 33 | #define BRCMF_USB_RESET_GETVER_SPINWAIT 100 /* in unit of ms */ |
46 | #define BRCMF_USB_DLIMAGE_LIMIT 500 /* spinwait limit (ms) */ | 34 | #define BRCMF_USB_RESET_GETVER_LOOP_CNT 10 |
47 | 35 | ||
48 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle | 36 | #define BRCMF_POSTBOOT_ID 0xA123 /* ID to detect if dongle |
49 | has boot up */ | 37 | has boot up */ |
50 | #define BRCMF_USB_RESETCFG_SPINWAIT 1 /* wait after resetcfg (ms) */ | ||
51 | |||
52 | #define BRCMF_USB_NRXQ 50 | 38 | #define BRCMF_USB_NRXQ 50 |
53 | #define BRCMF_USB_NTXQ 50 | 39 | #define BRCMF_USB_NTXQ 50 |
54 | 40 | ||
@@ -69,16 +55,6 @@ | |||
69 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" | 55 | #define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" |
70 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" | 56 | #define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin" |
71 | 57 | ||
72 | enum usbdev_suspend_state { | ||
73 | USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow | ||
74 | suspend */ | ||
75 | USBOS_SUSPEND_STATE_SUSPEND_PENDING, /* Device is idle, can be | ||
76 | * suspended. Wating PM to | ||
77 | * suspend the device | ||
78 | */ | ||
79 | USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ | ||
80 | }; | ||
81 | |||
82 | struct brcmf_usb_image { | 58 | struct brcmf_usb_image { |
83 | struct list_head list; | 59 | struct list_head list; |
84 | s8 *fwname; | 60 | s8 *fwname; |
@@ -99,10 +75,8 @@ struct brcmf_usbdev_info { | |||
99 | struct list_head rx_postq; | 75 | struct list_head rx_postq; |
100 | struct list_head tx_freeq; | 76 | struct list_head tx_freeq; |
101 | struct list_head tx_postq; | 77 | struct list_head tx_postq; |
102 | enum usbdev_suspend_state suspend_state; | ||
103 | uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; | 78 | uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2; |
104 | 79 | ||
105 | bool activity; | ||
106 | int rx_low_watermark; | 80 | int rx_low_watermark; |
107 | int tx_low_watermark; | 81 | int tx_low_watermark; |
108 | int tx_high_watermark; | 82 | int tx_high_watermark; |
@@ -170,6 +144,7 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo) | |||
170 | static void | 144 | static void |
171 | brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) | 145 | brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) |
172 | { | 146 | { |
147 | brcmf_dbg(USB, "Enter, status=%d\n", status); | ||
173 | 148 | ||
174 | if (unlikely(devinfo == NULL)) | 149 | if (unlikely(devinfo == NULL)) |
175 | return; | 150 | return; |
@@ -197,6 +172,7 @@ brcmf_usb_ctlread_complete(struct urb *urb) | |||
197 | struct brcmf_usbdev_info *devinfo = | 172 | struct brcmf_usbdev_info *devinfo = |
198 | (struct brcmf_usbdev_info *)urb->context; | 173 | (struct brcmf_usbdev_info *)urb->context; |
199 | 174 | ||
175 | brcmf_dbg(USB, "Enter\n"); | ||
200 | devinfo->ctl_urb_actual_length = urb->actual_length; | 176 | devinfo->ctl_urb_actual_length = urb->actual_length; |
201 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, | 177 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ, |
202 | urb->status); | 178 | urb->status); |
@@ -208,33 +184,22 @@ brcmf_usb_ctlwrite_complete(struct urb *urb) | |||
208 | struct brcmf_usbdev_info *devinfo = | 184 | struct brcmf_usbdev_info *devinfo = |
209 | (struct brcmf_usbdev_info *)urb->context; | 185 | (struct brcmf_usbdev_info *)urb->context; |
210 | 186 | ||
187 | brcmf_dbg(USB, "Enter\n"); | ||
211 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, | 188 | brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE, |
212 | urb->status); | 189 | urb->status); |
213 | } | 190 | } |
214 | 191 | ||
215 | static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state) | ||
216 | { | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int | 192 | static int |
221 | brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) | 193 | brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) |
222 | { | 194 | { |
223 | int ret; | 195 | int ret; |
224 | u16 size; | 196 | u16 size; |
225 | 197 | ||
198 | brcmf_dbg(USB, "Enter\n"); | ||
226 | if (devinfo == NULL || buf == NULL || | 199 | if (devinfo == NULL || buf == NULL || |
227 | len == 0 || devinfo->ctl_urb == NULL) | 200 | len == 0 || devinfo->ctl_urb == NULL) |
228 | return -EINVAL; | 201 | return -EINVAL; |
229 | 202 | ||
230 | /* If the USB/HSIC bus in sleep state, wake it up */ | ||
231 | if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) | ||
232 | if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { | ||
233 | brcmf_dbg(ERROR, "Could not Resume the bus!\n"); | ||
234 | return -EIO; | ||
235 | } | ||
236 | |||
237 | devinfo->activity = true; | ||
238 | size = len; | 203 | size = len; |
239 | devinfo->ctl_write.wLength = cpu_to_le16p(&size); | 204 | devinfo->ctl_write.wLength = cpu_to_le16p(&size); |
240 | devinfo->ctl_urb->transfer_buffer_length = size; | 205 | devinfo->ctl_urb->transfer_buffer_length = size; |
@@ -262,6 +227,7 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) | |||
262 | int ret; | 227 | int ret; |
263 | u16 size; | 228 | u16 size; |
264 | 229 | ||
230 | brcmf_dbg(USB, "Enter\n"); | ||
265 | if ((devinfo == NULL) || (buf == NULL) || (len == 0) | 231 | if ((devinfo == NULL) || (buf == NULL) || (len == 0) |
266 | || (devinfo->ctl_urb == NULL)) | 232 | || (devinfo->ctl_urb == NULL)) |
267 | return -EINVAL; | 233 | return -EINVAL; |
@@ -295,10 +261,9 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len) | |||
295 | int timeout = 0; | 261 | int timeout = 0; |
296 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 262 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
297 | 263 | ||
298 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 264 | brcmf_dbg(USB, "Enter\n"); |
299 | /* TODO: handle suspend/resume */ | 265 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
300 | return -EIO; | 266 | return -EIO; |
301 | } | ||
302 | 267 | ||
303 | if (test_and_set_bit(0, &devinfo->ctl_op)) | 268 | if (test_and_set_bit(0, &devinfo->ctl_op)) |
304 | return -EIO; | 269 | return -EIO; |
@@ -325,10 +290,10 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len) | |||
325 | int timeout = 0; | 290 | int timeout = 0; |
326 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 291 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
327 | 292 | ||
328 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 293 | brcmf_dbg(USB, "Enter\n"); |
329 | /* TODO: handle suspend/resume */ | 294 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
330 | return -EIO; | 295 | return -EIO; |
331 | } | 296 | |
332 | if (test_and_set_bit(0, &devinfo->ctl_op)) | 297 | if (test_and_set_bit(0, &devinfo->ctl_op)) |
333 | return -EIO; | 298 | return -EIO; |
334 | 299 | ||
@@ -453,6 +418,8 @@ static void brcmf_usb_tx_complete(struct urb *urb) | |||
453 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; | 418 | struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context; |
454 | struct brcmf_usbdev_info *devinfo = req->devinfo; | 419 | struct brcmf_usbdev_info *devinfo = req->devinfo; |
455 | 420 | ||
421 | brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status, | ||
422 | req->skb); | ||
456 | brcmf_usb_del_fromq(devinfo, req); | 423 | brcmf_usb_del_fromq(devinfo, req); |
457 | if (urb->status == 0) | 424 | if (urb->status == 0) |
458 | devinfo->bus_pub.bus->dstats.tx_packets++; | 425 | devinfo->bus_pub.bus->dstats.tx_packets++; |
@@ -478,6 +445,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
478 | struct sk_buff *skb; | 445 | struct sk_buff *skb; |
479 | int ifidx = 0; | 446 | int ifidx = 0; |
480 | 447 | ||
448 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); | ||
481 | brcmf_usb_del_fromq(devinfo, req); | 449 | brcmf_usb_del_fromq(devinfo, req); |
482 | skb = req->skb; | 450 | skb = req->skb; |
483 | req->skb = NULL; | 451 | req->skb = NULL; |
@@ -491,7 +459,7 @@ static void brcmf_usb_rx_complete(struct urb *urb) | |||
491 | return; | 459 | return; |
492 | } | 460 | } |
493 | 461 | ||
494 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) { | 462 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { |
495 | skb_put(skb, urb->actual_length); | 463 | skb_put(skb, urb->actual_length); |
496 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { | 464 | if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { |
497 | brcmf_dbg(ERROR, "rx protocol error\n"); | 465 | brcmf_dbg(ERROR, "rx protocol error\n"); |
@@ -544,8 +512,8 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo) | |||
544 | { | 512 | { |
545 | struct brcmf_usbreq *req; | 513 | struct brcmf_usbreq *req; |
546 | 514 | ||
547 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 515 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) { |
548 | brcmf_dbg(ERROR, "bus is not up\n"); | 516 | brcmf_dbg(ERROR, "bus is not up=%d\n", devinfo->bus_pub.state); |
549 | return; | 517 | return; |
550 | } | 518 | } |
551 | while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) | 519 | while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL) |
@@ -558,29 +526,24 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) | |||
558 | struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; | 526 | struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; |
559 | int old_state; | 527 | int old_state; |
560 | 528 | ||
529 | brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", | ||
530 | devinfo->bus_pub.state, state); | ||
561 | 531 | ||
562 | if (devinfo->bus_pub.state == state) | 532 | if (devinfo->bus_pub.state == state) |
563 | return; | 533 | return; |
564 | 534 | ||
565 | old_state = devinfo->bus_pub.state; | 535 | old_state = devinfo->bus_pub.state; |
566 | brcmf_dbg(TRACE, "dbus state change from %d to to %d\n", | 536 | devinfo->bus_pub.state = state; |
567 | old_state, state); | ||
568 | |||
569 | /* Don't update state if it's PnP firmware re-download */ | ||
570 | if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */ | ||
571 | devinfo->bus_pub.state = state; | ||
572 | |||
573 | if ((old_state == BCMFMAC_USB_STATE_SLEEP) | ||
574 | && (state == BCMFMAC_USB_STATE_UP)) { | ||
575 | brcmf_usb_rx_fill_all(devinfo); | ||
576 | } | ||
577 | 537 | ||
578 | /* update state of upper layer */ | 538 | /* update state of upper layer */ |
579 | if (state == BCMFMAC_USB_STATE_DOWN) { | 539 | if (state == BRCMFMAC_USB_STATE_DOWN) { |
580 | brcmf_dbg(INFO, "DBUS is down\n"); | 540 | brcmf_dbg(USB, "DBUS is down\n"); |
581 | bcmf_bus->state = BRCMF_BUS_DOWN; | 541 | bcmf_bus->state = BRCMF_BUS_DOWN; |
542 | } else if (state == BRCMFMAC_USB_STATE_UP) { | ||
543 | brcmf_dbg(USB, "DBUS is up\n"); | ||
544 | bcmf_bus->state = BRCMF_BUS_DATA; | ||
582 | } else { | 545 | } else { |
583 | brcmf_dbg(INFO, "DBUS current state=%d\n", state); | 546 | brcmf_dbg(USB, "DBUS current state=%d\n", state); |
584 | } | 547 | } |
585 | } | 548 | } |
586 | 549 | ||
@@ -589,30 +552,32 @@ brcmf_usb_intr_complete(struct urb *urb) | |||
589 | { | 552 | { |
590 | struct brcmf_usbdev_info *devinfo = | 553 | struct brcmf_usbdev_info *devinfo = |
591 | (struct brcmf_usbdev_info *)urb->context; | 554 | (struct brcmf_usbdev_info *)urb->context; |
592 | bool killed; | 555 | int err; |
556 | |||
557 | brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status); | ||
593 | 558 | ||
594 | if (devinfo == NULL) | 559 | if (devinfo == NULL) |
595 | return; | 560 | return; |
596 | 561 | ||
597 | if (unlikely(urb->status)) { | 562 | if (unlikely(urb->status)) { |
598 | if (devinfo->suspend_state == | 563 | if (urb->status == -ENOENT || |
599 | USBOS_SUSPEND_STATE_SUSPEND_PENDING) | 564 | urb->status == -ESHUTDOWN || |
600 | killed = true; | 565 | urb->status == -ENODEV) { |
601 | 566 | brcmf_usb_state_change(devinfo, | |
602 | if ((urb->status == -ENOENT && (!killed)) | 567 | BRCMFMAC_USB_STATE_DOWN); |
603 | || urb->status == -ESHUTDOWN || | ||
604 | urb->status == -ENODEV) { | ||
605 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); | ||
606 | } | 568 | } |
607 | } | 569 | } |
608 | 570 | ||
609 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) { | 571 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) { |
610 | brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); | 572 | brcmf_dbg(ERROR, "intr cb when DBUS down, ignoring\n"); |
611 | return; | 573 | return; |
612 | } | 574 | } |
613 | 575 | ||
614 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 576 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { |
615 | usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); | 577 | err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC); |
578 | if (err) | ||
579 | brcmf_dbg(ERROR, "usb_submit_urb, err=%d\n", err); | ||
580 | } | ||
616 | } | 581 | } |
617 | 582 | ||
618 | static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | 583 | static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) |
@@ -621,10 +586,9 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) | |||
621 | struct brcmf_usbreq *req; | 586 | struct brcmf_usbreq *req; |
622 | int ret; | 587 | int ret; |
623 | 588 | ||
624 | if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { | 589 | brcmf_dbg(USB, "Enter, skb=%p\n", skb); |
625 | /* TODO: handle suspend/resume */ | 590 | if (devinfo->bus_pub.state != BRCMFMAC_USB_STATE_UP) |
626 | return -EIO; | 591 | return -EIO; |
627 | } | ||
628 | 592 | ||
629 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, | 593 | req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq, |
630 | &devinfo->tx_freecount); | 594 | &devinfo->tx_freecount); |
@@ -664,25 +628,16 @@ static int brcmf_usb_up(struct device *dev) | |||
664 | { | 628 | { |
665 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 629 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
666 | u16 ifnum; | 630 | u16 ifnum; |
631 | int ret; | ||
667 | 632 | ||
668 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP) | 633 | brcmf_dbg(USB, "Enter\n"); |
634 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) | ||
669 | return 0; | 635 | return 0; |
670 | 636 | ||
671 | /* If the USB/HSIC bus in sleep state, wake it up */ | ||
672 | if (devinfo->suspend_state == USBOS_SUSPEND_STATE_SUSPENDED) { | ||
673 | if (brcmf_usb_pnp(devinfo, BCMFMAC_USB_PNP_RESUME) != 0) { | ||
674 | brcmf_dbg(ERROR, "Could not Resume the bus!\n"); | ||
675 | return -EIO; | ||
676 | } | ||
677 | } | ||
678 | devinfo->activity = true; | ||
679 | |||
680 | /* Success, indicate devinfo is fully up */ | 637 | /* Success, indicate devinfo is fully up */ |
681 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_UP); | 638 | brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP); |
682 | 639 | ||
683 | if (devinfo->intr_urb) { | 640 | if (devinfo->intr_urb) { |
684 | int ret; | ||
685 | |||
686 | usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, | 641 | usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev, |
687 | devinfo->intr_pipe, | 642 | devinfo->intr_pipe, |
688 | &devinfo->intr, | 643 | &devinfo->intr, |
@@ -727,14 +682,14 @@ static void brcmf_usb_down(struct device *dev) | |||
727 | { | 682 | { |
728 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); | 683 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); |
729 | 684 | ||
685 | brcmf_dbg(USB, "Enter\n"); | ||
730 | if (devinfo == NULL) | 686 | if (devinfo == NULL) |
731 | return; | 687 | return; |
732 | 688 | ||
733 | brcmf_dbg(TRACE, "enter\n"); | 689 | if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) |
734 | if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN) | ||
735 | return; | 690 | return; |
736 | 691 | ||
737 | brcmf_usb_state_change(devinfo, BCMFMAC_USB_STATE_DOWN); | 692 | brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN); |
738 | if (devinfo->intr_urb) | 693 | if (devinfo->intr_urb) |
739 | usb_kill_urb(devinfo->intr_urb); | 694 | usb_kill_urb(devinfo->intr_urb); |
740 | 695 | ||
@@ -808,27 +763,25 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo) | |||
808 | struct bootrom_id_le id; | 763 | struct bootrom_id_le id; |
809 | u32 chipid, chiprev; | 764 | u32 chipid, chiprev; |
810 | 765 | ||
811 | brcmf_dbg(TRACE, "enter\n"); | 766 | brcmf_dbg(USB, "Enter\n"); |
812 | 767 | ||
813 | if (devinfo == NULL) | 768 | if (devinfo == NULL) |
814 | return false; | 769 | return false; |
815 | 770 | ||
816 | /* Check if firmware downloaded already by querying runtime ID */ | 771 | /* Check if firmware downloaded already by querying runtime ID */ |
817 | id.chip = cpu_to_le32(0xDEAD); | 772 | id.chip = cpu_to_le32(0xDEAD); |
818 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, | 773 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); |
819 | sizeof(struct bootrom_id_le)); | ||
820 | 774 | ||
821 | chipid = le32_to_cpu(id.chip); | 775 | chipid = le32_to_cpu(id.chip); |
822 | chiprev = le32_to_cpu(id.chiprev); | 776 | chiprev = le32_to_cpu(id.chiprev); |
823 | 777 | ||
824 | if ((chipid & 0x4300) == 0x4300) | 778 | if ((chipid & 0x4300) == 0x4300) |
825 | brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev); | 779 | brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev); |
826 | else | 780 | else |
827 | brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev); | 781 | brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev); |
828 | if (chipid == BRCMF_POSTBOOT_ID) { | 782 | if (chipid == BRCMF_POSTBOOT_ID) { |
829 | brcmf_dbg(INFO, "firmware already downloaded\n"); | 783 | brcmf_dbg(USB, "firmware already downloaded\n"); |
830 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, | 784 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); |
831 | sizeof(struct bootrom_id_le)); | ||
832 | return false; | 785 | return false; |
833 | } else { | 786 | } else { |
834 | devinfo->bus_pub.devid = chipid; | 787 | devinfo->bus_pub.devid = chipid; |
@@ -841,38 +794,29 @@ static int | |||
841 | brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) | 794 | brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) |
842 | { | 795 | { |
843 | struct bootrom_id_le id; | 796 | struct bootrom_id_le id; |
844 | u16 wait = 0, wait_time; | 797 | u32 loop_cnt; |
845 | 798 | ||
846 | brcmf_dbg(TRACE, "enter\n"); | 799 | brcmf_dbg(USB, "Enter\n"); |
847 | |||
848 | if (devinfo == NULL) | ||
849 | return -EINVAL; | ||
850 | 800 | ||
851 | /* Give dongle chance to boot */ | 801 | loop_cnt = 0; |
852 | wait_time = BRCMF_USB_DLIMAGE_SPINWAIT; | 802 | do { |
853 | while (wait < BRCMF_USB_DLIMAGE_LIMIT) { | 803 | mdelay(BRCMF_USB_RESET_GETVER_SPINWAIT); |
854 | mdelay(wait_time); | 804 | loop_cnt++; |
855 | wait += wait_time; | ||
856 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ | 805 | id.chip = cpu_to_le32(0xDEAD); /* Get the ID */ |
857 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, | 806 | brcmf_usb_dl_cmd(devinfo, DL_GETVER, &id, sizeof(id)); |
858 | sizeof(struct bootrom_id_le)); | ||
859 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) | 807 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) |
860 | break; | 808 | break; |
861 | } | 809 | } while (loop_cnt < BRCMF_USB_RESET_GETVER_LOOP_CNT); |
862 | 810 | ||
863 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { | 811 | if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) { |
864 | brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n", | 812 | brcmf_dbg(USB, "postboot chip 0x%x/rev 0x%x\n", |
865 | wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); | 813 | le32_to_cpu(id.chip), le32_to_cpu(id.chiprev)); |
866 | |||
867 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, | ||
868 | sizeof(struct bootrom_id_le)); | ||
869 | 814 | ||
870 | /* XXX this wait may not be necessary */ | 815 | brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id, sizeof(id)); |
871 | mdelay(BRCMF_USB_RESETCFG_SPINWAIT); | ||
872 | return 0; | 816 | return 0; |
873 | } else { | 817 | } else { |
874 | brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", | 818 | brcmf_dbg(ERROR, "Cannot talk to Dongle. Firmware is not UP, %d ms\n", |
875 | wait); | 819 | BRCMF_USB_RESET_GETVER_SPINWAIT * loop_cnt); |
876 | return -EINVAL; | 820 | return -EINVAL; |
877 | } | 821 | } |
878 | } | 822 | } |
@@ -911,7 +855,8 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
911 | struct rdl_state_le state; | 855 | struct rdl_state_le state; |
912 | u32 rdlstate, rdlbytes; | 856 | u32 rdlstate, rdlbytes; |
913 | int err = 0; | 857 | int err = 0; |
914 | brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen); | 858 | |
859 | brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen); | ||
915 | 860 | ||
916 | bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); | 861 | bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC); |
917 | if (bulkchunk == NULL) { | 862 | if (bulkchunk == NULL) { |
@@ -986,7 +931,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen) | |||
986 | 931 | ||
987 | fail: | 932 | fail: |
988 | kfree(bulkchunk); | 933 | kfree(bulkchunk); |
989 | brcmf_dbg(TRACE, "err=%d\n", err); | 934 | brcmf_dbg(USB, "Exit, err=%d\n", err); |
990 | return err; | 935 | return err; |
991 | } | 936 | } |
992 | 937 | ||
@@ -994,7 +939,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
994 | { | 939 | { |
995 | int err; | 940 | int err; |
996 | 941 | ||
997 | brcmf_dbg(TRACE, "enter\n"); | 942 | brcmf_dbg(USB, "Enter\n"); |
998 | 943 | ||
999 | if (devinfo == NULL) | 944 | if (devinfo == NULL) |
1000 | return -EINVAL; | 945 | return -EINVAL; |
@@ -1004,10 +949,10 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len) | |||
1004 | 949 | ||
1005 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); | 950 | err = brcmf_usb_dl_writeimage(devinfo, fw, len); |
1006 | if (err == 0) | 951 | if (err == 0) |
1007 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE; | 952 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_DONE; |
1008 | else | 953 | else |
1009 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING; | 954 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DL_FAIL; |
1010 | brcmf_dbg(TRACE, "exit: err=%d\n", err); | 955 | brcmf_dbg(USB, "Exit, err=%d\n", err); |
1011 | 956 | ||
1012 | return err; | 957 | return err; |
1013 | } | 958 | } |
@@ -1016,7 +961,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
1016 | { | 961 | { |
1017 | struct rdl_state_le state; | 962 | struct rdl_state_le state; |
1018 | 963 | ||
1019 | brcmf_dbg(TRACE, "enter\n"); | 964 | brcmf_dbg(USB, "Enter\n"); |
1020 | if (!devinfo) | 965 | if (!devinfo) |
1021 | return -EINVAL; | 966 | return -EINVAL; |
1022 | 967 | ||
@@ -1039,7 +984,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo) | |||
1039 | brcmf_dbg(ERROR, "Dongle not runnable\n"); | 984 | brcmf_dbg(ERROR, "Dongle not runnable\n"); |
1040 | return -EINVAL; | 985 | return -EINVAL; |
1041 | } | 986 | } |
1042 | brcmf_dbg(TRACE, "exit\n"); | 987 | brcmf_dbg(USB, "Exit\n"); |
1043 | return 0; | 988 | return 0; |
1044 | } | 989 | } |
1045 | 990 | ||
@@ -1066,7 +1011,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | |||
1066 | int devid, chiprev; | 1011 | int devid, chiprev; |
1067 | int err; | 1012 | int err; |
1068 | 1013 | ||
1069 | brcmf_dbg(TRACE, "enter\n"); | 1014 | brcmf_dbg(USB, "Enter\n"); |
1070 | if (devinfo == NULL) | 1015 | if (devinfo == NULL) |
1071 | return -ENODEV; | 1016 | return -ENODEV; |
1072 | 1017 | ||
@@ -1094,7 +1039,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo) | |||
1094 | 1039 | ||
1095 | static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) | 1040 | static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) |
1096 | { | 1041 | { |
1097 | brcmf_dbg(TRACE, "devinfo %p\n", devinfo); | 1042 | brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); |
1098 | 1043 | ||
1099 | /* free the URBS */ | 1044 | /* free the URBS */ |
1100 | brcmf_usb_free_q(&devinfo->rx_freeq, false); | 1045 | brcmf_usb_free_q(&devinfo->rx_freeq, false); |
@@ -1129,6 +1074,7 @@ static int check_file(const u8 *headers) | |||
1129 | struct trx_header_le *trx; | 1074 | struct trx_header_le *trx; |
1130 | int actual_len = -1; | 1075 | int actual_len = -1; |
1131 | 1076 | ||
1077 | brcmf_dbg(USB, "Enter\n"); | ||
1132 | /* Extract trx header */ | 1078 | /* Extract trx header */ |
1133 | trx = (struct trx_header_le *) headers; | 1079 | trx = (struct trx_header_le *) headers; |
1134 | if (trx->magic != cpu_to_le32(TRX_MAGIC)) | 1080 | if (trx->magic != cpu_to_le32(TRX_MAGIC)) |
@@ -1150,6 +1096,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | |||
1150 | struct brcmf_usb_image *fw_image; | 1096 | struct brcmf_usb_image *fw_image; |
1151 | int err; | 1097 | int err; |
1152 | 1098 | ||
1099 | brcmf_dbg(USB, "Enter\n"); | ||
1153 | switch (devinfo->bus_pub.devid) { | 1100 | switch (devinfo->bus_pub.devid) { |
1154 | case 43143: | 1101 | case 43143: |
1155 | fwname = BRCMF_USB_43143_FW_NAME; | 1102 | fwname = BRCMF_USB_43143_FW_NAME; |
@@ -1166,7 +1113,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo) | |||
1166 | return -EINVAL; | 1113 | return -EINVAL; |
1167 | break; | 1114 | break; |
1168 | } | 1115 | } |
1169 | 1116 | brcmf_dbg(USB, "Loading FW %s\n", fwname); | |
1170 | list_for_each_entry(fw_image, &fw_image_list, list) { | 1117 | list_for_each_entry(fw_image, &fw_image_list, list) { |
1171 | if (fw_image->fwname == fwname) { | 1118 | if (fw_image->fwname == fwname) { |
1172 | devinfo->image = fw_image->image; | 1119 | devinfo->image = fw_image->image; |
@@ -1211,10 +1158,13 @@ static | |||
1211 | struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, | 1158 | struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, |
1212 | int nrxq, int ntxq) | 1159 | int nrxq, int ntxq) |
1213 | { | 1160 | { |
1161 | brcmf_dbg(USB, "Enter\n"); | ||
1162 | |||
1214 | devinfo->bus_pub.nrxq = nrxq; | 1163 | devinfo->bus_pub.nrxq = nrxq; |
1215 | devinfo->rx_low_watermark = nrxq / 2; | 1164 | devinfo->rx_low_watermark = nrxq / 2; |
1216 | devinfo->bus_pub.devinfo = devinfo; | 1165 | devinfo->bus_pub.devinfo = devinfo; |
1217 | devinfo->bus_pub.ntxq = ntxq; | 1166 | devinfo->bus_pub.ntxq = ntxq; |
1167 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_DOWN; | ||
1218 | 1168 | ||
1219 | /* flow control when too many tx urbs posted */ | 1169 | /* flow control when too many tx urbs posted */ |
1220 | devinfo->tx_low_watermark = ntxq / 4; | 1170 | devinfo->tx_low_watermark = ntxq / 4; |
@@ -1263,7 +1213,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, | |||
1263 | if (!brcmf_usb_dlneeded(devinfo)) | 1213 | if (!brcmf_usb_dlneeded(devinfo)) |
1264 | return &devinfo->bus_pub; | 1214 | return &devinfo->bus_pub; |
1265 | 1215 | ||
1266 | brcmf_dbg(TRACE, "start fw downloading\n"); | 1216 | brcmf_dbg(USB, "Start fw downloading\n"); |
1267 | if (brcmf_usb_get_fw(devinfo)) | 1217 | if (brcmf_usb_get_fw(devinfo)) |
1268 | goto error; | 1218 | goto error; |
1269 | 1219 | ||
@@ -1278,14 +1228,14 @@ error: | |||
1278 | return NULL; | 1228 | return NULL; |
1279 | } | 1229 | } |
1280 | 1230 | ||
1281 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | 1231 | static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo) |
1282 | const char *desc, u32 bustype, u32 hdrlen) | ||
1283 | { | 1232 | { |
1284 | struct brcmf_bus *bus = NULL; | 1233 | struct brcmf_bus *bus = NULL; |
1285 | struct brcmf_usbdev *bus_pub = NULL; | 1234 | struct brcmf_usbdev *bus_pub = NULL; |
1286 | int ret; | 1235 | int ret; |
1287 | struct device *dev = devinfo->dev; | 1236 | struct device *dev = devinfo->dev; |
1288 | 1237 | ||
1238 | brcmf_dbg(USB, "Enter\n"); | ||
1289 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); | 1239 | bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ); |
1290 | if (!bus_pub) | 1240 | if (!bus_pub) |
1291 | return -ENODEV; | 1241 | return -ENODEV; |
@@ -1302,14 +1252,13 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, | |||
1302 | bus->brcmf_bus_stop = brcmf_usb_down; | 1252 | bus->brcmf_bus_stop = brcmf_usb_down; |
1303 | bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; | 1253 | bus->brcmf_bus_txctl = brcmf_usb_tx_ctlpkt; |
1304 | bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; | 1254 | bus->brcmf_bus_rxctl = brcmf_usb_rx_ctlpkt; |
1305 | bus->type = bustype; | ||
1306 | bus->bus_priv.usb = bus_pub; | 1255 | bus->bus_priv.usb = bus_pub; |
1307 | dev_set_drvdata(dev, bus); | 1256 | dev_set_drvdata(dev, bus); |
1308 | 1257 | ||
1309 | /* Attach to the common driver interface */ | 1258 | /* Attach to the common driver interface */ |
1310 | ret = brcmf_attach(hdrlen, dev); | 1259 | ret = brcmf_attach(0, dev); |
1311 | if (ret) { | 1260 | if (ret) { |
1312 | brcmf_dbg(ERROR, "dhd_attach failed\n"); | 1261 | brcmf_dbg(ERROR, "brcmf_attach failed\n"); |
1313 | goto fail; | 1262 | goto fail; |
1314 | } | 1263 | } |
1315 | 1264 | ||
@@ -1333,7 +1282,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo) | |||
1333 | { | 1282 | { |
1334 | if (!devinfo) | 1283 | if (!devinfo) |
1335 | return; | 1284 | return; |
1336 | brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo); | 1285 | brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); |
1337 | 1286 | ||
1338 | brcmf_detach(devinfo->dev); | 1287 | brcmf_detach(devinfo->dev); |
1339 | kfree(devinfo->bus_pub.bus); | 1288 | kfree(devinfo->bus_pub.bus); |
@@ -1351,7 +1300,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1351 | u8 endpoint_num; | 1300 | u8 endpoint_num; |
1352 | struct brcmf_usbdev_info *devinfo; | 1301 | struct brcmf_usbdev_info *devinfo; |
1353 | 1302 | ||
1354 | brcmf_dbg(TRACE, "enter\n"); | 1303 | brcmf_dbg(USB, "Enter\n"); |
1355 | 1304 | ||
1356 | devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); | 1305 | devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC); |
1357 | if (devinfo == NULL) | 1306 | if (devinfo == NULL) |
@@ -1452,11 +1401,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1452 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; | 1401 | devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; |
1453 | 1402 | ||
1454 | if (usb->speed == USB_SPEED_HIGH) | 1403 | if (usb->speed == USB_SPEED_HIGH) |
1455 | brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); | 1404 | brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n"); |
1456 | else | 1405 | else |
1457 | brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); | 1406 | brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n"); |
1458 | 1407 | ||
1459 | ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0); | 1408 | ret = brcmf_usb_probe_cb(devinfo); |
1460 | if (ret) | 1409 | if (ret) |
1461 | goto fail; | 1410 | goto fail; |
1462 | 1411 | ||
@@ -1476,40 +1425,55 @@ brcmf_usb_disconnect(struct usb_interface *intf) | |||
1476 | { | 1425 | { |
1477 | struct brcmf_usbdev_info *devinfo; | 1426 | struct brcmf_usbdev_info *devinfo; |
1478 | 1427 | ||
1479 | brcmf_dbg(TRACE, "enter\n"); | 1428 | brcmf_dbg(USB, "Enter\n"); |
1480 | devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); | 1429 | devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); |
1481 | brcmf_usb_disconnect_cb(devinfo); | 1430 | brcmf_usb_disconnect_cb(devinfo); |
1482 | kfree(devinfo); | 1431 | kfree(devinfo); |
1432 | brcmf_dbg(USB, "Exit\n"); | ||
1483 | } | 1433 | } |
1484 | 1434 | ||
1485 | /* | 1435 | /* |
1486 | * only need to signal the bus being down and update the suspend state. | 1436 | * only need to signal the bus being down and update the state. |
1487 | */ | 1437 | */ |
1488 | static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) | 1438 | static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) |
1489 | { | 1439 | { |
1490 | struct usb_device *usb = interface_to_usbdev(intf); | 1440 | struct usb_device *usb = interface_to_usbdev(intf); |
1491 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1441 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1492 | 1442 | ||
1493 | brcmf_dbg(TRACE, "enter\n"); | 1443 | brcmf_dbg(USB, "Enter\n"); |
1494 | devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN; | 1444 | devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; |
1495 | devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED; | 1445 | brcmf_detach(&usb->dev); |
1496 | return 0; | 1446 | return 0; |
1497 | } | 1447 | } |
1498 | 1448 | ||
1499 | /* | 1449 | /* |
1500 | * mark suspend state active and crank up the bus. | 1450 | * (re-) start the bus. |
1501 | */ | 1451 | */ |
1502 | static int brcmf_usb_resume(struct usb_interface *intf) | 1452 | static int brcmf_usb_resume(struct usb_interface *intf) |
1503 | { | 1453 | { |
1504 | struct usb_device *usb = interface_to_usbdev(intf); | 1454 | struct usb_device *usb = interface_to_usbdev(intf); |
1505 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | 1455 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); |
1506 | 1456 | ||
1507 | brcmf_dbg(TRACE, "enter\n"); | 1457 | brcmf_dbg(USB, "Enter\n"); |
1508 | devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE; | 1458 | if (!brcmf_attach(0, devinfo->dev)) |
1509 | brcmf_bus_start(&usb->dev); | 1459 | return brcmf_bus_start(&usb->dev); |
1460 | |||
1510 | return 0; | 1461 | return 0; |
1511 | } | 1462 | } |
1512 | 1463 | ||
1464 | static int brcmf_usb_reset_resume(struct usb_interface *intf) | ||
1465 | { | ||
1466 | struct usb_device *usb = interface_to_usbdev(intf); | ||
1467 | struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); | ||
1468 | |||
1469 | brcmf_dbg(USB, "Enter\n"); | ||
1470 | |||
1471 | if (!brcmf_usb_fw_download(devinfo)) | ||
1472 | return brcmf_usb_resume(intf); | ||
1473 | |||
1474 | return -EIO; | ||
1475 | } | ||
1476 | |||
1513 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c | 1477 | #define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c |
1514 | #define BRCMF_USB_DEVICE_ID_43143 0xbd1e | 1478 | #define BRCMF_USB_DEVICE_ID_43143 0xbd1e |
1515 | #define BRCMF_USB_DEVICE_ID_43236 0xbd17 | 1479 | #define BRCMF_USB_DEVICE_ID_43236 0xbd17 |
@@ -1529,7 +1493,6 @@ MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME); | |||
1529 | MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); | 1493 | MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); |
1530 | MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); | 1494 | MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); |
1531 | 1495 | ||
1532 | /* TODO: suspend and resume entries */ | ||
1533 | static struct usb_driver brcmf_usbdrvr = { | 1496 | static struct usb_driver brcmf_usbdrvr = { |
1534 | .name = KBUILD_MODNAME, | 1497 | .name = KBUILD_MODNAME, |
1535 | .probe = brcmf_usb_probe, | 1498 | .probe = brcmf_usb_probe, |
@@ -1537,6 +1500,7 @@ static struct usb_driver brcmf_usbdrvr = { | |||
1537 | .id_table = brcmf_usb_devid_table, | 1500 | .id_table = brcmf_usb_devid_table, |
1538 | .suspend = brcmf_usb_suspend, | 1501 | .suspend = brcmf_usb_suspend, |
1539 | .resume = brcmf_usb_resume, | 1502 | .resume = brcmf_usb_resume, |
1503 | .reset_resume = brcmf_usb_reset_resume, | ||
1540 | .supports_autosuspend = 1, | 1504 | .supports_autosuspend = 1, |
1541 | .disable_hub_initiated_lpm = 1, | 1505 | .disable_hub_initiated_lpm = 1, |
1542 | }; | 1506 | }; |
@@ -1554,12 +1518,14 @@ static void brcmf_release_fw(struct list_head *q) | |||
1554 | 1518 | ||
1555 | void brcmf_usb_exit(void) | 1519 | void brcmf_usb_exit(void) |
1556 | { | 1520 | { |
1521 | brcmf_dbg(USB, "Enter\n"); | ||
1557 | usb_deregister(&brcmf_usbdrvr); | 1522 | usb_deregister(&brcmf_usbdrvr); |
1558 | brcmf_release_fw(&fw_image_list); | 1523 | brcmf_release_fw(&fw_image_list); |
1559 | } | 1524 | } |
1560 | 1525 | ||
1561 | void brcmf_usb_init(void) | 1526 | void brcmf_usb_init(void) |
1562 | { | 1527 | { |
1528 | brcmf_dbg(USB, "Enter\n"); | ||
1563 | INIT_LIST_HEAD(&fw_image_list); | 1529 | INIT_LIST_HEAD(&fw_image_list); |
1564 | usb_register(&brcmf_usbdrvr); | 1530 | usb_register(&brcmf_usbdrvr); |
1565 | } | 1531 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.h b/drivers/net/wireless/brcm80211/brcmfmac/usb.h index acfa5e89872f..f483a8c9945b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/usb.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.h | |||
@@ -17,19 +17,11 @@ | |||
17 | #define BRCMFMAC_USB_H | 17 | #define BRCMFMAC_USB_H |
18 | 18 | ||
19 | enum brcmf_usb_state { | 19 | enum brcmf_usb_state { |
20 | BCMFMAC_USB_STATE_DL_PENDING, | 20 | BRCMFMAC_USB_STATE_DOWN, |
21 | BCMFMAC_USB_STATE_DL_DONE, | 21 | BRCMFMAC_USB_STATE_DL_FAIL, |
22 | BCMFMAC_USB_STATE_UP, | 22 | BRCMFMAC_USB_STATE_DL_DONE, |
23 | BCMFMAC_USB_STATE_DOWN, | 23 | BRCMFMAC_USB_STATE_UP, |
24 | BCMFMAC_USB_STATE_PNP_FWDL, | 24 | BRCMFMAC_USB_STATE_SLEEP |
25 | BCMFMAC_USB_STATE_DISCONNECT, | ||
26 | BCMFMAC_USB_STATE_SLEEP | ||
27 | }; | ||
28 | |||
29 | enum brcmf_usb_pnp_state { | ||
30 | BCMFMAC_USB_PNP_DISCONNECT, | ||
31 | BCMFMAC_USB_PNP_SLEEP, | ||
32 | BCMFMAC_USB_PNP_RESUME, | ||
33 | }; | 25 | }; |
34 | 26 | ||
35 | struct brcmf_stats { | 27 | struct brcmf_stats { |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 6d554249394f..2044fdb55558 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | |||
@@ -19,14 +19,7 @@ | |||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/if_arp.h> | ||
23 | #include <linux/sched.h> | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/netdevice.h> | ||
26 | #include <linux/bitops.h> | ||
27 | #include <linux/etherdevice.h> | 22 | #include <linux/etherdevice.h> |
28 | #include <linux/ieee80211.h> | ||
29 | #include <linux/uaccess.h> | ||
30 | #include <net/cfg80211.h> | 23 | #include <net/cfg80211.h> |
31 | #include <net/netlink.h> | 24 | #include <net/netlink.h> |
32 | 25 | ||
@@ -486,13 +479,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, | |||
486 | 479 | ||
487 | if (ap) { | 480 | if (ap) { |
488 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); | 481 | set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state); |
489 | if (!cfg->ap_info) | ||
490 | cfg->ap_info = kzalloc(sizeof(*cfg->ap_info), | ||
491 | GFP_KERNEL); | ||
492 | if (!cfg->ap_info) { | ||
493 | err = -ENOMEM; | ||
494 | goto done; | ||
495 | } | ||
496 | WL_INFO("IF Type = AP\n"); | 482 | WL_INFO("IF Type = AP\n"); |
497 | } else { | 483 | } else { |
498 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), | 484 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), |
@@ -529,185 +515,6 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc) | |||
529 | } | 515 | } |
530 | } | 516 | } |
531 | 517 | ||
532 | static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le, | ||
533 | struct brcmf_ssid *ssid) | ||
534 | { | ||
535 | memset(params_le->bssid, 0xFF, ETH_ALEN); | ||
536 | params_le->bss_type = DOT11_BSSTYPE_ANY; | ||
537 | params_le->scan_type = 0; | ||
538 | params_le->channel_num = 0; | ||
539 | params_le->nprobes = cpu_to_le32(-1); | ||
540 | params_le->active_time = cpu_to_le32(-1); | ||
541 | params_le->passive_time = cpu_to_le32(-1); | ||
542 | params_le->home_time = cpu_to_le32(-1); | ||
543 | if (ssid && ssid->SSID_len) { | ||
544 | params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len); | ||
545 | memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | static s32 | ||
550 | brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, | ||
551 | struct brcmf_ssid *ssid, u16 action) | ||
552 | { | ||
553 | s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + | ||
554 | offsetof(struct brcmf_iscan_params_le, params_le); | ||
555 | struct brcmf_iscan_params_le *params; | ||
556 | s32 err = 0; | ||
557 | |||
558 | if (ssid && ssid->SSID_len) | ||
559 | params_size += sizeof(struct brcmf_ssid); | ||
560 | params = kzalloc(params_size, GFP_KERNEL); | ||
561 | if (!params) | ||
562 | return -ENOMEM; | ||
563 | BUG_ON(params_size >= BRCMF_DCMD_SMLEN); | ||
564 | |||
565 | brcmf_iscan_prep(¶ms->params_le, ssid); | ||
566 | |||
567 | params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); | ||
568 | params->action = cpu_to_le16(action); | ||
569 | params->scan_duration = cpu_to_le16(0); | ||
570 | |||
571 | err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan", | ||
572 | params, params_size); | ||
573 | if (err) { | ||
574 | if (err == -EBUSY) | ||
575 | WL_INFO("system busy : iscan canceled\n"); | ||
576 | else | ||
577 | WL_ERR("error (%d)\n", err); | ||
578 | } | ||
579 | |||
580 | kfree(params); | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg) | ||
585 | { | ||
586 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
587 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
588 | struct brcmf_ssid ssid; | ||
589 | u32 passive_scan; | ||
590 | s32 err = 0; | ||
591 | |||
592 | /* Broadcast scan by default */ | ||
593 | memset(&ssid, 0, sizeof(ssid)); | ||
594 | |||
595 | iscan->state = WL_ISCAN_STATE_SCANING; | ||
596 | |||
597 | passive_scan = cfg->active_scan ? 0 : 1; | ||
598 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), | ||
599 | BRCMF_C_SET_PASSIVE_SCAN, passive_scan); | ||
600 | if (err) { | ||
601 | WL_ERR("error (%d)\n", err); | ||
602 | return err; | ||
603 | } | ||
604 | brcmf_set_mpc(ndev, 0); | ||
605 | cfg->iscan_kickstart = true; | ||
606 | err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); | ||
607 | if (err) { | ||
608 | brcmf_set_mpc(ndev, 1); | ||
609 | cfg->iscan_kickstart = false; | ||
610 | return err; | ||
611 | } | ||
612 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
613 | iscan->timer_on = 1; | ||
614 | return err; | ||
615 | } | ||
616 | |||
617 | static s32 | ||
618 | brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev, | ||
619 | struct cfg80211_scan_request *request, | ||
620 | struct cfg80211_ssid *this_ssid) | ||
621 | { | ||
622 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
623 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
624 | struct cfg80211_ssid *ssids; | ||
625 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | ||
626 | u32 passive_scan; | ||
627 | bool iscan_req; | ||
628 | bool spec_scan; | ||
629 | s32 err = 0; | ||
630 | u32 SSID_len; | ||
631 | |||
632 | if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
633 | WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status); | ||
634 | return -EAGAIN; | ||
635 | } | ||
636 | if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { | ||
637 | WL_ERR("Scanning being aborted: status (%lu)\n", | ||
638 | cfg->scan_status); | ||
639 | return -EAGAIN; | ||
640 | } | ||
641 | if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) { | ||
642 | WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state); | ||
643 | return -EAGAIN; | ||
644 | } | ||
645 | |||
646 | iscan_req = false; | ||
647 | spec_scan = false; | ||
648 | if (request) { | ||
649 | /* scan bss */ | ||
650 | ssids = request->ssids; | ||
651 | if (cfg->iscan_on && (!ssids || !ssids->ssid_len)) | ||
652 | iscan_req = true; | ||
653 | } else { | ||
654 | /* scan in ibss */ | ||
655 | /* we don't do iscan in ibss */ | ||
656 | ssids = this_ssid; | ||
657 | } | ||
658 | |||
659 | cfg->scan_request = request; | ||
660 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | ||
661 | if (iscan_req) { | ||
662 | err = brcmf_do_iscan(cfg); | ||
663 | if (!err) | ||
664 | return err; | ||
665 | else | ||
666 | goto scan_out; | ||
667 | } else { | ||
668 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", | ||
669 | ssids->ssid, ssids->ssid_len); | ||
670 | memset(&sr->ssid_le, 0, sizeof(sr->ssid_le)); | ||
671 | SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len); | ||
672 | sr->ssid_le.SSID_len = cpu_to_le32(0); | ||
673 | if (SSID_len) { | ||
674 | memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len); | ||
675 | sr->ssid_le.SSID_len = cpu_to_le32(SSID_len); | ||
676 | spec_scan = true; | ||
677 | } else { | ||
678 | WL_SCAN("Broadcast scan\n"); | ||
679 | } | ||
680 | |||
681 | passive_scan = cfg->active_scan ? 0 : 1; | ||
682 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN, | ||
683 | passive_scan); | ||
684 | if (err) { | ||
685 | WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); | ||
686 | goto scan_out; | ||
687 | } | ||
688 | brcmf_set_mpc(ndev, 0); | ||
689 | err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, | ||
690 | &sr->ssid_le, sizeof(sr->ssid_le)); | ||
691 | if (err) { | ||
692 | if (err == -EBUSY) | ||
693 | WL_INFO("system busy : scan for \"%s\" " | ||
694 | "canceled\n", sr->ssid_le.SSID); | ||
695 | else | ||
696 | WL_ERR("WLC_SCAN error (%d)\n", err); | ||
697 | |||
698 | brcmf_set_mpc(ndev, 1); | ||
699 | goto scan_out; | ||
700 | } | ||
701 | } | ||
702 | |||
703 | return 0; | ||
704 | |||
705 | scan_out: | ||
706 | clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | ||
707 | cfg->scan_request = NULL; | ||
708 | return err; | ||
709 | } | ||
710 | |||
711 | static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, | 518 | static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, |
712 | struct cfg80211_scan_request *request) | 519 | struct cfg80211_scan_request *request) |
713 | { | 520 | { |
@@ -931,7 +738,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, | |||
931 | struct brcmf_if *ifp = netdev_priv(ndev); | 738 | struct brcmf_if *ifp = netdev_priv(ndev); |
932 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | 739 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); |
933 | struct cfg80211_ssid *ssids; | 740 | struct cfg80211_ssid *ssids; |
934 | struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int; | 741 | struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int; |
935 | u32 passive_scan; | 742 | u32 passive_scan; |
936 | bool escan_req; | 743 | bool escan_req; |
937 | bool spec_scan; | 744 | bool spec_scan; |
@@ -973,9 +780,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev, | |||
973 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); | 780 | set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); |
974 | if (escan_req) { | 781 | if (escan_req) { |
975 | err = brcmf_do_escan(cfg, wiphy, ndev, request); | 782 | err = brcmf_do_escan(cfg, wiphy, ndev, request); |
976 | if (!err) | 783 | if (err) |
977 | return err; | ||
978 | else | ||
979 | goto scan_out; | 784 | goto scan_out; |
980 | } else { | 785 | } else { |
981 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", | 786 | WL_SCAN("ssid \"%s\", ssid_len (%d)\n", |
@@ -1027,7 +832,6 @@ static s32 | |||
1027 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) | 832 | brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) |
1028 | { | 833 | { |
1029 | struct net_device *ndev = request->wdev->netdev; | 834 | struct net_device *ndev = request->wdev->netdev; |
1030 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
1031 | s32 err = 0; | 835 | s32 err = 0; |
1032 | 836 | ||
1033 | WL_TRACE("Enter\n"); | 837 | WL_TRACE("Enter\n"); |
@@ -1036,10 +840,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) | |||
1036 | struct brcmf_cfg80211_vif, wdev))) | 840 | struct brcmf_cfg80211_vif, wdev))) |
1037 | return -EIO; | 841 | return -EIO; |
1038 | 842 | ||
1039 | if (cfg->iscan_on) | 843 | err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); |
1040 | err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL); | ||
1041 | else if (cfg->escan_on) | ||
1042 | err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL); | ||
1043 | 844 | ||
1044 | if (err) | 845 | if (err) |
1045 | WL_ERR("scan error (%d)\n", err); | 846 | WL_ERR("scan error (%d)\n", err); |
@@ -1075,7 +876,7 @@ static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) | |||
1075 | static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) | 876 | static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) |
1076 | { | 877 | { |
1077 | s32 err = 0; | 878 | s32 err = 0; |
1078 | u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL); | 879 | u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); |
1079 | 880 | ||
1080 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); | 881 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); |
1081 | if (err) { | 882 | if (err) { |
@@ -1212,8 +1013,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1212 | else | 1013 | else |
1213 | WL_CONN("No BSSID specified\n"); | 1014 | WL_CONN("No BSSID specified\n"); |
1214 | 1015 | ||
1215 | if (params->channel) | 1016 | if (params->chandef.chan) |
1216 | WL_CONN("channel: %d\n", params->channel->center_freq); | 1017 | WL_CONN("channel: %d\n", params->chandef.chan->center_freq); |
1217 | else | 1018 | else |
1218 | WL_CONN("no channel specified\n"); | 1019 | WL_CONN("no channel specified\n"); |
1219 | 1020 | ||
@@ -1258,7 +1059,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1258 | else | 1059 | else |
1259 | bcnprd = 100; | 1060 | bcnprd = 100; |
1260 | 1061 | ||
1261 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_BCNPRD, bcnprd); | 1062 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); |
1262 | if (err) { | 1063 | if (err) { |
1263 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); | 1064 | WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err); |
1264 | goto done; | 1065 | goto done; |
@@ -1286,12 +1087,12 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1286 | } | 1087 | } |
1287 | 1088 | ||
1288 | /* Channel */ | 1089 | /* Channel */ |
1289 | if (params->channel) { | 1090 | if (params->chandef.chan) { |
1290 | u32 target_channel; | 1091 | u32 target_channel; |
1291 | 1092 | ||
1292 | cfg->channel = | 1093 | cfg->channel = |
1293 | ieee80211_frequency_to_channel( | 1094 | ieee80211_frequency_to_channel( |
1294 | params->channel->center_freq); | 1095 | params->chandef.chan->center_freq); |
1295 | if (params->channel_fixed) { | 1096 | if (params->channel_fixed) { |
1296 | /* adding chanspec */ | 1097 | /* adding chanspec */ |
1297 | brcmf_ch_to_chanspec(cfg->channel, | 1098 | brcmf_ch_to_chanspec(cfg->channel, |
@@ -1300,7 +1101,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, | |||
1300 | 1101 | ||
1301 | /* set channel for starter */ | 1102 | /* set channel for starter */ |
1302 | target_channel = cfg->channel; | 1103 | target_channel = cfg->channel; |
1303 | err = brcmf_fil_cmd_int_set(ifp, BRCM_SET_CHANNEL, | 1104 | err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, |
1304 | target_channel); | 1105 | target_channel); |
1305 | if (err) { | 1106 | if (err) { |
1306 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); | 1107 | WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err); |
@@ -1721,7 +1522,7 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, | |||
1721 | } | 1522 | } |
1722 | 1523 | ||
1723 | static s32 | 1524 | static s32 |
1724 | brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, | 1525 | brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, |
1725 | enum nl80211_tx_power_setting type, s32 mbm) | 1526 | enum nl80211_tx_power_setting type, s32 mbm) |
1726 | { | 1527 | { |
1727 | 1528 | ||
@@ -1770,7 +1571,9 @@ done: | |||
1770 | return err; | 1571 | return err; |
1771 | } | 1572 | } |
1772 | 1573 | ||
1773 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) | 1574 | static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, |
1575 | struct wireless_dev *wdev, | ||
1576 | s32 *dbm) | ||
1774 | { | 1577 | { |
1775 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | 1578 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); |
1776 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | 1579 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); |
@@ -2014,6 +1817,12 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2014 | if (!check_vif_up(ifp->vif)) | 1817 | if (!check_vif_up(ifp->vif)) |
2015 | return -EIO; | 1818 | return -EIO; |
2016 | 1819 | ||
1820 | if (key_idx >= DOT11_MAX_DEFAULT_KEYS) { | ||
1821 | /* we ignore this key index in this case */ | ||
1822 | WL_ERR("invalid key index (%d)\n", key_idx); | ||
1823 | return -EINVAL; | ||
1824 | } | ||
1825 | |||
2017 | memset(&key, 0, sizeof(key)); | 1826 | memset(&key, 0, sizeof(key)); |
2018 | 1827 | ||
2019 | key.index = (u32) key_idx; | 1828 | key.index = (u32) key_idx; |
@@ -2024,15 +1833,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, | |||
2024 | 1833 | ||
2025 | /* Set the new key/index */ | 1834 | /* Set the new key/index */ |
2026 | err = send_key_to_dongle(ndev, &key); | 1835 | err = send_key_to_dongle(ndev, &key); |
2027 | if (err) { | ||
2028 | if (err == -EINVAL) { | ||
2029 | if (key.index >= DOT11_MAX_DEFAULT_KEYS) | ||
2030 | /* we ignore this key index in this case */ | ||
2031 | WL_ERR("invalid key index (%d)\n", key_idx); | ||
2032 | } | ||
2033 | /* Ignore this error, may happen during DISASSOC */ | ||
2034 | err = -EAGAIN; | ||
2035 | } | ||
2036 | 1836 | ||
2037 | WL_TRACE("Exit\n"); | 1837 | WL_TRACE("Exit\n"); |
2038 | return err; | 1838 | return err; |
@@ -2239,7 +2039,7 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev, | |||
2239 | 2039 | ||
2240 | /* addr param is always NULL. ignore it */ | 2040 | /* addr param is always NULL. ignore it */ |
2241 | /* Get current rateset */ | 2041 | /* Get current rateset */ |
2242 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_CURR_RATESET, | 2042 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET, |
2243 | &rateset_le, sizeof(rateset_le)); | 2043 | &rateset_le, sizeof(rateset_le)); |
2244 | if (err) { | 2044 | if (err) { |
2245 | WL_ERR("could not get current rateset (%d)\n", err); | 2045 | WL_ERR("could not get current rateset (%d)\n", err); |
@@ -2354,13 +2154,14 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) | |||
2354 | int i; | 2154 | int i; |
2355 | 2155 | ||
2356 | bss_list = cfg->bss_list; | 2156 | bss_list = cfg->bss_list; |
2357 | if (bss_list->version != BRCMF_BSS_INFO_VERSION) { | 2157 | if (bss_list->count != 0 && |
2158 | bss_list->version != BRCMF_BSS_INFO_VERSION) { | ||
2358 | WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", | 2159 | WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", |
2359 | bss_list->version); | 2160 | bss_list->version); |
2360 | return -EOPNOTSUPP; | 2161 | return -EOPNOTSUPP; |
2361 | } | 2162 | } |
2362 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); | 2163 | WL_SCAN("scanned AP count (%d)\n", bss_list->count); |
2363 | for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { | 2164 | for (i = 0; i < bss_list->count; i++) { |
2364 | bi = next_bss_le(bss_list, bi); | 2165 | bi = next_bss_le(bss_list, bi); |
2365 | err = brcmf_inform_single_bss(cfg, bi); | 2166 | err = brcmf_inform_single_bss(cfg, bi); |
2366 | if (err) | 2167 | if (err) |
@@ -2582,33 +2383,10 @@ update_bss_info_out: | |||
2582 | 2383 | ||
2583 | static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) | 2384 | static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) |
2584 | { | 2385 | { |
2585 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2586 | struct escan_info *escan = &cfg->escan_info; | 2386 | struct escan_info *escan = &cfg->escan_info; |
2587 | struct brcmf_ssid ssid; | ||
2588 | 2387 | ||
2589 | set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); | 2388 | set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
2590 | if (cfg->iscan_on) { | 2389 | if (cfg->scan_request) { |
2591 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2592 | |||
2593 | if (iscan->timer_on) { | ||
2594 | del_timer_sync(&iscan->timer); | ||
2595 | iscan->timer_on = 0; | ||
2596 | } | ||
2597 | |||
2598 | cancel_work_sync(&iscan->work); | ||
2599 | |||
2600 | /* Abort iscan running in FW */ | ||
2601 | memset(&ssid, 0, sizeof(ssid)); | ||
2602 | brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); | ||
2603 | |||
2604 | if (cfg->scan_request) { | ||
2605 | /* Indidate scan abort to cfg80211 layer */ | ||
2606 | WL_INFO("Terminating scan in progress\n"); | ||
2607 | cfg80211_scan_done(cfg->scan_request, true); | ||
2608 | cfg->scan_request = NULL; | ||
2609 | } | ||
2610 | } | ||
2611 | if (cfg->escan_on && cfg->scan_request) { | ||
2612 | escan->escan_state = WL_ESCAN_STATE_IDLE; | 2390 | escan->escan_state = WL_ESCAN_STATE_IDLE; |
2613 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); | 2391 | brcmf_notify_escan_complete(cfg, escan->ndev, true, true); |
2614 | } | 2392 | } |
@@ -2616,198 +2394,6 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) | |||
2616 | clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); | 2394 | clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status); |
2617 | } | 2395 | } |
2618 | 2396 | ||
2619 | static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, | ||
2620 | bool aborted) | ||
2621 | { | ||
2622 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); | ||
2623 | struct net_device *ndev = cfg_to_ndev(cfg); | ||
2624 | |||
2625 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
2626 | WL_ERR("Scan complete while device not scanning\n"); | ||
2627 | return; | ||
2628 | } | ||
2629 | if (cfg->scan_request) { | ||
2630 | WL_SCAN("ISCAN Completed scan: %s\n", | ||
2631 | aborted ? "Aborted" : "Done"); | ||
2632 | cfg80211_scan_done(cfg->scan_request, aborted); | ||
2633 | brcmf_set_mpc(ndev, 1); | ||
2634 | cfg->scan_request = NULL; | ||
2635 | } | ||
2636 | cfg->iscan_kickstart = false; | ||
2637 | } | ||
2638 | |||
2639 | static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) | ||
2640 | { | ||
2641 | if (iscan->state != WL_ISCAN_STATE_IDLE) { | ||
2642 | WL_SCAN("wake up iscan\n"); | ||
2643 | schedule_work(&iscan->work); | ||
2644 | return 0; | ||
2645 | } | ||
2646 | |||
2647 | return -EIO; | ||
2648 | } | ||
2649 | |||
2650 | static s32 | ||
2651 | brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, | ||
2652 | struct brcmf_scan_results **bss_list) | ||
2653 | { | ||
2654 | struct brcmf_scan_results *results; | ||
2655 | struct brcmf_scan_results_le *results_le; | ||
2656 | struct brcmf_iscan_results *list_buf; | ||
2657 | s32 err = 0; | ||
2658 | |||
2659 | memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX); | ||
2660 | list_buf = (struct brcmf_iscan_results *)iscan->scan_buf; | ||
2661 | results = &list_buf->results; | ||
2662 | results_le = &list_buf->results_le; | ||
2663 | results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf)); | ||
2664 | results_le->version = 0; | ||
2665 | results_le->count = 0; | ||
2666 | |||
2667 | err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults", | ||
2668 | iscan->scan_buf, | ||
2669 | sizeof(iscan->scan_buf)); | ||
2670 | if (err) { | ||
2671 | WL_ERR("error (%d)\n", err); | ||
2672 | return err; | ||
2673 | } | ||
2674 | results->buflen = le32_to_cpu(results_le->buflen); | ||
2675 | results->version = le32_to_cpu(results_le->version); | ||
2676 | results->count = le32_to_cpu(results_le->count); | ||
2677 | WL_SCAN("results->count = %d\n", results_le->count); | ||
2678 | WL_SCAN("results->buflen = %d\n", results_le->buflen); | ||
2679 | *status = le32_to_cpu(list_buf->status_le); | ||
2680 | WL_SCAN("status = %d\n", *status); | ||
2681 | *bss_list = results; | ||
2682 | |||
2683 | return err; | ||
2684 | } | ||
2685 | |||
2686 | static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg) | ||
2687 | { | ||
2688 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2689 | s32 err = 0; | ||
2690 | |||
2691 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2692 | brcmf_inform_bss(cfg); | ||
2693 | brcmf_notify_iscan_complete(iscan, false); | ||
2694 | |||
2695 | return err; | ||
2696 | } | ||
2697 | |||
2698 | static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg) | ||
2699 | { | ||
2700 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2701 | s32 err = 0; | ||
2702 | |||
2703 | /* Reschedule the timer */ | ||
2704 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
2705 | iscan->timer_on = 1; | ||
2706 | |||
2707 | return err; | ||
2708 | } | ||
2709 | |||
2710 | static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg) | ||
2711 | { | ||
2712 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2713 | s32 err = 0; | ||
2714 | |||
2715 | brcmf_inform_bss(cfg); | ||
2716 | brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); | ||
2717 | /* Reschedule the timer */ | ||
2718 | mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); | ||
2719 | iscan->timer_on = 1; | ||
2720 | |||
2721 | return err; | ||
2722 | } | ||
2723 | |||
2724 | static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg) | ||
2725 | { | ||
2726 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan; | ||
2727 | s32 err = 0; | ||
2728 | |||
2729 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2730 | brcmf_notify_iscan_complete(iscan, true); | ||
2731 | |||
2732 | return err; | ||
2733 | } | ||
2734 | |||
2735 | static void brcmf_cfg80211_iscan_handler(struct work_struct *work) | ||
2736 | { | ||
2737 | struct brcmf_cfg80211_iscan_ctrl *iscan = | ||
2738 | container_of(work, struct brcmf_cfg80211_iscan_ctrl, | ||
2739 | work); | ||
2740 | struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan); | ||
2741 | struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; | ||
2742 | u32 status = BRCMF_SCAN_RESULTS_PARTIAL; | ||
2743 | |||
2744 | if (iscan->timer_on) { | ||
2745 | del_timer_sync(&iscan->timer); | ||
2746 | iscan->timer_on = 0; | ||
2747 | } | ||
2748 | |||
2749 | if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) { | ||
2750 | status = BRCMF_SCAN_RESULTS_ABORTED; | ||
2751 | WL_ERR("Abort iscan\n"); | ||
2752 | } | ||
2753 | |||
2754 | el->handler[status](cfg); | ||
2755 | } | ||
2756 | |||
2757 | static void brcmf_iscan_timer(unsigned long data) | ||
2758 | { | ||
2759 | struct brcmf_cfg80211_iscan_ctrl *iscan = | ||
2760 | (struct brcmf_cfg80211_iscan_ctrl *)data; | ||
2761 | |||
2762 | if (iscan) { | ||
2763 | iscan->timer_on = 0; | ||
2764 | WL_SCAN("timer expired\n"); | ||
2765 | brcmf_wakeup_iscan(iscan); | ||
2766 | } | ||
2767 | } | ||
2768 | |||
2769 | static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg) | ||
2770 | { | ||
2771 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2772 | |||
2773 | if (cfg->iscan_on) { | ||
2774 | iscan->state = WL_ISCAN_STATE_IDLE; | ||
2775 | INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); | ||
2776 | } | ||
2777 | |||
2778 | return 0; | ||
2779 | } | ||
2780 | |||
2781 | static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) | ||
2782 | { | ||
2783 | memset(el, 0, sizeof(*el)); | ||
2784 | el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done; | ||
2785 | el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress; | ||
2786 | el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending; | ||
2787 | el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted; | ||
2788 | el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; | ||
2789 | } | ||
2790 | |||
2791 | static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg) | ||
2792 | { | ||
2793 | struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg); | ||
2794 | int err = 0; | ||
2795 | |||
2796 | if (cfg->iscan_on) { | ||
2797 | iscan->ndev = cfg_to_ndev(cfg); | ||
2798 | brcmf_init_iscan_eloop(&iscan->el); | ||
2799 | iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; | ||
2800 | init_timer(&iscan->timer); | ||
2801 | iscan->timer.data = (unsigned long) iscan; | ||
2802 | iscan->timer.function = brcmf_iscan_timer; | ||
2803 | err = brcmf_invoke_iscan(cfg); | ||
2804 | if (!err) | ||
2805 | iscan->data = cfg; | ||
2806 | } | ||
2807 | |||
2808 | return err; | ||
2809 | } | ||
2810 | |||
2811 | static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) | 2397 | static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) |
2812 | { | 2398 | { |
2813 | struct brcmf_cfg80211_info *cfg = | 2399 | struct brcmf_cfg80211_info *cfg = |
@@ -2825,8 +2411,7 @@ static void brcmf_escan_timeout(unsigned long data) | |||
2825 | 2411 | ||
2826 | if (cfg->scan_request) { | 2412 | if (cfg->scan_request) { |
2827 | WL_ERR("timer expired\n"); | 2413 | WL_ERR("timer expired\n"); |
2828 | if (cfg->escan_on) | 2414 | schedule_work(&cfg->escan_timeout_work); |
2829 | schedule_work(&cfg->escan_timeout_work); | ||
2830 | } | 2415 | } |
2831 | } | 2416 | } |
2832 | 2417 | ||
@@ -2863,10 +2448,11 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss, | |||
2863 | } | 2448 | } |
2864 | 2449 | ||
2865 | static s32 | 2450 | static s32 |
2866 | brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, | 2451 | brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, |
2867 | struct net_device *ndev, | ||
2868 | const struct brcmf_event_msg *e, void *data) | 2452 | const struct brcmf_event_msg *e, void *data) |
2869 | { | 2453 | { |
2454 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
2455 | struct net_device *ndev = ifp->ndev; | ||
2870 | s32 status; | 2456 | s32 status; |
2871 | s32 err = 0; | 2457 | s32 err = 0; |
2872 | struct brcmf_escan_result_le *escan_result_le; | 2458 | struct brcmf_escan_result_le *escan_result_le; |
@@ -2877,13 +2463,11 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, | |||
2877 | u32 i; | 2463 | u32 i; |
2878 | bool aborted; | 2464 | bool aborted; |
2879 | 2465 | ||
2880 | status = be32_to_cpu(e->status); | 2466 | status = e->status; |
2881 | 2467 | ||
2882 | if (!ndev || !cfg->escan_on || | 2468 | if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { |
2883 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | 2469 | WL_ERR("scan not ready ndev %p drv_status %x\n", ndev, |
2884 | WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n", | 2470 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); |
2885 | ndev, cfg->escan_on, | ||
2886 | !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)); | ||
2887 | return -EPERM; | 2471 | return -EPERM; |
2888 | } | 2472 | } |
2889 | 2473 | ||
@@ -2960,18 +2544,15 @@ exit: | |||
2960 | 2544 | ||
2961 | static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) | 2545 | static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) |
2962 | { | 2546 | { |
2963 | 2547 | brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT, | |
2964 | if (cfg->escan_on) { | 2548 | brcmf_cfg80211_escan_handler); |
2965 | cfg->el.handler[BRCMF_E_ESCAN_RESULT] = | 2549 | cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; |
2966 | brcmf_cfg80211_escan_handler; | 2550 | /* Init scan_timeout timer */ |
2967 | cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE; | 2551 | init_timer(&cfg->escan_timeout); |
2968 | /* Init scan_timeout timer */ | 2552 | cfg->escan_timeout.data = (unsigned long) cfg; |
2969 | init_timer(&cfg->escan_timeout); | 2553 | cfg->escan_timeout.function = brcmf_escan_timeout; |
2970 | cfg->escan_timeout.data = (unsigned long) cfg; | 2554 | INIT_WORK(&cfg->escan_timeout_work, |
2971 | cfg->escan_timeout.function = brcmf_escan_timeout; | 2555 | brcmf_cfg80211_escan_timeout_worker); |
2972 | INIT_WORK(&cfg->escan_timeout_work, | ||
2973 | brcmf_cfg80211_escan_timeout_worker); | ||
2974 | } | ||
2975 | } | 2556 | } |
2976 | 2557 | ||
2977 | static __always_inline void brcmf_delay(u32 ms) | 2558 | static __always_inline void brcmf_delay(u32 ms) |
@@ -2986,20 +2567,8 @@ static __always_inline void brcmf_delay(u32 ms) | |||
2986 | 2567 | ||
2987 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) | 2568 | static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) |
2988 | { | 2569 | { |
2989 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
2990 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
2991 | |||
2992 | /* | ||
2993 | * Check for BRCMF_VIF_STATUS_READY before any function call which | ||
2994 | * could result is bus access. Don't block the resume for | ||
2995 | * any driver error conditions | ||
2996 | */ | ||
2997 | WL_TRACE("Enter\n"); | 2570 | WL_TRACE("Enter\n"); |
2998 | 2571 | ||
2999 | if (check_vif_up(ifp->vif)) | ||
3000 | brcmf_invoke_iscan(cfg); | ||
3001 | |||
3002 | WL_TRACE("Exit\n"); | ||
3003 | return 0; | 2572 | return 0; |
3004 | } | 2573 | } |
3005 | 2574 | ||
@@ -3198,10 +2767,11 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) | |||
3198 | * cfg80211_scan_request one out of the received PNO event. | 2767 | * cfg80211_scan_request one out of the received PNO event. |
3199 | */ | 2768 | */ |
3200 | static s32 | 2769 | static s32 |
3201 | brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, | 2770 | brcmf_notify_sched_scan_results(struct brcmf_if *ifp, |
3202 | struct net_device *ndev, | ||
3203 | const struct brcmf_event_msg *e, void *data) | 2771 | const struct brcmf_event_msg *e, void *data) |
3204 | { | 2772 | { |
2773 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
2774 | struct net_device *ndev = ifp->ndev; | ||
3205 | struct brcmf_pno_net_info_le *netinfo, *netinfo_start; | 2775 | struct brcmf_pno_net_info_le *netinfo, *netinfo_start; |
3206 | struct cfg80211_scan_request *request = NULL; | 2776 | struct cfg80211_scan_request *request = NULL; |
3207 | struct cfg80211_ssid *ssid = NULL; | 2777 | struct cfg80211_ssid *ssid = NULL; |
@@ -3216,7 +2786,7 @@ brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, | |||
3216 | 2786 | ||
3217 | WL_SCAN("Enter\n"); | 2787 | WL_SCAN("Enter\n"); |
3218 | 2788 | ||
3219 | if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) { | 2789 | if (e->event_code == BRCMF_E_PFN_NET_LOST) { |
3220 | WL_SCAN("PFN NET LOST event. Do Nothing\n"); | 2790 | WL_SCAN("PFN NET LOST event. Do Nothing\n"); |
3221 | return 0; | 2791 | return 0; |
3222 | } | 2792 | } |
@@ -3309,7 +2879,6 @@ out_err: | |||
3309 | return err; | 2879 | return err; |
3310 | } | 2880 | } |
3311 | 2881 | ||
3312 | #ifndef CONFIG_BRCMISCAN | ||
3313 | static int brcmf_dev_pno_clean(struct net_device *ndev) | 2882 | static int brcmf_dev_pno_clean(struct net_device *ndev) |
3314 | { | 2883 | { |
3315 | int ret; | 2884 | int ret; |
@@ -3446,7 +3015,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy, | |||
3446 | brcmf_notify_escan_complete(cfg, ndev, true, true); | 3015 | brcmf_notify_escan_complete(cfg, ndev, true, true); |
3447 | return 0; | 3016 | return 0; |
3448 | } | 3017 | } |
3449 | #endif /* CONFIG_BRCMISCAN */ | ||
3450 | 3018 | ||
3451 | #ifdef CONFIG_NL80211_TESTMODE | 3019 | #ifdef CONFIG_NL80211_TESTMODE |
3452 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) | 3020 | static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) |
@@ -3512,7 +3080,7 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie) | |||
3512 | 3080 | ||
3513 | static s32 | 3081 | static s32 |
3514 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, | 3082 | brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, |
3515 | bool is_rsn_ie, s32 bssidx) | 3083 | bool is_rsn_ie) |
3516 | { | 3084 | { |
3517 | struct brcmf_if *ifp = netdev_priv(ndev); | 3085 | struct brcmf_if *ifp = netdev_priv(ndev); |
3518 | u32 auth = 0; /* d11 open authentication */ | 3086 | u32 auth = 0; /* d11 open authentication */ |
@@ -3689,7 +3257,7 @@ exit: | |||
3689 | } | 3257 | } |
3690 | 3258 | ||
3691 | static s32 | 3259 | static s32 |
3692 | brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, | 3260 | brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len, |
3693 | struct parsed_vndr_ies *vndr_ies) | 3261 | struct parsed_vndr_ies *vndr_ies) |
3694 | { | 3262 | { |
3695 | s32 err = 0; | 3263 | s32 err = 0; |
@@ -3768,13 +3336,12 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) | |||
3768 | return ie_len + VNDR_IE_HDR_SIZE; | 3336 | return ie_len + VNDR_IE_HDR_SIZE; |
3769 | } | 3337 | } |
3770 | 3338 | ||
3771 | static s32 | 3339 | static |
3772 | brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | 3340 | s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, |
3773 | struct net_device *ndev, s32 pktflag, | 3341 | const u8 *vndr_ie_buf, u32 vndr_ie_len) |
3774 | u8 *vndr_ie_buf, u32 vndr_ie_len) | ||
3775 | { | 3342 | { |
3776 | struct brcmf_if *ifp = netdev_priv(ndev); | 3343 | struct brcmf_if *ifp; |
3777 | struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie; | 3344 | struct vif_saved_ie *saved_ie; |
3778 | s32 err = 0; | 3345 | s32 err = 0; |
3779 | u8 *iovar_ie_buf; | 3346 | u8 *iovar_ie_buf; |
3780 | u8 *curr_ie_buf; | 3347 | u8 *curr_ie_buf; |
@@ -3791,8 +3358,12 @@ brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, | |||
3791 | u8 *ptr; | 3358 | u8 *ptr; |
3792 | int remained_buf_len; | 3359 | int remained_buf_len; |
3793 | 3360 | ||
3794 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", | 3361 | if (!vif) |
3795 | brcmf_ndev_bssidx(ndev), pktflag); | 3362 | return -ENODEV; |
3363 | ifp = vif->ifp; | ||
3364 | saved_ie = &vif->saved_ie; | ||
3365 | |||
3366 | WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag); | ||
3796 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 3367 | iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
3797 | if (!iovar_ie_buf) | 3368 | if (!iovar_ie_buf) |
3798 | return -ENOMEM; | 3369 | return -ENOMEM; |
@@ -3932,13 +3503,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
3932 | struct brcmf_tlv *rsn_ie; | 3503 | struct brcmf_tlv *rsn_ie; |
3933 | struct brcmf_vs_tlv *wpa_ie; | 3504 | struct brcmf_vs_tlv *wpa_ie; |
3934 | struct brcmf_join_params join_params; | 3505 | struct brcmf_join_params join_params; |
3935 | struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); | ||
3936 | s32 bssidx = 0; | 3506 | s32 bssidx = 0; |
3937 | 3507 | ||
3938 | WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", | 3508 | WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", |
3939 | settings->channel_type, settings->beacon_interval, | 3509 | cfg80211_get_chandef_type(&settings->chandef), |
3510 | settings->beacon_interval, | ||
3940 | settings->dtim_period); | 3511 | settings->dtim_period); |
3941 | WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n", | 3512 | WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", |
3942 | settings->ssid, settings->ssid_len, settings->auth_type, | 3513 | settings->ssid, settings->ssid_len, settings->auth_type, |
3943 | settings->inactivity_timeout); | 3514 | settings->inactivity_timeout); |
3944 | 3515 | ||
@@ -3990,55 +3561,39 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, | |||
3990 | wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, | 3561 | wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail, |
3991 | settings->beacon.tail_len); | 3562 | settings->beacon.tail_len); |
3992 | 3563 | ||
3993 | kfree(cfg->ap_info->rsn_ie); | ||
3994 | cfg->ap_info->rsn_ie = NULL; | ||
3995 | kfree(cfg->ap_info->wpa_ie); | ||
3996 | cfg->ap_info->wpa_ie = NULL; | ||
3997 | |||
3998 | if ((wpa_ie != NULL || rsn_ie != NULL)) { | 3564 | if ((wpa_ie != NULL || rsn_ie != NULL)) { |
3999 | WL_TRACE("WPA(2) IE is found\n"); | 3565 | WL_TRACE("WPA(2) IE is found\n"); |
4000 | if (wpa_ie != NULL) { | 3566 | if (wpa_ie != NULL) { |
4001 | /* WPA IE */ | 3567 | /* WPA IE */ |
4002 | err = brcmf_configure_wpaie(ndev, wpa_ie, false, | 3568 | err = brcmf_configure_wpaie(ndev, wpa_ie, false); |
4003 | bssidx); | ||
4004 | if (err < 0) | 3569 | if (err < 0) |
4005 | goto exit; | 3570 | goto exit; |
4006 | cfg->ap_info->wpa_ie = kmemdup(wpa_ie, | ||
4007 | wpa_ie->len + | ||
4008 | TLV_HDR_LEN, | ||
4009 | GFP_KERNEL); | ||
4010 | } else { | 3571 | } else { |
4011 | /* RSN IE */ | 3572 | /* RSN IE */ |
4012 | err = brcmf_configure_wpaie(ndev, | 3573 | err = brcmf_configure_wpaie(ndev, |
4013 | (struct brcmf_vs_tlv *)rsn_ie, true, bssidx); | 3574 | (struct brcmf_vs_tlv *)rsn_ie, true); |
4014 | if (err < 0) | 3575 | if (err < 0) |
4015 | goto exit; | 3576 | goto exit; |
4016 | cfg->ap_info->rsn_ie = kmemdup(rsn_ie, | ||
4017 | rsn_ie->len + | ||
4018 | TLV_HDR_LEN, | ||
4019 | GFP_KERNEL); | ||
4020 | } | 3577 | } |
4021 | cfg->ap_info->security_mode = true; | ||
4022 | } else { | 3578 | } else { |
4023 | WL_TRACE("No WPA(2) IEs found\n"); | 3579 | WL_TRACE("No WPA(2) IEs found\n"); |
4024 | brcmf_configure_opensecurity(ndev, bssidx); | 3580 | brcmf_configure_opensecurity(ndev, bssidx); |
4025 | cfg->ap_info->security_mode = false; | ||
4026 | } | 3581 | } |
4027 | /* Set Beacon IEs to FW */ | 3582 | /* Set Beacon IEs to FW */ |
4028 | err = brcmf_set_management_ie(cfg, ndev, | 3583 | err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), |
4029 | VNDR_IE_BEACON_FLAG, | 3584 | VNDR_IE_BEACON_FLAG, |
4030 | (u8 *)settings->beacon.tail, | 3585 | settings->beacon.tail, |
4031 | settings->beacon.tail_len); | 3586 | settings->beacon.tail_len); |
4032 | if (err) | 3587 | if (err) |
4033 | WL_ERR("Set Beacon IE Failed\n"); | 3588 | WL_ERR("Set Beacon IE Failed\n"); |
4034 | else | 3589 | else |
4035 | WL_TRACE("Applied Vndr IEs for Beacon\n"); | 3590 | WL_TRACE("Applied Vndr IEs for Beacon\n"); |
4036 | 3591 | ||
4037 | /* Set Probe Response IEs to FW */ | 3592 | /* Set Probe Response IEs to FW */ |
4038 | err = brcmf_set_management_ie(cfg, ndev, | 3593 | err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev), |
4039 | VNDR_IE_PRBRSP_FLAG, | 3594 | VNDR_IE_PRBRSP_FLAG, |
4040 | (u8 *)settings->beacon.proberesp_ies, | 3595 | settings->beacon.proberesp_ies, |
4041 | settings->beacon.proberesp_ies_len); | 3596 | settings->beacon.proberesp_ies_len); |
4042 | if (err) | 3597 | if (err) |
4043 | WL_ERR("Set Probe Resp IE Failed\n"); | 3598 | WL_ERR("Set Probe Resp IE Failed\n"); |
4044 | else | 3599 | else |
@@ -4169,11 +3724,8 @@ static struct cfg80211_ops wl_cfg80211_ops = { | |||
4169 | .start_ap = brcmf_cfg80211_start_ap, | 3724 | .start_ap = brcmf_cfg80211_start_ap, |
4170 | .stop_ap = brcmf_cfg80211_stop_ap, | 3725 | .stop_ap = brcmf_cfg80211_stop_ap, |
4171 | .del_station = brcmf_cfg80211_del_station, | 3726 | .del_station = brcmf_cfg80211_del_station, |
4172 | #ifndef CONFIG_BRCMISCAN | ||
4173 | /* scheduled scan need e-scan, which is mutual exclusive with i-scan */ | ||
4174 | .sched_scan_start = brcmf_cfg80211_sched_scan_start, | 3727 | .sched_scan_start = brcmf_cfg80211_sched_scan_start, |
4175 | .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, | 3728 | .sched_scan_stop = brcmf_cfg80211_sched_scan_stop, |
4176 | #endif | ||
4177 | #ifdef CONFIG_NL80211_TESTMODE | 3729 | #ifdef CONFIG_NL80211_TESTMODE |
4178 | .testmode_cmd = brcmf_cfg80211_testmode | 3730 | .testmode_cmd = brcmf_cfg80211_testmode |
4179 | #endif | 3731 | #endif |
@@ -4197,13 +3749,11 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode) | |||
4197 | 3749 | ||
4198 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) | 3750 | static void brcmf_wiphy_pno_params(struct wiphy *wiphy) |
4199 | { | 3751 | { |
4200 | #ifndef CONFIG_BRCMISCAN | ||
4201 | /* scheduled scan settings */ | 3752 | /* scheduled scan settings */ |
4202 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; | 3753 | wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT; |
4203 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; | 3754 | wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT; |
4204 | wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; | 3755 | wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; |
4205 | wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; | 3756 | wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; |
4206 | #endif | ||
4207 | } | 3757 | } |
4208 | 3758 | ||
4209 | static struct wiphy *brcmf_setup_wiphy(struct device *phydev) | 3759 | static struct wiphy *brcmf_setup_wiphy(struct device *phydev) |
@@ -4302,8 +3852,8 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif) | |||
4302 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, | 3852 | static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, |
4303 | const struct brcmf_event_msg *e) | 3853 | const struct brcmf_event_msg *e) |
4304 | { | 3854 | { |
4305 | u32 event = be32_to_cpu(e->event_type); | 3855 | u32 event = e->event_code; |
4306 | u32 status = be32_to_cpu(e->status); | 3856 | u32 status = e->status; |
4307 | 3857 | ||
4308 | if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { | 3858 | if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { |
4309 | WL_CONN("Processing set ssid\n"); | 3859 | WL_CONN("Processing set ssid\n"); |
@@ -4317,8 +3867,8 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, | |||
4317 | static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, | 3867 | static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, |
4318 | const struct brcmf_event_msg *e) | 3868 | const struct brcmf_event_msg *e) |
4319 | { | 3869 | { |
4320 | u32 event = be32_to_cpu(e->event_type); | 3870 | u32 event = e->event_code; |
4321 | u16 flags = be16_to_cpu(e->flags); | 3871 | u16 flags = e->flags; |
4322 | 3872 | ||
4323 | if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { | 3873 | if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) { |
4324 | WL_CONN("Processing link down\n"); | 3874 | WL_CONN("Processing link down\n"); |
@@ -4330,13 +3880,12 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, | |||
4330 | static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, | 3880 | static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, |
4331 | const struct brcmf_event_msg *e) | 3881 | const struct brcmf_event_msg *e) |
4332 | { | 3882 | { |
4333 | u32 event = be32_to_cpu(e->event_type); | 3883 | u32 event = e->event_code; |
4334 | u32 status = be32_to_cpu(e->status); | 3884 | u32 status = e->status; |
4335 | 3885 | ||
4336 | if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { | 3886 | if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) { |
4337 | WL_CONN("Processing Link %s & no network found\n", | 3887 | WL_CONN("Processing Link %s & no network found\n", |
4338 | be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ? | 3888 | e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down"); |
4339 | "up" : "down"); | ||
4340 | return true; | 3889 | return true; |
4341 | } | 3890 | } |
4342 | 3891 | ||
@@ -4524,9 +4073,9 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, | |||
4524 | const struct brcmf_event_msg *e, void *data) | 4073 | const struct brcmf_event_msg *e, void *data) |
4525 | { | 4074 | { |
4526 | s32 err = 0; | 4075 | s32 err = 0; |
4527 | u32 event = be32_to_cpu(e->event_type); | 4076 | u32 event = e->event_code; |
4528 | u32 reason = be32_to_cpu(e->reason); | 4077 | u32 reason = e->reason; |
4529 | u32 len = be32_to_cpu(e->datalen); | 4078 | u32 len = e->datalen; |
4530 | static int generation; | 4079 | static int generation; |
4531 | 4080 | ||
4532 | struct station_info sinfo; | 4081 | struct station_info sinfo; |
@@ -4558,11 +4107,11 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg, | |||
4558 | } | 4107 | } |
4559 | 4108 | ||
4560 | static s32 | 4109 | static s32 |
4561 | brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, | 4110 | brcmf_notify_connect_status(struct brcmf_if *ifp, |
4562 | struct net_device *ndev, | ||
4563 | const struct brcmf_event_msg *e, void *data) | 4111 | const struct brcmf_event_msg *e, void *data) |
4564 | { | 4112 | { |
4565 | struct brcmf_if *ifp = netdev_priv(ndev); | 4113 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
4114 | struct net_device *ndev = ifp->ndev; | ||
4566 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; | 4115 | struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; |
4567 | s32 err = 0; | 4116 | s32 err = 0; |
4568 | 4117 | ||
@@ -4610,31 +4159,29 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, | |||
4610 | } | 4159 | } |
4611 | 4160 | ||
4612 | static s32 | 4161 | static s32 |
4613 | brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, | 4162 | brcmf_notify_roaming_status(struct brcmf_if *ifp, |
4614 | struct net_device *ndev, | ||
4615 | const struct brcmf_event_msg *e, void *data) | 4163 | const struct brcmf_event_msg *e, void *data) |
4616 | { | 4164 | { |
4617 | struct brcmf_if *ifp = netdev_priv(ndev); | 4165 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
4618 | s32 err = 0; | 4166 | s32 err = 0; |
4619 | u32 event = be32_to_cpu(e->event_type); | 4167 | u32 event = e->event_code; |
4620 | u32 status = be32_to_cpu(e->status); | 4168 | u32 status = e->status; |
4621 | 4169 | ||
4622 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { | 4170 | if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { |
4623 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) | 4171 | if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) |
4624 | brcmf_bss_roaming_done(cfg, ndev, e); | 4172 | brcmf_bss_roaming_done(cfg, ifp->ndev, e); |
4625 | else | 4173 | else |
4626 | brcmf_bss_connect_done(cfg, ndev, e, true); | 4174 | brcmf_bss_connect_done(cfg, ifp->ndev, e, true); |
4627 | } | 4175 | } |
4628 | 4176 | ||
4629 | return err; | 4177 | return err; |
4630 | } | 4178 | } |
4631 | 4179 | ||
4632 | static s32 | 4180 | static s32 |
4633 | brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, | 4181 | brcmf_notify_mic_status(struct brcmf_if *ifp, |
4634 | struct net_device *ndev, | ||
4635 | const struct brcmf_event_msg *e, void *data) | 4182 | const struct brcmf_event_msg *e, void *data) |
4636 | { | 4183 | { |
4637 | u16 flags = be16_to_cpu(e->flags); | 4184 | u16 flags = e->flags; |
4638 | enum nl80211_key_type key_type; | 4185 | enum nl80211_key_type key_type; |
4639 | 4186 | ||
4640 | if (flags & BRCMF_EVENT_MSG_GROUP) | 4187 | if (flags & BRCMF_EVENT_MSG_GROUP) |
@@ -4642,84 +4189,12 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, | |||
4642 | else | 4189 | else |
4643 | key_type = NL80211_KEYTYPE_PAIRWISE; | 4190 | key_type = NL80211_KEYTYPE_PAIRWISE; |
4644 | 4191 | ||
4645 | cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1, | 4192 | cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1, |
4646 | NULL, GFP_KERNEL); | 4193 | NULL, GFP_KERNEL); |
4647 | 4194 | ||
4648 | return 0; | 4195 | return 0; |
4649 | } | 4196 | } |
4650 | 4197 | ||
4651 | static s32 | ||
4652 | brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg, | ||
4653 | struct net_device *ndev, | ||
4654 | const struct brcmf_event_msg *e, void *data) | ||
4655 | { | ||
4656 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4657 | struct brcmf_channel_info_le channel_inform_le; | ||
4658 | struct brcmf_scan_results_le *bss_list_le; | ||
4659 | u32 len = WL_SCAN_BUF_MAX; | ||
4660 | s32 err = 0; | ||
4661 | bool scan_abort = false; | ||
4662 | u32 scan_channel; | ||
4663 | |||
4664 | WL_TRACE("Enter\n"); | ||
4665 | |||
4666 | if (cfg->iscan_on && cfg->iscan_kickstart) { | ||
4667 | WL_TRACE("Exit\n"); | ||
4668 | return brcmf_wakeup_iscan(cfg_to_iscan(cfg)); | ||
4669 | } | ||
4670 | |||
4671 | if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { | ||
4672 | WL_ERR("Scan complete while device not scanning\n"); | ||
4673 | scan_abort = true; | ||
4674 | err = -EINVAL; | ||
4675 | goto scan_done_out; | ||
4676 | } | ||
4677 | |||
4678 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL, | ||
4679 | &channel_inform_le, | ||
4680 | sizeof(channel_inform_le)); | ||
4681 | if (err) { | ||
4682 | WL_ERR("scan busy (%d)\n", err); | ||
4683 | scan_abort = true; | ||
4684 | goto scan_done_out; | ||
4685 | } | ||
4686 | scan_channel = le32_to_cpu(channel_inform_le.scan_channel); | ||
4687 | if (scan_channel) | ||
4688 | WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); | ||
4689 | cfg->bss_list = cfg->scan_results; | ||
4690 | bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list; | ||
4691 | |||
4692 | memset(cfg->scan_results, 0, len); | ||
4693 | bss_list_le->buflen = cpu_to_le32(len); | ||
4694 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS, | ||
4695 | cfg->scan_results, len); | ||
4696 | if (err) { | ||
4697 | WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); | ||
4698 | err = -EINVAL; | ||
4699 | scan_abort = true; | ||
4700 | goto scan_done_out; | ||
4701 | } | ||
4702 | cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); | ||
4703 | cfg->scan_results->version = le32_to_cpu(bss_list_le->version); | ||
4704 | cfg->scan_results->count = le32_to_cpu(bss_list_le->count); | ||
4705 | |||
4706 | err = brcmf_inform_bss(cfg); | ||
4707 | if (err) | ||
4708 | scan_abort = true; | ||
4709 | |||
4710 | scan_done_out: | ||
4711 | if (cfg->scan_request) { | ||
4712 | WL_SCAN("calling cfg80211_scan_done\n"); | ||
4713 | cfg80211_scan_done(cfg->scan_request, scan_abort); | ||
4714 | brcmf_set_mpc(ndev, 1); | ||
4715 | cfg->scan_request = NULL; | ||
4716 | } | ||
4717 | |||
4718 | WL_TRACE("Exit\n"); | ||
4719 | |||
4720 | return err; | ||
4721 | } | ||
4722 | |||
4723 | static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) | 4198 | static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) |
4724 | { | 4199 | { |
4725 | conf->mode = (u32)-1; | 4200 | conf->mode = (u32)-1; |
@@ -4730,77 +4205,53 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) | |||
4730 | conf->tx_power = -1; | 4205 | conf->tx_power = -1; |
4731 | } | 4206 | } |
4732 | 4207 | ||
4733 | static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) | 4208 | static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg) |
4734 | { | 4209 | { |
4735 | memset(el, 0, sizeof(*el)); | 4210 | brcmf_fweh_register(cfg->pub, BRCMF_E_LINK, |
4736 | el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; | 4211 | brcmf_notify_connect_status); |
4737 | el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; | 4212 | brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND, |
4738 | el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status; | 4213 | brcmf_notify_connect_status); |
4739 | el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status; | 4214 | brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH, |
4740 | el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status; | 4215 | brcmf_notify_connect_status); |
4741 | el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status; | 4216 | brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND, |
4742 | el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status; | 4217 | brcmf_notify_connect_status); |
4743 | el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; | 4218 | brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND, |
4744 | el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; | 4219 | brcmf_notify_connect_status); |
4745 | el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; | 4220 | brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND, |
4746 | el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results; | 4221 | brcmf_notify_connect_status); |
4222 | brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM, | ||
4223 | brcmf_notify_roaming_status); | ||
4224 | brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR, | ||
4225 | brcmf_notify_mic_status); | ||
4226 | brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID, | ||
4227 | brcmf_notify_connect_status); | ||
4228 | brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, | ||
4229 | brcmf_notify_sched_scan_results); | ||
4747 | } | 4230 | } |
4748 | 4231 | ||
4749 | static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) | 4232 | static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) |
4750 | { | 4233 | { |
4751 | kfree(cfg->scan_results); | ||
4752 | cfg->scan_results = NULL; | ||
4753 | kfree(cfg->bss_info); | ||
4754 | cfg->bss_info = NULL; | ||
4755 | kfree(cfg->conf); | 4234 | kfree(cfg->conf); |
4756 | cfg->conf = NULL; | 4235 | cfg->conf = NULL; |
4757 | kfree(cfg->scan_req_int); | ||
4758 | cfg->scan_req_int = NULL; | ||
4759 | kfree(cfg->escan_ioctl_buf); | 4236 | kfree(cfg->escan_ioctl_buf); |
4760 | cfg->escan_ioctl_buf = NULL; | 4237 | cfg->escan_ioctl_buf = NULL; |
4761 | kfree(cfg->dcmd_buf); | ||
4762 | cfg->dcmd_buf = NULL; | ||
4763 | kfree(cfg->extra_buf); | 4238 | kfree(cfg->extra_buf); |
4764 | cfg->extra_buf = NULL; | 4239 | cfg->extra_buf = NULL; |
4765 | kfree(cfg->iscan); | ||
4766 | cfg->iscan = NULL; | ||
4767 | kfree(cfg->pmk_list); | 4240 | kfree(cfg->pmk_list); |
4768 | cfg->pmk_list = NULL; | 4241 | cfg->pmk_list = NULL; |
4769 | if (cfg->ap_info) { | ||
4770 | kfree(cfg->ap_info->wpa_ie); | ||
4771 | kfree(cfg->ap_info->rsn_ie); | ||
4772 | kfree(cfg->ap_info); | ||
4773 | cfg->ap_info = NULL; | ||
4774 | } | ||
4775 | } | 4242 | } |
4776 | 4243 | ||
4777 | static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) | 4244 | static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) |
4778 | { | 4245 | { |
4779 | cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); | ||
4780 | if (!cfg->scan_results) | ||
4781 | goto init_priv_mem_out; | ||
4782 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); | 4246 | cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); |
4783 | if (!cfg->conf) | 4247 | if (!cfg->conf) |
4784 | goto init_priv_mem_out; | 4248 | goto init_priv_mem_out; |
4785 | cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); | ||
4786 | if (!cfg->bss_info) | ||
4787 | goto init_priv_mem_out; | ||
4788 | cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int), | ||
4789 | GFP_KERNEL); | ||
4790 | if (!cfg->scan_req_int) | ||
4791 | goto init_priv_mem_out; | ||
4792 | cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); | 4249 | cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); |
4793 | if (!cfg->escan_ioctl_buf) | 4250 | if (!cfg->escan_ioctl_buf) |
4794 | goto init_priv_mem_out; | 4251 | goto init_priv_mem_out; |
4795 | cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); | ||
4796 | if (!cfg->dcmd_buf) | ||
4797 | goto init_priv_mem_out; | ||
4798 | cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); | 4252 | cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); |
4799 | if (!cfg->extra_buf) | 4253 | if (!cfg->extra_buf) |
4800 | goto init_priv_mem_out; | 4254 | goto init_priv_mem_out; |
4801 | cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL); | ||
4802 | if (!cfg->iscan) | ||
4803 | goto init_priv_mem_out; | ||
4804 | cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); | 4255 | cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL); |
4805 | if (!cfg->pmk_list) | 4256 | if (!cfg->pmk_list) |
4806 | goto init_priv_mem_out; | 4257 | goto init_priv_mem_out; |
@@ -4813,149 +4264,22 @@ init_priv_mem_out: | |||
4813 | return -ENOMEM; | 4264 | return -ENOMEM; |
4814 | } | 4265 | } |
4815 | 4266 | ||
4816 | /* | ||
4817 | * retrieve first queued event from head | ||
4818 | */ | ||
4819 | |||
4820 | static struct brcmf_cfg80211_event_q *brcmf_deq_event( | ||
4821 | struct brcmf_cfg80211_info *cfg) | ||
4822 | { | ||
4823 | struct brcmf_cfg80211_event_q *e = NULL; | ||
4824 | |||
4825 | spin_lock_irq(&cfg->evt_q_lock); | ||
4826 | if (!list_empty(&cfg->evt_q_list)) { | ||
4827 | e = list_first_entry(&cfg->evt_q_list, | ||
4828 | struct brcmf_cfg80211_event_q, evt_q_list); | ||
4829 | list_del(&e->evt_q_list); | ||
4830 | } | ||
4831 | spin_unlock_irq(&cfg->evt_q_lock); | ||
4832 | |||
4833 | return e; | ||
4834 | } | ||
4835 | |||
4836 | /* | ||
4837 | * push event to tail of the queue | ||
4838 | * | ||
4839 | * remark: this function may not sleep as it is called in atomic context. | ||
4840 | */ | ||
4841 | |||
4842 | static s32 | ||
4843 | brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event, | ||
4844 | const struct brcmf_event_msg *msg, void *data) | ||
4845 | { | ||
4846 | struct brcmf_cfg80211_event_q *e; | ||
4847 | s32 err = 0; | ||
4848 | ulong flags; | ||
4849 | u32 data_len; | ||
4850 | u32 total_len; | ||
4851 | |||
4852 | total_len = sizeof(struct brcmf_cfg80211_event_q); | ||
4853 | if (data) | ||
4854 | data_len = be32_to_cpu(msg->datalen); | ||
4855 | else | ||
4856 | data_len = 0; | ||
4857 | total_len += data_len; | ||
4858 | e = kzalloc(total_len, GFP_ATOMIC); | ||
4859 | if (!e) | ||
4860 | return -ENOMEM; | ||
4861 | |||
4862 | e->etype = event; | ||
4863 | memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); | ||
4864 | if (data) | ||
4865 | memcpy(&e->edata, data, data_len); | ||
4866 | |||
4867 | spin_lock_irqsave(&cfg->evt_q_lock, flags); | ||
4868 | list_add_tail(&e->evt_q_list, &cfg->evt_q_list); | ||
4869 | spin_unlock_irqrestore(&cfg->evt_q_lock, flags); | ||
4870 | |||
4871 | return err; | ||
4872 | } | ||
4873 | |||
4874 | static void brcmf_put_event(struct brcmf_cfg80211_event_q *e) | ||
4875 | { | ||
4876 | kfree(e); | ||
4877 | } | ||
4878 | |||
4879 | static void brcmf_cfg80211_event_handler(struct work_struct *work) | ||
4880 | { | ||
4881 | struct brcmf_cfg80211_info *cfg = | ||
4882 | container_of(work, struct brcmf_cfg80211_info, | ||
4883 | event_work); | ||
4884 | struct brcmf_cfg80211_event_q *e; | ||
4885 | |||
4886 | e = brcmf_deq_event(cfg); | ||
4887 | if (unlikely(!e)) { | ||
4888 | WL_ERR("event queue empty...\n"); | ||
4889 | return; | ||
4890 | } | ||
4891 | |||
4892 | do { | ||
4893 | WL_INFO("event type (%d)\n", e->etype); | ||
4894 | if (cfg->el.handler[e->etype]) | ||
4895 | cfg->el.handler[e->etype](cfg, | ||
4896 | cfg_to_ndev(cfg), | ||
4897 | &e->emsg, e->edata); | ||
4898 | else | ||
4899 | WL_INFO("Unknown Event (%d): ignoring\n", e->etype); | ||
4900 | brcmf_put_event(e); | ||
4901 | } while ((e = brcmf_deq_event(cfg))); | ||
4902 | |||
4903 | } | ||
4904 | |||
4905 | static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg) | ||
4906 | { | ||
4907 | spin_lock_init(&cfg->evt_q_lock); | ||
4908 | INIT_LIST_HEAD(&cfg->evt_q_list); | ||
4909 | } | ||
4910 | |||
4911 | static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg) | ||
4912 | { | ||
4913 | struct brcmf_cfg80211_event_q *e; | ||
4914 | |||
4915 | spin_lock_irq(&cfg->evt_q_lock); | ||
4916 | while (!list_empty(&cfg->evt_q_list)) { | ||
4917 | e = list_first_entry(&cfg->evt_q_list, | ||
4918 | struct brcmf_cfg80211_event_q, evt_q_list); | ||
4919 | list_del(&e->evt_q_list); | ||
4920 | kfree(e); | ||
4921 | } | ||
4922 | spin_unlock_irq(&cfg->evt_q_lock); | ||
4923 | } | ||
4924 | |||
4925 | static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) | 4267 | static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) |
4926 | { | 4268 | { |
4927 | s32 err = 0; | 4269 | s32 err = 0; |
4928 | 4270 | ||
4929 | cfg->scan_request = NULL; | 4271 | cfg->scan_request = NULL; |
4930 | cfg->pwr_save = true; | 4272 | cfg->pwr_save = true; |
4931 | #ifdef CONFIG_BRCMISCAN | ||
4932 | cfg->iscan_on = true; /* iscan on & off switch. | ||
4933 | we enable iscan per default */ | ||
4934 | cfg->escan_on = false; /* escan on & off switch. | ||
4935 | we disable escan per default */ | ||
4936 | #else | ||
4937 | cfg->iscan_on = false; /* iscan on & off switch. | ||
4938 | we disable iscan per default */ | ||
4939 | cfg->escan_on = true; /* escan on & off switch. | ||
4940 | we enable escan per default */ | ||
4941 | #endif | ||
4942 | cfg->roam_on = true; /* roam on & off switch. | 4273 | cfg->roam_on = true; /* roam on & off switch. |
4943 | we enable roam per default */ | 4274 | we enable roam per default */ |
4944 | |||
4945 | cfg->iscan_kickstart = false; | ||
4946 | cfg->active_scan = true; /* we do active scan for | 4275 | cfg->active_scan = true; /* we do active scan for |
4947 | specific scan per default */ | 4276 | specific scan per default */ |
4948 | cfg->dongle_up = false; /* dongle is not up yet */ | 4277 | cfg->dongle_up = false; /* dongle is not up yet */ |
4949 | brcmf_init_eq(cfg); | ||
4950 | err = brcmf_init_priv_mem(cfg); | 4278 | err = brcmf_init_priv_mem(cfg); |
4951 | if (err) | 4279 | if (err) |
4952 | return err; | 4280 | return err; |
4953 | INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler); | 4281 | brcmf_register_event_handlers(cfg); |
4954 | brcmf_init_eloop_handler(&cfg->el); | ||
4955 | mutex_init(&cfg->usr_sync); | 4282 | mutex_init(&cfg->usr_sync); |
4956 | err = brcmf_init_iscan(cfg); | ||
4957 | if (err) | ||
4958 | return err; | ||
4959 | brcmf_init_escan(cfg); | 4283 | brcmf_init_escan(cfg); |
4960 | brcmf_init_conf(cfg->conf); | 4284 | brcmf_init_conf(cfg->conf); |
4961 | brcmf_link_down(cfg); | 4285 | brcmf_link_down(cfg); |
@@ -4965,9 +4289,7 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) | |||
4965 | 4289 | ||
4966 | static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) | 4290 | static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) |
4967 | { | 4291 | { |
4968 | cancel_work_sync(&cfg->event_work); | ||
4969 | cfg->dongle_up = false; /* dongle down */ | 4292 | cfg->dongle_up = false; /* dongle down */ |
4970 | brcmf_flush_eq(cfg); | ||
4971 | brcmf_link_down(cfg); | 4293 | brcmf_link_down(cfg); |
4972 | brcmf_abort_scanning(cfg); | 4294 | brcmf_abort_scanning(cfg); |
4973 | brcmf_deinit_priv_mem(cfg); | 4295 | brcmf_deinit_priv_mem(cfg); |
@@ -5029,66 +4351,6 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg) | |||
5029 | } | 4351 | } |
5030 | } | 4352 | } |
5031 | 4353 | ||
5032 | void | ||
5033 | brcmf_cfg80211_event(struct net_device *ndev, | ||
5034 | const struct brcmf_event_msg *e, void *data) | ||
5035 | { | ||
5036 | u32 event_type = be32_to_cpu(e->event_type); | ||
5037 | struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev); | ||
5038 | |||
5039 | if (!brcmf_enq_event(cfg, event_type, e, data)) | ||
5040 | schedule_work(&cfg->event_work); | ||
5041 | } | ||
5042 | |||
5043 | static s32 brcmf_dongle_eventmsg(struct net_device *ndev) | ||
5044 | { | ||
5045 | s8 eventmask[BRCMF_EVENTING_MASK_LEN]; | ||
5046 | s32 err = 0; | ||
5047 | |||
5048 | WL_TRACE("Enter\n"); | ||
5049 | |||
5050 | /* Setup event_msgs */ | ||
5051 | err = brcmf_fil_iovar_data_get(netdev_priv(ndev), "event_msgs", | ||
5052 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
5053 | if (err) { | ||
5054 | WL_ERR("Get event_msgs error (%d)\n", err); | ||
5055 | goto dongle_eventmsg_out; | ||
5056 | } | ||
5057 | |||
5058 | setbit(eventmask, BRCMF_E_SET_SSID); | ||
5059 | setbit(eventmask, BRCMF_E_ROAM); | ||
5060 | setbit(eventmask, BRCMF_E_PRUNE); | ||
5061 | setbit(eventmask, BRCMF_E_AUTH); | ||
5062 | setbit(eventmask, BRCMF_E_REASSOC); | ||
5063 | setbit(eventmask, BRCMF_E_REASSOC_IND); | ||
5064 | setbit(eventmask, BRCMF_E_DEAUTH_IND); | ||
5065 | setbit(eventmask, BRCMF_E_DISASSOC_IND); | ||
5066 | setbit(eventmask, BRCMF_E_DISASSOC); | ||
5067 | setbit(eventmask, BRCMF_E_JOIN); | ||
5068 | setbit(eventmask, BRCMF_E_ASSOC_IND); | ||
5069 | setbit(eventmask, BRCMF_E_PSK_SUP); | ||
5070 | setbit(eventmask, BRCMF_E_LINK); | ||
5071 | setbit(eventmask, BRCMF_E_NDIS_LINK); | ||
5072 | setbit(eventmask, BRCMF_E_MIC_ERROR); | ||
5073 | setbit(eventmask, BRCMF_E_PMKID_CACHE); | ||
5074 | setbit(eventmask, BRCMF_E_TXFAIL); | ||
5075 | setbit(eventmask, BRCMF_E_JOIN_START); | ||
5076 | setbit(eventmask, BRCMF_E_SCAN_COMPLETE); | ||
5077 | setbit(eventmask, BRCMF_E_ESCAN_RESULT); | ||
5078 | setbit(eventmask, BRCMF_E_PFN_NET_FOUND); | ||
5079 | |||
5080 | err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "event_msgs", | ||
5081 | eventmask, BRCMF_EVENTING_MASK_LEN); | ||
5082 | if (err) { | ||
5083 | WL_ERR("Set event_msgs error (%d)\n", err); | ||
5084 | goto dongle_eventmsg_out; | ||
5085 | } | ||
5086 | |||
5087 | dongle_eventmsg_out: | ||
5088 | WL_TRACE("Exit\n"); | ||
5089 | return err; | ||
5090 | } | ||
5091 | |||
5092 | static s32 | 4354 | static s32 |
5093 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) | 4355 | brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) |
5094 | { | 4356 | { |
@@ -5190,7 +4452,7 @@ static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg) | |||
5190 | s8 phy; | 4452 | s8 phy; |
5191 | s32 err = 0; | 4453 | s32 err = 0; |
5192 | 4454 | ||
5193 | err = brcmf_fil_cmd_data_get(ifp, BRCM_GET_PHYLIST, | 4455 | err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST, |
5194 | &phy_list, sizeof(phy_list)); | 4456 | &phy_list, sizeof(phy_list)); |
5195 | if (err) { | 4457 | if (err) { |
5196 | WL_ERR("error (%d)\n", err); | 4458 | WL_ERR("error (%d)\n", err); |
@@ -5228,10 +4490,6 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) | |||
5228 | brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, | 4490 | brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, |
5229 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); | 4491 | WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME); |
5230 | 4492 | ||
5231 | err = brcmf_dongle_eventmsg(ndev); | ||
5232 | if (err) | ||
5233 | goto default_conf_out; | ||
5234 | |||
5235 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; | 4493 | power_mode = cfg->pwr_save ? PM_FAST : PM_OFF; |
5236 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, | 4494 | err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM, |
5237 | power_mode); | 4495 | power_mode); |
@@ -5262,26 +4520,18 @@ default_conf_out: | |||
5262 | 4520 | ||
5263 | } | 4521 | } |
5264 | 4522 | ||
5265 | static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) | 4523 | static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp) |
5266 | { | 4524 | { |
5267 | struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); | ||
5268 | s32 err = 0; | ||
5269 | |||
5270 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); | 4525 | set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state); |
4526 | if (ifp->idx) | ||
4527 | return 0; | ||
5271 | 4528 | ||
5272 | err = brcmf_config_dongle(cfg); | 4529 | return brcmf_config_dongle(ifp->drvr->config); |
5273 | if (err) | ||
5274 | return err; | ||
5275 | |||
5276 | brcmf_invoke_iscan(cfg); | ||
5277 | |||
5278 | return err; | ||
5279 | } | 4530 | } |
5280 | 4531 | ||
5281 | static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | 4532 | static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp) |
5282 | { | 4533 | { |
5283 | struct net_device *ndev = cfg_to_ndev(cfg); | 4534 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; |
5284 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
5285 | 4535 | ||
5286 | /* | 4536 | /* |
5287 | * While going down, if associated with AP disassociate | 4537 | * While going down, if associated with AP disassociate |
@@ -5306,23 +4556,27 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | |||
5306 | return 0; | 4556 | return 0; |
5307 | } | 4557 | } |
5308 | 4558 | ||
5309 | s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) | 4559 | s32 brcmf_cfg80211_up(struct net_device *ndev) |
5310 | { | 4560 | { |
4561 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4562 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
5311 | s32 err = 0; | 4563 | s32 err = 0; |
5312 | 4564 | ||
5313 | mutex_lock(&cfg->usr_sync); | 4565 | mutex_lock(&cfg->usr_sync); |
5314 | err = __brcmf_cfg80211_up(cfg); | 4566 | err = __brcmf_cfg80211_up(ifp); |
5315 | mutex_unlock(&cfg->usr_sync); | 4567 | mutex_unlock(&cfg->usr_sync); |
5316 | 4568 | ||
5317 | return err; | 4569 | return err; |
5318 | } | 4570 | } |
5319 | 4571 | ||
5320 | s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) | 4572 | s32 brcmf_cfg80211_down(struct net_device *ndev) |
5321 | { | 4573 | { |
4574 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
4575 | struct brcmf_cfg80211_info *cfg = ifp->drvr->config; | ||
5322 | s32 err = 0; | 4576 | s32 err = 0; |
5323 | 4577 | ||
5324 | mutex_lock(&cfg->usr_sync); | 4578 | mutex_lock(&cfg->usr_sync); |
5325 | err = __brcmf_cfg80211_down(cfg); | 4579 | err = __brcmf_cfg80211_down(ifp); |
5326 | mutex_unlock(&cfg->usr_sync); | 4580 | mutex_unlock(&cfg->usr_sync); |
5327 | 4581 | ||
5328 | return err; | 4582 | return err; |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 1dd96f148ef7..e2ef8519ea84 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | |||
@@ -84,31 +84,12 @@ do { \ | |||
84 | #define WL_CONN(fmt, args...) | 84 | #define WL_CONN(fmt, args...) |
85 | #endif /* (defined DEBUG) */ | 85 | #endif /* (defined DEBUG) */ |
86 | 86 | ||
87 | #define WL_NUM_SCAN_MAX 1 | 87 | #define WL_NUM_SCAN_MAX 10 |
88 | #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used | 88 | #define WL_NUM_PMKIDS_MAX MAXPMKID |
89 | * for 2.6.33 kernel | ||
90 | * or later | ||
91 | */ | ||
92 | #define WL_SCAN_BUF_MAX (1024 * 8) | ||
93 | #define WL_TLV_INFO_MAX 1024 | 89 | #define WL_TLV_INFO_MAX 1024 |
94 | #define WL_BSS_INFO_MAX 2048 | 90 | #define WL_BSS_INFO_MAX 2048 |
95 | #define WL_ASSOC_INFO_MAX 512 /* | 91 | #define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */ |
96 | * needs to grab assoc info from dongle to | 92 | #define WL_EXTRA_BUF_MAX 2048 |
97 | * report it to cfg80211 through "connect" | ||
98 | * event | ||
99 | */ | ||
100 | #define WL_DCMD_LEN_MAX 1024 | ||
101 | #define WL_EXTRA_BUF_MAX 2048 | ||
102 | #define WL_ISCAN_BUF_MAX 2048 /* | ||
103 | * the buf length can be BRCMF_DCMD_MAXLEN | ||
104 | * to reduce iteration | ||
105 | */ | ||
106 | #define WL_ISCAN_TIMER_INTERVAL_MS 3000 | ||
107 | #define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1) | ||
108 | #define WL_AP_MAX 256 /* virtually unlimitted as long | ||
109 | * as kernel memory allows | ||
110 | */ | ||
111 | |||
112 | #define WL_ROAM_TRIGGER_LEVEL -75 | 93 | #define WL_ROAM_TRIGGER_LEVEL -75 |
113 | #define WL_ROAM_DELTA 20 | 94 | #define WL_ROAM_DELTA 20 |
114 | #define WL_BEACON_TIMEOUT 3 | 95 | #define WL_BEACON_TIMEOUT 3 |
@@ -145,12 +126,6 @@ enum wl_mode { | |||
145 | WL_MODE_AP | 126 | WL_MODE_AP |
146 | }; | 127 | }; |
147 | 128 | ||
148 | /* dongle iscan state */ | ||
149 | enum wl_iscan_state { | ||
150 | WL_ISCAN_STATE_IDLE, | ||
151 | WL_ISCAN_STATE_SCANING | ||
152 | }; | ||
153 | |||
154 | /* dongle configuration */ | 129 | /* dongle configuration */ |
155 | struct brcmf_cfg80211_conf { | 130 | struct brcmf_cfg80211_conf { |
156 | u32 mode; /* adhoc , infrastructure or ap */ | 131 | u32 mode; /* adhoc , infrastructure or ap */ |
@@ -162,17 +137,6 @@ struct brcmf_cfg80211_conf { | |||
162 | struct ieee80211_channel channel; | 137 | struct ieee80211_channel channel; |
163 | }; | 138 | }; |
164 | 139 | ||
165 | /* forward declaration */ | ||
166 | struct brcmf_cfg80211_info; | ||
167 | |||
168 | /* cfg80211 main event loop */ | ||
169 | struct brcmf_cfg80211_event_loop { | ||
170 | s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg, | ||
171 | struct net_device *ndev, | ||
172 | const struct brcmf_event_msg *e, | ||
173 | void *data); | ||
174 | }; | ||
175 | |||
176 | /* basic structure of scan request */ | 140 | /* basic structure of scan request */ |
177 | struct brcmf_cfg80211_scan_req { | 141 | struct brcmf_cfg80211_scan_req { |
178 | struct brcmf_ssid_le ssid_le; | 142 | struct brcmf_ssid_le ssid_le; |
@@ -184,14 +148,6 @@ struct brcmf_cfg80211_ie { | |||
184 | u8 buf[WL_TLV_INFO_MAX]; | 148 | u8 buf[WL_TLV_INFO_MAX]; |
185 | }; | 149 | }; |
186 | 150 | ||
187 | /* event queue for cfg80211 main event */ | ||
188 | struct brcmf_cfg80211_event_q { | ||
189 | struct list_head evt_q_list; | ||
190 | u32 etype; | ||
191 | struct brcmf_event_msg emsg; | ||
192 | s8 edata[1]; | ||
193 | }; | ||
194 | |||
195 | /* security information with currently associated ap */ | 151 | /* security information with currently associated ap */ |
196 | struct brcmf_cfg80211_security { | 152 | struct brcmf_cfg80211_security { |
197 | u32 wpa_versions; | 153 | u32 wpa_versions; |
@@ -270,26 +226,6 @@ struct brcmf_cfg80211_vif { | |||
270 | struct list_head list; | 226 | struct list_head list; |
271 | }; | 227 | }; |
272 | 228 | ||
273 | /* dongle iscan event loop */ | ||
274 | struct brcmf_cfg80211_iscan_eloop { | ||
275 | s32 (*handler[WL_SCAN_ERSULTS_LAST]) | ||
276 | (struct brcmf_cfg80211_info *cfg); | ||
277 | }; | ||
278 | |||
279 | /* dongle iscan controller */ | ||
280 | struct brcmf_cfg80211_iscan_ctrl { | ||
281 | struct net_device *ndev; | ||
282 | struct timer_list timer; | ||
283 | u32 timer_ms; | ||
284 | u32 timer_on; | ||
285 | s32 state; | ||
286 | struct work_struct work; | ||
287 | struct brcmf_cfg80211_iscan_eloop el; | ||
288 | void *data; | ||
289 | s8 dcmd_buf[BRCMF_DCMD_SMLEN]; | ||
290 | s8 scan_buf[WL_ISCAN_BUF_MAX]; | ||
291 | }; | ||
292 | |||
293 | /* association inform */ | 229 | /* association inform */ |
294 | struct brcmf_cfg80211_connect_info { | 230 | struct brcmf_cfg80211_connect_info { |
295 | u8 *req_ie; | 231 | u8 *req_ie; |
@@ -323,17 +259,6 @@ struct escan_info { | |||
323 | struct net_device *ndev; | 259 | struct net_device *ndev; |
324 | }; | 260 | }; |
325 | 261 | ||
326 | /* Structure to hold WPS, WPA IEs for a AP */ | ||
327 | struct ap_info { | ||
328 | u8 probe_res_ie[IE_MAX_LEN]; | ||
329 | u8 beacon_ie[IE_MAX_LEN]; | ||
330 | u32 probe_res_ie_len; | ||
331 | u32 beacon_ie_len; | ||
332 | u8 *wpa_ie; | ||
333 | u8 *rsn_ie; | ||
334 | bool security_mode; | ||
335 | }; | ||
336 | |||
337 | /** | 262 | /** |
338 | * struct brcmf_pno_param_le - PNO scan configuration parameters | 263 | * struct brcmf_pno_param_le - PNO scan configuration parameters |
339 | * | 264 | * |
@@ -421,24 +346,16 @@ struct brcmf_pno_scanresults_le { | |||
421 | * @wiphy: wiphy object for cfg80211 interface. | 346 | * @wiphy: wiphy object for cfg80211 interface. |
422 | * @conf: dongle configuration. | 347 | * @conf: dongle configuration. |
423 | * @scan_request: cfg80211 scan request object. | 348 | * @scan_request: cfg80211 scan request object. |
424 | * @el: main event loop. | ||
425 | * @evt_q_list: used for event queue. | ||
426 | * @evt_q_lock: for event queue synchronization. | ||
427 | * @usr_sync: mainly for dongle up/down synchronization. | 349 | * @usr_sync: mainly for dongle up/down synchronization. |
428 | * @bss_list: bss_list holding scanned ap information. | 350 | * @bss_list: bss_list holding scanned ap information. |
429 | * @scan_results: results of the last scan. | ||
430 | * @scan_req_int: internal scan request object. | 351 | * @scan_req_int: internal scan request object. |
431 | * @bss_info: bss information for cfg80211 layer. | 352 | * @bss_info: bss information for cfg80211 layer. |
432 | * @ie: information element object for internal purpose. | 353 | * @ie: information element object for internal purpose. |
433 | * @iscan: iscan controller information. | ||
434 | * @conn_info: association info. | 354 | * @conn_info: association info. |
435 | * @pmk_list: wpa2 pmk list. | 355 | * @pmk_list: wpa2 pmk list. |
436 | * @event_work: event handler work struct. | ||
437 | * @scan_status: scan activity on the dongle. | 356 | * @scan_status: scan activity on the dongle. |
438 | * @pub: common driver information. | 357 | * @pub: common driver information. |
439 | * @channel: current channel. | 358 | * @channel: current channel. |
440 | * @iscan_on: iscan on/off switch. | ||
441 | * @iscan_kickstart: indicate iscan already started. | ||
442 | * @active_scan: current scan mode. | 359 | * @active_scan: current scan mode. |
443 | * @sched_escan: e-scan for scheduled scan support running. | 360 | * @sched_escan: e-scan for scheduled scan support running. |
444 | * @ibss_starter: indicates this sta is ibss starter. | 361 | * @ibss_starter: indicates this sta is ibss starter. |
@@ -450,12 +367,10 @@ struct brcmf_pno_scanresults_le { | |||
450 | * @dcmd_buf: dcmd buffer. | 367 | * @dcmd_buf: dcmd buffer. |
451 | * @extra_buf: mainly to grab assoc information. | 368 | * @extra_buf: mainly to grab assoc information. |
452 | * @debugfsdir: debugfs folder for this device. | 369 | * @debugfsdir: debugfs folder for this device. |
453 | * @escan_on: escan on/off switch. | ||
454 | * @escan_info: escan information. | 370 | * @escan_info: escan information. |
455 | * @escan_timeout: Timer for catch scan timeout. | 371 | * @escan_timeout: Timer for catch scan timeout. |
456 | * @escan_timeout_work: scan timeout worker. | 372 | * @escan_timeout_work: scan timeout worker. |
457 | * @escan_ioctl_buf: dongle command buffer for escan commands. | 373 | * @escan_ioctl_buf: dongle command buffer for escan commands. |
458 | * @ap_info: host ap information. | ||
459 | * @vif_list: linked list of vif instances. | 374 | * @vif_list: linked list of vif instances. |
460 | * @vif_cnt: number of vif instances. | 375 | * @vif_cnt: number of vif instances. |
461 | */ | 376 | */ |
@@ -463,24 +378,16 @@ struct brcmf_cfg80211_info { | |||
463 | struct wiphy *wiphy; | 378 | struct wiphy *wiphy; |
464 | struct brcmf_cfg80211_conf *conf; | 379 | struct brcmf_cfg80211_conf *conf; |
465 | struct cfg80211_scan_request *scan_request; | 380 | struct cfg80211_scan_request *scan_request; |
466 | struct brcmf_cfg80211_event_loop el; | ||
467 | struct list_head evt_q_list; | ||
468 | spinlock_t evt_q_lock; | ||
469 | struct mutex usr_sync; | 381 | struct mutex usr_sync; |
470 | struct brcmf_scan_results *bss_list; | 382 | struct brcmf_scan_results *bss_list; |
471 | struct brcmf_scan_results *scan_results; | 383 | struct brcmf_cfg80211_scan_req scan_req_int; |
472 | struct brcmf_cfg80211_scan_req *scan_req_int; | ||
473 | struct wl_cfg80211_bss_info *bss_info; | 384 | struct wl_cfg80211_bss_info *bss_info; |
474 | struct brcmf_cfg80211_ie ie; | 385 | struct brcmf_cfg80211_ie ie; |
475 | struct brcmf_cfg80211_iscan_ctrl *iscan; | ||
476 | struct brcmf_cfg80211_connect_info conn_info; | 386 | struct brcmf_cfg80211_connect_info conn_info; |
477 | struct brcmf_cfg80211_pmk_list *pmk_list; | 387 | struct brcmf_cfg80211_pmk_list *pmk_list; |
478 | struct work_struct event_work; | ||
479 | unsigned long scan_status; | 388 | unsigned long scan_status; |
480 | struct brcmf_pub *pub; | 389 | struct brcmf_pub *pub; |
481 | u32 channel; | 390 | u32 channel; |
482 | bool iscan_on; | ||
483 | bool iscan_kickstart; | ||
484 | bool active_scan; | 391 | bool active_scan; |
485 | bool sched_escan; | 392 | bool sched_escan; |
486 | bool ibss_starter; | 393 | bool ibss_starter; |
@@ -492,12 +399,10 @@ struct brcmf_cfg80211_info { | |||
492 | u8 *dcmd_buf; | 399 | u8 *dcmd_buf; |
493 | u8 *extra_buf; | 400 | u8 *extra_buf; |
494 | struct dentry *debugfsdir; | 401 | struct dentry *debugfsdir; |
495 | bool escan_on; | ||
496 | struct escan_info escan_info; | 402 | struct escan_info escan_info; |
497 | struct timer_list escan_timeout; | 403 | struct timer_list escan_timeout; |
498 | struct work_struct escan_timeout_work; | 404 | struct work_struct escan_timeout_work; |
499 | u8 *escan_ioctl_buf; | 405 | u8 *escan_ioctl_buf; |
500 | struct ap_info *ap_info; | ||
501 | struct list_head vif_list; | 406 | struct list_head vif_list; |
502 | u8 vif_cnt; | 407 | u8 vif_cnt; |
503 | }; | 408 | }; |
@@ -536,8 +441,11 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd) | |||
536 | return &ifp->vif->profile; | 441 | return &ifp->vif->profile; |
537 | } | 442 | } |
538 | 443 | ||
539 | #define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data)) | 444 | static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev) |
540 | #define cfg_to_iscan(w) (w->iscan) | 445 | { |
446 | struct brcmf_if *ifp = netdev_priv(ndev); | ||
447 | return ifp->vif; | ||
448 | } | ||
541 | 449 | ||
542 | static inline struct | 450 | static inline struct |
543 | brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) | 451 | brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) |
@@ -547,11 +455,7 @@ brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) | |||
547 | 455 | ||
548 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); | 456 | struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); |
549 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); | 457 | void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); |
550 | 458 | s32 brcmf_cfg80211_up(struct net_device *ndev); | |
551 | /* event handler from dongle */ | 459 | s32 brcmf_cfg80211_down(struct net_device *ndev); |
552 | void brcmf_cfg80211_event(struct net_device *ndev, | ||
553 | const struct brcmf_event_msg *e, void *data); | ||
554 | s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg); | ||
555 | s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg); | ||
556 | 460 | ||
557 | #endif /* _wl_cfg80211_h_ */ | 461 | #endif /* _wl_cfg80211_h_ */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/Makefile b/drivers/net/wireless/brcm80211/brcmsmac/Makefile index e227c4c68ef9..d3d4151c3eda 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/Makefile +++ b/drivers/net/wireless/brcm80211/brcmsmac/Makefile | |||
@@ -40,7 +40,8 @@ BRCMSMAC_OFILES := \ | |||
40 | phy/phytbl_n.o \ | 40 | phy/phytbl_n.o \ |
41 | phy/phy_qmath.o \ | 41 | phy/phy_qmath.o \ |
42 | dma.o \ | 42 | dma.o \ |
43 | brcms_trace_events.o | 43 | brcms_trace_events.o \ |
44 | debug.o | ||
44 | 45 | ||
45 | MODULEPFX := brcmsmac | 46 | MODULEPFX := brcmsmac |
46 | 47 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index be5bcfb9153b..1de94f30564f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include "antsel.h" | 21 | #include "antsel.h" |
22 | #include "main.h" | 22 | #include "main.h" |
23 | #include "ampdu.h" | 23 | #include "ampdu.h" |
24 | #include "debug.h" | ||
25 | #include "brcms_trace_events.h" | ||
24 | 26 | ||
25 | /* max number of mpdus in an ampdu */ | 27 | /* max number of mpdus in an ampdu */ |
26 | #define AMPDU_MAX_MPDU 32 | 28 | #define AMPDU_MAX_MPDU 32 |
@@ -40,8 +42,6 @@ | |||
40 | #define AMPDU_DEF_RETRY_LIMIT 5 | 42 | #define AMPDU_DEF_RETRY_LIMIT 5 |
41 | /* default tx retry limit at reg rate */ | 43 | /* default tx retry limit at reg rate */ |
42 | #define AMPDU_DEF_RR_RETRY_LIMIT 2 | 44 | #define AMPDU_DEF_RR_RETRY_LIMIT 2 |
43 | /* default weight of ampdu in txfifo */ | ||
44 | #define AMPDU_DEF_TXPKT_WEIGHT 2 | ||
45 | /* default ffpld reserved bytes */ | 45 | /* default ffpld reserved bytes */ |
46 | #define AMPDU_DEF_FFPLD_RSVD 2048 | 46 | #define AMPDU_DEF_FFPLD_RSVD 2048 |
47 | /* # of inis to be freed on detach */ | 47 | /* # of inis to be freed on detach */ |
@@ -114,7 +114,6 @@ struct brcms_fifo_info { | |||
114 | * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec | 114 | * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec |
115 | * max_pdu: max pdus allowed in ampdu | 115 | * max_pdu: max pdus allowed in ampdu |
116 | * dur: max duration of an ampdu (in msec) | 116 | * dur: max duration of an ampdu (in msec) |
117 | * txpkt_weight: weight of ampdu in txfifo; reduces rate lag | ||
118 | * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes | 117 | * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes |
119 | * ffpld_rsvd: number of bytes to reserve for preload | 118 | * ffpld_rsvd: number of bytes to reserve for preload |
120 | * max_txlen: max size of ampdu per mcs, bw and sgi | 119 | * max_txlen: max size of ampdu per mcs, bw and sgi |
@@ -136,7 +135,6 @@ struct ampdu_info { | |||
136 | u8 mpdu_density; | 135 | u8 mpdu_density; |
137 | s8 max_pdu; | 136 | s8 max_pdu; |
138 | u8 dur; | 137 | u8 dur; |
139 | u8 txpkt_weight; | ||
140 | u8 rx_factor; | 138 | u8 rx_factor; |
141 | u32 ffpld_rsvd; | 139 | u32 ffpld_rsvd; |
142 | u32 max_txlen[MCS_TABLE_SIZE][2][2]; | 140 | u32 max_txlen[MCS_TABLE_SIZE][2][2]; |
@@ -183,18 +181,19 @@ static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu) | |||
183 | static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) | 181 | static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on) |
184 | { | 182 | { |
185 | struct brcms_c_info *wlc = ampdu->wlc; | 183 | struct brcms_c_info *wlc = ampdu->wlc; |
184 | struct bcma_device *core = wlc->hw->d11core; | ||
186 | 185 | ||
187 | wlc->pub->_ampdu = false; | 186 | wlc->pub->_ampdu = false; |
188 | 187 | ||
189 | if (on) { | 188 | if (on) { |
190 | if (!(wlc->pub->_n_enab & SUPPORT_11N)) { | 189 | if (!(wlc->pub->_n_enab & SUPPORT_11N)) { |
191 | wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not " | 190 | brcms_err(core, "wl%d: driver not nmode enabled\n", |
192 | "nmode enabled\n", wlc->pub->unit); | 191 | wlc->pub->unit); |
193 | return -ENOTSUPP; | 192 | return -ENOTSUPP; |
194 | } | 193 | } |
195 | if (!brcms_c_ampdu_cap(ampdu)) { | 194 | if (!brcms_c_ampdu_cap(ampdu)) { |
196 | wiphy_err(ampdu->wlc->wiphy, "wl%d: device not " | 195 | brcms_err(core, "wl%d: device not ampdu capable\n", |
197 | "ampdu capable\n", wlc->pub->unit); | 196 | wlc->pub->unit); |
198 | return -ENOTSUPP; | 197 | return -ENOTSUPP; |
199 | } | 198 | } |
200 | wlc->pub->_ampdu = on; | 199 | wlc->pub->_ampdu = on; |
@@ -247,7 +246,6 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) | |||
247 | ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; | 246 | ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY; |
248 | ampdu->max_pdu = AUTO; | 247 | ampdu->max_pdu = AUTO; |
249 | ampdu->dur = AMPDU_MAX_DUR; | 248 | ampdu->dur = AMPDU_MAX_DUR; |
250 | ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; | ||
251 | 249 | ||
252 | ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; | 250 | ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; |
253 | /* | 251 | /* |
@@ -374,7 +372,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
374 | offsetof(struct macstat, txfunfl[fid])); | 372 | offsetof(struct macstat, txfunfl[fid])); |
375 | new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); | 373 | new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); |
376 | if (new_txunfl == 0) { | 374 | if (new_txunfl == 0) { |
377 | BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n"); | 375 | brcms_dbg_ht(wlc->hw->d11core, |
376 | "TX status FRAG set but no tx underflows\n"); | ||
378 | return -1; | 377 | return -1; |
379 | } | 378 | } |
380 | fifo->prev_txfunfl = cur_txunfl; | 379 | fifo->prev_txfunfl = cur_txunfl; |
@@ -396,8 +395,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
396 | if (fifo->accum_txfunfl < 10) | 395 | if (fifo->accum_txfunfl < 10) |
397 | return 0; | 396 | return 0; |
398 | 397 | ||
399 | BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n", | 398 | brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", |
400 | current_ampdu_cnt, fifo->accum_txfunfl); | 399 | current_ampdu_cnt, fifo->accum_txfunfl); |
401 | 400 | ||
402 | /* | 401 | /* |
403 | compute the current ratio of tx unfl per ampdu. | 402 | compute the current ratio of tx unfl per ampdu. |
@@ -450,9 +449,10 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) | |||
450 | (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) | 449 | (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) |
451 | / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; | 450 | / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; |
452 | 451 | ||
453 | BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; " | 452 | brcms_dbg_ht(wlc->hw->d11core, |
454 | "pre-load size %d\n", | 453 | "DMA estimated transfer rate %d; " |
455 | fifo->dmaxferrate, fifo->ampdu_pld_size); | 454 | "pre-load size %d\n", |
455 | fifo->dmaxferrate, fifo->ampdu_pld_size); | ||
456 | } else { | 456 | } else { |
457 | 457 | ||
458 | /* decrease ampdu size */ | 458 | /* decrease ampdu size */ |
@@ -486,7 +486,7 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, | |||
486 | scb_ampdu = &scb->scb_ampdu; | 486 | scb_ampdu = &scb->scb_ampdu; |
487 | 487 | ||
488 | if (!ampdu->ini_enable[tid]) { | 488 | if (!ampdu->ini_enable[tid]) { |
489 | wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n", | 489 | brcms_err(wlc->hw->d11core, "%s: Rejecting tid %d\n", |
490 | __func__, tid); | 490 | __func__, tid); |
491 | return; | 491 | return; |
492 | } | 492 | } |
@@ -498,378 +498,324 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, | |||
498 | scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; | 498 | scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; |
499 | } | 499 | } |
500 | 500 | ||
501 | int | 501 | void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, |
502 | brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, | 502 | struct brcms_c_info *wlc) |
503 | struct sk_buff **pdu, int prec) | ||
504 | { | 503 | { |
505 | struct brcms_c_info *wlc; | 504 | session->wlc = wlc; |
506 | struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; | 505 | skb_queue_head_init(&session->skb_list); |
507 | u8 tid, ndelim; | 506 | session->max_ampdu_len = 0; /* determined from first MPDU */ |
508 | int err = 0; | 507 | session->max_ampdu_frames = 0; /* determined from first MPDU */ |
509 | u8 preamble_type = BRCMS_GF_PREAMBLE; | 508 | session->ampdu_len = 0; |
510 | u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; | 509 | session->dma_len = 0; |
511 | u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; | 510 | } |
512 | u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; | ||
513 | 511 | ||
514 | bool rr = true, fbr = false; | 512 | /* |
515 | uint i, count = 0, fifo, seg_cnt = 0; | 513 | * Preps the given packet for AMPDU based on the session data. If the |
516 | u16 plen, len, seq = 0, mcl, mch, index, frameid, dma_len = 0; | 514 | * frame cannot be accomodated in the current session, -ENOSPC is |
517 | u32 ampdu_len, max_ampdu_bytes = 0; | 515 | * returned. |
518 | struct d11txh *txh = NULL; | 516 | */ |
517 | int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, | ||
518 | struct sk_buff *p) | ||
519 | { | ||
520 | struct brcms_c_info *wlc = session->wlc; | ||
521 | struct ampdu_info *ampdu = wlc->ampdu; | ||
522 | struct scb *scb = &wlc->pri_scb; | ||
523 | struct scb_ampdu *scb_ampdu = &scb->scb_ampdu; | ||
524 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); | ||
525 | struct ieee80211_tx_rate *txrate = tx_info->status.rates; | ||
526 | struct d11txh *txh = (struct d11txh *)p->data; | ||
527 | unsigned ampdu_frames; | ||
528 | u8 ndelim, tid; | ||
519 | u8 *plcp; | 529 | u8 *plcp; |
520 | struct ieee80211_hdr *h; | 530 | uint len; |
521 | struct scb *scb; | 531 | u16 mcl; |
522 | struct scb_ampdu *scb_ampdu; | ||
523 | struct scb_ampdu_tid_ini *ini; | ||
524 | u8 mcs = 0; | ||
525 | bool use_rts = false, use_cts = false; | ||
526 | u32 rspec = 0, rspec_fallback = 0; | ||
527 | u32 rts_rspec = 0, rts_rspec_fallback = 0; | ||
528 | u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
529 | struct ieee80211_rts *rts; | ||
530 | u8 rr_retry_limit; | ||
531 | struct brcms_fifo_info *f; | ||
532 | bool fbr_iscck; | 532 | bool fbr_iscck; |
533 | struct ieee80211_tx_info *tx_info; | 533 | bool rr; |
534 | u16 qlen; | ||
535 | struct wiphy *wiphy; | ||
536 | |||
537 | wlc = ampdu->wlc; | ||
538 | wiphy = wlc->wiphy; | ||
539 | p = *pdu; | ||
540 | |||
541 | tid = (u8) (p->priority); | ||
542 | 534 | ||
543 | f = ampdu->fifo_tb + prio2fifo[tid]; | 535 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; |
536 | plcp = (u8 *)(txh + 1); | ||
537 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); | ||
538 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : | ||
539 | BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
540 | len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN; | ||
544 | 541 | ||
545 | scb = &wlc->pri_scb; | 542 | ampdu_frames = skb_queue_len(&session->skb_list); |
546 | scb_ampdu = &scb->scb_ampdu; | 543 | if (ampdu_frames != 0) { |
547 | ini = &scb_ampdu->ini[tid]; | 544 | struct sk_buff *first; |
548 | 545 | ||
549 | /* Let pressure continue to build ... */ | 546 | if (ampdu_frames + 1 > session->max_ampdu_frames || |
550 | qlen = pktq_plen(&qi->q, prec); | 547 | session->ampdu_len + len > session->max_ampdu_len) |
551 | if (ini->tx_in_transit > 0 && | 548 | return -ENOSPC; |
552 | qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) | ||
553 | /* Collect multiple MPDU's to be sent in the next AMPDU */ | ||
554 | return -EBUSY; | ||
555 | 549 | ||
556 | /* at this point we intend to transmit an AMPDU */ | 550 | /* |
557 | rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; | 551 | * We aren't really out of space if the new frame is of |
558 | ampdu_len = 0; | 552 | * a different priority, but we want the same behaviour |
559 | dma_len = 0; | 553 | * so return -ENOSPC anyway. |
560 | while (p) { | 554 | * |
561 | struct ieee80211_tx_rate *txrate; | 555 | * XXX: The old AMPDU code did this, but is it really |
562 | 556 | * necessary? | |
563 | tx_info = IEEE80211_SKB_CB(p); | 557 | */ |
564 | txrate = tx_info->status.rates; | 558 | first = skb_peek(&session->skb_list); |
559 | if (p->priority != first->priority) | ||
560 | return -ENOSPC; | ||
561 | } | ||
565 | 562 | ||
566 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 563 | /* |
567 | err = brcms_c_prep_pdu(wlc, p, &fifo); | 564 | * Now that we're sure this frame can be accomodated, update the |
568 | } else { | 565 | * session information. |
569 | wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__); | 566 | */ |
570 | *pdu = NULL; | 567 | session->ampdu_len += len; |
571 | err = 0; | 568 | session->dma_len += p->len; |
572 | break; | ||
573 | } | ||
574 | 569 | ||
575 | if (err) { | 570 | tid = (u8)p->priority; |
576 | if (err == -EBUSY) { | ||
577 | wiphy_err(wiphy, "wl%d: sendampdu: " | ||
578 | "prep_xdu retry; seq 0x%x\n", | ||
579 | wlc->pub->unit, seq); | ||
580 | *pdu = p; | ||
581 | break; | ||
582 | } | ||
583 | 571 | ||
584 | /* error in the packet; reject it */ | 572 | /* Handle retry limits */ |
585 | wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu " | 573 | if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) { |
586 | "rejected; seq 0x%x\n", wlc->pub->unit, seq); | 574 | txrate[0].count++; |
587 | *pdu = NULL; | 575 | rr = true; |
588 | break; | 576 | } else { |
589 | } | 577 | txrate[1].count++; |
578 | rr = false; | ||
579 | } | ||
590 | 580 | ||
591 | /* pkt is good to be aggregated */ | 581 | if (ampdu_frames == 0) { |
592 | txh = (struct d11txh *) p->data; | 582 | u8 plcp0, plcp3, is40, sgi, mcs; |
593 | plcp = (u8 *) (txh + 1); | 583 | uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; |
594 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); | 584 | struct brcms_fifo_info *f = &du->fifo_tb[fifo]; |
595 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; | ||
596 | index = TX_SEQ_TO_INDEX(seq); | ||
597 | 585 | ||
598 | /* check mcl fields and test whether it can be agg'd */ | 586 | if (rr) { |
599 | mcl = le16_to_cpu(txh->MacTxControlLow); | 587 | plcp0 = plcp[0]; |
600 | mcl &= ~TXC_AMPDU_MASK; | 588 | plcp3 = plcp[3]; |
601 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x3); | ||
602 | txh->PreloadSize = 0; /* always default to 0 */ | ||
603 | |||
604 | /* Handle retry limits */ | ||
605 | if (txrate[0].count <= rr_retry_limit) { | ||
606 | txrate[0].count++; | ||
607 | rr = true; | ||
608 | fbr = false; | ||
609 | } else { | 589 | } else { |
610 | fbr = true; | 590 | plcp0 = txh->FragPLCPFallback[0]; |
611 | rr = false; | 591 | plcp3 = txh->FragPLCPFallback[3]; |
612 | txrate[1].count++; | ||
613 | } | ||
614 | |||
615 | /* extract the length info */ | ||
616 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) | ||
617 | : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
618 | |||
619 | /* retrieve null delimiter count */ | ||
620 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; | ||
621 | seg_cnt += 1; | ||
622 | 592 | ||
623 | BCMMSG(wlc->wiphy, "wl%d: mpdu %d plcp_len %d\n", | ||
624 | wlc->pub->unit, count, len); | ||
625 | |||
626 | /* | ||
627 | * aggregateable mpdu. For ucode/hw agg, | ||
628 | * test whether need to break or change the epoch | ||
629 | */ | ||
630 | if (count == 0) { | ||
631 | mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); | ||
632 | /* refill the bits since might be a retx mpdu */ | ||
633 | mcl |= TXC_STARTMSDU; | ||
634 | rts = (struct ieee80211_rts *)&txh->rts_frame; | ||
635 | |||
636 | if (ieee80211_is_rts(rts->frame_control)) { | ||
637 | mcl |= TXC_SENDRTS; | ||
638 | use_rts = true; | ||
639 | } | ||
640 | if (ieee80211_is_cts(rts->frame_control)) { | ||
641 | mcl |= TXC_SENDCTS; | ||
642 | use_cts = true; | ||
643 | } | ||
644 | } else { | ||
645 | mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); | ||
646 | mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); | ||
647 | } | 593 | } |
648 | 594 | ||
649 | len = roundup(len, 4); | 595 | /* Limit AMPDU size based on MCS */ |
650 | ampdu_len += (len + (ndelim + 1) * AMPDU_DELIMITER_LEN); | 596 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; |
597 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | ||
598 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | ||
599 | session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes, | ||
600 | ampdu->max_txlen[mcs][is40][sgi]); | ||
651 | 601 | ||
652 | dma_len += (u16) p->len; | 602 | session->max_ampdu_frames = scb_ampdu->max_pdu; |
603 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
604 | session->max_ampdu_frames = | ||
605 | min_t(u16, f->mcs2ampdu_table[mcs], | ||
606 | session->max_ampdu_frames); | ||
607 | } | ||
608 | } | ||
653 | 609 | ||
654 | BCMMSG(wlc->wiphy, "wl%d: ampdu_len %d" | 610 | /* |
655 | " seg_cnt %d null delim %d\n", | 611 | * Treat all frames as "middle" frames of AMPDU here. First and |
656 | wlc->pub->unit, ampdu_len, seg_cnt, ndelim); | 612 | * last frames must be fixed up after all MPDUs have been prepped. |
613 | */ | ||
614 | mcl = le16_to_cpu(txh->MacTxControlLow); | ||
615 | mcl &= ~TXC_AMPDU_MASK; | ||
616 | mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT); | ||
617 | mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS); | ||
618 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
619 | txh->PreloadSize = 0; /* always default to 0 */ | ||
657 | 620 | ||
658 | txh->MacTxControlLow = cpu_to_le16(mcl); | 621 | skb_queue_tail(&session->skb_list, p); |
659 | 622 | ||
660 | /* this packet is added */ | 623 | return 0; |
661 | pkt[count++] = p; | 624 | } |
662 | 625 | ||
663 | /* patch the first MPDU */ | 626 | void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) |
664 | if (count == 1) { | 627 | { |
665 | u8 plcp0, plcp3, is40, sgi; | 628 | struct brcms_c_info *wlc = session->wlc; |
629 | struct ampdu_info *ampdu = wlc->ampdu; | ||
630 | struct sk_buff *first, *last; | ||
631 | struct d11txh *txh; | ||
632 | struct ieee80211_tx_info *tx_info; | ||
633 | struct ieee80211_tx_rate *txrate; | ||
634 | u8 ndelim; | ||
635 | u8 *plcp; | ||
636 | uint len; | ||
637 | uint fifo; | ||
638 | struct brcms_fifo_info *f; | ||
639 | u16 mcl; | ||
640 | bool fbr; | ||
641 | bool fbr_iscck; | ||
642 | struct ieee80211_rts *rts; | ||
643 | bool use_rts = false, use_cts = false; | ||
644 | u16 dma_len = session->dma_len; | ||
645 | u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
646 | u32 rspec = 0, rspec_fallback = 0; | ||
647 | u32 rts_rspec = 0, rts_rspec_fallback = 0; | ||
648 | u8 plcp0, plcp3, is40, sgi, mcs; | ||
649 | u16 mch; | ||
650 | u8 preamble_type = BRCMS_GF_PREAMBLE; | ||
651 | u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; | ||
652 | u8 rts_preamble_type = BRCMS_LONG_PREAMBLE; | ||
653 | u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE; | ||
666 | 654 | ||
667 | if (rr) { | 655 | if (skb_queue_empty(&session->skb_list)) |
668 | plcp0 = plcp[0]; | 656 | return; |
669 | plcp3 = plcp[3]; | ||
670 | } else { | ||
671 | plcp0 = txh->FragPLCPFallback[0]; | ||
672 | plcp3 = txh->FragPLCPFallback[3]; | ||
673 | 657 | ||
674 | } | 658 | first = skb_peek(&session->skb_list); |
675 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; | 659 | last = skb_peek_tail(&session->skb_list); |
676 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | 660 | |
677 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | 661 | /* Need to fix up last MPDU first to adjust AMPDU length */ |
678 | max_ampdu_bytes = | 662 | txh = (struct d11txh *)last->data; |
679 | min(scb_ampdu->max_rx_ampdu_bytes, | 663 | fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; |
680 | ampdu->max_txlen[mcs][is40][sgi]); | 664 | f = &du->fifo_tb[fifo]; |
681 | 665 | ||
682 | if (is40) | 666 | mcl = le16_to_cpu(txh->MacTxControlLow); |
683 | mimo_ctlchbw = | 667 | mcl &= ~TXC_AMPDU_MASK; |
684 | CHSPEC_SB_UPPER(wlc_phy_chanspec_get( | 668 | mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); |
685 | wlc->band->pi)) | 669 | txh->MacTxControlLow = cpu_to_le16(mcl); |
686 | ? PHY_TXC1_BW_20MHZ_UP : PHY_TXC1_BW_20MHZ; | 670 | |
687 | 671 | /* remove the null delimiter after last mpdu */ | |
688 | /* rebuild the rspec and rspec_fallback */ | 672 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; |
689 | rspec = RSPEC_MIMORATE; | 673 | txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; |
690 | rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; | 674 | session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; |
691 | if (plcp[0] & MIMO_PLCP_40MHZ) | 675 | |
692 | rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); | 676 | /* remove the pad len from last mpdu */ |
693 | 677 | fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); | |
694 | if (fbr_iscck) /* CCK */ | 678 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) : |
695 | rspec_fallback = cck_rspec(cck_phy2mac_rate | 679 | BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); |
696 | (txh->FragPLCPFallback[0])); | 680 | session->ampdu_len -= roundup(len, 4) - len; |
697 | else { /* MIMO */ | 681 | |
698 | rspec_fallback = RSPEC_MIMORATE; | 682 | /* Now fix up the first MPDU */ |
699 | rspec_fallback |= | 683 | tx_info = IEEE80211_SKB_CB(first); |
700 | txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; | 684 | txrate = tx_info->status.rates; |
701 | if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) | 685 | txh = (struct d11txh *)first->data; |
702 | rspec_fallback |= | 686 | plcp = (u8 *)(txh + 1); |
703 | (PHY_TXC1_BW_40MHZ << | 687 | rts = (struct ieee80211_rts *)&txh->rts_frame; |
704 | RSPEC_BW_SHIFT); | 688 | |
705 | } | 689 | mcl = le16_to_cpu(txh->MacTxControlLow); |
690 | /* If only one MPDU leave it marked as last */ | ||
691 | if (first != last) { | ||
692 | mcl &= ~TXC_AMPDU_MASK; | ||
693 | mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT); | ||
694 | } | ||
695 | mcl |= TXC_STARTMSDU; | ||
696 | if (ieee80211_is_rts(rts->frame_control)) { | ||
697 | mcl |= TXC_SENDRTS; | ||
698 | use_rts = true; | ||
699 | } | ||
700 | if (ieee80211_is_cts(rts->frame_control)) { | ||
701 | mcl |= TXC_SENDCTS; | ||
702 | use_cts = true; | ||
703 | } | ||
704 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
706 | 705 | ||
707 | if (use_rts || use_cts) { | 706 | fbr = txrate[1].count > 0; |
708 | rts_rspec = | 707 | if (!fbr) { |
709 | brcms_c_rspec_to_rts_rspec(wlc, | 708 | plcp0 = plcp[0]; |
710 | rspec, false, mimo_ctlchbw); | 709 | plcp3 = plcp[3]; |
711 | rts_rspec_fallback = | 710 | } else { |
712 | brcms_c_rspec_to_rts_rspec(wlc, | 711 | plcp0 = txh->FragPLCPFallback[0]; |
713 | rspec_fallback, false, mimo_ctlchbw); | 712 | plcp3 = txh->FragPLCPFallback[3]; |
714 | } | 713 | } |
715 | } | 714 | is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; |
715 | sgi = plcp3_issgi(plcp3) ? 1 : 0; | ||
716 | mcs = plcp0 & ~MIMO_PLCP_40MHZ; | ||
717 | |||
718 | if (is40) { | ||
719 | if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi))) | ||
720 | mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP; | ||
721 | else | ||
722 | mimo_ctlchbw = PHY_TXC1_BW_20MHZ; | ||
723 | } | ||
716 | 724 | ||
717 | /* if (first mpdu for host agg) */ | 725 | /* rebuild the rspec and rspec_fallback */ |
718 | /* test whether to add more */ | 726 | rspec = RSPEC_MIMORATE; |
719 | if ((mcs_2_rate(mcs, true, false) >= f->dmaxferrate) && | 727 | rspec |= plcp[0] & ~MIMO_PLCP_40MHZ; |
720 | (count == f->mcs2ampdu_table[mcs])) { | 728 | if (plcp[0] & MIMO_PLCP_40MHZ) |
721 | BCMMSG(wlc->wiphy, "wl%d: PR 37644: stopping" | 729 | rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT); |
722 | " ampdu at %d for mcs %d\n", | ||
723 | wlc->pub->unit, count, mcs); | ||
724 | break; | ||
725 | } | ||
726 | 730 | ||
727 | if (count == scb_ampdu->max_pdu) | 731 | fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03); |
728 | break; | 732 | if (fbr_iscck) { |
733 | rspec_fallback = | ||
734 | cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0])); | ||
735 | } else { | ||
736 | rspec_fallback = RSPEC_MIMORATE; | ||
737 | rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ; | ||
738 | if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ) | ||
739 | rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT; | ||
740 | } | ||
729 | 741 | ||
730 | /* | 742 | if (use_rts || use_cts) { |
731 | * check to see if the next pkt is | 743 | rts_rspec = |
732 | * a candidate for aggregation | 744 | brcms_c_rspec_to_rts_rspec(wlc, rspec, |
733 | */ | 745 | false, mimo_ctlchbw); |
734 | p = pktq_ppeek(&qi->q, prec); | 746 | rts_rspec_fallback = |
735 | if (p) { | 747 | brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback, |
736 | tx_info = IEEE80211_SKB_CB(p); | 748 | false, mimo_ctlchbw); |
737 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | 749 | } |
738 | ((u8) (p->priority) == tid)) { | ||
739 | plen = p->len + AMPDU_MAX_MPDU_OVERHEAD; | ||
740 | plen = max(scb_ampdu->min_len, plen); | ||
741 | 750 | ||
742 | if ((plen + ampdu_len) > max_ampdu_bytes) { | 751 | BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len); |
743 | p = NULL; | 752 | /* mark plcp to indicate ampdu */ |
744 | continue; | 753 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); |
745 | } | ||
746 | 754 | ||
747 | /* | 755 | /* reset the mixed mode header durations */ |
748 | * check if there are enough | 756 | if (txh->MModeLen) { |
749 | * descriptors available | 757 | u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec, |
750 | */ | 758 | session->ampdu_len); |
751 | if (*wlc->core->txavail[fifo] <= seg_cnt + 1) { | 759 | txh->MModeLen = cpu_to_le16(mmodelen); |
752 | wiphy_err(wiphy, "%s: No fifo space " | 760 | preamble_type = BRCMS_MM_PREAMBLE; |
753 | "!!\n", __func__); | 761 | } |
754 | p = NULL; | 762 | if (txh->MModeFbrLen) { |
755 | continue; | 763 | u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback, |
756 | } | 764 | session->ampdu_len); |
757 | /* next packet fit for aggregation so dequeue */ | 765 | txh->MModeFbrLen = cpu_to_le16(mmfbrlen); |
758 | p = brcmu_pktq_pdeq(&qi->q, prec); | 766 | fbr_preamble_type = BRCMS_MM_PREAMBLE; |
759 | } else { | 767 | } |
760 | p = NULL; | ||
761 | } | ||
762 | } | ||
763 | } /* end while(p) */ | ||
764 | 768 | ||
765 | ini->tx_in_transit += count; | 769 | /* set the preload length */ |
770 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
771 | dma_len = min(dma_len, f->ampdu_pld_size); | ||
772 | txh->PreloadSize = cpu_to_le16(dma_len); | ||
773 | } else { | ||
774 | txh->PreloadSize = 0; | ||
775 | } | ||
766 | 776 | ||
767 | if (count) { | 777 | mch = le16_to_cpu(txh->MacTxControlHigh); |
768 | /* patch up the last txh */ | ||
769 | txh = (struct d11txh *) pkt[count - 1]->data; | ||
770 | mcl = le16_to_cpu(txh->MacTxControlLow); | ||
771 | mcl &= ~TXC_AMPDU_MASK; | ||
772 | mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); | ||
773 | txh->MacTxControlLow = cpu_to_le16(mcl); | ||
774 | |||
775 | /* remove the null delimiter after last mpdu */ | ||
776 | ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; | ||
777 | txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0; | ||
778 | ampdu_len -= ndelim * AMPDU_DELIMITER_LEN; | ||
779 | |||
780 | /* remove the pad len from last mpdu */ | ||
781 | fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0); | ||
782 | len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) | ||
783 | : BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback); | ||
784 | ampdu_len -= roundup(len, 4) - len; | ||
785 | |||
786 | /* patch up the first txh & plcp */ | ||
787 | txh = (struct d11txh *) pkt[0]->data; | ||
788 | plcp = (u8 *) (txh + 1); | ||
789 | 778 | ||
790 | BRCMS_SET_MIMO_PLCP_LEN(plcp, ampdu_len); | 779 | /* update RTS dur fields */ |
791 | /* mark plcp to indicate ampdu */ | 780 | if (use_rts || use_cts) { |
792 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | 781 | u16 durid; |
782 | if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == | ||
783 | TXC_PREAMBLE_RTS_MAIN_SHORT) | ||
784 | rts_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
793 | 785 | ||
794 | /* reset the mixed mode header durations */ | 786 | if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == |
795 | if (txh->MModeLen) { | 787 | TXC_PREAMBLE_RTS_FB_SHORT) |
796 | u16 mmodelen = | 788 | rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; |
797 | brcms_c_calc_lsig_len(wlc, rspec, ampdu_len); | ||
798 | txh->MModeLen = cpu_to_le16(mmodelen); | ||
799 | preamble_type = BRCMS_MM_PREAMBLE; | ||
800 | } | ||
801 | if (txh->MModeFbrLen) { | ||
802 | u16 mmfbrlen = | ||
803 | brcms_c_calc_lsig_len(wlc, rspec_fallback, | ||
804 | ampdu_len); | ||
805 | txh->MModeFbrLen = cpu_to_le16(mmfbrlen); | ||
806 | fbr_preamble_type = BRCMS_MM_PREAMBLE; | ||
807 | } | ||
808 | 789 | ||
809 | /* set the preload length */ | 790 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, |
810 | if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) { | ||
811 | dma_len = min(dma_len, f->ampdu_pld_size); | ||
812 | txh->PreloadSize = cpu_to_le16(dma_len); | ||
813 | } else | ||
814 | txh->PreloadSize = 0; | ||
815 | |||
816 | mch = le16_to_cpu(txh->MacTxControlHigh); | ||
817 | |||
818 | /* update RTS dur fields */ | ||
819 | if (use_rts || use_cts) { | ||
820 | u16 durid; | ||
821 | rts = (struct ieee80211_rts *)&txh->rts_frame; | ||
822 | if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) == | ||
823 | TXC_PREAMBLE_RTS_MAIN_SHORT) | ||
824 | rts_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
825 | |||
826 | if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) == | ||
827 | TXC_PREAMBLE_RTS_FB_SHORT) | ||
828 | rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE; | ||
829 | |||
830 | durid = | ||
831 | brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec, | ||
832 | rspec, rts_preamble_type, | 791 | rspec, rts_preamble_type, |
833 | preamble_type, ampdu_len, | 792 | preamble_type, |
834 | true); | 793 | session->ampdu_len, true); |
835 | rts->duration = cpu_to_le16(durid); | 794 | rts->duration = cpu_to_le16(durid); |
836 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, | 795 | durid = brcms_c_compute_rtscts_dur(wlc, use_cts, |
837 | rts_rspec_fallback, | 796 | rts_rspec_fallback, |
838 | rspec_fallback, | 797 | rspec_fallback, |
839 | rts_fbr_preamble_type, | 798 | rts_fbr_preamble_type, |
840 | fbr_preamble_type, | 799 | fbr_preamble_type, |
841 | ampdu_len, true); | 800 | session->ampdu_len, true); |
842 | txh->RTSDurFallback = cpu_to_le16(durid); | 801 | txh->RTSDurFallback = cpu_to_le16(durid); |
843 | /* set TxFesTimeNormal */ | 802 | /* set TxFesTimeNormal */ |
844 | txh->TxFesTimeNormal = rts->duration; | 803 | txh->TxFesTimeNormal = rts->duration; |
845 | /* set fallback rate version of TxFesTimeNormal */ | 804 | /* set fallback rate version of TxFesTimeNormal */ |
846 | txh->TxFesTimeFallback = txh->RTSDurFallback; | 805 | txh->TxFesTimeFallback = txh->RTSDurFallback; |
847 | } | 806 | } |
848 | |||
849 | /* set flag and plcp for fallback rate */ | ||
850 | if (fbr) { | ||
851 | mch |= TXC_AMPDU_FBR; | ||
852 | txh->MacTxControlHigh = cpu_to_le16(mch); | ||
853 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | ||
854 | BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); | ||
855 | } | ||
856 | |||
857 | BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n", | ||
858 | wlc->pub->unit, count, ampdu_len); | ||
859 | |||
860 | /* inform rate_sel if it this is a rate probe pkt */ | ||
861 | frameid = le16_to_cpu(txh->TxFrameID); | ||
862 | if (frameid & TXFID_RATE_PROBE_MASK) | ||
863 | wiphy_err(wiphy, "%s: XXX what to do with " | ||
864 | "TXFID_RATE_PROBE_MASK!?\n", __func__); | ||
865 | |||
866 | for (i = 0; i < count; i++) | ||
867 | brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), | ||
868 | ampdu->txpkt_weight); | ||
869 | 807 | ||
808 | /* set flag and plcp for fallback rate */ | ||
809 | if (fbr) { | ||
810 | mch |= TXC_AMPDU_FBR; | ||
811 | txh->MacTxControlHigh = cpu_to_le16(mch); | ||
812 | BRCMS_SET_MIMO_PLCP_AMPDU(plcp); | ||
813 | BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); | ||
870 | } | 814 | } |
871 | /* endif (count) */ | 815 | |
872 | return err; | 816 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: count %d ampdu_len %d\n", |
817 | wlc->pub->unit, skb_queue_len(&session->skb_list), | ||
818 | session->ampdu_len); | ||
873 | } | 819 | } |
874 | 820 | ||
875 | static void | 821 | static void |
@@ -909,7 +855,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
909 | u8 antselid = 0; | 855 | u8 antselid = 0; |
910 | u8 retry_limit, rr_retry_limit; | 856 | u8 retry_limit, rr_retry_limit; |
911 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); | 857 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); |
912 | struct wiphy *wiphy = wlc->wiphy; | ||
913 | 858 | ||
914 | #ifdef DEBUG | 859 | #ifdef DEBUG |
915 | u8 hole[AMPDU_MAX_MPDU]; | 860 | u8 hole[AMPDU_MAX_MPDU]; |
@@ -955,13 +900,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
955 | if (supr_status) { | 900 | if (supr_status) { |
956 | update_rate = false; | 901 | update_rate = false; |
957 | if (supr_status == TX_STATUS_SUPR_BADCH) { | 902 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
958 | wiphy_err(wiphy, | 903 | brcms_err(wlc->hw->d11core, |
959 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", | 904 | "%s: Pkt tx suppressed, illegal channel possibly %d\n", |
960 | __func__, CHSPEC_CHANNEL( | 905 | __func__, CHSPEC_CHANNEL( |
961 | wlc->default_bss->chanspec)); | 906 | wlc->default_bss->chanspec)); |
962 | } else { | 907 | } else { |
963 | if (supr_status != TX_STATUS_SUPR_FRAG) | 908 | if (supr_status != TX_STATUS_SUPR_FRAG) |
964 | wiphy_err(wiphy, "%s: supr_status 0x%x\n", | 909 | brcms_err(wlc->hw->d11core, |
910 | "%s: supr_status 0x%x\n", | ||
965 | __func__, supr_status); | 911 | __func__, supr_status); |
966 | } | 912 | } |
967 | /* no need to retry for badch; will fail again */ | 913 | /* no need to retry for badch; will fail again */ |
@@ -977,20 +923,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
977 | * if there were underflows, but pre-loading | 923 | * if there were underflows, but pre-loading |
978 | * is not active, notify rate adaptation. | 924 | * is not active, notify rate adaptation. |
979 | */ | 925 | */ |
980 | if (brcms_c_ffpld_check_txfunfl(wlc, | 926 | if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0) |
981 | prio2fifo[tid]) > 0) | ||
982 | tx_error = true; | 927 | tx_error = true; |
983 | } | 928 | } |
984 | } else if (txs->phyerr) { | 929 | } else if (txs->phyerr) { |
985 | update_rate = false; | 930 | update_rate = false; |
986 | wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n", | 931 | brcms_err(wlc->hw->d11core, |
932 | "%s: ampdu tx phy error (0x%x)\n", | ||
987 | __func__, txs->phyerr); | 933 | __func__, txs->phyerr); |
988 | |||
989 | if (brcm_msg_level & LOG_ERROR_VAL) { | ||
990 | brcmu_prpkt("txpkt (AMPDU)", p); | ||
991 | brcms_c_print_txdesc((struct d11txh *) p->data); | ||
992 | } | ||
993 | brcms_c_print_txstatus(txs); | ||
994 | } | 934 | } |
995 | } | 935 | } |
996 | 936 | ||
@@ -1003,6 +943,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1003 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); | 943 | h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN); |
1004 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; | 944 | seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT; |
1005 | 945 | ||
946 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); | ||
947 | |||
1006 | if (tot_mpdu == 0) { | 948 | if (tot_mpdu == 0) { |
1007 | mcs = plcp[0] & MIMO_PLCP_MCS_MASK; | 949 | mcs = plcp[0] & MIMO_PLCP_MCS_MASK; |
1008 | mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); | 950 | mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel); |
@@ -1012,10 +954,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1012 | ack_recd = false; | 954 | ack_recd = false; |
1013 | if (ba_recd) { | 955 | if (ba_recd) { |
1014 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); | 956 | bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); |
1015 | BCMMSG(wiphy, | 957 | brcms_dbg_ht(wlc->hw->d11core, |
1016 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", | 958 | "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", |
1017 | tid, seq, start_seq, bindex, | 959 | tid, seq, start_seq, bindex, |
1018 | isset(bitmap, bindex), index); | 960 | isset(bitmap, bindex), index); |
1019 | /* if acked then clear bit and free packet */ | 961 | /* if acked then clear bit and free packet */ |
1020 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) | 962 | if ((bindex < AMPDU_TX_BA_MAX_WSIZE) |
1021 | && isset(bitmap, bindex)) { | 963 | && isset(bitmap, bindex)) { |
@@ -1046,14 +988,16 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1046 | /* either retransmit or send bar if ack not recd */ | 988 | /* either retransmit or send bar if ack not recd */ |
1047 | if (!ack_recd) { | 989 | if (!ack_recd) { |
1048 | if (retry && (ini->txretry[index] < (int)retry_limit)) { | 990 | if (retry && (ini->txretry[index] < (int)retry_limit)) { |
991 | int ret; | ||
1049 | ini->txretry[index]++; | 992 | ini->txretry[index]++; |
1050 | ini->tx_in_transit--; | 993 | ini->tx_in_transit--; |
994 | ret = brcms_c_txfifo(wlc, queue, p); | ||
1051 | /* | 995 | /* |
1052 | * Use high prededence for retransmit to | 996 | * We shouldn't be out of space in the DMA |
1053 | * give some punch | 997 | * ring here since we're reinserting a frame |
998 | * that was just pulled out. | ||
1054 | */ | 999 | */ |
1055 | brcms_c_txq_enq(wlc, scb, p, | 1000 | WARN_ONCE(ret, "queue %d out of txds\n", queue); |
1056 | BRCMS_PRIO_TO_HI_PREC(tid)); | ||
1057 | } else { | 1001 | } else { |
1058 | /* Retry timeout */ | 1002 | /* Retry timeout */ |
1059 | ini->tx_in_transit--; | 1003 | ini->tx_in_transit--; |
@@ -1064,9 +1008,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1064 | IEEE80211_TX_STAT_AMPDU_NO_BACK; | 1008 | IEEE80211_TX_STAT_AMPDU_NO_BACK; |
1065 | skb_pull(p, D11_PHY_HDR_LEN); | 1009 | skb_pull(p, D11_PHY_HDR_LEN); |
1066 | skb_pull(p, D11_TXH_LEN); | 1010 | skb_pull(p, D11_TXH_LEN); |
1067 | BCMMSG(wiphy, | 1011 | brcms_dbg_ht(wlc->hw->d11core, |
1068 | "BA Timeout, seq %d, in_transit %d\n", | 1012 | "BA Timeout, seq %d, in_transit %d\n", |
1069 | seq, ini->tx_in_transit); | 1013 | seq, ini->tx_in_transit); |
1070 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, | 1014 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, |
1071 | p); | 1015 | p); |
1072 | } | 1016 | } |
@@ -1080,12 +1024,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, | |||
1080 | 1024 | ||
1081 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); | 1025 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); |
1082 | } | 1026 | } |
1083 | brcms_c_send_q(wlc); | ||
1084 | 1027 | ||
1085 | /* update rate state */ | 1028 | /* update rate state */ |
1086 | antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); | 1029 | antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); |
1087 | |||
1088 | brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); | ||
1089 | } | 1030 | } |
1090 | 1031 | ||
1091 | void | 1032 | void |
@@ -1133,6 +1074,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | |||
1133 | while (p) { | 1074 | while (p) { |
1134 | tx_info = IEEE80211_SKB_CB(p); | 1075 | tx_info = IEEE80211_SKB_CB(p); |
1135 | txh = (struct d11txh *) p->data; | 1076 | txh = (struct d11txh *) p->data; |
1077 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, | ||
1078 | sizeof(*txh)); | ||
1136 | mcl = le16_to_cpu(txh->MacTxControlLow); | 1079 | mcl = le16_to_cpu(txh->MacTxControlLow); |
1137 | brcmu_pkt_buf_free_skb(p); | 1080 | brcmu_pkt_buf_free_skb(p); |
1138 | /* break out if last packet of ampdu */ | 1081 | /* break out if last packet of ampdu */ |
@@ -1142,7 +1085,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | |||
1142 | p = dma_getnexttxp(wlc->hw->di[queue], | 1085 | p = dma_getnexttxp(wlc->hw->di[queue], |
1143 | DMA_RANGE_TRANSMITTED); | 1086 | DMA_RANGE_TRANSMITTED); |
1144 | } | 1087 | } |
1145 | brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight); | ||
1146 | } | 1088 | } |
1147 | } | 1089 | } |
1148 | 1090 | ||
@@ -1182,23 +1124,6 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) | |||
1182 | } | 1124 | } |
1183 | 1125 | ||
1184 | /* | 1126 | /* |
1185 | * callback function that helps flushing ampdu packets from a priority queue | ||
1186 | */ | ||
1187 | static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a) | ||
1188 | { | ||
1189 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu); | ||
1190 | struct cb_del_ampdu_pars *ampdu_pars = | ||
1191 | (struct cb_del_ampdu_pars *)arg_a; | ||
1192 | bool rc; | ||
1193 | |||
1194 | rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false; | ||
1195 | rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL || | ||
1196 | tx_info->rate_driver_data[0] == ampdu_pars->sta); | ||
1197 | rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid); | ||
1198 | return rc; | ||
1199 | } | ||
1200 | |||
1201 | /* | ||
1202 | * callback function that helps invalidating ampdu packets in a DMA queue | 1127 | * callback function that helps invalidating ampdu packets in a DMA queue |
1203 | */ | 1128 | */ |
1204 | static void dma_cb_fn_ampdu(void *txi, void *arg_a) | 1129 | static void dma_cb_fn_ampdu(void *txi, void *arg_a) |
@@ -1218,15 +1143,5 @@ static void dma_cb_fn_ampdu(void *txi, void *arg_a) | |||
1218 | void brcms_c_ampdu_flush(struct brcms_c_info *wlc, | 1143 | void brcms_c_ampdu_flush(struct brcms_c_info *wlc, |
1219 | struct ieee80211_sta *sta, u16 tid) | 1144 | struct ieee80211_sta *sta, u16 tid) |
1220 | { | 1145 | { |
1221 | struct brcms_txq_info *qi = wlc->pkt_queue; | ||
1222 | struct pktq *pq = &qi->q; | ||
1223 | int prec; | ||
1224 | struct cb_del_ampdu_pars ampdu_pars; | ||
1225 | |||
1226 | ampdu_pars.sta = sta; | ||
1227 | ampdu_pars.tid = tid; | ||
1228 | for (prec = 0; prec < pq->num_prec; prec++) | ||
1229 | brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, | ||
1230 | (void *)&du_pars); | ||
1231 | brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); | 1146 | brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); |
1232 | } | 1147 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h index 421f4ba7c63c..73d01e586109 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.h | |||
@@ -17,11 +17,34 @@ | |||
17 | #ifndef _BRCM_AMPDU_H_ | 17 | #ifndef _BRCM_AMPDU_H_ |
18 | #define _BRCM_AMPDU_H_ | 18 | #define _BRCM_AMPDU_H_ |
19 | 19 | ||
20 | /* | ||
21 | * Data structure representing an in-progress session for accumulating | ||
22 | * frames for AMPDU. | ||
23 | * | ||
24 | * wlc: pointer to common driver data | ||
25 | * skb_list: queue of skb's for AMPDU | ||
26 | * max_ampdu_len: maximum length for this AMPDU | ||
27 | * max_ampdu_frames: maximum number of frames for this AMPDU | ||
28 | * ampdu_len: total number of bytes accumulated for this AMPDU | ||
29 | * dma_len: DMA length of this AMPDU | ||
30 | */ | ||
31 | struct brcms_ampdu_session { | ||
32 | struct brcms_c_info *wlc; | ||
33 | struct sk_buff_head skb_list; | ||
34 | unsigned max_ampdu_len; | ||
35 | u16 max_ampdu_frames; | ||
36 | u16 ampdu_len; | ||
37 | u16 dma_len; | ||
38 | }; | ||
39 | |||
40 | extern void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, | ||
41 | struct brcms_c_info *wlc); | ||
42 | extern int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, | ||
43 | struct sk_buff *p); | ||
44 | extern void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session); | ||
45 | |||
20 | extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); | 46 | extern struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc); |
21 | extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); | 47 | extern void brcms_c_ampdu_detach(struct ampdu_info *ampdu); |
22 | extern int brcms_c_sendampdu(struct ampdu_info *ampdu, | ||
23 | struct brcms_txq_info *qi, | ||
24 | struct sk_buff **aggp, int prec); | ||
25 | extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, | 48 | extern void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, |
26 | struct sk_buff *p, struct tx_status *txs); | 49 | struct sk_buff *p, struct tx_status *txs); |
27 | extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); | 50 | extern void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c index 55e12c327911..54c616919590 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/antsel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/antsel.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "main.h" | 21 | #include "main.h" |
22 | #include "phy_shim.h" | 22 | #include "phy_shim.h" |
23 | #include "antsel.h" | 23 | #include "antsel.h" |
24 | #include "debug.h" | ||
24 | 25 | ||
25 | #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ | 26 | #define ANT_SELCFG_AUTO 0x80 /* bit indicates antenna sel AUTO */ |
26 | #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ | 27 | #define ANT_SELCFG_MASK 0x33 /* antenna configuration mask */ |
@@ -137,7 +138,8 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) | |||
137 | asi->antsel_avail = false; | 138 | asi->antsel_avail = false; |
138 | } else { | 139 | } else { |
139 | asi->antsel_avail = false; | 140 | asi->antsel_avail = false; |
140 | wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " | 141 | brcms_err(wlc->hw->d11core, |
142 | "antsel_attach: 2o3 " | ||
141 | "board cfg invalid\n"); | 143 | "board cfg invalid\n"); |
142 | } | 144 | } |
143 | 145 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h index 27dd73eef56d..871781e6a713 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/brcms_trace_events.h | |||
@@ -14,22 +14,29 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #undef TRACE_SYSTEM | ||
18 | #define TRACE_SYSTEM brcmsmac | ||
19 | |||
20 | #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) | 17 | #if !defined(__TRACE_BRCMSMAC_H) || defined(TRACE_HEADER_MULTI_READ) |
21 | 18 | ||
22 | #define __TRACE_BRCMSMAC_H | 19 | #define __TRACE_BRCMSMAC_H |
23 | 20 | ||
21 | #include <linux/types.h> | ||
22 | #include <linux/device.h> | ||
24 | #include <linux/tracepoint.h> | 23 | #include <linux/tracepoint.h> |
25 | #include "mac80211_if.h" | 24 | #include "mac80211_if.h" |
26 | 25 | ||
27 | #ifndef CONFIG_BRCMDBG | 26 | #ifndef CONFIG_BRCM_TRACING |
28 | #undef TRACE_EVENT | 27 | #undef TRACE_EVENT |
29 | #define TRACE_EVENT(name, proto, ...) \ | 28 | #define TRACE_EVENT(name, proto, ...) \ |
30 | static inline void trace_ ## name(proto) {} | 29 | static inline void trace_ ## name(proto) {} |
30 | #undef DECLARE_EVENT_CLASS | ||
31 | #define DECLARE_EVENT_CLASS(...) | ||
32 | #undef DEFINE_EVENT | ||
33 | #define DEFINE_EVENT(evt_class, name, proto, ...) \ | ||
34 | static inline void trace_ ## name(proto) {} | ||
31 | #endif | 35 | #endif |
32 | 36 | ||
37 | #undef TRACE_SYSTEM | ||
38 | #define TRACE_SYSTEM brcmsmac | ||
39 | |||
33 | /* | 40 | /* |
34 | * We define a tracepoint, its arguments, its printk format and its | 41 | * We define a tracepoint, its arguments, its printk format and its |
35 | * 'fast binary record' layout. | 42 | * 'fast binary record' layout. |
@@ -78,9 +85,165 @@ TRACE_EVENT(brcms_dpc, | |||
78 | ) | 85 | ) |
79 | ); | 86 | ); |
80 | 87 | ||
88 | TRACE_EVENT(brcms_macintstatus, | ||
89 | TP_PROTO(const struct device *dev, int in_isr, u32 macintstatus, | ||
90 | u32 mask), | ||
91 | TP_ARGS(dev, in_isr, macintstatus, mask), | ||
92 | TP_STRUCT__entry( | ||
93 | __string(dev, dev_name(dev)) | ||
94 | __field(int, in_isr) | ||
95 | __field(u32, macintstatus) | ||
96 | __field(u32, mask) | ||
97 | ), | ||
98 | TP_fast_assign( | ||
99 | __assign_str(dev, dev_name(dev)); | ||
100 | __entry->in_isr = in_isr; | ||
101 | __entry->macintstatus = macintstatus; | ||
102 | __entry->mask = mask; | ||
103 | ), | ||
104 | TP_printk("[%s] in_isr=%d macintstatus=%#x mask=%#x", __get_str(dev), | ||
105 | __entry->in_isr, __entry->macintstatus, __entry->mask) | ||
106 | ); | ||
107 | |||
108 | #undef TRACE_SYSTEM | ||
109 | #define TRACE_SYSTEM brcmsmac_tx | ||
110 | |||
111 | TRACE_EVENT(brcms_txdesc, | ||
112 | TP_PROTO(const struct device *dev, | ||
113 | void *txh, size_t txh_len), | ||
114 | TP_ARGS(dev, txh, txh_len), | ||
115 | TP_STRUCT__entry( | ||
116 | __string(dev, dev_name(dev)) | ||
117 | __dynamic_array(u8, txh, txh_len) | ||
118 | ), | ||
119 | TP_fast_assign( | ||
120 | __assign_str(dev, dev_name(dev)); | ||
121 | memcpy(__get_dynamic_array(txh), txh, txh_len); | ||
122 | ), | ||
123 | TP_printk("[%s] txdesc", __get_str(dev)) | ||
124 | ); | ||
125 | |||
126 | TRACE_EVENT(brcms_txstatus, | ||
127 | TP_PROTO(const struct device *dev, u16 framelen, u16 frameid, | ||
128 | u16 status, u16 lasttxtime, u16 sequence, u16 phyerr, | ||
129 | u16 ackphyrxsh), | ||
130 | TP_ARGS(dev, framelen, frameid, status, lasttxtime, sequence, phyerr, | ||
131 | ackphyrxsh), | ||
132 | TP_STRUCT__entry( | ||
133 | __string(dev, dev_name(dev)) | ||
134 | __field(u16, framelen) | ||
135 | __field(u16, frameid) | ||
136 | __field(u16, status) | ||
137 | __field(u16, lasttxtime) | ||
138 | __field(u16, sequence) | ||
139 | __field(u16, phyerr) | ||
140 | __field(u16, ackphyrxsh) | ||
141 | ), | ||
142 | TP_fast_assign( | ||
143 | __assign_str(dev, dev_name(dev)); | ||
144 | __entry->framelen = framelen; | ||
145 | __entry->frameid = frameid; | ||
146 | __entry->status = status; | ||
147 | __entry->lasttxtime = lasttxtime; | ||
148 | __entry->sequence = sequence; | ||
149 | __entry->phyerr = phyerr; | ||
150 | __entry->ackphyrxsh = ackphyrxsh; | ||
151 | ), | ||
152 | TP_printk("[%s] FrameId %#04x TxStatus %#04x LastTxTime %#04x " | ||
153 | "Seq %#04x PHYTxStatus %#04x RxAck %#04x", | ||
154 | __get_str(dev), __entry->frameid, __entry->status, | ||
155 | __entry->lasttxtime, __entry->sequence, __entry->phyerr, | ||
156 | __entry->ackphyrxsh) | ||
157 | ); | ||
158 | |||
159 | TRACE_EVENT(brcms_ampdu_session, | ||
160 | TP_PROTO(const struct device *dev, unsigned max_ampdu_len, | ||
161 | u16 max_ampdu_frames, u16 ampdu_len, u16 ampdu_frames, | ||
162 | u16 dma_len), | ||
163 | TP_ARGS(dev, max_ampdu_len, max_ampdu_frames, ampdu_len, ampdu_frames, | ||
164 | dma_len), | ||
165 | TP_STRUCT__entry( | ||
166 | __string(dev, dev_name(dev)) | ||
167 | __field(unsigned, max_ampdu_len) | ||
168 | __field(u16, max_ampdu_frames) | ||
169 | __field(u16, ampdu_len) | ||
170 | __field(u16, ampdu_frames) | ||
171 | __field(u16, dma_len) | ||
172 | ), | ||
173 | TP_fast_assign( | ||
174 | __assign_str(dev, dev_name(dev)); | ||
175 | __entry->max_ampdu_len = max_ampdu_len; | ||
176 | __entry->max_ampdu_frames = max_ampdu_frames; | ||
177 | __entry->ampdu_len = ampdu_len; | ||
178 | __entry->ampdu_frames = ampdu_frames; | ||
179 | __entry->dma_len = dma_len; | ||
180 | ), | ||
181 | TP_printk("[%s] ampdu session max_len=%u max_frames=%u len=%u frames=%u dma_len=%u", | ||
182 | __get_str(dev), __entry->max_ampdu_len, | ||
183 | __entry->max_ampdu_frames, __entry->ampdu_len, | ||
184 | __entry->ampdu_frames, __entry->dma_len) | ||
185 | ); | ||
186 | |||
187 | #undef TRACE_SYSTEM | ||
188 | #define TRACE_SYSTEM brcmsmac_msg | ||
189 | |||
190 | #define MAX_MSG_LEN 100 | ||
191 | |||
192 | DECLARE_EVENT_CLASS(brcms_msg_event, | ||
193 | TP_PROTO(struct va_format *vaf), | ||
194 | TP_ARGS(vaf), | ||
195 | TP_STRUCT__entry( | ||
196 | __dynamic_array(char, msg, MAX_MSG_LEN) | ||
197 | ), | ||
198 | TP_fast_assign( | ||
199 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
200 | MAX_MSG_LEN, vaf->fmt, | ||
201 | *vaf->va) >= MAX_MSG_LEN); | ||
202 | ), | ||
203 | TP_printk("%s", __get_str(msg)) | ||
204 | ); | ||
205 | |||
206 | DEFINE_EVENT(brcms_msg_event, brcms_info, | ||
207 | TP_PROTO(struct va_format *vaf), | ||
208 | TP_ARGS(vaf) | ||
209 | ); | ||
210 | |||
211 | DEFINE_EVENT(brcms_msg_event, brcms_warn, | ||
212 | TP_PROTO(struct va_format *vaf), | ||
213 | TP_ARGS(vaf) | ||
214 | ); | ||
215 | |||
216 | DEFINE_EVENT(brcms_msg_event, brcms_err, | ||
217 | TP_PROTO(struct va_format *vaf), | ||
218 | TP_ARGS(vaf) | ||
219 | ); | ||
220 | |||
221 | DEFINE_EVENT(brcms_msg_event, brcms_crit, | ||
222 | TP_PROTO(struct va_format *vaf), | ||
223 | TP_ARGS(vaf) | ||
224 | ); | ||
225 | |||
226 | TRACE_EVENT(brcms_dbg, | ||
227 | TP_PROTO(u32 level, const char *func, struct va_format *vaf), | ||
228 | TP_ARGS(level, func, vaf), | ||
229 | TP_STRUCT__entry( | ||
230 | __field(u32, level) | ||
231 | __string(func, func) | ||
232 | __dynamic_array(char, msg, MAX_MSG_LEN) | ||
233 | ), | ||
234 | TP_fast_assign( | ||
235 | __entry->level = level; | ||
236 | __assign_str(func, func); | ||
237 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
238 | MAX_MSG_LEN, vaf->fmt, | ||
239 | *vaf->va) >= MAX_MSG_LEN); | ||
240 | ), | ||
241 | TP_printk("%s: %s", __get_str(func), __get_str(msg)) | ||
242 | ); | ||
243 | |||
81 | #endif /* __TRACE_BRCMSMAC_H */ | 244 | #endif /* __TRACE_BRCMSMAC_H */ |
82 | 245 | ||
83 | #ifdef CONFIG_BRCMDBG | 246 | #ifdef CONFIG_BRCM_TRACING |
84 | 247 | ||
85 | #undef TRACE_INCLUDE_PATH | 248 | #undef TRACE_INCLUDE_PATH |
86 | #define TRACE_INCLUDE_PATH . | 249 | #define TRACE_INCLUDE_PATH . |
@@ -89,4 +252,4 @@ TRACE_EVENT(brcms_dpc, | |||
89 | 252 | ||
90 | #include <trace/define_trace.h> | 253 | #include <trace/define_trace.h> |
91 | 254 | ||
92 | #endif /* CONFIG_BRCMDBG */ | 255 | #endif /* CONFIG_BRCM_TRACING */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 64a48f06d68b..a90b72202ec5 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "stf.h" | 26 | #include "stf.h" |
27 | #include "channel.h" | 27 | #include "channel.h" |
28 | #include "mac80211_if.h" | 28 | #include "mac80211_if.h" |
29 | #include "debug.h" | ||
29 | 30 | ||
30 | /* QDB() macro takes a dB value and converts to a quarter dB value */ | 31 | /* QDB() macro takes a dB value and converts to a quarter dB value */ |
31 | #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) | 32 | #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) |
@@ -336,8 +337,6 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) | |||
336 | const char *ccode = sprom->alpha2; | 337 | const char *ccode = sprom->alpha2; |
337 | int ccode_len = sizeof(sprom->alpha2); | 338 | int ccode_len = sizeof(sprom->alpha2); |
338 | 339 | ||
339 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
340 | |||
341 | wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); | 340 | wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); |
342 | if (wlc_cm == NULL) | 341 | if (wlc_cm == NULL) |
343 | return NULL; | 342 | return NULL; |
@@ -615,8 +614,8 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec) | |||
615 | 614 | ||
616 | /* check the chanspec */ | 615 | /* check the chanspec */ |
617 | if (brcms_c_chspec_malformed(chspec)) { | 616 | if (brcms_c_chspec_malformed(chspec)) { |
618 | wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", | 617 | brcms_err(wlc->hw->d11core, "wl%d: malformed chanspec 0x%x\n", |
619 | wlc->pub->unit, chspec); | 618 | wlc->pub->unit, chspec); |
620 | return false; | 619 | return false; |
621 | } | 620 | } |
622 | 621 | ||
@@ -738,7 +737,8 @@ static int brcms_reg_notifier(struct wiphy *wiphy, | |||
738 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); | 737 | mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); |
739 | } else { | 738 | } else { |
740 | mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); | 739 | mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); |
741 | wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\"\n", | 740 | brcms_err(wlc->hw->d11core, |
741 | "wl%d: %s: no valid channel for \"%s\"\n", | ||
742 | wlc->pub->unit, __func__, request->alpha2); | 742 | wlc->pub->unit, __func__, request->alpha2); |
743 | } | 743 | } |
744 | 744 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.c b/drivers/net/wireless/brcm80211/brcmsmac/debug.c new file mode 100644 index 000000000000..6ba4136c7cf6 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <linux/net.h> | ||
2 | #include "types.h" | ||
3 | #include "debug.h" | ||
4 | #include "brcms_trace_events.h" | ||
5 | |||
6 | #define __brcms_fn(fn) \ | ||
7 | void __brcms_ ##fn(struct device *dev, const char *fmt, ...) \ | ||
8 | { \ | ||
9 | struct va_format vaf = { \ | ||
10 | .fmt = fmt, \ | ||
11 | }; \ | ||
12 | va_list args; \ | ||
13 | \ | ||
14 | va_start(args, fmt); \ | ||
15 | vaf.va = &args; \ | ||
16 | dev_ ##fn(dev, "%pV", &vaf); \ | ||
17 | trace_brcms_ ##fn(&vaf); \ | ||
18 | va_end(args); \ | ||
19 | } | ||
20 | |||
21 | __brcms_fn(info) | ||
22 | __brcms_fn(warn) | ||
23 | __brcms_fn(err) | ||
24 | __brcms_fn(crit) | ||
25 | |||
26 | #if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) | ||
27 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
28 | const char *fmt, ...) | ||
29 | { | ||
30 | struct va_format vaf = { | ||
31 | .fmt = fmt, | ||
32 | }; | ||
33 | va_list args; | ||
34 | |||
35 | va_start(args, fmt); | ||
36 | vaf.va = &args; | ||
37 | #ifdef CONFIG_BRCMDBG | ||
38 | if ((brcm_msg_level & level) && net_ratelimit()) | ||
39 | dev_err(dev, "%s %pV", func, &vaf); | ||
40 | #endif | ||
41 | trace_brcms_dbg(level, func, &vaf); | ||
42 | va_end(args); | ||
43 | } | ||
44 | #endif | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/debug.h b/drivers/net/wireless/brcm80211/brcmsmac/debug.h new file mode 100644 index 000000000000..f77066bda9d2 --- /dev/null +++ b/drivers/net/wireless/brcm80211/brcmsmac/debug.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #ifndef _BRCMS_DEBUG_H_ | ||
2 | #define _BRCMS_DEBUG_H_ | ||
3 | |||
4 | #include <linux/device.h> | ||
5 | #include <linux/bcma/bcma.h> | ||
6 | #include <net/cfg80211.h> | ||
7 | #include <net/mac80211.h> | ||
8 | #include "main.h" | ||
9 | #include "mac80211_if.h" | ||
10 | |||
11 | __printf(2, 3) | ||
12 | void __brcms_info(struct device *dev, const char *fmt, ...); | ||
13 | __printf(2, 3) | ||
14 | void __brcms_warn(struct device *dev, const char *fmt, ...); | ||
15 | __printf(2, 3) | ||
16 | void __brcms_err(struct device *dev, const char *fmt, ...); | ||
17 | __printf(2, 3) | ||
18 | void __brcms_crit(struct device *dev, const char *fmt, ...); | ||
19 | |||
20 | #if defined(CONFIG_BRCMDBG) || defined(CONFIG_BRCM_TRACING) | ||
21 | __printf(4, 5) | ||
22 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
23 | const char *fmt, ...); | ||
24 | #else | ||
25 | static inline __printf(4, 5) | ||
26 | void __brcms_dbg(struct device *dev, u32 level, const char *func, | ||
27 | const char *fmt, ...) | ||
28 | { | ||
29 | } | ||
30 | #endif | ||
31 | |||
32 | /* | ||
33 | * Debug macros cannot be used when wlc is uninitialized. Generally | ||
34 | * this means any code that could run before brcms_c_attach() has | ||
35 | * returned successfully probably shouldn't use the following macros. | ||
36 | */ | ||
37 | |||
38 | #define brcms_dbg(core, l, f, a...) __brcms_dbg(&(core)->dev, l, __func__, f, ##a) | ||
39 | #define brcms_info(core, f, a...) __brcms_info(&(core)->dev, f, ##a) | ||
40 | #define brcms_warn(core, f, a...) __brcms_warn(&(core)->dev, f, ##a) | ||
41 | #define brcms_err(core, f, a...) __brcms_err(&(core)->dev, f, ##a) | ||
42 | #define brcms_crit(core, f, a...) __brcms_crit(&(core)->dev, f, ##a) | ||
43 | |||
44 | #define brcms_dbg_info(core, f, a...) brcms_dbg(core, BRCM_DL_INFO, f, ##a) | ||
45 | #define brcms_dbg_mac80211(core, f, a...) brcms_dbg(core, BRCM_DL_MAC80211, f, ##a) | ||
46 | #define brcms_dbg_rx(core, f, a...) brcms_dbg(core, BRCM_DL_RX, f, ##a) | ||
47 | #define brcms_dbg_tx(core, f, a...) brcms_dbg(core, BRCM_DL_TX, f, ##a) | ||
48 | #define brcms_dbg_int(core, f, a...) brcms_dbg(core, BRCM_DL_INT, f, ##a) | ||
49 | #define brcms_dbg_dma(core, f, a...) brcms_dbg(core, BRCM_DL_DMA, f, ##a) | ||
50 | #define brcms_dbg_ht(core, f, a...) brcms_dbg(core, BRCM_DL_HT, f, ##a) | ||
51 | |||
52 | #endif /* _BRCMS_DEBUG_H_ */ | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 5e53305bd9a9..511e45775c33 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c | |||
@@ -14,17 +14,22 @@ | |||
14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
18 | |||
19 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
20 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
21 | #include <linux/pci.h> | 19 | #include <linux/pci.h> |
20 | #include <net/cfg80211.h> | ||
21 | #include <net/mac80211.h> | ||
22 | 22 | ||
23 | #include <brcmu_utils.h> | 23 | #include <brcmu_utils.h> |
24 | #include <aiutils.h> | 24 | #include <aiutils.h> |
25 | #include "types.h" | 25 | #include "types.h" |
26 | #include "main.h" | ||
26 | #include "dma.h" | 27 | #include "dma.h" |
27 | #include "soc.h" | 28 | #include "soc.h" |
29 | #include "scb.h" | ||
30 | #include "ampdu.h" | ||
31 | #include "debug.h" | ||
32 | #include "brcms_trace_events.h" | ||
28 | 33 | ||
29 | /* | 34 | /* |
30 | * dma register field offset calculation | 35 | * dma register field offset calculation |
@@ -176,28 +181,6 @@ | |||
176 | 181 | ||
177 | #define BCMEXTRAHDROOM 172 | 182 | #define BCMEXTRAHDROOM 172 |
178 | 183 | ||
179 | /* debug/trace */ | ||
180 | #ifdef DEBUG | ||
181 | #define DMA_ERROR(fmt, ...) \ | ||
182 | do { \ | ||
183 | if (*di->msg_level & 1) \ | ||
184 | pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ | ||
185 | } while (0) | ||
186 | #define DMA_TRACE(fmt, ...) \ | ||
187 | do { \ | ||
188 | if (*di->msg_level & 2) \ | ||
189 | pr_debug("%s: " fmt, __func__, ##__VA_ARGS__); \ | ||
190 | } while (0) | ||
191 | #else | ||
192 | #define DMA_ERROR(fmt, ...) \ | ||
193 | no_printk(fmt, ##__VA_ARGS__) | ||
194 | #define DMA_TRACE(fmt, ...) \ | ||
195 | no_printk(fmt, ##__VA_ARGS__) | ||
196 | #endif /* DEBUG */ | ||
197 | |||
198 | #define DMA_NONE(fmt, ...) \ | ||
199 | no_printk(fmt, ##__VA_ARGS__) | ||
200 | |||
201 | #define MAXNAMEL 8 /* 8 char names */ | 184 | #define MAXNAMEL 8 /* 8 char names */ |
202 | 185 | ||
203 | /* macros to convert between byte offsets and indexes */ | 186 | /* macros to convert between byte offsets and indexes */ |
@@ -224,12 +207,14 @@ struct dma64desc { | |||
224 | /* dma engine software state */ | 207 | /* dma engine software state */ |
225 | struct dma_info { | 208 | struct dma_info { |
226 | struct dma_pub dma; /* exported structure */ | 209 | struct dma_pub dma; /* exported structure */ |
227 | uint *msg_level; /* message level pointer */ | ||
228 | char name[MAXNAMEL]; /* callers name for diag msgs */ | 210 | char name[MAXNAMEL]; /* callers name for diag msgs */ |
229 | 211 | ||
230 | struct bcma_device *core; | 212 | struct bcma_device *core; |
231 | struct device *dmadev; | 213 | struct device *dmadev; |
232 | 214 | ||
215 | /* session information for AMPDU */ | ||
216 | struct brcms_ampdu_session ampdu_session; | ||
217 | |||
233 | bool dma64; /* this dma engine is operating in 64-bit mode */ | 218 | bool dma64; /* this dma engine is operating in 64-bit mode */ |
234 | bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ | 219 | bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ |
235 | 220 | ||
@@ -298,12 +283,6 @@ struct dma_info { | |||
298 | bool aligndesc_4k; | 283 | bool aligndesc_4k; |
299 | }; | 284 | }; |
300 | 285 | ||
301 | /* | ||
302 | * default dma message level (if input msg_level | ||
303 | * pointer is null in dma_attach()) | ||
304 | */ | ||
305 | static uint dma_msg_level; | ||
306 | |||
307 | /* Check for odd number of 1's */ | 286 | /* Check for odd number of 1's */ |
308 | static u32 parity32(__le32 data) | 287 | static u32 parity32(__le32 data) |
309 | { | 288 | { |
@@ -353,7 +332,7 @@ static uint prevtxd(struct dma_info *di, uint i) | |||
353 | 332 | ||
354 | static uint nextrxd(struct dma_info *di, uint i) | 333 | static uint nextrxd(struct dma_info *di, uint i) |
355 | { | 334 | { |
356 | return txd(di, i + 1); | 335 | return rxd(di, i + 1); |
357 | } | 336 | } |
358 | 337 | ||
359 | static uint ntxdactive(struct dma_info *di, uint h, uint t) | 338 | static uint ntxdactive(struct dma_info *di, uint h, uint t) |
@@ -371,7 +350,7 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) | |||
371 | uint dmactrlflags; | 350 | uint dmactrlflags; |
372 | 351 | ||
373 | if (di == NULL) { | 352 | if (di == NULL) { |
374 | DMA_ERROR("NULL dma handle\n"); | 353 | brcms_dbg_dma(di->core, "NULL dma handle\n"); |
375 | return 0; | 354 | return 0; |
376 | } | 355 | } |
377 | 356 | ||
@@ -423,13 +402,15 @@ static bool _dma_isaddrext(struct dma_info *di) | |||
423 | /* not all tx or rx channel are available */ | 402 | /* not all tx or rx channel are available */ |
424 | if (di->d64txregbase != 0) { | 403 | if (di->d64txregbase != 0) { |
425 | if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) | 404 | if (!_dma64_addrext(di, DMA64TXREGOFFS(di, control))) |
426 | DMA_ERROR("%s: DMA64 tx doesn't have AE set\n", | 405 | brcms_dbg_dma(di->core, |
427 | di->name); | 406 | "%s: DMA64 tx doesn't have AE set\n", |
407 | di->name); | ||
428 | return true; | 408 | return true; |
429 | } else if (di->d64rxregbase != 0) { | 409 | } else if (di->d64rxregbase != 0) { |
430 | if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) | 410 | if (!_dma64_addrext(di, DMA64RXREGOFFS(di, control))) |
431 | DMA_ERROR("%s: DMA64 rx doesn't have AE set\n", | 411 | brcms_dbg_dma(di->core, |
432 | di->name); | 412 | "%s: DMA64 rx doesn't have AE set\n", |
413 | di->name); | ||
433 | return true; | 414 | return true; |
434 | } | 415 | } |
435 | 416 | ||
@@ -530,8 +511,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction) | |||
530 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, | 511 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, |
531 | &alloced, &di->txdpaorig); | 512 | &alloced, &di->txdpaorig); |
532 | if (va == NULL) { | 513 | if (va == NULL) { |
533 | DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", | 514 | brcms_dbg_dma(di->core, |
534 | di->name); | 515 | "%s: DMA_ALLOC_CONSISTENT(ntxd) failed\n", |
516 | di->name); | ||
535 | return false; | 517 | return false; |
536 | } | 518 | } |
537 | align = (1 << align_bits); | 519 | align = (1 << align_bits); |
@@ -544,8 +526,9 @@ static bool dma64_alloc(struct dma_info *di, uint direction) | |||
544 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, | 526 | va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, |
545 | &alloced, &di->rxdpaorig); | 527 | &alloced, &di->rxdpaorig); |
546 | if (va == NULL) { | 528 | if (va == NULL) { |
547 | DMA_ERROR("%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", | 529 | brcms_dbg_dma(di->core, |
548 | di->name); | 530 | "%s: DMA_ALLOC_CONSISTENT(nrxd) failed\n", |
531 | di->name); | ||
549 | return false; | 532 | return false; |
550 | } | 533 | } |
551 | align = (1 << align_bits); | 534 | align = (1 << align_bits); |
@@ -564,12 +547,13 @@ static bool _dma_alloc(struct dma_info *di, uint direction) | |||
564 | return dma64_alloc(di, direction); | 547 | return dma64_alloc(di, direction); |
565 | } | 548 | } |
566 | 549 | ||
567 | struct dma_pub *dma_attach(char *name, struct si_pub *sih, | 550 | struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, |
568 | struct bcma_device *core, | ||
569 | uint txregbase, uint rxregbase, uint ntxd, uint nrxd, | 551 | uint txregbase, uint rxregbase, uint ntxd, uint nrxd, |
570 | uint rxbufsize, int rxextheadroom, | 552 | uint rxbufsize, int rxextheadroom, |
571 | uint nrxpost, uint rxoffset, uint *msg_level) | 553 | uint nrxpost, uint rxoffset) |
572 | { | 554 | { |
555 | struct si_pub *sih = wlc->hw->sih; | ||
556 | struct bcma_device *core = wlc->hw->d11core; | ||
573 | struct dma_info *di; | 557 | struct dma_info *di; |
574 | u8 rev = core->id.rev; | 558 | u8 rev = core->id.rev; |
575 | uint size; | 559 | uint size; |
@@ -580,9 +564,6 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
580 | if (di == NULL) | 564 | if (di == NULL) |
581 | return NULL; | 565 | return NULL; |
582 | 566 | ||
583 | di->msg_level = msg_level ? msg_level : &dma_msg_level; | ||
584 | |||
585 | |||
586 | di->dma64 = | 567 | di->dma64 = |
587 | ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); | 568 | ((bcma_aread32(core, BCMA_IOST) & SISF_DMA64) == SISF_DMA64); |
588 | 569 | ||
@@ -598,11 +579,11 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
598 | */ | 579 | */ |
599 | _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); | 580 | _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); |
600 | 581 | ||
601 | DMA_TRACE("%s: %s flags 0x%x ntxd %d nrxd %d " | 582 | brcms_dbg_dma(di->core, "%s: %s flags 0x%x ntxd %d nrxd %d " |
602 | "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " | 583 | "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " |
603 | "txregbase %u rxregbase %u\n", name, "DMA64", | 584 | "txregbase %u rxregbase %u\n", name, "DMA64", |
604 | di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, | 585 | di->dma.dmactrlflags, ntxd, nrxd, rxbufsize, |
605 | rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); | 586 | rxextheadroom, nrxpost, rxoffset, txregbase, rxregbase); |
606 | 587 | ||
607 | /* make a private copy of our callers name */ | 588 | /* make a private copy of our callers name */ |
608 | strncpy(di->name, name, MAXNAMEL); | 589 | strncpy(di->name, name, MAXNAMEL); |
@@ -664,8 +645,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
664 | di->dmadesc_align = 4; /* 16 byte alignment */ | 645 | di->dmadesc_align = 4; /* 16 byte alignment */ |
665 | } | 646 | } |
666 | 647 | ||
667 | DMA_NONE("DMA descriptor align_needed %d, align %d\n", | 648 | brcms_dbg_dma(di->core, "DMA descriptor align_needed %d, align %d\n", |
668 | di->aligndesc_4k, di->dmadesc_align); | 649 | di->aligndesc_4k, di->dmadesc_align); |
669 | 650 | ||
670 | /* allocate tx packet pointer vector */ | 651 | /* allocate tx packet pointer vector */ |
671 | if (ntxd) { | 652 | if (ntxd) { |
@@ -703,21 +684,27 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, | |||
703 | 684 | ||
704 | if ((di->ddoffsetlow != 0) && !di->addrext) { | 685 | if ((di->ddoffsetlow != 0) && !di->addrext) { |
705 | if (di->txdpa > SI_PCI_DMA_SZ) { | 686 | if (di->txdpa > SI_PCI_DMA_SZ) { |
706 | DMA_ERROR("%s: txdpa 0x%x: addrext not supported\n", | 687 | brcms_dbg_dma(di->core, |
707 | di->name, (u32)di->txdpa); | 688 | "%s: txdpa 0x%x: addrext not supported\n", |
689 | di->name, (u32)di->txdpa); | ||
708 | goto fail; | 690 | goto fail; |
709 | } | 691 | } |
710 | if (di->rxdpa > SI_PCI_DMA_SZ) { | 692 | if (di->rxdpa > SI_PCI_DMA_SZ) { |
711 | DMA_ERROR("%s: rxdpa 0x%x: addrext not supported\n", | 693 | brcms_dbg_dma(di->core, |
712 | di->name, (u32)di->rxdpa); | 694 | "%s: rxdpa 0x%x: addrext not supported\n", |
695 | di->name, (u32)di->rxdpa); | ||
713 | goto fail; | 696 | goto fail; |
714 | } | 697 | } |
715 | } | 698 | } |
716 | 699 | ||
717 | DMA_TRACE("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", | 700 | /* Initialize AMPDU session */ |
718 | di->ddoffsetlow, di->ddoffsethigh, | 701 | brcms_c_ampdu_reset_session(&di->ampdu_session, wlc); |
719 | di->dataoffsetlow, di->dataoffsethigh, | 702 | |
720 | di->addrext); | 703 | brcms_dbg_dma(di->core, |
704 | "ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh 0x%x addrext %d\n", | ||
705 | di->ddoffsetlow, di->ddoffsethigh, | ||
706 | di->dataoffsetlow, di->dataoffsethigh, | ||
707 | di->addrext); | ||
721 | 708 | ||
722 | return (struct dma_pub *) di; | 709 | return (struct dma_pub *) di; |
723 | 710 | ||
@@ -763,7 +750,7 @@ void dma_detach(struct dma_pub *pub) | |||
763 | { | 750 | { |
764 | struct dma_info *di = (struct dma_info *)pub; | 751 | struct dma_info *di = (struct dma_info *)pub; |
765 | 752 | ||
766 | DMA_TRACE("%s:\n", di->name); | 753 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
767 | 754 | ||
768 | /* free dma descriptor rings */ | 755 | /* free dma descriptor rings */ |
769 | if (di->txd64) | 756 | if (di->txd64) |
@@ -839,7 +826,7 @@ static void _dma_rxenable(struct dma_info *di) | |||
839 | uint dmactrlflags = di->dma.dmactrlflags; | 826 | uint dmactrlflags = di->dma.dmactrlflags; |
840 | u32 control; | 827 | u32 control; |
841 | 828 | ||
842 | DMA_TRACE("%s:\n", di->name); | 829 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
843 | 830 | ||
844 | control = D64_RC_RE | (bcma_read32(di->core, | 831 | control = D64_RC_RE | (bcma_read32(di->core, |
845 | DMA64RXREGOFFS(di, control)) & | 832 | DMA64RXREGOFFS(di, control)) & |
@@ -859,7 +846,7 @@ void dma_rxinit(struct dma_pub *pub) | |||
859 | { | 846 | { |
860 | struct dma_info *di = (struct dma_info *)pub; | 847 | struct dma_info *di = (struct dma_info *)pub; |
861 | 848 | ||
862 | DMA_TRACE("%s:\n", di->name); | 849 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
863 | 850 | ||
864 | if (di->nrxd == 0) | 851 | if (di->nrxd == 0) |
865 | return; | 852 | return; |
@@ -954,7 +941,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
954 | return 0; | 941 | return 0; |
955 | 942 | ||
956 | len = le16_to_cpu(*(__le16 *) (p->data)); | 943 | len = le16_to_cpu(*(__le16 *) (p->data)); |
957 | DMA_TRACE("%s: dma_rx len %d\n", di->name, len); | 944 | brcms_dbg_dma(di->core, "%s: dma_rx len %d\n", di->name, len); |
958 | dma_spin_for_len(len, p); | 945 | dma_spin_for_len(len, p); |
959 | 946 | ||
960 | /* set actual length */ | 947 | /* set actual length */ |
@@ -981,14 +968,15 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
981 | DMA64RXREGOFFS(di, status0)) & | 968 | DMA64RXREGOFFS(di, status0)) & |
982 | D64_RS0_CD_MASK) - di->rcvptrbase) & | 969 | D64_RS0_CD_MASK) - di->rcvptrbase) & |
983 | D64_RS0_CD_MASK, struct dma64desc); | 970 | D64_RS0_CD_MASK, struct dma64desc); |
984 | DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", | 971 | brcms_dbg_dma(di->core, |
985 | di->rxin, di->rxout, cur); | 972 | "rxin %d rxout %d, hw_curr %d\n", |
973 | di->rxin, di->rxout, cur); | ||
986 | } | 974 | } |
987 | #endif /* DEBUG */ | 975 | #endif /* DEBUG */ |
988 | 976 | ||
989 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { | 977 | if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { |
990 | DMA_ERROR("%s: bad frame length (%d)\n", | 978 | brcms_dbg_dma(di->core, "%s: bad frame length (%d)\n", |
991 | di->name, len); | 979 | di->name, len); |
992 | skb_queue_walk_safe(&dma_frames, p, next) { | 980 | skb_queue_walk_safe(&dma_frames, p, next) { |
993 | skb_unlink(p, &dma_frames); | 981 | skb_unlink(p, &dma_frames); |
994 | brcmu_pkt_buf_free_skb(p); | 982 | brcmu_pkt_buf_free_skb(p); |
@@ -1005,7 +993,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) | |||
1005 | 993 | ||
1006 | static bool dma64_rxidle(struct dma_info *di) | 994 | static bool dma64_rxidle(struct dma_info *di) |
1007 | { | 995 | { |
1008 | DMA_TRACE("%s:\n", di->name); | 996 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1009 | 997 | ||
1010 | if (di->nrxd == 0) | 998 | if (di->nrxd == 0) |
1011 | return true; | 999 | return true; |
@@ -1016,6 +1004,17 @@ static bool dma64_rxidle(struct dma_info *di) | |||
1016 | D64_RS0_CD_MASK)); | 1004 | D64_RS0_CD_MASK)); |
1017 | } | 1005 | } |
1018 | 1006 | ||
1007 | static bool dma64_txidle(struct dma_info *di) | ||
1008 | { | ||
1009 | if (di->ntxd == 0) | ||
1010 | return true; | ||
1011 | |||
1012 | return ((bcma_read32(di->core, | ||
1013 | DMA64TXREGOFFS(di, status0)) & D64_XS0_CD_MASK) == | ||
1014 | (bcma_read32(di->core, DMA64TXREGOFFS(di, ptr)) & | ||
1015 | D64_XS0_CD_MASK)); | ||
1016 | } | ||
1017 | |||
1019 | /* | 1018 | /* |
1020 | * post receive buffers | 1019 | * post receive buffers |
1021 | * return false is refill failed completely and ring is empty this will stall | 1020 | * return false is refill failed completely and ring is empty this will stall |
@@ -1047,7 +1046,7 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1047 | 1046 | ||
1048 | n = di->nrxpost - nrxdactive(di, rxin, rxout); | 1047 | n = di->nrxpost - nrxdactive(di, rxin, rxout); |
1049 | 1048 | ||
1050 | DMA_TRACE("%s: post %d\n", di->name, n); | 1049 | brcms_dbg_dma(di->core, "%s: post %d\n", di->name, n); |
1051 | 1050 | ||
1052 | if (di->rxbufsize > BCMEXTRAHDROOM) | 1051 | if (di->rxbufsize > BCMEXTRAHDROOM) |
1053 | extra_offset = di->rxextrahdrroom; | 1052 | extra_offset = di->rxextrahdrroom; |
@@ -1060,9 +1059,11 @@ bool dma_rxfill(struct dma_pub *pub) | |||
1060 | p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); | 1059 | p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); |
1061 | 1060 | ||
1062 | if (p == NULL) { | 1061 | if (p == NULL) { |
1063 | DMA_ERROR("%s: out of rxbufs\n", di->name); | 1062 | brcms_dbg_dma(di->core, "%s: out of rxbufs\n", |
1063 | di->name); | ||
1064 | if (i == 0 && dma64_rxidle(di)) { | 1064 | if (i == 0 && dma64_rxidle(di)) { |
1065 | DMA_ERROR("%s: ring is empty !\n", di->name); | 1065 | brcms_dbg_dma(di->core, "%s: ring is empty !\n", |
1066 | di->name); | ||
1066 | ring_empty = true; | 1067 | ring_empty = true; |
1067 | } | 1068 | } |
1068 | di->dma.rxnobuf++; | 1069 | di->dma.rxnobuf++; |
@@ -1107,7 +1108,7 @@ void dma_rxreclaim(struct dma_pub *pub) | |||
1107 | struct dma_info *di = (struct dma_info *)pub; | 1108 | struct dma_info *di = (struct dma_info *)pub; |
1108 | struct sk_buff *p; | 1109 | struct sk_buff *p; |
1109 | 1110 | ||
1110 | DMA_TRACE("%s:\n", di->name); | 1111 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1111 | 1112 | ||
1112 | while ((p = _dma_getnextrxp(di, true))) | 1113 | while ((p = _dma_getnextrxp(di, true))) |
1113 | brcmu_pkt_buf_free_skb(p); | 1114 | brcmu_pkt_buf_free_skb(p); |
@@ -1138,7 +1139,7 @@ void dma_txinit(struct dma_pub *pub) | |||
1138 | struct dma_info *di = (struct dma_info *)pub; | 1139 | struct dma_info *di = (struct dma_info *)pub; |
1139 | u32 control = D64_XC_XE; | 1140 | u32 control = D64_XC_XE; |
1140 | 1141 | ||
1141 | DMA_TRACE("%s:\n", di->name); | 1142 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1142 | 1143 | ||
1143 | if (di->ntxd == 0) | 1144 | if (di->ntxd == 0) |
1144 | return; | 1145 | return; |
@@ -1170,7 +1171,7 @@ void dma_txsuspend(struct dma_pub *pub) | |||
1170 | { | 1171 | { |
1171 | struct dma_info *di = (struct dma_info *)pub; | 1172 | struct dma_info *di = (struct dma_info *)pub; |
1172 | 1173 | ||
1173 | DMA_TRACE("%s:\n", di->name); | 1174 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1174 | 1175 | ||
1175 | if (di->ntxd == 0) | 1176 | if (di->ntxd == 0) |
1176 | return; | 1177 | return; |
@@ -1182,7 +1183,7 @@ void dma_txresume(struct dma_pub *pub) | |||
1182 | { | 1183 | { |
1183 | struct dma_info *di = (struct dma_info *)pub; | 1184 | struct dma_info *di = (struct dma_info *)pub; |
1184 | 1185 | ||
1185 | DMA_TRACE("%s:\n", di->name); | 1186 | brcms_dbg_dma(di->core, "%s:\n", di->name); |
1186 | 1187 | ||
1187 | if (di->ntxd == 0) | 1188 | if (di->ntxd == 0) |
1188 | return; | 1189 | return; |
@@ -1205,11 +1206,11 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range) | |||
1205 | struct dma_info *di = (struct dma_info *)pub; | 1206 | struct dma_info *di = (struct dma_info *)pub; |
1206 | struct sk_buff *p; | 1207 | struct sk_buff *p; |
1207 | 1208 | ||
1208 | DMA_TRACE("%s: %s\n", | 1209 | brcms_dbg_dma(di->core, "%s: %s\n", |
1209 | di->name, | 1210 | di->name, |
1210 | range == DMA_RANGE_ALL ? "all" : | 1211 | range == DMA_RANGE_ALL ? "all" : |
1211 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : | 1212 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : |
1212 | "transferred"); | 1213 | "transferred"); |
1213 | 1214 | ||
1214 | if (di->txin == di->txout) | 1215 | if (di->txin == di->txout) |
1215 | return; | 1216 | return; |
@@ -1264,39 +1265,25 @@ bool dma_rxreset(struct dma_pub *pub) | |||
1264 | return status == D64_RS0_RS_DISABLED; | 1265 | return status == D64_RS0_RS_DISABLED; |
1265 | } | 1266 | } |
1266 | 1267 | ||
1267 | /* | 1268 | static void dma_txenq(struct dma_info *di, struct sk_buff *p) |
1268 | * !! tx entry routine | ||
1269 | * WARNING: call must check the return value for error. | ||
1270 | * the error(toss frames) could be fatal and cause many subsequent hard | ||
1271 | * to debug problems | ||
1272 | */ | ||
1273 | int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) | ||
1274 | { | 1269 | { |
1275 | struct dma_info *di = (struct dma_info *)pub; | ||
1276 | unsigned char *data; | 1270 | unsigned char *data; |
1277 | uint len; | 1271 | uint len; |
1278 | u16 txout; | 1272 | u16 txout; |
1279 | u32 flags = 0; | 1273 | u32 flags = 0; |
1280 | dma_addr_t pa; | 1274 | dma_addr_t pa; |
1281 | 1275 | ||
1282 | DMA_TRACE("%s:\n", di->name); | ||
1283 | |||
1284 | txout = di->txout; | 1276 | txout = di->txout; |
1285 | 1277 | ||
1278 | if (WARN_ON(nexttxd(di, txout) == di->txin)) | ||
1279 | return; | ||
1280 | |||
1286 | /* | 1281 | /* |
1287 | * obtain and initialize transmit descriptor entry. | 1282 | * obtain and initialize transmit descriptor entry. |
1288 | */ | 1283 | */ |
1289 | data = p->data; | 1284 | data = p->data; |
1290 | len = p->len; | 1285 | len = p->len; |
1291 | 1286 | ||
1292 | /* no use to transmit a zero length packet */ | ||
1293 | if (len == 0) | ||
1294 | return 0; | ||
1295 | |||
1296 | /* return nonzero if out of tx descriptors */ | ||
1297 | if (nexttxd(di, txout) == di->txin) | ||
1298 | goto outoftxd; | ||
1299 | |||
1300 | /* get physical address of buffer start */ | 1287 | /* get physical address of buffer start */ |
1301 | pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); | 1288 | pa = dma_map_single(di->dmadev, data, len, DMA_TO_DEVICE); |
1302 | 1289 | ||
@@ -1318,23 +1305,147 @@ int dma_txfast(struct dma_pub *pub, struct sk_buff *p, bool commit) | |||
1318 | 1305 | ||
1319 | /* bump the tx descriptor index */ | 1306 | /* bump the tx descriptor index */ |
1320 | di->txout = txout; | 1307 | di->txout = txout; |
1308 | } | ||
1321 | 1309 | ||
1322 | /* kick the chip */ | 1310 | static void ampdu_finalize(struct dma_info *di) |
1323 | if (commit) | 1311 | { |
1324 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | 1312 | struct brcms_ampdu_session *session = &di->ampdu_session; |
1325 | di->xmtptrbase + I2B(txout, struct dma64desc)); | 1313 | struct sk_buff *p; |
1314 | |||
1315 | trace_brcms_ampdu_session(&session->wlc->hw->d11core->dev, | ||
1316 | session->max_ampdu_len, | ||
1317 | session->max_ampdu_frames, | ||
1318 | session->ampdu_len, | ||
1319 | skb_queue_len(&session->skb_list), | ||
1320 | session->dma_len); | ||
1321 | |||
1322 | if (WARN_ON(skb_queue_empty(&session->skb_list))) | ||
1323 | return; | ||
1324 | |||
1325 | brcms_c_ampdu_finalize(session); | ||
1326 | |||
1327 | while (!skb_queue_empty(&session->skb_list)) { | ||
1328 | p = skb_dequeue(&session->skb_list); | ||
1329 | dma_txenq(di, p); | ||
1330 | } | ||
1331 | |||
1332 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | ||
1333 | di->xmtptrbase + I2B(di->txout, struct dma64desc)); | ||
1334 | brcms_c_ampdu_reset_session(session, session->wlc); | ||
1335 | } | ||
1336 | |||
1337 | static void prep_ampdu_frame(struct dma_info *di, struct sk_buff *p) | ||
1338 | { | ||
1339 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1340 | int ret; | ||
1341 | |||
1342 | ret = brcms_c_ampdu_add_frame(session, p); | ||
1343 | if (ret == -ENOSPC) { | ||
1344 | /* | ||
1345 | * AMPDU cannot accomodate this frame. Close out the in- | ||
1346 | * progress AMPDU session and start a new one. | ||
1347 | */ | ||
1348 | ampdu_finalize(di); | ||
1349 | ret = brcms_c_ampdu_add_frame(session, p); | ||
1350 | } | ||
1351 | |||
1352 | WARN_ON(ret); | ||
1353 | } | ||
1354 | |||
1355 | /* Update count of available tx descriptors based on current DMA state */ | ||
1356 | static void dma_update_txavail(struct dma_info *di) | ||
1357 | { | ||
1358 | /* | ||
1359 | * Available space is number of descriptors less the number of | ||
1360 | * active descriptors and the number of queued AMPDU frames. | ||
1361 | */ | ||
1362 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - | ||
1363 | skb_queue_len(&di->ampdu_session.skb_list) - 1; | ||
1364 | } | ||
1365 | |||
1366 | /* | ||
1367 | * !! tx entry routine | ||
1368 | * WARNING: call must check the return value for error. | ||
1369 | * the error(toss frames) could be fatal and cause many subsequent hard | ||
1370 | * to debug problems | ||
1371 | */ | ||
1372 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, | ||
1373 | struct sk_buff *p) | ||
1374 | { | ||
1375 | struct dma_info *di = (struct dma_info *)pub; | ||
1376 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1377 | struct ieee80211_tx_info *tx_info; | ||
1378 | bool is_ampdu; | ||
1379 | |||
1380 | /* no use to transmit a zero length packet */ | ||
1381 | if (p->len == 0) | ||
1382 | return 0; | ||
1383 | |||
1384 | /* return nonzero if out of tx descriptors */ | ||
1385 | if (di->dma.txavail == 0 || nexttxd(di, di->txout) == di->txin) | ||
1386 | goto outoftxd; | ||
1387 | |||
1388 | tx_info = IEEE80211_SKB_CB(p); | ||
1389 | is_ampdu = tx_info->flags & IEEE80211_TX_CTL_AMPDU; | ||
1390 | if (is_ampdu) | ||
1391 | prep_ampdu_frame(di, p); | ||
1392 | else | ||
1393 | dma_txenq(di, p); | ||
1326 | 1394 | ||
1327 | /* tx flow control */ | 1395 | /* tx flow control */ |
1328 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; | 1396 | dma_update_txavail(di); |
1397 | |||
1398 | /* kick the chip */ | ||
1399 | if (is_ampdu) { | ||
1400 | /* | ||
1401 | * Start sending data if we've got a full AMPDU, there's | ||
1402 | * no more space in the DMA ring, or the ring isn't | ||
1403 | * currently transmitting. | ||
1404 | */ | ||
1405 | if (skb_queue_len(&session->skb_list) == session->max_ampdu_frames || | ||
1406 | di->dma.txavail == 0 || dma64_txidle(di)) | ||
1407 | ampdu_finalize(di); | ||
1408 | } else { | ||
1409 | bcma_write32(di->core, DMA64TXREGOFFS(di, ptr), | ||
1410 | di->xmtptrbase + I2B(di->txout, struct dma64desc)); | ||
1411 | } | ||
1329 | 1412 | ||
1330 | return 0; | 1413 | return 0; |
1331 | 1414 | ||
1332 | outoftxd: | 1415 | outoftxd: |
1333 | DMA_ERROR("%s: out of txds !!!\n", di->name); | 1416 | brcms_dbg_dma(di->core, "%s: out of txds !!!\n", di->name); |
1334 | brcmu_pkt_buf_free_skb(p); | 1417 | brcmu_pkt_buf_free_skb(p); |
1335 | di->dma.txavail = 0; | 1418 | di->dma.txavail = 0; |
1336 | di->dma.txnobuf++; | 1419 | di->dma.txnobuf++; |
1337 | return -1; | 1420 | return -ENOSPC; |
1421 | } | ||
1422 | |||
1423 | void dma_txflush(struct dma_pub *pub) | ||
1424 | { | ||
1425 | struct dma_info *di = (struct dma_info *)pub; | ||
1426 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1427 | |||
1428 | if (!skb_queue_empty(&session->skb_list)) | ||
1429 | ampdu_finalize(di); | ||
1430 | } | ||
1431 | |||
1432 | int dma_txpending(struct dma_pub *pub) | ||
1433 | { | ||
1434 | struct dma_info *di = (struct dma_info *)pub; | ||
1435 | return ntxdactive(di, di->txin, di->txout); | ||
1436 | } | ||
1437 | |||
1438 | /* | ||
1439 | * If we have an active AMPDU session and are not transmitting, | ||
1440 | * this function will force tx to start. | ||
1441 | */ | ||
1442 | void dma_kick_tx(struct dma_pub *pub) | ||
1443 | { | ||
1444 | struct dma_info *di = (struct dma_info *)pub; | ||
1445 | struct brcms_ampdu_session *session = &di->ampdu_session; | ||
1446 | |||
1447 | if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) | ||
1448 | ampdu_finalize(di); | ||
1338 | } | 1449 | } |
1339 | 1450 | ||
1340 | /* | 1451 | /* |
@@ -1354,11 +1465,11 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | |||
1354 | u16 active_desc; | 1465 | u16 active_desc; |
1355 | struct sk_buff *txp; | 1466 | struct sk_buff *txp; |
1356 | 1467 | ||
1357 | DMA_TRACE("%s: %s\n", | 1468 | brcms_dbg_dma(di->core, "%s: %s\n", |
1358 | di->name, | 1469 | di->name, |
1359 | range == DMA_RANGE_ALL ? "all" : | 1470 | range == DMA_RANGE_ALL ? "all" : |
1360 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : | 1471 | range == DMA_RANGE_TRANSMITTED ? "transmitted" : |
1361 | "transferred"); | 1472 | "transferred"); |
1362 | 1473 | ||
1363 | if (di->ntxd == 0) | 1474 | if (di->ntxd == 0) |
1364 | return NULL; | 1475 | return NULL; |
@@ -1412,13 +1523,13 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) | |||
1412 | di->txin = i; | 1523 | di->txin = i; |
1413 | 1524 | ||
1414 | /* tx flow control */ | 1525 | /* tx flow control */ |
1415 | di->dma.txavail = di->ntxd - ntxdactive(di, di->txin, di->txout) - 1; | 1526 | dma_update_txavail(di); |
1416 | 1527 | ||
1417 | return txp; | 1528 | return txp; |
1418 | 1529 | ||
1419 | bogus: | 1530 | bogus: |
1420 | DMA_NONE("bogus curr: start %d end %d txout %d\n", | 1531 | brcms_dbg_dma(di->core, "bogus curr: start %d end %d txout %d\n", |
1421 | start, end, di->txout); | 1532 | start, end, di->txout); |
1422 | return NULL; | 1533 | return NULL; |
1423 | } | 1534 | } |
1424 | 1535 | ||
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.h b/drivers/net/wireless/brcm80211/brcmsmac/dma.h index cc269ee5c499..ff5b80b09046 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.h | |||
@@ -74,12 +74,11 @@ struct dma_pub { | |||
74 | uint txnobuf; /* tx out of dma descriptors */ | 74 | uint txnobuf; /* tx out of dma descriptors */ |
75 | }; | 75 | }; |
76 | 76 | ||
77 | extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, | 77 | extern struct dma_pub *dma_attach(char *name, struct brcms_c_info *wlc, |
78 | struct bcma_device *d11core, | ||
79 | uint txregbase, uint rxregbase, | 78 | uint txregbase, uint rxregbase, |
80 | uint ntxd, uint nrxd, | 79 | uint ntxd, uint nrxd, |
81 | uint rxbufsize, int rxextheadroom, | 80 | uint rxbufsize, int rxextheadroom, |
82 | uint nrxpost, uint rxoffset, uint *msg_level); | 81 | uint nrxpost, uint rxoffset); |
83 | 82 | ||
84 | void dma_rxinit(struct dma_pub *pub); | 83 | void dma_rxinit(struct dma_pub *pub); |
85 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); | 84 | int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list); |
@@ -87,7 +86,11 @@ bool dma_rxfill(struct dma_pub *pub); | |||
87 | bool dma_rxreset(struct dma_pub *pub); | 86 | bool dma_rxreset(struct dma_pub *pub); |
88 | bool dma_txreset(struct dma_pub *pub); | 87 | bool dma_txreset(struct dma_pub *pub); |
89 | void dma_txinit(struct dma_pub *pub); | 88 | void dma_txinit(struct dma_pub *pub); |
90 | int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); | 89 | int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, |
90 | struct sk_buff *p0); | ||
91 | void dma_txflush(struct dma_pub *pub); | ||
92 | int dma_txpending(struct dma_pub *pub); | ||
93 | void dma_kick_tx(struct dma_pub *pub); | ||
91 | void dma_txsuspend(struct dma_pub *pub); | 94 | void dma_txsuspend(struct dma_pub *pub); |
92 | bool dma_txsuspended(struct dma_pub *pub); | 95 | bool dma_txsuspended(struct dma_pub *pub); |
93 | void dma_txresume(struct dma_pub *pub); | 96 | void dma_txresume(struct dma_pub *pub); |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index a744ea5a9559..1710ccba8bac 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "ucode_loader.h" | 33 | #include "ucode_loader.h" |
34 | #include "mac80211_if.h" | 34 | #include "mac80211_if.h" |
35 | #include "main.h" | 35 | #include "main.h" |
36 | #include "debug.h" | ||
36 | 37 | ||
37 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ | 38 | #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */ |
38 | 39 | ||
@@ -98,10 +99,14 @@ static struct bcma_device_id brcms_coreid_table[] = { | |||
98 | }; | 99 | }; |
99 | MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); | 100 | MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); |
100 | 101 | ||
101 | #ifdef DEBUG | 102 | #if defined(CONFIG_BRCMDBG) |
102 | static int msglevel = 0xdeadbeef; | 103 | /* |
103 | module_param(msglevel, int, 0); | 104 | * Module parameter for setting the debug message level. Available |
104 | #endif /* DEBUG */ | 105 | * flags are specified by the BRCM_DL_* macros in |
106 | * drivers/net/wireless/brcm80211/include/defs.h. | ||
107 | */ | ||
108 | module_param_named(debug, brcm_msg_level, uint, S_IRUGO | S_IWUSR); | ||
109 | #endif | ||
105 | 110 | ||
106 | static struct ieee80211_channel brcms_2ghz_chantable[] = { | 111 | static struct ieee80211_channel brcms_2ghz_chantable[] = { |
107 | CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), | 112 | CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), |
@@ -276,7 +281,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, | |||
276 | 281 | ||
277 | spin_lock_bh(&wl->lock); | 282 | spin_lock_bh(&wl->lock); |
278 | if (!wl->pub->up) { | 283 | if (!wl->pub->up) { |
279 | wiphy_err(wl->wiphy, "ops->tx called while down\n"); | 284 | brcms_err(wl->wlc->hw->d11core, "ops->tx called while down\n"); |
280 | kfree_skb(skb); | 285 | kfree_skb(skb); |
281 | goto done; | 286 | goto done; |
282 | } | 287 | } |
@@ -313,8 +318,8 @@ static int brcms_ops_start(struct ieee80211_hw *hw) | |||
313 | spin_unlock_bh(&wl->lock); | 318 | spin_unlock_bh(&wl->lock); |
314 | 319 | ||
315 | if (err != 0) | 320 | if (err != 0) |
316 | wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, | 321 | brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", |
317 | err); | 322 | __func__, err); |
318 | return err; | 323 | return err; |
319 | } | 324 | } |
320 | 325 | ||
@@ -332,7 +337,7 @@ static void brcms_ops_stop(struct ieee80211_hw *hw) | |||
332 | status = brcms_c_chipmatch(wl->wlc->hw->d11core); | 337 | status = brcms_c_chipmatch(wl->wlc->hw->d11core); |
333 | spin_unlock_bh(&wl->lock); | 338 | spin_unlock_bh(&wl->lock); |
334 | if (!status) { | 339 | if (!status) { |
335 | wiphy_err(wl->wiphy, | 340 | brcms_err(wl->wlc->hw->d11core, |
336 | "wl: brcms_ops_stop: chipmatch failed\n"); | 341 | "wl: brcms_ops_stop: chipmatch failed\n"); |
337 | return; | 342 | return; |
338 | } | 343 | } |
@@ -350,8 +355,9 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
350 | 355 | ||
351 | /* Just STA for now */ | 356 | /* Just STA for now */ |
352 | if (vif->type != NL80211_IFTYPE_STATION) { | 357 | if (vif->type != NL80211_IFTYPE_STATION) { |
353 | wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only" | 358 | brcms_err(wl->wlc->hw->d11core, |
354 | " STA for now\n", __func__, vif->type); | 359 | "%s: Attempt to add type %d, only STA for now\n", |
360 | __func__, vif->type); | ||
355 | return -EOPNOTSUPP; | 361 | return -EOPNOTSUPP; |
356 | } | 362 | } |
357 | 363 | ||
@@ -370,9 +376,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
370 | { | 376 | { |
371 | struct ieee80211_conf *conf = &hw->conf; | 377 | struct ieee80211_conf *conf = &hw->conf; |
372 | struct brcms_info *wl = hw->priv; | 378 | struct brcms_info *wl = hw->priv; |
379 | struct bcma_device *core = wl->wlc->hw->d11core; | ||
373 | int err = 0; | 380 | int err = 0; |
374 | int new_int; | 381 | int new_int; |
375 | struct wiphy *wiphy = hw->wiphy; | ||
376 | 382 | ||
377 | spin_lock_bh(&wl->lock); | 383 | spin_lock_bh(&wl->lock); |
378 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { | 384 | if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { |
@@ -380,25 +386,26 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) | |||
380 | conf->listen_interval); | 386 | conf->listen_interval); |
381 | } | 387 | } |
382 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) | 388 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) |
383 | wiphy_dbg(wiphy, "%s: change monitor mode: %s\n", | 389 | brcms_dbg_info(core, "%s: change monitor mode: %s\n", |
384 | __func__, conf->flags & IEEE80211_CONF_MONITOR ? | 390 | __func__, conf->flags & IEEE80211_CONF_MONITOR ? |
385 | "true" : "false"); | 391 | "true" : "false"); |
386 | if (changed & IEEE80211_CONF_CHANGE_PS) | 392 | if (changed & IEEE80211_CONF_CHANGE_PS) |
387 | wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n", | 393 | brcms_err(core, "%s: change power-save mode: %s (implement)\n", |
388 | __func__, conf->flags & IEEE80211_CONF_PS ? | 394 | __func__, conf->flags & IEEE80211_CONF_PS ? |
389 | "true" : "false"); | 395 | "true" : "false"); |
390 | 396 | ||
391 | if (changed & IEEE80211_CONF_CHANGE_POWER) { | 397 | if (changed & IEEE80211_CONF_CHANGE_POWER) { |
392 | err = brcms_c_set_tx_power(wl->wlc, conf->power_level); | 398 | err = brcms_c_set_tx_power(wl->wlc, conf->power_level); |
393 | if (err < 0) { | 399 | if (err < 0) { |
394 | wiphy_err(wiphy, "%s: Error setting power_level\n", | 400 | brcms_err(core, "%s: Error setting power_level\n", |
395 | __func__); | 401 | __func__); |
396 | goto config_out; | 402 | goto config_out; |
397 | } | 403 | } |
398 | new_int = brcms_c_get_tx_power(wl->wlc); | 404 | new_int = brcms_c_get_tx_power(wl->wlc); |
399 | if (new_int != conf->power_level) | 405 | if (new_int != conf->power_level) |
400 | wiphy_err(wiphy, "%s: Power level req != actual, %d %d" | 406 | brcms_err(core, |
401 | "\n", __func__, conf->power_level, | 407 | "%s: Power level req != actual, %d %d\n", |
408 | __func__, conf->power_level, | ||
402 | new_int); | 409 | new_int); |
403 | } | 410 | } |
404 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 411 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
@@ -425,13 +432,13 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
425 | struct ieee80211_bss_conf *info, u32 changed) | 432 | struct ieee80211_bss_conf *info, u32 changed) |
426 | { | 433 | { |
427 | struct brcms_info *wl = hw->priv; | 434 | struct brcms_info *wl = hw->priv; |
428 | struct wiphy *wiphy = hw->wiphy; | 435 | struct bcma_device *core = wl->wlc->hw->d11core; |
429 | 436 | ||
430 | if (changed & BSS_CHANGED_ASSOC) { | 437 | if (changed & BSS_CHANGED_ASSOC) { |
431 | /* association status changed (associated/disassociated) | 438 | /* association status changed (associated/disassociated) |
432 | * also implies a change in the AID. | 439 | * also implies a change in the AID. |
433 | */ | 440 | */ |
434 | wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME, | 441 | brcms_err(core, "%s: %s: %sassociated\n", KBUILD_MODNAME, |
435 | __func__, info->assoc ? "" : "dis"); | 442 | __func__, info->assoc ? "" : "dis"); |
436 | spin_lock_bh(&wl->lock); | 443 | spin_lock_bh(&wl->lock); |
437 | brcms_c_associate_upd(wl->wlc, info->assoc); | 444 | brcms_c_associate_upd(wl->wlc, info->assoc); |
@@ -491,7 +498,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
491 | error = brcms_c_set_rateset(wl->wlc, &rs); | 498 | error = brcms_c_set_rateset(wl->wlc, &rs); |
492 | spin_unlock_bh(&wl->lock); | 499 | spin_unlock_bh(&wl->lock); |
493 | if (error) | 500 | if (error) |
494 | wiphy_err(wiphy, "changing basic rates failed: %d\n", | 501 | brcms_err(core, "changing basic rates failed: %d\n", |
495 | error); | 502 | error); |
496 | } | 503 | } |
497 | if (changed & BSS_CHANGED_BEACON_INT) { | 504 | if (changed & BSS_CHANGED_BEACON_INT) { |
@@ -508,30 +515,30 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
508 | } | 515 | } |
509 | if (changed & BSS_CHANGED_BEACON) | 516 | if (changed & BSS_CHANGED_BEACON) |
510 | /* Beacon data changed, retrieve new beacon (beaconing modes) */ | 517 | /* Beacon data changed, retrieve new beacon (beaconing modes) */ |
511 | wiphy_err(wiphy, "%s: beacon changed\n", __func__); | 518 | brcms_err(core, "%s: beacon changed\n", __func__); |
512 | 519 | ||
513 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 520 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
514 | /* Beaconing should be enabled/disabled (beaconing modes) */ | 521 | /* Beaconing should be enabled/disabled (beaconing modes) */ |
515 | wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, | 522 | brcms_err(core, "%s: Beacon enabled: %s\n", __func__, |
516 | info->enable_beacon ? "true" : "false"); | 523 | info->enable_beacon ? "true" : "false"); |
517 | } | 524 | } |
518 | 525 | ||
519 | if (changed & BSS_CHANGED_CQM) { | 526 | if (changed & BSS_CHANGED_CQM) { |
520 | /* Connection quality monitor config changed */ | 527 | /* Connection quality monitor config changed */ |
521 | wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " | 528 | brcms_err(core, "%s: cqm change: threshold %d, hys %d " |
522 | " (implement)\n", __func__, info->cqm_rssi_thold, | 529 | " (implement)\n", __func__, info->cqm_rssi_thold, |
523 | info->cqm_rssi_hyst); | 530 | info->cqm_rssi_hyst); |
524 | } | 531 | } |
525 | 532 | ||
526 | if (changed & BSS_CHANGED_IBSS) { | 533 | if (changed & BSS_CHANGED_IBSS) { |
527 | /* IBSS join status changed */ | 534 | /* IBSS join status changed */ |
528 | wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, | 535 | brcms_err(core, "%s: IBSS joined: %s (implement)\n", |
529 | info->ibss_joined ? "true" : "false"); | 536 | __func__, info->ibss_joined ? "true" : "false"); |
530 | } | 537 | } |
531 | 538 | ||
532 | if (changed & BSS_CHANGED_ARP_FILTER) { | 539 | if (changed & BSS_CHANGED_ARP_FILTER) { |
533 | /* Hardware ARP filter address list or state changed */ | 540 | /* Hardware ARP filter address list or state changed */ |
534 | wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" | 541 | brcms_err(core, "%s: arp filtering: enabled %s, count %d" |
535 | " (implement)\n", __func__, info->arp_filter_enabled ? | 542 | " (implement)\n", __func__, info->arp_filter_enabled ? |
536 | "true" : "false", info->arp_addr_cnt); | 543 | "true" : "false", info->arp_addr_cnt); |
537 | } | 544 | } |
@@ -541,8 +548,8 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, | |||
541 | * QoS for this association was enabled/disabled. | 548 | * QoS for this association was enabled/disabled. |
542 | * Note that it is only ever disabled for station mode. | 549 | * Note that it is only ever disabled for station mode. |
543 | */ | 550 | */ |
544 | wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__, | 551 | brcms_err(core, "%s: qos enabled: %s (implement)\n", |
545 | info->qos ? "true" : "false"); | 552 | __func__, info->qos ? "true" : "false"); |
546 | } | 553 | } |
547 | return; | 554 | return; |
548 | } | 555 | } |
@@ -553,25 +560,25 @@ brcms_ops_configure_filter(struct ieee80211_hw *hw, | |||
553 | unsigned int *total_flags, u64 multicast) | 560 | unsigned int *total_flags, u64 multicast) |
554 | { | 561 | { |
555 | struct brcms_info *wl = hw->priv; | 562 | struct brcms_info *wl = hw->priv; |
556 | struct wiphy *wiphy = hw->wiphy; | 563 | struct bcma_device *core = wl->wlc->hw->d11core; |
557 | 564 | ||
558 | changed_flags &= MAC_FILTERS; | 565 | changed_flags &= MAC_FILTERS; |
559 | *total_flags &= MAC_FILTERS; | 566 | *total_flags &= MAC_FILTERS; |
560 | 567 | ||
561 | if (changed_flags & FIF_PROMISC_IN_BSS) | 568 | if (changed_flags & FIF_PROMISC_IN_BSS) |
562 | wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n"); | 569 | brcms_dbg_info(core, "FIF_PROMISC_IN_BSS\n"); |
563 | if (changed_flags & FIF_ALLMULTI) | 570 | if (changed_flags & FIF_ALLMULTI) |
564 | wiphy_dbg(wiphy, "FIF_ALLMULTI\n"); | 571 | brcms_dbg_info(core, "FIF_ALLMULTI\n"); |
565 | if (changed_flags & FIF_FCSFAIL) | 572 | if (changed_flags & FIF_FCSFAIL) |
566 | wiphy_dbg(wiphy, "FIF_FCSFAIL\n"); | 573 | brcms_dbg_info(core, "FIF_FCSFAIL\n"); |
567 | if (changed_flags & FIF_CONTROL) | 574 | if (changed_flags & FIF_CONTROL) |
568 | wiphy_dbg(wiphy, "FIF_CONTROL\n"); | 575 | brcms_dbg_info(core, "FIF_CONTROL\n"); |
569 | if (changed_flags & FIF_OTHER_BSS) | 576 | if (changed_flags & FIF_OTHER_BSS) |
570 | wiphy_dbg(wiphy, "FIF_OTHER_BSS\n"); | 577 | brcms_dbg_info(core, "FIF_OTHER_BSS\n"); |
571 | if (changed_flags & FIF_PSPOLL) | 578 | if (changed_flags & FIF_PSPOLL) |
572 | wiphy_dbg(wiphy, "FIF_PSPOLL\n"); | 579 | brcms_dbg_info(core, "FIF_PSPOLL\n"); |
573 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) | 580 | if (changed_flags & FIF_BCN_PRBRESP_PROMISC) |
574 | wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n"); | 581 | brcms_dbg_info(core, "FIF_BCN_PRBRESP_PROMISC\n"); |
575 | 582 | ||
576 | spin_lock_bh(&wl->lock); | 583 | spin_lock_bh(&wl->lock); |
577 | brcms_c_mac_promisc(wl->wlc, *total_flags); | 584 | brcms_c_mac_promisc(wl->wlc, *total_flags); |
@@ -653,8 +660,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, | |||
653 | status = brcms_c_aggregatable(wl->wlc, tid); | 660 | status = brcms_c_aggregatable(wl->wlc, tid); |
654 | spin_unlock_bh(&wl->lock); | 661 | spin_unlock_bh(&wl->lock); |
655 | if (!status) { | 662 | if (!status) { |
656 | wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n", | 663 | brcms_err(wl->wlc->hw->d11core, |
657 | tid); | 664 | "START: tid %d is not agg\'able\n", tid); |
658 | return -EINVAL; | 665 | return -EINVAL; |
659 | } | 666 | } |
660 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | 667 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); |
@@ -681,8 +688,8 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, | |||
681 | /* Power save wakeup */ | 688 | /* Power save wakeup */ |
682 | break; | 689 | break; |
683 | default: | 690 | default: |
684 | wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n", | 691 | brcms_err(wl->wlc->hw->d11core, |
685 | __func__); | 692 | "%s: Invalid command, ignoring\n", __func__); |
686 | } | 693 | } |
687 | 694 | ||
688 | return 0; | 695 | return 0; |
@@ -1144,14 +1151,13 @@ static int brcms_suspend(struct bcma_device *pdev) | |||
1144 | wl->pub->hw_up = false; | 1151 | wl->pub->hw_up = false; |
1145 | spin_unlock_bh(&wl->lock); | 1152 | spin_unlock_bh(&wl->lock); |
1146 | 1153 | ||
1147 | pr_debug("brcms_suspend ok\n"); | 1154 | brcms_dbg_info(wl->wlc->hw->d11core, "brcms_suspend ok\n"); |
1148 | 1155 | ||
1149 | return 0; | 1156 | return 0; |
1150 | } | 1157 | } |
1151 | 1158 | ||
1152 | static int brcms_resume(struct bcma_device *pdev) | 1159 | static int brcms_resume(struct bcma_device *pdev) |
1153 | { | 1160 | { |
1154 | pr_debug("brcms_resume ok\n"); | ||
1155 | return 0; | 1161 | return 0; |
1156 | } | 1162 | } |
1157 | 1163 | ||
@@ -1184,10 +1190,6 @@ static DECLARE_WORK(brcms_driver_work, brcms_driver_init); | |||
1184 | 1190 | ||
1185 | static int __init brcms_module_init(void) | 1191 | static int __init brcms_module_init(void) |
1186 | { | 1192 | { |
1187 | #ifdef DEBUG | ||
1188 | if (msglevel != 0xdeadbeef) | ||
1189 | brcm_msg_level = msglevel; | ||
1190 | #endif | ||
1191 | if (!schedule_work(&brcms_driver_work)) | 1193 | if (!schedule_work(&brcms_driver_work)) |
1192 | return -EBUSY; | 1194 | return -EBUSY; |
1193 | 1195 | ||
@@ -1216,7 +1218,7 @@ module_exit(brcms_module_exit); | |||
1216 | void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, | 1218 | void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, |
1217 | bool state, int prio) | 1219 | bool state, int prio) |
1218 | { | 1220 | { |
1219 | wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__); | 1221 | brcms_err(wl->wlc->hw->d11core, "Shouldn't be here %s\n", __func__); |
1220 | } | 1222 | } |
1221 | 1223 | ||
1222 | /* | 1224 | /* |
@@ -1224,7 +1226,8 @@ void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif, | |||
1224 | */ | 1226 | */ |
1225 | void brcms_init(struct brcms_info *wl) | 1227 | void brcms_init(struct brcms_info *wl) |
1226 | { | 1228 | { |
1227 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1229 | brcms_dbg_info(wl->wlc->hw->d11core, "Initializing wl%d\n", |
1230 | wl->pub->unit); | ||
1228 | brcms_reset(wl); | 1231 | brcms_reset(wl); |
1229 | brcms_c_init(wl->wlc, wl->mute_tx); | 1232 | brcms_c_init(wl->wlc, wl->mute_tx); |
1230 | } | 1233 | } |
@@ -1234,7 +1237,7 @@ void brcms_init(struct brcms_info *wl) | |||
1234 | */ | 1237 | */ |
1235 | uint brcms_reset(struct brcms_info *wl) | 1238 | uint brcms_reset(struct brcms_info *wl) |
1236 | { | 1239 | { |
1237 | BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit); | 1240 | brcms_dbg_info(wl->wlc->hw->d11core, "Resetting wl%d\n", wl->pub->unit); |
1238 | brcms_c_reset(wl->wlc); | 1241 | brcms_c_reset(wl->wlc); |
1239 | 1242 | ||
1240 | /* dpc will not be rescheduled */ | 1243 | /* dpc will not be rescheduled */ |
@@ -1248,7 +1251,7 @@ uint brcms_reset(struct brcms_info *wl) | |||
1248 | 1251 | ||
1249 | void brcms_fatal_error(struct brcms_info *wl) | 1252 | void brcms_fatal_error(struct brcms_info *wl) |
1250 | { | 1253 | { |
1251 | wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n", | 1254 | brcms_err(wl->wlc->hw->d11core, "wl%d: fatal error, reinitializing\n", |
1252 | wl->wlc->pub->unit); | 1255 | wl->wlc->pub->unit); |
1253 | brcms_reset(wl); | 1256 | brcms_reset(wl); |
1254 | ieee80211_restart_hw(wl->pub->ieee_hw); | 1257 | ieee80211_restart_hw(wl->pub->ieee_hw); |
@@ -1396,8 +1399,9 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) | |||
1396 | 1399 | ||
1397 | #ifdef DEBUG | 1400 | #ifdef DEBUG |
1398 | if (t->set) | 1401 | if (t->set) |
1399 | wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", | 1402 | brcms_dbg_info(t->wl->wlc->hw->d11core, |
1400 | __func__, t->name, periodic); | 1403 | "%s: Already set. Name: %s, per %d\n", |
1404 | __func__, t->name, periodic); | ||
1401 | #endif | 1405 | #endif |
1402 | t->ms = ms; | 1406 | t->ms = ms; |
1403 | t->periodic = (bool) periodic; | 1407 | t->periodic = (bool) periodic; |
@@ -1486,8 +1490,8 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) | |||
1486 | } | 1490 | } |
1487 | } | 1491 | } |
1488 | } | 1492 | } |
1489 | wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n", | 1493 | brcms_err(wl->wlc->hw->d11core, |
1490 | idx); | 1494 | "ERROR: ucode buf tag:%d can not be found!\n", idx); |
1491 | *pbuf = NULL; | 1495 | *pbuf = NULL; |
1492 | fail: | 1496 | fail: |
1493 | return -ENODATA; | 1497 | return -ENODATA; |
@@ -1510,7 +1514,7 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) | |||
1510 | pdata = wl->fw.fw_bin[i]->data + | 1514 | pdata = wl->fw.fw_bin[i]->data + |
1511 | le32_to_cpu(hdr->offset); | 1515 | le32_to_cpu(hdr->offset); |
1512 | if (le32_to_cpu(hdr->len) != 4) { | 1516 | if (le32_to_cpu(hdr->len) != 4) { |
1513 | wiphy_err(wl->wiphy, | 1517 | brcms_err(wl->wlc->hw->d11core, |
1514 | "ERROR: fw hdr len\n"); | 1518 | "ERROR: fw hdr len\n"); |
1515 | return -ENOMSG; | 1519 | return -ENOMSG; |
1516 | } | 1520 | } |
@@ -1519,7 +1523,8 @@ int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx) | |||
1519 | } | 1523 | } |
1520 | } | 1524 | } |
1521 | } | 1525 | } |
1522 | wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx); | 1526 | brcms_err(wl->wlc->hw->d11core, |
1527 | "ERROR: ucode tag:%d can not be found!\n", idx); | ||
1523 | return -ENOMSG; | 1528 | return -ENOMSG; |
1524 | } | 1529 | } |
1525 | 1530 | ||
@@ -1560,8 +1565,8 @@ int brcms_check_firmwares(struct brcms_info *wl) | |||
1560 | sizeof(struct firmware_hdr)); | 1565 | sizeof(struct firmware_hdr)); |
1561 | rc = -EBADF; | 1566 | rc = -EBADF; |
1562 | } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { | 1567 | } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { |
1563 | wiphy_err(wl->wiphy, "%s: out of bounds fw file size " | 1568 | wiphy_err(wl->wiphy, "%s: out of bounds fw file size %zu\n", |
1564 | "%zu\n", __func__, fw->size); | 1569 | __func__, fw->size); |
1565 | rc = -EBADF; | 1570 | rc = -EBADF; |
1566 | } else { | 1571 | } else { |
1567 | /* check if ucode section overruns firmware image */ | 1572 | /* check if ucode section overruns firmware image */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 565c15abbed5..2a44593f1e37 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c | |||
@@ -34,12 +34,9 @@ | |||
34 | #include "ucode_loader.h" | 34 | #include "ucode_loader.h" |
35 | #include "main.h" | 35 | #include "main.h" |
36 | #include "soc.h" | 36 | #include "soc.h" |
37 | 37 | #include "dma.h" | |
38 | /* | 38 | #include "debug.h" |
39 | * Indication for txflowcontrol that all priority bits in | 39 | #include "brcms_trace_events.h" |
40 | * TXQ_STOP_FOR_PRIOFC_MASK are to be considered. | ||
41 | */ | ||
42 | #define ALLPRIO -1 | ||
43 | 40 | ||
44 | /* watchdog timer, in unit of ms */ | 41 | /* watchdog timer, in unit of ms */ |
45 | #define TIMER_INTERVAL_WATCHDOG 1000 | 42 | #define TIMER_INTERVAL_WATCHDOG 1000 |
@@ -126,21 +123,6 @@ | |||
126 | 123 | ||
127 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ | 124 | #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ |
128 | 125 | ||
129 | /* precedences numbers for wlc queues. These are twice as may levels as | ||
130 | * 802.1D priorities. | ||
131 | * Odd numbers are used for HI priority traffic at same precedence levels | ||
132 | * These constants are used ONLY by wlc_prio2prec_map. Do not use them | ||
133 | * elsewhere. | ||
134 | */ | ||
135 | #define _BRCMS_PREC_NONE 0 /* None = - */ | ||
136 | #define _BRCMS_PREC_BK 2 /* BK - Background */ | ||
137 | #define _BRCMS_PREC_BE 4 /* BE - Best-effort */ | ||
138 | #define _BRCMS_PREC_EE 6 /* EE - Excellent-effort */ | ||
139 | #define _BRCMS_PREC_CL 8 /* CL - Controlled Load */ | ||
140 | #define _BRCMS_PREC_VI 10 /* Vi - Video */ | ||
141 | #define _BRCMS_PREC_VO 12 /* Vo - Voice */ | ||
142 | #define _BRCMS_PREC_NC 14 /* NC - Network Control */ | ||
143 | |||
144 | /* synthpu_dly times in us */ | 126 | /* synthpu_dly times in us */ |
145 | #define SYNTHPU_DLY_APHY_US 3700 | 127 | #define SYNTHPU_DLY_APHY_US 3700 |
146 | #define SYNTHPU_DLY_BPHY_US 1050 | 128 | #define SYNTHPU_DLY_BPHY_US 1050 |
@@ -237,17 +219,17 @@ | |||
237 | 219 | ||
238 | #define MAX_DMA_SEGS 4 | 220 | #define MAX_DMA_SEGS 4 |
239 | 221 | ||
240 | /* Max # of entries in Tx FIFO based on 4kb page size */ | 222 | /* # of entries in Tx FIFO */ |
241 | #define NTXD 256 | 223 | #define NTXD 64 |
242 | /* Max # of entries in Rx FIFO based on 4kb page size */ | 224 | /* Max # of entries in Rx FIFO based on 4kb page size */ |
243 | #define NRXD 256 | 225 | #define NRXD 256 |
244 | 226 | ||
227 | /* Amount of headroom to leave in Tx FIFO */ | ||
228 | #define TX_HEADROOM 4 | ||
229 | |||
245 | /* try to keep this # rbufs posted to the chip */ | 230 | /* try to keep this # rbufs posted to the chip */ |
246 | #define NRXBUFPOST 32 | 231 | #define NRXBUFPOST 32 |
247 | 232 | ||
248 | /* data msg txq hiwat mark */ | ||
249 | #define BRCMS_DATAHIWAT 50 | ||
250 | |||
251 | /* max # frames to process in brcms_c_recv() */ | 233 | /* max # frames to process in brcms_c_recv() */ |
252 | #define RXBND 8 | 234 | #define RXBND 8 |
253 | /* max # tx status to process in wlc_txstatus() */ | 235 | /* max # tx status to process in wlc_txstatus() */ |
@@ -283,24 +265,8 @@ struct edcf_acparam { | |||
283 | u16 TXOP; | 265 | u16 TXOP; |
284 | } __packed; | 266 | } __packed; |
285 | 267 | ||
286 | const u8 prio2fifo[NUMPRIO] = { | ||
287 | TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ | ||
288 | TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ | ||
289 | TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ | ||
290 | TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ | ||
291 | TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ | ||
292 | TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ | ||
293 | TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ | ||
294 | TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ | ||
295 | }; | ||
296 | |||
297 | /* debug/trace */ | 268 | /* debug/trace */ |
298 | uint brcm_msg_level = | 269 | uint brcm_msg_level; |
299 | #if defined(DEBUG) | ||
300 | LOG_ERROR_VAL; | ||
301 | #else | ||
302 | 0; | ||
303 | #endif /* DEBUG */ | ||
304 | 270 | ||
305 | /* TX FIFO number to WME/802.1E Access Category */ | 271 | /* TX FIFO number to WME/802.1E Access Category */ |
306 | static const u8 wme_fifo2ac[] = { | 272 | static const u8 wme_fifo2ac[] = { |
@@ -320,18 +286,6 @@ static const u8 wme_ac2fifo[] = { | |||
320 | TX_AC_BK_FIFO | 286 | TX_AC_BK_FIFO |
321 | }; | 287 | }; |
322 | 288 | ||
323 | /* 802.1D Priority to precedence queue mapping */ | ||
324 | const u8 wlc_prio2prec_map[] = { | ||
325 | _BRCMS_PREC_BE, /* 0 BE - Best-effort */ | ||
326 | _BRCMS_PREC_BK, /* 1 BK - Background */ | ||
327 | _BRCMS_PREC_NONE, /* 2 None = - */ | ||
328 | _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ | ||
329 | _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ | ||
330 | _BRCMS_PREC_VI, /* 5 Vi - Video */ | ||
331 | _BRCMS_PREC_VO, /* 6 Vo - Voice */ | ||
332 | _BRCMS_PREC_NC, /* 7 NC - Network Control */ | ||
333 | }; | ||
334 | |||
335 | static const u16 xmtfifo_sz[][NFIFO] = { | 289 | static const u16 xmtfifo_sz[][NFIFO] = { |
336 | /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ | 290 | /* corerev 17: 5120, 49152, 49152, 5376, 4352, 1280 */ |
337 | {20, 192, 192, 21, 17, 5}, | 291 | {20, 192, 192, 21, 17, 5}, |
@@ -371,6 +325,36 @@ static const char fifo_names[6][0]; | |||
371 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); | 325 | static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); |
372 | #endif | 326 | #endif |
373 | 327 | ||
328 | /* Mapping of ieee80211 AC numbers to tx fifos */ | ||
329 | static const u8 ac_to_fifo_mapping[IEEE80211_NUM_ACS] = { | ||
330 | [IEEE80211_AC_VO] = TX_AC_VO_FIFO, | ||
331 | [IEEE80211_AC_VI] = TX_AC_VI_FIFO, | ||
332 | [IEEE80211_AC_BE] = TX_AC_BE_FIFO, | ||
333 | [IEEE80211_AC_BK] = TX_AC_BK_FIFO, | ||
334 | }; | ||
335 | |||
336 | /* Mapping of tx fifos to ieee80211 AC numbers */ | ||
337 | static const u8 fifo_to_ac_mapping[IEEE80211_NUM_ACS] = { | ||
338 | [TX_AC_BK_FIFO] = IEEE80211_AC_BK, | ||
339 | [TX_AC_BE_FIFO] = IEEE80211_AC_BE, | ||
340 | [TX_AC_VI_FIFO] = IEEE80211_AC_VI, | ||
341 | [TX_AC_VO_FIFO] = IEEE80211_AC_VO, | ||
342 | }; | ||
343 | |||
344 | static u8 brcms_ac_to_fifo(u8 ac) | ||
345 | { | ||
346 | if (ac >= ARRAY_SIZE(ac_to_fifo_mapping)) | ||
347 | return TX_AC_BE_FIFO; | ||
348 | return ac_to_fifo_mapping[ac]; | ||
349 | } | ||
350 | |||
351 | static u8 brcms_fifo_to_ac(u8 fifo) | ||
352 | { | ||
353 | if (fifo >= ARRAY_SIZE(fifo_to_ac_mapping)) | ||
354 | return IEEE80211_AC_BE; | ||
355 | return fifo_to_ac_mapping[fifo]; | ||
356 | } | ||
357 | |||
374 | /* Find basic rate for a given rate */ | 358 | /* Find basic rate for a given rate */ |
375 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) | 359 | static u8 brcms_basic_rate(struct brcms_c_info *wlc, u32 rspec) |
376 | { | 360 | { |
@@ -415,10 +399,15 @@ static bool brcms_deviceremoved(struct brcms_c_info *wlc) | |||
415 | } | 399 | } |
416 | 400 | ||
417 | /* sum the individual fifo tx pending packet counts */ | 401 | /* sum the individual fifo tx pending packet counts */ |
418 | static s16 brcms_txpktpendtot(struct brcms_c_info *wlc) | 402 | static int brcms_txpktpendtot(struct brcms_c_info *wlc) |
419 | { | 403 | { |
420 | return wlc->core->txpktpend[0] + wlc->core->txpktpend[1] + | 404 | int i; |
421 | wlc->core->txpktpend[2] + wlc->core->txpktpend[3]; | 405 | int pending = 0; |
406 | |||
407 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) | ||
408 | if (wlc->hw->di[i]) | ||
409 | pending += dma_txpending(wlc->hw->di[i]); | ||
410 | return pending; | ||
422 | } | 411 | } |
423 | 412 | ||
424 | static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) | 413 | static bool brcms_is_mband_unlocked(struct brcms_c_info *wlc) |
@@ -626,14 +615,11 @@ static uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, | |||
626 | uint rate = rspec2rate(ratespec); | 615 | uint rate = rspec2rate(ratespec); |
627 | 616 | ||
628 | if (rate == 0) { | 617 | if (rate == 0) { |
629 | wiphy_err(wlc->wiphy, "wl%d: WAR: using rate of 1 mbps\n", | 618 | brcms_err(wlc->hw->d11core, "wl%d: WAR: using rate of 1 mbps\n", |
630 | wlc->pub->unit); | 619 | wlc->pub->unit); |
631 | rate = BRCM_RATE_1M; | 620 | rate = BRCM_RATE_1M; |
632 | } | 621 | } |
633 | 622 | ||
634 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, len%d\n", | ||
635 | wlc->pub->unit, ratespec, preamble_type, mac_len); | ||
636 | |||
637 | if (is_mcs_rate(ratespec)) { | 623 | if (is_mcs_rate(ratespec)) { |
638 | uint mcs = ratespec & RSPEC_RATE_MASK; | 624 | uint mcs = ratespec & RSPEC_RATE_MASK; |
639 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); | 625 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); |
@@ -696,7 +682,7 @@ static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, | |||
696 | u16 size; | 682 | u16 size; |
697 | u32 value; | 683 | u32 value; |
698 | 684 | ||
699 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 685 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
700 | 686 | ||
701 | for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { | 687 | for (i = 0; inits[i].addr != cpu_to_le16(0xffff); i++) { |
702 | size = le16_to_cpu(inits[i].size); | 688 | size = le16_to_cpu(inits[i].size); |
@@ -725,7 +711,6 @@ static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) | |||
725 | 711 | ||
726 | static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | 712 | static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) |
727 | { | 713 | { |
728 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | ||
729 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; | 714 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; |
730 | 715 | ||
731 | /* init microcode host flags */ | 716 | /* init microcode host flags */ |
@@ -736,8 +721,9 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | |||
736 | if (BRCMS_ISNPHY(wlc_hw->band)) | 721 | if (BRCMS_ISNPHY(wlc_hw->band)) |
737 | brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); | 722 | brcms_c_write_inits(wlc_hw, ucode->d11n0bsinitvals16); |
738 | else | 723 | else |
739 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 724 | brcms_err(wlc_hw->d11core, |
740 | " %d\n", __func__, wlc_hw->unit, | 725 | "%s: wl%d: unsupported phy in corerev %d\n", |
726 | __func__, wlc_hw->unit, | ||
741 | wlc_hw->corerev); | 727 | wlc_hw->corerev); |
742 | } else { | 728 | } else { |
743 | if (D11REV_IS(wlc_hw->corerev, 24)) { | 729 | if (D11REV_IS(wlc_hw->corerev, 24)) { |
@@ -745,12 +731,14 @@ static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) | |||
745 | brcms_c_write_inits(wlc_hw, | 731 | brcms_c_write_inits(wlc_hw, |
746 | ucode->d11lcn0bsinitvals24); | 732 | ucode->d11lcn0bsinitvals24); |
747 | else | 733 | else |
748 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in" | 734 | brcms_err(wlc_hw->d11core, |
749 | " core rev %d\n", __func__, | 735 | "%s: wl%d: unsupported phy in core rev %d\n", |
750 | wlc_hw->unit, wlc_hw->corerev); | 736 | __func__, wlc_hw->unit, |
737 | wlc_hw->corerev); | ||
751 | } else { | 738 | } else { |
752 | wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", | 739 | brcms_err(wlc_hw->d11core, |
753 | __func__, wlc_hw->unit, wlc_hw->corerev); | 740 | "%s: wl%d: unsupported corerev %d\n", |
741 | __func__, wlc_hw->unit, wlc_hw->corerev); | ||
754 | } | 742 | } |
755 | } | 743 | } |
756 | } | 744 | } |
@@ -765,7 +753,7 @@ static void brcms_b_core_ioctl(struct brcms_hardware *wlc_hw, u32 m, u32 v) | |||
765 | 753 | ||
766 | static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) | 754 | static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) |
767 | { | 755 | { |
768 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); | 756 | brcms_dbg_info(wlc_hw->d11core, "wl%d: clk %d\n", wlc_hw->unit, clk); |
769 | 757 | ||
770 | wlc_hw->phyclk = clk; | 758 | wlc_hw->phyclk = clk; |
771 | 759 | ||
@@ -790,8 +778,8 @@ static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) | |||
790 | /* low-level band switch utility routine */ | 778 | /* low-level band switch utility routine */ |
791 | static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) | 779 | static void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) |
792 | { | 780 | { |
793 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 781 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, |
794 | bandunit); | 782 | bandunit); |
795 | 783 | ||
796 | wlc_hw->band = wlc_hw->bandstate[bandunit]; | 784 | wlc_hw->band = wlc_hw->bandstate[bandunit]; |
797 | 785 | ||
@@ -819,7 +807,7 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) | |||
819 | u32 macintmask; | 807 | u32 macintmask; |
820 | u32 macctrl; | 808 | u32 macctrl; |
821 | 809 | ||
822 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | 810 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
823 | macctrl = bcma_read32(wlc_hw->d11core, | 811 | macctrl = bcma_read32(wlc_hw->d11core, |
824 | D11REGOFFS(maccontrol)); | 812 | D11REGOFFS(maccontrol)); |
825 | WARN_ON((macctrl & MCTL_EN_MAC) != 0); | 813 | WARN_ON((macctrl & MCTL_EN_MAC) != 0); |
@@ -841,9 +829,10 @@ static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) | |||
841 | static bool | 829 | static bool |
842 | brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | 830 | brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) |
843 | { | 831 | { |
844 | struct sk_buff *p; | 832 | struct sk_buff *p = NULL; |
845 | uint queue; | 833 | uint queue = NFIFO; |
846 | struct d11txh *txh; | 834 | struct dma_pub *dma = NULL; |
835 | struct d11txh *txh = NULL; | ||
847 | struct scb *scb = NULL; | 836 | struct scb *scb = NULL; |
848 | bool free_pdu; | 837 | bool free_pdu; |
849 | int tx_rts, tx_frame_count, tx_rts_count; | 838 | int tx_rts, tx_frame_count, tx_rts_count; |
@@ -854,6 +843,11 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
854 | struct ieee80211_tx_info *tx_info; | 843 | struct ieee80211_tx_info *tx_info; |
855 | struct ieee80211_tx_rate *txrate; | 844 | struct ieee80211_tx_rate *txrate; |
856 | int i; | 845 | int i; |
846 | bool fatal = true; | ||
847 | |||
848 | trace_brcms_txstatus(&wlc->hw->d11core->dev, txs->framelen, | ||
849 | txs->frameid, txs->status, txs->lasttxtime, | ||
850 | txs->sequence, txs->phyerr, txs->ackphyrxsh); | ||
857 | 851 | ||
858 | /* discard intermediate indications for ucode with one legitimate case: | 852 | /* discard intermediate indications for ucode with one legitimate case: |
859 | * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, | 853 | * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, |
@@ -862,34 +856,36 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
862 | */ | 856 | */ |
863 | if (!(txs->status & TX_STATUS_AMPDU) | 857 | if (!(txs->status & TX_STATUS_AMPDU) |
864 | && (txs->status & TX_STATUS_INTERMEDIATE)) { | 858 | && (txs->status & TX_STATUS_INTERMEDIATE)) { |
865 | BCMMSG(wlc->wiphy, "INTERMEDIATE but not AMPDU\n"); | 859 | brcms_dbg_tx(wlc->hw->d11core, "INTERMEDIATE but not AMPDU\n"); |
866 | return false; | 860 | fatal = false; |
861 | goto out; | ||
867 | } | 862 | } |
868 | 863 | ||
869 | queue = txs->frameid & TXFID_QUEUE_MASK; | 864 | queue = txs->frameid & TXFID_QUEUE_MASK; |
870 | if (queue >= NFIFO) { | 865 | if (queue >= NFIFO) { |
871 | p = NULL; | 866 | brcms_err(wlc->hw->d11core, "queue %u >= NFIFO\n", queue); |
872 | goto fatal; | 867 | goto out; |
873 | } | 868 | } |
874 | 869 | ||
870 | dma = wlc->hw->di[queue]; | ||
871 | |||
875 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); | 872 | p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED); |
876 | if (p == NULL) | 873 | if (p == NULL) { |
877 | goto fatal; | 874 | brcms_err(wlc->hw->d11core, "dma_getnexttxp returned null!\n"); |
875 | goto out; | ||
876 | } | ||
878 | 877 | ||
879 | txh = (struct d11txh *) (p->data); | 878 | txh = (struct d11txh *) (p->data); |
880 | mcl = le16_to_cpu(txh->MacTxControlLow); | 879 | mcl = le16_to_cpu(txh->MacTxControlLow); |
881 | 880 | ||
882 | if (txs->phyerr) { | 881 | if (txs->phyerr) |
883 | if (brcm_msg_level & LOG_ERROR_VAL) { | 882 | brcms_err(wlc->hw->d11core, "phyerr 0x%x, rate 0x%x\n", |
884 | wiphy_err(wlc->wiphy, "phyerr 0x%x, rate 0x%x\n", | 883 | txs->phyerr, txh->MainRates); |
885 | txs->phyerr, txh->MainRates); | ||
886 | brcms_c_print_txdesc(txh); | ||
887 | } | ||
888 | brcms_c_print_txstatus(txs); | ||
889 | } | ||
890 | 884 | ||
891 | if (txs->frameid != le16_to_cpu(txh->TxFrameID)) | 885 | if (txs->frameid != le16_to_cpu(txh->TxFrameID)) { |
892 | goto fatal; | 886 | brcms_err(wlc->hw->d11core, "frameid != txh->TxFrameID\n"); |
887 | goto out; | ||
888 | } | ||
893 | tx_info = IEEE80211_SKB_CB(p); | 889 | tx_info = IEEE80211_SKB_CB(p); |
894 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); | 890 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); |
895 | 891 | ||
@@ -898,14 +894,24 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
898 | 894 | ||
899 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | 895 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { |
900 | brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); | 896 | brcms_c_ampdu_dotxstatus(wlc->ampdu, scb, p, txs); |
901 | return false; | 897 | fatal = false; |
898 | goto out; | ||
902 | } | 899 | } |
903 | 900 | ||
901 | /* | ||
902 | * brcms_c_ampdu_dotxstatus() will trace tx descriptors for AMPDU | ||
903 | * frames; this traces them for the rest. | ||
904 | */ | ||
905 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); | ||
906 | |||
904 | supr_status = txs->status & TX_STATUS_SUPR_MASK; | 907 | supr_status = txs->status & TX_STATUS_SUPR_MASK; |
905 | if (supr_status == TX_STATUS_SUPR_BADCH) | 908 | if (supr_status == TX_STATUS_SUPR_BADCH) { |
906 | BCMMSG(wlc->wiphy, | 909 | unsigned xfts = le16_to_cpu(txh->XtraFrameTypes); |
907 | "%s: Pkt tx suppressed, possibly channel %d\n", | 910 | brcms_dbg_tx(wlc->hw->d11core, |
908 | __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); | 911 | "Pkt tx suppressed, dest chan %u, current %d\n", |
912 | (xfts >> XFTS_CHANNEL_SHIFT) & 0xff, | ||
913 | CHSPEC_CHANNEL(wlc->default_bss->chanspec)); | ||
914 | } | ||
909 | 915 | ||
910 | tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; | 916 | tx_rts = le16_to_cpu(txh->MacTxControlLow) & TXC_SENDRTS; |
911 | tx_frame_count = | 917 | tx_frame_count = |
@@ -916,7 +922,7 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
916 | lastframe = !ieee80211_has_morefrags(h->frame_control); | 922 | lastframe = !ieee80211_has_morefrags(h->frame_control); |
917 | 923 | ||
918 | if (!lastframe) { | 924 | if (!lastframe) { |
919 | wiphy_err(wlc->wiphy, "Not last frame!\n"); | 925 | brcms_err(wlc->hw->d11core, "Not last frame!\n"); |
920 | } else { | 926 | } else { |
921 | /* | 927 | /* |
922 | * Set information to be consumed by Minstrel ht. | 928 | * Set information to be consumed by Minstrel ht. |
@@ -982,26 +988,37 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs) | |||
982 | totlen = p->len; | 988 | totlen = p->len; |
983 | free_pdu = true; | 989 | free_pdu = true; |
984 | 990 | ||
985 | brcms_c_txfifo_complete(wlc, queue, 1); | ||
986 | |||
987 | if (lastframe) { | 991 | if (lastframe) { |
988 | /* remove PLCP & Broadcom tx descriptor header */ | 992 | /* remove PLCP & Broadcom tx descriptor header */ |
989 | skb_pull(p, D11_PHY_HDR_LEN); | 993 | skb_pull(p, D11_PHY_HDR_LEN); |
990 | skb_pull(p, D11_TXH_LEN); | 994 | skb_pull(p, D11_TXH_LEN); |
991 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); | 995 | ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); |
992 | } else { | 996 | } else { |
993 | wiphy_err(wlc->wiphy, "%s: Not last frame => not calling " | 997 | brcms_err(wlc->hw->d11core, |
994 | "tx_status\n", __func__); | 998 | "%s: Not last frame => not calling tx_status\n", |
999 | __func__); | ||
995 | } | 1000 | } |
996 | 1001 | ||
997 | return false; | 1002 | fatal = false; |
998 | 1003 | ||
999 | fatal: | 1004 | out: |
1000 | if (p) | 1005 | if (fatal) { |
1001 | brcmu_pkt_buf_free_skb(p); | 1006 | if (txh) |
1007 | trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, | ||
1008 | sizeof(*txh)); | ||
1009 | if (p) | ||
1010 | brcmu_pkt_buf_free_skb(p); | ||
1011 | } | ||
1002 | 1012 | ||
1003 | return true; | 1013 | if (dma && queue < NFIFO) { |
1014 | u16 ac_queue = brcms_fifo_to_ac(queue); | ||
1015 | if (dma->txavail > TX_HEADROOM && queue < TX_BCMC_FIFO && | ||
1016 | ieee80211_queue_stopped(wlc->pub->ieee_hw, ac_queue)) | ||
1017 | ieee80211_wake_queue(wlc->pub->ieee_hw, ac_queue); | ||
1018 | dma_kick_tx(dma); | ||
1019 | } | ||
1004 | 1020 | ||
1021 | return fatal; | ||
1005 | } | 1022 | } |
1006 | 1023 | ||
1007 | /* process tx completion events in BMAC | 1024 | /* process tx completion events in BMAC |
@@ -1011,7 +1028,6 @@ static bool | |||
1011 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | 1028 | brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) |
1012 | { | 1029 | { |
1013 | bool morepending = false; | 1030 | bool morepending = false; |
1014 | struct brcms_c_info *wlc = wlc_hw->wlc; | ||
1015 | struct bcma_device *core; | 1031 | struct bcma_device *core; |
1016 | struct tx_status txstatus, *txs; | 1032 | struct tx_status txstatus, *txs; |
1017 | u32 s1, s2; | 1033 | u32 s1, s2; |
@@ -1022,8 +1038,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1022 | */ | 1038 | */ |
1023 | uint max_tx_num = bound ? TXSBND : -1; | 1039 | uint max_tx_num = bound ? TXSBND : -1; |
1024 | 1040 | ||
1025 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
1026 | |||
1027 | txs = &txstatus; | 1041 | txs = &txstatus; |
1028 | core = wlc_hw->d11core; | 1042 | core = wlc_hw->d11core; |
1029 | *fatal = false; | 1043 | *fatal = false; |
@@ -1032,8 +1046,8 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1032 | && (s1 & TXS_V)) { | 1046 | && (s1 & TXS_V)) { |
1033 | 1047 | ||
1034 | if (s1 == 0xffffffff) { | 1048 | if (s1 == 0xffffffff) { |
1035 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", | 1049 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
1036 | wlc_hw->unit, __func__); | 1050 | __func__); |
1037 | return morepending; | 1051 | return morepending; |
1038 | } | 1052 | } |
1039 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); | 1053 | s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); |
@@ -1058,9 +1072,6 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) | |||
1058 | if (n >= max_tx_num) | 1072 | if (n >= max_tx_num) |
1059 | morepending = true; | 1073 | morepending = true; |
1060 | 1074 | ||
1061 | if (!pktq_empty(&wlc->pkt_queue->q)) | ||
1062 | brcms_c_send_q(wlc); | ||
1063 | |||
1064 | return morepending; | 1075 | return morepending; |
1065 | } | 1076 | } |
1066 | 1077 | ||
@@ -1112,7 +1123,6 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1112 | u16 pio_mhf2 = 0; | 1123 | u16 pio_mhf2 = 0; |
1113 | struct brcms_hardware *wlc_hw = wlc->hw; | 1124 | struct brcms_hardware *wlc_hw = wlc->hw; |
1114 | uint unit = wlc_hw->unit; | 1125 | uint unit = wlc_hw->unit; |
1115 | struct wiphy *wiphy = wlc->wiphy; | ||
1116 | 1126 | ||
1117 | /* name and offsets for dma_attach */ | 1127 | /* name and offsets for dma_attach */ |
1118 | snprintf(name, sizeof(name), "wl%d", unit); | 1128 | snprintf(name, sizeof(name), "wl%d", unit); |
@@ -1125,12 +1135,12 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1125 | * TX: TX_AC_BK_FIFO (TX AC Background data packets) | 1135 | * TX: TX_AC_BK_FIFO (TX AC Background data packets) |
1126 | * RX: RX_FIFO (RX data packets) | 1136 | * RX: RX_FIFO (RX data packets) |
1127 | */ | 1137 | */ |
1128 | wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1138 | wlc_hw->di[0] = dma_attach(name, wlc, |
1129 | (wme ? dmareg(DMA_TX, 0) : 0), | 1139 | (wme ? dmareg(DMA_TX, 0) : 0), |
1130 | dmareg(DMA_RX, 0), | 1140 | dmareg(DMA_RX, 0), |
1131 | (wme ? NTXD : 0), NRXD, | 1141 | (wme ? NTXD : 0), NRXD, |
1132 | RXBUFSZ, -1, NRXBUFPOST, | 1142 | RXBUFSZ, -1, NRXBUFPOST, |
1133 | BRCMS_HWRXOFF, &brcm_msg_level); | 1143 | BRCMS_HWRXOFF); |
1134 | dma_attach_err |= (NULL == wlc_hw->di[0]); | 1144 | dma_attach_err |= (NULL == wlc_hw->di[0]); |
1135 | 1145 | ||
1136 | /* | 1146 | /* |
@@ -1139,10 +1149,9 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1139 | * (legacy) TX_DATA_FIFO (TX data packets) | 1149 | * (legacy) TX_DATA_FIFO (TX data packets) |
1140 | * RX: UNUSED | 1150 | * RX: UNUSED |
1141 | */ | 1151 | */ |
1142 | wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1152 | wlc_hw->di[1] = dma_attach(name, wlc, |
1143 | dmareg(DMA_TX, 1), 0, | 1153 | dmareg(DMA_TX, 1), 0, |
1144 | NTXD, 0, 0, -1, 0, 0, | 1154 | NTXD, 0, 0, -1, 0, 0); |
1145 | &brcm_msg_level); | ||
1146 | dma_attach_err |= (NULL == wlc_hw->di[1]); | 1155 | dma_attach_err |= (NULL == wlc_hw->di[1]); |
1147 | 1156 | ||
1148 | /* | 1157 | /* |
@@ -1150,26 +1159,26 @@ static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) | |||
1150 | * TX: TX_AC_VI_FIFO (TX AC Video data packets) | 1159 | * TX: TX_AC_VI_FIFO (TX AC Video data packets) |
1151 | * RX: UNUSED | 1160 | * RX: UNUSED |
1152 | */ | 1161 | */ |
1153 | wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1162 | wlc_hw->di[2] = dma_attach(name, wlc, |
1154 | dmareg(DMA_TX, 2), 0, | 1163 | dmareg(DMA_TX, 2), 0, |
1155 | NTXD, 0, 0, -1, 0, 0, | 1164 | NTXD, 0, 0, -1, 0, 0); |
1156 | &brcm_msg_level); | ||
1157 | dma_attach_err |= (NULL == wlc_hw->di[2]); | 1165 | dma_attach_err |= (NULL == wlc_hw->di[2]); |
1158 | /* | 1166 | /* |
1159 | * FIFO 3 | 1167 | * FIFO 3 |
1160 | * TX: TX_AC_VO_FIFO (TX AC Voice data packets) | 1168 | * TX: TX_AC_VO_FIFO (TX AC Voice data packets) |
1161 | * (legacy) TX_CTL_FIFO (TX control & mgmt packets) | 1169 | * (legacy) TX_CTL_FIFO (TX control & mgmt packets) |
1162 | */ | 1170 | */ |
1163 | wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, wlc_hw->d11core, | 1171 | wlc_hw->di[3] = dma_attach(name, wlc, |
1164 | dmareg(DMA_TX, 3), | 1172 | dmareg(DMA_TX, 3), |
1165 | 0, NTXD, 0, 0, -1, | 1173 | 0, NTXD, 0, 0, -1, |
1166 | 0, 0, &brcm_msg_level); | 1174 | 0, 0); |
1167 | dma_attach_err |= (NULL == wlc_hw->di[3]); | 1175 | dma_attach_err |= (NULL == wlc_hw->di[3]); |
1168 | /* Cleaner to leave this as if with AP defined */ | 1176 | /* Cleaner to leave this as if with AP defined */ |
1169 | 1177 | ||
1170 | if (dma_attach_err) { | 1178 | if (dma_attach_err) { |
1171 | wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" | 1179 | brcms_err(wlc_hw->d11core, |
1172 | "\n", unit); | 1180 | "wl%d: wlc_attach: dma_attach failed\n", |
1181 | unit); | ||
1173 | return false; | 1182 | return false; |
1174 | } | 1183 | } |
1175 | 1184 | ||
@@ -1503,8 +1512,7 @@ brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, | |||
1503 | u16 mac_m; | 1512 | u16 mac_m; |
1504 | u16 mac_h; | 1513 | u16 mac_h; |
1505 | 1514 | ||
1506 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", | 1515 | brcms_dbg_rx(core, "wl%d: brcms_b_set_addrmatch\n", wlc_hw->unit); |
1507 | wlc_hw->unit); | ||
1508 | 1516 | ||
1509 | mac_l = addr[0] | (addr[1] << 8); | 1517 | mac_l = addr[0] | (addr[1] << 8); |
1510 | mac_m = addr[2] | (addr[3] << 8); | 1518 | mac_m = addr[2] | (addr[3] << 8); |
@@ -1527,7 +1535,7 @@ brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, | |||
1527 | __le32 word_le; | 1535 | __le32 word_le; |
1528 | __be32 word_be; | 1536 | __be32 word_be; |
1529 | bool be_bit; | 1537 | bool be_bit; |
1530 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 1538 | brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); |
1531 | 1539 | ||
1532 | bcma_write32(core, D11REGOFFS(tplatewrptr), offset); | 1540 | bcma_write32(core, D11REGOFFS(tplatewrptr), offset); |
1533 | 1541 | ||
@@ -1700,8 +1708,8 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) | |||
1700 | { | 1708 | { |
1701 | struct brcms_hardware *wlc_hw = wlc->hw; | 1709 | struct brcms_hardware *wlc_hw = wlc->hw; |
1702 | 1710 | ||
1703 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 1711 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: bandunit %d\n", wlc_hw->unit, |
1704 | wlc_hw->band->bandunit); | 1712 | wlc_hw->band->bandunit); |
1705 | 1713 | ||
1706 | brcms_c_ucode_bsinit(wlc_hw); | 1714 | brcms_c_ucode_bsinit(wlc_hw); |
1707 | 1715 | ||
@@ -1736,8 +1744,6 @@ static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) | |||
1736 | /* Perform a soft reset of the PHY PLL */ | 1744 | /* Perform a soft reset of the PHY PLL */ |
1737 | void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) | 1745 | void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) |
1738 | { | 1746 | { |
1739 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
1740 | |||
1741 | ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), | 1747 | ai_cc_reg(wlc_hw->sih, offsetof(struct chipcregs, chipcontrol_addr), |
1742 | ~0, 0); | 1748 | ~0, 0); |
1743 | udelay(1); | 1749 | udelay(1); |
@@ -1782,7 +1788,7 @@ void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) | |||
1782 | u32 phy_bw_clkbits; | 1788 | u32 phy_bw_clkbits; |
1783 | bool phy_in_reset = false; | 1789 | bool phy_in_reset = false; |
1784 | 1790 | ||
1785 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 1791 | brcms_dbg_info(wlc_hw->d11core, "wl%d: reset phy\n", wlc_hw->unit); |
1786 | 1792 | ||
1787 | if (pih == NULL) | 1793 | if (pih == NULL) |
1788 | return; | 1794 | return; |
@@ -1916,7 +1922,7 @@ static void brcms_c_get_macaddr(struct brcms_hardware *wlc_hw, u8 etheraddr[ETH_ | |||
1916 | /* power both the pll and external oscillator on/off */ | 1922 | /* power both the pll and external oscillator on/off */ |
1917 | static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) | 1923 | static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) |
1918 | { | 1924 | { |
1919 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); | 1925 | brcms_dbg_info(wlc_hw->d11core, "wl%d: want %d\n", wlc_hw->unit, want); |
1920 | 1926 | ||
1921 | /* | 1927 | /* |
1922 | * dont power down if plldown is false or | 1928 | * dont power down if plldown is false or |
@@ -2005,7 +2011,7 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) | |||
2005 | if (flags == BRCMS_USE_COREFLAGS) | 2011 | if (flags == BRCMS_USE_COREFLAGS) |
2006 | flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); | 2012 | flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); |
2007 | 2013 | ||
2008 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2014 | brcms_dbg_info(wlc_hw->d11core, "wl%d: core reset\n", wlc_hw->unit); |
2009 | 2015 | ||
2010 | /* request FAST clock if not on */ | 2016 | /* request FAST clock if not on */ |
2011 | fastclk = wlc_hw->forcefastclk; | 2017 | fastclk = wlc_hw->forcefastclk; |
@@ -2016,13 +2022,13 @@ void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) | |||
2016 | if (bcma_core_is_enabled(wlc_hw->d11core)) { | 2022 | if (bcma_core_is_enabled(wlc_hw->d11core)) { |
2017 | for (i = 0; i < NFIFO; i++) | 2023 | for (i = 0; i < NFIFO; i++) |
2018 | if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) | 2024 | if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) |
2019 | wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " | 2025 | brcms_err(wlc_hw->d11core, "wl%d: %s: " |
2020 | "dma_txreset[%d]: cannot stop dma\n", | 2026 | "dma_txreset[%d]: cannot stop dma\n", |
2021 | wlc_hw->unit, __func__, i); | 2027 | wlc_hw->unit, __func__, i); |
2022 | 2028 | ||
2023 | if ((wlc_hw->di[RX_FIFO]) | 2029 | if ((wlc_hw->di[RX_FIFO]) |
2024 | && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) | 2030 | && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) |
2025 | wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" | 2031 | brcms_err(wlc_hw->d11core, "wl%d: %s: dma_rxreset" |
2026 | "[%d]: cannot stop dma\n", | 2032 | "[%d]: cannot stop dma\n", |
2027 | wlc_hw->unit, __func__, RX_FIFO); | 2033 | wlc_hw->unit, __func__, RX_FIFO); |
2028 | } | 2034 | } |
@@ -2235,7 +2241,7 @@ static void brcms_ucode_write(struct brcms_hardware *wlc_hw, | |||
2235 | uint i; | 2241 | uint i; |
2236 | uint count; | 2242 | uint count; |
2237 | 2243 | ||
2238 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2244 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
2239 | 2245 | ||
2240 | count = (nbytes / sizeof(u32)); | 2246 | count = (nbytes / sizeof(u32)); |
2241 | 2247 | ||
@@ -2263,8 +2269,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) | |||
2263 | ucode->bcm43xx_16_mimosz); | 2269 | ucode->bcm43xx_16_mimosz); |
2264 | wlc_hw->ucode_loaded = true; | 2270 | wlc_hw->ucode_loaded = true; |
2265 | } else | 2271 | } else |
2266 | wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " | 2272 | brcms_err(wlc_hw->d11core, |
2267 | "corerev %d\n", | 2273 | "%s: wl%d: unsupported phy in corerev %d\n", |
2268 | __func__, wlc_hw->unit, wlc_hw->corerev); | 2274 | __func__, wlc_hw->unit, wlc_hw->corerev); |
2269 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { | 2275 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { |
2270 | if (BRCMS_ISLCNPHY(wlc_hw->band)) { | 2276 | if (BRCMS_ISLCNPHY(wlc_hw->band)) { |
@@ -2272,8 +2278,8 @@ static void brcms_ucode_download(struct brcms_hardware *wlc_hw) | |||
2272 | ucode->bcm43xx_24_lcnsz); | 2278 | ucode->bcm43xx_24_lcnsz); |
2273 | wlc_hw->ucode_loaded = true; | 2279 | wlc_hw->ucode_loaded = true; |
2274 | } else { | 2280 | } else { |
2275 | wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " | 2281 | brcms_err(wlc_hw->d11core, |
2276 | "corerev %d\n", | 2282 | "%s: wl%d: unsupported phy in corerev %d\n", |
2277 | __func__, wlc_hw->unit, wlc_hw->corerev); | 2283 | __func__, wlc_hw->unit, wlc_hw->corerev); |
2278 | } | 2284 | } |
2279 | } | 2285 | } |
@@ -2310,7 +2316,6 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2310 | uint unit; | 2316 | uint unit; |
2311 | uint intstatus, idx; | 2317 | uint intstatus, idx; |
2312 | struct bcma_device *core = wlc_hw->d11core; | 2318 | struct bcma_device *core = wlc_hw->d11core; |
2313 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | ||
2314 | 2319 | ||
2315 | unit = wlc_hw->unit; | 2320 | unit = wlc_hw->unit; |
2316 | 2321 | ||
@@ -2323,39 +2328,39 @@ static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) | |||
2323 | if (!intstatus) | 2328 | if (!intstatus) |
2324 | continue; | 2329 | continue; |
2325 | 2330 | ||
2326 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", | 2331 | brcms_dbg_int(core, "wl%d: intstatus%d 0x%x\n", |
2327 | unit, idx, intstatus); | 2332 | unit, idx, intstatus); |
2328 | 2333 | ||
2329 | if (intstatus & I_RO) { | 2334 | if (intstatus & I_RO) { |
2330 | wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " | 2335 | brcms_err(core, "wl%d: fifo %d: receive fifo " |
2331 | "overflow\n", unit, idx); | 2336 | "overflow\n", unit, idx); |
2332 | fatal = true; | 2337 | fatal = true; |
2333 | } | 2338 | } |
2334 | 2339 | ||
2335 | if (intstatus & I_PC) { | 2340 | if (intstatus & I_PC) { |
2336 | wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", | 2341 | brcms_err(core, "wl%d: fifo %d: descriptor error\n", |
2337 | unit, idx); | 2342 | unit, idx); |
2338 | fatal = true; | 2343 | fatal = true; |
2339 | } | 2344 | } |
2340 | 2345 | ||
2341 | if (intstatus & I_PD) { | 2346 | if (intstatus & I_PD) { |
2342 | wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, | 2347 | brcms_err(core, "wl%d: fifo %d: data error\n", unit, |
2343 | idx); | 2348 | idx); |
2344 | fatal = true; | 2349 | fatal = true; |
2345 | } | 2350 | } |
2346 | 2351 | ||
2347 | if (intstatus & I_DE) { | 2352 | if (intstatus & I_DE) { |
2348 | wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " | 2353 | brcms_err(core, "wl%d: fifo %d: descriptor protocol " |
2349 | "error\n", unit, idx); | 2354 | "error\n", unit, idx); |
2350 | fatal = true; | 2355 | fatal = true; |
2351 | } | 2356 | } |
2352 | 2357 | ||
2353 | if (intstatus & I_RU) | 2358 | if (intstatus & I_RU) |
2354 | wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " | 2359 | brcms_err(core, "wl%d: fifo %d: receive descriptor " |
2355 | "underflow\n", idx, unit); | 2360 | "underflow\n", idx, unit); |
2356 | 2361 | ||
2357 | if (intstatus & I_XU) { | 2362 | if (intstatus & I_XU) { |
2358 | wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " | 2363 | brcms_err(core, "wl%d: fifo %d: transmit fifo " |
2359 | "underflow\n", idx, unit); | 2364 | "underflow\n", idx, unit); |
2360 | fatal = true; | 2365 | fatal = true; |
2361 | } | 2366 | } |
@@ -2516,13 +2521,13 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) | |||
2516 | { | 2521 | { |
2517 | struct brcms_hardware *wlc_hw = wlc->hw; | 2522 | struct brcms_hardware *wlc_hw = wlc->hw; |
2518 | struct bcma_device *core = wlc_hw->d11core; | 2523 | struct bcma_device *core = wlc_hw->d11core; |
2519 | u32 macintstatus; | 2524 | u32 macintstatus, mask; |
2520 | 2525 | ||
2521 | /* macintstatus includes a DMA interrupt summary bit */ | 2526 | /* macintstatus includes a DMA interrupt summary bit */ |
2522 | macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); | 2527 | macintstatus = bcma_read32(core, D11REGOFFS(macintstatus)); |
2528 | mask = in_isr ? wlc->macintmask : wlc->defmacintmask; | ||
2523 | 2529 | ||
2524 | BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, | 2530 | trace_brcms_macintstatus(&core->dev, in_isr, macintstatus, mask); |
2525 | macintstatus); | ||
2526 | 2531 | ||
2527 | /* detect cardbus removed, in power down(suspend) and in reset */ | 2532 | /* detect cardbus removed, in power down(suspend) and in reset */ |
2528 | if (brcms_deviceremoved(wlc)) | 2533 | if (brcms_deviceremoved(wlc)) |
@@ -2535,7 +2540,7 @@ static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) | |||
2535 | return 0; | 2540 | return 0; |
2536 | 2541 | ||
2537 | /* defer unsolicited interrupts */ | 2542 | /* defer unsolicited interrupts */ |
2538 | macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); | 2543 | macintstatus &= mask; |
2539 | 2544 | ||
2540 | /* if not for us */ | 2545 | /* if not for us */ |
2541 | if (macintstatus == 0) | 2546 | if (macintstatus == 0) |
@@ -2605,8 +2610,8 @@ bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) | |||
2605 | macintstatus = wlc_intstatus(wlc, true); | 2610 | macintstatus = wlc_intstatus(wlc, true); |
2606 | 2611 | ||
2607 | if (macintstatus == 0xffffffff) | 2612 | if (macintstatus == 0xffffffff) |
2608 | wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" | 2613 | brcms_err(wlc_hw->d11core, |
2609 | " path\n"); | 2614 | "DEVICEREMOVED detected in the ISR code path\n"); |
2610 | 2615 | ||
2611 | /* it is not for us */ | 2616 | /* it is not for us */ |
2612 | if (macintstatus == 0) | 2617 | if (macintstatus == 0) |
@@ -2626,10 +2631,9 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2626 | struct brcms_hardware *wlc_hw = wlc->hw; | 2631 | struct brcms_hardware *wlc_hw = wlc->hw; |
2627 | struct bcma_device *core = wlc_hw->d11core; | 2632 | struct bcma_device *core = wlc_hw->d11core; |
2628 | u32 mc, mi; | 2633 | u32 mc, mi; |
2629 | struct wiphy *wiphy = wlc->wiphy; | ||
2630 | 2634 | ||
2631 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 2635 | brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, |
2632 | wlc_hw->band->bandunit); | 2636 | wlc_hw->band->bandunit); |
2633 | 2637 | ||
2634 | /* | 2638 | /* |
2635 | * Track overlapping suspend requests | 2639 | * Track overlapping suspend requests |
@@ -2644,7 +2648,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2644 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); | 2648 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); |
2645 | 2649 | ||
2646 | if (mc == 0xffffffff) { | 2650 | if (mc == 0xffffffff) { |
2647 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2651 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2648 | __func__); | 2652 | __func__); |
2649 | brcms_down(wlc->wl); | 2653 | brcms_down(wlc->wl); |
2650 | return; | 2654 | return; |
@@ -2655,7 +2659,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2655 | 2659 | ||
2656 | mi = bcma_read32(core, D11REGOFFS(macintstatus)); | 2660 | mi = bcma_read32(core, D11REGOFFS(macintstatus)); |
2657 | if (mi == 0xffffffff) { | 2661 | if (mi == 0xffffffff) { |
2658 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2662 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2659 | __func__); | 2663 | __func__); |
2660 | brcms_down(wlc->wl); | 2664 | brcms_down(wlc->wl); |
2661 | return; | 2665 | return; |
@@ -2668,10 +2672,10 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2668 | BRCMS_MAX_MAC_SUSPEND); | 2672 | BRCMS_MAX_MAC_SUSPEND); |
2669 | 2673 | ||
2670 | if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { | 2674 | if (!(bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD)) { |
2671 | wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" | 2675 | brcms_err(core, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" |
2672 | " and MI_MACSSPNDD is still not on.\n", | 2676 | " and MI_MACSSPNDD is still not on.\n", |
2673 | wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); | 2677 | wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); |
2674 | wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " | 2678 | brcms_err(core, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " |
2675 | "psm_brc 0x%04x\n", wlc_hw->unit, | 2679 | "psm_brc 0x%04x\n", wlc_hw->unit, |
2676 | bcma_read32(core, D11REGOFFS(psmdebug)), | 2680 | bcma_read32(core, D11REGOFFS(psmdebug)), |
2677 | bcma_read32(core, D11REGOFFS(phydebug)), | 2681 | bcma_read32(core, D11REGOFFS(phydebug)), |
@@ -2680,7 +2684,7 @@ void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) | |||
2680 | 2684 | ||
2681 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); | 2685 | mc = bcma_read32(core, D11REGOFFS(maccontrol)); |
2682 | if (mc == 0xffffffff) { | 2686 | if (mc == 0xffffffff) { |
2683 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 2687 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
2684 | __func__); | 2688 | __func__); |
2685 | brcms_down(wlc->wl); | 2689 | brcms_down(wlc->wl); |
2686 | return; | 2690 | return; |
@@ -2696,8 +2700,8 @@ void brcms_c_enable_mac(struct brcms_c_info *wlc) | |||
2696 | struct bcma_device *core = wlc_hw->d11core; | 2700 | struct bcma_device *core = wlc_hw->d11core; |
2697 | u32 mc, mi; | 2701 | u32 mc, mi; |
2698 | 2702 | ||
2699 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, | 2703 | brcms_dbg_mac80211(core, "wl%d: bandunit %d\n", wlc_hw->unit, |
2700 | wlc->band->bandunit); | 2704 | wlc->band->bandunit); |
2701 | 2705 | ||
2702 | /* | 2706 | /* |
2703 | * Track overlapping suspend requests | 2707 | * Track overlapping suspend requests |
@@ -2740,8 +2744,6 @@ static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) | |||
2740 | u32 w, val; | 2744 | u32 w, val; |
2741 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; | 2745 | struct wiphy *wiphy = wlc_hw->wlc->wiphy; |
2742 | 2746 | ||
2743 | BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); | ||
2744 | |||
2745 | /* Validate dchip register access */ | 2747 | /* Validate dchip register access */ |
2746 | 2748 | ||
2747 | bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); | 2749 | bcma_write32(core, D11REGOFFS(objaddr), OBJADDR_SHM_SEL | 0); |
@@ -2802,7 +2804,7 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2802 | struct bcma_device *core = wlc_hw->d11core; | 2804 | struct bcma_device *core = wlc_hw->d11core; |
2803 | u32 tmp; | 2805 | u32 tmp; |
2804 | 2806 | ||
2805 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2807 | brcms_dbg_info(core, "wl%d\n", wlc_hw->unit); |
2806 | 2808 | ||
2807 | tmp = 0; | 2809 | tmp = 0; |
2808 | 2810 | ||
@@ -2818,8 +2820,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2818 | 2820 | ||
2819 | tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); | 2821 | tmp = bcma_read32(core, D11REGOFFS(clk_ctl_st)); |
2820 | if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) | 2822 | if ((tmp & CCS_ERSRC_AVAIL_HT) != CCS_ERSRC_AVAIL_HT) |
2821 | wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" | 2823 | brcms_err(core, "%s: turn on PHY PLL failed\n", |
2822 | " PLL failed\n", __func__); | 2824 | __func__); |
2823 | } else { | 2825 | } else { |
2824 | bcma_set32(core, D11REGOFFS(clk_ctl_st), | 2826 | bcma_set32(core, D11REGOFFS(clk_ctl_st), |
2825 | tmp | CCS_ERSRC_REQ_D11PLL | | 2827 | tmp | CCS_ERSRC_REQ_D11PLL | |
@@ -2835,8 +2837,8 @@ void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) | |||
2835 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) | 2837 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) |
2836 | != | 2838 | != |
2837 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) | 2839 | (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) |
2838 | wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " | 2840 | brcms_err(core, "%s: turn on PHY PLL failed\n", |
2839 | "PHY PLL failed\n", __func__); | 2841 | __func__); |
2840 | } | 2842 | } |
2841 | } else { | 2843 | } else { |
2842 | /* | 2844 | /* |
@@ -2854,7 +2856,7 @@ static void brcms_c_coredisable(struct brcms_hardware *wlc_hw) | |||
2854 | { | 2856 | { |
2855 | bool dev_gone; | 2857 | bool dev_gone; |
2856 | 2858 | ||
2857 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 2859 | brcms_dbg_info(wlc_hw->d11core, "wl%d: disable core\n", wlc_hw->unit); |
2858 | 2860 | ||
2859 | dev_gone = brcms_deviceremoved(wlc_hw->wlc); | 2861 | dev_gone = brcms_deviceremoved(wlc_hw->wlc); |
2860 | 2862 | ||
@@ -2884,12 +2886,14 @@ static void brcms_c_flushqueues(struct brcms_c_info *wlc) | |||
2884 | uint i; | 2886 | uint i; |
2885 | 2887 | ||
2886 | /* free any posted tx packets */ | 2888 | /* free any posted tx packets */ |
2887 | for (i = 0; i < NFIFO; i++) | 2889 | for (i = 0; i < NFIFO; i++) { |
2888 | if (wlc_hw->di[i]) { | 2890 | if (wlc_hw->di[i]) { |
2889 | dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); | 2891 | dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); |
2890 | wlc->core->txpktpend[i] = 0; | 2892 | if (i < TX_BCMC_FIFO) |
2891 | BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); | 2893 | ieee80211_wake_queue(wlc->pub->ieee_hw, |
2894 | brcms_fifo_to_ac(i)); | ||
2892 | } | 2895 | } |
2896 | } | ||
2893 | 2897 | ||
2894 | /* free any posted rx packets */ | 2898 | /* free any posted rx packets */ |
2895 | dma_rxreclaim(wlc_hw->di[RX_FIFO]); | 2899 | dma_rxreclaim(wlc_hw->di[RX_FIFO]); |
@@ -3109,7 +3113,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3109 | /* check for rx fifo 0 overflow */ | 3113 | /* check for rx fifo 0 overflow */ |
3110 | delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); | 3114 | delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); |
3111 | if (delta) | 3115 | if (delta) |
3112 | wiphy_err(wlc->wiphy, "wl%d: %u rx fifo 0 overflows!\n", | 3116 | brcms_err(wlc->hw->d11core, "wl%d: %u rx fifo 0 overflows!\n", |
3113 | wlc->pub->unit, delta); | 3117 | wlc->pub->unit, delta); |
3114 | 3118 | ||
3115 | /* check for tx fifo underflows */ | 3119 | /* check for tx fifo underflows */ |
@@ -3118,8 +3122,9 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3118 | (u16) (wlc->core->macstat_snapshot->txfunfl[i] - | 3122 | (u16) (wlc->core->macstat_snapshot->txfunfl[i] - |
3119 | txfunfl[i]); | 3123 | txfunfl[i]); |
3120 | if (delta) | 3124 | if (delta) |
3121 | wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" | 3125 | brcms_err(wlc->hw->d11core, |
3122 | "\n", wlc->pub->unit, delta, i); | 3126 | "wl%d: %u tx fifo %d underflows!\n", |
3127 | wlc->pub->unit, delta, i); | ||
3123 | } | 3128 | } |
3124 | #endif /* DEBUG */ | 3129 | #endif /* DEBUG */ |
3125 | 3130 | ||
@@ -3132,8 +3137,6 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) | |||
3132 | 3137 | ||
3133 | static void brcms_b_reset(struct brcms_hardware *wlc_hw) | 3138 | static void brcms_b_reset(struct brcms_hardware *wlc_hw) |
3134 | { | 3139 | { |
3135 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
3136 | |||
3137 | /* reset the core */ | 3140 | /* reset the core */ |
3138 | if (!brcms_deviceremoved(wlc_hw->wlc)) | 3141 | if (!brcms_deviceremoved(wlc_hw->wlc)) |
3139 | brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); | 3142 | brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); |
@@ -3144,7 +3147,7 @@ static void brcms_b_reset(struct brcms_hardware *wlc_hw) | |||
3144 | 3147 | ||
3145 | void brcms_c_reset(struct brcms_c_info *wlc) | 3148 | void brcms_c_reset(struct brcms_c_info *wlc) |
3146 | { | 3149 | { |
3147 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 3150 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
3148 | 3151 | ||
3149 | /* slurp up hw mac counters before core reset */ | 3152 | /* slurp up hw mac counters before core reset */ |
3150 | brcms_c_statsupd(wlc); | 3153 | brcms_c_statsupd(wlc); |
@@ -3189,10 +3192,9 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3189 | bool fifosz_fixup = false; | 3192 | bool fifosz_fixup = false; |
3190 | int err = 0; | 3193 | int err = 0; |
3191 | u16 buf[NFIFO]; | 3194 | u16 buf[NFIFO]; |
3192 | struct wiphy *wiphy = wlc->wiphy; | ||
3193 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; | 3195 | struct brcms_ucode *ucode = &wlc_hw->wlc->wl->ucode; |
3194 | 3196 | ||
3195 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | 3197 | brcms_dbg_info(core, "wl%d: core init\n", wlc_hw->unit); |
3196 | 3198 | ||
3197 | /* reset PSM */ | 3199 | /* reset PSM */ |
3198 | brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); | 3200 | brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); |
@@ -3212,7 +3214,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3212 | SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & | 3214 | SPINWAIT(((bcma_read32(core, D11REGOFFS(macintstatus)) & |
3213 | MI_MACSSPNDD) == 0), 1000 * 1000); | 3215 | MI_MACSSPNDD) == 0), 1000 * 1000); |
3214 | if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) | 3216 | if ((bcma_read32(core, D11REGOFFS(macintstatus)) & MI_MACSSPNDD) == 0) |
3215 | wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" | 3217 | brcms_err(core, "wl%d: wlc_coreinit: ucode did not self-" |
3216 | "suspend!\n", wlc_hw->unit); | 3218 | "suspend!\n", wlc_hw->unit); |
3217 | 3219 | ||
3218 | brcms_c_gpio_init(wlc); | 3220 | brcms_c_gpio_init(wlc); |
@@ -3223,18 +3225,18 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3223 | if (BRCMS_ISNPHY(wlc_hw->band)) | 3225 | if (BRCMS_ISNPHY(wlc_hw->band)) |
3224 | brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); | 3226 | brcms_c_write_inits(wlc_hw, ucode->d11n0initvals16); |
3225 | else | 3227 | else |
3226 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 3228 | brcms_err(core, "%s: wl%d: unsupported phy in corerev" |
3227 | " %d\n", __func__, wlc_hw->unit, | 3229 | " %d\n", __func__, wlc_hw->unit, |
3228 | wlc_hw->corerev); | 3230 | wlc_hw->corerev); |
3229 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { | 3231 | } else if (D11REV_IS(wlc_hw->corerev, 24)) { |
3230 | if (BRCMS_ISLCNPHY(wlc_hw->band)) | 3232 | if (BRCMS_ISLCNPHY(wlc_hw->band)) |
3231 | brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); | 3233 | brcms_c_write_inits(wlc_hw, ucode->d11lcn0initvals24); |
3232 | else | 3234 | else |
3233 | wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" | 3235 | brcms_err(core, "%s: wl%d: unsupported phy in corerev" |
3234 | " %d\n", __func__, wlc_hw->unit, | 3236 | " %d\n", __func__, wlc_hw->unit, |
3235 | wlc_hw->corerev); | 3237 | wlc_hw->corerev); |
3236 | } else { | 3238 | } else { |
3237 | wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", | 3239 | brcms_err(core, "%s: wl%d: unsupported corerev %d\n", |
3238 | __func__, wlc_hw->unit, wlc_hw->corerev); | 3240 | __func__, wlc_hw->unit, wlc_hw->corerev); |
3239 | } | 3241 | } |
3240 | 3242 | ||
@@ -3276,7 +3278,7 @@ static void brcms_b_coreinit(struct brcms_c_info *wlc) | |||
3276 | err = -1; | 3278 | err = -1; |
3277 | } | 3279 | } |
3278 | if (err != 0) | 3280 | if (err != 0) |
3279 | wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" | 3281 | brcms_err(core, "wlc_coreinit: txfifo mismatch: ucode size %d" |
3280 | " driver size %d index %d\n", buf[i], | 3282 | " driver size %d index %d\n", buf[i], |
3281 | wlc_hw->xmtfifo_sz[i], i); | 3283 | wlc_hw->xmtfifo_sz[i], i); |
3282 | 3284 | ||
@@ -3359,8 +3361,6 @@ static brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec) { | |||
3359 | bool fastclk; | 3361 | bool fastclk; |
3360 | struct brcms_c_info *wlc = wlc_hw->wlc; | 3362 | struct brcms_c_info *wlc = wlc_hw->wlc; |
3361 | 3363 | ||
3362 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
3363 | |||
3364 | /* request FAST clock if not on */ | 3364 | /* request FAST clock if not on */ |
3365 | fastclk = wlc_hw->forcefastclk; | 3365 | fastclk = wlc_hw->forcefastclk; |
3366 | if (!fastclk) | 3366 | if (!fastclk) |
@@ -3453,7 +3453,7 @@ static void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, | |||
3453 | rate = (rateset->rates[i] & BRCMS_RATE_MASK); | 3453 | rate = (rateset->rates[i] & BRCMS_RATE_MASK); |
3454 | 3454 | ||
3455 | if (rate > BRCM_MAXRATE) { | 3455 | if (rate > BRCM_MAXRATE) { |
3456 | wiphy_err(wlc->wiphy, "brcms_c_rate_lookup_init: " | 3456 | brcms_err(wlc->hw->d11core, "brcms_c_rate_lookup_init: " |
3457 | "invalid rate 0x%X in rate set\n", | 3457 | "invalid rate 0x%X in rate set\n", |
3458 | rateset->rates[i]); | 3458 | rateset->rates[i]); |
3459 | continue; | 3459 | continue; |
@@ -3529,7 +3529,6 @@ static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, | |||
3529 | uint parkband; | 3529 | uint parkband; |
3530 | uint i, band_order[2]; | 3530 | uint i, band_order[2]; |
3531 | 3531 | ||
3532 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
3533 | /* | 3532 | /* |
3534 | * We might have been bandlocked during down and the chip | 3533 | * We might have been bandlocked during down and the chip |
3535 | * power-cycled (hibernate). Figure out the right band to park on | 3534 | * power-cycled (hibernate). Figure out the right band to park on |
@@ -3710,8 +3709,8 @@ static void brcms_c_set_ratetable(struct brcms_c_info *wlc) | |||
3710 | /* band-specific init */ | 3709 | /* band-specific init */ |
3711 | static void brcms_c_bsinit(struct brcms_c_info *wlc) | 3710 | static void brcms_c_bsinit(struct brcms_c_info *wlc) |
3712 | { | 3711 | { |
3713 | BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", | 3712 | brcms_dbg_info(wlc->hw->d11core, "wl%d: bandunit %d\n", |
3714 | wlc->pub->unit, wlc->band->bandunit); | 3713 | wlc->pub->unit, wlc->band->bandunit); |
3715 | 3714 | ||
3716 | /* write ucode ACK/CTS rate table */ | 3715 | /* write ucode ACK/CTS rate table */ |
3717 | brcms_c_set_ratetable(wlc); | 3716 | brcms_c_set_ratetable(wlc); |
@@ -3734,7 +3733,8 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, | |||
3734 | isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : | 3733 | isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : |
3735 | M_TX_IDLE_BUSY_RATIO_X_16_CCK; | 3734 | M_TX_IDLE_BUSY_RATIO_X_16_CCK; |
3736 | if (duty_cycle > 100 || duty_cycle < 0) { | 3735 | if (duty_cycle > 100 || duty_cycle < 0) { |
3737 | wiphy_err(wlc->wiphy, "wl%d: duty cycle value off limit\n", | 3736 | brcms_err(wlc->hw->d11core, |
3737 | "wl%d: duty cycle value off limit\n", | ||
3738 | wlc->pub->unit); | 3738 | wlc->pub->unit); |
3739 | return -EINVAL; | 3739 | return -EINVAL; |
3740 | } | 3740 | } |
@@ -3752,40 +3752,6 @@ brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, | |||
3752 | return 0; | 3752 | return 0; |
3753 | } | 3753 | } |
3754 | 3754 | ||
3755 | /* | ||
3756 | * Initialize the base precedence map for dequeueing | ||
3757 | * from txq based on WME settings | ||
3758 | */ | ||
3759 | static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) | ||
3760 | { | ||
3761 | wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; | ||
3762 | memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); | ||
3763 | |||
3764 | wlc->fifo2prec_map[TX_AC_BK_FIFO] = BRCMS_PREC_BMP_AC_BK; | ||
3765 | wlc->fifo2prec_map[TX_AC_BE_FIFO] = BRCMS_PREC_BMP_AC_BE; | ||
3766 | wlc->fifo2prec_map[TX_AC_VI_FIFO] = BRCMS_PREC_BMP_AC_VI; | ||
3767 | wlc->fifo2prec_map[TX_AC_VO_FIFO] = BRCMS_PREC_BMP_AC_VO; | ||
3768 | } | ||
3769 | |||
3770 | static void | ||
3771 | brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, | ||
3772 | struct brcms_txq_info *qi, bool on, int prio) | ||
3773 | { | ||
3774 | /* transmit flowcontrol is not yet implemented */ | ||
3775 | } | ||
3776 | |||
3777 | static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc) | ||
3778 | { | ||
3779 | struct brcms_txq_info *qi; | ||
3780 | |||
3781 | for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { | ||
3782 | if (qi->stopped) { | ||
3783 | brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); | ||
3784 | qi->stopped = 0; | ||
3785 | } | ||
3786 | } | ||
3787 | } | ||
3788 | |||
3789 | /* push sw hps and wake state through hardware */ | 3755 | /* push sw hps and wake state through hardware */ |
3790 | static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) | 3756 | static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) |
3791 | { | 3757 | { |
@@ -3795,7 +3761,8 @@ static void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc) | |||
3795 | 3761 | ||
3796 | hps = brcms_c_ps_allowed(wlc); | 3762 | hps = brcms_c_ps_allowed(wlc); |
3797 | 3763 | ||
3798 | BCMMSG(wlc->wiphy, "wl%d: hps %d\n", wlc->pub->unit, hps); | 3764 | brcms_dbg_mac80211(wlc->hw->d11core, "wl%d: hps %d\n", wlc->pub->unit, |
3765 | hps); | ||
3799 | 3766 | ||
3800 | v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); | 3767 | v1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(maccontrol)); |
3801 | v2 = MCTL_WAKE; | 3768 | v2 = MCTL_WAKE; |
@@ -3881,7 +3848,8 @@ brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, | |||
3881 | { | 3848 | { |
3882 | uint bandunit; | 3849 | uint bandunit; |
3883 | 3850 | ||
3884 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); | 3851 | brcms_dbg_mac80211(wlc_hw->d11core, "wl%d: 0x%x\n", wlc_hw->unit, |
3852 | chanspec); | ||
3885 | 3853 | ||
3886 | wlc_hw->chanspec = chanspec; | 3854 | wlc_hw->chanspec = chanspec; |
3887 | 3855 | ||
@@ -3942,7 +3910,7 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3942 | u16 old_chanspec = wlc->chanspec; | 3910 | u16 old_chanspec = wlc->chanspec; |
3943 | 3911 | ||
3944 | if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { | 3912 | if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { |
3945 | wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", | 3913 | brcms_err(wlc->hw->d11core, "wl%d: %s: Bad channel %d\n", |
3946 | wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); | 3914 | wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); |
3947 | return; | 3915 | return; |
3948 | } | 3916 | } |
@@ -3953,8 +3921,8 @@ static void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) | |||
3953 | if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { | 3921 | if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { |
3954 | switchband = true; | 3922 | switchband = true; |
3955 | if (wlc->bandlocked) { | 3923 | if (wlc->bandlocked) { |
3956 | wiphy_err(wlc->wiphy, "wl%d: %s: chspec %d " | 3924 | brcms_err(wlc->hw->d11core, |
3957 | "band is locked!\n", | 3925 | "wl%d: %s: chspec %d band is locked!\n", |
3958 | wlc->pub->unit, __func__, | 3926 | wlc->pub->unit, __func__, |
3959 | CHSPEC_CHANNEL(chanspec)); | 3927 | CHSPEC_CHANNEL(chanspec)); |
3960 | return; | 3928 | return; |
@@ -4018,6 +3986,10 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, | |||
4018 | */ | 3986 | */ |
4019 | void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) | 3987 | void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) |
4020 | { | 3988 | { |
3989 | /* | ||
3990 | * Cannot use brcms_dbg_* here because this function is called | ||
3991 | * before wlc is sufficiently initialized. | ||
3992 | */ | ||
4021 | BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); | 3993 | BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); |
4022 | 3994 | ||
4023 | switch (idx) { | 3995 | switch (idx) { |
@@ -4090,8 +4062,8 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4090 | 4062 | ||
4091 | /* Only apply params if the core is out of reset and has clocks */ | 4063 | /* Only apply params if the core is out of reset and has clocks */ |
4092 | if (!wlc->clk) { | 4064 | if (!wlc->clk) { |
4093 | wiphy_err(wlc->wiphy, "wl%d: %s : no-clock\n", wlc->pub->unit, | 4065 | brcms_err(wlc->hw->d11core, "wl%d: %s : no-clock\n", |
4094 | __func__); | 4066 | wlc->pub->unit, __func__); |
4095 | return; | 4067 | return; |
4096 | } | 4068 | } |
4097 | 4069 | ||
@@ -4109,7 +4081,7 @@ void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, | |||
4109 | 4081 | ||
4110 | if (acp_shm.aifs < EDCF_AIFSN_MIN | 4082 | if (acp_shm.aifs < EDCF_AIFSN_MIN |
4111 | || acp_shm.aifs > EDCF_AIFSN_MAX) { | 4083 | || acp_shm.aifs > EDCF_AIFSN_MAX) { |
4112 | wiphy_err(wlc->wiphy, "wl%d: edcf_setparams: bad " | 4084 | brcms_err(wlc->hw->d11core, "wl%d: edcf_setparams: bad " |
4113 | "aifs %d\n", wlc->pub->unit, acp_shm.aifs); | 4085 | "aifs %d\n", wlc->pub->unit, acp_shm.aifs); |
4114 | } else { | 4086 | } else { |
4115 | acp_shm.cwmin = params->cw_min; | 4087 | acp_shm.cwmin = params->cw_min; |
@@ -4224,8 +4196,8 @@ static void brcms_c_radio_timer(void *arg) | |||
4224 | struct brcms_c_info *wlc = (struct brcms_c_info *) arg; | 4196 | struct brcms_c_info *wlc = (struct brcms_c_info *) arg; |
4225 | 4197 | ||
4226 | if (brcms_deviceremoved(wlc)) { | 4198 | if (brcms_deviceremoved(wlc)) { |
4227 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, | 4199 | brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", |
4228 | __func__); | 4200 | wlc->pub->unit, __func__); |
4229 | brcms_down(wlc->wl); | 4201 | brcms_down(wlc->wl); |
4230 | return; | 4202 | return; |
4231 | } | 4203 | } |
@@ -4238,8 +4210,6 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) | |||
4238 | { | 4210 | { |
4239 | struct brcms_hardware *wlc_hw = wlc->hw; | 4211 | struct brcms_hardware *wlc_hw = wlc->hw; |
4240 | 4212 | ||
4241 | BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
4242 | |||
4243 | if (!wlc_hw->up) | 4213 | if (!wlc_hw->up) |
4244 | return; | 4214 | return; |
4245 | 4215 | ||
@@ -4258,14 +4228,14 @@ static void brcms_b_watchdog(struct brcms_c_info *wlc) | |||
4258 | /* common watchdog code */ | 4228 | /* common watchdog code */ |
4259 | static void brcms_c_watchdog(struct brcms_c_info *wlc) | 4229 | static void brcms_c_watchdog(struct brcms_c_info *wlc) |
4260 | { | 4230 | { |
4261 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 4231 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
4262 | 4232 | ||
4263 | if (!wlc->pub->up) | 4233 | if (!wlc->pub->up) |
4264 | return; | 4234 | return; |
4265 | 4235 | ||
4266 | if (brcms_deviceremoved(wlc)) { | 4236 | if (brcms_deviceremoved(wlc)) { |
4267 | wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", wlc->pub->unit, | 4237 | brcms_err(wlc->hw->d11core, "wl%d: %s: dead chip\n", |
4268 | __func__); | 4238 | wlc->pub->unit, __func__); |
4269 | brcms_down(wlc->wl); | 4239 | brcms_down(wlc->wl); |
4270 | return; | 4240 | return; |
4271 | } | 4241 | } |
@@ -4437,13 +4407,13 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, | |||
4437 | struct ssb_sprom *sprom = &core->bus->sprom; | 4407 | struct ssb_sprom *sprom = &core->bus->sprom; |
4438 | 4408 | ||
4439 | if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) | 4409 | if (core->bus->hosttype == BCMA_HOSTTYPE_PCI) |
4440 | BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, | 4410 | brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, |
4441 | pcidev->vendor, | 4411 | pcidev->vendor, |
4442 | pcidev->device); | 4412 | pcidev->device); |
4443 | else | 4413 | else |
4444 | BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, | 4414 | brcms_dbg_info(core, "wl%d: vendor 0x%x device 0x%x\n", unit, |
4445 | core->bus->boardinfo.vendor, | 4415 | core->bus->boardinfo.vendor, |
4446 | core->bus->boardinfo.type); | 4416 | core->bus->boardinfo.type); |
4447 | 4417 | ||
4448 | wme = true; | 4418 | wme = true; |
4449 | 4419 | ||
@@ -4715,8 +4685,9 @@ static int brcms_b_attach(struct brcms_c_info *wlc, struct bcma_device *core, | |||
4715 | goto fail; | 4685 | goto fail; |
4716 | } | 4686 | } |
4717 | 4687 | ||
4718 | BCMMSG(wlc->wiphy, "deviceid 0x%x nbands %d board 0x%x\n", | 4688 | brcms_dbg_info(wlc_hw->d11core, "deviceid 0x%x nbands %d board 0x%x\n", |
4719 | wlc_hw->deviceid, wlc_hw->_nbands, ai_get_boardtype(wlc_hw->sih)); | 4689 | wlc_hw->deviceid, wlc_hw->_nbands, |
4690 | ai_get_boardtype(wlc_hw->sih)); | ||
4720 | 4691 | ||
4721 | return err; | 4692 | return err; |
4722 | 4693 | ||
@@ -4836,56 +4807,6 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc) | |||
4836 | bi->flags |= BRCMS_BSS_HT; | 4807 | bi->flags |= BRCMS_BSS_HT; |
4837 | } | 4808 | } |
4838 | 4809 | ||
4839 | static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) | ||
4840 | { | ||
4841 | struct brcms_txq_info *qi, *p; | ||
4842 | |||
4843 | qi = kzalloc(sizeof(struct brcms_txq_info), GFP_ATOMIC); | ||
4844 | if (qi != NULL) { | ||
4845 | /* | ||
4846 | * Have enough room for control packets along with HI watermark | ||
4847 | * Also, add room to txq for total psq packets if all the SCBs | ||
4848 | * leave PS mode. The watermark for flowcontrol to OS packets | ||
4849 | * will remain the same | ||
4850 | */ | ||
4851 | brcmu_pktq_init(&qi->q, BRCMS_PREC_COUNT, | ||
4852 | 2 * BRCMS_DATAHIWAT + PKTQ_LEN_DEFAULT); | ||
4853 | |||
4854 | /* add this queue to the the global list */ | ||
4855 | p = wlc->tx_queues; | ||
4856 | if (p == NULL) { | ||
4857 | wlc->tx_queues = qi; | ||
4858 | } else { | ||
4859 | while (p->next != NULL) | ||
4860 | p = p->next; | ||
4861 | p->next = qi; | ||
4862 | } | ||
4863 | } | ||
4864 | return qi; | ||
4865 | } | ||
4866 | |||
4867 | static void brcms_c_txq_free(struct brcms_c_info *wlc, | ||
4868 | struct brcms_txq_info *qi) | ||
4869 | { | ||
4870 | struct brcms_txq_info *p; | ||
4871 | |||
4872 | if (qi == NULL) | ||
4873 | return; | ||
4874 | |||
4875 | /* remove the queue from the linked list */ | ||
4876 | p = wlc->tx_queues; | ||
4877 | if (p == qi) | ||
4878 | wlc->tx_queues = p->next; | ||
4879 | else { | ||
4880 | while (p != NULL && p->next != qi) | ||
4881 | p = p->next; | ||
4882 | if (p != NULL) | ||
4883 | p->next = p->next->next; | ||
4884 | } | ||
4885 | |||
4886 | kfree(qi); | ||
4887 | } | ||
4888 | |||
4889 | static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) | 4810 | static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) |
4890 | { | 4811 | { |
4891 | uint i; | 4812 | uint i; |
@@ -4991,8 +4912,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc) | |||
4991 | if (wlc == NULL) | 4912 | if (wlc == NULL) |
4992 | return 0; | 4913 | return 0; |
4993 | 4914 | ||
4994 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
4995 | |||
4996 | callbacks += brcms_b_detach(wlc); | 4915 | callbacks += brcms_b_detach(wlc); |
4997 | 4916 | ||
4998 | /* delete software timers */ | 4917 | /* delete software timers */ |
@@ -5005,10 +4924,6 @@ uint brcms_c_detach(struct brcms_c_info *wlc) | |||
5005 | 4924 | ||
5006 | brcms_c_detach_module(wlc); | 4925 | brcms_c_detach_module(wlc); |
5007 | 4926 | ||
5008 | |||
5009 | while (wlc->tx_queues != NULL) | ||
5010 | brcms_c_txq_free(wlc, wlc->tx_queues); | ||
5011 | |||
5012 | brcms_c_detach_mfree(wlc); | 4927 | brcms_c_detach_mfree(wlc); |
5013 | return callbacks; | 4928 | return callbacks; |
5014 | } | 4929 | } |
@@ -5026,7 +4941,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) | |||
5026 | if (wlc_hw->wlc->pub->hw_up) | 4941 | if (wlc_hw->wlc->pub->hw_up) |
5027 | return; | 4942 | return; |
5028 | 4943 | ||
5029 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 4944 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
5030 | 4945 | ||
5031 | /* | 4946 | /* |
5032 | * Enable pll and xtal, initialize the power control registers, | 4947 | * Enable pll and xtal, initialize the power control registers, |
@@ -5063,7 +4978,7 @@ static void brcms_b_hw_up(struct brcms_hardware *wlc_hw) | |||
5063 | 4978 | ||
5064 | static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) | 4979 | static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) |
5065 | { | 4980 | { |
5066 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | 4981 | brcms_dbg_info(wlc_hw->d11core, "wl%d\n", wlc_hw->unit); |
5067 | 4982 | ||
5068 | /* | 4983 | /* |
5069 | * Enable pll and xtal, initialize the power control registers, | 4984 | * Enable pll and xtal, initialize the power control registers, |
@@ -5102,8 +5017,6 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw) | |||
5102 | 5017 | ||
5103 | static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) | 5018 | static int brcms_b_up_finish(struct brcms_hardware *wlc_hw) |
5104 | { | 5019 | { |
5105 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5106 | |||
5107 | wlc_hw->up = true; | 5020 | wlc_hw->up = true; |
5108 | wlc_phy_hw_state_upd(wlc_hw->band->pi, true); | 5021 | wlc_phy_hw_state_upd(wlc_hw->band->pi, true); |
5109 | 5022 | ||
@@ -5135,7 +5048,7 @@ int brcms_c_up(struct brcms_c_info *wlc) | |||
5135 | { | 5048 | { |
5136 | struct ieee80211_channel *ch; | 5049 | struct ieee80211_channel *ch; |
5137 | 5050 | ||
5138 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 5051 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
5139 | 5052 | ||
5140 | /* HW is turned off so don't try to access it */ | 5053 | /* HW is turned off so don't try to access it */ |
5141 | if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) | 5054 | if (wlc->pub->hw_off || brcms_deviceremoved(wlc)) |
@@ -5176,8 +5089,8 @@ int brcms_c_up(struct brcms_c_info *wlc) | |||
5176 | WL_RADIO_HW_DISABLE); | 5089 | WL_RADIO_HW_DISABLE); |
5177 | 5090 | ||
5178 | if (bsscfg->enable && bsscfg->BSS) | 5091 | if (bsscfg->enable && bsscfg->BSS) |
5179 | wiphy_err(wlc->wiphy, "wl%d: up" | 5092 | brcms_err(wlc->hw->d11core, |
5180 | ": rfdisable -> " | 5093 | "wl%d: up: rfdisable -> " |
5181 | "bsscfg_disable()\n", | 5094 | "bsscfg_disable()\n", |
5182 | wlc->pub->unit); | 5095 | wlc->pub->unit); |
5183 | } | 5096 | } |
@@ -5237,8 +5150,6 @@ static int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) | |||
5237 | bool dev_gone; | 5150 | bool dev_gone; |
5238 | uint callbacks = 0; | 5151 | uint callbacks = 0; |
5239 | 5152 | ||
5240 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5241 | |||
5242 | if (!wlc_hw->up) | 5153 | if (!wlc_hw->up) |
5243 | return callbacks; | 5154 | return callbacks; |
5244 | 5155 | ||
@@ -5265,8 +5176,6 @@ static int brcms_b_down_finish(struct brcms_hardware *wlc_hw) | |||
5265 | uint callbacks = 0; | 5176 | uint callbacks = 0; |
5266 | bool dev_gone; | 5177 | bool dev_gone; |
5267 | 5178 | ||
5268 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
5269 | |||
5270 | if (!wlc_hw->up) | 5179 | if (!wlc_hw->up) |
5271 | return callbacks; | 5180 | return callbacks; |
5272 | 5181 | ||
@@ -5314,14 +5223,14 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5314 | uint callbacks = 0; | 5223 | uint callbacks = 0; |
5315 | int i; | 5224 | int i; |
5316 | bool dev_gone = false; | 5225 | bool dev_gone = false; |
5317 | struct brcms_txq_info *qi; | ||
5318 | 5226 | ||
5319 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 5227 | brcms_dbg_info(wlc->hw->d11core, "wl%d\n", wlc->pub->unit); |
5320 | 5228 | ||
5321 | /* check if we are already in the going down path */ | 5229 | /* check if we are already in the going down path */ |
5322 | if (wlc->going_down) { | 5230 | if (wlc->going_down) { |
5323 | wiphy_err(wlc->wiphy, "wl%d: %s: Driver going down so return" | 5231 | brcms_err(wlc->hw->d11core, |
5324 | "\n", wlc->pub->unit, __func__); | 5232 | "wl%d: %s: Driver going down so return\n", |
5233 | wlc->pub->unit, __func__); | ||
5325 | return 0; | 5234 | return 0; |
5326 | } | 5235 | } |
5327 | if (!wlc->pub->up) | 5236 | if (!wlc->pub->up) |
@@ -5353,13 +5262,6 @@ uint brcms_c_down(struct brcms_c_info *wlc) | |||
5353 | 5262 | ||
5354 | wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); | 5263 | wlc_phy_mute_upd(wlc->band->pi, false, PHY_MUTE_ALL); |
5355 | 5264 | ||
5356 | /* clear txq flow control */ | ||
5357 | brcms_c_txflowcontrol_reset(wlc); | ||
5358 | |||
5359 | /* flush tx queues */ | ||
5360 | for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) | ||
5361 | brcmu_pktq_flush(&qi->q, true, NULL, NULL); | ||
5362 | |||
5363 | callbacks += brcms_b_down_finish(wlc->hw); | 5265 | callbacks += brcms_b_down_finish(wlc->hw); |
5364 | 5266 | ||
5365 | /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ | 5267 | /* brcms_b_down_finish has done brcms_c_coredisable(). so clk is off */ |
@@ -5441,7 +5343,7 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) | |||
5441 | 5343 | ||
5442 | default: | 5344 | default: |
5443 | /* Error */ | 5345 | /* Error */ |
5444 | wiphy_err(wlc->wiphy, "wl%d: %s: invalid gmode %d\n", | 5346 | brcms_err(wlc->hw->d11core, "wl%d: %s: invalid gmode %d\n", |
5445 | wlc->pub->unit, __func__, gmode); | 5347 | wlc->pub->unit, __func__, gmode); |
5446 | return -ENOTSUPP; | 5348 | return -ENOTSUPP; |
5447 | } | 5349 | } |
@@ -5745,45 +5647,6 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, | |||
5745 | return -ENODATA; | 5647 | return -ENODATA; |
5746 | } | 5648 | } |
5747 | 5649 | ||
5748 | void brcms_c_print_txstatus(struct tx_status *txs) | ||
5749 | { | ||
5750 | pr_debug("\ntxpkt (MPDU) Complete\n"); | ||
5751 | |||
5752 | pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); | ||
5753 | |||
5754 | pr_debug("[15:12] %d frame attempts\n", | ||
5755 | (txs->status & TX_STATUS_FRM_RTX_MASK) >> | ||
5756 | TX_STATUS_FRM_RTX_SHIFT); | ||
5757 | pr_debug(" [11:8] %d rts attempts\n", | ||
5758 | (txs->status & TX_STATUS_RTS_RTX_MASK) >> | ||
5759 | TX_STATUS_RTS_RTX_SHIFT); | ||
5760 | pr_debug(" [7] %d PM mode indicated\n", | ||
5761 | txs->status & TX_STATUS_PMINDCTD ? 1 : 0); | ||
5762 | pr_debug(" [6] %d intermediate status\n", | ||
5763 | txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); | ||
5764 | pr_debug(" [5] %d AMPDU\n", | ||
5765 | txs->status & TX_STATUS_AMPDU ? 1 : 0); | ||
5766 | pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", | ||
5767 | (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, | ||
5768 | (const char *[]) { | ||
5769 | "None", | ||
5770 | "PMQ Entry", | ||
5771 | "Flush request", | ||
5772 | "Previous frag failure", | ||
5773 | "Channel mismatch", | ||
5774 | "Lifetime Expiry", | ||
5775 | "Underflow" | ||
5776 | } [(txs->status & TX_STATUS_SUPR_MASK) >> | ||
5777 | TX_STATUS_SUPR_SHIFT]); | ||
5778 | pr_debug(" [1] %d acked\n", | ||
5779 | txs->status & TX_STATUS_ACK_RCV ? 1 : 0); | ||
5780 | |||
5781 | pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", | ||
5782 | txs->lasttxtime, txs->sequence, txs->phyerr, | ||
5783 | (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, | ||
5784 | (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); | ||
5785 | } | ||
5786 | |||
5787 | static bool brcms_c_chipmatch_pci(struct bcma_device *core) | 5650 | static bool brcms_c_chipmatch_pci(struct bcma_device *core) |
5788 | { | 5651 | { |
5789 | struct pci_dev *pcidev = core->bus->host_pci; | 5652 | struct pci_dev *pcidev = core->bus->host_pci; |
@@ -5832,184 +5695,6 @@ bool brcms_c_chipmatch(struct bcma_device *core) | |||
5832 | } | 5695 | } |
5833 | } | 5696 | } |
5834 | 5697 | ||
5835 | #if defined(DEBUG) | ||
5836 | void brcms_c_print_txdesc(struct d11txh *txh) | ||
5837 | { | ||
5838 | u16 mtcl = le16_to_cpu(txh->MacTxControlLow); | ||
5839 | u16 mtch = le16_to_cpu(txh->MacTxControlHigh); | ||
5840 | u16 mfc = le16_to_cpu(txh->MacFrameControl); | ||
5841 | u16 tfest = le16_to_cpu(txh->TxFesTimeNormal); | ||
5842 | u16 ptcw = le16_to_cpu(txh->PhyTxControlWord); | ||
5843 | u16 ptcw_1 = le16_to_cpu(txh->PhyTxControlWord_1); | ||
5844 | u16 ptcw_1_Fbr = le16_to_cpu(txh->PhyTxControlWord_1_Fbr); | ||
5845 | u16 ptcw_1_Rts = le16_to_cpu(txh->PhyTxControlWord_1_Rts); | ||
5846 | u16 ptcw_1_FbrRts = le16_to_cpu(txh->PhyTxControlWord_1_FbrRts); | ||
5847 | u16 mainrates = le16_to_cpu(txh->MainRates); | ||
5848 | u16 xtraft = le16_to_cpu(txh->XtraFrameTypes); | ||
5849 | u8 *iv = txh->IV; | ||
5850 | u8 *ra = txh->TxFrameRA; | ||
5851 | u16 tfestfb = le16_to_cpu(txh->TxFesTimeFallback); | ||
5852 | u8 *rtspfb = txh->RTSPLCPFallback; | ||
5853 | u16 rtsdfb = le16_to_cpu(txh->RTSDurFallback); | ||
5854 | u8 *fragpfb = txh->FragPLCPFallback; | ||
5855 | u16 fragdfb = le16_to_cpu(txh->FragDurFallback); | ||
5856 | u16 mmodelen = le16_to_cpu(txh->MModeLen); | ||
5857 | u16 mmodefbrlen = le16_to_cpu(txh->MModeFbrLen); | ||
5858 | u16 tfid = le16_to_cpu(txh->TxFrameID); | ||
5859 | u16 txs = le16_to_cpu(txh->TxStatus); | ||
5860 | u16 mnmpdu = le16_to_cpu(txh->MaxNMpdus); | ||
5861 | u16 mabyte = le16_to_cpu(txh->MaxABytes_MRT); | ||
5862 | u16 mabyte_f = le16_to_cpu(txh->MaxABytes_FBR); | ||
5863 | u16 mmbyte = le16_to_cpu(txh->MinMBytes); | ||
5864 | |||
5865 | u8 *rtsph = txh->RTSPhyHeader; | ||
5866 | struct ieee80211_rts rts = txh->rts_frame; | ||
5867 | |||
5868 | /* add plcp header along with txh descriptor */ | ||
5869 | brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, | ||
5870 | "Raw TxDesc + plcp header:\n"); | ||
5871 | |||
5872 | pr_debug("TxCtlLow: %04x ", mtcl); | ||
5873 | pr_debug("TxCtlHigh: %04x ", mtch); | ||
5874 | pr_debug("FC: %04x ", mfc); | ||
5875 | pr_debug("FES Time: %04x\n", tfest); | ||
5876 | pr_debug("PhyCtl: %04x%s ", ptcw, | ||
5877 | (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); | ||
5878 | pr_debug("PhyCtl_1: %04x ", ptcw_1); | ||
5879 | pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); | ||
5880 | pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); | ||
5881 | pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); | ||
5882 | pr_debug("MainRates: %04x ", mainrates); | ||
5883 | pr_debug("XtraFrameTypes: %04x ", xtraft); | ||
5884 | pr_debug("\n"); | ||
5885 | |||
5886 | print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); | ||
5887 | print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, | ||
5888 | ra, sizeof(txh->TxFrameRA)); | ||
5889 | |||
5890 | pr_debug("Fb FES Time: %04x ", tfestfb); | ||
5891 | print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, | ||
5892 | rtspfb, sizeof(txh->RTSPLCPFallback)); | ||
5893 | pr_debug("RTS DUR: %04x ", rtsdfb); | ||
5894 | print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, | ||
5895 | fragpfb, sizeof(txh->FragPLCPFallback)); | ||
5896 | pr_debug("DUR: %04x", fragdfb); | ||
5897 | pr_debug("\n"); | ||
5898 | |||
5899 | pr_debug("MModeLen: %04x ", mmodelen); | ||
5900 | pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); | ||
5901 | |||
5902 | pr_debug("FrameID: %04x\n", tfid); | ||
5903 | pr_debug("TxStatus: %04x\n", txs); | ||
5904 | |||
5905 | pr_debug("MaxNumMpdu: %04x\n", mnmpdu); | ||
5906 | pr_debug("MaxAggbyte: %04x\n", mabyte); | ||
5907 | pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); | ||
5908 | pr_debug("MinByte: %04x\n", mmbyte); | ||
5909 | |||
5910 | print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, | ||
5911 | rtsph, sizeof(txh->RTSPhyHeader)); | ||
5912 | print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, | ||
5913 | (u8 *)&rts, sizeof(txh->rts_frame)); | ||
5914 | pr_debug("\n"); | ||
5915 | } | ||
5916 | #endif /* defined(DEBUG) */ | ||
5917 | |||
5918 | #if defined(DEBUG) | ||
5919 | static int | ||
5920 | brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, | ||
5921 | int len) | ||
5922 | { | ||
5923 | int i; | ||
5924 | char *p = buf; | ||
5925 | char hexstr[16]; | ||
5926 | int slen = 0, nlen = 0; | ||
5927 | u32 bit; | ||
5928 | const char *name; | ||
5929 | |||
5930 | if (len < 2 || !buf) | ||
5931 | return 0; | ||
5932 | |||
5933 | buf[0] = '\0'; | ||
5934 | |||
5935 | for (i = 0; flags != 0; i++) { | ||
5936 | bit = bd[i].bit; | ||
5937 | name = bd[i].name; | ||
5938 | if (bit == 0 && flags != 0) { | ||
5939 | /* print any unnamed bits */ | ||
5940 | snprintf(hexstr, 16, "0x%X", flags); | ||
5941 | name = hexstr; | ||
5942 | flags = 0; /* exit loop */ | ||
5943 | } else if ((flags & bit) == 0) | ||
5944 | continue; | ||
5945 | flags &= ~bit; | ||
5946 | nlen = strlen(name); | ||
5947 | slen += nlen; | ||
5948 | /* count btwn flag space */ | ||
5949 | if (flags != 0) | ||
5950 | slen += 1; | ||
5951 | /* need NULL char as well */ | ||
5952 | if (len <= slen) | ||
5953 | break; | ||
5954 | /* copy NULL char but don't count it */ | ||
5955 | strncpy(p, name, nlen + 1); | ||
5956 | p += nlen; | ||
5957 | /* copy btwn flag space and NULL char */ | ||
5958 | if (flags != 0) | ||
5959 | p += snprintf(p, 2, " "); | ||
5960 | len -= slen; | ||
5961 | } | ||
5962 | |||
5963 | /* indicate the str was too short */ | ||
5964 | if (flags != 0) { | ||
5965 | if (len < 2) | ||
5966 | p -= 2 - len; /* overwrite last char */ | ||
5967 | p += snprintf(p, 2, ">"); | ||
5968 | } | ||
5969 | |||
5970 | return (int)(p - buf); | ||
5971 | } | ||
5972 | #endif /* defined(DEBUG) */ | ||
5973 | |||
5974 | #if defined(DEBUG) | ||
5975 | void brcms_c_print_rxh(struct d11rxhdr *rxh) | ||
5976 | { | ||
5977 | u16 len = rxh->RxFrameSize; | ||
5978 | u16 phystatus_0 = rxh->PhyRxStatus_0; | ||
5979 | u16 phystatus_1 = rxh->PhyRxStatus_1; | ||
5980 | u16 phystatus_2 = rxh->PhyRxStatus_2; | ||
5981 | u16 phystatus_3 = rxh->PhyRxStatus_3; | ||
5982 | u16 macstatus1 = rxh->RxStatus1; | ||
5983 | u16 macstatus2 = rxh->RxStatus2; | ||
5984 | char flagstr[64]; | ||
5985 | char lenbuf[20]; | ||
5986 | static const struct brcms_c_bit_desc macstat_flags[] = { | ||
5987 | {RXS_FCSERR, "FCSErr"}, | ||
5988 | {RXS_RESPFRAMETX, "Reply"}, | ||
5989 | {RXS_PBPRES, "PADDING"}, | ||
5990 | {RXS_DECATMPT, "DeCr"}, | ||
5991 | {RXS_DECERR, "DeCrErr"}, | ||
5992 | {RXS_BCNSENT, "Bcn"}, | ||
5993 | {0, NULL} | ||
5994 | }; | ||
5995 | |||
5996 | brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); | ||
5997 | |||
5998 | brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); | ||
5999 | |||
6000 | snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); | ||
6001 | |||
6002 | pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, | ||
6003 | (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); | ||
6004 | pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", | ||
6005 | phystatus_0, phystatus_1, phystatus_2, phystatus_3); | ||
6006 | pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); | ||
6007 | pr_debug("RXMACaggtype: %x\n", | ||
6008 | (macstatus2 & RXS_AGGTYPE_MASK)); | ||
6009 | pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); | ||
6010 | } | ||
6011 | #endif /* defined(DEBUG) */ | ||
6012 | |||
6013 | u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) | 5698 | u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) |
6014 | { | 5699 | { |
6015 | u16 table_ptr; | 5700 | u16 table_ptr; |
@@ -6033,86 +5718,6 @@ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) | |||
6033 | return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); | 5718 | return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); |
6034 | } | 5719 | } |
6035 | 5720 | ||
6036 | static bool | ||
6037 | brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, | ||
6038 | struct sk_buff *pkt, int prec, bool head) | ||
6039 | { | ||
6040 | struct sk_buff *p; | ||
6041 | int eprec = -1; /* precedence to evict from */ | ||
6042 | |||
6043 | /* Determine precedence from which to evict packet, if any */ | ||
6044 | if (pktq_pfull(q, prec)) | ||
6045 | eprec = prec; | ||
6046 | else if (pktq_full(q)) { | ||
6047 | p = brcmu_pktq_peek_tail(q, &eprec); | ||
6048 | if (eprec > prec) { | ||
6049 | wiphy_err(wlc->wiphy, "%s: Failing: eprec %d > prec %d" | ||
6050 | "\n", __func__, eprec, prec); | ||
6051 | return false; | ||
6052 | } | ||
6053 | } | ||
6054 | |||
6055 | /* Evict if needed */ | ||
6056 | if (eprec >= 0) { | ||
6057 | bool discard_oldest; | ||
6058 | |||
6059 | discard_oldest = ac_bitmap_tst(0, eprec); | ||
6060 | |||
6061 | /* Refuse newer packet unless configured to discard oldest */ | ||
6062 | if (eprec == prec && !discard_oldest) { | ||
6063 | wiphy_err(wlc->wiphy, "%s: No where to go, prec == %d" | ||
6064 | "\n", __func__, prec); | ||
6065 | return false; | ||
6066 | } | ||
6067 | |||
6068 | /* Evict packet according to discard policy */ | ||
6069 | p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : | ||
6070 | brcmu_pktq_pdeq_tail(q, eprec); | ||
6071 | brcmu_pkt_buf_free_skb(p); | ||
6072 | } | ||
6073 | |||
6074 | /* Enqueue */ | ||
6075 | if (head) | ||
6076 | p = brcmu_pktq_penq_head(q, prec, pkt); | ||
6077 | else | ||
6078 | p = brcmu_pktq_penq(q, prec, pkt); | ||
6079 | |||
6080 | return true; | ||
6081 | } | ||
6082 | |||
6083 | /* | ||
6084 | * Attempts to queue a packet onto a multiple-precedence queue, | ||
6085 | * if necessary evicting a lower precedence packet from the queue. | ||
6086 | * | ||
6087 | * 'prec' is the precedence number that has already been mapped | ||
6088 | * from the packet priority. | ||
6089 | * | ||
6090 | * Returns true if packet consumed (queued), false if not. | ||
6091 | */ | ||
6092 | static bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, | ||
6093 | struct sk_buff *pkt, int prec) | ||
6094 | { | ||
6095 | return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); | ||
6096 | } | ||
6097 | |||
6098 | void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, | ||
6099 | struct sk_buff *sdu, uint prec) | ||
6100 | { | ||
6101 | struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ | ||
6102 | struct pktq *q = &qi->q; | ||
6103 | int prio; | ||
6104 | |||
6105 | prio = sdu->priority; | ||
6106 | |||
6107 | if (!brcms_c_prec_enq(wlc, q, sdu, prec)) { | ||
6108 | /* | ||
6109 | * we might hit this condtion in case | ||
6110 | * packet flooding from mac80211 stack | ||
6111 | */ | ||
6112 | brcmu_pkt_buf_free_skb(sdu); | ||
6113 | } | ||
6114 | } | ||
6115 | |||
6116 | /* | 5721 | /* |
6117 | * bcmc_fid_generate: | 5722 | * bcmc_fid_generate: |
6118 | * Generate frame ID for a BCMC packet. The frag field is not used | 5723 | * Generate frame ID for a BCMC packet. The frag field is not used |
@@ -6140,8 +5745,6 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, | |||
6140 | { | 5745 | { |
6141 | uint dur = 0; | 5746 | uint dur = 0; |
6142 | 5747 | ||
6143 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", | ||
6144 | wlc->pub->unit, rspec, preamble_type); | ||
6145 | /* | 5748 | /* |
6146 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that | 5749 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that |
6147 | * is less than or equal to the rate of the immediately previous | 5750 | * is less than or equal to the rate of the immediately previous |
@@ -6159,8 +5762,6 @@ static uint | |||
6159 | brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, | 5762 | brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, |
6160 | u8 preamble_type) | 5763 | u8 preamble_type) |
6161 | { | 5764 | { |
6162 | BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", | ||
6163 | wlc->pub->unit, rspec, preamble_type); | ||
6164 | return brcms_c_calc_ack_time(wlc, rspec, preamble_type); | 5765 | return brcms_c_calc_ack_time(wlc, rspec, preamble_type); |
6165 | } | 5766 | } |
6166 | 5767 | ||
@@ -6168,8 +5769,6 @@ static uint | |||
6168 | brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, | 5769 | brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, |
6169 | u8 preamble_type) | 5770 | u8 preamble_type) |
6170 | { | 5771 | { |
6171 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " | ||
6172 | "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); | ||
6173 | /* | 5772 | /* |
6174 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that | 5773 | * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that |
6175 | * is less than or equal to the rate of the immediately previous | 5774 | * is less than or equal to the rate of the immediately previous |
@@ -6223,9 +5822,6 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, | |||
6223 | uint nsyms, mac_len, Ndps, kNdps; | 5822 | uint nsyms, mac_len, Ndps, kNdps; |
6224 | uint rate = rspec2rate(ratespec); | 5823 | uint rate = rspec2rate(ratespec); |
6225 | 5824 | ||
6226 | BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d, dur %d\n", | ||
6227 | wlc->pub->unit, ratespec, preamble_type, dur); | ||
6228 | |||
6229 | if (is_mcs_rate(ratespec)) { | 5825 | if (is_mcs_rate(ratespec)) { |
6230 | uint mcs = ratespec & RSPEC_RATE_MASK; | 5826 | uint mcs = ratespec & RSPEC_RATE_MASK; |
6231 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); | 5827 | int tot_streams = mcs_2_txstreams(mcs) + rspec_stc(ratespec); |
@@ -6292,7 +5888,7 @@ static bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, | |||
6292 | return true; | 5888 | return true; |
6293 | error: | 5889 | error: |
6294 | if (verbose) | 5890 | if (verbose) |
6295 | wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " | 5891 | brcms_err(wlc->hw->d11core, "wl%d: valid_rate: rate spec 0x%x " |
6296 | "not in hw_rateset\n", wlc->pub->unit, rspec); | 5892 | "not in hw_rateset\n", wlc->pub->unit, rspec); |
6297 | 5893 | ||
6298 | return false; | 5894 | return false; |
@@ -6302,6 +5898,7 @@ static u32 | |||
6302 | mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | 5898 | mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, |
6303 | u32 int_val) | 5899 | u32 int_val) |
6304 | { | 5900 | { |
5901 | struct bcma_device *core = wlc->hw->d11core; | ||
6305 | u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; | 5902 | u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; |
6306 | u8 rate = int_val & NRATE_RATE_MASK; | 5903 | u8 rate = int_val & NRATE_RATE_MASK; |
6307 | u32 rspec; | 5904 | u32 rspec; |
@@ -6318,7 +5915,7 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6318 | if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { | 5915 | if ((wlc->pub->_n_enab & SUPPORT_11N) && ismcs) { |
6319 | /* mcs only allowed when nmode */ | 5916 | /* mcs only allowed when nmode */ |
6320 | if (stf > PHY_TXC1_MODE_SDM) { | 5917 | if (stf > PHY_TXC1_MODE_SDM) { |
6321 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid stf\n", | 5918 | brcms_err(core, "wl%d: %s: Invalid stf\n", |
6322 | wlc->pub->unit, __func__); | 5919 | wlc->pub->unit, __func__); |
6323 | bcmerror = -EINVAL; | 5920 | bcmerror = -EINVAL; |
6324 | goto done; | 5921 | goto done; |
@@ -6329,8 +5926,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6329 | if (!CHSPEC_IS40(wlc->home_chanspec) || | 5926 | if (!CHSPEC_IS40(wlc->home_chanspec) || |
6330 | ((stf != PHY_TXC1_MODE_SISO) | 5927 | ((stf != PHY_TXC1_MODE_SISO) |
6331 | && (stf != PHY_TXC1_MODE_CDD))) { | 5928 | && (stf != PHY_TXC1_MODE_CDD))) { |
6332 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid mcs " | 5929 | brcms_err(core, "wl%d: %s: Invalid mcs 32\n", |
6333 | "32\n", wlc->pub->unit, __func__); | 5930 | wlc->pub->unit, __func__); |
6334 | bcmerror = -EINVAL; | 5931 | bcmerror = -EINVAL; |
6335 | goto done; | 5932 | goto done; |
6336 | } | 5933 | } |
@@ -6338,9 +5935,9 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6338 | } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { | 5935 | } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { |
6339 | /* mcs > 7 must use stf SDM */ | 5936 | /* mcs > 7 must use stf SDM */ |
6340 | if (stf != PHY_TXC1_MODE_SDM) { | 5937 | if (stf != PHY_TXC1_MODE_SDM) { |
6341 | BCMMSG(wlc->wiphy, "wl%d: enabling " | 5938 | brcms_dbg_mac80211(core, "wl%d: enabling " |
6342 | "SDM mode for mcs %d\n", | 5939 | "SDM mode for mcs %d\n", |
6343 | wlc->pub->unit, rate); | 5940 | wlc->pub->unit, rate); |
6344 | stf = PHY_TXC1_MODE_SDM; | 5941 | stf = PHY_TXC1_MODE_SDM; |
6345 | } | 5942 | } |
6346 | } else { | 5943 | } else { |
@@ -6351,15 +5948,15 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6351 | if ((stf > PHY_TXC1_MODE_STBC) || | 5948 | if ((stf > PHY_TXC1_MODE_STBC) || |
6352 | (!BRCMS_STBC_CAP_PHY(wlc) | 5949 | (!BRCMS_STBC_CAP_PHY(wlc) |
6353 | && (stf == PHY_TXC1_MODE_STBC))) { | 5950 | && (stf == PHY_TXC1_MODE_STBC))) { |
6354 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid STBC" | 5951 | brcms_err(core, "wl%d: %s: Invalid STBC\n", |
6355 | "\n", wlc->pub->unit, __func__); | 5952 | wlc->pub->unit, __func__); |
6356 | bcmerror = -EINVAL; | 5953 | bcmerror = -EINVAL; |
6357 | goto done; | 5954 | goto done; |
6358 | } | 5955 | } |
6359 | } | 5956 | } |
6360 | } else if (is_ofdm_rate(rate)) { | 5957 | } else if (is_ofdm_rate(rate)) { |
6361 | if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { | 5958 | if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { |
6362 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid OFDM\n", | 5959 | brcms_err(core, "wl%d: %s: Invalid OFDM\n", |
6363 | wlc->pub->unit, __func__); | 5960 | wlc->pub->unit, __func__); |
6364 | bcmerror = -EINVAL; | 5961 | bcmerror = -EINVAL; |
6365 | goto done; | 5962 | goto done; |
@@ -6367,20 +5964,20 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, | |||
6367 | } else if (is_cck_rate(rate)) { | 5964 | } else if (is_cck_rate(rate)) { |
6368 | if ((cur_band->bandtype != BRCM_BAND_2G) | 5965 | if ((cur_band->bandtype != BRCM_BAND_2G) |
6369 | || (stf != PHY_TXC1_MODE_SISO)) { | 5966 | || (stf != PHY_TXC1_MODE_SISO)) { |
6370 | wiphy_err(wlc->wiphy, "wl%d: %s: Invalid CCK\n", | 5967 | brcms_err(core, "wl%d: %s: Invalid CCK\n", |
6371 | wlc->pub->unit, __func__); | 5968 | wlc->pub->unit, __func__); |
6372 | bcmerror = -EINVAL; | 5969 | bcmerror = -EINVAL; |
6373 | goto done; | 5970 | goto done; |
6374 | } | 5971 | } |
6375 | } else { | 5972 | } else { |
6376 | wiphy_err(wlc->wiphy, "wl%d: %s: Unknown rate type\n", | 5973 | brcms_err(core, "wl%d: %s: Unknown rate type\n", |
6377 | wlc->pub->unit, __func__); | 5974 | wlc->pub->unit, __func__); |
6378 | bcmerror = -EINVAL; | 5975 | bcmerror = -EINVAL; |
6379 | goto done; | 5976 | goto done; |
6380 | } | 5977 | } |
6381 | /* make sure multiple antennae are available for non-siso rates */ | 5978 | /* make sure multiple antennae are available for non-siso rates */ |
6382 | if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { | 5979 | if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { |
6383 | wiphy_err(wlc->wiphy, "wl%d: %s: SISO antenna but !SISO " | 5980 | brcms_err(core, "wl%d: %s: SISO antenna but !SISO " |
6384 | "request\n", wlc->pub->unit, __func__); | 5981 | "request\n", wlc->pub->unit, __func__); |
6385 | bcmerror = -EINVAL; | 5982 | bcmerror = -EINVAL; |
6386 | goto done; | 5983 | goto done; |
@@ -6449,7 +6046,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, | |||
6449 | break; | 6046 | break; |
6450 | 6047 | ||
6451 | default: | 6048 | default: |
6452 | wiphy_err(wlc->wiphy, | 6049 | brcms_err(wlc->hw->d11core, |
6453 | "brcms_c_cck_plcp_set: unsupported rate %d\n", | 6050 | "brcms_c_cck_plcp_set: unsupported rate %d\n", |
6454 | rate_500); | 6051 | rate_500); |
6455 | rate_500 = BRCM_RATE_1M; | 6052 | rate_500 = BRCM_RATE_1M; |
@@ -6582,7 +6179,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) | |||
6582 | bw = rspec_get_bw(rspec); | 6179 | bw = rspec_get_bw(rspec); |
6583 | /* 10Mhz is not supported yet */ | 6180 | /* 10Mhz is not supported yet */ |
6584 | if (bw < PHY_TXC1_BW_20MHZ) { | 6181 | if (bw < PHY_TXC1_BW_20MHZ) { |
6585 | wiphy_err(wlc->wiphy, "phytxctl1_calc: bw %d is " | 6182 | brcms_err(wlc->hw->d11core, "phytxctl1_calc: bw %d is " |
6586 | "not supported yet, set to 20L\n", bw); | 6183 | "not supported yet, set to 20L\n", bw); |
6587 | bw = PHY_TXC1_BW_20MHZ; | 6184 | bw = PHY_TXC1_BW_20MHZ; |
6588 | } | 6185 | } |
@@ -6609,7 +6206,7 @@ static u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) | |||
6609 | /* get the phyctl byte from rate phycfg table */ | 6206 | /* get the phyctl byte from rate phycfg table */ |
6610 | phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); | 6207 | phycfg = brcms_c_rate_legacy_phyctl(rspec2rate(rspec)); |
6611 | if (phycfg == -1) { | 6208 | if (phycfg == -1) { |
6612 | wiphy_err(wlc->wiphy, "phytxctl1_calc: wrong " | 6209 | brcms_err(wlc->hw->d11core, "phytxctl1_calc: wrong " |
6613 | "legacy OFDM/CCK rate\n"); | 6210 | "legacy OFDM/CCK rate\n"); |
6614 | phycfg = 0; | 6211 | phycfg = 0; |
6615 | } | 6212 | } |
@@ -6689,8 +6286,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6689 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 6286 | if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
6690 | /* non-AP STA should never use BCMC queue */ | 6287 | /* non-AP STA should never use BCMC queue */ |
6691 | if (queue == TX_BCMC_FIFO) { | 6288 | if (queue == TX_BCMC_FIFO) { |
6692 | wiphy_err(wlc->wiphy, "wl%d: %s: ASSERT queue == " | 6289 | brcms_err(wlc->hw->d11core, |
6693 | "TX_BCMC!\n", wlc->pub->unit, __func__); | 6290 | "wl%d: %s: ASSERT queue == TX_BCMC!\n", |
6291 | wlc->pub->unit, __func__); | ||
6694 | frameid = bcmc_fid_generate(wlc, NULL, txh); | 6292 | frameid = bcmc_fid_generate(wlc, NULL, txh); |
6695 | } else { | 6293 | } else { |
6696 | /* Increment the counter for first fragment */ | 6294 | /* Increment the counter for first fragment */ |
@@ -6860,7 +6458,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
6860 | 6458 | ||
6861 | if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) | 6459 | if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) |
6862 | && (!is_mcs_rate(rspec[k]))) { | 6460 | && (!is_mcs_rate(rspec[k]))) { |
6863 | wiphy_err(wlc->wiphy, "wl%d: %s: IEEE80211_TX_" | 6461 | brcms_err(wlc->hw->d11core, |
6462 | "wl%d: %s: IEEE80211_TX_" | ||
6864 | "RC_MCS != is_mcs_rate(rspec)\n", | 6463 | "RC_MCS != is_mcs_rate(rspec)\n", |
6865 | wlc->pub->unit, __func__); | 6464 | wlc->pub->unit, __func__); |
6866 | } | 6465 | } |
@@ -7254,14 +6853,16 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
7254 | wlc->fragthresh[queue] = | 6853 | wlc->fragthresh[queue] = |
7255 | (u16) newfragthresh; | 6854 | (u16) newfragthresh; |
7256 | } else { | 6855 | } else { |
7257 | wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " | 6856 | brcms_err(wlc->hw->d11core, |
6857 | "wl%d: %s txop invalid " | ||
7258 | "for rate %d\n", | 6858 | "for rate %d\n", |
7259 | wlc->pub->unit, fifo_names[queue], | 6859 | wlc->pub->unit, fifo_names[queue], |
7260 | rspec2rate(rspec[0])); | 6860 | rspec2rate(rspec[0])); |
7261 | } | 6861 | } |
7262 | 6862 | ||
7263 | if (dur > wlc->edcf_txop[ac]) | 6863 | if (dur > wlc->edcf_txop[ac]) |
7264 | wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " | 6864 | brcms_err(wlc->hw->d11core, |
6865 | "wl%d: %s: %s txop " | ||
7265 | "exceeded phylen %d/%d dur %d/%d\n", | 6866 | "exceeded phylen %d/%d dur %d/%d\n", |
7266 | wlc->pub->unit, __func__, | 6867 | wlc->pub->unit, __func__, |
7267 | fifo_names[queue], | 6868 | fifo_names[queue], |
@@ -7273,79 +6874,33 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, | |||
7273 | return 0; | 6874 | return 0; |
7274 | } | 6875 | } |
7275 | 6876 | ||
7276 | void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, | 6877 | static int brcms_c_tx(struct brcms_c_info *wlc, struct sk_buff *skb) |
7277 | struct ieee80211_hw *hw) | ||
7278 | { | 6878 | { |
7279 | u8 prio; | 6879 | struct dma_pub *dma; |
7280 | uint fifo; | 6880 | int fifo, ret = -ENOSPC; |
7281 | struct scb *scb = &wlc->pri_scb; | 6881 | struct d11txh *txh; |
7282 | struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); | 6882 | u16 frameid = INVALIDFID; |
7283 | |||
7284 | /* | ||
7285 | * 802.11 standard requires management traffic | ||
7286 | * to go at highest priority | ||
7287 | */ | ||
7288 | prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : | ||
7289 | MAXPRIO; | ||
7290 | fifo = prio2fifo[prio]; | ||
7291 | if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) | ||
7292 | return; | ||
7293 | brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); | ||
7294 | brcms_c_send_q(wlc); | ||
7295 | } | ||
7296 | |||
7297 | void brcms_c_send_q(struct brcms_c_info *wlc) | ||
7298 | { | ||
7299 | struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; | ||
7300 | int prec; | ||
7301 | u16 prec_map; | ||
7302 | int err = 0, i, count; | ||
7303 | uint fifo; | ||
7304 | struct brcms_txq_info *qi = wlc->pkt_queue; | ||
7305 | struct pktq *q = &qi->q; | ||
7306 | struct ieee80211_tx_info *tx_info; | ||
7307 | |||
7308 | prec_map = wlc->tx_prec_map; | ||
7309 | 6883 | ||
7310 | /* Send all the enq'd pkts that we can. | 6884 | fifo = brcms_ac_to_fifo(skb_get_queue_mapping(skb)); |
7311 | * Dequeue packets with precedence with empty HW fifo only | 6885 | dma = wlc->hw->di[fifo]; |
7312 | */ | 6886 | txh = (struct d11txh *)(skb->data); |
7313 | while (prec_map && (pkt[0] = brcmu_pktq_mdeq(q, prec_map, &prec))) { | ||
7314 | tx_info = IEEE80211_SKB_CB(pkt[0]); | ||
7315 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
7316 | err = brcms_c_sendampdu(wlc->ampdu, qi, pkt, prec); | ||
7317 | } else { | ||
7318 | count = 1; | ||
7319 | err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); | ||
7320 | if (!err) { | ||
7321 | for (i = 0; i < count; i++) | ||
7322 | brcms_c_txfifo(wlc, fifo, pkt[i], true, | ||
7323 | 1); | ||
7324 | } | ||
7325 | } | ||
7326 | 6887 | ||
7327 | if (err == -EBUSY) { | 6888 | if (dma->txavail == 0) { |
7328 | brcmu_pktq_penq_head(q, prec, pkt[0]); | 6889 | /* |
7329 | /* | 6890 | * We sometimes get a frame from mac80211 after stopping |
7330 | * If send failed due to any other reason than a | 6891 | * the queues. This only ever seems to be a single frame |
7331 | * change in HW FIFO condition, quit. Otherwise, | 6892 | * and is seems likely to be a race. TX_HEADROOM should |
7332 | * read the new prec_map! | 6893 | * ensure that we have enough space to handle these stray |
7333 | */ | 6894 | * packets, so warn if there isn't. If we're out of space |
7334 | if (prec_map == wlc->tx_prec_map) | 6895 | * in the tx ring and the tx queue isn't stopped then |
7335 | break; | 6896 | * we've really got a bug; warn loudly if that happens. |
7336 | prec_map = wlc->tx_prec_map; | 6897 | */ |
7337 | } | 6898 | brcms_warn(wlc->hw->d11core, |
6899 | "Received frame for tx with no space in DMA ring\n"); | ||
6900 | WARN_ON(!ieee80211_queue_stopped(wlc->pub->ieee_hw, | ||
6901 | skb_get_queue_mapping(skb))); | ||
6902 | return -ENOSPC; | ||
7338 | } | 6903 | } |
7339 | } | ||
7340 | |||
7341 | void | ||
7342 | brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | ||
7343 | bool commit, s8 txpktpend) | ||
7344 | { | ||
7345 | u16 frameid = INVALIDFID; | ||
7346 | struct d11txh *txh; | ||
7347 | |||
7348 | txh = (struct d11txh *) (p->data); | ||
7349 | 6904 | ||
7350 | /* When a BC/MC frame is being committed to the BCMC fifo | 6905 | /* When a BC/MC frame is being committed to the BCMC fifo |
7351 | * via DMA (NOT PIO), update ucode or BSS info as appropriate. | 6906 | * via DMA (NOT PIO), update ucode or BSS info as appropriate. |
@@ -7353,16 +6908,6 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | |||
7353 | if (fifo == TX_BCMC_FIFO) | 6908 | if (fifo == TX_BCMC_FIFO) |
7354 | frameid = le16_to_cpu(txh->TxFrameID); | 6909 | frameid = le16_to_cpu(txh->TxFrameID); |
7355 | 6910 | ||
7356 | /* | ||
7357 | * Bump up pending count for if not using rpc. If rpc is | ||
7358 | * used, this will be handled in brcms_b_txfifo() | ||
7359 | */ | ||
7360 | if (commit) { | ||
7361 | wlc->core->txpktpend[fifo] += txpktpend; | ||
7362 | BCMMSG(wlc->wiphy, "pktpend inc %d to %d\n", | ||
7363 | txpktpend, wlc->core->txpktpend[fifo]); | ||
7364 | } | ||
7365 | |||
7366 | /* Commit BCMC sequence number in the SHM frame ID location */ | 6911 | /* Commit BCMC sequence number in the SHM frame ID location */ |
7367 | if (frameid != INVALIDFID) { | 6912 | if (frameid != INVALIDFID) { |
7368 | /* | 6913 | /* |
@@ -7372,8 +6917,52 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, | |||
7372 | brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); | 6917 | brcms_b_write_shm(wlc->hw, M_BCMC_FID, frameid); |
7373 | } | 6918 | } |
7374 | 6919 | ||
7375 | if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) | 6920 | ret = brcms_c_txfifo(wlc, fifo, skb); |
6921 | /* | ||
6922 | * The only reason for brcms_c_txfifo to fail is because | ||
6923 | * there weren't any DMA descriptors, but we've already | ||
6924 | * checked for that. So if it does fail yell loudly. | ||
6925 | */ | ||
6926 | WARN_ON_ONCE(ret); | ||
6927 | |||
6928 | return ret; | ||
6929 | } | ||
6930 | |||
6931 | void brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, | ||
6932 | struct ieee80211_hw *hw) | ||
6933 | { | ||
6934 | uint fifo; | ||
6935 | struct scb *scb = &wlc->pri_scb; | ||
6936 | |||
6937 | fifo = brcms_ac_to_fifo(skb_get_queue_mapping(sdu)); | ||
6938 | if (brcms_c_d11hdrs_mac80211(wlc, hw, sdu, scb, 0, 1, fifo, 0)) | ||
6939 | return; | ||
6940 | if (brcms_c_tx(wlc, sdu)) | ||
6941 | dev_kfree_skb_any(sdu); | ||
6942 | } | ||
6943 | |||
6944 | int | ||
6945 | brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p) | ||
6946 | { | ||
6947 | struct dma_pub *dma = wlc->hw->di[fifo]; | ||
6948 | int ret; | ||
6949 | u16 queue; | ||
6950 | |||
6951 | ret = dma_txfast(wlc, dma, p); | ||
6952 | if (ret < 0) | ||
7376 | wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); | 6953 | wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); |
6954 | |||
6955 | /* | ||
6956 | * Stop queue if DMA ring is full. Reserve some free descriptors, | ||
6957 | * as we sometimes receive a frame from mac80211 after the queues | ||
6958 | * are stopped. | ||
6959 | */ | ||
6960 | queue = skb_get_queue_mapping(p); | ||
6961 | if (dma->txavail <= TX_HEADROOM && fifo < TX_BCMC_FIFO && | ||
6962 | !ieee80211_queue_stopped(wlc->pub->ieee_hw, queue)) | ||
6963 | ieee80211_stop_queue(wlc->pub->ieee_hw, queue); | ||
6964 | |||
6965 | return ret; | ||
7377 | } | 6966 | } |
7378 | 6967 | ||
7379 | u32 | 6968 | u32 |
@@ -7423,19 +7012,6 @@ brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, | |||
7423 | return rts_rspec; | 7012 | return rts_rspec; |
7424 | } | 7013 | } |
7425 | 7014 | ||
7426 | void | ||
7427 | brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) | ||
7428 | { | ||
7429 | wlc->core->txpktpend[fifo] -= txpktpend; | ||
7430 | BCMMSG(wlc->wiphy, "pktpend dec %d to %d\n", txpktpend, | ||
7431 | wlc->core->txpktpend[fifo]); | ||
7432 | |||
7433 | /* There is more room; mark precedences related to this FIFO sendable */ | ||
7434 | wlc->tx_prec_map |= wlc->fifo2prec_map[fifo]; | ||
7435 | |||
7436 | /* figure out which bsscfg is being worked on... */ | ||
7437 | } | ||
7438 | |||
7439 | /* Update beacon listen interval in shared memory */ | 7015 | /* Update beacon listen interval in shared memory */ |
7440 | static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) | 7016 | static void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) |
7441 | { | 7017 | { |
@@ -7508,7 +7084,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7508 | 7084 | ||
7509 | /* fill in TSF and flag its presence */ | 7085 | /* fill in TSF and flag its presence */ |
7510 | rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); | 7086 | rx_status->mactime = brcms_c_recover_tsf64(wlc, rxh); |
7511 | rx_status->flag |= RX_FLAG_MACTIME_MPDU; | 7087 | rx_status->flag |= RX_FLAG_MACTIME_START; |
7512 | 7088 | ||
7513 | channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); | 7089 | channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); |
7514 | 7090 | ||
@@ -7571,7 +7147,8 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7571 | rx_status->rate_idx = 11; | 7147 | rx_status->rate_idx = 11; |
7572 | break; | 7148 | break; |
7573 | default: | 7149 | default: |
7574 | wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); | 7150 | brcms_err(wlc->hw->d11core, |
7151 | "%s: Unknown rate\n", __func__); | ||
7575 | } | 7152 | } |
7576 | 7153 | ||
7577 | /* | 7154 | /* |
@@ -7590,7 +7167,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7590 | } else if (is_ofdm_rate(rspec)) { | 7167 | } else if (is_ofdm_rate(rspec)) { |
7591 | rx_status->flag |= RX_FLAG_SHORTPRE; | 7168 | rx_status->flag |= RX_FLAG_SHORTPRE; |
7592 | } else { | 7169 | } else { |
7593 | wiphy_err(wlc->wiphy, "%s: Unknown modulation\n", | 7170 | brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n", |
7594 | __func__); | 7171 | __func__); |
7595 | } | 7172 | } |
7596 | } | 7173 | } |
@@ -7600,12 +7177,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, | |||
7600 | 7177 | ||
7601 | if (rxh->RxStatus1 & RXS_DECERR) { | 7178 | if (rxh->RxStatus1 & RXS_DECERR) { |
7602 | rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; | 7179 | rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; |
7603 | wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_PLCP_CRC\n", | 7180 | brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_PLCP_CRC\n", |
7604 | __func__); | 7181 | __func__); |
7605 | } | 7182 | } |
7606 | if (rxh->RxStatus1 & RXS_FCSERR) { | 7183 | if (rxh->RxStatus1 & RXS_FCSERR) { |
7607 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | 7184 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; |
7608 | wiphy_err(wlc->wiphy, "%s: RX_FLAG_FAILED_FCS_CRC\n", | 7185 | brcms_err(wlc->hw->d11core, "%s: RX_FLAG_FAILED_FCS_CRC\n", |
7609 | __func__); | 7186 | __func__); |
7610 | } | 7187 | } |
7611 | } | 7188 | } |
@@ -7649,9 +7226,6 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, | |||
7649 | { | 7226 | { |
7650 | uint nsyms, len = 0, kNdps; | 7227 | uint nsyms, len = 0, kNdps; |
7651 | 7228 | ||
7652 | BCMMSG(wlc->wiphy, "wl%d: rate %d, len%d\n", | ||
7653 | wlc->pub->unit, rspec2rate(ratespec), mac_len); | ||
7654 | |||
7655 | if (is_mcs_rate(ratespec)) { | 7229 | if (is_mcs_rate(ratespec)) { |
7656 | uint mcs = ratespec & RSPEC_RATE_MASK; | 7230 | uint mcs = ratespec & RSPEC_RATE_MASK; |
7657 | int tot_streams = (mcs_2_txstreams(mcs) + 1) + | 7231 | int tot_streams = (mcs_2_txstreams(mcs) + 1) + |
@@ -7883,35 +7457,6 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) | |||
7883 | brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); | 7457 | brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); |
7884 | } | 7458 | } |
7885 | 7459 | ||
7886 | /* prepares pdu for transmission. returns BCM error codes */ | ||
7887 | int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifop) | ||
7888 | { | ||
7889 | uint fifo; | ||
7890 | struct d11txh *txh; | ||
7891 | struct ieee80211_hdr *h; | ||
7892 | struct scb *scb; | ||
7893 | |||
7894 | txh = (struct d11txh *) (pdu->data); | ||
7895 | h = (struct ieee80211_hdr *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); | ||
7896 | |||
7897 | /* get the pkt queue info. This was put at brcms_c_sendctl or | ||
7898 | * brcms_c_send for PDU */ | ||
7899 | fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK; | ||
7900 | |||
7901 | scb = NULL; | ||
7902 | |||
7903 | *fifop = fifo; | ||
7904 | |||
7905 | /* return if insufficient dma resources */ | ||
7906 | if (*wlc->core->txavail[fifo] < MAX_DMA_SEGS) { | ||
7907 | /* Mark precedences related to this FIFO, unsendable */ | ||
7908 | /* A fifo is full. Clear precedences related to that FIFO */ | ||
7909 | wlc->tx_prec_map &= ~(wlc->fifo2prec_map[fifo]); | ||
7910 | return -EBUSY; | ||
7911 | } | ||
7912 | return 0; | ||
7913 | } | ||
7914 | |||
7915 | int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, | 7460 | int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, |
7916 | uint *blocks) | 7461 | uint *blocks) |
7917 | { | 7462 | { |
@@ -7977,13 +7522,15 @@ int brcms_c_get_curband(struct brcms_c_info *wlc) | |||
7977 | void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) | 7522 | void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) |
7978 | { | 7523 | { |
7979 | int timeout = 20; | 7524 | int timeout = 20; |
7525 | int i; | ||
7980 | 7526 | ||
7981 | /* flush packet queue when requested */ | 7527 | /* Kick DMA to send any pending AMPDU */ |
7982 | if (drop) | 7528 | for (i = 0; i < ARRAY_SIZE(wlc->hw->di); i++) |
7983 | brcmu_pktq_flush(&wlc->pkt_queue->q, false, NULL, NULL); | 7529 | if (wlc->hw->di[i]) |
7530 | dma_txflush(wlc->hw->di[i]); | ||
7984 | 7531 | ||
7985 | /* wait for queue and DMA fifos to run dry */ | 7532 | /* wait for queue and DMA fifos to run dry */ |
7986 | while (!pktq_empty(&wlc->pkt_queue->q) || brcms_txpktpendtot(wlc) > 0) { | 7533 | while (brcms_txpktpendtot(wlc) > 0) { |
7987 | brcms_msleep(wlc->wl, 1); | 7534 | brcms_msleep(wlc->wl, 1); |
7988 | 7535 | ||
7989 | if (--timeout == 0) | 7536 | if (--timeout == 0) |
@@ -8032,8 +7579,6 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) | |||
8032 | uint len; | 7579 | uint len; |
8033 | bool is_amsdu; | 7580 | bool is_amsdu; |
8034 | 7581 | ||
8035 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | ||
8036 | |||
8037 | /* frame starts with rxhdr */ | 7582 | /* frame starts with rxhdr */ |
8038 | rxh = (struct d11rxhdr *) (p->data); | 7583 | rxh = (struct d11rxhdr *) (p->data); |
8039 | 7584 | ||
@@ -8043,8 +7588,9 @@ static void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) | |||
8043 | /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ | 7588 | /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ |
8044 | if (rxh->RxStatus1 & RXS_PBPRES) { | 7589 | if (rxh->RxStatus1 & RXS_PBPRES) { |
8045 | if (p->len < 2) { | 7590 | if (p->len < 2) { |
8046 | wiphy_err(wlc->wiphy, "wl%d: recv: rcvd runt of " | 7591 | brcms_err(wlc->hw->d11core, |
8047 | "len %d\n", wlc->pub->unit, p->len); | 7592 | "wl%d: recv: rcvd runt of len %d\n", |
7593 | wlc->pub->unit, p->len); | ||
8048 | goto toss; | 7594 | goto toss; |
8049 | } | 7595 | } |
8050 | skb_pull(p, 2); | 7596 | skb_pull(p, 2); |
@@ -8089,7 +7635,6 @@ brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) | |||
8089 | uint n = 0; | 7635 | uint n = 0; |
8090 | uint bound_limit = bound ? RXBND : -1; | 7636 | uint bound_limit = bound ? RXBND : -1; |
8091 | 7637 | ||
8092 | BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); | ||
8093 | skb_queue_head_init(&recv_frames); | 7638 | skb_queue_head_init(&recv_frames); |
8094 | 7639 | ||
8095 | /* gather received frames */ | 7640 | /* gather received frames */ |
@@ -8140,10 +7685,9 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8140 | u32 macintstatus; | 7685 | u32 macintstatus; |
8141 | struct brcms_hardware *wlc_hw = wlc->hw; | 7686 | struct brcms_hardware *wlc_hw = wlc->hw; |
8142 | struct bcma_device *core = wlc_hw->d11core; | 7687 | struct bcma_device *core = wlc_hw->d11core; |
8143 | struct wiphy *wiphy = wlc->wiphy; | ||
8144 | 7688 | ||
8145 | if (brcms_deviceremoved(wlc)) { | 7689 | if (brcms_deviceremoved(wlc)) { |
8146 | wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, | 7690 | brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, |
8147 | __func__); | 7691 | __func__); |
8148 | brcms_down(wlc->wl); | 7692 | brcms_down(wlc->wl); |
8149 | return false; | 7693 | return false; |
@@ -8153,8 +7697,8 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8153 | macintstatus = wlc->macintstatus; | 7697 | macintstatus = wlc->macintstatus; |
8154 | wlc->macintstatus = 0; | 7698 | wlc->macintstatus = 0; |
8155 | 7699 | ||
8156 | BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", | 7700 | brcms_dbg_int(core, "wl%d: macintstatus 0x%x\n", |
8157 | wlc_hw->unit, macintstatus); | 7701 | wlc_hw->unit, macintstatus); |
8158 | 7702 | ||
8159 | WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ | 7703 | WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ |
8160 | 7704 | ||
@@ -8164,7 +7708,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8164 | if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) | 7708 | if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) |
8165 | wlc->macintstatus |= MI_TFS; | 7709 | wlc->macintstatus |= MI_TFS; |
8166 | if (fatal) { | 7710 | if (fatal) { |
8167 | wiphy_err(wiphy, "MI_TFS: fatal\n"); | 7711 | brcms_err(core, "MI_TFS: fatal\n"); |
8168 | goto fatal; | 7712 | goto fatal; |
8169 | } | 7713 | } |
8170 | } | 7714 | } |
@@ -8174,7 +7718,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8174 | 7718 | ||
8175 | /* ATIM window end */ | 7719 | /* ATIM window end */ |
8176 | if (macintstatus & MI_ATIMWINEND) { | 7720 | if (macintstatus & MI_ATIMWINEND) { |
8177 | BCMMSG(wlc->wiphy, "end of ATIM window\n"); | 7721 | brcms_dbg_info(core, "end of ATIM window\n"); |
8178 | bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); | 7722 | bcma_set32(core, D11REGOFFS(maccommand), wlc->qvalid); |
8179 | wlc->qvalid = 0; | 7723 | wlc->qvalid = 0; |
8180 | } | 7724 | } |
@@ -8192,7 +7736,7 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8192 | wlc_phy_noise_sample_intr(wlc_hw->band->pi); | 7736 | wlc_phy_noise_sample_intr(wlc_hw->band->pi); |
8193 | 7737 | ||
8194 | if (macintstatus & MI_GP0) { | 7738 | if (macintstatus & MI_GP0) { |
8195 | wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " | 7739 | brcms_err(core, "wl%d: PSM microcode watchdog fired at %d " |
8196 | "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); | 7740 | "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); |
8197 | 7741 | ||
8198 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", | 7742 | printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", |
@@ -8206,15 +7750,11 @@ bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) | |||
8206 | bcma_write32(core, D11REGOFFS(gptimer), 0); | 7750 | bcma_write32(core, D11REGOFFS(gptimer), 0); |
8207 | 7751 | ||
8208 | if (macintstatus & MI_RFDISABLE) { | 7752 | if (macintstatus & MI_RFDISABLE) { |
8209 | BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" | 7753 | brcms_dbg_info(core, "wl%d: BMAC Detected a change on the" |
8210 | " RF Disable Input\n", wlc_hw->unit); | 7754 | " RF Disable Input\n", wlc_hw->unit); |
8211 | brcms_rfkill_set_hw_state(wlc->wl); | 7755 | brcms_rfkill_set_hw_state(wlc->wl); |
8212 | } | 7756 | } |
8213 | 7757 | ||
8214 | /* send any enq'd tx packets. Just makes sure to jump start tx */ | ||
8215 | if (!pktq_empty(&wlc->pkt_queue->q)) | ||
8216 | brcms_c_send_q(wlc); | ||
8217 | |||
8218 | /* it isn't done and needs to be resched if macintstatus is non-zero */ | 7758 | /* it isn't done and needs to be resched if macintstatus is non-zero */ |
8219 | return wlc->macintstatus != 0; | 7759 | return wlc->macintstatus != 0; |
8220 | 7760 | ||
@@ -8229,7 +7769,7 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8229 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; | 7769 | struct ieee80211_channel *ch = wlc->pub->ieee_hw->conf.channel; |
8230 | u16 chanspec; | 7770 | u16 chanspec; |
8231 | 7771 | ||
8232 | BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); | 7772 | brcms_dbg_info(core, "wl%d\n", wlc->pub->unit); |
8233 | 7773 | ||
8234 | chanspec = ch20mhz_chspec(ch->hw_value); | 7774 | chanspec = ch20mhz_chspec(ch->hw_value); |
8235 | 7775 | ||
@@ -8286,9 +7826,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8286 | bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); | 7826 | bcma_set16(core, D11REGOFFS(ifs_ctl), IFS_USEEDCF); |
8287 | brcms_c_edcf_setparams(wlc, false); | 7827 | brcms_c_edcf_setparams(wlc, false); |
8288 | 7828 | ||
8289 | /* Init precedence maps for empty FIFOs */ | ||
8290 | brcms_c_tx_prec_map_init(wlc); | ||
8291 | |||
8292 | /* read the ucode version if we have not yet done so */ | 7829 | /* read the ucode version if we have not yet done so */ |
8293 | if (wlc->ucode_rev == 0) { | 7830 | if (wlc->ucode_rev == 0) { |
8294 | wlc->ucode_rev = | 7831 | wlc->ucode_rev = |
@@ -8303,9 +7840,6 @@ void brcms_c_init(struct brcms_c_info *wlc, bool mute_tx) | |||
8303 | if (mute_tx) | 7840 | if (mute_tx) |
8304 | brcms_b_mute(wlc->hw, true); | 7841 | brcms_b_mute(wlc->hw, true); |
8305 | 7842 | ||
8306 | /* clear tx flow control */ | ||
8307 | brcms_c_txflowcontrol_reset(wlc); | ||
8308 | |||
8309 | /* enable the RF Disable Delay timer */ | 7843 | /* enable the RF Disable Delay timer */ |
8310 | bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); | 7844 | bcma_write32(core, D11REGOFFS(rfdisabledly), RFDISABLE_DEFAULT); |
8311 | 7845 | ||
@@ -8464,15 +7998,6 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, | |||
8464 | * Complete the wlc default state initializations.. | 7998 | * Complete the wlc default state initializations.. |
8465 | */ | 7999 | */ |
8466 | 8000 | ||
8467 | /* allocate our initial queue */ | ||
8468 | wlc->pkt_queue = brcms_c_txq_alloc(wlc); | ||
8469 | if (wlc->pkt_queue == NULL) { | ||
8470 | wiphy_err(wl->wiphy, "wl%d: %s: failed to malloc tx queue\n", | ||
8471 | unit, __func__); | ||
8472 | err = 100; | ||
8473 | goto fail; | ||
8474 | } | ||
8475 | |||
8476 | wlc->bsscfg->wlc = wlc; | 8001 | wlc->bsscfg->wlc = wlc; |
8477 | 8002 | ||
8478 | wlc->mimoft = FT_HT; | 8003 | wlc->mimoft = FT_HT; |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index 8debc74c54e1..fb447747c2c6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h | |||
@@ -101,9 +101,6 @@ | |||
101 | 101 | ||
102 | #define DATA_BLOCK_TX_SUPR (1 << 4) | 102 | #define DATA_BLOCK_TX_SUPR (1 << 4) |
103 | 103 | ||
104 | /* 802.1D Priority to TX FIFO number for wme */ | ||
105 | extern const u8 prio2fifo[]; | ||
106 | |||
107 | /* Ucode MCTL_WAKE override bits */ | 104 | /* Ucode MCTL_WAKE override bits */ |
108 | #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 | 105 | #define BRCMS_WAKE_OVERRIDE_CLKCTL 0x01 |
109 | #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 | 106 | #define BRCMS_WAKE_OVERRIDE_PHYREG 0x02 |
@@ -242,7 +239,6 @@ struct brcms_core { | |||
242 | 239 | ||
243 | /* fifo */ | 240 | /* fifo */ |
244 | uint *txavail[NFIFO]; /* # tx descriptors available */ | 241 | uint *txavail[NFIFO]; /* # tx descriptors available */ |
245 | s16 txpktpend[NFIFO]; /* tx admission control */ | ||
246 | 242 | ||
247 | struct macstat *macstat_snapshot; /* mac hw prev read values */ | 243 | struct macstat *macstat_snapshot; /* mac hw prev read values */ |
248 | }; | 244 | }; |
@@ -382,19 +378,6 @@ struct brcms_hardware { | |||
382 | */ | 378 | */ |
383 | }; | 379 | }; |
384 | 380 | ||
385 | /* TX Queue information | ||
386 | * | ||
387 | * Each flow of traffic out of the device has a TX Queue with independent | ||
388 | * flow control. Several interfaces may be associated with a single TX Queue | ||
389 | * if they belong to the same flow of traffic from the device. For multi-channel | ||
390 | * operation there are independent TX Queues for each channel. | ||
391 | */ | ||
392 | struct brcms_txq_info { | ||
393 | struct brcms_txq_info *next; | ||
394 | struct pktq q; | ||
395 | uint stopped; /* tx flow control bits */ | ||
396 | }; | ||
397 | |||
398 | /* | 381 | /* |
399 | * Principal common driver data structure. | 382 | * Principal common driver data structure. |
400 | * | 383 | * |
@@ -435,11 +418,8 @@ struct brcms_txq_info { | |||
435 | * WDlast: last time wlc_watchdog() was called. | 418 | * WDlast: last time wlc_watchdog() was called. |
436 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. | 419 | * edcf_txop[IEEE80211_NUM_ACS]: current txop for each ac. |
437 | * wme_retries: per-AC retry limits. | 420 | * wme_retries: per-AC retry limits. |
438 | * tx_prec_map: Precedence map based on HW FIFO space. | ||
439 | * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. | ||
440 | * bsscfg: set of BSS configurations, idx 0 is default and always valid. | 421 | * bsscfg: set of BSS configurations, idx 0 is default and always valid. |
441 | * cfg: the primary bsscfg (can be AP or STA). | 422 | * cfg: the primary bsscfg (can be AP or STA). |
442 | * tx_queues: common TX Queue list. | ||
443 | * modulecb: | 423 | * modulecb: |
444 | * mimoft: SIGN or 11N. | 424 | * mimoft: SIGN or 11N. |
445 | * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. | 425 | * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. |
@@ -469,7 +449,6 @@ struct brcms_txq_info { | |||
469 | * tempsense_lasttime; | 449 | * tempsense_lasttime; |
470 | * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. | 450 | * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. |
471 | * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. | 451 | * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. |
472 | * pkt_queue: txq for transmit packets. | ||
473 | * wiphy: | 452 | * wiphy: |
474 | * pri_scb: primary Station Control Block | 453 | * pri_scb: primary Station Control Block |
475 | */ | 454 | */ |
@@ -533,14 +512,9 @@ struct brcms_c_info { | |||
533 | u16 edcf_txop[IEEE80211_NUM_ACS]; | 512 | u16 edcf_txop[IEEE80211_NUM_ACS]; |
534 | 513 | ||
535 | u16 wme_retries[IEEE80211_NUM_ACS]; | 514 | u16 wme_retries[IEEE80211_NUM_ACS]; |
536 | u16 tx_prec_map; | ||
537 | u16 fifo2prec_map[NFIFO]; | ||
538 | 515 | ||
539 | struct brcms_bss_cfg *bsscfg; | 516 | struct brcms_bss_cfg *bsscfg; |
540 | 517 | ||
541 | /* tx queue */ | ||
542 | struct brcms_txq_info *tx_queues; | ||
543 | |||
544 | struct modulecb *modulecb; | 518 | struct modulecb *modulecb; |
545 | 519 | ||
546 | u8 mimoft; | 520 | u8 mimoft; |
@@ -585,7 +559,6 @@ struct brcms_c_info { | |||
585 | u16 tx_duty_cycle_ofdm; | 559 | u16 tx_duty_cycle_ofdm; |
586 | u16 tx_duty_cycle_cck; | 560 | u16 tx_duty_cycle_cck; |
587 | 561 | ||
588 | struct brcms_txq_info *pkt_queue; | ||
589 | struct wiphy *wiphy; | 562 | struct wiphy *wiphy; |
590 | struct scb pri_scb; | 563 | struct scb pri_scb; |
591 | }; | 564 | }; |
@@ -637,30 +610,13 @@ struct brcms_bss_cfg { | |||
637 | struct brcms_bss_info *current_bss; | 610 | struct brcms_bss_info *current_bss; |
638 | }; | 611 | }; |
639 | 612 | ||
640 | extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, | 613 | extern int brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, |
641 | struct sk_buff *p, | 614 | struct sk_buff *p); |
642 | bool commit, s8 txpktpend); | ||
643 | extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, | ||
644 | s8 txpktpend); | ||
645 | extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, | ||
646 | struct sk_buff *sdu, uint prec); | ||
647 | extern void brcms_c_print_txstatus(struct tx_status *txs); | ||
648 | extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, | 615 | extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, |
649 | uint *blocks); | 616 | uint *blocks); |
650 | 617 | ||
651 | #if defined(DEBUG) | ||
652 | extern void brcms_c_print_txdesc(struct d11txh *txh); | ||
653 | #else | ||
654 | static inline void brcms_c_print_txdesc(struct d11txh *txh) | ||
655 | { | ||
656 | } | ||
657 | #endif | ||
658 | |||
659 | extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); | 618 | extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); |
660 | extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); | 619 | extern void brcms_c_mac_promisc(struct brcms_c_info *wlc, uint filter_flags); |
661 | extern void brcms_c_send_q(struct brcms_c_info *wlc); | ||
662 | extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, | ||
663 | uint *fifo); | ||
664 | extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, | 620 | extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, |
665 | uint mac_len); | 621 | uint mac_len); |
666 | extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, | 622 | extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h index 5855f4fd16dc..0148dec104f0 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h | |||
@@ -200,43 +200,6 @@ enum wlc_par_id { | |||
200 | /* WL11N Support */ | 200 | /* WL11N Support */ |
201 | #define AMPDU_AGG_HOST 1 | 201 | #define AMPDU_AGG_HOST 1 |
202 | 202 | ||
203 | /* pri is priority encoded in the packet. This maps the Packet priority to | ||
204 | * enqueue precedence as defined in wlc_prec_map | ||
205 | */ | ||
206 | extern const u8 wlc_prio2prec_map[]; | ||
207 | #define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] | ||
208 | |||
209 | #define BRCMS_PREC_COUNT 16 /* Max precedence level implemented */ | ||
210 | |||
211 | /* Mask to describe all precedence levels */ | ||
212 | #define BRCMS_PREC_BMP_ALL MAXBITVAL(BRCMS_PREC_COUNT) | ||
213 | |||
214 | /* | ||
215 | * This maps priority to one precedence higher - Used by PS-Poll response | ||
216 | * packets to simulate enqueue-at-head operation, but still maintain the | ||
217 | * order on the queue | ||
218 | */ | ||
219 | #define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ | ||
220 | BRCMS_PREC_COUNT - 1) | ||
221 | |||
222 | /* Define a bitmap of precedences comprised by each AC */ | ||
223 | #define BRCMS_PREC_BMP_AC_BE (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BE)) | \ | ||
224 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BE)) | \ | ||
225 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_EE)) | \ | ||
226 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_EE))) | ||
227 | #define BRCMS_PREC_BMP_AC_BK (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_BK)) | \ | ||
228 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_BK)) | \ | ||
229 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NONE)) | \ | ||
230 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NONE))) | ||
231 | #define BRCMS_PREC_BMP_AC_VI (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_CL)) | \ | ||
232 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_CL)) | \ | ||
233 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VI)) | \ | ||
234 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VI))) | ||
235 | #define BRCMS_PREC_BMP_AC_VO (NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_VO)) | \ | ||
236 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_VO)) | \ | ||
237 | NBITVAL(BRCMS_PRIO_TO_PREC(PRIO_8021D_NC)) | \ | ||
238 | NBITVAL(BRCMS_PRIO_TO_HI_PREC(PRIO_8021D_NC))) | ||
239 | |||
240 | /* network protection config */ | 203 | /* network protection config */ |
241 | #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ | 204 | #define BRCMS_PROT_G_SPEC 1 /* SPEC g protection */ |
242 | #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ | 205 | #define BRCMS_PROT_G_OVR 2 /* SPEC g prot override */ |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/stf.c b/drivers/net/wireless/brcm80211/brcmsmac/stf.c index ed1d1aa71d2d..dd9162722495 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/stf.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/stf.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "channel.h" | 23 | #include "channel.h" |
24 | #include "main.h" | 24 | #include "main.h" |
25 | #include "stf.h" | 25 | #include "stf.h" |
26 | #include "debug.h" | ||
26 | 27 | ||
27 | #define MIN_SPATIAL_EXPANSION 0 | 28 | #define MIN_SPATIAL_EXPANSION 0 |
28 | #define MAX_SPATIAL_EXPANSION 1 | 29 | #define MAX_SPATIAL_EXPANSION 1 |
@@ -160,8 +161,8 @@ bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) | |||
160 | static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, | 161 | static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, |
161 | u8 core_mask) | 162 | u8 core_mask) |
162 | { | 163 | { |
163 | BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", | 164 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: Nsts %d core_mask %x\n", |
164 | wlc->pub->unit, Nsts, core_mask); | 165 | wlc->pub->unit, Nsts, core_mask); |
165 | 166 | ||
166 | if (hweight8(core_mask) > wlc->stf->txstreams) | 167 | if (hweight8(core_mask) > wlc->stf->txstreams) |
167 | core_mask = 0; | 168 | core_mask = 0; |
@@ -194,7 +195,8 @@ static int brcms_c_stf_spatial_policy_set(struct brcms_c_info *wlc, int val) | |||
194 | int i; | 195 | int i; |
195 | u8 core_mask = 0; | 196 | u8 core_mask = 0; |
196 | 197 | ||
197 | BCMMSG(wlc->wiphy, "wl%d: val %x\n", wlc->pub->unit, val); | 198 | brcms_dbg_ht(wlc->hw->d11core, "wl%d: val %x\n", wlc->pub->unit, |
199 | val); | ||
198 | 200 | ||
199 | wlc->stf->spatial_policy = (s8) val; | 201 | wlc->stf->spatial_policy = (s8) val; |
200 | for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { | 202 | for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { |
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/types.h b/drivers/net/wireless/brcm80211/brcmsmac/types.h index e11ae83111e4..ae1f3ad40d45 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/types.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/types.h | |||
@@ -246,7 +246,7 @@ | |||
246 | 246 | ||
247 | #define BCMMSG(dev, fmt, args...) \ | 247 | #define BCMMSG(dev, fmt, args...) \ |
248 | do { \ | 248 | do { \ |
249 | if (brcm_msg_level & LOG_TRACE_VAL) \ | 249 | if (brcm_msg_level & BRCM_DL_INFO) \ |
250 | wiphy_err(dev, "%s: " fmt, __func__, ##args); \ | 250 | wiphy_err(dev, "%s: " fmt, __func__, ##args); \ |
251 | } while (0) | 251 | } while (0) |
252 | 252 | ||
@@ -281,7 +281,6 @@ struct ieee80211_tx_queue_params; | |||
281 | struct brcms_info; | 281 | struct brcms_info; |
282 | struct brcms_c_info; | 282 | struct brcms_c_info; |
283 | struct brcms_hardware; | 283 | struct brcms_hardware; |
284 | struct brcms_txq_info; | ||
285 | struct brcms_band; | 284 | struct brcms_band; |
286 | struct dma_pub; | 285 | struct dma_pub; |
287 | struct si_pub; | 286 | struct si_pub; |
diff --git a/drivers/net/wireless/brcm80211/include/defs.h b/drivers/net/wireless/brcm80211/include/defs.h index f0d8c04a9c8c..fb7cbcf81179 100644 --- a/drivers/net/wireless/brcm80211/include/defs.h +++ b/drivers/net/wireless/brcm80211/include/defs.h | |||
@@ -78,9 +78,14 @@ | |||
78 | #define PM_OFF 0 | 78 | #define PM_OFF 0 |
79 | #define PM_MAX 1 | 79 | #define PM_MAX 1 |
80 | 80 | ||
81 | /* Message levels */ | 81 | /* Debug levels */ |
82 | #define LOG_ERROR_VAL 0x00000001 | 82 | #define BRCM_DL_INFO 0x00000001 |
83 | #define LOG_TRACE_VAL 0x00000002 | 83 | #define BRCM_DL_MAC80211 0x00000002 |
84 | #define BRCM_DL_RX 0x00000004 | ||
85 | #define BRCM_DL_TX 0x00000008 | ||
86 | #define BRCM_DL_INT 0x00000010 | ||
87 | #define BRCM_DL_DMA 0x00000020 | ||
88 | #define BRCM_DL_HT 0x00000040 | ||
84 | 89 | ||
85 | #define PM_OFF 0 | 90 | #define PM_OFF 0 |
86 | #define PM_MAX 1 | 91 | #define PM_MAX 1 |