Skip to content

Commit 37d6017

Browse files
Fugang Duandavem330
authored andcommitted
net: fec: Workaround for imx6sx enet tx hang when enable three queues
When enable three queues on imx6sx enet, and then do tx performance test with iperf tool, after some time running, tx hang. Found that: If uDMA is running, software set TDAR may cause tx hang. If uDMA is in idle, software set TDAR don't cause tx hang. There is a TDAR race condition for mutliQ when the software sets TDAR and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles). This will cause the udma_tx and udma_tx_arbiter state machines to hang. The issue exist at i.MX6SX enet IP. So, the Workaround is checking TDAR status four time, if TDAR cleared by hardware and then write TDAR, otherwise don't set TDAR. The patch is only one Workaround for the issue ERR007885. Signed-off-by: Fugang Duan <B38611@freescale.com> Signed-off-by: Frank Li <Frank.Li@freescale.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 73e7228 commit 37d6017

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

drivers/net/ethernet/freescale/fec_main.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ static void fec_enet_itr_coal_init(struct net_device *ndev);
111111
* independent rings
112112
*/
113113
#define FEC_QUIRK_HAS_AVB (1 << 8)
114+
/* There is a TDAR race condition for mutliQ when the software sets TDAR
115+
* and the UDMA clears TDAR simultaneously or in a small window (2-4 cycles).
116+
* This will cause the udma_tx and udma_tx_arbiter state machines to hang.
117+
* The issue exist at i.MX6SX enet IP.
118+
*/
119+
#define FEC_QUIRK_ERR007885 (1 << 9)
114120

115121
static struct platform_device_id fec_devtype[] = {
116122
{
@@ -139,7 +145,7 @@ static struct platform_device_id fec_devtype[] = {
139145
.driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
140146
FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
141147
FEC_QUIRK_HAS_VLAN | FEC_QUIRK_ERR006358 |
142-
FEC_QUIRK_HAS_AVB,
148+
FEC_QUIRK_HAS_AVB | FEC_QUIRK_ERR007885,
143149
}, {
144150
/* sentinel */
145151
}
@@ -709,6 +715,8 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
709715
struct tso_t tso;
710716
unsigned int index = 0;
711717
int ret;
718+
const struct platform_device_id *id_entry =
719+
platform_get_device_id(fep->pdev);
712720

713721
if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep, txq)) {
714722
dev_kfree_skb_any(skb);
@@ -770,7 +778,12 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
770778
txq->cur_tx = bdp;
771779

772780
/* Trigger transmission start */
773-
writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
781+
if (!(id_entry->driver_data & FEC_QUIRK_ERR007885) ||
782+
!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
783+
!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
784+
!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
785+
!readl(fep->hwp + FEC_X_DES_ACTIVE(queue)))
786+
writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
774787

775788
return 0;
776789

0 commit comments

Comments
 (0)