aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/Makefile1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c43
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c140
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h186
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h3
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c72
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c452
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h10
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c509
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h7
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c252
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.c509
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fweh.h207
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil.c26
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c278
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.h18
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c1010
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h120
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
25brcmfmac-objs += \ 25brcmfmac-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
43static irqreturn_t brcmf_sdio_irqhandler(int irq, void *dev_id) 43static 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 */
118static void brcmf_sdio_irqhandler(struct sdio_func *func) 125static 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
378done: 376done:
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
405done: 399done:
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
469done: 459done:
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
552int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) 535int 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
413out: 409out:
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
461static int brcmf_ops_sdio_probe(struct sdio_func *func, 458static 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; 517fail:
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
523static void brcmf_ops_sdio_remove(struct sdio_func *func) 525static 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
546static int brcmf_sdio_suspend(struct device *dev) 554static 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
574static int brcmf_sdio_resume(struct device *dev) 582static 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
144struct 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
158struct brcm_ethhdr {
159 u16 subtype;
160 u16 length;
161 u8 version;
162 u8 oui[3];
163 u16 usr_subtype;
164} __packed;
165
166struct 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
409struct brcmf_ssid { 289struct 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 */
456struct brcmf_iscan_params_le {
457 __le32 version;
458 __le16 action;
459 __le16 scan_duration;
460 struct brcmf_scan_params_le params_le;
461};
462
463struct brcmf_scan_results { 335struct 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
470struct brcmf_scan_results_le {
471 __le32 buflen;
472 __le32 version;
473 __le32 count;
474};
475
476struct brcmf_escan_params_le { 342struct 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 */
512struct 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
528struct brcmf_wsec_key { 377struct 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
715extern const struct bcmevent_name bcmevent_names[]; 567extern const struct bcmevent_name bcmevent_names[];
716 568
717extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
718 char *buf, uint len);
719
720extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 569extern 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,
728extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 577extern 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
731extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name);
732extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
733 void *pktdata, struct brcmf_event_msg *,
734 void **data_ptr);
735
736extern int brcmf_net_attach(struct brcmf_if *ifp); 580extern int brcmf_net_attach(struct brcmf_if *ifp);
737extern struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, 581extern 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);
739extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); 583extern 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 */
47struct brcmf_bus { 47struct 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. */
88extern void brcmf_rx_frame(struct device *dev, int ifidx, 87extern void brcmf_rx_frame(struct device *dev, u8 ifidx,
89 struct sk_buff_head *rxlist); 88 struct sk_buff_head *rxlist);
90static inline void brcmf_rx_packet(struct device *dev, int ifidx, 89static 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
280int
281brcmf_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
344done:
345 mutex_unlock(&drvr->proto_block);
346
347 return ret;
348}
349
350static bool pkt_sum_needed(struct sk_buff *skb) 278static 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
50static const char brcmf_version[] = 38static 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 */
59struct 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
75uint
76brcmf_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
96bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 47bool 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
147static void
148brcmf_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
445int
446brcmf_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 */
546static int brcmf_c_pattern_atoh(char *src, char *dst) 98static 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
31static struct dentry *root_folder; 25static 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
49MODULE_AUTHOR("Broadcom Corporation"); 34MODULE_AUTHOR("Broadcom Corporation");
50MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); 35MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
51MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); 36MODULE_SUPPORTED_DEVICE("Broadcom 802.11 WLAN fullmac cards");
52MODULE_LICENSE("Dual BSD/GPL"); 37MODULE_LICENSE("Dual BSD/GPL");
53 38
39#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */
54 40
55/* Error bits */ 41/* Error bits */
56int brcmf_msg_level = BRCMF_ERROR_VAL; 42int brcmf_msg_level = BRCMF_ERROR_VAL;
57module_param(brcmf_msg_level, int, 0); 43module_param(brcmf_msg_level, int, 0);
58 44
59int 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
78char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) 46char *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
96static void _brcmf_set_multicast_list(struct work_struct *work) 64static 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
212static void 128static 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
246static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) 148static 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
257static void brcmf_netdev_set_multicast_list(struct net_device *ndev) 158static 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
265static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 165static 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
353static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, 253void 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
370void 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
469static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev) 349static 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,
492static 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; 374static 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 */
528static 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
569static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, 392static 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
584static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) 407static 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
603static 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
782int brcmf_net_attach(struct brcmf_if *ifp) 613int 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
825fail: 645fail:
826 ndev->netdev_ops = NULL; 646 ndev->netdev_ops = NULL;
827 free_netdev(ndev);
828 return -EBADE; 647 return -EBADE;
829} 648}
830 649
831struct brcmf_if *brcmf_add_if(struct device *dev, int ifidx, s32 bssidx, 650struct 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
944fail: 777fail:
@@ -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);
823fail:
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
1040int brcmf_netdev_wait_pend8021x(struct net_device *ndev) 884int 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
1060static void brcmf_driver_init(struct work_struct *work) 899static 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);
36extern void brcmf_proto_hdrpush(struct brcmf_pub *, int ifidx, 36extern 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 */
40extern 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). */
44extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); 40extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
45 41
46extern 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
1040static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header, 1040static 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
1161static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1161static 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
1442brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) 1448brcmf_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
1512gotpkt: 1522gotpkt:
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
1521done: 1540done:
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
1757static void 1788static void
1758brcmf_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
1766static void
1767brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus) 1789brcmf_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
1897done: 1921done:
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
2316static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2343static 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;
2940done: 2975done:
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
3444exit: 3486exit:
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
3721fail: 3769fail:
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 */
35struct brcm_ethhdr {
36 __be16 subtype;
37 __be16 length;
38 u8 version;
39 u8 oui[3];
40 __be16 usr_subtype;
41} __packed;
42
43struct 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 */
64struct 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 */
80struct 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 */
92struct 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 */
99static 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 */
174static 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
184static 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 */
196static 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
207static 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 */
236static 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 */
279static struct brcmf_fweh_queue_item *
280brcmf_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 */
301static 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 }
355event_free:
356 kfree(event);
357 }
358}
359
360/**
361 * brcmf_fweh_attach() - initialize firmware event handling.
362 *
363 * @drvr: driver information object.
364 */
365void 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 */
378void 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 */
404int 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 */
423void 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 */
436int 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 */
471void 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 */
27struct brcmf_pub;
28struct brcmf_if;
29struct brcmf_cfg80211_info;
30struct brcmf_event;
31
32/* firmware event codes sent by the dongle */
33enum 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 */
133struct 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
147typedef 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 */
159struct 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
168void brcmf_fweh_attach(struct brcmf_pub *drvr);
169void brcmf_fweh_detach(struct brcmf_pub *drvr);
170int 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));
174void brcmf_fweh_unregister(struct brcmf_pub *drvr,
175 enum brcmf_fweh_event_code code);
176int brcmf_fweh_activate_events(struct brcmf_if *ifp);
177void brcmf_fweh_process_event(struct brcmf_pub *drvr,
178 struct brcmf_event *event_packet, u8 *ifidx);
179
180static 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
32static s32 34static s32
33brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) 35brcmf_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
72enum 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
82struct brcmf_usb_image { 58struct 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)
170static void 144static void
171brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status) 145brcmf_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
215static int brcmf_usb_pnp(struct brcmf_usbdev_info *devinfo, uint state)
216{
217 return 0;
218}
219
220static int 192static int
221brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len) 193brcmf_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
618static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb) 583static 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
841brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo) 794brcmf_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
987fail: 932fail:
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
1095static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo) 1040static 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
1211struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo, 1158struct 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
1281static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo, 1231static 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 */
1488static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state) 1438static 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 */
1502static int brcmf_usb_resume(struct usb_interface *intf) 1452static 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
1464static 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);
1529MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); 1493MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
1530MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME); 1494MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
1531 1495
1532/* TODO: suspend and resume entries */
1533static struct usb_driver brcmf_usbdrvr = { 1496static 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
1555void brcmf_usb_exit(void) 1519void 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
1561void brcmf_usb_init(void) 1526void 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
19enum brcmf_usb_state { 19enum 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
29enum brcmf_usb_pnp_state {
30 BCMFMAC_USB_PNP_DISCONNECT,
31 BCMFMAC_USB_PNP_SLEEP,
32 BCMFMAC_USB_PNP_RESUME,
33}; 25};
34 26
35struct brcmf_stats { 27struct 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
532static 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(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
546 }
547}
548
549static s32
550brcmf_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(&params->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
584static 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
617static s32
618brcmf_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
705scan_out:
706 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
707 cfg->scan_request = NULL;
708 return err;
709}
710
711static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le, 518static 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
1027brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) 832brcmf_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)
1075static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) 876static 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
1723static s32 1524static s32
1724brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, 1525brcmf_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
1773static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) 1574static 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
2583static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg) 2384static 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
2619static 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
2639static 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
2650static s32
2651brcmf_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
2686static 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
2698static 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
2710static 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
2724static 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
2735static 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
2757static 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
2769static 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
2781static 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
2791static 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
2811static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work) 2397static 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
2865static s32 2450static s32
2866brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg, 2451brcmf_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
2961static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg) 2545static 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
2977static __always_inline void brcmf_delay(u32 ms) 2558static __always_inline void brcmf_delay(u32 ms)
@@ -2986,20 +2567,8 @@ static __always_inline void brcmf_delay(u32 ms)
2986 2567
2987static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 2568static 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 */
3200static s32 2769static s32
3201brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg, 2770brcmf_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
3313static int brcmf_dev_pno_clean(struct net_device *ndev) 2882static 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
3452static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len) 3020static 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
3513static s32 3081static s32
3514brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie, 3082brcmf_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
3691static s32 3259static s32
3692brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len, 3260brcmf_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
3771static s32 3339static
3772brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg, 3340s32 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
4198static void brcmf_wiphy_pno_params(struct wiphy *wiphy) 3750static 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
4209static struct wiphy *brcmf_setup_wiphy(struct device *phydev) 3759static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
@@ -4302,8 +3852,8 @@ static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4302static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg, 3852static 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,
4317static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg, 3867static 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,
4330static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg, 3880static 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
4560static s32 4109static s32
4561brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg, 4110brcmf_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
4612static s32 4161static s32
4613brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg, 4162brcmf_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
4632static s32 4180static s32
4633brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg, 4181brcmf_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
4651static s32
4652brcmf_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
4710scan_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
4723static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf) 4198static 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
4733static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el) 4208static 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
4749static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg) 4232static 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
4777static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) 4244static 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
4820static 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
4842static s32
4843brcmf_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
4874static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
4875{
4876 kfree(e);
4877}
4878
4879static 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
4905static 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
4911static 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
4925static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg) 4267static 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
4966static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg) 4290static 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
5032void
5033brcmf_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
5043static 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
5087dongle_eventmsg_out:
5088 WL_TRACE("Exit\n");
5089 return err;
5090}
5091
5092static s32 4354static s32
5093brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) 4355brcmf_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
5265static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) 4523static 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
5281static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) 4532static 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
5309s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg) 4559s32 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
5320s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg) 4572s32 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 */
149enum wl_iscan_state {
150 WL_ISCAN_STATE_IDLE,
151 WL_ISCAN_STATE_SCANING
152};
153
154/* dongle configuration */ 129/* dongle configuration */
155struct brcmf_cfg80211_conf { 130struct 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 */
166struct brcmf_cfg80211_info;
167
168/* cfg80211 main event loop */
169struct 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 */
177struct brcmf_cfg80211_scan_req { 141struct 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 */
188struct 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 */
196struct brcmf_cfg80211_security { 152struct 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 */
274struct brcmf_cfg80211_iscan_eloop {
275 s32 (*handler[WL_SCAN_ERSULTS_LAST])
276 (struct brcmf_cfg80211_info *cfg);
277};
278
279/* dongle iscan controller */
280struct 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 */
294struct brcmf_cfg80211_connect_info { 230struct 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 */
327struct 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)) 444static 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
542static inline struct 450static inline struct
543brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg) 451brcmf_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
548struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr); 456struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr);
549void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg); 457void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
550 458s32 brcmf_cfg80211_up(struct net_device *ndev);
551/* event handler from dongle */ 459s32 brcmf_cfg80211_down(struct net_device *ndev);
552void brcmf_cfg80211_event(struct net_device *ndev,
553 const struct brcmf_event_msg *e, void *data);
554s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
555s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
556 460
557#endif /* _wl_cfg80211_h_ */ 461#endif /* _wl_cfg80211_h_ */