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