xref: /titanic_51/usr/src/uts/common/io/atge/atge_mii.c (revision 5e8715b93d1d651ab2805b5e6e98b17df49fa92f)
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