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 #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_ECC_ERR_COUNTER_REG, err_cnt); 571 572 return (NPI_SUCCESS); 573 } 574