[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