diff options
Diffstat (limited to 'drivers/net/pcs')
-rw-r--r-- | drivers/net/pcs/pcs-lynx.c | 1 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-mtk-lynxi.c | 1 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-rzn1-miic.c | 22 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.c | 105 | ||||
-rw-r--r-- | drivers/net/pcs/pcs-xpcs.h | 26 |
5 files changed, 89 insertions, 66 deletions
diff --git a/drivers/net/pcs/pcs-lynx.c b/drivers/net/pcs/pcs-lynx.c index e46f588cae7d..23b40e9eacbb 100644 --- a/drivers/net/pcs/pcs-lynx.c +++ b/drivers/net/pcs/pcs-lynx.c @@ -355,7 +355,6 @@ static struct phylink_pcs *lynx_pcs_create(struct mdio_device *mdio) mdio_device_get(mdio); lynx->mdio = mdio; lynx->pcs.ops = &lynx_pcs_phylink_ops; - lynx->pcs.neg_mode = true; lynx->pcs.poll = true; for (i = 0; i < ARRAY_SIZE(lynx_interfaces); i++) diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c index 7d6261dee534..149ddf51d785 100644 --- a/drivers/net/pcs/pcs-mtk-lynxi.c +++ b/drivers/net/pcs/pcs-mtk-lynxi.c @@ -305,7 +305,6 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev, mpcs->regmap = regmap; mpcs->flags = flags; mpcs->pcs.ops = &mtk_pcs_lynxi_ops; - mpcs->pcs.neg_mode = true; mpcs->pcs.poll = true; mpcs->interface = PHY_INTERFACE_MODE_NA; diff --git a/drivers/net/pcs/pcs-rzn1-miic.c b/drivers/net/pcs/pcs-rzn1-miic.c index 61944574d087..d79bb9b06cd2 100644 --- a/drivers/net/pcs/pcs-rzn1-miic.c +++ b/drivers/net/pcs/pcs-rzn1-miic.c @@ -268,17 +268,6 @@ static void miic_link_up(struct phylink_pcs *pcs, unsigned int neg_mode, (MIIC_CONVCTRL_CONV_SPEED | MIIC_CONVCTRL_FULLD), val); } -static int miic_validate(struct phylink_pcs *pcs, unsigned long *supported, - const struct phylink_link_state *state) -{ - if (phy_interface_mode_is_rgmii(state->interface) || - state->interface == PHY_INTERFACE_MODE_RMII || - state->interface == PHY_INTERFACE_MODE_MII) - return 1; - - return -EINVAL; -} - static int miic_pre_init(struct phylink_pcs *pcs) { struct miic_port *miic_port = phylink_pcs_to_miic_port(pcs); @@ -307,7 +296,6 @@ static int miic_pre_init(struct phylink_pcs *pcs) } static const struct phylink_pcs_ops miic_phylink_ops = { - .pcs_validate = miic_validate, .pcs_config = miic_config, .pcs_link_up = miic_link_up, .pcs_pre_init = miic_pre_init, @@ -361,7 +349,10 @@ struct phylink_pcs *miic_create(struct device *dev, struct device_node *np) miic_port->miic = miic; miic_port->port = port - 1; miic_port->pcs.ops = &miic_phylink_ops; - miic_port->pcs.neg_mode = true; + + phy_interface_set_rgmii(miic_port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_RMII, miic_port->pcs.supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_MII, miic_port->pcs.supported_interfaces); return &miic_port->pcs; } @@ -472,13 +463,10 @@ static int miic_parse_dt(struct device *dev, u32 *mode_cfg) if (of_property_read_u32(np, "renesas,miic-switch-portin", &conf) == 0) dt_val[0] = conf; - for_each_child_of_node(np, conv) { + for_each_available_child_of_node(np, conv) { if (of_property_read_u32(conv, "reg", &port)) continue; - if (!of_device_is_available(conv)) - continue; - if (of_property_read_u32(conv, "renesas,miic-input", &conf) == 0) dt_val[port] = conf; } diff --git a/drivers/net/pcs/pcs-xpcs.c b/drivers/net/pcs/pcs-xpcs.c index 1faa37f0e7b9..3d1bd5aac093 100644 --- a/drivers/net/pcs/pcs-xpcs.c +++ b/drivers/net/pcs/pcs-xpcs.c @@ -602,35 +602,21 @@ static void xpcs_get_interfaces(struct dw_xpcs *xpcs, unsigned long *interfaces) __set_bit(compat->interface, interfaces); } -int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) +static int xpcs_switch_interface_mode(struct dw_xpcs *xpcs, + phy_interface_t interface) { - u16 mask, val; - int ret; - - mask = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | - DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | - DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | - DW_VR_MII_EEE_MULT_FACT_100NS; + int ret = 0; - if (enable) - val = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | - DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | - DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | - FIELD_PREP(DW_VR_MII_EEE_MULT_FACT_100NS, - mult_fact_100ns); - else - val = 0; - - ret = xpcs_modify(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, mask, - val); - if (ret < 0) - return ret; + if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { + ret = txgbe_xpcs_switch_mode(xpcs, interface); + } else if (xpcs->interface != interface) { + if (interface == PHY_INTERFACE_MODE_SGMII) + xpcs->need_reset = true; + xpcs->interface = interface; + } - return xpcs_modify(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, - DW_VR_MII_EEE_TRN_LPI, - enable ? DW_VR_MII_EEE_TRN_LPI : 0); + return ret; } -EXPORT_SYMBOL_GPL(xpcs_config_eee); static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface) { @@ -638,6 +624,11 @@ static void xpcs_pre_config(struct phylink_pcs *pcs, phy_interface_t interface) const struct dw_xpcs_compat *compat; int ret; + ret = xpcs_switch_interface_mode(xpcs, interface); + if (ret) + dev_err(&xpcs->mdiodev->dev, "switch interface failed: %pe\n", + ERR_PTR(ret)); + if (!xpcs->need_reset) return; @@ -829,10 +820,6 @@ static int xpcs_do_config(struct dw_xpcs *xpcs, phy_interface_t interface, return -ENODEV; if (xpcs->info.pma == WX_TXGBE_XPCS_PMA_10G_ID) { - ret = txgbe_xpcs_switch_mode(xpcs, interface); - if (ret) - return ret; - /* Wangxun devices need backplane CL37 AN enabled for * SGMII and 1000base-X */ @@ -1193,6 +1180,63 @@ static void xpcs_an_restart(struct phylink_pcs *pcs) BMCR_ANRESTART); } +static int xpcs_config_eee(struct dw_xpcs *xpcs, bool enable) +{ + u16 mask, val; + int ret; + + mask = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | + DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | + DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | + DW_VR_MII_EEE_MULT_FACT_100NS; + + if (enable) + val = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | + DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | + DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | + FIELD_PREP(DW_VR_MII_EEE_MULT_FACT_100NS, + xpcs->eee_mult_fact); + else + val = 0; + + ret = xpcs_modify(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0, mask, + val); + if (ret < 0) + return ret; + + return xpcs_modify(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, + DW_VR_MII_EEE_TRN_LPI, + enable ? DW_VR_MII_EEE_TRN_LPI : 0); +} + +static void xpcs_disable_eee(struct phylink_pcs *pcs) +{ + struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); + + xpcs_config_eee(xpcs, false); +} + +static void xpcs_enable_eee(struct phylink_pcs *pcs) +{ + struct dw_xpcs *xpcs = phylink_pcs_to_xpcs(pcs); + + xpcs_config_eee(xpcs, true); +} + +/** + * xpcs_config_eee_mult_fact() - set the EEE clock multiplying factor + * @xpcs: pointer to a &struct dw_xpcs instance + * @mult_fact: the multiplying factor + * + * Configure the EEE clock multiplying factor. This value should be such that + * clk_eee_time_period * (mult_fact + 1) is within the range 80 to 120ns. + */ +void xpcs_config_eee_mult_fact(struct dw_xpcs *xpcs, u8 mult_fact) +{ + xpcs->eee_mult_fact = mult_fact; +} +EXPORT_SYMBOL_GPL(xpcs_config_eee_mult_fact); + static int xpcs_read_ids(struct dw_xpcs *xpcs) { int ret; @@ -1341,6 +1385,8 @@ static const struct phylink_pcs_ops xpcs_phylink_ops = { .pcs_get_state = xpcs_get_state, .pcs_an_restart = xpcs_an_restart, .pcs_link_up = xpcs_link_up, + .pcs_disable_eee = xpcs_disable_eee, + .pcs_enable_eee = xpcs_enable_eee, }; static int xpcs_identify(struct dw_xpcs *xpcs) @@ -1374,7 +1420,6 @@ static struct dw_xpcs *xpcs_create_data(struct mdio_device *mdiodev) mdio_device_get(mdiodev); xpcs->mdiodev = mdiodev; xpcs->pcs.ops = &xpcs_phylink_ops; - xpcs->pcs.neg_mode = true; xpcs->pcs.poll = true; return xpcs; diff --git a/drivers/net/pcs/pcs-xpcs.h b/drivers/net/pcs/pcs-xpcs.h index adc5a0b3c883..929fa238445e 100644 --- a/drivers/net/pcs/pcs-xpcs.h +++ b/drivers/net/pcs/pcs-xpcs.h @@ -55,23 +55,11 @@ /* Clause 37 Defines */ /* VR MII MMD registers offsets */ #define DW_VR_MII_DIG_CTRL1 0x8000 -#define DW_VR_MII_AN_CTRL 0x8001 -#define DW_VR_MII_AN_INTR_STS 0x8002 -/* EEE Mode Control Register */ -#define DW_VR_MII_EEE_MCTRL0 0x8006 -#define DW_VR_MII_EEE_MCTRL1 0x800b -#define DW_VR_MII_DIG_CTRL2 0x80e1 - -/* VR_MII_DIG_CTRL1 */ #define DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW BIT(9) #define DW_VR_MII_DIG_CTRL1_2G5_EN BIT(2) #define DW_VR_MII_DIG_CTRL1_PHY_MODE_CTRL BIT(0) -/* VR_MII_DIG_CTRL2 */ -#define DW_VR_MII_DIG_CTRL2_TX_POL_INV BIT(4) -#define DW_VR_MII_DIG_CTRL2_RX_POL_INV BIT(0) - -/* VR_MII_AN_CTRL */ +#define DW_VR_MII_AN_CTRL 0x8001 #define DW_VR_MII_AN_CTRL_8BIT BIT(8) #define DW_VR_MII_TX_CONFIG_MASK BIT(3) #define DW_VR_MII_TX_CONFIG_PHY_SIDE_SGMII 0x1 @@ -81,7 +69,7 @@ #define DW_VR_MII_PCS_MODE_C37_SGMII 0x2 #define DW_VR_MII_AN_INTR_EN BIT(0) -/* VR_MII_AN_INTR_STS */ +#define DW_VR_MII_AN_INTR_STS 0x8002 #define DW_VR_MII_AN_STS_C37_ANCMPLT_INTR BIT(0) #define DW_VR_MII_AN_STS_C37_ANSGM_FD BIT(1) #define DW_VR_MII_AN_STS_C37_ANSGM_SP GENMASK(3, 2) @@ -90,19 +78,22 @@ #define DW_VR_MII_C37_ANSGM_SP_1000 0x2 #define DW_VR_MII_C37_ANSGM_SP_LNKSTS BIT(4) -/* VR MII EEE Control 0 defines */ +#define DW_VR_MII_EEE_MCTRL0 0x8006 #define DW_VR_MII_EEE_LTX_EN BIT(0) /* LPI Tx Enable */ #define DW_VR_MII_EEE_LRX_EN BIT(1) /* LPI Rx Enable */ #define DW_VR_MII_EEE_TX_QUIET_EN BIT(2) /* Tx Quiet Enable */ #define DW_VR_MII_EEE_RX_QUIET_EN BIT(3) /* Rx Quiet Enable */ #define DW_VR_MII_EEE_TX_EN_CTRL BIT(4) /* Tx Control Enable */ #define DW_VR_MII_EEE_RX_EN_CTRL BIT(7) /* Rx Control Enable */ - #define DW_VR_MII_EEE_MULT_FACT_100NS GENMASK(11, 8) -/* VR MII EEE Control 1 defines */ +#define DW_VR_MII_EEE_MCTRL1 0x800b #define DW_VR_MII_EEE_TRN_LPI BIT(0) /* Transparent Mode Enable */ +#define DW_VR_MII_DIG_CTRL2 0x80e1 +#define DW_VR_MII_DIG_CTRL2_TX_POL_INV BIT(4) +#define DW_VR_MII_DIG_CTRL2_RX_POL_INV BIT(0) + #define DW_XPCS_INFO_DECLARE(_name, _pcs, _pma) \ static const struct dw_xpcs_info _name = { .pcs = _pcs, .pma = _pma } @@ -122,6 +113,7 @@ struct dw_xpcs { struct phylink_pcs pcs; phy_interface_t interface; bool need_reset; + u8 eee_mult_fact; }; int xpcs_read(struct dw_xpcs *xpcs, int dev, u32 reg); |