[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