2015-11-05 04:27:36 +00:00
|
|
|
From a50240ffd6743509d23a673bb04710496c660860 Mon Sep 17 00:00:00 2001
|
2015-07-03 02:06:55 +00:00
|
|
|
From: Kevin Mihelich <kevin@archlinuxarm.org>
|
|
|
|
Date: Thu, 2 Jul 2015 17:48:41 -0600
|
2015-08-06 00:00:52 +00:00
|
|
|
Subject: [PATCH 4/4] fix brcmfmac oops and race condition
|
2015-07-03 02:06:55 +00:00
|
|
|
|
|
|
|
This fixes a potential null pointer dereference by checking if null before
|
|
|
|
freeing the vif struct.
|
|
|
|
|
|
|
|
Also works around a race condition between brcm_patchram_plus loading the BT
|
|
|
|
firmware, which exposes the wireless device, and the kernel loading bcrmfmac.
|
|
|
|
100ms delay loops up to 1s are added around the first three initialization
|
|
|
|
functions to hold off a failure until the device is actually ready. This is a
|
|
|
|
hack.
|
|
|
|
|
|
|
|
Signed-off-by: Kevin Mihelich <kevin@archlinuxarm.org>
|
|
|
|
---
|
|
|
|
.../wireless-3.8/brcm80211/brcmfmac/dhd_common.c | 47 ++++++++++++++--------
|
2015-11-05 04:27:36 +00:00
|
|
|
1 file changed, 30 insertions(+), 17 deletions(-)
|
2015-07-03 02:06:55 +00:00
|
|
|
|
|
|
|
diff --git a/drivers/net/wireless-3.8/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless-3.8/brcm80211/brcmfmac/dhd_common.c
|
|
|
|
index 05d4042..7006d19 100644
|
|
|
|
--- a/drivers/net/wireless-3.8/brcm80211/brcmfmac/dhd_common.c
|
|
|
|
+++ b/drivers/net/wireless-3.8/brcm80211/brcmfmac/dhd_common.c
|
|
|
|
@@ -252,25 +252,34 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
|
|
|
struct brcmf_join_pref_params join_pref_params[2];
|
|
|
|
char *ptr;
|
|
|
|
s32 err;
|
|
|
|
+ int i;
|
|
|
|
|
|
|
|
/* retreive mac address */
|
|
|
|
- err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
|
|
|
|
- sizeof(ifp->mac_addr));
|
|
|
|
- if (err < 0) {
|
|
|
|
- brcmf_err("Retreiving cur_etheraddr failed, %d\n",
|
|
|
|
- err);
|
|
|
|
- goto done;
|
|
|
|
+ for (i = 0; i < 9; i++) {
|
|
|
|
+ err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
|
|
|
|
+ sizeof(ifp->mac_addr));
|
|
|
|
+ if (err < 0 && i == 9) {
|
|
|
|
+ brcmf_err("Retreiving cur_etheraddr failed, %d\n",
|
|
|
|
+ err);
|
|
|
|
+ goto done;
|
|
|
|
+ } else {
|
|
|
|
+ msleep(100);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
memcpy(ifp->drvr->mac, ifp->mac_addr, sizeof(ifp->drvr->mac));
|
|
|
|
|
|
|
|
/* query for 'ver' to get version info from firmware */
|
|
|
|
- memset(buf, 0, sizeof(buf));
|
|
|
|
- strcpy(buf, "ver");
|
|
|
|
- err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
|
|
|
|
- if (err < 0) {
|
|
|
|
- brcmf_err("Retreiving version information failed, %d\n",
|
|
|
|
- err);
|
|
|
|
- goto done;
|
|
|
|
+ for (i = 0; i < 10; i++) {
|
|
|
|
+ memset(buf, 0, sizeof(buf));
|
|
|
|
+ strcpy(buf, "ver");
|
|
|
|
+ err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
|
|
|
|
+ if (err < 0 && i == 9) {
|
|
|
|
+ brcmf_err("Retreiving version information failed, %d\n",
|
|
|
|
+ err);
|
|
|
|
+ goto done;
|
|
|
|
+ } else {
|
|
|
|
+ msleep(100);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
ptr = (char *)buf;
|
|
|
|
strsep(&ptr, "\n");
|
|
|
|
@@ -283,10 +292,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
|
|
|
|
strlcpy(ifp->drvr->fwver, ptr, sizeof(ifp->drvr->fwver));
|
|
|
|
|
|
|
|
/* set mpc */
|
|
|
|
- err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
|
|
|
|
- if (err) {
|
|
|
|
- brcmf_err("failed setting mpc\n");
|
|
|
|
- goto done;
|
|
|
|
+ for (i = 0; i < 10; i++) {
|
|
|
|
+ err = brcmf_fil_iovar_int_set(ifp, "mpc", 1);
|
|
|
|
+ if (err && i == 9) {
|
|
|
|
+ brcmf_err("failed setting mpc\n");
|
|
|
|
+ goto done;
|
|
|
|
+ } else {
|
|
|
|
+ msleep(100);
|
|
|
|
+ }
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
--
|
2015-11-05 04:27:36 +00:00
|
|
|
2.6.1
|
2015-07-03 02:06:55 +00:00
|
|
|
|