Home | History | Annotate | Download | only in common
      1 // SPDX-License-Identifier: GPL-2.0+
      2 /*
      3  * (C) Copyright 2001
      4  * Gerald Van Baren, Custom IDEAS, vanbaren (at) cideas.com.
      5  */
      6 
      7 /*
      8  * This provides a bit-banged interface to the ethernet MII management
      9  * channel.
     10  */
     11 
     12 #include <common.h>
     13 #include <dm.h>
     14 #include <miiphy.h>
     15 #include <phy.h>
     16 
     17 #include <asm/types.h>
     18 #include <linux/list.h>
     19 #include <malloc.h>
     20 #include <net.h>
     21 
     22 /* local debug macro */
     23 #undef MII_DEBUG
     24 
     25 #undef debug
     26 #ifdef MII_DEBUG
     27 #define debug(fmt, args...)	printf(fmt, ##args)
     28 #else
     29 #define debug(fmt, args...)
     30 #endif /* MII_DEBUG */
     31 
     32 static struct list_head mii_devs;
     33 static struct mii_dev *current_mii;
     34 
     35 /*
     36  * Lookup the mii_dev struct by the registered device name.
     37  */
     38 struct mii_dev *miiphy_get_dev_by_name(const char *devname)
     39 {
     40 	struct list_head *entry;
     41 	struct mii_dev *dev;
     42 
     43 	if (!devname) {
     44 		printf("NULL device name!\n");
     45 		return NULL;
     46 	}
     47 
     48 	list_for_each(entry, &mii_devs) {
     49 		dev = list_entry(entry, struct mii_dev, link);
     50 		if (strcmp(dev->name, devname) == 0)
     51 			return dev;
     52 	}
     53 
     54 	return NULL;
     55 }
     56 
     57 /*****************************************************************************
     58  *
     59  * Initialize global data. Need to be called before any other miiphy routine.
     60  */
     61 void miiphy_init(void)
     62 {
     63 	INIT_LIST_HEAD(&mii_devs);
     64 	current_mii = NULL;
     65 }
     66 
     67 struct mii_dev *mdio_alloc(void)
     68 {
     69 	struct mii_dev *bus;
     70 
     71 	bus = malloc(sizeof(*bus));
     72 	if (!bus)
     73 		return bus;
     74 
     75 	memset(bus, 0, sizeof(*bus));
     76 
     77 	/* initalize mii_dev struct fields */
     78 	INIT_LIST_HEAD(&bus->link);
     79 
     80 	return bus;
     81 }
     82 
     83 void mdio_free(struct mii_dev *bus)
     84 {
     85 	free(bus);
     86 }
     87 
     88 int mdio_register(struct mii_dev *bus)
     89 {
     90 	if (!bus || !bus->read || !bus->write)
     91 		return -1;
     92 
     93 	/* check if we have unique name */
     94 	if (miiphy_get_dev_by_name(bus->name)) {
     95 		printf("mdio_register: non unique device name '%s'\n",
     96 			bus->name);
     97 		return -1;
     98 	}
     99 
    100 	/* add it to the list */
    101 	list_add_tail(&bus->link, &mii_devs);
    102 
    103 	if (!current_mii)
    104 		current_mii = bus;
    105 
    106 	return 0;
    107 }
    108 
    109 int mdio_register_seq(struct mii_dev *bus, int seq)
    110 {
    111 	int ret;
    112 
    113 	/* Setup a unique name for each mdio bus */
    114 	ret = snprintf(bus->name, MDIO_NAME_LEN, "eth%d", seq);
    115 	if (ret < 0)
    116 		return ret;
    117 
    118 	return mdio_register(bus);
    119 }
    120 
    121 int mdio_unregister(struct mii_dev *bus)
    122 {
    123 	if (!bus)
    124 		return 0;
    125 
    126 	/* delete it from the list */
    127 	list_del(&bus->link);
    128 
    129 	if (current_mii == bus)
    130 		current_mii = NULL;
    131 
    132 	return 0;
    133 }
    134 
    135 void mdio_list_devices(void)
    136 {
    137 	struct list_head *entry;
    138 
    139 	list_for_each(entry, &mii_devs) {
    140 		int i;
    141 		struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
    142 
    143 		printf("%s:\n", bus->name);
    144 
    145 		for (i = 0; i < PHY_MAX_ADDR; i++) {
    146 			struct phy_device *phydev = bus->phymap[i];
    147 
    148 			if (phydev) {
    149 				printf("%x - %s", i, phydev->drv->name);
    150 
    151 				if (phydev->dev)
    152 					printf(" <--> %s\n", phydev->dev->name);
    153 				else
    154 					printf("\n");
    155 			}
    156 		}
    157 	}
    158 }
    159 
    160 int miiphy_set_current_dev(const char *devname)
    161 {
    162 	struct mii_dev *dev;
    163 
    164 	dev = miiphy_get_dev_by_name(devname);
    165 	if (dev) {
    166 		current_mii = dev;
    167 		return 0;
    168 	}
    169 
    170 	printf("No such device: %s\n", devname);
    171 
    172 	return 1;
    173 }
    174 
    175 struct mii_dev *mdio_get_current_dev(void)
    176 {
    177 	return current_mii;
    178 }
    179 
    180 struct phy_device *mdio_phydev_for_ethname(const char *ethname)
    181 {
    182 	struct list_head *entry;
    183 	struct mii_dev *bus;
    184 
    185 	list_for_each(entry, &mii_devs) {
    186 		int i;
    187 		bus = list_entry(entry, struct mii_dev, link);
    188 
    189 		for (i = 0; i < PHY_MAX_ADDR; i++) {
    190 			if (!bus->phymap[i] || !bus->phymap[i]->dev)
    191 				continue;
    192 
    193 			if (strcmp(bus->phymap[i]->dev->name, ethname) == 0)
    194 				return bus->phymap[i];
    195 		}
    196 	}
    197 
    198 	printf("%s is not a known ethernet\n", ethname);
    199 	return NULL;
    200 }
    201 
    202 const char *miiphy_get_current_dev(void)
    203 {
    204 	if (current_mii)
    205 		return current_mii->name;
    206 
    207 	return NULL;
    208 }
    209 
    210 static struct mii_dev *miiphy_get_active_dev(const char *devname)
    211 {
    212 	/* If the current mii is the one we want, return it */
    213 	if (current_mii)
    214 		if (strcmp(current_mii->name, devname) == 0)
    215 			return current_mii;
    216 
    217 	/* Otherwise, set the active one to the one we want */
    218 	if (miiphy_set_current_dev(devname))
    219 		return NULL;
    220 	else
    221 		return current_mii;
    222 }
    223 
    224 /*****************************************************************************
    225  *
    226  * Read to variable <value> from the PHY attached to device <devname>,
    227  * use PHY address <addr> and register <reg>.
    228  *
    229  * This API is deprecated. Use phy_read on a phy_device found via phy_connect
    230  *
    231  * Returns:
    232  *   0 on success
    233  */
    234 int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
    235 		 unsigned short *value)
    236 {
    237 	struct mii_dev *bus;
    238 	int ret;
    239 
    240 	bus = miiphy_get_active_dev(devname);
    241 	if (!bus)
    242 		return 1;
    243 
    244 	ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
    245 	if (ret < 0)
    246 		return 1;
    247 
    248 	*value = (unsigned short)ret;
    249 	return 0;
    250 }
    251 
    252 /*****************************************************************************
    253  *
    254  * Write <value> to the PHY attached to device <devname>,
    255  * use PHY address <addr> and register <reg>.
    256  *
    257  * This API is deprecated. Use phy_write on a phy_device found by phy_connect
    258  *
    259  * Returns:
    260  *   0 on success
    261  */
    262 int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
    263 		  unsigned short value)
    264 {
    265 	struct mii_dev *bus;
    266 
    267 	bus = miiphy_get_active_dev(devname);
    268 	if (bus)
    269 		return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
    270 
    271 	return 1;
    272 }
    273 
    274 /*****************************************************************************
    275  *
    276  * Print out list of registered MII capable devices.
    277  */
    278 void miiphy_listdev(void)
    279 {
    280 	struct list_head *entry;
    281 	struct mii_dev *dev;
    282 
    283 	puts("MII devices: ");
    284 	list_for_each(entry, &mii_devs) {
    285 		dev = list_entry(entry, struct mii_dev, link);
    286 		printf("'%s' ", dev->name);
    287 	}
    288 	puts("\n");
    289 
    290 	if (current_mii)
    291 		printf("Current device: '%s'\n", current_mii->name);
    292 }
    293 
    294 /*****************************************************************************
    295  *
    296  * Read the OUI, manufacture's model number, and revision number.
    297  *
    298  * OUI:     22 bits (unsigned int)
    299  * Model:    6 bits (unsigned char)
    300  * Revision: 4 bits (unsigned char)
    301  *
    302  * This API is deprecated.
    303  *
    304  * Returns:
    305  *   0 on success
    306  */
    307 int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
    308 		 unsigned char *model, unsigned char *rev)
    309 {
    310 	unsigned int reg = 0;
    311 	unsigned short tmp;
    312 
    313 	if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
    314 		debug("PHY ID register 2 read failed\n");
    315 		return -1;
    316 	}
    317 	reg = tmp;
    318 
    319 	debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);
    320 
    321 	if (reg == 0xFFFF) {
    322 		/* No physical device present at this address */
    323 		return -1;
    324 	}
    325 
    326 	if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
    327 		debug("PHY ID register 1 read failed\n");
    328 		return -1;
    329 	}
    330 	reg |= tmp << 16;
    331 	debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
    332 
    333 	*oui = (reg >> 10);
    334 	*model = (unsigned char)((reg >> 4) & 0x0000003F);
    335 	*rev = (unsigned char)(reg & 0x0000000F);
    336 	return 0;
    337 }
    338 
    339 #ifndef CONFIG_PHYLIB
    340 /*****************************************************************************
    341  *
    342  * Reset the PHY.
    343  *
    344  * This API is deprecated. Use PHYLIB.
    345  *
    346  * Returns:
    347  *   0 on success
    348  */
    349 int miiphy_reset(const char *devname, unsigned char addr)
    350 {
    351 	unsigned short reg;
    352 	int timeout = 500;
    353 
    354 	if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
    355 		debug("PHY status read failed\n");
    356 		return -1;
    357 	}
    358 	if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
    359 		debug("PHY reset failed\n");
    360 		return -1;
    361 	}
    362 #ifdef CONFIG_PHY_RESET_DELAY
    363 	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
    364 #endif
    365 	/*
    366 	 * Poll the control register for the reset bit to go to 0 (it is
    367 	 * auto-clearing).  This should happen within 0.5 seconds per the
    368 	 * IEEE spec.
    369 	 */
    370 	reg = 0x8000;
    371 	while (((reg & 0x8000) != 0) && timeout--) {
    372 		if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
    373 			debug("PHY status read failed\n");
    374 			return -1;
    375 		}
    376 		udelay(1000);
    377 	}
    378 	if ((reg & 0x8000) == 0) {
    379 		return 0;
    380 	} else {
    381 		puts("PHY reset timed out\n");
    382 		return -1;
    383 	}
    384 	return 0;
    385 }
    386 #endif /* !PHYLIB */
    387 
    388 /*****************************************************************************
    389  *
    390  * Determine the ethernet speed (10/100/1000).  Return 10 on error.
    391  */
    392 int miiphy_speed(const char *devname, unsigned char addr)
    393 {
    394 	u16 bmcr, anlpar, adv;
    395 
    396 #if defined(CONFIG_PHY_GIGE)
    397 	u16 btsr;
    398 
    399 	/*
    400 	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
    401 	 * is 1000.
    402 	 */
    403 	if (miiphy_is_1000base_x(devname, addr))
    404 		return _1000BASET;
    405 
    406 	/*
    407 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
    408 	 */
    409 	/* Check for 1000BASE-T. */
    410 	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
    411 		printf("PHY 1000BT status");
    412 		goto miiphy_read_failed;
    413 	}
    414 	if (btsr != 0xFFFF &&
    415 			(btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)))
    416 		return _1000BASET;
    417 #endif /* CONFIG_PHY_GIGE */
    418 
    419 	/* Check Basic Management Control Register first. */
    420 	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
    421 		printf("PHY speed");
    422 		goto miiphy_read_failed;
    423 	}
    424 	/* Check if auto-negotiation is on. */
    425 	if (bmcr & BMCR_ANENABLE) {
    426 		/* Get auto-negotiation results. */
    427 		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
    428 			printf("PHY AN speed");
    429 			goto miiphy_read_failed;
    430 		}
    431 
    432 		if (miiphy_read(devname, addr, MII_ADVERTISE, &adv)) {
    433 			puts("PHY AN adv speed");
    434 			goto miiphy_read_failed;
    435 		}
    436 		return ((anlpar & adv) & LPA_100) ? _100BASET : _10BASET;
    437 	}
    438 	/* Get speed from basic control settings. */
    439 	return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
    440 
    441 miiphy_read_failed:
    442 	printf(" read failed, assuming 10BASE-T\n");
    443 	return _10BASET;
    444 }
    445 
    446 /*****************************************************************************
    447  *
    448  * Determine full/half duplex.  Return half on error.
    449  */
    450 int miiphy_duplex(const char *devname, unsigned char addr)
    451 {
    452 	u16 bmcr, anlpar, adv;
    453 
    454 #if defined(CONFIG_PHY_GIGE)
    455 	u16 btsr;
    456 
    457 	/* Check for 1000BASE-X. */
    458 	if (miiphy_is_1000base_x(devname, addr)) {
    459 		/* 1000BASE-X */
    460 		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
    461 			printf("1000BASE-X PHY AN duplex");
    462 			goto miiphy_read_failed;
    463 		}
    464 	}
    465 	/*
    466 	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
    467 	 */
    468 	/* Check for 1000BASE-T. */
    469 	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
    470 		printf("PHY 1000BT status");
    471 		goto miiphy_read_failed;
    472 	}
    473 	if (btsr != 0xFFFF) {
    474 		if (btsr & PHY_1000BTSR_1000FD) {
    475 			return FULL;
    476 		} else if (btsr & PHY_1000BTSR_1000HD) {
    477 			return HALF;
    478 		}
    479 	}
    480 #endif /* CONFIG_PHY_GIGE */
    481 
    482 	/* Check Basic Management Control Register first. */
    483 	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
    484 		puts("PHY duplex");
    485 		goto miiphy_read_failed;
    486 	}
    487 	/* Check if auto-negotiation is on. */
    488 	if (bmcr & BMCR_ANENABLE) {
    489 		/* Get auto-negotiation results. */
    490 		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
    491 			puts("PHY AN duplex");
    492 			goto miiphy_read_failed;
    493 		}
    494 
    495 		if (miiphy_read(devname, addr, MII_ADVERTISE, &adv)) {
    496 			puts("PHY AN adv duplex");
    497 			goto miiphy_read_failed;
    498 		}
    499 		return ((anlpar & adv) & (LPA_10FULL | LPA_100FULL)) ?
    500 		    FULL : HALF;
    501 	}
    502 	/* Get speed from basic control settings. */
    503 	return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
    504 
    505 miiphy_read_failed:
    506 	printf(" read failed, assuming half duplex\n");
    507 	return HALF;
    508 }
    509 
    510 /*****************************************************************************
    511  *
    512  * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
    513  * 1000BASE-T, or on error.
    514  */
    515 int miiphy_is_1000base_x(const char *devname, unsigned char addr)
    516 {
    517 #if defined(CONFIG_PHY_GIGE)
    518 	u16 exsr;
    519 
    520 	if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
    521 		printf("PHY extended status read failed, assuming no "
    522 			"1000BASE-X\n");
    523 		return 0;
    524 	}
    525 	return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
    526 #else
    527 	return 0;
    528 #endif
    529 }
    530 
    531 #ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
    532 /*****************************************************************************
    533  *
    534  * Determine link status
    535  */
    536 int miiphy_link(const char *devname, unsigned char addr)
    537 {
    538 	unsigned short reg;
    539 
    540 	/* dummy read; needed to latch some phys */
    541 	(void)miiphy_read(devname, addr, MII_BMSR, &reg);
    542 	if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
    543 		puts("MII_BMSR read failed, assuming no link\n");
    544 		return 0;
    545 	}
    546 
    547 	/* Determine if a link is active */
    548 	if ((reg & BMSR_LSTATUS) != 0) {
    549 		return 1;
    550 	} else {
    551 		return 0;
    552 	}
    553 }
    554 #endif
    555