# HG changeset patch # User Michael Speer # Date 1225171306 25200 # Node ID a5d463530d7fca67a27f1dd722421b86298643bc # Parent b5b6e6dd6061ef4ca9d4cbd20b1f23a7f63d6a6e 6757912 hxge needs to implement recovery for rbr empty diff -r b5b6e6dd6061 -r a5d463530d7f usr/src/uts/common/io/hxge/hpi_rxdma.c --- 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 #include #include @@ -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); } diff -r b5b6e6dd6061 -r a5d463530d7f usr/src/uts/common/io/hxge/hpi_rxdma.h --- 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); diff -r b5b6e6dd6061 -r a5d463530d7f usr/src/uts/common/io/hxge/hxge_rxdma.c --- 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;