changeset 7959:a5d463530d7f onnv_102

6757912 hxge needs to implement recovery for rbr empty
author Michael Speer <Michael.Speer@Sun.COM>
date Mon, 27 Oct 2008 22:21:46 -0700
parents b5b6e6dd6061
children dab1829da853
files usr/src/uts/common/io/hxge/hpi_rxdma.c usr/src/uts/common/io/hxge/hpi_rxdma.h usr/src/uts/common/io/hxge/hxge_rxdma.c
diffstat 3 files changed, 45 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/hxge/hpi_rxdma.c	Tue Oct 28 00:00:40 2008 -0500
+++ b/usr/src/uts/common/io/hxge/hpi_rxdma.c	Mon Oct 27 22:21:46 2008 -0700
@@ -23,8 +23,6 @@
  * Use is subject to license terms.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <hpi_rxdma.h>
 #include <hxge_common.h>
 #include <hxge_impl.h>
@@ -61,6 +59,25 @@
 	return (HPI_SUCCESS);
 }
 
+hpi_status_t
+hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc)
+{
+	rdc_rx_cfg1_t	cfg;
+	uint32_t	count = RXDMA_RESET_TRY_COUNT;
+	uint32_t	delay_time = RXDMA_RESET_DELAY;
+
+	RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
+
+	while ((count--) && (cfg.bits.qst == 0)) {
+		HXGE_DELAY(delay_time);
+		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
+	}
+
+	if (cfg.bits.qst == 0)
+		return (HPI_FAILURE);
+
+	return (HPI_SUCCESS);
+}
 
 /* RX DMA functions */
 static hpi_status_t
@@ -84,29 +101,34 @@
 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
 
 		HXGE_DELAY(delay_time);
+		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
 
+		while ((count--) && (cfg.bits.qst == 1)) {
+			HXGE_DELAY(delay_time);
+			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
+		}
+		if (cfg.bits.qst == 1) {
+			cmn_err(CE_CONT, "hxge rdc(%d): not enabled\n", rdc);
+			return (HPI_FAILURE);
+		}
 		break;
+
 	case RXDMA_OP_DISABLE:
 		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
 		cfg.bits.enable = 0;
 		RXDMA_REG_WRITE64(handle, RDC_RX_CFG1, rdc, cfg.value);
 
 		HXGE_DELAY(delay_time);
-		RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
-
-		while ((count--) && (cfg.bits.qst == 0)) {
-			HXGE_DELAY(delay_time);
-			RXDMA_REG_READ64(handle, RDC_RX_CFG1, rdc, &cfg.value);
-		}
-		if (cfg.bits.qst == 0) {
+		if (hpi_rxdma_cfg_rdc_wait_for_qst(handle,
+		    rdc) != HPI_SUCCESS) {
 			HPI_ERROR_MSG((handle.function, HPI_ERR_CTL,
 			    " hpi_rxdma_cfg_rdc_ctl"
 			    " RXDMA_OP_DISABLE Failed for RDC %d \n",
 			    rdc));
 			return (error);
 		}
+		break;
 
-		break;
 	case RXDMA_OP_RESET:
 		cfg.value = 0;
 		cfg.bits.reset = 1;
@@ -124,8 +146,8 @@
 			    " Reset Failed for RDC %d \n", rdc));
 			return (error);
 		}
+		break;
 
-		break;
 	default:
 		return (HPI_RXDMA_SW_PARAM_ERROR);
 	}
--- a/usr/src/uts/common/io/hxge/hpi_rxdma.h	Tue Oct 28 00:00:40 2008 -0500
+++ b/usr/src/uts/common/io/hxge/hpi_rxdma.h	Mon Oct 27 22:21:46 2008 -0700
@@ -26,8 +26,6 @@
 #ifndef _HPI_RXDMA_H
 #define	_HPI_RXDMA_H
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -165,6 +163,7 @@
 #define	hpi_rxdma_rdc_rbr_kick(handle, rdc, num_buffers) \
 	RXDMA_REG_WRITE64(handle, RDC_RBR_KICK, rdc, num_buffers)
 
+hpi_status_t hpi_rxdma_cfg_rdc_wait_for_qst(hpi_handle_t handle, uint8_t rdc);
 hpi_status_t hpi_rxdma_cfg_rdc_ring(hpi_handle_t handle, uint8_t rdc,
     rdc_desc_cfg_t *rdc_desc_params);
 hpi_status_t hpi_rxdma_cfg_clock_div_set(hpi_handle_t handle, uint16_t count);
--- a/usr/src/uts/common/io/hxge/hxge_rxdma.c	Tue Oct 28 00:00:40 2008 -0500
+++ b/usr/src/uts/common/io/hxge/hxge_rxdma.c	Mon Oct 27 22:21:46 2008 -0700
@@ -2024,14 +2024,19 @@
 
 	if (cs.bits.rbr_empty) {
 		rdc_stats->rbr_empty++;
-		if (rdc_stats->rbr_empty == 1)
+		if (rdc_stats->rbr_empty == 1) {
 			HXGE_ERROR_MSG((hxgep, HXGE_ERR_CTL,
 			    "==> hxge_rx_err_evnts(channel %d): "
 			    "rbr empty error", channel));
+		}
+
 		/*
-		 * DMA channel is disabled due to rbr_empty bit is set
-		 * although it is not fatal. Enable the DMA channel here
-		 * to work-around the hardware bug.
+		 * Wait for channel to be quiet.
+		 */
+		(void) hpi_rxdma_cfg_rdc_wait_for_qst(handle, channel);
+
+		/*
+		 * Re-enable the DMA.
 		 */
 		(void) hpi_rxdma_cfg_rdc_enable(handle, channel);
 	}
@@ -2533,6 +2538,7 @@
 	/* Map in the receive completion ring */
 	rcrp = (p_rx_rcr_ring_t)KMEM_ZALLOC(sizeof (rx_rcr_ring_t), KM_SLEEP);
 	rcrp->rdc = dma_channel;
+	rcrp->hxgep = hxgep;
 
 	hxge_port_rcr_size = hxgep->hxge_port_rcr_size;
 	rcrp->comp_size = hxge_port_rcr_size;
@@ -2710,6 +2716,7 @@
 	    (void *) hxgep->interrupt_cookie);
 	MUTEX_INIT(&rbrp->post_lock, NULL, MUTEX_DRIVER,
 	    (void *) hxgep->interrupt_cookie);
+
 	rbrp->rdc = channel;
 	rbrp->num_blocks = num_chunks;
 	rbrp->tnblocks = nmsgs;