summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/p54/p54spi.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2009-03-27 07:50:53 +0300
committerJohn W. Linville <linville@tuxdriver.com>2009-04-22 16:54:27 -0400
commit9f201a87831af9458df1eda65941c955f2da87ed (patch)
tree6203d7556d501769d2bd551afe25233a4b98cf6c /drivers/net/wireless/p54/p54spi.c
parent488829f1b141858944a24fd793220fa1d52cd9a6 (diff)
p54spi: compensate firmware alignment bug in p54spi_rx
Firmware may insert up to 4 padding bytes after the lmac header, but it does not amend the size of SPI data transfer. Such packets has correct data size in header, thus referencing past the end of allocated skb. Put extra 4 bytes to the end of the received skb to compensate for this case. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Acked-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54spi.c')
-rw-r--r--drivers/net/wireless/p54/p54spi.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index f8af09610180..52023127cf37 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -395,7 +395,12 @@ static int p54spi_rx(struct p54s_priv *priv)
return 0;
}
- skb = dev_alloc_skb(len);
+
+ /* Firmware may insert up to 4 padding bytes after the lmac header,
+ * but it does not amend the size of SPI data transfer.
+ * Such packets has correct data size in header, thus referencing
+ * past the end of allocated skb. Reserve extra 4 bytes for this case */
+ skb = dev_alloc_skb(len + 4);
if (!skb) {
dev_err(&priv->spi->dev, "could not alloc skb");
return 0;
@@ -403,6 +408,9 @@ static int p54spi_rx(struct p54s_priv *priv)
p54spi_spi_read(priv, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
p54spi_sleep(priv);
+ /* Put additional bytes to compensate for the possible
+ * alignment-caused truncation */
+ skb_put(skb, 4);
if (p54_rx(priv->hw, skb) == 0)
dev_kfree_skb(skb);