diff options
Diffstat (limited to 'drivers/net/phy/qcom/qca807x.c')
-rw-r--r-- | drivers/net/phy/qcom/qca807x.c | 58 |
1 files changed, 43 insertions, 15 deletions
diff --git a/drivers/net/phy/qcom/qca807x.c b/drivers/net/phy/qcom/qca807x.c index 3279de857b47..070dc8c00835 100644 --- a/drivers/net/phy/qcom/qca807x.c +++ b/drivers/net/phy/qcom/qca807x.c @@ -15,6 +15,7 @@ #include <linux/gpio/driver.h> #include <linux/sfp.h> +#include "../phylib.h" #include "qcom.h" #define QCA807X_CHIP_CONFIGURATION 0x1f @@ -123,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) @@ -376,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; @@ -385,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) @@ -486,13 +489,13 @@ static int qca807x_read_status(struct phy_device *phydev) static int qca807x_phy_package_probe_once(struct phy_device *phydev) { - struct phy_package_shared *shared = phydev->shared; - struct qca807x_shared_priv *priv = shared->priv; + struct qca807x_shared_priv *priv = phy_package_get_priv(phydev); + struct device_node *np = phy_package_get_node(phydev); unsigned int tx_drive_strength; const char *package_mode_name; /* Default to 600mw if not defined */ - if (of_property_read_u32(shared->np, "qcom,tx-drive-strength-milliwatt", + if (of_property_read_u32(np, "qcom,tx-drive-strength-milliwatt", &tx_drive_strength)) tx_drive_strength = 600; @@ -541,7 +544,7 @@ static int qca807x_phy_package_probe_once(struct phy_device *phydev) } priv->package_mode = PHY_INTERFACE_MODE_NA; - if (!of_property_read_string(shared->np, "qcom,package-mode", + if (!of_property_read_string(np, "qcom,package-mode", &package_mode_name)) { if (!strcasecmp(package_mode_name, phy_modes(PHY_INTERFACE_MODE_PSGMII))) @@ -558,8 +561,7 @@ static int qca807x_phy_package_probe_once(struct phy_device *phydev) static int qca807x_phy_package_config_init_once(struct phy_device *phydev) { - struct phy_package_shared *shared = phydev->shared; - struct qca807x_shared_priv *priv = shared->priv; + struct qca807x_shared_priv *priv = phy_package_get_priv(phydev); int val, ret; /* Make sure PHY follow PHY package mode if enforced */ @@ -708,7 +710,6 @@ static int qca807x_probe(struct phy_device *phydev) struct device_node *node = phydev->mdio.dev.of_node; struct qca807x_shared_priv *shared_priv; struct device *dev = &phydev->mdio.dev; - struct phy_package_shared *shared; struct qca807x_priv *priv; int ret; @@ -722,8 +723,7 @@ static int qca807x_probe(struct phy_device *phydev) return ret; } - shared = phydev->shared; - shared_priv = shared->priv; + shared_priv = phy_package_get_priv(phydev); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -769,12 +769,16 @@ 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; if (!priv->dac_full_amplitude) control_dac |= QCA807X_CONTROL_DAC_DSP_AMPLITUDE; - if (!priv->dac_full_amplitude) + if (!priv->dac_full_bias_current) control_dac |= QCA807X_CONTROL_DAC_DSP_BIAS_CURRENT; if (!priv->dac_disable_bias_current_tweak) control_dac |= QCA807X_CONTROL_DAC_BIAS_CURRENT_TWEAK; @@ -783,6 +787,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), @@ -801,6 +821,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), @@ -824,6 +848,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); |