summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/libbsdport/miistuff.c
blob: b15545f9f9d7ec21ceffba66d72f8a0babde91e0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <rtems.h>
#define _KERNEL
#include <rtems/rtems_bsdnet.h>
#include <rtems/rtems_bsdnet_internal.h>

#include <bsp/rtems_verscheck.h>

#include <sys/malloc.h>
#include <sys/errno.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <net/if.h>
#include <net/if_media.h>
#include <rtems/rtems_mii_ioctl.h>

#define PHY_MAX 32

#undef  DEBUG

/* A helper to find the active PHY. We really should port
 * the entire BSD miibus/phy support but that's a bigger
 * project...
 */
int
rtems_mii_phy_probe(struct rtems_mdio_info *mdio, void *softc)
{
int      phy;
uint32_t bmsr, bmcr;
	for ( phy = 0; phy<PHY_MAX; phy++ ) {
		if ( mdio->mdio_r(phy, softc, MII_BMSR, &bmsr) )
			continue;

		bmsr &= 0xffff;

		if ( 0 == bmsr || 0xffff == bmsr )	
			continue; /* nothing here */

		/* no media supported ? */
		if ( 0 == ((BMSR_EXTSTAT | 0xfe00) & bmsr ) )
			continue; /* probably nothing there */

		if ( mdio->mdio_r(phy, softc, MII_BMCR, &bmcr) )
			continue;

		/* skip isolated or powered-down phys */
		if ( (BMCR_PDOWN | BMCR_ISO) & bmcr )
			continue;

#ifdef DEBUG
		printk("PHY #%u seems active; link status is %s\n", phy, BMSR_LINK & bmsr ? "UP" : "DOWN");
#endif

		/* seems we found one */
		return phy;
	}

	return -1;
}