13859Sml29623 /*
23859Sml29623 * CDDL HEADER START
33859Sml29623 *
43859Sml29623 * The contents of this file are subject to the terms of the
53859Sml29623 * Common Development and Distribution License (the "License").
63859Sml29623 * You may not use this file except in compliance with the License.
73859Sml29623 *
83859Sml29623 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93859Sml29623 * or http://www.opensolaris.org/os/licensing.
103859Sml29623 * See the License for the specific language governing permissions
113859Sml29623 * and limitations under the License.
123859Sml29623 *
133859Sml29623 * When distributing Covered Code, include this CDDL HEADER in each
143859Sml29623 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153859Sml29623 * If applicable, add the following below this CDDL HEADER, with the
163859Sml29623 * fields enclosed by brackets "[]" replaced with your own identifying
173859Sml29623 * information: Portions Copyright [yyyy] [name of copyright owner]
183859Sml29623 *
193859Sml29623 * CDDL HEADER END
203859Sml29623 */
213859Sml29623 /*
226172Syc148097 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
233859Sml29623 * Use is subject to license terms.
243859Sml29623 */
253859Sml29623
263859Sml29623 #pragma ident "%Z%%M% %I% %E% SMI"
273859Sml29623
283859Sml29623 #include <nxge_impl.h>
293859Sml29623 #include <nxge_ipp.h>
303859Sml29623
313859Sml29623 #define NXGE_IPP_FIFO_SYNC_TRY_COUNT 100
323859Sml29623
333859Sml29623 /* ARGSUSED */
343859Sml29623 nxge_status_t
nxge_ipp_init(p_nxge_t nxgep)353859Sml29623 nxge_ipp_init(p_nxge_t nxgep)
363859Sml29623 {
373859Sml29623 uint8_t portn;
383859Sml29623 uint32_t config;
393859Sml29623 npi_handle_t handle;
403859Sml29623 uint32_t pkt_size;
413859Sml29623 ipp_status_t istatus;
423859Sml29623 npi_status_t rs = NPI_SUCCESS;
433859Sml29623 uint64_t val;
443859Sml29623 uint32_t d0, d1, d2, d3, d4;
453859Sml29623 int i;
463859Sml29623 uint32_t dfifo_entries;
473859Sml29623
483859Sml29623 handle = nxgep->npi_handle;
493859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
503859Sml29623
513859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_init: port%d", portn));
523859Sml29623
533859Sml29623 /* Initialize ECC and parity in SRAM of DFIFO and PFIFO */
544732Sdavemq if (nxgep->niu_type == N2_NIU) {
554732Sdavemq dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
564977Sraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
573859Sml29623 if (portn < 2)
583859Sml29623 dfifo_entries = IPP_P0_P1_DFIFO_ENTRIES;
593859Sml29623 else
603859Sml29623 dfifo_entries = IPP_P2_P3_DFIFO_ENTRIES;
614732Sdavemq } else {
623859Sml29623 goto fail;
634732Sdavemq }
643859Sml29623
653859Sml29623 for (i = 0; i < dfifo_entries; i++) {
663859Sml29623 if ((rs = npi_ipp_write_dfifo(handle,
67*6929Smisaki portn, i, 0, 0, 0, 0, 0)) != NPI_SUCCESS)
683859Sml29623 goto fail;
693859Sml29623 if ((rs = npi_ipp_read_dfifo(handle, portn,
70*6929Smisaki i, &d0, &d1, &d2, &d3, &d4)) != NPI_SUCCESS)
713859Sml29623 goto fail;
723859Sml29623 }
733859Sml29623
743859Sml29623 /* Clear PFIFO DFIFO status bits */
753859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
763859Sml29623 goto fail;
773859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
783859Sml29623 goto fail;
793859Sml29623
803859Sml29623 /*
813859Sml29623 * Soft reset to make sure we bring the FIFO pointers back to the
823859Sml29623 * original initial position.
833859Sml29623 */
843859Sml29623 if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS)
853859Sml29623 goto fail;
863859Sml29623
873859Sml29623 /* Clean up ECC counter */
883859Sml29623 IPP_REG_RD(nxgep->npi_handle, portn, IPP_ECC_ERR_COUNTER_REG, &val);
895523Syc148097 IPP_REG_RD(nxgep->npi_handle, portn, IPP_BAD_CKSUM_ERR_CNT_REG, &val);
903859Sml29623 IPP_REG_RD(nxgep->npi_handle, portn, IPP_DISCARD_PKT_CNT_REG, &val);
913859Sml29623
923859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
933859Sml29623 goto fail;
943859Sml29623
953859Sml29623 /* Configure IPP port */
963859Sml29623 if ((rs = npi_ipp_iconfig(handle, INIT, portn, ICFG_IPP_ALL))
97*6929Smisaki != NPI_SUCCESS)
983859Sml29623 goto fail;
993859Sml29623 nxgep->ipp.iconfig = ICFG_IPP_ALL;
1003859Sml29623
1013859Sml29623 config = CFG_IPP | CFG_IPP_DFIFO_ECC_CORRECT | CFG_IPP_DROP_BAD_CRC |
102*6929Smisaki CFG_IPP_TCP_UDP_CKSUM;
1033859Sml29623 if ((rs = npi_ipp_config(handle, INIT, portn, config)) != NPI_SUCCESS)
1043859Sml29623 goto fail;
1053859Sml29623 nxgep->ipp.config = config;
1063859Sml29623
1073859Sml29623 /* Set max packet size */
1083859Sml29623 pkt_size = IPP_MAX_PKT_SIZE;
1093859Sml29623 if ((rs = npi_ipp_set_max_pktsize(handle, portn,
110*6929Smisaki IPP_MAX_PKT_SIZE)) != NPI_SUCCESS)
1113859Sml29623 goto fail;
1123859Sml29623 nxgep->ipp.max_pkt_size = pkt_size;
1133859Sml29623
1143859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "<== nxge_ipp_init: port%d", portn));
1153859Sml29623
1163859Sml29623 return (NXGE_OK);
1173859Sml29623 fail:
1183859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
119*6929Smisaki "nxge_ipp_init: Fail to initialize IPP Port #%d\n",
120*6929Smisaki portn));
1213859Sml29623 return (NXGE_ERROR | rs);
1223859Sml29623 }
1233859Sml29623
1243859Sml29623 /* ARGSUSED */
1253859Sml29623 nxge_status_t
nxge_ipp_disable(p_nxge_t nxgep)1263859Sml29623 nxge_ipp_disable(p_nxge_t nxgep)
1273859Sml29623 {
1283859Sml29623 uint8_t portn;
1293859Sml29623 uint32_t config;
1303859Sml29623 npi_handle_t handle;
1313859Sml29623 npi_status_t rs = NPI_SUCCESS;
1323859Sml29623 uint16_t wr_ptr, rd_ptr;
1333859Sml29623 uint32_t try_count;
1343859Sml29623
1353859Sml29623 handle = nxgep->npi_handle;
1363859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1373859Sml29623
1383859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_disable: port%d", portn));
1393859Sml29623 (void) nxge_rx_mac_disable(nxgep);
1403859Sml29623
1413859Sml29623 /*
1423859Sml29623 * Wait until ip read and write fifo pointers are equal
1433859Sml29623 */
1443859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
1453859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
1463859Sml29623 try_count = NXGE_IPP_FIFO_SYNC_TRY_COUNT;
1473859Sml29623
1483859Sml29623 while ((try_count > 0) && (rd_ptr != wr_ptr)) {
1493859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
1503859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
1513859Sml29623 try_count--;
1523859Sml29623 }
1533859Sml29623
1543859Sml29623 if (try_count == 0) {
1553859Sml29623 if ((rd_ptr != 0) && (wr_ptr != 1)) {
1563859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
157*6929Smisaki " nxge_ipp_disable: port%d failed"
158*6929Smisaki " rd_fifo != wr_fifo", portn));
1593859Sml29623 goto fail;
1603859Sml29623 }
1613859Sml29623 }
1623859Sml29623 /* disable the IPP */
1633859Sml29623 config = nxgep->ipp.config;
1643859Sml29623 if ((rs = npi_ipp_config(handle, DISABLE,
165*6929Smisaki portn, config)) != NPI_SUCCESS)
1663859Sml29623 goto fail;
1673859Sml29623
1683859Sml29623 /* IPP soft reset */
1693859Sml29623 if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS)
1703859Sml29623 goto fail;
1713859Sml29623
1723859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "<== nxge_ipp_disable: port%d", portn));
1733859Sml29623 return (NXGE_OK);
1743859Sml29623 fail:
1753859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
176*6929Smisaki "nxge_ipp_disable: Fail to disable IPP Port #%d\n", portn));
1773859Sml29623 return (NXGE_ERROR | rs);
1783859Sml29623 }
1793859Sml29623
1803859Sml29623 /* ARGSUSED */
1813859Sml29623 nxge_status_t
nxge_ipp_reset(p_nxge_t nxgep)1823859Sml29623 nxge_ipp_reset(p_nxge_t nxgep)
1833859Sml29623 {
1843859Sml29623 uint8_t portn;
1853859Sml29623 uint32_t config;
1863859Sml29623 npi_handle_t handle;
1873859Sml29623 npi_status_t rs = NPI_SUCCESS;
1883859Sml29623 uint16_t wr_ptr, rd_ptr;
1893859Sml29623 uint32_t try_count;
1903859Sml29623
1913859Sml29623 handle = nxgep->npi_handle;
1923859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
1933859Sml29623
1943859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_reset: port%d", portn));
1953859Sml29623
1963859Sml29623 /* disable the IPP */
1973859Sml29623 config = nxgep->ipp.config;
1983859Sml29623 if ((rs = npi_ipp_config(handle, DISABLE,
199*6929Smisaki portn, config)) != NPI_SUCCESS)
2003859Sml29623 goto fail;
2013859Sml29623
2023859Sml29623 /*
2033859Sml29623 * Wait until ip read and write fifo pointers are equal
2043859Sml29623 */
2053859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
2063859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
2073859Sml29623 try_count = NXGE_IPP_FIFO_SYNC_TRY_COUNT;
2083859Sml29623
2093859Sml29623 while ((try_count > 0) && (rd_ptr != wr_ptr)) {
2103859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
2113859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
2123859Sml29623 try_count--;
2133859Sml29623 }
2143859Sml29623
2153859Sml29623 if (try_count == 0) {
2163859Sml29623 if ((rd_ptr != 0) && (wr_ptr != 1)) {
2173859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
218*6929Smisaki " nxge_ipp_disable: port%d failed"
219*6929Smisaki " rd_fifo != wr_fifo", portn));
2203859Sml29623 goto fail;
2213859Sml29623 }
2223859Sml29623 }
2233859Sml29623
2243859Sml29623 /* IPP soft reset */
2253859Sml29623 if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS) {
2263859Sml29623 goto fail;
2273859Sml29623 }
2283859Sml29623
2293859Sml29623 /* to reset control FIFO */
2303859Sml29623 if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS)
2313859Sml29623 goto fail;
2323859Sml29623
2333859Sml29623 /*
2343859Sml29623 * Making sure that error source is cleared if this is an injected
2353859Sml29623 * error.
2363859Sml29623 */
2373859Sml29623 IPP_REG_WR(handle, portn, IPP_ECC_CTRL_REG, 0);
2383859Sml29623
2393859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "<== nxge_ipp_reset: port%d", portn));
2403859Sml29623 return (NXGE_OK);
2413859Sml29623 fail:
2423859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
243*6929Smisaki "nxge_ipp_init: Fail to Reset IPP Port #%d\n",
244*6929Smisaki portn));
2453859Sml29623 return (NXGE_ERROR | rs);
2463859Sml29623 }
2473859Sml29623
2483859Sml29623 /* ARGSUSED */
2493859Sml29623 nxge_status_t
nxge_ipp_enable(p_nxge_t nxgep)2503859Sml29623 nxge_ipp_enable(p_nxge_t nxgep)
2513859Sml29623 {
2523859Sml29623 uint8_t portn;
2533859Sml29623 uint32_t config;
2543859Sml29623 npi_handle_t handle;
2553859Sml29623 uint32_t pkt_size;
2563859Sml29623 npi_status_t rs = NPI_SUCCESS;
2573859Sml29623
2583859Sml29623 handle = nxgep->npi_handle;
2593859Sml29623 portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2603859Sml29623
2613859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_enable: port%d", portn));
2623859Sml29623
2633859Sml29623 config = CFG_IPP | CFG_IPP_DFIFO_ECC_CORRECT | CFG_IPP_DROP_BAD_CRC |
264*6929Smisaki CFG_IPP_TCP_UDP_CKSUM;
2653859Sml29623 if ((rs = npi_ipp_config(handle, INIT, portn, config)) != NPI_SUCCESS)
2663859Sml29623 goto fail;
2673859Sml29623 nxgep->ipp.config = config;
2683859Sml29623
2693859Sml29623 /* Set max packet size */
2703859Sml29623 pkt_size = IPP_MAX_PKT_SIZE;
2713859Sml29623 if ((rs = npi_ipp_set_max_pktsize(handle, portn,
272*6929Smisaki IPP_MAX_PKT_SIZE)) != NPI_SUCCESS)
2733859Sml29623 goto fail;
2743859Sml29623 nxgep->ipp.max_pkt_size = pkt_size;
2753859Sml29623
2763859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "<== nxge_ipp_enable: port%d", portn));
2773859Sml29623 return (NXGE_OK);
2783859Sml29623 fail:
2793859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
280*6929Smisaki "nxge_ipp_init: Fail to Enable IPP Port #%d\n", portn));
2813859Sml29623 return (NXGE_ERROR | rs);
2823859Sml29623 }
2833859Sml29623
2843859Sml29623 /* ARGSUSED */
2853859Sml29623 nxge_status_t
nxge_ipp_drain(p_nxge_t nxgep)2866495Sspeer nxge_ipp_drain(p_nxge_t nxgep)
2876495Sspeer {
2886495Sspeer uint8_t portn;
2896495Sspeer npi_handle_t handle;
2906495Sspeer npi_status_t rs = NPI_SUCCESS;
2916495Sspeer uint16_t wr_ptr, rd_ptr;
2926495Sspeer uint32_t try_count;
2936495Sspeer
2946495Sspeer handle = nxgep->npi_handle;
2956495Sspeer portn = NXGE_GET_PORT_NUM(nxgep->function_num);
2966495Sspeer
2976495Sspeer NXGE_DEBUG_MSG((nxgep, IPP_CTL, "==> nxge_ipp_drain: port%d", portn));
2986495Sspeer
2996495Sspeer /*
3006495Sspeer * Wait until ip read and write fifo pointers are equal
3016495Sspeer */
3026495Sspeer (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
3036495Sspeer (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
3046495Sspeer try_count = NXGE_IPP_FIFO_SYNC_TRY_COUNT;
3056495Sspeer
3066495Sspeer while ((try_count > 0) && (rd_ptr != wr_ptr)) {
3076495Sspeer (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
3086495Sspeer (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
3096495Sspeer try_count--;
3106495Sspeer }
3116495Sspeer
3126495Sspeer if (try_count == 0) {
3136495Sspeer if ((rd_ptr != 0) && (wr_ptr != 1)) {
3146495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
3156495Sspeer " nxge_ipp_drain: port%d failed"
3166495Sspeer " rd_fifo != wr_fifo", portn));
3176495Sspeer goto fail;
3186495Sspeer }
3196495Sspeer }
3206495Sspeer
3216495Sspeer NXGE_DEBUG_MSG((nxgep, IPP_CTL, "<== nxge_ipp_drain: port%d", portn));
3226495Sspeer return (NXGE_OK);
3236495Sspeer fail:
3246495Sspeer NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_ipp_init: "
3256495Sspeer "Fail to Reset IPP Port #%d\n", portn));
3266495Sspeer return (NXGE_ERROR | rs);
3276495Sspeer }
3286495Sspeer
3296495Sspeer /* ARGSUSED */
3306495Sspeer nxge_status_t
nxge_ipp_handle_sys_errors(p_nxge_t nxgep)3313859Sml29623 nxge_ipp_handle_sys_errors(p_nxge_t nxgep)
3323859Sml29623 {
3333859Sml29623 npi_handle_t handle;
3343859Sml29623 npi_status_t rs = NPI_SUCCESS;
3353859Sml29623 p_nxge_ipp_stats_t statsp;
3363859Sml29623 ipp_status_t istatus;
3373859Sml29623 uint8_t portn;
3383859Sml29623 p_ipp_errlog_t errlogp;
3393859Sml29623 boolean_t rxport_fatal = B_FALSE;
3403859Sml29623 nxge_status_t status = NXGE_OK;
3415165Syc148097 uint8_t cnt8;
3425165Syc148097 uint16_t cnt16;
3433859Sml29623
3443859Sml29623 handle = nxgep->npi_handle;
3453859Sml29623 statsp = (p_nxge_ipp_stats_t)&nxgep->statsp->ipp_stats;
3463859Sml29623 portn = nxgep->mac.portnum;
3473859Sml29623
3483859Sml29623 errlogp = (p_ipp_errlog_t)&statsp->errlog;
3493859Sml29623
3503859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
3513859Sml29623 return (NXGE_ERROR | rs);
3523859Sml29623
3533859Sml29623 if (istatus.value == 0) {
3543859Sml29623 /*
3553859Sml29623 * The error is not initiated from this port, so just exit.
3563859Sml29623 */
3573859Sml29623 return (NXGE_OK);
3583859Sml29623 }
3593859Sml29623
3603859Sml29623 if (istatus.bits.w0.dfifo_missed_sop) {
3613859Sml29623 statsp->sop_miss++;
3623859Sml29623 if ((rs = npi_ipp_get_dfifo_eopm_rdptr(handle, portn,
363*6929Smisaki &errlogp->dfifo_rd_ptr)) != NPI_SUCCESS)
3643859Sml29623 return (NXGE_ERROR | rs);
3653859Sml29623 if ((rs = npi_ipp_get_state_mach(handle, portn,
366*6929Smisaki &errlogp->state_mach)) != NPI_SUCCESS)
3673859Sml29623 return (NXGE_ERROR | rs);
3683859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
369*6929Smisaki NXGE_FM_EREPORT_IPP_SOP_MISS);
3703859Sml29623 if (statsp->sop_miss < IPP_MAX_ERR_SHOW)
3713859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
372*6929Smisaki "nxge_ipp_err_evnts: fatal error: sop_miss\n"));
3733859Sml29623 rxport_fatal = B_TRUE;
3743859Sml29623 }
3753859Sml29623 if (istatus.bits.w0.dfifo_missed_eop) {
3763859Sml29623 statsp->eop_miss++;
3773859Sml29623 if ((rs = npi_ipp_get_dfifo_eopm_rdptr(handle, portn,
378*6929Smisaki &errlogp->dfifo_rd_ptr)) != NPI_SUCCESS)
3793859Sml29623 return (NXGE_ERROR | rs);
3803859Sml29623 if ((rs = npi_ipp_get_state_mach(handle, portn,
381*6929Smisaki &errlogp->state_mach)) != NPI_SUCCESS)
3823859Sml29623 return (NXGE_ERROR | rs);
3833859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
384*6929Smisaki NXGE_FM_EREPORT_IPP_EOP_MISS);
3853859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
386*6929Smisaki "nxge_ipp_err_evnts: fatal error: eop_miss\n"));
3873859Sml29623 rxport_fatal = B_TRUE;
3883859Sml29623 }
3893859Sml29623 if (istatus.bits.w0.dfifo_uncorr_ecc_err) {
3903859Sml29623 boolean_t ue_ecc_valid;
3913859Sml29623
3923859Sml29623 if ((status = nxge_ipp_eccue_valid_check(nxgep,
393*6929Smisaki &ue_ecc_valid)) != NXGE_OK)
3943859Sml29623 return (status);
3953859Sml29623
3963859Sml29623 if (ue_ecc_valid) {
3973859Sml29623 statsp->dfifo_ue++;
3983859Sml29623 if ((rs = npi_ipp_get_ecc_syndrome(handle, portn,
399*6929Smisaki &errlogp->ecc_syndrome)) != NPI_SUCCESS)
4003859Sml29623 return (NXGE_ERROR | rs);
4013859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
402*6929Smisaki NXGE_FM_EREPORT_IPP_DFIFO_UE);
4033859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
404*6929Smisaki "nxge_ipp_err_evnts: fatal error: dfifo_ue\n"));
4053859Sml29623 rxport_fatal = B_TRUE;
4063859Sml29623 }
4073859Sml29623 }
4083859Sml29623 if (istatus.bits.w0.pre_fifo_perr) {
4093859Sml29623 statsp->pfifo_perr++;
4103859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
411*6929Smisaki NXGE_FM_EREPORT_IPP_PFIFO_PERR);
4123859Sml29623 if (statsp->pfifo_perr < IPP_MAX_ERR_SHOW)
4133859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
414*6929Smisaki "nxge_ipp_err_evnts: "
415*6929Smisaki "fatal error: pre_pifo_perr\n"));
4163859Sml29623 rxport_fatal = B_TRUE;
4173859Sml29623 }
4183859Sml29623 if (istatus.bits.w0.pre_fifo_overrun) {
4193859Sml29623 statsp->pfifo_over++;
4203859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
421*6929Smisaki NXGE_FM_EREPORT_IPP_PFIFO_OVER);
4223859Sml29623 if (statsp->pfifo_over < IPP_MAX_ERR_SHOW)
4233859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
424*6929Smisaki "nxge_ipp_err_evnts: "
425*6929Smisaki "fatal error: pfifo_over\n"));
4263859Sml29623 rxport_fatal = B_TRUE;
4273859Sml29623 }
4283859Sml29623 if (istatus.bits.w0.pre_fifo_underrun) {
4293859Sml29623 statsp->pfifo_und++;
4303859Sml29623 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
431*6929Smisaki NXGE_FM_EREPORT_IPP_PFIFO_UND);
4323859Sml29623 if (statsp->pfifo_und < IPP_MAX_ERR_SHOW)
4333859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
434*6929Smisaki "nxge_ipp_err_evnts: "
435*6929Smisaki "fatal error: pfifo_und\n"));
4363859Sml29623 rxport_fatal = B_TRUE;
4373859Sml29623 }
4383859Sml29623 if (istatus.bits.w0.bad_cksum_cnt_ovfl) {
4395222Syc148097 /*
4406172Syc148097 * Do not send FMA ereport or log error message
4416172Syc148097 * in /var/adm/messages because this error does not
4426172Syc148097 * indicate a HW failure.
4436172Syc148097 *
4445222Syc148097 * Clear bit BAD_CS_MX of register IPP_INT_STAT
4455222Syc148097 * by reading register IPP_BAD_CS_CNT
4465222Syc148097 */
4475165Syc148097 (void) npi_ipp_get_cs_err_count(handle, portn, &cnt16);
4483859Sml29623 statsp->bad_cs_cnt += IPP_BAD_CS_CNT_MASK;
4493859Sml29623 }
4503859Sml29623 if (istatus.bits.w0.pkt_discard_cnt_ovfl) {
4515222Syc148097 /*
4526172Syc148097 * Do not send FMA ereport or log error message
4536172Syc148097 * in /var/adm/messages because this error does not
4546172Syc148097 * indicate a HW failure.
4556172Syc148097 *
4565222Syc148097 * Clear bit PKT_DIS_MX of register IPP_INT_STAT
4575222Syc148097 * by reading register IPP_PKT_DIS
4585222Syc148097 */
4595165Syc148097 (void) npi_ipp_get_pkt_dis_count(handle, portn, &cnt16);
4603859Sml29623 statsp->pkt_dis_cnt += IPP_PKT_DIS_CNT_MASK;
4613859Sml29623 }
4625165Syc148097 if (istatus.bits.w0.ecc_err_cnt_ovfl) {
4635222Syc148097 /*
4645222Syc148097 * Clear bit ECC_ERR_MAX of register IPP_INI_STAT
4655222Syc148097 * by reading register IPP_ECC
4665222Syc148097 */
4675165Syc148097 (void) npi_ipp_get_ecc_err_count(handle, portn, &cnt8);
4685165Syc148097 statsp->ecc_err_cnt += IPP_ECC_CNT_MASK;
4695523Syc148097 /*
4705523Syc148097 * A defect in Neptune port2's IPP module could generate
4715523Syc148097 * many fake but harmless ECC errors under stress and cause
4725523Syc148097 * the ecc-error-counter register IPP_ECC to reach its
4735523Syc148097 * maximum value in a few seconds. To avoid false alarm, do
4745523Syc148097 * not report the error if it is port2.
4755523Syc148097 */
4765523Syc148097 if (portn != 2) {
4775523Syc148097 NXGE_FM_REPORT_ERROR(nxgep, portn, NULL,
4785523Syc148097 NXGE_FM_EREPORT_IPP_ECC_ERR_MAX);
4795523Syc148097 if (statsp->ecc_err_cnt < (IPP_MAX_ERR_SHOW *
4805523Syc148097 IPP_ECC_CNT_MASK)) {
4815523Syc148097 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
4825523Syc148097 "nxge_ipp_err_evnts: pkt_ecc_err_max\n"));
4835523Syc148097 }
4845523Syc148097 }
4855165Syc148097 }
4863859Sml29623 /*
4873859Sml29623 * Making sure that error source is cleared if this is an injected
4883859Sml29623 * error.
4893859Sml29623 */
4903859Sml29623 IPP_REG_WR(handle, portn, IPP_ECC_CTRL_REG, 0);
4913859Sml29623
4923859Sml29623 if (rxport_fatal) {
4933859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL,
494*6929Smisaki " nxge_ipp_handle_sys_errors:"
495*6929Smisaki " fatal Error on Port #%d\n", portn));
4963859Sml29623 status = nxge_ipp_fatal_err_recover(nxgep);
4973859Sml29623 if (status == NXGE_OK) {
4983859Sml29623 FM_SERVICE_RESTORED(nxgep);
4993859Sml29623 }
5003859Sml29623 }
5013859Sml29623 return (status);
5023859Sml29623 }
5033859Sml29623
5043859Sml29623 /* ARGSUSED */
5053859Sml29623 void
nxge_ipp_inject_err(p_nxge_t nxgep,uint32_t err_id)5063859Sml29623 nxge_ipp_inject_err(p_nxge_t nxgep, uint32_t err_id)
5073859Sml29623 {
5083859Sml29623 ipp_status_t ipps;
5093859Sml29623 ipp_ecc_ctrl_t ecc_ctrl;
5103859Sml29623 uint8_t portn = nxgep->mac.portnum;
5113859Sml29623
5123859Sml29623 switch (err_id) {
5133859Sml29623 case NXGE_FM_EREPORT_IPP_DFIFO_UE:
5143859Sml29623 ecc_ctrl.value = 0;
5153859Sml29623 ecc_ctrl.bits.w0.cor_dbl = 1;
5163859Sml29623 ecc_ctrl.bits.w0.cor_1 = 1;
5173859Sml29623 ecc_ctrl.bits.w0.cor_lst = 1;
5183859Sml29623 cmn_err(CE_NOTE, "!Write 0x%llx to IPP_ECC_CTRL_REG\n",
519*6929Smisaki (unsigned long long) ecc_ctrl.value);
5203859Sml29623 IPP_REG_WR(nxgep->npi_handle, portn, IPP_ECC_CTRL_REG,
521*6929Smisaki ecc_ctrl.value);
5223859Sml29623 break;
5233859Sml29623
5243859Sml29623 case NXGE_FM_EREPORT_IPP_DFIFO_CE:
5253859Sml29623 ecc_ctrl.value = 0;
5263859Sml29623 ecc_ctrl.bits.w0.cor_sng = 1;
5273859Sml29623 ecc_ctrl.bits.w0.cor_1 = 1;
5283859Sml29623 ecc_ctrl.bits.w0.cor_snd = 1;
5293859Sml29623 cmn_err(CE_NOTE, "!Write 0x%llx to IPP_ECC_CTRL_REG\n",
530*6929Smisaki (unsigned long long) ecc_ctrl.value);
5313859Sml29623 IPP_REG_WR(nxgep->npi_handle, portn, IPP_ECC_CTRL_REG,
532*6929Smisaki ecc_ctrl.value);
5333859Sml29623 break;
5343859Sml29623
5353859Sml29623 case NXGE_FM_EREPORT_IPP_EOP_MISS:
5363859Sml29623 case NXGE_FM_EREPORT_IPP_SOP_MISS:
5373859Sml29623 case NXGE_FM_EREPORT_IPP_PFIFO_PERR:
5383859Sml29623 case NXGE_FM_EREPORT_IPP_ECC_ERR_MAX:
5393859Sml29623 case NXGE_FM_EREPORT_IPP_PFIFO_OVER:
5403859Sml29623 case NXGE_FM_EREPORT_IPP_PFIFO_UND:
5413859Sml29623 case NXGE_FM_EREPORT_IPP_BAD_CS_MX:
5423859Sml29623 case NXGE_FM_EREPORT_IPP_PKT_DIS_MX:
5433859Sml29623 case NXGE_FM_EREPORT_IPP_RESET_FAIL:
5443859Sml29623 IPP_REG_RD(nxgep->npi_handle, portn, IPP_INT_STATUS_REG,
545*6929Smisaki &ipps.value);
5463859Sml29623 if (err_id == NXGE_FM_EREPORT_IPP_EOP_MISS)
5473859Sml29623 ipps.bits.w0.dfifo_missed_eop = 1;
5483859Sml29623 else if (err_id == NXGE_FM_EREPORT_IPP_SOP_MISS)
5493859Sml29623 ipps.bits.w0.dfifo_missed_sop = 1;
5503859Sml29623 else if (err_id == NXGE_FM_EREPORT_IPP_DFIFO_UE)
5513859Sml29623 ipps.bits.w0.dfifo_uncorr_ecc_err = 1;
5523859Sml29623 else if (err_id == NXGE_FM_EREPORT_IPP_DFIFO_CE)
5533859Sml29623 ipps.bits.w0.dfifo_corr_ecc_err = 1;
5543859Sml29623 else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_PERR)
5553859Sml29623 ipps.bits.w0.pre_fifo_perr = 1;
5565222Syc148097 else if (err_id == NXGE_FM_EREPORT_IPP_ECC_ERR_MAX) {
5575222Syc148097 /*
5585222Syc148097 * Fill register IPP_ECC with max ECC-error-
5595222Syc148097 * counter value (0xff) to set the ECC_ERR_MAX bit
5605222Syc148097 * of the IPP_INT_STAT register and trigger an
5615222Syc148097 * FMA ereport.
5625222Syc148097 */
5635222Syc148097 IPP_REG_WR(nxgep->npi_handle, portn,
5645222Syc148097 IPP_ECC_ERR_COUNTER_REG, IPP_ECC_CNT_MASK);
5655222Syc148097 } else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_OVER)
5663859Sml29623 ipps.bits.w0.pre_fifo_overrun = 1;
5673859Sml29623 else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_UND)
5683859Sml29623 ipps.bits.w0.pre_fifo_underrun = 1;
5695222Syc148097 else if (err_id == NXGE_FM_EREPORT_IPP_BAD_CS_MX) {
5705222Syc148097 /*
5715222Syc148097 * Fill IPP_BAD_CS_CNT with max bad-checksum-counter
5725222Syc148097 * value (0x3fff) to set the BAD_CS_MX bit of
5735222Syc148097 * IPP_INT_STAT and trigger an FMA ereport.
5745222Syc148097 */
5755222Syc148097 IPP_REG_WR(nxgep->npi_handle, portn,
5765523Syc148097 IPP_BAD_CKSUM_ERR_CNT_REG, IPP_BAD_CS_CNT_MASK);
5775222Syc148097 } else if (err_id == NXGE_FM_EREPORT_IPP_PKT_DIS_MX) {
5785222Syc148097 /*
5795222Syc148097 * Fill IPP_PKT_DIS with max packet-discard-counter
5805222Syc148097 * value (0x3fff) to set the PKT_DIS_MX bit of
5815222Syc148097 * IPP_INT_STAT and trigger an FMA ereport.
5825222Syc148097 */
5835222Syc148097 IPP_REG_WR(nxgep->npi_handle, portn,
5845222Syc148097 IPP_DISCARD_PKT_CNT_REG, IPP_PKT_DIS_CNT_MASK);
5855222Syc148097 }
5863859Sml29623 cmn_err(CE_NOTE, "!Write 0x%llx to IPP_INT_STATUS_REG\n",
587*6929Smisaki (unsigned long long) ipps.value);
5883859Sml29623 IPP_REG_WR(nxgep->npi_handle, portn, IPP_INT_STATUS_REG,
589*6929Smisaki ipps.value);
5903859Sml29623 break;
5913859Sml29623 }
5923859Sml29623 }
5933859Sml29623
5943859Sml29623 /* ARGSUSED */
5953859Sml29623 nxge_status_t
nxge_ipp_fatal_err_recover(p_nxge_t nxgep)5963859Sml29623 nxge_ipp_fatal_err_recover(p_nxge_t nxgep)
5973859Sml29623 {
5983859Sml29623 npi_handle_t handle;
5993859Sml29623 npi_status_t rs = NPI_SUCCESS;
6003859Sml29623 nxge_status_t status = NXGE_OK;
6013859Sml29623 uint8_t portn;
6023859Sml29623 uint16_t wr_ptr;
6033859Sml29623 uint16_t rd_ptr;
6043859Sml29623 uint32_t try_count;
6053859Sml29623 uint32_t dfifo_entries;
6063859Sml29623 ipp_status_t istatus;
6073859Sml29623 uint32_t d0, d1, d2, d3, d4;
6083859Sml29623 int i;
6093859Sml29623
6103859Sml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "<== nxge_ipp_fatal_err_recover"));
6113859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
612*6929Smisaki "Recovering from RxPort error..."));
6133859Sml29623
6143859Sml29623 handle = nxgep->npi_handle;
6153859Sml29623 portn = nxgep->mac.portnum;
6163859Sml29623
6173859Sml29623 /*
6183859Sml29623 * Making sure that error source is cleared if this is an injected
6193859Sml29623 * error.
6203859Sml29623 */
6213859Sml29623 IPP_REG_WR(handle, portn, IPP_ECC_CTRL_REG, 0);
6223859Sml29623
6233859Sml29623 /* Disable RxMAC */
6243859Sml29623 if (nxge_rx_mac_disable(nxgep) != NXGE_OK)
6253859Sml29623 goto fail;
6263859Sml29623
6273859Sml29623 /* When recovering from IPP, RxDMA channel resets are not necessary */
6283859Sml29623 /* Reset ZCP CFIFO */
6293859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "port%d Reset ZCP CFIFO...", portn));
6303859Sml29623 if ((rs = npi_zcp_rest_cfifo_port(handle, portn)) != NPI_SUCCESS)
6313859Sml29623 goto fail;
6323859Sml29623
6333859Sml29623 /*
6343859Sml29623 * Wait until ip read and write fifo pointers are equal
6353859Sml29623 */
6363859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
6373859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
6383859Sml29623 try_count = 512;
6393859Sml29623
6403859Sml29623 while ((try_count > 0) && (rd_ptr != wr_ptr)) {
6413859Sml29623 (void) npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr);
6423859Sml29623 (void) npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr);
6433859Sml29623 try_count--;
6443859Sml29623 }
6453859Sml29623
6463859Sml29623 if (try_count == 0) {
6473859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
648*6929Smisaki " nxge_ipp_reset: port%d IPP stalled..."
649*6929Smisaki " rd_fifo_ptr = 0x%x wr_fifo_ptr = 0x%x",
650*6929Smisaki portn, rd_ptr, wr_ptr));
6513859Sml29623 /*
6523859Sml29623 * This means the fatal error occurred on the first line of the
6533859Sml29623 * fifo. In this case, just reset the IPP without draining the
6543859Sml29623 * PFIFO.
6553859Sml29623 */
6563859Sml29623 }
6573859Sml29623
6584732Sdavemq if (nxgep->niu_type == N2_NIU) {
6594732Sdavemq dfifo_entries = IPP_NIU_DFIFO_ENTRIES;
6604977Sraghus } else if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) {
6613859Sml29623 if (portn < 2)
6623859Sml29623 dfifo_entries = IPP_P0_P1_DFIFO_ENTRIES;
6633859Sml29623 else
6643859Sml29623 dfifo_entries = IPP_P2_P3_DFIFO_ENTRIES;
6654732Sdavemq } else {
6663859Sml29623 goto fail;
6674732Sdavemq }
6683859Sml29623
6693859Sml29623 /* Clean up DFIFO SRAM entries */
6703859Sml29623 for (i = 0; i < dfifo_entries; i++) {
6713859Sml29623 if ((rs = npi_ipp_write_dfifo(handle, portn,
672*6929Smisaki i, 0, 0, 0, 0, 0)) != NPI_SUCCESS)
6733859Sml29623 goto fail;
6743859Sml29623 if ((rs = npi_ipp_read_dfifo(handle, portn, i,
675*6929Smisaki &d0, &d1, &d2, &d3, &d4)) != NPI_SUCCESS)
6763859Sml29623 goto fail;
6773859Sml29623 }
6783859Sml29623
6793859Sml29623 /* Clear PFIFO DFIFO status bits */
6803859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
6813859Sml29623 goto fail;
6823859Sml29623 if ((rs = npi_ipp_get_status(handle, portn, &istatus)) != NPI_SUCCESS)
6833859Sml29623 goto fail;
6843859Sml29623
6853859Sml29623 /* Reset IPP */
6863859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "port%d Reset IPP...", portn));
6873859Sml29623 if ((rs = npi_ipp_reset(handle, portn)) != NPI_SUCCESS)
6883859Sml29623 goto fail;
6893859Sml29623
6903859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "port%d Reset RxMAC...", portn));
6913859Sml29623 if (nxge_rx_mac_reset(nxgep) != NXGE_OK)
6923859Sml29623 goto fail;
6933859Sml29623
6943859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "port%d Initialize RxMAC...", portn));
6953859Sml29623 if ((status = nxge_rx_mac_init(nxgep)) != NXGE_OK)
6963859Sml29623 goto fail;
6973859Sml29623
6983859Sml29623 NXGE_DEBUG_MSG((nxgep, IPP_CTL, "port%d Enable RxMAC...", portn));
6993859Sml29623 if (nxge_rx_mac_enable(nxgep) != NXGE_OK)
7003859Sml29623 goto fail;
7013859Sml29623
7023859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL,
703*6929Smisaki "Recovery successful, RxPort restored"));
7043859Sml29623 NXGE_DEBUG_MSG((nxgep, RX_CTL, "==> nxge_ipp_fatal_err_recover"));
7053859Sml29623
7063859Sml29623 return (NXGE_OK);
7073859Sml29623 fail:
7083859Sml29623 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "Recovery failed"));
7093859Sml29623 return (status | rs);
7103859Sml29623 }
7113859Sml29623
7123859Sml29623 /* ARGSUSED */
7134638Syc148097 /*
7145165Syc148097 * A hardware bug may cause fake ECCUEs (ECC Uncorrectable Error).
7154638Syc148097 * This function checks if a ECCUE is real(valid) or not. It is not
7164638Syc148097 * real if rd_ptr == wr_ptr.
7174638Syc148097 * The hardware module that has the bug is used not only by the IPP
7184638Syc148097 * FIFO but also by the ZCP FIFO, therefore this function is also
7194638Syc148097 * called by nxge_zcp_handle_sys_errors for validating the ZCP FIFO
7204638Syc148097 * error.
7214638Syc148097 */
7223859Sml29623 nxge_status_t
nxge_ipp_eccue_valid_check(p_nxge_t nxgep,boolean_t * valid)7233859Sml29623 nxge_ipp_eccue_valid_check(p_nxge_t nxgep, boolean_t *valid)
7243859Sml29623 {
7253859Sml29623 npi_handle_t handle;
7263859Sml29623 npi_status_t rs = NPI_SUCCESS;
7273859Sml29623 uint8_t portn;
7283859Sml29623 uint16_t rd_ptr;
7293859Sml29623 uint16_t wr_ptr;
7303859Sml29623 uint16_t curr_rd_ptr;
7313859Sml29623 uint16_t curr_wr_ptr;
7323859Sml29623 uint32_t stall_cnt;
7333859Sml29623 uint32_t d0, d1, d2, d3, d4;
7343859Sml29623
7353859Sml29623 handle = nxgep->npi_handle;
7363859Sml29623 portn = nxgep->mac.portnum;
7373859Sml29623 *valid = B_TRUE;
7383859Sml29623
7393859Sml29623 if ((rs = npi_ipp_get_dfifo_rd_ptr(handle, portn, &rd_ptr))
740*6929Smisaki != NPI_SUCCESS)
7413859Sml29623 goto fail;
7424638Syc148097 if ((rs = npi_ipp_get_dfifo_wr_ptr(handle, portn, &wr_ptr))
743*6929Smisaki != NPI_SUCCESS)
7443859Sml29623 goto fail;
7453859Sml29623
7463859Sml29623 if (rd_ptr == wr_ptr) {
7474638Syc148097 *valid = B_FALSE; /* FIFO not stuck, so it's not a real ECCUE */
7483859Sml29623 } else {
7493859Sml29623 stall_cnt = 0;
7505060Syc148097 /*
7515060Syc148097 * Check if the two pointers are moving, the ECCUE is invali
7525060Syc148097 * if either pointer is moving, which indicates that the FIFO
7535060Syc148097 * is functional.
7545060Syc148097 */
7553859Sml29623 while (stall_cnt < 16) {
7563859Sml29623 if ((rs = npi_ipp_get_dfifo_rd_ptr(handle,
757*6929Smisaki portn, &curr_rd_ptr)) != NPI_SUCCESS)
7583859Sml29623 goto fail;
7593859Sml29623 if ((rs = npi_ipp_get_dfifo_wr_ptr(handle,
760*6929Smisaki portn, &curr_wr_ptr)) != NPI_SUCCESS)
7613859Sml29623 goto fail;
7623859Sml29623
7635060Syc148097 if (rd_ptr == curr_rd_ptr && wr_ptr == curr_wr_ptr) {
7643859Sml29623 stall_cnt++;
7655060Syc148097 } else {
7663859Sml29623 *valid = B_FALSE;
7673859Sml29623 break;
7683859Sml29623 }
7693859Sml29623 }
7703859Sml29623
7713859Sml29623 if (valid) {
7725060Syc148097 /*
7735222Syc148097 * Further check to see if the ECCUE is valid. The
7745060Syc148097 * error is real if the LSB of d4 is 1, which
7755060Syc148097 * indicates that the data that has set the ECC
7765060Syc148097 * error flag is the 16-byte internal control word.
7775060Syc148097 */
7785060Syc148097 if ((rs = npi_ipp_read_dfifo(handle, portn, rd_ptr,
7795060Syc148097 &d0, &d1, &d2, &d3, &d4)) != NPI_SUCCESS)
7803859Sml29623 goto fail;
7813859Sml29623 if ((d4 & 0x1) == 0) /* Not the 1st line */
7823859Sml29623 *valid = B_FALSE;
7833859Sml29623 }
7843859Sml29623 }
7853859Sml29623 return (NXGE_OK);
7863859Sml29623 fail:
7873859Sml29623 return (NXGE_ERROR | rs);
7883859Sml29623 }
789