xref: /dragonfly/sys/dev/netif/mii_layer/ukphy_subr.c (revision 86d7f5d3)
1*86d7f5d3SJohn Marino /*	$NetBSD: ukphy_subr.c,v 1.9 2005/12/11 12:22:42 christos Exp $	*/
2*86d7f5d3SJohn Marino 
3*86d7f5d3SJohn Marino /*-
4*86d7f5d3SJohn Marino  * Copyright (c) 1998 The NetBSD Foundation, Inc.
5*86d7f5d3SJohn Marino  * All rights reserved.
6*86d7f5d3SJohn Marino  *
7*86d7f5d3SJohn Marino  * This code is derived from software contributed to The NetBSD Foundation
8*86d7f5d3SJohn Marino  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9*86d7f5d3SJohn Marino  * NASA Ames Research Center, and by Frank van der Linden.
10*86d7f5d3SJohn Marino  *
11*86d7f5d3SJohn Marino  * Redistribution and use in source and binary forms, with or without
12*86d7f5d3SJohn Marino  * modification, are permitted provided that the following conditions
13*86d7f5d3SJohn Marino  * are met:
14*86d7f5d3SJohn Marino  * 1. Redistributions of source code must retain the above copyright
15*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer.
16*86d7f5d3SJohn Marino  * 2. Redistributions in binary form must reproduce the above copyright
17*86d7f5d3SJohn Marino  *    notice, this list of conditions and the following disclaimer in the
18*86d7f5d3SJohn Marino  *    documentation and/or other materials provided with the distribution.
19*86d7f5d3SJohn Marino  * 3. All advertising materials mentioning features or use of this software
20*86d7f5d3SJohn Marino  *    must display the following acknowledgement:
21*86d7f5d3SJohn Marino  *	This product includes software developed by the NetBSD
22*86d7f5d3SJohn Marino  *	Foundation, Inc. and its contributors.
23*86d7f5d3SJohn Marino  * 4. Neither the name of The NetBSD Foundation nor the names of its
24*86d7f5d3SJohn Marino  *    contributors may be used to endorse or promote products derived
25*86d7f5d3SJohn Marino  *    from this software without specific prior written permission.
26*86d7f5d3SJohn Marino  *
27*86d7f5d3SJohn Marino  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28*86d7f5d3SJohn Marino  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29*86d7f5d3SJohn Marino  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30*86d7f5d3SJohn Marino  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31*86d7f5d3SJohn Marino  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*86d7f5d3SJohn Marino  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*86d7f5d3SJohn Marino  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*86d7f5d3SJohn Marino  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*86d7f5d3SJohn Marino  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*86d7f5d3SJohn Marino  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*86d7f5d3SJohn Marino  * POSSIBILITY OF SUCH DAMAGE.
38*86d7f5d3SJohn Marino  *
39*86d7f5d3SJohn Marino  * $DragonFly: src/sys/dev/netif/mii_layer/ukphy_subr.c,v 1.7 2006/08/06 10:32:23 sephe Exp $
40*86d7f5d3SJohn Marino  */
41*86d7f5d3SJohn Marino 
42*86d7f5d3SJohn Marino /*
43*86d7f5d3SJohn Marino  * Subroutines shared by the ukphy driver and other PHY drivers.
44*86d7f5d3SJohn Marino  */
45*86d7f5d3SJohn Marino 
46*86d7f5d3SJohn Marino #include <sys/param.h>
47*86d7f5d3SJohn Marino #include <sys/systm.h>
48*86d7f5d3SJohn Marino #include <sys/kernel.h>
49*86d7f5d3SJohn Marino #include <sys/socket.h>
50*86d7f5d3SJohn Marino #include <sys/module.h>
51*86d7f5d3SJohn Marino #include <sys/bus.h>
52*86d7f5d3SJohn Marino 
53*86d7f5d3SJohn Marino #include <net/if.h>
54*86d7f5d3SJohn Marino #include <net/if_media.h>
55*86d7f5d3SJohn Marino 
56*86d7f5d3SJohn Marino #include "mii.h"
57*86d7f5d3SJohn Marino #include "miivar.h"
58*86d7f5d3SJohn Marino 
59*86d7f5d3SJohn Marino #include "miibus_if.h"
60*86d7f5d3SJohn Marino 
61*86d7f5d3SJohn Marino /*
62*86d7f5d3SJohn Marino  * Media status subroutine.  If a PHY driver does media detection simply
63*86d7f5d3SJohn Marino  * by decoding the NWay autonegotiation, use this routine.
64*86d7f5d3SJohn Marino  */
65*86d7f5d3SJohn Marino void
ukphy_status(struct mii_softc * phy)66*86d7f5d3SJohn Marino ukphy_status(struct mii_softc *phy)
67*86d7f5d3SJohn Marino {
68*86d7f5d3SJohn Marino 	struct mii_data *mii = phy->mii_pdata;
69*86d7f5d3SJohn Marino 	int bmsr, bmcr, anlpar, gtcr, gtsr;
70*86d7f5d3SJohn Marino 
71*86d7f5d3SJohn Marino 	mii->mii_media_status = IFM_AVALID;
72*86d7f5d3SJohn Marino 	mii->mii_media_active = IFM_ETHER;
73*86d7f5d3SJohn Marino 
74*86d7f5d3SJohn Marino 	bmsr = PHY_READ(phy, MII_BMSR) | PHY_READ(phy, MII_BMSR);
75*86d7f5d3SJohn Marino 	if (bmsr & BMSR_LINK)
76*86d7f5d3SJohn Marino 		mii->mii_media_status |= IFM_ACTIVE;
77*86d7f5d3SJohn Marino 
78*86d7f5d3SJohn Marino 	bmcr = PHY_READ(phy, MII_BMCR);
79*86d7f5d3SJohn Marino 	if (bmcr & BMCR_ISO) {
80*86d7f5d3SJohn Marino 		mii->mii_media_active |= IFM_NONE;
81*86d7f5d3SJohn Marino 		mii->mii_media_status = 0;
82*86d7f5d3SJohn Marino 		return;
83*86d7f5d3SJohn Marino 	}
84*86d7f5d3SJohn Marino 
85*86d7f5d3SJohn Marino 	if (bmcr & BMCR_LOOP)
86*86d7f5d3SJohn Marino 		mii->mii_media_active |= IFM_LOOP;
87*86d7f5d3SJohn Marino 
88*86d7f5d3SJohn Marino 	if (bmcr & BMCR_AUTOEN) {
89*86d7f5d3SJohn Marino 		/*
90*86d7f5d3SJohn Marino 		 * NWay autonegotiation takes the highest-order common
91*86d7f5d3SJohn Marino 		 * bit of the ANAR and ANLPAR (i.e. best media advertised
92*86d7f5d3SJohn Marino 		 * both by us and our link partner).
93*86d7f5d3SJohn Marino 		 */
94*86d7f5d3SJohn Marino 		if ((bmsr & BMSR_ACOMP) == 0) {
95*86d7f5d3SJohn Marino 			/* Erg, still trying, I guess... */
96*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_NONE;
97*86d7f5d3SJohn Marino 			return;
98*86d7f5d3SJohn Marino 		}
99*86d7f5d3SJohn Marino 
100*86d7f5d3SJohn Marino 		anlpar = PHY_READ(phy, MII_ANAR) & PHY_READ(phy, MII_ANLPAR);
101*86d7f5d3SJohn Marino 		if ((phy->mii_flags & MIIF_HAVE_GTCR) != 0 &&
102*86d7f5d3SJohn Marino 		    (phy->mii_extcapabilities &
103*86d7f5d3SJohn Marino 		     (EXTSR_1000THDX | EXTSR_1000TFDX)) != 0) {
104*86d7f5d3SJohn Marino 			gtcr = PHY_READ(phy, MII_100T2CR);
105*86d7f5d3SJohn Marino 			gtsr = PHY_READ(phy, MII_100T2SR);
106*86d7f5d3SJohn Marino 		} else {
107*86d7f5d3SJohn Marino 			gtcr = gtsr = 0;
108*86d7f5d3SJohn Marino 		}
109*86d7f5d3SJohn Marino 
110*86d7f5d3SJohn Marino 		if ((gtcr & GTCR_ADV_1000TFDX) && (gtsr & GTSR_LP_1000TFDX))
111*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_1000_T|IFM_FDX;
112*86d7f5d3SJohn Marino 		else if ((gtcr & GTCR_ADV_1000THDX) &&
113*86d7f5d3SJohn Marino 			 (gtsr & GTSR_LP_1000THDX))
114*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_1000_T;
115*86d7f5d3SJohn Marino 		else if (anlpar & ANLPAR_T4)
116*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_100_T4;
117*86d7f5d3SJohn Marino 		else if (anlpar & ANLPAR_TX_FD)
118*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_100_TX|IFM_FDX;
119*86d7f5d3SJohn Marino 		else if (anlpar & ANLPAR_TX)
120*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_100_TX;
121*86d7f5d3SJohn Marino 		else if (anlpar & ANLPAR_10_FD)
122*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_10_T|IFM_FDX;
123*86d7f5d3SJohn Marino 		else if (anlpar & ANLPAR_10)
124*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_10_T;
125*86d7f5d3SJohn Marino 		else
126*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_NONE;
127*86d7f5d3SJohn Marino 
128*86d7f5d3SJohn Marino 		if ((mii->mii_media_active & IFM_1000_T) &&
129*86d7f5d3SJohn Marino 		    (gtsr & GTSR_MS_RES))
130*86d7f5d3SJohn Marino 			mii->mii_media_active |= IFM_ETH_MASTER;
131*86d7f5d3SJohn Marino 
132*86d7f5d3SJohn Marino 		if (mii->mii_media_active & IFM_FDX)
133*86d7f5d3SJohn Marino 			mii->mii_media_active |= mii_phy_flowstatus(phy);
134*86d7f5d3SJohn Marino 	} else {
135*86d7f5d3SJohn Marino 		mii->mii_media_active = mii->mii_media.ifm_cur->ifm_media;
136*86d7f5d3SJohn Marino 	}
137*86d7f5d3SJohn Marino }
138