aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211
diff options
context:
space:
mode:
authorFranky Lin <frankyl@broadcom.com>2013-04-11 07:28:47 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-04-12 14:27:53 -0400
commitba540b01a9837ea106a7ca614a23eb4ac194da9c (patch)
treedfa172f1fa9f9514b37fe27900c7d51208c84230 /drivers/net/wireless/brcm80211
parent4a3da9906bbf37f6b0d44ddb753d3198e73c3c6d (diff)
brcmfmac: aggregate dongle ram access interface
For fullmac chips host driver can access to dongle RAM through SDIO function 1. Introduce brcmf_sdio_ramrw and place it at bcmsdh.c with other interface functions. Reviewed-by: Arend van Spriel <arend@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Franky Lin <frankyl@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/brcm80211')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c88
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c120
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h2
3 files changed, 96 insertions, 114 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index f3149debede0..aa51f370be49 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -457,36 +457,80 @@ done:
457 return err; 457 return err;
458} 458}
459 459
460int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, 460int
461 u8 *buf, uint nbytes) 461brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write, u32 address,
462 u8 *data, uint size)
462{ 463{
463 struct sk_buff *mypkt; 464 int bcmerror = 0;
464 bool write = rw ? SDIOH_WRITE : SDIOH_READ; 465 struct sk_buff *pkt;
465 int err; 466 u32 sdaddr;
467 uint dsize;
468
469 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
470 pkt = dev_alloc_skb(dsize);
471 if (!pkt) {
472 brcmf_err("dev_alloc_skb failed: len %d\n", dsize);
473 return -EIO;
474 }
475 pkt->priority = 0;
466 476
467 addr &= SBSDIO_SB_OFT_ADDR_MASK; 477 /* Determine initial transfer parameters */
468 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 478 sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
479 if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
480 dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
481 else
482 dsize = size;
469 483
470 mypkt = brcmu_pkt_buf_get_skb(nbytes); 484 sdio_claim_host(sdiodev->func[1]);
471 if (!mypkt) { 485
472 brcmf_err("brcmu_pkt_buf_get_skb failed: len %d\n", 486 /* Do the transfer(s) */
473 nbytes); 487 while (size) {
474 return -EIO; 488 /* Set the backplane window to include the start address */
489 bcmerror = brcmf_sdcard_set_sbaddr_window(sdiodev, address);
490 if (bcmerror)
491 break;
492
493 brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
494 write ? "write" : "read", dsize,
495 sdaddr, address & SBSDIO_SBWINDOW_MASK);
496
497 sdaddr &= SBSDIO_SB_OFT_ADDR_MASK;
498 sdaddr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
499
500 skb_put(pkt, dsize);
501 if (write)
502 memcpy(pkt->data, data, dsize);
503 bcmerror = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC,
504 write, SDIO_FUNC_1,
505 sdaddr, pkt);
506 if (bcmerror) {
507 brcmf_err("membytes transfer failed\n");
508 break;
509 }
510 if (!write)
511 memcpy(data, pkt->data, dsize);
512 skb_trim(pkt, dsize);
513
514 /* Adjust for next transfer (if any) */
515 size -= dsize;
516 if (size) {
517 data += dsize;
518 address += dsize;
519 sdaddr = 0;
520 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
521 }
475 } 522 }
476 523
477 /* For a write, copy the buffer data into the packet. */ 524 dev_kfree_skb(pkt);
478 if (write)
479 memcpy(mypkt->data, buf, nbytes);
480 525
481 err = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_INC, write, 526 /* Return the window to backplane enumeration space for core access */
482 SDIO_FUNC_1, addr, mypkt); 527 if (brcmf_sdcard_set_sbaddr_window(sdiodev, sdiodev->sbwad))
528 brcmf_err("FAILED to set window back to 0x%x\n",
529 sdiodev->sbwad);
483 530
484 /* For a read, copy the packet data back to the buffer. */ 531 sdio_release_host(sdiodev->func[1]);
485 if (!err && !write)
486 memcpy(buf, mypkt->data, nbytes);
487 532
488 brcmu_pkt_buf_free_skb(mypkt); 533 return bcmerror;
489 return err;
490} 534}
491 535
492int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) 536int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index fb4ff910c8a4..26e34b69a5a3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2486,69 +2486,6 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
2486 return ret; 2486 return ret;
2487} 2487}
2488 2488
2489static int
2490brcmf_sdbrcm_membytes(struct brcmf_sdio *bus, bool write, u32 address, u8 *data,
2491 uint size)
2492{
2493 int bcmerror = 0;
2494 u32 sdaddr;
2495 uint dsize;
2496
2497 /* Determine initial transfer parameters */
2498 sdaddr = address & SBSDIO_SB_OFT_ADDR_MASK;
2499 if ((sdaddr + size) & SBSDIO_SBWINDOW_MASK)
2500 dsize = (SBSDIO_SB_OFT_ADDR_LIMIT - sdaddr);
2501 else
2502 dsize = size;
2503
2504 sdio_claim_host(bus->sdiodev->func[1]);
2505
2506 /* Set the backplane window to include the start address */
2507 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev, address);
2508 if (bcmerror) {
2509 brcmf_err("window change failed\n");
2510 goto xfer_done;
2511 }
2512
2513 /* Do the transfer(s) */
2514 while (size) {
2515 brcmf_dbg(SDIO, "%s %d bytes at offset 0x%08x in window 0x%08x\n",
2516 write ? "write" : "read", dsize,
2517 sdaddr, address & SBSDIO_SBWINDOW_MASK);
2518 bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write,
2519 sdaddr, data, dsize);
2520 if (bcmerror) {
2521 brcmf_err("membytes transfer failed\n");
2522 break;
2523 }
2524
2525 /* Adjust for next transfer (if any) */
2526 size -= dsize;
2527 if (size) {
2528 data += dsize;
2529 address += dsize;
2530 bcmerror = brcmf_sdcard_set_sbaddr_window(bus->sdiodev,
2531 address);
2532 if (bcmerror) {
2533 brcmf_err("window change failed\n");
2534 break;
2535 }
2536 sdaddr = 0;
2537 dsize = min_t(uint, SBSDIO_SB_OFT_ADDR_LIMIT, size);
2538 }
2539 }
2540
2541xfer_done:
2542 /* Return the window to backplane enumeration space for core access */
2543 if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, bus->sdiodev->sbwad))
2544 brcmf_err("FAILED to set window back to 0x%x\n",
2545 bus->sdiodev->sbwad);
2546
2547 sdio_release_host(bus->sdiodev->func[1]);
2548
2549 return bcmerror;
2550}
2551
2552#ifdef DEBUG 2489#ifdef DEBUG
2553#define CONSOLE_LINE_MAX 192 2490#define CONSOLE_LINE_MAX 192
2554 2491
@@ -2565,8 +2502,8 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
2565 2502
2566 /* Read console log struct */ 2503 /* Read console log struct */
2567 addr = bus->console_addr + offsetof(struct rte_console, log_le); 2504 addr = bus->console_addr + offsetof(struct rte_console, log_le);
2568 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&c->log_le, 2505 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&c->log_le,
2569 sizeof(c->log_le)); 2506 sizeof(c->log_le));
2570 if (rv < 0) 2507 if (rv < 0)
2571 return rv; 2508 return rv;
2572 2509
@@ -2591,7 +2528,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus)
2591 2528
2592 /* Read the console buffer */ 2529 /* Read the console buffer */
2593 addr = le32_to_cpu(c->log_le.buf); 2530 addr = le32_to_cpu(c->log_le.buf);
2594 rv = brcmf_sdbrcm_membytes(bus, false, addr, c->buf, c->bufsize); 2531 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, c->buf, c->bufsize);
2595 if (rv < 0) 2532 if (rv < 0)
2596 return rv; 2533 return rv;
2597 2534
@@ -2812,8 +2749,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2812 */ 2749 */
2813 sdio_claim_host(bus->sdiodev->func[1]); 2750 sdio_claim_host(bus->sdiodev->func[1]);
2814 brcmf_sdbrcm_bus_sleep(bus, false, false); 2751 brcmf_sdbrcm_bus_sleep(bus, false, false);
2815 rv = brcmf_sdbrcm_membytes(bus, false, shaddr, 2752 rv = brcmf_sdio_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
2816 (u8 *)&addr_le, 4);
2817 sdio_release_host(bus->sdiodev->func[1]); 2753 sdio_release_host(bus->sdiodev->func[1]);
2818 if (rv < 0) 2754 if (rv < 0)
2819 return rv; 2755 return rv;
@@ -2833,8 +2769,8 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
2833 } 2769 }
2834 2770
2835 /* Read hndrte_shared structure */ 2771 /* Read hndrte_shared structure */
2836 rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le, 2772 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
2837 sizeof(struct sdpcm_shared_le)); 2773 sizeof(struct sdpcm_shared_le));
2838 if (rv < 0) 2774 if (rv < 0)
2839 return rv; 2775 return rv;
2840 2776
@@ -2870,22 +2806,22 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2870 2806
2871 /* obtain console information from device memory */ 2807 /* obtain console information from device memory */
2872 addr = sh->console_addr + offsetof(struct rte_console, log_le); 2808 addr = sh->console_addr + offsetof(struct rte_console, log_le);
2873 rv = brcmf_sdbrcm_membytes(bus, false, addr, 2809 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
2874 (u8 *)&sh_val, sizeof(u32)); 2810 (u8 *)&sh_val, sizeof(u32));
2875 if (rv < 0) 2811 if (rv < 0)
2876 return rv; 2812 return rv;
2877 console_ptr = le32_to_cpu(sh_val); 2813 console_ptr = le32_to_cpu(sh_val);
2878 2814
2879 addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size); 2815 addr = sh->console_addr + offsetof(struct rte_console, log_le.buf_size);
2880 rv = brcmf_sdbrcm_membytes(bus, false, addr, 2816 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
2881 (u8 *)&sh_val, sizeof(u32)); 2817 (u8 *)&sh_val, sizeof(u32));
2882 if (rv < 0) 2818 if (rv < 0)
2883 return rv; 2819 return rv;
2884 console_size = le32_to_cpu(sh_val); 2820 console_size = le32_to_cpu(sh_val);
2885 2821
2886 addr = sh->console_addr + offsetof(struct rte_console, log_le.idx); 2822 addr = sh->console_addr + offsetof(struct rte_console, log_le.idx);
2887 rv = brcmf_sdbrcm_membytes(bus, false, addr, 2823 rv = brcmf_sdio_ramrw(bus->sdiodev, false, addr,
2888 (u8 *)&sh_val, sizeof(u32)); 2824 (u8 *)&sh_val, sizeof(u32));
2889 if (rv < 0) 2825 if (rv < 0)
2890 return rv; 2826 return rv;
2891 console_index = le32_to_cpu(sh_val); 2827 console_index = le32_to_cpu(sh_val);
@@ -2899,8 +2835,8 @@ static int brcmf_sdio_dump_console(struct brcmf_sdio *bus,
2899 2835
2900 /* obtain the console data from device */ 2836 /* obtain the console data from device */
2901 conbuf[console_size] = '\0'; 2837 conbuf[console_size] = '\0';
2902 rv = brcmf_sdbrcm_membytes(bus, false, console_ptr, (u8 *)conbuf, 2838 rv = brcmf_sdio_ramrw(bus->sdiodev, false, console_ptr, (u8 *)conbuf,
2903 console_size); 2839 console_size);
2904 if (rv < 0) 2840 if (rv < 0)
2905 goto done; 2841 goto done;
2906 2842
@@ -2937,8 +2873,8 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
2937 return 0; 2873 return 0;
2938 } 2874 }
2939 2875
2940 error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr, 2876 error = brcmf_sdio_ramrw(bus->sdiodev, false, sh->trap_addr, (u8 *)&tr,
2941 sizeof(struct brcmf_trap_info)); 2877 sizeof(struct brcmf_trap_info));
2942 if (error < 0) 2878 if (error < 0)
2943 return error; 2879 return error;
2944 2880
@@ -2981,14 +2917,14 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
2981 2917
2982 sdio_claim_host(bus->sdiodev->func[1]); 2918 sdio_claim_host(bus->sdiodev->func[1]);
2983 if (sh->assert_file_addr != 0) { 2919 if (sh->assert_file_addr != 0) {
2984 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr, 2920 error = brcmf_sdio_ramrw(bus->sdiodev, false,
2985 (u8 *)file, 80); 2921 sh->assert_file_addr, (u8 *)file, 80);
2986 if (error < 0) 2922 if (error < 0)
2987 return error; 2923 return error;
2988 } 2924 }
2989 if (sh->assert_exp_addr != 0) { 2925 if (sh->assert_exp_addr != 0) {
2990 error = brcmf_sdbrcm_membytes(bus, false, sh->assert_exp_addr, 2926 error = brcmf_sdio_ramrw(bus->sdiodev, false,
2991 (u8 *)expr, 80); 2927 sh->assert_exp_addr, (u8 *)expr, 80);
2992 if (error < 0) 2928 if (error < 0)
2993 return error; 2929 return error;
2994 } 2930 }
@@ -3162,8 +3098,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
3162 3098
3163 if (bus->vars) { 3099 if (bus->vars) {
3164 /* Write the vars list */ 3100 /* Write the vars list */
3165 bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, 3101 bcmerror = brcmf_sdio_ramrw(bus->sdiodev, true, varaddr,
3166 bus->vars, bus->varsz); 3102 bus->vars, bus->varsz);
3167#ifdef DEBUG 3103#ifdef DEBUG
3168 /* Verify NVRAM bytes */ 3104 /* Verify NVRAM bytes */
3169 brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", 3105 brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n",
@@ -3176,8 +3112,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
3176 memset(nvram_ularray, 0xaa, bus->varsz); 3112 memset(nvram_ularray, 0xaa, bus->varsz);
3177 3113
3178 /* Read the vars list to temp buffer for comparison */ 3114 /* Read the vars list to temp buffer for comparison */
3179 bcmerror = brcmf_sdbrcm_membytes(bus, false, varaddr, 3115 bcmerror = brcmf_sdio_ramrw(bus->sdiodev, false, varaddr,
3180 nvram_ularray, bus->varsz); 3116 nvram_ularray, bus->varsz);
3181 if (bcmerror) { 3117 if (bcmerror) {
3182 brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n", 3118 brcmf_err("error %d on reading %d nvram bytes at 0x%08x\n",
3183 bcmerror, bus->varsz, varaddr); 3119 bcmerror, bus->varsz, varaddr);
@@ -3215,8 +3151,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus)
3215 bus->varsz, varsizew); 3151 bus->varsz, varsizew);
3216 3152
3217 /* Write the length token to the last word */ 3153 /* Write the length token to the last word */
3218 bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->ramsize - 4), 3154 bcmerror = brcmf_sdio_ramrw(bus->sdiodev, true, (bus->ramsize - 4),
3219 (u8 *)&varsizew_le, 4); 3155 (u8 *)&varsizew_le, 4);
3220 3156
3221 return bcmerror; 3157 return bcmerror;
3222} 3158}
@@ -3239,7 +3175,7 @@ static int brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
3239 /* Clear the top bit of memory */ 3175 /* Clear the top bit of memory */
3240 if (bus->ramsize) { 3176 if (bus->ramsize) {
3241 u32 zeros = 0; 3177 u32 zeros = 0;
3242 brcmf_sdbrcm_membytes(bus, true, bus->ramsize - 4, 3178 brcmf_sdio_ramrw(bus->sdiodev, true, bus->ramsize - 4,
3243 (u8 *)&zeros, 4); 3179 (u8 *)&zeros, 4);
3244 } 3180 }
3245 } else { 3181 } else {
@@ -3308,7 +3244,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
3308 /* Download image */ 3244 /* Download image */
3309 while ((len = 3245 while ((len =
3310 brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { 3246 brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) {
3311 ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len); 3247 ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len);
3312 if (ret) { 3248 if (ret) {
3313 brcmf_err("error %d on writing %d membytes at 0x%08x\n", 3249 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3314 ret, MEMBLOCK, offset); 3250 ret, MEMBLOCK, offset);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 4e681ae9eb81..b9b397b59965 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -242,6 +242,8 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
242 */ 242 */
243extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, 243extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw,
244 u32 addr, u8 *buf, uint nbytes); 244 u32 addr, u8 *buf, uint nbytes);
245extern int brcmf_sdio_ramrw(struct brcmf_sdio_dev *sdiodev, bool write,
246 u32 address, u8 *data, uint size);
245 247
246/* Issue an abort to the specified function */ 248/* Issue an abort to the specified function */
247extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); 249extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);