1015a6ef6SSaurabh Misra /* 2*5e8715b9SGary Mills * CDDL HEADER START 3*5e8715b9SGary Mills * 4*5e8715b9SGary Mills * The contents of this file are subject to the terms of the 5*5e8715b9SGary Mills * Common Development and Distribution License (the "License"). 6*5e8715b9SGary Mills * You may not use this file except in compliance with the License. 7*5e8715b9SGary Mills * 8*5e8715b9SGary Mills * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5e8715b9SGary Mills * or http://www.opensolaris.org/os/licensing. 10*5e8715b9SGary Mills * See the License for the specific language governing permissions 11*5e8715b9SGary Mills * and limitations under the License. 12*5e8715b9SGary Mills * 13*5e8715b9SGary Mills * When distributing Covered Code, include this CDDL HEADER in each 14*5e8715b9SGary Mills * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5e8715b9SGary Mills * If applicable, add the following below this CDDL HEADER, with the 16*5e8715b9SGary Mills * fields enclosed by brackets "[]" replaced with your own identifying 17*5e8715b9SGary Mills * information: Portions Copyright [yyyy] [name of copyright owner] 18*5e8715b9SGary Mills * 19*5e8715b9SGary Mills * CDDL HEADER END 20*5e8715b9SGary Mills */ 21*5e8715b9SGary Mills 22*5e8715b9SGary Mills /* 23*5e8715b9SGary Mills * Copyright (c) 2012 Gary Mills 24*5e8715b9SGary Mills * 25*5e8715b9SGary Mills * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 26*5e8715b9SGary Mills */ 27*5e8715b9SGary Mills /* 28015a6ef6SSaurabh Misra * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org> 29015a6ef6SSaurabh Misra * All rights reserved. 30015a6ef6SSaurabh Misra * 31015a6ef6SSaurabh Misra * Redistribution and use in source and binary forms, with or without 32015a6ef6SSaurabh Misra * modification, are permitted provided that the following conditions 33015a6ef6SSaurabh Misra * are met: 34015a6ef6SSaurabh Misra * 1. Redistributions of source code must retain the above copyright 35015a6ef6SSaurabh Misra * notice unmodified, this list of conditions, and the following 36015a6ef6SSaurabh Misra * disclaimer. 37015a6ef6SSaurabh Misra * 2. Redistributions in binary form must reproduce the above copyright 38015a6ef6SSaurabh Misra * notice, this list of conditions and the following disclaimer in the 39015a6ef6SSaurabh Misra * documentation and/or other materials provided with the distribution. 40015a6ef6SSaurabh Misra * 41015a6ef6SSaurabh Misra * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 42015a6ef6SSaurabh Misra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43015a6ef6SSaurabh Misra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44015a6ef6SSaurabh Misra * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45015a6ef6SSaurabh Misra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46015a6ef6SSaurabh Misra * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47015a6ef6SSaurabh Misra * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48015a6ef6SSaurabh Misra * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49015a6ef6SSaurabh Misra * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50015a6ef6SSaurabh Misra * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51015a6ef6SSaurabh Misra * SUCH DAMAGE. 52015a6ef6SSaurabh Misra */ 53015a6ef6SSaurabh Misra 54015a6ef6SSaurabh Misra #include <sys/mii.h> 55015a6ef6SSaurabh Misra #include <sys/miiregs.h> 56015a6ef6SSaurabh Misra 57015a6ef6SSaurabh Misra #include "atge.h" 58015a6ef6SSaurabh Misra #include "atge_cmn_reg.h" 59*5e8715b9SGary Mills #include "atge_l1c_reg.h" 60015a6ef6SSaurabh Misra #include "atge_l1e_reg.h" 610eb090a7SSaurabh Misra #include "atge_l1_reg.h" 62015a6ef6SSaurabh Misra 63015a6ef6SSaurabh Misra uint16_t 64015a6ef6SSaurabh Misra atge_mii_read(void *arg, uint8_t phy, uint8_t reg) 65015a6ef6SSaurabh Misra { 66015a6ef6SSaurabh Misra atge_t *atgep = arg; 67015a6ef6SSaurabh Misra uint32_t v; 68015a6ef6SSaurabh Misra int i; 69015a6ef6SSaurabh Misra 70015a6ef6SSaurabh Misra mutex_enter(&atgep->atge_mii_lock); 71015a6ef6SSaurabh Misra 72015a6ef6SSaurabh Misra OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ | 73015a6ef6SSaurabh Misra MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg)); 74015a6ef6SSaurabh Misra 75015a6ef6SSaurabh Misra for (i = PHY_TIMEOUT; i > 0; i--) { 76015a6ef6SSaurabh Misra drv_usecwait(5); 77015a6ef6SSaurabh Misra v = INL(atgep, ATGE_MDIO); 78015a6ef6SSaurabh Misra if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0) 79015a6ef6SSaurabh Misra break; 80015a6ef6SSaurabh Misra } 81015a6ef6SSaurabh Misra 82015a6ef6SSaurabh Misra mutex_exit(&atgep->atge_mii_lock); 83015a6ef6SSaurabh Misra 84015a6ef6SSaurabh Misra if (i == 0) { 85015a6ef6SSaurabh Misra atge_error(atgep->atge_dip, "PHY (%d) read timeout : %d", 86015a6ef6SSaurabh Misra phy, reg); 87015a6ef6SSaurabh Misra 88015a6ef6SSaurabh Misra return (0xffff); 89015a6ef6SSaurabh Misra } 90015a6ef6SSaurabh Misra 91836d2888SSaurabh Misra /* 92836d2888SSaurabh Misra * Some fast ethernet chips may not be able to auto-nego with 93836d2888SSaurabh Misra * switches even though they have 1000T based PHY. Hence we mask 94836d2888SSaurabh Misra * 1000T based capabilities. 95836d2888SSaurabh Misra */ 96836d2888SSaurabh Misra if (atgep->atge_flags & ATGE_FLAG_FASTETHER) { 97836d2888SSaurabh Misra if (reg == MII_STATUS) 98836d2888SSaurabh Misra v &= ~MII_STATUS_EXTSTAT; 99836d2888SSaurabh Misra else if (reg == MII_EXTSTATUS) 100836d2888SSaurabh Misra v = 0; 101836d2888SSaurabh Misra } 102836d2888SSaurabh Misra 103015a6ef6SSaurabh Misra return ((v & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT); 104015a6ef6SSaurabh Misra } 105015a6ef6SSaurabh Misra 106015a6ef6SSaurabh Misra void 107015a6ef6SSaurabh Misra atge_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val) 108015a6ef6SSaurabh Misra { 109015a6ef6SSaurabh Misra atge_t *atgep = arg; 110015a6ef6SSaurabh Misra uint32_t v; 111015a6ef6SSaurabh Misra int i; 112015a6ef6SSaurabh Misra 113015a6ef6SSaurabh Misra mutex_enter(&atgep->atge_mii_lock); 114015a6ef6SSaurabh Misra 115015a6ef6SSaurabh Misra OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE | 116015a6ef6SSaurabh Misra (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT | 117015a6ef6SSaurabh Misra MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg)); 118015a6ef6SSaurabh Misra 119015a6ef6SSaurabh Misra for (i = PHY_TIMEOUT; i > 0; i--) { 120*5e8715b9SGary Mills drv_usecwait(5); 121015a6ef6SSaurabh Misra v = INL(atgep, ATGE_MDIO); 122015a6ef6SSaurabh Misra if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0) 123015a6ef6SSaurabh Misra break; 124015a6ef6SSaurabh Misra } 125015a6ef6SSaurabh Misra 126015a6ef6SSaurabh Misra mutex_exit(&atgep->atge_mii_lock); 127015a6ef6SSaurabh Misra 128015a6ef6SSaurabh Misra if (i == 0) { 129015a6ef6SSaurabh Misra atge_error(atgep->atge_dip, "PHY (%d) write timeout:reg %d," 130015a6ef6SSaurabh Misra " val :%d", phy, reg, val); 131015a6ef6SSaurabh Misra } 132015a6ef6SSaurabh Misra } 133015a6ef6SSaurabh Misra 134015a6ef6SSaurabh Misra void 135015a6ef6SSaurabh Misra atge_l1e_mii_reset(void *arg) 136015a6ef6SSaurabh Misra { 137015a6ef6SSaurabh Misra atge_t *atgep = arg; 138015a6ef6SSaurabh Misra int phyaddr; 139015a6ef6SSaurabh Misra 140015a6ef6SSaurabh Misra phyaddr = mii_get_addr(atgep->atge_mii); 141015a6ef6SSaurabh Misra 1420eb090a7SSaurabh Misra OUTW(atgep, ATGE_GPHY_CTRL, 143015a6ef6SSaurabh Misra GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET | 144015a6ef6SSaurabh Misra GPHY_CTRL_PHY_PLL_ON); 145015a6ef6SSaurabh Misra drv_usecwait(1000); 146015a6ef6SSaurabh Misra 1470eb090a7SSaurabh Misra OUTW(atgep, ATGE_GPHY_CTRL, 148015a6ef6SSaurabh Misra GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | 149015a6ef6SSaurabh Misra GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON); 150015a6ef6SSaurabh Misra drv_usecwait(1000); 151015a6ef6SSaurabh Misra 152836d2888SSaurabh Misra /* 153836d2888SSaurabh Misra * Some fast ethernet chips may not be able to auto-nego with 154836d2888SSaurabh Misra * switches even though they have 1000T based PHY. Hence we need 155836d2888SSaurabh Misra * to write 0 to MII_MSCONTROL control register. 156836d2888SSaurabh Misra */ 157836d2888SSaurabh Misra if (atgep->atge_flags & ATGE_FLAG_FASTETHER) 158836d2888SSaurabh Misra atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0); 159836d2888SSaurabh Misra 160015a6ef6SSaurabh Misra /* Enable hibernation mode. */ 161015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0B); 162015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xBC00); 163015a6ef6SSaurabh Misra 164015a6ef6SSaurabh Misra /* Set Class A/B for all modes. */ 165015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x00); 166015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x02EF); 167015a6ef6SSaurabh Misra 168015a6ef6SSaurabh Misra /* Enable 10BT power saving. */ 169015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x12); 170015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x4C04); 171015a6ef6SSaurabh Misra 172015a6ef6SSaurabh Misra /* Adjust 1000T power. */ 173015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x04); 174015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x8BBB); 175015a6ef6SSaurabh Misra 176015a6ef6SSaurabh Misra /* 10BT center tap voltage. */ 177015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x05); 178015a6ef6SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x2C46); 179015a6ef6SSaurabh Misra drv_usecwait(1000); 180015a6ef6SSaurabh Misra } 1810eb090a7SSaurabh Misra 1820eb090a7SSaurabh Misra void 1830eb090a7SSaurabh Misra atge_l1_mii_reset(void *arg) 1840eb090a7SSaurabh Misra { 1850eb090a7SSaurabh Misra atge_t *atgep = arg; 1860eb090a7SSaurabh Misra int linkup, i; 1870eb090a7SSaurabh Misra uint16_t reg, pn; 1880eb090a7SSaurabh Misra int phyaddr; 1890eb090a7SSaurabh Misra 1900eb090a7SSaurabh Misra phyaddr = mii_get_addr(atgep->atge_mii); 1910eb090a7SSaurabh Misra 1920eb090a7SSaurabh Misra OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_RST); 1930eb090a7SSaurabh Misra drv_usecwait(1000); 1940eb090a7SSaurabh Misra 1950eb090a7SSaurabh Misra OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_CLR); 1960eb090a7SSaurabh Misra drv_usecwait(1000); 1970eb090a7SSaurabh Misra 1980eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, MII_CONTROL, MII_CONTROL_RESET); 1990eb090a7SSaurabh Misra 2000eb090a7SSaurabh Misra for (linkup = 0, pn = 0; pn < 4; pn++) { 2010eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_CDTC, 2020eb090a7SSaurabh Misra (pn << PHY_CDTC_POFF) | PHY_CDTC_ENB); 2030eb090a7SSaurabh Misra 2040eb090a7SSaurabh Misra for (i = 200; i > 0; i--) { 2050eb090a7SSaurabh Misra drv_usecwait(1000); 2060eb090a7SSaurabh Misra 2070eb090a7SSaurabh Misra reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTC); 2080eb090a7SSaurabh Misra 2090eb090a7SSaurabh Misra if ((reg & PHY_CDTC_ENB) == 0) 2100eb090a7SSaurabh Misra break; 2110eb090a7SSaurabh Misra } 2120eb090a7SSaurabh Misra 2130eb090a7SSaurabh Misra drv_usecwait(1000); 2140eb090a7SSaurabh Misra 2150eb090a7SSaurabh Misra reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTS); 2160eb090a7SSaurabh Misra 2170eb090a7SSaurabh Misra if ((reg & PHY_CDTS_STAT_MASK) != PHY_CDTS_STAT_OPEN) { 2180eb090a7SSaurabh Misra linkup++; 2190eb090a7SSaurabh Misra break; 2200eb090a7SSaurabh Misra } 2210eb090a7SSaurabh Misra } 2220eb090a7SSaurabh Misra 2230eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, MII_CONTROL, 2240eb090a7SSaurabh Misra MII_CONTROL_RESET | MII_CONTROL_ANE | MII_CONTROL_RSAN); 2250eb090a7SSaurabh Misra 2260eb090a7SSaurabh Misra if (linkup == 0) { 2270eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0); 2280eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x124E); 2290eb090a7SSaurabh Misra 2300eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 1); 2310eb090a7SSaurabh Misra reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA); 2320eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg | 0x03); 2330eb090a7SSaurabh Misra 2340eb090a7SSaurabh Misra drv_usecwait(1500 * 1000); 2350eb090a7SSaurabh Misra 2360eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0); 2370eb090a7SSaurabh Misra atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x024E); 2380eb090a7SSaurabh Misra } 2390eb090a7SSaurabh Misra } 240*5e8715b9SGary Mills 241*5e8715b9SGary Mills void 242*5e8715b9SGary Mills atge_l1c_mii_reset(void *arg) 243*5e8715b9SGary Mills { 244*5e8715b9SGary Mills atge_t *atgep = arg; 245*5e8715b9SGary Mills uint16_t data; 246*5e8715b9SGary Mills int phyaddr; 247*5e8715b9SGary Mills 248*5e8715b9SGary Mills phyaddr = mii_get_addr(atgep->atge_mii); 249*5e8715b9SGary Mills 250*5e8715b9SGary Mills /* Reset magic from Linux, via Freebsd */ 251*5e8715b9SGary Mills OUTW(atgep, ATGE_GPHY_CTRL, 252*5e8715b9SGary Mills GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET); 253*5e8715b9SGary Mills (void) INW(atgep, ATGE_GPHY_CTRL); 254*5e8715b9SGary Mills drv_usecwait(10 * 1000); 255*5e8715b9SGary Mills 256*5e8715b9SGary Mills OUTW(atgep, ATGE_GPHY_CTRL, 257*5e8715b9SGary Mills GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | 258*5e8715b9SGary Mills GPHY_CTRL_SEL_ANA_RESET); 259*5e8715b9SGary Mills (void) INW(atgep, ATGE_GPHY_CTRL); 260*5e8715b9SGary Mills drv_usecwait(10 * 1000); 261*5e8715b9SGary Mills 262*5e8715b9SGary Mills /* 263*5e8715b9SGary Mills * Some fast ethernet chips may not be able to auto-nego with 264*5e8715b9SGary Mills * switches even though they have 1000T based PHY. Hence we need 265*5e8715b9SGary Mills * to write 0 to MII_MSCONTROL control register. 266*5e8715b9SGary Mills */ 267*5e8715b9SGary Mills if (atgep->atge_flags & ATGE_FLAG_FASTETHER) 268*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0); 269*5e8715b9SGary Mills 270*5e8715b9SGary Mills /* DSP fixup, Vendor magic. */ 271*5e8715b9SGary Mills switch (ATGE_DID(atgep)) { 272*5e8715b9SGary Mills uint16_t reg; 273*5e8715b9SGary Mills 274*5e8715b9SGary Mills case ATGE_CHIP_AR8152V1_DEV_ID: 275*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x000A); 276*5e8715b9SGary Mills reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA); 277*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xDFFF); 278*5e8715b9SGary Mills /* FALLTHROUGH */ 279*5e8715b9SGary Mills case ATGE_CHIP_AR8151V2_DEV_ID: 280*5e8715b9SGary Mills case ATGE_CHIP_AR8151V1_DEV_ID: 281*5e8715b9SGary Mills case ATGE_CHIP_AR8152V2_DEV_ID: 282*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x003B); 283*5e8715b9SGary Mills reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA); 284*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xFFF7); 285*5e8715b9SGary Mills drv_usecwait(20 * 1000); 286*5e8715b9SGary Mills break; 287*5e8715b9SGary Mills } 288*5e8715b9SGary Mills 289*5e8715b9SGary Mills switch (ATGE_DID(atgep)) { 290*5e8715b9SGary Mills case ATGE_CHIP_AR8151V1_DEV_ID: 291*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029); 292*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x929D); 293*5e8715b9SGary Mills break; 294*5e8715b9SGary Mills case ATGE_CHIP_AR8151V2_DEV_ID: 295*5e8715b9SGary Mills case ATGE_CHIP_AR8152V2_DEV_ID: 296*5e8715b9SGary Mills case ATGE_CHIP_L1CG_DEV_ID: 297*5e8715b9SGary Mills case ATGE_CHIP_L1CF_DEV_ID: 298*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029); 299*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xB6DD); 300*5e8715b9SGary Mills break; 301*5e8715b9SGary Mills } 302*5e8715b9SGary Mills 303*5e8715b9SGary Mills /* Load DSP codes, vendor magic. */ 304*5e8715b9SGary Mills data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE | 305*5e8715b9SGary Mills ((1 << ANA_INTERVAL_SEL_TIMER_SHIFT) & 306*5e8715b9SGary Mills ANA_INTERVAL_SEL_TIMER_MASK); 307*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 308*5e8715b9SGary Mills ATPHY_DBG_ADDR, MII_ANA_CFG18); 309*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 310*5e8715b9SGary Mills ATPHY_DBG_DATA, data); 311*5e8715b9SGary Mills 312*5e8715b9SGary Mills data = ((2 << ANA_SERDES_CDR_BW_SHIFT) & ANA_SERDES_CDR_BW_MASK) | 313*5e8715b9SGary Mills ANA_MS_PAD_DBG | ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP | 314*5e8715b9SGary Mills ANA_SERDES_EN_PLL | ANA_SERDES_EN_LCKDT; 315*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 316*5e8715b9SGary Mills ATPHY_DBG_ADDR, MII_ANA_CFG5); 317*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 318*5e8715b9SGary Mills ATPHY_DBG_DATA, data); 319*5e8715b9SGary Mills 320*5e8715b9SGary Mills data = ((44 << ANA_LONG_CABLE_TH_100_SHIFT) & 321*5e8715b9SGary Mills ANA_LONG_CABLE_TH_100_MASK) | 322*5e8715b9SGary Mills ((33 << ANA_SHORT_CABLE_TH_100_SHIFT) & 323*5e8715b9SGary Mills ANA_SHORT_CABLE_TH_100_SHIFT) | 324*5e8715b9SGary Mills ANA_BP_BAD_LINK_ACCUM | ANA_BP_SMALL_BW; 325*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 326*5e8715b9SGary Mills ATPHY_DBG_ADDR, MII_ANA_CFG54); 327*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 328*5e8715b9SGary Mills ATPHY_DBG_DATA, data); 329*5e8715b9SGary Mills 330*5e8715b9SGary Mills data = ((11 << ANA_IECHO_ADJ_3_SHIFT) & ANA_IECHO_ADJ_3_MASK) | 331*5e8715b9SGary Mills ((11 << ANA_IECHO_ADJ_2_SHIFT) & ANA_IECHO_ADJ_2_MASK) | 332*5e8715b9SGary Mills ((8 << ANA_IECHO_ADJ_1_SHIFT) & ANA_IECHO_ADJ_1_MASK) | 333*5e8715b9SGary Mills ((8 << ANA_IECHO_ADJ_0_SHIFT) & ANA_IECHO_ADJ_0_MASK); 334*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 335*5e8715b9SGary Mills ATPHY_DBG_ADDR, MII_ANA_CFG4); 336*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 337*5e8715b9SGary Mills ATPHY_DBG_DATA, data); 338*5e8715b9SGary Mills 339*5e8715b9SGary Mills data = ((7 & ANA_MANUL_SWICH_ON_SHIFT) & ANA_MANUL_SWICH_ON_MASK) | 340*5e8715b9SGary Mills ANA_RESTART_CAL | ANA_MAN_ENABLE | ANA_SEL_HSP | ANA_EN_HB | 341*5e8715b9SGary Mills ANA_OEN_125M; 342*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 343*5e8715b9SGary Mills ATPHY_DBG_ADDR, MII_ANA_CFG0); 344*5e8715b9SGary Mills atge_mii_write(atgep, phyaddr, 345*5e8715b9SGary Mills ATPHY_DBG_DATA, data); 346*5e8715b9SGary Mills drv_usecwait(1000); 347*5e8715b9SGary Mills } 348*5e8715b9SGary Mills 349*5e8715b9SGary Mills uint16_t 350*5e8715b9SGary Mills atge_l1c_mii_read(void *arg, uint8_t phy, uint8_t reg) 351*5e8715b9SGary Mills { 352*5e8715b9SGary Mills 353*5e8715b9SGary Mills if (phy != 0) { 354*5e8715b9SGary Mills /* avoid PHY address alias */ 355*5e8715b9SGary Mills return (0xffffU); 356*5e8715b9SGary Mills } 357*5e8715b9SGary Mills 358*5e8715b9SGary Mills return (atge_mii_read(arg, phy, reg)); 359*5e8715b9SGary Mills } 360*5e8715b9SGary Mills 361*5e8715b9SGary Mills void 362*5e8715b9SGary Mills atge_l1c_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val) 363*5e8715b9SGary Mills { 364*5e8715b9SGary Mills 365*5e8715b9SGary Mills if (phy != 0) { 366*5e8715b9SGary Mills /* avoid PHY address alias */ 367*5e8715b9SGary Mills return; 368*5e8715b9SGary Mills } 369*5e8715b9SGary Mills 370*5e8715b9SGary Mills if (reg == MII_CONTROL) { 371*5e8715b9SGary Mills /* 372*5e8715b9SGary Mills * Don't issue a reset if MII_CONTROL_RESET is set. 373*5e8715b9SGary Mills * Otherwise it occasionally 374*5e8715b9SGary Mills * advertises incorrect capability. 375*5e8715b9SGary Mills */ 376*5e8715b9SGary Mills if ((val & MII_CONTROL_RESET) == 0) { 377*5e8715b9SGary Mills /* RESET bit is required to set mode */ 378*5e8715b9SGary Mills atge_mii_write(arg, phy, reg, val | MII_CONTROL_RESET); 379*5e8715b9SGary Mills } 380*5e8715b9SGary Mills } else { 381*5e8715b9SGary Mills atge_mii_write(arg, phy, reg, val); 382*5e8715b9SGary Mills } 383*5e8715b9SGary Mills } 384