|
|
|
From 3eee5fd6d045dc744f98fd684258e3fdfa667fd6 Mon Sep 17 00:00:00 2001
|
|
|
|
From: Arend van Spriel <arend@broadcom.com>
|
|
|
|
Date: Tue, 25 Feb 2014 20:30:27 +0100
|
|
|
|
Subject: [PATCH] brcmfmac: fix use of skb control buffer in SDIO driver part
|
|
|
|
|
|
|
|
The SDIO driver has a 16-bit field defined in the skbuff control buffer.
|
|
|
|
However, it is accessed as a u32 overwriting other control info. Another
|
|
|
|
issue is that the field is not initialized for networking packets, but
|
|
|
|
the control buffer content is unspecified as other networking layers can
|
|
|
|
use it.
|
|
|
|
|
|
|
|
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
|
|
|
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
|
|
|
Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
|
|
|
|
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
|
|
|
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
|
|
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
|
|
|
---
|
|
|
|
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 10 ++++++----
|
|
|
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
|
|
|
|
|
|
|
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
|
|
|
|
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
|
|
|
|
@@ -1955,7 +1955,7 @@ static int brcmf_sdio_txpkt_prep_sg(stru
|
|
|
|
memcpy(pkt_pad->data,
|
|
|
|
pkt->data + pkt->len - tail_chop,
|
|
|
|
tail_chop);
|
|
|
|
- *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
|
|
|
|
+ *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
|
|
|
|
skb_trim(pkt, pkt->len - tail_chop);
|
|
|
|
skb_trim(pkt_pad, tail_pad + tail_chop);
|
|
|
|
__skb_queue_after(pktq, pkt, pkt_pad);
|
|
|
|
@@ -2003,7 +2003,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio
|
|
|
|
* already properly aligned and does not
|
|
|
|
* need an sdpcm header.
|
|
|
|
*/
|
|
|
|
- if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
|
|
|
|
+ if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* align packet data pointer */
|
|
|
|
@@ -2067,11 +2067,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio
|
|
|
|
u8 *hdr;
|
|
|
|
u32 dat_offset;
|
|
|
|
u16 tail_pad;
|
|
|
|
- u32 dummy_flags, chop_len;
|
|
|
|
+ u16 dummy_flags, chop_len;
|
|
|
|
struct sk_buff *pkt_next, *tmp, *pkt_prev;
|
|
|
|
|
|
|
|
skb_queue_walk_safe(pktq, pkt_next, tmp) {
|
|
|
|
- dummy_flags = *(u32 *)(pkt_next->cb);
|
|
|
|
+ dummy_flags = *(u16 *)(pkt_next->cb);
|
|
|
|
if (dummy_flags & ALIGN_SKB_FLAG) {
|
|
|
|
chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
|
|
|
|
if (chop_len) {
|
|
|
|
@@ -2554,6 +2554,8 @@ static int brcmf_sdio_bus_txdata(struct
|
|
|
|
|
|
|
|
/* Priority based enq */
|
|
|
|
spin_lock_irqsave(&bus->txqlock, flags);
|
|
|
|
+ /* reset bus_flags in packet cb */
|
|
|
|
+ *(u16 *)(pkt->cb) = 0;
|
|
|
|
if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
|
|
|
|
skb_pull(pkt, bus->tx_hdrlen);
|
|
|
|
brcmf_err("out of bus->txq !!!\n");
|