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.kagst...@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

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to