diff options
| author | David S. Miller <davem@davemloft.net> | 2019-03-20 13:58:17 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-03-20 13:58:17 -0400 |
| commit | 6a23c0a6af98c927f387353a219c1f5664bb3d5b (patch) | |
| tree | 203b4e4e68befe46a1fe99cd3687bb4f4067292f | |
| parent | 5c5f626bcacee0a345b8fd0af81be45eedb9bda9 (diff) | |
| parent | 1e614b5086ee8b2287238f74a9fa6d7935084a3c (diff) | |
Merge branch 'net-phy-aquantia-add-interface-mode-handling'
Heiner Kallweit says:
====================
net: phy: aquantia: add interface mode handling
These two patches add interface mode handling for the AQR107/AQCS109.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/phy/aquantia_main.c | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/drivers/net/phy/aquantia_main.c b/drivers/net/phy/aquantia_main.c index 37218e5d7cc9..034b82d413ee 100644 --- a/drivers/net/phy/aquantia_main.c +++ b/drivers/net/phy/aquantia_main.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/delay.h> | 12 | #include <linux/delay.h> |
| 13 | #include <linux/bitfield.h> | ||
| 13 | #include <linux/phy.h> | 14 | #include <linux/phy.h> |
| 14 | 15 | ||
| 15 | #include "aquantia.h" | 16 | #include "aquantia.h" |
| @@ -22,6 +23,13 @@ | |||
| 22 | #define PHY_ID_AQCS109 0x03a1b5c2 | 23 | #define PHY_ID_AQCS109 0x03a1b5c2 |
| 23 | #define PHY_ID_AQR405 0x03a1b4b0 | 24 | #define PHY_ID_AQR405 0x03a1b4b0 |
| 24 | 25 | ||
| 26 | #define MDIO_PHYXS_VEND_IF_STATUS 0xe812 | ||
| 27 | #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK GENMASK(7, 3) | ||
| 28 | #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR 0 | ||
| 29 | #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI 2 | ||
| 30 | #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII 6 | ||
| 31 | #define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII 10 | ||
| 32 | |||
| 25 | #define MDIO_AN_VEND_PROV 0xc400 | 33 | #define MDIO_AN_VEND_PROV 0xc400 |
| 26 | #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) | 34 | #define MDIO_AN_VEND_PROV_1000BASET_FULL BIT(15) |
| 27 | #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) | 35 | #define MDIO_AN_VEND_PROV_1000BASET_HALF BIT(14) |
| @@ -178,8 +186,58 @@ static int aqr_read_status(struct phy_device *phydev) | |||
| 178 | return genphy_c45_read_status(phydev); | 186 | return genphy_c45_read_status(phydev); |
| 179 | } | 187 | } |
| 180 | 188 | ||
| 189 | static int aqr107_read_status(struct phy_device *phydev) | ||
| 190 | { | ||
| 191 | int val, ret; | ||
| 192 | |||
| 193 | ret = aqr_read_status(phydev); | ||
| 194 | if (ret) | ||
| 195 | return ret; | ||
| 196 | |||
| 197 | if (!phydev->link) | ||
| 198 | return 0; | ||
| 199 | |||
| 200 | val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS); | ||
| 201 | if (val < 0) | ||
| 202 | return val; | ||
| 203 | |||
| 204 | switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) { | ||
| 205 | case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR: | ||
| 206 | case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI: | ||
| 207 | phydev->interface = PHY_INTERFACE_MODE_10GKR; | ||
| 208 | break; | ||
| 209 | case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII: | ||
| 210 | phydev->interface = PHY_INTERFACE_MODE_SGMII; | ||
| 211 | break; | ||
| 212 | case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII: | ||
| 213 | phydev->interface = PHY_INTERFACE_MODE_2500BASEX; | ||
| 214 | break; | ||
| 215 | default: | ||
| 216 | phydev->interface = PHY_INTERFACE_MODE_NA; | ||
| 217 | break; | ||
| 218 | } | ||
| 219 | |||
| 220 | return 0; | ||
| 221 | } | ||
| 222 | |||
| 223 | static int aqr107_config_init(struct phy_device *phydev) | ||
| 224 | { | ||
| 225 | /* Check that the PHY interface type is compatible */ | ||
| 226 | if (phydev->interface != PHY_INTERFACE_MODE_SGMII && | ||
| 227 | phydev->interface != PHY_INTERFACE_MODE_2500BASEX && | ||
| 228 | phydev->interface != PHY_INTERFACE_MODE_10GKR) | ||
| 229 | return -ENODEV; | ||
| 230 | |||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | |||
| 181 | static int aqcs109_config_init(struct phy_device *phydev) | 234 | static int aqcs109_config_init(struct phy_device *phydev) |
| 182 | { | 235 | { |
| 236 | /* Check that the PHY interface type is compatible */ | ||
| 237 | if (phydev->interface != PHY_INTERFACE_MODE_SGMII && | ||
| 238 | phydev->interface != PHY_INTERFACE_MODE_2500BASEX) | ||
| 239 | return -ENODEV; | ||
| 240 | |||
| 183 | /* AQCS109 belongs to a chip family partially supporting 10G and 5G. | 241 | /* AQCS109 belongs to a chip family partially supporting 10G and 5G. |
| 184 | * PMA speed ability bits are the same for all members of the family, | 242 | * PMA speed ability bits are the same for all members of the family, |
| 185 | * AQCS109 however supports speeds up to 2.5G only. | 243 | * AQCS109 however supports speeds up to 2.5G only. |
| @@ -234,10 +292,11 @@ static struct phy_driver aqr_driver[] = { | |||
| 234 | .aneg_done = genphy_c45_aneg_done, | 292 | .aneg_done = genphy_c45_aneg_done, |
| 235 | .get_features = genphy_c45_pma_read_abilities, | 293 | .get_features = genphy_c45_pma_read_abilities, |
| 236 | .probe = aqr_hwmon_probe, | 294 | .probe = aqr_hwmon_probe, |
| 295 | .config_init = aqr107_config_init, | ||
| 237 | .config_aneg = aqr_config_aneg, | 296 | .config_aneg = aqr_config_aneg, |
| 238 | .config_intr = aqr_config_intr, | 297 | .config_intr = aqr_config_intr, |
| 239 | .ack_interrupt = aqr_ack_interrupt, | 298 | .ack_interrupt = aqr_ack_interrupt, |
| 240 | .read_status = aqr_read_status, | 299 | .read_status = aqr107_read_status, |
| 241 | }, | 300 | }, |
| 242 | { | 301 | { |
| 243 | PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), | 302 | PHY_ID_MATCH_MODEL(PHY_ID_AQCS109), |
| @@ -249,7 +308,7 @@ static struct phy_driver aqr_driver[] = { | |||
| 249 | .config_aneg = aqr_config_aneg, | 308 | .config_aneg = aqr_config_aneg, |
| 250 | .config_intr = aqr_config_intr, | 309 | .config_intr = aqr_config_intr, |
| 251 | .ack_interrupt = aqr_ack_interrupt, | 310 | .ack_interrupt = aqr_ack_interrupt, |
| 252 | .read_status = aqr_read_status, | 311 | .read_status = aqr107_read_status, |
| 253 | }, | 312 | }, |
| 254 | { | 313 | { |
| 255 | PHY_ID_MATCH_MODEL(PHY_ID_AQR405), | 314 | PHY_ID_MATCH_MODEL(PHY_ID_AQR405), |
