Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b69c1df4 authored by Arend Van Spriel's avatar Arend Van Spriel Committed by Kalle Valo
Browse files

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: default avatarHante Meuleman <hante.meuleman@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
Reviewed-by: default avatarFranky Lin <franky.lin@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 5242a544
Loading
Loading
Loading
Loading
+6 −5
Original line number Original line Diff line number Diff line
@@ -165,7 +165,7 @@ static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)


static int
static int
brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
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_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
	struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
	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);
	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);


	*fwerr = 0;
	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
	if (ret < 0) {
	if (ret < 0) {
		brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
		brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n",
@@ -215,15 +216,14 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,


	/* Check the ERROR flag */
	/* Check the ERROR flag */
	if (flags & BCDC_DCMD_ERROR)
	if (flags & BCDC_DCMD_ERROR)
		ret = le32_to_cpu(msg->status);
		*fwerr = le32_to_cpu(msg->status);

done:
done:
	return ret;
	return ret;
}
}


static int
static int
brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
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_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
	struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
	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,


	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
	brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);


	*fwerr = 0;
	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
	ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
	if (ret < 0)
	if (ret < 0)
		goto done;
		goto done;
@@ -255,7 +256,7 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,


	/* Check the ERROR flag */
	/* Check the ERROR flag */
	if (flags & BCDC_DCMD_ERROR)
	if (flags & BCDC_DCMD_ERROR)
		ret = le32_to_cpu(msg->status);
		*fwerr = le32_to_cpu(msg->status);


done:
done:
	return ret;
	return ret;
+11 −5
Original line number Original line Diff line number Diff line
@@ -107,7 +107,7 @@ static s32
brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
{
{
	struct brcmf_pub *drvr = ifp->drvr;
	struct brcmf_pub *drvr = ifp->drvr;
	s32 err;
	s32 err, fwerr;


	if (drvr->bus_if->state != BRCMF_BUS_UP) {
	if (drvr->bus_if->state != BRCMF_BUS_UP) {
		brcmf_err("bus is down. we have nothing to do.\n");
		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)
	if (data != NULL)
	if (data != NULL)
		len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
		len = min_t(uint, len, BRCMF_DCMD_MAXLEN);
	if (set)
	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
	else
		err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd, data, len);
		err = brcmf_proto_query_dcmd(drvr, ifp->ifidx, cmd,
					     data, len, &fwerr);


	if (err)
	if (err) {
		brcmf_dbg(FIL, "Failed: %s (%d)\n",
		brcmf_dbg(FIL, "Failed: %s (%d)\n",
			  brcmf_fil_get_errstr((u32)(-err)), err);
			  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;
	return err;
}
}


+6 −4
Original line number Original line Diff line number Diff line
@@ -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,
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 brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
	struct sk_buff *skb = NULL;
	struct sk_buff *skb = NULL;
@@ -485,6 +485,7 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
	int err;
	int err;


	brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
	brcmf_dbg(MSGBUF, "ifidx=%d, cmd=%d, len=%d\n", ifidx, cmd, len);
	*fwerr = 0;
	msgbuf->ctl_completed = false;
	msgbuf->ctl_completed = false;
	err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
	err = brcmf_msgbuf_tx_ioctl(drvr, ifidx, cmd, buf, len);
	if (err)
	if (err)
@@ -508,14 +509,15 @@ static int brcmf_msgbuf_query_dcmd(struct brcmf_pub *drvr, int ifidx,
	}
	}
	brcmu_pkt_buf_free_skb(skb);
	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,
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);
}
}




+8 −6
Original line number Original line Diff line number Diff line
@@ -30,9 +30,9 @@ struct brcmf_proto {
	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
	int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
		       struct sk_buff *skb, struct brcmf_if **ifp);
		       struct sk_buff *skb, struct brcmf_if **ifp);
	int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
	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,
	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,
	int (*tx_queue_data)(struct brcmf_pub *drvr, int ifidx,
			     struct sk_buff *skb);
			     struct sk_buff *skb);
	int (*txdata)(struct brcmf_pub *drvr, int ifidx, u8 offset,
	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);
	return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
}
}
static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
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,
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,
static inline int brcmf_proto_tx_queue_data(struct brcmf_pub *drvr, int ifidx,