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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * MII overrides for Intel PHYs. 28 */ 29 30 #include <sys/types.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 #include <sys/cmn_err.h> 34 #include <sys/note.h> 35 #include <sys/mii.h> 36 #include <sys/miiregs.h> 37 #include "miipriv.h" 38 39 #define MII_82555_SPCL_CONTROL MII_VENDOR(1) 40 #define I82555_AUTOPOL_DIS (1<<4) 41 42 /* 43 * The older 82555 code in iprb had a bunch of workarounds to deal 44 * with chip errata surrounding (I believe) autonegotiation problems 45 * with the 82555 and long cables. 46 * 47 * I can't find any evidence in current Linux, NetBSD, or FreeBSD 48 * sources for the same kinds of workarounds for this PHY, so I'm 49 * going to operate on the belief that these workarounds are simply 50 * not necessary. Without access to the errata for these parts, as 51 * well as parts that exhibit the problems, I can't be certain that 52 * such workarounds will work properly. So I'm leaving them out for 53 * now. I believe that the errata were mostly problems for 10 Mbps 54 * links which are very hard to find anymore, anyway. 55 */ 56 57 static int 58 i82555_start(phy_handle_t *ph) 59 { 60 int rv; 61 62 if ((rv = phy_start(ph)) != DDI_SUCCESS) { 63 return (rv); 64 } 65 66 /* 67 * Apparently some devices have problem with 10 Mbps polarity and 68 * short cable lengths. However, these days everyone should be using 69 * 100 Mbps, and rather than retain the extra legacy complexity 70 * here, I'm going to simply offer the choice to disable auto polarity. 71 * 72 * If autopolarity doesn't work for you, you have several choices: 73 * 74 * 1) Find a longer cable. 75 * 2) Upgrade to 100Mbps. 76 * 3) Disable the polarity check by setting AutoPolarity to 0. 77 * 78 * We also believe that 10BASE-T autopolarity may be harmful (because 79 * when used it can prevent use of a superior 100Mbps mode), so we 80 * disable autopolarity by default. 81 */ 82 if (phy_get_prop(ph, "AutoPolarity", 0) == 0) { 83 /* disable autopolarity */ 84 PHY_SET(ph, MII_82555_SPCL_CONTROL, I82555_AUTOPOL_DIS); 85 } else { 86 /* enable basic autopolarity */ 87 PHY_CLR(ph, MII_82555_SPCL_CONTROL, I82555_AUTOPOL_DIS); 88 } 89 90 return (rv); 91 } 92 93 boolean_t 94 phy_intel_probe(phy_handle_t *ph) 95 { 96 const char *model; 97 98 if (MII_PHY_MFG(ph->phy_id) != MII_OUI_INTEL) { 99 return (B_FALSE); 100 } 101 102 switch (MII_PHY_MODEL(ph->phy_id)) { 103 case MII_MODEL_INTEL_82553_CSTEP: 104 model = "82553 C-step"; 105 break; 106 case MII_MODEL_INTEL_82555: 107 ph->phy_start = i82555_start; 108 model = "82555"; 109 break; 110 case MII_MODEL_INTEL_82562_EH: 111 model = "Intel 82562 EH"; 112 break; 113 case MII_MODEL_INTEL_82562_ET: 114 model = "Intel 82562 ET"; 115 break; 116 case MII_MODEL_INTEL_82562_EM: 117 model = "Intel 82562 EM"; 118 break; 119 default: 120 return (B_FALSE); 121 } 122 123 ph->phy_vendor = "Intel"; 124 ph->phy_model = model; 125 126 return (B_TRUE); 127 } 128