aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArend van Spriel <arend@broadcom.com>2014-02-25 14:30:27 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-28 14:33:18 -0500
commit5aa9f0ea18f3d5ec329a619b0bc54e214e02bc33 (patch)
tree10c54fd91f6e92d6a0c9c3a8e60126aaef66aace
parent68ca395f94e932a2d9a775f2c103c5bce257e795 (diff)
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>
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c10
1 files 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 631d5dc5b6d5..fa4ec69871c7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -2112,7 +2112,7 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
2112 memcpy(pkt_pad->data, 2112 memcpy(pkt_pad->data,
2113 pkt->data + pkt->len - tail_chop, 2113 pkt->data + pkt->len - tail_chop,
2114 tail_chop); 2114 tail_chop);
2115 *(u32 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop; 2115 *(u16 *)(pkt_pad->cb) = ALIGN_SKB_FLAG + tail_chop;
2116 skb_trim(pkt, pkt->len - tail_chop); 2116 skb_trim(pkt, pkt->len - tail_chop);
2117 __skb_queue_after(pktq, pkt, pkt_pad); 2117 __skb_queue_after(pktq, pkt, pkt_pad);
2118 } else { 2118 } else {
@@ -2159,7 +2159,7 @@ brcmf_sdio_txpkt_prep(struct brcmf_sdio *bus, struct sk_buff_head *pktq,
2159 * already properly aligned and does not 2159 * already properly aligned and does not
2160 * need an sdpcm header. 2160 * need an sdpcm header.
2161 */ 2161 */
2162 if (*(u32 *)(pkt_next->cb) & ALIGN_SKB_FLAG) 2162 if (*(u16 *)(pkt_next->cb) & ALIGN_SKB_FLAG)
2163 continue; 2163 continue;
2164 2164
2165 /* align packet data pointer */ 2165 /* align packet data pointer */
@@ -2223,11 +2223,11 @@ brcmf_sdio_txpkt_postp(struct brcmf_sdio *bus, struct sk_buff_head *pktq)
2223 u8 *hdr; 2223 u8 *hdr;
2224 u32 dat_offset; 2224 u32 dat_offset;
2225 u16 tail_pad; 2225 u16 tail_pad;
2226 u32 dummy_flags, chop_len; 2226 u16 dummy_flags, chop_len;
2227 struct sk_buff *pkt_next, *tmp, *pkt_prev; 2227 struct sk_buff *pkt_next, *tmp, *pkt_prev;
2228 2228
2229 skb_queue_walk_safe(pktq, pkt_next, tmp) { 2229 skb_queue_walk_safe(pktq, pkt_next, tmp) {
2230 dummy_flags = *(u32 *)(pkt_next->cb); 2230 dummy_flags = *(u16 *)(pkt_next->cb);
2231 if (dummy_flags & ALIGN_SKB_FLAG) { 2231 if (dummy_flags & ALIGN_SKB_FLAG) {
2232 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK; 2232 chop_len = dummy_flags & ALIGN_SKB_CHOP_LEN_MASK;
2233 if (chop_len) { 2233 if (chop_len) {
@@ -2709,6 +2709,8 @@ static int brcmf_sdio_bus_txdata(struct device *dev, struct sk_buff *pkt)
2709 2709
2710 /* Priority based enq */ 2710 /* Priority based enq */
2711 spin_lock_irqsave(&bus->txqlock, flags); 2711 spin_lock_irqsave(&bus->txqlock, flags);
2712 /* reset bus_flags in packet cb */
2713 *(u16 *)(pkt->cb) = 0;
2712 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) { 2714 if (!brcmf_c_prec_enq(bus->sdiodev->dev, &bus->txq, pkt, prec)) {
2713 skb_pull(pkt, bus->tx_hdrlen); 2715 skb_pull(pkt, bus->tx_hdrlen);
2714 brcmf_err("out of bus->txq !!!\n"); 2716 brcmf_err("out of bus->txq !!!\n");