static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy) { struct phylink_link_state config; __ETHTOOL_DECLARE_LINK_MODE_MASK(supported); int ret; memset(&config, 0, sizeof(config)); linkmode_copy(supported, phy->supported); linkmode_copy(config.advertising, phy->advertising); config.interface = pl->link_config.interface; /* * This is the new way of dealing with flow control for PHYs, * as described by Timur Tabi in commit 529ed1275263 ("net: phy: * phy drivers should not set SUPPORTED_[Asym_]Pause") except * using our validate call to the MAC, we rely upon the MAC * clearing the bits from both supported and advertising fields. */ if (phylink_test(supported, Pause)) phylink_set(config.advertising, Pause); if (phylink_test(supported, Asym_Pause)) phylink_set(config.advertising, Asym_Pause); ret = phylink_validate(pl, supported, &config); if (ret) return ret; phy->phylink = pl; phy->phy_link_change = phylink_phy_change; netdev_info(pl->netdev, "PHY [%s] driver [%s]\n", dev_name(&phy->mdio.dev), phy->drv->name); mutex_lock(&phy->lock); mutex_lock(&pl->state_mutex); pl->phydev = phy; linkmode_copy(pl->supported, supported); linkmode_copy(pl->link_config.advertising, config.advertising); /* Restrict the phy advertisement according to the MAC support. */ linkmode_copy(phy->advertising, config.advertising); mutex_unlock(&pl->state_mutex); mutex_unlock(&phy->lock); netdev_dbg(pl->netdev, "phy: setting supported %*pb advertising %*pb\n", __ETHTOOL_LINK_MODE_MASK_NBITS, pl->supported, __ETHTOOL_LINK_MODE_MASK_NBITS, phy->advertising); if (phy_interrupt_is_valid(phy)) phy_request_interrupt(phy); return 0; }
static int dp83867_config_init(struct phy_device *phydev) { struct dp83867_private *dp83867; int ret, val, bs; u16 delay; if (!phydev->priv) { dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867), GFP_KERNEL); if (!dp83867) return -ENOMEM; phydev->priv = dp83867; ret = dp83867_of_init(phydev); if (ret) return ret; } else { dp83867 = (struct dp83867_private *)phydev->priv; } /* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */ if (dp83867->rxctrl_strap_quirk) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4); val &= ~BIT(7); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val); } if (phy_interface_is_rgmii(phydev)) { val = phy_read(phydev, MII_DP83867_PHYCTRL); if (val < 0) return val; val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK; val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT); /* The code below checks if "port mirroring" N/A MODE4 has been * enabled during power on bootstrap. * * Such N/A mode enabled by mistake can put PHY IC in some * internal testing mode and disable RGMII transmission. * * In this particular case one needs to check STRAP_STS1 * register's bit 11 (marked as RESERVED). */ bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS1); if (bs & DP83867_STRAP_STS1_RESERVED) val &= ~DP83867_PHYCR_RESERVED_MASK; ret = phy_write(phydev, MII_DP83867_PHYCTRL, val); if (ret) return ret; } if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) val |= DP83867_RGMII_TX_CLK_DELAY_EN; if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) val |= DP83867_RGMII_RX_CLK_DELAY_EN; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val); delay = (dp83867->rx_id_delay | (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL, delay); if (dp83867->io_impedance >= 0) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; val |= dp83867->io_impedance & DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val); } } /* Enable Interrupt output INT_OE in CFG3 register */ if (phy_interrupt_is_valid(phydev)) { val = phy_read(phydev, DP83867_CFG3); val |= BIT(7); phy_write(phydev, DP83867_CFG3, val); } if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) dp83867_config_port_mirroring(phydev); /* Clock output selection if muxing property is set */ if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK; val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val); } return 0; }
static int dp83867_config_init(struct phy_device *phydev) { struct dp83867_private *dp83867; int ret, bs; u16 val, delay, cfg2; if (!phydev->priv) { dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867), GFP_KERNEL); if (!dp83867) return -ENOMEM; phydev->priv = dp83867; ret = dp83867_of_init(phydev); if (ret) return ret; } else { dp83867 = (struct dp83867_private *)phydev->priv; } /* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */ if (dp83867->rxctrl_strap_quirk) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4); val &= ~BIT(7); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val); } if (phy_interface_is_rgmii(phydev)) { ret = phy_write(phydev, MII_DP83867_PHYCTRL, (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) | (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT)); if (ret) return ret; val = phy_read(phydev, MII_DP83867_PHYCTRL); if (val < 0) return val; val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK; val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT); /* The code below checks if "port mirroring" N/A MODE4 has been * enabled during power on bootstrap. * * Such N/A mode enabled by mistake can put PHY IC in some * internal testing mode and disable RGMII transmission. * * In this particular case one needs to check STRAP_STS1 * register's bit 11 (marked as RESERVED). */ bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS1); if (bs & DP83867_STRAP_STS1_RESERVED) val &= ~DP83867_PHYCR_RESERVED_MASK; ret = phy_write(phydev, MII_DP83867_PHYCTRL, val); if (ret) return ret; } else { /* Set SGMIICTL1 6-wire mode */ if (dp83867->wiremode_6) phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIITYPE, DP83867_SGMIICLK_EN); phy_write(phydev, MII_BMCR, (BMCR_ANENABLE | BMCR_FULLDPLX | BMCR_SPEED1000)); cfg2 = phy_read(phydev, MII_DP83867_CFG2); cfg2 &= MII_DP83867_CFG2_MASK; cfg2 |= (MII_DP83867_CFG2_SPEEDOPT_10EN | MII_DP83867_CFG2_SGMII_AUTONEGEN | MII_DP83867_CFG2_SPEEDOPT_ENH | MII_DP83867_CFG2_SPEEDOPT_CNT | MII_DP83867_CFG2_SPEEDOPT_INTLOW); phy_write(phydev, MII_DP83867_CFG2, cfg2); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, 0x0); phy_write(phydev, MII_DP83867_PHYCTRL, DP83867_PHYCTRL_SGMIIEN | (DP83867_MDI_CROSSOVER_MDIX << DP83867_MDI_CROSSOVER) | (dp83867->fifo_depth << DP83867_PHYCTRL_RXFIFO_SHIFT) | (dp83867->fifo_depth << DP83867_PHYCTRL_TXFIFO_SHIFT)); phy_write(phydev, MII_DP83867_BISCR, 0x0); /* This is a SW workaround for link instability if * RX_CTRL is not strapped to mode 3 or 4 in HW. */ if (dp83867->rxctrl_strap_quirk) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4); val &= ~DP83867_CFG4_RESVDBIT7; val |= DP83867_CFG4_RESVDBIT8; val &= ~DP83867_CFG4_SGMII_AUTONEG_TIMER_MASK; val |= DP83867_CFG4_SGMII_AUTONEG_TIMER_11MS; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val); } } if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) val |= DP83867_RGMII_TX_CLK_DELAY_EN; if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) val |= DP83867_RGMII_RX_CLK_DELAY_EN; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val); delay = (dp83867->rx_id_delay | (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT)); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL, delay); if (dp83867->io_impedance >= 0) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; val |= dp83867->io_impedance & DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL; phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val); } } /* Enable Interrupt output INT_OE in CFG3 register */ if (phy_interrupt_is_valid(phydev)) { val = phy_read(phydev, DP83867_CFG3); val |= BIT(7); phy_write(phydev, DP83867_CFG3, val); } if (dp83867->port_mirroring != DP83867_PORT_MIRROING_KEEP) dp83867_config_port_mirroring(phydev); /* Clock output selection if muxing property is set */ if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) { val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG); val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK; val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT); phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val); } return 0; }