2 * Marvell 10G 88x3310 PHY driver
4 * Based upon the ID registers, this PHY appears to be a mixture of IPs
5 * from two different companies.
7 * There appears to be several different data paths through the PHY which
8 * are automatically managed by the PHY. The following has been determined
9 * via observation and experimentation for a setup using single-lane Serdes:
11 * SGMII PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for <= 1G)
12 * 10GBASE-KR PHYXS -- BASE-T PCS -- 10G PMA -- AN -- Copper (for 10G)
13 * 10GBASE-KR PHYXS -- BASE-R PCS -- Fiber
15 * With XAUI, observation shows:
17 * XAUI PHYXS -- <appropriate PCS as above>
19 * and no switching of the host interface mode occurs.
21 * If both the fiber and copper ports are connected, the first to gain
22 * link takes priority and the other port is completely locked out.
24 #include <linux/ctype.h>
25 #include <linux/hwmon.h>
26 #include <linux/marvell_phy.h>
27 #include <linux/phy.h>
30 MV_PCS_BASE_T
= 0x0000,
31 MV_PCS_BASE_R
= 0x1000,
32 MV_PCS_1000BASEX
= 0x2000,
34 MV_PCS_PAIRSWAP
= 0x8182,
35 MV_PCS_PAIRSWAP_MASK
= 0x0003,
36 MV_PCS_PAIRSWAP_AB
= 0x0002,
37 MV_PCS_PAIRSWAP_NONE
= 0x0003,
39 /* These registers appear at 0x800X and 0xa00X - the 0xa00X control
40 * registers appear to set themselves to the 0x800X when AN is
41 * restarted, but status registers appear readable from either.
43 MV_AN_CTRL1000
= 0x8000, /* 1000base-T control register */
44 MV_AN_STAT1000
= 0x8001, /* 1000base-T status register */
46 /* Vendor2 MMD registers */
47 MV_V2_TEMP_CTRL
= 0xf08a,
48 MV_V2_TEMP_CTRL_MASK
= 0xc000,
49 MV_V2_TEMP_CTRL_SAMPLE
= 0x0000,
50 MV_V2_TEMP_CTRL_DISABLE
= 0xc000,
52 MV_V2_TEMP_UNKNOWN
= 0x9600, /* unknown function */
56 struct device
*hwmon_dev
;
60 static int mv3310_modify(struct phy_device
*phydev
, int devad
, u16 reg
,
65 old
= phy_read_mmd(phydev
, devad
, reg
);
69 val
= (old
& ~mask
) | (bits
& mask
);
73 ret
= phy_write_mmd(phydev
, devad
, reg
, val
);
75 return ret
< 0 ? ret
: 1;
79 static umode_t
mv3310_hwmon_is_visible(const void *data
,
80 enum hwmon_sensor_types type
,
81 u32 attr
, int channel
)
83 if (type
== hwmon_chip
&& attr
== hwmon_chip_update_interval
)
85 if (type
== hwmon_temp
&& attr
== hwmon_temp_input
)
90 static int mv3310_hwmon_read(struct device
*dev
, enum hwmon_sensor_types type
,
91 u32 attr
, int channel
, long *value
)
93 struct phy_device
*phydev
= dev_get_drvdata(dev
);
96 if (type
== hwmon_chip
&& attr
== hwmon_chip_update_interval
) {
97 *value
= MSEC_PER_SEC
;
101 if (type
== hwmon_temp
&& attr
== hwmon_temp_input
) {
102 temp
= phy_read_mmd(phydev
, MDIO_MMD_VEND2
, MV_V2_TEMP
);
106 *value
= ((temp
& 0xff) - 75) * 1000;
114 static const struct hwmon_ops mv3310_hwmon_ops
= {
115 .is_visible
= mv3310_hwmon_is_visible
,
116 .read
= mv3310_hwmon_read
,
119 static u32 mv3310_hwmon_chip_config
[] = {
120 HWMON_C_REGISTER_TZ
| HWMON_C_UPDATE_INTERVAL
,
124 static const struct hwmon_channel_info mv3310_hwmon_chip
= {
126 .config
= mv3310_hwmon_chip_config
,
129 static u32 mv3310_hwmon_temp_config
[] = {
134 static const struct hwmon_channel_info mv3310_hwmon_temp
= {
136 .config
= mv3310_hwmon_temp_config
,
139 static const struct hwmon_channel_info
*mv3310_hwmon_info
[] = {
145 static const struct hwmon_chip_info mv3310_hwmon_chip_info
= {
146 .ops
= &mv3310_hwmon_ops
,
147 .info
= mv3310_hwmon_info
,
150 static int mv3310_hwmon_config(struct phy_device
*phydev
, bool enable
)
155 ret
= phy_write_mmd(phydev
, MDIO_MMD_VEND2
, MV_V2_TEMP
,
160 val
= enable
? MV_V2_TEMP_CTRL_SAMPLE
: MV_V2_TEMP_CTRL_DISABLE
;
161 ret
= mv3310_modify(phydev
, MDIO_MMD_VEND2
, MV_V2_TEMP_CTRL
,
162 MV_V2_TEMP_CTRL_MASK
, val
);
164 return ret
< 0 ? ret
: 0;
167 static void mv3310_hwmon_disable(void *data
)
169 struct phy_device
*phydev
= data
;
171 mv3310_hwmon_config(phydev
, false);
174 static int mv3310_hwmon_probe(struct phy_device
*phydev
)
176 struct device
*dev
= &phydev
->mdio
.dev
;
177 struct mv3310_priv
*priv
= dev_get_drvdata(&phydev
->mdio
.dev
);
180 priv
->hwmon_name
= devm_kstrdup(dev
, dev_name(dev
), GFP_KERNEL
);
181 if (!priv
->hwmon_name
)
184 for (i
= j
= 0; priv
->hwmon_name
[i
]; i
++) {
185 if (isalnum(priv
->hwmon_name
[i
])) {
187 priv
->hwmon_name
[j
] = priv
->hwmon_name
[i
];
191 priv
->hwmon_name
[j
] = '\0';
193 ret
= mv3310_hwmon_config(phydev
, true);
197 ret
= devm_add_action_or_reset(dev
, mv3310_hwmon_disable
, phydev
);
201 priv
->hwmon_dev
= devm_hwmon_device_register_with_info(dev
,
202 priv
->hwmon_name
, phydev
,
203 &mv3310_hwmon_chip_info
, NULL
);
205 return PTR_ERR_OR_ZERO(priv
->hwmon_dev
);
208 static inline int mv3310_hwmon_config(struct phy_device
*phydev
, bool enable
)
213 static int mv3310_hwmon_probe(struct phy_device
*phydev
)
219 static int mv3310_probe(struct phy_device
*phydev
)
221 struct mv3310_priv
*priv
;
222 u32 mmd_mask
= MDIO_DEVS_PMAPMD
| MDIO_DEVS_AN
;
225 if (!phydev
->is_c45
||
226 (phydev
->c45_ids
.devices_in_package
& mmd_mask
) != mmd_mask
)
229 priv
= devm_kzalloc(&phydev
->mdio
.dev
, sizeof(*priv
), GFP_KERNEL
);
233 dev_set_drvdata(&phydev
->mdio
.dev
, priv
);
235 ret
= mv3310_hwmon_probe(phydev
);
242 static int mv3310_suspend(struct phy_device
*phydev
)
247 static int mv3310_resume(struct phy_device
*phydev
)
249 return mv3310_hwmon_config(phydev
, true);
252 static int mv3310_config_init(struct phy_device
*phydev
)
254 __ETHTOOL_DECLARE_LINK_MODE_MASK(supported
) = { 0, };
258 /* Check that the PHY interface type is compatible */
259 if (phydev
->interface
!= PHY_INTERFACE_MODE_SGMII
&&
260 phydev
->interface
!= PHY_INTERFACE_MODE_XAUI
&&
261 phydev
->interface
!= PHY_INTERFACE_MODE_RXAUI
&&
262 phydev
->interface
!= PHY_INTERFACE_MODE_10GKR
)
265 __set_bit(ETHTOOL_LINK_MODE_Pause_BIT
, supported
);
266 __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT
, supported
);
268 if (phydev
->c45_ids
.devices_in_package
& MDIO_DEVS_AN
) {
269 val
= phy_read_mmd(phydev
, MDIO_MMD_AN
, MDIO_STAT1
);
273 if (val
& MDIO_AN_STAT1_ABLE
)
274 __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT
, supported
);
277 val
= phy_read_mmd(phydev
, MDIO_MMD_PMAPMD
, MDIO_STAT2
);
281 /* Ethtool does not support the WAN mode bits */
282 if (val
& (MDIO_PMA_STAT2_10GBSR
| MDIO_PMA_STAT2_10GBLR
|
283 MDIO_PMA_STAT2_10GBER
| MDIO_PMA_STAT2_10GBLX4
|
284 MDIO_PMA_STAT2_10GBSW
| MDIO_PMA_STAT2_10GBLW
|
285 MDIO_PMA_STAT2_10GBEW
))
286 __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
, supported
);
287 if (val
& MDIO_PMA_STAT2_10GBSR
)
288 __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT
, supported
);
289 if (val
& MDIO_PMA_STAT2_10GBLR
)
290 __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT
, supported
);
291 if (val
& MDIO_PMA_STAT2_10GBER
)
292 __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT
, supported
);
294 if (val
& MDIO_PMA_STAT2_EXTABLE
) {
295 val
= phy_read_mmd(phydev
, MDIO_MMD_PMAPMD
, MDIO_PMA_EXTABLE
);
299 if (val
& (MDIO_PMA_EXTABLE_10GBT
| MDIO_PMA_EXTABLE_1000BT
|
300 MDIO_PMA_EXTABLE_100BTX
| MDIO_PMA_EXTABLE_10BT
))
301 __set_bit(ETHTOOL_LINK_MODE_TP_BIT
, supported
);
302 if (val
& MDIO_PMA_EXTABLE_10GBLRM
)
303 __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT
, supported
);
304 if (val
& (MDIO_PMA_EXTABLE_10GBKX4
| MDIO_PMA_EXTABLE_10GBKR
|
305 MDIO_PMA_EXTABLE_1000BKX
))
306 __set_bit(ETHTOOL_LINK_MODE_Backplane_BIT
, supported
);
307 if (val
& MDIO_PMA_EXTABLE_10GBLRM
)
308 __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT
,
310 if (val
& MDIO_PMA_EXTABLE_10GBT
)
311 __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT
,
313 if (val
& MDIO_PMA_EXTABLE_10GBKX4
)
314 __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT
,
316 if (val
& MDIO_PMA_EXTABLE_10GBKR
)
317 __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT
,
319 if (val
& MDIO_PMA_EXTABLE_1000BT
)
320 __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT
,
322 if (val
& MDIO_PMA_EXTABLE_1000BKX
)
323 __set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT
,
325 if (val
& MDIO_PMA_EXTABLE_100BTX
) {
326 __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT
,
328 __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT
,
331 if (val
& MDIO_PMA_EXTABLE_10BT
) {
332 __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT
,
334 __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT
,
339 if (!ethtool_convert_link_mode_to_legacy_u32(&mask
, supported
))
341 "PHY supports (%*pb) more modes than phylib supports, some modes not supported.\n",
342 __ETHTOOL_LINK_MODE_MASK_NBITS
, supported
);
344 phydev
->supported
&= mask
;
345 phydev
->advertising
&= phydev
->supported
;
350 static int mv3310_config_aneg(struct phy_device
*phydev
)
352 bool changed
= false;
356 /* We don't support manual MDI control */
357 phydev
->mdix_ctrl
= ETH_TP_MDI_AUTO
;
359 if (phydev
->autoneg
== AUTONEG_DISABLE
) {
360 ret
= genphy_c45_pma_setup_forced(phydev
);
364 return genphy_c45_an_disable_aneg(phydev
);
367 phydev
->advertising
&= phydev
->supported
;
368 advertising
= phydev
->advertising
;
370 ret
= mv3310_modify(phydev
, MDIO_MMD_AN
, MDIO_AN_ADVERTISE
,
371 ADVERTISE_ALL
| ADVERTISE_100BASE4
|
372 ADVERTISE_PAUSE_CAP
| ADVERTISE_PAUSE_ASYM
,
373 ethtool_adv_to_mii_adv_t(advertising
));
379 ret
= mv3310_modify(phydev
, MDIO_MMD_AN
, MV_AN_CTRL1000
,
380 ADVERTISE_1000FULL
| ADVERTISE_1000HALF
,
381 ethtool_adv_to_mii_ctrl1000_t(advertising
));
387 /* 10G control register */
388 ret
= mv3310_modify(phydev
, MDIO_MMD_AN
, MDIO_AN_10GBT_CTRL
,
389 MDIO_AN_10GBT_CTRL_ADV10G
,
390 advertising
& ADVERTISED_10000baseT_Full
?
391 MDIO_AN_10GBT_CTRL_ADV10G
: 0);
398 ret
= genphy_c45_restart_aneg(phydev
);
403 static int mv3310_aneg_done(struct phy_device
*phydev
)
407 val
= phy_read_mmd(phydev
, MDIO_MMD_PCS
, MV_PCS_BASE_R
+ MDIO_STAT1
);
411 if (val
& MDIO_STAT1_LSTATUS
)
414 return genphy_c45_aneg_done(phydev
);
417 static void mv3310_update_interface(struct phy_device
*phydev
)
419 if ((phydev
->interface
== PHY_INTERFACE_MODE_SGMII
||
420 phydev
->interface
== PHY_INTERFACE_MODE_10GKR
) && phydev
->link
) {
421 /* The PHY automatically switches its serdes interface (and
422 * active PHYXS instance) between Cisco SGMII and 10GBase-KR
423 * modes according to the speed. Florian suggests setting
424 * phydev->interface to communicate this to the MAC. Only do
425 * this if we are already in either SGMII or 10GBase-KR mode.
427 if (phydev
->speed
== SPEED_10000
)
428 phydev
->interface
= PHY_INTERFACE_MODE_10GKR
;
429 else if (phydev
->speed
>= SPEED_10
&&
430 phydev
->speed
< SPEED_10000
)
431 phydev
->interface
= PHY_INTERFACE_MODE_SGMII
;
435 /* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */
436 static int mv3310_read_10gbr_status(struct phy_device
*phydev
)
439 phydev
->speed
= SPEED_10000
;
440 phydev
->duplex
= DUPLEX_FULL
;
442 mv3310_update_interface(phydev
);
447 static int mv3310_read_status(struct phy_device
*phydev
)
449 u32 mmd_mask
= phydev
->c45_ids
.devices_in_package
;
452 /* The vendor devads do not report link status. Avoid the PHYXS
453 * instance as there are three, and its status depends on the MAC
454 * being appropriately configured for the negotiated speed.
456 mmd_mask
&= ~(BIT(MDIO_MMD_VEND1
) | BIT(MDIO_MMD_VEND2
) |
457 BIT(MDIO_MMD_PHYXS
));
459 phydev
->speed
= SPEED_UNKNOWN
;
460 phydev
->duplex
= DUPLEX_UNKNOWN
;
461 phydev
->lp_advertising
= 0;
464 phydev
->asym_pause
= 0;
467 val
= phy_read_mmd(phydev
, MDIO_MMD_PCS
, MV_PCS_BASE_R
+ MDIO_STAT1
);
471 if (val
& MDIO_STAT1_LSTATUS
)
472 return mv3310_read_10gbr_status(phydev
);
474 val
= genphy_c45_read_link(phydev
, mmd_mask
);
478 phydev
->link
= val
> 0 ? 1 : 0;
480 val
= phy_read_mmd(phydev
, MDIO_MMD_AN
, MDIO_STAT1
);
484 if (val
& MDIO_AN_STAT1_COMPLETE
) {
485 val
= genphy_c45_read_lpa(phydev
);
489 /* Read the link partner's 1G advertisement */
490 val
= phy_read_mmd(phydev
, MDIO_MMD_AN
, MV_AN_STAT1000
);
494 phydev
->lp_advertising
|= mii_stat1000_to_ethtool_lpa_t(val
);
496 if (phydev
->autoneg
== AUTONEG_ENABLE
)
497 phy_resolve_aneg_linkmode(phydev
);
500 if (phydev
->autoneg
!= AUTONEG_ENABLE
) {
501 val
= genphy_c45_read_pma(phydev
);
506 if (phydev
->speed
== SPEED_10000
) {
507 val
= genphy_c45_read_mdix(phydev
);
511 val
= phy_read_mmd(phydev
, MDIO_MMD_PCS
, MV_PCS_PAIRSWAP
);
515 switch (val
& MV_PCS_PAIRSWAP_MASK
) {
516 case MV_PCS_PAIRSWAP_AB
:
517 phydev
->mdix
= ETH_TP_MDI_X
;
519 case MV_PCS_PAIRSWAP_NONE
:
520 phydev
->mdix
= ETH_TP_MDI
;
523 phydev
->mdix
= ETH_TP_MDI_INVALID
;
528 mv3310_update_interface(phydev
);
533 static struct phy_driver mv3310_drivers
[] = {
535 .phy_id
= 0x002b09aa,
536 .phy_id_mask
= MARVELL_PHY_ID_MASK
,
538 .features
= PHY_10GBIT_FEATURES
,
539 .soft_reset
= gen10g_no_soft_reset
,
540 .config_init
= mv3310_config_init
,
541 .probe
= mv3310_probe
,
542 .suspend
= mv3310_suspend
,
543 .resume
= mv3310_resume
,
544 .config_aneg
= mv3310_config_aneg
,
545 .aneg_done
= mv3310_aneg_done
,
546 .read_status
= mv3310_read_status
,
550 module_phy_driver(mv3310_drivers
);
552 static struct mdio_device_id __maybe_unused mv3310_tbl
[] = {
553 { 0x002b09aa, MARVELL_PHY_ID_MASK
},
556 MODULE_DEVICE_TABLE(mdio
, mv3310_tbl
);
557 MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)");
558 MODULE_LICENSE("GPL");