Commit 7249e6a1 authored by Roland Vossen's avatar Roland Vossen Committed by Greg Kroah-Hartman

staging: brcm80211: improved checks on incompatible firmware

The return status of wl_ucode_init_buf() is now being used. Also a bug in
firmware validation, which could lead to incompatible firmware not being
rejected by the driver, has been fixed. Comment from Dan Carpenter on using
negative error values has been incorporated in this commit.
Signed-off-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 490e00f6
...@@ -755,7 +755,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, ...@@ -755,7 +755,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
spin_lock_init(&wl->isr_lock); spin_lock_init(&wl->isr_lock);
/* prepare ucode */ /* prepare ucode */
if (wl_request_fw(wl, (struct pci_dev *)btparam)) { if (wl_request_fw(wl, (struct pci_dev *)btparam) < 0) {
WL_ERROR("%s: Failed to find firmware usually in %s\n", WL_ERROR("%s: Failed to find firmware usually in %s\n",
KBUILD_MODNAME, "/lib/firmware/brcm"); KBUILD_MODNAME, "/lib/firmware/brcm");
wl_release_fw(wl); wl_release_fw(wl);
...@@ -1760,7 +1760,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) ...@@ -1760,7 +1760,7 @@ int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx)
WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx); WL_ERROR("ERROR: ucode buf tag:%d can not be found!\n", idx);
*pbuf = NULL; *pbuf = NULL;
fail: fail:
return -1; return BCME_NOTFOUND;
} }
int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
...@@ -1868,8 +1868,8 @@ int wl_check_firmwares(struct wl_info *wl) ...@@ -1868,8 +1868,8 @@ int wl_check_firmwares(struct wl_info *wl)
} else { } else {
/* check if ucode section overruns firmware image */ /* check if ucode section overruns firmware image */
ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data;
for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
entry++, ucode_hdr++) { !rc; entry++, ucode_hdr++) {
if (ucode_hdr->offset + ucode_hdr->len > if (ucode_hdr->offset + ucode_hdr->len >
fw->size) { fw->size) {
WL_ERROR("%s: conflicting bin/hdr\n", WL_ERROR("%s: conflicting bin/hdr\n",
......
...@@ -41,32 +41,38 @@ int wl_ucode_data_init(struct wl_info *wl) ...@@ -41,32 +41,38 @@ int wl_ucode_data_init(struct wl_info *wl)
{ {
int rc; int rc;
rc = wl_check_firmwares(wl); rc = wl_check_firmwares(wl);
if (rc < 0)
return rc;
wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
D11LCN0BSINITVALS24);
wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24);
wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
D11LCN1BSINITVALS24);
wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24, D11LCN1INITVALS24);
wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
D11LCN2BSINITVALS24);
wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24, D11LCN2INITVALS24);
wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16, D11N0ABSINITVALS16);
wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16, D11N0BSINITVALS16);
wl_ucode_init_buf(wl, (void **)&d11n0initvals16, D11N0INITVALS16);
wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
D11UCODE_OVERSIGHT16_MIMO);
wl_ucode_init_uint(wl, &bcm43xx_16_mimosz, D11UCODE_OVERSIGHT16_MIMOSZ);
wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
D11UCODE_OVERSIGHT24_LCN);
wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz, D11UCODE_OVERSIGHT24_LCNSZ);
wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
D11UCODE_OVERSIGHT_BOMMAJOR);
wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
D11UCODE_OVERSIGHT_BOMMINOR);
return 0; rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24,
D11LCN0BSINITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24,
D11LCN0INITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1bsinitvals24,
D11LCN1BSINITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn1initvals24,
D11LCN1INITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2bsinitvals24,
D11LCN2BSINITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11lcn2initvals24,
D11LCN2INITVALS24);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0absinitvals16,
D11N0ABSINITVALS16);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0bsinitvals16,
D11N0BSINITVALS16);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&d11n0initvals16,
D11N0INITVALS16);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_16_mimo,
D11UCODE_OVERSIGHT16_MIMO);
rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_16_mimosz,
D11UCODE_OVERSIGHT16_MIMOSZ);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_24_lcn,
D11UCODE_OVERSIGHT24_LCN);
rc = rc < 0 ? rc : wl_ucode_init_uint(wl, &bcm43xx_24_lcnsz,
D11UCODE_OVERSIGHT24_LCNSZ);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bommajor,
D11UCODE_OVERSIGHT_BOMMAJOR);
rc = rc < 0 ? rc : wl_ucode_init_buf(wl, (void **)&bcm43xx_bomminor,
D11UCODE_OVERSIGHT_BOMMINOR);
return rc;
} }
void wl_ucode_data_free(void) void wl_ucode_data_free(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment