diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c')
| -rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 30 | 
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index a2354d951dd..e224bcb9002 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -28,6 +28,7 @@  #include "dhd.h"  #include "dhd_proto.h"  #include "dhd_bus.h" +#include "fwsignal.h"  #include "dhd_dbg.h"  struct brcmf_proto_cdc_dcmd { @@ -71,13 +72,26 @@ struct brcmf_proto_cdc_dcmd {  	((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \  	((idx) << BDC_FLAG2_IF_SHIFT))) +/** + * struct brcmf_proto_bdc_header - BDC header format + * + * @flags: flags contain protocol and checksum info. + * @priority: 802.1d priority and USB flow control info (bit 4:7). + * @flags2: additional flags containing dongle interface index. + * @data_offset: start of packet data. header is following by firmware signals. + */  struct brcmf_proto_bdc_header {  	u8 flags; -	u8 priority;	/* 802.1d Priority, 4:7 flow control info for usb */ +	u8 priority;  	u8 flags2;  	u8 data_offset;  }; +/* + * maximum length of firmware signal data between + * the BDC header and packet data in the tx path. + */ +#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES	12  #define RETRIES 2 /* # of retries to retrieve matching dcmd response */  #define BUS_HEADER_LEN	(16+64)		/* Must be atleast SDPCM_RESERVE @@ -258,7 +272,7 @@ static void pkt_set_sum_good(struct sk_buff *skb, bool x)  	skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);  } -void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, +void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,  			 struct sk_buff *pktbuf)  {  	struct brcmf_proto_bdc_header *h; @@ -266,7 +280,6 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,  	brcmf_dbg(CDC, "Enter\n");  	/* Push BDC header used to convey priority for buses that don't */ -  	skb_push(pktbuf, BDC_HEADER_LEN);  	h = (struct brcmf_proto_bdc_header *)(pktbuf->data); @@ -277,11 +290,11 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,  	h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);  	h->flags2 = 0; -	h->data_offset = 0; +	h->data_offset = offset;  	BDC_SET_IF_IDX(h, ifidx);  } -int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, +int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,  			struct sk_buff *pktbuf)  {  	struct brcmf_proto_bdc_header *h; @@ -328,7 +341,10 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,  	pktbuf->priority = h->priority & BDC_PRIORITY_MASK;  	skb_pull(pktbuf, BDC_HEADER_LEN); -	skb_pull(pktbuf, h->data_offset << 2); +	if (do_fws) +		brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf); +	else +		skb_pull(pktbuf, h->data_offset << 2);  	if (pktbuf->len == 0)  		return -ENODATA; @@ -350,7 +366,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)  	}  	drvr->prot = cdc; -	drvr->hdrlen += BDC_HEADER_LEN; +	drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;  	drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +  			sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;  	return 0;  |