Lines Matching +full:force +full:- +full:internal +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0+
3 * drivers/net/phy/micrel.c
9 * Copyright (c) 2010-2013 Micrel, Inc.
25 #include <linux/phy.h>
52 /* PHY Control 1 */
55 /* PHY Control 2 / PHY Control (if no PHY Control 1) */
58 /* bitmap of PHY register to set interrupt mode */
160 const struct kszphy_type *type = phydev->drv->driver_data; in kszphy_config_intr()
164 if (type && type->interrupt_level_mask) in kszphy_config_intr()
165 mask = type->interrupt_level_mask; in kszphy_config_intr()
177 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) in kszphy_config_intr()
213 return -EINVAL; in kszphy_setup_led()
232 /* Disable PHY address 0 as the broadcast address, so that it can be used as a
233 * unique (non-broadcast) address on a shared bus.
274 struct kszphy_priv *priv = phydev->priv; in kszphy_config_reset()
277 if (priv->rmii_ref_clk_sel) { in kszphy_config_reset()
278 ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val); in kszphy_config_reset()
286 if (priv->led_mode >= 0) in kszphy_config_reset()
287 kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode); in kszphy_config_reset()
294 struct kszphy_priv *priv = phydev->priv; in kszphy_config_init()
300 type = priv->type; in kszphy_config_init()
302 if (type->has_broadcast_disable) in kszphy_config_init()
305 if (type->has_nand_tree_disable) in kszphy_config_init()
315 struct device_node *of_node = phydev->mdio.dev.of_node; in ksz8041_config_init()
318 if (of_property_read_bool(of_node, "micrel,fiber-mode")) { in ksz8041_config_init()
319 phydev->dev_flags |= MICREL_PHY_FXEN; in ksz8041_config_init()
323 linkmode_and(phydev->supported, phydev->supported, mask); in ksz8041_config_init()
325 phydev->supported); in ksz8041_config_init()
326 linkmode_and(phydev->advertising, phydev->advertising, mask); in ksz8041_config_init()
328 phydev->advertising); in ksz8041_config_init()
329 phydev->autoneg = AUTONEG_DISABLE; in ksz8041_config_init()
337 /* Skip auto-negotiation in fiber mode */ in ksz8041_config_aneg()
338 if (phydev->dev_flags & MICREL_PHY_FXEN) { in ksz8041_config_aneg()
339 phydev->speed = SPEED_100; in ksz8041_config_aneg()
351 if ((phydev->phy_id & MICREL_PHY_ID_MASK) != ksz_phy_id) in ksz8051_ksz8795_match_phy_device()
358 /* KSZ8051 PHY and KSZ8794/KSZ8795/KSZ8765 switch share the same in ksz8051_ksz8795_match_phy_device()
359 * exact PHY ID. However, they can be told apart by the extended in ksz8051_ksz8795_match_phy_device()
360 * capability registers presence. The KSZ8051 PHY has them while in ksz8051_ksz8795_match_phy_device()
377 /* KSZPHY_OMSO_FACTORY_TEST is set at de-assertion of the reset line in ksz8081_config_init()
379 * pull-down is missing, the factory test mode should be cleared by in ksz8081_config_init()
409 int val1 = -1; in ksz9021_load_values_from_of()
410 int val2 = -2; in ksz9021_load_values_from_of()
411 int val3 = -3; in ksz9021_load_values_from_of()
412 int val4 = -4; in ksz9021_load_values_from_of()
436 if (val1 != -1) in ksz9021_load_values_from_of()
439 if (val2 != -2) in ksz9021_load_values_from_of()
442 if (val3 != -3) in ksz9021_load_values_from_of()
445 if (val4 != -4) in ksz9021_load_values_from_of()
453 const struct device *dev = &phydev->mdio.dev; in ksz9021_config_init()
454 const struct device_node *of_node = dev->of_node; in ksz9021_config_init()
457 /* The Micrel driver has a deprecated option to place phy OF in ksz9021_config_init()
461 dev_walker = &phydev->mdio.dev; in ksz9021_config_init()
463 of_node = dev_walker->of_node; in ksz9021_config_init()
464 dev_walker = dev_walker->parent; in ksz9021_config_init()
471 "txen-skew-ps", "txc-skew-ps", in ksz9021_config_init()
472 "rxdv-skew-ps", "rxc-skew-ps"); in ksz9021_config_init()
475 "rxd0-skew-ps", "rxd1-skew-ps", in ksz9021_config_init()
476 "rxd2-skew-ps", "rxd3-skew-ps"); in ksz9021_config_init()
479 "txd0-skew-ps", "txd1-skew-ps", in ksz9021_config_init()
480 "txd2-skew-ps", "txd3-skew-ps"); in ksz9021_config_init()
513 /* KSZ9031 has internal RGMII_IDRX = 1.2ns and RGMII_IDTX = 0ns. To
523 /* set rx to +0.30ns and rx_clk to -0.90ns to compensate the
524 * internal 1.2ns delay.
529 /* set tx to -0.42ns and tx_clk to +0.96ns to get 1.38ns delay */
549 int val[4] = {-1, -2, -3, -4}; in ksz9031_of_load_skew_values()
572 if (val[i] != -(i + 1)) { in ksz9031_of_load_skew_values()
601 /* Enable energy-detect power-down mode */
618 switch (phydev->interface) { in ksz9031_config_rgmii_delay()
676 const struct device *dev = &phydev->mdio.dev; in ksz9031_config_init()
677 const struct device_node *of_node = dev->of_node; in ksz9031_config_init()
678 static const char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"}; in ksz9031_config_init()
680 "rxd0-skew-ps", "rxd1-skew-ps", in ksz9031_config_init()
681 "rxd2-skew-ps", "rxd3-skew-ps" in ksz9031_config_init()
684 "txd0-skew-ps", "txd1-skew-ps", in ksz9031_config_init()
685 "txd2-skew-ps", "txd3-skew-ps" in ksz9031_config_init()
687 static const char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"}; in ksz9031_config_init()
695 /* The Micrel driver has a deprecated option to place phy OF in ksz9031_config_init()
699 dev_walker = &phydev->mdio.dev; in ksz9031_config_init()
701 of_node = dev_walker->of_node; in ksz9031_config_init()
702 dev_walker = dev_walker->parent; in ksz9031_config_init()
730 if (update && phydev->interface != PHY_INTERFACE_MODE_RGMII) in ksz9031_config_init()
732 "*-skew-ps values should be used only with phy-mode = \"rgmii\"\n"); in ksz9031_config_init()
735 * When the device links in the 1000BASE-T slave mode only, in ksz9031_config_init()
746 * Force the phy to be the master to receive a stable clock in ksz9031_config_init()
749 if (of_property_read_bool(of_node, "micrel,force-master")) { in ksz9031_config_init()
765 phydev_err(phydev, "failed to force the phy to master mode\n"); in ksz9031_config_init()
779 int val[4] = {-(1 + KSZ9131_OFFSET), -(2 + KSZ9131_OFFSET), in ksz9131_of_load_skew_values()
780 -(3 + KSZ9131_OFFSET), -(4 + KSZ9131_OFFSET)}; in ksz9131_of_load_skew_values()
796 if (skewval < -KSZ9131_OFFSET) in ksz9131_of_load_skew_values()
797 skewval = -KSZ9131_OFFSET; in ksz9131_of_load_skew_values()
815 if (val[i] != -(i + 1 + KSZ9131_OFFSET)) { in ksz9131_of_load_skew_values()
838 switch (phydev->interface) { in ksz9131_config_rgmii_delay()
872 const struct device *dev = &phydev->mdio.dev; in ksz9131_config_init()
873 struct device_node *of_node = dev->of_node; in ksz9131_config_init()
874 char *clk_skews[2] = {"rxc-skew-psec", "txc-skew-psec"}; in ksz9131_config_init()
876 "rxd0-skew-psec", "rxd1-skew-psec", in ksz9131_config_init()
877 "rxd2-skew-psec", "rxd3-skew-psec" in ksz9131_config_init()
880 "txd0-skew-psec", "txd1-skew-psec", in ksz9131_config_init()
881 "txd2-skew-psec", "txd3-skew-psec" in ksz9131_config_init()
883 char *control_skews[2] = {"txen-skew-psec", "rxdv-skew-psec"}; in ksz9131_config_init()
887 dev_walker = &phydev->mdio.dev; in ksz9131_config_init()
889 of_node = dev_walker->of_node; in ksz9131_config_init()
890 dev_walker = dev_walker->parent; in ksz9131_config_init()
942 phydev->duplex = DUPLEX_HALF; in ksz8873mll_read_status()
944 phydev->duplex = DUPLEX_FULL; in ksz8873mll_read_status()
947 phydev->speed = SPEED_10; in ksz8873mll_read_status()
949 phydev->speed = SPEED_100; in ksz8873mll_read_status()
951 phydev->link = 1; in ksz8873mll_read_status()
952 phydev->pause = phydev->asym_pause = 0; in ksz8873mll_read_status()
967 * link-up may fail after a link-up to link-down transition. in ksz9031_get_features()
974 linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported); in ksz9031_get_features()
976 /* We force setting the Pause capability as the core will force the in ksz9031_get_features()
979 linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported); in ksz9031_get_features()
993 /* Make sure the PHY is not broken. Read idle error count, in ksz9031_read_status()
994 * and reset the PHY if it is maxed out. in ksz9031_read_status()
999 phydev->link = 0; in ksz9031_read_status()
1000 if (phydev->drv->config_intr && phy_interrupt_is_valid(phydev)) in ksz9031_read_status()
1001 phydev->drv->config_intr(phydev); in ksz9031_read_status()
1031 struct kszphy_priv *priv = phydev->priv; in kszphy_get_stat()
1039 val = val & ((1 << stat.bits) - 1); in kszphy_get_stat()
1040 priv->stats[i] += val; in kszphy_get_stat()
1041 ret = priv->stats[i]; in kszphy_get_stat()
1058 /* Disable PHY Interrupts */ in kszphy_suspend()
1060 phydev->interrupts = PHY_INTERRUPT_DISABLED; in kszphy_suspend()
1061 if (phydev->drv->config_intr) in kszphy_suspend()
1062 phydev->drv->config_intr(phydev); in kszphy_suspend()
1074 /* After switching from power-down to normal mode, an internal global in kszphy_resume()
1076 * read/write access to the PHY registers. in kszphy_resume()
1084 /* Enable PHY Interrupts */ in kszphy_resume()
1086 phydev->interrupts = PHY_INTERRUPT_ENABLED; in kszphy_resume()
1087 if (phydev->drv->config_intr) in kszphy_resume()
1088 phydev->drv->config_intr(phydev); in kszphy_resume()
1096 const struct kszphy_type *type = phydev->drv->driver_data; in kszphy_probe()
1097 const struct device_node *np = phydev->mdio.dev.of_node; in kszphy_probe()
1102 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); in kszphy_probe()
1104 return -ENOMEM; in kszphy_probe()
1106 phydev->priv = priv; in kszphy_probe()
1108 priv->type = type; in kszphy_probe()
1110 if (type->led_mode_reg) { in kszphy_probe()
1111 ret = of_property_read_u32(np, "micrel,led-mode", in kszphy_probe()
1112 &priv->led_mode); in kszphy_probe()
1114 priv->led_mode = -1; in kszphy_probe()
1116 if (priv->led_mode > 3) { in kszphy_probe()
1118 priv->led_mode); in kszphy_probe()
1119 priv->led_mode = -1; in kszphy_probe()
1122 priv->led_mode = -1; in kszphy_probe()
1125 clk = devm_clk_get(&phydev->mdio.dev, "rmii-ref"); in kszphy_probe()
1131 priv->rmii_ref_clk_sel = type->has_rmii_ref_clk_sel; in kszphy_probe()
1133 "micrel,rmii-reference-clock-select-25-mhz"); in kszphy_probe()
1136 priv->rmii_ref_clk_sel_val = rmii_ref_clk_sel_25_mhz; in kszphy_probe()
1138 priv->rmii_ref_clk_sel_val = !rmii_ref_clk_sel_25_mhz; in kszphy_probe()
1142 return -EINVAL; in kszphy_probe()
1146 /* Support legacy board-file configuration */ in kszphy_probe()
1147 if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK) { in kszphy_probe()
1148 priv->rmii_ref_clk_sel = true; in kszphy_probe()
1149 priv->rmii_ref_clk_sel_val = true; in kszphy_probe()
1285 .name = "Micrel KSZ9021 Gigabit PHY",
1303 .name = "Micrel KSZ9031 Gigabit PHY",
1320 .name = "Microchip INDY Gigabit Quad PHY",
1333 .name = "Microchip KSZ9131 Gigabit PHY",
1385 MODULE_DESCRIPTION("Micrel PHY driver");