xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_espc.c (revision 6f45ec7b0b964c3be967c4880e8867ac1e7763a5)
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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 #include <npi_espc.h>
29 #include <nxge_espc.h>
30 
31 npi_status_t
32 npi_espc_pio_enable(npi_handle_t handle)
33 {
34 	NXGE_REG_WR64(handle, ESPC_REG_ADDR(ESPC_PIO_EN_REG), 0x1);
35 	return (NPI_SUCCESS);
36 }
37 
38 npi_status_t
39 npi_espc_pio_disable(npi_handle_t handle)
40 {
41 	NXGE_REG_WR64(handle, ESPC_PIO_EN_REG, 0);
42 	return (NPI_SUCCESS);
43 }
44 
45 npi_status_t
46 npi_espc_eeprom_entry(npi_handle_t handle, io_op_t op, uint32_t addr,
47 			uint8_t *data)
48 {
49 	uint64_t val = 0;
50 
51 	if ((addr & ~EPC_EEPROM_ADDR_BITS) != 0) {
52 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
53 			" npi_espc_eerprom_entry"
54 			" Invalid input addr <0x%x>\n",
55 			addr));
56 		return (NPI_FAILURE | NPI_ESPC_EEPROM_ADDR_INVALID);
57 	}
58 
59 	switch (op) {
60 	case OP_SET:
61 		val = EPC_WRITE_INITIATE | (addr << EPC_EEPROM_ADDR_SHIFT) |
62 			*data;
63 		NXGE_REG_WR64(handle, ESPC_REG_ADDR(ESPC_PIO_STATUS_REG), val);
64 		EPC_WAIT_RW_COMP(handle, &val, EPC_WRITE_COMPLETE);
65 		if ((val & EPC_WRITE_COMPLETE) == 0) {
66 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
67 				" npi_espc_eeprom_entry"
68 				" HW Error: EEPROM_WR <0x%x>\n",
69 				val));
70 			return (NPI_FAILURE | NPI_ESPC_EEPROM_WRITE_FAILED);
71 		}
72 		break;
73 	case OP_GET:
74 		val = EPC_READ_INITIATE | (addr << EPC_EEPROM_ADDR_SHIFT);
75 		NXGE_REG_WR64(handle, ESPC_REG_ADDR(ESPC_PIO_STATUS_REG), val);
76 		EPC_WAIT_RW_COMP(handle, &val, EPC_READ_COMPLETE);
77 		if ((val & EPC_READ_COMPLETE) == 0) {
78 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
79 				" npi_espc_eeprom_entry"
80 				" HW Error: EEPROM_RD <0x%x>",
81 				val));
82 			return (NPI_FAILURE | NPI_ESPC_EEPROM_READ_FAILED);
83 		}
84 		NXGE_REG_RD64(handle, ESPC_REG_ADDR(ESPC_PIO_STATUS_REG), &val);
85 		*data = val & EPC_EEPROM_DATA_MASK;
86 		break;
87 	default:
88 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
89 				    " npi_espc_eeprom_entry"
90 				    " Invalid Input addr <0x%x>\n", addr));
91 		return (NPI_FAILURE | NPI_ESPC_OPCODE_INVALID);
92 	}
93 
94 	return (NPI_SUCCESS);
95 }
96 
97 npi_status_t
98 npi_espc_mac_addr_get(npi_handle_t handle, uint8_t *data)
99 {
100 	mac_addr_0_t mac0;
101 	mac_addr_1_t mac1;
102 
103 	NXGE_REG_RD64(handle, ESPC_MAC_ADDR_0, &mac0.value);
104 	data[0] = mac0.bits.w0.byte0;
105 	data[1] = mac0.bits.w0.byte1;
106 	data[2] = mac0.bits.w0.byte2;
107 	data[3] = mac0.bits.w0.byte3;
108 
109 	NXGE_REG_RD64(handle, ESPC_MAC_ADDR_1, &mac1.value);
110 	data[4] = mac1.bits.w0.byte4;
111 	data[5] = mac1.bits.w0.byte5;
112 
113 	return (NPI_SUCCESS);
114 }
115 
116 npi_status_t
117 npi_espc_num_ports_get(npi_handle_t handle, uint8_t *data)
118 {
119 	uint64_t val = 0;
120 
121 	NXGE_REG_RD64(handle, ESPC_NUM_PORTS_MACS, &val);
122 	val &= NUM_PORTS_MASK;
123 	*data = (uint8_t)val;
124 
125 	return (NPI_SUCCESS);
126 }
127 
128 npi_status_t
129 npi_espc_num_macs_get(npi_handle_t handle, uint8_t *data)
130 {
131 	uint64_t val = 0;
132 
133 	NXGE_REG_RD64(handle, ESPC_NUM_PORTS_MACS, &val);
134 	val &= NUM_MAC_ADDRS_MASK;
135 	val = (val >> NUM_MAC_ADDRS_SHIFT);
136 	*data = (uint8_t)val;
137 
138 	return (NPI_SUCCESS);
139 }
140 
141 npi_status_t
142 npi_espc_model_str_get(npi_handle_t handle, char *data)
143 {
144 	uint64_t val = 0;
145 	uint16_t str_len;
146 	int i, j;
147 
148 	NXGE_REG_RD64(handle, ESPC_MOD_STR_LEN, &val);
149 	val &= MOD_STR_LEN_MASK;
150 	str_len = (uint8_t)val;
151 
152 	if (str_len > MAX_MOD_STR_LEN) {
153 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
154 				" npi_espc_model_str_get"
155 				" Model string length %d exceeds max %d\n",
156 				str_len, MAX_MOD_STR_LEN));
157 		return (NPI_FAILURE | NPI_ESPC_STR_LEN_INVALID);
158 	}
159 
160 	/*
161 	 * Might have to reverse the order depending on how the string
162 	 * is written.
163 	 */
164 	for (i = 0, j = 0; i < str_len; j++) {
165 		NXGE_REG_RD64(handle, ESPC_MOD_STR(j), &val);
166 		data[i++] = ((char *)&val)[3];
167 		data[i++] = ((char *)&val)[2];
168 		data[i++] = ((char *)&val)[1];
169 		data[i++] = ((char *)&val)[0];
170 	}
171 
172 	data[str_len] = '\0';
173 
174 	return (NPI_SUCCESS);
175 }
176 
177 npi_status_t
178 npi_espc_bd_model_str_get(npi_handle_t handle, char *data)
179 {
180 	uint64_t val = 0;
181 	uint16_t str_len;
182 	int i, j;
183 
184 	NXGE_REG_RD64(handle, ESPC_BD_MOD_STR_LEN, &val);
185 	val &= BD_MOD_STR_LEN_MASK;
186 	str_len = (uint8_t)val;
187 
188 	if (str_len > MAX_BD_MOD_STR_LEN) {
189 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
190 				" npi_espc_model_str_get"
191 				" Board Model string length %d "
192 				"exceeds max %d\n",
193 				str_len, MAX_BD_MOD_STR_LEN));
194 		return (NPI_FAILURE | NPI_ESPC_STR_LEN_INVALID);
195 	}
196 
197 	/*
198 	 * Might have to reverse the order depending on how the string
199 	 * is written.
200 	 */
201 	for (i = 0, j = 0; i < str_len; j++) {
202 		NXGE_REG_RD64(handle, ESPC_BD_MOD_STR(j), &val);
203 		data[i++] = ((char *)&val)[3];
204 		data[i++] = ((char *)&val)[2];
205 		data[i++] = ((char *)&val)[1];
206 		data[i++] = ((char *)&val)[0];
207 	}
208 
209 	data[str_len] = '\0';
210 
211 	return (NPI_SUCCESS);
212 }
213 
214 npi_status_t
215 npi_espc_phy_type_get(npi_handle_t handle, uint8_t *data)
216 {
217 	phy_type_t	phy;
218 
219 	NXGE_REG_RD64(handle, ESPC_PHY_TYPE, &phy.value);
220 	data[0] = phy.bits.w0.pt0_phy_type;
221 	data[1] = phy.bits.w0.pt1_phy_type;
222 	data[2] = phy.bits.w0.pt2_phy_type;
223 	data[3] = phy.bits.w0.pt3_phy_type;
224 
225 	return (NPI_SUCCESS);
226 }
227 
228 npi_status_t
229 npi_espc_port_phy_type_get(npi_handle_t handle, uint8_t *data, uint8_t portn)
230 {
231 	phy_type_t	phy;
232 
233 	ASSERT(IS_PORT_NUM_VALID(portn));
234 
235 	NXGE_REG_RD64(handle, ESPC_PHY_TYPE, &phy.value);
236 	switch (portn) {
237 	case 0:
238 		*data = phy.bits.w0.pt0_phy_type;
239 		break;
240 	case 1:
241 		*data = phy.bits.w0.pt1_phy_type;
242 		break;
243 	case 2:
244 		*data = phy.bits.w0.pt2_phy_type;
245 		break;
246 	case 3:
247 		*data = phy.bits.w0.pt3_phy_type;
248 		break;
249 	default:
250 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
251 				" npi_espc_port_phy_type_get"
252 				" Invalid Input: portn <%d>",
253 				portn));
254 		return (NPI_FAILURE | NPI_ESPC_PORT_INVALID);
255 	}
256 
257 	return (NPI_SUCCESS);
258 }
259 
260 npi_status_t
261 npi_espc_max_frame_get(npi_handle_t handle, uint16_t *data)
262 {
263 	uint64_t val = 0;
264 
265 	NXGE_REG_RD64(handle, ESPC_MAX_FM_SZ, &val);
266 	val &= MAX_FM_SZ_MASK;
267 	*data = (uint8_t)val;
268 
269 	return (NPI_SUCCESS);
270 }
271 
272 npi_status_t
273 npi_espc_version_get(npi_handle_t handle, uint16_t *data)
274 {
275 	uint64_t val = 0;
276 
277 	NXGE_REG_RD64(handle, ESPC_VER_IMGSZ, &val);
278 	val &= VER_NUM_MASK;
279 	*data = (uint8_t)val;
280 
281 	return (NPI_SUCCESS);
282 }
283 
284 npi_status_t
285 npi_espc_img_sz_get(npi_handle_t handle, uint16_t *data)
286 {
287 	uint64_t val = 0;
288 
289 	NXGE_REG_RD64(handle, ESPC_VER_IMGSZ, &val);
290 	val &= IMG_SZ_MASK;
291 	val = val >> IMG_SZ_SHIFT;
292 	*data = (uint8_t)val;
293 
294 	return (NPI_SUCCESS);
295 }
296 
297 npi_status_t
298 npi_espc_chksum_get(npi_handle_t handle, uint8_t *data)
299 {
300 	uint64_t val = 0;
301 
302 	NXGE_REG_RD64(handle, ESPC_CHKSUM, &val);
303 	val &= CHKSUM_MASK;
304 	*data = (uint8_t)val;
305 
306 	return (NPI_SUCCESS);
307 }
308 
309 npi_status_t
310 npi_espc_intr_num_get(npi_handle_t handle, uint8_t *data)
311 {
312 	intr_num_t	intr;
313 
314 	NXGE_REG_RD64(handle, ESPC_INTR_NUM, &intr.value);
315 	data[0] = intr.bits.w0.pt0_intr_num;
316 	data[1] = intr.bits.w0.pt1_intr_num;
317 	data[2] = intr.bits.w0.pt2_intr_num;
318 	data[3] = intr.bits.w0.pt3_intr_num;
319 
320 	return (NPI_SUCCESS);
321 }
322 
323 void
324 npi_espc_dump(npi_handle_t handle)
325 {
326 	int i;
327 	uint64_t val = 0;
328 
329 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
330 				    "Dumping SEEPROM registers directly:\n\n"));
331 
332 	for (i = 0; i < 23; i++) {
333 		NXGE_REG_RD64(handle, ESPC_NCR_REGN(i), &val);
334 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
335 					    "reg[%d]      0x%llx\n",
336 					    i, val & 0xffffffff));
337 	}
338 
339 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "\n\n"));
340 }
341 
342 uint32_t
343 npi_espc_reg_get(npi_handle_t handle, int reg_idx)
344 {
345 	uint64_t val = 0;
346 	uint32_t reg_val = 0;
347 
348 	NXGE_REG_RD64(handle, ESPC_NCR_REGN(reg_idx), &val);
349 	reg_val = val & 0xffffffff;
350 
351 	return (reg_val);
352 }
353