* [PATCH net-next v2 0/3] gianfar: xmit() improvements
@ 2016-02-23 9:48 Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 1/3] gianfar: Map head TxBD first Claudiu Manoil
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Claudiu Manoil @ 2016-02-23 9:48 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
Remove redundant operations, improve code locality and maintainability.
Thanks.
V2: Updated first patch to not touch existing wmb().
Claudiu Manoil (3):
gianfar: Map head TxBD first
gianfar: Use skb_frag_t pointers inside xmit()
gianfar: Remove redundant ops for do_tstamp from xmit()
drivers/net/ethernet/freescale/gianfar.c | 100 +++++++++++++++----------------
1 file changed, 48 insertions(+), 52 deletions(-)
--
1.7.11.7
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH net-next v2 1/3] gianfar: Map head TxBD first
2016-02-23 9:48 [PATCH net-next v2 0/3] gianfar: xmit() improvements Claudiu Manoil
@ 2016-02-23 9:48 ` Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 2/3] gianfar: Use skb_frag_t pointers inside xmit() Claudiu Manoil
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Claudiu Manoil @ 2016-02-23 9:48 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
Move the mapping of the head BD before the mapping of fragments.
The TOE (h/w offload) decision logic block can be also moved up
(as the TOE flag belongs to the head BD), resulting in more
localized code (TOE logic vs BD mapping code blocks).
Note that, for this h/w, the R (status) bit for the head BD of a S/G
frame needs to be written last for a reliable transmission.
For the fragmented skb case, a local variable is used to temporarily
store the status info of the first BD, replacing a BD status read.
A merge of 2 "if(do_tstamp)" blocks was also possible.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
v2: Don't remove the wmb() preceding the head BD status write.
drivers/net/ethernet/freescale/gianfar.c | 96 ++++++++++++++++----------------
1 file changed, 48 insertions(+), 48 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 2aa7b40..cb80dba8 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2389,6 +2389,47 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp = txbdp_start = tx_queue->cur_tx;
lstatus = be32_to_cpu(txbdp->lstatus);
+ /* Add TxPAL between FCB and frame if required */
+ if (unlikely(do_tstamp)) {
+ skb_push(skb, GMAC_TXPAL_LEN);
+ memset(skb->data, 0, GMAC_TXPAL_LEN);
+ }
+
+ /* Add TxFCB if required */
+ if (fcb_len) {
+ fcb = gfar_add_fcb(skb);
+ lstatus |= BD_LFLAG(TXBD_TOE);
+ }
+
+ /* Set up checksumming */
+ if (do_csum) {
+ gfar_tx_checksum(skb, fcb, fcb_len);
+
+ if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
+ unlikely(gfar_csum_errata_76(priv, skb->len))) {
+ __skb_pull(skb, GMAC_FCB_LEN);
+ skb_checksum_help(skb);
+ if (do_vlan || do_tstamp) {
+ /* put back a new fcb for vlan/tstamp TOE */
+ fcb = gfar_add_fcb(skb);
+ } else {
+ /* Tx TOE not used */
+ lstatus &= ~(BD_LFLAG(TXBD_TOE));
+ fcb = NULL;
+ }
+ }
+ }
+
+ if (do_vlan)
+ gfar_tx_vlan(skb, fcb);
+
+ bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
+ DMA_TO_DEVICE);
+ if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
+ goto dma_map_err;
+
+ txbdp_start->bufPtr = cpu_to_be32(bufaddr);
+
/* Time stamp insertion requires one additional TxBD */
if (unlikely(do_tstamp))
txbdp_tstamp = txbdp = next_txbd(txbdp, base,
@@ -2404,6 +2445,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
}
} else {
+ u32 lstatus_start = lstatus;
+
/* Place the fragment addresses and lengths into the TxBDs */
for (i = 0; i < nr_frags; i++) {
unsigned int frag_len;
@@ -2432,56 +2475,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp->lstatus = cpu_to_be32(lstatus);
}
- lstatus = be32_to_cpu(txbdp_start->lstatus);
+ lstatus = lstatus_start;
}
- /* Add TxPAL between FCB and frame if required */
- if (unlikely(do_tstamp)) {
- skb_push(skb, GMAC_TXPAL_LEN);
- memset(skb->data, 0, GMAC_TXPAL_LEN);
- }
-
- /* Add TxFCB if required */
- if (fcb_len) {
- fcb = gfar_add_fcb(skb);
- lstatus |= BD_LFLAG(TXBD_TOE);
- }
-
- /* Set up checksumming */
- if (do_csum) {
- gfar_tx_checksum(skb, fcb, fcb_len);
-
- if (unlikely(gfar_csum_errata_12(priv, (unsigned long)fcb)) ||
- unlikely(gfar_csum_errata_76(priv, skb->len))) {
- __skb_pull(skb, GMAC_FCB_LEN);
- skb_checksum_help(skb);
- if (do_vlan || do_tstamp) {
- /* put back a new fcb for vlan/tstamp TOE */
- fcb = gfar_add_fcb(skb);
- } else {
- /* Tx TOE not used */
- lstatus &= ~(BD_LFLAG(TXBD_TOE));
- fcb = NULL;
- }
- }
- }
-
- if (do_vlan)
- gfar_tx_vlan(skb, fcb);
-
- /* Setup tx hardware time stamping if requested */
- if (unlikely(do_tstamp)) {
- skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
- fcb->ptp = 1;
- }
-
- bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
- DMA_TO_DEVICE);
- if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
- goto dma_map_err;
-
- txbdp_start->bufPtr = cpu_to_be32(bufaddr);
-
/* If time stamping is requested one additional TxBD must be set up. The
* first TxBD points to the FCB and must have a data length of
* GMAC_FCB_LEN. The second TxBD points to the actual frame data with
@@ -2498,6 +2494,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_tstamp->bufPtr = cpu_to_be32(bufaddr);
txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
+
+ /* Setup tx hardware time stamping */
+ skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+ fcb->ptp = 1;
} else {
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v2 2/3] gianfar: Use skb_frag_t pointers inside xmit()
2016-02-23 9:48 [PATCH net-next v2 0/3] gianfar: xmit() improvements Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 1/3] gianfar: Map head TxBD first Claudiu Manoil
@ 2016-02-23 9:48 ` Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 3/3] gianfar: Remove redundant ops for do_tstamp from xmit() Claudiu Manoil
2016-02-24 21:56 ` [PATCH net-next v2 0/3] gianfar: xmit() improvements David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Claudiu Manoil @ 2016-02-23 9:48 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index cb80dba8..7b16ce6 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2322,6 +2322,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct txfcb *fcb = NULL;
struct txbd8 *txbdp, *txbdp_start, *base, *txbdp_tstamp = NULL;
u32 lstatus;
+ skb_frag_t *frag;
int i, rq = 0;
int do_tstamp, do_csum, do_vlan;
u32 bufaddr;
@@ -2448,25 +2449,24 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
u32 lstatus_start = lstatus;
/* Place the fragment addresses and lengths into the TxBDs */
- for (i = 0; i < nr_frags; i++) {
- unsigned int frag_len;
+ frag = &skb_shinfo(skb)->frags[0];
+ for (i = 0; i < nr_frags; i++, frag++) {
+ unsigned int size;
+
/* Point at the next BD, wrapping as needed */
txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
- frag_len = skb_shinfo(skb)->frags[i].size;
+ size = skb_frag_size(frag);
- lstatus = be32_to_cpu(txbdp->lstatus) | frag_len |
+ lstatus = be32_to_cpu(txbdp->lstatus) | size |
BD_LFLAG(TXBD_READY);
/* Handle the last BD specially */
if (i == nr_frags - 1)
lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- bufaddr = skb_frag_dma_map(priv->dev,
- &skb_shinfo(skb)->frags[i],
- 0,
- frag_len,
- DMA_TO_DEVICE);
+ bufaddr = skb_frag_dma_map(priv->dev, frag, 0,
+ size, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
goto dma_map_err;
--
1.7.11.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH net-next v2 3/3] gianfar: Remove redundant ops for do_tstamp from xmit()
2016-02-23 9:48 [PATCH net-next v2 0/3] gianfar: xmit() improvements Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 1/3] gianfar: Map head TxBD first Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 2/3] gianfar: Use skb_frag_t pointers inside xmit() Claudiu Manoil
@ 2016-02-23 9:48 ` Claudiu Manoil
2016-02-24 21:56 ` [PATCH net-next v2 0/3] gianfar: xmit() improvements David Miller
3 siblings, 0 replies; 5+ messages in thread
From: Claudiu Manoil @ 2016-02-23 9:48 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller
Timestamp BD status updates that can be merged into the
same "do_tstamp" block, no need for extra save/restore
to the BD area. The code is more readable too.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 7b16ce6..1e1157f 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2436,15 +2436,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_tstamp = txbdp = next_txbd(txbdp, base,
tx_queue->tx_ring_size);
- if (nr_frags == 0) {
- if (unlikely(do_tstamp)) {
- u32 lstatus_ts = be32_to_cpu(txbdp_tstamp->lstatus);
-
- lstatus_ts |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
- } else {
- lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
- }
+ if (likely(!nr_frags)) {
+ lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
} else {
u32 lstatus_start = lstatus;
@@ -2488,8 +2481,11 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
bufaddr = be32_to_cpu(txbdp_start->bufPtr);
bufaddr += fcb_len;
+
lstatus_ts |= BD_LFLAG(TXBD_READY) |
(skb_headlen(skb) - fcb_len);
+ if (!nr_frags)
+ lstatus_ts |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
txbdp_tstamp->bufPtr = cpu_to_be32(bufaddr);
txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH net-next v2 0/3] gianfar: xmit() improvements
2016-02-23 9:48 [PATCH net-next v2 0/3] gianfar: xmit() improvements Claudiu Manoil
` (2 preceding siblings ...)
2016-02-23 9:48 ` [PATCH net-next v2 3/3] gianfar: Remove redundant ops for do_tstamp from xmit() Claudiu Manoil
@ 2016-02-24 21:56 ` David Miller
3 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2016-02-24 21:56 UTC (permalink / raw)
To: claudiu.manoil; +Cc: netdev
From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Tue, 23 Feb 2016 11:48:36 +0200
> Remove redundant operations, improve code locality and maintainability.
> Thanks.
>
> V2: Updated first patch to not touch existing wmb().
Series applied, thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2016-02-24 21:56 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-02-23 9:48 [PATCH net-next v2 0/3] gianfar: xmit() improvements Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 1/3] gianfar: Map head TxBD first Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 2/3] gianfar: Use skb_frag_t pointers inside xmit() Claudiu Manoil
2016-02-23 9:48 ` [PATCH net-next v2 3/3] gianfar: Remove redundant ops for do_tstamp from xmit() Claudiu Manoil
2016-02-24 21:56 ` [PATCH net-next v2 0/3] gianfar: xmit() improvements David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).