sunxi: initial 3.14 patchset
[openwrt/openwrt.git] / target / linux / sunxi / patches-3.14 / 231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch
diff --git a/target/linux/sunxi/patches-3.14/231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch b/target/linux/sunxi/patches-3.14/231-2-brcmfmac-fix-use-of-skb-ctrlbuf-in-SDIO.patch
new file mode 100644 (file)
index 0000000..5743e66
--- /dev/null
@@ -0,0 +1,69 @@
+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(-)
+
+diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+index ddaa9ef..e006e7c 100644
+--- 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(struct brcmf_sdio *bus,
+               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 *bus, struct sk_buff_head *pktq,
+                * 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 *bus, struct sk_buff_head *pktq)
+       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 device *dev, struct sk_buff *pkt)
+       /* 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");
+-- 
+2.0.3
+