source: bootcd/isolinux/syslinux-6.03/gpxe/src/net/mii.c @ 26ffad7

Last change on this file since 26ffad7 was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 4.0 KB
Line 
1/*
2
3        mii.c: MII interface library
4
5        Ported to gPXE by Daniel Verkamp <daniel@drv.nu>
6        from Linux drivers/net/mii.c
7
8        Maintained by Jeff Garzik <jgarzik@pobox.com>
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 becker@scyld.com, 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 */
40int
41mii_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 */
58void
59mii_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 */
80unsigned int
81mii_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}
Note: See TracBrowser for help on using the repository browser.