Commit 75354148 authored by Claudiu Manoil's avatar Claudiu Manoil Committed by David S. Miller

gianfar: Add paged allocation and Rx S/G

The eTSEC h/w is capable of scatter/gather on the receive side
too if MAXFRM > MRBLR, when the allowed maximum Rx frame size
is set to be greater than the maximum Rx buffer size (MRBLR).
It's about time the driver makes use of this h/w capability,
by supporting fixed buffer sizes and Rx S/G.

The buffer size given to eTSEC for reception is fixed to
1536B (must be multiple of 64), which is the same default
buffer size as before, used to accommodate standard MTU
(1500B) size frames.  As before, eTSEC can receive frames of
up to 9600B.  Individual Rx buffers are mapped to page halves
(page size for eTSEC systems is 4KB).  The skb is built around
the first buffer of a frame (using build_skb()).  In case the
frame spans multiple buffers, the trailing buffers are added
as Rx fragments to the skb.  The last buffer in frame is marked
by the L status flag.  A mechanism is in place to reuse the pages
owned by the driver (for Rx) for subsequent receptions.

Supporting fixed size buffers allows the implementation of Rx S/G,
which in turn removes the memory pressure issues the driver had
before when MTU was set for jumbo frame reception.
Also, in most cases, the Rx path becomes faster due to Rx page
reusal, since the overhead of allocating new rx buffers is removed
from the fast path.
Signed-off-by: default avatarClaudiu Manoil <claudiu.manoil@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f23223f1
This diff is collapsed.
...@@ -71,11 +71,6 @@ struct ethtool_rx_list { ...@@ -71,11 +71,6 @@ struct ethtool_rx_list {
/* Number of bytes to align the rx bufs to */ /* Number of bytes to align the rx bufs to */
#define RXBUF_ALIGNMENT 64 #define RXBUF_ALIGNMENT 64
/* The number of bytes which composes a unit for the purpose of
* allocating data buffers. ie-for any given MTU, the data buffer
* will be the next highest multiple of 512 bytes. */
#define INCREMENTAL_BUFFER_SIZE 512
#define PHY_INIT_TIMEOUT 100000 #define PHY_INIT_TIMEOUT 100000
#define DRV_NAME "gfar-enet" #define DRV_NAME "gfar-enet"
...@@ -105,11 +100,14 @@ extern const char gfar_driver_version[]; ...@@ -105,11 +100,14 @@ extern const char gfar_driver_version[];
#define DEFAULT_RX_LFC_THR 16 #define DEFAULT_RX_LFC_THR 16
#define DEFAULT_LFC_PTVVAL 4 #define DEFAULT_LFC_PTVVAL 4
#define DEFAULT_RX_BUFFER_SIZE 1536 #define GFAR_RXB_SIZE 1536
#define GFAR_SKBFRAG_SIZE (RXBUF_ALIGNMENT + GFAR_RXB_SIZE \
+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
#define GFAR_RXB_TRUESIZE 2048
#define TX_RING_MOD_MASK(size) (size-1) #define TX_RING_MOD_MASK(size) (size-1)
#define RX_RING_MOD_MASK(size) (size-1) #define RX_RING_MOD_MASK(size) (size-1)
#define JUMBO_BUFFER_SIZE 9728 #define GFAR_JUMBO_FRAME_SIZE 9600
#define JUMBO_FRAME_SIZE 9600
#define DEFAULT_FIFO_TX_THR 0x100 #define DEFAULT_FIFO_TX_THR 0x100
#define DEFAULT_FIFO_TX_STARVE 0x40 #define DEFAULT_FIFO_TX_STARVE 0x40
...@@ -654,7 +652,6 @@ struct gfar_extra_stats { ...@@ -654,7 +652,6 @@ struct gfar_extra_stats {
atomic64_t eberr; atomic64_t eberr;
atomic64_t tx_babt; atomic64_t tx_babt;
atomic64_t tx_underrun; atomic64_t tx_underrun;
atomic64_t rx_skbmissing;
atomic64_t tx_timeout; atomic64_t tx_timeout;
}; };
...@@ -1015,9 +1012,15 @@ struct rx_q_stats { ...@@ -1015,9 +1012,15 @@ struct rx_q_stats {
unsigned long rx_dropped; unsigned long rx_dropped;
}; };
struct gfar_rx_buff {
dma_addr_t dma;
struct page *page;
unsigned int page_offset;
};
/** /**
* struct gfar_priv_rx_q - per rx queue structure * struct gfar_priv_rx_q - per rx queue structure
* @rx_skbuff: skb pointers * @rx_buff: Array of buffer info metadata structs
* @rx_bd_base: First rx buffer descriptor * @rx_bd_base: First rx buffer descriptor
* @next_to_use: index of the next buffer to be alloc'd * @next_to_use: index of the next buffer to be alloc'd
* @next_to_clean: index of the next buffer to be cleaned * @next_to_clean: index of the next buffer to be cleaned
...@@ -1029,14 +1032,17 @@ struct rx_q_stats { ...@@ -1029,14 +1032,17 @@ struct rx_q_stats {
*/ */
struct gfar_priv_rx_q { struct gfar_priv_rx_q {
struct sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES); struct gfar_rx_buff *rx_buff __aligned(SMP_CACHE_BYTES);
struct rxbd8 *rx_bd_base; struct rxbd8 *rx_bd_base;
struct net_device *ndev; struct net_device *ndev;
struct gfar_priv_grp *grp; struct device *dev;
u16 rx_ring_size; u16 rx_ring_size;
u16 qindex; u16 qindex;
struct gfar_priv_grp *grp;
u16 next_to_clean; u16 next_to_clean;
u16 next_to_use; u16 next_to_use;
u16 next_to_alloc;
struct sk_buff *skb;
struct rx_q_stats stats; struct rx_q_stats stats;
u32 __iomem *rfbptr; u32 __iomem *rfbptr;
unsigned char rxcoalescing; unsigned char rxcoalescing;
...@@ -1111,7 +1117,6 @@ struct gfar_private { ...@@ -1111,7 +1117,6 @@ struct gfar_private {
struct device *dev; struct device *dev;
struct net_device *ndev; struct net_device *ndev;
enum gfar_errata errata; enum gfar_errata errata;
unsigned int rx_buffer_size;
u16 uses_rxfcb; u16 uses_rxfcb;
u16 padding; u16 padding;
......
...@@ -74,7 +74,6 @@ static const char stat_gstrings[][ETH_GSTRING_LEN] = { ...@@ -74,7 +74,6 @@ static const char stat_gstrings[][ETH_GSTRING_LEN] = {
"ethernet-bus-error", "ethernet-bus-error",
"tx-babbling-errors", "tx-babbling-errors",
"tx-underrun-errors", "tx-underrun-errors",
"rx-skb-missing-errors",
"tx-timeout-errors", "tx-timeout-errors",
/* rmon stats */ /* rmon stats */
"tx-rx-64-frames", "tx-rx-64-frames",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment