summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>2010-08-18 15:57:57 -0600
committerSukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>2010-08-18 15:57:57 -0600
commitcddcb3dae85e03889ec217ef3da5a8898f4f66c7 (patch)
tree8a83d5bfd225c541f5ff89b46fc9b02fb83524b4
parent44bffe012cad6481c82ad67bacd6b40bd29def2b (diff)
downloadillumos-joyent-cddcb3dae85e03889ec217ef3da5a8898f4f66c7.tar.gz
6926521 Sun VTS test fails for qlge interface
6964519 qlge driver panic when the MTU is set to 9000
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c86
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c9
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c2
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h1
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h2
5 files changed, 67 insertions, 33 deletions
diff --git a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c
index 9c4e4d874c..e624ea7cf1 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge.c
@@ -58,7 +58,6 @@ static int ql_alloc_phys_rbuf(dev_info_t *, ddi_dma_handle_t *,
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 @@ ql_alloc_sbufs(qlge_t *qlge, struct rx_ring *rx_ring)
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 @@ ql_alloc_sbufs(qlge_t *qlge, struct rx_ring *rx_ring)
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 @@ ql_alloc_lbufs(qlge_t *qlge, struct rx_ring *rx_ring)
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 @@ ql_alloc_lbufs(qlge_t *qlge, struct rx_ring *rx_ring)
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 @@ ql_alloc_rx_buffers(qlge_t *qlge)
return (DDI_SUCCESS);
alloc_err:
-
+ ql_free_rx_buffers(qlge);
return (DDI_FAILURE);
}
@@ -3189,11 +3189,13 @@ ql_alloc_ioctl_dma_buf(qlge_t *qlge)
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 @@ ql_free_tx_resources(struct tx_ring *tx_ring)
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 @@ ql_alloc_tx_resources(qlge_t *qlge, struct tx_ring *tx_ring)
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 @@ ql_alloc_tx_resources(qlge_t *qlge, struct tx_ring *tx_ring)
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 @@ ql_alloc_tx_resources(qlge_t *qlge, struct tx_ring *tx_ring)
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 @@ ql_free_rx_resources(struct rx_ring *rx_ring)
}
/* 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 @@ ql_free_rx_resources(struct rx_ring *rx_ring)
}
/* 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 @@ ql_alloc_rx_resources(qlge_t *qlge, struct rx_ring *rx_ring)
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 @@ ql_alloc_mem_resources(qlge_t *qlge)
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 @@ ql_alloc_phys_rbuf(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
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 @@ ql_alloc_phys_rbuf(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
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 @@ ql_alloc_phys_rbuf(dev_info_t *dip, ddi_dma_handle_t *dma_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);
}
@@ -3834,6 +3852,7 @@ ql_alloc_phys(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
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 @@ ql_alloc_phys(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
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 @@ ql_alloc_phys(dev_info_t *dip, ddi_dma_handle_t *dma_handle,
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 @@ ql_free_resources(qlge_t *qlge)
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 @@ ql_stop_routing(qlge_t *qlge)
}
/* Initialize the frame-to-queue routing. */
-static int
+int
ql_route_initialize(qlge_t *qlge)
{
int status = 0;
diff --git a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c
index 7f3cbddec5..bbb092c70b 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_dbg.c
@@ -1478,6 +1478,7 @@ static lb_property_t loopmodes[] = {
{ 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 @@ qlge_set_loop_mode(qlge_t *qlge, uint32_t mode)
case QLGE_LOOP_NONE:
case QLGE_LOOP_INTERNAL_PARALLEL:
case QLGE_LOOP_INTERNAL_SERIAL:
+ case QLGE_LOOP_EXTERNAL_PHY:
break;
}
@@ -1512,6 +1514,13 @@ qlge_set_loop_mode(qlge_t *qlge, uint32_t mode)
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);
}
/*
diff --git a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c
index d10feb48df..a5aa6a0359 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/qlge/qlge_mpi.c
@@ -981,6 +981,8 @@ ql_set_loop_back_mode(qlge_t *qlge)
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));
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h
index a82820f9c7..414336bc0f 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge.h
@@ -876,6 +876,7 @@ extern uint8_t ql_tx_hashing(qlge_t *qlge, caddr_t bp);
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.
*/
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h
index 8d61ddcf2b..eef16fa9ec 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/qlge/qlge_open.h
@@ -31,7 +31,7 @@ extern "C" {
#endif
#ifndef VERSIONSTR
-#define VERSIONSTR "100429-v1.05"
+#define VERSIONSTR "100721-v1.07"
#endif
#ifndef QL_DEBUG