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