summaryrefslogtreecommitdiff
path: root/drivers/net/phy/aquantia/aquantia_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/aquantia/aquantia_main.c')
-rw-r--r--drivers/net/phy/aquantia/aquantia_main.c140
1 files changed, 97 insertions, 43 deletions
diff --git a/drivers/net/phy/aquantia/aquantia_main.c b/drivers/net/phy/aquantia/aquantia_main.c
index d34cdec47636..d12e35374231 100644
--- a/drivers/net/phy/aquantia/aquantia_main.c
+++ b/drivers/net/phy/aquantia/aquantia_main.c
@@ -29,6 +29,7 @@
#define PHY_ID_AQR113 0x31c31c40
#define PHY_ID_AQR113C 0x31c31c12
#define PHY_ID_AQR114C 0x31c31c22
+#define PHY_ID_AQR115C 0x31c31c33
#define PHY_ID_AQR813 0x31c31cb2
#define MDIO_PHYXS_VEND_IF_STATUS 0xe812
@@ -84,49 +85,12 @@
#define MDIO_AN_RX_VEND_STAT3 0xe832
#define MDIO_AN_RX_VEND_STAT3_AFR BIT(0)
-/* MDIO_MMD_C22EXT */
-#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES 0xd292
-#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES 0xd294
-#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER 0xd297
-#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES 0xd313
-#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES 0xd315
-#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER 0xd317
-#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS 0xd318
-#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS 0xd319
-#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR 0xd31a
-#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES 0xd31b
-
/* Sleep and timeout for checking if the Processor-Intensive
* MDIO operation is finished
*/
#define AQR107_OP_IN_PROG_SLEEP 1000
#define AQR107_OP_IN_PROG_TIMEOUT 100000
-struct aqr107_hw_stat {
- const char *name;
- int reg;
- int size;
-};
-
-#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
-static const struct aqr107_hw_stat aqr107_hw_stats[] = {
- SGMII_STAT("sgmii_rx_good_frames", RX_GOOD_FRAMES, 26),
- SGMII_STAT("sgmii_rx_bad_frames", RX_BAD_FRAMES, 26),
- SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER, 8),
- SGMII_STAT("sgmii_tx_good_frames", TX_GOOD_FRAMES, 26),
- SGMII_STAT("sgmii_tx_bad_frames", TX_BAD_FRAMES, 26),
- SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER, 8),
- SGMII_STAT("sgmii_tx_collisions", TX_COLLISIONS, 8),
- SGMII_STAT("sgmii_tx_line_collisions", TX_LINE_COLLISIONS, 8),
- SGMII_STAT("sgmii_tx_frame_alignment_err", TX_FRAME_ALIGN_ERR, 16),
- SGMII_STAT("sgmii_tx_runt_frames", TX_RUNT_FRAMES, 22),
-};
-#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
-
-struct aqr107_priv {
- u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
-};
-
static int aqr107_get_sset_count(struct phy_device *phydev)
{
return AQR107_SGMII_STAT_SZ;
@@ -478,7 +442,7 @@ static int aqr107_set_tunable(struct phy_device *phydev,
* The chip also provides a "reset completed" bit, but it's cleared after
* read. Therefore function would time out if called again.
*/
-static int aqr107_wait_reset_complete(struct phy_device *phydev)
+int aqr_wait_reset_complete(struct phy_device *phydev)
{
int val;
@@ -512,7 +476,9 @@ static void aqr107_chip_info(struct phy_device *phydev)
static int aqr107_config_init(struct phy_device *phydev)
{
- int ret;
+ struct aqr107_priv *priv = phydev->priv;
+ u32 led_active_low;
+ int ret, index = 0;
/* Check that the PHY interface type is compatible */
if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
@@ -529,11 +495,23 @@ static int aqr107_config_init(struct phy_device *phydev)
WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
"Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
- ret = aqr107_wait_reset_complete(phydev);
+ ret = aqr_wait_reset_complete(phydev);
if (!ret)
aqr107_chip_info(phydev);
- return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+ ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
+ if (ret)
+ return ret;
+
+ /* Restore LED polarity state after reset */
+ for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {
+ ret = aqr_phy_led_active_low_set(phydev, index, led_active_low);
+ if (ret)
+ return ret;
+ index++;
+ }
+
+ return 0;
}
static int aqcs109_config_init(struct phy_device *phydev)
@@ -545,7 +523,7 @@ static int aqcs109_config_init(struct phy_device *phydev)
phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
return -ENODEV;
- ret = aqr107_wait_reset_complete(phydev);
+ ret = aqr_wait_reset_complete(phydev);
if (!ret)
aqr107_chip_info(phydev);
@@ -675,7 +653,13 @@ static int aqr107_fill_interface_modes(struct phy_device *phydev)
unsigned long *possible = phydev->possible_interfaces;
unsigned int serdes_mode, rate_adapt;
phy_interface_t interface;
- int i, val;
+ int i, val, ret;
+
+ ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
+ VEND1_GLOBAL_CFG_10M, val, val != 0,
+ 1000, 100000, false);
+ if (ret)
+ return ret;
/* Walk the media-speed configuration registers to determine which
* host-side serdes modes may be used by the PHY depending on the
@@ -823,6 +807,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
@@ -842,6 +831,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR111),
@@ -861,6 +855,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),
@@ -880,6 +879,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
@@ -906,6 +910,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR412),
@@ -943,6 +952,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),
@@ -962,6 +976,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),
@@ -981,6 +1000,35 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
+},
+{
+ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C),
+ .name = "Aquantia AQR115C",
+ .probe = aqr107_probe,
+ .get_rate_matching = aqr107_get_rate_matching,
+ .config_init = aqr113c_config_init,
+ .config_aneg = aqr_config_aneg,
+ .config_intr = aqr_config_intr,
+ .handle_interrupt = aqr_handle_interrupt,
+ .read_status = aqr107_read_status,
+ .get_tunable = aqr107_get_tunable,
+ .set_tunable = aqr107_set_tunable,
+ .suspend = aqr107_suspend,
+ .resume = aqr107_resume,
+ .get_sset_count = aqr107_get_sset_count,
+ .get_strings = aqr107_get_strings,
+ .get_stats = aqr107_get_stats,
+ .link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
{
PHY_ID_MATCH_MODEL(PHY_ID_AQR813),
@@ -1000,6 +1048,11 @@ static struct phy_driver aqr_driver[] = {
.get_strings = aqr107_get_strings,
.get_stats = aqr107_get_stats,
.link_change_notify = aqr107_link_change_notify,
+ .led_brightness_set = aqr_phy_led_brightness_set,
+ .led_hw_is_supported = aqr_phy_led_hw_is_supported,
+ .led_hw_control_set = aqr_phy_led_hw_control_set,
+ .led_hw_control_get = aqr_phy_led_hw_control_get,
+ .led_polarity_set = aqr_phy_led_polarity_set,
},
};
@@ -1020,6 +1073,7 @@ static struct mdio_device_id __maybe_unused aqr_tbl[] = {
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },
+ { PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },
{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },
{ }
};