diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
19 files changed, 1442 insertions, 2407 deletions
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_ */ |