aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet
diff options
context:
space:
mode:
authorFugang Duan <B38611@freescale.com>2014-02-20 20:45:20 -0500
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:57:35 -0400
commitd472828dac9afbe09139a8a9aa0805719bec3e89 (patch)
treea01b0e5b6a5178490f9c868d1616caf023ca50ce /drivers/net/ethernet
parentfcc6fc800470df5651b5339c2521340fbc039860 (diff)
net: fec: fix potential issue to avoid fec interrupt lost and crc error
The current flow: Set TX BD ready, and then set "INT" and "PINS" bit to enable tx interrupt generation and crc checksum. There has potential issue like as: CPU fec uDMA Set tx ready bit uDMA start the BD transmission Set "INT" bit Set "PINS" bit ... Above situation cause fec tx interrupt lost and fec MAC don't do CRC checksum. The patch fix the potential issue. Signed-off-by: Fugang Duan <B38611@freescale.com> Acked-by: Frank Li <Frank.li@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet')
-rw-r--r--drivers/net/ethernet/freescale/fec_main.c13
1 files changed, 7 insertions, 6 deletions
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index dde2cd85dfc4..cb3e5fec4897 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -386,12 +386,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
386 netdev_err(ndev, "Tx DMA memory map failed\n"); 386 netdev_err(ndev, "Tx DMA memory map failed\n");
387 return NETDEV_TX_OK; 387 return NETDEV_TX_OK;
388 } 388 }
389 /* Send it on its way. Tell FEC it's ready, interrupt when done,
390 * it's the last BD of the frame, and to put the CRC on the end.
391 */
392 status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
393 | BD_ENET_TX_LAST | BD_ENET_TX_TC);
394 bdp->cbd_sc = status;
395 389
396 if (fep->bufdesc_ex) { 390 if (fep->bufdesc_ex) {
397 391
@@ -417,6 +411,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
417 ebdp->cbd_esc |= FEC_TX_BD_FTYPE(queue); 411 ebdp->cbd_esc |= FEC_TX_BD_FTYPE(queue);
418 } 412 }
419 413
414 /* Send it on its way. Tell FEC it's ready, interrupt when done,
415 * it's the last BD of the frame, and to put the CRC on the end.
416 */
417 status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
418 | BD_ENET_TX_LAST | BD_ENET_TX_TC);
419 bdp->cbd_sc = status;
420
420 bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); 421 bdp_pre = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex);
421 if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && 422 if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
422 !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { 423 !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {