marvell10g.c (8d8963c3db6c3895eadf028d8c782cf18c1b3ff2) marvell10g.c (a585c03e63fd3537cdf94e52485699617424453c)
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Marvell 10G 88x3310 PHY driver
4 *
5 * Based upon the ID registers, this PHY appears to be a mixture of IPs
6 * from two different companies.
7 *
8 * There appears to be several different data paths through the PHY which

--- 27 unchanged lines hidden (view full) ---

36 MV_PMA_BOOT = 0xc050,
37 MV_PMA_BOOT_FATAL = BIT(0),
38
39 MV_PCS_BASE_T = 0x0000,
40 MV_PCS_BASE_R = 0x1000,
41 MV_PCS_1000BASEX = 0x2000,
42
43 MV_PCS_CSCR1 = 0x8000,
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Marvell 10G 88x3310 PHY driver
4 *
5 * Based upon the ID registers, this PHY appears to be a mixture of IPs
6 * from two different companies.
7 *
8 * There appears to be several different data paths through the PHY which

--- 27 unchanged lines hidden (view full) ---

36 MV_PMA_BOOT = 0xc050,
37 MV_PMA_BOOT_FATAL = BIT(0),
38
39 MV_PCS_BASE_T = 0x0000,
40 MV_PCS_BASE_R = 0x1000,
41 MV_PCS_1000BASEX = 0x2000,
42
43 MV_PCS_CSCR1 = 0x8000,
44 MV_PCS_CSCR1_ED_MASK = 0x0300,
45 MV_PCS_CSCR1_ED_OFF = 0x0000,
46 MV_PCS_CSCR1_ED_RX = 0x0200,
47 MV_PCS_CSCR1_ED_NLP = 0x0300,
44 MV_PCS_CSCR1_MDIX_MASK = 0x0060,
45 MV_PCS_CSCR1_MDIX_MDI = 0x0000,
46 MV_PCS_CSCR1_MDIX_MDIX = 0x0020,
47 MV_PCS_CSCR1_MDIX_AUTO = 0x0060,
48
49 MV_PCS_CSSR1 = 0x8008,
50 MV_PCS_CSSR1_SPD1_MASK = 0xc000,
51 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000,

--- 186 unchanged lines hidden (view full) ---

238 val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1);
239 if (val < 0)
240 return val;
241 } while (val & MDIO_CTRL1_RESET && --retries);
242
243 return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0;
244}
245
48 MV_PCS_CSCR1_MDIX_MASK = 0x0060,
49 MV_PCS_CSCR1_MDIX_MDI = 0x0000,
50 MV_PCS_CSCR1_MDIX_MDIX = 0x0020,
51 MV_PCS_CSCR1_MDIX_AUTO = 0x0060,
52
53 MV_PCS_CSSR1 = 0x8008,
54 MV_PCS_CSSR1_SPD1_MASK = 0xc000,
55 MV_PCS_CSSR1_SPD1_SPD2 = 0xc000,

--- 186 unchanged lines hidden (view full) ---

242 val = phy_read_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1);
243 if (val < 0)
244 return val;
245 } while (val & MDIO_CTRL1_RESET && --retries);
246
247 return val & MDIO_CTRL1_RESET ? -ETIMEDOUT : 0;
248}
249
250static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
251{
252 int val;
253
254 val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1);
255 if (val < 0)
256 return val;
257
258 switch (val & MV_PCS_CSCR1_ED_MASK) {
259 case MV_PCS_CSCR1_ED_NLP:
260 *edpd = 1000;
261 break;
262 case MV_PCS_CSCR1_ED_RX:
263 *edpd = ETHTOOL_PHY_EDPD_NO_TX;
264 break;
265 default:
266 *edpd = ETHTOOL_PHY_EDPD_DISABLE;
267 break;
268 }
269 return 0;
270}
271
272static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd)
273{
274 u16 val;
275 int err;
276
277 switch (edpd) {
278 case 1000:
279 case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
280 val = MV_PCS_CSCR1_ED_NLP;
281 break;
282
283 case ETHTOOL_PHY_EDPD_NO_TX:
284 val = MV_PCS_CSCR1_ED_RX;
285 break;
286
287 case ETHTOOL_PHY_EDPD_DISABLE:
288 val = MV_PCS_CSCR1_ED_OFF;
289 break;
290
291 default:
292 return -EINVAL;
293 }
294
295 err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
296 MV_PCS_CSCR1_ED_MASK, val);
297 if (err > 0)
298 err = mv3310_reset(phydev, MV_PCS_BASE_T);
299
300 return err;
301}
302
246static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
247{
248 struct phy_device *phydev = upstream;
249 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
250 phy_interface_t iface;
251
252 sfp_parse_support(phydev->sfp_bus, id, support);
253 iface = sfp_select_interface(phydev->sfp_bus, support);

--- 86 unchanged lines hidden (view full) ---

340 phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
341 phydev->interface != PHY_INTERFACE_MODE_XAUI &&
342 phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
343 phydev->interface != PHY_INTERFACE_MODE_10GBASER)
344 return -ENODEV;
345
346 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
347
303static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
304{
305 struct phy_device *phydev = upstream;
306 __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
307 phy_interface_t iface;
308
309 sfp_parse_support(phydev->sfp_bus, id, support);
310 iface = sfp_select_interface(phydev->sfp_bus, support);

--- 86 unchanged lines hidden (view full) ---

397 phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
398 phydev->interface != PHY_INTERFACE_MODE_XAUI &&
399 phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
400 phydev->interface != PHY_INTERFACE_MODE_10GBASER)
401 return -ENODEV;
402
403 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
404
348 return 0;
405 /* Enable EDPD mode - saving 600mW */
406 return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
349}
350
351static int mv3310_get_features(struct phy_device *phydev)
352{
353 int ret, val;
354
355 ret = genphy_c45_pma_read_abilities(phydev);
356 if (ret)

--- 232 unchanged lines hidden (view full) ---

589 return err;
590
591 if (phydev->link)
592 mv3310_update_interface(phydev);
593
594 return 0;
595}
596
407}
408
409static int mv3310_get_features(struct phy_device *phydev)
410{
411 int ret, val;
412
413 ret = genphy_c45_pma_read_abilities(phydev);
414 if (ret)

--- 232 unchanged lines hidden (view full) ---

647 return err;
648
649 if (phydev->link)
650 mv3310_update_interface(phydev);
651
652 return 0;
653}
654
655static int mv3310_get_tunable(struct phy_device *phydev,
656 struct ethtool_tunable *tuna, void *data)
657{
658 switch (tuna->id) {
659 case ETHTOOL_PHY_EDPD:
660 return mv3310_get_edpd(phydev, data);
661 default:
662 return -EOPNOTSUPP;
663 }
664}
665
666static int mv3310_set_tunable(struct phy_device *phydev,
667 struct ethtool_tunable *tuna, const void *data)
668{
669 switch (tuna->id) {
670 case ETHTOOL_PHY_EDPD:
671 return mv3310_set_edpd(phydev, *(u16 *)data);
672 default:
673 return -EOPNOTSUPP;
674 }
675}
676
597static struct phy_driver mv3310_drivers[] = {
598 {
599 .phy_id = MARVELL_PHY_ID_88X3310,
600 .phy_id_mask = MARVELL_PHY_ID_MASK,
601 .name = "mv88x3310",
602 .get_features = mv3310_get_features,
603 .soft_reset = genphy_no_soft_reset,
604 .config_init = mv3310_config_init,
605 .probe = mv3310_probe,
606 .suspend = mv3310_suspend,
607 .resume = mv3310_resume,
608 .config_aneg = mv3310_config_aneg,
609 .aneg_done = mv3310_aneg_done,
610 .read_status = mv3310_read_status,
677static struct phy_driver mv3310_drivers[] = {
678 {
679 .phy_id = MARVELL_PHY_ID_88X3310,
680 .phy_id_mask = MARVELL_PHY_ID_MASK,
681 .name = "mv88x3310",
682 .get_features = mv3310_get_features,
683 .soft_reset = genphy_no_soft_reset,
684 .config_init = mv3310_config_init,
685 .probe = mv3310_probe,
686 .suspend = mv3310_suspend,
687 .resume = mv3310_resume,
688 .config_aneg = mv3310_config_aneg,
689 .aneg_done = mv3310_aneg_done,
690 .read_status = mv3310_read_status,
691 .get_tunable = mv3310_get_tunable,
692 .set_tunable = mv3310_set_tunable,
611 },
612 {
613 .phy_id = MARVELL_PHY_ID_88E2110,
614 .phy_id_mask = MARVELL_PHY_ID_MASK,
615 .name = "mv88x2110",
616 .probe = mv3310_probe,
617 .suspend = mv3310_suspend,
618 .resume = mv3310_resume,
619 .soft_reset = genphy_no_soft_reset,
620 .config_init = mv3310_config_init,
621 .config_aneg = mv3310_config_aneg,
622 .aneg_done = mv3310_aneg_done,
623 .read_status = mv3310_read_status,
693 },
694 {
695 .phy_id = MARVELL_PHY_ID_88E2110,
696 .phy_id_mask = MARVELL_PHY_ID_MASK,
697 .name = "mv88x2110",
698 .probe = mv3310_probe,
699 .suspend = mv3310_suspend,
700 .resume = mv3310_resume,
701 .soft_reset = genphy_no_soft_reset,
702 .config_init = mv3310_config_init,
703 .config_aneg = mv3310_config_aneg,
704 .aneg_done = mv3310_aneg_done,
705 .read_status = mv3310_read_status,
706 .get_tunable = mv3310_get_tunable,
707 .set_tunable = mv3310_set_tunable,
624 },
625};
626
627module_phy_driver(mv3310_drivers);
628
629static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
630 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
631 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
632 { },
633};
634MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
635MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)");
636MODULE_LICENSE("GPL");
708 },
709};
710
711module_phy_driver(mv3310_drivers);
712
713static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
714 { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
715 { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
716 { },
717};
718MODULE_DEVICE_TABLE(mdio, mv3310_tbl);
719MODULE_DESCRIPTION("Marvell Alaska X 10Gigabit Ethernet PHY driver (MV88X3310)");
720MODULE_LICENSE("GPL");