1*bdb9230aSGarrett D'Amore /* 2*bdb9230aSGarrett D'Amore * CDDL HEADER START 3*bdb9230aSGarrett D'Amore * 4*bdb9230aSGarrett D'Amore * The contents of this file are subject to the terms of the 5*bdb9230aSGarrett D'Amore * Common Development and Distribution License (the "License"). 6*bdb9230aSGarrett D'Amore * You may not use this file except in compliance with the License. 7*bdb9230aSGarrett D'Amore * 8*bdb9230aSGarrett D'Amore * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*bdb9230aSGarrett D'Amore * or http://www.opensolaris.org/os/licensing. 10*bdb9230aSGarrett D'Amore * See the License for the specific language governing permissions 11*bdb9230aSGarrett D'Amore * and limitations under the License. 12*bdb9230aSGarrett D'Amore * 13*bdb9230aSGarrett D'Amore * When distributing Covered Code, include this CDDL HEADER in each 14*bdb9230aSGarrett D'Amore * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*bdb9230aSGarrett D'Amore * If applicable, add the following below this CDDL HEADER, with the 16*bdb9230aSGarrett D'Amore * fields enclosed by brackets "[]" replaced with your own identifying 17*bdb9230aSGarrett D'Amore * information: Portions Copyright [yyyy] [name of copyright owner] 18*bdb9230aSGarrett D'Amore * 19*bdb9230aSGarrett D'Amore * CDDL HEADER END 20*bdb9230aSGarrett D'Amore */ 21*bdb9230aSGarrett D'Amore /* 22*bdb9230aSGarrett D'Amore * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*bdb9230aSGarrett D'Amore * Use is subject to license terms. 24*bdb9230aSGarrett D'Amore */ 25*bdb9230aSGarrett D'Amore 26*bdb9230aSGarrett D'Amore /* 27*bdb9230aSGarrett D'Amore * MII overrides for Quality Semiconductor PHYs. 28*bdb9230aSGarrett D'Amore */ 29*bdb9230aSGarrett D'Amore 30*bdb9230aSGarrett D'Amore #include <sys/types.h> 31*bdb9230aSGarrett D'Amore #include <sys/ddi.h> 32*bdb9230aSGarrett D'Amore #include <sys/sunddi.h> 33*bdb9230aSGarrett D'Amore #include <sys/mii.h> 34*bdb9230aSGarrett D'Amore #include <sys/miiregs.h> 35*bdb9230aSGarrett D'Amore #include "miipriv.h" 36*bdb9230aSGarrett D'Amore 37*bdb9230aSGarrett D'Amore #define QS_IMASK_REG 30 38*bdb9230aSGarrett D'Amore #define QS_BTXPC 31 39*bdb9230aSGarrett D'Amore #define QS_BTXPC_SCRAM_DIS 0x1 40*bdb9230aSGarrett D'Amore 41*bdb9230aSGarrett D'Amore static int 42*bdb9230aSGarrett D'Amore qs6612_reset(phy_handle_t *ph) 43*bdb9230aSGarrett D'Amore { 44*bdb9230aSGarrett D'Amore /* Ordinary reset. */ 45*bdb9230aSGarrett D'Amore if (phy_reset(ph) != DDI_SUCCESS) { 46*bdb9230aSGarrett D'Amore return (DDI_FAILURE); 47*bdb9230aSGarrett D'Amore } 48*bdb9230aSGarrett D'Amore 49*bdb9230aSGarrett D'Amore /* Disable QS6612 proprietary interrupts. */ 50*bdb9230aSGarrett D'Amore phy_write(ph, QS_IMASK_REG, 0); 51*bdb9230aSGarrett D'Amore 52*bdb9230aSGarrett D'Amore return (DDI_SUCCESS); 53*bdb9230aSGarrett D'Amore } 54*bdb9230aSGarrett D'Amore 55*bdb9230aSGarrett D'Amore static int 56*bdb9230aSGarrett D'Amore qs6612_check(phy_handle_t *ph) 57*bdb9230aSGarrett D'Amore { 58*bdb9230aSGarrett D'Amore link_state_t link; 59*bdb9230aSGarrett D'Amore int rv; 60*bdb9230aSGarrett D'Amore 61*bdb9230aSGarrett D'Amore /* 62*bdb9230aSGarrett D'Amore * Apparently some *ancient* Synoptics 28115 firwmare has a bug that 63*bdb9230aSGarrett D'Amore * doesn't connect with certain devices. While I'm fairly sure we 64*bdb9230aSGarrett D'Amore * could probably remove this workaround (for another vendor's bug!) 65*bdb9230aSGarrett D'Amore * at this point, it might crop up as a regression. 66*bdb9230aSGarrett D'Amore * 67*bdb9230aSGarrett D'Amore * Apparently, the workaround is to disable the scrambler for a bit 68*bdb9230aSGarrett D'Amore * once 100 Mbps link is achieved, and then reactivate. This lets 69*bdb9230aSGarrett D'Amore * the busted switch work. We only do it when first bringing up 70*bdb9230aSGarrett D'Amore * the 100 Mbps link. 71*bdb9230aSGarrett D'Amore * 72*bdb9230aSGarrett D'Amore * Yes, I resent having to do this. But the code is carried over 73*bdb9230aSGarrett D'Amore * from old hme/qfe. See 4071199 for details. 74*bdb9230aSGarrett D'Amore */ 75*bdb9230aSGarrett D'Amore link = ph->phy_link; 76*bdb9230aSGarrett D'Amore 77*bdb9230aSGarrett D'Amore rv = phy_check(ph); 78*bdb9230aSGarrett D'Amore 79*bdb9230aSGarrett D'Amore if ((ph->phy_link == LINK_STATE_UP) && (link != LINK_STATE_UP) && 80*bdb9230aSGarrett D'Amore (ph->phy_speed == 100)) { 81*bdb9230aSGarrett D'Amore uint16_t val; 82*bdb9230aSGarrett D'Amore val = phy_read(ph, QS_BTXPC); 83*bdb9230aSGarrett D'Amore phy_write(ph, QS_BTXPC, val | QS_BTXPC_SCRAM_DIS); 84*bdb9230aSGarrett D'Amore drv_usecwait(20); 85*bdb9230aSGarrett D'Amore phy_write(ph, QS_BTXPC, val); 86*bdb9230aSGarrett D'Amore } 87*bdb9230aSGarrett D'Amore 88*bdb9230aSGarrett D'Amore return (rv); 89*bdb9230aSGarrett D'Amore } 90*bdb9230aSGarrett D'Amore 91*bdb9230aSGarrett D'Amore boolean_t 92*bdb9230aSGarrett D'Amore phy_qualsemi_probe(phy_handle_t *ph) 93*bdb9230aSGarrett D'Amore { 94*bdb9230aSGarrett D'Amore if ((MII_PHY_MFG(ph->phy_id) == MII_OUI_QUALITY_SEMI) && 95*bdb9230aSGarrett D'Amore (MII_PHY_MODEL(ph->phy_id) == MII_MODEL_QUALITY_SEMI_QS6612)) { 96*bdb9230aSGarrett D'Amore ph->phy_vendor = "Quality Semiconductor"; 97*bdb9230aSGarrett D'Amore ph->phy_model = "QS6612"; 98*bdb9230aSGarrett D'Amore ph->phy_reset = qs6612_reset; 99*bdb9230aSGarrett D'Amore ph->phy_check = qs6612_check; 100*bdb9230aSGarrett D'Amore return (B_TRUE); 101*bdb9230aSGarrett D'Amore } 102*bdb9230aSGarrett D'Amore return (B_FALSE); 103*bdb9230aSGarrett D'Amore } 104