Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-stmmac-multi-interface-stmmac'

Russell King says:

====================
net: stmmac: multi-interface stmmac

This series adds a callback for platform glue to configure the stmmac
core interface mode depending on the PHY interface mode that is being
used. This is currently only called just before the dwmac core is reset
since these signals are latched on reset.

Included in this series are changes to s32 to move its PHY_INTF_SEL_x
definitions out of the way of the dwmac core's signals which has more
entitlement to use this name. We convert dwmac-imx as an example.

Including other platform glue would make this series excessively large,
but once this core code is merged, the individual platform glue updates
can be posted one after another as they will be independent of each
other.

It is hoped that this callback can be used in future to reconfigure the
dwmac core when the interface mode changes to support PHYs that change
their interface mode, but we're nowhere near being able to do that yet.
====================

Link: https://patch.msgid.link/aQiWzyrXU_2hGJ4j@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+113 -93
+10
drivers/net/ethernet/stmicro/stmmac/common.h
··· 313 313 #define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY iface */ 314 314 #define DEFAULT_DMA_PBL 8 315 315 316 + /* phy_intf_sel_i and ACTPHYIF encodings */ 317 + #define PHY_INTF_SEL_GMII_MII 0 318 + #define PHY_INTF_SEL_RGMII 1 319 + #define PHY_INTF_SEL_SGMII 2 320 + #define PHY_INTF_SEL_TBI 3 321 + #define PHY_INTF_SEL_RMII 4 322 + #define PHY_INTF_SEL_RTBI 5 323 + #define PHY_INTF_SEL_SMII 6 324 + #define PHY_INTF_SEL_REVMII 7 325 + 316 326 /* MSI defines */ 317 327 #define STMMAC_MSI_VEC_MAX 32 318 328
+42 -88
drivers/net/ethernet/stmicro/stmmac/dwmac-imx.c
··· 23 23 #include "stmmac_platform.h" 24 24 25 25 #define GPR_ENET_QOS_INTF_MODE_MASK GENMASK(21, 16) 26 - #define GPR_ENET_QOS_INTF_SEL_MII (0x0 << 16) 27 - #define GPR_ENET_QOS_INTF_SEL_RMII (0x4 << 16) 28 - #define GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 16) 26 + #define GPR_ENET_QOS_INTF_SEL_MASK GENMASK(20, 16) 29 27 #define GPR_ENET_QOS_CLK_GEN_EN (0x1 << 19) 30 28 #define GPR_ENET_QOS_CLK_TX_CLK_SEL (0x1 << 20) 31 29 #define GPR_ENET_QOS_RGMII_EN (0x1 << 21) 32 30 33 31 #define MX93_GPR_ENET_QOS_INTF_MODE_MASK GENMASK(3, 0) 34 - #define MX93_GPR_ENET_QOS_INTF_MASK GENMASK(3, 1) 35 - #define MX93_GPR_ENET_QOS_INTF_SEL_MII (0x0 << 1) 36 - #define MX93_GPR_ENET_QOS_INTF_SEL_RMII (0x4 << 1) 37 - #define MX93_GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 1) 32 + #define MX93_GPR_ENET_QOS_INTF_SEL_MASK GENMASK(3, 1) 38 33 #define MX93_GPR_ENET_QOS_CLK_GEN_EN (0x1 << 0) 39 34 #define MX93_GPR_ENET_QOS_CLK_SEL_MASK BIT_MASK(0) 40 35 #define MX93_GPR_CLK_SEL_OFFSET (4) ··· 39 44 #define RMII_RESET_SPEED (0x3 << 14) 40 45 #define CTRL_SPEED_MASK GENMASK(15, 14) 41 46 47 + struct imx_priv_data; 48 + 42 49 struct imx_dwmac_ops { 43 50 u32 addr_width; 44 51 u32 flags; 45 52 bool mac_rgmii_txclk_auto_adj; 46 53 47 54 int (*fix_soc_reset)(struct stmmac_priv *priv, void __iomem *ioaddr); 48 - int (*set_intf_mode)(struct plat_stmmacenet_data *plat_dat); 55 + int (*set_intf_mode)(struct imx_priv_data *dwmac, u8 phy_intf_sel); 49 56 void (*fix_mac_speed)(void *priv, int speed, unsigned int mode); 50 57 }; 51 58 ··· 64 67 struct plat_stmmacenet_data *plat_dat; 65 68 }; 66 69 67 - static int imx8mp_set_intf_mode(struct plat_stmmacenet_data *plat_dat) 70 + static int imx8mp_set_intf_mode(struct imx_priv_data *dwmac, u8 phy_intf_sel) 68 71 { 69 - struct imx_priv_data *dwmac = plat_dat->bsp_priv; 70 - int val; 72 + unsigned int val; 71 73 72 - switch (plat_dat->phy_interface) { 73 - case PHY_INTERFACE_MODE_MII: 74 - val = GPR_ENET_QOS_INTF_SEL_MII; 75 - break; 76 - case PHY_INTERFACE_MODE_RMII: 77 - val = GPR_ENET_QOS_INTF_SEL_RMII; 78 - val |= (dwmac->rmii_refclk_ext ? 0 : GPR_ENET_QOS_CLK_TX_CLK_SEL); 79 - break; 80 - case PHY_INTERFACE_MODE_RGMII: 81 - case PHY_INTERFACE_MODE_RGMII_ID: 82 - case PHY_INTERFACE_MODE_RGMII_RXID: 83 - case PHY_INTERFACE_MODE_RGMII_TXID: 84 - val = GPR_ENET_QOS_INTF_SEL_RGMII | 85 - GPR_ENET_QOS_RGMII_EN; 86 - break; 87 - default: 88 - pr_debug("imx dwmac doesn't support %s interface\n", 89 - phy_modes(plat_dat->phy_interface)); 90 - return -EINVAL; 91 - } 74 + val = FIELD_PREP(GPR_ENET_QOS_INTF_SEL_MASK, phy_intf_sel) | 75 + GPR_ENET_QOS_CLK_GEN_EN; 92 76 93 - val |= GPR_ENET_QOS_CLK_GEN_EN; 77 + if (phy_intf_sel == PHY_INTF_SEL_RMII && !dwmac->rmii_refclk_ext) 78 + val |= GPR_ENET_QOS_CLK_TX_CLK_SEL; 79 + else if (phy_intf_sel == PHY_INTF_SEL_RGMII) 80 + val |= GPR_ENET_QOS_RGMII_EN; 81 + 94 82 return regmap_update_bits(dwmac->intf_regmap, dwmac->intf_reg_off, 95 83 GPR_ENET_QOS_INTF_MODE_MASK, val); 96 84 }; 97 85 98 86 static int 99 - imx8dxl_set_intf_mode(struct plat_stmmacenet_data *plat_dat) 87 + imx8dxl_set_intf_mode(struct imx_priv_data *dwmac, u8 phy_intf_sel) 100 88 { 101 - int ret = 0; 102 - 103 89 /* TBD: depends on imx8dxl scu interfaces to be upstreamed */ 104 - return ret; 90 + return 0; 105 91 } 106 92 107 - static int imx93_set_intf_mode(struct plat_stmmacenet_data *plat_dat) 93 + static int imx93_set_intf_mode(struct imx_priv_data *dwmac, u8 phy_intf_sel) 108 94 { 109 - struct imx_priv_data *dwmac = plat_dat->bsp_priv; 110 - int val, ret; 95 + unsigned int val; 96 + int ret; 111 97 112 - switch (plat_dat->phy_interface) { 113 - case PHY_INTERFACE_MODE_MII: 114 - val = MX93_GPR_ENET_QOS_INTF_SEL_MII; 115 - break; 116 - case PHY_INTERFACE_MODE_RMII: 117 - if (dwmac->rmii_refclk_ext) { 118 - ret = regmap_clear_bits(dwmac->intf_regmap, 119 - dwmac->intf_reg_off + 120 - MX93_GPR_CLK_SEL_OFFSET, 121 - MX93_GPR_ENET_QOS_CLK_SEL_MASK); 122 - if (ret) 123 - return ret; 124 - } 125 - val = MX93_GPR_ENET_QOS_INTF_SEL_RMII; 126 - break; 127 - case PHY_INTERFACE_MODE_RGMII: 128 - case PHY_INTERFACE_MODE_RGMII_ID: 129 - case PHY_INTERFACE_MODE_RGMII_RXID: 130 - case PHY_INTERFACE_MODE_RGMII_TXID: 131 - val = MX93_GPR_ENET_QOS_INTF_SEL_RGMII; 132 - break; 133 - default: 134 - dev_dbg(dwmac->dev, "imx dwmac doesn't support %s interface\n", 135 - phy_modes(plat_dat->phy_interface)); 136 - return -EINVAL; 98 + if (phy_intf_sel == PHY_INTF_SEL_RMII && dwmac->rmii_refclk_ext) { 99 + ret = regmap_clear_bits(dwmac->intf_regmap, 100 + dwmac->intf_reg_off + 101 + MX93_GPR_CLK_SEL_OFFSET, 102 + MX93_GPR_ENET_QOS_CLK_SEL_MASK); 103 + if (ret) 104 + return ret; 137 105 } 138 106 139 - val |= MX93_GPR_ENET_QOS_CLK_GEN_EN; 107 + val = FIELD_PREP(MX93_GPR_ENET_QOS_INTF_SEL_MASK, phy_intf_sel) | 108 + MX93_GPR_ENET_QOS_CLK_GEN_EN; 109 + 140 110 return regmap_update_bits(dwmac->intf_regmap, dwmac->intf_reg_off, 141 111 MX93_GPR_ENET_QOS_INTF_MODE_MASK, val); 142 112 }; ··· 134 170 return ret; 135 171 } 136 172 137 - static int imx_dwmac_init(struct platform_device *pdev, void *priv) 173 + static int imx_set_phy_intf_sel(void *bsp_priv, u8 phy_intf_sel) 138 174 { 139 - struct plat_stmmacenet_data *plat_dat; 140 - struct imx_priv_data *dwmac = priv; 141 - int ret; 175 + struct imx_priv_data *dwmac = bsp_priv; 142 176 143 - plat_dat = dwmac->plat_dat; 177 + if (!dwmac->ops->set_intf_mode) 178 + return 0; 144 179 145 - if (dwmac->ops->set_intf_mode) { 146 - ret = dwmac->ops->set_intf_mode(plat_dat); 147 - if (ret) 148 - return ret; 149 - } 180 + if (phy_intf_sel != PHY_INTF_SEL_GMII_MII && 181 + phy_intf_sel != PHY_INTF_SEL_RGMII && 182 + phy_intf_sel != PHY_INTF_SEL_RMII) 183 + return -EINVAL; 150 184 151 - return 0; 152 - } 153 - 154 - static void imx_dwmac_exit(struct platform_device *pdev, void *priv) 155 - { 156 - /* nothing to do now */ 185 + return dwmac->ops->set_intf_mode(dwmac, phy_intf_sel); 157 186 } 158 187 159 188 static int imx_dwmac_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i, 160 189 phy_interface_t interface, int speed) 161 190 { 162 - struct imx_priv_data *dwmac = bsp_priv; 163 - 164 - interface = dwmac->plat_dat->phy_interface; 165 191 if (interface == PHY_INTERFACE_MODE_RMII || 166 192 interface == PHY_INTERFACE_MODE_MII) 167 193 return 0; ··· 198 244 if (regmap_read(dwmac->intf_regmap, dwmac->intf_reg_off, &iface)) 199 245 return; 200 246 201 - iface &= MX93_GPR_ENET_QOS_INTF_MASK; 202 - if (iface != MX93_GPR_ENET_QOS_INTF_SEL_RGMII) 247 + if (FIELD_GET(MX93_GPR_ENET_QOS_INTF_SEL_MASK, iface) != 248 + PHY_INTF_SEL_RGMII) 203 249 return; 204 250 205 251 old_ctrl = readl(dwmac->base_addr + MAC_CTRL_REG); ··· 212 258 readl(dwmac->base_addr + MAC_CTRL_REG); 213 259 214 260 usleep_range(10, 20); 261 + iface &= MX93_GPR_ENET_QOS_INTF_SEL_MASK; 215 262 iface |= MX93_GPR_ENET_QOS_CLK_GEN_EN; 216 263 regmap_update_bits(dwmac->intf_regmap, dwmac->intf_reg_off, 217 264 MX93_GPR_ENET_QOS_INTF_MODE_MASK, iface); ··· 325 370 plat_dat->tx_queues_cfg[i].tbs_en = 1; 326 371 327 372 plat_dat->host_dma_width = dwmac->ops->addr_width; 328 - plat_dat->init = imx_dwmac_init; 329 - plat_dat->exit = imx_dwmac_exit; 373 + plat_dat->set_phy_intf_sel = imx_set_phy_intf_sel; 330 374 plat_dat->clks_config = imx_dwmac_clks_config; 331 375 plat_dat->bsp_priv = dwmac; 332 376 dwmac->plat_dat = plat_dat;
+5 -5
drivers/net/ethernet/stmicro/stmmac/dwmac-s32.c
··· 24 24 #define GMAC_INTF_RATE_125M 125000000 /* 125MHz */ 25 25 26 26 /* SoC PHY interface control register */ 27 - #define PHY_INTF_SEL_MII 0x00 28 - #define PHY_INTF_SEL_SGMII 0x01 29 - #define PHY_INTF_SEL_RGMII 0x02 30 - #define PHY_INTF_SEL_RMII 0x08 27 + #define S32_PHY_INTF_SEL_MII 0x00 28 + #define S32_PHY_INTF_SEL_SGMII 0x01 29 + #define S32_PHY_INTF_SEL_RGMII 0x02 30 + #define S32_PHY_INTF_SEL_RMII 0x08 31 31 32 32 struct s32_priv_data { 33 33 void __iomem *ioaddr; ··· 40 40 41 41 static int s32_gmac_write_phy_intf_select(struct s32_priv_data *gmac) 42 42 { 43 - writel(PHY_INTF_SEL_RGMII, gmac->ctrl_sts); 43 + writel(S32_PHY_INTF_SEL_RGMII, gmac->ctrl_sts); 44 44 45 45 dev_dbg(gmac->dev, "PHY mode set to %s\n", phy_modes(*gmac->intf_mode)); 46 46
+1
drivers/net/ethernet/stmicro/stmmac/stmmac.h
··· 396 396 void stmmac_ptp_unregister(struct stmmac_priv *priv); 397 397 int stmmac_xdp_open(struct net_device *dev); 398 398 void stmmac_xdp_release(struct net_device *dev); 399 + int stmmac_get_phy_intf_sel(phy_interface_t interface); 399 400 int stmmac_resume(struct device *dev); 400 401 int stmmac_suspend(struct device *dev); 401 402 void stmmac_dvr_remove(struct device *dev);
+54
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 3082 3082 } 3083 3083 } 3084 3084 3085 + int stmmac_get_phy_intf_sel(phy_interface_t interface) 3086 + { 3087 + int phy_intf_sel = -EINVAL; 3088 + 3089 + if (interface == PHY_INTERFACE_MODE_MII || 3090 + interface == PHY_INTERFACE_MODE_GMII) 3091 + phy_intf_sel = PHY_INTF_SEL_GMII_MII; 3092 + else if (phy_interface_mode_is_rgmii(interface)) 3093 + phy_intf_sel = PHY_INTF_SEL_RGMII; 3094 + else if (interface == PHY_INTERFACE_MODE_SGMII) 3095 + phy_intf_sel = PHY_INTF_SEL_SGMII; 3096 + else if (interface == PHY_INTERFACE_MODE_RMII) 3097 + phy_intf_sel = PHY_INTF_SEL_RMII; 3098 + else if (interface == PHY_INTERFACE_MODE_REVMII) 3099 + phy_intf_sel = PHY_INTF_SEL_REVMII; 3100 + 3101 + return phy_intf_sel; 3102 + } 3103 + EXPORT_SYMBOL_GPL(stmmac_get_phy_intf_sel); 3104 + 3105 + static int stmmac_prereset_configure(struct stmmac_priv *priv) 3106 + { 3107 + struct plat_stmmacenet_data *plat_dat = priv->plat; 3108 + phy_interface_t interface; 3109 + int phy_intf_sel, ret; 3110 + 3111 + if (!plat_dat->set_phy_intf_sel) 3112 + return 0; 3113 + 3114 + interface = plat_dat->phy_interface; 3115 + phy_intf_sel = stmmac_get_phy_intf_sel(interface); 3116 + if (phy_intf_sel < 0) { 3117 + netdev_err(priv->dev, 3118 + "failed to get phy_intf_sel for %s: %pe\n", 3119 + phy_modes(interface), ERR_PTR(phy_intf_sel)); 3120 + return phy_intf_sel; 3121 + } 3122 + 3123 + ret = plat_dat->set_phy_intf_sel(plat_dat->bsp_priv, phy_intf_sel); 3124 + if (ret == -EINVAL) 3125 + netdev_err(priv->dev, "platform does not support %s\n", 3126 + phy_modes(interface)); 3127 + else if (ret < 0) 3128 + netdev_err(priv->dev, 3129 + "platform failed to set interface %s: %pe\n", 3130 + phy_modes(interface), ERR_PTR(ret)); 3131 + 3132 + return ret; 3133 + } 3134 + 3085 3135 /** 3086 3136 * stmmac_init_dma_engine - DMA init. 3087 3137 * @priv: driver private structure ··· 3157 3107 3158 3108 if (priv->extend_desc && (priv->mode == STMMAC_RING_MODE)) 3159 3109 priv->plat->dma_cfg->atds = 1; 3110 + 3111 + ret = stmmac_prereset_configure(priv); 3112 + if (ret) 3113 + return ret; 3160 3114 3161 3115 ret = stmmac_reset(priv, priv->ioaddr); 3162 3116 if (ret) {
+1
include/linux/stmmac.h
··· 250 250 struct stmmac_txq_cfg tx_queues_cfg[MTL_MAX_TX_QUEUES]; 251 251 void (*get_interfaces)(struct stmmac_priv *priv, void *bsp_priv, 252 252 unsigned long *interfaces); 253 + int (*set_phy_intf_sel)(void *priv, u8 phy_intf_sel); 253 254 int (*set_clk_tx_rate)(void *priv, struct clk *clk_tx_i, 254 255 phy_interface_t interface, int speed); 255 256 void (*fix_mac_speed)(void *priv, int speed, unsigned int mode);