xref: /titanic_41/usr/src/uts/common/io/mii/mii_realtek.c (revision bbb1277b6ec1b0daad4e3ed1a2b891d3e2ece2eb)
1*bbb1277bSGarrett D'Amore /*
2*bbb1277bSGarrett D'Amore  * CDDL HEADER START
3*bbb1277bSGarrett D'Amore  *
4*bbb1277bSGarrett D'Amore  * The contents of this file are subject to the terms of the
5*bbb1277bSGarrett D'Amore  * Common Development and Distribution License (the "License").
6*bbb1277bSGarrett D'Amore  * You may not use this file except in compliance with the License.
7*bbb1277bSGarrett D'Amore  *
8*bbb1277bSGarrett D'Amore  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*bbb1277bSGarrett D'Amore  * or http://www.opensolaris.org/os/licensing.
10*bbb1277bSGarrett D'Amore  * See the License for the specific language governing permissions
11*bbb1277bSGarrett D'Amore  * and limitations under the License.
12*bbb1277bSGarrett D'Amore  *
13*bbb1277bSGarrett D'Amore  * When distributing Covered Code, include this CDDL HEADER in each
14*bbb1277bSGarrett D'Amore  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*bbb1277bSGarrett D'Amore  * If applicable, add the following below this CDDL HEADER, with the
16*bbb1277bSGarrett D'Amore  * fields enclosed by brackets "[]" replaced with your own identifying
17*bbb1277bSGarrett D'Amore  * information: Portions Copyright [yyyy] [name of copyright owner]
18*bbb1277bSGarrett D'Amore  *
19*bbb1277bSGarrett D'Amore  * CDDL HEADER END
20*bbb1277bSGarrett D'Amore  */
21*bbb1277bSGarrett D'Amore /*
22*bbb1277bSGarrett D'Amore  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23*bbb1277bSGarrett D'Amore  * Use is subject to license terms.
24*bbb1277bSGarrett D'Amore  */
25*bbb1277bSGarrett D'Amore 
26*bbb1277bSGarrett D'Amore /*
27*bbb1277bSGarrett D'Amore  * MII overrides for Cicada (now Vitesse) PHYs.
28*bbb1277bSGarrett D'Amore  */
29*bbb1277bSGarrett D'Amore 
30*bbb1277bSGarrett D'Amore #include <sys/types.h>
31*bbb1277bSGarrett D'Amore #include <sys/ddi.h>
32*bbb1277bSGarrett D'Amore #include <sys/sunddi.h>
33*bbb1277bSGarrett D'Amore #include <sys/mii.h>
34*bbb1277bSGarrett D'Amore #include <sys/miiregs.h>
35*bbb1277bSGarrett D'Amore #include "miipriv.h"
36*bbb1277bSGarrett D'Amore 
37*bbb1277bSGarrett D'Amore 
38*bbb1277bSGarrett D'Amore /*
39*bbb1277bSGarrett D'Amore  * The Realtek 10/100 PHYs are mostly standard compliant, but they
40*bbb1277bSGarrett D'Amore  * lack a true vendor/device ID for the integrated PHY, and they don't
41*bbb1277bSGarrett D'Amore  * report the "detected" non-Nway link speed in the appropriate
42*bbb1277bSGarrett D'Amore  * registers.
43*bbb1277bSGarrett D'Amore  */
44*bbb1277bSGarrett D'Amore static int rtl8139_check(phy_handle_t *);
45*bbb1277bSGarrett D'Amore static int rtl8201_check(phy_handle_t *);
46*bbb1277bSGarrett D'Amore 
47*bbb1277bSGarrett D'Amore boolean_t
phy_realtek_probe(phy_handle_t * ph)48*bbb1277bSGarrett D'Amore phy_realtek_probe(phy_handle_t *ph)
49*bbb1277bSGarrett D'Amore {
50*bbb1277bSGarrett D'Amore 	if ((ph->phy_id == 0) &&
51*bbb1277bSGarrett D'Amore 	    (strcmp(phy_get_driver(ph), "rtls") == 0)) {
52*bbb1277bSGarrett D'Amore 		ph->phy_vendor = "Realtek";
53*bbb1277bSGarrett D'Amore 		ph->phy_model = "Internal RTL8139";
54*bbb1277bSGarrett D'Amore 		ph->phy_check = rtl8139_check;
55*bbb1277bSGarrett D'Amore 		return (B_TRUE);
56*bbb1277bSGarrett D'Amore 	} else if (ph->phy_id == 0x8201) {
57*bbb1277bSGarrett D'Amore 		ph->phy_vendor = "Realtek";
58*bbb1277bSGarrett D'Amore 		ph->phy_model = "RTL8201";
59*bbb1277bSGarrett D'Amore 		ph->phy_check = rtl8201_check;
60*bbb1277bSGarrett D'Amore 		return (B_TRUE);
61*bbb1277bSGarrett D'Amore 	} else {
62*bbb1277bSGarrett D'Amore 		return (B_FALSE);
63*bbb1277bSGarrett D'Amore 	}
64*bbb1277bSGarrett D'Amore }
65*bbb1277bSGarrett D'Amore 
66*bbb1277bSGarrett D'Amore static int
rtl8139_check(phy_handle_t * ph)67*bbb1277bSGarrett D'Amore rtl8139_check(phy_handle_t *ph)
68*bbb1277bSGarrett D'Amore {
69*bbb1277bSGarrett D'Amore 	int		rv;
70*bbb1277bSGarrett D'Amore 	uint16_t	s;
71*bbb1277bSGarrett D'Amore 
72*bbb1277bSGarrett D'Amore 	rv = phy_check(ph);
73*bbb1277bSGarrett D'Amore 
74*bbb1277bSGarrett D'Amore 	/*
75*bbb1277bSGarrett D'Amore 	 * We possibly override settings, so that we can use the PHYs
76*bbb1277bSGarrett D'Amore 	 * autodetected link speed if the partner isn't doing NWay.
77*bbb1277bSGarrett D'Amore 	 */
78*bbb1277bSGarrett D'Amore 	s = phy_read(ph, MII_VENDOR(0));
79*bbb1277bSGarrett D'Amore 	if (s & (1 << 2)) {
80*bbb1277bSGarrett D'Amore 		ph->phy_link = LINK_STATE_DOWN;
81*bbb1277bSGarrett D'Amore 	} else {
82*bbb1277bSGarrett D'Amore 		ph->phy_link = LINK_STATE_UP;
83*bbb1277bSGarrett D'Amore 		if (s & (1 << 3)) {
84*bbb1277bSGarrett D'Amore 			ph->phy_speed = 10;
85*bbb1277bSGarrett D'Amore 		} else {
86*bbb1277bSGarrett D'Amore 			ph->phy_speed = 100;
87*bbb1277bSGarrett D'Amore 		}
88*bbb1277bSGarrett D'Amore 	}
89*bbb1277bSGarrett D'Amore 
90*bbb1277bSGarrett D'Amore 	return (rv);
91*bbb1277bSGarrett D'Amore }
92*bbb1277bSGarrett D'Amore 
93*bbb1277bSGarrett D'Amore static int
rtl8201_check(phy_handle_t * ph)94*bbb1277bSGarrett D'Amore rtl8201_check(phy_handle_t *ph)
95*bbb1277bSGarrett D'Amore {
96*bbb1277bSGarrett D'Amore 	int		rv;
97*bbb1277bSGarrett D'Amore 	uint16_t	s;
98*bbb1277bSGarrett D'Amore 
99*bbb1277bSGarrett D'Amore 	rv = phy_check(ph);
100*bbb1277bSGarrett D'Amore 
101*bbb1277bSGarrett D'Amore 	/*
102*bbb1277bSGarrett D'Amore 	 * We possibly override settings, so that we can use the PHYs
103*bbb1277bSGarrett D'Amore 	 * autodetected link speed if the partner isn't doing NWay.
104*bbb1277bSGarrett D'Amore 	 */
105*bbb1277bSGarrett D'Amore 	s = phy_read(ph, MII_VENDOR(9));
106*bbb1277bSGarrett D'Amore 	if (s & (1 << 0)) {
107*bbb1277bSGarrett D'Amore 		ph->phy_link = LINK_STATE_UP;
108*bbb1277bSGarrett D'Amore 		ph->phy_speed = 100;
109*bbb1277bSGarrett D'Amore 	} else if (s & (1 << 1)) {
110*bbb1277bSGarrett D'Amore 		ph->phy_link = LINK_STATE_UP;
111*bbb1277bSGarrett D'Amore 		ph->phy_speed = 10;
112*bbb1277bSGarrett D'Amore 	} else {
113*bbb1277bSGarrett D'Amore 		ph->phy_link = LINK_STATE_DOWN;
114*bbb1277bSGarrett D'Amore 	}
115*bbb1277bSGarrett D'Amore 
116*bbb1277bSGarrett D'Amore 	return (rv);
117*bbb1277bSGarrett D'Amore }
118