Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Broadcom GENET MDIO routines
0004  *
0005  * Copyright (c) 2014-2017 Broadcom
0006  */
0007 
0008 #include <linux/acpi.h>
0009 #include <linux/types.h>
0010 #include <linux/delay.h>
0011 #include <linux/wait.h>
0012 #include <linux/mii.h>
0013 #include <linux/ethtool.h>
0014 #include <linux/bitops.h>
0015 #include <linux/netdevice.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/phy.h>
0018 #include <linux/phy_fixed.h>
0019 #include <linux/brcmphy.h>
0020 #include <linux/of.h>
0021 #include <linux/of_net.h>
0022 #include <linux/of_mdio.h>
0023 #include <linux/platform_data/bcmgenet.h>
0024 #include <linux/platform_data/mdio-bcm-unimac.h>
0025 
0026 #include "bcmgenet.h"
0027 
0028 static void bcmgenet_mac_config(struct net_device *dev)
0029 {
0030     struct bcmgenet_priv *priv = netdev_priv(dev);
0031     struct phy_device *phydev = dev->phydev;
0032     u32 reg, cmd_bits = 0;
0033 
0034     /* speed */
0035     if (phydev->speed == SPEED_1000)
0036         cmd_bits = CMD_SPEED_1000;
0037     else if (phydev->speed == SPEED_100)
0038         cmd_bits = CMD_SPEED_100;
0039     else
0040         cmd_bits = CMD_SPEED_10;
0041     cmd_bits <<= CMD_SPEED_SHIFT;
0042 
0043     /* duplex */
0044     if (phydev->duplex != DUPLEX_FULL) {
0045         cmd_bits |= CMD_HD_EN |
0046             CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
0047     } else {
0048         /* pause capability defaults to Symmetric */
0049         if (priv->autoneg_pause) {
0050             bool tx_pause = 0, rx_pause = 0;
0051 
0052             if (phydev->autoneg)
0053                 phy_get_pause(phydev, &tx_pause, &rx_pause);
0054 
0055             if (!tx_pause)
0056                 cmd_bits |= CMD_TX_PAUSE_IGNORE;
0057             if (!rx_pause)
0058                 cmd_bits |= CMD_RX_PAUSE_IGNORE;
0059         }
0060 
0061         /* Manual override */
0062         if (!priv->rx_pause)
0063             cmd_bits |= CMD_RX_PAUSE_IGNORE;
0064         if (!priv->tx_pause)
0065             cmd_bits |= CMD_TX_PAUSE_IGNORE;
0066     }
0067 
0068     /* Program UMAC and RGMII block based on established
0069      * link speed, duplex, and pause. The speed set in
0070      * umac->cmd tell RGMII block which clock to use for
0071      * transmit -- 25MHz(100Mbps) or 125MHz(1Gbps).
0072      * Receive clock is provided by the PHY.
0073      */
0074     reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
0075     reg &= ~OOB_DISABLE;
0076     reg |= RGMII_LINK;
0077     bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
0078 
0079     reg = bcmgenet_umac_readl(priv, UMAC_CMD);
0080     reg &= ~((CMD_SPEED_MASK << CMD_SPEED_SHIFT) |
0081                CMD_HD_EN |
0082                CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE);
0083     reg |= cmd_bits;
0084     if (reg & CMD_SW_RESET) {
0085         reg &= ~CMD_SW_RESET;
0086         bcmgenet_umac_writel(priv, reg, UMAC_CMD);
0087         udelay(2);
0088         reg |= CMD_TX_EN | CMD_RX_EN;
0089     }
0090     bcmgenet_umac_writel(priv, reg, UMAC_CMD);
0091 }
0092 
0093 /* setup netdev link state when PHY link status change and
0094  * update UMAC and RGMII block when link up
0095  */
0096 void bcmgenet_mii_setup(struct net_device *dev)
0097 {
0098     struct phy_device *phydev = dev->phydev;
0099 
0100     if (phydev->link)
0101         bcmgenet_mac_config(dev);
0102     phy_print_status(phydev);
0103 }
0104 
0105 
0106 static int bcmgenet_fixed_phy_link_update(struct net_device *dev,
0107                       struct fixed_phy_status *status)
0108 {
0109     struct bcmgenet_priv *priv;
0110     u32 reg;
0111 
0112     if (dev && dev->phydev && status) {
0113         priv = netdev_priv(dev);
0114         reg = bcmgenet_umac_readl(priv, UMAC_MODE);
0115         status->link = !!(reg & MODE_LINK_STATUS);
0116     }
0117 
0118     return 0;
0119 }
0120 
0121 void bcmgenet_phy_pause_set(struct net_device *dev, bool rx, bool tx)
0122 {
0123     struct phy_device *phydev = dev->phydev;
0124 
0125     linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->advertising, rx);
0126     linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->advertising,
0127              rx | tx);
0128     phy_start_aneg(phydev);
0129 
0130     mutex_lock(&phydev->lock);
0131     if (phydev->link)
0132         bcmgenet_mac_config(dev);
0133     mutex_unlock(&phydev->lock);
0134 }
0135 
0136 void bcmgenet_phy_power_set(struct net_device *dev, bool enable)
0137 {
0138     struct bcmgenet_priv *priv = netdev_priv(dev);
0139     u32 reg = 0;
0140 
0141     /* EXT_GPHY_CTRL is only valid for GENETv4 and onward */
0142     if (GENET_IS_V4(priv) || priv->ephy_16nm) {
0143         reg = bcmgenet_ext_readl(priv, EXT_GPHY_CTRL);
0144         if (enable) {
0145             reg &= ~EXT_CK25_DIS;
0146             bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
0147             mdelay(1);
0148 
0149             reg &= ~(EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN |
0150                  EXT_CFG_IDDQ_GLOBAL_PWR);
0151             reg |= EXT_GPHY_RESET;
0152             bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
0153             mdelay(1);
0154 
0155             reg &= ~EXT_GPHY_RESET;
0156         } else {
0157             reg |= EXT_CFG_IDDQ_BIAS | EXT_CFG_PWR_DOWN |
0158                    EXT_GPHY_RESET | EXT_CFG_IDDQ_GLOBAL_PWR;
0159             bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
0160             mdelay(1);
0161             reg |= EXT_CK25_DIS;
0162         }
0163         bcmgenet_ext_writel(priv, reg, EXT_GPHY_CTRL);
0164         udelay(60);
0165     } else {
0166         mdelay(1);
0167     }
0168 }
0169 
0170 static void bcmgenet_moca_phy_setup(struct bcmgenet_priv *priv)
0171 {
0172     u32 reg;
0173 
0174     if (!GENET_IS_V5(priv)) {
0175         /* Speed settings are set in bcmgenet_mii_setup() */
0176         reg = bcmgenet_sys_readl(priv, SYS_PORT_CTRL);
0177         reg |= LED_ACT_SOURCE_MAC;
0178         bcmgenet_sys_writel(priv, reg, SYS_PORT_CTRL);
0179     }
0180 
0181     if (priv->hw_params->flags & GENET_HAS_MOCA_LINK_DET)
0182         fixed_phy_set_link_update(priv->dev->phydev,
0183                       bcmgenet_fixed_phy_link_update);
0184 }
0185 
0186 int bcmgenet_mii_config(struct net_device *dev, bool init)
0187 {
0188     struct bcmgenet_priv *priv = netdev_priv(dev);
0189     struct phy_device *phydev = dev->phydev;
0190     struct device *kdev = &priv->pdev->dev;
0191     const char *phy_name = NULL;
0192     u32 id_mode_dis = 0;
0193     u32 port_ctrl;
0194     u32 reg;
0195 
0196     switch (priv->phy_interface) {
0197     case PHY_INTERFACE_MODE_INTERNAL:
0198         phy_name = "internal PHY";
0199         fallthrough;
0200     case PHY_INTERFACE_MODE_MOCA:
0201         /* Irrespective of the actually configured PHY speed (100 or
0202          * 1000) GENETv4 only has an internal GPHY so we will just end
0203          * up masking the Gigabit features from what we support, not
0204          * switching to the EPHY
0205          */
0206         if (GENET_IS_V4(priv))
0207             port_ctrl = PORT_MODE_INT_GPHY;
0208         else
0209             port_ctrl = PORT_MODE_INT_EPHY;
0210 
0211         if (!phy_name) {
0212             phy_name = "MoCA";
0213             bcmgenet_moca_phy_setup(priv);
0214         }
0215         break;
0216 
0217     case PHY_INTERFACE_MODE_MII:
0218         phy_name = "external MII";
0219         phy_set_max_speed(phydev, SPEED_100);
0220         port_ctrl = PORT_MODE_EXT_EPHY;
0221         break;
0222 
0223     case PHY_INTERFACE_MODE_REVMII:
0224         phy_name = "external RvMII";
0225         /* of_mdiobus_register took care of reading the 'max-speed'
0226          * PHY property for us, effectively limiting the PHY supported
0227          * capabilities, use that knowledge to also configure the
0228          * Reverse MII interface correctly.
0229          */
0230         if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
0231                       dev->phydev->supported))
0232             port_ctrl = PORT_MODE_EXT_RVMII_50;
0233         else
0234             port_ctrl = PORT_MODE_EXT_RVMII_25;
0235         break;
0236 
0237     case PHY_INTERFACE_MODE_RGMII:
0238         /* RGMII_NO_ID: TXC transitions at the same time as TXD
0239          *      (requires PCB or receiver-side delay)
0240          *
0241          * ID is implicitly disabled for 100Mbps (RG)MII operation.
0242          */
0243         phy_name = "external RGMII (no delay)";
0244         id_mode_dis = BIT(16);
0245         port_ctrl = PORT_MODE_EXT_GPHY;
0246         break;
0247 
0248     case PHY_INTERFACE_MODE_RGMII_TXID:
0249         /* RGMII_TXID:  Add 2ns delay on TXC (90 degree shift) */
0250         phy_name = "external RGMII (TX delay)";
0251         port_ctrl = PORT_MODE_EXT_GPHY;
0252         break;
0253 
0254     case PHY_INTERFACE_MODE_RGMII_RXID:
0255         phy_name = "external RGMII (RX delay)";
0256         port_ctrl = PORT_MODE_EXT_GPHY;
0257         break;
0258     default:
0259         dev_err(kdev, "unknown phy mode: %d\n", priv->phy_interface);
0260         return -EINVAL;
0261     }
0262 
0263     bcmgenet_sys_writel(priv, port_ctrl, SYS_PORT_CTRL);
0264 
0265     priv->ext_phy = !priv->internal_phy &&
0266             (priv->phy_interface != PHY_INTERFACE_MODE_MOCA);
0267 
0268     /* This is an external PHY (xMII), so we need to enable the RGMII
0269      * block for the interface to work
0270      */
0271     if (priv->ext_phy) {
0272         reg = bcmgenet_ext_readl(priv, EXT_RGMII_OOB_CTRL);
0273         reg &= ~ID_MODE_DIS;
0274         reg |= id_mode_dis;
0275         if (GENET_IS_V1(priv) || GENET_IS_V2(priv) || GENET_IS_V3(priv))
0276             reg |= RGMII_MODE_EN_V123;
0277         else
0278             reg |= RGMII_MODE_EN;
0279         bcmgenet_ext_writel(priv, reg, EXT_RGMII_OOB_CTRL);
0280     }
0281 
0282     if (init)
0283         dev_info(kdev, "configuring instance for %s\n", phy_name);
0284 
0285     return 0;
0286 }
0287 
0288 int bcmgenet_mii_probe(struct net_device *dev)
0289 {
0290     struct bcmgenet_priv *priv = netdev_priv(dev);
0291     struct device *kdev = &priv->pdev->dev;
0292     struct device_node *dn = kdev->of_node;
0293     phy_interface_t phy_iface = priv->phy_interface;
0294     struct phy_device *phydev;
0295     u32 phy_flags = PHY_BRCM_AUTO_PWRDWN_ENABLE |
0296             PHY_BRCM_DIS_TXCRXC_NOENRGY |
0297             PHY_BRCM_IDDQ_SUSPEND;
0298     int ret;
0299 
0300     /* Communicate the integrated PHY revision */
0301     if (priv->internal_phy)
0302         phy_flags = priv->gphy_rev;
0303 
0304     /* This is an ugly quirk but we have not been correctly interpreting
0305      * the phy_interface values and we have done that across different
0306      * drivers, so at least we are consistent in our mistakes.
0307      *
0308      * When the Generic PHY driver is in use either the PHY has been
0309      * strapped or programmed correctly by the boot loader so we should
0310      * stick to our incorrect interpretation since we have validated it.
0311      *
0312      * Now when a dedicated PHY driver is in use, we need to reverse the
0313      * meaning of the phy_interface_mode values to something that the PHY
0314      * driver will interpret and act on such that we have two mistakes
0315      * canceling themselves so to speak. We only do this for the two
0316      * modes that GENET driver officially supports on Broadcom STB chips:
0317      * PHY_INTERFACE_MODE_RGMII and PHY_INTERFACE_MODE_RGMII_TXID. Other
0318      * modes are not *officially* supported with the boot loader and the
0319      * scripted environment generating Device Tree blobs for those
0320      * platforms.
0321      *
0322      * Note that internal PHY, MoCA and fixed-link configurations are not
0323      * affected because they use different phy_interface_t values or the
0324      * Generic PHY driver.
0325      */
0326     switch (priv->phy_interface) {
0327     case PHY_INTERFACE_MODE_RGMII:
0328         phy_iface = PHY_INTERFACE_MODE_RGMII_ID;
0329         break;
0330     case PHY_INTERFACE_MODE_RGMII_TXID:
0331         phy_iface = PHY_INTERFACE_MODE_RGMII_RXID;
0332         break;
0333     default:
0334         break;
0335     }
0336 
0337     if (dn) {
0338         phydev = of_phy_connect(dev, priv->phy_dn, bcmgenet_mii_setup,
0339                     phy_flags, phy_iface);
0340         if (!phydev) {
0341             pr_err("could not attach to PHY\n");
0342             return -ENODEV;
0343         }
0344     } else {
0345         if (has_acpi_companion(kdev)) {
0346             char mdio_bus_id[MII_BUS_ID_SIZE];
0347             struct mii_bus *unimacbus;
0348 
0349             snprintf(mdio_bus_id, MII_BUS_ID_SIZE, "%s-%d",
0350                  UNIMAC_MDIO_DRV_NAME, priv->pdev->id);
0351 
0352             unimacbus = mdio_find_bus(mdio_bus_id);
0353             if (!unimacbus) {
0354                 pr_err("Unable to find mii\n");
0355                 return -ENODEV;
0356             }
0357             phydev = phy_find_first(unimacbus);
0358             put_device(&unimacbus->dev);
0359             if (!phydev) {
0360                 pr_err("Unable to find PHY\n");
0361                 return -ENODEV;
0362             }
0363         } else {
0364             phydev = dev->phydev;
0365         }
0366         phydev->dev_flags = phy_flags;
0367 
0368         ret = phy_connect_direct(dev, phydev, bcmgenet_mii_setup,
0369                      phy_iface);
0370         if (ret) {
0371             pr_err("could not attach to PHY\n");
0372             return -ENODEV;
0373         }
0374     }
0375 
0376     /* Configure port multiplexer based on what the probed PHY device since
0377      * reading the 'max-speed' property determines the maximum supported
0378      * PHY speed which is needed for bcmgenet_mii_config() to configure
0379      * things appropriately.
0380      */
0381     ret = bcmgenet_mii_config(dev, true);
0382     if (ret) {
0383         phy_disconnect(dev->phydev);
0384         return ret;
0385     }
0386 
0387     /* The internal PHY has its link interrupts routed to the
0388      * Ethernet MAC ISRs. On GENETv5 there is a hardware issue
0389      * that prevents the signaling of link UP interrupts when
0390      * the link operates at 10Mbps, so fallback to polling for
0391      * those versions of GENET.
0392      */
0393     if (priv->internal_phy && !GENET_IS_V5(priv))
0394         dev->phydev->irq = PHY_MAC_INTERRUPT;
0395 
0396     /* Indicate that the MAC is responsible for PHY PM */
0397     dev->phydev->mac_managed_pm = true;
0398 
0399     return 0;
0400 }
0401 
0402 static struct device_node *bcmgenet_mii_of_find_mdio(struct bcmgenet_priv *priv)
0403 {
0404     struct device_node *dn = priv->pdev->dev.of_node;
0405     struct device *kdev = &priv->pdev->dev;
0406     char *compat;
0407 
0408     compat = kasprintf(GFP_KERNEL, "brcm,genet-mdio-v%d", priv->version);
0409     if (!compat)
0410         return NULL;
0411 
0412     priv->mdio_dn = of_get_compatible_child(dn, compat);
0413     kfree(compat);
0414     if (!priv->mdio_dn) {
0415         dev_err(kdev, "unable to find MDIO bus node\n");
0416         return NULL;
0417     }
0418 
0419     return priv->mdio_dn;
0420 }
0421 
0422 static void bcmgenet_mii_pdata_init(struct bcmgenet_priv *priv,
0423                     struct unimac_mdio_pdata *ppd)
0424 {
0425     struct device *kdev = &priv->pdev->dev;
0426     struct bcmgenet_platform_data *pd = kdev->platform_data;
0427 
0428     if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
0429         /*
0430          * Internal or external PHY with MDIO access
0431          */
0432         if (pd->phy_address >= 0 && pd->phy_address < PHY_MAX_ADDR)
0433             ppd->phy_mask = 1 << pd->phy_address;
0434         else
0435             ppd->phy_mask = 0;
0436     }
0437 }
0438 
0439 static int bcmgenet_mii_wait(void *wait_func_data)
0440 {
0441     struct bcmgenet_priv *priv = wait_func_data;
0442 
0443     wait_event_timeout(priv->wq,
0444                !(bcmgenet_umac_readl(priv, UMAC_MDIO_CMD)
0445                & MDIO_START_BUSY),
0446                HZ / 100);
0447     return 0;
0448 }
0449 
0450 static int bcmgenet_mii_register(struct bcmgenet_priv *priv)
0451 {
0452     struct platform_device *pdev = priv->pdev;
0453     struct bcmgenet_platform_data *pdata = pdev->dev.platform_data;
0454     struct device_node *dn = pdev->dev.of_node;
0455     struct unimac_mdio_pdata ppd;
0456     struct platform_device *ppdev;
0457     struct resource *pres, res;
0458     int id, ret;
0459 
0460     pres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0461     if (!pres) {
0462         dev_err(&pdev->dev, "Invalid resource\n");
0463         return -EINVAL;
0464     }
0465     memset(&res, 0, sizeof(res));
0466     memset(&ppd, 0, sizeof(ppd));
0467 
0468     ppd.wait_func = bcmgenet_mii_wait;
0469     ppd.wait_func_data = priv;
0470     ppd.bus_name = "bcmgenet MII bus";
0471 
0472     /* Unimac MDIO bus controller starts at UniMAC offset + MDIO_CMD
0473      * and is 2 * 32-bits word long, 8 bytes total.
0474      */
0475     res.start = pres->start + GENET_UMAC_OFF + UMAC_MDIO_CMD;
0476     res.end = res.start + 8;
0477     res.flags = IORESOURCE_MEM;
0478 
0479     if (dn)
0480         id = of_alias_get_id(dn, "eth");
0481     else
0482         id = pdev->id;
0483 
0484     ppdev = platform_device_alloc(UNIMAC_MDIO_DRV_NAME, id);
0485     if (!ppdev)
0486         return -ENOMEM;
0487 
0488     /* Retain this platform_device pointer for later cleanup */
0489     priv->mii_pdev = ppdev;
0490     ppdev->dev.parent = &pdev->dev;
0491     if (dn)
0492         ppdev->dev.of_node = bcmgenet_mii_of_find_mdio(priv);
0493     else if (pdata)
0494         bcmgenet_mii_pdata_init(priv, &ppd);
0495     else
0496         ppd.phy_mask = ~0;
0497 
0498     ret = platform_device_add_resources(ppdev, &res, 1);
0499     if (ret)
0500         goto out;
0501 
0502     ret = platform_device_add_data(ppdev, &ppd, sizeof(ppd));
0503     if (ret)
0504         goto out;
0505 
0506     ret = platform_device_add(ppdev);
0507     if (ret)
0508         goto out;
0509 
0510     return 0;
0511 out:
0512     platform_device_put(ppdev);
0513     return ret;
0514 }
0515 
0516 static int bcmgenet_phy_interface_init(struct bcmgenet_priv *priv)
0517 {
0518     struct device *kdev = &priv->pdev->dev;
0519     int phy_mode = device_get_phy_mode(kdev);
0520 
0521     if (phy_mode < 0) {
0522         dev_err(kdev, "invalid PHY mode property\n");
0523         return phy_mode;
0524     }
0525 
0526     priv->phy_interface = phy_mode;
0527 
0528     /* We need to specifically look up whether this PHY interface is
0529      * internal or not *before* we even try to probe the PHY driver
0530      * over MDIO as we may have shut down the internal PHY for power
0531      * saving purposes.
0532      */
0533     if (priv->phy_interface == PHY_INTERFACE_MODE_INTERNAL)
0534         priv->internal_phy = true;
0535 
0536     return 0;
0537 }
0538 
0539 static int bcmgenet_mii_of_init(struct bcmgenet_priv *priv)
0540 {
0541     struct device_node *dn = priv->pdev->dev.of_node;
0542     struct phy_device *phydev;
0543     int ret;
0544 
0545     /* Fetch the PHY phandle */
0546     priv->phy_dn = of_parse_phandle(dn, "phy-handle", 0);
0547 
0548     /* In the case of a fixed PHY, the DT node associated
0549      * to the PHY is the Ethernet MAC DT node.
0550      */
0551     if (!priv->phy_dn && of_phy_is_fixed_link(dn)) {
0552         ret = of_phy_register_fixed_link(dn);
0553         if (ret)
0554             return ret;
0555 
0556         priv->phy_dn = of_node_get(dn);
0557     }
0558 
0559     /* Get the link mode */
0560     ret = bcmgenet_phy_interface_init(priv);
0561     if (ret)
0562         return ret;
0563 
0564     /* Make sure we initialize MoCA PHYs with a link down */
0565     if (priv->phy_interface == PHY_INTERFACE_MODE_MOCA) {
0566         phydev = of_phy_find_device(dn);
0567         if (phydev) {
0568             phydev->link = 0;
0569             put_device(&phydev->mdio.dev);
0570         }
0571     }
0572 
0573     return 0;
0574 }
0575 
0576 static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv)
0577 {
0578     struct device *kdev = &priv->pdev->dev;
0579     struct bcmgenet_platform_data *pd = kdev->platform_data;
0580     char phy_name[MII_BUS_ID_SIZE + 3];
0581     char mdio_bus_id[MII_BUS_ID_SIZE];
0582     struct phy_device *phydev;
0583 
0584     snprintf(mdio_bus_id, MII_BUS_ID_SIZE, "%s-%d",
0585          UNIMAC_MDIO_DRV_NAME, priv->pdev->id);
0586 
0587     if (pd->phy_interface != PHY_INTERFACE_MODE_MOCA && pd->mdio_enabled) {
0588         snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT,
0589              mdio_bus_id, pd->phy_address);
0590 
0591         /*
0592          * Internal or external PHY with MDIO access
0593          */
0594         phydev = phy_attach(priv->dev, phy_name, pd->phy_interface);
0595         if (IS_ERR(phydev)) {
0596             dev_err(kdev, "failed to register PHY device\n");
0597             return PTR_ERR(phydev);
0598         }
0599     } else {
0600         /*
0601          * MoCA port or no MDIO access.
0602          * Use fixed PHY to represent the link layer.
0603          */
0604         struct fixed_phy_status fphy_status = {
0605             .link = 1,
0606             .speed = pd->phy_speed,
0607             .duplex = pd->phy_duplex,
0608             .pause = 0,
0609             .asym_pause = 0,
0610         };
0611 
0612         phydev = fixed_phy_register(PHY_POLL, &fphy_status, NULL);
0613         if (!phydev || IS_ERR(phydev)) {
0614             dev_err(kdev, "failed to register fixed PHY device\n");
0615             return -ENODEV;
0616         }
0617 
0618         /* Make sure we initialize MoCA PHYs with a link down */
0619         phydev->link = 0;
0620 
0621     }
0622 
0623     priv->phy_interface = pd->phy_interface;
0624 
0625     return 0;
0626 }
0627 
0628 static int bcmgenet_mii_bus_init(struct bcmgenet_priv *priv)
0629 {
0630     struct device *kdev = &priv->pdev->dev;
0631     struct device_node *dn = kdev->of_node;
0632 
0633     if (dn)
0634         return bcmgenet_mii_of_init(priv);
0635     else if (has_acpi_companion(kdev))
0636         return bcmgenet_phy_interface_init(priv);
0637     else
0638         return bcmgenet_mii_pd_init(priv);
0639 }
0640 
0641 int bcmgenet_mii_init(struct net_device *dev)
0642 {
0643     struct bcmgenet_priv *priv = netdev_priv(dev);
0644     int ret;
0645 
0646     ret = bcmgenet_mii_register(priv);
0647     if (ret)
0648         return ret;
0649 
0650     ret = bcmgenet_mii_bus_init(priv);
0651     if (ret)
0652         goto out;
0653 
0654     return 0;
0655 
0656 out:
0657     bcmgenet_mii_exit(dev);
0658     return ret;
0659 }
0660 
0661 void bcmgenet_mii_exit(struct net_device *dev)
0662 {
0663     struct bcmgenet_priv *priv = netdev_priv(dev);
0664     struct device_node *dn = priv->pdev->dev.of_node;
0665 
0666     if (of_phy_is_fixed_link(dn))
0667         of_phy_deregister_fixed_link(dn);
0668     of_node_put(priv->phy_dn);
0669     platform_device_unregister(priv->mii_pdev);
0670 }