diff options
Diffstat (limited to 'drivers/net/ethernet/stmicro')
18 files changed, 447 insertions, 657 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index ea5da5793362..cbffccb3b9af 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -396,17 +396,6 @@ enum request_irq_err { #define CORE_IRQ_MTL_RX_OVERFLOW BIT(8) -/* Physical Coding Sublayer */ -struct rgmii_adv { - unsigned int pause; - unsigned int duplex; - unsigned int lp_pause; - unsigned int lp_duplex; -}; - -#define STMMAC_PCS_PAUSE 1 -#define STMMAC_PCS_ASYM_PAUSE 2 - /* DMA HW capabilities */ struct dma_features { unsigned int mbps_10_100; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c index 9a47015254bb..ea33ae39be6b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-intel.c @@ -433,6 +433,12 @@ static int intel_crosststamp(ktime_t *device, return -ETIMEDOUT; } + *system = (struct system_counterval_t) { + .cycles = 0, + .cs_id = CSID_X86_ART, + .use_nsecs = false, + }; + num_snapshot = (readl(ioaddr + GMAC_TIMESTAMP_STATUS) & GMAC_TIMESTAMP_ATSNS_MASK) >> GMAC_TIMESTAMP_ATSNS_SHIFT; @@ -448,7 +454,7 @@ static int intel_crosststamp(ktime_t *device, } system->cycles *= intel_priv->crossts_adj; - system->cs_id = CSID_X86_ART; + priv->plat->flags &= ~STMMAC_FLAG_INT_SNAPSHOT_EN; return 0; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c index 3e86810717d3..32b5d1492e2e 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-loongson1.c @@ -44,24 +44,50 @@ struct ls1x_dwmac { struct plat_stmmacenet_data *plat_dat; struct regmap *regmap; + unsigned int id; }; -static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv) +struct ls1x_data { + int (*setup)(struct platform_device *pdev, + struct plat_stmmacenet_data *plat_dat); + int (*init)(struct platform_device *pdev, void *bsp_priv); +}; + +static int ls1b_dwmac_setup(struct platform_device *pdev, + struct plat_stmmacenet_data *plat_dat) { - struct ls1x_dwmac *dwmac = priv; - struct plat_stmmacenet_data *plat = dwmac->plat_dat; - struct regmap *regmap = dwmac->regmap; + struct ls1x_dwmac *dwmac = plat_dat->bsp_priv; struct resource *res; - unsigned long reg_base; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { + /* This shouldn't fail - stmmac_get_platform_resources() + * already mapped this resource. + */ dev_err(&pdev->dev, "Could not get IO_MEM resources\n"); return -EINVAL; } - reg_base = (unsigned long)res->start; - if (reg_base == LS1B_GMAC0_BASE) { + if (res->start == LS1B_GMAC0_BASE) { + dwmac->id = 0; + } else if (res->start == LS1B_GMAC1_BASE) { + dwmac->id = 1; + } else { + dev_err(&pdev->dev, "Invalid Ethernet MAC base address %pR", + res); + return -EINVAL; + } + + return 0; +} + +static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv) +{ + struct ls1x_dwmac *dwmac = priv; + struct plat_stmmacenet_data *plat = dwmac->plat_dat; + struct regmap *regmap = dwmac->regmap; + + if (dwmac->id == 0) { switch (plat->phy_interface) { case PHY_INTERFACE_MODE_RGMII_ID: regmap_update_bits(regmap, LS1X_SYSCON0, @@ -80,7 +106,7 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv) } regmap_update_bits(regmap, LS1X_SYSCON0, GMAC0_SHUT, 0); - } else if (reg_base == LS1B_GMAC1_BASE) { + } else if (dwmac->id == 1) { regmap_update_bits(regmap, LS1X_SYSCON0, GMAC1_USE_UART1 | GMAC1_USE_UART0, GMAC1_USE_UART1 | GMAC1_USE_UART0); @@ -104,10 +130,6 @@ static int ls1b_dwmac_syscon_init(struct platform_device *pdev, void *priv) } regmap_update_bits(regmap, LS1X_SYSCON1, GMAC1_SHUT, 0); - } else { - dev_err(&pdev->dev, "Invalid Ethernet MAC base address %lx", - reg_base); - return -EINVAL; } return 0; @@ -143,9 +165,9 @@ static int ls1x_dwmac_probe(struct platform_device *pdev) { struct plat_stmmacenet_data *plat_dat; struct stmmac_resources stmmac_res; + const struct ls1x_data *data; struct regmap *regmap; struct ls1x_dwmac *dwmac; - int (*init)(struct platform_device *pdev, void *priv); int ret; ret = stmmac_get_platform_resources(pdev, &stmmac_res); @@ -159,8 +181,8 @@ static int ls1x_dwmac_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(regmap), "Unable to find syscon\n"); - init = of_device_get_match_data(&pdev->dev); - if (!init) { + data = of_device_get_match_data(&pdev->dev); + if (!data) { dev_err(&pdev->dev, "No of match data provided\n"); return -EINVAL; } @@ -175,21 +197,36 @@ static int ls1x_dwmac_probe(struct platform_device *pdev) "dt configuration failed\n"); plat_dat->bsp_priv = dwmac; - plat_dat->init = init; + plat_dat->init = data->init; dwmac->plat_dat = plat_dat; dwmac->regmap = regmap; + if (data->setup) { + ret = data->setup(pdev, plat_dat); + if (ret) + return ret; + } + return devm_stmmac_pltfr_probe(pdev, plat_dat, &stmmac_res); } +static const struct ls1x_data ls1b_dwmac_data = { + .setup = ls1b_dwmac_setup, + .init = ls1b_dwmac_syscon_init, +}; + +static const struct ls1x_data ls1c_dwmac_data = { + .init = ls1c_dwmac_syscon_init, +}; + static const struct of_device_id ls1x_dwmac_match[] = { { .compatible = "loongson,ls1b-gmac", - .data = &ls1b_dwmac_syscon_init, + .data = &ls1b_dwmac_data, }, { .compatible = "loongson,ls1c-emac", - .data = &ls1c_dwmac_syscon_init, + .data = &ls1c_dwmac_data, }, { } }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c index 22653ffd2a04..c0c44916f849 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-lpc18xx.c @@ -41,6 +41,7 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev) if (IS_ERR(plat_dat)) return PTR_ERR(plat_dat); + plat_dat->mac_interface = PHY_INTERFACE_MODE_NA; plat_dat->has_gmac = true; reg = syscon_regmap_lookup_by_compatible("nxp,lpc1850-creg"); @@ -49,9 +50,9 @@ static int lpc18xx_dwmac_probe(struct platform_device *pdev) return PTR_ERR(reg); } - if (plat_dat->mac_interface == PHY_INTERFACE_MODE_MII) { + if (plat_dat->phy_interface == PHY_INTERFACE_MODE_MII) { ethmode = LPC18XX_CREG_CREG6_ETHMODE_MII; - } else if (plat_dat->mac_interface == PHY_INTERFACE_MODE_RMII) { + } else if (plat_dat->phy_interface == PHY_INTERFACE_MODE_RMII) { ethmode = LPC18XX_CREG_CREG6_ETHMODE_RMII; } else { dev_err(&pdev->dev, "Only MII and RMII mode supported\n"); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c index e30bdf72331a..d8fd4d8f6ced 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c @@ -622,6 +622,11 @@ static void ethqos_set_serdes_speed(struct qcom_ethqos *ethqos, int speed) } } +static void ethqos_pcs_set_inband(struct stmmac_priv *priv, bool enable) +{ + stmmac_pcs_ctrl_ane(priv, enable, 0, 0); +} + /* On interface toggle MAC registers gets reset. * Configure MAC block for SGMII on ethernet phy link up */ @@ -640,7 +645,7 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos, int speed) RGMII_CONFIG2_RGMII_CLK_SEL_CFG, RGMII_IO_MACRO_CONFIG2); ethqos_set_serdes_speed(ethqos, SPEED_2500); - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 0, 0, 0); + ethqos_pcs_set_inband(priv, false); break; case SPEED_1000: val &= ~ETHQOS_MAC_CTRL_PORT_SEL; @@ -648,12 +653,12 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos, int speed) RGMII_CONFIG2_RGMII_CLK_SEL_CFG, RGMII_IO_MACRO_CONFIG2); ethqos_set_serdes_speed(ethqos, SPEED_1000); - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0); + ethqos_pcs_set_inband(priv, true); break; case SPEED_100: val |= ETHQOS_MAC_CTRL_PORT_SEL | ETHQOS_MAC_CTRL_SPEED_MODE; ethqos_set_serdes_speed(ethqos, SPEED_1000); - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0); + ethqos_pcs_set_inband(priv, true); break; case SPEED_10: val |= ETHQOS_MAC_CTRL_PORT_SEL; @@ -663,7 +668,7 @@ static int ethqos_configure_sgmii(struct qcom_ethqos *ethqos, int speed) SGMII_10M_RX_CLK_DVDR), RGMII_IO_MACRO_CONFIG); ethqos_set_serdes_speed(ethqos, SPEED_1000); - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, 0, 0); + ethqos_pcs_set_inband(priv, true); break; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c index 9a774046455b..df4ca897a60c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c @@ -136,6 +136,7 @@ static struct platform_driver renesas_gbeth_driver = { .probe = renesas_gbeth_probe, .driver = { .name = "renesas-gbeth", + .pm = &stmmac_pltfr_pm_ops, .of_match_table = renesas_gbeth_match, }, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 700858ff6f7c..79b92130a03f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -24,12 +24,21 @@ #include "stmmac_platform.h" struct rk_priv_data; + +struct rk_reg_speed_data { + unsigned int rgmii_10; + unsigned int rgmii_100; + unsigned int rgmii_1000; + unsigned int rmii_10; + unsigned int rmii_100; +}; + struct rk_gmac_ops { void (*set_to_rgmii)(struct rk_priv_data *bsp_priv, int tx_delay, int rx_delay); void (*set_to_rmii)(struct rk_priv_data *bsp_priv); - void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed); - void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed); + int (*set_speed)(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed); void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input, bool enable); void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv); @@ -58,7 +67,7 @@ enum rk_clocks_index { }; struct rk_priv_data { - struct platform_device *pdev; + struct device *dev; phy_interface_t phy_iface; int id; struct regulator *regulator; @@ -71,7 +80,6 @@ struct rk_priv_data { struct clk_bulk_data *clks; int num_clks; - struct clk *clk_mac; struct clk *clk_phy; struct reset_control *phy_reset; @@ -83,6 +91,64 @@ struct rk_priv_data { struct regmap *php_grf; }; +static int rk_set_reg_speed(struct rk_priv_data *bsp_priv, + const struct rk_reg_speed_data *rsd, + unsigned int reg, phy_interface_t interface, + int speed) +{ + unsigned int val; + + if (phy_interface_mode_is_rgmii(interface)) { + if (speed == SPEED_10) { + val = rsd->rgmii_10; + } else if (speed == SPEED_100) { + val = rsd->rgmii_100; + } else if (speed == SPEED_1000) { + val = rsd->rgmii_1000; + } else { + /* Phylink will not allow inappropriate speeds for + * interface modes, so this should never happen. + */ + return -EINVAL; + } + } else if (interface == PHY_INTERFACE_MODE_RMII) { + if (speed == SPEED_10) { + val = rsd->rmii_10; + } else if (speed == SPEED_100) { + val = rsd->rmii_100; + } else { + /* Phylink will not allow inappropriate speeds for + * interface modes, so this should never happen. + */ + return -EINVAL; + } + } else { + /* This should never happen, as .get_interfaces() limits + * the interface modes that are supported to RGMII and/or + * RMII. + */ + return -EINVAL; + } + + regmap_write(bsp_priv->grf, reg, val); + + return 0; + +} + +static int rk_set_clk_mac_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) +{ + struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; + long rate; + + rate = rgmii_clock(speed); + if (rate < 0) + return rate; + + return clk_set_rate(clk_mac_speed, rate); +} + #define HIWORD_UPDATE(val, mask, shift) \ ((val) << (shift) | (mask) << ((shift) + 16)) @@ -177,42 +243,38 @@ static void px30_set_to_rmii(struct rk_priv_data *bsp_priv) PX30_GMAC_PHY_INTF_SEL_RMII); } -static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int px30_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; - struct device *dev = &bsp_priv->pdev->dev; - int ret; + struct device *dev = bsp_priv->dev; + unsigned int con1; + long rate; if (!clk_mac_speed) { dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__); - return; + return -EINVAL; } if (speed == 10) { - regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, - PX30_GMAC_SPEED_10M); - - ret = clk_set_rate(clk_mac_speed, 2500000); - if (ret) - dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n", - __func__, ret); + con1 = PX30_GMAC_SPEED_10M; + rate = 2500000; } else if (speed == 100) { - regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, - PX30_GMAC_SPEED_100M); - - ret = clk_set_rate(clk_mac_speed, 25000000); - if (ret) - dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n", - __func__, ret); - + con1 = PX30_GMAC_SPEED_100M; + rate = 25000000; } else { dev_err(dev, "unknown speed value for RMII! speed=%d", speed); + return -EINVAL; } + + regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1, con1); + + return clk_set_rate(clk_mac_speed, rate); } static const struct rk_gmac_ops px30_ops = { .set_to_rmii = px30_set_to_rmii, - .set_rmii_speed = px30_set_rmii_speed, + .set_speed = px30_set_speed, }; #define RK3128_GRF_MAC_CON0 0x0168 @@ -261,45 +323,25 @@ static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv) RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE); } -static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, - RK3128_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, - RK3128_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, - RK3128_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3128_reg_speed_data = { + .rgmii_10 = RK3128_GMAC_CLK_2_5M, + .rgmii_100 = RK3128_GMAC_CLK_25M, + .rgmii_1000 = RK3128_GMAC_CLK_125M, + .rmii_10 = RK3128_GMAC_RMII_CLK_2_5M | RK3128_GMAC_SPEED_10M, + .rmii_100 = RK3128_GMAC_RMII_CLK_25M | RK3128_GMAC_SPEED_100M, +}; -static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3128_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, - RK3128_GMAC_RMII_CLK_2_5M | - RK3128_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1, - RK3128_GMAC_RMII_CLK_25M | - RK3128_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } + return rk_set_reg_speed(bsp_priv, &rk3128_reg_speed_data, + RK3128_GRF_MAC_CON1, interface, speed); } static const struct rk_gmac_ops rk3128_ops = { .set_to_rgmii = rk3128_set_to_rgmii, .set_to_rmii = rk3128_set_to_rmii, - .set_rgmii_speed = rk3128_set_rgmii_speed, - .set_rmii_speed = rk3128_set_rmii_speed, + .set_speed = rk3128_set_speed, }; #define RK3228_GRF_MAC_CON0 0x0900 @@ -358,37 +400,19 @@ static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv) regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11)); } -static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, - RK3228_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, - RK3228_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, - RK3228_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3228_reg_speed_data = { + .rgmii_10 = RK3228_GMAC_CLK_2_5M, + .rgmii_100 = RK3228_GMAC_CLK_25M, + .rgmii_1000 = RK3228_GMAC_CLK_125M, + .rmii_10 = RK3228_GMAC_RMII_CLK_2_5M | RK3228_GMAC_SPEED_10M, + .rmii_100 = RK3228_GMAC_RMII_CLK_25M | RK3228_GMAC_SPEED_100M, +}; -static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3228_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, - RK3228_GMAC_RMII_CLK_2_5M | - RK3228_GMAC_SPEED_10M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, - RK3228_GMAC_RMII_CLK_25M | - RK3228_GMAC_SPEED_100M); - else - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); + return rk_set_reg_speed(bsp_priv, &rk3228_reg_speed_data, + RK3228_GRF_MAC_CON1, interface, speed); } static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) @@ -402,8 +426,7 @@ static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv) static const struct rk_gmac_ops rk3228_ops = { .set_to_rgmii = rk3228_set_to_rgmii, .set_to_rmii = rk3228_set_to_rmii, - .set_rgmii_speed = rk3228_set_rgmii_speed, - .set_rmii_speed = rk3228_set_rmii_speed, + .set_speed = rk3228_set_speed, .integrated_phy_powerup = rk3228_integrated_phy_powerup, .integrated_phy_powerdown = rk_gmac_integrated_ephy_powerdown, }; @@ -454,45 +477,25 @@ static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv) RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE); } -static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, - RK3288_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, - RK3288_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, - RK3288_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3288_reg_speed_data = { + .rgmii_10 = RK3288_GMAC_CLK_2_5M, + .rgmii_100 = RK3288_GMAC_CLK_25M, + .rgmii_1000 = RK3288_GMAC_CLK_125M, + .rmii_10 = RK3288_GMAC_RMII_CLK_2_5M | RK3288_GMAC_SPEED_10M, + .rmii_100 = RK3288_GMAC_RMII_CLK_25M | RK3288_GMAC_SPEED_100M, +}; -static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3288_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, - RK3288_GMAC_RMII_CLK_2_5M | - RK3288_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1, - RK3288_GMAC_RMII_CLK_25M | - RK3288_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } + return rk_set_reg_speed(bsp_priv, &rk3288_reg_speed_data, + RK3288_GRF_SOC_CON1, interface, speed); } static const struct rk_gmac_ops rk3288_ops = { .set_to_rgmii = rk3288_set_to_rgmii, .set_to_rmii = rk3288_set_to_rmii, - .set_rgmii_speed = rk3288_set_rgmii_speed, - .set_rmii_speed = rk3288_set_rmii_speed, + .set_speed = rk3288_set_speed, }; #define RK3308_GRF_MAC_CON0 0x04a0 @@ -511,24 +514,21 @@ static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv) RK3308_GMAC_PHY_INTF_SEL_RMII); } -static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; +static const struct rk_reg_speed_data rk3308_reg_speed_data = { + .rmii_10 = RK3308_GMAC_SPEED_10M, + .rmii_100 = RK3308_GMAC_SPEED_100M, +}; - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, - RK3308_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0, - RK3308_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } +static int rk3308_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) +{ + return rk_set_reg_speed(bsp_priv, &rk3308_reg_speed_data, + RK3308_GRF_MAC_CON0, interface, speed); } static const struct rk_gmac_ops rk3308_ops = { .set_to_rmii = rk3308_set_to_rmii, - .set_rmii_speed = rk3308_set_rmii_speed, + .set_speed = rk3308_set_speed, }; #define RK3328_GRF_MAC_CON0 0x0900 @@ -590,41 +590,26 @@ static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv) RK3328_GMAC_RMII_MODE); } -static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, - RK3328_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, - RK3328_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1, - RK3328_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3328_reg_speed_data = { + .rgmii_10 = RK3328_GMAC_CLK_2_5M, + .rgmii_100 = RK3328_GMAC_CLK_25M, + .rgmii_1000 = RK3328_GMAC_CLK_125M, + .rmii_10 = RK3328_GMAC_RMII_CLK_2_5M | RK3328_GMAC_SPEED_10M, + .rmii_100 = RK3328_GMAC_RMII_CLK_25M | RK3328_GMAC_SPEED_100M, +}; -static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3328_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; unsigned int reg; - reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 : - RK3328_GRF_MAC_CON1; - - if (speed == 10) - regmap_write(bsp_priv->grf, reg, - RK3328_GMAC_RMII_CLK_2_5M | - RK3328_GMAC_SPEED_10M); - else if (speed == 100) - regmap_write(bsp_priv->grf, reg, - RK3328_GMAC_RMII_CLK_25M | - RK3328_GMAC_SPEED_100M); + if (interface == PHY_INTERFACE_MODE_RMII && bsp_priv->integrated_phy) + reg = RK3328_GRF_MAC_CON2; else - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); + reg = RK3328_GRF_MAC_CON1; + + return rk_set_reg_speed(bsp_priv, &rk3328_reg_speed_data, reg, + interface, speed); } static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) @@ -638,8 +623,7 @@ static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv) static const struct rk_gmac_ops rk3328_ops = { .set_to_rgmii = rk3328_set_to_rgmii, .set_to_rmii = rk3328_set_to_rmii, - .set_rgmii_speed = rk3328_set_rgmii_speed, - .set_rmii_speed = rk3328_set_rmii_speed, + .set_speed = rk3328_set_speed, .integrated_phy_powerup = rk3328_integrated_phy_powerup, .integrated_phy_powerdown = rk_gmac_integrated_ephy_powerdown, }; @@ -690,45 +674,25 @@ static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv) RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE); } -static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, - RK3366_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, - RK3366_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, - RK3366_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3366_reg_speed_data = { + .rgmii_10 = RK3366_GMAC_CLK_2_5M, + .rgmii_100 = RK3366_GMAC_CLK_25M, + .rgmii_1000 = RK3366_GMAC_CLK_125M, + .rmii_10 = RK3366_GMAC_RMII_CLK_2_5M | RK3366_GMAC_SPEED_10M, + .rmii_100 = RK3366_GMAC_RMII_CLK_25M | RK3366_GMAC_SPEED_100M, +}; -static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3366_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, - RK3366_GMAC_RMII_CLK_2_5M | - RK3366_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6, - RK3366_GMAC_RMII_CLK_25M | - RK3366_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } + return rk_set_reg_speed(bsp_priv, &rk3366_reg_speed_data, + RK3366_GRF_SOC_CON6, interface, speed); } static const struct rk_gmac_ops rk3366_ops = { .set_to_rgmii = rk3366_set_to_rgmii, .set_to_rmii = rk3366_set_to_rmii, - .set_rgmii_speed = rk3366_set_rgmii_speed, - .set_rmii_speed = rk3366_set_rmii_speed, + .set_speed = rk3366_set_speed, }; #define RK3368_GRF_SOC_CON15 0x043c @@ -777,45 +741,25 @@ static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv) RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE); } -static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, - RK3368_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, - RK3368_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, - RK3368_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3368_reg_speed_data = { + .rgmii_10 = RK3368_GMAC_CLK_2_5M, + .rgmii_100 = RK3368_GMAC_CLK_25M, + .rgmii_1000 = RK3368_GMAC_CLK_125M, + .rmii_10 = RK3368_GMAC_RMII_CLK_2_5M | RK3368_GMAC_SPEED_10M, + .rmii_100 = RK3368_GMAC_RMII_CLK_25M | RK3368_GMAC_SPEED_100M, +}; -static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3368_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, - RK3368_GMAC_RMII_CLK_2_5M | - RK3368_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15, - RK3368_GMAC_RMII_CLK_25M | - RK3368_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } + return rk_set_reg_speed(bsp_priv, &rk3368_reg_speed_data, + RK3368_GRF_SOC_CON15, interface, speed); } static const struct rk_gmac_ops rk3368_ops = { .set_to_rgmii = rk3368_set_to_rgmii, .set_to_rmii = rk3368_set_to_rmii, - .set_rgmii_speed = rk3368_set_rgmii_speed, - .set_rmii_speed = rk3368_set_rmii_speed, + .set_speed = rk3368_set_speed, }; #define RK3399_GRF_SOC_CON5 0xc214 @@ -864,45 +808,25 @@ static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv) RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE); } -static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) - regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, - RK3399_GMAC_CLK_2_5M); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, - RK3399_GMAC_CLK_25M); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, - RK3399_GMAC_CLK_125M); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3399_reg_speed_data = { + .rgmii_10 = RK3399_GMAC_CLK_2_5M, + .rgmii_100 = RK3399_GMAC_CLK_25M, + .rgmii_1000 = RK3399_GMAC_CLK_125M, + .rmii_10 = RK3399_GMAC_RMII_CLK_2_5M | RK3399_GMAC_SPEED_10M, + .rmii_100 = RK3399_GMAC_RMII_CLK_25M | RK3399_GMAC_SPEED_100M, +}; -static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3399_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - - if (speed == 10) { - regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, - RK3399_GMAC_RMII_CLK_2_5M | - RK3399_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5, - RK3399_GMAC_RMII_CLK_25M | - RK3399_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } + return rk_set_reg_speed(bsp_priv, &rk3399_reg_speed_data, + RK3399_GRF_SOC_CON5, interface, speed); } static const struct rk_gmac_ops rk3399_ops = { .set_to_rgmii = rk3399_set_to_rgmii, .set_to_rmii = rk3399_set_to_rmii, - .set_rgmii_speed = rk3399_set_rgmii_speed, - .set_rmii_speed = rk3399_set_rmii_speed, + .set_speed = rk3399_set_speed, }; #define RK3528_VO_GRF_GMAC_CON 0x0018 @@ -965,43 +889,34 @@ static void rk3528_set_to_rmii(struct rk_priv_data *bsp_priv) RK3528_GMAC0_CLK_RMII_DIV2); } -static void rk3528_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; +static const struct rk_reg_speed_data rk3528_gmac0_reg_speed_data = { + .rmii_10 = RK3528_GMAC0_CLK_RMII_DIV20, + .rmii_100 = RK3528_GMAC0_CLK_RMII_DIV2, +}; - if (speed == 10) - regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, - RK3528_GMAC1_CLK_RGMII_DIV50); - else if (speed == 100) - regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, - RK3528_GMAC1_CLK_RGMII_DIV5); - else if (speed == 1000) - regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, - RK3528_GMAC1_CLK_RGMII_DIV1); - else - dev_err(dev, "unknown speed value for RGMII! speed=%d", speed); -} +static const struct rk_reg_speed_data rk3528_gmac1_reg_speed_data = { + .rgmii_10 = RK3528_GMAC1_CLK_RGMII_DIV50, + .rgmii_100 = RK3528_GMAC1_CLK_RGMII_DIV5, + .rgmii_1000 = RK3528_GMAC1_CLK_RGMII_DIV1, + .rmii_10 = RK3528_GMAC1_CLK_RMII_DIV20, + .rmii_100 = RK3528_GMAC1_CLK_RMII_DIV2, +}; -static void rk3528_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3528_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; - unsigned int reg, val; + const struct rk_reg_speed_data *rsd; + unsigned int reg; - if (speed == 10) - val = bsp_priv->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV20 : - RK3528_GMAC0_CLK_RMII_DIV20; - else if (speed == 100) - val = bsp_priv->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV2 : - RK3528_GMAC0_CLK_RMII_DIV2; - else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - return; + if (bsp_priv->id == 1) { + rsd = &rk3528_gmac1_reg_speed_data; + reg = RK3528_VPU_GRF_GMAC_CON5; + } else { + rsd = &rk3528_gmac0_reg_speed_data; + reg = RK3528_VO_GRF_GMAC_CON; } - reg = bsp_priv->id == 1 ? RK3528_VPU_GRF_GMAC_CON5 : - RK3528_VO_GRF_GMAC_CON; - - regmap_write(bsp_priv->grf, reg, val); + return rk_set_reg_speed(bsp_priv, rsd, reg, interface, speed); } static void rk3528_set_clock_selection(struct rk_priv_data *bsp_priv, @@ -1035,8 +950,7 @@ static void rk3528_integrated_phy_powerdown(struct rk_priv_data *bsp_priv) static const struct rk_gmac_ops rk3528_ops = { .set_to_rgmii = rk3528_set_to_rgmii, .set_to_rmii = rk3528_set_to_rmii, - .set_rgmii_speed = rk3528_set_rgmii_speed, - .set_rmii_speed = rk3528_set_rmii_speed, + .set_speed = rk3528_set_speed, .set_clock_selection = rk3528_set_clock_selection, .integrated_phy_powerup = rk3528_integrated_phy_powerup, .integrated_phy_powerdown = rk3528_integrated_phy_powerdown, @@ -1098,30 +1012,10 @@ static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv) regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII); } -static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; - struct device *dev = &bsp_priv->pdev->dev; - long rate; - int ret; - - rate = rgmii_clock(speed); - if (rate < 0) { - dev_err(dev, "unknown speed value for GMAC speed=%d", speed); - return; - } - - ret = clk_set_rate(clk_mac_speed, rate); - if (ret) - dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", - __func__, rate, ret); -} - static const struct rk_gmac_ops rk3568_ops = { .set_to_rgmii = rk3568_set_to_rgmii, .set_to_rmii = rk3568_set_to_rmii, - .set_rgmii_speed = rk3568_set_gmac_speed, - .set_rmii_speed = rk3568_set_gmac_speed, + .set_speed = rk_set_clk_mac_speed, .regs_valid = true, .regs = { 0xfe2a0000, /* gmac0 */ @@ -1205,42 +1099,24 @@ static void rk3576_set_to_rmii(struct rk_priv_data *bsp_priv) regmap_write(bsp_priv->grf, offset_con, RK3576_GMAC_RMII_MODE); } -static void rk3576_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; - unsigned int val = 0, offset_con; +static const struct rk_reg_speed_data rk3578_reg_speed_data = { + .rgmii_10 = RK3576_GMAC_CLK_RGMII_DIV50, + .rgmii_100 = RK3576_GMAC_CLK_RGMII_DIV5, + .rgmii_1000 = RK3576_GMAC_CLK_RGMII_DIV1, + .rmii_10 = RK3576_GMAC_CLK_RMII_DIV20, + .rmii_100 = RK3576_GMAC_CLK_RMII_DIV2, +}; - switch (speed) { - case 10: - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) - val = RK3576_GMAC_CLK_RMII_DIV20; - else - val = RK3576_GMAC_CLK_RGMII_DIV50; - break; - case 100: - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) - val = RK3576_GMAC_CLK_RMII_DIV2; - else - val = RK3576_GMAC_CLK_RGMII_DIV5; - break; - case 1000: - if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII) - val = RK3576_GMAC_CLK_RGMII_DIV1; - else - goto err; - break; - default: - goto err; - } +static int rk3576_set_gmac_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) +{ + unsigned int offset_con; offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 : RK3576_GRF_GMAC_CON0; - regmap_write(bsp_priv->grf, offset_con, val); - - return; -err: - dev_err(dev, "unknown speed value for GMAC speed=%d", speed); + return rk_set_reg_speed(bsp_priv, &rk3578_reg_speed_data, offset_con, + interface, speed); } static void rk3576_set_clock_selection(struct rk_priv_data *bsp_priv, bool input, @@ -1262,8 +1138,7 @@ static void rk3576_set_clock_selection(struct rk_priv_data *bsp_priv, bool input static const struct rk_gmac_ops rk3576_ops = { .set_to_rgmii = rk3576_set_to_rgmii, .set_to_rmii = rk3576_set_to_rmii, - .set_rgmii_speed = rk3576_set_gmac_speed, - .set_rmii_speed = rk3576_set_gmac_speed, + .set_speed = rk3576_set_gmac_speed, .set_clock_selection = rk3576_set_clock_selection, .php_grf_required = true, .regs_valid = true, @@ -1347,26 +1222,26 @@ static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv) RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id)); } -static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) +static int rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) { - struct device *dev = &bsp_priv->pdev->dev; unsigned int val = 0, id = bsp_priv->id; switch (speed) { case 10: - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) + if (interface == PHY_INTERFACE_MODE_RMII) val = RK3588_GMA_CLK_RMII_DIV20(id); else val = RK3588_GMAC_CLK_RGMII_DIV50(id); break; case 100: - if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) + if (interface == PHY_INTERFACE_MODE_RMII) val = RK3588_GMA_CLK_RMII_DIV2(id); else val = RK3588_GMAC_CLK_RGMII_DIV5(id); break; case 1000: - if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII) + if (interface != PHY_INTERFACE_MODE_RMII) val = RK3588_GMAC_CLK_RGMII_DIV1(id); else goto err; @@ -1377,9 +1252,9 @@ static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed) regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val); - return; + return 0; err: - dev_err(dev, "unknown speed value for GMAC speed=%d", speed); + return -EINVAL; } static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input, @@ -1397,8 +1272,7 @@ static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input static const struct rk_gmac_ops rk3588_ops = { .set_to_rgmii = rk3588_set_to_rgmii, .set_to_rmii = rk3588_set_to_rmii, - .set_rgmii_speed = rk3588_set_gmac_speed, - .set_rmii_speed = rk3588_set_gmac_speed, + .set_speed = rk3588_set_gmac_speed, .set_clock_selection = rk3588_set_clock_selection, .php_grf_required = true, .regs_valid = true, @@ -1427,26 +1301,21 @@ static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv) RV1108_GMAC_PHY_INTF_SEL_RMII); } -static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct device *dev = &bsp_priv->pdev->dev; +static const struct rk_reg_speed_data rv1108_reg_speed_data = { + .rmii_10 = RV1108_GMAC_RMII_CLK_2_5M | RV1108_GMAC_SPEED_10M, + .rmii_100 = RV1108_GMAC_RMII_CLK_25M | RV1108_GMAC_SPEED_100M, +}; - if (speed == 10) { - regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, - RV1108_GMAC_RMII_CLK_2_5M | - RV1108_GMAC_SPEED_10M); - } else if (speed == 100) { - regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0, - RV1108_GMAC_RMII_CLK_25M | - RV1108_GMAC_SPEED_100M); - } else { - dev_err(dev, "unknown speed value for RMII! speed=%d", speed); - } +static int rv1108_set_speed(struct rk_priv_data *bsp_priv, + phy_interface_t interface, int speed) +{ + return rk_set_reg_speed(bsp_priv, &rv1108_reg_speed_data, + RV1108_GRF_GMAC_CON0, interface, speed); } static const struct rk_gmac_ops rv1108_ops = { .set_to_rmii = rv1108_set_to_rmii, - .set_rmii_speed = rv1108_set_rmii_speed, + .set_speed = rv1108_set_speed, }; #define RV1126_GRF_GMAC_CON0 0X0070 @@ -1501,62 +1370,17 @@ static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv) RV1126_GMAC_PHY_INTF_SEL_RMII); } -static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; - struct device *dev = &bsp_priv->pdev->dev; - long rate; - int ret; - - rate = rgmii_clock(speed); - if (rate < 0) { - dev_err(dev, "unknown speed value for RGMII speed=%d", speed); - return; - } - - ret = clk_set_rate(clk_mac_speed, rate); - if (ret) - dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", - __func__, rate, ret); -} - -static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) -{ - struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk; - struct device *dev = &bsp_priv->pdev->dev; - unsigned long rate; - int ret; - - switch (speed) { - case 10: - rate = 2500000; - break; - case 100: - rate = 25000000; - break; - default: - dev_err(dev, "unknown speed value for RGMII speed=%d", speed); - return; - } - - ret = clk_set_rate(clk_mac_speed, rate); - if (ret) - dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n", - __func__, rate, ret); -} - static const struct rk_gmac_ops rv1126_ops = { .set_to_rgmii = rv1126_set_to_rgmii, .set_to_rmii = rv1126_set_to_rmii, - .set_rgmii_speed = rv1126_set_rgmii_speed, - .set_rmii_speed = rv1126_set_rmii_speed, + .set_speed = rk_set_clk_mac_speed, }; static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) { struct rk_priv_data *bsp_priv = plat->bsp_priv; - struct device *dev = &bsp_priv->pdev->dev; int phy_iface = bsp_priv->phy_iface; + struct device *dev = bsp_priv->dev; int i, j, ret; bsp_priv->clk_enabled = false; @@ -1583,16 +1407,10 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat) if (ret) return dev_err_probe(dev, ret, "Failed to get clocks\n"); - /* "stmmaceth" will be enabled by the core */ - bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth"); - ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac); - if (ret) - return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n"); - if (bsp_priv->clock_input) { dev_info(dev, "clock input from PHY\n"); } else if (phy_iface == PHY_INTERFACE_MODE_RMII) { - clk_set_rate(bsp_priv->clk_mac, 50000000); + clk_set_rate(plat->stmmac_clk, 50000000); } if (plat->phy_node && bsp_priv->integrated_phy) { @@ -1648,8 +1466,8 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable) static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable) { struct regulator *ldo = bsp_priv->regulator; + struct device *dev = bsp_priv->dev; int ret; - struct device *dev = &bsp_priv->pdev->dev; if (enable) { ret = regulator_enable(ldo); @@ -1773,7 +1591,7 @@ static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev, dev_info(dev, "integrated PHY? (%s).\n", bsp_priv->integrated_phy ? "yes" : "no"); - bsp_priv->pdev = pdev; + bsp_priv->dev = dev; return bsp_priv; } @@ -1793,7 +1611,7 @@ static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) return -EINVAL; break; default: - dev_err(&bsp_priv->pdev->dev, + dev_err(bsp_priv->dev, "unsupported interface %d", bsp_priv->phy_iface); } return 0; @@ -1801,8 +1619,8 @@ static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv) static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) { + struct device *dev = bsp_priv->dev; int ret; - struct device *dev = &bsp_priv->pdev->dev; ret = rk_gmac_check_ops(bsp_priv); if (ret) @@ -1858,35 +1676,34 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) if (gmac->integrated_phy && gmac->ops->integrated_phy_powerdown) gmac->ops->integrated_phy_powerdown(gmac); - pm_runtime_put_sync(&gmac->pdev->dev); + pm_runtime_put_sync(gmac->dev); phy_power_on(gmac, false); gmac_clk_enable(gmac, false); } +static void rk_get_interfaces(struct stmmac_priv *priv, void *bsp_priv, + unsigned long *interfaces) +{ + struct rk_priv_data *rk = bsp_priv; + + if (rk->ops->set_to_rgmii) + phy_interface_set_rgmii(interfaces); + + if (rk->ops->set_to_rmii) + __set_bit(PHY_INTERFACE_MODE_RMII, interfaces); +} + static int rk_set_clk_tx_rate(void *bsp_priv_, struct clk *clk_tx_i, phy_interface_t interface, int speed) { struct rk_priv_data *bsp_priv = bsp_priv_; - struct device *dev = &bsp_priv->pdev->dev; - switch (bsp_priv->phy_iface) { - case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: - case PHY_INTERFACE_MODE_RGMII_TXID: - if (bsp_priv->ops->set_rgmii_speed) - bsp_priv->ops->set_rgmii_speed(bsp_priv, speed); - break; - case PHY_INTERFACE_MODE_RMII: - if (bsp_priv->ops->set_rmii_speed) - bsp_priv->ops->set_rmii_speed(bsp_priv, speed); - break; - default: - dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface); - } + if (bsp_priv->ops->set_speed) + return bsp_priv->ops->set_speed(bsp_priv, bsp_priv->phy_iface, + speed); - return 0; + return -EINVAL; } static int rk_gmac_probe(struct platform_device *pdev) @@ -1919,6 +1736,7 @@ static int rk_gmac_probe(struct platform_device *pdev) plat_dat->tx_fifo_size = 2048; } + plat_dat->get_interfaces = rk_get_interfaces; plat_dat->set_clk_tx_rate = rk_set_clk_tx_rate; plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c index 72b50f6d72f4..01dd0cf0923c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -515,6 +515,7 @@ static const struct socfpga_dwmac_ops socfpga_gen10_ops = { static const struct of_device_id socfpga_dwmac_match[] = { { .compatible = "altr,socfpga-stmmac", .data = &socfpga_gen5_ops }, { .compatible = "altr,socfpga-stmmac-a10-s10", .data = &socfpga_gen10_ops }, + { .compatible = "altr,socfpga-stmmac-agilex5", .data = &socfpga_gen10_ops }, { } }; MODULE_DEVICE_TABLE(of, socfpga_dwmac_match); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c index 3303784cbbf8..3b7947a7a7ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sophgo.c @@ -54,6 +54,7 @@ static int sophgo_dwmac_probe(struct platform_device *pdev) } static const struct of_device_id sophgo_dwmac_match[] = { + { .compatible = "sophgo,sg2042-dwmac" }, { .compatible = "sophgo,sg2044-dwmac" }, { /* sentinel */ } }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c index 5e6ac82a89b9..bd65d4239054 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-visconti.c @@ -48,7 +48,6 @@ struct visconti_eth { void __iomem *reg; - u32 phy_intf_sel; struct clk *phy_ref_clk; struct device *dev; }; @@ -57,42 +56,35 @@ static int visconti_eth_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, phy_interface_t interface, int speed) { struct visconti_eth *dwmac = bsp_priv; - struct net_device *netdev = dev_get_drvdata(dwmac->dev); - unsigned int val, clk_sel_val = 0; - - switch (speed) { - case SPEED_1000: - if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII) - clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_125M; - break; - case SPEED_100: - if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII) - clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_25M; - if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RMII) - clk_sel_val = ETHER_CLK_SEL_DIV_SEL_2; - break; - case SPEED_10: - if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RGMII) - clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_2P5M; - if (dwmac->phy_intf_sel == ETHER_CONFIG_INTF_RMII) - clk_sel_val = ETHER_CLK_SEL_DIV_SEL_20; - break; - default: - /* No bit control */ - netdev_err(netdev, "Unsupported speed request (%d)", speed); - return -EINVAL; - } - - /* Stop internal clock */ - val = readl(dwmac->reg + REG_ETHER_CLOCK_SEL); - val &= ~(ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN); - val |= ETHER_CLK_SEL_TX_O_E_N_IN; - writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); + unsigned long clk_sel, val; + + if (phy_interface_mode_is_rgmii(interface)) { + switch (speed) { + case SPEED_1000: + clk_sel = ETHER_CLK_SEL_FREQ_SEL_125M; + break; + + case SPEED_100: + clk_sel = ETHER_CLK_SEL_FREQ_SEL_25M; + break; + + case SPEED_10: + clk_sel = ETHER_CLK_SEL_FREQ_SEL_2P5M; + break; + + default: + return -EINVAL; + } + + /* Stop internal clock */ + val = readl(dwmac->reg + REG_ETHER_CLOCK_SEL); + val &= ~(ETHER_CLK_SEL_RMII_CLK_EN | + ETHER_CLK_SEL_RX_TX_CLK_EN); + val |= ETHER_CLK_SEL_TX_O_E_N_IN; + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); - /* Set Clock-Mux, Start clock, Set TX_O direction */ - switch (dwmac->phy_intf_sel) { - case ETHER_CONFIG_INTF_RGMII: - val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC; + /* Set Clock-Mux, Start clock, Set TX_O direction */ + val = clk_sel | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); val |= ETHER_CLK_SEL_RX_TX_CLK_EN; @@ -100,11 +92,32 @@ static int visconti_eth_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, val &= ~ETHER_CLK_SEL_TX_O_E_N_IN; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); - break; - case ETHER_CONFIG_INTF_RMII: - val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV | - ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | ETHER_CLK_SEL_TX_O_E_N_IN | - ETHER_CLK_SEL_RMII_CLK_SEL_RX_C; + } else if (interface == PHY_INTERFACE_MODE_RMII) { + switch (speed) { + case SPEED_100: + clk_sel = ETHER_CLK_SEL_DIV_SEL_2; + break; + + case SPEED_10: + clk_sel = ETHER_CLK_SEL_DIV_SEL_20; + break; + + default: + return -EINVAL; + } + + /* Stop internal clock */ + val = readl(dwmac->reg + REG_ETHER_CLOCK_SEL); + val &= ~(ETHER_CLK_SEL_RMII_CLK_EN | + ETHER_CLK_SEL_RX_TX_CLK_EN); + val |= ETHER_CLK_SEL_TX_O_E_N_IN; + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); + + /* Set Clock-Mux, Start clock, Set TX_O direction */ + val = clk_sel | ETHER_CLK_SEL_RX_CLK_EXT_SEL_DIV | + ETHER_CLK_SEL_TX_CLK_EXT_SEL_DIV | + ETHER_CLK_SEL_TX_O_E_N_IN | + ETHER_CLK_SEL_RMII_CLK_SEL_RX_C; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); val |= ETHER_CLK_SEL_RMII_CLK_RST; @@ -112,16 +125,22 @@ static int visconti_eth_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, val |= ETHER_CLK_SEL_RMII_CLK_EN | ETHER_CLK_SEL_RX_TX_CLK_EN; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); - break; - case ETHER_CONFIG_INTF_MII: - default: - val = clk_sel_val | ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC | - ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | ETHER_CLK_SEL_TX_O_E_N_IN; + } else { + /* Stop internal clock */ + val = readl(dwmac->reg + REG_ETHER_CLOCK_SEL); + val &= ~(ETHER_CLK_SEL_RMII_CLK_EN | + ETHER_CLK_SEL_RX_TX_CLK_EN); + val |= ETHER_CLK_SEL_TX_O_E_N_IN; + writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); + + /* Set Clock-Mux, Start clock, Set TX_O direction */ + val = ETHER_CLK_SEL_RX_CLK_EXT_SEL_RXC | + ETHER_CLK_SEL_TX_CLK_EXT_SEL_TXC | + ETHER_CLK_SEL_TX_O_E_N_IN; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); val |= ETHER_CLK_SEL_RX_TX_CLK_EN; writel(val, dwmac->reg + REG_ETHER_CLOCK_SEL); - break; } return 0; @@ -130,28 +149,28 @@ static int visconti_eth_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, static int visconti_eth_init_hw(struct platform_device *pdev, struct plat_stmmacenet_data *plat_dat) { struct visconti_eth *dwmac = plat_dat->bsp_priv; - unsigned int reg_val, clk_sel_val; + unsigned int clk_sel_val; + u32 phy_intf_sel; switch (plat_dat->phy_interface) { case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: - dwmac->phy_intf_sel = ETHER_CONFIG_INTF_RGMII; + phy_intf_sel = ETHER_CONFIG_INTF_RGMII; break; case PHY_INTERFACE_MODE_MII: - dwmac->phy_intf_sel = ETHER_CONFIG_INTF_MII; + phy_intf_sel = ETHER_CONFIG_INTF_MII; break; case PHY_INTERFACE_MODE_RMII: - dwmac->phy_intf_sel = ETHER_CONFIG_INTF_RMII; + phy_intf_sel = ETHER_CONFIG_INTF_RMII; break; default: dev_err(&pdev->dev, "Unsupported phy-mode (%d)\n", plat_dat->phy_interface); return -EOPNOTSUPP; } - reg_val = dwmac->phy_intf_sel; - writel(reg_val, dwmac->reg + REG_ETHER_CONTROL); + writel(phy_intf_sel, dwmac->reg + REG_ETHER_CONTROL); /* Enable TX/RX clock */ clk_sel_val = ETHER_CLK_SEL_FREQ_SEL_125M; @@ -161,8 +180,8 @@ static int visconti_eth_init_hw(struct platform_device *pdev, struct plat_stmmac dwmac->reg + REG_ETHER_CLOCK_SEL); /* release internal-reset */ - reg_val |= ETHER_ETH_CONTROL_RESET; - writel(reg_val, dwmac->reg + REG_ETHER_CONTROL); + phy_intf_sel |= ETHER_ETH_CONTROL_RESET; + writel(phy_intf_sel, dwmac->reg + REG_ETHER_CONTROL); return 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 56b76aaa58f0..fe776ddf6889 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -393,15 +393,10 @@ static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw) writel(value, ioaddr + LPI_TIMER_CTRL); } -static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral, - bool loopback) +static void dwmac1000_ctrl_ane(struct stmmac_priv *priv, bool ane, + bool srgmi_ral, bool loopback) { - dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); -} - -static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv) -{ - dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv); + dwmac_ctrl_ane(priv->ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); } static void dwmac1000_debug(struct stmmac_priv *priv, void __iomem *ioaddr, @@ -508,7 +503,6 @@ const struct stmmac_ops dwmac1000_ops = { .set_eee_pls = dwmac1000_set_eee_pls, .debug = dwmac1000_debug, .pcs_ctrl_ane = dwmac1000_ctrl_ane, - .pcs_get_adv_lp = dwmac1000_get_adv_lp, .set_mac_loopback = dwmac1000_set_mac_loopback, }; diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 9c2549d4100f..d85bc0bb5c3c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -583,15 +583,10 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, } } -static void dwmac4_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral, +static void dwmac4_ctrl_ane(struct stmmac_priv *priv, bool ane, bool srgmi_ral, bool loopback) { - dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); -} - -static void dwmac4_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv) -{ - dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv); + dwmac_ctrl_ane(priv->ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback); } /* RGMII or SMII interface */ @@ -958,7 +953,6 @@ const struct stmmac_ops dwmac4_ops = { .set_eee_timer = dwmac4_set_eee_timer, .set_eee_pls = dwmac4_set_eee_pls, .pcs_ctrl_ane = dwmac4_ctrl_ane, - .pcs_get_adv_lp = dwmac4_get_adv_lp, .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, .set_mac_loopback = dwmac4_set_mac_loopback, @@ -993,7 +987,6 @@ const struct stmmac_ops dwmac410_ops = { .set_eee_timer = dwmac4_set_eee_timer, .set_eee_pls = dwmac4_set_eee_pls, .pcs_ctrl_ane = dwmac4_ctrl_ane, - .pcs_get_adv_lp = dwmac4_get_adv_lp, .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, .flex_pps_config = dwmac5_flex_pps_config, @@ -1030,7 +1023,6 @@ const struct stmmac_ops dwmac510_ops = { .set_eee_timer = dwmac4_set_eee_timer, .set_eee_pls = dwmac4_set_eee_pls, .pcs_ctrl_ane = dwmac4_ctrl_ane, - .pcs_get_adv_lp = dwmac4_get_adv_lp, .debug = dwmac4_debug, .set_filter = dwmac4_set_filter, .safety_feat_config = dwmac5_safety_feat_config, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c index 7840bc403788..5dcc95bc0ad2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c @@ -364,19 +364,17 @@ static int dwxgmac2_dma_interrupt(struct stmmac_priv *priv, } /* TX/RX NORMAL interrupts */ - if (likely(intr_status & XGMAC_NIS)) { - if (likely(intr_status & XGMAC_RI)) { - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->rx_normal_irq_n[chan]); - u64_stats_update_end(&stats->syncp); - ret |= handle_rx; - } - if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { - u64_stats_update_begin(&stats->syncp); - u64_stats_inc(&stats->tx_normal_irq_n[chan]); - u64_stats_update_end(&stats->syncp); - ret |= handle_tx; - } + if (likely(intr_status & XGMAC_RI)) { + u64_stats_update_begin(&stats->syncp); + u64_stats_inc(&stats->rx_normal_irq_n[chan]); + u64_stats_update_end(&stats->syncp); + ret |= handle_rx; + } + if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) { + u64_stats_update_begin(&stats->syncp); + u64_stats_inc(&stats->tx_normal_irq_n[chan]); + u64_stats_update_end(&stats->syncp); + ret |= handle_tx; } /* Clear interrupts */ diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index ae4efffb785f..14dbe0685997 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -300,7 +300,6 @@ struct stmmac_dma_ops { struct mac_device_info; struct net_device; -struct rgmii_adv; struct stmmac_tc_entry; struct stmmac_pps_cfg; struct stmmac_rss; @@ -375,9 +374,8 @@ struct stmmac_ops { struct stmmac_extra_stats *x, u32 rx_queues, u32 tx_queues); /* PCS calls */ - void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral, + void (*pcs_ctrl_ane)(struct stmmac_priv *priv, bool ane, bool srgmi_ral, bool loopback); - void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv); /* Safety Features */ int (*safety_feat_config)(void __iomem *ioaddr, unsigned int asp, struct stmmac_safety_feature_cfg *safety_cfg); @@ -466,9 +464,7 @@ struct stmmac_ops { #define stmmac_mac_debug(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, debug, __priv, __args) #define stmmac_pcs_ctrl_ane(__priv, __args...) \ - stmmac_do_void_callback(__priv, mac, pcs_ctrl_ane, __args) -#define stmmac_pcs_get_adv_lp(__priv, __args...) \ - stmmac_do_void_callback(__priv, mac, pcs_get_adv_lp, __args) + stmmac_do_void_callback(__priv, mac, pcs_ctrl_ane, __priv, __args) #define stmmac_safety_feat_config(__priv, __args...) \ stmmac_do_callback(__priv, mac, safety_feat_config, __args) #define stmmac_safety_feat_irq_status(__priv, __args...) \ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index f702f7b7bf9f..77758a7299b4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -325,7 +325,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, if (!(priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) && (priv->hw->pcs & STMMAC_PCS_RGMII || priv->hw->pcs & STMMAC_PCS_SGMII)) { - struct rgmii_adv adv; u32 supported, advertising, lp_advertising; if (!priv->xstats.pcs_link) { @@ -337,10 +336,6 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, cmd->base.speed = priv->xstats.pcs_speed; - /* Get and convert ADV/LP_ADV from the HW AN registers */ - if (stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv)) - return -EOPNOTSUPP; /* should never happen indeed */ - /* Encoding of PSE bits is defined in 802.3z, 37.2.1.4 */ ethtool_convert_link_mode_to_legacy_u32( @@ -350,44 +345,12 @@ static int stmmac_ethtool_get_link_ksettings(struct net_device *dev, ethtool_convert_link_mode_to_legacy_u32( &lp_advertising, cmd->link_modes.lp_advertising); - if (adv.pause & STMMAC_PCS_PAUSE) - advertising |= ADVERTISED_Pause; - if (adv.pause & STMMAC_PCS_ASYM_PAUSE) - advertising |= ADVERTISED_Asym_Pause; - if (adv.lp_pause & STMMAC_PCS_PAUSE) - lp_advertising |= ADVERTISED_Pause; - if (adv.lp_pause & STMMAC_PCS_ASYM_PAUSE) - lp_advertising |= ADVERTISED_Asym_Pause; - /* Reg49[3] always set because ANE is always supported */ cmd->base.autoneg = ADVERTISED_Autoneg; supported |= SUPPORTED_Autoneg; advertising |= ADVERTISED_Autoneg; lp_advertising |= ADVERTISED_Autoneg; - if (adv.duplex) { - supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_100baseT_Full | - SUPPORTED_10baseT_Full); - advertising |= (ADVERTISED_1000baseT_Full | - ADVERTISED_100baseT_Full | - ADVERTISED_10baseT_Full); - } else { - supported |= (SUPPORTED_1000baseT_Half | - SUPPORTED_100baseT_Half | - SUPPORTED_10baseT_Half); - advertising |= (ADVERTISED_1000baseT_Half | - ADVERTISED_100baseT_Half | - ADVERTISED_10baseT_Half); - } - if (adv.lp_duplex) - lp_advertising |= (ADVERTISED_1000baseT_Full | - ADVERTISED_100baseT_Full | - ADVERTISED_10baseT_Full); - else - lp_advertising |= (ADVERTISED_1000baseT_Half | - ADVERTISED_100baseT_Half | - ADVERTISED_10baseT_Half); cmd->base.port = PORT_OTHER; ethtool_convert_legacy_u32_to_link_mode( @@ -417,7 +380,7 @@ stmmac_ethtool_set_link_ksettings(struct net_device *dev, return -EINVAL; mutex_lock(&priv->lock); - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); + stmmac_pcs_ctrl_ane(priv, 1, priv->hw->ps, 0); mutex_unlock(&priv->lock); return 0; @@ -515,12 +478,9 @@ stmmac_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct stmmac_priv *priv = netdev_priv(netdev); - struct rgmii_adv adv_lp; - if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) { + if (priv->hw->pcs) { pause->autoneg = 1; - if (!adv_lp.pause) - return; } else { phylink_ethtool_get_pauseparam(priv->phylink, pause); } @@ -531,12 +491,9 @@ stmmac_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct stmmac_priv *priv = netdev_priv(netdev); - struct rgmii_adv adv_lp; - if (priv->hw->pcs && !stmmac_pcs_get_adv_lp(priv, priv->ioaddr, &adv_lp)) { + if (priv->hw->pcs) { pause->autoneg = 1; - if (!adv_lp.pause) - return -EOPNOTSUPP; return 0; } else { return phylink_ethtool_set_pauseparam(priv->phylink, pause); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index b948df1bff9a..f1abf4242cd2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1062,8 +1062,8 @@ static void stmmac_mac_link_up(struct phylink_config *config, interface, speed); if (ret < 0) netdev_err(priv->dev, - "failed to configure transmit clock for %dMbps: %pe\n", - speed, ERR_PTR(ret)); + "failed to configure %s transmit clock for %dMbps: %pe\n", + phy_modes(interface), speed, ERR_PTR(ret)); } stmmac_mac_set(priv, priv->ioaddr, true); @@ -2596,7 +2596,7 @@ static bool stmmac_xdp_xmit_zc(struct stmmac_priv *priv, u32 queue, u32 budget) budget = min(budget, stmmac_tx_avail(priv, queue)); - while (budget-- > 0) { + for (; budget > 0; budget--) { struct stmmac_metadata_request meta_req; struct xsk_tx_metadata *meta = NULL; dma_addr_t dma_addr; @@ -3586,7 +3586,7 @@ static int stmmac_hw_setup(struct net_device *dev, bool ptp_register) } if (priv->hw->pcs) - stmmac_pcs_ctrl_ane(priv, priv->ioaddr, 1, priv->hw->ps, 0); + stmmac_pcs_ctrl_ane(priv, 1, priv->hw->ps, 0); /* set TX and RX rings length */ stmmac_set_rings_length(priv); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h index 1bdf87b237c4..4a684c97dfae 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -16,6 +16,8 @@ /* PCS registers (AN/TBI/SGMII/RGMII) offsets */ #define GMAC_AN_CTRL(x) (x) /* AN control */ #define GMAC_AN_STATUS(x) (x + 0x4) /* AN status */ + +/* ADV, LPA and EXP are only available for the TBI and RTBI interfaces */ #define GMAC_ANE_ADV(x) (x + 0x8) /* ANE Advertisement */ #define GMAC_ANE_LPA(x) (x + 0xc) /* ANE link partener ability */ #define GMAC_ANE_EXP(x) (x + 0x10) /* ANE expansion */ @@ -107,34 +109,4 @@ static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane, writel(value, ioaddr + GMAC_AN_CTRL(reg)); } - -/** - * dwmac_get_adv_lp - Get ADV and LP cap - * @ioaddr: IO registers pointer - * @reg: Base address of the AN Control Register. - * @adv_lp: structure to store the adv,lp status - * Description: this is to expose the ANE advertisement and Link partner ability - * status to ethtool support. - */ -static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg, - struct rgmii_adv *adv_lp) -{ - u32 value = readl(ioaddr + GMAC_ANE_ADV(reg)); - - if (value & GMAC_ANE_FD) - adv_lp->duplex = DUPLEX_FULL; - if (value & GMAC_ANE_HD) - adv_lp->duplex |= DUPLEX_HALF; - - adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; - - value = readl(ioaddr + GMAC_ANE_LPA(reg)); - - if (value & GMAC_ANE_FD) - adv_lp->lp_duplex = DUPLEX_FULL; - if (value & GMAC_ANE_HD) - adv_lp->lp_duplex = DUPLEX_HALF; - - adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; -} #endif /* __STMMAC_PCS_H__ */ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index b80c1efdb323..030fcf1b5993 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -60,7 +60,7 @@ static int dwmac1000_validate_mcast_bins(struct device *dev, int mcast_bins) * Description: * This function validates the number of Unicast address entries supported * by a particular Synopsys 10/100/1000 controller. The Synopsys controller - * supports 1..32, 64, or 128 Unicast filter entries for it's Unicast filter + * supports 1..32, 64, or 128 Unicast filter entries for its Unicast filter * logic. This function validates a valid, supported configuration is * selected, and defaults to 1 Unicast address if an unsupported * configuration is selected. @@ -410,6 +410,7 @@ static const char * const stmmac_gmac4_compats[] = { "snps,dwmac-4.00", "snps,dwmac-4.10a", "snps,dwmac-4.20a", + "snps,dwmac-5.00a", "snps,dwmac-5.10a", "snps,dwmac-5.20", "snps,dwmac-5.30a", @@ -579,6 +580,8 @@ stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac) plat->pmt = 1; if (of_property_read_bool(np, "snps,tso")) plat->flags |= STMMAC_FLAG_TSO_EN; + of_property_read_u32(np, "snps,multicast-filter-bins", + &plat->multicast_filter_bins); } dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg), |