^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Framework for finding and configuring PHYs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Also contains generic PHY driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Author: Andy Fleming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2004 Freescale Semiconductor, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/phy_led_triggers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/sfp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) MODULE_DESCRIPTION("PHY library");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) MODULE_AUTHOR("Andy Fleming");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) EXPORT_SYMBOL_GPL(phy_basic_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_basic_t1_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) EXPORT_SYMBOL_GPL(phy_basic_t1_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) EXPORT_SYMBOL_GPL(phy_gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_fibre_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) EXPORT_SYMBOL_GPL(phy_gbit_fibre_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_gbit_all_ports_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) EXPORT_SYMBOL_GPL(phy_gbit_all_ports_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) EXPORT_SYMBOL_GPL(phy_10gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_fec_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) EXPORT_SYMBOL_GPL(phy_10gbit_fec_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) const int phy_basic_ports_array[3] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ETHTOOL_LINK_MODE_Autoneg_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) ETHTOOL_LINK_MODE_TP_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) ETHTOOL_LINK_MODE_MII_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) EXPORT_SYMBOL_GPL(phy_basic_ports_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) const int phy_fibre_port_array[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ETHTOOL_LINK_MODE_FIBRE_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) EXPORT_SYMBOL_GPL(phy_fibre_port_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) const int phy_all_ports_features_array[7] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ETHTOOL_LINK_MODE_Autoneg_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ETHTOOL_LINK_MODE_TP_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ETHTOOL_LINK_MODE_MII_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) ETHTOOL_LINK_MODE_FIBRE_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) ETHTOOL_LINK_MODE_AUI_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ETHTOOL_LINK_MODE_BNC_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ETHTOOL_LINK_MODE_Backplane_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) EXPORT_SYMBOL_GPL(phy_all_ports_features_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const int phy_10_100_features_array[4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ETHTOOL_LINK_MODE_10baseT_Half_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ETHTOOL_LINK_MODE_10baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) ETHTOOL_LINK_MODE_100baseT_Half_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) ETHTOOL_LINK_MODE_100baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) EXPORT_SYMBOL_GPL(phy_10_100_features_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) const int phy_basic_t1_features_array[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ETHTOOL_LINK_MODE_TP_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) EXPORT_SYMBOL_GPL(phy_basic_t1_features_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) const int phy_gbit_features_array[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) EXPORT_SYMBOL_GPL(phy_gbit_features_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) const int phy_10gbit_features_array[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL_GPL(phy_10gbit_features_array);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) static const int phy_10gbit_fec_features_array[1] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) ETHTOOL_LINK_MODE_10000baseR_FEC_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_10gbit_full_features) __ro_after_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) EXPORT_SYMBOL_GPL(phy_10gbit_full_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) static const int phy_10gbit_full_features_array[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ETHTOOL_LINK_MODE_10baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) ETHTOOL_LINK_MODE_100baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) static void features_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) /* 10/100 half/full*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) linkmode_set_bit_array(phy_basic_ports_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ARRAY_SIZE(phy_basic_ports_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) phy_basic_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) linkmode_set_bit_array(phy_10_100_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ARRAY_SIZE(phy_10_100_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) phy_basic_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) /* 100 full, TP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) linkmode_set_bit_array(phy_basic_t1_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ARRAY_SIZE(phy_basic_t1_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) phy_basic_t1_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* 10/100 half/full + 1000 half/full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) linkmode_set_bit_array(phy_basic_ports_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) ARRAY_SIZE(phy_basic_ports_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) phy_gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) linkmode_set_bit_array(phy_10_100_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) ARRAY_SIZE(phy_10_100_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) phy_gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) linkmode_set_bit_array(phy_gbit_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) ARRAY_SIZE(phy_gbit_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) phy_gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /* 10/100 half/full + 1000 half/full + fibre*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) linkmode_set_bit_array(phy_basic_ports_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) ARRAY_SIZE(phy_basic_ports_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) phy_gbit_fibre_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) linkmode_set_bit_array(phy_10_100_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ARRAY_SIZE(phy_10_100_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) phy_gbit_fibre_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) linkmode_set_bit_array(phy_gbit_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) ARRAY_SIZE(phy_gbit_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) phy_gbit_fibre_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) linkmode_set_bit_array(phy_fibre_port_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) ARRAY_SIZE(phy_fibre_port_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) phy_gbit_fibre_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* 10/100 half/full + 1000 half/full + TP/MII/FIBRE/AUI/BNC/Backplane*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) linkmode_set_bit_array(phy_all_ports_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ARRAY_SIZE(phy_all_ports_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) phy_gbit_all_ports_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) linkmode_set_bit_array(phy_10_100_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ARRAY_SIZE(phy_10_100_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) phy_gbit_all_ports_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) linkmode_set_bit_array(phy_gbit_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) ARRAY_SIZE(phy_gbit_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) phy_gbit_all_ports_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* 10/100 half/full + 1000 half/full + 10G full*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) linkmode_set_bit_array(phy_all_ports_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ARRAY_SIZE(phy_all_ports_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) phy_10gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) linkmode_set_bit_array(phy_10_100_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ARRAY_SIZE(phy_10_100_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) phy_10gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) linkmode_set_bit_array(phy_gbit_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ARRAY_SIZE(phy_gbit_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) phy_10gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) linkmode_set_bit_array(phy_10gbit_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) ARRAY_SIZE(phy_10gbit_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) phy_10gbit_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* 10/100/1000/10G full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) linkmode_set_bit_array(phy_all_ports_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ARRAY_SIZE(phy_all_ports_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) phy_10gbit_full_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) linkmode_set_bit_array(phy_10gbit_full_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ARRAY_SIZE(phy_10gbit_full_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) phy_10gbit_full_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* 10G FEC only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) linkmode_set_bit_array(phy_10gbit_fec_features_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) ARRAY_SIZE(phy_10gbit_fec_features_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) phy_10gbit_fec_features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) void phy_device_free(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) put_device(&phydev->mdio.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EXPORT_SYMBOL(phy_device_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static void phy_mdio_device_free(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) phydev = container_of(mdiodev, struct phy_device, mdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) phy_device_free(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static void phy_device_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) kfree(to_phy_device(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) static void phy_mdio_device_remove(struct mdio_device *mdiodev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) phydev = container_of(mdiodev, struct phy_device, mdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) phy_device_remove(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static struct phy_driver genphy_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static LIST_HEAD(phy_fixup_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static DEFINE_MUTEX(phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static bool mdio_bus_phy_may_suspend(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) struct device_driver *drv = phydev->mdio.dev.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct phy_driver *phydrv = to_phy_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct net_device *netdev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (!drv || !phydrv->suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* PHY not attached? May suspend if the PHY has not already been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * suspended as part of a prior call to phy_disconnect() ->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * phy_detach() -> phy_suspend() because the parent netdev might be the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * MDIO bus driver and clock gated at this point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (!netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (netdev->wol_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* As long as not all affected network drivers support the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * wol_enabled flag, let's check for hints that WoL is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Don't suspend PHY if the attached netdev parent may wake up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * The parent may point to a PCI device, as in tg3 driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (netdev->dev.parent && device_may_wakeup(netdev->dev.parent))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* Also don't suspend PHY if the netdev itself may wakeup. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * is the case for devices w/o underlaying pwr. mgmt. aware bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * e.g. SoC devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (device_may_wakeup(&netdev->dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return !phydev->suspended;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static __maybe_unused int mdio_bus_phy_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) /* We must stop the state machine manually, otherwise it stops out of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * control, possibly with the phydev->lock held. Upon resume, netdev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * may call phy routines that try to grab the same lock, and that may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * lead to a deadlock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (phydev->attached_dev && phydev->adjust_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) phy_stop_machine(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (!mdio_bus_phy_may_suspend(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) phydev->suspended_by_mdio_bus = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) return phy_suspend(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) static __maybe_unused int mdio_bus_phy_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) if (!phydev->suspended_by_mdio_bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) goto no_resume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) phydev->suspended_by_mdio_bus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) ret = phy_init_hw(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ret = phy_resume(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) no_resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (phydev->attached_dev && phydev->adjust_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) phy_start_machine(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static SIMPLE_DEV_PM_OPS(mdio_bus_phy_pm_ops, mdio_bus_phy_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) mdio_bus_phy_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * phy_register_fixup - creates a new phy_fixup and adds it to the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * @bus_id: A string which matches phydev->mdio.dev.bus_id (or PHY_ANY_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * It can also be PHY_ANY_UID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * @run: The actual code to be run when a matching PHY is found
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) int (*run)(struct phy_device *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) struct phy_fixup *fixup = kzalloc(sizeof(*fixup), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) if (!fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) strlcpy(fixup->bus_id, bus_id, sizeof(fixup->bus_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) fixup->phy_uid = phy_uid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) fixup->phy_uid_mask = phy_uid_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) fixup->run = run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mutex_lock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) list_add_tail(&fixup->list, &phy_fixup_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) mutex_unlock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) EXPORT_SYMBOL(phy_register_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) /* Registers a fixup to be run on any PHY with the UID in phy_uid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int (*run)(struct phy_device *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) EXPORT_SYMBOL(phy_register_fixup_for_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /* Registers a fixup to be run on the PHY with id string bus_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int phy_register_fixup_for_id(const char *bus_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) int (*run)(struct phy_device *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(phy_register_fixup_for_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * phy_unregister_fixup - remove a phy_fixup from the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * @bus_id: A string matches fixup->bus_id (or PHY_ANY_ID) in phy_fixup_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * @phy_uid: A phy id matches fixup->phy_id (or PHY_ANY_UID) in phy_fixup_list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * @phy_uid_mask: Applied to phy_uid and fixup->phy_uid before comparison
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) int phy_unregister_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) struct list_head *pos, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) struct phy_fixup *fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) mutex_lock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) list_for_each_safe(pos, n, &phy_fixup_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) fixup = list_entry(pos, struct phy_fixup, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if ((!strcmp(fixup->bus_id, bus_id)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ((fixup->phy_uid & phy_uid_mask) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) (phy_uid & phy_uid_mask))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) list_del(&fixup->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) kfree(fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) mutex_unlock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) EXPORT_SYMBOL(phy_unregister_fixup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* Unregisters a fixup of any PHY with the UID in phy_uid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) int phy_unregister_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return phy_unregister_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) EXPORT_SYMBOL(phy_unregister_fixup_for_uid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /* Unregisters a fixup of the PHY with id string bus_id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int phy_unregister_fixup_for_id(const char *bus_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return phy_unregister_fixup(bus_id, PHY_ANY_UID, 0xffffffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) EXPORT_SYMBOL(phy_unregister_fixup_for_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) /* Returns 1 if fixup matches phydev in bus_id and phy_uid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) * Fixups can be set to match any in one or more fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (strcmp(fixup->bus_id, phydev_name(phydev)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if ((fixup->phy_uid & fixup->phy_uid_mask) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) (phydev->phy_id & fixup->phy_uid_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (fixup->phy_uid != PHY_ANY_UID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /* Runs any matching fixups for this phydev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static int phy_scan_fixups(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct phy_fixup *fixup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) mutex_lock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) list_for_each_entry(fixup, &phy_fixup_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (phy_needs_fixup(phydev, fixup)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) int err = fixup->run(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) mutex_unlock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) phydev->has_fixups = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) mutex_unlock(&phy_fixup_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static int phy_bus_match(struct device *dev, struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) struct phy_driver *phydrv = to_phy_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (phydrv->match_phy_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return phydrv->match_phy_device(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if (phydev->is_c45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) for (i = 1; i < num_ids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (phydev->c45_ids.device_ids[i] == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) if ((phydrv->phy_id & phydrv->phy_id_mask) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) (phydev->c45_ids.device_ids[i] &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) phydrv->phy_id_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return (phydrv->phy_id & phydrv->phy_id_mask) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) (phydev->phy_id & phydrv->phy_id_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) phy_id_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) return sprintf(buf, "0x%.8lx\n", (unsigned long)phydev->phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) static DEVICE_ATTR_RO(phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) phy_interface_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) const char *mode = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (phy_is_internal(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) mode = "internal";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) mode = phy_modes(phydev->interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return sprintf(buf, "%s\n", mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) static DEVICE_ATTR_RO(phy_interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return sprintf(buf, "%d\n", phydev->has_fixups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) static DEVICE_ATTR_RO(phy_has_fixups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) phy_registers_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) for (index = 0; index < 32; index++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) sprintf(buf, "%s%2d: 0x%x\n", buf, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) phy_read(phydev, index));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) return strlen(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) phy_registers_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int index = 0, val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) char tmp[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) char *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (count >= sizeof(tmp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) memset(tmp, 0, sizeof(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) memcpy(tmp, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) data = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) data = strstr(data, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *data = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) if (kstrtoint(tmp, 0, &index) || index >= 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (kstrtoint(data, 0, &val) || val > 0xffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) pr_info("Set Ethernet PHY register %d to 0x%x\n", (int)index, (int)val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) phy_write(phydev, index, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) pr_err("wrong register value input\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) pr_err("usage: <reg index> <value>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static DEVICE_ATTR_RW(phy_registers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static struct attribute *phy_dev_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) &dev_attr_phy_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) &dev_attr_phy_interface.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) &dev_attr_phy_has_fixups.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) &dev_attr_phy_registers.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ATTRIBUTE_GROUPS(phy_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) static const struct device_type mdio_bus_phy_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) .name = "PHY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) .groups = phy_dev_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) .release = phy_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) .pm = pm_ptr(&mdio_bus_phy_pm_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) static int phy_request_driver_module(struct phy_device *dev, u32 phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) ret = request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) MDIO_ID_ARGS(phy_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) /* We only check for failures in executing the usermode binary,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * not whether a PHY driver module exists for the PHY ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * Accept -ENOENT because this may occur in case no initramfs exists,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * then modprobe isn't available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (IS_ENABLED(CONFIG_MODULES) && ret < 0 && ret != -ENOENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) phydev_err(dev, "error %d loading PHY driver module for ID 0x%08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) ret, (unsigned long)phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) struct phy_device *phy_device_create(struct mii_bus *bus, int addr, u32 phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) bool is_c45,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct phy_c45_device_ids *c45_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct phy_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct mdio_device *mdiodev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) /* We allocate the device, and initialize the default values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dev = kzalloc(sizeof(*dev), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) mdiodev = &dev->mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) mdiodev->dev.parent = &bus->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) mdiodev->dev.bus = &mdio_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) mdiodev->dev.type = &mdio_bus_phy_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) mdiodev->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) mdiodev->bus_match = phy_bus_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) mdiodev->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) mdiodev->flags = MDIO_DEVICE_FLAG_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) mdiodev->device_free = phy_mdio_device_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) mdiodev->device_remove = phy_mdio_device_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) dev->speed = SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) dev->duplex = DUPLEX_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) dev->asym_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) dev->link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev->port = PORT_TP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) dev->interface = PHY_INTERFACE_MODE_GMII;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) dev->autoneg = AUTONEG_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) dev->is_c45 = is_c45;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev->phy_id = phy_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (c45_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) dev->c45_ids = *c45_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dev->irq = bus->irq[addr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) dev_set_name(&mdiodev->dev, PHY_ID_FMT, bus->id, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) device_initialize(&mdiodev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dev->state = PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) mutex_init(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) /* Request the appropriate module unconditionally; don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * bother trying to do so only if it isn't already loaded,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) * because that gets complicated. A hotplug event would have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * done an unconditional modprobe anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * We don't do normal hotplug because it won't work for MDIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * -- because it relies on the device staying around for long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * enough for the driver to get loaded. With MDIO, the NIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * driver will get bored and give up as soon as it finds that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * there's no driver _already_ loaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (is_c45 && c45_ids) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) for (i = 1; i < num_ids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) if (c45_ids->device_ids[i] == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ret = phy_request_driver_module(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) c45_ids->device_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ret = phy_request_driver_module(dev, phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) put_device(&mdiodev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) dev = ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) EXPORT_SYMBOL(phy_device_create);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) /* phy_c45_probe_present - checks to see if a MMD is present in the package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * @prtad: PHY package address on the MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * @devad: PHY device (MMD) address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * Read the MDIO_STAT2 register, and check whether a device is responding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * at this address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * Returns: negative error number on bus access error, zero if no device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * is responding, or positive if a device is present.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) static int phy_c45_probe_present(struct mii_bus *bus, int prtad, int devad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int stat2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) stat2 = mdiobus_c45_read(bus, prtad, devad, MDIO_STAT2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (stat2 < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return stat2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) return (stat2 & MDIO_STAT2_DEVPRST) == MDIO_STAT2_DEVPRST_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) /* get_phy_c45_devs_in_pkg - reads a MMD's devices in package registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) * @addr: PHY address on the MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) * @dev_addr: MMD address in the PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) * @devices_in_package: where to store the devices in package information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * Description: reads devices in package registers of a MMD at @dev_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * from PHY at @addr on @bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) * Returns: 0 on success, -EIO on failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) static int get_phy_c45_devs_in_pkg(struct mii_bus *bus, int addr, int dev_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) u32 *devices_in_package)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) phy_reg = mdiobus_c45_read(bus, addr, dev_addr, MDIO_DEVS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) *devices_in_package = phy_reg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) phy_reg = mdiobus_c45_read(bus, addr, dev_addr, MDIO_DEVS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) *devices_in_package |= phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * get_phy_c45_ids - reads the specified addr for its 802.3-c45 IDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * @addr: PHY address on the MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * @c45_ids: where to store the c45 ID information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * Read the PHY "devices in package". If this appears to be valid, read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * the PHY identifiers for each device. Return the "devices in package"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * and identifiers in @c45_ids.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) * Returns zero on success, %-EIO on bus access error, or %-ENODEV if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * the "devices in package" is invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) static int get_phy_c45_ids(struct mii_bus *bus, int addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct phy_c45_device_ids *c45_ids)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) const int num_ids = ARRAY_SIZE(c45_ids->device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) u32 devs_in_pkg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) int i, ret, phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* Find first non-zero Devices In package. Device zero is reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) * for 802.3 c45 complied PHYs, so don't probe it at first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) for (i = 1; i < MDIO_MMD_NUM && (devs_in_pkg == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) (devs_in_pkg & 0x1fffffff) == 0x1fffffff); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) /* Check that there is a device present at this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * address before reading the devices-in-package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * register to avoid reading garbage from the PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * Some PHYs (88x3310) vendor space is not IEEE802.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * compliant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ret = phy_c45_probe_present(bus, addr, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) phy_reg = get_phy_c45_devs_in_pkg(bus, addr, i, &devs_in_pkg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* If mostly Fs, there is no device there, then let's probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) * MMD 0, as some 10G PHYs have zero Devices In package,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) * e.g. Cortina CS4315/CS4340 PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) phy_reg = get_phy_c45_devs_in_pkg(bus, addr, 0, &devs_in_pkg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* no device there, let's get out of here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if ((devs_in_pkg & 0x1fffffff) == 0x1fffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /* Now probe Device Identifiers for each device present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) for (i = 1; i < num_ids; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (!(devs_in_pkg & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (i == MDIO_MMD_VEND1 || i == MDIO_MMD_VEND2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Probe the "Device Present" bits for the vendor MMDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * to ignore these if they do not contain IEEE 802.3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ret = phy_c45_probe_present(bus, addr, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) phy_reg = mdiobus_c45_read(bus, addr, i, MII_PHYSID1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) c45_ids->device_ids[i] = phy_reg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) phy_reg = mdiobus_c45_read(bus, addr, i, MII_PHYSID2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (phy_reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) c45_ids->device_ids[i] |= phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) c45_ids->devices_in_package = devs_in_pkg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* Bit 0 doesn't represent a device, it indicates c22 regs presence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) c45_ids->mmds_present = devs_in_pkg & ~BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) * get_phy_c22_id - reads the specified addr for its clause 22 ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) * @addr: PHY address on the MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) * @phy_id: where to store the ID retrieved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) * Read the 802.3 clause 22 PHY ID from the PHY at @addr on the @bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) * placing it in @phy_id. Return zero on successful read and the ID is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) * valid, %-EIO on bus access error, or %-ENODEV if no device responds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * or invalid ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static int get_phy_c22_id(struct mii_bus *bus, int addr, u32 *phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) int phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) /* Grab the bits from PHYIR1, and put them in the upper half */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) phy_reg = mdiobus_read(bus, addr, MII_PHYSID1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (phy_reg < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* returning -ENODEV doesn't stop bus scanning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) *phy_id = phy_reg << 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* Grab the bits from PHYIR2, and put them in the lower half */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) phy_reg = mdiobus_read(bus, addr, MII_PHYSID2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (phy_reg < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* returning -ENODEV doesn't stop bus scanning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return (phy_reg == -EIO || phy_reg == -ENODEV) ? -ENODEV : -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) *phy_id |= phy_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* If the phy_id is mostly Fs, there is no device there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) if ((*phy_id & 0x1fffffff) == 0x1fffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * get_phy_device - reads the specified PHY device and returns its @phy_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * @addr: PHY address on the MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) * @is_c45: If true the PHY uses the 802.3 clause 45 protocol
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * Probe for a PHY at @addr on @bus.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * When probing for a clause 22 PHY, then read the ID registers. If we find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * a valid ID, allocate and return a &struct phy_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * When probing for a clause 45 PHY, read the "devices in package" registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * If the "devices in package" appears valid, read the ID registers for each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * MMD, allocate and return a &struct phy_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * Returns an allocated &struct phy_device on success, %-ENODEV if there is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * no PHY present, or %-EIO on bus access error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct phy_device *get_phy_device(struct mii_bus *bus, int addr, bool is_c45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) struct phy_c45_device_ids c45_ids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) u32 phy_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) c45_ids.devices_in_package = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) c45_ids.mmds_present = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) memset(c45_ids.device_ids, 0xff, sizeof(c45_ids.device_ids));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (is_c45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) r = get_phy_c45_ids(bus, addr, &c45_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) r = get_phy_c22_id(bus, addr, &phy_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) if (r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) return ERR_PTR(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return phy_device_create(bus, addr, phy_id, is_c45, &c45_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) EXPORT_SYMBOL(get_phy_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * phy_device_register - Register the phy device on the MDIO bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * @phydev: phy_device structure to be added to the MDIO bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) int phy_device_register(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) err = mdiobus_register_device(&phydev->mdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* Deassert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) phy_device_reset(phydev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) /* Run all of the fixups for this PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) err = phy_scan_fixups(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) phydev_err(phydev, "failed to initialize\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) err = device_add(&phydev->mdio.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) phydev_err(phydev, "failed to add\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /* Assert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) mdiobus_unregister_device(&phydev->mdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) EXPORT_SYMBOL(phy_device_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * phy_device_remove - Remove a previously registered phy device from the MDIO bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * @phydev: phy_device structure to remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * This doesn't free the phy_device itself, it merely reverses the effects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) * of phy_device_register(). Use phy_device_free() to free the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) * after calling this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) void phy_device_remove(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) if (phydev->mii_ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) unregister_mii_timestamper(phydev->mii_ts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) device_del(&phydev->mdio.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) /* Assert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) mdiobus_unregister_device(&phydev->mdio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) EXPORT_SYMBOL(phy_device_remove);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * phy_find_first - finds the first PHY device on the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * @bus: the target MII bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) struct phy_device *phy_find_first(struct mii_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) for (addr = 0; addr < PHY_MAX_ADDR; addr++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) phydev = mdiobus_get_phy(bus, addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) if (phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) EXPORT_SYMBOL(phy_find_first);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) static void phy_link_change(struct phy_device *phydev, bool up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct net_device *netdev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) netif_carrier_on(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) netif_carrier_off(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) phydev->adjust_link(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) if (phydev->mii_ts && phydev->mii_ts->link_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) phydev->mii_ts->link_state(phydev->mii_ts, phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) * phy_prepare_link - prepares the PHY layer to monitor link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) * @handler: callback function for link status change notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * Description: Tells the PHY infrastructure to handle the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) * gory details on monitoring link status (whether through
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) * polling or an interrupt), and to call back to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) * connected device driver when the link status changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) * If you want to monitor your own link state, don't call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * this function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static void phy_prepare_link(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) void (*handler)(struct net_device *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) phydev->adjust_link = handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) * phy_connect_direct - connect an ethernet device to a specific phy_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * @dev: the network device to connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) * @phydev: the pointer to the phy device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * @handler: callback function for state change notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * @interface: PHY device's interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int phy_connect_direct(struct net_device *dev, struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) void (*handler)(struct net_device *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) phy_prepare_link(phydev, handler);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (phy_interrupt_is_valid(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) phy_request_interrupt(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) EXPORT_SYMBOL(phy_connect_direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * phy_connect - connect an ethernet device to a PHY device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) * @dev: the network device to connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * @bus_id: the id string of the PHY device to connect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * @handler: callback function for state change notifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * @interface: PHY device's interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * Description: Convenience function for connecting ethernet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * devices to PHY devices. The default behavior is for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * the PHY infrastructure to handle everything, and only notify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * the connected driver when the link status changes. If you
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * don't want, or can't use the provided functionality, you may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * choose to call only the subset of functions which provide
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * the desired functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct phy_device *phy_connect(struct net_device *dev, const char *bus_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) void (*handler)(struct net_device *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct device *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /* Search the list of PHY devices on the mdio bus for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * PHY with the requested name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) d = bus_find_device_by_name(&mdio_bus_type, NULL, bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) if (!d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) pr_err("PHY %s not found\n", bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) phydev = to_phy_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) rc = phy_connect_direct(dev, phydev, handler, interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) put_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) return phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) EXPORT_SYMBOL(phy_connect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * phy_disconnect - disable interrupts, stop state machine, and detach a PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) void phy_disconnect(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (phy_is_started(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) phy_stop(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (phy_interrupt_is_valid(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) phy_free_interrupt(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) phydev->adjust_link = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) phy_detach(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) EXPORT_SYMBOL(phy_disconnect);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) * phy_poll_reset - Safely wait until a PHY reset has properly completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * @phydev: The PHY device to poll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) * Description: According to IEEE 802.3, Section 2, Subsection 22.2.4.1.1, as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * published in 2008, a PHY reset may take up to 0.5 seconds. The MII BMCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) * register must be polled until the BMCR_RESET bit clears.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) * Furthermore, any attempts to write to PHY registers may have no effect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) * or even generate MDIO bus errors until this is complete.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) * Some PHYs (such as the Marvell 88E1111) don't entirely conform to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * standard and do not fully reset after the BMCR_RESET bit is set, and may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * even *REQUIRE* a soft-reset to properly restart autonegotiation. In an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * effort to support such broken PHYs, this function is separate from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * standard phy_init_hw() which will zero all the other bits in the BMCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) * and reapply all driver-specific and board-specific fixups.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static int phy_poll_reset(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) /* Poll until the reset bit clears (50ms per retry == 0.6 sec) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 50000, 600000, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /* Some chips (smsc911x) may still need up to another 1ms after the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * BMCR_RESET bit is cleared before they are usable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) int phy_init_hw(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /* Deassert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) phy_device_reset(phydev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) if (!phydev->drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (phydev->drv->soft_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) ret = phydev->drv->soft_reset(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) /* see comment in genphy_soft_reset for an explanation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) phydev->suspended = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) ret = phy_scan_fixups(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (phydev->drv->config_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) ret = phydev->drv->config_init(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) if (phydev->drv->config_intr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) ret = phydev->drv->config_intr(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) EXPORT_SYMBOL(phy_init_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) void phy_attached_info(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) phy_attached_print(phydev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) EXPORT_SYMBOL(phy_attached_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) #define ATTACHED_FMT "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%s)"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) char *phy_attached_info_irq(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) char *irq_str;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) char irq_num[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) switch(phydev->irq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) case PHY_POLL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) irq_str = "POLL";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) case PHY_IGNORE_INTERRUPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) irq_str = "IGNORE";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) snprintf(irq_num, sizeof(irq_num), "%d", phydev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) irq_str = irq_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return kasprintf(GFP_KERNEL, "%s", irq_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) EXPORT_SYMBOL(phy_attached_info_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) void phy_attached_print(struct phy_device *phydev, const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) const char *drv_name = phydev->drv ? phydev->drv->name : "unbound";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) char *irq_str = phy_attached_info_irq(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) if (!fmt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) phydev_info(phydev, ATTACHED_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) drv_name, phydev_name(phydev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) irq_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) va_list ap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) phydev_info(phydev, ATTACHED_FMT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) drv_name, phydev_name(phydev),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) irq_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) va_start(ap, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) vprintk(fmt, ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) va_end(ap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) kfree(irq_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) EXPORT_SYMBOL(phy_attached_print);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) static void phy_sysfs_create_links(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct net_device *dev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) err = sysfs_create_link(&phydev->mdio.dev.kobj, &dev->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) "attached_dev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) err = sysfs_create_link_nowarn(&dev->dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) &phydev->mdio.dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) "phydev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) dev_err(&dev->dev, "could not add device link to %s err %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) kobject_name(&phydev->mdio.dev.kobj),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /* non-fatal - some net drivers can use one netdevice
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * with more then one phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) phydev->sysfs_links = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) static ssize_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) phy_standalone_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return sprintf(buf, "%d\n", !phydev->attached_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) static DEVICE_ATTR_RO(phy_standalone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) * phy_sfp_attach - attach the SFP bus to the PHY upstream network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) * @upstream: pointer to the phy device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) * @bus: sfp bus representing cage being attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * This is used to fill in the sfp_upstream_ops .attach member.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) void phy_sfp_attach(void *upstream, struct sfp_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct phy_device *phydev = upstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (phydev->attached_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) phydev->attached_dev->sfp_bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) phydev->sfp_bus_attached = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) EXPORT_SYMBOL(phy_sfp_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) * phy_sfp_detach - detach the SFP bus from the PHY upstream network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * @upstream: pointer to the phy device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) * @bus: sfp bus representing cage being attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) * This is used to fill in the sfp_upstream_ops .detach member.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) void phy_sfp_detach(void *upstream, struct sfp_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) struct phy_device *phydev = upstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (phydev->attached_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) phydev->attached_dev->sfp_bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) phydev->sfp_bus_attached = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) EXPORT_SYMBOL(phy_sfp_detach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * phy_sfp_probe - probe for a SFP cage attached to this PHY device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) * @phydev: Pointer to phy_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) * @ops: SFP's upstream operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) int phy_sfp_probe(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) const struct sfp_upstream_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct sfp_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) if (phydev->mdio.dev.fwnode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) bus = sfp_bus_find_fwnode(phydev->mdio.dev.fwnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) if (IS_ERR(bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return PTR_ERR(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) phydev->sfp_bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) ret = sfp_bus_add_upstream(bus, phydev, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) sfp_bus_put(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) EXPORT_SYMBOL(phy_sfp_probe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) * phy_attach_direct - attach a network device to a given PHY device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) * @dev: network device to attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) * @phydev: Pointer to phy_device to attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) * @flags: PHY device's dev_flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) * @interface: PHY device's interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) * Description: Called by drivers to attach to a particular PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) * device. The phy_device is found, and properly hooked up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) * to the phy_driver. If no driver is attached, then a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) * generic driver is used. The phy_device is given a ptr to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) * the attaching device, and given a callback for link status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) * change. The phy_device is returned to the attaching driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) * This function takes a reference on the phy device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) u32 flags, phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) struct mii_bus *bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) struct device *d = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) struct module *ndev_owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) bool using_genphy = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /* For Ethernet device drivers that register their own MDIO bus, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * will have bus->owner match ndev_mod, so we do not want to increment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * our own module->refcnt here, otherwise we would not be able to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * unload later on.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) ndev_owner = dev->dev.parent->driver->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) if (ndev_owner != bus->owner && !try_module_get(bus->owner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) phydev_err(phydev, "failed to get the bus module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) get_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) /* Assume that if there is no driver, that it doesn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) * exist, and we should use the genphy driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (!d->driver) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) if (phydev->is_c45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) d->driver = &genphy_c45_driver.mdiodrv.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) d->driver = &genphy_driver.mdiodrv.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) using_genphy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if (!try_module_get(d->driver->owner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) phydev_err(phydev, "failed to get the device driver module\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) err = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) goto error_put_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) if (using_genphy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) err = d->driver->probe(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) if (err >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) err = device_bind_driver(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) goto error_module_put;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) if (phydev->attached_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) dev_err(&dev->dev, "PHY already attached\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) err = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) phydev->phy_link_change = phy_link_change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) phydev->attached_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) dev->phydev = phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) if (phydev->sfp_bus_attached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) dev->sfp_bus = phydev->sfp_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) /* Some Ethernet drivers try to connect to a PHY device before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) * calling register_netdevice() -> netdev_register_kobject() and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) * does the dev->dev.kobj initialization. Here we only check for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) * success which indicates that the network device kobject is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) * ready. Once we do that we still need to keep track of whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) * links were successfully set up or not for phy_detach() to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) * remove them accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) phydev->sysfs_links = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) phy_sysfs_create_links(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) if (!phydev->attached_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) err = sysfs_create_file(&phydev->mdio.dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) &dev_attr_phy_standalone.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) phydev_err(phydev, "error creating 'phy_standalone' sysfs entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) phydev->dev_flags |= flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) phydev->interface = interface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) phydev->state = PHY_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* Port is set to PORT_TP by default and the actual PHY driver will set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) * it to different value depending on the PHY configuration. If we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) * the generic PHY driver we can't figure it out, thus set the old
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) * legacy PORT_MII value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (using_genphy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) phydev->port = PORT_MII;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) /* Initial carrier state is off as the phy is about to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * (re)initialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) netif_carrier_off(phydev->attached_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) /* Do initial configuration here, now that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) * we have certain key parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) * (dev_flags and interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) err = phy_init_hw(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) err = phy_disable_interrupts(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) phy_resume(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) phy_led_triggers_register(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) /* phy_detach() does all of the cleanup below */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) phy_detach(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) error_module_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) module_put(d->driver->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) error_put_device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) put_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (ndev_owner != bus->owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) module_put(bus->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) EXPORT_SYMBOL(phy_attach_direct);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) * phy_attach - attach a network device to a particular PHY device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * @dev: network device to attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) * @bus_id: Bus ID of PHY device to attach
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) * @interface: PHY device's interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * Description: Same as phy_attach_direct() except that a PHY bus_id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * string is passed instead of a pointer to a struct phy_device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) phy_interface_t interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) struct bus_type *bus = &mdio_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) struct device *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) return ERR_PTR(-EINVAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* Search the list of PHY devices on the mdio bus for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * PHY with the requested name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) d = bus_find_device_by_name(bus, NULL, bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) if (!d) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) pr_err("PHY %s not found\n", bus_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) phydev = to_phy_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) put_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) return ERR_PTR(rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) return phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) EXPORT_SYMBOL(phy_attach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) static bool phy_driver_is_genphy_kind(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) struct device_driver *driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) struct device *d = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (!phydev->drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) get_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) ret = d->driver == driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) put_device(d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) bool phy_driver_is_genphy(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) return phy_driver_is_genphy_kind(phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) &genphy_driver.mdiodrv.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) EXPORT_SYMBOL_GPL(phy_driver_is_genphy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) bool phy_driver_is_genphy_10g(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return phy_driver_is_genphy_kind(phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) &genphy_c45_driver.mdiodrv.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) EXPORT_SYMBOL_GPL(phy_driver_is_genphy_10g);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) * phy_package_join - join a common PHY group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) * @addr: cookie and PHY address for global register access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) * @priv_size: if non-zero allocate this amount of bytes for private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) * This joins a PHY group and provides a shared storage for all phydevs in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) * this group. This is intended to be used for packages which contain
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) * more than one PHY, for example a quad PHY transceiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) * The addr parameter serves as a cookie which has to have the same value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) * for all members of one group and as a PHY address to access generic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) * registers of a PHY package. Usually, one of the PHY addresses of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) * different PHYs in the package provides access to these global registers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) * The address which is given here, will be used in the phy_package_read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) * and phy_package_write() convenience functions. If your PHY doesn't have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) * global registers you can just pick any of the PHY addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * This will set the shared pointer of the phydev to the shared storage.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * If this is the first call for a this cookie the shared storage will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * allocated. If priv_size is non-zero, the given amount of bytes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * allocated for the priv member.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * Returns < 1 on error, 0 on success. Esp. calling phy_package_join()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * with the same cookie but a different priv_size is an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) int phy_package_join(struct phy_device *phydev, int addr, size_t priv_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) struct mii_bus *bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) struct phy_package_shared *shared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) if (addr < 0 || addr >= PHY_MAX_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) mutex_lock(&bus->shared_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) shared = bus->shared[addr];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) if (!shared) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) shared = kzalloc(sizeof(*shared), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) if (!shared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) if (priv_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) shared->priv = kzalloc(priv_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (!shared->priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) goto err_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) shared->priv_size = priv_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) shared->addr = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) refcount_set(&shared->refcnt, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) bus->shared[addr] = shared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (priv_size && priv_size != shared->priv_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) refcount_inc(&shared->refcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) mutex_unlock(&bus->shared_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) phydev->shared = shared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) err_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) kfree(shared);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) mutex_unlock(&bus->shared_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) EXPORT_SYMBOL_GPL(phy_package_join);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * phy_package_leave - leave a common PHY group
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) * This leaves a PHY group created by phy_package_join(). If this phydev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * was the last user of the shared data between the group, this data is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) * freed. Resets the phydev->shared pointer to NULL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) void phy_package_leave(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) struct phy_package_shared *shared = phydev->shared;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) struct mii_bus *bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (!shared)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) if (refcount_dec_and_mutex_lock(&shared->refcnt, &bus->shared_lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) bus->shared[shared->addr] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) mutex_unlock(&bus->shared_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) kfree(shared->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) kfree(shared);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) phydev->shared = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) EXPORT_SYMBOL_GPL(phy_package_leave);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) static void devm_phy_package_leave(struct device *dev, void *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) phy_package_leave(*(struct phy_device **)res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) * devm_phy_package_join - resource managed phy_package_join()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) * @dev: device that is registering this PHY package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) * @addr: cookie and PHY address for global register access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) * @priv_size: if non-zero allocate this amount of bytes for private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) * Managed phy_package_join(). Shared storage fetched by this function,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) * phy_package_leave() is automatically called on driver detach. See
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) * phy_package_join() for more information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) int devm_phy_package_join(struct device *dev, struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) int addr, size_t priv_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) struct phy_device **ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) ptr = devres_alloc(devm_phy_package_leave, sizeof(*ptr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) if (!ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ret = phy_package_join(phydev, addr, priv_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) *ptr = phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) devres_add(dev, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) devres_free(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) EXPORT_SYMBOL_GPL(devm_phy_package_join);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) * phy_detach - detach a PHY device from its network device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) * This detaches the phy device from its network device and the phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * driver, and drops the reference count taken in phy_attach_direct().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) void phy_detach(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) struct net_device *dev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) struct module *ndev_owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) struct mii_bus *bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) if (phydev->sysfs_links) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) sysfs_remove_link(&dev->dev.kobj, "phydev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) sysfs_remove_link(&phydev->mdio.dev.kobj, "attached_dev");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (!phydev->attached_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) sysfs_remove_file(&phydev->mdio.dev.kobj,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) &dev_attr_phy_standalone.attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) phy_suspend(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) phydev->attached_dev->phydev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) phydev->attached_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) phydev->phylink = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) phy_led_triggers_unregister(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (phydev->mdio.dev.driver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) module_put(phydev->mdio.dev.driver->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) /* If the device had no specific driver before (i.e. - it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) * was using the generic driver), we unbind the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) * from the generic driver so that there's a chance a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) * real driver could be loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) if (phy_driver_is_genphy(phydev) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) phy_driver_is_genphy_10g(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) device_release_driver(&phydev->mdio.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) /* Assert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) * The phydev might go away on the put_device() below, so avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) * a use-after-free bug by reading the underlying bus first.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) put_device(&phydev->mdio.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) ndev_owner = dev->dev.parent->driver->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (ndev_owner != bus->owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) module_put(bus->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) EXPORT_SYMBOL(phy_detach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) int phy_suspend(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) struct net_device *netdev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) struct phy_driver *phydrv = phydev->drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (phydev->suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) /* If the device has WOL enabled, we cannot suspend the PHY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) phy_ethtool_get_wol(phydev, &wol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) if (wol.wolopts || (netdev && netdev->wol_enabled))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) if (!phydrv || !phydrv->suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) ret = phydrv->suspend(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) phydev->suspended = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) EXPORT_SYMBOL(phy_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) int __phy_resume(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) struct phy_driver *phydrv = phydev->drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) WARN_ON(!mutex_is_locked(&phydev->lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) if (!phydrv || !phydrv->resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) ret = phydrv->resume(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) phydev->suspended = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) EXPORT_SYMBOL(__phy_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) int phy_resume(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) mutex_lock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) ret = __phy_resume(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) mutex_unlock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) EXPORT_SYMBOL(phy_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) int phy_loopback(struct phy_device *phydev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) struct phy_driver *phydrv = to_phy_driver(phydev->mdio.dev.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) mutex_lock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) if (enable && phydev->loopback_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) if (!enable && !phydev->loopback_enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) if (phydev->drv && phydrv->set_loopback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) ret = phydrv->set_loopback(phydev, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) phydev->loopback_enabled = enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) mutex_unlock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) EXPORT_SYMBOL(phy_loopback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) * phy_reset_after_clk_enable - perform a PHY reset if needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) * Description: Some PHYs are known to need a reset after their refclk was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) * enabled. This function evaluates the flags and perform the reset if it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) * needed. Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) * was reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) int phy_reset_after_clk_enable(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (!phydev || !phydev->drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) phy_device_reset(phydev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) EXPORT_SYMBOL(phy_reset_after_clk_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) /* Generic PHY support and helper functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) * genphy_config_advert - sanitize and advertise auto-negotiation parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) * Description: Writes MII_ADVERTISE with the appropriate values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * after sanitizing the values to make sure we only advertise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * hasn't changed, and > 0 if it has changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) static int genphy_config_advert(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) int err, bmsr, changed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) u32 adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /* Only allow advertising what this PHY supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) linkmode_and(phydev->advertising, phydev->advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) adv = linkmode_adv_to_mii_adv_t(phydev->advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) /* Setup standard advertisement */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) err = phy_modify_changed(phydev, MII_ADVERTISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) ADVERTISE_ALL | ADVERTISE_100BASE4 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) bmsr = phy_read(phydev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) if (bmsr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) return bmsr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * logical 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) if (!(bmsr & BMSR_ESTATEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) adv = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) err = phy_modify_changed(phydev, MII_CTRL1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) ADVERTISE_1000FULL | ADVERTISE_1000HALF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (err > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) changed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) * genphy_c37_config_advert - sanitize and advertise auto-negotiation parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * Description: Writes MII_ADVERTISE with the appropriate values,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) * after sanitizing the values to make sure we only advertise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) * what is supported. Returns < 0 on error, 0 if the PHY's advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) * hasn't changed, and > 0 if it has changed. This function is intended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) * for Clause 37 1000Base-X mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) static int genphy_c37_config_advert(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) u16 adv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /* Only allow advertising what this PHY supports */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) linkmode_and(phydev->advertising, phydev->advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) phydev->advertising))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) adv |= ADVERTISE_1000XFULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) phydev->advertising))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) adv |= ADVERTISE_1000XPAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) phydev->advertising))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) adv |= ADVERTISE_1000XPSE_ASYM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) return phy_modify_changed(phydev, MII_ADVERTISE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) ADVERTISE_1000XHALF | ADVERTISE_1000XPSE_ASYM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) adv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) * genphy_config_eee_advert - disable unwanted eee mode advertisement
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) * Description: Writes MDIO_AN_EEE_ADV after disabling unsupported energy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) * efficent ethernet modes. Returns 0 if the PHY's advertisement hasn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) * changed, and 1 if it has changed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) int genphy_config_eee_advert(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /* Nothing to disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) if (!phydev->eee_broken_modes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) err = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) phydev->eee_broken_modes, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) /* If the call failed, we assume that EEE is not supported */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) return err < 0 ? 0 : err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) EXPORT_SYMBOL(genphy_config_eee_advert);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) * genphy_setup_forced - configures/forces speed/duplex from @phydev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) * Description: Configures MII_BMCR to force speed/duplex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) * to the values in phydev. Assumes that the values are valid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) * Please see phy_sanitize_settings().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) int genphy_setup_forced(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) u16 ctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) phydev->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) phydev->asym_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) if (SPEED_1000 == phydev->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) ctl |= BMCR_SPEED1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) else if (SPEED_100 == phydev->speed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) ctl |= BMCR_SPEED100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) if (DUPLEX_FULL == phydev->duplex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) ctl |= BMCR_FULLDPLX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) return phy_modify(phydev, MII_BMCR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) ~(BMCR_LOOPBACK | BMCR_ISOLATE | BMCR_PDOWN), ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) EXPORT_SYMBOL(genphy_setup_forced);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) static int genphy_setup_master_slave(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) u16 ctl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) if (!phydev->is_gigabit_capable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) switch (phydev->master_slave_set) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) case MASTER_SLAVE_CFG_MASTER_PREFERRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) ctl |= CTL1000_PREFER_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) case MASTER_SLAVE_CFG_SLAVE_PREFERRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) case MASTER_SLAVE_CFG_MASTER_FORCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) ctl |= CTL1000_AS_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) case MASTER_SLAVE_CFG_SLAVE_FORCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) ctl |= CTL1000_ENABLE_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) case MASTER_SLAVE_CFG_UNKNOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) case MASTER_SLAVE_CFG_UNSUPPORTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) phydev_warn(phydev, "Unsupported Master/Slave mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) return phy_modify_changed(phydev, MII_CTRL1000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) (CTL1000_ENABLE_MASTER | CTL1000_AS_MASTER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) CTL1000_PREFER_MASTER), ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) static int genphy_read_master_slave(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) int cfg, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (!phydev->is_gigabit_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) phydev->master_slave_get = MASTER_SLAVE_CFG_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) phydev->master_slave_state = MASTER_SLAVE_STATE_UNSUPPORTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) val = phy_read(phydev, MII_CTRL1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) if (val & CTL1000_ENABLE_MASTER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) if (val & CTL1000_AS_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) if (val & CTL1000_PREFER_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) cfg = MASTER_SLAVE_CFG_MASTER_PREFERRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) cfg = MASTER_SLAVE_CFG_SLAVE_PREFERRED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) val = phy_read(phydev, MII_STAT1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) if (val & LPA_1000MSFAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) state = MASTER_SLAVE_STATE_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) } else if (phydev->link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) /* this bits are valid only for active link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) if (val & LPA_1000MSRES)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) state = MASTER_SLAVE_STATE_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) state = MASTER_SLAVE_STATE_SLAVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) state = MASTER_SLAVE_STATE_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) phydev->master_slave_get = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) phydev->master_slave_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) * genphy_restart_aneg - Enable and Restart Autonegotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) int genphy_restart_aneg(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) /* Don't isolate the PHY if we're negotiating */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) return phy_modify(phydev, MII_BMCR, BMCR_ISOLATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) BMCR_ANENABLE | BMCR_ANRESTART);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) EXPORT_SYMBOL(genphy_restart_aneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) * genphy_check_and_restart_aneg - Enable and restart auto-negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * @restart: whether aneg restart is requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) * Check, and restart auto-negotiation if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) int genphy_check_and_restart_aneg(struct phy_device *phydev, bool restart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) if (!restart) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) /* Advertisement hasn't changed, but maybe aneg was never on to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) * begin with? Or maybe phy was isolated?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) ret = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (!(ret & BMCR_ANENABLE) || (ret & BMCR_ISOLATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) restart = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) if (restart)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) return genphy_restart_aneg(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) EXPORT_SYMBOL(genphy_check_and_restart_aneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) * __genphy_config_aneg - restart auto-negotiation or write BMCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) * @changed: whether autoneg is requested
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) * Description: If auto-negotiation is enabled, we configure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) * advertising, and then restart auto-negotiation. If it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) * enabled, then we write the BMCR.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) int __genphy_config_aneg(struct phy_device *phydev, bool changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) if (genphy_config_eee_advert(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) err = genphy_setup_master_slave(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) else if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) if (AUTONEG_ENABLE != phydev->autoneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) return genphy_setup_forced(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) err = genphy_config_advert(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (err < 0) /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) else if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) changed = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) return genphy_check_and_restart_aneg(phydev, changed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) EXPORT_SYMBOL(__genphy_config_aneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * genphy_c37_config_aneg - restart auto-negotiation or write BMCR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) * Description: If auto-negotiation is enabled, we configure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) * advertising, and then restart auto-negotiation. If it is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) * enabled, then we write the BMCR. This function is intended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) * for use with Clause 37 1000Base-X mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) int genphy_c37_config_aneg(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) int err, changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) if (phydev->autoneg != AUTONEG_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) return genphy_setup_forced(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) err = phy_modify(phydev, MII_BMCR, BMCR_SPEED1000 | BMCR_SPEED100,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) BMCR_SPEED1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) changed = genphy_c37_config_advert(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) if (changed < 0) /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) return changed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) if (!changed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) /* Advertisement hasn't changed, but maybe aneg was never on to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) * begin with? Or maybe phy was isolated?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) int ctl = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) if (ctl < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) return ctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) changed = 1; /* do restart aneg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) /* Only restart aneg if we are advertising something different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) * than we were before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) if (changed > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) return genphy_restart_aneg(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) EXPORT_SYMBOL(genphy_c37_config_aneg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * genphy_aneg_done - return auto-negotiation status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * Description: Reads the status register and returns 0 either if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * auto-negotiation is incomplete, or if there was an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) int genphy_aneg_done(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) int retval = phy_read(phydev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) EXPORT_SYMBOL(genphy_aneg_done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) * genphy_update_link - update link status in @phydev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) * Description: Update the value in phydev->link to reflect the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244) * current link value. In order to do this, we need to read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) * the status register twice, keeping the second value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) int genphy_update_link(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) int status = 0, bmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) bmcr = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) if (bmcr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) return bmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* Autoneg is being started, therefore disregard BMSR value and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) * report link as down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) if (bmcr & BMCR_ANRESTART)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) /* The link state is latched low so that momentary link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) * drops can be detected. Do not double-read the status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) * in polling mode to detect such short link drops except
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) * the link was already down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) if (!phy_polling_mode(phydev) || !phydev->link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) status = phy_read(phydev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) else if (status & BMSR_LSTATUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) /* Read link and autonegotiation status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) status = phy_read(phydev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) if (status < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) phydev->link = status & BMSR_LSTATUS ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) phydev->autoneg_complete = status & BMSR_ANEGCOMPLETE ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) /* Consider the case that autoneg was started and "aneg complete"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) * bit has been reset, but "link up" bit not yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) phydev->link = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) EXPORT_SYMBOL(genphy_update_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) int genphy_read_lpa(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) int lpa, lpagb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) if (phydev->autoneg == AUTONEG_ENABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) if (!phydev->autoneg_complete) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) if (phydev->is_gigabit_capable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) lpagb = phy_read(phydev, MII_STAT1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) if (lpagb < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) return lpagb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) if (lpagb & LPA_1000MSFAIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) int adv = phy_read(phydev, MII_CTRL1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) if (adv < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) return adv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) if (adv & CTL1000_ENABLE_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) phydev_err(phydev, "Master/Slave resolution failed, maybe conflicting manual settings?\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) phydev_err(phydev, "Master/Slave resolution failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) return -ENOLINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) lpagb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) lpa = phy_read(phydev, MII_LPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) if (lpa < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) return lpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) mii_lpa_mod_linkmode_lpa_t(phydev->lp_advertising, lpa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) linkmode_zero(phydev->lp_advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) EXPORT_SYMBOL(genphy_read_lpa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) * genphy_read_status_fixed - read the link parameters for !aneg mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) * Read the current duplex and speed state for a PHY operating with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) * autonegotiation disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) int genphy_read_status_fixed(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) int bmcr = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) if (bmcr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) return bmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) if (bmcr & BMCR_FULLDPLX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) phydev->duplex = DUPLEX_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) phydev->duplex = DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) if (bmcr & BMCR_SPEED1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) phydev->speed = SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) else if (bmcr & BMCR_SPEED100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) phydev->speed = SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) phydev->speed = SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) EXPORT_SYMBOL(genphy_read_status_fixed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) * genphy_read_status - check the link status and update current link state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) * Description: Check the link, then figure out the current state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) * by comparing what we advertise with what the link partner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) * advertises. Start by checking the gigabit possibilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) * then move on to 10/100.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) int genphy_read_status(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) int err, old_link = phydev->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) /* Update the link, but return if there was an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) err = genphy_update_link(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) /* why bother the PHY if nothing can have changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) phydev->speed = SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) phydev->duplex = DUPLEX_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) phydev->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) phydev->asym_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) err = genphy_read_master_slave(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) err = genphy_read_lpa(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) phy_resolve_aneg_linkmode(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) } else if (phydev->autoneg == AUTONEG_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) err = genphy_read_status_fixed(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) EXPORT_SYMBOL(genphy_read_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) * genphy_c37_read_status - check the link status and update current link state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * Description: Check the link, then figure out the current state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) * by comparing what we advertise with what the link partner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) * advertises. This function is for Clause 37 1000Base-X mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) int genphy_c37_read_status(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) int lpa, err, old_link = phydev->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) /* Update the link, but return if there was an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) err = genphy_update_link(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) /* why bother the PHY if nothing can have changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) phydev->duplex = DUPLEX_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) phydev->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) phydev->asym_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) lpa = phy_read(phydev, MII_LPA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) if (lpa < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) return lpa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) phydev->lp_advertising, lpa & LPA_LPACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) phydev->lp_advertising, lpa & LPA_1000XFULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) phydev->lp_advertising, lpa & LPA_1000XPAUSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) phydev->lp_advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) lpa & LPA_1000XPAUSE_ASYM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) phy_resolve_aneg_linkmode(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) } else if (phydev->autoneg == AUTONEG_DISABLE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) int bmcr = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) if (bmcr < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) return bmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) if (bmcr & BMCR_FULLDPLX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) phydev->duplex = DUPLEX_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) phydev->duplex = DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) EXPORT_SYMBOL(genphy_c37_read_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) * genphy_soft_reset - software reset the PHY via BMCR_RESET bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) * Description: Perform a software PHY reset using the standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) * BMCR_RESET bit and poll for the reset bit to be cleared.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) * Returns: 0 on success, < 0 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) int genphy_soft_reset(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) u16 res = BMCR_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) if (phydev->autoneg == AUTONEG_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) res |= BMCR_ANRESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) ret = phy_modify(phydev, MII_BMCR, BMCR_ISOLATE, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) /* Clause 22 states that setting bit BMCR_RESET sets control registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) * to their default value. Therefore the POWER DOWN bit is supposed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) * be cleared after soft reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) phydev->suspended = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) ret = phy_poll_reset(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) /* BMCR may be reset to defaults */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) if (phydev->autoneg == AUTONEG_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) ret = genphy_setup_forced(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) EXPORT_SYMBOL(genphy_soft_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) * genphy_read_abilities - read PHY abilities from Clause 22 registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) * Description: Reads the PHY's abilities and populates
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) * phydev->supported accordingly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) * Returns: 0 on success, < 0 on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) int genphy_read_abilities(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) linkmode_set_bit_array(phy_basic_ports_array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) ARRAY_SIZE(phy_basic_ports_array),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) val = phy_read(phydev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) val & BMSR_ANEGCAPABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, phydev->supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) val & BMSR_100FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, phydev->supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) val & BMSR_100HALF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, phydev->supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) val & BMSR_10FULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, phydev->supported,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) val & BMSR_10HALF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) if (val & BMSR_ESTATEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) val = phy_read(phydev, MII_ESTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) phydev->supported, val & ESTATUS_1000_TFULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) phydev->supported, val & ESTATUS_1000_THALF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) phydev->supported, val & ESTATUS_1000_XFULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) EXPORT_SYMBOL(genphy_read_abilities);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) /* This is used for the phy device which doesn't support the MMD extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) * register access, but it does have side effect when we are trying to access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) * the MMD register via indirect method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) int genphy_read_mmd_unsupported(struct phy_device *phdev, int devad, u16 regnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) EXPORT_SYMBOL(genphy_read_mmd_unsupported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) int genphy_write_mmd_unsupported(struct phy_device *phdev, int devnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) u16 regnum, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) EXPORT_SYMBOL(genphy_write_mmd_unsupported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) int genphy_suspend(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) return phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) EXPORT_SYMBOL(genphy_suspend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) int genphy_resume(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) EXPORT_SYMBOL(genphy_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) int genphy_loopback(struct phy_device *phydev, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) enable ? BMCR_LOOPBACK : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) EXPORT_SYMBOL(genphy_loopback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) * phy_remove_link_mode - Remove a supported link mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) * @phydev: phy_device structure to remove link mode from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) * @link_mode: Link mode to be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) * Description: Some MACs don't support all link modes which the PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) * does. e.g. a 1G MAC often does not support 1000Half. Add a helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) * to remove a link mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609) linkmode_clear_bit(link_mode, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610) phy_advertise_supported(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) EXPORT_SYMBOL(phy_remove_link_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) static void phy_copy_pause_bits(unsigned long *dst, unsigned long *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT, dst,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT, src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) * phy_advertise_supported - Advertise all supported modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) * Description: Called to advertise all supported modes, doesn't touch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) * pause mode advertising.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) void phy_advertise_supported(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) __ETHTOOL_DECLARE_LINK_MODE_MASK(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) linkmode_copy(new, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) phy_copy_pause_bits(new, phydev->advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) linkmode_copy(phydev->advertising, new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) EXPORT_SYMBOL(phy_advertise_supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) * phy_support_sym_pause - Enable support of symmetrical pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) * Description: Called by the MAC to indicate is supports symmetrical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) * Pause, but not asym pause.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) void phy_support_sym_pause(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) linkmode_clear_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) phy_copy_pause_bits(phydev->advertising, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) EXPORT_SYMBOL(phy_support_sym_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) * phy_support_asym_pause - Enable support of asym pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) * Description: Called by the MAC to indicate is supports Asym Pause.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) void phy_support_asym_pause(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) phy_copy_pause_bits(phydev->advertising, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) EXPORT_SYMBOL(phy_support_asym_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) * phy_set_sym_pause - Configure symmetric Pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) * @rx: Receiver Pause is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) * @tx: Transmit Pause is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) * @autoneg: Auto neg should be used
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) * Description: Configure advertised Pause support depending on if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) * receiver pause and pause auto neg is supported. Generally called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) * from the set_pauseparam .ndo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) void phy_set_sym_pause(struct phy_device *phydev, bool rx, bool tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) bool autoneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) linkmode_clear_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) if (rx && tx && autoneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) linkmode_copy(phydev->advertising, phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) EXPORT_SYMBOL(phy_set_sym_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) * phy_set_asym_pause - Configure Pause and Asym Pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) * @phydev: target phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) * @rx: Receiver Pause is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) * @tx: Transmit Pause is supported
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) * Description: Configure advertised Pause support depending on if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) * transmit and receiver pause is supported. If there has been a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) * change in adverting, trigger a new autoneg. Generally called from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) * the set_pauseparam .ndo.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) void phy_set_asym_pause(struct phy_device *phydev, bool rx, bool tx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) __ETHTOOL_DECLARE_LINK_MODE_MASK(oldadv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) linkmode_copy(oldadv, phydev->advertising);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) linkmode_set_pause(phydev->advertising, tx, rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) if (!linkmode_equal(oldadv, phydev->advertising) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) phydev->autoneg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) phy_start_aneg(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) EXPORT_SYMBOL(phy_set_asym_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) * phy_validate_pause - Test if the PHY/MAC support the pause configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) * @phydev: phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) * @pp: requested pause configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) * Description: Test if the PHY/MAC combination supports the Pause
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) * configuration the user is requesting. Returns True if it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) * supported, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) bool phy_validate_pause(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) struct ethtool_pauseparam *pp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) phydev->supported) && pp->rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) phydev->supported) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) pp->rx_pause != pp->tx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) EXPORT_SYMBOL(phy_validate_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) * phy_get_pause - resolve negotiated pause modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) * @phydev: phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) * @tx_pause: pointer to bool to indicate whether transmit pause should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) * @rx_pause: pointer to bool to indicate whether receive pause should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) * Resolve and return the flow control modes according to the negotiation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) * result. This includes checking that we are operating in full duplex mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) * See linkmode_resolve_pause() for further details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) if (phydev->duplex != DUPLEX_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) *tx_pause = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) *rx_pause = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) return linkmode_resolve_pause(phydev->advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) phydev->lp_advertising,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) tx_pause, rx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) EXPORT_SYMBOL(phy_get_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) #if IS_ENABLED(CONFIG_OF_MDIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) static int phy_get_int_delay_property(struct device *dev, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) s32 int_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) ret = device_property_read_u32(dev, name, &int_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) return int_delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) static int phy_get_int_delay_property(struct device *dev, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) * phy_get_delay_index - returns the index of the internal delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) * @phydev: phy_device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) * @dev: pointer to the devices device struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) * @delay_values: array of delays the PHY supports
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) * @size: the size of the delay array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) * @is_rx: boolean to indicate to get the rx internal delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) * Returns the index within the array of internal delay passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) * If the device property is not present then the interface type is checked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) * if the interface defines use of internal delay then a 1 is returned otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) * a 0 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) * The array must be in ascending order. If PHY does not have an ascending order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) * array then size = 0 and the value of the delay property is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) * Return -EINVAL if the delay is invalid or cannot be found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) const int *delay_values, int size, bool is_rx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) s32 delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) if (is_rx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) delay = phy_get_int_delay_property(dev, "rx-internal-delay-ps");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) if (delay < 0 && size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) delay = phy_get_int_delay_property(dev, "tx-internal-delay-ps");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) if (delay < 0 && size == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) if (delay < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) return delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) if (delay && size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) return delay;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) if (delay < delay_values[0] || delay > delay_values[size - 1]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) phydev_err(phydev, "Delay %d is out of range\n", delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) if (delay == delay_values[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840) for (i = 1; i < size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) if (delay == delay_values[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) /* Find an approximate index by looking up the table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) if (delay > delay_values[i - 1] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) delay < delay_values[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) if (delay - delay_values[i - 1] <
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) delay_values[i] - delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) return i - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) phydev_err(phydev, "error finding internal delay index for %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) EXPORT_SYMBOL(phy_get_internal_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) static bool phy_drv_supports_irq(struct phy_driver *phydrv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) return phydrv->config_intr && phydrv->ack_interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) * phy_probe - probe and init a PHY device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) * @dev: device to probe and init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) * Description: Take care of setting up the phy_device structure,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) * set the state to READY (the driver's init function should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) * set it to STARTING if needed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) static int phy_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) struct device_driver *drv = phydev->mdio.dev.driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) struct phy_driver *phydrv = to_phy_driver(drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) phydev->drv = phydrv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) /* Disable the interrupt if the PHY doesn't support it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) * but the interrupt is still a valid one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) if (!phy_drv_supports_irq(phydrv) && phy_interrupt_is_valid(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) phydev->irq = PHY_POLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) if (phydrv->flags & PHY_IS_INTERNAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) phydev->is_internal = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) mutex_lock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) /* Deassert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) phy_device_reset(phydev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) if (phydev->drv->probe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) err = phydev->drv->probe(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) /* Start out supporting everything. Eventually,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) * a controller will attach, and may modify one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) * or both of these values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) if (phydrv->features) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) linkmode_copy(phydev->supported, phydrv->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) } else if (phydrv->get_features) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) err = phydrv->get_features(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) } else if (phydev->is_c45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) err = genphy_c45_pma_read_abilities(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) err = genphy_read_abilities(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) if (!linkmode_test_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) phydev->supported))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) phydev->autoneg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) phydev->supported))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) phydev->is_gigabit_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) phydev->supported))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) phydev->is_gigabit_capable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) of_set_phy_supported(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) phy_advertise_supported(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) /* Get the EEE modes we want to prohibit. We will ask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) * the PHY stop advertising these mode later on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) of_set_phy_eee_broken(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) /* The Pause Frame bits indicate that the PHY can support passing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) * pause frames. During autonegotiation, the PHYs will determine if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) * they should allow pause frames to pass. The MAC driver should then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) * use that result to determine whether to enable flow control via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) * pause frames.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) * Normally, PHY drivers should not set the Pause bits, and instead
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) * allow phylib to do that. However, there may be some situations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) * (e.g. hardware erratum) where the driver wants to set only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) * of these bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) if (!test_bit(ETHTOOL_LINK_MODE_Pause_BIT, phydev->supported) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) !test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, phydev->supported)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) linkmode_set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) phydev->supported);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) /* Set the state to READY by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) phydev->state = PHY_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) /* Assert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) mutex_unlock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) static int phy_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) struct phy_device *phydev = to_phy_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) cancel_delayed_work_sync(&phydev->state_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) mutex_lock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) phydev->state = PHY_DOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) mutex_unlock(&phydev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) sfp_bus_del_upstream(phydev->sfp_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) phydev->sfp_bus = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) if (phydev->drv && phydev->drv->remove)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) phydev->drv->remove(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) /* Assert the reset signal */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) phydev->drv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) * phy_driver_register - register a phy_driver with the PHY layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) * @new_driver: new phy_driver to register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) * @owner: module owning this PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) /* Either the features are hard coded, or dynamically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) * determined. It cannot be both.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) if (WARN_ON(new_driver->features && new_driver->get_features)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) pr_err("%s: features and get_features must not both be set\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) new_driver->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) new_driver->mdiodrv.driver.name = new_driver->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) new_driver->mdiodrv.driver.bus = &mdio_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) new_driver->mdiodrv.driver.probe = phy_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) new_driver->mdiodrv.driver.remove = phy_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) new_driver->mdiodrv.driver.owner = owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) new_driver->mdiodrv.driver.probe_type = PROBE_FORCE_SYNCHRONOUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) retval = driver_register(&new_driver->mdiodrv.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) pr_err("%s: Error %d in registering driver\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) new_driver->name, retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) pr_debug("%s: Registered new driver\n", new_driver->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) EXPORT_SYMBOL(phy_driver_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) int phy_drivers_register(struct phy_driver *new_driver, int n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) int i, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) for (i = 0; i < n; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) ret = phy_driver_register(new_driver + i, owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) while (i-- > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) phy_driver_unregister(new_driver + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) EXPORT_SYMBOL(phy_drivers_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) void phy_driver_unregister(struct phy_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) driver_unregister(&drv->mdiodrv.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) EXPORT_SYMBOL(phy_driver_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) void phy_drivers_unregister(struct phy_driver *drv, int n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) for (i = 0; i < n; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) phy_driver_unregister(drv + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) EXPORT_SYMBOL(phy_drivers_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) static struct phy_driver genphy_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) .phy_id = 0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) .phy_id_mask = 0xffffffff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) .name = "Generic PHY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) .get_features = genphy_read_abilities,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) .suspend = genphy_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) .resume = genphy_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) .set_loopback = genphy_loopback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) static const struct ethtool_phy_ops phy_ethtool_phy_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) .get_sset_count = phy_ethtool_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) .get_strings = phy_ethtool_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) .get_stats = phy_ethtool_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) .start_cable_test = phy_start_cable_test,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) .start_cable_test_tdr = phy_start_cable_test_tdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) static int __init phy_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) rc = mdio_bus_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) ethtool_set_ethtool_phy_ops(&phy_ethtool_phy_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) features_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) rc = phy_driver_register(&genphy_c45_driver, THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) goto err_c45;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) rc = phy_driver_register(&genphy_driver, THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) phy_driver_unregister(&genphy_c45_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) err_c45:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) mdio_bus_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) static void __exit phy_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) phy_driver_unregister(&genphy_c45_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) phy_driver_unregister(&genphy_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) mdio_bus_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) ethtool_set_ethtool_phy_ops(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) subsys_initcall(phy_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) module_exit(phy_exit);