[U-Boot] [PATCH] net: See to it that sent data is aligned to the ethernet controllers wishes

Simon Kagstrom simon.kagstrom at netinsight.net
Wed Aug 19 09:26:07 CEST 2009


See to it that sent data is aligned to the ethernet controllers wishes

This patch adds a send_alignment member to the eth_device structure
which specifies what the alignment requirements are for the particular
device. eth_send checks this alignment on sends, and if it doesn't match
the device requirement, allocates an aligned buffer and copies the data
there.

Currently kirkwood_egiga.c has an 8-byte requirement. This patch is an
alternative and replacement for "[PATCH] arm:kirkwood See to it that
sent data is 8-byte aligned" sent here

  http://lists.denx.de/pipermail/u-boot/2009-August/058829.html

For other devices, I've setup send_alignment to 1.

Signed-off-by: Simon Kagstrom <simon.kagstrom at netinsight.net>
---
 board/MAI/AmigaOneG3SE/enet.c   |    1 +
 board/Marvell/db64360/mv_eth.c  |    1 +
 board/Marvell/db64460/mv_eth.c  |    1 +
 board/esd/cpci750/mv_eth.c      |    1 +
 board/evb64260/eth.c            |    1 +
 board/prodrive/p3mx/mv_eth.c    |    1 +
 cpu/ixp/npe/npe.c               |    1 +
 cpu/mips/au1x00_eth.c           |    1 +
 cpu/mpc8260/ether_scc.c         |    1 +
 drivers/net/4xx_enet.c          |    1 +
 drivers/net/ax88180.c           |    1 +
 drivers/net/bfin_mac.c          |    1 +
 drivers/net/davinci_emac.c      |    1 +
 drivers/net/dc2114x.c           |    1 +
 drivers/net/dm9000x.c           |    1 +
 drivers/net/dnet.c              |    1 +
 drivers/net/e1000.c             |    1 +
 drivers/net/eepro100.c          |    1 +
 drivers/net/fec_mxc.c           |    1 +
 drivers/net/fsl_mcdmafec.c      |    1 +
 drivers/net/ftmac100.c          |    1 +
 drivers/net/greth.c             |    1 +
 drivers/net/inca-ip_sw.c        |    1 +
 drivers/net/kirkwood_egiga.c    |    1 +
 drivers/net/macb.c              |    1 +
 drivers/net/mcffec.c            |    1 +
 drivers/net/mpc5xxx_fec.c       |    1 +
 drivers/net/natsemi.c           |    1 +
 drivers/net/ns8382x.c           |    1 +
 drivers/net/pcnet.c             |    1 +
 drivers/net/plb2800_eth.c       |    1 +
 drivers/net/rtl8139.c           |    1 +
 drivers/net/rtl8169.c           |    1 +
 drivers/net/sh_eth.c            |    1 +
 drivers/net/sk98lin/uboot_drv.c |    1 +
 drivers/net/smc911x.c           |    1 +
 drivers/net/tsec.c              |    1 +
 drivers/net/tsi108_eth.c        |    1 +
 drivers/net/uli526x.c           |    1 +
 drivers/qe/uec.c                |    1 +
 include/net.h                   |    1 +
 net/eth.c                       |   31 ++++++++++++++++++++++++++++++-
 42 files changed, 71 insertions(+), 1 deletions(-)

diff --git a/board/MAI/AmigaOneG3SE/enet.c b/board/MAI/AmigaOneG3SE/enet.c
index b9df55c..fb63de4 100644
--- a/board/MAI/AmigaOneG3SE/enet.c
+++ b/board/MAI/AmigaOneG3SE/enet.c
@@ -481,6 +481,7 @@ int eth_3com_initialize (bd_t * bis)
 
 	sprintf (dev->name, "3Com 3c920c#%d", card_number);
 	dev->iobase = eth_iobase;
+	dev->send_alignment = 1;
 	dev->priv = (void *) devno;
 	dev->init = eth_3com_init;
 	dev->halt = eth_3com_halt;
diff --git a/board/Marvell/db64360/mv_eth.c b/board/Marvell/db64360/mv_eth.c
index dfc0bf7..a083af1 100644
--- a/board/Marvell/db64360/mv_eth.c
+++ b/board/Marvell/db64360/mv_eth.c
@@ -262,6 +262,7 @@ void mv6436x_eth_initialize (bd_t * bis)
 		/* ronen - set the MAC addr in the HW */
 		eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
 
+		dev->send_alignment = 1;
 		dev->init = (void *) db64360_eth_probe;
 		dev->halt = (void *) ethernet_phy_reset;
 		dev->send = (void *) db64360_eth_transmit;
diff --git a/board/Marvell/db64460/mv_eth.c b/board/Marvell/db64460/mv_eth.c
index 0458164..9eaa547 100644
--- a/board/Marvell/db64460/mv_eth.c
+++ b/board/Marvell/db64460/mv_eth.c
@@ -262,6 +262,7 @@ void mv6446x_eth_initialize (bd_t * bis)
 		/* ronen - set the MAC addr in the HW */
 		eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
 
+		dev->send_alignment = 1;
 		dev->init = (void *) db64460_eth_probe;
 		dev->halt = (void *) ethernet_phy_reset;
 		dev->send = (void *) db64460_eth_transmit;
diff --git a/board/esd/cpci750/mv_eth.c b/board/esd/cpci750/mv_eth.c
index 1c21527..45dab40 100644
--- a/board/esd/cpci750/mv_eth.c
+++ b/board/esd/cpci750/mv_eth.c
@@ -262,6 +262,7 @@ void mv6436x_eth_initialize (bd_t * bis)
 		/* ronen - set the MAC addr in the HW */
 		eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
 
+		dev->send_alignment = 1;
 		dev->init = (void *) db64360_eth_probe;
 		dev->halt = (void *) ethernet_phy_reset;
 		dev->send = (void *) db64360_eth_transmit;
diff --git a/board/evb64260/eth.c b/board/evb64260/eth.c
index ca8bab5..91d5bf4 100644
--- a/board/evb64260/eth.c
+++ b/board/evb64260/eth.c
@@ -720,6 +720,7 @@ gt6426x_eth_initialize(bd_t *bis)
 				s = (*e) ? e+1 : e;
 		}
 
+		dev->send_alignment = 1;
 		dev->init = (void*)gt6426x_eth_probe;
 		dev->halt = (void*)gt6426x_eth_reset;
 		dev->send = (void*)gt6426x_eth_transmit;
diff --git a/board/prodrive/p3mx/mv_eth.c b/board/prodrive/p3mx/mv_eth.c
index 8203b3c..2b0b1fa 100644
--- a/board/prodrive/p3mx/mv_eth.c
+++ b/board/prodrive/p3mx/mv_eth.c
@@ -312,6 +312,7 @@ void mv6446x_eth_initialize (bd_t * bis)
 		/* ronen - set the MAC addr in the HW */
 		eth_port_uc_addr_set (devnum, dev->enetaddr, 0);
 
+		dev->send_alignment = 1;
 		dev->init = (void *) db64460_eth_probe;
 		dev->halt = (void *) ethernet_phy_reset;
 		dev->send = (void *) db64460_eth_transmit;
diff --git a/cpu/ixp/npe/npe.c b/cpu/ixp/npe/npe.c
index 2e68689..42ba735 100644
--- a/cpu/ixp/npe/npe.c
+++ b/cpu/ixp/npe/npe.c
@@ -607,6 +607,7 @@ int npe_initialize(bd_t * bis)
 			p_npe->phy_no = CONFIG_PHY_ADDR;
 
 		sprintf(dev->name, "NPE%d", eth_num);
+		dev->send_alignment = 1;
 		dev->priv = (void *)p_npe;
 		dev->init = npe_init;
 		dev->halt = npe_halt;
diff --git a/cpu/mips/au1x00_eth.c b/cpu/mips/au1x00_eth.c
index 5074997..569745d 100644
--- a/cpu/mips/au1x00_eth.c
+++ b/cpu/mips/au1x00_eth.c
@@ -294,6 +294,7 @@ int au1x00_enet_initialize(bd_t *bis){
 
 	sprintf(dev->name, "Au1X00 ethernet");
 	dev->iobase = 0;
+	dev->send_alignment = 1;
 	dev->priv   = 0;
 	dev->init   = au1x00_init;
 	dev->halt   = au1x00_halt;
diff --git a/cpu/mpc8260/ether_scc.c b/cpu/mpc8260/ether_scc.c
index 432111d..9fdf992 100644
--- a/cpu/mpc8260/ether_scc.c
+++ b/cpu/mpc8260/ether_scc.c
@@ -376,6 +376,7 @@ int mpc82xx_scc_enet_initialize(bd_t *bis)
 	memset(dev, 0, sizeof *dev);
 
 	sprintf(dev->name, "SCC ETHERNET");
+	dev->send_alignment = 1;
 	dev->init   = sec_init;
 	dev->halt   = sec_halt;
 	dev->send   = sec_send;
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index 329eef0..3d68a80 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -2016,6 +2016,7 @@ int ppc_4xx_eth_initialize (bd_t * bis)
 		hw->print_speed = 1;
 
 		sprintf (dev->name, "ppc_4xx_eth%d", eth_num - CONFIG_EMAC_NR_START);
+		dev->send_alignment = 1;
 		dev->priv = (void *) hw;
 		dev->init = ppc_4xx_eth_init;
 		dev->halt = ppc_4xx_eth_halt;
diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c
index d843397..6c77865 100644
--- a/drivers/net/ax88180.c
+++ b/drivers/net/ax88180.c
@@ -694,6 +694,7 @@ int ax88180_initialize (bd_t * bis)
 
 	sprintf (dev->name, "ax88180");
 	dev->iobase = AX88180_BASE;
+	dev->send_alignment = 1;
 	dev->priv = priv;
 	dev->init = ax88180_init;
 	dev->halt = ax88180_halt;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 12d98c2..02f6e8b 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -101,6 +101,7 @@ int bfin_EMAC_initialize(bd_t *bis)
 	sprintf(dev->name, "Blackfin EMAC");
 
 	dev->iobase = 0;
+	dev->send_alignment = 1;
 	dev->priv = 0;
 	dev->init = bfin_EMAC_init;
 	dev->halt = bfin_EMAC_halt;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index fa8cee4..e9e930e 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -556,6 +556,7 @@ int davinci_emac_initialize(void)
 	memset(dev, 0, sizeof *dev);
 
 	dev->iobase = 0;
+	dev->send_alignment = 1;
 	dev->init = davinci_eth_open;
 	dev->halt = davinci_eth_close;
 	dev->send = davinci_eth_send_packet;
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 5ae53e8..c927a0a 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -291,6 +291,7 @@ int dc21x4x_initialize(bd_t *bis)
 #else
 		dev->iobase = pci_mem_to_phys(devbusfn, iobase);
 #endif
+		dev->send_alignment = 1;
 		dev->priv   = (void*) devbusfn;
 		dev->init   = dc21x4x_init;
 		dev->halt   = dc21x4x_halt;
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index efe9135..c2f3a80 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -621,6 +621,7 @@ int dm9000_initialize(bd_t *bis)
 {
 	struct eth_device *dev = &(dm9000_info.netdev);
 
+	dev->send_alignment = 1;
 	dev->init = dm9000_init;
 	dev->halt = dm9000_halt;
 	dev->send = dm9000_send;
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index bfe87fa..7881ef5 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -377,6 +377,7 @@ int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr)
 	dnet->phy_addr = phy_addr;
 
 	sprintf(netdev->name, "dnet%d", id);
+	netdev->send_alignment = 1;
 	netdev->init = dnet_init;
 	netdev->halt = dnet_halt;
 	netdev->send = dnet_send;
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 777783a..83cc03e 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -5215,6 +5215,7 @@ e1000_initialize(bd_t * bis)
 		       nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2],
 		       nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]);
 
+		nic->send_alignment = 1;
 		nic->init = e1000_init;
 		nic->recv = e1000_poll;
 		nic->send = e1000_transmit;
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 9c06b25..a0ccad1 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -453,6 +453,7 @@ int eepro100_initialize (bd_t * bis)
 		sprintf (dev->name, "i82559#%d", card_number);
 		dev->priv = (void *) devno; /* this have to come before bus_to_phys() */
 		dev->iobase = bus_to_phys (iobase);
+		dev->send_alignment = 1;
 		dev->init = eepro100_init;
 		dev->halt = eepro100_halt;
 		dev->send = eepro100_send;
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index bd83a24..2238d1c 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -665,6 +665,7 @@ static int fec_probe(bd_t *bd)
 		return -ENOMEM;
 	}
 	edev->priv = fec;
+	edev->send_alignment = 1;
 	edev->init = fec_init;
 	edev->send = fec_send;
 	edev->recv = fec_recv;
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index 35a6dfb..3a59a22 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -533,6 +533,7 @@ int mcdmafec_initialize(bd_t * bis)
 
 		sprintf(dev->name, "FEC%d", fec_info[i].index);
 
+		dev->send_alignment = 1;
 		dev->priv = &fec_info[i];
 		dev->init = fec_init;
 		dev->halt = fec_halt;
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index 2328cb5..0bee211 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -261,6 +261,7 @@ int ftmac100_initialize (bd_t *bd)
 
 	sprintf (dev->name, "FTMAC100");
 	dev->iobase	= CONFIG_FTMAC100_BASE;
+	dev->send_alignment = 1;
 	dev->init	= ftmac100_init;
 	dev->halt	= ftmac100_halt;
 	dev->send	= ftmac100_send;
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 79bc4d9..dbfc737 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -601,6 +601,7 @@ int greth_initialize(bd_t * bis)
 #endif
 	dev->priv = (void *)greth;
 	dev->iobase = (unsigned int)greth->regs;
+	dev->send_alignment = 1;
 	dev->init = greth_init;
 	dev->halt = greth_halt;
 	dev->send = greth_send;
diff --git a/drivers/net/inca-ip_sw.c b/drivers/net/inca-ip_sw.c
index 492f5ce..b900de5 100644
--- a/drivers/net/inca-ip_sw.c
+++ b/drivers/net/inca-ip_sw.c
@@ -189,6 +189,7 @@ int inca_switch_initialize(bd_t * bis)
 #endif
 
 	sprintf(dev->name, "INCA-IP Switch");
+	dev->send_alignment = 1;
 	dev->init = inca_switch_init;
 	dev->halt = inca_switch_halt;
 	dev->send = inca_switch_send;
diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c
index f31fefc..c460e4a 100644
--- a/drivers/net/kirkwood_egiga.c
+++ b/drivers/net/kirkwood_egiga.c
@@ -660,6 +660,7 @@ int kirkwood_egiga_initialize(bd_t * bis)
 			eth_setenv_enetaddr(s, dev->enetaddr);
 		}
 
+		dev->send_alignment = 8;
 		dev->init = (void *)kwgbe_init;
 		dev->halt = (void *)kwgbe_halt;
 		dev->send = (void *)kwgbe_send;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c184353..5bdef70 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -519,6 +519,7 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
 	macb->phy_addr = phy_addr;
 
 	sprintf(netdev->name, "macb%d", id);
+	netdev->send_alignment = 1;
 	netdev->init = macb_init;
 	netdev->halt = macb_halt;
 	netdev->send = macb_send;
diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c
index 64be5de..1413860 100644
--- a/drivers/net/mcffec.c
+++ b/drivers/net/mcffec.c
@@ -572,6 +572,7 @@ int mcffec_initialize(bd_t * bis)
 
 		sprintf(dev->name, "FEC%d", fec_info[i].index);
 
+		dev->send_alignment = 1;
 		dev->priv = &fec_info[i];
 		dev->init = fec_init;
 		dev->halt = fec_halt;
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index 1876b76..46c001b 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -918,6 +918,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
 
 	dev->priv = (void *)fec;
 	dev->iobase = MPC5XXX_FEC;
+	dev->send_alignment = 1;
 	dev->init = mpc5xxx_fec_init;
 	dev->halt = mpc5xxx_fec_halt;
 	dev->send = mpc5xxx_fec_send;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ce12c3b..4709ec7 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -327,6 +327,7 @@ natsemi_initialize(bd_t * bis)
 #ifdef NATSEMI_DEBUG
 		printf("natsemi: NatSemi ns8381[56] @ %#x\n", dev->iobase);
 #endif
+		dev->send_alignment = 1;
 		dev->priv = (void *) devno;
 		dev->init = natsemi_init;
 		dev->halt = natsemi_disable;
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index 198f73d..fac0395 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -343,6 +343,7 @@ ns8382x_initialize(bd_t * bis)
 
 		sprintf(dev->name, "dp8382x#%d", card_number);
 		dev->iobase = bus_to_phys(iobase);
+		dev->send_alignment = 1;
 		dev->priv = (void *) devno;
 		dev->init = ns8382x_init;
 		dev->halt = ns8382x_disable;
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c
index 99b6942..ea02f6f 100644
--- a/drivers/net/pcnet.c
+++ b/drivers/net/pcnet.c
@@ -223,6 +223,7 @@ int pcnet_initialize (bd_t * bis)
 		/*
 		 * Setup device structure and register the driver.
 		 */
+		dev->send_alignment = 1;
 		dev->init = pcnet_init;
 		dev->halt = pcnet_halt;
 		dev->send = pcnet_send;
diff --git a/drivers/net/plb2800_eth.c b/drivers/net/plb2800_eth.c
index d799c73..1de73ae 100644
--- a/drivers/net/plb2800_eth.c
+++ b/drivers/net/plb2800_eth.c
@@ -111,6 +111,7 @@ int plb2800_eth_initialize(bd_t * bis)
 	memset(dev, 0, sizeof(*dev));
 
 	sprintf(dev->name, "PLB2800 Switch");
+	dev->send_alignment = 1;
 	dev->init = plb2800_eth_init;
 	dev->halt = plb2800_eth_halt;
 	dev->send = plb2800_eth_send;
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index db8a727..b9fe39e 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -225,6 +225,7 @@ int rtl8139_initialize(bd_t *bis)
 
 		dev->priv = (void *) devno;
 		dev->iobase = (int)bus_to_phys(iobase);
+		dev->send_alignment = 1;
 		dev->init = rtl8139_probe;
 		dev->halt = rtl_disable;
 		dev->send = rtl_transmit;
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index e45d1a5..5919723 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -899,6 +899,7 @@ int rtl8169_initialize(bd_t *bis)
 
 		dev->priv = (void *) devno;
 		dev->iobase = (int)pci_mem_to_phys(devno, iobase);
+		dev->send_alignment = 1;
 
 		dev->init = rtl_reset;
 		dev->halt = rtl_halt;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 86cc324..d977169 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -652,6 +652,7 @@ int sh_eth_initialize(bd_t *bd)
 
     dev->priv = (void *)eth;
     dev->iobase = 0;
+    dev->send_alignment = 1;
     dev->init = sh_eth_init;
     dev->halt = sh_eth_halt;
     dev->send = sh_eth_send;
diff --git a/drivers/net/sk98lin/uboot_drv.c b/drivers/net/sk98lin/uboot_drv.c
index 0199b33..c166057 100644
--- a/drivers/net/sk98lin/uboot_drv.c
+++ b/drivers/net/sk98lin/uboot_drv.c
@@ -63,6 +63,7 @@ int skge_initialize(bd_t * bis)
 	{
 		sprintf (dev[i]->name, "SK98#%d", i);
 
+		dev[i]->send_alignment = 1;
 		dev[i]->init = skge_init;
 		dev[i]->halt = skge_halt;
 		dev[i]->send = skge_send;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 18a729c..ca99fcd 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -262,6 +262,7 @@ int smc911x_initialize(u8 dev_num, int base_addr)
 	dev->enetaddr[4] = addrh;
 	dev->enetaddr[5] = addrh >> 8;
 
+	dev->send_alignment = 1;
 	dev->init = smc911x_init;
 	dev->halt = smc911x_halt;
 	dev->send = smc911x_send;
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index a9ba683..30c0ee3 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -141,6 +141,7 @@ int tsec_initialize(bd_t * bis, struct tsec_info_struct *tsec_info)
 
 	sprintf(dev->name, tsec_info->devname);
 	dev->iobase = 0;
+	dev->send_alignment = 1;
 	dev->priv = priv;
 	dev->init = tsec_init;
 	dev->halt = tsec_halt;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 079354a..cbab8f0 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -735,6 +735,7 @@ int tsi108_eth_initialize (bd_t * bis)
 		sprintf (dev->name, "TSI108_eth%d", index);
 
 		dev->iobase = ETH_BASE + (index * ETH_PORT_OFFSET);
+		dev->send_alignment = 1;
 		dev->priv = (void *)(phy_address[index]);
 		dev->init = tsi108_eth_probe;
 		dev->halt = tsi108_eth_halt;
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
index 9477851..e86c0a1 100644
--- a/drivers/net/uli526x.c
+++ b/drivers/net/uli526x.c
@@ -232,6 +232,7 @@ int uli526x_initialize(bd_t *bis)
 		dev->priv = db;
 		db->pdev = devno;
 		dev->iobase = iobase;
+		dev->send_alignment = 1;
 
 		dev->init = uli526x_init_one;
 		dev->halt = uli526x_disable;
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index db95ada..aed7bf3 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -1354,6 +1354,7 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
 
 	sprintf(dev->name, "FSL UEC%d", uec_info->uf_info.ucc_num);
 	dev->iobase = 0;
+	dev->send_alignment = 1;
 	dev->priv = (void *)uec;
 	dev->init = uec_init;
 	dev->halt = uec_halt;
diff --git a/include/net.h b/include/net.h
index 4873000..1f84981 100644
--- a/include/net.h
+++ b/include/net.h
@@ -97,6 +97,7 @@ struct eth_device {
 	unsigned char enetaddr[6];
 	int iobase;
 	int state;
+	int send_alignment; /* Power of two send buffer alignment requirement */
 
 	int  (*init) (struct eth_device*, bd_t*);
 	int  (*send) (struct eth_device*, volatile void* packet, int length);
diff --git a/net/eth.c b/net/eth.c
index 9b50312..4508a7d 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -362,10 +362,39 @@ void eth_halt(void)
 
 int eth_send(volatile void *packet, int length)
 {
+	void *p = (void *)packet;
+
 	if (!eth_current)
 		return -1;
 
-	return eth_current->send(eth_current, packet, length);
+	/* Copy buffer if it's misaligned */
+	if ((u32) packet & (eth_current->send_alignment - 1)) {
+		static void *aligned_buf;
+
+		/* eth_current might have changed, so possibly reallocate the buf
+		 * if it doesn't match the requirements for eth_current */
+		if (aligned_buf &&
+				((u32)aligned_buf & (eth_current->send_alignment - 1))) {
+			free(aligned_buf);
+			aligned_buf = NULL;
+		}
+
+		if (!aligned_buf)
+			aligned_buf = memalign(eth_current->send_alignment,
+					PKTSIZE_ALIGN);
+		if (!aligned_buf) {
+			printf("eth_send: Cannot allocate aligned buffer\n");
+			return -1;
+		}
+		if (length > PKTSIZE_ALIGN) {
+			printf("eth_send: Non-aligned data too large (%d)\n", length);
+			return -1;
+		}
+		memcpy(aligned_buf, p, length);
+		p = aligned_buf;
+	}
+
+	return eth_current->send(eth_current, p, length);
 }
 
 int eth_rx(void)
-- 
1.6.0.4



More information about the U-Boot mailing list