Skip to content

Commit 8b73fa3

Browse files
robhancockseddavem330
authored andcommitted
net: macb: Added ZynqMP-specific initialization
The GEM controllers on ZynqMP were missing some initialization steps which are required in some cases when using SGMII mode, which uses the PS-GTR transceivers managed by the phy-zynqmp driver. The GEM core appears to need a hardware-level reset in order to work properly in SGMII mode in cases where the GT reference clock was not present at initial power-on. This can be done using a reset mapped to the zynqmp-reset driver in the device tree. Also, when in SGMII mode, the GEM driver needs to ensure the PHY is initialized and powered on. Signed-off-by: Robert Hancock <[email protected]> Reviewed-by: Claudiu Beznea <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent f4ea385 commit 8b73fa3

File tree

2 files changed

+64
-3
lines changed

2 files changed

+64
-3
lines changed

drivers/net/ethernet/cadence/macb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/ptp_clock_kernel.h>
1313
#include <linux/net_tstamp.h>
1414
#include <linux/interrupt.h>
15+
#include <linux/phy/phy.h>
1516

1617
#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) || defined(CONFIG_MACB_USE_HWSTAMP)
1718
#define MACB_EXT_DESC
@@ -1291,6 +1292,9 @@ struct macb {
12911292
u32 wol;
12921293

12931294
struct macb_ptp_info *ptp_info; /* macb-ptp interface */
1295+
1296+
struct phy *sgmii_phy; /* for ZynqMP SGMII mode */
1297+
12941298
#ifdef MACB_EXT_DESC
12951299
uint8_t hw_dma_cap;
12961300
#endif

drivers/net/ethernet/cadence/macb_main.c

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
#include <linux/udp.h>
3535
#include <linux/tcp.h>
3636
#include <linux/iopoll.h>
37+
#include <linux/phy/phy.h>
3738
#include <linux/pm_runtime.h>
39+
#include <linux/reset.h>
3840
#include "macb.h"
3941

4042
/* This structure is only used for MACB on SiFive FU540 devices */
@@ -2739,17 +2741,24 @@ static int macb_open(struct net_device *dev)
27392741

27402742
macb_init_hw(bp);
27412743

2742-
err = macb_phylink_connect(bp);
2744+
err = phy_power_on(bp->sgmii_phy);
27432745
if (err)
27442746
goto reset_hw;
27452747

2748+
err = macb_phylink_connect(bp);
2749+
if (err)
2750+
goto phy_off;
2751+
27462752
netif_tx_start_all_queues(dev);
27472753

27482754
if (bp->ptp_info)
27492755
bp->ptp_info->ptp_init(dev);
27502756

27512757
return 0;
27522758

2759+
phy_off:
2760+
phy_power_off(bp->sgmii_phy);
2761+
27532762
reset_hw:
27542763
macb_reset_hw(bp);
27552764
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
@@ -2775,6 +2784,8 @@ static int macb_close(struct net_device *dev)
27752784
phylink_stop(bp->phylink);
27762785
phylink_disconnect_phy(bp->phylink);
27772786

2787+
phy_power_off(bp->sgmii_phy);
2788+
27782789
spin_lock_irqsave(&bp->lock, flags);
27792790
macb_reset_hw(bp);
27802791
netif_carrier_off(dev);
@@ -4544,13 +4555,55 @@ static const struct macb_config np4_config = {
45444555
.usrio = &macb_default_usrio,
45454556
};
45464557

4558+
static int zynqmp_init(struct platform_device *pdev)
4559+
{
4560+
struct net_device *dev = platform_get_drvdata(pdev);
4561+
struct macb *bp = netdev_priv(dev);
4562+
int ret;
4563+
4564+
if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
4565+
/* Ensure PS-GTR PHY device used in SGMII mode is ready */
4566+
bp->sgmii_phy = devm_phy_get(&pdev->dev, "sgmii-phy");
4567+
4568+
if (IS_ERR(bp->sgmii_phy)) {
4569+
ret = PTR_ERR(bp->sgmii_phy);
4570+
dev_err_probe(&pdev->dev, ret,
4571+
"failed to get PS-GTR PHY\n");
4572+
return ret;
4573+
}
4574+
4575+
ret = phy_init(bp->sgmii_phy);
4576+
if (ret) {
4577+
dev_err(&pdev->dev, "failed to init PS-GTR PHY: %d\n",
4578+
ret);
4579+
return ret;
4580+
}
4581+
}
4582+
4583+
/* Fully reset GEM controller at hardware level using zynqmp-reset driver,
4584+
* if mapped in device tree.
4585+
*/
4586+
ret = device_reset_optional(&pdev->dev);
4587+
if (ret) {
4588+
dev_err_probe(&pdev->dev, ret, "failed to reset controller");
4589+
phy_exit(bp->sgmii_phy);
4590+
return ret;
4591+
}
4592+
4593+
ret = macb_init(pdev);
4594+
if (ret)
4595+
phy_exit(bp->sgmii_phy);
4596+
4597+
return ret;
4598+
}
4599+
45474600
static const struct macb_config zynqmp_config = {
45484601
.caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE |
45494602
MACB_CAPS_JUMBO |
45504603
MACB_CAPS_GEM_HAS_PTP | MACB_CAPS_BD_RD_PREFETCH,
45514604
.dma_burst_length = 16,
45524605
.clk_init = macb_clk_init,
4553-
.init = macb_init,
4606+
.init = zynqmp_init,
45544607
.jumbo_max_len = 10240,
45554608
.usrio = &macb_default_usrio,
45564609
};
@@ -4767,7 +4820,7 @@ static int macb_probe(struct platform_device *pdev)
47674820

47684821
err = macb_mii_init(bp);
47694822
if (err)
4770-
goto err_out_free_netdev;
4823+
goto err_out_phy_exit;
47714824

47724825
netif_carrier_off(dev);
47734826

@@ -4792,6 +4845,9 @@ static int macb_probe(struct platform_device *pdev)
47924845
mdiobus_unregister(bp->mii_bus);
47934846
mdiobus_free(bp->mii_bus);
47944847

4848+
err_out_phy_exit:
4849+
phy_exit(bp->sgmii_phy);
4850+
47954851
err_out_free_netdev:
47964852
free_netdev(dev);
47974853

@@ -4813,6 +4869,7 @@ static int macb_remove(struct platform_device *pdev)
48134869

48144870
if (dev) {
48154871
bp = netdev_priv(dev);
4872+
phy_exit(bp->sgmii_phy);
48164873
mdiobus_unregister(bp->mii_bus);
48174874
mdiobus_free(bp->mii_bus);
48184875

0 commit comments

Comments
 (0)