182527734SSukumar Swaminathan /* 282527734SSukumar Swaminathan * CDDL HEADER START 382527734SSukumar Swaminathan * 482527734SSukumar Swaminathan * The contents of this file are subject to the terms of the 582527734SSukumar Swaminathan * Common Development and Distribution License (the "License"). 682527734SSukumar Swaminathan * You may not use this file except in compliance with the License. 782527734SSukumar Swaminathan * 882527734SSukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 982527734SSukumar Swaminathan * or http://www.opensolaris.org/os/licensing. 1082527734SSukumar Swaminathan * See the License for the specific language governing permissions 1182527734SSukumar Swaminathan * and limitations under the License. 1282527734SSukumar Swaminathan * 1382527734SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each 1482527734SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1582527734SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the 1682527734SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying 1782527734SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner] 1882527734SSukumar Swaminathan * 1982527734SSukumar Swaminathan * CDDL HEADER END 2082527734SSukumar Swaminathan */ 2182527734SSukumar Swaminathan 2282527734SSukumar Swaminathan /* 23bce54adfSSukumar Swaminathan * Copyright 2010 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 2582527734SSukumar Swaminathan */ 2682527734SSukumar Swaminathan 2782527734SSukumar Swaminathan 2882527734SSukumar Swaminathan #include <emlxs.h> 2982527734SSukumar Swaminathan 3082527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 3182527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_SLI4_C); 3282527734SSukumar Swaminathan 3382527734SSukumar Swaminathan static int emlxs_sli4_create_queues(emlxs_hba_t *hba, 3482527734SSukumar Swaminathan MAILBOXQ *mbq); 3582527734SSukumar Swaminathan static int emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, 3682527734SSukumar Swaminathan MAILBOXQ *mbq); 3782527734SSukumar Swaminathan static int emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, 3882527734SSukumar Swaminathan MAILBOXQ *mbq); 3982527734SSukumar Swaminathan 40*a9800bebSGarrett D'Amore static int emlxs_sli4_read_eq(emlxs_hba_t *hba, EQ_DESC_t *eq); 4182527734SSukumar Swaminathan 4282527734SSukumar Swaminathan extern void emlxs_parse_prog_types(emlxs_hba_t *hba, char *types); 4382527734SSukumar Swaminathan 4482527734SSukumar Swaminathan extern int32_t emlxs_parse_vpd(emlxs_hba_t *hba, uint8_t *vpd, 4582527734SSukumar Swaminathan uint32_t size); 4682527734SSukumar Swaminathan extern void emlxs_decode_label(char *label, char *buffer, int bige); 4782527734SSukumar Swaminathan 4882527734SSukumar Swaminathan extern void emlxs_build_prog_types(emlxs_hba_t *hba, 4982527734SSukumar Swaminathan char *prog_types); 5082527734SSukumar Swaminathan 5182527734SSukumar Swaminathan extern int emlxs_pci_model_count; 5282527734SSukumar Swaminathan 5382527734SSukumar Swaminathan extern emlxs_model_t emlxs_pci_model[]; 5482527734SSukumar Swaminathan 5582527734SSukumar Swaminathan static int emlxs_sli4_map_hdw(emlxs_hba_t *hba); 5682527734SSukumar Swaminathan 5782527734SSukumar Swaminathan static void emlxs_sli4_unmap_hdw(emlxs_hba_t *hba); 5882527734SSukumar Swaminathan 5982527734SSukumar Swaminathan static int32_t emlxs_sli4_online(emlxs_hba_t *hba); 6082527734SSukumar Swaminathan 6182527734SSukumar Swaminathan static void emlxs_sli4_offline(emlxs_hba_t *hba); 6282527734SSukumar Swaminathan 6382527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, 6482527734SSukumar Swaminathan uint32_t skip_post, uint32_t quiesce); 6582527734SSukumar Swaminathan static void emlxs_sli4_hba_kill(emlxs_hba_t *hba); 6682527734SSukumar Swaminathan 6782527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_init(emlxs_hba_t *hba); 6882527734SSukumar Swaminathan 6982527734SSukumar Swaminathan static uint32_t emlxs_sli4_bde_setup(emlxs_port_t *port, 7082527734SSukumar Swaminathan emlxs_buf_t *sbp); 71*a9800bebSGarrett D'Amore 72*a9800bebSGarrett D'Amore 7382527734SSukumar Swaminathan static void emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, 74*a9800bebSGarrett D'Amore CHANNEL *cp, IOCBQ *iocb_cmd); 7582527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, 7682527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 7782527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, 7882527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 7982527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 8082527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, 8182527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp, int channel); 8282527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 8382527734SSukumar Swaminathan 8482527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, 8582527734SSukumar Swaminathan emlxs_buf_t *sbp, int ring); 8682527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, 8782527734SSukumar Swaminathan emlxs_buf_t *sbp); 8882527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_els_iocb(emlxs_port_t *port, 8982527734SSukumar Swaminathan emlxs_buf_t *sbp); 9082527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, 9182527734SSukumar Swaminathan emlxs_buf_t *sbp); 9282527734SSukumar Swaminathan static void emlxs_sli4_poll_intr(emlxs_hba_t *hba, 9382527734SSukumar Swaminathan uint32_t att_bit); 9482527734SSukumar Swaminathan static int32_t emlxs_sli4_intx_intr(char *arg); 9582527734SSukumar Swaminathan 9682527734SSukumar Swaminathan #ifdef MSI_SUPPORT 9782527734SSukumar Swaminathan static uint32_t emlxs_sli4_msi_intr(char *arg1, char *arg2); 9882527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 9982527734SSukumar Swaminathan 10082527734SSukumar Swaminathan static void emlxs_sli4_resource_free(emlxs_hba_t *hba); 10182527734SSukumar Swaminathan 10282527734SSukumar Swaminathan static int emlxs_sli4_resource_alloc(emlxs_hba_t *hba); 10382527734SSukumar Swaminathan 10482527734SSukumar Swaminathan static XRIobj_t *emlxs_sli4_alloc_xri(emlxs_hba_t *hba, 105*a9800bebSGarrett D'Amore emlxs_buf_t *sbp, RPIobj_t *rpip); 10682527734SSukumar Swaminathan static void emlxs_sli4_enable_intr(emlxs_hba_t *hba); 10782527734SSukumar Swaminathan 10882527734SSukumar Swaminathan static void emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att); 10982527734SSukumar Swaminathan 11082527734SSukumar Swaminathan extern void emlxs_sli4_timer(emlxs_hba_t *hba); 11182527734SSukumar Swaminathan 11282527734SSukumar Swaminathan static void emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba); 11382527734SSukumar Swaminathan 114*a9800bebSGarrett D'Amore static void emlxs_sli4_poll_erratt(emlxs_hba_t *hba); 11582527734SSukumar Swaminathan 11682527734SSukumar Swaminathan static XRIobj_t *emlxs_sli4_register_xri(emlxs_hba_t *hba, 11782527734SSukumar Swaminathan emlxs_buf_t *sbp, uint16_t xri); 11882527734SSukumar Swaminathan 119*a9800bebSGarrett D'Amore static XRIobj_t *emlxs_sli4_reserve_xri(emlxs_hba_t *hba, 120*a9800bebSGarrett D'Amore RPIobj_t *rpip); 12182527734SSukumar Swaminathan static int emlxs_check_hdw_ready(emlxs_hba_t *); 12282527734SSukumar Swaminathan 123*a9800bebSGarrett D'Amore 12482527734SSukumar Swaminathan /* Define SLI4 API functions */ 12582527734SSukumar Swaminathan emlxs_sli_api_t emlxs_sli4_api = { 12682527734SSukumar Swaminathan emlxs_sli4_map_hdw, 12782527734SSukumar Swaminathan emlxs_sli4_unmap_hdw, 12882527734SSukumar Swaminathan emlxs_sli4_online, 12982527734SSukumar Swaminathan emlxs_sli4_offline, 13082527734SSukumar Swaminathan emlxs_sli4_hba_reset, 13182527734SSukumar Swaminathan emlxs_sli4_hba_kill, 13282527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd, 13382527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd, 13482527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 13582527734SSukumar Swaminathan emlxs_sli4_prep_fct_iocb, 13682527734SSukumar Swaminathan #else 13782527734SSukumar Swaminathan NULL, 13882527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 13982527734SSukumar Swaminathan emlxs_sli4_prep_fcp_iocb, 14082527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb, 14182527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb, 14282527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb, 14382527734SSukumar Swaminathan emlxs_sli4_poll_intr, 14482527734SSukumar Swaminathan emlxs_sli4_intx_intr, 14582527734SSukumar Swaminathan emlxs_sli4_msi_intr, 14682527734SSukumar Swaminathan emlxs_sli4_disable_intr, 14782527734SSukumar Swaminathan emlxs_sli4_timer, 14882527734SSukumar Swaminathan emlxs_sli4_poll_erratt 14982527734SSukumar Swaminathan }; 15082527734SSukumar Swaminathan 15182527734SSukumar Swaminathan 15282527734SSukumar Swaminathan /* ************************************************************************** */ 15382527734SSukumar Swaminathan 15482527734SSukumar Swaminathan 15582527734SSukumar Swaminathan /* 15682527734SSukumar Swaminathan * emlxs_sli4_online() 15782527734SSukumar Swaminathan * 15882527734SSukumar Swaminathan * This routine will start initialization of the SLI4 HBA. 15982527734SSukumar Swaminathan */ 16082527734SSukumar Swaminathan static int32_t 16182527734SSukumar Swaminathan emlxs_sli4_online(emlxs_hba_t *hba) 16282527734SSukumar Swaminathan { 16382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 16482527734SSukumar Swaminathan emlxs_config_t *cfg; 16582527734SSukumar Swaminathan emlxs_vpd_t *vpd; 16682527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 16782527734SSukumar Swaminathan MAILBOX4 *mb = NULL; 16882527734SSukumar Swaminathan MATCHMAP *mp = NULL; 16982527734SSukumar Swaminathan uint32_t i; 17082527734SSukumar Swaminathan uint32_t j; 17182527734SSukumar Swaminathan uint32_t rval = 0; 17282527734SSukumar Swaminathan uint8_t *vpd_data; 17382527734SSukumar Swaminathan uint32_t sli_mode; 17482527734SSukumar Swaminathan uint8_t *outptr; 17582527734SSukumar Swaminathan uint32_t status; 17682527734SSukumar Swaminathan uint32_t fw_check; 1776a573d82SSukumar Swaminathan uint32_t kern_update = 0; 17882527734SSukumar Swaminathan emlxs_firmware_t hba_fw; 17982527734SSukumar Swaminathan emlxs_firmware_t *fw; 180*a9800bebSGarrett D'Amore uint16_t ssvid; 18182527734SSukumar Swaminathan 18282527734SSukumar Swaminathan cfg = &CFG; 18382527734SSukumar Swaminathan vpd = &VPD; 18482527734SSukumar Swaminathan 18582527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI4_MODE; 18682527734SSukumar Swaminathan hba->sli_mode = sli_mode; 18782527734SSukumar Swaminathan 18882527734SSukumar Swaminathan /* Set the fw_check flag */ 18982527734SSukumar Swaminathan fw_check = cfg[CFG_FW_CHECK].current; 19082527734SSukumar Swaminathan 1916a573d82SSukumar Swaminathan if ((fw_check & 0x04) || 1926a573d82SSukumar Swaminathan (hba->fw_flag & FW_UPDATE_KERNEL)) { 1936a573d82SSukumar Swaminathan kern_update = 1; 1946a573d82SSukumar Swaminathan } 1956a573d82SSukumar Swaminathan 19682527734SSukumar Swaminathan hba->mbox_queue_flag = 0; 19782527734SSukumar Swaminathan hba->fc_edtov = FF_DEF_EDTOV; 19882527734SSukumar Swaminathan hba->fc_ratov = FF_DEF_RATOV; 19982527734SSukumar Swaminathan hba->fc_altov = FF_DEF_ALTOV; 20082527734SSukumar Swaminathan hba->fc_arbtov = FF_DEF_ARBTOV; 20182527734SSukumar Swaminathan 20282527734SSukumar Swaminathan /* Target mode not supported */ 20382527734SSukumar Swaminathan if (hba->tgt_mode) { 20482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 20582527734SSukumar Swaminathan "Target mode not supported in SLI4."); 20682527734SSukumar Swaminathan 20782527734SSukumar Swaminathan return (ENOMEM); 20882527734SSukumar Swaminathan } 20982527734SSukumar Swaminathan 21082527734SSukumar Swaminathan /* Networking not supported */ 21182527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current) { 21282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 21382527734SSukumar Swaminathan "Networking not supported in SLI4, turning it off"); 21482527734SSukumar Swaminathan cfg[CFG_NETWORK_ON].current = 0; 21582527734SSukumar Swaminathan } 21682527734SSukumar Swaminathan 21782527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 21882527734SSukumar Swaminathan if (hba->chan_count > MAX_CHANNEL) { 21982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 22082527734SSukumar Swaminathan "Max channels exceeded, dropping num-wq from %d to 1", 22182527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current); 22282527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current = 1; 22382527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 22482527734SSukumar Swaminathan } 22582527734SSukumar Swaminathan hba->channel_fcp = 0; /* First channel */ 22682527734SSukumar Swaminathan 22782527734SSukumar Swaminathan /* Default channel for everything else is the last channel */ 22882527734SSukumar Swaminathan hba->channel_ip = hba->chan_count - 1; 22982527734SSukumar Swaminathan hba->channel_els = hba->chan_count - 1; 23082527734SSukumar Swaminathan hba->channel_ct = hba->chan_count - 1; 23182527734SSukumar Swaminathan 23282527734SSukumar Swaminathan hba->fc_iotag = 1; 23382527734SSukumar Swaminathan hba->io_count = 0; 23482527734SSukumar Swaminathan hba->channel_tx_count = 0; 23582527734SSukumar Swaminathan 23682527734SSukumar Swaminathan /* Initialize the local dump region buffer */ 23782527734SSukumar Swaminathan bzero(&hba->sli.sli4.dump_region, sizeof (MBUF_INFO)); 23882527734SSukumar Swaminathan hba->sli.sli4.dump_region.size = EMLXS_DUMP_REGION_SIZE; 23982527734SSukumar Swaminathan hba->sli.sli4.dump_region.flags = FC_MBUF_DMA | FC_MBUF_SNGLSG 24082527734SSukumar Swaminathan | FC_MBUF_DMA32; 24182527734SSukumar Swaminathan hba->sli.sli4.dump_region.align = ddi_ptob(hba->dip, 1L); 24282527734SSukumar Swaminathan 24382527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, &hba->sli.sli4.dump_region); 24482527734SSukumar Swaminathan 24582527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt == NULL) { 24682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 24782527734SSukumar Swaminathan "Unable to allocate dump region buffer."); 24882527734SSukumar Swaminathan 24982527734SSukumar Swaminathan return (ENOMEM); 25082527734SSukumar Swaminathan } 25182527734SSukumar Swaminathan 25282527734SSukumar Swaminathan /* 25382527734SSukumar Swaminathan * Get a buffer which will be used repeatedly for mailbox commands 25482527734SSukumar Swaminathan */ 25582527734SSukumar Swaminathan mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP); 25682527734SSukumar Swaminathan 25782527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 25882527734SSukumar Swaminathan 25982527734SSukumar Swaminathan reset: 26082527734SSukumar Swaminathan /* Reset & Initialize the adapter */ 26182527734SSukumar Swaminathan if (emlxs_sli4_hba_init(hba)) { 26282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 26382527734SSukumar Swaminathan "Unable to init hba."); 26482527734SSukumar Swaminathan 26582527734SSukumar Swaminathan rval = EIO; 26682527734SSukumar Swaminathan goto failed1; 26782527734SSukumar Swaminathan } 26882527734SSukumar Swaminathan 26982527734SSukumar Swaminathan #ifdef FMA_SUPPORT 27082527734SSukumar Swaminathan /* Access handle validation */ 27182527734SSukumar Swaminathan if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 27282527734SSukumar Swaminathan != DDI_FM_OK) || 27382527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli4.bar1_acc_handle) 27482527734SSukumar Swaminathan != DDI_FM_OK) || 27582527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli4.bar2_acc_handle) 27682527734SSukumar Swaminathan != DDI_FM_OK)) { 27782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 27882527734SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 27982527734SSukumar Swaminathan 28082527734SSukumar Swaminathan rval = EIO; 28182527734SSukumar Swaminathan goto failed1; 28282527734SSukumar Swaminathan } 28382527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 28482527734SSukumar Swaminathan 28582527734SSukumar Swaminathan /* 28682527734SSukumar Swaminathan * Setup and issue mailbox READ REV command 28782527734SSukumar Swaminathan */ 28882527734SSukumar Swaminathan vpd->opFwRev = 0; 28982527734SSukumar Swaminathan vpd->postKernRev = 0; 29082527734SSukumar Swaminathan vpd->sli1FwRev = 0; 29182527734SSukumar Swaminathan vpd->sli2FwRev = 0; 29282527734SSukumar Swaminathan vpd->sli3FwRev = 0; 29382527734SSukumar Swaminathan vpd->sli4FwRev = 0; 29482527734SSukumar Swaminathan 29582527734SSukumar Swaminathan vpd->postKernName[0] = 0; 29682527734SSukumar Swaminathan vpd->opFwName[0] = 0; 29782527734SSukumar Swaminathan vpd->sli1FwName[0] = 0; 29882527734SSukumar Swaminathan vpd->sli2FwName[0] = 0; 29982527734SSukumar Swaminathan vpd->sli3FwName[0] = 0; 30082527734SSukumar Swaminathan vpd->sli4FwName[0] = 0; 30182527734SSukumar Swaminathan 30282527734SSukumar Swaminathan vpd->opFwLabel[0] = 0; 30382527734SSukumar Swaminathan vpd->sli1FwLabel[0] = 0; 30482527734SSukumar Swaminathan vpd->sli2FwLabel[0] = 0; 30582527734SSukumar Swaminathan vpd->sli3FwLabel[0] = 0; 30682527734SSukumar Swaminathan vpd->sli4FwLabel[0] = 0; 30782527734SSukumar Swaminathan 30882527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_REV); 30982527734SSukumar Swaminathan 31082527734SSukumar Swaminathan emlxs_mb_read_rev(hba, mbq, 0); 31182527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 31282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 31382527734SSukumar Swaminathan "Unable to read rev. Mailbox cmd=%x status=%x", 31482527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 31582527734SSukumar Swaminathan 31682527734SSukumar Swaminathan rval = EIO; 31782527734SSukumar Swaminathan goto failed1; 31882527734SSukumar Swaminathan 31982527734SSukumar Swaminathan } 32082527734SSukumar Swaminathan 321*a9800bebSGarrett D'Amore emlxs_data_dump(port, "RD_REV", (uint32_t *)mb, 18, 0); 32282527734SSukumar Swaminathan if (mb->un.varRdRev4.sliLevel != 4) { 32382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 32482527734SSukumar Swaminathan "Invalid read rev Version for SLI4: 0x%x", 32582527734SSukumar Swaminathan mb->un.varRdRev4.sliLevel); 32682527734SSukumar Swaminathan 32782527734SSukumar Swaminathan rval = EIO; 32882527734SSukumar Swaminathan goto failed1; 32982527734SSukumar Swaminathan } 33082527734SSukumar Swaminathan 33182527734SSukumar Swaminathan switch (mb->un.varRdRev4.dcbxMode) { 33282527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CIN: /* Mapped to nonFIP mode */ 33382527734SSukumar Swaminathan hba->flag &= ~FC_FIP_SUPPORTED; 33482527734SSukumar Swaminathan break; 33582527734SSukumar Swaminathan 33682527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CEE: /* Mapped to FIP mode */ 33782527734SSukumar Swaminathan hba->flag |= FC_FIP_SUPPORTED; 33882527734SSukumar Swaminathan break; 33982527734SSukumar Swaminathan 34082527734SSukumar Swaminathan default: 34182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 34282527734SSukumar Swaminathan "Invalid read rev dcbx mode for SLI4: 0x%x", 34382527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 34482527734SSukumar Swaminathan 34582527734SSukumar Swaminathan rval = EIO; 34682527734SSukumar Swaminathan goto failed1; 34782527734SSukumar Swaminathan } 34882527734SSukumar Swaminathan 34982527734SSukumar Swaminathan 35082527734SSukumar Swaminathan /* Save information as VPD data */ 35182527734SSukumar Swaminathan vpd->rBit = 1; 35282527734SSukumar Swaminathan 35382527734SSukumar Swaminathan vpd->sli4FwRev = (mb->un.varRdRev4.ULPFwId); 35482527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->sli4FwName, 16); 35582527734SSukumar Swaminathan 35682527734SSukumar Swaminathan vpd->opFwRev = (mb->un.varRdRev4.ULPFwId); 35782527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->opFwName, 16); 35882527734SSukumar Swaminathan 35982527734SSukumar Swaminathan vpd->postKernRev = (mb->un.varRdRev4.ARMFwId); 36082527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ARMFwName, vpd->postKernName, 16); 36182527734SSukumar Swaminathan 36282527734SSukumar Swaminathan vpd->fcphHigh = mb->un.varRdRev4.fcphHigh; 36382527734SSukumar Swaminathan vpd->fcphLow = mb->un.varRdRev4.fcphLow; 36482527734SSukumar Swaminathan vpd->feaLevelHigh = mb->un.varRdRev4.feaLevelHigh; 36582527734SSukumar Swaminathan vpd->feaLevelLow = mb->un.varRdRev4.feaLevelLow; 36682527734SSukumar Swaminathan 36782527734SSukumar Swaminathan /* Decode FW labels */ 36882527734SSukumar Swaminathan emlxs_decode_label(vpd->sli4FwName, vpd->sli4FwName, 0); 36982527734SSukumar Swaminathan emlxs_decode_label(vpd->opFwName, vpd->opFwName, 0); 37082527734SSukumar Swaminathan emlxs_decode_label(vpd->postKernName, vpd->postKernName, 0); 37182527734SSukumar Swaminathan 372*a9800bebSGarrett D'Amore if (hba->model_info.chip == EMLXS_BE2_CHIP) { 37382527734SSukumar Swaminathan (void) strcpy(vpd->sli4FwLabel, "be2.ufi"); 374*a9800bebSGarrett D'Amore } else if (hba->model_info.chip == EMLXS_BE3_CHIP) { 375*a9800bebSGarrett D'Amore (void) strcpy(vpd->sli4FwLabel, "be3.ufi"); 37682527734SSukumar Swaminathan } else { 37782527734SSukumar Swaminathan (void) strcpy(vpd->sli4FwLabel, "sli4.fw"); 37882527734SSukumar Swaminathan } 37982527734SSukumar Swaminathan 38082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 38182527734SSukumar Swaminathan "VPD ULP:%08x %s ARM:%08x %s f:%d %d %d %d : dcbx %d", 38282527734SSukumar Swaminathan vpd->opFwRev, vpd->opFwName, vpd->postKernRev, vpd->postKernName, 38382527734SSukumar Swaminathan vpd->fcphHigh, vpd->fcphLow, vpd->feaLevelHigh, vpd->feaLevelLow, 38482527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 38582527734SSukumar Swaminathan 38682527734SSukumar Swaminathan /* No key information is needed for SLI4 products */ 38782527734SSukumar Swaminathan 38882527734SSukumar Swaminathan /* Get adapter VPD information */ 38982527734SSukumar Swaminathan vpd->port_index = (uint32_t)-1; 39082527734SSukumar Swaminathan 39182527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 39282527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 39382527734SSukumar Swaminathan 39482527734SSukumar Swaminathan emlxs_mb_dump_vpd(hba, mbq, 0); 39582527734SSukumar Swaminathan vpd_data = hba->sli.sli4.dump_region.virt; 39682527734SSukumar Swaminathan 39782527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 39882527734SSukumar Swaminathan MBX_SUCCESS) { 39982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 40082527734SSukumar Swaminathan "No VPD found. status=%x", mb->mbxStatus); 40182527734SSukumar Swaminathan } else { 40282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 40382527734SSukumar Swaminathan &emlxs_init_debug_msg, 40482527734SSukumar Swaminathan "VPD dumped. rsp_cnt=%d status=%x", 40582527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 40682527734SSukumar Swaminathan 40782527734SSukumar Swaminathan if (mb->un.varDmp4.rsp_cnt) { 40882527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 40982527734SSukumar Swaminathan 0, mb->un.varDmp4.rsp_cnt, DDI_DMA_SYNC_FORKERNEL); 41082527734SSukumar Swaminathan 411b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 412b3660a96SSukumar Swaminathan if (hba->sli.sli4.dump_region.dma_handle) { 413b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 414b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle) 415b3660a96SSukumar Swaminathan != DDI_FM_OK) { 416b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 417b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 418b3660a96SSukumar Swaminathan "emlxs_sli4_online: hdl=%p", 419b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region. 420b3660a96SSukumar Swaminathan dma_handle); 421b3660a96SSukumar Swaminathan rval = EIO; 422b3660a96SSukumar Swaminathan goto failed1; 423b3660a96SSukumar Swaminathan } 424b3660a96SSukumar Swaminathan } 425b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 426b3660a96SSukumar Swaminathan 42782527734SSukumar Swaminathan } 42882527734SSukumar Swaminathan } 42982527734SSukumar Swaminathan 43082527734SSukumar Swaminathan if (vpd_data[0]) { 43182527734SSukumar Swaminathan (void) emlxs_parse_vpd(hba, (uint8_t *)vpd_data, 43282527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt); 43382527734SSukumar Swaminathan 43482527734SSukumar Swaminathan /* 43582527734SSukumar Swaminathan * If there is a VPD part number, and it does not 43682527734SSukumar Swaminathan * match the current default HBA model info, 43782527734SSukumar Swaminathan * replace the default data with an entry that 43882527734SSukumar Swaminathan * does match. 43982527734SSukumar Swaminathan * 44082527734SSukumar Swaminathan * After emlxs_parse_vpd model holds the VPD value 44182527734SSukumar Swaminathan * for V2 and part_num hold the value for PN. These 44282527734SSukumar Swaminathan * 2 values are NOT necessarily the same. 44382527734SSukumar Swaminathan */ 44482527734SSukumar Swaminathan 44582527734SSukumar Swaminathan rval = 0; 44682527734SSukumar Swaminathan if ((vpd->model[0] != 0) && 44782527734SSukumar Swaminathan (strcmp(&vpd->model[0], hba->model_info.model) != 0)) { 44882527734SSukumar Swaminathan 44982527734SSukumar Swaminathan /* First scan for a V2 match */ 45082527734SSukumar Swaminathan 45182527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 45282527734SSukumar Swaminathan if (strcmp(&vpd->model[0], 45382527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 45482527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 45582527734SSukumar Swaminathan &hba->model_info, 45682527734SSukumar Swaminathan sizeof (emlxs_model_t)); 45782527734SSukumar Swaminathan rval = 1; 45882527734SSukumar Swaminathan break; 45982527734SSukumar Swaminathan } 46082527734SSukumar Swaminathan } 46182527734SSukumar Swaminathan } 46282527734SSukumar Swaminathan 46382527734SSukumar Swaminathan if (!rval && (vpd->part_num[0] != 0) && 46482527734SSukumar Swaminathan (strcmp(&vpd->part_num[0], hba->model_info.model) != 0)) { 46582527734SSukumar Swaminathan 46682527734SSukumar Swaminathan /* Next scan for a PN match */ 46782527734SSukumar Swaminathan 46882527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 46982527734SSukumar Swaminathan if (strcmp(&vpd->part_num[0], 47082527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 47182527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 47282527734SSukumar Swaminathan &hba->model_info, 47382527734SSukumar Swaminathan sizeof (emlxs_model_t)); 47482527734SSukumar Swaminathan break; 47582527734SSukumar Swaminathan } 47682527734SSukumar Swaminathan } 47782527734SSukumar Swaminathan } 47882527734SSukumar Swaminathan 479*a9800bebSGarrett D'Amore /* HP CNA port indices start at 1 instead of 0 */ 480*a9800bebSGarrett D'Amore if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 481*a9800bebSGarrett D'Amore (hba->model_info.chip == EMLXS_BE3_CHIP)) { 482*a9800bebSGarrett D'Amore 483*a9800bebSGarrett D'Amore ssvid = ddi_get16(hba->pci_acc_handle, 484*a9800bebSGarrett D'Amore (uint16_t *)(hba->pci_addr + PCI_SSVID_REGISTER)); 485*a9800bebSGarrett D'Amore 486*a9800bebSGarrett D'Amore if ((ssvid == PCI_SSVID_HP) && (vpd->port_index > 0)) { 487*a9800bebSGarrett D'Amore vpd->port_index--; 488*a9800bebSGarrett D'Amore } 489*a9800bebSGarrett D'Amore } 490*a9800bebSGarrett D'Amore 49182527734SSukumar Swaminathan /* 49282527734SSukumar Swaminathan * Now lets update hba->model_info with the real 49382527734SSukumar Swaminathan * VPD data, if any. 49482527734SSukumar Swaminathan */ 49582527734SSukumar Swaminathan 49682527734SSukumar Swaminathan /* 49782527734SSukumar Swaminathan * Replace the default model description with vpd data 49882527734SSukumar Swaminathan */ 49982527734SSukumar Swaminathan if (vpd->model_desc[0] != 0) { 50082527734SSukumar Swaminathan (void) strcpy(hba->model_info.model_desc, 50182527734SSukumar Swaminathan vpd->model_desc); 50282527734SSukumar Swaminathan } 50382527734SSukumar Swaminathan 50482527734SSukumar Swaminathan /* Replace the default model with vpd data */ 50582527734SSukumar Swaminathan if (vpd->model[0] != 0) { 50682527734SSukumar Swaminathan (void) strcpy(hba->model_info.model, vpd->model); 50782527734SSukumar Swaminathan } 50882527734SSukumar Swaminathan 50982527734SSukumar Swaminathan /* Replace the default program types with vpd data */ 51082527734SSukumar Swaminathan if (vpd->prog_types[0] != 0) { 51182527734SSukumar Swaminathan emlxs_parse_prog_types(hba, vpd->prog_types); 51282527734SSukumar Swaminathan } 51382527734SSukumar Swaminathan } 51482527734SSukumar Swaminathan 51582527734SSukumar Swaminathan /* 51682527734SSukumar Swaminathan * Since the adapter model may have changed with the vpd data 51782527734SSukumar Swaminathan * lets double check if adapter is not supported 51882527734SSukumar Swaminathan */ 51982527734SSukumar Swaminathan if (hba->model_info.flags & EMLXS_NOT_SUPPORTED) { 52082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 52182527734SSukumar Swaminathan "Unsupported adapter found. " 52282527734SSukumar Swaminathan "Id:%d Device id:0x%x SSDID:0x%x Model:%s", 52382527734SSukumar Swaminathan hba->model_info.id, hba->model_info.device_id, 52482527734SSukumar Swaminathan hba->model_info.ssdid, hba->model_info.model); 52582527734SSukumar Swaminathan 52682527734SSukumar Swaminathan rval = EIO; 52782527734SSukumar Swaminathan goto failed1; 52882527734SSukumar Swaminathan } 52982527734SSukumar Swaminathan 53082527734SSukumar Swaminathan (void) strcpy(vpd->boot_version, vpd->sli4FwName); 53182527734SSukumar Swaminathan 53282527734SSukumar Swaminathan /* Get fcode version property */ 53382527734SSukumar Swaminathan emlxs_get_fcode_version(hba); 53482527734SSukumar Swaminathan 53582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 53682527734SSukumar Swaminathan "Firmware: kern=%08x stub=%08x sli1=%08x", vpd->postKernRev, 53782527734SSukumar Swaminathan vpd->opFwRev, vpd->sli1FwRev); 53882527734SSukumar Swaminathan 53982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 54082527734SSukumar Swaminathan "Firmware: sli2=%08x sli3=%08x sli4=%08x fl=%x", vpd->sli2FwRev, 54182527734SSukumar Swaminathan vpd->sli3FwRev, vpd->sli4FwRev, vpd->feaLevelHigh); 54282527734SSukumar Swaminathan 54382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 54482527734SSukumar Swaminathan "BIOS: boot=%s fcode=%s", vpd->boot_version, vpd->fcode_version); 54582527734SSukumar Swaminathan 54682527734SSukumar Swaminathan /* 54782527734SSukumar Swaminathan * If firmware checking is enabled and the adapter model indicates 54882527734SSukumar Swaminathan * a firmware image, then perform firmware version check 54982527734SSukumar Swaminathan */ 5506a573d82SSukumar Swaminathan hba->fw_flag = 0; 5516a573d82SSukumar Swaminathan hba->fw_timer = 0; 5526a573d82SSukumar Swaminathan 5536a573d82SSukumar Swaminathan if (((fw_check & 0x1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && 5546a573d82SSukumar Swaminathan hba->model_info.fwid) || ((fw_check & 0x2) && 55582527734SSukumar Swaminathan hba->model_info.fwid)) { 55682527734SSukumar Swaminathan 55782527734SSukumar Swaminathan /* Find firmware image indicated by adapter model */ 55882527734SSukumar Swaminathan fw = NULL; 55982527734SSukumar Swaminathan for (i = 0; i < emlxs_fw_count; i++) { 56082527734SSukumar Swaminathan if (emlxs_fw_table[i].id == hba->model_info.fwid) { 56182527734SSukumar Swaminathan fw = &emlxs_fw_table[i]; 56282527734SSukumar Swaminathan break; 56382527734SSukumar Swaminathan } 56482527734SSukumar Swaminathan } 56582527734SSukumar Swaminathan 56682527734SSukumar Swaminathan /* 56782527734SSukumar Swaminathan * If the image was found, then verify current firmware 56882527734SSukumar Swaminathan * versions of adapter 56982527734SSukumar Swaminathan */ 57082527734SSukumar Swaminathan if (fw) { 57182527734SSukumar Swaminathan 57282527734SSukumar Swaminathan /* Obtain current firmware version info */ 573*a9800bebSGarrett D'Amore if ((hba->model_info.chip == EMLXS_BE2_CHIP) || 574*a9800bebSGarrett D'Amore (hba->model_info.chip == EMLXS_BE3_CHIP)) { 57582527734SSukumar Swaminathan (void) emlxs_sli4_read_fw_version(hba, &hba_fw); 57682527734SSukumar Swaminathan } else { 57782527734SSukumar Swaminathan hba_fw.kern = vpd->postKernRev; 57882527734SSukumar Swaminathan hba_fw.stub = vpd->opFwRev; 57982527734SSukumar Swaminathan hba_fw.sli1 = vpd->sli1FwRev; 58082527734SSukumar Swaminathan hba_fw.sli2 = vpd->sli2FwRev; 58182527734SSukumar Swaminathan hba_fw.sli3 = vpd->sli3FwRev; 58282527734SSukumar Swaminathan hba_fw.sli4 = vpd->sli4FwRev; 58382527734SSukumar Swaminathan } 58482527734SSukumar Swaminathan 5856a573d82SSukumar Swaminathan if (!kern_update && 5866a573d82SSukumar Swaminathan ((fw->kern && (hba_fw.kern != fw->kern)) || 5876a573d82SSukumar Swaminathan (fw->stub && (hba_fw.stub != fw->stub)))) { 5886a573d82SSukumar Swaminathan 5896a573d82SSukumar Swaminathan hba->fw_flag |= FW_UPDATE_NEEDED; 5906a573d82SSukumar Swaminathan 5916a573d82SSukumar Swaminathan } else if ((fw->kern && (hba_fw.kern != fw->kern)) || 59282527734SSukumar Swaminathan (fw->stub && (hba_fw.stub != fw->stub)) || 59382527734SSukumar Swaminathan (fw->sli1 && (hba_fw.sli1 != fw->sli1)) || 59482527734SSukumar Swaminathan (fw->sli2 && (hba_fw.sli2 != fw->sli2)) || 59582527734SSukumar Swaminathan (fw->sli3 && (hba_fw.sli3 != fw->sli3)) || 59682527734SSukumar Swaminathan (fw->sli4 && (hba_fw.sli4 != fw->sli4))) { 59782527734SSukumar Swaminathan 59882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 59982527734SSukumar Swaminathan "Firmware update needed. " 60082527734SSukumar Swaminathan "Updating. id=%d fw=%d", 60182527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 60282527734SSukumar Swaminathan 60382527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 60482527734SSukumar Swaminathan /* 60582527734SSukumar Swaminathan * Load the firmware image now 60682527734SSukumar Swaminathan * If MODFW_SUPPORT is not defined, the 60782527734SSukumar Swaminathan * firmware image will already be defined 60882527734SSukumar Swaminathan * in the emlxs_fw_table 60982527734SSukumar Swaminathan */ 61082527734SSukumar Swaminathan emlxs_fw_load(hba, fw); 61182527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 61282527734SSukumar Swaminathan 61382527734SSukumar Swaminathan if (fw->image && fw->size) { 61482527734SSukumar Swaminathan if (emlxs_fw_download(hba, 61582527734SSukumar Swaminathan (char *)fw->image, fw->size, 0)) { 61682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 61782527734SSukumar Swaminathan &emlxs_init_msg, 61882527734SSukumar Swaminathan "Firmware update failed."); 6196a573d82SSukumar Swaminathan 6206a573d82SSukumar Swaminathan hba->fw_flag |= 6216a573d82SSukumar Swaminathan FW_UPDATE_NEEDED; 62282527734SSukumar Swaminathan } 62382527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 62482527734SSukumar Swaminathan /* 62582527734SSukumar Swaminathan * Unload the firmware image from 62682527734SSukumar Swaminathan * kernel memory 62782527734SSukumar Swaminathan */ 62882527734SSukumar Swaminathan emlxs_fw_unload(hba, fw); 62982527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 63082527734SSukumar Swaminathan 63182527734SSukumar Swaminathan fw_check = 0; 63282527734SSukumar Swaminathan 63382527734SSukumar Swaminathan goto reset; 63482527734SSukumar Swaminathan } 63582527734SSukumar Swaminathan 63682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 63782527734SSukumar Swaminathan "Firmware image unavailable."); 63882527734SSukumar Swaminathan } else { 63982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 64082527734SSukumar Swaminathan "Firmware update not needed."); 64182527734SSukumar Swaminathan } 64282527734SSukumar Swaminathan } else { 64382527734SSukumar Swaminathan /* 64482527734SSukumar Swaminathan * This means either the adapter database is not 64582527734SSukumar Swaminathan * correct or a firmware image is missing from the 64682527734SSukumar Swaminathan * compile 64782527734SSukumar Swaminathan */ 64882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 64982527734SSukumar Swaminathan "Firmware image unavailable. id=%d fw=%d", 65082527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 65182527734SSukumar Swaminathan } 65282527734SSukumar Swaminathan } 65382527734SSukumar Swaminathan 65482527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 65582527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 65682527734SSukumar Swaminathan 65782527734SSukumar Swaminathan emlxs_mb_dump_fcoe(hba, mbq, 0); 65882527734SSukumar Swaminathan 65982527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 66082527734SSukumar Swaminathan MBX_SUCCESS) { 66182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 66282527734SSukumar Swaminathan "No FCOE info found. status=%x", mb->mbxStatus); 66382527734SSukumar Swaminathan } else { 66482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 66582527734SSukumar Swaminathan &emlxs_init_debug_msg, 66682527734SSukumar Swaminathan "FCOE info dumped. rsp_cnt=%d status=%x", 66782527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 66882527734SSukumar Swaminathan (void) emlxs_parse_fcoe(hba, 669fe199829SSukumar Swaminathan (uint8_t *)hba->sli.sli4.dump_region.virt, 670fe199829SSukumar Swaminathan mb->un.varDmp4.rsp_cnt); 67182527734SSukumar Swaminathan } 67282527734SSukumar Swaminathan 67382527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 67482527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 67582527734SSukumar Swaminathan 67682527734SSukumar Swaminathan emlxs_mb_request_features(hba, mbq); 67782527734SSukumar Swaminathan 67882527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 67982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 68082527734SSukumar Swaminathan "Unable to REQUEST_FEATURES. Mailbox cmd=%x status=%x", 68182527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 68282527734SSukumar Swaminathan 68382527734SSukumar Swaminathan rval = EIO; 68482527734SSukumar Swaminathan goto failed1; 68582527734SSukumar Swaminathan } 686*a9800bebSGarrett D'Amore emlxs_data_dump(port, "REQ_FEATURE", (uint32_t *)mb, 6, 0); 68782527734SSukumar Swaminathan 68882527734SSukumar Swaminathan /* Make sure we get the features we requested */ 68982527734SSukumar Swaminathan if (mb->un.varReqFeatures.featuresRequested != 69082527734SSukumar Swaminathan mb->un.varReqFeatures.featuresEnabled) { 69182527734SSukumar Swaminathan 69282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 69382527734SSukumar Swaminathan "Unable to get REQUESTed_FEATURES. want:x%x got:x%x", 69482527734SSukumar Swaminathan mb->un.varReqFeatures.featuresRequested, 69582527734SSukumar Swaminathan mb->un.varReqFeatures.featuresEnabled); 69682527734SSukumar Swaminathan 69782527734SSukumar Swaminathan rval = EIO; 69882527734SSukumar Swaminathan goto failed1; 69982527734SSukumar Swaminathan } 70082527734SSukumar Swaminathan 70182527734SSukumar Swaminathan if (mb->un.varReqFeatures.featuresEnabled & SLI4_FEATURE_NPIV) { 70282527734SSukumar Swaminathan hba->flag |= FC_NPIV_ENABLED; 70382527734SSukumar Swaminathan } 70482527734SSukumar Swaminathan 70582527734SSukumar Swaminathan /* Check enable-npiv driver parameter for now */ 70682527734SSukumar Swaminathan if (cfg[CFG_NPIV_ENABLE].current) { 70782527734SSukumar Swaminathan hba->flag |= FC_NPIV_ENABLED; 70882527734SSukumar Swaminathan } 70982527734SSukumar Swaminathan 71082527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 71182527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 71282527734SSukumar Swaminathan 71382527734SSukumar Swaminathan emlxs_mb_read_config(hba, mbq); 71482527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 71582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 71682527734SSukumar Swaminathan "Unable to READ_CONFIG. Mailbox cmd=%x status=%x", 71782527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 71882527734SSukumar Swaminathan 71982527734SSukumar Swaminathan rval = EIO; 72082527734SSukumar Swaminathan goto failed1; 72182527734SSukumar Swaminathan } 722*a9800bebSGarrett D'Amore emlxs_data_dump(port, "READ_CONFIG4", (uint32_t *)mb, 18, 0); 72382527734SSukumar Swaminathan 72482527734SSukumar Swaminathan hba->sli.sli4.XRICount = (mb->un.varRdConfig4.XRICount); 72582527734SSukumar Swaminathan hba->sli.sli4.XRIBase = (mb->un.varRdConfig4.XRIBase); 72682527734SSukumar Swaminathan hba->sli.sli4.RPICount = (mb->un.varRdConfig4.RPICount); 72782527734SSukumar Swaminathan hba->sli.sli4.RPIBase = (mb->un.varRdConfig4.RPIBase); 72882527734SSukumar Swaminathan hba->sli.sli4.VPICount = (mb->un.varRdConfig4.VPICount); 72982527734SSukumar Swaminathan hba->sli.sli4.VPIBase = (mb->un.varRdConfig4.VPIBase); 73082527734SSukumar Swaminathan hba->sli.sli4.VFICount = (mb->un.varRdConfig4.VFICount); 73182527734SSukumar Swaminathan hba->sli.sli4.VFIBase = (mb->un.varRdConfig4.VFIBase); 73282527734SSukumar Swaminathan hba->sli.sli4.FCFICount = (mb->un.varRdConfig4.FCFICount); 73382527734SSukumar Swaminathan 73482527734SSukumar Swaminathan if (hba->sli.sli4.VPICount) { 73582527734SSukumar Swaminathan hba->vpi_max = min(hba->sli.sli4.VPICount, MAX_VPORTS) - 1; 73682527734SSukumar Swaminathan } 73782527734SSukumar Swaminathan hba->vpi_base = mb->un.varRdConfig4.VPIBase; 73882527734SSukumar Swaminathan 73982527734SSukumar Swaminathan /* Set the max node count */ 74082527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 74182527734SSukumar Swaminathan hba->max_nodes = 74282527734SSukumar Swaminathan min(cfg[CFG_NUM_NODES].current, 74382527734SSukumar Swaminathan hba->sli.sli4.RPICount); 74482527734SSukumar Swaminathan } else { 74582527734SSukumar Swaminathan hba->max_nodes = hba->sli.sli4.RPICount; 74682527734SSukumar Swaminathan } 74782527734SSukumar Swaminathan 74882527734SSukumar Swaminathan /* Set the io throttle */ 74982527734SSukumar Swaminathan hba->io_throttle = hba->sli.sli4.XRICount - IO_THROTTLE_RESERVE; 75082527734SSukumar Swaminathan hba->max_iotag = hba->sli.sli4.XRICount; 75182527734SSukumar Swaminathan 75282527734SSukumar Swaminathan /* Save the link speed capabilities */ 753*a9800bebSGarrett D'Amore vpd->link_speed = (uint16_t)mb->un.varRdConfig4.lmt; 75482527734SSukumar Swaminathan emlxs_process_link_speed(hba); 75582527734SSukumar Swaminathan 75682527734SSukumar Swaminathan /* 75782527734SSukumar Swaminathan * Allocate some memory for buffers 75882527734SSukumar Swaminathan */ 75982527734SSukumar Swaminathan if (emlxs_mem_alloc_buffer(hba) == 0) { 76082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 76182527734SSukumar Swaminathan "Unable to allocate memory buffers."); 76282527734SSukumar Swaminathan 76382527734SSukumar Swaminathan rval = ENOMEM; 76482527734SSukumar Swaminathan goto failed1; 76582527734SSukumar Swaminathan } 76682527734SSukumar Swaminathan 76782527734SSukumar Swaminathan /* 76882527734SSukumar Swaminathan * OutOfRange (oor) iotags are used for abort or close 76982527734SSukumar Swaminathan * XRI commands or any WQE that does not require a SGL 77082527734SSukumar Swaminathan */ 77182527734SSukumar Swaminathan hba->fc_oor_iotag = hba->max_iotag; 77282527734SSukumar Swaminathan 77382527734SSukumar Swaminathan if (emlxs_sli4_resource_alloc(hba)) { 77482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 77582527734SSukumar Swaminathan "Unable to allocate resources."); 77682527734SSukumar Swaminathan 77782527734SSukumar Swaminathan rval = ENOMEM; 77882527734SSukumar Swaminathan goto failed2; 77982527734SSukumar Swaminathan } 780*a9800bebSGarrett D'Amore emlxs_data_dump(port, "XRIp", (uint32_t *)hba->sli.sli4.XRIp, 18, 0); 78182527734SSukumar Swaminathan 78282527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV5) 78382527734SSukumar Swaminathan if ((cfg[CFG_NPIV_ENABLE].current) && (hba->flag & FC_NPIV_ENABLED)) { 78482527734SSukumar Swaminathan hba->fca_tran->fca_num_npivports = hba->vpi_max; 78582527734SSukumar Swaminathan } 78682527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV5 */ 78782527734SSukumar Swaminathan 78882527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 78982527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 79082527734SSukumar Swaminathan 79182527734SSukumar Swaminathan if (emlxs_sli4_post_sgl_pages(hba, mbq)) { 79282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 79382527734SSukumar Swaminathan "Unable to post sgl pages."); 79482527734SSukumar Swaminathan 79582527734SSukumar Swaminathan rval = EIO; 79682527734SSukumar Swaminathan goto failed3; 79782527734SSukumar Swaminathan } 79882527734SSukumar Swaminathan 79982527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 80082527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 80182527734SSukumar Swaminathan 80282527734SSukumar Swaminathan if (emlxs_sli4_post_hdr_tmplates(hba, mbq)) { 80382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 80482527734SSukumar Swaminathan "Unable to post header templates."); 80582527734SSukumar Swaminathan 80682527734SSukumar Swaminathan rval = EIO; 80782527734SSukumar Swaminathan goto failed3; 80882527734SSukumar Swaminathan } 80982527734SSukumar Swaminathan 81082527734SSukumar Swaminathan /* 81182527734SSukumar Swaminathan * Add our interrupt routine to kernel's interrupt chain & enable it 81282527734SSukumar Swaminathan * If MSI is enabled this will cause Solaris to program the MSI address 81382527734SSukumar Swaminathan * and data registers in PCI config space 81482527734SSukumar Swaminathan */ 81582527734SSukumar Swaminathan if (EMLXS_INTR_ADD(hba) != DDI_SUCCESS) { 81682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 81782527734SSukumar Swaminathan "Unable to add interrupt(s)."); 81882527734SSukumar Swaminathan 81982527734SSukumar Swaminathan rval = EIO; 82082527734SSukumar Swaminathan goto failed3; 82182527734SSukumar Swaminathan } 82282527734SSukumar Swaminathan 82382527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 82482527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 82582527734SSukumar Swaminathan 82682527734SSukumar Swaminathan /* This MUST be done after EMLXS_INTR_ADD */ 82782527734SSukumar Swaminathan if (emlxs_sli4_create_queues(hba, mbq)) { 82882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 82982527734SSukumar Swaminathan "Unable to create queues."); 83082527734SSukumar Swaminathan 83182527734SSukumar Swaminathan rval = EIO; 83282527734SSukumar Swaminathan goto failed3; 83382527734SSukumar Swaminathan } 83482527734SSukumar Swaminathan 83582527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_CFGPORT); 83682527734SSukumar Swaminathan 83782527734SSukumar Swaminathan /* Get and save the current firmware version (based on sli_mode) */ 83882527734SSukumar Swaminathan emlxs_decode_firmware_rev(hba, vpd); 83982527734SSukumar Swaminathan 84082527734SSukumar Swaminathan 84182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_INITLINK); 84282527734SSukumar Swaminathan 84382527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 84482527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 84582527734SSukumar Swaminathan 84682527734SSukumar Swaminathan /* 84782527734SSukumar Swaminathan * We need to get login parameters for NID 84882527734SSukumar Swaminathan */ 84982527734SSukumar Swaminathan (void) emlxs_mb_read_sparam(hba, mbq); 850*a9800bebSGarrett D'Amore mp = (MATCHMAP *)mbq->bp; 85182527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 85282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 85382527734SSukumar Swaminathan "Unable to read parameters. Mailbox cmd=%x status=%x", 85482527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 85582527734SSukumar Swaminathan 85682527734SSukumar Swaminathan rval = EIO; 85782527734SSukumar Swaminathan goto failed3; 85882527734SSukumar Swaminathan } 85982527734SSukumar Swaminathan 86082527734SSukumar Swaminathan /* Free the buffer since we were polling */ 861*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_BUF, (void *)mp); 86282527734SSukumar Swaminathan mp = NULL; 86382527734SSukumar Swaminathan 86482527734SSukumar Swaminathan /* If no serial number in VPD data, then use the WWPN */ 86582527734SSukumar Swaminathan if (vpd->serial_num[0] == 0) { 86682527734SSukumar Swaminathan outptr = (uint8_t *)&hba->wwpn.IEEE[0]; 86782527734SSukumar Swaminathan for (i = 0; i < 12; i++) { 86882527734SSukumar Swaminathan status = *outptr++; 86982527734SSukumar Swaminathan j = ((status & 0xf0) >> 4); 87082527734SSukumar Swaminathan if (j <= 9) { 87182527734SSukumar Swaminathan vpd->serial_num[i] = 87282527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 87382527734SSukumar Swaminathan } else { 87482527734SSukumar Swaminathan vpd->serial_num[i] = 87582527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 87682527734SSukumar Swaminathan } 87782527734SSukumar Swaminathan 87882527734SSukumar Swaminathan i++; 87982527734SSukumar Swaminathan j = (status & 0xf); 88082527734SSukumar Swaminathan if (j <= 9) { 88182527734SSukumar Swaminathan vpd->serial_num[i] = 88282527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 88382527734SSukumar Swaminathan } else { 88482527734SSukumar Swaminathan vpd->serial_num[i] = 88582527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 88682527734SSukumar Swaminathan } 88782527734SSukumar Swaminathan } 88882527734SSukumar Swaminathan 88982527734SSukumar Swaminathan /* 89082527734SSukumar Swaminathan * Set port number and port index to zero 89182527734SSukumar Swaminathan * The WWN's are unique to each port and therefore port_num 89282527734SSukumar Swaminathan * must equal zero. This effects the hba_fru_details structure 89382527734SSukumar Swaminathan * in fca_bind_port() 89482527734SSukumar Swaminathan */ 89582527734SSukumar Swaminathan vpd->port_num[0] = 0; 89682527734SSukumar Swaminathan vpd->port_index = 0; 89782527734SSukumar Swaminathan } 89882527734SSukumar Swaminathan 89982527734SSukumar Swaminathan /* Make attempt to set a port index */ 900*a9800bebSGarrett D'Amore if (vpd->port_index == (uint32_t)-1) { 90182527734SSukumar Swaminathan dev_info_t *p_dip; 90282527734SSukumar Swaminathan dev_info_t *c_dip; 90382527734SSukumar Swaminathan 90482527734SSukumar Swaminathan p_dip = ddi_get_parent(hba->dip); 90582527734SSukumar Swaminathan c_dip = ddi_get_child(p_dip); 90682527734SSukumar Swaminathan 90782527734SSukumar Swaminathan vpd->port_index = 0; 90882527734SSukumar Swaminathan while (c_dip && (hba->dip != c_dip)) { 90982527734SSukumar Swaminathan c_dip = ddi_get_next_sibling(c_dip); 91082527734SSukumar Swaminathan 91182527734SSukumar Swaminathan if (strcmp(ddi_get_name(c_dip), "ethernet")) { 91282527734SSukumar Swaminathan vpd->port_index++; 91382527734SSukumar Swaminathan } 91482527734SSukumar Swaminathan } 91582527734SSukumar Swaminathan } 91682527734SSukumar Swaminathan 91782527734SSukumar Swaminathan if (vpd->port_num[0] == 0) { 91882527734SSukumar Swaminathan if (hba->model_info.channels > 1) { 91982527734SSukumar Swaminathan (void) sprintf(vpd->port_num, "%d", vpd->port_index); 92082527734SSukumar Swaminathan } 92182527734SSukumar Swaminathan } 92282527734SSukumar Swaminathan 92382527734SSukumar Swaminathan if (vpd->id[0] == 0) { 92482527734SSukumar Swaminathan (void) sprintf(vpd->id, "%s %d", 92582527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 92682527734SSukumar Swaminathan 92782527734SSukumar Swaminathan } 92882527734SSukumar Swaminathan 92982527734SSukumar Swaminathan if (vpd->manufacturer[0] == 0) { 93082527734SSukumar Swaminathan (void) strcpy(vpd->manufacturer, hba->model_info.manufacturer); 93182527734SSukumar Swaminathan } 93282527734SSukumar Swaminathan 93382527734SSukumar Swaminathan if (vpd->part_num[0] == 0) { 93482527734SSukumar Swaminathan (void) strcpy(vpd->part_num, hba->model_info.model); 93582527734SSukumar Swaminathan } 93682527734SSukumar Swaminathan 93782527734SSukumar Swaminathan if (vpd->model_desc[0] == 0) { 93882527734SSukumar Swaminathan (void) sprintf(vpd->model_desc, "%s %d", 93982527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 94082527734SSukumar Swaminathan } 94182527734SSukumar Swaminathan 94282527734SSukumar Swaminathan if (vpd->model[0] == 0) { 94382527734SSukumar Swaminathan (void) strcpy(vpd->model, hba->model_info.model); 94482527734SSukumar Swaminathan } 94582527734SSukumar Swaminathan 94682527734SSukumar Swaminathan if (vpd->prog_types[0] == 0) { 94782527734SSukumar Swaminathan emlxs_build_prog_types(hba, vpd->prog_types); 94882527734SSukumar Swaminathan } 94982527734SSukumar Swaminathan 95082527734SSukumar Swaminathan /* Create the symbolic names */ 95182527734SSukumar Swaminathan (void) sprintf(hba->snn, "Emulex %s FV%s DV%s %s", 95282527734SSukumar Swaminathan hba->model_info.model, hba->vpd.fw_version, emlxs_version, 95382527734SSukumar Swaminathan (char *)utsname.nodename); 95482527734SSukumar Swaminathan 95582527734SSukumar Swaminathan (void) sprintf(hba->spn, 95682527734SSukumar Swaminathan "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 95782527734SSukumar Swaminathan hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb, 95882527734SSukumar Swaminathan hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2], 95982527734SSukumar Swaminathan hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]); 96082527734SSukumar Swaminathan 96182527734SSukumar Swaminathan 96282527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN); 96382527734SSukumar Swaminathan emlxs_sli4_enable_intr(hba); 96482527734SSukumar Swaminathan 96582527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 96682527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 96782527734SSukumar Swaminathan 96882527734SSukumar Swaminathan /* 96982527734SSukumar Swaminathan * Setup and issue mailbox INITIALIZE LINK command 97082527734SSukumar Swaminathan * At this point, the interrupt will be generated by the HW 97182527734SSukumar Swaminathan * Do this only if persist-linkdown is not set 97282527734SSukumar Swaminathan */ 97382527734SSukumar Swaminathan if (cfg[CFG_PERSIST_LINKDOWN].current == 0) { 97482527734SSukumar Swaminathan emlxs_mb_init_link(hba, mbq, 97582527734SSukumar Swaminathan cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current); 97682527734SSukumar Swaminathan 97782527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) 97882527734SSukumar Swaminathan != MBX_SUCCESS) { 97982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 980*a9800bebSGarrett D'Amore "Unable to initialize link. " 98182527734SSukumar Swaminathan "Mailbox cmd=%x status=%x", 98282527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 98382527734SSukumar Swaminathan 98482527734SSukumar Swaminathan rval = EIO; 98582527734SSukumar Swaminathan goto failed3; 98682527734SSukumar Swaminathan } 98782527734SSukumar Swaminathan 98882527734SSukumar Swaminathan /* Wait for link to come up */ 98982527734SSukumar Swaminathan i = cfg[CFG_LINKUP_DELAY].current; 99082527734SSukumar Swaminathan while (i && (hba->state < FC_LINK_UP)) { 99182527734SSukumar Swaminathan /* Check for hardware error */ 99282527734SSukumar Swaminathan if (hba->state == FC_ERROR) { 99382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 99482527734SSukumar Swaminathan &emlxs_init_failed_msg, 99582527734SSukumar Swaminathan "Adapter error.", mb->mbxCommand, 99682527734SSukumar Swaminathan mb->mbxStatus); 99782527734SSukumar Swaminathan 99882527734SSukumar Swaminathan rval = EIO; 99982527734SSukumar Swaminathan goto failed3; 100082527734SSukumar Swaminathan } 100182527734SSukumar Swaminathan 100282527734SSukumar Swaminathan DELAYMS(1000); 100382527734SSukumar Swaminathan i--; 100482527734SSukumar Swaminathan } 1005*a9800bebSGarrett D'Amore } else { 1006*a9800bebSGarrett D'Amore EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN_PERSIST); 100782527734SSukumar Swaminathan } 100882527734SSukumar Swaminathan 100982527734SSukumar Swaminathan /* 101082527734SSukumar Swaminathan * The leadvile driver will now handle the FLOGI at the driver level 101182527734SSukumar Swaminathan */ 101282527734SSukumar Swaminathan 1013bce54adfSSukumar Swaminathan if (mbq) { 1014bce54adfSSukumar Swaminathan (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ)); 1015bce54adfSSukumar Swaminathan mbq = NULL; 1016bce54adfSSukumar Swaminathan mb = NULL; 1017bce54adfSSukumar Swaminathan } 101882527734SSukumar Swaminathan return (0); 101982527734SSukumar Swaminathan 102082527734SSukumar Swaminathan failed3: 102182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 102282527734SSukumar Swaminathan 102382527734SSukumar Swaminathan if (mp) { 1024*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_BUF, (void *)mp); 102582527734SSukumar Swaminathan mp = NULL; 102682527734SSukumar Swaminathan } 102782527734SSukumar Swaminathan 102882527734SSukumar Swaminathan 102982527734SSukumar Swaminathan if (hba->intr_flags & EMLXS_MSI_ADDED) { 103082527734SSukumar Swaminathan (void) EMLXS_INTR_REMOVE(hba); 103182527734SSukumar Swaminathan } 103282527734SSukumar Swaminathan 103382527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 103482527734SSukumar Swaminathan 103582527734SSukumar Swaminathan failed2: 103682527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 103782527734SSukumar Swaminathan 103882527734SSukumar Swaminathan failed1: 103982527734SSukumar Swaminathan if (mbq) { 104082527734SSukumar Swaminathan (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ)); 104182527734SSukumar Swaminathan mbq = NULL; 104282527734SSukumar Swaminathan mb = NULL; 104382527734SSukumar Swaminathan } 104482527734SSukumar Swaminathan 104582527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt) { 104682527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 104782527734SSukumar Swaminathan } 104882527734SSukumar Swaminathan 104982527734SSukumar Swaminathan if (rval == 0) { 105082527734SSukumar Swaminathan rval = EIO; 105182527734SSukumar Swaminathan } 105282527734SSukumar Swaminathan 105382527734SSukumar Swaminathan return (rval); 105482527734SSukumar Swaminathan 105582527734SSukumar Swaminathan } /* emlxs_sli4_online() */ 105682527734SSukumar Swaminathan 105782527734SSukumar Swaminathan 105882527734SSukumar Swaminathan static void 105982527734SSukumar Swaminathan emlxs_sli4_offline(emlxs_hba_t *hba) 106082527734SSukumar Swaminathan { 106182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 106282527734SSukumar Swaminathan MAILBOXQ mboxq; 106382527734SSukumar Swaminathan 106482527734SSukumar Swaminathan /* Reverse emlxs_sli4_online */ 106582527734SSukumar Swaminathan 106682527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 106782527734SSukumar Swaminathan if (!(hba->flag & FC_INTERLOCKED)) { 106882527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 106982527734SSukumar Swaminathan 107082527734SSukumar Swaminathan /* This is the only way to disable interupts */ 107182527734SSukumar Swaminathan bzero((void *)&mboxq, sizeof (MAILBOXQ)); 107282527734SSukumar Swaminathan emlxs_mb_resetport(hba, &mboxq); 107382527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, &mboxq, 107482527734SSukumar Swaminathan MBX_WAIT, 0) != MBX_SUCCESS) { 107582527734SSukumar Swaminathan /* Timeout occurred */ 107682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 107782527734SSukumar Swaminathan "Timeout: Offline RESET"); 107882527734SSukumar Swaminathan } 107982527734SSukumar Swaminathan (void) emlxs_check_hdw_ready(hba); 108082527734SSukumar Swaminathan } else { 108182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 108282527734SSukumar Swaminathan } 108382527734SSukumar Swaminathan 108482527734SSukumar Swaminathan /* Shutdown the adapter interface */ 108582527734SSukumar Swaminathan emlxs_sli4_hba_kill(hba); 108682527734SSukumar Swaminathan 108782527734SSukumar Swaminathan /* Free SLI shared memory */ 108882527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 108982527734SSukumar Swaminathan 109082527734SSukumar Swaminathan /* Free driver shared memory */ 109182527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 109282527734SSukumar Swaminathan 109382527734SSukumar Swaminathan /* Free the host dump region buffer */ 109482527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 109582527734SSukumar Swaminathan 109682527734SSukumar Swaminathan } /* emlxs_sli4_offline() */ 109782527734SSukumar Swaminathan 109882527734SSukumar Swaminathan 109982527734SSukumar Swaminathan /*ARGSUSED*/ 110082527734SSukumar Swaminathan static int 110182527734SSukumar Swaminathan emlxs_sli4_map_hdw(emlxs_hba_t *hba) 110282527734SSukumar Swaminathan { 110382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 110482527734SSukumar Swaminathan dev_info_t *dip; 110582527734SSukumar Swaminathan ddi_device_acc_attr_t dev_attr; 110682527734SSukumar Swaminathan int status; 110782527734SSukumar Swaminathan 110882527734SSukumar Swaminathan dip = (dev_info_t *)hba->dip; 110982527734SSukumar Swaminathan dev_attr = emlxs_dev_acc_attr; 111082527734SSukumar Swaminathan 111182527734SSukumar Swaminathan /* 111282527734SSukumar Swaminathan * Map in Hardware BAR pages that will be used for 111382527734SSukumar Swaminathan * communication with HBA. 111482527734SSukumar Swaminathan */ 111582527734SSukumar Swaminathan if (hba->sli.sli4.bar1_acc_handle == 0) { 111682527734SSukumar Swaminathan status = ddi_regs_map_setup(dip, PCI_BAR1_RINDEX, 111782527734SSukumar Swaminathan (caddr_t *)&hba->sli.sli4.bar1_addr, 111882527734SSukumar Swaminathan 0, 0, &dev_attr, &hba->sli.sli4.bar1_acc_handle); 111982527734SSukumar Swaminathan if (status != DDI_SUCCESS) { 112082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 112182527734SSukumar Swaminathan &emlxs_attach_failed_msg, 112282527734SSukumar Swaminathan "(PCI) ddi_regs_map_setup BAR1 failed. " 112382527734SSukumar Swaminathan "stat=%d mem=%p attr=%p hdl=%p", 112482527734SSukumar Swaminathan status, &hba->sli.sli4.bar1_addr, &dev_attr, 112582527734SSukumar Swaminathan &hba->sli.sli4.bar1_acc_handle); 112682527734SSukumar Swaminathan goto failed; 112782527734SSukumar Swaminathan } 112882527734SSukumar Swaminathan } 112982527734SSukumar Swaminathan 113082527734SSukumar Swaminathan if (hba->sli.sli4.bar2_acc_handle == 0) { 113182527734SSukumar Swaminathan status = ddi_regs_map_setup(dip, PCI_BAR2_RINDEX, 113282527734SSukumar Swaminathan (caddr_t *)&hba->sli.sli4.bar2_addr, 113382527734SSukumar Swaminathan 0, 0, &dev_attr, &hba->sli.sli4.bar2_acc_handle); 113482527734SSukumar Swaminathan if (status != DDI_SUCCESS) { 113582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 113682527734SSukumar Swaminathan &emlxs_attach_failed_msg, 113782527734SSukumar Swaminathan "ddi_regs_map_setup BAR2 failed. status=%x", 113882527734SSukumar Swaminathan status); 113982527734SSukumar Swaminathan goto failed; 114082527734SSukumar Swaminathan } 114182527734SSukumar Swaminathan } 114282527734SSukumar Swaminathan 114382527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt == 0) { 114482527734SSukumar Swaminathan MBUF_INFO *buf_info; 114582527734SSukumar Swaminathan MBUF_INFO bufinfo; 114682527734SSukumar Swaminathan 114782527734SSukumar Swaminathan buf_info = &bufinfo; 114882527734SSukumar Swaminathan 114982527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 115082527734SSukumar Swaminathan buf_info->size = EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE; 115182527734SSukumar Swaminathan buf_info->flags = 115282527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 115382527734SSukumar Swaminathan buf_info->align = ddi_ptob(dip, 1L); 115482527734SSukumar Swaminathan 115582527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 115682527734SSukumar Swaminathan 115782527734SSukumar Swaminathan if (buf_info->virt == NULL) { 115882527734SSukumar Swaminathan goto failed; 115982527734SSukumar Swaminathan } 116082527734SSukumar Swaminathan 1161*a9800bebSGarrett D'Amore hba->sli.sli4.bootstrapmb.virt = buf_info->virt; 116282527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.phys = buf_info->phys; 116382527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.size = EMLXS_BOOTSTRAP_MB_SIZE + 116482527734SSukumar Swaminathan MBOX_EXTENSION_SIZE; 116582527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle = buf_info->data_handle; 116682527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle = buf_info->dma_handle; 116782527734SSukumar Swaminathan bzero((char *)hba->sli.sli4.bootstrapmb.virt, 116882527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE); 116982527734SSukumar Swaminathan } 117082527734SSukumar Swaminathan 117182527734SSukumar Swaminathan /* offset from beginning of register space */ 117282527734SSukumar Swaminathan hba->sli.sli4.MPUEPSemaphore_reg_addr = 117382527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar1_addr + CSR_MPU_EP_SEMAPHORE_OFFSET); 117482527734SSukumar Swaminathan hba->sli.sli4.MBDB_reg_addr = 117582527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MB_DB_OFFSET); 117682527734SSukumar Swaminathan hba->sli.sli4.CQDB_reg_addr = 117782527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_CQ_DB_OFFSET); 117882527734SSukumar Swaminathan hba->sli.sli4.MQDB_reg_addr = 117982527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MQ_DB_OFFSET); 118082527734SSukumar Swaminathan hba->sli.sli4.WQDB_reg_addr = 118182527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_WQ_DB_OFFSET); 118282527734SSukumar Swaminathan hba->sli.sli4.RQDB_reg_addr = 118382527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_RQ_DB_OFFSET); 118482527734SSukumar Swaminathan hba->chan_count = MAX_CHANNEL; 118582527734SSukumar Swaminathan 118682527734SSukumar Swaminathan return (0); 118782527734SSukumar Swaminathan 118882527734SSukumar Swaminathan failed: 118982527734SSukumar Swaminathan 119082527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(hba); 119182527734SSukumar Swaminathan return (ENOMEM); 119282527734SSukumar Swaminathan 119382527734SSukumar Swaminathan 119482527734SSukumar Swaminathan } /* emlxs_sli4_map_hdw() */ 119582527734SSukumar Swaminathan 119682527734SSukumar Swaminathan 119782527734SSukumar Swaminathan /*ARGSUSED*/ 119882527734SSukumar Swaminathan static void 119982527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(emlxs_hba_t *hba) 120082527734SSukumar Swaminathan { 120182527734SSukumar Swaminathan MBUF_INFO bufinfo; 120282527734SSukumar Swaminathan MBUF_INFO *buf_info = &bufinfo; 120382527734SSukumar Swaminathan 120482527734SSukumar Swaminathan /* 120582527734SSukumar Swaminathan * Free map for Hardware BAR pages that were used for 120682527734SSukumar Swaminathan * communication with HBA. 120782527734SSukumar Swaminathan */ 120882527734SSukumar Swaminathan if (hba->sli.sli4.bar1_acc_handle) { 120982527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar1_acc_handle); 121082527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle = 0; 121182527734SSukumar Swaminathan } 121282527734SSukumar Swaminathan 121382527734SSukumar Swaminathan if (hba->sli.sli4.bar2_acc_handle) { 121482527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar2_acc_handle); 121582527734SSukumar Swaminathan hba->sli.sli4.bar2_acc_handle = 0; 121682527734SSukumar Swaminathan } 121782527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt) { 121882527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 121982527734SSukumar Swaminathan 122082527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.phys) { 122182527734SSukumar Swaminathan buf_info->phys = hba->sli.sli4.bootstrapmb.phys; 122282527734SSukumar Swaminathan buf_info->data_handle = 122382527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle; 122482527734SSukumar Swaminathan buf_info->dma_handle = 122582527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle; 122682527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 122782527734SSukumar Swaminathan } 122882527734SSukumar Swaminathan 1229*a9800bebSGarrett D'Amore buf_info->virt = hba->sli.sli4.bootstrapmb.virt; 123082527734SSukumar Swaminathan buf_info->size = hba->sli.sli4.bootstrapmb.size; 123182527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 123282527734SSukumar Swaminathan 1233*a9800bebSGarrett D'Amore hba->sli.sli4.bootstrapmb.virt = NULL; 123482527734SSukumar Swaminathan } 123582527734SSukumar Swaminathan 123682527734SSukumar Swaminathan return; 123782527734SSukumar Swaminathan 123882527734SSukumar Swaminathan } /* emlxs_sli4_unmap_hdw() */ 123982527734SSukumar Swaminathan 124082527734SSukumar Swaminathan 124182527734SSukumar Swaminathan static int 124282527734SSukumar Swaminathan emlxs_check_hdw_ready(emlxs_hba_t *hba) 124382527734SSukumar Swaminathan { 124482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 124582527734SSukumar Swaminathan uint32_t status; 124682527734SSukumar Swaminathan uint32_t i = 0; 124782527734SSukumar Swaminathan 124882527734SSukumar Swaminathan /* Wait for reset completion */ 124982527734SSukumar Swaminathan while (i < 30) { 125082527734SSukumar Swaminathan /* Check Semaphore register to see what the ARM state is */ 125182527734SSukumar Swaminathan status = READ_BAR1_REG(hba, FC_SEMA_REG(hba)); 125282527734SSukumar Swaminathan 125382527734SSukumar Swaminathan /* Check to see if any errors occurred during init */ 125482527734SSukumar Swaminathan if (status & ARM_POST_FATAL) { 125582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 125682527734SSukumar Swaminathan "SEMA Error: status=0x%x", status); 125782527734SSukumar Swaminathan 125882527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 125982527734SSukumar Swaminathan #ifdef FMA_SUPPORT 126082527734SSukumar Swaminathan /* Access handle validation */ 126182527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 126282527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle); 126382527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 126482527734SSukumar Swaminathan return (1); 126582527734SSukumar Swaminathan } 126682527734SSukumar Swaminathan if ((status & ARM_POST_MASK) == ARM_POST_READY) { 126782527734SSukumar Swaminathan /* ARM Ready !! */ 126882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 126982527734SSukumar Swaminathan "ARM Ready: status=0x%x", status); 127082527734SSukumar Swaminathan #ifdef FMA_SUPPORT 127182527734SSukumar Swaminathan /* Access handle validation */ 127282527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 127382527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle); 127482527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 127582527734SSukumar Swaminathan return (0); 127682527734SSukumar Swaminathan } 127782527734SSukumar Swaminathan 127882527734SSukumar Swaminathan DELAYMS(1000); 127982527734SSukumar Swaminathan i++; 128082527734SSukumar Swaminathan } 128182527734SSukumar Swaminathan 128282527734SSukumar Swaminathan /* Timeout occurred */ 128382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 128482527734SSukumar Swaminathan "Timeout waiting for READY: status=0x%x", status); 128582527734SSukumar Swaminathan 128682527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 128782527734SSukumar Swaminathan 128882527734SSukumar Swaminathan #ifdef FMA_SUPPORT 128982527734SSukumar Swaminathan /* Access handle validation */ 129082527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar1_acc_handle); 129182527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 129282527734SSukumar Swaminathan 129382527734SSukumar Swaminathan /* Log a dump event - not supported */ 129482527734SSukumar Swaminathan 129582527734SSukumar Swaminathan return (2); 129682527734SSukumar Swaminathan 129782527734SSukumar Swaminathan } /* emlxs_check_hdw_ready() */ 129882527734SSukumar Swaminathan 129982527734SSukumar Swaminathan 130082527734SSukumar Swaminathan static uint32_t 130182527734SSukumar Swaminathan emlxs_check_bootstrap_ready(emlxs_hba_t *hba, uint32_t tmo) 130282527734SSukumar Swaminathan { 130382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 130482527734SSukumar Swaminathan uint32_t status; 130582527734SSukumar Swaminathan 130682527734SSukumar Swaminathan /* Wait for reset completion, tmo is in 10ms ticks */ 130782527734SSukumar Swaminathan while (tmo) { 130882527734SSukumar Swaminathan /* Check Semaphore register to see what the ARM state is */ 130982527734SSukumar Swaminathan status = READ_BAR2_REG(hba, FC_MBDB_REG(hba)); 131082527734SSukumar Swaminathan 131182527734SSukumar Swaminathan /* Check to see if any errors occurred during init */ 131282527734SSukumar Swaminathan if (status & BMBX_READY) { 131382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 131482527734SSukumar Swaminathan "BMBX Ready: status=0x%x", status); 131582527734SSukumar Swaminathan #ifdef FMA_SUPPORT 131682527734SSukumar Swaminathan /* Access handle validation */ 131782527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 131882527734SSukumar Swaminathan hba->sli.sli4.bar2_acc_handle); 131982527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 132082527734SSukumar Swaminathan return (tmo); 132182527734SSukumar Swaminathan } 132282527734SSukumar Swaminathan 132382527734SSukumar Swaminathan DELAYMS(10); 132482527734SSukumar Swaminathan tmo--; 132582527734SSukumar Swaminathan } 132682527734SSukumar Swaminathan 132782527734SSukumar Swaminathan /* Timeout occurred */ 132882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 132982527734SSukumar Swaminathan "Timeout waiting for BMailbox: status=0x%x", status); 133082527734SSukumar Swaminathan 133182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 133282527734SSukumar Swaminathan 133382527734SSukumar Swaminathan #ifdef FMA_SUPPORT 133482527734SSukumar Swaminathan /* Access handle validation */ 133582527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar2_acc_handle); 133682527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 133782527734SSukumar Swaminathan 133882527734SSukumar Swaminathan /* Log a dump event - not supported */ 133982527734SSukumar Swaminathan 134082527734SSukumar Swaminathan return (0); 134182527734SSukumar Swaminathan 134282527734SSukumar Swaminathan } /* emlxs_check_bootstrap_ready() */ 134382527734SSukumar Swaminathan 134482527734SSukumar Swaminathan 134582527734SSukumar Swaminathan static uint32_t 134682527734SSukumar Swaminathan emlxs_issue_bootstrap_mb(emlxs_hba_t *hba, uint32_t tmo) 134782527734SSukumar Swaminathan { 134882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 134982527734SSukumar Swaminathan uint32_t *iptr; 135082527734SSukumar Swaminathan uint32_t addr30; 135182527734SSukumar Swaminathan 135282527734SSukumar Swaminathan /* 135382527734SSukumar Swaminathan * This routine assumes the bootstrap mbox is loaded 135482527734SSukumar Swaminathan * with the mailbox command to be executed. 135582527734SSukumar Swaminathan * 135682527734SSukumar Swaminathan * First, load the high 30 bits of bootstrap mailbox 135782527734SSukumar Swaminathan */ 135882527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>32) & 0xfffffffc); 135982527734SSukumar Swaminathan addr30 |= BMBX_ADDR_HI; 136082527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MBDB_REG(hba), addr30); 136182527734SSukumar Swaminathan 136282527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 136382527734SSukumar Swaminathan if (tmo == 0) { 136482527734SSukumar Swaminathan return (0); 136582527734SSukumar Swaminathan } 136682527734SSukumar Swaminathan 136782527734SSukumar Swaminathan /* Load the low 30 bits of bootstrap mailbox */ 136882527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>2) & 0xfffffffc); 136982527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MBDB_REG(hba), addr30); 137082527734SSukumar Swaminathan 137182527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 137282527734SSukumar Swaminathan if (tmo == 0) { 137382527734SSukumar Swaminathan return (0); 137482527734SSukumar Swaminathan } 137582527734SSukumar Swaminathan 137682527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 137782527734SSukumar Swaminathan 137882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 137982527734SSukumar Swaminathan "BootstrapMB: %p Completed %08x %08x %08x", 138082527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.virt, 138182527734SSukumar Swaminathan *iptr, *(iptr+1), *(iptr+2)); 138282527734SSukumar Swaminathan 138382527734SSukumar Swaminathan return (tmo); 138482527734SSukumar Swaminathan 138582527734SSukumar Swaminathan } /* emlxs_issue_bootstrap_mb() */ 138682527734SSukumar Swaminathan 138782527734SSukumar Swaminathan 138882527734SSukumar Swaminathan static int 138982527734SSukumar Swaminathan emlxs_init_bootstrap_mb(emlxs_hba_t *hba) 139082527734SSukumar Swaminathan { 139182527734SSukumar Swaminathan #ifdef FMA_SUPPORT 139282527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 139382527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 139482527734SSukumar Swaminathan uint32_t *iptr; 139582527734SSukumar Swaminathan uint32_t tmo; 139682527734SSukumar Swaminathan 139782527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 139882527734SSukumar Swaminathan return (1); 139982527734SSukumar Swaminathan } 140082527734SSukumar Swaminathan 140182527734SSukumar Swaminathan if (hba->flag & FC_BOOTSTRAPMB_INIT) { 140282527734SSukumar Swaminathan return (0); /* Already initialized */ 140382527734SSukumar Swaminathan } 140482527734SSukumar Swaminathan 140582527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 140682527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, 3000); 140782527734SSukumar Swaminathan if (tmo == 0) { 140882527734SSukumar Swaminathan return (1); 140982527734SSukumar Swaminathan } 141082527734SSukumar Swaminathan 141182527734SSukumar Swaminathan /* Special words to initialize bootstrap mbox MUST be little endian */ 141282527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 141382527734SSukumar Swaminathan *iptr++ = LE_SWAP32(MQE_SPECIAL_WORD0); 141482527734SSukumar Swaminathan *iptr = LE_SWAP32(MQE_SPECIAL_WORD1); 141582527734SSukumar Swaminathan 141682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 141782527734SSukumar Swaminathan MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV); 141882527734SSukumar Swaminathan 1419*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EndianIN", (uint32_t *)iptr, 6, 0); 142082527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 142182527734SSukumar Swaminathan return (1); 142282527734SSukumar Swaminathan } 142382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 142482527734SSukumar Swaminathan MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL); 1425*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EndianOUT", (uint32_t *)iptr, 6, 0); 142682527734SSukumar Swaminathan 1427b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 1428b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, hba->sli.sli4.bootstrapmb.dma_handle) 1429b3660a96SSukumar Swaminathan != DDI_FM_OK) { 1430b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1431b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 1432b3660a96SSukumar Swaminathan "emlxs_init_bootstrap_mb: hdl=%p", 1433b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle); 1434b3660a96SSukumar Swaminathan return (1); 1435b3660a96SSukumar Swaminathan } 1436b3660a96SSukumar Swaminathan #endif 143782527734SSukumar Swaminathan hba->flag |= FC_BOOTSTRAPMB_INIT; 143882527734SSukumar Swaminathan return (0); 143982527734SSukumar Swaminathan 144082527734SSukumar Swaminathan } /* emlxs_init_bootstrap_mb() */ 144182527734SSukumar Swaminathan 144282527734SSukumar Swaminathan 144382527734SSukumar Swaminathan static uint32_t 144482527734SSukumar Swaminathan emlxs_sli4_hba_init(emlxs_hba_t *hba) 144582527734SSukumar Swaminathan { 144682527734SSukumar Swaminathan int rc; 1447*a9800bebSGarrett D'Amore uint16_t i; 144882527734SSukumar Swaminathan emlxs_port_t *vport; 144982527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 145082527734SSukumar Swaminathan CHANNEL *cp; 145182527734SSukumar Swaminathan 145282527734SSukumar Swaminathan /* Restart the adapter */ 145382527734SSukumar Swaminathan if (emlxs_sli4_hba_reset(hba, 1, 0, 0)) { 145482527734SSukumar Swaminathan return (1); 145582527734SSukumar Swaminathan } 145682527734SSukumar Swaminathan 145782527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 145882527734SSukumar Swaminathan cp = &hba->chan[i]; 145982527734SSukumar Swaminathan cp->iopath = (void *)&hba->sli.sli4.wq[i]; 146082527734SSukumar Swaminathan } 146182527734SSukumar Swaminathan 146282527734SSukumar Swaminathan /* Initialize all the port objects */ 146382527734SSukumar Swaminathan hba->vpi_base = 0; 146482527734SSukumar Swaminathan hba->vpi_max = 0; 146582527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 146682527734SSukumar Swaminathan vport = &VPORT(i); 146782527734SSukumar Swaminathan vport->hba = hba; 146882527734SSukumar Swaminathan vport->vpi = i; 1469*a9800bebSGarrett D'Amore 1470*a9800bebSGarrett D'Amore vport->VPIobj.index = i; 1471*a9800bebSGarrett D'Amore vport->VPIobj.VPI = i; 1472*a9800bebSGarrett D'Amore vport->VPIobj.port = vport; 147382527734SSukumar Swaminathan } 147482527734SSukumar Swaminathan 147582527734SSukumar Swaminathan /* Set the max node count */ 147682527734SSukumar Swaminathan if (hba->max_nodes == 0) { 147782527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 147882527734SSukumar Swaminathan hba->max_nodes = cfg[CFG_NUM_NODES].current; 147982527734SSukumar Swaminathan } else { 148082527734SSukumar Swaminathan hba->max_nodes = 4096; 148182527734SSukumar Swaminathan } 148282527734SSukumar Swaminathan } 148382527734SSukumar Swaminathan 148482527734SSukumar Swaminathan rc = emlxs_init_bootstrap_mb(hba); 148582527734SSukumar Swaminathan if (rc) { 148682527734SSukumar Swaminathan return (rc); 148782527734SSukumar Swaminathan } 148882527734SSukumar Swaminathan 148982527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[0] = FCOE_FCF_MAP0; 149082527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[1] = FCOE_FCF_MAP1; 149182527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[2] = FCOE_FCF_MAP2; 149282527734SSukumar Swaminathan 1493fe199829SSukumar Swaminathan /* Cache the UE MASK registers value for UE error detection */ 1494fe199829SSukumar Swaminathan hba->sli.sli4.ue_mask_lo = ddi_get32(hba->pci_acc_handle, 1495fe199829SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_LO_OFFSET)); 1496fe199829SSukumar Swaminathan hba->sli.sli4.ue_mask_hi = ddi_get32(hba->pci_acc_handle, 1497fe199829SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_HI_OFFSET)); 1498fe199829SSukumar Swaminathan 149982527734SSukumar Swaminathan return (0); 150082527734SSukumar Swaminathan 150182527734SSukumar Swaminathan } /* emlxs_sli4_hba_init() */ 150282527734SSukumar Swaminathan 150382527734SSukumar Swaminathan 150482527734SSukumar Swaminathan /*ARGSUSED*/ 150582527734SSukumar Swaminathan static uint32_t 150682527734SSukumar Swaminathan emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, uint32_t skip_post, 150782527734SSukumar Swaminathan uint32_t quiesce) 150882527734SSukumar Swaminathan { 150982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 151082527734SSukumar Swaminathan emlxs_port_t *vport; 151182527734SSukumar Swaminathan CHANNEL *cp; 151282527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 151382527734SSukumar Swaminathan MAILBOXQ mboxq; 151482527734SSukumar Swaminathan uint32_t i; 151582527734SSukumar Swaminathan uint32_t rc; 1516*a9800bebSGarrett D'Amore uint16_t channelno; 151782527734SSukumar Swaminathan 151882527734SSukumar Swaminathan if (!cfg[CFG_RESET_ENABLE].current) { 151982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 152082527734SSukumar Swaminathan "Adapter reset disabled."); 152182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 152282527734SSukumar Swaminathan 152382527734SSukumar Swaminathan return (1); 152482527734SSukumar Swaminathan } 152582527734SSukumar Swaminathan 152682527734SSukumar Swaminathan if (quiesce == 0) { 152782527734SSukumar Swaminathan emlxs_sli4_hba_kill(hba); 152882527734SSukumar Swaminathan 152982527734SSukumar Swaminathan /* 153082527734SSukumar Swaminathan * Initalize Hardware that will be used to bring 153182527734SSukumar Swaminathan * SLI4 online. 153282527734SSukumar Swaminathan */ 153382527734SSukumar Swaminathan rc = emlxs_init_bootstrap_mb(hba); 153482527734SSukumar Swaminathan if (rc) { 153582527734SSukumar Swaminathan return (rc); 153682527734SSukumar Swaminathan } 153782527734SSukumar Swaminathan } 153882527734SSukumar Swaminathan 153982527734SSukumar Swaminathan bzero((void *)&mboxq, sizeof (MAILBOXQ)); 154082527734SSukumar Swaminathan emlxs_mb_resetport(hba, &mboxq); 154182527734SSukumar Swaminathan 154282527734SSukumar Swaminathan if (quiesce == 0) { 154382527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, &mboxq, 154482527734SSukumar Swaminathan MBX_POLL, 0) != MBX_SUCCESS) { 154582527734SSukumar Swaminathan /* Timeout occurred */ 154682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 154782527734SSukumar Swaminathan "Timeout: RESET"); 154882527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 154982527734SSukumar Swaminathan /* Log a dump event - not supported */ 155082527734SSukumar Swaminathan return (1); 155182527734SSukumar Swaminathan } 155282527734SSukumar Swaminathan } else { 155382527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd4quiesce(hba, &mboxq, 155482527734SSukumar Swaminathan MBX_POLL, 0) != MBX_SUCCESS) { 155582527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 155682527734SSukumar Swaminathan /* Log a dump event - not supported */ 155782527734SSukumar Swaminathan return (1); 155882527734SSukumar Swaminathan } 155982527734SSukumar Swaminathan } 1560*a9800bebSGarrett D'Amore emlxs_data_dump(port, "resetPort", (uint32_t *)&mboxq, 12, 0); 156182527734SSukumar Swaminathan 156282527734SSukumar Swaminathan /* Reset the hba structure */ 156382527734SSukumar Swaminathan hba->flag &= FC_RESET_MASK; 156482527734SSukumar Swaminathan 156582527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 156682527734SSukumar Swaminathan cp = &hba->chan[channelno]; 156782527734SSukumar Swaminathan cp->hba = hba; 156882527734SSukumar Swaminathan cp->channelno = channelno; 156982527734SSukumar Swaminathan } 157082527734SSukumar Swaminathan 157182527734SSukumar Swaminathan hba->channel_tx_count = 0; 157282527734SSukumar Swaminathan hba->io_count = 0; 157382527734SSukumar Swaminathan hba->iodone_count = 0; 157482527734SSukumar Swaminathan hba->topology = 0; 157582527734SSukumar Swaminathan hba->linkspeed = 0; 157682527734SSukumar Swaminathan hba->heartbeat_active = 0; 157782527734SSukumar Swaminathan hba->discovery_timer = 0; 157882527734SSukumar Swaminathan hba->linkup_timer = 0; 157982527734SSukumar Swaminathan hba->loopback_tics = 0; 158082527734SSukumar Swaminathan 158182527734SSukumar Swaminathan /* Reset the port objects */ 158282527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 158382527734SSukumar Swaminathan vport = &VPORT(i); 158482527734SSukumar Swaminathan 158582527734SSukumar Swaminathan vport->flag &= EMLXS_PORT_RESET_MASK; 158682527734SSukumar Swaminathan vport->did = 0; 158782527734SSukumar Swaminathan vport->prev_did = 0; 158882527734SSukumar Swaminathan vport->lip_type = 0; 158982527734SSukumar Swaminathan bzero(&vport->fabric_sparam, sizeof (SERV_PARM)); 1590*a9800bebSGarrett D'Amore bzero(&vport->prev_fabric_sparam, sizeof (SERV_PARM)); 159182527734SSukumar Swaminathan 159282527734SSukumar Swaminathan bzero((caddr_t)&vport->node_base, sizeof (NODELIST)); 159382527734SSukumar Swaminathan vport->node_base.nlp_Rpi = 0; 159482527734SSukumar Swaminathan vport->node_base.nlp_DID = 0xffffff; 159582527734SSukumar Swaminathan vport->node_base.nlp_list_next = NULL; 159682527734SSukumar Swaminathan vport->node_base.nlp_list_prev = NULL; 159782527734SSukumar Swaminathan vport->node_base.nlp_active = 1; 159882527734SSukumar Swaminathan vport->node_count = 0; 159982527734SSukumar Swaminathan 160082527734SSukumar Swaminathan if (vport->ub_count < EMLXS_UB_TOKEN_OFFSET) { 160182527734SSukumar Swaminathan vport->ub_count = EMLXS_UB_TOKEN_OFFSET; 160282527734SSukumar Swaminathan } 160382527734SSukumar Swaminathan } 160482527734SSukumar Swaminathan 160582527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 160682527734SSukumar Swaminathan return (1); 160782527734SSukumar Swaminathan } 160882527734SSukumar Swaminathan 160982527734SSukumar Swaminathan return (0); 161082527734SSukumar Swaminathan 161182527734SSukumar Swaminathan } /* emlxs_sli4_hba_reset */ 161282527734SSukumar Swaminathan 161382527734SSukumar Swaminathan 161482527734SSukumar Swaminathan #define SGL_CMD 0 161582527734SSukumar Swaminathan #define SGL_RESP 1 161682527734SSukumar Swaminathan #define SGL_DATA 2 161782527734SSukumar Swaminathan #define SGL_LAST 0x80 161882527734SSukumar Swaminathan 161982527734SSukumar Swaminathan /*ARGSUSED*/ 162082527734SSukumar Swaminathan ULP_SGE64 * 162182527734SSukumar Swaminathan emlxs_pkt_to_sgl(emlxs_port_t *port, ULP_SGE64 *sge, fc_packet_t *pkt, 162282527734SSukumar Swaminathan uint32_t sgl_type, uint32_t *pcnt) 162382527734SSukumar Swaminathan { 162482527734SSukumar Swaminathan #ifdef DEBUG_SGE 162582527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 162682527734SSukumar Swaminathan #endif 162782527734SSukumar Swaminathan ddi_dma_cookie_t *cp; 162882527734SSukumar Swaminathan uint_t i; 162982527734SSukumar Swaminathan uint_t last; 163082527734SSukumar Swaminathan int32_t size; 163182527734SSukumar Swaminathan int32_t sge_size; 163282527734SSukumar Swaminathan uint64_t sge_addr; 163382527734SSukumar Swaminathan int32_t len; 163482527734SSukumar Swaminathan uint32_t cnt; 163582527734SSukumar Swaminathan uint_t cookie_cnt; 163682527734SSukumar Swaminathan ULP_SGE64 stage_sge; 163782527734SSukumar Swaminathan 163882527734SSukumar Swaminathan last = sgl_type & SGL_LAST; 163982527734SSukumar Swaminathan sgl_type &= ~SGL_LAST; 164082527734SSukumar Swaminathan 164182527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 164282527734SSukumar Swaminathan switch (sgl_type) { 164382527734SSukumar Swaminathan case SGL_CMD: 164482527734SSukumar Swaminathan cp = pkt->pkt_cmd_cookie; 164582527734SSukumar Swaminathan cookie_cnt = pkt->pkt_cmd_cookie_cnt; 164682527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 164782527734SSukumar Swaminathan break; 164882527734SSukumar Swaminathan 164982527734SSukumar Swaminathan case SGL_RESP: 165082527734SSukumar Swaminathan cp = pkt->pkt_resp_cookie; 165182527734SSukumar Swaminathan cookie_cnt = pkt->pkt_resp_cookie_cnt; 165282527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 165382527734SSukumar Swaminathan break; 165482527734SSukumar Swaminathan 165582527734SSukumar Swaminathan 165682527734SSukumar Swaminathan case SGL_DATA: 165782527734SSukumar Swaminathan cp = pkt->pkt_data_cookie; 165882527734SSukumar Swaminathan cookie_cnt = pkt->pkt_data_cookie_cnt; 165982527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 166082527734SSukumar Swaminathan break; 166182527734SSukumar Swaminathan } 166282527734SSukumar Swaminathan 166382527734SSukumar Swaminathan #else 166482527734SSukumar Swaminathan switch (sgl_type) { 166582527734SSukumar Swaminathan case SGL_CMD: 166682527734SSukumar Swaminathan cp = &pkt->pkt_cmd_cookie; 166782527734SSukumar Swaminathan cookie_cnt = 1; 166882527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 166982527734SSukumar Swaminathan break; 167082527734SSukumar Swaminathan 167182527734SSukumar Swaminathan case SGL_RESP: 167282527734SSukumar Swaminathan cp = &pkt->pkt_resp_cookie; 167382527734SSukumar Swaminathan cookie_cnt = 1; 167482527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 167582527734SSukumar Swaminathan break; 167682527734SSukumar Swaminathan 167782527734SSukumar Swaminathan 167882527734SSukumar Swaminathan case SGL_DATA: 167982527734SSukumar Swaminathan cp = &pkt->pkt_data_cookie; 168082527734SSukumar Swaminathan cookie_cnt = 1; 168182527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 168282527734SSukumar Swaminathan break; 168382527734SSukumar Swaminathan } 168482527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 168582527734SSukumar Swaminathan 168682527734SSukumar Swaminathan stage_sge.offset = 0; 168782527734SSukumar Swaminathan stage_sge.reserved = 0; 168882527734SSukumar Swaminathan stage_sge.last = 0; 168982527734SSukumar Swaminathan cnt = 0; 169082527734SSukumar Swaminathan for (i = 0; i < cookie_cnt && size > 0; i++, cp++) { 169182527734SSukumar Swaminathan 169282527734SSukumar Swaminathan sge_size = cp->dmac_size; 169382527734SSukumar Swaminathan sge_addr = cp->dmac_laddress; 169482527734SSukumar Swaminathan while (sge_size && size) { 169582527734SSukumar Swaminathan if (cnt) { 169682527734SSukumar Swaminathan /* Copy staged SGE before we build next one */ 169782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 169882527734SSukumar Swaminathan (uint8_t *)sge, sizeof (ULP_SGE64)); 169982527734SSukumar Swaminathan sge++; 170082527734SSukumar Swaminathan } 170182527734SSukumar Swaminathan len = MIN(EMLXS_MAX_SGE_SIZE, sge_size); 170282527734SSukumar Swaminathan len = MIN(size, len); 170382527734SSukumar Swaminathan 170482527734SSukumar Swaminathan stage_sge.addrHigh = 170582527734SSukumar Swaminathan PADDR_HI(sge_addr); 170682527734SSukumar Swaminathan stage_sge.addrLow = 170782527734SSukumar Swaminathan PADDR_LO(sge_addr); 170882527734SSukumar Swaminathan stage_sge.length = len; 170982527734SSukumar Swaminathan if (sgl_type == SGL_DATA) { 171082527734SSukumar Swaminathan stage_sge.offset = cnt; 171182527734SSukumar Swaminathan } 171282527734SSukumar Swaminathan #ifdef DEBUG_SGE 1713*a9800bebSGarrett D'Amore emlxs_data_dump(port, "SGE", (uint32_t *)&stage_sge, 171482527734SSukumar Swaminathan 4, 0); 171582527734SSukumar Swaminathan #endif 171682527734SSukumar Swaminathan sge_addr += len; 171782527734SSukumar Swaminathan sge_size -= len; 171882527734SSukumar Swaminathan 171982527734SSukumar Swaminathan cnt += len; 172082527734SSukumar Swaminathan size -= len; 172182527734SSukumar Swaminathan } 172282527734SSukumar Swaminathan } 172382527734SSukumar Swaminathan 172482527734SSukumar Swaminathan if (last) { 172582527734SSukumar Swaminathan stage_sge.last = 1; 172682527734SSukumar Swaminathan } 172782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 172882527734SSukumar Swaminathan sizeof (ULP_SGE64)); 1729*a9800bebSGarrett D'Amore 173082527734SSukumar Swaminathan sge++; 173182527734SSukumar Swaminathan 173282527734SSukumar Swaminathan *pcnt = cnt; 173382527734SSukumar Swaminathan return (sge); 173482527734SSukumar Swaminathan 173582527734SSukumar Swaminathan } /* emlxs_pkt_to_sgl */ 173682527734SSukumar Swaminathan 173782527734SSukumar Swaminathan 173882527734SSukumar Swaminathan /*ARGSUSED*/ 173982527734SSukumar Swaminathan uint32_t 174082527734SSukumar Swaminathan emlxs_sli4_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp) 174182527734SSukumar Swaminathan { 174282527734SSukumar Swaminathan fc_packet_t *pkt; 1743*a9800bebSGarrett D'Amore XRIobj_t *xrip; 174482527734SSukumar Swaminathan ULP_SGE64 *sge; 174582527734SSukumar Swaminathan emlxs_wqe_t *wqe; 174682527734SSukumar Swaminathan IOCBQ *iocbq; 174782527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 174882527734SSukumar Swaminathan uint32_t cmd_cnt; 174982527734SSukumar Swaminathan uint32_t resp_cnt; 175082527734SSukumar Swaminathan uint32_t cnt; 175182527734SSukumar Swaminathan 175282527734SSukumar Swaminathan iocbq = (IOCBQ *) &sbp->iocbq; 175382527734SSukumar Swaminathan wqe = &iocbq->wqe; 175482527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 1755*a9800bebSGarrett D'Amore xrip = sbp->xrip; 1756*a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 175782527734SSukumar Swaminathan 175882527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 175982527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 176082527734SSukumar Swaminathan #else 176182527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 176282527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 176382527734SSukumar Swaminathan 176482527734SSukumar Swaminathan iocbq = &sbp->iocbq; 176582527734SSukumar Swaminathan if (iocbq->flag & IOCB_FCP_CMD) { 176682527734SSukumar Swaminathan 176782527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 176882527734SSukumar Swaminathan return (1); 176982527734SSukumar Swaminathan } 177082527734SSukumar Swaminathan 177182527734SSukumar Swaminathan /* CMD payload */ 177282527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, SGL_CMD, &cmd_cnt); 177382527734SSukumar Swaminathan 177482527734SSukumar Swaminathan /* DATA payload */ 177582527734SSukumar Swaminathan if (pkt->pkt_datalen != 0) { 177682527734SSukumar Swaminathan /* RSP payload */ 177782527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 177882527734SSukumar Swaminathan SGL_RESP, &resp_cnt); 177982527734SSukumar Swaminathan 178082527734SSukumar Swaminathan /* Data portion */ 178182527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 178282527734SSukumar Swaminathan SGL_DATA | SGL_LAST, &cnt); 178382527734SSukumar Swaminathan } else { 178482527734SSukumar Swaminathan /* RSP payload */ 178582527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 178682527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 178782527734SSukumar Swaminathan } 178882527734SSukumar Swaminathan 178982527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrHigh = 179082527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 179182527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrLow = 179282527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 179382527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.tus.f.bdeSize = cmd_cnt; 179482527734SSukumar Swaminathan wqe->un.FcpCmd.PayloadLength = cmd_cnt + resp_cnt; 179582527734SSukumar Swaminathan 179682527734SSukumar Swaminathan } else { 179782527734SSukumar Swaminathan 179882527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 179982527734SSukumar Swaminathan /* CMD payload */ 180082527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 180182527734SSukumar Swaminathan SGL_CMD | SGL_LAST, &cmd_cnt); 180282527734SSukumar Swaminathan } else { 180382527734SSukumar Swaminathan /* CMD payload */ 180482527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 180582527734SSukumar Swaminathan SGL_CMD, &cmd_cnt); 180682527734SSukumar Swaminathan 180782527734SSukumar Swaminathan /* RSP payload */ 180882527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 180982527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 181082527734SSukumar Swaminathan wqe->un.GenReq.PayloadLength = cmd_cnt; 181182527734SSukumar Swaminathan } 181282527734SSukumar Swaminathan 181382527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrHigh = 181482527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 181582527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrLow = 181682527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 181782527734SSukumar Swaminathan wqe->un.GenReq.Payload.tus.f.bdeSize = cmd_cnt; 181882527734SSukumar Swaminathan } 181982527734SSukumar Swaminathan return (0); 182082527734SSukumar Swaminathan } /* emlxs_sli4_bde_setup */ 182182527734SSukumar Swaminathan 182282527734SSukumar Swaminathan 182382527734SSukumar Swaminathan 182482527734SSukumar Swaminathan 182582527734SSukumar Swaminathan static void 182682527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 182782527734SSukumar Swaminathan { 182882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 182982527734SSukumar Swaminathan emlxs_buf_t *sbp; 183082527734SSukumar Swaminathan uint32_t channelno; 183182527734SSukumar Swaminathan int32_t throttle; 183282527734SSukumar Swaminathan emlxs_wqe_t *wqe; 183382527734SSukumar Swaminathan emlxs_wqe_t *wqeslot; 183482527734SSukumar Swaminathan WQ_DESC_t *wq; 183582527734SSukumar Swaminathan uint32_t flag; 183682527734SSukumar Swaminathan uint32_t wqdb; 1837*a9800bebSGarrett D'Amore uint16_t next_wqe; 1838b3660a96SSukumar Swaminathan off_t offset; 183982527734SSukumar Swaminathan 184082527734SSukumar Swaminathan 184182527734SSukumar Swaminathan channelno = cp->channelno; 184282527734SSukumar Swaminathan wq = (WQ_DESC_t *)cp->iopath; 184382527734SSukumar Swaminathan 184482527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 184582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 184682527734SSukumar Swaminathan "ISSUE WQE channel: %x %p", channelno, wq); 184782527734SSukumar Swaminathan #endif 184882527734SSukumar Swaminathan 184982527734SSukumar Swaminathan throttle = 0; 185082527734SSukumar Swaminathan 185182527734SSukumar Swaminathan /* Check if FCP ring and adapter is not ready */ 185282527734SSukumar Swaminathan /* We may use any ring for FCP_CMD */ 185382527734SSukumar Swaminathan if (iocbq && (iocbq->flag & IOCB_FCP_CMD) && (hba->state != FC_READY)) { 185482527734SSukumar Swaminathan if (!(iocbq->flag & IOCB_SPECIAL) || !iocbq->port || 185582527734SSukumar Swaminathan !(((emlxs_port_t *)iocbq->port)->tgt_mode)) { 185682527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 185782527734SSukumar Swaminathan return; 185882527734SSukumar Swaminathan } 185982527734SSukumar Swaminathan } 186082527734SSukumar Swaminathan 186182527734SSukumar Swaminathan /* Attempt to acquire CMD_RING lock */ 1862*a9800bebSGarrett D'Amore if (mutex_tryenter(&EMLXS_QUE_LOCK(channelno)) == 0) { 186382527734SSukumar Swaminathan /* Queue it for later */ 186482527734SSukumar Swaminathan if (iocbq) { 186582527734SSukumar Swaminathan if ((hba->io_count - 186682527734SSukumar Swaminathan hba->channel_tx_count) > 10) { 186782527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 186882527734SSukumar Swaminathan return; 186982527734SSukumar Swaminathan } else { 187082527734SSukumar Swaminathan 1871*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_QUE_LOCK(channelno)); 187282527734SSukumar Swaminathan } 187382527734SSukumar Swaminathan } else { 187482527734SSukumar Swaminathan return; 187582527734SSukumar Swaminathan } 187682527734SSukumar Swaminathan } 1877*a9800bebSGarrett D'Amore /* EMLXS_QUE_LOCK acquired */ 187882527734SSukumar Swaminathan 187982527734SSukumar Swaminathan /* Throttle check only applies to non special iocb */ 188082527734SSukumar Swaminathan if (iocbq && (!(iocbq->flag & IOCB_SPECIAL))) { 188182527734SSukumar Swaminathan /* Check if HBA is full */ 188282527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 188382527734SSukumar Swaminathan if (throttle <= 0) { 188482527734SSukumar Swaminathan /* Hitting adapter throttle limit */ 188582527734SSukumar Swaminathan /* Queue it for later */ 188682527734SSukumar Swaminathan if (iocbq) { 188782527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 188882527734SSukumar Swaminathan } 188982527734SSukumar Swaminathan 189082527734SSukumar Swaminathan goto busy; 189182527734SSukumar Swaminathan } 189282527734SSukumar Swaminathan } 189382527734SSukumar Swaminathan 189482527734SSukumar Swaminathan /* Check to see if we have room for this WQE */ 189582527734SSukumar Swaminathan next_wqe = wq->host_index + 1; 189682527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 189782527734SSukumar Swaminathan next_wqe = 0; 189882527734SSukumar Swaminathan } 189982527734SSukumar Swaminathan 190082527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 190182527734SSukumar Swaminathan /* Queue it for later */ 190282527734SSukumar Swaminathan if (iocbq) { 190382527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 190482527734SSukumar Swaminathan } 190582527734SSukumar Swaminathan goto busy; 190682527734SSukumar Swaminathan } 190782527734SSukumar Swaminathan 190882527734SSukumar Swaminathan /* 190982527734SSukumar Swaminathan * We have a command ring slot available 191082527734SSukumar Swaminathan * Make sure we have an iocb to send 191182527734SSukumar Swaminathan */ 191282527734SSukumar Swaminathan if (iocbq) { 191382527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 191482527734SSukumar Swaminathan 191582527734SSukumar Swaminathan /* Check if the ring already has iocb's waiting */ 191682527734SSukumar Swaminathan if (cp->nodeq.q_first != NULL) { 191782527734SSukumar Swaminathan /* Put the current iocbq on the tx queue */ 191882527734SSukumar Swaminathan emlxs_tx_put(iocbq, 0); 191982527734SSukumar Swaminathan 192082527734SSukumar Swaminathan /* 192182527734SSukumar Swaminathan * Attempt to replace it with the next iocbq 192282527734SSukumar Swaminathan * in the tx queue 192382527734SSukumar Swaminathan */ 192482527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 0); 192582527734SSukumar Swaminathan } 192682527734SSukumar Swaminathan 192782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 192882527734SSukumar Swaminathan } else { 192982527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 193082527734SSukumar Swaminathan } 193182527734SSukumar Swaminathan 193282527734SSukumar Swaminathan sendit: 193382527734SSukumar Swaminathan /* Process each iocbq */ 193482527734SSukumar Swaminathan while (iocbq) { 193582527734SSukumar Swaminathan 193682527734SSukumar Swaminathan wqe = &iocbq->wqe; 193782527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 193882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 193982527734SSukumar Swaminathan "ISSUE QID %d WQE iotag: %x xri: %x", wq->qid, 194082527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 194182527734SSukumar Swaminathan #endif 194282527734SSukumar Swaminathan 194382527734SSukumar Swaminathan sbp = iocbq->sbp; 194482527734SSukumar Swaminathan if (sbp) { 194582527734SSukumar Swaminathan /* If exchange removed after wqe was prep'ed, drop it */ 1946*a9800bebSGarrett D'Amore if (!(sbp->xrip)) { 194782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 194882527734SSukumar Swaminathan "Xmit WQE iotag: %x xri: %x aborted", 194982527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 195082527734SSukumar Swaminathan 195182527734SSukumar Swaminathan /* Get next iocb from the tx queue */ 195282527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 195382527734SSukumar Swaminathan continue; 195482527734SSukumar Swaminathan } 195582527734SSukumar Swaminathan 195682527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_DELAY_REQUIRED) { 195782527734SSukumar Swaminathan 195882527734SSukumar Swaminathan /* Perform delay */ 195982527734SSukumar Swaminathan if ((channelno == hba->channel_els) && 196082527734SSukumar Swaminathan !(iocbq->flag & IOCB_FCP_CMD)) { 196182527734SSukumar Swaminathan drv_usecwait(100000); 196282527734SSukumar Swaminathan } else { 196382527734SSukumar Swaminathan drv_usecwait(20000); 196482527734SSukumar Swaminathan } 196582527734SSukumar Swaminathan } 196682527734SSukumar Swaminathan } 196782527734SSukumar Swaminathan 196882527734SSukumar Swaminathan /* 196982527734SSukumar Swaminathan * At this point, we have a command ring slot available 197082527734SSukumar Swaminathan * and an iocb to send 197182527734SSukumar Swaminathan */ 197282527734SSukumar Swaminathan wq->release_depth--; 197382527734SSukumar Swaminathan if (wq->release_depth == 0) { 197482527734SSukumar Swaminathan wq->release_depth = WQE_RELEASE_DEPTH; 197582527734SSukumar Swaminathan wqe->WQEC = 1; 197682527734SSukumar Swaminathan } 197782527734SSukumar Swaminathan 197882527734SSukumar Swaminathan 197982527734SSukumar Swaminathan HBASTATS.IocbIssued[channelno]++; 198082527734SSukumar Swaminathan 198182527734SSukumar Swaminathan /* Check for ULP pkt request */ 198282527734SSukumar Swaminathan if (sbp) { 198382527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 198482527734SSukumar Swaminathan 198582527734SSukumar Swaminathan if (sbp->node == NULL) { 198682527734SSukumar Swaminathan /* Set node to base node by default */ 198782527734SSukumar Swaminathan iocbq->node = (void *)&port->node_base; 198882527734SSukumar Swaminathan sbp->node = (void *)&port->node_base; 198982527734SSukumar Swaminathan } 199082527734SSukumar Swaminathan 199182527734SSukumar Swaminathan sbp->pkt_flags |= PACKET_IN_CHIPQ; 199282527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 199382527734SSukumar Swaminathan 199482527734SSukumar Swaminathan atomic_add_32(&hba->io_active, 1); 1995*a9800bebSGarrett D'Amore sbp->xrip->flag |= EMLXS_XRI_PENDING_IO; 199682527734SSukumar Swaminathan } 199782527734SSukumar Swaminathan 199882527734SSukumar Swaminathan 199982527734SSukumar Swaminathan /* Free the local iocb if there is no sbp tracking it */ 200082527734SSukumar Swaminathan if (sbp) { 200182527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 200282527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 200382527734SSukumar Swaminathan if (sbp->fct_cmd) { 200482527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 200582527734SSukumar Swaminathan EMLXS_FCT_IOCB_ISSUED); 200682527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 200782527734SSukumar Swaminathan icmd->ULPCOMMAND); 200882527734SSukumar Swaminathan } 200982527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 201082527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 201182527734SSukumar Swaminathan cp->hbaSendCmd_sbp++; 201282527734SSukumar Swaminathan iocbq->channel = cp; 201382527734SSukumar Swaminathan } else { 201482527734SSukumar Swaminathan cp->hbaSendCmd++; 201582527734SSukumar Swaminathan } 201682527734SSukumar Swaminathan 201782527734SSukumar Swaminathan flag = iocbq->flag; 201882527734SSukumar Swaminathan 201982527734SSukumar Swaminathan /* Send the iocb */ 202082527734SSukumar Swaminathan wqeslot = (emlxs_wqe_t *)wq->addr.virt; 202182527734SSukumar Swaminathan wqeslot += wq->host_index; 202282527734SSukumar Swaminathan 202382527734SSukumar Swaminathan wqe->CQId = wq->cqid; 202482527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)wqe, (uint8_t *)wqeslot, 202582527734SSukumar Swaminathan sizeof (emlxs_wqe_t)); 202682527734SSukumar Swaminathan #ifdef DEBUG_WQE 2027*a9800bebSGarrett D'Amore emlxs_data_dump(port, "WQE", (uint32_t *)wqe, 18, 0); 202882527734SSukumar Swaminathan #endif 2029b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 2030b3660a96SSukumar Swaminathan wq->addr.virt) - 2031b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 2032b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 2033b3660a96SSukumar Swaminathan 2034b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(wq->addr.dma_handle, offset, 203582527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 203682527734SSukumar Swaminathan 203782527734SSukumar Swaminathan /* Ring the WQ Doorbell */ 203882527734SSukumar Swaminathan wqdb = wq->qid; 203982527734SSukumar Swaminathan wqdb |= ((1 << 24) | (wq->host_index << 16)); 204082527734SSukumar Swaminathan 204182527734SSukumar Swaminathan 204282527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_WQDB_REG(hba), wqdb); 204382527734SSukumar Swaminathan wq->host_index = next_wqe; 204482527734SSukumar Swaminathan 204582527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 204682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 204782527734SSukumar Swaminathan "WQ RING: %08x", wqdb); 204882527734SSukumar Swaminathan #endif 204982527734SSukumar Swaminathan 205082527734SSukumar Swaminathan /* 205182527734SSukumar Swaminathan * After this, the sbp / iocb / wqe should not be 205282527734SSukumar Swaminathan * accessed in the xmit path. 205382527734SSukumar Swaminathan */ 205482527734SSukumar Swaminathan 205582527734SSukumar Swaminathan if (!sbp) { 2056*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 205782527734SSukumar Swaminathan } 205882527734SSukumar Swaminathan 205982527734SSukumar Swaminathan if (iocbq && (!(flag & IOCB_SPECIAL))) { 206082527734SSukumar Swaminathan /* Check if HBA is full */ 206182527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 206282527734SSukumar Swaminathan if (throttle <= 0) { 206382527734SSukumar Swaminathan goto busy; 206482527734SSukumar Swaminathan } 206582527734SSukumar Swaminathan } 206682527734SSukumar Swaminathan 206782527734SSukumar Swaminathan /* Check to see if we have room for another WQE */ 206882527734SSukumar Swaminathan next_wqe++; 206982527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 207082527734SSukumar Swaminathan next_wqe = 0; 207182527734SSukumar Swaminathan } 207282527734SSukumar Swaminathan 207382527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 207482527734SSukumar Swaminathan /* Queue it for later */ 207582527734SSukumar Swaminathan goto busy; 207682527734SSukumar Swaminathan } 207782527734SSukumar Swaminathan 207882527734SSukumar Swaminathan 207982527734SSukumar Swaminathan /* Get the next iocb from the tx queue if there is one */ 208082527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 208182527734SSukumar Swaminathan } 208282527734SSukumar Swaminathan 2083*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_QUE_LOCK(channelno)); 208482527734SSukumar Swaminathan 208582527734SSukumar Swaminathan return; 208682527734SSukumar Swaminathan 208782527734SSukumar Swaminathan busy: 208882527734SSukumar Swaminathan if (throttle <= 0) { 208982527734SSukumar Swaminathan HBASTATS.IocbThrottled++; 209082527734SSukumar Swaminathan } else { 209182527734SSukumar Swaminathan HBASTATS.IocbRingFull[channelno]++; 209282527734SSukumar Swaminathan } 209382527734SSukumar Swaminathan 2094*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_QUE_LOCK(channelno)); 209582527734SSukumar Swaminathan 209682527734SSukumar Swaminathan return; 209782527734SSukumar Swaminathan 209882527734SSukumar Swaminathan } /* emlxs_sli4_issue_iocb_cmd() */ 209982527734SSukumar Swaminathan 210082527734SSukumar Swaminathan 210182527734SSukumar Swaminathan /*ARGSUSED*/ 210282527734SSukumar Swaminathan static uint32_t 2103*a9800bebSGarrett D'Amore emlxs_sli4_issue_mq(emlxs_port_t *port, MAILBOX4 *mqe, MAILBOX *mb, 2104*a9800bebSGarrett D'Amore uint32_t tmo) 210582527734SSukumar Swaminathan { 2106*a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 210782527734SSukumar Swaminathan MAILBOXQ *mbq; 210882527734SSukumar Swaminathan MAILBOX4 *mb4; 210982527734SSukumar Swaminathan MATCHMAP *mp; 211082527734SSukumar Swaminathan uint32_t *iptr; 211182527734SSukumar Swaminathan uint32_t mqdb; 2112b3660a96SSukumar Swaminathan off_t offset; 211382527734SSukumar Swaminathan 211482527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 211582527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 211682527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 2117*a9800bebSGarrett D'Amore hba->mbox_mqe = (void *)mqe; 211882527734SSukumar Swaminathan 211982527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 212082527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 212182527734SSukumar Swaminathan /* 212282527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 212382527734SSukumar Swaminathan * into the mailbox area. 212482527734SSukumar Swaminathan */ 212582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 212682527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 212782527734SSukumar Swaminathan 212882527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0, 212982527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 213082527734SSukumar Swaminathan 2131*a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 2132*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMD", (uint32_t *)mqe, 2133*a9800bebSGarrett D'Amore 18, 0); 2134*a9800bebSGarrett D'Amore } 213582527734SSukumar Swaminathan } else { 213682527734SSukumar Swaminathan /* SLI_CONFIG and non-embedded */ 213782527734SSukumar Swaminathan 213882527734SSukumar Swaminathan /* 213982527734SSukumar Swaminathan * If this is not embedded, the MQ area 214082527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 214182527734SSukumar Swaminathan * non-embedded mailbox command. 214282527734SSukumar Swaminathan * mp will point to the actual mailbox command which 214382527734SSukumar Swaminathan * should be copied into the non-embedded area. 214482527734SSukumar Swaminathan */ 214582527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 214682527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 214782527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 214882527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 214982527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 215082527734SSukumar Swaminathan *iptr = mp->size; 215182527734SSukumar Swaminathan 215282527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 215382527734SSukumar Swaminathan 215482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 215582527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 215682527734SSukumar Swaminathan 215782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 215882527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 215982527734SSukumar Swaminathan 2160b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 2161b3660a96SSukumar Swaminathan hba->sli.sli4.mq.addr.virt) - 2162b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 2163b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 2164b3660a96SSukumar Swaminathan 2165b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset, 216682527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 216782527734SSukumar Swaminathan 2168*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX EXT", (uint32_t *)mqe, 12, 0); 216982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 217082527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, (uint32_t *)(mp->virt)); 2171*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 217282527734SSukumar Swaminathan } 217382527734SSukumar Swaminathan 217482527734SSukumar Swaminathan /* Ring the MQ Doorbell */ 217582527734SSukumar Swaminathan mqdb = hba->sli.sli4.mq.qid; 217682527734SSukumar Swaminathan mqdb |= ((1 << MQ_DB_POP_SHIFT) & MQ_DB_POP_MASK); 217782527734SSukumar Swaminathan 2178*a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 2179*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2180*a9800bebSGarrett D'Amore "MQ RING: %08x", mqdb); 2181*a9800bebSGarrett D'Amore } 218282527734SSukumar Swaminathan 218382527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MQDB_REG(hba), mqdb); 218482527734SSukumar Swaminathan return (MBX_SUCCESS); 218582527734SSukumar Swaminathan 218682527734SSukumar Swaminathan } /* emlxs_sli4_issue_mq() */ 218782527734SSukumar Swaminathan 218882527734SSukumar Swaminathan 218982527734SSukumar Swaminathan /*ARGSUSED*/ 219082527734SSukumar Swaminathan static uint32_t 219182527734SSukumar Swaminathan emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo) 219282527734SSukumar Swaminathan { 219382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 219482527734SSukumar Swaminathan MAILBOXQ *mbq; 219582527734SSukumar Swaminathan MAILBOX4 *mb4; 2196b3660a96SSukumar Swaminathan MATCHMAP *mp = NULL; 219782527734SSukumar Swaminathan uint32_t *iptr; 2198b3660a96SSukumar Swaminathan int nonembed = 0; 219982527734SSukumar Swaminathan 220082527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 220182527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 220282527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 2203*a9800bebSGarrett D'Amore hba->mbox_mqe = hba->sli.sli4.bootstrapmb.virt; 220482527734SSukumar Swaminathan 220582527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 220682527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 220782527734SSukumar Swaminathan /* 220882527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 220982527734SSukumar Swaminathan * into the bootstrap mailbox area. 221082527734SSukumar Swaminathan */ 221182527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 221282527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 221382527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 221482527734SSukumar Swaminathan 221582527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 221682527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORDEV); 2217*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMD", iptr, 18, 0); 221882527734SSukumar Swaminathan } else { 221982527734SSukumar Swaminathan /* 222082527734SSukumar Swaminathan * If this is not embedded, the bootstrap mailbox area 222182527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 222282527734SSukumar Swaminathan * non-embedded mailbox command. 222382527734SSukumar Swaminathan * mp will point to the actual mailbox command which 222482527734SSukumar Swaminathan * should be copied into the non-embedded area. 222582527734SSukumar Swaminathan */ 2226b3660a96SSukumar Swaminathan nonembed = 1; 222782527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 222882527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 222982527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 223082527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 223182527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 223282527734SSukumar Swaminathan *iptr = mp->size; 223382527734SSukumar Swaminathan 223482527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 223582527734SSukumar Swaminathan 223682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 223782527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 223882527734SSukumar Swaminathan 223982527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 224082527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 224182527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 224282527734SSukumar Swaminathan 224382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 224482527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 224582527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 224682527734SSukumar Swaminathan 2247*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX EXT", iptr, 12, 0); 224882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 224982527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, 225082527734SSukumar Swaminathan (uint32_t *)((uint8_t *)mp->virt)); 225182527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 2252*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 225382527734SSukumar Swaminathan } 225482527734SSukumar Swaminathan 225582527734SSukumar Swaminathan 225682527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 225782527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 225882527734SSukumar Swaminathan return (MBX_TIMEOUT); 225982527734SSukumar Swaminathan } 226082527734SSukumar Swaminathan 226182527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 226282527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 226382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 226482527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORKERNEL); 226582527734SSukumar Swaminathan 226682527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 226782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 226882527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 226982527734SSukumar Swaminathan 2270*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", iptr, 18, 0); 227182527734SSukumar Swaminathan 227282527734SSukumar Swaminathan } else { 227382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 227482527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 227582527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 227682527734SSukumar Swaminathan 227782527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 227882527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 227982527734SSukumar Swaminathan 228082527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 228182527734SSukumar Swaminathan 228282527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 228382527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 228482527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 228582527734SSukumar Swaminathan 2286*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", iptr, 12, 0); 228782527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 2288*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)iptr, 24, 0); 228982527734SSukumar Swaminathan } 229082527734SSukumar Swaminathan 2291b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 2292b3660a96SSukumar Swaminathan if (nonembed && mp) { 2293b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, mp->dma_handle) 2294b3660a96SSukumar Swaminathan != DDI_FM_OK) { 2295b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2296b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 2297b3660a96SSukumar Swaminathan "emlxs_sli4_issue_bootstrap: mp_hdl=%p", 2298b3660a96SSukumar Swaminathan mp->dma_handle); 2299b3660a96SSukumar Swaminathan return (MBXERR_DMA_ERROR); 2300b3660a96SSukumar Swaminathan } 2301b3660a96SSukumar Swaminathan } 2302b3660a96SSukumar Swaminathan 2303b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 2304b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle) 2305b3660a96SSukumar Swaminathan != DDI_FM_OK) { 2306b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2307b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 2308b3660a96SSukumar Swaminathan "emlxs_sli4_issue_bootstrap: hdl=%p", 2309b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle); 2310b3660a96SSukumar Swaminathan return (MBXERR_DMA_ERROR); 2311b3660a96SSukumar Swaminathan } 2312b3660a96SSukumar Swaminathan #endif 2313b3660a96SSukumar Swaminathan 231482527734SSukumar Swaminathan return (MBX_SUCCESS); 231582527734SSukumar Swaminathan 231682527734SSukumar Swaminathan } /* emlxs_sli4_issue_bootstrap() */ 231782527734SSukumar Swaminathan 231882527734SSukumar Swaminathan 231982527734SSukumar Swaminathan /*ARGSUSED*/ 232082527734SSukumar Swaminathan static uint32_t 232182527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 232282527734SSukumar Swaminathan uint32_t tmo) 232382527734SSukumar Swaminathan { 2324*a9800bebSGarrett D'Amore emlxs_port_t *port; 232582527734SSukumar Swaminathan MAILBOX4 *mb4; 232682527734SSukumar Swaminathan MAILBOX *mb; 232782527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 232882527734SSukumar Swaminathan MATCHMAP *mp; 232982527734SSukumar Swaminathan uint32_t *iptr; 233082527734SSukumar Swaminathan uint32_t rc; 233182527734SSukumar Swaminathan uint32_t i; 233282527734SSukumar Swaminathan uint32_t tmo_local; 233382527734SSukumar Swaminathan 2334*a9800bebSGarrett D'Amore if (!mbq->port) { 2335*a9800bebSGarrett D'Amore mbq->port = &PPORT; 2336*a9800bebSGarrett D'Amore } 2337*a9800bebSGarrett D'Amore 2338*a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 2339*a9800bebSGarrett D'Amore 234082527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mbq; 234182527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 234282527734SSukumar Swaminathan 234382527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 234482527734SSukumar Swaminathan rc = MBX_SUCCESS; 234582527734SSukumar Swaminathan 234682527734SSukumar Swaminathan /* Check for minimum timeouts */ 234782527734SSukumar Swaminathan switch (mb->mbxCommand) { 234882527734SSukumar Swaminathan /* Mailbox commands that erase/write flash */ 234982527734SSukumar Swaminathan case MBX_DOWN_LOAD: 235082527734SSukumar Swaminathan case MBX_UPDATE_CFG: 235182527734SSukumar Swaminathan case MBX_LOAD_AREA: 235282527734SSukumar Swaminathan case MBX_LOAD_EXP_ROM: 235382527734SSukumar Swaminathan case MBX_WRITE_NV: 235482527734SSukumar Swaminathan case MBX_FLASH_WR_ULA: 235582527734SSukumar Swaminathan case MBX_DEL_LD_ENTRY: 235682527734SSukumar Swaminathan case MBX_LOAD_SM: 235782527734SSukumar Swaminathan if (tmo < 300) { 235882527734SSukumar Swaminathan tmo = 300; 235982527734SSukumar Swaminathan } 236082527734SSukumar Swaminathan break; 236182527734SSukumar Swaminathan 236282527734SSukumar Swaminathan default: 236382527734SSukumar Swaminathan if (tmo < 30) { 236482527734SSukumar Swaminathan tmo = 30; 236582527734SSukumar Swaminathan } 236682527734SSukumar Swaminathan break; 236782527734SSukumar Swaminathan } 236882527734SSukumar Swaminathan 236982527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 237082527734SSukumar Swaminathan tmo_local = tmo * 100; 237182527734SSukumar Swaminathan 237282527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 237382527734SSukumar Swaminathan 237482527734SSukumar Swaminathan /* Adjust wait flag */ 237582527734SSukumar Swaminathan if (flag != MBX_NOWAIT) { 237682527734SSukumar Swaminathan if (hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED) { 237782527734SSukumar Swaminathan flag = MBX_SLEEP; 237882527734SSukumar Swaminathan } else { 237982527734SSukumar Swaminathan flag = MBX_POLL; 238082527734SSukumar Swaminathan } 238182527734SSukumar Swaminathan } else { 238282527734SSukumar Swaminathan /* Must have interrupts enabled to perform MBX_NOWAIT */ 238382527734SSukumar Swaminathan if (!(hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED)) { 238482527734SSukumar Swaminathan 238582527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 238682527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 238782527734SSukumar Swaminathan 238882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2389*a9800bebSGarrett D'Amore "Interrupts disabled. %s failed.", 239082527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 239182527734SSukumar Swaminathan 239282527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 239382527734SSukumar Swaminathan } 239482527734SSukumar Swaminathan } 239582527734SSukumar Swaminathan 2396bce54adfSSukumar Swaminathan /* Check for hardware error ; special case SLI_CONFIG */ 2397bce54adfSSukumar Swaminathan if ((hba->flag & FC_HARDWARE_ERROR) && 2398bce54adfSSukumar Swaminathan ! ((mb4->mbxCommand == MBX_SLI_CONFIG) && 2399bce54adfSSukumar Swaminathan (mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode == 2400bce54adfSSukumar Swaminathan COMMON_OPCODE_RESET))) { 240182527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 240282527734SSukumar Swaminathan 240382527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 240482527734SSukumar Swaminathan 240582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 240682527734SSukumar Swaminathan "Hardware error reported. %s failed. status=%x mb=%p", 240782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb); 240882527734SSukumar Swaminathan 240982527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 241082527734SSukumar Swaminathan } 241182527734SSukumar Swaminathan 241282527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 241382527734SSukumar Swaminathan /* If we are not polling, then queue it for later */ 241482527734SSukumar Swaminathan if (flag == MBX_NOWAIT) { 241582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 241682527734SSukumar Swaminathan "Busy. %s: mb=%p NoWait.", 241782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 241882527734SSukumar Swaminathan 241982527734SSukumar Swaminathan emlxs_mb_put(hba, mbq); 242082527734SSukumar Swaminathan 242182527734SSukumar Swaminathan HBASTATS.MboxBusy++; 242282527734SSukumar Swaminathan 242382527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 242482527734SSukumar Swaminathan 242582527734SSukumar Swaminathan return (MBX_BUSY); 242682527734SSukumar Swaminathan } 242782527734SSukumar Swaminathan 242882527734SSukumar Swaminathan while (hba->mbox_queue_flag) { 242982527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 243082527734SSukumar Swaminathan 243182527734SSukumar Swaminathan if (tmo_local-- == 0) { 243282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 243382527734SSukumar Swaminathan &emlxs_mbox_event_msg, 243482527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%d Waiting.", 243582527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 243682527734SSukumar Swaminathan tmo); 243782527734SSukumar Swaminathan 243882527734SSukumar Swaminathan /* Non-lethalStatus mailbox timeout */ 243982527734SSukumar Swaminathan /* Does not indicate a hardware error */ 244082527734SSukumar Swaminathan mb->mbxStatus = MBX_TIMEOUT; 244182527734SSukumar Swaminathan return (MBX_TIMEOUT); 244282527734SSukumar Swaminathan } 244382527734SSukumar Swaminathan 244482527734SSukumar Swaminathan DELAYMS(10); 244582527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 244682527734SSukumar Swaminathan } 244782527734SSukumar Swaminathan } 244882527734SSukumar Swaminathan 244982527734SSukumar Swaminathan /* Initialize mailbox area */ 245082527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 245182527734SSukumar Swaminathan 2452*a9800bebSGarrett D'Amore if (mb->mbxCommand == MBX_DOWN_LINK) { 2453*a9800bebSGarrett D'Amore hba->sli.sli4.flag |= EMLXS_SLI4_DOWN_LINK; 2454*a9800bebSGarrett D'Amore } 2455*a9800bebSGarrett D'Amore 245682527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 245782527734SSukumar Swaminathan switch (flag) { 245882527734SSukumar Swaminathan 245982527734SSukumar Swaminathan case MBX_NOWAIT: 246082527734SSukumar Swaminathan if (mb->mbxCommand != MBX_HEARTBEAT) { 246182527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 246282527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 246382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 246482527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 246582527734SSukumar Swaminathan "Sending. %s: mb=%p NoWait. embedded %d", 246682527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 246782527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 246882527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 246982527734SSukumar Swaminathan } 247082527734SSukumar Swaminathan } 247182527734SSukumar Swaminathan 247282527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 247382527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 247482527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 247582527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 247682527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 247782527734SSukumar Swaminathan } 247882527734SSukumar Swaminathan 247982527734SSukumar Swaminathan if (mbq->bp) { 248082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 248182527734SSukumar Swaminathan "BDE virt %p phys %p size x%x", 248282527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->virt, 248382527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->phys, 248482527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->size); 2485*a9800bebSGarrett D'Amore emlxs_data_dump(port, "DATA", 248682527734SSukumar Swaminathan (uint32_t *)(((MATCHMAP *)mbq->bp)->virt), 30, 0); 248782527734SSukumar Swaminathan } 2488*a9800bebSGarrett D'Amore rc = emlxs_sli4_issue_mq(port, (MAILBOX4 *)iptr, mb, tmo_local); 248982527734SSukumar Swaminathan break; 249082527734SSukumar Swaminathan 249182527734SSukumar Swaminathan case MBX_POLL: 249282527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 249382527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 249482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 249582527734SSukumar Swaminathan "Sending. %s: mb=%p Poll. embedded %d", 249682527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 249782527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 249882527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 249982527734SSukumar Swaminathan } 250082527734SSukumar Swaminathan 250182527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 250282527734SSukumar Swaminathan 250382527734SSukumar Swaminathan /* Clean up the mailbox area */ 250482527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 250582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 250682527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Poll. embedded %d", 250782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 250882527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 250982527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 251082527734SSukumar Swaminathan 251182527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 251282527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 251382527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 251482527734SSukumar Swaminathan 251582527734SSukumar Swaminathan } else { 251682527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 251782527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 251882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 251982527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 2520*a9800bebSGarrett D'Amore "Completed. %s: mb=%p status=%x Poll. " 252182527734SSukumar Swaminathan "embedded %d", 252282527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 252382527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 252482527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 252582527734SSukumar Swaminathan } 252682527734SSukumar Swaminathan 252782527734SSukumar Swaminathan /* Process the result */ 252882527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 252982527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 253082527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 253182527734SSukumar Swaminathan } 253282527734SSukumar Swaminathan } 253382527734SSukumar Swaminathan 253482527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 253582527734SSukumar Swaminathan } 253682527734SSukumar Swaminathan 253782527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 253882527734SSukumar Swaminathan if (mp) { 253982527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 254082527734SSukumar Swaminathan if (hdr_rsp->status) { 2541*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 2542*a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 2543*a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 2544*a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 2545*a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 2546*a9800bebSGarrett D'Amore 254782527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 254882527734SSukumar Swaminathan } 254982527734SSukumar Swaminathan } 255082527734SSukumar Swaminathan rc = mb->mbxStatus; 255182527734SSukumar Swaminathan 255282527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 255382527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 255482527734SSukumar Swaminathan if (mbq) { 255582527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 255682527734SSukumar Swaminathan i = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 255782527734SSukumar Swaminathan if ((i != MBX_BUSY) && (i != MBX_SUCCESS)) { 2558*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 255982527734SSukumar Swaminathan } 256082527734SSukumar Swaminathan } 256182527734SSukumar Swaminathan break; 256282527734SSukumar Swaminathan 256382527734SSukumar Swaminathan case MBX_SLEEP: 256482527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 256582527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 256682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 256782527734SSukumar Swaminathan "Sending. %s: mb=%p Sleep. embedded %d", 256882527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 256982527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 257082527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 257182527734SSukumar Swaminathan } 257282527734SSukumar Swaminathan 257382527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 257482527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 257582527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 257682527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 257782527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 257882527734SSukumar Swaminathan } 257982527734SSukumar Swaminathan 2580*a9800bebSGarrett D'Amore rc = emlxs_sli4_issue_mq(port, (MAILBOX4 *)iptr, mb, tmo_local); 258182527734SSukumar Swaminathan 258282527734SSukumar Swaminathan if (rc != MBX_SUCCESS) { 258382527734SSukumar Swaminathan break; 258482527734SSukumar Swaminathan } 258582527734SSukumar Swaminathan 258682527734SSukumar Swaminathan /* Wait for completion */ 258782527734SSukumar Swaminathan /* The driver clock is timing the mailbox. */ 258882527734SSukumar Swaminathan 258982527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 259082527734SSukumar Swaminathan while (!(mbq->flag & MBQ_COMPLETED)) { 259182527734SSukumar Swaminathan cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK); 259282527734SSukumar Swaminathan } 259382527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 259482527734SSukumar Swaminathan 259582527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 259682527734SSukumar Swaminathan if (mp) { 259782527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 259882527734SSukumar Swaminathan if (hdr_rsp->status) { 2599*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 2600*a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 2601*a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 2602*a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 2603*a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 2604*a9800bebSGarrett D'Amore 260582527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 260682527734SSukumar Swaminathan } 260782527734SSukumar Swaminathan } 260882527734SSukumar Swaminathan rc = mb->mbxStatus; 260982527734SSukumar Swaminathan 261082527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 261182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 261282527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Sleep. embedded %d", 261382527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 261482527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 261582527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 261682527734SSukumar Swaminathan } else { 261782527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 261882527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 261982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 262082527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 2621*a9800bebSGarrett D'Amore "Completed. %s: mb=%p status=%x Sleep. " 262282527734SSukumar Swaminathan "embedded %d", 262382527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 262482527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 262582527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 262682527734SSukumar Swaminathan } 262782527734SSukumar Swaminathan } 262882527734SSukumar Swaminathan break; 262982527734SSukumar Swaminathan } 263082527734SSukumar Swaminathan 263182527734SSukumar Swaminathan return (rc); 263282527734SSukumar Swaminathan 263382527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd() */ 263482527734SSukumar Swaminathan 263582527734SSukumar Swaminathan 263682527734SSukumar Swaminathan 263782527734SSukumar Swaminathan /*ARGSUSED*/ 263882527734SSukumar Swaminathan static uint32_t 263982527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 264082527734SSukumar Swaminathan uint32_t tmo) 264182527734SSukumar Swaminathan { 264282527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 264382527734SSukumar Swaminathan MAILBOX *mb; 264482527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 264582527734SSukumar Swaminathan MATCHMAP *mp; 264682527734SSukumar Swaminathan uint32_t rc; 264782527734SSukumar Swaminathan uint32_t tmo_local; 264882527734SSukumar Swaminathan 264982527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 265082527734SSukumar Swaminathan 265182527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 265282527734SSukumar Swaminathan rc = MBX_SUCCESS; 265382527734SSukumar Swaminathan 265482527734SSukumar Swaminathan if (tmo < 30) { 265582527734SSukumar Swaminathan tmo = 30; 265682527734SSukumar Swaminathan } 265782527734SSukumar Swaminathan 265882527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 265982527734SSukumar Swaminathan tmo_local = tmo * 100; 266082527734SSukumar Swaminathan 266182527734SSukumar Swaminathan flag = MBX_POLL; 266282527734SSukumar Swaminathan 266382527734SSukumar Swaminathan /* Check for hardware error */ 266482527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 266582527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 266682527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 266782527734SSukumar Swaminathan } 266882527734SSukumar Swaminathan 266982527734SSukumar Swaminathan /* Initialize mailbox area */ 267082527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 267182527734SSukumar Swaminathan 267282527734SSukumar Swaminathan switch (flag) { 267382527734SSukumar Swaminathan 267482527734SSukumar Swaminathan case MBX_POLL: 267582527734SSukumar Swaminathan 267682527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 267782527734SSukumar Swaminathan 267882527734SSukumar Swaminathan /* Clean up the mailbox area */ 267982527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 268082527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 268182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 268282527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 268382527734SSukumar Swaminathan 268482527734SSukumar Swaminathan } else { 268582527734SSukumar Swaminathan /* Process the result */ 268682527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 268782527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 268882527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 268982527734SSukumar Swaminathan } 269082527734SSukumar Swaminathan } 269182527734SSukumar Swaminathan 269282527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 269382527734SSukumar Swaminathan } 269482527734SSukumar Swaminathan 269582527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 269682527734SSukumar Swaminathan if (mp) { 269782527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 269882527734SSukumar Swaminathan if (hdr_rsp->status) { 2699*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 2700*a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 2701*a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 2702*a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 2703*a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 2704*a9800bebSGarrett D'Amore 270582527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 270682527734SSukumar Swaminathan } 270782527734SSukumar Swaminathan } 270882527734SSukumar Swaminathan rc = mb->mbxStatus; 270982527734SSukumar Swaminathan 271082527734SSukumar Swaminathan break; 271182527734SSukumar Swaminathan } 271282527734SSukumar Swaminathan 271382527734SSukumar Swaminathan return (rc); 271482527734SSukumar Swaminathan 271582527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd4quiesce() */ 271682527734SSukumar Swaminathan 271782527734SSukumar Swaminathan 271882527734SSukumar Swaminathan 271982527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 272082527734SSukumar Swaminathan /*ARGSUSED*/ 272182527734SSukumar Swaminathan static uint32_t 272282527734SSukumar Swaminathan emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, emlxs_buf_t *cmd_sbp, int channel) 272382527734SSukumar Swaminathan { 272482527734SSukumar Swaminathan return (IOERR_NO_RESOURCES); 272582527734SSukumar Swaminathan 272682527734SSukumar Swaminathan } /* emlxs_sli4_prep_fct_iocb() */ 272782527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 272882527734SSukumar Swaminathan 272982527734SSukumar Swaminathan 273082527734SSukumar Swaminathan /*ARGSUSED*/ 273182527734SSukumar Swaminathan extern uint32_t 273282527734SSukumar Swaminathan emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel) 273382527734SSukumar Swaminathan { 273482527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 273582527734SSukumar Swaminathan fc_packet_t *pkt; 273682527734SSukumar Swaminathan CHANNEL *cp; 2737*a9800bebSGarrett D'Amore RPIobj_t *rpip; 2738*a9800bebSGarrett D'Amore XRIobj_t *xrip; 273982527734SSukumar Swaminathan emlxs_wqe_t *wqe; 274082527734SSukumar Swaminathan IOCBQ *iocbq; 274182527734SSukumar Swaminathan NODELIST *node; 274282527734SSukumar Swaminathan uint16_t iotag; 274382527734SSukumar Swaminathan uint32_t did; 2744b3660a96SSukumar Swaminathan off_t offset; 274582527734SSukumar Swaminathan 274682527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 274782527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 274882527734SSukumar Swaminathan cp = &hba->chan[channel]; 274982527734SSukumar Swaminathan 275082527734SSukumar Swaminathan iocbq = &sbp->iocbq; 275182527734SSukumar Swaminathan iocbq->channel = (void *) cp; 275282527734SSukumar Swaminathan iocbq->port = (void *) port; 275382527734SSukumar Swaminathan 275482527734SSukumar Swaminathan wqe = &iocbq->wqe; 275582527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 275682527734SSukumar Swaminathan 275782527734SSukumar Swaminathan /* Find target node object */ 275882527734SSukumar Swaminathan node = (NODELIST *)iocbq->node; 2759*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 276082527734SSukumar Swaminathan 2761*a9800bebSGarrett D'Amore if (!rpip) { 276282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 276382527734SSukumar Swaminathan "Unable to find rpi. did=0x%x", did); 276482527734SSukumar Swaminathan 276582527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 276682527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 276782527734SSukumar Swaminathan return (0xff); 276882527734SSukumar Swaminathan } 276982527734SSukumar Swaminathan 277082527734SSukumar Swaminathan sbp->channel = cp; 277182527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 2772*a9800bebSGarrett D'Amore xrip = emlxs_sli4_alloc_xri(hba, sbp, rpip); 277382527734SSukumar Swaminathan 2774*a9800bebSGarrett D'Amore if (!xrip) { 277582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 277682527734SSukumar Swaminathan "Adapter Busy. Unable to allocate exchange. did=0x%x", did); 277782527734SSukumar Swaminathan 277882527734SSukumar Swaminathan return (FC_TRAN_BUSY); 277982527734SSukumar Swaminathan } 278082527734SSukumar Swaminathan sbp->bmp = NULL; 278182527734SSukumar Swaminathan iotag = sbp->iotag; 278282527734SSukumar Swaminathan 278382527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 278482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, /* DEBUG */ 2785*a9800bebSGarrett D'Amore "Prep FCP iotag: %x xri: %x", iotag, xrip->XRI); 278682527734SSukumar Swaminathan #endif 278782527734SSukumar Swaminathan 278882527734SSukumar Swaminathan /* Indicate this is a FCP cmd */ 278982527734SSukumar Swaminathan iocbq->flag |= IOCB_FCP_CMD; 279082527734SSukumar Swaminathan 279182527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 2792*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, sbp, xrip, 1); 279382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 279482527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 279582527734SSukumar Swaminathan 279682527734SSukumar Swaminathan return (FC_TRAN_BUSY); 279782527734SSukumar Swaminathan } 279882527734SSukumar Swaminathan 279982527734SSukumar Swaminathan 280082527734SSukumar Swaminathan /* DEBUG */ 280182527734SSukumar Swaminathan #ifdef DEBUG_FCP 280282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2803*a9800bebSGarrett D'Amore "SGLaddr virt %p phys %p size %d", xrip->SGList.virt, 2804*a9800bebSGarrett D'Amore xrip->SGList.phys, pkt->pkt_datalen); 2805*a9800bebSGarrett D'Amore emlxs_data_dump(port, "SGL", (uint32_t *)xrip->SGList.virt, 20, 0); 280682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 280782527734SSukumar Swaminathan "CMD virt %p len %d:%d:%d", 280882527734SSukumar Swaminathan pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen, pkt->pkt_datalen); 2809*a9800bebSGarrett D'Amore emlxs_data_dump(port, "FCP CMD", (uint32_t *)pkt->pkt_cmd, 10, 0); 281082527734SSukumar Swaminathan #endif 281182527734SSukumar Swaminathan 2812b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 2813*a9800bebSGarrett D'Amore xrip->SGList.virt) - 2814b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 2815b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 2816b3660a96SSukumar Swaminathan 2817*a9800bebSGarrett D'Amore EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 2818*a9800bebSGarrett D'Amore xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 281982527734SSukumar Swaminathan 282082527734SSukumar Swaminathan /* if device is FCP-2 device, set the following bit */ 282182527734SSukumar Swaminathan /* that says to run the FC-TAPE protocol. */ 282282527734SSukumar Swaminathan if (node->nlp_fcp_info & NLP_FCP_2_DEVICE) { 282382527734SSukumar Swaminathan wqe->ERP = 1; 282482527734SSukumar Swaminathan } 282582527734SSukumar Swaminathan 282682527734SSukumar Swaminathan if (pkt->pkt_datalen == 0) { 282782527734SSukumar Swaminathan wqe->Command = CMD_FCP_ICMND64_CR; 282882527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 282982527734SSukumar Swaminathan } else if (pkt->pkt_tran_type == FC_PKT_FCP_READ) { 283082527734SSukumar Swaminathan wqe->Command = CMD_FCP_IREAD64_CR; 283182527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 283282527734SSukumar Swaminathan wqe->PU = PARM_READ_CHECK; 283382527734SSukumar Swaminathan } else { 283482527734SSukumar Swaminathan wqe->Command = CMD_FCP_IWRITE64_CR; 283582527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_OUT; 283682527734SSukumar Swaminathan } 283782527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount = pkt->pkt_datalen; 283882527734SSukumar Swaminathan 2839*a9800bebSGarrett D'Amore wqe->ContextTag = rpip->RPI; 284082527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 2841*a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 284282527734SSukumar Swaminathan wqe->Timer = 284382527734SSukumar Swaminathan ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 284482527734SSukumar Swaminathan 284582527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 284682527734SSukumar Swaminathan wqe->CCPE = 1; 284782527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 284882527734SSukumar Swaminathan } 284982527734SSukumar Swaminathan 285082527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 285182527734SSukumar Swaminathan case FC_TRAN_CLASS2: 285282527734SSukumar Swaminathan wqe->Class = CLASS2; 285382527734SSukumar Swaminathan break; 285482527734SSukumar Swaminathan case FC_TRAN_CLASS3: 285582527734SSukumar Swaminathan default: 285682527734SSukumar Swaminathan wqe->Class = CLASS3; 285782527734SSukumar Swaminathan break; 285882527734SSukumar Swaminathan } 285982527734SSukumar Swaminathan sbp->class = wqe->Class; 286082527734SSukumar Swaminathan wqe->RequestTag = iotag; 286181a990d5SRichard Lowe wqe->CQId = 0x3ff; /* default CQ for response */ 286282527734SSukumar Swaminathan return (FC_SUCCESS); 286382527734SSukumar Swaminathan } /* emlxs_sli4_prep_fcp_iocb() */ 286482527734SSukumar Swaminathan 286582527734SSukumar Swaminathan 286682527734SSukumar Swaminathan /*ARGSUSED*/ 286782527734SSukumar Swaminathan static uint32_t 286882527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 286982527734SSukumar Swaminathan { 287082527734SSukumar Swaminathan return (FC_TRAN_BUSY); 287182527734SSukumar Swaminathan 287282527734SSukumar Swaminathan } /* emlxs_sli4_prep_ip_iocb() */ 287382527734SSukumar Swaminathan 287482527734SSukumar Swaminathan 287582527734SSukumar Swaminathan /*ARGSUSED*/ 287682527734SSukumar Swaminathan static uint32_t 287782527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 287882527734SSukumar Swaminathan { 287982527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 288082527734SSukumar Swaminathan fc_packet_t *pkt; 288182527734SSukumar Swaminathan IOCBQ *iocbq; 288282527734SSukumar Swaminathan IOCB *iocb; 288382527734SSukumar Swaminathan emlxs_wqe_t *wqe; 2884*a9800bebSGarrett D'Amore FCFIobj_t *fcfp; 2885*a9800bebSGarrett D'Amore RPIobj_t *rpip = NULL; 2886*a9800bebSGarrett D'Amore XRIobj_t *xrip; 288782527734SSukumar Swaminathan CHANNEL *cp; 288882527734SSukumar Swaminathan uint32_t did; 288982527734SSukumar Swaminathan uint32_t cmd; 289082527734SSukumar Swaminathan ULP_SGE64 stage_sge; 289182527734SSukumar Swaminathan ULP_SGE64 *sge; 289282527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 289382527734SSukumar Swaminathan ddi_dma_cookie_t *cp_resp; 289482527734SSukumar Swaminathan emlxs_node_t *node; 2895b3660a96SSukumar Swaminathan off_t offset; 289682527734SSukumar Swaminathan 289782527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 289882527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 289982527734SSukumar Swaminathan 290082527734SSukumar Swaminathan iocbq = &sbp->iocbq; 290182527734SSukumar Swaminathan wqe = &iocbq->wqe; 290282527734SSukumar Swaminathan iocb = &iocbq->iocb; 290382527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 290482527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 290582527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 290682527734SSukumar Swaminathan 290782527734SSukumar Swaminathan /* Initalize iocbq */ 290882527734SSukumar Swaminathan iocbq->port = (void *) port; 290982527734SSukumar Swaminathan iocbq->channel = (void *) cp; 291082527734SSukumar Swaminathan 291182527734SSukumar Swaminathan sbp->channel = cp; 291282527734SSukumar Swaminathan sbp->bmp = NULL; 291382527734SSukumar Swaminathan 291482527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 291582527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 291682527734SSukumar Swaminathan cp_resp = pkt->pkt_resp_cookie; 291782527734SSukumar Swaminathan #else 291882527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 291982527734SSukumar Swaminathan cp_resp = &pkt->pkt_resp_cookie; 292082527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 292182527734SSukumar Swaminathan 292282527734SSukumar Swaminathan /* CMD payload */ 292382527734SSukumar Swaminathan sge = &stage_sge; 292482527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_cmd->dmac_laddress); 292582527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_cmd->dmac_laddress); 292682527734SSukumar Swaminathan sge->length = pkt->pkt_cmdlen; 292782527734SSukumar Swaminathan sge->offset = 0; 2928*a9800bebSGarrett D'Amore sge->reserved = 0; 292982527734SSukumar Swaminathan 293082527734SSukumar Swaminathan /* Initalize iocb */ 293182527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 293282527734SSukumar Swaminathan /* ELS Response */ 293382527734SSukumar Swaminathan 2934*a9800bebSGarrett D'Amore xrip = emlxs_sli4_register_xri(hba, sbp, 2935*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.rx_id); 293682527734SSukumar Swaminathan 2937*a9800bebSGarrett D'Amore if (!xrip) { 293882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 293982527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 294082527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 294182527734SSukumar Swaminathan 294282527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 294382527734SSukumar Swaminathan IOERR_NO_XRI, 0); 294482527734SSukumar Swaminathan return (0xff); 294582527734SSukumar Swaminathan } 294682527734SSukumar Swaminathan 2947*a9800bebSGarrett D'Amore rpip = xrip->rpip; 294882527734SSukumar Swaminathan 2949*a9800bebSGarrett D'Amore if (!rpip) { 295082527734SSukumar Swaminathan /* This means that we had a node registered */ 295182527734SSukumar Swaminathan /* when the unsol request came in but the node */ 295282527734SSukumar Swaminathan /* has since been unregistered. */ 295382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 295482527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 295582527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 295682527734SSukumar Swaminathan 295782527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 295882527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 295982527734SSukumar Swaminathan return (0xff); 296082527734SSukumar Swaminathan } 296182527734SSukumar Swaminathan 296282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 296382527734SSukumar Swaminathan "Prep ELS XRI: xri=%x iotag=%x oxid=%x rpi=%x", 2964*a9800bebSGarrett D'Amore xrip->XRI, xrip->iotag, xrip->rx_id, rpip->RPI); 296582527734SSukumar Swaminathan 296682527734SSukumar Swaminathan wqe->Command = CMD_XMIT_ELS_RSP64_CX; 296782527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 296882527734SSukumar Swaminathan 296982527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrHigh = sge->addrHigh; 297082527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrLow = sge->addrLow; 297182527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 297282527734SSukumar Swaminathan 297382527734SSukumar Swaminathan wqe->un.ElsRsp.RemoteId = did; 297482527734SSukumar Swaminathan wqe->PU = 0x3; 297582527734SSukumar Swaminathan 297682527734SSukumar Swaminathan sge->last = 1; 297782527734SSukumar Swaminathan /* Now sge is fully staged */ 297882527734SSukumar Swaminathan 2979*a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 298082527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 298182527734SSukumar Swaminathan sizeof (ULP_SGE64)); 298282527734SSukumar Swaminathan 2983*a9800bebSGarrett D'Amore wqe->ContextTag = port->VPIobj.VPI; 298482527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 2985*a9800bebSGarrett D'Amore wqe->OXId = xrip->rx_id; 298682527734SSukumar Swaminathan 298782527734SSukumar Swaminathan } else { 298882527734SSukumar Swaminathan /* ELS Request */ 298982527734SSukumar Swaminathan 299082527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 2991*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 2992*a9800bebSGarrett D'Amore fcfp = port->VPIobj.vfip->fcfp; 299382527734SSukumar Swaminathan 2994*a9800bebSGarrett D'Amore if (!rpip) { 2995*a9800bebSGarrett D'Amore rpip = port->VPIobj.rpip; 299682527734SSukumar Swaminathan } 299782527734SSukumar Swaminathan 299882527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 2999*a9800bebSGarrett D'Amore xrip = emlxs_sli4_alloc_xri(hba, sbp, rpip); 300082527734SSukumar Swaminathan 3001*a9800bebSGarrett D'Amore if (!xrip) { 300282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3003*a9800bebSGarrett D'Amore "Adapter Busy. Unable to allocate exchange. " 300482527734SSukumar Swaminathan "did=0x%x", did); 300582527734SSukumar Swaminathan 300682527734SSukumar Swaminathan return (FC_TRAN_BUSY); 300782527734SSukumar Swaminathan } 300882527734SSukumar Swaminathan 300982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3010*a9800bebSGarrett D'Amore "Prep ELS XRI: xri=%x iotag=%x rpi=%x", xrip->XRI, 3011*a9800bebSGarrett D'Amore xrip->iotag, rpip->RPI); 301282527734SSukumar Swaminathan 301382527734SSukumar Swaminathan wqe->Command = CMD_ELS_REQUEST64_CR; 301482527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_ELS; 301582527734SSukumar Swaminathan 301682527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrHigh = sge->addrHigh; 301782527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrLow = sge->addrLow; 301882527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 301982527734SSukumar Swaminathan 302082527734SSukumar Swaminathan /* setup for rsp */ 302182527734SSukumar Swaminathan iocb->un.elsreq64.remoteID = (did == BCAST_DID) ? 0 : did; 302282527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 302382527734SSukumar Swaminathan 302482527734SSukumar Swaminathan sge->last = 0; 302582527734SSukumar Swaminathan 3026*a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 302782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 302882527734SSukumar Swaminathan sizeof (ULP_SGE64)); 302982527734SSukumar Swaminathan 303082527734SSukumar Swaminathan wqe->un.ElsCmd.PayloadLength = 303182527734SSukumar Swaminathan pkt->pkt_cmdlen; /* Byte offset of rsp data */ 303282527734SSukumar Swaminathan 303382527734SSukumar Swaminathan /* RSP payload */ 303482527734SSukumar Swaminathan sge = &stage_sge; 303582527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_resp->dmac_laddress); 303682527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_resp->dmac_laddress); 303782527734SSukumar Swaminathan sge->length = pkt->pkt_rsplen; 3038b3660a96SSukumar Swaminathan sge->offset = 0; 303982527734SSukumar Swaminathan sge->last = 1; 304082527734SSukumar Swaminathan /* Now sge is fully staged */ 304182527734SSukumar Swaminathan 3042*a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 304382527734SSukumar Swaminathan sge++; 304482527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 304582527734SSukumar Swaminathan sizeof (ULP_SGE64)); 304682527734SSukumar Swaminathan #ifdef DEBUG_ELS 304782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 304882527734SSukumar Swaminathan "SGLaddr virt %p phys %p", 3049*a9800bebSGarrett D'Amore xrip->SGList.virt, xrip->SGList.phys); 305082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 305182527734SSukumar Swaminathan "PAYLOAD virt %p phys %p", 305282527734SSukumar Swaminathan pkt->pkt_cmd, cp_cmd->dmac_laddress); 3053*a9800bebSGarrett D'Amore emlxs_data_dump(port, "SGL", (uint32_t *)xrip->SGList.virt, 3054*a9800bebSGarrett D'Amore 12, 0); 305582527734SSukumar Swaminathan #endif 305682527734SSukumar Swaminathan 305782527734SSukumar Swaminathan cmd = *((uint32_t *)pkt->pkt_cmd); 305882527734SSukumar Swaminathan cmd &= ELS_CMD_MASK; 305982527734SSukumar Swaminathan 306082527734SSukumar Swaminathan switch (cmd) { 306182527734SSukumar Swaminathan case ELS_CMD_FLOGI: 306282527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 3063*a9800bebSGarrett D'Amore wqe->ContextTag = fcfp->FCFI; 306482527734SSukumar Swaminathan wqe->ContextType = WQE_FCFI_CONTEXT; 306582527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 306682527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 306782527734SSukumar Swaminathan wqe->ELSId |= WQE_ELSID_FLOGI; 306882527734SSukumar Swaminathan } 306982527734SSukumar Swaminathan break; 307082527734SSukumar Swaminathan case ELS_CMD_FDISC: 307182527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 3072*a9800bebSGarrett D'Amore wqe->ContextTag = port->VPIobj.VPI; 307382527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 307482527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 307582527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 307682527734SSukumar Swaminathan wqe->ELSId |= WQE_ELSID_FDISC; 307782527734SSukumar Swaminathan } 307882527734SSukumar Swaminathan break; 307982527734SSukumar Swaminathan case ELS_CMD_LOGO: 3080*a9800bebSGarrett D'Amore if (did == FABRIC_DID) { 3081*a9800bebSGarrett D'Amore wqe->ContextTag = fcfp->FCFI; 3082*a9800bebSGarrett D'Amore wqe->ContextType = WQE_FCFI_CONTEXT; 3083*a9800bebSGarrett D'Amore if (hba->flag & FC_FIP_SUPPORTED) { 3084*a9800bebSGarrett D'Amore wqe->CmdType |= WQE_TYPE_MASK_FIP; 3085*a9800bebSGarrett D'Amore wqe->ELSId |= WQE_ELSID_LOGO; 3086*a9800bebSGarrett D'Amore } 3087*a9800bebSGarrett D'Amore } else { 3088*a9800bebSGarrett D'Amore wqe->ContextTag = port->VPIobj.VPI; 3089*a9800bebSGarrett D'Amore wqe->ContextType = WQE_VPI_CONTEXT; 309082527734SSukumar Swaminathan } 309182527734SSukumar Swaminathan break; 309282527734SSukumar Swaminathan 309382527734SSukumar Swaminathan case ELS_CMD_SCR: 309482527734SSukumar Swaminathan case ELS_CMD_PLOGI: 309582527734SSukumar Swaminathan case ELS_CMD_PRLI: 309682527734SSukumar Swaminathan default: 3097*a9800bebSGarrett D'Amore wqe->ContextTag = port->VPIobj.VPI; 309882527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 309982527734SSukumar Swaminathan break; 310082527734SSukumar Swaminathan } 310182527734SSukumar Swaminathan wqe->un.ElsCmd.RemoteId = did; 310282527734SSukumar Swaminathan wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 310382527734SSukumar Swaminathan } 310482527734SSukumar Swaminathan 3105b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3106*a9800bebSGarrett D'Amore xrip->SGList.virt) - 3107b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3108b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3109b3660a96SSukumar Swaminathan 3110*a9800bebSGarrett D'Amore EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 3111*a9800bebSGarrett D'Amore xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 311282527734SSukumar Swaminathan 311382527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 311482527734SSukumar Swaminathan wqe->CCPE = 1; 311582527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 311682527734SSukumar Swaminathan } 311782527734SSukumar Swaminathan 311882527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 311982527734SSukumar Swaminathan case FC_TRAN_CLASS2: 312082527734SSukumar Swaminathan wqe->Class = CLASS2; 312182527734SSukumar Swaminathan break; 312282527734SSukumar Swaminathan case FC_TRAN_CLASS3: 312382527734SSukumar Swaminathan default: 312482527734SSukumar Swaminathan wqe->Class = CLASS3; 312582527734SSukumar Swaminathan break; 312682527734SSukumar Swaminathan } 312782527734SSukumar Swaminathan sbp->class = wqe->Class; 3128*a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 3129*a9800bebSGarrett D'Amore wqe->RequestTag = xrip->iotag; 313082527734SSukumar Swaminathan wqe->CQId = 0x3ff; 313182527734SSukumar Swaminathan return (FC_SUCCESS); 313282527734SSukumar Swaminathan 313382527734SSukumar Swaminathan } /* emlxs_sli4_prep_els_iocb() */ 313482527734SSukumar Swaminathan 313582527734SSukumar Swaminathan 313682527734SSukumar Swaminathan /*ARGSUSED*/ 313782527734SSukumar Swaminathan static uint32_t 313882527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 313982527734SSukumar Swaminathan { 314082527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 314182527734SSukumar Swaminathan fc_packet_t *pkt; 314282527734SSukumar Swaminathan IOCBQ *iocbq; 314382527734SSukumar Swaminathan IOCB *iocb; 314482527734SSukumar Swaminathan emlxs_wqe_t *wqe; 314582527734SSukumar Swaminathan NODELIST *node = NULL; 314682527734SSukumar Swaminathan CHANNEL *cp; 3147*a9800bebSGarrett D'Amore RPIobj_t *rpip; 3148*a9800bebSGarrett D'Amore XRIobj_t *xrip; 314982527734SSukumar Swaminathan uint32_t did; 3150b3660a96SSukumar Swaminathan off_t offset; 315182527734SSukumar Swaminathan 315282527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 315382527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 315482527734SSukumar Swaminathan 315582527734SSukumar Swaminathan iocbq = &sbp->iocbq; 315682527734SSukumar Swaminathan wqe = &iocbq->wqe; 315782527734SSukumar Swaminathan iocb = &iocbq->iocb; 315882527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 315982527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 316082527734SSukumar Swaminathan 316182527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 316282527734SSukumar Swaminathan 316382527734SSukumar Swaminathan iocbq->port = (void *) port; 316482527734SSukumar Swaminathan iocbq->channel = (void *) cp; 316582527734SSukumar Swaminathan 316682527734SSukumar Swaminathan sbp->bmp = NULL; 316782527734SSukumar Swaminathan sbp->channel = cp; 316882527734SSukumar Swaminathan 316982527734SSukumar Swaminathan /* Initalize wqe */ 317082527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 317182527734SSukumar Swaminathan /* CT Response */ 317282527734SSukumar Swaminathan 3173*a9800bebSGarrett D'Amore xrip = emlxs_sli4_register_xri(hba, sbp, 3174*a9800bebSGarrett D'Amore pkt->pkt_cmd_fhdr.rx_id); 317582527734SSukumar Swaminathan 3176*a9800bebSGarrett D'Amore if (!xrip) { 317782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 317882527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 317982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 318082527734SSukumar Swaminathan 318182527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 318282527734SSukumar Swaminathan IOERR_NO_XRI, 0); 318382527734SSukumar Swaminathan return (0xff); 318482527734SSukumar Swaminathan } 318582527734SSukumar Swaminathan 3186*a9800bebSGarrett D'Amore rpip = xrip->rpip; 318782527734SSukumar Swaminathan 3188*a9800bebSGarrett D'Amore if (!rpip) { 318982527734SSukumar Swaminathan /* This means that we had a node registered */ 319082527734SSukumar Swaminathan /* when the unsol request came in but the node */ 319182527734SSukumar Swaminathan /* has since been unregistered. */ 319282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 319382527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 319482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 319582527734SSukumar Swaminathan 319682527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 319782527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 319882527734SSukumar Swaminathan return (0xff); 319982527734SSukumar Swaminathan } 320082527734SSukumar Swaminathan 320182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3202*a9800bebSGarrett D'Amore "Prep CT XRI: xri=%x iotag=%x oxid=%x", xrip->XRI, 3203*a9800bebSGarrett D'Amore xrip->iotag, xrip->rx_id); 320482527734SSukumar Swaminathan 320582527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 320682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 320782527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 320882527734SSukumar Swaminathan 320982527734SSukumar Swaminathan return (FC_TRAN_BUSY); 321082527734SSukumar Swaminathan } 321182527734SSukumar Swaminathan 321282527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 321382527734SSukumar Swaminathan wqe->Command = CMD_XMIT_SEQUENCE64_CR; 321482527734SSukumar Swaminathan wqe->un.XmitSeq.la = 1; 321582527734SSukumar Swaminathan 321682527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_LAST_SEQ) { 321782527734SSukumar Swaminathan wqe->un.XmitSeq.ls = 1; 321882527734SSukumar Swaminathan } 321982527734SSukumar Swaminathan 322082527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_SEQ_INITIATIVE) { 322182527734SSukumar Swaminathan wqe->un.XmitSeq.si = 1; 322282527734SSukumar Swaminathan } 322382527734SSukumar Swaminathan 322482527734SSukumar Swaminathan wqe->un.XmitSeq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 322582527734SSukumar Swaminathan wqe->un.XmitSeq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 322682527734SSukumar Swaminathan wqe->un.XmitSeq.Type = pkt->pkt_cmd_fhdr.type; 3227*a9800bebSGarrett D'Amore wqe->OXId = xrip->rx_id; 322862379b58SSukumar Swaminathan wqe->XC = 0; /* xri_tag is a new exchange */ 322982527734SSukumar Swaminathan wqe->CmdSpecific[0] = wqe->un.GenReq.Payload.tus.f.bdeSize; 323082527734SSukumar Swaminathan 323182527734SSukumar Swaminathan } else { 323282527734SSukumar Swaminathan /* CT Request */ 323382527734SSukumar Swaminathan 323482527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 3235*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 323682527734SSukumar Swaminathan 3237*a9800bebSGarrett D'Amore if (!rpip) { 323882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 3239*a9800bebSGarrett D'Amore "Unable to find rpi. did=0x%x rpi=%x", 3240*a9800bebSGarrett D'Amore did, node->nlp_Rpi); 324182527734SSukumar Swaminathan 324282527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 324382527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 324482527734SSukumar Swaminathan return (0xff); 324582527734SSukumar Swaminathan } 324682527734SSukumar Swaminathan 324782527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 3248*a9800bebSGarrett D'Amore xrip = emlxs_sli4_alloc_xri(hba, sbp, rpip); 324982527734SSukumar Swaminathan 3250*a9800bebSGarrett D'Amore if (!xrip) { 325182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3252*a9800bebSGarrett D'Amore "Adapter Busy. Unable to allocate exchange. " 325382527734SSukumar Swaminathan "did=0x%x", did); 325482527734SSukumar Swaminathan 325582527734SSukumar Swaminathan return (FC_TRAN_BUSY); 325682527734SSukumar Swaminathan } 325782527734SSukumar Swaminathan 325882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3259*a9800bebSGarrett D'Amore "Prep CT XRI: %x iotag %x", xrip->XRI, xrip->iotag); 326082527734SSukumar Swaminathan 326182527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 326282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 326382527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 326482527734SSukumar Swaminathan 3265*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, sbp, xrip, 1); 326682527734SSukumar Swaminathan return (FC_TRAN_BUSY); 326782527734SSukumar Swaminathan } 326882527734SSukumar Swaminathan 326982527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 327082527734SSukumar Swaminathan wqe->Command = CMD_GEN_REQUEST64_CR; 327182527734SSukumar Swaminathan wqe->un.GenReq.la = 1; 327282527734SSukumar Swaminathan wqe->un.GenReq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 327382527734SSukumar Swaminathan wqe->un.GenReq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 327482527734SSukumar Swaminathan wqe->un.GenReq.Type = pkt->pkt_cmd_fhdr.type; 327582527734SSukumar Swaminathan wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 327682527734SSukumar Swaminathan 327782527734SSukumar Swaminathan #ifdef DEBUG_CT 327882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3279*a9800bebSGarrett D'Amore "SGLaddr virt %p phys %p", xrip->SGList.virt, 3280*a9800bebSGarrett D'Amore xrip->SGList.phys); 3281*a9800bebSGarrett D'Amore emlxs_data_dump(port, "SGL", (uint32_t *)xrip->SGList.virt, 3282*a9800bebSGarrett D'Amore 12, 0); 328382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 328482527734SSukumar Swaminathan "CMD virt %p len %d:%d", 328582527734SSukumar Swaminathan pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen); 3286*a9800bebSGarrett D'Amore emlxs_data_dump(port, "DATA", (uint32_t *)pkt->pkt_cmd, 20, 0); 328782527734SSukumar Swaminathan #endif /* DEBUG_CT */ 328882527734SSukumar Swaminathan } 328982527734SSukumar Swaminathan 329082527734SSukumar Swaminathan /* Setup for rsp */ 329182527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 329282527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Type = pkt->pkt_cmd_fhdr.type; 329382527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Dfctl = pkt->pkt_cmd_fhdr.df_ctl; 329482527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 329582527734SSukumar Swaminathan 3296b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3297*a9800bebSGarrett D'Amore xrip->SGList.virt) - 3298b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3299b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3300b3660a96SSukumar Swaminathan 3301*a9800bebSGarrett D'Amore EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 3302*a9800bebSGarrett D'Amore xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 330382527734SSukumar Swaminathan 3304*a9800bebSGarrett D'Amore wqe->ContextTag = rpip->RPI; 330582527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 3306*a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 330782527734SSukumar Swaminathan 330882527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 330982527734SSukumar Swaminathan wqe->CCPE = 1; 331082527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 331182527734SSukumar Swaminathan } 331282527734SSukumar Swaminathan 331382527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 331482527734SSukumar Swaminathan case FC_TRAN_CLASS2: 331582527734SSukumar Swaminathan wqe->Class = CLASS2; 331682527734SSukumar Swaminathan break; 331782527734SSukumar Swaminathan case FC_TRAN_CLASS3: 331882527734SSukumar Swaminathan default: 331982527734SSukumar Swaminathan wqe->Class = CLASS3; 332082527734SSukumar Swaminathan break; 332182527734SSukumar Swaminathan } 332282527734SSukumar Swaminathan sbp->class = wqe->Class; 3323*a9800bebSGarrett D'Amore wqe->RequestTag = xrip->iotag; 332481a990d5SRichard Lowe wqe->CQId = 0x3ff; 332582527734SSukumar Swaminathan return (FC_SUCCESS); 332682527734SSukumar Swaminathan 332782527734SSukumar Swaminathan } /* emlxs_sli4_prep_ct_iocb() */ 332882527734SSukumar Swaminathan 332982527734SSukumar Swaminathan 333082527734SSukumar Swaminathan /*ARGSUSED*/ 333182527734SSukumar Swaminathan static int 3332*a9800bebSGarrett D'Amore emlxs_sli4_read_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 333382527734SSukumar Swaminathan { 333482527734SSukumar Swaminathan uint32_t *ptr; 333582527734SSukumar Swaminathan EQE_u eqe; 333682527734SSukumar Swaminathan int rc = 0; 3337b3660a96SSukumar Swaminathan off_t offset; 333882527734SSukumar Swaminathan 333982527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 334082527734SSukumar Swaminathan ptr = eq->addr.virt; 334182527734SSukumar Swaminathan ptr += eq->host_index; 334282527734SSukumar Swaminathan 3343b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3344b3660a96SSukumar Swaminathan eq->addr.virt) - 3345b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3346b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3347b3660a96SSukumar Swaminathan 3348b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset, 334982527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 335082527734SSukumar Swaminathan 335182527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 335282527734SSukumar Swaminathan 3353*a9800bebSGarrett D'Amore eqe.word = *ptr; 3354*a9800bebSGarrett D'Amore eqe.word = BE_SWAP32(eqe.word); 335582527734SSukumar Swaminathan 3356*a9800bebSGarrett D'Amore if (eqe.word & EQE_VALID) { 3357*a9800bebSGarrett D'Amore rc = 1; 335882527734SSukumar Swaminathan } 335982527734SSukumar Swaminathan 336082527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 336182527734SSukumar Swaminathan 336282527734SSukumar Swaminathan return (rc); 336382527734SSukumar Swaminathan 3364*a9800bebSGarrett D'Amore } /* emlxs_sli4_read_eq */ 336582527734SSukumar Swaminathan 336682527734SSukumar Swaminathan 336782527734SSukumar Swaminathan /*ARGSUSED*/ 336882527734SSukumar Swaminathan static void 336982527734SSukumar Swaminathan emlxs_sli4_poll_intr(emlxs_hba_t *hba, uint32_t att_bit) 337082527734SSukumar Swaminathan { 337182527734SSukumar Swaminathan int rc = 0; 337282527734SSukumar Swaminathan int i; 337382527734SSukumar Swaminathan char arg[] = {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}; 337482527734SSukumar Swaminathan char arg2; 337582527734SSukumar Swaminathan 337682527734SSukumar Swaminathan /* 337782527734SSukumar Swaminathan * Poll the eqe to see if the valid bit is set or not 337882527734SSukumar Swaminathan */ 337982527734SSukumar Swaminathan 338082527734SSukumar Swaminathan for (;;) { 338182527734SSukumar Swaminathan if (hba->intr_type == DDI_INTR_TYPE_FIXED) { 338282527734SSukumar Swaminathan /* only poll eqe0 */ 3383*a9800bebSGarrett D'Amore rc = emlxs_sli4_read_eq(hba, 338482527734SSukumar Swaminathan &hba->sli.sli4.eq[0]); 338582527734SSukumar Swaminathan if (rc == 1) { 338682527734SSukumar Swaminathan (void) bcopy((char *)&arg[0], 338782527734SSukumar Swaminathan (char *)&arg2, sizeof (char)); 338882527734SSukumar Swaminathan break; 338982527734SSukumar Swaminathan } 339082527734SSukumar Swaminathan } else { 339182527734SSukumar Swaminathan /* poll every msi vector */ 339282527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 3393*a9800bebSGarrett D'Amore rc = emlxs_sli4_read_eq(hba, 339482527734SSukumar Swaminathan &hba->sli.sli4.eq[i]); 339582527734SSukumar Swaminathan 339682527734SSukumar Swaminathan if (rc == 1) { 339782527734SSukumar Swaminathan break; 339882527734SSukumar Swaminathan } 339982527734SSukumar Swaminathan } 340082527734SSukumar Swaminathan if ((i != hba->intr_count) && (rc == 1)) { 340182527734SSukumar Swaminathan (void) bcopy((char *)&arg[i], 340282527734SSukumar Swaminathan (char *)&arg2, sizeof (char)); 340382527734SSukumar Swaminathan break; 340482527734SSukumar Swaminathan } 340582527734SSukumar Swaminathan } 340682527734SSukumar Swaminathan } 340782527734SSukumar Swaminathan 340882527734SSukumar Swaminathan /* process it here */ 340982527734SSukumar Swaminathan rc = emlxs_sli4_msi_intr((char *)hba, (char *)&arg2); 341082527734SSukumar Swaminathan 341182527734SSukumar Swaminathan return; 341282527734SSukumar Swaminathan 341382527734SSukumar Swaminathan } /* emlxs_sli4_poll_intr() */ 341482527734SSukumar Swaminathan 341582527734SSukumar Swaminathan 341682527734SSukumar Swaminathan /*ARGSUSED*/ 341782527734SSukumar Swaminathan static void 341882527734SSukumar Swaminathan emlxs_sli4_process_async_event(emlxs_hba_t *hba, CQE_ASYNC_t *cqe) 341982527734SSukumar Swaminathan { 342082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 342182527734SSukumar Swaminathan 3422*a9800bebSGarrett D'Amore /* Save the event tag */ 3423*a9800bebSGarrett D'Amore hba->link_event_tag = cqe->un.link.event_tag; 342482527734SSukumar Swaminathan 342582527734SSukumar Swaminathan switch (cqe->event_code) { 342682527734SSukumar Swaminathan case ASYNC_EVENT_CODE_LINK_STATE: 3427*a9800bebSGarrett D'Amore switch (cqe->un.link.link_status) { 342882527734SSukumar Swaminathan case ASYNC_EVENT_PHYS_LINK_UP: 342982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3430*a9800bebSGarrett D'Amore "Link Async Event: PHYS_LINK_UP. val=%d type=%x", 3431*a9800bebSGarrett D'Amore cqe->valid, cqe->event_type); 343282527734SSukumar Swaminathan break; 343382527734SSukumar Swaminathan 343482527734SSukumar Swaminathan case ASYNC_EVENT_PHYS_LINK_DOWN: 343582527734SSukumar Swaminathan case ASYNC_EVENT_LOGICAL_LINK_DOWN: 3436*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3437*a9800bebSGarrett D'Amore "Link Async Event: LINK_DOWN. val=%d type=%x", 3438*a9800bebSGarrett D'Amore cqe->valid, cqe->event_type); 3439*a9800bebSGarrett D'Amore 3440*a9800bebSGarrett D'Amore (void) emlxs_fcf_linkdown_notify(port); 3441*a9800bebSGarrett D'Amore 3442*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_PORT_LOCK); 3443*a9800bebSGarrett D'Amore hba->sli.sli4.flag &= ~EMLXS_SLI4_DOWN_LINK; 3444*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 344582527734SSukumar Swaminathan break; 344682527734SSukumar Swaminathan 344782527734SSukumar Swaminathan case ASYNC_EVENT_LOGICAL_LINK_UP: 3448*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3449*a9800bebSGarrett D'Amore "Link Async Event: LOGICAL_LINK_UP. val=%d type=%x", 3450*a9800bebSGarrett D'Amore cqe->valid, cqe->event_type); 345182527734SSukumar Swaminathan 3452*a9800bebSGarrett D'Amore if (cqe->un.link.port_speed == PHY_1GHZ_LINK) { 3453*a9800bebSGarrett D'Amore hba->linkspeed = LA_1GHZ_LINK; 3454*a9800bebSGarrett D'Amore } else { 3455*a9800bebSGarrett D'Amore hba->linkspeed = LA_10GHZ_LINK; 345682527734SSukumar Swaminathan } 3457*a9800bebSGarrett D'Amore hba->topology = TOPOLOGY_PT_PT; 3458*a9800bebSGarrett D'Amore hba->qos_linkspeed = cqe->un.link.qos_link_speed; 3459*a9800bebSGarrett D'Amore 3460*a9800bebSGarrett D'Amore (void) emlxs_fcf_linkup_notify(port); 346182527734SSukumar Swaminathan break; 346282527734SSukumar Swaminathan } 346382527734SSukumar Swaminathan break; 346482527734SSukumar Swaminathan case ASYNC_EVENT_CODE_FCOE_FIP: 3465*a9800bebSGarrett D'Amore switch (cqe->un.fcoe.evt_type) { 346682527734SSukumar Swaminathan case ASYNC_EVENT_NEW_FCF_DISC: 346782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3468*a9800bebSGarrett D'Amore "FCOE Async Event: FCF_FOUND %d:%d", 3469*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 3470*a9800bebSGarrett D'Amore 3471*a9800bebSGarrett D'Amore (void) emlxs_fcf_found_notify(port, 3472*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 347382527734SSukumar Swaminathan break; 347482527734SSukumar Swaminathan case ASYNC_EVENT_FCF_TABLE_FULL: 3475*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3476*a9800bebSGarrett D'Amore "FCOE Async Event: FCFTAB_FULL %d:%d", 3477*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 3478*a9800bebSGarrett D'Amore 3479*a9800bebSGarrett D'Amore (void) emlxs_fcf_full_notify(port); 348082527734SSukumar Swaminathan break; 348182527734SSukumar Swaminathan case ASYNC_EVENT_FCF_DEAD: 348282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3483*a9800bebSGarrett D'Amore "FCOE Async Event: FCF_LOST %d:%d", 3484*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 3485*a9800bebSGarrett D'Amore 3486*a9800bebSGarrett D'Amore (void) emlxs_fcf_lost_notify(port, 3487*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 348882527734SSukumar Swaminathan break; 348982527734SSukumar Swaminathan case ASYNC_EVENT_VIRT_LINK_CLEAR: 349082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3491*a9800bebSGarrett D'Amore "FCOE Async Event: CVL %d", 3492*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 3493*a9800bebSGarrett D'Amore 3494*a9800bebSGarrett D'Amore (void) emlxs_fcf_cvl_notify(port, 3495*a9800bebSGarrett D'Amore (cqe->un.fcoe.ref_index - hba->vpi_base)); 3496*a9800bebSGarrett D'Amore break; 3497*a9800bebSGarrett D'Amore 3498*a9800bebSGarrett D'Amore case ASYNC_EVENT_FCF_MODIFIED: 3499*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3500*a9800bebSGarrett D'Amore "FCOE Async Event: FCF_CHANGED %d", 3501*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 3502*a9800bebSGarrett D'Amore 3503*a9800bebSGarrett D'Amore (void) emlxs_fcf_changed_notify(port, 3504*a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 350582527734SSukumar Swaminathan break; 350682527734SSukumar Swaminathan } 350782527734SSukumar Swaminathan break; 350882527734SSukumar Swaminathan case ASYNC_EVENT_CODE_DCBX: 350982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3510*a9800bebSGarrett D'Amore "DCBX Async Event Code %d: Not supported", 351182527734SSukumar Swaminathan cqe->event_code); 351282527734SSukumar Swaminathan break; 3513*a9800bebSGarrett D'Amore case ASYNC_EVENT_CODE_GRP_5: 3514*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3515*a9800bebSGarrett D'Amore "Group 5 Async Event type %d", cqe->event_type); 3516*a9800bebSGarrett D'Amore if (cqe->event_type == ASYNC_EVENT_QOS_SPEED) { 3517*a9800bebSGarrett D'Amore hba->qos_linkspeed = cqe->un.qos.qos_link_speed; 3518*a9800bebSGarrett D'Amore } 3519*a9800bebSGarrett D'Amore break; 352082527734SSukumar Swaminathan default: 352182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 352282527734SSukumar Swaminathan "Unknown Async Event Code %d", cqe->event_code); 352382527734SSukumar Swaminathan break; 352482527734SSukumar Swaminathan } 352582527734SSukumar Swaminathan 352682527734SSukumar Swaminathan } /* emlxs_sli4_process_async_event() */ 352782527734SSukumar Swaminathan 352882527734SSukumar Swaminathan 352982527734SSukumar Swaminathan /*ARGSUSED*/ 353082527734SSukumar Swaminathan static void 353182527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe) 353282527734SSukumar Swaminathan { 353382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 353482527734SSukumar Swaminathan MAILBOX4 *mb; 353582527734SSukumar Swaminathan MATCHMAP *mbox_bp; 353682527734SSukumar Swaminathan MATCHMAP *mbox_nonembed; 3537*a9800bebSGarrett D'Amore MAILBOXQ *mbq = NULL; 353882527734SSukumar Swaminathan uint32_t size; 353982527734SSukumar Swaminathan uint32_t *iptr; 354082527734SSukumar Swaminathan int rc; 3541b3660a96SSukumar Swaminathan off_t offset; 354282527734SSukumar Swaminathan 354382527734SSukumar Swaminathan if (cqe->consumed && !cqe->completed) { 354482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3545*a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Entry consumed but not completed"); 354682527734SSukumar Swaminathan return; 354782527734SSukumar Swaminathan } 354882527734SSukumar Swaminathan 3549*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_PORT_LOCK); 355082527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 355182527734SSukumar Swaminathan case 0: 355282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg, 3553*a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. No mailbox active."); 3554*a9800bebSGarrett D'Amore 3555*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 355682527734SSukumar Swaminathan return; 355782527734SSukumar Swaminathan 355882527734SSukumar Swaminathan case MBX_POLL: 355982527734SSukumar Swaminathan 356082527734SSukumar Swaminathan /* Mark mailbox complete, this should wake up any polling */ 356182527734SSukumar Swaminathan /* threads. This can happen if interrupts are enabled while */ 356282527734SSukumar Swaminathan /* a polled mailbox command is outstanding. If we don't set */ 356382527734SSukumar Swaminathan /* MBQ_COMPLETED here, the polling thread may wait until */ 356482527734SSukumar Swaminathan /* timeout error occurs */ 356582527734SSukumar Swaminathan 356682527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 356782527734SSukumar Swaminathan mbq = (MAILBOXQ *)hba->mbox_mbq; 356882527734SSukumar Swaminathan if (mbq) { 3569*a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 357082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3571*a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Completing Polled command."); 357282527734SSukumar Swaminathan mbq->flag |= MBQ_COMPLETED; 357382527734SSukumar Swaminathan } 357482527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 357582527734SSukumar Swaminathan 3576*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 357782527734SSukumar Swaminathan return; 357882527734SSukumar Swaminathan 357982527734SSukumar Swaminathan case MBX_SLEEP: 358082527734SSukumar Swaminathan case MBX_NOWAIT: 3581*a9800bebSGarrett D'Amore /* Check mbox_timer, it acts as a service flag too */ 3582*a9800bebSGarrett D'Amore /* The first to service the mbox queue will clear the timer */ 3583*a9800bebSGarrett D'Amore if (hba->mbox_timer) { 3584*a9800bebSGarrett D'Amore hba->mbox_timer = 0; 3585*a9800bebSGarrett D'Amore 3586*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_MBOX_LOCK); 3587*a9800bebSGarrett D'Amore mbq = (MAILBOXQ *)hba->mbox_mbq; 3588*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_MBOX_LOCK); 3589*a9800bebSGarrett D'Amore } 3590*a9800bebSGarrett D'Amore 3591*a9800bebSGarrett D'Amore if (!mbq) { 3592*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3593*a9800bebSGarrett D'Amore "Mailbox event. No service required."); 3594*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 3595*a9800bebSGarrett D'Amore return; 3596*a9800bebSGarrett D'Amore } 3597*a9800bebSGarrett D'Amore 359882527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 3599*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 360082527734SSukumar Swaminathan break; 360182527734SSukumar Swaminathan 360282527734SSukumar Swaminathan default: 360382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 3604*a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Invalid Mailbox flag (%x).", 3605*a9800bebSGarrett D'Amore hba->mbox_queue_flag); 3606*a9800bebSGarrett D'Amore 3607*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 360882527734SSukumar Swaminathan return; 360982527734SSukumar Swaminathan } 361082527734SSukumar Swaminathan 3611*a9800bebSGarrett D'Amore /* Set port context */ 3612*a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 3613*a9800bebSGarrett D'Amore 3614b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3615b3660a96SSukumar Swaminathan hba->sli.sli4.mq.addr.virt) - 3616b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3617b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3618b3660a96SSukumar Swaminathan 361982527734SSukumar Swaminathan /* Now that we are the owner, DMA Sync entire MQ if needed */ 3620b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset, 362182527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 362282527734SSukumar Swaminathan 362382527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)hba->mbox_mqe, (uint8_t *)mb, 362482527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 362582527734SSukumar Swaminathan 3626*a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 3627*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3628*a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Mbox complete. status=%x cmd=%x", 3629*a9800bebSGarrett D'Amore mb->mbxStatus, mb->mbxCommand); 3630*a9800bebSGarrett D'Amore 3631*a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", (uint32_t *)hba->mbox_mqe, 3632*a9800bebSGarrett D'Amore 12, 0); 3633*a9800bebSGarrett D'Amore } 363482527734SSukumar Swaminathan 363582527734SSukumar Swaminathan if (mb->mbxCommand == MBX_SLI_CONFIG) { 363682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 363782527734SSukumar Swaminathan "Mbox sge_cnt: %d length: %d embed: %d", 363882527734SSukumar Swaminathan mb->un.varSLIConfig.be.sge_cnt, 363982527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length, 364082527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded); 364182527734SSukumar Swaminathan } 364282527734SSukumar Swaminathan 364382527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 364482527734SSukumar Swaminathan if (mbq->bp) { 364582527734SSukumar Swaminathan mbox_bp = (MATCHMAP *)mbq->bp; 364682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0, mbox_bp->size, 364782527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 3648b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3649b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, mbox_bp->dma_handle) 3650b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3651b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3652b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3653b3660a96SSukumar Swaminathan "emlxs_sli4_process_mbox_event: hdl=%p", 3654b3660a96SSukumar Swaminathan mbox_bp->dma_handle); 3655b3660a96SSukumar Swaminathan 3656b3660a96SSukumar Swaminathan mb->mbxStatus = MBXERR_DMA_ERROR; 3657b3660a96SSukumar Swaminathan } 3658b3660a96SSukumar Swaminathan #endif 365982527734SSukumar Swaminathan } 366082527734SSukumar Swaminathan 366182527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 366282527734SSukumar Swaminathan if (mbq->nonembed) { 366382527734SSukumar Swaminathan mbox_nonembed = (MATCHMAP *)mbq->nonembed; 366482527734SSukumar Swaminathan size = mbox_nonembed->size; 366582527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_nonembed->dma_handle, 0, size, 366682527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 366782527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mbox_nonembed->virt); 366882527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)iptr, size); 366982527734SSukumar Swaminathan 3670b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3671b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 3672b3660a96SSukumar Swaminathan mbox_nonembed->dma_handle) != DDI_FM_OK) { 3673b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3674b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3675b3660a96SSukumar Swaminathan "emlxs_sli4_process_mbox_event: hdl=%p", 3676b3660a96SSukumar Swaminathan mbox_nonembed->dma_handle); 3677b3660a96SSukumar Swaminathan 3678b3660a96SSukumar Swaminathan mb->mbxStatus = MBXERR_DMA_ERROR; 3679b3660a96SSukumar Swaminathan } 3680b3660a96SSukumar Swaminathan #endif 3681*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)iptr, 24, 0); 368282527734SSukumar Swaminathan } 368382527734SSukumar Swaminathan 368482527734SSukumar Swaminathan /* Mailbox has been completely received at this point */ 368582527734SSukumar Swaminathan 368682527734SSukumar Swaminathan if (mb->mbxCommand == MBX_HEARTBEAT) { 368782527734SSukumar Swaminathan hba->heartbeat_active = 0; 368882527734SSukumar Swaminathan goto done; 368982527734SSukumar Swaminathan } 369082527734SSukumar Swaminathan 369182527734SSukumar Swaminathan if (hba->mbox_queue_flag == MBX_SLEEP) { 369282527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 369382527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 369482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 369582527734SSukumar Swaminathan "Received. %s: status=%x Sleep.", 369682527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 369782527734SSukumar Swaminathan mb->mbxStatus); 369882527734SSukumar Swaminathan } 369982527734SSukumar Swaminathan } else { 370082527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 370182527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 370282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 370382527734SSukumar Swaminathan "Completed. %s: status=%x", 370482527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 370582527734SSukumar Swaminathan mb->mbxStatus); 370682527734SSukumar Swaminathan } 370782527734SSukumar Swaminathan } 370882527734SSukumar Swaminathan 370982527734SSukumar Swaminathan /* Filter out passthru mailbox */ 371082527734SSukumar Swaminathan if (mbq->flag & MBQ_PASSTHRU) { 371182527734SSukumar Swaminathan goto done; 371282527734SSukumar Swaminathan } 371382527734SSukumar Swaminathan 371482527734SSukumar Swaminathan if (mb->mbxStatus) { 371582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 371682527734SSukumar Swaminathan "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand), 371782527734SSukumar Swaminathan (uint32_t)mb->mbxStatus); 371882527734SSukumar Swaminathan } 371982527734SSukumar Swaminathan 372082527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 372182527734SSukumar Swaminathan rc = (mbq->mbox_cmpl)(hba, mbq); 372282527734SSukumar Swaminathan 372382527734SSukumar Swaminathan /* If mbox was retried, return immediately */ 372482527734SSukumar Swaminathan if (rc) { 372582527734SSukumar Swaminathan return; 372682527734SSukumar Swaminathan } 372782527734SSukumar Swaminathan } 372882527734SSukumar Swaminathan 372982527734SSukumar Swaminathan done: 373082527734SSukumar Swaminathan 373182527734SSukumar Swaminathan /* Clean up the mailbox area */ 373282527734SSukumar Swaminathan emlxs_mb_fini(hba, (MAILBOX *)mb, mb->mbxStatus); 373382527734SSukumar Swaminathan 373482527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 373582527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 373682527734SSukumar Swaminathan if (mbq) { 373782527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 373882527734SSukumar Swaminathan rc = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 373982527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 3740*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 374182527734SSukumar Swaminathan } 374282527734SSukumar Swaminathan } 374382527734SSukumar Swaminathan return; 374482527734SSukumar Swaminathan 374582527734SSukumar Swaminathan } /* emlxs_sli4_process_mbox_event() */ 374682527734SSukumar Swaminathan 374782527734SSukumar Swaminathan 3748bce54adfSSukumar Swaminathan /*ARGSUSED*/ 374982527734SSukumar Swaminathan static void 375082527734SSukumar Swaminathan emlxs_CQE_to_IOCB(emlxs_hba_t *hba, CQE_CmplWQ_t *cqe, emlxs_buf_t *sbp) 375182527734SSukumar Swaminathan { 3752bce54adfSSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 375382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3754bce54adfSSukumar Swaminathan #endif 375582527734SSukumar Swaminathan IOCBQ *iocbq; 375682527734SSukumar Swaminathan IOCB *iocb; 3757*a9800bebSGarrett D'Amore uint32_t *iptr; 3758*a9800bebSGarrett D'Amore fc_packet_t *pkt; 375982527734SSukumar Swaminathan emlxs_wqe_t *wqe; 376082527734SSukumar Swaminathan 376182527734SSukumar Swaminathan iocbq = &sbp->iocbq; 376282527734SSukumar Swaminathan wqe = &iocbq->wqe; 376382527734SSukumar Swaminathan iocb = &iocbq->iocb; 376482527734SSukumar Swaminathan 376582527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 376682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 376782527734SSukumar Swaminathan "CQE to IOCB: cmd:x%x tag:x%x xri:x%x", wqe->Command, 376882527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 376982527734SSukumar Swaminathan #endif 377082527734SSukumar Swaminathan 377182527734SSukumar Swaminathan iocb->ULPSTATUS = cqe->Status; 377282527734SSukumar Swaminathan iocb->un.ulpWord[4] = cqe->Parameter; 377382527734SSukumar Swaminathan iocb->ULPIOTAG = cqe->RequestTag; 377482527734SSukumar Swaminathan iocb->ULPCONTEXT = wqe->XRITag; 377582527734SSukumar Swaminathan 377682527734SSukumar Swaminathan switch (wqe->Command) { 377782527734SSukumar Swaminathan 377882527734SSukumar Swaminathan case CMD_FCP_ICMND64_CR: 377982527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_ICMND64_CX; 378082527734SSukumar Swaminathan break; 378182527734SSukumar Swaminathan 378282527734SSukumar Swaminathan case CMD_FCP_IREAD64_CR: 378382527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IREAD64_CX; 378482527734SSukumar Swaminathan iocb->ULPPU = PARM_READ_CHECK; 378582527734SSukumar Swaminathan if (iocb->ULPSTATUS == IOSTAT_FCP_RSP_ERROR) { 378682527734SSukumar Swaminathan iocb->un.fcpi64.fcpi_parm = 378782527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount - 378882527734SSukumar Swaminathan cqe->CmdSpecific; 378982527734SSukumar Swaminathan } 379082527734SSukumar Swaminathan break; 379182527734SSukumar Swaminathan 379282527734SSukumar Swaminathan case CMD_FCP_IWRITE64_CR: 379382527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IWRITE64_CX; 379482527734SSukumar Swaminathan break; 379582527734SSukumar Swaminathan 379682527734SSukumar Swaminathan case CMD_ELS_REQUEST64_CR: 379782527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_ELS_REQUEST64_CX; 379882527734SSukumar Swaminathan iocb->un.elsreq64.bdl.bdeSize = cqe->CmdSpecific; 379982527734SSukumar Swaminathan if (iocb->ULPSTATUS == 0) { 380082527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 380182527734SSukumar Swaminathan } 3802*a9800bebSGarrett D'Amore if (iocb->ULPSTATUS == IOSTAT_LS_RJT) { 3803*a9800bebSGarrett D'Amore /* For LS_RJT, the driver populates the rsp buffer */ 3804*a9800bebSGarrett D'Amore pkt = PRIV2PKT(sbp); 3805*a9800bebSGarrett D'Amore iptr = (uint32_t *)pkt->pkt_resp; 3806*a9800bebSGarrett D'Amore *iptr++ = ELS_CMD_LS_RJT; 3807*a9800bebSGarrett D'Amore *iptr = cqe->Parameter; 3808*a9800bebSGarrett D'Amore } 380982527734SSukumar Swaminathan break; 381082527734SSukumar Swaminathan 381182527734SSukumar Swaminathan case CMD_GEN_REQUEST64_CR: 381282527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_GEN_REQUEST64_CX; 381382527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 381482527734SSukumar Swaminathan break; 381582527734SSukumar Swaminathan 381682527734SSukumar Swaminathan case CMD_XMIT_SEQUENCE64_CR: 381782527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CX; 381882527734SSukumar Swaminathan break; 381982527734SSukumar Swaminathan 382082527734SSukumar Swaminathan default: 382182527734SSukumar Swaminathan iocb->ULPCOMMAND = wqe->Command; 382282527734SSukumar Swaminathan 382382527734SSukumar Swaminathan } 382482527734SSukumar Swaminathan 382582527734SSukumar Swaminathan } /* emlxs_CQE_to_IOCB() */ 382682527734SSukumar Swaminathan 382782527734SSukumar Swaminathan 382882527734SSukumar Swaminathan /*ARGSUSED*/ 382982527734SSukumar Swaminathan static void 383082527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(emlxs_hba_t *hba) 383182527734SSukumar Swaminathan { 3832bce54adfSSukumar Swaminathan #ifdef SFCT_SUPPORT 3833bce54adfSSukumar Swaminathan #ifdef FCT_IO_TRACE 3834bce54adfSSukumar Swaminathan emlxs_port_t *port = &PPORT; 3835bce54adfSSukumar Swaminathan #endif /* FCT_IO_TRACE */ 3836bce54adfSSukumar Swaminathan #endif /* SFCT_SUPPORT */ 383782527734SSukumar Swaminathan CHANNEL *cp; 383882527734SSukumar Swaminathan emlxs_buf_t *sbp; 383982527734SSukumar Swaminathan IOCBQ *iocbq; 3840*a9800bebSGarrett D'Amore uint16_t i; 384182527734SSukumar Swaminathan uint32_t trigger; 384282527734SSukumar Swaminathan CQE_CmplWQ_t cqe; 384382527734SSukumar Swaminathan 384482527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 384582527734SSukumar Swaminathan for (i = 0; i < hba->max_iotag; i++) { 384682527734SSukumar Swaminathan sbp = hba->fc_table[i]; 384782527734SSukumar Swaminathan if (sbp == NULL || sbp == STALE_PACKET) { 384882527734SSukumar Swaminathan continue; 384982527734SSukumar Swaminathan } 3850*a9800bebSGarrett D'Amore hba->fc_table[i] = STALE_PACKET; 385182527734SSukumar Swaminathan hba->io_count--; 3852*a9800bebSGarrett D'Amore sbp->iotag = 0; 385382527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 385482527734SSukumar Swaminathan 385582527734SSukumar Swaminathan cp = sbp->channel; 385682527734SSukumar Swaminathan bzero(&cqe, sizeof (CQE_CmplWQ_t)); 385782527734SSukumar Swaminathan cqe.RequestTag = i; 385882527734SSukumar Swaminathan cqe.Status = IOSTAT_LOCAL_REJECT; 385982527734SSukumar Swaminathan cqe.Parameter = IOERR_SEQUENCE_TIMEOUT; 386082527734SSukumar Swaminathan 386182527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 386282527734SSukumar Swaminathan 386382527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 386482527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 386582527734SSukumar Swaminathan if (sbp->fct_cmd) { 386682527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 386782527734SSukumar Swaminathan EMLXS_FCT_IOCB_COMPLETE); 386882527734SSukumar Swaminathan } 386982527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 387082527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 387182527734SSukumar Swaminathan 387282527734SSukumar Swaminathan atomic_add_32(&hba->io_active, -1); 387382527734SSukumar Swaminathan 387482527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 387582527734SSukumar Swaminathan iocbq = &sbp->iocbq; 387682527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, &cqe, sbp); 387782527734SSukumar Swaminathan 387882527734SSukumar Swaminathan iocbq->next = NULL; 387982527734SSukumar Swaminathan 388082527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 3881*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, sbp, sbp->xrip, 1); 388282527734SSukumar Swaminathan 388382527734SSukumar Swaminathan if (!(sbp->pkt_flags & 388482527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 388582527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 388682527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 388782527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 388882527734SSukumar Swaminathan cp->rsp_head = iocbq; 388982527734SSukumar Swaminathan cp->rsp_tail = iocbq; 389082527734SSukumar Swaminathan } else { 389182527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 389282527734SSukumar Swaminathan cp->rsp_tail = iocbq; 389382527734SSukumar Swaminathan } 389482527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 389582527734SSukumar Swaminathan trigger = 1; 389682527734SSukumar Swaminathan } else { 389782527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 389882527734SSukumar Swaminathan } 389982527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 390082527734SSukumar Swaminathan } 390182527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 390282527734SSukumar Swaminathan 390382527734SSukumar Swaminathan if (trigger) { 390482527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 390582527734SSukumar Swaminathan cp = &hba->chan[i]; 390682527734SSukumar Swaminathan if (cp->rsp_head != NULL) { 390782527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 390882527734SSukumar Swaminathan emlxs_proc_channel, cp); 390982527734SSukumar Swaminathan } 391082527734SSukumar Swaminathan } 391182527734SSukumar Swaminathan } 391282527734SSukumar Swaminathan 391382527734SSukumar Swaminathan } /* emlxs_sli4_hba_flush_chipq() */ 391482527734SSukumar Swaminathan 391582527734SSukumar Swaminathan 391682527734SSukumar Swaminathan /*ARGSUSED*/ 391782527734SSukumar Swaminathan static void 391882527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(emlxs_hba_t *hba, 391982527734SSukumar Swaminathan CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 392082527734SSukumar Swaminathan { 392182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 392282527734SSukumar Swaminathan CHANNEL *cp; 392382527734SSukumar Swaminathan uint16_t request_tag; 3924*a9800bebSGarrett D'Amore CQE_u *cq_entry; 392582527734SSukumar Swaminathan 392682527734SSukumar Swaminathan request_tag = cqe->RequestTag; 392782527734SSukumar Swaminathan 3928*a9800bebSGarrett D'Amore cq_entry = (CQE_u *)cqe; 3929*a9800bebSGarrett D'Amore 393082527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 393182527734SSukumar Swaminathan cp = cq->channelp; 393282527734SSukumar Swaminathan 393382527734SSukumar Swaminathan cp->hbaCmplCmd++; 393482527734SSukumar Swaminathan 393582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 393682527734SSukumar Swaminathan "CQ ENTRY: OOR Cmpl: tag=%x", request_tag); 393782527734SSukumar Swaminathan 3938*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3939*a9800bebSGarrett D'Amore "CQ ENTRY: %08x %08x %08x %08x", cq_entry->word[0], 3940*a9800bebSGarrett D'Amore cq_entry->word[1], cq_entry->word[2], cq_entry->word[3]); 3941*a9800bebSGarrett D'Amore 394282527734SSukumar Swaminathan } /* emlxs_sli4_process_oor_wqe_cmpl() */ 394382527734SSukumar Swaminathan 394482527734SSukumar Swaminathan 394582527734SSukumar Swaminathan /*ARGSUSED*/ 394682527734SSukumar Swaminathan static void 394782527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(emlxs_hba_t *hba, CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 394882527734SSukumar Swaminathan { 394982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 395082527734SSukumar Swaminathan CHANNEL *cp; 395182527734SSukumar Swaminathan emlxs_buf_t *sbp; 395282527734SSukumar Swaminathan IOCBQ *iocbq; 395382527734SSukumar Swaminathan uint16_t request_tag; 395482527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 395582527734SSukumar Swaminathan fct_cmd_t *fct_cmd; 395682527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 395782527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 395882527734SSukumar Swaminathan 395982527734SSukumar Swaminathan request_tag = cqe->RequestTag; 396082527734SSukumar Swaminathan 396182527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 396282527734SSukumar Swaminathan cp = cq->channelp; 396382527734SSukumar Swaminathan 3964*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 396582527734SSukumar Swaminathan sbp = hba->fc_table[request_tag]; 396682527734SSukumar Swaminathan atomic_add_32(&hba->io_active, -1); 396782527734SSukumar Swaminathan 396882527734SSukumar Swaminathan if (sbp == STALE_PACKET) { 396982527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 3970*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 397182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 397282527734SSukumar Swaminathan "CQ ENTRY: Stale sbp. tag=%x. Dropping...", request_tag); 397382527734SSukumar Swaminathan return; 397482527734SSukumar Swaminathan } 397582527734SSukumar Swaminathan 3976*a9800bebSGarrett D'Amore if (!sbp || !(sbp->xrip)) { 397782527734SSukumar Swaminathan cp->hbaCmplCmd++; 3978*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 397982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 398082527734SSukumar Swaminathan "CQ ENTRY: NULL sbp %p. tag=%x. Dropping...", 398182527734SSukumar Swaminathan sbp, request_tag); 398282527734SSukumar Swaminathan return; 398382527734SSukumar Swaminathan } 398482527734SSukumar Swaminathan 398582527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 398682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 398782527734SSukumar Swaminathan "CQ ENTRY: process wqe compl"); 398882527734SSukumar Swaminathan #endif 398982527734SSukumar Swaminathan 399082527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 399182527734SSukumar Swaminathan 399282527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 399382527734SSukumar Swaminathan iocbq = &sbp->iocbq; 399482527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, cqe, sbp); 399582527734SSukumar Swaminathan 399682527734SSukumar Swaminathan iocbq->next = NULL; 399782527734SSukumar Swaminathan 399882527734SSukumar Swaminathan if (cqe->XB) { 399982527734SSukumar Swaminathan /* Mark exchange as ABORT in progress */ 4000*a9800bebSGarrett D'Amore sbp->xrip->flag &= ~EMLXS_XRI_PENDING_IO; 4001*a9800bebSGarrett D'Amore sbp->xrip->flag |= EMLXS_XRI_ABORT_INP; 400282527734SSukumar Swaminathan 400382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 400482527734SSukumar Swaminathan "CQ ENTRY: ABORT INP: tag=%x xri=%x", request_tag, 4005*a9800bebSGarrett D'Amore sbp->xrip->XRI); 400682527734SSukumar Swaminathan 4007*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, sbp, 0, 0); 400882527734SSukumar Swaminathan } else { 400982527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 4010*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, sbp, sbp->xrip, 0); 4011*a9800bebSGarrett D'Amore } 4012*a9800bebSGarrett D'Amore 4013*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 4014*a9800bebSGarrett D'Amore 4015*a9800bebSGarrett D'Amore #ifdef SFCT_SUPPORT 4016*a9800bebSGarrett D'Amore fct_cmd = sbp->fct_cmd; 4017*a9800bebSGarrett D'Amore if (fct_cmd) { 4018*a9800bebSGarrett D'Amore cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 4019*a9800bebSGarrett D'Amore mutex_enter(&cmd_sbp->fct_mtx); 4020*a9800bebSGarrett D'Amore EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_IOCB_COMPLETE); 4021*a9800bebSGarrett D'Amore mutex_exit(&cmd_sbp->fct_mtx); 402282527734SSukumar Swaminathan } 4023*a9800bebSGarrett D'Amore #endif /* SFCT_SUPPORT */ 402482527734SSukumar Swaminathan 402582527734SSukumar Swaminathan /* 402682527734SSukumar Swaminathan * If this is NOT a polled command completion 402782527734SSukumar Swaminathan * or a driver allocated pkt, then defer pkt 402882527734SSukumar Swaminathan * completion. 402982527734SSukumar Swaminathan */ 403082527734SSukumar Swaminathan if (!(sbp->pkt_flags & 403182527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 403282527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 403382527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 403482527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 403582527734SSukumar Swaminathan cp->rsp_head = iocbq; 403682527734SSukumar Swaminathan cp->rsp_tail = iocbq; 403782527734SSukumar Swaminathan } else { 403882527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 403982527734SSukumar Swaminathan cp->rsp_tail = iocbq; 404082527734SSukumar Swaminathan } 404182527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 404282527734SSukumar Swaminathan 404382527734SSukumar Swaminathan /* Delay triggering thread till end of ISR */ 404482527734SSukumar Swaminathan cp->chan_flag |= EMLXS_NEEDS_TRIGGER; 404582527734SSukumar Swaminathan } else { 404682527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 404782527734SSukumar Swaminathan } 404882527734SSukumar Swaminathan 404982527734SSukumar Swaminathan } /* emlxs_sli4_process_wqe_cmpl() */ 405082527734SSukumar Swaminathan 405182527734SSukumar Swaminathan 405282527734SSukumar Swaminathan /*ARGSUSED*/ 405382527734SSukumar Swaminathan static void 405482527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(emlxs_hba_t *hba, CQ_DESC_t *cq, 405582527734SSukumar Swaminathan CQE_RelWQ_t *cqe) 405682527734SSukumar Swaminathan { 4057bce54adfSSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 405882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4059bce54adfSSukumar Swaminathan #endif 406082527734SSukumar Swaminathan WQ_DESC_t *wq; 406182527734SSukumar Swaminathan CHANNEL *cp; 406282527734SSukumar Swaminathan uint32_t i; 406382527734SSukumar Swaminathan 406482527734SSukumar Swaminathan i = cqe->WQid; 406582527734SSukumar Swaminathan wq = &hba->sli.sli4.wq[hba->sli.sli4.wq_map[i]]; 406682527734SSukumar Swaminathan 406782527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 406882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 406982527734SSukumar Swaminathan "CQ ENTRY: process release wqe: old %d new %d", wq->port_index, 407082527734SSukumar Swaminathan cqe->WQindex); 407182527734SSukumar Swaminathan #endif 407282527734SSukumar Swaminathan 407382527734SSukumar Swaminathan wq->port_index = cqe->WQindex; 407482527734SSukumar Swaminathan 407582527734SSukumar Swaminathan /* Cmd ring may be available. Try sending more iocbs */ 407682527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 407782527734SSukumar Swaminathan cp = &hba->chan[i]; 407882527734SSukumar Swaminathan if (wq == (WQ_DESC_t *)cp->iopath) { 407982527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(hba, cp, 0); 408082527734SSukumar Swaminathan } 408182527734SSukumar Swaminathan } 408282527734SSukumar Swaminathan 408382527734SSukumar Swaminathan } /* emlxs_sli4_process_release_wqe() */ 408482527734SSukumar Swaminathan 408582527734SSukumar Swaminathan 408682527734SSukumar Swaminathan /*ARGSUSED*/ 408782527734SSukumar Swaminathan emlxs_iocbq_t * 408882527734SSukumar Swaminathan emlxs_sli4_rxq_get(emlxs_hba_t *hba, fc_frame_hdr_t *fchdr) 408982527734SSukumar Swaminathan { 409082527734SSukumar Swaminathan emlxs_queue_t *q; 409182527734SSukumar Swaminathan emlxs_iocbq_t *iocbq; 409282527734SSukumar Swaminathan emlxs_iocbq_t *prev; 409382527734SSukumar Swaminathan fc_frame_hdr_t *fchdr2; 409482527734SSukumar Swaminathan RXQ_DESC_t *rxq; 409582527734SSukumar Swaminathan 409682527734SSukumar Swaminathan switch (fchdr->type) { 409782527734SSukumar Swaminathan case 1: /* ELS */ 409882527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 409982527734SSukumar Swaminathan break; 410082527734SSukumar Swaminathan case 0x20: /* CT */ 410182527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 410282527734SSukumar Swaminathan break; 410382527734SSukumar Swaminathan default: 410482527734SSukumar Swaminathan return (NULL); 410582527734SSukumar Swaminathan } 410682527734SSukumar Swaminathan 410782527734SSukumar Swaminathan mutex_enter(&rxq->lock); 410882527734SSukumar Swaminathan 410982527734SSukumar Swaminathan q = &rxq->active; 411082527734SSukumar Swaminathan iocbq = (emlxs_iocbq_t *)q->q_first; 411182527734SSukumar Swaminathan prev = NULL; 411282527734SSukumar Swaminathan 411382527734SSukumar Swaminathan while (iocbq) { 411482527734SSukumar Swaminathan 411582527734SSukumar Swaminathan fchdr2 = (fc_frame_hdr_t *)iocbq->iocb.un.ulpWord; 411682527734SSukumar Swaminathan 411782527734SSukumar Swaminathan if ((fchdr2->s_id == fchdr->s_id) && 411882527734SSukumar Swaminathan (fchdr2->ox_id == fchdr->ox_id) && 411982527734SSukumar Swaminathan (fchdr2->seq_id == fchdr->seq_id)) { 412082527734SSukumar Swaminathan /* Remove iocbq */ 412182527734SSukumar Swaminathan if (prev) { 412282527734SSukumar Swaminathan prev->next = iocbq->next; 412382527734SSukumar Swaminathan } 412482527734SSukumar Swaminathan if (q->q_first == (uint8_t *)iocbq) { 412582527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq->next; 412682527734SSukumar Swaminathan } 412782527734SSukumar Swaminathan if (q->q_last == (uint8_t *)iocbq) { 412882527734SSukumar Swaminathan q->q_last = (uint8_t *)prev; 412982527734SSukumar Swaminathan } 413082527734SSukumar Swaminathan q->q_cnt--; 413182527734SSukumar Swaminathan 413282527734SSukumar Swaminathan break; 413382527734SSukumar Swaminathan } 413482527734SSukumar Swaminathan 413582527734SSukumar Swaminathan prev = iocbq; 413682527734SSukumar Swaminathan iocbq = iocbq->next; 413782527734SSukumar Swaminathan } 413882527734SSukumar Swaminathan 413982527734SSukumar Swaminathan mutex_exit(&rxq->lock); 414082527734SSukumar Swaminathan 414182527734SSukumar Swaminathan return (iocbq); 414282527734SSukumar Swaminathan 414382527734SSukumar Swaminathan } /* emlxs_sli4_rxq_get() */ 414482527734SSukumar Swaminathan 414582527734SSukumar Swaminathan 414682527734SSukumar Swaminathan /*ARGSUSED*/ 414782527734SSukumar Swaminathan void 414882527734SSukumar Swaminathan emlxs_sli4_rxq_put(emlxs_hba_t *hba, emlxs_iocbq_t *iocbq) 414982527734SSukumar Swaminathan { 415082527734SSukumar Swaminathan emlxs_queue_t *q; 415182527734SSukumar Swaminathan fc_frame_hdr_t *fchdr; 415282527734SSukumar Swaminathan RXQ_DESC_t *rxq; 415382527734SSukumar Swaminathan 415482527734SSukumar Swaminathan fchdr = (fc_frame_hdr_t *)iocbq->iocb.RXFCHDR; 415582527734SSukumar Swaminathan 415682527734SSukumar Swaminathan switch (fchdr->type) { 415782527734SSukumar Swaminathan case 1: /* ELS */ 415882527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 415982527734SSukumar Swaminathan break; 416082527734SSukumar Swaminathan case 0x20: /* CT */ 416182527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 416282527734SSukumar Swaminathan break; 416382527734SSukumar Swaminathan default: 416482527734SSukumar Swaminathan return; 416582527734SSukumar Swaminathan } 416682527734SSukumar Swaminathan 416782527734SSukumar Swaminathan mutex_enter(&rxq->lock); 416882527734SSukumar Swaminathan 416982527734SSukumar Swaminathan q = &rxq->active; 417082527734SSukumar Swaminathan 417182527734SSukumar Swaminathan if (q->q_last) { 417282527734SSukumar Swaminathan ((emlxs_iocbq_t *)q->q_last)->next = iocbq; 417382527734SSukumar Swaminathan q->q_cnt++; 417482527734SSukumar Swaminathan } else { 417582527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq; 417682527734SSukumar Swaminathan q->q_cnt = 1; 417782527734SSukumar Swaminathan } 417882527734SSukumar Swaminathan 417982527734SSukumar Swaminathan q->q_last = (uint8_t *)iocbq; 418082527734SSukumar Swaminathan iocbq->next = NULL; 418182527734SSukumar Swaminathan 418282527734SSukumar Swaminathan mutex_exit(&rxq->lock); 418382527734SSukumar Swaminathan 418482527734SSukumar Swaminathan return; 418582527734SSukumar Swaminathan 418682527734SSukumar Swaminathan } /* emlxs_sli4_rxq_put() */ 418782527734SSukumar Swaminathan 418882527734SSukumar Swaminathan 418982527734SSukumar Swaminathan static void 4190*a9800bebSGarrett D'Amore emlxs_sli4_rq_post(emlxs_port_t *port, uint16_t rqid) 419182527734SSukumar Swaminathan { 4192*a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 419382527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 419482527734SSukumar Swaminathan 419582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 419682527734SSukumar Swaminathan "RQ POST: rqid=%d count=1", rqid); 419782527734SSukumar Swaminathan 419882527734SSukumar Swaminathan /* Ring the RQ doorbell once to repost the RQ buffer */ 419982527734SSukumar Swaminathan rqdb.word = 0; 420082527734SSukumar Swaminathan rqdb.db.Qid = rqid; 420182527734SSukumar Swaminathan rqdb.db.NumPosted = 1; 420282527734SSukumar Swaminathan 420382527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_RQDB_REG(hba), rqdb.word); 420482527734SSukumar Swaminathan 420582527734SSukumar Swaminathan } /* emlxs_sli4_rq_post() */ 420682527734SSukumar Swaminathan 420782527734SSukumar Swaminathan 420882527734SSukumar Swaminathan /*ARGSUSED*/ 420982527734SSukumar Swaminathan static void 421082527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq, 421182527734SSukumar Swaminathan CQE_UnsolRcv_t *cqe) 421282527734SSukumar Swaminathan { 421382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 421482527734SSukumar Swaminathan emlxs_port_t *vport; 421582527734SSukumar Swaminathan RQ_DESC_t *hdr_rq; 421682527734SSukumar Swaminathan RQ_DESC_t *data_rq; 4217b3660a96SSukumar Swaminathan MBUF_INFO *hdr_mp; 4218b3660a96SSukumar Swaminathan MBUF_INFO *data_mp; 421982527734SSukumar Swaminathan MATCHMAP *seq_mp; 422082527734SSukumar Swaminathan uint32_t *data; 422182527734SSukumar Swaminathan fc_frame_hdr_t fchdr; 422282527734SSukumar Swaminathan uint32_t hdr_rqi; 422382527734SSukumar Swaminathan uint32_t host_index; 422482527734SSukumar Swaminathan emlxs_iocbq_t *iocbq = NULL; 422582527734SSukumar Swaminathan emlxs_iocb_t *iocb; 422682527734SSukumar Swaminathan emlxs_node_t *node; 422782527734SSukumar Swaminathan uint32_t i; 422882527734SSukumar Swaminathan uint32_t seq_len; 422982527734SSukumar Swaminathan uint32_t seq_cnt; 423082527734SSukumar Swaminathan uint32_t buf_type; 423182527734SSukumar Swaminathan char label[32]; 423282527734SSukumar Swaminathan emlxs_wqe_t *wqe; 423382527734SSukumar Swaminathan CHANNEL *cp; 423482527734SSukumar Swaminathan uint16_t iotag; 4235*a9800bebSGarrett D'Amore XRIobj_t *xrip; 4236*a9800bebSGarrett D'Amore RPIobj_t *rpip = NULL; 423782527734SSukumar Swaminathan uint32_t cmd; 423882527734SSukumar Swaminathan uint32_t posted = 0; 423982527734SSukumar Swaminathan uint32_t abort = 1; 4240b3660a96SSukumar Swaminathan off_t offset; 424182527734SSukumar Swaminathan 424282527734SSukumar Swaminathan hdr_rqi = hba->sli.sli4.rq_map[cqe->RQid]; 424382527734SSukumar Swaminathan hdr_rq = &hba->sli.sli4.rq[hdr_rqi]; 424482527734SSukumar Swaminathan data_rq = &hba->sli.sli4.rq[hdr_rqi + 1]; 424582527734SSukumar Swaminathan 424682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4247*a9800bebSGarrett D'Amore "CQ ENTRY: Unsol Rcv: RQid=%d,%d index=%d status=%x " 424882527734SSukumar Swaminathan "hdr_size=%d data_size=%d", 424982527734SSukumar Swaminathan cqe->RQid, hdr_rqi, hdr_rq->host_index, cqe->Status, cqe->hdr_size, 425082527734SSukumar Swaminathan cqe->data_size); 425182527734SSukumar Swaminathan 425282527734SSukumar Swaminathan /* Validate the CQE */ 425382527734SSukumar Swaminathan 425482527734SSukumar Swaminathan /* Check status */ 425582527734SSukumar Swaminathan switch (cqe->Status) { 425682527734SSukumar Swaminathan case RQ_STATUS_SUCCESS: /* 0x10 */ 425782527734SSukumar Swaminathan break; 425882527734SSukumar Swaminathan 425982527734SSukumar Swaminathan case RQ_STATUS_BUFLEN_EXCEEDED: /* 0x11 */ 426082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 426182527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload truncated."); 426282527734SSukumar Swaminathan break; 426382527734SSukumar Swaminathan 426482527734SSukumar Swaminathan case RQ_STATUS_NEED_BUFFER: /* 0x12 */ 426582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 426682527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer needed."); 426782527734SSukumar Swaminathan return; 426882527734SSukumar Swaminathan 426982527734SSukumar Swaminathan case RQ_STATUS_FRAME_DISCARDED: /* 0x13 */ 427082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 427182527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer discarded."); 427282527734SSukumar Swaminathan return; 427382527734SSukumar Swaminathan 427482527734SSukumar Swaminathan default: 427582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 427682527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Unknown status=%x.", 427782527734SSukumar Swaminathan cqe->Status); 427882527734SSukumar Swaminathan break; 427982527734SSukumar Swaminathan } 428082527734SSukumar Swaminathan 428182527734SSukumar Swaminathan /* Make sure there is a frame header */ 428282527734SSukumar Swaminathan if (cqe->hdr_size < sizeof (fc_frame_hdr_t)) { 428382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 428482527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: FC header too small. Dropping..."); 428582527734SSukumar Swaminathan return; 428682527734SSukumar Swaminathan } 428782527734SSukumar Swaminathan 428882527734SSukumar Swaminathan /* Update host index */ 428982527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.rq[hdr_rqi].lock); 429082527734SSukumar Swaminathan host_index = hdr_rq->host_index; 429182527734SSukumar Swaminathan hdr_rq->host_index++; 429282527734SSukumar Swaminathan if (hdr_rq->host_index >= hdr_rq->max_index) { 429382527734SSukumar Swaminathan hdr_rq->host_index = 0; 429482527734SSukumar Swaminathan } 429582527734SSukumar Swaminathan data_rq->host_index = hdr_rq->host_index; 429682527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.rq[hdr_rqi].lock); 429782527734SSukumar Swaminathan 429882527734SSukumar Swaminathan /* Get the next header rqb */ 4299b3660a96SSukumar Swaminathan hdr_mp = &hdr_rq->rqb[host_index]; 430082527734SSukumar Swaminathan 4301b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long)hdr_mp->virt) - 4302b3660a96SSukumar Swaminathan (uint64_t)((unsigned long)hba->sli.sli4.slim2.virt)); 4303b3660a96SSukumar Swaminathan 4304b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hdr_mp->dma_handle, offset, 430582527734SSukumar Swaminathan sizeof (fc_frame_hdr_t), DDI_DMA_SYNC_FORKERNEL); 430682527734SSukumar Swaminathan 430782527734SSukumar Swaminathan LE_SWAP32_BCOPY(hdr_mp->virt, (uint8_t *)&fchdr, 430882527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 430982527734SSukumar Swaminathan 431082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4311*a9800bebSGarrett D'Amore "RQ HDR[%d]: rctl:%x type:%x " 431282527734SSukumar Swaminathan "sid:%x did:%x oxid:%x rxid:%x", 431382527734SSukumar Swaminathan host_index, fchdr.r_ctl, fchdr.type, 431482527734SSukumar Swaminathan fchdr.s_id, fchdr.d_id, fchdr.ox_id, fchdr.rx_id); 431582527734SSukumar Swaminathan 431682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 431782527734SSukumar Swaminathan "RQ HDR[%d]: fctl:%x seq_id:%x seq_cnt:%x df_ctl:%x ro:%x", 431882527734SSukumar Swaminathan host_index, fchdr.f_ctl, fchdr.seq_id, fchdr.seq_cnt, 431982527734SSukumar Swaminathan fchdr.df_ctl, fchdr.ro); 432082527734SSukumar Swaminathan 432182527734SSukumar Swaminathan /* Verify fc header type */ 432282527734SSukumar Swaminathan switch (fchdr.type) { 432382527734SSukumar Swaminathan case 0: /* BLS */ 432482527734SSukumar Swaminathan if (fchdr.r_ctl != 0x81) { 432582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4326*a9800bebSGarrett D'Amore "RQ ENTRY: Unexpected FC rctl (0x%x) " 432782527734SSukumar Swaminathan "received. Dropping...", 432882527734SSukumar Swaminathan fchdr.r_ctl); 432982527734SSukumar Swaminathan 433082527734SSukumar Swaminathan goto done; 433182527734SSukumar Swaminathan } 433282527734SSukumar Swaminathan 433382527734SSukumar Swaminathan /* Make sure there is no payload */ 433482527734SSukumar Swaminathan if (cqe->data_size != 0) { 433582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 433682527734SSukumar Swaminathan "RQ ENTRY: ABTS payload provided. Dropping..."); 433782527734SSukumar Swaminathan 433882527734SSukumar Swaminathan goto done; 433982527734SSukumar Swaminathan } 434082527734SSukumar Swaminathan 434182527734SSukumar Swaminathan buf_type = 0xFFFFFFFF; 434282527734SSukumar Swaminathan (void) strcpy(label, "ABTS"); 434382527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 434482527734SSukumar Swaminathan break; 434582527734SSukumar Swaminathan 434682527734SSukumar Swaminathan case 0x01: /* ELS */ 434782527734SSukumar Swaminathan /* Make sure there is a payload */ 434882527734SSukumar Swaminathan if (cqe->data_size == 0) { 434982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4350*a9800bebSGarrett D'Amore "RQ ENTRY: Unsol Rcv: No ELS payload provided. " 435182527734SSukumar Swaminathan "Dropping..."); 435282527734SSukumar Swaminathan 435382527734SSukumar Swaminathan goto done; 435482527734SSukumar Swaminathan } 435582527734SSukumar Swaminathan 435682527734SSukumar Swaminathan buf_type = MEM_ELSBUF; 435782527734SSukumar Swaminathan (void) strcpy(label, "Unsol ELS"); 435882527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 435982527734SSukumar Swaminathan break; 436082527734SSukumar Swaminathan 436182527734SSukumar Swaminathan case 0x20: /* CT */ 436282527734SSukumar Swaminathan /* Make sure there is a payload */ 436382527734SSukumar Swaminathan if (cqe->data_size == 0) { 436482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4365*a9800bebSGarrett D'Amore "RQ ENTRY: Unsol Rcv: No CT payload provided. " 436682527734SSukumar Swaminathan "Dropping..."); 436782527734SSukumar Swaminathan 436882527734SSukumar Swaminathan goto done; 436982527734SSukumar Swaminathan } 437082527734SSukumar Swaminathan 437182527734SSukumar Swaminathan buf_type = MEM_CTBUF; 437282527734SSukumar Swaminathan (void) strcpy(label, "Unsol CT"); 437382527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 437482527734SSukumar Swaminathan break; 437582527734SSukumar Swaminathan 437682527734SSukumar Swaminathan default: 437782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 437882527734SSukumar Swaminathan "RQ ENTRY: Unexpected FC type (0x%x) received. Dropping...", 437982527734SSukumar Swaminathan fchdr.type); 438082527734SSukumar Swaminathan 438182527734SSukumar Swaminathan goto done; 438282527734SSukumar Swaminathan } 438382527734SSukumar Swaminathan /* Fc Header is valid */ 438482527734SSukumar Swaminathan 438582527734SSukumar Swaminathan /* Check if this is an active sequence */ 438682527734SSukumar Swaminathan iocbq = emlxs_sli4_rxq_get(hba, &fchdr); 438782527734SSukumar Swaminathan 438882527734SSukumar Swaminathan if (!iocbq) { 438982527734SSukumar Swaminathan if (fchdr.type != 0) { 439082527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_FIRST_SEQ)) { 439182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4392*a9800bebSGarrett D'Amore "RQ ENTRY: %s: First of sequence not" 439382527734SSukumar Swaminathan " set. Dropping...", 439482527734SSukumar Swaminathan label); 439582527734SSukumar Swaminathan 439682527734SSukumar Swaminathan goto done; 439782527734SSukumar Swaminathan } 439882527734SSukumar Swaminathan } 439982527734SSukumar Swaminathan 440082527734SSukumar Swaminathan if (fchdr.seq_cnt != 0) { 440182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4402*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Sequence count not zero (%d). " 440382527734SSukumar Swaminathan "Dropping...", 440482527734SSukumar Swaminathan label, fchdr.seq_cnt); 440582527734SSukumar Swaminathan 440682527734SSukumar Swaminathan goto done; 440782527734SSukumar Swaminathan } 440882527734SSukumar Swaminathan 440982527734SSukumar Swaminathan /* Find vport (defaults to physical port) */ 441082527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 441182527734SSukumar Swaminathan vport = &VPORT(i); 441282527734SSukumar Swaminathan 441382527734SSukumar Swaminathan if (vport->did == fchdr.d_id) { 441482527734SSukumar Swaminathan port = vport; 441582527734SSukumar Swaminathan break; 441682527734SSukumar Swaminathan } 441782527734SSukumar Swaminathan } 441882527734SSukumar Swaminathan 441982527734SSukumar Swaminathan /* Allocate an IOCBQ */ 442082527734SSukumar Swaminathan iocbq = (emlxs_iocbq_t *)emlxs_mem_get(hba, 442182527734SSukumar Swaminathan MEM_IOCB, 1); 442282527734SSukumar Swaminathan 442382527734SSukumar Swaminathan if (!iocbq) { 442482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4425*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of IOCB " 442682527734SSukumar Swaminathan "resources. Dropping...", 442782527734SSukumar Swaminathan label); 442882527734SSukumar Swaminathan 442982527734SSukumar Swaminathan goto done; 443082527734SSukumar Swaminathan } 443182527734SSukumar Swaminathan 443282527734SSukumar Swaminathan seq_mp = NULL; 443382527734SSukumar Swaminathan if (fchdr.type != 0) { 443482527734SSukumar Swaminathan /* Allocate a buffer */ 443582527734SSukumar Swaminathan seq_mp = (MATCHMAP *)emlxs_mem_get(hba, buf_type, 1); 443682527734SSukumar Swaminathan 443782527734SSukumar Swaminathan if (!seq_mp) { 443882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4439*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of buffer " 444082527734SSukumar Swaminathan "resources. Dropping...", 444182527734SSukumar Swaminathan label); 444282527734SSukumar Swaminathan 444382527734SSukumar Swaminathan goto done; 444482527734SSukumar Swaminathan } 444582527734SSukumar Swaminathan 444682527734SSukumar Swaminathan iocbq->bp = (uint8_t *)seq_mp; 444782527734SSukumar Swaminathan } 444882527734SSukumar Swaminathan 444982527734SSukumar Swaminathan node = (void *)emlxs_node_find_did(port, fchdr.s_id); 445082527734SSukumar Swaminathan if (node == NULL) { 445182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 445282527734SSukumar Swaminathan "RQ ENTRY: %s: Node not found. sid=%x", 445382527734SSukumar Swaminathan label, fchdr.s_id); 445482527734SSukumar Swaminathan } 445582527734SSukumar Swaminathan 445682527734SSukumar Swaminathan /* Initialize the iocbq */ 445782527734SSukumar Swaminathan iocbq->port = port; 445882527734SSukumar Swaminathan iocbq->channel = cp; 445982527734SSukumar Swaminathan iocbq->node = node; 446082527734SSukumar Swaminathan 446182527734SSukumar Swaminathan iocb = &iocbq->iocb; 446282527734SSukumar Swaminathan iocb->RXSEQCNT = 0; 446382527734SSukumar Swaminathan iocb->RXSEQLEN = 0; 446482527734SSukumar Swaminathan 446582527734SSukumar Swaminathan seq_len = 0; 446682527734SSukumar Swaminathan seq_cnt = 0; 446782527734SSukumar Swaminathan 446882527734SSukumar Swaminathan } else { 446982527734SSukumar Swaminathan 447082527734SSukumar Swaminathan iocb = &iocbq->iocb; 447182527734SSukumar Swaminathan port = iocbq->port; 447282527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 447382527734SSukumar Swaminathan 447482527734SSukumar Swaminathan seq_mp = (MATCHMAP *)iocbq->bp; 447582527734SSukumar Swaminathan seq_len = iocb->RXSEQLEN; 447682527734SSukumar Swaminathan seq_cnt = iocb->RXSEQCNT; 447782527734SSukumar Swaminathan 447882527734SSukumar Swaminathan /* Check sequence order */ 447982527734SSukumar Swaminathan if (fchdr.seq_cnt != seq_cnt) { 448082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4481*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of order frame received " 448282527734SSukumar Swaminathan "(%d != %d). Dropping...", 448382527734SSukumar Swaminathan label, fchdr.seq_cnt, seq_cnt); 448482527734SSukumar Swaminathan 448582527734SSukumar Swaminathan goto done; 448682527734SSukumar Swaminathan } 448782527734SSukumar Swaminathan } 448882527734SSukumar Swaminathan 448982527734SSukumar Swaminathan /* We now have an iocbq */ 449082527734SSukumar Swaminathan 4491*a9800bebSGarrett D'Amore if (!port->VPIobj.vfip) { 4492*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4493*a9800bebSGarrett D'Amore "RQ ENTRY: %s: No fabric connection. " 4494*a9800bebSGarrett D'Amore "Dropping...", 4495*a9800bebSGarrett D'Amore label); 4496*a9800bebSGarrett D'Amore 4497*a9800bebSGarrett D'Amore goto done; 4498*a9800bebSGarrett D'Amore } 4499*a9800bebSGarrett D'Amore 450082527734SSukumar Swaminathan /* Save the frame data to our seq buffer */ 450182527734SSukumar Swaminathan if (cqe->data_size && seq_mp) { 450282527734SSukumar Swaminathan /* Get the next data rqb */ 4503b3660a96SSukumar Swaminathan data_mp = &data_rq->rqb[host_index]; 4504b3660a96SSukumar Swaminathan 4505b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 4506b3660a96SSukumar Swaminathan data_mp->virt) - 4507b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 4508b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 450982527734SSukumar Swaminathan 4510b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(data_mp->dma_handle, offset, 451182527734SSukumar Swaminathan cqe->data_size, DDI_DMA_SYNC_FORKERNEL); 451282527734SSukumar Swaminathan 451382527734SSukumar Swaminathan data = (uint32_t *)data_mp->virt; 451482527734SSukumar Swaminathan 451582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 451682527734SSukumar Swaminathan "RQ DAT[%d]: %08x %08x %08x %08x %08x %08x ...", 451782527734SSukumar Swaminathan host_index, data[0], data[1], data[2], data[3], 451882527734SSukumar Swaminathan data[4], data[5]); 451982527734SSukumar Swaminathan 452082527734SSukumar Swaminathan /* Check sequence length */ 452182527734SSukumar Swaminathan if ((seq_len + cqe->data_size) > seq_mp->size) { 452282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4523*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Sequence buffer overflow. " 452482527734SSukumar Swaminathan "(%d > %d). Dropping...", 452582527734SSukumar Swaminathan label, (seq_len + cqe->data_size), seq_mp->size); 452682527734SSukumar Swaminathan 452782527734SSukumar Swaminathan goto done; 452882527734SSukumar Swaminathan } 452982527734SSukumar Swaminathan 453082527734SSukumar Swaminathan /* Copy data to local receive buffer */ 453182527734SSukumar Swaminathan bcopy((uint8_t *)data, ((uint8_t *)seq_mp->virt + 453282527734SSukumar Swaminathan seq_len), cqe->data_size); 453382527734SSukumar Swaminathan 453482527734SSukumar Swaminathan seq_len += cqe->data_size; 453582527734SSukumar Swaminathan } 453682527734SSukumar Swaminathan 453782527734SSukumar Swaminathan /* If this is not the last frame of sequence, queue it. */ 453882527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_END_SEQ)) { 453982527734SSukumar Swaminathan /* Save sequence header */ 454082527734SSukumar Swaminathan if (seq_cnt == 0) { 454182527734SSukumar Swaminathan bcopy((uint8_t *)&fchdr, (uint8_t *)iocb->RXFCHDR, 454282527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 454382527734SSukumar Swaminathan } 454482527734SSukumar Swaminathan 454582527734SSukumar Swaminathan /* Update sequence info in iocb */ 454682527734SSukumar Swaminathan iocb->RXSEQCNT = seq_cnt + 1; 454782527734SSukumar Swaminathan iocb->RXSEQLEN = seq_len; 454882527734SSukumar Swaminathan 454982527734SSukumar Swaminathan /* Queue iocbq for next frame */ 455082527734SSukumar Swaminathan emlxs_sli4_rxq_put(hba, iocbq); 455182527734SSukumar Swaminathan 455282527734SSukumar Swaminathan /* Don't free resources */ 455382527734SSukumar Swaminathan iocbq = NULL; 455482527734SSukumar Swaminathan 455582527734SSukumar Swaminathan /* No need to abort */ 455682527734SSukumar Swaminathan abort = 0; 455782527734SSukumar Swaminathan 455882527734SSukumar Swaminathan goto done; 455982527734SSukumar Swaminathan } 456082527734SSukumar Swaminathan 4561*a9800bebSGarrett D'Amore emlxs_sli4_rq_post(port, hdr_rq->qid); 456282527734SSukumar Swaminathan posted = 1; 456382527734SSukumar Swaminathan 456482527734SSukumar Swaminathan /* End of sequence found. Process request now. */ 456582527734SSukumar Swaminathan 456682527734SSukumar Swaminathan if (seq_cnt > 0) { 456782527734SSukumar Swaminathan /* Retrieve first frame of sequence */ 456882527734SSukumar Swaminathan bcopy((uint8_t *)iocb->RXFCHDR, (uint8_t *)&fchdr, 456982527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 457082527734SSukumar Swaminathan 457182527734SSukumar Swaminathan bzero((uint8_t *)iocb, sizeof (emlxs_iocb_t)); 457282527734SSukumar Swaminathan } 457382527734SSukumar Swaminathan 457482527734SSukumar Swaminathan /* Build rcv iocb and process it */ 457582527734SSukumar Swaminathan switch (fchdr.type) { 457682527734SSukumar Swaminathan case 0: /* BLS */ 457782527734SSukumar Swaminathan 457882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 457982527734SSukumar Swaminathan "RQ ENTRY: %s: xid:%x sid:%x. Sending BLS ACC...", 458082527734SSukumar Swaminathan label, fchdr.ox_id, fchdr.s_id); 458182527734SSukumar Swaminathan 458282527734SSukumar Swaminathan iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 458382527734SSukumar Swaminathan 458482527734SSukumar Swaminathan /* Set up an iotag using special Abort iotags */ 4585fe199829SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 458682527734SSukumar Swaminathan if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 458782527734SSukumar Swaminathan hba->fc_oor_iotag = hba->max_iotag; 458882527734SSukumar Swaminathan } 458982527734SSukumar Swaminathan iotag = hba->fc_oor_iotag++; 4590fe199829SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 459182527734SSukumar Swaminathan 459282527734SSukumar Swaminathan /* BLS ACC Response */ 459382527734SSukumar Swaminathan wqe = &iocbq->wqe; 459482527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 459582527734SSukumar Swaminathan 459682527734SSukumar Swaminathan wqe->Command = CMD_XMIT_BLS_RSP64_CX; 459782527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 459882527734SSukumar Swaminathan 459982527734SSukumar Swaminathan wqe->un.BlsRsp.Payload0 = 0x80; 460082527734SSukumar Swaminathan wqe->un.BlsRsp.Payload1 = fchdr.seq_id; 460182527734SSukumar Swaminathan 460282527734SSukumar Swaminathan wqe->un.BlsRsp.OXId = fchdr.ox_id; 460382527734SSukumar Swaminathan wqe->un.BlsRsp.RXId = fchdr.rx_id; 460482527734SSukumar Swaminathan 460582527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntLow = 0; 460682527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntHigh = 0xFFFF; 460782527734SSukumar Swaminathan 460882527734SSukumar Swaminathan wqe->un.BlsRsp.XO = 0; 460982527734SSukumar Swaminathan wqe->un.BlsRsp.AR = 0; 461082527734SSukumar Swaminathan wqe->un.BlsRsp.PT = 1; 461182527734SSukumar Swaminathan wqe->un.BlsRsp.RemoteId = fchdr.s_id; 461282527734SSukumar Swaminathan 461382527734SSukumar Swaminathan wqe->PU = 0x3; 4614*a9800bebSGarrett D'Amore wqe->ContextTag = port->VPIobj.VPI; 461582527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 461682527734SSukumar Swaminathan wqe->OXId = (volatile uint16_t) fchdr.ox_id; 461782527734SSukumar Swaminathan wqe->XRITag = 0xffff; 461882527734SSukumar Swaminathan 461982527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 462082527734SSukumar Swaminathan wqe->CCPE = 1; 462182527734SSukumar Swaminathan wqe->CCP = fchdr.rsvd; 462282527734SSukumar Swaminathan } 462382527734SSukumar Swaminathan 462482527734SSukumar Swaminathan wqe->Class = CLASS3; 462582527734SSukumar Swaminathan wqe->RequestTag = iotag; 462682527734SSukumar Swaminathan wqe->CQId = 0x3ff; 462782527734SSukumar Swaminathan 462882527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(hba, iocbq->channel, iocbq); 462982527734SSukumar Swaminathan 463082527734SSukumar Swaminathan break; 463182527734SSukumar Swaminathan 463282527734SSukumar Swaminathan case 1: /* ELS */ 4633*a9800bebSGarrett D'Amore if (!(port->VPIobj.flag & EMLXS_VPI_PORT_ENABLED)) { 4634*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4635*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Port not yet enabled. " 4636*a9800bebSGarrett D'Amore "Dropping...", 4637*a9800bebSGarrett D'Amore label); 4638*a9800bebSGarrett D'Amore 4639*a9800bebSGarrett D'Amore goto done; 4640*a9800bebSGarrett D'Amore } 4641*a9800bebSGarrett D'Amore 464282527734SSukumar Swaminathan cmd = *((uint32_t *)seq_mp->virt); 464382527734SSukumar Swaminathan cmd &= ELS_CMD_MASK; 4644*a9800bebSGarrett D'Amore rpip = NULL; 464582527734SSukumar Swaminathan 464682527734SSukumar Swaminathan if (cmd != ELS_CMD_LOGO) { 4647*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 464882527734SSukumar Swaminathan } 464982527734SSukumar Swaminathan 4650*a9800bebSGarrett D'Amore if (!rpip) { 4651*a9800bebSGarrett D'Amore rpip = port->VPIobj.rpip; 465282527734SSukumar Swaminathan } 465382527734SSukumar Swaminathan 4654*a9800bebSGarrett D'Amore xrip = emlxs_sli4_reserve_xri(hba, rpip); 465582527734SSukumar Swaminathan 4656*a9800bebSGarrett D'Amore if (!xrip) { 465782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4658*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of exchange " 465982527734SSukumar Swaminathan "resources. Dropping...", 466082527734SSukumar Swaminathan label); 466182527734SSukumar Swaminathan 466282527734SSukumar Swaminathan goto done; 466382527734SSukumar Swaminathan } 466482527734SSukumar Swaminathan 4665*a9800bebSGarrett D'Amore xrip->rx_id = fchdr.ox_id; 466682527734SSukumar Swaminathan 466782527734SSukumar Swaminathan /* Build CMD_RCV_ELS64_CX */ 466882527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeFlags = 0; 466982527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeSize = seq_len; 467082527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrLow = PADDR_LO(seq_mp->phys); 467182527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrHigh = PADDR_HI(seq_mp->phys); 467282527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 467382527734SSukumar Swaminathan 467482527734SSukumar Swaminathan iocb->un.rcvels64.remoteID = fchdr.s_id; 467582527734SSukumar Swaminathan iocb->un.rcvels64.parmRo = fchdr.d_id; 467682527734SSukumar Swaminathan 467782527734SSukumar Swaminathan iocb->ULPPU = 0x3; 4678*a9800bebSGarrett D'Amore iocb->ULPCONTEXT = xrip->XRI; 467982527734SSukumar Swaminathan iocb->ULPIOTAG = ((node)? node->nlp_Rpi:0); 468082527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 468182527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_ELS64_CX; 468282527734SSukumar Swaminathan 468382527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 4684*a9800bebSGarrett D'Amore iocb->unsli3.ext_rcv.vpi = port->VPIobj.VPI; 468582527734SSukumar Swaminathan 468682527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 468782527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 468882527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 468982527734SSukumar Swaminathan } 469082527734SSukumar Swaminathan 469182527734SSukumar Swaminathan (void) emlxs_els_handle_unsol_req(port, iocbq->channel, 469282527734SSukumar Swaminathan iocbq, seq_mp, seq_len); 469382527734SSukumar Swaminathan 469482527734SSukumar Swaminathan break; 469582527734SSukumar Swaminathan 469682527734SSukumar Swaminathan case 0x20: /* CT */ 4697*a9800bebSGarrett D'Amore if (!(port->VPIobj.flag & EMLXS_VPI_PORT_ENABLED)) { 4698*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4699*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Port not yet enabled. " 4700*a9800bebSGarrett D'Amore "Dropping...", 4701*a9800bebSGarrett D'Amore label); 4702*a9800bebSGarrett D'Amore 4703*a9800bebSGarrett D'Amore goto done; 4704*a9800bebSGarrett D'Amore } 470582527734SSukumar Swaminathan 470682527734SSukumar Swaminathan if (!node) { 470782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4708*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Node not found (did=%x). " 470982527734SSukumar Swaminathan "Dropping...", 471082527734SSukumar Swaminathan label, fchdr.d_id); 471182527734SSukumar Swaminathan 471282527734SSukumar Swaminathan goto done; 471382527734SSukumar Swaminathan } 471482527734SSukumar Swaminathan 4715*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 471682527734SSukumar Swaminathan 4717*a9800bebSGarrett D'Amore if (!rpip) { 471882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4719*a9800bebSGarrett D'Amore "RQ ENTRY: %s: RPI not found (did=%x rpi=%x). " 472082527734SSukumar Swaminathan "Dropping...", 472182527734SSukumar Swaminathan label, fchdr.d_id, node->nlp_Rpi); 472282527734SSukumar Swaminathan 472382527734SSukumar Swaminathan goto done; 472482527734SSukumar Swaminathan } 472582527734SSukumar Swaminathan 4726*a9800bebSGarrett D'Amore xrip = emlxs_sli4_reserve_xri(hba, rpip); 472782527734SSukumar Swaminathan 4728*a9800bebSGarrett D'Amore if (!xrip) { 472982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4730*a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of exchange " 473182527734SSukumar Swaminathan "resources. Dropping...", 473282527734SSukumar Swaminathan label); 473382527734SSukumar Swaminathan 473482527734SSukumar Swaminathan goto done; 473582527734SSukumar Swaminathan } 473682527734SSukumar Swaminathan 4737*a9800bebSGarrett D'Amore xrip->rx_id = fchdr.ox_id; 473882527734SSukumar Swaminathan 473982527734SSukumar Swaminathan /* Build CMD_RCV_SEQ64_CX */ 474082527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeFlags = 0; 474182527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeSize = seq_len; 474282527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrLow = PADDR_LO(seq_mp->phys); 474382527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrHigh = PADDR_HI(seq_mp->phys); 474482527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 474582527734SSukumar Swaminathan 474682527734SSukumar Swaminathan iocb->un.rcvseq64.xrsqRo = 0; 474782527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Rctl = fchdr.r_ctl; 474882527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Type = fchdr.type; 474982527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Dfctl = fchdr.df_ctl; 475082527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Fctl = fchdr.f_ctl; 475182527734SSukumar Swaminathan 475282527734SSukumar Swaminathan iocb->ULPPU = 0x3; 4753*a9800bebSGarrett D'Amore iocb->ULPCONTEXT = xrip->XRI; 4754*a9800bebSGarrett D'Amore iocb->ULPIOTAG = rpip->RPI; 475582527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 475682527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_SEQ64_CX; 475782527734SSukumar Swaminathan 475882527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 4759*a9800bebSGarrett D'Amore iocb->unsli3.ext_rcv.vpi = port->VPIobj.VPI; 476082527734SSukumar Swaminathan 476182527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 476282527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 476382527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 476482527734SSukumar Swaminathan } 476582527734SSukumar Swaminathan 476682527734SSukumar Swaminathan (void) emlxs_ct_handle_unsol_req(port, iocbq->channel, 476782527734SSukumar Swaminathan iocbq, seq_mp, seq_len); 476882527734SSukumar Swaminathan 476982527734SSukumar Swaminathan break; 477082527734SSukumar Swaminathan } 477182527734SSukumar Swaminathan 477282527734SSukumar Swaminathan /* Sequence handled, no need to abort */ 477382527734SSukumar Swaminathan abort = 0; 477482527734SSukumar Swaminathan 477582527734SSukumar Swaminathan done: 477682527734SSukumar Swaminathan 477782527734SSukumar Swaminathan if (!posted) { 4778*a9800bebSGarrett D'Amore emlxs_sli4_rq_post(port, hdr_rq->qid); 477982527734SSukumar Swaminathan } 478082527734SSukumar Swaminathan 478182527734SSukumar Swaminathan if (abort) { 478282527734SSukumar Swaminathan /* Send ABTS for this exchange */ 478382527734SSukumar Swaminathan /* !!! Currently, we have no implementation for this !!! */ 478482527734SSukumar Swaminathan abort = 0; 478582527734SSukumar Swaminathan } 478682527734SSukumar Swaminathan 478782527734SSukumar Swaminathan /* Return memory resources to pools */ 478882527734SSukumar Swaminathan if (iocbq) { 478982527734SSukumar Swaminathan if (iocbq->bp) { 4790*a9800bebSGarrett D'Amore emlxs_mem_put(hba, buf_type, (void *)iocbq->bp); 479182527734SSukumar Swaminathan } 479282527734SSukumar Swaminathan 4793*a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 479482527734SSukumar Swaminathan } 479582527734SSukumar Swaminathan 4796b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 4797b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 4798b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle) 4799b3660a96SSukumar Swaminathan != DDI_FM_OK) { 4800b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 4801b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 4802b3660a96SSukumar Swaminathan "emlxs_sli4_process_unsol_rcv: hdl=%p", 4803b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle); 4804b3660a96SSukumar Swaminathan 4805b3660a96SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_restart_thread, 4806*a9800bebSGarrett D'Amore 0, 0); 4807b3660a96SSukumar Swaminathan } 4808b3660a96SSukumar Swaminathan #endif 480982527734SSukumar Swaminathan return; 481082527734SSukumar Swaminathan 481182527734SSukumar Swaminathan } /* emlxs_sli4_process_unsol_rcv() */ 481282527734SSukumar Swaminathan 481382527734SSukumar Swaminathan 481482527734SSukumar Swaminathan /*ARGSUSED*/ 481582527734SSukumar Swaminathan static void 481682527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(emlxs_hba_t *hba, CQ_DESC_t *cq, 481782527734SSukumar Swaminathan CQE_XRI_Abort_t *cqe) 481882527734SSukumar Swaminathan { 481982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4820*a9800bebSGarrett D'Amore XRIobj_t *xrip; 4821*a9800bebSGarrett D'Amore 4822*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 482382527734SSukumar Swaminathan 4824*a9800bebSGarrett D'Amore xrip = emlxs_sli4_find_xri(hba, cqe->XRI); 4825*a9800bebSGarrett D'Amore if (xrip == NULL) { 482682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 482782527734SSukumar Swaminathan "CQ ENTRY: process xri aborted ignored"); 4828*a9800bebSGarrett D'Amore 4829*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 483082527734SSukumar Swaminathan return; 483182527734SSukumar Swaminathan } 483282527734SSukumar Swaminathan 483382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 483482527734SSukumar Swaminathan "CQ ENTRY: process xri x%x aborted: IA %d EO %d BR %d", 483582527734SSukumar Swaminathan cqe->XRI, cqe->IA, cqe->EO, cqe->BR); 483682527734SSukumar Swaminathan 4837*a9800bebSGarrett D'Amore if (!(xrip->flag & EMLXS_XRI_ABORT_INP)) { 483882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 483982527734SSukumar Swaminathan "XRI Aborted: Bad state: x%x xri x%x", 4840*a9800bebSGarrett D'Amore xrip->flag, xrip->XRI); 4841*a9800bebSGarrett D'Amore 4842*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 484382527734SSukumar Swaminathan return; 484482527734SSukumar Swaminathan } 484582527734SSukumar Swaminathan 484682527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 4847*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(hba, 0, xrip, 0); 4848*a9800bebSGarrett D'Amore 4849*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 4850*a9800bebSGarrett D'Amore 4851*a9800bebSGarrett D'Amore return; 485282527734SSukumar Swaminathan 485382527734SSukumar Swaminathan } /* emlxs_sli4_process_xri_aborted () */ 485482527734SSukumar Swaminathan 485582527734SSukumar Swaminathan 485682527734SSukumar Swaminathan /*ARGSUSED*/ 485782527734SSukumar Swaminathan static void 485882527734SSukumar Swaminathan emlxs_sli4_process_cq(emlxs_hba_t *hba, CQ_DESC_t *cq) 485982527734SSukumar Swaminathan { 486082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 486182527734SSukumar Swaminathan CQE_u *cqe; 486282527734SSukumar Swaminathan CQE_u cq_entry; 486382527734SSukumar Swaminathan uint32_t cqdb; 486482527734SSukumar Swaminathan int num_entries = 0; 4865b3660a96SSukumar Swaminathan off_t offset; 486682527734SSukumar Swaminathan 486782527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 486882527734SSukumar Swaminathan 486982527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 487082527734SSukumar Swaminathan cqe += cq->host_index; 487182527734SSukumar Swaminathan 4872b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 4873b3660a96SSukumar Swaminathan cq->addr.virt) - 4874b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 4875b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 4876b3660a96SSukumar Swaminathan 4877b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(cq->addr.dma_handle, offset, 487882527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 487982527734SSukumar Swaminathan 488082527734SSukumar Swaminathan for (;;) { 488182527734SSukumar Swaminathan cq_entry.word[3] = BE_SWAP32(cqe->word[3]); 488282527734SSukumar Swaminathan if (!(cq_entry.word[3] & CQE_VALID)) 488382527734SSukumar Swaminathan break; 488482527734SSukumar Swaminathan 488582527734SSukumar Swaminathan cq_entry.word[2] = BE_SWAP32(cqe->word[2]); 488682527734SSukumar Swaminathan cq_entry.word[1] = BE_SWAP32(cqe->word[1]); 488782527734SSukumar Swaminathan cq_entry.word[0] = BE_SWAP32(cqe->word[0]); 488882527734SSukumar Swaminathan 488982527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 489082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 489182527734SSukumar Swaminathan "CQ ENTRY: %08x %08x %08x %08x", cq_entry.word[0], 489282527734SSukumar Swaminathan cq_entry.word[1], cq_entry.word[2], cq_entry.word[3]); 489382527734SSukumar Swaminathan #endif 489482527734SSukumar Swaminathan 489582527734SSukumar Swaminathan num_entries++; 489682527734SSukumar Swaminathan cqe->word[3] = 0; 489782527734SSukumar Swaminathan 489882527734SSukumar Swaminathan cq->host_index++; 489982527734SSukumar Swaminathan if (cq->host_index >= cq->max_index) { 490082527734SSukumar Swaminathan cq->host_index = 0; 490182527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 490282527734SSukumar Swaminathan } else { 490382527734SSukumar Swaminathan cqe++; 490482527734SSukumar Swaminathan } 490582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 490682527734SSukumar Swaminathan 490782527734SSukumar Swaminathan /* Now handle specific cq type */ 490882527734SSukumar Swaminathan if (cq->type == EMLXS_CQ_TYPE_GROUP1) { 490982527734SSukumar Swaminathan if (cq_entry.cqAsyncEntry.async_evt) { 491082527734SSukumar Swaminathan emlxs_sli4_process_async_event(hba, 491182527734SSukumar Swaminathan (CQE_ASYNC_t *)&cq_entry); 491282527734SSukumar Swaminathan } else { 491382527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(hba, 491482527734SSukumar Swaminathan (CQE_MBOX_t *)&cq_entry); 491582527734SSukumar Swaminathan } 491682527734SSukumar Swaminathan } else { /* EMLXS_CQ_TYPE_GROUP2 */ 491782527734SSukumar Swaminathan switch (cq_entry.cqCmplEntry.Code) { 491882527734SSukumar Swaminathan case CQE_TYPE_WQ_COMPLETION: 491982527734SSukumar Swaminathan if (cq_entry.cqCmplEntry.RequestTag < 492082527734SSukumar Swaminathan hba->max_iotag) { 492182527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(hba, cq, 492282527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 492382527734SSukumar Swaminathan } else { 492482527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(hba, cq, 492582527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 492682527734SSukumar Swaminathan } 492782527734SSukumar Swaminathan break; 492882527734SSukumar Swaminathan case CQE_TYPE_RELEASE_WQE: 492982527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(hba, cq, 493082527734SSukumar Swaminathan (CQE_RelWQ_t *)&cq_entry); 493182527734SSukumar Swaminathan break; 493282527734SSukumar Swaminathan case CQE_TYPE_UNSOL_RCV: 493382527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(hba, cq, 493482527734SSukumar Swaminathan (CQE_UnsolRcv_t *)&cq_entry); 493582527734SSukumar Swaminathan break; 493682527734SSukumar Swaminathan case CQE_TYPE_XRI_ABORTED: 493782527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(hba, cq, 493882527734SSukumar Swaminathan (CQE_XRI_Abort_t *)&cq_entry); 493982527734SSukumar Swaminathan break; 494082527734SSukumar Swaminathan default: 494182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 494282527734SSukumar Swaminathan "Invalid CQ entry %d: %08x %08x %08x %08x", 494382527734SSukumar Swaminathan cq_entry.cqCmplEntry.Code, cq_entry.word[0], 494482527734SSukumar Swaminathan cq_entry.word[1], cq_entry.word[2], 494582527734SSukumar Swaminathan cq_entry.word[3]); 494682527734SSukumar Swaminathan break; 494782527734SSukumar Swaminathan } 494882527734SSukumar Swaminathan } 494982527734SSukumar Swaminathan 495082527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 495182527734SSukumar Swaminathan } 495282527734SSukumar Swaminathan 495382527734SSukumar Swaminathan cqdb = cq->qid; 495482527734SSukumar Swaminathan cqdb |= CQ_DB_REARM; 495582527734SSukumar Swaminathan if (num_entries != 0) { 495682527734SSukumar Swaminathan cqdb |= ((num_entries << CQ_DB_POP_SHIFT) & CQ_DB_POP_MASK); 495782527734SSukumar Swaminathan } 495882527734SSukumar Swaminathan 495982527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 496082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 496182527734SSukumar Swaminathan "CQ CLEAR: %08x: pops:x%x", cqdb, num_entries); 496282527734SSukumar Swaminathan #endif 496382527734SSukumar Swaminathan 496482527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), cqdb); 496582527734SSukumar Swaminathan 496682527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 496782527734SSukumar Swaminathan 496882527734SSukumar Swaminathan } /* emlxs_sli4_process_cq() */ 496982527734SSukumar Swaminathan 497082527734SSukumar Swaminathan 497182527734SSukumar Swaminathan /*ARGSUSED*/ 497282527734SSukumar Swaminathan static void 497382527734SSukumar Swaminathan emlxs_sli4_process_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 497482527734SSukumar Swaminathan { 4975bce54adfSSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 497682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4977bce54adfSSukumar Swaminathan #endif 497882527734SSukumar Swaminathan uint32_t eqdb; 497982527734SSukumar Swaminathan uint32_t *ptr; 498082527734SSukumar Swaminathan CHANNEL *cp; 498182527734SSukumar Swaminathan EQE_u eqe; 498282527734SSukumar Swaminathan uint32_t i; 498382527734SSukumar Swaminathan uint32_t value; 498482527734SSukumar Swaminathan int num_entries = 0; 4985b3660a96SSukumar Swaminathan off_t offset; 498682527734SSukumar Swaminathan 498782527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 498882527734SSukumar Swaminathan 498982527734SSukumar Swaminathan ptr = eq->addr.virt; 499082527734SSukumar Swaminathan ptr += eq->host_index; 499182527734SSukumar Swaminathan 4992b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 4993b3660a96SSukumar Swaminathan eq->addr.virt) - 4994b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 4995b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 4996b3660a96SSukumar Swaminathan 4997b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset, 499882527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 499982527734SSukumar Swaminathan 500082527734SSukumar Swaminathan for (;;) { 500182527734SSukumar Swaminathan eqe.word = *ptr; 500282527734SSukumar Swaminathan eqe.word = BE_SWAP32(eqe.word); 500382527734SSukumar Swaminathan 500482527734SSukumar Swaminathan if (!(eqe.word & EQE_VALID)) 500582527734SSukumar Swaminathan break; 500682527734SSukumar Swaminathan 500782527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 500882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 500982527734SSukumar Swaminathan "EQ ENTRY: %08x", eqe.word); 501082527734SSukumar Swaminathan #endif 501182527734SSukumar Swaminathan 501282527734SSukumar Swaminathan *ptr = 0; 501382527734SSukumar Swaminathan num_entries++; 501482527734SSukumar Swaminathan eq->host_index++; 501582527734SSukumar Swaminathan if (eq->host_index >= eq->max_index) { 501682527734SSukumar Swaminathan eq->host_index = 0; 501782527734SSukumar Swaminathan ptr = eq->addr.virt; 501882527734SSukumar Swaminathan } else { 501982527734SSukumar Swaminathan ptr++; 502082527734SSukumar Swaminathan } 502182527734SSukumar Swaminathan 502282527734SSukumar Swaminathan value = hba->sli.sli4.cq_map[eqe.entry.CQId]; 502382527734SSukumar Swaminathan 502482527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 502582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 502682527734SSukumar Swaminathan "EQ ENTRY: CQIndex:x%x: cqid:x%x", value, eqe.entry.CQId); 502782527734SSukumar Swaminathan #endif 502882527734SSukumar Swaminathan 502982527734SSukumar Swaminathan emlxs_sli4_process_cq(hba, &hba->sli.sli4.cq[value]); 503082527734SSukumar Swaminathan } 503182527734SSukumar Swaminathan 503282527734SSukumar Swaminathan eqdb = eq->qid; 503382527734SSukumar Swaminathan eqdb |= (EQ_DB_CLEAR | EQ_DB_EVENT | EQ_DB_REARM); 503482527734SSukumar Swaminathan 503582527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 503682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 503782527734SSukumar Swaminathan "EQ CLEAR: %08x: pops:x%x", eqdb, num_entries); 503882527734SSukumar Swaminathan #endif 503982527734SSukumar Swaminathan 504082527734SSukumar Swaminathan if (num_entries != 0) { 504182527734SSukumar Swaminathan eqdb |= ((num_entries << EQ_DB_POP_SHIFT) & EQ_DB_POP_MASK); 504282527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 504382527734SSukumar Swaminathan cp = &hba->chan[i]; 504482527734SSukumar Swaminathan if (cp->chan_flag & EMLXS_NEEDS_TRIGGER) { 504582527734SSukumar Swaminathan cp->chan_flag &= ~EMLXS_NEEDS_TRIGGER; 504682527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 504782527734SSukumar Swaminathan emlxs_proc_channel, cp); 504882527734SSukumar Swaminathan } 504982527734SSukumar Swaminathan } 505082527734SSukumar Swaminathan } 505182527734SSukumar Swaminathan 505282527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), eqdb); 505382527734SSukumar Swaminathan 505482527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 505582527734SSukumar Swaminathan 505682527734SSukumar Swaminathan } /* emlxs_sli4_process_eq() */ 505782527734SSukumar Swaminathan 505882527734SSukumar Swaminathan 505982527734SSukumar Swaminathan #ifdef MSI_SUPPORT 506082527734SSukumar Swaminathan /*ARGSUSED*/ 506182527734SSukumar Swaminathan static uint32_t 506282527734SSukumar Swaminathan emlxs_sli4_msi_intr(char *arg1, char *arg2) 506382527734SSukumar Swaminathan { 506482527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg1; 5065bce54adfSSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 506682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5067bce54adfSSukumar Swaminathan #endif 506882527734SSukumar Swaminathan uint16_t msgid; 506982527734SSukumar Swaminathan int rc; 507082527734SSukumar Swaminathan 507182527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 507282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 507382527734SSukumar Swaminathan "msiINTR arg1:%p arg2:%p", arg1, arg2); 507482527734SSukumar Swaminathan #endif 507582527734SSukumar Swaminathan 507682527734SSukumar Swaminathan /* Check for legacy interrupt handling */ 507782527734SSukumar Swaminathan if (hba->intr_type == DDI_INTR_TYPE_FIXED) { 507882527734SSukumar Swaminathan rc = emlxs_sli4_intx_intr(arg1); 507982527734SSukumar Swaminathan return (rc); 508082527734SSukumar Swaminathan } 508182527734SSukumar Swaminathan 508282527734SSukumar Swaminathan /* Get MSI message id */ 508382527734SSukumar Swaminathan msgid = (uint16_t)((unsigned long)arg2); 508482527734SSukumar Swaminathan 508582527734SSukumar Swaminathan /* Validate the message id */ 508682527734SSukumar Swaminathan if (msgid >= hba->intr_count) { 508782527734SSukumar Swaminathan msgid = 0; 508882527734SSukumar Swaminathan } 508982527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 509082527734SSukumar Swaminathan 5091bce54adfSSukumar Swaminathan if ((hba->state == FC_KILLED) || (hba->flag & FC_OFFLINE_MODE)) { 509282527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 509382527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 509482527734SSukumar Swaminathan } 509582527734SSukumar Swaminathan 509682527734SSukumar Swaminathan /* The eq[] index == the MSI vector number */ 509782527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[msgid]); 509882527734SSukumar Swaminathan 509982527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 510082527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 510182527734SSukumar Swaminathan 510282527734SSukumar Swaminathan } /* emlxs_sli4_msi_intr() */ 510382527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 510482527734SSukumar Swaminathan 510582527734SSukumar Swaminathan 510682527734SSukumar Swaminathan /*ARGSUSED*/ 510782527734SSukumar Swaminathan static int 510882527734SSukumar Swaminathan emlxs_sli4_intx_intr(char *arg) 510982527734SSukumar Swaminathan { 511082527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg; 5111bce54adfSSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 511282527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5113bce54adfSSukumar Swaminathan #endif 511482527734SSukumar Swaminathan 511582527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 511682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 511782527734SSukumar Swaminathan "intxINTR arg:%p", arg); 511882527734SSukumar Swaminathan #endif 511982527734SSukumar Swaminathan 512082527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 512182527734SSukumar Swaminathan 5122bce54adfSSukumar Swaminathan if ((hba->state == FC_KILLED) || (hba->flag & FC_OFFLINE_MODE)) { 512382527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 512482527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 512582527734SSukumar Swaminathan } 512682527734SSukumar Swaminathan 512782527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[0]); 512882527734SSukumar Swaminathan 512982527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 513082527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 513182527734SSukumar Swaminathan } /* emlxs_sli4_intx_intr() */ 513282527734SSukumar Swaminathan 513382527734SSukumar Swaminathan 513482527734SSukumar Swaminathan static void 513582527734SSukumar Swaminathan emlxs_sli4_hba_kill(emlxs_hba_t *hba) 513682527734SSukumar Swaminathan { 513782527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 513882527734SSukumar Swaminathan uint32_t j; 513982527734SSukumar Swaminathan 514082527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 514182527734SSukumar Swaminathan if (hba->flag & FC_INTERLOCKED) { 514282527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 514382527734SSukumar Swaminathan 514482527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 514582527734SSukumar Swaminathan 514682527734SSukumar Swaminathan return; 514782527734SSukumar Swaminathan } 514882527734SSukumar Swaminathan 514982527734SSukumar Swaminathan j = 0; 515082527734SSukumar Swaminathan while (j++ < 10000) { 515182527734SSukumar Swaminathan if (hba->mbox_queue_flag == 0) { 515282527734SSukumar Swaminathan break; 515382527734SSukumar Swaminathan } 515482527734SSukumar Swaminathan 515582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 515682527734SSukumar Swaminathan DELAYUS(100); 515782527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 515882527734SSukumar Swaminathan } 515982527734SSukumar Swaminathan 516082527734SSukumar Swaminathan if (hba->mbox_queue_flag != 0) { 516182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 516282527734SSukumar Swaminathan "Board kill failed. Mailbox busy."); 516382527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 516482527734SSukumar Swaminathan return; 516582527734SSukumar Swaminathan } 516682527734SSukumar Swaminathan 516782527734SSukumar Swaminathan hba->flag |= FC_INTERLOCKED; 516882527734SSukumar Swaminathan 516982527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 517082527734SSukumar Swaminathan 517182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 517282527734SSukumar Swaminathan 517382527734SSukumar Swaminathan } /* emlxs_sli4_hba_kill() */ 517482527734SSukumar Swaminathan 517582527734SSukumar Swaminathan 517682527734SSukumar Swaminathan static void 517782527734SSukumar Swaminathan emlxs_sli4_enable_intr(emlxs_hba_t *hba) 517882527734SSukumar Swaminathan { 517982527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 518082527734SSukumar Swaminathan int i; 518182527734SSukumar Swaminathan int num_cq; 518282527734SSukumar Swaminathan uint32_t data; 518382527734SSukumar Swaminathan 518482527734SSukumar Swaminathan hba->sli.sli4.flag |= EMLXS_SLI4_INTR_ENABLED; 518582527734SSukumar Swaminathan 518682527734SSukumar Swaminathan num_cq = (hba->intr_count * cfg[CFG_NUM_WQ].current) + 518782527734SSukumar Swaminathan EMLXS_CQ_OFFSET_WQ; 518882527734SSukumar Swaminathan 518982527734SSukumar Swaminathan /* ARM EQ / CQs */ 519082527734SSukumar Swaminathan for (i = 0; i < num_cq; i++) { 519182527734SSukumar Swaminathan data = hba->sli.sli4.cq[i].qid; 519282527734SSukumar Swaminathan data |= CQ_DB_REARM; 519382527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), data); 519482527734SSukumar Swaminathan } 519582527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 519682527734SSukumar Swaminathan data = hba->sli.sli4.eq[i].qid; 519782527734SSukumar Swaminathan data |= (EQ_DB_REARM | EQ_DB_EVENT); 519882527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), data); 519982527734SSukumar Swaminathan } 520082527734SSukumar Swaminathan } /* emlxs_sli4_enable_intr() */ 520182527734SSukumar Swaminathan 520282527734SSukumar Swaminathan 520382527734SSukumar Swaminathan static void 520482527734SSukumar Swaminathan emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att) 520582527734SSukumar Swaminathan { 520682527734SSukumar Swaminathan if (att) { 520782527734SSukumar Swaminathan return; 520882527734SSukumar Swaminathan } 520982527734SSukumar Swaminathan 521082527734SSukumar Swaminathan hba->sli.sli4.flag &= ~EMLXS_SLI4_INTR_ENABLED; 521182527734SSukumar Swaminathan 521282527734SSukumar Swaminathan /* Short of reset, we cannot disable interrupts */ 521382527734SSukumar Swaminathan } /* emlxs_sli4_disable_intr() */ 521482527734SSukumar Swaminathan 521582527734SSukumar Swaminathan 521682527734SSukumar Swaminathan static void 521782527734SSukumar Swaminathan emlxs_sli4_resource_free(emlxs_hba_t *hba) 521882527734SSukumar Swaminathan { 521982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 522082527734SSukumar Swaminathan MBUF_INFO *buf_info; 522182527734SSukumar Swaminathan uint32_t i; 522282527734SSukumar Swaminathan 5223*a9800bebSGarrett D'Amore emlxs_fcf_fini(hba); 522482527734SSukumar Swaminathan 522582527734SSukumar Swaminathan buf_info = &hba->sli.sli4.HeaderTmplate; 522682527734SSukumar Swaminathan if (buf_info->virt) { 522782527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 522882527734SSukumar Swaminathan } 522982527734SSukumar Swaminathan 523082527734SSukumar Swaminathan if (hba->sli.sli4.XRIp) { 523182527734SSukumar Swaminathan if ((hba->sli.sli4.XRIinuse_f != 523282527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) || 523382527734SSukumar Swaminathan (hba->sli.sli4.XRIinuse_b != 523482527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f)) { 5235*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 523682527734SSukumar Swaminathan "XRIs inuse during free!: %p %p != %p\n", 523782527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_f, 523882527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b, 523982527734SSukumar Swaminathan &hba->sli.sli4.XRIinuse_f); 524082527734SSukumar Swaminathan } 524182527734SSukumar Swaminathan kmem_free(hba->sli.sli4.XRIp, 524282527734SSukumar Swaminathan (sizeof (XRIobj_t) * hba->sli.sli4.XRICount)); 524382527734SSukumar Swaminathan hba->sli.sli4.XRIp = NULL; 5244b3660a96SSukumar Swaminathan 5245b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_f = 5246b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5247b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_b = 5248b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 524982527734SSukumar Swaminathan hba->sli.sli4.xrif_count = 0; 525082527734SSukumar Swaminathan } 525182527734SSukumar Swaminathan 525282527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQS; i++) { 5253b3660a96SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.eq[i].lastwq_lock); 525482527734SSukumar Swaminathan bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 525582527734SSukumar Swaminathan } 525682527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQS; i++) { 525782527734SSukumar Swaminathan bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 525882527734SSukumar Swaminathan } 525982527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQS; i++) { 526082527734SSukumar Swaminathan bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 526182527734SSukumar Swaminathan } 526282527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 5263b3660a96SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.rq[i].lock); 5264b3660a96SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.rxq[i].lock); 5265b3660a96SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 526682527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 526782527734SSukumar Swaminathan } 526882527734SSukumar Swaminathan 526982527734SSukumar Swaminathan /* Free the MQ */ 5270b3660a96SSukumar Swaminathan bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 5271b3660a96SSukumar Swaminathan 5272b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.slim2; 5273b3660a96SSukumar Swaminathan if (buf_info->virt) { 527482527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 527582527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 5276b3660a96SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 527782527734SSukumar Swaminathan } 527882527734SSukumar Swaminathan 527982527734SSukumar Swaminathan /* Cleanup queue ordinal mapping */ 528082527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQ_IDS; i++) { 528182527734SSukumar Swaminathan hba->sli.sli4.eq_map[i] = 0xffff; 528282527734SSukumar Swaminathan } 528382527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQ_IDS; i++) { 528482527734SSukumar Swaminathan hba->sli.sli4.cq_map[i] = 0xffff; 528582527734SSukumar Swaminathan } 528682527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQ_IDS; i++) { 528782527734SSukumar Swaminathan hba->sli.sli4.wq_map[i] = 0xffff; 528882527734SSukumar Swaminathan } 528982527734SSukumar Swaminathan 529082527734SSukumar Swaminathan } /* emlxs_sli4_resource_free() */ 529182527734SSukumar Swaminathan 529282527734SSukumar Swaminathan 529382527734SSukumar Swaminathan static int 529482527734SSukumar Swaminathan emlxs_sli4_resource_alloc(emlxs_hba_t *hba) 529582527734SSukumar Swaminathan { 529682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 529782527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 529882527734SSukumar Swaminathan MBUF_INFO *buf_info; 529982527734SSukumar Swaminathan uint16_t index; 530082527734SSukumar Swaminathan int num_eq; 530182527734SSukumar Swaminathan int num_wq; 5302*a9800bebSGarrett D'Amore uint16_t i; 530382527734SSukumar Swaminathan uint32_t j; 530482527734SSukumar Swaminathan uint32_t k; 530582527734SSukumar Swaminathan uint32_t word; 5306*a9800bebSGarrett D'Amore XRIobj_t *xrip; 530782527734SSukumar Swaminathan char buf[64]; 530882527734SSukumar Swaminathan RQE_t *rqe; 5309b3660a96SSukumar Swaminathan MBUF_INFO *rqb; 5310b3660a96SSukumar Swaminathan uint64_t phys; 5311b3660a96SSukumar Swaminathan uint64_t tmp_phys; 5312b3660a96SSukumar Swaminathan char *virt; 5313b3660a96SSukumar Swaminathan char *tmp_virt; 5314b3660a96SSukumar Swaminathan void *data_handle; 5315b3660a96SSukumar Swaminathan void *dma_handle; 5316b3660a96SSukumar Swaminathan int32_t size; 5317b3660a96SSukumar Swaminathan off_t offset; 5318b3660a96SSukumar Swaminathan uint32_t count = 0; 531982527734SSukumar Swaminathan 5320*a9800bebSGarrett D'Amore emlxs_fcf_init(hba); 532182527734SSukumar Swaminathan 5322b3660a96SSukumar Swaminathan /* EQs - 1 per Interrupt vector */ 5323b3660a96SSukumar Swaminathan num_eq = hba->intr_count; 5324b3660a96SSukumar Swaminathan /* CQs - number of WQs + 1 for RQs + 1 for mbox/async events */ 5325b3660a96SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current * num_eq; 532682527734SSukumar Swaminathan 5327b3660a96SSukumar Swaminathan /* Calculate total dmable memory we need */ 5328b3660a96SSukumar Swaminathan /* EQ */ 5329b3660a96SSukumar Swaminathan count += num_eq * 4096; 5330b3660a96SSukumar Swaminathan /* CQ */ 5331b3660a96SSukumar Swaminathan count += (num_wq + EMLXS_CQ_OFFSET_WQ) * 4096; 5332b3660a96SSukumar Swaminathan /* WQ */ 5333b3660a96SSukumar Swaminathan count += num_wq * (4096 * EMLXS_NUM_WQ_PAGES); 5334b3660a96SSukumar Swaminathan /* MQ */ 5335b3660a96SSukumar Swaminathan count += EMLXS_MAX_MQS * 4096; 5336b3660a96SSukumar Swaminathan /* RQ */ 5337b3660a96SSukumar Swaminathan count += EMLXS_MAX_RQS * 4096; 5338b3660a96SSukumar Swaminathan /* RQB/E */ 5339b3660a96SSukumar Swaminathan count += RQB_COUNT * (RQB_DATA_SIZE + RQB_HEADER_SIZE); 5340b3660a96SSukumar Swaminathan /* SGL */ 5341b3660a96SSukumar Swaminathan count += hba->sli.sli4.XRICount * hba->sli.sli4.mem_sgl_size; 5342b3660a96SSukumar Swaminathan /* RPI Head Template */ 5343b3660a96SSukumar Swaminathan count += hba->sli.sli4.RPICount * sizeof (RPIHdrTmplate_t); 5344b3660a96SSukumar Swaminathan 5345b3660a96SSukumar Swaminathan /* Allocate slim2 for SLI4 */ 5346b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.slim2; 5347b3660a96SSukumar Swaminathan buf_info->size = count; 5348b3660a96SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5349b3660a96SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5350b3660a96SSukumar Swaminathan 5351b3660a96SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 535282527734SSukumar Swaminathan 5353b3660a96SSukumar Swaminathan if (buf_info->virt == NULL) { 5354b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5355b3660a96SSukumar Swaminathan &emlxs_init_failed_msg, 5356b3660a96SSukumar Swaminathan "Unable to allocate internal memory for SLI4: %d", 5357b3660a96SSukumar Swaminathan count); 5358b3660a96SSukumar Swaminathan goto failed; 535982527734SSukumar Swaminathan } 5360b3660a96SSukumar Swaminathan bzero(buf_info->virt, buf_info->size); 5361b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(buf_info->dma_handle, 0, 5362b3660a96SSukumar Swaminathan buf_info->size, DDI_DMA_SYNC_FORDEV); 536382527734SSukumar Swaminathan 5364b3660a96SSukumar Swaminathan /* Assign memory to SGL, Head Template, EQ, CQ, WQ, RQ and MQ */ 5365b3660a96SSukumar Swaminathan data_handle = buf_info->data_handle; 5366b3660a96SSukumar Swaminathan dma_handle = buf_info->dma_handle; 5367b3660a96SSukumar Swaminathan phys = buf_info->phys; 5368b3660a96SSukumar Swaminathan virt = (char *)buf_info->virt; 536982527734SSukumar Swaminathan 537082527734SSukumar Swaminathan /* Allocate space for queues */ 5371b3660a96SSukumar Swaminathan size = 4096; 537282527734SSukumar Swaminathan for (i = 0; i < num_eq; i++) { 537382527734SSukumar Swaminathan buf_info = &hba->sli.sli4.eq[i].addr; 537482527734SSukumar Swaminathan if (buf_info->virt == NULL) { 537582527734SSukumar Swaminathan bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 5376b3660a96SSukumar Swaminathan buf_info->size = size; 537782527734SSukumar Swaminathan buf_info->flags = 537882527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 537982527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5380b3660a96SSukumar Swaminathan buf_info->phys = phys; 5381*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5382b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5383b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 538482527734SSukumar Swaminathan 5385b3660a96SSukumar Swaminathan phys += size; 5386b3660a96SSukumar Swaminathan virt += size; 538782527734SSukumar Swaminathan 538882527734SSukumar Swaminathan hba->sli.sli4.eq[i].max_index = EQ_DEPTH; 538982527734SSukumar Swaminathan } 539082527734SSukumar Swaminathan 539182527734SSukumar Swaminathan (void) sprintf(buf, "%s_eq%d_lastwq_lock mutex", 539282527734SSukumar Swaminathan DRIVER_NAME, i); 539382527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.eq[i].lastwq_lock, buf, 539482527734SSukumar Swaminathan MUTEX_DRIVER, NULL); 539582527734SSukumar Swaminathan } 5396b3660a96SSukumar Swaminathan 5397b3660a96SSukumar Swaminathan size = 4096; 539882527734SSukumar Swaminathan for (i = 0; i < (num_wq + EMLXS_CQ_OFFSET_WQ); i++) { 539982527734SSukumar Swaminathan buf_info = &hba->sli.sli4.cq[i].addr; 540082527734SSukumar Swaminathan if (buf_info->virt == NULL) { 540182527734SSukumar Swaminathan bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 5402b3660a96SSukumar Swaminathan buf_info->size = size; 540382527734SSukumar Swaminathan buf_info->flags = 540482527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 540582527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5406b3660a96SSukumar Swaminathan buf_info->phys = phys; 5407*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5408b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5409b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 541082527734SSukumar Swaminathan 5411b3660a96SSukumar Swaminathan phys += size; 5412b3660a96SSukumar Swaminathan virt += size; 541382527734SSukumar Swaminathan 541482527734SSukumar Swaminathan hba->sli.sli4.cq[i].max_index = CQ_DEPTH; 541582527734SSukumar Swaminathan } 541682527734SSukumar Swaminathan } 5417b3660a96SSukumar Swaminathan 541882527734SSukumar Swaminathan /* WQs - NUM_WQ config parameter * number of EQs */ 5419b3660a96SSukumar Swaminathan size = 4096 * EMLXS_NUM_WQ_PAGES; 542082527734SSukumar Swaminathan for (i = 0; i < num_wq; i++) { 542182527734SSukumar Swaminathan buf_info = &hba->sli.sli4.wq[i].addr; 542282527734SSukumar Swaminathan if (buf_info->virt == NULL) { 542382527734SSukumar Swaminathan bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 5424b3660a96SSukumar Swaminathan buf_info->size = size; 542582527734SSukumar Swaminathan buf_info->flags = 542682527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 542782527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5428b3660a96SSukumar Swaminathan buf_info->phys = phys; 5429*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5430b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5431b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 543282527734SSukumar Swaminathan 5433b3660a96SSukumar Swaminathan phys += size; 5434b3660a96SSukumar Swaminathan virt += size; 543582527734SSukumar Swaminathan 543682527734SSukumar Swaminathan hba->sli.sli4.wq[i].max_index = WQ_DEPTH; 543782527734SSukumar Swaminathan hba->sli.sli4.wq[i].release_depth = WQE_RELEASE_DEPTH; 543882527734SSukumar Swaminathan } 543982527734SSukumar Swaminathan } 544082527734SSukumar Swaminathan 5441b3660a96SSukumar Swaminathan /* MQ */ 5442b3660a96SSukumar Swaminathan size = 4096; 5443b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.mq.addr; 5444b3660a96SSukumar Swaminathan if (!buf_info->virt) { 5445b3660a96SSukumar Swaminathan bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 5446b3660a96SSukumar Swaminathan buf_info->size = size; 5447b3660a96SSukumar Swaminathan buf_info->flags = 5448b3660a96SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5449b3660a96SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5450b3660a96SSukumar Swaminathan buf_info->phys = phys; 5451*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5452b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5453b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 5454b3660a96SSukumar Swaminathan 5455b3660a96SSukumar Swaminathan phys += size; 5456b3660a96SSukumar Swaminathan virt += size; 5457b3660a96SSukumar Swaminathan 5458b3660a96SSukumar Swaminathan hba->sli.sli4.mq.max_index = MQ_DEPTH; 5459b3660a96SSukumar Swaminathan } 5460b3660a96SSukumar Swaminathan 546182527734SSukumar Swaminathan /* RXQs */ 546282527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RXQS; i++) { 546382527734SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 546482527734SSukumar Swaminathan 546582527734SSukumar Swaminathan (void) sprintf(buf, "%s_rxq%d_lock mutex", DRIVER_NAME, i); 546682527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.rxq[i].lock, buf, MUTEX_DRIVER, NULL); 546782527734SSukumar Swaminathan } 546882527734SSukumar Swaminathan 546982527734SSukumar Swaminathan /* RQs */ 5470b3660a96SSukumar Swaminathan size = 4096; 547182527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 547282527734SSukumar Swaminathan buf_info = &hba->sli.sli4.rq[i].addr; 547382527734SSukumar Swaminathan if (buf_info->virt) { 547482527734SSukumar Swaminathan continue; 547582527734SSukumar Swaminathan } 547682527734SSukumar Swaminathan 547782527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 5478b3660a96SSukumar Swaminathan buf_info->size = size; 547982527734SSukumar Swaminathan buf_info->flags = 548082527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 548182527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5482b3660a96SSukumar Swaminathan buf_info->phys = phys; 5483*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5484b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5485b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 548682527734SSukumar Swaminathan 5487b3660a96SSukumar Swaminathan phys += size; 5488b3660a96SSukumar Swaminathan virt += size; 548982527734SSukumar Swaminathan 549082527734SSukumar Swaminathan hba->sli.sli4.rq[i].max_index = RQ_DEPTH; 549182527734SSukumar Swaminathan 5492b3660a96SSukumar Swaminathan (void) sprintf(buf, "%s_rq%d_lock mutex", DRIVER_NAME, i); 5493b3660a96SSukumar Swaminathan mutex_init(&hba->sli.sli4.rq[i].lock, buf, MUTEX_DRIVER, NULL); 5494b3660a96SSukumar Swaminathan } 549582527734SSukumar Swaminathan 5496b3660a96SSukumar Swaminathan /* Setup RQE */ 5497b3660a96SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 5498b3660a96SSukumar Swaminathan size = (i & 0x1) ? RQB_DATA_SIZE : RQB_HEADER_SIZE; 5499b3660a96SSukumar Swaminathan tmp_phys = phys; 5500b3660a96SSukumar Swaminathan tmp_virt = virt; 550182527734SSukumar Swaminathan 550282527734SSukumar Swaminathan /* Initialize the RQEs */ 550382527734SSukumar Swaminathan rqe = (RQE_t *)hba->sli.sli4.rq[i].addr.virt; 550482527734SSukumar Swaminathan for (j = 0; j < (RQ_DEPTH/RQB_COUNT); j++) { 5505b3660a96SSukumar Swaminathan phys = tmp_phys; 5506b3660a96SSukumar Swaminathan virt = tmp_virt; 550782527734SSukumar Swaminathan for (k = 0; k < RQB_COUNT; k++) { 5508b3660a96SSukumar Swaminathan word = PADDR_HI(phys); 550982527734SSukumar Swaminathan rqe->AddrHi = BE_SWAP32(word); 551082527734SSukumar Swaminathan 5511b3660a96SSukumar Swaminathan word = PADDR_LO(phys); 551282527734SSukumar Swaminathan rqe->AddrLo = BE_SWAP32(word); 551382527734SSukumar Swaminathan 5514b3660a96SSukumar Swaminathan rqb = &hba->sli.sli4.rq[i]. 5515b3660a96SSukumar Swaminathan rqb[k + (j * RQB_COUNT)]; 5516b3660a96SSukumar Swaminathan rqb->size = size; 5517b3660a96SSukumar Swaminathan rqb->flags = FC_MBUF_DMA | 5518b3660a96SSukumar Swaminathan FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5519b3660a96SSukumar Swaminathan rqb->align = ddi_ptob(hba->dip, 1L); 5520b3660a96SSukumar Swaminathan rqb->phys = phys; 5521*a9800bebSGarrett D'Amore rqb->virt = (void *)virt; 5522b3660a96SSukumar Swaminathan rqb->data_handle = data_handle; 5523b3660a96SSukumar Swaminathan rqb->dma_handle = dma_handle; 5524b3660a96SSukumar Swaminathan 5525b3660a96SSukumar Swaminathan phys += size; 5526b3660a96SSukumar Swaminathan virt += size; 552782527734SSukumar Swaminathan #ifdef RQ_DEBUG 552882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 552982527734SSukumar Swaminathan "RQ_ALLOC: rq[%d] rqb[%d,%d]=%p tag=%08x", 553082527734SSukumar Swaminathan i, j, k, mp, mp->tag); 553182527734SSukumar Swaminathan #endif 553282527734SSukumar Swaminathan 553382527734SSukumar Swaminathan rqe++; 553482527734SSukumar Swaminathan } 553582527734SSukumar Swaminathan } 553682527734SSukumar Swaminathan 5537b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 5538b3660a96SSukumar Swaminathan hba->sli.sli4.rq[i].addr.virt) - 5539b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 5540b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 5541b3660a96SSukumar Swaminathan 554282527734SSukumar Swaminathan /* Sync the RQ buffer list */ 5543b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, offset, 554482527734SSukumar Swaminathan hba->sli.sli4.rq[i].addr.size, DDI_DMA_SYNC_FORDEV); 5545b3660a96SSukumar Swaminathan } 554682527734SSukumar Swaminathan 5547b3660a96SSukumar Swaminathan if ((!hba->sli.sli4.XRIp) && (hba->sli.sli4.XRICount)) { 5548b3660a96SSukumar Swaminathan /* Initialize double linked lists */ 5549b3660a96SSukumar Swaminathan hba->sli.sli4.XRIinuse_f = 5550b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5551b3660a96SSukumar Swaminathan hba->sli.sli4.XRIinuse_b = 5552b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5553b3660a96SSukumar Swaminathan hba->sli.sli4.xria_count = 0; 5554b3660a96SSukumar Swaminathan 5555b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_f = 5556b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5557b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_b = 5558b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5559b3660a96SSukumar Swaminathan hba->sli.sli4.xria_count = 0; 5560b3660a96SSukumar Swaminathan 5561b3660a96SSukumar Swaminathan hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc( 5562b3660a96SSukumar Swaminathan (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP); 5563b3660a96SSukumar Swaminathan 5564*a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIp; 5565b3660a96SSukumar Swaminathan index = hba->sli.sli4.XRIBase; 5566b3660a96SSukumar Swaminathan size = hba->sli.sli4.mem_sgl_size; 5567b3660a96SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.XRICount; i++) { 5568*a9800bebSGarrett D'Amore xrip->sge_count = 5569b3660a96SSukumar Swaminathan (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64)); 5570*a9800bebSGarrett D'Amore xrip->XRI = index; 5571*a9800bebSGarrett D'Amore xrip->iotag = i; 5572*a9800bebSGarrett D'Amore if ((xrip->XRI == 0) || (xrip->iotag == 0)) { 5573b3660a96SSukumar Swaminathan index++; /* Skip XRI 0 or IOTag 0 */ 5574*a9800bebSGarrett D'Amore xrip++; 5575b3660a96SSukumar Swaminathan continue; 5576b3660a96SSukumar Swaminathan } 5577*a9800bebSGarrett D'Amore /* Add xrip to end of free list */ 5578*a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIfree_b; 5579*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b->_f = xrip; 5580*a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5581*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b = xrip; 5582b3660a96SSukumar Swaminathan hba->sli.sli4.xrif_count++; 5583b3660a96SSukumar Swaminathan 5584*a9800bebSGarrett D'Amore /* Allocate SGL for this xrip */ 5585*a9800bebSGarrett D'Amore buf_info = &xrip->SGList; 5586b3660a96SSukumar Swaminathan buf_info->size = size; 5587b3660a96SSukumar Swaminathan buf_info->flags = 5588b3660a96SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5589b3660a96SSukumar Swaminathan buf_info->align = size; 5590b3660a96SSukumar Swaminathan buf_info->phys = phys; 5591*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5592b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5593b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 5594b3660a96SSukumar Swaminathan 5595b3660a96SSukumar Swaminathan phys += size; 5596b3660a96SSukumar Swaminathan virt += size; 5597b3660a96SSukumar Swaminathan 5598*a9800bebSGarrett D'Amore xrip++; 5599b3660a96SSukumar Swaminathan index++; 5600b3660a96SSukumar Swaminathan } 560182527734SSukumar Swaminathan } 560282527734SSukumar Swaminathan 5603b3660a96SSukumar Swaminathan size = sizeof (RPIHdrTmplate_t) * hba->sli.sli4.RPICount; 5604b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.HeaderTmplate; 5605b3660a96SSukumar Swaminathan if ((buf_info->virt == NULL) && (hba->sli.sli4.RPICount)) { 5606b3660a96SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 5607b3660a96SSukumar Swaminathan buf_info->size = size; 5608b3660a96SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_DMA32; 560982527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5610b3660a96SSukumar Swaminathan buf_info->phys = phys; 5611*a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 5612b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 5613b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 5614b3660a96SSukumar Swaminathan } 561582527734SSukumar Swaminathan 5616b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 5617b3660a96SSukumar Swaminathan if (hba->sli.sli4.slim2.dma_handle) { 5618b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 5619b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle) 5620b3660a96SSukumar Swaminathan != DDI_FM_OK) { 5621b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5622b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 5623b3660a96SSukumar Swaminathan "emlxs_sli4_resource_alloc: hdl=%p", 5624b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle); 562582527734SSukumar Swaminathan goto failed; 562682527734SSukumar Swaminathan } 562782527734SSukumar Swaminathan } 5628b3660a96SSukumar Swaminathan #endif 562982527734SSukumar Swaminathan 563082527734SSukumar Swaminathan return (0); 563182527734SSukumar Swaminathan 563282527734SSukumar Swaminathan failed: 563382527734SSukumar Swaminathan 563482527734SSukumar Swaminathan (void) emlxs_sli4_resource_free(hba); 563582527734SSukumar Swaminathan return (ENOMEM); 563682527734SSukumar Swaminathan 563782527734SSukumar Swaminathan } /* emlxs_sli4_resource_alloc */ 563882527734SSukumar Swaminathan 563982527734SSukumar Swaminathan 5640*a9800bebSGarrett D'Amore static XRIobj_t * 5641*a9800bebSGarrett D'Amore emlxs_sli4_reserve_xri(emlxs_hba_t *hba, RPIobj_t *rpip) 564282527734SSukumar Swaminathan { 5643*a9800bebSGarrett D'Amore emlxs_port_t *port = &PPORT; 5644*a9800bebSGarrett D'Amore XRIobj_t *xrip; 5645*a9800bebSGarrett D'Amore uint16_t iotag; 564682527734SSukumar Swaminathan 5647*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 564882527734SSukumar Swaminathan 5649*a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIfree_f; 565082527734SSukumar Swaminathan 5651*a9800bebSGarrett D'Amore if (xrip == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) { 5652*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 565382527734SSukumar Swaminathan 5654*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5655*a9800bebSGarrett D'Amore "Unable to reserve XRI"); 565682527734SSukumar Swaminathan 5657*a9800bebSGarrett D'Amore return (NULL); 5658*a9800bebSGarrett D'Amore } 565982527734SSukumar Swaminathan 5660*a9800bebSGarrett D'Amore iotag = xrip->iotag; 566182527734SSukumar Swaminathan 5662*a9800bebSGarrett D'Amore if ((!iotag) || 5663*a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 5664*a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 5665*a9800bebSGarrett D'Amore /* 5666*a9800bebSGarrett D'Amore * No more command slots available, retry later 5667*a9800bebSGarrett D'Amore */ 5668*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5669*a9800bebSGarrett D'Amore "Adapter Busy. Unable to reserve iotag"); 567082527734SSukumar Swaminathan 5671*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5672*a9800bebSGarrett D'Amore return (NULL); 567382527734SSukumar Swaminathan } 567482527734SSukumar Swaminathan 5675*a9800bebSGarrett D'Amore xrip->state = XRI_STATE_ALLOCATED; 5676*a9800bebSGarrett D'Amore xrip->flag = EMLXS_XRI_RESERVED; 5677*a9800bebSGarrett D'Amore xrip->rpip = rpip; 5678*a9800bebSGarrett D'Amore xrip->sbp = NULL; 567982527734SSukumar Swaminathan 5680*a9800bebSGarrett D'Amore if (rpip) { 5681*a9800bebSGarrett D'Amore rpip->xri_count++; 5682*a9800bebSGarrett D'Amore } 568382527734SSukumar Swaminathan 5684*a9800bebSGarrett D'Amore /* Take it off free list */ 5685*a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 5686*a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 5687*a9800bebSGarrett D'Amore xrip->_f = NULL; 5688*a9800bebSGarrett D'Amore xrip->_b = NULL; 5689*a9800bebSGarrett D'Amore hba->sli.sli4.xrif_count--; 569082527734SSukumar Swaminathan 569182527734SSukumar Swaminathan /* Add it to end of inuse list */ 5692*a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIinuse_b; 5693*a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b->_f = xrip; 5694*a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5695*a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b = xrip; 569682527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 569782527734SSukumar Swaminathan 569882527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5699*a9800bebSGarrett D'Amore return (xrip); 570082527734SSukumar Swaminathan 570182527734SSukumar Swaminathan } /* emlxs_sli4_reserve_xri() */ 570282527734SSukumar Swaminathan 570382527734SSukumar Swaminathan 570482527734SSukumar Swaminathan extern uint32_t 5705*a9800bebSGarrett D'Amore emlxs_sli4_unreserve_xri(emlxs_hba_t *hba, uint16_t xri, uint32_t lock) 570682527734SSukumar Swaminathan { 570782527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5708*a9800bebSGarrett D'Amore XRIobj_t *xrip; 570982527734SSukumar Swaminathan 5710*a9800bebSGarrett D'Amore if (lock) { 5711*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 5712*a9800bebSGarrett D'Amore } 571382527734SSukumar Swaminathan 5714*a9800bebSGarrett D'Amore xrip = emlxs_sli4_find_xri(hba, xri); 5715*a9800bebSGarrett D'Amore 5716*a9800bebSGarrett D'Amore if (!xrip || xrip->state == XRI_STATE_FREE) { 5717*a9800bebSGarrett D'Amore if (lock) { 5718*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5719*a9800bebSGarrett D'Amore } 572082527734SSukumar Swaminathan 572182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5722*a9800bebSGarrett D'Amore "emlxs_sli4_unreserve_xri: xri=%x already freed.", 5723*a9800bebSGarrett D'Amore xrip->XRI); 572482527734SSukumar Swaminathan return (0); 572582527734SSukumar Swaminathan } 572682527734SSukumar Swaminathan 5727*a9800bebSGarrett D'Amore if (!(xrip->flag & EMLXS_XRI_RESERVED)) { 5728*a9800bebSGarrett D'Amore if (lock) { 5729*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5730*a9800bebSGarrett D'Amore } 5731*a9800bebSGarrett D'Amore 573282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5733*a9800bebSGarrett D'Amore "emlxs_sli4_unreserve_xri: xri=%x in use.", xrip->XRI); 573482527734SSukumar Swaminathan return (1); 573582527734SSukumar Swaminathan } 573682527734SSukumar Swaminathan 5737*a9800bebSGarrett D'Amore if (xrip->iotag && 5738*a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != NULL) && 5739*a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != STALE_PACKET)) { 5740*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5741*a9800bebSGarrett D'Amore "emlxs_sli4_unreserve_xri:%x sbp dropped:%p", 5742*a9800bebSGarrett D'Amore xrip->XRI, hba->fc_table[xrip->iotag]); 5743*a9800bebSGarrett D'Amore 5744*a9800bebSGarrett D'Amore hba->fc_table[xrip->iotag] = NULL; 574582527734SSukumar Swaminathan hba->io_count--; 574682527734SSukumar Swaminathan } 574782527734SSukumar Swaminathan 5748*a9800bebSGarrett D'Amore xrip->state = XRI_STATE_FREE; 574982527734SSukumar Swaminathan 5750*a9800bebSGarrett D'Amore if (xrip->rpip) { 5751*a9800bebSGarrett D'Amore xrip->rpip->xri_count--; 5752*a9800bebSGarrett D'Amore xrip->rpip = NULL; 575382527734SSukumar Swaminathan } 575482527734SSukumar Swaminathan 575582527734SSukumar Swaminathan /* Take it off inuse list */ 5756*a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 5757*a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 5758*a9800bebSGarrett D'Amore xrip->_f = NULL; 5759*a9800bebSGarrett D'Amore xrip->_b = NULL; 576082527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 576182527734SSukumar Swaminathan 576282527734SSukumar Swaminathan /* Add it to end of free list */ 5763*a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIfree_b; 5764*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b->_f = xrip; 5765*a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5766*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b = xrip; 576782527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 576882527734SSukumar Swaminathan 576982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5770*a9800bebSGarrett D'Amore "emlxs_sli4_unreserve_xri: xri=%x unreserved.", xrip->XRI); 577182527734SSukumar Swaminathan 5772*a9800bebSGarrett D'Amore if (lock) { 5773*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5774*a9800bebSGarrett D'Amore } 577582527734SSukumar Swaminathan 577682527734SSukumar Swaminathan return (0); 577782527734SSukumar Swaminathan 577882527734SSukumar Swaminathan } /* emlxs_sli4_unreserve_xri() */ 577982527734SSukumar Swaminathan 578082527734SSukumar Swaminathan 578182527734SSukumar Swaminathan static XRIobj_t * 578282527734SSukumar Swaminathan emlxs_sli4_register_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, uint16_t xri) 578382527734SSukumar Swaminathan { 578482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 578582527734SSukumar Swaminathan uint16_t iotag; 5786*a9800bebSGarrett D'Amore XRIobj_t *xrip; 578782527734SSukumar Swaminathan 578882527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 578982527734SSukumar Swaminathan 5790*a9800bebSGarrett D'Amore xrip = emlxs_sli4_find_xri(hba, xri); 5791*a9800bebSGarrett D'Amore 5792*a9800bebSGarrett D'Amore if (!xrip) { 579382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 579482527734SSukumar Swaminathan "emlxs_sli4_register_xri: XRI not found."); 579582527734SSukumar Swaminathan 579682527734SSukumar Swaminathan 579782527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 579882527734SSukumar Swaminathan return (NULL); 579982527734SSukumar Swaminathan } 580082527734SSukumar Swaminathan 5801*a9800bebSGarrett D'Amore if ((xrip->state == XRI_STATE_FREE) || 5802*a9800bebSGarrett D'Amore !(xrip->flag & EMLXS_XRI_RESERVED)) { 580382527734SSukumar Swaminathan 580482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5805*a9800bebSGarrett D'Amore "emlxs_sli4_register_xri: Invalid XRI. xrip=%p " 5806*a9800bebSGarrett D'Amore "state=%x flag=%x", 5807*a9800bebSGarrett D'Amore xrip, xrip->state, xrip->flag); 580882527734SSukumar Swaminathan 580982527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 581082527734SSukumar Swaminathan return (NULL); 581182527734SSukumar Swaminathan } 581282527734SSukumar Swaminathan 5813*a9800bebSGarrett D'Amore iotag = xrip->iotag; 581482527734SSukumar Swaminathan 581582527734SSukumar Swaminathan if ((!iotag) || 5816*a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 5817*a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 581882527734SSukumar Swaminathan 581982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5820*a9800bebSGarrett D'Amore "emlxs_sli4_register_xri: Invalid fc_table entry. " 582182527734SSukumar Swaminathan "iotag=%x entry=%p", 582282527734SSukumar Swaminathan iotag, hba->fc_table[iotag]); 582382527734SSukumar Swaminathan 582482527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 582582527734SSukumar Swaminathan return (NULL); 582682527734SSukumar Swaminathan } 582782527734SSukumar Swaminathan 582882527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 582982527734SSukumar Swaminathan hba->io_count++; 583082527734SSukumar Swaminathan 583182527734SSukumar Swaminathan sbp->iotag = iotag; 5832*a9800bebSGarrett D'Amore sbp->xrip = xrip; 583382527734SSukumar Swaminathan 5834*a9800bebSGarrett D'Amore xrip->flag &= ~EMLXS_XRI_RESERVED; 5835*a9800bebSGarrett D'Amore xrip->sbp = sbp; 583682527734SSukumar Swaminathan 583782527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 583882527734SSukumar Swaminathan 5839*a9800bebSGarrett D'Amore return (xrip); 584082527734SSukumar Swaminathan 584182527734SSukumar Swaminathan } /* emlxs_sli4_register_xri() */ 584282527734SSukumar Swaminathan 584382527734SSukumar Swaminathan 584482527734SSukumar Swaminathan /* Performs both reserve and register functions for XRI */ 584582527734SSukumar Swaminathan static XRIobj_t * 5846*a9800bebSGarrett D'Amore emlxs_sli4_alloc_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, RPIobj_t *rpip) 584782527734SSukumar Swaminathan { 584882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5849*a9800bebSGarrett D'Amore XRIobj_t *xrip; 585082527734SSukumar Swaminathan uint16_t iotag; 585182527734SSukumar Swaminathan 585282527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 585382527734SSukumar Swaminathan 5854*a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIfree_f; 585582527734SSukumar Swaminathan 5856*a9800bebSGarrett D'Amore if (xrip == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) { 585782527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 585882527734SSukumar Swaminathan 585982527734SSukumar Swaminathan return (NULL); 586082527734SSukumar Swaminathan } 586182527734SSukumar Swaminathan 586282527734SSukumar Swaminathan /* Get the iotag by registering the packet */ 5863*a9800bebSGarrett D'Amore iotag = xrip->iotag; 586482527734SSukumar Swaminathan 586582527734SSukumar Swaminathan if ((!iotag) || 5866*a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 5867*a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 586882527734SSukumar Swaminathan /* 586982527734SSukumar Swaminathan * No more command slots available, retry later 587082527734SSukumar Swaminathan */ 587182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5872*a9800bebSGarrett D'Amore "Adapter Busy. Unable to alloc iotag:(0x%x)(%p)", 5873*a9800bebSGarrett D'Amore iotag, hba->fc_table[iotag]); 587482527734SSukumar Swaminathan 587582527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 587682527734SSukumar Swaminathan return (NULL); 587782527734SSukumar Swaminathan } 587882527734SSukumar Swaminathan 587982527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 588082527734SSukumar Swaminathan hba->io_count++; 588182527734SSukumar Swaminathan 588282527734SSukumar Swaminathan sbp->iotag = iotag; 5883*a9800bebSGarrett D'Amore sbp->xrip = xrip; 588482527734SSukumar Swaminathan 5885*a9800bebSGarrett D'Amore xrip->state = XRI_STATE_ALLOCATED; 5886*a9800bebSGarrett D'Amore xrip->flag = 0; 5887*a9800bebSGarrett D'Amore xrip->rpip = rpip; 5888*a9800bebSGarrett D'Amore xrip->sbp = sbp; 588982527734SSukumar Swaminathan 5890*a9800bebSGarrett D'Amore if (rpip) { 5891*a9800bebSGarrett D'Amore rpip->xri_count++; 589282527734SSukumar Swaminathan } 589382527734SSukumar Swaminathan 589482527734SSukumar Swaminathan /* Take it off free list */ 5895*a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 5896*a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 5897*a9800bebSGarrett D'Amore xrip->_f = NULL; 5898*a9800bebSGarrett D'Amore xrip->_b = NULL; 589982527734SSukumar Swaminathan hba->sli.sli4.xrif_count--; 590082527734SSukumar Swaminathan 590182527734SSukumar Swaminathan /* Add it to end of inuse list */ 5902*a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIinuse_b; 5903*a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b->_f = xrip; 5904*a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5905*a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b = xrip; 590682527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 590782527734SSukumar Swaminathan 590882527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 590982527734SSukumar Swaminathan 5910*a9800bebSGarrett D'Amore return (xrip); 591182527734SSukumar Swaminathan 591282527734SSukumar Swaminathan } /* emlxs_sli4_alloc_xri() */ 591382527734SSukumar Swaminathan 591482527734SSukumar Swaminathan 5915*a9800bebSGarrett D'Amore /* EMLXS_FCTAB_LOCK must be held to enter */ 591682527734SSukumar Swaminathan extern XRIobj_t * 591782527734SSukumar Swaminathan emlxs_sli4_find_xri(emlxs_hba_t *hba, uint16_t xri) 591882527734SSukumar Swaminathan { 591982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5920*a9800bebSGarrett D'Amore XRIobj_t *xrip; 592182527734SSukumar Swaminathan 5922*a9800bebSGarrett D'Amore xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 5923*a9800bebSGarrett D'Amore while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 5924*a9800bebSGarrett D'Amore if ((xrip->state >= XRI_STATE_ALLOCATED) && 5925*a9800bebSGarrett D'Amore (xrip->XRI == xri)) { 5926*a9800bebSGarrett D'Amore return (xrip); 592782527734SSukumar Swaminathan } 5928*a9800bebSGarrett D'Amore xrip = xrip->_f; 592982527734SSukumar Swaminathan } 593082527734SSukumar Swaminathan 5931*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5932*a9800bebSGarrett D'Amore "Unable to find XRI x%x", xri); 593382527734SSukumar Swaminathan 5934*a9800bebSGarrett D'Amore return (NULL); 593582527734SSukumar Swaminathan 5936*a9800bebSGarrett D'Amore } /* emlxs_sli4_find_xri() */ 593782527734SSukumar Swaminathan 593882527734SSukumar Swaminathan 593982527734SSukumar Swaminathan 594082527734SSukumar Swaminathan 594182527734SSukumar Swaminathan extern void 5942*a9800bebSGarrett D'Amore emlxs_sli4_free_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, XRIobj_t *xrip, 5943*a9800bebSGarrett D'Amore uint8_t lock) 594482527734SSukumar Swaminathan { 594582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 594682527734SSukumar Swaminathan 5947*a9800bebSGarrett D'Amore if (lock) { 5948*a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 594982527734SSukumar Swaminathan } 595082527734SSukumar Swaminathan 5951*a9800bebSGarrett D'Amore if (xrip) { 5952*a9800bebSGarrett D'Amore if (xrip->state == XRI_STATE_FREE) { 5953*a9800bebSGarrett D'Amore if (lock) { 5954*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5955*a9800bebSGarrett D'Amore } 595682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5957*a9800bebSGarrett D'Amore "Free XRI:%x, Already freed", xrip->XRI); 595882527734SSukumar Swaminathan return; 595982527734SSukumar Swaminathan } 596082527734SSukumar Swaminathan 5961*a9800bebSGarrett D'Amore if (xrip->iotag && 5962*a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != NULL) && 5963*a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != STALE_PACKET)) { 5964*a9800bebSGarrett D'Amore hba->fc_table[xrip->iotag] = NULL; 596582527734SSukumar Swaminathan hba->io_count--; 596682527734SSukumar Swaminathan } 596782527734SSukumar Swaminathan 5968*a9800bebSGarrett D'Amore xrip->state = XRI_STATE_FREE; 5969*a9800bebSGarrett D'Amore xrip->flag = 0; 597082527734SSukumar Swaminathan 5971*a9800bebSGarrett D'Amore if (xrip->rpip) { 5972*a9800bebSGarrett D'Amore xrip->rpip->xri_count--; 5973*a9800bebSGarrett D'Amore xrip->rpip = NULL; 597482527734SSukumar Swaminathan } 597582527734SSukumar Swaminathan 597682527734SSukumar Swaminathan /* Take it off inuse list */ 5977*a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 5978*a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 5979*a9800bebSGarrett D'Amore xrip->_f = NULL; 5980*a9800bebSGarrett D'Amore xrip->_b = NULL; 598182527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 598282527734SSukumar Swaminathan 598382527734SSukumar Swaminathan /* Add it to end of free list */ 5984*a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIfree_b; 5985*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b->_f = xrip; 5986*a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 5987*a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b = xrip; 598882527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 598982527734SSukumar Swaminathan } 599082527734SSukumar Swaminathan 599182527734SSukumar Swaminathan if (sbp) { 5992*a9800bebSGarrett D'Amore if (!(sbp->pkt_flags & PACKET_VALID) || 5993*a9800bebSGarrett D'Amore (sbp->pkt_flags & 5994*a9800bebSGarrett D'Amore (PACKET_ULP_OWNED|PACKET_COMPLETED|PACKET_IN_COMPLETION))) { 5995*a9800bebSGarrett D'Amore if (lock) { 5996*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5997*a9800bebSGarrett D'Amore } 5998*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5999*a9800bebSGarrett D'Amore "Free XRI: sbp invalid. sbp=%p flags=%x xri=%x", 6000*a9800bebSGarrett D'Amore sbp, sbp->pkt_flags, ((xrip)? xrip->XRI:0)); 6001*a9800bebSGarrett D'Amore return; 6002*a9800bebSGarrett D'Amore } 600382527734SSukumar Swaminathan 6004*a9800bebSGarrett D'Amore sbp->xrip = 0; 6005*a9800bebSGarrett D'Amore 6006*a9800bebSGarrett D'Amore if (xrip && (xrip->iotag != sbp->iotag)) { 6007*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 600882527734SSukumar Swaminathan "sbp / iotag mismatch %p iotag:%d %d", sbp, 6009*a9800bebSGarrett D'Amore sbp->iotag, xrip->iotag); 601082527734SSukumar Swaminathan } 601182527734SSukumar Swaminathan 601282527734SSukumar Swaminathan if (sbp->iotag) { 6013*a9800bebSGarrett D'Amore if (sbp == hba->fc_table[sbp->iotag]) { 601482527734SSukumar Swaminathan hba->fc_table[sbp->iotag] = NULL; 601582527734SSukumar Swaminathan hba->io_count--; 601682527734SSukumar Swaminathan } 601782527734SSukumar Swaminathan sbp->iotag = 0; 601882527734SSukumar Swaminathan } 601982527734SSukumar Swaminathan 6020*a9800bebSGarrett D'Amore if (lock) { 6021*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 6022*a9800bebSGarrett D'Amore } 602382527734SSukumar Swaminathan 602482527734SSukumar Swaminathan /* Clean up the sbp */ 602582527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 602682527734SSukumar Swaminathan 602782527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_TXQ) { 602882527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_TXQ; 602982527734SSukumar Swaminathan hba->channel_tx_count--; 603082527734SSukumar Swaminathan } 603182527734SSukumar Swaminathan 603282527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 603382527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_CHIPQ; 603482527734SSukumar Swaminathan } 603582527734SSukumar Swaminathan 603682527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 603782527734SSukumar Swaminathan } else { 6038*a9800bebSGarrett D'Amore if (lock) { 6039*a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 6040*a9800bebSGarrett D'Amore } 604182527734SSukumar Swaminathan } 604282527734SSukumar Swaminathan 604382527734SSukumar Swaminathan } /* emlxs_sli4_free_xri() */ 604482527734SSukumar Swaminathan 604582527734SSukumar Swaminathan 604682527734SSukumar Swaminathan static int 604782527734SSukumar Swaminathan emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, MAILBOXQ *mbq) 604882527734SSukumar Swaminathan { 604982527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 605082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6051*a9800bebSGarrett D'Amore XRIobj_t *xrip; 605282527734SSukumar Swaminathan MATCHMAP *mp; 605382527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 605482527734SSukumar Swaminathan uint32_t i, cnt, xri_cnt; 605582527734SSukumar Swaminathan uint32_t size; 605682527734SSukumar Swaminathan IOCTL_FCOE_CFG_POST_SGL_PAGES *post_sgl; 605782527734SSukumar Swaminathan 605882527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 605982527734SSukumar Swaminathan mbq->bp = NULL; 606082527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 606182527734SSukumar Swaminathan 606282527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, EMLXS_MAX_NONEMBED_SIZE)) == 0) { 606382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 606482527734SSukumar Swaminathan "Unable to POST_SGL. Mailbox cmd=%x ", 606582527734SSukumar Swaminathan mb->mbxCommand); 606682527734SSukumar Swaminathan return (EIO); 606782527734SSukumar Swaminathan } 6068*a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 606982527734SSukumar Swaminathan 607082527734SSukumar Swaminathan /* 607182527734SSukumar Swaminathan * Signifies a non embedded command 607282527734SSukumar Swaminathan */ 607382527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 607482527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 607582527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 607682527734SSukumar Swaminathan 607782527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 607882527734SSukumar Swaminathan post_sgl = 607982527734SSukumar Swaminathan (IOCTL_FCOE_CFG_POST_SGL_PAGES *)(hdr_req + 1); 608082527734SSukumar Swaminathan 608182527734SSukumar Swaminathan 6082*a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIp; 608382527734SSukumar Swaminathan cnt = hba->sli.sli4.XRICount; 608482527734SSukumar Swaminathan while (cnt) { 608582527734SSukumar Swaminathan bzero((void *) hdr_req, mp->size); 608682527734SSukumar Swaminathan size = mp->size - IOCTL_HEADER_SZ; 608782527734SSukumar Swaminathan 608882527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length = 608982527734SSukumar Swaminathan mp->size; 609082527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 609182527734SSukumar Swaminathan IOCTL_SUBSYSTEM_FCOE; 609282527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 609382527734SSukumar Swaminathan FCOE_OPCODE_CFG_POST_SGL_PAGES; 609482527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 609582527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = size; 609682527734SSukumar Swaminathan 609782527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 609882527734SSukumar Swaminathan hdr_req->opcode = FCOE_OPCODE_CFG_POST_SGL_PAGES; 609982527734SSukumar Swaminathan hdr_req->timeout = 0; 610082527734SSukumar Swaminathan hdr_req->req_length = size; 610182527734SSukumar Swaminathan 610282527734SSukumar Swaminathan post_sgl->params.request.xri_count = 0; 6103*a9800bebSGarrett D'Amore post_sgl->params.request.xri_start = xrip->XRI; 610482527734SSukumar Swaminathan xri_cnt = (size - sizeof (IOCTL_FCOE_CFG_POST_SGL_PAGES)) / 610582527734SSukumar Swaminathan sizeof (FCOE_SGL_PAGES); 610682527734SSukumar Swaminathan for (i = 0; i < xri_cnt; i++) { 610782527734SSukumar Swaminathan 610882527734SSukumar Swaminathan post_sgl->params.request.xri_count++; 610982527734SSukumar Swaminathan post_sgl->params.request.pages[i].sgl_page0.addrLow = 6110*a9800bebSGarrett D'Amore PADDR_LO(xrip->SGList.phys); 611182527734SSukumar Swaminathan post_sgl->params.request.pages[i].sgl_page0.addrHigh = 6112*a9800bebSGarrett D'Amore PADDR_HI(xrip->SGList.phys); 611382527734SSukumar Swaminathan cnt--; 6114*a9800bebSGarrett D'Amore xrip++; 611582527734SSukumar Swaminathan if (cnt == 0) { 611682527734SSukumar Swaminathan break; 611782527734SSukumar Swaminathan } 611882527734SSukumar Swaminathan } 611982527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 612082527734SSukumar Swaminathan MBX_SUCCESS) { 612182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 612282527734SSukumar Swaminathan "Unable to POST_SGL. Mailbox cmd=%x status=%x " 612382527734SSukumar Swaminathan "XRI cnt:%d start:%d", 612482527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus, 612582527734SSukumar Swaminathan post_sgl->params.request.xri_count, 612682527734SSukumar Swaminathan post_sgl->params.request.xri_start); 6127*a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 6128*a9800bebSGarrett D'Amore mbq->nonembed = NULL; 612982527734SSukumar Swaminathan return (EIO); 613082527734SSukumar Swaminathan } 613182527734SSukumar Swaminathan } 6132*a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 6133*a9800bebSGarrett D'Amore mbq->nonembed = NULL; 613482527734SSukumar Swaminathan return (0); 613582527734SSukumar Swaminathan 613682527734SSukumar Swaminathan } /* emlxs_sli4_post_sgl_pages() */ 613782527734SSukumar Swaminathan 613882527734SSukumar Swaminathan 613982527734SSukumar Swaminathan static int 614082527734SSukumar Swaminathan emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, MAILBOXQ *mbq) 614182527734SSukumar Swaminathan { 614282527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 614382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 614482527734SSukumar Swaminathan int i, cnt; 614582527734SSukumar Swaminathan uint64_t addr; 614682527734SSukumar Swaminathan IOCTL_FCOE_POST_HDR_TEMPLATES *post_hdr; 614782527734SSukumar Swaminathan 614882527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 614982527734SSukumar Swaminathan mbq->bp = NULL; 615082527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 615182527734SSukumar Swaminathan 615282527734SSukumar Swaminathan /* 615382527734SSukumar Swaminathan * Signifies an embedded command 615482527734SSukumar Swaminathan */ 615582527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 1; 615682527734SSukumar Swaminathan 615782527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 615882527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 615982527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length = 616082527734SSukumar Swaminathan sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES) + IOCTL_HEADER_SZ; 616182527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 616282527734SSukumar Swaminathan IOCTL_SUBSYSTEM_FCOE; 616382527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 616482527734SSukumar Swaminathan FCOE_OPCODE_POST_HDR_TEMPLATES; 616582527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 616682527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 616782527734SSukumar Swaminathan sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES); 616882527734SSukumar Swaminathan post_hdr = 616982527734SSukumar Swaminathan (IOCTL_FCOE_POST_HDR_TEMPLATES *)&mb->un.varSLIConfig.payload; 617082527734SSukumar Swaminathan addr = hba->sli.sli4.HeaderTmplate.phys; 617182527734SSukumar Swaminathan post_hdr->params.request.num_pages = 0; 617282527734SSukumar Swaminathan i = 0; 617382527734SSukumar Swaminathan cnt = hba->sli.sli4.HeaderTmplate.size; 617482527734SSukumar Swaminathan while (cnt > 0) { 617582527734SSukumar Swaminathan post_hdr->params.request.num_pages++; 617682527734SSukumar Swaminathan post_hdr->params.request.pages[i].addrLow = PADDR_LO(addr); 617782527734SSukumar Swaminathan post_hdr->params.request.pages[i].addrHigh = PADDR_HI(addr); 617882527734SSukumar Swaminathan i++; 617982527734SSukumar Swaminathan addr += 4096; 618082527734SSukumar Swaminathan cnt -= 4096; 618182527734SSukumar Swaminathan } 618282527734SSukumar Swaminathan post_hdr->params.request.starting_rpi_index = hba->sli.sli4.RPIBase; 618382527734SSukumar Swaminathan 618482527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 618582527734SSukumar Swaminathan MBX_SUCCESS) { 618682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 618782527734SSukumar Swaminathan "Unable to POST_HDR_TEMPLATES. Mailbox cmd=%x status=%x ", 618882527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 618982527734SSukumar Swaminathan return (EIO); 619082527734SSukumar Swaminathan } 6191*a9800bebSGarrett D'Amore emlxs_data_dump(port, "POST_HDR", (uint32_t *)mb, 18, 0); 619282527734SSukumar Swaminathan return (0); 619382527734SSukumar Swaminathan 619482527734SSukumar Swaminathan } /* emlxs_sli4_post_hdr_tmplates() */ 619582527734SSukumar Swaminathan 619682527734SSukumar Swaminathan 619782527734SSukumar Swaminathan static int 619882527734SSukumar Swaminathan emlxs_sli4_create_queues(emlxs_hba_t *hba, MAILBOXQ *mbq) 619982527734SSukumar Swaminathan { 620082527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 620182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 620282527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 620382527734SSukumar Swaminathan IOCTL_COMMON_EQ_CREATE *eq; 620482527734SSukumar Swaminathan IOCTL_COMMON_CQ_CREATE *cq; 620582527734SSukumar Swaminathan IOCTL_FCOE_WQ_CREATE *wq; 620682527734SSukumar Swaminathan IOCTL_FCOE_RQ_CREATE *rq; 620782527734SSukumar Swaminathan IOCTL_COMMON_MQ_CREATE *mq; 6208*a9800bebSGarrett D'Amore IOCTL_COMMON_MCC_CREATE_EXT *mcc_ext; 620982527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 6210*a9800bebSGarrett D'Amore uint16_t i, j; 6211*a9800bebSGarrett D'Amore uint16_t num_cq, total_cq; 6212*a9800bebSGarrett D'Amore uint16_t num_wq, total_wq; 621382527734SSukumar Swaminathan 621482527734SSukumar Swaminathan /* 621582527734SSukumar Swaminathan * The first CQ is reserved for ASYNC events, 621682527734SSukumar Swaminathan * the second is reserved for unsol rcv, the rest 621782527734SSukumar Swaminathan * correspond to WQs. (WQ0 -> CQ2, WQ1 -> CQ3, ...) 621882527734SSukumar Swaminathan */ 621982527734SSukumar Swaminathan 622082527734SSukumar Swaminathan /* First initialize queue ordinal mapping */ 622182527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQ_IDS; i++) { 622282527734SSukumar Swaminathan hba->sli.sli4.eq_map[i] = 0xffff; 622382527734SSukumar Swaminathan } 622482527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQ_IDS; i++) { 622582527734SSukumar Swaminathan hba->sli.sli4.cq_map[i] = 0xffff; 622682527734SSukumar Swaminathan } 622782527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQ_IDS; i++) { 622882527734SSukumar Swaminathan hba->sli.sli4.wq_map[i] = 0xffff; 622982527734SSukumar Swaminathan } 623082527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQ_IDS; i++) { 623182527734SSukumar Swaminathan hba->sli.sli4.rq_map[i] = 0xffff; 623282527734SSukumar Swaminathan } 623382527734SSukumar Swaminathan 623482527734SSukumar Swaminathan total_cq = 0; 623582527734SSukumar Swaminathan total_wq = 0; 623682527734SSukumar Swaminathan 623782527734SSukumar Swaminathan /* Create EQ's */ 623882527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 623982527734SSukumar Swaminathan emlxs_mb_eq_create(hba, mbq, i); 624082527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 624182527734SSukumar Swaminathan MBX_SUCCESS) { 624282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 624382527734SSukumar Swaminathan "Unable to Create EQ %d: Mailbox cmd=%x status=%x ", 624482527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 624582527734SSukumar Swaminathan return (EIO); 624682527734SSukumar Swaminathan } 624782527734SSukumar Swaminathan eq = (IOCTL_COMMON_EQ_CREATE *)&mb->un.varSLIConfig.payload; 624882527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid = eq->params.response.EQId; 624982527734SSukumar Swaminathan hba->sli.sli4.eq_map[eq->params.response.EQId] = i; 625082527734SSukumar Swaminathan hba->sli.sli4.eq[i].lastwq = total_wq; 625182527734SSukumar Swaminathan 6252*a9800bebSGarrett D'Amore emlxs_data_dump(port, "EQ0_CREATE", (uint32_t *)mb, 18, 0); 625382527734SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current; 625482527734SSukumar Swaminathan num_cq = num_wq; 625582527734SSukumar Swaminathan if (i == 0) { 625682527734SSukumar Swaminathan /* One for RQ handling, one for mbox/event handling */ 625782527734SSukumar Swaminathan num_cq += EMLXS_CQ_OFFSET_WQ; 625882527734SSukumar Swaminathan } 625982527734SSukumar Swaminathan 626082527734SSukumar Swaminathan for (j = 0; j < num_cq; j++) { 626182527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 626282527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 626382527734SSukumar Swaminathan 626482527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].eqid = 626582527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid; 626682527734SSukumar Swaminathan 626782527734SSukumar Swaminathan emlxs_mb_cq_create(hba, mbq, total_cq); 626882527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 626982527734SSukumar Swaminathan MBX_SUCCESS) { 627082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 627182527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 627282527734SSukumar Swaminathan "CQ %d: Mailbox cmd=%x status=%x ", 627382527734SSukumar Swaminathan total_cq, mb->mbxCommand, mb->mbxStatus); 627482527734SSukumar Swaminathan return (EIO); 627582527734SSukumar Swaminathan } 627682527734SSukumar Swaminathan cq = (IOCTL_COMMON_CQ_CREATE *) 627782527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 627882527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].qid = 627982527734SSukumar Swaminathan cq->params.response.CQId; 628082527734SSukumar Swaminathan hba->sli.sli4.cq_map[cq->params.response.CQId] = 628182527734SSukumar Swaminathan total_cq; 628282527734SSukumar Swaminathan 628382527734SSukumar Swaminathan switch (total_cq) { 628482527734SSukumar Swaminathan case EMLXS_CQ_MBOX: 628582527734SSukumar Swaminathan /* First CQ is for async event handling */ 628682527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 628782527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP1; 628882527734SSukumar Swaminathan break; 628982527734SSukumar Swaminathan 629082527734SSukumar Swaminathan case EMLXS_CQ_RCV: 629182527734SSukumar Swaminathan /* Second CQ is for unsol receive handling */ 629282527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 629382527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 629482527734SSukumar Swaminathan break; 629582527734SSukumar Swaminathan 629682527734SSukumar Swaminathan default: 629782527734SSukumar Swaminathan /* Setup CQ to channel mapping */ 629882527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 629982527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 630082527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].channelp = 630182527734SSukumar Swaminathan &hba->chan[total_cq - EMLXS_CQ_OFFSET_WQ]; 630282527734SSukumar Swaminathan break; 630382527734SSukumar Swaminathan } 6304*a9800bebSGarrett D'Amore emlxs_data_dump(port, "CQX_CREATE", (uint32_t *)mb, 18, 0); 630582527734SSukumar Swaminathan total_cq++; 630682527734SSukumar Swaminathan } 630782527734SSukumar Swaminathan 630882527734SSukumar Swaminathan for (j = 0; j < num_wq; j++) { 630982527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 631082527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 631182527734SSukumar Swaminathan 631282527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 631382527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq + EMLXS_CQ_OFFSET_WQ].qid; 631482527734SSukumar Swaminathan 631582527734SSukumar Swaminathan emlxs_mb_wq_create(hba, mbq, total_wq); 631682527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 631782527734SSukumar Swaminathan MBX_SUCCESS) { 631882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 631982527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 632082527734SSukumar Swaminathan "WQ %d: Mailbox cmd=%x status=%x ", 632182527734SSukumar Swaminathan total_wq, mb->mbxCommand, mb->mbxStatus); 632282527734SSukumar Swaminathan return (EIO); 632382527734SSukumar Swaminathan } 632482527734SSukumar Swaminathan wq = (IOCTL_FCOE_WQ_CREATE *) 632582527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 632682527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].qid = 632782527734SSukumar Swaminathan wq->params.response.WQId; 632882527734SSukumar Swaminathan hba->sli.sli4.wq_map[wq->params.response.WQId] = 632982527734SSukumar Swaminathan total_wq; 633082527734SSukumar Swaminathan 633182527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 633282527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq+EMLXS_CQ_OFFSET_WQ].qid; 6333*a9800bebSGarrett D'Amore emlxs_data_dump(port, "WQ_CREATE", (uint32_t *)mb, 18, 0); 633482527734SSukumar Swaminathan total_wq++; 633582527734SSukumar Swaminathan } 6336*a9800bebSGarrett D'Amore hba->last_msiid = i; 633782527734SSukumar Swaminathan } 633882527734SSukumar Swaminathan 633982527734SSukumar Swaminathan /* We assume 1 RQ pair will handle ALL incoming data */ 634082527734SSukumar Swaminathan /* Create RQs */ 634182527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 634282527734SSukumar Swaminathan /* Personalize the RQ */ 634382527734SSukumar Swaminathan switch (i) { 634482527734SSukumar Swaminathan case 0: 634582527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 634682527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 634782527734SSukumar Swaminathan break; 634882527734SSukumar Swaminathan case 1: 634982527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 635082527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 635182527734SSukumar Swaminathan break; 635282527734SSukumar Swaminathan default: 635382527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 0xffff; 635482527734SSukumar Swaminathan } 635582527734SSukumar Swaminathan 635682527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 635782527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 635882527734SSukumar Swaminathan 635982527734SSukumar Swaminathan emlxs_mb_rq_create(hba, mbq, i); 636082527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 636182527734SSukumar Swaminathan MBX_SUCCESS) { 636282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 636382527734SSukumar Swaminathan "Unable to Create RQ %d: Mailbox cmd=%x status=%x ", 636482527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 636582527734SSukumar Swaminathan return (EIO); 636682527734SSukumar Swaminathan } 636782527734SSukumar Swaminathan rq = (IOCTL_FCOE_RQ_CREATE *)&mb->un.varSLIConfig.payload; 636882527734SSukumar Swaminathan hba->sli.sli4.rq[i].qid = rq->params.response.RQId; 636982527734SSukumar Swaminathan hba->sli.sli4.rq_map[rq->params.response.RQId] = i; 6370*a9800bebSGarrett D'Amore emlxs_data_dump(port, "RQ CREATE", (uint32_t *)mb, 18, 0); 637182527734SSukumar Swaminathan 637282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 637382527734SSukumar Swaminathan "RQ CREATE: rq[%d].qid=%d cqid=%d", 637482527734SSukumar Swaminathan i, hba->sli.sli4.rq[i].qid, hba->sli.sli4.rq[i].cqid); 637582527734SSukumar Swaminathan 637682527734SSukumar Swaminathan /* Initialize the host_index */ 637782527734SSukumar Swaminathan hba->sli.sli4.rq[i].host_index = 0; 637882527734SSukumar Swaminathan 637982527734SSukumar Swaminathan /* If Data queue was just created, */ 638082527734SSukumar Swaminathan /* then post buffers using the header qid */ 638182527734SSukumar Swaminathan if ((i & 0x1)) { 638282527734SSukumar Swaminathan /* Ring the RQ doorbell to post buffers */ 638382527734SSukumar Swaminathan rqdb.word = 0; 638482527734SSukumar Swaminathan rqdb.db.Qid = hba->sli.sli4.rq[i-1].qid; 638582527734SSukumar Swaminathan rqdb.db.NumPosted = RQB_COUNT; 638682527734SSukumar Swaminathan 638782527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_RQDB_REG(hba), rqdb.word); 638882527734SSukumar Swaminathan 638982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 639082527734SSukumar Swaminathan "RQ CREATE: Doorbell rang: qid=%d count=%d", 639182527734SSukumar Swaminathan hba->sli.sli4.rq[i-1].qid, RQB_COUNT); 639282527734SSukumar Swaminathan } 639382527734SSukumar Swaminathan } 639482527734SSukumar Swaminathan 639582527734SSukumar Swaminathan /* Create MQ */ 639682527734SSukumar Swaminathan 639782527734SSukumar Swaminathan /* Personalize the MQ */ 639882527734SSukumar Swaminathan hba->sli.sli4.mq.cqid = hba->sli.sli4.cq[EMLXS_CQ_MBOX].qid; 639982527734SSukumar Swaminathan 640082527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 640182527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 640282527734SSukumar Swaminathan 6403*a9800bebSGarrett D'Amore emlxs_mb_mcc_create_ext(hba, mbq); 640482527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 640582527734SSukumar Swaminathan MBX_SUCCESS) { 640682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6407*a9800bebSGarrett D'Amore "Unable to Create MCC_EXT %d: Mailbox cmd=%x status=%x ", 640882527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 640982527734SSukumar Swaminathan 6410*a9800bebSGarrett D'Amore /* Reuse mbq from previous mbox */ 6411*a9800bebSGarrett D'Amore bzero(mbq, sizeof (MAILBOXQ)); 641282527734SSukumar Swaminathan 6413*a9800bebSGarrett D'Amore emlxs_mb_mq_create(hba, mbq); 6414*a9800bebSGarrett D'Amore if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6415*a9800bebSGarrett D'Amore MBX_SUCCESS) { 6416*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6417*a9800bebSGarrett D'Amore "Unable to Create MQ %d: Mailbox cmd=%x status=%x ", 6418*a9800bebSGarrett D'Amore i, mb->mbxCommand, mb->mbxStatus); 6419*a9800bebSGarrett D'Amore return (EIO); 6420*a9800bebSGarrett D'Amore } 642182527734SSukumar Swaminathan 6422*a9800bebSGarrett D'Amore mq = (IOCTL_COMMON_MQ_CREATE *)&mb->un.varSLIConfig.payload; 6423*a9800bebSGarrett D'Amore hba->sli.sli4.mq.qid = mq->params.response.MQId; 642482527734SSukumar Swaminathan return (0); 642582527734SSukumar Swaminathan } 642682527734SSukumar Swaminathan 6427*a9800bebSGarrett D'Amore mcc_ext = (IOCTL_COMMON_MCC_CREATE_EXT *)&mb->un.varSLIConfig.payload; 6428*a9800bebSGarrett D'Amore hba->sli.sli4.mq.qid = mcc_ext->params.response.id; 642982527734SSukumar Swaminathan return (0); 643082527734SSukumar Swaminathan 6431*a9800bebSGarrett D'Amore } /* emlxs_sli4_create_queues() */ 643282527734SSukumar Swaminathan 643382527734SSukumar Swaminathan 643482527734SSukumar Swaminathan /*ARGSUSED*/ 643582527734SSukumar Swaminathan extern int 643682527734SSukumar Swaminathan emlxs_sli4_check_fcf_config(emlxs_hba_t *hba, FCF_RECORD_t *fcfrec) 643782527734SSukumar Swaminathan { 643882527734SSukumar Swaminathan int i; 643982527734SSukumar Swaminathan 644082527734SSukumar Swaminathan if (!(hba->flag & FC_FIP_SUPPORTED)) { 644182527734SSukumar Swaminathan if (!hba->sli.sli4.cfgFCOE.length) { 644282527734SSukumar Swaminathan /* Nothing specified, so everything matches */ 644382527734SSukumar Swaminathan /* For nonFIP only use index 0 */ 644482527734SSukumar Swaminathan if (fcfrec->fcf_index == 0) { 644582527734SSukumar Swaminathan return (1); /* success */ 644682527734SSukumar Swaminathan } 644782527734SSukumar Swaminathan return (0); 644882527734SSukumar Swaminathan } 644982527734SSukumar Swaminathan 645082527734SSukumar Swaminathan /* Just check FCMap for now */ 645182527734SSukumar Swaminathan if (bcmp((char *)fcfrec->fc_map, 645282527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap, 3) == 0) { 645382527734SSukumar Swaminathan return (1); /* success */ 645482527734SSukumar Swaminathan } 645582527734SSukumar Swaminathan return (0); 645682527734SSukumar Swaminathan } 645782527734SSukumar Swaminathan 645882527734SSukumar Swaminathan /* For FIP mode, the FCF record must match Config Region 23 */ 645982527734SSukumar Swaminathan 646082527734SSukumar Swaminathan if (!hba->sli.sli4.cfgFCF.length) { 646182527734SSukumar Swaminathan /* Nothing specified, so everything matches */ 646282527734SSukumar Swaminathan return (1); /* success */ 646382527734SSukumar Swaminathan } 646482527734SSukumar Swaminathan 646582527734SSukumar Swaminathan /* Just check FabricName for now */ 646682527734SSukumar Swaminathan for (i = 0; i < MAX_FCFCONNECTLIST_ENTRIES; i++) { 646782527734SSukumar Swaminathan if ((hba->sli.sli4.cfgFCF.entry[i].FabricNameValid) && 6468*a9800bebSGarrett D'Amore (bcmp((char *)fcfrec->fabric_name_identifier, 6469*a9800bebSGarrett D'Amore hba->sli.sli4.cfgFCF.entry[i].FabricName, 8) == 0)) { 6470*a9800bebSGarrett D'Amore return (1); /* success */ 647182527734SSukumar Swaminathan } 647282527734SSukumar Swaminathan } 6473*a9800bebSGarrett D'Amore return (0); 647482527734SSukumar Swaminathan 6475*a9800bebSGarrett D'Amore } /* emlxs_sli4_check_fcf_config() */ 647682527734SSukumar Swaminathan 647782527734SSukumar Swaminathan 647882527734SSukumar Swaminathan extern void 647982527734SSukumar Swaminathan emlxs_sli4_timer(emlxs_hba_t *hba) 648082527734SSukumar Swaminathan { 648182527734SSukumar Swaminathan /* Perform SLI4 level timer checks */ 648282527734SSukumar Swaminathan 6483*a9800bebSGarrett D'Amore emlxs_fcf_timer_notify(hba); 6484*a9800bebSGarrett D'Amore 648582527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(hba); 648682527734SSukumar Swaminathan 648782527734SSukumar Swaminathan return; 648882527734SSukumar Swaminathan 648982527734SSukumar Swaminathan } /* emlxs_sli4_timer() */ 649082527734SSukumar Swaminathan 649182527734SSukumar Swaminathan 649282527734SSukumar Swaminathan static void 649382527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba) 649482527734SSukumar Swaminathan { 649582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 649682527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 649782527734SSukumar Swaminathan MAILBOX *mb = NULL; 649882527734SSukumar Swaminathan 649982527734SSukumar Swaminathan if (!cfg[CFG_TIMEOUT_ENABLE].current) { 650082527734SSukumar Swaminathan return; 650182527734SSukumar Swaminathan } 650282527734SSukumar Swaminathan 650382527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 650482527734SSukumar Swaminathan 650582527734SSukumar Swaminathan /* Return if timer hasn't expired */ 650682527734SSukumar Swaminathan if (!hba->mbox_timer || (hba->timer_tics < hba->mbox_timer)) { 650782527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 650882527734SSukumar Swaminathan return; 650982527734SSukumar Swaminathan } 6510*a9800bebSGarrett D'Amore 6511*a9800bebSGarrett D'Amore /* The first to service the mbox queue will clear the timer */ 651282527734SSukumar Swaminathan hba->mbox_timer = 0; 651382527734SSukumar Swaminathan 651482527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 651582527734SSukumar Swaminathan if (hba->mbox_mbq) { 651682527734SSukumar Swaminathan mb = (MAILBOX *)hba->mbox_mbq; 651782527734SSukumar Swaminathan } 651882527734SSukumar Swaminathan } 651982527734SSukumar Swaminathan 652082527734SSukumar Swaminathan if (mb) { 652182527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 652282527734SSukumar Swaminathan case MBX_NOWAIT: 652382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 652482527734SSukumar Swaminathan "%s: Nowait.", 652582527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 652682527734SSukumar Swaminathan break; 652782527734SSukumar Swaminathan 652882527734SSukumar Swaminathan case MBX_SLEEP: 652982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 653082527734SSukumar Swaminathan "%s: mb=%p Sleep.", 653182527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 653282527734SSukumar Swaminathan mb); 653382527734SSukumar Swaminathan break; 653482527734SSukumar Swaminathan 653582527734SSukumar Swaminathan case MBX_POLL: 653682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 653782527734SSukumar Swaminathan "%s: mb=%p Polled.", 653882527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 653982527734SSukumar Swaminathan mb); 654082527734SSukumar Swaminathan break; 654182527734SSukumar Swaminathan 654282527734SSukumar Swaminathan default: 654382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 654482527734SSukumar Swaminathan "%s: mb=%p (%d).", 654582527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 654682527734SSukumar Swaminathan mb, hba->mbox_queue_flag); 654782527734SSukumar Swaminathan break; 654882527734SSukumar Swaminathan } 654982527734SSukumar Swaminathan } else { 655082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, NULL); 655182527734SSukumar Swaminathan } 655282527734SSukumar Swaminathan 655382527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 655482527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_ERROR); 655582527734SSukumar Swaminathan 655682527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 655782527734SSukumar Swaminathan 655882527734SSukumar Swaminathan /* Perform mailbox cleanup */ 655982527734SSukumar Swaminathan /* This will wake any sleeping or polling threads */ 656082527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 656182527734SSukumar Swaminathan 656282527734SSukumar Swaminathan /* Trigger adapter shutdown */ 6563*a9800bebSGarrett D'Amore emlxs_thread_spawn(hba, emlxs_shutdown_thread, 0, 0); 656482527734SSukumar Swaminathan 656582527734SSukumar Swaminathan return; 656682527734SSukumar Swaminathan 656782527734SSukumar Swaminathan } /* emlxs_sli4_timer_check_mbox() */ 656882527734SSukumar Swaminathan 656982527734SSukumar Swaminathan 657082527734SSukumar Swaminathan extern void 6571*a9800bebSGarrett D'Amore emlxs_data_dump(emlxs_port_t *port, char *str, uint32_t *iptr, int cnt, int err) 657282527734SSukumar Swaminathan { 657382527734SSukumar Swaminathan void *msg; 657482527734SSukumar Swaminathan 657582527734SSukumar Swaminathan if (err) { 657682527734SSukumar Swaminathan msg = &emlxs_sli_err_msg; 657782527734SSukumar Swaminathan } else { 657882527734SSukumar Swaminathan msg = &emlxs_sli_detail_msg; 657982527734SSukumar Swaminathan } 658082527734SSukumar Swaminathan 658182527734SSukumar Swaminathan if (cnt) { 658282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 658382527734SSukumar Swaminathan "%s00: %08x %08x %08x %08x %08x %08x", str, *iptr, 658482527734SSukumar Swaminathan *(iptr+1), *(iptr+2), *(iptr+3), *(iptr+4), *(iptr+5)); 658582527734SSukumar Swaminathan } 658682527734SSukumar Swaminathan if (cnt > 6) { 658782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 658882527734SSukumar Swaminathan "%s06: %08x %08x %08x %08x %08x %08x", str, *(iptr+6), 658982527734SSukumar Swaminathan *(iptr+7), *(iptr+8), *(iptr+9), *(iptr+10), *(iptr+11)); 659082527734SSukumar Swaminathan } 659182527734SSukumar Swaminathan if (cnt > 12) { 659282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 659382527734SSukumar Swaminathan "%s12: %08x %08x %08x %08x %08x %08x", str, *(iptr+12), 659482527734SSukumar Swaminathan *(iptr+13), *(iptr+14), *(iptr+15), *(iptr+16), *(iptr+17)); 659582527734SSukumar Swaminathan } 659682527734SSukumar Swaminathan if (cnt > 18) { 659782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 659882527734SSukumar Swaminathan "%s18: %08x %08x %08x %08x %08x %08x", str, *(iptr+18), 659982527734SSukumar Swaminathan *(iptr+19), *(iptr+20), *(iptr+21), *(iptr+22), *(iptr+23)); 660082527734SSukumar Swaminathan } 660182527734SSukumar Swaminathan if (cnt > 24) { 660282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 660382527734SSukumar Swaminathan "%s24: %08x %08x %08x %08x %08x %08x", str, *(iptr+24), 660482527734SSukumar Swaminathan *(iptr+25), *(iptr+26), *(iptr+27), *(iptr+28), *(iptr+29)); 660582527734SSukumar Swaminathan } 660682527734SSukumar Swaminathan if (cnt > 30) { 660782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 660882527734SSukumar Swaminathan "%s30: %08x %08x %08x %08x %08x %08x", str, *(iptr+30), 660982527734SSukumar Swaminathan *(iptr+31), *(iptr+32), *(iptr+33), *(iptr+34), *(iptr+35)); 661082527734SSukumar Swaminathan } 661182527734SSukumar Swaminathan if (cnt > 36) { 661282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 661382527734SSukumar Swaminathan "%s36: %08x %08x %08x %08x %08x %08x", str, *(iptr+36), 661482527734SSukumar Swaminathan *(iptr+37), *(iptr+38), *(iptr+39), *(iptr+40), *(iptr+41)); 661582527734SSukumar Swaminathan } 661682527734SSukumar Swaminathan 661782527734SSukumar Swaminathan } /* emlxs_data_dump() */ 661882527734SSukumar Swaminathan 661982527734SSukumar Swaminathan 662082527734SSukumar Swaminathan extern void 662182527734SSukumar Swaminathan emlxs_ue_dump(emlxs_hba_t *hba, char *str) 662282527734SSukumar Swaminathan { 662382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 662482527734SSukumar Swaminathan uint32_t ue_h; 662582527734SSukumar Swaminathan uint32_t ue_l; 662682527734SSukumar Swaminathan uint32_t on1; 662782527734SSukumar Swaminathan uint32_t on2; 662882527734SSukumar Swaminathan 662982527734SSukumar Swaminathan ue_l = ddi_get32(hba->pci_acc_handle, 663082527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET)); 663182527734SSukumar Swaminathan ue_h = ddi_get32(hba->pci_acc_handle, 663282527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET)); 663382527734SSukumar Swaminathan on1 = ddi_get32(hba->pci_acc_handle, 663482527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE1)); 663582527734SSukumar Swaminathan on2 = ddi_get32(hba->pci_acc_handle, 663682527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE2)); 663782527734SSukumar Swaminathan 663882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 663982527734SSukumar Swaminathan "%s: ueLow:%08x ueHigh:%08x on1:%08x on2:%08x", str, 664082527734SSukumar Swaminathan ue_l, ue_h, on1, on2); 664182527734SSukumar Swaminathan 664282527734SSukumar Swaminathan #ifdef FMA_SUPPORT 664382527734SSukumar Swaminathan /* Access handle validation */ 664482527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->pci_acc_handle); 664582527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 664682527734SSukumar Swaminathan 664782527734SSukumar Swaminathan } /* emlxs_ue_dump() */ 664882527734SSukumar Swaminathan 664982527734SSukumar Swaminathan 6650*a9800bebSGarrett D'Amore static void 665182527734SSukumar Swaminathan emlxs_sli4_poll_erratt(emlxs_hba_t *hba) 665282527734SSukumar Swaminathan { 665382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 665482527734SSukumar Swaminathan uint32_t ue_h; 665582527734SSukumar Swaminathan uint32_t ue_l; 665682527734SSukumar Swaminathan 665782527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 665882527734SSukumar Swaminathan return; 665982527734SSukumar Swaminathan } 666082527734SSukumar Swaminathan 6661fe199829SSukumar Swaminathan ue_l = ddi_get32(hba->pci_acc_handle, 6662fe199829SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET)); 6663fe199829SSukumar Swaminathan ue_h = ddi_get32(hba->pci_acc_handle, 6664fe199829SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET)); 666582527734SSukumar Swaminathan 6666fe199829SSukumar Swaminathan if ((~hba->sli.sli4.ue_mask_lo & ue_l) || 6667*a9800bebSGarrett D'Amore (~hba->sli.sli4.ue_mask_hi & ue_h) || 6668*a9800bebSGarrett D'Amore (hba->sli.sli4.flag & EMLXS_SLI4_HW_ERROR)) { 666982527734SSukumar Swaminathan /* Unrecoverable error detected */ 667082527734SSukumar Swaminathan /* Shut the HBA down */ 667182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg, 6672fe199829SSukumar Swaminathan "Host Error: ueLow:%08x ueHigh:%08x maskLow:%08x " 6673fe199829SSukumar Swaminathan "maskHigh:%08x", 6674fe199829SSukumar Swaminathan ue_l, ue_h, hba->sli.sli4.ue_mask_lo, 6675fe199829SSukumar Swaminathan hba->sli.sli4.ue_mask_hi); 667682527734SSukumar Swaminathan 667782527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 667882527734SSukumar Swaminathan 667982527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(hba); 668082527734SSukumar Swaminathan 6681*a9800bebSGarrett D'Amore emlxs_thread_spawn(hba, emlxs_shutdown_thread, 0, 0); 668282527734SSukumar Swaminathan } 668382527734SSukumar Swaminathan 668482527734SSukumar Swaminathan } /* emlxs_sli4_poll_erratt() */ 668582527734SSukumar Swaminathan 6686*a9800bebSGarrett D'Amore 6687*a9800bebSGarrett D'Amore extern uint32_t 6688*a9800bebSGarrett D'Amore emlxs_sli4_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param, 6689*a9800bebSGarrett D'Amore emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq) 669082527734SSukumar Swaminathan { 669182527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 6692*a9800bebSGarrett D'Amore NODELIST *node; 6693*a9800bebSGarrett D'Amore RPIobj_t *rpip; 6694*a9800bebSGarrett D'Amore uint32_t rval; 6695*a9800bebSGarrett D'Amore 6696*a9800bebSGarrett D'Amore /* Check for invalid node ids to register */ 6697*a9800bebSGarrett D'Amore if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) { 6698*a9800bebSGarrett D'Amore return (1); 6699*a9800bebSGarrett D'Amore } 6700*a9800bebSGarrett D'Amore 6701*a9800bebSGarrett D'Amore if (did & 0xff000000) { 6702*a9800bebSGarrett D'Amore return (1); 6703*a9800bebSGarrett D'Amore } 6704*a9800bebSGarrett D'Amore 6705*a9800bebSGarrett D'Amore if ((rval = emlxs_mb_check_sparm(hba, param))) { 6706*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 6707*a9800bebSGarrett D'Amore "Invalid service parameters. did=%06x rval=%d", did, 6708*a9800bebSGarrett D'Amore rval); 6709*a9800bebSGarrett D'Amore 6710*a9800bebSGarrett D'Amore return (1); 6711*a9800bebSGarrett D'Amore } 6712*a9800bebSGarrett D'Amore 6713*a9800bebSGarrett D'Amore /* Check if the node limit has been reached */ 6714*a9800bebSGarrett D'Amore if (port->node_count >= hba->max_nodes) { 6715*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 6716*a9800bebSGarrett D'Amore "Limit reached. did=%06x count=%d", did, 6717*a9800bebSGarrett D'Amore port->node_count); 6718*a9800bebSGarrett D'Amore 6719*a9800bebSGarrett D'Amore return (1); 6720*a9800bebSGarrett D'Amore } 6721*a9800bebSGarrett D'Amore 6722*a9800bebSGarrett D'Amore node = emlxs_node_find_did(port, did); 6723*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 6724*a9800bebSGarrett D'Amore 6725*a9800bebSGarrett D'Amore rval = emlxs_rpi_online_notify(port, rpip, did, param, (void *)sbp, 6726*a9800bebSGarrett D'Amore (void *)ubp, (void *)iocbq); 6727*a9800bebSGarrett D'Amore 6728*a9800bebSGarrett D'Amore return (rval); 6729*a9800bebSGarrett D'Amore 6730*a9800bebSGarrett D'Amore } /* emlxs_sli4_reg_did() */ 6731*a9800bebSGarrett D'Amore 6732*a9800bebSGarrett D'Amore 6733*a9800bebSGarrett D'Amore extern uint32_t 6734*a9800bebSGarrett D'Amore emlxs_sli4_unreg_node(emlxs_port_t *port, emlxs_node_t *node, 6735*a9800bebSGarrett D'Amore emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq) 6736*a9800bebSGarrett D'Amore { 6737*a9800bebSGarrett D'Amore RPIobj_t *rpip; 6738*a9800bebSGarrett D'Amore uint32_t rval; 6739*a9800bebSGarrett D'Amore 6740*a9800bebSGarrett D'Amore if (!node) { 6741*a9800bebSGarrett D'Amore /* Unreg all nodes */ 6742*a9800bebSGarrett D'Amore (void) emlxs_sli4_unreg_all_nodes(port); 6743*a9800bebSGarrett D'Amore return (1); 6744*a9800bebSGarrett D'Amore } 6745*a9800bebSGarrett D'Amore 6746*a9800bebSGarrett D'Amore /* Check for base node */ 6747*a9800bebSGarrett D'Amore if (node == &port->node_base) { 6748*a9800bebSGarrett D'Amore /* Just flush base node */ 6749*a9800bebSGarrett D'Amore (void) emlxs_tx_node_flush(port, &port->node_base, 6750*a9800bebSGarrett D'Amore 0, 0, 0); 6751*a9800bebSGarrett D'Amore 6752*a9800bebSGarrett D'Amore (void) emlxs_chipq_node_flush(port, 0, 6753*a9800bebSGarrett D'Amore &port->node_base, 0); 6754*a9800bebSGarrett D'Amore 6755*a9800bebSGarrett D'Amore port->did = 0; 6756*a9800bebSGarrett D'Amore 6757*a9800bebSGarrett D'Amore /* Return now */ 6758*a9800bebSGarrett D'Amore return (1); 6759*a9800bebSGarrett D'Amore } 6760*a9800bebSGarrett D'Amore 6761*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6762*a9800bebSGarrett D'Amore "unreg_node:%p did=%x rpi=%d", 6763*a9800bebSGarrett D'Amore node, node->nlp_DID, node->nlp_Rpi); 6764*a9800bebSGarrett D'Amore 6765*a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 6766*a9800bebSGarrett D'Amore 6767*a9800bebSGarrett D'Amore if (!rpip) { 6768*a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6769*a9800bebSGarrett D'Amore "unreg_node:%p did=%x rpi=%d. RPI not found.", 6770*a9800bebSGarrett D'Amore node, node->nlp_DID, node->nlp_Rpi); 6771*a9800bebSGarrett D'Amore 6772*a9800bebSGarrett D'Amore emlxs_node_rm(port, node); 6773*a9800bebSGarrett D'Amore return (1); 6774*a9800bebSGarrett D'Amore } 6775*a9800bebSGarrett D'Amore 6776*a9800bebSGarrett D'Amore rval = emlxs_rpi_offline_notify(port, rpip, (void *)sbp, (void *)ubp, 6777*a9800bebSGarrett D'Amore (void *)iocbq); 6778*a9800bebSGarrett D'Amore 6779*a9800bebSGarrett D'Amore return (rval); 6780*a9800bebSGarrett D'Amore 6781*a9800bebSGarrett D'Amore } /* emlxs_sli4_unreg_node() */ 6782*a9800bebSGarrett D'Amore 6783*a9800bebSGarrett D'Amore 6784*a9800bebSGarrett D'Amore extern uint32_t 6785*a9800bebSGarrett D'Amore emlxs_sli4_unreg_all_nodes(emlxs_port_t *port) 6786*a9800bebSGarrett D'Amore { 678782527734SSukumar Swaminathan NODELIST *nlp; 678882527734SSukumar Swaminathan int i; 6789*a9800bebSGarrett D'Amore uint32_t found; 679082527734SSukumar Swaminathan 6791*a9800bebSGarrett D'Amore /* Set the node tags */ 6792*a9800bebSGarrett D'Amore /* We will process all nodes with this tag */ 6793*a9800bebSGarrett D'Amore rw_enter(&port->node_rwlock, RW_READER); 6794*a9800bebSGarrett D'Amore found = 0; 679582527734SSukumar Swaminathan for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 679682527734SSukumar Swaminathan nlp = port->node_table[i]; 679782527734SSukumar Swaminathan while (nlp != NULL) { 6798*a9800bebSGarrett D'Amore found = 1; 6799*a9800bebSGarrett D'Amore nlp->nlp_tag = 1; 6800*a9800bebSGarrett D'Amore nlp = nlp->nlp_list_next; 680182527734SSukumar Swaminathan } 680282527734SSukumar Swaminathan } 680382527734SSukumar Swaminathan rw_exit(&port->node_rwlock); 680482527734SSukumar Swaminathan 6805*a9800bebSGarrett D'Amore if (!found) { 6806*a9800bebSGarrett D'Amore return (0); 6807*a9800bebSGarrett D'Amore } 6808*a9800bebSGarrett D'Amore 6809*a9800bebSGarrett D'Amore for (;;) { 6810*a9800bebSGarrett D'Amore rw_enter(&port->node_rwlock, RW_READER); 6811*a9800bebSGarrett D'Amore found = 0; 6812*a9800bebSGarrett D'Amore for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 6813*a9800bebSGarrett D'Amore nlp = port->node_table[i]; 6814*a9800bebSGarrett D'Amore while (nlp != NULL) { 6815*a9800bebSGarrett D'Amore if (!nlp->nlp_tag) { 6816*a9800bebSGarrett D'Amore nlp = nlp->nlp_list_next; 6817*a9800bebSGarrett D'Amore continue; 6818*a9800bebSGarrett D'Amore } 6819*a9800bebSGarrett D'Amore nlp->nlp_tag = 0; 6820*a9800bebSGarrett D'Amore found = 1; 6821*a9800bebSGarrett D'Amore break; 6822*a9800bebSGarrett D'Amore } 6823*a9800bebSGarrett D'Amore 6824*a9800bebSGarrett D'Amore if (found) { 6825*a9800bebSGarrett D'Amore break; 6826*a9800bebSGarrett D'Amore } 6827*a9800bebSGarrett D'Amore } 6828*a9800bebSGarrett D'Amore rw_exit(&port->node_rwlock); 6829*a9800bebSGarrett D'Amore 6830*a9800bebSGarrett D'Amore if (!found) { 6831*a9800bebSGarrett D'Amore break; 6832*a9800bebSGarrett D'Amore } 6833*a9800bebSGarrett D'Amore 6834*a9800bebSGarrett D'Amore (void) emlxs_sli4_unreg_node(port, nlp, 0, 0, 0); 6835*a9800bebSGarrett D'Amore } 6836*a9800bebSGarrett D'Amore 683782527734SSukumar Swaminathan return (0); 6838*a9800bebSGarrett D'Amore 6839*a9800bebSGarrett D'Amore } /* emlxs_sli4_unreg_all_nodes() */ 6840