aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c30
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 a2354d951dd7..e224bcb90024 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -28,6 +28,7 @@
28#include "dhd.h" 28#include "dhd.h"
29#include "dhd_proto.h" 29#include "dhd_proto.h"
30#include "dhd_bus.h" 30#include "dhd_bus.h"
31#include "fwsignal.h"
31#include "dhd_dbg.h" 32#include "dhd_dbg.h"
32 33
33struct brcmf_proto_cdc_dcmd { 34struct brcmf_proto_cdc_dcmd {
@@ -71,13 +72,26 @@ struct brcmf_proto_cdc_dcmd {
71 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \ 72 ((hdr)->flags2 = (((hdr)->flags2 & ~BDC_FLAG2_IF_MASK) | \
72 ((idx) << BDC_FLAG2_IF_SHIFT))) 73 ((idx) << BDC_FLAG2_IF_SHIFT)))
73 74
75/**
76 * struct brcmf_proto_bdc_header - BDC header format
77 *
78 * @flags: flags contain protocol and checksum info.
79 * @priority: 802.1d priority and USB flow control info (bit 4:7).
80 * @flags2: additional flags containing dongle interface index.
81 * @data_offset: start of packet data. header is following by firmware signals.
82 */
74struct brcmf_proto_bdc_header { 83struct brcmf_proto_bdc_header {
75 u8 flags; 84 u8 flags;
76 u8 priority; /* 802.1d Priority, 4:7 flow control info for usb */ 85 u8 priority;
77 u8 flags2; 86 u8 flags2;
78 u8 data_offset; 87 u8 data_offset;
79}; 88};
80 89
90/*
91 * maximum length of firmware signal data between
92 * the BDC header and packet data in the tx path.
93 */
94#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
81 95
82#define RETRIES 2 /* # of retries to retrieve matching dcmd response */ 96#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
83#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE 97#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)
258 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE); 272 skb->ip_summed = (x ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE);
259} 273}
260 274
261void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, 275void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
262 struct sk_buff *pktbuf) 276 struct sk_buff *pktbuf)
263{ 277{
264 struct brcmf_proto_bdc_header *h; 278 struct brcmf_proto_bdc_header *h;
@@ -266,7 +280,6 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
266 brcmf_dbg(CDC, "Enter\n"); 280 brcmf_dbg(CDC, "Enter\n");
267 281
268 /* Push BDC header used to convey priority for buses that don't */ 282 /* Push BDC header used to convey priority for buses that don't */
269
270 skb_push(pktbuf, BDC_HEADER_LEN); 283 skb_push(pktbuf, BDC_HEADER_LEN);
271 284
272 h = (struct brcmf_proto_bdc_header *)(pktbuf->data); 285 h = (struct brcmf_proto_bdc_header *)(pktbuf->data);
@@ -277,11 +290,11 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx,
277 290
278 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); 291 h->priority = (pktbuf->priority & BDC_PRIORITY_MASK);
279 h->flags2 = 0; 292 h->flags2 = 0;
280 h->data_offset = 0; 293 h->data_offset = offset;
281 BDC_SET_IF_IDX(h, ifidx); 294 BDC_SET_IF_IDX(h, ifidx);
282} 295}
283 296
284int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx, 297int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
285 struct sk_buff *pktbuf) 298 struct sk_buff *pktbuf)
286{ 299{
287 struct brcmf_proto_bdc_header *h; 300 struct brcmf_proto_bdc_header *h;
@@ -328,7 +341,10 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, u8 *ifidx,
328 pktbuf->priority = h->priority & BDC_PRIORITY_MASK; 341 pktbuf->priority = h->priority & BDC_PRIORITY_MASK;
329 342
330 skb_pull(pktbuf, BDC_HEADER_LEN); 343 skb_pull(pktbuf, BDC_HEADER_LEN);
331 skb_pull(pktbuf, h->data_offset << 2); 344 if (do_fws)
345 brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
346 else
347 skb_pull(pktbuf, h->data_offset << 2);
332 348
333 if (pktbuf->len == 0) 349 if (pktbuf->len == 0)
334 return -ENODATA; 350 return -ENODATA;
@@ -350,7 +366,7 @@ int brcmf_proto_attach(struct brcmf_pub *drvr)
350 } 366 }
351 367
352 drvr->prot = cdc; 368 drvr->prot = cdc;
353 drvr->hdrlen += BDC_HEADER_LEN; 369 drvr->hdrlen += BDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
354 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN + 370 drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
355 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN; 371 sizeof(struct brcmf_proto_cdc_dcmd) + ROUND_UP_MARGIN;
356 return 0; 372 return 0;