aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/Kconfig8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c39
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c27
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h62
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c73
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c65
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c1047
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c17
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c353
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c3135
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h296
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/aiutils.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c15
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c13
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h1
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h5
19 files changed, 3428 insertions, 1737 deletions
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index b480088b3dbe..c9d811eb6556 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -55,6 +55,14 @@ config BRCMFMAC_USB
55 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to 55 IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
56 use the driver for an USB wireless card. 56 use the driver for an USB wireless card.
57 57
58config BRCMISCAN
59 bool "Broadcom I-Scan (OBSOLETE)"
60 depends on BRCMFMAC
61 ---help---
62 This option enables the I-Scan method. By default fullmac uses the
63 new E-Scan method which uses less memory in firmware and gives no
64 limitation on the number of scan results.
65
58config BRCMDBG 66config BRCMDBG
59 bool "Broadcom driver debug functions" 67 bool "Broadcom driver debug functions"
60 depends on BRCMSMAC || BRCMFMAC 68 depends on BRCMSMAC || BRCMFMAC
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 8e7e6928c936..3b2c4c20e7fc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -185,7 +185,7 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
185 return err; 185 return err;
186} 186}
187 187
188static int 188int
189brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 189brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
190 void *data, bool write) 190 void *data, bool write)
191{ 191{
@@ -249,7 +249,9 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
249 int retval; 249 int retval;
250 250
251 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 251 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
252 sdio_claim_host(sdiodev->func[1]);
252 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 253 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
254 sdio_release_host(sdiodev->func[1]);
253 brcmf_dbg(INFO, "data:0x%02x\n", data); 255 brcmf_dbg(INFO, "data:0x%02x\n", data);
254 256
255 if (ret) 257 if (ret)
@@ -264,7 +266,9 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
264 int retval; 266 int retval;
265 267
266 brcmf_dbg(INFO, "addr:0x%08x\n", addr); 268 brcmf_dbg(INFO, "addr:0x%08x\n", addr);
269 sdio_claim_host(sdiodev->func[1]);
267 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false); 270 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
271 sdio_release_host(sdiodev->func[1]);
268 brcmf_dbg(INFO, "data:0x%08x\n", data); 272 brcmf_dbg(INFO, "data:0x%08x\n", data);
269 273
270 if (ret) 274 if (ret)
@@ -279,7 +283,9 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
279 int retval; 283 int retval;
280 284
281 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data); 285 brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
286 sdio_claim_host(sdiodev->func[1]);
282 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 287 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
288 sdio_release_host(sdiodev->func[1]);
283 289
284 if (ret) 290 if (ret)
285 *ret = retval; 291 *ret = retval;
@@ -291,7 +297,9 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
291 int retval; 297 int retval;
292 298
293 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data); 299 brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
300 sdio_claim_host(sdiodev->func[1]);
294 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true); 301 retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
302 sdio_release_host(sdiodev->func[1]);
295 303
296 if (ret) 304 if (ret)
297 *ret = retval; 305 *ret = retval;
@@ -356,15 +364,20 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
356 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 364 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
357 fn, addr, pkt->len); 365 fn, addr, pkt->len);
358 366
367 sdio_claim_host(sdiodev->func[1]);
368
359 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 369 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
360 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 370 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
361 if (err) 371 if (err)
362 return err; 372 goto done;
363 373
364 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; 374 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
365 err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ, 375 err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_READ,
366 fn, addr, pkt); 376 fn, addr, pkt);
367 377
378done:
379 sdio_release_host(sdiodev->func[1]);
380
368 return err; 381 return err;
369} 382}
370 383
@@ -378,15 +391,20 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
378 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", 391 brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
379 fn, addr, pktq->qlen); 392 fn, addr, pktq->qlen);
380 393
394 sdio_claim_host(sdiodev->func[1]);
395
381 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 396 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
382 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 397 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
383 if (err) 398 if (err)
384 return err; 399 goto done;
385 400
386 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC; 401 incr_fix = (flags & SDIO_REQ_FIXED) ? SDIOH_DATA_FIX : SDIOH_DATA_INC;
387 err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr, 402 err = brcmf_sdioh_request_chain(sdiodev, incr_fix, SDIOH_READ, fn, addr,
388 pktq); 403 pktq);
389 404
405done:
406 sdio_release_host(sdiodev->func[1]);
407
390 return err; 408 return err;
391} 409}
392 410
@@ -428,10 +446,12 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
428 if (flags & SDIO_REQ_ASYNC) 446 if (flags & SDIO_REQ_ASYNC)
429 return -ENOTSUPP; 447 return -ENOTSUPP;
430 448
449 sdio_claim_host(sdiodev->func[1]);
450
431 if (bar0 != sdiodev->sbwad) { 451 if (bar0 != sdiodev->sbwad) {
432 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 452 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
433 if (err) 453 if (err)
434 return err; 454 goto done;
435 455
436 sdiodev->sbwad = bar0; 456 sdiodev->sbwad = bar0;
437 } 457 }
@@ -443,8 +463,13 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
443 if (width == 4) 463 if (width == 4)
444 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 464 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
445 465
446 return brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn, 466 err = brcmf_sdioh_request_buffer(sdiodev, incr_fix, SDIOH_WRITE, fn,
447 addr, pkt); 467 addr, pkt);
468
469done:
470 sdio_release_host(sdiodev->func[1]);
471
472 return err;
448} 473}
449 474
450int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, 475int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr,
@@ -485,8 +510,10 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
485 brcmf_dbg(TRACE, "Enter\n"); 510 brcmf_dbg(TRACE, "Enter\n");
486 511
487 /* issue abort cmd52 command through F0 */ 512 /* issue abort cmd52 command through F0 */
513 sdio_claim_host(sdiodev->func[1]);
488 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, 514 brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
489 SDIO_CCCR_ABORT, &t_func); 515 SDIO_CCCR_ABORT, &t_func);
516 sdio_release_host(sdiodev->func[1]);
490 517
491 brcmf_dbg(TRACE, "Exit\n"); 518 brcmf_dbg(TRACE, "Exit\n");
492 return 0; 519 return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index 7c4ee72f9d56..c3247d5b3c22 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -42,6 +42,7 @@
42 42
43#define DMA_ALIGN_MASK 0x03 43#define DMA_ALIGN_MASK 0x03
44 44
45#define SDIO_DEVICE_ID_BROADCOM_43241 0x4324
45#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329 46#define SDIO_DEVICE_ID_BROADCOM_4329 0x4329
46#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330 47#define SDIO_DEVICE_ID_BROADCOM_4330 0x4330
47#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334 48#define SDIO_DEVICE_ID_BROADCOM_4334 0x4334
@@ -51,6 +52,7 @@
51 52
52/* devices we support, null terminated */ 53/* devices we support, null terminated */
53static const struct sdio_device_id brcmf_sdmmc_ids[] = { 54static const struct sdio_device_id brcmf_sdmmc_ids[] = {
55 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_43241)},
54 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)}, 56 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4329)},
55 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)}, 57 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4330)},
56 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)}, 58 {SDIO_DEVICE(SDIO_VENDOR_ID_BROADCOM, SDIO_DEVICE_ID_BROADCOM_4334)},
@@ -101,7 +103,6 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
101 if (regaddr == SDIO_CCCR_IOEx) { 103 if (regaddr == SDIO_CCCR_IOEx) {
102 sdfunc = sdiodev->func[2]; 104 sdfunc = sdiodev->func[2];
103 if (sdfunc) { 105 if (sdfunc) {
104 sdio_claim_host(sdfunc);
105 if (*byte & SDIO_FUNC_ENABLE_2) { 106 if (*byte & SDIO_FUNC_ENABLE_2) {
106 /* Enable Function 2 */ 107 /* Enable Function 2 */
107 err_ret = sdio_enable_func(sdfunc); 108 err_ret = sdio_enable_func(sdfunc);
@@ -117,7 +118,6 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
117 "Disable F2 failed:%d\n", 118 "Disable F2 failed:%d\n",
118 err_ret); 119 err_ret);
119 } 120 }
120 sdio_release_host(sdfunc);
121 } 121 }
122 } else if ((regaddr == SDIO_CCCR_ABORT) || 122 } else if ((regaddr == SDIO_CCCR_ABORT) ||
123 (regaddr == SDIO_CCCR_IENx)) { 123 (regaddr == SDIO_CCCR_IENx)) {
@@ -126,17 +126,13 @@ static inline int brcmf_sdioh_f0_write_byte(struct brcmf_sdio_dev *sdiodev,
126 if (!sdfunc) 126 if (!sdfunc)
127 return -ENOMEM; 127 return -ENOMEM;
128 sdfunc->num = 0; 128 sdfunc->num = 0;
129 sdio_claim_host(sdfunc);
130 sdio_writeb(sdfunc, *byte, regaddr, &err_ret); 129 sdio_writeb(sdfunc, *byte, regaddr, &err_ret);
131 sdio_release_host(sdfunc);
132 kfree(sdfunc); 130 kfree(sdfunc);
133 } else if (regaddr < 0xF0) { 131 } else if (regaddr < 0xF0) {
134 brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr); 132 brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", regaddr);
135 err_ret = -EPERM; 133 err_ret = -EPERM;
136 } else { 134 } else {
137 sdio_claim_host(sdfunc);
138 sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret); 135 sdio_f0_writeb(sdfunc, *byte, regaddr, &err_ret);
139 sdio_release_host(sdfunc);
140 } 136 }
141 137
142 return err_ret; 138 return err_ret;
@@ -157,7 +153,6 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
157 /* handle F0 separately */ 153 /* handle F0 separately */
158 err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte); 154 err_ret = brcmf_sdioh_f0_write_byte(sdiodev, regaddr, byte);
159 } else { 155 } else {
160 sdio_claim_host(sdiodev->func[func]);
161 if (rw) /* CMD52 Write */ 156 if (rw) /* CMD52 Write */
162 sdio_writeb(sdiodev->func[func], *byte, regaddr, 157 sdio_writeb(sdiodev->func[func], *byte, regaddr,
163 &err_ret); 158 &err_ret);
@@ -168,7 +163,6 @@ int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func,
168 *byte = sdio_readb(sdiodev->func[func], regaddr, 163 *byte = sdio_readb(sdiodev->func[func], regaddr,
169 &err_ret); 164 &err_ret);
170 } 165 }
171 sdio_release_host(sdiodev->func[func]);
172 } 166 }
173 167
174 if (err_ret) 168 if (err_ret)
@@ -195,8 +189,6 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
195 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait); 189 brcmf_pm_resume_wait(sdiodev, &sdiodev->request_word_wait);
196 if (brcmf_pm_resume_error(sdiodev)) 190 if (brcmf_pm_resume_error(sdiodev))
197 return -EIO; 191 return -EIO;
198 /* Claim host controller */
199 sdio_claim_host(sdiodev->func[func]);
200 192
201 if (rw) { /* CMD52 Write */ 193 if (rw) { /* CMD52 Write */
202 if (nbytes == 4) 194 if (nbytes == 4)
@@ -217,9 +209,6 @@ int brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev,
217 brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes); 209 brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes);
218 } 210 }
219 211
220 /* Release host controller */
221 sdio_release_host(sdiodev->func[func]);
222
223 if (err_ret) 212 if (err_ret)
224 brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n", 213 brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n",
225 rw ? "write" : "read", err_ret); 214 rw ? "write" : "read", err_ret);
@@ -273,9 +262,6 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
273 if (brcmf_pm_resume_error(sdiodev)) 262 if (brcmf_pm_resume_error(sdiodev))
274 return -EIO; 263 return -EIO;
275 264
276 /* Claim host controller */
277 sdio_claim_host(sdiodev->func[func]);
278
279 skb_queue_walk(pktq, pkt) { 265 skb_queue_walk(pktq, pkt) {
280 uint pkt_len = pkt->len; 266 uint pkt_len = pkt->len;
281 pkt_len += 3; 267 pkt_len += 3;
@@ -298,9 +284,6 @@ brcmf_sdioh_request_chain(struct brcmf_sdio_dev *sdiodev, uint fix_inc,
298 SGCount++; 284 SGCount++;
299 } 285 }
300 286
301 /* Release host controller */
302 sdio_release_host(sdiodev->func[func]);
303
304 brcmf_dbg(TRACE, "Exit\n"); 287 brcmf_dbg(TRACE, "Exit\n");
305 return err_ret; 288 return err_ret;
306} 289}
@@ -326,9 +309,6 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
326 if (brcmf_pm_resume_error(sdiodev)) 309 if (brcmf_pm_resume_error(sdiodev))
327 return -EIO; 310 return -EIO;
328 311
329 /* Claim host controller */
330 sdio_claim_host(sdiodev->func[func]);
331
332 pkt_len += 3; 312 pkt_len += 3;
333 pkt_len &= (uint)~3; 313 pkt_len &= (uint)~3;
334 314
@@ -342,9 +322,6 @@ int brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev,
342 write ? "TX" : "RX", pkt, addr, pkt_len); 322 write ? "TX" : "RX", pkt, addr, pkt_len);
343 } 323 }
344 324
345 /* Release host controller */
346 sdio_release_host(sdiodev->func[func]);
347
348 return status; 325 return status;
349} 326}
350 327
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index a11fe54f5950..17e7ae73e008 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -27,6 +27,7 @@
27 * IO codes that are interpreted by dongle firmware 27 * IO codes that are interpreted by dongle firmware
28 ******************************************************************************/ 28 ******************************************************************************/
29#define BRCMF_C_UP 2 29#define BRCMF_C_UP 2
30#define BRCMF_C_DOWN 3
30#define BRCMF_C_SET_PROMISC 10 31#define BRCMF_C_SET_PROMISC 10
31#define BRCMF_C_GET_RATE 12 32#define BRCMF_C_GET_RATE 12
32#define BRCMF_C_GET_INFRA 19 33#define BRCMF_C_GET_INFRA 19
@@ -50,7 +51,10 @@
50#define BRCMF_C_REASSOC 53 51#define BRCMF_C_REASSOC 53
51#define BRCMF_C_SET_ROAM_TRIGGER 55 52#define BRCMF_C_SET_ROAM_TRIGGER 55
52#define BRCMF_C_SET_ROAM_DELTA 57 53#define BRCMF_C_SET_ROAM_DELTA 57
54#define BRCMF_C_GET_BCNPRD 75
55#define BRCMF_C_SET_BCNPRD 76
53#define BRCMF_C_GET_DTIMPRD 77 56#define BRCMF_C_GET_DTIMPRD 77
57#define BRCMF_C_SET_DTIMPRD 78
54#define BRCMF_C_SET_COUNTRY 84 58#define BRCMF_C_SET_COUNTRY 84
55#define BRCMF_C_GET_PM 85 59#define BRCMF_C_GET_PM 85
56#define BRCMF_C_SET_PM 86 60#define BRCMF_C_SET_PM 86
@@ -130,6 +134,13 @@
130#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02 134#define BRCMF_EVENT_MSG_FLUSHTXQ 0x02
131#define BRCMF_EVENT_MSG_GROUP 0x04 135#define BRCMF_EVENT_MSG_GROUP 0x04
132 136
137#define BRCMF_ESCAN_REQ_VERSION 1
138
139#define WLC_BSS_RSSI_ON_CHANNEL 0x0002
140
141#define BRCMF_MAXRATES_IN_SET 16 /* max # of rates in rateset */
142#define BRCMF_STA_ASSOC 0x10 /* Associated */
143
133struct brcmf_event_msg { 144struct brcmf_event_msg {
134 __be16 version; 145 __be16 version;
135 __be16 flags; 146 __be16 flags;
@@ -140,6 +151,8 @@ struct brcmf_event_msg {
140 __be32 datalen; 151 __be32 datalen;
141 u8 addr[ETH_ALEN]; 152 u8 addr[ETH_ALEN];
142 char ifname[IFNAMSIZ]; 153 char ifname[IFNAMSIZ];
154 u8 ifidx;
155 u8 bsscfgidx;
143} __packed; 156} __packed;
144 157
145struct brcm_ethhdr { 158struct brcm_ethhdr {
@@ -454,6 +467,24 @@ struct brcmf_scan_results_le {
454 __le32 count; 467 __le32 count;
455}; 468};
456 469
470struct brcmf_escan_params_le {
471 __le32 version;
472 __le16 action;
473 __le16 sync_id;
474 struct brcmf_scan_params_le params_le;
475};
476
477struct brcmf_escan_result_le {
478 __le32 buflen;
479 __le32 version;
480 __le16 sync_id;
481 __le16 bss_count;
482 struct brcmf_bss_info_le bss_info_le;
483};
484
485#define WL_ESCAN_RESULTS_FIXED_SIZE (sizeof(struct brcmf_escan_result_le) - \
486 sizeof(struct brcmf_bss_info_le))
487
457/* used for association with a specific BSSID and chanspec list */ 488/* used for association with a specific BSSID and chanspec list */
458struct brcmf_assoc_params_le { 489struct brcmf_assoc_params_le {
459 /* 00:00:00:00:00:00: broadcast scan */ 490 /* 00:00:00:00:00:00: broadcast scan */
@@ -542,6 +573,28 @@ struct brcmf_channel_info_le {
542 __le32 scan_channel; 573 __le32 scan_channel;
543}; 574};
544 575
576struct brcmf_sta_info_le {
577 __le16 ver; /* version of this struct */
578 __le16 len; /* length in bytes of this structure */
579 __le16 cap; /* sta's advertised capabilities */
580 __le32 flags; /* flags defined below */
581 __le32 idle; /* time since data pkt rx'd from sta */
582 u8 ea[ETH_ALEN]; /* Station address */
583 __le32 count; /* # rates in this set */
584 u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */
585 /* w/hi bit set if basic */
586 __le32 in; /* seconds elapsed since associated */
587 __le32 listen_interval_inms; /* Min Listen interval in ms for STA */
588 __le32 tx_pkts; /* # of packets transmitted */
589 __le32 tx_failures; /* # of packets failed */
590 __le32 rx_ucast_pkts; /* # of unicast packets received */
591 __le32 rx_mcast_pkts; /* # of multicast packets received */
592 __le32 tx_rate; /* Rate of last successful tx frame */
593 __le32 rx_rate; /* Rate of last successful rx frame */
594 __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */
595 __le32 rx_decrypt_failures; /* # of packet decrypted failed */
596};
597
545/* Bus independent dongle command */ 598/* Bus independent dongle command */
546struct brcmf_dcmd { 599struct brcmf_dcmd {
547 uint cmd; /* common dongle cmd definition */ 600 uint cmd; /* common dongle cmd definition */
@@ -561,7 +614,7 @@ struct brcmf_pub {
561 /* Linkage ponters */ 614 /* Linkage ponters */
562 struct brcmf_bus *bus_if; 615 struct brcmf_bus *bus_if;
563 struct brcmf_proto *prot; 616 struct brcmf_proto *prot;
564 struct brcmf_cfg80211_dev *config; 617 struct brcmf_cfg80211_info *config;
565 struct device *dev; /* fullmac dongle device pointer */ 618 struct device *dev; /* fullmac dongle device pointer */
566 619
567 /* Internal brcmf items */ 620 /* Internal brcmf items */
@@ -634,10 +687,13 @@ extern const struct bcmevent_name bcmevent_names[];
634 687
635extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen, 688extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
636 char *buf, uint len); 689 char *buf, uint len);
690extern uint brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
691 char *buf, uint buflen, s32 bssidx);
637 692
638extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev); 693extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);
639 694
640extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len); 695extern s32 brcmf_exec_dcmd(struct net_device *dev, u32 cmd, void *arg, u32 len);
696extern int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd);
641 697
642/* Return pointer to interface name */ 698/* Return pointer to interface name */
643extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); 699extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
@@ -657,10 +713,6 @@ extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx,
657 713
658extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx); 714extern void brcmf_del_if(struct brcmf_pub *drvr, int ifidx);
659 715
660/* Send packet to dongle via data channel */
661extern int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx,\
662 struct sk_buff *pkt);
663
664extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg); 716extern void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg);
665extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, 717extern void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg,
666 int enable, int master_mode); 718 int enable, int master_mode);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index 537f499cc5d2..9b8ee19ea55d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -103,7 +103,7 @@ extern int brcmf_attach(uint bus_hdrlen, struct device *dev);
103extern void brcmf_detach(struct device *dev); 103extern void brcmf_detach(struct device *dev);
104 104
105/* Indication from bus module to change flow-control state */ 105/* Indication from bus module to change flow-control state */
106extern void brcmf_txflowcontrol(struct device *dev, int ifidx, bool on); 106extern void brcmf_txflowblock(struct device *dev, bool state);
107 107
108/* Notify tx completion */ 108/* Notify tx completion */
109extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, 109extern void brcmf_txcomplete(struct device *dev, struct sk_buff *txp,
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 6f70953f0bad..15c5db5752d1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -80,12 +80,60 @@ brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
80 strncpy(buf, name, buflen); 80 strncpy(buf, name, buflen);
81 81
82 /* append data onto the end of the name string */ 82 /* append data onto the end of the name string */
83 memcpy(&buf[len], data, datalen); 83 if (data && datalen) {
84 len += datalen; 84 memcpy(&buf[len], data, datalen);
85 len += datalen;
86 }
85 87
86 return len; 88 return len;
87} 89}
88 90
91uint
92brcmf_c_mkiovar_bsscfg(char *name, char *data, uint datalen,
93 char *buf, uint buflen, s32 bssidx)
94{
95 const s8 *prefix = "bsscfg:";
96 s8 *p;
97 u32 prefixlen;
98 u32 namelen;
99 u32 iolen;
100 __le32 bssidx_le;
101
102 if (bssidx == 0)
103 return brcmf_c_mkiovar(name, data, datalen, buf, buflen);
104
105 prefixlen = (u32) strlen(prefix); /* lengh of bsscfg prefix */
106 namelen = (u32) strlen(name) + 1; /* lengh of iovar name + null */
107 iolen = prefixlen + namelen + sizeof(bssidx_le) + datalen;
108
109 if (buflen < 0 || iolen > (u32)buflen) {
110 brcmf_dbg(ERROR, "buffer is too short\n");
111 return 0;
112 }
113
114 p = buf;
115
116 /* copy prefix, no null */
117 memcpy(p, prefix, prefixlen);
118 p += prefixlen;
119
120 /* copy iovar name including null */
121 memcpy(p, name, namelen);
122 p += namelen;
123
124 /* bss config index as first data */
125 bssidx_le = cpu_to_le32(bssidx);
126 memcpy(p, &bssidx_le, sizeof(bssidx_le));
127 p += sizeof(bssidx_le);
128
129 /* parameter buffer follows */
130 if (datalen)
131 memcpy(p, data, datalen);
132
133 return iolen;
134
135}
136
89bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 137bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
90 struct sk_buff *pkt, int prec) 138 struct sk_buff *pkt, int prec)
91{ 139{
@@ -205,7 +253,8 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
205 BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, { 253 BRCMF_E_ACTION_FRAME_COMPLETE, "ACTION FRAME TX COMPLETE"}, {
206 BRCMF_E_IF, "IF"}, { 254 BRCMF_E_IF, "IF"}, {
207 BRCMF_E_RSSI, "RSSI"}, { 255 BRCMF_E_RSSI, "RSSI"}, {
208 BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"} 256 BRCMF_E_PFN_SCAN_COMPLETE, "SCAN_COMPLETE"}, {
257 BRCMF_E_ESCAN_RESULT, "ESCAN_RESULT"}
209 }; 258 };
210 uint event_type, flags, auth_type, datalen; 259 uint event_type, flags, auth_type, datalen;
211 static u32 seqnum_prev; 260 static u32 seqnum_prev;
@@ -350,6 +399,11 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
350 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); 399 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
351 break; 400 break;
352 401
402 case BRCMF_E_ESCAN_RESULT:
403 brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name);
404 datalen = 0;
405 break;
406
353 case BRCMF_E_PFN_NET_FOUND: 407 case BRCMF_E_PFN_NET_FOUND:
354 case BRCMF_E_PFN_NET_LOST: 408 case BRCMF_E_PFN_NET_LOST:
355 case BRCMF_E_PFN_SCAN_COMPLETE: 409 case BRCMF_E_PFN_SCAN_COMPLETE:
@@ -425,13 +479,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data)
425 } 479 }
426 480
427 /* show any appended data */ 481 /* show any appended data */
428 if (datalen) { 482 brcmf_dbg_hex_dump(datalen, event_data, datalen, "Received data");
429 buf = (unsigned char *) event_data;
430 brcmf_dbg(EVENT, " data (%d) : ", datalen);
431 for (i = 0; i < datalen; i++)
432 brcmf_dbg(EVENT, " 0x%02x ", *buf++);
433 brcmf_dbg(EVENT, "\n");
434 }
435} 483}
436#endif /* DEBUG */ 484#endif /* DEBUG */
437 485
@@ -522,8 +570,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata,
522 } 570 }
523 571
524#ifdef DEBUG 572#ifdef DEBUG
525 brcmf_c_show_host_event(event, event_data); 573 if (BRCMF_EVENT_ON())
526#endif /* DEBUG */ 574 brcmf_c_show_host_event(event, event_data);
575#endif /* DEBUG */
527 576
528 return 0; 577 return 0;
529} 578}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index b784920532d3..fb508c2256dd 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -55,6 +55,7 @@ do { \
55#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL) 55#define BRCMF_HDRS_ON() (brcmf_msg_level & BRCMF_HDRS_VAL)
56#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) 56#define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL)
57#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) 57#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
58#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL)
58 59
59#else /* (defined DEBUG) || (defined DEBUG) */ 60#else /* (defined DEBUG) || (defined DEBUG) */
60 61
@@ -65,6 +66,7 @@ do { \
65#define BRCMF_HDRS_ON() 0 66#define BRCMF_HDRS_ON() 0
66#define BRCMF_BYTES_ON() 0 67#define BRCMF_BYTES_ON() 0
67#define BRCMF_GLOM_ON() 0 68#define BRCMF_GLOM_ON() 0
69#define BRCMF_EVENT_ON() 0
68 70
69#endif /* defined(DEBUG) */ 71#endif /* defined(DEBUG) */
70 72
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 9ab24528f9b9..d7c76ce9d8cb 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -272,30 +272,6 @@ static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
272 schedule_work(&drvr->multicast_work); 272 schedule_work(&drvr->multicast_work);
273} 273}
274 274
275int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf)
276{
277 /* Reject if down */
278 if (!drvr->bus_if->drvr_up || (drvr->bus_if->state == BRCMF_BUS_DOWN))
279 return -ENODEV;
280
281 /* Update multicast statistic */
282 if (pktbuf->len >= ETH_ALEN) {
283 u8 *pktdata = (u8 *) (pktbuf->data);
284 struct ethhdr *eh = (struct ethhdr *)pktdata;
285
286 if (is_multicast_ether_addr(eh->h_dest))
287 drvr->tx_multicast++;
288 if (ntohs(eh->h_proto) == ETH_P_PAE)
289 atomic_inc(&drvr->pend_8021x_cnt);
290 }
291
292 /* If the protocol uses a data header, apply it */
293 brcmf_proto_hdrpush(drvr, ifidx, pktbuf);
294
295 /* Use bus module to send data frame */
296 return drvr->bus_if->brcmf_bus_txdata(drvr->dev, pktbuf);
297}
298
299static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev) 275static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
300{ 276{
301 int ret; 277 int ret;
@@ -338,7 +314,22 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)
338 } 314 }
339 } 315 }
340 316
341 ret = brcmf_sendpkt(drvr, ifp->idx, skb); 317 /* Update multicast statistic */
318 if (skb->len >= ETH_ALEN) {
319 u8 *pktdata = (u8 *)(skb->data);
320 struct ethhdr *eh = (struct ethhdr *)pktdata;
321
322 if (is_multicast_ether_addr(eh->h_dest))
323 drvr->tx_multicast++;
324 if (ntohs(eh->h_proto) == ETH_P_PAE)
325 atomic_inc(&drvr->pend_8021x_cnt);
326 }
327
328 /* If the protocol uses a data header, apply it */
329 brcmf_proto_hdrpush(drvr, ifp->idx, skb);
330
331 /* Use bus module to send data frame */
332 ret = drvr->bus_if->brcmf_bus_txdata(drvr->dev, skb);
342 333
343done: 334done:
344 if (ret) 335 if (ret)
@@ -350,19 +341,23 @@ done:
350 return 0; 341 return 0;
351} 342}
352 343
353void brcmf_txflowcontrol(struct device *dev, int ifidx, bool state) 344void brcmf_txflowblock(struct device *dev, bool state)
354{ 345{
355 struct net_device *ndev; 346 struct net_device *ndev;
356 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 347 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
357 struct brcmf_pub *drvr = bus_if->drvr; 348 struct brcmf_pub *drvr = bus_if->drvr;
349 int i;
358 350
359 brcmf_dbg(TRACE, "Enter\n"); 351 brcmf_dbg(TRACE, "Enter\n");
360 352
361 ndev = drvr->iflist[ifidx]->ndev; 353 for (i = 0; i < BRCMF_MAX_IFS; i++)
362 if (state == ON) 354 if (drvr->iflist[i]) {
363 netif_stop_queue(ndev); 355 ndev = drvr->iflist[i]->ndev;
364 else 356 if (state)
365 netif_wake_queue(ndev); 357 netif_stop_queue(ndev);
358 else
359 netif_wake_queue(ndev);
360 }
366} 361}
367 362
368static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx, 363static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
@@ -775,6 +770,14 @@ done:
775 return err; 770 return err;
776} 771}
777 772
773int brcmf_netlink_dcmd(struct net_device *ndev, struct brcmf_dcmd *dcmd)
774{
775 brcmf_dbg(TRACE, "enter: cmd %x buf %p len %d\n",
776 dcmd->cmd, dcmd->buf, dcmd->len);
777
778 return brcmf_exec_dcmd(ndev, dcmd->cmd, dcmd->buf, dcmd->len);
779}
780
778static int brcmf_netdev_stop(struct net_device *ndev) 781static int brcmf_netdev_stop(struct net_device *ndev)
779{ 782{
780 struct brcmf_if *ifp = netdev_priv(ndev); 783 struct brcmf_if *ifp = netdev_priv(ndev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 472f2ef5c652..3564686add9a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -482,6 +482,15 @@ struct sdpcm_shared_le {
482 __le32 brpt_addr; 482 __le32 brpt_addr;
483}; 483};
484 484
485/* SDIO read frame info */
486struct brcmf_sdio_read {
487 u8 seq_num;
488 u8 channel;
489 u16 len;
490 u16 len_left;
491 u16 len_nxtfrm;
492 u8 dat_offset;
493};
485 494
486/* misc chip info needed by some of the routines */ 495/* misc chip info needed by some of the routines */
487/* Private data for SDIO bus interaction */ 496/* Private data for SDIO bus interaction */
@@ -494,9 +503,8 @@ struct brcmf_sdio {
494 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ 503 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
495 504
496 u32 hostintmask; /* Copy of Host Interrupt Mask */ 505 u32 hostintmask; /* Copy of Host Interrupt Mask */
497 u32 intstatus; /* Intstatus bits (events) pending */ 506 atomic_t intstatus; /* Intstatus bits (events) pending */
498 bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ 507 atomic_t fcstate; /* State of dongle flow-control */
499 bool fcstate; /* State of dongle flow-control */
500 508
501 uint blocksize; /* Block size of SDIO transfers */ 509 uint blocksize; /* Block size of SDIO transfers */
502 uint roundup; /* Max roundup limit */ 510 uint roundup; /* Max roundup limit */
@@ -508,9 +516,11 @@ struct brcmf_sdio {
508 516
509 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN]; 517 u8 hdrbuf[MAX_HDR_READ + BRCMF_SDALIGN];
510 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */ 518 u8 *rxhdr; /* Header of current rx frame (in hdrbuf) */
511 u16 nextlen; /* Next Read Len from last header */
512 u8 rx_seq; /* Receive sequence number (expected) */ 519 u8 rx_seq; /* Receive sequence number (expected) */
520 struct brcmf_sdio_read cur_read;
521 /* info of current read frame */
513 bool rxskip; /* Skip receive (awaiting NAK ACK) */ 522 bool rxskip; /* Skip receive (awaiting NAK ACK) */
523 bool rxpending; /* Data frame pending in dongle */
514 524
515 uint rxbound; /* Rx frames to read before resched */ 525 uint rxbound; /* Rx frames to read before resched */
516 uint txbound; /* Tx frames to send before resched */ 526 uint txbound; /* Tx frames to send before resched */
@@ -531,7 +541,7 @@ struct brcmf_sdio {
531 541
532 bool intr; /* Use interrupts */ 542 bool intr; /* Use interrupts */
533 bool poll; /* Use polling */ 543 bool poll; /* Use polling */
534 bool ipend; /* Device interrupt is pending */ 544 atomic_t ipend; /* Device interrupt is pending */
535 uint spurious; /* Count of spurious interrupts */ 545 uint spurious; /* Count of spurious interrupts */
536 uint pollrate; /* Ticks between device polls */ 546 uint pollrate; /* Ticks between device polls */
537 uint polltick; /* Tick counter */ 547 uint polltick; /* Tick counter */
@@ -549,12 +559,9 @@ struct brcmf_sdio {
549 s32 idleclock; /* How to set bus driver when idle */ 559 s32 idleclock; /* How to set bus driver when idle */
550 s32 sd_rxchain; 560 s32 sd_rxchain;
551 bool use_rxchain; /* If brcmf should use PKT chains */ 561 bool use_rxchain; /* If brcmf should use PKT chains */
552 bool sleeping; /* Is SDIO bus sleeping? */
553 bool rxflow_mode; /* Rx flow control mode */ 562 bool rxflow_mode; /* Rx flow control mode */
554 bool rxflow; /* Is rx flow control on */ 563 bool rxflow; /* Is rx flow control on */
555 bool alp_only; /* Don't use HT clock (ALP only) */ 564 bool alp_only; /* Don't use HT clock (ALP only) */
556/* Field to decide if rx of control frames happen in rxbuf or lb-pool */
557 bool usebufpool;
558 565
559 u8 *ctrl_frame_buf; 566 u8 *ctrl_frame_buf;
560 u32 ctrl_frame_len; 567 u32 ctrl_frame_len;
@@ -570,8 +577,8 @@ struct brcmf_sdio {
570 bool wd_timer_valid; 577 bool wd_timer_valid;
571 uint save_ms; 578 uint save_ms;
572 579
573 struct task_struct *dpc_tsk; 580 struct workqueue_struct *brcmf_wq;
574 struct completion dpc_wait; 581 struct work_struct datawork;
575 struct list_head dpc_tsklst; 582 struct list_head dpc_tsklst;
576 spinlock_t dpc_tl_lock; 583 spinlock_t dpc_tl_lock;
577 584
@@ -657,15 +664,6 @@ w_sdreg32(struct brcmf_sdio *bus, u32 regval, u32 reg_offset)
657 664
658#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) 665#define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE)
659 666
660/* Packet free applicable unconditionally for sdio and sdspi.
661 * Conditional if bufpool was present for gspi bus.
662 */
663static void brcmf_sdbrcm_pktfree2(struct brcmf_sdio *bus, struct sk_buff *pkt)
664{
665 if (bus->usebufpool)
666 brcmu_pkt_buf_free_skb(pkt);
667}
668
669/* Turn backplane clock on or off */ 667/* Turn backplane clock on or off */
670static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) 668static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok)
671{ 669{
@@ -853,81 +851,6 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
853 return 0; 851 return 0;
854} 852}
855 853
856static int brcmf_sdbrcm_bussleep(struct brcmf_sdio *bus, bool sleep)
857{
858 int ret;
859
860 brcmf_dbg(INFO, "request %s (currently %s)\n",
861 sleep ? "SLEEP" : "WAKE",
862 bus->sleeping ? "SLEEP" : "WAKE");
863
864 /* Done if we're already in the requested state */
865 if (sleep == bus->sleeping)
866 return 0;
867
868 /* Going to sleep: set the alarm and turn off the lights... */
869 if (sleep) {
870 /* Don't sleep if something is pending */
871 if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq))
872 return -EBUSY;
873
874 /* Make sure the controller has the bus up */
875 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
876
877 /* Tell device to start using OOB wakeup */
878 ret = w_sdreg32(bus, SMB_USE_OOB,
879 offsetof(struct sdpcmd_regs, tosbmailbox));
880 if (ret != 0)
881 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n");
882
883 /* Turn off our contribution to the HT clock request */
884 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
885
886 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
887 SBSDIO_FORCE_HW_CLKREQ_OFF, NULL);
888
889 /* Isolate the bus */
890 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,
891 SBSDIO_DEVCTL_PADS_ISO, NULL);
892
893 /* Change state */
894 bus->sleeping = true;
895
896 } else {
897 /* Waking up: bus power up is ok, set local state */
898
899 brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
900 0, NULL);
901
902 /* Make sure the controller has the bus up */
903 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
904
905 /* Send misc interrupt to indicate OOB not needed */
906 ret = w_sdreg32(bus, 0,
907 offsetof(struct sdpcmd_regs, tosbmailboxdata));
908 if (ret == 0)
909 ret = w_sdreg32(bus, SMB_DEV_INT,
910 offsetof(struct sdpcmd_regs, tosbmailbox));
911
912 if (ret != 0)
913 brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n");
914
915 /* Make sure we have SD bus access */
916 brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
917
918 /* Change state */
919 bus->sleeping = false;
920 }
921
922 return 0;
923}
924
925static void bus_wake(struct brcmf_sdio *bus)
926{
927 if (bus->sleeping)
928 brcmf_sdbrcm_bussleep(bus, false);
929}
930
931static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus) 854static u32 brcmf_sdbrcm_hostmail(struct brcmf_sdio *bus)
932{ 855{
933 u32 intstatus = 0; 856 u32 intstatus = 0;
@@ -1056,7 +979,7 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_sdio *bus, bool abort, bool rtx)
1056 } 979 }
1057 980
1058 /* Clear partial in any case */ 981 /* Clear partial in any case */
1059 bus->nextlen = 0; 982 bus->cur_read.len = 0;
1060 983
1061 /* If we can't reach the device, signal failure */ 984 /* If we can't reach the device, signal failure */
1062 if (err) 985 if (err)
@@ -1108,6 +1031,96 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
1108 } 1031 }
1109} 1032}
1110 1033
1034static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
1035 struct brcmf_sdio_read *rd)
1036{
1037 u16 len, checksum;
1038 u8 rx_seq, fc, tx_seq_max;
1039
1040 /*
1041 * 4 bytes hardware header (frame tag)
1042 * Byte 0~1: Frame length
1043 * Byte 2~3: Checksum, bit-wise inverse of frame length
1044 */
1045 len = get_unaligned_le16(header);
1046 checksum = get_unaligned_le16(header + sizeof(u16));
1047 /* All zero means no more to read */
1048 if (!(len | checksum)) {
1049 bus->rxpending = false;
1050 return false;
1051 }
1052 if ((u16)(~(len ^ checksum))) {
1053 brcmf_dbg(ERROR, "HW header checksum error\n");
1054 bus->sdcnt.rx_badhdr++;
1055 brcmf_sdbrcm_rxfail(bus, false, false);
1056 return false;
1057 }
1058 if (len < SDPCM_HDRLEN) {
1059 brcmf_dbg(ERROR, "HW header length error\n");
1060 return false;
1061 }
1062 rd->len = len;
1063
1064 /*
1065 * 8 bytes hardware header
1066 * Byte 0: Rx sequence number
1067 * Byte 1: 4 MSB Channel number, 4 LSB arbitrary flag
1068 * Byte 2: Length of next data frame
1069 * Byte 3: Data offset
1070 * Byte 4: Flow control bits
1071 * Byte 5: Maximum Sequence number allow for Tx
1072 * Byte 6~7: Reserved
1073 */
1074 rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]);
1075 rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]);
1076 if (len > MAX_RX_DATASZ && rd->channel != SDPCM_CONTROL_CHANNEL) {
1077 brcmf_dbg(ERROR, "HW header length too long\n");
1078 bus->sdiodev->bus_if->dstats.rx_errors++;
1079 bus->sdcnt.rx_toolong++;
1080 brcmf_sdbrcm_rxfail(bus, false, false);
1081 rd->len = 0;
1082 return false;
1083 }
1084 rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]);
1085 if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
1086 brcmf_dbg(ERROR, "seq %d: bad data offset\n", rx_seq);
1087 bus->sdcnt.rx_badhdr++;
1088 brcmf_sdbrcm_rxfail(bus, false, false);
1089 rd->len = 0;
1090 return false;
1091 }
1092 if (rd->seq_num != rx_seq) {
1093 brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n",
1094 rx_seq, rd->seq_num);
1095 bus->sdcnt.rx_badseq++;
1096 rd->seq_num = rx_seq;
1097 }
1098 rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
1099 if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
1100 /* only warm for NON glom packet */
1101 if (rd->channel != SDPCM_GLOM_CHANNEL)
1102 brcmf_dbg(ERROR, "seq %d: next length error\n", rx_seq);
1103 rd->len_nxtfrm = 0;
1104 }
1105 fc = SDPCM_FCMASK_VALUE(&header[SDPCM_FRAMETAG_LEN]);
1106 if (bus->flowcontrol != fc) {
1107 if (~bus->flowcontrol & fc)
1108 bus->sdcnt.fc_xoff++;
1109 if (bus->flowcontrol & ~fc)
1110 bus->sdcnt.fc_xon++;
1111 bus->sdcnt.fc_rcvd++;
1112 bus->flowcontrol = fc;
1113 }
1114 tx_seq_max = SDPCM_WINDOW_VALUE(&header[SDPCM_FRAMETAG_LEN]);
1115 if ((u8)(tx_seq_max - bus->tx_seq) > 0x40) {
1116 brcmf_dbg(ERROR, "seq %d: max tx seq number error\n", rx_seq);
1117 tx_seq_max = bus->tx_seq + 2;
1118 }
1119 bus->tx_max = tx_seq_max;
1120
1121 return true;
1122}
1123
1111static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) 1124static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1112{ 1125{
1113 u16 dlen, totlen; 1126 u16 dlen, totlen;
@@ -1122,6 +1135,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1122 1135
1123 int ifidx = 0; 1136 int ifidx = 0;
1124 bool usechain = bus->use_rxchain; 1137 bool usechain = bus->use_rxchain;
1138 u16 next_len;
1125 1139
1126 /* If packets, issue read(s) and send up packet chain */ 1140 /* If packets, issue read(s) and send up packet chain */
1127 /* Return sequence numbers consumed? */ 1141 /* Return sequence numbers consumed? */
@@ -1185,10 +1199,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1185 if (pnext) { 1199 if (pnext) {
1186 brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n", 1200 brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n",
1187 totlen, num); 1201 totlen, num);
1188 if (BRCMF_GLOM_ON() && bus->nextlen && 1202 if (BRCMF_GLOM_ON() && bus->cur_read.len &&
1189 totlen != bus->nextlen) { 1203 totlen != bus->cur_read.len) {
1190 brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", 1204 brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
1191 bus->nextlen, totlen, rxseq); 1205 bus->cur_read.len, totlen, rxseq);
1192 } 1206 }
1193 pfirst = pnext = NULL; 1207 pfirst = pnext = NULL;
1194 } else { 1208 } else {
@@ -1199,7 +1213,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1199 /* Done with descriptor packet */ 1213 /* Done with descriptor packet */
1200 brcmu_pkt_buf_free_skb(bus->glomd); 1214 brcmu_pkt_buf_free_skb(bus->glomd);
1201 bus->glomd = NULL; 1215 bus->glomd = NULL;
1202 bus->nextlen = 0; 1216 bus->cur_read.len = 0;
1203 } 1217 }
1204 1218
1205 /* Ok -- either we just generated a packet chain, 1219 /* Ok -- either we just generated a packet chain,
@@ -1272,12 +1286,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1272 1286
1273 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); 1287 chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]);
1274 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); 1288 seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]);
1275 bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; 1289 next_len = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
1276 if ((bus->nextlen << 4) > MAX_RX_DATASZ) { 1290 if ((next_len << 4) > MAX_RX_DATASZ) {
1277 brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n", 1291 brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n",
1278 bus->nextlen, seq); 1292 next_len, seq);
1279 bus->nextlen = 0; 1293 next_len = 0;
1280 } 1294 }
1295 bus->cur_read.len = next_len << 4;
1281 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); 1296 doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1282 txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); 1297 txmax = SDPCM_WINDOW_VALUE(&dptr[SDPCM_FRAMETAG_LEN]);
1283 1298
@@ -1378,7 +1393,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
1378 bus->sdcnt.rxglomfail++; 1393 bus->sdcnt.rxglomfail++;
1379 brcmf_sdbrcm_free_glom(bus); 1394 brcmf_sdbrcm_free_glom(bus);
1380 } 1395 }
1381 bus->nextlen = 0; 1396 bus->cur_read.len = 0;
1382 return 0; 1397 return 0;
1383 } 1398 }
1384 1399
@@ -1573,422 +1588,166 @@ static void brcmf_pad(struct brcmf_sdio *bus, u16 *pad, u16 *rdlen)
1573 } 1588 }
1574} 1589}
1575 1590
1576static void 1591static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
1577brcmf_alloc_pkt_and_read(struct brcmf_sdio *bus, u16 rdlen,
1578 struct sk_buff **pkt, u8 **rxbuf)
1579{ 1592{
1580 int sdret; /* Return code from calls */
1581
1582 *pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN);
1583 if (*pkt == NULL)
1584 return;
1585
1586 pkt_align(*pkt, rdlen, BRCMF_SDALIGN);
1587 *rxbuf = (u8 *) ((*pkt)->data);
1588 /* Read the entire frame */
1589 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1590 SDIO_FUNC_2, F2SYNC, *pkt);
1591 bus->sdcnt.f2rxdata++;
1592
1593 if (sdret < 0) {
1594 brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n",
1595 rdlen, sdret);
1596 brcmu_pkt_buf_free_skb(*pkt);
1597 bus->sdiodev->bus_if->dstats.rx_errors++;
1598 /* Force retry w/normal header read.
1599 * Don't attempt NAK for
1600 * gSPI
1601 */
1602 brcmf_sdbrcm_rxfail(bus, true, true);
1603 *pkt = NULL;
1604 }
1605}
1606
1607/* Checks the header */
1608static int
1609brcmf_check_rxbuf(struct brcmf_sdio *bus, struct sk_buff *pkt, u8 *rxbuf,
1610 u8 rxseq, u16 nextlen, u16 *len)
1611{
1612 u16 check;
1613 bool len_consistent; /* Result of comparing readahead len and
1614 len from hw-hdr */
1615
1616 memcpy(bus->rxhdr, rxbuf, SDPCM_HDRLEN);
1617
1618 /* Extract hardware header fields */
1619 *len = get_unaligned_le16(bus->rxhdr);
1620 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
1621
1622 /* All zeros means readahead info was bad */
1623 if (!(*len | check)) {
1624 brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n");
1625 goto fail;
1626 }
1627
1628 /* Validate check bytes */
1629 if ((u16)~(*len ^ check)) {
1630 brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n",
1631 nextlen, *len, check);
1632 bus->sdcnt.rx_badhdr++;
1633 brcmf_sdbrcm_rxfail(bus, false, false);
1634 goto fail;
1635 }
1636
1637 /* Validate frame length */
1638 if (*len < SDPCM_HDRLEN) {
1639 brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n",
1640 *len);
1641 goto fail;
1642 }
1643
1644 /* Check for consistency with readahead info */
1645 len_consistent = (nextlen != (roundup(*len, 16) >> 4));
1646 if (len_consistent) {
1647 /* Mismatch, force retry w/normal
1648 header (may be >4K) */
1649 brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n",
1650 nextlen, *len, roundup(*len, 16),
1651 rxseq);
1652 brcmf_sdbrcm_rxfail(bus, true, true);
1653 goto fail;
1654 }
1655
1656 return 0;
1657
1658fail:
1659 brcmf_sdbrcm_pktfree2(bus, pkt);
1660 return -EINVAL;
1661}
1662
1663/* Return true if there may be more frames to read */
1664static uint
1665brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished)
1666{
1667 u16 len, check; /* Extracted hardware header fields */
1668 u8 chan, seq, doff; /* Extracted software header fields */
1669 u8 fcbits; /* Extracted fcbits from software header */
1670
1671 struct sk_buff *pkt; /* Packet for event or data frames */ 1593 struct sk_buff *pkt; /* Packet for event or data frames */
1672 u16 pad; /* Number of pad bytes to read */ 1594 u16 pad; /* Number of pad bytes to read */
1673 u16 rdlen; /* Total number of bytes to read */
1674 u8 rxseq; /* Next sequence number to expect */
1675 uint rxleft = 0; /* Remaining number of frames allowed */ 1595 uint rxleft = 0; /* Remaining number of frames allowed */
1676 int sdret; /* Return code from calls */ 1596 int sdret; /* Return code from calls */
1677 u8 txmax; /* Maximum tx sequence offered */
1678 u8 *rxbuf;
1679 int ifidx = 0; 1597 int ifidx = 0;
1680 uint rxcount = 0; /* Total frames read */ 1598 uint rxcount = 0; /* Total frames read */
1599 struct brcmf_sdio_read *rd = &bus->cur_read, rd_new;
1600 u8 head_read = 0;
1681 1601
1682 brcmf_dbg(TRACE, "Enter\n"); 1602 brcmf_dbg(TRACE, "Enter\n");
1683 1603
1684 /* Not finished unless we encounter no more frames indication */ 1604 /* Not finished unless we encounter no more frames indication */
1685 *finished = false; 1605 bus->rxpending = true;
1686 1606
1687 for (rxseq = bus->rx_seq, rxleft = maxframes; 1607 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;
1688 !bus->rxskip && rxleft && 1608 !bus->rxskip && rxleft &&
1689 bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN; 1609 bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;
1690 rxseq++, rxleft--) { 1610 rd->seq_num++, rxleft--) {
1691 1611
1692 /* Handle glomming separately */ 1612 /* Handle glomming separately */
1693 if (bus->glomd || !skb_queue_empty(&bus->glom)) { 1613 if (bus->glomd || !skb_queue_empty(&bus->glom)) {
1694 u8 cnt; 1614 u8 cnt;
1695 brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", 1615 brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
1696 bus->glomd, skb_peek(&bus->glom)); 1616 bus->glomd, skb_peek(&bus->glom));
1697 cnt = brcmf_sdbrcm_rxglom(bus, rxseq); 1617 cnt = brcmf_sdbrcm_rxglom(bus, rd->seq_num);
1698 brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); 1618 brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
1699 rxseq += cnt - 1; 1619 rd->seq_num += cnt - 1;
1700 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; 1620 rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1;
1701 continue; 1621 continue;
1702 } 1622 }
1703 1623
1704 /* Try doing single read if we can */ 1624 rd->len_left = rd->len;
1705 if (bus->nextlen) { 1625 /* read header first for unknow frame length */
1706 u16 nextlen = bus->nextlen; 1626 if (!rd->len) {
1707 bus->nextlen = 0; 1627 sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
1708 1628 bus->sdiodev->sbwad,
1709 rdlen = len = nextlen << 4; 1629 SDIO_FUNC_2, F2SYNC,
1710 brcmf_pad(bus, &pad, &rdlen); 1630 bus->rxhdr,
1711 1631 BRCMF_FIRSTREAD);
1712 /* 1632 bus->sdcnt.f2rxhdrs++;
1713 * After the frame is received we have to 1633 if (sdret < 0) {
1714 * distinguish whether it is data 1634 brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n",
1715 * or non-data frame. 1635 sdret);
1716 */ 1636 bus->sdcnt.rx_hdrfail++;
1717 brcmf_alloc_pkt_and_read(bus, rdlen, &pkt, &rxbuf); 1637 brcmf_sdbrcm_rxfail(bus, true, true);
1718 if (pkt == NULL) {
1719 /* Give up on data, request rtx of events */
1720 brcmf_dbg(ERROR, "(nextlen): brcmf_alloc_pkt_and_read failed: len %d rdlen %d expected rxseq %d\n",
1721 len, rdlen, rxseq);
1722 continue;
1723 }
1724
1725 if (brcmf_check_rxbuf(bus, pkt, rxbuf, rxseq, nextlen,
1726 &len) < 0)
1727 continue; 1638 continue;
1728
1729 /* Extract software header fields */
1730 chan = SDPCM_PACKET_CHANNEL(
1731 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1732 seq = SDPCM_PACKET_SEQUENCE(
1733 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1734 doff = SDPCM_DOFFSET_VALUE(
1735 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1736 txmax = SDPCM_WINDOW_VALUE(
1737 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1738
1739 bus->nextlen =
1740 bus->rxhdr[SDPCM_FRAMETAG_LEN +
1741 SDPCM_NEXTLEN_OFFSET];
1742 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
1743 brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
1744 bus->nextlen, seq);
1745 bus->nextlen = 0;
1746 } 1639 }
1747 1640
1748 bus->sdcnt.rx_readahead_cnt++; 1641 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
1749
1750 /* Handle Flow Control */
1751 fcbits = SDPCM_FCMASK_VALUE(
1752 &bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1753
1754 if (bus->flowcontrol != fcbits) {
1755 if (~bus->flowcontrol & fcbits)
1756 bus->sdcnt.fc_xoff++;
1757
1758 if (bus->flowcontrol & ~fcbits)
1759 bus->sdcnt.fc_xon++;
1760
1761 bus->sdcnt.fc_rcvd++;
1762 bus->flowcontrol = fcbits;
1763 }
1764
1765 /* Check and update sequence number */
1766 if (rxseq != seq) {
1767 brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n",
1768 seq, rxseq);
1769 bus->sdcnt.rx_badseq++;
1770 rxseq = seq;
1771 }
1772
1773 /* Check window for sanity */
1774 if ((u8) (txmax - bus->tx_seq) > 0x40) {
1775 brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n",
1776 txmax, bus->tx_seq);
1777 txmax = bus->tx_seq + 2;
1778 }
1779 bus->tx_max = txmax;
1780
1781 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
1782 rxbuf, len, "Rx Data:\n");
1783 brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
1784 BRCMF_DATA_ON()) &&
1785 BRCMF_HDRS_ON(),
1786 bus->rxhdr, SDPCM_HDRLEN, 1642 bus->rxhdr, SDPCM_HDRLEN,
1787 "RxHdr:\n"); 1643 "RxHdr:\n");
1788 1644
1789 if (chan == SDPCM_CONTROL_CHANNEL) { 1645 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd)) {
1790 brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n", 1646 if (!bus->rxpending)
1791 seq); 1647 break;
1792 /* Force retry w/normal header read */ 1648 else
1793 bus->nextlen = 0; 1649 continue;
1794 brcmf_sdbrcm_rxfail(bus, false, true);
1795 brcmf_sdbrcm_pktfree2(bus, pkt);
1796 continue;
1797 } 1650 }
1798 1651
1799 /* Validate data offset */ 1652 if (rd->channel == SDPCM_CONTROL_CHANNEL) {
1800 if ((doff < SDPCM_HDRLEN) || (doff > len)) { 1653 brcmf_sdbrcm_read_control(bus, bus->rxhdr,
1801 brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n", 1654 rd->len,
1802 doff, len, SDPCM_HDRLEN); 1655 rd->dat_offset);
1803 brcmf_sdbrcm_rxfail(bus, false, false); 1656 /* prepare the descriptor for the next read */
1804 brcmf_sdbrcm_pktfree2(bus, pkt); 1657 rd->len = rd->len_nxtfrm << 4;
1658 rd->len_nxtfrm = 0;
1659 /* treat all packet as event if we don't know */
1660 rd->channel = SDPCM_EVENT_CHANNEL;
1805 continue; 1661 continue;
1806 } 1662 }
1807 1663 rd->len_left = rd->len > BRCMF_FIRSTREAD ?
1808 /* All done with this one -- now deliver the packet */ 1664 rd->len - BRCMF_FIRSTREAD : 0;
1809 goto deliver; 1665 head_read = BRCMF_FIRSTREAD;
1810 }
1811
1812 /* Read frame header (hardware and software) */
1813 sdret = brcmf_sdcard_recv_buf(bus->sdiodev, bus->sdiodev->sbwad,
1814 SDIO_FUNC_2, F2SYNC, bus->rxhdr,
1815 BRCMF_FIRSTREAD);
1816 bus->sdcnt.f2rxhdrs++;
1817
1818 if (sdret < 0) {
1819 brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret);
1820 bus->sdcnt.rx_hdrfail++;
1821 brcmf_sdbrcm_rxfail(bus, true, true);
1822 continue;
1823 }
1824 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(),
1825 bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n");
1826
1827
1828 /* Extract hardware header fields */
1829 len = get_unaligned_le16(bus->rxhdr);
1830 check = get_unaligned_le16(bus->rxhdr + sizeof(u16));
1831
1832 /* All zeros means no more frames */
1833 if (!(len | check)) {
1834 *finished = true;
1835 break;
1836 }
1837
1838 /* Validate check bytes */
1839 if ((u16) ~(len ^ check)) {
1840 brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n",
1841 len, check);
1842 bus->sdcnt.rx_badhdr++;
1843 brcmf_sdbrcm_rxfail(bus, false, false);
1844 continue;
1845 }
1846
1847 /* Validate frame length */
1848 if (len < SDPCM_HDRLEN) {
1849 brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len);
1850 continue;
1851 }
1852
1853 /* Extract software header fields */
1854 chan = SDPCM_PACKET_CHANNEL(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1855 seq = SDPCM_PACKET_SEQUENCE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1856 doff = SDPCM_DOFFSET_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1857 txmax = SDPCM_WINDOW_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1858
1859 /* Validate data offset */
1860 if ((doff < SDPCM_HDRLEN) || (doff > len)) {
1861 brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n",
1862 doff, len, SDPCM_HDRLEN, seq);
1863 bus->sdcnt.rx_badhdr++;
1864 brcmf_sdbrcm_rxfail(bus, false, false);
1865 continue;
1866 }
1867
1868 /* Save the readahead length if there is one */
1869 bus->nextlen =
1870 bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
1871 if ((bus->nextlen << 4) > MAX_RX_DATASZ) {
1872 brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n",
1873 bus->nextlen, seq);
1874 bus->nextlen = 0;
1875 }
1876
1877 /* Handle Flow Control */
1878 fcbits = SDPCM_FCMASK_VALUE(&bus->rxhdr[SDPCM_FRAMETAG_LEN]);
1879
1880 if (bus->flowcontrol != fcbits) {
1881 if (~bus->flowcontrol & fcbits)
1882 bus->sdcnt.fc_xoff++;
1883
1884 if (bus->flowcontrol & ~fcbits)
1885 bus->sdcnt.fc_xon++;
1886
1887 bus->sdcnt.fc_rcvd++;
1888 bus->flowcontrol = fcbits;
1889 }
1890
1891 /* Check and update sequence number */
1892 if (rxseq != seq) {
1893 brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq);
1894 bus->sdcnt.rx_badseq++;
1895 rxseq = seq;
1896 }
1897
1898 /* Check window for sanity */
1899 if ((u8) (txmax - bus->tx_seq) > 0x40) {
1900 brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n",
1901 txmax, bus->tx_seq);
1902 txmax = bus->tx_seq + 2;
1903 }
1904 bus->tx_max = txmax;
1905
1906 /* Call a separate function for control frames */
1907 if (chan == SDPCM_CONTROL_CHANNEL) {
1908 brcmf_sdbrcm_read_control(bus, bus->rxhdr, len, doff);
1909 continue;
1910 }
1911
1912 /* precondition: chan is either SDPCM_DATA_CHANNEL,
1913 SDPCM_EVENT_CHANNEL, SDPCM_TEST_CHANNEL or
1914 SDPCM_GLOM_CHANNEL */
1915
1916 /* Length to read */
1917 rdlen = (len > BRCMF_FIRSTREAD) ? (len - BRCMF_FIRSTREAD) : 0;
1918
1919 /* May pad read to blocksize for efficiency */
1920 if (bus->roundup && bus->blocksize &&
1921 (rdlen > bus->blocksize)) {
1922 pad = bus->blocksize - (rdlen % bus->blocksize);
1923 if ((pad <= bus->roundup) && (pad < bus->blocksize) &&
1924 ((rdlen + pad + BRCMF_FIRSTREAD) < MAX_RX_DATASZ))
1925 rdlen += pad;
1926 } else if (rdlen % BRCMF_SDALIGN) {
1927 rdlen += BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN);
1928 } 1666 }
1929 1667
1930 /* Satisfy length-alignment requirements */ 1668 brcmf_pad(bus, &pad, &rd->len_left);
1931 if (rdlen & (ALIGNMENT - 1))
1932 rdlen = roundup(rdlen, ALIGNMENT);
1933
1934 if ((rdlen + BRCMF_FIRSTREAD) > MAX_RX_DATASZ) {
1935 /* Too long -- skip this frame */
1936 brcmf_dbg(ERROR, "too long: len %d rdlen %d\n",
1937 len, rdlen);
1938 bus->sdiodev->bus_if->dstats.rx_errors++;
1939 bus->sdcnt.rx_toolong++;
1940 brcmf_sdbrcm_rxfail(bus, false, false);
1941 continue;
1942 }
1943 1669
1944 pkt = brcmu_pkt_buf_get_skb(rdlen + 1670 pkt = brcmu_pkt_buf_get_skb(rd->len_left + head_read +
1945 BRCMF_FIRSTREAD + BRCMF_SDALIGN); 1671 BRCMF_SDALIGN);
1946 if (!pkt) { 1672 if (!pkt) {
1947 /* Give up on data, request rtx of events */ 1673 /* Give up on data, request rtx of events */
1948 brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n", 1674 brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed\n");
1949 rdlen, chan);
1950 bus->sdiodev->bus_if->dstats.rx_dropped++; 1675 bus->sdiodev->bus_if->dstats.rx_dropped++;
1951 brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan)); 1676 brcmf_sdbrcm_rxfail(bus, false,
1677 RETRYCHAN(rd->channel));
1952 continue; 1678 continue;
1953 } 1679 }
1680 skb_pull(pkt, head_read);
1681 pkt_align(pkt, rd->len_left, BRCMF_SDALIGN);
1954 1682
1955 /* Leave room for what we already read, and align remainder */
1956 skb_pull(pkt, BRCMF_FIRSTREAD);
1957 pkt_align(pkt, rdlen, BRCMF_SDALIGN);
1958
1959 /* Read the remaining frame data */
1960 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad, 1683 sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
1961 SDIO_FUNC_2, F2SYNC, pkt); 1684 SDIO_FUNC_2, F2SYNC, pkt);
1962 bus->sdcnt.f2rxdata++; 1685 bus->sdcnt.f2rxdata++;
1963 1686
1964 if (sdret < 0) { 1687 if (sdret < 0) {
1965 brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen, 1688 brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
1966 ((chan == SDPCM_EVENT_CHANNEL) ? "event" 1689 rd->len, rd->channel, sdret);
1967 : ((chan == SDPCM_DATA_CHANNEL) ? "data"
1968 : "test")), sdret);
1969 brcmu_pkt_buf_free_skb(pkt); 1690 brcmu_pkt_buf_free_skb(pkt);
1970 bus->sdiodev->bus_if->dstats.rx_errors++; 1691 bus->sdiodev->bus_if->dstats.rx_errors++;
1971 brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan)); 1692 brcmf_sdbrcm_rxfail(bus, true,
1693 RETRYCHAN(rd->channel));
1972 continue; 1694 continue;
1973 } 1695 }
1974 1696
1975 /* Copy the already-read portion */ 1697 if (head_read) {
1976 skb_push(pkt, BRCMF_FIRSTREAD); 1698 skb_push(pkt, head_read);
1977 memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); 1699 memcpy(pkt->data, bus->rxhdr, head_read);
1700 head_read = 0;
1701 } else {
1702 memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
1703 rd_new.seq_num = rd->seq_num;
1704 if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new)) {
1705 rd->len = 0;
1706 brcmu_pkt_buf_free_skb(pkt);
1707 }
1708 bus->sdcnt.rx_readahead_cnt++;
1709 if (rd->len != roundup(rd_new.len, 16)) {
1710 brcmf_dbg(ERROR, "frame length mismatch:read %d, should be %d\n",
1711 rd->len,
1712 roundup(rd_new.len, 16) >> 4);
1713 rd->len = 0;
1714 brcmf_sdbrcm_rxfail(bus, true, true);
1715 brcmu_pkt_buf_free_skb(pkt);
1716 continue;
1717 }
1718 rd->len_nxtfrm = rd_new.len_nxtfrm;
1719 rd->channel = rd_new.channel;
1720 rd->dat_offset = rd_new.dat_offset;
1721
1722 brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() &&
1723 BRCMF_DATA_ON()) &&
1724 BRCMF_HDRS_ON(),
1725 bus->rxhdr, SDPCM_HDRLEN,
1726 "RxHdr:\n");
1727
1728 if (rd_new.channel == SDPCM_CONTROL_CHANNEL) {
1729 brcmf_dbg(ERROR, "readahead on control packet %d?\n",
1730 rd_new.seq_num);
1731 /* Force retry w/normal header read */
1732 rd->len = 0;
1733 brcmf_sdbrcm_rxfail(bus, false, true);
1734 brcmu_pkt_buf_free_skb(pkt);
1735 continue;
1736 }
1737 }
1978 1738
1979 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), 1739 brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(),
1980 pkt->data, len, "Rx Data:\n"); 1740 pkt->data, rd->len, "Rx Data:\n");
1981 1741
1982deliver:
1983 /* Save superframe descriptor and allocate packet frame */ 1742 /* Save superframe descriptor and allocate packet frame */
1984 if (chan == SDPCM_GLOM_CHANNEL) { 1743 if (rd->channel == SDPCM_GLOM_CHANNEL) {
1985 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { 1744 if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) {
1986 brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", 1745 brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n",
1987 len); 1746 rd->len);
1988 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), 1747 brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
1989 pkt->data, len, 1748 pkt->data, rd->len,
1990 "Glom Data:\n"); 1749 "Glom Data:\n");
1991 __skb_trim(pkt, len); 1750 __skb_trim(pkt, rd->len);
1992 skb_pull(pkt, SDPCM_HDRLEN); 1751 skb_pull(pkt, SDPCM_HDRLEN);
1993 bus->glomd = pkt; 1752 bus->glomd = pkt;
1994 } else { 1753 } else {
@@ -1996,12 +1755,23 @@ deliver:
1996 "descriptor!\n", __func__); 1755 "descriptor!\n", __func__);
1997 brcmf_sdbrcm_rxfail(bus, false, false); 1756 brcmf_sdbrcm_rxfail(bus, false, false);
1998 } 1757 }
1758 /* prepare the descriptor for the next read */
1759 rd->len = rd->len_nxtfrm << 4;
1760 rd->len_nxtfrm = 0;
1761 /* treat all packet as event if we don't know */
1762 rd->channel = SDPCM_EVENT_CHANNEL;
1999 continue; 1763 continue;
2000 } 1764 }
2001 1765
2002 /* Fill in packet len and prio, deliver upward */ 1766 /* Fill in packet len and prio, deliver upward */
2003 __skb_trim(pkt, len); 1767 __skb_trim(pkt, rd->len);
2004 skb_pull(pkt, doff); 1768 skb_pull(pkt, rd->dat_offset);
1769
1770 /* prepare the descriptor for the next read */
1771 rd->len = rd->len_nxtfrm << 4;
1772 rd->len_nxtfrm = 0;
1773 /* treat all packet as event if we don't know */
1774 rd->channel = SDPCM_EVENT_CHANNEL;
2005 1775
2006 if (pkt->len == 0) { 1776 if (pkt->len == 0) {
2007 brcmu_pkt_buf_free_skb(pkt); 1777 brcmu_pkt_buf_free_skb(pkt);
@@ -2019,17 +1789,17 @@ deliver:
2019 brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt); 1789 brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
2020 down(&bus->sdsem); 1790 down(&bus->sdsem);
2021 } 1791 }
1792
2022 rxcount = maxframes - rxleft; 1793 rxcount = maxframes - rxleft;
2023 /* Message if we hit the limit */ 1794 /* Message if we hit the limit */
2024 if (!rxleft) 1795 if (!rxleft)
2025 brcmf_dbg(DATA, "hit rx limit of %d frames\n", 1796 brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes);
2026 maxframes);
2027 else 1797 else
2028 brcmf_dbg(DATA, "processed %d frames\n", rxcount); 1798 brcmf_dbg(DATA, "processed %d frames\n", rxcount);
2029 /* Back off rxseq if awaiting rtx, update rx_seq */ 1799 /* Back off rxseq if awaiting rtx, update rx_seq */
2030 if (bus->rxskip) 1800 if (bus->rxskip)
2031 rxseq--; 1801 rd->seq_num--;
2032 bus->rx_seq = rxseq; 1802 bus->rx_seq = rd->seq_num;
2033 1803
2034 return rxcount; 1804 return rxcount;
2035} 1805}
@@ -2227,7 +1997,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2227 if (ret != 0) 1997 if (ret != 0)
2228 break; 1998 break;
2229 if (intstatus & bus->hostintmask) 1999 if (intstatus & bus->hostintmask)
2230 bus->ipend = true; 2000 atomic_set(&bus->ipend, 1);
2231 } 2001 }
2232 } 2002 }
2233 2003
@@ -2235,8 +2005,8 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
2235 if (bus->sdiodev->bus_if->drvr_up && 2005 if (bus->sdiodev->bus_if->drvr_up &&
2236 (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) && 2006 (bus->sdiodev->bus_if->state == BRCMF_BUS_DATA) &&
2237 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) { 2007 bus->txoff && (pktq_len(&bus->txq) < TXLOW)) {
2238 bus->txoff = OFF; 2008 bus->txoff = false;
2239 brcmf_txflowcontrol(bus->sdiodev->dev, 0, OFF); 2009 brcmf_txflowblock(bus->sdiodev->dev, false);
2240 } 2010 }
2241 2011
2242 return cnt; 2012 return cnt;
@@ -2259,16 +2029,8 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
2259 bus->watchdog_tsk = NULL; 2029 bus->watchdog_tsk = NULL;
2260 } 2030 }
2261 2031
2262 if (bus->dpc_tsk && bus->dpc_tsk != current) {
2263 send_sig(SIGTERM, bus->dpc_tsk, 1);
2264 kthread_stop(bus->dpc_tsk);
2265 bus->dpc_tsk = NULL;
2266 }
2267
2268 down(&bus->sdsem); 2032 down(&bus->sdsem);
2269 2033
2270 bus_wake(bus);
2271
2272 /* Enable clock for device interrupts */ 2034 /* Enable clock for device interrupts */
2273 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2035 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2274 2036
@@ -2327,7 +2089,7 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
2327 unsigned long flags; 2089 unsigned long flags;
2328 2090
2329 spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); 2091 spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags);
2330 if (!bus->sdiodev->irq_en && !bus->ipend) { 2092 if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) {
2331 enable_irq(bus->sdiodev->irq); 2093 enable_irq(bus->sdiodev->irq);
2332 bus->sdiodev->irq_en = true; 2094 bus->sdiodev->irq_en = true;
2333 } 2095 }
@@ -2339,21 +2101,69 @@ static inline void brcmf_sdbrcm_clrintr(struct brcmf_sdio *bus)
2339} 2101}
2340#endif /* CONFIG_BRCMFMAC_SDIO_OOB */ 2102#endif /* CONFIG_BRCMFMAC_SDIO_OOB */
2341 2103
2342static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) 2104static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
2343{ 2105{
2344 u32 intstatus, newstatus = 0; 2106 struct list_head *new_hd;
2107 unsigned long flags;
2108
2109 if (in_interrupt())
2110 new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
2111 else
2112 new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
2113 if (new_hd == NULL)
2114 return;
2115
2116 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2117 list_add_tail(new_hd, &bus->dpc_tsklst);
2118 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2119}
2120
2121static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
2122{
2123 u8 idx;
2124 u32 addr;
2125 unsigned long val;
2126 int n, ret;
2127
2128 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
2129 addr = bus->ci->c_inf[idx].base +
2130 offsetof(struct sdpcmd_regs, intstatus);
2131
2132 ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, false);
2133 bus->sdcnt.f1regdata++;
2134 if (ret != 0)
2135 val = 0;
2136
2137 val &= bus->hostintmask;
2138 atomic_set(&bus->fcstate, !!(val & I_HMB_FC_STATE));
2139
2140 /* Clear interrupts */
2141 if (val) {
2142 ret = brcmf_sdio_regrw_helper(bus->sdiodev, addr, &val, true);
2143 bus->sdcnt.f1regdata++;
2144 }
2145
2146 if (ret) {
2147 atomic_set(&bus->intstatus, 0);
2148 } else if (val) {
2149 for_each_set_bit(n, &val, 32)
2150 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2151 }
2152
2153 return ret;
2154}
2155
2156static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2157{
2158 u32 newstatus = 0;
2159 unsigned long intstatus;
2345 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */ 2160 uint rxlimit = bus->rxbound; /* Rx frames to read before resched */
2346 uint txlimit = bus->txbound; /* Tx frames to send before resched */ 2161 uint txlimit = bus->txbound; /* Tx frames to send before resched */
2347 uint framecnt = 0; /* Temporary counter of tx/rx frames */ 2162 uint framecnt = 0; /* Temporary counter of tx/rx frames */
2348 bool rxdone = true; /* Flag for no more read data */ 2163 int err = 0, n;
2349 bool resched = false; /* Flag indicating resched wanted */
2350 int err;
2351 2164
2352 brcmf_dbg(TRACE, "Enter\n"); 2165 brcmf_dbg(TRACE, "Enter\n");
2353 2166
2354 /* Start with leftover status bits */
2355 intstatus = bus->intstatus;
2356
2357 down(&bus->sdsem); 2167 down(&bus->sdsem);
2358 2168
2359 /* If waiting for HTAVAIL, check status */ 2169 /* If waiting for HTAVAIL, check status */
@@ -2399,39 +2209,22 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2399 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2209 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2400 } 2210 }
2401 bus->clkstate = CLK_AVAIL; 2211 bus->clkstate = CLK_AVAIL;
2402 } else {
2403 goto clkwait;
2404 } 2212 }
2405 } 2213 }
2406 2214
2407 bus_wake(bus);
2408
2409 /* Make sure backplane clock is on */ 2215 /* Make sure backplane clock is on */
2410 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); 2216 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true);
2411 if (bus->clkstate == CLK_PENDING)
2412 goto clkwait;
2413 2217
2414 /* Pending interrupt indicates new device status */ 2218 /* Pending interrupt indicates new device status */
2415 if (bus->ipend) { 2219 if (atomic_read(&bus->ipend) > 0) {
2416 bus->ipend = false; 2220 atomic_set(&bus->ipend, 0);
2417 err = r_sdreg32(bus, &newstatus, 2221 sdio_claim_host(bus->sdiodev->func[1]);
2418 offsetof(struct sdpcmd_regs, intstatus)); 2222 err = brcmf_sdio_intr_rstatus(bus);
2419 bus->sdcnt.f1regdata++; 2223 sdio_release_host(bus->sdiodev->func[1]);
2420 if (err != 0)
2421 newstatus = 0;
2422 newstatus &= bus->hostintmask;
2423 bus->fcstate = !!(newstatus & I_HMB_FC_STATE);
2424 if (newstatus) {
2425 err = w_sdreg32(bus, newstatus,
2426 offsetof(struct sdpcmd_regs,
2427 intstatus));
2428 bus->sdcnt.f1regdata++;
2429 }
2430 } 2224 }
2431 2225
2432 /* Merge new bits with previous */ 2226 /* Start with leftover status bits */
2433 intstatus |= newstatus; 2227 intstatus = atomic_xchg(&bus->intstatus, 0);
2434 bus->intstatus = 0;
2435 2228
2436 /* Handle flow-control change: read new state in case our ack 2229 /* Handle flow-control change: read new state in case our ack
2437 * crossed another change interrupt. If change still set, assume 2230 * crossed another change interrupt. If change still set, assume
@@ -2445,8 +2238,8 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2445 err = r_sdreg32(bus, &newstatus, 2238 err = r_sdreg32(bus, &newstatus,
2446 offsetof(struct sdpcmd_regs, intstatus)); 2239 offsetof(struct sdpcmd_regs, intstatus));
2447 bus->sdcnt.f1regdata += 2; 2240 bus->sdcnt.f1regdata += 2;
2448 bus->fcstate = 2241 atomic_set(&bus->fcstate,
2449 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)); 2242 !!(newstatus & (I_HMB_FC_STATE | I_HMB_FC_CHANGE)));
2450 intstatus |= (newstatus & bus->hostintmask); 2243 intstatus |= (newstatus & bus->hostintmask);
2451 } 2244 }
2452 2245
@@ -2483,32 +2276,34 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
2483 intstatus &= ~I_HMB_FRAME_IND; 2276 intstatus &= ~I_HMB_FRAME_IND;
2484 2277
2485 /* On frame indication, read available frames */ 2278 /* On frame indication, read available frames */
2486 if (PKT_AVAILABLE()) { 2279 if (PKT_AVAILABLE() && bus->clkstate == CLK_AVAIL) {
2487 framecnt = brcmf_sdbrcm_readframes(bus, rxlimit, &rxdone); 2280 framecnt = brcmf_sdio_readframes(bus, rxlimit);
2488 if (rxdone || bus->rxskip) 2281 if (!bus->rxpending)
2489 intstatus &= ~I_HMB_FRAME_IND; 2282 intstatus &= ~I_HMB_FRAME_IND;
2490 rxlimit -= min(framecnt, rxlimit); 2283 rxlimit -= min(framecnt, rxlimit);
2491 } 2284 }
2492 2285
2493 /* Keep still-pending events for next scheduling */ 2286 /* Keep still-pending events for next scheduling */
2494 bus->intstatus = intstatus; 2287 if (intstatus) {
2288 for_each_set_bit(n, &intstatus, 32)
2289 set_bit(n, (unsigned long *)&bus->intstatus.counter);
2290 }
2495 2291
2496clkwait:
2497 brcmf_sdbrcm_clrintr(bus); 2292 brcmf_sdbrcm_clrintr(bus);
2498 2293
2499 if (data_ok(bus) && bus->ctrl_frame_stat && 2294 if (data_ok(bus) && bus->ctrl_frame_stat &&
2500 (bus->clkstate == CLK_AVAIL)) { 2295 (bus->clkstate == CLK_AVAIL)) {
2501 int ret, i; 2296 int i;
2502 2297
2503 ret = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad, 2298 err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
2504 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf, 2299 SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
2505 (u32) bus->ctrl_frame_len); 2300 (u32) bus->ctrl_frame_len);
2506 2301
2507 if (ret < 0) { 2302 if (err < 0) {
2508 /* On failure, abort the command and 2303 /* On failure, abort the command and
2509 terminate the frame */ 2304 terminate the frame */
2510 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", 2305 brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n",
2511 ret); 2306 err);
2512 bus->sdcnt.tx_sderrs++; 2307 bus->sdcnt.tx_sderrs++;
2513 2308
2514 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); 2309 brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2);
@@ -2530,42 +2325,34 @@ clkwait:
2530 break; 2325 break;
2531 } 2326 }
2532 2327
2533 } 2328 } else {
2534 if (ret == 0)
2535 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; 2329 bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
2536 2330 }
2537 brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret);
2538 bus->ctrl_frame_stat = false; 2331 bus->ctrl_frame_stat = false;
2539 brcmf_sdbrcm_wait_event_wakeup(bus); 2332 brcmf_sdbrcm_wait_event_wakeup(bus);
2540 } 2333 }
2541 /* Send queued frames (limit 1 if rx may still be pending) */ 2334 /* Send queued frames (limit 1 if rx may still be pending) */
2542 else if ((bus->clkstate == CLK_AVAIL) && !bus->fcstate && 2335 else if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
2543 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit 2336 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit
2544 && data_ok(bus)) { 2337 && data_ok(bus)) {
2545 framecnt = rxdone ? txlimit : min(txlimit, bus->txminmax); 2338 framecnt = bus->rxpending ? min(txlimit, bus->txminmax) :
2339 txlimit;
2546 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt); 2340 framecnt = brcmf_sdbrcm_sendfromq(bus, framecnt);
2547 txlimit -= framecnt; 2341 txlimit -= framecnt;
2548 } 2342 }
2549 2343
2550 /* Resched if events or tx frames are pending,
2551 else await next interrupt */
2552 /* On failed register access, all bets are off:
2553 no resched or interrupts */
2554 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) { 2344 if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {
2555 brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n"); 2345 brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation\n");
2556 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 2346 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
2557 bus->intstatus = 0; 2347 atomic_set(&bus->intstatus, 0);
2558 } else if (bus->clkstate == CLK_PENDING) { 2348 } else if (atomic_read(&bus->intstatus) ||
2559 brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n"); 2349 atomic_read(&bus->ipend) > 0 ||
2560 resched = true; 2350 (!atomic_read(&bus->fcstate) &&
2561 } else if (bus->intstatus || bus->ipend || 2351 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
2562 (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) 2352 data_ok(bus)) || PKT_AVAILABLE()) {
2563 && data_ok(bus)) || PKT_AVAILABLE()) { 2353 brcmf_sdbrcm_adddpctsk(bus);
2564 resched = true;
2565 } 2354 }
2566 2355
2567 bus->dpc_sched = resched;
2568
2569 /* If we're done for now, turn off clock request. */ 2356 /* If we're done for now, turn off clock request. */
2570 if ((bus->clkstate != CLK_PENDING) 2357 if ((bus->clkstate != CLK_PENDING)
2571 && bus->idletime == BRCMF_IDLE_IMMEDIATE) { 2358 && bus->idletime == BRCMF_IDLE_IMMEDIATE) {
@@ -2574,65 +2361,6 @@ clkwait:
2574 } 2361 }
2575 2362
2576 up(&bus->sdsem); 2363 up(&bus->sdsem);
2577
2578 return resched;
2579}
2580
2581static inline void brcmf_sdbrcm_adddpctsk(struct brcmf_sdio *bus)
2582{
2583 struct list_head *new_hd;
2584 unsigned long flags;
2585
2586 if (in_interrupt())
2587 new_hd = kzalloc(sizeof(struct list_head), GFP_ATOMIC);
2588 else
2589 new_hd = kzalloc(sizeof(struct list_head), GFP_KERNEL);
2590 if (new_hd == NULL)
2591 return;
2592
2593 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2594 list_add_tail(new_hd, &bus->dpc_tsklst);
2595 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2596}
2597
2598static int brcmf_sdbrcm_dpc_thread(void *data)
2599{
2600 struct brcmf_sdio *bus = (struct brcmf_sdio *) data;
2601 struct list_head *cur_hd, *tmp_hd;
2602 unsigned long flags;
2603
2604 allow_signal(SIGTERM);
2605 /* Run until signal received */
2606 while (1) {
2607 if (kthread_should_stop())
2608 break;
2609
2610 if (list_empty(&bus->dpc_tsklst))
2611 if (wait_for_completion_interruptible(&bus->dpc_wait))
2612 break;
2613
2614 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2615 list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
2616 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2617
2618 if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {
2619 /* after stopping the bus, exit thread */
2620 brcmf_sdbrcm_bus_stop(bus->sdiodev->dev);
2621 bus->dpc_tsk = NULL;
2622 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2623 break;
2624 }
2625
2626 if (brcmf_sdbrcm_dpc(bus))
2627 brcmf_sdbrcm_adddpctsk(bus);
2628
2629 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2630 list_del(cur_hd);
2631 kfree(cur_hd);
2632 }
2633 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2634 }
2635 return 0;
2636} 2364}
2637 2365
2638static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) 2366static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
@@ -2642,6 +2370,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2642 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2370 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2643 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2371 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2644 struct brcmf_sdio *bus = sdiodev->bus; 2372 struct brcmf_sdio *bus = sdiodev->bus;
2373 unsigned long flags;
2645 2374
2646 brcmf_dbg(TRACE, "Enter\n"); 2375 brcmf_dbg(TRACE, "Enter\n");
2647 2376
@@ -2672,21 +2401,23 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2672 spin_unlock_bh(&bus->txqlock); 2401 spin_unlock_bh(&bus->txqlock);
2673 2402
2674 if (pktq_len(&bus->txq) >= TXHI) { 2403 if (pktq_len(&bus->txq) >= TXHI) {
2675 bus->txoff = ON; 2404 bus->txoff = true;
2676 brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON); 2405 brcmf_txflowblock(bus->sdiodev->dev, true);
2677 } 2406 }
2678 2407
2679#ifdef DEBUG 2408#ifdef DEBUG
2680 if (pktq_plen(&bus->txq, prec) > qcount[prec]) 2409 if (pktq_plen(&bus->txq, prec) > qcount[prec])
2681 qcount[prec] = pktq_plen(&bus->txq, prec); 2410 qcount[prec] = pktq_plen(&bus->txq, prec);
2682#endif 2411#endif
2683 /* Schedule DPC if needed to send queued packet(s) */ 2412
2684 if (!bus->dpc_sched) { 2413 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2685 bus->dpc_sched = true; 2414 if (list_empty(&bus->dpc_tsklst)) {
2686 if (bus->dpc_tsk) { 2415 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2687 brcmf_sdbrcm_adddpctsk(bus); 2416
2688 complete(&bus->dpc_wait); 2417 brcmf_sdbrcm_adddpctsk(bus);
2689 } 2418 queue_work(bus->brcmf_wq, &bus->datawork);
2419 } else {
2420 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2690 } 2421 }
2691 2422
2692 return ret; 2423 return ret;
@@ -2707,6 +2438,8 @@ brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
2707 else 2438 else
2708 dsize = size; 2439 dsize = size;
2709 2440
2441 sdio_claim_host(bus->sdiodev->func[1]);
2442
2710 /* Set the backplane window to include the start address */ 2443 /* Set the backplane window to include the start address */
2711 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address); 2444 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
2712 if (bcmerror) { 2445 if (bcmerror) {
@@ -2748,6 +2481,8 @@ xfer_done:
2748 brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n", 2481 brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n",
2749 bus->sdiodev->sbwad); 2482 bus->sdiodev->sbwad);
2750 2483
2484 sdio_release_host(bus->sdiodev->func[1]);
2485
2751 return bcmerror; 2486 return bcmerror;
2752} 2487}
2753 2488
@@ -2882,6 +2617,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2882 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 2617 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
2883 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; 2618 struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
2884 struct brcmf_sdio *bus = sdiodev->bus; 2619 struct brcmf_sdio *bus = sdiodev->bus;
2620 unsigned long flags;
2885 2621
2886 brcmf_dbg(TRACE, "Enter\n"); 2622 brcmf_dbg(TRACE, "Enter\n");
2887 2623
@@ -2918,8 +2654,6 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2918 /* Need to lock here to protect txseq and SDIO tx calls */ 2654 /* Need to lock here to protect txseq and SDIO tx calls */
2919 down(&bus->sdsem); 2655 down(&bus->sdsem);
2920 2656
2921 bus_wake(bus);
2922
2923 /* Make sure backplane clock is on */ 2657 /* Make sure backplane clock is on */
2924 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); 2658 brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
2925 2659
@@ -2967,9 +2701,15 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2967 } while (ret < 0 && retries++ < TXRETRIES); 2701 } while (ret < 0 && retries++ < TXRETRIES);
2968 } 2702 }
2969 2703
2970 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) && !bus->dpc_sched) { 2704 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
2705 if ((bus->idletime == BRCMF_IDLE_IMMEDIATE) &&
2706 list_empty(&bus->dpc_tsklst)) {
2707 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2708
2971 bus->activity = false; 2709 bus->activity = false;
2972 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true); 2710 brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
2711 } else {
2712 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
2973 } 2713 }
2974 2714
2975 up(&bus->sdsem); 2715 up(&bus->sdsem);
@@ -3774,23 +3514,20 @@ void brcmf_sdbrcm_isr(void *arg)
3774 } 3514 }
3775 /* Count the interrupt call */ 3515 /* Count the interrupt call */
3776 bus->sdcnt.intrcount++; 3516 bus->sdcnt.intrcount++;
3777 bus->ipend = true; 3517 if (in_interrupt())
3778 3518 atomic_set(&bus->ipend, 1);
3779 /* Shouldn't get this interrupt if we're sleeping? */ 3519 else
3780 if (bus->sleeping) { 3520 if (brcmf_sdio_intr_rstatus(bus)) {
3781 brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n"); 3521 brcmf_dbg(ERROR, "failed backplane access\n");
3782 return; 3522 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
3783 } 3523 }
3784 3524
3785 /* Disable additional interrupts (is this needed now)? */ 3525 /* Disable additional interrupts (is this needed now)? */
3786 if (!bus->intr) 3526 if (!bus->intr)
3787 brcmf_dbg(ERROR, "isr w/o interrupt configured!\n"); 3527 brcmf_dbg(ERROR, "isr w/o interrupt configured!\n");
3788 3528
3789 bus->dpc_sched = true; 3529 brcmf_sdbrcm_adddpctsk(bus);
3790 if (bus->dpc_tsk) { 3530 queue_work(bus->brcmf_wq, &bus->datawork);
3791 brcmf_sdbrcm_adddpctsk(bus);
3792 complete(&bus->dpc_wait);
3793 }
3794} 3531}
3795 3532
3796static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) 3533static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
@@ -3798,13 +3535,10 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3798#ifdef DEBUG 3535#ifdef DEBUG
3799 struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); 3536 struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev);
3800#endif /* DEBUG */ 3537#endif /* DEBUG */
3538 unsigned long flags;
3801 3539
3802 brcmf_dbg(TIMER, "Enter\n"); 3540 brcmf_dbg(TIMER, "Enter\n");
3803 3541
3804 /* Ignore the timer if simulating bus down */
3805 if (bus->sleeping)
3806 return false;
3807
3808 down(&bus->sdsem); 3542 down(&bus->sdsem);
3809 3543
3810 /* Poll period: check device if appropriate. */ 3544 /* Poll period: check device if appropriate. */
@@ -3818,27 +3552,30 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3818 if (!bus->intr || 3552 if (!bus->intr ||
3819 (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { 3553 (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
3820 3554
3821 if (!bus->dpc_sched) { 3555 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
3556 if (list_empty(&bus->dpc_tsklst)) {
3822 u8 devpend; 3557 u8 devpend;
3558 spin_unlock_irqrestore(&bus->dpc_tl_lock,
3559 flags);
3823 devpend = brcmf_sdio_regrb(bus->sdiodev, 3560 devpend = brcmf_sdio_regrb(bus->sdiodev,
3824 SDIO_CCCR_INTx, 3561 SDIO_CCCR_INTx,
3825 NULL); 3562 NULL);
3826 intstatus = 3563 intstatus =
3827 devpend & (INTR_STATUS_FUNC1 | 3564 devpend & (INTR_STATUS_FUNC1 |
3828 INTR_STATUS_FUNC2); 3565 INTR_STATUS_FUNC2);
3566 } else {
3567 spin_unlock_irqrestore(&bus->dpc_tl_lock,
3568 flags);
3829 } 3569 }
3830 3570
3831 /* If there is something, make like the ISR and 3571 /* If there is something, make like the ISR and
3832 schedule the DPC */ 3572 schedule the DPC */
3833 if (intstatus) { 3573 if (intstatus) {
3834 bus->sdcnt.pollcnt++; 3574 bus->sdcnt.pollcnt++;
3835 bus->ipend = true; 3575 atomic_set(&bus->ipend, 1);
3836 3576
3837 bus->dpc_sched = true; 3577 brcmf_sdbrcm_adddpctsk(bus);
3838 if (bus->dpc_tsk) { 3578 queue_work(bus->brcmf_wq, &bus->datawork);
3839 brcmf_sdbrcm_adddpctsk(bus);
3840 complete(&bus->dpc_wait);
3841 }
3842 } 3579 }
3843 } 3580 }
3844 3581
@@ -3876,11 +3613,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
3876 3613
3877 up(&bus->sdsem); 3614 up(&bus->sdsem);
3878 3615
3879 return bus->ipend; 3616 return (atomic_read(&bus->ipend) > 0);
3880} 3617}
3881 3618
3882static bool brcmf_sdbrcm_chipmatch(u16 chipid) 3619static bool brcmf_sdbrcm_chipmatch(u16 chipid)
3883{ 3620{
3621 if (chipid == BCM43241_CHIP_ID)
3622 return true;
3884 if (chipid == BCM4329_CHIP_ID) 3623 if (chipid == BCM4329_CHIP_ID)
3885 return true; 3624 return true;
3886 if (chipid == BCM4330_CHIP_ID) 3625 if (chipid == BCM4330_CHIP_ID)
@@ -3890,6 +3629,26 @@ static bool brcmf_sdbrcm_chipmatch(u16 chipid)
3890 return false; 3629 return false;
3891} 3630}
3892 3631
3632static void brcmf_sdio_dataworker(struct work_struct *work)
3633{
3634 struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
3635 datawork);
3636 struct list_head *cur_hd, *tmp_hd;
3637 unsigned long flags;
3638
3639 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
3640 list_for_each_safe(cur_hd, tmp_hd, &bus->dpc_tsklst) {
3641 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
3642
3643 brcmf_sdbrcm_dpc(bus);
3644
3645 spin_lock_irqsave(&bus->dpc_tl_lock, flags);
3646 list_del(cur_hd);
3647 kfree(cur_hd);
3648 }
3649 spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
3650}
3651
3893static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus) 3652static void brcmf_sdbrcm_release_malloc(struct brcmf_sdio *bus)
3894{ 3653{
3895 brcmf_dbg(TRACE, "Enter\n"); 3654 brcmf_dbg(TRACE, "Enter\n");
@@ -4022,7 +3781,6 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
4022 SDIO_FUNC_ENABLE_1, NULL); 3781 SDIO_FUNC_ENABLE_1, NULL);
4023 3782
4024 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; 3783 bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;
4025 bus->sleeping = false;
4026 bus->rxflow = false; 3784 bus->rxflow = false;
4027 3785
4028 /* Done with backplane-dependent accesses, can drop clock... */ 3786 /* Done with backplane-dependent accesses, can drop clock... */
@@ -4103,6 +3861,9 @@ static void brcmf_sdbrcm_release(struct brcmf_sdio *bus)
4103 /* De-register interrupt handler */ 3861 /* De-register interrupt handler */
4104 brcmf_sdio_intr_unregister(bus->sdiodev); 3862 brcmf_sdio_intr_unregister(bus->sdiodev);
4105 3863
3864 cancel_work_sync(&bus->datawork);
3865 destroy_workqueue(bus->brcmf_wq);
3866
4106 if (bus->sdiodev->bus_if->drvr) { 3867 if (bus->sdiodev->bus_if->drvr) {
4107 brcmf_detach(bus->sdiodev->dev); 3868 brcmf_detach(bus->sdiodev->dev);
4108 brcmf_sdbrcm_release_dongle(bus); 3869 brcmf_sdbrcm_release_dongle(bus);
@@ -4142,8 +3903,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4142 bus->rxbound = BRCMF_RXBOUND; 3903 bus->rxbound = BRCMF_RXBOUND;
4143 bus->txminmax = BRCMF_TXMINMAX; 3904 bus->txminmax = BRCMF_TXMINMAX;
4144 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; 3905 bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1;
4145 bus->usebufpool = false; /* Use bufpool if allocated,
4146 else use locally malloced rxbuf */
4147 3906
4148 /* attempt to attach to the dongle */ 3907 /* attempt to attach to the dongle */
4149 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { 3908 if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) {
@@ -4155,6 +3914,13 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4155 init_waitqueue_head(&bus->ctrl_wait); 3914 init_waitqueue_head(&bus->ctrl_wait);
4156 init_waitqueue_head(&bus->dcmd_resp_wait); 3915 init_waitqueue_head(&bus->dcmd_resp_wait);
4157 3916
3917 bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
3918 if (bus->brcmf_wq == NULL) {
3919 brcmf_dbg(ERROR, "insufficient memory to create txworkqueue\n");
3920 goto fail;
3921 }
3922 INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
3923
4158 /* Set up the watchdog timer */ 3924 /* Set up the watchdog timer */
4159 init_timer(&bus->timer); 3925 init_timer(&bus->timer);
4160 bus->timer.data = (unsigned long)bus; 3926 bus->timer.data = (unsigned long)bus;
@@ -4172,15 +3938,8 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
4172 bus->watchdog_tsk = NULL; 3938 bus->watchdog_tsk = NULL;
4173 } 3939 }
4174 /* Initialize DPC thread */ 3940 /* Initialize DPC thread */
4175 init_completion(&bus->dpc_wait);
4176 INIT_LIST_HEAD(&bus->dpc_tsklst); 3941 INIT_LIST_HEAD(&bus->dpc_tsklst);
4177 spin_lock_init(&bus->dpc_tl_lock); 3942 spin_lock_init(&bus->dpc_tl_lock);
4178 bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread,
4179 bus, "brcmf_dpc");
4180 if (IS_ERR(bus->dpc_tsk)) {
4181 pr_warn("brcmf_dpc thread failed to start\n");
4182 bus->dpc_tsk = NULL;
4183 }
4184 3943
4185 /* Assign bus interface call back */ 3944 /* Assign bus interface call back */
4186 bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop; 3945 bus->sdiodev->bus_if->brcmf_bus_stop = brcmf_sdbrcm_bus_stop;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
index 58155e23d220..9434440bbc65 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c
@@ -377,6 +377,23 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
377 377
378 /* Address of cores for new chips should be added here */ 378 /* Address of cores for new chips should be added here */
379 switch (ci->chip) { 379 switch (ci->chip) {
380 case BCM43241_CHIP_ID:
381 ci->c_inf[0].wrapbase = 0x18100000;
382 ci->c_inf[0].cib = 0x2a084411;
383 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
384 ci->c_inf[1].base = 0x18002000;
385 ci->c_inf[1].wrapbase = 0x18102000;
386 ci->c_inf[1].cib = 0x0e004211;
387 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
388 ci->c_inf[2].base = 0x18004000;
389 ci->c_inf[2].wrapbase = 0x18104000;
390 ci->c_inf[2].cib = 0x14080401;
391 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
392 ci->c_inf[3].base = 0x18003000;
393 ci->c_inf[3].wrapbase = 0x18103000;
394 ci->c_inf[3].cib = 0x07004211;
395 ci->ramsize = 0x90000;
396 break;
380 case BCM4329_CHIP_ID: 397 case BCM4329_CHIP_ID:
381 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV; 398 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
382 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE; 399 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 29bf78d264e0..0d30afd8c672 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -174,6 +174,8 @@ extern void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
174 u8 data, int *ret); 174 u8 data, int *ret);
175extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr, 175extern void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
176 u32 data, int *ret); 176 u32 data, int *ret);
177extern int brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
178 void *data, bool write);
177 179
178/* Buffer transfer to/from device (client) core via cmd53. 180/* Buffer transfer to/from device (client) core via cmd53.
179 * fn: function number 181 * fn: function number
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 58f89fa9c9f8..a2b4b1e71017 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -66,7 +66,9 @@
66#define BRCMF_USB_CBCTL_READ 1 66#define BRCMF_USB_CBCTL_READ 1
67#define BRCMF_USB_MAX_PKT_SIZE 1600 67#define BRCMF_USB_MAX_PKT_SIZE 1600
68 68
69#define BRCMF_USB_43143_FW_NAME "brcm/brcmfmac43143.bin"
69#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin" 70#define BRCMF_USB_43236_FW_NAME "brcm/brcmfmac43236b.bin"
71#define BRCMF_USB_43242_FW_NAME "brcm/brcmfmac43242a.bin"
70 72
71enum usbdev_suspend_state { 73enum usbdev_suspend_state {
72 USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow 74 USBOS_SUSPEND_STATE_DEVICE_ACTIVE = 0, /* Device is busy, won't allow
@@ -78,25 +80,13 @@ enum usbdev_suspend_state {
78 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */ 80 USBOS_SUSPEND_STATE_SUSPENDED /* Device suspended */
79}; 81};
80 82
81struct brcmf_usb_probe_info {
82 void *usbdev_info;
83 struct usb_device *usb; /* USB device pointer from OS */
84 uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;
85 int intr_size; /* Size of interrupt message */
86 int interval; /* Interrupt polling interval */
87 int vid;
88 int pid;
89 enum usb_device_speed device_speed;
90 enum usbdev_suspend_state suspend_state;
91 struct usb_interface *intf;
92};
93static struct brcmf_usb_probe_info usbdev_probe_info;
94
95struct brcmf_usb_image { 83struct brcmf_usb_image {
96 void *data; 84 struct list_head list;
97 u32 len; 85 s8 *fwname;
86 u8 *image;
87 int image_len;
98}; 88};
99static struct brcmf_usb_image g_image = { NULL, 0 }; 89static struct list_head fw_image_list;
100 90
101struct intr_transfer_buf { 91struct intr_transfer_buf {
102 u32 notification; 92 u32 notification;
@@ -117,9 +107,8 @@ struct brcmf_usbdev_info {
117 int rx_low_watermark; 107 int rx_low_watermark;
118 int tx_low_watermark; 108 int tx_low_watermark;
119 int tx_high_watermark; 109 int tx_high_watermark;
120 bool txoff; 110 int tx_freecount;
121 bool rxoff; 111 bool tx_flowblock;
122 bool txoverride;
123 112
124 struct brcmf_usbreq *tx_reqs; 113 struct brcmf_usbreq *tx_reqs;
125 struct brcmf_usbreq *rx_reqs; 114 struct brcmf_usbreq *rx_reqs;
@@ -133,7 +122,6 @@ struct brcmf_usbdev_info {
133 122
134 struct usb_device *usbdev; 123 struct usb_device *usbdev;
135 struct device *dev; 124 struct device *dev;
136 enum usb_device_speed device_speed;
137 125
138 int ctl_in_pipe, ctl_out_pipe; 126 int ctl_in_pipe, ctl_out_pipe;
139 struct urb *ctl_urb; /* URB for control endpoint */ 127 struct urb *ctl_urb; /* URB for control endpoint */
@@ -146,16 +134,11 @@ struct brcmf_usbdev_info {
146 wait_queue_head_t ctrl_wait; 134 wait_queue_head_t ctrl_wait;
147 ulong ctl_op; 135 ulong ctl_op;
148 136
149 bool rxctl_deferrespok;
150
151 struct urb *bulk_urb; /* used for FW download */ 137 struct urb *bulk_urb; /* used for FW download */
152 struct urb *intr_urb; /* URB for interrupt endpoint */ 138 struct urb *intr_urb; /* URB for interrupt endpoint */
153 int intr_size; /* Size of interrupt message */ 139 int intr_size; /* Size of interrupt message */
154 int interval; /* Interrupt polling interval */ 140 int interval; /* Interrupt polling interval */
155 struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */ 141 struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */
156
157 struct brcmf_usb_probe_info probe_info;
158
159}; 142};
160 143
161static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, 144static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -177,48 +160,17 @@ static struct brcmf_usbdev_info *brcmf_usb_get_businfo(struct device *dev)
177 return brcmf_usb_get_buspub(dev)->devinfo; 160 return brcmf_usb_get_buspub(dev)->devinfo;
178} 161}
179 162
180#if 0 163static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo)
181static void
182brcmf_usb_txflowcontrol(struct brcmf_usbdev_info *devinfo, bool onoff)
183{ 164{
184 dhd_txflowcontrol(devinfo->bus_pub.netdev, 0, onoff); 165 return wait_event_timeout(devinfo->ioctl_resp_wait,
166 devinfo->ctl_completed,
167 msecs_to_jiffies(IOCTL_RESP_TIMEOUT));
185} 168}
186#endif
187 169
188static int brcmf_usb_ioctl_resp_wait(struct brcmf_usbdev_info *devinfo, 170static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
189 uint *condition, bool *pending)
190{
191 DECLARE_WAITQUEUE(wait, current);
192 int timeout = IOCTL_RESP_TIMEOUT;
193
194 /* Convert timeout in millsecond to jiffies */
195 timeout = msecs_to_jiffies(timeout);
196 /* Wait until control frame is available */
197 add_wait_queue(&devinfo->ioctl_resp_wait, &wait);
198 set_current_state(TASK_INTERRUPTIBLE);
199
200 smp_mb();
201 while (!(*condition) && (!signal_pending(current) && timeout)) {
202 timeout = schedule_timeout(timeout);
203 /* Wait until control frame is available */
204 smp_mb();
205 }
206
207 if (signal_pending(current))
208 *pending = true;
209
210 set_current_state(TASK_RUNNING);
211 remove_wait_queue(&devinfo->ioctl_resp_wait, &wait);
212
213 return timeout;
214}
215
216static int brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
217{ 171{
218 if (waitqueue_active(&devinfo->ioctl_resp_wait)) 172 if (waitqueue_active(&devinfo->ioctl_resp_wait))
219 wake_up_interruptible(&devinfo->ioctl_resp_wait); 173 wake_up(&devinfo->ioctl_resp_wait);
220
221 return 0;
222} 174}
223 175
224static void 176static void
@@ -324,17 +276,9 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
324 devinfo->ctl_read.wLength = cpu_to_le16p(&size); 276 devinfo->ctl_read.wLength = cpu_to_le16p(&size);
325 devinfo->ctl_urb->transfer_buffer_length = size; 277 devinfo->ctl_urb->transfer_buffer_length = size;
326 278
327 if (devinfo->rxctl_deferrespok) { 279 devinfo->ctl_read.bRequestType = USB_DIR_IN
328 /* BMAC model */ 280 | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
329 devinfo->ctl_read.bRequestType = USB_DIR_IN 281 devinfo->ctl_read.bRequest = 1;
330 | USB_TYPE_VENDOR | USB_RECIP_INTERFACE;
331 devinfo->ctl_read.bRequest = DL_DEFER_RESP_OK;
332 } else {
333 /* full dongle model */
334 devinfo->ctl_read.bRequestType = USB_DIR_IN
335 | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
336 devinfo->ctl_read.bRequest = 1;
337 }
338 282
339 usb_fill_control_urb(devinfo->ctl_urb, 283 usb_fill_control_urb(devinfo->ctl_urb,
340 devinfo->usbdev, 284 devinfo->usbdev,
@@ -355,7 +299,6 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
355{ 299{
356 int err = 0; 300 int err = 0;
357 int timeout = 0; 301 int timeout = 0;
358 bool pending;
359 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 302 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
360 303
361 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 304 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
@@ -366,15 +309,14 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
366 if (test_and_set_bit(0, &devinfo->ctl_op)) 309 if (test_and_set_bit(0, &devinfo->ctl_op))
367 return -EIO; 310 return -EIO;
368 311
312 devinfo->ctl_completed = false;
369 err = brcmf_usb_send_ctl(devinfo, buf, len); 313 err = brcmf_usb_send_ctl(devinfo, buf, len);
370 if (err) { 314 if (err) {
371 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); 315 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
316 clear_bit(0, &devinfo->ctl_op);
372 return err; 317 return err;
373 } 318 }
374 319 timeout = brcmf_usb_ioctl_resp_wait(devinfo);
375 devinfo->ctl_completed = false;
376 timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
377 &pending);
378 clear_bit(0, &devinfo->ctl_op); 320 clear_bit(0, &devinfo->ctl_op);
379 if (!timeout) { 321 if (!timeout) {
380 brcmf_dbg(ERROR, "Txctl wait timed out\n"); 322 brcmf_dbg(ERROR, "Txctl wait timed out\n");
@@ -387,7 +329,6 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
387{ 329{
388 int err = 0; 330 int err = 0;
389 int timeout = 0; 331 int timeout = 0;
390 bool pending;
391 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev); 332 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
392 333
393 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) { 334 if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
@@ -397,14 +338,14 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
397 if (test_and_set_bit(0, &devinfo->ctl_op)) 338 if (test_and_set_bit(0, &devinfo->ctl_op))
398 return -EIO; 339 return -EIO;
399 340
341 devinfo->ctl_completed = false;
400 err = brcmf_usb_recv_ctl(devinfo, buf, len); 342 err = brcmf_usb_recv_ctl(devinfo, buf, len);
401 if (err) { 343 if (err) {
402 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len); 344 brcmf_dbg(ERROR, "fail %d bytes: %d\n", err, len);
345 clear_bit(0, &devinfo->ctl_op);
403 return err; 346 return err;
404 } 347 }
405 devinfo->ctl_completed = false; 348 timeout = brcmf_usb_ioctl_resp_wait(devinfo);
406 timeout = brcmf_usb_ioctl_resp_wait(devinfo, &devinfo->ctl_completed,
407 &pending);
408 err = devinfo->ctl_urb_status; 349 err = devinfo->ctl_urb_status;
409 clear_bit(0, &devinfo->ctl_op); 350 clear_bit(0, &devinfo->ctl_op);
410 if (!timeout) { 351 if (!timeout) {
@@ -418,7 +359,7 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
418} 359}
419 360
420static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo, 361static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
421 struct list_head *q) 362 struct list_head *q, int *counter)
422{ 363{
423 unsigned long flags; 364 unsigned long flags;
424 struct brcmf_usbreq *req; 365 struct brcmf_usbreq *req;
@@ -429,17 +370,22 @@ static struct brcmf_usbreq *brcmf_usb_deq(struct brcmf_usbdev_info *devinfo,
429 } 370 }
430 req = list_entry(q->next, struct brcmf_usbreq, list); 371 req = list_entry(q->next, struct brcmf_usbreq, list);
431 list_del_init(q->next); 372 list_del_init(q->next);
373 if (counter)
374 (*counter)--;
432 spin_unlock_irqrestore(&devinfo->qlock, flags); 375 spin_unlock_irqrestore(&devinfo->qlock, flags);
433 return req; 376 return req;
434 377
435} 378}
436 379
437static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo, 380static void brcmf_usb_enq(struct brcmf_usbdev_info *devinfo,
438 struct list_head *q, struct brcmf_usbreq *req) 381 struct list_head *q, struct brcmf_usbreq *req,
382 int *counter)
439{ 383{
440 unsigned long flags; 384 unsigned long flags;
441 spin_lock_irqsave(&devinfo->qlock, flags); 385 spin_lock_irqsave(&devinfo->qlock, flags);
442 list_add_tail(&req->list, q); 386 list_add_tail(&req->list, q);
387 if (counter)
388 (*counter)++;
443 spin_unlock_irqrestore(&devinfo->qlock, flags); 389 spin_unlock_irqrestore(&devinfo->qlock, flags);
444} 390}
445 391
@@ -519,10 +465,16 @@ static void brcmf_usb_tx_complete(struct urb *urb)
519 else 465 else
520 devinfo->bus_pub.bus->dstats.tx_errors++; 466 devinfo->bus_pub.bus->dstats.tx_errors++;
521 467
468 brcmf_txcomplete(devinfo->dev, req->skb, urb->status == 0);
469
522 brcmu_pkt_buf_free_skb(req->skb); 470 brcmu_pkt_buf_free_skb(req->skb);
523 req->skb = NULL; 471 req->skb = NULL;
524 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); 472 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req, &devinfo->tx_freecount);
525 473 if (devinfo->tx_freecount > devinfo->tx_high_watermark &&
474 devinfo->tx_flowblock) {
475 brcmf_txflowblock(devinfo->dev, false);
476 devinfo->tx_flowblock = false;
477 }
526} 478}
527 479
528static void brcmf_usb_rx_complete(struct urb *urb) 480static void brcmf_usb_rx_complete(struct urb *urb)
@@ -541,7 +493,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
541 } else { 493 } else {
542 devinfo->bus_pub.bus->dstats.rx_errors++; 494 devinfo->bus_pub.bus->dstats.rx_errors++;
543 brcmu_pkt_buf_free_skb(skb); 495 brcmu_pkt_buf_free_skb(skb);
544 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); 496 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
545 return; 497 return;
546 } 498 }
547 499
@@ -550,15 +502,13 @@ static void brcmf_usb_rx_complete(struct urb *urb)
550 if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) { 502 if (brcmf_proto_hdrpull(devinfo->dev, &ifidx, skb) != 0) {
551 brcmf_dbg(ERROR, "rx protocol error\n"); 503 brcmf_dbg(ERROR, "rx protocol error\n");
552 brcmu_pkt_buf_free_skb(skb); 504 brcmu_pkt_buf_free_skb(skb);
553 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req);
554 devinfo->bus_pub.bus->dstats.rx_errors++; 505 devinfo->bus_pub.bus->dstats.rx_errors++;
555 } else { 506 } else
556 brcmf_rx_packet(devinfo->dev, ifidx, skb); 507 brcmf_rx_packet(devinfo->dev, ifidx, skb);
557 brcmf_usb_rx_refill(devinfo, req); 508 brcmf_usb_rx_refill(devinfo, req);
558 }
559 } else { 509 } else {
560 brcmu_pkt_buf_free_skb(skb); 510 brcmu_pkt_buf_free_skb(skb);
561 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); 511 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
562 } 512 }
563 return; 513 return;
564 514
@@ -575,7 +525,7 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
575 525
576 skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu); 526 skb = dev_alloc_skb(devinfo->bus_pub.bus_mtu);
577 if (!skb) { 527 if (!skb) {
578 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); 528 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
579 return; 529 return;
580 } 530 }
581 req->skb = skb; 531 req->skb = skb;
@@ -584,14 +534,14 @@ static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
584 skb->data, skb_tailroom(skb), brcmf_usb_rx_complete, 534 skb->data, skb_tailroom(skb), brcmf_usb_rx_complete,
585 req); 535 req);
586 req->devinfo = devinfo; 536 req->devinfo = devinfo;
587 brcmf_usb_enq(devinfo, &devinfo->rx_postq, req); 537 brcmf_usb_enq(devinfo, &devinfo->rx_postq, req, NULL);
588 538
589 ret = usb_submit_urb(req->urb, GFP_ATOMIC); 539 ret = usb_submit_urb(req->urb, GFP_ATOMIC);
590 if (ret) { 540 if (ret) {
591 brcmf_usb_del_fromq(devinfo, req); 541 brcmf_usb_del_fromq(devinfo, req);
592 brcmu_pkt_buf_free_skb(req->skb); 542 brcmu_pkt_buf_free_skb(req->skb);
593 req->skb = NULL; 543 req->skb = NULL;
594 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req); 544 brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL);
595 } 545 }
596 return; 546 return;
597} 547}
@@ -604,7 +554,7 @@ static void brcmf_usb_rx_fill_all(struct brcmf_usbdev_info *devinfo)
604 brcmf_dbg(ERROR, "bus is not up\n"); 554 brcmf_dbg(ERROR, "bus is not up\n");
605 return; 555 return;
606 } 556 }
607 while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq)) != NULL) 557 while ((req = brcmf_usb_deq(devinfo, &devinfo->rx_freeq, NULL)) != NULL)
608 brcmf_usb_rx_refill(devinfo, req); 558 brcmf_usb_rx_refill(devinfo, req);
609} 559}
610 560
@@ -682,7 +632,8 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
682 return -EIO; 632 return -EIO;
683 } 633 }
684 634
685 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq); 635 req = brcmf_usb_deq(devinfo, &devinfo->tx_freeq,
636 &devinfo->tx_freecount);
686 if (!req) { 637 if (!req) {
687 brcmu_pkt_buf_free_skb(skb); 638 brcmu_pkt_buf_free_skb(skb);
688 brcmf_dbg(ERROR, "no req to send\n"); 639 brcmf_dbg(ERROR, "no req to send\n");
@@ -694,14 +645,21 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
694 usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe, 645 usb_fill_bulk_urb(req->urb, devinfo->usbdev, devinfo->tx_pipe,
695 skb->data, skb->len, brcmf_usb_tx_complete, req); 646 skb->data, skb->len, brcmf_usb_tx_complete, req);
696 req->urb->transfer_flags |= URB_ZERO_PACKET; 647 req->urb->transfer_flags |= URB_ZERO_PACKET;
697 brcmf_usb_enq(devinfo, &devinfo->tx_postq, req); 648 brcmf_usb_enq(devinfo, &devinfo->tx_postq, req, NULL);
698 ret = usb_submit_urb(req->urb, GFP_ATOMIC); 649 ret = usb_submit_urb(req->urb, GFP_ATOMIC);
699 if (ret) { 650 if (ret) {
700 brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n"); 651 brcmf_dbg(ERROR, "brcmf_usb_tx usb_submit_urb FAILED\n");
701 brcmf_usb_del_fromq(devinfo, req); 652 brcmf_usb_del_fromq(devinfo, req);
702 brcmu_pkt_buf_free_skb(req->skb); 653 brcmu_pkt_buf_free_skb(req->skb);
703 req->skb = NULL; 654 req->skb = NULL;
704 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req); 655 brcmf_usb_enq(devinfo, &devinfo->tx_freeq, req,
656 &devinfo->tx_freecount);
657 } else {
658 if (devinfo->tx_freecount < devinfo->tx_low_watermark &&
659 !devinfo->tx_flowblock) {
660 brcmf_txflowblock(dev, true);
661 devinfo->tx_flowblock = true;
662 }
705 } 663 }
706 664
707 return ret; 665 return ret;
@@ -1112,10 +1070,14 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
1112static bool brcmf_usb_chip_support(int chipid, int chiprev) 1070static bool brcmf_usb_chip_support(int chipid, int chiprev)
1113{ 1071{
1114 switch(chipid) { 1072 switch(chipid) {
1073 case 43143:
1074 return true;
1115 case 43235: 1075 case 43235:
1116 case 43236: 1076 case 43236:
1117 case 43238: 1077 case 43238:
1118 return (chiprev == 3); 1078 return (chiprev == 3);
1079 case 43242:
1080 return true;
1119 default: 1081 default:
1120 break; 1082 break;
1121 } 1083 }
@@ -1154,17 +1116,10 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
1154} 1116}
1155 1117
1156 1118
1157static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub) 1119static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
1158{ 1120{
1159 struct brcmf_usbdev_info *devinfo =
1160 (struct brcmf_usbdev_info *)bus_pub;
1161
1162 brcmf_dbg(TRACE, "devinfo %p\n", devinfo); 1121 brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
1163 1122
1164 /* store the image globally */
1165 g_image.data = devinfo->image;
1166 g_image.len = devinfo->image_len;
1167
1168 /* free the URBS */ 1123 /* free the URBS */
1169 brcmf_usb_free_q(&devinfo->rx_freeq, false); 1124 brcmf_usb_free_q(&devinfo->rx_freeq, false);
1170 brcmf_usb_free_q(&devinfo->tx_freeq, false); 1125 brcmf_usb_free_q(&devinfo->tx_freeq, false);
@@ -1175,7 +1130,6 @@ static void brcmf_usb_detach(const struct brcmf_usbdev *bus_pub)
1175 1130
1176 kfree(devinfo->tx_reqs); 1131 kfree(devinfo->tx_reqs);
1177 kfree(devinfo->rx_reqs); 1132 kfree(devinfo->rx_reqs);
1178 kfree(devinfo);
1179} 1133}
1180 1134
1181#define TRX_MAGIC 0x30524448 /* "HDR0" */ 1135#define TRX_MAGIC 0x30524448 /* "HDR0" */
@@ -1217,19 +1171,34 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
1217{ 1171{
1218 s8 *fwname; 1172 s8 *fwname;
1219 const struct firmware *fw; 1173 const struct firmware *fw;
1174 struct brcmf_usb_image *fw_image;
1220 int err; 1175 int err;
1221 1176
1222 devinfo->image = g_image.data; 1177 switch (devinfo->bus_pub.devid) {
1223 devinfo->image_len = g_image.len; 1178 case 43143:
1224 1179 fwname = BRCMF_USB_43143_FW_NAME;
1225 /* 1180 break;
1226 * if we have an image we can leave here. 1181 case 43235:
1227 */ 1182 case 43236:
1228 if (devinfo->image) 1183 case 43238:
1229 return 0; 1184 fwname = BRCMF_USB_43236_FW_NAME;
1230 1185 break;
1231 fwname = BRCMF_USB_43236_FW_NAME; 1186 case 43242:
1187 fwname = BRCMF_USB_43242_FW_NAME;
1188 break;
1189 default:
1190 return -EINVAL;
1191 break;
1192 }
1232 1193
1194 list_for_each_entry(fw_image, &fw_image_list, list) {
1195 if (fw_image->fwname == fwname) {
1196 devinfo->image = fw_image->image;
1197 devinfo->image_len = fw_image->image_len;
1198 return 0;
1199 }
1200 }
1201 /* fw image not yet loaded. Load it now and add to list */
1233 err = request_firmware(&fw, fwname, devinfo->dev); 1202 err = request_firmware(&fw, fwname, devinfo->dev);
1234 if (!fw) { 1203 if (!fw) {
1235 brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname); 1204 brcmf_dbg(ERROR, "fail to request firmware %s\n", fwname);
@@ -1240,27 +1209,32 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
1240 return -EINVAL; 1209 return -EINVAL;
1241 } 1210 }
1242 1211
1243 devinfo->image = vmalloc(fw->size); /* plus nvram */ 1212 fw_image = kzalloc(sizeof(*fw_image), GFP_ATOMIC);
1244 if (!devinfo->image) 1213 if (!fw_image)
1214 return -ENOMEM;
1215 INIT_LIST_HEAD(&fw_image->list);
1216 list_add_tail(&fw_image->list, &fw_image_list);
1217 fw_image->fwname = fwname;
1218 fw_image->image = vmalloc(fw->size);
1219 if (!fw_image->image)
1245 return -ENOMEM; 1220 return -ENOMEM;
1246 1221
1247 memcpy(devinfo->image, fw->data, fw->size); 1222 memcpy(fw_image->image, fw->data, fw->size);
1248 devinfo->image_len = fw->size; 1223 fw_image->image_len = fw->size;
1249 1224
1250 release_firmware(fw); 1225 release_firmware(fw);
1226
1227 devinfo->image = fw_image->image;
1228 devinfo->image_len = fw_image->image_len;
1229
1251 return 0; 1230 return 0;
1252} 1231}
1253 1232
1254 1233
1255static 1234static
1256struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev) 1235struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
1236 int nrxq, int ntxq)
1257{ 1237{
1258 struct brcmf_usbdev_info *devinfo;
1259
1260 devinfo = kzalloc(sizeof(struct brcmf_usbdev_info), GFP_ATOMIC);
1261 if (devinfo == NULL)
1262 return NULL;
1263
1264 devinfo->bus_pub.nrxq = nrxq; 1238 devinfo->bus_pub.nrxq = nrxq;
1265 devinfo->rx_low_watermark = nrxq / 2; 1239 devinfo->rx_low_watermark = nrxq / 2;
1266 devinfo->bus_pub.devinfo = devinfo; 1240 devinfo->bus_pub.devinfo = devinfo;
@@ -1269,18 +1243,6 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1269 /* flow control when too many tx urbs posted */ 1243 /* flow control when too many tx urbs posted */
1270 devinfo->tx_low_watermark = ntxq / 4; 1244 devinfo->tx_low_watermark = ntxq / 4;
1271 devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3; 1245 devinfo->tx_high_watermark = devinfo->tx_low_watermark * 3;
1272 devinfo->dev = dev;
1273 devinfo->usbdev = usbdev_probe_info.usb;
1274 devinfo->tx_pipe = usbdev_probe_info.tx_pipe;
1275 devinfo->rx_pipe = usbdev_probe_info.rx_pipe;
1276 devinfo->rx_pipe2 = usbdev_probe_info.rx_pipe2;
1277 devinfo->intr_pipe = usbdev_probe_info.intr_pipe;
1278
1279 devinfo->interval = usbdev_probe_info.interval;
1280 devinfo->intr_size = usbdev_probe_info.intr_size;
1281
1282 memcpy(&devinfo->probe_info, &usbdev_probe_info,
1283 sizeof(struct brcmf_usb_probe_info));
1284 devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE; 1246 devinfo->bus_pub.bus_mtu = BRCMF_USB_MAX_PKT_SIZE;
1285 1247
1286 /* Initialize other structure content */ 1248 /* Initialize other structure content */
@@ -1295,6 +1257,8 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1295 INIT_LIST_HEAD(&devinfo->tx_freeq); 1257 INIT_LIST_HEAD(&devinfo->tx_freeq);
1296 INIT_LIST_HEAD(&devinfo->tx_postq); 1258 INIT_LIST_HEAD(&devinfo->tx_postq);
1297 1259
1260 devinfo->tx_flowblock = false;
1261
1298 devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq); 1262 devinfo->rx_reqs = brcmf_usbdev_qinit(&devinfo->rx_freeq, nrxq);
1299 if (!devinfo->rx_reqs) 1263 if (!devinfo->rx_reqs)
1300 goto error; 1264 goto error;
@@ -1302,6 +1266,7 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1302 devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq); 1266 devinfo->tx_reqs = brcmf_usbdev_qinit(&devinfo->tx_freeq, ntxq);
1303 if (!devinfo->tx_reqs) 1267 if (!devinfo->tx_reqs)
1304 goto error; 1268 goto error;
1269 devinfo->tx_freecount = ntxq;
1305 1270
1306 devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC); 1271 devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);
1307 if (!devinfo->intr_urb) { 1272 if (!devinfo->intr_urb) {
@@ -1313,8 +1278,6 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1313 brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n"); 1278 brcmf_dbg(ERROR, "usb_alloc_urb (ctl) failed\n");
1314 goto error; 1279 goto error;
1315 } 1280 }
1316 devinfo->rxctl_deferrespok = 0;
1317
1318 devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); 1281 devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
1319 if (!devinfo->bulk_urb) { 1282 if (!devinfo->bulk_urb) {
1320 brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n"); 1283 brcmf_dbg(ERROR, "usb_alloc_urb (bulk) failed\n");
@@ -1336,23 +1299,21 @@ struct brcmf_usbdev *brcmf_usb_attach(int nrxq, int ntxq, struct device *dev)
1336 1299
1337error: 1300error:
1338 brcmf_dbg(ERROR, "failed!\n"); 1301 brcmf_dbg(ERROR, "failed!\n");
1339 brcmf_usb_detach(&devinfo->bus_pub); 1302 brcmf_usb_detach(devinfo);
1340 return NULL; 1303 return NULL;
1341} 1304}
1342 1305
1343static int brcmf_usb_probe_cb(struct device *dev, const char *desc, 1306static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
1344 u32 bustype, u32 hdrlen) 1307 const char *desc, u32 bustype, u32 hdrlen)
1345{ 1308{
1346 struct brcmf_bus *bus = NULL; 1309 struct brcmf_bus *bus = NULL;
1347 struct brcmf_usbdev *bus_pub = NULL; 1310 struct brcmf_usbdev *bus_pub = NULL;
1348 int ret; 1311 int ret;
1312 struct device *dev = devinfo->dev;
1349 1313
1350 1314 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
1351 bus_pub = brcmf_usb_attach(BRCMF_USB_NRXQ, BRCMF_USB_NTXQ, dev); 1315 if (!bus_pub)
1352 if (!bus_pub) { 1316 return -ENODEV;
1353 ret = -ENODEV;
1354 goto fail;
1355 }
1356 1317
1357 bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); 1318 bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC);
1358 if (!bus) { 1319 if (!bus) {
@@ -1387,23 +1348,21 @@ static int brcmf_usb_probe_cb(struct device *dev, const char *desc,
1387 return 0; 1348 return 0;
1388fail: 1349fail:
1389 /* Release resources in reverse order */ 1350 /* Release resources in reverse order */
1390 if (bus_pub)
1391 brcmf_usb_detach(bus_pub);
1392 kfree(bus); 1351 kfree(bus);
1352 brcmf_usb_detach(devinfo);
1393 return ret; 1353 return ret;
1394} 1354}
1395 1355
1396static void 1356static void
1397brcmf_usb_disconnect_cb(struct brcmf_usbdev *bus_pub) 1357brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
1398{ 1358{
1399 if (!bus_pub) 1359 if (!devinfo)
1400 return; 1360 return;
1401 brcmf_dbg(TRACE, "enter: bus_pub %p\n", bus_pub); 1361 brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo);
1402
1403 brcmf_detach(bus_pub->devinfo->dev);
1404 kfree(bus_pub->bus);
1405 brcmf_usb_detach(bus_pub);
1406 1362
1363 brcmf_detach(devinfo->dev);
1364 kfree(devinfo->bus_pub.bus);
1365 brcmf_usb_detach(devinfo);
1407} 1366}
1408 1367
1409static int 1368static int
@@ -1415,18 +1374,18 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1415 struct usb_device *usb = interface_to_usbdev(intf); 1374 struct usb_device *usb = interface_to_usbdev(intf);
1416 int num_of_eps; 1375 int num_of_eps;
1417 u8 endpoint_num; 1376 u8 endpoint_num;
1377 struct brcmf_usbdev_info *devinfo;
1418 1378
1419 brcmf_dbg(TRACE, "enter\n"); 1379 brcmf_dbg(TRACE, "enter\n");
1420 1380
1421 usbdev_probe_info.usb = usb; 1381 devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
1422 usbdev_probe_info.intf = intf; 1382 if (devinfo == NULL)
1383 return -ENOMEM;
1423 1384
1424 if (id != NULL) { 1385 devinfo->usbdev = usb;
1425 usbdev_probe_info.vid = id->idVendor; 1386 devinfo->dev = &usb->dev;
1426 usbdev_probe_info.pid = id->idProduct;
1427 }
1428 1387
1429 usb_set_intfdata(intf, &usbdev_probe_info); 1388 usb_set_intfdata(intf, devinfo);
1430 1389
1431 /* Check that the device supports only one configuration */ 1390 /* Check that the device supports only one configuration */
1432 if (usb->descriptor.bNumConfigurations != 1) { 1391 if (usb->descriptor.bNumConfigurations != 1) {
@@ -1475,11 +1434,11 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1475 } 1434 }
1476 1435
1477 endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; 1436 endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
1478 usbdev_probe_info.intr_pipe = usb_rcvintpipe(usb, endpoint_num); 1437 devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);
1479 1438
1480 usbdev_probe_info.rx_pipe = 0; 1439 devinfo->rx_pipe = 0;
1481 usbdev_probe_info.rx_pipe2 = 0; 1440 devinfo->rx_pipe2 = 0;
1482 usbdev_probe_info.tx_pipe = 0; 1441 devinfo->tx_pipe = 0;
1483 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1; 1442 num_of_eps = IFDESC(usb, BULK_IF).bNumEndpoints - 1;
1484 1443
1485 /* Check data endpoints and get pipes */ 1444 /* Check data endpoints and get pipes */
@@ -1496,35 +1455,33 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1496 USB_ENDPOINT_NUMBER_MASK; 1455 USB_ENDPOINT_NUMBER_MASK;
1497 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) 1456 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1498 == USB_DIR_IN) { 1457 == USB_DIR_IN) {
1499 if (!usbdev_probe_info.rx_pipe) { 1458 if (!devinfo->rx_pipe) {
1500 usbdev_probe_info.rx_pipe = 1459 devinfo->rx_pipe =
1501 usb_rcvbulkpipe(usb, endpoint_num); 1460 usb_rcvbulkpipe(usb, endpoint_num);
1502 } else { 1461 } else {
1503 usbdev_probe_info.rx_pipe2 = 1462 devinfo->rx_pipe2 =
1504 usb_rcvbulkpipe(usb, endpoint_num); 1463 usb_rcvbulkpipe(usb, endpoint_num);
1505 } 1464 }
1506 } else { 1465 } else {
1507 usbdev_probe_info.tx_pipe = 1466 devinfo->tx_pipe = usb_sndbulkpipe(usb, endpoint_num);
1508 usb_sndbulkpipe(usb, endpoint_num);
1509 } 1467 }
1510 } 1468 }
1511 1469
1512 /* Allocate interrupt URB and data buffer */ 1470 /* Allocate interrupt URB and data buffer */
1513 /* RNDIS says 8-byte intr, our old drivers used 4-byte */ 1471 /* RNDIS says 8-byte intr, our old drivers used 4-byte */
1514 if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16)) 1472 if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))
1515 usbdev_probe_info.intr_size = 8; 1473 devinfo->intr_size = 8;
1516 else 1474 else
1517 usbdev_probe_info.intr_size = 4; 1475 devinfo->intr_size = 4;
1518 1476
1519 usbdev_probe_info.interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval; 1477 devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;
1520 1478
1521 usbdev_probe_info.device_speed = usb->speed;
1522 if (usb->speed == USB_SPEED_HIGH) 1479 if (usb->speed == USB_SPEED_HIGH)
1523 brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n"); 1480 brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
1524 else 1481 else
1525 brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n"); 1482 brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
1526 1483
1527 ret = brcmf_usb_probe_cb(&usb->dev, "", USB_BUS, 0); 1484 ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0);
1528 if (ret) 1485 if (ret)
1529 goto fail; 1486 goto fail;
1530 1487
@@ -1533,6 +1490,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
1533 1490
1534fail: 1491fail:
1535 brcmf_dbg(ERROR, "failed with errno %d\n", ret); 1492 brcmf_dbg(ERROR, "failed with errno %d\n", ret);
1493 kfree(devinfo);
1536 usb_set_intfdata(intf, NULL); 1494 usb_set_intfdata(intf, NULL);
1537 return ret; 1495 return ret;
1538 1496
@@ -1541,11 +1499,12 @@ fail:
1541static void 1499static void
1542brcmf_usb_disconnect(struct usb_interface *intf) 1500brcmf_usb_disconnect(struct usb_interface *intf)
1543{ 1501{
1544 struct usb_device *usb = interface_to_usbdev(intf); 1502 struct brcmf_usbdev_info *devinfo;
1545 1503
1546 brcmf_dbg(TRACE, "enter\n"); 1504 brcmf_dbg(TRACE, "enter\n");
1547 brcmf_usb_disconnect_cb(brcmf_usb_get_buspub(&usb->dev)); 1505 devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
1548 usb_set_intfdata(intf, NULL); 1506 brcmf_usb_disconnect_cb(devinfo);
1507 kfree(devinfo);
1549} 1508}
1550 1509
1551/* 1510/*
@@ -1577,17 +1536,23 @@ static int brcmf_usb_resume(struct usb_interface *intf)
1577} 1536}
1578 1537
1579#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c 1538#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c
1539#define BRCMF_USB_DEVICE_ID_43143 0xbd1e
1580#define BRCMF_USB_DEVICE_ID_43236 0xbd17 1540#define BRCMF_USB_DEVICE_ID_43236 0xbd17
1541#define BRCMF_USB_DEVICE_ID_43242 0xbd1f
1581#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc 1542#define BRCMF_USB_DEVICE_ID_BCMFW 0x0bdc
1582 1543
1583static struct usb_device_id brcmf_usb_devid_table[] = { 1544static struct usb_device_id brcmf_usb_devid_table[] = {
1545 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43143) },
1584 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) }, 1546 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43236) },
1547 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_43242) },
1585 /* special entry for device with firmware loaded and running */ 1548 /* special entry for device with firmware loaded and running */
1586 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) }, 1549 { USB_DEVICE(BRCMF_USB_VENDOR_ID_BROADCOM, BRCMF_USB_DEVICE_ID_BCMFW) },
1587 { } 1550 { }
1588}; 1551};
1589MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table); 1552MODULE_DEVICE_TABLE(usb, brcmf_usb_devid_table);
1553MODULE_FIRMWARE(BRCMF_USB_43143_FW_NAME);
1590MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME); 1554MODULE_FIRMWARE(BRCMF_USB_43236_FW_NAME);
1555MODULE_FIRMWARE(BRCMF_USB_43242_FW_NAME);
1591 1556
1592/* TODO: suspend and resume entries */ 1557/* TODO: suspend and resume entries */
1593static struct usb_driver brcmf_usbdrvr = { 1558static struct usb_driver brcmf_usbdrvr = {
@@ -1601,15 +1566,25 @@ static struct usb_driver brcmf_usbdrvr = {
1601 .disable_hub_initiated_lpm = 1, 1566 .disable_hub_initiated_lpm = 1,
1602}; 1567};
1603 1568
1569static void brcmf_release_fw(struct list_head *q)
1570{
1571 struct brcmf_usb_image *fw_image, *next;
1572
1573 list_for_each_entry_safe(fw_image, next, q, list) {
1574 vfree(fw_image->image);
1575 list_del_init(&fw_image->list);
1576 }
1577}
1578
1579
1604void brcmf_usb_exit(void) 1580void brcmf_usb_exit(void)
1605{ 1581{
1606 usb_deregister(&brcmf_usbdrvr); 1582 usb_deregister(&brcmf_usbdrvr);
1607 vfree(g_image.data); 1583 brcmf_release_fw(&fw_image_list);
1608 g_image.data = NULL;
1609 g_image.len = 0;
1610} 1584}
1611 1585
1612void brcmf_usb_init(void) 1586void brcmf_usb_init(void)
1613{ 1587{
1588 INIT_LIST_HEAD(&fw_image_list);
1614 usb_register(&brcmf_usbdrvr); 1589 usb_register(&brcmf_usbdrvr);
1615} 1590}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 50b5553b6964..c1abaa6db59e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -28,6 +28,7 @@
28#include <linux/ieee80211.h> 28#include <linux/ieee80211.h>
29#include <linux/uaccess.h> 29#include <linux/uaccess.h>
30#include <net/cfg80211.h> 30#include <net/cfg80211.h>
31#include <net/netlink.h>
31 32
32#include <brcmu_utils.h> 33#include <brcmu_utils.h>
33#include <defs.h> 34#include <defs.h>
@@ -35,6 +36,58 @@
35#include "dhd.h" 36#include "dhd.h"
36#include "wl_cfg80211.h" 37#include "wl_cfg80211.h"
37 38
39#define BRCMF_SCAN_IE_LEN_MAX 2048
40#define BRCMF_PNO_VERSION 2
41#define BRCMF_PNO_TIME 30
42#define BRCMF_PNO_REPEAT 4
43#define BRCMF_PNO_FREQ_EXPO_MAX 3
44#define BRCMF_PNO_MAX_PFN_COUNT 16
45#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
46#define BRCMF_PNO_HIDDEN_BIT 2
47#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
48#define BRCMF_PNO_SCAN_COMPLETE 1
49#define BRCMF_PNO_SCAN_INCOMPLETE 0
50
51#define TLV_LEN_OFF 1 /* length offset */
52#define TLV_HDR_LEN 2 /* header length */
53#define TLV_BODY_OFF 2 /* body offset */
54#define TLV_OUI_LEN 3 /* oui id length */
55#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56#define WPA_OUI_TYPE 1
57#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58#define WME_OUI_TYPE 2
59
60#define VS_IE_FIXED_HDR_LEN 6
61#define WPA_IE_VERSION_LEN 2
62#define WPA_IE_MIN_OUI_LEN 4
63#define WPA_IE_SUITE_COUNT_LEN 2
64
65#define WPA_CIPHER_NONE 0 /* None */
66#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
70
71#define RSN_AKM_NONE 0 /* None (IBSS) */
72#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73#define RSN_AKM_PSK 2 /* Pre-shared Key */
74#define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
76
77#define VNDR_IE_CMD_LEN 4 /* length of the set command
78 * string :"add", "del" (+ NUL)
79 */
80#define VNDR_IE_COUNT_OFFSET 4
81#define VNDR_IE_PKTFLAG_OFFSET 8
82#define VNDR_IE_VSIE_OFFSET 12
83#define VNDR_IE_HDR_SIZE 12
84#define VNDR_IE_BEACON_FLAG 0x1
85#define VNDR_IE_PRBRSP_FLAG 0x2
86#define MAX_VNDR_IE_NUMBER 5
87
88#define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
89#define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90
38#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ 91#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
39 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16)) 92 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
40 93
@@ -42,33 +95,12 @@ static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
42 95
43static u32 brcmf_dbg_level = WL_DBG_ERR; 96static u32 brcmf_dbg_level = WL_DBG_ERR;
44 97
45static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
46{
47 dev->driver_data = data;
48}
49
50static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
51{
52 void *data = NULL;
53
54 if (dev)
55 data = dev->driver_data;
56 return data;
57}
58
59static
60struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
61{
62 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
63 return ci->cfg_priv;
64}
65
66static bool check_sys_up(struct wiphy *wiphy) 98static bool check_sys_up(struct wiphy *wiphy)
67{ 99{
68 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 100 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
69 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 101 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
70 WL_INFO("device is not ready : status (%d)\n", 102 WL_INFO("device is not ready : status (%d)\n",
71 (int)cfg_priv->status); 103 (int)cfg->status);
72 return false; 104 return false;
73 } 105 }
74 return true; 106 return true;
@@ -256,6 +288,25 @@ struct brcmf_tlv {
256 u8 data[1]; 288 u8 data[1];
257}; 289};
258 290
291/* Vendor specific ie. id = 221, oui and type defines exact ie */
292struct brcmf_vs_tlv {
293 u8 id;
294 u8 len;
295 u8 oui[3];
296 u8 oui_type;
297};
298
299struct parsed_vndr_ie_info {
300 u8 *ie_ptr;
301 u32 ie_len; /* total length including id & length field */
302 struct brcmf_vs_tlv vndrie;
303};
304
305struct parsed_vndr_ies {
306 u32 count;
307 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
308};
309
259/* Quarter dBm units to mW 310/* Quarter dBm units to mW
260 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 311 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
261 * Table is offset so the last entry is largest mW value that fits in 312 * Table is offset so the last entry is largest mW value that fits in
@@ -353,6 +404,44 @@ brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
353 return err; 404 return err;
354} 405}
355 406
407static s32
408brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
409 void *param, s32 paramlen,
410 void *buf, s32 buflen, s32 bssidx)
411{
412 s32 err = -ENOMEM;
413 u32 len;
414
415 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
416 buf, buflen, bssidx);
417 BUG_ON(!len);
418 if (len > 0)
419 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
420 if (err)
421 WL_ERR("error (%d)\n", err);
422
423 return err;
424}
425
426static s32
427brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
428 void *param, s32 paramlen,
429 void *buf, s32 buflen, s32 bssidx)
430{
431 s32 err = -ENOMEM;
432 u32 len;
433
434 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
435 buf, buflen, bssidx);
436 BUG_ON(!len);
437 if (len > 0)
438 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
439 if (err)
440 WL_ERR("error (%d)\n", err);
441
442 return err;
443}
444
356static void convert_key_from_CPU(struct brcmf_wsec_key *key, 445static void convert_key_from_CPU(struct brcmf_wsec_key *key,
357 struct brcmf_wsec_key_le *key_le) 446 struct brcmf_wsec_key_le *key_le)
358{ 447{
@@ -367,16 +456,22 @@ static void convert_key_from_CPU(struct brcmf_wsec_key *key,
367 memcpy(key_le->ea, key->ea, sizeof(key->ea)); 456 memcpy(key_le->ea, key->ea, sizeof(key->ea));
368} 457}
369 458
370static int send_key_to_dongle(struct net_device *ndev, 459static int
371 struct brcmf_wsec_key *key) 460send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
461 struct net_device *ndev, struct brcmf_wsec_key *key)
372{ 462{
373 int err; 463 int err;
374 struct brcmf_wsec_key_le key_le; 464 struct brcmf_wsec_key_le key_le;
375 465
376 convert_key_from_CPU(key, &key_le); 466 convert_key_from_CPU(key, &key_le);
377 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le)); 467
468 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
469 sizeof(key_le),
470 cfg->extra_buf,
471 WL_EXTRA_BUF_MAX, bssidx);
472
378 if (err) 473 if (err)
379 WL_ERR("WLC_SET_KEY error (%d)\n", err); 474 WL_ERR("wsec_key error (%d)\n", err);
380 return err; 475 return err;
381} 476}
382 477
@@ -385,14 +480,12 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
385 enum nl80211_iftype type, u32 *flags, 480 enum nl80211_iftype type, u32 *flags,
386 struct vif_params *params) 481 struct vif_params *params)
387{ 482{
388 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 483 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
389 struct wireless_dev *wdev;
390 s32 infra = 0; 484 s32 infra = 0;
485 s32 ap = 0;
391 s32 err = 0; 486 s32 err = 0;
392 487
393 WL_TRACE("Enter\n"); 488 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
394 if (!check_sys_up(wiphy))
395 return -EIO;
396 489
397 switch (type) { 490 switch (type) {
398 case NL80211_IFTYPE_MONITOR: 491 case NL80211_IFTYPE_MONITOR:
@@ -401,29 +494,44 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
401 type); 494 type);
402 return -EOPNOTSUPP; 495 return -EOPNOTSUPP;
403 case NL80211_IFTYPE_ADHOC: 496 case NL80211_IFTYPE_ADHOC:
404 cfg_priv->conf->mode = WL_MODE_IBSS; 497 cfg->conf->mode = WL_MODE_IBSS;
405 infra = 0; 498 infra = 0;
406 break; 499 break;
407 case NL80211_IFTYPE_STATION: 500 case NL80211_IFTYPE_STATION:
408 cfg_priv->conf->mode = WL_MODE_BSS; 501 cfg->conf->mode = WL_MODE_BSS;
409 infra = 1; 502 infra = 1;
410 break; 503 break;
504 case NL80211_IFTYPE_AP:
505 cfg->conf->mode = WL_MODE_AP;
506 ap = 1;
507 break;
411 default: 508 default:
412 err = -EINVAL; 509 err = -EINVAL;
413 goto done; 510 goto done;
414 } 511 }
415 512
416 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra); 513 if (ap) {
417 if (err) { 514 set_bit(WL_STATUS_AP_CREATING, &cfg->status);
418 WL_ERR("WLC_SET_INFRA error (%d)\n", err); 515 if (!cfg->ap_info)
419 err = -EAGAIN; 516 cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
517 GFP_KERNEL);
518 if (!cfg->ap_info) {
519 err = -ENOMEM;
520 goto done;
521 }
522 WL_INFO("IF Type = AP\n");
420 } else { 523 } else {
421 wdev = ndev->ieee80211_ptr; 524 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
422 wdev->iftype = type; 525 if (err) {
526 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
527 err = -EAGAIN;
528 goto done;
529 }
530 WL_INFO("IF Type = %s\n",
531 (cfg->conf->mode == WL_MODE_IBSS) ?
532 "Adhoc" : "Infra");
423 } 533 }
424 534 ndev->ieee80211_ptr->iftype = type;
425 WL_INFO("IF Type = %s\n",
426 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
427 535
428done: 536done:
429 WL_TRACE("Exit\n"); 537 WL_TRACE("Exit\n");
@@ -474,12 +582,55 @@ brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
474 return err; 582 return err;
475} 583}
476 584
585static s32
586brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
587 s32 bssidx)
588{
589 s8 buf[BRCMF_DCMD_SMLEN];
590 __le32 val_le;
591
592 val_le = cpu_to_le32(val);
593
594 return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
595 sizeof(val_le), buf, sizeof(buf),
596 bssidx);
597}
598
599static s32
600brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
601 s32 bssidx)
602{
603 s8 buf[BRCMF_DCMD_SMLEN];
604 s32 err;
605 __le32 val_le;
606
607 memset(buf, 0, sizeof(buf));
608 err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
609 sizeof(buf), bssidx);
610 if (err == 0) {
611 memcpy(&val_le, buf, sizeof(val_le));
612 *val = le32_to_cpu(val_le);
613 }
614 return err;
615}
616
617
618/*
619 * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
620 * should return the ndev matching bssidx.
621 */
622static s32
623brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
624{
625 return 0;
626}
627
477static void brcmf_set_mpc(struct net_device *ndev, int mpc) 628static void brcmf_set_mpc(struct net_device *ndev, int mpc)
478{ 629{
479 s32 err = 0; 630 s32 err = 0;
480 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 631 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
481 632
482 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { 633 if (test_bit(WL_STATUS_READY, &cfg->status)) {
483 err = brcmf_dev_intvar_set(ndev, "mpc", mpc); 634 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
484 if (err) { 635 if (err) {
485 WL_ERR("fail to set mpc\n"); 636 WL_ERR("fail to set mpc\n");
@@ -489,8 +640,8 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
489 } 640 }
490} 641}
491 642
492static void wl_iscan_prep(struct brcmf_scan_params_le *params_le, 643static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
493 struct brcmf_ssid *ssid) 644 struct brcmf_ssid *ssid)
494{ 645{
495 memcpy(params_le->bssid, ether_bcast, ETH_ALEN); 646 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
496 params_le->bss_type = DOT11_BSSTYPE_ANY; 647 params_le->bss_type = DOT11_BSSTYPE_ANY;
@@ -546,7 +697,7 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
546 return -ENOMEM; 697 return -ENOMEM;
547 BUG_ON(params_size >= BRCMF_DCMD_SMLEN); 698 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
548 699
549 wl_iscan_prep(&params->params_le, ssid); 700 brcmf_iscan_prep(&params->params_le, ssid);
550 701
551 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION); 702 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
552 params->action = cpu_to_le16(action); 703 params->action = cpu_to_le16(action);
@@ -565,10 +716,10 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
565 return err; 716 return err;
566} 717}
567 718
568static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv) 719static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
569{ 720{
570 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 721 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
571 struct net_device *ndev = cfg_to_ndev(cfg_priv); 722 struct net_device *ndev = cfg_to_ndev(cfg);
572 struct brcmf_ssid ssid; 723 struct brcmf_ssid ssid;
573 __le32 passive_scan; 724 __le32 passive_scan;
574 s32 err = 0; 725 s32 err = 0;
@@ -578,19 +729,19 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
578 729
579 iscan->state = WL_ISCAN_STATE_SCANING; 730 iscan->state = WL_ISCAN_STATE_SCANING;
580 731
581 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 732 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
582 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN, 733 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
583 &passive_scan, sizeof(passive_scan)); 734 &passive_scan, sizeof(passive_scan));
584 if (err) { 735 if (err) {
585 WL_ERR("error (%d)\n", err); 736 WL_ERR("error (%d)\n", err);
586 return err; 737 return err;
587 } 738 }
588 brcmf_set_mpc(ndev, 0); 739 brcmf_set_mpc(ndev, 0);
589 cfg_priv->iscan_kickstart = true; 740 cfg->iscan_kickstart = true;
590 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); 741 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
591 if (err) { 742 if (err) {
592 brcmf_set_mpc(ndev, 1); 743 brcmf_set_mpc(ndev, 1);
593 cfg_priv->iscan_kickstart = false; 744 cfg->iscan_kickstart = false;
594 return err; 745 return err;
595 } 746 }
596 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 747 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -599,31 +750,31 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
599} 750}
600 751
601static s32 752static s32
602__brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, 753brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
603 struct cfg80211_scan_request *request, 754 struct cfg80211_scan_request *request,
604 struct cfg80211_ssid *this_ssid) 755 struct cfg80211_ssid *this_ssid)
605{ 756{
606 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 757 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
607 struct cfg80211_ssid *ssids; 758 struct cfg80211_ssid *ssids;
608 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int; 759 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
609 __le32 passive_scan; 760 __le32 passive_scan;
610 bool iscan_req; 761 bool iscan_req;
611 bool spec_scan; 762 bool spec_scan;
612 s32 err = 0; 763 s32 err = 0;
613 u32 SSID_len; 764 u32 SSID_len;
614 765
615 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 766 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
616 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status); 767 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
617 return -EAGAIN; 768 return -EAGAIN;
618 } 769 }
619 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) { 770 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
620 WL_ERR("Scanning being aborted : status (%lu)\n", 771 WL_ERR("Scanning being aborted : status (%lu)\n",
621 cfg_priv->status); 772 cfg->status);
622 return -EAGAIN; 773 return -EAGAIN;
623 } 774 }
624 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 775 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
625 WL_ERR("Connecting : status (%lu)\n", 776 WL_ERR("Connecting : status (%lu)\n",
626 cfg_priv->status); 777 cfg->status);
627 return -EAGAIN; 778 return -EAGAIN;
628 } 779 }
629 780
@@ -632,7 +783,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
632 if (request) { 783 if (request) {
633 /* scan bss */ 784 /* scan bss */
634 ssids = request->ssids; 785 ssids = request->ssids;
635 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len)) 786 if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
636 iscan_req = true; 787 iscan_req = true;
637 } else { 788 } else {
638 /* scan in ibss */ 789 /* scan in ibss */
@@ -640,10 +791,10 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
640 ssids = this_ssid; 791 ssids = this_ssid;
641 } 792 }
642 793
643 cfg_priv->scan_request = request; 794 cfg->scan_request = request;
644 set_bit(WL_STATUS_SCANNING, &cfg_priv->status); 795 set_bit(WL_STATUS_SCANNING, &cfg->status);
645 if (iscan_req) { 796 if (iscan_req) {
646 err = brcmf_do_iscan(cfg_priv); 797 err = brcmf_do_iscan(cfg);
647 if (!err) 798 if (!err)
648 return err; 799 return err;
649 else 800 else
@@ -662,7 +813,7 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
662 WL_SCAN("Broadcast scan\n"); 813 WL_SCAN("Broadcast scan\n");
663 } 814 }
664 815
665 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1); 816 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
666 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN, 817 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
667 &passive_scan, sizeof(passive_scan)); 818 &passive_scan, sizeof(passive_scan));
668 if (err) { 819 if (err) {
@@ -687,8 +838,346 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
687 return 0; 838 return 0;
688 839
689scan_out: 840scan_out:
690 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status); 841 clear_bit(WL_STATUS_SCANNING, &cfg->status);
691 cfg_priv->scan_request = NULL; 842 cfg->scan_request = NULL;
843 return err;
844}
845
846static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
847 struct cfg80211_scan_request *request)
848{
849 u32 n_ssids;
850 u32 n_channels;
851 s32 i;
852 s32 offset;
853 u16 chanspec;
854 u16 channel;
855 struct ieee80211_channel *req_channel;
856 char *ptr;
857 struct brcmf_ssid_le ssid_le;
858
859 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
860 params_le->bss_type = DOT11_BSSTYPE_ANY;
861 params_le->scan_type = 0;
862 params_le->channel_num = 0;
863 params_le->nprobes = cpu_to_le32(-1);
864 params_le->active_time = cpu_to_le32(-1);
865 params_le->passive_time = cpu_to_le32(-1);
866 params_le->home_time = cpu_to_le32(-1);
867 memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
868
869 /* if request is null exit so it will be all channel broadcast scan */
870 if (!request)
871 return;
872
873 n_ssids = request->n_ssids;
874 n_channels = request->n_channels;
875 /* Copy channel array if applicable */
876 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
877 if (n_channels > 0) {
878 for (i = 0; i < n_channels; i++) {
879 chanspec = 0;
880 req_channel = request->channels[i];
881 channel = ieee80211_frequency_to_channel(
882 req_channel->center_freq);
883 if (req_channel->band == IEEE80211_BAND_2GHZ)
884 chanspec |= WL_CHANSPEC_BAND_2G;
885 else
886 chanspec |= WL_CHANSPEC_BAND_5G;
887
888 if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
889 chanspec |= WL_CHANSPEC_BW_20;
890 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
891 } else {
892 chanspec |= WL_CHANSPEC_BW_40;
893 if (req_channel->flags &
894 IEEE80211_CHAN_NO_HT40PLUS)
895 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
896 else
897 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
898 }
899
900 chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
901 WL_SCAN("Chan : %d, Channel spec: %x\n",
902 channel, chanspec);
903 params_le->channel_list[i] = cpu_to_le16(chanspec);
904 }
905 } else {
906 WL_SCAN("Scanning all channels\n");
907 }
908 /* Copy ssid array if applicable */
909 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
910 if (n_ssids > 0) {
911 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
912 n_channels * sizeof(u16);
913 offset = roundup(offset, sizeof(u32));
914 ptr = (char *)params_le + offset;
915 for (i = 0; i < n_ssids; i++) {
916 memset(&ssid_le, 0, sizeof(ssid_le));
917 ssid_le.SSID_len =
918 cpu_to_le32(request->ssids[i].ssid_len);
919 memcpy(ssid_le.SSID, request->ssids[i].ssid,
920 request->ssids[i].ssid_len);
921 if (!ssid_le.SSID_len)
922 WL_SCAN("%d: Broadcast scan\n", i);
923 else
924 WL_SCAN("%d: scan for %s size =%d\n", i,
925 ssid_le.SSID, ssid_le.SSID_len);
926 memcpy(ptr, &ssid_le, sizeof(ssid_le));
927 ptr += sizeof(ssid_le);
928 }
929 } else {
930 WL_SCAN("Broadcast scan %p\n", request->ssids);
931 if ((request->ssids) && request->ssids->ssid_len) {
932 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
933 request->ssids->ssid_len);
934 params_le->ssid_le.SSID_len =
935 cpu_to_le32(request->ssids->ssid_len);
936 memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
937 request->ssids->ssid_len);
938 }
939 }
940 /* Adding mask to channel numbers */
941 params_le->channel_num =
942 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
943 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
944}
945
946static s32
947brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
948 struct net_device *ndev,
949 bool aborted, bool fw_abort)
950{
951 struct brcmf_scan_params_le params_le;
952 struct cfg80211_scan_request *scan_request;
953 s32 err = 0;
954
955 WL_SCAN("Enter\n");
956
957 /* clear scan request, because the FW abort can cause a second call */
958 /* to this functon and might cause a double cfg80211_scan_done */
959 scan_request = cfg->scan_request;
960 cfg->scan_request = NULL;
961
962 if (timer_pending(&cfg->escan_timeout))
963 del_timer_sync(&cfg->escan_timeout);
964
965 if (fw_abort) {
966 /* Do a scan abort to stop the driver's scan engine */
967 WL_SCAN("ABORT scan in firmware\n");
968 memset(&params_le, 0, sizeof(params_le));
969 memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
970 params_le.bss_type = DOT11_BSSTYPE_ANY;
971 params_le.scan_type = 0;
972 params_le.channel_num = cpu_to_le32(1);
973 params_le.nprobes = cpu_to_le32(1);
974 params_le.active_time = cpu_to_le32(-1);
975 params_le.passive_time = cpu_to_le32(-1);
976 params_le.home_time = cpu_to_le32(-1);
977 /* Scan is aborted by setting channel_list[0] to -1 */
978 params_le.channel_list[0] = cpu_to_le16(-1);
979 /* E-Scan (or anyother type) can be aborted by SCAN */
980 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &params_le,
981 sizeof(params_le));
982 if (err)
983 WL_ERR("Scan abort failed\n");
984 }
985 /*
986 * e-scan can be initiated by scheduled scan
987 * which takes precedence.
988 */
989 if (cfg->sched_escan) {
990 WL_SCAN("scheduled scan completed\n");
991 cfg->sched_escan = false;
992 if (!aborted)
993 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
994 brcmf_set_mpc(ndev, 1);
995 } else if (scan_request) {
996 WL_SCAN("ESCAN Completed scan: %s\n",
997 aborted ? "Aborted" : "Done");
998 cfg80211_scan_done(scan_request, aborted);
999 brcmf_set_mpc(ndev, 1);
1000 }
1001 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
1002 WL_ERR("Scan complete while device not scanning\n");
1003 return -EPERM;
1004 }
1005
1006 return err;
1007}
1008
1009static s32
1010brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
1011 struct cfg80211_scan_request *request, u16 action)
1012{
1013 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1014 offsetof(struct brcmf_escan_params_le, params_le);
1015 struct brcmf_escan_params_le *params;
1016 s32 err = 0;
1017
1018 WL_SCAN("E-SCAN START\n");
1019
1020 if (request != NULL) {
1021 /* Allocate space for populating ssids in struct */
1022 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1023
1024 /* Allocate space for populating ssids in struct */
1025 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
1026 }
1027
1028 params = kzalloc(params_size, GFP_KERNEL);
1029 if (!params) {
1030 err = -ENOMEM;
1031 goto exit;
1032 }
1033 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1034 brcmf_escan_prep(&params->params_le, request);
1035 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1036 params->action = cpu_to_le16(action);
1037 params->sync_id = cpu_to_le16(0x1234);
1038
1039 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
1040 cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
1041 if (err) {
1042 if (err == -EBUSY)
1043 WL_INFO("system busy : escan canceled\n");
1044 else
1045 WL_ERR("error (%d)\n", err);
1046 }
1047
1048 kfree(params);
1049exit:
1050 return err;
1051}
1052
1053static s32
1054brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1055 struct net_device *ndev, struct cfg80211_scan_request *request)
1056{
1057 s32 err;
1058 __le32 passive_scan;
1059 struct brcmf_scan_results *results;
1060
1061 WL_SCAN("Enter\n");
1062 cfg->escan_info.ndev = ndev;
1063 cfg->escan_info.wiphy = wiphy;
1064 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
1065 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1066 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1067 &passive_scan, sizeof(passive_scan));
1068 if (err) {
1069 WL_ERR("error (%d)\n", err);
1070 return err;
1071 }
1072 brcmf_set_mpc(ndev, 0);
1073 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1074 results->version = 0;
1075 results->count = 0;
1076 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1077
1078 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
1079 if (err)
1080 brcmf_set_mpc(ndev, 1);
1081 return err;
1082}
1083
1084static s32
1085brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1086 struct cfg80211_scan_request *request,
1087 struct cfg80211_ssid *this_ssid)
1088{
1089 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1090 struct cfg80211_ssid *ssids;
1091 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
1092 __le32 passive_scan;
1093 bool escan_req;
1094 bool spec_scan;
1095 s32 err;
1096 u32 SSID_len;
1097
1098 WL_SCAN("START ESCAN\n");
1099
1100 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
1101 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
1102 return -EAGAIN;
1103 }
1104 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
1105 WL_ERR("Scanning being aborted : status (%lu)\n",
1106 cfg->status);
1107 return -EAGAIN;
1108 }
1109 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
1110 WL_ERR("Connecting : status (%lu)\n",
1111 cfg->status);
1112 return -EAGAIN;
1113 }
1114
1115 /* Arm scan timeout timer */
1116 mod_timer(&cfg->escan_timeout, jiffies +
1117 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1118
1119 escan_req = false;
1120 if (request) {
1121 /* scan bss */
1122 ssids = request->ssids;
1123 escan_req = true;
1124 } else {
1125 /* scan in ibss */
1126 /* we don't do escan in ibss */
1127 ssids = this_ssid;
1128 }
1129
1130 cfg->scan_request = request;
1131 set_bit(WL_STATUS_SCANNING, &cfg->status);
1132 if (escan_req) {
1133 err = brcmf_do_escan(cfg, wiphy, ndev, request);
1134 if (!err)
1135 return err;
1136 else
1137 goto scan_out;
1138 } else {
1139 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
1140 ssids->ssid, ssids->ssid_len);
1141 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1142 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1143 sr->ssid_le.SSID_len = cpu_to_le32(0);
1144 spec_scan = false;
1145 if (SSID_len) {
1146 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1147 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1148 spec_scan = true;
1149 } else
1150 WL_SCAN("Broadcast scan\n");
1151
1152 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1154 &passive_scan, sizeof(passive_scan));
1155 if (err) {
1156 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1157 goto scan_out;
1158 }
1159 brcmf_set_mpc(ndev, 0);
1160 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
1161 sizeof(sr->ssid_le));
1162 if (err) {
1163 if (err == -EBUSY)
1164 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1165 sr->ssid_le.SSID);
1166 else
1167 WL_ERR("WLC_SCAN error (%d)\n", err);
1168
1169 brcmf_set_mpc(ndev, 1);
1170 goto scan_out;
1171 }
1172 }
1173
1174 return 0;
1175
1176scan_out:
1177 clear_bit(WL_STATUS_SCANNING, &cfg->status);
1178 if (timer_pending(&cfg->escan_timeout))
1179 del_timer_sync(&cfg->escan_timeout);
1180 cfg->scan_request = NULL;
692 return err; 1181 return err;
693} 1182}
694 1183
@@ -697,6 +1186,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
697 struct cfg80211_scan_request *request) 1186 struct cfg80211_scan_request *request)
698{ 1187{
699 struct net_device *ndev = request->wdev->netdev; 1188 struct net_device *ndev = request->wdev->netdev;
1189 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
700 s32 err = 0; 1190 s32 err = 0;
701 1191
702 WL_TRACE("Enter\n"); 1192 WL_TRACE("Enter\n");
@@ -704,7 +1194,11 @@ brcmf_cfg80211_scan(struct wiphy *wiphy,
704 if (!check_sys_up(wiphy)) 1194 if (!check_sys_up(wiphy))
705 return -EIO; 1195 return -EIO;
706 1196
707 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL); 1197 if (cfg->iscan_on)
1198 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1199 else if (cfg->escan_on)
1200 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1201
708 if (err) 1202 if (err)
709 WL_ERR("scan error (%d)\n", err); 1203 WL_ERR("scan error (%d)\n", err);
710 1204
@@ -749,8 +1243,8 @@ static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
749 1243
750static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) 1244static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
751{ 1245{
752 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1246 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
753 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1247 struct net_device *ndev = cfg_to_ndev(cfg);
754 s32 err = 0; 1248 s32 err = 0;
755 1249
756 WL_TRACE("Enter\n"); 1250 WL_TRACE("Enter\n");
@@ -758,30 +1252,30 @@ static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
758 return -EIO; 1252 return -EIO;
759 1253
760 if (changed & WIPHY_PARAM_RTS_THRESHOLD && 1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
761 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) { 1255 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
762 cfg_priv->conf->rts_threshold = wiphy->rts_threshold; 1256 cfg->conf->rts_threshold = wiphy->rts_threshold;
763 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold); 1257 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
764 if (!err) 1258 if (!err)
765 goto done; 1259 goto done;
766 } 1260 }
767 if (changed & WIPHY_PARAM_FRAG_THRESHOLD && 1261 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
768 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) { 1262 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
769 cfg_priv->conf->frag_threshold = wiphy->frag_threshold; 1263 cfg->conf->frag_threshold = wiphy->frag_threshold;
770 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold); 1264 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
771 if (!err) 1265 if (!err)
772 goto done; 1266 goto done;
773 } 1267 }
774 if (changed & WIPHY_PARAM_RETRY_LONG 1268 if (changed & WIPHY_PARAM_RETRY_LONG
775 && (cfg_priv->conf->retry_long != wiphy->retry_long)) { 1269 && (cfg->conf->retry_long != wiphy->retry_long)) {
776 cfg_priv->conf->retry_long = wiphy->retry_long; 1270 cfg->conf->retry_long = wiphy->retry_long;
777 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true); 1271 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
778 if (!err) 1272 if (!err)
779 goto done; 1273 goto done;
780 } 1274 }
781 if (changed & WIPHY_PARAM_RETRY_SHORT 1275 if (changed & WIPHY_PARAM_RETRY_SHORT
782 && (cfg_priv->conf->retry_short != wiphy->retry_short)) { 1276 && (cfg->conf->retry_short != wiphy->retry_short)) {
783 cfg_priv->conf->retry_short = wiphy->retry_short; 1277 cfg->conf->retry_short = wiphy->retry_short;
784 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false); 1278 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
785 if (!err) 1279 if (!err)
786 goto done; 1280 goto done;
787 } 1281 }
@@ -791,61 +1285,6 @@ done:
791 return err; 1285 return err;
792} 1286}
793 1287
794static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
795{
796 switch (item) {
797 case WL_PROF_SEC:
798 return &cfg_priv->profile->sec;
799 case WL_PROF_BSSID:
800 return &cfg_priv->profile->bssid;
801 case WL_PROF_SSID:
802 return &cfg_priv->profile->ssid;
803 }
804 WL_ERR("invalid item (%d)\n", item);
805 return NULL;
806}
807
808static s32
809brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
810 const struct brcmf_event_msg *e, void *data, s32 item)
811{
812 s32 err = 0;
813 struct brcmf_ssid *ssid;
814
815 switch (item) {
816 case WL_PROF_SSID:
817 ssid = (struct brcmf_ssid *) data;
818 memset(cfg_priv->profile->ssid.SSID, 0,
819 sizeof(cfg_priv->profile->ssid.SSID));
820 memcpy(cfg_priv->profile->ssid.SSID,
821 ssid->SSID, ssid->SSID_len);
822 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
823 break;
824 case WL_PROF_BSSID:
825 if (data)
826 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
827 else
828 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
829 break;
830 case WL_PROF_SEC:
831 memcpy(&cfg_priv->profile->sec, data,
832 sizeof(cfg_priv->profile->sec));
833 break;
834 case WL_PROF_BEACONINT:
835 cfg_priv->profile->beacon_interval = *(u16 *)data;
836 break;
837 case WL_PROF_DTIMPERIOD:
838 cfg_priv->profile->dtim_period = *(u8 *)data;
839 break;
840 default:
841 WL_ERR("unsupported item (%d)\n", item);
842 err = -EOPNOTSUPP;
843 break;
844 }
845
846 return err;
847}
848
849static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof) 1288static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
850{ 1289{
851 memset(prof, 0, sizeof(*prof)); 1290 memset(prof, 0, sizeof(*prof));
@@ -878,20 +1317,20 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
878 } 1317 }
879} 1318}
880 1319
881static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv) 1320static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
882{ 1321{
883 struct net_device *ndev = NULL; 1322 struct net_device *ndev = NULL;
884 s32 err = 0; 1323 s32 err = 0;
885 1324
886 WL_TRACE("Enter\n"); 1325 WL_TRACE("Enter\n");
887 1326
888 if (cfg_priv->link_up) { 1327 if (cfg->link_up) {
889 ndev = cfg_to_ndev(cfg_priv); 1328 ndev = cfg_to_ndev(cfg);
890 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n "); 1329 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
891 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0); 1330 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
892 if (err) 1331 if (err)
893 WL_ERR("WLC_DISASSOC failed (%d)\n", err); 1332 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
894 cfg_priv->link_up = false; 1333 cfg->link_up = false;
895 } 1334 }
896 WL_TRACE("Exit\n"); 1335 WL_TRACE("Exit\n");
897} 1336}
@@ -900,13 +1339,13 @@ static s32
900brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev, 1339brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
901 struct cfg80211_ibss_params *params) 1340 struct cfg80211_ibss_params *params)
902{ 1341{
903 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1342 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1343 struct brcmf_cfg80211_profile *profile = cfg->profile;
904 struct brcmf_join_params join_params; 1344 struct brcmf_join_params join_params;
905 size_t join_params_size = 0; 1345 size_t join_params_size = 0;
906 s32 err = 0; 1346 s32 err = 0;
907 s32 wsec = 0; 1347 s32 wsec = 0;
908 s32 bcnprd; 1348 s32 bcnprd;
909 struct brcmf_ssid ssid;
910 1349
911 WL_TRACE("Enter\n"); 1350 WL_TRACE("Enter\n");
912 if (!check_sys_up(wiphy)) 1351 if (!check_sys_up(wiphy))
@@ -919,7 +1358,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
919 return -EOPNOTSUPP; 1358 return -EOPNOTSUPP;
920 } 1359 }
921 1360
922 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1361 set_bit(WL_STATUS_CONNECTING, &cfg->status);
923 1362
924 if (params->bssid) 1363 if (params->bssid)
925 WL_CONN("BSSID: %pM\n", params->bssid); 1364 WL_CONN("BSSID: %pM\n", params->bssid);
@@ -982,40 +1421,38 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
982 memset(&join_params, 0, sizeof(struct brcmf_join_params)); 1421 memset(&join_params, 0, sizeof(struct brcmf_join_params));
983 1422
984 /* SSID */ 1423 /* SSID */
985 ssid.SSID_len = min_t(u32, params->ssid_len, 32); 1424 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
986 memcpy(ssid.SSID, params->ssid, ssid.SSID_len); 1425 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
987 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len); 1426 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
988 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1427 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
989 join_params_size = sizeof(join_params.ssid_le); 1428 join_params_size = sizeof(join_params.ssid_le);
990 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
991 1429
992 /* BSSID */ 1430 /* BSSID */
993 if (params->bssid) { 1431 if (params->bssid) {
994 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN); 1432 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
995 join_params_size = sizeof(join_params.ssid_le) + 1433 join_params_size = sizeof(join_params.ssid_le) +
996 BRCMF_ASSOC_PARAMS_FIXED_SIZE; 1434 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1435 memcpy(profile->bssid, params->bssid, ETH_ALEN);
997 } else { 1436 } else {
998 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1437 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1438 memset(profile->bssid, 0, ETH_ALEN);
999 } 1439 }
1000 1440
1001 brcmf_update_prof(cfg_priv, NULL,
1002 &join_params.params_le.bssid, WL_PROF_BSSID);
1003
1004 /* Channel */ 1441 /* Channel */
1005 if (params->channel) { 1442 if (params->channel) {
1006 u32 target_channel; 1443 u32 target_channel;
1007 1444
1008 cfg_priv->channel = 1445 cfg->channel =
1009 ieee80211_frequency_to_channel( 1446 ieee80211_frequency_to_channel(
1010 params->channel->center_freq); 1447 params->channel->center_freq);
1011 if (params->channel_fixed) { 1448 if (params->channel_fixed) {
1012 /* adding chanspec */ 1449 /* adding chanspec */
1013 brcmf_ch_to_chanspec(cfg_priv->channel, 1450 brcmf_ch_to_chanspec(cfg->channel,
1014 &join_params, &join_params_size); 1451 &join_params, &join_params_size);
1015 } 1452 }
1016 1453
1017 /* set channel for starter */ 1454 /* set channel for starter */
1018 target_channel = cfg_priv->channel; 1455 target_channel = cfg->channel;
1019 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL, 1456 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1020 &target_channel); 1457 &target_channel);
1021 if (err) { 1458 if (err) {
@@ -1023,9 +1460,9 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1023 goto done; 1460 goto done;
1024 } 1461 }
1025 } else 1462 } else
1026 cfg_priv->channel = 0; 1463 cfg->channel = 0;
1027 1464
1028 cfg_priv->ibss_starter = false; 1465 cfg->ibss_starter = false;
1029 1466
1030 1467
1031 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1468 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
@@ -1037,7 +1474,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1037 1474
1038done: 1475done:
1039 if (err) 1476 if (err)
1040 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1477 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1041 WL_TRACE("Exit\n"); 1478 WL_TRACE("Exit\n");
1042 return err; 1479 return err;
1043} 1480}
@@ -1045,14 +1482,14 @@ done:
1045static s32 1482static s32
1046brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev) 1483brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1047{ 1484{
1048 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1485 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1049 s32 err = 0; 1486 s32 err = 0;
1050 1487
1051 WL_TRACE("Enter\n"); 1488 WL_TRACE("Enter\n");
1052 if (!check_sys_up(wiphy)) 1489 if (!check_sys_up(wiphy))
1053 return -EIO; 1490 return -EIO;
1054 1491
1055 brcmf_link_down(cfg_priv); 1492 brcmf_link_down(cfg);
1056 1493
1057 WL_TRACE("Exit\n"); 1494 WL_TRACE("Exit\n");
1058 1495
@@ -1062,7 +1499,8 @@ brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1062static s32 brcmf_set_wpa_version(struct net_device *ndev, 1499static s32 brcmf_set_wpa_version(struct net_device *ndev,
1063 struct cfg80211_connect_params *sme) 1500 struct cfg80211_connect_params *sme)
1064{ 1501{
1065 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1502 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1503 struct brcmf_cfg80211_profile *profile = cfg->profile;
1066 struct brcmf_cfg80211_security *sec; 1504 struct brcmf_cfg80211_security *sec;
1067 s32 val = 0; 1505 s32 val = 0;
1068 s32 err = 0; 1506 s32 err = 0;
@@ -1079,7 +1517,7 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1079 WL_ERR("set wpa_auth failed (%d)\n", err); 1517 WL_ERR("set wpa_auth failed (%d)\n", err);
1080 return err; 1518 return err;
1081 } 1519 }
1082 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1520 sec = &profile->sec;
1083 sec->wpa_versions = sme->crypto.wpa_versions; 1521 sec->wpa_versions = sme->crypto.wpa_versions;
1084 return err; 1522 return err;
1085} 1523}
@@ -1087,7 +1525,8 @@ static s32 brcmf_set_wpa_version(struct net_device *ndev,
1087static s32 brcmf_set_auth_type(struct net_device *ndev, 1525static s32 brcmf_set_auth_type(struct net_device *ndev,
1088 struct cfg80211_connect_params *sme) 1526 struct cfg80211_connect_params *sme)
1089{ 1527{
1090 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1528 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1529 struct brcmf_cfg80211_profile *profile = cfg->profile;
1091 struct brcmf_cfg80211_security *sec; 1530 struct brcmf_cfg80211_security *sec;
1092 s32 val = 0; 1531 s32 val = 0;
1093 s32 err = 0; 1532 s32 err = 0;
@@ -1118,7 +1557,7 @@ static s32 brcmf_set_auth_type(struct net_device *ndev,
1118 WL_ERR("set auth failed (%d)\n", err); 1557 WL_ERR("set auth failed (%d)\n", err);
1119 return err; 1558 return err;
1120 } 1559 }
1121 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1560 sec = &profile->sec;
1122 sec->auth_type = sme->auth_type; 1561 sec->auth_type = sme->auth_type;
1123 return err; 1562 return err;
1124} 1563}
@@ -1127,7 +1566,8 @@ static s32
1127brcmf_set_set_cipher(struct net_device *ndev, 1566brcmf_set_set_cipher(struct net_device *ndev,
1128 struct cfg80211_connect_params *sme) 1567 struct cfg80211_connect_params *sme)
1129{ 1568{
1130 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1569 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1570 struct brcmf_cfg80211_profile *profile = cfg->profile;
1131 struct brcmf_cfg80211_security *sec; 1571 struct brcmf_cfg80211_security *sec;
1132 s32 pval = 0; 1572 s32 pval = 0;
1133 s32 gval = 0; 1573 s32 gval = 0;
@@ -1183,7 +1623,7 @@ brcmf_set_set_cipher(struct net_device *ndev,
1183 return err; 1623 return err;
1184 } 1624 }
1185 1625
1186 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1626 sec = &profile->sec;
1187 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0]; 1627 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1188 sec->cipher_group = sme->crypto.cipher_group; 1628 sec->cipher_group = sme->crypto.cipher_group;
1189 1629
@@ -1193,7 +1633,8 @@ brcmf_set_set_cipher(struct net_device *ndev,
1193static s32 1633static s32
1194brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) 1634brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1195{ 1635{
1196 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1636 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1637 struct brcmf_cfg80211_profile *profile = cfg->profile;
1197 struct brcmf_cfg80211_security *sec; 1638 struct brcmf_cfg80211_security *sec;
1198 s32 val = 0; 1639 s32 val = 0;
1199 s32 err = 0; 1640 s32 err = 0;
@@ -1239,74 +1680,76 @@ brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1239 return err; 1680 return err;
1240 } 1681 }
1241 } 1682 }
1242 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1683 sec = &profile->sec;
1243 sec->wpa_auth = sme->crypto.akm_suites[0]; 1684 sec->wpa_auth = sme->crypto.akm_suites[0];
1244 1685
1245 return err; 1686 return err;
1246} 1687}
1247 1688
1248static s32 1689static s32
1249brcmf_set_wep_sharedkey(struct net_device *ndev, 1690brcmf_set_sharedkey(struct net_device *ndev,
1250 struct cfg80211_connect_params *sme) 1691 struct cfg80211_connect_params *sme)
1251{ 1692{
1252 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 1693 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1694 struct brcmf_cfg80211_profile *profile = cfg->profile;
1253 struct brcmf_cfg80211_security *sec; 1695 struct brcmf_cfg80211_security *sec;
1254 struct brcmf_wsec_key key; 1696 struct brcmf_wsec_key key;
1255 s32 val; 1697 s32 val;
1256 s32 err = 0; 1698 s32 err = 0;
1699 s32 bssidx;
1257 1700
1258 WL_CONN("key len (%d)\n", sme->key_len); 1701 WL_CONN("key len (%d)\n", sme->key_len);
1259 1702
1260 if (sme->key_len == 0) 1703 if (sme->key_len == 0)
1261 return 0; 1704 return 0;
1262 1705
1263 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 1706 sec = &profile->sec;
1264 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n", 1707 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1265 sec->wpa_versions, sec->cipher_pairwise); 1708 sec->wpa_versions, sec->cipher_pairwise);
1266 1709
1267 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) 1710 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1268 return 0; 1711 return 0;
1269 1712
1270 if (sec->cipher_pairwise & 1713 if (!(sec->cipher_pairwise &
1271 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) { 1714 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1272 memset(&key, 0, sizeof(key)); 1715 return 0;
1273 key.len = (u32) sme->key_len;
1274 key.index = (u32) sme->key_idx;
1275 if (key.len > sizeof(key.data)) {
1276 WL_ERR("Too long key length (%u)\n", key.len);
1277 return -EINVAL;
1278 }
1279 memcpy(key.data, sme->key, key.len);
1280 key.flags = BRCMF_PRIMARY_KEY;
1281 switch (sec->cipher_pairwise) {
1282 case WLAN_CIPHER_SUITE_WEP40:
1283 key.algo = CRYPTO_ALGO_WEP1;
1284 break;
1285 case WLAN_CIPHER_SUITE_WEP104:
1286 key.algo = CRYPTO_ALGO_WEP128;
1287 break;
1288 default:
1289 WL_ERR("Invalid algorithm (%d)\n",
1290 sme->crypto.ciphers_pairwise[0]);
1291 return -EINVAL;
1292 }
1293 /* Set the new key/index */
1294 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1295 key.len, key.index, key.algo);
1296 WL_CONN("key \"%s\"\n", key.data);
1297 err = send_key_to_dongle(ndev, &key);
1298 if (err)
1299 return err;
1300 1716
1301 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { 1717 memset(&key, 0, sizeof(key));
1302 WL_CONN("set auth_type to shared key\n"); 1718 key.len = (u32) sme->key_len;
1303 val = 1; /* shared key */ 1719 key.index = (u32) sme->key_idx;
1304 err = brcmf_dev_intvar_set(ndev, "auth", val); 1720 if (key.len > sizeof(key.data)) {
1305 if (err) { 1721 WL_ERR("Too long key length (%u)\n", key.len);
1306 WL_ERR("set auth failed (%d)\n", err); 1722 return -EINVAL;
1307 return err; 1723 }
1308 } 1724 memcpy(key.data, sme->key, key.len);
1309 } 1725 key.flags = BRCMF_PRIMARY_KEY;
1726 switch (sec->cipher_pairwise) {
1727 case WLAN_CIPHER_SUITE_WEP40:
1728 key.algo = CRYPTO_ALGO_WEP1;
1729 break;
1730 case WLAN_CIPHER_SUITE_WEP104:
1731 key.algo = CRYPTO_ALGO_WEP128;
1732 break;
1733 default:
1734 WL_ERR("Invalid algorithm (%d)\n",
1735 sme->crypto.ciphers_pairwise[0]);
1736 return -EINVAL;
1737 }
1738 /* Set the new key/index */
1739 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1740 key.len, key.index, key.algo);
1741 WL_CONN("key \"%s\"\n", key.data);
1742 bssidx = brcmf_find_bssidx(cfg, ndev);
1743 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1744 if (err)
1745 return err;
1746
1747 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1748 WL_CONN("set auth_type to shared key\n");
1749 val = WL_AUTH_SHARED_KEY; /* shared key */
1750 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
1751 if (err)
1752 WL_ERR("set auth failed (%d)\n", err);
1310 } 1753 }
1311 return err; 1754 return err;
1312} 1755}
@@ -1315,7 +1758,8 @@ static s32
1315brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev, 1758brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1316 struct cfg80211_connect_params *sme) 1759 struct cfg80211_connect_params *sme)
1317{ 1760{
1318 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1761 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1762 struct brcmf_cfg80211_profile *profile = cfg->profile;
1319 struct ieee80211_channel *chan = sme->channel; 1763 struct ieee80211_channel *chan = sme->channel;
1320 struct brcmf_join_params join_params; 1764 struct brcmf_join_params join_params;
1321 size_t join_params_size; 1765 size_t join_params_size;
@@ -1332,15 +1776,15 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1332 return -EOPNOTSUPP; 1776 return -EOPNOTSUPP;
1333 } 1777 }
1334 1778
1335 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1779 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1336 1780
1337 if (chan) { 1781 if (chan) {
1338 cfg_priv->channel = 1782 cfg->channel =
1339 ieee80211_frequency_to_channel(chan->center_freq); 1783 ieee80211_frequency_to_channel(chan->center_freq);
1340 WL_CONN("channel (%d), center_req (%d)\n", 1784 WL_CONN("channel (%d), center_req (%d)\n",
1341 cfg_priv->channel, chan->center_freq); 1785 cfg->channel, chan->center_freq);
1342 } else 1786 } else
1343 cfg_priv->channel = 0; 1787 cfg->channel = 0;
1344 1788
1345 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); 1789 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1346 1790
@@ -1368,20 +1812,20 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1368 goto done; 1812 goto done;
1369 } 1813 }
1370 1814
1371 err = brcmf_set_wep_sharedkey(ndev, sme); 1815 err = brcmf_set_sharedkey(ndev, sme);
1372 if (err) { 1816 if (err) {
1373 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err); 1817 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1374 goto done; 1818 goto done;
1375 } 1819 }
1376 1820
1377 memset(&join_params, 0, sizeof(join_params)); 1821 memset(&join_params, 0, sizeof(join_params));
1378 join_params_size = sizeof(join_params.ssid_le); 1822 join_params_size = sizeof(join_params.ssid_le);
1379 1823
1380 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len); 1824 profile->ssid.SSID_len = min_t(u32,
1381 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len); 1825 sizeof(ssid.SSID), (u32)sme->ssid_len);
1382 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len); 1826 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1383 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len); 1827 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1384 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID); 1828 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1385 1829
1386 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN); 1830 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1387 1831
@@ -1389,7 +1833,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1389 WL_CONN("ssid \"%s\", len (%d)\n", 1833 WL_CONN("ssid \"%s\", len (%d)\n",
1390 ssid.SSID, ssid.SSID_len); 1834 ssid.SSID, ssid.SSID_len);
1391 1835
1392 brcmf_ch_to_chanspec(cfg_priv->channel, 1836 brcmf_ch_to_chanspec(cfg->channel,
1393 &join_params, &join_params_size); 1837 &join_params, &join_params_size);
1394 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, 1838 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1395 &join_params, join_params_size); 1839 &join_params, join_params_size);
@@ -1398,7 +1842,7 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1398 1842
1399done: 1843done:
1400 if (err) 1844 if (err)
1401 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 1845 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1402 WL_TRACE("Exit\n"); 1846 WL_TRACE("Exit\n");
1403 return err; 1847 return err;
1404} 1848}
@@ -1407,7 +1851,8 @@ static s32
1407brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, 1851brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1408 u16 reason_code) 1852 u16 reason_code)
1409{ 1853{
1410 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1855 struct brcmf_cfg80211_profile *profile = cfg->profile;
1411 struct brcmf_scb_val_le scbval; 1856 struct brcmf_scb_val_le scbval;
1412 s32 err = 0; 1857 s32 err = 0;
1413 1858
@@ -1415,16 +1860,16 @@ brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1415 if (!check_sys_up(wiphy)) 1860 if (!check_sys_up(wiphy))
1416 return -EIO; 1861 return -EIO;
1417 1862
1418 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 1863 clear_bit(WL_STATUS_CONNECTED, &cfg->status);
1419 1864
1420 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN); 1865 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1421 scbval.val = cpu_to_le32(reason_code); 1866 scbval.val = cpu_to_le32(reason_code);
1422 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval, 1867 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1423 sizeof(struct brcmf_scb_val_le)); 1868 sizeof(struct brcmf_scb_val_le));
1424 if (err) 1869 if (err)
1425 WL_ERR("error (%d)\n", err); 1870 WL_ERR("error (%d)\n", err);
1426 1871
1427 cfg_priv->link_up = false; 1872 cfg->link_up = false;
1428 1873
1429 WL_TRACE("Exit\n"); 1874 WL_TRACE("Exit\n");
1430 return err; 1875 return err;
@@ -1435,8 +1880,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1435 enum nl80211_tx_power_setting type, s32 mbm) 1880 enum nl80211_tx_power_setting type, s32 mbm)
1436{ 1881{
1437 1882
1438 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1883 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1439 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1884 struct net_device *ndev = cfg_to_ndev(cfg);
1440 u16 txpwrmw; 1885 u16 txpwrmw;
1441 s32 err = 0; 1886 s32 err = 0;
1442 s32 disable = 0; 1887 s32 disable = 0;
@@ -1472,7 +1917,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1472 (s32) (brcmf_mw_to_qdbm(txpwrmw))); 1917 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1473 if (err) 1918 if (err)
1474 WL_ERR("qtxpower error (%d)\n", err); 1919 WL_ERR("qtxpower error (%d)\n", err);
1475 cfg_priv->conf->tx_power = dbm; 1920 cfg->conf->tx_power = dbm;
1476 1921
1477done: 1922done:
1478 WL_TRACE("Exit\n"); 1923 WL_TRACE("Exit\n");
@@ -1481,8 +1926,8 @@ done:
1481 1926
1482static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) 1927static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1483{ 1928{
1484 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 1929 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1485 struct net_device *ndev = cfg_to_ndev(cfg_priv); 1930 struct net_device *ndev = cfg_to_ndev(cfg);
1486 s32 txpwrdbm; 1931 s32 txpwrdbm;
1487 u8 result; 1932 u8 result;
1488 s32 err = 0; 1933 s32 err = 0;
@@ -1509,16 +1954,19 @@ static s32
1509brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev, 1954brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1510 u8 key_idx, bool unicast, bool multicast) 1955 u8 key_idx, bool unicast, bool multicast)
1511{ 1956{
1957 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1512 u32 index; 1958 u32 index;
1513 u32 wsec; 1959 u32 wsec;
1514 s32 err = 0; 1960 s32 err = 0;
1961 s32 bssidx;
1515 1962
1516 WL_TRACE("Enter\n"); 1963 WL_TRACE("Enter\n");
1517 WL_CONN("key index (%d)\n", key_idx); 1964 WL_CONN("key index (%d)\n", key_idx);
1518 if (!check_sys_up(wiphy)) 1965 if (!check_sys_up(wiphy))
1519 return -EIO; 1966 return -EIO;
1520 1967
1521 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 1968 bssidx = brcmf_find_bssidx(cfg, ndev);
1969 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1522 if (err) { 1970 if (err) {
1523 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 1971 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1524 goto done; 1972 goto done;
@@ -1541,9 +1989,11 @@ static s32
1541brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, 1989brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1542 u8 key_idx, const u8 *mac_addr, struct key_params *params) 1990 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1543{ 1991{
1992 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1544 struct brcmf_wsec_key key; 1993 struct brcmf_wsec_key key;
1545 struct brcmf_wsec_key_le key_le; 1994 struct brcmf_wsec_key_le key_le;
1546 s32 err = 0; 1995 s32 err = 0;
1996 s32 bssidx;
1547 1997
1548 memset(&key, 0, sizeof(key)); 1998 memset(&key, 0, sizeof(key));
1549 key.index = (u32) key_idx; 1999 key.index = (u32) key_idx;
@@ -1552,12 +2002,13 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1552 if (!is_multicast_ether_addr(mac_addr)) 2002 if (!is_multicast_ether_addr(mac_addr))
1553 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); 2003 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1554 key.len = (u32) params->key_len; 2004 key.len = (u32) params->key_len;
2005 bssidx = brcmf_find_bssidx(cfg, ndev);
1555 /* check for key index change */ 2006 /* check for key index change */
1556 if (key.len == 0) { 2007 if (key.len == 0) {
1557 /* key delete */ 2008 /* key delete */
1558 err = send_key_to_dongle(ndev, &key); 2009 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1559 if (err) 2010 if (err)
1560 return err; 2011 WL_ERR("key delete error (%d)\n", err);
1561 } else { 2012 } else {
1562 if (key.len > sizeof(key.data)) { 2013 if (key.len > sizeof(key.data)) {
1563 WL_ERR("Invalid key length (%d)\n", key.len); 2014 WL_ERR("Invalid key length (%d)\n", key.len);
@@ -1613,12 +2064,12 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1613 convert_key_from_CPU(&key, &key_le); 2064 convert_key_from_CPU(&key, &key_le);
1614 2065
1615 brcmf_netdev_wait_pend8021x(ndev); 2066 brcmf_netdev_wait_pend8021x(ndev);
1616 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, 2067 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
1617 sizeof(key_le)); 2068 sizeof(key_le),
1618 if (err) { 2069 cfg->extra_buf,
1619 WL_ERR("WLC_SET_KEY error (%d)\n", err); 2070 WL_EXTRA_BUF_MAX, bssidx);
1620 return err; 2071 if (err)
1621 } 2072 WL_ERR("wsec_key error (%d)\n", err);
1622 } 2073 }
1623 return err; 2074 return err;
1624} 2075}
@@ -1628,11 +2079,13 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1628 u8 key_idx, bool pairwise, const u8 *mac_addr, 2079 u8 key_idx, bool pairwise, const u8 *mac_addr,
1629 struct key_params *params) 2080 struct key_params *params)
1630{ 2081{
2082 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1631 struct brcmf_wsec_key key; 2083 struct brcmf_wsec_key key;
1632 s32 val; 2084 s32 val;
1633 s32 wsec; 2085 s32 wsec;
1634 s32 err = 0; 2086 s32 err = 0;
1635 u8 keybuf[8]; 2087 u8 keybuf[8];
2088 s32 bssidx;
1636 2089
1637 WL_TRACE("Enter\n"); 2090 WL_TRACE("Enter\n");
1638 WL_CONN("key index (%d)\n", key_idx); 2091 WL_CONN("key index (%d)\n", key_idx);
@@ -1659,25 +2112,33 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1659 switch (params->cipher) { 2112 switch (params->cipher) {
1660 case WLAN_CIPHER_SUITE_WEP40: 2113 case WLAN_CIPHER_SUITE_WEP40:
1661 key.algo = CRYPTO_ALGO_WEP1; 2114 key.algo = CRYPTO_ALGO_WEP1;
2115 val = WEP_ENABLED;
1662 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2116 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1663 break; 2117 break;
1664 case WLAN_CIPHER_SUITE_WEP104: 2118 case WLAN_CIPHER_SUITE_WEP104:
1665 key.algo = CRYPTO_ALGO_WEP128; 2119 key.algo = CRYPTO_ALGO_WEP128;
2120 val = WEP_ENABLED;
1666 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n"); 2121 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1667 break; 2122 break;
1668 case WLAN_CIPHER_SUITE_TKIP: 2123 case WLAN_CIPHER_SUITE_TKIP:
1669 memcpy(keybuf, &key.data[24], sizeof(keybuf)); 2124 if (cfg->conf->mode != WL_MODE_AP) {
1670 memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); 2125 WL_CONN("Swapping key\n");
1671 memcpy(&key.data[16], keybuf, sizeof(keybuf)); 2126 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2127 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2128 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2129 }
1672 key.algo = CRYPTO_ALGO_TKIP; 2130 key.algo = CRYPTO_ALGO_TKIP;
2131 val = TKIP_ENABLED;
1673 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n"); 2132 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1674 break; 2133 break;
1675 case WLAN_CIPHER_SUITE_AES_CMAC: 2134 case WLAN_CIPHER_SUITE_AES_CMAC:
1676 key.algo = CRYPTO_ALGO_AES_CCM; 2135 key.algo = CRYPTO_ALGO_AES_CCM;
2136 val = AES_ENABLED;
1677 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n"); 2137 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1678 break; 2138 break;
1679 case WLAN_CIPHER_SUITE_CCMP: 2139 case WLAN_CIPHER_SUITE_CCMP:
1680 key.algo = CRYPTO_ALGO_AES_CCM; 2140 key.algo = CRYPTO_ALGO_AES_CCM;
2141 val = AES_ENABLED;
1681 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n"); 2142 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1682 break; 2143 break;
1683 default: 2144 default:
@@ -1686,28 +2147,23 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1686 goto done; 2147 goto done;
1687 } 2148 }
1688 2149
1689 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */ 2150 bssidx = brcmf_find_bssidx(cfg, ndev);
2151 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1690 if (err) 2152 if (err)
1691 goto done; 2153 goto done;
1692 2154
1693 val = WEP_ENABLED; 2155 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1694 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1695 if (err) { 2156 if (err) {
1696 WL_ERR("get wsec error (%d)\n", err); 2157 WL_ERR("get wsec error (%d)\n", err);
1697 goto done; 2158 goto done;
1698 } 2159 }
1699 wsec &= ~(WEP_ENABLED);
1700 wsec |= val; 2160 wsec |= val;
1701 err = brcmf_dev_intvar_set(ndev, "wsec", wsec); 2161 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
1702 if (err) { 2162 if (err) {
1703 WL_ERR("set wsec error (%d)\n", err); 2163 WL_ERR("set wsec error (%d)\n", err);
1704 goto done; 2164 goto done;
1705 } 2165 }
1706 2166
1707 val = 1; /* assume shared key. otherwise 0 */
1708 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1709 if (err)
1710 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1711done: 2167done:
1712 WL_TRACE("Exit\n"); 2168 WL_TRACE("Exit\n");
1713 return err; 2169 return err;
@@ -1717,10 +2173,10 @@ static s32
1717brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, 2173brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1718 u8 key_idx, bool pairwise, const u8 *mac_addr) 2174 u8 key_idx, bool pairwise, const u8 *mac_addr)
1719{ 2175{
2176 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1720 struct brcmf_wsec_key key; 2177 struct brcmf_wsec_key key;
1721 s32 err = 0; 2178 s32 err = 0;
1722 s32 val; 2179 s32 bssidx;
1723 s32 wsec;
1724 2180
1725 WL_TRACE("Enter\n"); 2181 WL_TRACE("Enter\n");
1726 if (!check_sys_up(wiphy)) 2182 if (!check_sys_up(wiphy))
@@ -1735,7 +2191,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1735 WL_CONN("key index (%d)\n", key_idx); 2191 WL_CONN("key index (%d)\n", key_idx);
1736 2192
1737 /* Set the new key/index */ 2193 /* Set the new key/index */
1738 err = send_key_to_dongle(ndev, &key); 2194 bssidx = brcmf_find_bssidx(cfg, ndev);
2195 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1739 if (err) { 2196 if (err) {
1740 if (err == -EINVAL) { 2197 if (err == -EINVAL) {
1741 if (key.index >= DOT11_MAX_DEFAULT_KEYS) 2198 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
@@ -1744,35 +2201,8 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1744 } 2201 }
1745 /* Ignore this error, may happen during DISASSOC */ 2202 /* Ignore this error, may happen during DISASSOC */
1746 err = -EAGAIN; 2203 err = -EAGAIN;
1747 goto done;
1748 } 2204 }
1749 2205
1750 val = 0;
1751 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1752 if (err) {
1753 WL_ERR("get wsec error (%d)\n", err);
1754 /* Ignore this error, may happen during DISASSOC */
1755 err = -EAGAIN;
1756 goto done;
1757 }
1758 wsec &= ~(WEP_ENABLED);
1759 wsec |= val;
1760 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1761 if (err) {
1762 WL_ERR("set wsec error (%d)\n", err);
1763 /* Ignore this error, may happen during DISASSOC */
1764 err = -EAGAIN;
1765 goto done;
1766 }
1767
1768 val = 0; /* assume open key. otherwise 1 */
1769 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1770 if (err) {
1771 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1772 /* Ignore this error, may happen during DISASSOC */
1773 err = -EAGAIN;
1774 }
1775done:
1776 WL_TRACE("Exit\n"); 2206 WL_TRACE("Exit\n");
1777 return err; 2207 return err;
1778} 2208}
@@ -1783,10 +2213,12 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1783 void (*callback) (void *cookie, struct key_params * params)) 2213 void (*callback) (void *cookie, struct key_params * params))
1784{ 2214{
1785 struct key_params params; 2215 struct key_params params;
1786 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2216 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2217 struct brcmf_cfg80211_profile *profile = cfg->profile;
1787 struct brcmf_cfg80211_security *sec; 2218 struct brcmf_cfg80211_security *sec;
1788 s32 wsec; 2219 s32 wsec;
1789 s32 err = 0; 2220 s32 err = 0;
2221 s32 bssidx;
1790 2222
1791 WL_TRACE("Enter\n"); 2223 WL_TRACE("Enter\n");
1792 WL_CONN("key index (%d)\n", key_idx); 2224 WL_CONN("key index (%d)\n", key_idx);
@@ -1795,16 +2227,17 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1795 2227
1796 memset(&params, 0, sizeof(params)); 2228 memset(&params, 0, sizeof(params));
1797 2229
1798 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec); 2230 bssidx = brcmf_find_bssidx(cfg, ndev);
2231 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1799 if (err) { 2232 if (err) {
1800 WL_ERR("WLC_GET_WSEC error (%d)\n", err); 2233 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1801 /* Ignore this error, may happen during DISASSOC */ 2234 /* Ignore this error, may happen during DISASSOC */
1802 err = -EAGAIN; 2235 err = -EAGAIN;
1803 goto done; 2236 goto done;
1804 } 2237 }
1805 switch (wsec) { 2238 switch (wsec & ~SES_OW_ENABLED) {
1806 case WEP_ENABLED: 2239 case WEP_ENABLED:
1807 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC); 2240 sec = &profile->sec;
1808 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { 2241 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1809 params.cipher = WLAN_CIPHER_SUITE_WEP40; 2242 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1810 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n"); 2243 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
@@ -1844,53 +2277,73 @@ brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1844 2277
1845static s32 2278static s32
1846brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, 2279brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1847 u8 *mac, struct station_info *sinfo) 2280 u8 *mac, struct station_info *sinfo)
1848{ 2281{
1849 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2282 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2283 struct brcmf_cfg80211_profile *profile = cfg->profile;
1850 struct brcmf_scb_val_le scb_val; 2284 struct brcmf_scb_val_le scb_val;
1851 int rssi; 2285 int rssi;
1852 s32 rate; 2286 s32 rate;
1853 s32 err = 0; 2287 s32 err = 0;
1854 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID); 2288 u8 *bssid = profile->bssid;
2289 struct brcmf_sta_info_le *sta_info_le;
1855 2290
1856 WL_TRACE("Enter\n"); 2291 WL_TRACE("Enter, MAC %pM\n", mac);
1857 if (!check_sys_up(wiphy)) 2292 if (!check_sys_up(wiphy))
1858 return -EIO; 2293 return -EIO;
1859 2294
1860 if (memcmp(mac, bssid, ETH_ALEN)) { 2295 if (cfg->conf->mode == WL_MODE_AP) {
1861 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X" 2296 err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
1862 "wl_bssid-%X:%X:%X:%X:%X:%X\n", 2297 cfg->dcmd_buf,
1863 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], 2298 WL_DCMD_LEN_MAX);
1864 bssid[0], bssid[1], bssid[2], bssid[3], 2299 if (err < 0) {
1865 bssid[4], bssid[5]); 2300 WL_ERR("GET STA INFO failed, %d\n", err);
1866 err = -ENOENT; 2301 goto done;
1867 goto done; 2302 }
1868 } 2303 sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
1869
1870 /* Report the current tx rate */
1871 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1872 if (err) {
1873 WL_ERR("Could not get rate (%d)\n", err);
1874 } else {
1875 sinfo->filled |= STATION_INFO_TX_BITRATE;
1876 sinfo->txrate.legacy = rate * 5;
1877 WL_CONN("Rate %d Mbps\n", rate / 2);
1878 }
1879 2304
1880 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { 2305 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1881 memset(&scb_val, 0, sizeof(scb_val)); 2306 sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
1882 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val, 2307 if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
1883 sizeof(struct brcmf_scb_val_le)); 2308 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2309 sinfo->connected_time = le32_to_cpu(sta_info_le->in);
2310 }
2311 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2312 sinfo->inactive_time, sinfo->connected_time);
2313 } else if (cfg->conf->mode == WL_MODE_BSS) {
2314 if (memcmp(mac, bssid, ETH_ALEN)) {
2315 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2316 mac, bssid);
2317 err = -ENOENT;
2318 goto done;
2319 }
2320 /* Report the current tx rate */
2321 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1884 if (err) { 2322 if (err) {
1885 WL_ERR("Could not get rssi (%d)\n", err); 2323 WL_ERR("Could not get rate (%d)\n", err);
2324 goto done;
1886 } else { 2325 } else {
1887 rssi = le32_to_cpu(scb_val.val); 2326 sinfo->filled |= STATION_INFO_TX_BITRATE;
1888 sinfo->filled |= STATION_INFO_SIGNAL; 2327 sinfo->txrate.legacy = rate * 5;
1889 sinfo->signal = rssi; 2328 WL_CONN("Rate %d Mbps\n", rate / 2);
1890 WL_CONN("RSSI %d dBm\n", rssi);
1891 } 2329 }
1892 }
1893 2330
2331 if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
2332 memset(&scb_val, 0, sizeof(scb_val));
2333 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2334 sizeof(scb_val));
2335 if (err) {
2336 WL_ERR("Could not get rssi (%d)\n", err);
2337 goto done;
2338 } else {
2339 rssi = le32_to_cpu(scb_val.val);
2340 sinfo->filled |= STATION_INFO_SIGNAL;
2341 sinfo->signal = rssi;
2342 WL_CONN("RSSI %d dBm\n", rssi);
2343 }
2344 }
2345 } else
2346 err = -EPERM;
1894done: 2347done:
1895 WL_TRACE("Exit\n"); 2348 WL_TRACE("Exit\n");
1896 return err; 2349 return err;
@@ -1902,7 +2355,7 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1902{ 2355{
1903 s32 pm; 2356 s32 pm;
1904 s32 err = 0; 2357 s32 err = 0;
1905 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 2358 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1906 2359
1907 WL_TRACE("Enter\n"); 2360 WL_TRACE("Enter\n");
1908 2361
@@ -1910,14 +2363,13 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1910 * Powersave enable/disable request is coming from the 2363 * Powersave enable/disable request is coming from the
1911 * cfg80211 even before the interface is up. In that 2364 * cfg80211 even before the interface is up. In that
1912 * scenario, driver will be storing the power save 2365 * scenario, driver will be storing the power save
1913 * preference in cfg_priv struct to apply this to 2366 * preference in cfg struct to apply this to
1914 * FW later while initializing the dongle 2367 * FW later while initializing the dongle
1915 */ 2368 */
1916 cfg_priv->pwr_save = enabled; 2369 cfg->pwr_save = enabled;
1917 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { 2370 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
1918 2371
1919 WL_INFO("Device is not ready," 2372 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
1920 "storing the value in cfg_priv struct\n");
1921 goto done; 2373 goto done;
1922 } 2374 }
1923 2375
@@ -1995,10 +2447,10 @@ done:
1995 return err; 2447 return err;
1996} 2448}
1997 2449
1998static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv, 2450static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
1999 struct brcmf_bss_info_le *bi) 2451 struct brcmf_bss_info_le *bi)
2000{ 2452{
2001 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2453 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2002 struct ieee80211_channel *notify_channel; 2454 struct ieee80211_channel *notify_channel;
2003 struct cfg80211_bss *bss; 2455 struct cfg80211_bss *bss;
2004 struct ieee80211_supported_band *band; 2456 struct ieee80211_supported_band *band;
@@ -2062,14 +2514,14 @@ next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2062 le32_to_cpu(bss->length)); 2514 le32_to_cpu(bss->length));
2063} 2515}
2064 2516
2065static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv) 2517static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2066{ 2518{
2067 struct brcmf_scan_results *bss_list; 2519 struct brcmf_scan_results *bss_list;
2068 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ 2520 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2069 s32 err = 0; 2521 s32 err = 0;
2070 int i; 2522 int i;
2071 2523
2072 bss_list = cfg_priv->bss_list; 2524 bss_list = cfg->bss_list;
2073 if (bss_list->version != BRCMF_BSS_INFO_VERSION) { 2525 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2074 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", 2526 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2075 bss_list->version); 2527 bss_list->version);
@@ -2078,17 +2530,17 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2078 WL_SCAN("scanned AP count (%d)\n", bss_list->count); 2530 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2079 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) { 2531 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2080 bi = next_bss_le(bss_list, bi); 2532 bi = next_bss_le(bss_list, bi);
2081 err = brcmf_inform_single_bss(cfg_priv, bi); 2533 err = brcmf_inform_single_bss(cfg, bi);
2082 if (err) 2534 if (err)
2083 break; 2535 break;
2084 } 2536 }
2085 return err; 2537 return err;
2086} 2538}
2087 2539
2088static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv, 2540static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2089 struct net_device *ndev, const u8 *bssid) 2541 struct net_device *ndev, const u8 *bssid)
2090{ 2542{
2091 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 2543 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2092 struct ieee80211_channel *notify_channel; 2544 struct ieee80211_channel *notify_channel;
2093 struct brcmf_bss_info_le *bi = NULL; 2545 struct brcmf_bss_info_le *bi = NULL;
2094 struct ieee80211_supported_band *band; 2546 struct ieee80211_supported_band *band;
@@ -2163,9 +2615,9 @@ CleanUp:
2163 return err; 2615 return err;
2164} 2616}
2165 2617
2166static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv) 2618static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2167{ 2619{
2168 return cfg_priv->conf->mode == WL_MODE_IBSS; 2620 return cfg->conf->mode == WL_MODE_IBSS;
2169} 2621}
2170 2622
2171/* 2623/*
@@ -2182,22 +2634,62 @@ static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2182 totlen = buflen; 2634 totlen = buflen;
2183 2635
2184 /* find tagged parameter */ 2636 /* find tagged parameter */
2185 while (totlen >= 2) { 2637 while (totlen >= TLV_HDR_LEN) {
2186 int len = elt->len; 2638 int len = elt->len;
2187 2639
2188 /* validate remaining totlen */ 2640 /* validate remaining totlen */
2189 if ((elt->id == key) && (totlen >= (len + 2))) 2641 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2190 return elt; 2642 return elt;
2191 2643
2192 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2)); 2644 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2193 totlen -= (len + 2); 2645 totlen -= (len + TLV_HDR_LEN);
2194 } 2646 }
2195 2647
2196 return NULL; 2648 return NULL;
2197} 2649}
2198 2650
2199static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv) 2651/* Is any of the tlvs the expected entry? If
2652 * not update the tlvs buffer pointer/length.
2653 */
2654static bool
2655brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2656 u8 *oui, u32 oui_len, u8 type)
2657{
2658 /* If the contents match the OUI and the type */
2659 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2660 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2661 type == ie[TLV_BODY_OFF + oui_len]) {
2662 return true;
2663 }
2664
2665 if (tlvs == NULL)
2666 return false;
2667 /* point to the next ie */
2668 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2669 /* calculate the length of the rest of the buffer */
2670 *tlvs_len -= (int)(ie - *tlvs);
2671 /* update the pointer to the start of the buffer */
2672 *tlvs = ie;
2673
2674 return false;
2675}
2676
2677struct brcmf_vs_tlv *
2678brcmf_find_wpaie(u8 *parse, u32 len)
2679{
2680 struct brcmf_tlv *ie;
2681
2682 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) {
2683 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2684 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2685 return (struct brcmf_vs_tlv *)ie;
2686 }
2687 return NULL;
2688}
2689
2690static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2200{ 2691{
2692 struct brcmf_cfg80211_profile *profile = cfg->profile;
2201 struct brcmf_bss_info_le *bi; 2693 struct brcmf_bss_info_le *bi;
2202 struct brcmf_ssid *ssid; 2694 struct brcmf_ssid *ssid;
2203 struct brcmf_tlv *tim; 2695 struct brcmf_tlv *tim;
@@ -2208,21 +2700,21 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2208 s32 err = 0; 2700 s32 err = 0;
2209 2701
2210 WL_TRACE("Enter\n"); 2702 WL_TRACE("Enter\n");
2211 if (brcmf_is_ibssmode(cfg_priv)) 2703 if (brcmf_is_ibssmode(cfg))
2212 return err; 2704 return err;
2213 2705
2214 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID); 2706 ssid = &profile->ssid;
2215 2707
2216 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX); 2708 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2217 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO, 2709 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
2218 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX); 2710 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2219 if (err) { 2711 if (err) {
2220 WL_ERR("Could not get bss info %d\n", err); 2712 WL_ERR("Could not get bss info %d\n", err);
2221 goto update_bss_info_out; 2713 goto update_bss_info_out;
2222 } 2714 }
2223 2715
2224 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4); 2716 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2225 err = brcmf_inform_single_bss(cfg_priv, bi); 2717 err = brcmf_inform_single_bss(cfg, bi);
2226 if (err) 2718 if (err)
2227 goto update_bss_info_out; 2719 goto update_bss_info_out;
2228 2720
@@ -2240,7 +2732,7 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2240 * so we speficially query dtim information to dongle. 2732 * so we speficially query dtim information to dongle.
2241 */ 2733 */
2242 u32 var; 2734 u32 var;
2243 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv), 2735 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
2244 "dtim_assoc", &var); 2736 "dtim_assoc", &var);
2245 if (err) { 2737 if (err) {
2246 WL_ERR("wl dtim_assoc failed (%d)\n", err); 2738 WL_ERR("wl dtim_assoc failed (%d)\n", err);
@@ -2249,20 +2741,22 @@ static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2249 dtim_period = (u8)var; 2741 dtim_period = (u8)var;
2250 } 2742 }
2251 2743
2252 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT); 2744 profile->beacon_interval = beacon_interval;
2253 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD); 2745 profile->dtim_period = dtim_period;
2254 2746
2255update_bss_info_out: 2747update_bss_info_out:
2256 WL_TRACE("Exit"); 2748 WL_TRACE("Exit");
2257 return err; 2749 return err;
2258} 2750}
2259 2751
2260static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2752static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2261{ 2753{
2262 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2754 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2755 struct escan_info *escan = &cfg->escan_info;
2263 struct brcmf_ssid ssid; 2756 struct brcmf_ssid ssid;
2264 2757
2265 if (cfg_priv->iscan_on) { 2758 set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2759 if (cfg->iscan_on) {
2266 iscan->state = WL_ISCAN_STATE_IDLE; 2760 iscan->state = WL_ISCAN_STATE_IDLE;
2267 2761
2268 if (iscan->timer_on) { 2762 if (iscan->timer_on) {
@@ -2275,27 +2769,40 @@ static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2275 /* Abort iscan running in FW */ 2769 /* Abort iscan running in FW */
2276 memset(&ssid, 0, sizeof(ssid)); 2770 memset(&ssid, 0, sizeof(ssid));
2277 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); 2771 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2772
2773 if (cfg->scan_request) {
2774 /* Indidate scan abort to cfg80211 layer */
2775 WL_INFO("Terminating scan in progress\n");
2776 cfg80211_scan_done(cfg->scan_request, true);
2777 cfg->scan_request = NULL;
2778 }
2779 }
2780 if (cfg->escan_on && cfg->scan_request) {
2781 escan->escan_state = WL_ESCAN_STATE_IDLE;
2782 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2278 } 2783 }
2784 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2785 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2279} 2786}
2280 2787
2281static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan, 2788static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2282 bool aborted) 2789 bool aborted)
2283{ 2790{
2284 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2791 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2285 struct net_device *ndev = cfg_to_ndev(cfg_priv); 2792 struct net_device *ndev = cfg_to_ndev(cfg);
2286 2793
2287 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 2794 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
2288 WL_ERR("Scan complete while device not scanning\n"); 2795 WL_ERR("Scan complete while device not scanning\n");
2289 return; 2796 return;
2290 } 2797 }
2291 if (cfg_priv->scan_request) { 2798 if (cfg->scan_request) {
2292 WL_SCAN("ISCAN Completed scan: %s\n", 2799 WL_SCAN("ISCAN Completed scan: %s\n",
2293 aborted ? "Aborted" : "Done"); 2800 aborted ? "Aborted" : "Done");
2294 cfg80211_scan_done(cfg_priv->scan_request, aborted); 2801 cfg80211_scan_done(cfg->scan_request, aborted);
2295 brcmf_set_mpc(ndev, 1); 2802 brcmf_set_mpc(ndev, 1);
2296 cfg_priv->scan_request = NULL; 2803 cfg->scan_request = NULL;
2297 } 2804 }
2298 cfg_priv->iscan_kickstart = false; 2805 cfg->iscan_kickstart = false;
2299} 2806}
2300 2807
2301static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) 2808static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
@@ -2348,21 +2855,21 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2348 return err; 2855 return err;
2349} 2856}
2350 2857
2351static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv) 2858static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2352{ 2859{
2353 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2860 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2354 s32 err = 0; 2861 s32 err = 0;
2355 2862
2356 iscan->state = WL_ISCAN_STATE_IDLE; 2863 iscan->state = WL_ISCAN_STATE_IDLE;
2357 brcmf_inform_bss(cfg_priv); 2864 brcmf_inform_bss(cfg);
2358 brcmf_notify_iscan_complete(iscan, false); 2865 brcmf_notify_iscan_complete(iscan, false);
2359 2866
2360 return err; 2867 return err;
2361} 2868}
2362 2869
2363static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv) 2870static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2364{ 2871{
2365 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2872 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2366 s32 err = 0; 2873 s32 err = 0;
2367 2874
2368 /* Reschedule the timer */ 2875 /* Reschedule the timer */
@@ -2372,12 +2879,12 @@ static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2372 return err; 2879 return err;
2373} 2880}
2374 2881
2375static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv) 2882static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2376{ 2883{
2377 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2884 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2378 s32 err = 0; 2885 s32 err = 0;
2379 2886
2380 brcmf_inform_bss(cfg_priv); 2887 brcmf_inform_bss(cfg);
2381 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE); 2888 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2382 /* Reschedule the timer */ 2889 /* Reschedule the timer */
2383 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); 2890 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
@@ -2386,9 +2893,9 @@ static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2386 return err; 2893 return err;
2387} 2894}
2388 2895
2389static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv) 2896static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2390{ 2897{
2391 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan; 2898 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2392 s32 err = 0; 2899 s32 err = 0;
2393 2900
2394 iscan->state = WL_ISCAN_STATE_IDLE; 2901 iscan->state = WL_ISCAN_STATE_IDLE;
@@ -2402,7 +2909,7 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2402 struct brcmf_cfg80211_iscan_ctrl *iscan = 2909 struct brcmf_cfg80211_iscan_ctrl *iscan =
2403 container_of(work, struct brcmf_cfg80211_iscan_ctrl, 2910 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2404 work); 2911 work);
2405 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); 2912 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2406 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; 2913 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2407 u32 status = BRCMF_SCAN_RESULTS_PARTIAL; 2914 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2408 2915
@@ -2411,12 +2918,12 @@ static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2411 iscan->timer_on = 0; 2918 iscan->timer_on = 0;
2412 } 2919 }
2413 2920
2414 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) { 2921 if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2415 status = BRCMF_SCAN_RESULTS_ABORTED; 2922 status = BRCMF_SCAN_RESULTS_ABORTED;
2416 WL_ERR("Abort iscan\n"); 2923 WL_ERR("Abort iscan\n");
2417 } 2924 }
2418 2925
2419 el->handler[status](cfg_priv); 2926 el->handler[status](cfg);
2420} 2927}
2421 2928
2422static void brcmf_iscan_timer(unsigned long data) 2929static void brcmf_iscan_timer(unsigned long data)
@@ -2431,11 +2938,11 @@ static void brcmf_iscan_timer(unsigned long data)
2431 } 2938 }
2432} 2939}
2433 2940
2434static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2941static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2435{ 2942{
2436 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2943 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2437 2944
2438 if (cfg_priv->iscan_on) { 2945 if (cfg->iscan_on) {
2439 iscan->state = WL_ISCAN_STATE_IDLE; 2946 iscan->state = WL_ISCAN_STATE_IDLE;
2440 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler); 2947 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2441 } 2948 }
@@ -2453,26 +2960,192 @@ static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2453 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted; 2960 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2454} 2961}
2455 2962
2456static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) 2963static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2457{ 2964{
2458 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); 2965 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2459 int err = 0; 2966 int err = 0;
2460 2967
2461 if (cfg_priv->iscan_on) { 2968 if (cfg->iscan_on) {
2462 iscan->ndev = cfg_to_ndev(cfg_priv); 2969 iscan->ndev = cfg_to_ndev(cfg);
2463 brcmf_init_iscan_eloop(&iscan->el); 2970 brcmf_init_iscan_eloop(&iscan->el);
2464 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; 2971 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2465 init_timer(&iscan->timer); 2972 init_timer(&iscan->timer);
2466 iscan->timer.data = (unsigned long) iscan; 2973 iscan->timer.data = (unsigned long) iscan;
2467 iscan->timer.function = brcmf_iscan_timer; 2974 iscan->timer.function = brcmf_iscan_timer;
2468 err = brcmf_invoke_iscan(cfg_priv); 2975 err = brcmf_invoke_iscan(cfg);
2469 if (!err) 2976 if (!err)
2470 iscan->data = cfg_priv; 2977 iscan->data = cfg;
2471 } 2978 }
2472 2979
2473 return err; 2980 return err;
2474} 2981}
2475 2982
2983static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2984{
2985 struct brcmf_cfg80211_info *cfg =
2986 container_of(work, struct brcmf_cfg80211_info,
2987 escan_timeout_work);
2988
2989 brcmf_notify_escan_complete(cfg,
2990 cfg->escan_info.ndev, true, true);
2991}
2992
2993static void brcmf_escan_timeout(unsigned long data)
2994{
2995 struct brcmf_cfg80211_info *cfg =
2996 (struct brcmf_cfg80211_info *)data;
2997
2998 if (cfg->scan_request) {
2999 WL_ERR("timer expired\n");
3000 if (cfg->escan_on)
3001 schedule_work(&cfg->escan_timeout_work);
3002 }
3003}
3004
3005static s32
3006brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
3007 struct brcmf_bss_info_le *bss_info_le)
3008{
3009 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3010 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
3011 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
3012 bss_info_le->SSID_len == bss->SSID_len &&
3013 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3014 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
3015 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
3016 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3017 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3018
3019 /* preserve max RSSI if the measurements are
3020 * both on-channel or both off-channel
3021 */
3022 if (bss_info_rssi > bss_rssi)
3023 bss->RSSI = bss_info_le->RSSI;
3024 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
3025 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
3026 /* preserve the on-channel rssi measurement
3027 * if the new measurement is off channel
3028 */
3029 bss->RSSI = bss_info_le->RSSI;
3030 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
3031 }
3032 return 1;
3033 }
3034 return 0;
3035}
3036
3037static s32
3038brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
3039 struct net_device *ndev,
3040 const struct brcmf_event_msg *e, void *data)
3041{
3042 s32 status;
3043 s32 err = 0;
3044 struct brcmf_escan_result_le *escan_result_le;
3045 struct brcmf_bss_info_le *bss_info_le;
3046 struct brcmf_bss_info_le *bss = NULL;
3047 u32 bi_length;
3048 struct brcmf_scan_results *list;
3049 u32 i;
3050 bool aborted;
3051
3052 status = be32_to_cpu(e->status);
3053
3054 if (!ndev || !cfg->escan_on ||
3055 !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3056 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
3057 ndev, cfg->escan_on,
3058 !test_bit(WL_STATUS_SCANNING, &cfg->status));
3059 return -EPERM;
3060 }
3061
3062 if (status == BRCMF_E_STATUS_PARTIAL) {
3063 WL_SCAN("ESCAN Partial result\n");
3064 escan_result_le = (struct brcmf_escan_result_le *) data;
3065 if (!escan_result_le) {
3066 WL_ERR("Invalid escan result (NULL pointer)\n");
3067 goto exit;
3068 }
3069 if (!cfg->scan_request) {
3070 WL_SCAN("result without cfg80211 request\n");
3071 goto exit;
3072 }
3073
3074 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3075 WL_ERR("Invalid bss_count %d: ignoring\n",
3076 escan_result_le->bss_count);
3077 goto exit;
3078 }
3079 bss_info_le = &escan_result_le->bss_info_le;
3080
3081 bi_length = le32_to_cpu(bss_info_le->length);
3082 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3083 WL_ESCAN_RESULTS_FIXED_SIZE)) {
3084 WL_ERR("Invalid bss_info length %d: ignoring\n",
3085 bi_length);
3086 goto exit;
3087 }
3088
3089 if (!(cfg_to_wiphy(cfg)->interface_modes &
3090 BIT(NL80211_IFTYPE_ADHOC))) {
3091 if (le16_to_cpu(bss_info_le->capability) &
3092 WLAN_CAPABILITY_IBSS) {
3093 WL_ERR("Ignoring IBSS result\n");
3094 goto exit;
3095 }
3096 }
3097
3098 list = (struct brcmf_scan_results *)
3099 cfg->escan_info.escan_buf;
3100 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
3101 WL_ERR("Buffer is too small: ignoring\n");
3102 goto exit;
3103 }
3104
3105 for (i = 0; i < list->count; i++) {
3106 bss = bss ? (struct brcmf_bss_info_le *)
3107 ((unsigned char *)bss +
3108 le32_to_cpu(bss->length)) : list->bss_info_le;
3109 if (brcmf_compare_update_same_bss(bss, bss_info_le))
3110 goto exit;
3111 }
3112 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3113 bss_info_le, bi_length);
3114 list->version = le32_to_cpu(bss_info_le->version);
3115 list->buflen += bi_length;
3116 list->count++;
3117 } else {
3118 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3119 if (cfg->scan_request) {
3120 cfg->bss_list = (struct brcmf_scan_results *)
3121 cfg->escan_info.escan_buf;
3122 brcmf_inform_bss(cfg);
3123 aborted = status != BRCMF_E_STATUS_SUCCESS;
3124 brcmf_notify_escan_complete(cfg, ndev, aborted,
3125 false);
3126 } else
3127 WL_ERR("Unexpected scan result 0x%x\n", status);
3128 }
3129exit:
3130 return err;
3131}
3132
3133static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3134{
3135
3136 if (cfg->escan_on) {
3137 cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
3138 brcmf_cfg80211_escan_handler;
3139 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3140 /* Init scan_timeout timer */
3141 init_timer(&cfg->escan_timeout);
3142 cfg->escan_timeout.data = (unsigned long) cfg;
3143 cfg->escan_timeout.function = brcmf_escan_timeout;
3144 INIT_WORK(&cfg->escan_timeout_work,
3145 brcmf_cfg80211_escan_timeout_worker);
3146 }
3147}
3148
2476static __always_inline void brcmf_delay(u32 ms) 3149static __always_inline void brcmf_delay(u32 ms)
2477{ 3150{
2478 if (ms < 1000 / HZ) { 3151 if (ms < 1000 / HZ) {
@@ -2485,7 +3158,7 @@ static __always_inline void brcmf_delay(u32 ms)
2485 3158
2486static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) 3159static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2487{ 3160{
2488 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3161 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2489 3162
2490 /* 3163 /*
2491 * Check for WL_STATUS_READY before any function call which 3164 * Check for WL_STATUS_READY before any function call which
@@ -2494,7 +3167,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2494 */ 3167 */
2495 WL_TRACE("Enter\n"); 3168 WL_TRACE("Enter\n");
2496 3169
2497 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3170 if (test_bit(WL_STATUS_READY, &cfg->status))
2498 brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); 3171 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2499 3172
2500 WL_TRACE("Exit\n"); 3173 WL_TRACE("Exit\n");
@@ -2504,8 +3177,8 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2504static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, 3177static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2505 struct cfg80211_wowlan *wow) 3178 struct cfg80211_wowlan *wow)
2506{ 3179{
2507 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3180 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2508 struct net_device *ndev = cfg_to_ndev(cfg_priv); 3181 struct net_device *ndev = cfg_to_ndev(cfg);
2509 3182
2510 WL_TRACE("Enter\n"); 3183 WL_TRACE("Enter\n");
2511 3184
@@ -2519,12 +3192,12 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2519 * While going to suspend if associated with AP disassociate 3192 * While going to suspend if associated with AP disassociate
2520 * from AP to save power while system is in suspended state 3193 * from AP to save power while system is in suspended state
2521 */ 3194 */
2522 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 3195 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
2523 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 3196 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
2524 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 3197 test_bit(WL_STATUS_READY, &cfg->status)) {
2525 WL_INFO("Disassociating from AP" 3198 WL_INFO("Disassociating from AP"
2526 " while entering suspend state\n"); 3199 " while entering suspend state\n");
2527 brcmf_link_down(cfg_priv); 3200 brcmf_link_down(cfg);
2528 3201
2529 /* 3202 /*
2530 * Make sure WPA_Supplicant receives all the event 3203 * Make sure WPA_Supplicant receives all the event
@@ -2534,24 +3207,14 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2534 brcmf_delay(500); 3207 brcmf_delay(500);
2535 } 3208 }
2536 3209
2537 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 3210 if (test_bit(WL_STATUS_READY, &cfg->status))
2538 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) 3211 brcmf_abort_scanning(cfg);
2539 brcmf_term_iscan(cfg_priv); 3212 else
2540 3213 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2541 if (cfg_priv->scan_request) {
2542 /* Indidate scan abort to cfg80211 layer */
2543 WL_INFO("Terminating scan in progress\n");
2544 cfg80211_scan_done(cfg_priv->scan_request, true);
2545 cfg_priv->scan_request = NULL;
2546 }
2547 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2548 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2549 3214
2550 /* Turn off watchdog timer */ 3215 /* Turn off watchdog timer */
2551 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) { 3216 if (test_bit(WL_STATUS_READY, &cfg->status))
2552 WL_INFO("Enable MPC\n");
2553 brcmf_set_mpc(ndev, 1); 3217 brcmf_set_mpc(ndev, 1);
2554 }
2555 3218
2556 WL_TRACE("Exit\n"); 3219 WL_TRACE("Exit\n");
2557 3220
@@ -2561,14 +3224,14 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2561static __used s32 3224static __used s32
2562brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len) 3225brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2563{ 3226{
2564 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3227 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
2565 u32 buflen; 3228 u32 buflen;
2566 3229
2567 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf, 3230 buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
2568 WL_DCMD_LEN_MAX); 3231 WL_DCMD_LEN_MAX);
2569 BUG_ON(!buflen); 3232 BUG_ON(!buflen);
2570 3233
2571 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf, 3234 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
2572 buflen); 3235 buflen);
2573} 3236}
2574 3237
@@ -2576,20 +3239,20 @@ static s32
2576brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf, 3239brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2577 s32 buf_len) 3240 s32 buf_len)
2578{ 3241{
2579 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 3242 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
2580 u32 len; 3243 u32 len;
2581 s32 err = 0; 3244 s32 err = 0;
2582 3245
2583 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf, 3246 len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
2584 WL_DCMD_LEN_MAX); 3247 WL_DCMD_LEN_MAX);
2585 BUG_ON(!len); 3248 BUG_ON(!len);
2586 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf, 3249 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
2587 WL_DCMD_LEN_MAX); 3250 WL_DCMD_LEN_MAX);
2588 if (err) { 3251 if (err) {
2589 WL_ERR("error (%d)\n", err); 3252 WL_ERR("error (%d)\n", err);
2590 return err; 3253 return err;
2591 } 3254 }
2592 memcpy(buf, cfg_priv->dcmd_buf, buf_len); 3255 memcpy(buf, cfg->dcmd_buf, buf_len);
2593 3256
2594 return err; 3257 return err;
2595} 3258}
@@ -2622,8 +3285,8 @@ static s32
2622brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3285brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2623 struct cfg80211_pmksa *pmksa) 3286 struct cfg80211_pmksa *pmksa)
2624{ 3287{
2625 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3288 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2626 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; 3289 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2627 s32 err = 0; 3290 s32 err = 0;
2628 int i; 3291 int i;
2629 int pmkid_len; 3292 int pmkid_len;
@@ -2651,7 +3314,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2651 for (i = 0; i < WLAN_PMKID_LEN; i++) 3314 for (i = 0; i < WLAN_PMKID_LEN; i++)
2652 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]); 3315 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2653 3316
2654 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3317 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2655 3318
2656 WL_TRACE("Exit\n"); 3319 WL_TRACE("Exit\n");
2657 return err; 3320 return err;
@@ -2661,7 +3324,7 @@ static s32
2661brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev, 3324brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2662 struct cfg80211_pmksa *pmksa) 3325 struct cfg80211_pmksa *pmksa)
2663{ 3326{
2664 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3327 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2665 struct pmkid_list pmkid; 3328 struct pmkid_list pmkid;
2666 s32 err = 0; 3329 s32 err = 0;
2667 int i, pmkid_len; 3330 int i, pmkid_len;
@@ -2678,30 +3341,30 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2678 for (i = 0; i < WLAN_PMKID_LEN; i++) 3341 for (i = 0; i < WLAN_PMKID_LEN; i++)
2679 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]); 3342 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2680 3343
2681 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid); 3344 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2682 for (i = 0; i < pmkid_len; i++) 3345 for (i = 0; i < pmkid_len; i++)
2683 if (!memcmp 3346 if (!memcmp
2684 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3347 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2685 ETH_ALEN)) 3348 ETH_ALEN))
2686 break; 3349 break;
2687 3350
2688 if ((pmkid_len > 0) 3351 if ((pmkid_len > 0)
2689 && (i < pmkid_len)) { 3352 && (i < pmkid_len)) {
2690 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0, 3353 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2691 sizeof(struct pmkid)); 3354 sizeof(struct pmkid));
2692 for (; i < (pmkid_len - 1); i++) { 3355 for (; i < (pmkid_len - 1); i++) {
2693 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, 3356 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2694 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID, 3357 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2695 ETH_ALEN); 3358 ETH_ALEN);
2696 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID, 3359 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2697 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID, 3360 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2698 WLAN_PMKID_LEN); 3361 WLAN_PMKID_LEN);
2699 } 3362 }
2700 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1); 3363 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2701 } else 3364 } else
2702 err = -EINVAL; 3365 err = -EINVAL;
2703 3366
2704 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3367 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2705 3368
2706 WL_TRACE("Exit\n"); 3369 WL_TRACE("Exit\n");
2707 return err; 3370 return err;
@@ -2711,21 +3374,979 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2711static s32 3374static s32
2712brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev) 3375brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2713{ 3376{
2714 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); 3377 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2715 s32 err = 0; 3378 s32 err = 0;
2716 3379
2717 WL_TRACE("Enter\n"); 3380 WL_TRACE("Enter\n");
2718 if (!check_sys_up(wiphy)) 3381 if (!check_sys_up(wiphy))
2719 return -EIO; 3382 return -EIO;
2720 3383
2721 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list)); 3384 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2722 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err); 3385 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2723 3386
2724 WL_TRACE("Exit\n"); 3387 WL_TRACE("Exit\n");
2725 return err; 3388 return err;
2726 3389
2727} 3390}
2728 3391
3392/*
3393 * PFN result doesn't have all the info which are
3394 * required by the supplicant
3395 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3396 * via wl_inform_single_bss in the required format. Escan does require the
3397 * scan request in the form of cfg80211_scan_request. For timebeing, create
3398 * cfg80211_scan_request one out of the received PNO event.
3399 */
3400static s32
3401brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3402 struct net_device *ndev,
3403 const struct brcmf_event_msg *e, void *data)
3404{
3405 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3406 struct cfg80211_scan_request *request = NULL;
3407 struct cfg80211_ssid *ssid = NULL;
3408 struct ieee80211_channel *channel = NULL;
3409 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3410 int err = 0;
3411 int channel_req = 0;
3412 int band = 0;
3413 struct brcmf_pno_scanresults_le *pfn_result;
3414 u32 result_count;
3415 u32 status;
3416
3417 WL_SCAN("Enter\n");
3418
3419 if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) {
3420 WL_SCAN("PFN NET LOST event. Do Nothing\n");
3421 return 0;
3422 }
3423
3424 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3425 result_count = le32_to_cpu(pfn_result->count);
3426 status = le32_to_cpu(pfn_result->status);
3427
3428 /*
3429 * PFN event is limited to fit 512 bytes so we may get
3430 * multiple NET_FOUND events. For now place a warning here.
3431 */
3432 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3433 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
3434 if (result_count > 0) {
3435 int i;
3436
3437 request = kzalloc(sizeof(*request), GFP_KERNEL);
3438 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3439 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3440 if (!request || !ssid || !channel) {
3441 err = -ENOMEM;
3442 goto out_err;
3443 }
3444
3445 request->wiphy = wiphy;
3446 data += sizeof(struct brcmf_pno_scanresults_le);
3447 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3448
3449 for (i = 0; i < result_count; i++) {
3450 netinfo = &netinfo_start[i];
3451 if (!netinfo) {
3452 WL_ERR("Invalid netinfo ptr. index: %d\n", i);
3453 err = -EINVAL;
3454 goto out_err;
3455 }
3456
3457 WL_SCAN("SSID:%s Channel:%d\n",
3458 netinfo->SSID, netinfo->channel);
3459 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3460 ssid[i].ssid_len = netinfo->SSID_len;
3461 request->n_ssids++;
3462
3463 channel_req = netinfo->channel;
3464 if (channel_req <= CH_MAX_2G_CHANNEL)
3465 band = NL80211_BAND_2GHZ;
3466 else
3467 band = NL80211_BAND_5GHZ;
3468 channel[i].center_freq =
3469 ieee80211_channel_to_frequency(channel_req,
3470 band);
3471 channel[i].band = band;
3472 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3473 request->channels[i] = &channel[i];
3474 request->n_channels++;
3475 }
3476
3477 /* assign parsed ssid array */
3478 if (request->n_ssids)
3479 request->ssids = &ssid[0];
3480
3481 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3482 /* Abort any on-going scan */
3483 brcmf_abort_scanning(cfg);
3484 }
3485
3486 set_bit(WL_STATUS_SCANNING, &cfg->status);
3487 err = brcmf_do_escan(cfg, wiphy, ndev, request);
3488 if (err) {
3489 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3490 goto out_err;
3491 }
3492 cfg->sched_escan = true;
3493 cfg->scan_request = request;
3494 } else {
3495 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3496 goto out_err;
3497 }
3498
3499 kfree(ssid);
3500 kfree(channel);
3501 kfree(request);
3502 return 0;
3503
3504out_err:
3505 kfree(ssid);
3506 kfree(channel);
3507 kfree(request);
3508 cfg80211_sched_scan_stopped(wiphy);
3509 return err;
3510}
3511
3512#ifndef CONFIG_BRCMISCAN
3513static int brcmf_dev_pno_clean(struct net_device *ndev)
3514{
3515 char iovbuf[128];
3516 int ret;
3517
3518 /* Disable pfn */
3519 ret = brcmf_dev_intvar_set(ndev, "pfn", 0);
3520 if (ret == 0) {
3521 /* clear pfn */
3522 ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0,
3523 iovbuf, sizeof(iovbuf));
3524 }
3525 if (ret < 0)
3526 WL_ERR("failed code %d\n", ret);
3527
3528 return ret;
3529}
3530
3531static int brcmf_dev_pno_config(struct net_device *ndev)
3532{
3533 struct brcmf_pno_param_le pfn_param;
3534 char iovbuf[128];
3535
3536 memset(&pfn_param, 0, sizeof(pfn_param));
3537 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3538
3539 /* set extra pno params */
3540 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3541 pfn_param.repeat = BRCMF_PNO_REPEAT;
3542 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3543
3544 /* set up pno scan fr */
3545 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3546
3547 return brcmf_dev_iovar_setbuf(ndev, "pfn_set",
3548 &pfn_param, sizeof(pfn_param),
3549 iovbuf, sizeof(iovbuf));
3550}
3551
3552static int
3553brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3554 struct net_device *ndev,
3555 struct cfg80211_sched_scan_request *request)
3556{
3557 char iovbuf[128];
3558 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3559 struct brcmf_pno_net_param_le pfn;
3560 int i;
3561 int ret = 0;
3562
3563 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3564 request->n_match_sets, request->n_ssids);
3565 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3566 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
3567 return -EAGAIN;
3568 }
3569
3570 if (!request || !request->n_ssids || !request->n_match_sets) {
3571 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
3572 request->n_ssids);
3573 return -EINVAL;
3574 }
3575
3576 if (request->n_ssids > 0) {
3577 for (i = 0; i < request->n_ssids; i++) {
3578 /* Active scan req for ssids */
3579 WL_SCAN(">>> Active scan req for ssid (%s)\n",
3580 request->ssids[i].ssid);
3581
3582 /*
3583 * match_set ssids is a supert set of n_ssid list,
3584 * so we need not add these set seperately.
3585 */
3586 }
3587 }
3588
3589 if (request->n_match_sets > 0) {
3590 /* clean up everything */
3591 ret = brcmf_dev_pno_clean(ndev);
3592 if (ret < 0) {
3593 WL_ERR("failed error=%d\n", ret);
3594 return ret;
3595 }
3596
3597 /* configure pno */
3598 ret = brcmf_dev_pno_config(ndev);
3599 if (ret < 0) {
3600 WL_ERR("PNO setup failed!! ret=%d\n", ret);
3601 return -EINVAL;
3602 }
3603
3604 /* configure each match set */
3605 for (i = 0; i < request->n_match_sets; i++) {
3606 struct cfg80211_ssid *ssid;
3607 u32 ssid_len;
3608
3609 ssid = &request->match_sets[i].ssid;
3610 ssid_len = ssid->ssid_len;
3611
3612 if (!ssid_len) {
3613 WL_ERR("skip broadcast ssid\n");
3614 continue;
3615 }
3616 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3617 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3618 pfn.wsec = cpu_to_le32(0);
3619 pfn.infra = cpu_to_le32(1);
3620 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3621 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3622 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3623 ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add",
3624 &pfn, sizeof(pfn),
3625 iovbuf, sizeof(iovbuf));
3626 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
3627 ret == 0 ? "set" : "failed",
3628 ssid->ssid);
3629 }
3630 /* Enable the PNO */
3631 if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) {
3632 WL_ERR("PNO enable failed!! ret=%d\n", ret);
3633 return -EINVAL;
3634 }
3635 } else {
3636 return -EINVAL;
3637 }
3638
3639 return 0;
3640}
3641
3642static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3643 struct net_device *ndev)
3644{
3645 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3646
3647 WL_SCAN("enter\n");
3648 brcmf_dev_pno_clean(ndev);
3649 if (cfg->sched_escan)
3650 brcmf_notify_escan_complete(cfg, ndev, true, true);
3651 return 0;
3652}
3653#endif /* CONFIG_BRCMISCAN */
3654
3655#ifdef CONFIG_NL80211_TESTMODE
3656static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3657{
3658 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3659 struct net_device *ndev = cfg->wdev->netdev;
3660 struct brcmf_dcmd *dcmd = data;
3661 struct sk_buff *reply;
3662 int ret;
3663
3664 ret = brcmf_netlink_dcmd(ndev, dcmd);
3665 if (ret == 0) {
3666 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3667 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3668 ret = cfg80211_testmode_reply(reply);
3669 }
3670 return ret;
3671}
3672#endif
3673
3674static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3675{
3676 s32 err;
3677
3678 /* set auth */
3679 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
3680 if (err < 0) {
3681 WL_ERR("auth error %d\n", err);
3682 return err;
3683 }
3684 /* set wsec */
3685 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
3686 if (err < 0) {
3687 WL_ERR("wsec error %d\n", err);
3688 return err;
3689 }
3690 /* set upper-layer auth */
3691 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
3692 WPA_AUTH_NONE, bssidx);
3693 if (err < 0) {
3694 WL_ERR("wpa_auth error %d\n", err);
3695 return err;
3696 }
3697
3698 return 0;
3699}
3700
3701static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3702{
3703 if (is_rsn_ie)
3704 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3705
3706 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3707}
3708
3709static s32
3710brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3711 bool is_rsn_ie, s32 bssidx)
3712{
3713 u32 auth = 0; /* d11 open authentication */
3714 u16 count;
3715 s32 err = 0;
3716 s32 len = 0;
3717 u32 i;
3718 u32 wsec;
3719 u32 pval = 0;
3720 u32 gval = 0;
3721 u32 wpa_auth = 0;
3722 u32 offset;
3723 u8 *data;
3724 u16 rsn_cap;
3725 u32 wme_bss_disable;
3726
3727 WL_TRACE("Enter\n");
3728 if (wpa_ie == NULL)
3729 goto exit;
3730
3731 len = wpa_ie->len + TLV_HDR_LEN;
3732 data = (u8 *)wpa_ie;
3733 offset = 0;
3734 if (!is_rsn_ie)
3735 offset += VS_IE_FIXED_HDR_LEN;
3736 offset += WPA_IE_VERSION_LEN;
3737
3738 /* check for multicast cipher suite */
3739 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3740 err = -EINVAL;
3741 WL_ERR("no multicast cipher suite\n");
3742 goto exit;
3743 }
3744
3745 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3746 err = -EINVAL;
3747 WL_ERR("ivalid OUI\n");
3748 goto exit;
3749 }
3750 offset += TLV_OUI_LEN;
3751
3752 /* pick up multicast cipher */
3753 switch (data[offset]) {
3754 case WPA_CIPHER_NONE:
3755 gval = 0;
3756 break;
3757 case WPA_CIPHER_WEP_40:
3758 case WPA_CIPHER_WEP_104:
3759 gval = WEP_ENABLED;
3760 break;
3761 case WPA_CIPHER_TKIP:
3762 gval = TKIP_ENABLED;
3763 break;
3764 case WPA_CIPHER_AES_CCM:
3765 gval = AES_ENABLED;
3766 break;
3767 default:
3768 err = -EINVAL;
3769 WL_ERR("Invalid multi cast cipher info\n");
3770 goto exit;
3771 }
3772
3773 offset++;
3774 /* walk thru unicast cipher list and pick up what we recognize */
3775 count = data[offset] + (data[offset + 1] << 8);
3776 offset += WPA_IE_SUITE_COUNT_LEN;
3777 /* Check for unicast suite(s) */
3778 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3779 err = -EINVAL;
3780 WL_ERR("no unicast cipher suite\n");
3781 goto exit;
3782 }
3783 for (i = 0; i < count; i++) {
3784 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3785 err = -EINVAL;
3786 WL_ERR("ivalid OUI\n");
3787 goto exit;
3788 }
3789 offset += TLV_OUI_LEN;
3790 switch (data[offset]) {
3791 case WPA_CIPHER_NONE:
3792 break;
3793 case WPA_CIPHER_WEP_40:
3794 case WPA_CIPHER_WEP_104:
3795 pval |= WEP_ENABLED;
3796 break;
3797 case WPA_CIPHER_TKIP:
3798 pval |= TKIP_ENABLED;
3799 break;
3800 case WPA_CIPHER_AES_CCM:
3801 pval |= AES_ENABLED;
3802 break;
3803 default:
3804 WL_ERR("Ivalid unicast security info\n");
3805 }
3806 offset++;
3807 }
3808 /* walk thru auth management suite list and pick up what we recognize */
3809 count = data[offset] + (data[offset + 1] << 8);
3810 offset += WPA_IE_SUITE_COUNT_LEN;
3811 /* Check for auth key management suite(s) */
3812 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3813 err = -EINVAL;
3814 WL_ERR("no auth key mgmt suite\n");
3815 goto exit;
3816 }
3817 for (i = 0; i < count; i++) {
3818 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3819 err = -EINVAL;
3820 WL_ERR("ivalid OUI\n");
3821 goto exit;
3822 }
3823 offset += TLV_OUI_LEN;
3824 switch (data[offset]) {
3825 case RSN_AKM_NONE:
3826 WL_TRACE("RSN_AKM_NONE\n");
3827 wpa_auth |= WPA_AUTH_NONE;
3828 break;
3829 case RSN_AKM_UNSPECIFIED:
3830 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3831 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3832 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3833 break;
3834 case RSN_AKM_PSK:
3835 WL_TRACE("RSN_AKM_PSK\n");
3836 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3837 (wpa_auth |= WPA_AUTH_PSK);
3838 break;
3839 default:
3840 WL_ERR("Ivalid key mgmt info\n");
3841 }
3842 offset++;
3843 }
3844
3845 if (is_rsn_ie) {
3846 wme_bss_disable = 1;
3847 if ((offset + RSN_CAP_LEN) <= len) {
3848 rsn_cap = data[offset] + (data[offset + 1] << 8);
3849 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3850 wme_bss_disable = 0;
3851 }
3852 /* set wme_bss_disable to sync RSN Capabilities */
3853 err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
3854 wme_bss_disable, bssidx);
3855 if (err < 0) {
3856 WL_ERR("wme_bss_disable error %d\n", err);
3857 goto exit;
3858 }
3859 }
3860 /* FOR WPS , set SES_OW_ENABLED */
3861 wsec = (pval | gval | SES_OW_ENABLED);
3862
3863 /* set auth */
3864 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
3865 if (err < 0) {
3866 WL_ERR("auth error %d\n", err);
3867 goto exit;
3868 }
3869 /* set wsec */
3870 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
3871 if (err < 0) {
3872 WL_ERR("wsec error %d\n", err);
3873 goto exit;
3874 }
3875 /* set upper-layer auth */
3876 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
3877 if (err < 0) {
3878 WL_ERR("wpa_auth error %d\n", err);
3879 goto exit;
3880 }
3881
3882exit:
3883 return err;
3884}
3885
3886static s32
3887brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
3888 struct parsed_vndr_ies *vndr_ies)
3889{
3890 s32 err = 0;
3891 struct brcmf_vs_tlv *vndrie;
3892 struct brcmf_tlv *ie;
3893 struct parsed_vndr_ie_info *parsed_info;
3894 s32 remaining_len;
3895
3896 remaining_len = (s32)vndr_ie_len;
3897 memset(vndr_ies, 0, sizeof(*vndr_ies));
3898
3899 ie = (struct brcmf_tlv *)vndr_ie_buf;
3900 while (ie) {
3901 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3902 goto next;
3903 vndrie = (struct brcmf_vs_tlv *)ie;
3904 /* len should be bigger than OUI length + one */
3905 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3906 WL_ERR("invalid vndr ie. length is too small %d\n",
3907 vndrie->len);
3908 goto next;
3909 }
3910 /* if wpa or wme ie, do not add ie */
3911 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3912 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3913 (vndrie->oui_type == WME_OUI_TYPE))) {
3914 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3915 goto next;
3916 }
3917
3918 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3919
3920 /* save vndr ie information */
3921 parsed_info->ie_ptr = (char *)vndrie;
3922 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3923 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3924
3925 vndr_ies->count++;
3926
3927 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3928 parsed_info->vndrie.oui[0],
3929 parsed_info->vndrie.oui[1],
3930 parsed_info->vndrie.oui[2],
3931 parsed_info->vndrie.oui_type);
3932
3933 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3934 break;
3935next:
3936 remaining_len -= ie->len;
3937 if (remaining_len <= 2)
3938 ie = NULL;
3939 else
3940 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3941 }
3942 return err;
3943}
3944
3945static u32
3946brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3947{
3948
3949 __le32 iecount_le;
3950 __le32 pktflag_le;
3951
3952 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3953 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3954
3955 iecount_le = cpu_to_le32(1);
3956 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3957
3958 pktflag_le = cpu_to_le32(pktflag);
3959 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3960
3961 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3962
3963 return ie_len + VNDR_IE_HDR_SIZE;
3964}
3965
3966s32
3967brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
3968 struct net_device *ndev, s32 bssidx, s32 pktflag,
3969 u8 *vndr_ie_buf, u32 vndr_ie_len)
3970{
3971 s32 err = 0;
3972 u8 *iovar_ie_buf;
3973 u8 *curr_ie_buf;
3974 u8 *mgmt_ie_buf = NULL;
3975 u32 mgmt_ie_buf_len = 0;
3976 u32 *mgmt_ie_len = 0;
3977 u32 del_add_ie_buf_len = 0;
3978 u32 total_ie_buf_len = 0;
3979 u32 parsed_ie_buf_len = 0;
3980 struct parsed_vndr_ies old_vndr_ies;
3981 struct parsed_vndr_ies new_vndr_ies;
3982 struct parsed_vndr_ie_info *vndrie_info;
3983 s32 i;
3984 u8 *ptr;
3985 u32 remained_buf_len;
3986
3987 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
3988 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3989 if (!iovar_ie_buf)
3990 return -ENOMEM;
3991 curr_ie_buf = iovar_ie_buf;
3992 if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
3993 test_bit(WL_STATUS_AP_CREATED, &cfg->status)) {
3994 switch (pktflag) {
3995 case VNDR_IE_PRBRSP_FLAG:
3996 mgmt_ie_buf = cfg->ap_info->probe_res_ie;
3997 mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
3998 mgmt_ie_buf_len =
3999 sizeof(cfg->ap_info->probe_res_ie);
4000 break;
4001 case VNDR_IE_BEACON_FLAG:
4002 mgmt_ie_buf = cfg->ap_info->beacon_ie;
4003 mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
4004 mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
4005 break;
4006 default:
4007 err = -EPERM;
4008 WL_ERR("not suitable type\n");
4009 goto exit;
4010 }
4011 bssidx = 0;
4012 } else {
4013 err = -EPERM;
4014 WL_ERR("not suitable type\n");
4015 goto exit;
4016 }
4017
4018 if (vndr_ie_len > mgmt_ie_buf_len) {
4019 err = -ENOMEM;
4020 WL_ERR("extra IE size too big\n");
4021 goto exit;
4022 }
4023
4024 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4025 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4026 ptr = curr_ie_buf;
4027 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4028 for (i = 0; i < new_vndr_ies.count; i++) {
4029 vndrie_info = &new_vndr_ies.ie_info[i];
4030 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4031 vndrie_info->ie_len);
4032 parsed_ie_buf_len += vndrie_info->ie_len;
4033 }
4034 }
4035
4036 if (mgmt_ie_buf != NULL) {
4037 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4038 (memcmp(mgmt_ie_buf, curr_ie_buf,
4039 parsed_ie_buf_len) == 0)) {
4040 WL_TRACE("Previous mgmt IE is equals to current IE");
4041 goto exit;
4042 }
4043
4044 /* parse old vndr_ie */
4045 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4046
4047 /* make a command to delete old ie */
4048 for (i = 0; i < old_vndr_ies.count; i++) {
4049 vndrie_info = &old_vndr_ies.ie_info[i];
4050
4051 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4052 vndrie_info->vndrie.id,
4053 vndrie_info->vndrie.len,
4054 vndrie_info->vndrie.oui[0],
4055 vndrie_info->vndrie.oui[1],
4056 vndrie_info->vndrie.oui[2]);
4057
4058 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4059 vndrie_info->ie_ptr,
4060 vndrie_info->ie_len,
4061 "del");
4062 curr_ie_buf += del_add_ie_buf_len;
4063 total_ie_buf_len += del_add_ie_buf_len;
4064 }
4065 }
4066
4067 *mgmt_ie_len = 0;
4068 /* Add if there is any extra IE */
4069 if (mgmt_ie_buf && parsed_ie_buf_len) {
4070 ptr = mgmt_ie_buf;
4071
4072 remained_buf_len = mgmt_ie_buf_len;
4073
4074 /* make a command to add new ie */
4075 for (i = 0; i < new_vndr_ies.count; i++) {
4076 vndrie_info = &new_vndr_ies.ie_info[i];
4077
4078 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4079 vndrie_info->vndrie.id,
4080 vndrie_info->vndrie.len,
4081 vndrie_info->vndrie.oui[0],
4082 vndrie_info->vndrie.oui[1],
4083 vndrie_info->vndrie.oui[2]);
4084
4085 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4086 vndrie_info->ie_ptr,
4087 vndrie_info->ie_len,
4088 "add");
4089 /* verify remained buf size before copy data */
4090 remained_buf_len -= vndrie_info->ie_len;
4091 if (remained_buf_len < 0) {
4092 WL_ERR("no space in mgmt_ie_buf: len left %d",
4093 remained_buf_len);
4094 break;
4095 }
4096
4097 /* save the parsed IE in wl struct */
4098 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4099 vndrie_info->ie_len);
4100 *mgmt_ie_len += vndrie_info->ie_len;
4101
4102 curr_ie_buf += del_add_ie_buf_len;
4103 total_ie_buf_len += del_add_ie_buf_len;
4104 }
4105 }
4106 if (total_ie_buf_len) {
4107 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
4108 iovar_ie_buf,
4109 total_ie_buf_len,
4110 cfg->extra_buf,
4111 WL_EXTRA_BUF_MAX, bssidx);
4112 if (err)
4113 WL_ERR("vndr ie set error : %d\n", err);
4114 }
4115
4116exit:
4117 kfree(iovar_ie_buf);
4118 return err;
4119}
4120
4121static s32
4122brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4123 struct cfg80211_ap_settings *settings)
4124{
4125 s32 ie_offset;
4126 struct brcmf_tlv *ssid_ie;
4127 struct brcmf_ssid_le ssid_le;
4128 s32 ioctl_value;
4129 s32 err = -EPERM;
4130 struct brcmf_tlv *rsn_ie;
4131 struct brcmf_vs_tlv *wpa_ie;
4132 struct brcmf_join_params join_params;
4133 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4134 s32 bssidx = 0;
4135
4136 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
4137 settings->channel_type, settings->beacon_interval,
4138 settings->dtim_period);
4139 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
4140 settings->ssid, settings->ssid_len, settings->auth_type,
4141 settings->inactivity_timeout);
4142
4143 if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
4144 WL_ERR("Not in AP creation mode\n");
4145 return -EPERM;
4146 }
4147
4148 memset(&ssid_le, 0, sizeof(ssid_le));
4149 if (settings->ssid == NULL || settings->ssid_len == 0) {
4150 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4151 ssid_ie = brcmf_parse_tlvs(
4152 (u8 *)&settings->beacon.head[ie_offset],
4153 settings->beacon.head_len - ie_offset,
4154 WLAN_EID_SSID);
4155 if (!ssid_ie)
4156 return -EINVAL;
4157
4158 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4159 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4160 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
4161 } else {
4162 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4163 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4164 }
4165
4166 brcmf_set_mpc(ndev, 0);
4167 ioctl_value = 1;
4168 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
4169 if (err < 0) {
4170 WL_ERR("BRCMF_C_DOWN error %d\n", err);
4171 goto exit;
4172 }
4173 ioctl_value = 1;
4174 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
4175 if (err < 0) {
4176 WL_ERR("SET INFRA error %d\n", err);
4177 goto exit;
4178 }
4179 ioctl_value = 1;
4180 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4181 if (err < 0) {
4182 WL_ERR("setting AP mode failed %d\n", err);
4183 goto exit;
4184 }
4185
4186 /* find the RSN_IE */
4187 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4188 settings->beacon.tail_len, WLAN_EID_RSN);
4189
4190 /* find the WPA_IE */
4191 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4192 settings->beacon.tail_len);
4193
4194 kfree(cfg->ap_info->rsn_ie);
4195 cfg->ap_info->rsn_ie = NULL;
4196 kfree(cfg->ap_info->wpa_ie);
4197 cfg->ap_info->wpa_ie = NULL;
4198
4199 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4200 WL_TRACE("WPA(2) IE is found\n");
4201 if (wpa_ie != NULL) {
4202 /* WPA IE */
4203 err = brcmf_configure_wpaie(ndev, wpa_ie, false,
4204 bssidx);
4205 if (err < 0)
4206 goto exit;
4207 cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4208 wpa_ie->len +
4209 TLV_HDR_LEN,
4210 GFP_KERNEL);
4211 } else {
4212 /* RSN IE */
4213 err = brcmf_configure_wpaie(ndev,
4214 (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
4215 if (err < 0)
4216 goto exit;
4217 cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4218 rsn_ie->len +
4219 TLV_HDR_LEN,
4220 GFP_KERNEL);
4221 }
4222 cfg->ap_info->security_mode = true;
4223 } else {
4224 WL_TRACE("No WPA(2) IEs found\n");
4225 brcmf_configure_opensecurity(ndev, bssidx);
4226 cfg->ap_info->security_mode = false;
4227 }
4228 /* Set Beacon IEs to FW */
4229 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4230 VNDR_IE_BEACON_FLAG,
4231 (u8 *)settings->beacon.tail,
4232 settings->beacon.tail_len);
4233 if (err)
4234 WL_ERR("Set Beacon IE Failed\n");
4235 else
4236 WL_TRACE("Applied Vndr IEs for Beacon\n");
4237
4238 /* Set Probe Response IEs to FW */
4239 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4240 VNDR_IE_PRBRSP_FLAG,
4241 (u8 *)settings->beacon.proberesp_ies,
4242 settings->beacon.proberesp_ies_len);
4243 if (err)
4244 WL_ERR("Set Probe Resp IE Failed\n");
4245 else
4246 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4247
4248 if (settings->beacon_interval) {
4249 ioctl_value = settings->beacon_interval;
4250 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
4251 &ioctl_value);
4252 if (err < 0) {
4253 WL_ERR("Beacon Interval Set Error, %d\n", err);
4254 goto exit;
4255 }
4256 }
4257 if (settings->dtim_period) {
4258 ioctl_value = settings->dtim_period;
4259 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
4260 &ioctl_value);
4261 if (err < 0) {
4262 WL_ERR("DTIM Interval Set Error, %d\n", err);
4263 goto exit;
4264 }
4265 }
4266 ioctl_value = 1;
4267 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4268 if (err < 0) {
4269 WL_ERR("BRCMF_C_UP error (%d)\n", err);
4270 goto exit;
4271 }
4272
4273 memset(&join_params, 0, sizeof(join_params));
4274 /* join parameters starts with ssid */
4275 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4276 /* create softap */
4277 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
4278 sizeof(join_params));
4279 if (err < 0) {
4280 WL_ERR("SET SSID error (%d)\n", err);
4281 goto exit;
4282 }
4283 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4284 set_bit(WL_STATUS_AP_CREATED, &cfg->status);
4285
4286exit:
4287 if (err)
4288 brcmf_set_mpc(ndev, 1);
4289 return err;
4290}
4291
4292static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4293{
4294 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4295 s32 ioctl_value;
4296 s32 err = -EPERM;
4297
4298 WL_TRACE("Enter\n");
4299
4300 if (cfg->conf->mode == WL_MODE_AP) {
4301 /* Due to most likely deauths outstanding we sleep */
4302 /* first to make sure they get processed by fw. */
4303 msleep(400);
4304 ioctl_value = 0;
4305 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4306 if (err < 0) {
4307 WL_ERR("setting AP mode failed %d\n", err);
4308 goto exit;
4309 }
4310 ioctl_value = 0;
4311 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4312 if (err < 0) {
4313 WL_ERR("BRCMF_C_UP error %d\n", err);
4314 goto exit;
4315 }
4316 brcmf_set_mpc(ndev, 1);
4317 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4318 clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
4319 }
4320exit:
4321 return err;
4322}
4323
4324static int
4325brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4326 u8 *mac)
4327{
4328 struct brcmf_scb_val_le scbval;
4329 s32 err;
4330
4331 if (!mac)
4332 return -EFAULT;
4333
4334 WL_TRACE("Enter %pM\n", mac);
4335
4336 if (!check_sys_up(wiphy))
4337 return -EIO;
4338
4339 memcpy(&scbval.ea, mac, ETH_ALEN);
4340 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4341 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4342 &scbval, sizeof(scbval));
4343 if (err)
4344 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4345
4346 WL_TRACE("Exit\n");
4347 return err;
4348}
4349
2729static struct cfg80211_ops wl_cfg80211_ops = { 4350static struct cfg80211_ops wl_cfg80211_ops = {
2730 .change_virtual_intf = brcmf_cfg80211_change_iface, 4351 .change_virtual_intf = brcmf_cfg80211_change_iface,
2731 .scan = brcmf_cfg80211_scan, 4352 .scan = brcmf_cfg80211_scan,
@@ -2748,7 +4369,18 @@ static struct cfg80211_ops wl_cfg80211_ops = {
2748 .resume = brcmf_cfg80211_resume, 4369 .resume = brcmf_cfg80211_resume,
2749 .set_pmksa = brcmf_cfg80211_set_pmksa, 4370 .set_pmksa = brcmf_cfg80211_set_pmksa,
2750 .del_pmksa = brcmf_cfg80211_del_pmksa, 4371 .del_pmksa = brcmf_cfg80211_del_pmksa,
2751 .flush_pmksa = brcmf_cfg80211_flush_pmksa 4372 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4373 .start_ap = brcmf_cfg80211_start_ap,
4374 .stop_ap = brcmf_cfg80211_stop_ap,
4375 .del_station = brcmf_cfg80211_del_station,
4376#ifndef CONFIG_BRCMISCAN
4377 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4378 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4379 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4380#endif
4381#ifdef CONFIG_NL80211_TESTMODE
4382 .testmode_cmd = brcmf_cfg80211_testmode
4383#endif
2752}; 4384};
2753 4385
2754static s32 brcmf_mode_to_nl80211_iftype(s32 mode) 4386static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
@@ -2767,8 +4399,18 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2767 return err; 4399 return err;
2768} 4400}
2769 4401
2770static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, 4402static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
2771 struct device *ndev) 4403{
4404#ifndef CONFIG_BRCMFISCAN
4405 /* scheduled scan settings */
4406 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4407 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4408 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4409 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4410#endif
4411}
4412
4413static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
2772{ 4414{
2773 struct wireless_dev *wdev; 4415 struct wireless_dev *wdev;
2774 s32 err = 0; 4416 s32 err = 0;
@@ -2777,9 +4419,8 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2777 if (!wdev) 4419 if (!wdev)
2778 return ERR_PTR(-ENOMEM); 4420 return ERR_PTR(-ENOMEM);
2779 4421
2780 wdev->wiphy = 4422 wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
2781 wiphy_new(&wl_cfg80211_ops, 4423 sizeof(struct brcmf_cfg80211_info));
2782 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2783 if (!wdev->wiphy) { 4424 if (!wdev->wiphy) {
2784 WL_ERR("Could not allocate wiphy device\n"); 4425 WL_ERR("Could not allocate wiphy device\n");
2785 err = -ENOMEM; 4426 err = -ENOMEM;
@@ -2788,8 +4429,9 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2788 set_wiphy_dev(wdev->wiphy, ndev); 4429 set_wiphy_dev(wdev->wiphy, ndev);
2789 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; 4430 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2790 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; 4431 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2791 wdev->wiphy->interface_modes = 4432 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2792 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); 4433 BIT(NL80211_IFTYPE_ADHOC) |
4434 BIT(NL80211_IFTYPE_AP);
2793 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz; 4435 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2794 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set 4436 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2795 * it as 11a by default. 4437 * it as 11a by default.
@@ -2805,6 +4447,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2805 * save mode 4447 * save mode
2806 * by default 4448 * by default
2807 */ 4449 */
4450 brcmf_wiphy_pno_params(wdev->wiphy);
2808 err = wiphy_register(wdev->wiphy); 4451 err = wiphy_register(wdev->wiphy);
2809 if (err < 0) { 4452 if (err < 0) {
2810 WL_ERR("Could not register wiphy device (%d)\n", err); 4453 WL_ERR("Could not register wiphy device (%d)\n", err);
@@ -2821,9 +4464,9 @@ wiphy_new_out:
2821 return ERR_PTR(err); 4464 return ERR_PTR(err);
2822} 4465}
2823 4466
2824static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv) 4467static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
2825{ 4468{
2826 struct wireless_dev *wdev = cfg_priv->wdev; 4469 struct wireless_dev *wdev = cfg->wdev;
2827 4470
2828 if (!wdev) { 4471 if (!wdev) {
2829 WL_ERR("wdev is invalid\n"); 4472 WL_ERR("wdev is invalid\n");
@@ -2832,10 +4475,10 @@ static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2832 wiphy_unregister(wdev->wiphy); 4475 wiphy_unregister(wdev->wiphy);
2833 wiphy_free(wdev->wiphy); 4476 wiphy_free(wdev->wiphy);
2834 kfree(wdev); 4477 kfree(wdev);
2835 cfg_priv->wdev = NULL; 4478 cfg->wdev = NULL;
2836} 4479}
2837 4480
2838static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv, 4481static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
2839 const struct brcmf_event_msg *e) 4482 const struct brcmf_event_msg *e)
2840{ 4483{
2841 u32 event = be32_to_cpu(e->event_type); 4484 u32 event = be32_to_cpu(e->event_type);
@@ -2843,14 +4486,14 @@ static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2843 4486
2844 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) { 4487 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2845 WL_CONN("Processing set ssid\n"); 4488 WL_CONN("Processing set ssid\n");
2846 cfg_priv->link_up = true; 4489 cfg->link_up = true;
2847 return true; 4490 return true;
2848 } 4491 }
2849 4492
2850 return false; 4493 return false;
2851} 4494}
2852 4495
2853static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv, 4496static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
2854 const struct brcmf_event_msg *e) 4497 const struct brcmf_event_msg *e)
2855{ 4498{
2856 u32 event = be32_to_cpu(e->event_type); 4499 u32 event = be32_to_cpu(e->event_type);
@@ -2863,7 +4506,7 @@ static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2863 return false; 4506 return false;
2864} 4507}
2865 4508
2866static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv, 4509static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
2867 const struct brcmf_event_msg *e) 4510 const struct brcmf_event_msg *e)
2868{ 4511{
2869 u32 event = be32_to_cpu(e->event_type); 4512 u32 event = be32_to_cpu(e->event_type);
@@ -2884,9 +4527,9 @@ static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2884 return false; 4527 return false;
2885} 4528}
2886 4529
2887static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4530static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
2888{ 4531{
2889 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4532 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
2890 4533
2891 kfree(conn_info->req_ie); 4534 kfree(conn_info->req_ie);
2892 conn_info->req_ie = NULL; 4535 conn_info->req_ie = NULL;
@@ -2896,30 +4539,30 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2896 conn_info->resp_ie_len = 0; 4539 conn_info->resp_ie_len = 0;
2897} 4540}
2898 4541
2899static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) 4542static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
2900{ 4543{
2901 struct net_device *ndev = cfg_to_ndev(cfg_priv); 4544 struct net_device *ndev = cfg_to_ndev(cfg);
2902 struct brcmf_cfg80211_assoc_ielen_le *assoc_info; 4545 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2903 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4546 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
2904 u32 req_len; 4547 u32 req_len;
2905 u32 resp_len; 4548 u32 resp_len;
2906 s32 err = 0; 4549 s32 err = 0;
2907 4550
2908 brcmf_clear_assoc_ies(cfg_priv); 4551 brcmf_clear_assoc_ies(cfg);
2909 4552
2910 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf, 4553 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
2911 WL_ASSOC_INFO_MAX); 4554 WL_ASSOC_INFO_MAX);
2912 if (err) { 4555 if (err) {
2913 WL_ERR("could not get assoc info (%d)\n", err); 4556 WL_ERR("could not get assoc info (%d)\n", err);
2914 return err; 4557 return err;
2915 } 4558 }
2916 assoc_info = 4559 assoc_info =
2917 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf; 4560 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
2918 req_len = le32_to_cpu(assoc_info->req_len); 4561 req_len = le32_to_cpu(assoc_info->req_len);
2919 resp_len = le32_to_cpu(assoc_info->resp_len); 4562 resp_len = le32_to_cpu(assoc_info->resp_len);
2920 if (req_len) { 4563 if (req_len) {
2921 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies", 4564 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2922 cfg_priv->extra_buf, 4565 cfg->extra_buf,
2923 WL_ASSOC_INFO_MAX); 4566 WL_ASSOC_INFO_MAX);
2924 if (err) { 4567 if (err) {
2925 WL_ERR("could not get assoc req (%d)\n", err); 4568 WL_ERR("could not get assoc req (%d)\n", err);
@@ -2927,7 +4570,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2927 } 4570 }
2928 conn_info->req_ie_len = req_len; 4571 conn_info->req_ie_len = req_len;
2929 conn_info->req_ie = 4572 conn_info->req_ie =
2930 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len, 4573 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
2931 GFP_KERNEL); 4574 GFP_KERNEL);
2932 } else { 4575 } else {
2933 conn_info->req_ie_len = 0; 4576 conn_info->req_ie_len = 0;
@@ -2935,7 +4578,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2935 } 4578 }
2936 if (resp_len) { 4579 if (resp_len) {
2937 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies", 4580 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2938 cfg_priv->extra_buf, 4581 cfg->extra_buf,
2939 WL_ASSOC_INFO_MAX); 4582 WL_ASSOC_INFO_MAX);
2940 if (err) { 4583 if (err) {
2941 WL_ERR("could not get assoc resp (%d)\n", err); 4584 WL_ERR("could not get assoc resp (%d)\n", err);
@@ -2943,7 +4586,7 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2943 } 4586 }
2944 conn_info->resp_ie_len = resp_len; 4587 conn_info->resp_ie_len = resp_len;
2945 conn_info->resp_ie = 4588 conn_info->resp_ie =
2946 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len, 4589 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
2947 GFP_KERNEL); 4590 GFP_KERNEL);
2948 } else { 4591 } else {
2949 conn_info->resp_ie_len = 0; 4592 conn_info->resp_ie_len = 0;
@@ -2956,12 +4599,13 @@ static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2956} 4599}
2957 4600
2958static s32 4601static s32
2959brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, 4602brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
2960 struct net_device *ndev, 4603 struct net_device *ndev,
2961 const struct brcmf_event_msg *e) 4604 const struct brcmf_event_msg *e)
2962{ 4605{
2963 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4606 struct brcmf_cfg80211_profile *profile = cfg->profile;
2964 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); 4607 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4608 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2965 struct brcmf_channel_info_le channel_le; 4609 struct brcmf_channel_info_le channel_le;
2966 struct ieee80211_channel *notify_channel; 4610 struct ieee80211_channel *notify_channel;
2967 struct ieee80211_supported_band *band; 4611 struct ieee80211_supported_band *band;
@@ -2971,9 +4615,9 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2971 4615
2972 WL_TRACE("Enter\n"); 4616 WL_TRACE("Enter\n");
2973 4617
2974 brcmf_get_assoc_ies(cfg_priv); 4618 brcmf_get_assoc_ies(cfg);
2975 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID); 4619 memcpy(profile->bssid, e->addr, ETH_ALEN);
2976 brcmf_update_bss_info(cfg_priv); 4620 brcmf_update_bss_info(cfg);
2977 4621
2978 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le, 4622 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2979 sizeof(channel_le)); 4623 sizeof(channel_le));
@@ -2989,37 +4633,35 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2989 freq = ieee80211_channel_to_frequency(target_channel, band->band); 4633 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2990 notify_channel = ieee80211_get_channel(wiphy, freq); 4634 notify_channel = ieee80211_get_channel(wiphy, freq);
2991 4635
2992 cfg80211_roamed(ndev, notify_channel, 4636 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
2993 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2994 conn_info->req_ie, conn_info->req_ie_len, 4637 conn_info->req_ie, conn_info->req_ie_len,
2995 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); 4638 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2996 WL_CONN("Report roaming result\n"); 4639 WL_CONN("Report roaming result\n");
2997 4640
2998 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4641 set_bit(WL_STATUS_CONNECTED, &cfg->status);
2999 WL_TRACE("Exit\n"); 4642 WL_TRACE("Exit\n");
3000 return err; 4643 return err;
3001} 4644}
3002 4645
3003static s32 4646static s32
3004brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, 4647brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
3005 struct net_device *ndev, const struct brcmf_event_msg *e, 4648 struct net_device *ndev, const struct brcmf_event_msg *e,
3006 bool completed) 4649 bool completed)
3007{ 4650{
3008 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); 4651 struct brcmf_cfg80211_profile *profile = cfg->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3009 s32 err = 0; 4653 s32 err = 0;
3010 4654
3011 WL_TRACE("Enter\n"); 4655 WL_TRACE("Enter\n");
3012 4656
3013 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) { 4657 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
3014 if (completed) { 4658 if (completed) {
3015 brcmf_get_assoc_ies(cfg_priv); 4659 brcmf_get_assoc_ies(cfg);
3016 brcmf_update_prof(cfg_priv, NULL, &e->addr, 4660 memcpy(profile->bssid, e->addr, ETH_ALEN);
3017 WL_PROF_BSSID); 4661 brcmf_update_bss_info(cfg);
3018 brcmf_update_bss_info(cfg_priv);
3019 } 4662 }
3020 cfg80211_connect_result(ndev, 4663 cfg80211_connect_result(ndev,
3021 (u8 *)brcmf_read_prof(cfg_priv, 4664 (u8 *)profile->bssid,
3022 WL_PROF_BSSID),
3023 conn_info->req_ie, 4665 conn_info->req_ie,
3024 conn_info->req_ie_len, 4666 conn_info->req_ie_len,
3025 conn_info->resp_ie, 4667 conn_info->resp_ie,
@@ -3028,7 +4670,7 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3028 WLAN_STATUS_AUTH_TIMEOUT, 4670 WLAN_STATUS_AUTH_TIMEOUT,
3029 GFP_KERNEL); 4671 GFP_KERNEL);
3030 if (completed) 4672 if (completed)
3031 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4673 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3032 WL_CONN("Report connect result - connection %s\n", 4674 WL_CONN("Report connect result - connection %s\n",
3033 completed ? "succeeded" : "failed"); 4675 completed ? "succeeded" : "failed");
3034 } 4676 }
@@ -3037,52 +4679,93 @@ brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3037} 4679}
3038 4680
3039static s32 4681static s32
3040brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, 4682brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4683 struct net_device *ndev,
4684 const struct brcmf_event_msg *e, void *data)
4685{
4686 s32 err = 0;
4687 u32 event = be32_to_cpu(e->event_type);
4688 u32 reason = be32_to_cpu(e->reason);
4689 u32 len = be32_to_cpu(e->datalen);
4690 static int generation;
4691
4692 struct station_info sinfo;
4693
4694 WL_CONN("event %d, reason %d\n", event, reason);
4695 memset(&sinfo, 0, sizeof(sinfo));
4696
4697 sinfo.filled = 0;
4698 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4699 reason == BRCMF_E_STATUS_SUCCESS) {
4700 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4701 if (!data) {
4702 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4703 return -EINVAL;
4704 }
4705 sinfo.assoc_req_ies = data;
4706 sinfo.assoc_req_ies_len = len;
4707 generation++;
4708 sinfo.generation = generation;
4709 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4710 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4711 (event == BRCMF_E_DEAUTH_IND) ||
4712 (event == BRCMF_E_DEAUTH)) {
4713 generation++;
4714 sinfo.generation = generation;
4715 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4716 }
4717 return err;
4718}
4719
4720static s32
4721brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
3041 struct net_device *ndev, 4722 struct net_device *ndev,
3042 const struct brcmf_event_msg *e, void *data) 4723 const struct brcmf_event_msg *e, void *data)
3043{ 4724{
4725 struct brcmf_cfg80211_profile *profile = cfg->profile;
3044 s32 err = 0; 4726 s32 err = 0;
3045 4727
3046 if (brcmf_is_linkup(cfg_priv, e)) { 4728 if (cfg->conf->mode == WL_MODE_AP) {
4729 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4730 } else if (brcmf_is_linkup(cfg, e)) {
3047 WL_CONN("Linkup\n"); 4731 WL_CONN("Linkup\n");
3048 if (brcmf_is_ibssmode(cfg_priv)) { 4732 if (brcmf_is_ibssmode(cfg)) {
3049 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr, 4733 memcpy(profile->bssid, e->addr, ETH_ALEN);
3050 WL_PROF_BSSID); 4734 wl_inform_ibss(cfg, ndev, e->addr);
3051 wl_inform_ibss(cfg_priv, ndev, e->addr);
3052 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL); 4735 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3053 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4736 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3054 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); 4737 set_bit(WL_STATUS_CONNECTED, &cfg->status);
3055 } else 4738 } else
3056 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4739 brcmf_bss_connect_done(cfg, ndev, e, true);
3057 } else if (brcmf_is_linkdown(cfg_priv, e)) { 4740 } else if (brcmf_is_linkdown(cfg, e)) {
3058 WL_CONN("Linkdown\n"); 4741 WL_CONN("Linkdown\n");
3059 if (brcmf_is_ibssmode(cfg_priv)) { 4742 if (brcmf_is_ibssmode(cfg)) {
3060 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4743 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3061 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4744 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3062 &cfg_priv->status)) 4745 &cfg->status))
3063 brcmf_link_down(cfg_priv); 4746 brcmf_link_down(cfg);
3064 } else { 4747 } else {
3065 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4748 brcmf_bss_connect_done(cfg, ndev, e, false);
3066 if (test_and_clear_bit(WL_STATUS_CONNECTED, 4749 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3067 &cfg_priv->status)) { 4750 &cfg->status)) {
3068 cfg80211_disconnected(ndev, 0, NULL, 0, 4751 cfg80211_disconnected(ndev, 0, NULL, 0,
3069 GFP_KERNEL); 4752 GFP_KERNEL);
3070 brcmf_link_down(cfg_priv); 4753 brcmf_link_down(cfg);
3071 } 4754 }
3072 } 4755 }
3073 brcmf_init_prof(cfg_priv->profile); 4756 brcmf_init_prof(cfg->profile);
3074 } else if (brcmf_is_nonetwork(cfg_priv, e)) { 4757 } else if (brcmf_is_nonetwork(cfg, e)) {
3075 if (brcmf_is_ibssmode(cfg_priv)) 4758 if (brcmf_is_ibssmode(cfg))
3076 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); 4759 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
3077 else 4760 else
3078 brcmf_bss_connect_done(cfg_priv, ndev, e, false); 4761 brcmf_bss_connect_done(cfg, ndev, e, false);
3079 } 4762 }
3080 4763
3081 return err; 4764 return err;
3082} 4765}
3083 4766
3084static s32 4767static s32
3085brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, 4768brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
3086 struct net_device *ndev, 4769 struct net_device *ndev,
3087 const struct brcmf_event_msg *e, void *data) 4770 const struct brcmf_event_msg *e, void *data)
3088{ 4771{
@@ -3091,17 +4774,17 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3091 u32 status = be32_to_cpu(e->status); 4774 u32 status = be32_to_cpu(e->status);
3092 4775
3093 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { 4776 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3094 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) 4777 if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
3095 brcmf_bss_roaming_done(cfg_priv, ndev, e); 4778 brcmf_bss_roaming_done(cfg, ndev, e);
3096 else 4779 else
3097 brcmf_bss_connect_done(cfg_priv, ndev, e, true); 4780 brcmf_bss_connect_done(cfg, ndev, e, true);
3098 } 4781 }
3099 4782
3100 return err; 4783 return err;
3101} 4784}
3102 4785
3103static s32 4786static s32
3104brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, 4787brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
3105 struct net_device *ndev, 4788 struct net_device *ndev,
3106 const struct brcmf_event_msg *e, void *data) 4789 const struct brcmf_event_msg *e, void *data)
3107{ 4790{
@@ -3120,7 +4803,7 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3120} 4803}
3121 4804
3122static s32 4805static s32
3123brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, 4806brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
3124 struct net_device *ndev, 4807 struct net_device *ndev,
3125 const struct brcmf_event_msg *e, void *data) 4808 const struct brcmf_event_msg *e, void *data)
3126{ 4809{
@@ -3133,12 +4816,12 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3133 4816
3134 WL_TRACE("Enter\n"); 4817 WL_TRACE("Enter\n");
3135 4818
3136 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) { 4819 if (cfg->iscan_on && cfg->iscan_kickstart) {
3137 WL_TRACE("Exit\n"); 4820 WL_TRACE("Exit\n");
3138 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv)); 4821 return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
3139 } 4822 }
3140 4823
3141 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) { 4824 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
3142 WL_ERR("Scan complete while device not scanning\n"); 4825 WL_ERR("Scan complete while device not scanning\n");
3143 scan_abort = true; 4826 scan_abort = true;
3144 err = -EINVAL; 4827 err = -EINVAL;
@@ -3155,35 +4838,33 @@ brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3155 scan_channel = le32_to_cpu(channel_inform_le.scan_channel); 4838 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3156 if (scan_channel) 4839 if (scan_channel)
3157 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel); 4840 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3158 cfg_priv->bss_list = cfg_priv->scan_results; 4841 cfg->bss_list = cfg->scan_results;
3159 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list; 4842 bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
3160 4843
3161 memset(cfg_priv->scan_results, 0, len); 4844 memset(cfg->scan_results, 0, len);
3162 bss_list_le->buflen = cpu_to_le32(len); 4845 bss_list_le->buflen = cpu_to_le32(len);
3163 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS, 4846 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3164 cfg_priv->scan_results, len); 4847 cfg->scan_results, len);
3165 if (err) { 4848 if (err) {
3166 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); 4849 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3167 err = -EINVAL; 4850 err = -EINVAL;
3168 scan_abort = true; 4851 scan_abort = true;
3169 goto scan_done_out; 4852 goto scan_done_out;
3170 } 4853 }
3171 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen); 4854 cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3172 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version); 4855 cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
3173 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count); 4856 cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
3174 4857
3175 err = brcmf_inform_bss(cfg_priv); 4858 err = brcmf_inform_bss(cfg);
3176 if (err) { 4859 if (err)
3177 scan_abort = true; 4860 scan_abort = true;
3178 goto scan_done_out;
3179 }
3180 4861
3181scan_done_out: 4862scan_done_out:
3182 if (cfg_priv->scan_request) { 4863 if (cfg->scan_request) {
3183 WL_SCAN("calling cfg80211_scan_done\n"); 4864 WL_SCAN("calling cfg80211_scan_done\n");
3184 cfg80211_scan_done(cfg_priv->scan_request, scan_abort); 4865 cfg80211_scan_done(cfg->scan_request, scan_abort);
3185 brcmf_set_mpc(ndev, 1); 4866 brcmf_set_mpc(ndev, 1);
3186 cfg_priv->scan_request = NULL; 4867 cfg->scan_request = NULL;
3187 } 4868 }
3188 4869
3189 WL_TRACE("Exit\n"); 4870 WL_TRACE("Exit\n");
@@ -3206,68 +4887,85 @@ static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3206 memset(el, 0, sizeof(*el)); 4887 memset(el, 0, sizeof(*el));
3207 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status; 4888 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3208 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status; 4889 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
4890 el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
4891 el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
4892 el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status;
4893 el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status;
4894 el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status;
3209 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status; 4895 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3210 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status; 4896 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3211 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status; 4897 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
4898 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results;
4899}
4900
4901static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4902{
4903 kfree(cfg->scan_results);
4904 cfg->scan_results = NULL;
4905 kfree(cfg->bss_info);
4906 cfg->bss_info = NULL;
4907 kfree(cfg->conf);
4908 cfg->conf = NULL;
4909 kfree(cfg->profile);
4910 cfg->profile = NULL;
4911 kfree(cfg->scan_req_int);
4912 cfg->scan_req_int = NULL;
4913 kfree(cfg->escan_ioctl_buf);
4914 cfg->escan_ioctl_buf = NULL;
4915 kfree(cfg->dcmd_buf);
4916 cfg->dcmd_buf = NULL;
4917 kfree(cfg->extra_buf);
4918 cfg->extra_buf = NULL;
4919 kfree(cfg->iscan);
4920 cfg->iscan = NULL;
4921 kfree(cfg->pmk_list);
4922 cfg->pmk_list = NULL;
4923 if (cfg->ap_info) {
4924 kfree(cfg->ap_info->wpa_ie);
4925 kfree(cfg->ap_info->rsn_ie);
4926 kfree(cfg->ap_info);
4927 cfg->ap_info = NULL;
4928 }
3212} 4929}
3213 4930
3214static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) 4931static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
3215{ 4932{
3216 kfree(cfg_priv->scan_results); 4933 cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3217 cfg_priv->scan_results = NULL; 4934 if (!cfg->scan_results)
3218 kfree(cfg_priv->bss_info);
3219 cfg_priv->bss_info = NULL;
3220 kfree(cfg_priv->conf);
3221 cfg_priv->conf = NULL;
3222 kfree(cfg_priv->profile);
3223 cfg_priv->profile = NULL;
3224 kfree(cfg_priv->scan_req_int);
3225 cfg_priv->scan_req_int = NULL;
3226 kfree(cfg_priv->dcmd_buf);
3227 cfg_priv->dcmd_buf = NULL;
3228 kfree(cfg_priv->extra_buf);
3229 cfg_priv->extra_buf = NULL;
3230 kfree(cfg_priv->iscan);
3231 cfg_priv->iscan = NULL;
3232 kfree(cfg_priv->pmk_list);
3233 cfg_priv->pmk_list = NULL;
3234}
3235
3236static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3237{
3238 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3239 if (!cfg_priv->scan_results)
3240 goto init_priv_mem_out; 4935 goto init_priv_mem_out;
3241 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL); 4936 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
3242 if (!cfg_priv->conf) 4937 if (!cfg->conf)
3243 goto init_priv_mem_out; 4938 goto init_priv_mem_out;
3244 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL); 4939 cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
3245 if (!cfg_priv->profile) 4940 if (!cfg->profile)
3246 goto init_priv_mem_out; 4941 goto init_priv_mem_out;
3247 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); 4942 cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3248 if (!cfg_priv->bss_info) 4943 if (!cfg->bss_info)
3249 goto init_priv_mem_out; 4944 goto init_priv_mem_out;
3250 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int), 4945 cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
3251 GFP_KERNEL); 4946 GFP_KERNEL);
3252 if (!cfg_priv->scan_req_int) 4947 if (!cfg->scan_req_int)
4948 goto init_priv_mem_out;
4949 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4950 if (!cfg->escan_ioctl_buf)
3253 goto init_priv_mem_out; 4951 goto init_priv_mem_out;
3254 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL); 4952 cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3255 if (!cfg_priv->dcmd_buf) 4953 if (!cfg->dcmd_buf)
3256 goto init_priv_mem_out; 4954 goto init_priv_mem_out;
3257 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); 4955 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3258 if (!cfg_priv->extra_buf) 4956 if (!cfg->extra_buf)
3259 goto init_priv_mem_out; 4957 goto init_priv_mem_out;
3260 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL); 4958 cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
3261 if (!cfg_priv->iscan) 4959 if (!cfg->iscan)
3262 goto init_priv_mem_out; 4960 goto init_priv_mem_out;
3263 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL); 4961 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
3264 if (!cfg_priv->pmk_list) 4962 if (!cfg->pmk_list)
3265 goto init_priv_mem_out; 4963 goto init_priv_mem_out;
3266 4964
3267 return 0; 4965 return 0;
3268 4966
3269init_priv_mem_out: 4967init_priv_mem_out:
3270 brcmf_deinit_priv_mem(cfg_priv); 4968 brcmf_deinit_priv_mem(cfg);
3271 4969
3272 return -ENOMEM; 4970 return -ENOMEM;
3273} 4971}
@@ -3277,17 +4975,17 @@ init_priv_mem_out:
3277*/ 4975*/
3278 4976
3279static struct brcmf_cfg80211_event_q *brcmf_deq_event( 4977static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3280 struct brcmf_cfg80211_priv *cfg_priv) 4978 struct brcmf_cfg80211_info *cfg)
3281{ 4979{
3282 struct brcmf_cfg80211_event_q *e = NULL; 4980 struct brcmf_cfg80211_event_q *e = NULL;
3283 4981
3284 spin_lock_irq(&cfg_priv->evt_q_lock); 4982 spin_lock_irq(&cfg->evt_q_lock);
3285 if (!list_empty(&cfg_priv->evt_q_list)) { 4983 if (!list_empty(&cfg->evt_q_list)) {
3286 e = list_first_entry(&cfg_priv->evt_q_list, 4984 e = list_first_entry(&cfg->evt_q_list,
3287 struct brcmf_cfg80211_event_q, evt_q_list); 4985 struct brcmf_cfg80211_event_q, evt_q_list);
3288 list_del(&e->evt_q_list); 4986 list_del(&e->evt_q_list);
3289 } 4987 }
3290 spin_unlock_irq(&cfg_priv->evt_q_lock); 4988 spin_unlock_irq(&cfg->evt_q_lock);
3291 4989
3292 return e; 4990 return e;
3293} 4991}
@@ -3299,23 +4997,33 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3299*/ 4997*/
3300 4998
3301static s32 4999static s32
3302brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, 5000brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
3303 const struct brcmf_event_msg *msg) 5001 const struct brcmf_event_msg *msg, void *data)
3304{ 5002{
3305 struct brcmf_cfg80211_event_q *e; 5003 struct brcmf_cfg80211_event_q *e;
3306 s32 err = 0; 5004 s32 err = 0;
3307 ulong flags; 5005 ulong flags;
5006 u32 data_len;
5007 u32 total_len;
3308 5008
3309 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC); 5009 total_len = sizeof(struct brcmf_cfg80211_event_q);
5010 if (data)
5011 data_len = be32_to_cpu(msg->datalen);
5012 else
5013 data_len = 0;
5014 total_len += data_len;
5015 e = kzalloc(total_len, GFP_ATOMIC);
3310 if (!e) 5016 if (!e)
3311 return -ENOMEM; 5017 return -ENOMEM;
3312 5018
3313 e->etype = event; 5019 e->etype = event;
3314 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg)); 5020 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
5021 if (data)
5022 memcpy(&e->edata, data, data_len);
3315 5023
3316 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags); 5024 spin_lock_irqsave(&cfg->evt_q_lock, flags);
3317 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list); 5025 list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
3318 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags); 5026 spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
3319 5027
3320 return err; 5028 return err;
3321} 5029}
@@ -3327,12 +5035,12 @@ static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3327 5035
3328static void brcmf_cfg80211_event_handler(struct work_struct *work) 5036static void brcmf_cfg80211_event_handler(struct work_struct *work)
3329{ 5037{
3330 struct brcmf_cfg80211_priv *cfg_priv = 5038 struct brcmf_cfg80211_info *cfg =
3331 container_of(work, struct brcmf_cfg80211_priv, 5039 container_of(work, struct brcmf_cfg80211_info,
3332 event_work); 5040 event_work);
3333 struct brcmf_cfg80211_event_q *e; 5041 struct brcmf_cfg80211_event_q *e;
3334 5042
3335 e = brcmf_deq_event(cfg_priv); 5043 e = brcmf_deq_event(cfg);
3336 if (unlikely(!e)) { 5044 if (unlikely(!e)) {
3337 WL_ERR("event queue empty...\n"); 5045 WL_ERR("event queue empty...\n");
3338 return; 5046 return;
@@ -3340,137 +5048,131 @@ static void brcmf_cfg80211_event_handler(struct work_struct *work)
3340 5048
3341 do { 5049 do {
3342 WL_INFO("event type (%d)\n", e->etype); 5050 WL_INFO("event type (%d)\n", e->etype);
3343 if (cfg_priv->el.handler[e->etype]) 5051 if (cfg->el.handler[e->etype])
3344 cfg_priv->el.handler[e->etype](cfg_priv, 5052 cfg->el.handler[e->etype](cfg,
3345 cfg_to_ndev(cfg_priv), 5053 cfg_to_ndev(cfg),
3346 &e->emsg, e->edata); 5054 &e->emsg, e->edata);
3347 else 5055 else
3348 WL_INFO("Unknown Event (%d): ignoring\n", e->etype); 5056 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3349 brcmf_put_event(e); 5057 brcmf_put_event(e);
3350 } while ((e = brcmf_deq_event(cfg_priv))); 5058 } while ((e = brcmf_deq_event(cfg)));
3351 5059
3352} 5060}
3353 5061
3354static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv) 5062static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
3355{ 5063{
3356 spin_lock_init(&cfg_priv->evt_q_lock); 5064 spin_lock_init(&cfg->evt_q_lock);
3357 INIT_LIST_HEAD(&cfg_priv->evt_q_list); 5065 INIT_LIST_HEAD(&cfg->evt_q_list);
3358} 5066}
3359 5067
3360static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv) 5068static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
3361{ 5069{
3362 struct brcmf_cfg80211_event_q *e; 5070 struct brcmf_cfg80211_event_q *e;
3363 5071
3364 spin_lock_irq(&cfg_priv->evt_q_lock); 5072 spin_lock_irq(&cfg->evt_q_lock);
3365 while (!list_empty(&cfg_priv->evt_q_list)) { 5073 while (!list_empty(&cfg->evt_q_list)) {
3366 e = list_first_entry(&cfg_priv->evt_q_list, 5074 e = list_first_entry(&cfg->evt_q_list,
3367 struct brcmf_cfg80211_event_q, evt_q_list); 5075 struct brcmf_cfg80211_event_q, evt_q_list);
3368 list_del(&e->evt_q_list); 5076 list_del(&e->evt_q_list);
3369 kfree(e); 5077 kfree(e);
3370 } 5078 }
3371 spin_unlock_irq(&cfg_priv->evt_q_lock); 5079 spin_unlock_irq(&cfg->evt_q_lock);
3372} 5080}
3373 5081
3374static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv) 5082static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
3375{ 5083{
3376 s32 err = 0; 5084 s32 err = 0;
3377 5085
3378 cfg_priv->scan_request = NULL; 5086 cfg->scan_request = NULL;
3379 cfg_priv->pwr_save = true; 5087 cfg->pwr_save = true;
3380 cfg_priv->iscan_on = true; /* iscan on & off switch. 5088#ifdef CONFIG_BRCMISCAN
5089 cfg->iscan_on = true; /* iscan on & off switch.
3381 we enable iscan per default */ 5090 we enable iscan per default */
3382 cfg_priv->roam_on = true; /* roam on & off switch. 5091 cfg->escan_on = false; /* escan on & off switch.
5092 we disable escan per default */
5093#else
5094 cfg->iscan_on = false; /* iscan on & off switch.
5095 we disable iscan per default */
5096 cfg->escan_on = true; /* escan on & off switch.
5097 we enable escan per default */
5098#endif
5099 cfg->roam_on = true; /* roam on & off switch.
3383 we enable roam per default */ 5100 we enable roam per default */
3384 5101
3385 cfg_priv->iscan_kickstart = false; 5102 cfg->iscan_kickstart = false;
3386 cfg_priv->active_scan = true; /* we do active scan for 5103 cfg->active_scan = true; /* we do active scan for
3387 specific scan per default */ 5104 specific scan per default */
3388 cfg_priv->dongle_up = false; /* dongle is not up yet */ 5105 cfg->dongle_up = false; /* dongle is not up yet */
3389 brcmf_init_eq(cfg_priv); 5106 brcmf_init_eq(cfg);
3390 err = brcmf_init_priv_mem(cfg_priv); 5107 err = brcmf_init_priv_mem(cfg);
3391 if (err) 5108 if (err)
3392 return err; 5109 return err;
3393 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler); 5110 INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
3394 brcmf_init_eloop_handler(&cfg_priv->el); 5111 brcmf_init_eloop_handler(&cfg->el);
3395 mutex_init(&cfg_priv->usr_sync); 5112 mutex_init(&cfg->usr_sync);
3396 err = brcmf_init_iscan(cfg_priv); 5113 err = brcmf_init_iscan(cfg);
3397 if (err) 5114 if (err)
3398 return err; 5115 return err;
3399 brcmf_init_conf(cfg_priv->conf); 5116 brcmf_init_escan(cfg);
3400 brcmf_init_prof(cfg_priv->profile); 5117 brcmf_init_conf(cfg->conf);
3401 brcmf_link_down(cfg_priv); 5118 brcmf_init_prof(cfg->profile);
5119 brcmf_link_down(cfg);
3402 5120
3403 return err; 5121 return err;
3404} 5122}
3405 5123
3406static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv) 5124static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
3407{ 5125{
3408 cancel_work_sync(&cfg_priv->event_work); 5126 cancel_work_sync(&cfg->event_work);
3409 cfg_priv->dongle_up = false; /* dongle down */ 5127 cfg->dongle_up = false; /* dongle down */
3410 brcmf_flush_eq(cfg_priv); 5128 brcmf_flush_eq(cfg);
3411 brcmf_link_down(cfg_priv); 5129 brcmf_link_down(cfg);
3412 brcmf_term_iscan(cfg_priv); 5130 brcmf_abort_scanning(cfg);
3413 brcmf_deinit_priv_mem(cfg_priv); 5131 brcmf_deinit_priv_mem(cfg);
3414} 5132}
3415 5133
3416struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, 5134struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
3417 struct device *busdev, 5135 struct device *busdev,
3418 void *data) 5136 struct brcmf_pub *drvr)
3419{ 5137{
3420 struct wireless_dev *wdev; 5138 struct wireless_dev *wdev;
3421 struct brcmf_cfg80211_priv *cfg_priv; 5139 struct brcmf_cfg80211_info *cfg;
3422 struct brcmf_cfg80211_iface *ci;
3423 struct brcmf_cfg80211_dev *cfg_dev;
3424 s32 err = 0; 5140 s32 err = 0;
3425 5141
3426 if (!ndev) { 5142 if (!ndev) {
3427 WL_ERR("ndev is invalid\n"); 5143 WL_ERR("ndev is invalid\n");
3428 return NULL; 5144 return NULL;
3429 } 5145 }
3430 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3431 if (!cfg_dev)
3432 return NULL;
3433 5146
3434 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev); 5147 wdev = brcmf_alloc_wdev(busdev);
3435 if (IS_ERR(wdev)) { 5148 if (IS_ERR(wdev)) {
3436 kfree(cfg_dev);
3437 return NULL; 5149 return NULL;
3438 } 5150 }
3439 5151
3440 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS); 5152 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3441 cfg_priv = wdev_to_cfg(wdev); 5153 cfg = wdev_to_cfg(wdev);
3442 cfg_priv->wdev = wdev; 5154 cfg->wdev = wdev;
3443 cfg_priv->pub = data; 5155 cfg->pub = drvr;
3444 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3445 ci->cfg_priv = cfg_priv;
3446 ndev->ieee80211_ptr = wdev; 5156 ndev->ieee80211_ptr = wdev;
3447 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 5157 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3448 wdev->netdev = ndev; 5158 wdev->netdev = ndev;
3449 err = wl_init_priv(cfg_priv); 5159 err = wl_init_priv(cfg);
3450 if (err) { 5160 if (err) {
3451 WL_ERR("Failed to init iwm_priv (%d)\n", err); 5161 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3452 goto cfg80211_attach_out; 5162 goto cfg80211_attach_out;
3453 } 5163 }
3454 brcmf_set_drvdata(cfg_dev, ci);
3455 5164
3456 return cfg_dev; 5165 return cfg;
3457 5166
3458cfg80211_attach_out: 5167cfg80211_attach_out:
3459 brcmf_free_wdev(cfg_priv); 5168 brcmf_free_wdev(cfg);
3460 kfree(cfg_dev);
3461 return NULL; 5169 return NULL;
3462} 5170}
3463 5171
3464void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev) 5172void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
3465{ 5173{
3466 struct brcmf_cfg80211_priv *cfg_priv; 5174 wl_deinit_priv(cfg);
3467 5175 brcmf_free_wdev(cfg);
3468 cfg_priv = brcmf_priv_get(cfg_dev);
3469
3470 wl_deinit_priv(cfg_priv);
3471 brcmf_free_wdev(cfg_priv);
3472 brcmf_set_drvdata(cfg_dev, NULL);
3473 kfree(cfg_dev);
3474} 5176}
3475 5177
3476void 5178void
@@ -3478,10 +5180,10 @@ brcmf_cfg80211_event(struct net_device *ndev,
3478 const struct brcmf_event_msg *e, void *data) 5180 const struct brcmf_event_msg *e, void *data)
3479{ 5181{
3480 u32 event_type = be32_to_cpu(e->event_type); 5182 u32 event_type = be32_to_cpu(e->event_type);
3481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); 5183 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3482 5184
3483 if (!brcmf_enq_event(cfg_priv, event_type, e)) 5185 if (!brcmf_enq_event(cfg, event_type, e, data))
3484 schedule_work(&cfg_priv->event_work); 5186 schedule_work(&cfg->event_work);
3485} 5187}
3486 5188
3487static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype) 5189static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
@@ -3502,6 +5204,9 @@ static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3502 case NL80211_IFTYPE_STATION: 5204 case NL80211_IFTYPE_STATION:
3503 infra = 1; 5205 infra = 1;
3504 break; 5206 break;
5207 case NL80211_IFTYPE_AP:
5208 infra = 1;
5209 break;
3505 default: 5210 default:
3506 err = -EINVAL; 5211 err = -EINVAL;
3507 WL_ERR("invalid type (%d)\n", iftype); 5212 WL_ERR("invalid type (%d)\n", iftype);
@@ -3554,6 +5259,8 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3554 setbit(eventmask, BRCMF_E_TXFAIL); 5259 setbit(eventmask, BRCMF_E_TXFAIL);
3555 setbit(eventmask, BRCMF_E_JOIN_START); 5260 setbit(eventmask, BRCMF_E_JOIN_START);
3556 setbit(eventmask, BRCMF_E_SCAN_COMPLETE); 5261 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
5262 setbit(eventmask, BRCMF_E_ESCAN_RESULT);
5263 setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
3557 5264
3558 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, 5265 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3559 iovbuf, sizeof(iovbuf)); 5266 iovbuf, sizeof(iovbuf));
@@ -3672,46 +5379,46 @@ dongle_scantime_out:
3672 return err; 5379 return err;
3673} 5380}
3674 5381
3675static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv) 5382static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
3676{ 5383{
3677 struct wiphy *wiphy; 5384 struct wiphy *wiphy;
3678 s32 phy_list; 5385 s32 phy_list;
3679 s8 phy; 5386 s8 phy;
3680 s32 err = 0; 5387 s32 err = 0;
3681 5388
3682 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST, 5389 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
3683 &phy_list, sizeof(phy_list)); 5390 &phy_list, sizeof(phy_list));
3684 if (err) { 5391 if (err) {
3685 WL_ERR("error (%d)\n", err); 5392 WL_ERR("error (%d)\n", err);
3686 return err; 5393 return err;
3687 } 5394 }
3688 5395
3689 phy = ((char *)&phy_list)[1]; 5396 phy = ((char *)&phy_list)[0];
3690 WL_INFO("%c phy\n", phy); 5397 WL_INFO("%c phy\n", phy);
3691 if (phy == 'n' || phy == 'a') { 5398 if (phy == 'n' || phy == 'a') {
3692 wiphy = cfg_to_wiphy(cfg_priv); 5399 wiphy = cfg_to_wiphy(cfg);
3693 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; 5400 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3694 } 5401 }
3695 5402
3696 return err; 5403 return err;
3697} 5404}
3698 5405
3699static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv) 5406static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
3700{ 5407{
3701 return wl_update_wiphybands(cfg_priv); 5408 return wl_update_wiphybands(cfg);
3702} 5409}
3703 5410
3704static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv) 5411static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
3705{ 5412{
3706 struct net_device *ndev; 5413 struct net_device *ndev;
3707 struct wireless_dev *wdev; 5414 struct wireless_dev *wdev;
3708 s32 power_mode; 5415 s32 power_mode;
3709 s32 err = 0; 5416 s32 err = 0;
3710 5417
3711 if (cfg_priv->dongle_up) 5418 if (cfg->dongle_up)
3712 return err; 5419 return err;
3713 5420
3714 ndev = cfg_to_ndev(cfg_priv); 5421 ndev = cfg_to_ndev(cfg);
3715 wdev = ndev->ieee80211_ptr; 5422 wdev = ndev->ieee80211_ptr;
3716 5423
3717 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME, 5424 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
@@ -3721,21 +5428,21 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3721 if (err) 5428 if (err)
3722 goto default_conf_out; 5429 goto default_conf_out;
3723 5430
3724 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF; 5431 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
3725 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode); 5432 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3726 if (err) 5433 if (err)
3727 goto default_conf_out; 5434 goto default_conf_out;
3728 WL_INFO("power save set to %s\n", 5435 WL_INFO("power save set to %s\n",
3729 (power_mode ? "enabled" : "disabled")); 5436 (power_mode ? "enabled" : "disabled"));
3730 5437
3731 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1), 5438 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
3732 WL_BEACON_TIMEOUT); 5439 WL_BEACON_TIMEOUT);
3733 if (err) 5440 if (err)
3734 goto default_conf_out; 5441 goto default_conf_out;
3735 err = brcmf_dongle_mode(ndev, wdev->iftype); 5442 err = brcmf_dongle_mode(ndev, wdev->iftype);
3736 if (err && err != -EINPROGRESS) 5443 if (err && err != -EINPROGRESS)
3737 goto default_conf_out; 5444 goto default_conf_out;
3738 err = brcmf_dongle_probecap(cfg_priv); 5445 err = brcmf_dongle_probecap(cfg);
3739 if (err) 5446 if (err)
3740 goto default_conf_out; 5447 goto default_conf_out;
3741 5448
@@ -3743,31 +5450,31 @@ static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3743 5450
3744default_conf_out: 5451default_conf_out:
3745 5452
3746 cfg_priv->dongle_up = true; 5453 cfg->dongle_up = true;
3747 5454
3748 return err; 5455 return err;
3749 5456
3750} 5457}
3751 5458
3752static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv) 5459static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
3753{ 5460{
3754 char buf[10+IFNAMSIZ]; 5461 char buf[10+IFNAMSIZ];
3755 struct dentry *fd; 5462 struct dentry *fd;
3756 s32 err = 0; 5463 s32 err = 0;
3757 5464
3758 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name); 5465 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
3759 cfg_priv->debugfsdir = debugfs_create_dir(buf, 5466 cfg->debugfsdir = debugfs_create_dir(buf,
3760 cfg_to_wiphy(cfg_priv)->debugfsdir); 5467 cfg_to_wiphy(cfg)->debugfsdir);
3761 5468
3762 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir, 5469 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
3763 (u16 *)&cfg_priv->profile->beacon_interval); 5470 (u16 *)&cfg->profile->beacon_interval);
3764 if (!fd) { 5471 if (!fd) {
3765 err = -ENOMEM; 5472 err = -ENOMEM;
3766 goto err_out; 5473 goto err_out;
3767 } 5474 }
3768 5475
3769 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir, 5476 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
3770 (u8 *)&cfg_priv->profile->dtim_period); 5477 (u8 *)&cfg->profile->dtim_period);
3771 if (!fd) { 5478 if (!fd) {
3772 err = -ENOMEM; 5479 err = -ENOMEM;
3773 goto err_out; 5480 goto err_out;
@@ -3777,40 +5484,40 @@ err_out:
3777 return err; 5484 return err;
3778} 5485}
3779 5486
3780static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv) 5487static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
3781{ 5488{
3782 debugfs_remove_recursive(cfg_priv->debugfsdir); 5489 debugfs_remove_recursive(cfg->debugfsdir);
3783 cfg_priv->debugfsdir = NULL; 5490 cfg->debugfsdir = NULL;
3784} 5491}
3785 5492
3786static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv) 5493static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
3787{ 5494{
3788 s32 err = 0; 5495 s32 err = 0;
3789 5496
3790 set_bit(WL_STATUS_READY, &cfg_priv->status); 5497 set_bit(WL_STATUS_READY, &cfg->status);
3791 5498
3792 brcmf_debugfs_add_netdev_params(cfg_priv); 5499 brcmf_debugfs_add_netdev_params(cfg);
3793 5500
3794 err = brcmf_config_dongle(cfg_priv); 5501 err = brcmf_config_dongle(cfg);
3795 if (err) 5502 if (err)
3796 return err; 5503 return err;
3797 5504
3798 brcmf_invoke_iscan(cfg_priv); 5505 brcmf_invoke_iscan(cfg);
3799 5506
3800 return err; 5507 return err;
3801} 5508}
3802 5509
3803static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv) 5510static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
3804{ 5511{
3805 /* 5512 /*
3806 * While going down, if associated with AP disassociate 5513 * While going down, if associated with AP disassociate
3807 * from AP to save power 5514 * from AP to save power
3808 */ 5515 */
3809 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) || 5516 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
3810 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) && 5517 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
3811 test_bit(WL_STATUS_READY, &cfg_priv->status)) { 5518 test_bit(WL_STATUS_READY, &cfg->status)) {
3812 WL_INFO("Disassociating from AP"); 5519 WL_INFO("Disassociating from AP");
3813 brcmf_link_down(cfg_priv); 5520 brcmf_link_down(cfg);
3814 5521
3815 /* Make sure WPA_Supplicant receives all the event 5522 /* Make sure WPA_Supplicant receives all the event
3816 generated due to DISASSOC call to the fw to keep 5523 generated due to DISASSOC call to the fw to keep
@@ -3819,63 +5526,33 @@ static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3819 brcmf_delay(500); 5526 brcmf_delay(500);
3820 } 5527 }
3821 5528
3822 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status); 5529 brcmf_abort_scanning(cfg);
3823 brcmf_term_iscan(cfg_priv); 5530 clear_bit(WL_STATUS_READY, &cfg->status);
3824 if (cfg_priv->scan_request) {
3825 cfg80211_scan_done(cfg_priv->scan_request, true);
3826 /* May need to perform this to cover rmmod */
3827 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3828 cfg_priv->scan_request = NULL;
3829 }
3830 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3831 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3832 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3833 5531
3834 brcmf_debugfs_remove_netdev(cfg_priv); 5532 brcmf_debugfs_remove_netdev(cfg);
3835 5533
3836 return 0; 5534 return 0;
3837} 5535}
3838 5536
3839s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev) 5537s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
3840{ 5538{
3841 struct brcmf_cfg80211_priv *cfg_priv;
3842 s32 err = 0; 5539 s32 err = 0;
3843 5540
3844 cfg_priv = brcmf_priv_get(cfg_dev); 5541 mutex_lock(&cfg->usr_sync);
3845 mutex_lock(&cfg_priv->usr_sync); 5542 err = __brcmf_cfg80211_up(cfg);
3846 err = __brcmf_cfg80211_up(cfg_priv); 5543 mutex_unlock(&cfg->usr_sync);
3847 mutex_unlock(&cfg_priv->usr_sync);
3848 5544
3849 return err; 5545 return err;
3850} 5546}
3851 5547
3852s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev) 5548s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
3853{ 5549{
3854 struct brcmf_cfg80211_priv *cfg_priv;
3855 s32 err = 0; 5550 s32 err = 0;
3856 5551
3857 cfg_priv = brcmf_priv_get(cfg_dev); 5552 mutex_lock(&cfg->usr_sync);
3858 mutex_lock(&cfg_priv->usr_sync); 5553 err = __brcmf_cfg80211_down(cfg);
3859 err = __brcmf_cfg80211_down(cfg_priv); 5554 mutex_unlock(&cfg->usr_sync);
3860 mutex_unlock(&cfg_priv->usr_sync);
3861 5555
3862 return err; 5556 return err;
3863} 5557}
3864 5558
3865static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3866 u8 t, u8 l, u8 *v)
3867{
3868 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3869 s32 err = 0;
3870
3871 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3872 WL_ERR("ei crosses buffer boundary\n");
3873 return -ENOSPC;
3874 }
3875 ie->buf[ie->offset] = t;
3876 ie->buf[ie->offset + 1] = l;
3877 memcpy(&ie->buf[ie->offset + 2], v, l);
3878 ie->offset += l + 2;
3879
3880 return err;
3881}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index b5d9b36df3d0..71ced174748a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -17,12 +17,6 @@
17#ifndef _wl_cfg80211_h_ 17#ifndef _wl_cfg80211_h_
18#define _wl_cfg80211_h_ 18#define _wl_cfg80211_h_
19 19
20struct brcmf_cfg80211_conf;
21struct brcmf_cfg80211_iface;
22struct brcmf_cfg80211_priv;
23struct brcmf_cfg80211_security;
24struct brcmf_cfg80211_ibss;
25
26#define WL_DBG_NONE 0 20#define WL_DBG_NONE 0
27#define WL_DBG_CONN (1 << 5) 21#define WL_DBG_CONN (1 << 5)
28#define WL_DBG_SCAN (1 << 4) 22#define WL_DBG_SCAN (1 << 4)
@@ -123,13 +117,25 @@ do { \
123#define WL_SCAN_UNASSOC_TIME 40 117#define WL_SCAN_UNASSOC_TIME 40
124#define WL_SCAN_PASSIVE_TIME 120 118#define WL_SCAN_PASSIVE_TIME 120
125 119
120#define WL_ESCAN_BUF_SIZE (1024 * 64)
121#define WL_ESCAN_TIMER_INTERVAL_MS 8000 /* E-Scan timeout */
122
123#define WL_ESCAN_ACTION_START 1
124#define WL_ESCAN_ACTION_CONTINUE 2
125#define WL_ESCAN_ACTION_ABORT 3
126
127#define WL_AUTH_SHARED_KEY 1 /* d11 shared authentication */
128#define IE_MAX_LEN 512
129
126/* dongle status */ 130/* dongle status */
127enum wl_status { 131enum wl_status {
128 WL_STATUS_READY, 132 WL_STATUS_READY,
129 WL_STATUS_SCANNING, 133 WL_STATUS_SCANNING,
130 WL_STATUS_SCAN_ABORTING, 134 WL_STATUS_SCAN_ABORTING,
131 WL_STATUS_CONNECTING, 135 WL_STATUS_CONNECTING,
132 WL_STATUS_CONNECTED 136 WL_STATUS_CONNECTED,
137 WL_STATUS_AP_CREATING,
138 WL_STATUS_AP_CREATED
133}; 139};
134 140
135/* wi-fi mode */ 141/* wi-fi mode */
@@ -169,23 +175,17 @@ struct brcmf_cfg80211_conf {
169 struct ieee80211_channel channel; 175 struct ieee80211_channel channel;
170}; 176};
171 177
178/* forward declaration */
179struct brcmf_cfg80211_info;
180
172/* cfg80211 main event loop */ 181/* cfg80211 main event loop */
173struct brcmf_cfg80211_event_loop { 182struct brcmf_cfg80211_event_loop {
174 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_priv *cfg_priv, 183 s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg,
175 struct net_device *ndev, 184 struct net_device *ndev,
176 const struct brcmf_event_msg *e, 185 const struct brcmf_event_msg *e,
177 void *data); 186 void *data);
178}; 187};
179 188
180/* representing interface of cfg80211 plane */
181struct brcmf_cfg80211_iface {
182 struct brcmf_cfg80211_priv *cfg_priv;
183};
184
185struct brcmf_cfg80211_dev {
186 void *driver_data; /* to store cfg80211 object information */
187};
188
189/* basic structure of scan request */ 189/* basic structure of scan request */
190struct brcmf_cfg80211_scan_req { 190struct brcmf_cfg80211_scan_req {
191 struct brcmf_ssid_le ssid_le; 191 struct brcmf_ssid_le ssid_le;
@@ -238,7 +238,7 @@ struct brcmf_cfg80211_profile {
238/* dongle iscan event loop */ 238/* dongle iscan event loop */
239struct brcmf_cfg80211_iscan_eloop { 239struct brcmf_cfg80211_iscan_eloop {
240 s32 (*handler[WL_SCAN_ERSULTS_LAST]) 240 s32 (*handler[WL_SCAN_ERSULTS_LAST])
241 (struct brcmf_cfg80211_priv *cfg_priv); 241 (struct brcmf_cfg80211_info *cfg);
242}; 242};
243 243
244/* dongle iscan controller */ 244/* dongle iscan controller */
@@ -275,92 +275,240 @@ struct brcmf_cfg80211_pmk_list {
275 struct pmkid foo[MAXPMKID - 1]; 275 struct pmkid foo[MAXPMKID - 1];
276}; 276};
277 277
278/* dongle private data of cfg80211 interface */ 278/* dongle escan state */
279struct brcmf_cfg80211_priv { 279enum wl_escan_state {
280 struct wireless_dev *wdev; /* representing wl cfg80211 device */ 280 WL_ESCAN_STATE_IDLE,
281 struct brcmf_cfg80211_conf *conf; /* dongle configuration */ 281 WL_ESCAN_STATE_SCANNING
282 struct cfg80211_scan_request *scan_request; /* scan request 282};
283 object */ 283
284 struct brcmf_cfg80211_event_loop el; /* main event loop */ 284struct escan_info {
285 struct list_head evt_q_list; /* used for event queue */ 285 u32 escan_state;
286 spinlock_t evt_q_lock; /* for event queue synchronization */ 286 u8 escan_buf[WL_ESCAN_BUF_SIZE];
287 struct mutex usr_sync; /* maily for dongle up/down synchronization */ 287 struct wiphy *wiphy;
288 struct brcmf_scan_results *bss_list; /* bss_list holding scanned 288 struct net_device *ndev;
289 ap information */ 289};
290
291/* Structure to hold WPS, WPA IEs for a AP */
292struct ap_info {
293 u8 probe_res_ie[IE_MAX_LEN];
294 u8 beacon_ie[IE_MAX_LEN];
295 u32 probe_res_ie_len;
296 u32 beacon_ie_len;
297 u8 *wpa_ie;
298 u8 *rsn_ie;
299 bool security_mode;
300};
301
302/**
303 * struct brcmf_pno_param_le - PNO scan configuration parameters
304 *
305 * @version: PNO parameters version.
306 * @scan_freq: scan frequency.
307 * @lost_network_timeout: #sec. to declare discovered network as lost.
308 * @flags: Bit field to control features of PFN such as sort criteria auto
309 * enable switch and background scan.
310 * @rssi_margin: Margin to avoid jitter for choosing a PFN based on RSSI sort
311 * criteria.
312 * @bestn: number of best networks in each scan.
313 * @mscan: number of scans recorded.
314 * @repeat: minimum number of scan intervals before scan frequency changes
315 * in adaptive scan.
316 * @exp: exponent of 2 for maximum scan interval.
317 * @slow_freq: slow scan period.
318 */
319struct brcmf_pno_param_le {
320 __le32 version;
321 __le32 scan_freq;
322 __le32 lost_network_timeout;
323 __le16 flags;
324 __le16 rssi_margin;
325 u8 bestn;
326 u8 mscan;
327 u8 repeat;
328 u8 exp;
329 __le32 slow_freq;
330};
331
332/**
333 * struct brcmf_pno_net_param_le - scan parameters per preferred network.
334 *
335 * @ssid: ssid name and its length.
336 * @flags: bit2: hidden.
337 * @infra: BSS vs IBSS.
338 * @auth: Open vs Closed.
339 * @wpa_auth: WPA type.
340 * @wsec: wsec value.
341 */
342struct brcmf_pno_net_param_le {
343 struct brcmf_ssid_le ssid;
344 __le32 flags;
345 __le32 infra;
346 __le32 auth;
347 __le32 wpa_auth;
348 __le32 wsec;
349};
350
351/**
352 * struct brcmf_pno_net_info_le - information per found network.
353 *
354 * @bssid: BSS network identifier.
355 * @channel: channel number only.
356 * @SSID_len: length of ssid.
357 * @SSID: ssid characters.
358 * @RSSI: receive signal strength (in dBm).
359 * @timestamp: age in seconds.
360 */
361struct brcmf_pno_net_info_le {
362 u8 bssid[ETH_ALEN];
363 u8 channel;
364 u8 SSID_len;
365 u8 SSID[32];
366 __le16 RSSI;
367 __le16 timestamp;
368};
369
370/**
371 * struct brcmf_pno_scanresults_le - result returned in PNO NET FOUND event.
372 *
373 * @version: PNO version identifier.
374 * @status: indicates completion status of PNO scan.
375 * @count: amount of brcmf_pno_net_info_le entries appended.
376 */
377struct brcmf_pno_scanresults_le {
378 __le32 version;
379 __le32 status;
380 __le32 count;
381};
382
383/**
384 * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
385 *
386 * @wdev: representing wl cfg80211 device.
387 * @conf: dongle configuration.
388 * @scan_request: cfg80211 scan request object.
389 * @el: main event loop.
390 * @evt_q_list: used for event queue.
391 * @evt_q_lock: for event queue synchronization.
392 * @usr_sync: mainly for dongle up/down synchronization.
393 * @bss_list: bss_list holding scanned ap information.
394 * @scan_results: results of the last scan.
395 * @scan_req_int: internal scan request object.
396 * @bss_info: bss information for cfg80211 layer.
397 * @ie: information element object for internal purpose.
398 * @profile: holding dongle profile.
399 * @iscan: iscan controller information.
400 * @conn_info: association info.
401 * @pmk_list: wpa2 pmk list.
402 * @event_work: event handler work struct.
403 * @status: current dongle status.
404 * @pub: common driver information.
405 * @channel: current channel.
406 * @iscan_on: iscan on/off switch.
407 * @iscan_kickstart: indicate iscan already started.
408 * @active_scan: current scan mode.
409 * @sched_escan: e-scan for scheduled scan support running.
410 * @ibss_starter: indicates this sta is ibss starter.
411 * @link_up: link/connection up flag.
412 * @pwr_save: indicate whether dongle to support power save mode.
413 * @dongle_up: indicate whether dongle up or not.
414 * @roam_on: on/off switch for dongle self-roaming.
415 * @scan_tried: indicates if first scan attempted.
416 * @dcmd_buf: dcmd buffer.
417 * @extra_buf: mainly to grab assoc information.
418 * @debugfsdir: debugfs folder for this device.
419 * @escan_on: escan on/off switch.
420 * @escan_info: escan information.
421 * @escan_timeout: Timer for catch scan timeout.
422 * @escan_timeout_work: scan timeout worker.
423 * @escan_ioctl_buf: dongle command buffer for escan commands.
424 * @ap_info: host ap information.
425 * @ci: used to link this structure to netdev private data.
426 */
427struct brcmf_cfg80211_info {
428 struct wireless_dev *wdev;
429 struct brcmf_cfg80211_conf *conf;
430 struct cfg80211_scan_request *scan_request;
431 struct brcmf_cfg80211_event_loop el;
432 struct list_head evt_q_list;
433 spinlock_t evt_q_lock;
434 struct mutex usr_sync;
435 struct brcmf_scan_results *bss_list;
290 struct brcmf_scan_results *scan_results; 436 struct brcmf_scan_results *scan_results;
291 struct brcmf_cfg80211_scan_req *scan_req_int; /* scan request object 437 struct brcmf_cfg80211_scan_req *scan_req_int;
292 for internal purpose */ 438 struct wl_cfg80211_bss_info *bss_info;
293 struct wl_cfg80211_bss_info *bss_info; /* bss information for 439 struct brcmf_cfg80211_ie ie;
294 cfg80211 layer */ 440 struct brcmf_cfg80211_profile *profile;
295 struct brcmf_cfg80211_ie ie; /* information element object for 441 struct brcmf_cfg80211_iscan_ctrl *iscan;
296 internal purpose */ 442 struct brcmf_cfg80211_connect_info conn_info;
297 struct brcmf_cfg80211_profile *profile; /* holding dongle profile */ 443 struct brcmf_cfg80211_pmk_list *pmk_list;
298 struct brcmf_cfg80211_iscan_ctrl *iscan; /* iscan controller */ 444 struct work_struct event_work;
299 struct brcmf_cfg80211_connect_info conn_info; /* association info */ 445 unsigned long status;
300 struct brcmf_cfg80211_pmk_list *pmk_list; /* wpa2 pmk list */ 446 struct brcmf_pub *pub;
301 struct work_struct event_work; /* event handler work struct */ 447 u32 channel;
302 unsigned long status; /* current dongle status */ 448 bool iscan_on;
303 void *pub; 449 bool iscan_kickstart;
304 u32 channel; /* current channel */ 450 bool active_scan;
305 bool iscan_on; /* iscan on/off switch */ 451 bool sched_escan;
306 bool iscan_kickstart; /* indicate iscan already started */ 452 bool ibss_starter;
307 bool active_scan; /* current scan mode */ 453 bool link_up;
308 bool ibss_starter; /* indicates this sta is ibss starter */ 454 bool pwr_save;
309 bool link_up; /* link/connection up flag */ 455 bool dongle_up;
310 bool pwr_save; /* indicate whether dongle to support 456 bool roam_on;
311 power save mode */ 457 bool scan_tried;
312 bool dongle_up; /* indicate whether dongle up or not */ 458 u8 *dcmd_buf;
313 bool roam_on; /* on/off switch for dongle self-roaming */ 459 u8 *extra_buf;
314 bool scan_tried; /* indicates if first scan attempted */
315 u8 *dcmd_buf; /* dcmd buffer */
316 u8 *extra_buf; /* maily to grab assoc information */
317 struct dentry *debugfsdir; 460 struct dentry *debugfsdir;
318 u8 ci[0] __aligned(NETDEV_ALIGN); 461 bool escan_on;
462 struct escan_info escan_info;
463 struct timer_list escan_timeout;
464 struct work_struct escan_timeout_work;
465 u8 *escan_ioctl_buf;
466 struct ap_info *ap_info;
319}; 467};
320 468
321static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_priv *w) 469static inline struct wiphy *cfg_to_wiphy(struct brcmf_cfg80211_info *w)
322{ 470{
323 return w->wdev->wiphy; 471 return w->wdev->wiphy;
324} 472}
325 473
326static inline struct brcmf_cfg80211_priv *wiphy_to_cfg(struct wiphy *w) 474static inline struct brcmf_cfg80211_info *wiphy_to_cfg(struct wiphy *w)
327{ 475{
328 return (struct brcmf_cfg80211_priv *)(wiphy_priv(w)); 476 return (struct brcmf_cfg80211_info *)(wiphy_priv(w));
329} 477}
330 478
331static inline struct brcmf_cfg80211_priv *wdev_to_cfg(struct wireless_dev *wd) 479static inline struct brcmf_cfg80211_info *wdev_to_cfg(struct wireless_dev *wd)
332{ 480{
333 return (struct brcmf_cfg80211_priv *)(wdev_priv(wd)); 481 return (struct brcmf_cfg80211_info *)(wdev_priv(wd));
334} 482}
335 483
336static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_priv *cfg) 484static inline struct net_device *cfg_to_ndev(struct brcmf_cfg80211_info *cfg)
337{ 485{
338 return cfg->wdev->netdev; 486 return cfg->wdev->netdev;
339} 487}
340 488
341static inline struct brcmf_cfg80211_priv *ndev_to_cfg(struct net_device *ndev) 489static inline struct brcmf_cfg80211_info *ndev_to_cfg(struct net_device *ndev)
342{ 490{
343 return wdev_to_cfg(ndev->ieee80211_ptr); 491 return wdev_to_cfg(ndev->ieee80211_ptr);
344} 492}
345 493
346#define iscan_to_cfg(i) ((struct brcmf_cfg80211_priv *)(i->data)) 494#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data))
347#define cfg_to_iscan(w) (w->iscan) 495#define cfg_to_iscan(w) (w->iscan)
348 496
349static inline struct 497static inline struct
350brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_priv *cfg) 498brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
351{ 499{
352 return &cfg->conn_info; 500 return &cfg->conn_info;
353} 501}
354 502
355extern struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev, 503struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
356 struct device *busdev, 504 struct device *busdev,
357 void *data); 505 struct brcmf_pub *drvr);
358extern void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg); 506void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
359 507
360/* event handler from dongle */ 508/* event handler from dongle */
361extern void brcmf_cfg80211_event(struct net_device *ndev, 509void brcmf_cfg80211_event(struct net_device *ndev,
362 const struct brcmf_event_msg *e, void *data); 510 const struct brcmf_event_msg *e, void *data);
363extern s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev); 511s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
364extern s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev); 512s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);
365 513
366#endif /* _wl_cfg80211_h_ */ 514#endif /* _wl_cfg80211_h_ */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
index 8c9345dd37d2..b89f1272b93f 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c
@@ -535,9 +535,6 @@ void ai_detach(struct si_pub *sih)
535{ 535{
536 struct si_info *sii; 536 struct si_info *sii;
537 537
538 struct si_pub *si_local = NULL;
539 memcpy(&si_local, &sih, sizeof(struct si_pub **));
540
541 sii = container_of(sih, struct si_info, pub); 538 sii = container_of(sih, struct si_info, pub);
542 539
543 if (sii == NULL) 540 if (sii == NULL)
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index a5edebeb0b4f..a744ea5a9559 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -86,7 +86,9 @@ MODULE_AUTHOR("Broadcom Corporation");
86MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); 86MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
87MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); 87MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
88MODULE_LICENSE("Dual BSD/GPL"); 88MODULE_LICENSE("Dual BSD/GPL");
89 89/* This needs to be adjusted when brcms_firmwares changes */
90MODULE_FIRMWARE("brcm/bcm43xx-0.fw");
91MODULE_FIRMWARE("brcm/bcm43xx_hdr-0.fw");
90 92
91/* recognized BCMA Core IDs */ 93/* recognized BCMA Core IDs */
92static struct bcma_device_id brcms_coreid_table[] = { 94static struct bcma_device_id brcms_coreid_table[] = {
@@ -265,7 +267,9 @@ static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
265 } 267 }
266} 268}
267 269
268static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 270static void brcms_ops_tx(struct ieee80211_hw *hw,
271 struct ieee80211_tx_control *control,
272 struct sk_buff *skb)
269{ 273{
270 struct brcms_info *wl = hw->priv; 274 struct brcms_info *wl = hw->priv;
271 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 275 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
@@ -277,7 +281,7 @@ static void brcms_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
277 goto done; 281 goto done;
278 } 282 }
279 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw); 283 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
280 tx_info->rate_driver_data[0] = tx_info->control.sta; 284 tx_info->rate_driver_data[0] = control->sta;
281 done: 285 done:
282 spin_unlock_bh(&wl->lock); 286 spin_unlock_bh(&wl->lock);
283} 287}
@@ -300,7 +304,10 @@ static int brcms_ops_start(struct ieee80211_hw *hw)
300 wl->mute_tx = true; 304 wl->mute_tx = true;
301 305
302 if (!wl->pub->up) 306 if (!wl->pub->up)
303 err = brcms_up(wl); 307 if (!blocked)
308 err = brcms_up(wl);
309 else
310 err = -ERFKILL;
304 else 311 else
305 err = -ENODEV; 312 err = -ENODEV;
306 spin_unlock_bh(&wl->lock); 313 spin_unlock_bh(&wl->lock);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 03ca65324845..75086b37c817 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -7512,15 +7512,10 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
7512 7512
7513 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan); 7513 channel = BRCMS_CHAN_CHANNEL(rxh->RxChan);
7514 7514
7515 if (channel > 14) { 7515 rx_status->band =
7516 rx_status->band = IEEE80211_BAND_5GHZ; 7516 channel > 14 ? IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ;
7517 rx_status->freq = ieee80211_ofdm_chan_to_freq( 7517 rx_status->freq =
7518 WF_CHAN_FACTOR_5_G/2, channel); 7518 ieee80211_channel_to_frequency(channel, rx_status->band);
7519
7520 } else {
7521 rx_status->band = IEEE80211_BAND_2GHZ;
7522 rx_status->freq = ieee80211_dsss_chan_to_freq(channel);
7523 }
7524 7519
7525 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh); 7520 rx_status->signal = wlc_phy_rssi_compute(wlc->hw->band->pi, rxh);
7526 7521
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index bcc79b4e3267..e8682855b73a 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -34,6 +34,7 @@
34#define BCM43235_CHIP_ID 43235 34#define BCM43235_CHIP_ID 43235
35#define BCM43236_CHIP_ID 43236 35#define BCM43236_CHIP_ID 43236
36#define BCM43238_CHIP_ID 43238 36#define BCM43238_CHIP_ID 43238
37#define BCM43241_CHIP_ID 0x4324
37#define BCM4329_CHIP_ID 0x4329 38#define BCM4329_CHIP_ID 0x4329
38#define BCM4330_CHIP_ID 0x4330 39#define BCM4330_CHIP_ID 0x4330
39#define BCM4331_CHIP_ID 0x4331 40#define BCM4331_CHIP_ID 0x4331
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index f10d30274c23..c11a290a1edf 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -67,11 +67,6 @@
67#define WL_CHANSPEC_BAND_2G 0x2000 67#define WL_CHANSPEC_BAND_2G 0x2000
68#define INVCHANSPEC 255 68#define INVCHANSPEC 255
69 69
70/* used to calculate the chan_freq = chan_factor * 500Mhz + 5 * chan_number */
71#define WF_CHAN_FACTOR_2_4_G 4814 /* 2.4 GHz band, 2407 MHz */
72#define WF_CHAN_FACTOR_5_G 10000 /* 5 GHz band, 5000 MHz */
73#define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */
74
75#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) 70#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK))
76#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) 71#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK)
77 72