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