Skip to content

Commit 603ead9

Browse files
HoratiuVulturkuba-moo
authored andcommitted
net: sparx5: Add spinlock for frame transmission from CPU
Both registers used when doing manual injection or fdma injection are shared between all the net devices of the switch. It was noticed that when having two process which each of them trying to inject frames on different ethernet ports, that the HW started to behave strange, by sending out more frames then expected. When doing fdma injection it is required to set the frame in the DCB and then make sure that the next pointer of the last DCB is invalid. But because there is no locks for this, then easily this pointer between the DCB can be broken and then it would create a loop of DCBs. And that means that the HW will continuously transmit these frames in a loop. Until the SW will break this loop. Therefore to fix this issue, add a spin lock for when accessing the registers for manual or fdma injection. Signed-off-by: Horatiu Vultur <[email protected]> Reviewed-by: Daniel Machon <[email protected]> Fixes: f3cad26 ("net: sparx5: add hostmode with phylink support") Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 1fde0ca commit 603ead9

File tree

3 files changed

+4
-0
lines changed

3 files changed

+4
-0
lines changed

drivers/net/ethernet/microchip/sparx5/sparx5_main.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,7 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
757757
platform_set_drvdata(pdev, sparx5);
758758
sparx5->pdev = pdev;
759759
sparx5->dev = &pdev->dev;
760+
spin_lock_init(&sparx5->tx_lock);
760761

761762
/* Do switch core reset if available */
762763
reset = devm_reset_control_get_optional_shared(&pdev->dev, "switch");

drivers/net/ethernet/microchip/sparx5/sparx5_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ struct sparx5 {
280280
int xtr_irq;
281281
/* Frame DMA */
282282
int fdma_irq;
283+
spinlock_t tx_lock; /* lock for frame transmission */
283284
struct sparx5_rx rx;
284285
struct sparx5_tx tx;
285286
/* PTP */

drivers/net/ethernet/microchip/sparx5/sparx5_packet.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,12 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
244244
}
245245

246246
skb_tx_timestamp(skb);
247+
spin_lock(&sparx5->tx_lock);
247248
if (sparx5->fdma_irq > 0)
248249
ret = sparx5_fdma_xmit(sparx5, ifh, skb);
249250
else
250251
ret = sparx5_inject(sparx5, ifh, skb, dev);
252+
spin_unlock(&sparx5->tx_lock);
251253

252254
if (ret == -EBUSY)
253255
goto busy;

0 commit comments

Comments
 (0)