diff options
Diffstat (limited to 'drivers/net/phy/qcom/qca807x.c')
-rw-r--r-- | drivers/net/phy/qcom/qca807x.c | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c index 1af6b5ead74b..1be8295a95cb 100644 --- a/drivers/net/phy/qcom/qca807x.c +++ b/drivers/net/phy/qcom/qca807x.c @@ -124,6 +124,7 @@ struct qca807x_priv { bool dac_full_amplitude; bool dac_full_bias_current; bool dac_disable_bias_current_tweak; + struct qcom_phy_hw_stats hw_stats; }; static int qca807x_cable_test_start(struct phy_device *phydev) @@ -377,7 +378,7 @@ static int qca807x_gpio_get(struct gpio_chip *gc, unsigned int offset) return FIELD_GET(QCA807X_GPIO_FORCE_MODE_MASK, val); } -static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) +static int qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) { struct qca807x_gpio_priv *priv = gpiochip_get_data(gc); u16 reg; @@ -386,18 +387,19 @@ static void qca807x_gpio_set(struct gpio_chip *gc, unsigned int offset, int valu reg = QCA807X_MMD7_LED_FORCE_CTRL(offset); val = phy_read_mmd(priv->phy, MDIO_MMD_AN, reg); + if (val < 0) + return val; + val &= ~QCA807X_GPIO_FORCE_MODE_MASK; val |= QCA807X_GPIO_FORCE_EN; val |= FIELD_PREP(QCA807X_GPIO_FORCE_MODE_MASK, value); - phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); + return phy_write_mmd(priv->phy, MDIO_MMD_AN, reg, val); } static int qca807x_gpio_dir_out(struct gpio_chip *gc, unsigned int offset, int value) { - qca807x_gpio_set(gc, offset, value); - - return 0; + return qca807x_gpio_set(gc, offset, value); } static int qca807x_gpio(struct phy_device *phydev) @@ -644,13 +646,12 @@ exit: static int qca807x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) { struct phy_device *phydev = upstream; - __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, }; + const struct sfp_module_caps *caps; phy_interface_t iface; int ret; - DECLARE_PHY_INTERFACE_MASK(interfaces); - sfp_parse_support(phydev->sfp_bus, id, support, interfaces); - iface = sfp_select_interface(phydev->sfp_bus, support); + caps = sfp_get_module_caps(phydev->sfp_bus); + iface = sfp_select_interface(phydev->sfp_bus, caps->link_modes); dev_info(&phydev->mdio.dev, "%s SFP module inserted\n", phy_modes(iface)); @@ -767,6 +768,10 @@ static int qca807x_config_init(struct phy_device *phydev) return ret; } + ret = qcom_phy_counter_config(phydev); + if (ret) + return ret; + control_dac = phy_read_mmd(phydev, MDIO_MMD_AN, QCA807X_MMD7_1000BASE_T_POWER_SAVE_PER_CABLE_LENGTH); control_dac &= ~QCA807X_CONTROL_DAC_MASK; @@ -781,6 +786,22 @@ static int qca807x_config_init(struct phy_device *phydev) control_dac); } +static int qca807x_update_stats(struct phy_device *phydev) +{ + struct qca807x_priv *priv = phydev->priv; + + return qcom_phy_update_stats(phydev, &priv->hw_stats); +} + +static void qca807x_get_phy_stats(struct phy_device *phydev, + struct ethtool_eth_phy_stats *eth_stats, + struct ethtool_phy_stats *stats) +{ + struct qca807x_priv *priv = phydev->priv; + + qcom_phy_get_stats(stats, priv->hw_stats); +} + static struct phy_driver qca807x_drivers[] = { { PHY_ID_MATCH_EXACT(PHY_ID_QCA8072), @@ -799,6 +820,10 @@ static struct phy_driver qca807x_drivers[] = { .suspend = genphy_suspend, .cable_test_start = qca807x_cable_test_start, .cable_test_get_status = qca808x_cable_test_get_status, + .update_stats = qca807x_update_stats, + .get_phy_stats = qca807x_get_phy_stats, + .set_wol = at8031_set_wol, + .get_wol = at803x_get_wol, }, { PHY_ID_MATCH_EXACT(PHY_ID_QCA8075), @@ -822,6 +847,10 @@ static struct phy_driver qca807x_drivers[] = { .led_hw_is_supported = qca807x_led_hw_is_supported, .led_hw_control_set = qca807x_led_hw_control_set, .led_hw_control_get = qca807x_led_hw_control_get, + .update_stats = qca807x_update_stats, + .get_phy_stats = qca807x_get_phy_stats, + .set_wol = at8031_set_wol, + .get_wol = at803x_get_wol, }, }; module_phy_driver(qca807x_drivers); |