[email protected] writes:

> From: Steve Chen <[email protected]>
>
> The skb data allocated for packet data received is 4 byte aligned.
>
> Unfortunately, this causes non-32bit aligned accesses in IP stack because
> the MAC header is non-word aligned (14 bytes).
>
> The result can be observed by looking at /proc/cpu/alignment while the
> device is over network.
>
> This issue is resolved by using a 2-byte extra offset in the packet buffer.
>
> A quick performance test over lab network using iperf on DM6446 EVM showed
> an increase in bandwidth from 60Mbits/s to 70Mbits/s.
>
> Signed-off-by: Steve Chen <[email protected]>
> Signed-off-by: Sekhar Nori <[email protected]>

Nori,

What are the plans to submit this driver to netdev?  I'd like to see
this driver submitted upstream and thes kinds of issues being sorted
out on the netdev list.

Also, I thought you were planning to use NET_IP_ALIGN?

Kevin

> ---
>  drivers/net/davinci_emac.c |   21 +++++++++++++++++----
>  1 files changed, 17 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
> index 635e31f..471126a 100644
> --- a/drivers/net/davinci_emac.c
> +++ b/drivers/net/davinci_emac.c
> @@ -349,6 +349,15 @@ static const char emac_version_string[] = "TI DaVinci 
> EMAC Linux v6.0";
>  #define EMAC_DM646X_MAC_EOI_C0_RXEN  (0x01)
>  #define EMAC_DM646X_MAC_EOI_C0_TXEN  (0x02)
>  
> +/*
> + * L3 Alignment mechanism: The below given macro returns the number of
> + * bytes required to align the given size to a L3 frame 4 byte
> + * boundry. This is typically required to add 2 bytes to the ethernet
> + * frame start to make sure the IP header (L3) is aligned on a 4 byte
> + * boundry
> + */
> +#define EMAC_L3_ALIGN(size)    ((2 - (size)) & 0x3)
> +
>
>  /** net_buf_obj: EMAC network bufferdata structure
>   *
>   * EMAC network buffer data structure
> @@ -1560,7 +1569,8 @@ static void *emac_net_alloc_rx_buf(struct emac_priv 
> *priv, int buf_size,
>  
>       /* set device pointer in skb and reserve space for extra bytes */
>       p_skb->dev = ndev;
> -     skb_reserve(p_skb, EMAC_DEF_EXTRA_RXBUF_SIZE);
> +     skb_reserve(p_skb, EMAC_DEF_EXTRA_RXBUF_SIZE +
> +                 EMAC_L3_ALIGN(EMAC_DEF_EXTRA_RXBUF_SIZE));
>       *data_token = (void *) p_skb;
>       EMAC_CACHE_WRITEBACK_INVALIDATE((unsigned long)p_skb->data, buf_size);
>       return p_skb->data;
> @@ -1990,8 +2000,9 @@ static int emac_rx_bdproc(struct emac_priv *priv, u32 
> ch, u32 budget,
>              (pkts_processed < budget)) {
>  
>               new_buffer = emac_net_alloc_rx_buf(priv,
> -                                     EMAC_DEF_MAX_FRAME_SIZE,
> -                                     &new_buf_token, EMAC_DEF_RX_CH);
> +                             EMAC_DEF_MAX_FRAME_SIZE +
> +                             EMAC_L3_ALIGN(EMAC_DEF_EXTRA_RXBUF_SIZE),
> +                             &new_buf_token, EMAC_DEF_RX_CH);
>               if (unlikely(NULL == new_buffer)) {
>                       ++rxch->out_of_rx_buffers;
>                       goto end_emac_rx_bdproc;
> @@ -2411,7 +2422,9 @@ static int emac_dev_open(struct net_device *ndev)
>               ndev->dev_addr[cnt] = priv->mac_addr[cnt];
>  
>       /* Configuration items */
> -     priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE + EMAC_DEF_EXTRA_RXBUF_SIZE;
> +     priv->rx_buf_size = EMAC_DEF_MAX_FRAME_SIZE +
> +                         EMAC_DEF_EXTRA_RXBUF_SIZE +
> +                         EMAC_L3_ALIGN(EMAC_DEF_EXTRA_RXBUF_SIZE);
>  
>       /* Clear basic hardware */
>       for (ch = 0; ch < EMAC_MAX_TXRX_CHANNELS; ch++) {
> -- 
> 1.6.0.3
>
> _______________________________________________
> Davinci-linux-open-source mailing list
> [email protected]
> http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to