aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2013-09-25 07:05:45 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-10-03 16:24:25 -0400
commitf2c44fe7c83eeee6ca8828d9b3d0b4c205a7bc1b (patch)
tree2794f8597d7ab10487764de62325eca7d6d1c9ba
parent5af47fb394b54c4e8ff9035d1aa590e3c7b611dd (diff)
brcmfmac: Use fw filename and nvram based of devid for sdio.
SDIO firmware download routines uses one name for firmware file and nvram file for all sdio devices. This is not user friendly. Use fw filename and nvram filename based upon chip id and revision. Reported-by: Stephen Warren <swarren@wwwdotorg.org> Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c207
1 files changed, 133 insertions, 74 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index f9ba4d0970d1..6e72b7378f95 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -275,11 +275,6 @@ struct rte_console {
275/* Flags for SDH calls */ 275/* Flags for SDH calls */
276#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED) 276#define F2SYNC (SDIO_REQ_4BYTE | SDIO_REQ_FIXED)
277 277
278#define BRCMF_SDIO_FW_NAME "brcm/brcmfmac-sdio.bin"
279#define BRCMF_SDIO_NV_NAME "brcm/brcmfmac-sdio.txt"
280MODULE_FIRMWARE(BRCMF_SDIO_FW_NAME);
281MODULE_FIRMWARE(BRCMF_SDIO_NV_NAME);
282
283#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */ 278#define BRCMF_IDLE_IMMEDIATE (-1) /* Enter idle immediately */
284#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change 279#define BRCMF_IDLE_ACTIVE 0 /* Do not request any SD clock change
285 * when idle 280 * when idle
@@ -454,9 +449,6 @@ struct brcmf_sdio {
454 struct work_struct datawork; 449 struct work_struct datawork;
455 atomic_t dpc_tskcnt; 450 atomic_t dpc_tskcnt;
456 451
457 const struct firmware *firmware;
458 u32 fw_ptr;
459
460 bool txoff; /* Transmit flow-controlled */ 452 bool txoff; /* Transmit flow-controlled */
461 struct brcmf_sdio_count sdcnt; 453 struct brcmf_sdio_count sdcnt;
462 bool sr_enabled; /* SaveRestore enabled */ 454 bool sr_enabled; /* SaveRestore enabled */
@@ -493,6 +485,100 @@ enum brcmf_sdio_frmtype {
493 BRCMF_SDIO_FT_SUB, 485 BRCMF_SDIO_FT_SUB,
494}; 486};
495 487
488#define BCM43143_FIRMWARE_NAME "brcm/brcmfmac43143-sdio.bin"
489#define BCM43143_NVRAM_NAME "brcm/brcmfmac43143-sdio.txt"
490#define BCM43241B0_FIRMWARE_NAME "brcm/brcmfmac43241b0-sdio.bin"
491#define BCM43241B0_NVRAM_NAME "brcm/brcmfmac43241b0-sdio.txt"
492#define BCM43241B4_FIRMWARE_NAME "brcm/brcmfmac43241b4-sdio.bin"
493#define BCM43241B4_NVRAM_NAME "brcm/brcmfmac43241b4-sdio.txt"
494#define BCM4329_FIRMWARE_NAME "brcm/brcmfmac4329-sdio.bin"
495#define BCM4329_NVRAM_NAME "brcm/brcmfmac4329-sdio.txt"
496#define BCM4330_FIRMWARE_NAME "brcm/brcmfmac4330-sdio.bin"
497#define BCM4330_NVRAM_NAME "brcm/brcmfmac4330-sdio.txt"
498#define BCM4334_FIRMWARE_NAME "brcm/brcmfmac4334-sdio.bin"
499#define BCM4334_NVRAM_NAME "brcm/brcmfmac4334-sdio.txt"
500#define BCM4335_FIRMWARE_NAME "brcm/brcmfmac4335-sdio.bin"
501#define BCM4335_NVRAM_NAME "brcm/brcmfmac4335-sdio.txt"
502
503MODULE_FIRMWARE(BCM43143_FIRMWARE_NAME);
504MODULE_FIRMWARE(BCM43143_NVRAM_NAME);
505MODULE_FIRMWARE(BCM43241B0_FIRMWARE_NAME);
506MODULE_FIRMWARE(BCM43241B0_NVRAM_NAME);
507MODULE_FIRMWARE(BCM43241B4_FIRMWARE_NAME);
508MODULE_FIRMWARE(BCM43241B4_NVRAM_NAME);
509MODULE_FIRMWARE(BCM4329_FIRMWARE_NAME);
510MODULE_FIRMWARE(BCM4329_NVRAM_NAME);
511MODULE_FIRMWARE(BCM4330_FIRMWARE_NAME);
512MODULE_FIRMWARE(BCM4330_NVRAM_NAME);
513MODULE_FIRMWARE(BCM4334_FIRMWARE_NAME);
514MODULE_FIRMWARE(BCM4334_NVRAM_NAME);
515MODULE_FIRMWARE(BCM4335_FIRMWARE_NAME);
516MODULE_FIRMWARE(BCM4335_NVRAM_NAME);
517
518struct brcmf_firmware_names {
519 u32 chipid;
520 u32 revmsk;
521 const char *bin;
522 const char *nv;
523};
524
525enum brcmf_firmware_type {
526 BRCMF_FIRMWARE_BIN,
527 BRCMF_FIRMWARE_NVRAM
528};
529
530#define BRCMF_FIRMWARE_NVRAM(name) \
531 name ## _FIRMWARE_NAME, name ## _NVRAM_NAME
532
533static const struct brcmf_firmware_names brcmf_fwname_data[] = {
534 { BCM43143_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43143) },
535 { BCM43241_CHIP_ID, 0x0000001F, BRCMF_FIRMWARE_NVRAM(BCM43241B0) },
536 { BCM43241_CHIP_ID, 0xFFFFFFE0, BRCMF_FIRMWARE_NVRAM(BCM43241B4) },
537 { BCM4329_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4329) },
538 { BCM4330_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4330) },
539 { BCM4334_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4334) },
540 { BCM4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }
541};
542
543
544static const struct firmware *brcmf_sdbrcm_get_fw(struct brcmf_sdio *bus,
545 enum brcmf_firmware_type type)
546{
547 const struct firmware *fw;
548 const char *name;
549 int err, i;
550
551 for (i = 0; i < ARRAY_SIZE(brcmf_fwname_data); i++) {
552 if (brcmf_fwname_data[i].chipid == bus->ci->chip &&
553 brcmf_fwname_data[i].revmsk & BIT(bus->ci->chiprev)) {
554 switch (type) {
555 case BRCMF_FIRMWARE_BIN:
556 name = brcmf_fwname_data[i].bin;
557 break;
558 case BRCMF_FIRMWARE_NVRAM:
559 name = brcmf_fwname_data[i].nv;
560 break;
561 default:
562 brcmf_err("invalid firmware type (%d)\n", type);
563 return NULL;
564 }
565 goto found;
566 }
567 }
568 brcmf_err("Unknown chipid %d [%d]\n",
569 bus->ci->chip, bus->ci->chiprev);
570 return NULL;
571
572found:
573 err = request_firmware(&fw, name, &bus->sdiodev->func[2]->dev);
574 if ((err) || (!fw)) {
575 brcmf_err("fail to request firmware %s (%d)\n", name, err);
576 return NULL;
577 }
578
579 return fw;
580}
581
496static void pkt_align(struct sk_buff *p, int len, int align) 582static void pkt_align(struct sk_buff *p, int len, int align)
497{ 583{
498 uint datalign; 584 uint datalign;
@@ -3042,69 +3128,43 @@ static bool brcmf_sdbrcm_download_state(struct brcmf_sdio *bus, bool enter)
3042 return true; 3128 return true;
3043} 3129}
3044 3130
3045static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus)
3046{
3047 if (bus->firmware->size < bus->fw_ptr + len)
3048 len = bus->firmware->size - bus->fw_ptr;
3049
3050 memcpy(buf, &bus->firmware->data[bus->fw_ptr], len);
3051 bus->fw_ptr += len;
3052 return len;
3053}
3054
3055static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) 3131static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus)
3056{ 3132{
3133 const struct firmware *fw;
3134 int err;
3057 int offset; 3135 int offset;
3058 uint len; 3136 int address;
3059 u8 *memblock = NULL, *memptr; 3137 int len;
3060 int ret; 3138
3061 u8 idx; 3139 fw = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_BIN);
3062 3140 if (fw == NULL)
3063 brcmf_dbg(INFO, "Enter\n"); 3141 return -ENOENT;
3064 3142
3065 ret = request_firmware(&bus->firmware, BRCMF_SDIO_FW_NAME, 3143 if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) !=
3066 &bus->sdiodev->func[2]->dev); 3144 BRCMF_MAX_CORENUM)
3067 if (ret) { 3145 memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec));
3068 brcmf_err("Fail to request firmware %d\n", ret); 3146
3069 return ret; 3147 err = 0;
3070 } 3148 offset = 0;
3071 bus->fw_ptr = 0; 3149 address = bus->ci->rambase;
3072 3150 while (offset < fw->size) {
3073 memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC); 3151 len = ((offset + MEMBLOCK) < fw->size) ? MEMBLOCK :
3074 if (memblock == NULL) { 3152 fw->size - offset;
3075 ret = -ENOMEM; 3153 err = brcmf_sdio_ramrw(bus->sdiodev, true, address,
3076 goto err; 3154 (u8 *)&fw->data[offset], len);
3077 } 3155 if (err) {
3078 if ((u32)(unsigned long)memblock % BRCMF_SDALIGN)
3079 memptr += (BRCMF_SDALIGN -
3080 ((u32)(unsigned long)memblock % BRCMF_SDALIGN));
3081
3082 offset = bus->ci->rambase;
3083
3084 /* Download image */
3085 len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus);
3086 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4);
3087 if (BRCMF_MAX_CORENUM != idx)
3088 memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec));
3089 while (len) {
3090 ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len);
3091 if (ret) {
3092 brcmf_err("error %d on writing %d membytes at 0x%08x\n", 3156 brcmf_err("error %d on writing %d membytes at 0x%08x\n",
3093 ret, MEMBLOCK, offset); 3157 err, len, address);
3094 goto err; 3158 goto failure;
3095 } 3159 }
3096 3160 offset += len;
3097 offset += MEMBLOCK; 3161 address += len;
3098 len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus);
3099 } 3162 }
3100 3163
3101err: 3164failure:
3102 kfree(memblock); 3165 release_firmware(fw);
3103
3104 release_firmware(bus->firmware);
3105 bus->fw_ptr = 0;
3106 3166
3107 return ret; 3167 return err;
3108} 3168}
3109 3169
3110/* 3170/*
@@ -3116,7 +3176,8 @@ err:
3116 * by two NULs. 3176 * by two NULs.
3117*/ 3177*/
3118 3178
3119static int brcmf_process_nvram_vars(struct brcmf_sdio *bus) 3179static int brcmf_process_nvram_vars(struct brcmf_sdio *bus,
3180 const struct firmware *nv)
3120{ 3181{
3121 char *varbuf; 3182 char *varbuf;
3122 char *dp; 3183 char *dp;
@@ -3125,12 +3186,12 @@ static int brcmf_process_nvram_vars(struct brcmf_sdio *bus)
3125 int ret = 0; 3186 int ret = 0;
3126 uint buf_len, n, len; 3187 uint buf_len, n, len;
3127 3188
3128 len = bus->firmware->size; 3189 len = nv->size;
3129 varbuf = vmalloc(len); 3190 varbuf = vmalloc(len);
3130 if (!varbuf) 3191 if (!varbuf)
3131 return -ENOMEM; 3192 return -ENOMEM;
3132 3193
3133 memcpy(varbuf, bus->firmware->data, len); 3194 memcpy(varbuf, nv->data, len);
3134 dp = varbuf; 3195 dp = varbuf;
3135 3196
3136 findNewline = false; 3197 findNewline = false;
@@ -3182,18 +3243,16 @@ err:
3182 3243
3183static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus) 3244static int brcmf_sdbrcm_download_nvram(struct brcmf_sdio *bus)
3184{ 3245{
3246 const struct firmware *nv;
3185 int ret; 3247 int ret;
3186 3248
3187 ret = request_firmware(&bus->firmware, BRCMF_SDIO_NV_NAME, 3249 nv = brcmf_sdbrcm_get_fw(bus, BRCMF_FIRMWARE_NVRAM);
3188 &bus->sdiodev->func[2]->dev); 3250 if (nv == NULL)
3189 if (ret) { 3251 return -ENOENT;
3190 brcmf_err("Fail to request nvram %d\n", ret);
3191 return ret;
3192 }
3193 3252
3194 ret = brcmf_process_nvram_vars(bus); 3253 ret = brcmf_process_nvram_vars(bus, nv);
3195 3254
3196 release_firmware(bus->firmware); 3255 release_firmware(nv);
3197 3256
3198 return ret; 3257 return ret;
3199} 3258}