aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend Van Spriel <arend.vanspriel@broadcom.com>2018-01-22 15:46:40 -0500
committerKalle Valo <kvalo@codeaurora.org>2018-01-24 11:02:39 -0500
commitb69c1df47281ad47bd2037a42b98f5c7115b7fd5 (patch)
tree8fc1f6eb8204ef06b99d7b0281e051b09c7f5555
parent5242a5444e0b6464d7455beb55d936dd192b5e9d (diff)
brcmfmac: separate firmware errors from i/o errors
When using the firmware api it can fail simply because firmware does not like the request or it fails due to issues in the host interface. Currently, there is only a single error code which is confusing. So adding a parameter to pass the firmware error separately and in case of a firmware error always return -EBADE to user-space. Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com> Reviewed-by: Franky Lin <franky.lin@broadcom.com> Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c11
-rw-r--r--drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c16
-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, 31 insertions, 20 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
index bd6da053c03e..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)
165 165
166static int 166static int
167brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 167brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
168 void *buf, uint len) 168 void *buf, uint len, int *fwerr)
169{ 169{
170 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 170 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
171 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; 171 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,
175 175
176 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); 176 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
177 177
178 *fwerr = 0;
178 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); 179 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
179 if (ret < 0) { 180 if (ret < 0) {
180 brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", 181 brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
@@ -215,15 +216,14 @@ retry:
215 216
216 /* Check the ERROR flag */ 217 /* Check the ERROR flag */
217 if (flags & BCDC_DCMD_ERROR) 218 if (flags & BCDC_DCMD_ERROR)
218 ret = le32_to_cpu(msg->status); 219 *fwerr = le32_to_cpu(msg->status);
219
220done: 220done:
221 return ret; 221 return ret;
222} 222}
223 223
224static int 224static int
225brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, 225brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
226 void *buf, uint len) 226 void *buf, uint len, int *fwerr)
227{ 227{
228 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd; 228 struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
229 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg; 229 struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
@@ -232,6 +232,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
232 232
233 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len); 233 brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
234 234
235 *fwerr = 0;
235 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true); 236 ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
236 if (ret < 0) 237 if (ret < 0)
237 goto done; 238 goto done;
@@ -255,7 +256,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
255 256
256 /* Check the ERROR flag */ 257 /* Check the ERROR flag */
257 if (flags & BCDC_DCMD_ERROR) 258 if (flags & BCDC_DCMD_ERROR)
258 ret = le32_to_cpu(msg->status); 259 *fwerr = le32_to_cpu(msg->status);
259 260
260done: 261done:
261 return ret; 262 return ret;
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c
index d328aae0a0a4..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
107brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set) 107brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
108{ 108{
109 struct brcmf_pub *drvr = ifp->drvr; 109 struct brcmf_pub *drvr = ifp->drvr;
110 s32 err; 110 s32 err, fwerr;
111 111
112 if (drvr->bus_if->state != BRCMF_BUS_UP) { 112 if (drvr->bus_if->state != BRCMF_BUS_UP) {
113 brcmf_err("bus is down. we have nothing to do.\n"); 113 brcmf_err("bus is down. we have nothing to do.\n");
@@ -117,14 +117,20 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
117 if (data != NULL) 117 if (data != NULL)
118 len = min_t(uint, len, BRCMF_DCMD_MAXLEN); 118 len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
119 if (set) 119 if (set)
120 err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd, data, len); 120 err = brcmf_proto_set_dcmd(drvr, ifp->ifidx, cmd,
121 data, len, &fwerr);
121 else 122 else
122 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len); 123 err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd,
124 data, len, &fwerr);
123 125
124 if (err) 126 if (err) {
125 brcmf_dbg(FIL, "Failed: %s (%d)\n", 127 brcmf_dbg(FIL, "Failed: %s (%d)\n",
126 brcmf_fil_get_errstr((u32)(-err)), err); 128 brcmf_fil_get_errstr((u32)(-err)), err);
127 129 } else if (fwerr < 0) {
130 brcmf_dbg(FIL, "Firmware error: %s (%d)\n",
131 brcmf_fil_get_errstr((u32)(-fwerr)), fwerr);
132 err = -EBADE;
133 }
128 return err; 134 return err;
129} 135}
130 136
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)
477 477
478 478
479static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx, 479static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
480 uint cmd, void *buf, uint len) 480 uint cmd, void *buf, uint len, int *fwerr)
481{ 481{
482 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; 482 struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
483 struct sk_buff *skb = NULL; 483 struct sk_buff *skb = NULL;
@@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
485 int err; 485 int err;
486 486
487 brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len); 487 brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
488 *fwerr = 0;
488 msgbuf->ctl_completed = false; 489 msgbuf->ctl_completed = false;
489 err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len); 490 err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
490 if (err) 491 if (err)
@@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
508 } 509 }
509 brcmu_pkt_buf_free_skb(skb); 510 brcmu_pkt_buf_free_skb(skb);
510 511
511 return msgbuf->ioctl_resp_status; 512 *fwerr = msgbuf->ioctl_resp_status;
513 return 0;
512} 514}
513 515
514 516
515static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx, 517static int brcmf_msgbuf_set_dcmd(struct brcmf_pub *drvr, int ifidx,
516 uint cmd, void *buf, uint len) 518 uint cmd, void *buf, uint len, int *fwerr)
517{ 519{
518 return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len); 520 return brcmf_msgbuf_query_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
519} 521}
520 522
521 523
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 {
30 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, 30 int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
31 struct sk_buff *skb, struct brcmf_if **ifp); 31 struct sk_buff *skb, struct brcmf_if **ifp);
32 int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, 32 int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
33 void *buf, uint len); 33 void *buf, uint len, int *fwerr);
34 int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, 34 int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
35 uint len); 35 uint len, int *fwerr);
36 int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx, 36 int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx,
37 struct sk_buff *skb); 37 struct sk_buff *skb);
38 int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset, 38 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,
71 return drvr->proto->hdrpull(drvr, do_fws, skb, ifp); 71 return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
72} 72}
73static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx, 73static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
74 uint cmd, void *buf, uint len) 74 uint cmd, void *buf, uint len,
75 int *fwerr)
75{ 76{
76 return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len); 77 return drvr->proto->query_dcmd(drvr, ifidx, cmd, buf, len,fwerr);
77} 78}
78static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx, 79static inline int brcmf_proto_set_dcmd(struct brcmf_pub *drvr, int ifidx,
79 uint cmd, void *buf, uint len) 80 uint cmd, void *buf, uint len,
81 int *fwerr)
80{ 82{
81 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len); 83 return drvr->proto->set_dcmd(drvr, ifidx, cmd, buf, len, fwerr);
82} 84}
83 85
84static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx, 86static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx,