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
atge_mii_read(void * arg,uint8_t phy,uint8_t reg)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
atge_mii_write(void * arg,uint8_t phy,uint8_t reg,uint16_t val)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
atge_l1e_mii_reset(void * arg)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
atge_l1_mii_reset(void * arg)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
atge_l1c_mii_reset(void * arg)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
atge_l1c_mii_read(void * arg,uint8_t phy,uint8_t reg)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
atge_l1c_mii_write(void * arg,uint8_t phy,uint8_t reg,uint16_t val)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