1*82527734SSukumar Swaminathan /* 2*82527734SSukumar Swaminathan * CDDL HEADER START 3*82527734SSukumar Swaminathan * 4*82527734SSukumar Swaminathan * The contents of this file are subject to the terms of the 5*82527734SSukumar Swaminathan * Common Development and Distribution License (the "License"). 6*82527734SSukumar Swaminathan * You may not use this file except in compliance with the License. 7*82527734SSukumar Swaminathan * 8*82527734SSukumar Swaminathan * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*82527734SSukumar Swaminathan * or http://www.opensolaris.org/os/licensing. 10*82527734SSukumar Swaminathan * See the License for the specific language governing permissions 11*82527734SSukumar Swaminathan * and limitations under the License. 12*82527734SSukumar Swaminathan * 13*82527734SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each 14*82527734SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*82527734SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the 16*82527734SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying 17*82527734SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner] 18*82527734SSukumar Swaminathan * 19*82527734SSukumar Swaminathan * CDDL HEADER END 20*82527734SSukumar Swaminathan */ 21*82527734SSukumar Swaminathan 22*82527734SSukumar Swaminathan /* 23*82527734SSukumar Swaminathan * Copyright 2009 Emulex. All rights reserved. 24*82527734SSukumar Swaminathan * Use is subject to license terms. 25*82527734SSukumar Swaminathan */ 26*82527734SSukumar Swaminathan 27*82527734SSukumar Swaminathan 28*82527734SSukumar Swaminathan #include <emlxs.h> 29*82527734SSukumar Swaminathan 30*82527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 31*82527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_SLI4_C); 32*82527734SSukumar Swaminathan 33*82527734SSukumar Swaminathan static int emlxs_sli4_create_queues(emlxs_hba_t *hba, 34*82527734SSukumar Swaminathan MAILBOXQ *mbq); 35*82527734SSukumar Swaminathan static int emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, 36*82527734SSukumar Swaminathan MAILBOXQ *mbq); 37*82527734SSukumar Swaminathan static int emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, 38*82527734SSukumar Swaminathan MAILBOXQ *mbq); 39*82527734SSukumar Swaminathan static int emlxs_fcf_bind(emlxs_hba_t *hba); 40*82527734SSukumar Swaminathan 41*82527734SSukumar Swaminathan static int emlxs_fcf_unbind(emlxs_hba_t *hba, uint32_t index); 42*82527734SSukumar Swaminathan 43*82527734SSukumar Swaminathan static int emlxs_sli4_poll_eq(emlxs_hba_t *hba, EQ_DESC_t *eq); 44*82527734SSukumar Swaminathan 45*82527734SSukumar Swaminathan extern void emlxs_parse_prog_types(emlxs_hba_t *hba, char *types); 46*82527734SSukumar Swaminathan 47*82527734SSukumar Swaminathan extern int32_t emlxs_parse_vpd(emlxs_hba_t *hba, uint8_t *vpd, 48*82527734SSukumar Swaminathan uint32_t size); 49*82527734SSukumar Swaminathan extern void emlxs_decode_label(char *label, char *buffer, int bige); 50*82527734SSukumar Swaminathan 51*82527734SSukumar Swaminathan extern void emlxs_build_prog_types(emlxs_hba_t *hba, 52*82527734SSukumar Swaminathan char *prog_types); 53*82527734SSukumar Swaminathan 54*82527734SSukumar Swaminathan extern int emlxs_pci_model_count; 55*82527734SSukumar Swaminathan 56*82527734SSukumar Swaminathan extern emlxs_model_t emlxs_pci_model[]; 57*82527734SSukumar Swaminathan 58*82527734SSukumar Swaminathan static int emlxs_sli4_map_hdw(emlxs_hba_t *hba); 59*82527734SSukumar Swaminathan 60*82527734SSukumar Swaminathan static void emlxs_sli4_unmap_hdw(emlxs_hba_t *hba); 61*82527734SSukumar Swaminathan 62*82527734SSukumar Swaminathan static int32_t emlxs_sli4_online(emlxs_hba_t *hba); 63*82527734SSukumar Swaminathan 64*82527734SSukumar Swaminathan static void emlxs_sli4_offline(emlxs_hba_t *hba); 65*82527734SSukumar Swaminathan 66*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, 67*82527734SSukumar Swaminathan uint32_t skip_post, uint32_t quiesce); 68*82527734SSukumar Swaminathan static void emlxs_sli4_hba_kill(emlxs_hba_t *hba); 69*82527734SSukumar Swaminathan 70*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_init(emlxs_hba_t *hba); 71*82527734SSukumar Swaminathan 72*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_bde_setup(emlxs_port_t *port, 73*82527734SSukumar Swaminathan emlxs_buf_t *sbp); 74*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_fct_bde_setup(emlxs_port_t *port, 75*82527734SSukumar Swaminathan emlxs_buf_t *sbp); 76*82527734SSukumar Swaminathan static void emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, 77*82527734SSukumar Swaminathan CHANNEL *rp, IOCBQ *iocb_cmd); 78*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, 79*82527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 80*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, 81*82527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 82*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 83*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, 84*82527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp, int channel); 85*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 86*82527734SSukumar Swaminathan 87*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, 88*82527734SSukumar Swaminathan emlxs_buf_t *sbp, int ring); 89*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, 90*82527734SSukumar Swaminathan emlxs_buf_t *sbp); 91*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_els_iocb(emlxs_port_t *port, 92*82527734SSukumar Swaminathan emlxs_buf_t *sbp); 93*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, 94*82527734SSukumar Swaminathan emlxs_buf_t *sbp); 95*82527734SSukumar Swaminathan static void emlxs_sli4_poll_intr(emlxs_hba_t *hba, 96*82527734SSukumar Swaminathan uint32_t att_bit); 97*82527734SSukumar Swaminathan static int32_t emlxs_sli4_intx_intr(char *arg); 98*82527734SSukumar Swaminathan 99*82527734SSukumar Swaminathan #ifdef MSI_SUPPORT 100*82527734SSukumar Swaminathan static uint32_t emlxs_sli4_msi_intr(char *arg1, char *arg2); 101*82527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 102*82527734SSukumar Swaminathan 103*82527734SSukumar Swaminathan static void emlxs_sli4_resource_free(emlxs_hba_t *hba); 104*82527734SSukumar Swaminathan 105*82527734SSukumar Swaminathan static int emlxs_sli4_resource_alloc(emlxs_hba_t *hba); 106*82527734SSukumar Swaminathan 107*82527734SSukumar Swaminathan static void emlxs_sli4_destroy_queues(emlxs_hba_t *hba); 108*82527734SSukumar Swaminathan 109*82527734SSukumar Swaminathan static XRIobj_t *emlxs_sli4_alloc_xri(emlxs_hba_t *hba, 110*82527734SSukumar Swaminathan emlxs_buf_t *sbp, RPIobj_t *rp); 111*82527734SSukumar Swaminathan static void emlxs_sli4_free_vpi(emlxs_hba_t *hba, emlxs_port_t *pp); 112*82527734SSukumar Swaminathan 113*82527734SSukumar Swaminathan static void emlxs_sli4_enable_intr(emlxs_hba_t *hba); 114*82527734SSukumar Swaminathan 115*82527734SSukumar Swaminathan static void emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att); 116*82527734SSukumar Swaminathan 117*82527734SSukumar Swaminathan extern void emlxs_sli4_timer(emlxs_hba_t *hba); 118*82527734SSukumar Swaminathan 119*82527734SSukumar Swaminathan static void emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba); 120*82527734SSukumar Swaminathan 121*82527734SSukumar Swaminathan extern void emlxs_sli4_poll_erratt(emlxs_hba_t *hba); 122*82527734SSukumar Swaminathan 123*82527734SSukumar Swaminathan static XRIobj_t *emlxs_sli4_register_xri(emlxs_hba_t *hba, 124*82527734SSukumar Swaminathan emlxs_buf_t *sbp, uint16_t xri); 125*82527734SSukumar Swaminathan 126*82527734SSukumar Swaminathan static XRIobj_t *emlxs_sli4_reserve_xri(emlxs_hba_t *hba, RPIobj_t *rp); 127*82527734SSukumar Swaminathan 128*82527734SSukumar Swaminathan static int emlxs_check_hdw_ready(emlxs_hba_t *); 129*82527734SSukumar Swaminathan 130*82527734SSukumar Swaminathan /* Define SLI4 API functions */ 131*82527734SSukumar Swaminathan emlxs_sli_api_t emlxs_sli4_api = { 132*82527734SSukumar Swaminathan emlxs_sli4_map_hdw, 133*82527734SSukumar Swaminathan emlxs_sli4_unmap_hdw, 134*82527734SSukumar Swaminathan emlxs_sli4_online, 135*82527734SSukumar Swaminathan emlxs_sli4_offline, 136*82527734SSukumar Swaminathan emlxs_sli4_hba_reset, 137*82527734SSukumar Swaminathan emlxs_sli4_hba_kill, 138*82527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd, 139*82527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd, 140*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 141*82527734SSukumar Swaminathan emlxs_sli4_prep_fct_iocb, 142*82527734SSukumar Swaminathan #else 143*82527734SSukumar Swaminathan NULL, 144*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 145*82527734SSukumar Swaminathan emlxs_sli4_prep_fcp_iocb, 146*82527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb, 147*82527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb, 148*82527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb, 149*82527734SSukumar Swaminathan emlxs_sli4_poll_intr, 150*82527734SSukumar Swaminathan emlxs_sli4_intx_intr, 151*82527734SSukumar Swaminathan emlxs_sli4_msi_intr, 152*82527734SSukumar Swaminathan emlxs_sli4_disable_intr, 153*82527734SSukumar Swaminathan emlxs_sli4_timer, 154*82527734SSukumar Swaminathan emlxs_sli4_poll_erratt 155*82527734SSukumar Swaminathan }; 156*82527734SSukumar Swaminathan 157*82527734SSukumar Swaminathan 158*82527734SSukumar Swaminathan /* ************************************************************************** */ 159*82527734SSukumar Swaminathan 160*82527734SSukumar Swaminathan 161*82527734SSukumar Swaminathan /* 162*82527734SSukumar Swaminathan * emlxs_sli4_online() 163*82527734SSukumar Swaminathan * 164*82527734SSukumar Swaminathan * This routine will start initialization of the SLI4 HBA. 165*82527734SSukumar Swaminathan */ 166*82527734SSukumar Swaminathan static int32_t 167*82527734SSukumar Swaminathan emlxs_sli4_online(emlxs_hba_t *hba) 168*82527734SSukumar Swaminathan { 169*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 170*82527734SSukumar Swaminathan emlxs_config_t *cfg; 171*82527734SSukumar Swaminathan emlxs_vpd_t *vpd; 172*82527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 173*82527734SSukumar Swaminathan MAILBOX4 *mb = NULL; 174*82527734SSukumar Swaminathan MATCHMAP *mp = NULL; 175*82527734SSukumar Swaminathan MATCHMAP *mp1 = NULL; 176*82527734SSukumar Swaminathan uint32_t i; 177*82527734SSukumar Swaminathan uint32_t j; 178*82527734SSukumar Swaminathan uint32_t rval = 0; 179*82527734SSukumar Swaminathan uint8_t *vpd_data; 180*82527734SSukumar Swaminathan uint32_t sli_mode; 181*82527734SSukumar Swaminathan uint8_t *outptr; 182*82527734SSukumar Swaminathan uint32_t status; 183*82527734SSukumar Swaminathan uint32_t fw_check; 184*82527734SSukumar Swaminathan emlxs_firmware_t hba_fw; 185*82527734SSukumar Swaminathan emlxs_firmware_t *fw; 186*82527734SSukumar Swaminathan 187*82527734SSukumar Swaminathan cfg = &CFG; 188*82527734SSukumar Swaminathan vpd = &VPD; 189*82527734SSukumar Swaminathan 190*82527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI4_MODE; 191*82527734SSukumar Swaminathan hba->sli_mode = sli_mode; 192*82527734SSukumar Swaminathan 193*82527734SSukumar Swaminathan /* Set the fw_check flag */ 194*82527734SSukumar Swaminathan fw_check = cfg[CFG_FW_CHECK].current; 195*82527734SSukumar Swaminathan 196*82527734SSukumar Swaminathan hba->mbox_queue_flag = 0; 197*82527734SSukumar Swaminathan hba->fc_edtov = FF_DEF_EDTOV; 198*82527734SSukumar Swaminathan hba->fc_ratov = FF_DEF_RATOV; 199*82527734SSukumar Swaminathan hba->fc_altov = FF_DEF_ALTOV; 200*82527734SSukumar Swaminathan hba->fc_arbtov = FF_DEF_ARBTOV; 201*82527734SSukumar Swaminathan 202*82527734SSukumar Swaminathan /* Target mode not supported */ 203*82527734SSukumar Swaminathan if (hba->tgt_mode) { 204*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 205*82527734SSukumar Swaminathan "Target mode not supported in SLI4."); 206*82527734SSukumar Swaminathan 207*82527734SSukumar Swaminathan return (ENOMEM); 208*82527734SSukumar Swaminathan } 209*82527734SSukumar Swaminathan 210*82527734SSukumar Swaminathan /* Networking not supported */ 211*82527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current) { 212*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 213*82527734SSukumar Swaminathan "Networking not supported in SLI4, turning it off"); 214*82527734SSukumar Swaminathan cfg[CFG_NETWORK_ON].current = 0; 215*82527734SSukumar Swaminathan } 216*82527734SSukumar Swaminathan 217*82527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 218*82527734SSukumar Swaminathan if (hba->chan_count > MAX_CHANNEL) { 219*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 220*82527734SSukumar Swaminathan "Max channels exceeded, dropping num-wq from %d to 1", 221*82527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current); 222*82527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current = 1; 223*82527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 224*82527734SSukumar Swaminathan } 225*82527734SSukumar Swaminathan hba->channel_fcp = 0; /* First channel */ 226*82527734SSukumar Swaminathan 227*82527734SSukumar Swaminathan /* Default channel for everything else is the last channel */ 228*82527734SSukumar Swaminathan hba->channel_ip = hba->chan_count - 1; 229*82527734SSukumar Swaminathan hba->channel_els = hba->chan_count - 1; 230*82527734SSukumar Swaminathan hba->channel_ct = hba->chan_count - 1; 231*82527734SSukumar Swaminathan 232*82527734SSukumar Swaminathan hba->fc_iotag = 1; 233*82527734SSukumar Swaminathan hba->io_count = 0; 234*82527734SSukumar Swaminathan hba->channel_tx_count = 0; 235*82527734SSukumar Swaminathan 236*82527734SSukumar Swaminathan /* Initialize the local dump region buffer */ 237*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.dump_region, sizeof (MBUF_INFO)); 238*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.size = EMLXS_DUMP_REGION_SIZE; 239*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.flags = FC_MBUF_DMA | FC_MBUF_SNGLSG 240*82527734SSukumar Swaminathan | FC_MBUF_DMA32; 241*82527734SSukumar Swaminathan hba->sli.sli4.dump_region.align = ddi_ptob(hba->dip, 1L); 242*82527734SSukumar Swaminathan 243*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, &hba->sli.sli4.dump_region); 244*82527734SSukumar Swaminathan 245*82527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt == NULL) { 246*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 247*82527734SSukumar Swaminathan "Unable to allocate dump region buffer."); 248*82527734SSukumar Swaminathan 249*82527734SSukumar Swaminathan return (ENOMEM); 250*82527734SSukumar Swaminathan } 251*82527734SSukumar Swaminathan 252*82527734SSukumar Swaminathan /* 253*82527734SSukumar Swaminathan * Get a buffer which will be used repeatedly for mailbox commands 254*82527734SSukumar Swaminathan */ 255*82527734SSukumar Swaminathan mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP); 256*82527734SSukumar Swaminathan 257*82527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 258*82527734SSukumar Swaminathan 259*82527734SSukumar Swaminathan reset: 260*82527734SSukumar Swaminathan /* Reset & Initialize the adapter */ 261*82527734SSukumar Swaminathan if (emlxs_sli4_hba_init(hba)) { 262*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 263*82527734SSukumar Swaminathan "Unable to init hba."); 264*82527734SSukumar Swaminathan 265*82527734SSukumar Swaminathan rval = EIO; 266*82527734SSukumar Swaminathan goto failed1; 267*82527734SSukumar Swaminathan } 268*82527734SSukumar Swaminathan 269*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 270*82527734SSukumar Swaminathan /* Access handle validation */ 271*82527734SSukumar Swaminathan if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle) 272*82527734SSukumar Swaminathan != DDI_FM_OK) || 273*82527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli4.bar1_acc_handle) 274*82527734SSukumar Swaminathan != DDI_FM_OK) || 275*82527734SSukumar Swaminathan (emlxs_fm_check_acc_handle(hba, hba->sli.sli4.bar2_acc_handle) 276*82527734SSukumar Swaminathan != DDI_FM_OK)) { 277*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 278*82527734SSukumar Swaminathan &emlxs_invalid_access_handle_msg, NULL); 279*82527734SSukumar Swaminathan 280*82527734SSukumar Swaminathan rval = EIO; 281*82527734SSukumar Swaminathan goto failed1; 282*82527734SSukumar Swaminathan } 283*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 284*82527734SSukumar Swaminathan 285*82527734SSukumar Swaminathan /* 286*82527734SSukumar Swaminathan * Setup and issue mailbox READ REV command 287*82527734SSukumar Swaminathan */ 288*82527734SSukumar Swaminathan vpd->opFwRev = 0; 289*82527734SSukumar Swaminathan vpd->postKernRev = 0; 290*82527734SSukumar Swaminathan vpd->sli1FwRev = 0; 291*82527734SSukumar Swaminathan vpd->sli2FwRev = 0; 292*82527734SSukumar Swaminathan vpd->sli3FwRev = 0; 293*82527734SSukumar Swaminathan vpd->sli4FwRev = 0; 294*82527734SSukumar Swaminathan 295*82527734SSukumar Swaminathan vpd->postKernName[0] = 0; 296*82527734SSukumar Swaminathan vpd->opFwName[0] = 0; 297*82527734SSukumar Swaminathan vpd->sli1FwName[0] = 0; 298*82527734SSukumar Swaminathan vpd->sli2FwName[0] = 0; 299*82527734SSukumar Swaminathan vpd->sli3FwName[0] = 0; 300*82527734SSukumar Swaminathan vpd->sli4FwName[0] = 0; 301*82527734SSukumar Swaminathan 302*82527734SSukumar Swaminathan vpd->opFwLabel[0] = 0; 303*82527734SSukumar Swaminathan vpd->sli1FwLabel[0] = 0; 304*82527734SSukumar Swaminathan vpd->sli2FwLabel[0] = 0; 305*82527734SSukumar Swaminathan vpd->sli3FwLabel[0] = 0; 306*82527734SSukumar Swaminathan vpd->sli4FwLabel[0] = 0; 307*82527734SSukumar Swaminathan 308*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_REV); 309*82527734SSukumar Swaminathan 310*82527734SSukumar Swaminathan emlxs_mb_read_rev(hba, mbq, 0); 311*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 312*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 313*82527734SSukumar Swaminathan "Unable to read rev. Mailbox cmd=%x status=%x", 314*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 315*82527734SSukumar Swaminathan 316*82527734SSukumar Swaminathan rval = EIO; 317*82527734SSukumar Swaminathan goto failed1; 318*82527734SSukumar Swaminathan 319*82527734SSukumar Swaminathan } 320*82527734SSukumar Swaminathan 321*82527734SSukumar Swaminathan emlxs_data_dump(hba, "RD_REV", (uint32_t *)mb, 18, 0); 322*82527734SSukumar Swaminathan if (mb->un.varRdRev4.sliLevel != 4) { 323*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 324*82527734SSukumar Swaminathan "Invalid read rev Version for SLI4: 0x%x", 325*82527734SSukumar Swaminathan mb->un.varRdRev4.sliLevel); 326*82527734SSukumar Swaminathan 327*82527734SSukumar Swaminathan rval = EIO; 328*82527734SSukumar Swaminathan goto failed1; 329*82527734SSukumar Swaminathan } 330*82527734SSukumar Swaminathan 331*82527734SSukumar Swaminathan switch (mb->un.varRdRev4.dcbxMode) { 332*82527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CIN: /* Mapped to nonFIP mode */ 333*82527734SSukumar Swaminathan hba->flag &= ~FC_FIP_SUPPORTED; 334*82527734SSukumar Swaminathan break; 335*82527734SSukumar Swaminathan 336*82527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CEE: /* Mapped to FIP mode */ 337*82527734SSukumar Swaminathan hba->flag |= FC_FIP_SUPPORTED; 338*82527734SSukumar Swaminathan break; 339*82527734SSukumar Swaminathan 340*82527734SSukumar Swaminathan default: 341*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 342*82527734SSukumar Swaminathan "Invalid read rev dcbx mode for SLI4: 0x%x", 343*82527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 344*82527734SSukumar Swaminathan 345*82527734SSukumar Swaminathan rval = EIO; 346*82527734SSukumar Swaminathan goto failed1; 347*82527734SSukumar Swaminathan } 348*82527734SSukumar Swaminathan 349*82527734SSukumar Swaminathan 350*82527734SSukumar Swaminathan /* Save information as VPD data */ 351*82527734SSukumar Swaminathan vpd->rBit = 1; 352*82527734SSukumar Swaminathan 353*82527734SSukumar Swaminathan vpd->sli4FwRev = (mb->un.varRdRev4.ULPFwId); 354*82527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->sli4FwName, 16); 355*82527734SSukumar Swaminathan 356*82527734SSukumar Swaminathan vpd->opFwRev = (mb->un.varRdRev4.ULPFwId); 357*82527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->opFwName, 16); 358*82527734SSukumar Swaminathan 359*82527734SSukumar Swaminathan vpd->postKernRev = (mb->un.varRdRev4.ARMFwId); 360*82527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ARMFwName, vpd->postKernName, 16); 361*82527734SSukumar Swaminathan 362*82527734SSukumar Swaminathan vpd->fcphHigh = mb->un.varRdRev4.fcphHigh; 363*82527734SSukumar Swaminathan vpd->fcphLow = mb->un.varRdRev4.fcphLow; 364*82527734SSukumar Swaminathan vpd->feaLevelHigh = mb->un.varRdRev4.feaLevelHigh; 365*82527734SSukumar Swaminathan vpd->feaLevelLow = mb->un.varRdRev4.feaLevelLow; 366*82527734SSukumar Swaminathan 367*82527734SSukumar Swaminathan /* Decode FW labels */ 368*82527734SSukumar Swaminathan emlxs_decode_label(vpd->sli4FwName, vpd->sli4FwName, 0); 369*82527734SSukumar Swaminathan emlxs_decode_label(vpd->opFwName, vpd->opFwName, 0); 370*82527734SSukumar Swaminathan emlxs_decode_label(vpd->postKernName, vpd->postKernName, 0); 371*82527734SSukumar Swaminathan 372*82527734SSukumar Swaminathan if (hba->model_info.chip == EMLXS_TIGERSHARK_CHIP) { 373*82527734SSukumar Swaminathan (void) strcpy(vpd->sli4FwLabel, "be2.ufi"); 374*82527734SSukumar Swaminathan } else { 375*82527734SSukumar Swaminathan (void) strcpy(vpd->sli4FwLabel, "sli4.fw"); 376*82527734SSukumar Swaminathan } 377*82527734SSukumar Swaminathan 378*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 379*82527734SSukumar Swaminathan "VPD ULP:%08x %s ARM:%08x %s f:%d %d %d %d : dcbx %d", 380*82527734SSukumar Swaminathan vpd->opFwRev, vpd->opFwName, vpd->postKernRev, vpd->postKernName, 381*82527734SSukumar Swaminathan vpd->fcphHigh, vpd->fcphLow, vpd->feaLevelHigh, vpd->feaLevelLow, 382*82527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 383*82527734SSukumar Swaminathan 384*82527734SSukumar Swaminathan /* No key information is needed for SLI4 products */ 385*82527734SSukumar Swaminathan 386*82527734SSukumar Swaminathan /* Get adapter VPD information */ 387*82527734SSukumar Swaminathan vpd->port_index = (uint32_t)-1; 388*82527734SSukumar Swaminathan 389*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 390*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 391*82527734SSukumar Swaminathan 392*82527734SSukumar Swaminathan emlxs_mb_dump_vpd(hba, mbq, 0); 393*82527734SSukumar Swaminathan vpd_data = hba->sli.sli4.dump_region.virt; 394*82527734SSukumar Swaminathan 395*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 396*82527734SSukumar Swaminathan MBX_SUCCESS) { 397*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 398*82527734SSukumar Swaminathan "No VPD found. status=%x", mb->mbxStatus); 399*82527734SSukumar Swaminathan } else { 400*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 401*82527734SSukumar Swaminathan &emlxs_init_debug_msg, 402*82527734SSukumar Swaminathan "VPD dumped. rsp_cnt=%d status=%x", 403*82527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 404*82527734SSukumar Swaminathan 405*82527734SSukumar Swaminathan if (mb->un.varDmp4.rsp_cnt) { 406*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 407*82527734SSukumar Swaminathan 0, mb->un.varDmp4.rsp_cnt, DDI_DMA_SYNC_FORKERNEL); 408*82527734SSukumar Swaminathan 409*82527734SSukumar Swaminathan } 410*82527734SSukumar Swaminathan } 411*82527734SSukumar Swaminathan 412*82527734SSukumar Swaminathan if (vpd_data[0]) { 413*82527734SSukumar Swaminathan (void) emlxs_parse_vpd(hba, (uint8_t *)vpd_data, 414*82527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt); 415*82527734SSukumar Swaminathan 416*82527734SSukumar Swaminathan /* 417*82527734SSukumar Swaminathan * If there is a VPD part number, and it does not 418*82527734SSukumar Swaminathan * match the current default HBA model info, 419*82527734SSukumar Swaminathan * replace the default data with an entry that 420*82527734SSukumar Swaminathan * does match. 421*82527734SSukumar Swaminathan * 422*82527734SSukumar Swaminathan * After emlxs_parse_vpd model holds the VPD value 423*82527734SSukumar Swaminathan * for V2 and part_num hold the value for PN. These 424*82527734SSukumar Swaminathan * 2 values are NOT necessarily the same. 425*82527734SSukumar Swaminathan */ 426*82527734SSukumar Swaminathan 427*82527734SSukumar Swaminathan rval = 0; 428*82527734SSukumar Swaminathan if ((vpd->model[0] != 0) && 429*82527734SSukumar Swaminathan (strcmp(&vpd->model[0], hba->model_info.model) != 0)) { 430*82527734SSukumar Swaminathan 431*82527734SSukumar Swaminathan /* First scan for a V2 match */ 432*82527734SSukumar Swaminathan 433*82527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 434*82527734SSukumar Swaminathan if (strcmp(&vpd->model[0], 435*82527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 436*82527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 437*82527734SSukumar Swaminathan &hba->model_info, 438*82527734SSukumar Swaminathan sizeof (emlxs_model_t)); 439*82527734SSukumar Swaminathan rval = 1; 440*82527734SSukumar Swaminathan break; 441*82527734SSukumar Swaminathan } 442*82527734SSukumar Swaminathan } 443*82527734SSukumar Swaminathan } 444*82527734SSukumar Swaminathan 445*82527734SSukumar Swaminathan if (!rval && (vpd->part_num[0] != 0) && 446*82527734SSukumar Swaminathan (strcmp(&vpd->part_num[0], hba->model_info.model) != 0)) { 447*82527734SSukumar Swaminathan 448*82527734SSukumar Swaminathan /* Next scan for a PN match */ 449*82527734SSukumar Swaminathan 450*82527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 451*82527734SSukumar Swaminathan if (strcmp(&vpd->part_num[0], 452*82527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 453*82527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 454*82527734SSukumar Swaminathan &hba->model_info, 455*82527734SSukumar Swaminathan sizeof (emlxs_model_t)); 456*82527734SSukumar Swaminathan break; 457*82527734SSukumar Swaminathan } 458*82527734SSukumar Swaminathan } 459*82527734SSukumar Swaminathan } 460*82527734SSukumar Swaminathan 461*82527734SSukumar Swaminathan /* 462*82527734SSukumar Swaminathan * Now lets update hba->model_info with the real 463*82527734SSukumar Swaminathan * VPD data, if any. 464*82527734SSukumar Swaminathan */ 465*82527734SSukumar Swaminathan 466*82527734SSukumar Swaminathan /* 467*82527734SSukumar Swaminathan * Replace the default model description with vpd data 468*82527734SSukumar Swaminathan */ 469*82527734SSukumar Swaminathan if (vpd->model_desc[0] != 0) { 470*82527734SSukumar Swaminathan (void) strcpy(hba->model_info.model_desc, 471*82527734SSukumar Swaminathan vpd->model_desc); 472*82527734SSukumar Swaminathan } 473*82527734SSukumar Swaminathan 474*82527734SSukumar Swaminathan /* Replace the default model with vpd data */ 475*82527734SSukumar Swaminathan if (vpd->model[0] != 0) { 476*82527734SSukumar Swaminathan (void) strcpy(hba->model_info.model, vpd->model); 477*82527734SSukumar Swaminathan } 478*82527734SSukumar Swaminathan 479*82527734SSukumar Swaminathan /* Replace the default program types with vpd data */ 480*82527734SSukumar Swaminathan if (vpd->prog_types[0] != 0) { 481*82527734SSukumar Swaminathan emlxs_parse_prog_types(hba, vpd->prog_types); 482*82527734SSukumar Swaminathan } 483*82527734SSukumar Swaminathan } 484*82527734SSukumar Swaminathan 485*82527734SSukumar Swaminathan /* 486*82527734SSukumar Swaminathan * Since the adapter model may have changed with the vpd data 487*82527734SSukumar Swaminathan * lets double check if adapter is not supported 488*82527734SSukumar Swaminathan */ 489*82527734SSukumar Swaminathan if (hba->model_info.flags & EMLXS_NOT_SUPPORTED) { 490*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 491*82527734SSukumar Swaminathan "Unsupported adapter found. " 492*82527734SSukumar Swaminathan "Id:%d Device id:0x%x SSDID:0x%x Model:%s", 493*82527734SSukumar Swaminathan hba->model_info.id, hba->model_info.device_id, 494*82527734SSukumar Swaminathan hba->model_info.ssdid, hba->model_info.model); 495*82527734SSukumar Swaminathan 496*82527734SSukumar Swaminathan rval = EIO; 497*82527734SSukumar Swaminathan goto failed1; 498*82527734SSukumar Swaminathan } 499*82527734SSukumar Swaminathan 500*82527734SSukumar Swaminathan (void) strcpy(vpd->boot_version, vpd->sli4FwName); 501*82527734SSukumar Swaminathan 502*82527734SSukumar Swaminathan /* Get fcode version property */ 503*82527734SSukumar Swaminathan emlxs_get_fcode_version(hba); 504*82527734SSukumar Swaminathan 505*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 506*82527734SSukumar Swaminathan "Firmware: kern=%08x stub=%08x sli1=%08x", vpd->postKernRev, 507*82527734SSukumar Swaminathan vpd->opFwRev, vpd->sli1FwRev); 508*82527734SSukumar Swaminathan 509*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 510*82527734SSukumar Swaminathan "Firmware: sli2=%08x sli3=%08x sli4=%08x fl=%x", vpd->sli2FwRev, 511*82527734SSukumar Swaminathan vpd->sli3FwRev, vpd->sli4FwRev, vpd->feaLevelHigh); 512*82527734SSukumar Swaminathan 513*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 514*82527734SSukumar Swaminathan "BIOS: boot=%s fcode=%s", vpd->boot_version, vpd->fcode_version); 515*82527734SSukumar Swaminathan 516*82527734SSukumar Swaminathan /* 517*82527734SSukumar Swaminathan * If firmware checking is enabled and the adapter model indicates 518*82527734SSukumar Swaminathan * a firmware image, then perform firmware version check 519*82527734SSukumar Swaminathan */ 520*82527734SSukumar Swaminathan if (((fw_check == 1) && (hba->model_info.flags & EMLXS_SUN_BRANDED) && 521*82527734SSukumar Swaminathan hba->model_info.fwid) || ((fw_check == 2) && 522*82527734SSukumar Swaminathan hba->model_info.fwid)) { 523*82527734SSukumar Swaminathan 524*82527734SSukumar Swaminathan /* Find firmware image indicated by adapter model */ 525*82527734SSukumar Swaminathan fw = NULL; 526*82527734SSukumar Swaminathan for (i = 0; i < emlxs_fw_count; i++) { 527*82527734SSukumar Swaminathan if (emlxs_fw_table[i].id == hba->model_info.fwid) { 528*82527734SSukumar Swaminathan fw = &emlxs_fw_table[i]; 529*82527734SSukumar Swaminathan break; 530*82527734SSukumar Swaminathan } 531*82527734SSukumar Swaminathan } 532*82527734SSukumar Swaminathan 533*82527734SSukumar Swaminathan /* 534*82527734SSukumar Swaminathan * If the image was found, then verify current firmware 535*82527734SSukumar Swaminathan * versions of adapter 536*82527734SSukumar Swaminathan */ 537*82527734SSukumar Swaminathan if (fw) { 538*82527734SSukumar Swaminathan 539*82527734SSukumar Swaminathan /* Obtain current firmware version info */ 540*82527734SSukumar Swaminathan if (hba->model_info.chip == EMLXS_TIGERSHARK_CHIP) { 541*82527734SSukumar Swaminathan (void) emlxs_sli4_read_fw_version(hba, &hba_fw); 542*82527734SSukumar Swaminathan } else { 543*82527734SSukumar Swaminathan hba_fw.kern = vpd->postKernRev; 544*82527734SSukumar Swaminathan hba_fw.stub = vpd->opFwRev; 545*82527734SSukumar Swaminathan hba_fw.sli1 = vpd->sli1FwRev; 546*82527734SSukumar Swaminathan hba_fw.sli2 = vpd->sli2FwRev; 547*82527734SSukumar Swaminathan hba_fw.sli3 = vpd->sli3FwRev; 548*82527734SSukumar Swaminathan hba_fw.sli4 = vpd->sli4FwRev; 549*82527734SSukumar Swaminathan } 550*82527734SSukumar Swaminathan 551*82527734SSukumar Swaminathan if ((fw->kern && (hba_fw.kern != fw->kern)) || 552*82527734SSukumar Swaminathan (fw->stub && (hba_fw.stub != fw->stub)) || 553*82527734SSukumar Swaminathan (fw->sli1 && (hba_fw.sli1 != fw->sli1)) || 554*82527734SSukumar Swaminathan (fw->sli2 && (hba_fw.sli2 != fw->sli2)) || 555*82527734SSukumar Swaminathan (fw->sli3 && (hba_fw.sli3 != fw->sli3)) || 556*82527734SSukumar Swaminathan (fw->sli4 && (hba_fw.sli4 != fw->sli4))) { 557*82527734SSukumar Swaminathan 558*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 559*82527734SSukumar Swaminathan "Firmware update needed. " 560*82527734SSukumar Swaminathan "Updating. id=%d fw=%d", 561*82527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 562*82527734SSukumar Swaminathan 563*82527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 564*82527734SSukumar Swaminathan /* 565*82527734SSukumar Swaminathan * Load the firmware image now 566*82527734SSukumar Swaminathan * If MODFW_SUPPORT is not defined, the 567*82527734SSukumar Swaminathan * firmware image will already be defined 568*82527734SSukumar Swaminathan * in the emlxs_fw_table 569*82527734SSukumar Swaminathan */ 570*82527734SSukumar Swaminathan emlxs_fw_load(hba, fw); 571*82527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 572*82527734SSukumar Swaminathan 573*82527734SSukumar Swaminathan if (fw->image && fw->size) { 574*82527734SSukumar Swaminathan if (emlxs_fw_download(hba, 575*82527734SSukumar Swaminathan (char *)fw->image, fw->size, 0)) { 576*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 577*82527734SSukumar Swaminathan &emlxs_init_msg, 578*82527734SSukumar Swaminathan "Firmware update failed."); 579*82527734SSukumar Swaminathan } 580*82527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 581*82527734SSukumar Swaminathan /* 582*82527734SSukumar Swaminathan * Unload the firmware image from 583*82527734SSukumar Swaminathan * kernel memory 584*82527734SSukumar Swaminathan */ 585*82527734SSukumar Swaminathan emlxs_fw_unload(hba, fw); 586*82527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 587*82527734SSukumar Swaminathan 588*82527734SSukumar Swaminathan fw_check = 0; 589*82527734SSukumar Swaminathan 590*82527734SSukumar Swaminathan goto reset; 591*82527734SSukumar Swaminathan } 592*82527734SSukumar Swaminathan 593*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 594*82527734SSukumar Swaminathan "Firmware image unavailable."); 595*82527734SSukumar Swaminathan } else { 596*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 597*82527734SSukumar Swaminathan "Firmware update not needed."); 598*82527734SSukumar Swaminathan } 599*82527734SSukumar Swaminathan } else { 600*82527734SSukumar Swaminathan /* 601*82527734SSukumar Swaminathan * This means either the adapter database is not 602*82527734SSukumar Swaminathan * correct or a firmware image is missing from the 603*82527734SSukumar Swaminathan * compile 604*82527734SSukumar Swaminathan */ 605*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 606*82527734SSukumar Swaminathan "Firmware image unavailable. id=%d fw=%d", 607*82527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 608*82527734SSukumar Swaminathan } 609*82527734SSukumar Swaminathan } 610*82527734SSukumar Swaminathan 611*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 612*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 613*82527734SSukumar Swaminathan 614*82527734SSukumar Swaminathan emlxs_mb_dump_fcoe(hba, mbq, 0); 615*82527734SSukumar Swaminathan 616*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 617*82527734SSukumar Swaminathan MBX_SUCCESS) { 618*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 619*82527734SSukumar Swaminathan "No FCOE info found. status=%x", mb->mbxStatus); 620*82527734SSukumar Swaminathan } else { 621*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 622*82527734SSukumar Swaminathan &emlxs_init_debug_msg, 623*82527734SSukumar Swaminathan "FCOE info dumped. rsp_cnt=%d status=%x", 624*82527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 625*82527734SSukumar Swaminathan (void) emlxs_parse_fcoe(hba, 626*82527734SSukumar Swaminathan (uint8_t *)hba->sli.sli4.dump_region.virt, 0); 627*82527734SSukumar Swaminathan } 628*82527734SSukumar Swaminathan 629*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 630*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 631*82527734SSukumar Swaminathan 632*82527734SSukumar Swaminathan emlxs_mb_request_features(hba, mbq); 633*82527734SSukumar Swaminathan 634*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 635*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 636*82527734SSukumar Swaminathan "Unable to REQUEST_FEATURES. Mailbox cmd=%x status=%x", 637*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 638*82527734SSukumar Swaminathan 639*82527734SSukumar Swaminathan rval = EIO; 640*82527734SSukumar Swaminathan goto failed1; 641*82527734SSukumar Swaminathan } 642*82527734SSukumar Swaminathan emlxs_data_dump(hba, "REQ_FEATURE", (uint32_t *)mb, 6, 0); 643*82527734SSukumar Swaminathan 644*82527734SSukumar Swaminathan /* Make sure we get the features we requested */ 645*82527734SSukumar Swaminathan if (mb->un.varReqFeatures.featuresRequested != 646*82527734SSukumar Swaminathan mb->un.varReqFeatures.featuresEnabled) { 647*82527734SSukumar Swaminathan 648*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 649*82527734SSukumar Swaminathan "Unable to get REQUESTed_FEATURES. want:x%x got:x%x", 650*82527734SSukumar Swaminathan mb->un.varReqFeatures.featuresRequested, 651*82527734SSukumar Swaminathan mb->un.varReqFeatures.featuresEnabled); 652*82527734SSukumar Swaminathan 653*82527734SSukumar Swaminathan rval = EIO; 654*82527734SSukumar Swaminathan goto failed1; 655*82527734SSukumar Swaminathan } 656*82527734SSukumar Swaminathan 657*82527734SSukumar Swaminathan if (mb->un.varReqFeatures.featuresEnabled & SLI4_FEATURE_NPIV) { 658*82527734SSukumar Swaminathan hba->flag |= FC_NPIV_ENABLED; 659*82527734SSukumar Swaminathan } 660*82527734SSukumar Swaminathan 661*82527734SSukumar Swaminathan /* Check enable-npiv driver parameter for now */ 662*82527734SSukumar Swaminathan if (cfg[CFG_NPIV_ENABLE].current) { 663*82527734SSukumar Swaminathan hba->flag |= FC_NPIV_ENABLED; 664*82527734SSukumar Swaminathan } 665*82527734SSukumar Swaminathan 666*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 667*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 668*82527734SSukumar Swaminathan 669*82527734SSukumar Swaminathan emlxs_mb_read_config(hba, mbq); 670*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 671*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 672*82527734SSukumar Swaminathan "Unable to READ_CONFIG. Mailbox cmd=%x status=%x", 673*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 674*82527734SSukumar Swaminathan 675*82527734SSukumar Swaminathan rval = EIO; 676*82527734SSukumar Swaminathan goto failed1; 677*82527734SSukumar Swaminathan } 678*82527734SSukumar Swaminathan emlxs_data_dump(hba, "READ_CONFIG4", (uint32_t *)mb, 18, 0); 679*82527734SSukumar Swaminathan 680*82527734SSukumar Swaminathan hba->sli.sli4.XRICount = (mb->un.varRdConfig4.XRICount); 681*82527734SSukumar Swaminathan hba->sli.sli4.XRIBase = (mb->un.varRdConfig4.XRIBase); 682*82527734SSukumar Swaminathan hba->sli.sli4.RPICount = (mb->un.varRdConfig4.RPICount); 683*82527734SSukumar Swaminathan hba->sli.sli4.RPIBase = (mb->un.varRdConfig4.RPIBase); 684*82527734SSukumar Swaminathan hba->sli.sli4.VPICount = (mb->un.varRdConfig4.VPICount); 685*82527734SSukumar Swaminathan hba->sli.sli4.VPIBase = (mb->un.varRdConfig4.VPIBase); 686*82527734SSukumar Swaminathan hba->sli.sli4.VFICount = (mb->un.varRdConfig4.VFICount); 687*82527734SSukumar Swaminathan hba->sli.sli4.VFIBase = (mb->un.varRdConfig4.VFIBase); 688*82527734SSukumar Swaminathan hba->sli.sli4.FCFICount = (mb->un.varRdConfig4.FCFICount); 689*82527734SSukumar Swaminathan 690*82527734SSukumar Swaminathan if (hba->sli.sli4.VPICount) { 691*82527734SSukumar Swaminathan hba->vpi_max = min(hba->sli.sli4.VPICount, MAX_VPORTS) - 1; 692*82527734SSukumar Swaminathan } 693*82527734SSukumar Swaminathan hba->vpi_base = mb->un.varRdConfig4.VPIBase; 694*82527734SSukumar Swaminathan 695*82527734SSukumar Swaminathan /* Set the max node count */ 696*82527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 697*82527734SSukumar Swaminathan hba->max_nodes = 698*82527734SSukumar Swaminathan min(cfg[CFG_NUM_NODES].current, 699*82527734SSukumar Swaminathan hba->sli.sli4.RPICount); 700*82527734SSukumar Swaminathan } else { 701*82527734SSukumar Swaminathan hba->max_nodes = hba->sli.sli4.RPICount; 702*82527734SSukumar Swaminathan } 703*82527734SSukumar Swaminathan 704*82527734SSukumar Swaminathan /* Set the io throttle */ 705*82527734SSukumar Swaminathan hba->io_throttle = hba->sli.sli4.XRICount - IO_THROTTLE_RESERVE; 706*82527734SSukumar Swaminathan hba->max_iotag = hba->sli.sli4.XRICount; 707*82527734SSukumar Swaminathan 708*82527734SSukumar Swaminathan /* Save the link speed capabilities */ 709*82527734SSukumar Swaminathan vpd->link_speed = mb->un.varRdConfig4.lmt; 710*82527734SSukumar Swaminathan emlxs_process_link_speed(hba); 711*82527734SSukumar Swaminathan 712*82527734SSukumar Swaminathan /* 713*82527734SSukumar Swaminathan * Allocate some memory for buffers 714*82527734SSukumar Swaminathan */ 715*82527734SSukumar Swaminathan if (emlxs_mem_alloc_buffer(hba) == 0) { 716*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 717*82527734SSukumar Swaminathan "Unable to allocate memory buffers."); 718*82527734SSukumar Swaminathan 719*82527734SSukumar Swaminathan rval = ENOMEM; 720*82527734SSukumar Swaminathan goto failed1; 721*82527734SSukumar Swaminathan } 722*82527734SSukumar Swaminathan 723*82527734SSukumar Swaminathan /* 724*82527734SSukumar Swaminathan * OutOfRange (oor) iotags are used for abort or close 725*82527734SSukumar Swaminathan * XRI commands or any WQE that does not require a SGL 726*82527734SSukumar Swaminathan */ 727*82527734SSukumar Swaminathan hba->fc_oor_iotag = hba->max_iotag; 728*82527734SSukumar Swaminathan 729*82527734SSukumar Swaminathan if (emlxs_sli4_resource_alloc(hba)) { 730*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 731*82527734SSukumar Swaminathan "Unable to allocate resources."); 732*82527734SSukumar Swaminathan 733*82527734SSukumar Swaminathan rval = ENOMEM; 734*82527734SSukumar Swaminathan goto failed2; 735*82527734SSukumar Swaminathan } 736*82527734SSukumar Swaminathan emlxs_data_dump(hba, "XRIp", (uint32_t *)hba->sli.sli4.XRIp, 18, 0); 737*82527734SSukumar Swaminathan 738*82527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV5) 739*82527734SSukumar Swaminathan if ((cfg[CFG_NPIV_ENABLE].current) && (hba->flag & FC_NPIV_ENABLED)) { 740*82527734SSukumar Swaminathan hba->fca_tran->fca_num_npivports = hba->vpi_max; 741*82527734SSukumar Swaminathan } 742*82527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV5 */ 743*82527734SSukumar Swaminathan 744*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 745*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 746*82527734SSukumar Swaminathan 747*82527734SSukumar Swaminathan if (emlxs_sli4_post_sgl_pages(hba, mbq)) { 748*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 749*82527734SSukumar Swaminathan "Unable to post sgl pages."); 750*82527734SSukumar Swaminathan 751*82527734SSukumar Swaminathan rval = EIO; 752*82527734SSukumar Swaminathan goto failed3; 753*82527734SSukumar Swaminathan } 754*82527734SSukumar Swaminathan 755*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 756*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 757*82527734SSukumar Swaminathan 758*82527734SSukumar Swaminathan if (emlxs_sli4_post_hdr_tmplates(hba, mbq)) { 759*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 760*82527734SSukumar Swaminathan "Unable to post header templates."); 761*82527734SSukumar Swaminathan 762*82527734SSukumar Swaminathan rval = EIO; 763*82527734SSukumar Swaminathan goto failed3; 764*82527734SSukumar Swaminathan } 765*82527734SSukumar Swaminathan 766*82527734SSukumar Swaminathan /* 767*82527734SSukumar Swaminathan * Add our interrupt routine to kernel's interrupt chain & enable it 768*82527734SSukumar Swaminathan * If MSI is enabled this will cause Solaris to program the MSI address 769*82527734SSukumar Swaminathan * and data registers in PCI config space 770*82527734SSukumar Swaminathan */ 771*82527734SSukumar Swaminathan if (EMLXS_INTR_ADD(hba) != DDI_SUCCESS) { 772*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 773*82527734SSukumar Swaminathan "Unable to add interrupt(s)."); 774*82527734SSukumar Swaminathan 775*82527734SSukumar Swaminathan rval = EIO; 776*82527734SSukumar Swaminathan goto failed3; 777*82527734SSukumar Swaminathan } 778*82527734SSukumar Swaminathan 779*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 780*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 781*82527734SSukumar Swaminathan 782*82527734SSukumar Swaminathan /* This MUST be done after EMLXS_INTR_ADD */ 783*82527734SSukumar Swaminathan if (emlxs_sli4_create_queues(hba, mbq)) { 784*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 785*82527734SSukumar Swaminathan "Unable to create queues."); 786*82527734SSukumar Swaminathan 787*82527734SSukumar Swaminathan rval = EIO; 788*82527734SSukumar Swaminathan goto failed3; 789*82527734SSukumar Swaminathan } 790*82527734SSukumar Swaminathan 791*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_CFGPORT); 792*82527734SSukumar Swaminathan 793*82527734SSukumar Swaminathan /* Get and save the current firmware version (based on sli_mode) */ 794*82527734SSukumar Swaminathan emlxs_decode_firmware_rev(hba, vpd); 795*82527734SSukumar Swaminathan 796*82527734SSukumar Swaminathan /* 797*82527734SSukumar Swaminathan * Setup and issue mailbox RUN BIU DIAG command Setup test buffers 798*82527734SSukumar Swaminathan */ 799*82527734SSukumar Swaminathan if (((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) || 800*82527734SSukumar Swaminathan ((mp1 = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0)) { 801*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 802*82527734SSukumar Swaminathan "Unable to allocate diag buffers."); 803*82527734SSukumar Swaminathan 804*82527734SSukumar Swaminathan rval = ENOMEM; 805*82527734SSukumar Swaminathan goto failed3; 806*82527734SSukumar Swaminathan } 807*82527734SSukumar Swaminathan 808*82527734SSukumar Swaminathan bcopy((caddr_t)&emlxs_diag_pattern[0], (caddr_t)mp->virt, 809*82527734SSukumar Swaminathan MEM_ELSBUF_SIZE); 810*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, MEM_ELSBUF_SIZE, 811*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 812*82527734SSukumar Swaminathan 813*82527734SSukumar Swaminathan bzero(mp1->virt, MEM_ELSBUF_SIZE); 814*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp1->dma_handle, 0, MEM_ELSBUF_SIZE, 815*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 816*82527734SSukumar Swaminathan 817*82527734SSukumar Swaminathan 818*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 819*82527734SSukumar Swaminathan mp = NULL; 820*82527734SSukumar Swaminathan 821*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_INITLINK); 822*82527734SSukumar Swaminathan 823*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 824*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 825*82527734SSukumar Swaminathan 826*82527734SSukumar Swaminathan /* 827*82527734SSukumar Swaminathan * We need to get login parameters for NID 828*82527734SSukumar Swaminathan */ 829*82527734SSukumar Swaminathan (void) emlxs_mb_read_sparam(hba, mbq); 830*82527734SSukumar Swaminathan mp = (MATCHMAP *)(mbq->bp); 831*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 832*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 833*82527734SSukumar Swaminathan "Unable to read parameters. Mailbox cmd=%x status=%x", 834*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 835*82527734SSukumar Swaminathan 836*82527734SSukumar Swaminathan rval = EIO; 837*82527734SSukumar Swaminathan goto failed3; 838*82527734SSukumar Swaminathan } 839*82527734SSukumar Swaminathan 840*82527734SSukumar Swaminathan /* Free the buffer since we were polling */ 841*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 842*82527734SSukumar Swaminathan mp = NULL; 843*82527734SSukumar Swaminathan 844*82527734SSukumar Swaminathan /* If no serial number in VPD data, then use the WWPN */ 845*82527734SSukumar Swaminathan if (vpd->serial_num[0] == 0) { 846*82527734SSukumar Swaminathan outptr = (uint8_t *)&hba->wwpn.IEEE[0]; 847*82527734SSukumar Swaminathan for (i = 0; i < 12; i++) { 848*82527734SSukumar Swaminathan status = *outptr++; 849*82527734SSukumar Swaminathan j = ((status & 0xf0) >> 4); 850*82527734SSukumar Swaminathan if (j <= 9) { 851*82527734SSukumar Swaminathan vpd->serial_num[i] = 852*82527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 853*82527734SSukumar Swaminathan } else { 854*82527734SSukumar Swaminathan vpd->serial_num[i] = 855*82527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 856*82527734SSukumar Swaminathan } 857*82527734SSukumar Swaminathan 858*82527734SSukumar Swaminathan i++; 859*82527734SSukumar Swaminathan j = (status & 0xf); 860*82527734SSukumar Swaminathan if (j <= 9) { 861*82527734SSukumar Swaminathan vpd->serial_num[i] = 862*82527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 863*82527734SSukumar Swaminathan } else { 864*82527734SSukumar Swaminathan vpd->serial_num[i] = 865*82527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 866*82527734SSukumar Swaminathan } 867*82527734SSukumar Swaminathan } 868*82527734SSukumar Swaminathan 869*82527734SSukumar Swaminathan /* 870*82527734SSukumar Swaminathan * Set port number and port index to zero 871*82527734SSukumar Swaminathan * The WWN's are unique to each port and therefore port_num 872*82527734SSukumar Swaminathan * must equal zero. This effects the hba_fru_details structure 873*82527734SSukumar Swaminathan * in fca_bind_port() 874*82527734SSukumar Swaminathan */ 875*82527734SSukumar Swaminathan vpd->port_num[0] = 0; 876*82527734SSukumar Swaminathan vpd->port_index = 0; 877*82527734SSukumar Swaminathan } 878*82527734SSukumar Swaminathan 879*82527734SSukumar Swaminathan /* Make attempt to set a port index */ 880*82527734SSukumar Swaminathan if (vpd->port_index == -1) { 881*82527734SSukumar Swaminathan dev_info_t *p_dip; 882*82527734SSukumar Swaminathan dev_info_t *c_dip; 883*82527734SSukumar Swaminathan 884*82527734SSukumar Swaminathan p_dip = ddi_get_parent(hba->dip); 885*82527734SSukumar Swaminathan c_dip = ddi_get_child(p_dip); 886*82527734SSukumar Swaminathan 887*82527734SSukumar Swaminathan vpd->port_index = 0; 888*82527734SSukumar Swaminathan while (c_dip && (hba->dip != c_dip)) { 889*82527734SSukumar Swaminathan c_dip = ddi_get_next_sibling(c_dip); 890*82527734SSukumar Swaminathan 891*82527734SSukumar Swaminathan if (strcmp(ddi_get_name(c_dip), "ethernet")) { 892*82527734SSukumar Swaminathan vpd->port_index++; 893*82527734SSukumar Swaminathan } 894*82527734SSukumar Swaminathan } 895*82527734SSukumar Swaminathan } 896*82527734SSukumar Swaminathan 897*82527734SSukumar Swaminathan if (vpd->port_num[0] == 0) { 898*82527734SSukumar Swaminathan if (hba->model_info.channels > 1) { 899*82527734SSukumar Swaminathan (void) sprintf(vpd->port_num, "%d", vpd->port_index); 900*82527734SSukumar Swaminathan } 901*82527734SSukumar Swaminathan } 902*82527734SSukumar Swaminathan 903*82527734SSukumar Swaminathan if (vpd->id[0] == 0) { 904*82527734SSukumar Swaminathan (void) sprintf(vpd->id, "%s %d", 905*82527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 906*82527734SSukumar Swaminathan 907*82527734SSukumar Swaminathan } 908*82527734SSukumar Swaminathan 909*82527734SSukumar Swaminathan if (vpd->manufacturer[0] == 0) { 910*82527734SSukumar Swaminathan (void) strcpy(vpd->manufacturer, hba->model_info.manufacturer); 911*82527734SSukumar Swaminathan } 912*82527734SSukumar Swaminathan 913*82527734SSukumar Swaminathan if (vpd->part_num[0] == 0) { 914*82527734SSukumar Swaminathan (void) strcpy(vpd->part_num, hba->model_info.model); 915*82527734SSukumar Swaminathan } 916*82527734SSukumar Swaminathan 917*82527734SSukumar Swaminathan if (vpd->model_desc[0] == 0) { 918*82527734SSukumar Swaminathan (void) sprintf(vpd->model_desc, "%s %d", 919*82527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 920*82527734SSukumar Swaminathan } 921*82527734SSukumar Swaminathan 922*82527734SSukumar Swaminathan if (vpd->model[0] == 0) { 923*82527734SSukumar Swaminathan (void) strcpy(vpd->model, hba->model_info.model); 924*82527734SSukumar Swaminathan } 925*82527734SSukumar Swaminathan 926*82527734SSukumar Swaminathan if (vpd->prog_types[0] == 0) { 927*82527734SSukumar Swaminathan emlxs_build_prog_types(hba, vpd->prog_types); 928*82527734SSukumar Swaminathan } 929*82527734SSukumar Swaminathan 930*82527734SSukumar Swaminathan /* Create the symbolic names */ 931*82527734SSukumar Swaminathan (void) sprintf(hba->snn, "Emulex %s FV%s DV%s %s", 932*82527734SSukumar Swaminathan hba->model_info.model, hba->vpd.fw_version, emlxs_version, 933*82527734SSukumar Swaminathan (char *)utsname.nodename); 934*82527734SSukumar Swaminathan 935*82527734SSukumar Swaminathan (void) sprintf(hba->spn, 936*82527734SSukumar Swaminathan "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 937*82527734SSukumar Swaminathan hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb, 938*82527734SSukumar Swaminathan hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2], 939*82527734SSukumar Swaminathan hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]); 940*82527734SSukumar Swaminathan 941*82527734SSukumar Swaminathan 942*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN); 943*82527734SSukumar Swaminathan emlxs_sli4_enable_intr(hba); 944*82527734SSukumar Swaminathan 945*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 946*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 947*82527734SSukumar Swaminathan 948*82527734SSukumar Swaminathan /* 949*82527734SSukumar Swaminathan * Setup and issue mailbox INITIALIZE LINK command 950*82527734SSukumar Swaminathan * At this point, the interrupt will be generated by the HW 951*82527734SSukumar Swaminathan * Do this only if persist-linkdown is not set 952*82527734SSukumar Swaminathan */ 953*82527734SSukumar Swaminathan if (cfg[CFG_PERSIST_LINKDOWN].current == 0) { 954*82527734SSukumar Swaminathan emlxs_mb_init_link(hba, mbq, 955*82527734SSukumar Swaminathan cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current); 956*82527734SSukumar Swaminathan 957*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) 958*82527734SSukumar Swaminathan != MBX_SUCCESS) { 959*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 960*82527734SSukumar Swaminathan "Unable to initialize link. " \ 961*82527734SSukumar Swaminathan "Mailbox cmd=%x status=%x", 962*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 963*82527734SSukumar Swaminathan 964*82527734SSukumar Swaminathan rval = EIO; 965*82527734SSukumar Swaminathan goto failed3; 966*82527734SSukumar Swaminathan } 967*82527734SSukumar Swaminathan 968*82527734SSukumar Swaminathan /* Wait for link to come up */ 969*82527734SSukumar Swaminathan i = cfg[CFG_LINKUP_DELAY].current; 970*82527734SSukumar Swaminathan while (i && (hba->state < FC_LINK_UP)) { 971*82527734SSukumar Swaminathan /* Check for hardware error */ 972*82527734SSukumar Swaminathan if (hba->state == FC_ERROR) { 973*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 974*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 975*82527734SSukumar Swaminathan "Adapter error.", mb->mbxCommand, 976*82527734SSukumar Swaminathan mb->mbxStatus); 977*82527734SSukumar Swaminathan 978*82527734SSukumar Swaminathan rval = EIO; 979*82527734SSukumar Swaminathan goto failed3; 980*82527734SSukumar Swaminathan } 981*82527734SSukumar Swaminathan 982*82527734SSukumar Swaminathan DELAYMS(1000); 983*82527734SSukumar Swaminathan i--; 984*82527734SSukumar Swaminathan } 985*82527734SSukumar Swaminathan } 986*82527734SSukumar Swaminathan 987*82527734SSukumar Swaminathan /* 988*82527734SSukumar Swaminathan * The leadvile driver will now handle the FLOGI at the driver level 989*82527734SSukumar Swaminathan */ 990*82527734SSukumar Swaminathan 991*82527734SSukumar Swaminathan return (0); 992*82527734SSukumar Swaminathan 993*82527734SSukumar Swaminathan failed3: 994*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 995*82527734SSukumar Swaminathan 996*82527734SSukumar Swaminathan if (mp) { 997*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp); 998*82527734SSukumar Swaminathan mp = NULL; 999*82527734SSukumar Swaminathan } 1000*82527734SSukumar Swaminathan 1001*82527734SSukumar Swaminathan if (mp1) { 1002*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mp1); 1003*82527734SSukumar Swaminathan mp1 = NULL; 1004*82527734SSukumar Swaminathan } 1005*82527734SSukumar Swaminathan 1006*82527734SSukumar Swaminathan if (hba->intr_flags & EMLXS_MSI_ADDED) { 1007*82527734SSukumar Swaminathan (void) EMLXS_INTR_REMOVE(hba); 1008*82527734SSukumar Swaminathan } 1009*82527734SSukumar Swaminathan 1010*82527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 1011*82527734SSukumar Swaminathan 1012*82527734SSukumar Swaminathan failed2: 1013*82527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 1014*82527734SSukumar Swaminathan 1015*82527734SSukumar Swaminathan failed1: 1016*82527734SSukumar Swaminathan if (mbq) { 1017*82527734SSukumar Swaminathan (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ)); 1018*82527734SSukumar Swaminathan mbq = NULL; 1019*82527734SSukumar Swaminathan mb = NULL; 1020*82527734SSukumar Swaminathan } 1021*82527734SSukumar Swaminathan 1022*82527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt) { 1023*82527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 1024*82527734SSukumar Swaminathan } 1025*82527734SSukumar Swaminathan 1026*82527734SSukumar Swaminathan if (rval == 0) { 1027*82527734SSukumar Swaminathan rval = EIO; 1028*82527734SSukumar Swaminathan } 1029*82527734SSukumar Swaminathan 1030*82527734SSukumar Swaminathan return (rval); 1031*82527734SSukumar Swaminathan 1032*82527734SSukumar Swaminathan } /* emlxs_sli4_online() */ 1033*82527734SSukumar Swaminathan 1034*82527734SSukumar Swaminathan 1035*82527734SSukumar Swaminathan static void 1036*82527734SSukumar Swaminathan emlxs_sli4_offline(emlxs_hba_t *hba) 1037*82527734SSukumar Swaminathan { 1038*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1039*82527734SSukumar Swaminathan MAILBOXQ mboxq; 1040*82527734SSukumar Swaminathan 1041*82527734SSukumar Swaminathan /* Reverse emlxs_sli4_online */ 1042*82527734SSukumar Swaminathan 1043*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 1044*82527734SSukumar Swaminathan if (!(hba->flag & FC_INTERLOCKED)) { 1045*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 1046*82527734SSukumar Swaminathan 1047*82527734SSukumar Swaminathan /* This is the only way to disable interupts */ 1048*82527734SSukumar Swaminathan bzero((void *)&mboxq, sizeof (MAILBOXQ)); 1049*82527734SSukumar Swaminathan emlxs_mb_resetport(hba, &mboxq); 1050*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, &mboxq, 1051*82527734SSukumar Swaminathan MBX_WAIT, 0) != MBX_SUCCESS) { 1052*82527734SSukumar Swaminathan /* Timeout occurred */ 1053*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1054*82527734SSukumar Swaminathan "Timeout: Offline RESET"); 1055*82527734SSukumar Swaminathan } 1056*82527734SSukumar Swaminathan (void) emlxs_check_hdw_ready(hba); 1057*82527734SSukumar Swaminathan } else { 1058*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 1059*82527734SSukumar Swaminathan } 1060*82527734SSukumar Swaminathan 1061*82527734SSukumar Swaminathan 1062*82527734SSukumar Swaminathan /* Shutdown the adapter interface */ 1063*82527734SSukumar Swaminathan emlxs_sli4_hba_kill(hba); 1064*82527734SSukumar Swaminathan 1065*82527734SSukumar Swaminathan /* Free SLI shared memory */ 1066*82527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 1067*82527734SSukumar Swaminathan 1068*82527734SSukumar Swaminathan /* Free driver shared memory */ 1069*82527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 1070*82527734SSukumar Swaminathan 1071*82527734SSukumar Swaminathan /* Free the host dump region buffer */ 1072*82527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 1073*82527734SSukumar Swaminathan 1074*82527734SSukumar Swaminathan } /* emlxs_sli4_offline() */ 1075*82527734SSukumar Swaminathan 1076*82527734SSukumar Swaminathan 1077*82527734SSukumar Swaminathan /*ARGSUSED*/ 1078*82527734SSukumar Swaminathan static int 1079*82527734SSukumar Swaminathan emlxs_sli4_map_hdw(emlxs_hba_t *hba) 1080*82527734SSukumar Swaminathan { 1081*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1082*82527734SSukumar Swaminathan dev_info_t *dip; 1083*82527734SSukumar Swaminathan ddi_device_acc_attr_t dev_attr; 1084*82527734SSukumar Swaminathan int status; 1085*82527734SSukumar Swaminathan 1086*82527734SSukumar Swaminathan dip = (dev_info_t *)hba->dip; 1087*82527734SSukumar Swaminathan dev_attr = emlxs_dev_acc_attr; 1088*82527734SSukumar Swaminathan 1089*82527734SSukumar Swaminathan /* 1090*82527734SSukumar Swaminathan * Map in Hardware BAR pages that will be used for 1091*82527734SSukumar Swaminathan * communication with HBA. 1092*82527734SSukumar Swaminathan */ 1093*82527734SSukumar Swaminathan if (hba->sli.sli4.bar1_acc_handle == 0) { 1094*82527734SSukumar Swaminathan status = ddi_regs_map_setup(dip, PCI_BAR1_RINDEX, 1095*82527734SSukumar Swaminathan (caddr_t *)&hba->sli.sli4.bar1_addr, 1096*82527734SSukumar Swaminathan 0, 0, &dev_attr, &hba->sli.sli4.bar1_acc_handle); 1097*82527734SSukumar Swaminathan if (status != DDI_SUCCESS) { 1098*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1099*82527734SSukumar Swaminathan &emlxs_attach_failed_msg, 1100*82527734SSukumar Swaminathan "(PCI) ddi_regs_map_setup BAR1 failed. " 1101*82527734SSukumar Swaminathan "stat=%d mem=%p attr=%p hdl=%p", 1102*82527734SSukumar Swaminathan status, &hba->sli.sli4.bar1_addr, &dev_attr, 1103*82527734SSukumar Swaminathan &hba->sli.sli4.bar1_acc_handle); 1104*82527734SSukumar Swaminathan goto failed; 1105*82527734SSukumar Swaminathan } 1106*82527734SSukumar Swaminathan } 1107*82527734SSukumar Swaminathan 1108*82527734SSukumar Swaminathan if (hba->sli.sli4.bar2_acc_handle == 0) { 1109*82527734SSukumar Swaminathan status = ddi_regs_map_setup(dip, PCI_BAR2_RINDEX, 1110*82527734SSukumar Swaminathan (caddr_t *)&hba->sli.sli4.bar2_addr, 1111*82527734SSukumar Swaminathan 0, 0, &dev_attr, &hba->sli.sli4.bar2_acc_handle); 1112*82527734SSukumar Swaminathan if (status != DDI_SUCCESS) { 1113*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 1114*82527734SSukumar Swaminathan &emlxs_attach_failed_msg, 1115*82527734SSukumar Swaminathan "ddi_regs_map_setup BAR2 failed. status=%x", 1116*82527734SSukumar Swaminathan status); 1117*82527734SSukumar Swaminathan goto failed; 1118*82527734SSukumar Swaminathan } 1119*82527734SSukumar Swaminathan } 1120*82527734SSukumar Swaminathan 1121*82527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt == 0) { 1122*82527734SSukumar Swaminathan MBUF_INFO *buf_info; 1123*82527734SSukumar Swaminathan MBUF_INFO bufinfo; 1124*82527734SSukumar Swaminathan 1125*82527734SSukumar Swaminathan buf_info = &bufinfo; 1126*82527734SSukumar Swaminathan 1127*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 1128*82527734SSukumar Swaminathan buf_info->size = EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE; 1129*82527734SSukumar Swaminathan buf_info->flags = 1130*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 1131*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(dip, 1L); 1132*82527734SSukumar Swaminathan 1133*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 1134*82527734SSukumar Swaminathan 1135*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 1136*82527734SSukumar Swaminathan goto failed; 1137*82527734SSukumar Swaminathan } 1138*82527734SSukumar Swaminathan 1139*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.virt = (uint8_t *)buf_info->virt; 1140*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.phys = buf_info->phys; 1141*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.size = EMLXS_BOOTSTRAP_MB_SIZE + 1142*82527734SSukumar Swaminathan MBOX_EXTENSION_SIZE; 1143*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle = buf_info->data_handle; 1144*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle = buf_info->dma_handle; 1145*82527734SSukumar Swaminathan bzero((char *)hba->sli.sli4.bootstrapmb.virt, 1146*82527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE); 1147*82527734SSukumar Swaminathan } 1148*82527734SSukumar Swaminathan 1149*82527734SSukumar Swaminathan /* offset from beginning of register space */ 1150*82527734SSukumar Swaminathan hba->sli.sli4.MPUEPSemaphore_reg_addr = 1151*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar1_addr + CSR_MPU_EP_SEMAPHORE_OFFSET); 1152*82527734SSukumar Swaminathan hba->sli.sli4.MBDB_reg_addr = 1153*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MB_DB_OFFSET); 1154*82527734SSukumar Swaminathan hba->sli.sli4.CQDB_reg_addr = 1155*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_CQ_DB_OFFSET); 1156*82527734SSukumar Swaminathan hba->sli.sli4.MQDB_reg_addr = 1157*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MQ_DB_OFFSET); 1158*82527734SSukumar Swaminathan hba->sli.sli4.WQDB_reg_addr = 1159*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_WQ_DB_OFFSET); 1160*82527734SSukumar Swaminathan hba->sli.sli4.RQDB_reg_addr = 1161*82527734SSukumar Swaminathan (uint32_t *)(hba->sli.sli4.bar2_addr + PD_RQ_DB_OFFSET); 1162*82527734SSukumar Swaminathan hba->chan_count = MAX_CHANNEL; 1163*82527734SSukumar Swaminathan 1164*82527734SSukumar Swaminathan return (0); 1165*82527734SSukumar Swaminathan 1166*82527734SSukumar Swaminathan failed: 1167*82527734SSukumar Swaminathan 1168*82527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(hba); 1169*82527734SSukumar Swaminathan return (ENOMEM); 1170*82527734SSukumar Swaminathan 1171*82527734SSukumar Swaminathan 1172*82527734SSukumar Swaminathan } /* emlxs_sli4_map_hdw() */ 1173*82527734SSukumar Swaminathan 1174*82527734SSukumar Swaminathan 1175*82527734SSukumar Swaminathan /*ARGSUSED*/ 1176*82527734SSukumar Swaminathan static void 1177*82527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(emlxs_hba_t *hba) 1178*82527734SSukumar Swaminathan { 1179*82527734SSukumar Swaminathan MBUF_INFO bufinfo; 1180*82527734SSukumar Swaminathan MBUF_INFO *buf_info = &bufinfo; 1181*82527734SSukumar Swaminathan 1182*82527734SSukumar Swaminathan /* 1183*82527734SSukumar Swaminathan * Free map for Hardware BAR pages that were used for 1184*82527734SSukumar Swaminathan * communication with HBA. 1185*82527734SSukumar Swaminathan */ 1186*82527734SSukumar Swaminathan if (hba->sli.sli4.bar1_acc_handle) { 1187*82527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar1_acc_handle); 1188*82527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle = 0; 1189*82527734SSukumar Swaminathan } 1190*82527734SSukumar Swaminathan 1191*82527734SSukumar Swaminathan if (hba->sli.sli4.bar2_acc_handle) { 1192*82527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar2_acc_handle); 1193*82527734SSukumar Swaminathan hba->sli.sli4.bar2_acc_handle = 0; 1194*82527734SSukumar Swaminathan } 1195*82527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt) { 1196*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 1197*82527734SSukumar Swaminathan 1198*82527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.phys) { 1199*82527734SSukumar Swaminathan buf_info->phys = hba->sli.sli4.bootstrapmb.phys; 1200*82527734SSukumar Swaminathan buf_info->data_handle = 1201*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle; 1202*82527734SSukumar Swaminathan buf_info->dma_handle = 1203*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle; 1204*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 1205*82527734SSukumar Swaminathan } 1206*82527734SSukumar Swaminathan 1207*82527734SSukumar Swaminathan buf_info->virt = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 1208*82527734SSukumar Swaminathan buf_info->size = hba->sli.sli4.bootstrapmb.size; 1209*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 1210*82527734SSukumar Swaminathan 1211*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.virt = 0; 1212*82527734SSukumar Swaminathan } 1213*82527734SSukumar Swaminathan 1214*82527734SSukumar Swaminathan return; 1215*82527734SSukumar Swaminathan 1216*82527734SSukumar Swaminathan } /* emlxs_sli4_unmap_hdw() */ 1217*82527734SSukumar Swaminathan 1218*82527734SSukumar Swaminathan 1219*82527734SSukumar Swaminathan static int 1220*82527734SSukumar Swaminathan emlxs_check_hdw_ready(emlxs_hba_t *hba) 1221*82527734SSukumar Swaminathan { 1222*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1223*82527734SSukumar Swaminathan uint32_t status; 1224*82527734SSukumar Swaminathan uint32_t i = 0; 1225*82527734SSukumar Swaminathan 1226*82527734SSukumar Swaminathan /* Wait for reset completion */ 1227*82527734SSukumar Swaminathan while (i < 30) { 1228*82527734SSukumar Swaminathan /* Check Semaphore register to see what the ARM state is */ 1229*82527734SSukumar Swaminathan status = READ_BAR1_REG(hba, FC_SEMA_REG(hba)); 1230*82527734SSukumar Swaminathan 1231*82527734SSukumar Swaminathan /* Check to see if any errors occurred during init */ 1232*82527734SSukumar Swaminathan if (status & ARM_POST_FATAL) { 1233*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1234*82527734SSukumar Swaminathan "SEMA Error: status=0x%x", status); 1235*82527734SSukumar Swaminathan 1236*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1237*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1238*82527734SSukumar Swaminathan /* Access handle validation */ 1239*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 1240*82527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle); 1241*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1242*82527734SSukumar Swaminathan return (1); 1243*82527734SSukumar Swaminathan } 1244*82527734SSukumar Swaminathan if ((status & ARM_POST_MASK) == ARM_POST_READY) { 1245*82527734SSukumar Swaminathan /* ARM Ready !! */ 1246*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 1247*82527734SSukumar Swaminathan "ARM Ready: status=0x%x", status); 1248*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1249*82527734SSukumar Swaminathan /* Access handle validation */ 1250*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 1251*82527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle); 1252*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1253*82527734SSukumar Swaminathan return (0); 1254*82527734SSukumar Swaminathan } 1255*82527734SSukumar Swaminathan 1256*82527734SSukumar Swaminathan DELAYMS(1000); 1257*82527734SSukumar Swaminathan i++; 1258*82527734SSukumar Swaminathan } 1259*82527734SSukumar Swaminathan 1260*82527734SSukumar Swaminathan /* Timeout occurred */ 1261*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1262*82527734SSukumar Swaminathan "Timeout waiting for READY: status=0x%x", status); 1263*82527734SSukumar Swaminathan 1264*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1265*82527734SSukumar Swaminathan 1266*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1267*82527734SSukumar Swaminathan /* Access handle validation */ 1268*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar1_acc_handle); 1269*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1270*82527734SSukumar Swaminathan 1271*82527734SSukumar Swaminathan /* Log a dump event - not supported */ 1272*82527734SSukumar Swaminathan 1273*82527734SSukumar Swaminathan return (2); 1274*82527734SSukumar Swaminathan 1275*82527734SSukumar Swaminathan } /* emlxs_check_hdw_ready() */ 1276*82527734SSukumar Swaminathan 1277*82527734SSukumar Swaminathan 1278*82527734SSukumar Swaminathan static uint32_t 1279*82527734SSukumar Swaminathan emlxs_check_bootstrap_ready(emlxs_hba_t *hba, uint32_t tmo) 1280*82527734SSukumar Swaminathan { 1281*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1282*82527734SSukumar Swaminathan uint32_t status; 1283*82527734SSukumar Swaminathan 1284*82527734SSukumar Swaminathan /* Wait for reset completion, tmo is in 10ms ticks */ 1285*82527734SSukumar Swaminathan while (tmo) { 1286*82527734SSukumar Swaminathan /* Check Semaphore register to see what the ARM state is */ 1287*82527734SSukumar Swaminathan status = READ_BAR2_REG(hba, FC_MBDB_REG(hba)); 1288*82527734SSukumar Swaminathan 1289*82527734SSukumar Swaminathan /* Check to see if any errors occurred during init */ 1290*82527734SSukumar Swaminathan if (status & BMBX_READY) { 1291*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 1292*82527734SSukumar Swaminathan "BMBX Ready: status=0x%x", status); 1293*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1294*82527734SSukumar Swaminathan /* Access handle validation */ 1295*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, 1296*82527734SSukumar Swaminathan hba->sli.sli4.bar2_acc_handle); 1297*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1298*82527734SSukumar Swaminathan return (tmo); 1299*82527734SSukumar Swaminathan } 1300*82527734SSukumar Swaminathan 1301*82527734SSukumar Swaminathan DELAYMS(10); 1302*82527734SSukumar Swaminathan tmo--; 1303*82527734SSukumar Swaminathan } 1304*82527734SSukumar Swaminathan 1305*82527734SSukumar Swaminathan /* Timeout occurred */ 1306*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1307*82527734SSukumar Swaminathan "Timeout waiting for BMailbox: status=0x%x", status); 1308*82527734SSukumar Swaminathan 1309*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1310*82527734SSukumar Swaminathan 1311*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1312*82527734SSukumar Swaminathan /* Access handle validation */ 1313*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar2_acc_handle); 1314*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1315*82527734SSukumar Swaminathan 1316*82527734SSukumar Swaminathan /* Log a dump event - not supported */ 1317*82527734SSukumar Swaminathan 1318*82527734SSukumar Swaminathan return (0); 1319*82527734SSukumar Swaminathan 1320*82527734SSukumar Swaminathan } /* emlxs_check_bootstrap_ready() */ 1321*82527734SSukumar Swaminathan 1322*82527734SSukumar Swaminathan 1323*82527734SSukumar Swaminathan static uint32_t 1324*82527734SSukumar Swaminathan emlxs_issue_bootstrap_mb(emlxs_hba_t *hba, uint32_t tmo) 1325*82527734SSukumar Swaminathan { 1326*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1327*82527734SSukumar Swaminathan uint32_t *iptr; 1328*82527734SSukumar Swaminathan uint32_t addr30; 1329*82527734SSukumar Swaminathan 1330*82527734SSukumar Swaminathan /* 1331*82527734SSukumar Swaminathan * This routine assumes the bootstrap mbox is loaded 1332*82527734SSukumar Swaminathan * with the mailbox command to be executed. 1333*82527734SSukumar Swaminathan * 1334*82527734SSukumar Swaminathan * First, load the high 30 bits of bootstrap mailbox 1335*82527734SSukumar Swaminathan */ 1336*82527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>32) & 0xfffffffc); 1337*82527734SSukumar Swaminathan addr30 |= BMBX_ADDR_HI; 1338*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MBDB_REG(hba), addr30); 1339*82527734SSukumar Swaminathan 1340*82527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 1341*82527734SSukumar Swaminathan if (tmo == 0) { 1342*82527734SSukumar Swaminathan return (0); 1343*82527734SSukumar Swaminathan } 1344*82527734SSukumar Swaminathan 1345*82527734SSukumar Swaminathan /* Load the low 30 bits of bootstrap mailbox */ 1346*82527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>2) & 0xfffffffc); 1347*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MBDB_REG(hba), addr30); 1348*82527734SSukumar Swaminathan 1349*82527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 1350*82527734SSukumar Swaminathan if (tmo == 0) { 1351*82527734SSukumar Swaminathan return (0); 1352*82527734SSukumar Swaminathan } 1353*82527734SSukumar Swaminathan 1354*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 1355*82527734SSukumar Swaminathan 1356*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_adapter_trans_msg, 1357*82527734SSukumar Swaminathan "BootstrapMB: %p Completed %08x %08x %08x", 1358*82527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.virt, 1359*82527734SSukumar Swaminathan *iptr, *(iptr+1), *(iptr+2)); 1360*82527734SSukumar Swaminathan 1361*82527734SSukumar Swaminathan return (tmo); 1362*82527734SSukumar Swaminathan 1363*82527734SSukumar Swaminathan } /* emlxs_issue_bootstrap_mb() */ 1364*82527734SSukumar Swaminathan 1365*82527734SSukumar Swaminathan 1366*82527734SSukumar Swaminathan static int 1367*82527734SSukumar Swaminathan emlxs_init_bootstrap_mb(emlxs_hba_t *hba) 1368*82527734SSukumar Swaminathan { 1369*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1370*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1371*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1372*82527734SSukumar Swaminathan uint32_t *iptr; 1373*82527734SSukumar Swaminathan uint32_t tmo; 1374*82527734SSukumar Swaminathan 1375*82527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 1376*82527734SSukumar Swaminathan return (1); 1377*82527734SSukumar Swaminathan } 1378*82527734SSukumar Swaminathan 1379*82527734SSukumar Swaminathan if (hba->flag & FC_BOOTSTRAPMB_INIT) { 1380*82527734SSukumar Swaminathan return (0); /* Already initialized */ 1381*82527734SSukumar Swaminathan } 1382*82527734SSukumar Swaminathan 1383*82527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 1384*82527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, 3000); 1385*82527734SSukumar Swaminathan if (tmo == 0) { 1386*82527734SSukumar Swaminathan return (1); 1387*82527734SSukumar Swaminathan } 1388*82527734SSukumar Swaminathan 1389*82527734SSukumar Swaminathan /* Special words to initialize bootstrap mbox MUST be little endian */ 1390*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 1391*82527734SSukumar Swaminathan *iptr++ = LE_SWAP32(MQE_SPECIAL_WORD0); 1392*82527734SSukumar Swaminathan *iptr = LE_SWAP32(MQE_SPECIAL_WORD1); 1393*82527734SSukumar Swaminathan 1394*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 1395*82527734SSukumar Swaminathan MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV); 1396*82527734SSukumar Swaminathan 1397*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EndianIN", (uint32_t *)iptr, 6, 0); 1398*82527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 1399*82527734SSukumar Swaminathan return (1); 1400*82527734SSukumar Swaminathan } 1401*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 1402*82527734SSukumar Swaminathan MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL); 1403*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EndianOUT", (uint32_t *)iptr, 6, 0); 1404*82527734SSukumar Swaminathan 1405*82527734SSukumar Swaminathan hba->flag |= FC_BOOTSTRAPMB_INIT; 1406*82527734SSukumar Swaminathan return (0); 1407*82527734SSukumar Swaminathan 1408*82527734SSukumar Swaminathan } /* emlxs_init_bootstrap_mb() */ 1409*82527734SSukumar Swaminathan 1410*82527734SSukumar Swaminathan 1411*82527734SSukumar Swaminathan static uint32_t 1412*82527734SSukumar Swaminathan emlxs_sli4_hba_init(emlxs_hba_t *hba) 1413*82527734SSukumar Swaminathan { 1414*82527734SSukumar Swaminathan int rc; 1415*82527734SSukumar Swaminathan uint32_t i; 1416*82527734SSukumar Swaminathan emlxs_port_t *vport; 1417*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1418*82527734SSukumar Swaminathan CHANNEL *cp; 1419*82527734SSukumar Swaminathan 1420*82527734SSukumar Swaminathan /* Restart the adapter */ 1421*82527734SSukumar Swaminathan if (emlxs_sli4_hba_reset(hba, 1, 0, 0)) { 1422*82527734SSukumar Swaminathan return (1); 1423*82527734SSukumar Swaminathan } 1424*82527734SSukumar Swaminathan 1425*82527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 1426*82527734SSukumar Swaminathan cp = &hba->chan[i]; 1427*82527734SSukumar Swaminathan cp->iopath = (void *)&hba->sli.sli4.wq[i]; 1428*82527734SSukumar Swaminathan } 1429*82527734SSukumar Swaminathan 1430*82527734SSukumar Swaminathan /* Initialize all the port objects */ 1431*82527734SSukumar Swaminathan hba->vpi_base = 0; 1432*82527734SSukumar Swaminathan hba->vpi_max = 0; 1433*82527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 1434*82527734SSukumar Swaminathan vport = &VPORT(i); 1435*82527734SSukumar Swaminathan vport->hba = hba; 1436*82527734SSukumar Swaminathan vport->vpi = i; 1437*82527734SSukumar Swaminathan } 1438*82527734SSukumar Swaminathan 1439*82527734SSukumar Swaminathan /* Set the max node count */ 1440*82527734SSukumar Swaminathan if (hba->max_nodes == 0) { 1441*82527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 1442*82527734SSukumar Swaminathan hba->max_nodes = cfg[CFG_NUM_NODES].current; 1443*82527734SSukumar Swaminathan } else { 1444*82527734SSukumar Swaminathan hba->max_nodes = 4096; 1445*82527734SSukumar Swaminathan } 1446*82527734SSukumar Swaminathan } 1447*82527734SSukumar Swaminathan 1448*82527734SSukumar Swaminathan rc = emlxs_init_bootstrap_mb(hba); 1449*82527734SSukumar Swaminathan if (rc) { 1450*82527734SSukumar Swaminathan return (rc); 1451*82527734SSukumar Swaminathan } 1452*82527734SSukumar Swaminathan 1453*82527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[0] = FCOE_FCF_MAP0; 1454*82527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[1] = FCOE_FCF_MAP1; 1455*82527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[2] = FCOE_FCF_MAP2; 1456*82527734SSukumar Swaminathan 1457*82527734SSukumar Swaminathan return (0); 1458*82527734SSukumar Swaminathan 1459*82527734SSukumar Swaminathan } /* emlxs_sli4_hba_init() */ 1460*82527734SSukumar Swaminathan 1461*82527734SSukumar Swaminathan 1462*82527734SSukumar Swaminathan /*ARGSUSED*/ 1463*82527734SSukumar Swaminathan static uint32_t 1464*82527734SSukumar Swaminathan emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, uint32_t skip_post, 1465*82527734SSukumar Swaminathan uint32_t quiesce) 1466*82527734SSukumar Swaminathan { 1467*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1468*82527734SSukumar Swaminathan emlxs_port_t *vport; 1469*82527734SSukumar Swaminathan CHANNEL *cp; 1470*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 1471*82527734SSukumar Swaminathan MAILBOXQ mboxq; 1472*82527734SSukumar Swaminathan uint32_t i; 1473*82527734SSukumar Swaminathan uint32_t rc; 1474*82527734SSukumar Swaminathan uint32_t channelno; 1475*82527734SSukumar Swaminathan 1476*82527734SSukumar Swaminathan if (!cfg[CFG_RESET_ENABLE].current) { 1477*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1478*82527734SSukumar Swaminathan "Adapter reset disabled."); 1479*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1480*82527734SSukumar Swaminathan 1481*82527734SSukumar Swaminathan return (1); 1482*82527734SSukumar Swaminathan } 1483*82527734SSukumar Swaminathan 1484*82527734SSukumar Swaminathan if (quiesce == 0) { 1485*82527734SSukumar Swaminathan emlxs_sli4_hba_kill(hba); 1486*82527734SSukumar Swaminathan 1487*82527734SSukumar Swaminathan /* 1488*82527734SSukumar Swaminathan * Initalize Hardware that will be used to bring 1489*82527734SSukumar Swaminathan * SLI4 online. 1490*82527734SSukumar Swaminathan */ 1491*82527734SSukumar Swaminathan rc = emlxs_init_bootstrap_mb(hba); 1492*82527734SSukumar Swaminathan if (rc) { 1493*82527734SSukumar Swaminathan return (rc); 1494*82527734SSukumar Swaminathan } 1495*82527734SSukumar Swaminathan } 1496*82527734SSukumar Swaminathan 1497*82527734SSukumar Swaminathan bzero((void *)&mboxq, sizeof (MAILBOXQ)); 1498*82527734SSukumar Swaminathan emlxs_mb_resetport(hba, &mboxq); 1499*82527734SSukumar Swaminathan 1500*82527734SSukumar Swaminathan if (quiesce == 0) { 1501*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, &mboxq, 1502*82527734SSukumar Swaminathan MBX_POLL, 0) != MBX_SUCCESS) { 1503*82527734SSukumar Swaminathan /* Timeout occurred */ 1504*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1505*82527734SSukumar Swaminathan "Timeout: RESET"); 1506*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1507*82527734SSukumar Swaminathan /* Log a dump event - not supported */ 1508*82527734SSukumar Swaminathan return (1); 1509*82527734SSukumar Swaminathan } 1510*82527734SSukumar Swaminathan } else { 1511*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd4quiesce(hba, &mboxq, 1512*82527734SSukumar Swaminathan MBX_POLL, 0) != MBX_SUCCESS) { 1513*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 1514*82527734SSukumar Swaminathan /* Log a dump event - not supported */ 1515*82527734SSukumar Swaminathan return (1); 1516*82527734SSukumar Swaminathan } 1517*82527734SSukumar Swaminathan } 1518*82527734SSukumar Swaminathan emlxs_data_dump(hba, "resetPort", (uint32_t *)&mboxq, 12, 0); 1519*82527734SSukumar Swaminathan 1520*82527734SSukumar Swaminathan /* Reset the hba structure */ 1521*82527734SSukumar Swaminathan hba->flag &= FC_RESET_MASK; 1522*82527734SSukumar Swaminathan 1523*82527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 1524*82527734SSukumar Swaminathan cp = &hba->chan[channelno]; 1525*82527734SSukumar Swaminathan cp->hba = hba; 1526*82527734SSukumar Swaminathan cp->channelno = channelno; 1527*82527734SSukumar Swaminathan } 1528*82527734SSukumar Swaminathan 1529*82527734SSukumar Swaminathan hba->channel_tx_count = 0; 1530*82527734SSukumar Swaminathan hba->io_count = 0; 1531*82527734SSukumar Swaminathan hba->iodone_count = 0; 1532*82527734SSukumar Swaminathan hba->topology = 0; 1533*82527734SSukumar Swaminathan hba->linkspeed = 0; 1534*82527734SSukumar Swaminathan hba->heartbeat_active = 0; 1535*82527734SSukumar Swaminathan hba->discovery_timer = 0; 1536*82527734SSukumar Swaminathan hba->linkup_timer = 0; 1537*82527734SSukumar Swaminathan hba->loopback_tics = 0; 1538*82527734SSukumar Swaminathan 1539*82527734SSukumar Swaminathan /* Reset the port objects */ 1540*82527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 1541*82527734SSukumar Swaminathan vport = &VPORT(i); 1542*82527734SSukumar Swaminathan 1543*82527734SSukumar Swaminathan vport->flag &= EMLXS_PORT_RESET_MASK; 1544*82527734SSukumar Swaminathan vport->did = 0; 1545*82527734SSukumar Swaminathan vport->prev_did = 0; 1546*82527734SSukumar Swaminathan vport->lip_type = 0; 1547*82527734SSukumar Swaminathan bzero(&vport->fabric_sparam, sizeof (SERV_PARM)); 1548*82527734SSukumar Swaminathan 1549*82527734SSukumar Swaminathan bzero((caddr_t)&vport->node_base, sizeof (NODELIST)); 1550*82527734SSukumar Swaminathan vport->node_base.nlp_Rpi = 0; 1551*82527734SSukumar Swaminathan vport->node_base.nlp_DID = 0xffffff; 1552*82527734SSukumar Swaminathan vport->node_base.nlp_list_next = NULL; 1553*82527734SSukumar Swaminathan vport->node_base.nlp_list_prev = NULL; 1554*82527734SSukumar Swaminathan vport->node_base.nlp_active = 1; 1555*82527734SSukumar Swaminathan vport->node_count = 0; 1556*82527734SSukumar Swaminathan 1557*82527734SSukumar Swaminathan if (vport->ub_count < EMLXS_UB_TOKEN_OFFSET) { 1558*82527734SSukumar Swaminathan vport->ub_count = EMLXS_UB_TOKEN_OFFSET; 1559*82527734SSukumar Swaminathan } 1560*82527734SSukumar Swaminathan } 1561*82527734SSukumar Swaminathan 1562*82527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 1563*82527734SSukumar Swaminathan return (1); 1564*82527734SSukumar Swaminathan } 1565*82527734SSukumar Swaminathan 1566*82527734SSukumar Swaminathan return (0); 1567*82527734SSukumar Swaminathan 1568*82527734SSukumar Swaminathan } /* emlxs_sli4_hba_reset */ 1569*82527734SSukumar Swaminathan 1570*82527734SSukumar Swaminathan 1571*82527734SSukumar Swaminathan #define SGL_CMD 0 1572*82527734SSukumar Swaminathan #define SGL_RESP 1 1573*82527734SSukumar Swaminathan #define SGL_DATA 2 1574*82527734SSukumar Swaminathan #define SGL_LAST 0x80 1575*82527734SSukumar Swaminathan 1576*82527734SSukumar Swaminathan /*ARGSUSED*/ 1577*82527734SSukumar Swaminathan ULP_SGE64 * 1578*82527734SSukumar Swaminathan emlxs_pkt_to_sgl(emlxs_port_t *port, ULP_SGE64 *sge, fc_packet_t *pkt, 1579*82527734SSukumar Swaminathan uint32_t sgl_type, uint32_t *pcnt) 1580*82527734SSukumar Swaminathan { 1581*82527734SSukumar Swaminathan #ifdef DEBUG_SGE 1582*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 1583*82527734SSukumar Swaminathan #endif 1584*82527734SSukumar Swaminathan ddi_dma_cookie_t *cp; 1585*82527734SSukumar Swaminathan uint_t i; 1586*82527734SSukumar Swaminathan uint_t last; 1587*82527734SSukumar Swaminathan int32_t size; 1588*82527734SSukumar Swaminathan int32_t sge_size; 1589*82527734SSukumar Swaminathan uint64_t sge_addr; 1590*82527734SSukumar Swaminathan int32_t len; 1591*82527734SSukumar Swaminathan uint32_t cnt; 1592*82527734SSukumar Swaminathan uint_t cookie_cnt; 1593*82527734SSukumar Swaminathan ULP_SGE64 stage_sge; 1594*82527734SSukumar Swaminathan 1595*82527734SSukumar Swaminathan last = sgl_type & SGL_LAST; 1596*82527734SSukumar Swaminathan sgl_type &= ~SGL_LAST; 1597*82527734SSukumar Swaminathan 1598*82527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 1599*82527734SSukumar Swaminathan switch (sgl_type) { 1600*82527734SSukumar Swaminathan case SGL_CMD: 1601*82527734SSukumar Swaminathan cp = pkt->pkt_cmd_cookie; 1602*82527734SSukumar Swaminathan cookie_cnt = pkt->pkt_cmd_cookie_cnt; 1603*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 1604*82527734SSukumar Swaminathan break; 1605*82527734SSukumar Swaminathan 1606*82527734SSukumar Swaminathan case SGL_RESP: 1607*82527734SSukumar Swaminathan cp = pkt->pkt_resp_cookie; 1608*82527734SSukumar Swaminathan cookie_cnt = pkt->pkt_resp_cookie_cnt; 1609*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 1610*82527734SSukumar Swaminathan break; 1611*82527734SSukumar Swaminathan 1612*82527734SSukumar Swaminathan 1613*82527734SSukumar Swaminathan case SGL_DATA: 1614*82527734SSukumar Swaminathan cp = pkt->pkt_data_cookie; 1615*82527734SSukumar Swaminathan cookie_cnt = pkt->pkt_data_cookie_cnt; 1616*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 1617*82527734SSukumar Swaminathan break; 1618*82527734SSukumar Swaminathan } 1619*82527734SSukumar Swaminathan 1620*82527734SSukumar Swaminathan #else 1621*82527734SSukumar Swaminathan switch (sgl_type) { 1622*82527734SSukumar Swaminathan case SGL_CMD: 1623*82527734SSukumar Swaminathan cp = &pkt->pkt_cmd_cookie; 1624*82527734SSukumar Swaminathan cookie_cnt = 1; 1625*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 1626*82527734SSukumar Swaminathan break; 1627*82527734SSukumar Swaminathan 1628*82527734SSukumar Swaminathan case SGL_RESP: 1629*82527734SSukumar Swaminathan cp = &pkt->pkt_resp_cookie; 1630*82527734SSukumar Swaminathan cookie_cnt = 1; 1631*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 1632*82527734SSukumar Swaminathan break; 1633*82527734SSukumar Swaminathan 1634*82527734SSukumar Swaminathan 1635*82527734SSukumar Swaminathan case SGL_DATA: 1636*82527734SSukumar Swaminathan cp = &pkt->pkt_data_cookie; 1637*82527734SSukumar Swaminathan cookie_cnt = 1; 1638*82527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 1639*82527734SSukumar Swaminathan break; 1640*82527734SSukumar Swaminathan } 1641*82527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 1642*82527734SSukumar Swaminathan 1643*82527734SSukumar Swaminathan stage_sge.offset = 0; 1644*82527734SSukumar Swaminathan stage_sge.reserved = 0; 1645*82527734SSukumar Swaminathan stage_sge.last = 0; 1646*82527734SSukumar Swaminathan cnt = 0; 1647*82527734SSukumar Swaminathan for (i = 0; i < cookie_cnt && size > 0; i++, cp++) { 1648*82527734SSukumar Swaminathan 1649*82527734SSukumar Swaminathan 1650*82527734SSukumar Swaminathan sge_size = cp->dmac_size; 1651*82527734SSukumar Swaminathan sge_addr = cp->dmac_laddress; 1652*82527734SSukumar Swaminathan while (sge_size && size) { 1653*82527734SSukumar Swaminathan if (cnt) { 1654*82527734SSukumar Swaminathan /* Copy staged SGE before we build next one */ 1655*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 1656*82527734SSukumar Swaminathan (uint8_t *)sge, sizeof (ULP_SGE64)); 1657*82527734SSukumar Swaminathan sge++; 1658*82527734SSukumar Swaminathan } 1659*82527734SSukumar Swaminathan len = MIN(EMLXS_MAX_SGE_SIZE, sge_size); 1660*82527734SSukumar Swaminathan len = MIN(size, len); 1661*82527734SSukumar Swaminathan 1662*82527734SSukumar Swaminathan stage_sge.addrHigh = 1663*82527734SSukumar Swaminathan PADDR_HI(sge_addr); 1664*82527734SSukumar Swaminathan stage_sge.addrLow = 1665*82527734SSukumar Swaminathan PADDR_LO(sge_addr); 1666*82527734SSukumar Swaminathan stage_sge.length = len; 1667*82527734SSukumar Swaminathan if (sgl_type == SGL_DATA) { 1668*82527734SSukumar Swaminathan stage_sge.offset = cnt; 1669*82527734SSukumar Swaminathan } 1670*82527734SSukumar Swaminathan #ifdef DEBUG_SGE 1671*82527734SSukumar Swaminathan emlxs_data_dump(hba, "SGE", (uint32_t *)&stage_sge, 1672*82527734SSukumar Swaminathan 4, 0); 1673*82527734SSukumar Swaminathan #endif 1674*82527734SSukumar Swaminathan sge_addr += len; 1675*82527734SSukumar Swaminathan sge_size -= len; 1676*82527734SSukumar Swaminathan 1677*82527734SSukumar Swaminathan cnt += len; 1678*82527734SSukumar Swaminathan size -= len; 1679*82527734SSukumar Swaminathan } 1680*82527734SSukumar Swaminathan } 1681*82527734SSukumar Swaminathan 1682*82527734SSukumar Swaminathan if (last) { 1683*82527734SSukumar Swaminathan stage_sge.last = 1; 1684*82527734SSukumar Swaminathan } 1685*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 1686*82527734SSukumar Swaminathan sizeof (ULP_SGE64)); 1687*82527734SSukumar Swaminathan sge++; 1688*82527734SSukumar Swaminathan 1689*82527734SSukumar Swaminathan *pcnt = cnt; 1690*82527734SSukumar Swaminathan return (sge); 1691*82527734SSukumar Swaminathan 1692*82527734SSukumar Swaminathan } /* emlxs_pkt_to_sgl */ 1693*82527734SSukumar Swaminathan 1694*82527734SSukumar Swaminathan 1695*82527734SSukumar Swaminathan /*ARGSUSED*/ 1696*82527734SSukumar Swaminathan uint32_t 1697*82527734SSukumar Swaminathan emlxs_sli4_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp) 1698*82527734SSukumar Swaminathan { 1699*82527734SSukumar Swaminathan fc_packet_t *pkt; 1700*82527734SSukumar Swaminathan XRIobj_t *xp; 1701*82527734SSukumar Swaminathan ULP_SGE64 *sge; 1702*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 1703*82527734SSukumar Swaminathan IOCBQ *iocbq; 1704*82527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 1705*82527734SSukumar Swaminathan uint32_t cmd_cnt; 1706*82527734SSukumar Swaminathan uint32_t resp_cnt; 1707*82527734SSukumar Swaminathan uint32_t cnt; 1708*82527734SSukumar Swaminathan 1709*82527734SSukumar Swaminathan iocbq = (IOCBQ *) &sbp->iocbq; 1710*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 1711*82527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 1712*82527734SSukumar Swaminathan xp = sbp->xp; 1713*82527734SSukumar Swaminathan sge = xp->SGList.virt; 1714*82527734SSukumar Swaminathan 1715*82527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 1716*82527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 1717*82527734SSukumar Swaminathan #else 1718*82527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 1719*82527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 1720*82527734SSukumar Swaminathan 1721*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 1722*82527734SSukumar Swaminathan if (iocbq->flag & IOCB_FCP_CMD) { 1723*82527734SSukumar Swaminathan 1724*82527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 1725*82527734SSukumar Swaminathan return (1); 1726*82527734SSukumar Swaminathan } 1727*82527734SSukumar Swaminathan 1728*82527734SSukumar Swaminathan /* CMD payload */ 1729*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, SGL_CMD, &cmd_cnt); 1730*82527734SSukumar Swaminathan 1731*82527734SSukumar Swaminathan /* DATA payload */ 1732*82527734SSukumar Swaminathan if (pkt->pkt_datalen != 0) { 1733*82527734SSukumar Swaminathan /* RSP payload */ 1734*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1735*82527734SSukumar Swaminathan SGL_RESP, &resp_cnt); 1736*82527734SSukumar Swaminathan 1737*82527734SSukumar Swaminathan /* Data portion */ 1738*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1739*82527734SSukumar Swaminathan SGL_DATA | SGL_LAST, &cnt); 1740*82527734SSukumar Swaminathan } else { 1741*82527734SSukumar Swaminathan /* RSP payload */ 1742*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1743*82527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 1744*82527734SSukumar Swaminathan } 1745*82527734SSukumar Swaminathan 1746*82527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrHigh = 1747*82527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 1748*82527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrLow = 1749*82527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 1750*82527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.tus.f.bdeSize = cmd_cnt; 1751*82527734SSukumar Swaminathan wqe->un.FcpCmd.PayloadLength = cmd_cnt + resp_cnt; 1752*82527734SSukumar Swaminathan 1753*82527734SSukumar Swaminathan } else { 1754*82527734SSukumar Swaminathan 1755*82527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 1756*82527734SSukumar Swaminathan /* CMD payload */ 1757*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1758*82527734SSukumar Swaminathan SGL_CMD | SGL_LAST, &cmd_cnt); 1759*82527734SSukumar Swaminathan } else { 1760*82527734SSukumar Swaminathan /* CMD payload */ 1761*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1762*82527734SSukumar Swaminathan SGL_CMD, &cmd_cnt); 1763*82527734SSukumar Swaminathan 1764*82527734SSukumar Swaminathan /* RSP payload */ 1765*82527734SSukumar Swaminathan sge = emlxs_pkt_to_sgl(port, sge, pkt, 1766*82527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 1767*82527734SSukumar Swaminathan wqe->un.GenReq.PayloadLength = cmd_cnt; 1768*82527734SSukumar Swaminathan } 1769*82527734SSukumar Swaminathan 1770*82527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrHigh = 1771*82527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 1772*82527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrLow = 1773*82527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 1774*82527734SSukumar Swaminathan wqe->un.GenReq.Payload.tus.f.bdeSize = cmd_cnt; 1775*82527734SSukumar Swaminathan } 1776*82527734SSukumar Swaminathan return (0); 1777*82527734SSukumar Swaminathan } /* emlxs_sli4_bde_setup */ 1778*82527734SSukumar Swaminathan 1779*82527734SSukumar Swaminathan 1780*82527734SSukumar Swaminathan /*ARGSUSED*/ 1781*82527734SSukumar Swaminathan static uint32_t 1782*82527734SSukumar Swaminathan emlxs_sli4_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp) 1783*82527734SSukumar Swaminathan { 1784*82527734SSukumar Swaminathan return (0); 1785*82527734SSukumar Swaminathan 1786*82527734SSukumar Swaminathan } /* emlxs_sli4_fct_bde_setup */ 1787*82527734SSukumar Swaminathan 1788*82527734SSukumar Swaminathan 1789*82527734SSukumar Swaminathan static void 1790*82527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 1791*82527734SSukumar Swaminathan { 1792*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1793*82527734SSukumar Swaminathan emlxs_buf_t *sbp; 1794*82527734SSukumar Swaminathan uint32_t channelno; 1795*82527734SSukumar Swaminathan int32_t throttle; 1796*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 1797*82527734SSukumar Swaminathan emlxs_wqe_t *wqeslot; 1798*82527734SSukumar Swaminathan WQ_DESC_t *wq; 1799*82527734SSukumar Swaminathan uint32_t flag; 1800*82527734SSukumar Swaminathan uint32_t wqdb; 1801*82527734SSukumar Swaminathan uint32_t next_wqe; 1802*82527734SSukumar Swaminathan 1803*82527734SSukumar Swaminathan 1804*82527734SSukumar Swaminathan channelno = cp->channelno; 1805*82527734SSukumar Swaminathan wq = (WQ_DESC_t *)cp->iopath; 1806*82527734SSukumar Swaminathan 1807*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 1808*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 1809*82527734SSukumar Swaminathan "ISSUE WQE channel: %x %p", channelno, wq); 1810*82527734SSukumar Swaminathan #endif 1811*82527734SSukumar Swaminathan 1812*82527734SSukumar Swaminathan throttle = 0; 1813*82527734SSukumar Swaminathan 1814*82527734SSukumar Swaminathan /* Check if FCP ring and adapter is not ready */ 1815*82527734SSukumar Swaminathan /* We may use any ring for FCP_CMD */ 1816*82527734SSukumar Swaminathan if (iocbq && (iocbq->flag & IOCB_FCP_CMD) && (hba->state != FC_READY)) { 1817*82527734SSukumar Swaminathan if (!(iocbq->flag & IOCB_SPECIAL) || !iocbq->port || 1818*82527734SSukumar Swaminathan !(((emlxs_port_t *)iocbq->port)->tgt_mode)) { 1819*82527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 1820*82527734SSukumar Swaminathan return; 1821*82527734SSukumar Swaminathan } 1822*82527734SSukumar Swaminathan } 1823*82527734SSukumar Swaminathan 1824*82527734SSukumar Swaminathan /* Attempt to acquire CMD_RING lock */ 1825*82527734SSukumar Swaminathan if (mutex_tryenter(&EMLXS_CMD_RING_LOCK(channelno)) == 0) { 1826*82527734SSukumar Swaminathan /* Queue it for later */ 1827*82527734SSukumar Swaminathan if (iocbq) { 1828*82527734SSukumar Swaminathan if ((hba->io_count - 1829*82527734SSukumar Swaminathan hba->channel_tx_count) > 10) { 1830*82527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 1831*82527734SSukumar Swaminathan return; 1832*82527734SSukumar Swaminathan } else { 1833*82527734SSukumar Swaminathan 1834*82527734SSukumar Swaminathan mutex_enter(&EMLXS_CMD_RING_LOCK(channelno)); 1835*82527734SSukumar Swaminathan } 1836*82527734SSukumar Swaminathan } else { 1837*82527734SSukumar Swaminathan return; 1838*82527734SSukumar Swaminathan } 1839*82527734SSukumar Swaminathan } 1840*82527734SSukumar Swaminathan /* CMD_RING_LOCK acquired */ 1841*82527734SSukumar Swaminathan 1842*82527734SSukumar Swaminathan /* Throttle check only applies to non special iocb */ 1843*82527734SSukumar Swaminathan if (iocbq && (!(iocbq->flag & IOCB_SPECIAL))) { 1844*82527734SSukumar Swaminathan /* Check if HBA is full */ 1845*82527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 1846*82527734SSukumar Swaminathan if (throttle <= 0) { 1847*82527734SSukumar Swaminathan /* Hitting adapter throttle limit */ 1848*82527734SSukumar Swaminathan /* Queue it for later */ 1849*82527734SSukumar Swaminathan if (iocbq) { 1850*82527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 1851*82527734SSukumar Swaminathan } 1852*82527734SSukumar Swaminathan 1853*82527734SSukumar Swaminathan goto busy; 1854*82527734SSukumar Swaminathan } 1855*82527734SSukumar Swaminathan } 1856*82527734SSukumar Swaminathan 1857*82527734SSukumar Swaminathan /* Check to see if we have room for this WQE */ 1858*82527734SSukumar Swaminathan next_wqe = wq->host_index + 1; 1859*82527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 1860*82527734SSukumar Swaminathan next_wqe = 0; 1861*82527734SSukumar Swaminathan } 1862*82527734SSukumar Swaminathan 1863*82527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 1864*82527734SSukumar Swaminathan /* Queue it for later */ 1865*82527734SSukumar Swaminathan if (iocbq) { 1866*82527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 1867*82527734SSukumar Swaminathan } 1868*82527734SSukumar Swaminathan goto busy; 1869*82527734SSukumar Swaminathan } 1870*82527734SSukumar Swaminathan 1871*82527734SSukumar Swaminathan /* 1872*82527734SSukumar Swaminathan * We have a command ring slot available 1873*82527734SSukumar Swaminathan * Make sure we have an iocb to send 1874*82527734SSukumar Swaminathan */ 1875*82527734SSukumar Swaminathan if (iocbq) { 1876*82527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 1877*82527734SSukumar Swaminathan 1878*82527734SSukumar Swaminathan /* Check if the ring already has iocb's waiting */ 1879*82527734SSukumar Swaminathan if (cp->nodeq.q_first != NULL) { 1880*82527734SSukumar Swaminathan /* Put the current iocbq on the tx queue */ 1881*82527734SSukumar Swaminathan emlxs_tx_put(iocbq, 0); 1882*82527734SSukumar Swaminathan 1883*82527734SSukumar Swaminathan /* 1884*82527734SSukumar Swaminathan * Attempt to replace it with the next iocbq 1885*82527734SSukumar Swaminathan * in the tx queue 1886*82527734SSukumar Swaminathan */ 1887*82527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 0); 1888*82527734SSukumar Swaminathan } 1889*82527734SSukumar Swaminathan 1890*82527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 1891*82527734SSukumar Swaminathan } else { 1892*82527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 1893*82527734SSukumar Swaminathan } 1894*82527734SSukumar Swaminathan 1895*82527734SSukumar Swaminathan sendit: 1896*82527734SSukumar Swaminathan /* Process each iocbq */ 1897*82527734SSukumar Swaminathan while (iocbq) { 1898*82527734SSukumar Swaminathan 1899*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 1900*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 1901*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 1902*82527734SSukumar Swaminathan "ISSUE QID %d WQE iotag: %x xri: %x", wq->qid, 1903*82527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 1904*82527734SSukumar Swaminathan #endif 1905*82527734SSukumar Swaminathan 1906*82527734SSukumar Swaminathan sbp = iocbq->sbp; 1907*82527734SSukumar Swaminathan if (sbp) { 1908*82527734SSukumar Swaminathan /* If exchange removed after wqe was prep'ed, drop it */ 1909*82527734SSukumar Swaminathan if (!(sbp->xp)) { 1910*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 1911*82527734SSukumar Swaminathan "Xmit WQE iotag: %x xri: %x aborted", 1912*82527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 1913*82527734SSukumar Swaminathan 1914*82527734SSukumar Swaminathan /* Get next iocb from the tx queue */ 1915*82527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 1916*82527734SSukumar Swaminathan continue; 1917*82527734SSukumar Swaminathan } 1918*82527734SSukumar Swaminathan 1919*82527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_DELAY_REQUIRED) { 1920*82527734SSukumar Swaminathan 1921*82527734SSukumar Swaminathan /* Perform delay */ 1922*82527734SSukumar Swaminathan if ((channelno == hba->channel_els) && 1923*82527734SSukumar Swaminathan !(iocbq->flag & IOCB_FCP_CMD)) { 1924*82527734SSukumar Swaminathan drv_usecwait(100000); 1925*82527734SSukumar Swaminathan } else { 1926*82527734SSukumar Swaminathan drv_usecwait(20000); 1927*82527734SSukumar Swaminathan } 1928*82527734SSukumar Swaminathan } 1929*82527734SSukumar Swaminathan } 1930*82527734SSukumar Swaminathan 1931*82527734SSukumar Swaminathan /* 1932*82527734SSukumar Swaminathan * At this point, we have a command ring slot available 1933*82527734SSukumar Swaminathan * and an iocb to send 1934*82527734SSukumar Swaminathan */ 1935*82527734SSukumar Swaminathan wq->release_depth--; 1936*82527734SSukumar Swaminathan if (wq->release_depth == 0) { 1937*82527734SSukumar Swaminathan wq->release_depth = WQE_RELEASE_DEPTH; 1938*82527734SSukumar Swaminathan wqe->WQEC = 1; 1939*82527734SSukumar Swaminathan } 1940*82527734SSukumar Swaminathan 1941*82527734SSukumar Swaminathan 1942*82527734SSukumar Swaminathan HBASTATS.IocbIssued[channelno]++; 1943*82527734SSukumar Swaminathan 1944*82527734SSukumar Swaminathan /* Check for ULP pkt request */ 1945*82527734SSukumar Swaminathan if (sbp) { 1946*82527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 1947*82527734SSukumar Swaminathan 1948*82527734SSukumar Swaminathan if (sbp->node == NULL) { 1949*82527734SSukumar Swaminathan /* Set node to base node by default */ 1950*82527734SSukumar Swaminathan iocbq->node = (void *)&port->node_base; 1951*82527734SSukumar Swaminathan sbp->node = (void *)&port->node_base; 1952*82527734SSukumar Swaminathan } 1953*82527734SSukumar Swaminathan 1954*82527734SSukumar Swaminathan sbp->pkt_flags |= PACKET_IN_CHIPQ; 1955*82527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 1956*82527734SSukumar Swaminathan 1957*82527734SSukumar Swaminathan atomic_add_32(&hba->io_active, 1); 1958*82527734SSukumar Swaminathan sbp->xp->state |= RESOURCE_XRI_PENDING_IO; 1959*82527734SSukumar Swaminathan } 1960*82527734SSukumar Swaminathan 1961*82527734SSukumar Swaminathan 1962*82527734SSukumar Swaminathan /* Free the local iocb if there is no sbp tracking it */ 1963*82527734SSukumar Swaminathan if (sbp) { 1964*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 1965*82527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 1966*82527734SSukumar Swaminathan if (sbp->fct_cmd) { 1967*82527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 1968*82527734SSukumar Swaminathan EMLXS_FCT_IOCB_ISSUED); 1969*82527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 1970*82527734SSukumar Swaminathan icmd->ULPCOMMAND); 1971*82527734SSukumar Swaminathan } 1972*82527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 1973*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 1974*82527734SSukumar Swaminathan cp->hbaSendCmd_sbp++; 1975*82527734SSukumar Swaminathan iocbq->channel = cp; 1976*82527734SSukumar Swaminathan } else { 1977*82527734SSukumar Swaminathan cp->hbaSendCmd++; 1978*82527734SSukumar Swaminathan } 1979*82527734SSukumar Swaminathan 1980*82527734SSukumar Swaminathan flag = iocbq->flag; 1981*82527734SSukumar Swaminathan 1982*82527734SSukumar Swaminathan /* Send the iocb */ 1983*82527734SSukumar Swaminathan wqeslot = (emlxs_wqe_t *)wq->addr.virt; 1984*82527734SSukumar Swaminathan wqeslot += wq->host_index; 1985*82527734SSukumar Swaminathan 1986*82527734SSukumar Swaminathan wqe->CQId = wq->cqid; 1987*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)wqe, (uint8_t *)wqeslot, 1988*82527734SSukumar Swaminathan sizeof (emlxs_wqe_t)); 1989*82527734SSukumar Swaminathan #ifdef DEBUG_WQE 1990*82527734SSukumar Swaminathan emlxs_data_dump(hba, "WQE", (uint32_t *)wqe, 18, 0); 1991*82527734SSukumar Swaminathan #endif 1992*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(wq->addr.dma_handle, 0, 1993*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 1994*82527734SSukumar Swaminathan 1995*82527734SSukumar Swaminathan /* Ring the WQ Doorbell */ 1996*82527734SSukumar Swaminathan wqdb = wq->qid; 1997*82527734SSukumar Swaminathan wqdb |= ((1 << 24) | (wq->host_index << 16)); 1998*82527734SSukumar Swaminathan 1999*82527734SSukumar Swaminathan 2000*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_WQDB_REG(hba), wqdb); 2001*82527734SSukumar Swaminathan wq->host_index = next_wqe; 2002*82527734SSukumar Swaminathan 2003*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 2004*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2005*82527734SSukumar Swaminathan "WQ RING: %08x", wqdb); 2006*82527734SSukumar Swaminathan #endif 2007*82527734SSukumar Swaminathan 2008*82527734SSukumar Swaminathan /* 2009*82527734SSukumar Swaminathan * After this, the sbp / iocb / wqe should not be 2010*82527734SSukumar Swaminathan * accessed in the xmit path. 2011*82527734SSukumar Swaminathan */ 2012*82527734SSukumar Swaminathan 2013*82527734SSukumar Swaminathan if (!sbp) { 2014*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_IOCB, (uint8_t *)iocbq); 2015*82527734SSukumar Swaminathan } 2016*82527734SSukumar Swaminathan 2017*82527734SSukumar Swaminathan if (iocbq && (!(flag & IOCB_SPECIAL))) { 2018*82527734SSukumar Swaminathan /* Check if HBA is full */ 2019*82527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 2020*82527734SSukumar Swaminathan if (throttle <= 0) { 2021*82527734SSukumar Swaminathan goto busy; 2022*82527734SSukumar Swaminathan } 2023*82527734SSukumar Swaminathan } 2024*82527734SSukumar Swaminathan 2025*82527734SSukumar Swaminathan /* Check to see if we have room for another WQE */ 2026*82527734SSukumar Swaminathan next_wqe++; 2027*82527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 2028*82527734SSukumar Swaminathan next_wqe = 0; 2029*82527734SSukumar Swaminathan } 2030*82527734SSukumar Swaminathan 2031*82527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 2032*82527734SSukumar Swaminathan /* Queue it for later */ 2033*82527734SSukumar Swaminathan goto busy; 2034*82527734SSukumar Swaminathan } 2035*82527734SSukumar Swaminathan 2036*82527734SSukumar Swaminathan 2037*82527734SSukumar Swaminathan /* Get the next iocb from the tx queue if there is one */ 2038*82527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 2039*82527734SSukumar Swaminathan } 2040*82527734SSukumar Swaminathan 2041*82527734SSukumar Swaminathan mutex_exit(&EMLXS_CMD_RING_LOCK(channelno)); 2042*82527734SSukumar Swaminathan 2043*82527734SSukumar Swaminathan return; 2044*82527734SSukumar Swaminathan 2045*82527734SSukumar Swaminathan busy: 2046*82527734SSukumar Swaminathan if (throttle <= 0) { 2047*82527734SSukumar Swaminathan HBASTATS.IocbThrottled++; 2048*82527734SSukumar Swaminathan } else { 2049*82527734SSukumar Swaminathan HBASTATS.IocbRingFull[channelno]++; 2050*82527734SSukumar Swaminathan } 2051*82527734SSukumar Swaminathan 2052*82527734SSukumar Swaminathan mutex_exit(&EMLXS_CMD_RING_LOCK(channelno)); 2053*82527734SSukumar Swaminathan 2054*82527734SSukumar Swaminathan return; 2055*82527734SSukumar Swaminathan 2056*82527734SSukumar Swaminathan } /* emlxs_sli4_issue_iocb_cmd() */ 2057*82527734SSukumar Swaminathan 2058*82527734SSukumar Swaminathan 2059*82527734SSukumar Swaminathan /*ARGSUSED*/ 2060*82527734SSukumar Swaminathan static uint32_t 2061*82527734SSukumar Swaminathan emlxs_sli4_issue_mq(emlxs_hba_t *hba, MAILBOX4 *mqe, MAILBOX *mb, uint32_t tmo) 2062*82527734SSukumar Swaminathan { 2063*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 2064*82527734SSukumar Swaminathan MAILBOXQ *mbq; 2065*82527734SSukumar Swaminathan MAILBOX4 *mb4; 2066*82527734SSukumar Swaminathan MATCHMAP *mp; 2067*82527734SSukumar Swaminathan uint32_t *iptr; 2068*82527734SSukumar Swaminathan uint32_t mqdb; 2069*82527734SSukumar Swaminathan 2070*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 2071*82527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 2072*82527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 2073*82527734SSukumar Swaminathan hba->mbox_mqe = (uint32_t *)mqe; 2074*82527734SSukumar Swaminathan 2075*82527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 2076*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 2077*82527734SSukumar Swaminathan /* 2078*82527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 2079*82527734SSukumar Swaminathan * into the mailbox area. 2080*82527734SSukumar Swaminathan */ 2081*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 2082*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2083*82527734SSukumar Swaminathan 2084*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0, 2085*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 2086*82527734SSukumar Swaminathan 2087*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX CMD", (uint32_t *)mqe, 18, 0); 2088*82527734SSukumar Swaminathan } else { 2089*82527734SSukumar Swaminathan /* SLI_CONFIG and non-embedded */ 2090*82527734SSukumar Swaminathan 2091*82527734SSukumar Swaminathan /* 2092*82527734SSukumar Swaminathan * If this is not embedded, the MQ area 2093*82527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 2094*82527734SSukumar Swaminathan * non-embedded mailbox command. 2095*82527734SSukumar Swaminathan * mp will point to the actual mailbox command which 2096*82527734SSukumar Swaminathan * should be copied into the non-embedded area. 2097*82527734SSukumar Swaminathan */ 2098*82527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 2099*82527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 2100*82527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 2101*82527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 2102*82527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 2103*82527734SSukumar Swaminathan *iptr = mp->size; 2104*82527734SSukumar Swaminathan 2105*82527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 2106*82527734SSukumar Swaminathan 2107*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 2108*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 2109*82527734SSukumar Swaminathan 2110*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 2111*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2112*82527734SSukumar Swaminathan 2113*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0, 2114*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 2115*82527734SSukumar Swaminathan 2116*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX EXT", (uint32_t *)mqe, 12, 0); 2117*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2118*82527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, (uint32_t *)(mp->virt)); 2119*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 2120*82527734SSukumar Swaminathan } 2121*82527734SSukumar Swaminathan 2122*82527734SSukumar Swaminathan /* Ring the MQ Doorbell */ 2123*82527734SSukumar Swaminathan mqdb = hba->sli.sli4.mq.qid; 2124*82527734SSukumar Swaminathan mqdb |= ((1 << MQ_DB_POP_SHIFT) & MQ_DB_POP_MASK); 2125*82527734SSukumar Swaminathan 2126*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2127*82527734SSukumar Swaminathan "MQ RING: %08x", mqdb); 2128*82527734SSukumar Swaminathan 2129*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_MQDB_REG(hba), mqdb); 2130*82527734SSukumar Swaminathan return (MBX_SUCCESS); 2131*82527734SSukumar Swaminathan 2132*82527734SSukumar Swaminathan } /* emlxs_sli4_issue_mq() */ 2133*82527734SSukumar Swaminathan 2134*82527734SSukumar Swaminathan 2135*82527734SSukumar Swaminathan /*ARGSUSED*/ 2136*82527734SSukumar Swaminathan static uint32_t 2137*82527734SSukumar Swaminathan emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo) 2138*82527734SSukumar Swaminathan { 2139*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 2140*82527734SSukumar Swaminathan MAILBOXQ *mbq; 2141*82527734SSukumar Swaminathan MAILBOX4 *mb4; 2142*82527734SSukumar Swaminathan MATCHMAP *mp; 2143*82527734SSukumar Swaminathan uint32_t *iptr; 2144*82527734SSukumar Swaminathan 2145*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 2146*82527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 2147*82527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 2148*82527734SSukumar Swaminathan hba->mbox_mqe = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2149*82527734SSukumar Swaminathan 2150*82527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 2151*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 2152*82527734SSukumar Swaminathan /* 2153*82527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 2154*82527734SSukumar Swaminathan * into the bootstrap mailbox area. 2155*82527734SSukumar Swaminathan */ 2156*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2157*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 2158*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2159*82527734SSukumar Swaminathan 2160*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 2161*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORDEV); 2162*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX CMD", iptr, 18, 0); 2163*82527734SSukumar Swaminathan } else { 2164*82527734SSukumar Swaminathan /* 2165*82527734SSukumar Swaminathan * If this is not embedded, the bootstrap mailbox area 2166*82527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 2167*82527734SSukumar Swaminathan * non-embedded mailbox command. 2168*82527734SSukumar Swaminathan * mp will point to the actual mailbox command which 2169*82527734SSukumar Swaminathan * should be copied into the non-embedded area. 2170*82527734SSukumar Swaminathan */ 2171*82527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 2172*82527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 2173*82527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 2174*82527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 2175*82527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 2176*82527734SSukumar Swaminathan *iptr = mp->size; 2177*82527734SSukumar Swaminathan 2178*82527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 2179*82527734SSukumar Swaminathan 2180*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 2181*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 2182*82527734SSukumar Swaminathan 2183*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2184*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 2185*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2186*82527734SSukumar Swaminathan 2187*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 2188*82527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 2189*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 2190*82527734SSukumar Swaminathan 2191*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX EXT", iptr, 12, 0); 2192*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2193*82527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, 2194*82527734SSukumar Swaminathan (uint32_t *)((uint8_t *)mp->virt)); 2195*82527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 2196*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 2197*82527734SSukumar Swaminathan } 2198*82527734SSukumar Swaminathan 2199*82527734SSukumar Swaminathan 2200*82527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 2201*82527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 2202*82527734SSukumar Swaminathan return (MBX_TIMEOUT); 2203*82527734SSukumar Swaminathan } 2204*82527734SSukumar Swaminathan 2205*82527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 2206*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 2207*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 2208*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORKERNEL); 2209*82527734SSukumar Swaminathan 2210*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2211*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 2212*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2213*82527734SSukumar Swaminathan 2214*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX CMPL", iptr, 18, 0); 2215*82527734SSukumar Swaminathan 2216*82527734SSukumar Swaminathan } else { 2217*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 2218*82527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 2219*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 2220*82527734SSukumar Swaminathan 2221*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 2222*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 2223*82527734SSukumar Swaminathan 2224*82527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 2225*82527734SSukumar Swaminathan 2226*82527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2227*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 2228*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 2229*82527734SSukumar Swaminathan 2230*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX CMPL", iptr, 12, 0); 2231*82527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 2232*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EXT AREA", (uint32_t *)iptr, 24, 0); 2233*82527734SSukumar Swaminathan } 2234*82527734SSukumar Swaminathan 2235*82527734SSukumar Swaminathan return (MBX_SUCCESS); 2236*82527734SSukumar Swaminathan 2237*82527734SSukumar Swaminathan } /* emlxs_sli4_issue_bootstrap() */ 2238*82527734SSukumar Swaminathan 2239*82527734SSukumar Swaminathan 2240*82527734SSukumar Swaminathan /*ARGSUSED*/ 2241*82527734SSukumar Swaminathan static uint32_t 2242*82527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 2243*82527734SSukumar Swaminathan uint32_t tmo) 2244*82527734SSukumar Swaminathan { 2245*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 2246*82527734SSukumar Swaminathan MAILBOX4 *mb4; 2247*82527734SSukumar Swaminathan MAILBOX *mb; 2248*82527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 2249*82527734SSukumar Swaminathan MATCHMAP *mp; 2250*82527734SSukumar Swaminathan uint32_t *iptr; 2251*82527734SSukumar Swaminathan uint32_t rc; 2252*82527734SSukumar Swaminathan uint32_t i; 2253*82527734SSukumar Swaminathan uint32_t tmo_local; 2254*82527734SSukumar Swaminathan 2255*82527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mbq; 2256*82527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 2257*82527734SSukumar Swaminathan 2258*82527734SSukumar Swaminathan 2259*82527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 2260*82527734SSukumar Swaminathan rc = MBX_SUCCESS; 2261*82527734SSukumar Swaminathan 2262*82527734SSukumar Swaminathan /* Check for minimum timeouts */ 2263*82527734SSukumar Swaminathan switch (mb->mbxCommand) { 2264*82527734SSukumar Swaminathan /* Mailbox commands that erase/write flash */ 2265*82527734SSukumar Swaminathan case MBX_DOWN_LOAD: 2266*82527734SSukumar Swaminathan case MBX_UPDATE_CFG: 2267*82527734SSukumar Swaminathan case MBX_LOAD_AREA: 2268*82527734SSukumar Swaminathan case MBX_LOAD_EXP_ROM: 2269*82527734SSukumar Swaminathan case MBX_WRITE_NV: 2270*82527734SSukumar Swaminathan case MBX_FLASH_WR_ULA: 2271*82527734SSukumar Swaminathan case MBX_DEL_LD_ENTRY: 2272*82527734SSukumar Swaminathan case MBX_LOAD_SM: 2273*82527734SSukumar Swaminathan if (tmo < 300) { 2274*82527734SSukumar Swaminathan tmo = 300; 2275*82527734SSukumar Swaminathan } 2276*82527734SSukumar Swaminathan break; 2277*82527734SSukumar Swaminathan 2278*82527734SSukumar Swaminathan default: 2279*82527734SSukumar Swaminathan if (tmo < 30) { 2280*82527734SSukumar Swaminathan tmo = 30; 2281*82527734SSukumar Swaminathan } 2282*82527734SSukumar Swaminathan break; 2283*82527734SSukumar Swaminathan } 2284*82527734SSukumar Swaminathan 2285*82527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 2286*82527734SSukumar Swaminathan tmo_local = tmo * 100; 2287*82527734SSukumar Swaminathan 2288*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 2289*82527734SSukumar Swaminathan 2290*82527734SSukumar Swaminathan /* Adjust wait flag */ 2291*82527734SSukumar Swaminathan if (flag != MBX_NOWAIT) { 2292*82527734SSukumar Swaminathan if (hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED) { 2293*82527734SSukumar Swaminathan flag = MBX_SLEEP; 2294*82527734SSukumar Swaminathan } else { 2295*82527734SSukumar Swaminathan flag = MBX_POLL; 2296*82527734SSukumar Swaminathan } 2297*82527734SSukumar Swaminathan } else { 2298*82527734SSukumar Swaminathan /* Must have interrupts enabled to perform MBX_NOWAIT */ 2299*82527734SSukumar Swaminathan if (!(hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED)) { 2300*82527734SSukumar Swaminathan 2301*82527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 2302*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 2303*82527734SSukumar Swaminathan 2304*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2305*82527734SSukumar Swaminathan "Mailbox Queue missing %s failed", 2306*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 2307*82527734SSukumar Swaminathan 2308*82527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 2309*82527734SSukumar Swaminathan } 2310*82527734SSukumar Swaminathan } 2311*82527734SSukumar Swaminathan 2312*82527734SSukumar Swaminathan /* Check for hardware error */ 2313*82527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 2314*82527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 2315*82527734SSukumar Swaminathan 2316*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 2317*82527734SSukumar Swaminathan 2318*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2319*82527734SSukumar Swaminathan "Hardware error reported. %s failed. status=%x mb=%p", 2320*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb); 2321*82527734SSukumar Swaminathan 2322*82527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 2323*82527734SSukumar Swaminathan } 2324*82527734SSukumar Swaminathan 2325*82527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 2326*82527734SSukumar Swaminathan /* If we are not polling, then queue it for later */ 2327*82527734SSukumar Swaminathan if (flag == MBX_NOWAIT) { 2328*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2329*82527734SSukumar Swaminathan "Busy. %s: mb=%p NoWait.", 2330*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 2331*82527734SSukumar Swaminathan 2332*82527734SSukumar Swaminathan emlxs_mb_put(hba, mbq); 2333*82527734SSukumar Swaminathan 2334*82527734SSukumar Swaminathan HBASTATS.MboxBusy++; 2335*82527734SSukumar Swaminathan 2336*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 2337*82527734SSukumar Swaminathan 2338*82527734SSukumar Swaminathan return (MBX_BUSY); 2339*82527734SSukumar Swaminathan } 2340*82527734SSukumar Swaminathan 2341*82527734SSukumar Swaminathan while (hba->mbox_queue_flag) { 2342*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 2343*82527734SSukumar Swaminathan 2344*82527734SSukumar Swaminathan if (tmo_local-- == 0) { 2345*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2346*82527734SSukumar Swaminathan &emlxs_mbox_event_msg, 2347*82527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%d Waiting.", 2348*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 2349*82527734SSukumar Swaminathan tmo); 2350*82527734SSukumar Swaminathan 2351*82527734SSukumar Swaminathan /* Non-lethalStatus mailbox timeout */ 2352*82527734SSukumar Swaminathan /* Does not indicate a hardware error */ 2353*82527734SSukumar Swaminathan mb->mbxStatus = MBX_TIMEOUT; 2354*82527734SSukumar Swaminathan return (MBX_TIMEOUT); 2355*82527734SSukumar Swaminathan } 2356*82527734SSukumar Swaminathan 2357*82527734SSukumar Swaminathan DELAYMS(10); 2358*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 2359*82527734SSukumar Swaminathan } 2360*82527734SSukumar Swaminathan } 2361*82527734SSukumar Swaminathan 2362*82527734SSukumar Swaminathan /* Initialize mailbox area */ 2363*82527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 2364*82527734SSukumar Swaminathan 2365*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 2366*82527734SSukumar Swaminathan switch (flag) { 2367*82527734SSukumar Swaminathan 2368*82527734SSukumar Swaminathan case MBX_NOWAIT: 2369*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_HEARTBEAT) { 2370*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 2371*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 2372*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2373*82527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 2374*82527734SSukumar Swaminathan "Sending. %s: mb=%p NoWait. embedded %d", 2375*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 2376*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2377*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2378*82527734SSukumar Swaminathan } 2379*82527734SSukumar Swaminathan } 2380*82527734SSukumar Swaminathan 2381*82527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 2382*82527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 2383*82527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 2384*82527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 2385*82527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 2386*82527734SSukumar Swaminathan } 2387*82527734SSukumar Swaminathan 2388*82527734SSukumar Swaminathan if (mbq->bp) { 2389*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2390*82527734SSukumar Swaminathan "BDE virt %p phys %p size x%x", 2391*82527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->virt, 2392*82527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->phys, 2393*82527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->size); 2394*82527734SSukumar Swaminathan emlxs_data_dump(hba, "DATA", 2395*82527734SSukumar Swaminathan (uint32_t *)(((MATCHMAP *)mbq->bp)->virt), 30, 0); 2396*82527734SSukumar Swaminathan } 2397*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_mq(hba, (MAILBOX4 *)iptr, mb, tmo_local); 2398*82527734SSukumar Swaminathan break; 2399*82527734SSukumar Swaminathan 2400*82527734SSukumar Swaminathan case MBX_POLL: 2401*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 2402*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 2403*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2404*82527734SSukumar Swaminathan "Sending. %s: mb=%p Poll. embedded %d", 2405*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 2406*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2407*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2408*82527734SSukumar Swaminathan } 2409*82527734SSukumar Swaminathan 2410*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 2411*82527734SSukumar Swaminathan 2412*82527734SSukumar Swaminathan /* Clean up the mailbox area */ 2413*82527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 2414*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2415*82527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Poll. embedded %d", 2416*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 2417*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2418*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2419*82527734SSukumar Swaminathan 2420*82527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 2421*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 2422*82527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 2423*82527734SSukumar Swaminathan 2424*82527734SSukumar Swaminathan } else { 2425*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 2426*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 2427*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2428*82527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 2429*82527734SSukumar Swaminathan "Completed. %s: mb=%p status=%x Poll. " \ 2430*82527734SSukumar Swaminathan "embedded %d", 2431*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 2432*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2433*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2434*82527734SSukumar Swaminathan } 2435*82527734SSukumar Swaminathan 2436*82527734SSukumar Swaminathan /* Process the result */ 2437*82527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 2438*82527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 2439*82527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 2440*82527734SSukumar Swaminathan } 2441*82527734SSukumar Swaminathan } 2442*82527734SSukumar Swaminathan 2443*82527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 2444*82527734SSukumar Swaminathan } 2445*82527734SSukumar Swaminathan 2446*82527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 2447*82527734SSukumar Swaminathan if (mp) { 2448*82527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 2449*82527734SSukumar Swaminathan if (hdr_rsp->status) { 2450*82527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 2451*82527734SSukumar Swaminathan } 2452*82527734SSukumar Swaminathan } 2453*82527734SSukumar Swaminathan rc = mb->mbxStatus; 2454*82527734SSukumar Swaminathan 2455*82527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 2456*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 2457*82527734SSukumar Swaminathan if (mbq) { 2458*82527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 2459*82527734SSukumar Swaminathan i = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 2460*82527734SSukumar Swaminathan if ((i != MBX_BUSY) && (i != MBX_SUCCESS)) { 2461*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, 2462*82527734SSukumar Swaminathan (uint8_t *)mbq); 2463*82527734SSukumar Swaminathan } 2464*82527734SSukumar Swaminathan } 2465*82527734SSukumar Swaminathan break; 2466*82527734SSukumar Swaminathan 2467*82527734SSukumar Swaminathan case MBX_SLEEP: 2468*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 2469*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 2470*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2471*82527734SSukumar Swaminathan "Sending. %s: mb=%p Sleep. embedded %d", 2472*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 2473*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2474*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2475*82527734SSukumar Swaminathan } 2476*82527734SSukumar Swaminathan 2477*82527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 2478*82527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 2479*82527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 2480*82527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 2481*82527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 2482*82527734SSukumar Swaminathan } 2483*82527734SSukumar Swaminathan 2484*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_mq(hba, (MAILBOX4 *)iptr, mb, tmo_local); 2485*82527734SSukumar Swaminathan 2486*82527734SSukumar Swaminathan if (rc != MBX_SUCCESS) { 2487*82527734SSukumar Swaminathan break; 2488*82527734SSukumar Swaminathan } 2489*82527734SSukumar Swaminathan 2490*82527734SSukumar Swaminathan /* Wait for completion */ 2491*82527734SSukumar Swaminathan /* The driver clock is timing the mailbox. */ 2492*82527734SSukumar Swaminathan 2493*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 2494*82527734SSukumar Swaminathan while (!(mbq->flag & MBQ_COMPLETED)) { 2495*82527734SSukumar Swaminathan cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK); 2496*82527734SSukumar Swaminathan } 2497*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 2498*82527734SSukumar Swaminathan 2499*82527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 2500*82527734SSukumar Swaminathan if (mp) { 2501*82527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 2502*82527734SSukumar Swaminathan if (hdr_rsp->status) { 2503*82527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 2504*82527734SSukumar Swaminathan } 2505*82527734SSukumar Swaminathan } 2506*82527734SSukumar Swaminathan rc = mb->mbxStatus; 2507*82527734SSukumar Swaminathan 2508*82527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 2509*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 2510*82527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Sleep. embedded %d", 2511*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 2512*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2513*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2514*82527734SSukumar Swaminathan } else { 2515*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 2516*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 2517*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2518*82527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 2519*82527734SSukumar Swaminathan "Completed. %s: mb=%p status=%x Sleep. " \ 2520*82527734SSukumar Swaminathan "embedded %d", 2521*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 2522*82527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 2523*82527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 2524*82527734SSukumar Swaminathan } 2525*82527734SSukumar Swaminathan } 2526*82527734SSukumar Swaminathan break; 2527*82527734SSukumar Swaminathan } 2528*82527734SSukumar Swaminathan 2529*82527734SSukumar Swaminathan return (rc); 2530*82527734SSukumar Swaminathan 2531*82527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd() */ 2532*82527734SSukumar Swaminathan 2533*82527734SSukumar Swaminathan 2534*82527734SSukumar Swaminathan 2535*82527734SSukumar Swaminathan /*ARGSUSED*/ 2536*82527734SSukumar Swaminathan static uint32_t 2537*82527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 2538*82527734SSukumar Swaminathan uint32_t tmo) 2539*82527734SSukumar Swaminathan { 2540*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 2541*82527734SSukumar Swaminathan MAILBOX *mb; 2542*82527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 2543*82527734SSukumar Swaminathan MATCHMAP *mp; 2544*82527734SSukumar Swaminathan uint32_t rc; 2545*82527734SSukumar Swaminathan uint32_t tmo_local; 2546*82527734SSukumar Swaminathan 2547*82527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 2548*82527734SSukumar Swaminathan 2549*82527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 2550*82527734SSukumar Swaminathan rc = MBX_SUCCESS; 2551*82527734SSukumar Swaminathan 2552*82527734SSukumar Swaminathan if (tmo < 30) { 2553*82527734SSukumar Swaminathan tmo = 30; 2554*82527734SSukumar Swaminathan } 2555*82527734SSukumar Swaminathan 2556*82527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 2557*82527734SSukumar Swaminathan tmo_local = tmo * 100; 2558*82527734SSukumar Swaminathan 2559*82527734SSukumar Swaminathan flag = MBX_POLL; 2560*82527734SSukumar Swaminathan 2561*82527734SSukumar Swaminathan /* Check for hardware error */ 2562*82527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 2563*82527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 2564*82527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 2565*82527734SSukumar Swaminathan } 2566*82527734SSukumar Swaminathan 2567*82527734SSukumar Swaminathan /* Initialize mailbox area */ 2568*82527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 2569*82527734SSukumar Swaminathan 2570*82527734SSukumar Swaminathan switch (flag) { 2571*82527734SSukumar Swaminathan 2572*82527734SSukumar Swaminathan case MBX_POLL: 2573*82527734SSukumar Swaminathan 2574*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 2575*82527734SSukumar Swaminathan 2576*82527734SSukumar Swaminathan /* Clean up the mailbox area */ 2577*82527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 2578*82527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 2579*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 2580*82527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 2581*82527734SSukumar Swaminathan 2582*82527734SSukumar Swaminathan } else { 2583*82527734SSukumar Swaminathan /* Process the result */ 2584*82527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 2585*82527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 2586*82527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 2587*82527734SSukumar Swaminathan } 2588*82527734SSukumar Swaminathan } 2589*82527734SSukumar Swaminathan 2590*82527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 2591*82527734SSukumar Swaminathan } 2592*82527734SSukumar Swaminathan 2593*82527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 2594*82527734SSukumar Swaminathan if (mp) { 2595*82527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 2596*82527734SSukumar Swaminathan if (hdr_rsp->status) { 2597*82527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 2598*82527734SSukumar Swaminathan } 2599*82527734SSukumar Swaminathan } 2600*82527734SSukumar Swaminathan rc = mb->mbxStatus; 2601*82527734SSukumar Swaminathan 2602*82527734SSukumar Swaminathan break; 2603*82527734SSukumar Swaminathan } 2604*82527734SSukumar Swaminathan 2605*82527734SSukumar Swaminathan return (rc); 2606*82527734SSukumar Swaminathan 2607*82527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd4quiesce() */ 2608*82527734SSukumar Swaminathan 2609*82527734SSukumar Swaminathan 2610*82527734SSukumar Swaminathan 2611*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 2612*82527734SSukumar Swaminathan /*ARGSUSED*/ 2613*82527734SSukumar Swaminathan static uint32_t 2614*82527734SSukumar Swaminathan emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, emlxs_buf_t *cmd_sbp, int channel) 2615*82527734SSukumar Swaminathan { 2616*82527734SSukumar Swaminathan return (IOERR_NO_RESOURCES); 2617*82527734SSukumar Swaminathan 2618*82527734SSukumar Swaminathan } /* emlxs_sli4_prep_fct_iocb() */ 2619*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 2620*82527734SSukumar Swaminathan 2621*82527734SSukumar Swaminathan 2622*82527734SSukumar Swaminathan /*ARGSUSED*/ 2623*82527734SSukumar Swaminathan extern uint32_t 2624*82527734SSukumar Swaminathan emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel) 2625*82527734SSukumar Swaminathan { 2626*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2627*82527734SSukumar Swaminathan fc_packet_t *pkt; 2628*82527734SSukumar Swaminathan CHANNEL *cp; 2629*82527734SSukumar Swaminathan RPIobj_t *rp; 2630*82527734SSukumar Swaminathan XRIobj_t *xp; 2631*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 2632*82527734SSukumar Swaminathan IOCBQ *iocbq; 2633*82527734SSukumar Swaminathan NODELIST *node; 2634*82527734SSukumar Swaminathan uint16_t iotag; 2635*82527734SSukumar Swaminathan uint32_t did; 2636*82527734SSukumar Swaminathan 2637*82527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 2638*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2639*82527734SSukumar Swaminathan cp = &hba->chan[channel]; 2640*82527734SSukumar Swaminathan 2641*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 2642*82527734SSukumar Swaminathan iocbq->channel = (void *) cp; 2643*82527734SSukumar Swaminathan iocbq->port = (void *) port; 2644*82527734SSukumar Swaminathan 2645*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 2646*82527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 2647*82527734SSukumar Swaminathan 2648*82527734SSukumar Swaminathan /* Find target node object */ 2649*82527734SSukumar Swaminathan node = (NODELIST *)iocbq->node; 2650*82527734SSukumar Swaminathan rp = EMLXS_NODE_TO_RPI(hba, node); 2651*82527734SSukumar Swaminathan 2652*82527734SSukumar Swaminathan if (!rp) { 2653*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 2654*82527734SSukumar Swaminathan "Unable to find rpi. did=0x%x", did); 2655*82527734SSukumar Swaminathan 2656*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 2657*82527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 2658*82527734SSukumar Swaminathan return (0xff); 2659*82527734SSukumar Swaminathan } 2660*82527734SSukumar Swaminathan 2661*82527734SSukumar Swaminathan sbp->channel = cp; 2662*82527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 2663*82527734SSukumar Swaminathan xp = emlxs_sli4_alloc_xri(hba, sbp, rp); 2664*82527734SSukumar Swaminathan 2665*82527734SSukumar Swaminathan if (!xp) { 2666*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 2667*82527734SSukumar Swaminathan "Adapter Busy. Unable to allocate exchange. did=0x%x", did); 2668*82527734SSukumar Swaminathan 2669*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 2670*82527734SSukumar Swaminathan } 2671*82527734SSukumar Swaminathan sbp->bmp = NULL; 2672*82527734SSukumar Swaminathan iotag = sbp->iotag; 2673*82527734SSukumar Swaminathan 2674*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 2675*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, /* DEBUG */ 2676*82527734SSukumar Swaminathan "Prep FCP iotag: %x xri: %x", iotag, xp->XRI); 2677*82527734SSukumar Swaminathan #endif 2678*82527734SSukumar Swaminathan 2679*82527734SSukumar Swaminathan /* Indicate this is a FCP cmd */ 2680*82527734SSukumar Swaminathan iocbq->flag |= IOCB_FCP_CMD; 2681*82527734SSukumar Swaminathan 2682*82527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 2683*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, xp); 2684*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 2685*82527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 2686*82527734SSukumar Swaminathan 2687*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 2688*82527734SSukumar Swaminathan } 2689*82527734SSukumar Swaminathan 2690*82527734SSukumar Swaminathan 2691*82527734SSukumar Swaminathan /* DEBUG */ 2692*82527734SSukumar Swaminathan #ifdef DEBUG_FCP 2693*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2694*82527734SSukumar Swaminathan "SGLaddr virt %p phys %p size %d", xp->SGList.virt, 2695*82527734SSukumar Swaminathan xp->SGList.phys, pkt->pkt_datalen); 2696*82527734SSukumar Swaminathan emlxs_data_dump(hba, "SGL", (uint32_t *)xp->SGList.virt, 20, 0); 2697*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2698*82527734SSukumar Swaminathan "CMD virt %p len %d:%d:%d", 2699*82527734SSukumar Swaminathan pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen, pkt->pkt_datalen); 2700*82527734SSukumar Swaminathan emlxs_data_dump(hba, "FCP CMD", (uint32_t *)pkt->pkt_cmd, 10, 0); 2701*82527734SSukumar Swaminathan #endif 2702*82527734SSukumar Swaminathan 2703*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0, 2704*82527734SSukumar Swaminathan xp->SGList.size, DDI_DMA_SYNC_FORDEV); 2705*82527734SSukumar Swaminathan 2706*82527734SSukumar Swaminathan /* if device is FCP-2 device, set the following bit */ 2707*82527734SSukumar Swaminathan /* that says to run the FC-TAPE protocol. */ 2708*82527734SSukumar Swaminathan if (node->nlp_fcp_info & NLP_FCP_2_DEVICE) { 2709*82527734SSukumar Swaminathan wqe->ERP = 1; 2710*82527734SSukumar Swaminathan } 2711*82527734SSukumar Swaminathan 2712*82527734SSukumar Swaminathan if (pkt->pkt_datalen == 0) { 2713*82527734SSukumar Swaminathan wqe->Command = CMD_FCP_ICMND64_CR; 2714*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 2715*82527734SSukumar Swaminathan } else if (pkt->pkt_tran_type == FC_PKT_FCP_READ) { 2716*82527734SSukumar Swaminathan wqe->Command = CMD_FCP_IREAD64_CR; 2717*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 2718*82527734SSukumar Swaminathan wqe->PU = PARM_READ_CHECK; 2719*82527734SSukumar Swaminathan } else { 2720*82527734SSukumar Swaminathan wqe->Command = CMD_FCP_IWRITE64_CR; 2721*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_OUT; 2722*82527734SSukumar Swaminathan } 2723*82527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount = pkt->pkt_datalen; 2724*82527734SSukumar Swaminathan 2725*82527734SSukumar Swaminathan wqe->ContextTag = rp->RPI; 2726*82527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 2727*82527734SSukumar Swaminathan wqe->XRITag = xp->XRI; 2728*82527734SSukumar Swaminathan wqe->Timer = 2729*82527734SSukumar Swaminathan ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 2730*82527734SSukumar Swaminathan 2731*82527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 2732*82527734SSukumar Swaminathan wqe->CCPE = 1; 2733*82527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 2734*82527734SSukumar Swaminathan } 2735*82527734SSukumar Swaminathan 2736*82527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 2737*82527734SSukumar Swaminathan case FC_TRAN_CLASS2: 2738*82527734SSukumar Swaminathan wqe->Class = CLASS2; 2739*82527734SSukumar Swaminathan break; 2740*82527734SSukumar Swaminathan case FC_TRAN_CLASS3: 2741*82527734SSukumar Swaminathan default: 2742*82527734SSukumar Swaminathan wqe->Class = CLASS3; 2743*82527734SSukumar Swaminathan break; 2744*82527734SSukumar Swaminathan } 2745*82527734SSukumar Swaminathan sbp->class = wqe->Class; 2746*82527734SSukumar Swaminathan wqe->RequestTag = iotag; 2747*82527734SSukumar Swaminathan wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 2748*82527734SSukumar Swaminathan return (FC_SUCCESS); 2749*82527734SSukumar Swaminathan } /* emlxs_sli4_prep_fcp_iocb() */ 2750*82527734SSukumar Swaminathan 2751*82527734SSukumar Swaminathan 2752*82527734SSukumar Swaminathan /*ARGSUSED*/ 2753*82527734SSukumar Swaminathan static uint32_t 2754*82527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 2755*82527734SSukumar Swaminathan { 2756*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 2757*82527734SSukumar Swaminathan 2758*82527734SSukumar Swaminathan } /* emlxs_sli4_prep_ip_iocb() */ 2759*82527734SSukumar Swaminathan 2760*82527734SSukumar Swaminathan 2761*82527734SSukumar Swaminathan /*ARGSUSED*/ 2762*82527734SSukumar Swaminathan static uint32_t 2763*82527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 2764*82527734SSukumar Swaminathan { 2765*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2766*82527734SSukumar Swaminathan fc_packet_t *pkt; 2767*82527734SSukumar Swaminathan IOCBQ *iocbq; 2768*82527734SSukumar Swaminathan IOCB *iocb; 2769*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 2770*82527734SSukumar Swaminathan FCFIobj_t *fp; 2771*82527734SSukumar Swaminathan RPIobj_t *rp = NULL; 2772*82527734SSukumar Swaminathan XRIobj_t *xp; 2773*82527734SSukumar Swaminathan CHANNEL *cp; 2774*82527734SSukumar Swaminathan uint32_t did; 2775*82527734SSukumar Swaminathan uint32_t cmd; 2776*82527734SSukumar Swaminathan ULP_SGE64 stage_sge; 2777*82527734SSukumar Swaminathan ULP_SGE64 *sge; 2778*82527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 2779*82527734SSukumar Swaminathan ddi_dma_cookie_t *cp_resp; 2780*82527734SSukumar Swaminathan emlxs_node_t *node; 2781*82527734SSukumar Swaminathan 2782*82527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 2783*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 2784*82527734SSukumar Swaminathan 2785*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 2786*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 2787*82527734SSukumar Swaminathan iocb = &iocbq->iocb; 2788*82527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 2789*82527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 2790*82527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 2791*82527734SSukumar Swaminathan 2792*82527734SSukumar Swaminathan /* Initalize iocbq */ 2793*82527734SSukumar Swaminathan iocbq->port = (void *) port; 2794*82527734SSukumar Swaminathan iocbq->channel = (void *) cp; 2795*82527734SSukumar Swaminathan 2796*82527734SSukumar Swaminathan sbp->channel = cp; 2797*82527734SSukumar Swaminathan sbp->bmp = NULL; 2798*82527734SSukumar Swaminathan 2799*82527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 2800*82527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 2801*82527734SSukumar Swaminathan cp_resp = pkt->pkt_resp_cookie; 2802*82527734SSukumar Swaminathan #else 2803*82527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 2804*82527734SSukumar Swaminathan cp_resp = &pkt->pkt_resp_cookie; 2805*82527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 2806*82527734SSukumar Swaminathan 2807*82527734SSukumar Swaminathan /* CMD payload */ 2808*82527734SSukumar Swaminathan sge = &stage_sge; 2809*82527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_cmd->dmac_laddress); 2810*82527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_cmd->dmac_laddress); 2811*82527734SSukumar Swaminathan sge->length = pkt->pkt_cmdlen; 2812*82527734SSukumar Swaminathan sge->offset = 0; 2813*82527734SSukumar Swaminathan 2814*82527734SSukumar Swaminathan /* Initalize iocb */ 2815*82527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 2816*82527734SSukumar Swaminathan /* ELS Response */ 2817*82527734SSukumar Swaminathan 2818*82527734SSukumar Swaminathan xp = emlxs_sli4_register_xri(hba, sbp, pkt->pkt_cmd_fhdr.rx_id); 2819*82527734SSukumar Swaminathan 2820*82527734SSukumar Swaminathan if (!xp) { 2821*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 2822*82527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 2823*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 2824*82527734SSukumar Swaminathan 2825*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 2826*82527734SSukumar Swaminathan IOERR_NO_XRI, 0); 2827*82527734SSukumar Swaminathan return (0xff); 2828*82527734SSukumar Swaminathan } 2829*82527734SSukumar Swaminathan 2830*82527734SSukumar Swaminathan rp = xp->RPIp; 2831*82527734SSukumar Swaminathan 2832*82527734SSukumar Swaminathan if (!rp) { 2833*82527734SSukumar Swaminathan /* This means that we had a node registered */ 2834*82527734SSukumar Swaminathan /* when the unsol request came in but the node */ 2835*82527734SSukumar Swaminathan /* has since been unregistered. */ 2836*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 2837*82527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 2838*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 2839*82527734SSukumar Swaminathan 2840*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 2841*82527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 2842*82527734SSukumar Swaminathan return (0xff); 2843*82527734SSukumar Swaminathan } 2844*82527734SSukumar Swaminathan 2845*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2846*82527734SSukumar Swaminathan "Prep ELS XRI: xri=%x iotag=%x oxid=%x rpi=%x", 2847*82527734SSukumar Swaminathan xp->XRI, xp->iotag, xp->rx_id, rp->RPI); 2848*82527734SSukumar Swaminathan 2849*82527734SSukumar Swaminathan wqe->Command = CMD_XMIT_ELS_RSP64_CX; 2850*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 2851*82527734SSukumar Swaminathan 2852*82527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrHigh = sge->addrHigh; 2853*82527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrLow = sge->addrLow; 2854*82527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 2855*82527734SSukumar Swaminathan 2856*82527734SSukumar Swaminathan wqe->un.ElsRsp.RemoteId = did; 2857*82527734SSukumar Swaminathan wqe->PU = 0x3; 2858*82527734SSukumar Swaminathan 2859*82527734SSukumar Swaminathan sge->last = 1; 2860*82527734SSukumar Swaminathan /* Now sge is fully staged */ 2861*82527734SSukumar Swaminathan 2862*82527734SSukumar Swaminathan sge = xp->SGList.virt; 2863*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 2864*82527734SSukumar Swaminathan sizeof (ULP_SGE64)); 2865*82527734SSukumar Swaminathan 2866*82527734SSukumar Swaminathan wqe->ContextTag = port->vpi + hba->vpi_base; 2867*82527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 2868*82527734SSukumar Swaminathan wqe->OXId = xp->rx_id; 2869*82527734SSukumar Swaminathan 2870*82527734SSukumar Swaminathan } else { 2871*82527734SSukumar Swaminathan /* ELS Request */ 2872*82527734SSukumar Swaminathan 2873*82527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 2874*82527734SSukumar Swaminathan rp = EMLXS_NODE_TO_RPI(hba, node); 2875*82527734SSukumar Swaminathan 2876*82527734SSukumar Swaminathan if (!rp) { 2877*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 2878*82527734SSukumar Swaminathan rp = &fp->scratch_rpi; 2879*82527734SSukumar Swaminathan } 2880*82527734SSukumar Swaminathan 2881*82527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 2882*82527734SSukumar Swaminathan xp = emlxs_sli4_alloc_xri(hba, sbp, rp); 2883*82527734SSukumar Swaminathan 2884*82527734SSukumar Swaminathan if (!xp) { 2885*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 2886*82527734SSukumar Swaminathan "Adapter Busy. Unable to allocate exchange. " \ 2887*82527734SSukumar Swaminathan "did=0x%x", did); 2888*82527734SSukumar Swaminathan 2889*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 2890*82527734SSukumar Swaminathan } 2891*82527734SSukumar Swaminathan 2892*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2893*82527734SSukumar Swaminathan "Prep ELS XRI: xri=%x iotag=%x rpi=%x", xp->XRI, 2894*82527734SSukumar Swaminathan xp->iotag, rp->RPI); 2895*82527734SSukumar Swaminathan 2896*82527734SSukumar Swaminathan wqe->Command = CMD_ELS_REQUEST64_CR; 2897*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_ELS; 2898*82527734SSukumar Swaminathan 2899*82527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrHigh = sge->addrHigh; 2900*82527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrLow = sge->addrLow; 2901*82527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 2902*82527734SSukumar Swaminathan 2903*82527734SSukumar Swaminathan /* setup for rsp */ 2904*82527734SSukumar Swaminathan iocb->un.elsreq64.remoteID = (did == BCAST_DID) ? 0 : did; 2905*82527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 2906*82527734SSukumar Swaminathan 2907*82527734SSukumar Swaminathan sge->last = 0; 2908*82527734SSukumar Swaminathan 2909*82527734SSukumar Swaminathan sge = xp->SGList.virt; 2910*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 2911*82527734SSukumar Swaminathan sizeof (ULP_SGE64)); 2912*82527734SSukumar Swaminathan 2913*82527734SSukumar Swaminathan wqe->un.ElsCmd.PayloadLength = 2914*82527734SSukumar Swaminathan pkt->pkt_cmdlen; /* Byte offset of rsp data */ 2915*82527734SSukumar Swaminathan 2916*82527734SSukumar Swaminathan /* RSP payload */ 2917*82527734SSukumar Swaminathan sge = &stage_sge; 2918*82527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_resp->dmac_laddress); 2919*82527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_resp->dmac_laddress); 2920*82527734SSukumar Swaminathan sge->length = pkt->pkt_rsplen; 2921*82527734SSukumar Swaminathan sge->offset = pkt->pkt_cmdlen; 2922*82527734SSukumar Swaminathan sge->last = 1; 2923*82527734SSukumar Swaminathan /* Now sge is fully staged */ 2924*82527734SSukumar Swaminathan 2925*82527734SSukumar Swaminathan sge = xp->SGList.virt; 2926*82527734SSukumar Swaminathan sge++; 2927*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 2928*82527734SSukumar Swaminathan sizeof (ULP_SGE64)); 2929*82527734SSukumar Swaminathan #ifdef DEBUG_ELS 2930*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2931*82527734SSukumar Swaminathan "SGLaddr virt %p phys %p", 2932*82527734SSukumar Swaminathan xp->SGList.virt, xp->SGList.phys); 2933*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2934*82527734SSukumar Swaminathan "PAYLOAD virt %p phys %p", 2935*82527734SSukumar Swaminathan pkt->pkt_cmd, cp_cmd->dmac_laddress); 2936*82527734SSukumar Swaminathan emlxs_data_dump(hba, "SGL", (uint32_t *)xp->SGList.virt, 12, 0); 2937*82527734SSukumar Swaminathan #endif 2938*82527734SSukumar Swaminathan 2939*82527734SSukumar Swaminathan cmd = *((uint32_t *)pkt->pkt_cmd); 2940*82527734SSukumar Swaminathan cmd &= ELS_CMD_MASK; 2941*82527734SSukumar Swaminathan 2942*82527734SSukumar Swaminathan switch (cmd) { 2943*82527734SSukumar Swaminathan case ELS_CMD_FLOGI: 2944*82527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 2945*82527734SSukumar Swaminathan wqe->ContextTag = fp->FCFI; 2946*82527734SSukumar Swaminathan wqe->ContextType = WQE_FCFI_CONTEXT; 2947*82527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 2948*82527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 2949*82527734SSukumar Swaminathan wqe->ELSId |= WQE_ELSID_FLOGI; 2950*82527734SSukumar Swaminathan } 2951*82527734SSukumar Swaminathan break; 2952*82527734SSukumar Swaminathan case ELS_CMD_FDISC: 2953*82527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 2954*82527734SSukumar Swaminathan wqe->ContextTag = port->vpi + hba->vpi_base; 2955*82527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 2956*82527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 2957*82527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 2958*82527734SSukumar Swaminathan wqe->ELSId |= WQE_ELSID_FDISC; 2959*82527734SSukumar Swaminathan } 2960*82527734SSukumar Swaminathan break; 2961*82527734SSukumar Swaminathan case ELS_CMD_LOGO: 2962*82527734SSukumar Swaminathan wqe->ContextTag = port->vpi + hba->vpi_base; 2963*82527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 2964*82527734SSukumar Swaminathan if ((hba->flag & FC_FIP_SUPPORTED) && 2965*82527734SSukumar Swaminathan (did == FABRIC_DID)) { 2966*82527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 2967*82527734SSukumar Swaminathan wqe->ELSId |= WQE_ELSID_LOGO; 2968*82527734SSukumar Swaminathan } 2969*82527734SSukumar Swaminathan break; 2970*82527734SSukumar Swaminathan 2971*82527734SSukumar Swaminathan case ELS_CMD_SCR: 2972*82527734SSukumar Swaminathan case ELS_CMD_PLOGI: 2973*82527734SSukumar Swaminathan case ELS_CMD_PRLI: 2974*82527734SSukumar Swaminathan default: 2975*82527734SSukumar Swaminathan wqe->ContextTag = port->vpi + hba->vpi_base; 2976*82527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 2977*82527734SSukumar Swaminathan break; 2978*82527734SSukumar Swaminathan } 2979*82527734SSukumar Swaminathan wqe->un.ElsCmd.RemoteId = did; 2980*82527734SSukumar Swaminathan wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 2981*82527734SSukumar Swaminathan } 2982*82527734SSukumar Swaminathan 2983*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0, 2984*82527734SSukumar Swaminathan xp->SGList.size, DDI_DMA_SYNC_FORDEV); 2985*82527734SSukumar Swaminathan 2986*82527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 2987*82527734SSukumar Swaminathan wqe->CCPE = 1; 2988*82527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 2989*82527734SSukumar Swaminathan } 2990*82527734SSukumar Swaminathan 2991*82527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 2992*82527734SSukumar Swaminathan case FC_TRAN_CLASS2: 2993*82527734SSukumar Swaminathan wqe->Class = CLASS2; 2994*82527734SSukumar Swaminathan break; 2995*82527734SSukumar Swaminathan case FC_TRAN_CLASS3: 2996*82527734SSukumar Swaminathan default: 2997*82527734SSukumar Swaminathan wqe->Class = CLASS3; 2998*82527734SSukumar Swaminathan break; 2999*82527734SSukumar Swaminathan } 3000*82527734SSukumar Swaminathan sbp->class = wqe->Class; 3001*82527734SSukumar Swaminathan wqe->XRITag = xp->XRI; 3002*82527734SSukumar Swaminathan wqe->RequestTag = xp->iotag; 3003*82527734SSukumar Swaminathan wqe->CQId = 0x3ff; 3004*82527734SSukumar Swaminathan return (FC_SUCCESS); 3005*82527734SSukumar Swaminathan 3006*82527734SSukumar Swaminathan } /* emlxs_sli4_prep_els_iocb() */ 3007*82527734SSukumar Swaminathan 3008*82527734SSukumar Swaminathan 3009*82527734SSukumar Swaminathan /*ARGSUSED*/ 3010*82527734SSukumar Swaminathan static uint32_t 3011*82527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 3012*82527734SSukumar Swaminathan { 3013*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 3014*82527734SSukumar Swaminathan fc_packet_t *pkt; 3015*82527734SSukumar Swaminathan IOCBQ *iocbq; 3016*82527734SSukumar Swaminathan IOCB *iocb; 3017*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 3018*82527734SSukumar Swaminathan NODELIST *node = NULL; 3019*82527734SSukumar Swaminathan CHANNEL *cp; 3020*82527734SSukumar Swaminathan RPIobj_t *rp; 3021*82527734SSukumar Swaminathan XRIobj_t *xp; 3022*82527734SSukumar Swaminathan uint32_t did; 3023*82527734SSukumar Swaminathan 3024*82527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 3025*82527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 3026*82527734SSukumar Swaminathan 3027*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 3028*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 3029*82527734SSukumar Swaminathan iocb = &iocbq->iocb; 3030*82527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 3031*82527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 3032*82527734SSukumar Swaminathan 3033*82527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 3034*82527734SSukumar Swaminathan 3035*82527734SSukumar Swaminathan iocbq->port = (void *) port; 3036*82527734SSukumar Swaminathan iocbq->channel = (void *) cp; 3037*82527734SSukumar Swaminathan 3038*82527734SSukumar Swaminathan sbp->bmp = NULL; 3039*82527734SSukumar Swaminathan sbp->channel = cp; 3040*82527734SSukumar Swaminathan 3041*82527734SSukumar Swaminathan /* Initalize wqe */ 3042*82527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 3043*82527734SSukumar Swaminathan /* CT Response */ 3044*82527734SSukumar Swaminathan 3045*82527734SSukumar Swaminathan xp = emlxs_sli4_register_xri(hba, sbp, pkt->pkt_cmd_fhdr.rx_id); 3046*82527734SSukumar Swaminathan 3047*82527734SSukumar Swaminathan if (!xp) { 3048*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 3049*82527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 3050*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 3051*82527734SSukumar Swaminathan 3052*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 3053*82527734SSukumar Swaminathan IOERR_NO_XRI, 0); 3054*82527734SSukumar Swaminathan return (0xff); 3055*82527734SSukumar Swaminathan } 3056*82527734SSukumar Swaminathan 3057*82527734SSukumar Swaminathan rp = xp->RPIp; 3058*82527734SSukumar Swaminathan 3059*82527734SSukumar Swaminathan if (!rp) { 3060*82527734SSukumar Swaminathan /* This means that we had a node registered */ 3061*82527734SSukumar Swaminathan /* when the unsol request came in but the node */ 3062*82527734SSukumar Swaminathan /* has since been unregistered. */ 3063*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 3064*82527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 3065*82527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 3066*82527734SSukumar Swaminathan 3067*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 3068*82527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 3069*82527734SSukumar Swaminathan return (0xff); 3070*82527734SSukumar Swaminathan } 3071*82527734SSukumar Swaminathan 3072*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3073*82527734SSukumar Swaminathan "Prep CT XRI: xri=%x iotag=%x oxid=%x", xp->XRI, 3074*82527734SSukumar Swaminathan xp->iotag, xp->rx_id); 3075*82527734SSukumar Swaminathan 3076*82527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 3077*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3078*82527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 3079*82527734SSukumar Swaminathan 3080*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 3081*82527734SSukumar Swaminathan } 3082*82527734SSukumar Swaminathan 3083*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 3084*82527734SSukumar Swaminathan wqe->Command = CMD_XMIT_SEQUENCE64_CR; 3085*82527734SSukumar Swaminathan wqe->un.XmitSeq.la = 1; 3086*82527734SSukumar Swaminathan 3087*82527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_LAST_SEQ) { 3088*82527734SSukumar Swaminathan wqe->un.XmitSeq.ls = 1; 3089*82527734SSukumar Swaminathan } 3090*82527734SSukumar Swaminathan 3091*82527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_SEQ_INITIATIVE) { 3092*82527734SSukumar Swaminathan wqe->un.XmitSeq.si = 1; 3093*82527734SSukumar Swaminathan } 3094*82527734SSukumar Swaminathan 3095*82527734SSukumar Swaminathan wqe->un.XmitSeq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 3096*82527734SSukumar Swaminathan wqe->un.XmitSeq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 3097*82527734SSukumar Swaminathan wqe->un.XmitSeq.Type = pkt->pkt_cmd_fhdr.type; 3098*82527734SSukumar Swaminathan wqe->OXId = xp->rx_id; 3099*82527734SSukumar Swaminathan wqe->XC = 1; 3100*82527734SSukumar Swaminathan wqe->CmdSpecific[0] = wqe->un.GenReq.Payload.tus.f.bdeSize; 3101*82527734SSukumar Swaminathan 3102*82527734SSukumar Swaminathan } else { 3103*82527734SSukumar Swaminathan /* CT Request */ 3104*82527734SSukumar Swaminathan 3105*82527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 3106*82527734SSukumar Swaminathan rp = EMLXS_NODE_TO_RPI(hba, node); 3107*82527734SSukumar Swaminathan 3108*82527734SSukumar Swaminathan if (!rp) { 3109*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 3110*82527734SSukumar Swaminathan "Unable to find rpi. did=0x%x", did); 3111*82527734SSukumar Swaminathan 3112*82527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 3113*82527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 3114*82527734SSukumar Swaminathan return (0xff); 3115*82527734SSukumar Swaminathan } 3116*82527734SSukumar Swaminathan 3117*82527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 3118*82527734SSukumar Swaminathan xp = emlxs_sli4_alloc_xri(hba, sbp, rp); 3119*82527734SSukumar Swaminathan 3120*82527734SSukumar Swaminathan if (!xp) { 3121*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3122*82527734SSukumar Swaminathan "Adapter Busy. Unable to allocate exchange. " \ 3123*82527734SSukumar Swaminathan "did=0x%x", did); 3124*82527734SSukumar Swaminathan 3125*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 3126*82527734SSukumar Swaminathan } 3127*82527734SSukumar Swaminathan 3128*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3129*82527734SSukumar Swaminathan "Prep CT XRI: %x iotag %x", xp->XRI, xp->iotag); 3130*82527734SSukumar Swaminathan 3131*82527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 3132*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3133*82527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 3134*82527734SSukumar Swaminathan 3135*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, xp); 3136*82527734SSukumar Swaminathan return (FC_TRAN_BUSY); 3137*82527734SSukumar Swaminathan } 3138*82527734SSukumar Swaminathan 3139*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 3140*82527734SSukumar Swaminathan wqe->Command = CMD_GEN_REQUEST64_CR; 3141*82527734SSukumar Swaminathan wqe->un.GenReq.la = 1; 3142*82527734SSukumar Swaminathan wqe->un.GenReq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 3143*82527734SSukumar Swaminathan wqe->un.GenReq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 3144*82527734SSukumar Swaminathan wqe->un.GenReq.Type = pkt->pkt_cmd_fhdr.type; 3145*82527734SSukumar Swaminathan wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 3146*82527734SSukumar Swaminathan 3147*82527734SSukumar Swaminathan #ifdef DEBUG_CT 3148*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3149*82527734SSukumar Swaminathan "SGLaddr virt %p phys %p", xp->SGList.virt, 3150*82527734SSukumar Swaminathan xp->SGList.phys); 3151*82527734SSukumar Swaminathan emlxs_data_dump(hba, "SGL", (uint32_t *)xp->SGList.virt, 12, 0); 3152*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3153*82527734SSukumar Swaminathan "CMD virt %p len %d:%d", 3154*82527734SSukumar Swaminathan pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen); 3155*82527734SSukumar Swaminathan emlxs_data_dump(hba, "DATA", (uint32_t *)pkt->pkt_cmd, 20, 0); 3156*82527734SSukumar Swaminathan #endif /* DEBUG_CT */ 3157*82527734SSukumar Swaminathan } 3158*82527734SSukumar Swaminathan 3159*82527734SSukumar Swaminathan /* Setup for rsp */ 3160*82527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 3161*82527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Type = pkt->pkt_cmd_fhdr.type; 3162*82527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Dfctl = pkt->pkt_cmd_fhdr.df_ctl; 3163*82527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 3164*82527734SSukumar Swaminathan 3165*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(xp->SGList.dma_handle, 0, 3166*82527734SSukumar Swaminathan xp->SGList.size, DDI_DMA_SYNC_FORDEV); 3167*82527734SSukumar Swaminathan 3168*82527734SSukumar Swaminathan wqe->ContextTag = rp->RPI; 3169*82527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 3170*82527734SSukumar Swaminathan wqe->XRITag = xp->XRI; 3171*82527734SSukumar Swaminathan 3172*82527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 3173*82527734SSukumar Swaminathan wqe->CCPE = 1; 3174*82527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 3175*82527734SSukumar Swaminathan } 3176*82527734SSukumar Swaminathan 3177*82527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 3178*82527734SSukumar Swaminathan case FC_TRAN_CLASS2: 3179*82527734SSukumar Swaminathan wqe->Class = CLASS2; 3180*82527734SSukumar Swaminathan break; 3181*82527734SSukumar Swaminathan case FC_TRAN_CLASS3: 3182*82527734SSukumar Swaminathan default: 3183*82527734SSukumar Swaminathan wqe->Class = CLASS3; 3184*82527734SSukumar Swaminathan break; 3185*82527734SSukumar Swaminathan } 3186*82527734SSukumar Swaminathan sbp->class = wqe->Class; 3187*82527734SSukumar Swaminathan wqe->RequestTag = xp->iotag; 3188*82527734SSukumar Swaminathan wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 3189*82527734SSukumar Swaminathan return (FC_SUCCESS); 3190*82527734SSukumar Swaminathan 3191*82527734SSukumar Swaminathan } /* emlxs_sli4_prep_ct_iocb() */ 3192*82527734SSukumar Swaminathan 3193*82527734SSukumar Swaminathan 3194*82527734SSukumar Swaminathan /*ARGSUSED*/ 3195*82527734SSukumar Swaminathan static int 3196*82527734SSukumar Swaminathan emlxs_sli4_poll_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 3197*82527734SSukumar Swaminathan { 3198*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3199*82527734SSukumar Swaminathan uint32_t *ptr; 3200*82527734SSukumar Swaminathan int num_entries = 0; 3201*82527734SSukumar Swaminathan EQE_u eqe; 3202*82527734SSukumar Swaminathan uint32_t host_index, shost_index; 3203*82527734SSukumar Swaminathan int rc = 0; 3204*82527734SSukumar Swaminathan 3205*82527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 3206*82527734SSukumar Swaminathan ptr = eq->addr.virt; 3207*82527734SSukumar Swaminathan ptr += eq->host_index; 3208*82527734SSukumar Swaminathan host_index = eq->host_index; 3209*82527734SSukumar Swaminathan 3210*82527734SSukumar Swaminathan shost_index = host_index; 3211*82527734SSukumar Swaminathan 3212*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, 0, 3213*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 3214*82527734SSukumar Swaminathan 3215*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 3216*82527734SSukumar Swaminathan 3217*82527734SSukumar Swaminathan for (;;) { 3218*82527734SSukumar Swaminathan eqe.word = *ptr; 3219*82527734SSukumar Swaminathan eqe.word = BE_SWAP32(eqe.word); 3220*82527734SSukumar Swaminathan 3221*82527734SSukumar Swaminathan if (eqe.word & EQE_VALID) { 3222*82527734SSukumar Swaminathan rc = 1; 3223*82527734SSukumar Swaminathan break; 3224*82527734SSukumar Swaminathan } 3225*82527734SSukumar Swaminathan 3226*82527734SSukumar Swaminathan *ptr = 0; 3227*82527734SSukumar Swaminathan num_entries++; 3228*82527734SSukumar Swaminathan host_index++; 3229*82527734SSukumar Swaminathan if (host_index >= eq->max_index) { 3230*82527734SSukumar Swaminathan host_index = 0; 3231*82527734SSukumar Swaminathan ptr = eq->addr.virt; 3232*82527734SSukumar Swaminathan } else { 3233*82527734SSukumar Swaminathan ptr++; 3234*82527734SSukumar Swaminathan } 3235*82527734SSukumar Swaminathan 3236*82527734SSukumar Swaminathan if (host_index == shost_index) { 3237*82527734SSukumar Swaminathan /* We donot need to loop forever */ 3238*82527734SSukumar Swaminathan break; 3239*82527734SSukumar Swaminathan } 3240*82527734SSukumar Swaminathan } 3241*82527734SSukumar Swaminathan 3242*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 3243*82527734SSukumar Swaminathan 3244*82527734SSukumar Swaminathan return (rc); 3245*82527734SSukumar Swaminathan 3246*82527734SSukumar Swaminathan } /* emlxs_sli4_poll_eq */ 3247*82527734SSukumar Swaminathan 3248*82527734SSukumar Swaminathan 3249*82527734SSukumar Swaminathan /*ARGSUSED*/ 3250*82527734SSukumar Swaminathan static void 3251*82527734SSukumar Swaminathan emlxs_sli4_poll_intr(emlxs_hba_t *hba, uint32_t att_bit) 3252*82527734SSukumar Swaminathan { 3253*82527734SSukumar Swaminathan int rc = 0; 3254*82527734SSukumar Swaminathan int i; 3255*82527734SSukumar Swaminathan char arg[] = {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}; 3256*82527734SSukumar Swaminathan char arg2; 3257*82527734SSukumar Swaminathan 3258*82527734SSukumar Swaminathan /* 3259*82527734SSukumar Swaminathan * Poll the eqe to see if the valid bit is set or not 3260*82527734SSukumar Swaminathan */ 3261*82527734SSukumar Swaminathan 3262*82527734SSukumar Swaminathan for (;;) { 3263*82527734SSukumar Swaminathan if (hba->intr_type == DDI_INTR_TYPE_FIXED) { 3264*82527734SSukumar Swaminathan /* only poll eqe0 */ 3265*82527734SSukumar Swaminathan rc = emlxs_sli4_poll_eq(hba, 3266*82527734SSukumar Swaminathan &hba->sli.sli4.eq[0]); 3267*82527734SSukumar Swaminathan if (rc == 1) { 3268*82527734SSukumar Swaminathan (void) bcopy((char *)&arg[0], 3269*82527734SSukumar Swaminathan (char *)&arg2, sizeof (char)); 3270*82527734SSukumar Swaminathan break; 3271*82527734SSukumar Swaminathan } 3272*82527734SSukumar Swaminathan } else { 3273*82527734SSukumar Swaminathan /* poll every msi vector */ 3274*82527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 3275*82527734SSukumar Swaminathan rc = emlxs_sli4_poll_eq(hba, 3276*82527734SSukumar Swaminathan &hba->sli.sli4.eq[i]); 3277*82527734SSukumar Swaminathan 3278*82527734SSukumar Swaminathan if (rc == 1) { 3279*82527734SSukumar Swaminathan break; 3280*82527734SSukumar Swaminathan } 3281*82527734SSukumar Swaminathan } 3282*82527734SSukumar Swaminathan if ((i != hba->intr_count) && (rc == 1)) { 3283*82527734SSukumar Swaminathan (void) bcopy((char *)&arg[i], 3284*82527734SSukumar Swaminathan (char *)&arg2, sizeof (char)); 3285*82527734SSukumar Swaminathan break; 3286*82527734SSukumar Swaminathan } 3287*82527734SSukumar Swaminathan } 3288*82527734SSukumar Swaminathan } 3289*82527734SSukumar Swaminathan 3290*82527734SSukumar Swaminathan /* process it here */ 3291*82527734SSukumar Swaminathan rc = emlxs_sli4_msi_intr((char *)hba, (char *)&arg2); 3292*82527734SSukumar Swaminathan 3293*82527734SSukumar Swaminathan return; 3294*82527734SSukumar Swaminathan 3295*82527734SSukumar Swaminathan } /* emlxs_sli4_poll_intr() */ 3296*82527734SSukumar Swaminathan 3297*82527734SSukumar Swaminathan 3298*82527734SSukumar Swaminathan /*ARGSUSED*/ 3299*82527734SSukumar Swaminathan static void 3300*82527734SSukumar Swaminathan emlxs_sli4_process_async_event(emlxs_hba_t *hba, CQE_ASYNC_t *cqe) 3301*82527734SSukumar Swaminathan { 3302*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3303*82527734SSukumar Swaminathan CQE_ASYNC_FCOE_t *fcoe; 3304*82527734SSukumar Swaminathan 3305*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3306*82527734SSukumar Swaminathan "CQ ENTRY: process async event %d stat %d tag %d", 3307*82527734SSukumar Swaminathan cqe->event_code, cqe->link_status, cqe->event_tag); 3308*82527734SSukumar Swaminathan 3309*82527734SSukumar Swaminathan hba->link_event_tag = cqe->event_tag; 3310*82527734SSukumar Swaminathan switch (cqe->event_code) { 3311*82527734SSukumar Swaminathan case ASYNC_EVENT_CODE_LINK_STATE: 3312*82527734SSukumar Swaminathan switch (cqe->link_status) { 3313*82527734SSukumar Swaminathan case ASYNC_EVENT_PHYS_LINK_UP: 3314*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3315*82527734SSukumar Swaminathan "Physical link up received"); 3316*82527734SSukumar Swaminathan break; 3317*82527734SSukumar Swaminathan 3318*82527734SSukumar Swaminathan case ASYNC_EVENT_PHYS_LINK_DOWN: 3319*82527734SSukumar Swaminathan case ASYNC_EVENT_LOGICAL_LINK_DOWN: 3320*82527734SSukumar Swaminathan if (hba->state > FC_LINK_DOWN) { 3321*82527734SSukumar Swaminathan (void) emlxs_fcf_unbind(hba, 3322*82527734SSukumar Swaminathan MAX_FCFCONNECTLIST_ENTRIES); 3323*82527734SSukumar Swaminathan } 3324*82527734SSukumar Swaminathan /* Log the link event */ 3325*82527734SSukumar Swaminathan emlxs_log_link_event(port); 3326*82527734SSukumar Swaminathan break; 3327*82527734SSukumar Swaminathan 3328*82527734SSukumar Swaminathan case ASYNC_EVENT_LOGICAL_LINK_UP: 3329*82527734SSukumar Swaminathan /* If link not already up then declare it up now */ 3330*82527734SSukumar Swaminathan if (hba->state < FC_LINK_UP) { 3331*82527734SSukumar Swaminathan if (cqe->port_speed == PHY_1GHZ_LINK) { 3332*82527734SSukumar Swaminathan hba->linkspeed = LA_1GHZ_LINK; 3333*82527734SSukumar Swaminathan } else { 3334*82527734SSukumar Swaminathan hba->linkspeed = LA_10GHZ_LINK; 3335*82527734SSukumar Swaminathan } 3336*82527734SSukumar Swaminathan hba->topology = TOPOLOGY_PT_PT; 3337*82527734SSukumar Swaminathan 3338*82527734SSukumar Swaminathan /* 3339*82527734SSukumar Swaminathan * This link is not really up till we have 3340*82527734SSukumar Swaminathan * a valid FCF. 3341*82527734SSukumar Swaminathan */ 3342*82527734SSukumar Swaminathan (void) emlxs_fcf_bind(hba); 3343*82527734SSukumar Swaminathan } 3344*82527734SSukumar Swaminathan /* Log the link event */ 3345*82527734SSukumar Swaminathan emlxs_log_link_event(port); 3346*82527734SSukumar Swaminathan break; 3347*82527734SSukumar Swaminathan } 3348*82527734SSukumar Swaminathan break; 3349*82527734SSukumar Swaminathan case ASYNC_EVENT_CODE_FCOE_FIP: 3350*82527734SSukumar Swaminathan fcoe = (CQE_ASYNC_FCOE_t *)cqe; 3351*82527734SSukumar Swaminathan switch (fcoe->evt_type) { 3352*82527734SSukumar Swaminathan case ASYNC_EVENT_NEW_FCF_DISC: 3353*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3354*82527734SSukumar Swaminathan "FCOE Async Event New FCF %d:%d: received ", 3355*82527734SSukumar Swaminathan fcoe->ref_index, fcoe->fcf_count); 3356*82527734SSukumar Swaminathan (void) emlxs_fcf_bind(hba); 3357*82527734SSukumar Swaminathan break; 3358*82527734SSukumar Swaminathan case ASYNC_EVENT_FCF_TABLE_FULL: 3359*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 3360*82527734SSukumar Swaminathan "FCOE Async Event FCF Table Full %d:%d: received ", 3361*82527734SSukumar Swaminathan fcoe->ref_index, fcoe->fcf_count); 3362*82527734SSukumar Swaminathan break; 3363*82527734SSukumar Swaminathan case ASYNC_EVENT_FCF_DEAD: 3364*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3365*82527734SSukumar Swaminathan "FCOE Async Event FCF Disappeared %d:%d: received ", 3366*82527734SSukumar Swaminathan fcoe->ref_index, fcoe->fcf_count); 3367*82527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 1, 0); 3368*82527734SSukumar Swaminathan break; 3369*82527734SSukumar Swaminathan case ASYNC_EVENT_VIRT_LINK_CLEAR: 3370*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3371*82527734SSukumar Swaminathan "FCOE Async Event VLINK CLEAR %d: received ", 3372*82527734SSukumar Swaminathan fcoe->ref_index); 3373*82527734SSukumar Swaminathan if (fcoe->ref_index == 0) { 3374*82527734SSukumar Swaminathan /* 3375*82527734SSukumar Swaminathan * Bounce the link to force rediscovery for 3376*82527734SSukumar Swaminathan * VPI 0. We are ignoring this event for 3377*82527734SSukumar Swaminathan * all other VPIs for now. 3378*82527734SSukumar Swaminathan */ 3379*82527734SSukumar Swaminathan (void) emlxs_reset_link(hba, 1, 0); 3380*82527734SSukumar Swaminathan } 3381*82527734SSukumar Swaminathan break; 3382*82527734SSukumar Swaminathan } 3383*82527734SSukumar Swaminathan break; 3384*82527734SSukumar Swaminathan case ASYNC_EVENT_CODE_DCBX: 3385*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3386*82527734SSukumar Swaminathan "DCBX Async Event Code %d: Not supported ", 3387*82527734SSukumar Swaminathan cqe->event_code); 3388*82527734SSukumar Swaminathan break; 3389*82527734SSukumar Swaminathan default: 3390*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3391*82527734SSukumar Swaminathan "Unknown Async Event Code %d", cqe->event_code); 3392*82527734SSukumar Swaminathan break; 3393*82527734SSukumar Swaminathan } 3394*82527734SSukumar Swaminathan 3395*82527734SSukumar Swaminathan } /* emlxs_sli4_process_async_event() */ 3396*82527734SSukumar Swaminathan 3397*82527734SSukumar Swaminathan 3398*82527734SSukumar Swaminathan /*ARGSUSED*/ 3399*82527734SSukumar Swaminathan static void 3400*82527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe) 3401*82527734SSukumar Swaminathan { 3402*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3403*82527734SSukumar Swaminathan MAILBOX4 *mb; 3404*82527734SSukumar Swaminathan MATCHMAP *mbox_bp; 3405*82527734SSukumar Swaminathan MATCHMAP *mbox_nonembed; 3406*82527734SSukumar Swaminathan MAILBOXQ *mbq; 3407*82527734SSukumar Swaminathan uint32_t size; 3408*82527734SSukumar Swaminathan uint32_t *iptr; 3409*82527734SSukumar Swaminathan int rc; 3410*82527734SSukumar Swaminathan 3411*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3412*82527734SSukumar Swaminathan "CQ ENTRY: process mbox event"); 3413*82527734SSukumar Swaminathan 3414*82527734SSukumar Swaminathan if (cqe->consumed && !cqe->completed) { 3415*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3416*82527734SSukumar Swaminathan "CQ ENTRY: Entry comsumed but not completed"); 3417*82527734SSukumar Swaminathan return; 3418*82527734SSukumar Swaminathan } 3419*82527734SSukumar Swaminathan 3420*82527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 3421*82527734SSukumar Swaminathan case 0: 3422*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg, 3423*82527734SSukumar Swaminathan "No mailbox active."); 3424*82527734SSukumar Swaminathan return; 3425*82527734SSukumar Swaminathan 3426*82527734SSukumar Swaminathan case MBX_POLL: 3427*82527734SSukumar Swaminathan 3428*82527734SSukumar Swaminathan /* Mark mailbox complete, this should wake up any polling */ 3429*82527734SSukumar Swaminathan /* threads. This can happen if interrupts are enabled while */ 3430*82527734SSukumar Swaminathan /* a polled mailbox command is outstanding. If we don't set */ 3431*82527734SSukumar Swaminathan /* MBQ_COMPLETED here, the polling thread may wait until */ 3432*82527734SSukumar Swaminathan /* timeout error occurs */ 3433*82527734SSukumar Swaminathan 3434*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 3435*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)hba->mbox_mbq; 3436*82527734SSukumar Swaminathan if (mbq) { 3437*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3438*82527734SSukumar Swaminathan "Mailbox event. Completing Polled command."); 3439*82527734SSukumar Swaminathan mbq->flag |= MBQ_COMPLETED; 3440*82527734SSukumar Swaminathan } 3441*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 3442*82527734SSukumar Swaminathan 3443*82527734SSukumar Swaminathan return; 3444*82527734SSukumar Swaminathan 3445*82527734SSukumar Swaminathan case MBX_SLEEP: 3446*82527734SSukumar Swaminathan case MBX_NOWAIT: 3447*82527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 3448*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)hba->mbox_mbq; 3449*82527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 3450*82527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 3451*82527734SSukumar Swaminathan break; 3452*82527734SSukumar Swaminathan 3453*82527734SSukumar Swaminathan default: 3454*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 3455*82527734SSukumar Swaminathan "Invalid Mailbox flag (%x)."); 3456*82527734SSukumar Swaminathan return; 3457*82527734SSukumar Swaminathan } 3458*82527734SSukumar Swaminathan 3459*82527734SSukumar Swaminathan /* Now that we are the owner, DMA Sync entire MQ if needed */ 3460*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0, 3461*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 3462*82527734SSukumar Swaminathan 3463*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)hba->mbox_mqe, (uint8_t *)mb, 3464*82527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 3465*82527734SSukumar Swaminathan 3466*82527734SSukumar Swaminathan emlxs_data_dump(hba, "MBOX CMP", (uint32_t *)hba->mbox_mqe, 12, 0); 3467*82527734SSukumar Swaminathan 3468*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3469*82527734SSukumar Swaminathan "Mbox cmpl: %x cmd: %x", mb->mbxStatus, mb->mbxCommand); 3470*82527734SSukumar Swaminathan if (mb->mbxCommand == MBX_SLI_CONFIG) { 3471*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3472*82527734SSukumar Swaminathan "Mbox sge_cnt: %d length: %d embed: %d", 3473*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.sge_cnt, 3474*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length, 3475*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded); 3476*82527734SSukumar Swaminathan } 3477*82527734SSukumar Swaminathan 3478*82527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 3479*82527734SSukumar Swaminathan if (mbq->bp) { 3480*82527734SSukumar Swaminathan mbox_bp = (MATCHMAP *)mbq->bp; 3481*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0, mbox_bp->size, 3482*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 3483*82527734SSukumar Swaminathan } 3484*82527734SSukumar Swaminathan 3485*82527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 3486*82527734SSukumar Swaminathan if (mbq->nonembed) { 3487*82527734SSukumar Swaminathan mbox_nonembed = (MATCHMAP *)mbq->nonembed; 3488*82527734SSukumar Swaminathan size = mbox_nonembed->size; 3489*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_nonembed->dma_handle, 0, size, 3490*82527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 3491*82527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mbox_nonembed->virt); 3492*82527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)iptr, size); 3493*82527734SSukumar Swaminathan 3494*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EXT AREA", (uint32_t *)iptr, 24, 0); 3495*82527734SSukumar Swaminathan } 3496*82527734SSukumar Swaminathan 3497*82527734SSukumar Swaminathan /* Mailbox has been completely received at this point */ 3498*82527734SSukumar Swaminathan 3499*82527734SSukumar Swaminathan if (mb->mbxCommand == MBX_HEARTBEAT) { 3500*82527734SSukumar Swaminathan hba->heartbeat_active = 0; 3501*82527734SSukumar Swaminathan goto done; 3502*82527734SSukumar Swaminathan } 3503*82527734SSukumar Swaminathan 3504*82527734SSukumar Swaminathan if (hba->mbox_queue_flag == MBX_SLEEP) { 3505*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 3506*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 3507*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3508*82527734SSukumar Swaminathan "Received. %s: status=%x Sleep.", 3509*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 3510*82527734SSukumar Swaminathan mb->mbxStatus); 3511*82527734SSukumar Swaminathan } 3512*82527734SSukumar Swaminathan } else { 3513*82527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 3514*82527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 3515*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3516*82527734SSukumar Swaminathan "Completed. %s: status=%x", 3517*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 3518*82527734SSukumar Swaminathan mb->mbxStatus); 3519*82527734SSukumar Swaminathan } 3520*82527734SSukumar Swaminathan } 3521*82527734SSukumar Swaminathan 3522*82527734SSukumar Swaminathan /* Filter out passthru mailbox */ 3523*82527734SSukumar Swaminathan if (mbq->flag & MBQ_PASSTHRU) { 3524*82527734SSukumar Swaminathan goto done; 3525*82527734SSukumar Swaminathan } 3526*82527734SSukumar Swaminathan 3527*82527734SSukumar Swaminathan if (mb->mbxStatus) { 3528*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3529*82527734SSukumar Swaminathan "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand), 3530*82527734SSukumar Swaminathan (uint32_t)mb->mbxStatus); 3531*82527734SSukumar Swaminathan } 3532*82527734SSukumar Swaminathan 3533*82527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 3534*82527734SSukumar Swaminathan rc = (mbq->mbox_cmpl)(hba, mbq); 3535*82527734SSukumar Swaminathan 3536*82527734SSukumar Swaminathan /* If mbox was retried, return immediately */ 3537*82527734SSukumar Swaminathan if (rc) { 3538*82527734SSukumar Swaminathan return; 3539*82527734SSukumar Swaminathan } 3540*82527734SSukumar Swaminathan } 3541*82527734SSukumar Swaminathan 3542*82527734SSukumar Swaminathan done: 3543*82527734SSukumar Swaminathan 3544*82527734SSukumar Swaminathan /* Clean up the mailbox area */ 3545*82527734SSukumar Swaminathan emlxs_mb_fini(hba, (MAILBOX *)mb, mb->mbxStatus); 3546*82527734SSukumar Swaminathan 3547*82527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 3548*82527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 3549*82527734SSukumar Swaminathan if (mbq) { 3550*82527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 3551*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 3552*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 3553*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 3554*82527734SSukumar Swaminathan } 3555*82527734SSukumar Swaminathan } 3556*82527734SSukumar Swaminathan return; 3557*82527734SSukumar Swaminathan 3558*82527734SSukumar Swaminathan } /* emlxs_sli4_process_mbox_event() */ 3559*82527734SSukumar Swaminathan 3560*82527734SSukumar Swaminathan 3561*82527734SSukumar Swaminathan static void 3562*82527734SSukumar Swaminathan emlxs_CQE_to_IOCB(emlxs_hba_t *hba, CQE_CmplWQ_t *cqe, emlxs_buf_t *sbp) 3563*82527734SSukumar Swaminathan { 3564*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3565*82527734SSukumar Swaminathan IOCBQ *iocbq; 3566*82527734SSukumar Swaminathan IOCB *iocb; 3567*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 3568*82527734SSukumar Swaminathan 3569*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 3570*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 3571*82527734SSukumar Swaminathan iocb = &iocbq->iocb; 3572*82527734SSukumar Swaminathan 3573*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 3574*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3575*82527734SSukumar Swaminathan "CQE to IOCB: cmd:x%x tag:x%x xri:x%x", wqe->Command, 3576*82527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 3577*82527734SSukumar Swaminathan #endif 3578*82527734SSukumar Swaminathan 3579*82527734SSukumar Swaminathan iocb->ULPSTATUS = cqe->Status; 3580*82527734SSukumar Swaminathan iocb->un.ulpWord[4] = cqe->Parameter; 3581*82527734SSukumar Swaminathan iocb->ULPIOTAG = cqe->RequestTag; 3582*82527734SSukumar Swaminathan iocb->ULPCONTEXT = wqe->XRITag; 3583*82527734SSukumar Swaminathan 3584*82527734SSukumar Swaminathan switch (wqe->Command) { 3585*82527734SSukumar Swaminathan 3586*82527734SSukumar Swaminathan case CMD_FCP_ICMND64_CR: 3587*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_ICMND64_CX; 3588*82527734SSukumar Swaminathan break; 3589*82527734SSukumar Swaminathan 3590*82527734SSukumar Swaminathan case CMD_FCP_IREAD64_CR: 3591*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IREAD64_CX; 3592*82527734SSukumar Swaminathan iocb->ULPPU = PARM_READ_CHECK; 3593*82527734SSukumar Swaminathan if (iocb->ULPSTATUS == IOSTAT_FCP_RSP_ERROR) { 3594*82527734SSukumar Swaminathan iocb->un.fcpi64.fcpi_parm = 3595*82527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount - 3596*82527734SSukumar Swaminathan cqe->CmdSpecific; 3597*82527734SSukumar Swaminathan } 3598*82527734SSukumar Swaminathan break; 3599*82527734SSukumar Swaminathan 3600*82527734SSukumar Swaminathan case CMD_FCP_IWRITE64_CR: 3601*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IWRITE64_CX; 3602*82527734SSukumar Swaminathan break; 3603*82527734SSukumar Swaminathan 3604*82527734SSukumar Swaminathan case CMD_ELS_REQUEST64_CR: 3605*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_ELS_REQUEST64_CX; 3606*82527734SSukumar Swaminathan iocb->un.elsreq64.bdl.bdeSize = cqe->CmdSpecific; 3607*82527734SSukumar Swaminathan if (iocb->ULPSTATUS == 0) { 3608*82527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 3609*82527734SSukumar Swaminathan } 3610*82527734SSukumar Swaminathan break; 3611*82527734SSukumar Swaminathan 3612*82527734SSukumar Swaminathan case CMD_GEN_REQUEST64_CR: 3613*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_GEN_REQUEST64_CX; 3614*82527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 3615*82527734SSukumar Swaminathan break; 3616*82527734SSukumar Swaminathan 3617*82527734SSukumar Swaminathan case CMD_XMIT_SEQUENCE64_CR: 3618*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CX; 3619*82527734SSukumar Swaminathan break; 3620*82527734SSukumar Swaminathan 3621*82527734SSukumar Swaminathan default: 3622*82527734SSukumar Swaminathan iocb->ULPCOMMAND = wqe->Command; 3623*82527734SSukumar Swaminathan 3624*82527734SSukumar Swaminathan } 3625*82527734SSukumar Swaminathan 3626*82527734SSukumar Swaminathan } /* emlxs_CQE_to_IOCB() */ 3627*82527734SSukumar Swaminathan 3628*82527734SSukumar Swaminathan 3629*82527734SSukumar Swaminathan /*ARGSUSED*/ 3630*82527734SSukumar Swaminathan static void 3631*82527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(emlxs_hba_t *hba) 3632*82527734SSukumar Swaminathan { 3633*82527734SSukumar Swaminathan CHANNEL *cp; 3634*82527734SSukumar Swaminathan emlxs_buf_t *sbp; 3635*82527734SSukumar Swaminathan IOCBQ *iocbq; 3636*82527734SSukumar Swaminathan uint32_t i; 3637*82527734SSukumar Swaminathan uint32_t trigger; 3638*82527734SSukumar Swaminathan CQE_CmplWQ_t cqe; 3639*82527734SSukumar Swaminathan 3640*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 3641*82527734SSukumar Swaminathan for (i = 0; i < hba->max_iotag; i++) { 3642*82527734SSukumar Swaminathan sbp = hba->fc_table[i]; 3643*82527734SSukumar Swaminathan if (sbp == NULL || sbp == STALE_PACKET) { 3644*82527734SSukumar Swaminathan continue; 3645*82527734SSukumar Swaminathan } 3646*82527734SSukumar Swaminathan hba->fc_table[i] = NULL; 3647*82527734SSukumar Swaminathan hba->io_count--; 3648*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 3649*82527734SSukumar Swaminathan 3650*82527734SSukumar Swaminathan cp = sbp->channel; 3651*82527734SSukumar Swaminathan bzero(&cqe, sizeof (CQE_CmplWQ_t)); 3652*82527734SSukumar Swaminathan cqe.RequestTag = i; 3653*82527734SSukumar Swaminathan cqe.Status = IOSTAT_LOCAL_REJECT; 3654*82527734SSukumar Swaminathan cqe.Parameter = IOERR_SEQUENCE_TIMEOUT; 3655*82527734SSukumar Swaminathan 3656*82527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 3657*82527734SSukumar Swaminathan 3658*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 3659*82527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 3660*82527734SSukumar Swaminathan if (sbp->fct_cmd) { 3661*82527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 3662*82527734SSukumar Swaminathan EMLXS_FCT_IOCB_COMPLETE); 3663*82527734SSukumar Swaminathan } 3664*82527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 3665*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 3666*82527734SSukumar Swaminathan 3667*82527734SSukumar Swaminathan atomic_add_32(&hba->io_active, -1); 3668*82527734SSukumar Swaminathan 3669*82527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 3670*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 3671*82527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, &cqe, sbp); 3672*82527734SSukumar Swaminathan 3673*82527734SSukumar Swaminathan iocbq->next = NULL; 3674*82527734SSukumar Swaminathan 3675*82527734SSukumar Swaminathan sbp->xp->state &= ~RESOURCE_XRI_PENDING_IO; 3676*82527734SSukumar Swaminathan 3677*82527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 3678*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, sbp->xp); 3679*82527734SSukumar Swaminathan 3680*82527734SSukumar Swaminathan if (!(sbp->pkt_flags & 3681*82527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 3682*82527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 3683*82527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 3684*82527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 3685*82527734SSukumar Swaminathan cp->rsp_head = iocbq; 3686*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 3687*82527734SSukumar Swaminathan } else { 3688*82527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 3689*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 3690*82527734SSukumar Swaminathan } 3691*82527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 3692*82527734SSukumar Swaminathan trigger = 1; 3693*82527734SSukumar Swaminathan } else { 3694*82527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 3695*82527734SSukumar Swaminathan } 3696*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 3697*82527734SSukumar Swaminathan } 3698*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 3699*82527734SSukumar Swaminathan 3700*82527734SSukumar Swaminathan if (trigger) { 3701*82527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 3702*82527734SSukumar Swaminathan cp = &hba->chan[i]; 3703*82527734SSukumar Swaminathan if (cp->rsp_head != NULL) { 3704*82527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 3705*82527734SSukumar Swaminathan emlxs_proc_channel, cp); 3706*82527734SSukumar Swaminathan } 3707*82527734SSukumar Swaminathan } 3708*82527734SSukumar Swaminathan } 3709*82527734SSukumar Swaminathan 3710*82527734SSukumar Swaminathan } /* emlxs_sli4_hba_flush_chipq() */ 3711*82527734SSukumar Swaminathan 3712*82527734SSukumar Swaminathan 3713*82527734SSukumar Swaminathan /*ARGSUSED*/ 3714*82527734SSukumar Swaminathan static void 3715*82527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(emlxs_hba_t *hba, 3716*82527734SSukumar Swaminathan CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 3717*82527734SSukumar Swaminathan { 3718*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3719*82527734SSukumar Swaminathan CHANNEL *cp; 3720*82527734SSukumar Swaminathan uint16_t request_tag; 3721*82527734SSukumar Swaminathan 3722*82527734SSukumar Swaminathan request_tag = cqe->RequestTag; 3723*82527734SSukumar Swaminathan 3724*82527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 3725*82527734SSukumar Swaminathan cp = cq->channelp; 3726*82527734SSukumar Swaminathan 3727*82527734SSukumar Swaminathan cp->hbaCmplCmd++; 3728*82527734SSukumar Swaminathan 3729*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3730*82527734SSukumar Swaminathan "CQ ENTRY: OOR Cmpl: tag=%x", request_tag); 3731*82527734SSukumar Swaminathan 3732*82527734SSukumar Swaminathan } /* emlxs_sli4_process_oor_wqe_cmpl() */ 3733*82527734SSukumar Swaminathan 3734*82527734SSukumar Swaminathan 3735*82527734SSukumar Swaminathan /*ARGSUSED*/ 3736*82527734SSukumar Swaminathan static void 3737*82527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(emlxs_hba_t *hba, CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 3738*82527734SSukumar Swaminathan { 3739*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3740*82527734SSukumar Swaminathan CHANNEL *cp; 3741*82527734SSukumar Swaminathan emlxs_buf_t *sbp; 3742*82527734SSukumar Swaminathan IOCBQ *iocbq; 3743*82527734SSukumar Swaminathan uint16_t request_tag; 3744*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 3745*82527734SSukumar Swaminathan fct_cmd_t *fct_cmd; 3746*82527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 3747*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 3748*82527734SSukumar Swaminathan 3749*82527734SSukumar Swaminathan request_tag = cqe->RequestTag; 3750*82527734SSukumar Swaminathan 3751*82527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 3752*82527734SSukumar Swaminathan cp = cq->channelp; 3753*82527734SSukumar Swaminathan 3754*82527734SSukumar Swaminathan sbp = hba->fc_table[request_tag]; 3755*82527734SSukumar Swaminathan atomic_add_32(&hba->io_active, -1); 3756*82527734SSukumar Swaminathan 3757*82527734SSukumar Swaminathan if (sbp == STALE_PACKET) { 3758*82527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 3759*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3760*82527734SSukumar Swaminathan "CQ ENTRY: Stale sbp. tag=%x. Dropping...", request_tag); 3761*82527734SSukumar Swaminathan return; 3762*82527734SSukumar Swaminathan } 3763*82527734SSukumar Swaminathan 3764*82527734SSukumar Swaminathan if (!sbp || !(sbp->xp)) { 3765*82527734SSukumar Swaminathan cp->hbaCmplCmd++; 3766*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3767*82527734SSukumar Swaminathan "CQ ENTRY: NULL sbp %p. tag=%x. Dropping...", 3768*82527734SSukumar Swaminathan sbp, request_tag); 3769*82527734SSukumar Swaminathan return; 3770*82527734SSukumar Swaminathan } 3771*82527734SSukumar Swaminathan 3772*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 3773*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3774*82527734SSukumar Swaminathan "CQ ENTRY: process wqe compl"); 3775*82527734SSukumar Swaminathan #endif 3776*82527734SSukumar Swaminathan 3777*82527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 3778*82527734SSukumar Swaminathan 3779*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 3780*82527734SSukumar Swaminathan fct_cmd = sbp->fct_cmd; 3781*82527734SSukumar Swaminathan if (fct_cmd) { 3782*82527734SSukumar Swaminathan cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 3783*82527734SSukumar Swaminathan mutex_enter(&cmd_sbp->fct_mtx); 3784*82527734SSukumar Swaminathan EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_IOCB_COMPLETE); 3785*82527734SSukumar Swaminathan mutex_exit(&cmd_sbp->fct_mtx); 3786*82527734SSukumar Swaminathan } 3787*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 3788*82527734SSukumar Swaminathan 3789*82527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 3790*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 3791*82527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, cqe, sbp); 3792*82527734SSukumar Swaminathan 3793*82527734SSukumar Swaminathan iocbq->next = NULL; 3794*82527734SSukumar Swaminathan 3795*82527734SSukumar Swaminathan sbp->xp->state &= ~RESOURCE_XRI_PENDING_IO; 3796*82527734SSukumar Swaminathan if (cqe->XB) { 3797*82527734SSukumar Swaminathan /* Mark exchange as ABORT in progress */ 3798*82527734SSukumar Swaminathan sbp->xp->state |= RESOURCE_XRI_ABORT_INP; 3799*82527734SSukumar Swaminathan 3800*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3801*82527734SSukumar Swaminathan "CQ ENTRY: ABORT INP: tag=%x xri=%x", request_tag, 3802*82527734SSukumar Swaminathan sbp->xp->XRI); 3803*82527734SSukumar Swaminathan 3804*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, 0); 3805*82527734SSukumar Swaminathan } else { 3806*82527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 3807*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, sbp, sbp->xp); 3808*82527734SSukumar Swaminathan } 3809*82527734SSukumar Swaminathan 3810*82527734SSukumar Swaminathan /* 3811*82527734SSukumar Swaminathan * If this is NOT a polled command completion 3812*82527734SSukumar Swaminathan * or a driver allocated pkt, then defer pkt 3813*82527734SSukumar Swaminathan * completion. 3814*82527734SSukumar Swaminathan */ 3815*82527734SSukumar Swaminathan if (!(sbp->pkt_flags & 3816*82527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 3817*82527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 3818*82527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 3819*82527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 3820*82527734SSukumar Swaminathan cp->rsp_head = iocbq; 3821*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 3822*82527734SSukumar Swaminathan } else { 3823*82527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 3824*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 3825*82527734SSukumar Swaminathan } 3826*82527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 3827*82527734SSukumar Swaminathan 3828*82527734SSukumar Swaminathan /* Delay triggering thread till end of ISR */ 3829*82527734SSukumar Swaminathan cp->chan_flag |= EMLXS_NEEDS_TRIGGER; 3830*82527734SSukumar Swaminathan } else { 3831*82527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 3832*82527734SSukumar Swaminathan } 3833*82527734SSukumar Swaminathan 3834*82527734SSukumar Swaminathan } /* emlxs_sli4_process_wqe_cmpl() */ 3835*82527734SSukumar Swaminathan 3836*82527734SSukumar Swaminathan 3837*82527734SSukumar Swaminathan /*ARGSUSED*/ 3838*82527734SSukumar Swaminathan static void 3839*82527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(emlxs_hba_t *hba, CQ_DESC_t *cq, 3840*82527734SSukumar Swaminathan CQE_RelWQ_t *cqe) 3841*82527734SSukumar Swaminathan { 3842*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3843*82527734SSukumar Swaminathan WQ_DESC_t *wq; 3844*82527734SSukumar Swaminathan CHANNEL *cp; 3845*82527734SSukumar Swaminathan uint32_t i; 3846*82527734SSukumar Swaminathan 3847*82527734SSukumar Swaminathan i = cqe->WQid; 3848*82527734SSukumar Swaminathan wq = &hba->sli.sli4.wq[hba->sli.sli4.wq_map[i]]; 3849*82527734SSukumar Swaminathan 3850*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 3851*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3852*82527734SSukumar Swaminathan "CQ ENTRY: process release wqe: old %d new %d", wq->port_index, 3853*82527734SSukumar Swaminathan cqe->WQindex); 3854*82527734SSukumar Swaminathan #endif 3855*82527734SSukumar Swaminathan 3856*82527734SSukumar Swaminathan wq->port_index = cqe->WQindex; 3857*82527734SSukumar Swaminathan 3858*82527734SSukumar Swaminathan /* Cmd ring may be available. Try sending more iocbs */ 3859*82527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 3860*82527734SSukumar Swaminathan cp = &hba->chan[i]; 3861*82527734SSukumar Swaminathan if (wq == (WQ_DESC_t *)cp->iopath) { 3862*82527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(hba, cp, 0); 3863*82527734SSukumar Swaminathan } 3864*82527734SSukumar Swaminathan } 3865*82527734SSukumar Swaminathan 3866*82527734SSukumar Swaminathan } /* emlxs_sli4_process_release_wqe() */ 3867*82527734SSukumar Swaminathan 3868*82527734SSukumar Swaminathan 3869*82527734SSukumar Swaminathan /*ARGSUSED*/ 3870*82527734SSukumar Swaminathan emlxs_iocbq_t * 3871*82527734SSukumar Swaminathan emlxs_sli4_rxq_get(emlxs_hba_t *hba, fc_frame_hdr_t *fchdr) 3872*82527734SSukumar Swaminathan { 3873*82527734SSukumar Swaminathan emlxs_queue_t *q; 3874*82527734SSukumar Swaminathan emlxs_iocbq_t *iocbq; 3875*82527734SSukumar Swaminathan emlxs_iocbq_t *prev; 3876*82527734SSukumar Swaminathan fc_frame_hdr_t *fchdr2; 3877*82527734SSukumar Swaminathan RXQ_DESC_t *rxq; 3878*82527734SSukumar Swaminathan 3879*82527734SSukumar Swaminathan switch (fchdr->type) { 3880*82527734SSukumar Swaminathan case 1: /* ELS */ 3881*82527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 3882*82527734SSukumar Swaminathan break; 3883*82527734SSukumar Swaminathan case 0x20: /* CT */ 3884*82527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 3885*82527734SSukumar Swaminathan break; 3886*82527734SSukumar Swaminathan default: 3887*82527734SSukumar Swaminathan return (NULL); 3888*82527734SSukumar Swaminathan } 3889*82527734SSukumar Swaminathan 3890*82527734SSukumar Swaminathan mutex_enter(&rxq->lock); 3891*82527734SSukumar Swaminathan 3892*82527734SSukumar Swaminathan q = &rxq->active; 3893*82527734SSukumar Swaminathan iocbq = (emlxs_iocbq_t *)q->q_first; 3894*82527734SSukumar Swaminathan prev = NULL; 3895*82527734SSukumar Swaminathan 3896*82527734SSukumar Swaminathan while (iocbq) { 3897*82527734SSukumar Swaminathan 3898*82527734SSukumar Swaminathan fchdr2 = (fc_frame_hdr_t *)iocbq->iocb.un.ulpWord; 3899*82527734SSukumar Swaminathan 3900*82527734SSukumar Swaminathan if ((fchdr2->s_id == fchdr->s_id) && 3901*82527734SSukumar Swaminathan (fchdr2->ox_id == fchdr->ox_id) && 3902*82527734SSukumar Swaminathan (fchdr2->seq_id == fchdr->seq_id)) { 3903*82527734SSukumar Swaminathan /* Remove iocbq */ 3904*82527734SSukumar Swaminathan if (prev) { 3905*82527734SSukumar Swaminathan prev->next = iocbq->next; 3906*82527734SSukumar Swaminathan } 3907*82527734SSukumar Swaminathan if (q->q_first == (uint8_t *)iocbq) { 3908*82527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq->next; 3909*82527734SSukumar Swaminathan } 3910*82527734SSukumar Swaminathan if (q->q_last == (uint8_t *)iocbq) { 3911*82527734SSukumar Swaminathan q->q_last = (uint8_t *)prev; 3912*82527734SSukumar Swaminathan } 3913*82527734SSukumar Swaminathan q->q_cnt--; 3914*82527734SSukumar Swaminathan 3915*82527734SSukumar Swaminathan break; 3916*82527734SSukumar Swaminathan } 3917*82527734SSukumar Swaminathan 3918*82527734SSukumar Swaminathan prev = iocbq; 3919*82527734SSukumar Swaminathan iocbq = iocbq->next; 3920*82527734SSukumar Swaminathan } 3921*82527734SSukumar Swaminathan 3922*82527734SSukumar Swaminathan mutex_exit(&rxq->lock); 3923*82527734SSukumar Swaminathan 3924*82527734SSukumar Swaminathan return (iocbq); 3925*82527734SSukumar Swaminathan 3926*82527734SSukumar Swaminathan } /* emlxs_sli4_rxq_get() */ 3927*82527734SSukumar Swaminathan 3928*82527734SSukumar Swaminathan 3929*82527734SSukumar Swaminathan /*ARGSUSED*/ 3930*82527734SSukumar Swaminathan void 3931*82527734SSukumar Swaminathan emlxs_sli4_rxq_put(emlxs_hba_t *hba, emlxs_iocbq_t *iocbq) 3932*82527734SSukumar Swaminathan { 3933*82527734SSukumar Swaminathan emlxs_queue_t *q; 3934*82527734SSukumar Swaminathan fc_frame_hdr_t *fchdr; 3935*82527734SSukumar Swaminathan RXQ_DESC_t *rxq; 3936*82527734SSukumar Swaminathan 3937*82527734SSukumar Swaminathan fchdr = (fc_frame_hdr_t *)iocbq->iocb.RXFCHDR; 3938*82527734SSukumar Swaminathan 3939*82527734SSukumar Swaminathan switch (fchdr->type) { 3940*82527734SSukumar Swaminathan case 1: /* ELS */ 3941*82527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 3942*82527734SSukumar Swaminathan break; 3943*82527734SSukumar Swaminathan case 0x20: /* CT */ 3944*82527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 3945*82527734SSukumar Swaminathan break; 3946*82527734SSukumar Swaminathan default: 3947*82527734SSukumar Swaminathan return; 3948*82527734SSukumar Swaminathan } 3949*82527734SSukumar Swaminathan 3950*82527734SSukumar Swaminathan mutex_enter(&rxq->lock); 3951*82527734SSukumar Swaminathan 3952*82527734SSukumar Swaminathan q = &rxq->active; 3953*82527734SSukumar Swaminathan 3954*82527734SSukumar Swaminathan if (q->q_last) { 3955*82527734SSukumar Swaminathan ((emlxs_iocbq_t *)q->q_last)->next = iocbq; 3956*82527734SSukumar Swaminathan q->q_cnt++; 3957*82527734SSukumar Swaminathan } else { 3958*82527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq; 3959*82527734SSukumar Swaminathan q->q_cnt = 1; 3960*82527734SSukumar Swaminathan } 3961*82527734SSukumar Swaminathan 3962*82527734SSukumar Swaminathan q->q_last = (uint8_t *)iocbq; 3963*82527734SSukumar Swaminathan iocbq->next = NULL; 3964*82527734SSukumar Swaminathan 3965*82527734SSukumar Swaminathan mutex_exit(&rxq->lock); 3966*82527734SSukumar Swaminathan 3967*82527734SSukumar Swaminathan return; 3968*82527734SSukumar Swaminathan 3969*82527734SSukumar Swaminathan } /* emlxs_sli4_rxq_put() */ 3970*82527734SSukumar Swaminathan 3971*82527734SSukumar Swaminathan 3972*82527734SSukumar Swaminathan static void 3973*82527734SSukumar Swaminathan emlxs_sli4_rq_post(emlxs_hba_t *hba, uint16_t rqid) 3974*82527734SSukumar Swaminathan { 3975*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3976*82527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 3977*82527734SSukumar Swaminathan 3978*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3979*82527734SSukumar Swaminathan "RQ POST: rqid=%d count=1", rqid); 3980*82527734SSukumar Swaminathan 3981*82527734SSukumar Swaminathan /* Ring the RQ doorbell once to repost the RQ buffer */ 3982*82527734SSukumar Swaminathan rqdb.word = 0; 3983*82527734SSukumar Swaminathan rqdb.db.Qid = rqid; 3984*82527734SSukumar Swaminathan rqdb.db.NumPosted = 1; 3985*82527734SSukumar Swaminathan 3986*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_RQDB_REG(hba), rqdb.word); 3987*82527734SSukumar Swaminathan 3988*82527734SSukumar Swaminathan } /* emlxs_sli4_rq_post() */ 3989*82527734SSukumar Swaminathan 3990*82527734SSukumar Swaminathan 3991*82527734SSukumar Swaminathan /*ARGSUSED*/ 3992*82527734SSukumar Swaminathan static void 3993*82527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq, 3994*82527734SSukumar Swaminathan CQE_UnsolRcv_t *cqe) 3995*82527734SSukumar Swaminathan { 3996*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 3997*82527734SSukumar Swaminathan emlxs_port_t *vport; 3998*82527734SSukumar Swaminathan RQ_DESC_t *hdr_rq; 3999*82527734SSukumar Swaminathan RQ_DESC_t *data_rq; 4000*82527734SSukumar Swaminathan MATCHMAP *hdr_mp; 4001*82527734SSukumar Swaminathan MATCHMAP *data_mp; 4002*82527734SSukumar Swaminathan MATCHMAP *seq_mp; 4003*82527734SSukumar Swaminathan uint32_t *data; 4004*82527734SSukumar Swaminathan fc_frame_hdr_t fchdr; 4005*82527734SSukumar Swaminathan uint32_t hdr_rqi; 4006*82527734SSukumar Swaminathan uint32_t host_index; 4007*82527734SSukumar Swaminathan emlxs_iocbq_t *iocbq = NULL; 4008*82527734SSukumar Swaminathan emlxs_iocb_t *iocb; 4009*82527734SSukumar Swaminathan emlxs_node_t *node; 4010*82527734SSukumar Swaminathan uint32_t i; 4011*82527734SSukumar Swaminathan uint32_t seq_len; 4012*82527734SSukumar Swaminathan uint32_t seq_cnt; 4013*82527734SSukumar Swaminathan uint32_t buf_type; 4014*82527734SSukumar Swaminathan char label[32]; 4015*82527734SSukumar Swaminathan emlxs_wqe_t *wqe; 4016*82527734SSukumar Swaminathan CHANNEL *cp; 4017*82527734SSukumar Swaminathan uint16_t iotag; 4018*82527734SSukumar Swaminathan XRIobj_t *xp; 4019*82527734SSukumar Swaminathan RPIobj_t *rp = NULL; 4020*82527734SSukumar Swaminathan FCFIobj_t *fp; 4021*82527734SSukumar Swaminathan uint32_t cmd; 4022*82527734SSukumar Swaminathan uint32_t posted = 0; 4023*82527734SSukumar Swaminathan uint32_t abort = 1; 4024*82527734SSukumar Swaminathan 4025*82527734SSukumar Swaminathan hdr_rqi = hba->sli.sli4.rq_map[cqe->RQid]; 4026*82527734SSukumar Swaminathan hdr_rq = &hba->sli.sli4.rq[hdr_rqi]; 4027*82527734SSukumar Swaminathan data_rq = &hba->sli.sli4.rq[hdr_rqi + 1]; 4028*82527734SSukumar Swaminathan 4029*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4030*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: RQid=%d,%d index=%d status=%x " \ 4031*82527734SSukumar Swaminathan "hdr_size=%d data_size=%d", 4032*82527734SSukumar Swaminathan cqe->RQid, hdr_rqi, hdr_rq->host_index, cqe->Status, cqe->hdr_size, 4033*82527734SSukumar Swaminathan cqe->data_size); 4034*82527734SSukumar Swaminathan 4035*82527734SSukumar Swaminathan /* Validate the CQE */ 4036*82527734SSukumar Swaminathan 4037*82527734SSukumar Swaminathan /* Check status */ 4038*82527734SSukumar Swaminathan switch (cqe->Status) { 4039*82527734SSukumar Swaminathan case RQ_STATUS_SUCCESS: /* 0x10 */ 4040*82527734SSukumar Swaminathan break; 4041*82527734SSukumar Swaminathan 4042*82527734SSukumar Swaminathan case RQ_STATUS_BUFLEN_EXCEEDED: /* 0x11 */ 4043*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4044*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload truncated."); 4045*82527734SSukumar Swaminathan break; 4046*82527734SSukumar Swaminathan 4047*82527734SSukumar Swaminathan case RQ_STATUS_NEED_BUFFER: /* 0x12 */ 4048*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4049*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer needed."); 4050*82527734SSukumar Swaminathan return; 4051*82527734SSukumar Swaminathan 4052*82527734SSukumar Swaminathan case RQ_STATUS_FRAME_DISCARDED: /* 0x13 */ 4053*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4054*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer discarded."); 4055*82527734SSukumar Swaminathan return; 4056*82527734SSukumar Swaminathan 4057*82527734SSukumar Swaminathan default: 4058*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4059*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Unknown status=%x.", 4060*82527734SSukumar Swaminathan cqe->Status); 4061*82527734SSukumar Swaminathan break; 4062*82527734SSukumar Swaminathan } 4063*82527734SSukumar Swaminathan 4064*82527734SSukumar Swaminathan /* Make sure there is a frame header */ 4065*82527734SSukumar Swaminathan if (cqe->hdr_size < sizeof (fc_frame_hdr_t)) { 4066*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4067*82527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: FC header too small. Dropping..."); 4068*82527734SSukumar Swaminathan return; 4069*82527734SSukumar Swaminathan } 4070*82527734SSukumar Swaminathan 4071*82527734SSukumar Swaminathan /* Update host index */ 4072*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.rq[hdr_rqi].lock); 4073*82527734SSukumar Swaminathan host_index = hdr_rq->host_index; 4074*82527734SSukumar Swaminathan hdr_rq->host_index++; 4075*82527734SSukumar Swaminathan if (hdr_rq->host_index >= hdr_rq->max_index) { 4076*82527734SSukumar Swaminathan hdr_rq->host_index = 0; 4077*82527734SSukumar Swaminathan } 4078*82527734SSukumar Swaminathan data_rq->host_index = hdr_rq->host_index; 4079*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.rq[hdr_rqi].lock); 4080*82527734SSukumar Swaminathan 4081*82527734SSukumar Swaminathan /* Get the next header rqb */ 4082*82527734SSukumar Swaminathan hdr_mp = hdr_rq->rqb[host_index]; 4083*82527734SSukumar Swaminathan 4084*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hdr_mp->dma_handle, 0, 4085*82527734SSukumar Swaminathan sizeof (fc_frame_hdr_t), DDI_DMA_SYNC_FORKERNEL); 4086*82527734SSukumar Swaminathan 4087*82527734SSukumar Swaminathan LE_SWAP32_BCOPY(hdr_mp->virt, (uint8_t *)&fchdr, 4088*82527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 4089*82527734SSukumar Swaminathan 4090*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4091*82527734SSukumar Swaminathan "RQ HDR[%d]: rctl:%x type:%x " \ 4092*82527734SSukumar Swaminathan "sid:%x did:%x oxid:%x rxid:%x", 4093*82527734SSukumar Swaminathan host_index, fchdr.r_ctl, fchdr.type, 4094*82527734SSukumar Swaminathan fchdr.s_id, fchdr.d_id, fchdr.ox_id, fchdr.rx_id); 4095*82527734SSukumar Swaminathan 4096*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4097*82527734SSukumar Swaminathan "RQ HDR[%d]: fctl:%x seq_id:%x seq_cnt:%x df_ctl:%x ro:%x", 4098*82527734SSukumar Swaminathan host_index, fchdr.f_ctl, fchdr.seq_id, fchdr.seq_cnt, 4099*82527734SSukumar Swaminathan fchdr.df_ctl, fchdr.ro); 4100*82527734SSukumar Swaminathan 4101*82527734SSukumar Swaminathan /* Verify fc header type */ 4102*82527734SSukumar Swaminathan switch (fchdr.type) { 4103*82527734SSukumar Swaminathan case 0: /* BLS */ 4104*82527734SSukumar Swaminathan if (fchdr.r_ctl != 0x81) { 4105*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4106*82527734SSukumar Swaminathan "RQ ENTRY: Unexpected FC rctl (0x%x) " \ 4107*82527734SSukumar Swaminathan "received. Dropping...", 4108*82527734SSukumar Swaminathan fchdr.r_ctl); 4109*82527734SSukumar Swaminathan 4110*82527734SSukumar Swaminathan goto done; 4111*82527734SSukumar Swaminathan } 4112*82527734SSukumar Swaminathan 4113*82527734SSukumar Swaminathan /* Make sure there is no payload */ 4114*82527734SSukumar Swaminathan if (cqe->data_size != 0) { 4115*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4116*82527734SSukumar Swaminathan "RQ ENTRY: ABTS payload provided. Dropping..."); 4117*82527734SSukumar Swaminathan 4118*82527734SSukumar Swaminathan goto done; 4119*82527734SSukumar Swaminathan } 4120*82527734SSukumar Swaminathan 4121*82527734SSukumar Swaminathan buf_type = 0xFFFFFFFF; 4122*82527734SSukumar Swaminathan (void) strcpy(label, "ABTS"); 4123*82527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 4124*82527734SSukumar Swaminathan break; 4125*82527734SSukumar Swaminathan 4126*82527734SSukumar Swaminathan case 0x01: /* ELS */ 4127*82527734SSukumar Swaminathan /* Make sure there is a payload */ 4128*82527734SSukumar Swaminathan if (cqe->data_size == 0) { 4129*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4130*82527734SSukumar Swaminathan "RQ ENTRY: Unsol Rcv: No ELS payload provided. " \ 4131*82527734SSukumar Swaminathan "Dropping..."); 4132*82527734SSukumar Swaminathan 4133*82527734SSukumar Swaminathan goto done; 4134*82527734SSukumar Swaminathan } 4135*82527734SSukumar Swaminathan 4136*82527734SSukumar Swaminathan buf_type = MEM_ELSBUF; 4137*82527734SSukumar Swaminathan (void) strcpy(label, "Unsol ELS"); 4138*82527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 4139*82527734SSukumar Swaminathan break; 4140*82527734SSukumar Swaminathan 4141*82527734SSukumar Swaminathan case 0x20: /* CT */ 4142*82527734SSukumar Swaminathan /* Make sure there is a payload */ 4143*82527734SSukumar Swaminathan if (cqe->data_size == 0) { 4144*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4145*82527734SSukumar Swaminathan "RQ ENTRY: Unsol Rcv: No CT payload provided. " \ 4146*82527734SSukumar Swaminathan "Dropping..."); 4147*82527734SSukumar Swaminathan 4148*82527734SSukumar Swaminathan goto done; 4149*82527734SSukumar Swaminathan } 4150*82527734SSukumar Swaminathan 4151*82527734SSukumar Swaminathan buf_type = MEM_CTBUF; 4152*82527734SSukumar Swaminathan (void) strcpy(label, "Unsol CT"); 4153*82527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 4154*82527734SSukumar Swaminathan break; 4155*82527734SSukumar Swaminathan 4156*82527734SSukumar Swaminathan default: 4157*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4158*82527734SSukumar Swaminathan "RQ ENTRY: Unexpected FC type (0x%x) received. Dropping...", 4159*82527734SSukumar Swaminathan fchdr.type); 4160*82527734SSukumar Swaminathan 4161*82527734SSukumar Swaminathan goto done; 4162*82527734SSukumar Swaminathan } 4163*82527734SSukumar Swaminathan /* Fc Header is valid */ 4164*82527734SSukumar Swaminathan 4165*82527734SSukumar Swaminathan /* Check if this is an active sequence */ 4166*82527734SSukumar Swaminathan iocbq = emlxs_sli4_rxq_get(hba, &fchdr); 4167*82527734SSukumar Swaminathan 4168*82527734SSukumar Swaminathan if (!iocbq) { 4169*82527734SSukumar Swaminathan if (fchdr.type != 0) { 4170*82527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_FIRST_SEQ)) { 4171*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4172*82527734SSukumar Swaminathan "RQ ENTRY: %s: First of sequence not" \ 4173*82527734SSukumar Swaminathan " set. Dropping...", 4174*82527734SSukumar Swaminathan label); 4175*82527734SSukumar Swaminathan 4176*82527734SSukumar Swaminathan goto done; 4177*82527734SSukumar Swaminathan } 4178*82527734SSukumar Swaminathan } 4179*82527734SSukumar Swaminathan 4180*82527734SSukumar Swaminathan if (fchdr.seq_cnt != 0) { 4181*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4182*82527734SSukumar Swaminathan "RQ ENTRY: %s: Sequence count not zero (%d). " \ 4183*82527734SSukumar Swaminathan "Dropping...", 4184*82527734SSukumar Swaminathan label, fchdr.seq_cnt); 4185*82527734SSukumar Swaminathan 4186*82527734SSukumar Swaminathan goto done; 4187*82527734SSukumar Swaminathan } 4188*82527734SSukumar Swaminathan 4189*82527734SSukumar Swaminathan /* Find vport (defaults to physical port) */ 4190*82527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 4191*82527734SSukumar Swaminathan vport = &VPORT(i); 4192*82527734SSukumar Swaminathan 4193*82527734SSukumar Swaminathan if (vport->did == fchdr.d_id) { 4194*82527734SSukumar Swaminathan port = vport; 4195*82527734SSukumar Swaminathan break; 4196*82527734SSukumar Swaminathan } 4197*82527734SSukumar Swaminathan } 4198*82527734SSukumar Swaminathan 4199*82527734SSukumar Swaminathan /* Allocate an IOCBQ */ 4200*82527734SSukumar Swaminathan iocbq = (emlxs_iocbq_t *)emlxs_mem_get(hba, 4201*82527734SSukumar Swaminathan MEM_IOCB, 1); 4202*82527734SSukumar Swaminathan 4203*82527734SSukumar Swaminathan if (!iocbq) { 4204*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4205*82527734SSukumar Swaminathan "RQ ENTRY: %s: Out of IOCB " \ 4206*82527734SSukumar Swaminathan "resources. Dropping...", 4207*82527734SSukumar Swaminathan label); 4208*82527734SSukumar Swaminathan 4209*82527734SSukumar Swaminathan goto done; 4210*82527734SSukumar Swaminathan } 4211*82527734SSukumar Swaminathan 4212*82527734SSukumar Swaminathan seq_mp = NULL; 4213*82527734SSukumar Swaminathan if (fchdr.type != 0) { 4214*82527734SSukumar Swaminathan /* Allocate a buffer */ 4215*82527734SSukumar Swaminathan seq_mp = (MATCHMAP *)emlxs_mem_get(hba, buf_type, 1); 4216*82527734SSukumar Swaminathan 4217*82527734SSukumar Swaminathan if (!seq_mp) { 4218*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4219*82527734SSukumar Swaminathan "RQ ENTRY: %s: Out of buffer " \ 4220*82527734SSukumar Swaminathan "resources. Dropping...", 4221*82527734SSukumar Swaminathan label); 4222*82527734SSukumar Swaminathan 4223*82527734SSukumar Swaminathan goto done; 4224*82527734SSukumar Swaminathan } 4225*82527734SSukumar Swaminathan 4226*82527734SSukumar Swaminathan iocbq->bp = (uint8_t *)seq_mp; 4227*82527734SSukumar Swaminathan } 4228*82527734SSukumar Swaminathan 4229*82527734SSukumar Swaminathan node = (void *)emlxs_node_find_did(port, fchdr.s_id); 4230*82527734SSukumar Swaminathan if (node == NULL) { 4231*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4232*82527734SSukumar Swaminathan "RQ ENTRY: %s: Node not found. sid=%x", 4233*82527734SSukumar Swaminathan label, fchdr.s_id); 4234*82527734SSukumar Swaminathan } 4235*82527734SSukumar Swaminathan 4236*82527734SSukumar Swaminathan /* Initialize the iocbq */ 4237*82527734SSukumar Swaminathan iocbq->port = port; 4238*82527734SSukumar Swaminathan iocbq->channel = cp; 4239*82527734SSukumar Swaminathan iocbq->node = node; 4240*82527734SSukumar Swaminathan 4241*82527734SSukumar Swaminathan iocb = &iocbq->iocb; 4242*82527734SSukumar Swaminathan iocb->RXSEQCNT = 0; 4243*82527734SSukumar Swaminathan iocb->RXSEQLEN = 0; 4244*82527734SSukumar Swaminathan 4245*82527734SSukumar Swaminathan seq_len = 0; 4246*82527734SSukumar Swaminathan seq_cnt = 0; 4247*82527734SSukumar Swaminathan 4248*82527734SSukumar Swaminathan } else { 4249*82527734SSukumar Swaminathan 4250*82527734SSukumar Swaminathan iocb = &iocbq->iocb; 4251*82527734SSukumar Swaminathan port = iocbq->port; 4252*82527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 4253*82527734SSukumar Swaminathan 4254*82527734SSukumar Swaminathan seq_mp = (MATCHMAP *)iocbq->bp; 4255*82527734SSukumar Swaminathan seq_len = iocb->RXSEQLEN; 4256*82527734SSukumar Swaminathan seq_cnt = iocb->RXSEQCNT; 4257*82527734SSukumar Swaminathan 4258*82527734SSukumar Swaminathan /* Check sequence order */ 4259*82527734SSukumar Swaminathan if (fchdr.seq_cnt != seq_cnt) { 4260*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4261*82527734SSukumar Swaminathan "RQ ENTRY: %s: Out of order frame received " \ 4262*82527734SSukumar Swaminathan "(%d != %d). Dropping...", 4263*82527734SSukumar Swaminathan label, fchdr.seq_cnt, seq_cnt); 4264*82527734SSukumar Swaminathan 4265*82527734SSukumar Swaminathan goto done; 4266*82527734SSukumar Swaminathan } 4267*82527734SSukumar Swaminathan } 4268*82527734SSukumar Swaminathan 4269*82527734SSukumar Swaminathan /* We now have an iocbq */ 4270*82527734SSukumar Swaminathan 4271*82527734SSukumar Swaminathan /* Save the frame data to our seq buffer */ 4272*82527734SSukumar Swaminathan if (cqe->data_size && seq_mp) { 4273*82527734SSukumar Swaminathan /* Get the next data rqb */ 4274*82527734SSukumar Swaminathan data_mp = data_rq->rqb[host_index]; 4275*82527734SSukumar Swaminathan 4276*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(data_mp->dma_handle, 0, 4277*82527734SSukumar Swaminathan cqe->data_size, DDI_DMA_SYNC_FORKERNEL); 4278*82527734SSukumar Swaminathan 4279*82527734SSukumar Swaminathan data = (uint32_t *)data_mp->virt; 4280*82527734SSukumar Swaminathan 4281*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4282*82527734SSukumar Swaminathan "RQ DAT[%d]: %08x %08x %08x %08x %08x %08x ...", 4283*82527734SSukumar Swaminathan host_index, data[0], data[1], data[2], data[3], 4284*82527734SSukumar Swaminathan data[4], data[5]); 4285*82527734SSukumar Swaminathan 4286*82527734SSukumar Swaminathan /* Check sequence length */ 4287*82527734SSukumar Swaminathan if ((seq_len + cqe->data_size) > seq_mp->size) { 4288*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4289*82527734SSukumar Swaminathan "RQ ENTRY: %s: Sequence buffer overflow. " \ 4290*82527734SSukumar Swaminathan "(%d > %d). Dropping...", 4291*82527734SSukumar Swaminathan label, (seq_len + cqe->data_size), seq_mp->size); 4292*82527734SSukumar Swaminathan 4293*82527734SSukumar Swaminathan goto done; 4294*82527734SSukumar Swaminathan } 4295*82527734SSukumar Swaminathan 4296*82527734SSukumar Swaminathan /* Copy data to local receive buffer */ 4297*82527734SSukumar Swaminathan bcopy((uint8_t *)data, ((uint8_t *)seq_mp->virt + 4298*82527734SSukumar Swaminathan seq_len), cqe->data_size); 4299*82527734SSukumar Swaminathan 4300*82527734SSukumar Swaminathan seq_len += cqe->data_size; 4301*82527734SSukumar Swaminathan } 4302*82527734SSukumar Swaminathan 4303*82527734SSukumar Swaminathan /* If this is not the last frame of sequence, queue it. */ 4304*82527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_END_SEQ)) { 4305*82527734SSukumar Swaminathan /* Save sequence header */ 4306*82527734SSukumar Swaminathan if (seq_cnt == 0) { 4307*82527734SSukumar Swaminathan bcopy((uint8_t *)&fchdr, (uint8_t *)iocb->RXFCHDR, 4308*82527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 4309*82527734SSukumar Swaminathan } 4310*82527734SSukumar Swaminathan 4311*82527734SSukumar Swaminathan /* Update sequence info in iocb */ 4312*82527734SSukumar Swaminathan iocb->RXSEQCNT = seq_cnt + 1; 4313*82527734SSukumar Swaminathan iocb->RXSEQLEN = seq_len; 4314*82527734SSukumar Swaminathan 4315*82527734SSukumar Swaminathan /* Queue iocbq for next frame */ 4316*82527734SSukumar Swaminathan emlxs_sli4_rxq_put(hba, iocbq); 4317*82527734SSukumar Swaminathan 4318*82527734SSukumar Swaminathan /* Don't free resources */ 4319*82527734SSukumar Swaminathan iocbq = NULL; 4320*82527734SSukumar Swaminathan 4321*82527734SSukumar Swaminathan /* No need to abort */ 4322*82527734SSukumar Swaminathan abort = 0; 4323*82527734SSukumar Swaminathan 4324*82527734SSukumar Swaminathan goto done; 4325*82527734SSukumar Swaminathan } 4326*82527734SSukumar Swaminathan 4327*82527734SSukumar Swaminathan emlxs_sli4_rq_post(hba, hdr_rq->qid); 4328*82527734SSukumar Swaminathan posted = 1; 4329*82527734SSukumar Swaminathan 4330*82527734SSukumar Swaminathan /* End of sequence found. Process request now. */ 4331*82527734SSukumar Swaminathan 4332*82527734SSukumar Swaminathan if (seq_cnt > 0) { 4333*82527734SSukumar Swaminathan /* Retrieve first frame of sequence */ 4334*82527734SSukumar Swaminathan bcopy((uint8_t *)iocb->RXFCHDR, (uint8_t *)&fchdr, 4335*82527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 4336*82527734SSukumar Swaminathan 4337*82527734SSukumar Swaminathan bzero((uint8_t *)iocb, sizeof (emlxs_iocb_t)); 4338*82527734SSukumar Swaminathan } 4339*82527734SSukumar Swaminathan 4340*82527734SSukumar Swaminathan /* Build rcv iocb and process it */ 4341*82527734SSukumar Swaminathan switch (fchdr.type) { 4342*82527734SSukumar Swaminathan case 0: /* BLS */ 4343*82527734SSukumar Swaminathan 4344*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4345*82527734SSukumar Swaminathan "RQ ENTRY: %s: xid:%x sid:%x. Sending BLS ACC...", 4346*82527734SSukumar Swaminathan label, fchdr.ox_id, fchdr.s_id); 4347*82527734SSukumar Swaminathan 4348*82527734SSukumar Swaminathan iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 4349*82527734SSukumar Swaminathan 4350*82527734SSukumar Swaminathan /* Set up an iotag using special Abort iotags */ 4351*82527734SSukumar Swaminathan if ((hba->fc_oor_iotag >= EMLXS_MAX_ABORT_TAG)) { 4352*82527734SSukumar Swaminathan hba->fc_oor_iotag = hba->max_iotag; 4353*82527734SSukumar Swaminathan } 4354*82527734SSukumar Swaminathan iotag = hba->fc_oor_iotag++; 4355*82527734SSukumar Swaminathan 4356*82527734SSukumar Swaminathan /* BLS ACC Response */ 4357*82527734SSukumar Swaminathan wqe = &iocbq->wqe; 4358*82527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 4359*82527734SSukumar Swaminathan 4360*82527734SSukumar Swaminathan wqe->Command = CMD_XMIT_BLS_RSP64_CX; 4361*82527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 4362*82527734SSukumar Swaminathan 4363*82527734SSukumar Swaminathan wqe->un.BlsRsp.Payload0 = 0x80; 4364*82527734SSukumar Swaminathan wqe->un.BlsRsp.Payload1 = fchdr.seq_id; 4365*82527734SSukumar Swaminathan 4366*82527734SSukumar Swaminathan wqe->un.BlsRsp.OXId = fchdr.ox_id; 4367*82527734SSukumar Swaminathan wqe->un.BlsRsp.RXId = fchdr.rx_id; 4368*82527734SSukumar Swaminathan 4369*82527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntLow = 0; 4370*82527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntHigh = 0xFFFF; 4371*82527734SSukumar Swaminathan 4372*82527734SSukumar Swaminathan wqe->un.BlsRsp.XO = 0; 4373*82527734SSukumar Swaminathan wqe->un.BlsRsp.AR = 0; 4374*82527734SSukumar Swaminathan wqe->un.BlsRsp.PT = 1; 4375*82527734SSukumar Swaminathan wqe->un.BlsRsp.RemoteId = fchdr.s_id; 4376*82527734SSukumar Swaminathan 4377*82527734SSukumar Swaminathan wqe->PU = 0x3; 4378*82527734SSukumar Swaminathan wqe->ContextTag = port->vpi + hba->vpi_base; 4379*82527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 4380*82527734SSukumar Swaminathan wqe->OXId = (volatile uint16_t) fchdr.ox_id; 4381*82527734SSukumar Swaminathan wqe->XRITag = 0xffff; 4382*82527734SSukumar Swaminathan 4383*82527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 4384*82527734SSukumar Swaminathan wqe->CCPE = 1; 4385*82527734SSukumar Swaminathan wqe->CCP = fchdr.rsvd; 4386*82527734SSukumar Swaminathan } 4387*82527734SSukumar Swaminathan 4388*82527734SSukumar Swaminathan wqe->Class = CLASS3; 4389*82527734SSukumar Swaminathan wqe->RequestTag = iotag; 4390*82527734SSukumar Swaminathan wqe->CQId = 0x3ff; 4391*82527734SSukumar Swaminathan 4392*82527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(hba, iocbq->channel, iocbq); 4393*82527734SSukumar Swaminathan 4394*82527734SSukumar Swaminathan break; 4395*82527734SSukumar Swaminathan 4396*82527734SSukumar Swaminathan case 1: /* ELS */ 4397*82527734SSukumar Swaminathan cmd = *((uint32_t *)seq_mp->virt); 4398*82527734SSukumar Swaminathan cmd &= ELS_CMD_MASK; 4399*82527734SSukumar Swaminathan rp = NULL; 4400*82527734SSukumar Swaminathan 4401*82527734SSukumar Swaminathan if (cmd != ELS_CMD_LOGO) { 4402*82527734SSukumar Swaminathan rp = EMLXS_NODE_TO_RPI(hba, node); 4403*82527734SSukumar Swaminathan } 4404*82527734SSukumar Swaminathan 4405*82527734SSukumar Swaminathan if (!rp) { 4406*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 4407*82527734SSukumar Swaminathan rp = &fp->scratch_rpi; 4408*82527734SSukumar Swaminathan } 4409*82527734SSukumar Swaminathan 4410*82527734SSukumar Swaminathan xp = emlxs_sli4_reserve_xri(hba, rp); 4411*82527734SSukumar Swaminathan 4412*82527734SSukumar Swaminathan if (!xp) { 4413*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4414*82527734SSukumar Swaminathan "RQ ENTRY: %s: Out of exchange " \ 4415*82527734SSukumar Swaminathan "resources. Dropping...", 4416*82527734SSukumar Swaminathan label); 4417*82527734SSukumar Swaminathan 4418*82527734SSukumar Swaminathan goto done; 4419*82527734SSukumar Swaminathan } 4420*82527734SSukumar Swaminathan 4421*82527734SSukumar Swaminathan xp->rx_id = fchdr.ox_id; 4422*82527734SSukumar Swaminathan 4423*82527734SSukumar Swaminathan /* Build CMD_RCV_ELS64_CX */ 4424*82527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeFlags = 0; 4425*82527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeSize = seq_len; 4426*82527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrLow = PADDR_LO(seq_mp->phys); 4427*82527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrHigh = PADDR_HI(seq_mp->phys); 4428*82527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 4429*82527734SSukumar Swaminathan 4430*82527734SSukumar Swaminathan iocb->un.rcvels64.remoteID = fchdr.s_id; 4431*82527734SSukumar Swaminathan iocb->un.rcvels64.parmRo = fchdr.d_id; 4432*82527734SSukumar Swaminathan 4433*82527734SSukumar Swaminathan iocb->ULPPU = 0x3; 4434*82527734SSukumar Swaminathan iocb->ULPCONTEXT = xp->XRI; 4435*82527734SSukumar Swaminathan iocb->ULPIOTAG = ((node)? node->nlp_Rpi:0); 4436*82527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 4437*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_ELS64_CX; 4438*82527734SSukumar Swaminathan 4439*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 4440*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.vpi = port->vpi + hba->vpi_base; 4441*82527734SSukumar Swaminathan 4442*82527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 4443*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 4444*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 4445*82527734SSukumar Swaminathan } 4446*82527734SSukumar Swaminathan 4447*82527734SSukumar Swaminathan (void) emlxs_els_handle_unsol_req(port, iocbq->channel, 4448*82527734SSukumar Swaminathan iocbq, seq_mp, seq_len); 4449*82527734SSukumar Swaminathan 4450*82527734SSukumar Swaminathan break; 4451*82527734SSukumar Swaminathan 4452*82527734SSukumar Swaminathan case 0x20: /* CT */ 4453*82527734SSukumar Swaminathan 4454*82527734SSukumar Swaminathan if (!node) { 4455*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4456*82527734SSukumar Swaminathan "RQ ENTRY: %s: Node not found (did=%x). " \ 4457*82527734SSukumar Swaminathan "Dropping...", 4458*82527734SSukumar Swaminathan label, fchdr.d_id); 4459*82527734SSukumar Swaminathan 4460*82527734SSukumar Swaminathan goto done; 4461*82527734SSukumar Swaminathan } 4462*82527734SSukumar Swaminathan 4463*82527734SSukumar Swaminathan rp = EMLXS_NODE_TO_RPI(hba, node); 4464*82527734SSukumar Swaminathan 4465*82527734SSukumar Swaminathan if (!rp) { 4466*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4467*82527734SSukumar Swaminathan "RQ ENTRY: %s: RPI not found (did=%x rpi=%x). " \ 4468*82527734SSukumar Swaminathan "Dropping...", 4469*82527734SSukumar Swaminathan label, fchdr.d_id, node->nlp_Rpi); 4470*82527734SSukumar Swaminathan 4471*82527734SSukumar Swaminathan goto done; 4472*82527734SSukumar Swaminathan } 4473*82527734SSukumar Swaminathan 4474*82527734SSukumar Swaminathan xp = emlxs_sli4_reserve_xri(hba, rp); 4475*82527734SSukumar Swaminathan 4476*82527734SSukumar Swaminathan if (!xp) { 4477*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4478*82527734SSukumar Swaminathan "RQ ENTRY: %s: Out of exchange " \ 4479*82527734SSukumar Swaminathan "resources. Dropping...", 4480*82527734SSukumar Swaminathan label); 4481*82527734SSukumar Swaminathan 4482*82527734SSukumar Swaminathan goto done; 4483*82527734SSukumar Swaminathan } 4484*82527734SSukumar Swaminathan 4485*82527734SSukumar Swaminathan xp->rx_id = fchdr.ox_id; 4486*82527734SSukumar Swaminathan 4487*82527734SSukumar Swaminathan /* Build CMD_RCV_SEQ64_CX */ 4488*82527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeFlags = 0; 4489*82527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeSize = seq_len; 4490*82527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrLow = PADDR_LO(seq_mp->phys); 4491*82527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrHigh = PADDR_HI(seq_mp->phys); 4492*82527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 4493*82527734SSukumar Swaminathan 4494*82527734SSukumar Swaminathan iocb->un.rcvseq64.xrsqRo = 0; 4495*82527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Rctl = fchdr.r_ctl; 4496*82527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Type = fchdr.type; 4497*82527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Dfctl = fchdr.df_ctl; 4498*82527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Fctl = fchdr.f_ctl; 4499*82527734SSukumar Swaminathan 4500*82527734SSukumar Swaminathan iocb->ULPPU = 0x3; 4501*82527734SSukumar Swaminathan iocb->ULPCONTEXT = xp->XRI; 4502*82527734SSukumar Swaminathan iocb->ULPIOTAG = rp->RPI; 4503*82527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 4504*82527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_SEQ64_CX; 4505*82527734SSukumar Swaminathan 4506*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 4507*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.vpi = port->vpi + hba->vpi_base; 4508*82527734SSukumar Swaminathan 4509*82527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 4510*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 4511*82527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 4512*82527734SSukumar Swaminathan } 4513*82527734SSukumar Swaminathan 4514*82527734SSukumar Swaminathan (void) emlxs_ct_handle_unsol_req(port, iocbq->channel, 4515*82527734SSukumar Swaminathan iocbq, seq_mp, seq_len); 4516*82527734SSukumar Swaminathan 4517*82527734SSukumar Swaminathan break; 4518*82527734SSukumar Swaminathan } 4519*82527734SSukumar Swaminathan 4520*82527734SSukumar Swaminathan /* Sequence handled, no need to abort */ 4521*82527734SSukumar Swaminathan abort = 0; 4522*82527734SSukumar Swaminathan 4523*82527734SSukumar Swaminathan done: 4524*82527734SSukumar Swaminathan 4525*82527734SSukumar Swaminathan if (!posted) { 4526*82527734SSukumar Swaminathan emlxs_sli4_rq_post(hba, hdr_rq->qid); 4527*82527734SSukumar Swaminathan } 4528*82527734SSukumar Swaminathan 4529*82527734SSukumar Swaminathan if (abort) { 4530*82527734SSukumar Swaminathan /* Send ABTS for this exchange */ 4531*82527734SSukumar Swaminathan /* !!! Currently, we have no implementation for this !!! */ 4532*82527734SSukumar Swaminathan abort = 0; 4533*82527734SSukumar Swaminathan } 4534*82527734SSukumar Swaminathan 4535*82527734SSukumar Swaminathan /* Return memory resources to pools */ 4536*82527734SSukumar Swaminathan if (iocbq) { 4537*82527734SSukumar Swaminathan if (iocbq->bp) { 4538*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, buf_type, 4539*82527734SSukumar Swaminathan (uint8_t *)iocbq->bp); 4540*82527734SSukumar Swaminathan } 4541*82527734SSukumar Swaminathan 4542*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_IOCB, (uint8_t *)iocbq); 4543*82527734SSukumar Swaminathan } 4544*82527734SSukumar Swaminathan 4545*82527734SSukumar Swaminathan return; 4546*82527734SSukumar Swaminathan 4547*82527734SSukumar Swaminathan } /* emlxs_sli4_process_unsol_rcv() */ 4548*82527734SSukumar Swaminathan 4549*82527734SSukumar Swaminathan 4550*82527734SSukumar Swaminathan /*ARGSUSED*/ 4551*82527734SSukumar Swaminathan static void 4552*82527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(emlxs_hba_t *hba, CQ_DESC_t *cq, 4553*82527734SSukumar Swaminathan CQE_XRI_Abort_t *cqe) 4554*82527734SSukumar Swaminathan { 4555*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4556*82527734SSukumar Swaminathan XRIobj_t *xp; 4557*82527734SSukumar Swaminathan 4558*82527734SSukumar Swaminathan xp = emlxs_sli4_find_xri(hba, cqe->XRI); 4559*82527734SSukumar Swaminathan if (xp == NULL) { 4560*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4561*82527734SSukumar Swaminathan "CQ ENTRY: process xri aborted ignored"); 4562*82527734SSukumar Swaminathan return; 4563*82527734SSukumar Swaminathan } 4564*82527734SSukumar Swaminathan 4565*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4566*82527734SSukumar Swaminathan "CQ ENTRY: process xri x%x aborted: IA %d EO %d BR %d", 4567*82527734SSukumar Swaminathan cqe->XRI, cqe->IA, cqe->EO, cqe->BR); 4568*82527734SSukumar Swaminathan 4569*82527734SSukumar Swaminathan if (!(xp->state & RESOURCE_XRI_ABORT_INP)) { 4570*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4571*82527734SSukumar Swaminathan "XRI Aborted: Bad state: x%x xri x%x", 4572*82527734SSukumar Swaminathan xp->state, xp->XRI); 4573*82527734SSukumar Swaminathan return; 4574*82527734SSukumar Swaminathan } 4575*82527734SSukumar Swaminathan 4576*82527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 4577*82527734SSukumar Swaminathan emlxs_sli4_free_xri(hba, 0, xp); 4578*82527734SSukumar Swaminathan 4579*82527734SSukumar Swaminathan } /* emlxs_sli4_process_xri_aborted () */ 4580*82527734SSukumar Swaminathan 4581*82527734SSukumar Swaminathan 4582*82527734SSukumar Swaminathan /*ARGSUSED*/ 4583*82527734SSukumar Swaminathan static void 4584*82527734SSukumar Swaminathan emlxs_sli4_process_cq(emlxs_hba_t *hba, CQ_DESC_t *cq) 4585*82527734SSukumar Swaminathan { 4586*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4587*82527734SSukumar Swaminathan CQE_u *cqe; 4588*82527734SSukumar Swaminathan CQE_u cq_entry; 4589*82527734SSukumar Swaminathan uint32_t cqdb; 4590*82527734SSukumar Swaminathan int num_entries = 0; 4591*82527734SSukumar Swaminathan 4592*82527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 4593*82527734SSukumar Swaminathan 4594*82527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 4595*82527734SSukumar Swaminathan cqe += cq->host_index; 4596*82527734SSukumar Swaminathan 4597*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(cq->addr.dma_handle, 0, 4598*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 4599*82527734SSukumar Swaminathan 4600*82527734SSukumar Swaminathan for (;;) { 4601*82527734SSukumar Swaminathan cq_entry.word[3] = BE_SWAP32(cqe->word[3]); 4602*82527734SSukumar Swaminathan if (!(cq_entry.word[3] & CQE_VALID)) 4603*82527734SSukumar Swaminathan break; 4604*82527734SSukumar Swaminathan 4605*82527734SSukumar Swaminathan cq_entry.word[2] = BE_SWAP32(cqe->word[2]); 4606*82527734SSukumar Swaminathan cq_entry.word[1] = BE_SWAP32(cqe->word[1]); 4607*82527734SSukumar Swaminathan cq_entry.word[0] = BE_SWAP32(cqe->word[0]); 4608*82527734SSukumar Swaminathan 4609*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4610*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4611*82527734SSukumar Swaminathan "CQ ENTRY: %08x %08x %08x %08x", cq_entry.word[0], 4612*82527734SSukumar Swaminathan cq_entry.word[1], cq_entry.word[2], cq_entry.word[3]); 4613*82527734SSukumar Swaminathan #endif 4614*82527734SSukumar Swaminathan 4615*82527734SSukumar Swaminathan num_entries++; 4616*82527734SSukumar Swaminathan cqe->word[3] = 0; 4617*82527734SSukumar Swaminathan 4618*82527734SSukumar Swaminathan cq->host_index++; 4619*82527734SSukumar Swaminathan if (cq->host_index >= cq->max_index) { 4620*82527734SSukumar Swaminathan cq->host_index = 0; 4621*82527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 4622*82527734SSukumar Swaminathan } else { 4623*82527734SSukumar Swaminathan cqe++; 4624*82527734SSukumar Swaminathan } 4625*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4626*82527734SSukumar Swaminathan 4627*82527734SSukumar Swaminathan /* Now handle specific cq type */ 4628*82527734SSukumar Swaminathan if (cq->type == EMLXS_CQ_TYPE_GROUP1) { 4629*82527734SSukumar Swaminathan if (cq_entry.cqAsyncEntry.async_evt) { 4630*82527734SSukumar Swaminathan emlxs_sli4_process_async_event(hba, 4631*82527734SSukumar Swaminathan (CQE_ASYNC_t *)&cq_entry); 4632*82527734SSukumar Swaminathan } else { 4633*82527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(hba, 4634*82527734SSukumar Swaminathan (CQE_MBOX_t *)&cq_entry); 4635*82527734SSukumar Swaminathan } 4636*82527734SSukumar Swaminathan } else { /* EMLXS_CQ_TYPE_GROUP2 */ 4637*82527734SSukumar Swaminathan switch (cq_entry.cqCmplEntry.Code) { 4638*82527734SSukumar Swaminathan case CQE_TYPE_WQ_COMPLETION: 4639*82527734SSukumar Swaminathan if (cq_entry.cqCmplEntry.RequestTag < 4640*82527734SSukumar Swaminathan hba->max_iotag) { 4641*82527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(hba, cq, 4642*82527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 4643*82527734SSukumar Swaminathan } else { 4644*82527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(hba, cq, 4645*82527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 4646*82527734SSukumar Swaminathan } 4647*82527734SSukumar Swaminathan break; 4648*82527734SSukumar Swaminathan case CQE_TYPE_RELEASE_WQE: 4649*82527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(hba, cq, 4650*82527734SSukumar Swaminathan (CQE_RelWQ_t *)&cq_entry); 4651*82527734SSukumar Swaminathan break; 4652*82527734SSukumar Swaminathan case CQE_TYPE_UNSOL_RCV: 4653*82527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(hba, cq, 4654*82527734SSukumar Swaminathan (CQE_UnsolRcv_t *)&cq_entry); 4655*82527734SSukumar Swaminathan break; 4656*82527734SSukumar Swaminathan case CQE_TYPE_XRI_ABORTED: 4657*82527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(hba, cq, 4658*82527734SSukumar Swaminathan (CQE_XRI_Abort_t *)&cq_entry); 4659*82527734SSukumar Swaminathan break; 4660*82527734SSukumar Swaminathan default: 4661*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4662*82527734SSukumar Swaminathan "Invalid CQ entry %d: %08x %08x %08x %08x", 4663*82527734SSukumar Swaminathan cq_entry.cqCmplEntry.Code, cq_entry.word[0], 4664*82527734SSukumar Swaminathan cq_entry.word[1], cq_entry.word[2], 4665*82527734SSukumar Swaminathan cq_entry.word[3]); 4666*82527734SSukumar Swaminathan break; 4667*82527734SSukumar Swaminathan } 4668*82527734SSukumar Swaminathan } 4669*82527734SSukumar Swaminathan 4670*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 4671*82527734SSukumar Swaminathan } 4672*82527734SSukumar Swaminathan 4673*82527734SSukumar Swaminathan cqdb = cq->qid; 4674*82527734SSukumar Swaminathan cqdb |= CQ_DB_REARM; 4675*82527734SSukumar Swaminathan if (num_entries != 0) { 4676*82527734SSukumar Swaminathan cqdb |= ((num_entries << CQ_DB_POP_SHIFT) & CQ_DB_POP_MASK); 4677*82527734SSukumar Swaminathan } 4678*82527734SSukumar Swaminathan 4679*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4680*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4681*82527734SSukumar Swaminathan "CQ CLEAR: %08x: pops:x%x", cqdb, num_entries); 4682*82527734SSukumar Swaminathan #endif 4683*82527734SSukumar Swaminathan 4684*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), cqdb); 4685*82527734SSukumar Swaminathan 4686*82527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 4687*82527734SSukumar Swaminathan 4688*82527734SSukumar Swaminathan } /* emlxs_sli4_process_cq() */ 4689*82527734SSukumar Swaminathan 4690*82527734SSukumar Swaminathan 4691*82527734SSukumar Swaminathan /*ARGSUSED*/ 4692*82527734SSukumar Swaminathan static void 4693*82527734SSukumar Swaminathan emlxs_sli4_process_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 4694*82527734SSukumar Swaminathan { 4695*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4696*82527734SSukumar Swaminathan uint32_t eqdb; 4697*82527734SSukumar Swaminathan uint32_t *ptr; 4698*82527734SSukumar Swaminathan CHANNEL *cp; 4699*82527734SSukumar Swaminathan EQE_u eqe; 4700*82527734SSukumar Swaminathan uint32_t i; 4701*82527734SSukumar Swaminathan uint32_t value; 4702*82527734SSukumar Swaminathan int num_entries = 0; 4703*82527734SSukumar Swaminathan 4704*82527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 4705*82527734SSukumar Swaminathan 4706*82527734SSukumar Swaminathan ptr = eq->addr.virt; 4707*82527734SSukumar Swaminathan ptr += eq->host_index; 4708*82527734SSukumar Swaminathan 4709*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, 0, 4710*82527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 4711*82527734SSukumar Swaminathan 4712*82527734SSukumar Swaminathan for (;;) { 4713*82527734SSukumar Swaminathan eqe.word = *ptr; 4714*82527734SSukumar Swaminathan eqe.word = BE_SWAP32(eqe.word); 4715*82527734SSukumar Swaminathan 4716*82527734SSukumar Swaminathan if (!(eqe.word & EQE_VALID)) 4717*82527734SSukumar Swaminathan break; 4718*82527734SSukumar Swaminathan 4719*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4720*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4721*82527734SSukumar Swaminathan "EQ ENTRY: %08x", eqe.word); 4722*82527734SSukumar Swaminathan #endif 4723*82527734SSukumar Swaminathan 4724*82527734SSukumar Swaminathan *ptr = 0; 4725*82527734SSukumar Swaminathan num_entries++; 4726*82527734SSukumar Swaminathan eq->host_index++; 4727*82527734SSukumar Swaminathan if (eq->host_index >= eq->max_index) { 4728*82527734SSukumar Swaminathan eq->host_index = 0; 4729*82527734SSukumar Swaminathan ptr = eq->addr.virt; 4730*82527734SSukumar Swaminathan } else { 4731*82527734SSukumar Swaminathan ptr++; 4732*82527734SSukumar Swaminathan } 4733*82527734SSukumar Swaminathan 4734*82527734SSukumar Swaminathan value = hba->sli.sli4.cq_map[eqe.entry.CQId]; 4735*82527734SSukumar Swaminathan 4736*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4737*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4738*82527734SSukumar Swaminathan "EQ ENTRY: CQIndex:x%x: cqid:x%x", value, eqe.entry.CQId); 4739*82527734SSukumar Swaminathan #endif 4740*82527734SSukumar Swaminathan 4741*82527734SSukumar Swaminathan emlxs_sli4_process_cq(hba, &hba->sli.sli4.cq[value]); 4742*82527734SSukumar Swaminathan } 4743*82527734SSukumar Swaminathan 4744*82527734SSukumar Swaminathan eqdb = eq->qid; 4745*82527734SSukumar Swaminathan eqdb |= (EQ_DB_CLEAR | EQ_DB_EVENT | EQ_DB_REARM); 4746*82527734SSukumar Swaminathan 4747*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4748*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4749*82527734SSukumar Swaminathan "EQ CLEAR: %08x: pops:x%x", eqdb, num_entries); 4750*82527734SSukumar Swaminathan #endif 4751*82527734SSukumar Swaminathan 4752*82527734SSukumar Swaminathan if (num_entries != 0) { 4753*82527734SSukumar Swaminathan eqdb |= ((num_entries << EQ_DB_POP_SHIFT) & EQ_DB_POP_MASK); 4754*82527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 4755*82527734SSukumar Swaminathan cp = &hba->chan[i]; 4756*82527734SSukumar Swaminathan if (cp->chan_flag & EMLXS_NEEDS_TRIGGER) { 4757*82527734SSukumar Swaminathan cp->chan_flag &= ~EMLXS_NEEDS_TRIGGER; 4758*82527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 4759*82527734SSukumar Swaminathan emlxs_proc_channel, cp); 4760*82527734SSukumar Swaminathan } 4761*82527734SSukumar Swaminathan } 4762*82527734SSukumar Swaminathan } 4763*82527734SSukumar Swaminathan 4764*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), eqdb); 4765*82527734SSukumar Swaminathan 4766*82527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 4767*82527734SSukumar Swaminathan 4768*82527734SSukumar Swaminathan } /* emlxs_sli4_process_eq() */ 4769*82527734SSukumar Swaminathan 4770*82527734SSukumar Swaminathan 4771*82527734SSukumar Swaminathan #ifdef MSI_SUPPORT 4772*82527734SSukumar Swaminathan /*ARGSUSED*/ 4773*82527734SSukumar Swaminathan static uint32_t 4774*82527734SSukumar Swaminathan emlxs_sli4_msi_intr(char *arg1, char *arg2) 4775*82527734SSukumar Swaminathan { 4776*82527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg1; 4777*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4778*82527734SSukumar Swaminathan uint16_t msgid; 4779*82527734SSukumar Swaminathan int rc; 4780*82527734SSukumar Swaminathan 4781*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4782*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4783*82527734SSukumar Swaminathan "msiINTR arg1:%p arg2:%p", arg1, arg2); 4784*82527734SSukumar Swaminathan #endif 4785*82527734SSukumar Swaminathan 4786*82527734SSukumar Swaminathan /* Check for legacy interrupt handling */ 4787*82527734SSukumar Swaminathan if (hba->intr_type == DDI_INTR_TYPE_FIXED) { 4788*82527734SSukumar Swaminathan rc = emlxs_sli4_intx_intr(arg1); 4789*82527734SSukumar Swaminathan return (rc); 4790*82527734SSukumar Swaminathan } 4791*82527734SSukumar Swaminathan 4792*82527734SSukumar Swaminathan /* Get MSI message id */ 4793*82527734SSukumar Swaminathan msgid = (uint16_t)((unsigned long)arg2); 4794*82527734SSukumar Swaminathan 4795*82527734SSukumar Swaminathan /* Validate the message id */ 4796*82527734SSukumar Swaminathan if (msgid >= hba->intr_count) { 4797*82527734SSukumar Swaminathan msgid = 0; 4798*82527734SSukumar Swaminathan } 4799*82527734SSukumar Swaminathan 4800*82527734SSukumar Swaminathan mutex_enter(&EMLXS_INTR_LOCK(msgid)); 4801*82527734SSukumar Swaminathan 4802*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 4803*82527734SSukumar Swaminathan 4804*82527734SSukumar Swaminathan if (hba->flag & FC_OFFLINE_MODE) { 4805*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4806*82527734SSukumar Swaminathan mutex_exit(&EMLXS_INTR_LOCK(msgid)); 4807*82527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 4808*82527734SSukumar Swaminathan } 4809*82527734SSukumar Swaminathan 4810*82527734SSukumar Swaminathan /* The eq[] index == the MSI vector number */ 4811*82527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[msgid]); 4812*82527734SSukumar Swaminathan 4813*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4814*82527734SSukumar Swaminathan mutex_exit(&EMLXS_INTR_LOCK(msgid)); 4815*82527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 4816*82527734SSukumar Swaminathan 4817*82527734SSukumar Swaminathan } /* emlxs_sli4_msi_intr() */ 4818*82527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 4819*82527734SSukumar Swaminathan 4820*82527734SSukumar Swaminathan 4821*82527734SSukumar Swaminathan /*ARGSUSED*/ 4822*82527734SSukumar Swaminathan static int 4823*82527734SSukumar Swaminathan emlxs_sli4_intx_intr(char *arg) 4824*82527734SSukumar Swaminathan { 4825*82527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg; 4826*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4827*82527734SSukumar Swaminathan 4828*82527734SSukumar Swaminathan #ifdef SLI4_FASTPATH_DEBUG 4829*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4830*82527734SSukumar Swaminathan "intxINTR arg:%p", arg); 4831*82527734SSukumar Swaminathan #endif 4832*82527734SSukumar Swaminathan 4833*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 4834*82527734SSukumar Swaminathan 4835*82527734SSukumar Swaminathan if (hba->flag & FC_OFFLINE_MODE) { 4836*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4837*82527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 4838*82527734SSukumar Swaminathan } 4839*82527734SSukumar Swaminathan 4840*82527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[0]); 4841*82527734SSukumar Swaminathan 4842*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4843*82527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 4844*82527734SSukumar Swaminathan } /* emlxs_sli4_intx_intr() */ 4845*82527734SSukumar Swaminathan 4846*82527734SSukumar Swaminathan 4847*82527734SSukumar Swaminathan static void 4848*82527734SSukumar Swaminathan emlxs_sli4_hba_kill(emlxs_hba_t *hba) 4849*82527734SSukumar Swaminathan { 4850*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4851*82527734SSukumar Swaminathan uint32_t j; 4852*82527734SSukumar Swaminathan 4853*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 4854*82527734SSukumar Swaminathan if (hba->flag & FC_INTERLOCKED) { 4855*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 4856*82527734SSukumar Swaminathan 4857*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4858*82527734SSukumar Swaminathan 4859*82527734SSukumar Swaminathan return; 4860*82527734SSukumar Swaminathan } 4861*82527734SSukumar Swaminathan 4862*82527734SSukumar Swaminathan j = 0; 4863*82527734SSukumar Swaminathan while (j++ < 10000) { 4864*82527734SSukumar Swaminathan if (hba->mbox_queue_flag == 0) { 4865*82527734SSukumar Swaminathan break; 4866*82527734SSukumar Swaminathan } 4867*82527734SSukumar Swaminathan 4868*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4869*82527734SSukumar Swaminathan DELAYUS(100); 4870*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 4871*82527734SSukumar Swaminathan } 4872*82527734SSukumar Swaminathan 4873*82527734SSukumar Swaminathan if (hba->mbox_queue_flag != 0) { 4874*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 4875*82527734SSukumar Swaminathan "Board kill failed. Mailbox busy."); 4876*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4877*82527734SSukumar Swaminathan return; 4878*82527734SSukumar Swaminathan } 4879*82527734SSukumar Swaminathan 4880*82527734SSukumar Swaminathan hba->flag |= FC_INTERLOCKED; 4881*82527734SSukumar Swaminathan 4882*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 4883*82527734SSukumar Swaminathan 4884*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 4885*82527734SSukumar Swaminathan 4886*82527734SSukumar Swaminathan } /* emlxs_sli4_hba_kill() */ 4887*82527734SSukumar Swaminathan 4888*82527734SSukumar Swaminathan 4889*82527734SSukumar Swaminathan static void 4890*82527734SSukumar Swaminathan emlxs_sli4_enable_intr(emlxs_hba_t *hba) 4891*82527734SSukumar Swaminathan { 4892*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 4893*82527734SSukumar Swaminathan int i; 4894*82527734SSukumar Swaminathan int num_cq; 4895*82527734SSukumar Swaminathan uint32_t data; 4896*82527734SSukumar Swaminathan 4897*82527734SSukumar Swaminathan hba->sli.sli4.flag |= EMLXS_SLI4_INTR_ENABLED; 4898*82527734SSukumar Swaminathan 4899*82527734SSukumar Swaminathan num_cq = (hba->intr_count * cfg[CFG_NUM_WQ].current) + 4900*82527734SSukumar Swaminathan EMLXS_CQ_OFFSET_WQ; 4901*82527734SSukumar Swaminathan 4902*82527734SSukumar Swaminathan /* ARM EQ / CQs */ 4903*82527734SSukumar Swaminathan for (i = 0; i < num_cq; i++) { 4904*82527734SSukumar Swaminathan data = hba->sli.sli4.cq[i].qid; 4905*82527734SSukumar Swaminathan data |= CQ_DB_REARM; 4906*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), data); 4907*82527734SSukumar Swaminathan } 4908*82527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 4909*82527734SSukumar Swaminathan data = hba->sli.sli4.eq[i].qid; 4910*82527734SSukumar Swaminathan data |= (EQ_DB_REARM | EQ_DB_EVENT); 4911*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_CQDB_REG(hba), data); 4912*82527734SSukumar Swaminathan } 4913*82527734SSukumar Swaminathan } /* emlxs_sli4_enable_intr() */ 4914*82527734SSukumar Swaminathan 4915*82527734SSukumar Swaminathan 4916*82527734SSukumar Swaminathan static void 4917*82527734SSukumar Swaminathan emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att) 4918*82527734SSukumar Swaminathan { 4919*82527734SSukumar Swaminathan if (att) { 4920*82527734SSukumar Swaminathan return; 4921*82527734SSukumar Swaminathan } 4922*82527734SSukumar Swaminathan 4923*82527734SSukumar Swaminathan hba->sli.sli4.flag &= ~EMLXS_SLI4_INTR_ENABLED; 4924*82527734SSukumar Swaminathan 4925*82527734SSukumar Swaminathan /* Short of reset, we cannot disable interrupts */ 4926*82527734SSukumar Swaminathan } /* emlxs_sli4_disable_intr() */ 4927*82527734SSukumar Swaminathan 4928*82527734SSukumar Swaminathan 4929*82527734SSukumar Swaminathan static void 4930*82527734SSukumar Swaminathan emlxs_sli4_resource_free(emlxs_hba_t *hba) 4931*82527734SSukumar Swaminathan { 4932*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4933*82527734SSukumar Swaminathan MBUF_INFO *buf_info; 4934*82527734SSukumar Swaminathan XRIobj_t *xp; 4935*82527734SSukumar Swaminathan uint32_t i; 4936*82527734SSukumar Swaminathan 4937*82527734SSukumar Swaminathan if (hba->sli.sli4.FCFIp) { 4938*82527734SSukumar Swaminathan kmem_free(hba->sli.sli4.FCFIp, 4939*82527734SSukumar Swaminathan (sizeof (FCFIobj_t) * hba->sli.sli4.FCFICount)); 4940*82527734SSukumar Swaminathan hba->sli.sli4.FCFIp = NULL; 4941*82527734SSukumar Swaminathan } 4942*82527734SSukumar Swaminathan if (hba->sli.sli4.VFIp) { 4943*82527734SSukumar Swaminathan kmem_free(hba->sli.sli4.VFIp, 4944*82527734SSukumar Swaminathan (sizeof (VFIobj_t) * hba->sli.sli4.VFICount)); 4945*82527734SSukumar Swaminathan hba->sli.sli4.VFIp = NULL; 4946*82527734SSukumar Swaminathan } 4947*82527734SSukumar Swaminathan if (hba->sli.sli4.RPIp) { 4948*82527734SSukumar Swaminathan kmem_free(hba->sli.sli4.RPIp, 4949*82527734SSukumar Swaminathan (sizeof (RPIobj_t) * hba->sli.sli4.RPICount)); 4950*82527734SSukumar Swaminathan hba->sli.sli4.RPIp = NULL; 4951*82527734SSukumar Swaminathan } 4952*82527734SSukumar Swaminathan 4953*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.HeaderTmplate; 4954*82527734SSukumar Swaminathan if (buf_info->virt) { 4955*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 4956*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 4957*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 4958*82527734SSukumar Swaminathan } 4959*82527734SSukumar Swaminathan 4960*82527734SSukumar Swaminathan if (hba->sli.sli4.XRIp) { 4961*82527734SSukumar Swaminathan if ((hba->sli.sli4.XRIinuse_f != 4962*82527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) || 4963*82527734SSukumar Swaminathan (hba->sli.sli4.XRIinuse_b != 4964*82527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f)) { 4965*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 4966*82527734SSukumar Swaminathan "XRIs inuse during free!: %p %p != %p\n", 4967*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_f, 4968*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b, 4969*82527734SSukumar Swaminathan &hba->sli.sli4.XRIinuse_f); 4970*82527734SSukumar Swaminathan } 4971*82527734SSukumar Swaminathan xp = hba->sli.sli4.XRIp; 4972*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.XRICount; i++) { 4973*82527734SSukumar Swaminathan buf_info = &xp->SGList; 4974*82527734SSukumar Swaminathan if (buf_info->virt) { 4975*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 4976*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 4977*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 4978*82527734SSukumar Swaminathan } 4979*82527734SSukumar Swaminathan xp++; 4980*82527734SSukumar Swaminathan } 4981*82527734SSukumar Swaminathan kmem_free(hba->sli.sli4.XRIp, 4982*82527734SSukumar Swaminathan (sizeof (XRIobj_t) * hba->sli.sli4.XRICount)); 4983*82527734SSukumar Swaminathan hba->sli.sli4.XRIp = NULL; 4984*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail = NULL; 4985*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_list = NULL; 4986*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count = 0; 4987*82527734SSukumar Swaminathan } 4988*82527734SSukumar Swaminathan 4989*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQS; i++) { 4990*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.eq[i].addr; 4991*82527734SSukumar Swaminathan if (buf_info->virt) { 4992*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 4993*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 4994*82527734SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.eq[i].lastwq_lock); 4995*82527734SSukumar Swaminathan } 4996*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 4997*82527734SSukumar Swaminathan } 4998*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQS; i++) { 4999*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.cq[i].addr; 5000*82527734SSukumar Swaminathan if (buf_info->virt) { 5001*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 5002*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 5003*82527734SSukumar Swaminathan } 5004*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 5005*82527734SSukumar Swaminathan } 5006*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQS; i++) { 5007*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.wq[i].addr; 5008*82527734SSukumar Swaminathan if (buf_info->virt) { 5009*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 5010*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 5011*82527734SSukumar Swaminathan } 5012*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 5013*82527734SSukumar Swaminathan } 5014*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 5015*82527734SSukumar Swaminathan /* Free the RQ */ 5016*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.rq[i].addr; 5017*82527734SSukumar Swaminathan if (buf_info->virt) { 5018*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 5019*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 5020*82527734SSukumar Swaminathan 5021*82527734SSukumar Swaminathan /* Free the RQB pool */ 5022*82527734SSukumar Swaminathan emlxs_mem_pool_free(hba, &hba->sli.sli4.rq[i].rqb_pool); 5023*82527734SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.rq[i].lock); 5024*82527734SSukumar Swaminathan 5025*82527734SSukumar Swaminathan /* Free the associated RXQ */ 5026*82527734SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.rxq[i].lock); 5027*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 5028*82527734SSukumar Swaminathan } 5029*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 5030*82527734SSukumar Swaminathan } 5031*82527734SSukumar Swaminathan 5032*82527734SSukumar Swaminathan /* Free the MQ */ 5033*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.mq.addr; 5034*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5035*82527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 5036*82527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 5037*82527734SSukumar Swaminathan } 5038*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 5039*82527734SSukumar Swaminathan 5040*82527734SSukumar Swaminathan /* Cleanup queue ordinal mapping */ 5041*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQ_IDS; i++) { 5042*82527734SSukumar Swaminathan hba->sli.sli4.eq_map[i] = 0xffff; 5043*82527734SSukumar Swaminathan } 5044*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQ_IDS; i++) { 5045*82527734SSukumar Swaminathan hba->sli.sli4.cq_map[i] = 0xffff; 5046*82527734SSukumar Swaminathan } 5047*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQ_IDS; i++) { 5048*82527734SSukumar Swaminathan hba->sli.sli4.wq_map[i] = 0xffff; 5049*82527734SSukumar Swaminathan } 5050*82527734SSukumar Swaminathan 5051*82527734SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.id_lock); 5052*82527734SSukumar Swaminathan 5053*82527734SSukumar Swaminathan } /* emlxs_sli4_resource_free() */ 5054*82527734SSukumar Swaminathan 5055*82527734SSukumar Swaminathan 5056*82527734SSukumar Swaminathan static int 5057*82527734SSukumar Swaminathan emlxs_sli4_resource_alloc(emlxs_hba_t *hba) 5058*82527734SSukumar Swaminathan { 5059*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5060*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 5061*82527734SSukumar Swaminathan MBUF_INFO *buf_info; 5062*82527734SSukumar Swaminathan uint16_t index; 5063*82527734SSukumar Swaminathan int num_eq; 5064*82527734SSukumar Swaminathan int num_wq; 5065*82527734SSukumar Swaminathan uint32_t i; 5066*82527734SSukumar Swaminathan uint32_t j; 5067*82527734SSukumar Swaminathan uint32_t k; 5068*82527734SSukumar Swaminathan uint32_t word; 5069*82527734SSukumar Swaminathan FCFIobj_t *fp; 5070*82527734SSukumar Swaminathan VFIobj_t *vp; 5071*82527734SSukumar Swaminathan RPIobj_t *rp; 5072*82527734SSukumar Swaminathan XRIobj_t *xp; 5073*82527734SSukumar Swaminathan char buf[64]; 5074*82527734SSukumar Swaminathan emlxs_memseg_t *seg; 5075*82527734SSukumar Swaminathan MATCHMAP *mp; 5076*82527734SSukumar Swaminathan MATCHMAP **rqb; 5077*82527734SSukumar Swaminathan RQE_t *rqe; 5078*82527734SSukumar Swaminathan 5079*82527734SSukumar Swaminathan (void) sprintf(buf, "%s_id_lock mutex", DRIVER_NAME); 5080*82527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.id_lock, buf, MUTEX_DRIVER, NULL); 5081*82527734SSukumar Swaminathan 5082*82527734SSukumar Swaminathan if ((!hba->sli.sli4.FCFIp) && (hba->sli.sli4.FCFICount)) { 5083*82527734SSukumar Swaminathan hba->sli.sli4.FCFIp = (FCFIobj_t *)kmem_zalloc( 5084*82527734SSukumar Swaminathan (sizeof (FCFIobj_t) * hba->sli.sli4.FCFICount), KM_SLEEP); 5085*82527734SSukumar Swaminathan 5086*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 5087*82527734SSukumar Swaminathan index = 0; /* Start FCFIs at 0 */ 5088*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.FCFICount; i++) { 5089*82527734SSukumar Swaminathan fp->FCFI = index; 5090*82527734SSukumar Swaminathan fp->index = i; 5091*82527734SSukumar Swaminathan fp++; 5092*82527734SSukumar Swaminathan index++; 5093*82527734SSukumar Swaminathan } 5094*82527734SSukumar Swaminathan } 5095*82527734SSukumar Swaminathan 5096*82527734SSukumar Swaminathan if ((!hba->sli.sli4.VFIp) && (hba->sli.sli4.VFICount)) { 5097*82527734SSukumar Swaminathan hba->sli.sli4.VFIp = (VFIobj_t *)kmem_zalloc( 5098*82527734SSukumar Swaminathan (sizeof (VFIobj_t) * hba->sli.sli4.VFICount), KM_SLEEP); 5099*82527734SSukumar Swaminathan 5100*82527734SSukumar Swaminathan vp = hba->sli.sli4.VFIp; 5101*82527734SSukumar Swaminathan index = hba->sli.sli4.VFIBase; 5102*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.VFICount; i++) { 5103*82527734SSukumar Swaminathan vp->VFI = index; 5104*82527734SSukumar Swaminathan vp->index = i; 5105*82527734SSukumar Swaminathan vp++; 5106*82527734SSukumar Swaminathan index++; 5107*82527734SSukumar Swaminathan } 5108*82527734SSukumar Swaminathan } 5109*82527734SSukumar Swaminathan 5110*82527734SSukumar Swaminathan if ((!hba->sli.sli4.RPIp) && (hba->sli.sli4.RPICount)) { 5111*82527734SSukumar Swaminathan hba->sli.sli4.RPIp = (RPIobj_t *)kmem_zalloc( 5112*82527734SSukumar Swaminathan (sizeof (RPIobj_t) * hba->sli.sli4.RPICount), KM_SLEEP); 5113*82527734SSukumar Swaminathan 5114*82527734SSukumar Swaminathan rp = hba->sli.sli4.RPIp; 5115*82527734SSukumar Swaminathan index = hba->sli.sli4.RPIBase; 5116*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.RPICount; i++) { 5117*82527734SSukumar Swaminathan rp->RPI = index; 5118*82527734SSukumar Swaminathan rp->index = i; /* offset into HdrTmplate */ 5119*82527734SSukumar Swaminathan rp++; 5120*82527734SSukumar Swaminathan index++; 5121*82527734SSukumar Swaminathan } 5122*82527734SSukumar Swaminathan } 5123*82527734SSukumar Swaminathan 5124*82527734SSukumar Swaminathan if ((!hba->sli.sli4.XRIp) && (hba->sli.sli4.XRICount)) { 5125*82527734SSukumar Swaminathan hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc( 5126*82527734SSukumar Swaminathan (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP); 5127*82527734SSukumar Swaminathan 5128*82527734SSukumar Swaminathan xp = hba->sli.sli4.XRIp; 5129*82527734SSukumar Swaminathan index = hba->sli.sli4.XRIBase; 5130*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.XRICount; i++) { 5131*82527734SSukumar Swaminathan xp->sge_count = 5132*82527734SSukumar Swaminathan (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64)); 5133*82527734SSukumar Swaminathan xp->XRI = index; 5134*82527734SSukumar Swaminathan xp->iotag = i; 5135*82527734SSukumar Swaminathan if ((xp->XRI == 0) || (xp->iotag == 0)) { 5136*82527734SSukumar Swaminathan index++; /* Skip XRI 0 or IOTag 0 */ 5137*82527734SSukumar Swaminathan xp++; 5138*82527734SSukumar Swaminathan continue; 5139*82527734SSukumar Swaminathan } 5140*82527734SSukumar Swaminathan /* Add xp to end of single linked free list */ 5141*82527734SSukumar Swaminathan if (hba->sli.sli4.XRIfree_tail) { 5142*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail->_f = xp; 5143*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail = xp; 5144*82527734SSukumar Swaminathan } else { 5145*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail = xp; 5146*82527734SSukumar Swaminathan } 5147*82527734SSukumar Swaminathan if (hba->sli.sli4.XRIfree_list == NULL) { 5148*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_list = xp; 5149*82527734SSukumar Swaminathan } 5150*82527734SSukumar Swaminathan xp->_f = NULL; 5151*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 5152*82527734SSukumar Swaminathan 5153*82527734SSukumar Swaminathan /* Allocate SGL for this xp */ 5154*82527734SSukumar Swaminathan buf_info = &xp->SGList; 5155*82527734SSukumar Swaminathan buf_info->size = hba->sli.sli4.mem_sgl_size; 5156*82527734SSukumar Swaminathan buf_info->flags = 5157*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5158*82527734SSukumar Swaminathan buf_info->align = hba->sli.sli4.mem_sgl_size; 5159*82527734SSukumar Swaminathan 5160*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5161*82527734SSukumar Swaminathan 5162*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5163*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5164*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 5165*82527734SSukumar Swaminathan "Unable to allocate XRI SGL area: %d", 5166*82527734SSukumar Swaminathan hba->sli.sli4.mem_sgl_size); 5167*82527734SSukumar Swaminathan goto failed; 5168*82527734SSukumar Swaminathan } 5169*82527734SSukumar Swaminathan bzero(buf_info->virt, hba->sli.sli4.mem_sgl_size); 5170*82527734SSukumar Swaminathan xp++; 5171*82527734SSukumar Swaminathan index++; 5172*82527734SSukumar Swaminathan } 5173*82527734SSukumar Swaminathan /* Initialize double linked list */ 5174*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_f = 5175*82527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5176*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b = 5177*82527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5178*82527734SSukumar Swaminathan hba->sli.sli4.xria_count = 0; 5179*82527734SSukumar Swaminathan } 5180*82527734SSukumar Swaminathan 5181*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.HeaderTmplate; 5182*82527734SSukumar Swaminathan if ((buf_info->virt == NULL) && (hba->sli.sli4.RPICount)) { 5183*82527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 5184*82527734SSukumar Swaminathan buf_info->size = (sizeof (RPIHdrTmplate_t) * 5185*82527734SSukumar Swaminathan hba->sli.sli4.RPICount); 5186*82527734SSukumar Swaminathan buf_info->flags = 5187*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_DMA32; 5188*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5189*82527734SSukumar Swaminathan 5190*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5191*82527734SSukumar Swaminathan 5192*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5193*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 5194*82527734SSukumar Swaminathan "Unable to allocate Header Tmplate area: %d", 5195*82527734SSukumar Swaminathan (sizeof (RPIHdrTmplate_t) * 5196*82527734SSukumar Swaminathan hba->sli.sli4.RPICount)); 5197*82527734SSukumar Swaminathan goto failed; 5198*82527734SSukumar Swaminathan } 5199*82527734SSukumar Swaminathan bzero(buf_info->virt, 5200*82527734SSukumar Swaminathan (sizeof (RPIHdrTmplate_t) * hba->sli.sli4.RPICount)); 5201*82527734SSukumar Swaminathan } 5202*82527734SSukumar Swaminathan 5203*82527734SSukumar Swaminathan /* Allocate space for queues */ 5204*82527734SSukumar Swaminathan /* EQs - 1 per Interrupt vector */ 5205*82527734SSukumar Swaminathan num_eq = hba->intr_count; 5206*82527734SSukumar Swaminathan for (i = 0; i < num_eq; i++) { 5207*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.eq[i].addr; 5208*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5209*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 5210*82527734SSukumar Swaminathan buf_info->size = 4096; 5211*82527734SSukumar Swaminathan buf_info->flags = 5212*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5213*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5214*82527734SSukumar Swaminathan 5215*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5216*82527734SSukumar Swaminathan 5217*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5218*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5219*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 5220*82527734SSukumar Swaminathan "Unable to allocate EQ %d area", i); 5221*82527734SSukumar Swaminathan goto failed; 5222*82527734SSukumar Swaminathan } 5223*82527734SSukumar Swaminathan bzero(buf_info->virt, 4096); 5224*82527734SSukumar Swaminathan hba->sli.sli4.eq[i].max_index = EQ_DEPTH; 5225*82527734SSukumar Swaminathan } 5226*82527734SSukumar Swaminathan 5227*82527734SSukumar Swaminathan (void) sprintf(buf, "%s_eq%d_lastwq_lock mutex", 5228*82527734SSukumar Swaminathan DRIVER_NAME, i); 5229*82527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.eq[i].lastwq_lock, buf, 5230*82527734SSukumar Swaminathan MUTEX_DRIVER, NULL); 5231*82527734SSukumar Swaminathan } 5232*82527734SSukumar Swaminathan /* CQs - number of WQs + 1 for RQs + 1 for mbox/async events */ 5233*82527734SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current * num_eq; 5234*82527734SSukumar Swaminathan for (i = 0; i < (num_wq + EMLXS_CQ_OFFSET_WQ); i++) { 5235*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.cq[i].addr; 5236*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5237*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 5238*82527734SSukumar Swaminathan buf_info->size = 4096; 5239*82527734SSukumar Swaminathan buf_info->flags = 5240*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5241*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5242*82527734SSukumar Swaminathan 5243*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5244*82527734SSukumar Swaminathan 5245*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5246*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5247*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 5248*82527734SSukumar Swaminathan "Unable to allocate CQ %d area", i); 5249*82527734SSukumar Swaminathan goto failed; 5250*82527734SSukumar Swaminathan } 5251*82527734SSukumar Swaminathan bzero(buf_info->virt, 4096); 5252*82527734SSukumar Swaminathan hba->sli.sli4.cq[i].max_index = CQ_DEPTH; 5253*82527734SSukumar Swaminathan } 5254*82527734SSukumar Swaminathan } 5255*82527734SSukumar Swaminathan /* WQs - NUM_WQ config parameter * number of EQs */ 5256*82527734SSukumar Swaminathan for (i = 0; i < num_wq; i++) { 5257*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.wq[i].addr; 5258*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5259*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 5260*82527734SSukumar Swaminathan buf_info->size = (4096 * EMLXS_NUM_WQ_PAGES); 5261*82527734SSukumar Swaminathan buf_info->flags = 5262*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5263*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5264*82527734SSukumar Swaminathan 5265*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5266*82527734SSukumar Swaminathan 5267*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5268*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5269*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 5270*82527734SSukumar Swaminathan "Unable to allocate WQ %d area", i); 5271*82527734SSukumar Swaminathan goto failed; 5272*82527734SSukumar Swaminathan } 5273*82527734SSukumar Swaminathan bzero(buf_info->virt, (4096 * EMLXS_NUM_WQ_PAGES)); 5274*82527734SSukumar Swaminathan hba->sli.sli4.wq[i].max_index = WQ_DEPTH; 5275*82527734SSukumar Swaminathan hba->sli.sli4.wq[i].release_depth = WQE_RELEASE_DEPTH; 5276*82527734SSukumar Swaminathan } 5277*82527734SSukumar Swaminathan } 5278*82527734SSukumar Swaminathan 5279*82527734SSukumar Swaminathan /* RXQs */ 5280*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RXQS; i++) { 5281*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 5282*82527734SSukumar Swaminathan 5283*82527734SSukumar Swaminathan (void) sprintf(buf, "%s_rxq%d_lock mutex", DRIVER_NAME, i); 5284*82527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.rxq[i].lock, buf, MUTEX_DRIVER, NULL); 5285*82527734SSukumar Swaminathan } 5286*82527734SSukumar Swaminathan 5287*82527734SSukumar Swaminathan /* RQs */ 5288*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 5289*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.rq[i].addr; 5290*82527734SSukumar Swaminathan if (buf_info->virt) { 5291*82527734SSukumar Swaminathan continue; 5292*82527734SSukumar Swaminathan } 5293*82527734SSukumar Swaminathan 5294*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 5295*82527734SSukumar Swaminathan buf_info->size = 4096; 5296*82527734SSukumar Swaminathan buf_info->flags = 5297*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5298*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5299*82527734SSukumar Swaminathan 5300*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5301*82527734SSukumar Swaminathan 5302*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5303*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5304*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 5305*82527734SSukumar Swaminathan "Unable to allocate RQ %d area", i); 5306*82527734SSukumar Swaminathan goto failed; 5307*82527734SSukumar Swaminathan } 5308*82527734SSukumar Swaminathan bzero(buf_info->virt, 4096); 5309*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].max_index = RQ_DEPTH; 5310*82527734SSukumar Swaminathan 5311*82527734SSukumar Swaminathan /* RQBs */ 5312*82527734SSukumar Swaminathan seg = &hba->sli.sli4.rq[i].rqb_pool; 5313*82527734SSukumar Swaminathan bzero(seg, sizeof (MEMSEG)); 5314*82527734SSukumar Swaminathan seg->fc_numblks = RQB_COUNT; 5315*82527734SSukumar Swaminathan seg->fc_memflag = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5316*82527734SSukumar Swaminathan seg->fc_memalign = 8; 5317*82527734SSukumar Swaminathan seg->fc_memtag = (i<<16); 5318*82527734SSukumar Swaminathan 5319*82527734SSukumar Swaminathan if ((i & 0x1)) { 5320*82527734SSukumar Swaminathan /* Odd == Data pool */ 5321*82527734SSukumar Swaminathan seg->fc_memsize = RQB_DATA_SIZE; 5322*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "RQB Data Pool"); 5323*82527734SSukumar Swaminathan 5324*82527734SSukumar Swaminathan } else { 5325*82527734SSukumar Swaminathan /* Even == Header pool */ 5326*82527734SSukumar Swaminathan seg->fc_memsize = RQB_HEADER_SIZE; 5327*82527734SSukumar Swaminathan (void) strcpy(seg->fc_label, "RQB Header Pool"); 5328*82527734SSukumar Swaminathan } 5329*82527734SSukumar Swaminathan 5330*82527734SSukumar Swaminathan /* Allocate the pool */ 5331*82527734SSukumar Swaminathan if (emlxs_mem_pool_alloc(hba, seg) == NULL) { 5332*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 5333*82527734SSukumar Swaminathan "Unable to allocate RQ %d pool", i); 5334*82527734SSukumar Swaminathan 5335*82527734SSukumar Swaminathan goto failed; 5336*82527734SSukumar Swaminathan } 5337*82527734SSukumar Swaminathan 5338*82527734SSukumar Swaminathan /* Initialize the RQEs */ 5339*82527734SSukumar Swaminathan rqe = (RQE_t *)hba->sli.sli4.rq[i].addr.virt; 5340*82527734SSukumar Swaminathan rqb = hba->sli.sli4.rq[i].rqb; 5341*82527734SSukumar Swaminathan 5342*82527734SSukumar Swaminathan for (j = 0; j < (RQ_DEPTH/RQB_COUNT); j++) { 5343*82527734SSukumar Swaminathan mp = (MATCHMAP*)seg->fc_memget_ptr; 5344*82527734SSukumar Swaminathan for (k = 0; k < RQB_COUNT; k++) { 5345*82527734SSukumar Swaminathan if (j == 0) { 5346*82527734SSukumar Swaminathan mp->tag = (seg->fc_memtag | k); 5347*82527734SSukumar Swaminathan } 5348*82527734SSukumar Swaminathan 5349*82527734SSukumar Swaminathan word = PADDR_HI(mp->phys); 5350*82527734SSukumar Swaminathan rqe->AddrHi = BE_SWAP32(word); 5351*82527734SSukumar Swaminathan 5352*82527734SSukumar Swaminathan word = PADDR_LO(mp->phys); 5353*82527734SSukumar Swaminathan rqe->AddrLo = BE_SWAP32(word); 5354*82527734SSukumar Swaminathan 5355*82527734SSukumar Swaminathan *rqb = mp; 5356*82527734SSukumar Swaminathan 5357*82527734SSukumar Swaminathan #ifdef RQ_DEBUG 5358*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5359*82527734SSukumar Swaminathan "RQ_ALLOC: rq[%d] rqb[%d,%d]=%p tag=%08x", 5360*82527734SSukumar Swaminathan i, j, k, mp, mp->tag); 5361*82527734SSukumar Swaminathan #endif 5362*82527734SSukumar Swaminathan 5363*82527734SSukumar Swaminathan mp = (MATCHMAP *)mp->fc_mptr; 5364*82527734SSukumar Swaminathan rqe++; 5365*82527734SSukumar Swaminathan rqb++; 5366*82527734SSukumar Swaminathan } 5367*82527734SSukumar Swaminathan } 5368*82527734SSukumar Swaminathan 5369*82527734SSukumar Swaminathan /* Sync the RQ buffer list */ 5370*82527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, 0, 5371*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].addr.size, DDI_DMA_SYNC_FORDEV); 5372*82527734SSukumar Swaminathan 5373*82527734SSukumar Swaminathan (void) sprintf(buf, "%s_rq%d_lock mutex", DRIVER_NAME, i); 5374*82527734SSukumar Swaminathan mutex_init(&hba->sli.sli4.rq[i].lock, buf, MUTEX_DRIVER, NULL); 5375*82527734SSukumar Swaminathan } 5376*82527734SSukumar Swaminathan 5377*82527734SSukumar Swaminathan /* MQ */ 5378*82527734SSukumar Swaminathan buf_info = &hba->sli.sli4.mq.addr; 5379*82527734SSukumar Swaminathan if (!buf_info->virt) { 5380*82527734SSukumar Swaminathan bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 5381*82527734SSukumar Swaminathan buf_info->size = 4096; 5382*82527734SSukumar Swaminathan buf_info->flags = 5383*82527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 5384*82527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 5385*82527734SSukumar Swaminathan 5386*82527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 5387*82527734SSukumar Swaminathan 5388*82527734SSukumar Swaminathan if (buf_info->virt == NULL) { 5389*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 5390*82527734SSukumar Swaminathan "Unable to allocate MQ area"); 5391*82527734SSukumar Swaminathan goto failed; 5392*82527734SSukumar Swaminathan } 5393*82527734SSukumar Swaminathan bzero(buf_info->virt, 4096); 5394*82527734SSukumar Swaminathan hba->sli.sli4.mq.max_index = MQ_DEPTH; 5395*82527734SSukumar Swaminathan } 5396*82527734SSukumar Swaminathan 5397*82527734SSukumar Swaminathan return (0); 5398*82527734SSukumar Swaminathan 5399*82527734SSukumar Swaminathan failed: 5400*82527734SSukumar Swaminathan 5401*82527734SSukumar Swaminathan (void) emlxs_sli4_resource_free(hba); 5402*82527734SSukumar Swaminathan return (ENOMEM); 5403*82527734SSukumar Swaminathan 5404*82527734SSukumar Swaminathan } /* emlxs_sli4_resource_alloc */ 5405*82527734SSukumar Swaminathan 5406*82527734SSukumar Swaminathan 5407*82527734SSukumar Swaminathan static FCFIobj_t * 5408*82527734SSukumar Swaminathan emlxs_sli4_alloc_fcfi(emlxs_hba_t *hba) 5409*82527734SSukumar Swaminathan { 5410*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5411*82527734SSukumar Swaminathan uint32_t i; 5412*82527734SSukumar Swaminathan FCFIobj_t *fp; 5413*82527734SSukumar Swaminathan 5414*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5415*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 5416*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.FCFICount; i++) { 5417*82527734SSukumar Swaminathan if (fp->state == RESOURCE_FREE) { 5418*82527734SSukumar Swaminathan fp->state = RESOURCE_ALLOCATED; 5419*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5420*82527734SSukumar Swaminathan return (fp); 5421*82527734SSukumar Swaminathan } 5422*82527734SSukumar Swaminathan fp++; 5423*82527734SSukumar Swaminathan } 5424*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5425*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5426*82527734SSukumar Swaminathan "Unable to Alloc FCFI"); 5427*82527734SSukumar Swaminathan return (NULL); 5428*82527734SSukumar Swaminathan 5429*82527734SSukumar Swaminathan } /* emlxs_sli4_alloc_fcfi() */ 5430*82527734SSukumar Swaminathan 5431*82527734SSukumar Swaminathan 5432*82527734SSukumar Swaminathan static FCFIobj_t * 5433*82527734SSukumar Swaminathan emlxs_sli4_find_fcfi_fcfrec(emlxs_hba_t *hba, FCF_RECORD_t *fcfrec) 5434*82527734SSukumar Swaminathan { 5435*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5436*82527734SSukumar Swaminathan uint32_t i; 5437*82527734SSukumar Swaminathan FCFIobj_t *fp; 5438*82527734SSukumar Swaminathan 5439*82527734SSukumar Swaminathan /* Check for BOTH a matching FCF index and mac address */ 5440*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5441*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 5442*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.FCFICount; i++) { 5443*82527734SSukumar Swaminathan if (fp->state & RESOURCE_ALLOCATED) { 5444*82527734SSukumar Swaminathan if ((fp->FCF_index == fcfrec->fcf_index) && 5445*82527734SSukumar Swaminathan (bcmp((char *)fcfrec->fcf_mac_address_hi, 5446*82527734SSukumar Swaminathan fp->fcf_rec.fcf_mac_address_hi, 4) == 0) && 5447*82527734SSukumar Swaminathan (bcmp((char *)fcfrec->fcf_mac_address_low, 5448*82527734SSukumar Swaminathan fp->fcf_rec.fcf_mac_address_low, 2) == 0)) { 5449*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5450*82527734SSukumar Swaminathan return (fp); 5451*82527734SSukumar Swaminathan } 5452*82527734SSukumar Swaminathan } 5453*82527734SSukumar Swaminathan fp++; 5454*82527734SSukumar Swaminathan } 5455*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5456*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5457*82527734SSukumar Swaminathan "Unable to Find FCF Index %d", fcfrec->fcf_index); 5458*82527734SSukumar Swaminathan return (0); 5459*82527734SSukumar Swaminathan 5460*82527734SSukumar Swaminathan } /* emlxs_sli4_find_fcfi_fcfrec() */ 5461*82527734SSukumar Swaminathan 5462*82527734SSukumar Swaminathan 5463*82527734SSukumar Swaminathan extern VFIobj_t * 5464*82527734SSukumar Swaminathan emlxs_sli4_alloc_vfi(emlxs_hba_t *hba, FCFIobj_t *fp) 5465*82527734SSukumar Swaminathan { 5466*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5467*82527734SSukumar Swaminathan uint32_t i; 5468*82527734SSukumar Swaminathan VFIobj_t *vp; 5469*82527734SSukumar Swaminathan 5470*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5471*82527734SSukumar Swaminathan vp = hba->sli.sli4.VFIp; 5472*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.VFICount; i++) { 5473*82527734SSukumar Swaminathan if (vp->state == RESOURCE_FREE) { 5474*82527734SSukumar Swaminathan vp->state = RESOURCE_ALLOCATED; 5475*82527734SSukumar Swaminathan vp->FCFIp = fp; 5476*82527734SSukumar Swaminathan fp->outstandingVFIs++; 5477*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5478*82527734SSukumar Swaminathan return (vp); 5479*82527734SSukumar Swaminathan } 5480*82527734SSukumar Swaminathan vp++; 5481*82527734SSukumar Swaminathan } 5482*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5483*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5484*82527734SSukumar Swaminathan "Unable to Alloc VFI"); 5485*82527734SSukumar Swaminathan return (NULL); 5486*82527734SSukumar Swaminathan 5487*82527734SSukumar Swaminathan } /* emlxs_sli4_alloc_vfi() */ 5488*82527734SSukumar Swaminathan 5489*82527734SSukumar Swaminathan 5490*82527734SSukumar Swaminathan extern RPIobj_t * 5491*82527734SSukumar Swaminathan emlxs_sli4_alloc_rpi(emlxs_port_t *port) 5492*82527734SSukumar Swaminathan { 5493*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 5494*82527734SSukumar Swaminathan uint32_t i; 5495*82527734SSukumar Swaminathan RPIobj_t *rp; 5496*82527734SSukumar Swaminathan 5497*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5498*82527734SSukumar Swaminathan rp = hba->sli.sli4.RPIp; 5499*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.RPICount; i++) { 5500*82527734SSukumar Swaminathan /* To be consistent with SLI3, the RPI assignment */ 5501*82527734SSukumar Swaminathan /* starts with 1. ONLY one SLI4 HBA in the entire */ 5502*82527734SSukumar Swaminathan /* system will be sacrificed by one RPI and that */ 5503*82527734SSukumar Swaminathan /* is the one having RPI base equal 0. */ 5504*82527734SSukumar Swaminathan if ((rp->state == RESOURCE_FREE) && (rp->RPI != 0)) { 5505*82527734SSukumar Swaminathan rp->state = RESOURCE_ALLOCATED; 5506*82527734SSukumar Swaminathan rp->VPIp = port; 5507*82527734SSukumar Swaminathan port->outstandingRPIs++; 5508*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5509*82527734SSukumar Swaminathan return (rp); 5510*82527734SSukumar Swaminathan } 5511*82527734SSukumar Swaminathan rp++; 5512*82527734SSukumar Swaminathan } 5513*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5514*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5515*82527734SSukumar Swaminathan "Unable to Alloc RPI"); 5516*82527734SSukumar Swaminathan return (NULL); 5517*82527734SSukumar Swaminathan 5518*82527734SSukumar Swaminathan } /* emlxs_sli4_alloc_rpi() */ 5519*82527734SSukumar Swaminathan 5520*82527734SSukumar Swaminathan 5521*82527734SSukumar Swaminathan extern RPIobj_t * 5522*82527734SSukumar Swaminathan emlxs_sli4_find_rpi(emlxs_hba_t *hba, uint16_t rpi) 5523*82527734SSukumar Swaminathan { 5524*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5525*82527734SSukumar Swaminathan RPIobj_t *rp; 5526*82527734SSukumar Swaminathan int index; 5527*82527734SSukumar Swaminathan 5528*82527734SSukumar Swaminathan rp = hba->sli.sli4.RPIp; 5529*82527734SSukumar Swaminathan index = rpi - hba->sli.sli4.RPIBase; 5530*82527734SSukumar Swaminathan if ((rpi == 0xffff) || (index >= hba->sli.sli4.RPICount)) { 5531*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5532*82527734SSukumar Swaminathan "RPI %d out of range: Count = %d", 5533*82527734SSukumar Swaminathan index, hba->sli.sli4.RPICount); 5534*82527734SSukumar Swaminathan return (NULL); 5535*82527734SSukumar Swaminathan } 5536*82527734SSukumar Swaminathan rp += index; 5537*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5538*82527734SSukumar Swaminathan if ((index < 0) || !(rp->state & RESOURCE_ALLOCATED)) { 5539*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5540*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5541*82527734SSukumar Swaminathan "Unable to find RPI %d", index); 5542*82527734SSukumar Swaminathan return (NULL); 5543*82527734SSukumar Swaminathan } 5544*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5545*82527734SSukumar Swaminathan return (rp); 5546*82527734SSukumar Swaminathan 5547*82527734SSukumar Swaminathan } /* emlxs_sli4_find_rpi() */ 5548*82527734SSukumar Swaminathan 5549*82527734SSukumar Swaminathan 5550*82527734SSukumar Swaminathan static XRIobj_t * 5551*82527734SSukumar Swaminathan emlxs_sli4_reserve_xri(emlxs_hba_t *hba, RPIobj_t *rp) 5552*82527734SSukumar Swaminathan { 5553*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5554*82527734SSukumar Swaminathan XRIobj_t *xp; 5555*82527734SSukumar Swaminathan uint16_t iotag; 5556*82527734SSukumar Swaminathan 5557*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5558*82527734SSukumar Swaminathan 5559*82527734SSukumar Swaminathan xp = hba->sli.sli4.XRIfree_list; 5560*82527734SSukumar Swaminathan 5561*82527734SSukumar Swaminathan if (xp == NULL) { 5562*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5563*82527734SSukumar Swaminathan 5564*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5565*82527734SSukumar Swaminathan "Unable to reserve XRI"); 5566*82527734SSukumar Swaminathan 5567*82527734SSukumar Swaminathan return (NULL); 5568*82527734SSukumar Swaminathan } 5569*82527734SSukumar Swaminathan 5570*82527734SSukumar Swaminathan iotag = xp->iotag; 5571*82527734SSukumar Swaminathan 5572*82527734SSukumar Swaminathan if ((!iotag) || 5573*82527734SSukumar Swaminathan (hba->fc_table[iotag] != NULL && 5574*82527734SSukumar Swaminathan hba->fc_table[iotag] != STALE_PACKET)) { 5575*82527734SSukumar Swaminathan /* 5576*82527734SSukumar Swaminathan * No more command slots available, retry later 5577*82527734SSukumar Swaminathan */ 5578*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5579*82527734SSukumar Swaminathan "Adapter Busy. Unable to reserve iotag"); 5580*82527734SSukumar Swaminathan 5581*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5582*82527734SSukumar Swaminathan return (NULL); 5583*82527734SSukumar Swaminathan } 5584*82527734SSukumar Swaminathan 5585*82527734SSukumar Swaminathan xp->state = (RESOURCE_ALLOCATED | RESOURCE_XRI_RESERVED); 5586*82527734SSukumar Swaminathan xp->RPIp = rp; 5587*82527734SSukumar Swaminathan xp->sbp = NULL; 5588*82527734SSukumar Swaminathan 5589*82527734SSukumar Swaminathan if (rp) { 5590*82527734SSukumar Swaminathan rp->outstandingXRIs++; 5591*82527734SSukumar Swaminathan } 5592*82527734SSukumar Swaminathan 5593*82527734SSukumar Swaminathan /* Take it off free list */ 5594*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_list = xp->_f; 5595*82527734SSukumar Swaminathan xp->_f = NULL; 5596*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count--; 5597*82527734SSukumar Swaminathan 5598*82527734SSukumar Swaminathan /* Add it to end of inuse list */ 5599*82527734SSukumar Swaminathan xp->_b = hba->sli.sli4.XRIinuse_b; 5600*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b->_f = xp; 5601*82527734SSukumar Swaminathan xp->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5602*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b = xp; 5603*82527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 5604*82527734SSukumar Swaminathan 5605*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5606*82527734SSukumar Swaminathan return (xp); 5607*82527734SSukumar Swaminathan 5608*82527734SSukumar Swaminathan } /* emlxs_sli4_reserve_xri() */ 5609*82527734SSukumar Swaminathan 5610*82527734SSukumar Swaminathan 5611*82527734SSukumar Swaminathan extern uint32_t 5612*82527734SSukumar Swaminathan emlxs_sli4_unreserve_xri(emlxs_hba_t *hba, uint16_t xri) 5613*82527734SSukumar Swaminathan { 5614*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5615*82527734SSukumar Swaminathan XRIobj_t *xp; 5616*82527734SSukumar Swaminathan 5617*82527734SSukumar Swaminathan xp = emlxs_sli4_find_xri(hba, xri); 5618*82527734SSukumar Swaminathan 5619*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5620*82527734SSukumar Swaminathan 5621*82527734SSukumar Swaminathan if (!xp || xp->state == RESOURCE_FREE) { 5622*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5623*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5624*82527734SSukumar Swaminathan "emlxs_sli4_unreserve_xri: xri=%x already freed.", xp->XRI); 5625*82527734SSukumar Swaminathan return (0); 5626*82527734SSukumar Swaminathan } 5627*82527734SSukumar Swaminathan 5628*82527734SSukumar Swaminathan if (!(xp->state & RESOURCE_XRI_RESERVED)) { 5629*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5630*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5631*82527734SSukumar Swaminathan "emlxs_sli4_unreserve_xri: xri=%x in use.", xp->XRI); 5632*82527734SSukumar Swaminathan return (1); 5633*82527734SSukumar Swaminathan } 5634*82527734SSukumar Swaminathan 5635*82527734SSukumar Swaminathan if (hba->fc_table[xp->iotag]) { 5636*82527734SSukumar Swaminathan hba->fc_table[xp->iotag] = NULL; 5637*82527734SSukumar Swaminathan hba->io_count--; 5638*82527734SSukumar Swaminathan } 5639*82527734SSukumar Swaminathan 5640*82527734SSukumar Swaminathan xp->state = RESOURCE_FREE; 5641*82527734SSukumar Swaminathan 5642*82527734SSukumar Swaminathan if (xp->RPIp) { 5643*82527734SSukumar Swaminathan xp->RPIp->outstandingXRIs--; 5644*82527734SSukumar Swaminathan xp->RPIp = NULL; 5645*82527734SSukumar Swaminathan } 5646*82527734SSukumar Swaminathan 5647*82527734SSukumar Swaminathan /* Take it off inuse list */ 5648*82527734SSukumar Swaminathan (xp->_b)->_f = xp->_f; 5649*82527734SSukumar Swaminathan (xp->_f)->_b = xp->_b; 5650*82527734SSukumar Swaminathan xp->_f = NULL; 5651*82527734SSukumar Swaminathan xp->_b = NULL; 5652*82527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 5653*82527734SSukumar Swaminathan 5654*82527734SSukumar Swaminathan /* Add it to end of free list */ 5655*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail->_f = xp; 5656*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail = xp; 5657*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 5658*82527734SSukumar Swaminathan 5659*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5660*82527734SSukumar Swaminathan "emlxs_sli4_unreserve_xri: xri=%x unreserved.", xp->XRI); 5661*82527734SSukumar Swaminathan 5662*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5663*82527734SSukumar Swaminathan 5664*82527734SSukumar Swaminathan return (0); 5665*82527734SSukumar Swaminathan 5666*82527734SSukumar Swaminathan } /* emlxs_sli4_unreserve_xri() */ 5667*82527734SSukumar Swaminathan 5668*82527734SSukumar Swaminathan 5669*82527734SSukumar Swaminathan static XRIobj_t * 5670*82527734SSukumar Swaminathan emlxs_sli4_register_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, uint16_t xri) 5671*82527734SSukumar Swaminathan { 5672*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5673*82527734SSukumar Swaminathan uint16_t iotag; 5674*82527734SSukumar Swaminathan XRIobj_t *xp; 5675*82527734SSukumar Swaminathan 5676*82527734SSukumar Swaminathan xp = emlxs_sli4_find_xri(hba, xri); 5677*82527734SSukumar Swaminathan 5678*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5679*82527734SSukumar Swaminathan 5680*82527734SSukumar Swaminathan if (!xp) { 5681*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5682*82527734SSukumar Swaminathan "emlxs_sli4_register_xri: XRI not found."); 5683*82527734SSukumar Swaminathan 5684*82527734SSukumar Swaminathan 5685*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5686*82527734SSukumar Swaminathan return (NULL); 5687*82527734SSukumar Swaminathan } 5688*82527734SSukumar Swaminathan 5689*82527734SSukumar Swaminathan if (!(xp->state & RESOURCE_ALLOCATED) || 5690*82527734SSukumar Swaminathan !(xp->state & RESOURCE_XRI_RESERVED)) { 5691*82527734SSukumar Swaminathan 5692*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5693*82527734SSukumar Swaminathan "emlxs_sli4_register_xri: Invalid XRI. xp=%p state=%x", 5694*82527734SSukumar Swaminathan xp, xp->state); 5695*82527734SSukumar Swaminathan 5696*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5697*82527734SSukumar Swaminathan return (NULL); 5698*82527734SSukumar Swaminathan } 5699*82527734SSukumar Swaminathan 5700*82527734SSukumar Swaminathan iotag = xp->iotag; 5701*82527734SSukumar Swaminathan 5702*82527734SSukumar Swaminathan if ((!iotag) || 5703*82527734SSukumar Swaminathan (hba->fc_table[iotag] != NULL && 5704*82527734SSukumar Swaminathan hba->fc_table[iotag] != STALE_PACKET)) { 5705*82527734SSukumar Swaminathan 5706*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5707*82527734SSukumar Swaminathan "emlxs_sli4_register_xri: Invalid fc_table entry. " \ 5708*82527734SSukumar Swaminathan "iotag=%x entry=%p", 5709*82527734SSukumar Swaminathan iotag, hba->fc_table[iotag]); 5710*82527734SSukumar Swaminathan 5711*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5712*82527734SSukumar Swaminathan return (NULL); 5713*82527734SSukumar Swaminathan } 5714*82527734SSukumar Swaminathan 5715*82527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 5716*82527734SSukumar Swaminathan hba->io_count++; 5717*82527734SSukumar Swaminathan 5718*82527734SSukumar Swaminathan sbp->iotag = iotag; 5719*82527734SSukumar Swaminathan sbp->xp = xp; 5720*82527734SSukumar Swaminathan 5721*82527734SSukumar Swaminathan xp->state &= ~RESOURCE_XRI_RESERVED; 5722*82527734SSukumar Swaminathan xp->sbp = sbp; 5723*82527734SSukumar Swaminathan 5724*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5725*82527734SSukumar Swaminathan 5726*82527734SSukumar Swaminathan return (xp); 5727*82527734SSukumar Swaminathan 5728*82527734SSukumar Swaminathan } /* emlxs_sli4_register_xri() */ 5729*82527734SSukumar Swaminathan 5730*82527734SSukumar Swaminathan 5731*82527734SSukumar Swaminathan /* Performs both reserve and register functions for XRI */ 5732*82527734SSukumar Swaminathan static XRIobj_t * 5733*82527734SSukumar Swaminathan emlxs_sli4_alloc_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, RPIobj_t *rp) 5734*82527734SSukumar Swaminathan { 5735*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5736*82527734SSukumar Swaminathan XRIobj_t *xp; 5737*82527734SSukumar Swaminathan uint16_t iotag; 5738*82527734SSukumar Swaminathan 5739*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5740*82527734SSukumar Swaminathan 5741*82527734SSukumar Swaminathan xp = hba->sli.sli4.XRIfree_list; 5742*82527734SSukumar Swaminathan 5743*82527734SSukumar Swaminathan if (xp == NULL) { 5744*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5745*82527734SSukumar Swaminathan 5746*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5747*82527734SSukumar Swaminathan "Unable to allocate XRI"); 5748*82527734SSukumar Swaminathan 5749*82527734SSukumar Swaminathan return (NULL); 5750*82527734SSukumar Swaminathan } 5751*82527734SSukumar Swaminathan 5752*82527734SSukumar Swaminathan /* Get the iotag by registering the packet */ 5753*82527734SSukumar Swaminathan iotag = xp->iotag; 5754*82527734SSukumar Swaminathan 5755*82527734SSukumar Swaminathan if ((!iotag) || 5756*82527734SSukumar Swaminathan (hba->fc_table[iotag] != NULL && 5757*82527734SSukumar Swaminathan hba->fc_table[iotag] != STALE_PACKET)) { 5758*82527734SSukumar Swaminathan /* 5759*82527734SSukumar Swaminathan * No more command slots available, retry later 5760*82527734SSukumar Swaminathan */ 5761*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 5762*82527734SSukumar Swaminathan "Adapter Busy. Unable to allocate iotag"); 5763*82527734SSukumar Swaminathan 5764*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5765*82527734SSukumar Swaminathan return (NULL); 5766*82527734SSukumar Swaminathan } 5767*82527734SSukumar Swaminathan 5768*82527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 5769*82527734SSukumar Swaminathan hba->io_count++; 5770*82527734SSukumar Swaminathan 5771*82527734SSukumar Swaminathan sbp->iotag = iotag; 5772*82527734SSukumar Swaminathan sbp->xp = xp; 5773*82527734SSukumar Swaminathan 5774*82527734SSukumar Swaminathan xp->state = RESOURCE_ALLOCATED; 5775*82527734SSukumar Swaminathan xp->RPIp = rp; 5776*82527734SSukumar Swaminathan xp->sbp = sbp; 5777*82527734SSukumar Swaminathan 5778*82527734SSukumar Swaminathan if (rp) { 5779*82527734SSukumar Swaminathan rp->outstandingXRIs++; 5780*82527734SSukumar Swaminathan } 5781*82527734SSukumar Swaminathan 5782*82527734SSukumar Swaminathan /* Take it off free list */ 5783*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_list = xp->_f; 5784*82527734SSukumar Swaminathan xp->_f = NULL; 5785*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count--; 5786*82527734SSukumar Swaminathan 5787*82527734SSukumar Swaminathan /* Add it to end of inuse list */ 5788*82527734SSukumar Swaminathan xp->_b = hba->sli.sli4.XRIinuse_b; 5789*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b->_f = xp; 5790*82527734SSukumar Swaminathan xp->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 5791*82527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b = xp; 5792*82527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 5793*82527734SSukumar Swaminathan 5794*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5795*82527734SSukumar Swaminathan 5796*82527734SSukumar Swaminathan return (xp); 5797*82527734SSukumar Swaminathan 5798*82527734SSukumar Swaminathan } /* emlxs_sli4_alloc_xri() */ 5799*82527734SSukumar Swaminathan 5800*82527734SSukumar Swaminathan 5801*82527734SSukumar Swaminathan extern XRIobj_t * 5802*82527734SSukumar Swaminathan emlxs_sli4_find_xri(emlxs_hba_t *hba, uint16_t xri) 5803*82527734SSukumar Swaminathan { 5804*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5805*82527734SSukumar Swaminathan XRIobj_t *xp; 5806*82527734SSukumar Swaminathan 5807*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5808*82527734SSukumar Swaminathan xp = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 5809*82527734SSukumar Swaminathan while (xp != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 5810*82527734SSukumar Swaminathan if ((xp->state & RESOURCE_ALLOCATED) && 5811*82527734SSukumar Swaminathan (xp->XRI == xri)) { 5812*82527734SSukumar Swaminathan break; 5813*82527734SSukumar Swaminathan } 5814*82527734SSukumar Swaminathan xp = xp->_f; 5815*82527734SSukumar Swaminathan } 5816*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 5817*82527734SSukumar Swaminathan 5818*82527734SSukumar Swaminathan if (xp == (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 5819*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5820*82527734SSukumar Swaminathan "Unable to find XRI x%x", xri); 5821*82527734SSukumar Swaminathan return (NULL); 5822*82527734SSukumar Swaminathan } 5823*82527734SSukumar Swaminathan return (xp); 5824*82527734SSukumar Swaminathan 5825*82527734SSukumar Swaminathan } /* emlxs_sli4_find_xri() */ 5826*82527734SSukumar Swaminathan 5827*82527734SSukumar Swaminathan extern void 5828*82527734SSukumar Swaminathan emlxs_sli4_free_fcfi(emlxs_hba_t *hba, FCFIobj_t *fp) 5829*82527734SSukumar Swaminathan { 5830*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5831*82527734SSukumar Swaminathan 5832*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5833*82527734SSukumar Swaminathan if (fp->state == RESOURCE_FREE) { 5834*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5835*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5836*82527734SSukumar Swaminathan "Free FCFI:%d idx:%d, Already freed", 5837*82527734SSukumar Swaminathan fp->FCFI, fp->FCF_index); 5838*82527734SSukumar Swaminathan return; 5839*82527734SSukumar Swaminathan } 5840*82527734SSukumar Swaminathan 5841*82527734SSukumar Swaminathan if (fp->outstandingVFIs) { 5842*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5843*82527734SSukumar Swaminathan "Free FCFI:%d, %d outstanding VFIs", fp->FCFI, 5844*82527734SSukumar Swaminathan fp->outstandingVFIs); 5845*82527734SSukumar Swaminathan } 5846*82527734SSukumar Swaminathan fp->state = RESOURCE_FREE; 5847*82527734SSukumar Swaminathan fp->FCF_index = 0; 5848*82527734SSukumar Swaminathan bzero(&fp->fcf_rec, sizeof (FCF_RECORD_t)); 5849*82527734SSukumar Swaminathan fp->fcf_vfi = 0; 5850*82527734SSukumar Swaminathan fp->fcf_vpi = 0; 5851*82527734SSukumar Swaminathan 5852*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5853*82527734SSukumar Swaminathan 5854*82527734SSukumar Swaminathan } /* emlxs_sli4_free_fcfi() */ 5855*82527734SSukumar Swaminathan 5856*82527734SSukumar Swaminathan 5857*82527734SSukumar Swaminathan extern void 5858*82527734SSukumar Swaminathan emlxs_sli4_free_vfi(emlxs_hba_t *hba, VFIobj_t *fp) 5859*82527734SSukumar Swaminathan { 5860*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5861*82527734SSukumar Swaminathan 5862*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5863*82527734SSukumar Swaminathan if (fp->state == RESOURCE_FREE) { 5864*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5865*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5866*82527734SSukumar Swaminathan "Free VFI:%d, Already freed", fp->VFI); 5867*82527734SSukumar Swaminathan return; 5868*82527734SSukumar Swaminathan } 5869*82527734SSukumar Swaminathan 5870*82527734SSukumar Swaminathan if (fp->outstandingVPIs) { 5871*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5872*82527734SSukumar Swaminathan "Free VFI:%d, %d outstanding VPIs", fp->VFI, 5873*82527734SSukumar Swaminathan fp->outstandingVPIs); 5874*82527734SSukumar Swaminathan } 5875*82527734SSukumar Swaminathan fp->state = RESOURCE_FREE; 5876*82527734SSukumar Swaminathan fp->FCFIp->outstandingVFIs--; 5877*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5878*82527734SSukumar Swaminathan 5879*82527734SSukumar Swaminathan if ((fp->FCFIp->outstandingVFIs == 0) && 5880*82527734SSukumar Swaminathan (hba->state == FC_LINK_DOWN)) { 5881*82527734SSukumar Swaminathan 5882*82527734SSukumar Swaminathan /* No more VPIs so unreg the VFI */ 5883*82527734SSukumar Swaminathan (void) emlxs_mb_unreg_fcfi(hba, fp->FCFIp); 5884*82527734SSukumar Swaminathan } 5885*82527734SSukumar Swaminathan fp->FCFIp = NULL; 5886*82527734SSukumar Swaminathan 5887*82527734SSukumar Swaminathan 5888*82527734SSukumar Swaminathan } /* emlxs_sli4_free_vfi() */ 5889*82527734SSukumar Swaminathan 5890*82527734SSukumar Swaminathan 5891*82527734SSukumar Swaminathan static void 5892*82527734SSukumar Swaminathan emlxs_sli4_free_vpi(emlxs_hba_t *hba, emlxs_port_t *pp) 5893*82527734SSukumar Swaminathan { 5894*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5895*82527734SSukumar Swaminathan 5896*82527734SSukumar Swaminathan if (!(pp->flag & EMLXS_PORT_ENABLE)) { 5897*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5898*82527734SSukumar Swaminathan "Free VPI:%d, Already freed", pp->vpi); 5899*82527734SSukumar Swaminathan return; 5900*82527734SSukumar Swaminathan } 5901*82527734SSukumar Swaminathan 5902*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5903*82527734SSukumar Swaminathan if (pp->outstandingRPIs) { 5904*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5905*82527734SSukumar Swaminathan "Free VPI:%d, %d outstanding RPIs", pp->vpi, 5906*82527734SSukumar Swaminathan pp->outstandingRPIs); 5907*82527734SSukumar Swaminathan } 5908*82527734SSukumar Swaminathan pp->VFIp->outstandingVPIs--; 5909*82527734SSukumar Swaminathan if (pp->VFIp->outstandingVPIs == 0) { 5910*82527734SSukumar Swaminathan /* No more VPIs so unreg the VFI */ 5911*82527734SSukumar Swaminathan (void) emlxs_mb_unreg_vfi(hba, pp->VFIp); 5912*82527734SSukumar Swaminathan } 5913*82527734SSukumar Swaminathan 5914*82527734SSukumar Swaminathan pp->VFIp = NULL; 5915*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5916*82527734SSukumar Swaminathan 5917*82527734SSukumar Swaminathan } /* emlxs_sli4_free_vpi() */ 5918*82527734SSukumar Swaminathan 5919*82527734SSukumar Swaminathan 5920*82527734SSukumar Swaminathan static void 5921*82527734SSukumar Swaminathan emlxs_sli4_cmpl_io(emlxs_hba_t *hba, emlxs_buf_t *sbp) 5922*82527734SSukumar Swaminathan { 5923*82527734SSukumar Swaminathan CHANNEL *cp; 5924*82527734SSukumar Swaminathan IOCBQ *iocbq; 5925*82527734SSukumar Swaminathan CQE_u cq_entry; 5926*82527734SSukumar Swaminathan 5927*82527734SSukumar Swaminathan cp = sbp->channel; 5928*82527734SSukumar Swaminathan iocbq = &sbp->iocbq; 5929*82527734SSukumar Swaminathan 5930*82527734SSukumar Swaminathan bzero((void *) &cq_entry, sizeof (CQE_u)); 5931*82527734SSukumar Swaminathan cq_entry.cqCmplEntry.Status = IOSTAT_LOCAL_REJECT; 5932*82527734SSukumar Swaminathan cq_entry.cqCmplEntry.Parameter = IOERR_SEQUENCE_TIMEOUT; 5933*82527734SSukumar Swaminathan cq_entry.cqCmplEntry.RequestTag = sbp->iotag; 5934*82527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, &cq_entry.cqCmplEntry, sbp); 5935*82527734SSukumar Swaminathan 5936*82527734SSukumar Swaminathan /* 5937*82527734SSukumar Swaminathan * If this is NOT a polled command completion 5938*82527734SSukumar Swaminathan * or a driver allocated pkt, then defer pkt 5939*82527734SSukumar Swaminathan * completion. 5940*82527734SSukumar Swaminathan */ 5941*82527734SSukumar Swaminathan if (!(sbp->pkt_flags & 5942*82527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 5943*82527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 5944*82527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 5945*82527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 5946*82527734SSukumar Swaminathan cp->rsp_head = iocbq; 5947*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 5948*82527734SSukumar Swaminathan } else { 5949*82527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 5950*82527734SSukumar Swaminathan cp->rsp_tail = iocbq; 5951*82527734SSukumar Swaminathan } 5952*82527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 5953*82527734SSukumar Swaminathan 5954*82527734SSukumar Swaminathan /* Delay triggering thread till end of ISR */ 5955*82527734SSukumar Swaminathan cp->chan_flag |= EMLXS_NEEDS_TRIGGER; 5956*82527734SSukumar Swaminathan } else { 5957*82527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 5958*82527734SSukumar Swaminathan } 5959*82527734SSukumar Swaminathan } /* emlxs_sli4_cmpl_io() */ 5960*82527734SSukumar Swaminathan 5961*82527734SSukumar Swaminathan extern void 5962*82527734SSukumar Swaminathan emlxs_sli4_free_rpi(emlxs_hba_t *hba, RPIobj_t *rp) 5963*82527734SSukumar Swaminathan { 5964*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5965*82527734SSukumar Swaminathan XRIobj_t *xp; 5966*82527734SSukumar Swaminathan XRIobj_t *next_xp; 5967*82527734SSukumar Swaminathan 5968*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 5969*82527734SSukumar Swaminathan if (rp->state == RESOURCE_FREE) { 5970*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5971*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5972*82527734SSukumar Swaminathan "Free RPI:%d, Already freed", rp->RPI); 5973*82527734SSukumar Swaminathan return; 5974*82527734SSukumar Swaminathan } 5975*82527734SSukumar Swaminathan if (rp->outstandingXRIs) { 5976*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5977*82527734SSukumar Swaminathan "Free RPI:%d, %d outstanding XRIs", rp->RPI, 5978*82527734SSukumar Swaminathan rp->outstandingXRIs); 5979*82527734SSukumar Swaminathan } 5980*82527734SSukumar Swaminathan rp->state = RESOURCE_FREE; 5981*82527734SSukumar Swaminathan rp->VPIp = NULL; 5982*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 5983*82527734SSukumar Swaminathan 5984*82527734SSukumar Swaminathan /* Break node/RPI binding */ 5985*82527734SSukumar Swaminathan if (rp->node) { 5986*82527734SSukumar Swaminathan rw_enter(&port->node_rwlock, RW_WRITER); 5987*82527734SSukumar Swaminathan rp->node->RPIp = NULL; 5988*82527734SSukumar Swaminathan rp->node = NULL; 5989*82527734SSukumar Swaminathan rw_exit(&port->node_rwlock); 5990*82527734SSukumar Swaminathan } 5991*82527734SSukumar Swaminathan 5992*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 5993*82527734SSukumar Swaminathan /* Remove all XRIs under this RPI */ 5994*82527734SSukumar Swaminathan xp = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 5995*82527734SSukumar Swaminathan while (xp != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 5996*82527734SSukumar Swaminathan next_xp = xp->_f; 5997*82527734SSukumar Swaminathan if ((xp->state & RESOURCE_ALLOCATED) && 5998*82527734SSukumar Swaminathan (xp->RPIp == rp)) { 5999*82527734SSukumar Swaminathan xp->RPIp->outstandingXRIs--; 6000*82527734SSukumar Swaminathan xp->RPIp = NULL; 6001*82527734SSukumar Swaminathan } 6002*82527734SSukumar Swaminathan xp = next_xp; 6003*82527734SSukumar Swaminathan } 6004*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 6005*82527734SSukumar Swaminathan 6006*82527734SSukumar Swaminathan } /* emlxs_sli4_free_rpi() */ 6007*82527734SSukumar Swaminathan 6008*82527734SSukumar Swaminathan 6009*82527734SSukumar Swaminathan extern void 6010*82527734SSukumar Swaminathan emlxs_sli4_free_xri(emlxs_hba_t *hba, emlxs_buf_t *sbp, XRIobj_t *xp) 6011*82527734SSukumar Swaminathan { 6012*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6013*82527734SSukumar Swaminathan 6014*82527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 6015*82527734SSukumar Swaminathan if (xp) { 6016*82527734SSukumar Swaminathan if (xp->state == RESOURCE_FREE) { 6017*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 6018*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6019*82527734SSukumar Swaminathan "Free XRI:%x, Already freed", xp->XRI); 6020*82527734SSukumar Swaminathan return; 6021*82527734SSukumar Swaminathan } 6022*82527734SSukumar Swaminathan 6023*82527734SSukumar Swaminathan if (hba->fc_table[xp->iotag]) { 6024*82527734SSukumar Swaminathan hba->fc_table[xp->iotag] = NULL; 6025*82527734SSukumar Swaminathan hba->io_count--; 6026*82527734SSukumar Swaminathan } 6027*82527734SSukumar Swaminathan 6028*82527734SSukumar Swaminathan xp->state = RESOURCE_FREE; 6029*82527734SSukumar Swaminathan 6030*82527734SSukumar Swaminathan if (xp->RPIp) { 6031*82527734SSukumar Swaminathan xp->RPIp->outstandingXRIs--; 6032*82527734SSukumar Swaminathan xp->RPIp = NULL; 6033*82527734SSukumar Swaminathan } 6034*82527734SSukumar Swaminathan 6035*82527734SSukumar Swaminathan /* Take it off inuse list */ 6036*82527734SSukumar Swaminathan (xp->_b)->_f = xp->_f; 6037*82527734SSukumar Swaminathan (xp->_f)->_b = xp->_b; 6038*82527734SSukumar Swaminathan xp->_f = NULL; 6039*82527734SSukumar Swaminathan xp->_b = NULL; 6040*82527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 6041*82527734SSukumar Swaminathan 6042*82527734SSukumar Swaminathan /* Add it to end of free list */ 6043*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail->_f = xp; 6044*82527734SSukumar Swaminathan hba->sli.sli4.XRIfree_tail = xp; 6045*82527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 6046*82527734SSukumar Swaminathan } 6047*82527734SSukumar Swaminathan 6048*82527734SSukumar Swaminathan if (sbp) { 6049*82527734SSukumar Swaminathan sbp->xp = 0; 6050*82527734SSukumar Swaminathan 6051*82527734SSukumar Swaminathan if (xp && (xp->iotag != sbp->iotag)) { 6052*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6053*82527734SSukumar Swaminathan "sbp / iotag mismatch %p iotag:%d %d", sbp, 6054*82527734SSukumar Swaminathan sbp->iotag, xp->iotag); 6055*82527734SSukumar Swaminathan } 6056*82527734SSukumar Swaminathan 6057*82527734SSukumar Swaminathan if (sbp->iotag) { 6058*82527734SSukumar Swaminathan if (hba->fc_table[sbp->iotag]) { 6059*82527734SSukumar Swaminathan hba->fc_table[sbp->iotag] = NULL; 6060*82527734SSukumar Swaminathan hba->io_count--; 6061*82527734SSukumar Swaminathan } 6062*82527734SSukumar Swaminathan sbp->iotag = 0; 6063*82527734SSukumar Swaminathan } 6064*82527734SSukumar Swaminathan 6065*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 6066*82527734SSukumar Swaminathan 6067*82527734SSukumar Swaminathan /* Clean up the sbp */ 6068*82527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 6069*82527734SSukumar Swaminathan 6070*82527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_TXQ) { 6071*82527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_TXQ; 6072*82527734SSukumar Swaminathan hba->channel_tx_count--; 6073*82527734SSukumar Swaminathan } 6074*82527734SSukumar Swaminathan 6075*82527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 6076*82527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_CHIPQ; 6077*82527734SSukumar Swaminathan } 6078*82527734SSukumar Swaminathan 6079*82527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 6080*82527734SSukumar Swaminathan } else { 6081*82527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 6082*82527734SSukumar Swaminathan } 6083*82527734SSukumar Swaminathan 6084*82527734SSukumar Swaminathan } /* emlxs_sli4_free_xri() */ 6085*82527734SSukumar Swaminathan 6086*82527734SSukumar Swaminathan 6087*82527734SSukumar Swaminathan static int 6088*82527734SSukumar Swaminathan emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, MAILBOXQ *mbq) 6089*82527734SSukumar Swaminathan { 6090*82527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 6091*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6092*82527734SSukumar Swaminathan XRIobj_t *xp; 6093*82527734SSukumar Swaminathan MATCHMAP *mp; 6094*82527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 6095*82527734SSukumar Swaminathan uint32_t i, cnt, xri_cnt; 6096*82527734SSukumar Swaminathan uint32_t size; 6097*82527734SSukumar Swaminathan IOCTL_FCOE_CFG_POST_SGL_PAGES *post_sgl; 6098*82527734SSukumar Swaminathan 6099*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 6100*82527734SSukumar Swaminathan mbq->bp = NULL; 6101*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 6102*82527734SSukumar Swaminathan 6103*82527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, EMLXS_MAX_NONEMBED_SIZE)) == 0) { 6104*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6105*82527734SSukumar Swaminathan "Unable to POST_SGL. Mailbox cmd=%x ", 6106*82527734SSukumar Swaminathan mb->mbxCommand); 6107*82527734SSukumar Swaminathan return (EIO); 6108*82527734SSukumar Swaminathan } 6109*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)mp; 6110*82527734SSukumar Swaminathan 6111*82527734SSukumar Swaminathan /* 6112*82527734SSukumar Swaminathan * Signifies a non embedded command 6113*82527734SSukumar Swaminathan */ 6114*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 6115*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 6116*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 6117*82527734SSukumar Swaminathan 6118*82527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 6119*82527734SSukumar Swaminathan post_sgl = 6120*82527734SSukumar Swaminathan (IOCTL_FCOE_CFG_POST_SGL_PAGES *)(hdr_req + 1); 6121*82527734SSukumar Swaminathan 6122*82527734SSukumar Swaminathan 6123*82527734SSukumar Swaminathan xp = hba->sli.sli4.XRIp; 6124*82527734SSukumar Swaminathan cnt = hba->sli.sli4.XRICount; 6125*82527734SSukumar Swaminathan while (cnt) { 6126*82527734SSukumar Swaminathan bzero((void *) hdr_req, mp->size); 6127*82527734SSukumar Swaminathan size = mp->size - IOCTL_HEADER_SZ; 6128*82527734SSukumar Swaminathan 6129*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length = 6130*82527734SSukumar Swaminathan mp->size; 6131*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 6132*82527734SSukumar Swaminathan IOCTL_SUBSYSTEM_FCOE; 6133*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 6134*82527734SSukumar Swaminathan FCOE_OPCODE_CFG_POST_SGL_PAGES; 6135*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 6136*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = size; 6137*82527734SSukumar Swaminathan 6138*82527734SSukumar Swaminathan hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 6139*82527734SSukumar Swaminathan hdr_req->opcode = FCOE_OPCODE_CFG_POST_SGL_PAGES; 6140*82527734SSukumar Swaminathan hdr_req->timeout = 0; 6141*82527734SSukumar Swaminathan hdr_req->req_length = size; 6142*82527734SSukumar Swaminathan 6143*82527734SSukumar Swaminathan post_sgl->params.request.xri_count = 0; 6144*82527734SSukumar Swaminathan post_sgl->params.request.xri_start = xp->XRI; 6145*82527734SSukumar Swaminathan xri_cnt = (size - sizeof (IOCTL_FCOE_CFG_POST_SGL_PAGES)) / 6146*82527734SSukumar Swaminathan sizeof (FCOE_SGL_PAGES); 6147*82527734SSukumar Swaminathan for (i = 0; i < xri_cnt; i++) { 6148*82527734SSukumar Swaminathan 6149*82527734SSukumar Swaminathan post_sgl->params.request.xri_count++; 6150*82527734SSukumar Swaminathan post_sgl->params.request.pages[i].sgl_page0.addrLow = 6151*82527734SSukumar Swaminathan PADDR_LO(xp->SGList.phys); 6152*82527734SSukumar Swaminathan post_sgl->params.request.pages[i].sgl_page0.addrHigh = 6153*82527734SSukumar Swaminathan PADDR_HI(xp->SGList.phys); 6154*82527734SSukumar Swaminathan cnt--; 6155*82527734SSukumar Swaminathan xp++; 6156*82527734SSukumar Swaminathan if (cnt == 0) { 6157*82527734SSukumar Swaminathan break; 6158*82527734SSukumar Swaminathan } 6159*82527734SSukumar Swaminathan } 6160*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6161*82527734SSukumar Swaminathan MBX_SUCCESS) { 6162*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6163*82527734SSukumar Swaminathan "Unable to POST_SGL. Mailbox cmd=%x status=%x " 6164*82527734SSukumar Swaminathan "XRI cnt:%d start:%d", 6165*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus, 6166*82527734SSukumar Swaminathan post_sgl->params.request.xri_count, 6167*82527734SSukumar Swaminathan post_sgl->params.request.xri_start); 6168*82527734SSukumar Swaminathan (void) emlxs_mem_buf_free(hba, mp); 6169*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)NULL; 6170*82527734SSukumar Swaminathan return (EIO); 6171*82527734SSukumar Swaminathan } 6172*82527734SSukumar Swaminathan } 6173*82527734SSukumar Swaminathan (void) emlxs_mem_buf_free(hba, mp); 6174*82527734SSukumar Swaminathan mbq->nonembed = (uint8_t *)NULL; 6175*82527734SSukumar Swaminathan return (0); 6176*82527734SSukumar Swaminathan 6177*82527734SSukumar Swaminathan } /* emlxs_sli4_post_sgl_pages() */ 6178*82527734SSukumar Swaminathan 6179*82527734SSukumar Swaminathan 6180*82527734SSukumar Swaminathan static int 6181*82527734SSukumar Swaminathan emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, MAILBOXQ *mbq) 6182*82527734SSukumar Swaminathan { 6183*82527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 6184*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6185*82527734SSukumar Swaminathan int i, cnt; 6186*82527734SSukumar Swaminathan uint64_t addr; 6187*82527734SSukumar Swaminathan IOCTL_FCOE_POST_HDR_TEMPLATES *post_hdr; 6188*82527734SSukumar Swaminathan 6189*82527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 6190*82527734SSukumar Swaminathan mbq->bp = NULL; 6191*82527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 6192*82527734SSukumar Swaminathan 6193*82527734SSukumar Swaminathan /* 6194*82527734SSukumar Swaminathan * Signifies an embedded command 6195*82527734SSukumar Swaminathan */ 6196*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 1; 6197*82527734SSukumar Swaminathan 6198*82527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 6199*82527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 6200*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length = 6201*82527734SSukumar Swaminathan sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES) + IOCTL_HEADER_SZ; 6202*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 6203*82527734SSukumar Swaminathan IOCTL_SUBSYSTEM_FCOE; 6204*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 6205*82527734SSukumar Swaminathan FCOE_OPCODE_POST_HDR_TEMPLATES; 6206*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 6207*82527734SSukumar Swaminathan mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 6208*82527734SSukumar Swaminathan sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES); 6209*82527734SSukumar Swaminathan post_hdr = 6210*82527734SSukumar Swaminathan (IOCTL_FCOE_POST_HDR_TEMPLATES *)&mb->un.varSLIConfig.payload; 6211*82527734SSukumar Swaminathan addr = hba->sli.sli4.HeaderTmplate.phys; 6212*82527734SSukumar Swaminathan post_hdr->params.request.num_pages = 0; 6213*82527734SSukumar Swaminathan i = 0; 6214*82527734SSukumar Swaminathan cnt = hba->sli.sli4.HeaderTmplate.size; 6215*82527734SSukumar Swaminathan while (cnt > 0) { 6216*82527734SSukumar Swaminathan post_hdr->params.request.num_pages++; 6217*82527734SSukumar Swaminathan post_hdr->params.request.pages[i].addrLow = PADDR_LO(addr); 6218*82527734SSukumar Swaminathan post_hdr->params.request.pages[i].addrHigh = PADDR_HI(addr); 6219*82527734SSukumar Swaminathan i++; 6220*82527734SSukumar Swaminathan addr += 4096; 6221*82527734SSukumar Swaminathan cnt -= 4096; 6222*82527734SSukumar Swaminathan } 6223*82527734SSukumar Swaminathan post_hdr->params.request.starting_rpi_index = hba->sli.sli4.RPIBase; 6224*82527734SSukumar Swaminathan 6225*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6226*82527734SSukumar Swaminathan MBX_SUCCESS) { 6227*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6228*82527734SSukumar Swaminathan "Unable to POST_HDR_TEMPLATES. Mailbox cmd=%x status=%x ", 6229*82527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 6230*82527734SSukumar Swaminathan return (EIO); 6231*82527734SSukumar Swaminathan } 6232*82527734SSukumar Swaminathan emlxs_data_dump(hba, "POST_HDR", (uint32_t *)mb, 18, 0); 6233*82527734SSukumar Swaminathan return (0); 6234*82527734SSukumar Swaminathan 6235*82527734SSukumar Swaminathan } /* emlxs_sli4_post_hdr_tmplates() */ 6236*82527734SSukumar Swaminathan 6237*82527734SSukumar Swaminathan 6238*82527734SSukumar Swaminathan static int 6239*82527734SSukumar Swaminathan emlxs_sli4_create_queues(emlxs_hba_t *hba, MAILBOXQ *mbq) 6240*82527734SSukumar Swaminathan { 6241*82527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 6242*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6243*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 6244*82527734SSukumar Swaminathan IOCTL_COMMON_EQ_CREATE *eq; 6245*82527734SSukumar Swaminathan IOCTL_COMMON_CQ_CREATE *cq; 6246*82527734SSukumar Swaminathan IOCTL_FCOE_WQ_CREATE *wq; 6247*82527734SSukumar Swaminathan IOCTL_FCOE_RQ_CREATE *rq; 6248*82527734SSukumar Swaminathan IOCTL_COMMON_MQ_CREATE *mq; 6249*82527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 6250*82527734SSukumar Swaminathan int i, j; 6251*82527734SSukumar Swaminathan int num_cq, total_cq; 6252*82527734SSukumar Swaminathan int num_wq, total_wq; 6253*82527734SSukumar Swaminathan 6254*82527734SSukumar Swaminathan /* 6255*82527734SSukumar Swaminathan * The first CQ is reserved for ASYNC events, 6256*82527734SSukumar Swaminathan * the second is reserved for unsol rcv, the rest 6257*82527734SSukumar Swaminathan * correspond to WQs. (WQ0 -> CQ2, WQ1 -> CQ3, ...) 6258*82527734SSukumar Swaminathan */ 6259*82527734SSukumar Swaminathan 6260*82527734SSukumar Swaminathan /* First initialize queue ordinal mapping */ 6261*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_EQ_IDS; i++) { 6262*82527734SSukumar Swaminathan hba->sli.sli4.eq_map[i] = 0xffff; 6263*82527734SSukumar Swaminathan } 6264*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQ_IDS; i++) { 6265*82527734SSukumar Swaminathan hba->sli.sli4.cq_map[i] = 0xffff; 6266*82527734SSukumar Swaminathan } 6267*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQ_IDS; i++) { 6268*82527734SSukumar Swaminathan hba->sli.sli4.wq_map[i] = 0xffff; 6269*82527734SSukumar Swaminathan } 6270*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQ_IDS; i++) { 6271*82527734SSukumar Swaminathan hba->sli.sli4.rq_map[i] = 0xffff; 6272*82527734SSukumar Swaminathan } 6273*82527734SSukumar Swaminathan 6274*82527734SSukumar Swaminathan total_cq = 0; 6275*82527734SSukumar Swaminathan total_wq = 0; 6276*82527734SSukumar Swaminathan 6277*82527734SSukumar Swaminathan /* Create EQ's */ 6278*82527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 6279*82527734SSukumar Swaminathan emlxs_mb_eq_create(hba, mbq, i); 6280*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6281*82527734SSukumar Swaminathan MBX_SUCCESS) { 6282*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6283*82527734SSukumar Swaminathan "Unable to Create EQ %d: Mailbox cmd=%x status=%x ", 6284*82527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 6285*82527734SSukumar Swaminathan return (EIO); 6286*82527734SSukumar Swaminathan } 6287*82527734SSukumar Swaminathan eq = (IOCTL_COMMON_EQ_CREATE *)&mb->un.varSLIConfig.payload; 6288*82527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid = eq->params.response.EQId; 6289*82527734SSukumar Swaminathan hba->sli.sli4.eq_map[eq->params.response.EQId] = i; 6290*82527734SSukumar Swaminathan hba->sli.sli4.eq[i].lastwq = total_wq; 6291*82527734SSukumar Swaminathan 6292*82527734SSukumar Swaminathan emlxs_data_dump(hba, "EQ0_CREATE", (uint32_t *)mb, 18, 0); 6293*82527734SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current; 6294*82527734SSukumar Swaminathan num_cq = num_wq; 6295*82527734SSukumar Swaminathan if (i == 0) { 6296*82527734SSukumar Swaminathan /* One for RQ handling, one for mbox/event handling */ 6297*82527734SSukumar Swaminathan num_cq += EMLXS_CQ_OFFSET_WQ; 6298*82527734SSukumar Swaminathan } 6299*82527734SSukumar Swaminathan 6300*82527734SSukumar Swaminathan for (j = 0; j < num_cq; j++) { 6301*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 6302*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 6303*82527734SSukumar Swaminathan 6304*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].eqid = 6305*82527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid; 6306*82527734SSukumar Swaminathan 6307*82527734SSukumar Swaminathan emlxs_mb_cq_create(hba, mbq, total_cq); 6308*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6309*82527734SSukumar Swaminathan MBX_SUCCESS) { 6310*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 6311*82527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 6312*82527734SSukumar Swaminathan "CQ %d: Mailbox cmd=%x status=%x ", 6313*82527734SSukumar Swaminathan total_cq, mb->mbxCommand, mb->mbxStatus); 6314*82527734SSukumar Swaminathan return (EIO); 6315*82527734SSukumar Swaminathan } 6316*82527734SSukumar Swaminathan cq = (IOCTL_COMMON_CQ_CREATE *) 6317*82527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 6318*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].qid = 6319*82527734SSukumar Swaminathan cq->params.response.CQId; 6320*82527734SSukumar Swaminathan hba->sli.sli4.cq_map[cq->params.response.CQId] = 6321*82527734SSukumar Swaminathan total_cq; 6322*82527734SSukumar Swaminathan 6323*82527734SSukumar Swaminathan switch (total_cq) { 6324*82527734SSukumar Swaminathan case EMLXS_CQ_MBOX: 6325*82527734SSukumar Swaminathan /* First CQ is for async event handling */ 6326*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 6327*82527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP1; 6328*82527734SSukumar Swaminathan break; 6329*82527734SSukumar Swaminathan 6330*82527734SSukumar Swaminathan case EMLXS_CQ_RCV: 6331*82527734SSukumar Swaminathan /* Second CQ is for unsol receive handling */ 6332*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 6333*82527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 6334*82527734SSukumar Swaminathan break; 6335*82527734SSukumar Swaminathan 6336*82527734SSukumar Swaminathan default: 6337*82527734SSukumar Swaminathan /* Setup CQ to channel mapping */ 6338*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 6339*82527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 6340*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].channelp = 6341*82527734SSukumar Swaminathan &hba->chan[total_cq - EMLXS_CQ_OFFSET_WQ]; 6342*82527734SSukumar Swaminathan break; 6343*82527734SSukumar Swaminathan } 6344*82527734SSukumar Swaminathan emlxs_data_dump(hba, "CQX_CREATE", (uint32_t *)mb, 18, 0); 6345*82527734SSukumar Swaminathan total_cq++; 6346*82527734SSukumar Swaminathan } 6347*82527734SSukumar Swaminathan 6348*82527734SSukumar Swaminathan for (j = 0; j < num_wq; j++) { 6349*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 6350*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 6351*82527734SSukumar Swaminathan 6352*82527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 6353*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq + EMLXS_CQ_OFFSET_WQ].qid; 6354*82527734SSukumar Swaminathan 6355*82527734SSukumar Swaminathan emlxs_mb_wq_create(hba, mbq, total_wq); 6356*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6357*82527734SSukumar Swaminathan MBX_SUCCESS) { 6358*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 6359*82527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 6360*82527734SSukumar Swaminathan "WQ %d: Mailbox cmd=%x status=%x ", 6361*82527734SSukumar Swaminathan total_wq, mb->mbxCommand, mb->mbxStatus); 6362*82527734SSukumar Swaminathan return (EIO); 6363*82527734SSukumar Swaminathan } 6364*82527734SSukumar Swaminathan wq = (IOCTL_FCOE_WQ_CREATE *) 6365*82527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 6366*82527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].qid = 6367*82527734SSukumar Swaminathan wq->params.response.WQId; 6368*82527734SSukumar Swaminathan hba->sli.sli4.wq_map[wq->params.response.WQId] = 6369*82527734SSukumar Swaminathan total_wq; 6370*82527734SSukumar Swaminathan 6371*82527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 6372*82527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq+EMLXS_CQ_OFFSET_WQ].qid; 6373*82527734SSukumar Swaminathan emlxs_data_dump(hba, "WQ_CREATE", (uint32_t *)mb, 18, 0); 6374*82527734SSukumar Swaminathan total_wq++; 6375*82527734SSukumar Swaminathan } 6376*82527734SSukumar Swaminathan } 6377*82527734SSukumar Swaminathan 6378*82527734SSukumar Swaminathan /* We assume 1 RQ pair will handle ALL incoming data */ 6379*82527734SSukumar Swaminathan /* Create RQs */ 6380*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 6381*82527734SSukumar Swaminathan /* Personalize the RQ */ 6382*82527734SSukumar Swaminathan switch (i) { 6383*82527734SSukumar Swaminathan case 0: 6384*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 6385*82527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 6386*82527734SSukumar Swaminathan break; 6387*82527734SSukumar Swaminathan case 1: 6388*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 6389*82527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 6390*82527734SSukumar Swaminathan break; 6391*82527734SSukumar Swaminathan default: 6392*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 0xffff; 6393*82527734SSukumar Swaminathan } 6394*82527734SSukumar Swaminathan 6395*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 6396*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 6397*82527734SSukumar Swaminathan 6398*82527734SSukumar Swaminathan emlxs_mb_rq_create(hba, mbq, i); 6399*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6400*82527734SSukumar Swaminathan MBX_SUCCESS) { 6401*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6402*82527734SSukumar Swaminathan "Unable to Create RQ %d: Mailbox cmd=%x status=%x ", 6403*82527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 6404*82527734SSukumar Swaminathan return (EIO); 6405*82527734SSukumar Swaminathan } 6406*82527734SSukumar Swaminathan rq = (IOCTL_FCOE_RQ_CREATE *)&mb->un.varSLIConfig.payload; 6407*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].qid = rq->params.response.RQId; 6408*82527734SSukumar Swaminathan hba->sli.sli4.rq_map[rq->params.response.RQId] = i; 6409*82527734SSukumar Swaminathan emlxs_data_dump(hba, "RQ CREATE", (uint32_t *)mb, 18, 0); 6410*82527734SSukumar Swaminathan 6411*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6412*82527734SSukumar Swaminathan "RQ CREATE: rq[%d].qid=%d cqid=%d", 6413*82527734SSukumar Swaminathan i, hba->sli.sli4.rq[i].qid, hba->sli.sli4.rq[i].cqid); 6414*82527734SSukumar Swaminathan 6415*82527734SSukumar Swaminathan /* Initialize the host_index */ 6416*82527734SSukumar Swaminathan hba->sli.sli4.rq[i].host_index = 0; 6417*82527734SSukumar Swaminathan 6418*82527734SSukumar Swaminathan /* If Data queue was just created, */ 6419*82527734SSukumar Swaminathan /* then post buffers using the header qid */ 6420*82527734SSukumar Swaminathan if ((i & 0x1)) { 6421*82527734SSukumar Swaminathan /* Ring the RQ doorbell to post buffers */ 6422*82527734SSukumar Swaminathan rqdb.word = 0; 6423*82527734SSukumar Swaminathan rqdb.db.Qid = hba->sli.sli4.rq[i-1].qid; 6424*82527734SSukumar Swaminathan rqdb.db.NumPosted = RQB_COUNT; 6425*82527734SSukumar Swaminathan 6426*82527734SSukumar Swaminathan WRITE_BAR2_REG(hba, FC_RQDB_REG(hba), rqdb.word); 6427*82527734SSukumar Swaminathan 6428*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6429*82527734SSukumar Swaminathan "RQ CREATE: Doorbell rang: qid=%d count=%d", 6430*82527734SSukumar Swaminathan hba->sli.sli4.rq[i-1].qid, RQB_COUNT); 6431*82527734SSukumar Swaminathan } 6432*82527734SSukumar Swaminathan } 6433*82527734SSukumar Swaminathan 6434*82527734SSukumar Swaminathan /* Create MQ */ 6435*82527734SSukumar Swaminathan 6436*82527734SSukumar Swaminathan /* Personalize the MQ */ 6437*82527734SSukumar Swaminathan hba->sli.sli4.mq.cqid = hba->sli.sli4.cq[EMLXS_CQ_MBOX].qid; 6438*82527734SSukumar Swaminathan 6439*82527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 6440*82527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 6441*82527734SSukumar Swaminathan 6442*82527734SSukumar Swaminathan emlxs_mb_mq_create(hba, mbq); 6443*82527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 6444*82527734SSukumar Swaminathan MBX_SUCCESS) { 6445*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6446*82527734SSukumar Swaminathan "Unable to Create MQ %d: Mailbox cmd=%x status=%x ", 6447*82527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 6448*82527734SSukumar Swaminathan return (EIO); 6449*82527734SSukumar Swaminathan } 6450*82527734SSukumar Swaminathan mq = (IOCTL_COMMON_MQ_CREATE *)&mb->un.varSLIConfig.payload; 6451*82527734SSukumar Swaminathan hba->sli.sli4.mq.qid = mq->params.response.MQId; 6452*82527734SSukumar Swaminathan return (0); 6453*82527734SSukumar Swaminathan 6454*82527734SSukumar Swaminathan } /* emlxs_sli4_create_queues() */ 6455*82527734SSukumar Swaminathan 6456*82527734SSukumar Swaminathan 6457*82527734SSukumar Swaminathan static int 6458*82527734SSukumar Swaminathan emlxs_fcf_bind(emlxs_hba_t *hba) 6459*82527734SSukumar Swaminathan { 6460*82527734SSukumar Swaminathan MAILBOXQ *mbq; 6461*82527734SSukumar Swaminathan int rc; 6462*82527734SSukumar Swaminathan 6463*82527734SSukumar Swaminathan if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) { 6464*82527734SSukumar Swaminathan return (0); 6465*82527734SSukumar Swaminathan } 6466*82527734SSukumar Swaminathan if (!(hba->flag & FC_FIP_SUPPORTED)) { 6467*82527734SSukumar Swaminathan /* 6468*82527734SSukumar Swaminathan * If the firmware donesn't support FIP, we must 6469*82527734SSukumar Swaminathan * build the fcf table manually first. 6470*82527734SSukumar Swaminathan */ 6471*82527734SSukumar Swaminathan rc = emlxs_mbext_add_fcf_table(hba, mbq, 0); 6472*82527734SSukumar Swaminathan } else { 6473*82527734SSukumar Swaminathan rc = emlxs_mbext_read_fcf_table(hba, mbq, -1); 6474*82527734SSukumar Swaminathan } 6475*82527734SSukumar Swaminathan 6476*82527734SSukumar Swaminathan if (rc == 0) { 6477*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 6478*82527734SSukumar Swaminathan return (0); 6479*82527734SSukumar Swaminathan } 6480*82527734SSukumar Swaminathan 6481*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 6482*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 6483*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 6484*82527734SSukumar Swaminathan } 6485*82527734SSukumar Swaminathan return (1); 6486*82527734SSukumar Swaminathan 6487*82527734SSukumar Swaminathan } /* emlxs_fcf_bind() */ 6488*82527734SSukumar Swaminathan 6489*82527734SSukumar Swaminathan 6490*82527734SSukumar Swaminathan static int 6491*82527734SSukumar Swaminathan emlxs_fcf_unbind(emlxs_hba_t *hba, uint32_t index) 6492*82527734SSukumar Swaminathan { 6493*82527734SSukumar Swaminathan FCFIobj_t *fp; 6494*82527734SSukumar Swaminathan int i; 6495*82527734SSukumar Swaminathan 6496*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 6497*82527734SSukumar Swaminathan /* Loop thru all FCFIs */ 6498*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 6499*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.FCFICount; i++) { 6500*82527734SSukumar Swaminathan if ((index == MAX_FCFCONNECTLIST_ENTRIES) || 6501*82527734SSukumar Swaminathan (index == fp->FCF_index)) { 6502*82527734SSukumar Swaminathan if (fp->state & RESOURCE_ALLOCATED) { 6503*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 6504*82527734SSukumar Swaminathan if (hba->state > FC_LINK_DOWN) { 6505*82527734SSukumar Swaminathan fp->state &= ~RESOURCE_FCFI_DISC; 6506*82527734SSukumar Swaminathan /* Declare link down here */ 6507*82527734SSukumar Swaminathan emlxs_linkdown(hba); 6508*82527734SSukumar Swaminathan } 6509*82527734SSukumar Swaminathan /* There should only be 1 FCF for now */ 6510*82527734SSukumar Swaminathan return (1); 6511*82527734SSukumar Swaminathan } 6512*82527734SSukumar Swaminathan } 6513*82527734SSukumar Swaminathan } 6514*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 6515*82527734SSukumar Swaminathan return (0); 6516*82527734SSukumar Swaminathan 6517*82527734SSukumar Swaminathan } /* emlxs_fcf_unbind() */ 6518*82527734SSukumar Swaminathan 6519*82527734SSukumar Swaminathan 6520*82527734SSukumar Swaminathan /*ARGSUSED*/ 6521*82527734SSukumar Swaminathan extern int 6522*82527734SSukumar Swaminathan emlxs_sli4_check_fcf_config(emlxs_hba_t *hba, FCF_RECORD_t *fcfrec) 6523*82527734SSukumar Swaminathan { 6524*82527734SSukumar Swaminathan int i; 6525*82527734SSukumar Swaminathan 6526*82527734SSukumar Swaminathan if (!(hba->flag & FC_FIP_SUPPORTED)) { 6527*82527734SSukumar Swaminathan if (!hba->sli.sli4.cfgFCOE.length) { 6528*82527734SSukumar Swaminathan /* Nothing specified, so everything matches */ 6529*82527734SSukumar Swaminathan /* For nonFIP only use index 0 */ 6530*82527734SSukumar Swaminathan if (fcfrec->fcf_index == 0) { 6531*82527734SSukumar Swaminathan return (1); /* success */ 6532*82527734SSukumar Swaminathan } 6533*82527734SSukumar Swaminathan return (0); 6534*82527734SSukumar Swaminathan } 6535*82527734SSukumar Swaminathan 6536*82527734SSukumar Swaminathan /* Just check FCMap for now */ 6537*82527734SSukumar Swaminathan if (bcmp((char *)fcfrec->fc_map, 6538*82527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap, 3) == 0) { 6539*82527734SSukumar Swaminathan return (1); /* success */ 6540*82527734SSukumar Swaminathan } 6541*82527734SSukumar Swaminathan return (0); 6542*82527734SSukumar Swaminathan } 6543*82527734SSukumar Swaminathan 6544*82527734SSukumar Swaminathan /* For FIP mode, the FCF record must match Config Region 23 */ 6545*82527734SSukumar Swaminathan 6546*82527734SSukumar Swaminathan if (!hba->sli.sli4.cfgFCF.length) { 6547*82527734SSukumar Swaminathan /* Nothing specified, so everything matches */ 6548*82527734SSukumar Swaminathan return (1); /* success */ 6549*82527734SSukumar Swaminathan } 6550*82527734SSukumar Swaminathan 6551*82527734SSukumar Swaminathan /* Just check FabricName for now */ 6552*82527734SSukumar Swaminathan for (i = 0; i < MAX_FCFCONNECTLIST_ENTRIES; i++) { 6553*82527734SSukumar Swaminathan if ((hba->sli.sli4.cfgFCF.entry[i].FabricNameValid) && 6554*82527734SSukumar Swaminathan (bcmp((char *)fcfrec->fabric_name_identifier, 6555*82527734SSukumar Swaminathan hba->sli.sli4.cfgFCF.entry[i].FabricName, 8) == 0)) { 6556*82527734SSukumar Swaminathan return (1); /* success */ 6557*82527734SSukumar Swaminathan } 6558*82527734SSukumar Swaminathan } 6559*82527734SSukumar Swaminathan return (0); 6560*82527734SSukumar Swaminathan } 6561*82527734SSukumar Swaminathan 6562*82527734SSukumar Swaminathan 6563*82527734SSukumar Swaminathan extern FCFIobj_t * 6564*82527734SSukumar Swaminathan emlxs_sli4_assign_fcfi(emlxs_hba_t *hba, FCF_RECORD_t *fcfrec) 6565*82527734SSukumar Swaminathan { 6566*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6567*82527734SSukumar Swaminathan FCFIobj_t *fcfp; 6568*82527734SSukumar Swaminathan int i; 6569*82527734SSukumar Swaminathan 6570*82527734SSukumar Swaminathan fcfp = emlxs_sli4_find_fcfi_fcfrec(hba, fcfrec); 6571*82527734SSukumar Swaminathan if (!fcfp) { 6572*82527734SSukumar Swaminathan fcfp = emlxs_sli4_alloc_fcfi(hba); 6573*82527734SSukumar Swaminathan if (!fcfp) { 6574*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6575*82527734SSukumar Swaminathan "Unable to alloc FCFI for fcf index %d", 6576*82527734SSukumar Swaminathan fcfrec->fcf_index); 6577*82527734SSukumar Swaminathan return (0); 6578*82527734SSukumar Swaminathan } 6579*82527734SSukumar Swaminathan fcfp->FCF_index = fcfrec->fcf_index; 6580*82527734SSukumar Swaminathan } 6581*82527734SSukumar Swaminathan 6582*82527734SSukumar Swaminathan bcopy((char *)fcfrec, &fcfp->fcf_rec, sizeof (FCF_RECORD_t)); 6583*82527734SSukumar Swaminathan 6584*82527734SSukumar Swaminathan for (i = 0; i < 512; i++) { 6585*82527734SSukumar Swaminathan if (fcfrec->vlan_bitmap[i / 8] == (1 << (i % 8))) { 6586*82527734SSukumar Swaminathan fcfp->vlan_id = i; 6587*82527734SSukumar Swaminathan fcfp->state |= RESOURCE_FCFI_VLAN_ID; 6588*82527734SSukumar Swaminathan break; 6589*82527734SSukumar Swaminathan } 6590*82527734SSukumar Swaminathan } 6591*82527734SSukumar Swaminathan 6592*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6593*82527734SSukumar Swaminathan "FCFI %d: idx %x av %x val %x ste %x macp %x vid %x " 6594*82527734SSukumar Swaminathan "addr: %02x:%02x:%02x:%02x:%02x:%02x", 6595*82527734SSukumar Swaminathan fcfp->FCFI, 6596*82527734SSukumar Swaminathan fcfrec->fcf_index, 6597*82527734SSukumar Swaminathan fcfrec->fcf_available, 6598*82527734SSukumar Swaminathan fcfrec->fcf_valid, 6599*82527734SSukumar Swaminathan fcfrec->fcf_state, 6600*82527734SSukumar Swaminathan fcfrec->mac_address_provider, 6601*82527734SSukumar Swaminathan fcfp->vlan_id, 6602*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_hi[0], 6603*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_hi[1], 6604*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_hi[2], 6605*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_hi[3], 6606*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_low[0], 6607*82527734SSukumar Swaminathan fcfrec->fcf_mac_address_low[1]); 6608*82527734SSukumar Swaminathan 6609*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6610*82527734SSukumar Swaminathan "fabric: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 6611*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[0], 6612*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[1], 6613*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[2], 6614*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[3], 6615*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[4], 6616*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[5], 6617*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[6], 6618*82527734SSukumar Swaminathan fcfrec->fabric_name_identifier[7]); 6619*82527734SSukumar Swaminathan 6620*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6621*82527734SSukumar Swaminathan "switch: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 6622*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[0], 6623*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[1], 6624*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[2], 6625*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[3], 6626*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[4], 6627*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[5], 6628*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[6], 6629*82527734SSukumar Swaminathan fcfrec->switch_name_identifier[7]); 6630*82527734SSukumar Swaminathan 6631*82527734SSukumar Swaminathan return (fcfp); 6632*82527734SSukumar Swaminathan 6633*82527734SSukumar Swaminathan } /* emlxs_sli4_assign_fcfi() */ 6634*82527734SSukumar Swaminathan 6635*82527734SSukumar Swaminathan 6636*82527734SSukumar Swaminathan extern FCFIobj_t * 6637*82527734SSukumar Swaminathan emlxs_sli4_bind_fcfi(emlxs_hba_t *hba) 6638*82527734SSukumar Swaminathan { 6639*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6640*82527734SSukumar Swaminathan FCFIobj_t *fp; 6641*82527734SSukumar Swaminathan VFIobj_t *vfip; 6642*82527734SSukumar Swaminathan MAILBOXQ *mbq; 6643*82527734SSukumar Swaminathan int rc; 6644*82527734SSukumar Swaminathan uint32_t i; 6645*82527734SSukumar Swaminathan 6646*82527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.id_lock); 6647*82527734SSukumar Swaminathan /* Loop thru all FCFIs */ 6648*82527734SSukumar Swaminathan fp = hba->sli.sli4.FCFIp; 6649*82527734SSukumar Swaminathan for (i = 0; i < hba->sli.sli4.FCFICount; i++) { 6650*82527734SSukumar Swaminathan if (fp->state & RESOURCE_ALLOCATED) { 6651*82527734SSukumar Swaminathan /* 6652*82527734SSukumar Swaminathan * Look for one thats valid, available 6653*82527734SSukumar Swaminathan * and matches our FCF configuration info. 6654*82527734SSukumar Swaminathan */ 6655*82527734SSukumar Swaminathan if (fp->fcf_rec.fcf_valid && 6656*82527734SSukumar Swaminathan fp->fcf_rec.fcf_available && 6657*82527734SSukumar Swaminathan emlxs_sli4_check_fcf_config(hba, &fp->fcf_rec)) { 6658*82527734SSukumar Swaminathan /* Since we only support one FCF */ 6659*82527734SSukumar Swaminathan break; 6660*82527734SSukumar Swaminathan } 6661*82527734SSukumar Swaminathan } 6662*82527734SSukumar Swaminathan fp++; 6663*82527734SSukumar Swaminathan } 6664*82527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.id_lock); 6665*82527734SSukumar Swaminathan 6666*82527734SSukumar Swaminathan if (i == hba->sli.sli4.FCFICount) { 6667*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6668*82527734SSukumar Swaminathan "Not a valid FCF"); 6669*82527734SSukumar Swaminathan return (0); 6670*82527734SSukumar Swaminathan } 6671*82527734SSukumar Swaminathan 6672*82527734SSukumar Swaminathan if (fp->state & RESOURCE_FCFI_REG) { 6673*82527734SSukumar Swaminathan 6674*82527734SSukumar Swaminathan if (!fp->fcf_vfi) { 6675*82527734SSukumar Swaminathan vfip = emlxs_sli4_alloc_vfi(hba, fp); 6676*82527734SSukumar Swaminathan if (!vfip) { 6677*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 6678*82527734SSukumar Swaminathan &emlxs_init_failed_msg, 6679*82527734SSukumar Swaminathan "Fabric VFI alloc failure, fcf index %d", 6680*82527734SSukumar Swaminathan fp->FCF_index); 6681*82527734SSukumar Swaminathan (void) emlxs_sli4_free_fcfi(hba, fp); 6682*82527734SSukumar Swaminathan return (0); 6683*82527734SSukumar Swaminathan } 6684*82527734SSukumar Swaminathan fp->fcf_vfi = vfip; 6685*82527734SSukumar Swaminathan } 6686*82527734SSukumar Swaminathan 6687*82527734SSukumar Swaminathan if (!fp->fcf_vpi) { 6688*82527734SSukumar Swaminathan fp->fcf_vpi = port; 6689*82527734SSukumar Swaminathan port->VFIp = fp->fcf_vfi; 6690*82527734SSukumar Swaminathan port->VFIp->outstandingVPIs++; 6691*82527734SSukumar Swaminathan } 6692*82527734SSukumar Swaminathan 6693*82527734SSukumar Swaminathan if (!(fp->state & RESOURCE_FCFI_DISC)) { 6694*82527734SSukumar Swaminathan fp->state |= RESOURCE_FCFI_DISC; 6695*82527734SSukumar Swaminathan emlxs_linkup(hba); 6696*82527734SSukumar Swaminathan } 6697*82527734SSukumar Swaminathan return (fp); 6698*82527734SSukumar Swaminathan } 6699*82527734SSukumar Swaminathan 6700*82527734SSukumar Swaminathan if ((mbq = (MAILBOXQ *) emlxs_mem_get(hba, MEM_MBOX, 1)) == 0) { 6701*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6702*82527734SSukumar Swaminathan "Unable to alloc mbox for fcf index %d", 6703*82527734SSukumar Swaminathan fp->fcf_rec.fcf_index); 6704*82527734SSukumar Swaminathan return (0); 6705*82527734SSukumar Swaminathan } 6706*82527734SSukumar Swaminathan emlxs_mb_reg_fcfi(hba, mbq, fp); 6707*82527734SSukumar Swaminathan 6708*82527734SSukumar Swaminathan rc = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 6709*82527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 6710*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 6711*82527734SSukumar Swaminathan "Unable to issue mbox for fcf index %d", 6712*82527734SSukumar Swaminathan fp->fcf_rec.fcf_index); 6713*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq); 6714*82527734SSukumar Swaminathan } 6715*82527734SSukumar Swaminathan 6716*82527734SSukumar Swaminathan return (fp); 6717*82527734SSukumar Swaminathan 6718*82527734SSukumar Swaminathan } /* emlxs_sli4_bind_fcfi() */ 6719*82527734SSukumar Swaminathan 6720*82527734SSukumar Swaminathan 6721*82527734SSukumar Swaminathan extern void 6722*82527734SSukumar Swaminathan emlxs_sli4_timer(emlxs_hba_t *hba) 6723*82527734SSukumar Swaminathan { 6724*82527734SSukumar Swaminathan /* Perform SLI4 level timer checks */ 6725*82527734SSukumar Swaminathan 6726*82527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(hba); 6727*82527734SSukumar Swaminathan 6728*82527734SSukumar Swaminathan return; 6729*82527734SSukumar Swaminathan 6730*82527734SSukumar Swaminathan } /* emlxs_sli4_timer() */ 6731*82527734SSukumar Swaminathan 6732*82527734SSukumar Swaminathan 6733*82527734SSukumar Swaminathan static void 6734*82527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba) 6735*82527734SSukumar Swaminathan { 6736*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6737*82527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 6738*82527734SSukumar Swaminathan MAILBOX *mb = NULL; 6739*82527734SSukumar Swaminathan 6740*82527734SSukumar Swaminathan if (!cfg[CFG_TIMEOUT_ENABLE].current) { 6741*82527734SSukumar Swaminathan return; 6742*82527734SSukumar Swaminathan } 6743*82527734SSukumar Swaminathan 6744*82527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 6745*82527734SSukumar Swaminathan 6746*82527734SSukumar Swaminathan /* Return if timer hasn't expired */ 6747*82527734SSukumar Swaminathan if (!hba->mbox_timer || (hba->timer_tics < hba->mbox_timer)) { 6748*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 6749*82527734SSukumar Swaminathan return; 6750*82527734SSukumar Swaminathan } 6751*82527734SSukumar Swaminathan hba->mbox_timer = 0; 6752*82527734SSukumar Swaminathan 6753*82527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 6754*82527734SSukumar Swaminathan if (hba->mbox_mbq) { 6755*82527734SSukumar Swaminathan mb = (MAILBOX *)hba->mbox_mbq; 6756*82527734SSukumar Swaminathan } 6757*82527734SSukumar Swaminathan } 6758*82527734SSukumar Swaminathan 6759*82527734SSukumar Swaminathan if (mb) { 6760*82527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 6761*82527734SSukumar Swaminathan case MBX_NOWAIT: 6762*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 6763*82527734SSukumar Swaminathan "%s: Nowait.", 6764*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 6765*82527734SSukumar Swaminathan break; 6766*82527734SSukumar Swaminathan 6767*82527734SSukumar Swaminathan case MBX_SLEEP: 6768*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 6769*82527734SSukumar Swaminathan "%s: mb=%p Sleep.", 6770*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 6771*82527734SSukumar Swaminathan mb); 6772*82527734SSukumar Swaminathan break; 6773*82527734SSukumar Swaminathan 6774*82527734SSukumar Swaminathan case MBX_POLL: 6775*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 6776*82527734SSukumar Swaminathan "%s: mb=%p Polled.", 6777*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 6778*82527734SSukumar Swaminathan mb); 6779*82527734SSukumar Swaminathan break; 6780*82527734SSukumar Swaminathan 6781*82527734SSukumar Swaminathan default: 6782*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 6783*82527734SSukumar Swaminathan "%s: mb=%p (%d).", 6784*82527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 6785*82527734SSukumar Swaminathan mb, hba->mbox_queue_flag); 6786*82527734SSukumar Swaminathan break; 6787*82527734SSukumar Swaminathan } 6788*82527734SSukumar Swaminathan } else { 6789*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, NULL); 6790*82527734SSukumar Swaminathan } 6791*82527734SSukumar Swaminathan 6792*82527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 6793*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_ERROR); 6794*82527734SSukumar Swaminathan 6795*82527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 6796*82527734SSukumar Swaminathan 6797*82527734SSukumar Swaminathan /* Perform mailbox cleanup */ 6798*82527734SSukumar Swaminathan /* This will wake any sleeping or polling threads */ 6799*82527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 6800*82527734SSukumar Swaminathan 6801*82527734SSukumar Swaminathan /* Trigger adapter shutdown */ 6802*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, NULL, NULL); 6803*82527734SSukumar Swaminathan 6804*82527734SSukumar Swaminathan return; 6805*82527734SSukumar Swaminathan 6806*82527734SSukumar Swaminathan } /* emlxs_sli4_timer_check_mbox() */ 6807*82527734SSukumar Swaminathan 6808*82527734SSukumar Swaminathan 6809*82527734SSukumar Swaminathan extern void 6810*82527734SSukumar Swaminathan emlxs_data_dump(emlxs_hba_t *hba, char *str, uint32_t *iptr, int cnt, int err) 6811*82527734SSukumar Swaminathan { 6812*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6813*82527734SSukumar Swaminathan void *msg; 6814*82527734SSukumar Swaminathan 6815*82527734SSukumar Swaminathan if (err) { 6816*82527734SSukumar Swaminathan msg = &emlxs_sli_err_msg; 6817*82527734SSukumar Swaminathan } else { 6818*82527734SSukumar Swaminathan msg = &emlxs_sli_detail_msg; 6819*82527734SSukumar Swaminathan } 6820*82527734SSukumar Swaminathan 6821*82527734SSukumar Swaminathan if (cnt) { 6822*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6823*82527734SSukumar Swaminathan "%s00: %08x %08x %08x %08x %08x %08x", str, *iptr, 6824*82527734SSukumar Swaminathan *(iptr+1), *(iptr+2), *(iptr+3), *(iptr+4), *(iptr+5)); 6825*82527734SSukumar Swaminathan } 6826*82527734SSukumar Swaminathan if (cnt > 6) { 6827*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6828*82527734SSukumar Swaminathan "%s06: %08x %08x %08x %08x %08x %08x", str, *(iptr+6), 6829*82527734SSukumar Swaminathan *(iptr+7), *(iptr+8), *(iptr+9), *(iptr+10), *(iptr+11)); 6830*82527734SSukumar Swaminathan } 6831*82527734SSukumar Swaminathan if (cnt > 12) { 6832*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6833*82527734SSukumar Swaminathan "%s12: %08x %08x %08x %08x %08x %08x", str, *(iptr+12), 6834*82527734SSukumar Swaminathan *(iptr+13), *(iptr+14), *(iptr+15), *(iptr+16), *(iptr+17)); 6835*82527734SSukumar Swaminathan } 6836*82527734SSukumar Swaminathan if (cnt > 18) { 6837*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6838*82527734SSukumar Swaminathan "%s18: %08x %08x %08x %08x %08x %08x", str, *(iptr+18), 6839*82527734SSukumar Swaminathan *(iptr+19), *(iptr+20), *(iptr+21), *(iptr+22), *(iptr+23)); 6840*82527734SSukumar Swaminathan } 6841*82527734SSukumar Swaminathan if (cnt > 24) { 6842*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6843*82527734SSukumar Swaminathan "%s24: %08x %08x %08x %08x %08x %08x", str, *(iptr+24), 6844*82527734SSukumar Swaminathan *(iptr+25), *(iptr+26), *(iptr+27), *(iptr+28), *(iptr+29)); 6845*82527734SSukumar Swaminathan } 6846*82527734SSukumar Swaminathan if (cnt > 30) { 6847*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6848*82527734SSukumar Swaminathan "%s30: %08x %08x %08x %08x %08x %08x", str, *(iptr+30), 6849*82527734SSukumar Swaminathan *(iptr+31), *(iptr+32), *(iptr+33), *(iptr+34), *(iptr+35)); 6850*82527734SSukumar Swaminathan } 6851*82527734SSukumar Swaminathan if (cnt > 36) { 6852*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 6853*82527734SSukumar Swaminathan "%s36: %08x %08x %08x %08x %08x %08x", str, *(iptr+36), 6854*82527734SSukumar Swaminathan *(iptr+37), *(iptr+38), *(iptr+39), *(iptr+40), *(iptr+41)); 6855*82527734SSukumar Swaminathan } 6856*82527734SSukumar Swaminathan 6857*82527734SSukumar Swaminathan } /* emlxs_data_dump() */ 6858*82527734SSukumar Swaminathan 6859*82527734SSukumar Swaminathan 6860*82527734SSukumar Swaminathan extern void 6861*82527734SSukumar Swaminathan emlxs_ue_dump(emlxs_hba_t *hba, char *str) 6862*82527734SSukumar Swaminathan { 6863*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6864*82527734SSukumar Swaminathan uint32_t ue_h; 6865*82527734SSukumar Swaminathan uint32_t ue_l; 6866*82527734SSukumar Swaminathan uint32_t on1; 6867*82527734SSukumar Swaminathan uint32_t on2; 6868*82527734SSukumar Swaminathan 6869*82527734SSukumar Swaminathan ue_l = ddi_get32(hba->pci_acc_handle, 6870*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET)); 6871*82527734SSukumar Swaminathan ue_h = ddi_get32(hba->pci_acc_handle, 6872*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET)); 6873*82527734SSukumar Swaminathan on1 = ddi_get32(hba->pci_acc_handle, 6874*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE1)); 6875*82527734SSukumar Swaminathan on2 = ddi_get32(hba->pci_acc_handle, 6876*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE2)); 6877*82527734SSukumar Swaminathan 6878*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6879*82527734SSukumar Swaminathan "%s: ueLow:%08x ueHigh:%08x on1:%08x on2:%08x", str, 6880*82527734SSukumar Swaminathan ue_l, ue_h, on1, on2); 6881*82527734SSukumar Swaminathan 6882*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 6883*82527734SSukumar Swaminathan /* Access handle validation */ 6884*82527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->pci_acc_handle); 6885*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 6886*82527734SSukumar Swaminathan 6887*82527734SSukumar Swaminathan } /* emlxs_ue_dump() */ 6888*82527734SSukumar Swaminathan 6889*82527734SSukumar Swaminathan 6890*82527734SSukumar Swaminathan void 6891*82527734SSukumar Swaminathan emlxs_sli4_poll_erratt(emlxs_hba_t *hba) 6892*82527734SSukumar Swaminathan { 6893*82527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6894*82527734SSukumar Swaminathan uint32_t ue_h; 6895*82527734SSukumar Swaminathan uint32_t ue_l; 6896*82527734SSukumar Swaminathan uint32_t on1; 6897*82527734SSukumar Swaminathan uint32_t on2; 6898*82527734SSukumar Swaminathan 6899*82527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 6900*82527734SSukumar Swaminathan return; 6901*82527734SSukumar Swaminathan } 6902*82527734SSukumar Swaminathan 6903*82527734SSukumar Swaminathan on1 = ddi_get32(hba->pci_acc_handle, 6904*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE1)); 6905*82527734SSukumar Swaminathan on2 = ddi_get32(hba->pci_acc_handle, 6906*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE2)); 6907*82527734SSukumar Swaminathan 6908*82527734SSukumar Swaminathan if (on1 != 0xffffffff || on2 != 0xffffffff) { 6909*82527734SSukumar Swaminathan ue_l = ddi_get32(hba->pci_acc_handle, 6910*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET)); 6911*82527734SSukumar Swaminathan ue_h = ddi_get32(hba->pci_acc_handle, 6912*82527734SSukumar Swaminathan (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET)); 6913*82527734SSukumar Swaminathan 6914*82527734SSukumar Swaminathan /* Unrecoverable error detected */ 6915*82527734SSukumar Swaminathan /* Shut the HBA down */ 6916*82527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg, 6917*82527734SSukumar Swaminathan "Host Error: ueLow:%08x ueHigh:%08x on1:%08x on2:%08x", 6918*82527734SSukumar Swaminathan ue_l, ue_h, on1, on2); 6919*82527734SSukumar Swaminathan 6920*82527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 6921*82527734SSukumar Swaminathan 6922*82527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(hba); 6923*82527734SSukumar Swaminathan 6924*82527734SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_shutdown_thread, NULL, NULL); 6925*82527734SSukumar Swaminathan } 6926*82527734SSukumar Swaminathan 6927*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT 6928*82527734SSukumar Swaminathan /* The PCI(e) driver generates PCI error when PCI read returns */ 6929*82527734SSukumar Swaminathan /* 0xFFFFFFFF value. Since PCICFG_UE_STATUS_ONLINE0 and */ 6930*82527734SSukumar Swaminathan /* PCICFG_UE_STATUS_ONLINE1 registers return 0xFFFFFFFF to */ 6931*82527734SSukumar Swaminathan /* indicate that no internal component has an unrecoverable */ 6932*82527734SSukumar Swaminathan /* error on HBA, no access handle check and just call below */ 6933*82527734SSukumar Swaminathan /* function to clear the access handle error here. */ 6934*82527734SSukumar Swaminathan 6935*82527734SSukumar Swaminathan /* Some S10 versions do not define the ddi_fm_acc_err_clear function */ 6936*82527734SSukumar Swaminathan if ((void *)&ddi_fm_acc_err_clear != NULL) { 6937*82527734SSukumar Swaminathan (void) ddi_fm_acc_err_clear(hba->pci_acc_handle, 6938*82527734SSukumar Swaminathan DDI_FME_VERSION); 6939*82527734SSukumar Swaminathan } 6940*82527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 6941*82527734SSukumar Swaminathan 6942*82527734SSukumar Swaminathan } /* emlxs_sli4_poll_erratt() */ 6943*82527734SSukumar Swaminathan 6944*82527734SSukumar Swaminathan int 6945*82527734SSukumar Swaminathan emlxs_sli4_unreg_all_rpi_by_port(emlxs_port_t *port) 6946*82527734SSukumar Swaminathan { 6947*82527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 6948*82527734SSukumar Swaminathan NODELIST *nlp; 6949*82527734SSukumar Swaminathan int i; 6950*82527734SSukumar Swaminathan 6951*82527734SSukumar Swaminathan rw_enter(&port->node_rwlock, RW_WRITER); 6952*82527734SSukumar Swaminathan for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 6953*82527734SSukumar Swaminathan nlp = port->node_table[i]; 6954*82527734SSukumar Swaminathan while (nlp != NULL) { 6955*82527734SSukumar Swaminathan if (nlp->nlp_Rpi != 0xffff) { 6956*82527734SSukumar Swaminathan rw_exit(&port->node_rwlock); 6957*82527734SSukumar Swaminathan (void) emlxs_mb_unreg_rpi(port, 6958*82527734SSukumar Swaminathan nlp->nlp_Rpi, 0, 0, 0); 6959*82527734SSukumar Swaminathan rw_enter(&port->node_rwlock, RW_WRITER); 6960*82527734SSukumar Swaminathan } else { 6961*82527734SSukumar Swaminathan /* Just free nlp back to the pool */ 6962*82527734SSukumar Swaminathan port->node_table[i] = nlp->nlp_list_next; 6963*82527734SSukumar Swaminathan (void) emlxs_mem_put(hba, MEM_NLP, 6964*82527734SSukumar Swaminathan (uint8_t *)nlp); 6965*82527734SSukumar Swaminathan } 6966*82527734SSukumar Swaminathan nlp = port->node_table[i]; 6967*82527734SSukumar Swaminathan } 6968*82527734SSukumar Swaminathan } 6969*82527734SSukumar Swaminathan rw_exit(&port->node_rwlock); 6970*82527734SSukumar Swaminathan 6971*82527734SSukumar Swaminathan return (0); 6972*82527734SSukumar Swaminathan } /* emlxs_sli4_unreg_all_rpi_by_port() */ 6973