[U-Boot] [PATCH v2 38/40] net: rtl8169: Properly align buffers
Nobuhiro Iwamatsu
nobuhiro.iwamatsu.yj at renesas.com
Thu Nov 13 00:37:33 CET 2014
Hi,
I tested on sh7785lcr board with this patch.
This worked without any problems. Thanks.
2014-08-27 0:34 GMT+09:00 Thierry Reding <thierry.reding at gmail.com>:
> From: Thierry Reding <treding at nvidia.com>
>
> RX and TX descriptor rings should be aligned to 256 byte boundaries. Use
> the DEFINE_ALIGN_BUFFER() macro to define the buffers so that they don't
> have to be manually aligned later on. Also make sure that the buffers do
> align to cache-line boundaries in case the cache-line is higher than the
> 256 byte alignment requirements of the NIC.
>
> Also add a warning if the cache-line size is larger than the descriptor
> size, because the driver may discard changes to descriptors made by the
> hardware when requeuing RX buffers.
>
> Signed-off-by: Thierry Reding <treding at nvidia.com>
> ---
> Changes in v2:
> - make cache-line vs. descriptor size a compile-time warning
Tested-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj at renesas.com>
>
> drivers/net/rtl8169.c | 63 +++++++++++++++++++++++++++------------------------
> 1 file changed, 34 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
> index c3eb474f0fba..d81ee8af1cc1 100644
> --- a/drivers/net/rtl8169.c
> +++ b/drivers/net/rtl8169.c
> @@ -277,23 +277,41 @@ struct RxDesc {
> u32 buf_Haddr;
> };
>
> -/* Define the TX Descriptor */
> -static u8 tx_ring[NUM_TX_DESC * sizeof(struct TxDesc) + 256];
> -/* __attribute__ ((aligned(256))); */
> +#define RTL8169_DESC_SIZE 16
>
> -/* Create a static buffer of size RX_BUF_SZ for each
> -TX Descriptor. All descriptors point to a
> -part of this buffer */
> -static unsigned char txb[NUM_TX_DESC * RX_BUF_SIZE];
> +#if ARCH_DMA_MINALIGN > 256
> +# define RTL8169_ALIGN ARCH_DMA_MINALIGN
> +#else
> +# define RTL8169_ALIGN 256
> +#endif
> +
> +/*
> + * Warn if the cache-line size is larger than the descriptor size. In such
> + * cases the driver will likely fail because the CPU needs to flush the cache
> + * when requeuing RX buffers, therefore descriptors written by the hardware
> + * may be discarded.
> + */
> +#if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN
> +#warning cache-line size is larger than descriptor size
> +#endif
> +
> +/* Define the TX Descriptor */
> +DEFINE_ALIGN_BUFFER(struct TxDesc, tx_ring, NUM_TX_DESC, RTL8169_ALIGN);
>
> /* Define the RX Descriptor */
> -static u8 rx_ring[NUM_RX_DESC * sizeof(struct TxDesc) + 256];
> - /* __attribute__ ((aligned(256))); */
> +DEFINE_ALIGN_BUFFER(struct RxDesc, rx_ring, NUM_RX_DESC, RTL8169_ALIGN);
>
> -/* Create a static buffer of size RX_BUF_SZ for each
> -RX Descriptor All descriptors point to a
> -part of this buffer */
> -static unsigned char rxb[NUM_RX_DESC * RX_BUF_SIZE];
> +/*
> + * Create a static buffer of size RX_BUF_SZ for each TX Descriptor. All
> + * descriptors point to a part of this buffer.
> + */
> +DEFINE_ALIGN_BUFFER(u8, txb, NUM_TX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
> +
> +/*
> + * Create a static buffer of size RX_BUF_SZ for each RX Descriptor. All
> + * descriptors point to a part of this buffer.
> + */
> +DEFINE_ALIGN_BUFFER(u8, rxb, NUM_RX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
>
> struct rtl8169_private {
> void *mmio_addr; /* memory map physical address */
> @@ -301,8 +319,6 @@ struct rtl8169_private {
> unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
> unsigned long cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
> unsigned long dirty_tx;
> - unsigned char *TxDescArrays; /* Index of Tx Descriptor buffer */
> - unsigned char *RxDescArrays; /* Index of Rx Descriptor buffer */
> struct TxDesc *TxDescArray; /* Index of 256-alignment Tx Descriptor buffer */
> struct RxDesc *RxDescArray; /* Index of 256-alignment Rx Descriptor buffer */
> unsigned char *RxBufferRings; /* Index of Rx Buffer */
> @@ -710,16 +726,6 @@ static int rtl_reset(struct eth_device *dev, bd_t *bis)
> printf ("%s\n", __FUNCTION__);
> #endif
>
> - tpc->TxDescArrays = tx_ring;
> - /* Tx Desscriptor needs 256 bytes alignment; */
> - tpc->TxDescArray = (struct TxDesc *) ((unsigned long)(tpc->TxDescArrays +
> - 255) & ~255);
> -
> - tpc->RxDescArrays = rx_ring;
> - /* Rx Desscriptor needs 256 bytes alignment; */
> - tpc->RxDescArray = (struct RxDesc *) ((unsigned long)(tpc->RxDescArrays +
> - 255) & ~255);
> -
> rtl8169_init_ring(dev);
> rtl8169_hw_start(dev);
> /* Construct a perfect filter frame with the mac address as first match
> @@ -761,10 +767,6 @@ static void rtl_halt(struct eth_device *dev)
>
> RTL_W32(RxMissed, 0);
>
> - tpc->TxDescArrays = NULL;
> - tpc->RxDescArrays = NULL;
> - tpc->TxDescArray = NULL;
> - tpc->RxDescArray = NULL;
> for (i = 0; i < NUM_RX_DESC; i++) {
> tpc->RxBufferRing[i] = NULL;
> }
> @@ -909,6 +911,9 @@ static int rtl_init(struct eth_device *dev, bd_t *bis)
> #endif
> }
>
> + tpc->TxDescArray = tx_ring;
> + tpc->RxDescArray = rx_ring;
> +
> return 1;
> }
>
> --
> 2.0.4
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
--
Nobuhiro Iwamatsu
More information about the U-Boot
mailing list