changeset 13179:7f829eb09eb7

6926521 Sun VTS test fails for qlge interface 6964519 qlge driver panic when the MTU is set to 9000
author Sukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>
date Wed, 18 Aug 2010 15:57:57 -0600
parents 5f70b43d6386
children b23a4dab3d50
files usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h
diffstat 5 files changed, 67 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c	Wed Aug 18 13:59:31 2010 -0600
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c	Wed Aug 18 15:57:57 2010 -0600
@@ -58,7 +58,6 @@
     size_t, size_t, caddr_t *, ddi_dma_cookie_t *);
 static void ql_free_phys(ddi_dma_handle_t *, ddi_acc_handle_t *);
 static int ql_set_routing_reg(qlge_t *, uint32_t, uint32_t, int);
-static int ql_route_initialize(qlge_t *);
 static int ql_attach(dev_info_t *, ddi_attach_cmd_t);
 static int ql_detach(dev_info_t *, ddi_detach_cmd_t);
 static int ql_bringdown_adapter(qlge_t *);
@@ -1446,13 +1445,18 @@
 	int i;
 	ddi_dma_cookie_t dma_cookie;
 
+	rx_ring->sbq_use_head = 0;
+	rx_ring->sbq_use_tail = 0;
+	rx_ring->sbuf_in_use_count = 0;
+	rx_ring->sbq_free_head = 0;
+	rx_ring->sbq_free_tail = 0;
+	rx_ring->sbuf_free_count = 0;
 	rx_ring->sbuf_free = kmem_zalloc(rx_ring->sbq_len *
 	    sizeof (struct bq_desc *), KM_NOSLEEP);
 	if (rx_ring->sbuf_free == NULL) {
 		cmn_err(CE_WARN,
 		    "!%s: sbuf_free_list alloc: failed",
 		    __func__);
-		rx_ring->sbuf_free_count = 0;
 		goto alloc_sbuf_err;
 	}
 
@@ -1462,13 +1466,9 @@
 		cmn_err(CE_WARN,
 		    "!%s: sbuf_inuse_list alloc: failed",
 		    __func__);
-		rx_ring->sbuf_in_use_count = 0;
 		goto alloc_sbuf_err;
 	}
-	rx_ring->sbq_use_head = 0;
-	rx_ring->sbq_use_tail = 0;
-	rx_ring->sbq_free_head = 0;
-	rx_ring->sbq_free_tail = 0;
+
 	sbq_desc = &rx_ring->sbq_desc[0];
 
 	for (i = 0; i < rx_ring->sbq_len; i++, sbq_desc++) {
@@ -1591,13 +1591,18 @@
 	int i;
 	uint32_t lbq_buf_size;
 
+	rx_ring->lbq_use_head = 0;
+	rx_ring->lbq_use_tail = 0;
+	rx_ring->lbuf_in_use_count = 0;
+	rx_ring->lbq_free_head = 0;
+	rx_ring->lbq_free_tail = 0;
+	rx_ring->lbuf_free_count = 0;
 	rx_ring->lbuf_free = kmem_zalloc(rx_ring->lbq_len *
 	    sizeof (struct bq_desc *), KM_NOSLEEP);
 	if (rx_ring->lbuf_free == NULL) {
 		cmn_err(CE_WARN,
 		    "!%s: lbuf_free_list alloc: failed",
 		    __func__);
-		rx_ring->lbuf_free_count = 0;
 		goto alloc_lbuf_err;
 	}
 
@@ -1608,13 +1613,8 @@
 		cmn_err(CE_WARN,
 		    "!%s: lbuf_inuse_list alloc: failed",
 		    __func__);
-		rx_ring->lbuf_in_use_count = 0;
 		goto alloc_lbuf_err;
 	}
-	rx_ring->lbq_use_head = 0;
-	rx_ring->lbq_use_tail = 0;
-	rx_ring->lbq_free_head = 0;
-	rx_ring->lbq_free_tail = 0;
 
 	lbq_buf_size = (qlge->mtu == ETHERMTU) ?
 	    LRG_BUF_NORMAL_SIZE : LRG_BUF_JUMBO_SIZE;
@@ -1710,7 +1710,7 @@
 	return (DDI_SUCCESS);
 
 alloc_err:
-
+	ql_free_rx_buffers(qlge);
 	return (DDI_FAILURE);
 }
 
@@ -3189,11 +3189,13 @@
 static void
 ql_free_phys(ddi_dma_handle_t *dma_handle, ddi_acc_handle_t *acc_handle)
 {
-	if (dma_handle != NULL) {
+	if (*dma_handle != NULL) {
 		(void) ddi_dma_unbind_handle(*dma_handle);
-		if (acc_handle != NULL)
+		if (*acc_handle != NULL)
 			ddi_dma_mem_free(acc_handle);
 		ddi_dma_free_handle(dma_handle);
+		*acc_handle = NULL;
+		*dma_handle = NULL;
 	}
 }
 
@@ -3319,9 +3321,11 @@
 	struct tx_ring_desc *tx_ring_desc;
 	int i, j;
 
-	ql_free_phys(&tx_ring->wq_dma.dma_handle, &tx_ring->wq_dma.acc_handle);
-	bzero(&tx_ring->wq_dma, sizeof (tx_ring->wq_dma));
-
+	if (tx_ring->wq_dma.dma_handle != NULL) {
+		ql_free_phys(&tx_ring->wq_dma.dma_handle,
+		    &tx_ring->wq_dma.acc_handle);
+		bzero(&tx_ring->wq_dma, sizeof (tx_ring->wq_dma));
+	}
 	if (tx_ring->wq_desc != NULL) {
 		tx_ring_desc = tx_ring->wq_desc;
 		for (i = 0; i < tx_ring->wq_len; i++, tx_ring_desc++) {
@@ -3417,7 +3421,7 @@
 				cmn_err(CE_WARN, "%s(%d): reqQ tx buf &"
 				    "oal alloc failed.",
 				    __func__, qlge->instance);
-				return (DDI_FAILURE);
+				goto err;
 			}
 
 			tx_ring_desc->oal = tx_ring_desc->oal_dma.vaddr;
@@ -3436,10 +3440,14 @@
 				    DDI_DMA_DONTWAIT,
 				    0, &tx_ring_desc->tx_dma_handle[j])
 				    != DDI_SUCCESS) {
+					tx_ring_desc->tx_dma_handle[j] = NULL;
 					cmn_err(CE_WARN,
 					    "!%s: ddi_dma_alloc_handle: "
 					    "tx_dma_handle "
 					    "alloc failed", __func__);
+					ql_free_phys(
+					    &tx_ring_desc->oal_dma.dma_handle,
+					    &tx_ring_desc->oal_dma.acc_handle);
 					goto err;
 				}
 			}
@@ -3457,7 +3465,7 @@
 		bzero(&tx_ring->wqicb_dma, sizeof (tx_ring->wqicb_dma));
 		cmn_err(CE_WARN, "%s(%d): wqicb allocation failed.",
 		    __func__, qlge->instance);
-		return (DDI_FAILURE);
+		goto err;
 	}
 	tx_ring->wqicb_dma.dma_addr = dma_cookie.dmac_laddress;
 
@@ -3482,9 +3490,11 @@
 	}
 
 	/* Free the small buffer queue control blocks. */
-	kmem_free(rx_ring->sbq_desc, rx_ring->sbq_len *
-	    sizeof (struct bq_desc));
-	rx_ring->sbq_desc = NULL;
+	if (rx_ring->sbq_desc != NULL) {
+		kmem_free(rx_ring->sbq_desc, rx_ring->sbq_len *
+		    sizeof (struct bq_desc));
+		rx_ring->sbq_desc = NULL;
+	}
 
 	/* Free the large buffer queue. */
 	if (rx_ring->lbq_dma.dma_handle) {
@@ -3494,9 +3504,11 @@
 	}
 
 	/* Free the large buffer queue control blocks. */
-	kmem_free(rx_ring->lbq_desc, rx_ring->lbq_len *
-	    sizeof (struct bq_desc));
-	rx_ring->lbq_desc = NULL;
+	if (rx_ring->lbq_desc != NULL) {
+		kmem_free(rx_ring->lbq_desc, rx_ring->lbq_len *
+		    sizeof (struct bq_desc));
+		rx_ring->lbq_desc = NULL;
+	}
 
 	/* Free cqicb struct */
 	if (rx_ring->cqicb_dma.dma_handle) {
@@ -3616,7 +3628,7 @@
 		bzero(&rx_ring->cqicb_dma, sizeof (rx_ring->cqicb_dma));
 		cmn_err(CE_WARN, "%s(%d): cqicb allocation failed.",
 		    __func__, qlge->instance);
-		return (DDI_FAILURE);
+		goto err_mem;
 	}
 	rx_ring->cqicb_dma.dma_addr = dma_cookie.dmac_laddress;
 
@@ -3709,13 +3721,14 @@
 		bzero(&qlge->ricb_dma, sizeof (qlge->ricb_dma));
 		cmn_err(CE_WARN, "%s(%d): ricb allocation failed.",
 		    __func__, qlge->instance);
-		return (DDI_FAILURE);
+		goto err_mem;
 	}
 	qlge->ricb_dma.dma_addr = dma_cookie.dmac_laddress;
 
 	return (DDI_SUCCESS);
 
 err_mem:
+	ql_free_mem_resources(qlge);
 	return (DDI_FAILURE);
 }
 
@@ -3758,6 +3771,7 @@
 	    dma_handle) != DDI_SUCCESS) {
 		cmn_err(CE_WARN, QL_BANG "%s:  ddi_dma_alloc_handle FAILED",
 		    __func__);
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 	/*
@@ -3769,6 +3783,8 @@
 	    NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) {
 		cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed");
 		ddi_dma_free_handle(dma_handle);
+		*acc_handle = NULL;
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 
@@ -3780,6 +3796,8 @@
 		ddi_dma_free_handle(dma_handle);
 		cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED",
 		    __func__);
+		*acc_handle = NULL;
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 
@@ -3834,6 +3852,7 @@
 	    dma_handle) != DDI_SUCCESS) {
 		cmn_err(CE_WARN, QL_BANG "%s:  ddi_dma_alloc_handle FAILED",
 		    __func__);
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 	/*
@@ -3845,6 +3864,8 @@
 	    NULL, vaddr, &rlen, acc_handle) != DDI_SUCCESS) {
 		cmn_err(CE_WARN, "alloc_phys: DMA Memory alloc Failed");
 		ddi_dma_free_handle(dma_handle);
+		*acc_handle = NULL;
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 
@@ -3852,10 +3873,11 @@
 	    dma_flags, DDI_DMA_DONTWAIT, NULL,
 	    dma_cookie, &cnt) != DDI_DMA_MAPPED) {
 		ddi_dma_mem_free(acc_handle);
-
 		ddi_dma_free_handle(dma_handle);
 		cmn_err(CE_WARN, "%s ddi_dma_addr_bind_handle FAILED",
 		    __func__);
+		*acc_handle = NULL;
+		*dma_handle = NULL;
 		return (QL_ERROR);
 	}
 
@@ -4462,7 +4484,7 @@
 		qlge->sequence &= ~INIT_PCI_CONFIG_SETUP;
 	}
 
-	if (qlge->sequence & INIT_ADD_INTERRUPT) {
+	if (qlge->sequence & INIT_INTR_ALLOC) {
 		ql_free_irq_vectors(qlge);
 		qlge->sequence &= ~INIT_ADD_INTERRUPT;
 	}
@@ -6862,7 +6884,7 @@
 }
 
 /* Initialize the frame-to-queue routing. */
-static int
+int
 ql_route_initialize(qlge_t *qlge)
 {
 	int status = 0;
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c	Wed Aug 18 13:59:31 2010 -0600
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c	Wed Aug 18 15:57:57 2010 -0600
@@ -1478,6 +1478,7 @@
 	{ normal,	"normal",	QLGE_LOOP_NONE			},
 	{ internal,	"parallel",	QLGE_LOOP_INTERNAL_PARALLEL	},
 	{ internal,	"serial",	QLGE_LOOP_INTERNAL_SERIAL	},
+	{ external,	"phy",		QLGE_LOOP_EXTERNAL_PHY		}
 };
 
 /*
@@ -1502,6 +1503,7 @@
 	case QLGE_LOOP_NONE:
 	case QLGE_LOOP_INTERNAL_PARALLEL:
 	case QLGE_LOOP_INTERNAL_SERIAL:
+	case QLGE_LOOP_EXTERNAL_PHY:
 		break;
 	}
 
@@ -1512,6 +1514,13 @@
 	mutex_enter(&qlge->mbx_mutex);
 	(void) ql_set_loop_back_mode(qlge);
 	mutex_exit(&qlge->mbx_mutex);
+	/* if loopback mode test is done */
+	if (mode == QLGE_LOOP_NONE) {
+		mutex_enter(&qlge->hw_mutex);
+		(void) ql_route_initialize(qlge);
+		mutex_exit(&qlge->hw_mutex);
+	}
+
 	return (IOC_REPLY);
 }
 /*
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c	Wed Aug 18 13:59:31 2010 -0600
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c	Wed Aug 18 15:57:57 2010 -0600
@@ -981,6 +981,8 @@
 		qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_PARALLEL;
 	else if (qlge->loop_back_mode == QLGE_LOOP_INTERNAL_SERIAL)
 		qlge->port_cfg_info.link_cfg |= LOOP_INTERNAL_SERIAL;
+	else if (qlge->loop_back_mode == QLGE_LOOP_EXTERNAL_PHY)
+		qlge->port_cfg_info.link_cfg |= LOOP_EXTERNAL_PHY;
 
 	return (ql_set_mpi_port_config(qlge, qlge->port_cfg_info));
 
--- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h	Wed Aug 18 13:59:31 2010 -0600
+++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h	Wed Aug 18 15:57:57 2010 -0600
@@ -876,6 +876,7 @@
 extern void ql_atomic_set_32(volatile uint32_t *target, uint32_t newval);
 extern uint32_t ql_atomic_read_32(volatile uint32_t *target);
 extern void ql_restart_timer(qlge_t *qlge);
+extern int ql_route_initialize(qlge_t *);
 /*
  * Global Function Prototypes in qlge_flash.c source file.
  */
--- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h	Wed Aug 18 13:59:31 2010 -0600
+++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h	Wed Aug 18 15:57:57 2010 -0600
@@ -31,7 +31,7 @@
 #endif
 
 #ifndef VERSIONSTR
-#define	VERSIONSTR	"100429-v1.05"
+#define	VERSIONSTR	"100721-v1.07"
 #endif
 
 #ifndef	QL_DEBUG