b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | From 98f64a89977a32df96cdb8aaf3884086b2309924 Mon Sep 17 00:00:00 2001 |
| 2 | From: Alex Marginean <alexandru.marginean@nxp.com> |
| 3 | Date: Tue, 27 Aug 2019 15:14:11 +0300 |
| 4 | Subject: [PATCH] enetc: Use DT protocol information to set up the ports |
| 5 | |
| 6 | Use DT information rather than in-band information from bootloader to |
| 7 | set up MAC for XGMII. For RGMII use the DT indication in addition to |
| 8 | RGMII defaults in hardware. |
| 9 | However, this implies that PHY connection information needs to be |
| 10 | extracted before netdevice creation, when the ENETC Port MAC is |
| 11 | being configured. |
| 12 | |
| 13 | Signed-off-by: Alex Marginean <alexandru.marginean@nxp.com> |
| 14 | Signed-off-by: Claudiu Manoil <claudiu.manoil@nxp.com> |
| 15 | --- |
| 16 | drivers/net/ethernet/freescale/enetc/enetc_pf.c | 55 ++++++++++++++----------- |
| 17 | drivers/net/ethernet/freescale/enetc/enetc_pf.h | 3 ++ |
| 18 | 2 files changed, 33 insertions(+), 25 deletions(-) |
| 19 | |
| 20 | --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c |
| 21 | +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c |
| 22 | @@ -507,7 +507,8 @@ static void enetc_port_si_configure(stru |
| 23 | enetc_port_wr(hw, ENETC_PSIVLANFMR, ENETC_PSIVLANFMR_VS); |
| 24 | } |
| 25 | |
| 26 | -static void enetc_configure_port_mac(struct enetc_hw *hw) |
| 27 | +static void enetc_configure_port_mac(struct enetc_hw *hw, |
| 28 | + phy_interface_t phy_mode) |
| 29 | { |
| 30 | enetc_port_wr(hw, ENETC_PM0_MAXFRM, |
| 31 | ENETC_SET_MAXFRM(ENETC_RX_MAXFRM_SIZE)); |
| 32 | @@ -523,9 +524,11 @@ static void enetc_configure_port_mac(str |
| 33 | ENETC_PM0_CMD_TXP | ENETC_PM0_PROMISC | |
| 34 | ENETC_PM0_TX_EN | ENETC_PM0_RX_EN); |
| 35 | /* set auto-speed for RGMII */ |
| 36 | - if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG) |
| 37 | + if (enetc_port_rd(hw, ENETC_PM0_IF_MODE) & ENETC_PMO_IFM_RG || |
| 38 | + phy_mode == PHY_INTERFACE_MODE_RGMII) |
| 39 | enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_RGAUTO); |
| 40 | - if (enetc_global_rd(hw, ENETC_G_EPFBLPR(1)) == ENETC_G_EPFBLPR1_XGMII) |
| 41 | + |
| 42 | + if (phy_mode == PHY_INTERFACE_MODE_XGMII) |
| 43 | enetc_port_wr(hw, ENETC_PM0_IF_MODE, ENETC_PM0_IFM_XGMII); |
| 44 | } |
| 45 | |
| 46 | @@ -549,7 +552,7 @@ static void enetc_configure_port(struct |
| 47 | |
| 48 | enetc_configure_port_pmac(hw); |
| 49 | |
| 50 | - enetc_configure_port_mac(hw); |
| 51 | + enetc_configure_port_mac(hw, pf->if_mode); |
| 52 | |
| 53 | enetc_port_si_configure(pf->si); |
| 54 | |
| 55 | @@ -749,28 +752,28 @@ static void enetc_pf_netdev_setup(struct |
| 56 | enetc_get_primary_mac_addr(&si->hw, ndev->dev_addr); |
| 57 | } |
| 58 | |
| 59 | -static int enetc_of_get_phy(struct enetc_ndev_priv *priv) |
| 60 | +static int enetc_of_get_phy(struct enetc_pf *pf) |
| 61 | { |
| 62 | - struct enetc_pf *pf = enetc_si_priv(priv->si); |
| 63 | - struct device_node *np = priv->dev->of_node; |
| 64 | + struct device *dev = &pf->si->pdev->dev; |
| 65 | + struct device_node *np = dev->of_node; |
| 66 | struct device_node *mdio_np; |
| 67 | int phy_mode; |
| 68 | int err; |
| 69 | |
| 70 | - priv->phy_node = of_parse_phandle(np, "phy-handle", 0); |
| 71 | - if (!priv->phy_node) { |
| 72 | + pf->phy_node = of_parse_phandle(np, "phy-handle", 0); |
| 73 | + if (!pf->phy_node) { |
| 74 | if (!of_phy_is_fixed_link(np)) { |
| 75 | - dev_err(priv->dev, "PHY not specified\n"); |
| 76 | + dev_err(dev, "PHY not specified\n"); |
| 77 | return -ENODEV; |
| 78 | } |
| 79 | |
| 80 | err = of_phy_register_fixed_link(np); |
| 81 | if (err < 0) { |
| 82 | - dev_err(priv->dev, "fixed link registration failed\n"); |
| 83 | + dev_err(dev, "fixed link registration failed\n"); |
| 84 | return err; |
| 85 | } |
| 86 | |
| 87 | - priv->phy_node = of_node_get(np); |
| 88 | + pf->phy_node = of_node_get(np); |
| 89 | } |
| 90 | |
| 91 | mdio_np = of_get_child_by_name(np, "mdio"); |
| 92 | @@ -778,28 +781,28 @@ static int enetc_of_get_phy(struct enetc |
| 93 | of_node_put(mdio_np); |
| 94 | err = enetc_mdio_probe(pf); |
| 95 | if (err) { |
| 96 | - of_node_put(priv->phy_node); |
| 97 | + of_node_put(pf->phy_node); |
| 98 | return err; |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | phy_mode = of_get_phy_mode(np); |
| 103 | if (phy_mode < 0) |
| 104 | - priv->if_mode = PHY_INTERFACE_MODE_NA; /* fixed link */ |
| 105 | + pf->if_mode = PHY_INTERFACE_MODE_NA; /* fixed link */ |
| 106 | else |
| 107 | - priv->if_mode = phy_mode; |
| 108 | + pf->if_mode = phy_mode; |
| 109 | |
| 110 | return 0; |
| 111 | } |
| 112 | |
| 113 | -static void enetc_of_put_phy(struct enetc_ndev_priv *priv) |
| 114 | +static void enetc_of_put_phy(struct enetc_pf *pf) |
| 115 | { |
| 116 | - struct device_node *np = priv->dev->of_node; |
| 117 | + struct device_node *np = pf->si->pdev->dev.of_node; |
| 118 | |
| 119 | if (np && of_phy_is_fixed_link(np)) |
| 120 | of_phy_deregister_fixed_link(np); |
| 121 | - if (priv->phy_node) |
| 122 | - of_node_put(priv->phy_node); |
| 123 | + if (pf->phy_node) |
| 124 | + of_node_put(pf->phy_node); |
| 125 | } |
| 126 | |
| 127 | /* Initialize the entire shared memory for the flow steering entries |
| 128 | @@ -955,6 +958,10 @@ static int enetc_pf_probe(struct pci_dev |
| 129 | pf->si = si; |
| 130 | pf->total_vfs = pci_sriov_get_totalvfs(pdev); |
| 131 | |
| 132 | + err = enetc_of_get_phy(pf); |
| 133 | + if (err) |
| 134 | + dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); |
| 135 | + |
| 136 | enetc_configure_port(pf); |
| 137 | |
| 138 | enetc_get_si_caps(si); |
| 139 | @@ -969,6 +976,8 @@ static int enetc_pf_probe(struct pci_dev |
| 140 | enetc_pf_netdev_setup(si, ndev, &enetc_ndev_ops); |
| 141 | |
| 142 | priv = netdev_priv(ndev); |
| 143 | + priv->phy_node = pf->phy_node; |
| 144 | + priv->if_mode = pf->if_mode; |
| 145 | |
| 146 | enetc_init_si_rings_params(priv); |
| 147 | |
| 148 | @@ -1002,10 +1011,6 @@ static int enetc_pf_probe(struct pci_dev |
| 149 | goto err_alloc_msix; |
| 150 | } |
| 151 | |
| 152 | - err = enetc_of_get_phy(priv); |
| 153 | - if (err) |
| 154 | - dev_warn(&pdev->dev, "Fallback to PHY-less operation\n"); |
| 155 | - |
| 156 | err = enetc_configure_serdes(priv); |
| 157 | if (err) |
| 158 | dev_warn(&pdev->dev, "Attempted serdes config but failed\n"); |
| 159 | @@ -1023,7 +1028,6 @@ static int enetc_pf_probe(struct pci_dev |
| 160 | |
| 161 | err_reg_netdev: |
| 162 | enetc_mdio_remove(pf); |
| 163 | - enetc_of_put_phy(priv); |
| 164 | enetc_free_msix(priv); |
| 165 | err_config_si: |
| 166 | err_init_port_rss: |
| 167 | @@ -1034,6 +1038,7 @@ err_alloc_si_res: |
| 168 | si->ndev = NULL; |
| 169 | free_netdev(ndev); |
| 170 | err_alloc_netdev: |
| 171 | + enetc_of_put_phy(pf); |
| 172 | err_device_disabled: |
| 173 | err_map_pf_space: |
| 174 | enetc_pci_remove(pdev); |
| 175 | @@ -1057,7 +1062,7 @@ static void enetc_pf_remove(struct pci_d |
| 176 | unregister_netdev(si->ndev); |
| 177 | |
| 178 | enetc_mdio_remove(pf); |
| 179 | - enetc_of_put_phy(priv); |
| 180 | + enetc_of_put_phy(pf); |
| 181 | |
| 182 | enetc_free_msix(priv); |
| 183 | |
| 184 | --- a/drivers/net/ethernet/freescale/enetc/enetc_pf.h |
| 185 | +++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.h |
| 186 | @@ -45,6 +45,9 @@ struct enetc_pf { |
| 187 | |
| 188 | struct mii_bus *mdio; /* saved for cleanup */ |
| 189 | struct mii_bus *imdio; |
| 190 | + |
| 191 | + struct device_node *phy_node; |
| 192 | + phy_interface_t if_mode; |
| 193 | }; |
| 194 | |
| 195 | int enetc_msg_psi_init(struct enetc_pf *pf); |