net: rtl8169: Properly align buffers
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@nvidia.com> Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: Tom Warren <twarren@nvidia.com>
This commit is contained in:
		
							parent
							
								
									c94bbfdf51
								
							
						
					
					
						commit
						dad3ba0f0b
					
				|  | @ -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  */ | ||||
|  | @ -711,16 +727,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
 | ||||
|  | @ -762,10 +768,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; | ||||
| 	} | ||||
|  | @ -910,6 +912,9 @@ static int rtl_init(struct eth_device *dev, bd_t *bis) | |||
| #endif | ||||
| 	} | ||||
| 
 | ||||
| 	tpc->TxDescArray = tx_ring; | ||||
| 	tpc->RxDescArray = rx_ring; | ||||
| 
 | ||||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue