xref: /illumos-gate/usr/src/uts/common/io/chxge/com/xpak.c (revision 0ccfe5834c3b867c1b6c273cae02ec8922bc0fd2)
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) 2003-2005 Chelsio Communications.  All rights reserved.
24  */
25 
26 #include "cphy.h"
27 #include "elmer0.h"
28 
29 /* ARGSUSED */
30 static int xpak_reset(struct cphy *cphy, int wait)
31 {
32 	return 0;
33 }
34 
35 /* ARGSUSED */
36 static int xpak_interrupt_enable(struct cphy *cphy)
37 {
38 	return 0;
39 }
40 
41 /* ARGSUSED */
42 static int xpak_interrupt_disable(struct cphy *cphy)
43 {
44 	return 0;
45 }
46 
47 /* ARGSUSED */
48 static int xpak_interrupt_clear(struct cphy *cphy)
49 {
50 	return 0;
51 }
52 
53 /* ARGSUSED */
54 static int xpak_set_loopback(struct cphy *cphy, int on)
55 {
56 	return 0;
57 }
58 
59 /* ARGSUSED */
60 static int xpak_get_link_status(struct cphy *cphy, int *link_ok, int *speed,
61 				int *duplex, int *fc)
62 {
63 	if (link_ok)
64 		*link_ok = 1;
65 	if (speed)
66 		*speed = SPEED_10000;
67 	if (duplex)
68 		*duplex = DUPLEX_FULL;
69 	if (fc)
70 		*fc = PAUSE_RX | PAUSE_TX;
71 	return 0;
72 }
73 
74 static void xpak_destroy(struct cphy *cphy)
75 {
76 	t1_os_free((void *)cphy, sizeof(*cphy));
77 }
78 
79 #ifdef C99_NOT_SUPPORTED
80 static struct cphy_ops xpak_ops = {
81 	 xpak_destroy,
82          xpak_reset,
83          xpak_interrupt_enable,
84          xpak_interrupt_disable,
85          xpak_interrupt_clear,
86          NULL,
87          NULL,
88          NULL,
89          NULL,
90          NULL,
91 	 xpak_set_loopback,
92          NULL,
93          xpak_get_link_status,
94 };
95 #else
96 static struct cphy_ops xpak_ops = {
97 	.destroy           = xpak_destroy,
98 	.reset             = xpak_reset,
99 	.interrupt_enable  = xpak_interrupt_enable,
100 	.interrupt_disable = xpak_interrupt_disable,
101 	.interrupt_clear   = xpak_interrupt_clear,
102 	.get_link_status   = xpak_get_link_status,
103 	.set_loopback      = xpak_set_loopback,
104 };
105 #endif
106 
107 /* ARGSUSED */
108 static struct cphy *xpak_phy_create(adapter_t * adapter, int phy_addr,
109 				    struct mdio_ops *mdio_ops)
110 {
111 	struct cphy *cphy = t1_os_malloc_wait_zero(sizeof(*cphy));
112 
113 	if (!cphy)
114 		return NULL;
115 
116 	cphy->ops        = &xpak_ops;
117 	cphy->adapter    = adapter;
118 	cphy->mdio_read  = mdio_ops->read;
119 	cphy->mdio_write = mdio_ops->write;
120 	return cphy;
121 }
122 
123 static int xpak_phy_reset(adapter_t *adapter)
124 {
125 	u32 val;
126 
127 	(void) t1_tpi_read(adapter, A_ELMER0_GPO, &val);
128 	val &= ~4;
129 	(void) t1_tpi_write(adapter, A_ELMER0_GPO, val);
130 	DELAY_MS(100);
131 
132 	/*
133 	 * Errata #26 states to wait 5 seconds after reset before transceiver
134 	 * becomes operational.
135 	 */
136 	(void) t1_tpi_write(adapter, A_ELMER0_GPO, val | 4);
137 	DELAY_MS(5000);
138 
139 	/* Now lets enable the Laser. Delay 100us
140 	 * as defined in XPAK errata.
141 	 */
142 	(void) t1_tpi_read(adapter, A_ELMER0_GPO, &val);
143 	val |= 0x8000;
144 	(void) t1_tpi_write(adapter, A_ELMER0_GPO, val);
145 	DELAY_US(100);
146 	return 0;
147 }
148 
149 struct gphy t1_xpak_ops = {
150 	xpak_phy_create,
151 	xpak_phy_reset
152 };
153 
154