summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Tarnyagin <dmitry.tarnyagin@stericsson.com>2011-05-25 01:57:34 +0200
committerPhilippe LANGLAIS <philippe.langlais@stericsson.com>2011-05-25 13:14:00 +0200
commit320a37b8466d738b80c3102a744720cd43eb022c (patch)
tree7fbc2e1fdfdb5e93a8749194ab126cfe2962873f
parenta3395967873328bf64dff77ba499f965e0b2f5ff (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.c23
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))