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