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

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)

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.
Basically NACK for it. Why you don't resolve the alignment issue in your driver?
Thanks, Dave

On Wed, 19 Aug 2009 15:36:04 +0800 "Liu Dave-R63238" DaveLiu@freescale.com wrote:
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.
Basically NACK for it. Why you don't resolve the alignment issue in your driver?
Well, that's what the other patch I sent does (the link above), but there were wishes then to handle this above the driver layer, hence this patch :-)
I'm fine with either way, but if there are other drivers with alignment requirements, I'd prefer this variant.
// Simon

Well, that's what the other patch I sent does (the link above), but there were wishes then to handle this above the driver layer, hence this patch :-)
I'm fine with either way, but if there are other drivers with alignment requirements, I'd prefer this variant.
I believe some Freescale's CPM/QE controllers need care the alignement requirement.
If you don't care the performance, you can malloc memory to get the aligned buffer pool in the initiaize phase, then use the buffer pool to resolve your alignment issue, of course It needs a copy, but it avoids to malloc/free buffer in run-time.
Thanks, Dave

On Wed, 19 Aug 2009 16:06:12 +0800 "Liu Dave-R63238" DaveLiu@freescale.com wrote:
Well, that's what the other patch I sent does (the link above), but there were wishes then to handle this above the driver layer, hence this patch :-)
I'm fine with either way, but if there are other drivers with alignment requirements, I'd prefer this variant.
I believe some Freescale's CPM/QE controllers need care the alignement requirement.
If you don't care the performance, you can malloc memory to get the aligned buffer pool in the initiaize phase, then use the buffer pool to resolve your alignment issue, of course It needs a copy, but it avoids to malloc/free buffer in run-time.
The malloc is only done once - the first time a non-aligned send is done. After that it's just reused until the alignment requirement exceeds the current allocation (if another interface is set as current).
So I think the performance impact is very small.
// Simon

Simon Kagstrom wrote:
On Wed, 19 Aug 2009 16:06:12 +0800 "Liu Dave-R63238" DaveLiu@freescale.com wrote:
Well, that's what the other patch I sent does (the link above), but there were wishes then to handle this above the driver layer, hence this patch :-)
I'm fine with either way, but if there are other drivers with alignment requirements, I'd prefer this variant.
I believe some Freescale's CPM/QE controllers need care the alignement requirement.
If you don't care the performance, you can malloc memory to get the aligned buffer pool in the initiaize phase, then use the buffer pool to resolve your alignment issue, of course It needs a copy, but it avoids to malloc/free buffer in run-time.
The malloc is only done once - the first time a non-aligned send is done. After that it's just reused until the alignment requirement exceeds the current allocation (if another interface is set as current).
So I think the performance impact is very small.
// Simon _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
My preference is for the drivers to handle alignment. I like Dave's idea of creating a buffer (or multiple buffers) in initialization(), then memcpy'ing to to it in the send() routine. You could make it smart to only memcpy if the frame is not aligned as needed.
Your original patch created a buffer of size 9000, which I commented was probably bigger than necessary. I didn't see a response to that (which doesn't mean you didn't send one, but I get a lot of e-mail :)
regards, Ben

On Wed, 19 Aug 2009 09:55:46 -0700 Ben Warren biggerbadderben@gmail.com wrote:
My preference is for the drivers to handle alignment.
OK, I'm fine with that. I'd like to withdraw this patch then.
I like Dave's idea of creating a buffer (or multiple buffers) in initialization(), then memcpy'ing to to it in the send() routine. You could make it smart to only memcpy if the frame is not aligned as needed.
It already only memcpys unaligned buffers, but I'll go with Daves suggestion and allocate it at startup instead.
Your original patch created a buffer of size 9000, which I commented was probably bigger than necessary. I didn't see a response to that (which doesn't mean you didn't send one, but I get a lot of e-mail :)
I was off for vacation [*], so I only sent it this week. I'll rework this patch a bit to address a small bug I found.
Thanks for the comments! // Simon [*] By now the U-boot list is probably tired of hearing about my vacation, but I can assure you that I had a good time!
participants (3)
-
Ben Warren
-
Liu Dave-R63238
-
Simon Kagstrom