diff options
author | Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> | 2011-05-25 01:57:34 +0200 |
---|---|---|
committer | Philippe LANGLAIS <philippe.langlais@stericsson.com> | 2011-05-25 13:14:00 +0200 |
commit | 320a37b8466d738b80c3102a744720cd43eb022c (patch) | |
tree | 7fbc2e1fdfdb5e93a8749194ab126cfe2962873f | |
parent | a3395967873328bf64dff77ba499f965e0b2f5ff (diff) |
cw1200: Align TX buffers for DMA.
u8500 platform requires that DMA buffers should be 4 bytes aligned.
In most cases skb's passed by network stack are already aligned.
Known exception: TCP connect.
Patch checks alignment of skb->data and move it to the 4 bytes
boundary if not aligned.
Change-Id: I3ce7ba9baa42e6956b2a5cff04ad6a0aacc9f257
Signed-off-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23803
Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
-rw-r--r-- | drivers/staging/cw1200/txrx.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/drivers/staging/cw1200/txrx.c b/drivers/staging/cw1200/txrx.c index 5f3c859fb9e..3435a7b59da 100644 --- a/drivers/staging/cw1200/txrx.c +++ b/drivers/staging/cw1200/txrx.c @@ -430,9 +430,10 @@ int cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) icv_len += 8; /* MIC */ } - if (WARN_ON(skb_headroom(skb) < iv_len + WSM_TX_EXTRA_HEADROOM - || skb_tailroom(skb) < icv_len)) { - printk(KERN_ERR "Bug: no space allocated " + if (skb_headroom(skb) < iv_len + WSM_TX_EXTRA_HEADROOM + || skb_tailroom(skb) < icv_len) { + wiphy_err(priv->hw->wiphy, + "Bug: no space allocated " "for crypto headers.\n" "headroom: %d, tailroom: %d, " "req_headroom: %d, req_tailroom: %d\n" @@ -449,6 +450,22 @@ int cw1200_tx(struct ieee80211_hw *dev, struct sk_buff *skb) memset(icv, 0, icv_len); } + if ((size_t)skb->data & 3) { + size_t offset = (size_t)skb->data & 3; + u8 *p; + if (skb_headroom(skb) < 4) { + wiphy_err(priv->hw->wiphy, + "Bug: no space allocated " + "for DMA alignment.\n" + "headroom: %d\n", + skb_headroom(skb)); + goto err; + } + p = skb_push(skb, offset); + memmove(p, &p[offset], skb->len - offset); + skb_trim(skb, skb->len - offset); + } + ret = cw1200_queue_put(&priv->tx_queue[queue], priv, skb, link_id); if (!WARN_ON(ret)) |