summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale/gianfar.h
diff options
context:
space:
mode:
authorClaudiu Manoil <claudiu.manoil@freescale.com>2015-07-13 16:22:03 +0300
committerDavid S. Miller <davem@davemloft.net>2015-07-15 17:13:23 -0700
commit76f31e8b0911e620ac9191c8d3775cc91ed65c4c (patch)
tree2e67920867ed291043c11c51e9ac15097edc0c5b /drivers/net/ethernet/freescale/gianfar.h
parentaad0d51e933f8656880592020319d2dbd09532a2 (diff)
downloadtalos-obmc-linux-76f31e8b0911e620ac9191c8d3775cc91ed65c4c.tar.gz
talos-obmc-linux-76f31e8b0911e620ac9191c8d3775cc91ed65c4c.zip
gianfar: Bundle Rx allocation, cleanup
Use a more common consumer/ producer index design to improve rx buffer allocation. Instead of allocating a single new buffer (skb) on each iteration, bundle the allocation of several rx buffers at a time. This also opens the path for further memory optimizations. Remove useless check of rxq->rfbptr, since this patch touches rx pause frame handling code as well. rxq->rfbptr is always initialized as part of Rx BD ring init. Remove redundant (and misleading) 'amount_pull' parameter. Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/freescale/gianfar.h')
-rw-r--r--drivers/net/ethernet/freescale/gianfar.h39
1 files changed, 29 insertions, 10 deletions
diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
index daa1d37de642..cadb068cb37f 100644
--- a/drivers/net/ethernet/freescale/gianfar.h
+++ b/drivers/net/ethernet/freescale/gianfar.h
@@ -92,6 +92,8 @@ extern const char gfar_driver_version[];
#define DEFAULT_TX_RING_SIZE 256
#define DEFAULT_RX_RING_SIZE 256
+#define GFAR_RX_BUFF_ALLOC 16
+
#define GFAR_RX_MAX_RING_SIZE 256
#define GFAR_TX_MAX_RING_SIZE 256
@@ -640,6 +642,7 @@ struct rmon_mib
};
struct gfar_extra_stats {
+ atomic64_t rx_alloc_err;
atomic64_t rx_large;
atomic64_t rx_short;
atomic64_t rx_nonoctet;
@@ -1015,9 +1018,9 @@ struct rx_q_stats {
/**
* struct gfar_priv_rx_q - per rx queue structure
* @rx_skbuff: skb pointers
- * @skb_currx: currently use skb pointer
* @rx_bd_base: First rx buffer descriptor
- * @cur_rx: Next free rx ring entry
+ * @next_to_use: index of the next buffer to be alloc'd
+ * @next_to_clean: index of the next buffer to be cleaned
* @qindex: index of this queue
* @dev: back pointer to the dev structure
* @rx_ring_size: Rx ring size
@@ -1027,19 +1030,18 @@ struct rx_q_stats {
struct gfar_priv_rx_q {
struct sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES);
- dma_addr_t rx_bd_dma_base;
struct rxbd8 *rx_bd_base;
- struct rxbd8 *cur_rx;
struct net_device *dev;
- struct gfar_priv_grp *grp;
+ struct gfar_priv_grp *grp;
+ u16 rx_ring_size;
+ u16 qindex;
+ u16 next_to_clean;
+ u16 next_to_use;
struct rx_q_stats stats;
- u16 skb_currx;
- u16 qindex;
- unsigned int rx_ring_size;
- /* RX Coalescing values */
+ u32 __iomem *rfbptr;
unsigned char rxcoalescing;
unsigned long rxic;
- u32 __iomem *rfbptr;
+ dma_addr_t rx_bd_dma_base;
};
enum gfar_irqinfo_id {
@@ -1295,6 +1297,23 @@ static inline void gfar_clear_txbd_status(struct txbd8 *bdp)
bdp->lstatus = cpu_to_be32(lstatus);
}
+static inline int gfar_rxbd_unused(struct gfar_priv_rx_q *rxq)
+{
+ if (rxq->next_to_clean > rxq->next_to_use)
+ return rxq->next_to_clean - rxq->next_to_use - 1;
+
+ return rxq->rx_ring_size + rxq->next_to_clean - rxq->next_to_use - 1;
+}
+
+static inline struct rxbd8 *gfar_rxbd_lastfree(struct gfar_priv_rx_q *rxq)
+{
+ int i;
+
+ i = rxq->next_to_use ? rxq->next_to_use - 1 : rxq->rx_ring_size - 1;
+
+ return &rxq->rx_bd_base[i];
+}
+
irqreturn_t gfar_receive(int irq, void *dev_id);
int startup_gfar(struct net_device *dev);
void stop_gfar(struct net_device *dev);
OpenPOWER on IntegriCloud