Currently the internal PCS initialization procedure is split up into several functions and special flags: 1. stmmac_check_pcs_mode() - determine the internal PCS based on the specified interface and init the mac_device_info::pcs field with the respective flag (STMMAC_PCS_RGMII or STMMAC_PCS_SGMII); 2. stmmac_ops::phylink_select_pcs() - callback specific for the DW GMAC and DW QoS Eth IP-cores which returns the pointer to the phylink_pcs structure if any of the STMMAC_PCS_RGMII or STMMAC_PCS_SGMII flag is found in the mac_device_info::pcs field. The initialization procedure described above can be simplified by converting the stmmac_check_pcs_mode() to the PCS-init method defined in stmmac_pcs.c, which besides would take the STMMAC_FLAG_HAS_INTEGRATED_PCS flag into account. Seeing the RGMII and SGMII MAC-interfaces can be only found on the DW GMAC and DW QoS Eth, the stmmac_ops::phylink_select_pcs() callbacks content can be freely moved right into the generic phylink_mac_ops::mac_select_pcs() function. Signed-off-by: Serge Semin <fancer.lancer@xxxxxxxxx> --- The change looks very promising and greatly simplifying the internal PCS initialization procedure by providing a single coherent method activating the internal PCS capability based on the requested interface and the detected DW MAC HW-capability. --- .../ethernet/stmicro/stmmac/dwmac1000_core.c | 16 +------------ .../net/ethernet/stmicro/stmmac/dwmac4_core.c | 17 +------------ drivers/net/ethernet/stmicro/stmmac/hwif.h | 15 ++---------- .../net/ethernet/stmicro/stmmac/stmmac_main.c | 24 ++++--------------- .../net/ethernet/stmicro/stmmac/stmmac_mdio.c | 3 +++ .../net/ethernet/stmicro/stmmac/stmmac_pcs.c | 15 ++++++++++++ .../net/ethernet/stmicro/stmmac/stmmac_pcs.h | 2 ++ 7 files changed, 28 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 2d77ffd16f0a..2fbb853cc19c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -16,7 +16,7 @@ #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/io.h> -#include <linux/phylink.h> + #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac1000.h" @@ -388,17 +388,6 @@ static u16 dwmac1000_pcs_get_config_reg(struct mac_device_info *hw) return FIELD_GET(GMAC_RGSMIIIS_CONFIG_REG, val); } -static struct phylink_pcs * -dwmac1000_phylink_select_pcs(struct stmmac_priv *priv, - phy_interface_t interface) -{ - if (priv->hw->pcs & STMMAC_PCS_RGMII || - priv->hw->pcs & STMMAC_PCS_SGMII) - return &priv->hw->mac_pcs; - - return NULL; -} - static void dwmac1000_debug(struct stmmac_priv *priv, void __iomem *ioaddr, struct stmmac_extra_stats *x, u32 rx_queues, u32 tx_queues) @@ -489,7 +478,6 @@ static void dwmac1000_set_mac_loopback(void __iomem *ioaddr, bool enable) const struct stmmac_ops dwmac1000_ops = { .core_init = dwmac1000_core_init, - .phylink_select_pcs = dwmac1000_phylink_select_pcs, .set_mac = stmmac_set_mac, .rx_ipc = dwmac1000_rx_ipc_enable, .dump_regs = dwmac1000_dump_regs, @@ -541,7 +529,5 @@ int dwmac1000_setup(struct stmmac_priv *priv) mac->mii.clk_csr_shift = 2; mac->mii.clk_csr_mask = GENMASK(5, 2); - mac->mac_pcs.neg_mode = true; - return 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index c58dc20eddeb..f5449f0962ad 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -14,7 +14,7 @@ #include <linux/slab.h> #include <linux/ethtool.h> #include <linux/io.h> -#include <linux/phylink.h> + #include "stmmac.h" #include "stmmac_pcs.h" #include "dwmac4.h" @@ -780,16 +780,6 @@ static void dwmac4_flow_ctrl(struct mac_device_info *hw, unsigned int duplex, } } -static struct phylink_pcs * -dwmac4_phylink_select_pcs(struct stmmac_priv *priv, phy_interface_t interface) -{ - if (priv->hw->pcs & STMMAC_PCS_RGMII || - priv->hw->pcs & STMMAC_PCS_SGMII) - return &priv->hw->mac_pcs; - - return NULL; -} - static int dwmac4_irq_mtl_status(struct stmmac_priv *priv, struct mac_device_info *hw, u32 chan) { @@ -1178,7 +1168,6 @@ static void dwmac4_set_hw_vlan_mode(struct mac_device_info *hw) const struct stmmac_ops dwmac4_ops = { .core_init = dwmac4_core_init, .update_caps = dwmac4_update_caps, - .phylink_select_pcs = dwmac4_phylink_select_pcs, .set_mac = stmmac_set_mac, .rx_ipc = dwmac4_rx_ipc_enable, .rx_queue_enable = dwmac4_rx_queue_enable, @@ -1224,7 +1213,6 @@ const struct stmmac_ops dwmac4_ops = { const struct stmmac_ops dwmac410_ops = { .core_init = dwmac4_core_init, .update_caps = dwmac4_update_caps, - .phylink_select_pcs = dwmac4_phylink_select_pcs, .set_mac = stmmac_dwmac4_set_mac, .rx_ipc = dwmac4_rx_ipc_enable, .rx_queue_enable = dwmac4_rx_queue_enable, @@ -1274,7 +1262,6 @@ const struct stmmac_ops dwmac410_ops = { const struct stmmac_ops dwmac510_ops = { .core_init = dwmac4_core_init, .update_caps = dwmac4_update_caps, - .phylink_select_pcs = dwmac4_phylink_select_pcs, .set_mac = stmmac_dwmac4_set_mac, .rx_ipc = dwmac4_rx_ipc_enable, .rx_queue_enable = dwmac4_rx_queue_enable, @@ -1389,7 +1376,5 @@ int dwmac4_setup(struct stmmac_priv *priv) mac->mii.clk_csr_mask = GENMASK(11, 8); mac->num_vlan = dwmac4_get_num_vlan(priv->ioaddr); - mac->mac_pcs.neg_mode = true; - return 0; } diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h index 3d39417e906d..4bacfe8a18e0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/hwif.h +++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h @@ -18,17 +18,13 @@ } \ __result; \ }) -#define stmmac_do_typed_callback(__type, __fail_ret, __priv, __module, \ - __cname, __arg0, __args...) \ +#define stmmac_do_callback(__priv, __module, __cname, __arg0, __args...) \ ({ \ - __type __result = __fail_ret; \ + int __result = -EINVAL; \ if ((__priv)->hw->__module && (__priv)->hw->__module->__cname) \ __result = (__priv)->hw->__module->__cname((__arg0), ##__args); \ __result; \ }) -#define stmmac_do_callback(__priv, __module, __cname, __arg0, __args...) \ - stmmac_do_typed_callback(int, -EINVAL, __priv, __module, __cname, \ - __arg0, ##__args) struct stmmac_extra_stats; struct stmmac_priv; @@ -315,9 +311,6 @@ struct stmmac_ops { void (*core_init)(struct mac_device_info *hw, struct net_device *dev); /* Update MAC capabilities */ void (*update_caps)(struct stmmac_priv *priv); - /* Get phylink PCS (for MAC */ - struct phylink_pcs *(*phylink_select_pcs)(struct stmmac_priv *priv, - phy_interface_t interface); /* Enable the MAC RX/TX */ void (*set_mac)(void __iomem *ioaddr, bool enable); /* Enable and verify that the IPC module is supported */ @@ -439,10 +432,6 @@ struct stmmac_ops { stmmac_do_void_callback(__priv, mac, core_init, __args) #define stmmac_mac_update_caps(__priv) \ stmmac_do_void_callback(__priv, mac, update_caps, __priv) -#define stmmac_mac_phylink_select_pcs(__priv, __interface) \ - stmmac_do_typed_callback(struct phylink_pcs *, ERR_PTR(-EOPNOTSUPP), \ - __priv, mac, phylink_select_pcs, __priv,\ - __interface) #define stmmac_mac_set(__priv, __args...) \ stmmac_do_void_callback(__priv, mac, set_mac, __args) #define stmmac_rx_ipc(__priv, __args...) \ diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 72c2d3e2c121..743d356f6d12 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -950,13 +950,16 @@ static struct phylink_pcs *stmmac_mac_select_pcs(struct phylink_config *config, { struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); + if (priv->hw->pcs) + return &priv->hw->mac_pcs; + if (priv->hw->xpcs) return &priv->hw->xpcs->pcs; if (priv->hw->phylink_pcs) return priv->hw->phylink_pcs; - return stmmac_mac_phylink_select_pcs(priv, interface); + return NULL; } static void stmmac_mac_config(struct phylink_config *config, unsigned int mode, @@ -1121,23 +1124,6 @@ static const struct phylink_mac_ops stmmac_phylink_mac_ops = { .mac_link_up = stmmac_mac_link_up, }; -/** - * stmmac_check_pcs_mode - verify if RGMII/SGMII is supported - * @priv: driver private structure - * Description: this is to verify if the HW supports the PCS. - * Physical Coding Sublayer (PCS) interface that can be used when the MAC is - * configured for the TBI, RTBI, or SGMII PHY interface. - */ -static void stmmac_check_pcs_mode(struct stmmac_priv *priv) -{ - int interface = priv->plat->mac_interface; - - if (phy_interface_mode_is_rgmii(interface)) - priv->hw->pcs = STMMAC_PCS_RGMII; - else if (priv->dma_cap.pcs && interface == PHY_INTERFACE_MODE_SGMII) - priv->hw->pcs = STMMAC_PCS_SGMII; -} - /** * stmmac_init_phy - PHY initialization * @dev: net device structure @@ -7704,8 +7690,6 @@ int stmmac_dvr_probe(struct device *device, else stmmac_clk_csr_set(priv); - stmmac_check_pcs_mode(priv); - pm_runtime_get_noresume(device); pm_runtime_set_active(device); if (!pm_runtime_enabled(device)) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index aa43117134d3..985b4b8c021f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -22,6 +22,7 @@ #include "dwxgmac2.h" #include "stmmac.h" +#include "stmmac_pcs.h" #define MII_BUSY 0x00000001 #define MII_WRITE 0x00000002 @@ -505,6 +506,8 @@ int stmmac_pcs_setup(struct net_device *ndev) priv = netdev_priv(ndev); mode = priv->plat->phy_interface; + dwmac_pcs_init(priv->hw); + if (priv->plat->pcs_init) { ret = priv->plat->pcs_init(priv); } else if (priv->plat->mdio_bus_data && diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c index aac49f6472f0..fdfc95299f89 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.c @@ -167,3 +167,18 @@ void dwmac_pcs_isr(struct mac_device_info *hw, unsigned int intr_status, if (an_status || sr_status) phylink_pcs_change(&hw->mac_pcs, false); } + +void dwmac_pcs_init(struct mac_device_info *hw) +{ + struct stmmac_priv *priv = hw->priv; + int interface = priv->plat->mac_interface; + + if (priv->plat->flags & STMMAC_FLAG_HAS_INTEGRATED_PCS) + return; + else if (phy_interface_mode_is_rgmii(interface)) + hw->pcs = STMMAC_PCS_RGMII; + else if (priv->dma_cap.pcs && interface == PHY_INTERFACE_MODE_SGMII) + hw->pcs = STMMAC_PCS_SGMII; + + hw->mac_pcs.neg_mode = true; +} diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h index 6e364285a4ef..a17e5b37c411 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h @@ -61,4 +61,6 @@ void dwmac_pcs_isr(struct mac_device_info *hw, unsigned int intr_status, struct stmmac_extra_stats *x); +void dwmac_pcs_init(struct mac_device_info *hw); + #endif /* __STMMAC_PCS_H__ */ -- 2.43.0