summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorSukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>2009-12-23 12:12:50 -0800
committerSukumar Swaminathan <Sukumar.Swaminathan@Sun.COM>2009-12-23 12:12:50 -0800
commitb3660a963b4e1d5319365d4d7c34beb66fb5abc7 (patch)
tree5db85949647f6909b745c70b079b95460c581819 /usr/src
parentb885580b43755ee4ea1e280b85428893d2ba9291 (diff)
downloadillumos-joyent-b3660a963b4e1d5319365d4d7c34beb66fb5abc7.tar.gz
6911213 emlxs 2.50 driver queue list corruption for FCoE adapters
6902275 emlxs drivers sets DDI_FM_DMACHK_CAPABLE without correctly handling dma errors
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c101
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_diag.c20
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c39
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dump.c11
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c12
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c67
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_mbox.c20
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c55
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c661
-rw-r--r--usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c132
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfc.h1
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h2
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h14
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h12
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_os.h16
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_queue.h10
-rw-r--r--usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h4
17 files changed, 844 insertions, 333 deletions
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c
index 7d4afbfb34..82ff99ffb9 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dfc.c
@@ -166,6 +166,8 @@ static int emlxs_dfc_set_be_dcbx(emlxs_hba_t *hba, dfc_t *dfc,
int32_t mode);
static int emlxs_dfc_get_be_dcbx(emlxs_hba_t *hba, dfc_t *dfc,
int32_t mode);
+static int emlxs_dfc_get_qos(emlxs_hba_t *hba, dfc_t *dfc,
+ int32_t mode);
uint32_t emlxs_loopback_tmo = 60;
@@ -223,6 +225,7 @@ emlxs_table_t emlxs_dfc_table[] = {
{EMLXS_RD_BE_FCF, "RD_BE_FCF"},
{EMLXS_SET_BE_DCBX, "SET_BE_DCBX"},
{EMLXS_GET_BE_DCBX, "GET_BE_DCBX"},
+ {EMLXS_GET_QOS, "GET_QOS"},
}; /* emlxs_dfc_table */
@@ -784,6 +787,10 @@ emlxs_dfc_manage(emlxs_hba_t *hba, void *arg, int32_t mode)
rval = emlxs_dfc_get_be_dcbx(hba, dfc, mode);
break;
+ case EMLXS_GET_QOS:
+ rval = emlxs_dfc_get_qos(hba, dfc, mode);
+ break;
+
default:
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_detail_msg,
"Unknown command received. (0x%x)", dfc->cmd);
@@ -3033,52 +3040,27 @@ emlxs_dfc_npiv_test(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
els->elsCode = 0x04; /* FLOGI - This will be changed automatically */
/* by the drive (See emlxs_send_els()) */
- els->un.logi.cmn.fcphHigh = 0x09;
- els->un.logi.cmn.fcphLow = 0x08;
- els->un.logi.cmn.bbCreditMsb = 0xff;
- els->un.logi.cmn.bbCreditlsb = 0xff;
- els->un.logi.cmn.reqMultipleNPort = 1;
- els->un.logi.cmn.bbRcvSizeMsb = 0x08;
- els->un.logi.cmn.bbRcvSizeLsb = 0x00;
- els->un.logi.cmn.w2.nPort.totalConcurrSeq = 0xff;
- els->un.logi.cmn.w2.nPort.roByCategoryMsb = 0xff;
- els->un.logi.cmn.w2.nPort.roByCategoryLsb = 0xff;
- els->un.logi.cmn.e_d_tov = 0x7d0;
+ /* Copy latest service parameters to payload */
+ bcopy((void *)&port->sparam,
+ (void *)&els->un.logi, sizeof (SERV_PARM));
bcopy((caddr_t)&hba->wwnn, (caddr_t)wwn, 8);
wwn[0] = 0x28;
wwn[1] = hba->vpi_max;
bcopy((caddr_t)wwn, (caddr_t)&els->un.logi.nodeName, 8);
+ bcopy((caddr_t)wwn, (caddr_t)&vport->wwnn, 8);
bcopy((caddr_t)&hba->wwpn, (caddr_t)wwn, 8);
wwn[0] = 0x20;
wwn[1] = hba->vpi_max;
bcopy((caddr_t)wwn, (caddr_t)&els->un.logi.portName, 8);
-
- els->un.logi.cls1.openSeqPerXchgMsb = 0x00;
- els->un.logi.cls1.openSeqPerXchgLsb = 0x01;
-
- els->un.logi.cls2.classValid = 1;
- els->un.logi.cls2.rcvDataSizeMsb = 0x08;
- els->un.logi.cls2.rcvDataSizeLsb = 0x00;
- els->un.logi.cls2.concurrentSeqMsb = 0x00;
- els->un.logi.cls2.concurrentSeqLsb = 0xff;
- els->un.logi.cls2.EeCreditSeqMsb = 0x00;
- els->un.logi.cls2.EeCreditSeqLsb = 0x0c;
- els->un.logi.cls2.openSeqPerXchgMsb = 0x00;
- els->un.logi.cls2.openSeqPerXchgLsb = 0x01;
-
- els->un.logi.cls3.classValid = 1;
- els->un.logi.cls3.rcvDataSizeMsb = 0x08;
- els->un.logi.cls3.rcvDataSizeLsb = 0x00;
- els->un.logi.cls3.concurrentSeqMsb = 0x00;
- els->un.logi.cls3.concurrentSeqLsb = 0xff;
- els->un.logi.cls3.openSeqPerXchgMsb = 0x00;
- els->un.logi.cls3.openSeqPerXchgLsb = 0x01;
+ bcopy((caddr_t)wwn, (caddr_t)&vport->wwpn, 8);
bcopy((void *)&els->un.logi, (void *)&vport->sparam,
sizeof (SERV_PARM));
+
+
/* Make this a polled IO */
pkt->pkt_tran_flags &= ~FC_TRAN_INTR;
pkt->pkt_tran_flags |= FC_TRAN_NO_INTR;
@@ -4650,10 +4632,34 @@ done:
/* Free allocated mbuf memory */
if (rx_mp) {
+#ifdef FMA_SUPPORT
+ if (!rval) {
+ if (emlxs_fm_check_dma_handle(hba, rx_mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_dfc_send_mbox: hdl=%p",
+ rx_mp->dma_handle);
+ rval = DFC_IO_ERROR;
+ }
+ }
+#endif /* FMA_SUPPORT */
(void) emlxs_mem_buf_free(hba, rx_mp);
}
if (tx_mp) {
+#ifdef FMA_SUPPORT
+ if (!rval) {
+ if (emlxs_fm_check_dma_handle(hba, tx_mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_dfc_send_mbox: hdl=%p",
+ tx_mp->dma_handle);
+ rval = DFC_IO_ERROR;
+ }
+ }
+#endif /* FMA_SUPPORT */
(void) emlxs_mem_buf_free(hba, tx_mp);
}
@@ -10490,7 +10496,7 @@ emlxs_dfc_send_mbox4(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
"%s: ddi_copyout failed. cmd=%x",
emlxs_dfc_xlate(dfc->cmd), mb4->mbxCommand);
- rval = DFC_COPYIN_ERROR;
+ rval = DFC_COPYOUT_ERROR;
goto done;
}
}
@@ -10700,3 +10706,32 @@ done:
return (rval);
}
+
+
+static int
+emlxs_dfc_get_qos(emlxs_hba_t *hba, dfc_t *dfc, int32_t mode)
+{
+ emlxs_port_t *port = &PPORT;
+ uint32_t rval = 0;
+
+ if (! (hba->model_info.flags & EMLXS_FCOE_SUPPORTED)) {
+ EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
+ "%s: FCoE not supported.", emlxs_dfc_xlate(dfc->cmd));
+
+ return (DFC_FCOE_NOTSUPPORTED);
+ }
+
+ if (dfc->buf1_size) {
+ if (ddi_copyout((void *)&hba->qos_linkspeed, (void *)dfc->buf1,
+ dfc->buf1_size, mode) != 0) {
+ EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_dfc_error_msg,
+ "%s: ddi_copyout failed.",
+ emlxs_dfc_xlate(dfc->cmd));
+
+ rval = DFC_COPYOUT_ERROR;
+ return (rval);
+ }
+ }
+
+ return (rval);
+}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_diag.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_diag.c
index 470e596e99..eaef06e270 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_diag.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_diag.c
@@ -397,9 +397,29 @@ emlxs_diag_biu_run(emlxs_hba_t *hba, uint32_t pattern)
done:
if (mp) {
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_diag_biu_run: hdl=%p",
+ mp->dma_handle);
+ rval = EMLXS_TEST_FAILED;
+ }
+#endif /* FMA_SUPPORT */
(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp);
}
if (mp1) {
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, mp1->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_diag_biu_run: hdl=%p",
+ mp1->dma_handle);
+ rval = EMLXS_TEST_FAILED;
+ }
+#endif /* FMA_SUPPORT */
(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1);
}
if (mbq) {
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c
index 131b9247f1..c514029031 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_download.c
@@ -2794,6 +2794,19 @@ done:
kmem_free(mbox, sizeof (MAILBOXQ));
}
+#ifdef FMA_SUPPORT
+ if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_read_wakeup_parms: hdl=%p",
+ hba->sli.sli4.dump_region.dma_handle);
+ rval = 1;
+ }
+ }
+#endif /* FMA_SUPPORT */
+
return (rval);
} /* emlxs_read_wakeup_parms() */
@@ -2889,6 +2902,19 @@ done:
kmem_free(mbox, sizeof (MAILBOXQ));
}
+#ifdef FMA_SUPPORT
+ if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_read_load_list: hdl=%p",
+ hba->sli.sli4.dump_region.dma_handle);
+ return (1);
+ }
+ }
+#endif /* FMA_SUPPORT */
+
return (0);
} /* emlxs_read_load_list() */
@@ -4408,6 +4434,19 @@ Exit_Function:
kmem_free(mbox, sizeof (MAILBOXQ));
}
+#ifdef FMA_SUPPORT
+ if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.dump_region.dma_handle) != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_get_max_sram: hdl=%p",
+ hba->sli.sli4.dump_region.dma_handle);
+ rval = 1;
+ }
+ }
+#endif /* FMA_SUPPORT */
+
return (rval);
} /* emlxs_get_max_sram() */
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dump.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dump.c
index 68cbccb1fe..63a4e97e1c 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dump.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_dump.c
@@ -3777,6 +3777,17 @@ emlxs_dump_saturn_log(
SID_NON_VOLATILE_LOG, LEGEND_NON_VOLATILE_LOG, LEGEND_NULL,
fSwap);
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_dump_saturn_log: hdl=%p",
+ mp->dma_handle);
+ status = 1;
+ }
+#endif /* FMA_SUPPORT */
+
(void) emlxs_mem_buf_free(hba, mp);
kmem_free(mbq, sizeof (MAILBOXQ));
return (status);
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c
index b2fb0586f0..6dca92af23 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fcp.c
@@ -158,9 +158,21 @@ emlxs_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
#if (EMLXS_MODREVX == EMLXS_MODREV2X)
emlxs_unswap_pkt(sbp);
#endif /* EMLXS_MODREV2X */
+
+#ifdef FMA_SUPPORT
+ emlxs_check_dma(hba, sbp);
+#endif /* FMA_SUPPORT */
+
cp->ulpCmplCmd++;
(*pkt->pkt_comp) (pkt);
+#ifdef FMA_SUPPORT
+ if (hba->flag & FC_DMA_CHECK_ERROR) {
+ emlxs_thread_spawn(hba, emlxs_restart_thread,
+ NULL, NULL);
+ }
+#endif /* FMA_SUPPORT */
+
return;
}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c
index 7aa0cf2899..dd04d0b08a 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_fct.c
@@ -83,7 +83,8 @@ static stmf_data_buf_t *emlxs_fct_dbuf_alloc(fct_local_port_t *fct_port,
uint32_t size, uint32_t *pminsize, uint32_t flags);
static void emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf);
-static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
+static int emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf,
+ uint_t sync_type);
static emlxs_buf_t *emlxs_fct_pkt_init(emlxs_port_t *port,
fct_cmd_t *fct_cmd, fc_packet_t *pkt);
@@ -96,7 +97,6 @@ static uint32_t emlxs_fct_pkt_abort_txq(emlxs_port_t *port,
emlxs_buf_t *cmd_sbp);
static fct_status_t emlxs_fct_send_qfull_reply(emlxs_port_t *port,
emlxs_node_t *ndlp, uint16_t xid, uint32_t class, emlxs_fcp_cmd_t *fcp_cmd);
-static void emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type);
#ifdef FCT_IO_TRACE
uint8_t *emlxs_iotrace = 0; /* global for mdb */
@@ -2535,7 +2535,7 @@ emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf,
int channel;
int channelno;
- fct_status_t rval;
+ fct_status_t rval = 0;
rval = emlxs_fct_cmd_accept(port, fct_cmd, EMLXS_FCT_SEND_FCP_DATA);
if (rval) {
@@ -2588,7 +2588,12 @@ emlxs_fct_send_fcp_data(fct_cmd_t *fct_cmd, stmf_data_buf_t *dbuf,
}
if (dbuf->db_flags & DB_DIRECTION_TO_RPORT) {
- emlxs_fct_dbuf_dma_sync(dbuf, DDI_DMA_SYNC_FORDEV);
+ if (emlxs_fct_dbuf_dma_sync(hba, dbuf, DDI_DMA_SYNC_FORDEV)) {
+ emlxs_fct_cmd_post(port, fct_cmd, EMLXS_FCT_CMD_POSTED);
+ /* mutex_exit(&cmd_sbp->fct_mtx); */
+
+ return (FCT_BUSY);
+ }
}
cmd_sbp->fct_flags |= EMLXS_FCT_IO_INP;
@@ -2902,6 +2907,7 @@ emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
fct_cmd->cmd_comp_status = FCT_SUCCESS;
if (status) {
+emlxs_dma_error:
/*
* The error indicates this IO should be terminated
* immediately.
@@ -2935,8 +2941,10 @@ emlxs_fct_handle_fcp_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
case CMD_FCP_TRECEIVE64_CX:
if (dbuf->db_flags & DB_DIRECTION_FROM_RPORT) {
- emlxs_fct_dbuf_dma_sync(dbuf,
- DDI_DMA_SYNC_FORCPU);
+ if (emlxs_fct_dbuf_dma_sync(hba, dbuf,
+ DDI_DMA_SYNC_FORCPU)) {
+ goto emlxs_dma_error;
+ }
}
if ((cmd_sbp->fct_flags & EMLXS_FCT_SEND_STATUS) &&
@@ -3818,6 +3826,20 @@ emlxs_fct_pkt_comp(fc_packet_t *pkt)
fct_cmd, fct_cmd->cmd_comp_status);
#endif /* FCT_API_TRACE */
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_fct_pkt_comp: hdl=%p",
+ pkt->pkt_resp_dma);
+ MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE,
+ FCT_IOF_FCA_DONE);
+
+ break;
+ }
+#endif /* FMA_SUPPORT */
+
MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
FCT_IOF_FCA_DONE);
@@ -3848,6 +3870,19 @@ emlxs_fct_pkt_comp(fc_packet_t *pkt)
fct_cmd, fct_cmd->cmd_comp_status);
#endif /* FCT_API_TRACE */
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_fct_pkt_comp: hdl=%p",
+ pkt->pkt_resp_dma);
+ MODSYM(fct_send_cmd_done) (fct_cmd, FCT_FAILURE,
+ FCT_IOF_FCA_DONE);
+
+ break;
+ }
+#endif /* FMA_SUPPORT */
MODSYM(fct_send_cmd_done) (fct_cmd, FCT_SUCCESS,
FCT_IOF_FCA_DONE);
@@ -4988,17 +5023,33 @@ emlxs_fct_dbuf_free(fct_dbuf_store_t *fds, stmf_data_buf_t *dbuf)
} /* emlxs_fct_dbuf_free() */
-static void
-emlxs_fct_dbuf_dma_sync(stmf_data_buf_t *dbuf, uint_t sync_type)
+static int
+emlxs_fct_dbuf_dma_sync(emlxs_hba_t *hba, stmf_data_buf_t *dbuf,
+ uint_t sync_type)
{
emlxs_fct_dmem_bctl_t *bctl =
(emlxs_fct_dmem_bctl_t *)dbuf->db_port_private;
emlxs_fct_dmem_bucket_t *p = bctl->bctl_bucket;
+ emlxs_port_t *port = &PPORT;
+ int retval = 0;
(void) ddi_dma_sync(p->dmem_dma_handle,
(unsigned long)(bctl->bctl_dev_addr - p->dmem_dev_addr),
dbuf->db_data_size, sync_type);
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, p->dmem_dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_fct_dbuf_dma_sync: hdl=%p",
+ p->dmem_dma_handle);
+ retval = 1;
+ }
+#endif /* FMA_SUPPORT */
+
+ return (retval);
+
} /* emlxs_fct_dbuf_dma_sync() */
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_mbox.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_mbox.c
index 822f379ddb..204515c70a 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_mbox.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_mbox.c
@@ -487,6 +487,9 @@ emlxs_mbext_add_fcf_table(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t index)
FCF_RECORD_t *fcfrec;
MATCHMAP *mp;
mbox_req_hdr_t *hdr_req;
+ uint16_t i;
+ uint8_t bitmap[512];
+
bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
@@ -540,13 +543,14 @@ emlxs_mbext_add_fcf_table(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t index)
#endif
if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) {
- uint16_t i;
- uint8_t bitmap[512];
-
bzero((void *) bitmap, 512);
i = hba->sli.sli4.cfgFCOE.VLanId;
bitmap[i / 8] = (1 << (i % 8));
BE_SWAP32_BCOPY(bitmap, fcfrec->vlan_bitmap, 512);
+ } else {
+ bzero((void *) bitmap, 512);
+ bitmap[0] = 1; /* represents bit 0 */
+ BE_SWAP32_BCOPY(bitmap, fcfrec->vlan_bitmap, 512);
}
fcfrec->fcf_valid = 1;
@@ -3562,6 +3566,7 @@ emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp)
emlxs_hba_t *hba = HBA;
MAILBOXQ *mbq;
MAILBOX *mb;
+ uint32_t *pn;
int rval;
if (!(hba->flag & FC_NPIV_ENABLED)) {
@@ -3600,6 +3605,12 @@ emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp)
bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
mbq->nonembed = NULL;
mb->un.varRegVpi.vfi = port->VFIp->VFI;
+
+ pn = (uint32_t *)&port->wwpn;
+ mb->un.varRegVpi.portname[0] = BE_SWAP32(*pn);
+ pn++;
+ mb->un.varRegVpi.portname[1] = BE_SWAP32(*pn);
+
mbq->mbox_cmpl = emlxs_cmpl_reg_vpi;
} else {
bzero((void *)mb, MAILBOX_CMD_BSIZE);
@@ -3858,9 +3869,6 @@ emlxs_mb_get(emlxs_hba_t *hba)
void
emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
{
-#ifdef FMA_SUPPORT
- emlxs_port_t *port = &PPORT;
-#endif /* FMA_SUPPORT */
MATCHMAP *mp;
HBASTATS.MboxIssued++;
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c
index ade7643d18..7b672d6bd4 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c
@@ -929,6 +929,32 @@ reset:
EMLXS_MPDATA_SYNC(mp1->dma_handle, 0, MEM_ELSBUF_SIZE,
DDI_DMA_SYNC_FORKERNEL);
+#ifdef FMA_SUPPORT
+ if (mp->dma_handle) {
+ if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli3_online: hdl=%p",
+ mp->dma_handle);
+ rval = EIO;
+ goto failed;
+ }
+ }
+
+ if (mp1->dma_handle) {
+ if (emlxs_fm_check_dma_handle(hba, mp1->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli3_online: hdl=%p",
+ mp1->dma_handle);
+ rval = EIO;
+ goto failed;
+ }
+ }
+#endif /* FMA_SUPPORT */
+
outptr = mp->virt;
inptr = mp1->virt;
@@ -4991,6 +5017,19 @@ emlxs_handle_rcv_seq(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
goto dropped;
}
+#ifdef FMA_SUPPORT
+ if (mp->dma_handle) {
+ if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_handle_rcv_seq: hdl=%p",
+ mp->dma_handle);
+ goto dropped;
+ }
+ }
+#endif /* FMA_SUPPORT */
+
if (!size) {
(void) strcpy(error_str, "Buffer empty:");
goto dropped;
@@ -5574,6 +5613,22 @@ emlxs_reset_ring(emlxs_hba_t *hba, uint32_t ringno)
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ring_reset_msg, "%s",
emlxs_ring_xlate(ringno));
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, hba->sli.sli3.slim2.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_reset_ring: hdl=%p",
+ hba->sli.sli3.slim2.dma_handle);
+
+ emlxs_thread_spawn(hba, emlxs_restart_thread,
+ NULL, NULL);
+
+ return ((uint32_t)FC_FAILURE);
+ }
+#endif /* FMA_SUPPORT */
+
+
return (FC_SUCCESS);
} /* emlxs_reset_ring() */
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c
index 9aa820a2ae..0bc4936b3c 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli4.c
@@ -406,6 +406,22 @@ emlxs_data_dump(hba, "RD_REV", (uint32_t *)mb, 18, 0);
EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle,
0, mb->un.varDmp4.rsp_cnt, DDI_DMA_SYNC_FORKERNEL);
+#ifdef FMA_SUPPORT
+ if (hba->sli.sli4.dump_region.dma_handle) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.dump_region.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_online: hdl=%p",
+ hba->sli.sli4.dump_region.
+ dma_handle);
+ rval = EIO;
+ goto failed1;
+ }
+ }
+#endif /* FMA_SUPPORT */
+
}
}
@@ -1403,6 +1419,16 @@ emlxs_data_dump(hba, "EndianIN", (uint32_t *)iptr, 6, 0);
MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL);
emlxs_data_dump(hba, "EndianOUT", (uint32_t *)iptr, 6, 0);
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, hba->sli.sli4.bootstrapmb.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_init_bootstrap_mb: hdl=%p",
+ hba->sli.sli4.bootstrapmb.dma_handle);
+ return (1);
+ }
+#endif
hba->flag |= FC_BOOTSTRAPMB_INIT;
return (0);
@@ -1806,6 +1832,7 @@ emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
uint32_t flag;
uint32_t wqdb;
uint32_t next_wqe;
+ off_t offset;
channelno = cp->channelno;
@@ -1996,7 +2023,12 @@ sendit:
#ifdef DEBUG_WQE
emlxs_data_dump(hba, "WQE", (uint32_t *)wqe, 18, 0);
#endif
- EMLXS_MPDATA_SYNC(wq->addr.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ wq->addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(wq->addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORDEV);
/* Ring the WQ Doorbell */
@@ -2073,6 +2105,7 @@ emlxs_sli4_issue_mq(emlxs_hba_t *hba, MAILBOX4 *mqe, MAILBOX *mb, uint32_t tmo)
MATCHMAP *mp;
uint32_t *iptr;
uint32_t mqdb;
+ off_t offset;
mbq = (MAILBOXQ *)mb;
mb4 = (MAILBOX4 *)mb;
@@ -2117,7 +2150,12 @@ emlxs_sli4_issue_mq(emlxs_hba_t *hba, MAILBOX4 *mqe, MAILBOX *mb, uint32_t tmo)
BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe,
MAILBOX_CMD_SLI4_BSIZE);
- EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ hba->sli.sli4.mq.addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORDEV);
emlxs_data_dump(hba, "MBOX EXT", (uint32_t *)mqe, 12, 0);
@@ -2146,8 +2184,9 @@ emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo)
emlxs_port_t *port = &PPORT;
MAILBOXQ *mbq;
MAILBOX4 *mb4;
- MATCHMAP *mp;
+ MATCHMAP *mp = NULL;
uint32_t *iptr;
+ int nonembed = 0;
mbq = (MAILBOXQ *)mb;
mb4 = (MAILBOX4 *)mb;
@@ -2175,6 +2214,7 @@ emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo)
* mp will point to the actual mailbox command which
* should be copied into the non-embedded area.
*/
+ nonembed = 1;
mb4->un.varSLIConfig.be.sge_cnt = 1;
mb4->un.varSLIConfig.be.payload_length = mp->size;
iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req;
@@ -2239,6 +2279,29 @@ emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo)
emlxs_data_dump(hba, "EXT AREA", (uint32_t *)iptr, 24, 0);
}
+#ifdef FMA_SUPPORT
+ if (nonembed && mp) {
+ if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_issue_bootstrap: mp_hdl=%p",
+ mp->dma_handle);
+ return (MBXERR_DMA_ERROR);
+ }
+ }
+
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.bootstrapmb.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_issue_bootstrap: hdl=%p",
+ hba->sli.sli4.bootstrapmb.dma_handle);
+ return (MBXERR_DMA_ERROR);
+ }
+#endif
+
return (MBX_SUCCESS);
} /* emlxs_sli4_issue_bootstrap() */
@@ -2640,6 +2703,7 @@ emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel)
NODELIST *node;
uint16_t iotag;
uint32_t did;
+ off_t offset;
pkt = PRIV2PKT(sbp);
did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
@@ -2707,7 +2771,12 @@ emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel)
emlxs_data_dump(hba, "FCP CMD", (uint32_t *)pkt->pkt_cmd, 10, 0);
#endif
- EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ xp->SGList.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, offset,
xp->SGList.size, DDI_DMA_SYNC_FORDEV);
/* if device is FCP-2 device, set the following bit */
@@ -2785,6 +2854,7 @@ emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
ddi_dma_cookie_t *cp_cmd;
ddi_dma_cookie_t *cp_resp;
emlxs_node_t *node;
+ off_t offset;
pkt = PRIV2PKT(sbp);
did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
@@ -2925,7 +2995,7 @@ emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
sge->addrHigh = PADDR_HI(cp_resp->dmac_laddress);
sge->addrLow = PADDR_LO(cp_resp->dmac_laddress);
sge->length = pkt->pkt_rsplen;
- sge->offset = pkt->pkt_cmdlen;
+ sge->offset = 0;
sge->last = 1;
/* Now sge is fully staged */
@@ -2987,7 +3057,12 @@ emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
}
- EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ xp->SGList.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, offset,
xp->SGList.size, DDI_DMA_SYNC_FORDEV);
if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) {
@@ -3027,6 +3102,7 @@ emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
RPIobj_t *rp;
XRIobj_t *xp;
uint32_t did;
+ off_t offset;
pkt = PRIV2PKT(sbp);
did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
@@ -3169,7 +3245,12 @@ emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
iocb->un.genreq64.w5.hcsw.Dfctl = pkt->pkt_cmd_fhdr.df_ctl;
iocb->ULPPU = 1; /* Wd4 is relative offset */
- EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ xp->SGList.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, offset,
xp->SGList.size, DDI_DMA_SYNC_FORDEV);
wqe->ContextTag = rp->RPI;
@@ -3202,12 +3283,12 @@ emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
static int
emlxs_sli4_poll_eq(emlxs_hba_t *hba, EQ_DESC_t *eq)
{
- emlxs_port_t *port = &PPORT;
uint32_t *ptr;
int num_entries = 0;
EQE_u eqe;
uint32_t host_index, shost_index;
int rc = 0;
+ off_t offset;
/* EMLXS_PORT_LOCK must be held when entering this routine */
ptr = eq->addr.virt;
@@ -3216,7 +3297,12 @@ emlxs_sli4_poll_eq(emlxs_hba_t *hba, EQ_DESC_t *eq)
shost_index = host_index;
- EMLXS_MPDATA_SYNC(eq->addr.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ eq->addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORKERNEL);
mutex_enter(&EMLXS_PORT_LOCK);
@@ -3341,6 +3427,7 @@ emlxs_sli4_process_async_event(emlxs_hba_t *hba, CQE_ASYNC_t *cqe)
hba->linkspeed = LA_10GHZ_LINK;
}
hba->topology = TOPOLOGY_PT_PT;
+ hba->qos_linkspeed = cqe->qos_link_speed;
/*
* This link is not really up till we have
@@ -3414,6 +3501,7 @@ emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe)
uint32_t size;
uint32_t *iptr;
int rc;
+ off_t offset;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"CQ ENTRY: process mbox event");
@@ -3463,8 +3551,13 @@ emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe)
return;
}
+ offset = (off_t)((uint64_t)((unsigned long)
+ hba->sli.sli4.mq.addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
/* Now that we are the owner, DMA Sync entire MQ if needed */
- EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0,
+ EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORDEV);
BE_SWAP32_BCOPY((uint8_t *)hba->mbox_mqe, (uint8_t *)mb,
@@ -3487,6 +3580,17 @@ emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe)
mbox_bp = (MATCHMAP *)mbq->bp;
EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0, mbox_bp->size,
DDI_DMA_SYNC_FORKERNEL);
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba, mbox_bp->dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_process_mbox_event: hdl=%p",
+ mbox_bp->dma_handle);
+
+ mb->mbxStatus = MBXERR_DMA_ERROR;
+}
+#endif
}
/* Now sync the memory buffer if one was used */
@@ -3498,6 +3602,17 @@ emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe)
iptr = (uint32_t *)((uint8_t *)mbox_nonembed->virt);
BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)iptr, size);
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba,
+ mbox_nonembed->dma_handle) != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_process_mbox_event: hdl=%p",
+ mbox_nonembed->dma_handle);
+
+ mb->mbxStatus = MBXERR_DMA_ERROR;
+ }
+#endif
emlxs_data_dump(hba, "EXT AREA", (uint32_t *)iptr, 24, 0);
}
@@ -4004,8 +4119,8 @@ emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq,
emlxs_port_t *vport;
RQ_DESC_t *hdr_rq;
RQ_DESC_t *data_rq;
- MATCHMAP *hdr_mp;
- MATCHMAP *data_mp;
+ MBUF_INFO *hdr_mp;
+ MBUF_INFO *data_mp;
MATCHMAP *seq_mp;
uint32_t *data;
fc_frame_hdr_t fchdr;
@@ -4028,6 +4143,7 @@ emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq,
uint32_t cmd;
uint32_t posted = 0;
uint32_t abort = 1;
+ off_t offset;
hdr_rqi = hba->sli.sli4.rq_map[cqe->RQid];
hdr_rq = &hba->sli.sli4.rq[hdr_rqi];
@@ -4086,9 +4202,12 @@ emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq,
mutex_exit(&hba->sli.sli4.rq[hdr_rqi].lock);
/* Get the next header rqb */
- hdr_mp = hdr_rq->rqb[host_index];
+ hdr_mp = &hdr_rq->rqb[host_index];
+
+ offset = (off_t)((uint64_t)((unsigned long)hdr_mp->virt) -
+ (uint64_t)((unsigned long)hba->sli.sli4.slim2.virt));
- EMLXS_MPDATA_SYNC(hdr_mp->dma_handle, 0,
+ EMLXS_MPDATA_SYNC(hdr_mp->dma_handle, offset,
sizeof (fc_frame_hdr_t), DDI_DMA_SYNC_FORKERNEL);
LE_SWAP32_BCOPY(hdr_mp->virt, (uint8_t *)&fchdr,
@@ -4278,9 +4397,14 @@ emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq,
/* Save the frame data to our seq buffer */
if (cqe->data_size && seq_mp) {
/* Get the next data rqb */
- data_mp = data_rq->rqb[host_index];
+ data_mp = &data_rq->rqb[host_index];
- EMLXS_MPDATA_SYNC(data_mp->dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ data_mp->virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(data_mp->dma_handle, offset,
cqe->data_size, DDI_DMA_SYNC_FORKERNEL);
data = (uint32_t *)data_mp->virt;
@@ -4551,6 +4675,19 @@ done:
(void) emlxs_mem_put(hba, MEM_IOCB, (uint8_t *)iocbq);
}
+#ifdef FMA_SUPPORT
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.slim2.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_process_unsol_rcv: hdl=%p",
+ hba->sli.sli4.slim2.dma_handle);
+
+ emlxs_thread_spawn(hba, emlxs_restart_thread,
+ NULL, NULL);
+ }
+#endif
return;
} /* emlxs_sli4_process_unsol_rcv() */
@@ -4597,13 +4734,19 @@ emlxs_sli4_process_cq(emlxs_hba_t *hba, CQ_DESC_t *cq)
CQE_u cq_entry;
uint32_t cqdb;
int num_entries = 0;
+ off_t offset;
/* EMLXS_PORT_LOCK must be held when entering this routine */
cqe = (CQE_u *)cq->addr.virt;
cqe += cq->host_index;
- EMLXS_MPDATA_SYNC(cq->addr.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ cq->addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(cq->addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORKERNEL);
for (;;) {
@@ -4709,13 +4852,19 @@ emlxs_sli4_process_eq(emlxs_hba_t *hba, EQ_DESC_t *eq)
uint32_t i;
uint32_t value;
int num_entries = 0;
+ off_t offset;
/* EMLXS_PORT_LOCK must be held when entering this routine */
ptr = eq->addr.virt;
ptr += eq->host_index;
- EMLXS_MPDATA_SYNC(eq->addr.dma_handle, 0,
+ offset = (off_t)((uint64_t)((unsigned long)
+ eq->addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
+ EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset,
4096, DDI_DMA_SYNC_FORKERNEL);
for (;;) {
@@ -4940,7 +5089,6 @@ emlxs_sli4_resource_free(emlxs_hba_t *hba)
{
emlxs_port_t *port = &PPORT;
MBUF_INFO *buf_info;
- XRIobj_t *xp;
uint32_t i;
if (hba->sli.sli4.FCFIp) {
@@ -4961,8 +5109,6 @@ emlxs_sli4_resource_free(emlxs_hba_t *hba)
buf_info = &hba->sli.sli4.HeaderTmplate;
if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
bzero(buf_info, sizeof (MBUF_INFO));
}
@@ -4977,74 +5123,43 @@ emlxs_sli4_resource_free(emlxs_hba_t *hba)
hba->sli.sli4.XRIinuse_b,
&hba->sli.sli4.XRIinuse_f);
}
- xp = hba->sli.sli4.XRIp;
- for (i = 0; i < hba->sli.sli4.XRICount; i++) {
- buf_info = &xp->SGList;
- if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
- bzero(buf_info, sizeof (MBUF_INFO));
- }
- xp++;
- }
kmem_free(hba->sli.sli4.XRIp,
(sizeof (XRIobj_t) * hba->sli.sli4.XRICount));
hba->sli.sli4.XRIp = NULL;
- hba->sli.sli4.XRIfree_tail = NULL;
- hba->sli.sli4.XRIfree_list = NULL;
+
+ hba->sli.sli4.XRIfree_f =
+ (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.XRIfree_b =
+ (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
hba->sli.sli4.xrif_count = 0;
}
for (i = 0; i < EMLXS_MAX_EQS; i++) {
- buf_info = &hba->sli.sli4.eq[i].addr;
- if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
- mutex_destroy(&hba->sli.sli4.eq[i].lastwq_lock);
- }
+ mutex_destroy(&hba->sli.sli4.eq[i].lastwq_lock);
bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t));
}
for (i = 0; i < EMLXS_MAX_CQS; i++) {
- buf_info = &hba->sli.sli4.cq[i].addr;
- if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
- }
bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t));
}
for (i = 0; i < EMLXS_MAX_WQS; i++) {
- buf_info = &hba->sli.sli4.wq[i].addr;
- if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
- }
bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t));
}
for (i = 0; i < EMLXS_MAX_RQS; i++) {
- /* Free the RQ */
- buf_info = &hba->sli.sli4.rq[i].addr;
- if (buf_info->virt) {
- buf_info->flags = FC_MBUF_DMA;
- emlxs_mem_free(hba, buf_info);
-
- /* Free the RQB pool */
- emlxs_mem_pool_free(hba, &hba->sli.sli4.rq[i].rqb_pool);
- mutex_destroy(&hba->sli.sli4.rq[i].lock);
-
- /* Free the associated RXQ */
- mutex_destroy(&hba->sli.sli4.rxq[i].lock);
- bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t));
- }
+ mutex_destroy(&hba->sli.sli4.rq[i].lock);
+ mutex_destroy(&hba->sli.sli4.rxq[i].lock);
+ bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t));
bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t));
}
/* Free the MQ */
- buf_info = &hba->sli.sli4.mq.addr;
- if (buf_info->virt == NULL) {
+ bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t));
+
+ buf_info = &hba->sli.sli4.slim2;
+ if (buf_info->virt) {
buf_info->flags = FC_MBUF_DMA;
emlxs_mem_free(hba, buf_info);
+ bzero(buf_info, sizeof (MBUF_INFO));
}
- bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t));
/* Cleanup queue ordinal mapping */
for (i = 0; i < EMLXS_MAX_EQ_IDS; i++) {
@@ -5080,10 +5195,17 @@ emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
RPIobj_t *rp;
XRIobj_t *xp;
char buf[64];
- emlxs_memseg_t *seg;
- MATCHMAP *mp;
- MATCHMAP **rqb;
RQE_t *rqe;
+ MBUF_INFO *rqb;
+ uint64_t phys;
+ uint64_t tmp_phys;
+ char *virt;
+ char *tmp_virt;
+ void *data_handle;
+ void *dma_handle;
+ int32_t size;
+ off_t offset;
+ uint32_t count = 0;
(void) sprintf(buf, "%s_id_lock mutex", DRIVER_NAME);
mutex_init(&hba->sli.sli4.id_lock, buf, MUTEX_DRIVER, NULL);
@@ -5130,106 +5252,72 @@ emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
}
}
- if ((!hba->sli.sli4.XRIp) && (hba->sli.sli4.XRICount)) {
- hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc(
- (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP);
-
- xp = hba->sli.sli4.XRIp;
- index = hba->sli.sli4.XRIBase;
- for (i = 0; i < hba->sli.sli4.XRICount; i++) {
- xp->sge_count =
- (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64));
- xp->XRI = index;
- xp->iotag = i;
- if ((xp->XRI == 0) || (xp->iotag == 0)) {
- index++; /* Skip XRI 0 or IOTag 0 */
- xp++;
- continue;
- }
- /* Add xp to end of single linked free list */
- if (hba->sli.sli4.XRIfree_tail) {
- hba->sli.sli4.XRIfree_tail->_f = xp;
- hba->sli.sli4.XRIfree_tail = xp;
- } else {
- hba->sli.sli4.XRIfree_tail = xp;
- }
- if (hba->sli.sli4.XRIfree_list == NULL) {
- hba->sli.sli4.XRIfree_list = xp;
- }
- xp->_f = NULL;
- hba->sli.sli4.xrif_count++;
-
- /* Allocate SGL for this xp */
- buf_info = &xp->SGList;
- buf_info->size = hba->sli.sli4.mem_sgl_size;
- buf_info->flags =
- FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
- buf_info->align = hba->sli.sli4.mem_sgl_size;
+ /* EQs - 1 per Interrupt vector */
+ num_eq = hba->intr_count;
+ /* CQs - number of WQs + 1 for RQs + 1 for mbox/async events */
+ num_wq = cfg[CFG_NUM_WQ].current * num_eq;
- (void) emlxs_mem_alloc(hba, buf_info);
+ /* Calculate total dmable memory we need */
+ /* EQ */
+ count += num_eq * 4096;
+ /* CQ */
+ count += (num_wq + EMLXS_CQ_OFFSET_WQ) * 4096;
+ /* WQ */
+ count += num_wq * (4096 * EMLXS_NUM_WQ_PAGES);
+ /* MQ */
+ count += EMLXS_MAX_MQS * 4096;
+ /* RQ */
+ count += EMLXS_MAX_RQS * 4096;
+ /* RQB/E */
+ count += RQB_COUNT * (RQB_DATA_SIZE + RQB_HEADER_SIZE);
+ /* SGL */
+ count += hba->sli.sli4.XRICount * hba->sli.sli4.mem_sgl_size;
+ /* RPI Head Template */
+ count += hba->sli.sli4.RPICount * sizeof (RPIHdrTmplate_t);
+
+ /* Allocate slim2 for SLI4 */
+ buf_info = &hba->sli.sli4.slim2;
+ buf_info->size = count;
+ buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
+ buf_info->align = ddi_ptob(hba->dip, 1L);
+
+ (void) emlxs_mem_alloc(hba, buf_info);
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT,
- &emlxs_init_failed_msg,
- "Unable to allocate XRI SGL area: %d",
- hba->sli.sli4.mem_sgl_size);
- goto failed;
- }
- bzero(buf_info->virt, hba->sli.sli4.mem_sgl_size);
- xp++;
- index++;
- }
- /* Initialize double linked list */
- hba->sli.sli4.XRIinuse_f =
- (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
- hba->sli.sli4.XRIinuse_b =
- (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
- hba->sli.sli4.xria_count = 0;
+ if (buf_info->virt == NULL) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_init_failed_msg,
+ "Unable to allocate internal memory for SLI4: %d",
+ count);
+ goto failed;
}
+ bzero(buf_info->virt, buf_info->size);
+ EMLXS_MPDATA_SYNC(buf_info->dma_handle, 0,
+ buf_info->size, DDI_DMA_SYNC_FORDEV);
- buf_info = &hba->sli.sli4.HeaderTmplate;
- if ((buf_info->virt == NULL) && (hba->sli.sli4.RPICount)) {
- bzero(buf_info, sizeof (MBUF_INFO));
- buf_info->size = (sizeof (RPIHdrTmplate_t) *
- hba->sli.sli4.RPICount);
- buf_info->flags =
- FC_MBUF_DMA | FC_MBUF_DMA32;
- buf_info->align = ddi_ptob(hba->dip, 1L);
-
- (void) emlxs_mem_alloc(hba, buf_info);
-
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
- "Unable to allocate Header Tmplate area: %d",
- (sizeof (RPIHdrTmplate_t) *
- hba->sli.sli4.RPICount));
- goto failed;
- }
- bzero(buf_info->virt,
- (sizeof (RPIHdrTmplate_t) * hba->sli.sli4.RPICount));
- }
+ /* Assign memory to SGL, Head Template, EQ, CQ, WQ, RQ and MQ */
+ data_handle = buf_info->data_handle;
+ dma_handle = buf_info->dma_handle;
+ phys = buf_info->phys;
+ virt = (char *)buf_info->virt;
/* Allocate space for queues */
- /* EQs - 1 per Interrupt vector */
- num_eq = hba->intr_count;
+ size = 4096;
for (i = 0; i < num_eq; i++) {
buf_info = &hba->sli.sli4.eq[i].addr;
if (buf_info->virt == NULL) {
bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t));
- buf_info->size = 4096;
+ buf_info->size = size;
buf_info->flags =
FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
- (void) emlxs_mem_alloc(hba, buf_info);
+ phys += size;
+ virt += size;
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT,
- &emlxs_init_failed_msg,
- "Unable to allocate EQ %d area", i);
- goto failed;
- }
- bzero(buf_info->virt, 4096);
hba->sli.sli4.eq[i].max_index = EQ_DEPTH;
}
@@ -5238,53 +5326,71 @@ emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
mutex_init(&hba->sli.sli4.eq[i].lastwq_lock, buf,
MUTEX_DRIVER, NULL);
}
- /* CQs - number of WQs + 1 for RQs + 1 for mbox/async events */
- num_wq = cfg[CFG_NUM_WQ].current * num_eq;
+
+ size = 4096;
for (i = 0; i < (num_wq + EMLXS_CQ_OFFSET_WQ); i++) {
buf_info = &hba->sli.sli4.cq[i].addr;
if (buf_info->virt == NULL) {
bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t));
- buf_info->size = 4096;
+ buf_info->size = size;
buf_info->flags =
FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
- (void) emlxs_mem_alloc(hba, buf_info);
+ phys += size;
+ virt += size;
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT,
- &emlxs_init_failed_msg,
- "Unable to allocate CQ %d area", i);
- goto failed;
- }
- bzero(buf_info->virt, 4096);
hba->sli.sli4.cq[i].max_index = CQ_DEPTH;
}
}
+
/* WQs - NUM_WQ config parameter * number of EQs */
+ size = 4096 * EMLXS_NUM_WQ_PAGES;
for (i = 0; i < num_wq; i++) {
buf_info = &hba->sli.sli4.wq[i].addr;
if (buf_info->virt == NULL) {
bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t));
- buf_info->size = (4096 * EMLXS_NUM_WQ_PAGES);
+ buf_info->size = size;
buf_info->flags =
FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
- (void) emlxs_mem_alloc(hba, buf_info);
+ phys += size;
+ virt += size;
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT,
- &emlxs_init_failed_msg,
- "Unable to allocate WQ %d area", i);
- goto failed;
- }
- bzero(buf_info->virt, (4096 * EMLXS_NUM_WQ_PAGES));
hba->sli.sli4.wq[i].max_index = WQ_DEPTH;
hba->sli.sli4.wq[i].release_depth = WQE_RELEASE_DEPTH;
}
}
+ /* MQ */
+ size = 4096;
+ buf_info = &hba->sli.sli4.mq.addr;
+ if (!buf_info->virt) {
+ bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t));
+ buf_info->size = size;
+ buf_info->flags =
+ FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
+ buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
+
+ phys += size;
+ virt += size;
+
+ hba->sli.sli4.mq.max_index = MQ_DEPTH;
+ }
+
/* RXQs */
for (i = 0; i < EMLXS_MAX_RXQS; i++) {
bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t));
@@ -5294,6 +5400,7 @@ emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
}
/* RQs */
+ size = 4096;
for (i = 0; i < EMLXS_MAX_RQS; i++) {
buf_info = &hba->sli.sli4.rq[i].addr;
if (buf_info->virt) {
@@ -5301,107 +5408,157 @@ emlxs_sli4_resource_alloc(emlxs_hba_t *hba)
}
bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t));
- buf_info->size = 4096;
+ buf_info->size = size;
buf_info->flags =
FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
- (void) emlxs_mem_alloc(hba, buf_info);
+ phys += size;
+ virt += size;
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT,
- &emlxs_init_failed_msg,
- "Unable to allocate RQ %d area", i);
- goto failed;
- }
- bzero(buf_info->virt, 4096);
hba->sli.sli4.rq[i].max_index = RQ_DEPTH;
- /* RQBs */
- seg = &hba->sli.sli4.rq[i].rqb_pool;
- bzero(seg, sizeof (MEMSEG));
- seg->fc_numblks = RQB_COUNT;
- seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
- seg->fc_memalign = 8;
- seg->fc_memtag = (i<<16);
-
- if ((i & 0x1)) {
- /* Odd == Data pool */
- seg->fc_memsize = RQB_DATA_SIZE;
- (void) strcpy(seg->fc_label, "RQB Data Pool");
-
- } else {
- /* Even == Header pool */
- seg->fc_memsize = RQB_HEADER_SIZE;
- (void) strcpy(seg->fc_label, "RQB Header Pool");
- }
-
- /* Allocate the pool */
- if (emlxs_mem_pool_alloc(hba, seg) == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
- "Unable to allocate RQ %d pool", i);
+ (void) sprintf(buf, "%s_rq%d_lock mutex", DRIVER_NAME, i);
+ mutex_init(&hba->sli.sli4.rq[i].lock, buf, MUTEX_DRIVER, NULL);
+ }
- goto failed;
- }
+ /* Setup RQE */
+ for (i = 0; i < EMLXS_MAX_RQS; i++) {
+ size = (i & 0x1) ? RQB_DATA_SIZE : RQB_HEADER_SIZE;
+ tmp_phys = phys;
+ tmp_virt = virt;
/* Initialize the RQEs */
rqe = (RQE_t *)hba->sli.sli4.rq[i].addr.virt;
- rqb = hba->sli.sli4.rq[i].rqb;
-
for (j = 0; j < (RQ_DEPTH/RQB_COUNT); j++) {
- mp = (MATCHMAP*)seg->fc_memget_ptr;
+ phys = tmp_phys;
+ virt = tmp_virt;
for (k = 0; k < RQB_COUNT; k++) {
- if (j == 0) {
- mp->tag = (seg->fc_memtag | k);
- }
-
- word = PADDR_HI(mp->phys);
+ word = PADDR_HI(phys);
rqe->AddrHi = BE_SWAP32(word);
- word = PADDR_LO(mp->phys);
+ word = PADDR_LO(phys);
rqe->AddrLo = BE_SWAP32(word);
- *rqb = mp;
-
+ rqb = &hba->sli.sli4.rq[i].
+ rqb[k + (j * RQB_COUNT)];
+ rqb->size = size;
+ rqb->flags = FC_MBUF_DMA |
+ FC_MBUF_SNGLSG | FC_MBUF_DMA32;
+ rqb->align = ddi_ptob(hba->dip, 1L);
+ rqb->phys = phys;
+ rqb->virt = virt;
+ rqb->data_handle = data_handle;
+ rqb->dma_handle = dma_handle;
+
+ phys += size;
+ virt += size;
#ifdef RQ_DEBUG
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
"RQ_ALLOC: rq[%d] rqb[%d,%d]=%p tag=%08x",
i, j, k, mp, mp->tag);
#endif
- mp = (MATCHMAP *)mp->fc_mptr;
rqe++;
- rqb++;
}
}
+ offset = (off_t)((uint64_t)((unsigned long)
+ hba->sli.sli4.rq[i].addr.virt) -
+ (uint64_t)((unsigned long)
+ hba->sli.sli4.slim2.virt));
+
/* Sync the RQ buffer list */
- EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, 0,
+ EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, offset,
hba->sli.sli4.rq[i].addr.size, DDI_DMA_SYNC_FORDEV);
+ }
- (void) sprintf(buf, "%s_rq%d_lock mutex", DRIVER_NAME, i);
- mutex_init(&hba->sli.sli4.rq[i].lock, buf, MUTEX_DRIVER, NULL);
+ if ((!hba->sli.sli4.XRIp) && (hba->sli.sli4.XRICount)) {
+ /* Initialize double linked lists */
+ hba->sli.sli4.XRIinuse_f =
+ (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
+ hba->sli.sli4.XRIinuse_b =
+ (XRIobj_t *)&hba->sli.sli4.XRIinuse_f;
+ hba->sli.sli4.xria_count = 0;
+
+ hba->sli.sli4.XRIfree_f =
+ (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.XRIfree_b =
+ (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.xria_count = 0;
+
+ hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc(
+ (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP);
+
+ xp = hba->sli.sli4.XRIp;
+ index = hba->sli.sli4.XRIBase;
+ size = hba->sli.sli4.mem_sgl_size;
+ for (i = 0; i < hba->sli.sli4.XRICount; i++) {
+ xp->sge_count =
+ (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64));
+ xp->XRI = index;
+ xp->iotag = i;
+ if ((xp->XRI == 0) || (xp->iotag == 0)) {
+ index++; /* Skip XRI 0 or IOTag 0 */
+ xp++;
+ continue;
+ }
+ /* Add xp to end of free list */
+ xp->_b = hba->sli.sli4.XRIfree_b;
+ hba->sli.sli4.XRIfree_b->_f = xp;
+ xp->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.XRIfree_b = xp;
+ hba->sli.sli4.xrif_count++;
+
+ /* Allocate SGL for this xp */
+ buf_info = &xp->SGList;
+ buf_info->size = size;
+ buf_info->flags =
+ FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
+ buf_info->align = size;
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
+
+ phys += size;
+ virt += size;
+
+ xp++;
+ index++;
+ }
}
- /* MQ */
- buf_info = &hba->sli.sli4.mq.addr;
- if (!buf_info->virt) {
- bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t));
- buf_info->size = 4096;
- buf_info->flags =
- FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
+ size = sizeof (RPIHdrTmplate_t) * hba->sli.sli4.RPICount;
+ buf_info = &hba->sli.sli4.HeaderTmplate;
+ if ((buf_info->virt == NULL) && (hba->sli.sli4.RPICount)) {
+ bzero(buf_info, sizeof (MBUF_INFO));
+ buf_info->size = size;
+ buf_info->flags = FC_MBUF_DMA | FC_MBUF_DMA32;
buf_info->align = ddi_ptob(hba->dip, 1L);
+ buf_info->phys = phys;
+ buf_info->virt = virt;
+ buf_info->data_handle = data_handle;
+ buf_info->dma_handle = dma_handle;
+ }
- (void) emlxs_mem_alloc(hba, buf_info);
-
- if (buf_info->virt == NULL) {
- EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
- "Unable to allocate MQ area");
+#ifdef FMA_SUPPORT
+ if (hba->sli.sli4.slim2.dma_handle) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.slim2.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "emlxs_sli4_resource_alloc: hdl=%p",
+ hba->sli.sli4.slim2.dma_handle);
goto failed;
}
- bzero(buf_info->virt, 4096);
- hba->sli.sli4.mq.max_index = MQ_DEPTH;
}
+#endif
return (0);
@@ -5565,9 +5722,9 @@ emlxs_sli4_reserve_xri(emlxs_hba_t *hba, RPIobj_t *rp)
mutex_enter(&EMLXS_FCTAB_LOCK);
- xp = hba->sli.sli4.XRIfree_list;
+ xp = hba->sli.sli4.XRIfree_f;
- if (xp == NULL) {
+ if (xp == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) {
mutex_exit(&EMLXS_FCTAB_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
@@ -5600,8 +5757,10 @@ emlxs_sli4_reserve_xri(emlxs_hba_t *hba, RPIobj_t *rp)
}
/* Take it off free list */
- hba->sli.sli4.XRIfree_list = xp->_f;
+ (xp->_b)->_f = xp->_f;
+ (xp->_f)->_b = xp->_b;
xp->_f = NULL;
+ xp->_b = NULL;
hba->sli.sli4.xrif_count--;
/* Add it to end of inuse list */
@@ -5661,8 +5820,10 @@ emlxs_sli4_unreserve_xri(emlxs_hba_t *hba, uint16_t xri)
hba->sli.sli4.xria_count--;
/* Add it to end of free list */
- hba->sli.sli4.XRIfree_tail->_f = xp;
- hba->sli.sli4.XRIfree_tail = xp;
+ xp->_b = hba->sli.sli4.XRIfree_b;
+ hba->sli.sli4.XRIfree_b->_f = xp;
+ xp->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.XRIfree_b = xp;
hba->sli.sli4.xrif_count++;
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
@@ -5747,9 +5908,9 @@ emlxs_sli4_alloc_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, RPIobj_t *rp)
mutex_enter(&EMLXS_FCTAB_LOCK);
- xp = hba->sli.sli4.XRIfree_list;
+ xp = hba->sli.sli4.XRIfree_f;
- if (xp == NULL) {
+ if (xp == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) {
mutex_exit(&EMLXS_FCTAB_LOCK);
EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg,
@@ -5789,8 +5950,10 @@ emlxs_sli4_alloc_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, RPIobj_t *rp)
}
/* Take it off free list */
- hba->sli.sli4.XRIfree_list = xp->_f;
+ (xp->_b)->_f = xp->_f;
+ (xp->_f)->_b = xp->_b;
xp->_f = NULL;
+ xp->_b = NULL;
hba->sli.sli4.xrif_count--;
/* Add it to end of inuse list */
@@ -6049,8 +6212,10 @@ emlxs_sli4_free_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, XRIobj_t *xp)
hba->sli.sli4.xria_count--;
/* Add it to end of free list */
- hba->sli.sli4.XRIfree_tail->_f = xp;
- hba->sli.sli4.XRIfree_tail = xp;
+ xp->_b = hba->sli.sli4.XRIfree_b;
+ hba->sli.sli4.XRIfree_b->_f = xp;
+ xp->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f;
+ hba->sli.sli4.XRIfree_b = xp;
hba->sli.sli4.xrif_count++;
}
diff --git a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c
index c1b063ceef..66c4c645c6 100644
--- a/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c
+++ b/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_solaris.c
@@ -2581,6 +2581,7 @@ emlxs_poll(emlxs_port_t *port, emlxs_buf_t *sbp)
clock_t time;
uint32_t att_bit;
CHANNEL *cp;
+ int in_panic = 0;
mutex_enter(&EMLXS_PORT_LOCK);
hba->io_poll_count++;
@@ -2590,6 +2591,7 @@ emlxs_poll(emlxs_port_t *port, emlxs_buf_t *sbp)
cp = (CHANNEL *)sbp->channel;
if (ddi_in_panic()) {
+ in_panic = 1;
/*
* In panic situations there will be one thread with
* no interrrupts (hard or soft) and no timers
@@ -2752,12 +2754,25 @@ done:
hba->io_poll_count--;
mutex_exit(&EMLXS_PORT_LOCK);
+#ifdef FMA_SUPPORT
+ if (!in_panic) {
+ emlxs_check_dma(hba, sbp);
+ }
+#endif
+
/* Make ULP completion callback if required */
if (pkt->pkt_comp) {
cp->ulpCmplCmd++;
(*pkt->pkt_comp) (pkt);
}
+#ifdef FMA_SUPPORT
+ if (hba->flag & FC_DMA_CHECK_ERROR) {
+ emlxs_thread_spawn(hba, emlxs_restart_thread,
+ NULL, NULL);
+ }
+#endif
+
return;
} /* emlxs_poll() */
@@ -9482,6 +9497,13 @@ emlxs_iodone_server(void *arg1, void *arg2, void *arg3)
mutex_exit(&EMLXS_PORT_LOCK);
+#ifdef FMA_SUPPORT
+ if (hba->flag & FC_DMA_CHECK_ERROR) {
+ emlxs_thread_spawn(hba, emlxs_restart_thread,
+ NULL, NULL);
+ }
+#endif /* FMA_SUPPORT */
+
return;
} /* End emlxs_iodone_server */
@@ -9490,6 +9512,11 @@ emlxs_iodone_server(void *arg1, void *arg2, void *arg3)
static void
emlxs_iodone(emlxs_buf_t *sbp)
{
+#ifdef FMA_SUPPORT
+ emlxs_port_t *port = sbp->port;
+ emlxs_hba_t *hba = port->hba;
+#endif /* FMA_SUPPORT */
+
fc_packet_t *pkt;
CHANNEL *cp;
@@ -9510,6 +9537,9 @@ emlxs_iodone(emlxs_buf_t *sbp)
mutex_exit(&sbp->mtx);
if (pkt->pkt_comp) {
+#ifdef FMA_SUPPORT
+ emlxs_check_dma(hba, sbp);
+#endif /* FMA_SUPPORT */
cp->ulpCmplCmd++;
(*pkt->pkt_comp) (pkt);
}
@@ -11017,9 +11047,6 @@ emlxs_fm_init(emlxs_hba_t *hba)
if (DDI_FM_ACC_ERR_CAP(hba->fm_caps)) {
emlxs_dev_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
emlxs_data_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
- } else {
- emlxs_dev_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
- emlxs_data_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
}
if (DDI_FM_DMA_ERR_CAP(hba->fm_caps)) {
@@ -11155,6 +11182,8 @@ emlxs_fm_service_impact(emlxs_hba_t *hba, int impact)
ddi_fm_service_impact(hba->dip, impact);
+ return;
+
} /* emlxs_fm_service_impact() */
@@ -11175,6 +11204,103 @@ emlxs_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err,
return (err->fme_status);
} /* emlxs_fm_error_cb() */
+
+extern void
+emlxs_check_dma(emlxs_hba_t *hba, emlxs_buf_t *sbp)
+{
+ emlxs_port_t *port = sbp->port;
+ fc_packet_t *pkt = PRIV2PKT(sbp);
+
+ if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli4.slim2.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "slim2: hdl=%p",
+ hba->sli.sli4.slim2.dma_handle);
+
+ mutex_enter(&EMLXS_PORT_LOCK);
+ hba->flag |= FC_DMA_CHECK_ERROR;
+ mutex_exit(&EMLXS_PORT_LOCK);
+ }
+ } else {
+ if (emlxs_fm_check_dma_handle(hba,
+ hba->sli.sli3.slim2.dma_handle)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "slim2: hdl=%p",
+ hba->sli.sli3.slim2.dma_handle);
+
+ mutex_enter(&EMLXS_PORT_LOCK);
+ hba->flag |= FC_DMA_CHECK_ERROR;
+ mutex_exit(&EMLXS_PORT_LOCK);
+ }
+ }
+
+ if (hba->flag & FC_DMA_CHECK_ERROR) {
+ pkt->pkt_state = FC_PKT_TRAN_ERROR;
+ pkt->pkt_reason = FC_REASON_DMA_ERROR;
+ pkt->pkt_expln = FC_EXPLN_NONE;
+ pkt->pkt_action = FC_ACTION_RETRYABLE;
+ return;
+ }
+
+ if (pkt->pkt_cmdlen) {
+ if (emlxs_fm_check_dma_handle(hba, pkt->pkt_cmd_dma)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "pkt_cmd_dma: hdl=%p",
+ pkt->pkt_cmd_dma);
+
+ pkt->pkt_state = FC_PKT_TRAN_ERROR;
+ pkt->pkt_reason = FC_REASON_DMA_ERROR;
+ pkt->pkt_expln = FC_EXPLN_NONE;
+ pkt->pkt_action = FC_ACTION_RETRYABLE;
+
+ return;
+ }
+ }
+
+ if (pkt->pkt_rsplen) {
+ if (emlxs_fm_check_dma_handle(hba, pkt->pkt_resp_dma)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "pkt_resp_dma: hdl=%p",
+ pkt->pkt_resp_dma);
+
+ pkt->pkt_state = FC_PKT_TRAN_ERROR;
+ pkt->pkt_reason = FC_REASON_DMA_ERROR;
+ pkt->pkt_expln = FC_EXPLN_NONE;
+ pkt->pkt_action = FC_ACTION_RETRYABLE;
+
+ return;
+ }
+ }
+
+ if (pkt->pkt_datalen) {
+ if (emlxs_fm_check_dma_handle(hba, pkt->pkt_data_dma)
+ != DDI_FM_OK) {
+ EMLXS_MSGF(EMLXS_CONTEXT,
+ &emlxs_invalid_dma_handle_msg,
+ "pkt_data_dma: hdl=%p",
+ pkt->pkt_data_dma);
+
+ pkt->pkt_state = FC_PKT_TRAN_ERROR;
+ pkt->pkt_reason = FC_REASON_DMA_ERROR;
+ pkt->pkt_expln = FC_EXPLN_NONE;
+ pkt->pkt_action = FC_ACTION_RETRYABLE;
+
+ return;
+ }
+ }
+
+ return;
+
+}
#endif /* FMA_SUPPORT */
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfc.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfc.h
index 8a19ca417a..7559fd7d02 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfc.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_dfc.h
@@ -176,6 +176,7 @@ typedef struct sd_bucket_info
#define EMLXS_RD_BE_FCF 82
#define EMLXS_SET_BE_DCBX 83
#define EMLXS_GET_BE_DCBX 84
+#define EMLXS_GET_QOS 85
/* SAN DIAG SUPPORT */
#define EMLXS_SD_SET_BUCKET 100
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h
index 8be3cf912a..12f551013f 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_extern.h
@@ -224,6 +224,8 @@ extern void emlxs_fm_service_impact(emlxs_hba_t *hba,
extern int emlxs_fm_error_cb(dev_info_t *dip,
ddi_fm_error_t *err,
const void *impl_data);
+extern void emlxs_check_dma(emlxs_hba_t *hba,
+ emlxs_buf_t *sbp);
#endif /* FMA_SUPPORT */
/* Module emlxs_pkt.c External Routine Declarations */
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h
index bc4e50300f..51a0b89938 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_fc.h
@@ -1456,8 +1456,7 @@ typedef struct RQ_DESC
uint16_t cqid;
MBUF_INFO addr;
- MEMSEG rqb_pool;
- MATCHMAP *rqb[RQ_DEPTH];
+ MBUF_INFO rqb[RQ_DEPTH];
kmutex_t lock;
@@ -1627,15 +1626,17 @@ typedef struct emlxs_sli4
tlv_fcoe_t cfgFCOE;
tlv_fcfconnectlist_t cfgFCF;
+ MBUF_INFO slim2;
MBUF_INFO dump_region;
#define EMLXS_DUMP_REGION_SIZE 1024
RPIobj_t *RPIp;
MBUF_INFO HeaderTmplate;
XRIobj_t *XRIp;
- /* Single linked list for available XRIs */
- XRIobj_t *XRIfree_list;
- XRIobj_t *XRIfree_tail;
+
+ /* Double linked list for available XRIs */
+ XRIobj_t *XRIfree_f;
+ XRIobj_t *XRIfree_b;
uint32_t xrif_count;
uint32_t mem_sgl_size;
@@ -1727,6 +1728,7 @@ typedef struct emlxs_hba
uint32_t link_event_tag;
uint8_t topology;
uint8_t linkspeed;
+ uint16_t qos_linkspeed;
uint32_t linkup_wait_flag;
kcondvar_t linkup_lock_cv;
kmutex_t linkup_lock;
@@ -1804,6 +1806,8 @@ typedef struct emlxs_hba
/* over temperature event */
#define FC_MBOX_TIMEOUT 0x20000000 /* FC_ERROR reason: */
/* mailbox timeout event */
+#define FC_DMA_CHECK_ERROR 0x40000000 /* Shared memory (slim,..) */
+ /* DMA handle went bad */
#define FC_HARDWARE_ERROR 0x80000000 /* FC_ERROR state triggered */
#define FC_RESET_MASK 0x00030C1F /* Bits to protect during */
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h
index 094163307c..3ede834f4a 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_mbox.h
@@ -1868,8 +1868,7 @@ typedef struct
uint32_t rsvd1;
uint32_t rsvd2:8;
uint32_t sid:24;
- uint32_t rsvd3;
- uint32_t rsvd4;
+ uint32_t portname[2]; /* N_PORT name */
uint32_t rsvd5;
uint16_t vfi;
uint16_t vpi;
@@ -1878,8 +1877,7 @@ typedef struct
uint32_t rsvd1;
uint32_t sid:24;
uint32_t rsvd2:8;
- uint32_t rsvd3;
- uint32_t rsvd4;
+ uint32_t portname[2]; /* N_PORT name */
uint32_t rsvd5;
uint16_t vpi;
uint16_t vfi;
@@ -1953,8 +1951,7 @@ typedef struct
uint16_t vpi;
uint16_t fcfi;
- uint32_t rsvd3;
- uint32_t rsvd4;
+ uint32_t portname[2]; /* N_PORT name */
ULP_BDE64 bde;
@@ -1974,8 +1971,7 @@ typedef struct
uint16_t fcfi;
uint16_t vpi;
- uint32_t rsvd3;
- uint32_t rsvd4;
+ uint32_t portname[2]; /* N_PORT name */
ULP_BDE64 bde;
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_os.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_os.h
index e7a2226b8e..d846254d95 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_os.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_os.h
@@ -302,27 +302,11 @@ extern void ddi_fm_acc_err_clear();
#define DELAYMS(ms) drv_usecwait((ms*1000))
#define DELAYUS(us) drv_usecwait(us)
-#ifdef FMA_SUPPORT
-#define EMLXS_MPDATA_SYNC(h, a, b, c) \
- if (h) { \
- (void) ddi_dma_sync((ddi_dma_handle_t)(h), \
- (off_t)(a), (size_t)(b), (uint_t)c); \
- if (emlxs_fm_check_dma_handle(hba, h) != DDI_FM_OK) { \
- EMLXS_MSGF(EMLXS_CONTEXT, \
- &emlxs_invalid_dma_handle_msg, \
- "ddi_dma_sync hdl=%p off=%x " \
- "size=%d dir=%x ", \
- h, a, b, c); \
- } \
- }
-#else /* !FMA_SUPPORT */
#define EMLXS_MPDATA_SYNC(h, a, b, c) \
if (h) { \
(void) ddi_dma_sync((ddi_dma_handle_t)(h), \
(off_t)(a), (size_t)(b), (uint_t)c); \
}
-#endif /* FMA_SUPPORT */
-
#define PKT2PRIV(pkt) ((emlxs_buf_t *)(pkt)->pkt_fca_private)
#define PRIV2PKT(sbp) sbp->pkt
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_queue.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_queue.h
index 536824b584..c410fe935f 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_queue.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_queue.h
@@ -267,8 +267,9 @@ typedef struct CQE_ASYNC
uint8_t link_status;
uint8_t phys_port;
- uint32_t Rsvd1: 24; /* Word 1 */
- uint32_t port_fault: 8;
+ uint16_t qos_link_speed; /* Word 1 */
+ uint8_t Rsvd1;
+ uint8_t port_fault;
uint32_t event_tag; /* Word 2 */
@@ -285,8 +286,9 @@ typedef struct CQE_ASYNC
uint8_t port_duplex;
uint8_t port_speed; /* Word 0 */
- uint32_t port_fault: 8;
- uint32_t Rsvd1: 24; /* Word 1 */
+ uint8_t port_fault; /* Word 1 */
+ uint8_t Rsvd1;
+ uint16_t qos_link_speed;
uint32_t event_tag; /* Word 2 */
diff --git a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h
index 6fd91ec7dc..a8579afff5 100644
--- a/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h
+++ b/usr/src/uts/common/sys/fibre-channel/fca/emlxs/emlxs_version.h
@@ -31,10 +31,10 @@
extern "C" {
#endif
-#define EMLXS_VERSION "2.50m"
+#define EMLXS_VERSION "2.50n"
#define EMLXS_DATE_MINUTE "00" /* 00-59 */
#define EMLXS_DATE_HOUR "16" /* 00-23 */
-#define EMLXS_DATE_DAY "08" /* 00-31 */
+#define EMLXS_DATE_DAY "14" /* 00-31 */
#define EMLXS_DATE_MONTH "12" /* 01-12 */
#define EMLXS_DATE_YEAR "2009" /* YYYY */