aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/phy/aquantia_main.c63
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
189static 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
223static 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
181static int aqcs109_config_init(struct phy_device *phydev) 234static 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),