diff --git a/src/drivers/net/rtl8139.c b/src/drivers/net/rtl8139.c index 5e37f9c1..4981329c 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 ) );