* [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup
@ 2013-08-05 14:20 Claudiu Manoil
2013-08-05 14:20 ` [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling Claudiu Manoil
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
Hi David,
Please find these cleanup patches for the gfar_start_xmit() function,
including a fix for an old errata workaround implementation (eTSEC76,
for MPC8313 and MPC837x). I find this cleanup quite necessary to make
future fixes and improvements in xmit (and Tx processing) easier.
Thanks,
Claudiu Manoil (2):
gianfar: Fix Tx csum generation errata handling
gianfar: Cleanup TxFCB insertion on xmit
drivers/net/ethernet/freescale/gianfar.c | 100 +++++++++++++++++--------------
1 file changed, 55 insertions(+), 45 deletions(-)
--
1.7.11.7
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling
2013-08-05 14:20 [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup Claudiu Manoil
@ 2013-08-05 14:20 ` Claudiu Manoil
2013-08-05 14:20 ` [PATCH 2/2][net-next] gianfar: Cleanup TxFCB insertion on xmit Claudiu Manoil
2013-08-05 19:29 ` [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
Both [eTSEC76] and [eTSEC12] errata relate to Tx checksum generation
(for some MPC83xx and MCP8548 older revisions). They require the same
workaround: manual checksum computation and insertion, and disabling
the H/W Tx csum acceleration feature (per frame) through Tx FCB
(Frame Control Block) csum offload settings.
The workaround for [eTSEC76] needs to be fixed because it currently
fails to disable H/W Tx csum insertion via FCB. This patch fixes it
and provides a common workaround implementation for both Tx csum errata.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 44 ++++++++++++++++++--------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 0f05b96..3a543f7 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2054,6 +2054,24 @@ static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base,
return skip_txbd(bdp, 1, base, ring_size);
}
+/* eTSEC12: csum generation not supported for some fcb offsets */
+static inline bool gfar_csum_errata_12(struct gfar_private *priv,
+ unsigned long fcb_addr)
+{
+ return (gfar_has_errata(priv, GFAR_ERRATA_12) &&
+ (fcb_addr % 0x20) > 0x18);
+}
+
+/* eTSEC76: csum generation for frames larger than 2500 may
+ * cause excess delays before start of transmission
+ */
+static inline bool gfar_csum_errata_76(struct gfar_private *priv,
+ unsigned int len)
+{
+ return (gfar_has_errata(priv, GFAR_ERRATA_76) &&
+ (len > 2500));
+}
+
/* This is called by the kernel when a frame is ready for transmission.
* It is pointed to by the dev->hard_start_xmit function pointer
*/
@@ -2071,19 +2089,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
- /* TOE=1 frames larger than 2500 bytes may see excess delays
- * before start of transmission.
- */
- if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) &&
- skb->ip_summed == CHECKSUM_PARTIAL &&
- skb->len > 2500)) {
- int ret;
-
- ret = skb_checksum_help(skb);
- if (ret)
- return ret;
- }
-
rq = skb->queue_mapping;
tx_queue = priv->tx_queue[rq];
txq = netdev_get_tx_queue(dev, rq);
@@ -2190,14 +2195,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Set up checksumming */
if (CHECKSUM_PARTIAL == skb->ip_summed) {
fcb = gfar_add_fcb(skb);
- /* as specified by errata */
- if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_12) &&
- ((unsigned long)fcb % 0x20) > 0x18)) {
+ lstatus |= BD_LFLAG(TXBD_TOE);
+ gfar_tx_checksum(skb, fcb, fcb_length);
+
+ 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);
- } else {
- lstatus |= BD_LFLAG(TXBD_TOE);
- gfar_tx_checksum(skb, fcb, fcb_length);
+ lstatus &= ~(BD_LFLAG(TXBD_TOE));
+ fcb = NULL;
}
}
--
1.7.11.7
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2][net-next] gianfar: Cleanup TxFCB insertion on xmit
2013-08-05 14:20 [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup Claudiu Manoil
2013-08-05 14:20 ` [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling Claudiu Manoil
@ 2013-08-05 14:20 ` Claudiu Manoil
2013-08-05 19:29 ` [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Claudiu Manoil @ 2013-08-05 14:20 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Paul Gortmaker
Cleanup gfar_start_xmit()'s fast path by factoring out "redundant"
FCB insertion code (repeated gfar_add_fcb() calls and related)
and by reducing the number of if() clauses (i.e. if(fcb) checks).
Improve maintainability (e.g. there's less code and easier to read)
also by introducing do_csum and do_vlan to mark the other 2 Tx TOE
functionalities, following the same model as do_tstamp.
fcb_len may also be 0 now, to mark that Tx FCB insertion conditions
(do_csum, do_vlan, do_tstamp) have not been met.
Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
drivers/net/ethernet/freescale/gianfar.c | 62 +++++++++++++++++---------------
1 file changed, 33 insertions(+), 29 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 3a543f7..d4f22c6 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2084,10 +2084,11 @@ 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;
- int i, rq = 0, do_tstamp = 0;
+ int i, rq = 0;
+ int do_tstamp, do_csum, do_vlan;
u32 bufaddr;
unsigned long flags;
- unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
+ unsigned int nr_frags, nr_txbds, length, fcb_len = 0;
rq = skb->queue_mapping;
tx_queue = priv->tx_queue[rq];
@@ -2095,21 +2096,23 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
base = tx_queue->tx_bd_base;
regs = tx_queue->grp->regs;
+ do_csum = (CHECKSUM_PARTIAL == skb->ip_summed);
+ do_vlan = vlan_tx_tag_present(skb);
+ do_tstamp = (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+ priv->hwts_tx_en;
+
+ if (do_csum || do_vlan)
+ fcb_len = GMAC_FCB_LEN;
+
/* check if time stamp should be generated */
- if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
- priv->hwts_tx_en)) {
- do_tstamp = 1;
- fcb_length = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
- }
+ if (unlikely(do_tstamp))
+ fcb_len = GMAC_FCB_LEN + GMAC_TXPAL_LEN;
/* make space for additional header when fcb is needed */
- if (((skb->ip_summed == CHECKSUM_PARTIAL) ||
- vlan_tx_tag_present(skb) ||
- unlikely(do_tstamp)) &&
- (skb_headroom(skb) < fcb_length)) {
+ if (fcb_len && unlikely(skb_headroom(skb) < fcb_len)) {
struct sk_buff *skb_new;
- skb_new = skb_realloc_headroom(skb, fcb_length);
+ skb_new = skb_realloc_headroom(skb, fcb_len);
if (!skb_new) {
dev->stats.tx_errors++;
kfree_skb(skb);
@@ -2192,37 +2195,38 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
memset(skb->data, 0, GMAC_TXPAL_LEN);
}
- /* Set up checksumming */
- if (CHECKSUM_PARTIAL == skb->ip_summed) {
+ /* Add TxFCB if required */
+ if (fcb_len) {
fcb = gfar_add_fcb(skb);
lstatus |= BD_LFLAG(TXBD_TOE);
- gfar_tx_checksum(skb, fcb, fcb_length);
+ }
+
+ /* 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);
- lstatus &= ~(BD_LFLAG(TXBD_TOE));
- fcb = NULL;
+ 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 (vlan_tx_tag_present(skb)) {
- if (unlikely(NULL == fcb)) {
- fcb = gfar_add_fcb(skb);
- lstatus |= BD_LFLAG(TXBD_TOE);
- }
-
+ 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;
- if (fcb == NULL)
- fcb = gfar_add_fcb(skb);
fcb->ptp = 1;
- lstatus |= BD_LFLAG(TXBD_TOE);
}
txbdp_start->bufPtr = dma_map_single(priv->dev, skb->data,
@@ -2234,9 +2238,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
* the full frame length.
*/
if (unlikely(do_tstamp)) {
- txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_length;
+ txbdp_tstamp->bufPtr = txbdp_start->bufPtr + fcb_len;
txbdp_tstamp->lstatus |= BD_LFLAG(TXBD_READY) |
- (skb_headlen(skb) - fcb_length);
+ (skb_headlen(skb) - fcb_len);
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
} else {
lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup
2013-08-05 14:20 [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup Claudiu Manoil
2013-08-05 14:20 ` [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling Claudiu Manoil
2013-08-05 14:20 ` [PATCH 2/2][net-next] gianfar: Cleanup TxFCB insertion on xmit Claudiu Manoil
@ 2013-08-05 19:29 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2013-08-05 19:29 UTC (permalink / raw)
To: claudiu.manoil; +Cc: netdev, paul.gortmaker
From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Mon, 5 Aug 2013 17:20:08 +0300
> Please find these cleanup patches for the gfar_start_xmit() function,
> including a fix for an old errata workaround implementation (eTSEC76,
> for MPC8313 and MPC837x). I find this cleanup quite necessary to make
> future fixes and improvements in xmit (and Tx processing) easier.
Both applied, thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-08-05 19:29 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-05 14:20 [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup Claudiu Manoil
2013-08-05 14:20 ` [PATCH 1/2][net-next] gianfar: Fix Tx csum generation errata handling Claudiu Manoil
2013-08-05 14:20 ` [PATCH 2/2][net-next] gianfar: Cleanup TxFCB insertion on xmit Claudiu Manoil
2013-08-05 19:29 ` [PATCH 0/2][net-next] gianfar: xmit - fix errata workaround and cleanup 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).