net: enetc: Use DT protocol information to set up the ports
Use DT information rather than in-band information from bootloader to set up MAC for XGMII. For RGMII use the DT indication in addition to RGMII defaults in hardware. However, this implies that PHY connection information needs to be extracted before netdevice creation, when the ENETC Port MAC is being configured. Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com> Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com> Signed-off-by: Michael Walle <michael@walle.cc> Tested-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
975d183ef0
commit
07095c025a
|
@ -482,7 +482,8 @@ static void enetc_port_si_configure(struct enetc_si *si)
|
||||||
enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS);
|
enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enetc_configure_port_mac(struct enetc_hw *hw)
|
static void enetc_configure_port_mac(struct enetc_hw *hw,
|
||||||
|
phy_interface_t phy_mode)
|
||||||
{
|
{
|
||||||
enetc_port_wr(hw, ENETC_PM0_MAXFRM,
|
enetc_port_wr(hw, ENETC_PM0_MAXFRM,
|
||||||
ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE));
|
ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE));
|
||||||
|
@ -498,9 +499,11 @@ static void enetc_configure_port_mac(struct enetc_hw *hw)
|
||||||
ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC |
|
ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC |
|
||||||
ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
|
ENETC_PM0_TX_EN | ENETC_PM0_RX_EN);
|
||||||
/* set auto-speed for RGMII */
|
/* set auto-speed for RGMII */
|
||||||
if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG)
|
if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG ||
|
||||||
|
phy_interface_mode_is_rgmii(phy_mode))
|
||||||
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO);
|
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO);
|
||||||
if (enetc_global_rd(hw, ENETC_G_EPFBLPR(1)) == ENETC_G_EPFBLPR1_XGMII)
|
|
||||||
|
if (phy_mode == PHY_INTERFACE_MODE_USXGMII)
|
||||||
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII);
|
enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +527,7 @@ static void enetc_configure_port(struct enetc_pf *pf)
|
||||||
|
|
||||||
enetc_configure_port_pmac(hw);
|
enetc_configure_port_pmac(hw);
|
||||||
|
|
||||||
enetc_configure_port_mac(hw);
|
enetc_configure_port_mac(hw, pf->if_mode);
|
||||||
|
|
||||||
enetc_port_si_configure(pf->si);
|
enetc_port_si_configure(pf->si);
|
||||||
|
|
||||||
|
@ -776,27 +779,27 @@ static void enetc_mdio_remove(struct enetc_pf *pf)
|
||||||
mdiobus_unregister(pf->mdio);
|
mdiobus_unregister(pf->mdio);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
|
static int enetc_of_get_phy(struct enetc_pf *pf)
|
||||||
{
|
{
|
||||||
struct enetc_pf *pf = enetc_si_priv(priv->si);
|
struct device *dev = &pf->si->pdev->dev;
|
||||||
struct device_node *np = priv->dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
struct device_node *mdio_np;
|
struct device_node *mdio_np;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
pf->phy_node = of_parse_phandle(np, "phy-handle", 0);
|
||||||
if (!priv->phy_node) {
|
if (!pf->phy_node) {
|
||||||
if (!of_phy_is_fixed_link(np)) {
|
if (!of_phy_is_fixed_link(np)) {
|
||||||
dev_err(priv->dev, "PHY not specified\n");
|
dev_err(dev, "PHY not specified\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = of_phy_register_fixed_link(np);
|
err = of_phy_register_fixed_link(np);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(priv->dev, "fixed link registration failed\n");
|
dev_err(dev, "fixed link registration failed\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->phy_node = of_node_get(np);
|
pf->phy_node = of_node_get(np);
|
||||||
}
|
}
|
||||||
|
|
||||||
mdio_np = of_get_child_by_name(np, "mdio");
|
mdio_np = of_get_child_by_name(np, "mdio");
|
||||||
|
@ -804,15 +807,15 @@ static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
|
||||||
of_node_put(mdio_np);
|
of_node_put(mdio_np);
|
||||||
err = enetc_mdio_probe(pf);
|
err = enetc_mdio_probe(pf);
|
||||||
if (err) {
|
if (err) {
|
||||||
of_node_put(priv->phy_node);
|
of_node_put(pf->phy_node);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = of_get_phy_mode(np, &priv->if_mode);
|
err = of_get_phy_mode(np, &pf->if_mode);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(priv->dev, "missing phy type\n");
|
dev_err(dev, "missing phy type\n");
|
||||||
of_node_put(priv->phy_node);
|
of_node_put(pf->phy_node);
|
||||||
if (of_phy_is_fixed_link(np))
|
if (of_phy_is_fixed_link(np))
|
||||||
of_phy_deregister_fixed_link(np);
|
of_phy_deregister_fixed_link(np);
|
||||||
else
|
else
|
||||||
|
@ -824,14 +827,14 @@ static int enetc_of_get_phy(struct enetc_ndev_priv *priv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void enetc_of_put_phy(struct enetc_ndev_priv *priv)
|
static void enetc_of_put_phy(struct enetc_pf *pf)
|
||||||
{
|
{
|
||||||
struct device_node *np = priv->dev->of_node;
|
struct device_node *np = pf->si->pdev->dev.of_node;
|
||||||
|
|
||||||
if (np && of_phy_is_fixed_link(np))
|
if (np && of_phy_is_fixed_link(np))
|
||||||
of_phy_deregister_fixed_link(np);
|
of_phy_deregister_fixed_link(np);
|
||||||
if (priv->phy_node)
|
if (pf->phy_node)
|
||||||
of_node_put(priv->phy_node);
|
of_node_put(pf->phy_node);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int enetc_imdio_init(struct enetc_pf *pf, bool is_c45)
|
static int enetc_imdio_init(struct enetc_pf *pf, bool is_c45)
|
||||||
|
@ -994,6 +997,10 @@ static int enetc_pf_probe(struct pci_dev *pdev,
|
||||||
pf->si = si;
|
pf->si = si;
|
||||||
pf->total_vfs = pci_sriov_get_totalvfs(pdev);
|
pf->total_vfs = pci_sriov_get_totalvfs(pdev);
|
||||||
|
|
||||||
|
err = enetc_of_get_phy(pf);
|
||||||
|
if (err)
|
||||||
|
dev_warn(&pdev->dev, "Fallback to PHY-less operation\n");
|
||||||
|
|
||||||
enetc_configure_port(pf);
|
enetc_configure_port(pf);
|
||||||
|
|
||||||
enetc_get_si_caps(si);
|
enetc_get_si_caps(si);
|
||||||
|
@ -1008,6 +1015,8 @@ static int enetc_pf_probe(struct pci_dev *pdev,
|
||||||
enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops);
|
enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops);
|
||||||
|
|
||||||
priv = netdev_priv(ndev);
|
priv = netdev_priv(ndev);
|
||||||
|
priv->phy_node = pf->phy_node;
|
||||||
|
priv->if_mode = pf->if_mode;
|
||||||
|
|
||||||
enetc_init_si_rings_params(priv);
|
enetc_init_si_rings_params(priv);
|
||||||
|
|
||||||
|
@ -1023,10 +1032,6 @@ static int enetc_pf_probe(struct pci_dev *pdev,
|
||||||
goto err_alloc_msix;
|
goto err_alloc_msix;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = enetc_of_get_phy(priv);
|
|
||||||
if (err)
|
|
||||||
dev_warn(&pdev->dev, "Fallback to PHY-less operation\n");
|
|
||||||
|
|
||||||
err = enetc_configure_serdes(priv);
|
err = enetc_configure_serdes(priv);
|
||||||
if (err)
|
if (err)
|
||||||
dev_warn(&pdev->dev, "Attempted SerDes config but failed\n");
|
dev_warn(&pdev->dev, "Attempted SerDes config but failed\n");
|
||||||
|
@ -1040,7 +1045,6 @@ static int enetc_pf_probe(struct pci_dev *pdev,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_reg_netdev:
|
err_reg_netdev:
|
||||||
enetc_of_put_phy(priv);
|
|
||||||
enetc_free_msix(priv);
|
enetc_free_msix(priv);
|
||||||
err_alloc_msix:
|
err_alloc_msix:
|
||||||
enetc_free_si_resources(priv);
|
enetc_free_si_resources(priv);
|
||||||
|
@ -1048,6 +1052,7 @@ err_alloc_si_res:
|
||||||
si->ndev = NULL;
|
si->ndev = NULL;
|
||||||
free_netdev(ndev);
|
free_netdev(ndev);
|
||||||
err_alloc_netdev:
|
err_alloc_netdev:
|
||||||
|
enetc_of_put_phy(pf);
|
||||||
err_map_pf_space:
|
err_map_pf_space:
|
||||||
enetc_pci_remove(pdev);
|
enetc_pci_remove(pdev);
|
||||||
|
|
||||||
|
@ -1068,7 +1073,7 @@ static void enetc_pf_remove(struct pci_dev *pdev)
|
||||||
|
|
||||||
enetc_imdio_remove(pf);
|
enetc_imdio_remove(pf);
|
||||||
enetc_mdio_remove(pf);
|
enetc_mdio_remove(pf);
|
||||||
enetc_of_put_phy(priv);
|
enetc_of_put_phy(pf);
|
||||||
|
|
||||||
enetc_free_msix(priv);
|
enetc_free_msix(priv);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,9 @@ struct enetc_pf {
|
||||||
struct mii_bus *mdio; /* saved for cleanup */
|
struct mii_bus *mdio; /* saved for cleanup */
|
||||||
struct mii_bus *imdio;
|
struct mii_bus *imdio;
|
||||||
struct phy_device *pcs;
|
struct phy_device *pcs;
|
||||||
|
|
||||||
|
struct device_node *phy_node;
|
||||||
|
phy_interface_t if_mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
int enetc_msg_psi_init(struct enetc_pf *pf);
|
int enetc_msg_psi_init(struct enetc_pf *pf);
|
||||||
|
|
Loading…
Reference in New Issue