aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/broadcom/brcm80211
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211')
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c17
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c24
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c10
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h14
4 files changed, 39 insertions, 26 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
index 9f2d0b0cf6e5..2d3a5dd07a3f 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
@@ -165,7 +165,7 @@ static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
static int
brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
- void *buf, uint len)
+ void *buf, uint len, int *fwerr)
{
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
@@ -175,6 +175,7 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+ *fwerr = 0;
ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
if (ret < 0) {
brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
@@ -211,25 +212,27 @@ retry:
memcpy(buf, info, len);
}
+ ret = 0;
+
/* Check the ERROR flag */
if (flags & BCDC_DCMD_ERROR)
- ret = le32_to_cpu(msg->status);
-
+ *fwerr = le32_to_cpu(msg->status);
done:
return ret;
}
static int
brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
- void *buf, uint len)
+ void *buf, uint len, int *fwerr)
{
struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
- int ret = 0;
+ int ret;
u32 flags, id;
brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+ *fwerr = 0;
ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
if (ret < 0)
goto done;
@@ -249,9 +252,11 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
goto done;
}
+ ret = 0;
+
/* Check the ERROR flag */
if (flags & BCDC_DCMD_ERROR)
- ret = le32_to_cpu(msg->status);
+ *fwerr = le32_to_cpu(msg->status);
done:
return ret;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
index f6a2df94dba7..f2cfdd3b2bf1 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
@@ -107,7 +107,7 @@ static s32
brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
{
struct brcmf_pub *drvr = ifp->drvr;
- s32 err;
+ s32 err, fwerr;
if (drvr->bus_if->state != BRCMF_BUS_UP) {
brcmf_err("bus is down. we have nothing to do.\n");
@@ -117,16 +117,20 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
if (data != NULL)
len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
if (set)
- err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len);
+ err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd,
+ data, len, &fwerr);
else
- err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
-
- if (err >= 0)
- return 0;
-
- brcmf_dbg(FIL, "Failed: %s (%d)\n",
- brcmf_fil_get_errstr((u32)(-err)), err);
-
+ err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd,
+ data, len, &fwerr);
+
+ if (err) {
+ brcmf_dbg(FIL, "Failed: %s (%d)\n",
+ brcmf_fil_get_errstr((u32)(-err)), err);
+ } else if (fwerr < 0) {
+ brcmf_dbg(FIL, "Firmware error: %s (%d)\n",
+ brcmf_fil_get_errstr((u32)(-fwerr)), fwerr);
+ err = -EBADE;
+ }
return err;
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
index d2c834c3b2fc..e212a791a072 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
@@ -477,7 +477,7 @@ static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len)
+ uint cmd, void *buf, uint len, int *fwerr)
{
struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
struct sk_buff *skb = NULL;
@@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
int err;
brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
+ *fwerr = 0;
msgbuf->ctl_completed = false;
err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
if (err)
@@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
}
brcmu_pkt_buf_free_skb(skb);
- return msgbuf->ioctl_resp_status;
+ *fwerr = msgbuf->ioctl_resp_status;
+ return 0;
}
static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len)
+ uint cmd, void *buf, uint len, int *fwerr)
{
- return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len);
+ return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
}
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
index 2404f8a7c31c..8a8e08f09ea0 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h
@@ -30,9 +30,9 @@ struct brcmf_proto {
int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
struct sk_buff *skb, struct brcmf_if **ifp);
int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
- void *buf, uint len);
+ void *buf, uint len, int *fwerr);
int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
- uint len);
+ uint len, int *fwerr);
int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx,
struct sk_buff *skb);
int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
@@ -71,14 +71,16 @@ static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
}
static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len)
+ uint cmd, void *buf, uint len,
+ int *fwerr)
{
- return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len);
+ return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len,fwerr);
}
static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len)
+ uint cmd, void *buf, uint len,
+ int *fwerr)
{
- return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len);
+ return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
}
static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx,