summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/net/rtl8139.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c
index 5e37f9c13..4981329c3 100644
--- a/src/drivers/net/rtl8139.c
+++ b/src/drivers/net/rtl8139.c
@@ -367,8 +367,10 @@ static void rtl_close ( struct net_device *netdev ) {
*/
static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
struct rtl8139_nic *rtl = netdev->priv;
- int align;
- int pad_len;
+ void *data;
+ size_t len;
+ size_t headroom;
+ signed int pad_len;
/* Check for space in TX ring */
if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
@@ -376,11 +378,18 @@ static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
return -ENOBUFS;
}
- /* Align packet data */
- align = ( virt_to_bus ( pkb->data ) & 0x3 );
- pkb_push ( pkb, align );
- memmove ( pkb->data, pkb->data + align, pkb_len ( pkb ) - align );
- pkb_unput ( pkb, align );
+ /* Move packet data to start of packet buffer. This will both
+ * align the data (since packet buffers are aligned to
+ * PKB_ALIGN) and give us sufficient space for the
+ * zero-padding
+ */
+ data = pkb->data;
+ len = pkb_len ( pkb );
+ headroom = pkb_headroom ( pkb );
+ pkb_push ( pkb, headroom );
+ memmove ( pkb->data, data, len );
+ pkb_unput ( pkb, headroom );
+ assert ( ( virt_to_bus ( pkb->data ) & 0x3 ) == 0 );
/* Pad to minimum packet length */
pad_len = ( ETH_ZLEN - pkb_len ( pkb ) );