Lines Matching +full:switch +full:- +full:x +full:- +full:sgmii

1 // SPDX-License-Identifier: GPL-2.0+
52 #define PHY_IMASK_WOL BIT(15) /* Wake-on-LAN */
53 #define PHY_IMASK_ANC BIT(10) /* Auto-Neg complete */
54 #define PHY_IMASK_ADSC BIT(5) /* Link auto-downspeed detect */
75 /* SGMII */
112 /* It takes 3 seconds to fully switch out of loopback mode before
113 * it can safely re-enter loopback mode. Record the time when
133 * T = -2.5761e-11*(N^4) + 9.7332e-8*(N^3) + -1.9165e-4*(N^2) +
134 * 3.0762e-1*(N^1) + -5.2156e1
136 * where [-52.156, 137.961]C and N = [0, 1023].
145 * T = -25761e-12*(N^4) + 97332e-9*(N^3) + -191650e-6*(N^2) +
146 * 307620e-3*(N^1) + -52156
148 * where T = [-52156, 137961]mC and N = [0, 1023].
152 {4, -25761, 1000, 1},
154 {2, -191650, 1000, 1},
156 {0, -52156, 1, 1}
171 return -ENODATA; in gpy_hwmon_read()
203 struct device *dev = &phydev->mdio.dev; in gpy_hwmon_register()
236 struct gpy_priv *priv = phydev->priv; in gpy_mbox_read()
240 mutex_lock(&priv->mbox_lock); in gpy_mbox_read()
269 mutex_unlock(&priv->mbox_lock); in gpy_mbox_read()
281 __set_bit(PHY_INTERFACE_MODE_2500BASEX, phydev->possible_interfaces); in gpy21x_config_init()
282 __set_bit(PHY_INTERFACE_MODE_SGMII, phydev->possible_interfaces); in gpy21x_config_init()
289 struct device *dev = &phydev->mdio.dev; in gpy_probe()
294 if (!phydev->is_c45) { in gpy_probe()
302 return -ENOMEM; in gpy_probe()
303 phydev->priv = priv; in gpy_probe()
304 mutex_init(&priv->mbox_lock); in gpy_probe()
306 if (!device_property_present(dev, "maxlinear,use-broken-interrupts")) in gpy_probe()
307 phydev->dev_flags |= PHY_F_NO_IRQ; in gpy_probe()
312 priv->fw_major = FIELD_GET(PHY_FWV_MAJOR_MASK, fw_version); in gpy_probe()
313 priv->fw_minor = FIELD_GET(PHY_FWV_MINOR_MASK, fw_version); in gpy_probe()
320 phydev_info(phydev, "Firmware Version: %d.%d (0x%04X%s)\n", in gpy_probe()
321 priv->fw_major, priv->fw_minor, fw_version, in gpy_probe()
329 struct gpy_priv *priv = phydev->priv; in gpy_sgmii_need_reaneg()
333 if (priv->fw_major != ver_need_sgmii_reaneg[i].major) in gpy_sgmii_need_reaneg()
335 if (priv->fw_minor < ver_need_sgmii_reaneg[i].minor) in gpy_sgmii_need_reaneg()
358 phydev->speed = SPEED_2500; in gpy_2500basex_chk()
359 phydev->interface = PHY_INTERFACE_MODE_2500BASEX; in gpy_2500basex_chk()
384 switch (ctrl) { in gpy_config_mdix()
412 if (phydev->autoneg == AUTONEG_DISABLE) { in gpy_config_aneg()
416 return phydev->duplex != DUPLEX_FULL in gpy_config_aneg()
421 ret = gpy_config_mdix(phydev, phydev->mdix_ctrl); in gpy_config_aneg()
431 adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising); in gpy_config_aneg()
444 if (phydev->interface == PHY_INTERFACE_MODE_USXGMII || in gpy_config_aneg()
445 phydev->interface == PHY_INTERFACE_MODE_INTERNAL) in gpy_config_aneg()
448 /* No need to trigger re-ANEG if link speed is 2.5G or SGMII ANEG is in gpy_config_aneg()
455 /* There is a design constraint in GPY2xx device where SGMII AN is in gpy_config_aneg()
458 * again, SGMII AN is not triggered and hence no new in-band message in gpy_config_aneg()
459 * from GPY to MAC side SGMII. in gpy_config_aneg()
461 * MAC. At this condition, once MAC side SGMII is up, MAC side SGMII in gpy_config_aneg()
462 * wouldn`t receive new in-band message from GPY with correct link in gpy_config_aneg()
467 * retriggerring SGMII AN. in gpy_config_aneg()
469 * reboot), polling of TPI link status is not needed and SGMII AN is in gpy_config_aneg()
472 * retriggering SGMII AN. Note: in case of speed change, GPY FW will in gpy_config_aneg()
473 * initiate SGMII AN. in gpy_config_aneg()
476 if (phydev->state != PHY_UP) in gpy_config_aneg()
481 if (ret == -ETIMEDOUT) in gpy_config_aneg()
486 /* Trigger SGMII AN. */ in gpy_config_aneg()
500 phydev->mdix_ctrl = ETH_TP_MDI_AUTO; in gpy_update_mdix()
503 phydev->mdix_ctrl = ETH_TP_MDI_X; in gpy_update_mdix()
505 phydev->mdix_ctrl = ETH_TP_MDI; in gpy_update_mdix()
512 phydev->mdix = ETH_TP_MDI_X; in gpy_update_mdix()
514 phydev->mdix = ETH_TP_MDI; in gpy_update_mdix()
524 if (phydev->interface == PHY_INTERFACE_MODE_USXGMII || in gpy_update_interface()
525 phydev->interface == PHY_INTERFACE_MODE_INTERNAL) in gpy_update_interface()
526 return -EINVAL; in gpy_update_interface()
528 /* Automatically switch SERDES interface between SGMII and 2500-BaseX in gpy_update_interface()
529 * according to speed. Disable ANEG in 2500-BaseX mode. in gpy_update_interface()
531 switch (phydev->speed) { in gpy_update_interface()
533 phydev->interface = PHY_INTERFACE_MODE_2500BASEX; in gpy_update_interface()
538 "Error: Disable of SGMII ANEG failed: %d\n", in gpy_update_interface()
546 phydev->interface = PHY_INTERFACE_MODE_SGMII; in gpy_update_interface()
549 /* Enable and restart SGMII ANEG for 10/100/1000Mbps link speed in gpy_update_interface()
550 * if ANEG is disabled (in 2500-BaseX mode). in gpy_update_interface()
557 "Error: Enable of SGMII ANEG failed: %d\n", in gpy_update_interface()
564 if (phydev->speed == SPEED_2500 || phydev->speed == SPEED_1000) { in gpy_update_interface()
581 phydev->speed = SPEED_UNKNOWN; in gpy_read_status()
582 phydev->duplex = DUPLEX_UNKNOWN; in gpy_read_status()
583 phydev->pause = 0; in gpy_read_status()
584 phydev->asym_pause = 0; in gpy_read_status()
586 if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) { in gpy_read_status()
595 mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, ret); in gpy_read_status()
596 } else if (phydev->autoneg == AUTONEG_DISABLE) { in gpy_read_status()
597 linkmode_zero(phydev->lp_advertising); in gpy_read_status()
604 phydev->link = (ret & PHY_MIISTAT_LS) ? 1 : 0; in gpy_read_status()
605 phydev->duplex = (ret & PHY_MIISTAT_DPX) ? DUPLEX_FULL : DUPLEX_HALF; in gpy_read_status()
606 switch (FIELD_GET(PHY_MIISTAT_SPD_MASK, ret)) { in gpy_read_status()
608 phydev->speed = SPEED_10; in gpy_read_status()
611 phydev->speed = SPEED_100; in gpy_read_status()
614 phydev->speed = SPEED_1000; in gpy_read_status()
617 phydev->speed = SPEED_2500; in gpy_read_status()
621 if (phydev->link) { in gpy_read_status()
632 struct gpy_priv *priv = phydev->priv; in gpy_config_intr()
640 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) in gpy_config_intr()
643 if (priv->wolopts & WAKE_MAGIC) in gpy_config_intr()
646 if (priv->wolopts & WAKE_PHY) in gpy_config_intr()
694 struct net_device *attach_dev = phydev->attached_dev; in gpy_set_wol()
695 struct gpy_priv *priv = phydev->priv; in gpy_set_wol()
698 if (wol->wolopts & WAKE_MAGIC) { in gpy_set_wol()
699 /* MAC address - Byte0:Byte1:Byte2:Byte3:Byte4:Byte5 in gpy_set_wol()
706 ((attach_dev->dev_addr[0] << 8) | in gpy_set_wol()
707 attach_dev->dev_addr[1])); in gpy_set_wol()
713 ((attach_dev->dev_addr[2] << 8) | in gpy_set_wol()
714 attach_dev->dev_addr[3])); in gpy_set_wol()
720 ((attach_dev->dev_addr[4] << 8) | in gpy_set_wol()
721 attach_dev->dev_addr[5])); in gpy_set_wol()
744 priv->wolopts |= WAKE_MAGIC; in gpy_set_wol()
758 priv->wolopts &= ~WAKE_MAGIC; in gpy_set_wol()
761 if (wol->wolopts & WAKE_PHY) { in gpy_set_wol()
775 priv->wolopts |= WAKE_PHY; in gpy_set_wol()
779 priv->wolopts &= ~WAKE_PHY; in gpy_set_wol()
787 struct gpy_priv *priv = phydev->priv; in gpy_get_wol()
789 wol->supported = WAKE_MAGIC | WAKE_PHY; in gpy_get_wol()
790 wol->wolopts = priv->wolopts; in gpy_get_wol()
795 struct gpy_priv *priv = phydev->priv; in gpy_loopback()
803 if (time_before64(now, priv->lb_dis_to)) in gpy_loopback()
804 msleep(jiffies64_to_msecs(priv->lb_dis_to - now)); in gpy_loopback()
814 /* It takes some time for PHY device to switch into in gpy_loopback()
819 priv->lb_dis_to = get_jiffies_64() + HZ * 3; in gpy_loopback()
827 struct gpy_priv *priv = phydev->priv; in gpy115_loopback()
832 if (priv->fw_minor > 0x76) in gpy115_loopback()