nxge_ipp.c revision 14ea4bb737263733ad80a36b4f73f681c30a6b45
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <nxge_impl.h>
#include <nxge_ipp.h>
#define NXGE_IPP_FIFO_SYNC_TRY_COUNT 100
{
int i;
/* Initialize ECC and parity in SRAM of DFIFO and PFIFO */
if (portn < 2)
else
} else
goto fail;
for (i = 0; i < dfifo_entries; i++) {
!= NPI_SUCCESS)
goto fail;
goto fail;
}
/* Clear PFIFO DFIFO status bits */
goto fail;
goto fail;
/*
* Soft reset to make sure we bring the FIFO pointers back to the
* original initial position.
*/
goto fail;
/* Clean up ECC counter */
goto fail;
/* Configure IPP port */
!= NPI_SUCCESS)
goto fail;
goto fail;
/* Set max packet size */
goto fail;
return (NXGE_OK);
fail:
"nxge_ipp_init: Fail to initialize IPP Port #%d\n",
portn));
return (NXGE_ERROR | rs);
}
{
(void) nxge_rx_mac_disable(nxgep);
/*
* Wait until ip read and write fifo pointers
* are equal
*/
try_count--;
}
if (try_count == 0) {
" nxge_ipp_disable: port%d failed"
" rd_fifo != wr_fifo", portn));
goto fail;
}
}
/* disable the IPP */
!= NPI_SUCCESS) {
goto fail;
}
/* IPP soft reset */
goto fail;
}
return (NXGE_OK);
fail:
"nxge_ipp_disable: Fail to disable IPP Port #%d\n",
portn));
return (NXGE_ERROR | rs);
}
{
/* disable the IPP */
!= NPI_SUCCESS) {
goto fail;
}
/*
* Wait until ip read and write fifo pointers
* are equal
*/
try_count--;
}
if (try_count == 0) {
" nxge_ipp_disable: port%d failed"
" rd_fifo != wr_fifo", portn));
goto fail;
}
}
/* IPP soft reset */
goto fail;
}
/* to reset control FIFO */
goto fail;
}
/*
* Making sure that error source is cleared if this is an
* injected error.
*/
return (NXGE_OK);
fail:
"nxge_ipp_init: Fail to Reset IPP Port #%d\n",
portn));
return (NXGE_ERROR | rs);
}
{
goto fail;
/* Set max packet size */
goto fail;
return (NXGE_OK);
fail:
"nxge_ipp_init: Fail to Enable IPP Port #%d\n",
portn));
return (NXGE_ERROR | rs);
}
{
return (NXGE_ERROR | rs);
/*
* The error is not initiated from this port, so just exit.
*/
return (NXGE_OK);
return (NXGE_ERROR | rs);
return (NXGE_ERROR | rs);
"nxge_ipp_err_evnts: fatal error: sop_miss\n"));
}
return (NXGE_ERROR | rs);
return (NXGE_ERROR | rs);
"nxge_ipp_err_evnts: fatal error: eop_miss\n"));
}
!= NXGE_OK)
return (status);
if (ue_ecc_valid) {
return (NXGE_ERROR | rs);
"nxge_ipp_err_evnts: fatal error: dfifo_ue\n"));
}
}
statsp->pfifo_perr++;
"nxge_ipp_err_evnts: fatal error: pre_pifo_perr\n"));
}
statsp->pfifo_over++;
"nxge_ipp_err_evnts: fatal error: pfifo_over\n"));
}
"nxge_ipp_err_evnts: fatal error: pfifo_und\n"));
}
if (statsp->bad_cs_cnt <
"nxge_ipp_err_evnts: bad_cs_max\n"));
}
if (statsp->pkt_dis_cnt <
"nxge_ipp_err_evnts: pkt_dis_max\n"));
}
/*
* Making sure that error source is cleared if this is an
* injected error.
*/
if (rxport_fatal) {
" nxge_ipp_handle_sys_errors:"
" fatal Error on Port #%d\n",
portn));
}
}
return (status);
}
void
{
switch (err_id) {
break;
break;
if (err_id == NXGE_FM_EREPORT_IPP_EOP_MISS)
else if (err_id == NXGE_FM_EREPORT_IPP_SOP_MISS)
else if (err_id == NXGE_FM_EREPORT_IPP_DFIFO_UE)
else if (err_id == NXGE_FM_EREPORT_IPP_DFIFO_CE)
else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_PERR)
else if (err_id == NXGE_FM_EREPORT_IPP_ECC_ERR_MAX)
else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_OVER)
else if (err_id == NXGE_FM_EREPORT_IPP_PFIFO_UND)
else if (err_id == NXGE_FM_EREPORT_IPP_BAD_CS_MX)
else if (err_id == NXGE_FM_EREPORT_IPP_PKT_DIS_MX)
break;
}
}
{
int i;
"Recovering from RxPort error..."));
/*
* Making sure that error source is cleared if this is an
* injected error.
*/
/* Disable RxMAC */
goto fail;
/* When recovering from IPP, RxDMA channel resets are not necessary */
/* Reset ZCP CFIFO */
goto fail;
/*
* Wait until ip read and write fifo pointers
* are equal
*/
try_count = 512;
try_count--;
}
if (try_count == 0) {
" nxge_ipp_reset: port%d IPP stalled..."
" rd_fifo_ptr = 0x%x wr_fifo_ptr = 0x%x",
/*
* This means the fatal error occurred on the first line
* of the fifo. In this case, just reset the IPP without
* draining the PFIFO.
*/
}
if (portn < 2)
else
} else
goto fail;
/* Clean up DFIFO SRAM entries */
for (i = 0; i < dfifo_entries; i++) {
!= NPI_SUCCESS)
goto fail;
goto fail;
}
/* Clear PFIFO DFIFO status bits */
goto fail;
goto fail;
/* Reset IPP */
goto fail;
goto fail;
goto fail;
goto fail;
"Recovery Sucessful, RxPort Restored"));
return (NXGE_OK);
fail:
}
{
!= NPI_SUCCESS)
goto fail;
!= NPI_SUCCESS)
goto fail;
"nxge_ipp_eccue_valid_check: rd_ptr = %d wr_ptr = %d\n",
} else {
stall_cnt = 0;
while (stall_cnt < 16) {
&curr_rd_ptr))
!= NPI_SUCCESS)
goto fail;
&curr_wr_ptr))
!= NPI_SUCCESS)
goto fail;
stall_cnt++;
else {
break;
}
}
if (valid) { /* futher check to see if ECC UE is valid */
goto fail;
}
}
return (NXGE_OK);
fail:
return (NXGE_ERROR | rs);
}