return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
 }
 
+static char *brcm_alt_fw_path(const char *path, const char *board_type)
+{
+       char alt_path[BRCMF_FW_NAME_LEN];
+       char suffix[5];
+
+       strscpy(alt_path, path, BRCMF_FW_NAME_LEN);
+       /* At least one character + suffix */
+       if (strlen(alt_path) < 5)
+               return NULL;
+
+       /* strip .txt or .bin at the end */
+       strscpy(suffix, alt_path + strlen(alt_path) - 4, 5);
+       alt_path[strlen(alt_path) - 4] = 0;
+       strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
+       strlcat(alt_path, board_type, BRCMF_FW_NAME_LEN);
+       strlcat(alt_path, suffix, BRCMF_FW_NAME_LEN);
+
+       return kstrdup(alt_path, GFP_KERNEL);
+}
+
 static int brcmf_fw_request_firmware(const struct firmware **fw,
                                     struct brcmf_fw *fwctx)
 {
        struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
        int ret;
 
-       /* nvram files are board-specific, first try a board-specific path */
+       /* Files can be board-specific, first try a board-specific path */
        if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
-               char alt_path[BRCMF_FW_NAME_LEN];
+               char *alt_path;
 
-               strlcpy(alt_path, cur->path, BRCMF_FW_NAME_LEN);
-               /* strip .txt at the end */
-               alt_path[strlen(alt_path) - 4] = 0;
-               strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
-               strlcat(alt_path, fwctx->req->board_type, BRCMF_FW_NAME_LEN);
-               strlcat(alt_path, ".txt", BRCMF_FW_NAME_LEN);
+               alt_path = brcm_alt_fw_path(cur->path, fwctx->req->board_type);
+               if (!alt_path)
+                       goto fallback;
 
                ret = request_firmware(fw, alt_path, fwctx->dev);
+               kfree(alt_path);
                if (ret == 0)
                        return ret;
        }
 
+fallback:
        return request_firmware(fw, cur->path, fwctx->dev);
 }
 
 {
        struct brcmf_fw_item *first = &req->items[0];
        struct brcmf_fw *fwctx;
+       char *alt_path;
        int ret;
 
        brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
        fwctx->req = req;
        fwctx->done = fw_cb;
 
-       ret = request_firmware_nowait(THIS_MODULE, true, first->path,
-                                     fwctx->dev, GFP_KERNEL, fwctx,
-                                     brcmf_fw_request_done);
+       /* First try alternative board-specific path if any */
+       alt_path = brcm_alt_fw_path(first->path, fwctx->req->board_type);
+       if (alt_path) {
+               ret = request_firmware_nowait(THIS_MODULE, true, alt_path,
+                                             fwctx->dev, GFP_KERNEL, fwctx,
+                                             brcmf_fw_request_done);
+               kfree(alt_path);
+       }
+       /* Else try canonical path */
+       if (ret) {
+               ret = request_firmware_nowait(THIS_MODULE, true, first->path,
+                                             fwctx->dev, GFP_KERNEL, fwctx,
+                                             brcmf_fw_request_done);
+       }
        if (ret < 0)
                brcmf_fw_request_done(NULL, fwctx);