Patchwork [U-Boot] drivers/net/designware - fix alignment of buffer descriptors

login
register
mail settings
Submitter Alexey Brodkin
Date Sept. 25, 2013, 1:34 p.m.
Message ID <1380116041-24750-1-git-send-email-abrodkin@synopsys.com>
Download mbox | patch
Permalink /patch/277863/
State Superseded
Delegated to: Joe Hershberger
Headers show

Comments

Alexey Brodkin - Sept. 25, 2013, 1:34 p.m.
It's important that buffer descriptors are aligned in accordance to GMAC
data bus width (32/64/128-bit). It's safe to align to 128-bit (16-bytes)
for every bus width type.

If buffer descriptor is improperly aligned GMAC discards lower bits of
provided address and as a result reads from improper location that
doesn't match expected fields.

Any other members of structure "dw_eth_dev" (and structure itself) don't
need any specific alignment.

Moreover commit ef76025a99247cdb8f927a2c9f15400678dfb599 "net: Multiple
updates/enhancements to designware.c" introduced another structure
member "link_printed" right before buffer descriptors while "padding"
member was left untouched. This together with alignment of structure
itself to 8-byte boundary forces buffer descriptoprs always to be 4-byte
aligned that causes driver complete disfunction if GMAC bus width is 64
or 128-bit.

Proposed change makes sure all buffer descriptors are 128-bit aligned.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
---
 drivers/net/designware.c | 6 +-----
 drivers/net/designware.h | 7 +++----
 2 files changed, 4 insertions(+), 9 deletions(-)

Patch

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index f11cb0b..c8e3fc8 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -534,11 +534,7 @@  int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface)
 	if (!dev)
 		return -ENOMEM;
 
-	/*
-	 * Since the priv structure contains the descriptors which need a strict
-	 * buswidth alignment, memalign is used to allocate memory
-	 */
-	priv = (struct dw_eth_dev *) memalign(16, sizeof(struct dw_eth_dev));
+	priv = (struct dw_eth_dev *) malloc(sizeof(struct dw_eth_dev));
 	if (!priv) {
 		free(dev);
 		return -ENOMEM;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index d668f8f..137acb0 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -128,7 +128,7 @@  struct dmamacdescr {
 	u32 dmamac_cntl;
 	void *dmamac_addr;
 	struct dmamacdescr *dmamac_next;
-};
+} __aligned(16);
 
 /*
  * txrx_status definitions
@@ -240,8 +240,7 @@  struct dw_eth_dev {
 	u32 tx_currdescnum;
 	u32 rx_currdescnum;
 	u32 phy_configured;
-	int link_printed;
-	u32 padding;
+	u32 link_printed;
 
 	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
 	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
@@ -253,7 +252,7 @@  struct dw_eth_dev {
 	struct eth_dma_regs *dma_regs_p;
 
 	struct eth_device *dev;
-} __attribute__ ((aligned(8)));
+};
 
 /* Speed specific definitions */
 #define SPEED_10M		1