diff options
Diffstat (limited to 'drivers/net/phy/mscc')
| -rw-r--r-- | drivers/net/phy/mscc/mscc.h | 12 | ||||
| -rw-r--r-- | drivers/net/phy/mscc/mscc_main.c | 466 | ||||
| -rw-r--r-- | drivers/net/phy/mscc/mscc_ptp.c | 21 |
3 files changed, 377 insertions, 122 deletions
diff --git a/drivers/net/phy/mscc/mscc.h b/drivers/net/phy/mscc/mscc.h index 2d8eca54c40a..65c9d7bd9315 100644 --- a/drivers/net/phy/mscc/mscc.h +++ b/drivers/net/phy/mscc/mscc.h @@ -85,6 +85,10 @@ enum rgmii_clock_delay { #define LED_MODE_SEL_MASK(x) (GENMASK(3, 0) << LED_MODE_SEL_POS(x)) #define LED_MODE_SEL(x, mode) (((mode) << LED_MODE_SEL_POS(x)) & LED_MODE_SEL_MASK(x)) +#define MSCC_PHY_LED_BEHAVIOR 30 +#define LED_COMBINE_DIS_MASK(x) BIT(x) +#define LED_COMBINE_DIS(x, dis) (((dis) ? 1 : 0) << (x)) + #define MSCC_EXT_PAGE_CSR_CNTL_17 17 #define MSCC_EXT_PAGE_CSR_CNTL_18 18 @@ -289,12 +293,12 @@ enum rgmii_clock_delay { #define PHY_ID_VSC8540 0x00070760 #define PHY_ID_VSC8541 0x00070770 #define PHY_ID_VSC8552 0x000704e0 -#define PHY_ID_VSC856X 0x000707e0 +#define PHY_ID_VSC856X 0x000707e1 #define PHY_ID_VSC8572 0x000704d0 #define PHY_ID_VSC8574 0x000704a0 -#define PHY_ID_VSC8575 0x000707d0 -#define PHY_ID_VSC8582 0x000707b0 -#define PHY_ID_VSC8584 0x000707c0 +#define PHY_ID_VSC8575 0x000707d1 +#define PHY_ID_VSC8582 0x000707b1 +#define PHY_ID_VSC8584 0x000707c1 #define PHY_VENDOR_MSCC 0x00070400 #define MSCC_VDDMAC_1500 1500 diff --git a/drivers/net/phy/mscc/mscc_main.c b/drivers/net/phy/mscc/mscc_main.c index ef0ef1570d39..2b9fb8a675a6 100644 --- a/drivers/net/phy/mscc/mscc_main.c +++ b/drivers/net/phy/mscc/mscc_main.c @@ -22,6 +22,24 @@ #include "mscc_serdes.h" #include "mscc.h" +struct vsc85xx_probe_config { + const struct vsc85xx_hw_stat *hw_stats; + size_t shared_size; + size_t nstats; + u16 supp_led_modes; + u8 nleds; + bool check_rate_magic; + bool use_package; + bool has_ptp; +}; + +static const u32 vsc85xx_default_led_modes_4[] = { + VSC8531_LINK_1000_ACTIVITY, + VSC8531_LINK_100_ACTIVITY, + VSC8531_LINK_ACTIVITY, + VSC8531_DUPLEX_COLLISION +}; + static const struct vsc85xx_hw_stat vsc85xx_hw_stats[] = { { .string = "phy_receive_errors", @@ -177,17 +195,19 @@ static int vsc85xx_led_cntl_set(struct phy_device *phydev, u8 led_num, u8 mode) { - int rc; - u16 reg_val; + u16 mask = LED_MODE_SEL_MASK(led_num); + u16 val = LED_MODE_SEL(led_num, mode); - mutex_lock(&phydev->lock); - reg_val = phy_read(phydev, MSCC_PHY_LED_MODE_SEL); - reg_val &= ~LED_MODE_SEL_MASK(led_num); - reg_val |= LED_MODE_SEL(led_num, (u16)mode); - rc = phy_write(phydev, MSCC_PHY_LED_MODE_SEL, reg_val); - mutex_unlock(&phydev->lock); + return phy_modify(phydev, MSCC_PHY_LED_MODE_SEL, mask, val); +} - return rc; +static int vsc85xx_led_combine_disable_set(struct phy_device *phydev, + u8 led_num, bool combine_disable) +{ + u16 val = LED_COMBINE_DIS(led_num, combine_disable); + u16 mask = LED_COMBINE_DIS_MASK(led_num); + + return phy_modify(phydev, MSCC_PHY_LED_BEHAVIOR, mask, val); } static int vsc85xx_mdix_get(struct phy_device *phydev, u8 *mdix) @@ -443,7 +463,7 @@ static int vsc85xx_dt_led_mode_get(struct phy_device *phydev, #endif /* CONFIG_OF_MDIO */ static int vsc85xx_dt_led_modes_get(struct phy_device *phydev, - u32 *default_mode) + const u32 *default_mode) { struct vsc8531_private *priv = phydev->priv; char led_dt_prop[28]; @@ -1724,12 +1744,6 @@ static int vsc8584_config_init(struct phy_device *phydev) * in this pre-init function. */ if (phy_package_init_once(phydev)) { - /* The following switch statement assumes that the lowest - * nibble of the phy_id_mask is always 0. This works because - * the lowest nibble of the PHY_ID's below are also 0. - */ - WARN_ON(phydev->drv->phy_id_mask & 0xf); - switch (phydev->phy_id & phydev->drv->phy_id_mask) { case PHY_ID_VSC8504: case PHY_ID_VSC8552: @@ -2224,12 +2238,13 @@ static int vsc85xx_config_inband(struct phy_device *phydev, unsigned int modes) reg_val); } -static int vsc8514_probe(struct phy_device *phydev) +static int vsc85xx_probe_common(struct phy_device *phydev, + const struct vsc85xx_probe_config *cfg, + const u32 *default_led_mode) { struct vsc8531_private *vsc8531; - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, - VSC8531_DUPLEX_COLLISION}; + struct device_node *np; + int ret; vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); if (!vsc8531) @@ -2237,124 +2252,291 @@ static int vsc8514_probe(struct phy_device *phydev) phydev->priv = vsc8531; - vsc8584_get_base_addr(phydev); - devm_phy_package_join(&phydev->mdio.dev, phydev, - vsc8531->base_addr, 0); + /* Check rate magic if needed (only for non-package PHYs) */ + if (cfg->check_rate_magic) { + ret = vsc85xx_edge_rate_magic_get(phydev); + if (ret < 0) + return ret; - vsc8531->nleds = 4; - vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; - vsc8531->hw_stats = vsc85xx_hw_stats; - vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); + vsc8531->rate_magic = ret; + } + + /* Set up package if needed */ + if (cfg->use_package) { + vsc8584_get_base_addr(phydev); + ret = devm_phy_package_join(&phydev->mdio.dev, phydev, + vsc8531->base_addr, + cfg->shared_size); + if (ret) + return ret; + } + + /* Configure LED settings */ + vsc8531->nleds = cfg->nleds; + vsc8531->supp_led_modes = cfg->supp_led_modes; + + /* Configure hardware stats */ + vsc8531->hw_stats = cfg->hw_stats; + vsc8531->nstats = cfg->nstats; vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, sizeof(u64), GFP_KERNEL); if (!vsc8531->stats) return -ENOMEM; - return vsc85xx_dt_led_modes_get(phydev, default_mode); + /* PTP setup for VSC8584 */ + if (cfg->has_ptp) { + if (phy_package_probe_once(phydev)) { + ret = vsc8584_ptp_probe_once(phydev); + if (ret) + return ret; + } + + ret = vsc8584_ptp_probe(phydev); + if (ret) + return ret; + } + + /* + * Check for LED configuration in device tree if available + * or fall back to default `vsc8531,led-x-mode` DT properties. + */ + np = of_get_child_by_name(phydev->mdio.dev.of_node, "leds"); + if (np) { + of_node_put(np); + + /* Force to defaults */ + for (unsigned int i = 0; i < vsc8531->nleds; i++) + vsc8531->leds_mode[i] = default_led_mode[i]; + + return 0; + } + + /* Parse LED modes from device tree */ + return vsc85xx_dt_led_modes_get(phydev, default_led_mode); } -static int vsc8574_probe(struct phy_device *phydev) +static int vsc85xx_led_brightness_set(struct phy_device *phydev, + u8 index, enum led_brightness value) { - struct vsc8531_private *vsc8531; - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, - VSC8531_DUPLEX_COLLISION}; + struct vsc8531_private *vsc8531 = phydev->priv; - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); - if (!vsc8531) - return -ENOMEM; + if (index >= vsc8531->nleds) + return -EINVAL; - phydev->priv = vsc8531; + return vsc85xx_led_cntl_set(phydev, index, value == LED_OFF ? + VSC8531_FORCE_LED_OFF : VSC8531_FORCE_LED_ON); +} - vsc8584_get_base_addr(phydev); - devm_phy_package_join(&phydev->mdio.dev, phydev, - vsc8531->base_addr, 0); +static int vsc85xx_led_hw_is_supported(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + static const unsigned long supported = BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK) | + BIT(TRIGGER_NETDEV_RX) | + BIT(TRIGGER_NETDEV_TX); + struct vsc8531_private *vsc8531 = phydev->priv; - vsc8531->nleds = 4; - vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; - vsc8531->hw_stats = vsc8584_hw_stats; - vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, - sizeof(u64), GFP_KERNEL); - if (!vsc8531->stats) - return -ENOMEM; + if (index >= vsc8531->nleds) + return -EINVAL; - return vsc85xx_dt_led_modes_get(phydev, default_mode); + if (rules & ~supported) + return -EOPNOTSUPP; + + return 0; } -static int vsc8584_probe(struct phy_device *phydev) +static int vsc85xx_led_hw_control_get(struct phy_device *phydev, u8 index, + unsigned long *rules) { - struct vsc8531_private *vsc8531; - u32 default_mode[4] = {VSC8531_LINK_1000_ACTIVITY, - VSC8531_LINK_100_ACTIVITY, VSC8531_LINK_ACTIVITY, - VSC8531_DUPLEX_COLLISION}; - int ret; + struct vsc8531_private *vsc8531 = phydev->priv; + u8 mode, behavior; + int rc; - if ((phydev->phy_id & MSCC_DEV_REV_MASK) != VSC8584_REVB) { - dev_err(&phydev->mdio.dev, "Only VSC8584 revB is supported.\n"); - return -ENOTSUPP; - } + if (index >= vsc8531->nleds) + return -EINVAL; - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); - if (!vsc8531) - return -ENOMEM; + rc = phy_read(phydev, MSCC_PHY_LED_MODE_SEL); + if (rc < 0) + return rc; + mode = (rc & LED_MODE_SEL_MASK(index)) >> LED_MODE_SEL_POS(index); - phydev->priv = vsc8531; + rc = phy_read(phydev, MSCC_PHY_LED_BEHAVIOR); + if (rc < 0) + return rc; + behavior = (rc & LED_COMBINE_DIS_MASK(index)) >> index; - vsc8584_get_base_addr(phydev); - devm_phy_package_join(&phydev->mdio.dev, phydev, vsc8531->base_addr, - sizeof(struct vsc85xx_shared_private)); + switch (mode) { + case VSC8531_LINK_ACTIVITY: + case VSC8531_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK); + break; - vsc8531->nleds = 4; - vsc8531->supp_led_modes = VSC8584_SUPP_LED_MODES; - vsc8531->hw_stats = vsc8584_hw_stats; - vsc8531->nstats = ARRAY_SIZE(vsc8584_hw_stats); - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, - sizeof(u64), GFP_KERNEL); - if (!vsc8531->stats) - return -ENOMEM; + case VSC8531_LINK_1000_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_LINK); + break; - if (phy_package_probe_once(phydev)) { - ret = vsc8584_ptp_probe_once(phydev); - if (ret) - return ret; + case VSC8531_LINK_100_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK); + break; + + case VSC8531_LINK_10_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK); + break; + + case VSC8531_LINK_100_1000_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK); + break; + + case VSC8531_LINK_10_1000_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_1000) | + BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK); + break; + + case VSC8531_LINK_10_100_ACTIVITY: + *rules = BIT(TRIGGER_NETDEV_LINK_100) | + BIT(TRIGGER_NETDEV_LINK_10) | + BIT(TRIGGER_NETDEV_LINK); + break; + + default: + *rules = 0; + break; } - ret = vsc8584_ptp_probe(phydev); - if (ret) + if (!behavior && *rules) + *rules |= BIT(TRIGGER_NETDEV_RX) | BIT(TRIGGER_NETDEV_TX); + + return 0; +} + +static int vsc85xx_led_hw_control_set(struct phy_device *phydev, u8 index, + unsigned long rules) +{ + struct vsc8531_private *vsc8531 = phydev->priv; + u8 mode = VSC8531_FORCE_LED_ON; + bool combine_disable = false; + bool has_rx, has_tx; + int ret; + + if (index >= vsc8531->nleds) + return -EINVAL; + + if (rules & BIT(TRIGGER_NETDEV_LINK)) + mode = VSC8531_LINK_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_10)) + mode = VSC8531_LINK_10_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_100)) + mode = VSC8531_LINK_100_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_1000)) + mode = VSC8531_LINK_1000_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_100) && + rules & BIT(TRIGGER_NETDEV_LINK_1000)) + mode = VSC8531_LINK_100_1000_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_10) && + rules & BIT(TRIGGER_NETDEV_LINK_1000)) + mode = VSC8531_LINK_10_1000_ACTIVITY; + + if (rules & BIT(TRIGGER_NETDEV_LINK_10) && + rules & BIT(TRIGGER_NETDEV_LINK_100)) + mode = VSC8531_LINK_10_100_ACTIVITY; + + /* + * The VSC85xx PHYs provides an option to control LED behavior. By + * default, the LEDx combine function is enabled, meaning the LED + * will be on when there is link/activity or duplex/collision. If + * the combine function is disabled, the LED will be on only for + * link or duplex. + * + * To control this behavior, we check the selected rules. If both + * RX and TX activity are not selected, the LED combine function + * is disabled; otherwise, it remains enabled. + */ + has_rx = !!(rules & BIT(TRIGGER_NETDEV_RX)); + has_tx = !!(rules & BIT(TRIGGER_NETDEV_TX)); + if (!has_rx && !has_tx) + combine_disable = true; + + ret = vsc85xx_led_combine_disable_set(phydev, index, combine_disable); + if (ret < 0) return ret; - return vsc85xx_dt_led_modes_get(phydev, default_mode); + return vsc85xx_led_cntl_set(phydev, index, mode); } -static int vsc85xx_probe(struct phy_device *phydev) +static int vsc8514_probe(struct phy_device *phydev) { - struct vsc8531_private *vsc8531; - int rate_magic; - u32 default_mode[2] = {VSC8531_LINK_1000_ACTIVITY, - VSC8531_LINK_100_ACTIVITY}; + static const struct vsc85xx_probe_config vsc8514_cfg = { + .nleds = 4, + .supp_led_modes = VSC85XX_SUPP_LED_MODES, + .hw_stats = vsc85xx_hw_stats, + .nstats = ARRAY_SIZE(vsc85xx_hw_stats), + .use_package = true, + .shared_size = 0, + .has_ptp = false, + .check_rate_magic = false, + }; - rate_magic = vsc85xx_edge_rate_magic_get(phydev); - if (rate_magic < 0) - return rate_magic; + return vsc85xx_probe_common(phydev, &vsc8514_cfg, vsc85xx_default_led_modes_4); +} - vsc8531 = devm_kzalloc(&phydev->mdio.dev, sizeof(*vsc8531), GFP_KERNEL); - if (!vsc8531) - return -ENOMEM; +static int vsc8574_probe(struct phy_device *phydev) +{ + static const struct vsc85xx_probe_config vsc8574_cfg = { + .nleds = 4, + .supp_led_modes = VSC8584_SUPP_LED_MODES, + .hw_stats = vsc8584_hw_stats, + .nstats = ARRAY_SIZE(vsc8584_hw_stats), + .use_package = true, + .shared_size = 0, + .has_ptp = false, + .check_rate_magic = false, + }; - phydev->priv = vsc8531; + return vsc85xx_probe_common(phydev, &vsc8574_cfg, vsc85xx_default_led_modes_4); +} - vsc8531->rate_magic = rate_magic; - vsc8531->nleds = 2; - vsc8531->supp_led_modes = VSC85XX_SUPP_LED_MODES; - vsc8531->hw_stats = vsc85xx_hw_stats; - vsc8531->nstats = ARRAY_SIZE(vsc85xx_hw_stats); - vsc8531->stats = devm_kcalloc(&phydev->mdio.dev, vsc8531->nstats, - sizeof(u64), GFP_KERNEL); - if (!vsc8531->stats) - return -ENOMEM; +static int vsc8584_probe(struct phy_device *phydev) +{ + static const struct vsc85xx_probe_config vsc8584_cfg = { + .nleds = 4, + .supp_led_modes = VSC8584_SUPP_LED_MODES, + .hw_stats = vsc8584_hw_stats, + .nstats = ARRAY_SIZE(vsc8584_hw_stats), + .use_package = true, + .shared_size = sizeof(struct vsc85xx_shared_private), + .has_ptp = true, + .check_rate_magic = false, + }; + + return vsc85xx_probe_common(phydev, &vsc8584_cfg, vsc85xx_default_led_modes_4); +} + +static int vsc85xx_probe(struct phy_device *phydev) +{ + static const struct vsc85xx_probe_config vsc85xx_cfg = { + .nleds = 2, + .supp_led_modes = VSC85XX_SUPP_LED_MODES, + .hw_stats = vsc85xx_hw_stats, + .nstats = ARRAY_SIZE(vsc85xx_hw_stats), + .use_package = false, + .has_ptp = false, + .check_rate_magic = true, + }; - return vsc85xx_dt_led_modes_get(phydev, default_mode); + return vsc85xx_probe_common(phydev, &vsc85xx_cfg, vsc85xx_default_led_modes_4); } static void vsc85xx_remove(struct phy_device *phydev) @@ -2387,6 +2569,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8502, @@ -2411,6 +2597,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8504, @@ -2438,6 +2628,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8514, @@ -2463,6 +2657,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8530, @@ -2487,6 +2685,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8531, @@ -2511,6 +2713,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8540, @@ -2535,6 +2741,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8541, @@ -2559,6 +2769,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_sset_count = &vsc85xx_get_sset_count, .get_strings = &vsc85xx_get_strings, .get_stats = &vsc85xx_get_stats, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8552, @@ -2585,11 +2799,14 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { - .phy_id = PHY_ID_VSC856X, + PHY_ID_MATCH_EXACT(PHY_ID_VSC856X), .name = "Microsemi GE VSC856X SyncE", - .phy_id_mask = 0xfffffff0, /* PHY_GBIT_FEATURES */ .soft_reset = &genphy_soft_reset, .config_init = &vsc8584_config_init, @@ -2609,6 +2826,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8572, @@ -2625,7 +2846,7 @@ static struct phy_driver vsc85xx_driver[] = { .suspend = &genphy_suspend, .resume = &genphy_resume, .remove = &vsc85xx_remove, - .probe = &vsc8574_probe, + .probe = &vsc8584_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get, .get_tunable = &vsc85xx_get_tunable, @@ -2637,6 +2858,10 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { .phy_id = PHY_ID_VSC8574, @@ -2648,12 +2873,12 @@ static struct phy_driver vsc85xx_driver[] = { .config_aneg = &vsc85xx_config_aneg, .aneg_done = &genphy_aneg_done, .read_status = &vsc85xx_read_status, - .handle_interrupt = vsc85xx_handle_interrupt, + .handle_interrupt = vsc8584_handle_interrupt, .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, .remove = &vsc85xx_remove, - .probe = &vsc8574_probe, + .probe = &vsc8584_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get, .get_tunable = &vsc85xx_get_tunable, @@ -2665,11 +2890,14 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { - .phy_id = PHY_ID_VSC8575, + PHY_ID_MATCH_EXACT(PHY_ID_VSC8575), .name = "Microsemi GE VSC8575 SyncE", - .phy_id_mask = 0xfffffff0, /* PHY_GBIT_FEATURES */ .soft_reset = &genphy_soft_reset, .config_init = &vsc8584_config_init, @@ -2691,11 +2919,14 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { - .phy_id = PHY_ID_VSC8582, + PHY_ID_MATCH_EXACT(PHY_ID_VSC8582), .name = "Microsemi GE VSC8582 SyncE", - .phy_id_mask = 0xfffffff0, /* PHY_GBIT_FEATURES */ .soft_reset = &genphy_soft_reset, .config_init = &vsc8584_config_init, @@ -2717,11 +2948,14 @@ static struct phy_driver vsc85xx_driver[] = { .get_stats = &vsc85xx_get_stats, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, }, { - .phy_id = PHY_ID_VSC8584, + PHY_ID_MATCH_EXACT(PHY_ID_VSC8584), .name = "Microsemi GE VSC8584 SyncE", - .phy_id_mask = 0xfffffff0, /* PHY_GBIT_FEATURES */ .soft_reset = &genphy_soft_reset, .config_init = &vsc8584_config_init, @@ -2744,6 +2978,10 @@ static struct phy_driver vsc85xx_driver[] = { .link_change_notify = &vsc85xx_link_change_notify, .inband_caps = vsc85xx_inband_caps, .config_inband = vsc85xx_config_inband, + .led_brightness_set = vsc85xx_led_brightness_set, + .led_hw_is_supported = vsc85xx_led_hw_is_supported, + .led_hw_control_get = vsc85xx_led_hw_control_get, + .led_hw_control_set = vsc85xx_led_hw_control_set, } }; diff --git a/drivers/net/phy/mscc/mscc_ptp.c b/drivers/net/phy/mscc/mscc_ptp.c index d692df7d975c..4865eac74b0e 100644 --- a/drivers/net/phy/mscc/mscc_ptp.c +++ b/drivers/net/phy/mscc/mscc_ptp.c @@ -1051,9 +1051,21 @@ static void vsc85xx_ts_reset_fifo(struct phy_device *phydev) val); } -static int vsc85xx_hwtstamp(struct mii_timestamper *mii_ts, - struct kernel_hwtstamp_config *cfg, - struct netlink_ext_ack *extack) +static int vsc85xx_hwtstamp_get(struct mii_timestamper *mii_ts, + struct kernel_hwtstamp_config *cfg) +{ + struct vsc8531_private *vsc8531 = + container_of(mii_ts, struct vsc8531_private, mii_ts); + + cfg->tx_type = vsc8531->ptp->tx_type; + cfg->rx_filter = vsc8531->ptp->rx_filter; + + return 0; +} + +static int vsc85xx_hwtstamp_set(struct mii_timestamper *mii_ts, + struct kernel_hwtstamp_config *cfg, + struct netlink_ext_ack *extack) { struct vsc8531_private *vsc8531 = container_of(mii_ts, struct vsc8531_private, mii_ts); @@ -1611,7 +1623,8 @@ int vsc8584_ptp_probe(struct phy_device *phydev) vsc8531->mii_ts.rxtstamp = vsc85xx_rxtstamp; vsc8531->mii_ts.txtstamp = vsc85xx_txtstamp; - vsc8531->mii_ts.hwtstamp = vsc85xx_hwtstamp; + vsc8531->mii_ts.hwtstamp_set = vsc85xx_hwtstamp_set; + vsc8531->mii_ts.hwtstamp_get = vsc85xx_hwtstamp_get; vsc8531->mii_ts.ts_info = vsc85xx_ts_info; phydev->mii_ts = &vsc8531->mii_ts; |
