[U-Boot] [PATCH] arm:kirkwood See to it that sent data is 8-byte aligned

See to it that sent data is 8-byte aligned
U-boot might use non-8-byte-aligned addresses for sending data, which the kwgbe_send doesn't accept (bootp does this for me). This patch copies the data to be sent to a malloced temporary buffer if it is non-aligned.
v2: Malloc send buffer (comment from Stefan Roese) v3: No need to use jumbo frames, use 1518 bytes buffer instead (comment from Ben Warren)
Signed-off-by: Simon Kagstrom simon.kagstrom@netinsight.net --- drivers/net/kirkwood_egiga.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c index f31fefc..6627412 100644 --- a/drivers/net/kirkwood_egiga.c +++ b/drivers/net/kirkwood_egiga.c @@ -481,24 +481,42 @@ static int kwgbe_halt(struct eth_device *dev) return 0; }
+#define KWGBE_SEND_BUF_SIZE 1518 static int kwgbe_send(struct eth_device *dev, volatile void *dataptr, int datasize) { struct kwgbe_device *dkwgbe = to_dkwgbe(dev); struct kwgbe_registers *regs = dkwgbe->regs; struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc; + void *p = (void *)dataptr; u32 cmd_sts;
+ /* Copy buffer if it's misaligned */ if ((u32) dataptr & 0x07) { - printf("Err..(%s) xmit dataptr not 64bit aligned\n", - __FUNCTION__); - return -1; + static void *aligned_buf; + + if (!aligned_buf) + aligned_buf = memalign(sizeof(u32), + KWGBE_SEND_BUF_SIZE); + if (!aligned_buf) { + printf("Err...(%s): Cannot allocate aligned buffer\n", + __FUNCTION__); + return -1; + } + if (datasize > KWGBE_SEND_BUF_SIZE) { + printf("Err..(%s) Non-aligned data too large (%d)\n", + __FUNCTION__, datasize); + return -1; + } + memcpy(aligned_buf, p, datasize); + p = aligned_buf; } + p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC; p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC; p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA; p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT; - p_txdesc->buf_ptr = (u8 *) dataptr; + p_txdesc->buf_ptr = (u8 *) p; p_txdesc->byte_cnt = datasize;
/* Apply send command using zeroth RXUQ */

-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot-bounces@lists.denx.de] On Behalf Of Simon Kagstrom Sent: Tuesday, August 18, 2009 3:02 PM To: U-Boot ML Subject: [U-Boot] [PATCH] arm:kirkwood See to it that sent data is 8-byte aligned
See to it that sent data is 8-byte aligned
U-boot might use non-8-byte-aligned addresses for sending data, which the kwgbe_send doesn't accept (bootp does this for me). This patch copies the data to be sent to a malloced temporary buffer if it is non-aligned.
v2: Malloc send buffer (comment from Stefan Roese)
Malloc will always be an overhead. I strongly recommend- we should pass aligned buffers from upper layers to avoid such rework in all low level drivers, (few are already aligned).
v3: No need to use jumbo frames, use 1518 bytes buffer instead
Better to use PKTSIZE_ALIGN here, avoid magic numbers
(comment from Ben Warren)
Signed-off-by: Simon Kagstrom simon.kagstrom@netinsight.net
drivers/net/kirkwood_egiga.c | 26 ++++++++++++++++++++++---- 1 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/drivers/net/kirkwood_egiga.c b/drivers/net/kirkwood_egiga.c index f31fefc..6627412 100644 --- a/drivers/net/kirkwood_egiga.c +++ b/drivers/net/kirkwood_egiga.c @@ -481,24 +481,42 @@ static int kwgbe_halt(struct eth_device *dev) return 0; }
+#define KWGBE_SEND_BUF_SIZE 1518
Better to use PKTSIZE_ALIGN here, avoid magic numbers Regards.. Prafulla . .

Thanks for the review Prafulla!
On Tue, 18 Aug 2009 03:12:07 -0700 Prafulla Wadaskar prafulla@marvell.com wrote:
v2: Malloc send buffer (comment from Stefan Roese)
Malloc will always be an overhead.
It's only allocated once (the first time a non-aligned buffer is passed), so the overhead is minimal.
I strongly recommend- we should pass aligned buffers from upper layers to avoid such rework in all low level drivers, (few are already aligned).
We could put the same fix in eth_send instead. Then the issue is really just how we know what alignment requirement to go for. I guess one could add a field to the eth_device structure to store this and then fixup all drivers to supply this.
If the rest of you thinks this is a good idea, I can cook up a patch. Opinions?
v3: No need to use jumbo frames, use 1518 bytes buffer instead
Better to use PKTSIZE_ALIGN here, avoid magic numbers
OK, I'll fix that.
Thanks, // Simon

On 12:48 Tue 18 Aug , Simon Kagstrom wrote:
Thanks for the review Prafulla!
On Tue, 18 Aug 2009 03:12:07 -0700 Prafulla Wadaskar prafulla@marvell.com wrote:
v2: Malloc send buffer (comment from Stefan Roese)
Malloc will always be an overhead.
It's only allocated once (the first time a non-aligned buffer is passed), so the overhead is minimal.
I strongly recommend- we should pass aligned buffers from upper layers to avoid such rework in all low level drivers, (few are already aligned).
We could put the same fix in eth_send instead. Then the issue is really just how we know what alignment requirement to go for. I guess one could add a field to the eth_device structure to store this and then fixup all drivers to supply this.
If the rest of you thinks this is a good idea, I can cook up a patch. Opinions?
some drivers would also have the possibility to have multiple receive buffer specially when you use dma so IMHO it make more sense to let each drivers handle it itself
Best Regards, J.

-----Original Message----- From: Jean-Christophe PLAGNIOL-VILLARD [mailto:plagnioj@jcrosoft.com] Sent: Thursday, August 20, 2009 4:07 AM To: Simon Kagstrom Cc: Prafulla Wadaskar; U-Boot ML; Prabhanjan Sarnaik; Ashish Karkare Subject: Re: [U-Boot] [PATCH] arm:kirkwood See to it that sent data is 8-byte aligned
On 12:48 Tue 18 Aug , Simon Kagstrom wrote:
Thanks for the review Prafulla!
On Tue, 18 Aug 2009 03:12:07 -0700 Prafulla Wadaskar prafulla@marvell.com wrote:
v2: Malloc send buffer (comment from Stefan Roese)
Malloc will always be an overhead.
It's only allocated once (the first time a non-aligned buffer is passed), so the overhead is minimal.
I strongly recommend- we should pass aligned buffers from
upper layers
to avoid such rework in all low level drivers, (few are already aligned).
We could put the same fix in eth_send instead. Then the
issue is really
just how we know what alignment requirement to go for. I guess one could add a field to the eth_device structure to store this and then fixup all drivers to supply this.
If the rest of you thinks this is a good idea, I can cook
up a patch.
Opinions?
some drivers would also have the possibility to have multiple receive buffer specially when you use dma so IMHO it make more sense to let each drivers handle it itself
In that case it makes more sense to implement this even for rx path too in upper layer. We should always push common functionalities to upper layers And this is very generic need for any driver that uses dma for transfers
Regards.. Prafulla . .
Best Regards, J.

On Tue, 18 Aug 2009 11:32:06 +0200 Simon Kagstrom simon.kagstrom@netinsight.net wrote:
- /* Copy buffer if it's misaligned */ if ((u32) dataptr & 0x07) {
printf("Err..(%s) xmit dataptr not 64bit aligned\n",
__FUNCTION__);
return -1;
static void *aligned_buf;
if (!aligned_buf)
aligned_buf = memalign(sizeof(u32),
KWGBE_SEND_BUF_SIZE);
The memalign requests the wrong alignment here. I'll send a new patch unless the consensus is to prefer the other variant ("[PATCH] net: See to it that sent data is aligned to the ethernet controllers wishes").
// Simon
participants (3)
-
Jean-Christophe PLAGNIOL-VILLARD
-
Prafulla Wadaskar
-
Simon Kagstrom