aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/freescale
diff options
context:
space:
mode:
authorDuan Fugang-B38611 <B38611@freescale.com>2014-02-20 05:14:39 -0500
committerDavid S. Miller <davem@davemloft.net>2014-02-20 13:16:13 -0500
commitfb8ef788680d48523321e5f150b23700a1caf980 (patch)
tree5ed3d875d32a6e6b3b63808e5144ab9d4fec7356 /drivers/net/ethernet/freescale
parentcf71d2bc0b8a473209d5c770ce560853bd720d14 (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/freescale')
-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 903362a7b584..479a7cba45c0 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -389,12 +389,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
389 netdev_err(ndev, "Tx DMA memory map failed\n"); 389 netdev_err(ndev, "Tx DMA memory map failed\n");
390 return NETDEV_TX_OK; 390 return NETDEV_TX_OK;
391 } 391 }
392 /* Send it on its way. Tell FEC it's ready, interrupt when done,
393 * it's the last BD of the frame, and to put the CRC on the end.
394 */
395 status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
396 | BD_ENET_TX_LAST | BD_ENET_TX_TC);
397 bdp->cbd_sc = status;
398 392
399 if (fep->bufdesc_ex) { 393 if (fep->bufdesc_ex) {
400 394
@@ -416,6 +410,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
416 } 410 }
417 } 411 }
418 412
413 /* Send it on its way. Tell FEC it's ready, interrupt when done,
414 * it's the last BD of the frame, and to put the CRC on the end.
415 */
416 status |= (BD_ENET_TX_READY | BD_ENET_TX_INTR
417 | BD_ENET_TX_LAST | BD_ENET_TX_TC);
418 bdp->cbd_sc = status;
419
419 bdp_pre = fec_enet_get_prevdesc(bdp, fep); 420 bdp_pre = fec_enet_get_prevdesc(bdp, fep);
420 if ((id_entry->driver_data & FEC_QUIRK_ERR006358) && 421 if ((id_entry->driver_data & FEC_QUIRK_ERR006358) &&
421 !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) { 422 !(bdp_pre->cbd_sc & BD_ENET_TX_READY)) {