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