net: stmmac: adding multiple buffers
Subsystems (4)
v2 cover net: stmmac: adding multiple buffers
This patch adds multiple buffers to stmmac in a more fragmented way, in order to make problem debug easier.
I would kindly request to people to test this patch in their HWs in order to check if everything's functional. Thank you.
Joao Pinto (4):
net: stmmac: break some functions into RX and TX scopes
net: stmmac: adding multiple buffers for RX
net: stmmac: adding multiple buffers for TX
net: stmmac: adding multiple napi mechanism
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 45 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 49 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1257 ++++++++++++++------- 4 files changed, 947 insertions(+), 450 deletions(-)
Signature · 1 line
2.9.3
PATCH v2 1/4 net: stmmac: break some functions into RX and TX scopes
This patch breaks several functions into RX and TX scopes, which will be useful when adding multiple buffers mechanism.
---
changes v1->v2:
- RX and TX inconsistency
- stmmac_free_rx_buffers renamed to stmmac_free_rx_buffer
- stmmac_free_tx_buffers renamed to stmmac_free_tx_buffer
- some useless comments were removed
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 352 ++++++++++++++++------ 1 file changed, 266 insertions(+), 86 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +266 -86
@@ -889,24 +889,41 @@ static int stmmac_init_phy(struct net_device *dev)return 0 ; } -static void stmmac_display_rings (struct stmmac_priv *priv) +static void stmmac_display_rx_rings (struct stmmac_priv *priv) { -void *head_rx, *head_tx; +void *head_rx; -if (priv->extend_desc) { +if (priv->extend_desc) head_rx = (void *)priv->dma_erx; - head_tx = (void *)priv->dma_etx; - }else { +else head_rx = (void *)priv->dma_rx; - head_tx = (void *)priv->dma_tx; - } -/* Display Rx ring */ +/* Display RX ring */ priv->hw->desc->display_ring (head_rx,DMA_RX_SIZE , true); -/* Display Tx ring */ +} + +static void stmmac_display_tx_rings (struct stmmac_priv *priv) +{ +void *head_tx; + +if (priv->extend_desc) + head_tx = (void *)priv->dma_etx; +else + head_tx = (void *)priv->dma_tx; + +/* Display TX ring */ priv->hw->desc->display_ring (head_tx,DMA_TX_SIZE , false); } +static void stmmac_display_rings (struct stmmac_priv *priv) +{ +/* Display RX ring */ +stmmac_display_rx_rings (priv); + +/* Display TX ring */ +stmmac_display_tx_rings (priv); +} +static int stmmac_set_bfsize (int mtu,int bufsize) {int ret = bufsize;
@@ -924,16 +941,16 @@ static int stmmac_set_bfsize(int mtu, int bufsize) }/** -* stmmac_clear_descriptors - clear descriptors +* stmmac_clear_rx_descriptors - clear RX descriptors * @priv: driver private structure -* Description: this function is called to clear the tx and rx descriptors +* Description: this function is called to clear the RX descriptors * in case of both basic and extended descriptors are used. */ -static void stmmac_clear_descriptors (struct stmmac_priv *priv) +static void stmmac_clear_rx_descriptors (struct stmmac_priv *priv) {int i; -/* Clear the Rx/Tx descriptors */ +/* Clear the RX descriptors */ for (i =0 ; i <DMA_RX_SIZE ; i++)if (priv->extend_desc) priv->hw->desc->init_rx_desc(&priv->dma_erx[i].basic,
@@ -943,6 +960,19 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv) priv->hw->desc->init_rx_desc (&priv->dma_rx[i], priv->use_riwt, priv->mode, (i ==DMA_RX_SIZE -1 )); +} + +/** +* stmmac_clear_tx_descriptors - clear tx descriptors +* @priv: driver private structure +* Description: this function is called to clear the TX descriptors +* in case of both basic and extended descriptors are used. +*/ +static void stmmac_clear_tx_descriptors (struct stmmac_priv *priv) +{ +int i; + +/* Clear the TX descriptors */ for (i =0 ; i <DMA_TX_SIZE ; i++)if (priv->extend_desc) priv->hw->desc->init_tx_desc(&priv->dma_etx[i].basic,
@@ -955,6 +985,21 @@ static void stmmac_clear_descriptors(struct stmmac_priv *priv) }/** +* stmmac_clear_descriptors - clear descriptors +* @priv: driver private structure +* Description: this function is called to clear the TX and RX descriptors +* in case of both basic and extended descriptors are used. +*/ +static void stmmac_clear_descriptors (struct stmmac_priv *priv) +{ +/* Clear the RX descriptors */ +stmmac_clear_rx_descriptors (priv); + +/* Clear the TX descriptors */ +stmmac_clear_tx_descriptors (priv); +} + +/** * stmmac_init_rx_buffers - init the RX descriptor buffer. * @priv: driver private structure * @p: descriptor pointer
@@ -996,7 +1041,12 @@ static int stmmac_init_rx_buffers(struct stmmac_priv *priv, struct dma_desc *p,return 0 ; } -static void stmmac_free_rx_buffers (struct stmmac_priv *priv,int i) +/** +* stmmac_free_rx_buffer - free RX dma buffers +* @priv: private structure +* @i: buffer index. +*/ +static void stmmac_free_rx_buffer (struct stmmac_priv *priv,int i) {if (priv->rx_skbuff[i]) { dma_unmap_single(priv->device, priv->rx_skbuff_dma[i],
@@ -1007,14 +1057,42 @@ static void stmmac_free_rx_buffers(struct stmmac_priv *priv, int i) }/** -* init_dma_desc_rings - init the RX/TX descriptor rings +* stmmac_free_tx_buffer - free RX dma buffers +* @priv: private structure +* @i: buffer index. +*/ +static void stmmac_free_tx_buffer (struct stmmac_priv *priv,int i) +{ +if (priv->tx_skbuff_dma[i].buf) { +if (priv->tx_skbuff_dma[i].map_as_page) +dma_unmap_page (priv->device, + priv->tx_skbuff_dma[i].buf, + priv->tx_skbuff_dma[i].len, +DMA_TO_DEVICE ); +else +dma_unmap_single (priv->device, + priv->tx_skbuff_dma[i].buf, + priv->tx_skbuff_dma[i].len, +DMA_TO_DEVICE ); + } + +if (priv->tx_skbuff[i]) { +dev_kfree_skb_any (priv->tx_skbuff[i]); + priv->tx_skbuff[i] =NULL ; + priv->tx_skbuff_dma[i].buf =0 ; + priv->tx_skbuff_dma[i].map_as_page = false; + } +} + +/** +* init_dma_rx_desc_rings - init the RX descriptor rings * @dev: net device structure * @flags: gfp flag. -* Description: this function initializes the DMA RX/TX descriptors +* Description: this function initializes the DMA RX descriptors * and allocates the socket buffers. It supports the chained and ring * modes. */ -static int init_dma_desc_rings (struct net_device *dev,gfp_t flags) +static int init_dma_rx_desc_rings (struct net_device *dev,gfp_t flags) {int i;struct stmmac_priv *priv =netdev_priv (dev);
@@ -1030,10 +1108,8 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) priv->dma_buf_sz = bfsize;netif_dbg (priv, probe, priv->dev, -"(%s) dma_rx_phy=0x%08x dma_tx_phy=0x%08x\n" , - __func__, (u32 )priv->dma_rx_phy, (u32 )priv->dma_tx_phy); +"(%s) dma_rx_phy=0x%08x\n" , __func__, (u32 )priv->dma_rx_phy); -/* RX INITIALIZATION */ netif_dbg (priv, probe, priv->dev,"SKB addresses:\nskb\t\tskb data\tdma data\n" );
@@ -1058,20 +1134,46 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags)/* Setup the chained descriptor addresses */ if (priv->mode ==STMMAC_CHAIN_MODE ) { -if (priv->extend_desc) { +if (priv->extend_desc) priv->hw->mode->init (priv->dma_erx, priv->dma_rx_phy,DMA_RX_SIZE ,1 ); - priv->hw->mode->init (priv->dma_etx, priv->dma_tx_phy, -DMA_TX_SIZE ,1 ); - }else { +else priv->hw->mode->init (priv->dma_rx, priv->dma_rx_phy,DMA_RX_SIZE ,0 ); + } + +return 0 ; +err_init_rx_buffers: +while (--i >=0 ) +stmmac_free_rx_buffer (priv, i); +return ret; +} + +/** +* init_dma_tx_desc_rings - init the TX descriptor rings +* @dev: net device structure. +* Description: this function initializes the DMA TX descriptors +* and allocates the socket buffers. It supports the chained and ring +* modes. +*/ +static int init_dma_tx_desc_rings (struct net_device *dev) +{ +struct stmmac_priv *priv =netdev_priv (dev); +int i; + +netif_dbg (priv, probe, priv->dev, +"(%s) dma_tx_phy=0x%08x\n" , __func__, (u32 )priv->dma_tx_phy); + +/* Setup the chained descriptor addresses */ +if (priv->mode ==STMMAC_CHAIN_MODE ) { +if (priv->extend_desc) + priv->hw->mode->init (priv->dma_etx, priv->dma_tx_phy, +DMA_TX_SIZE ,1 ); +else priv->hw->mode->init (priv->dma_tx, priv->dma_tx_phy,DMA_TX_SIZE ,0 ); - } } -/* TX INITIALIZATION */ for (i =0 ; i <DMA_TX_SIZE ; i++) {struct dma_desc *p;if (priv->extend_desc)
@@ -1099,62 +1201,69 @@ static int init_dma_desc_rings(struct net_device *dev, gfp_t flags) priv->cur_tx =0 ;netdev_reset_queue (priv->dev); +return 0 ; +} + +/** +* init_dma_desc_rings - init the RX/TX descriptor rings +* @dev: net device structure +* @flags: gfp flag. +* Description: this function initializes the DMA RX/TX descriptors +* and allocates the socket buffers. It supports the chained and ring +* modes. +*/ +static int init_dma_desc_rings (struct net_device *dev,gfp_t flags) +{ +struct stmmac_priv *priv =netdev_priv (dev); +int ret; + + ret =init_dma_rx_desc_rings (dev, flags); +if (ret) +return ret; + + ret =init_dma_tx_desc_rings (dev); +stmmac_clear_descriptors (priv);if (netif_msg_hw (priv))stmmac_display_rings (priv); -return 0 ; -err_init_rx_buffers: -while (--i >=0 ) -stmmac_free_rx_buffers (priv, i);return ret; } +/** +* dma_free_rx_skbufs - free RX dma buffers +* @priv: private structure +*/ static void dma_free_rx_skbufs (struct stmmac_priv *priv) {int i;for (i =0 ; i <DMA_RX_SIZE ; i++) -stmmac_free_rx_buffers (priv, i); +stmmac_free_rx_buffer (priv, i); } +/** +* dma_free_tx_skbufs - free TX dma buffers +* @priv: private structure +*/ static void dma_free_tx_skbufs (struct stmmac_priv *priv) {int i; -for (i =0 ; i <DMA_TX_SIZE ; i++) { -if (priv->tx_skbuff_dma[i].buf) { -if (priv->tx_skbuff_dma[i].map_as_page) -dma_unmap_page (priv->device, - priv->tx_skbuff_dma[i].buf, - priv->tx_skbuff_dma[i].len, -DMA_TO_DEVICE ); -else -dma_unmap_single (priv->device, - priv->tx_skbuff_dma[i].buf, - priv->tx_skbuff_dma[i].len, -DMA_TO_DEVICE ); - } - -if (priv->tx_skbuff[i]) { -dev_kfree_skb_any (priv->tx_skbuff[i]); - priv->tx_skbuff[i] =NULL ; - priv->tx_skbuff_dma[i].buf =0 ; - priv->tx_skbuff_dma[i].map_as_page = false; - } - } +for (i =0 ; i <DMA_TX_SIZE ; i++) +stmmac_free_tx_buffer (priv, i); }/** -* alloc_dma_desc_resources - alloc TX/RX resources. +* alloc_dma_rx_desc_resources - alloc RX resources. * @priv: private structure * Description: according to which descriptor can be used (extend or basic) * this function allocates the resources for TX and RX paths. In case of * reception, for example, it pre-allocated the RX socket buffer in order to * allow zero-copy mechanism. */ -static int alloc_dma_desc_resources (struct stmmac_priv *priv) +static int alloc_dma_rx_desc_resources (struct stmmac_priv *priv) {int ret = -ENOMEM ;
@@ -1168,11 +1277,50 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv)if (!priv->rx_skbuff) goto err_rx_skbuff; +if (priv->extend_desc) { + priv->dma_erx =dma_zalloc_coherent (priv->device,DMA_RX_SIZE * +sizeof (struct +dma_extended_desc ), + &priv->dma_rx_phy, +GFP_KERNEL ); +if (!priv->dma_erx) + goto err_dma; + + }else { + priv->dma_rx =dma_zalloc_coherent (priv->device,DMA_RX_SIZE * +sizeof (struct dma_desc ), + &priv->dma_rx_phy, +GFP_KERNEL ); +if (!priv->dma_rx) + goto err_dma; + } + +return 0 ; + +err_dma: +kfree (priv->rx_skbuff); +err_rx_skbuff: +kfree (priv->rx_skbuff_dma); +return ret; +} + +/** +* alloc_dma_tx_desc_resources - alloc TX resources. +* @priv: private structure +* Description: according to which descriptor can be used (extend or basic) +* this function allocates the resources for TX and RX paths. In case of +* reception, for example, it pre-allocated the RX socket buffer in order to +* allow zero-copy mechanism. +*/ +static int alloc_dma_tx_desc_resources (struct stmmac_priv *priv) +{ +int ret = -ENOMEM ; + priv->tx_skbuff_dma =kmalloc_array (DMA_TX_SIZE ,sizeof (*priv->tx_skbuff_dma),GFP_KERNEL );if (!priv->tx_skbuff_dma) - goto err_tx_skbuff_dma; +return -ENOMEM ; priv->tx_skbuff =kmalloc_array (DMA_TX_SIZE ,sizeof (struct sk_buff *),GFP_KERNEL );
@@ -1180,14 +1328,6 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv) goto err_tx_skbuff;if (priv->extend_desc) { - priv->dma_erx =dma_zalloc_coherent (priv->device,DMA_RX_SIZE * -sizeof (struct -dma_extended_desc ), - &priv->dma_rx_phy, -GFP_KERNEL ); -if (!priv->dma_erx) - goto err_dma; - priv->dma_etx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * sizeof(struct dma_extended_desc),
@@ -1200,13 +1340,6 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv) goto err_dma; } }else { - priv->dma_rx =dma_zalloc_coherent (priv->device,DMA_RX_SIZE * -sizeof (struct dma_desc ), - &priv->dma_rx_phy, -GFP_KERNEL ); -if (!priv->dma_rx) - goto err_dma; - priv->dma_tx = dma_zalloc_coherent(priv->device, DMA_TX_SIZE * sizeof(struct dma_desc), &priv->dma_tx_phy,
@@ -1225,42 +1358,89 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv)kfree (priv->tx_skbuff); err_tx_skbuff:kfree (priv->tx_skbuff_dma); -err_tx_skbuff_dma: -kfree (priv->rx_skbuff); -err_rx_skbuff: -kfree (priv->rx_skbuff_dma);return ret; } -static void free_dma_desc_resources (struct stmmac_priv *priv) +/** +* alloc_dma_desc_resources - alloc TX/RX resources. +* @priv: private structure +* Description: according to which descriptor can be used (extend or basic) +* this function allocates the resources for TX and RX paths. In case of +* reception, for example, it pre-allocated the RX socket buffer in order to +* allow zero-copy mechanism. +*/ +static int alloc_dma_desc_resources (struct stmmac_priv *priv) { -/* Release the DMA TX/RX socket buffers */ +int ret =alloc_dma_rx_desc_resources (priv); + +if (ret) +return ret; + + ret =alloc_dma_tx_desc_resources (priv); + +return ret; +} + +/** +* free_dma_rx_desc_resources - free RX dma desc resources +* @priv: private structure +*/ +static void free_dma_rx_desc_resources (struct stmmac_priv *priv) +{ +/* Release the DMA RX socket buffers */ dma_free_rx_skbufs (priv); -dma_free_tx_skbufs (priv);/* Free DMA regions of consistent memory previously allocated */ -if (!priv->extend_desc) { -dma_free_coherent (priv->device, -DMA_TX_SIZE *sizeof (struct dma_desc ), - priv->dma_tx, priv->dma_tx_phy); +if (!priv->extend_desc)dma_free_coherent (priv->device,DMA_RX_SIZE *sizeof (struct dma_desc ), priv->dma_rx, priv->dma_rx_phy); - }else { -dma_free_coherent (priv->device,DMA_TX_SIZE * -sizeof (struct dma_extended_desc ), - priv->dma_etx, priv->dma_tx_phy); +else dma_free_coherent (priv->device,DMA_RX_SIZE *sizeof (struct dma_extended_desc ), priv->dma_erx, priv->dma_rx_phy); - } +kfree (priv->rx_skbuff_dma);kfree (priv->rx_skbuff); +} + +/** +* free_dma_tx_desc_resources - free TX dma desc resources +* @priv: private structure +*/ +static void free_dma_tx_desc_resources (struct stmmac_priv *priv) +{ +/* Release the DMA TX socket buffers */ +dma_free_tx_skbufs (priv); + +/* Free DMA regions of consistent memory previously allocated */ +if (!priv->extend_desc) +dma_free_coherent (priv->device, +DMA_TX_SIZE *sizeof (struct dma_desc ), + priv->dma_tx, priv->dma_tx_phy); +else +dma_free_coherent (priv->device,DMA_TX_SIZE * +sizeof (struct dma_extended_desc ), + priv->dma_etx, priv->dma_tx_phy); +kfree (priv->tx_skbuff_dma);kfree (priv->tx_skbuff); }/** +* free_dma_desc_resources - free dma desc resources +* @priv: private structure +*/ +static void free_dma_desc_resources (struct stmmac_priv *priv) +{ +/* Release the DMA RX socket buffers */ +free_dma_rx_desc_resources (priv); + +/* Release the DMA TX socket buffers */ +free_dma_tx_desc_resources (priv); +} + +/** * stmmac_mac_enable_rx_queues - Enable MAC rx queues * @priv: driver private structure * Description: It is used for enabling the rx queues in the MAC
Signature · 1 line
2.9.3
PATCH v2 2/4 net: stmmac: adding multiple buffers for RX
In reply to Joao PintoThis patch adds the structure stmmac_rx_queue which contains rx queues specific data (previously in stmmac_priv).
---
changes v1->v2:
- %d replaced by %u when printing unsigned
- err_init_rx_buffers treatment fixed
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 7 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 26 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 454 ++++++++++++++-------- 3 files changed, 303 insertions(+), 184 deletions(-)
drivers/net/ethernet/stmicro/stmmac/chain_mode.c +4 -3
@@ -136,15 +136,16 @@ static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,static void stmmac_refill_desc3 (void *priv_ptr,struct dma_desc *p) { -struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; +struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)priv_ptr; +struct stmmac_priv *priv = rx_q->priv_data;if (priv->hwts_rx_en && !priv->extend_desc)/* NOTE: Device will overwrite des3 with timestamp value if * 1588-2002 time stamping is enabled, hence reinitialize it * to keep explicit chaining in the descriptor. */ - p->des3 =cpu_to_le32 ((unsigned int )(priv->dma_rx_phy + - (((priv->dirty_rx) +1 ) % + p->des3 =cpu_to_le32 ((unsigned int )(rx_q->dma_rx_phy + + (((rx_q->dirty_rx) +1 ) %DMA_RX_SIZE ) *sizeof (struct dma_desc ))); }
drivers/net/ethernet/stmicro/stmmac/stmmac.h +17 -9
@@ -46,6 +46,20 @@ struct stmmac_tx_info {bool is_jumbo; }; +struct stmmac_rx_queue { +u32 queue_index; +struct stmmac_priv *priv_data; +struct dma_extended_desc *dma_erx; +struct dma_desc *dma_rx____cacheline_aligned_in_smp ; +struct sk_buff **rx_skbuff; +dma_addr_t *rx_skbuff_dma; +unsigned int cur_rx; +unsigned int dirty_rx; +u32 rx_zeroc_thresh; +dma_addr_t dma_rx_phy; +u32 rx_tail_addr; +}; +struct stmmac_priv {/* Frequently used values are kept adjacent for cache effect */ struct dma_extended_desc *dma_etx____cacheline_aligned_in_smp ;
@@ -64,18 +78,10 @@ struct stmmac_priv {struct timer_list txtimer;bool tso; -struct dma_desc *dma_rx____cacheline_aligned_in_smp ; -struct dma_extended_desc *dma_erx; -struct sk_buff **rx_skbuff; -unsigned int cur_rx; -unsigned int dirty_rx;unsigned int dma_buf_sz;unsigned int rx_copybreak; -unsigned int rx_zeroc_thresh;u32 rx_riwt;int hwts_rx_en; -dma_addr_t *rx_skbuff_dma; -dma_addr_t dma_rx_phy;struct napi_struct napi____cacheline_aligned_in_smp ;
@@ -85,6 +91,9 @@ struct stmmac_priv {struct mac_device_info *hw;spinlock_t lock; +/* RX Queue */ +struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES ]; +int oldlink;int speed;int oldduplex;
@@ -119,7 +128,6 @@ struct stmmac_priv {spinlock_t ptp_lock;void __iomem *mmcaddr;void __iomem *ptpaddr; -u32 rx_tail_addr;u32 tx_tail_addr;u32 mss;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +282 -172
831 lines not on this page · raw message
Signature · 1 line
2.9.3
PATCH v2 3/4 net: stmmac: adding multiple buffers for TX
In reply to Joao PintoThis patch adds the structure stmmac_tx_queue which contains tx queues specific data (previously in stmmac_priv).
---
changes v1->v2:
- just to keep up with patch-set version
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 38 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 26 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 519 +++++++++++++--------- 4 files changed, 374 insertions(+), 255 deletions(-)
drivers/net/ethernet/stmicro/stmmac/chain_mode.c +21 -17
@@ -26,12 +26,15 @@static int stmmac_jumbo_frm (void *p,struct sk_buff *skb,int csum) { -struct stmmac_priv *priv = (struct stmmac_priv *)p; -unsigned int entry = priv->cur_tx; -struct dma_desc *desc = priv->dma_tx + entry; +struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;unsigned int nopaged_len =skb_headlen (skb); +struct stmmac_priv *priv = tx_q->priv_data; +unsigned int entry = tx_q->cur_tx;unsigned int bmax, des2;unsigned int i =1 , len; +struct dma_desc *desc; + + desc = tx_q->dma_tx + entry;if (priv->plat->enh_desc) bmax = BUF_SIZE_8KiB;
@@ -45,16 +48,16 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) desc->des2 =cpu_to_le32 (des2);if (dma_mapping_error (priv->device, des2))return -1 ; - priv->tx_skbuff_dma[entry].buf = des2; - priv->tx_skbuff_dma[entry].len = bmax; + tx_q->tx_skbuff_dma[entry].buf = des2; + tx_q->tx_skbuff_dma[entry].len = bmax;/* do not close the descriptor and do not set own bit */ priv->hw->desc->prepare_tx_desc (desc,1 , bmax, csum,STMMAC_CHAIN_MODE ,0 , false);while (len !=0 ) { - priv->tx_skbuff[entry] =NULL ; + tx_q->tx_skbuff[entry] =NULL ; entry =STMMAC_GET_ENTRY (entry,DMA_TX_SIZE ); - desc = priv->dma_tx + entry; + desc = tx_q->dma_tx + entry;if (len > bmax) { des2 = dma_map_single(priv->device,
@@ -63,8 +66,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) desc->des2 =cpu_to_le32 (des2);if (dma_mapping_error (priv->device, des2))return -1 ; - priv->tx_skbuff_dma[entry].buf = des2; - priv->tx_skbuff_dma[entry].len = bmax; + tx_q->tx_skbuff_dma[entry].buf = des2; + tx_q->tx_skbuff_dma[entry].len = bmax; priv->hw->desc->prepare_tx_desc (desc,0 , bmax, csum,STMMAC_CHAIN_MODE ,1 , false);
@@ -77,8 +80,8 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) desc->des2 =cpu_to_le32 (des2);if (dma_mapping_error (priv->device, des2))return -1 ; - priv->tx_skbuff_dma[entry].buf = des2; - priv->tx_skbuff_dma[entry].len = len; + tx_q->tx_skbuff_dma[entry].buf = des2; + tx_q->tx_skbuff_dma[entry].len = len;/* last descriptor can be set now */ priv->hw->desc->prepare_tx_desc(desc, 0, len, csum, STMMAC_CHAIN_MODE, 1,
@@ -87,7 +90,7 @@ static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum) } } - priv->cur_tx = entry; + tx_q->cur_tx = entry;return entry; }
@@ -152,17 +155,18 @@ static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)static void stmmac_clean_desc3 (void *priv_ptr,struct dma_desc *p) { -struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr; -unsigned int entry = priv->dirty_tx; +struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr; +struct stmmac_priv *priv = tx_q->priv_data; +unsigned int entry = tx_q->dirty_tx; -if (priv->tx_skbuff_dma[entry].last_segment && !priv->extend_desc && +if (tx_q->tx_skbuff_dma[entry].last_segment && !priv->extend_desc && priv->hwts_tx_en)/* NOTE: Device will overwrite des3 with timestamp value if * 1588-2002 time stamping is enabled, hence reinitialize it * to keep explicit chaining in the descriptor. */ - p->des3 =cpu_to_le32 ((unsigned int )((priv->dma_tx_phy + - ((priv->dirty_tx +1 ) %DMA_TX_SIZE )) + p->des3 =cpu_to_le32 ((unsigned int )((tx_q->dma_tx_phy + + ((tx_q->dirty_tx +1 ) %DMA_TX_SIZE )) *sizeof (struct dma_desc ))); }
drivers/net/ethernet/stmicro/stmmac/ring_mode.c +24 -22
96 lines not on this page · raw message
drivers/net/ethernet/stmicro/stmmac/stmmac.h +18 -8
@@ -46,6 +46,20 @@ struct stmmac_tx_info {bool is_jumbo; }; +/* Frequently used values are kept adjacent for cache effect */ +struct stmmac_tx_queue { +u32 queue_index; +struct stmmac_priv *priv_data; +struct dma_extended_desc *dma_etx____cacheline_aligned_in_smp ; +struct dma_desc *dma_tx; +struct sk_buff **tx_skbuff; +struct stmmac_tx_info *tx_skbuff_dma; +unsigned int cur_tx; +unsigned int dirty_tx; +dma_addr_t dma_tx_phy; +u32 tx_tail_addr; +}; +struct stmmac_rx_queue {u32 queue_index;struct stmmac_priv *priv_data;
@@ -62,16 +76,10 @@ struct stmmac_rx_queue {struct stmmac_priv {/* Frequently used values are kept adjacent for cache effect */ -struct dma_extended_desc *dma_etx____cacheline_aligned_in_smp ; -struct dma_desc *dma_tx; -struct sk_buff **tx_skbuff; -unsigned int cur_tx; -unsigned int dirty_tx;u32 tx_count_frames;u32 tx_coal_frames;u32 tx_coal_timer; -struct stmmac_tx_info *tx_skbuff_dma; -dma_addr_t dma_tx_phy; +int tx_coalesce;int hwts_tx_en;bool tx_path_in_lpi_mode;
@@ -94,6 +102,9 @@ struct stmmac_priv {/* RX Queue */ struct stmmac_rx_queue rx_queue[MTL_MAX_RX_QUEUES ]; +/* TX Queue */ +struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES ]; +int oldlink;int speed;int oldduplex;
@@ -128,7 +139,6 @@ struct stmmac_priv {spinlock_t ptp_lock;void __iomem *mmcaddr;void __iomem *ptpaddr; -u32 tx_tail_addr;u32 mss;#ifdef CONFIG_DEBUG_FS
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +311 -208
973 lines not on this page · raw message
Signature · 1 line
2.9.3
PATCH v2 4/4 net: stmmac: adding multiple napi mechanism
In reply to Joao PintoThis patch adds the napi variable to the stmmac_rx_queue structure and forces that operations like netif_queue_stopped, netif_wake_queue, netif_stop_queue, netdev_reset_queue and netdev_sent_queue be made by queue.
---
changes v1->v2:
- init_dma_desc_rings() and alloc_dma_desc_resources() placed back to stmmac_open(), since they are not necessary anymore in probe() (old mechanism).
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 158 ++++++++++++++++------ 2 files changed, 120 insertions(+), 41 deletions(-)
drivers/net/ethernet/stmicro/stmmac/stmmac.h +1 -2
@@ -72,6 +72,7 @@ struct stmmac_rx_queue {u32 rx_zeroc_thresh;dma_addr_t dma_rx_phy;u32 rx_tail_addr; +struct napi_struct napi____cacheline_aligned_in_smp ; };struct stmmac_priv {
@@ -91,8 +92,6 @@ struct stmmac_priv {u32 rx_riwt;int hwts_rx_en; -struct napi_struct napi____cacheline_aligned_in_smp ; -void __iomem *ioaddr;struct net_device *dev;struct device *device;
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +119 -39
321 lines not on this page · raw message
Signature · 1 line
2.9.3
Quoted 12 lines · Joao Pinto
This patch adds multiple buffers to stmmac in a more fragmented way, in order to make problem debug easier.
I would kindly request to people to test this patch in their HWs in order to check if everything's functional. Thank you.
Joao Pinto (4):
net: stmmac: break some functions into RX and TX scopes
net: stmmac: adding multiple buffers for RX
net: stmmac: adding multiple buffers for TX
net: stmmac: adding multiple napi mechanism
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 45 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 49 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1257 ++++++++++++++------- 4 files changed, 947 insertions(+), 450 deletions(-)Signature · 1 line
2.9.3
Hello
I have tested v1 and didn't hit any issue on dwmac-sunxi/dwmac-sun8i. I will test the v2 and send just after my tested-by
Regards
Às 5:59 PM de 4/5/2017, Corentin Labbe escreveu:
Quoted 19 lines · Joao Pinto
Quoted 18 lines
This patch adds multiple buffers to stmmac in a more fragmented way, in order to make problem debug easier.
I would kindly request to people to test this patch in their HWs in order to check if everything's functional. Thank you.
Joao Pinto (4):
net: stmmac: break some functions into RX and TX scopes
net: stmmac: adding multiple buffers for RX
net: stmmac: adding multiple buffers for TX
net: stmmac: adding multiple napi mechanismdrivers/net/ethernet/stmicro/stmmac/chain_mode.c | 45 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 49 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1257 ++++++++++++++------- 4 files changed, 947 insertions(+), 450 deletions(-)
Quoted 9 lines
Quoted 3 lines
Signature · 1 line
2.9.3Hello
I have tested v1 and didn't hit any issue on dwmac-sunxi/dwmac-sun8i. I will test the v2 and send just after my tested-by
Hi,
Great news!
Joao
Quoted 2 lines
Regards
Quoted 12 lines · Joao Pinto
This patch adds multiple buffers to stmmac in a more fragmented way, in order to make problem debug easier.
I would kindly request to people to test this patch in their HWs in order to check if everything's functional. Thank you.
Joao Pinto (4):
net: stmmac: break some functions into RX and TX scopes
net: stmmac: adding multiple buffers for RX
net: stmmac: adding multiple buffers for TX
net: stmmac: adding multiple napi mechanism
Quoted 9 lines
drivers/net/ethernet/stmicro/stmmac/chain_mode.c | 45 +- drivers/net/ethernet/stmicro/stmmac/ring_mode.c | 46 +- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 49 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1257 ++++++++++++++------- 4 files changed, 947 insertions(+), 450 deletions(-)Signature · 1 line
2.9.3
For whole serie,