Lines Matching +full:ethernet +full:- +full:phy +full:- +full:package

1 // SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
3 * Copyright (c) 2014-2025, Advanced Micro Devices, Inc.
12 #include <linux/phy.h>
18 #include "xgbe-common.h"
23 if (!pdata->phy_if.phy_impl.module_eeprom)
24 return -ENXIO;
26 return pdata->phy_if.phy_impl.module_eeprom(pdata, eeprom, data);
32 if (!pdata->phy_if.phy_impl.module_info)
33 return -ENXIO;
35 return pdata->phy_if.phy_impl.module_info(pdata, modinfo);
90 switch (pdata->an_mode) {
113 pdata->hw_if.set_speed(pdata, SPEED_10000);
115 /* Call PHY implementation support to complete rate change */
116 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KR);
122 pdata->hw_if.set_speed(pdata, SPEED_2500);
124 /* Call PHY implementation support to complete rate change */
125 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_2500);
131 pdata->hw_if.set_speed(pdata, SPEED_1000);
133 /* Call PHY implementation support to complete rate change */
134 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_KX_1000);
139 /* If a KR re-driver is present, change to KR mode instead */
140 if (pdata->kr_redrv)
144 pdata->hw_if.set_speed(pdata, SPEED_10000);
146 /* Call PHY implementation support to complete rate change */
147 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SFI);
153 pdata->hw_if.set_speed(pdata, SPEED_1000);
155 /* Call PHY implementation support to complete rate change */
156 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_X);
162 pdata->hw_if.set_speed(pdata, SPEED_1000);
164 /* Call PHY implementation support to complete rate change */
165 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_1000);
171 pdata->hw_if.set_speed(pdata, SPEED_10);
173 /* Call PHY implementation support to complete rate change */
174 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_10);
180 pdata->hw_if.set_speed(pdata, SPEED_1000);
182 /* Call PHY implementation support to complete rate change */
183 pdata->phy_if.phy_impl.set_mode(pdata, XGBE_MODE_SGMII_100);
188 return pdata->phy_if.phy_impl.cur_mode(pdata);
227 netif_dbg(pdata, link, pdata->netdev,
234 xgbe_change_mode(pdata, pdata->phy_if.phy_impl.switch_mode(pdata));
251 return pdata->phy_if.phy_impl.use_mode(pdata, mode);
280 netif_dbg(pdata, link, pdata->netdev, "CL37 AN enabled/restarted\n");
288 netif_dbg(pdata, link, pdata->netdev, "CL37 AN disabled\n");
319 netif_dbg(pdata, link, pdata->netdev, "CL73 AN enabled/restarted\n");
327 pdata->an_start = 0;
329 netif_dbg(pdata, link, pdata->netdev, "CL73 AN disabled\n");
334 if (pdata->phy_if.phy_impl.an_pre)
335 pdata->phy_if.phy_impl.an_pre(pdata);
337 switch (pdata->an_mode) {
353 if (pdata->phy_if.phy_impl.an_post)
354 pdata->phy_if.phy_impl.an_post(pdata);
356 switch (pdata->an_mode) {
394 reg |= pdata->fec_ability;
399 if (pdata->phy_if.phy_impl.kr_training_pre)
400 pdata->phy_if.phy_impl.kr_training_pre(pdata);
406 pdata->kr_start_time = jiffies;
408 netif_dbg(pdata, link, pdata->netdev,
411 if (pdata->phy_if.phy_impl.kr_training_post)
412 pdata->phy_if.phy_impl.kr_training_post(pdata);
479 if (!pdata->an_start) {
480 pdata->an_start = jiffies;
482 an_timeout = pdata->an_start +
485 /* Auto-negotiation timed out, reset state */
486 pdata->kr_state = XGBE_RX_BPA;
487 pdata->kx_state = XGBE_RX_BPA;
489 pdata->an_start = jiffies;
491 netif_dbg(pdata, link, pdata->netdev,
496 state = xgbe_in_kr_mode(pdata) ? &pdata->kr_state
497 : &pdata->kx_state;
517 struct ethtool_link_ksettings *lks = &pdata->phy.lks;
521 pdata->kr_state = XGBE_RX_ERROR;
527 if (pdata->kx_state != XGBE_RX_BPA)
530 pdata->kx_state = XGBE_RX_ERROR;
535 if (pdata->kr_state != XGBE_RX_BPA)
543 pdata->an_result = XGBE_AN_READY;
559 pdata->an_int = reg & XGBE_AN_CL37_INT_MASK;
560 pdata->an_status = reg & ~XGBE_AN_CL37_INT_MASK;
562 if (pdata->an_int) {
567 queue_work(pdata->an_workqueue, &pdata->an_irq_work);
573 if (pdata->vdata->irq_reissue_support)
584 pdata->an_int = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_AN_INT);
586 if (pdata->an_int) {
588 XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_AN_INT, ~pdata->an_int);
590 queue_work(pdata->an_workqueue, &pdata->an_irq_work);
596 if (pdata->vdata->irq_reissue_support)
605 netif_dbg(pdata, intr, pdata->netdev, "AN interrupt received\n");
607 switch (pdata->an_mode) {
625 if (pdata->isr_as_bh_work)
626 queue_work(system_bh_wq, &pdata->an_bh_work);
628 xgbe_an_isr_bh_work(&pdata->an_bh_work);
635 xgbe_an_isr_bh_work(&pdata->an_bh_work);
649 flush_work(&pdata->an_work);
650 queue_work(pdata->an_workqueue, &pdata->an_work);
659 return "Page-Received";
661 return "Incompatible-Link";
665 return "No-Link";
675 enum xgbe_an cur_state = pdata->an_state;
677 if (!pdata->an_int)
680 if (pdata->an_int & XGBE_AN_CL37_INT_CMPLT) {
681 pdata->an_state = XGBE_AN_COMPLETE;
682 pdata->an_int &= ~XGBE_AN_CL37_INT_CMPLT;
685 if ((pdata->an_mode == XGBE_AN_MODE_CL37_SGMII) &&
686 !(pdata->an_status & XGBE_SGMII_AN_LINK_STATUS))
687 pdata->an_state = XGBE_AN_NO_LINK;
690 netif_dbg(pdata, link, pdata->netdev, "CL37 AN %s\n",
691 xgbe_state_as_string(pdata->an_state));
693 cur_state = pdata->an_state;
695 switch (pdata->an_state) {
700 netif_dbg(pdata, link, pdata->netdev,
708 pdata->an_state = XGBE_AN_ERROR;
711 if (pdata->an_state == XGBE_AN_ERROR) {
712 netdev_err(pdata->netdev,
713 "error during auto-negotiation, state=%u\n",
716 pdata->an_int = 0;
720 if (pdata->an_state >= XGBE_AN_COMPLETE) {
721 pdata->an_result = pdata->an_state;
722 pdata->an_state = XGBE_AN_READY;
724 if (pdata->phy_if.phy_impl.an_post)
725 pdata->phy_if.phy_impl.an_post(pdata);
727 netif_dbg(pdata, link, pdata->netdev, "CL37 AN result: %s\n",
728 xgbe_state_as_string(pdata->an_result));
736 enum xgbe_an cur_state = pdata->an_state;
738 if (!pdata->an_int)
742 if (pdata->an_int & XGBE_AN_CL73_PG_RCV) {
743 pdata->an_state = XGBE_AN_PAGE_RECEIVED;
744 pdata->an_int &= ~XGBE_AN_CL73_PG_RCV;
745 } else if (pdata->an_int & XGBE_AN_CL73_INC_LINK) {
746 pdata->an_state = XGBE_AN_INCOMPAT_LINK;
747 pdata->an_int &= ~XGBE_AN_CL73_INC_LINK;
748 } else if (pdata->an_int & XGBE_AN_CL73_INT_CMPLT) {
749 pdata->an_state = XGBE_AN_COMPLETE;
750 pdata->an_int &= ~XGBE_AN_CL73_INT_CMPLT;
752 pdata->an_state = XGBE_AN_ERROR;
756 netif_dbg(pdata, link, pdata->netdev, "CL73 AN %s\n",
757 xgbe_state_as_string(pdata->an_state));
759 cur_state = pdata->an_state;
761 switch (pdata->an_state) {
763 pdata->an_supported = 0;
767 pdata->an_state = xgbe_an73_page_received(pdata);
768 pdata->an_supported++;
772 pdata->an_supported = 0;
773 pdata->parallel_detect = 0;
774 pdata->an_state = xgbe_an73_incompat_link(pdata);
778 pdata->parallel_detect = pdata->an_supported ? 0 : 1;
779 netif_dbg(pdata, link, pdata->netdev, "%s successful\n",
780 pdata->an_supported ? "Auto negotiation"
788 pdata->an_state = XGBE_AN_ERROR;
791 if (pdata->an_state == XGBE_AN_NO_LINK) {
792 pdata->an_int = 0;
794 } else if (pdata->an_state == XGBE_AN_ERROR) {
795 netdev_err(pdata->netdev,
796 "error during auto-negotiation, state=%u\n",
799 pdata->an_int = 0;
803 if (pdata->an_state >= XGBE_AN_COMPLETE) {
804 pdata->an_result = pdata->an_state;
805 pdata->an_state = XGBE_AN_READY;
806 pdata->kr_state = XGBE_RX_BPA;
807 pdata->kx_state = XGBE_RX_BPA;
808 pdata->an_start = 0;
810 if (pdata->phy_if.phy_impl.an_post)
811 pdata->phy_if.phy_impl.an_post(pdata);
813 netif_dbg(pdata, link, pdata->netdev, "CL73 AN result: %s\n",
814 xgbe_state_as_string(pdata->an_result));
817 if (cur_state != pdata->an_state)
820 if (pdata->an_int)
832 mutex_lock(&pdata->an_mutex);
834 switch (pdata->an_mode) {
848 if (pdata->vdata->irq_reissue_support)
851 mutex_unlock(&pdata->an_mutex);
859 pdata->phy_if.phy_impl.an_advertising(pdata, &lks);
884 switch (pdata->an_mode) {
899 netif_dbg(pdata, link, pdata->netdev, "CL37 AN (%s) initialized\n",
900 (pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");
913 pdata->phy_if.phy_impl.an_advertising(pdata, &lks);
956 netif_dbg(pdata, link, pdata->netdev, "CL73 AN initialized\n");
962 pdata->an_mode = pdata->phy_if.phy_impl.an_mode(pdata);
963 switch (pdata->an_mode) {
979 if (pdata->tx_pause && pdata->rx_pause)
981 else if (pdata->rx_pause)
983 else if (pdata->tx_pause)
1011 if (pdata->phy.link)
1012 netdev_info(pdata->netdev,
1013 "Link is Up - %s/%s - flow control %s\n",
1014 xgbe_phy_speed_string(pdata->phy.speed),
1015 pdata->phy.duplex == DUPLEX_FULL ? "Full" : "Half",
1018 netdev_info(pdata->netdev, "Link is Down\n");
1025 if (pdata->phy.link) {
1027 pdata->pause_autoneg = pdata->phy.pause_autoneg;
1029 if (pdata->tx_pause != pdata->phy.tx_pause) {
1031 pdata->tx_pause = pdata->phy.tx_pause;
1032 pdata->hw_if.config_tx_flow_control(pdata);
1035 if (pdata->rx_pause != pdata->phy.rx_pause) {
1037 pdata->rx_pause = pdata->phy.rx_pause;
1038 pdata->hw_if.config_rx_flow_control(pdata);
1042 if (pdata->phy_speed != pdata->phy.speed) {
1044 pdata->phy_speed = pdata->phy.speed;
1047 if (pdata->phy_link != pdata->phy.link) {
1049 pdata->phy_link = pdata->phy.link;
1051 } else if (pdata->phy_link) {
1053 pdata->phy_link = 0;
1054 pdata->phy_speed = SPEED_UNKNOWN;
1063 return pdata->phy_if.phy_impl.valid_speed(pdata, speed);
1070 netif_dbg(pdata, link, pdata->netdev, "fixed PHY configuration\n");
1072 /* Disable auto-negotiation */
1076 mode = pdata->phy_if.phy_impl.get_mode(pdata, pdata->phy.speed);
1089 return -EINVAL;
1093 if (pdata->phy.duplex != DUPLEX_FULL)
1094 return -EINVAL;
1096 /* Force the mode change for SFI in Fixed PHY config.
1097 * Fixed PHY configs needs PLL to be enabled while doing mode set.
1100 * SFP comes up in Fixed PHY config, the link will not come up as
1102 * So, force the mode change for SFI in Fixed PHY configuration to
1117 mutex_lock(&pdata->an_mutex);
1119 set_bit(XGBE_LINK_INIT, &pdata->dev_state);
1120 pdata->link_check = jiffies;
1122 ret = pdata->phy_if.phy_impl.an_config(pdata);
1126 if (pdata->phy.autoneg != AUTONEG_ENABLE) {
1128 if (ret || !pdata->kr_redrv)
1131 netif_dbg(pdata, link, pdata->netdev, "AN redriver support\n");
1133 netif_dbg(pdata, link, pdata->netdev, "AN PHY configuration\n");
1136 /* Disable auto-negotiation interrupt */
1137 disable_irq(pdata->an_irq);
1140 /* Start auto-negotiation in a supported mode */
1158 enable_irq(pdata->an_irq);
1159 ret = -EINVAL;
1164 /* Disable and stop any in progress auto-negotiation */
1167 /* Clear any auto-negotitation interrupts */
1170 pdata->an_result = XGBE_AN_READY;
1171 pdata->an_state = XGBE_AN_READY;
1172 pdata->kr_state = XGBE_RX_BPA;
1173 pdata->kx_state = XGBE_RX_BPA;
1175 /* Re-enable auto-negotiation interrupt */
1176 enable_irq(pdata->an_irq);
1183 set_bit(XGBE_LINK_ERR, &pdata->dev_state);
1185 clear_bit(XGBE_LINK_ERR, &pdata->dev_state);
1187 mutex_unlock(&pdata->an_mutex);
1204 return (pdata->an_result == XGBE_AN_COMPLETE);
1213 link_timeout = pdata->link_check + (XGBE_LINK_TIMEOUT * HZ);
1216 pdata->phy.autoneg == AUTONEG_ENABLE) {
1223 while (wait--) {
1224 kr_time = pdata->kr_start_time +
1229 if (pdata->an_result == XGBE_AN_COMPLETE)
1234 netif_dbg(pdata, link, pdata->netdev, "AN link timeout\n");
1241 return pdata->phy_if.phy_impl.an_outcome(pdata);
1246 struct ethtool_link_ksettings *lks = &pdata->phy.lks;
1251 if ((pdata->phy.autoneg != AUTONEG_ENABLE) || pdata->parallel_detect)
1258 pdata->phy.speed = SPEED_10;
1261 pdata->phy.speed = SPEED_100;
1266 pdata->phy.speed = SPEED_1000;
1269 pdata->phy.speed = SPEED_2500;
1273 pdata->phy.speed = SPEED_10000;
1277 pdata->phy.speed = SPEED_UNKNOWN;
1280 pdata->phy.duplex = DUPLEX_FULL;
1285 if (pdata->an_again)
1296 if (test_bit(XGBE_LINK_ERR, &pdata->dev_state)) {
1297 netif_carrier_off(pdata->netdev);
1299 pdata->phy.link = 0;
1303 link_aneg = (pdata->phy.autoneg == AUTONEG_ENABLE);
1305 pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
1308 if (pdata->phy.link < 0)
1316 if (pdata->phy.link) {
1325 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state))
1326 clear_bit(XGBE_LINK_INIT, &pdata->dev_state);
1328 netif_carrier_on(pdata->netdev);
1330 if (test_bit(XGBE_LINK_INIT, &pdata->dev_state)) {
1339 netif_carrier_off(pdata->netdev);
1348 netif_dbg(pdata, link, pdata->netdev, "stopping PHY\n");
1350 if (!pdata->phy_started)
1353 /* Indicate the PHY is down */
1354 pdata->phy_started = 0;
1356 /* Disable auto-negotiation */
1359 if (pdata->dev_irq != pdata->an_irq) {
1360 devm_free_irq(pdata->dev, pdata->an_irq, pdata);
1361 cancel_work_sync(&pdata->an_bh_work);
1364 pdata->phy_if.phy_impl.stop(pdata);
1366 pdata->phy.link = 0;
1373 struct net_device *netdev = pdata->netdev;
1376 netif_dbg(pdata, link, pdata->netdev, "starting PHY\n");
1378 ret = pdata->phy_if.phy_impl.start(pdata);
1383 if (pdata->dev_irq != pdata->an_irq) {
1384 INIT_WORK(&pdata->an_bh_work, xgbe_an_isr_bh_work);
1386 ret = devm_request_irq(pdata->dev, pdata->an_irq,
1387 xgbe_an_isr, 0, pdata->an_name,
1390 netdev_err(netdev, "phy irq request failed\n");
1395 /* Set initial mode - call the mode setting routines
1415 ret = -EINVAL;
1419 /* Indicate the PHY is up and running */
1420 pdata->phy_started = 1;
1428 if (pdata->dev_irq != pdata->an_irq)
1429 devm_free_irq(pdata->dev, pdata->an_irq, pdata);
1432 pdata->phy_if.phy_impl.stop(pdata);
1441 ret = pdata->phy_if.phy_impl.reset(pdata);
1445 /* Disable auto-negotiation for now */
1448 /* Clear auto-negotiation interrupts */
1456 struct device *dev = pdata->dev;
1458 dev_dbg(dev, "\n************* PHY Reg dump **********************\n");
1464 dev_dbg(dev, "Phy Id (PHYS ID 1 %#06x)= %#06x\n", MDIO_DEVID1,
1466 dev_dbg(dev, "Phy Id (PHYS ID 2 %#06x)= %#06x\n", MDIO_DEVID2,
1468 dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS1,
1470 dev_dbg(dev, "Devices in Package (%#06x)= %#06x\n", MDIO_DEVS2,
1473 dev_dbg(dev, "Auto-Neg Control Reg (%#06x) = %#06x\n", MDIO_CTRL1,
1475 dev_dbg(dev, "Auto-Neg Status Reg (%#06x) = %#06x\n", MDIO_STAT1,
1477 dev_dbg(dev, "Auto-Neg Ad Reg 1 (%#06x) = %#06x\n",
1480 dev_dbg(dev, "Auto-Neg Ad Reg 2 (%#06x) = %#06x\n",
1483 dev_dbg(dev, "Auto-Neg Ad Reg 3 (%#06x) = %#06x\n",
1486 dev_dbg(dev, "Auto-Neg Completion Reg (%#06x) = %#06x\n",
1495 struct ethtool_link_ksettings *lks = &pdata->phy.lks;
1519 pdata->phy_if.phy_impl.exit(pdata);
1524 struct ethtool_link_ksettings *lks = &pdata->phy.lks;
1527 mutex_init(&pdata->an_mutex);
1528 INIT_WORK(&pdata->an_irq_work, xgbe_an_irq_work);
1529 INIT_WORK(&pdata->an_work, xgbe_an_state_machine);
1530 pdata->mdio_mmd = MDIO_MMD_PCS;
1533 pdata->fec_ability = XMDIO_READ(pdata, MDIO_MMD_PMAPMD,
1535 pdata->fec_ability &= (MDIO_PMA_10GBR_FECABLE_ABLE |
1538 /* Setup the phy (including supported features) */
1539 ret = pdata->phy_if.phy_impl.init(pdata);
1546 pdata->phy.address = 0;
1549 pdata->phy.autoneg = AUTONEG_ENABLE;
1550 pdata->phy.speed = SPEED_UNKNOWN;
1551 pdata->phy.duplex = DUPLEX_UNKNOWN;
1553 pdata->phy.autoneg = AUTONEG_DISABLE;
1554 pdata->phy.speed = xgbe_phy_best_advertised_speed(pdata);
1555 pdata->phy.duplex = DUPLEX_FULL;
1558 pdata->phy.link = 0;
1560 pdata->phy.pause_autoneg = pdata->pause_autoneg;
1561 pdata->phy.tx_pause = pdata->tx_pause;
1562 pdata->phy.rx_pause = pdata->rx_pause;
1568 if (pdata->rx_pause) {
1573 if (pdata->tx_pause) {
1589 phy_if->phy_init = xgbe_phy_init;
1590 phy_if->phy_exit = xgbe_phy_exit;
1592 phy_if->phy_reset = xgbe_phy_reset;
1593 phy_if->phy_start = xgbe_phy_start;
1594 phy_if->phy_stop = xgbe_phy_stop;
1596 phy_if->phy_status = xgbe_phy_status;
1597 phy_if->phy_config_aneg = xgbe_phy_config_aneg;
1599 phy_if->phy_valid_speed = xgbe_phy_valid_speed;
1601 phy_if->an_isr = xgbe_an_combined_isr;
1603 phy_if->module_info = xgbe_phy_module_info;
1604 phy_if->module_eeprom = xgbe_phy_module_eeprom;