xref: /illumos-gate/usr/src/uts/common/io/nxge/npi/npi_ipp.c (revision 2983dda76a6d296fdb560c88114fe41caad1b84f)
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 2008 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_ipp.h>
29 
30 uint64_t ipp_fzc_offset[] = {
31 		IPP_CONFIG_REG,
32 		IPP_DISCARD_PKT_CNT_REG,
33 		IPP_BAD_CKSUM_ERR_CNT_REG,
34 		IPP_ECC_ERR_COUNTER_REG,
35 		IPP_INT_STATUS_REG,
36 		IPP_INT_MASK_REG,
37 		IPP_PFIFO_RD_DATA0_REG,
38 		IPP_PFIFO_RD_DATA1_REG,
39 		IPP_PFIFO_RD_DATA2_REG,
40 		IPP_PFIFO_RD_DATA3_REG,
41 		IPP_PFIFO_RD_DATA4_REG,
42 		IPP_PFIFO_WR_DATA0_REG,
43 		IPP_PFIFO_WR_DATA1_REG,
44 		IPP_PFIFO_WR_DATA2_REG,
45 		IPP_PFIFO_WR_DATA3_REG,
46 		IPP_PFIFO_WR_DATA4_REG,
47 		IPP_PFIFO_RD_PTR_REG,
48 		IPP_PFIFO_WR_PTR_REG,
49 		IPP_DFIFO_RD_DATA0_REG,
50 		IPP_DFIFO_RD_DATA1_REG,
51 		IPP_DFIFO_RD_DATA2_REG,
52 		IPP_DFIFO_RD_DATA3_REG,
53 		IPP_DFIFO_RD_DATA4_REG,
54 		IPP_DFIFO_WR_DATA0_REG,
55 		IPP_DFIFO_WR_DATA1_REG,
56 		IPP_DFIFO_WR_DATA2_REG,
57 		IPP_DFIFO_WR_DATA3_REG,
58 		IPP_DFIFO_WR_DATA4_REG,
59 		IPP_DFIFO_RD_PTR_REG,
60 		IPP_DFIFO_WR_PTR_REG,
61 		IPP_STATE_MACHINE_REG,
62 		IPP_CKSUM_STATUS_REG,
63 		IPP_FFLP_CKSUM_INFO_REG,
64 		IPP_DEBUG_SELECT_REG,
65 		IPP_DFIFO_ECC_SYNDROME_REG,
66 		IPP_DFIFO_EOPM_RD_PTR_REG,
67 		IPP_ECC_CTRL_REG
68 };
69 
70 const char *ipp_fzc_name[] = {
71 		"IPP_CONFIG_REG",
72 		"IPP_DISCARD_PKT_CNT_REG",
73 		"IPP_BAD_CKSUM_ERR_CNT_REG",
74 		"IPP_ECC_ERR_COUNTER_REG",
75 		"IPP_INT_STATUS_REG",
76 		"IPP_INT_MASK_REG",
77 		"IPP_PFIFO_RD_DATA0_REG",
78 		"IPP_PFIFO_RD_DATA1_REG",
79 		"IPP_PFIFO_RD_DATA2_REG",
80 		"IPP_PFIFO_RD_DATA3_REG",
81 		"IPP_PFIFO_RD_DATA4_REG",
82 		"IPP_PFIFO_WR_DATA0_REG",
83 		"IPP_PFIFO_WR_DATA1_REG",
84 		"IPP_PFIFO_WR_DATA2_REG",
85 		"IPP_PFIFO_WR_DATA3_REG",
86 		"IPP_PFIFO_WR_DATA4_REG",
87 		"IPP_PFIFO_RD_PTR_REG",
88 		"IPP_PFIFO_WR_PTR_REG",
89 		"IPP_DFIFO_RD_DATA0_REG",
90 		"IPP_DFIFO_RD_DATA1_REG",
91 		"IPP_DFIFO_RD_DATA2_REG",
92 		"IPP_DFIFO_RD_DATA3_REG",
93 		"IPP_DFIFO_RD_DATA4_REG",
94 		"IPP_DFIFO_WR_DATA0_REG",
95 		"IPP_DFIFO_WR_DATA1_REG",
96 		"IPP_DFIFO_WR_DATA2_REG",
97 		"IPP_DFIFO_WR_DATA3_REG",
98 		"IPP_DFIFO_WR_DATA4_REG",
99 		"IPP_DFIFO_RD_PTR_REG",
100 		"IPP_DFIFO_WR_PTR_REG",
101 		"IPP_STATE_MACHINE_REG",
102 		"IPP_CKSUM_STATUS_REG",
103 		"IPP_FFLP_CKSUM_INFO_REG",
104 		"IPP_DEBUG_SELECT_REG",
105 		"IPP_DFIFO_ECC_SYNDROME_REG",
106 		"IPP_DFIFO_EOPM_RD_PTR_REG",
107 		"IPP_ECC_CTRL_REG",
108 };
109 
110 npi_status_t
111 npi_ipp_dump_regs(npi_handle_t handle, uint8_t port)
112 {
113 	uint64_t		value, offset;
114 	int 			num_regs, i;
115 
116 	ASSERT(IS_PORT_NUM_VALID(port));
117 
118 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
119 	    "\nIPP PORT Register Dump for port %d\n", port));
120 
121 	num_regs = sizeof (ipp_fzc_offset) / sizeof (uint64_t);
122 	for (i = 0; i < num_regs; i++) {
123 		offset = IPP_REG_ADDR(port, ipp_fzc_offset[i]);
124 #if defined(__i386)
125 		NXGE_REG_RD64(handle, (uint32_t)offset, &value);
126 #else
127 		NXGE_REG_RD64(handle, offset, &value);
128 #endif
129 		NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, "0x%08llx "
130 		    "%s\t 0x%08llx \n",
131 		    offset, ipp_fzc_name[i], value));
132 	}
133 
134 	NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL,
135 	    "\n IPP FZC Register Dump for port %d done\n", port));
136 
137 	return (NPI_SUCCESS);
138 }
139 
140 void
141 npi_ipp_read_regs(npi_handle_t handle, uint8_t port)
142 {
143 	uint64_t		value, offset;
144 	int 			num_regs, i;
145 
146 	ASSERT(IS_PORT_NUM_VALID(port));
147 
148 	NPI_DEBUG_MSG((handle.function, NPI_IPP_CTL,
149 	    "\nIPP PORT Register read (to clear) for port %d\n", port));
150 
151 	num_regs = sizeof (ipp_fzc_offset) / sizeof (uint64_t);
152 	for (i = 0; i < num_regs; i++) {
153 		offset = IPP_REG_ADDR(port, ipp_fzc_offset[i]);
154 #if defined(__i386)
155 		NXGE_REG_RD64(handle, (uint32_t)offset, &value);
156 #else
157 		NXGE_REG_RD64(handle, offset, &value);
158 #endif
159 	}
160 
161 }
162 
163 /*
164  * IPP Reset Routine
165  */
166 npi_status_t
167 npi_ipp_reset(npi_handle_t handle, uint8_t portn)
168 {
169 	uint64_t val = 0;
170 	uint32_t cnt = MAX_PIO_RETRIES;
171 
172 	ASSERT(IS_PORT_NUM_VALID(portn));
173 
174 	IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
175 	val |= IPP_SOFT_RESET;
176 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
177 
178 	do {
179 		NXGE_DELAY(IPP_RESET_WAIT);
180 		IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
181 		cnt--;
182 	} while (((val & IPP_SOFT_RESET) != 0) && (cnt > 0));
183 
184 	if (cnt == 0) {
185 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
186 		    " npi_ipp_reset"
187 		    " HW Error: IPP_RESET  <0x%x>", val));
188 		return (NPI_FAILURE | NPI_IPP_RESET_FAILED(portn));
189 	}
190 
191 	return (NPI_SUCCESS);
192 }
193 
194 
195 /*
196  * IPP Configuration Routine
197  */
198 npi_status_t
199 npi_ipp_config(npi_handle_t handle, config_op_t op, uint8_t portn,
200 		ipp_config_t config)
201 {
202 	uint64_t val = 0;
203 
204 	ASSERT(IS_PORT_NUM_VALID(portn));
205 
206 	switch (op) {
207 
208 	case ENABLE:
209 	case DISABLE:
210 		if ((config == 0) || ((config & ~CFG_IPP_ALL) != 0)) {
211 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
212 			    " npi_ipp_config",
213 			    " Invalid Input config <0x%x>",
214 			    config));
215 			return (NPI_FAILURE | NPI_IPP_CONFIG_INVALID(portn));
216 		}
217 
218 		IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
219 
220 		if (op == ENABLE)
221 			val |= config;
222 		else
223 			val &= ~config;
224 		break;
225 
226 	case INIT:
227 		if ((config & ~CFG_IPP_ALL) != 0) {
228 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
229 			    " npi_ipp_config"
230 			    " Invalid Input config <0x%x>",
231 			    config));
232 			return (NPI_FAILURE | NPI_IPP_CONFIG_INVALID(portn));
233 		}
234 		IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
235 
236 
237 		val &= (IPP_IP_MAX_PKT_BYTES_MASK);
238 		val |= config;
239 		break;
240 
241 	default:
242 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
243 		    " npi_ipp_config"
244 		    " Invalid Input op <0x%x>", op));
245 		return (NPI_FAILURE | NPI_IPP_OPCODE_INVALID(portn));
246 	}
247 
248 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
249 	return (NPI_SUCCESS);
250 }
251 
252 npi_status_t
253 npi_ipp_set_max_pktsize(npi_handle_t handle, uint8_t portn, uint32_t bytes)
254 {
255 	uint64_t val = 0;
256 
257 	ASSERT(IS_PORT_NUM_VALID(portn));
258 
259 	if (bytes > IPP_IP_MAX_PKT_BYTES_MASK) {
260 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
261 		    " npi_ipp_set_max_pktsize"
262 		    " Invalid Input Max bytes <0x%x>",
263 		    bytes));
264 		return (NPI_FAILURE | NPI_IPP_MAX_PKT_BYTES_INVALID(portn));
265 	}
266 
267 	IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
268 	val &= ~(IPP_IP_MAX_PKT_BYTES_MASK << IPP_IP_MAX_PKT_BYTES_SHIFT);
269 
270 	val |= (bytes << IPP_IP_MAX_PKT_BYTES_SHIFT);
271 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
272 
273 	return (NPI_SUCCESS);
274 }
275 
276 /*
277  * IPP Interrupt Configuration Routine
278  */
279 npi_status_t
280 npi_ipp_iconfig(npi_handle_t handle, config_op_t op, uint8_t portn,
281 		ipp_iconfig_t iconfig)
282 {
283 	uint64_t val = 0;
284 
285 	ASSERT(IS_PORT_NUM_VALID(portn));
286 
287 	switch (op) {
288 	case ENABLE:
289 	case DISABLE:
290 
291 		if ((iconfig == 0) || ((iconfig & ~ICFG_IPP_ALL) != 0)) {
292 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
293 			    " npi_ipp_iconfig"
294 			    " Invalid Input iconfig <0x%x>",
295 			    iconfig));
296 			return (NPI_FAILURE | NPI_IPP_CONFIG_INVALID(portn));
297 		}
298 
299 		IPP_REG_RD(handle, portn, IPP_INT_MASK_REG, &val);
300 		if (op == ENABLE)
301 			val &= ~iconfig;
302 		else
303 			val |= iconfig;
304 		IPP_REG_WR(handle, portn, IPP_INT_MASK_REG, val);
305 
306 		break;
307 	case INIT:
308 
309 		if ((iconfig & ~ICFG_IPP_ALL) != 0) {
310 			NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
311 			    " npi_ipp_iconfig"
312 			    " Invalid Input iconfig <0x%x>",
313 			    iconfig));
314 			return (NPI_FAILURE | NPI_IPP_CONFIG_INVALID(portn));
315 		}
316 		IPP_REG_WR(handle, portn, IPP_INT_MASK_REG, ~iconfig);
317 
318 		break;
319 	default:
320 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
321 		    " npi_ipp_iconfig"
322 		    " Invalid Input iconfig <0x%x>",
323 		    iconfig));
324 		return (NPI_FAILURE | NPI_IPP_OPCODE_INVALID(portn));
325 	}
326 
327 	return (NPI_SUCCESS);
328 }
329 
330 npi_status_t
331 npi_ipp_get_status(npi_handle_t handle, uint8_t portn, ipp_status_t *status)
332 {
333 	uint64_t val;
334 
335 	ASSERT(IS_PORT_NUM_VALID(portn));
336 
337 	IPP_REG_RD(handle, portn, IPP_INT_STATUS_REG, &val);
338 
339 	status->value = val;
340 	return (NPI_SUCCESS);
341 }
342 
343 npi_status_t
344 npi_ipp_get_pfifo_rd_ptr(npi_handle_t handle, uint8_t portn, uint16_t *rd_ptr)
345 {
346 	uint64_t value;
347 
348 	ASSERT(IS_PORT_NUM_VALID(portn));
349 
350 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_PTR_REG, &value);
351 	*rd_ptr = value & 0xfff;
352 	return (NPI_SUCCESS);
353 }
354 
355 npi_status_t
356 npi_ipp_get_pfifo_wr_ptr(npi_handle_t handle, uint8_t portn, uint16_t *wr_ptr)
357 {
358 	uint64_t value;
359 
360 	ASSERT(IS_PORT_NUM_VALID(portn));
361 
362 	IPP_REG_RD(handle, portn, IPP_PFIFO_WR_PTR_REG, &value);
363 	*wr_ptr = value & 0xfff;
364 	return (NPI_SUCCESS);
365 }
366 
367 npi_status_t
368 npi_ipp_get_dfifo_rd_ptr(npi_handle_t handle, uint8_t portn, uint16_t *rd_ptr)
369 {
370 	uint64_t value;
371 
372 	ASSERT(IS_PORT_NUM_VALID(portn));
373 
374 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_PTR_REG, &value);
375 	*rd_ptr = (uint16_t)(value & ((portn < 2) ? IPP_XMAC_DFIFO_PTR_MASK :
376 	    IPP_BMAC_DFIFO_PTR_MASK));
377 	return (NPI_SUCCESS);
378 }
379 
380 npi_status_t
381 npi_ipp_get_dfifo_wr_ptr(npi_handle_t handle, uint8_t portn, uint16_t *wr_ptr)
382 {
383 	uint64_t value;
384 
385 	ASSERT(IS_PORT_NUM_VALID(portn));
386 
387 	IPP_REG_RD(handle, portn, IPP_DFIFO_WR_PTR_REG, &value);
388 	*wr_ptr = (uint16_t)(value & ((portn < 2) ? IPP_XMAC_DFIFO_PTR_MASK :
389 	    IPP_BMAC_DFIFO_PTR_MASK));
390 	return (NPI_SUCCESS);
391 }
392 
393 npi_status_t
394 npi_ipp_write_pfifo(npi_handle_t handle, uint8_t portn, uint8_t addr,
395 		uint32_t d0, uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4)
396 {
397 	uint64_t val;
398 
399 	ASSERT(IS_PORT_NUM_VALID(portn));
400 
401 	if (addr >= 64) {
402 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
403 		    " npi_ipp_write_pfifo"
404 		    " Invalid PFIFO address <0x%x>", addr));
405 		return (NPI_FAILURE | NPI_IPP_FIFO_ADDR_INVALID(portn));
406 	}
407 
408 	IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
409 	val |= IPP_PRE_FIFO_PIO_WR_EN;
410 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
411 
412 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_PTR_REG, addr);
413 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_DATA0_REG, d0);
414 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_DATA1_REG, d1);
415 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_DATA2_REG, d2);
416 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_DATA3_REG, d3);
417 	IPP_REG_WR(handle, portn, IPP_PFIFO_WR_DATA4_REG, d4);
418 
419 	val &= ~IPP_PRE_FIFO_PIO_WR_EN;
420 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
421 
422 	return (NPI_SUCCESS);
423 }
424 
425 npi_status_t
426 npi_ipp_read_pfifo(npi_handle_t handle, uint8_t portn, uint8_t addr,
427 		uint32_t *d0, uint32_t *d1, uint32_t *d2, uint32_t *d3,
428 		uint32_t *d4)
429 {
430 	ASSERT(IS_PORT_NUM_VALID(portn));
431 
432 	if (addr >= 64) {
433 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
434 		    " npi_ipp_read_pfifo"
435 		    " Invalid PFIFO address <0x%x>", addr));
436 		return (NPI_FAILURE | NPI_IPP_FIFO_ADDR_INVALID(portn));
437 	}
438 
439 	IPP_REG_WR(handle, portn, IPP_PFIFO_RD_PTR_REG, addr);
440 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_DATA0_REG, d0);
441 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_DATA1_REG, d1);
442 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_DATA2_REG, d2);
443 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_DATA3_REG, d3);
444 	IPP_REG_RD(handle, portn, IPP_PFIFO_RD_DATA4_REG, d4);
445 
446 	return (NPI_SUCCESS);
447 }
448 
449 npi_status_t
450 npi_ipp_write_dfifo(npi_handle_t handle, uint8_t portn, uint16_t addr,
451 		uint32_t d0, uint32_t d1, uint32_t d2, uint32_t d3, uint32_t d4)
452 {
453 	uint64_t val;
454 
455 	ASSERT(IS_PORT_NUM_VALID(portn));
456 
457 	if (addr >= 2048) {
458 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
459 		    " npi_ipp_write_dfifo"
460 		    " Invalid DFIFO address <0x%x>", addr));
461 		return (NPI_FAILURE | NPI_IPP_FIFO_ADDR_INVALID(portn));
462 	}
463 
464 	IPP_REG_RD(handle, portn, IPP_CONFIG_REG, &val);
465 	val |= IPP_DFIFO_PIO_WR_EN;
466 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
467 
468 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_PTR_REG, addr);
469 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_DATA0_REG, d0);
470 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_DATA1_REG, d1);
471 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_DATA2_REG, d2);
472 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_DATA3_REG, d3);
473 	IPP_REG_WR(handle, portn, IPP_DFIFO_WR_DATA4_REG, d4);
474 
475 	val &= ~IPP_DFIFO_PIO_WR_EN;
476 	IPP_REG_WR(handle, portn, IPP_CONFIG_REG, val);
477 
478 	return (NPI_SUCCESS);
479 }
480 
481 npi_status_t
482 npi_ipp_read_dfifo(npi_handle_t handle, uint8_t portn, uint16_t addr,
483 		uint32_t *d0, uint32_t *d1, uint32_t *d2, uint32_t *d3,
484 		uint32_t *d4)
485 {
486 	ASSERT(IS_PORT_NUM_VALID(portn));
487 
488 	if (addr >= 2048) {
489 		NPI_ERROR_MSG((handle.function, NPI_ERR_CTL,
490 		    " npi_ipp_read_dfifo"
491 		    " Invalid DFIFO address <0x%x>", addr));
492 		return (NPI_FAILURE | NPI_IPP_FIFO_ADDR_INVALID(portn));
493 	}
494 
495 	IPP_REG_WR(handle, portn, IPP_DFIFO_RD_PTR_REG, addr);
496 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_DATA0_REG, d0);
497 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_DATA1_REG, d1);
498 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_DATA2_REG, d2);
499 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_DATA3_REG, d3);
500 	IPP_REG_RD(handle, portn, IPP_DFIFO_RD_DATA4_REG, d4);
501 
502 	return (NPI_SUCCESS);
503 }
504 
505 npi_status_t
506 npi_ipp_get_ecc_syndrome(npi_handle_t handle, uint8_t portn, uint16_t *syndrome)
507 {
508 	uint64_t val;
509 
510 	ASSERT(IS_PORT_NUM_VALID(portn));
511 
512 	IPP_REG_RD(handle, portn, IPP_DFIFO_ECC_SYNDROME_REG, &val);
513 
514 	*syndrome = (uint16_t)val;
515 	return (NPI_SUCCESS);
516 }
517 
518 npi_status_t
519 npi_ipp_get_dfifo_eopm_rdptr(npi_handle_t handle, uint8_t portn,
520 							uint16_t *rdptr)
521 {
522 	uint64_t val;
523 
524 	ASSERT(IS_PORT_NUM_VALID(portn));
525 
526 	IPP_REG_RD(handle, portn, IPP_DFIFO_EOPM_RD_PTR_REG, &val);
527 
528 	*rdptr = (uint16_t)val;
529 	return (NPI_SUCCESS);
530 }
531 
532 npi_status_t
533 npi_ipp_get_state_mach(npi_handle_t handle, uint8_t portn, uint32_t *sm)
534 {
535 	uint64_t val;
536 
537 	ASSERT(IS_PORT_NUM_VALID(portn));
538 
539 	IPP_REG_RD(handle, portn, IPP_STATE_MACHINE_REG, &val);
540 
541 	*sm = (uint32_t)val;
542 	return (NPI_SUCCESS);
543 }
544 
545 npi_status_t
546 npi_ipp_get_ecc_err_count(npi_handle_t handle, uint8_t portn, uint8_t *err_cnt)
547 {
548 	ASSERT(IS_PORT_NUM_VALID(portn));
549 
550 	IPP_REG_RD(handle, portn, IPP_ECC_ERR_COUNTER_REG, err_cnt);
551 
552 	return (NPI_SUCCESS);
553 }
554 
555 npi_status_t
556 npi_ipp_get_pkt_dis_count(npi_handle_t handle, uint8_t portn, uint16_t *dis_cnt)
557 {
558 	ASSERT(IS_PORT_NUM_VALID(portn));
559 
560 	IPP_REG_RD(handle, portn, IPP_DISCARD_PKT_CNT_REG, dis_cnt);
561 
562 	return (NPI_SUCCESS);
563 }
564 
565 npi_status_t
566 npi_ipp_get_cs_err_count(npi_handle_t handle, uint8_t portn, uint16_t *err_cnt)
567 {
568 	ASSERT(IS_PORT_NUM_VALID(portn));
569 
570 	IPP_REG_RD(handle, portn, IPP_BAD_CKSUM_ERR_CNT_REG, err_cnt);
571 
572 	return (NPI_SUCCESS);
573 }
574