Skip to content

Commit 4186c8d

Browse files
aspeedJackydavem330
authored andcommitted
net: ftgmac100: Ensure tx descriptor updates are visible
The driver must ensure TX descriptor updates are visible before updating TX pointer and TX clear pointer. This resolves TX hangs observed on AST2600 when running iperf3. Signed-off-by: Jacky Chou <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 8af174e commit 4186c8d

File tree

1 file changed

+18
-8
lines changed

1 file changed

+18
-8
lines changed

drivers/net/ethernet/faraday/ftgmac100.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ static bool ftgmac100_rx_packet(struct ftgmac100 *priv, int *processed)
572572
(*processed)++;
573573
return true;
574574

575-
drop:
575+
drop:
576576
/* Clean rxdes0 (which resets own bit) */
577577
rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask);
578578
priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer);
@@ -656,6 +656,11 @@ static bool ftgmac100_tx_complete_packet(struct ftgmac100 *priv)
656656
ftgmac100_free_tx_packet(priv, pointer, skb, txdes, ctl_stat);
657657
txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask);
658658

659+
/* Ensure the descriptor config is visible before setting the tx
660+
* pointer.
661+
*/
662+
smp_wmb();
663+
659664
priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer);
660665

661666
return true;
@@ -809,6 +814,11 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
809814
dma_wmb();
810815
first->txdes0 = cpu_to_le32(f_ctl_stat);
811816

817+
/* Ensure the descriptor config is visible before setting the tx
818+
* pointer.
819+
*/
820+
smp_wmb();
821+
812822
/* Update next TX pointer */
813823
priv->tx_pointer = pointer;
814824

@@ -829,7 +839,7 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
829839

830840
return NETDEV_TX_OK;
831841

832-
dma_err:
842+
dma_err:
833843
if (net_ratelimit())
834844
netdev_err(netdev, "map tx fragment failed\n");
835845

@@ -851,7 +861,7 @@ static netdev_tx_t ftgmac100_hard_start_xmit(struct sk_buff *skb,
851861
* last fragment, so we know ftgmac100_free_tx_packet()
852862
* hasn't freed the skb yet.
853863
*/
854-
drop:
864+
drop:
855865
/* Drop the packet */
856866
dev_kfree_skb_any(skb);
857867
netdev->stats.tx_dropped++;
@@ -1344,7 +1354,7 @@ static void ftgmac100_reset(struct ftgmac100 *priv)
13441354
ftgmac100_init_all(priv, true);
13451355

13461356
netdev_dbg(netdev, "Reset done !\n");
1347-
bail:
1357+
bail:
13481358
if (priv->mii_bus)
13491359
mutex_unlock(&priv->mii_bus->mdio_lock);
13501360
if (netdev->phydev)
@@ -1543,15 +1553,15 @@ static int ftgmac100_open(struct net_device *netdev)
15431553

15441554
return 0;
15451555

1546-
err_ncsi:
1556+
err_ncsi:
15471557
napi_disable(&priv->napi);
15481558
netif_stop_queue(netdev);
1549-
err_alloc:
1559+
err_alloc:
15501560
ftgmac100_free_buffers(priv);
15511561
free_irq(netdev->irq, netdev);
1552-
err_irq:
1562+
err_irq:
15531563
netif_napi_del(&priv->napi);
1554-
err_hw:
1564+
err_hw:
15551565
iowrite32(0, priv->base + FTGMAC100_OFFSET_IER);
15561566
ftgmac100_free_rings(priv);
15571567
return err;

0 commit comments

Comments
 (0)