[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH] e1000: fix RX/TX descriptor alignment.



This patch fixes the e1000 driver in VMware (and potentially some real
hardware as well) by enforcing a 16-byte alignment for transmit and
receive descriptors. Without this fix, the card automatically aligns the
addresses on a 16-byte boundary, causing corruption in several data
structures.

The specification specifically states "The * Descriptor Base Address must
point to a 16-byte aligned block of data". VMware appears to be far more
pedantic than QEMU and VirtualBox when using these buffers.

Signed-off-by: Matthew Iselin <matthew@xxxxxxxxxxxxxx>
---
 e1000/device.c |    6 +++---
 e1000/device.h |    4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/e1000/device.c b/e1000/device.c
index 6ce814c..027c3fe 100644
--- a/e1000/device.c
+++ b/e1000/device.c
@@ -277,6 +277,7 @@ static void reset_nic(struct e1000_device* netcard)
     // Rx/Tx-Ring initialisieren
     reg_outl(netcard, REG_RXDESC_ADDR_HI, 0);
     reg_outl(netcard, REG_RXDESC_ADDR_LO, PHYS(netcard, rx_desc[0]));
+    printf("RX descriptors at %x", PHYS(netcard, rx_desc[0]));
     reg_outl(netcard, REG_RXDESC_LEN,
         RX_BUFFER_NUM * sizeof(struct e1000_rx_descriptor));
     reg_outl(netcard, REG_RXDESC_HEAD, 0);
@@ -308,13 +309,12 @@ static void reset_nic(struct e1000_device* netcard)
     // Rx-Deskriptoren aufsetzen
     for (i = 0; i < RX_BUFFER_NUM; i++) {
         netcard->rx_desc[i].length = RX_BUFFER_SIZE;
-        netcard->rx_desc[i].buffer =
-            PHYS(netcard, rx_buffer[i * RX_BUFFER_SIZE]);
+        netcard->rx_desc[i].buffer = PHYS(netcard, rx_buffer[i * RX_BUFFER_SIZE]);
 
 #ifdef DEBUG
         printf("e1000: [%d] Rx: Buffer @ phys %08x, Desc @ phys %08x\n",
             i,
-            netcard->rx_desc[i].buffer, 
+            netcard->rx_desc[i].buffer,
             PHYS(netcard, rx_desc[i]));
 #endif
     }
diff --git a/e1000/device.h b/e1000/device.h
index af614c2..26f2a45 100644
--- a/e1000/device.h
+++ b/e1000/device.h
@@ -163,11 +163,11 @@ struct e1000_device {
 
     uintptr_t                   phys;
 
-    struct e1000_tx_descriptor  tx_desc[TX_BUFFER_NUM];
+    struct e1000_tx_descriptor  tx_desc[TX_BUFFER_NUM] __attribute__((aligned(16)));
     uint8_t                     tx_buffer[TX_BUFFER_NUM * TX_BUFFER_SIZE];
     uint32_t                    tx_cur_buffer;
 
-    struct e1000_rx_descriptor  rx_desc[RX_BUFFER_NUM];
+    struct e1000_rx_descriptor  rx_desc[RX_BUFFER_NUM] __attribute__((aligned(16)));
     uint8_t                     rx_buffer[RX_BUFFER_NUM * RX_BUFFER_SIZE];
     uint32_t                    rx_cur_buffer;
 
-- 
1.7.3.1.msysgit.0