diff options
-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), |