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/*
23 * Copyright (c) 2012 Gary Mills
24 *
25 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
26 */
27/*
28 * Copyright (c) 2008, Pyun YongHyeon <yongari@FreeBSD.org>
29 * All rights reserved.
30 *
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
33 * are met:
34 * 1. Redistributions of source code must retain the above copyright
35 *    notice unmodified, this list of conditions, and the following
36 *    disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 *    notice, this list of conditions and the following disclaimer in the
39 *    documentation and/or other materials provided with the distribution.
40 *
41 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 */
53
54#include <sys/mii.h>
55#include <sys/miiregs.h>
56
57#include "atge.h"
58#include "atge_cmn_reg.h"
59#include "atge_l1c_reg.h"
60#include "atge_l1e_reg.h"
61#include "atge_l1_reg.h"
62
63uint16_t
64atge_mii_read(void *arg, uint8_t phy, uint8_t reg)
65{
66	atge_t	*atgep = arg;
67	uint32_t v;
68	int i;
69
70	mutex_enter(&atgep->atge_mii_lock);
71
72	OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_READ |
73	    MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
74
75	for (i = PHY_TIMEOUT; i > 0; i--) {
76		drv_usecwait(5);
77		v = INL(atgep, ATGE_MDIO);
78		if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0)
79			break;
80	}
81
82	mutex_exit(&atgep->atge_mii_lock);
83
84	if (i == 0) {
85		atge_error(atgep->atge_dip, "PHY (%d) read timeout : %d",
86		    phy, reg);
87
88		return (0xffff);
89	}
90
91	/*
92	 * Some fast ethernet chips may not be able to auto-nego with
93	 * switches even though they have 1000T based PHY. Hence we mask
94	 * 1000T based capabilities.
95	 */
96	if (atgep->atge_flags & ATGE_FLAG_FASTETHER) {
97		if (reg == MII_STATUS)
98			v &= ~MII_STATUS_EXTSTAT;
99		else if (reg == MII_EXTSTATUS)
100			v = 0;
101	}
102
103	return ((v & MDIO_DATA_MASK) >> MDIO_DATA_SHIFT);
104}
105
106void
107atge_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val)
108{
109	atge_t	*atgep = arg;
110	uint32_t v;
111	int i;
112
113	mutex_enter(&atgep->atge_mii_lock);
114
115	OUTL(atgep, ATGE_MDIO, MDIO_OP_EXECUTE | MDIO_OP_WRITE |
116	    (val & MDIO_DATA_MASK) << MDIO_DATA_SHIFT |
117	    MDIO_SUP_PREAMBLE | MDIO_CLK_25_4 | MDIO_REG_ADDR(reg));
118
119	for (i = PHY_TIMEOUT; i > 0; i--) {
120		drv_usecwait(5);
121		v = INL(atgep, ATGE_MDIO);
122		if ((v & (MDIO_OP_EXECUTE | MDIO_OP_BUSY)) == 0)
123			break;
124	}
125
126	mutex_exit(&atgep->atge_mii_lock);
127
128	if (i == 0) {
129		atge_error(atgep->atge_dip, "PHY (%d) write timeout:reg %d,"
130		    "  val :%d", phy, reg, val);
131	}
132}
133
134void
135atge_l1e_mii_reset(void *arg)
136{
137	atge_t *atgep = arg;
138	int phyaddr;
139
140	phyaddr = mii_get_addr(atgep->atge_mii);
141
142	OUTW(atgep, ATGE_GPHY_CTRL,
143	    GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET |
144	    GPHY_CTRL_PHY_PLL_ON);
145	drv_usecwait(1000);
146
147	OUTW(atgep, ATGE_GPHY_CTRL,
148	    GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE |
149	    GPHY_CTRL_SEL_ANA_RESET | GPHY_CTRL_PHY_PLL_ON);
150	drv_usecwait(1000);
151
152	/*
153	 * Some fast ethernet chips may not be able to auto-nego with
154	 * switches even though they have 1000T based PHY. Hence we need
155	 * to write 0 to MII_MSCONTROL control register.
156	 */
157	if (atgep->atge_flags & ATGE_FLAG_FASTETHER)
158		atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0);
159
160	/* Enable hibernation mode. */
161	atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0B);
162	atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xBC00);
163
164	/* Set Class A/B for all modes. */
165	atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x00);
166	atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x02EF);
167
168	/* Enable 10BT power saving. */
169	atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x12);
170	atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x4C04);
171
172	/* Adjust 1000T power. */
173	atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x04);
174	atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x8BBB);
175
176	/* 10BT center tap voltage. */
177	atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x05);
178	atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x2C46);
179	drv_usecwait(1000);
180}
181
182void
183atge_l1_mii_reset(void *arg)
184{
185	atge_t *atgep = arg;
186	int linkup, i;
187	uint16_t reg, pn;
188	int phyaddr;
189
190	phyaddr = mii_get_addr(atgep->atge_mii);
191
192	OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_RST);
193	drv_usecwait(1000);
194
195	OUTL(atgep, ATGE_GPHY_CTRL, GPHY_CTRL_CLR);
196	drv_usecwait(1000);
197
198	atge_mii_write(atgep, phyaddr, MII_CONTROL, MII_CONTROL_RESET);
199
200	for (linkup = 0, pn = 0; pn < 4; pn++) {
201		atge_mii_write(atgep, phyaddr, ATPHY_CDTC,
202		    (pn << PHY_CDTC_POFF) | PHY_CDTC_ENB);
203
204		for (i = 200; i > 0; i--) {
205			drv_usecwait(1000);
206
207			reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTC);
208
209			if ((reg & PHY_CDTC_ENB) == 0)
210				break;
211		}
212
213		drv_usecwait(1000);
214
215		reg = atge_mii_read(atgep, phyaddr, ATPHY_CDTS);
216
217		if ((reg & PHY_CDTS_STAT_MASK) != PHY_CDTS_STAT_OPEN) {
218			linkup++;
219			break;
220		}
221	}
222
223	atge_mii_write(atgep, phyaddr, MII_CONTROL,
224	    MII_CONTROL_RESET |  MII_CONTROL_ANE | MII_CONTROL_RSAN);
225
226	if (linkup == 0) {
227		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0);
228		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x124E);
229
230		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 1);
231		reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
232		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg | 0x03);
233
234		drv_usecwait(1500 * 1000);
235
236		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0);
237		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x024E);
238	}
239}
240
241void
242atge_l1c_mii_reset(void *arg)
243{
244	atge_t *atgep = arg;
245	uint16_t data;
246	int phyaddr;
247
248	phyaddr = mii_get_addr(atgep->atge_mii);
249
250	/* Reset magic from Linux, via Freebsd */
251	OUTW(atgep, ATGE_GPHY_CTRL,
252	    GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE | GPHY_CTRL_SEL_ANA_RESET);
253	(void) INW(atgep, ATGE_GPHY_CTRL);
254	drv_usecwait(10 * 1000);
255
256	OUTW(atgep, ATGE_GPHY_CTRL,
257	    GPHY_CTRL_EXT_RESET | GPHY_CTRL_HIB_EN | GPHY_CTRL_HIB_PULSE |
258	    GPHY_CTRL_SEL_ANA_RESET);
259	(void) INW(atgep, ATGE_GPHY_CTRL);
260	drv_usecwait(10 * 1000);
261
262	/*
263	 * Some fast ethernet chips may not be able to auto-nego with
264	 * switches even though they have 1000T based PHY. Hence we need
265	 * to write 0 to MII_MSCONTROL control register.
266	 */
267	if (atgep->atge_flags & ATGE_FLAG_FASTETHER)
268		atge_mii_write(atgep, phyaddr, MII_MSCONTROL, 0x0);
269
270	/* DSP fixup, Vendor magic. */
271	switch (ATGE_DID(atgep)) {
272		uint16_t reg;
273
274	case ATGE_CHIP_AR8152V1_DEV_ID:
275		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x000A);
276		reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
277		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xDFFF);
278		/* FALLTHROUGH */
279	case ATGE_CHIP_AR8151V2_DEV_ID:
280	case ATGE_CHIP_AR8151V1_DEV_ID:
281	case ATGE_CHIP_AR8152V2_DEV_ID:
282		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x003B);
283		reg = atge_mii_read(atgep, phyaddr, ATPHY_DBG_DATA);
284		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, reg & 0xFFF7);
285		drv_usecwait(20 * 1000);
286		break;
287	}
288
289	switch (ATGE_DID(atgep)) {
290	case ATGE_CHIP_AR8151V1_DEV_ID:
291		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029);
292		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0x929D);
293		break;
294	case ATGE_CHIP_AR8151V2_DEV_ID:
295	case ATGE_CHIP_AR8152V2_DEV_ID:
296	case ATGE_CHIP_L1CG_DEV_ID:
297	case ATGE_CHIP_L1CF_DEV_ID:
298		atge_mii_write(atgep, phyaddr, ATPHY_DBG_ADDR, 0x0029);
299		atge_mii_write(atgep, phyaddr, ATPHY_DBG_DATA, 0xB6DD);
300		break;
301	}
302
303	/* Load DSP codes, vendor magic. */
304	data = ANA_LOOP_SEL_10BT | ANA_EN_MASK_TB | ANA_EN_10BT_IDLE |
305	    ((1 << ANA_INTERVAL_SEL_TIMER_SHIFT) &
306	    ANA_INTERVAL_SEL_TIMER_MASK);
307	atge_mii_write(atgep, phyaddr,
308	    ATPHY_DBG_ADDR, MII_ANA_CFG18);
309	atge_mii_write(atgep, phyaddr,
310	    ATPHY_DBG_DATA, data);
311
312	data = ((2 << ANA_SERDES_CDR_BW_SHIFT) & ANA_SERDES_CDR_BW_MASK) |
313	    ANA_MS_PAD_DBG | ANA_SERDES_EN_DEEM | ANA_SERDES_SEL_HSP |
314	    ANA_SERDES_EN_PLL | ANA_SERDES_EN_LCKDT;
315	atge_mii_write(atgep, phyaddr,
316	    ATPHY_DBG_ADDR, MII_ANA_CFG5);
317	atge_mii_write(atgep, phyaddr,
318	    ATPHY_DBG_DATA, data);
319
320	data = ((44 << ANA_LONG_CABLE_TH_100_SHIFT) &
321	    ANA_LONG_CABLE_TH_100_MASK) |
322	    ((33 << ANA_SHORT_CABLE_TH_100_SHIFT) &
323	    ANA_SHORT_CABLE_TH_100_SHIFT) |
324	    ANA_BP_BAD_LINK_ACCUM | ANA_BP_SMALL_BW;
325	atge_mii_write(atgep, phyaddr,
326	    ATPHY_DBG_ADDR, MII_ANA_CFG54);
327	atge_mii_write(atgep, phyaddr,
328	    ATPHY_DBG_DATA, data);
329
330	data = ((11 << ANA_IECHO_ADJ_3_SHIFT) & ANA_IECHO_ADJ_3_MASK) |
331	    ((11 << ANA_IECHO_ADJ_2_SHIFT) & ANA_IECHO_ADJ_2_MASK) |
332	    ((8 << ANA_IECHO_ADJ_1_SHIFT) & ANA_IECHO_ADJ_1_MASK) |
333	    ((8 << ANA_IECHO_ADJ_0_SHIFT) & ANA_IECHO_ADJ_0_MASK);
334	atge_mii_write(atgep, phyaddr,
335	    ATPHY_DBG_ADDR, MII_ANA_CFG4);
336	atge_mii_write(atgep, phyaddr,
337	    ATPHY_DBG_DATA, data);
338
339	data = ((7 & ANA_MANUL_SWICH_ON_SHIFT) & ANA_MANUL_SWICH_ON_MASK) |
340	    ANA_RESTART_CAL | ANA_MAN_ENABLE | ANA_SEL_HSP | ANA_EN_HB |
341	    ANA_OEN_125M;
342	atge_mii_write(atgep, phyaddr,
343	    ATPHY_DBG_ADDR, MII_ANA_CFG0);
344	atge_mii_write(atgep, phyaddr,
345	    ATPHY_DBG_DATA, data);
346	drv_usecwait(1000);
347}
348
349uint16_t
350atge_l1c_mii_read(void *arg, uint8_t phy, uint8_t reg)
351{
352
353	if (phy != 0) {
354		/* avoid PHY address alias */
355		return (0xffffU);
356	}
357
358	return (atge_mii_read(arg, phy, reg));
359}
360
361void
362atge_l1c_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t val)
363{
364
365	if (phy != 0) {
366		/* avoid PHY address alias */
367		return;
368	}
369
370	if (reg == MII_CONTROL) {
371		/*
372		 * Don't issue a reset if MII_CONTROL_RESET is set.
373		 * Otherwise it occasionally
374		 * advertises incorrect capability.
375		 */
376		if ((val & MII_CONTROL_RESET) == 0) {
377			/* RESET bit is required to set mode */
378			atge_mii_write(arg, phy, reg, val | MII_CONTROL_RESET);
379		}
380	} else {
381		atge_mii_write(arg, phy, reg, val);
382	}
383}
384