diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c')
| -rw-r--r-- | drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index aad1be1ec4c1..f5f9fa67ecd7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -6,6 +6,7 @@ #include <linux/pci.h> #include <linux/dmi.h> #include <linux/platform_data/x86/intel_pmc_ipc.h> +#include <asm/cpuid/api.h> #include "dwmac-intel.h" #include "dwmac4.h" #include "stmmac.h" @@ -298,7 +299,7 @@ static void tgl_get_interfaces(struct stmmac_priv *priv, void *bsp_priv, if (FIELD_GET(SERDES_LINK_MODE_MASK, data) == SERDES_LINK_MODE_2G5) { dev_info(priv->device, "Link Speed Mode: 2.5Gbps\n"); - priv->plat->mdio_bus_data->default_an_inband = false; + priv->plat->default_an_inband = false; interface = PHY_INTERFACE_MODE_2500BASEX; } else { interface = PHY_INTERFACE_MODE_SGMII; @@ -524,6 +525,32 @@ static int intel_set_reg_access(const struct pmc_serdes_regs *regs, int max_regs return ret; } +/* + * Return true if the SerDes lane rate must change to serve @interface. + * If the current rate cannot be determined, reconfigure as before. + */ +static bool intel_serdes_needs_reconfig(struct stmmac_priv *priv, + struct intel_priv_data *intel_priv, + phy_interface_t interface) +{ + u32 cur_rate, want_rate; + int data; + + if (!intel_priv->mdio_adhoc_addr) + return true; + + data = mdiobus_read(priv->mii, intel_priv->mdio_adhoc_addr, + SERDES_GCR0); + if (data < 0) + return true; + + cur_rate = (data & SERDES_RATE_MASK) >> SERDES_RATE_PCIE_SHIFT; + want_rate = interface == PHY_INTERFACE_MODE_2500BASEX ? + SERDES_RATE_PCIE_GEN2 : SERDES_RATE_PCIE_GEN1; + + return cur_rate != want_rate; +} + static int intel_mac_finish(struct net_device *ndev, void *intel_data, unsigned int mode, @@ -535,6 +562,11 @@ static int intel_mac_finish(struct net_device *ndev, int max_regs = 0; int ret = 0; + if (!intel_serdes_needs_reconfig(priv, intel_priv, interface)) { + priv->plat->phy_interface = interface; + return 0; + } + ret = intel_tsn_lane_is_available(ndev, intel_priv); if (ret < 0) { netdev_info(priv->dev, "No TSN lane available to set the registers.\n"); @@ -566,7 +598,7 @@ static void common_default_data(struct plat_stmmacenet_data *plat) /* clk_csr_i = 20-35MHz & MDC = clk_csr_i/16 */ plat->clk_csr = STMMAC_CSR_20_35M; plat->core_type = DWMAC_CORE_GMAC; - plat->force_sf_dma_mode = 1; + plat->force_sf_dma_mode = true; plat->mdio_bus_data->needs_reset = true; } @@ -589,7 +621,7 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, int ret; int i; - plat->pdev = pdev; + plat->provide_bus_info = true; plat->phy_addr = -1; plat->clk_csr = STMMAC_CSR_250_300M; plat->core_type = DWMAC_CORE_GMAC4; @@ -636,8 +668,6 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, plat->dma_cfg->pbl = 32; plat->dma_cfg->pblx8 = true; - plat->dma_cfg->fixed_burst = 0; - plat->dma_cfg->mixed_burst = 0; plat->dma_cfg->aal = 0; plat->dma_cfg->dche = true; @@ -701,8 +731,8 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, /* Intel mgbe SGMII interface uses pcs-xcps */ if (plat->phy_interface == PHY_INTERFACE_MODE_SGMII || plat->phy_interface == PHY_INTERFACE_MODE_1000BASEX) { - plat->mdio_bus_data->pcs_mask = BIT(INTEL_MGBE_XPCS_ADDR); - plat->mdio_bus_data->default_an_inband = true; + plat->mdio_bus_data->pcs_mask = BIT_U32(INTEL_MGBE_XPCS_ADDR); + plat->default_an_inband = true; plat->select_pcs = intel_mgbe_select_pcs; } @@ -719,7 +749,6 @@ static int intel_mgbe_common_data(struct pci_dev *pdev, /* Setup MSI vector offset specific to Intel mGbE controller */ plat->msi_mac_vec = 29; - plat->msi_lpi_vec = 28; plat->msi_sfty_ce_vec = 27; plat->msi_sfty_ue_vec = 26; plat->msi_rx_base_vec = 0; @@ -1107,7 +1136,7 @@ static int quark_default_data(struct pci_dev *pdev, plat->dma_cfg->pbl = 16; plat->dma_cfg->pblx8 = true; - plat->dma_cfg->fixed_burst = 1; + plat->dma_cfg->fixed_burst = true; /* AXI (TODO) */ return 0; @@ -1177,8 +1206,6 @@ static int stmmac_config_multi_msi(struct pci_dev *pdev, res->irq = pci_irq_vector(pdev, plat->msi_mac_vec); if (plat->msi_wol_vec < STMMAC_MSI_VEC_MAX) res->wol_irq = pci_irq_vector(pdev, plat->msi_wol_vec); - if (plat->msi_lpi_vec < STMMAC_MSI_VEC_MAX) - res->lpi_irq = pci_irq_vector(pdev, plat->msi_lpi_vec); if (plat->msi_sfty_ce_vec < STMMAC_MSI_VEC_MAX) res->sfty_ce_irq = pci_irq_vector(pdev, plat->msi_sfty_ce_vec); if (plat->msi_sfty_ue_vec < STMMAC_MSI_VEC_MAX) @@ -1256,11 +1283,6 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, if (!plat->mdio_bus_data) return -ENOMEM; - plat->dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->dma_cfg), - GFP_KERNEL); - if (!plat->dma_cfg) - return -ENOMEM; - plat->safety_feat_cfg = devm_kzalloc(&pdev->dev, sizeof(*plat->safety_feat_cfg), GFP_KERNEL); @@ -1294,7 +1316,6 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, */ plat->msi_mac_vec = STMMAC_MSI_VEC_MAX; plat->msi_wol_vec = STMMAC_MSI_VEC_MAX; - plat->msi_lpi_vec = STMMAC_MSI_VEC_MAX; plat->msi_sfty_ce_vec = STMMAC_MSI_VEC_MAX; plat->msi_sfty_ue_vec = STMMAC_MSI_VEC_MAX; plat->msi_rx_base_vec = STMMAC_MSI_VEC_MAX; @@ -1327,6 +1348,7 @@ static int intel_eth_pci_probe(struct pci_dev *pdev, err_alloc_irq: clk_disable_unprepare(plat->stmmac_clk); clk_unregister_fixed_rate(plat->stmmac_clk); + pci_free_irq_vectors(pdev); return ret; } @@ -1346,6 +1368,7 @@ static void intel_eth_pci_remove(struct pci_dev *pdev) clk_disable_unprepare(priv->plat->stmmac_clk); clk_unregister_fixed_rate(priv->plat->stmmac_clk); + pci_free_irq_vectors(pdev); } #define PCI_DEVICE_ID_INTEL_QUARK 0x0937 |
