|
|
1.1 ! root 1: /* ! 2: ! 3: mii.c: MII interface library ! 4: ! 5: Ported to iPXE by Daniel Verkamp <[email protected]> ! 6: from Linux drivers/net/mii.c ! 7: ! 8: Maintained by Jeff Garzik <[email protected]> ! 9: Copyright 2001,2002 Jeff Garzik ! 10: ! 11: Various code came from myson803.c and other files by ! 12: Donald Becker. Copyright: ! 13: ! 14: Written 1998-2002 by Donald Becker. ! 15: ! 16: This software may be used and distributed according ! 17: to the terms of the GNU General Public License (GPL), ! 18: incorporated herein by reference. Drivers based on ! 19: or derived from this code fall under the GPL and must ! 20: retain the authorship, copyright and license notice. ! 21: This file is not a complete program and may only be ! 22: used when the entire operating system is licensed ! 23: under the GPL. ! 24: ! 25: The author may be reached as [email protected], or C/O ! 26: Scyld Computing Corporation ! 27: 410 Severn Ave., Suite 210 ! 28: Annapolis MD 21403 ! 29: ! 30: */ ! 31: ! 32: #include <mii.h> ! 33: ! 34: /** ! 35: * mii_link_ok - is link status up/ok ! 36: * @mii: the MII interface ! 37: * ! 38: * Returns 1 if the MII reports link status up/ok, 0 otherwise. ! 39: */ ! 40: int ! 41: mii_link_ok ( struct mii_if_info *mii ) ! 42: { ! 43: /* first, a dummy read, needed to latch some MII phys */ ! 44: mii->mdio_read ( mii->dev, mii->phy_id, MII_BMSR ); ! 45: if ( mii->mdio_read ( mii->dev, mii->phy_id, MII_BMSR ) & BMSR_LSTATUS ) ! 46: return 1; ! 47: return 0; ! 48: } ! 49: ! 50: /** ! 51: * mii_check_link - check MII link status ! 52: * @mii: MII interface ! 53: * ! 54: * If the link status changed (previous != current), call ! 55: * netif_carrier_on() if current link status is Up or call ! 56: * netif_carrier_off() if current link status is Down. ! 57: */ ! 58: void ! 59: mii_check_link ( struct mii_if_info *mii ) ! 60: { ! 61: int cur_link = mii_link_ok ( mii ); ! 62: int prev_link = netdev_link_ok ( mii->dev ); ! 63: ! 64: if ( cur_link && !prev_link ) ! 65: netdev_link_up ( mii->dev ); ! 66: else if (prev_link && !cur_link) ! 67: netdev_link_down ( mii->dev ); ! 68: } ! 69: ! 70: ! 71: /** ! 72: * mii_check_media - check the MII interface for a duplex change ! 73: * @mii: the MII interface ! 74: * @ok_to_print: OK to print link up/down messages ! 75: * @init_media: OK to save duplex mode in @mii ! 76: * ! 77: * Returns 1 if the duplex mode changed, 0 if not. ! 78: * If the media type is forced, always returns 0. ! 79: */ ! 80: unsigned int ! 81: mii_check_media ( struct mii_if_info *mii, ! 82: unsigned int ok_to_print, ! 83: unsigned int init_media ) ! 84: { ! 85: unsigned int old_carrier, new_carrier; ! 86: int advertise, lpa, media, duplex; ! 87: int lpa2 = 0; ! 88: ! 89: /* if forced media, go no further */ ! 90: if (mii->force_media) ! 91: return 0; /* duplex did not change */ ! 92: ! 93: /* check current and old link status */ ! 94: old_carrier = netdev_link_ok ( mii->dev ) ? 1 : 0; ! 95: new_carrier = (unsigned int) mii_link_ok ( mii ); ! 96: ! 97: /* if carrier state did not change, this is a "bounce", ! 98: * just exit as everything is already set correctly ! 99: */ ! 100: if ( ( ! init_media ) && ( old_carrier == new_carrier ) ) ! 101: return 0; /* duplex did not change */ ! 102: ! 103: /* no carrier, nothing much to do */ ! 104: if ( ! new_carrier ) { ! 105: netdev_link_down ( mii->dev ); ! 106: if ( ok_to_print ) ! 107: DBG ( "%s: link down\n", mii->dev->name); ! 108: return 0; /* duplex did not change */ ! 109: } ! 110: ! 111: /* ! 112: * we have carrier, see who's on the other end ! 113: */ ! 114: netdev_link_up ( mii->dev ); ! 115: ! 116: /* get MII advertise and LPA values */ ! 117: if ( ( ! init_media ) && ( mii->advertising ) ) { ! 118: advertise = mii->advertising; ! 119: } else { ! 120: advertise = mii->mdio_read ( mii->dev, mii->phy_id, MII_ADVERTISE ); ! 121: mii->advertising = advertise; ! 122: } ! 123: lpa = mii->mdio_read ( mii->dev, mii->phy_id, MII_LPA ); ! 124: if ( mii->supports_gmii ) ! 125: lpa2 = mii->mdio_read ( mii->dev, mii->phy_id, MII_STAT1000 ); ! 126: ! 127: /* figure out media and duplex from advertise and LPA values */ ! 128: media = mii_nway_result ( lpa & advertise ); ! 129: duplex = ( media & ADVERTISE_FULL ) ? 1 : 0; ! 130: if ( lpa2 & LPA_1000FULL ) ! 131: duplex = 1; ! 132: ! 133: if ( ok_to_print ) ! 134: DBG ( "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n", ! 135: mii->dev->name, ! 136: lpa2 & ( LPA_1000FULL | LPA_1000HALF ) ? "1000" : ! 137: media & ( ADVERTISE_100FULL | ADVERTISE_100HALF ) ? "100" : "10", ! 138: duplex ? "full" : "half", ! 139: lpa); ! 140: ! 141: if ( ( init_media ) || ( mii->full_duplex != duplex ) ) { ! 142: mii->full_duplex = duplex; ! 143: return 1; /* duplex changed */ ! 144: } ! 145: ! 146: return 0; /* duplex did not change */ ! 147: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.