1291a2b48SSukumar Swaminathan /*
2291a2b48SSukumar Swaminathan * CDDL HEADER START
3291a2b48SSukumar Swaminathan *
4291a2b48SSukumar Swaminathan * The contents of this file are subject to the terms of the
5291a2b48SSukumar Swaminathan * Common Development and Distribution License (the "License").
6291a2b48SSukumar Swaminathan * You may not use this file except in compliance with the License.
7291a2b48SSukumar Swaminathan *
88f23e9faSHans Rosenfeld * You can obtain a copy of the license at
98f23e9faSHans Rosenfeld * http://www.opensource.org/licenses/cddl1.txt.
10291a2b48SSukumar Swaminathan * See the License for the specific language governing permissions
11291a2b48SSukumar Swaminathan * and limitations under the License.
12291a2b48SSukumar Swaminathan *
13291a2b48SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each
14291a2b48SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15291a2b48SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the
16291a2b48SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying
17291a2b48SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner]
18291a2b48SSukumar Swaminathan *
19291a2b48SSukumar Swaminathan * CDDL HEADER END
20291a2b48SSukumar Swaminathan */
21291a2b48SSukumar Swaminathan
22291a2b48SSukumar Swaminathan /*
238f23e9faSHans Rosenfeld * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan * Use is subject to license terms.
25*a3170057SPaul Winder * Copyright 2020 RackTop Systems, Inc.
26291a2b48SSukumar Swaminathan */
27291a2b48SSukumar Swaminathan
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29291a2b48SSukumar Swaminathan
30291a2b48SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
3182527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_SLI3_C);
32291a2b48SSukumar Swaminathan
3382527734SSukumar Swaminathan static void emlxs_sli3_issue_iocb(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq);
3482527734SSukumar Swaminathan static void emlxs_sli3_handle_link_event(emlxs_hba_t *hba);
3582527734SSukumar Swaminathan static void emlxs_sli3_handle_ring_event(emlxs_hba_t *hba, int32_t ring_no,
36291a2b48SSukumar Swaminathan uint32_t ha_copy);
37291a2b48SSukumar Swaminathan #ifdef SFCT_SUPPORT
38291a2b48SSukumar Swaminathan static uint32_t emlxs_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
39291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
4082527734SSukumar Swaminathan
41291a2b48SSukumar Swaminathan static uint32_t emlxs_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
42291a2b48SSukumar Swaminathan
4382527734SSukumar Swaminathan static uint32_t emlxs_disable_traffic_cop = 1;
44291a2b48SSukumar Swaminathan
4582527734SSukumar Swaminathan static int emlxs_sli3_map_hdw(emlxs_hba_t *hba);
46291a2b48SSukumar Swaminathan
4782527734SSukumar Swaminathan static void emlxs_sli3_unmap_hdw(emlxs_hba_t *hba);
48291a2b48SSukumar Swaminathan
4982527734SSukumar Swaminathan static int32_t emlxs_sli3_online(emlxs_hba_t *hba);
50291a2b48SSukumar Swaminathan
518f23e9faSHans Rosenfeld static void emlxs_sli3_offline(emlxs_hba_t *hba,
528f23e9faSHans Rosenfeld uint32_t reset_requested);
53291a2b48SSukumar Swaminathan
5482527734SSukumar Swaminathan static uint32_t emlxs_sli3_hba_reset(emlxs_hba_t *hba,
5582527734SSukumar Swaminathan uint32_t restart, uint32_t skip_post,
5682527734SSukumar Swaminathan uint32_t quiesce);
57291a2b48SSukumar Swaminathan
5882527734SSukumar Swaminathan static void emlxs_sli3_hba_kill(emlxs_hba_t *hba);
5982527734SSukumar Swaminathan static void emlxs_sli3_hba_kill4quiesce(emlxs_hba_t *hba);
6082527734SSukumar Swaminathan static uint32_t emlxs_sli3_hba_init(emlxs_hba_t *hba);
61291a2b48SSukumar Swaminathan
6282527734SSukumar Swaminathan static uint32_t emlxs_sli2_bde_setup(emlxs_port_t *port,
6382527734SSukumar Swaminathan emlxs_buf_t *sbp);
6482527734SSukumar Swaminathan static uint32_t emlxs_sli3_bde_setup(emlxs_port_t *port,
6582527734SSukumar Swaminathan emlxs_buf_t *sbp);
6682527734SSukumar Swaminathan static uint32_t emlxs_sli2_fct_bde_setup(emlxs_port_t *port,
6782527734SSukumar Swaminathan emlxs_buf_t *sbp);
6882527734SSukumar Swaminathan static uint32_t emlxs_sli3_fct_bde_setup(emlxs_port_t *port,
6982527734SSukumar Swaminathan emlxs_buf_t *sbp);
70291a2b48SSukumar Swaminathan
71291a2b48SSukumar Swaminathan
7282527734SSukumar Swaminathan static void emlxs_sli3_issue_iocb_cmd(emlxs_hba_t *hba,
7382527734SSukumar Swaminathan CHANNEL *rp, IOCBQ *iocb_cmd);
74291a2b48SSukumar Swaminathan
75291a2b48SSukumar Swaminathan
7682527734SSukumar Swaminathan static uint32_t emlxs_sli3_issue_mbox_cmd(emlxs_hba_t *hba,
7782527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg,
7882527734SSukumar Swaminathan uint32_t tmo);
79291a2b48SSukumar Swaminathan
80291a2b48SSukumar Swaminathan
8182527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
8282527734SSukumar Swaminathan static uint32_t emlxs_sli3_prep_fct_iocb(emlxs_port_t *port,
8382527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp, int channel);
84291a2b48SSukumar Swaminathan
8582527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
86291a2b48SSukumar Swaminathan
8782527734SSukumar Swaminathan static uint32_t emlxs_sli3_prep_fcp_iocb(emlxs_port_t *port,
8882527734SSukumar Swaminathan emlxs_buf_t *sbp, int ring);
89291a2b48SSukumar Swaminathan
9082527734SSukumar Swaminathan static uint32_t emlxs_sli3_prep_ip_iocb(emlxs_port_t *port,
9182527734SSukumar Swaminathan emlxs_buf_t *sbp);
92291a2b48SSukumar Swaminathan
9382527734SSukumar Swaminathan static uint32_t emlxs_sli3_prep_els_iocb(emlxs_port_t *port,
9482527734SSukumar Swaminathan emlxs_buf_t *sbp);
95291a2b48SSukumar Swaminathan
96291a2b48SSukumar Swaminathan
9782527734SSukumar Swaminathan static uint32_t emlxs_sli3_prep_ct_iocb(emlxs_port_t *port,
9882527734SSukumar Swaminathan emlxs_buf_t *sbp);
99291a2b48SSukumar Swaminathan
100291a2b48SSukumar Swaminathan
1018f23e9faSHans Rosenfeld static void emlxs_sli3_poll_intr(emlxs_hba_t *hba);
102291a2b48SSukumar Swaminathan
10382527734SSukumar Swaminathan static int32_t emlxs_sli3_intx_intr(char *arg);
10482527734SSukumar Swaminathan #ifdef MSI_SUPPORT
10582527734SSukumar Swaminathan static uint32_t emlxs_sli3_msi_intr(char *arg1, char *arg2);
10682527734SSukumar Swaminathan #endif /* MSI_SUPPORT */
107291a2b48SSukumar Swaminathan
10882527734SSukumar Swaminathan static void emlxs_sli3_enable_intr(emlxs_hba_t *hba);
10982527734SSukumar Swaminathan
11082527734SSukumar Swaminathan static void emlxs_sli3_disable_intr(emlxs_hba_t *hba,
11182527734SSukumar Swaminathan uint32_t att);
11282527734SSukumar Swaminathan
113a9800bebSGarrett D'Amore
11482527734SSukumar Swaminathan static void emlxs_handle_ff_error(emlxs_hba_t *hba);
11582527734SSukumar Swaminathan
11682527734SSukumar Swaminathan static uint32_t emlxs_handle_mb_event(emlxs_hba_t *hba);
11782527734SSukumar Swaminathan
11882527734SSukumar Swaminathan static void emlxs_sli3_timer_check_mbox(emlxs_hba_t *hba);
11982527734SSukumar Swaminathan
12082527734SSukumar Swaminathan static uint32_t emlxs_mb_config_port(emlxs_hba_t *hba,
12182527734SSukumar Swaminathan MAILBOXQ *mbq, uint32_t sli_mode,
12282527734SSukumar Swaminathan uint32_t hbainit);
12382527734SSukumar Swaminathan static void emlxs_enable_latt(emlxs_hba_t *hba);
12482527734SSukumar Swaminathan
12582527734SSukumar Swaminathan static uint32_t emlxs_check_attention(emlxs_hba_t *hba);
12682527734SSukumar Swaminathan
12782527734SSukumar Swaminathan static uint32_t emlxs_get_attention(emlxs_hba_t *hba,
128a9800bebSGarrett D'Amore int32_t msgid);
12982527734SSukumar Swaminathan static void emlxs_proc_attention(emlxs_hba_t *hba,
13082527734SSukumar Swaminathan uint32_t ha_copy);
13182527734SSukumar Swaminathan /* static int emlxs_handle_rcv_seq(emlxs_hba_t *hba, */
13282527734SSukumar Swaminathan /* CHANNEL *cp, IOCBQ *iocbq); */
13382527734SSukumar Swaminathan /* static void emlxs_update_HBQ_index(emlxs_hba_t *hba, */
13482527734SSukumar Swaminathan /* uint32_t hbq_id); */
13582527734SSukumar Swaminathan /* static void emlxs_hbq_free_all(emlxs_hba_t *hba, */
13682527734SSukumar Swaminathan /* uint32_t hbq_id); */
13782527734SSukumar Swaminathan static uint32_t emlxs_hbq_setup(emlxs_hba_t *hba,
13882527734SSukumar Swaminathan uint32_t hbq_id);
1398f23e9faSHans Rosenfeld static void emlxs_sli3_timer(emlxs_hba_t *hba);
1408f23e9faSHans Rosenfeld
1418f23e9faSHans Rosenfeld static void emlxs_sli3_poll_erratt(emlxs_hba_t *hba);
14282527734SSukumar Swaminathan
1438f23e9faSHans Rosenfeld static uint32_t emlxs_sli3_reg_did(emlxs_port_t *port,
1448f23e9faSHans Rosenfeld uint32_t did, SERV_PARM *param,
1458f23e9faSHans Rosenfeld emlxs_buf_t *sbp, fc_unsol_buf_t *ubp,
1468f23e9faSHans Rosenfeld IOCBQ *iocbq);
1478f23e9faSHans Rosenfeld
1488f23e9faSHans Rosenfeld static uint32_t emlxs_sli3_unreg_node(emlxs_port_t *port,
1498f23e9faSHans Rosenfeld NODELIST *node, emlxs_buf_t *sbp,
1508f23e9faSHans Rosenfeld fc_unsol_buf_t *ubp, IOCBQ *iocbq);
15182527734SSukumar Swaminathan
15282527734SSukumar Swaminathan
15382527734SSukumar Swaminathan /* Define SLI3 API functions */
15482527734SSukumar Swaminathan emlxs_sli_api_t emlxs_sli3_api = {
15582527734SSukumar Swaminathan emlxs_sli3_map_hdw,
15682527734SSukumar Swaminathan emlxs_sli3_unmap_hdw,
15782527734SSukumar Swaminathan emlxs_sli3_online,
15882527734SSukumar Swaminathan emlxs_sli3_offline,
15982527734SSukumar Swaminathan emlxs_sli3_hba_reset,
16082527734SSukumar Swaminathan emlxs_sli3_hba_kill,
16182527734SSukumar Swaminathan emlxs_sli3_issue_iocb_cmd,
16282527734SSukumar Swaminathan emlxs_sli3_issue_mbox_cmd,
16382527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
16482527734SSukumar Swaminathan emlxs_sli3_prep_fct_iocb,
16582527734SSukumar Swaminathan #else
16682527734SSukumar Swaminathan NULL,
16782527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
16882527734SSukumar Swaminathan emlxs_sli3_prep_fcp_iocb,
16982527734SSukumar Swaminathan emlxs_sli3_prep_ip_iocb,
17082527734SSukumar Swaminathan emlxs_sli3_prep_els_iocb,
17182527734SSukumar Swaminathan emlxs_sli3_prep_ct_iocb,
17282527734SSukumar Swaminathan emlxs_sli3_poll_intr,
17382527734SSukumar Swaminathan emlxs_sli3_intx_intr,
17482527734SSukumar Swaminathan emlxs_sli3_msi_intr,
17582527734SSukumar Swaminathan emlxs_sli3_disable_intr,
17682527734SSukumar Swaminathan emlxs_sli3_timer,
1778f23e9faSHans Rosenfeld emlxs_sli3_poll_erratt,
1788f23e9faSHans Rosenfeld emlxs_sli3_reg_did,
1798f23e9faSHans Rosenfeld emlxs_sli3_unreg_node
18082527734SSukumar Swaminathan };
181291a2b48SSukumar Swaminathan
182291a2b48SSukumar Swaminathan
18382527734SSukumar Swaminathan /*
18482527734SSukumar Swaminathan * emlxs_sli3_online()
18582527734SSukumar Swaminathan *
18682527734SSukumar Swaminathan * This routine will start initialization of the SLI2/3 HBA.
18782527734SSukumar Swaminathan */
18882527734SSukumar Swaminathan static int32_t
emlxs_sli3_online(emlxs_hba_t * hba)18982527734SSukumar Swaminathan emlxs_sli3_online(emlxs_hba_t *hba)
19082527734SSukumar Swaminathan {
19182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT;
19282527734SSukumar Swaminathan emlxs_config_t *cfg;
19382527734SSukumar Swaminathan emlxs_vpd_t *vpd;
19482527734SSukumar Swaminathan MAILBOX *mb = NULL;
19582527734SSukumar Swaminathan MAILBOXQ *mbq = NULL;
19682527734SSukumar Swaminathan RING *rp;
19782527734SSukumar Swaminathan CHANNEL *cp;
19882527734SSukumar Swaminathan MATCHMAP *mp = NULL;
19982527734SSukumar Swaminathan MATCHMAP *mp1 = NULL;
20082527734SSukumar Swaminathan uint8_t *inptr;
20182527734SSukumar Swaminathan uint8_t *outptr;
20282527734SSukumar Swaminathan uint32_t status;
203a9800bebSGarrett D'Amore uint16_t i;
20482527734SSukumar Swaminathan uint32_t j;
20582527734SSukumar Swaminathan uint32_t read_rev_reset;
20682527734SSukumar Swaminathan uint32_t key = 0;
20782527734SSukumar Swaminathan uint32_t fw_check;
2086a573d82SSukumar Swaminathan uint32_t kern_update = 0;
20982527734SSukumar Swaminathan uint32_t rval = 0;
21082527734SSukumar Swaminathan uint32_t offset;
21182527734SSukumar Swaminathan uint8_t vpd_data[DMP_VPD_SIZE];
21282527734SSukumar Swaminathan uint32_t MaxRbusSize;
21382527734SSukumar Swaminathan uint32_t MaxIbusSize;
21482527734SSukumar Swaminathan uint32_t sli_mode;
21582527734SSukumar Swaminathan uint32_t sli_mode_mask;
216291a2b48SSukumar Swaminathan
21782527734SSukumar Swaminathan cfg = &CFG;
21882527734SSukumar Swaminathan vpd = &VPD;
21982527734SSukumar Swaminathan MaxRbusSize = 0;
22082527734SSukumar Swaminathan MaxIbusSize = 0;
22182527734SSukumar Swaminathan read_rev_reset = 0;
22282527734SSukumar Swaminathan hba->chan_count = MAX_RINGS;
223291a2b48SSukumar Swaminathan
22482527734SSukumar Swaminathan if (hba->bus_type == SBUS_FC) {
22582527734SSukumar Swaminathan (void) READ_SBUS_CSR_REG(hba, FC_SHS_REG(hba));
22682527734SSukumar Swaminathan }
227291a2b48SSukumar Swaminathan
228a9800bebSGarrett D'Amore /* Set the fw_check flag */
229a9800bebSGarrett D'Amore fw_check = cfg[CFG_FW_CHECK].current;
2306a573d82SSukumar Swaminathan
231a9800bebSGarrett D'Amore if ((fw_check & 0x04) ||
232a9800bebSGarrett D'Amore (hba->fw_flag & FW_UPDATE_KERNEL)) {
233a9800bebSGarrett D'Amore kern_update = 1;
234a9800bebSGarrett D'Amore }
2356a573d82SSukumar Swaminathan
2366a573d82SSukumar Swaminathan hba->mbox_queue_flag = 0;
2376a573d82SSukumar Swaminathan hba->sli.sli3.hc_copy = 0;
2386a573d82SSukumar Swaminathan hba->fc_edtov = FF_DEF_EDTOV;
2396a573d82SSukumar Swaminathan hba->fc_ratov = FF_DEF_RATOV;
2406a573d82SSukumar Swaminathan hba->fc_altov = FF_DEF_ALTOV;
2416a573d82SSukumar Swaminathan hba->fc_arbtov = FF_DEF_ARBTOV;
2426a573d82SSukumar Swaminathan
243a9800bebSGarrett D'Amore /*
244a9800bebSGarrett D'Amore * Get a buffer which will be used repeatedly for mailbox commands
245a9800bebSGarrett D'Amore */
246a9800bebSGarrett D'Amore mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP);
2476a573d82SSukumar Swaminathan
248a9800bebSGarrett D'Amore mb = (MAILBOX *)mbq;
2496a573d82SSukumar Swaminathan
25082527734SSukumar Swaminathan /* Initialize sli mode based on configuration parameter */
25182527734SSukumar Swaminathan switch (cfg[CFG_SLI_MODE].current) {
25282527734SSukumar Swaminathan case 2: /* SLI2 mode */
25382527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI2_MODE;
25482527734SSukumar Swaminathan sli_mode_mask = EMLXS_SLI2_MASK;
25582527734SSukumar Swaminathan break;
256291a2b48SSukumar Swaminathan
25782527734SSukumar Swaminathan case 3: /* SLI3 mode */
25882527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI3_MODE;
25982527734SSukumar Swaminathan sli_mode_mask = EMLXS_SLI3_MASK;
26082527734SSukumar Swaminathan break;
261291a2b48SSukumar Swaminathan
26282527734SSukumar Swaminathan case 0: /* Best available */
26382527734SSukumar Swaminathan case 1: /* Best available */
26482527734SSukumar Swaminathan default:
26582527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI3_MASK) {
26682527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI3_MODE;
26782527734SSukumar Swaminathan sli_mode_mask = EMLXS_SLI3_MASK;
26882527734SSukumar Swaminathan } else if (hba->model_info.sli_mask & EMLXS_SLI2_MASK) {
26982527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI2_MODE;
27082527734SSukumar Swaminathan sli_mode_mask = EMLXS_SLI2_MASK;
2718f23e9faSHans Rosenfeld } else {
2728f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
2738f23e9faSHans Rosenfeld "No SLI mode available.");
2748f23e9faSHans Rosenfeld rval = EIO;
2758f23e9faSHans Rosenfeld goto failed;
27682527734SSukumar Swaminathan }
2778f23e9faSHans Rosenfeld break;
27882527734SSukumar Swaminathan }
27982527734SSukumar Swaminathan /* SBUS adapters only available in SLI2 */
28082527734SSukumar Swaminathan if (hba->bus_type == SBUS_FC) {
28182527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI2_MODE;
28282527734SSukumar Swaminathan sli_mode_mask = EMLXS_SLI2_MASK;
283291a2b48SSukumar Swaminathan }
284291a2b48SSukumar Swaminathan
2858f23e9faSHans Rosenfeld reset:
28682527734SSukumar Swaminathan /* Reset & Initialize the adapter */
28782527734SSukumar Swaminathan if (emlxs_sli3_hba_init(hba)) {
28882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
28982527734SSukumar Swaminathan "Unable to init hba.");
290291a2b48SSukumar Swaminathan
29182527734SSukumar Swaminathan rval = EIO;
29282527734SSukumar Swaminathan goto failed;
29382527734SSukumar Swaminathan }
294291a2b48SSukumar Swaminathan
29582527734SSukumar Swaminathan #ifdef FMA_SUPPORT
29682527734SSukumar Swaminathan /* Access handle validation */
29782527734SSukumar Swaminathan if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle)
29882527734SSukumar Swaminathan != DDI_FM_OK) ||
29982527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
30082527734SSukumar Swaminathan != DDI_FM_OK) ||
30182527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.csr_acc_handle)
30282527734SSukumar Swaminathan != DDI_FM_OK)) {
30382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT,
30482527734SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL);
30582527734SSukumar Swaminathan
30682527734SSukumar Swaminathan rval = EIO;
30782527734SSukumar Swaminathan goto failed;
308291a2b48SSukumar Swaminathan }
30982527734SSukumar Swaminathan #endif /* FMA_SUPPORT */
310291a2b48SSukumar Swaminathan
3118f23e9faSHans Rosenfeld /* Check for PEGASUS (This is a special case) */
31282527734SSukumar Swaminathan /* We need to check for dual channel adapter */
313*a3170057SPaul Winder if (hba->model_info.vendor_id == PCI_VENDOR_ID_EMULEX &&
314*a3170057SPaul Winder hba->model_info.device_id == PCI_DEVICE_ID_PEGASUS) {
31582527734SSukumar Swaminathan /* Try to determine if this is a DC adapter */
31682527734SSukumar Swaminathan if (emlxs_get_max_sram(hba, &MaxRbusSize, &MaxIbusSize) == 0) {
31782527734SSukumar Swaminathan if (MaxRbusSize == REDUCED_SRAM_CFG) {
31882527734SSukumar Swaminathan /* LP9802DC */
31982527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) {
32082527734SSukumar Swaminathan if (emlxs_pci_model[i].id == LP9802DC) {
32182527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i],
32282527734SSukumar Swaminathan &hba->model_info,
32382527734SSukumar Swaminathan sizeof (emlxs_model_t));
32482527734SSukumar Swaminathan break;
32582527734SSukumar Swaminathan }
32682527734SSukumar Swaminathan }
32782527734SSukumar Swaminathan } else if (hba->model_info.id != LP9802) {
32882527734SSukumar Swaminathan /* LP9802 */
32982527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) {
33082527734SSukumar Swaminathan if (emlxs_pci_model[i].id == LP9802) {
33182527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i],
33282527734SSukumar Swaminathan &hba->model_info,
33382527734SSukumar Swaminathan sizeof (emlxs_model_t));
33482527734SSukumar Swaminathan break;
33582527734SSukumar Swaminathan }
33682527734SSukumar Swaminathan }
33782527734SSukumar Swaminathan }
33882527734SSukumar Swaminathan }
33982527734SSukumar Swaminathan }
340291a2b48SSukumar Swaminathan
341291a2b48SSukumar Swaminathan /*
34282527734SSukumar Swaminathan * Setup and issue mailbox READ REV command
343291a2b48SSukumar Swaminathan */
34482527734SSukumar Swaminathan vpd->opFwRev = 0;
34582527734SSukumar Swaminathan vpd->postKernRev = 0;
34682527734SSukumar Swaminathan vpd->sli1FwRev = 0;
34782527734SSukumar Swaminathan vpd->sli2FwRev = 0;
34882527734SSukumar Swaminathan vpd->sli3FwRev = 0;
34982527734SSukumar Swaminathan vpd->sli4FwRev = 0;
35082527734SSukumar Swaminathan
35182527734SSukumar Swaminathan vpd->postKernName[0] = 0;
35282527734SSukumar Swaminathan vpd->opFwName[0] = 0;
35382527734SSukumar Swaminathan vpd->sli1FwName[0] = 0;
35482527734SSukumar Swaminathan vpd->sli2FwName[0] = 0;
35582527734SSukumar Swaminathan vpd->sli3FwName[0] = 0;
35682527734SSukumar Swaminathan vpd->sli4FwName[0] = 0;
35782527734SSukumar Swaminathan
35882527734SSukumar Swaminathan vpd->opFwLabel[0] = 0;
35982527734SSukumar Swaminathan vpd->sli1FwLabel[0] = 0;
36082527734SSukumar Swaminathan vpd->sli2FwLabel[0] = 0;
36182527734SSukumar Swaminathan vpd->sli3FwLabel[0] = 0;
36282527734SSukumar Swaminathan vpd->sli4FwLabel[0] = 0;
36382527734SSukumar Swaminathan
36482527734SSukumar Swaminathan /* Sanity check */
36582527734SSukumar Swaminathan if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) {
36682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
36782527734SSukumar Swaminathan "Adapter / SLI mode mismatch mask:x%x",
36882527734SSukumar Swaminathan hba->model_info.sli_mask);
36982527734SSukumar Swaminathan
37082527734SSukumar Swaminathan rval = EIO;
37182527734SSukumar Swaminathan goto failed;
372291a2b48SSukumar Swaminathan }
373291a2b48SSukumar Swaminathan
37482527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_REV);
37582527734SSukumar Swaminathan emlxs_mb_read_rev(hba, mbq, 0);
37682527734SSukumar Swaminathan if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
37782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
37882527734SSukumar Swaminathan "Unable to read rev. Mailbox cmd=%x status=%x",
37982527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus);
380291a2b48SSukumar Swaminathan
38182527734SSukumar Swaminathan rval = EIO;
38282527734SSukumar Swaminathan goto failed;
383291a2b48SSukumar Swaminathan }
384291a2b48SSukumar Swaminathan
38582527734SSukumar Swaminathan if (mb->un.varRdRev.rr == 0) {
38682527734SSukumar Swaminathan /* Old firmware */
38782527734SSukumar Swaminathan if (read_rev_reset == 0) {
38882527734SSukumar Swaminathan read_rev_reset = 1;
389291a2b48SSukumar Swaminathan
39082527734SSukumar Swaminathan goto reset;
39182527734SSukumar Swaminathan } else {
39282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
39382527734SSukumar Swaminathan "Outdated firmware detected.");
39482527734SSukumar Swaminathan }
395291a2b48SSukumar Swaminathan
39682527734SSukumar Swaminathan vpd->rBit = 0;
39782527734SSukumar Swaminathan } else {
39882527734SSukumar Swaminathan if (mb->un.varRdRev.un.b.ProgType != FUNC_FIRMWARE) {
39982527734SSukumar Swaminathan if (read_rev_reset == 0) {
40082527734SSukumar Swaminathan read_rev_reset = 1;
401291a2b48SSukumar Swaminathan
40282527734SSukumar Swaminathan goto reset;
40382527734SSukumar Swaminathan } else {
40482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
40582527734SSukumar Swaminathan "Non-operational firmware detected. "
40682527734SSukumar Swaminathan "type=%x",
40782527734SSukumar Swaminathan mb->un.varRdRev.un.b.ProgType);
40882527734SSukumar Swaminathan }
40982527734SSukumar Swaminathan }
410291a2b48SSukumar Swaminathan
41182527734SSukumar Swaminathan vpd->rBit = 1;
41282527734SSukumar Swaminathan vpd->sli1FwRev = mb->un.varRdRev.sliFwRev1;
41382527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev.sliFwName1, vpd->sli1FwLabel,
41482527734SSukumar Swaminathan 16);
41582527734SSukumar Swaminathan vpd->sli2FwRev = mb->un.varRdRev.sliFwRev2;
41682527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev.sliFwName2, vpd->sli2FwLabel,
41782527734SSukumar Swaminathan 16);
418291a2b48SSukumar Swaminathan
41982527734SSukumar Swaminathan /*
42082527734SSukumar Swaminathan * Lets try to read the SLI3 version
42182527734SSukumar Swaminathan * Setup and issue mailbox READ REV(v3) command
42282527734SSukumar Swaminathan */
42382527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_REV);
424