diff --git a/src/drivers/net/mii.c b/src/drivers/net/mii.c index 4e45874aa..9b297029a 100644 --- a/src/drivers/net/mii.c +++ b/src/drivers/net/mii.c @@ -115,3 +115,35 @@ int mii_reset ( struct mii_interface *mii ) { DBGC ( mii, "MII %p timed out waiting for reset\n", mii ); return -ETIMEDOUT; } + +/** + * Update link status via MII + * + * @v mii MII interface + * @v netdev Network device + * @ret rc Return status code + */ +int mii_check_link ( struct mii_interface *mii, struct net_device *netdev ) { + int bmsr; + int link; + int rc; + + /* Read BMSR */ + bmsr = mii_read ( mii, MII_BMSR ); + if ( bmsr < 0 ) { + rc = bmsr; + return rc; + } + + /* Report link status */ + link = ( bmsr & BMSR_LSTATUS ); + DBGC ( mii, "MII %p link %s (BMSR %#04x)\n", + mii, ( link ? "up" : "down" ), bmsr ); + if ( link ) { + netdev_link_up ( netdev ); + } else { + netdev_link_down ( netdev ); + } + + return 0; +} diff --git a/src/include/ipxe/mii.h b/src/include/ipxe/mii.h index daf29dac5..c2245b49e 100644 --- a/src/include/ipxe/mii.h +++ b/src/include/ipxe/mii.h @@ -114,5 +114,7 @@ mii_dump ( struct mii_interface *mii ) { extern int mii_restart ( struct mii_interface *mii ); extern int mii_reset ( struct mii_interface *mii ); +extern int mii_check_link ( struct mii_interface *mii, + struct net_device *netdev ); #endif /* _IPXE_MII_H */