
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@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)