1c916d7c9SKumar Gala /* 2c916d7c9SKumar Gala * Copyright 2011 Freescale Semiconductor, Inc. 3c916d7c9SKumar Gala * 41a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 5c916d7c9SKumar Gala */ 6c916d7c9SKumar Gala #include <common.h> 7c916d7c9SKumar Gala #include <asm/io.h> 8c916d7c9SKumar Gala #include <asm/fsl_serdes.h> 993f26f13SClaudiu Manoil #include <fsl_mdio.h> 10c916d7c9SKumar Gala 11c916d7c9SKumar Gala #include "fm.h" 12c916d7c9SKumar Gala 13c916d7c9SKumar Gala struct fm_eth_info fm_info[] = { 14c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_DTSEC >= 1) 15c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(1, 1), 16c916d7c9SKumar Gala #endif 17c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_DTSEC >= 2) 18c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(1, 2), 19c916d7c9SKumar Gala #endif 20c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_DTSEC >= 3) 21c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(1, 3), 22c916d7c9SKumar Gala #endif 23c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_DTSEC >= 4) 24c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(1, 4), 25c916d7c9SKumar Gala #endif 26c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_DTSEC >= 5) 27c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(1, 5), 28c916d7c9SKumar Gala #endif 299e758758SYork Sun #if (CONFIG_SYS_NUM_FM1_DTSEC >= 6) 309e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(1, 6), 319e758758SYork Sun #endif 329e758758SYork Sun #if (CONFIG_SYS_NUM_FM1_DTSEC >= 7) 339e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(1, 9), 349e758758SYork Sun #endif 359e758758SYork Sun #if (CONFIG_SYS_NUM_FM1_DTSEC >= 8) 369e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(1, 10), 379e758758SYork Sun #endif 38c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM2_DTSEC >= 1) 39c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(2, 1), 40c916d7c9SKumar Gala #endif 41c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM2_DTSEC >= 2) 42c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(2, 2), 43c916d7c9SKumar Gala #endif 44c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM2_DTSEC >= 3) 45c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(2, 3), 46c916d7c9SKumar Gala #endif 47c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM2_DTSEC >= 4) 48c916d7c9SKumar Gala FM_DTSEC_INFO_INITIALIZER(2, 4), 49c916d7c9SKumar Gala #endif 5099abf7deSTimur Tabi #if (CONFIG_SYS_NUM_FM2_DTSEC >= 5) 5199abf7deSTimur Tabi FM_DTSEC_INFO_INITIALIZER(2, 5), 5299abf7deSTimur Tabi #endif 539e758758SYork Sun #if (CONFIG_SYS_NUM_FM2_DTSEC >= 6) 549e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(2, 6), 559e758758SYork Sun #endif 569e758758SYork Sun #if (CONFIG_SYS_NUM_FM2_DTSEC >= 7) 579e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(2, 9), 589e758758SYork Sun #endif 599e758758SYork Sun #if (CONFIG_SYS_NUM_FM2_DTSEC >= 8) 609e758758SYork Sun FM_DTSEC_INFO_INITIALIZER(2, 10), 619e758758SYork Sun #endif 62c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM1_10GEC >= 1) 63c916d7c9SKumar Gala FM_TGEC_INFO_INITIALIZER(1, 1), 64c916d7c9SKumar Gala #endif 65944b6ccfSShaohui Xie #if (CONFIG_SYS_NUM_FM1_10GEC >= 2) 66944b6ccfSShaohui Xie FM_TGEC_INFO_INITIALIZER(1, 2), 67944b6ccfSShaohui Xie #endif 6882a55c1eSShengzhou Liu #if (CONFIG_SYS_NUM_FM1_10GEC >= 3) 6982a55c1eSShengzhou Liu FM_TGEC_INFO_INITIALIZER2(1, 3), 7082a55c1eSShengzhou Liu #endif 7182a55c1eSShengzhou Liu #if (CONFIG_SYS_NUM_FM1_10GEC >= 4) 7282a55c1eSShengzhou Liu FM_TGEC_INFO_INITIALIZER2(1, 4), 7382a55c1eSShengzhou Liu #endif 74c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FM2_10GEC >= 1) 75c916d7c9SKumar Gala FM_TGEC_INFO_INITIALIZER(2, 1), 76c916d7c9SKumar Gala #endif 77944b6ccfSShaohui Xie #if (CONFIG_SYS_NUM_FM2_10GEC >= 2) 78944b6ccfSShaohui Xie FM_TGEC_INFO_INITIALIZER(2, 2), 79944b6ccfSShaohui Xie #endif 80c916d7c9SKumar Gala }; 81c916d7c9SKumar Gala 82c916d7c9SKumar Gala int fm_standard_init(bd_t *bis) 83c916d7c9SKumar Gala { 84c916d7c9SKumar Gala int i; 85c916d7c9SKumar Gala struct ccsr_fman *reg; 86c916d7c9SKumar Gala 87c916d7c9SKumar Gala reg = (void *)CONFIG_SYS_FSL_FM1_ADDR; 88c916d7c9SKumar Gala if (fm_init_common(0, reg)) 89c916d7c9SKumar Gala return 0; 90c916d7c9SKumar Gala 91c916d7c9SKumar Gala for (i = 0; i < ARRAY_SIZE(fm_info); i++) { 92c916d7c9SKumar Gala if ((fm_info[i].enabled) && (fm_info[i].index == 1)) 93c916d7c9SKumar Gala fm_eth_initialize(reg, &fm_info[i]); 94c916d7c9SKumar Gala } 95c916d7c9SKumar Gala 96c916d7c9SKumar Gala #if (CONFIG_SYS_NUM_FMAN == 2) 97c916d7c9SKumar Gala reg = (void *)CONFIG_SYS_FSL_FM2_ADDR; 98c916d7c9SKumar Gala if (fm_init_common(1, reg)) 99c916d7c9SKumar Gala return 0; 100c916d7c9SKumar Gala 101c916d7c9SKumar Gala for (i = 0; i < ARRAY_SIZE(fm_info); i++) { 102c916d7c9SKumar Gala if ((fm_info[i].enabled) && (fm_info[i].index == 2)) 103c916d7c9SKumar Gala fm_eth_initialize(reg, &fm_info[i]); 104c916d7c9SKumar Gala } 105c916d7c9SKumar Gala #endif 106c916d7c9SKumar Gala 107c916d7c9SKumar Gala return 1; 108c916d7c9SKumar Gala } 109c916d7c9SKumar Gala 110c916d7c9SKumar Gala /* simple linear search to map from port to array index */ 111c916d7c9SKumar Gala static int fm_port_to_index(enum fm_port port) 112c916d7c9SKumar Gala { 113c916d7c9SKumar Gala int i; 114c916d7c9SKumar Gala 115c916d7c9SKumar Gala for (i = 0; i < ARRAY_SIZE(fm_info); i++) { 116c916d7c9SKumar Gala if (fm_info[i].port == port) 117c916d7c9SKumar Gala return i; 118c916d7c9SKumar Gala } 119c916d7c9SKumar Gala 120c916d7c9SKumar Gala return -1; 121c916d7c9SKumar Gala } 122c916d7c9SKumar Gala 123c916d7c9SKumar Gala /* 124c916d7c9SKumar Gala * Determine if an interface is actually active based on HW config 125c916d7c9SKumar Gala * we expect fman_port_enet_if() to report PHY_INTERFACE_MODE_NONE if 126c916d7c9SKumar Gala * the interface is not active based on HW cfg of the SoC 127c916d7c9SKumar Gala */ 128c916d7c9SKumar Gala void fman_enet_init(void) 129c916d7c9SKumar Gala { 130c916d7c9SKumar Gala int i; 131c916d7c9SKumar Gala 132c916d7c9SKumar Gala for (i = 0; i < ARRAY_SIZE(fm_info); i++) { 133c916d7c9SKumar Gala phy_interface_t enet_if; 134c916d7c9SKumar Gala 135c916d7c9SKumar Gala enet_if = fman_port_enet_if(fm_info[i].port); 136c916d7c9SKumar Gala if (enet_if != PHY_INTERFACE_MODE_NONE) { 137c916d7c9SKumar Gala fm_info[i].enabled = 1; 138c916d7c9SKumar Gala fm_info[i].enet_if = enet_if; 139c916d7c9SKumar Gala } else { 140c916d7c9SKumar Gala fm_info[i].enabled = 0; 141c916d7c9SKumar Gala } 142c916d7c9SKumar Gala } 143c916d7c9SKumar Gala 144c916d7c9SKumar Gala return ; 145c916d7c9SKumar Gala } 146c916d7c9SKumar Gala 14769a85242SKumar Gala void fm_disable_port(enum fm_port port) 14869a85242SKumar Gala { 14969a85242SKumar Gala int i = fm_port_to_index(port); 15069a85242SKumar Gala 1511155d8d8SRotariu Marian-Cristian if (i == -1) 1521155d8d8SRotariu Marian-Cristian return; 1531155d8d8SRotariu Marian-Cristian 15469a85242SKumar Gala fm_info[i].enabled = 0; 15569a85242SKumar Gala fman_disable_port(port); 15669a85242SKumar Gala } 15769a85242SKumar Gala 158f51d3b71SValentin Longchamp void fm_enable_port(enum fm_port port) 159f51d3b71SValentin Longchamp { 160f51d3b71SValentin Longchamp int i = fm_port_to_index(port); 161f51d3b71SValentin Longchamp 1621155d8d8SRotariu Marian-Cristian if (i == -1) 1631155d8d8SRotariu Marian-Cristian return; 1641155d8d8SRotariu Marian-Cristian 165f51d3b71SValentin Longchamp fm_info[i].enabled = 1; 166f51d3b71SValentin Longchamp fman_enable_port(port); 167f51d3b71SValentin Longchamp } 168f51d3b71SValentin Longchamp 169c916d7c9SKumar Gala void fm_info_set_mdio(enum fm_port port, struct mii_dev *bus) 170c916d7c9SKumar Gala { 171c916d7c9SKumar Gala int i = fm_port_to_index(port); 172c916d7c9SKumar Gala 173c916d7c9SKumar Gala if (i == -1) 174c916d7c9SKumar Gala return; 175c916d7c9SKumar Gala 176c916d7c9SKumar Gala fm_info[i].bus = bus; 177c916d7c9SKumar Gala } 178c916d7c9SKumar Gala 179c916d7c9SKumar Gala void fm_info_set_phy_address(enum fm_port port, int address) 180c916d7c9SKumar Gala { 181c916d7c9SKumar Gala int i = fm_port_to_index(port); 182c916d7c9SKumar Gala 183c916d7c9SKumar Gala if (i == -1) 184c916d7c9SKumar Gala return; 185c916d7c9SKumar Gala 186c916d7c9SKumar Gala fm_info[i].phy_addr = address; 187c916d7c9SKumar Gala } 188c916d7c9SKumar Gala 189c916d7c9SKumar Gala /* 190ae2291fbSTimur Tabi * Returns the PHY address for a given Fman port 191ae2291fbSTimur Tabi * 192ae2291fbSTimur Tabi * The port must be set via a prior call to fm_info_set_phy_address(). 193ae2291fbSTimur Tabi * A negative error code is returned if the port is invalid. 194ae2291fbSTimur Tabi */ 195ae2291fbSTimur Tabi int fm_info_get_phy_address(enum fm_port port) 196ae2291fbSTimur Tabi { 197ae2291fbSTimur Tabi int i = fm_port_to_index(port); 198ae2291fbSTimur Tabi 199ae2291fbSTimur Tabi if (i == -1) 200ae2291fbSTimur Tabi return -1; 201ae2291fbSTimur Tabi 202ae2291fbSTimur Tabi return fm_info[i].phy_addr; 203ae2291fbSTimur Tabi } 204ae2291fbSTimur Tabi 205ae2291fbSTimur Tabi /* 206c916d7c9SKumar Gala * Returns the type of the data interface between the given MAC and its PHY. 207c916d7c9SKumar Gala * This is typically determined by the RCW. 208c916d7c9SKumar Gala */ 209c916d7c9SKumar Gala phy_interface_t fm_info_get_enet_if(enum fm_port port) 210c916d7c9SKumar Gala { 211c916d7c9SKumar Gala int i = fm_port_to_index(port); 212c916d7c9SKumar Gala 213c916d7c9SKumar Gala if (i == -1) 214c916d7c9SKumar Gala return PHY_INTERFACE_MODE_NONE; 215c916d7c9SKumar Gala 216c916d7c9SKumar Gala if (fm_info[i].enabled) 217c916d7c9SKumar Gala return fm_info[i].enet_if; 218c916d7c9SKumar Gala 219c916d7c9SKumar Gala return PHY_INTERFACE_MODE_NONE; 220c916d7c9SKumar Gala } 221c916d7c9SKumar Gala 222c916d7c9SKumar Gala static void 223c916d7c9SKumar Gala __def_board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, 224c916d7c9SKumar Gala enum fm_port port, int offset) 225c916d7c9SKumar Gala { 226c916d7c9SKumar Gala return ; 227c916d7c9SKumar Gala } 228c916d7c9SKumar Gala 229c916d7c9SKumar Gala void board_ft_fman_fixup_port(void *blob, char * prop, phys_addr_t pa, 230c916d7c9SKumar Gala enum fm_port port, int offset) 231c916d7c9SKumar Gala __attribute__((weak, alias("__def_board_ft_fman_fixup_port"))); 232c916d7c9SKumar Gala 233c916d7c9SKumar Gala static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) 234c916d7c9SKumar Gala { 2354376b4c0STimur Tabi int off; 2364376b4c0STimur Tabi uint32_t ph; 237c916d7c9SKumar Gala phys_addr_t paddr = CONFIG_SYS_CCSRBAR_PHYS + info->compat_offset; 238e81c0abaSKumar Gala u64 dtsec1_addr = (u64)CONFIG_SYS_CCSRBAR_PHYS + 239e81c0abaSKumar Gala CONFIG_SYS_FSL_FM1_DTSEC1_OFFSET; 240c916d7c9SKumar Gala 241c916d7c9SKumar Gala off = fdt_node_offset_by_compat_reg(blob, prop, paddr); 242c916d7c9SKumar Gala 243c916d7c9SKumar Gala if (info->enabled) { 244c916d7c9SKumar Gala fdt_fixup_phy_connection(blob, off, info->enet_if); 245c916d7c9SKumar Gala board_ft_fman_fixup_port(blob, prop, paddr, info->port, off); 246c916d7c9SKumar Gala return ; 247c916d7c9SKumar Gala } 248c916d7c9SKumar Gala 249ae8a5d10SShengzhou Liu #ifdef CONFIG_SYS_FMAN_V3 250*24d827f5SShengzhou Liu #ifndef CONFIG_FSL_FM_10GEC_REGULAR_NOTATION 251ae8a5d10SShengzhou Liu /* 252*24d827f5SShengzhou Liu * On T2/T4 SoCs, physically FM1_DTSEC9 and FM1_10GEC1 use the same 253*24d827f5SShengzhou Liu * dual-role MAC, when FM1_10GEC1 is enabled and FM1_DTSEC9 254*24d827f5SShengzhou Liu * is disabled, ensure that the dual-role MAC is not disabled, 255*24d827f5SShengzhou Liu * ditto for other dual-role MACs. 256ae8a5d10SShengzhou Liu */ 257ae8a5d10SShengzhou Liu if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || 258ae8a5d10SShengzhou Liu ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || 25982a55c1eSShengzhou Liu ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3))) || 26082a55c1eSShengzhou Liu ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4))) || 261ae8a5d10SShengzhou Liu ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || 26282a55c1eSShengzhou Liu ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) || 26382a55c1eSShengzhou Liu ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1))) || 26482a55c1eSShengzhou Liu ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2))) 265ae8a5d10SShengzhou Liu #if (CONFIG_SYS_NUM_FMAN == 2) 266ae8a5d10SShengzhou Liu || 267ae8a5d10SShengzhou Liu ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1))) || 268ae8a5d10SShengzhou Liu ((info->port == FM2_DTSEC10) && (PORT_IS_ENABLED(FM2_10GEC2))) || 269ae8a5d10SShengzhou Liu ((info->port == FM2_10GEC1) && (PORT_IS_ENABLED(FM2_DTSEC9))) || 270ae8a5d10SShengzhou Liu ((info->port == FM2_10GEC2) && (PORT_IS_ENABLED(FM2_DTSEC10))) 271ae8a5d10SShengzhou Liu #endif 272*24d827f5SShengzhou Liu #else 273*24d827f5SShengzhou Liu /* FM1_DTSECx and FM1_10GECx use the same dual-role MAC */ 274*24d827f5SShengzhou Liu if (((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC1))) || 275*24d827f5SShengzhou Liu ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC2))) || 276*24d827f5SShengzhou Liu ((info->port == FM1_DTSEC3) && (PORT_IS_ENABLED(FM1_10GEC3))) || 277*24d827f5SShengzhou Liu ((info->port == FM1_DTSEC4) && (PORT_IS_ENABLED(FM1_10GEC4))) || 278*24d827f5SShengzhou Liu ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC1))) || 279*24d827f5SShengzhou Liu ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC2))) || 280*24d827f5SShengzhou Liu ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC3))) || 281*24d827f5SShengzhou Liu ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC4))) 282*24d827f5SShengzhou Liu #endif 283ae8a5d10SShengzhou Liu ) 284ae8a5d10SShengzhou Liu return; 285ae8a5d10SShengzhou Liu #endif 286c916d7c9SKumar Gala /* board code might have caused offset to change */ 287c916d7c9SKumar Gala off = fdt_node_offset_by_compat_reg(blob, prop, paddr); 288c916d7c9SKumar Gala 289e81c0abaSKumar Gala /* Don't disable FM1-DTSEC1 MAC as its used for MDIO */ 2904376b4c0STimur Tabi if (paddr != dtsec1_addr) 2914376b4c0STimur Tabi fdt_status_disabled(blob, off); /* disable the MAC node */ 292c916d7c9SKumar Gala 2934376b4c0STimur Tabi /* disable the fsl,dpa-ethernet node that points to the MAC */ 294c916d7c9SKumar Gala ph = fdt_get_phandle(blob, off); 295c916d7c9SKumar Gala do_fixup_by_prop(blob, "fsl,fman-mac", &ph, sizeof(ph), 296c916d7c9SKumar Gala "status", "disabled", strlen("disabled") + 1, 1); 297c916d7c9SKumar Gala } 298c916d7c9SKumar Gala 299c916d7c9SKumar Gala void fdt_fixup_fman_ethernet(void *blob) 300c916d7c9SKumar Gala { 301c916d7c9SKumar Gala int i; 302c916d7c9SKumar Gala 303ae8a5d10SShengzhou Liu #ifdef CONFIG_SYS_FMAN_V3 3044399434fSShengzhou Liu for (i = 0; i < ARRAY_SIZE(fm_info); i++) 305ae8a5d10SShengzhou Liu ft_fixup_port(blob, &fm_info[i], "fsl,fman-memac"); 306ae8a5d10SShengzhou Liu #else 307c916d7c9SKumar Gala for (i = 0; i < ARRAY_SIZE(fm_info); i++) { 308c916d7c9SKumar Gala if (fm_info[i].type == FM_ETH_1G_E) 309c916d7c9SKumar Gala ft_fixup_port(blob, &fm_info[i], "fsl,fman-1g-mac"); 310c916d7c9SKumar Gala else 311c916d7c9SKumar Gala ft_fixup_port(blob, &fm_info[i], "fsl,fman-10g-mac"); 312c916d7c9SKumar Gala } 313ae8a5d10SShengzhou Liu #endif 314c916d7c9SKumar Gala } 315ffee1ddeSZhao Qiang 316ffee1ddeSZhao Qiang /*QSGMII Riser Card can work in SGMII mode, but the PHY address is different. 317ffee1ddeSZhao Qiang *This function scans which Riser Card being used(QSGMII or SGMII Riser Card), 318ffee1ddeSZhao Qiang *then set the correct PHY address 319ffee1ddeSZhao Qiang */ 320ffee1ddeSZhao Qiang void set_sgmii_phy(struct mii_dev *bus, enum fm_port base_port, 321ffee1ddeSZhao Qiang unsigned int port_num, int phy_base_addr) 322ffee1ddeSZhao Qiang { 323ffee1ddeSZhao Qiang unsigned int regnum = 0; 324ffee1ddeSZhao Qiang int qsgmii; 325ffee1ddeSZhao Qiang int i; 326ffee1ddeSZhao Qiang int phy_real_addr; 327ffee1ddeSZhao Qiang 328ffee1ddeSZhao Qiang qsgmii = is_qsgmii_riser_card(bus, phy_base_addr, port_num, regnum); 329ffee1ddeSZhao Qiang 330ffee1ddeSZhao Qiang if (!qsgmii) 331ffee1ddeSZhao Qiang return; 332ffee1ddeSZhao Qiang 333ffee1ddeSZhao Qiang for (i = base_port; i < base_port + port_num; i++) { 334ffee1ddeSZhao Qiang if (fm_info_get_enet_if(i) == PHY_INTERFACE_MODE_SGMII) { 335ffee1ddeSZhao Qiang phy_real_addr = phy_base_addr + i - base_port; 336ffee1ddeSZhao Qiang fm_info_set_phy_address(i, phy_real_addr); 337ffee1ddeSZhao Qiang } 338ffee1ddeSZhao Qiang } 339ffee1ddeSZhao Qiang } 340ffee1ddeSZhao Qiang 341ffee1ddeSZhao Qiang /*to check whether qsgmii riser card is used*/ 342ffee1ddeSZhao Qiang int is_qsgmii_riser_card(struct mii_dev *bus, int phy_base_addr, 343ffee1ddeSZhao Qiang unsigned int port_num, unsigned regnum) 344ffee1ddeSZhao Qiang { 345ffee1ddeSZhao Qiang int i; 346ffee1ddeSZhao Qiang int val; 347ffee1ddeSZhao Qiang 348ffee1ddeSZhao Qiang if (!bus) 349ffee1ddeSZhao Qiang return 0; 350ffee1ddeSZhao Qiang 351ffee1ddeSZhao Qiang for (i = phy_base_addr; i < phy_base_addr + port_num; i++) { 352ffee1ddeSZhao Qiang val = bus->read(bus, i, MDIO_DEVAD_NONE, regnum); 353ffee1ddeSZhao Qiang if (val != MIIM_TIMEOUT) 354ffee1ddeSZhao Qiang return 1; 355ffee1ddeSZhao Qiang } 356ffee1ddeSZhao Qiang 357ffee1ddeSZhao Qiang return 0; 358ffee1ddeSZhao Qiang } 359