182527734SSukumar Swaminathan /* 282527734SSukumar Swaminathan * CDDL HEADER START 382527734SSukumar Swaminathan * 482527734SSukumar Swaminathan * The contents of this file are subject to the terms of the 582527734SSukumar Swaminathan * Common Development and Distribution License (the "License"). 682527734SSukumar Swaminathan * You may not use this file except in compliance with the License. 782527734SSukumar Swaminathan * 8*8f23e9faSHans Rosenfeld * You can obtain a copy of the license at 9*8f23e9faSHans Rosenfeld * http://www.opensource.org/licenses/cddl1.txt. 1082527734SSukumar Swaminathan * See the License for the specific language governing permissions 1182527734SSukumar Swaminathan * and limitations under the License. 1282527734SSukumar Swaminathan * 1382527734SSukumar Swaminathan * When distributing Covered Code, include this CDDL HEADER in each 1482527734SSukumar Swaminathan * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1582527734SSukumar Swaminathan * If applicable, add the following below this CDDL HEADER, with the 1682527734SSukumar Swaminathan * fields enclosed by brackets "[]" replaced with your own identifying 1782527734SSukumar Swaminathan * information: Portions Copyright [yyyy] [name of copyright owner] 1882527734SSukumar Swaminathan * 1982527734SSukumar Swaminathan * CDDL HEADER END 2082527734SSukumar Swaminathan */ 2182527734SSukumar Swaminathan 2282527734SSukumar Swaminathan /* 23*8f23e9faSHans Rosenfeld * Copyright (c) 2004-2012 Emulex. All rights reserved. 2482527734SSukumar Swaminathan * Use is subject to license terms. 2582527734SSukumar Swaminathan */ 2682527734SSukumar Swaminathan 2782527734SSukumar Swaminathan #include <emlxs.h> 2882527734SSukumar Swaminathan 29*8f23e9faSHans Rosenfeld 3082527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */ 3182527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_SLI4_C); 3282527734SSukumar Swaminathan 33*8f23e9faSHans Rosenfeld static int emlxs_sli4_init_extents(emlxs_hba_t *hba, 34*8f23e9faSHans Rosenfeld MAILBOXQ *mbq); 35*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_read_status(emlxs_hba_t *hba); 36*8f23e9faSHans Rosenfeld 37*8f23e9faSHans Rosenfeld static int emlxs_init_bootstrap_mb(emlxs_hba_t *hba); 38*8f23e9faSHans Rosenfeld 39*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_read_sema(emlxs_hba_t *hba); 40*8f23e9faSHans Rosenfeld 41*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_read_mbdb(emlxs_hba_t *hba); 42*8f23e9faSHans Rosenfeld 43*8f23e9faSHans Rosenfeld static void emlxs_sli4_write_mbdb(emlxs_hba_t *hba, uint32_t value); 44*8f23e9faSHans Rosenfeld 45*8f23e9faSHans Rosenfeld static void emlxs_sli4_write_wqdb(emlxs_hba_t *hba, uint32_t value); 46*8f23e9faSHans Rosenfeld 47*8f23e9faSHans Rosenfeld static void emlxs_sli4_write_mqdb(emlxs_hba_t *hba, uint32_t value); 48*8f23e9faSHans Rosenfeld 49*8f23e9faSHans Rosenfeld static void emlxs_sli4_write_rqdb(emlxs_hba_t *hba, uint32_t value); 50*8f23e9faSHans Rosenfeld 51*8f23e9faSHans Rosenfeld static void emlxs_sli4_write_cqdb(emlxs_hba_t *hba, uint32_t value); 52*8f23e9faSHans Rosenfeld 5382527734SSukumar Swaminathan static int emlxs_sli4_create_queues(emlxs_hba_t *hba, 5482527734SSukumar Swaminathan MAILBOXQ *mbq); 5582527734SSukumar Swaminathan static int emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, 5682527734SSukumar Swaminathan MAILBOXQ *mbq); 5782527734SSukumar Swaminathan static int emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, 5882527734SSukumar Swaminathan MAILBOXQ *mbq); 5982527734SSukumar Swaminathan 60a9800bebSGarrett D'Amore static int emlxs_sli4_read_eq(emlxs_hba_t *hba, EQ_DESC_t *eq); 6182527734SSukumar Swaminathan 6282527734SSukumar Swaminathan static int emlxs_sli4_map_hdw(emlxs_hba_t *hba); 6382527734SSukumar Swaminathan 6482527734SSukumar Swaminathan static void emlxs_sli4_unmap_hdw(emlxs_hba_t *hba); 6582527734SSukumar Swaminathan 6682527734SSukumar Swaminathan static int32_t emlxs_sli4_online(emlxs_hba_t *hba); 6782527734SSukumar Swaminathan 68*8f23e9faSHans Rosenfeld static void emlxs_sli4_offline(emlxs_hba_t *hba, 69*8f23e9faSHans Rosenfeld uint32_t reset_requested); 7082527734SSukumar Swaminathan 7182527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, 7282527734SSukumar Swaminathan uint32_t skip_post, uint32_t quiesce); 7382527734SSukumar Swaminathan static void emlxs_sli4_hba_kill(emlxs_hba_t *hba); 7482527734SSukumar Swaminathan 7582527734SSukumar Swaminathan static uint32_t emlxs_sli4_hba_init(emlxs_hba_t *hba); 7682527734SSukumar Swaminathan 7782527734SSukumar Swaminathan static uint32_t emlxs_sli4_bde_setup(emlxs_port_t *port, 7882527734SSukumar Swaminathan emlxs_buf_t *sbp); 79a9800bebSGarrett D'Amore 8082527734SSukumar Swaminathan static void emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, 81a9800bebSGarrett D'Amore CHANNEL *cp, IOCBQ *iocb_cmd); 8282527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, 8382527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 8482527734SSukumar Swaminathan static uint32_t emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, 8582527734SSukumar Swaminathan MAILBOXQ *mbq, int32_t flg, uint32_t tmo); 8682527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 8782527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, 8882527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp, int channel); 89*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_fct_bde_setup(emlxs_port_t *port, 90*8f23e9faSHans Rosenfeld emlxs_buf_t *sbp); 9182527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 9282527734SSukumar Swaminathan 9382527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, 9482527734SSukumar Swaminathan emlxs_buf_t *sbp, int ring); 9582527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, 9682527734SSukumar Swaminathan emlxs_buf_t *sbp); 9782527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_els_iocb(emlxs_port_t *port, 9882527734SSukumar Swaminathan emlxs_buf_t *sbp); 9982527734SSukumar Swaminathan static uint32_t emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, 10082527734SSukumar Swaminathan emlxs_buf_t *sbp); 101*8f23e9faSHans Rosenfeld static void emlxs_sli4_poll_intr(emlxs_hba_t *hba); 10282527734SSukumar Swaminathan static int32_t emlxs_sli4_intx_intr(char *arg); 10382527734SSukumar Swaminathan 10482527734SSukumar Swaminathan #ifdef MSI_SUPPORT 10582527734SSukumar Swaminathan static uint32_t emlxs_sli4_msi_intr(char *arg1, char *arg2); 10682527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 10782527734SSukumar Swaminathan 10882527734SSukumar Swaminathan static void emlxs_sli4_resource_free(emlxs_hba_t *hba); 10982527734SSukumar Swaminathan 11082527734SSukumar Swaminathan static int emlxs_sli4_resource_alloc(emlxs_hba_t *hba); 111*8f23e9faSHans Rosenfeld extern void emlxs_sli4_zero_queue_stat(emlxs_hba_t *hba); 11282527734SSukumar Swaminathan 113*8f23e9faSHans Rosenfeld static XRIobj_t *emlxs_sli4_alloc_xri(emlxs_port_t *port, 114*8f23e9faSHans Rosenfeld emlxs_buf_t *sbp, RPIobj_t *rpip, 115*8f23e9faSHans Rosenfeld uint32_t type); 11682527734SSukumar Swaminathan static void emlxs_sli4_enable_intr(emlxs_hba_t *hba); 11782527734SSukumar Swaminathan 11882527734SSukumar Swaminathan static void emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att); 11982527734SSukumar Swaminathan 120*8f23e9faSHans Rosenfeld static void emlxs_sli4_timer(emlxs_hba_t *hba); 12182527734SSukumar Swaminathan 12282527734SSukumar Swaminathan static void emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba); 12382527734SSukumar Swaminathan 124a9800bebSGarrett D'Amore static void emlxs_sli4_poll_erratt(emlxs_hba_t *hba); 12582527734SSukumar Swaminathan 126*8f23e9faSHans Rosenfeld extern XRIobj_t *emlxs_sli4_reserve_xri(emlxs_port_t *port, 127*8f23e9faSHans Rosenfeld RPIobj_t *rpip, uint32_t type, uint16_t rx_id); 12882527734SSukumar Swaminathan static int emlxs_check_hdw_ready(emlxs_hba_t *); 12982527734SSukumar Swaminathan 130*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_reg_did(emlxs_port_t *port, 131*8f23e9faSHans Rosenfeld uint32_t did, SERV_PARM *param, 132*8f23e9faSHans Rosenfeld emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, 133*8f23e9faSHans Rosenfeld IOCBQ *iocbq); 134*8f23e9faSHans Rosenfeld 135*8f23e9faSHans Rosenfeld static uint32_t emlxs_sli4_unreg_node(emlxs_port_t *port, 136*8f23e9faSHans Rosenfeld emlxs_node_t *node, emlxs_buf_t *sbp, 137*8f23e9faSHans Rosenfeld fc_unsol_buf_t *ubp, IOCBQ *iocbq); 138*8f23e9faSHans Rosenfeld 139*8f23e9faSHans Rosenfeld static void emlxs_sli4_handle_fc_link_att(emlxs_hba_t *hba, 140*8f23e9faSHans Rosenfeld CQE_ASYNC_t *cqe); 141*8f23e9faSHans Rosenfeld static void emlxs_sli4_handle_fcoe_link_event(emlxs_hba_t *hba, 142*8f23e9faSHans Rosenfeld CQE_ASYNC_t *cqe); 143*8f23e9faSHans Rosenfeld 144*8f23e9faSHans Rosenfeld 145*8f23e9faSHans Rosenfeld static uint16_t emlxs_sli4_rqid_to_index(emlxs_hba_t *hba, 146*8f23e9faSHans Rosenfeld uint16_t rqid); 147*8f23e9faSHans Rosenfeld static uint16_t emlxs_sli4_wqid_to_index(emlxs_hba_t *hba, 148*8f23e9faSHans Rosenfeld uint16_t wqid); 149*8f23e9faSHans Rosenfeld static uint16_t emlxs_sli4_cqid_to_index(emlxs_hba_t *hba, 150*8f23e9faSHans Rosenfeld uint16_t cqid); 151a9800bebSGarrett D'Amore 15282527734SSukumar Swaminathan /* Define SLI4 API functions */ 15382527734SSukumar Swaminathan emlxs_sli_api_t emlxs_sli4_api = { 15482527734SSukumar Swaminathan emlxs_sli4_map_hdw, 15582527734SSukumar Swaminathan emlxs_sli4_unmap_hdw, 15682527734SSukumar Swaminathan emlxs_sli4_online, 15782527734SSukumar Swaminathan emlxs_sli4_offline, 15882527734SSukumar Swaminathan emlxs_sli4_hba_reset, 15982527734SSukumar Swaminathan emlxs_sli4_hba_kill, 16082527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd, 16182527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd, 16282527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 16382527734SSukumar Swaminathan emlxs_sli4_prep_fct_iocb, 16482527734SSukumar Swaminathan #else 16582527734SSukumar Swaminathan NULL, 16682527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 16782527734SSukumar Swaminathan emlxs_sli4_prep_fcp_iocb, 16882527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb, 16982527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb, 17082527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb, 17182527734SSukumar Swaminathan emlxs_sli4_poll_intr, 17282527734SSukumar Swaminathan emlxs_sli4_intx_intr, 17382527734SSukumar Swaminathan emlxs_sli4_msi_intr, 17482527734SSukumar Swaminathan emlxs_sli4_disable_intr, 17582527734SSukumar Swaminathan emlxs_sli4_timer, 176*8f23e9faSHans Rosenfeld emlxs_sli4_poll_erratt, 177*8f23e9faSHans Rosenfeld emlxs_sli4_reg_did, 178*8f23e9faSHans Rosenfeld emlxs_sli4_unreg_node 17982527734SSukumar Swaminathan }; 18082527734SSukumar Swaminathan 18182527734SSukumar Swaminathan 18282527734SSukumar Swaminathan /* ************************************************************************** */ 18382527734SSukumar Swaminathan 184*8f23e9faSHans Rosenfeld static void 185*8f23e9faSHans Rosenfeld emlxs_sli4_set_default_params(emlxs_hba_t *hba) 186*8f23e9faSHans Rosenfeld { 187*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 188*8f23e9faSHans Rosenfeld 189*8f23e9faSHans Rosenfeld bzero((char *)&hba->sli.sli4.param, sizeof (sli_params_t)); 190*8f23e9faSHans Rosenfeld 191*8f23e9faSHans Rosenfeld hba->sli.sli4.param.ProtocolType = 0x3; /* FC/FCoE */ 192*8f23e9faSHans Rosenfeld 193*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SliHint2 = 0; 194*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SliHint1 = 0; 195*8f23e9faSHans Rosenfeld hba->sli.sli4.param.IfType = 0; 196*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SliFamily = 0; 197*8f23e9faSHans Rosenfeld hba->sli.sli4.param.Revision = 0x4; /* SLI4 */ 198*8f23e9faSHans Rosenfeld hba->sli.sli4.param.FT = 0; 199*8f23e9faSHans Rosenfeld 200*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EqeCntMethod = 0x1; /* Bit pattern */ 201*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EqPageSize = 0x1; /* 4096 */ 202*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EqeSize = 0x1; /* 4 byte */ 203*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EqPageCnt = 8; 204*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EqeCntMask = 0x1F; /* 256-4096 elements */ 205*8f23e9faSHans Rosenfeld 206*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CqeCntMethod = 0x1; /* Bit pattern */ 207*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CqPageSize = 0x1; /* 4096 */ 208*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CQV = 0; 209*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CqeSize = 0x3; /* 16 byte */ 210*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CqPageCnt = 4; 211*8f23e9faSHans Rosenfeld hba->sli.sli4.param.CqeCntMask = 0x70; /* 256-1024 elements */ 212*8f23e9faSHans Rosenfeld 213*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MqeCntMethod = 0x1; /* Bit pattern */ 214*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MqPageSize = 0x1; /* 4096 */ 215*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MQV = 0; 216*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MqPageCnt = 8; 217*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MqeCntMask = 0x0F; /* 16-128 elements */ 218*8f23e9faSHans Rosenfeld 219*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WqeCntMethod = 0; /* Page Count */ 220*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WqPageSize = 0x1; /* 4096 */ 221*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WQV = 0; 222*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WqeSize = 0x5; /* 64 byte */ 223*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WqPageCnt = 4; 224*8f23e9faSHans Rosenfeld hba->sli.sli4.param.WqeCntMask = 0x10; /* 256 elements */ 225*8f23e9faSHans Rosenfeld 226*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqeCntMethod = 0; /* Page Count */ 227*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqPageSize = 0x1; /* 4096 */ 228*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RQV = 0; 229*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqeSize = 0x2; /* 8 byte */ 230*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqPageCnt = 8; 231*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqDbWin = 1; 232*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RqeCntMask = 0x100; /* 4096 elements */ 233*8f23e9faSHans Rosenfeld 234*8f23e9faSHans Rosenfeld hba->sli.sli4.param.Loopback = 0xf; /* unsupported */ 235*8f23e9faSHans Rosenfeld hba->sli.sli4.param.PHWQ = 0; 236*8f23e9faSHans Rosenfeld hba->sli.sli4.param.PHON = 0; 237*8f23e9faSHans Rosenfeld hba->sli.sli4.param.TRIR = 0; 238*8f23e9faSHans Rosenfeld hba->sli.sli4.param.TRTY = 0; 239*8f23e9faSHans Rosenfeld hba->sli.sli4.param.TCCA = 0; 240*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MWQE = 0; 241*8f23e9faSHans Rosenfeld hba->sli.sli4.param.ASSI = 0; 242*8f23e9faSHans Rosenfeld hba->sli.sli4.param.TERP = 0; 243*8f23e9faSHans Rosenfeld hba->sli.sli4.param.TGT = 0; 244*8f23e9faSHans Rosenfeld hba->sli.sli4.param.AREG = 0; 245*8f23e9faSHans Rosenfeld hba->sli.sli4.param.FBRR = 0; 246*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SGLR = 1; 247*8f23e9faSHans Rosenfeld hba->sli.sli4.param.HDRR = 1; 248*8f23e9faSHans Rosenfeld hba->sli.sli4.param.EXT = 0; 249*8f23e9faSHans Rosenfeld hba->sli.sli4.param.FCOE = 1; 250*8f23e9faSHans Rosenfeld 251*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SgeLength = (64 * 1024); 252*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SglAlign = 0x7 /* 4096 */; 253*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SglPageSize = 0x1; /* 4096 */ 254*8f23e9faSHans Rosenfeld hba->sli.sli4.param.SglPageCnt = 2; 255*8f23e9faSHans Rosenfeld 256*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MinRqSize = 128; 257*8f23e9faSHans Rosenfeld hba->sli.sli4.param.MaxRqSize = 2048; 258*8f23e9faSHans Rosenfeld 259*8f23e9faSHans Rosenfeld hba->sli.sli4.param.RPIMax = 0x3ff; 260*8f23e9faSHans Rosenfeld hba->sli.sli4.param.XRIMax = 0x3ff; 261*8f23e9faSHans Rosenfeld hba->sli.sli4.param.VFIMax = 0xff; 262*8f23e9faSHans Rosenfeld hba->sli.sli4.param.VPIMax = 0xff; 263*8f23e9faSHans Rosenfeld 264*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 265*8f23e9faSHans Rosenfeld "Default SLI4 parameters set."); 266*8f23e9faSHans Rosenfeld 267*8f23e9faSHans Rosenfeld } /* emlxs_sli4_set_default_params() */ 268*8f23e9faSHans Rosenfeld 26982527734SSukumar Swaminathan 27082527734SSukumar Swaminathan /* 27182527734SSukumar Swaminathan * emlxs_sli4_online() 27282527734SSukumar Swaminathan * 27382527734SSukumar Swaminathan * This routine will start initialization of the SLI4 HBA. 27482527734SSukumar Swaminathan */ 27582527734SSukumar Swaminathan static int32_t 27682527734SSukumar Swaminathan emlxs_sli4_online(emlxs_hba_t *hba) 27782527734SSukumar Swaminathan { 27882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 27982527734SSukumar Swaminathan emlxs_config_t *cfg; 28082527734SSukumar Swaminathan emlxs_vpd_t *vpd; 28182527734SSukumar Swaminathan MAILBOXQ *mbq = NULL; 28282527734SSukumar Swaminathan MAILBOX4 *mb = NULL; 28382527734SSukumar Swaminathan MATCHMAP *mp = NULL; 28482527734SSukumar Swaminathan uint32_t i; 28582527734SSukumar Swaminathan uint32_t j; 28682527734SSukumar Swaminathan uint32_t rval = 0; 28782527734SSukumar Swaminathan uint8_t *vpd_data; 28882527734SSukumar Swaminathan uint32_t sli_mode; 28982527734SSukumar Swaminathan uint8_t *outptr; 29082527734SSukumar Swaminathan uint32_t status; 29182527734SSukumar Swaminathan uint32_t fw_check; 2926a573d82SSukumar Swaminathan uint32_t kern_update = 0; 29382527734SSukumar Swaminathan emlxs_firmware_t hba_fw; 29482527734SSukumar Swaminathan emlxs_firmware_t *fw; 295a9800bebSGarrett D'Amore uint16_t ssvid; 296*8f23e9faSHans Rosenfeld char buf[64]; 29782527734SSukumar Swaminathan 29882527734SSukumar Swaminathan cfg = &CFG; 29982527734SSukumar Swaminathan vpd = &VPD; 30082527734SSukumar Swaminathan 30182527734SSukumar Swaminathan sli_mode = EMLXS_HBA_SLI4_MODE; 30282527734SSukumar Swaminathan hba->sli_mode = sli_mode; 30382527734SSukumar Swaminathan 30482527734SSukumar Swaminathan /* Set the fw_check flag */ 30582527734SSukumar Swaminathan fw_check = cfg[CFG_FW_CHECK].current; 30682527734SSukumar Swaminathan 3076a573d82SSukumar Swaminathan if ((fw_check & 0x04) || 3086a573d82SSukumar Swaminathan (hba->fw_flag & FW_UPDATE_KERNEL)) { 3096a573d82SSukumar Swaminathan kern_update = 1; 3106a573d82SSukumar Swaminathan } 3116a573d82SSukumar Swaminathan 31282527734SSukumar Swaminathan hba->mbox_queue_flag = 0; 31382527734SSukumar Swaminathan hba->fc_edtov = FF_DEF_EDTOV; 31482527734SSukumar Swaminathan hba->fc_ratov = FF_DEF_RATOV; 31582527734SSukumar Swaminathan hba->fc_altov = FF_DEF_ALTOV; 31682527734SSukumar Swaminathan hba->fc_arbtov = FF_DEF_ARBTOV; 31782527734SSukumar Swaminathan 31882527734SSukumar Swaminathan /* Networking not supported */ 31982527734SSukumar Swaminathan if (cfg[CFG_NETWORK_ON].current) { 32082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 321*8f23e9faSHans Rosenfeld "Networking is not supported in SLI4, turning it off"); 32282527734SSukumar Swaminathan cfg[CFG_NETWORK_ON].current = 0; 32382527734SSukumar Swaminathan } 32482527734SSukumar Swaminathan 32582527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 32682527734SSukumar Swaminathan if (hba->chan_count > MAX_CHANNEL) { 32782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 32882527734SSukumar Swaminathan "Max channels exceeded, dropping num-wq from %d to 1", 32982527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current); 33082527734SSukumar Swaminathan cfg[CFG_NUM_WQ].current = 1; 33182527734SSukumar Swaminathan hba->chan_count = hba->intr_count * cfg[CFG_NUM_WQ].current; 33282527734SSukumar Swaminathan } 33382527734SSukumar Swaminathan hba->channel_fcp = 0; /* First channel */ 33482527734SSukumar Swaminathan 33582527734SSukumar Swaminathan /* Default channel for everything else is the last channel */ 33682527734SSukumar Swaminathan hba->channel_ip = hba->chan_count - 1; 33782527734SSukumar Swaminathan hba->channel_els = hba->chan_count - 1; 33882527734SSukumar Swaminathan hba->channel_ct = hba->chan_count - 1; 33982527734SSukumar Swaminathan 34082527734SSukumar Swaminathan hba->fc_iotag = 1; 34182527734SSukumar Swaminathan hba->io_count = 0; 34282527734SSukumar Swaminathan hba->channel_tx_count = 0; 34382527734SSukumar Swaminathan 34482527734SSukumar Swaminathan /* Initialize the local dump region buffer */ 34582527734SSukumar Swaminathan bzero(&hba->sli.sli4.dump_region, sizeof (MBUF_INFO)); 34682527734SSukumar Swaminathan hba->sli.sli4.dump_region.size = EMLXS_DUMP_REGION_SIZE; 34782527734SSukumar Swaminathan hba->sli.sli4.dump_region.flags = FC_MBUF_DMA | FC_MBUF_SNGLSG 34882527734SSukumar Swaminathan | FC_MBUF_DMA32; 34982527734SSukumar Swaminathan hba->sli.sli4.dump_region.align = ddi_ptob(hba->dip, 1L); 35082527734SSukumar Swaminathan 35182527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, &hba->sli.sli4.dump_region); 35282527734SSukumar Swaminathan 35382527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt == NULL) { 35482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 35582527734SSukumar Swaminathan "Unable to allocate dump region buffer."); 35682527734SSukumar Swaminathan 35782527734SSukumar Swaminathan return (ENOMEM); 35882527734SSukumar Swaminathan } 35982527734SSukumar Swaminathan 36082527734SSukumar Swaminathan /* 36182527734SSukumar Swaminathan * Get a buffer which will be used repeatedly for mailbox commands 36282527734SSukumar Swaminathan */ 36382527734SSukumar Swaminathan mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP); 36482527734SSukumar Swaminathan 36582527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 36682527734SSukumar Swaminathan 36782527734SSukumar Swaminathan reset: 36882527734SSukumar Swaminathan /* Reset & Initialize the adapter */ 36982527734SSukumar Swaminathan if (emlxs_sli4_hba_init(hba)) { 37082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 37182527734SSukumar Swaminathan "Unable to init hba."); 37282527734SSukumar Swaminathan 37382527734SSukumar Swaminathan rval = EIO; 37482527734SSukumar Swaminathan goto failed1; 37582527734SSukumar Swaminathan } 37682527734SSukumar Swaminathan 37782527734SSukumar Swaminathan #ifdef FMA_SUPPORT 37882527734SSukumar Swaminathan /* Access handle validation */ 379*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 380*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 381*8f23e9faSHans Rosenfeld if ((emlxs_fm_check_acc_handle(hba, 382*8f23e9faSHans Rosenfeld hba->pci_acc_handle) != DDI_FM_OK) || 383*8f23e9faSHans Rosenfeld (emlxs_fm_check_acc_handle(hba, 384*8f23e9faSHans Rosenfeld hba->sli.sli4.bar0_acc_handle) != DDI_FM_OK)) { 385*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 386*8f23e9faSHans Rosenfeld &emlxs_invalid_access_handle_msg, NULL); 38782527734SSukumar Swaminathan 388*8f23e9faSHans Rosenfeld rval = EIO; 389*8f23e9faSHans Rosenfeld goto failed1; 390*8f23e9faSHans Rosenfeld } 391*8f23e9faSHans Rosenfeld break; 392*8f23e9faSHans Rosenfeld 393*8f23e9faSHans Rosenfeld default : 394*8f23e9faSHans Rosenfeld if ((emlxs_fm_check_acc_handle(hba, 395*8f23e9faSHans Rosenfeld hba->pci_acc_handle) != DDI_FM_OK) || 396*8f23e9faSHans Rosenfeld (emlxs_fm_check_acc_handle(hba, 397*8f23e9faSHans Rosenfeld hba->sli.sli4.bar1_acc_handle) != DDI_FM_OK) || 398*8f23e9faSHans Rosenfeld (emlxs_fm_check_acc_handle(hba, 399*8f23e9faSHans Rosenfeld hba->sli.sli4.bar2_acc_handle) != DDI_FM_OK)) { 400*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 401*8f23e9faSHans Rosenfeld &emlxs_invalid_access_handle_msg, NULL); 402*8f23e9faSHans Rosenfeld 403*8f23e9faSHans Rosenfeld rval = EIO; 404*8f23e9faSHans Rosenfeld goto failed1; 405*8f23e9faSHans Rosenfeld } 406*8f23e9faSHans Rosenfeld break; 40782527734SSukumar Swaminathan } 40882527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 40982527734SSukumar Swaminathan 41082527734SSukumar Swaminathan /* 41182527734SSukumar Swaminathan * Setup and issue mailbox READ REV command 41282527734SSukumar Swaminathan */ 41382527734SSukumar Swaminathan vpd->opFwRev = 0; 41482527734SSukumar Swaminathan vpd->postKernRev = 0; 41582527734SSukumar Swaminathan vpd->sli1FwRev = 0; 41682527734SSukumar Swaminathan vpd->sli2FwRev = 0; 41782527734SSukumar Swaminathan vpd->sli3FwRev = 0; 41882527734SSukumar Swaminathan vpd->sli4FwRev = 0; 41982527734SSukumar Swaminathan 42082527734SSukumar Swaminathan vpd->postKernName[0] = 0; 42182527734SSukumar Swaminathan vpd->opFwName[0] = 0; 42282527734SSukumar Swaminathan vpd->sli1FwName[0] = 0; 42382527734SSukumar Swaminathan vpd->sli2FwName[0] = 0; 42482527734SSukumar Swaminathan vpd->sli3FwName[0] = 0; 42582527734SSukumar Swaminathan vpd->sli4FwName[0] = 0; 42682527734SSukumar Swaminathan 42782527734SSukumar Swaminathan vpd->opFwLabel[0] = 0; 42882527734SSukumar Swaminathan vpd->sli1FwLabel[0] = 0; 42982527734SSukumar Swaminathan vpd->sli2FwLabel[0] = 0; 43082527734SSukumar Swaminathan vpd->sli3FwLabel[0] = 0; 43182527734SSukumar Swaminathan vpd->sli4FwLabel[0] = 0; 43282527734SSukumar Swaminathan 43382527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_REV); 43482527734SSukumar Swaminathan 435*8f23e9faSHans Rosenfeld emlxs_mb_get_sli4_params(hba, mbq); 436*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 437*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 438*8f23e9faSHans Rosenfeld "Unable to read parameters. Mailbox cmd=%x status=%x", 439*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus); 440*8f23e9faSHans Rosenfeld 441*8f23e9faSHans Rosenfeld /* Set param defaults */ 442*8f23e9faSHans Rosenfeld emlxs_sli4_set_default_params(hba); 443*8f23e9faSHans Rosenfeld 444*8f23e9faSHans Rosenfeld } else { 445*8f23e9faSHans Rosenfeld /* Save parameters */ 446*8f23e9faSHans Rosenfeld bcopy((char *)&mb->un.varSLIConfig.payload, 447*8f23e9faSHans Rosenfeld (char *)&hba->sli.sli4.param, sizeof (sli_params_t)); 448*8f23e9faSHans Rosenfeld 449*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "SLI_PARMS", 450*8f23e9faSHans Rosenfeld (uint32_t *)&hba->sli.sli4.param, 451*8f23e9faSHans Rosenfeld sizeof (sli_params_t), 0); 452*8f23e9faSHans Rosenfeld } 453*8f23e9faSHans Rosenfeld 454*8f23e9faSHans Rosenfeld /* Reuse mbq from previous mbox */ 455*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 456*8f23e9faSHans Rosenfeld 457*8f23e9faSHans Rosenfeld emlxs_mb_get_port_name(hba, mbq); 458*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 459*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 460*8f23e9faSHans Rosenfeld "Unable to get port names. Mailbox cmd=%x status=%x", 461*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus); 462*8f23e9faSHans Rosenfeld 463*8f23e9faSHans Rosenfeld bzero(hba->sli.sli4.port_name, 464*8f23e9faSHans Rosenfeld sizeof (hba->sli.sli4.port_name)); 465*8f23e9faSHans Rosenfeld } else { 466*8f23e9faSHans Rosenfeld /* Save port names */ 467*8f23e9faSHans Rosenfeld bcopy((char *)&mb->un.varSLIConfig.payload, 468*8f23e9faSHans Rosenfeld (char *)&hba->sli.sli4.port_name, 469*8f23e9faSHans Rosenfeld sizeof (hba->sli.sli4.port_name)); 470*8f23e9faSHans Rosenfeld } 471*8f23e9faSHans Rosenfeld 472*8f23e9faSHans Rosenfeld /* Reuse mbq from previous mbox */ 473*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 474*8f23e9faSHans Rosenfeld 47582527734SSukumar Swaminathan emlxs_mb_read_rev(hba, mbq, 0); 47682527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 47782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 47882527734SSukumar Swaminathan "Unable to read rev. Mailbox cmd=%x status=%x", 47982527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 48082527734SSukumar Swaminathan 48182527734SSukumar Swaminathan rval = EIO; 48282527734SSukumar Swaminathan goto failed1; 48382527734SSukumar Swaminathan 48482527734SSukumar Swaminathan } 48582527734SSukumar Swaminathan 486*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "RD_REV", (uint32_t *)mb, 18, 0); 48782527734SSukumar Swaminathan if (mb->un.varRdRev4.sliLevel != 4) { 48882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 48982527734SSukumar Swaminathan "Invalid read rev Version for SLI4: 0x%x", 49082527734SSukumar Swaminathan mb->un.varRdRev4.sliLevel); 49182527734SSukumar Swaminathan 49282527734SSukumar Swaminathan rval = EIO; 49382527734SSukumar Swaminathan goto failed1; 49482527734SSukumar Swaminathan } 49582527734SSukumar Swaminathan 49682527734SSukumar Swaminathan switch (mb->un.varRdRev4.dcbxMode) { 49782527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CIN: /* Mapped to nonFIP mode */ 49882527734SSukumar Swaminathan hba->flag &= ~FC_FIP_SUPPORTED; 49982527734SSukumar Swaminathan break; 50082527734SSukumar Swaminathan 50182527734SSukumar Swaminathan case EMLXS_DCBX_MODE_CEE: /* Mapped to FIP mode */ 50282527734SSukumar Swaminathan hba->flag |= FC_FIP_SUPPORTED; 50382527734SSukumar Swaminathan break; 50482527734SSukumar Swaminathan 50582527734SSukumar Swaminathan default: 50682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 50782527734SSukumar Swaminathan "Invalid read rev dcbx mode for SLI4: 0x%x", 50882527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 50982527734SSukumar Swaminathan 51082527734SSukumar Swaminathan rval = EIO; 51182527734SSukumar Swaminathan goto failed1; 51282527734SSukumar Swaminathan } 51382527734SSukumar Swaminathan 514*8f23e9faSHans Rosenfeld /* Set FC/FCoE mode */ 515*8f23e9faSHans Rosenfeld if (mb->un.varRdRev4.FCoE) { 516*8f23e9faSHans Rosenfeld hba->sli.sli4.flag |= EMLXS_SLI4_FCOE_MODE; 517*8f23e9faSHans Rosenfeld } else { 518*8f23e9faSHans Rosenfeld hba->sli.sli4.flag &= ~EMLXS_SLI4_FCOE_MODE; 519*8f23e9faSHans Rosenfeld } 52082527734SSukumar Swaminathan 52182527734SSukumar Swaminathan /* Save information as VPD data */ 52282527734SSukumar Swaminathan vpd->rBit = 1; 52382527734SSukumar Swaminathan 52482527734SSukumar Swaminathan vpd->sli4FwRev = (mb->un.varRdRev4.ULPFwId); 52582527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->sli4FwName, 16); 52682527734SSukumar Swaminathan 52782527734SSukumar Swaminathan vpd->opFwRev = (mb->un.varRdRev4.ULPFwId); 52882527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ULPFwName, vpd->opFwName, 16); 52982527734SSukumar Swaminathan 53082527734SSukumar Swaminathan vpd->postKernRev = (mb->un.varRdRev4.ARMFwId); 53182527734SSukumar Swaminathan bcopy((char *)mb->un.varRdRev4.ARMFwName, vpd->postKernName, 16); 53282527734SSukumar Swaminathan 533*8f23e9faSHans Rosenfeld vpd->biuRev = mb->un.varRdRev4.HwRev1; 53482527734SSukumar Swaminathan vpd->fcphHigh = mb->un.varRdRev4.fcphHigh; 53582527734SSukumar Swaminathan vpd->fcphLow = mb->un.varRdRev4.fcphLow; 53682527734SSukumar Swaminathan vpd->feaLevelHigh = mb->un.varRdRev4.feaLevelHigh; 53782527734SSukumar Swaminathan vpd->feaLevelLow = mb->un.varRdRev4.feaLevelLow; 53882527734SSukumar Swaminathan 53982527734SSukumar Swaminathan /* Decode FW labels */ 540*8f23e9faSHans Rosenfeld if (hba->model_info.chip == EMLXS_LANCER_CHIP) { 541*8f23e9faSHans Rosenfeld bcopy(vpd->postKernName, vpd->sli4FwName, 16); 542*8f23e9faSHans Rosenfeld } 543*8f23e9faSHans Rosenfeld emlxs_decode_label(vpd->sli4FwName, vpd->sli4FwName, 0, 544*8f23e9faSHans Rosenfeld sizeof (vpd->sli4FwName)); 545*8f23e9faSHans Rosenfeld emlxs_decode_label(vpd->opFwName, vpd->opFwName, 0, 546*8f23e9faSHans Rosenfeld sizeof (vpd->opFwName)); 547*8f23e9faSHans Rosenfeld emlxs_decode_label(vpd->postKernName, vpd->postKernName, 0, 548*8f23e9faSHans Rosenfeld sizeof (vpd->postKernName)); 54982527734SSukumar Swaminathan 550a9800bebSGarrett D'Amore if (hba->model_info.chip == EMLXS_BE2_CHIP) { 551*8f23e9faSHans Rosenfeld (void) strlcpy(vpd->sli4FwLabel, "be2.ufi", 552*8f23e9faSHans Rosenfeld sizeof (vpd->sli4FwLabel)); 553a9800bebSGarrett D'Amore } else if (hba->model_info.chip == EMLXS_BE3_CHIP) { 554*8f23e9faSHans Rosenfeld (void) strlcpy(vpd->sli4FwLabel, "be3.ufi", 555*8f23e9faSHans Rosenfeld sizeof (vpd->sli4FwLabel)); 556*8f23e9faSHans Rosenfeld } else if (hba->model_info.chip == EMLXS_LANCER_CHIP) { 557*8f23e9faSHans Rosenfeld (void) strlcpy(vpd->sli4FwLabel, "xe201.grp", 558*8f23e9faSHans Rosenfeld sizeof (vpd->sli4FwLabel)); 55982527734SSukumar Swaminathan } else { 560*8f23e9faSHans Rosenfeld (void) strlcpy(vpd->sli4FwLabel, "sli4.fw", 561*8f23e9faSHans Rosenfeld sizeof (vpd->sli4FwLabel)); 56282527734SSukumar Swaminathan } 56382527734SSukumar Swaminathan 564*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 56582527734SSukumar Swaminathan "VPD ULP:%08x %s ARM:%08x %s f:%d %d %d %d : dcbx %d", 56682527734SSukumar Swaminathan vpd->opFwRev, vpd->opFwName, vpd->postKernRev, vpd->postKernName, 56782527734SSukumar Swaminathan vpd->fcphHigh, vpd->fcphLow, vpd->feaLevelHigh, vpd->feaLevelLow, 56882527734SSukumar Swaminathan mb->un.varRdRev4.dcbxMode); 56982527734SSukumar Swaminathan 57082527734SSukumar Swaminathan /* No key information is needed for SLI4 products */ 57182527734SSukumar Swaminathan 57282527734SSukumar Swaminathan /* Get adapter VPD information */ 57382527734SSukumar Swaminathan vpd->port_index = (uint32_t)-1; 57482527734SSukumar Swaminathan 57582527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 57682527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 57782527734SSukumar Swaminathan 57882527734SSukumar Swaminathan emlxs_mb_dump_vpd(hba, mbq, 0); 57982527734SSukumar Swaminathan vpd_data = hba->sli.sli4.dump_region.virt; 58082527734SSukumar Swaminathan 58182527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 58282527734SSukumar Swaminathan MBX_SUCCESS) { 58382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 58482527734SSukumar Swaminathan "No VPD found. status=%x", mb->mbxStatus); 58582527734SSukumar Swaminathan } else { 58682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 58782527734SSukumar Swaminathan &emlxs_init_debug_msg, 58882527734SSukumar Swaminathan "VPD dumped. rsp_cnt=%d status=%x", 58982527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 59082527734SSukumar Swaminathan 59182527734SSukumar Swaminathan if (mb->un.varDmp4.rsp_cnt) { 59282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.dump_region.dma_handle, 59382527734SSukumar Swaminathan 0, mb->un.varDmp4.rsp_cnt, DDI_DMA_SYNC_FORKERNEL); 59482527734SSukumar Swaminathan 595b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 596b3660a96SSukumar Swaminathan if (hba->sli.sli4.dump_region.dma_handle) { 597b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 598b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region.dma_handle) 599b3660a96SSukumar Swaminathan != DDI_FM_OK) { 600b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 601b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 602*8f23e9faSHans Rosenfeld "sli4_online: hdl=%p", 603b3660a96SSukumar Swaminathan hba->sli.sli4.dump_region. 604b3660a96SSukumar Swaminathan dma_handle); 605b3660a96SSukumar Swaminathan rval = EIO; 606b3660a96SSukumar Swaminathan goto failed1; 607b3660a96SSukumar Swaminathan } 608b3660a96SSukumar Swaminathan } 609b3660a96SSukumar Swaminathan #endif /* FMA_SUPPORT */ 610b3660a96SSukumar Swaminathan 61182527734SSukumar Swaminathan } 61282527734SSukumar Swaminathan } 61382527734SSukumar Swaminathan 61482527734SSukumar Swaminathan if (vpd_data[0]) { 61582527734SSukumar Swaminathan (void) emlxs_parse_vpd(hba, (uint8_t *)vpd_data, 61682527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt); 61782527734SSukumar Swaminathan 61882527734SSukumar Swaminathan /* 61982527734SSukumar Swaminathan * If there is a VPD part number, and it does not 62082527734SSukumar Swaminathan * match the current default HBA model info, 62182527734SSukumar Swaminathan * replace the default data with an entry that 62282527734SSukumar Swaminathan * does match. 62382527734SSukumar Swaminathan * 62482527734SSukumar Swaminathan * After emlxs_parse_vpd model holds the VPD value 62582527734SSukumar Swaminathan * for V2 and part_num hold the value for PN. These 62682527734SSukumar Swaminathan * 2 values are NOT necessarily the same. 62782527734SSukumar Swaminathan */ 62882527734SSukumar Swaminathan 62982527734SSukumar Swaminathan rval = 0; 63082527734SSukumar Swaminathan if ((vpd->model[0] != 0) && 63182527734SSukumar Swaminathan (strcmp(&vpd->model[0], hba->model_info.model) != 0)) { 63282527734SSukumar Swaminathan 63382527734SSukumar Swaminathan /* First scan for a V2 match */ 63482527734SSukumar Swaminathan 63582527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 63682527734SSukumar Swaminathan if (strcmp(&vpd->model[0], 63782527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 63882527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 63982527734SSukumar Swaminathan &hba->model_info, 64082527734SSukumar Swaminathan sizeof (emlxs_model_t)); 64182527734SSukumar Swaminathan rval = 1; 64282527734SSukumar Swaminathan break; 64382527734SSukumar Swaminathan } 64482527734SSukumar Swaminathan } 64582527734SSukumar Swaminathan } 64682527734SSukumar Swaminathan 64782527734SSukumar Swaminathan if (!rval && (vpd->part_num[0] != 0) && 64882527734SSukumar Swaminathan (strcmp(&vpd->part_num[0], hba->model_info.model) != 0)) { 64982527734SSukumar Swaminathan 65082527734SSukumar Swaminathan /* Next scan for a PN match */ 65182527734SSukumar Swaminathan 65282527734SSukumar Swaminathan for (i = 1; i < emlxs_pci_model_count; i++) { 65382527734SSukumar Swaminathan if (strcmp(&vpd->part_num[0], 65482527734SSukumar Swaminathan emlxs_pci_model[i].model) == 0) { 65582527734SSukumar Swaminathan bcopy(&emlxs_pci_model[i], 65682527734SSukumar Swaminathan &hba->model_info, 65782527734SSukumar Swaminathan sizeof (emlxs_model_t)); 65882527734SSukumar Swaminathan break; 65982527734SSukumar Swaminathan } 66082527734SSukumar Swaminathan } 66182527734SSukumar Swaminathan } 66282527734SSukumar Swaminathan 663a9800bebSGarrett D'Amore /* HP CNA port indices start at 1 instead of 0 */ 664*8f23e9faSHans Rosenfeld if (hba->model_info.chip & EMLXS_BE_CHIPS) { 665a9800bebSGarrett D'Amore ssvid = ddi_get16(hba->pci_acc_handle, 666a9800bebSGarrett D'Amore (uint16_t *)(hba->pci_addr + PCI_SSVID_REGISTER)); 667a9800bebSGarrett D'Amore 668a9800bebSGarrett D'Amore if ((ssvid == PCI_SSVID_HP) && (vpd->port_index > 0)) { 669a9800bebSGarrett D'Amore vpd->port_index--; 670a9800bebSGarrett D'Amore } 671a9800bebSGarrett D'Amore } 672a9800bebSGarrett D'Amore 67382527734SSukumar Swaminathan /* 67482527734SSukumar Swaminathan * Now lets update hba->model_info with the real 67582527734SSukumar Swaminathan * VPD data, if any. 67682527734SSukumar Swaminathan */ 67782527734SSukumar Swaminathan 67882527734SSukumar Swaminathan /* 67982527734SSukumar Swaminathan * Replace the default model description with vpd data 68082527734SSukumar Swaminathan */ 68182527734SSukumar Swaminathan if (vpd->model_desc[0] != 0) { 682*8f23e9faSHans Rosenfeld (void) strncpy(hba->model_info.model_desc, 683*8f23e9faSHans Rosenfeld vpd->model_desc, 684*8f23e9faSHans Rosenfeld (sizeof (hba->model_info.model_desc)-1)); 68582527734SSukumar Swaminathan } 68682527734SSukumar Swaminathan 68782527734SSukumar Swaminathan /* Replace the default model with vpd data */ 68882527734SSukumar Swaminathan if (vpd->model[0] != 0) { 689*8f23e9faSHans Rosenfeld (void) strncpy(hba->model_info.model, vpd->model, 690*8f23e9faSHans Rosenfeld (sizeof (hba->model_info.model)-1)); 69182527734SSukumar Swaminathan } 69282527734SSukumar Swaminathan 69382527734SSukumar Swaminathan /* Replace the default program types with vpd data */ 69482527734SSukumar Swaminathan if (vpd->prog_types[0] != 0) { 69582527734SSukumar Swaminathan emlxs_parse_prog_types(hba, vpd->prog_types); 69682527734SSukumar Swaminathan } 69782527734SSukumar Swaminathan } 69882527734SSukumar Swaminathan 69982527734SSukumar Swaminathan /* 70082527734SSukumar Swaminathan * Since the adapter model may have changed with the vpd data 70182527734SSukumar Swaminathan * lets double check if adapter is not supported 70282527734SSukumar Swaminathan */ 70382527734SSukumar Swaminathan if (hba->model_info.flags & EMLXS_NOT_SUPPORTED) { 70482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 70582527734SSukumar Swaminathan "Unsupported adapter found. " 70682527734SSukumar Swaminathan "Id:%d Device id:0x%x SSDID:0x%x Model:%s", 70782527734SSukumar Swaminathan hba->model_info.id, hba->model_info.device_id, 70882527734SSukumar Swaminathan hba->model_info.ssdid, hba->model_info.model); 70982527734SSukumar Swaminathan 71082527734SSukumar Swaminathan rval = EIO; 71182527734SSukumar Swaminathan goto failed1; 71282527734SSukumar Swaminathan } 71382527734SSukumar Swaminathan 714*8f23e9faSHans Rosenfeld (void) strncpy(vpd->boot_version, vpd->sli4FwName, 715*8f23e9faSHans Rosenfeld (sizeof (vpd->boot_version)-1)); 71682527734SSukumar Swaminathan 71782527734SSukumar Swaminathan /* Get fcode version property */ 71882527734SSukumar Swaminathan emlxs_get_fcode_version(hba); 71982527734SSukumar Swaminathan 72082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 72182527734SSukumar Swaminathan "Firmware: kern=%08x stub=%08x sli1=%08x", vpd->postKernRev, 72282527734SSukumar Swaminathan vpd->opFwRev, vpd->sli1FwRev); 72382527734SSukumar Swaminathan 72482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 72582527734SSukumar Swaminathan "Firmware: sli2=%08x sli3=%08x sli4=%08x fl=%x", vpd->sli2FwRev, 72682527734SSukumar Swaminathan vpd->sli3FwRev, vpd->sli4FwRev, vpd->feaLevelHigh); 72782527734SSukumar Swaminathan 72882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 72982527734SSukumar Swaminathan "BIOS: boot=%s fcode=%s", vpd->boot_version, vpd->fcode_version); 73082527734SSukumar Swaminathan 73182527734SSukumar Swaminathan /* 73282527734SSukumar Swaminathan * If firmware checking is enabled and the adapter model indicates 73382527734SSukumar Swaminathan * a firmware image, then perform firmware version check 73482527734SSukumar Swaminathan */ 7356a573d82SSukumar Swaminathan hba->fw_flag = 0; 7366a573d82SSukumar Swaminathan hba->fw_timer = 0; 7376a573d82SSukumar Swaminathan 738*8f23e9faSHans Rosenfeld if (((fw_check & 0x1) && 739*8f23e9faSHans Rosenfeld (hba->model_info.flags & EMLXS_ORACLE_BRANDED) && 740*8f23e9faSHans Rosenfeld hba->model_info.fwid) || 741*8f23e9faSHans Rosenfeld ((fw_check & 0x2) && hba->model_info.fwid)) { 74282527734SSukumar Swaminathan 74382527734SSukumar Swaminathan /* Find firmware image indicated by adapter model */ 74482527734SSukumar Swaminathan fw = NULL; 74582527734SSukumar Swaminathan for (i = 0; i < emlxs_fw_count; i++) { 74682527734SSukumar Swaminathan if (emlxs_fw_table[i].id == hba->model_info.fwid) { 74782527734SSukumar Swaminathan fw = &emlxs_fw_table[i]; 74882527734SSukumar Swaminathan break; 74982527734SSukumar Swaminathan } 75082527734SSukumar Swaminathan } 75182527734SSukumar Swaminathan 75282527734SSukumar Swaminathan /* 75382527734SSukumar Swaminathan * If the image was found, then verify current firmware 75482527734SSukumar Swaminathan * versions of adapter 75582527734SSukumar Swaminathan */ 75682527734SSukumar Swaminathan if (fw) { 75782527734SSukumar Swaminathan /* Obtain current firmware version info */ 758*8f23e9faSHans Rosenfeld if (hba->model_info.chip & EMLXS_BE_CHIPS) { 759*8f23e9faSHans Rosenfeld (void) emlxs_be_read_fw_version(hba, &hba_fw); 76082527734SSukumar Swaminathan } else { 76182527734SSukumar Swaminathan hba_fw.kern = vpd->postKernRev; 76282527734SSukumar Swaminathan hba_fw.stub = vpd->opFwRev; 76382527734SSukumar Swaminathan hba_fw.sli1 = vpd->sli1FwRev; 76482527734SSukumar Swaminathan hba_fw.sli2 = vpd->sli2FwRev; 76582527734SSukumar Swaminathan hba_fw.sli3 = vpd->sli3FwRev; 76682527734SSukumar Swaminathan hba_fw.sli4 = vpd->sli4FwRev; 76782527734SSukumar Swaminathan } 76882527734SSukumar Swaminathan 7696a573d82SSukumar Swaminathan if (!kern_update && 7706a573d82SSukumar Swaminathan ((fw->kern && (hba_fw.kern != fw->kern)) || 7716a573d82SSukumar Swaminathan (fw->stub && (hba_fw.stub != fw->stub)))) { 7726a573d82SSukumar Swaminathan 7736a573d82SSukumar Swaminathan hba->fw_flag |= FW_UPDATE_NEEDED; 7746a573d82SSukumar Swaminathan 7756a573d82SSukumar Swaminathan } else if ((fw->kern && (hba_fw.kern != fw->kern)) || 77682527734SSukumar Swaminathan (fw->stub && (hba_fw.stub != fw->stub)) || 77782527734SSukumar Swaminathan (fw->sli1 && (hba_fw.sli1 != fw->sli1)) || 77882527734SSukumar Swaminathan (fw->sli2 && (hba_fw.sli2 != fw->sli2)) || 77982527734SSukumar Swaminathan (fw->sli3 && (hba_fw.sli3 != fw->sli3)) || 78082527734SSukumar Swaminathan (fw->sli4 && (hba_fw.sli4 != fw->sli4))) { 78182527734SSukumar Swaminathan 78282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 78382527734SSukumar Swaminathan "Firmware update needed. " 78482527734SSukumar Swaminathan "Updating. id=%d fw=%d", 78582527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 78682527734SSukumar Swaminathan 78782527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 78882527734SSukumar Swaminathan /* 78982527734SSukumar Swaminathan * Load the firmware image now 79082527734SSukumar Swaminathan * If MODFW_SUPPORT is not defined, the 79182527734SSukumar Swaminathan * firmware image will already be defined 79282527734SSukumar Swaminathan * in the emlxs_fw_table 79382527734SSukumar Swaminathan */ 79482527734SSukumar Swaminathan emlxs_fw_load(hba, fw); 79582527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 79682527734SSukumar Swaminathan 79782527734SSukumar Swaminathan if (fw->image && fw->size) { 798*8f23e9faSHans Rosenfeld uint32_t rc; 799*8f23e9faSHans Rosenfeld 800*8f23e9faSHans Rosenfeld rc = emlxs_fw_download(hba, 801*8f23e9faSHans Rosenfeld (char *)fw->image, fw->size, 0); 802*8f23e9faSHans Rosenfeld if ((rc != FC_SUCCESS) && 803*8f23e9faSHans Rosenfeld (rc != EMLXS_REBOOT_REQUIRED)) { 80482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 80582527734SSukumar Swaminathan &emlxs_init_msg, 80682527734SSukumar Swaminathan "Firmware update failed."); 8076a573d82SSukumar Swaminathan hba->fw_flag |= 8086a573d82SSukumar Swaminathan FW_UPDATE_NEEDED; 80982527734SSukumar Swaminathan } 81082527734SSukumar Swaminathan #ifdef MODFW_SUPPORT 81182527734SSukumar Swaminathan /* 81282527734SSukumar Swaminathan * Unload the firmware image from 81382527734SSukumar Swaminathan * kernel memory 81482527734SSukumar Swaminathan */ 81582527734SSukumar Swaminathan emlxs_fw_unload(hba, fw); 81682527734SSukumar Swaminathan #endif /* MODFW_SUPPORT */ 81782527734SSukumar Swaminathan 81882527734SSukumar Swaminathan fw_check = 0; 81982527734SSukumar Swaminathan 82082527734SSukumar Swaminathan goto reset; 82182527734SSukumar Swaminathan } 82282527734SSukumar Swaminathan 823*8f23e9faSHans Rosenfeld hba->fw_flag |= FW_UPDATE_NEEDED; 824*8f23e9faSHans Rosenfeld 82582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 82682527734SSukumar Swaminathan "Firmware image unavailable."); 82782527734SSukumar Swaminathan } else { 82882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 82982527734SSukumar Swaminathan "Firmware update not needed."); 83082527734SSukumar Swaminathan } 83182527734SSukumar Swaminathan } else { 83282527734SSukumar Swaminathan /* 83382527734SSukumar Swaminathan * This means either the adapter database is not 83482527734SSukumar Swaminathan * correct or a firmware image is missing from the 83582527734SSukumar Swaminathan * compile 83682527734SSukumar Swaminathan */ 83782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg, 83882527734SSukumar Swaminathan "Firmware image unavailable. id=%d fw=%d", 83982527734SSukumar Swaminathan hba->model_info.id, hba->model_info.fwid); 84082527734SSukumar Swaminathan } 84182527734SSukumar Swaminathan } 84282527734SSukumar Swaminathan 84382527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 84482527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 84582527734SSukumar Swaminathan 84682527734SSukumar Swaminathan emlxs_mb_dump_fcoe(hba, mbq, 0); 84782527734SSukumar Swaminathan 84882527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 84982527734SSukumar Swaminathan MBX_SUCCESS) { 85082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 85182527734SSukumar Swaminathan "No FCOE info found. status=%x", mb->mbxStatus); 85282527734SSukumar Swaminathan } else { 85382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 85482527734SSukumar Swaminathan &emlxs_init_debug_msg, 85582527734SSukumar Swaminathan "FCOE info dumped. rsp_cnt=%d status=%x", 85682527734SSukumar Swaminathan mb->un.varDmp4.rsp_cnt, mb->mbxStatus); 85782527734SSukumar Swaminathan (void) emlxs_parse_fcoe(hba, 858fe199829SSukumar Swaminathan (uint8_t *)hba->sli.sli4.dump_region.virt, 859fe199829SSukumar Swaminathan mb->un.varDmp4.rsp_cnt); 86082527734SSukumar Swaminathan } 86182527734SSukumar Swaminathan 86282527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 86382527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 86482527734SSukumar Swaminathan 865*8f23e9faSHans Rosenfeld status = 0; 866*8f23e9faSHans Rosenfeld if (port->flag & EMLXS_INI_ENABLED) { 867*8f23e9faSHans Rosenfeld status |= SLI4_FEATURE_FCP_INITIATOR; 868*8f23e9faSHans Rosenfeld } 869*8f23e9faSHans Rosenfeld if (port->flag & EMLXS_TGT_ENABLED) { 870*8f23e9faSHans Rosenfeld status |= SLI4_FEATURE_FCP_TARGET; 871*8f23e9faSHans Rosenfeld } 872*8f23e9faSHans Rosenfeld if (cfg[CFG_NPIV_ENABLE].current) { 873*8f23e9faSHans Rosenfeld status |= SLI4_FEATURE_NPIV; 874*8f23e9faSHans Rosenfeld } 875*8f23e9faSHans Rosenfeld if (cfg[CFG_RQD_MODE].current) { 876*8f23e9faSHans Rosenfeld status |= SLI4_FEATURE_RQD; 877*8f23e9faSHans Rosenfeld } 878*8f23e9faSHans Rosenfeld if (cfg[CFG_PERF_HINT].current) { 879*8f23e9faSHans Rosenfeld if (hba->sli.sli4.param.PHON) { 880*8f23e9faSHans Rosenfeld status |= SLI4_FEATURE_PERF_HINT; 881*8f23e9faSHans Rosenfeld } 882*8f23e9faSHans Rosenfeld } 883*8f23e9faSHans Rosenfeld 884*8f23e9faSHans Rosenfeld emlxs_mb_request_features(hba, mbq, status); 88582527734SSukumar Swaminathan 88682527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 88782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 88882527734SSukumar Swaminathan "Unable to REQUEST_FEATURES. Mailbox cmd=%x status=%x", 88982527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 89082527734SSukumar Swaminathan 89182527734SSukumar Swaminathan rval = EIO; 89282527734SSukumar Swaminathan goto failed1; 89382527734SSukumar Swaminathan } 894*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "REQ_FEATURE", (uint32_t *)mb, 6, 0); 895*8f23e9faSHans Rosenfeld 896*8f23e9faSHans Rosenfeld /* Check to see if we get the features we requested */ 897*8f23e9faSHans Rosenfeld if (status != mb->un.varReqFeatures.featuresEnabled) { 898*8f23e9faSHans Rosenfeld 899*8f23e9faSHans Rosenfeld /* Just report descrepencies, don't abort the attach */ 900*8f23e9faSHans Rosenfeld 901*8f23e9faSHans Rosenfeld outptr = (uint8_t *)emlxs_request_feature_xlate( 902*8f23e9faSHans Rosenfeld mb->un.varReqFeatures.featuresRequested); 903*8f23e9faSHans Rosenfeld (void) strlcpy(buf, (char *)outptr, sizeof (buf)); 904*8f23e9faSHans Rosenfeld 905*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 906*8f23e9faSHans Rosenfeld "REQUEST_FEATURES: wanted:%s got:%s", 907*8f23e9faSHans Rosenfeld &buf[0], emlxs_request_feature_xlate( 908*8f23e9faSHans Rosenfeld mb->un.varReqFeatures.featuresEnabled)); 909*8f23e9faSHans Rosenfeld 910*8f23e9faSHans Rosenfeld } 911*8f23e9faSHans Rosenfeld 912*8f23e9faSHans Rosenfeld if ((port->flag & EMLXS_INI_ENABLED) && 913*8f23e9faSHans Rosenfeld !(mb->un.varReqFeatures.featuresEnabled & 914*8f23e9faSHans Rosenfeld SLI4_FEATURE_FCP_INITIATOR)) { 915*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 916*8f23e9faSHans Rosenfeld "Initiator mode not supported by adapter."); 917*8f23e9faSHans Rosenfeld 918*8f23e9faSHans Rosenfeld rval = EIO; 919*8f23e9faSHans Rosenfeld 920*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 921*8f23e9faSHans Rosenfeld /* Check if we can fall back to just target mode */ 922*8f23e9faSHans Rosenfeld if ((hba->pm_state == EMLXS_PM_IN_ATTACH) && 923*8f23e9faSHans Rosenfeld (mb->un.varReqFeatures.featuresEnabled & 924*8f23e9faSHans Rosenfeld SLI4_FEATURE_FCP_TARGET) && 925*8f23e9faSHans Rosenfeld (cfg[CFG_DTM_ENABLE].current == 1) && 926*8f23e9faSHans Rosenfeld (cfg[CFG_TARGET_MODE].current == 1)) { 92782527734SSukumar Swaminathan 928*8f23e9faSHans Rosenfeld cfg[CFG_DTM_ENABLE].current = 0; 92982527734SSukumar Swaminathan 930*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 931*8f23e9faSHans Rosenfeld &emlxs_init_failed_msg, 932*8f23e9faSHans Rosenfeld "Disabling dynamic target mode. " 933*8f23e9faSHans Rosenfeld "Enabling target mode only."); 934*8f23e9faSHans Rosenfeld 935*8f23e9faSHans Rosenfeld /* This will trigger the driver to reattach */ 936*8f23e9faSHans Rosenfeld rval = EAGAIN; 937*8f23e9faSHans Rosenfeld } 938*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 939*8f23e9faSHans Rosenfeld goto failed1; 940*8f23e9faSHans Rosenfeld } 941*8f23e9faSHans Rosenfeld 942*8f23e9faSHans Rosenfeld if ((port->flag & EMLXS_TGT_ENABLED) && 943*8f23e9faSHans Rosenfeld !(mb->un.varReqFeatures.featuresEnabled & 944*8f23e9faSHans Rosenfeld SLI4_FEATURE_FCP_TARGET)) { 94582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 946*8f23e9faSHans Rosenfeld "Target mode not supported by adapter."); 94782527734SSukumar Swaminathan 94882527734SSukumar Swaminathan rval = EIO; 949*8f23e9faSHans Rosenfeld 950*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 951*8f23e9faSHans Rosenfeld /* Check if we can fall back to just initiator mode */ 952*8f23e9faSHans Rosenfeld if ((hba->pm_state == EMLXS_PM_IN_ATTACH) && 953*8f23e9faSHans Rosenfeld (mb->un.varReqFeatures.featuresEnabled & 954*8f23e9faSHans Rosenfeld SLI4_FEATURE_FCP_INITIATOR) && 955*8f23e9faSHans Rosenfeld (cfg[CFG_DTM_ENABLE].current == 1) && 956*8f23e9faSHans Rosenfeld (cfg[CFG_TARGET_MODE].current == 0)) { 957*8f23e9faSHans Rosenfeld 958*8f23e9faSHans Rosenfeld cfg[CFG_DTM_ENABLE].current = 0; 959*8f23e9faSHans Rosenfeld 960*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 961*8f23e9faSHans Rosenfeld &emlxs_init_failed_msg, 962*8f23e9faSHans Rosenfeld "Disabling dynamic target mode. " 963*8f23e9faSHans Rosenfeld "Enabling initiator mode only."); 964*8f23e9faSHans Rosenfeld 965*8f23e9faSHans Rosenfeld /* This will trigger the driver to reattach */ 966*8f23e9faSHans Rosenfeld rval = EAGAIN; 967*8f23e9faSHans Rosenfeld } 968*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 96982527734SSukumar Swaminathan goto failed1; 97082527734SSukumar Swaminathan } 97182527734SSukumar Swaminathan 97282527734SSukumar Swaminathan if (mb->un.varReqFeatures.featuresEnabled & SLI4_FEATURE_NPIV) { 97382527734SSukumar Swaminathan hba->flag |= FC_NPIV_ENABLED; 97482527734SSukumar Swaminathan } 97582527734SSukumar Swaminathan 976*8f23e9faSHans Rosenfeld if (mb->un.varReqFeatures.featuresEnabled & SLI4_FEATURE_PERF_HINT) { 977*8f23e9faSHans Rosenfeld hba->sli.sli4.flag |= EMLXS_SLI4_PHON; 978*8f23e9faSHans Rosenfeld if (hba->sli.sli4.param.PHWQ) { 979*8f23e9faSHans Rosenfeld hba->sli.sli4.flag |= EMLXS_SLI4_PHWQ; 980*8f23e9faSHans Rosenfeld } 98182527734SSukumar Swaminathan } 98282527734SSukumar Swaminathan 98382527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 98482527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 98582527734SSukumar Swaminathan 98682527734SSukumar Swaminathan emlxs_mb_read_config(hba, mbq); 98782527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 98882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 98982527734SSukumar Swaminathan "Unable to READ_CONFIG. Mailbox cmd=%x status=%x", 99082527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 99182527734SSukumar Swaminathan 99282527734SSukumar Swaminathan rval = EIO; 99382527734SSukumar Swaminathan goto failed1; 99482527734SSukumar Swaminathan } 995*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "READ_CONFIG4", (uint32_t *)mb, 18, 0); 996*8f23e9faSHans Rosenfeld 997*8f23e9faSHans Rosenfeld /* Set default extents */ 998*8f23e9faSHans Rosenfeld hba->sli.sli4.XRICount = mb->un.varRdConfig4.XRICount; 999*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtCount = 1; 1000*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtSize = hba->sli.sli4.XRICount; 1001*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIBase[0] = mb->un.varRdConfig4.XRIBase; 1002*8f23e9faSHans Rosenfeld 1003*8f23e9faSHans Rosenfeld hba->sli.sli4.RPICount = mb->un.varRdConfig4.RPICount; 1004*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtCount = 1; 1005*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtSize = hba->sli.sli4.RPICount; 1006*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIBase[0] = mb->un.varRdConfig4.RPIBase; 1007*8f23e9faSHans Rosenfeld 1008*8f23e9faSHans Rosenfeld hba->sli.sli4.VPICount = mb->un.varRdConfig4.VPICount; 1009*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtCount = 1; 1010*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtSize = hba->sli.sli4.VPICount; 1011*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIBase[0] = mb->un.varRdConfig4.VPIBase; 1012*8f23e9faSHans Rosenfeld 1013*8f23e9faSHans Rosenfeld hba->sli.sli4.VFICount = mb->un.varRdConfig4.VFICount; 1014*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtCount = 1; 1015*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtSize = hba->sli.sli4.VFICount; 1016*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIBase[0] = mb->un.varRdConfig4.VFIBase; 1017*8f23e9faSHans Rosenfeld 1018*8f23e9faSHans Rosenfeld hba->sli.sli4.FCFICount = mb->un.varRdConfig4.FCFICount; 1019*8f23e9faSHans Rosenfeld 1020*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1021*8f23e9faSHans Rosenfeld "CONFIG: xri:%d rpi:%d vpi:%d vfi:%d fcfi:%d", 1022*8f23e9faSHans Rosenfeld hba->sli.sli4.XRICount, 1023*8f23e9faSHans Rosenfeld hba->sli.sli4.RPICount, 1024*8f23e9faSHans Rosenfeld hba->sli.sli4.VPICount, 1025*8f23e9faSHans Rosenfeld hba->sli.sli4.VFICount, 1026*8f23e9faSHans Rosenfeld hba->sli.sli4.FCFICount); 1027*8f23e9faSHans Rosenfeld 1028*8f23e9faSHans Rosenfeld if ((hba->sli.sli4.XRICount == 0) || 1029*8f23e9faSHans Rosenfeld (hba->sli.sli4.RPICount == 0) || 1030*8f23e9faSHans Rosenfeld (hba->sli.sli4.VPICount == 0) || 1031*8f23e9faSHans Rosenfeld (hba->sli.sli4.VFICount == 0) || 1032*8f23e9faSHans Rosenfeld (hba->sli.sli4.FCFICount == 0)) { 1033*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1034*8f23e9faSHans Rosenfeld "Invalid extent value(s) - xri:%d rpi:%d vpi:%d " 1035*8f23e9faSHans Rosenfeld "vfi:%d fcfi:%d", 1036*8f23e9faSHans Rosenfeld hba->sli.sli4.XRICount, 1037*8f23e9faSHans Rosenfeld hba->sli.sli4.RPICount, 1038*8f23e9faSHans Rosenfeld hba->sli.sli4.VPICount, 1039*8f23e9faSHans Rosenfeld hba->sli.sli4.VFICount, 1040*8f23e9faSHans Rosenfeld hba->sli.sli4.FCFICount); 1041*8f23e9faSHans Rosenfeld 1042*8f23e9faSHans Rosenfeld rval = EIO; 1043*8f23e9faSHans Rosenfeld goto failed1; 1044*8f23e9faSHans Rosenfeld } 1045*8f23e9faSHans Rosenfeld 1046*8f23e9faSHans Rosenfeld if (mb->un.varRdConfig4.extents) { 1047*8f23e9faSHans Rosenfeld if (emlxs_sli4_init_extents(hba, mbq)) { 1048*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1049*8f23e9faSHans Rosenfeld "Unable to initialize extents."); 1050*8f23e9faSHans Rosenfeld 1051*8f23e9faSHans Rosenfeld rval = EIO; 1052*8f23e9faSHans Rosenfeld goto failed1; 1053*8f23e9faSHans Rosenfeld } 1054*8f23e9faSHans Rosenfeld } 1055*8f23e9faSHans Rosenfeld 1056*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1057*8f23e9faSHans Rosenfeld "CONFIG: port_name:%c %c %c %c", 1058*8f23e9faSHans Rosenfeld hba->sli.sli4.port_name[0], 1059*8f23e9faSHans Rosenfeld hba->sli.sli4.port_name[1], 1060*8f23e9faSHans Rosenfeld hba->sli.sli4.port_name[2], 1061*8f23e9faSHans Rosenfeld hba->sli.sli4.port_name[3]); 1062*8f23e9faSHans Rosenfeld 1063*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1064*8f23e9faSHans Rosenfeld "CONFIG: ldv:%d link_type:%d link_number:%d", 1065*8f23e9faSHans Rosenfeld mb->un.varRdConfig4.ldv, 1066*8f23e9faSHans Rosenfeld mb->un.varRdConfig4.link_type, 1067*8f23e9faSHans Rosenfeld mb->un.varRdConfig4.link_number); 106882527734SSukumar Swaminathan 1069*8f23e9faSHans Rosenfeld if (mb->un.varRdConfig4.ldv) { 1070*8f23e9faSHans Rosenfeld hba->sli.sli4.link_number = mb->un.varRdConfig4.link_number; 1071*8f23e9faSHans Rosenfeld } else { 1072*8f23e9faSHans Rosenfeld hba->sli.sli4.link_number = (uint32_t)-1; 1073*8f23e9faSHans Rosenfeld } 107482527734SSukumar Swaminathan 107582527734SSukumar Swaminathan if (hba->sli.sli4.VPICount) { 107682527734SSukumar Swaminathan hba->vpi_max = min(hba->sli.sli4.VPICount, MAX_VPORTS) - 1; 107782527734SSukumar Swaminathan } 107882527734SSukumar Swaminathan 107982527734SSukumar Swaminathan /* Set the max node count */ 108082527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 108182527734SSukumar Swaminathan hba->max_nodes = 108282527734SSukumar Swaminathan min(cfg[CFG_NUM_NODES].current, 108382527734SSukumar Swaminathan hba->sli.sli4.RPICount); 108482527734SSukumar Swaminathan } else { 108582527734SSukumar Swaminathan hba->max_nodes = hba->sli.sli4.RPICount; 108682527734SSukumar Swaminathan } 108782527734SSukumar Swaminathan 108882527734SSukumar Swaminathan /* Set the io throttle */ 108982527734SSukumar Swaminathan hba->io_throttle = hba->sli.sli4.XRICount - IO_THROTTLE_RESERVE; 1090*8f23e9faSHans Rosenfeld 1091*8f23e9faSHans Rosenfeld /* Set max_iotag */ 1092*8f23e9faSHans Rosenfeld /* We add 1 in case all XRI's are non-zero */ 1093*8f23e9faSHans Rosenfeld hba->max_iotag = hba->sli.sli4.XRICount + 1; 1094*8f23e9faSHans Rosenfeld 1095*8f23e9faSHans Rosenfeld if (cfg[CFG_NUM_IOTAGS].current) { 1096*8f23e9faSHans Rosenfeld hba->max_iotag = min(hba->max_iotag, 1097*8f23e9faSHans Rosenfeld (uint16_t)cfg[CFG_NUM_IOTAGS].current); 1098*8f23e9faSHans Rosenfeld } 1099*8f23e9faSHans Rosenfeld 1100*8f23e9faSHans Rosenfeld /* Set out-of-range iotag base */ 1101*8f23e9faSHans Rosenfeld hba->fc_oor_iotag = hba->max_iotag; 110282527734SSukumar Swaminathan 110382527734SSukumar Swaminathan /* Save the link speed capabilities */ 1104a9800bebSGarrett D'Amore vpd->link_speed = (uint16_t)mb->un.varRdConfig4.lmt; 110582527734SSukumar Swaminathan emlxs_process_link_speed(hba); 110682527734SSukumar Swaminathan 110782527734SSukumar Swaminathan /* 110882527734SSukumar Swaminathan * Allocate some memory for buffers 110982527734SSukumar Swaminathan */ 111082527734SSukumar Swaminathan if (emlxs_mem_alloc_buffer(hba) == 0) { 111182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 111282527734SSukumar Swaminathan "Unable to allocate memory buffers."); 111382527734SSukumar Swaminathan 111482527734SSukumar Swaminathan rval = ENOMEM; 111582527734SSukumar Swaminathan goto failed1; 111682527734SSukumar Swaminathan } 111782527734SSukumar Swaminathan 111882527734SSukumar Swaminathan if (emlxs_sli4_resource_alloc(hba)) { 111982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 112082527734SSukumar Swaminathan "Unable to allocate resources."); 112182527734SSukumar Swaminathan 112282527734SSukumar Swaminathan rval = ENOMEM; 112382527734SSukumar Swaminathan goto failed2; 112482527734SSukumar Swaminathan } 1125*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "XRIp", (uint32_t *)hba->sli.sli4.XRIp, 18, 0); 1126*8f23e9faSHans Rosenfeld emlxs_sli4_zero_queue_stat(hba); 112782527734SSukumar Swaminathan 112882527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV5) 112982527734SSukumar Swaminathan if ((cfg[CFG_NPIV_ENABLE].current) && (hba->flag & FC_NPIV_ENABLED)) { 113082527734SSukumar Swaminathan hba->fca_tran->fca_num_npivports = hba->vpi_max; 113182527734SSukumar Swaminathan } 113282527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV5 */ 113382527734SSukumar Swaminathan 113482527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 113582527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 113682527734SSukumar Swaminathan 113782527734SSukumar Swaminathan if (emlxs_sli4_post_sgl_pages(hba, mbq)) { 113882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 113982527734SSukumar Swaminathan "Unable to post sgl pages."); 114082527734SSukumar Swaminathan 114182527734SSukumar Swaminathan rval = EIO; 114282527734SSukumar Swaminathan goto failed3; 114382527734SSukumar Swaminathan } 114482527734SSukumar Swaminathan 114582527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 114682527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 114782527734SSukumar Swaminathan 114882527734SSukumar Swaminathan if (emlxs_sli4_post_hdr_tmplates(hba, mbq)) { 114982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 115082527734SSukumar Swaminathan "Unable to post header templates."); 115182527734SSukumar Swaminathan 115282527734SSukumar Swaminathan rval = EIO; 115382527734SSukumar Swaminathan goto failed3; 115482527734SSukumar Swaminathan } 115582527734SSukumar Swaminathan 115682527734SSukumar Swaminathan /* 115782527734SSukumar Swaminathan * Add our interrupt routine to kernel's interrupt chain & enable it 115882527734SSukumar Swaminathan * If MSI is enabled this will cause Solaris to program the MSI address 115982527734SSukumar Swaminathan * and data registers in PCI config space 116082527734SSukumar Swaminathan */ 116182527734SSukumar Swaminathan if (EMLXS_INTR_ADD(hba) != DDI_SUCCESS) { 116282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 116382527734SSukumar Swaminathan "Unable to add interrupt(s)."); 116482527734SSukumar Swaminathan 116582527734SSukumar Swaminathan rval = EIO; 116682527734SSukumar Swaminathan goto failed3; 116782527734SSukumar Swaminathan } 116882527734SSukumar Swaminathan 116982527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 117082527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 117182527734SSukumar Swaminathan 117282527734SSukumar Swaminathan /* This MUST be done after EMLXS_INTR_ADD */ 117382527734SSukumar Swaminathan if (emlxs_sli4_create_queues(hba, mbq)) { 117482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 117582527734SSukumar Swaminathan "Unable to create queues."); 117682527734SSukumar Swaminathan 117782527734SSukumar Swaminathan rval = EIO; 117882527734SSukumar Swaminathan goto failed3; 117982527734SSukumar Swaminathan } 118082527734SSukumar Swaminathan 118182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_CFGPORT); 118282527734SSukumar Swaminathan 118382527734SSukumar Swaminathan /* Get and save the current firmware version (based on sli_mode) */ 118482527734SSukumar Swaminathan emlxs_decode_firmware_rev(hba, vpd); 118582527734SSukumar Swaminathan 118682527734SSukumar Swaminathan 118782527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_INIT_INITLINK); 118882527734SSukumar Swaminathan 1189*8f23e9faSHans Rosenfeld if (SLI4_FC_MODE) { 1190*8f23e9faSHans Rosenfeld /* Reuse mbq from previous mbox */ 1191*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 1192*8f23e9faSHans Rosenfeld 1193*8f23e9faSHans Rosenfeld emlxs_mb_config_link(hba, mbq); 1194*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 1195*8f23e9faSHans Rosenfeld MBX_SUCCESS) { 1196*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1197*8f23e9faSHans Rosenfeld "Unable to configure link. Mailbox cmd=%x " 1198*8f23e9faSHans Rosenfeld "status=%x", 1199*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus); 1200*8f23e9faSHans Rosenfeld 1201*8f23e9faSHans Rosenfeld rval = EIO; 1202*8f23e9faSHans Rosenfeld goto failed3; 1203*8f23e9faSHans Rosenfeld } 1204*8f23e9faSHans Rosenfeld } 1205*8f23e9faSHans Rosenfeld 120682527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 120782527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 120882527734SSukumar Swaminathan 120982527734SSukumar Swaminathan /* 121082527734SSukumar Swaminathan * We need to get login parameters for NID 121182527734SSukumar Swaminathan */ 121282527734SSukumar Swaminathan (void) emlxs_mb_read_sparam(hba, mbq); 1213a9800bebSGarrett D'Amore mp = (MATCHMAP *)mbq->bp; 121482527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 121582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 121682527734SSukumar Swaminathan "Unable to read parameters. Mailbox cmd=%x status=%x", 121782527734SSukumar Swaminathan mb->mbxCommand, mb->mbxStatus); 121882527734SSukumar Swaminathan 121982527734SSukumar Swaminathan rval = EIO; 122082527734SSukumar Swaminathan goto failed3; 122182527734SSukumar Swaminathan } 122282527734SSukumar Swaminathan 122382527734SSukumar Swaminathan /* Free the buffer since we were polling */ 1224a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_BUF, (void *)mp); 122582527734SSukumar Swaminathan mp = NULL; 122682527734SSukumar Swaminathan 122782527734SSukumar Swaminathan /* If no serial number in VPD data, then use the WWPN */ 122882527734SSukumar Swaminathan if (vpd->serial_num[0] == 0) { 122982527734SSukumar Swaminathan outptr = (uint8_t *)&hba->wwpn.IEEE[0]; 123082527734SSukumar Swaminathan for (i = 0; i < 12; i++) { 123182527734SSukumar Swaminathan status = *outptr++; 123282527734SSukumar Swaminathan j = ((status & 0xf0) >> 4); 123382527734SSukumar Swaminathan if (j <= 9) { 123482527734SSukumar Swaminathan vpd->serial_num[i] = 123582527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 123682527734SSukumar Swaminathan } else { 123782527734SSukumar Swaminathan vpd->serial_num[i] = 123882527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 123982527734SSukumar Swaminathan } 124082527734SSukumar Swaminathan 124182527734SSukumar Swaminathan i++; 124282527734SSukumar Swaminathan j = (status & 0xf); 124382527734SSukumar Swaminathan if (j <= 9) { 124482527734SSukumar Swaminathan vpd->serial_num[i] = 124582527734SSukumar Swaminathan (char)((uint8_t)'0' + (uint8_t)j); 124682527734SSukumar Swaminathan } else { 124782527734SSukumar Swaminathan vpd->serial_num[i] = 124882527734SSukumar Swaminathan (char)((uint8_t)'A' + (uint8_t)(j - 10)); 124982527734SSukumar Swaminathan } 125082527734SSukumar Swaminathan } 125182527734SSukumar Swaminathan 125282527734SSukumar Swaminathan /* 125382527734SSukumar Swaminathan * Set port number and port index to zero 125482527734SSukumar Swaminathan * The WWN's are unique to each port and therefore port_num 125582527734SSukumar Swaminathan * must equal zero. This effects the hba_fru_details structure 125682527734SSukumar Swaminathan * in fca_bind_port() 125782527734SSukumar Swaminathan */ 125882527734SSukumar Swaminathan vpd->port_num[0] = 0; 125982527734SSukumar Swaminathan vpd->port_index = 0; 1260*8f23e9faSHans Rosenfeld 1261*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 1262*8f23e9faSHans Rosenfeld "CONFIG: WWPN: port_index=0"); 126382527734SSukumar Swaminathan } 126482527734SSukumar Swaminathan 1265*8f23e9faSHans Rosenfeld /* Make final attempt to set a port index */ 1266a9800bebSGarrett D'Amore if (vpd->port_index == (uint32_t)-1) { 126782527734SSukumar Swaminathan dev_info_t *p_dip; 126882527734SSukumar Swaminathan dev_info_t *c_dip; 126982527734SSukumar Swaminathan 127082527734SSukumar Swaminathan p_dip = ddi_get_parent(hba->dip); 127182527734SSukumar Swaminathan c_dip = ddi_get_child(p_dip); 127282527734SSukumar Swaminathan 127382527734SSukumar Swaminathan vpd->port_index = 0; 127482527734SSukumar Swaminathan while (c_dip && (hba->dip != c_dip)) { 127582527734SSukumar Swaminathan c_dip = ddi_get_next_sibling(c_dip); 127682527734SSukumar Swaminathan 1277*8f23e9faSHans Rosenfeld if (strcmp(ddi_get_name(c_dip), "ethernet") == 0) { 1278*8f23e9faSHans Rosenfeld continue; 127982527734SSukumar Swaminathan } 1280*8f23e9faSHans Rosenfeld 1281*8f23e9faSHans Rosenfeld vpd->port_index++; 128282527734SSukumar Swaminathan } 1283*8f23e9faSHans Rosenfeld 1284*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1285*8f23e9faSHans Rosenfeld &emlxs_init_debug_msg, 1286*8f23e9faSHans Rosenfeld "CONFIG: Device tree: port_index=%d", 1287*8f23e9faSHans Rosenfeld vpd->port_index); 128882527734SSukumar Swaminathan } 128982527734SSukumar Swaminathan 129082527734SSukumar Swaminathan if (vpd->port_num[0] == 0) { 1291*8f23e9faSHans Rosenfeld if (hba->model_info.channels == EMLXS_MULTI_CHANNEL) { 1292*8f23e9faSHans Rosenfeld (void) snprintf(vpd->port_num, 1293*8f23e9faSHans Rosenfeld (sizeof (vpd->port_num)-1), 1294*8f23e9faSHans Rosenfeld "%d", vpd->port_index); 129582527734SSukumar Swaminathan } 129682527734SSukumar Swaminathan } 129782527734SSukumar Swaminathan 129882527734SSukumar Swaminathan if (vpd->id[0] == 0) { 1299*8f23e9faSHans Rosenfeld (void) snprintf(vpd->id, (sizeof (vpd->id)-1), 1300*8f23e9faSHans Rosenfeld "%s %d", 130182527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 130282527734SSukumar Swaminathan 130382527734SSukumar Swaminathan } 130482527734SSukumar Swaminathan 130582527734SSukumar Swaminathan if (vpd->manufacturer[0] == 0) { 1306*8f23e9faSHans Rosenfeld (void) strncpy(vpd->manufacturer, hba->model_info.manufacturer, 1307*8f23e9faSHans Rosenfeld (sizeof (vpd->manufacturer)-1)); 130882527734SSukumar Swaminathan } 130982527734SSukumar Swaminathan 131082527734SSukumar Swaminathan if (vpd->part_num[0] == 0) { 1311*8f23e9faSHans Rosenfeld (void) strncpy(vpd->part_num, hba->model_info.model, 1312*8f23e9faSHans Rosenfeld (sizeof (vpd->part_num)-1)); 131382527734SSukumar Swaminathan } 131482527734SSukumar Swaminathan 131582527734SSukumar Swaminathan if (vpd->model_desc[0] == 0) { 1316*8f23e9faSHans Rosenfeld (void) snprintf(vpd->model_desc, (sizeof (vpd->model_desc)-1), 1317*8f23e9faSHans Rosenfeld "%s %d", 131882527734SSukumar Swaminathan hba->model_info.model_desc, vpd->port_index); 131982527734SSukumar Swaminathan } 132082527734SSukumar Swaminathan 132182527734SSukumar Swaminathan if (vpd->model[0] == 0) { 1322*8f23e9faSHans Rosenfeld (void) strncpy(vpd->model, hba->model_info.model, 1323*8f23e9faSHans Rosenfeld (sizeof (vpd->model)-1)); 132482527734SSukumar Swaminathan } 132582527734SSukumar Swaminathan 132682527734SSukumar Swaminathan if (vpd->prog_types[0] == 0) { 1327*8f23e9faSHans Rosenfeld emlxs_build_prog_types(hba, vpd); 132882527734SSukumar Swaminathan } 132982527734SSukumar Swaminathan 133082527734SSukumar Swaminathan /* Create the symbolic names */ 1331*8f23e9faSHans Rosenfeld (void) snprintf(hba->snn, (sizeof (hba->snn)-1), 1332*8f23e9faSHans Rosenfeld "Emulex %s FV%s DV%s %s", 133382527734SSukumar Swaminathan hba->model_info.model, hba->vpd.fw_version, emlxs_version, 133482527734SSukumar Swaminathan (char *)utsname.nodename); 133582527734SSukumar Swaminathan 1336*8f23e9faSHans Rosenfeld (void) snprintf(hba->spn, (sizeof (hba->spn)-1), 133782527734SSukumar Swaminathan "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", 133882527734SSukumar Swaminathan hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb, 133982527734SSukumar Swaminathan hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2], 134082527734SSukumar Swaminathan hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]); 134182527734SSukumar Swaminathan 134282527734SSukumar Swaminathan 134382527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN); 134482527734SSukumar Swaminathan emlxs_sli4_enable_intr(hba); 134582527734SSukumar Swaminathan 1346*8f23e9faSHans Rosenfeld /* Check persist-linkdown */ 1347*8f23e9faSHans Rosenfeld if (cfg[CFG_PERSIST_LINKDOWN].current) { 1348*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN_PERSIST); 1349*8f23e9faSHans Rosenfeld goto done; 1350*8f23e9faSHans Rosenfeld } 1351*8f23e9faSHans Rosenfeld 1352*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 1353*8f23e9faSHans Rosenfeld if ((port->mode == MODE_TARGET) && 1354*8f23e9faSHans Rosenfeld !(port->fct_flags & FCT_STATE_PORT_ONLINE)) { 1355*8f23e9faSHans Rosenfeld goto done; 1356*8f23e9faSHans Rosenfeld } 1357*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 1358*8f23e9faSHans Rosenfeld 135982527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 136082527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 136182527734SSukumar Swaminathan 136282527734SSukumar Swaminathan /* 136382527734SSukumar Swaminathan * Setup and issue mailbox INITIALIZE LINK command 136482527734SSukumar Swaminathan * At this point, the interrupt will be generated by the HW 136582527734SSukumar Swaminathan */ 1366*8f23e9faSHans Rosenfeld emlxs_mb_init_link(hba, mbq, 1367*8f23e9faSHans Rosenfeld cfg[CFG_TOPOLOGY].current, cfg[CFG_LINK_SPEED].current); 136882527734SSukumar Swaminathan 1369*8f23e9faSHans Rosenfeld rval = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 1370*8f23e9faSHans Rosenfeld if ((rval != MBX_SUCCESS) && (rval != MBX_BUSY)) { 1371*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 1372*8f23e9faSHans Rosenfeld "Unable to initialize link. " 1373*8f23e9faSHans Rosenfeld "Mailbox cmd=%x status=%x", 1374*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus); 1375*8f23e9faSHans Rosenfeld 1376*8f23e9faSHans Rosenfeld rval = EIO; 1377*8f23e9faSHans Rosenfeld goto failed3; 1378*8f23e9faSHans Rosenfeld } 1379*8f23e9faSHans Rosenfeld 1380*8f23e9faSHans Rosenfeld /* Wait for link to come up */ 1381*8f23e9faSHans Rosenfeld i = cfg[CFG_LINKUP_DELAY].current; 1382*8f23e9faSHans Rosenfeld while (i && (hba->state < FC_LINK_UP)) { 1383*8f23e9faSHans Rosenfeld /* Check for hardware error */ 1384*8f23e9faSHans Rosenfeld if (hba->state == FC_ERROR) { 1385*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1386*8f23e9faSHans Rosenfeld &emlxs_init_failed_msg, 1387*8f23e9faSHans Rosenfeld "Adapter error.", mb->mbxCommand, 1388*8f23e9faSHans Rosenfeld mb->mbxStatus); 138982527734SSukumar Swaminathan 139082527734SSukumar Swaminathan rval = EIO; 139182527734SSukumar Swaminathan goto failed3; 139282527734SSukumar Swaminathan } 139382527734SSukumar Swaminathan 1394*8f23e9faSHans Rosenfeld BUSYWAIT_MS(1000); 1395*8f23e9faSHans Rosenfeld i--; 139682527734SSukumar Swaminathan } 139782527734SSukumar Swaminathan 1398*8f23e9faSHans Rosenfeld done: 139982527734SSukumar Swaminathan /* 1400*8f23e9faSHans Rosenfeld * The leadville driver will now handle the FLOGI at the driver level 140182527734SSukumar Swaminathan */ 140282527734SSukumar Swaminathan 1403bce54adfSSukumar Swaminathan if (mbq) { 1404bce54adfSSukumar Swaminathan (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ)); 1405bce54adfSSukumar Swaminathan mbq = NULL; 1406bce54adfSSukumar Swaminathan mb = NULL; 1407bce54adfSSukumar Swaminathan } 140882527734SSukumar Swaminathan return (0); 140982527734SSukumar Swaminathan 141082527734SSukumar Swaminathan failed3: 141182527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 141282527734SSukumar Swaminathan 141382527734SSukumar Swaminathan if (mp) { 1414a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_BUF, (void *)mp); 141582527734SSukumar Swaminathan mp = NULL; 141682527734SSukumar Swaminathan } 141782527734SSukumar Swaminathan 141882527734SSukumar Swaminathan 141982527734SSukumar Swaminathan if (hba->intr_flags & EMLXS_MSI_ADDED) { 142082527734SSukumar Swaminathan (void) EMLXS_INTR_REMOVE(hba); 142182527734SSukumar Swaminathan } 142282527734SSukumar Swaminathan 142382527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 142482527734SSukumar Swaminathan 142582527734SSukumar Swaminathan failed2: 142682527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 142782527734SSukumar Swaminathan 142882527734SSukumar Swaminathan failed1: 142982527734SSukumar Swaminathan if (mbq) { 143082527734SSukumar Swaminathan (void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ)); 143182527734SSukumar Swaminathan mbq = NULL; 143282527734SSukumar Swaminathan mb = NULL; 143382527734SSukumar Swaminathan } 143482527734SSukumar Swaminathan 143582527734SSukumar Swaminathan if (hba->sli.sli4.dump_region.virt) { 143682527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 143782527734SSukumar Swaminathan } 143882527734SSukumar Swaminathan 143982527734SSukumar Swaminathan if (rval == 0) { 144082527734SSukumar Swaminathan rval = EIO; 144182527734SSukumar Swaminathan } 144282527734SSukumar Swaminathan 144382527734SSukumar Swaminathan return (rval); 144482527734SSukumar Swaminathan 144582527734SSukumar Swaminathan } /* emlxs_sli4_online() */ 144682527734SSukumar Swaminathan 144782527734SSukumar Swaminathan 144882527734SSukumar Swaminathan static void 1449*8f23e9faSHans Rosenfeld emlxs_sli4_offline(emlxs_hba_t *hba, uint32_t reset_requested) 145082527734SSukumar Swaminathan { 145182527734SSukumar Swaminathan /* Reverse emlxs_sli4_online */ 145282527734SSukumar Swaminathan 145382527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 1454*8f23e9faSHans Rosenfeld if (hba->flag & FC_INTERLOCKED) { 145582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 1456*8f23e9faSHans Rosenfeld goto killed; 1457*8f23e9faSHans Rosenfeld } 1458*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 145982527734SSukumar Swaminathan 1460*8f23e9faSHans Rosenfeld if (reset_requested) { 1461*8f23e9faSHans Rosenfeld (void) emlxs_sli4_hba_reset(hba, 0, 0, 0); 146282527734SSukumar Swaminathan } 146382527734SSukumar Swaminathan 146482527734SSukumar Swaminathan /* Shutdown the adapter interface */ 146582527734SSukumar Swaminathan emlxs_sli4_hba_kill(hba); 146682527734SSukumar Swaminathan 1467*8f23e9faSHans Rosenfeld killed: 1468*8f23e9faSHans Rosenfeld 146982527734SSukumar Swaminathan /* Free SLI shared memory */ 147082527734SSukumar Swaminathan emlxs_sli4_resource_free(hba); 147182527734SSukumar Swaminathan 147282527734SSukumar Swaminathan /* Free driver shared memory */ 147382527734SSukumar Swaminathan (void) emlxs_mem_free_buffer(hba); 147482527734SSukumar Swaminathan 147582527734SSukumar Swaminathan /* Free the host dump region buffer */ 147682527734SSukumar Swaminathan (void) emlxs_mem_free(hba, &hba->sli.sli4.dump_region); 147782527734SSukumar Swaminathan 147882527734SSukumar Swaminathan } /* emlxs_sli4_offline() */ 147982527734SSukumar Swaminathan 148082527734SSukumar Swaminathan 148182527734SSukumar Swaminathan /*ARGSUSED*/ 148282527734SSukumar Swaminathan static int 148382527734SSukumar Swaminathan emlxs_sli4_map_hdw(emlxs_hba_t *hba) 148482527734SSukumar Swaminathan { 148582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 148682527734SSukumar Swaminathan dev_info_t *dip; 148782527734SSukumar Swaminathan ddi_device_acc_attr_t dev_attr; 148882527734SSukumar Swaminathan int status; 148982527734SSukumar Swaminathan 149082527734SSukumar Swaminathan dip = (dev_info_t *)hba->dip; 149182527734SSukumar Swaminathan dev_attr = emlxs_dev_acc_attr; 149282527734SSukumar Swaminathan 1493*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1494*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1495*8f23e9faSHans Rosenfeld 1496*8f23e9faSHans Rosenfeld /* Map in Hardware BAR pages that will be used for */ 1497*8f23e9faSHans Rosenfeld /* communication with HBA. */ 1498*8f23e9faSHans Rosenfeld if (hba->sli.sli4.bar1_acc_handle == 0) { 1499*8f23e9faSHans Rosenfeld status = ddi_regs_map_setup(dip, PCI_BAR1_RINDEX, 1500*8f23e9faSHans Rosenfeld (caddr_t *)&hba->sli.sli4.bar1_addr, 1501*8f23e9faSHans Rosenfeld 0, 0, &dev_attr, &hba->sli.sli4.bar1_acc_handle); 1502*8f23e9faSHans Rosenfeld if (status != DDI_SUCCESS) { 1503*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1504*8f23e9faSHans Rosenfeld &emlxs_attach_failed_msg, 1505*8f23e9faSHans Rosenfeld "(PCI) ddi_regs_map_setup BAR1 failed. " 1506*8f23e9faSHans Rosenfeld "stat=%d mem=%p attr=%p hdl=%p", 1507*8f23e9faSHans Rosenfeld status, &hba->sli.sli4.bar1_addr, &dev_attr, 1508*8f23e9faSHans Rosenfeld &hba->sli.sli4.bar1_acc_handle); 1509*8f23e9faSHans Rosenfeld goto failed; 1510*8f23e9faSHans Rosenfeld } 151182527734SSukumar Swaminathan } 151282527734SSukumar Swaminathan 1513*8f23e9faSHans Rosenfeld if (hba->sli.sli4.bar2_acc_handle == 0) { 1514*8f23e9faSHans Rosenfeld status = ddi_regs_map_setup(dip, PCI_BAR2_RINDEX, 1515*8f23e9faSHans Rosenfeld (caddr_t *)&hba->sli.sli4.bar2_addr, 1516*8f23e9faSHans Rosenfeld 0, 0, &dev_attr, &hba->sli.sli4.bar2_acc_handle); 1517*8f23e9faSHans Rosenfeld if (status != DDI_SUCCESS) { 1518*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1519*8f23e9faSHans Rosenfeld &emlxs_attach_failed_msg, 1520*8f23e9faSHans Rosenfeld "ddi_regs_map_setup BAR2 failed. status=%x", 1521*8f23e9faSHans Rosenfeld status); 1522*8f23e9faSHans Rosenfeld goto failed; 1523*8f23e9faSHans Rosenfeld } 1524*8f23e9faSHans Rosenfeld } 1525*8f23e9faSHans Rosenfeld 1526*8f23e9faSHans Rosenfeld /* offset from beginning of register space */ 1527*8f23e9faSHans Rosenfeld hba->sli.sli4.MPUEPSemaphore_reg_addr = 1528*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar1_addr + 1529*8f23e9faSHans Rosenfeld CSR_MPU_EP_SEMAPHORE_OFFSET); 1530*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr = 1531*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MB_DB_OFFSET); 1532*8f23e9faSHans Rosenfeld hba->sli.sli4.CQDB_reg_addr = 1533*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar2_addr + PD_CQ_DB_OFFSET); 1534*8f23e9faSHans Rosenfeld hba->sli.sli4.MQDB_reg_addr = 1535*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar2_addr + PD_MQ_DB_OFFSET); 1536*8f23e9faSHans Rosenfeld hba->sli.sli4.WQDB_reg_addr = 1537*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar2_addr + PD_WQ_DB_OFFSET); 1538*8f23e9faSHans Rosenfeld hba->sli.sli4.RQDB_reg_addr = 1539*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar2_addr + PD_RQ_DB_OFFSET); 1540*8f23e9faSHans Rosenfeld 1541*8f23e9faSHans Rosenfeld hba->sli.sli4.STATUS_reg_addr = 0; 1542*8f23e9faSHans Rosenfeld hba->sli.sli4.CNTL_reg_addr = 0; 1543*8f23e9faSHans Rosenfeld 1544*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr = 1545*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_LO_OFFSET); 1546*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr = 1547*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_HI_OFFSET); 1548*8f23e9faSHans Rosenfeld 1549*8f23e9faSHans Rosenfeld hba->sli.sli4.PHYSDEV_reg_addr = 0; 1550*8f23e9faSHans Rosenfeld break; 1551*8f23e9faSHans Rosenfeld 1552*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1553*8f23e9faSHans Rosenfeld 1554*8f23e9faSHans Rosenfeld /* Map in Hardware BAR pages that will be used for */ 1555*8f23e9faSHans Rosenfeld /* communication with HBA. */ 1556*8f23e9faSHans Rosenfeld if (hba->sli.sli4.bar0_acc_handle == 0) { 1557*8f23e9faSHans Rosenfeld status = ddi_regs_map_setup(dip, PCI_BAR0_RINDEX, 1558*8f23e9faSHans Rosenfeld (caddr_t *)&hba->sli.sli4.bar0_addr, 1559*8f23e9faSHans Rosenfeld 0, 0, &dev_attr, &hba->sli.sli4.bar0_acc_handle); 1560*8f23e9faSHans Rosenfeld if (status != DDI_SUCCESS) { 1561*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1562*8f23e9faSHans Rosenfeld &emlxs_attach_failed_msg, 1563*8f23e9faSHans Rosenfeld "(PCI) ddi_regs_map_setup BAR0 failed. " 1564*8f23e9faSHans Rosenfeld "stat=%d mem=%p attr=%p hdl=%p", 1565*8f23e9faSHans Rosenfeld status, &hba->sli.sli4.bar0_addr, &dev_attr, 1566*8f23e9faSHans Rosenfeld &hba->sli.sli4.bar0_acc_handle); 1567*8f23e9faSHans Rosenfeld goto failed; 1568*8f23e9faSHans Rosenfeld } 156982527734SSukumar Swaminathan } 1570*8f23e9faSHans Rosenfeld 1571*8f23e9faSHans Rosenfeld /* offset from beginning of register space */ 1572*8f23e9faSHans Rosenfeld hba->sli.sli4.MPUEPSemaphore_reg_addr = 1573*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1574*8f23e9faSHans Rosenfeld SLIPORT_SEMAPHORE_OFFSET); 1575*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr = 1576*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + PD_MB_DB_OFFSET); 1577*8f23e9faSHans Rosenfeld hba->sli.sli4.CQDB_reg_addr = 1578*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + PD_CQ_DB_OFFSET); 1579*8f23e9faSHans Rosenfeld hba->sli.sli4.MQDB_reg_addr = 1580*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + PD_MQ_DB_OFFSET); 1581*8f23e9faSHans Rosenfeld hba->sli.sli4.WQDB_reg_addr = 1582*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + PD_WQ_DB_OFFSET); 1583*8f23e9faSHans Rosenfeld hba->sli.sli4.RQDB_reg_addr = 1584*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + PD_RQ_DB_OFFSET); 1585*8f23e9faSHans Rosenfeld 1586*8f23e9faSHans Rosenfeld hba->sli.sli4.STATUS_reg_addr = 1587*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1588*8f23e9faSHans Rosenfeld SLIPORT_STATUS_OFFSET); 1589*8f23e9faSHans Rosenfeld hba->sli.sli4.CNTL_reg_addr = 1590*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1591*8f23e9faSHans Rosenfeld SLIPORT_CONTROL_OFFSET); 1592*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr = 1593*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1594*8f23e9faSHans Rosenfeld SLIPORT_ERROR1_OFFSET); 1595*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr = 1596*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1597*8f23e9faSHans Rosenfeld SLIPORT_ERROR2_OFFSET); 1598*8f23e9faSHans Rosenfeld hba->sli.sli4.PHYSDEV_reg_addr = 1599*8f23e9faSHans Rosenfeld (uint32_t *)(hba->sli.sli4.bar0_addr + 1600*8f23e9faSHans Rosenfeld PHYSDEV_CONTROL_OFFSET); 1601*8f23e9faSHans Rosenfeld 1602*8f23e9faSHans Rosenfeld break; 1603*8f23e9faSHans Rosenfeld 1604*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_1: 1605*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_3: 1606*8f23e9faSHans Rosenfeld default: 1607*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1608*8f23e9faSHans Rosenfeld &emlxs_attach_failed_msg, 1609*8f23e9faSHans Rosenfeld "Map hdw: Unsupported if_type %08x", 1610*8f23e9faSHans Rosenfeld (hba->sli_intf & SLI_INTF_IF_TYPE_MASK)); 1611*8f23e9faSHans Rosenfeld 1612*8f23e9faSHans Rosenfeld goto failed; 161382527734SSukumar Swaminathan } 161482527734SSukumar Swaminathan 161582527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt == 0) { 161682527734SSukumar Swaminathan MBUF_INFO *buf_info; 161782527734SSukumar Swaminathan MBUF_INFO bufinfo; 161882527734SSukumar Swaminathan 161982527734SSukumar Swaminathan buf_info = &bufinfo; 162082527734SSukumar Swaminathan 162182527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 162282527734SSukumar Swaminathan buf_info->size = EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE; 162382527734SSukumar Swaminathan buf_info->flags = 162482527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 162582527734SSukumar Swaminathan buf_info->align = ddi_ptob(dip, 1L); 162682527734SSukumar Swaminathan 162782527734SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 162882527734SSukumar Swaminathan 162982527734SSukumar Swaminathan if (buf_info->virt == NULL) { 163082527734SSukumar Swaminathan goto failed; 163182527734SSukumar Swaminathan } 163282527734SSukumar Swaminathan 1633a9800bebSGarrett D'Amore hba->sli.sli4.bootstrapmb.virt = buf_info->virt; 163482527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.phys = buf_info->phys; 163582527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.size = EMLXS_BOOTSTRAP_MB_SIZE + 163682527734SSukumar Swaminathan MBOX_EXTENSION_SIZE; 163782527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle = buf_info->data_handle; 163882527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle = buf_info->dma_handle; 163982527734SSukumar Swaminathan bzero((char *)hba->sli.sli4.bootstrapmb.virt, 164082527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE); 164182527734SSukumar Swaminathan } 164282527734SSukumar Swaminathan 164382527734SSukumar Swaminathan hba->chan_count = MAX_CHANNEL; 164482527734SSukumar Swaminathan 164582527734SSukumar Swaminathan return (0); 164682527734SSukumar Swaminathan 164782527734SSukumar Swaminathan failed: 164882527734SSukumar Swaminathan 164982527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(hba); 165082527734SSukumar Swaminathan return (ENOMEM); 165182527734SSukumar Swaminathan 165282527734SSukumar Swaminathan 165382527734SSukumar Swaminathan } /* emlxs_sli4_map_hdw() */ 165482527734SSukumar Swaminathan 165582527734SSukumar Swaminathan 165682527734SSukumar Swaminathan /*ARGSUSED*/ 165782527734SSukumar Swaminathan static void 165882527734SSukumar Swaminathan emlxs_sli4_unmap_hdw(emlxs_hba_t *hba) 165982527734SSukumar Swaminathan { 166082527734SSukumar Swaminathan MBUF_INFO bufinfo; 166182527734SSukumar Swaminathan MBUF_INFO *buf_info = &bufinfo; 166282527734SSukumar Swaminathan 1663*8f23e9faSHans Rosenfeld 1664*8f23e9faSHans Rosenfeld if (hba->sli.sli4.bar0_acc_handle) { 1665*8f23e9faSHans Rosenfeld ddi_regs_map_free(&hba->sli.sli4.bar0_acc_handle); 1666*8f23e9faSHans Rosenfeld hba->sli.sli4.bar0_acc_handle = 0; 1667*8f23e9faSHans Rosenfeld } 1668*8f23e9faSHans Rosenfeld 166982527734SSukumar Swaminathan if (hba->sli.sli4.bar1_acc_handle) { 167082527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar1_acc_handle); 167182527734SSukumar Swaminathan hba->sli.sli4.bar1_acc_handle = 0; 167282527734SSukumar Swaminathan } 167382527734SSukumar Swaminathan 167482527734SSukumar Swaminathan if (hba->sli.sli4.bar2_acc_handle) { 167582527734SSukumar Swaminathan ddi_regs_map_free(&hba->sli.sli4.bar2_acc_handle); 167682527734SSukumar Swaminathan hba->sli.sli4.bar2_acc_handle = 0; 167782527734SSukumar Swaminathan } 1678*8f23e9faSHans Rosenfeld 167982527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.virt) { 168082527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 168182527734SSukumar Swaminathan 168282527734SSukumar Swaminathan if (hba->sli.sli4.bootstrapmb.phys) { 168382527734SSukumar Swaminathan buf_info->phys = hba->sli.sli4.bootstrapmb.phys; 168482527734SSukumar Swaminathan buf_info->data_handle = 168582527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.data_handle; 168682527734SSukumar Swaminathan buf_info->dma_handle = 168782527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle; 168882527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 168982527734SSukumar Swaminathan } 169082527734SSukumar Swaminathan 1691a9800bebSGarrett D'Amore buf_info->virt = hba->sli.sli4.bootstrapmb.virt; 169282527734SSukumar Swaminathan buf_info->size = hba->sli.sli4.bootstrapmb.size; 169382527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 169482527734SSukumar Swaminathan 1695a9800bebSGarrett D'Amore hba->sli.sli4.bootstrapmb.virt = NULL; 169682527734SSukumar Swaminathan } 169782527734SSukumar Swaminathan 169882527734SSukumar Swaminathan return; 169982527734SSukumar Swaminathan 170082527734SSukumar Swaminathan } /* emlxs_sli4_unmap_hdw() */ 170182527734SSukumar Swaminathan 170282527734SSukumar Swaminathan 170382527734SSukumar Swaminathan static int 170482527734SSukumar Swaminathan emlxs_check_hdw_ready(emlxs_hba_t *hba) 170582527734SSukumar Swaminathan { 170682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 170782527734SSukumar Swaminathan uint32_t status; 170882527734SSukumar Swaminathan uint32_t i = 0; 1709*8f23e9faSHans Rosenfeld uint32_t err1; 1710*8f23e9faSHans Rosenfeld uint32_t err2; 171182527734SSukumar Swaminathan 171282527734SSukumar Swaminathan /* Wait for reset completion */ 171382527734SSukumar Swaminathan while (i < 30) { 171482527734SSukumar Swaminathan 1715*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1716*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1717*8f23e9faSHans Rosenfeld status = emlxs_sli4_read_sema(hba); 171882527734SSukumar Swaminathan 1719*8f23e9faSHans Rosenfeld /* Check to see if any errors occurred during init */ 1720*8f23e9faSHans Rosenfeld if (status & ARM_POST_FATAL) { 1721*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1722*8f23e9faSHans Rosenfeld &emlxs_reset_failed_msg, 1723*8f23e9faSHans Rosenfeld "SEMA Error: status=%x", status); 1724*8f23e9faSHans Rosenfeld 1725*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 1726*8f23e9faSHans Rosenfeld 1727*8f23e9faSHans Rosenfeld return (1); 1728*8f23e9faSHans Rosenfeld } 1729*8f23e9faSHans Rosenfeld 1730*8f23e9faSHans Rosenfeld if ((status & ARM_UNRECOVERABLE_ERROR) == 1731*8f23e9faSHans Rosenfeld ARM_UNRECOVERABLE_ERROR) { 1732*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1733*8f23e9faSHans Rosenfeld &emlxs_reset_failed_msg, 1734*8f23e9faSHans Rosenfeld "Unrecoverable Error: status=%x", status); 1735*8f23e9faSHans Rosenfeld 1736*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 1737*8f23e9faSHans Rosenfeld 1738*8f23e9faSHans Rosenfeld return (1); 1739*8f23e9faSHans Rosenfeld } 1740*8f23e9faSHans Rosenfeld 1741*8f23e9faSHans Rosenfeld if ((status & ARM_POST_MASK) == ARM_POST_READY) { 1742*8f23e9faSHans Rosenfeld /* ARM Ready !! */ 1743*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1744*8f23e9faSHans Rosenfeld &emlxs_sli_detail_msg, 1745*8f23e9faSHans Rosenfeld "ARM Ready: status=%x", status); 1746*8f23e9faSHans Rosenfeld 1747*8f23e9faSHans Rosenfeld return (0); 1748*8f23e9faSHans Rosenfeld } 1749*8f23e9faSHans Rosenfeld break; 1750*8f23e9faSHans Rosenfeld 1751*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1752*8f23e9faSHans Rosenfeld status = emlxs_sli4_read_status(hba); 1753*8f23e9faSHans Rosenfeld 1754*8f23e9faSHans Rosenfeld if (status & SLI_STATUS_READY) { 1755*8f23e9faSHans Rosenfeld if (!(status & SLI_STATUS_ERROR)) { 1756*8f23e9faSHans Rosenfeld /* ARM Ready !! */ 1757*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1758*8f23e9faSHans Rosenfeld &emlxs_sli_detail_msg, 1759*8f23e9faSHans Rosenfeld "ARM Ready: status=%x", status); 1760*8f23e9faSHans Rosenfeld 1761*8f23e9faSHans Rosenfeld return (0); 1762*8f23e9faSHans Rosenfeld } 1763*8f23e9faSHans Rosenfeld 1764*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1765*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 1766*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1767*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 1768*8f23e9faSHans Rosenfeld 1769*8f23e9faSHans Rosenfeld if (status & SLI_STATUS_RESET_NEEDED) { 1770*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1771*8f23e9faSHans Rosenfeld &emlxs_sli_detail_msg, 1772*8f23e9faSHans Rosenfeld "ARM Ready (Reset Needed): " 1773*8f23e9faSHans Rosenfeld "status=%x err1=%x " 1774*8f23e9faSHans Rosenfeld "err2=%x", 1775*8f23e9faSHans Rosenfeld status, err1, err2); 1776*8f23e9faSHans Rosenfeld 1777*8f23e9faSHans Rosenfeld return (1); 1778*8f23e9faSHans Rosenfeld } 1779*8f23e9faSHans Rosenfeld 1780*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 1781*8f23e9faSHans Rosenfeld &emlxs_reset_failed_msg, 1782*8f23e9faSHans Rosenfeld "Unrecoverable Error: status=%x err1=%x " 1783*8f23e9faSHans Rosenfeld "err2=%x", 1784*8f23e9faSHans Rosenfeld status, err1, err2); 1785*8f23e9faSHans Rosenfeld 1786*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 1787*8f23e9faSHans Rosenfeld 1788*8f23e9faSHans Rosenfeld return (2); 1789*8f23e9faSHans Rosenfeld } 1790*8f23e9faSHans Rosenfeld 1791*8f23e9faSHans Rosenfeld break; 1792*8f23e9faSHans Rosenfeld 1793*8f23e9faSHans Rosenfeld default: 1794*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 1795*8f23e9faSHans Rosenfeld 1796*8f23e9faSHans Rosenfeld return (3); 179782527734SSukumar Swaminathan } 179882527734SSukumar Swaminathan 1799*8f23e9faSHans Rosenfeld BUSYWAIT_MS(1000); 180082527734SSukumar Swaminathan i++; 180182527734SSukumar Swaminathan } 180282527734SSukumar Swaminathan 180382527734SSukumar Swaminathan /* Timeout occurred */ 1804*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1805*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1806*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->pci_acc_handle, 1807*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 1808*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->pci_acc_handle, 1809*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 1810*8f23e9faSHans Rosenfeld break; 1811*8f23e9faSHans Rosenfeld 1812*8f23e9faSHans Rosenfeld default: 1813*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1814*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 1815*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1816*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 1817*8f23e9faSHans Rosenfeld break; 1818*8f23e9faSHans Rosenfeld } 1819*8f23e9faSHans Rosenfeld 1820*8f23e9faSHans Rosenfeld if (status & SLI_STATUS_ERROR) { 1821*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1822*8f23e9faSHans Rosenfeld "Ready Timeout: Port Error: status=%x err1=%x err2=%x", 1823*8f23e9faSHans Rosenfeld status, err1, err2); 1824*8f23e9faSHans Rosenfeld } else { 1825*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 1826*8f23e9faSHans Rosenfeld "Ready Timeout: status=%x err1=%x err2=%x", 1827*8f23e9faSHans Rosenfeld status, err1, err2); 1828*8f23e9faSHans Rosenfeld } 182982527734SSukumar Swaminathan 183082527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 183182527734SSukumar Swaminathan 1832*8f23e9faSHans Rosenfeld return (3); 1833*8f23e9faSHans Rosenfeld 1834*8f23e9faSHans Rosenfeld } /* emlxs_check_hdw_ready() */ 1835*8f23e9faSHans Rosenfeld 1836*8f23e9faSHans Rosenfeld 1837*8f23e9faSHans Rosenfeld static uint32_t 1838*8f23e9faSHans Rosenfeld emlxs_sli4_read_status(emlxs_hba_t *hba) 1839*8f23e9faSHans Rosenfeld { 184082527734SSukumar Swaminathan #ifdef FMA_SUPPORT 1841*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 184282527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 1843*8f23e9faSHans Rosenfeld uint32_t status; 184482527734SSukumar Swaminathan 1845*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1846*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1847*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1848*8f23e9faSHans Rosenfeld hba->sli.sli4.STATUS_reg_addr); 1849*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1850*8f23e9faSHans Rosenfeld /* Access handle validation */ 1851*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar0_acc_handle); 1852*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1853*8f23e9faSHans Rosenfeld break; 1854*8f23e9faSHans Rosenfeld default: 1855*8f23e9faSHans Rosenfeld status = 0; 1856*8f23e9faSHans Rosenfeld break; 1857*8f23e9faSHans Rosenfeld } 185882527734SSukumar Swaminathan 1859*8f23e9faSHans Rosenfeld return (status); 186082527734SSukumar Swaminathan 1861*8f23e9faSHans Rosenfeld } /* emlxs_sli4_read_status() */ 186282527734SSukumar Swaminathan 186382527734SSukumar Swaminathan 186482527734SSukumar Swaminathan static uint32_t 1865*8f23e9faSHans Rosenfeld emlxs_sli4_read_sema(emlxs_hba_t *hba) 1866*8f23e9faSHans Rosenfeld { 1867*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1868*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 1869*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1870*8f23e9faSHans Rosenfeld uint32_t status; 1871*8f23e9faSHans Rosenfeld 1872*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1873*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1874*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar1_acc_handle, 1875*8f23e9faSHans Rosenfeld hba->sli.sli4.MPUEPSemaphore_reg_addr); 1876*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1877*8f23e9faSHans Rosenfeld /* Access handle validation */ 1878*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar1_acc_handle); 1879*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1880*8f23e9faSHans Rosenfeld break; 1881*8f23e9faSHans Rosenfeld 1882*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1883*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1884*8f23e9faSHans Rosenfeld hba->sli.sli4.MPUEPSemaphore_reg_addr); 1885*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1886*8f23e9faSHans Rosenfeld /* Access handle validation */ 1887*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar0_acc_handle); 1888*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1889*8f23e9faSHans Rosenfeld break; 1890*8f23e9faSHans Rosenfeld default: 1891*8f23e9faSHans Rosenfeld status = 0; 1892*8f23e9faSHans Rosenfeld break; 1893*8f23e9faSHans Rosenfeld } 1894*8f23e9faSHans Rosenfeld 1895*8f23e9faSHans Rosenfeld return (status); 1896*8f23e9faSHans Rosenfeld 1897*8f23e9faSHans Rosenfeld } /* emlxs_sli4_read_sema() */ 1898*8f23e9faSHans Rosenfeld 1899*8f23e9faSHans Rosenfeld 1900*8f23e9faSHans Rosenfeld static uint32_t 1901*8f23e9faSHans Rosenfeld emlxs_sli4_read_mbdb(emlxs_hba_t *hba) 190282527734SSukumar Swaminathan { 1903*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 190482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 1905*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 190682527734SSukumar Swaminathan uint32_t status; 190782527734SSukumar Swaminathan 1908*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1909*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1910*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar2_acc_handle, 1911*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr); 1912*8f23e9faSHans Rosenfeld 1913*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1914*8f23e9faSHans Rosenfeld /* Access handle validation */ 1915*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar2_acc_handle); 1916*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1917*8f23e9faSHans Rosenfeld break; 1918*8f23e9faSHans Rosenfeld 1919*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1920*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar0_acc_handle, 1921*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr); 1922*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 1923*8f23e9faSHans Rosenfeld /* Access handle validation */ 1924*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli4.bar0_acc_handle); 1925*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 1926*8f23e9faSHans Rosenfeld break; 1927*8f23e9faSHans Rosenfeld default: 1928*8f23e9faSHans Rosenfeld status = 0; 1929*8f23e9faSHans Rosenfeld break; 1930*8f23e9faSHans Rosenfeld } 1931*8f23e9faSHans Rosenfeld 1932*8f23e9faSHans Rosenfeld return (status); 1933*8f23e9faSHans Rosenfeld 1934*8f23e9faSHans Rosenfeld } /* emlxs_sli4_read_mbdb() */ 1935*8f23e9faSHans Rosenfeld 1936*8f23e9faSHans Rosenfeld 1937*8f23e9faSHans Rosenfeld static void 1938*8f23e9faSHans Rosenfeld emlxs_sli4_write_mbdb(emlxs_hba_t *hba, uint32_t value) 1939*8f23e9faSHans Rosenfeld { 1940*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1941*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1942*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar2_acc_handle, 1943*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr, value); 1944*8f23e9faSHans Rosenfeld break; 1945*8f23e9faSHans Rosenfeld 1946*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1947*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 1948*8f23e9faSHans Rosenfeld hba->sli.sli4.MBDB_reg_addr, value); 1949*8f23e9faSHans Rosenfeld break; 1950*8f23e9faSHans Rosenfeld } 1951*8f23e9faSHans Rosenfeld 1952*8f23e9faSHans Rosenfeld } /* emlxs_sli4_write_mbdb() */ 1953*8f23e9faSHans Rosenfeld 1954*8f23e9faSHans Rosenfeld 1955*8f23e9faSHans Rosenfeld static void 1956*8f23e9faSHans Rosenfeld emlxs_sli4_write_cqdb(emlxs_hba_t *hba, uint32_t value) 1957*8f23e9faSHans Rosenfeld { 1958*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1959*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1960*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar2_acc_handle, 1961*8f23e9faSHans Rosenfeld hba->sli.sli4.CQDB_reg_addr, value); 1962*8f23e9faSHans Rosenfeld break; 1963*8f23e9faSHans Rosenfeld 1964*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1965*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 1966*8f23e9faSHans Rosenfeld hba->sli.sli4.CQDB_reg_addr, value); 1967*8f23e9faSHans Rosenfeld break; 1968*8f23e9faSHans Rosenfeld } 1969*8f23e9faSHans Rosenfeld 1970*8f23e9faSHans Rosenfeld } /* emlxs_sli4_write_cqdb() */ 1971*8f23e9faSHans Rosenfeld 1972*8f23e9faSHans Rosenfeld 1973*8f23e9faSHans Rosenfeld static void 1974*8f23e9faSHans Rosenfeld emlxs_sli4_write_rqdb(emlxs_hba_t *hba, uint32_t value) 1975*8f23e9faSHans Rosenfeld { 1976*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1977*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1978*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar2_acc_handle, 1979*8f23e9faSHans Rosenfeld hba->sli.sli4.RQDB_reg_addr, value); 1980*8f23e9faSHans Rosenfeld break; 1981*8f23e9faSHans Rosenfeld 1982*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 1983*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 1984*8f23e9faSHans Rosenfeld hba->sli.sli4.RQDB_reg_addr, value); 1985*8f23e9faSHans Rosenfeld break; 1986*8f23e9faSHans Rosenfeld } 1987*8f23e9faSHans Rosenfeld 1988*8f23e9faSHans Rosenfeld } /* emlxs_sli4_write_rqdb() */ 1989*8f23e9faSHans Rosenfeld 1990*8f23e9faSHans Rosenfeld 1991*8f23e9faSHans Rosenfeld static void 1992*8f23e9faSHans Rosenfeld emlxs_sli4_write_mqdb(emlxs_hba_t *hba, uint32_t value) 1993*8f23e9faSHans Rosenfeld { 1994*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 1995*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 1996*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar2_acc_handle, 1997*8f23e9faSHans Rosenfeld hba->sli.sli4.MQDB_reg_addr, value); 1998*8f23e9faSHans Rosenfeld break; 1999*8f23e9faSHans Rosenfeld 2000*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 2001*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 2002*8f23e9faSHans Rosenfeld hba->sli.sli4.MQDB_reg_addr, value); 2003*8f23e9faSHans Rosenfeld break; 2004*8f23e9faSHans Rosenfeld } 2005*8f23e9faSHans Rosenfeld 2006*8f23e9faSHans Rosenfeld } /* emlxs_sli4_write_mqdb() */ 2007*8f23e9faSHans Rosenfeld 2008*8f23e9faSHans Rosenfeld 2009*8f23e9faSHans Rosenfeld static void 2010*8f23e9faSHans Rosenfeld emlxs_sli4_write_wqdb(emlxs_hba_t *hba, uint32_t value) 2011*8f23e9faSHans Rosenfeld { 2012*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 2013*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 2014*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar2_acc_handle, 2015*8f23e9faSHans Rosenfeld hba->sli.sli4.WQDB_reg_addr, value); 2016*8f23e9faSHans Rosenfeld break; 2017*8f23e9faSHans Rosenfeld 2018*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 2019*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 2020*8f23e9faSHans Rosenfeld hba->sli.sli4.WQDB_reg_addr, value); 2021*8f23e9faSHans Rosenfeld break; 2022*8f23e9faSHans Rosenfeld } 2023*8f23e9faSHans Rosenfeld 2024*8f23e9faSHans Rosenfeld } /* emlxs_sli4_write_wqdb() */ 2025*8f23e9faSHans Rosenfeld 2026*8f23e9faSHans Rosenfeld 2027*8f23e9faSHans Rosenfeld static uint32_t 2028*8f23e9faSHans Rosenfeld emlxs_check_bootstrap_ready(emlxs_hba_t *hba, uint32_t tmo) 2029*8f23e9faSHans Rosenfeld { 2030*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 2031*8f23e9faSHans Rosenfeld uint32_t status = 0; 2032*8f23e9faSHans Rosenfeld uint32_t err1; 2033*8f23e9faSHans Rosenfeld uint32_t err2; 2034*8f23e9faSHans Rosenfeld 203582527734SSukumar Swaminathan /* Wait for reset completion, tmo is in 10ms ticks */ 203682527734SSukumar Swaminathan while (tmo) { 2037*8f23e9faSHans Rosenfeld status = emlxs_sli4_read_mbdb(hba); 203882527734SSukumar Swaminathan 203982527734SSukumar Swaminathan /* Check to see if any errors occurred during init */ 204082527734SSukumar Swaminathan if (status & BMBX_READY) { 2041*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 204282527734SSukumar Swaminathan "BMBX Ready: status=0x%x", status); 2043*8f23e9faSHans Rosenfeld 204482527734SSukumar Swaminathan return (tmo); 204582527734SSukumar Swaminathan } 204682527734SSukumar Swaminathan 2047*8f23e9faSHans Rosenfeld BUSYWAIT_MS(10); 204882527734SSukumar Swaminathan tmo--; 204982527734SSukumar Swaminathan } 205082527734SSukumar Swaminathan 2051*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 2052*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 2053*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->pci_acc_handle, 2054*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 2055*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->pci_acc_handle, 2056*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 2057*8f23e9faSHans Rosenfeld break; 2058*8f23e9faSHans Rosenfeld 2059*8f23e9faSHans Rosenfeld default: 2060*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 2061*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 2062*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 2063*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 2064*8f23e9faSHans Rosenfeld break; 2065*8f23e9faSHans Rosenfeld } 2066*8f23e9faSHans Rosenfeld 206782527734SSukumar Swaminathan /* Timeout occurred */ 206882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 2069*8f23e9faSHans Rosenfeld "Timeout waiting for BMailbox: status=%x err1=%x err2=%x", 2070*8f23e9faSHans Rosenfeld status, err1, err2); 207182527734SSukumar Swaminathan 207282527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 207382527734SSukumar Swaminathan 207482527734SSukumar Swaminathan return (0); 207582527734SSukumar Swaminathan 207682527734SSukumar Swaminathan } /* emlxs_check_bootstrap_ready() */ 207782527734SSukumar Swaminathan 207882527734SSukumar Swaminathan 207982527734SSukumar Swaminathan static uint32_t 208082527734SSukumar Swaminathan emlxs_issue_bootstrap_mb(emlxs_hba_t *hba, uint32_t tmo) 208182527734SSukumar Swaminathan { 208282527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 208382527734SSukumar Swaminathan uint32_t *iptr; 208482527734SSukumar Swaminathan uint32_t addr30; 208582527734SSukumar Swaminathan 208682527734SSukumar Swaminathan /* 208782527734SSukumar Swaminathan * This routine assumes the bootstrap mbox is loaded 208882527734SSukumar Swaminathan * with the mailbox command to be executed. 208982527734SSukumar Swaminathan * 209082527734SSukumar Swaminathan * First, load the high 30 bits of bootstrap mailbox 209182527734SSukumar Swaminathan */ 209282527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>32) & 0xfffffffc); 209382527734SSukumar Swaminathan addr30 |= BMBX_ADDR_HI; 2094*8f23e9faSHans Rosenfeld emlxs_sli4_write_mbdb(hba, addr30); 209582527734SSukumar Swaminathan 209682527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 209782527734SSukumar Swaminathan if (tmo == 0) { 209882527734SSukumar Swaminathan return (0); 209982527734SSukumar Swaminathan } 210082527734SSukumar Swaminathan 210182527734SSukumar Swaminathan /* Load the low 30 bits of bootstrap mailbox */ 210282527734SSukumar Swaminathan addr30 = (uint32_t)((hba->sli.sli4.bootstrapmb.phys>>2) & 0xfffffffc); 2103*8f23e9faSHans Rosenfeld emlxs_sli4_write_mbdb(hba, addr30); 210482527734SSukumar Swaminathan 210582527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, tmo); 210682527734SSukumar Swaminathan if (tmo == 0) { 210782527734SSukumar Swaminathan return (0); 210882527734SSukumar Swaminathan } 210982527734SSukumar Swaminathan 211082527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 211182527734SSukumar Swaminathan 2112*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 211382527734SSukumar Swaminathan "BootstrapMB: %p Completed %08x %08x %08x", 211482527734SSukumar Swaminathan hba->sli.sli4.bootstrapmb.virt, 211582527734SSukumar Swaminathan *iptr, *(iptr+1), *(iptr+2)); 211682527734SSukumar Swaminathan 211782527734SSukumar Swaminathan return (tmo); 211882527734SSukumar Swaminathan 211982527734SSukumar Swaminathan } /* emlxs_issue_bootstrap_mb() */ 212082527734SSukumar Swaminathan 212182527734SSukumar Swaminathan 212282527734SSukumar Swaminathan static int 212382527734SSukumar Swaminathan emlxs_init_bootstrap_mb(emlxs_hba_t *hba) 212482527734SSukumar Swaminathan { 212582527734SSukumar Swaminathan #ifdef FMA_SUPPORT 212682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 212782527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 212882527734SSukumar Swaminathan uint32_t *iptr; 212982527734SSukumar Swaminathan uint32_t tmo; 213082527734SSukumar Swaminathan 213182527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 213282527734SSukumar Swaminathan return (1); 213382527734SSukumar Swaminathan } 213482527734SSukumar Swaminathan 213582527734SSukumar Swaminathan if (hba->flag & FC_BOOTSTRAPMB_INIT) { 213682527734SSukumar Swaminathan return (0); /* Already initialized */ 213782527734SSukumar Swaminathan } 213882527734SSukumar Swaminathan 213982527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 214082527734SSukumar Swaminathan tmo = emlxs_check_bootstrap_ready(hba, 3000); 214182527734SSukumar Swaminathan if (tmo == 0) { 214282527734SSukumar Swaminathan return (1); 214382527734SSukumar Swaminathan } 214482527734SSukumar Swaminathan 2145*8f23e9faSHans Rosenfeld /* Issue FW_INITIALIZE command */ 2146*8f23e9faSHans Rosenfeld 214782527734SSukumar Swaminathan /* Special words to initialize bootstrap mbox MUST be little endian */ 214882527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 2149*8f23e9faSHans Rosenfeld *iptr = LE_SWAP32(FW_INITIALIZE_WORD0); 2150*8f23e9faSHans Rosenfeld *(iptr+1) = LE_SWAP32(FW_INITIALIZE_WORD1); 215182527734SSukumar Swaminathan 215282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 215382527734SSukumar Swaminathan MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV); 215482527734SSukumar Swaminathan 2155*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "FW_INIT", (uint32_t *)iptr, 6, 0); 215682527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 215782527734SSukumar Swaminathan return (1); 215882527734SSukumar Swaminathan } 215982527734SSukumar Swaminathan 2160b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 2161b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, hba->sli.sli4.bootstrapmb.dma_handle) 2162b3660a96SSukumar Swaminathan != DDI_FM_OK) { 2163b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 2164b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 2165*8f23e9faSHans Rosenfeld "init_bootstrap_mb: hdl=%p", 2166b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle); 2167b3660a96SSukumar Swaminathan return (1); 2168b3660a96SSukumar Swaminathan } 2169b3660a96SSukumar Swaminathan #endif 217082527734SSukumar Swaminathan hba->flag |= FC_BOOTSTRAPMB_INIT; 217182527734SSukumar Swaminathan return (0); 217282527734SSukumar Swaminathan 217382527734SSukumar Swaminathan } /* emlxs_init_bootstrap_mb() */ 217482527734SSukumar Swaminathan 217582527734SSukumar Swaminathan 2176*8f23e9faSHans Rosenfeld 2177*8f23e9faSHans Rosenfeld 217882527734SSukumar Swaminathan static uint32_t 217982527734SSukumar Swaminathan emlxs_sli4_hba_init(emlxs_hba_t *hba) 218082527734SSukumar Swaminathan { 218182527734SSukumar Swaminathan int rc; 2182a9800bebSGarrett D'Amore uint16_t i; 218382527734SSukumar Swaminathan emlxs_port_t *vport; 218482527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 218582527734SSukumar Swaminathan CHANNEL *cp; 2186*8f23e9faSHans Rosenfeld VPIobj_t *vpip; 218782527734SSukumar Swaminathan 218882527734SSukumar Swaminathan /* Restart the adapter */ 218982527734SSukumar Swaminathan if (emlxs_sli4_hba_reset(hba, 1, 0, 0)) { 219082527734SSukumar Swaminathan return (1); 219182527734SSukumar Swaminathan } 219282527734SSukumar Swaminathan 219382527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 219482527734SSukumar Swaminathan cp = &hba->chan[i]; 219582527734SSukumar Swaminathan cp->iopath = (void *)&hba->sli.sli4.wq[i]; 219682527734SSukumar Swaminathan } 219782527734SSukumar Swaminathan 219882527734SSukumar Swaminathan /* Initialize all the port objects */ 219982527734SSukumar Swaminathan hba->vpi_max = 0; 220082527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 220182527734SSukumar Swaminathan vport = &VPORT(i); 220282527734SSukumar Swaminathan vport->hba = hba; 220382527734SSukumar Swaminathan vport->vpi = i; 2204a9800bebSGarrett D'Amore 2205*8f23e9faSHans Rosenfeld vpip = &vport->VPIobj; 2206*8f23e9faSHans Rosenfeld vpip->index = i; 2207*8f23e9faSHans Rosenfeld vpip->VPI = i; 2208*8f23e9faSHans Rosenfeld vpip->port = vport; 2209*8f23e9faSHans Rosenfeld vpip->state = VPI_STATE_OFFLINE; 2210*8f23e9faSHans Rosenfeld vport->vpip = vpip; 221182527734SSukumar Swaminathan } 221282527734SSukumar Swaminathan 221382527734SSukumar Swaminathan /* Set the max node count */ 221482527734SSukumar Swaminathan if (hba->max_nodes == 0) { 221582527734SSukumar Swaminathan if (cfg[CFG_NUM_NODES].current > 0) { 221682527734SSukumar Swaminathan hba->max_nodes = cfg[CFG_NUM_NODES].current; 221782527734SSukumar Swaminathan } else { 221882527734SSukumar Swaminathan hba->max_nodes = 4096; 221982527734SSukumar Swaminathan } 222082527734SSukumar Swaminathan } 222182527734SSukumar Swaminathan 222282527734SSukumar Swaminathan rc = emlxs_init_bootstrap_mb(hba); 222382527734SSukumar Swaminathan if (rc) { 222482527734SSukumar Swaminathan return (rc); 222582527734SSukumar Swaminathan } 222682527734SSukumar Swaminathan 222782527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[0] = FCOE_FCF_MAP0; 222882527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[1] = FCOE_FCF_MAP1; 222982527734SSukumar Swaminathan hba->sli.sli4.cfgFCOE.FCMap[2] = FCOE_FCF_MAP2; 223082527734SSukumar Swaminathan 2231*8f23e9faSHans Rosenfeld if ((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) == SLI_INTF_IF_TYPE_0) { 2232*8f23e9faSHans Rosenfeld /* Cache the UE MASK registers value for UE error detection */ 2233*8f23e9faSHans Rosenfeld hba->sli.sli4.ue_mask_lo = ddi_get32(hba->pci_acc_handle, 2234*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_LO_OFFSET)); 2235*8f23e9faSHans Rosenfeld hba->sli.sli4.ue_mask_hi = ddi_get32(hba->pci_acc_handle, 2236*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_MASK_HI_OFFSET)); 2237*8f23e9faSHans Rosenfeld } 2238fe199829SSukumar Swaminathan 223982527734SSukumar Swaminathan return (0); 224082527734SSukumar Swaminathan 224182527734SSukumar Swaminathan } /* emlxs_sli4_hba_init() */ 224282527734SSukumar Swaminathan 224382527734SSukumar Swaminathan 224482527734SSukumar Swaminathan /*ARGSUSED*/ 224582527734SSukumar Swaminathan static uint32_t 224682527734SSukumar Swaminathan emlxs_sli4_hba_reset(emlxs_hba_t *hba, uint32_t restart, uint32_t skip_post, 224782527734SSukumar Swaminathan uint32_t quiesce) 224882527734SSukumar Swaminathan { 224982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 225082527734SSukumar Swaminathan emlxs_port_t *vport; 225182527734SSukumar Swaminathan CHANNEL *cp; 225282527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 225382527734SSukumar Swaminathan MAILBOXQ mboxq; 2254*8f23e9faSHans Rosenfeld uint32_t value; 225582527734SSukumar Swaminathan uint32_t i; 225682527734SSukumar Swaminathan uint32_t rc; 2257a9800bebSGarrett D'Amore uint16_t channelno; 2258*8f23e9faSHans Rosenfeld uint32_t status; 2259*8f23e9faSHans Rosenfeld uint32_t err1; 2260*8f23e9faSHans Rosenfeld uint32_t err2; 2261*8f23e9faSHans Rosenfeld uint8_t generate_event = 0; 226282527734SSukumar Swaminathan 226382527734SSukumar Swaminathan if (!cfg[CFG_RESET_ENABLE].current) { 226482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg, 226582527734SSukumar Swaminathan "Adapter reset disabled."); 226682527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 226782527734SSukumar Swaminathan 226882527734SSukumar Swaminathan return (1); 226982527734SSukumar Swaminathan } 227082527734SSukumar Swaminathan 2271*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 2272*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 2273*8f23e9faSHans Rosenfeld if (quiesce == 0) { 2274*8f23e9faSHans Rosenfeld emlxs_sli4_hba_kill(hba); 227582527734SSukumar Swaminathan 2276*8f23e9faSHans Rosenfeld /* 2277*8f23e9faSHans Rosenfeld * Initalize Hardware that will be used to bring 2278*8f23e9faSHans Rosenfeld * SLI4 online. 2279*8f23e9faSHans Rosenfeld */ 2280*8f23e9faSHans Rosenfeld rc = emlxs_init_bootstrap_mb(hba); 2281*8f23e9faSHans Rosenfeld if (rc) { 2282*8f23e9faSHans Rosenfeld return (rc); 2283*8f23e9faSHans Rosenfeld } 228482527734SSukumar Swaminathan } 228582527734SSukumar Swaminathan 2286*8f23e9faSHans Rosenfeld bzero((void *)&mboxq, sizeof (MAILBOXQ)); 2287*8f23e9faSHans Rosenfeld emlxs_mb_resetport(hba, &mboxq); 228882527734SSukumar Swaminathan 2289*8f23e9faSHans Rosenfeld if (quiesce == 0) { 2290*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, &mboxq, 2291*8f23e9faSHans Rosenfeld MBX_POLL, 0) != MBX_SUCCESS) { 2292*8f23e9faSHans Rosenfeld /* Timeout occurred */ 2293*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 2294*8f23e9faSHans Rosenfeld &emlxs_reset_failed_msg, 2295*8f23e9faSHans Rosenfeld "Timeout: RESET"); 2296*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 2297*8f23e9faSHans Rosenfeld /* Log a dump event - not supported */ 2298*8f23e9faSHans Rosenfeld return (1); 2299*8f23e9faSHans Rosenfeld } 2300*8f23e9faSHans Rosenfeld } else { 2301*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd4quiesce(hba, &mboxq, 2302*8f23e9faSHans Rosenfeld MBX_POLL, 0) != MBX_SUCCESS) { 2303*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 2304*8f23e9faSHans Rosenfeld /* Log a dump event - not supported */ 2305*8f23e9faSHans Rosenfeld return (1); 2306*8f23e9faSHans Rosenfeld } 230782527734SSukumar Swaminathan } 2308*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "resetPort", (uint32_t *)&mboxq, 12, 0); 2309*8f23e9faSHans Rosenfeld break; 2310*8f23e9faSHans Rosenfeld 2311*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 2312*8f23e9faSHans Rosenfeld if (quiesce == 0) { 2313*8f23e9faSHans Rosenfeld emlxs_sli4_hba_kill(hba); 2314*8f23e9faSHans Rosenfeld } 2315*8f23e9faSHans Rosenfeld 2316*8f23e9faSHans Rosenfeld rc = emlxs_check_hdw_ready(hba); 2317*8f23e9faSHans Rosenfeld if (rc > 1) { 2318*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 2319*8f23e9faSHans Rosenfeld "Adapter not ready for reset."); 232082527734SSukumar Swaminathan return (1); 232182527734SSukumar Swaminathan } 2322*8f23e9faSHans Rosenfeld 2323*8f23e9faSHans Rosenfeld if (rc == 1) { 2324*8f23e9faSHans Rosenfeld err1 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 2325*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 2326*8f23e9faSHans Rosenfeld err2 = ddi_get32(hba->sli.sli4.bar0_acc_handle, 2327*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 2328*8f23e9faSHans Rosenfeld 2329*8f23e9faSHans Rosenfeld /* Don't generate an event if dump was forced */ 2330*8f23e9faSHans Rosenfeld if ((err1 != 0x2) || (err2 != 0x2)) { 2331*8f23e9faSHans Rosenfeld generate_event = 1; 2332*8f23e9faSHans Rosenfeld } 2333*8f23e9faSHans Rosenfeld } 2334*8f23e9faSHans Rosenfeld 2335*8f23e9faSHans Rosenfeld /* Reset the port now */ 2336*8f23e9faSHans Rosenfeld 2337*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 2338*8f23e9faSHans Rosenfeld value = SLI_CNTL_INIT_PORT; 2339*8f23e9faSHans Rosenfeld 2340*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 2341*8f23e9faSHans Rosenfeld hba->sli.sli4.CNTL_reg_addr, value); 2342*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 2343*8f23e9faSHans Rosenfeld 2344*8f23e9faSHans Rosenfeld break; 234582527734SSukumar Swaminathan } 234682527734SSukumar Swaminathan 234782527734SSukumar Swaminathan /* Reset the hba structure */ 234882527734SSukumar Swaminathan hba->flag &= FC_RESET_MASK; 234982527734SSukumar Swaminathan 235082527734SSukumar Swaminathan for (channelno = 0; channelno < hba->chan_count; channelno++) { 235182527734SSukumar Swaminathan cp = &hba->chan[channelno]; 235282527734SSukumar Swaminathan cp->hba = hba; 235382527734SSukumar Swaminathan cp->channelno = channelno; 235482527734SSukumar Swaminathan } 235582527734SSukumar Swaminathan 235682527734SSukumar Swaminathan hba->channel_tx_count = 0; 235782527734SSukumar Swaminathan hba->io_count = 0; 235882527734SSukumar Swaminathan hba->iodone_count = 0; 235982527734SSukumar Swaminathan hba->topology = 0; 236082527734SSukumar Swaminathan hba->linkspeed = 0; 236182527734SSukumar Swaminathan hba->heartbeat_active = 0; 236282527734SSukumar Swaminathan hba->discovery_timer = 0; 236382527734SSukumar Swaminathan hba->linkup_timer = 0; 236482527734SSukumar Swaminathan hba->loopback_tics = 0; 236582527734SSukumar Swaminathan 236682527734SSukumar Swaminathan /* Reset the port objects */ 236782527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 236882527734SSukumar Swaminathan vport = &VPORT(i); 236982527734SSukumar Swaminathan 237082527734SSukumar Swaminathan vport->flag &= EMLXS_PORT_RESET_MASK; 237182527734SSukumar Swaminathan vport->did = 0; 237282527734SSukumar Swaminathan vport->prev_did = 0; 237382527734SSukumar Swaminathan vport->lip_type = 0; 237482527734SSukumar Swaminathan bzero(&vport->fabric_sparam, sizeof (SERV_PARM)); 2375a9800bebSGarrett D'Amore bzero(&vport->prev_fabric_sparam, sizeof (SERV_PARM)); 237682527734SSukumar Swaminathan 237782527734SSukumar Swaminathan bzero((caddr_t)&vport->node_base, sizeof (NODELIST)); 237882527734SSukumar Swaminathan vport->node_base.nlp_Rpi = 0; 237982527734SSukumar Swaminathan vport->node_base.nlp_DID = 0xffffff; 238082527734SSukumar Swaminathan vport->node_base.nlp_list_next = NULL; 238182527734SSukumar Swaminathan vport->node_base.nlp_list_prev = NULL; 238282527734SSukumar Swaminathan vport->node_base.nlp_active = 1; 238382527734SSukumar Swaminathan vport->node_count = 0; 238482527734SSukumar Swaminathan 238582527734SSukumar Swaminathan if (vport->ub_count < EMLXS_UB_TOKEN_OFFSET) { 238682527734SSukumar Swaminathan vport->ub_count = EMLXS_UB_TOKEN_OFFSET; 238782527734SSukumar Swaminathan } 238882527734SSukumar Swaminathan } 238982527734SSukumar Swaminathan 239082527734SSukumar Swaminathan if (emlxs_check_hdw_ready(hba)) { 239182527734SSukumar Swaminathan return (1); 239282527734SSukumar Swaminathan } 239382527734SSukumar Swaminathan 2394*8f23e9faSHans Rosenfeld if (generate_event) { 2395*8f23e9faSHans Rosenfeld status = emlxs_sli4_read_status(hba); 2396*8f23e9faSHans Rosenfeld if (status & SLI_STATUS_DUMP_IMAGE_PRESENT) { 2397*8f23e9faSHans Rosenfeld emlxs_log_dump_event(port, NULL, 0); 2398*8f23e9faSHans Rosenfeld } 2399*8f23e9faSHans Rosenfeld } 2400*8f23e9faSHans Rosenfeld 240182527734SSukumar Swaminathan return (0); 240282527734SSukumar Swaminathan 240382527734SSukumar Swaminathan } /* emlxs_sli4_hba_reset */ 240482527734SSukumar Swaminathan 240582527734SSukumar Swaminathan 240682527734SSukumar Swaminathan #define SGL_CMD 0 240782527734SSukumar Swaminathan #define SGL_RESP 1 240882527734SSukumar Swaminathan #define SGL_DATA 2 240982527734SSukumar Swaminathan #define SGL_LAST 0x80 241082527734SSukumar Swaminathan 241182527734SSukumar Swaminathan /*ARGSUSED*/ 2412*8f23e9faSHans Rosenfeld static ULP_SGE64 * 2413*8f23e9faSHans Rosenfeld emlxs_pkt_to_sgl(emlxs_port_t *port, fc_packet_t *pkt, ULP_SGE64 *sge, 241482527734SSukumar Swaminathan uint32_t sgl_type, uint32_t *pcnt) 241582527734SSukumar Swaminathan { 241682527734SSukumar Swaminathan #ifdef DEBUG_SGE 241782527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 2418*8f23e9faSHans Rosenfeld #endif /* DEBUG_SGE */ 241982527734SSukumar Swaminathan ddi_dma_cookie_t *cp; 242082527734SSukumar Swaminathan uint_t i; 242182527734SSukumar Swaminathan uint_t last; 242282527734SSukumar Swaminathan int32_t size; 242382527734SSukumar Swaminathan int32_t sge_size; 242482527734SSukumar Swaminathan uint64_t sge_addr; 242582527734SSukumar Swaminathan int32_t len; 242682527734SSukumar Swaminathan uint32_t cnt; 242782527734SSukumar Swaminathan uint_t cookie_cnt; 242882527734SSukumar Swaminathan ULP_SGE64 stage_sge; 242982527734SSukumar Swaminathan 243082527734SSukumar Swaminathan last = sgl_type & SGL_LAST; 243182527734SSukumar Swaminathan sgl_type &= ~SGL_LAST; 243282527734SSukumar Swaminathan 243382527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 243482527734SSukumar Swaminathan switch (sgl_type) { 243582527734SSukumar Swaminathan case SGL_CMD: 243682527734SSukumar Swaminathan cp = pkt->pkt_cmd_cookie; 243782527734SSukumar Swaminathan cookie_cnt = pkt->pkt_cmd_cookie_cnt; 243882527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 243982527734SSukumar Swaminathan break; 244082527734SSukumar Swaminathan 244182527734SSukumar Swaminathan case SGL_RESP: 244282527734SSukumar Swaminathan cp = pkt->pkt_resp_cookie; 244382527734SSukumar Swaminathan cookie_cnt = pkt->pkt_resp_cookie_cnt; 244482527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 244582527734SSukumar Swaminathan break; 244682527734SSukumar Swaminathan 244782527734SSukumar Swaminathan 244882527734SSukumar Swaminathan case SGL_DATA: 244982527734SSukumar Swaminathan cp = pkt->pkt_data_cookie; 245082527734SSukumar Swaminathan cookie_cnt = pkt->pkt_data_cookie_cnt; 245182527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 245282527734SSukumar Swaminathan break; 2453*8f23e9faSHans Rosenfeld 2454*8f23e9faSHans Rosenfeld default: 2455*8f23e9faSHans Rosenfeld return (NULL); 245682527734SSukumar Swaminathan } 245782527734SSukumar Swaminathan 245882527734SSukumar Swaminathan #else 245982527734SSukumar Swaminathan switch (sgl_type) { 246082527734SSukumar Swaminathan case SGL_CMD: 246182527734SSukumar Swaminathan cp = &pkt->pkt_cmd_cookie; 246282527734SSukumar Swaminathan cookie_cnt = 1; 246382527734SSukumar Swaminathan size = (int32_t)pkt->pkt_cmdlen; 246482527734SSukumar Swaminathan break; 246582527734SSukumar Swaminathan 246682527734SSukumar Swaminathan case SGL_RESP: 246782527734SSukumar Swaminathan cp = &pkt->pkt_resp_cookie; 246882527734SSukumar Swaminathan cookie_cnt = 1; 246982527734SSukumar Swaminathan size = (int32_t)pkt->pkt_rsplen; 247082527734SSukumar Swaminathan break; 247182527734SSukumar Swaminathan 247282527734SSukumar Swaminathan 247382527734SSukumar Swaminathan case SGL_DATA: 247482527734SSukumar Swaminathan cp = &pkt->pkt_data_cookie; 247582527734SSukumar Swaminathan cookie_cnt = 1; 247682527734SSukumar Swaminathan size = (int32_t)pkt->pkt_datalen; 247782527734SSukumar Swaminathan break; 2478*8f23e9faSHans Rosenfeld 2479*8f23e9faSHans Rosenfeld default: 2480*8f23e9faSHans Rosenfeld return (NULL); 248182527734SSukumar Swaminathan } 248282527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 248382527734SSukumar Swaminathan 248482527734SSukumar Swaminathan stage_sge.offset = 0; 2485*8f23e9faSHans Rosenfeld stage_sge.type = 0; 248682527734SSukumar Swaminathan stage_sge.last = 0; 248782527734SSukumar Swaminathan cnt = 0; 248882527734SSukumar Swaminathan for (i = 0; i < cookie_cnt && size > 0; i++, cp++) { 248982527734SSukumar Swaminathan 249082527734SSukumar Swaminathan sge_size = cp->dmac_size; 249182527734SSukumar Swaminathan sge_addr = cp->dmac_laddress; 249282527734SSukumar Swaminathan while (sge_size && size) { 249382527734SSukumar Swaminathan if (cnt) { 249482527734SSukumar Swaminathan /* Copy staged SGE before we build next one */ 249582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 249682527734SSukumar Swaminathan (uint8_t *)sge, sizeof (ULP_SGE64)); 249782527734SSukumar Swaminathan sge++; 249882527734SSukumar Swaminathan } 249982527734SSukumar Swaminathan len = MIN(EMLXS_MAX_SGE_SIZE, sge_size); 250082527734SSukumar Swaminathan len = MIN(size, len); 250182527734SSukumar Swaminathan 250282527734SSukumar Swaminathan stage_sge.addrHigh = 250382527734SSukumar Swaminathan PADDR_HI(sge_addr); 250482527734SSukumar Swaminathan stage_sge.addrLow = 250582527734SSukumar Swaminathan PADDR_LO(sge_addr); 250682527734SSukumar Swaminathan stage_sge.length = len; 250782527734SSukumar Swaminathan if (sgl_type == SGL_DATA) { 250882527734SSukumar Swaminathan stage_sge.offset = cnt; 250982527734SSukumar Swaminathan } 251082527734SSukumar Swaminathan #ifdef DEBUG_SGE 2511a9800bebSGarrett D'Amore emlxs_data_dump(port, "SGE", (uint32_t *)&stage_sge, 251282527734SSukumar Swaminathan 4, 0); 2513*8f23e9faSHans Rosenfeld #endif /* DEBUG_SGE */ 251482527734SSukumar Swaminathan sge_addr += len; 251582527734SSukumar Swaminathan sge_size -= len; 251682527734SSukumar Swaminathan 251782527734SSukumar Swaminathan cnt += len; 251882527734SSukumar Swaminathan size -= len; 251982527734SSukumar Swaminathan } 252082527734SSukumar Swaminathan } 252182527734SSukumar Swaminathan 252282527734SSukumar Swaminathan if (last) { 252382527734SSukumar Swaminathan stage_sge.last = 1; 252482527734SSukumar Swaminathan } 252582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 252682527734SSukumar Swaminathan sizeof (ULP_SGE64)); 2527a9800bebSGarrett D'Amore 252882527734SSukumar Swaminathan sge++; 252982527734SSukumar Swaminathan 2530*8f23e9faSHans Rosenfeld if (pcnt) { 2531*8f23e9faSHans Rosenfeld *pcnt = cnt; 2532*8f23e9faSHans Rosenfeld } 253382527734SSukumar Swaminathan return (sge); 253482527734SSukumar Swaminathan 253582527734SSukumar Swaminathan } /* emlxs_pkt_to_sgl */ 253682527734SSukumar Swaminathan 253782527734SSukumar Swaminathan 253882527734SSukumar Swaminathan /*ARGSUSED*/ 253982527734SSukumar Swaminathan uint32_t 254082527734SSukumar Swaminathan emlxs_sli4_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp) 254182527734SSukumar Swaminathan { 2542*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 254382527734SSukumar Swaminathan fc_packet_t *pkt; 2544a9800bebSGarrett D'Amore XRIobj_t *xrip; 254582527734SSukumar Swaminathan ULP_SGE64 *sge; 254682527734SSukumar Swaminathan emlxs_wqe_t *wqe; 254782527734SSukumar Swaminathan IOCBQ *iocbq; 254882527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 2549*8f23e9faSHans Rosenfeld ddi_dma_cookie_t *cp_data; 2550*8f23e9faSHans Rosenfeld uint64_t sge_addr; 255182527734SSukumar Swaminathan uint32_t cmd_cnt; 255282527734SSukumar Swaminathan uint32_t resp_cnt; 255382527734SSukumar Swaminathan 255482527734SSukumar Swaminathan iocbq = (IOCBQ *) &sbp->iocbq; 255582527734SSukumar Swaminathan wqe = &iocbq->wqe; 255682527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 2557a9800bebSGarrett D'Amore xrip = sbp->xrip; 2558a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 255982527734SSukumar Swaminathan 256082527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 256182527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 2562*8f23e9faSHans Rosenfeld cp_data = pkt->pkt_data_cookie; 256382527734SSukumar Swaminathan #else 256482527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 2565*8f23e9faSHans Rosenfeld cp_data = &pkt->pkt_data_cookie; 256682527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 256782527734SSukumar Swaminathan 256882527734SSukumar Swaminathan iocbq = &sbp->iocbq; 256982527734SSukumar Swaminathan if (iocbq->flag & IOCB_FCP_CMD) { 257082527734SSukumar Swaminathan 257182527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 257282527734SSukumar Swaminathan return (1); 257382527734SSukumar Swaminathan } 257482527734SSukumar Swaminathan 257582527734SSukumar Swaminathan /* CMD payload */ 2576*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, SGL_CMD, &cmd_cnt); 2577*8f23e9faSHans Rosenfeld if (! sge) { 2578*8f23e9faSHans Rosenfeld return (1); 2579*8f23e9faSHans Rosenfeld } 258082527734SSukumar Swaminathan 258182527734SSukumar Swaminathan /* DATA payload */ 258282527734SSukumar Swaminathan if (pkt->pkt_datalen != 0) { 258382527734SSukumar Swaminathan /* RSP payload */ 2584*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 258582527734SSukumar Swaminathan SGL_RESP, &resp_cnt); 2586*8f23e9faSHans Rosenfeld if (! sge) { 2587*8f23e9faSHans Rosenfeld return (1); 2588*8f23e9faSHans Rosenfeld } 258982527734SSukumar Swaminathan 2590*8f23e9faSHans Rosenfeld /* Data payload */ 2591*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 2592*8f23e9faSHans Rosenfeld SGL_DATA | SGL_LAST, 0); 2593*8f23e9faSHans Rosenfeld if (! sge) { 2594*8f23e9faSHans Rosenfeld return (1); 2595*8f23e9faSHans Rosenfeld } 2596*8f23e9faSHans Rosenfeld sgl_done: 2597*8f23e9faSHans Rosenfeld if (hba->sli.sli4.flag & EMLXS_SLI4_PHON) { 2598*8f23e9faSHans Rosenfeld sge_addr = cp_data->dmac_laddress; 2599*8f23e9faSHans Rosenfeld wqe->FirstData.addrHigh = PADDR_HI(sge_addr); 2600*8f23e9faSHans Rosenfeld wqe->FirstData.addrLow = PADDR_LO(sge_addr); 2601*8f23e9faSHans Rosenfeld wqe->FirstData.tus.f.bdeSize = 2602*8f23e9faSHans Rosenfeld cp_data->dmac_size; 2603*8f23e9faSHans Rosenfeld } 260482527734SSukumar Swaminathan } else { 260582527734SSukumar Swaminathan /* RSP payload */ 2606*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 260782527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 2608*8f23e9faSHans Rosenfeld if (! sge) { 2609*8f23e9faSHans Rosenfeld return (1); 2610*8f23e9faSHans Rosenfeld } 261182527734SSukumar Swaminathan } 261282527734SSukumar Swaminathan 261382527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrHigh = 261482527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 261582527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.addrLow = 261682527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 261782527734SSukumar Swaminathan wqe->un.FcpCmd.Payload.tus.f.bdeSize = cmd_cnt; 261882527734SSukumar Swaminathan wqe->un.FcpCmd.PayloadLength = cmd_cnt + resp_cnt; 261982527734SSukumar Swaminathan 262082527734SSukumar Swaminathan } else { 262182527734SSukumar Swaminathan 262282527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 262382527734SSukumar Swaminathan /* CMD payload */ 2624*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 262582527734SSukumar Swaminathan SGL_CMD | SGL_LAST, &cmd_cnt); 2626*8f23e9faSHans Rosenfeld if (! sge) { 2627*8f23e9faSHans Rosenfeld return (1); 2628*8f23e9faSHans Rosenfeld } 262982527734SSukumar Swaminathan } else { 263082527734SSukumar Swaminathan /* CMD payload */ 2631*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 263282527734SSukumar Swaminathan SGL_CMD, &cmd_cnt); 2633*8f23e9faSHans Rosenfeld if (! sge) { 2634*8f23e9faSHans Rosenfeld return (1); 2635*8f23e9faSHans Rosenfeld } 263682527734SSukumar Swaminathan 263782527734SSukumar Swaminathan /* RSP payload */ 2638*8f23e9faSHans Rosenfeld sge = emlxs_pkt_to_sgl(port, pkt, sge, 263982527734SSukumar Swaminathan SGL_RESP | SGL_LAST, &resp_cnt); 2640*8f23e9faSHans Rosenfeld if (! sge) { 2641*8f23e9faSHans Rosenfeld return (1); 2642*8f23e9faSHans Rosenfeld } 264382527734SSukumar Swaminathan wqe->un.GenReq.PayloadLength = cmd_cnt; 264482527734SSukumar Swaminathan } 264582527734SSukumar Swaminathan 264682527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrHigh = 264782527734SSukumar Swaminathan PADDR_HI(cp_cmd->dmac_laddress); 264882527734SSukumar Swaminathan wqe->un.GenReq.Payload.addrLow = 264982527734SSukumar Swaminathan PADDR_LO(cp_cmd->dmac_laddress); 265082527734SSukumar Swaminathan wqe->un.GenReq.Payload.tus.f.bdeSize = cmd_cnt; 265182527734SSukumar Swaminathan } 265282527734SSukumar Swaminathan return (0); 265382527734SSukumar Swaminathan } /* emlxs_sli4_bde_setup */ 265482527734SSukumar Swaminathan 265582527734SSukumar Swaminathan 265682527734SSukumar Swaminathan 265782527734SSukumar Swaminathan 2658*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 2659*8f23e9faSHans Rosenfeld /*ARGSUSED*/ 2660*8f23e9faSHans Rosenfeld static uint32_t 2661*8f23e9faSHans Rosenfeld emlxs_sli4_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp) 266282527734SSukumar Swaminathan { 2663*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 266482527734SSukumar Swaminathan emlxs_wqe_t *wqe; 2665*8f23e9faSHans Rosenfeld ULP_SGE64 stage_sge; 2666*8f23e9faSHans Rosenfeld ULP_SGE64 *sge; 2667*8f23e9faSHans Rosenfeld IOCB *iocb; 2668*8f23e9faSHans Rosenfeld IOCBQ *iocbq; 2669*8f23e9faSHans Rosenfeld MATCHMAP *mp; 2670*8f23e9faSHans Rosenfeld MATCHMAP *fct_mp; 2671*8f23e9faSHans Rosenfeld XRIobj_t *xrip; 2672*8f23e9faSHans Rosenfeld uint64_t sge_addr; 2673*8f23e9faSHans Rosenfeld uint32_t sge_size; 2674*8f23e9faSHans Rosenfeld uint32_t cnt; 2675*8f23e9faSHans Rosenfeld uint32_t len; 2676*8f23e9faSHans Rosenfeld uint32_t size; 2677*8f23e9faSHans Rosenfeld uint32_t *xrdy_vaddr; 2678*8f23e9faSHans Rosenfeld stmf_data_buf_t *dbuf; 2679*8f23e9faSHans Rosenfeld 2680*8f23e9faSHans Rosenfeld iocbq = &sbp->iocbq; 2681*8f23e9faSHans Rosenfeld iocb = &iocbq->iocb; 2682*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 2683*8f23e9faSHans Rosenfeld xrip = sbp->xrip; 2684*8f23e9faSHans Rosenfeld 2685*8f23e9faSHans Rosenfeld if (!sbp->fct_buf) { 2686*8f23e9faSHans Rosenfeld return (0); 2687*8f23e9faSHans Rosenfeld } 2688*8f23e9faSHans Rosenfeld 2689*8f23e9faSHans Rosenfeld size = sbp->fct_buf->db_data_size; 2690*8f23e9faSHans Rosenfeld 2691*8f23e9faSHans Rosenfeld /* 2692*8f23e9faSHans Rosenfeld * The hardware will automaticlly round up 2693*8f23e9faSHans Rosenfeld * to multiple of 4. 2694*8f23e9faSHans Rosenfeld * 2695*8f23e9faSHans Rosenfeld * if (size & 3) { 2696*8f23e9faSHans Rosenfeld * size = (size + 3) & 0xfffffffc; 2697*8f23e9faSHans Rosenfeld * } 2698*8f23e9faSHans Rosenfeld */ 2699*8f23e9faSHans Rosenfeld fct_mp = (MATCHMAP *)sbp->fct_buf->db_port_private; 2700*8f23e9faSHans Rosenfeld 2701*8f23e9faSHans Rosenfeld if (sbp->fct_buf->db_sglist_length != 1) { 2702*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2703*8f23e9faSHans Rosenfeld "fct_bde_setup: Only 1 sglist entry supported: %d", 2704*8f23e9faSHans Rosenfeld sbp->fct_buf->db_sglist_length); 2705*8f23e9faSHans Rosenfeld return (1); 2706*8f23e9faSHans Rosenfeld } 2707*8f23e9faSHans Rosenfeld 2708*8f23e9faSHans Rosenfeld sge = xrip->SGList.virt; 2709*8f23e9faSHans Rosenfeld 2710*8f23e9faSHans Rosenfeld if (iocb->ULPCOMMAND == CMD_FCP_TRECEIVE64_CX) { 2711*8f23e9faSHans Rosenfeld 2712*8f23e9faSHans Rosenfeld mp = emlxs_mem_buf_alloc(hba, EMLXS_XFER_RDY_SIZE); 2713*8f23e9faSHans Rosenfeld if (!mp || !mp->virt || !mp->phys) { 2714*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg, 2715*8f23e9faSHans Rosenfeld "fct_bde_setup: Cannot allocate XRDY memory"); 2716*8f23e9faSHans Rosenfeld return (1); 2717*8f23e9faSHans Rosenfeld } 2718*8f23e9faSHans Rosenfeld /* Save the MATCHMAP info to free this memory later */ 2719*8f23e9faSHans Rosenfeld iocbq->bp = mp; 2720*8f23e9faSHans Rosenfeld 2721*8f23e9faSHans Rosenfeld /* Point to XRDY payload */ 2722*8f23e9faSHans Rosenfeld xrdy_vaddr = (uint32_t *)(mp->virt); 2723*8f23e9faSHans Rosenfeld 2724*8f23e9faSHans Rosenfeld /* Fill in burstsize in payload */ 2725*8f23e9faSHans Rosenfeld *xrdy_vaddr++ = 0; 2726*8f23e9faSHans Rosenfeld *xrdy_vaddr++ = LE_SWAP32(size); 2727*8f23e9faSHans Rosenfeld *xrdy_vaddr = 0; 2728*8f23e9faSHans Rosenfeld 2729*8f23e9faSHans Rosenfeld /* First 2 SGEs are XRDY and SKIP */ 2730*8f23e9faSHans Rosenfeld stage_sge.addrHigh = PADDR_HI(mp->phys); 2731*8f23e9faSHans Rosenfeld stage_sge.addrLow = PADDR_LO(mp->phys); 2732*8f23e9faSHans Rosenfeld stage_sge.length = EMLXS_XFER_RDY_SIZE; 2733*8f23e9faSHans Rosenfeld stage_sge.offset = 0; 2734*8f23e9faSHans Rosenfeld stage_sge.type = 0; 2735*8f23e9faSHans Rosenfeld stage_sge.last = 0; 2736*8f23e9faSHans Rosenfeld 2737*8f23e9faSHans Rosenfeld /* Words 0-3 */ 2738*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrHigh = stage_sge.addrHigh; 2739*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrLow = stage_sge.addrLow; 2740*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.tus.f.bdeSize = EMLXS_XFER_RDY_SIZE; 2741*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.PayloadLength = EMLXS_XFER_RDY_SIZE; 2742*8f23e9faSHans Rosenfeld 2743*8f23e9faSHans Rosenfeld } else { /* CMD_FCP_TSEND64_CX */ 2744*8f23e9faSHans Rosenfeld /* First 2 SGEs are SKIP */ 2745*8f23e9faSHans Rosenfeld stage_sge.addrHigh = 0; 2746*8f23e9faSHans Rosenfeld stage_sge.addrLow = 0; 2747*8f23e9faSHans Rosenfeld stage_sge.length = 0; 2748*8f23e9faSHans Rosenfeld stage_sge.offset = 0; 2749*8f23e9faSHans Rosenfeld stage_sge.type = EMLXS_SGE_TYPE_SKIP; 2750*8f23e9faSHans Rosenfeld stage_sge.last = 0; 2751*8f23e9faSHans Rosenfeld 2752*8f23e9faSHans Rosenfeld /* Words 0-3 */ 2753*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrHigh = PADDR_HI(fct_mp->phys); 2754*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrLow = PADDR_LO(fct_mp->phys); 2755*8f23e9faSHans Rosenfeld 2756*8f23e9faSHans Rosenfeld /* The BDE should match the contents of the first SGE payload */ 2757*8f23e9faSHans Rosenfeld len = MIN(EMLXS_MAX_SGE_SIZE, size); 2758*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.tus.f.bdeSize = len; 2759*8f23e9faSHans Rosenfeld 2760*8f23e9faSHans Rosenfeld /* The PayloadLength should be set to 0 for TSEND64. */ 2761*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.PayloadLength = 0; 2762*8f23e9faSHans Rosenfeld } 2763*8f23e9faSHans Rosenfeld 2764*8f23e9faSHans Rosenfeld dbuf = sbp->fct_buf; 2765*8f23e9faSHans Rosenfeld /* 2766*8f23e9faSHans Rosenfeld * TotalTransferCount equals to Relative Offset field (Word 4) 2767*8f23e9faSHans Rosenfeld * in both TSEND64 and TRECEIVE64 WQE. 2768*8f23e9faSHans Rosenfeld */ 2769*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.TotalTransferCount = dbuf->db_relative_offset; 2770*8f23e9faSHans Rosenfeld 2771*8f23e9faSHans Rosenfeld /* Copy staged SGE into SGL */ 2772*8f23e9faSHans Rosenfeld BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 2773*8f23e9faSHans Rosenfeld (uint8_t *)sge, sizeof (ULP_SGE64)); 2774*8f23e9faSHans Rosenfeld sge++; 2775*8f23e9faSHans Rosenfeld 2776*8f23e9faSHans Rosenfeld stage_sge.addrHigh = 0; 2777*8f23e9faSHans Rosenfeld stage_sge.addrLow = 0; 2778*8f23e9faSHans Rosenfeld stage_sge.length = 0; 2779*8f23e9faSHans Rosenfeld stage_sge.offset = 0; 2780*8f23e9faSHans Rosenfeld stage_sge.type = EMLXS_SGE_TYPE_SKIP; 2781*8f23e9faSHans Rosenfeld stage_sge.last = 0; 2782*8f23e9faSHans Rosenfeld 2783*8f23e9faSHans Rosenfeld /* Copy staged SGE into SGL */ 2784*8f23e9faSHans Rosenfeld BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 2785*8f23e9faSHans Rosenfeld (uint8_t *)sge, sizeof (ULP_SGE64)); 2786*8f23e9faSHans Rosenfeld sge++; 2787*8f23e9faSHans Rosenfeld 2788*8f23e9faSHans Rosenfeld sge_size = size; 2789*8f23e9faSHans Rosenfeld sge_addr = fct_mp->phys; 2790*8f23e9faSHans Rosenfeld cnt = 0; 2791*8f23e9faSHans Rosenfeld 2792*8f23e9faSHans Rosenfeld /* Build SGEs */ 2793*8f23e9faSHans Rosenfeld while (sge_size) { 2794*8f23e9faSHans Rosenfeld if (cnt) { 2795*8f23e9faSHans Rosenfeld /* Copy staged SGE before we build next one */ 2796*8f23e9faSHans Rosenfeld BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 2797*8f23e9faSHans Rosenfeld (uint8_t *)sge, sizeof (ULP_SGE64)); 2798*8f23e9faSHans Rosenfeld sge++; 2799*8f23e9faSHans Rosenfeld } 2800*8f23e9faSHans Rosenfeld 2801*8f23e9faSHans Rosenfeld len = MIN(EMLXS_MAX_SGE_SIZE, sge_size); 2802*8f23e9faSHans Rosenfeld 2803*8f23e9faSHans Rosenfeld stage_sge.addrHigh = PADDR_HI(sge_addr); 2804*8f23e9faSHans Rosenfeld stage_sge.addrLow = PADDR_LO(sge_addr); 2805*8f23e9faSHans Rosenfeld stage_sge.length = len; 2806*8f23e9faSHans Rosenfeld stage_sge.offset = cnt; 2807*8f23e9faSHans Rosenfeld stage_sge.type = EMLXS_SGE_TYPE_DATA; 2808*8f23e9faSHans Rosenfeld 2809*8f23e9faSHans Rosenfeld sge_addr += len; 2810*8f23e9faSHans Rosenfeld sge_size -= len; 2811*8f23e9faSHans Rosenfeld cnt += len; 2812*8f23e9faSHans Rosenfeld } 2813*8f23e9faSHans Rosenfeld 2814*8f23e9faSHans Rosenfeld stage_sge.last = 1; 2815*8f23e9faSHans Rosenfeld 2816*8f23e9faSHans Rosenfeld if (hba->sli.sli4.flag & EMLXS_SLI4_PHON) { 2817*8f23e9faSHans Rosenfeld wqe->FirstData.addrHigh = stage_sge.addrHigh; 2818*8f23e9faSHans Rosenfeld wqe->FirstData.addrLow = stage_sge.addrLow; 2819*8f23e9faSHans Rosenfeld wqe->FirstData.tus.f.bdeSize = stage_sge.length; 2820*8f23e9faSHans Rosenfeld } 2821*8f23e9faSHans Rosenfeld /* Copy staged SGE into SGL */ 2822*8f23e9faSHans Rosenfeld BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 2823*8f23e9faSHans Rosenfeld (uint8_t *)sge, sizeof (ULP_SGE64)); 2824*8f23e9faSHans Rosenfeld 2825*8f23e9faSHans Rosenfeld return (0); 2826*8f23e9faSHans Rosenfeld 2827*8f23e9faSHans Rosenfeld } /* emlxs_sli4_fct_bde_setup */ 2828*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 2829*8f23e9faSHans Rosenfeld 2830*8f23e9faSHans Rosenfeld 2831*8f23e9faSHans Rosenfeld static void 2832*8f23e9faSHans Rosenfeld emlxs_sli4_issue_iocb_cmd(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq) 2833*8f23e9faSHans Rosenfeld { 2834*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 2835*8f23e9faSHans Rosenfeld emlxs_buf_t *sbp; 2836*8f23e9faSHans Rosenfeld uint32_t channelno; 2837*8f23e9faSHans Rosenfeld int32_t throttle; 2838*8f23e9faSHans Rosenfeld emlxs_wqe_t *wqe; 2839*8f23e9faSHans Rosenfeld emlxs_wqe_t *wqeslot; 2840*8f23e9faSHans Rosenfeld WQ_DESC_t *wq; 2841*8f23e9faSHans Rosenfeld uint32_t flag; 2842*8f23e9faSHans Rosenfeld uint32_t wqdb; 2843*8f23e9faSHans Rosenfeld uint16_t next_wqe; 2844*8f23e9faSHans Rosenfeld off_t offset; 2845*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT 2846*8f23e9faSHans Rosenfeld int32_t node_throttle; 2847*8f23e9faSHans Rosenfeld NODELIST *marked_node = NULL; 2848*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */ 2849*8f23e9faSHans Rosenfeld 285082527734SSukumar Swaminathan 285182527734SSukumar Swaminathan channelno = cp->channelno; 285282527734SSukumar Swaminathan wq = (WQ_DESC_t *)cp->iopath; 285382527734SSukumar Swaminathan 2854*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 285582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 285682527734SSukumar Swaminathan "ISSUE WQE channel: %x %p", channelno, wq); 2857*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 285882527734SSukumar Swaminathan 285982527734SSukumar Swaminathan throttle = 0; 286082527734SSukumar Swaminathan 286182527734SSukumar Swaminathan /* Check if FCP ring and adapter is not ready */ 286282527734SSukumar Swaminathan /* We may use any ring for FCP_CMD */ 286382527734SSukumar Swaminathan if (iocbq && (iocbq->flag & IOCB_FCP_CMD) && (hba->state != FC_READY)) { 286482527734SSukumar Swaminathan if (!(iocbq->flag & IOCB_SPECIAL) || !iocbq->port || 2865*8f23e9faSHans Rosenfeld (((emlxs_port_t *)iocbq->port)->mode == MODE_INITIATOR)) { 286682527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 286782527734SSukumar Swaminathan return; 286882527734SSukumar Swaminathan } 286982527734SSukumar Swaminathan } 287082527734SSukumar Swaminathan 287182527734SSukumar Swaminathan /* Attempt to acquire CMD_RING lock */ 2872a9800bebSGarrett D'Amore if (mutex_tryenter(&EMLXS_QUE_LOCK(channelno)) == 0) { 287382527734SSukumar Swaminathan /* Queue it for later */ 287482527734SSukumar Swaminathan if (iocbq) { 287582527734SSukumar Swaminathan if ((hba->io_count - 287682527734SSukumar Swaminathan hba->channel_tx_count) > 10) { 287782527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 287882527734SSukumar Swaminathan return; 287982527734SSukumar Swaminathan } else { 288082527734SSukumar Swaminathan 2881a9800bebSGarrett D'Amore mutex_enter(&EMLXS_QUE_LOCK(channelno)); 288282527734SSukumar Swaminathan } 288382527734SSukumar Swaminathan } else { 288482527734SSukumar Swaminathan return; 288582527734SSukumar Swaminathan } 288682527734SSukumar Swaminathan } 2887a9800bebSGarrett D'Amore /* EMLXS_QUE_LOCK acquired */ 288882527734SSukumar Swaminathan 288982527734SSukumar Swaminathan /* Throttle check only applies to non special iocb */ 289082527734SSukumar Swaminathan if (iocbq && (!(iocbq->flag & IOCB_SPECIAL))) { 289182527734SSukumar Swaminathan /* Check if HBA is full */ 289282527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 289382527734SSukumar Swaminathan if (throttle <= 0) { 289482527734SSukumar Swaminathan /* Hitting adapter throttle limit */ 289582527734SSukumar Swaminathan /* Queue it for later */ 289682527734SSukumar Swaminathan if (iocbq) { 289782527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 289882527734SSukumar Swaminathan } 289982527734SSukumar Swaminathan 290082527734SSukumar Swaminathan goto busy; 290182527734SSukumar Swaminathan } 290282527734SSukumar Swaminathan } 290382527734SSukumar Swaminathan 290482527734SSukumar Swaminathan /* Check to see if we have room for this WQE */ 290582527734SSukumar Swaminathan next_wqe = wq->host_index + 1; 290682527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 290782527734SSukumar Swaminathan next_wqe = 0; 290882527734SSukumar Swaminathan } 290982527734SSukumar Swaminathan 291082527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 291182527734SSukumar Swaminathan /* Queue it for later */ 291282527734SSukumar Swaminathan if (iocbq) { 291382527734SSukumar Swaminathan emlxs_tx_put(iocbq, 1); 291482527734SSukumar Swaminathan } 291582527734SSukumar Swaminathan goto busy; 291682527734SSukumar Swaminathan } 291782527734SSukumar Swaminathan 291882527734SSukumar Swaminathan /* 291982527734SSukumar Swaminathan * We have a command ring slot available 292082527734SSukumar Swaminathan * Make sure we have an iocb to send 292182527734SSukumar Swaminathan */ 292282527734SSukumar Swaminathan if (iocbq) { 292382527734SSukumar Swaminathan mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 292482527734SSukumar Swaminathan 292582527734SSukumar Swaminathan /* Check if the ring already has iocb's waiting */ 292682527734SSukumar Swaminathan if (cp->nodeq.q_first != NULL) { 292782527734SSukumar Swaminathan /* Put the current iocbq on the tx queue */ 292882527734SSukumar Swaminathan emlxs_tx_put(iocbq, 0); 292982527734SSukumar Swaminathan 293082527734SSukumar Swaminathan /* 293182527734SSukumar Swaminathan * Attempt to replace it with the next iocbq 293282527734SSukumar Swaminathan * in the tx queue 293382527734SSukumar Swaminathan */ 293482527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 0); 293582527734SSukumar Swaminathan } 293682527734SSukumar Swaminathan 293782527734SSukumar Swaminathan mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 293882527734SSukumar Swaminathan } else { 293982527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 294082527734SSukumar Swaminathan } 294182527734SSukumar Swaminathan 294282527734SSukumar Swaminathan sendit: 294382527734SSukumar Swaminathan /* Process each iocbq */ 294482527734SSukumar Swaminathan while (iocbq) { 2945*8f23e9faSHans Rosenfeld sbp = iocbq->sbp; 2946*8f23e9faSHans Rosenfeld 2947*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT 2948*8f23e9faSHans Rosenfeld if (sbp && sbp->node && sbp->node->io_throttle) { 2949*8f23e9faSHans Rosenfeld node_throttle = sbp->node->io_throttle - 2950*8f23e9faSHans Rosenfeld sbp->node->io_active; 2951*8f23e9faSHans Rosenfeld if (node_throttle <= 0) { 2952*8f23e9faSHans Rosenfeld /* Node is busy */ 2953*8f23e9faSHans Rosenfeld /* Queue this iocb and get next iocb from */ 2954*8f23e9faSHans Rosenfeld /* channel */ 2955*8f23e9faSHans Rosenfeld 2956*8f23e9faSHans Rosenfeld if (!marked_node) { 2957*8f23e9faSHans Rosenfeld marked_node = sbp->node; 2958*8f23e9faSHans Rosenfeld } 2959*8f23e9faSHans Rosenfeld 2960*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_TX_CHANNEL_LOCK); 2961*8f23e9faSHans Rosenfeld emlxs_tx_put(iocbq, 0); 2962*8f23e9faSHans Rosenfeld 2963*8f23e9faSHans Rosenfeld if (cp->nodeq.q_first == marked_node) { 2964*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2965*8f23e9faSHans Rosenfeld goto busy; 2966*8f23e9faSHans Rosenfeld } 2967*8f23e9faSHans Rosenfeld 2968*8f23e9faSHans Rosenfeld iocbq = emlxs_tx_get(cp, 0); 2969*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_TX_CHANNEL_LOCK); 2970*8f23e9faSHans Rosenfeld continue; 2971*8f23e9faSHans Rosenfeld } 2972*8f23e9faSHans Rosenfeld } 2973*8f23e9faSHans Rosenfeld marked_node = 0; 2974*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */ 297582527734SSukumar Swaminathan 297682527734SSukumar Swaminathan wqe = &iocbq->wqe; 2977*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 297882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2979*8f23e9faSHans Rosenfeld "ISSUE QID %d WQE iotag:%x xri:%d", wq->qid, 298082527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 2981*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 298282527734SSukumar Swaminathan 298382527734SSukumar Swaminathan if (sbp) { 298482527734SSukumar Swaminathan /* If exchange removed after wqe was prep'ed, drop it */ 2985a9800bebSGarrett D'Amore if (!(sbp->xrip)) { 298682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 2987*8f23e9faSHans Rosenfeld "Xmit WQE iotag:%x xri:%d aborted", 298882527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 298982527734SSukumar Swaminathan 299082527734SSukumar Swaminathan /* Get next iocb from the tx queue */ 299182527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 299282527734SSukumar Swaminathan continue; 299382527734SSukumar Swaminathan } 299482527734SSukumar Swaminathan 299582527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_DELAY_REQUIRED) { 299682527734SSukumar Swaminathan 299782527734SSukumar Swaminathan /* Perform delay */ 299882527734SSukumar Swaminathan if ((channelno == hba->channel_els) && 299982527734SSukumar Swaminathan !(iocbq->flag & IOCB_FCP_CMD)) { 300082527734SSukumar Swaminathan drv_usecwait(100000); 300182527734SSukumar Swaminathan } else { 300282527734SSukumar Swaminathan drv_usecwait(20000); 300382527734SSukumar Swaminathan } 300482527734SSukumar Swaminathan } 300582527734SSukumar Swaminathan 3006*8f23e9faSHans Rosenfeld /* Check for ULP pkt request */ 300782527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 300882527734SSukumar Swaminathan 300982527734SSukumar Swaminathan if (sbp->node == NULL) { 301082527734SSukumar Swaminathan /* Set node to base node by default */ 301182527734SSukumar Swaminathan iocbq->node = (void *)&port->node_base; 301282527734SSukumar Swaminathan sbp->node = (void *)&port->node_base; 301382527734SSukumar Swaminathan } 301482527734SSukumar Swaminathan 301582527734SSukumar Swaminathan sbp->pkt_flags |= PACKET_IN_CHIPQ; 301682527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 301782527734SSukumar Swaminathan 30181a5e258fSJosef 'Jeff' Sipek atomic_inc_32(&hba->io_active); 3019*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT 3020*8f23e9faSHans Rosenfeld if (sbp->node) { 3021*8f23e9faSHans Rosenfeld atomic_inc_32(&sbp->node->io_active); 3022*8f23e9faSHans Rosenfeld } 3023*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */ 302482527734SSukumar Swaminathan 3025*8f23e9faSHans Rosenfeld sbp->xrip->flag |= EMLXS_XRI_PENDING_IO; 302682527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 302782527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 302882527734SSukumar Swaminathan if (sbp->fct_cmd) { 302982527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 303082527734SSukumar Swaminathan EMLXS_FCT_IOCB_ISSUED); 303182527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 303282527734SSukumar Swaminathan icmd->ULPCOMMAND); 303382527734SSukumar Swaminathan } 303482527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 303582527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 303682527734SSukumar Swaminathan cp->hbaSendCmd_sbp++; 303782527734SSukumar Swaminathan iocbq->channel = cp; 303882527734SSukumar Swaminathan } else { 303982527734SSukumar Swaminathan cp->hbaSendCmd++; 304082527734SSukumar Swaminathan } 304182527734SSukumar Swaminathan 304282527734SSukumar Swaminathan flag = iocbq->flag; 304382527734SSukumar Swaminathan 3044*8f23e9faSHans Rosenfeld /* 3045*8f23e9faSHans Rosenfeld * At this point, we have a command ring slot available 3046*8f23e9faSHans Rosenfeld * and an iocb to send 3047*8f23e9faSHans Rosenfeld */ 3048*8f23e9faSHans Rosenfeld wq->release_depth--; 3049*8f23e9faSHans Rosenfeld if (wq->release_depth == 0) { 3050*8f23e9faSHans Rosenfeld wq->release_depth = WQE_RELEASE_DEPTH; 3051*8f23e9faSHans Rosenfeld wqe->WQEC = 1; 3052*8f23e9faSHans Rosenfeld } 3053*8f23e9faSHans Rosenfeld 3054*8f23e9faSHans Rosenfeld HBASTATS.IocbIssued[channelno]++; 3055*8f23e9faSHans Rosenfeld wq->num_proc++; 3056*8f23e9faSHans Rosenfeld 305782527734SSukumar Swaminathan /* Send the iocb */ 305882527734SSukumar Swaminathan wqeslot = (emlxs_wqe_t *)wq->addr.virt; 305982527734SSukumar Swaminathan wqeslot += wq->host_index; 306082527734SSukumar Swaminathan 306182527734SSukumar Swaminathan wqe->CQId = wq->cqid; 3062*8f23e9faSHans Rosenfeld if (hba->sli.sli4.param.PHWQ) { 3063*8f23e9faSHans Rosenfeld WQE_PHWQ_WQID(wqe, wq->qid); 3064*8f23e9faSHans Rosenfeld } 306582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)wqe, (uint8_t *)wqeslot, 306682527734SSukumar Swaminathan sizeof (emlxs_wqe_t)); 306782527734SSukumar Swaminathan #ifdef DEBUG_WQE 3068a9800bebSGarrett D'Amore emlxs_data_dump(port, "WQE", (uint32_t *)wqe, 18, 0); 3069*8f23e9faSHans Rosenfeld #endif /* DEBUG_WQE */ 3070b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3071b3660a96SSukumar Swaminathan wq->addr.virt) - 3072b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3073b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3074b3660a96SSukumar Swaminathan 3075b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(wq->addr.dma_handle, offset, 307682527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 307782527734SSukumar Swaminathan 307882527734SSukumar Swaminathan /* Ring the WQ Doorbell */ 307982527734SSukumar Swaminathan wqdb = wq->qid; 308082527734SSukumar Swaminathan wqdb |= ((1 << 24) | (wq->host_index << 16)); 308182527734SSukumar Swaminathan 3082*8f23e9faSHans Rosenfeld /* 3083*8f23e9faSHans Rosenfeld * After this, the sbp / iocb / wqe should not be 3084*8f23e9faSHans Rosenfeld * accessed in the xmit path. 3085*8f23e9faSHans Rosenfeld */ 308682527734SSukumar Swaminathan 3087*8f23e9faSHans Rosenfeld emlxs_sli4_write_wqdb(hba, wqdb); 308882527734SSukumar Swaminathan wq->host_index = next_wqe; 308982527734SSukumar Swaminathan 3090*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 309182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 309282527734SSukumar Swaminathan "WQ RING: %08x", wqdb); 3093*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 309482527734SSukumar Swaminathan 309582527734SSukumar Swaminathan if (!sbp) { 3096a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 309782527734SSukumar Swaminathan } 309882527734SSukumar Swaminathan 309982527734SSukumar Swaminathan if (iocbq && (!(flag & IOCB_SPECIAL))) { 310082527734SSukumar Swaminathan /* Check if HBA is full */ 310182527734SSukumar Swaminathan throttle = hba->io_throttle - hba->io_active; 310282527734SSukumar Swaminathan if (throttle <= 0) { 310382527734SSukumar Swaminathan goto busy; 310482527734SSukumar Swaminathan } 310582527734SSukumar Swaminathan } 310682527734SSukumar Swaminathan 310782527734SSukumar Swaminathan /* Check to see if we have room for another WQE */ 310882527734SSukumar Swaminathan next_wqe++; 310982527734SSukumar Swaminathan if (next_wqe >= wq->max_index) { 311082527734SSukumar Swaminathan next_wqe = 0; 311182527734SSukumar Swaminathan } 311282527734SSukumar Swaminathan 311382527734SSukumar Swaminathan if (next_wqe == wq->port_index) { 311482527734SSukumar Swaminathan /* Queue it for later */ 311582527734SSukumar Swaminathan goto busy; 311682527734SSukumar Swaminathan } 311782527734SSukumar Swaminathan 311882527734SSukumar Swaminathan /* Get the next iocb from the tx queue if there is one */ 311982527734SSukumar Swaminathan iocbq = emlxs_tx_get(cp, 1); 312082527734SSukumar Swaminathan } 312182527734SSukumar Swaminathan 3122a9800bebSGarrett D'Amore mutex_exit(&EMLXS_QUE_LOCK(channelno)); 312382527734SSukumar Swaminathan 312482527734SSukumar Swaminathan return; 312582527734SSukumar Swaminathan 312682527734SSukumar Swaminathan busy: 3127*8f23e9faSHans Rosenfeld wq->num_busy++; 312882527734SSukumar Swaminathan if (throttle <= 0) { 312982527734SSukumar Swaminathan HBASTATS.IocbThrottled++; 313082527734SSukumar Swaminathan } else { 313182527734SSukumar Swaminathan HBASTATS.IocbRingFull[channelno]++; 313282527734SSukumar Swaminathan } 313382527734SSukumar Swaminathan 3134a9800bebSGarrett D'Amore mutex_exit(&EMLXS_QUE_LOCK(channelno)); 313582527734SSukumar Swaminathan 313682527734SSukumar Swaminathan return; 313782527734SSukumar Swaminathan 313882527734SSukumar Swaminathan } /* emlxs_sli4_issue_iocb_cmd() */ 313982527734SSukumar Swaminathan 314082527734SSukumar Swaminathan 314182527734SSukumar Swaminathan /*ARGSUSED*/ 314282527734SSukumar Swaminathan static uint32_t 3143a9800bebSGarrett D'Amore emlxs_sli4_issue_mq(emlxs_port_t *port, MAILBOX4 *mqe, MAILBOX *mb, 3144a9800bebSGarrett D'Amore uint32_t tmo) 314582527734SSukumar Swaminathan { 3146a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 314782527734SSukumar Swaminathan MAILBOXQ *mbq; 314882527734SSukumar Swaminathan MAILBOX4 *mb4; 314982527734SSukumar Swaminathan MATCHMAP *mp; 315082527734SSukumar Swaminathan uint32_t *iptr; 315182527734SSukumar Swaminathan uint32_t mqdb; 3152b3660a96SSukumar Swaminathan off_t offset; 315382527734SSukumar Swaminathan 315482527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 315582527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 315682527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 3157a9800bebSGarrett D'Amore hba->mbox_mqe = (void *)mqe; 315882527734SSukumar Swaminathan 315982527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 316082527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 316182527734SSukumar Swaminathan /* 316282527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 316382527734SSukumar Swaminathan * into the mailbox area. 316482527734SSukumar Swaminathan */ 316582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 316682527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 316782527734SSukumar Swaminathan 316882527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, 0, 316982527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 317082527734SSukumar Swaminathan 3171a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 3172a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMD", (uint32_t *)mqe, 3173a9800bebSGarrett D'Amore 18, 0); 3174a9800bebSGarrett D'Amore } 317582527734SSukumar Swaminathan } else { 317682527734SSukumar Swaminathan /* SLI_CONFIG and non-embedded */ 317782527734SSukumar Swaminathan 317882527734SSukumar Swaminathan /* 317982527734SSukumar Swaminathan * If this is not embedded, the MQ area 318082527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 318182527734SSukumar Swaminathan * non-embedded mailbox command. 318282527734SSukumar Swaminathan * mp will point to the actual mailbox command which 318382527734SSukumar Swaminathan * should be copied into the non-embedded area. 318482527734SSukumar Swaminathan */ 318582527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 318682527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 318782527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 318882527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 318982527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 319082527734SSukumar Swaminathan *iptr = mp->size; 319182527734SSukumar Swaminathan 319282527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 319382527734SSukumar Swaminathan 319482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 319582527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 319682527734SSukumar Swaminathan 319782527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mqe, 319882527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 319982527734SSukumar Swaminathan 3200b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 3201b3660a96SSukumar Swaminathan hba->sli.sli4.mq.addr.virt) - 3202b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 3203b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 3204b3660a96SSukumar Swaminathan 3205b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset, 320682527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 320782527734SSukumar Swaminathan 3208a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX EXT", (uint32_t *)mqe, 12, 0); 320982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 321082527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, (uint32_t *)(mp->virt)); 3211a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 321282527734SSukumar Swaminathan } 321382527734SSukumar Swaminathan 321482527734SSukumar Swaminathan /* Ring the MQ Doorbell */ 321582527734SSukumar Swaminathan mqdb = hba->sli.sli4.mq.qid; 321682527734SSukumar Swaminathan mqdb |= ((1 << MQ_DB_POP_SHIFT) & MQ_DB_POP_MASK); 321782527734SSukumar Swaminathan 3218a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 3219a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3220a9800bebSGarrett D'Amore "MQ RING: %08x", mqdb); 3221a9800bebSGarrett D'Amore } 322282527734SSukumar Swaminathan 3223*8f23e9faSHans Rosenfeld emlxs_sli4_write_mqdb(hba, mqdb); 3224*8f23e9faSHans Rosenfeld 322582527734SSukumar Swaminathan return (MBX_SUCCESS); 322682527734SSukumar Swaminathan 322782527734SSukumar Swaminathan } /* emlxs_sli4_issue_mq() */ 322882527734SSukumar Swaminathan 322982527734SSukumar Swaminathan 323082527734SSukumar Swaminathan /*ARGSUSED*/ 323182527734SSukumar Swaminathan static uint32_t 323282527734SSukumar Swaminathan emlxs_sli4_issue_bootstrap(emlxs_hba_t *hba, MAILBOX *mb, uint32_t tmo) 323382527734SSukumar Swaminathan { 323482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 323582527734SSukumar Swaminathan MAILBOXQ *mbq; 323682527734SSukumar Swaminathan MAILBOX4 *mb4; 3237b3660a96SSukumar Swaminathan MATCHMAP *mp = NULL; 323882527734SSukumar Swaminathan uint32_t *iptr; 3239b3660a96SSukumar Swaminathan int nonembed = 0; 324082527734SSukumar Swaminathan 324182527734SSukumar Swaminathan mbq = (MAILBOXQ *)mb; 324282527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mb; 324382527734SSukumar Swaminathan mp = (MATCHMAP *) mbq->nonembed; 3244a9800bebSGarrett D'Amore hba->mbox_mqe = hba->sli.sli4.bootstrapmb.virt; 324582527734SSukumar Swaminathan 324682527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 324782527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 324882527734SSukumar Swaminathan /* 324982527734SSukumar Swaminathan * If this is an embedded mbox, everything should fit 325082527734SSukumar Swaminathan * into the bootstrap mailbox area. 325182527734SSukumar Swaminathan */ 325282527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 325382527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 325482527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 325582527734SSukumar Swaminathan 325682527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 325782527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORDEV); 3258a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMD", iptr, 18, 0); 325982527734SSukumar Swaminathan } else { 326082527734SSukumar Swaminathan /* 326182527734SSukumar Swaminathan * If this is not embedded, the bootstrap mailbox area 326282527734SSukumar Swaminathan * MUST contain a SGE pointer to a larger area for the 326382527734SSukumar Swaminathan * non-embedded mailbox command. 326482527734SSukumar Swaminathan * mp will point to the actual mailbox command which 326582527734SSukumar Swaminathan * should be copied into the non-embedded area. 326682527734SSukumar Swaminathan */ 3267b3660a96SSukumar Swaminathan nonembed = 1; 326882527734SSukumar Swaminathan mb4->un.varSLIConfig.be.sge_cnt = 1; 326982527734SSukumar Swaminathan mb4->un.varSLIConfig.be.payload_length = mp->size; 327082527734SSukumar Swaminathan iptr = (uint32_t *)&mb4->un.varSLIConfig.be.un_hdr.hdr_req; 327182527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_LO(mp->phys); 327282527734SSukumar Swaminathan *iptr++ = (uint32_t)PADDR_HI(mp->phys); 327382527734SSukumar Swaminathan *iptr = mp->size; 327482527734SSukumar Swaminathan 327582527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 327682527734SSukumar Swaminathan 327782527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 327882527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 327982527734SSukumar Swaminathan 328082527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 328182527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)iptr, 328282527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 328382527734SSukumar Swaminathan 328482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 328582527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 328682527734SSukumar Swaminathan DDI_DMA_SYNC_FORDEV); 328782527734SSukumar Swaminathan 3288a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX EXT", iptr, 12, 0); 328982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 329082527734SSukumar Swaminathan "Extension Addr %p %p", mp->phys, 329182527734SSukumar Swaminathan (uint32_t *)((uint8_t *)mp->virt)); 329282527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 3293a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)mp->virt, 24, 0); 329482527734SSukumar Swaminathan } 329582527734SSukumar Swaminathan 329682527734SSukumar Swaminathan 329782527734SSukumar Swaminathan /* NOTE: tmo is in 10ms ticks */ 329882527734SSukumar Swaminathan if (!emlxs_issue_bootstrap_mb(hba, tmo)) { 329982527734SSukumar Swaminathan return (MBX_TIMEOUT); 330082527734SSukumar Swaminathan } 330182527734SSukumar Swaminathan 330282527734SSukumar Swaminathan if ((mb->mbxCommand != MBX_SLI_CONFIG) || 330382527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded)) { 330482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 330582527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE, DDI_DMA_SYNC_FORKERNEL); 330682527734SSukumar Swaminathan 330782527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 330882527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 330982527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 331082527734SSukumar Swaminathan 3311a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", iptr, 18, 0); 331282527734SSukumar Swaminathan 331382527734SSukumar Swaminathan } else { 331482527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.bootstrapmb.dma_handle, 0, 331582527734SSukumar Swaminathan EMLXS_BOOTSTRAP_MB_SIZE + MBOX_EXTENSION_SIZE, 331682527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 331782527734SSukumar Swaminathan 331882527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size, 331982527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 332082527734SSukumar Swaminathan 332182527734SSukumar Swaminathan BE_SWAP32_BUFFER(mp->virt, mp->size); 332282527734SSukumar Swaminathan 332382527734SSukumar Swaminathan iptr = (uint32_t *)hba->sli.sli4.bootstrapmb.virt; 332482527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)mb, 332582527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 332682527734SSukumar Swaminathan 3327a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", iptr, 12, 0); 332882527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mp->virt); 3329a9800bebSGarrett D'Amore emlxs_data_dump(port, "EXT AREA", (uint32_t *)iptr, 24, 0); 333082527734SSukumar Swaminathan } 333182527734SSukumar Swaminathan 3332b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 3333b3660a96SSukumar Swaminathan if (nonembed && mp) { 3334b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, mp->dma_handle) 3335b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3336b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3337b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3338*8f23e9faSHans Rosenfeld "sli4_issue_bootstrap: mp_hdl=%p", 3339b3660a96SSukumar Swaminathan mp->dma_handle); 3340b3660a96SSukumar Swaminathan return (MBXERR_DMA_ERROR); 3341b3660a96SSukumar Swaminathan } 3342b3660a96SSukumar Swaminathan } 3343b3660a96SSukumar Swaminathan 3344b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 3345b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle) 3346b3660a96SSukumar Swaminathan != DDI_FM_OK) { 3347b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 3348b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 3349*8f23e9faSHans Rosenfeld "sli4_issue_bootstrap: hdl=%p", 3350b3660a96SSukumar Swaminathan hba->sli.sli4.bootstrapmb.dma_handle); 3351b3660a96SSukumar Swaminathan return (MBXERR_DMA_ERROR); 3352b3660a96SSukumar Swaminathan } 3353b3660a96SSukumar Swaminathan #endif 3354b3660a96SSukumar Swaminathan 335582527734SSukumar Swaminathan return (MBX_SUCCESS); 335682527734SSukumar Swaminathan 335782527734SSukumar Swaminathan } /* emlxs_sli4_issue_bootstrap() */ 335882527734SSukumar Swaminathan 335982527734SSukumar Swaminathan 336082527734SSukumar Swaminathan /*ARGSUSED*/ 336182527734SSukumar Swaminathan static uint32_t 336282527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 336382527734SSukumar Swaminathan uint32_t tmo) 336482527734SSukumar Swaminathan { 3365a9800bebSGarrett D'Amore emlxs_port_t *port; 336682527734SSukumar Swaminathan MAILBOX4 *mb4; 336782527734SSukumar Swaminathan MAILBOX *mb; 336882527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 336982527734SSukumar Swaminathan MATCHMAP *mp; 337082527734SSukumar Swaminathan uint32_t *iptr; 337182527734SSukumar Swaminathan uint32_t rc; 337282527734SSukumar Swaminathan uint32_t i; 337382527734SSukumar Swaminathan uint32_t tmo_local; 337482527734SSukumar Swaminathan 3375a9800bebSGarrett D'Amore if (!mbq->port) { 3376a9800bebSGarrett D'Amore mbq->port = &PPORT; 3377a9800bebSGarrett D'Amore } 3378a9800bebSGarrett D'Amore 3379a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 3380a9800bebSGarrett D'Amore 338182527734SSukumar Swaminathan mb4 = (MAILBOX4 *)mbq; 338282527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 338382527734SSukumar Swaminathan 338482527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 338582527734SSukumar Swaminathan rc = MBX_SUCCESS; 338682527734SSukumar Swaminathan 338782527734SSukumar Swaminathan /* Check for minimum timeouts */ 338882527734SSukumar Swaminathan switch (mb->mbxCommand) { 338982527734SSukumar Swaminathan /* Mailbox commands that erase/write flash */ 339082527734SSukumar Swaminathan case MBX_DOWN_LOAD: 339182527734SSukumar Swaminathan case MBX_UPDATE_CFG: 339282527734SSukumar Swaminathan case MBX_LOAD_AREA: 339382527734SSukumar Swaminathan case MBX_LOAD_EXP_ROM: 339482527734SSukumar Swaminathan case MBX_WRITE_NV: 339582527734SSukumar Swaminathan case MBX_FLASH_WR_ULA: 339682527734SSukumar Swaminathan case MBX_DEL_LD_ENTRY: 339782527734SSukumar Swaminathan case MBX_LOAD_SM: 3398*8f23e9faSHans Rosenfeld case MBX_DUMP_MEMORY: 3399*8f23e9faSHans Rosenfeld case MBX_WRITE_VPARMS: 3400*8f23e9faSHans Rosenfeld case MBX_ACCESS_VDATA: 340182527734SSukumar Swaminathan if (tmo < 300) { 340282527734SSukumar Swaminathan tmo = 300; 340382527734SSukumar Swaminathan } 340482527734SSukumar Swaminathan break; 340582527734SSukumar Swaminathan 3406*8f23e9faSHans Rosenfeld case MBX_SLI_CONFIG: { 3407*8f23e9faSHans Rosenfeld mbox_req_hdr_t *hdr_req; 3408*8f23e9faSHans Rosenfeld 3409*8f23e9faSHans Rosenfeld hdr_req = (mbox_req_hdr_t *) 3410*8f23e9faSHans Rosenfeld &mb4->un.varSLIConfig.be.un_hdr.hdr_req; 3411*8f23e9faSHans Rosenfeld 3412*8f23e9faSHans Rosenfeld if (hdr_req->subsystem == IOCTL_SUBSYSTEM_COMMON) { 3413*8f23e9faSHans Rosenfeld switch (hdr_req->opcode) { 3414*8f23e9faSHans Rosenfeld case COMMON_OPCODE_WRITE_OBJ: 3415*8f23e9faSHans Rosenfeld case COMMON_OPCODE_READ_OBJ: 3416*8f23e9faSHans Rosenfeld case COMMON_OPCODE_READ_OBJ_LIST: 3417*8f23e9faSHans Rosenfeld case COMMON_OPCODE_DELETE_OBJ: 3418*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_BOOT_CFG: 3419*8f23e9faSHans Rosenfeld case COMMON_OPCODE_GET_PROFILE_CFG: 3420*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_PROFILE_CFG: 3421*8f23e9faSHans Rosenfeld case COMMON_OPCODE_GET_PROFILE_LIST: 3422*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_ACTIVE_PROFILE: 3423*8f23e9faSHans Rosenfeld case COMMON_OPCODE_GET_PROFILE_CAPS: 3424*8f23e9faSHans Rosenfeld case COMMON_OPCODE_GET_MR_PROFILE_CAPS: 3425*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_MR_PROFILE_CAPS: 3426*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_FACTORY_PROFILE_CFG: 3427*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SEND_ACTIVATION: 3428*8f23e9faSHans Rosenfeld case COMMON_OPCODE_RESET_LICENSES: 3429*8f23e9faSHans Rosenfeld case COMMON_OPCODE_SET_PHYSICAL_LINK_CFG_V1: 3430*8f23e9faSHans Rosenfeld case COMMON_OPCODE_GET_VPD_DATA: 3431*8f23e9faSHans Rosenfeld if (tmo < 300) { 3432*8f23e9faSHans Rosenfeld tmo = 300; 3433*8f23e9faSHans Rosenfeld } 3434*8f23e9faSHans Rosenfeld break; 3435*8f23e9faSHans Rosenfeld default: 3436*8f23e9faSHans Rosenfeld if (tmo < 30) { 3437*8f23e9faSHans Rosenfeld tmo = 30; 3438*8f23e9faSHans Rosenfeld } 3439*8f23e9faSHans Rosenfeld } 3440*8f23e9faSHans Rosenfeld } else if (hdr_req->subsystem == IOCTL_SUBSYSTEM_FCOE) { 3441*8f23e9faSHans Rosenfeld switch (hdr_req->opcode) { 3442*8f23e9faSHans Rosenfeld case FCOE_OPCODE_SET_FCLINK_SETTINGS: 3443*8f23e9faSHans Rosenfeld if (tmo < 300) { 3444*8f23e9faSHans Rosenfeld tmo = 300; 3445*8f23e9faSHans Rosenfeld } 3446*8f23e9faSHans Rosenfeld break; 3447*8f23e9faSHans Rosenfeld default: 3448*8f23e9faSHans Rosenfeld if (tmo < 30) { 3449*8f23e9faSHans Rosenfeld tmo = 30; 3450*8f23e9faSHans Rosenfeld } 3451*8f23e9faSHans Rosenfeld } 3452*8f23e9faSHans Rosenfeld } else { 3453*8f23e9faSHans Rosenfeld if (tmo < 30) { 3454*8f23e9faSHans Rosenfeld tmo = 30; 3455*8f23e9faSHans Rosenfeld } 3456*8f23e9faSHans Rosenfeld } 3457*8f23e9faSHans Rosenfeld 3458*8f23e9faSHans Rosenfeld /* 3459*8f23e9faSHans Rosenfeld * Also: VENDOR_MANAGE_FFV (0x13, 0x02) (not currently used) 3460*8f23e9faSHans Rosenfeld */ 3461*8f23e9faSHans Rosenfeld 3462*8f23e9faSHans Rosenfeld break; 3463*8f23e9faSHans Rosenfeld } 346482527734SSukumar Swaminathan default: 346582527734SSukumar Swaminathan if (tmo < 30) { 346682527734SSukumar Swaminathan tmo = 30; 346782527734SSukumar Swaminathan } 346882527734SSukumar Swaminathan break; 346982527734SSukumar Swaminathan } 347082527734SSukumar Swaminathan 347182527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 347282527734SSukumar Swaminathan tmo_local = tmo * 100; 347382527734SSukumar Swaminathan 347482527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 347582527734SSukumar Swaminathan 347682527734SSukumar Swaminathan /* Adjust wait flag */ 347782527734SSukumar Swaminathan if (flag != MBX_NOWAIT) { 347882527734SSukumar Swaminathan if (hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED) { 347982527734SSukumar Swaminathan flag = MBX_SLEEP; 348082527734SSukumar Swaminathan } else { 348182527734SSukumar Swaminathan flag = MBX_POLL; 348282527734SSukumar Swaminathan } 348382527734SSukumar Swaminathan } else { 348482527734SSukumar Swaminathan /* Must have interrupts enabled to perform MBX_NOWAIT */ 348582527734SSukumar Swaminathan if (!(hba->sli.sli4.flag & EMLXS_SLI4_INTR_ENABLED)) { 348682527734SSukumar Swaminathan 348782527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 348882527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 348982527734SSukumar Swaminathan 349082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 3491a9800bebSGarrett D'Amore "Interrupts disabled. %s failed.", 349282527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 349382527734SSukumar Swaminathan 349482527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 349582527734SSukumar Swaminathan } 349682527734SSukumar Swaminathan } 349782527734SSukumar Swaminathan 3498bce54adfSSukumar Swaminathan /* Check for hardware error ; special case SLI_CONFIG */ 3499bce54adfSSukumar Swaminathan if ((hba->flag & FC_HARDWARE_ERROR) && 3500bce54adfSSukumar Swaminathan ! ((mb4->mbxCommand == MBX_SLI_CONFIG) && 3501bce54adfSSukumar Swaminathan (mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode == 3502bce54adfSSukumar Swaminathan COMMON_OPCODE_RESET))) { 350382527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 350482527734SSukumar Swaminathan 350582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 350682527734SSukumar Swaminathan 350782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 350882527734SSukumar Swaminathan "Hardware error reported. %s failed. status=%x mb=%p", 3509*8f23e9faSHans Rosenfeld emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb); 351082527734SSukumar Swaminathan 351182527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 351282527734SSukumar Swaminathan } 351382527734SSukumar Swaminathan 351482527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 351582527734SSukumar Swaminathan /* If we are not polling, then queue it for later */ 351682527734SSukumar Swaminathan if (flag == MBX_NOWAIT) { 351782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 351882527734SSukumar Swaminathan "Busy. %s: mb=%p NoWait.", 351982527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb); 352082527734SSukumar Swaminathan 352182527734SSukumar Swaminathan emlxs_mb_put(hba, mbq); 352282527734SSukumar Swaminathan 352382527734SSukumar Swaminathan HBASTATS.MboxBusy++; 352482527734SSukumar Swaminathan 352582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 352682527734SSukumar Swaminathan 352782527734SSukumar Swaminathan return (MBX_BUSY); 352882527734SSukumar Swaminathan } 352982527734SSukumar Swaminathan 353082527734SSukumar Swaminathan while (hba->mbox_queue_flag) { 353182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 353282527734SSukumar Swaminathan 353382527734SSukumar Swaminathan if (tmo_local-- == 0) { 353482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 353582527734SSukumar Swaminathan &emlxs_mbox_event_msg, 353682527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%d Waiting.", 353782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 353882527734SSukumar Swaminathan tmo); 353982527734SSukumar Swaminathan 354082527734SSukumar Swaminathan /* Non-lethalStatus mailbox timeout */ 354182527734SSukumar Swaminathan /* Does not indicate a hardware error */ 354282527734SSukumar Swaminathan mb->mbxStatus = MBX_TIMEOUT; 354382527734SSukumar Swaminathan return (MBX_TIMEOUT); 354482527734SSukumar Swaminathan } 354582527734SSukumar Swaminathan 3546*8f23e9faSHans Rosenfeld BUSYWAIT_MS(10); 354782527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 3548*8f23e9faSHans Rosenfeld 3549*8f23e9faSHans Rosenfeld /* Check for hardware error ; special case SLI_CONFIG */ 3550*8f23e9faSHans Rosenfeld if ((hba->flag & FC_HARDWARE_ERROR) && 3551*8f23e9faSHans Rosenfeld ! ((mb4->mbxCommand == MBX_SLI_CONFIG) && 3552*8f23e9faSHans Rosenfeld (mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode == 3553*8f23e9faSHans Rosenfeld COMMON_OPCODE_RESET))) { 3554*8f23e9faSHans Rosenfeld mb->mbxStatus = MBX_HARDWARE_ERROR; 3555*8f23e9faSHans Rosenfeld 3556*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 3557*8f23e9faSHans Rosenfeld 3558*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 3559*8f23e9faSHans Rosenfeld &emlxs_mbox_detail_msg, 3560*8f23e9faSHans Rosenfeld "Hardware error reported. %s failed. " 3561*8f23e9faSHans Rosenfeld "status=%x mb=%p", 3562*8f23e9faSHans Rosenfeld emlxs_mb_cmd_xlate(mb->mbxCommand), 3563*8f23e9faSHans Rosenfeld mb->mbxStatus, mb); 3564*8f23e9faSHans Rosenfeld 3565*8f23e9faSHans Rosenfeld return (MBX_HARDWARE_ERROR); 3566*8f23e9faSHans Rosenfeld } 356782527734SSukumar Swaminathan } 356882527734SSukumar Swaminathan } 356982527734SSukumar Swaminathan 357082527734SSukumar Swaminathan /* Initialize mailbox area */ 357182527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 357282527734SSukumar Swaminathan 3573a9800bebSGarrett D'Amore if (mb->mbxCommand == MBX_DOWN_LINK) { 3574a9800bebSGarrett D'Amore hba->sli.sli4.flag |= EMLXS_SLI4_DOWN_LINK; 3575a9800bebSGarrett D'Amore } 3576a9800bebSGarrett D'Amore 357782527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 357882527734SSukumar Swaminathan switch (flag) { 357982527734SSukumar Swaminathan 358082527734SSukumar Swaminathan case MBX_NOWAIT: 358182527734SSukumar Swaminathan if (mb->mbxCommand != MBX_HEARTBEAT) { 358282527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 358382527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 358482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 358582527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 358682527734SSukumar Swaminathan "Sending. %s: mb=%p NoWait. embedded %d", 358782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 358882527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 358982527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 359082527734SSukumar Swaminathan } 359182527734SSukumar Swaminathan } 359282527734SSukumar Swaminathan 359382527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 359482527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 359582527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 359682527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 359782527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 359882527734SSukumar Swaminathan } 359982527734SSukumar Swaminathan 360082527734SSukumar Swaminathan if (mbq->bp) { 360182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 360282527734SSukumar Swaminathan "BDE virt %p phys %p size x%x", 360382527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->virt, 360482527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->phys, 360582527734SSukumar Swaminathan ((MATCHMAP *)mbq->bp)->size); 3606a9800bebSGarrett D'Amore emlxs_data_dump(port, "DATA", 360782527734SSukumar Swaminathan (uint32_t *)(((MATCHMAP *)mbq->bp)->virt), 30, 0); 360882527734SSukumar Swaminathan } 3609a9800bebSGarrett D'Amore rc = emlxs_sli4_issue_mq(port, (MAILBOX4 *)iptr, mb, tmo_local); 361082527734SSukumar Swaminathan break; 361182527734SSukumar Swaminathan 361282527734SSukumar Swaminathan case MBX_POLL: 361382527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 361482527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 361582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 361682527734SSukumar Swaminathan "Sending. %s: mb=%p Poll. embedded %d", 361782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 361882527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 361982527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 362082527734SSukumar Swaminathan } 362182527734SSukumar Swaminathan 362282527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 362382527734SSukumar Swaminathan 362482527734SSukumar Swaminathan /* Clean up the mailbox area */ 362582527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 362682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 362782527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Poll. embedded %d", 362882527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 362982527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 363082527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 363182527734SSukumar Swaminathan 363282527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 363382527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 363482527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 363582527734SSukumar Swaminathan 363682527734SSukumar Swaminathan } else { 363782527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 363882527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 363982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 364082527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 3641a9800bebSGarrett D'Amore "Completed. %s: mb=%p status=%x Poll. " 364282527734SSukumar Swaminathan "embedded %d", 364382527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 364482527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 364582527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 364682527734SSukumar Swaminathan } 364782527734SSukumar Swaminathan 364882527734SSukumar Swaminathan /* Process the result */ 364982527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 365082527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 365182527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 365282527734SSukumar Swaminathan } 365382527734SSukumar Swaminathan } 365482527734SSukumar Swaminathan 365582527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 365682527734SSukumar Swaminathan } 365782527734SSukumar Swaminathan 365882527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 365982527734SSukumar Swaminathan if (mp) { 366082527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 366182527734SSukumar Swaminathan if (hdr_rsp->status) { 3662a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 3663a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 3664a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 3665a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 3666a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 3667a9800bebSGarrett D'Amore 366882527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 366982527734SSukumar Swaminathan } 367082527734SSukumar Swaminathan } 367182527734SSukumar Swaminathan rc = mb->mbxStatus; 367282527734SSukumar Swaminathan 367382527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 367482527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 367582527734SSukumar Swaminathan if (mbq) { 367682527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 367782527734SSukumar Swaminathan i = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 367882527734SSukumar Swaminathan if ((i != MBX_BUSY) && (i != MBX_SUCCESS)) { 3679a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 368082527734SSukumar Swaminathan } 368182527734SSukumar Swaminathan } 368282527734SSukumar Swaminathan break; 368382527734SSukumar Swaminathan 368482527734SSukumar Swaminathan case MBX_SLEEP: 368582527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 368682527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 368782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 368882527734SSukumar Swaminathan "Sending. %s: mb=%p Sleep. embedded %d", 368982527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, 369082527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 369182527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 369282527734SSukumar Swaminathan } 369382527734SSukumar Swaminathan 369482527734SSukumar Swaminathan iptr = hba->sli.sli4.mq.addr.virt; 369582527734SSukumar Swaminathan iptr += (hba->sli.sli4.mq.host_index * MAILBOX_CMD_SLI4_WSIZE); 369682527734SSukumar Swaminathan hba->sli.sli4.mq.host_index++; 369782527734SSukumar Swaminathan if (hba->sli.sli4.mq.host_index >= hba->sli.sli4.mq.max_index) { 369882527734SSukumar Swaminathan hba->sli.sli4.mq.host_index = 0; 369982527734SSukumar Swaminathan } 370082527734SSukumar Swaminathan 3701a9800bebSGarrett D'Amore rc = emlxs_sli4_issue_mq(port, (MAILBOX4 *)iptr, mb, tmo_local); 370282527734SSukumar Swaminathan 370382527734SSukumar Swaminathan if (rc != MBX_SUCCESS) { 370482527734SSukumar Swaminathan break; 370582527734SSukumar Swaminathan } 370682527734SSukumar Swaminathan 370782527734SSukumar Swaminathan /* Wait for completion */ 370882527734SSukumar Swaminathan /* The driver clock is timing the mailbox. */ 370982527734SSukumar Swaminathan 371082527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 371182527734SSukumar Swaminathan while (!(mbq->flag & MBQ_COMPLETED)) { 371282527734SSukumar Swaminathan cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK); 371382527734SSukumar Swaminathan } 371482527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 371582527734SSukumar Swaminathan 371682527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 371782527734SSukumar Swaminathan if (mp) { 371882527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 371982527734SSukumar Swaminathan if (hdr_rsp->status) { 3720a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 3721a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 3722a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 3723a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 3724a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 3725a9800bebSGarrett D'Amore 372682527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 372782527734SSukumar Swaminathan } 372882527734SSukumar Swaminathan } 372982527734SSukumar Swaminathan rc = mb->mbxStatus; 373082527734SSukumar Swaminathan 373182527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 373282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 373382527734SSukumar Swaminathan "Timeout. %s: mb=%p tmo=%x Sleep. embedded %d", 373482527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo, 373582527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 373682527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 373782527734SSukumar Swaminathan } else { 373882527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 373982527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 374082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 374182527734SSukumar Swaminathan &emlxs_mbox_detail_msg, 3742a9800bebSGarrett D'Amore "Completed. %s: mb=%p status=%x Sleep. " 374382527734SSukumar Swaminathan "embedded %d", 374482527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), mb, rc, 374582527734SSukumar Swaminathan ((mb->mbxCommand != MBX_SLI_CONFIG) ? 1 : 374682527734SSukumar Swaminathan (mb4->un.varSLIConfig.be.embedded))); 374782527734SSukumar Swaminathan } 374882527734SSukumar Swaminathan } 374982527734SSukumar Swaminathan break; 375082527734SSukumar Swaminathan } 375182527734SSukumar Swaminathan 375282527734SSukumar Swaminathan return (rc); 375382527734SSukumar Swaminathan 375482527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd() */ 375582527734SSukumar Swaminathan 375682527734SSukumar Swaminathan 375782527734SSukumar Swaminathan 375882527734SSukumar Swaminathan /*ARGSUSED*/ 375982527734SSukumar Swaminathan static uint32_t 376082527734SSukumar Swaminathan emlxs_sli4_issue_mbox_cmd4quiesce(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag, 376182527734SSukumar Swaminathan uint32_t tmo) 376282527734SSukumar Swaminathan { 376382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 376482527734SSukumar Swaminathan MAILBOX *mb; 376582527734SSukumar Swaminathan mbox_rsp_hdr_t *hdr_rsp; 376682527734SSukumar Swaminathan MATCHMAP *mp; 376782527734SSukumar Swaminathan uint32_t rc; 376882527734SSukumar Swaminathan uint32_t tmo_local; 376982527734SSukumar Swaminathan 377082527734SSukumar Swaminathan mb = (MAILBOX *)mbq; 377182527734SSukumar Swaminathan 377282527734SSukumar Swaminathan mb->mbxStatus = MBX_SUCCESS; 377382527734SSukumar Swaminathan rc = MBX_SUCCESS; 377482527734SSukumar Swaminathan 377582527734SSukumar Swaminathan if (tmo < 30) { 377682527734SSukumar Swaminathan tmo = 30; 377782527734SSukumar Swaminathan } 377882527734SSukumar Swaminathan 377982527734SSukumar Swaminathan /* Convert tmo seconds to 10 millisecond tics */ 378082527734SSukumar Swaminathan tmo_local = tmo * 100; 378182527734SSukumar Swaminathan 378282527734SSukumar Swaminathan flag = MBX_POLL; 378382527734SSukumar Swaminathan 378482527734SSukumar Swaminathan /* Check for hardware error */ 378582527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 378682527734SSukumar Swaminathan mb->mbxStatus = MBX_HARDWARE_ERROR; 378782527734SSukumar Swaminathan return (MBX_HARDWARE_ERROR); 378882527734SSukumar Swaminathan } 378982527734SSukumar Swaminathan 379082527734SSukumar Swaminathan /* Initialize mailbox area */ 379182527734SSukumar Swaminathan emlxs_mb_init(hba, mbq, flag, tmo); 379282527734SSukumar Swaminathan 379382527734SSukumar Swaminathan switch (flag) { 379482527734SSukumar Swaminathan 379582527734SSukumar Swaminathan case MBX_POLL: 379682527734SSukumar Swaminathan 379782527734SSukumar Swaminathan rc = emlxs_sli4_issue_bootstrap(hba, mb, tmo_local); 379882527734SSukumar Swaminathan 379982527734SSukumar Swaminathan /* Clean up the mailbox area */ 380082527734SSukumar Swaminathan if (rc == MBX_TIMEOUT) { 380182527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 380282527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 380382527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 380482527734SSukumar Swaminathan 380582527734SSukumar Swaminathan } else { 380682527734SSukumar Swaminathan /* Process the result */ 380782527734SSukumar Swaminathan if (!(mbq->flag & MBQ_PASSTHRU)) { 380882527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 380982527734SSukumar Swaminathan (void) (mbq->mbox_cmpl)(hba, mbq); 381082527734SSukumar Swaminathan } 381182527734SSukumar Swaminathan } 381282527734SSukumar Swaminathan 381382527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, mb->mbxStatus); 381482527734SSukumar Swaminathan } 381582527734SSukumar Swaminathan 381682527734SSukumar Swaminathan mp = (MATCHMAP *)mbq->nonembed; 381782527734SSukumar Swaminathan if (mp) { 381882527734SSukumar Swaminathan hdr_rsp = (mbox_rsp_hdr_t *)mp->virt; 381982527734SSukumar Swaminathan if (hdr_rsp->status) { 3820a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, 3821a9800bebSGarrett D'Amore &emlxs_mbox_detail_msg, 3822a9800bebSGarrett D'Amore "%s: MBX_NONEMBED_ERROR: 0x%x, 0x%x", 3823a9800bebSGarrett D'Amore emlxs_mb_cmd_xlate(mb->mbxCommand), 3824a9800bebSGarrett D'Amore hdr_rsp->status, hdr_rsp->extra_status); 3825a9800bebSGarrett D'Amore 382682527734SSukumar Swaminathan mb->mbxStatus = MBX_NONEMBED_ERROR; 382782527734SSukumar Swaminathan } 382882527734SSukumar Swaminathan } 382982527734SSukumar Swaminathan rc = mb->mbxStatus; 383082527734SSukumar Swaminathan 383182527734SSukumar Swaminathan break; 383282527734SSukumar Swaminathan } 383382527734SSukumar Swaminathan 383482527734SSukumar Swaminathan return (rc); 383582527734SSukumar Swaminathan 383682527734SSukumar Swaminathan } /* emlxs_sli4_issue_mbox_cmd4quiesce() */ 383782527734SSukumar Swaminathan 383882527734SSukumar Swaminathan 383982527734SSukumar Swaminathan 384082527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 384182527734SSukumar Swaminathan /*ARGSUSED*/ 384282527734SSukumar Swaminathan extern uint32_t 3843*8f23e9faSHans Rosenfeld emlxs_sli4_prep_fct_iocb(emlxs_port_t *port, emlxs_buf_t *cmd_sbp, int channel) 384482527734SSukumar Swaminathan { 384582527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 3846*8f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG; 3847*8f23e9faSHans Rosenfeld fct_cmd_t *fct_cmd; 3848*8f23e9faSHans Rosenfeld stmf_data_buf_t *dbuf; 3849*8f23e9faSHans Rosenfeld scsi_task_t *fct_task; 385082527734SSukumar Swaminathan fc_packet_t *pkt; 385182527734SSukumar Swaminathan CHANNEL *cp; 3852a9800bebSGarrett D'Amore XRIobj_t *xrip; 3853*8f23e9faSHans Rosenfeld emlxs_node_t *ndlp; 385482527734SSukumar Swaminathan IOCBQ *iocbq; 3855*8f23e9faSHans Rosenfeld IOCB *iocb; 3856*8f23e9faSHans Rosenfeld emlxs_wqe_t *wqe; 3857*8f23e9faSHans Rosenfeld ULP_SGE64 stage_sge; 3858*8f23e9faSHans Rosenfeld ULP_SGE64 *sge; 3859*8f23e9faSHans Rosenfeld RPIobj_t *rpip; 3860*8f23e9faSHans Rosenfeld int32_t sge_size; 3861*8f23e9faSHans Rosenfeld uint64_t sge_addr; 386282527734SSukumar Swaminathan uint32_t did; 3863*8f23e9faSHans Rosenfeld uint32_t timeout; 386482527734SSukumar Swaminathan 3865*8f23e9faSHans Rosenfeld ddi_dma_cookie_t *cp_cmd; 386682527734SSukumar Swaminathan 3867*8f23e9faSHans Rosenfeld pkt = PRIV2PKT(cmd_sbp); 386882527734SSukumar Swaminathan 3869*8f23e9faSHans Rosenfeld cp = (CHANNEL *)cmd_sbp->channel; 387082527734SSukumar Swaminathan 3871*8f23e9faSHans Rosenfeld iocbq = &cmd_sbp->iocbq; 3872*8f23e9faSHans Rosenfeld iocb = &iocbq->iocb; 387382527734SSukumar Swaminathan 3874*8f23e9faSHans Rosenfeld did = cmd_sbp->did; 3875*8f23e9faSHans Rosenfeld if (iocb->ULPCOMMAND == CMD_ABORT_XRI_CX) { 387682527734SSukumar Swaminathan 3877*8f23e9faSHans Rosenfeld ndlp = cmd_sbp->node; 3878*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, ndlp); 387982527734SSukumar Swaminathan 3880*8f23e9faSHans Rosenfeld if (!rpip) { 3881*8f23e9faSHans Rosenfeld /* Use the fabric rpi */ 3882*8f23e9faSHans Rosenfeld rpip = port->vpip->fabric_rpip; 3883*8f23e9faSHans Rosenfeld } 388482527734SSukumar Swaminathan 3885*8f23e9faSHans Rosenfeld /* Next allocate an Exchange for this command */ 3886*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_alloc_xri(port, cmd_sbp, rpip, 3887*8f23e9faSHans Rosenfeld EMLXS_XRI_SOL_BLS_TYPE); 388882527734SSukumar Swaminathan 3889*8f23e9faSHans Rosenfeld if (!xrip) { 3890*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3891*8f23e9faSHans Rosenfeld "Adapter Busy. Unable to allocate exchange. " 3892*8f23e9faSHans Rosenfeld "did=0x%x", did); 389382527734SSukumar Swaminathan 3894*8f23e9faSHans Rosenfeld return (FC_TRAN_BUSY); 3895*8f23e9faSHans Rosenfeld } 389682527734SSukumar Swaminathan 3897*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 3898*8f23e9faSHans Rosenfeld "FCT Abort Request: xri=%d iotag=%d sbp=%p rxid=%x", 3899*8f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, cmd_sbp, pkt->pkt_cmd_fhdr.rx_id); 390082527734SSukumar Swaminathan 3901*8f23e9faSHans Rosenfeld cmd_sbp->xrip = xrip; 390282527734SSukumar Swaminathan 3903*8f23e9faSHans Rosenfeld cp->ulpSendCmd++; 390482527734SSukumar Swaminathan 3905*8f23e9faSHans Rosenfeld /* Initalize iocbq */ 3906*8f23e9faSHans Rosenfeld iocbq->port = (void *)port; 3907*8f23e9faSHans Rosenfeld iocbq->node = (void *)ndlp; 3908*8f23e9faSHans Rosenfeld iocbq->channel = (void *)cp; 390982527734SSukumar Swaminathan 3910*8f23e9faSHans Rosenfeld /* 3911*8f23e9faSHans Rosenfeld * Don't give the abort priority, we want the IOCB 3912*8f23e9faSHans Rosenfeld * we are aborting to be processed first. 3913*8f23e9faSHans Rosenfeld */ 3914*8f23e9faSHans Rosenfeld iocbq->flag |= IOCB_SPECIAL; 391582527734SSukumar Swaminathan 3916*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 3917*8f23e9faSHans Rosenfeld bzero((void *)wqe, sizeof (emlxs_wqe_t)); 3918b3660a96SSukumar Swaminathan 3919*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 3920*8f23e9faSHans Rosenfeld wqe->un.Abort.Criteria = ABORT_XRI_TAG; 3921*8f23e9faSHans Rosenfeld wqe->RequestTag = xrip->iotag; 3922*8f23e9faSHans Rosenfeld wqe->AbortTag = pkt->pkt_cmd_fhdr.rx_id; 3923*8f23e9faSHans Rosenfeld wqe->Command = CMD_ABORT_XRI_CX; 3924*8f23e9faSHans Rosenfeld wqe->Class = CLASS3; 3925*8f23e9faSHans Rosenfeld wqe->CQId = 0xffff; 3926*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_ABORT; 392782527734SSukumar Swaminathan 3928*8f23e9faSHans Rosenfeld if (hba->state >= FC_LINK_UP) { 3929*8f23e9faSHans Rosenfeld wqe->un.Abort.IA = 0; 3930*8f23e9faSHans Rosenfeld } else { 3931*8f23e9faSHans Rosenfeld wqe->un.Abort.IA = 1; 3932*8f23e9faSHans Rosenfeld } 393382527734SSukumar Swaminathan 3934*8f23e9faSHans Rosenfeld /* Set the pkt timer */ 3935*8f23e9faSHans Rosenfeld cmd_sbp->ticks = hba->timer_tics + pkt->pkt_timeout + 3936*8f23e9faSHans Rosenfeld ((pkt->pkt_timeout > 0xff) ? 0 : 10); 3937*8f23e9faSHans Rosenfeld 3938*8f23e9faSHans Rosenfeld return (IOERR_SUCCESS); 3939*8f23e9faSHans Rosenfeld 3940*8f23e9faSHans Rosenfeld } else if (iocb->ULPCOMMAND == CMD_FCP_TRSP64_CX) { 3941*8f23e9faSHans Rosenfeld 3942*8f23e9faSHans Rosenfeld timeout = pkt->pkt_timeout; 3943*8f23e9faSHans Rosenfeld ndlp = cmd_sbp->node; 3944*8f23e9faSHans Rosenfeld if (!ndlp) { 3945*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3946*8f23e9faSHans Rosenfeld "Unable to find rpi. did=0x%x", did); 3947*8f23e9faSHans Rosenfeld 3948*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(cmd_sbp, IOSTAT_LOCAL_REJECT, 3949*8f23e9faSHans Rosenfeld IOERR_INVALID_RPI, 0); 3950*8f23e9faSHans Rosenfeld return (0xff); 3951*8f23e9faSHans Rosenfeld } 3952*8f23e9faSHans Rosenfeld 3953*8f23e9faSHans Rosenfeld cp->ulpSendCmd++; 3954*8f23e9faSHans Rosenfeld 3955*8f23e9faSHans Rosenfeld /* Initalize iocbq */ 3956*8f23e9faSHans Rosenfeld iocbq->port = (void *)port; 3957*8f23e9faSHans Rosenfeld iocbq->node = (void *)ndlp; 3958*8f23e9faSHans Rosenfeld iocbq->channel = (void *)cp; 3959*8f23e9faSHans Rosenfeld 3960*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 3961*8f23e9faSHans Rosenfeld bzero((void *)wqe, sizeof (emlxs_wqe_t)); 3962*8f23e9faSHans Rosenfeld 3963*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_register_xri(port, cmd_sbp, 3964*8f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.rx_id, did); 3965*8f23e9faSHans Rosenfeld 3966*8f23e9faSHans Rosenfeld if (!xrip) { 3967*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 3968*8f23e9faSHans Rosenfeld "Unable to register xri %x. did=0x%x", 3969*8f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.rx_id, did); 3970*8f23e9faSHans Rosenfeld 3971*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(cmd_sbp, IOSTAT_LOCAL_REJECT, 3972*8f23e9faSHans Rosenfeld IOERR_NO_XRI, 0); 3973*8f23e9faSHans Rosenfeld return (0xff); 3974*8f23e9faSHans Rosenfeld } 3975*8f23e9faSHans Rosenfeld 3976*8f23e9faSHans Rosenfeld cmd_sbp->iotag = xrip->iotag; 3977*8f23e9faSHans Rosenfeld cmd_sbp->channel = cp; 3978*8f23e9faSHans Rosenfeld 3979*8f23e9faSHans Rosenfeld #if (EMLXS_MODREV >= EMLXS_MODREV3) 3980*8f23e9faSHans Rosenfeld cp_cmd = pkt->pkt_cmd_cookie; 3981*8f23e9faSHans Rosenfeld #else 3982*8f23e9faSHans Rosenfeld cp_cmd = &pkt->pkt_cmd_cookie; 3983*8f23e9faSHans Rosenfeld #endif /* >= EMLXS_MODREV3 */ 3984*8f23e9faSHans Rosenfeld 3985*8f23e9faSHans Rosenfeld sge_size = pkt->pkt_cmdlen; 3986*8f23e9faSHans Rosenfeld /* Make size a multiple of 4 */ 3987*8f23e9faSHans Rosenfeld if (sge_size & 3) { 3988*8f23e9faSHans Rosenfeld sge_size = (sge_size + 3) & 0xfffffffc; 3989*8f23e9faSHans Rosenfeld } 3990*8f23e9faSHans Rosenfeld sge_addr = cp_cmd->dmac_laddress; 3991*8f23e9faSHans Rosenfeld sge = xrip->SGList.virt; 3992*8f23e9faSHans Rosenfeld 3993*8f23e9faSHans Rosenfeld stage_sge.addrHigh = PADDR_HI(sge_addr); 3994*8f23e9faSHans Rosenfeld stage_sge.addrLow = PADDR_LO(sge_addr); 3995*8f23e9faSHans Rosenfeld stage_sge.length = sge_size; 3996*8f23e9faSHans Rosenfeld stage_sge.offset = 0; 3997*8f23e9faSHans Rosenfeld stage_sge.type = 0; 3998*8f23e9faSHans Rosenfeld stage_sge.last = 1; 3999*8f23e9faSHans Rosenfeld 4000*8f23e9faSHans Rosenfeld /* Copy staged SGE into SGL */ 4001*8f23e9faSHans Rosenfeld BE_SWAP32_BCOPY((uint8_t *)&stage_sge, 4002*8f23e9faSHans Rosenfeld (uint8_t *)sge, sizeof (ULP_SGE64)); 4003*8f23e9faSHans Rosenfeld 4004*8f23e9faSHans Rosenfeld /* Words 0-3 */ 4005*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrHigh = stage_sge.addrHigh; 4006*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.addrLow = stage_sge.addrLow; 4007*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.Payload.tus.f.bdeSize = sge_size; 4008*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.PayloadLength = sge_size; 4009*8f23e9faSHans Rosenfeld 4010*8f23e9faSHans Rosenfeld /* Word 6 */ 4011*8f23e9faSHans Rosenfeld wqe->ContextTag = ndlp->nlp_Rpi; 4012*8f23e9faSHans Rosenfeld wqe->XRITag = xrip->XRI; 4013*8f23e9faSHans Rosenfeld 4014*8f23e9faSHans Rosenfeld /* Word 7 */ 4015*8f23e9faSHans Rosenfeld wqe->Command = iocb->ULPCOMMAND; 4016*8f23e9faSHans Rosenfeld wqe->Class = cmd_sbp->class; 4017*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 4018*8f23e9faSHans Rosenfeld wqe->Timer = ((timeout > 0xff) ? 0 : timeout); 4019*8f23e9faSHans Rosenfeld 4020*8f23e9faSHans Rosenfeld /* Word 8 */ 4021*8f23e9faSHans Rosenfeld wqe->AbortTag = 0; 4022*8f23e9faSHans Rosenfeld 4023*8f23e9faSHans Rosenfeld /* Word 9 */ 4024*8f23e9faSHans Rosenfeld wqe->RequestTag = xrip->iotag; 4025*8f23e9faSHans Rosenfeld wqe->OXId = (uint16_t)xrip->rx_id; 4026*8f23e9faSHans Rosenfeld 4027*8f23e9faSHans Rosenfeld /* Word 10 */ 4028*8f23e9faSHans Rosenfeld if (xrip->flag & EMLXS_XRI_BUSY) { 4029*8f23e9faSHans Rosenfeld wqe->XC = 1; 4030*8f23e9faSHans Rosenfeld } 4031*8f23e9faSHans Rosenfeld 4032*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4033*8f23e9faSHans Rosenfeld wqe->QOSd = 1; 4034*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4035*8f23e9faSHans Rosenfeld } 4036*8f23e9faSHans Rosenfeld 4037*8f23e9faSHans Rosenfeld /* Word 11 */ 4038*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_TRSP; 4039*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4040*8f23e9faSHans Rosenfeld 4041*8f23e9faSHans Rosenfeld /* Set the pkt timer */ 4042*8f23e9faSHans Rosenfeld cmd_sbp->ticks = hba->timer_tics + timeout + 4043*8f23e9faSHans Rosenfeld ((timeout > 0xff) ? 0 : 10); 4044*8f23e9faSHans Rosenfeld 4045*8f23e9faSHans Rosenfeld if (pkt->pkt_cmdlen) { 4046*8f23e9faSHans Rosenfeld EMLXS_MPDATA_SYNC(pkt->pkt_cmd_dma, 0, pkt->pkt_cmdlen, 4047*8f23e9faSHans Rosenfeld DDI_DMA_SYNC_FORDEV); 4048*8f23e9faSHans Rosenfeld } 4049*8f23e9faSHans Rosenfeld 4050*8f23e9faSHans Rosenfeld return (IOERR_SUCCESS); 4051*8f23e9faSHans Rosenfeld } 4052*8f23e9faSHans Rosenfeld 4053*8f23e9faSHans Rosenfeld fct_cmd = cmd_sbp->fct_cmd; 4054*8f23e9faSHans Rosenfeld did = fct_cmd->cmd_rportid; 4055*8f23e9faSHans Rosenfeld dbuf = cmd_sbp->fct_buf; 4056*8f23e9faSHans Rosenfeld fct_task = (scsi_task_t *)fct_cmd->cmd_specific; 4057*8f23e9faSHans Rosenfeld ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private; 4058*8f23e9faSHans Rosenfeld if (!ndlp) { 4059*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4060*8f23e9faSHans Rosenfeld "Unable to find rpi. did=0x%x", did); 4061*8f23e9faSHans Rosenfeld 4062*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(cmd_sbp, IOSTAT_LOCAL_REJECT, 4063*8f23e9faSHans Rosenfeld IOERR_INVALID_RPI, 0); 4064*8f23e9faSHans Rosenfeld return (0xff); 4065*8f23e9faSHans Rosenfeld } 4066*8f23e9faSHans Rosenfeld 4067*8f23e9faSHans Rosenfeld 4068*8f23e9faSHans Rosenfeld /* Initalize iocbq */ 4069*8f23e9faSHans Rosenfeld iocbq->port = (void *) port; 4070*8f23e9faSHans Rosenfeld iocbq->node = (void *)ndlp; 4071*8f23e9faSHans Rosenfeld iocbq->channel = (void *) cp; 4072*8f23e9faSHans Rosenfeld 4073*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 4074*8f23e9faSHans Rosenfeld bzero((void *)wqe, sizeof (emlxs_wqe_t)); 4075*8f23e9faSHans Rosenfeld 4076*8f23e9faSHans Rosenfeld xrip = cmd_sbp->xrip; 4077*8f23e9faSHans Rosenfeld if (!xrip) { 4078*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4079*8f23e9faSHans Rosenfeld "Unable to find xri. did=0x%x", did); 4080*8f23e9faSHans Rosenfeld 4081*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(cmd_sbp, IOSTAT_LOCAL_REJECT, 4082*8f23e9faSHans Rosenfeld IOERR_NO_XRI, 0); 4083*8f23e9faSHans Rosenfeld return (0xff); 4084*8f23e9faSHans Rosenfeld } 4085*8f23e9faSHans Rosenfeld 4086*8f23e9faSHans Rosenfeld if (emlxs_sli4_register_xri(port, cmd_sbp, 4087*8f23e9faSHans Rosenfeld xrip->XRI, ndlp->nlp_DID) == NULL) { 4088*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4089*8f23e9faSHans Rosenfeld "Unable to register xri. did=0x%x", did); 4090*8f23e9faSHans Rosenfeld 4091*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(cmd_sbp, IOSTAT_LOCAL_REJECT, 4092*8f23e9faSHans Rosenfeld IOERR_NO_XRI, 0); 4093*8f23e9faSHans Rosenfeld return (0xff); 4094*8f23e9faSHans Rosenfeld } 4095*8f23e9faSHans Rosenfeld cmd_sbp->iotag = xrip->iotag; 4096*8f23e9faSHans Rosenfeld cmd_sbp->channel = cp; 4097*8f23e9faSHans Rosenfeld 4098*8f23e9faSHans Rosenfeld if (cfg[CFG_TIMEOUT_ENABLE].current) { 4099*8f23e9faSHans Rosenfeld timeout = 4100*8f23e9faSHans Rosenfeld ((2 * hba->fc_ratov) < 60) ? 60 : (2 * hba->fc_ratov); 4101*8f23e9faSHans Rosenfeld } else { 4102*8f23e9faSHans Rosenfeld timeout = 0x80000000; 4103*8f23e9faSHans Rosenfeld } 4104*8f23e9faSHans Rosenfeld cmd_sbp->ticks = 4105*8f23e9faSHans Rosenfeld hba->timer_tics + timeout + ((timeout > 0xff) ? 0 : 10); 4106*8f23e9faSHans Rosenfeld 4107*8f23e9faSHans Rosenfeld 4108*8f23e9faSHans Rosenfeld iocb->ULPCT = 0; 4109*8f23e9faSHans Rosenfeld if (fct_task->task_flags & TF_WRITE_DATA) { 4110*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_FCP_TRECEIVE64_CX; 4111*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_TRECEIVE; /* Word 11 */ 4112*8f23e9faSHans Rosenfeld 4113*8f23e9faSHans Rosenfeld } else { /* TF_READ_DATA */ 4114*8f23e9faSHans Rosenfeld 4115*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_FCP_TSEND64_CX; 4116*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_TSEND; /* Word 11 */ 4117*8f23e9faSHans Rosenfeld 4118*8f23e9faSHans Rosenfeld if ((dbuf->db_data_size >= 4119*8f23e9faSHans Rosenfeld fct_task->task_expected_xfer_length)) { 4120*8f23e9faSHans Rosenfeld /* enable auto-rsp AP feature */ 4121*8f23e9faSHans Rosenfeld wqe->AR = 0x1; 4122*8f23e9faSHans Rosenfeld iocb->ULPCT = 0x1; /* for cmpl */ 4123*8f23e9faSHans Rosenfeld } 4124*8f23e9faSHans Rosenfeld } 4125*8f23e9faSHans Rosenfeld 4126*8f23e9faSHans Rosenfeld (void) emlxs_sli4_fct_bde_setup(port, cmd_sbp); 4127*8f23e9faSHans Rosenfeld 4128*8f23e9faSHans Rosenfeld /* Word 6 */ 4129*8f23e9faSHans Rosenfeld wqe->ContextTag = ndlp->nlp_Rpi; 4130*8f23e9faSHans Rosenfeld wqe->XRITag = xrip->XRI; 4131*8f23e9faSHans Rosenfeld 4132*8f23e9faSHans Rosenfeld /* Word 7 */ 4133*8f23e9faSHans Rosenfeld wqe->Command = iocb->ULPCOMMAND; 4134*8f23e9faSHans Rosenfeld wqe->Class = cmd_sbp->class; 4135*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 4136*8f23e9faSHans Rosenfeld wqe->Timer = ((timeout > 0xff) ? 0 : timeout); 4137*8f23e9faSHans Rosenfeld wqe->PU = 1; 4138*8f23e9faSHans Rosenfeld 4139*8f23e9faSHans Rosenfeld /* Word 8 */ 4140*8f23e9faSHans Rosenfeld wqe->AbortTag = 0; 4141*8f23e9faSHans Rosenfeld 4142*8f23e9faSHans Rosenfeld /* Word 9 */ 4143*8f23e9faSHans Rosenfeld wqe->RequestTag = xrip->iotag; 4144*8f23e9faSHans Rosenfeld wqe->OXId = (uint16_t)fct_cmd->cmd_oxid; 4145*8f23e9faSHans Rosenfeld 4146*8f23e9faSHans Rosenfeld /* Word 10 */ 4147*8f23e9faSHans Rosenfeld if (xrip->flag & EMLXS_XRI_BUSY) { 4148*8f23e9faSHans Rosenfeld wqe->XC = 1; 4149*8f23e9faSHans Rosenfeld } 4150*8f23e9faSHans Rosenfeld 4151*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4152*8f23e9faSHans Rosenfeld wqe->QOSd = 1; 4153*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4154*8f23e9faSHans Rosenfeld } 4155*8f23e9faSHans Rosenfeld 4156*8f23e9faSHans Rosenfeld /* Word 11 */ 4157*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4158*8f23e9faSHans Rosenfeld 4159*8f23e9faSHans Rosenfeld /* Word 12 */ 4160*8f23e9faSHans Rosenfeld wqe->CmdSpecific = dbuf->db_data_size; 4161*8f23e9faSHans Rosenfeld 4162*8f23e9faSHans Rosenfeld return (IOERR_SUCCESS); 4163*8f23e9faSHans Rosenfeld 4164*8f23e9faSHans Rosenfeld } /* emlxs_sli4_prep_fct_iocb() */ 4165*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 4166*8f23e9faSHans Rosenfeld 4167*8f23e9faSHans Rosenfeld 4168*8f23e9faSHans Rosenfeld /*ARGSUSED*/ 4169*8f23e9faSHans Rosenfeld extern uint32_t 4170*8f23e9faSHans Rosenfeld emlxs_sli4_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel) 4171*8f23e9faSHans Rosenfeld { 4172*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 4173*8f23e9faSHans Rosenfeld fc_packet_t *pkt; 4174*8f23e9faSHans Rosenfeld CHANNEL *cp; 4175*8f23e9faSHans Rosenfeld RPIobj_t *rpip; 4176*8f23e9faSHans Rosenfeld XRIobj_t *xrip; 4177*8f23e9faSHans Rosenfeld emlxs_wqe_t *wqe; 4178*8f23e9faSHans Rosenfeld IOCBQ *iocbq; 4179*8f23e9faSHans Rosenfeld IOCB *iocb; 4180*8f23e9faSHans Rosenfeld NODELIST *node; 4181*8f23e9faSHans Rosenfeld uint16_t iotag; 4182*8f23e9faSHans Rosenfeld uint32_t did; 4183*8f23e9faSHans Rosenfeld off_t offset; 4184*8f23e9faSHans Rosenfeld 4185*8f23e9faSHans Rosenfeld pkt = PRIV2PKT(sbp); 4186*8f23e9faSHans Rosenfeld did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 4187*8f23e9faSHans Rosenfeld cp = &hba->chan[channel]; 4188*8f23e9faSHans Rosenfeld 4189*8f23e9faSHans Rosenfeld iocbq = &sbp->iocbq; 4190*8f23e9faSHans Rosenfeld iocbq->channel = (void *) cp; 4191*8f23e9faSHans Rosenfeld iocbq->port = (void *) port; 4192*8f23e9faSHans Rosenfeld 4193*8f23e9faSHans Rosenfeld wqe = &iocbq->wqe; 4194*8f23e9faSHans Rosenfeld iocb = &iocbq->iocb; 4195*8f23e9faSHans Rosenfeld bzero((void *)wqe, sizeof (emlxs_wqe_t)); 4196*8f23e9faSHans Rosenfeld bzero((void *)iocb, sizeof (IOCB)); 4197*8f23e9faSHans Rosenfeld 4198*8f23e9faSHans Rosenfeld /* Find target node object */ 4199*8f23e9faSHans Rosenfeld node = (NODELIST *)iocbq->node; 4200*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, node); 4201*8f23e9faSHans Rosenfeld 4202*8f23e9faSHans Rosenfeld if (!rpip) { 4203*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4204*8f23e9faSHans Rosenfeld "Unable to find rpi. did=0x%x", did); 4205*8f23e9faSHans Rosenfeld 4206*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 4207*8f23e9faSHans Rosenfeld IOERR_INVALID_RPI, 0); 4208*8f23e9faSHans Rosenfeld return (0xff); 4209*8f23e9faSHans Rosenfeld } 4210*8f23e9faSHans Rosenfeld 4211*8f23e9faSHans Rosenfeld sbp->channel = cp; 4212*8f23e9faSHans Rosenfeld /* Next allocate an Exchange for this command */ 4213*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_alloc_xri(port, sbp, rpip, 4214*8f23e9faSHans Rosenfeld EMLXS_XRI_SOL_FCP_TYPE); 4215*8f23e9faSHans Rosenfeld 4216*8f23e9faSHans Rosenfeld if (!xrip) { 4217*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4218*8f23e9faSHans Rosenfeld "Adapter Busy. Unable to allocate exchange. did=0x%x", did); 4219*8f23e9faSHans Rosenfeld 4220*8f23e9faSHans Rosenfeld return (FC_TRAN_BUSY); 4221*8f23e9faSHans Rosenfeld } 4222*8f23e9faSHans Rosenfeld sbp->bmp = NULL; 4223*8f23e9faSHans Rosenfeld iotag = sbp->iotag; 4224*8f23e9faSHans Rosenfeld 4225*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 4226*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4227*8f23e9faSHans Rosenfeld "FCP: Prep xri=%d iotag=%d oxid=%x rpi=%d", 4228*8f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, xrip->rx_id, rpip->RPI); 4229*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 4230*8f23e9faSHans Rosenfeld 4231*8f23e9faSHans Rosenfeld /* Indicate this is a FCP cmd */ 4232*8f23e9faSHans Rosenfeld iocbq->flag |= IOCB_FCP_CMD; 4233*8f23e9faSHans Rosenfeld 4234*8f23e9faSHans Rosenfeld if (emlxs_sli4_bde_setup(port, sbp)) { 4235*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, xrip, 1); 4236*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4237*8f23e9faSHans Rosenfeld "Adapter Busy. Unable to setup SGE. did=0x%x", did); 4238*8f23e9faSHans Rosenfeld 4239*8f23e9faSHans Rosenfeld return (FC_TRAN_BUSY); 4240*8f23e9faSHans Rosenfeld } 4241*8f23e9faSHans Rosenfeld 4242*8f23e9faSHans Rosenfeld /* DEBUG */ 4243*8f23e9faSHans Rosenfeld #ifdef DEBUG_FCP 4244*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4245*8f23e9faSHans Rosenfeld "FCP: SGLaddr virt %p phys %p size %d", xrip->SGList.virt, 4246*8f23e9faSHans Rosenfeld xrip->SGList.phys, pkt->pkt_datalen); 4247*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "FCP: SGL", (uint32_t *)xrip->SGList.virt, 20, 0); 4248*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4249*8f23e9faSHans Rosenfeld "FCP: CMD virt %p len %d:%d:%d", 4250*8f23e9faSHans Rosenfeld pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen, pkt->pkt_datalen); 4251*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "FCP: CMD", (uint32_t *)pkt->pkt_cmd, 10, 0); 4252*8f23e9faSHans Rosenfeld #endif /* DEBUG_FCP */ 4253*8f23e9faSHans Rosenfeld 4254*8f23e9faSHans Rosenfeld offset = (off_t)((uint64_t)((unsigned long) 4255*8f23e9faSHans Rosenfeld xrip->SGList.virt) - 4256*8f23e9faSHans Rosenfeld (uint64_t)((unsigned long) 4257*8f23e9faSHans Rosenfeld hba->sli.sli4.slim2.virt)); 4258*8f23e9faSHans Rosenfeld 4259*8f23e9faSHans Rosenfeld EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 4260*8f23e9faSHans Rosenfeld xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 4261*8f23e9faSHans Rosenfeld 4262*8f23e9faSHans Rosenfeld /* if device is FCP-2 device, set the following bit */ 4263*8f23e9faSHans Rosenfeld /* that says to run the FC-TAPE protocol. */ 4264*8f23e9faSHans Rosenfeld if (node->nlp_fcp_info & NLP_FCP_2_DEVICE) { 4265*8f23e9faSHans Rosenfeld wqe->ERP = 1; 4266*8f23e9faSHans Rosenfeld } 4267*8f23e9faSHans Rosenfeld 4268*8f23e9faSHans Rosenfeld if (pkt->pkt_datalen == 0) { 4269*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_FCP_ICMND64_CR; 4270*8f23e9faSHans Rosenfeld wqe->Command = CMD_FCP_ICMND64_CR; 4271*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 4272*8f23e9faSHans Rosenfeld } else if (pkt->pkt_tran_type == FC_PKT_FCP_READ) { 4273*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_FCP_IREAD64_CR; 4274*8f23e9faSHans Rosenfeld wqe->Command = CMD_FCP_IREAD64_CR; 4275*8f23e9faSHans Rosenfeld wqe->CmdType = WQE_TYPE_FCP_DATA_IN; 4276*8f23e9faSHans Rosenfeld wqe->PU = PARM_XFER_CHECK; 4277*8f23e9faSHans Rosenfeld } else { 4278*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_FCP_IWRITE64_CR; 4279*8f23e9faSHans Rosenfeld wqe->Command = CMD_FCP_IWRITE64_CR; 428082527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_FCP_DATA_OUT; 428182527734SSukumar Swaminathan } 428282527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount = pkt->pkt_datalen; 428382527734SSukumar Swaminathan 4284*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4285*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4286*8f23e9faSHans Rosenfeld } 4287a9800bebSGarrett D'Amore wqe->ContextTag = rpip->RPI; 428882527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 4289a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 429082527734SSukumar Swaminathan wqe->Timer = 429182527734SSukumar Swaminathan ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 429282527734SSukumar Swaminathan 429382527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 429482527734SSukumar Swaminathan wqe->CCPE = 1; 429582527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 429682527734SSukumar Swaminathan } 429782527734SSukumar Swaminathan 429882527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 429982527734SSukumar Swaminathan case FC_TRAN_CLASS2: 430082527734SSukumar Swaminathan wqe->Class = CLASS2; 430182527734SSukumar Swaminathan break; 430282527734SSukumar Swaminathan case FC_TRAN_CLASS3: 430382527734SSukumar Swaminathan default: 430482527734SSukumar Swaminathan wqe->Class = CLASS3; 430582527734SSukumar Swaminathan break; 430682527734SSukumar Swaminathan } 430782527734SSukumar Swaminathan sbp->class = wqe->Class; 430882527734SSukumar Swaminathan wqe->RequestTag = iotag; 4309*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 4310*8f23e9faSHans Rosenfeld 431182527734SSukumar Swaminathan return (FC_SUCCESS); 431282527734SSukumar Swaminathan } /* emlxs_sli4_prep_fcp_iocb() */ 431382527734SSukumar Swaminathan 431482527734SSukumar Swaminathan 431582527734SSukumar Swaminathan /*ARGSUSED*/ 431682527734SSukumar Swaminathan static uint32_t 431782527734SSukumar Swaminathan emlxs_sli4_prep_ip_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 431882527734SSukumar Swaminathan { 431982527734SSukumar Swaminathan return (FC_TRAN_BUSY); 432082527734SSukumar Swaminathan 432182527734SSukumar Swaminathan } /* emlxs_sli4_prep_ip_iocb() */ 432282527734SSukumar Swaminathan 432382527734SSukumar Swaminathan 432482527734SSukumar Swaminathan /*ARGSUSED*/ 432582527734SSukumar Swaminathan static uint32_t 432682527734SSukumar Swaminathan emlxs_sli4_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 432782527734SSukumar Swaminathan { 432882527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 432982527734SSukumar Swaminathan fc_packet_t *pkt; 433082527734SSukumar Swaminathan IOCBQ *iocbq; 433182527734SSukumar Swaminathan IOCB *iocb; 433282527734SSukumar Swaminathan emlxs_wqe_t *wqe; 4333a9800bebSGarrett D'Amore FCFIobj_t *fcfp; 4334*8f23e9faSHans Rosenfeld RPIobj_t *reserved_rpip = NULL; 4335a9800bebSGarrett D'Amore RPIobj_t *rpip = NULL; 4336a9800bebSGarrett D'Amore XRIobj_t *xrip; 433782527734SSukumar Swaminathan CHANNEL *cp; 433882527734SSukumar Swaminathan uint32_t did; 433982527734SSukumar Swaminathan uint32_t cmd; 434082527734SSukumar Swaminathan ULP_SGE64 stage_sge; 434182527734SSukumar Swaminathan ULP_SGE64 *sge; 434282527734SSukumar Swaminathan ddi_dma_cookie_t *cp_cmd; 434382527734SSukumar Swaminathan ddi_dma_cookie_t *cp_resp; 434482527734SSukumar Swaminathan emlxs_node_t *node; 4345b3660a96SSukumar Swaminathan off_t offset; 434682527734SSukumar Swaminathan 434782527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 434882527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 434982527734SSukumar Swaminathan 435082527734SSukumar Swaminathan iocbq = &sbp->iocbq; 435182527734SSukumar Swaminathan wqe = &iocbq->wqe; 435282527734SSukumar Swaminathan iocb = &iocbq->iocb; 435382527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 435482527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 435582527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 435682527734SSukumar Swaminathan 435782527734SSukumar Swaminathan /* Initalize iocbq */ 435882527734SSukumar Swaminathan iocbq->port = (void *) port; 435982527734SSukumar Swaminathan iocbq->channel = (void *) cp; 436082527734SSukumar Swaminathan 436182527734SSukumar Swaminathan sbp->channel = cp; 436282527734SSukumar Swaminathan sbp->bmp = NULL; 436382527734SSukumar Swaminathan 436482527734SSukumar Swaminathan #if (EMLXS_MODREV >= EMLXS_MODREV3) 436582527734SSukumar Swaminathan cp_cmd = pkt->pkt_cmd_cookie; 436682527734SSukumar Swaminathan cp_resp = pkt->pkt_resp_cookie; 436782527734SSukumar Swaminathan #else 436882527734SSukumar Swaminathan cp_cmd = &pkt->pkt_cmd_cookie; 436982527734SSukumar Swaminathan cp_resp = &pkt->pkt_resp_cookie; 437082527734SSukumar Swaminathan #endif /* >= EMLXS_MODREV3 */ 437182527734SSukumar Swaminathan 437282527734SSukumar Swaminathan /* CMD payload */ 437382527734SSukumar Swaminathan sge = &stage_sge; 437482527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_cmd->dmac_laddress); 437582527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_cmd->dmac_laddress); 437682527734SSukumar Swaminathan sge->length = pkt->pkt_cmdlen; 437782527734SSukumar Swaminathan sge->offset = 0; 4378*8f23e9faSHans Rosenfeld sge->type = 0; 4379*8f23e9faSHans Rosenfeld 4380*8f23e9faSHans Rosenfeld cmd = *((uint32_t *)pkt->pkt_cmd); 4381*8f23e9faSHans Rosenfeld cmd &= ELS_CMD_MASK; 438282527734SSukumar Swaminathan 438382527734SSukumar Swaminathan /* Initalize iocb */ 438482527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 438582527734SSukumar Swaminathan /* ELS Response */ 438682527734SSukumar Swaminathan 4387*8f23e9faSHans Rosenfeld sbp->xrip = 0; 4388*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_register_xri(port, sbp, 4389*8f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.rx_id, did); 439082527734SSukumar Swaminathan 4391a9800bebSGarrett D'Amore if (!xrip) { 439282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 439382527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 439482527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 439582527734SSukumar Swaminathan 439682527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 439782527734SSukumar Swaminathan IOERR_NO_XRI, 0); 439882527734SSukumar Swaminathan return (0xff); 439982527734SSukumar Swaminathan } 440082527734SSukumar Swaminathan 4401a9800bebSGarrett D'Amore rpip = xrip->rpip; 440282527734SSukumar Swaminathan 4403a9800bebSGarrett D'Amore if (!rpip) { 440482527734SSukumar Swaminathan /* This means that we had a node registered */ 440582527734SSukumar Swaminathan /* when the unsol request came in but the node */ 440682527734SSukumar Swaminathan /* has since been unregistered. */ 440782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 440882527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 440982527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 441082527734SSukumar Swaminathan 441182527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 441282527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 441382527734SSukumar Swaminathan return (0xff); 441482527734SSukumar Swaminathan } 441582527734SSukumar Swaminathan 441682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4417*8f23e9faSHans Rosenfeld "ELS: Prep xri=%d iotag=%d oxid=%x rpi=%d", 4418a9800bebSGarrett D'Amore xrip->XRI, xrip->iotag, xrip->rx_id, rpip->RPI); 441982527734SSukumar Swaminathan 4420*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_XMIT_ELS_RSP64_CX; 442182527734SSukumar Swaminathan wqe->Command = CMD_XMIT_ELS_RSP64_CX; 442282527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 4423*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4424*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4425*8f23e9faSHans Rosenfeld } 442682527734SSukumar Swaminathan 442782527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrHigh = sge->addrHigh; 442882527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.addrLow = sge->addrLow; 442982527734SSukumar Swaminathan wqe->un.ElsRsp.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 4430*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.PayloadLength = pkt->pkt_cmdlen; 443182527734SSukumar Swaminathan 443282527734SSukumar Swaminathan wqe->un.ElsRsp.RemoteId = did; 443382527734SSukumar Swaminathan wqe->PU = 0x3; 4434*8f23e9faSHans Rosenfeld wqe->OXId = xrip->rx_id; 443582527734SSukumar Swaminathan 443682527734SSukumar Swaminathan sge->last = 1; 443782527734SSukumar Swaminathan /* Now sge is fully staged */ 443882527734SSukumar Swaminathan 4439a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 444082527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 444182527734SSukumar Swaminathan sizeof (ULP_SGE64)); 444282527734SSukumar Swaminathan 4443*8f23e9faSHans Rosenfeld if (rpip->RPI == FABRIC_RPI) { 4444*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 4445*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_VPI_CONTEXT; 4446*8f23e9faSHans Rosenfeld } else { 4447*8f23e9faSHans Rosenfeld wqe->ContextTag = rpip->RPI; 4448*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 4449*8f23e9faSHans Rosenfeld } 4450*8f23e9faSHans Rosenfeld 4451*8f23e9faSHans Rosenfeld if ((cmd == ELS_CMD_ACC) && (sbp->ucmd == ELS_CMD_FLOGI)) { 4452*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.SP = 1; 4453*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.LocalId = 0xFFFFFE; 4454*8f23e9faSHans Rosenfeld } 445582527734SSukumar Swaminathan 445682527734SSukumar Swaminathan } else { 445782527734SSukumar Swaminathan /* ELS Request */ 445882527734SSukumar Swaminathan 4459*8f23e9faSHans Rosenfeld fcfp = port->vpip->vfip->fcfp; 446082527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 4461a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 446282527734SSukumar Swaminathan 4463a9800bebSGarrett D'Amore if (!rpip) { 4464*8f23e9faSHans Rosenfeld /* Use the fabric rpi */ 4465*8f23e9faSHans Rosenfeld rpip = port->vpip->fabric_rpip; 446682527734SSukumar Swaminathan } 446782527734SSukumar Swaminathan 446882527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 4469*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_alloc_xri(port, sbp, rpip, 4470*8f23e9faSHans Rosenfeld EMLXS_XRI_SOL_ELS_TYPE); 447182527734SSukumar Swaminathan 4472a9800bebSGarrett D'Amore if (!xrip) { 447382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4474a9800bebSGarrett D'Amore "Adapter Busy. Unable to allocate exchange. " 447582527734SSukumar Swaminathan "did=0x%x", did); 447682527734SSukumar Swaminathan 447782527734SSukumar Swaminathan return (FC_TRAN_BUSY); 447882527734SSukumar Swaminathan } 447982527734SSukumar Swaminathan 448082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4481*8f23e9faSHans Rosenfeld "ELS: Prep xri=%d iotag=%d rpi=%d", 4482*8f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, rpip->RPI); 448382527734SSukumar Swaminathan 4484*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_ELS_REQUEST64_CR; 448582527734SSukumar Swaminathan wqe->Command = CMD_ELS_REQUEST64_CR; 448682527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_ELS; 4487*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4488*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4489*8f23e9faSHans Rosenfeld } 449082527734SSukumar Swaminathan 449182527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrHigh = sge->addrHigh; 449282527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.addrLow = sge->addrLow; 449382527734SSukumar Swaminathan wqe->un.ElsCmd.Payload.tus.f.bdeSize = pkt->pkt_cmdlen; 449482527734SSukumar Swaminathan 4495*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.RemoteId = did; 4496*8f23e9faSHans Rosenfeld wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 4497*8f23e9faSHans Rosenfeld 449882527734SSukumar Swaminathan /* setup for rsp */ 449982527734SSukumar Swaminathan iocb->un.elsreq64.remoteID = (did == BCAST_DID) ? 0 : did; 450082527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 450182527734SSukumar Swaminathan 450282527734SSukumar Swaminathan sge->last = 0; 450382527734SSukumar Swaminathan 4504a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 450582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 450682527734SSukumar Swaminathan sizeof (ULP_SGE64)); 450782527734SSukumar Swaminathan 450882527734SSukumar Swaminathan wqe->un.ElsCmd.PayloadLength = 450982527734SSukumar Swaminathan pkt->pkt_cmdlen; /* Byte offset of rsp data */ 451082527734SSukumar Swaminathan 451182527734SSukumar Swaminathan /* RSP payload */ 451282527734SSukumar Swaminathan sge = &stage_sge; 451382527734SSukumar Swaminathan sge->addrHigh = PADDR_HI(cp_resp->dmac_laddress); 451482527734SSukumar Swaminathan sge->addrLow = PADDR_LO(cp_resp->dmac_laddress); 451582527734SSukumar Swaminathan sge->length = pkt->pkt_rsplen; 4516b3660a96SSukumar Swaminathan sge->offset = 0; 451782527734SSukumar Swaminathan sge->last = 1; 451882527734SSukumar Swaminathan /* Now sge is fully staged */ 451982527734SSukumar Swaminathan 4520a9800bebSGarrett D'Amore sge = xrip->SGList.virt; 452182527734SSukumar Swaminathan sge++; 452282527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)&stage_sge, (uint8_t *)sge, 452382527734SSukumar Swaminathan sizeof (ULP_SGE64)); 452482527734SSukumar Swaminathan #ifdef DEBUG_ELS 452582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4526*8f23e9faSHans Rosenfeld "ELS: SGLaddr virt %p phys %p", 4527a9800bebSGarrett D'Amore xrip->SGList.virt, xrip->SGList.phys); 452882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4529*8f23e9faSHans Rosenfeld "ELS: PAYLOAD virt %p phys %p", 453082527734SSukumar Swaminathan pkt->pkt_cmd, cp_cmd->dmac_laddress); 4531*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "ELS: SGL", (uint32_t *)xrip->SGList.virt, 4532a9800bebSGarrett D'Amore 12, 0); 4533*8f23e9faSHans Rosenfeld #endif /* DEBUG_ELS */ 453482527734SSukumar Swaminathan 453582527734SSukumar Swaminathan switch (cmd) { 453682527734SSukumar Swaminathan case ELS_CMD_FLOGI: 453782527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 4538*8f23e9faSHans Rosenfeld 4539*8f23e9faSHans Rosenfeld if ((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) == 4540*8f23e9faSHans Rosenfeld SLI_INTF_IF_TYPE_0) { 4541*8f23e9faSHans Rosenfeld wqe->ContextTag = fcfp->FCFI; 4542*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_FCFI_CONTEXT; 4543*8f23e9faSHans Rosenfeld } else { 4544*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 4545*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_VPI_CONTEXT; 4546*8f23e9faSHans Rosenfeld } 4547*8f23e9faSHans Rosenfeld 454882527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 454982527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 455082527734SSukumar Swaminathan } 4551*8f23e9faSHans Rosenfeld 4552*8f23e9faSHans Rosenfeld if (hba->topology == TOPOLOGY_LOOP) { 4553*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.LocalId = port->did; 4554*8f23e9faSHans Rosenfeld } 4555*8f23e9faSHans Rosenfeld 4556*8f23e9faSHans Rosenfeld wqe->ELSId = WQE_ELSID_FLOGI; 455782527734SSukumar Swaminathan break; 455882527734SSukumar Swaminathan case ELS_CMD_FDISC: 455982527734SSukumar Swaminathan wqe->un.ElsCmd.SP = 1; 4560*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 456182527734SSukumar Swaminathan wqe->ContextType = WQE_VPI_CONTEXT; 4562*8f23e9faSHans Rosenfeld 456382527734SSukumar Swaminathan if (hba->flag & FC_FIP_SUPPORTED) { 456482527734SSukumar Swaminathan wqe->CmdType |= WQE_TYPE_MASK_FIP; 456582527734SSukumar Swaminathan } 4566*8f23e9faSHans Rosenfeld 4567*8f23e9faSHans Rosenfeld wqe->ELSId = WQE_ELSID_FDISC; 456882527734SSukumar Swaminathan break; 456982527734SSukumar Swaminathan case ELS_CMD_LOGO: 4570*8f23e9faSHans Rosenfeld if ((did == FABRIC_DID) && 4571*8f23e9faSHans Rosenfeld (hba->flag & FC_FIP_SUPPORTED)) { 4572*8f23e9faSHans Rosenfeld wqe->CmdType |= WQE_TYPE_MASK_FIP; 4573*8f23e9faSHans Rosenfeld } 4574*8f23e9faSHans Rosenfeld 4575*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 4576*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_VPI_CONTEXT; 4577*8f23e9faSHans Rosenfeld wqe->ELSId = WQE_ELSID_LOGO; 4578*8f23e9faSHans Rosenfeld break; 4579*8f23e9faSHans Rosenfeld case ELS_CMD_PLOGI: 4580*8f23e9faSHans Rosenfeld if (rpip->RPI == FABRIC_RPI) { 4581*8f23e9faSHans Rosenfeld if (hba->flag & FC_PT_TO_PT) { 4582*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.SP = 1; 4583*8f23e9faSHans Rosenfeld wqe->un.ElsCmd.LocalId = port->did; 4584a9800bebSGarrett D'Amore } 4585*8f23e9faSHans Rosenfeld 4586*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 4587a9800bebSGarrett D'Amore wqe->ContextType = WQE_VPI_CONTEXT; 4588*8f23e9faSHans Rosenfeld } else { 4589*8f23e9faSHans Rosenfeld wqe->ContextTag = rpip->RPI; 4590*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 459182527734SSukumar Swaminathan } 459282527734SSukumar Swaminathan 4593*8f23e9faSHans Rosenfeld wqe->ELSId = WQE_ELSID_PLOGI; 4594*8f23e9faSHans Rosenfeld break; 459582527734SSukumar Swaminathan default: 4596*8f23e9faSHans Rosenfeld if (rpip->RPI == FABRIC_RPI) { 4597*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 4598*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_VPI_CONTEXT; 4599*8f23e9faSHans Rosenfeld } else { 4600*8f23e9faSHans Rosenfeld wqe->ContextTag = rpip->RPI; 4601*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 4602*8f23e9faSHans Rosenfeld } 4603*8f23e9faSHans Rosenfeld 4604*8f23e9faSHans Rosenfeld wqe->ELSId = WQE_ELSID_CMD; 460582527734SSukumar Swaminathan break; 460682527734SSukumar Swaminathan } 460782527734SSukumar Swaminathan 4608*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 4609*8f23e9faSHans Rosenfeld /* This allows fct to abort the request */ 4610*8f23e9faSHans Rosenfeld if (sbp->fct_cmd) { 4611*8f23e9faSHans Rosenfeld sbp->fct_cmd->cmd_oxid = xrip->XRI; 4612*8f23e9faSHans Rosenfeld sbp->fct_cmd->cmd_rxid = 0xFFFF; 4613*8f23e9faSHans Rosenfeld } 4614*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 4615*8f23e9faSHans Rosenfeld } 4616*8f23e9faSHans Rosenfeld 4617*8f23e9faSHans Rosenfeld if (wqe->ContextType == WQE_VPI_CONTEXT) { 4618*8f23e9faSHans Rosenfeld reserved_rpip = emlxs_rpi_reserve_notify(port, did, xrip); 4619*8f23e9faSHans Rosenfeld 4620*8f23e9faSHans Rosenfeld if (!reserved_rpip) { 4621*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 4622*8f23e9faSHans Rosenfeld "Unable to alloc reserved RPI. rxid=%x. Rejecting.", 4623*8f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.rx_id); 4624*8f23e9faSHans Rosenfeld 4625*8f23e9faSHans Rosenfeld emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 4626*8f23e9faSHans Rosenfeld IOERR_INVALID_RPI, 0); 4627*8f23e9faSHans Rosenfeld return (0xff); 4628*8f23e9faSHans Rosenfeld } 4629*8f23e9faSHans Rosenfeld 4630*8f23e9faSHans Rosenfeld /* Store the reserved rpi */ 4631*8f23e9faSHans Rosenfeld if (wqe->Command == CMD_ELS_REQUEST64_CR) { 4632*8f23e9faSHans Rosenfeld wqe->OXId = reserved_rpip->RPI; 4633*8f23e9faSHans Rosenfeld } else { 4634*8f23e9faSHans Rosenfeld wqe->CmdSpecific = reserved_rpip->RPI; 4635*8f23e9faSHans Rosenfeld } 4636*8f23e9faSHans Rosenfeld } 4637*8f23e9faSHans Rosenfeld 4638*8f23e9faSHans Rosenfeld offset = (off_t)((uint64_t)((unsigned long) 4639*8f23e9faSHans Rosenfeld xrip->SGList.virt) - 4640*8f23e9faSHans Rosenfeld (uint64_t)((unsigned long) 4641b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 4642b3660a96SSukumar Swaminathan 4643a9800bebSGarrett D'Amore EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 4644a9800bebSGarrett D'Amore xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 464582527734SSukumar Swaminathan 464682527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 464782527734SSukumar Swaminathan wqe->CCPE = 1; 464882527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 464982527734SSukumar Swaminathan } 465082527734SSukumar Swaminathan 465182527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 465282527734SSukumar Swaminathan case FC_TRAN_CLASS2: 465382527734SSukumar Swaminathan wqe->Class = CLASS2; 465482527734SSukumar Swaminathan break; 465582527734SSukumar Swaminathan case FC_TRAN_CLASS3: 465682527734SSukumar Swaminathan default: 465782527734SSukumar Swaminathan wqe->Class = CLASS3; 465882527734SSukumar Swaminathan break; 465982527734SSukumar Swaminathan } 466082527734SSukumar Swaminathan sbp->class = wqe->Class; 4661a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 4662a9800bebSGarrett D'Amore wqe->RequestTag = xrip->iotag; 4663*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 466482527734SSukumar Swaminathan return (FC_SUCCESS); 466582527734SSukumar Swaminathan 466682527734SSukumar Swaminathan } /* emlxs_sli4_prep_els_iocb() */ 466782527734SSukumar Swaminathan 466882527734SSukumar Swaminathan 466982527734SSukumar Swaminathan /*ARGSUSED*/ 467082527734SSukumar Swaminathan static uint32_t 467182527734SSukumar Swaminathan emlxs_sli4_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp) 467282527734SSukumar Swaminathan { 467382527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 467482527734SSukumar Swaminathan fc_packet_t *pkt; 467582527734SSukumar Swaminathan IOCBQ *iocbq; 467682527734SSukumar Swaminathan IOCB *iocb; 467782527734SSukumar Swaminathan emlxs_wqe_t *wqe; 467882527734SSukumar Swaminathan NODELIST *node = NULL; 467982527734SSukumar Swaminathan CHANNEL *cp; 4680a9800bebSGarrett D'Amore RPIobj_t *rpip; 4681a9800bebSGarrett D'Amore XRIobj_t *xrip; 468282527734SSukumar Swaminathan uint32_t did; 4683b3660a96SSukumar Swaminathan off_t offset; 468482527734SSukumar Swaminathan 468582527734SSukumar Swaminathan pkt = PRIV2PKT(sbp); 468682527734SSukumar Swaminathan did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id); 468782527734SSukumar Swaminathan 468882527734SSukumar Swaminathan iocbq = &sbp->iocbq; 468982527734SSukumar Swaminathan wqe = &iocbq->wqe; 469082527734SSukumar Swaminathan iocb = &iocbq->iocb; 469182527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 469282527734SSukumar Swaminathan bzero((void *)iocb, sizeof (IOCB)); 469382527734SSukumar Swaminathan 469482527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 469582527734SSukumar Swaminathan 469682527734SSukumar Swaminathan iocbq->port = (void *) port; 469782527734SSukumar Swaminathan iocbq->channel = (void *) cp; 469882527734SSukumar Swaminathan 469982527734SSukumar Swaminathan sbp->bmp = NULL; 470082527734SSukumar Swaminathan sbp->channel = cp; 470182527734SSukumar Swaminathan 470282527734SSukumar Swaminathan /* Initalize wqe */ 470382527734SSukumar Swaminathan if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) { 470482527734SSukumar Swaminathan /* CT Response */ 470582527734SSukumar Swaminathan 4706*8f23e9faSHans Rosenfeld sbp->xrip = 0; 4707*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_register_xri(port, sbp, 4708*8f23e9faSHans Rosenfeld pkt->pkt_cmd_fhdr.rx_id, did); 470982527734SSukumar Swaminathan 4710a9800bebSGarrett D'Amore if (!xrip) { 471182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 471282527734SSukumar Swaminathan "Unable to find XRI. rxid=%x", 471382527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 471482527734SSukumar Swaminathan 471582527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 471682527734SSukumar Swaminathan IOERR_NO_XRI, 0); 471782527734SSukumar Swaminathan return (0xff); 471882527734SSukumar Swaminathan } 471982527734SSukumar Swaminathan 4720a9800bebSGarrett D'Amore rpip = xrip->rpip; 472182527734SSukumar Swaminathan 4722a9800bebSGarrett D'Amore if (!rpip) { 472382527734SSukumar Swaminathan /* This means that we had a node registered */ 472482527734SSukumar Swaminathan /* when the unsol request came in but the node */ 472582527734SSukumar Swaminathan /* has since been unregistered. */ 472682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 472782527734SSukumar Swaminathan "Unable to find RPI. rxid=%x", 472882527734SSukumar Swaminathan pkt->pkt_cmd_fhdr.rx_id); 472982527734SSukumar Swaminathan 473082527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 473182527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 473282527734SSukumar Swaminathan return (0xff); 473382527734SSukumar Swaminathan } 473482527734SSukumar Swaminathan 473582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4736*8f23e9faSHans Rosenfeld "CT: Prep xri=%d iotag=%d oxid=%x rpi=%d", 4737*8f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, xrip->rx_id, rpip->RPI); 473882527734SSukumar Swaminathan 473982527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 474082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 474182527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 474282527734SSukumar Swaminathan 474382527734SSukumar Swaminathan return (FC_TRAN_BUSY); 474482527734SSukumar Swaminathan } 474582527734SSukumar Swaminathan 4746*8f23e9faSHans Rosenfeld if (!(hba->model_info.chip & EMLXS_BE_CHIPS)) { 4747*8f23e9faSHans Rosenfeld wqe->un.XmitSeq.Rsvd0 = 0; /* Word3 now reserved */ 4748*8f23e9faSHans Rosenfeld } 4749*8f23e9faSHans Rosenfeld 4750*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4751*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4752*8f23e9faSHans Rosenfeld } 4753*8f23e9faSHans Rosenfeld 4754*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CR; 475582527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 475682527734SSukumar Swaminathan wqe->Command = CMD_XMIT_SEQUENCE64_CR; 4757*8f23e9faSHans Rosenfeld wqe->LenLoc = 2; 4758*8f23e9faSHans Rosenfeld 4759*8f23e9faSHans Rosenfeld if (((SLI_CT_REQUEST *) pkt->pkt_cmd)->CommandResponse.bits. 4760*8f23e9faSHans Rosenfeld CmdRsp == (LE_SWAP16(SLI_CT_LOOPBACK))) { 4761*8f23e9faSHans Rosenfeld wqe->un.XmitSeq.xo = 1; 4762*8f23e9faSHans Rosenfeld } else { 4763*8f23e9faSHans Rosenfeld wqe->un.XmitSeq.xo = 0; 4764*8f23e9faSHans Rosenfeld } 476582527734SSukumar Swaminathan 476682527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_LAST_SEQ) { 476782527734SSukumar Swaminathan wqe->un.XmitSeq.ls = 1; 476882527734SSukumar Swaminathan } 476982527734SSukumar Swaminathan 477082527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_SEQ_INITIATIVE) { 477182527734SSukumar Swaminathan wqe->un.XmitSeq.si = 1; 477282527734SSukumar Swaminathan } 477382527734SSukumar Swaminathan 477482527734SSukumar Swaminathan wqe->un.XmitSeq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 477582527734SSukumar Swaminathan wqe->un.XmitSeq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 477682527734SSukumar Swaminathan wqe->un.XmitSeq.Type = pkt->pkt_cmd_fhdr.type; 4777a9800bebSGarrett D'Amore wqe->OXId = xrip->rx_id; 477862379b58SSukumar Swaminathan wqe->XC = 0; /* xri_tag is a new exchange */ 4779*8f23e9faSHans Rosenfeld wqe->CmdSpecific = wqe->un.GenReq.Payload.tus.f.bdeSize; 478082527734SSukumar Swaminathan 478182527734SSukumar Swaminathan } else { 478282527734SSukumar Swaminathan /* CT Request */ 478382527734SSukumar Swaminathan 478482527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 4785a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 478682527734SSukumar Swaminathan 4787a9800bebSGarrett D'Amore if (!rpip) { 478882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_failed_msg, 4789*8f23e9faSHans Rosenfeld "Unable to find rpi. did=0x%x rpi=%d", 4790a9800bebSGarrett D'Amore did, node->nlp_Rpi); 479182527734SSukumar Swaminathan 479282527734SSukumar Swaminathan emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT, 479382527734SSukumar Swaminathan IOERR_INVALID_RPI, 0); 479482527734SSukumar Swaminathan return (0xff); 479582527734SSukumar Swaminathan } 479682527734SSukumar Swaminathan 479782527734SSukumar Swaminathan /* Next allocate an Exchange for this command */ 4798*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_alloc_xri(port, sbp, rpip, 4799*8f23e9faSHans Rosenfeld EMLXS_XRI_SOL_CT_TYPE); 480082527734SSukumar Swaminathan 4801a9800bebSGarrett D'Amore if (!xrip) { 480282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 4803a9800bebSGarrett D'Amore "Adapter Busy. Unable to allocate exchange. " 480482527734SSukumar Swaminathan "did=0x%x", did); 480582527734SSukumar Swaminathan 480682527734SSukumar Swaminathan return (FC_TRAN_BUSY); 480782527734SSukumar Swaminathan } 480882527734SSukumar Swaminathan 480982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4810*8f23e9faSHans Rosenfeld "CT: Prep xri=%d iotag=%d oxid=%x rpi=%d", 4811*8f23e9faSHans Rosenfeld xrip->XRI, xrip->iotag, xrip->rx_id, rpip->RPI); 481282527734SSukumar Swaminathan 481382527734SSukumar Swaminathan if (emlxs_sli4_bde_setup(port, sbp)) { 481482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 481582527734SSukumar Swaminathan "Adapter Busy. Unable to setup SGE. did=0x%x", did); 481682527734SSukumar Swaminathan 4817*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, xrip, 1); 481882527734SSukumar Swaminathan return (FC_TRAN_BUSY); 481982527734SSukumar Swaminathan } 482082527734SSukumar Swaminathan 4821*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.PHWQ)) { 4822*8f23e9faSHans Rosenfeld wqe->DBDE = 1; /* Data type for BDE 0 */ 4823*8f23e9faSHans Rosenfeld } 4824*8f23e9faSHans Rosenfeld 4825*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_GEN_REQUEST64_CR; 482682527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 482782527734SSukumar Swaminathan wqe->Command = CMD_GEN_REQUEST64_CR; 482882527734SSukumar Swaminathan wqe->un.GenReq.la = 1; 482982527734SSukumar Swaminathan wqe->un.GenReq.DFctl = pkt->pkt_cmd_fhdr.df_ctl; 483082527734SSukumar Swaminathan wqe->un.GenReq.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 483182527734SSukumar Swaminathan wqe->un.GenReq.Type = pkt->pkt_cmd_fhdr.type; 483282527734SSukumar Swaminathan 483382527734SSukumar Swaminathan #ifdef DEBUG_CT 483482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4835*8f23e9faSHans Rosenfeld "CT: SGLaddr virt %p phys %p", xrip->SGList.virt, 4836a9800bebSGarrett D'Amore xrip->SGList.phys); 4837*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "CT: SGL", (uint32_t *)xrip->SGList.virt, 4838a9800bebSGarrett D'Amore 12, 0); 483982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4840*8f23e9faSHans Rosenfeld "CT: CMD virt %p len %d:%d", 484182527734SSukumar Swaminathan pkt->pkt_cmd, pkt->pkt_cmdlen, pkt->pkt_rsplen); 4842*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "CT: DATA", (uint32_t *)pkt->pkt_cmd, 4843*8f23e9faSHans Rosenfeld 20, 0); 484482527734SSukumar Swaminathan #endif /* DEBUG_CT */ 4845*8f23e9faSHans Rosenfeld 4846*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 4847*8f23e9faSHans Rosenfeld /* This allows fct to abort the request */ 4848*8f23e9faSHans Rosenfeld if (sbp->fct_cmd) { 4849*8f23e9faSHans Rosenfeld sbp->fct_cmd->cmd_oxid = xrip->XRI; 4850*8f23e9faSHans Rosenfeld sbp->fct_cmd->cmd_rxid = 0xFFFF; 4851*8f23e9faSHans Rosenfeld } 4852*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 485382527734SSukumar Swaminathan } 485482527734SSukumar Swaminathan 485582527734SSukumar Swaminathan /* Setup for rsp */ 485682527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Rctl = pkt->pkt_cmd_fhdr.r_ctl; 485782527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Type = pkt->pkt_cmd_fhdr.type; 485882527734SSukumar Swaminathan iocb->un.genreq64.w5.hcsw.Dfctl = pkt->pkt_cmd_fhdr.df_ctl; 485982527734SSukumar Swaminathan iocb->ULPPU = 1; /* Wd4 is relative offset */ 486082527734SSukumar Swaminathan 4861b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 4862a9800bebSGarrett D'Amore xrip->SGList.virt) - 4863b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 4864b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 4865b3660a96SSukumar Swaminathan 4866a9800bebSGarrett D'Amore EMLXS_MPDATA_SYNC(xrip->SGList.dma_handle, offset, 4867a9800bebSGarrett D'Amore xrip->SGList.size, DDI_DMA_SYNC_FORDEV); 486882527734SSukumar Swaminathan 4869a9800bebSGarrett D'Amore wqe->ContextTag = rpip->RPI; 487082527734SSukumar Swaminathan wqe->ContextType = WQE_RPI_CONTEXT; 4871a9800bebSGarrett D'Amore wqe->XRITag = xrip->XRI; 4872*8f23e9faSHans Rosenfeld wqe->Timer = ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout); 487382527734SSukumar Swaminathan 487482527734SSukumar Swaminathan if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_CHAINED_SEQ) { 487582527734SSukumar Swaminathan wqe->CCPE = 1; 487682527734SSukumar Swaminathan wqe->CCP = pkt->pkt_cmd_fhdr.rsvd; 487782527734SSukumar Swaminathan } 487882527734SSukumar Swaminathan 487982527734SSukumar Swaminathan switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) { 488082527734SSukumar Swaminathan case FC_TRAN_CLASS2: 488182527734SSukumar Swaminathan wqe->Class = CLASS2; 488282527734SSukumar Swaminathan break; 488382527734SSukumar Swaminathan case FC_TRAN_CLASS3: 488482527734SSukumar Swaminathan default: 488582527734SSukumar Swaminathan wqe->Class = CLASS3; 488682527734SSukumar Swaminathan break; 488782527734SSukumar Swaminathan } 488882527734SSukumar Swaminathan sbp->class = wqe->Class; 4889a9800bebSGarrett D'Amore wqe->RequestTag = xrip->iotag; 4890*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 489182527734SSukumar Swaminathan return (FC_SUCCESS); 489282527734SSukumar Swaminathan 489382527734SSukumar Swaminathan } /* emlxs_sli4_prep_ct_iocb() */ 489482527734SSukumar Swaminathan 489582527734SSukumar Swaminathan 489682527734SSukumar Swaminathan /*ARGSUSED*/ 489782527734SSukumar Swaminathan static int 4898a9800bebSGarrett D'Amore emlxs_sli4_read_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 489982527734SSukumar Swaminathan { 490082527734SSukumar Swaminathan uint32_t *ptr; 490182527734SSukumar Swaminathan EQE_u eqe; 490282527734SSukumar Swaminathan int rc = 0; 4903b3660a96SSukumar Swaminathan off_t offset; 490482527734SSukumar Swaminathan 4905*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 4906*8f23e9faSHans Rosenfeld 490782527734SSukumar Swaminathan ptr = eq->addr.virt; 490882527734SSukumar Swaminathan ptr += eq->host_index; 490982527734SSukumar Swaminathan 4910b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 4911b3660a96SSukumar Swaminathan eq->addr.virt) - 4912b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 4913b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 4914b3660a96SSukumar Swaminathan 4915b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset, 491682527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 491782527734SSukumar Swaminathan 4918a9800bebSGarrett D'Amore eqe.word = *ptr; 4919a9800bebSGarrett D'Amore eqe.word = BE_SWAP32(eqe.word); 492082527734SSukumar Swaminathan 4921a9800bebSGarrett D'Amore if (eqe.word & EQE_VALID) { 4922a9800bebSGarrett D'Amore rc = 1; 492382527734SSukumar Swaminathan } 492482527734SSukumar Swaminathan 492582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 492682527734SSukumar Swaminathan 492782527734SSukumar Swaminathan return (rc); 492882527734SSukumar Swaminathan 4929a9800bebSGarrett D'Amore } /* emlxs_sli4_read_eq */ 493082527734SSukumar Swaminathan 493182527734SSukumar Swaminathan 493282527734SSukumar Swaminathan static void 4933*8f23e9faSHans Rosenfeld emlxs_sli4_poll_intr(emlxs_hba_t *hba) 493482527734SSukumar Swaminathan { 493582527734SSukumar Swaminathan int rc = 0; 493682527734SSukumar Swaminathan int i; 493782527734SSukumar Swaminathan char arg[] = {0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7}; 493882527734SSukumar Swaminathan 4939*8f23e9faSHans Rosenfeld /* Check attention bits once and process if required */ 494082527734SSukumar Swaminathan 4941*8f23e9faSHans Rosenfeld for (i = 0; i < hba->intr_count; i++) { 4942*8f23e9faSHans Rosenfeld rc = emlxs_sli4_read_eq(hba, &hba->sli.sli4.eq[i]); 4943*8f23e9faSHans Rosenfeld if (rc == 1) { 4944*8f23e9faSHans Rosenfeld break; 494582527734SSukumar Swaminathan } 494682527734SSukumar Swaminathan } 494782527734SSukumar Swaminathan 4948*8f23e9faSHans Rosenfeld if (rc != 1) { 4949*8f23e9faSHans Rosenfeld return; 4950*8f23e9faSHans Rosenfeld } 4951*8f23e9faSHans Rosenfeld 4952*8f23e9faSHans Rosenfeld (void) emlxs_sli4_msi_intr((char *)hba, 4953*8f23e9faSHans Rosenfeld (char *)(unsigned long)arg[i]); 495482527734SSukumar Swaminathan 495582527734SSukumar Swaminathan return; 495682527734SSukumar Swaminathan 495782527734SSukumar Swaminathan } /* emlxs_sli4_poll_intr() */ 495882527734SSukumar Swaminathan 495982527734SSukumar Swaminathan 496082527734SSukumar Swaminathan /*ARGSUSED*/ 496182527734SSukumar Swaminathan static void 496282527734SSukumar Swaminathan emlxs_sli4_process_async_event(emlxs_hba_t *hba, CQE_ASYNC_t *cqe) 496382527734SSukumar Swaminathan { 496482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 4965*8f23e9faSHans Rosenfeld uint8_t status; 496682527734SSukumar Swaminathan 4967a9800bebSGarrett D'Amore /* Save the event tag */ 4968*8f23e9faSHans Rosenfeld if (hba->link_event_tag == cqe->un.link.event_tag) { 4969*8f23e9faSHans Rosenfeld HBASTATS.LinkMultiEvent++; 4970*8f23e9faSHans Rosenfeld } else if (hba->link_event_tag + 1 < cqe->un.link.event_tag) { 4971*8f23e9faSHans Rosenfeld HBASTATS.LinkMultiEvent++; 4972*8f23e9faSHans Rosenfeld } 4973a9800bebSGarrett D'Amore hba->link_event_tag = cqe->un.link.event_tag; 497482527734SSukumar Swaminathan 497582527734SSukumar Swaminathan switch (cqe->event_code) { 4976*8f23e9faSHans Rosenfeld case ASYNC_EVENT_CODE_FCOE_LINK_STATE: 4977*8f23e9faSHans Rosenfeld HBASTATS.LinkEvent++; 4978*8f23e9faSHans Rosenfeld 4979a9800bebSGarrett D'Amore switch (cqe->un.link.link_status) { 498082527734SSukumar Swaminathan case ASYNC_EVENT_PHYS_LINK_UP: 498182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4982*8f23e9faSHans Rosenfeld "Link Async Event: PHYS_LINK_UP. val=%d " 4983*8f23e9faSHans Rosenfeld "type=%x event=%x", 4984*8f23e9faSHans Rosenfeld cqe->valid, cqe->event_type, HBASTATS.LinkEvent); 498582527734SSukumar Swaminathan break; 498682527734SSukumar Swaminathan 4987*8f23e9faSHans Rosenfeld case ASYNC_EVENT_LOGICAL_LINK_UP: 4988a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4989*8f23e9faSHans Rosenfeld "Link Async Event: LOGICAL_LINK_UP. val=%d " 4990*8f23e9faSHans Rosenfeld "type=%x event=%x", 4991*8f23e9faSHans Rosenfeld cqe->valid, cqe->event_type, HBASTATS.LinkEvent); 4992a9800bebSGarrett D'Amore 4993*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fcoe_link_event(hba, cqe); 499482527734SSukumar Swaminathan break; 499582527734SSukumar Swaminathan 4996*8f23e9faSHans Rosenfeld case ASYNC_EVENT_PHYS_LINK_DOWN: 4997a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 4998*8f23e9faSHans Rosenfeld "Link Async Event: PHYS_LINK_DOWN. val=%d " 4999*8f23e9faSHans Rosenfeld "type=%x event=%x", 5000*8f23e9faSHans Rosenfeld cqe->valid, cqe->event_type, HBASTATS.LinkEvent); 500182527734SSukumar Swaminathan 5002*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fcoe_link_event(hba, cqe); 5003*8f23e9faSHans Rosenfeld break; 5004a9800bebSGarrett D'Amore 5005*8f23e9faSHans Rosenfeld case ASYNC_EVENT_LOGICAL_LINK_DOWN: 5006*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5007*8f23e9faSHans Rosenfeld "Link Async Event: LOGICAL_LINK_DOWN. val=%d " 5008*8f23e9faSHans Rosenfeld "type=%x event=%x", 5009*8f23e9faSHans Rosenfeld cqe->valid, cqe->event_type, HBASTATS.LinkEvent); 5010*8f23e9faSHans Rosenfeld 5011*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fcoe_link_event(hba, cqe); 5012*8f23e9faSHans Rosenfeld break; 5013*8f23e9faSHans Rosenfeld default: 5014*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5015*8f23e9faSHans Rosenfeld "Link Async Event: Unknown link status=%d event=%x", 5016*8f23e9faSHans Rosenfeld cqe->un.link.link_status, HBASTATS.LinkEvent); 501782527734SSukumar Swaminathan break; 501882527734SSukumar Swaminathan } 501982527734SSukumar Swaminathan break; 502082527734SSukumar Swaminathan case ASYNC_EVENT_CODE_FCOE_FIP: 5021a9800bebSGarrett D'Amore switch (cqe->un.fcoe.evt_type) { 502282527734SSukumar Swaminathan case ASYNC_EVENT_NEW_FCF_DISC: 502382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5024*8f23e9faSHans Rosenfeld "FIP Async Event: FCF_FOUND %d:%d", 5025a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 5026a9800bebSGarrett D'Amore 5027a9800bebSGarrett D'Amore (void) emlxs_fcf_found_notify(port, 5028a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 502982527734SSukumar Swaminathan break; 503082527734SSukumar Swaminathan case ASYNC_EVENT_FCF_TABLE_FULL: 5031a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5032*8f23e9faSHans Rosenfeld "FIP Async Event: FCFTAB_FULL %d:%d", 5033a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 5034a9800bebSGarrett D'Amore 5035a9800bebSGarrett D'Amore (void) emlxs_fcf_full_notify(port); 503682527734SSukumar Swaminathan break; 503782527734SSukumar Swaminathan case ASYNC_EVENT_FCF_DEAD: 503882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5039*8f23e9faSHans Rosenfeld "FIP Async Event: FCF_LOST %d:%d", 5040a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index, cqe->un.fcoe.fcf_count); 5041a9800bebSGarrett D'Amore 5042a9800bebSGarrett D'Amore (void) emlxs_fcf_lost_notify(port, 5043a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 504482527734SSukumar Swaminathan break; 504582527734SSukumar Swaminathan case ASYNC_EVENT_VIRT_LINK_CLEAR: 504682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5047*8f23e9faSHans Rosenfeld "FIP Async Event: CVL %d", 5048a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 5049a9800bebSGarrett D'Amore 5050a9800bebSGarrett D'Amore (void) emlxs_fcf_cvl_notify(port, 5051*8f23e9faSHans Rosenfeld emlxs_sli4_vpi_to_index(hba, 5052*8f23e9faSHans Rosenfeld cqe->un.fcoe.ref_index)); 5053a9800bebSGarrett D'Amore break; 5054a9800bebSGarrett D'Amore 5055a9800bebSGarrett D'Amore case ASYNC_EVENT_FCF_MODIFIED: 5056a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5057*8f23e9faSHans Rosenfeld "FIP Async Event: FCF_CHANGED %d", 5058a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 5059a9800bebSGarrett D'Amore 5060a9800bebSGarrett D'Amore (void) emlxs_fcf_changed_notify(port, 5061a9800bebSGarrett D'Amore cqe->un.fcoe.ref_index); 506282527734SSukumar Swaminathan break; 5063*8f23e9faSHans Rosenfeld default: 5064*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5065*8f23e9faSHans Rosenfeld "FIP Async Event: Unknown event type=%d", 5066*8f23e9faSHans Rosenfeld cqe->un.fcoe.evt_type); 5067*8f23e9faSHans Rosenfeld break; 506882527734SSukumar Swaminathan } 506982527734SSukumar Swaminathan break; 507082527734SSukumar Swaminathan case ASYNC_EVENT_CODE_DCBX: 507182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5072*8f23e9faSHans Rosenfeld "DCBX Async Event: type=%d. Not supported.", 5073*8f23e9faSHans Rosenfeld cqe->event_type); 507482527734SSukumar Swaminathan break; 5075a9800bebSGarrett D'Amore case ASYNC_EVENT_CODE_GRP_5: 5076a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5077*8f23e9faSHans Rosenfeld "Group 5 Async Event: type=%d.", cqe->event_type); 5078a9800bebSGarrett D'Amore if (cqe->event_type == ASYNC_EVENT_QOS_SPEED) { 5079a9800bebSGarrett D'Amore hba->qos_linkspeed = cqe->un.qos.qos_link_speed; 5080a9800bebSGarrett D'Amore } 5081a9800bebSGarrett D'Amore break; 5082*8f23e9faSHans Rosenfeld case ASYNC_EVENT_CODE_FC_EVENT: 5083*8f23e9faSHans Rosenfeld switch (cqe->event_type) { 5084*8f23e9faSHans Rosenfeld case ASYNC_EVENT_FC_LINK_ATT: 5085*8f23e9faSHans Rosenfeld HBASTATS.LinkEvent++; 5086*8f23e9faSHans Rosenfeld 5087*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5088*8f23e9faSHans Rosenfeld "FC Async Event: Link Attention. event=%x", 5089*8f23e9faSHans Rosenfeld HBASTATS.LinkEvent); 5090*8f23e9faSHans Rosenfeld 5091*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fc_link_att(hba, cqe); 5092*8f23e9faSHans Rosenfeld break; 5093*8f23e9faSHans Rosenfeld case ASYNC_EVENT_FC_SHARED_LINK_ATT: 5094*8f23e9faSHans Rosenfeld HBASTATS.LinkEvent++; 5095*8f23e9faSHans Rosenfeld 5096*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5097*8f23e9faSHans Rosenfeld "FC Async Event: Shared Link Attention. event=%x", 5098*8f23e9faSHans Rosenfeld HBASTATS.LinkEvent); 5099*8f23e9faSHans Rosenfeld 5100*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fc_link_att(hba, cqe); 5101*8f23e9faSHans Rosenfeld break; 5102*8f23e9faSHans Rosenfeld default: 5103*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5104*8f23e9faSHans Rosenfeld "FC Async Event: Unknown event. type=%d event=%x", 5105*8f23e9faSHans Rosenfeld cqe->event_type, HBASTATS.LinkEvent); 5106*8f23e9faSHans Rosenfeld } 5107*8f23e9faSHans Rosenfeld break; 5108*8f23e9faSHans Rosenfeld case ASYNC_EVENT_CODE_PORT: 5109*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5110*8f23e9faSHans Rosenfeld "SLI Port Async Event: type=%d", cqe->event_type); 5111*8f23e9faSHans Rosenfeld if (cqe->event_type == ASYNC_EVENT_MISCONFIG_PORT) { 5112*8f23e9faSHans Rosenfeld *((uint32_t *)cqe->un.port.link_status) = 5113*8f23e9faSHans Rosenfeld BE_SWAP32(*((uint32_t *)cqe->un.port.link_status)); 5114*8f23e9faSHans Rosenfeld status = 5115*8f23e9faSHans Rosenfeld cqe->un.port.link_status[hba->sli.sli4.link_number]; 5116*8f23e9faSHans Rosenfeld 5117*8f23e9faSHans Rosenfeld switch (status) { 5118*8f23e9faSHans Rosenfeld case 0 : 5119*8f23e9faSHans Rosenfeld break; 5120*8f23e9faSHans Rosenfeld 5121*8f23e9faSHans Rosenfeld case 1 : 5122*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5123*8f23e9faSHans Rosenfeld "SLI Port Async Event: Physical media not " 5124*8f23e9faSHans Rosenfeld "detected"); 5125*8f23e9faSHans Rosenfeld cmn_err(CE_WARN, 5126*8f23e9faSHans Rosenfeld "^%s%d: Optics faulted/incorrectly " 5127*8f23e9faSHans Rosenfeld "installed/not installed - Reseat optics, " 5128*8f23e9faSHans Rosenfeld "if issue not resolved, replace.", 5129*8f23e9faSHans Rosenfeld DRIVER_NAME, hba->ddiinst); 5130*8f23e9faSHans Rosenfeld break; 5131*8f23e9faSHans Rosenfeld 5132*8f23e9faSHans Rosenfeld case 2 : 5133*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5134*8f23e9faSHans Rosenfeld "SLI Port Async Event: Wrong physical " 5135*8f23e9faSHans Rosenfeld "media detected"); 5136*8f23e9faSHans Rosenfeld cmn_err(CE_WARN, 5137*8f23e9faSHans Rosenfeld "^%s%d: Optics of two types installed - " 5138*8f23e9faSHans Rosenfeld "Remove one optic or install matching" 5139*8f23e9faSHans Rosenfeld "pair of optics.", 5140*8f23e9faSHans Rosenfeld DRIVER_NAME, hba->ddiinst); 5141*8f23e9faSHans Rosenfeld break; 5142*8f23e9faSHans Rosenfeld 5143*8f23e9faSHans Rosenfeld case 3 : 5144*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5145*8f23e9faSHans Rosenfeld "SLI Port Async Event: Unsupported " 5146*8f23e9faSHans Rosenfeld "physical media detected"); 5147*8f23e9faSHans Rosenfeld cmn_err(CE_WARN, 5148*8f23e9faSHans Rosenfeld "^%s%d: Incompatible optics - Replace " 5149*8f23e9faSHans Rosenfeld "with compatible optics for card to " 5150*8f23e9faSHans Rosenfeld "function.", 5151*8f23e9faSHans Rosenfeld DRIVER_NAME, hba->ddiinst); 5152*8f23e9faSHans Rosenfeld break; 5153*8f23e9faSHans Rosenfeld 5154*8f23e9faSHans Rosenfeld default : 5155*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5156*8f23e9faSHans Rosenfeld "SLI Port Async Event: Physical media " 5157*8f23e9faSHans Rosenfeld "error, status=%x", status); 5158*8f23e9faSHans Rosenfeld cmn_err(CE_WARN, 5159*8f23e9faSHans Rosenfeld "^%s%d: Misconfigured port: status=0x%x - " 5160*8f23e9faSHans Rosenfeld "Check optics on card.", 5161*8f23e9faSHans Rosenfeld DRIVER_NAME, hba->ddiinst, status); 5162*8f23e9faSHans Rosenfeld break; 5163*8f23e9faSHans Rosenfeld } 5164*8f23e9faSHans Rosenfeld } 5165*8f23e9faSHans Rosenfeld break; 5166*8f23e9faSHans Rosenfeld case ASYNC_EVENT_CODE_VF: 5167*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5168*8f23e9faSHans Rosenfeld "VF Async Event: type=%d", 5169*8f23e9faSHans Rosenfeld cqe->event_type); 5170*8f23e9faSHans Rosenfeld break; 5171*8f23e9faSHans Rosenfeld case ASYNC_EVENT_CODE_MR: 5172*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5173*8f23e9faSHans Rosenfeld "MR Async Event: type=%d", 5174*8f23e9faSHans Rosenfeld cqe->event_type); 5175*8f23e9faSHans Rosenfeld break; 517682527734SSukumar Swaminathan default: 517782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5178*8f23e9faSHans Rosenfeld "Unknown Async Event: code=%d type=%d.", 5179*8f23e9faSHans Rosenfeld cqe->event_code, cqe->event_type); 518082527734SSukumar Swaminathan break; 518182527734SSukumar Swaminathan } 518282527734SSukumar Swaminathan 518382527734SSukumar Swaminathan } /* emlxs_sli4_process_async_event() */ 518482527734SSukumar Swaminathan 518582527734SSukumar Swaminathan 518682527734SSukumar Swaminathan /*ARGSUSED*/ 518782527734SSukumar Swaminathan static void 518882527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(emlxs_hba_t *hba, CQE_MBOX_t *cqe) 518982527734SSukumar Swaminathan { 519082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 519182527734SSukumar Swaminathan MAILBOX4 *mb; 519282527734SSukumar Swaminathan MATCHMAP *mbox_bp; 519382527734SSukumar Swaminathan MATCHMAP *mbox_nonembed; 5194a9800bebSGarrett D'Amore MAILBOXQ *mbq = NULL; 519582527734SSukumar Swaminathan uint32_t size; 519682527734SSukumar Swaminathan uint32_t *iptr; 519782527734SSukumar Swaminathan int rc; 5198b3660a96SSukumar Swaminathan off_t offset; 519982527734SSukumar Swaminathan 520082527734SSukumar Swaminathan if (cqe->consumed && !cqe->completed) { 520182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5202a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Entry consumed but not completed"); 520382527734SSukumar Swaminathan return; 520482527734SSukumar Swaminathan } 520582527734SSukumar Swaminathan 5206a9800bebSGarrett D'Amore mutex_enter(&EMLXS_PORT_LOCK); 520782527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 520882527734SSukumar Swaminathan case 0: 520982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg, 5210a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. No mailbox active."); 5211a9800bebSGarrett D'Amore 5212a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 521382527734SSukumar Swaminathan return; 521482527734SSukumar Swaminathan 521582527734SSukumar Swaminathan case MBX_POLL: 521682527734SSukumar Swaminathan 521782527734SSukumar Swaminathan /* Mark mailbox complete, this should wake up any polling */ 521882527734SSukumar Swaminathan /* threads. This can happen if interrupts are enabled while */ 521982527734SSukumar Swaminathan /* a polled mailbox command is outstanding. If we don't set */ 522082527734SSukumar Swaminathan /* MBQ_COMPLETED here, the polling thread may wait until */ 522182527734SSukumar Swaminathan /* timeout error occurs */ 522282527734SSukumar Swaminathan 522382527734SSukumar Swaminathan mutex_enter(&EMLXS_MBOX_LOCK); 522482527734SSukumar Swaminathan mbq = (MAILBOXQ *)hba->mbox_mbq; 522582527734SSukumar Swaminathan if (mbq) { 5226a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 522782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 5228a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Completing Polled command."); 522982527734SSukumar Swaminathan mbq->flag |= MBQ_COMPLETED; 523082527734SSukumar Swaminathan } 523182527734SSukumar Swaminathan mutex_exit(&EMLXS_MBOX_LOCK); 523282527734SSukumar Swaminathan 5233a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 523482527734SSukumar Swaminathan return; 523582527734SSukumar Swaminathan 523682527734SSukumar Swaminathan case MBX_SLEEP: 523782527734SSukumar Swaminathan case MBX_NOWAIT: 5238a9800bebSGarrett D'Amore /* Check mbox_timer, it acts as a service flag too */ 5239a9800bebSGarrett D'Amore /* The first to service the mbox queue will clear the timer */ 5240a9800bebSGarrett D'Amore if (hba->mbox_timer) { 5241a9800bebSGarrett D'Amore hba->mbox_timer = 0; 5242a9800bebSGarrett D'Amore 5243a9800bebSGarrett D'Amore mutex_enter(&EMLXS_MBOX_LOCK); 5244a9800bebSGarrett D'Amore mbq = (MAILBOXQ *)hba->mbox_mbq; 5245a9800bebSGarrett D'Amore mutex_exit(&EMLXS_MBOX_LOCK); 5246a9800bebSGarrett D'Amore } 5247a9800bebSGarrett D'Amore 5248a9800bebSGarrett D'Amore if (!mbq) { 5249a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 5250a9800bebSGarrett D'Amore "Mailbox event. No service required."); 5251a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 5252a9800bebSGarrett D'Amore return; 5253a9800bebSGarrett D'Amore } 5254a9800bebSGarrett D'Amore 525582527734SSukumar Swaminathan mb = (MAILBOX4 *)mbq; 5256a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 525782527734SSukumar Swaminathan break; 525882527734SSukumar Swaminathan 525982527734SSukumar Swaminathan default: 526082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg, 5261a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Invalid Mailbox flag (%x).", 5262a9800bebSGarrett D'Amore hba->mbox_queue_flag); 5263a9800bebSGarrett D'Amore 5264a9800bebSGarrett D'Amore mutex_exit(&EMLXS_PORT_LOCK); 526582527734SSukumar Swaminathan return; 526682527734SSukumar Swaminathan } 526782527734SSukumar Swaminathan 5268a9800bebSGarrett D'Amore /* Set port context */ 5269a9800bebSGarrett D'Amore port = (emlxs_port_t *)mbq->port; 5270a9800bebSGarrett D'Amore 5271b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 5272b3660a96SSukumar Swaminathan hba->sli.sli4.mq.addr.virt) - 5273b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 5274b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 5275b3660a96SSukumar Swaminathan 527682527734SSukumar Swaminathan /* Now that we are the owner, DMA Sync entire MQ if needed */ 5277b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.mq.addr.dma_handle, offset, 527882527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORDEV); 527982527734SSukumar Swaminathan 528082527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)hba->mbox_mqe, (uint8_t *)mb, 528182527734SSukumar Swaminathan MAILBOX_CMD_SLI4_BSIZE); 528282527734SSukumar Swaminathan 5283a9800bebSGarrett D'Amore if (mb->mbxCommand != MBX_HEARTBEAT) { 5284a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5285a9800bebSGarrett D'Amore "CQ ENTRY: Mbox event. Mbox complete. status=%x cmd=%x", 5286a9800bebSGarrett D'Amore mb->mbxStatus, mb->mbxCommand); 5287a9800bebSGarrett D'Amore 5288a9800bebSGarrett D'Amore emlxs_data_dump(port, "MBOX CMP", (uint32_t *)hba->mbox_mqe, 5289a9800bebSGarrett D'Amore 12, 0); 5290a9800bebSGarrett D'Amore } 529182527734SSukumar Swaminathan 529282527734SSukumar Swaminathan if (mb->mbxCommand == MBX_SLI_CONFIG) { 529382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 529482527734SSukumar Swaminathan "Mbox sge_cnt: %d length: %d embed: %d", 529582527734SSukumar Swaminathan mb->un.varSLIConfig.be.sge_cnt, 529682527734SSukumar Swaminathan mb->un.varSLIConfig.be.payload_length, 529782527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded); 529882527734SSukumar Swaminathan } 529982527734SSukumar Swaminathan 530082527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 530182527734SSukumar Swaminathan if (mbq->bp) { 530282527734SSukumar Swaminathan mbox_bp = (MATCHMAP *)mbq->bp; 530382527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0, mbox_bp->size, 530482527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 5305b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 5306b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, mbox_bp->dma_handle) 5307b3660a96SSukumar Swaminathan != DDI_FM_OK) { 5308b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5309b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 5310*8f23e9faSHans Rosenfeld "sli4_process_mbox_event: hdl=%p", 5311b3660a96SSukumar Swaminathan mbox_bp->dma_handle); 5312b3660a96SSukumar Swaminathan 5313b3660a96SSukumar Swaminathan mb->mbxStatus = MBXERR_DMA_ERROR; 5314b3660a96SSukumar Swaminathan } 5315b3660a96SSukumar Swaminathan #endif 531682527734SSukumar Swaminathan } 531782527734SSukumar Swaminathan 531882527734SSukumar Swaminathan /* Now sync the memory buffer if one was used */ 531982527734SSukumar Swaminathan if (mbq->nonembed) { 532082527734SSukumar Swaminathan mbox_nonembed = (MATCHMAP *)mbq->nonembed; 532182527734SSukumar Swaminathan size = mbox_nonembed->size; 532282527734SSukumar Swaminathan EMLXS_MPDATA_SYNC(mbox_nonembed->dma_handle, 0, size, 532382527734SSukumar Swaminathan DDI_DMA_SYNC_FORKERNEL); 532482527734SSukumar Swaminathan iptr = (uint32_t *)((uint8_t *)mbox_nonembed->virt); 532582527734SSukumar Swaminathan BE_SWAP32_BCOPY((uint8_t *)iptr, (uint8_t *)iptr, size); 532682527734SSukumar Swaminathan 5327b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 5328b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 5329b3660a96SSukumar Swaminathan mbox_nonembed->dma_handle) != DDI_FM_OK) { 5330b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 5331b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 5332*8f23e9faSHans Rosenfeld "sli4_process_mbox_event: hdl=%p", 5333b3660a96SSukumar Swaminathan mbox_nonembed->dma_handle); 5334b3660a96SSukumar Swaminathan 5335b3660a96SSukumar Swaminathan mb->mbxStatus = MBXERR_DMA_ERROR; 5336b3660a96SSukumar Swaminathan } 5337b3660a96SSukumar Swaminathan #endif 5338*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "EXT AREA", (uint32_t *)iptr, 24, 0); 533982527734SSukumar Swaminathan } 534082527734SSukumar Swaminathan 534182527734SSukumar Swaminathan /* Mailbox has been completely received at this point */ 534282527734SSukumar Swaminathan 534382527734SSukumar Swaminathan if (mb->mbxCommand == MBX_HEARTBEAT) { 534482527734SSukumar Swaminathan hba->heartbeat_active = 0; 534582527734SSukumar Swaminathan goto done; 534682527734SSukumar Swaminathan } 534782527734SSukumar Swaminathan 534882527734SSukumar Swaminathan if (hba->mbox_queue_flag == MBX_SLEEP) { 534982527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 535082527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 535182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 535282527734SSukumar Swaminathan "Received. %s: status=%x Sleep.", 535382527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 535482527734SSukumar Swaminathan mb->mbxStatus); 535582527734SSukumar Swaminathan } 535682527734SSukumar Swaminathan } else { 535782527734SSukumar Swaminathan if (mb->mbxCommand != MBX_DOWN_LOAD 535882527734SSukumar Swaminathan /* && mb->mbxCommand != MBX_DUMP_MEMORY */) { 535982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 536082527734SSukumar Swaminathan "Completed. %s: status=%x", 536182527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 536282527734SSukumar Swaminathan mb->mbxStatus); 536382527734SSukumar Swaminathan } 536482527734SSukumar Swaminathan } 536582527734SSukumar Swaminathan 536682527734SSukumar Swaminathan /* Filter out passthru mailbox */ 536782527734SSukumar Swaminathan if (mbq->flag & MBQ_PASSTHRU) { 536882527734SSukumar Swaminathan goto done; 536982527734SSukumar Swaminathan } 537082527734SSukumar Swaminathan 537182527734SSukumar Swaminathan if (mb->mbxStatus) { 537282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg, 537382527734SSukumar Swaminathan "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand), 537482527734SSukumar Swaminathan (uint32_t)mb->mbxStatus); 537582527734SSukumar Swaminathan } 537682527734SSukumar Swaminathan 537782527734SSukumar Swaminathan if (mbq->mbox_cmpl) { 537882527734SSukumar Swaminathan rc = (mbq->mbox_cmpl)(hba, mbq); 537982527734SSukumar Swaminathan 538082527734SSukumar Swaminathan /* If mbox was retried, return immediately */ 538182527734SSukumar Swaminathan if (rc) { 538282527734SSukumar Swaminathan return; 538382527734SSukumar Swaminathan } 538482527734SSukumar Swaminathan } 538582527734SSukumar Swaminathan 538682527734SSukumar Swaminathan done: 538782527734SSukumar Swaminathan 538882527734SSukumar Swaminathan /* Clean up the mailbox area */ 538982527734SSukumar Swaminathan emlxs_mb_fini(hba, (MAILBOX *)mb, mb->mbxStatus); 539082527734SSukumar Swaminathan 539182527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 539282527734SSukumar Swaminathan mbq = (MAILBOXQ *)emlxs_mb_get(hba); 539382527734SSukumar Swaminathan if (mbq) { 539482527734SSukumar Swaminathan /* Attempt to send pending mailboxes */ 539582527734SSukumar Swaminathan rc = emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0); 539682527734SSukumar Swaminathan if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) { 5397a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_MBOX, (void *)mbq); 539882527734SSukumar Swaminathan } 539982527734SSukumar Swaminathan } 540082527734SSukumar Swaminathan return; 540182527734SSukumar Swaminathan 540282527734SSukumar Swaminathan } /* emlxs_sli4_process_mbox_event() */ 540382527734SSukumar Swaminathan 540482527734SSukumar Swaminathan 5405bce54adfSSukumar Swaminathan /*ARGSUSED*/ 540682527734SSukumar Swaminathan static void 540782527734SSukumar Swaminathan emlxs_CQE_to_IOCB(emlxs_hba_t *hba, CQE_CmplWQ_t *cqe, emlxs_buf_t *sbp) 540882527734SSukumar Swaminathan { 5409*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 541082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 5411*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 541282527734SSukumar Swaminathan IOCBQ *iocbq; 541382527734SSukumar Swaminathan IOCB *iocb; 5414a9800bebSGarrett D'Amore uint32_t *iptr; 5415a9800bebSGarrett D'Amore fc_packet_t *pkt; 541682527734SSukumar Swaminathan emlxs_wqe_t *wqe; 541782527734SSukumar Swaminathan 541882527734SSukumar Swaminathan iocbq = &sbp->iocbq; 541982527734SSukumar Swaminathan wqe = &iocbq->wqe; 542082527734SSukumar Swaminathan iocb = &iocbq->iocb; 542182527734SSukumar Swaminathan 5422*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 542382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5424*8f23e9faSHans Rosenfeld "CQE to IOCB: cmd:%x tag:%x xri:%d", wqe->Command, 542582527734SSukumar Swaminathan wqe->RequestTag, wqe->XRITag); 5426*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 542782527734SSukumar Swaminathan 542882527734SSukumar Swaminathan iocb->ULPSTATUS = cqe->Status; 542982527734SSukumar Swaminathan iocb->un.ulpWord[4] = cqe->Parameter; 543082527734SSukumar Swaminathan iocb->ULPIOTAG = cqe->RequestTag; 543182527734SSukumar Swaminathan iocb->ULPCONTEXT = wqe->XRITag; 543282527734SSukumar Swaminathan 543382527734SSukumar Swaminathan switch (wqe->Command) { 543482527734SSukumar Swaminathan 543582527734SSukumar Swaminathan case CMD_FCP_ICMND64_CR: 543682527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_ICMND64_CX; 543782527734SSukumar Swaminathan break; 543882527734SSukumar Swaminathan 543982527734SSukumar Swaminathan case CMD_FCP_IREAD64_CR: 544082527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IREAD64_CX; 5441*8f23e9faSHans Rosenfeld iocb->ULPPU = PARM_XFER_CHECK; 544282527734SSukumar Swaminathan if (iocb->ULPSTATUS == IOSTAT_FCP_RSP_ERROR) { 544382527734SSukumar Swaminathan iocb->un.fcpi64.fcpi_parm = 544482527734SSukumar Swaminathan wqe->un.FcpCmd.TotalTransferCount - 544582527734SSukumar Swaminathan cqe->CmdSpecific; 544682527734SSukumar Swaminathan } 544782527734SSukumar Swaminathan break; 544882527734SSukumar Swaminathan 544982527734SSukumar Swaminathan case CMD_FCP_IWRITE64_CR: 545082527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_FCP_IWRITE64_CX; 5451*8f23e9faSHans Rosenfeld if (iocb->ULPSTATUS == IOSTAT_FCP_RSP_ERROR) { 5452*8f23e9faSHans Rosenfeld if (wqe->un.FcpCmd.TotalTransferCount > 5453*8f23e9faSHans Rosenfeld cqe->CmdSpecific) { 5454*8f23e9faSHans Rosenfeld iocb->un.fcpi64.fcpi_parm = 5455*8f23e9faSHans Rosenfeld wqe->un.FcpCmd.TotalTransferCount - 5456*8f23e9faSHans Rosenfeld cqe->CmdSpecific; 5457*8f23e9faSHans Rosenfeld } else { 5458*8f23e9faSHans Rosenfeld iocb->un.fcpi64.fcpi_parm = 0; 5459*8f23e9faSHans Rosenfeld } 5460*8f23e9faSHans Rosenfeld } 546182527734SSukumar Swaminathan break; 546282527734SSukumar Swaminathan 546382527734SSukumar Swaminathan case CMD_ELS_REQUEST64_CR: 546482527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_ELS_REQUEST64_CX; 546582527734SSukumar Swaminathan iocb->un.elsreq64.bdl.bdeSize = cqe->CmdSpecific; 546682527734SSukumar Swaminathan if (iocb->ULPSTATUS == 0) { 546782527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 546882527734SSukumar Swaminathan } 5469a9800bebSGarrett D'Amore if (iocb->ULPSTATUS == IOSTAT_LS_RJT) { 5470a9800bebSGarrett D'Amore /* For LS_RJT, the driver populates the rsp buffer */ 5471a9800bebSGarrett D'Amore pkt = PRIV2PKT(sbp); 5472a9800bebSGarrett D'Amore iptr = (uint32_t *)pkt->pkt_resp; 5473a9800bebSGarrett D'Amore *iptr++ = ELS_CMD_LS_RJT; 5474a9800bebSGarrett D'Amore *iptr = cqe->Parameter; 5475a9800bebSGarrett D'Amore } 547682527734SSukumar Swaminathan break; 547782527734SSukumar Swaminathan 547882527734SSukumar Swaminathan case CMD_GEN_REQUEST64_CR: 547982527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_GEN_REQUEST64_CX; 548082527734SSukumar Swaminathan iocb->unsli3.ext_iocb.rsplen = cqe->CmdSpecific; 548182527734SSukumar Swaminathan break; 548282527734SSukumar Swaminathan 548382527734SSukumar Swaminathan case CMD_XMIT_SEQUENCE64_CR: 548482527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CX; 548582527734SSukumar Swaminathan break; 548682527734SSukumar Swaminathan 5487*8f23e9faSHans Rosenfeld case CMD_ABORT_XRI_CX: 5488*8f23e9faSHans Rosenfeld iocb->ULPCONTEXT = wqe->AbortTag; 5489*8f23e9faSHans Rosenfeld break; 5490*8f23e9faSHans Rosenfeld 5491*8f23e9faSHans Rosenfeld case CMD_FCP_TRECEIVE64_CX: 5492*8f23e9faSHans Rosenfeld /* free memory for XRDY */ 5493*8f23e9faSHans Rosenfeld if (iocbq->bp) { 5494*8f23e9faSHans Rosenfeld emlxs_mem_buf_free(hba, iocbq->bp); 5495*8f23e9faSHans Rosenfeld iocbq->bp = 0; 5496*8f23e9faSHans Rosenfeld } 5497*8f23e9faSHans Rosenfeld 5498*8f23e9faSHans Rosenfeld /*FALLTHROUGH*/ 5499*8f23e9faSHans Rosenfeld 5500*8f23e9faSHans Rosenfeld case CMD_FCP_TSEND64_CX: 5501*8f23e9faSHans Rosenfeld case CMD_FCP_TRSP64_CX: 550282527734SSukumar Swaminathan default: 550382527734SSukumar Swaminathan iocb->ULPCOMMAND = wqe->Command; 550482527734SSukumar Swaminathan 550582527734SSukumar Swaminathan } 550682527734SSukumar Swaminathan } /* emlxs_CQE_to_IOCB() */ 550782527734SSukumar Swaminathan 550882527734SSukumar Swaminathan 550982527734SSukumar Swaminathan /*ARGSUSED*/ 551082527734SSukumar Swaminathan static void 551182527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(emlxs_hba_t *hba) 551282527734SSukumar Swaminathan { 5513bce54adfSSukumar Swaminathan emlxs_port_t *port = &PPORT; 551482527734SSukumar Swaminathan CHANNEL *cp; 551582527734SSukumar Swaminathan emlxs_buf_t *sbp; 551682527734SSukumar Swaminathan IOCBQ *iocbq; 5517a9800bebSGarrett D'Amore uint16_t i; 5518*8f23e9faSHans Rosenfeld uint32_t trigger = 0; 551982527734SSukumar Swaminathan CQE_CmplWQ_t cqe; 552082527734SSukumar Swaminathan 552182527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 552282527734SSukumar Swaminathan for (i = 0; i < hba->max_iotag; i++) { 552382527734SSukumar Swaminathan sbp = hba->fc_table[i]; 552482527734SSukumar Swaminathan if (sbp == NULL || sbp == STALE_PACKET) { 552582527734SSukumar Swaminathan continue; 552682527734SSukumar Swaminathan } 5527a9800bebSGarrett D'Amore hba->fc_table[i] = STALE_PACKET; 552882527734SSukumar Swaminathan hba->io_count--; 5529a9800bebSGarrett D'Amore sbp->iotag = 0; 553082527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 553182527734SSukumar Swaminathan 553282527734SSukumar Swaminathan cp = sbp->channel; 553382527734SSukumar Swaminathan bzero(&cqe, sizeof (CQE_CmplWQ_t)); 553482527734SSukumar Swaminathan cqe.RequestTag = i; 553582527734SSukumar Swaminathan cqe.Status = IOSTAT_LOCAL_REJECT; 553682527734SSukumar Swaminathan cqe.Parameter = IOERR_SEQUENCE_TIMEOUT; 553782527734SSukumar Swaminathan 553882527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 553982527734SSukumar Swaminathan 554082527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 554182527734SSukumar Swaminathan #ifdef FCT_IO_TRACE 554282527734SSukumar Swaminathan if (sbp->fct_cmd) { 554382527734SSukumar Swaminathan emlxs_fct_io_trace(port, sbp->fct_cmd, 554482527734SSukumar Swaminathan EMLXS_FCT_IOCB_COMPLETE); 554582527734SSukumar Swaminathan } 554682527734SSukumar Swaminathan #endif /* FCT_IO_TRACE */ 554782527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 554882527734SSukumar Swaminathan 5549*8f23e9faSHans Rosenfeld if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 5550*8f23e9faSHans Rosenfeld atomic_dec_32(&hba->io_active); 5551*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT 5552*8f23e9faSHans Rosenfeld if (sbp->node) { 5553*8f23e9faSHans Rosenfeld atomic_dec_32(&sbp->node->io_active); 5554*8f23e9faSHans Rosenfeld } 5555*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */ 5556*8f23e9faSHans Rosenfeld } 555782527734SSukumar Swaminathan 555882527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 555982527734SSukumar Swaminathan iocbq = &sbp->iocbq; 556082527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, &cqe, sbp); 556182527734SSukumar Swaminathan 556282527734SSukumar Swaminathan iocbq->next = NULL; 556382527734SSukumar Swaminathan 556482527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 5565*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, sbp->xrip, 1); 556682527734SSukumar Swaminathan 556782527734SSukumar Swaminathan if (!(sbp->pkt_flags & 556882527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 556982527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 557082527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 557182527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 557282527734SSukumar Swaminathan cp->rsp_head = iocbq; 557382527734SSukumar Swaminathan cp->rsp_tail = iocbq; 557482527734SSukumar Swaminathan } else { 557582527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 557682527734SSukumar Swaminathan cp->rsp_tail = iocbq; 557782527734SSukumar Swaminathan } 557882527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 557982527734SSukumar Swaminathan trigger = 1; 558082527734SSukumar Swaminathan } else { 558182527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 558282527734SSukumar Swaminathan } 558382527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 558482527734SSukumar Swaminathan } 558582527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 558682527734SSukumar Swaminathan 558782527734SSukumar Swaminathan if (trigger) { 558882527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 558982527734SSukumar Swaminathan cp = &hba->chan[i]; 559082527734SSukumar Swaminathan if (cp->rsp_head != NULL) { 559182527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 559282527734SSukumar Swaminathan emlxs_proc_channel, cp); 559382527734SSukumar Swaminathan } 559482527734SSukumar Swaminathan } 559582527734SSukumar Swaminathan } 559682527734SSukumar Swaminathan 559782527734SSukumar Swaminathan } /* emlxs_sli4_hba_flush_chipq() */ 559882527734SSukumar Swaminathan 559982527734SSukumar Swaminathan 560082527734SSukumar Swaminathan /*ARGSUSED*/ 560182527734SSukumar Swaminathan static void 560282527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(emlxs_hba_t *hba, 560382527734SSukumar Swaminathan CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 560482527734SSukumar Swaminathan { 560582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 560682527734SSukumar Swaminathan CHANNEL *cp; 560782527734SSukumar Swaminathan uint16_t request_tag; 560882527734SSukumar Swaminathan 560982527734SSukumar Swaminathan request_tag = cqe->RequestTag; 561082527734SSukumar Swaminathan 561182527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 561282527734SSukumar Swaminathan cp = cq->channelp; 561382527734SSukumar Swaminathan 561482527734SSukumar Swaminathan cp->hbaCmplCmd++; 561582527734SSukumar Swaminathan 561682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5617*8f23e9faSHans Rosenfeld "CQ ENTRY: OOR Cmpl: iotag=%d", request_tag); 561882527734SSukumar Swaminathan 5619*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "CQE", (uint32_t *)cqe, 4, 0); 5620a9800bebSGarrett D'Amore 562182527734SSukumar Swaminathan } /* emlxs_sli4_process_oor_wqe_cmpl() */ 562282527734SSukumar Swaminathan 562382527734SSukumar Swaminathan 562482527734SSukumar Swaminathan /*ARGSUSED*/ 562582527734SSukumar Swaminathan static void 562682527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(emlxs_hba_t *hba, CQ_DESC_t *cq, CQE_CmplWQ_t *cqe) 562782527734SSukumar Swaminathan { 562882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 562982527734SSukumar Swaminathan CHANNEL *cp; 563082527734SSukumar Swaminathan emlxs_buf_t *sbp; 563182527734SSukumar Swaminathan IOCBQ *iocbq; 563282527734SSukumar Swaminathan uint16_t request_tag; 563382527734SSukumar Swaminathan #ifdef SFCT_SUPPORT 5634*8f23e9faSHans Rosenfeld #ifdef FCT_IO_TRACE 563582527734SSukumar Swaminathan fct_cmd_t *fct_cmd; 563682527734SSukumar Swaminathan emlxs_buf_t *cmd_sbp; 5637*8f23e9faSHans Rosenfeld #endif /* FCT_IO_TRACE */ 563882527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */ 563982527734SSukumar Swaminathan 564082527734SSukumar Swaminathan request_tag = cqe->RequestTag; 564182527734SSukumar Swaminathan 564282527734SSukumar Swaminathan /* 1 to 1 mapping between CQ and channel */ 564382527734SSukumar Swaminathan cp = cq->channelp; 564482527734SSukumar Swaminathan 5645a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 564682527734SSukumar Swaminathan sbp = hba->fc_table[request_tag]; 5647*8f23e9faSHans Rosenfeld 5648*8f23e9faSHans Rosenfeld if (!sbp) { 5649*8f23e9faSHans Rosenfeld cp->hbaCmplCmd++; 5650*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_FCTAB_LOCK); 5651*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5652*8f23e9faSHans Rosenfeld "CQ ENTRY: NULL sbp. iotag=%d. Dropping...", 5653*8f23e9faSHans Rosenfeld request_tag); 5654*8f23e9faSHans Rosenfeld return; 5655*8f23e9faSHans Rosenfeld } 565682527734SSukumar Swaminathan 565782527734SSukumar Swaminathan if (sbp == STALE_PACKET) { 565882527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 5659a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 566082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5661*8f23e9faSHans Rosenfeld "CQ ENTRY: Stale sbp. iotag=%d. Dropping...", request_tag); 566282527734SSukumar Swaminathan return; 566382527734SSukumar Swaminathan } 566482527734SSukumar Swaminathan 5665*8f23e9faSHans Rosenfeld if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 5666*8f23e9faSHans Rosenfeld atomic_add_32(&hba->io_active, -1); 5667*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT 5668*8f23e9faSHans Rosenfeld if (sbp->node) { 5669*8f23e9faSHans Rosenfeld atomic_add_32(&sbp->node->io_active, -1); 5670*8f23e9faSHans Rosenfeld } 5671*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */ 5672*8f23e9faSHans Rosenfeld } 5673*8f23e9faSHans Rosenfeld 5674*8f23e9faSHans Rosenfeld if (!(sbp->xrip)) { 567582527734SSukumar Swaminathan cp->hbaCmplCmd++; 5676a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 567782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5678*8f23e9faSHans Rosenfeld "CQ ENTRY: NULL sbp xrip %p. iotag=%d. Dropping...", 567982527734SSukumar Swaminathan sbp, request_tag); 568082527734SSukumar Swaminathan return; 568182527734SSukumar Swaminathan } 568282527734SSukumar Swaminathan 5683*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 568482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 568582527734SSukumar Swaminathan "CQ ENTRY: process wqe compl"); 5686*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 568782527734SSukumar Swaminathan cp->hbaCmplCmd_sbp++; 568882527734SSukumar Swaminathan 568982527734SSukumar Swaminathan /* Copy entry to sbp's iocbq */ 569082527734SSukumar Swaminathan iocbq = &sbp->iocbq; 569182527734SSukumar Swaminathan emlxs_CQE_to_IOCB(hba, cqe, sbp); 569282527734SSukumar Swaminathan 569382527734SSukumar Swaminathan iocbq->next = NULL; 569482527734SSukumar Swaminathan 569582527734SSukumar Swaminathan if (cqe->XB) { 569682527734SSukumar Swaminathan /* Mark exchange as ABORT in progress */ 5697a9800bebSGarrett D'Amore sbp->xrip->flag &= ~EMLXS_XRI_PENDING_IO; 5698*8f23e9faSHans Rosenfeld sbp->xrip->flag |= EMLXS_XRI_BUSY; 569982527734SSukumar Swaminathan 570082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 5701*8f23e9faSHans Rosenfeld "CQ ENTRY: XRI BUSY: iotag=%d xri=%d", request_tag, 5702a9800bebSGarrett D'Amore sbp->xrip->XRI); 570382527734SSukumar Swaminathan 5704*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, 0, 0); 570582527734SSukumar Swaminathan } else { 570682527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 5707*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, sbp, sbp->xrip, 0); 5708a9800bebSGarrett D'Amore } 5709a9800bebSGarrett D'Amore 5710a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 5711a9800bebSGarrett D'Amore 5712a9800bebSGarrett D'Amore #ifdef SFCT_SUPPORT 5713*8f23e9faSHans Rosenfeld #ifdef FCT_IO_TRACE 5714a9800bebSGarrett D'Amore fct_cmd = sbp->fct_cmd; 5715a9800bebSGarrett D'Amore if (fct_cmd) { 5716a9800bebSGarrett D'Amore cmd_sbp = (emlxs_buf_t *)fct_cmd->cmd_fca_private; 5717a9800bebSGarrett D'Amore mutex_enter(&cmd_sbp->fct_mtx); 5718a9800bebSGarrett D'Amore EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp, EMLXS_FCT_IOCB_COMPLETE); 5719a9800bebSGarrett D'Amore mutex_exit(&cmd_sbp->fct_mtx); 572082527734SSukumar Swaminathan } 5721*8f23e9faSHans Rosenfeld #endif /* FCT_IO_TRACE */ 5722a9800bebSGarrett D'Amore #endif /* SFCT_SUPPORT */ 572382527734SSukumar Swaminathan 572482527734SSukumar Swaminathan /* 572582527734SSukumar Swaminathan * If this is NOT a polled command completion 572682527734SSukumar Swaminathan * or a driver allocated pkt, then defer pkt 572782527734SSukumar Swaminathan * completion. 572882527734SSukumar Swaminathan */ 572982527734SSukumar Swaminathan if (!(sbp->pkt_flags & 573082527734SSukumar Swaminathan (PACKET_POLLED | PACKET_ALLOCATED))) { 573182527734SSukumar Swaminathan /* Add the IOCB to the channel list */ 573282527734SSukumar Swaminathan mutex_enter(&cp->rsp_lock); 573382527734SSukumar Swaminathan if (cp->rsp_head == NULL) { 573482527734SSukumar Swaminathan cp->rsp_head = iocbq; 573582527734SSukumar Swaminathan cp->rsp_tail = iocbq; 573682527734SSukumar Swaminathan } else { 573782527734SSukumar Swaminathan cp->rsp_tail->next = iocbq; 573882527734SSukumar Swaminathan cp->rsp_tail = iocbq; 573982527734SSukumar Swaminathan } 574082527734SSukumar Swaminathan mutex_exit(&cp->rsp_lock); 574182527734SSukumar Swaminathan 574282527734SSukumar Swaminathan /* Delay triggering thread till end of ISR */ 574382527734SSukumar Swaminathan cp->chan_flag |= EMLXS_NEEDS_TRIGGER; 574482527734SSukumar Swaminathan } else { 574582527734SSukumar Swaminathan emlxs_proc_channel_event(hba, cp, iocbq); 574682527734SSukumar Swaminathan } 574782527734SSukumar Swaminathan 574882527734SSukumar Swaminathan } /* emlxs_sli4_process_wqe_cmpl() */ 574982527734SSukumar Swaminathan 575082527734SSukumar Swaminathan 575182527734SSukumar Swaminathan /*ARGSUSED*/ 575282527734SSukumar Swaminathan static void 575382527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(emlxs_hba_t *hba, CQ_DESC_t *cq, 575482527734SSukumar Swaminathan CQE_RelWQ_t *cqe) 575582527734SSukumar Swaminathan { 575682527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 575782527734SSukumar Swaminathan WQ_DESC_t *wq; 575882527734SSukumar Swaminathan CHANNEL *cp; 575982527734SSukumar Swaminathan uint32_t i; 5760*8f23e9faSHans Rosenfeld uint16_t wqi; 5761*8f23e9faSHans Rosenfeld 5762*8f23e9faSHans Rosenfeld wqi = emlxs_sli4_wqid_to_index(hba, (uint16_t)cqe->WQid); 5763*8f23e9faSHans Rosenfeld 5764*8f23e9faSHans Rosenfeld /* Verify WQ index */ 5765*8f23e9faSHans Rosenfeld if (wqi == 0xffff) { 5766*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 5767*8f23e9faSHans Rosenfeld "CQ ENTRY: Invalid WQid:%d. Dropping...", 5768*8f23e9faSHans Rosenfeld cqe->WQid); 5769*8f23e9faSHans Rosenfeld return; 5770*8f23e9faSHans Rosenfeld } 577182527734SSukumar Swaminathan 5772*8f23e9faSHans Rosenfeld wq = &hba->sli.sli4.wq[wqi]; 577382527734SSukumar Swaminathan 5774*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 577582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 577682527734SSukumar Swaminathan "CQ ENTRY: process release wqe: old %d new %d", wq->port_index, 577782527734SSukumar Swaminathan cqe->WQindex); 5778*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 577982527734SSukumar Swaminathan 578082527734SSukumar Swaminathan wq->port_index = cqe->WQindex; 578182527734SSukumar Swaminathan 578282527734SSukumar Swaminathan /* Cmd ring may be available. Try sending more iocbs */ 578382527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 578482527734SSukumar Swaminathan cp = &hba->chan[i]; 578582527734SSukumar Swaminathan if (wq == (WQ_DESC_t *)cp->iopath) { 578682527734SSukumar Swaminathan emlxs_sli4_issue_iocb_cmd(hba, cp, 0); 578782527734SSukumar Swaminathan } 578882527734SSukumar Swaminathan } 578982527734SSukumar Swaminathan 579082527734SSukumar Swaminathan } /* emlxs_sli4_process_release_wqe() */ 579182527734SSukumar Swaminathan 579282527734SSukumar Swaminathan 579382527734SSukumar Swaminathan /*ARGSUSED*/ 579482527734SSukumar Swaminathan emlxs_iocbq_t * 579582527734SSukumar Swaminathan emlxs_sli4_rxq_get(emlxs_hba_t *hba, fc_frame_hdr_t *fchdr) 579682527734SSukumar Swaminathan { 579782527734SSukumar Swaminathan emlxs_queue_t *q; 579882527734SSukumar Swaminathan emlxs_iocbq_t *iocbq; 579982527734SSukumar Swaminathan emlxs_iocbq_t *prev; 580082527734SSukumar Swaminathan fc_frame_hdr_t *fchdr2; 580182527734SSukumar Swaminathan RXQ_DESC_t *rxq; 580282527734SSukumar Swaminathan 580382527734SSukumar Swaminathan switch (fchdr->type) { 580482527734SSukumar Swaminathan case 1: /* ELS */ 580582527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 580682527734SSukumar Swaminathan break; 580782527734SSukumar Swaminathan case 0x20: /* CT */ 580882527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 580982527734SSukumar Swaminathan break; 581082527734SSukumar Swaminathan default: 581182527734SSukumar Swaminathan return (NULL); 581282527734SSukumar Swaminathan } 581382527734SSukumar Swaminathan 581482527734SSukumar Swaminathan mutex_enter(&rxq->lock); 581582527734SSukumar Swaminathan 581682527734SSukumar Swaminathan q = &rxq->active; 581782527734SSukumar Swaminathan iocbq = (emlxs_iocbq_t *)q->q_first; 581882527734SSukumar Swaminathan prev = NULL; 581982527734SSukumar Swaminathan 582082527734SSukumar Swaminathan while (iocbq) { 582182527734SSukumar Swaminathan 582282527734SSukumar Swaminathan fchdr2 = (fc_frame_hdr_t *)iocbq->iocb.un.ulpWord; 582382527734SSukumar Swaminathan 582482527734SSukumar Swaminathan if ((fchdr2->s_id == fchdr->s_id) && 582582527734SSukumar Swaminathan (fchdr2->ox_id == fchdr->ox_id) && 582682527734SSukumar Swaminathan (fchdr2->seq_id == fchdr->seq_id)) { 582782527734SSukumar Swaminathan /* Remove iocbq */ 582882527734SSukumar Swaminathan if (prev) { 582982527734SSukumar Swaminathan prev->next = iocbq->next; 583082527734SSukumar Swaminathan } 583182527734SSukumar Swaminathan if (q->q_first == (uint8_t *)iocbq) { 583282527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq->next; 583382527734SSukumar Swaminathan } 583482527734SSukumar Swaminathan if (q->q_last == (uint8_t *)iocbq) { 583582527734SSukumar Swaminathan q->q_last = (uint8_t *)prev; 583682527734SSukumar Swaminathan } 583782527734SSukumar Swaminathan q->q_cnt--; 583882527734SSukumar Swaminathan 583982527734SSukumar Swaminathan break; 584082527734SSukumar Swaminathan } 584182527734SSukumar Swaminathan 584282527734SSukumar Swaminathan prev = iocbq; 584382527734SSukumar Swaminathan iocbq = iocbq->next; 584482527734SSukumar Swaminathan } 584582527734SSukumar Swaminathan 584682527734SSukumar Swaminathan mutex_exit(&rxq->lock); 584782527734SSukumar Swaminathan 584882527734SSukumar Swaminathan return (iocbq); 584982527734SSukumar Swaminathan 585082527734SSukumar Swaminathan } /* emlxs_sli4_rxq_get() */ 585182527734SSukumar Swaminathan 585282527734SSukumar Swaminathan 585382527734SSukumar Swaminathan /*ARGSUSED*/ 585482527734SSukumar Swaminathan void 585582527734SSukumar Swaminathan emlxs_sli4_rxq_put(emlxs_hba_t *hba, emlxs_iocbq_t *iocbq) 585682527734SSukumar Swaminathan { 585782527734SSukumar Swaminathan emlxs_queue_t *q; 585882527734SSukumar Swaminathan fc_frame_hdr_t *fchdr; 585982527734SSukumar Swaminathan RXQ_DESC_t *rxq; 586082527734SSukumar Swaminathan 586182527734SSukumar Swaminathan fchdr = (fc_frame_hdr_t *)iocbq->iocb.RXFCHDR; 586282527734SSukumar Swaminathan 586382527734SSukumar Swaminathan switch (fchdr->type) { 586482527734SSukumar Swaminathan case 1: /* ELS */ 586582527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_ELS]; 586682527734SSukumar Swaminathan break; 586782527734SSukumar Swaminathan case 0x20: /* CT */ 586882527734SSukumar Swaminathan rxq = &hba->sli.sli4.rxq[EMLXS_RXQ_CT]; 586982527734SSukumar Swaminathan break; 587082527734SSukumar Swaminathan default: 587182527734SSukumar Swaminathan return; 587282527734SSukumar Swaminathan } 587382527734SSukumar Swaminathan 587482527734SSukumar Swaminathan mutex_enter(&rxq->lock); 587582527734SSukumar Swaminathan 587682527734SSukumar Swaminathan q = &rxq->active; 587782527734SSukumar Swaminathan 587882527734SSukumar Swaminathan if (q->q_last) { 587982527734SSukumar Swaminathan ((emlxs_iocbq_t *)q->q_last)->next = iocbq; 588082527734SSukumar Swaminathan q->q_cnt++; 588182527734SSukumar Swaminathan } else { 588282527734SSukumar Swaminathan q->q_first = (uint8_t *)iocbq; 588382527734SSukumar Swaminathan q->q_cnt = 1; 588482527734SSukumar Swaminathan } 588582527734SSukumar Swaminathan 588682527734SSukumar Swaminathan q->q_last = (uint8_t *)iocbq; 588782527734SSukumar Swaminathan iocbq->next = NULL; 588882527734SSukumar Swaminathan 588982527734SSukumar Swaminathan mutex_exit(&rxq->lock); 589082527734SSukumar Swaminathan 589182527734SSukumar Swaminathan return; 589282527734SSukumar Swaminathan 589382527734SSukumar Swaminathan } /* emlxs_sli4_rxq_put() */ 589482527734SSukumar Swaminathan 589582527734SSukumar Swaminathan 589682527734SSukumar Swaminathan static void 5897a9800bebSGarrett D'Amore emlxs_sli4_rq_post(emlxs_port_t *port, uint16_t rqid) 589882527734SSukumar Swaminathan { 5899a9800bebSGarrett D'Amore emlxs_hba_t *hba = HBA; 590082527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 590182527734SSukumar Swaminathan 590282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 590382527734SSukumar Swaminathan "RQ POST: rqid=%d count=1", rqid); 590482527734SSukumar Swaminathan 590582527734SSukumar Swaminathan /* Ring the RQ doorbell once to repost the RQ buffer */ 590682527734SSukumar Swaminathan rqdb.word = 0; 590782527734SSukumar Swaminathan rqdb.db.Qid = rqid; 590882527734SSukumar Swaminathan rqdb.db.NumPosted = 1; 590982527734SSukumar Swaminathan 5910*8f23e9faSHans Rosenfeld emlxs_sli4_write_rqdb(hba, rqdb.word); 591182527734SSukumar Swaminathan 591282527734SSukumar Swaminathan } /* emlxs_sli4_rq_post() */ 591382527734SSukumar Swaminathan 591482527734SSukumar Swaminathan 591582527734SSukumar Swaminathan /*ARGSUSED*/ 591682527734SSukumar Swaminathan static void 591782527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(emlxs_hba_t *hba, CQ_DESC_t *cq, 591882527734SSukumar Swaminathan CQE_UnsolRcv_t *cqe) 591982527734SSukumar Swaminathan { 592082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 592182527734SSukumar Swaminathan emlxs_port_t *vport; 592282527734SSukumar Swaminathan RQ_DESC_t *hdr_rq; 592382527734SSukumar Swaminathan RQ_DESC_t *data_rq; 5924b3660a96SSukumar Swaminathan MBUF_INFO *hdr_mp; 5925b3660a96SSukumar Swaminathan MBUF_INFO *data_mp; 592682527734SSukumar Swaminathan MATCHMAP *seq_mp; 592782527734SSukumar Swaminathan uint32_t *data; 592882527734SSukumar Swaminathan fc_frame_hdr_t fchdr; 5929*8f23e9faSHans Rosenfeld uint16_t hdr_rqi; 593082527734SSukumar Swaminathan uint32_t host_index; 593182527734SSukumar Swaminathan emlxs_iocbq_t *iocbq = NULL; 593282527734SSukumar Swaminathan emlxs_iocb_t *iocb; 5933*8f23e9faSHans Rosenfeld emlxs_node_t *node = NULL; 593482527734SSukumar Swaminathan uint32_t i; 593582527734SSukumar Swaminathan uint32_t seq_len; 593682527734SSukumar Swaminathan uint32_t seq_cnt; 593782527734SSukumar Swaminathan uint32_t buf_type; 593882527734SSukumar Swaminathan char label[32]; 593982527734SSukumar Swaminathan emlxs_wqe_t *wqe; 594082527734SSukumar Swaminathan CHANNEL *cp; 5941a9800bebSGarrett D'Amore XRIobj_t *xrip; 5942a9800bebSGarrett D'Amore RPIobj_t *rpip = NULL; 594382527734SSukumar Swaminathan uint32_t cmd; 594482527734SSukumar Swaminathan uint32_t posted = 0; 594582527734SSukumar Swaminathan uint32_t abort = 1; 5946b3660a96SSukumar Swaminathan off_t offset; 5947*8f23e9faSHans Rosenfeld uint32_t status; 5948*8f23e9faSHans Rosenfeld uint32_t data_size; 5949*8f23e9faSHans Rosenfeld uint16_t rqid; 5950*8f23e9faSHans Rosenfeld uint32_t hdr_size; 5951*8f23e9faSHans Rosenfeld fc_packet_t *pkt; 5952*8f23e9faSHans Rosenfeld emlxs_buf_t *sbp; 595382527734SSukumar Swaminathan 5954*8f23e9faSHans Rosenfeld if (cqe->Code == CQE_TYPE_UNSOL_RCV_V1) { 5955*8f23e9faSHans Rosenfeld CQE_UnsolRcvV1_t *cqeV1 = (CQE_UnsolRcvV1_t *)cqe; 595682527734SSukumar Swaminathan 5957*8f23e9faSHans Rosenfeld status = cqeV1->Status; 5958*8f23e9faSHans Rosenfeld data_size = cqeV1->data_size; 5959*8f23e9faSHans Rosenfeld rqid = cqeV1->RQid; 5960*8f23e9faSHans Rosenfeld hdr_size = cqeV1->hdr_size; 5961*8f23e9faSHans Rosenfeld } else { 5962*8f23e9faSHans Rosenfeld status = cqe->Status; 5963*8f23e9faSHans Rosenfeld data_size = cqe->data_size; 5964*8f23e9faSHans Rosenfeld rqid = cqe->RQid; 5965*8f23e9faSHans Rosenfeld hdr_size = cqe->hdr_size; 5966*8f23e9faSHans Rosenfeld } 596782527734SSukumar Swaminathan 596882527734SSukumar Swaminathan /* Validate the CQE */ 596982527734SSukumar Swaminathan 597082527734SSukumar Swaminathan /* Check status */ 5971*8f23e9faSHans Rosenfeld switch (status) { 597282527734SSukumar Swaminathan case RQ_STATUS_SUCCESS: /* 0x10 */ 597382527734SSukumar Swaminathan break; 597482527734SSukumar Swaminathan 597582527734SSukumar Swaminathan case RQ_STATUS_BUFLEN_EXCEEDED: /* 0x11 */ 597682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 597782527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload truncated."); 597882527734SSukumar Swaminathan break; 597982527734SSukumar Swaminathan 598082527734SSukumar Swaminathan case RQ_STATUS_NEED_BUFFER: /* 0x12 */ 598182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 598282527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer needed."); 598382527734SSukumar Swaminathan return; 598482527734SSukumar Swaminathan 598582527734SSukumar Swaminathan case RQ_STATUS_FRAME_DISCARDED: /* 0x13 */ 598682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 598782527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Payload buffer discarded."); 598882527734SSukumar Swaminathan return; 598982527734SSukumar Swaminathan 599082527734SSukumar Swaminathan default: 599182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 599282527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: Unknown status=%x.", 5993*8f23e9faSHans Rosenfeld status); 599482527734SSukumar Swaminathan break; 599582527734SSukumar Swaminathan } 599682527734SSukumar Swaminathan 599782527734SSukumar Swaminathan /* Make sure there is a frame header */ 5998*8f23e9faSHans Rosenfeld if (hdr_size < sizeof (fc_frame_hdr_t)) { 599982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 600082527734SSukumar Swaminathan "CQ ENTRY: Unsol Rcv: FC header too small. Dropping..."); 600182527734SSukumar Swaminathan return; 600282527734SSukumar Swaminathan } 600382527734SSukumar Swaminathan 6004*8f23e9faSHans Rosenfeld hdr_rqi = emlxs_sli4_rqid_to_index(hba, rqid); 6005*8f23e9faSHans Rosenfeld 6006*8f23e9faSHans Rosenfeld /* Verify RQ index */ 6007*8f23e9faSHans Rosenfeld if (hdr_rqi == 0xffff) { 6008*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6009*8f23e9faSHans Rosenfeld "CQ ENTRY: Unsol Rcv: Invalid RQID:%d. Dropping...", 6010*8f23e9faSHans Rosenfeld rqid); 6011*8f23e9faSHans Rosenfeld return; 6012*8f23e9faSHans Rosenfeld } 6013*8f23e9faSHans Rosenfeld 6014*8f23e9faSHans Rosenfeld hdr_rq = &hba->sli.sli4.rq[hdr_rqi]; 6015*8f23e9faSHans Rosenfeld data_rq = &hba->sli.sli4.rq[hdr_rqi + 1]; 6016*8f23e9faSHans Rosenfeld 6017*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6018*8f23e9faSHans Rosenfeld "CQ ENTRY: Unsol Rcv:%x rqid=%d,%d index=%d status=%x " 6019*8f23e9faSHans Rosenfeld "hdr_size=%d data_size=%d", 6020*8f23e9faSHans Rosenfeld cqe->Code, rqid, hdr_rqi, hdr_rq->host_index, status, hdr_size, 6021*8f23e9faSHans Rosenfeld data_size); 6022*8f23e9faSHans Rosenfeld 6023*8f23e9faSHans Rosenfeld hdr_rq->num_proc++; 6024*8f23e9faSHans Rosenfeld 602582527734SSukumar Swaminathan /* Update host index */ 602682527734SSukumar Swaminathan mutex_enter(&hba->sli.sli4.rq[hdr_rqi].lock); 602782527734SSukumar Swaminathan host_index = hdr_rq->host_index; 602882527734SSukumar Swaminathan hdr_rq->host_index++; 6029*8f23e9faSHans Rosenfeld 603082527734SSukumar Swaminathan if (hdr_rq->host_index >= hdr_rq->max_index) { 603182527734SSukumar Swaminathan hdr_rq->host_index = 0; 603282527734SSukumar Swaminathan } 603382527734SSukumar Swaminathan data_rq->host_index = hdr_rq->host_index; 603482527734SSukumar Swaminathan mutex_exit(&hba->sli.sli4.rq[hdr_rqi].lock); 603582527734SSukumar Swaminathan 603682527734SSukumar Swaminathan /* Get the next header rqb */ 6037b3660a96SSukumar Swaminathan hdr_mp = &hdr_rq->rqb[host_index]; 603882527734SSukumar Swaminathan 6039b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long)hdr_mp->virt) - 6040b3660a96SSukumar Swaminathan (uint64_t)((unsigned long)hba->sli.sli4.slim2.virt)); 6041b3660a96SSukumar Swaminathan 6042b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hdr_mp->dma_handle, offset, 604382527734SSukumar Swaminathan sizeof (fc_frame_hdr_t), DDI_DMA_SYNC_FORKERNEL); 604482527734SSukumar Swaminathan 604582527734SSukumar Swaminathan LE_SWAP32_BCOPY(hdr_mp->virt, (uint8_t *)&fchdr, 604682527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 604782527734SSukumar Swaminathan 604882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6049a9800bebSGarrett D'Amore "RQ HDR[%d]: rctl:%x type:%x " 605082527734SSukumar Swaminathan "sid:%x did:%x oxid:%x rxid:%x", 605182527734SSukumar Swaminathan host_index, fchdr.r_ctl, fchdr.type, 605282527734SSukumar Swaminathan fchdr.s_id, fchdr.d_id, fchdr.ox_id, fchdr.rx_id); 605382527734SSukumar Swaminathan 605482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 605582527734SSukumar Swaminathan "RQ HDR[%d]: fctl:%x seq_id:%x seq_cnt:%x df_ctl:%x ro:%x", 605682527734SSukumar Swaminathan host_index, fchdr.f_ctl, fchdr.seq_id, fchdr.seq_cnt, 605782527734SSukumar Swaminathan fchdr.df_ctl, fchdr.ro); 605882527734SSukumar Swaminathan 605982527734SSukumar Swaminathan /* Verify fc header type */ 606082527734SSukumar Swaminathan switch (fchdr.type) { 606182527734SSukumar Swaminathan case 0: /* BLS */ 606282527734SSukumar Swaminathan if (fchdr.r_ctl != 0x81) { 606382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6064a9800bebSGarrett D'Amore "RQ ENTRY: Unexpected FC rctl (0x%x) " 606582527734SSukumar Swaminathan "received. Dropping...", 606682527734SSukumar Swaminathan fchdr.r_ctl); 606782527734SSukumar Swaminathan 606882527734SSukumar Swaminathan goto done; 606982527734SSukumar Swaminathan } 607082527734SSukumar Swaminathan 607182527734SSukumar Swaminathan /* Make sure there is no payload */ 6072*8f23e9faSHans Rosenfeld if (data_size != 0) { 607382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 607482527734SSukumar Swaminathan "RQ ENTRY: ABTS payload provided. Dropping..."); 607582527734SSukumar Swaminathan 607682527734SSukumar Swaminathan goto done; 607782527734SSukumar Swaminathan } 607882527734SSukumar Swaminathan 607982527734SSukumar Swaminathan buf_type = 0xFFFFFFFF; 6080*8f23e9faSHans Rosenfeld (void) strlcpy(label, "ABTS", sizeof (label)); 608182527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 608282527734SSukumar Swaminathan break; 608382527734SSukumar Swaminathan 608482527734SSukumar Swaminathan case 0x01: /* ELS */ 608582527734SSukumar Swaminathan /* Make sure there is a payload */ 6086*8f23e9faSHans Rosenfeld if (data_size == 0) { 608782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6088a9800bebSGarrett D'Amore "RQ ENTRY: Unsol Rcv: No ELS payload provided. " 608982527734SSukumar Swaminathan "Dropping..."); 609082527734SSukumar Swaminathan 609182527734SSukumar Swaminathan goto done; 609282527734SSukumar Swaminathan } 609382527734SSukumar Swaminathan 609482527734SSukumar Swaminathan buf_type = MEM_ELSBUF; 6095*8f23e9faSHans Rosenfeld (void) strlcpy(label, "Unsol ELS", sizeof (label)); 609682527734SSukumar Swaminathan cp = &hba->chan[hba->channel_els]; 609782527734SSukumar Swaminathan break; 609882527734SSukumar Swaminathan 609982527734SSukumar Swaminathan case 0x20: /* CT */ 610082527734SSukumar Swaminathan /* Make sure there is a payload */ 6101*8f23e9faSHans Rosenfeld if (data_size == 0) { 610282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6103a9800bebSGarrett D'Amore "RQ ENTRY: Unsol Rcv: No CT payload provided. " 610482527734SSukumar Swaminathan "Dropping..."); 610582527734SSukumar Swaminathan 610682527734SSukumar Swaminathan goto done; 610782527734SSukumar Swaminathan } 610882527734SSukumar Swaminathan 610982527734SSukumar Swaminathan buf_type = MEM_CTBUF; 6110*8f23e9faSHans Rosenfeld (void) strlcpy(label, "Unsol CT", sizeof (label)); 611182527734SSukumar Swaminathan cp = &hba->chan[hba->channel_ct]; 611282527734SSukumar Swaminathan break; 611382527734SSukumar Swaminathan 6114*8f23e9faSHans Rosenfeld case 0x08: /* FCT */ 6115*8f23e9faSHans Rosenfeld /* Make sure there is a payload */ 6116*8f23e9faSHans Rosenfeld if (data_size == 0) { 6117*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6118*8f23e9faSHans Rosenfeld "RQ ENTRY: Unsol Rcv: No FCP payload provided. " 6119*8f23e9faSHans Rosenfeld "Dropping..."); 6120*8f23e9faSHans Rosenfeld 6121*8f23e9faSHans Rosenfeld goto done; 6122*8f23e9faSHans Rosenfeld } 6123*8f23e9faSHans Rosenfeld 6124*8f23e9faSHans Rosenfeld buf_type = MEM_FCTBUF; 6125*8f23e9faSHans Rosenfeld (void) strlcpy(label, "Unsol FCT", sizeof (label)); 6126*8f23e9faSHans Rosenfeld cp = &hba->chan[hba->CHANNEL_FCT]; 6127*8f23e9faSHans Rosenfeld break; 6128*8f23e9faSHans Rosenfeld 612982527734SSukumar Swaminathan default: 613082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 613182527734SSukumar Swaminathan "RQ ENTRY: Unexpected FC type (0x%x) received. Dropping...", 613282527734SSukumar Swaminathan fchdr.type); 613382527734SSukumar Swaminathan 613482527734SSukumar Swaminathan goto done; 613582527734SSukumar Swaminathan } 613682527734SSukumar Swaminathan /* Fc Header is valid */ 613782527734SSukumar Swaminathan 613882527734SSukumar Swaminathan /* Check if this is an active sequence */ 613982527734SSukumar Swaminathan iocbq = emlxs_sli4_rxq_get(hba, &fchdr); 614082527734SSukumar Swaminathan 614182527734SSukumar Swaminathan if (!iocbq) { 614282527734SSukumar Swaminathan if (fchdr.type != 0) { 614382527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_FIRST_SEQ)) { 614482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6145a9800bebSGarrett D'Amore "RQ ENTRY: %s: First of sequence not" 614682527734SSukumar Swaminathan " set. Dropping...", 614782527734SSukumar Swaminathan label); 614882527734SSukumar Swaminathan 614982527734SSukumar Swaminathan goto done; 615082527734SSukumar Swaminathan } 615182527734SSukumar Swaminathan } 615282527734SSukumar Swaminathan 6153*8f23e9faSHans Rosenfeld if ((fchdr.type != 0) && (fchdr.seq_cnt != 0)) { 615482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6155a9800bebSGarrett D'Amore "RQ ENTRY: %s: Sequence count not zero (%d). " 615682527734SSukumar Swaminathan "Dropping...", 615782527734SSukumar Swaminathan label, fchdr.seq_cnt); 615882527734SSukumar Swaminathan 615982527734SSukumar Swaminathan goto done; 616082527734SSukumar Swaminathan } 616182527734SSukumar Swaminathan 6162*8f23e9faSHans Rosenfeld /* Find vport */ 616382527734SSukumar Swaminathan for (i = 0; i < MAX_VPORTS; i++) { 616482527734SSukumar Swaminathan vport = &VPORT(i); 616582527734SSukumar Swaminathan 616682527734SSukumar Swaminathan if (vport->did == fchdr.d_id) { 616782527734SSukumar Swaminathan port = vport; 616882527734SSukumar Swaminathan break; 616982527734SSukumar Swaminathan } 617082527734SSukumar Swaminathan } 617182527734SSukumar Swaminathan 6172*8f23e9faSHans Rosenfeld if (i == MAX_VPORTS) { 6173*8f23e9faSHans Rosenfeld /* Allow unsol FLOGI & PLOGI for P2P */ 6174*8f23e9faSHans Rosenfeld if ((fchdr.type != 1 /* ELS*/) || 6175*8f23e9faSHans Rosenfeld ((fchdr.d_id != FABRIC_DID) && 6176*8f23e9faSHans Rosenfeld !(hba->flag & FC_PT_TO_PT))) { 6177*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6178*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Invalid did=%x. Dropping...", 6179*8f23e9faSHans Rosenfeld label, fchdr.d_id); 6180*8f23e9faSHans Rosenfeld 6181*8f23e9faSHans Rosenfeld goto done; 6182*8f23e9faSHans Rosenfeld } 6183*8f23e9faSHans Rosenfeld } 6184*8f23e9faSHans Rosenfeld 618582527734SSukumar Swaminathan /* Allocate an IOCBQ */ 6186*8f23e9faSHans Rosenfeld iocbq = (emlxs_iocbq_t *)emlxs_mem_get(hba, MEM_IOCB); 618782527734SSukumar Swaminathan 618882527734SSukumar Swaminathan if (!iocbq) { 618982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6190a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of IOCB " 619182527734SSukumar Swaminathan "resources. Dropping...", 619282527734SSukumar Swaminathan label); 619382527734SSukumar Swaminathan 619482527734SSukumar Swaminathan goto done; 619582527734SSukumar Swaminathan } 619682527734SSukumar Swaminathan 619782527734SSukumar Swaminathan seq_mp = NULL; 619882527734SSukumar Swaminathan if (fchdr.type != 0) { 619982527734SSukumar Swaminathan /* Allocate a buffer */ 6200*8f23e9faSHans Rosenfeld seq_mp = (MATCHMAP *)emlxs_mem_get(hba, buf_type); 620182527734SSukumar Swaminathan 620282527734SSukumar Swaminathan if (!seq_mp) { 620382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6204a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of buffer " 620582527734SSukumar Swaminathan "resources. Dropping...", 620682527734SSukumar Swaminathan label); 620782527734SSukumar Swaminathan 620882527734SSukumar Swaminathan goto done; 620982527734SSukumar Swaminathan } 621082527734SSukumar Swaminathan 621182527734SSukumar Swaminathan iocbq->bp = (uint8_t *)seq_mp; 621282527734SSukumar Swaminathan } 621382527734SSukumar Swaminathan 6214*8f23e9faSHans Rosenfeld node = (void *)emlxs_node_find_did(port, fchdr.s_id, 1); 621582527734SSukumar Swaminathan if (node == NULL) { 621682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 621782527734SSukumar Swaminathan "RQ ENTRY: %s: Node not found. sid=%x", 621882527734SSukumar Swaminathan label, fchdr.s_id); 621982527734SSukumar Swaminathan } 622082527734SSukumar Swaminathan 622182527734SSukumar Swaminathan /* Initialize the iocbq */ 622282527734SSukumar Swaminathan iocbq->port = port; 622382527734SSukumar Swaminathan iocbq->channel = cp; 622482527734SSukumar Swaminathan iocbq->node = node; 622582527734SSukumar Swaminathan 622682527734SSukumar Swaminathan iocb = &iocbq->iocb; 622782527734SSukumar Swaminathan iocb->RXSEQCNT = 0; 622882527734SSukumar Swaminathan iocb->RXSEQLEN = 0; 622982527734SSukumar Swaminathan 623082527734SSukumar Swaminathan seq_len = 0; 623182527734SSukumar Swaminathan seq_cnt = 0; 623282527734SSukumar Swaminathan 623382527734SSukumar Swaminathan } else { 623482527734SSukumar Swaminathan 623582527734SSukumar Swaminathan iocb = &iocbq->iocb; 623682527734SSukumar Swaminathan port = iocbq->port; 623782527734SSukumar Swaminathan node = (emlxs_node_t *)iocbq->node; 623882527734SSukumar Swaminathan 623982527734SSukumar Swaminathan seq_mp = (MATCHMAP *)iocbq->bp; 624082527734SSukumar Swaminathan seq_len = iocb->RXSEQLEN; 624182527734SSukumar Swaminathan seq_cnt = iocb->RXSEQCNT; 624282527734SSukumar Swaminathan 624382527734SSukumar Swaminathan /* Check sequence order */ 624482527734SSukumar Swaminathan if (fchdr.seq_cnt != seq_cnt) { 624582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6246a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of order frame received " 624782527734SSukumar Swaminathan "(%d != %d). Dropping...", 624882527734SSukumar Swaminathan label, fchdr.seq_cnt, seq_cnt); 624982527734SSukumar Swaminathan 625082527734SSukumar Swaminathan goto done; 625182527734SSukumar Swaminathan } 625282527734SSukumar Swaminathan } 625382527734SSukumar Swaminathan 625482527734SSukumar Swaminathan /* We now have an iocbq */ 625582527734SSukumar Swaminathan 6256*8f23e9faSHans Rosenfeld if (!port->vpip->vfip) { 6257a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6258a9800bebSGarrett D'Amore "RQ ENTRY: %s: No fabric connection. " 6259a9800bebSGarrett D'Amore "Dropping...", 6260a9800bebSGarrett D'Amore label); 6261a9800bebSGarrett D'Amore 6262a9800bebSGarrett D'Amore goto done; 6263a9800bebSGarrett D'Amore } 6264a9800bebSGarrett D'Amore 626582527734SSukumar Swaminathan /* Save the frame data to our seq buffer */ 6266*8f23e9faSHans Rosenfeld if (data_size && seq_mp) { 626782527734SSukumar Swaminathan /* Get the next data rqb */ 6268b3660a96SSukumar Swaminathan data_mp = &data_rq->rqb[host_index]; 6269b3660a96SSukumar Swaminathan 6270b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 6271b3660a96SSukumar Swaminathan data_mp->virt) - 6272b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 6273b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 627482527734SSukumar Swaminathan 6275b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(data_mp->dma_handle, offset, 6276*8f23e9faSHans Rosenfeld data_size, DDI_DMA_SYNC_FORKERNEL); 627782527734SSukumar Swaminathan 627882527734SSukumar Swaminathan data = (uint32_t *)data_mp->virt; 627982527734SSukumar Swaminathan 628082527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 628182527734SSukumar Swaminathan "RQ DAT[%d]: %08x %08x %08x %08x %08x %08x ...", 628282527734SSukumar Swaminathan host_index, data[0], data[1], data[2], data[3], 628382527734SSukumar Swaminathan data[4], data[5]); 628482527734SSukumar Swaminathan 628582527734SSukumar Swaminathan /* Check sequence length */ 6286*8f23e9faSHans Rosenfeld if ((seq_len + data_size) > seq_mp->size) { 628782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6288a9800bebSGarrett D'Amore "RQ ENTRY: %s: Sequence buffer overflow. " 628982527734SSukumar Swaminathan "(%d > %d). Dropping...", 6290*8f23e9faSHans Rosenfeld label, (seq_len + data_size), seq_mp->size); 629182527734SSukumar Swaminathan 629282527734SSukumar Swaminathan goto done; 629382527734SSukumar Swaminathan } 629482527734SSukumar Swaminathan 629582527734SSukumar Swaminathan /* Copy data to local receive buffer */ 629682527734SSukumar Swaminathan bcopy((uint8_t *)data, ((uint8_t *)seq_mp->virt + 6297*8f23e9faSHans Rosenfeld seq_len), data_size); 629882527734SSukumar Swaminathan 6299*8f23e9faSHans Rosenfeld seq_len += data_size; 630082527734SSukumar Swaminathan } 630182527734SSukumar Swaminathan 630282527734SSukumar Swaminathan /* If this is not the last frame of sequence, queue it. */ 630382527734SSukumar Swaminathan if (!(fchdr.f_ctl & F_CTL_END_SEQ)) { 630482527734SSukumar Swaminathan /* Save sequence header */ 630582527734SSukumar Swaminathan if (seq_cnt == 0) { 630682527734SSukumar Swaminathan bcopy((uint8_t *)&fchdr, (uint8_t *)iocb->RXFCHDR, 630782527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 630882527734SSukumar Swaminathan } 630982527734SSukumar Swaminathan 631082527734SSukumar Swaminathan /* Update sequence info in iocb */ 631182527734SSukumar Swaminathan iocb->RXSEQCNT = seq_cnt + 1; 631282527734SSukumar Swaminathan iocb->RXSEQLEN = seq_len; 631382527734SSukumar Swaminathan 631482527734SSukumar Swaminathan /* Queue iocbq for next frame */ 631582527734SSukumar Swaminathan emlxs_sli4_rxq_put(hba, iocbq); 631682527734SSukumar Swaminathan 631782527734SSukumar Swaminathan /* Don't free resources */ 631882527734SSukumar Swaminathan iocbq = NULL; 631982527734SSukumar Swaminathan 632082527734SSukumar Swaminathan /* No need to abort */ 632182527734SSukumar Swaminathan abort = 0; 632282527734SSukumar Swaminathan 632382527734SSukumar Swaminathan goto done; 632482527734SSukumar Swaminathan } 632582527734SSukumar Swaminathan 6326a9800bebSGarrett D'Amore emlxs_sli4_rq_post(port, hdr_rq->qid); 632782527734SSukumar Swaminathan posted = 1; 632882527734SSukumar Swaminathan 632982527734SSukumar Swaminathan /* End of sequence found. Process request now. */ 633082527734SSukumar Swaminathan 633182527734SSukumar Swaminathan if (seq_cnt > 0) { 633282527734SSukumar Swaminathan /* Retrieve first frame of sequence */ 633382527734SSukumar Swaminathan bcopy((uint8_t *)iocb->RXFCHDR, (uint8_t *)&fchdr, 633482527734SSukumar Swaminathan sizeof (fc_frame_hdr_t)); 633582527734SSukumar Swaminathan 633682527734SSukumar Swaminathan bzero((uint8_t *)iocb, sizeof (emlxs_iocb_t)); 633782527734SSukumar Swaminathan } 633882527734SSukumar Swaminathan 633982527734SSukumar Swaminathan /* Build rcv iocb and process it */ 634082527734SSukumar Swaminathan switch (fchdr.type) { 634182527734SSukumar Swaminathan case 0: /* BLS */ 634282527734SSukumar Swaminathan 634382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6344*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: oxid:%x rxid %x sid:%x. Sending BLS ACC...", 6345*8f23e9faSHans Rosenfeld label, fchdr.ox_id, fchdr.rx_id, fchdr.s_id); 634682527734SSukumar Swaminathan 6347*8f23e9faSHans Rosenfeld /* Try to send abort response */ 6348*8f23e9faSHans Rosenfeld if (!(pkt = emlxs_pkt_alloc(port, 0, 0, 0, KM_NOSLEEP))) { 6349*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6350*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Unable to alloc pkt. Dropping...", 6351*8f23e9faSHans Rosenfeld label); 6352*8f23e9faSHans Rosenfeld goto done; 6353*8f23e9faSHans Rosenfeld } 635482527734SSukumar Swaminathan 6355*8f23e9faSHans Rosenfeld /* Setup sbp / iocb for driver initiated cmd */ 6356*8f23e9faSHans Rosenfeld sbp = PKT2PRIV(pkt); 6357*8f23e9faSHans Rosenfeld 6358*8f23e9faSHans Rosenfeld /* Free the temporary iocbq */ 6359*8f23e9faSHans Rosenfeld emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 6360*8f23e9faSHans Rosenfeld 6361*8f23e9faSHans Rosenfeld iocbq = (emlxs_iocbq_t *)&sbp->iocbq; 6362*8f23e9faSHans Rosenfeld iocbq->port = port; 6363*8f23e9faSHans Rosenfeld iocbq->channel = cp; 6364*8f23e9faSHans Rosenfeld iocbq->node = node; 6365*8f23e9faSHans Rosenfeld 6366*8f23e9faSHans Rosenfeld sbp->pkt_flags &= ~PACKET_ULP_OWNED; 6367*8f23e9faSHans Rosenfeld 6368*8f23e9faSHans Rosenfeld if (node) { 6369*8f23e9faSHans Rosenfeld sbp->node = node; 6370*8f23e9faSHans Rosenfeld sbp->did = node->nlp_DID; 637182527734SSukumar Swaminathan } 6372*8f23e9faSHans Rosenfeld 6373*8f23e9faSHans Rosenfeld iocbq->flag |= (IOCB_PRIORITY | IOCB_SPECIAL); 637482527734SSukumar Swaminathan 637582527734SSukumar Swaminathan /* BLS ACC Response */ 637682527734SSukumar Swaminathan wqe = &iocbq->wqe; 637782527734SSukumar Swaminathan bzero((void *)wqe, sizeof (emlxs_wqe_t)); 637882527734SSukumar Swaminathan 6379*8f23e9faSHans Rosenfeld iocbq->iocb.ULPCOMMAND = CMD_XMIT_BLS_RSP64_CX; 638082527734SSukumar Swaminathan wqe->Command = CMD_XMIT_BLS_RSP64_CX; 638182527734SSukumar Swaminathan wqe->CmdType = WQE_TYPE_GEN; 638282527734SSukumar Swaminathan 638382527734SSukumar Swaminathan wqe->un.BlsRsp.Payload0 = 0x80; 638482527734SSukumar Swaminathan wqe->un.BlsRsp.Payload1 = fchdr.seq_id; 638582527734SSukumar Swaminathan 638682527734SSukumar Swaminathan wqe->un.BlsRsp.OXId = fchdr.ox_id; 638782527734SSukumar Swaminathan wqe->un.BlsRsp.RXId = fchdr.rx_id; 638882527734SSukumar Swaminathan 638982527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntLow = 0; 639082527734SSukumar Swaminathan wqe->un.BlsRsp.SeqCntHigh = 0xFFFF; 639182527734SSukumar Swaminathan 6392*8f23e9faSHans Rosenfeld wqe->un.BlsRsp.XO = ((fchdr.f_ctl & F_CTL_XCHG_CONTEXT)? 1:0); 639382527734SSukumar Swaminathan wqe->un.BlsRsp.AR = 0; 639482527734SSukumar Swaminathan 6395*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, node); 639682527734SSukumar Swaminathan 6397*8f23e9faSHans Rosenfeld if (rpip) { 6398*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_RPI_CONTEXT; 6399*8f23e9faSHans Rosenfeld wqe->ContextTag = rpip->RPI; 6400*8f23e9faSHans Rosenfeld } else { 6401*8f23e9faSHans Rosenfeld wqe->ContextType = WQE_VPI_CONTEXT; 6402*8f23e9faSHans Rosenfeld wqe->ContextTag = port->vpip->VPI; 640382527734SSukumar Swaminathan 6404*8f23e9faSHans Rosenfeld rpip = emlxs_rpi_reserve_notify(port, fchdr.s_id, 0); 640582527734SSukumar Swaminathan 6406*8f23e9faSHans Rosenfeld if (!rpip) { 6407*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6408*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Unable to alloc " 6409*8f23e9faSHans Rosenfeld "reserved RPI. Dropping...", 6410*8f23e9faSHans Rosenfeld label); 6411a9800bebSGarrett D'Amore 6412*8f23e9faSHans Rosenfeld goto done; 6413*8f23e9faSHans Rosenfeld } 6414a9800bebSGarrett D'Amore 6415*8f23e9faSHans Rosenfeld /* Store the reserved rpi */ 6416*8f23e9faSHans Rosenfeld wqe->CmdSpecific = rpip->RPI; 641782527734SSukumar Swaminathan 6418*8f23e9faSHans Rosenfeld wqe->un.BlsRsp.RemoteId = fchdr.s_id; 6419*8f23e9faSHans Rosenfeld wqe->un.BlsRsp.LocalId = fchdr.d_id; 642082527734SSukumar Swaminathan } 642182527734SSukumar Swaminathan 6422*8f23e9faSHans Rosenfeld if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 6423*8f23e9faSHans Rosenfeld wqe->CCPE = 1; 6424*8f23e9faSHans Rosenfeld wqe->CCP = fchdr.rsvd; 642582527734SSukumar Swaminathan } 642682527734SSukumar Swaminathan 6427*8f23e9faSHans Rosenfeld /* Allocate an exchange for this command */ 6428*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_alloc_xri(port, sbp, rpip, 6429*8f23e9faSHans Rosenfeld EMLXS_XRI_SOL_BLS_TYPE); 643082527734SSukumar Swaminathan 6431a9800bebSGarrett D'Amore if (!xrip) { 643282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6433*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Unable to alloc XRI. Dropping...", 643482527734SSukumar Swaminathan label); 643582527734SSukumar Swaminathan goto done; 643682527734SSukumar Swaminathan } 643782527734SSukumar Swaminathan 6438*8f23e9faSHans Rosenfeld wqe->XRITag = xrip->XRI; 6439*8f23e9faSHans Rosenfeld wqe->Class = CLASS3; 6440*8f23e9faSHans Rosenfeld wqe->RequestTag = xrip->iotag; 6441*8f23e9faSHans Rosenfeld wqe->CQId = (uint16_t)0xffff; /* default CQ for response */ 6442*8f23e9faSHans Rosenfeld 6443*8f23e9faSHans Rosenfeld sbp->ticks = hba->timer_tics + 30; 6444*8f23e9faSHans Rosenfeld 6445*8f23e9faSHans Rosenfeld emlxs_sli4_issue_iocb_cmd(hba, iocbq->channel, iocbq); 6446*8f23e9faSHans Rosenfeld 6447*8f23e9faSHans Rosenfeld /* The temporary iocbq has been freed already */ 6448*8f23e9faSHans Rosenfeld iocbq = NULL; 6449*8f23e9faSHans Rosenfeld 6450*8f23e9faSHans Rosenfeld break; 6451*8f23e9faSHans Rosenfeld 6452*8f23e9faSHans Rosenfeld case 1: /* ELS */ 6453*8f23e9faSHans Rosenfeld cmd = *((uint32_t *)seq_mp->virt); 6454*8f23e9faSHans Rosenfeld cmd &= ELS_CMD_MASK; 6455*8f23e9faSHans Rosenfeld 6456*8f23e9faSHans Rosenfeld if (!(port->vpip->flag & EMLXS_VPI_PORT_ENABLED)) { 6457*8f23e9faSHans Rosenfeld uint32_t dropit = 1; 6458*8f23e9faSHans Rosenfeld 6459*8f23e9faSHans Rosenfeld /* Allow for P2P handshaking */ 6460*8f23e9faSHans Rosenfeld switch (cmd) { 6461*8f23e9faSHans Rosenfeld case ELS_CMD_FLOGI: 6462*8f23e9faSHans Rosenfeld dropit = 0; 6463*8f23e9faSHans Rosenfeld break; 6464*8f23e9faSHans Rosenfeld 6465*8f23e9faSHans Rosenfeld case ELS_CMD_PLOGI: 6466*8f23e9faSHans Rosenfeld case ELS_CMD_PRLI: 6467*8f23e9faSHans Rosenfeld if (hba->flag & FC_PT_TO_PT) { 6468*8f23e9faSHans Rosenfeld dropit = 0; 6469*8f23e9faSHans Rosenfeld } 6470*8f23e9faSHans Rosenfeld break; 6471*8f23e9faSHans Rosenfeld } 6472*8f23e9faSHans Rosenfeld 6473*8f23e9faSHans Rosenfeld if (dropit) { 6474*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 6475*8f23e9faSHans Rosenfeld &emlxs_sli_detail_msg, 6476*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Port not yet enabled. " 6477*8f23e9faSHans Rosenfeld "Dropping...", 6478*8f23e9faSHans Rosenfeld label); 6479*8f23e9faSHans Rosenfeld goto done; 6480*8f23e9faSHans Rosenfeld } 6481*8f23e9faSHans Rosenfeld } 6482*8f23e9faSHans Rosenfeld 6483*8f23e9faSHans Rosenfeld rpip = NULL; 6484*8f23e9faSHans Rosenfeld 6485*8f23e9faSHans Rosenfeld if (cmd != ELS_CMD_LOGO) { 6486*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, node); 6487*8f23e9faSHans Rosenfeld } 6488*8f23e9faSHans Rosenfeld 6489*8f23e9faSHans Rosenfeld if (!rpip) { 6490*8f23e9faSHans Rosenfeld /* Use the fabric rpi */ 6491*8f23e9faSHans Rosenfeld rpip = port->vpip->fabric_rpip; 6492*8f23e9faSHans Rosenfeld } 6493*8f23e9faSHans Rosenfeld 6494*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_reserve_xri(port, rpip, 6495*8f23e9faSHans Rosenfeld EMLXS_XRI_UNSOL_ELS_TYPE, fchdr.ox_id); 6496*8f23e9faSHans Rosenfeld 6497*8f23e9faSHans Rosenfeld if (!xrip) { 6498*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6499*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Out of exchange " 6500*8f23e9faSHans Rosenfeld "resources. Dropping...", 6501*8f23e9faSHans Rosenfeld label); 6502*8f23e9faSHans Rosenfeld 6503*8f23e9faSHans Rosenfeld goto done; 6504*8f23e9faSHans Rosenfeld } 650582527734SSukumar Swaminathan 650682527734SSukumar Swaminathan /* Build CMD_RCV_ELS64_CX */ 650782527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeFlags = 0; 650882527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.tus.f.bdeSize = seq_len; 650982527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrLow = PADDR_LO(seq_mp->phys); 651082527734SSukumar Swaminathan iocb->un.rcvels64.elsReq.addrHigh = PADDR_HI(seq_mp->phys); 651182527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 651282527734SSukumar Swaminathan 651382527734SSukumar Swaminathan iocb->un.rcvels64.remoteID = fchdr.s_id; 651482527734SSukumar Swaminathan iocb->un.rcvels64.parmRo = fchdr.d_id; 651582527734SSukumar Swaminathan 651682527734SSukumar Swaminathan iocb->ULPPU = 0x3; 6517a9800bebSGarrett D'Amore iocb->ULPCONTEXT = xrip->XRI; 651882527734SSukumar Swaminathan iocb->ULPIOTAG = ((node)? node->nlp_Rpi:0); 651982527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 652082527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_ELS64_CX; 652182527734SSukumar Swaminathan 6522*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.seq_len = seq_len; 6523*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.vpi = port->vpip->VPI; 6524*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.oxid = fchdr.ox_id; 6525*8f23e9faSHans Rosenfeld 6526*8f23e9faSHans Rosenfeld if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 6527*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.ccpe = 1; 6528*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 6529*8f23e9faSHans Rosenfeld } 6530*8f23e9faSHans Rosenfeld 6531*8f23e9faSHans Rosenfeld if (port->mode == MODE_INITIATOR) { 6532*8f23e9faSHans Rosenfeld (void) emlxs_els_handle_unsol_req(port, iocbq->channel, 6533*8f23e9faSHans Rosenfeld iocbq, seq_mp, seq_len); 6534*8f23e9faSHans Rosenfeld } 6535*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 6536*8f23e9faSHans Rosenfeld else if (port->mode == MODE_TARGET) { 6537*8f23e9faSHans Rosenfeld (void) emlxs_fct_handle_unsol_els(port, iocbq->channel, 6538*8f23e9faSHans Rosenfeld iocbq, seq_mp, seq_len); 6539*8f23e9faSHans Rosenfeld } 6540*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 6541*8f23e9faSHans Rosenfeld break; 6542*8f23e9faSHans Rosenfeld 6543*8f23e9faSHans Rosenfeld #ifdef SFCT_SUPPORT 6544*8f23e9faSHans Rosenfeld case 8: /* FCT */ 6545*8f23e9faSHans Rosenfeld if (!(port->VPIobj.flag & EMLXS_VPI_PORT_ENABLED)) { 6546*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6547*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Port not yet enabled. " 6548*8f23e9faSHans Rosenfeld "Dropping...", 6549*8f23e9faSHans Rosenfeld label); 6550*8f23e9faSHans Rosenfeld 6551*8f23e9faSHans Rosenfeld goto done; 6552*8f23e9faSHans Rosenfeld } 6553*8f23e9faSHans Rosenfeld 6554*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, node); 6555*8f23e9faSHans Rosenfeld 6556*8f23e9faSHans Rosenfeld if (!rpip) { 6557*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6558*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Port not logged in. " 6559*8f23e9faSHans Rosenfeld "Dropping...", 6560*8f23e9faSHans Rosenfeld label); 6561*8f23e9faSHans Rosenfeld 6562*8f23e9faSHans Rosenfeld goto done; 6563*8f23e9faSHans Rosenfeld } 6564*8f23e9faSHans Rosenfeld 6565*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_reserve_xri(port, rpip, 6566*8f23e9faSHans Rosenfeld EMLXS_XRI_UNSOL_FCP_TYPE, fchdr.ox_id); 6567*8f23e9faSHans Rosenfeld 6568*8f23e9faSHans Rosenfeld if (!xrip) { 6569*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6570*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: Out of exchange " 6571*8f23e9faSHans Rosenfeld "resources. Dropping...", 6572*8f23e9faSHans Rosenfeld label); 6573*8f23e9faSHans Rosenfeld 6574*8f23e9faSHans Rosenfeld goto done; 6575*8f23e9faSHans Rosenfeld } 6576*8f23e9faSHans Rosenfeld 6577*8f23e9faSHans Rosenfeld /* Build CMD_RCV_SEQUENCE64_CX */ 6578*8f23e9faSHans Rosenfeld iocb->un.rcvseq64.rcvBde.tus.f.bdeFlags = 0; 6579*8f23e9faSHans Rosenfeld iocb->un.rcvseq64.rcvBde.tus.f.bdeSize = seq_len; 6580*8f23e9faSHans Rosenfeld iocb->un.rcvseq64.rcvBde.addrLow = PADDR_LO(seq_mp->phys); 6581*8f23e9faSHans Rosenfeld iocb->un.rcvseq64.rcvBde.addrHigh = PADDR_HI(seq_mp->phys); 6582*8f23e9faSHans Rosenfeld iocb->ULPBDECOUNT = 1; 6583*8f23e9faSHans Rosenfeld 6584*8f23e9faSHans Rosenfeld iocb->ULPPU = 0x3; 6585*8f23e9faSHans Rosenfeld iocb->ULPCONTEXT = xrip->XRI; 6586*8f23e9faSHans Rosenfeld iocb->ULPIOTAG = ((node)? node->nlp_Rpi:0); 6587*8f23e9faSHans Rosenfeld iocb->ULPCLASS = CLASS3; 6588*8f23e9faSHans Rosenfeld iocb->ULPCOMMAND = CMD_RCV_ELS64_CX; 6589*8f23e9faSHans Rosenfeld 659082527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 6591a9800bebSGarrett D'Amore iocb->unsli3.ext_rcv.vpi = port->VPIobj.VPI; 6592*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.oxid = fchdr.ox_id; 659382527734SSukumar Swaminathan 659482527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 659582527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 659682527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 659782527734SSukumar Swaminathan } 659882527734SSukumar Swaminathan 6599*8f23e9faSHans Rosenfeld /* pass xrip to FCT in the iocbq */ 6600*8f23e9faSHans Rosenfeld iocbq->sbp = xrip; 660182527734SSukumar Swaminathan 6602*8f23e9faSHans Rosenfeld #define EMLXS_FIX_CISCO_BUG1 6603*8f23e9faSHans Rosenfeld #ifdef EMLXS_FIX_CISCO_BUG1 6604*8f23e9faSHans Rosenfeld { 6605*8f23e9faSHans Rosenfeld uint8_t *ptr; 6606*8f23e9faSHans Rosenfeld ptr = ((uint8_t *)seq_mp->virt); 6607*8f23e9faSHans Rosenfeld if (((*ptr+12) != 0xa0) && (*(ptr+20) == 0x8) && (*(ptr+21) == 0x8)) { 6608*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6609*8f23e9faSHans Rosenfeld "RQ ENTRY: Bad CDB fixed"); 6610*8f23e9faSHans Rosenfeld *ptr++ = 0; 6611*8f23e9faSHans Rosenfeld *ptr = 0; 6612*8f23e9faSHans Rosenfeld } 6613*8f23e9faSHans Rosenfeld } 6614*8f23e9faSHans Rosenfeld #endif 6615*8f23e9faSHans Rosenfeld (void) emlxs_fct_handle_unsol_req(port, cp, iocbq, 6616*8f23e9faSHans Rosenfeld seq_mp, seq_len); 661782527734SSukumar Swaminathan break; 6618*8f23e9faSHans Rosenfeld #endif /* SFCT_SUPPORT */ 661982527734SSukumar Swaminathan 662082527734SSukumar Swaminathan case 0x20: /* CT */ 6621*8f23e9faSHans Rosenfeld if (!(port->vpip->flag & EMLXS_VPI_PORT_ENABLED) && 6622*8f23e9faSHans Rosenfeld !(hba->flag & FC_LOOPBACK_MODE)) { 6623a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6624a9800bebSGarrett D'Amore "RQ ENTRY: %s: Port not yet enabled. " 6625a9800bebSGarrett D'Amore "Dropping...", 6626a9800bebSGarrett D'Amore label); 6627a9800bebSGarrett D'Amore 6628a9800bebSGarrett D'Amore goto done; 6629a9800bebSGarrett D'Amore } 663082527734SSukumar Swaminathan 663182527734SSukumar Swaminathan if (!node) { 663282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6633a9800bebSGarrett D'Amore "RQ ENTRY: %s: Node not found (did=%x). " 663482527734SSukumar Swaminathan "Dropping...", 663582527734SSukumar Swaminathan label, fchdr.d_id); 663682527734SSukumar Swaminathan 663782527734SSukumar Swaminathan goto done; 663882527734SSukumar Swaminathan } 663982527734SSukumar Swaminathan 6640a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 664182527734SSukumar Swaminathan 6642a9800bebSGarrett D'Amore if (!rpip) { 664382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6644*8f23e9faSHans Rosenfeld "RQ ENTRY: %s: RPI not found (did=%x rpi=%d). " 664582527734SSukumar Swaminathan "Dropping...", 664682527734SSukumar Swaminathan label, fchdr.d_id, node->nlp_Rpi); 664782527734SSukumar Swaminathan 664882527734SSukumar Swaminathan goto done; 664982527734SSukumar Swaminathan } 665082527734SSukumar Swaminathan 6651*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_reserve_xri(port, rpip, 6652*8f23e9faSHans Rosenfeld EMLXS_XRI_UNSOL_CT_TYPE, fchdr.ox_id); 665382527734SSukumar Swaminathan 6654a9800bebSGarrett D'Amore if (!xrip) { 665582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6656a9800bebSGarrett D'Amore "RQ ENTRY: %s: Out of exchange " 665782527734SSukumar Swaminathan "resources. Dropping...", 665882527734SSukumar Swaminathan label); 665982527734SSukumar Swaminathan 666082527734SSukumar Swaminathan goto done; 666182527734SSukumar Swaminathan } 666282527734SSukumar Swaminathan 666382527734SSukumar Swaminathan /* Build CMD_RCV_SEQ64_CX */ 666482527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeFlags = 0; 666582527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.tus.f.bdeSize = seq_len; 666682527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrLow = PADDR_LO(seq_mp->phys); 666782527734SSukumar Swaminathan iocb->un.rcvseq64.rcvBde.addrHigh = PADDR_HI(seq_mp->phys); 666882527734SSukumar Swaminathan iocb->ULPBDECOUNT = 1; 666982527734SSukumar Swaminathan 667082527734SSukumar Swaminathan iocb->un.rcvseq64.xrsqRo = 0; 667182527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Rctl = fchdr.r_ctl; 667282527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Type = fchdr.type; 667382527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Dfctl = fchdr.df_ctl; 667482527734SSukumar Swaminathan iocb->un.rcvseq64.w5.hcsw.Fctl = fchdr.f_ctl; 667582527734SSukumar Swaminathan 667682527734SSukumar Swaminathan iocb->ULPPU = 0x3; 6677a9800bebSGarrett D'Amore iocb->ULPCONTEXT = xrip->XRI; 6678a9800bebSGarrett D'Amore iocb->ULPIOTAG = rpip->RPI; 667982527734SSukumar Swaminathan iocb->ULPCLASS = CLASS3; 668082527734SSukumar Swaminathan iocb->ULPCOMMAND = CMD_RCV_SEQ64_CX; 668182527734SSukumar Swaminathan 668282527734SSukumar Swaminathan iocb->unsli3.ext_rcv.seq_len = seq_len; 6683*8f23e9faSHans Rosenfeld iocb->unsli3.ext_rcv.vpi = port->vpip->VPI; 668482527734SSukumar Swaminathan 668582527734SSukumar Swaminathan if (fchdr.f_ctl & F_CTL_CHAINED_SEQ) { 668682527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccpe = 1; 668782527734SSukumar Swaminathan iocb->unsli3.ext_rcv.ccp = fchdr.rsvd; 668882527734SSukumar Swaminathan } 668982527734SSukumar Swaminathan 669082527734SSukumar Swaminathan (void) emlxs_ct_handle_unsol_req(port, iocbq->channel, 669182527734SSukumar Swaminathan iocbq, seq_mp, seq_len); 669282527734SSukumar Swaminathan 669382527734SSukumar Swaminathan break; 669482527734SSukumar Swaminathan } 669582527734SSukumar Swaminathan 669682527734SSukumar Swaminathan /* Sequence handled, no need to abort */ 669782527734SSukumar Swaminathan abort = 0; 669882527734SSukumar Swaminathan 669982527734SSukumar Swaminathan done: 670082527734SSukumar Swaminathan 670182527734SSukumar Swaminathan if (!posted) { 6702a9800bebSGarrett D'Amore emlxs_sli4_rq_post(port, hdr_rq->qid); 670382527734SSukumar Swaminathan } 670482527734SSukumar Swaminathan 670582527734SSukumar Swaminathan if (abort) { 670682527734SSukumar Swaminathan /* Send ABTS for this exchange */ 670782527734SSukumar Swaminathan /* !!! Currently, we have no implementation for this !!! */ 670882527734SSukumar Swaminathan abort = 0; 670982527734SSukumar Swaminathan } 671082527734SSukumar Swaminathan 671182527734SSukumar Swaminathan /* Return memory resources to pools */ 671282527734SSukumar Swaminathan if (iocbq) { 671382527734SSukumar Swaminathan if (iocbq->bp) { 6714a9800bebSGarrett D'Amore emlxs_mem_put(hba, buf_type, (void *)iocbq->bp); 6715*8f23e9faSHans Rosenfeld iocbq->bp = 0; 671682527734SSukumar Swaminathan } 671782527734SSukumar Swaminathan 6718a9800bebSGarrett D'Amore emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq); 671982527734SSukumar Swaminathan } 672082527734SSukumar Swaminathan 6721b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 6722b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 6723b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle) 6724b3660a96SSukumar Swaminathan != DDI_FM_OK) { 6725b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 6726b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 6727*8f23e9faSHans Rosenfeld "sli4_process_unsol_rcv: hdl=%p", 6728b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle); 6729b3660a96SSukumar Swaminathan 6730b3660a96SSukumar Swaminathan emlxs_thread_spawn(hba, emlxs_restart_thread, 6731a9800bebSGarrett D'Amore 0, 0); 6732b3660a96SSukumar Swaminathan } 6733b3660a96SSukumar Swaminathan #endif 673482527734SSukumar Swaminathan return; 673582527734SSukumar Swaminathan 673682527734SSukumar Swaminathan } /* emlxs_sli4_process_unsol_rcv() */ 673782527734SSukumar Swaminathan 673882527734SSukumar Swaminathan 673982527734SSukumar Swaminathan /*ARGSUSED*/ 674082527734SSukumar Swaminathan static void 674182527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(emlxs_hba_t *hba, CQ_DESC_t *cq, 674282527734SSukumar Swaminathan CQE_XRI_Abort_t *cqe) 674382527734SSukumar Swaminathan { 674482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 6745a9800bebSGarrett D'Amore XRIobj_t *xrip; 6746a9800bebSGarrett D'Amore 6747a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 674882527734SSukumar Swaminathan 6749*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_find_xri(port, cqe->XRI); 6750a9800bebSGarrett D'Amore if (xrip == NULL) { 6751*8f23e9faSHans Rosenfeld /* EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, */ 6752*8f23e9faSHans Rosenfeld /* "CQ ENTRY: process xri aborted ignored"); */ 6753a9800bebSGarrett D'Amore 6754a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 675582527734SSukumar Swaminathan return; 675682527734SSukumar Swaminathan } 675782527734SSukumar Swaminathan 675882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6759*8f23e9faSHans Rosenfeld "CQ ENTRY: XRI Aborted: xri=%d IA=%d EO=%d BR=%d", 676082527734SSukumar Swaminathan cqe->XRI, cqe->IA, cqe->EO, cqe->BR); 676182527734SSukumar Swaminathan 6762*8f23e9faSHans Rosenfeld if (!(xrip->flag & EMLXS_XRI_BUSY)) { 676382527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6764*8f23e9faSHans Rosenfeld "CQ ENTRY: XRI Aborted: xri=%d flag=%x. Bad state.", 6765*8f23e9faSHans Rosenfeld xrip->XRI, xrip->flag); 6766a9800bebSGarrett D'Amore 6767a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 676882527734SSukumar Swaminathan return; 676982527734SSukumar Swaminathan } 677082527734SSukumar Swaminathan 677182527734SSukumar Swaminathan /* Exchange is no longer busy on-chip, free it */ 6772*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(port, 0, xrip, 0); 6773a9800bebSGarrett D'Amore 6774a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 6775a9800bebSGarrett D'Amore 6776a9800bebSGarrett D'Amore return; 677782527734SSukumar Swaminathan 677882527734SSukumar Swaminathan } /* emlxs_sli4_process_xri_aborted () */ 677982527734SSukumar Swaminathan 678082527734SSukumar Swaminathan 678182527734SSukumar Swaminathan /*ARGSUSED*/ 678282527734SSukumar Swaminathan static void 678382527734SSukumar Swaminathan emlxs_sli4_process_cq(emlxs_hba_t *hba, CQ_DESC_t *cq) 678482527734SSukumar Swaminathan { 678582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 678682527734SSukumar Swaminathan CQE_u *cqe; 678782527734SSukumar Swaminathan CQE_u cq_entry; 678882527734SSukumar Swaminathan uint32_t cqdb; 678982527734SSukumar Swaminathan int num_entries = 0; 6790b3660a96SSukumar Swaminathan off_t offset; 679182527734SSukumar Swaminathan 679282527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 679382527734SSukumar Swaminathan 679482527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 679582527734SSukumar Swaminathan cqe += cq->host_index; 679682527734SSukumar Swaminathan 6797b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 6798b3660a96SSukumar Swaminathan cq->addr.virt) - 6799b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 6800b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 6801b3660a96SSukumar Swaminathan 6802b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(cq->addr.dma_handle, offset, 680382527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 680482527734SSukumar Swaminathan 680582527734SSukumar Swaminathan for (;;) { 680682527734SSukumar Swaminathan cq_entry.word[3] = BE_SWAP32(cqe->word[3]); 6807*8f23e9faSHans Rosenfeld if (!(cq_entry.word[3] & CQE_VALID)) { 680882527734SSukumar Swaminathan break; 6809*8f23e9faSHans Rosenfeld } 681082527734SSukumar Swaminathan 681182527734SSukumar Swaminathan cq_entry.word[2] = BE_SWAP32(cqe->word[2]); 681282527734SSukumar Swaminathan cq_entry.word[1] = BE_SWAP32(cqe->word[1]); 681382527734SSukumar Swaminathan cq_entry.word[0] = BE_SWAP32(cqe->word[0]); 681482527734SSukumar Swaminathan 6815*8f23e9faSHans Rosenfeld #ifdef DEBUG_CQE 6816*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "CQE", (uint32_t *)cqe, 6, 0); 6817*8f23e9faSHans Rosenfeld #endif /* DEBUG_CQE */ 681882527734SSukumar Swaminathan num_entries++; 681982527734SSukumar Swaminathan cqe->word[3] = 0; 682082527734SSukumar Swaminathan 682182527734SSukumar Swaminathan cq->host_index++; 682282527734SSukumar Swaminathan if (cq->host_index >= cq->max_index) { 682382527734SSukumar Swaminathan cq->host_index = 0; 682482527734SSukumar Swaminathan cqe = (CQE_u *)cq->addr.virt; 682582527734SSukumar Swaminathan } else { 682682527734SSukumar Swaminathan cqe++; 682782527734SSukumar Swaminathan } 682882527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 682982527734SSukumar Swaminathan 683082527734SSukumar Swaminathan /* Now handle specific cq type */ 683182527734SSukumar Swaminathan if (cq->type == EMLXS_CQ_TYPE_GROUP1) { 683282527734SSukumar Swaminathan if (cq_entry.cqAsyncEntry.async_evt) { 683382527734SSukumar Swaminathan emlxs_sli4_process_async_event(hba, 683482527734SSukumar Swaminathan (CQE_ASYNC_t *)&cq_entry); 683582527734SSukumar Swaminathan } else { 683682527734SSukumar Swaminathan emlxs_sli4_process_mbox_event(hba, 683782527734SSukumar Swaminathan (CQE_MBOX_t *)&cq_entry); 683882527734SSukumar Swaminathan } 683982527734SSukumar Swaminathan } else { /* EMLXS_CQ_TYPE_GROUP2 */ 684082527734SSukumar Swaminathan switch (cq_entry.cqCmplEntry.Code) { 684182527734SSukumar Swaminathan case CQE_TYPE_WQ_COMPLETION: 684282527734SSukumar Swaminathan if (cq_entry.cqCmplEntry.RequestTag < 684382527734SSukumar Swaminathan hba->max_iotag) { 684482527734SSukumar Swaminathan emlxs_sli4_process_wqe_cmpl(hba, cq, 684582527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 684682527734SSukumar Swaminathan } else { 684782527734SSukumar Swaminathan emlxs_sli4_process_oor_wqe_cmpl(hba, cq, 684882527734SSukumar Swaminathan (CQE_CmplWQ_t *)&cq_entry); 684982527734SSukumar Swaminathan } 685082527734SSukumar Swaminathan break; 685182527734SSukumar Swaminathan case CQE_TYPE_RELEASE_WQE: 685282527734SSukumar Swaminathan emlxs_sli4_process_release_wqe(hba, cq, 685382527734SSukumar Swaminathan (CQE_RelWQ_t *)&cq_entry); 685482527734SSukumar Swaminathan break; 685582527734SSukumar Swaminathan case CQE_TYPE_UNSOL_RCV: 6856*8f23e9faSHans Rosenfeld case CQE_TYPE_UNSOL_RCV_V1: 685782527734SSukumar Swaminathan emlxs_sli4_process_unsol_rcv(hba, cq, 685882527734SSukumar Swaminathan (CQE_UnsolRcv_t *)&cq_entry); 685982527734SSukumar Swaminathan break; 686082527734SSukumar Swaminathan case CQE_TYPE_XRI_ABORTED: 686182527734SSukumar Swaminathan emlxs_sli4_process_xri_aborted(hba, cq, 686282527734SSukumar Swaminathan (CQE_XRI_Abort_t *)&cq_entry); 686382527734SSukumar Swaminathan break; 686482527734SSukumar Swaminathan default: 686582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 686682527734SSukumar Swaminathan "Invalid CQ entry %d: %08x %08x %08x %08x", 686782527734SSukumar Swaminathan cq_entry.cqCmplEntry.Code, cq_entry.word[0], 686882527734SSukumar Swaminathan cq_entry.word[1], cq_entry.word[2], 686982527734SSukumar Swaminathan cq_entry.word[3]); 687082527734SSukumar Swaminathan break; 687182527734SSukumar Swaminathan } 687282527734SSukumar Swaminathan } 687382527734SSukumar Swaminathan 687482527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 687582527734SSukumar Swaminathan } 687682527734SSukumar Swaminathan 6877*8f23e9faSHans Rosenfeld /* Number of times this routine gets called for this CQ */ 6878*8f23e9faSHans Rosenfeld cq->isr_count++; 6879*8f23e9faSHans Rosenfeld 6880*8f23e9faSHans Rosenfeld /* num_entries is the number of CQEs we process in this specific CQ */ 6881*8f23e9faSHans Rosenfeld cq->num_proc += num_entries; 6882*8f23e9faSHans Rosenfeld if (cq->max_proc < num_entries) 6883*8f23e9faSHans Rosenfeld cq->max_proc = num_entries; 6884*8f23e9faSHans Rosenfeld 688582527734SSukumar Swaminathan cqdb = cq->qid; 688682527734SSukumar Swaminathan cqdb |= CQ_DB_REARM; 688782527734SSukumar Swaminathan if (num_entries != 0) { 688882527734SSukumar Swaminathan cqdb |= ((num_entries << CQ_DB_POP_SHIFT) & CQ_DB_POP_MASK); 688982527734SSukumar Swaminathan } 689082527734SSukumar Swaminathan 6891*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 689282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6893*8f23e9faSHans Rosenfeld "CQE: CLEAR cqdb=%08x: pops=%d", cqdb, num_entries); 6894*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 689582527734SSukumar Swaminathan 6896*8f23e9faSHans Rosenfeld emlxs_sli4_write_cqdb(hba, cqdb); 689782527734SSukumar Swaminathan 689882527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 689982527734SSukumar Swaminathan 690082527734SSukumar Swaminathan } /* emlxs_sli4_process_cq() */ 690182527734SSukumar Swaminathan 690282527734SSukumar Swaminathan 690382527734SSukumar Swaminathan /*ARGSUSED*/ 690482527734SSukumar Swaminathan static void 690582527734SSukumar Swaminathan emlxs_sli4_process_eq(emlxs_hba_t *hba, EQ_DESC_t *eq) 690682527734SSukumar Swaminathan { 690782527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 690882527734SSukumar Swaminathan uint32_t eqdb; 690982527734SSukumar Swaminathan uint32_t *ptr; 691082527734SSukumar Swaminathan CHANNEL *cp; 691182527734SSukumar Swaminathan EQE_u eqe; 691282527734SSukumar Swaminathan uint32_t i; 6913*8f23e9faSHans Rosenfeld uint16_t cqi; 691482527734SSukumar Swaminathan int num_entries = 0; 6915b3660a96SSukumar Swaminathan off_t offset; 691682527734SSukumar Swaminathan 691782527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when entering this routine */ 691882527734SSukumar Swaminathan 6919*8f23e9faSHans Rosenfeld hba->intr_busy_cnt ++; 6920*8f23e9faSHans Rosenfeld 692182527734SSukumar Swaminathan ptr = eq->addr.virt; 692282527734SSukumar Swaminathan ptr += eq->host_index; 692382527734SSukumar Swaminathan 6924b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 6925b3660a96SSukumar Swaminathan eq->addr.virt) - 6926b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 6927b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 6928b3660a96SSukumar Swaminathan 6929b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(eq->addr.dma_handle, offset, 693082527734SSukumar Swaminathan 4096, DDI_DMA_SYNC_FORKERNEL); 693182527734SSukumar Swaminathan 693282527734SSukumar Swaminathan for (;;) { 693382527734SSukumar Swaminathan eqe.word = *ptr; 693482527734SSukumar Swaminathan eqe.word = BE_SWAP32(eqe.word); 693582527734SSukumar Swaminathan 6936*8f23e9faSHans Rosenfeld if (!(eqe.word & EQE_VALID)) { 693782527734SSukumar Swaminathan break; 6938*8f23e9faSHans Rosenfeld } 693982527734SSukumar Swaminathan 6940*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 694182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6942*8f23e9faSHans Rosenfeld "EQE00: %08x", eqe.word); 6943*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 694482527734SSukumar Swaminathan 694582527734SSukumar Swaminathan *ptr = 0; 694682527734SSukumar Swaminathan num_entries++; 694782527734SSukumar Swaminathan eq->host_index++; 694882527734SSukumar Swaminathan if (eq->host_index >= eq->max_index) { 694982527734SSukumar Swaminathan eq->host_index = 0; 695082527734SSukumar Swaminathan ptr = eq->addr.virt; 695182527734SSukumar Swaminathan } else { 695282527734SSukumar Swaminathan ptr++; 695382527734SSukumar Swaminathan } 695482527734SSukumar Swaminathan 6955*8f23e9faSHans Rosenfeld cqi = emlxs_sli4_cqid_to_index(hba, eqe.entry.CQId); 6956*8f23e9faSHans Rosenfeld 6957*8f23e9faSHans Rosenfeld /* Verify CQ index */ 6958*8f23e9faSHans Rosenfeld if (cqi == 0xffff) { 6959*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 6960*8f23e9faSHans Rosenfeld "EQE: Invalid CQid: %d. Dropping...", 6961*8f23e9faSHans Rosenfeld eqe.entry.CQId); 6962*8f23e9faSHans Rosenfeld continue; 6963*8f23e9faSHans Rosenfeld } 696482527734SSukumar Swaminathan 6965*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 696682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6967*8f23e9faSHans Rosenfeld "EQE: CQIndex:%x cqid:%x", cqi, eqe.entry.CQId); 6968*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 6969*8f23e9faSHans Rosenfeld 6970*8f23e9faSHans Rosenfeld emlxs_sli4_process_cq(hba, &hba->sli.sli4.cq[cqi]); 6971*8f23e9faSHans Rosenfeld } 697282527734SSukumar Swaminathan 6973*8f23e9faSHans Rosenfeld /* Number of times the ISR for this EQ gets called */ 6974*8f23e9faSHans Rosenfeld eq->isr_count++; 6975*8f23e9faSHans Rosenfeld 6976*8f23e9faSHans Rosenfeld /* num_entries is the number of EQEs we process in this specific ISR */ 6977*8f23e9faSHans Rosenfeld eq->num_proc += num_entries; 6978*8f23e9faSHans Rosenfeld if (eq->max_proc < num_entries) { 6979*8f23e9faSHans Rosenfeld eq->max_proc = num_entries; 698082527734SSukumar Swaminathan } 698182527734SSukumar Swaminathan 698282527734SSukumar Swaminathan eqdb = eq->qid; 698382527734SSukumar Swaminathan eqdb |= (EQ_DB_CLEAR | EQ_DB_EVENT | EQ_DB_REARM); 698482527734SSukumar Swaminathan 6985*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 698682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 6987*8f23e9faSHans Rosenfeld "EQE: CLEAR eqdb=%08x pops=%d", eqdb, num_entries); 6988*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 698982527734SSukumar Swaminathan 699082527734SSukumar Swaminathan if (num_entries != 0) { 699182527734SSukumar Swaminathan eqdb |= ((num_entries << EQ_DB_POP_SHIFT) & EQ_DB_POP_MASK); 699282527734SSukumar Swaminathan for (i = 0; i < hba->chan_count; i++) { 699382527734SSukumar Swaminathan cp = &hba->chan[i]; 699482527734SSukumar Swaminathan if (cp->chan_flag & EMLXS_NEEDS_TRIGGER) { 699582527734SSukumar Swaminathan cp->chan_flag &= ~EMLXS_NEEDS_TRIGGER; 699682527734SSukumar Swaminathan emlxs_thread_trigger2(&cp->intr_thread, 699782527734SSukumar Swaminathan emlxs_proc_channel, cp); 699882527734SSukumar Swaminathan } 699982527734SSukumar Swaminathan } 700082527734SSukumar Swaminathan } 700182527734SSukumar Swaminathan 7002*8f23e9faSHans Rosenfeld emlxs_sli4_write_cqdb(hba, eqdb); 700382527734SSukumar Swaminathan 700482527734SSukumar Swaminathan /* EMLXS_PORT_LOCK must be held when exiting this routine */ 700582527734SSukumar Swaminathan 7006*8f23e9faSHans Rosenfeld hba->intr_busy_cnt --; 7007*8f23e9faSHans Rosenfeld 700882527734SSukumar Swaminathan } /* emlxs_sli4_process_eq() */ 700982527734SSukumar Swaminathan 701082527734SSukumar Swaminathan 701182527734SSukumar Swaminathan #ifdef MSI_SUPPORT 701282527734SSukumar Swaminathan /*ARGSUSED*/ 701382527734SSukumar Swaminathan static uint32_t 701482527734SSukumar Swaminathan emlxs_sli4_msi_intr(char *arg1, char *arg2) 701582527734SSukumar Swaminathan { 701682527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg1; 7017*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 701882527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 7019*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 702082527734SSukumar Swaminathan uint16_t msgid; 702182527734SSukumar Swaminathan int rc; 702282527734SSukumar Swaminathan 7023*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 702482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 702582527734SSukumar Swaminathan "msiINTR arg1:%p arg2:%p", arg1, arg2); 7026*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 702782527734SSukumar Swaminathan 702882527734SSukumar Swaminathan /* Check for legacy interrupt handling */ 702982527734SSukumar Swaminathan if (hba->intr_type == DDI_INTR_TYPE_FIXED) { 703082527734SSukumar Swaminathan rc = emlxs_sli4_intx_intr(arg1); 703182527734SSukumar Swaminathan return (rc); 703282527734SSukumar Swaminathan } 703382527734SSukumar Swaminathan 703482527734SSukumar Swaminathan /* Get MSI message id */ 703582527734SSukumar Swaminathan msgid = (uint16_t)((unsigned long)arg2); 703682527734SSukumar Swaminathan 703782527734SSukumar Swaminathan /* Validate the message id */ 703882527734SSukumar Swaminathan if (msgid >= hba->intr_count) { 703982527734SSukumar Swaminathan msgid = 0; 704082527734SSukumar Swaminathan } 704182527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 704282527734SSukumar Swaminathan 7043bce54adfSSukumar Swaminathan if ((hba->state == FC_KILLED) || (hba->flag & FC_OFFLINE_MODE)) { 704482527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 704582527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 704682527734SSukumar Swaminathan } 704782527734SSukumar Swaminathan 704882527734SSukumar Swaminathan /* The eq[] index == the MSI vector number */ 704982527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[msgid]); 705082527734SSukumar Swaminathan 705182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 705282527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 705382527734SSukumar Swaminathan 705482527734SSukumar Swaminathan } /* emlxs_sli4_msi_intr() */ 705582527734SSukumar Swaminathan #endif /* MSI_SUPPORT */ 705682527734SSukumar Swaminathan 705782527734SSukumar Swaminathan 705882527734SSukumar Swaminathan /*ARGSUSED*/ 705982527734SSukumar Swaminathan static int 706082527734SSukumar Swaminathan emlxs_sli4_intx_intr(char *arg) 706182527734SSukumar Swaminathan { 706282527734SSukumar Swaminathan emlxs_hba_t *hba = (emlxs_hba_t *)arg; 7063*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 706482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 7065*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 706682527734SSukumar Swaminathan 7067*8f23e9faSHans Rosenfeld #ifdef DEBUG_FASTPATH 706882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 706982527734SSukumar Swaminathan "intxINTR arg:%p", arg); 7070*8f23e9faSHans Rosenfeld #endif /* DEBUG_FASTPATH */ 707182527734SSukumar Swaminathan 707282527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 707382527734SSukumar Swaminathan 7074bce54adfSSukumar Swaminathan if ((hba->state == FC_KILLED) || (hba->flag & FC_OFFLINE_MODE)) { 707582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 707682527734SSukumar Swaminathan return (DDI_INTR_UNCLAIMED); 707782527734SSukumar Swaminathan } 707882527734SSukumar Swaminathan 707982527734SSukumar Swaminathan emlxs_sli4_process_eq(hba, &hba->sli.sli4.eq[0]); 708082527734SSukumar Swaminathan 708182527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 708282527734SSukumar Swaminathan return (DDI_INTR_CLAIMED); 708382527734SSukumar Swaminathan } /* emlxs_sli4_intx_intr() */ 708482527734SSukumar Swaminathan 708582527734SSukumar Swaminathan 708682527734SSukumar Swaminathan static void 708782527734SSukumar Swaminathan emlxs_sli4_hba_kill(emlxs_hba_t *hba) 708882527734SSukumar Swaminathan { 708982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 709082527734SSukumar Swaminathan uint32_t j; 709182527734SSukumar Swaminathan 709282527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 709382527734SSukumar Swaminathan if (hba->flag & FC_INTERLOCKED) { 709482527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 709582527734SSukumar Swaminathan 709682527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 709782527734SSukumar Swaminathan 709882527734SSukumar Swaminathan return; 709982527734SSukumar Swaminathan } 710082527734SSukumar Swaminathan 710182527734SSukumar Swaminathan j = 0; 710282527734SSukumar Swaminathan while (j++ < 10000) { 7103*8f23e9faSHans Rosenfeld if ((hba->mbox_queue_flag == 0) && 7104*8f23e9faSHans Rosenfeld (hba->intr_busy_cnt == 0)) { 710582527734SSukumar Swaminathan break; 710682527734SSukumar Swaminathan } 710782527734SSukumar Swaminathan 710882527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 7109*8f23e9faSHans Rosenfeld BUSYWAIT_US(100); 711082527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 711182527734SSukumar Swaminathan } 711282527734SSukumar Swaminathan 7113*8f23e9faSHans Rosenfeld if ((hba->mbox_queue_flag != 0) || (hba->intr_busy_cnt > 0)) { 711482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 7115*8f23e9faSHans Rosenfeld "Board kill failed. Adapter busy, %d, %d.", 7116*8f23e9faSHans Rosenfeld hba->mbox_queue_flag, hba->intr_busy_cnt); 711782527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 711882527734SSukumar Swaminathan return; 711982527734SSukumar Swaminathan } 712082527734SSukumar Swaminathan 712182527734SSukumar Swaminathan hba->flag |= FC_INTERLOCKED; 712282527734SSukumar Swaminathan 712382527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED); 712482527734SSukumar Swaminathan 712582527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 712682527734SSukumar Swaminathan 712782527734SSukumar Swaminathan } /* emlxs_sli4_hba_kill() */ 712882527734SSukumar Swaminathan 712982527734SSukumar Swaminathan 7130*8f23e9faSHans Rosenfeld extern void 7131*8f23e9faSHans Rosenfeld emlxs_sli4_hba_reset_all(emlxs_hba_t *hba, uint32_t flag) 7132*8f23e9faSHans Rosenfeld { 7133*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 7134*8f23e9faSHans Rosenfeld uint32_t value; 7135*8f23e9faSHans Rosenfeld 7136*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 7137*8f23e9faSHans Rosenfeld 7138*8f23e9faSHans Rosenfeld if ((hba->sli_intf & SLI_INTF_IF_TYPE_MASK) != SLI_INTF_IF_TYPE_2) { 7139*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 7140*8f23e9faSHans Rosenfeld "Reset All failed. Invalid Operation."); 7141*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 7142*8f23e9faSHans Rosenfeld return; 7143*8f23e9faSHans Rosenfeld } 7144*8f23e9faSHans Rosenfeld 7145*8f23e9faSHans Rosenfeld /* Issue a Firmware Reset All Request */ 7146*8f23e9faSHans Rosenfeld if (flag) { 7147*8f23e9faSHans Rosenfeld value = SLI_PHYDEV_FRST | SLI_PHYDEV_FRL_ALL | SLI_PHYDEV_DD; 7148*8f23e9faSHans Rosenfeld } else { 7149*8f23e9faSHans Rosenfeld value = SLI_PHYDEV_FRST | SLI_PHYDEV_FRL_ALL; 7150*8f23e9faSHans Rosenfeld } 7151*8f23e9faSHans Rosenfeld 7152*8f23e9faSHans Rosenfeld ddi_put32(hba->sli.sli4.bar0_acc_handle, 7153*8f23e9faSHans Rosenfeld hba->sli.sli4.PHYSDEV_reg_addr, value); 7154*8f23e9faSHans Rosenfeld 7155*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 7156*8f23e9faSHans Rosenfeld 7157*8f23e9faSHans Rosenfeld } /* emlxs_sli4_hba_reset_all() */ 7158*8f23e9faSHans Rosenfeld 7159*8f23e9faSHans Rosenfeld 716082527734SSukumar Swaminathan static void 716182527734SSukumar Swaminathan emlxs_sli4_enable_intr(emlxs_hba_t *hba) 716282527734SSukumar Swaminathan { 716382527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 716482527734SSukumar Swaminathan int i; 716582527734SSukumar Swaminathan int num_cq; 716682527734SSukumar Swaminathan uint32_t data; 716782527734SSukumar Swaminathan 716882527734SSukumar Swaminathan hba->sli.sli4.flag |= EMLXS_SLI4_INTR_ENABLED; 716982527734SSukumar Swaminathan 717082527734SSukumar Swaminathan num_cq = (hba->intr_count * cfg[CFG_NUM_WQ].current) + 717182527734SSukumar Swaminathan EMLXS_CQ_OFFSET_WQ; 717282527734SSukumar Swaminathan 717382527734SSukumar Swaminathan /* ARM EQ / CQs */ 717482527734SSukumar Swaminathan for (i = 0; i < num_cq; i++) { 717582527734SSukumar Swaminathan data = hba->sli.sli4.cq[i].qid; 717682527734SSukumar Swaminathan data |= CQ_DB_REARM; 7177*8f23e9faSHans Rosenfeld emlxs_sli4_write_cqdb(hba, data); 717882527734SSukumar Swaminathan } 717982527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 718082527734SSukumar Swaminathan data = hba->sli.sli4.eq[i].qid; 718182527734SSukumar Swaminathan data |= (EQ_DB_REARM | EQ_DB_EVENT); 7182*8f23e9faSHans Rosenfeld emlxs_sli4_write_cqdb(hba, data); 718382527734SSukumar Swaminathan } 718482527734SSukumar Swaminathan } /* emlxs_sli4_enable_intr() */ 718582527734SSukumar Swaminathan 718682527734SSukumar Swaminathan 718782527734SSukumar Swaminathan static void 718882527734SSukumar Swaminathan emlxs_sli4_disable_intr(emlxs_hba_t *hba, uint32_t att) 718982527734SSukumar Swaminathan { 719082527734SSukumar Swaminathan if (att) { 719182527734SSukumar Swaminathan return; 719282527734SSukumar Swaminathan } 719382527734SSukumar Swaminathan 719482527734SSukumar Swaminathan hba->sli.sli4.flag &= ~EMLXS_SLI4_INTR_ENABLED; 719582527734SSukumar Swaminathan 719682527734SSukumar Swaminathan /* Short of reset, we cannot disable interrupts */ 719782527734SSukumar Swaminathan } /* emlxs_sli4_disable_intr() */ 719882527734SSukumar Swaminathan 719982527734SSukumar Swaminathan 720082527734SSukumar Swaminathan static void 720182527734SSukumar Swaminathan emlxs_sli4_resource_free(emlxs_hba_t *hba) 720282527734SSukumar Swaminathan { 720382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 720482527734SSukumar Swaminathan MBUF_INFO *buf_info; 720582527734SSukumar Swaminathan uint32_t i; 720682527734SSukumar Swaminathan 7207*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.slim2; 7208*8f23e9faSHans Rosenfeld if (buf_info->virt == 0) { 7209*8f23e9faSHans Rosenfeld /* Already free */ 7210*8f23e9faSHans Rosenfeld return; 7211*8f23e9faSHans Rosenfeld } 7212*8f23e9faSHans Rosenfeld 7213a9800bebSGarrett D'Amore emlxs_fcf_fini(hba); 721482527734SSukumar Swaminathan 721582527734SSukumar Swaminathan buf_info = &hba->sli.sli4.HeaderTmplate; 721682527734SSukumar Swaminathan if (buf_info->virt) { 721782527734SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 721882527734SSukumar Swaminathan } 721982527734SSukumar Swaminathan 722082527734SSukumar Swaminathan if (hba->sli.sli4.XRIp) { 722182527734SSukumar Swaminathan if ((hba->sli.sli4.XRIinuse_f != 722282527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) || 722382527734SSukumar Swaminathan (hba->sli.sli4.XRIinuse_b != 722482527734SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIinuse_f)) { 7225a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 7226*8f23e9faSHans Rosenfeld "XRIs in use during free!: %p %p != %p\n", 722782527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_f, 722882527734SSukumar Swaminathan hba->sli.sli4.XRIinuse_b, 722982527734SSukumar Swaminathan &hba->sli.sli4.XRIinuse_f); 723082527734SSukumar Swaminathan } 723182527734SSukumar Swaminathan kmem_free(hba->sli.sli4.XRIp, 723282527734SSukumar Swaminathan (sizeof (XRIobj_t) * hba->sli.sli4.XRICount)); 723382527734SSukumar Swaminathan hba->sli.sli4.XRIp = NULL; 7234b3660a96SSukumar Swaminathan 7235b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_f = 7236b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 7237b3660a96SSukumar Swaminathan hba->sli.sli4.XRIfree_b = 7238b3660a96SSukumar Swaminathan (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 723982527734SSukumar Swaminathan hba->sli.sli4.xrif_count = 0; 724082527734SSukumar Swaminathan } 724182527734SSukumar Swaminathan 7242*8f23e9faSHans Rosenfeld for (i = 0; i < hba->intr_count; i++) { 7243b3660a96SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.eq[i].lastwq_lock); 724482527734SSukumar Swaminathan bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 7245*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].qid = 0xffff; 724682527734SSukumar Swaminathan } 724782527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_CQS; i++) { 724882527734SSukumar Swaminathan bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 7249*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].qid = 0xffff; 725082527734SSukumar Swaminathan } 725182527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_WQS; i++) { 725282527734SSukumar Swaminathan bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 7253*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].qid = 0xffff; 725482527734SSukumar Swaminathan } 7255*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_RXQS; i++) { 7256b3660a96SSukumar Swaminathan mutex_destroy(&hba->sli.sli4.rxq[i].lock); 7257b3660a96SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 7258*8f23e9faSHans Rosenfeld } 7259*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_RQS; i++) { 7260*8f23e9faSHans Rosenfeld mutex_destroy(&hba->sli.sli4.rq[i].lock); 726182527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 7262*8f23e9faSHans Rosenfeld hba->sli.sli4.rq[i].qid = 0xffff; 726382527734SSukumar Swaminathan } 726482527734SSukumar Swaminathan 726582527734SSukumar Swaminathan /* Free the MQ */ 7266b3660a96SSukumar Swaminathan bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 7267b3660a96SSukumar Swaminathan 7268b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.slim2; 7269b3660a96SSukumar Swaminathan if (buf_info->virt) { 727082527734SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA; 727182527734SSukumar Swaminathan emlxs_mem_free(hba, buf_info); 7272b3660a96SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 727382527734SSukumar Swaminathan } 727482527734SSukumar Swaminathan 727582527734SSukumar Swaminathan } /* emlxs_sli4_resource_free() */ 727682527734SSukumar Swaminathan 727782527734SSukumar Swaminathan 727882527734SSukumar Swaminathan static int 727982527734SSukumar Swaminathan emlxs_sli4_resource_alloc(emlxs_hba_t *hba) 728082527734SSukumar Swaminathan { 728182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 728282527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 728382527734SSukumar Swaminathan MBUF_INFO *buf_info; 728482527734SSukumar Swaminathan int num_eq; 728582527734SSukumar Swaminathan int num_wq; 7286a9800bebSGarrett D'Amore uint16_t i; 728782527734SSukumar Swaminathan uint32_t j; 728882527734SSukumar Swaminathan uint32_t k; 7289*8f23e9faSHans Rosenfeld uint16_t cq_depth; 7290*8f23e9faSHans Rosenfeld uint32_t cq_size; 729182527734SSukumar Swaminathan uint32_t word; 7292a9800bebSGarrett D'Amore XRIobj_t *xrip; 729382527734SSukumar Swaminathan RQE_t *rqe; 7294b3660a96SSukumar Swaminathan MBUF_INFO *rqb; 7295b3660a96SSukumar Swaminathan uint64_t phys; 7296b3660a96SSukumar Swaminathan uint64_t tmp_phys; 7297b3660a96SSukumar Swaminathan char *virt; 7298b3660a96SSukumar Swaminathan char *tmp_virt; 7299b3660a96SSukumar Swaminathan void *data_handle; 7300b3660a96SSukumar Swaminathan void *dma_handle; 7301b3660a96SSukumar Swaminathan int32_t size; 7302b3660a96SSukumar Swaminathan off_t offset; 7303b3660a96SSukumar Swaminathan uint32_t count = 0; 7304*8f23e9faSHans Rosenfeld uint32_t hddr_size = 0; 7305*8f23e9faSHans Rosenfeld uint32_t align; 7306*8f23e9faSHans Rosenfeld uint32_t iotag; 7307*8f23e9faSHans Rosenfeld 7308*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.slim2; 7309*8f23e9faSHans Rosenfeld if (buf_info->virt) { 7310*8f23e9faSHans Rosenfeld /* Already allocated */ 7311*8f23e9faSHans Rosenfeld return (0); 7312*8f23e9faSHans Rosenfeld } 731382527734SSukumar Swaminathan 7314a9800bebSGarrett D'Amore emlxs_fcf_init(hba); 731582527734SSukumar Swaminathan 7316*8f23e9faSHans Rosenfeld switch (hba->sli.sli4.param.CQV) { 7317*8f23e9faSHans Rosenfeld case 0: 7318*8f23e9faSHans Rosenfeld cq_depth = CQ_DEPTH; 7319*8f23e9faSHans Rosenfeld break; 7320*8f23e9faSHans Rosenfeld case 2: 7321*8f23e9faSHans Rosenfeld default: 7322*8f23e9faSHans Rosenfeld cq_depth = CQ_DEPTH_V2; 7323*8f23e9faSHans Rosenfeld break; 7324*8f23e9faSHans Rosenfeld } 7325*8f23e9faSHans Rosenfeld cq_size = (cq_depth * CQE_SIZE); 7326*8f23e9faSHans Rosenfeld 7327b3660a96SSukumar Swaminathan /* EQs - 1 per Interrupt vector */ 7328b3660a96SSukumar Swaminathan num_eq = hba->intr_count; 7329*8f23e9faSHans Rosenfeld 7330b3660a96SSukumar Swaminathan /* CQs - number of WQs + 1 for RQs + 1 for mbox/async events */ 7331b3660a96SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current * num_eq; 733282527734SSukumar Swaminathan 7333b3660a96SSukumar Swaminathan /* Calculate total dmable memory we need */ 7334*8f23e9faSHans Rosenfeld /* WARNING: make sure each section is aligned on 4K boundary */ 7335*8f23e9faSHans Rosenfeld 7336b3660a96SSukumar Swaminathan /* EQ */ 7337b3660a96SSukumar Swaminathan count += num_eq * 4096; 7338*8f23e9faSHans Rosenfeld 7339b3660a96SSukumar Swaminathan /* CQ */ 7340*8f23e9faSHans Rosenfeld count += (num_wq + EMLXS_CQ_OFFSET_WQ) * cq_size; 7341*8f23e9faSHans Rosenfeld 7342b3660a96SSukumar Swaminathan /* WQ */ 7343b3660a96SSukumar Swaminathan count += num_wq * (4096 * EMLXS_NUM_WQ_PAGES); 7344*8f23e9faSHans Rosenfeld 7345b3660a96SSukumar Swaminathan /* MQ */ 7346b3660a96SSukumar Swaminathan count += EMLXS_MAX_MQS * 4096; 7347*8f23e9faSHans Rosenfeld 7348b3660a96SSukumar Swaminathan /* RQ */ 7349b3660a96SSukumar Swaminathan count += EMLXS_MAX_RQS * 4096; 7350*8f23e9faSHans Rosenfeld 7351b3660a96SSukumar Swaminathan /* RQB/E */ 7352b3660a96SSukumar Swaminathan count += RQB_COUNT * (RQB_DATA_SIZE + RQB_HEADER_SIZE); 7353*8f23e9faSHans Rosenfeld count += (4096 - (count%4096)); /* Ensure 4K alignment */ 7354*8f23e9faSHans Rosenfeld 7355b3660a96SSukumar Swaminathan /* SGL */ 7356*8f23e9faSHans Rosenfeld count += hba->sli.sli4.XRIExtSize * hba->sli.sli4.mem_sgl_size; 7357*8f23e9faSHans Rosenfeld count += (4096 - (count%4096)); /* Ensure 4K alignment */ 7358*8f23e9faSHans Rosenfeld 7359*8f23e9faSHans Rosenfeld /* RPI Header Templates */ 7360*8f23e9faSHans Rosenfeld if (hba->sli.sli4.param.HDRR) { 7361*8f23e9faSHans Rosenfeld /* Bytes per extent */ 7362*8f23e9faSHans Rosenfeld j = hba->sli.sli4.RPIExtSize * sizeof (RPIHdrTmplate_t); 7363*8f23e9faSHans Rosenfeld 7364*8f23e9faSHans Rosenfeld /* Pages required per extent (page == 4096 bytes) */ 7365*8f23e9faSHans Rosenfeld k = (j/4096) + ((j%4096)? 1:0); 7366*8f23e9faSHans Rosenfeld 7367*8f23e9faSHans Rosenfeld /* Total size */ 7368*8f23e9faSHans Rosenfeld hddr_size = (k * hba->sli.sli4.RPIExtCount * 4096); 7369*8f23e9faSHans Rosenfeld 7370*8f23e9faSHans Rosenfeld count += hddr_size; 7371*8f23e9faSHans Rosenfeld } 7372b3660a96SSukumar Swaminathan 7373b3660a96SSukumar Swaminathan /* Allocate slim2 for SLI4 */ 7374b3660a96SSukumar Swaminathan buf_info = &hba->sli.sli4.slim2; 7375b3660a96SSukumar Swaminathan buf_info->size = count; 7376b3660a96SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7377b3660a96SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 7378b3660a96SSukumar Swaminathan 7379b3660a96SSukumar Swaminathan (void) emlxs_mem_alloc(hba, buf_info); 738082527734SSukumar Swaminathan 7381b3660a96SSukumar Swaminathan if (buf_info->virt == NULL) { 7382b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 7383b3660a96SSukumar Swaminathan &emlxs_init_failed_msg, 7384b3660a96SSukumar Swaminathan "Unable to allocate internal memory for SLI4: %d", 7385b3660a96SSukumar Swaminathan count); 7386b3660a96SSukumar Swaminathan goto failed; 738782527734SSukumar Swaminathan } 7388b3660a96SSukumar Swaminathan bzero(buf_info->virt, buf_info->size); 7389b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(buf_info->dma_handle, 0, 7390b3660a96SSukumar Swaminathan buf_info->size, DDI_DMA_SYNC_FORDEV); 739182527734SSukumar Swaminathan 7392b3660a96SSukumar Swaminathan /* Assign memory to SGL, Head Template, EQ, CQ, WQ, RQ and MQ */ 7393b3660a96SSukumar Swaminathan data_handle = buf_info->data_handle; 7394b3660a96SSukumar Swaminathan dma_handle = buf_info->dma_handle; 7395b3660a96SSukumar Swaminathan phys = buf_info->phys; 7396b3660a96SSukumar Swaminathan virt = (char *)buf_info->virt; 739782527734SSukumar Swaminathan 739882527734SSukumar Swaminathan /* Allocate space for queues */ 7399*8f23e9faSHans Rosenfeld 7400*8f23e9faSHans Rosenfeld /* EQ */ 7401b3660a96SSukumar Swaminathan size = 4096; 740282527734SSukumar Swaminathan for (i = 0; i < num_eq; i++) { 7403*8f23e9faSHans Rosenfeld bzero(&hba->sli.sli4.eq[i], sizeof (EQ_DESC_t)); 7404*8f23e9faSHans Rosenfeld 740582527734SSukumar Swaminathan buf_info = &hba->sli.sli4.eq[i].addr; 7406*8f23e9faSHans Rosenfeld buf_info->size = size; 7407*8f23e9faSHans Rosenfeld buf_info->flags = 7408*8f23e9faSHans Rosenfeld FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7409*8f23e9faSHans Rosenfeld buf_info->align = ddi_ptob(hba->dip, 1L); 7410*8f23e9faSHans Rosenfeld buf_info->phys = phys; 7411*8f23e9faSHans Rosenfeld buf_info->virt = (void *)virt; 7412*8f23e9faSHans Rosenfeld buf_info->data_handle = data_handle; 7413*8f23e9faSHans Rosenfeld buf_info->dma_handle = dma_handle; 741482527734SSukumar Swaminathan 7415*8f23e9faSHans Rosenfeld phys += size; 7416*8f23e9faSHans Rosenfeld virt += size; 741782527734SSukumar Swaminathan 7418*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].max_index = EQ_DEPTH; 7419*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].qid = 0xffff; 742082527734SSukumar Swaminathan 7421*8f23e9faSHans Rosenfeld mutex_init(&hba->sli.sli4.eq[i].lastwq_lock, NULL, 742282527734SSukumar Swaminathan MUTEX_DRIVER, NULL); 742382527734SSukumar Swaminathan } 7424b3660a96SSukumar Swaminathan 7425*8f23e9faSHans Rosenfeld 7426*8f23e9faSHans Rosenfeld /* CQ */ 742782527734SSukumar Swaminathan for (i = 0; i < (num_wq + EMLXS_CQ_OFFSET_WQ); i++) { 7428*8f23e9faSHans Rosenfeld bzero(&hba->sli.sli4.cq[i], sizeof (CQ_DESC_t)); 7429*8f23e9faSHans Rosenfeld 743082527734SSukumar Swaminathan buf_info = &hba->sli.sli4.cq[i].addr; 7431*8f23e9faSHans Rosenfeld buf_info->size = cq_size; 7432*8f23e9faSHans Rosenfeld buf_info->flags = 7433*8f23e9faSHans Rosenfeld FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7434*8f23e9faSHans Rosenfeld buf_info->align = ddi_ptob(hba->dip, 1L); 7435*8f23e9faSHans Rosenfeld buf_info->phys = phys; 7436*8f23e9faSHans Rosenfeld buf_info->virt = (void *)virt; 7437*8f23e9faSHans Rosenfeld buf_info->data_handle = data_handle; 7438*8f23e9faSHans Rosenfeld buf_info->dma_handle = dma_handle; 743982527734SSukumar Swaminathan 7440*8f23e9faSHans Rosenfeld phys += cq_size; 7441*8f23e9faSHans Rosenfeld virt += cq_size; 744282527734SSukumar Swaminathan 7443*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].max_index = cq_depth; 7444*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].qid = 0xffff; 744582527734SSukumar Swaminathan } 7446b3660a96SSukumar Swaminathan 7447*8f23e9faSHans Rosenfeld 7448*8f23e9faSHans Rosenfeld /* WQ */ 7449b3660a96SSukumar Swaminathan size = 4096 * EMLXS_NUM_WQ_PAGES; 745082527734SSukumar Swaminathan for (i = 0; i < num_wq; i++) { 7451*8f23e9faSHans Rosenfeld bzero(&hba->sli.sli4.wq[i], sizeof (WQ_DESC_t)); 745282527734SSukumar Swaminathan 7453*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.wq[i].addr; 7454b3660a96SSukumar Swaminathan buf_info->size = size; 7455b3660a96SSukumar Swaminathan buf_info->flags = 7456b3660a96SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7457b3660a96SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 7458b3660a96SSukumar Swaminathan buf_info->phys = phys; 7459a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 7460b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 7461b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 7462b3660a96SSukumar Swaminathan 7463b3660a96SSukumar Swaminathan phys += size; 7464b3660a96SSukumar Swaminathan virt += size; 7465b3660a96SSukumar Swaminathan 7466*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].max_index = WQ_DEPTH; 7467*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].release_depth = WQE_RELEASE_DEPTH; 7468*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].qid = 0xFFFF; 7469b3660a96SSukumar Swaminathan } 7470b3660a96SSukumar Swaminathan 7471*8f23e9faSHans Rosenfeld 7472*8f23e9faSHans Rosenfeld /* MQ */ 7473*8f23e9faSHans Rosenfeld size = 4096; 7474*8f23e9faSHans Rosenfeld bzero(&hba->sli.sli4.mq, sizeof (MQ_DESC_t)); 7475*8f23e9faSHans Rosenfeld 7476*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.mq.addr; 7477*8f23e9faSHans Rosenfeld buf_info->size = size; 7478*8f23e9faSHans Rosenfeld buf_info->flags = 7479*8f23e9faSHans Rosenfeld FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7480*8f23e9faSHans Rosenfeld buf_info->align = ddi_ptob(hba->dip, 1L); 7481*8f23e9faSHans Rosenfeld buf_info->phys = phys; 7482*8f23e9faSHans Rosenfeld buf_info->virt = (void *)virt; 7483*8f23e9faSHans Rosenfeld buf_info->data_handle = data_handle; 7484*8f23e9faSHans Rosenfeld buf_info->dma_handle = dma_handle; 7485*8f23e9faSHans Rosenfeld 7486*8f23e9faSHans Rosenfeld phys += size; 7487*8f23e9faSHans Rosenfeld virt += size; 7488*8f23e9faSHans Rosenfeld 7489*8f23e9faSHans Rosenfeld hba->sli.sli4.mq.max_index = MQ_DEPTH; 7490*8f23e9faSHans Rosenfeld 7491*8f23e9faSHans Rosenfeld 7492*8f23e9faSHans Rosenfeld /* RXQ */ 749382527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RXQS; i++) { 749482527734SSukumar Swaminathan bzero(&hba->sli.sli4.rxq[i], sizeof (RXQ_DESC_t)); 749582527734SSukumar Swaminathan 7496*8f23e9faSHans Rosenfeld mutex_init(&hba->sli.sli4.rxq[i].lock, NULL, MUTEX_DRIVER, 7497*8f23e9faSHans Rosenfeld NULL); 749882527734SSukumar Swaminathan } 749982527734SSukumar Swaminathan 7500*8f23e9faSHans Rosenfeld 7501*8f23e9faSHans Rosenfeld /* RQ */ 7502b3660a96SSukumar Swaminathan size = 4096; 750382527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 750482527734SSukumar Swaminathan bzero(&hba->sli.sli4.rq[i], sizeof (RQ_DESC_t)); 7505*8f23e9faSHans Rosenfeld 7506*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.rq[i].addr; 7507b3660a96SSukumar Swaminathan buf_info->size = size; 750882527734SSukumar Swaminathan buf_info->flags = 750982527734SSukumar Swaminathan FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 751082527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 7511b3660a96SSukumar Swaminathan buf_info->phys = phys; 7512a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 7513b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 7514b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 751582527734SSukumar Swaminathan 7516b3660a96SSukumar Swaminathan phys += size; 7517b3660a96SSukumar Swaminathan virt += size; 751882527734SSukumar Swaminathan 751982527734SSukumar Swaminathan hba->sli.sli4.rq[i].max_index = RQ_DEPTH; 7520*8f23e9faSHans Rosenfeld hba->sli.sli4.rq[i].qid = 0xFFFF; 752182527734SSukumar Swaminathan 7522*8f23e9faSHans Rosenfeld mutex_init(&hba->sli.sli4.rq[i].lock, NULL, MUTEX_DRIVER, NULL); 7523b3660a96SSukumar Swaminathan } 752482527734SSukumar Swaminathan 7525*8f23e9faSHans Rosenfeld 7526*8f23e9faSHans Rosenfeld /* RQB/E */ 7527*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_RQS; i++) { 7528b3660a96SSukumar Swaminathan size = (i & 0x1) ? RQB_DATA_SIZE : RQB_HEADER_SIZE; 7529b3660a96SSukumar Swaminathan tmp_phys = phys; 7530b3660a96SSukumar Swaminathan tmp_virt = virt; 753182527734SSukumar Swaminathan 753282527734SSukumar Swaminathan /* Initialize the RQEs */ 753382527734SSukumar Swaminathan rqe = (RQE_t *)hba->sli.sli4.rq[i].addr.virt; 753482527734SSukumar Swaminathan for (j = 0; j < (RQ_DEPTH/RQB_COUNT); j++) { 7535b3660a96SSukumar Swaminathan phys = tmp_phys; 7536b3660a96SSukumar Swaminathan virt = tmp_virt; 753782527734SSukumar Swaminathan for (k = 0; k < RQB_COUNT; k++) { 7538b3660a96SSukumar Swaminathan word = PADDR_HI(phys); 753982527734SSukumar Swaminathan rqe->AddrHi = BE_SWAP32(word); 754082527734SSukumar Swaminathan 7541b3660a96SSukumar Swaminathan word = PADDR_LO(phys); 754282527734SSukumar Swaminathan rqe->AddrLo = BE_SWAP32(word); 754382527734SSukumar Swaminathan 7544b3660a96SSukumar Swaminathan rqb = &hba->sli.sli4.rq[i]. 7545b3660a96SSukumar Swaminathan rqb[k + (j * RQB_COUNT)]; 7546b3660a96SSukumar Swaminathan rqb->size = size; 7547b3660a96SSukumar Swaminathan rqb->flags = FC_MBUF_DMA | 7548b3660a96SSukumar Swaminathan FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7549b3660a96SSukumar Swaminathan rqb->align = ddi_ptob(hba->dip, 1L); 7550b3660a96SSukumar Swaminathan rqb->phys = phys; 7551a9800bebSGarrett D'Amore rqb->virt = (void *)virt; 7552b3660a96SSukumar Swaminathan rqb->data_handle = data_handle; 7553b3660a96SSukumar Swaminathan rqb->dma_handle = dma_handle; 7554b3660a96SSukumar Swaminathan 7555b3660a96SSukumar Swaminathan phys += size; 7556b3660a96SSukumar Swaminathan virt += size; 7557*8f23e9faSHans Rosenfeld #ifdef DEBUG_RQE 755882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 7559*8f23e9faSHans Rosenfeld "RQ_ALLOC: rq[%d] rqb[%d,%d]=%p iotag=%d", 756082527734SSukumar Swaminathan i, j, k, mp, mp->tag); 7561*8f23e9faSHans Rosenfeld #endif /* DEBUG_RQE */ 756282527734SSukumar Swaminathan 756382527734SSukumar Swaminathan rqe++; 756482527734SSukumar Swaminathan } 756582527734SSukumar Swaminathan } 756682527734SSukumar Swaminathan 7567b3660a96SSukumar Swaminathan offset = (off_t)((uint64_t)((unsigned long) 7568b3660a96SSukumar Swaminathan hba->sli.sli4.rq[i].addr.virt) - 7569b3660a96SSukumar Swaminathan (uint64_t)((unsigned long) 7570b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.virt)); 7571b3660a96SSukumar Swaminathan 757282527734SSukumar Swaminathan /* Sync the RQ buffer list */ 7573b3660a96SSukumar Swaminathan EMLXS_MPDATA_SYNC(hba->sli.sli4.rq[i].addr.dma_handle, offset, 757482527734SSukumar Swaminathan hba->sli.sli4.rq[i].addr.size, DDI_DMA_SYNC_FORDEV); 7575b3660a96SSukumar Swaminathan } 757682527734SSukumar Swaminathan 7577*8f23e9faSHans Rosenfeld /* 4K Alignment */ 7578*8f23e9faSHans Rosenfeld align = (4096 - (phys%4096)); 7579*8f23e9faSHans Rosenfeld phys += align; 7580*8f23e9faSHans Rosenfeld virt += align; 7581b3660a96SSukumar Swaminathan 7582*8f23e9faSHans Rosenfeld /* SGL */ 7583*8f23e9faSHans Rosenfeld /* Initialize double linked lists */ 7584*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIinuse_f = 7585*8f23e9faSHans Rosenfeld (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 7586*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIinuse_b = 7587*8f23e9faSHans Rosenfeld (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 7588*8f23e9faSHans Rosenfeld hba->sli.sli4.xria_count = 0; 7589*8f23e9faSHans Rosenfeld 7590*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIfree_f = 7591*8f23e9faSHans Rosenfeld (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 7592*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIfree_b = 7593*8f23e9faSHans Rosenfeld (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 7594*8f23e9faSHans Rosenfeld hba->sli.sli4.xria_count = 0; 7595*8f23e9faSHans Rosenfeld 7596*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIp = (XRIobj_t *)kmem_zalloc( 7597*8f23e9faSHans Rosenfeld (sizeof (XRIobj_t) * hba->sli.sli4.XRICount), KM_SLEEP); 7598b3660a96SSukumar Swaminathan 7599*8f23e9faSHans Rosenfeld xrip = hba->sli.sli4.XRIp; 7600*8f23e9faSHans Rosenfeld size = hba->sli.sli4.mem_sgl_size; 7601*8f23e9faSHans Rosenfeld iotag = 1; 7602*8f23e9faSHans Rosenfeld for (i = 0; i < hba->sli.sli4.XRICount; i++) { 7603*8f23e9faSHans Rosenfeld xrip->XRI = emlxs_sli4_index_to_xri(hba, i); 7604*8f23e9faSHans Rosenfeld 7605*8f23e9faSHans Rosenfeld /* We don't use XRI==0, since it also represents an */ 7606*8f23e9faSHans Rosenfeld /* uninitialized exchange */ 7607*8f23e9faSHans Rosenfeld if (xrip->XRI == 0) { 7608a9800bebSGarrett D'Amore xrip++; 7609*8f23e9faSHans Rosenfeld continue; 7610b3660a96SSukumar Swaminathan } 7611*8f23e9faSHans Rosenfeld 7612*8f23e9faSHans Rosenfeld xrip->iotag = iotag++; 7613*8f23e9faSHans Rosenfeld xrip->sge_count = 7614*8f23e9faSHans Rosenfeld (hba->sli.sli4.mem_sgl_size / sizeof (ULP_SGE64)); 7615*8f23e9faSHans Rosenfeld 7616*8f23e9faSHans Rosenfeld /* Add xrip to end of free list */ 7617*8f23e9faSHans Rosenfeld xrip->_b = hba->sli.sli4.XRIfree_b; 7618*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIfree_b->_f = xrip; 7619*8f23e9faSHans Rosenfeld xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 7620*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIfree_b = xrip; 7621*8f23e9faSHans Rosenfeld hba->sli.sli4.xrif_count++; 7622*8f23e9faSHans Rosenfeld 7623*8f23e9faSHans Rosenfeld /* Allocate SGL for this xrip */ 7624*8f23e9faSHans Rosenfeld buf_info = &xrip->SGList; 7625*8f23e9faSHans Rosenfeld buf_info->size = size; 7626*8f23e9faSHans Rosenfeld buf_info->flags = 7627*8f23e9faSHans Rosenfeld FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32; 7628*8f23e9faSHans Rosenfeld buf_info->align = size; 7629*8f23e9faSHans Rosenfeld buf_info->phys = phys; 7630*8f23e9faSHans Rosenfeld buf_info->virt = (void *)virt; 7631*8f23e9faSHans Rosenfeld buf_info->data_handle = data_handle; 7632*8f23e9faSHans Rosenfeld buf_info->dma_handle = dma_handle; 7633*8f23e9faSHans Rosenfeld 7634*8f23e9faSHans Rosenfeld phys += size; 7635*8f23e9faSHans Rosenfeld virt += size; 7636*8f23e9faSHans Rosenfeld 7637*8f23e9faSHans Rosenfeld xrip++; 763882527734SSukumar Swaminathan } 763982527734SSukumar Swaminathan 7640*8f23e9faSHans Rosenfeld /* 4K Alignment */ 7641*8f23e9faSHans Rosenfeld align = (4096 - (phys%4096)); 7642*8f23e9faSHans Rosenfeld phys += align; 7643*8f23e9faSHans Rosenfeld virt += align; 7644*8f23e9faSHans Rosenfeld 7645*8f23e9faSHans Rosenfeld /* RPI Header Templates */ 7646*8f23e9faSHans Rosenfeld if (hba->sli.sli4.param.HDRR) { 7647*8f23e9faSHans Rosenfeld buf_info = &hba->sli.sli4.HeaderTmplate; 7648b3660a96SSukumar Swaminathan bzero(buf_info, sizeof (MBUF_INFO)); 7649*8f23e9faSHans Rosenfeld buf_info->size = hddr_size; 7650b3660a96SSukumar Swaminathan buf_info->flags = FC_MBUF_DMA | FC_MBUF_DMA32; 765182527734SSukumar Swaminathan buf_info->align = ddi_ptob(hba->dip, 1L); 7652b3660a96SSukumar Swaminathan buf_info->phys = phys; 7653a9800bebSGarrett D'Amore buf_info->virt = (void *)virt; 7654b3660a96SSukumar Swaminathan buf_info->data_handle = data_handle; 7655b3660a96SSukumar Swaminathan buf_info->dma_handle = dma_handle; 7656b3660a96SSukumar Swaminathan } 765782527734SSukumar Swaminathan 7658b3660a96SSukumar Swaminathan #ifdef FMA_SUPPORT 7659b3660a96SSukumar Swaminathan if (hba->sli.sli4.slim2.dma_handle) { 7660b3660a96SSukumar Swaminathan if (emlxs_fm_check_dma_handle(hba, 7661b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle) 7662b3660a96SSukumar Swaminathan != DDI_FM_OK) { 7663b3660a96SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 7664b3660a96SSukumar Swaminathan &emlxs_invalid_dma_handle_msg, 7665*8f23e9faSHans Rosenfeld "sli4_resource_alloc: hdl=%p", 7666b3660a96SSukumar Swaminathan hba->sli.sli4.slim2.dma_handle); 766782527734SSukumar Swaminathan goto failed; 766882527734SSukumar Swaminathan } 766982527734SSukumar Swaminathan } 7670*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 767182527734SSukumar Swaminathan 767282527734SSukumar Swaminathan return (0); 767382527734SSukumar Swaminathan 767482527734SSukumar Swaminathan failed: 767582527734SSukumar Swaminathan 767682527734SSukumar Swaminathan (void) emlxs_sli4_resource_free(hba); 767782527734SSukumar Swaminathan return (ENOMEM); 767882527734SSukumar Swaminathan 767982527734SSukumar Swaminathan } /* emlxs_sli4_resource_alloc */ 768082527734SSukumar Swaminathan 768182527734SSukumar Swaminathan 7682*8f23e9faSHans Rosenfeld extern void 7683*8f23e9faSHans Rosenfeld emlxs_sli4_zero_queue_stat(emlxs_hba_t *hba) 768482527734SSukumar Swaminathan { 7685*8f23e9faSHans Rosenfeld uint32_t i; 7686*8f23e9faSHans Rosenfeld uint32_t num_wq; 7687*8f23e9faSHans Rosenfeld emlxs_config_t *cfg = &CFG; 7688*8f23e9faSHans Rosenfeld clock_t time; 7689*8f23e9faSHans Rosenfeld 7690*8f23e9faSHans Rosenfeld /* EQ */ 7691*8f23e9faSHans Rosenfeld for (i = 0; i < hba->intr_count; i++) { 7692*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].num_proc = 0; 7693*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].max_proc = 0; 7694*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].isr_count = 0; 7695*8f23e9faSHans Rosenfeld } 7696*8f23e9faSHans Rosenfeld num_wq = cfg[CFG_NUM_WQ].current * hba->intr_count; 7697*8f23e9faSHans Rosenfeld /* CQ */ 7698*8f23e9faSHans Rosenfeld for (i = 0; i < (num_wq + EMLXS_CQ_OFFSET_WQ); i++) { 7699*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].num_proc = 0; 7700*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].max_proc = 0; 7701*8f23e9faSHans Rosenfeld hba->sli.sli4.cq[i].isr_count = 0; 7702*8f23e9faSHans Rosenfeld } 7703*8f23e9faSHans Rosenfeld /* WQ */ 7704*8f23e9faSHans Rosenfeld for (i = 0; i < num_wq; i++) { 7705*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].num_proc = 0; 7706*8f23e9faSHans Rosenfeld hba->sli.sli4.wq[i].num_busy = 0; 7707*8f23e9faSHans Rosenfeld } 7708*8f23e9faSHans Rosenfeld /* RQ */ 7709*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_RQS; i++) { 7710*8f23e9faSHans Rosenfeld hba->sli.sli4.rq[i].num_proc = 0; 7711*8f23e9faSHans Rosenfeld } 7712*8f23e9faSHans Rosenfeld (void) drv_getparm(LBOLT, &time); 7713*8f23e9faSHans Rosenfeld hba->sli.sli4.que_stat_timer = (uint32_t)time; 7714*8f23e9faSHans Rosenfeld 7715*8f23e9faSHans Rosenfeld } /* emlxs_sli4_zero_queue_stat */ 7716*8f23e9faSHans Rosenfeld 7717*8f23e9faSHans Rosenfeld 7718*8f23e9faSHans Rosenfeld extern XRIobj_t * 7719*8f23e9faSHans Rosenfeld emlxs_sli4_reserve_xri(emlxs_port_t *port, RPIobj_t *rpip, uint32_t type, 7720*8f23e9faSHans Rosenfeld uint16_t rx_id) 7721*8f23e9faSHans Rosenfeld { 7722*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 7723a9800bebSGarrett D'Amore XRIobj_t *xrip; 7724a9800bebSGarrett D'Amore uint16_t iotag; 772582527734SSukumar Swaminathan 7726a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 772782527734SSukumar Swaminathan 7728a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIfree_f; 772982527734SSukumar Swaminathan 7730a9800bebSGarrett D'Amore if (xrip == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) { 7731a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 773282527734SSukumar Swaminathan 7733a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 7734*8f23e9faSHans Rosenfeld "Unable to reserve XRI. type=%d", 7735*8f23e9faSHans Rosenfeld type); 773682527734SSukumar Swaminathan 7737a9800bebSGarrett D'Amore return (NULL); 7738a9800bebSGarrett D'Amore } 773982527734SSukumar Swaminathan 7740a9800bebSGarrett D'Amore iotag = xrip->iotag; 774182527734SSukumar Swaminathan 7742a9800bebSGarrett D'Amore if ((!iotag) || 7743a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 7744a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 7745a9800bebSGarrett D'Amore /* 7746a9800bebSGarrett D'Amore * No more command slots available, retry later 7747a9800bebSGarrett D'Amore */ 7748a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 7749*8f23e9faSHans Rosenfeld "Adapter Busy. Unable to reserve iotag. type=%d", 7750*8f23e9faSHans Rosenfeld type); 775182527734SSukumar Swaminathan 7752a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 7753a9800bebSGarrett D'Amore return (NULL); 775482527734SSukumar Swaminathan } 775582527734SSukumar Swaminathan 7756a9800bebSGarrett D'Amore xrip->state = XRI_STATE_ALLOCATED; 7757*8f23e9faSHans Rosenfeld xrip->type = type; 7758a9800bebSGarrett D'Amore xrip->flag = EMLXS_XRI_RESERVED; 7759a9800bebSGarrett D'Amore xrip->sbp = NULL; 776082527734SSukumar Swaminathan 7761*8f23e9faSHans Rosenfeld xrip->rpip = rpip; 7762*8f23e9faSHans Rosenfeld xrip->rx_id = rx_id; 7763*8f23e9faSHans Rosenfeld rpip->xri_count++; 776482527734SSukumar Swaminathan 7765a9800bebSGarrett D'Amore /* Take it off free list */ 7766a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 7767a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 7768a9800bebSGarrett D'Amore xrip->_f = NULL; 7769a9800bebSGarrett D'Amore xrip->_b = NULL; 7770a9800bebSGarrett D'Amore hba->sli.sli4.xrif_count--; 777182527734SSukumar Swaminathan 777282527734SSukumar Swaminathan /* Add it to end of inuse list */ 7773a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIinuse_b; 7774a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b->_f = xrip; 7775a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 7776a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b = xrip; 777782527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 777882527734SSukumar Swaminathan 777982527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 7780a9800bebSGarrett D'Amore return (xrip); 778182527734SSukumar Swaminathan 778282527734SSukumar Swaminathan } /* emlxs_sli4_reserve_xri() */ 778382527734SSukumar Swaminathan 778482527734SSukumar Swaminathan 778582527734SSukumar Swaminathan extern uint32_t 7786*8f23e9faSHans Rosenfeld emlxs_sli4_unreserve_xri(emlxs_port_t *port, uint16_t xri, uint32_t lock) 778782527734SSukumar Swaminathan { 7788*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 7789a9800bebSGarrett D'Amore XRIobj_t *xrip; 779082527734SSukumar Swaminathan 7791a9800bebSGarrett D'Amore if (lock) { 7792a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 7793a9800bebSGarrett D'Amore } 779482527734SSukumar Swaminathan 7795*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_find_xri(port, xri); 7796a9800bebSGarrett D'Amore 7797a9800bebSGarrett D'Amore if (!xrip || xrip->state == XRI_STATE_FREE) { 7798a9800bebSGarrett D'Amore if (lock) { 7799a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 7800a9800bebSGarrett D'Amore } 780182527734SSukumar Swaminathan 780282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 7803*8f23e9faSHans Rosenfeld "sli4_unreserve_xri:%d already freed.", xri); 780482527734SSukumar Swaminathan return (0); 780582527734SSukumar Swaminathan } 780682527734SSukumar Swaminathan 7807*8f23e9faSHans Rosenfeld /* Flush this unsolicited ct command */ 7808*8f23e9faSHans Rosenfeld if (xrip->type == EMLXS_XRI_UNSOL_CT_TYPE) { 7809*8f23e9faSHans Rosenfeld (void) emlxs_flush_ct_event(port, xrip->rx_id); 7810*8f23e9faSHans Rosenfeld } 7811*8f23e9faSHans Rosenfeld 7812a9800bebSGarrett D'Amore if (!(xrip->flag & EMLXS_XRI_RESERVED)) { 7813a9800bebSGarrett D'Amore if (lock) { 7814a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 7815a9800bebSGarrett D'Amore } 7816a9800bebSGarrett D'Amore 781782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 7818*8f23e9faSHans Rosenfeld "sli4_unreserve_xri:%d in use. type=%d", 7819*8f23e9faSHans Rosenfeld xrip->XRI, xrip->type); 782082527734SSukumar Swaminathan return (1); 782182527734SSukumar Swaminathan } 782282527734SSukumar Swaminathan 7823a9800bebSGarrett D'Amore if (xrip->iotag && 7824a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != NULL) && 7825a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != STALE_PACKET)) { 7826a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_err_msg, 7827*8f23e9faSHans Rosenfeld "sli4_unreserve_xri:%d sbp dropped:%p type=%d", 7828*8f23e9faSHans Rosenfeld xrip->XRI, hba->fc_table[xrip->iotag], xrip->type); 7829a9800bebSGarrett D'Amore 7830a9800bebSGarrett D'Amore hba->fc_table[xrip->iotag] = NULL; 783182527734SSukumar Swaminathan hba->io_count--; 783282527734SSukumar Swaminathan } 783382527734SSukumar Swaminathan 7834*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 7835*8f23e9faSHans Rosenfeld "sli4_unreserve_xri:%d unreserved. type=%d", 7836*8f23e9faSHans Rosenfeld xrip->XRI, xrip->type); 7837*8f23e9faSHans Rosenfeld 7838a9800bebSGarrett D'Amore xrip->state = XRI_STATE_FREE; 7839*8f23e9faSHans Rosenfeld xrip->type = 0; 784082527734SSukumar Swaminathan 7841a9800bebSGarrett D'Amore if (xrip->rpip) { 7842a9800bebSGarrett D'Amore xrip->rpip->xri_count--; 7843a9800bebSGarrett D'Amore xrip->rpip = NULL; 784482527734SSukumar Swaminathan } 784582527734SSukumar Swaminathan 7846*8f23e9faSHans Rosenfeld if (xrip->reserved_rpip) { 7847*8f23e9faSHans Rosenfeld xrip->reserved_rpip->xri_count--; 7848*8f23e9faSHans Rosenfeld xrip->reserved_rpip = NULL; 7849*8f23e9faSHans Rosenfeld } 7850*8f23e9faSHans Rosenfeld 785182527734SSukumar Swaminathan /* Take it off inuse list */ 7852a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 7853a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 7854a9800bebSGarrett D'Amore xrip->_f = NULL; 7855a9800bebSGarrett D'Amore xrip->_b = NULL; 785682527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 785782527734SSukumar Swaminathan 785882527734SSukumar Swaminathan /* Add it to end of free list */ 7859a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIfree_b; 7860a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b->_f = xrip; 7861a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 7862a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b = xrip; 786382527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 786482527734SSukumar Swaminathan 7865a9800bebSGarrett D'Amore if (lock) { 7866a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 7867a9800bebSGarrett D'Amore } 786882527734SSukumar Swaminathan 786982527734SSukumar Swaminathan return (0); 787082527734SSukumar Swaminathan 787182527734SSukumar Swaminathan } /* emlxs_sli4_unreserve_xri() */ 787282527734SSukumar Swaminathan 787382527734SSukumar Swaminathan 7874*8f23e9faSHans Rosenfeld XRIobj_t * 7875*8f23e9faSHans Rosenfeld emlxs_sli4_register_xri(emlxs_port_t *port, emlxs_buf_t *sbp, uint16_t xri, 7876*8f23e9faSHans Rosenfeld uint32_t did) 787782527734SSukumar Swaminathan { 7878*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 787982527734SSukumar Swaminathan uint16_t iotag; 7880a9800bebSGarrett D'Amore XRIobj_t *xrip; 7881*8f23e9faSHans Rosenfeld emlxs_node_t *node; 7882*8f23e9faSHans Rosenfeld RPIobj_t *rpip; 788382527734SSukumar Swaminathan 788482527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 788582527734SSukumar Swaminathan 7886*8f23e9faSHans Rosenfeld xrip = sbp->xrip; 7887a9800bebSGarrett D'Amore if (!xrip) { 7888*8f23e9faSHans Rosenfeld xrip = emlxs_sli4_find_xri(port, xri); 788982527734SSukumar Swaminathan 7890*8f23e9faSHans Rosenfeld if (!xrip) { 7891*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 7892*8f23e9faSHans Rosenfeld "sli4_register_xri:%d XRI not found.", xri); 789382527734SSukumar Swaminathan 7894*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_FCTAB_LOCK); 7895*8f23e9faSHans Rosenfeld return (NULL); 7896*8f23e9faSHans Rosenfeld } 789782527734SSukumar Swaminathan } 789882527734SSukumar Swaminathan 7899a9800bebSGarrett D'Amore if ((xrip->state == XRI_STATE_FREE) || 7900a9800bebSGarrett D'Amore !(xrip->flag & EMLXS_XRI_RESERVED)) { 790182527734SSukumar Swaminathan 790282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 7903*8f23e9faSHans Rosenfeld "sli4_register_xri:%d Invalid XRI. xrip=%p " 7904a9800bebSGarrett D'Amore "state=%x flag=%x", 7905*8f23e9faSHans Rosenfeld xrip->XRI, xrip, xrip->state, xrip->flag); 790682527734SSukumar Swaminathan 790782527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 790882527734SSukumar Swaminathan return (NULL); 790982527734SSukumar Swaminathan } 791082527734SSukumar Swaminathan 7911a9800bebSGarrett D'Amore iotag = xrip->iotag; 791282527734SSukumar Swaminathan 791382527734SSukumar Swaminathan if ((!iotag) || 7914a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 7915a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 791682527734SSukumar Swaminathan 791782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 7918*8f23e9faSHans Rosenfeld "sli4_register_xri:%d Invalid fc_table entry. " 7919*8f23e9faSHans Rosenfeld "iotag=%d entry=%p", 7920*8f23e9faSHans Rosenfeld xrip->XRI, iotag, hba->fc_table[iotag]); 792182527734SSukumar Swaminathan 792282527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 792382527734SSukumar Swaminathan return (NULL); 792482527734SSukumar Swaminathan } 792582527734SSukumar Swaminathan 792682527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 792782527734SSukumar Swaminathan hba->io_count++; 792882527734SSukumar Swaminathan 792982527734SSukumar Swaminathan sbp->iotag = iotag; 7930a9800bebSGarrett D'Amore sbp->xrip = xrip; 793182527734SSukumar Swaminathan 7932a9800bebSGarrett D'Amore xrip->flag &= ~EMLXS_XRI_RESERVED; 7933a9800bebSGarrett D'Amore xrip->sbp = sbp; 793482527734SSukumar Swaminathan 7935*8f23e9faSHans Rosenfeld /* If we did not have a registered RPI when we reserved */ 7936*8f23e9faSHans Rosenfeld /* this exchange, check again now. */ 7937*8f23e9faSHans Rosenfeld if (xrip->rpip && (xrip->rpip->RPI == FABRIC_RPI)) { 7938*8f23e9faSHans Rosenfeld node = emlxs_node_find_did(port, did, 1); 7939*8f23e9faSHans Rosenfeld rpip = EMLXS_NODE_TO_RPI(port, node); 7940*8f23e9faSHans Rosenfeld 7941*8f23e9faSHans Rosenfeld if (rpip && (rpip->RPI != FABRIC_RPI)) { 7942*8f23e9faSHans Rosenfeld /* Move the XRI to the new RPI */ 7943*8f23e9faSHans Rosenfeld xrip->rpip->xri_count--; 7944*8f23e9faSHans Rosenfeld xrip->rpip = rpip; 7945*8f23e9faSHans Rosenfeld rpip->xri_count++; 7946*8f23e9faSHans Rosenfeld } 7947*8f23e9faSHans Rosenfeld } 7948*8f23e9faSHans Rosenfeld 794982527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 795082527734SSukumar Swaminathan 7951a9800bebSGarrett D'Amore return (xrip); 795282527734SSukumar Swaminathan 795382527734SSukumar Swaminathan } /* emlxs_sli4_register_xri() */ 795482527734SSukumar Swaminathan 795582527734SSukumar Swaminathan 795682527734SSukumar Swaminathan /* Performs both reserve and register functions for XRI */ 795782527734SSukumar Swaminathan static XRIobj_t * 7958*8f23e9faSHans Rosenfeld emlxs_sli4_alloc_xri(emlxs_port_t *port, emlxs_buf_t *sbp, RPIobj_t *rpip, 7959*8f23e9faSHans Rosenfeld uint32_t type) 796082527734SSukumar Swaminathan { 7961*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 7962a9800bebSGarrett D'Amore XRIobj_t *xrip; 796382527734SSukumar Swaminathan uint16_t iotag; 796482527734SSukumar Swaminathan 796582527734SSukumar Swaminathan mutex_enter(&EMLXS_FCTAB_LOCK); 796682527734SSukumar Swaminathan 7967a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIfree_f; 796882527734SSukumar Swaminathan 7969a9800bebSGarrett D'Amore if (xrip == (XRIobj_t *)&hba->sli.sli4.XRIfree_f) { 797082527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 797182527734SSukumar Swaminathan 797282527734SSukumar Swaminathan return (NULL); 797382527734SSukumar Swaminathan } 797482527734SSukumar Swaminathan 797582527734SSukumar Swaminathan /* Get the iotag by registering the packet */ 7976a9800bebSGarrett D'Amore iotag = xrip->iotag; 797782527734SSukumar Swaminathan 797882527734SSukumar Swaminathan if ((!iotag) || 7979a9800bebSGarrett D'Amore ((hba->fc_table[iotag] != NULL) && 7980a9800bebSGarrett D'Amore (hba->fc_table[iotag] != STALE_PACKET))) { 798182527734SSukumar Swaminathan /* 798282527734SSukumar Swaminathan * No more command slots available, retry later 798382527734SSukumar Swaminathan */ 798482527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg, 7985*8f23e9faSHans Rosenfeld "Adapter Busy. Unable to alloc iotag:(0x%x)(%p) type=%d", 7986*8f23e9faSHans Rosenfeld iotag, hba->fc_table[iotag], type); 798782527734SSukumar Swaminathan 798882527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 798982527734SSukumar Swaminathan return (NULL); 799082527734SSukumar Swaminathan } 799182527734SSukumar Swaminathan 799282527734SSukumar Swaminathan hba->fc_table[iotag] = sbp; 799382527734SSukumar Swaminathan hba->io_count++; 799482527734SSukumar Swaminathan 799582527734SSukumar Swaminathan sbp->iotag = iotag; 7996a9800bebSGarrett D'Amore sbp->xrip = xrip; 799782527734SSukumar Swaminathan 7998a9800bebSGarrett D'Amore xrip->state = XRI_STATE_ALLOCATED; 7999*8f23e9faSHans Rosenfeld xrip->type = type; 8000a9800bebSGarrett D'Amore xrip->flag = 0; 8001a9800bebSGarrett D'Amore xrip->sbp = sbp; 800282527734SSukumar Swaminathan 8003*8f23e9faSHans Rosenfeld xrip->rpip = rpip; 8004*8f23e9faSHans Rosenfeld rpip->xri_count++; 800582527734SSukumar Swaminathan 800682527734SSukumar Swaminathan /* Take it off free list */ 8007a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 8008a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 8009a9800bebSGarrett D'Amore xrip->_f = NULL; 8010a9800bebSGarrett D'Amore xrip->_b = NULL; 801182527734SSukumar Swaminathan hba->sli.sli4.xrif_count--; 801282527734SSukumar Swaminathan 801382527734SSukumar Swaminathan /* Add it to end of inuse list */ 8014a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIinuse_b; 8015a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b->_f = xrip; 8016a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIinuse_f; 8017a9800bebSGarrett D'Amore hba->sli.sli4.XRIinuse_b = xrip; 801882527734SSukumar Swaminathan hba->sli.sli4.xria_count++; 801982527734SSukumar Swaminathan 802082527734SSukumar Swaminathan mutex_exit(&EMLXS_FCTAB_LOCK); 802182527734SSukumar Swaminathan 8022a9800bebSGarrett D'Amore return (xrip); 802382527734SSukumar Swaminathan 802482527734SSukumar Swaminathan } /* emlxs_sli4_alloc_xri() */ 802582527734SSukumar Swaminathan 802682527734SSukumar Swaminathan 8027a9800bebSGarrett D'Amore /* EMLXS_FCTAB_LOCK must be held to enter */ 802882527734SSukumar Swaminathan extern XRIobj_t * 8029*8f23e9faSHans Rosenfeld emlxs_sli4_find_xri(emlxs_port_t *port, uint16_t xri) 803082527734SSukumar Swaminathan { 8031*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 8032a9800bebSGarrett D'Amore XRIobj_t *xrip; 803382527734SSukumar Swaminathan 8034a9800bebSGarrett D'Amore xrip = (XRIobj_t *)hba->sli.sli4.XRIinuse_f; 8035a9800bebSGarrett D'Amore while (xrip != (XRIobj_t *)&hba->sli.sli4.XRIinuse_f) { 8036a9800bebSGarrett D'Amore if ((xrip->state >= XRI_STATE_ALLOCATED) && 8037a9800bebSGarrett D'Amore (xrip->XRI == xri)) { 8038a9800bebSGarrett D'Amore return (xrip); 803982527734SSukumar Swaminathan } 8040a9800bebSGarrett D'Amore xrip = xrip->_f; 804182527734SSukumar Swaminathan } 804282527734SSukumar Swaminathan 8043a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8044a9800bebSGarrett D'Amore "Unable to find XRI x%x", xri); 804582527734SSukumar Swaminathan 8046a9800bebSGarrett D'Amore return (NULL); 804782527734SSukumar Swaminathan 8048a9800bebSGarrett D'Amore } /* emlxs_sli4_find_xri() */ 804982527734SSukumar Swaminathan 805082527734SSukumar Swaminathan 805182527734SSukumar Swaminathan 805282527734SSukumar Swaminathan 805382527734SSukumar Swaminathan extern void 8054*8f23e9faSHans Rosenfeld emlxs_sli4_free_xri(emlxs_port_t *port, emlxs_buf_t *sbp, XRIobj_t *xrip, 8055a9800bebSGarrett D'Amore uint8_t lock) 805682527734SSukumar Swaminathan { 8057*8f23e9faSHans Rosenfeld emlxs_hba_t *hba = HBA; 805882527734SSukumar Swaminathan 8059a9800bebSGarrett D'Amore if (lock) { 8060a9800bebSGarrett D'Amore mutex_enter(&EMLXS_FCTAB_LOCK); 806182527734SSukumar Swaminathan } 806282527734SSukumar Swaminathan 8063a9800bebSGarrett D'Amore if (xrip) { 8064a9800bebSGarrett D'Amore if (xrip->state == XRI_STATE_FREE) { 8065a9800bebSGarrett D'Amore if (lock) { 8066a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 8067a9800bebSGarrett D'Amore } 806882527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8069*8f23e9faSHans Rosenfeld "Free XRI:%x, Already freed. type=%d", 8070*8f23e9faSHans Rosenfeld xrip->XRI, xrip->type); 807182527734SSukumar Swaminathan return; 807282527734SSukumar Swaminathan } 807382527734SSukumar Swaminathan 8074*8f23e9faSHans Rosenfeld if (xrip->type == EMLXS_XRI_UNSOL_CT_TYPE) { 8075*8f23e9faSHans Rosenfeld (void) emlxs_flush_ct_event(port, xrip->rx_id); 8076*8f23e9faSHans Rosenfeld } 8077*8f23e9faSHans Rosenfeld 8078a9800bebSGarrett D'Amore if (xrip->iotag && 8079a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != NULL) && 8080a9800bebSGarrett D'Amore (hba->fc_table[xrip->iotag] != STALE_PACKET)) { 8081a9800bebSGarrett D'Amore hba->fc_table[xrip->iotag] = NULL; 808282527734SSukumar Swaminathan hba->io_count--; 808382527734SSukumar Swaminathan } 808482527734SSukumar Swaminathan 8085a9800bebSGarrett D'Amore xrip->state = XRI_STATE_FREE; 8086*8f23e9faSHans Rosenfeld xrip->type = 0; 8087a9800bebSGarrett D'Amore xrip->flag = 0; 808882527734SSukumar Swaminathan 8089a9800bebSGarrett D'Amore if (xrip->rpip) { 8090a9800bebSGarrett D'Amore xrip->rpip->xri_count--; 8091a9800bebSGarrett D'Amore xrip->rpip = NULL; 809282527734SSukumar Swaminathan } 809382527734SSukumar Swaminathan 8094*8f23e9faSHans Rosenfeld if (xrip->reserved_rpip) { 8095*8f23e9faSHans Rosenfeld xrip->reserved_rpip->xri_count--; 8096*8f23e9faSHans Rosenfeld xrip->reserved_rpip = NULL; 8097*8f23e9faSHans Rosenfeld } 8098*8f23e9faSHans Rosenfeld 809982527734SSukumar Swaminathan /* Take it off inuse list */ 8100a9800bebSGarrett D'Amore (xrip->_b)->_f = xrip->_f; 8101a9800bebSGarrett D'Amore (xrip->_f)->_b = xrip->_b; 8102a9800bebSGarrett D'Amore xrip->_f = NULL; 8103a9800bebSGarrett D'Amore xrip->_b = NULL; 810482527734SSukumar Swaminathan hba->sli.sli4.xria_count--; 810582527734SSukumar Swaminathan 810682527734SSukumar Swaminathan /* Add it to end of free list */ 8107a9800bebSGarrett D'Amore xrip->_b = hba->sli.sli4.XRIfree_b; 8108a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b->_f = xrip; 8109a9800bebSGarrett D'Amore xrip->_f = (XRIobj_t *)&hba->sli.sli4.XRIfree_f; 8110a9800bebSGarrett D'Amore hba->sli.sli4.XRIfree_b = xrip; 811182527734SSukumar Swaminathan hba->sli.sli4.xrif_count++; 811282527734SSukumar Swaminathan } 811382527734SSukumar Swaminathan 811482527734SSukumar Swaminathan if (sbp) { 8115a9800bebSGarrett D'Amore if (!(sbp->pkt_flags & PACKET_VALID) || 8116a9800bebSGarrett D'Amore (sbp->pkt_flags & 8117a9800bebSGarrett D'Amore (PACKET_ULP_OWNED|PACKET_COMPLETED|PACKET_IN_COMPLETION))) { 8118a9800bebSGarrett D'Amore if (lock) { 8119a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 8120a9800bebSGarrett D'Amore } 8121a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8122*8f23e9faSHans Rosenfeld "Free XRI: sbp invalid. sbp=%p flags=%x xri=%d", 8123a9800bebSGarrett D'Amore sbp, sbp->pkt_flags, ((xrip)? xrip->XRI:0)); 8124a9800bebSGarrett D'Amore return; 8125a9800bebSGarrett D'Amore } 812682527734SSukumar Swaminathan 8127a9800bebSGarrett D'Amore if (xrip && (xrip->iotag != sbp->iotag)) { 8128a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 8129*8f23e9faSHans Rosenfeld "sbp/iotag mismatch %p iotag:%d %d", sbp, 8130a9800bebSGarrett D'Amore sbp->iotag, xrip->iotag); 813182527734SSukumar Swaminathan } 813282527734SSukumar Swaminathan 813382527734SSukumar Swaminathan if (sbp->iotag) { 8134a9800bebSGarrett D'Amore if (sbp == hba->fc_table[sbp->iotag]) { 813582527734SSukumar Swaminathan hba->fc_table[sbp->iotag] = NULL; 813682527734SSukumar Swaminathan hba->io_count--; 8137*8f23e9faSHans Rosenfeld 8138*8f23e9faSHans Rosenfeld if (sbp->xrip) { 8139*8f23e9faSHans Rosenfeld /* Exchange is still reserved */ 8140*8f23e9faSHans Rosenfeld sbp->xrip->flag |= EMLXS_XRI_RESERVED; 8141*8f23e9faSHans Rosenfeld } 814282527734SSukumar Swaminathan } 814382527734SSukumar Swaminathan sbp->iotag = 0; 814482527734SSukumar Swaminathan } 814582527734SSukumar Swaminathan 8146*8f23e9faSHans Rosenfeld if (xrip) { 8147*8f23e9faSHans Rosenfeld sbp->xrip = 0; 8148*8f23e9faSHans Rosenfeld } 8149*8f23e9faSHans Rosenfeld 8150a9800bebSGarrett D'Amore if (lock) { 8151a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 8152a9800bebSGarrett D'Amore } 815382527734SSukumar Swaminathan 815482527734SSukumar Swaminathan /* Clean up the sbp */ 815582527734SSukumar Swaminathan mutex_enter(&sbp->mtx); 815682527734SSukumar Swaminathan 815782527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_TXQ) { 815882527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_TXQ; 815982527734SSukumar Swaminathan hba->channel_tx_count--; 816082527734SSukumar Swaminathan } 816182527734SSukumar Swaminathan 816282527734SSukumar Swaminathan if (sbp->pkt_flags & PACKET_IN_CHIPQ) { 816382527734SSukumar Swaminathan sbp->pkt_flags &= ~PACKET_IN_CHIPQ; 816482527734SSukumar Swaminathan } 816582527734SSukumar Swaminathan 816682527734SSukumar Swaminathan mutex_exit(&sbp->mtx); 816782527734SSukumar Swaminathan } else { 8168a9800bebSGarrett D'Amore if (lock) { 8169a9800bebSGarrett D'Amore mutex_exit(&EMLXS_FCTAB_LOCK); 8170a9800bebSGarrett D'Amore } 817182527734SSukumar Swaminathan } 817282527734SSukumar Swaminathan 817382527734SSukumar Swaminathan } /* emlxs_sli4_free_xri() */ 817482527734SSukumar Swaminathan 817582527734SSukumar Swaminathan 817682527734SSukumar Swaminathan static int 817782527734SSukumar Swaminathan emlxs_sli4_post_sgl_pages(emlxs_hba_t *hba, MAILBOXQ *mbq) 817882527734SSukumar Swaminathan { 817982527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 818082527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 8181a9800bebSGarrett D'Amore XRIobj_t *xrip; 818282527734SSukumar Swaminathan MATCHMAP *mp; 818382527734SSukumar Swaminathan mbox_req_hdr_t *hdr_req; 8184*8f23e9faSHans Rosenfeld uint32_t i; 8185*8f23e9faSHans Rosenfeld uint32_t cnt; 8186*8f23e9faSHans Rosenfeld uint32_t xri_cnt; 8187*8f23e9faSHans Rosenfeld uint32_t j; 818882527734SSukumar Swaminathan uint32_t size; 818982527734SSukumar Swaminathan IOCTL_FCOE_CFG_POST_SGL_PAGES *post_sgl; 819082527734SSukumar Swaminathan 819182527734SSukumar Swaminathan bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 819282527734SSukumar Swaminathan mbq->bp = NULL; 819382527734SSukumar Swaminathan mbq->mbox_cmpl = NULL; 819482527734SSukumar Swaminathan 819582527734SSukumar Swaminathan if ((mp = emlxs_mem_buf_alloc(hba, EMLXS_MAX_NONEMBED_SIZE)) == 0) { 819682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 819782527734SSukumar Swaminathan "Unable to POST_SGL. Mailbox cmd=%x ", 819882527734SSukumar Swaminathan mb->mbxCommand); 819982527734SSukumar Swaminathan return (EIO); 820082527734SSukumar Swaminathan } 8201a9800bebSGarrett D'Amore mbq->nonembed = (void *)mp; 820282527734SSukumar Swaminathan 820382527734SSukumar Swaminathan /* 820482527734SSukumar Swaminathan * Signifies a non embedded command 820582527734SSukumar Swaminathan */ 820682527734SSukumar Swaminathan mb->un.varSLIConfig.be.embedded = 0; 820782527734SSukumar Swaminathan mb->mbxCommand = MBX_SLI_CONFIG; 820882527734SSukumar Swaminathan mb->mbxOwner = OWN_HOST; 820982527734SSukumar Swaminathan 821082527734SSukumar Swaminathan hdr_req = (mbox_req_hdr_t *)mp->virt; 821182527734SSukumar Swaminathan post_sgl = 821282527734SSukumar Swaminathan (IOCTL_FCOE_CFG_POST_SGL_PAGES *)(hdr_req + 1); 821382527734SSukumar Swaminathan 8214a9800bebSGarrett D'Amore xrip = hba->sli.sli4.XRIp; 821582527734SSukumar Swaminathan 8216*8f23e9faSHans Rosenfeld /* For each extent */ 8217*8f23e9faSHans Rosenfeld for (j = 0; j < hba->sli.sli4.XRIExtCount; j++) { 8218*8f23e9faSHans Rosenfeld cnt = hba->sli.sli4.XRIExtSize; 8219*8f23e9faSHans Rosenfeld while (cnt) { 8220*8f23e9faSHans Rosenfeld if (xrip->XRI == 0) { 8221*8f23e9faSHans Rosenfeld cnt--; 8222*8f23e9faSHans Rosenfeld xrip++; 8223*8f23e9faSHans Rosenfeld continue; 8224*8f23e9faSHans Rosenfeld } 8225*8f23e9faSHans Rosenfeld 8226*8f23e9faSHans Rosenfeld bzero((void *) hdr_req, mp->size); 8227*8f23e9faSHans Rosenfeld size = mp->size - IOCTL_HEADER_SZ; 8228*8f23e9faSHans Rosenfeld 8229*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.payload_length = 8230*8f23e9faSHans Rosenfeld mp->size; 8231*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 8232*8f23e9faSHans Rosenfeld IOCTL_SUBSYSTEM_FCOE; 8233*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 8234*8f23e9faSHans Rosenfeld FCOE_OPCODE_CFG_POST_SGL_PAGES; 8235*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 8236*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = size; 8237*8f23e9faSHans Rosenfeld 8238*8f23e9faSHans Rosenfeld hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE; 8239*8f23e9faSHans Rosenfeld hdr_req->opcode = FCOE_OPCODE_CFG_POST_SGL_PAGES; 8240*8f23e9faSHans Rosenfeld hdr_req->timeout = 0; 8241*8f23e9faSHans Rosenfeld hdr_req->req_length = size; 8242*8f23e9faSHans Rosenfeld 8243*8f23e9faSHans Rosenfeld post_sgl->params.request.xri_count = 0; 8244*8f23e9faSHans Rosenfeld post_sgl->params.request.xri_start = xrip->XRI; 8245*8f23e9faSHans Rosenfeld 8246*8f23e9faSHans Rosenfeld xri_cnt = (size - 8247*8f23e9faSHans Rosenfeld sizeof (IOCTL_FCOE_CFG_POST_SGL_PAGES)) / 8248*8f23e9faSHans Rosenfeld sizeof (FCOE_SGL_PAGES); 8249*8f23e9faSHans Rosenfeld 8250*8f23e9faSHans Rosenfeld for (i = 0; (i < xri_cnt) && cnt; i++) { 8251*8f23e9faSHans Rosenfeld post_sgl->params.request.xri_count++; 8252*8f23e9faSHans Rosenfeld post_sgl->params.request.pages[i].\ 8253*8f23e9faSHans Rosenfeld sgl_page0.addrLow = 8254*8f23e9faSHans Rosenfeld PADDR_LO(xrip->SGList.phys); 8255*8f23e9faSHans Rosenfeld post_sgl->params.request.pages[i].\ 8256*8f23e9faSHans Rosenfeld sgl_page0.addrHigh = 8257*8f23e9faSHans Rosenfeld PADDR_HI(xrip->SGList.phys); 8258*8f23e9faSHans Rosenfeld 8259*8f23e9faSHans Rosenfeld cnt--; 8260*8f23e9faSHans Rosenfeld xrip++; 8261*8f23e9faSHans Rosenfeld } 8262*8f23e9faSHans Rosenfeld 8263*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 8264*8f23e9faSHans Rosenfeld MBX_SUCCESS) { 8265*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8266*8f23e9faSHans Rosenfeld "Unable to POST_SGL. Mailbox cmd=%x " 8267*8f23e9faSHans Rosenfeld "status=%x XRI cnt:%d start:%d", 8268*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus, 8269*8f23e9faSHans Rosenfeld post_sgl->params.request.xri_count, 8270*8f23e9faSHans Rosenfeld post_sgl->params.request.xri_start); 8271*8f23e9faSHans Rosenfeld emlxs_mem_buf_free(hba, mp); 8272*8f23e9faSHans Rosenfeld mbq->nonembed = NULL; 8273*8f23e9faSHans Rosenfeld return (EIO); 827482527734SSukumar Swaminathan } 827582527734SSukumar Swaminathan } 827682527734SSukumar Swaminathan } 8277*8f23e9faSHans Rosenfeld 8278a9800bebSGarrett D'Amore emlxs_mem_buf_free(hba, mp); 8279a9800bebSGarrett D'Amore mbq->nonembed = NULL; 828082527734SSukumar Swaminathan return (0); 828182527734SSukumar Swaminathan 828282527734SSukumar Swaminathan } /* emlxs_sli4_post_sgl_pages() */ 828382527734SSukumar Swaminathan 828482527734SSukumar Swaminathan 828582527734SSukumar Swaminathan static int 828682527734SSukumar Swaminathan emlxs_sli4_post_hdr_tmplates(emlxs_hba_t *hba, MAILBOXQ *mbq) 828782527734SSukumar Swaminathan { 828882527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 828982527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 8290*8f23e9faSHans Rosenfeld uint32_t j; 8291*8f23e9faSHans Rosenfeld uint32_t k; 829282527734SSukumar Swaminathan uint64_t addr; 829382527734SSukumar Swaminathan IOCTL_FCOE_POST_HDR_TEMPLATES *post_hdr; 8294*8f23e9faSHans Rosenfeld uint16_t num_pages; 829582527734SSukumar Swaminathan 8296*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.HDRR)) { 8297*8f23e9faSHans Rosenfeld return (0); 8298*8f23e9faSHans Rosenfeld } 829982527734SSukumar Swaminathan 8300*8f23e9faSHans Rosenfeld /* Bytes per extent */ 8301*8f23e9faSHans Rosenfeld j = hba->sli.sli4.RPIExtSize * sizeof (RPIHdrTmplate_t); 8302*8f23e9faSHans Rosenfeld 8303*8f23e9faSHans Rosenfeld /* Pages required per extent (page == 4096 bytes) */ 8304*8f23e9faSHans Rosenfeld num_pages = (j/4096) + ((j%4096)? 1:0); 830582527734SSukumar Swaminathan 830682527734SSukumar Swaminathan addr = hba->sli.sli4.HeaderTmplate.phys; 830782527734SSukumar Swaminathan 8308*8f23e9faSHans Rosenfeld /* For each extent */ 8309*8f23e9faSHans Rosenfeld for (j = 0; j < hba->sli.sli4.RPIExtCount; j++) { 8310*8f23e9faSHans Rosenfeld bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE); 8311*8f23e9faSHans Rosenfeld mbq->bp = NULL; 8312*8f23e9faSHans Rosenfeld mbq->mbox_cmpl = NULL; 8313*8f23e9faSHans Rosenfeld 8314*8f23e9faSHans Rosenfeld /* 8315*8f23e9faSHans Rosenfeld * Signifies an embedded command 8316*8f23e9faSHans Rosenfeld */ 8317*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.embedded = 1; 8318*8f23e9faSHans Rosenfeld 8319*8f23e9faSHans Rosenfeld mb->mbxCommand = MBX_SLI_CONFIG; 8320*8f23e9faSHans Rosenfeld mb->mbxOwner = OWN_HOST; 8321*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.payload_length = 8322*8f23e9faSHans Rosenfeld sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES) + IOCTL_HEADER_SZ; 8323*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem = 8324*8f23e9faSHans Rosenfeld IOCTL_SUBSYSTEM_FCOE; 8325*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = 8326*8f23e9faSHans Rosenfeld FCOE_OPCODE_POST_HDR_TEMPLATES; 8327*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0; 8328*8f23e9faSHans Rosenfeld mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 8329*8f23e9faSHans Rosenfeld sizeof (IOCTL_FCOE_POST_HDR_TEMPLATES); 8330*8f23e9faSHans Rosenfeld 8331*8f23e9faSHans Rosenfeld post_hdr = 8332*8f23e9faSHans Rosenfeld (IOCTL_FCOE_POST_HDR_TEMPLATES *) 8333*8f23e9faSHans Rosenfeld &mb->un.varSLIConfig.payload; 8334*8f23e9faSHans Rosenfeld post_hdr->params.request.num_pages = num_pages; 8335*8f23e9faSHans Rosenfeld post_hdr->params.request.rpi_offset = hba->sli.sli4.RPIBase[j]; 8336*8f23e9faSHans Rosenfeld 8337*8f23e9faSHans Rosenfeld for (k = 0; k < num_pages; k++) { 8338*8f23e9faSHans Rosenfeld post_hdr->params.request.pages[k].addrLow = 8339*8f23e9faSHans Rosenfeld PADDR_LO(addr); 8340*8f23e9faSHans Rosenfeld post_hdr->params.request.pages[k].addrHigh = 8341*8f23e9faSHans Rosenfeld PADDR_HI(addr); 8342*8f23e9faSHans Rosenfeld addr += 4096; 8343*8f23e9faSHans Rosenfeld } 8344*8f23e9faSHans Rosenfeld 8345*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 8346*8f23e9faSHans Rosenfeld MBX_SUCCESS) { 8347*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8348*8f23e9faSHans Rosenfeld "Unable to POST_HDR_TEMPLATES. Mailbox cmd=%x " 8349*8f23e9faSHans Rosenfeld "status=%x ", 8350*8f23e9faSHans Rosenfeld mb->mbxCommand, mb->mbxStatus); 8351*8f23e9faSHans Rosenfeld return (EIO); 8352*8f23e9faSHans Rosenfeld } 8353*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "POST_HDR", (uint32_t *)mb, 18, 0); 835482527734SSukumar Swaminathan } 8355*8f23e9faSHans Rosenfeld 835682527734SSukumar Swaminathan return (0); 835782527734SSukumar Swaminathan 835882527734SSukumar Swaminathan } /* emlxs_sli4_post_hdr_tmplates() */ 835982527734SSukumar Swaminathan 836082527734SSukumar Swaminathan 836182527734SSukumar Swaminathan static int 836282527734SSukumar Swaminathan emlxs_sli4_create_queues(emlxs_hba_t *hba, MAILBOXQ *mbq) 836382527734SSukumar Swaminathan { 836482527734SSukumar Swaminathan MAILBOX4 *mb = (MAILBOX4 *)mbq; 836582527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 836682527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 836782527734SSukumar Swaminathan IOCTL_COMMON_EQ_CREATE *eq; 836882527734SSukumar Swaminathan IOCTL_COMMON_CQ_CREATE *cq; 836982527734SSukumar Swaminathan IOCTL_FCOE_WQ_CREATE *wq; 837082527734SSukumar Swaminathan IOCTL_FCOE_RQ_CREATE *rq; 837182527734SSukumar Swaminathan IOCTL_COMMON_MQ_CREATE *mq; 8372*8f23e9faSHans Rosenfeld IOCTL_COMMON_MQ_CREATE_EXT *mq_ext; 837382527734SSukumar Swaminathan emlxs_rqdbu_t rqdb; 8374a9800bebSGarrett D'Amore uint16_t i, j; 8375a9800bebSGarrett D'Amore uint16_t num_cq, total_cq; 8376a9800bebSGarrett D'Amore uint16_t num_wq, total_wq; 837782527734SSukumar Swaminathan 837882527734SSukumar Swaminathan /* 837982527734SSukumar Swaminathan * The first CQ is reserved for ASYNC events, 838082527734SSukumar Swaminathan * the second is reserved for unsol rcv, the rest 838182527734SSukumar Swaminathan * correspond to WQs. (WQ0 -> CQ2, WQ1 -> CQ3, ...) 838282527734SSukumar Swaminathan */ 838382527734SSukumar Swaminathan 838482527734SSukumar Swaminathan total_cq = 0; 838582527734SSukumar Swaminathan total_wq = 0; 838682527734SSukumar Swaminathan 838782527734SSukumar Swaminathan /* Create EQ's */ 838882527734SSukumar Swaminathan for (i = 0; i < hba->intr_count; i++) { 838982527734SSukumar Swaminathan emlxs_mb_eq_create(hba, mbq, i); 839082527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 839182527734SSukumar Swaminathan MBX_SUCCESS) { 839282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 839382527734SSukumar Swaminathan "Unable to Create EQ %d: Mailbox cmd=%x status=%x ", 839482527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 839582527734SSukumar Swaminathan return (EIO); 839682527734SSukumar Swaminathan } 839782527734SSukumar Swaminathan eq = (IOCTL_COMMON_EQ_CREATE *)&mb->un.varSLIConfig.payload; 839882527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid = eq->params.response.EQId; 839982527734SSukumar Swaminathan hba->sli.sli4.eq[i].lastwq = total_wq; 8400*8f23e9faSHans Rosenfeld hba->sli.sli4.eq[i].msix_vector = i; 840182527734SSukumar Swaminathan 8402*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "EQ0_CREATE", (uint32_t *)mb, 18, 0); 840382527734SSukumar Swaminathan num_wq = cfg[CFG_NUM_WQ].current; 840482527734SSukumar Swaminathan num_cq = num_wq; 840582527734SSukumar Swaminathan if (i == 0) { 840682527734SSukumar Swaminathan /* One for RQ handling, one for mbox/event handling */ 840782527734SSukumar Swaminathan num_cq += EMLXS_CQ_OFFSET_WQ; 840882527734SSukumar Swaminathan } 840982527734SSukumar Swaminathan 8410*8f23e9faSHans Rosenfeld /* Create CQ's */ 841182527734SSukumar Swaminathan for (j = 0; j < num_cq; j++) { 841282527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 841382527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 841482527734SSukumar Swaminathan 841582527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].eqid = 841682527734SSukumar Swaminathan hba->sli.sli4.eq[i].qid; 841782527734SSukumar Swaminathan 841882527734SSukumar Swaminathan emlxs_mb_cq_create(hba, mbq, total_cq); 841982527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 842082527734SSukumar Swaminathan MBX_SUCCESS) { 842182527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 842282527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 842382527734SSukumar Swaminathan "CQ %d: Mailbox cmd=%x status=%x ", 842482527734SSukumar Swaminathan total_cq, mb->mbxCommand, mb->mbxStatus); 842582527734SSukumar Swaminathan return (EIO); 842682527734SSukumar Swaminathan } 842782527734SSukumar Swaminathan cq = (IOCTL_COMMON_CQ_CREATE *) 842882527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 842982527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].qid = 843082527734SSukumar Swaminathan cq->params.response.CQId; 843182527734SSukumar Swaminathan 843282527734SSukumar Swaminathan switch (total_cq) { 843382527734SSukumar Swaminathan case EMLXS_CQ_MBOX: 843482527734SSukumar Swaminathan /* First CQ is for async event handling */ 843582527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 843682527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP1; 843782527734SSukumar Swaminathan break; 843882527734SSukumar Swaminathan 843982527734SSukumar Swaminathan case EMLXS_CQ_RCV: 844082527734SSukumar Swaminathan /* Second CQ is for unsol receive handling */ 844182527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 844282527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 844382527734SSukumar Swaminathan break; 844482527734SSukumar Swaminathan 844582527734SSukumar Swaminathan default: 844682527734SSukumar Swaminathan /* Setup CQ to channel mapping */ 844782527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].type = 844882527734SSukumar Swaminathan EMLXS_CQ_TYPE_GROUP2; 844982527734SSukumar Swaminathan hba->sli.sli4.cq[total_cq].channelp = 845082527734SSukumar Swaminathan &hba->chan[total_cq - EMLXS_CQ_OFFSET_WQ]; 845182527734SSukumar Swaminathan break; 845282527734SSukumar Swaminathan } 8453*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "CQX_CREATE", (uint32_t *)mb, 8454*8f23e9faSHans Rosenfeld 18, 0); 845582527734SSukumar Swaminathan total_cq++; 845682527734SSukumar Swaminathan } 845782527734SSukumar Swaminathan 8458*8f23e9faSHans Rosenfeld /* Create WQ's */ 845982527734SSukumar Swaminathan for (j = 0; j < num_wq; j++) { 846082527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 846182527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 846282527734SSukumar Swaminathan 846382527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 846482527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq + EMLXS_CQ_OFFSET_WQ].qid; 846582527734SSukumar Swaminathan 846682527734SSukumar Swaminathan emlxs_mb_wq_create(hba, mbq, total_wq); 846782527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 846882527734SSukumar Swaminathan MBX_SUCCESS) { 846982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, 847082527734SSukumar Swaminathan &emlxs_init_failed_msg, "Unable to Create " 847182527734SSukumar Swaminathan "WQ %d: Mailbox cmd=%x status=%x ", 847282527734SSukumar Swaminathan total_wq, mb->mbxCommand, mb->mbxStatus); 847382527734SSukumar Swaminathan return (EIO); 847482527734SSukumar Swaminathan } 847582527734SSukumar Swaminathan wq = (IOCTL_FCOE_WQ_CREATE *) 847682527734SSukumar Swaminathan &mb->un.varSLIConfig.payload; 847782527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].qid = 847882527734SSukumar Swaminathan wq->params.response.WQId; 847982527734SSukumar Swaminathan 848082527734SSukumar Swaminathan hba->sli.sli4.wq[total_wq].cqid = 848182527734SSukumar Swaminathan hba->sli.sli4.cq[total_wq+EMLXS_CQ_OFFSET_WQ].qid; 8482*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "WQ_CREATE", (uint32_t *)mb, 8483*8f23e9faSHans Rosenfeld 18, 0); 848482527734SSukumar Swaminathan total_wq++; 848582527734SSukumar Swaminathan } 8486a9800bebSGarrett D'Amore hba->last_msiid = i; 848782527734SSukumar Swaminathan } 848882527734SSukumar Swaminathan 848982527734SSukumar Swaminathan /* We assume 1 RQ pair will handle ALL incoming data */ 849082527734SSukumar Swaminathan /* Create RQs */ 849182527734SSukumar Swaminathan for (i = 0; i < EMLXS_MAX_RQS; i++) { 849282527734SSukumar Swaminathan /* Personalize the RQ */ 849382527734SSukumar Swaminathan switch (i) { 849482527734SSukumar Swaminathan case 0: 849582527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 849682527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 849782527734SSukumar Swaminathan break; 849882527734SSukumar Swaminathan case 1: 849982527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 850082527734SSukumar Swaminathan hba->sli.sli4.cq[EMLXS_CQ_RCV].qid; 850182527734SSukumar Swaminathan break; 850282527734SSukumar Swaminathan default: 850382527734SSukumar Swaminathan hba->sli.sli4.rq[i].cqid = 0xffff; 850482527734SSukumar Swaminathan } 850582527734SSukumar Swaminathan 850682527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 850782527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 850882527734SSukumar Swaminathan 850982527734SSukumar Swaminathan emlxs_mb_rq_create(hba, mbq, i); 851082527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 851182527734SSukumar Swaminathan MBX_SUCCESS) { 851282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 851382527734SSukumar Swaminathan "Unable to Create RQ %d: Mailbox cmd=%x status=%x ", 851482527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 851582527734SSukumar Swaminathan return (EIO); 851682527734SSukumar Swaminathan } 8517*8f23e9faSHans Rosenfeld 851882527734SSukumar Swaminathan rq = (IOCTL_FCOE_RQ_CREATE *)&mb->un.varSLIConfig.payload; 851982527734SSukumar Swaminathan hba->sli.sli4.rq[i].qid = rq->params.response.RQId; 8520*8f23e9faSHans Rosenfeld emlxs_data_dump(port, "RQ CREATE", (uint32_t *)mb, 18, 0); 852182527734SSukumar Swaminathan 852282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 852382527734SSukumar Swaminathan "RQ CREATE: rq[%d].qid=%d cqid=%d", 852482527734SSukumar Swaminathan i, hba->sli.sli4.rq[i].qid, hba->sli.sli4.rq[i].cqid); 852582527734SSukumar Swaminathan 852682527734SSukumar Swaminathan /* Initialize the host_index */ 852782527734SSukumar Swaminathan hba->sli.sli4.rq[i].host_index = 0; 852882527734SSukumar Swaminathan 852982527734SSukumar Swaminathan /* If Data queue was just created, */ 853082527734SSukumar Swaminathan /* then post buffers using the header qid */ 853182527734SSukumar Swaminathan if ((i & 0x1)) { 853282527734SSukumar Swaminathan /* Ring the RQ doorbell to post buffers */ 853382527734SSukumar Swaminathan rqdb.word = 0; 853482527734SSukumar Swaminathan rqdb.db.Qid = hba->sli.sli4.rq[i-1].qid; 853582527734SSukumar Swaminathan rqdb.db.NumPosted = RQB_COUNT; 853682527734SSukumar Swaminathan 8537*8f23e9faSHans Rosenfeld emlxs_sli4_write_rqdb(hba, rqdb.word); 853882527734SSukumar Swaminathan 853982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 854082527734SSukumar Swaminathan "RQ CREATE: Doorbell rang: qid=%d count=%d", 854182527734SSukumar Swaminathan hba->sli.sli4.rq[i-1].qid, RQB_COUNT); 854282527734SSukumar Swaminathan } 854382527734SSukumar Swaminathan } 854482527734SSukumar Swaminathan 854582527734SSukumar Swaminathan /* Create MQ */ 854682527734SSukumar Swaminathan 854782527734SSukumar Swaminathan /* Personalize the MQ */ 854882527734SSukumar Swaminathan hba->sli.sli4.mq.cqid = hba->sli.sli4.cq[EMLXS_CQ_MBOX].qid; 854982527734SSukumar Swaminathan 855082527734SSukumar Swaminathan /* Reuse mbq from previous mbox */ 855182527734SSukumar Swaminathan bzero(mbq, sizeof (MAILBOXQ)); 855282527734SSukumar Swaminathan 8553*8f23e9faSHans Rosenfeld emlxs_mb_mq_create_ext(hba, mbq); 855482527734SSukumar Swaminathan if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 855582527734SSukumar Swaminathan MBX_SUCCESS) { 855682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 8557*8f23e9faSHans Rosenfeld "Unable to Create MQ_EXT %d: Mailbox cmd=%x status=%x ", 855882527734SSukumar Swaminathan i, mb->mbxCommand, mb->mbxStatus); 855982527734SSukumar Swaminathan 8560a9800bebSGarrett D'Amore /* Reuse mbq from previous mbox */ 8561a9800bebSGarrett D'Amore bzero(mbq, sizeof (MAILBOXQ)); 856282527734SSukumar Swaminathan 8563a9800bebSGarrett D'Amore emlxs_mb_mq_create(hba, mbq); 8564a9800bebSGarrett D'Amore if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != 8565a9800bebSGarrett D'Amore MBX_SUCCESS) { 8566a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 8567a9800bebSGarrett D'Amore "Unable to Create MQ %d: Mailbox cmd=%x status=%x ", 8568a9800bebSGarrett D'Amore i, mb->mbxCommand, mb->mbxStatus); 8569a9800bebSGarrett D'Amore return (EIO); 8570a9800bebSGarrett D'Amore } 857182527734SSukumar Swaminathan 8572a9800bebSGarrett D'Amore mq = (IOCTL_COMMON_MQ_CREATE *)&mb->un.varSLIConfig.payload; 8573a9800bebSGarrett D'Amore hba->sli.sli4.mq.qid = mq->params.response.MQId; 857482527734SSukumar Swaminathan return (0); 857582527734SSukumar Swaminathan } 857682527734SSukumar Swaminathan 8577*8f23e9faSHans Rosenfeld mq_ext = (IOCTL_COMMON_MQ_CREATE_EXT *)&mb->un.varSLIConfig.payload; 8578*8f23e9faSHans Rosenfeld hba->sli.sli4.mq.qid = mq_ext->params.response.MQId; 857982527734SSukumar Swaminathan return (0); 858082527734SSukumar Swaminathan 8581a9800bebSGarrett D'Amore } /* emlxs_sli4_create_queues() */ 858282527734SSukumar Swaminathan 858382527734SSukumar Swaminathan 858482527734SSukumar Swaminathan extern void 858582527734SSukumar Swaminathan emlxs_sli4_timer(emlxs_hba_t *hba) 858682527734SSukumar Swaminathan { 858782527734SSukumar Swaminathan /* Perform SLI4 level timer checks */ 858882527734SSukumar Swaminathan 8589a9800bebSGarrett D'Amore emlxs_fcf_timer_notify(hba); 8590a9800bebSGarrett D'Amore 859182527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(hba); 859282527734SSukumar Swaminathan 859382527734SSukumar Swaminathan return; 859482527734SSukumar Swaminathan 859582527734SSukumar Swaminathan } /* emlxs_sli4_timer() */ 859682527734SSukumar Swaminathan 859782527734SSukumar Swaminathan 859882527734SSukumar Swaminathan static void 859982527734SSukumar Swaminathan emlxs_sli4_timer_check_mbox(emlxs_hba_t *hba) 860082527734SSukumar Swaminathan { 860182527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 860282527734SSukumar Swaminathan emlxs_config_t *cfg = &CFG; 860382527734SSukumar Swaminathan MAILBOX *mb = NULL; 860482527734SSukumar Swaminathan 860582527734SSukumar Swaminathan if (!cfg[CFG_TIMEOUT_ENABLE].current) { 860682527734SSukumar Swaminathan return; 860782527734SSukumar Swaminathan } 860882527734SSukumar Swaminathan 860982527734SSukumar Swaminathan mutex_enter(&EMLXS_PORT_LOCK); 861082527734SSukumar Swaminathan 861182527734SSukumar Swaminathan /* Return if timer hasn't expired */ 861282527734SSukumar Swaminathan if (!hba->mbox_timer || (hba->timer_tics < hba->mbox_timer)) { 861382527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 861482527734SSukumar Swaminathan return; 861582527734SSukumar Swaminathan } 8616a9800bebSGarrett D'Amore 8617a9800bebSGarrett D'Amore /* The first to service the mbox queue will clear the timer */ 861882527734SSukumar Swaminathan hba->mbox_timer = 0; 861982527734SSukumar Swaminathan 862082527734SSukumar Swaminathan if (hba->mbox_queue_flag) { 862182527734SSukumar Swaminathan if (hba->mbox_mbq) { 862282527734SSukumar Swaminathan mb = (MAILBOX *)hba->mbox_mbq; 862382527734SSukumar Swaminathan } 862482527734SSukumar Swaminathan } 862582527734SSukumar Swaminathan 862682527734SSukumar Swaminathan if (mb) { 862782527734SSukumar Swaminathan switch (hba->mbox_queue_flag) { 862882527734SSukumar Swaminathan case MBX_NOWAIT: 862982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 863082527734SSukumar Swaminathan "%s: Nowait.", 863182527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand)); 863282527734SSukumar Swaminathan break; 863382527734SSukumar Swaminathan 863482527734SSukumar Swaminathan case MBX_SLEEP: 863582527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 863682527734SSukumar Swaminathan "%s: mb=%p Sleep.", 863782527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 863882527734SSukumar Swaminathan mb); 863982527734SSukumar Swaminathan break; 864082527734SSukumar Swaminathan 864182527734SSukumar Swaminathan case MBX_POLL: 864282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 864382527734SSukumar Swaminathan "%s: mb=%p Polled.", 864482527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 864582527734SSukumar Swaminathan mb); 864682527734SSukumar Swaminathan break; 864782527734SSukumar Swaminathan 864882527734SSukumar Swaminathan default: 864982527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, 865082527734SSukumar Swaminathan "%s: mb=%p (%d).", 865182527734SSukumar Swaminathan emlxs_mb_cmd_xlate(mb->mbxCommand), 865282527734SSukumar Swaminathan mb, hba->mbox_queue_flag); 865382527734SSukumar Swaminathan break; 865482527734SSukumar Swaminathan } 865582527734SSukumar Swaminathan } else { 865682527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, NULL); 865782527734SSukumar Swaminathan } 865882527734SSukumar Swaminathan 865982527734SSukumar Swaminathan hba->flag |= FC_MBOX_TIMEOUT; 866082527734SSukumar Swaminathan EMLXS_STATE_CHANGE_LOCKED(hba, FC_ERROR); 866182527734SSukumar Swaminathan 866282527734SSukumar Swaminathan mutex_exit(&EMLXS_PORT_LOCK); 866382527734SSukumar Swaminathan 866482527734SSukumar Swaminathan /* Perform mailbox cleanup */ 866582527734SSukumar Swaminathan /* This will wake any sleeping or polling threads */ 866682527734SSukumar Swaminathan emlxs_mb_fini(hba, NULL, MBX_TIMEOUT); 866782527734SSukumar Swaminathan 866882527734SSukumar Swaminathan /* Trigger adapter shutdown */ 8669a9800bebSGarrett D'Amore emlxs_thread_spawn(hba, emlxs_shutdown_thread, 0, 0); 867082527734SSukumar Swaminathan 867182527734SSukumar Swaminathan return; 867282527734SSukumar Swaminathan 867382527734SSukumar Swaminathan } /* emlxs_sli4_timer_check_mbox() */ 867482527734SSukumar Swaminathan 867582527734SSukumar Swaminathan 867682527734SSukumar Swaminathan extern void 8677a9800bebSGarrett D'Amore emlxs_data_dump(emlxs_port_t *port, char *str, uint32_t *iptr, int cnt, int err) 867882527734SSukumar Swaminathan { 867982527734SSukumar Swaminathan void *msg; 868082527734SSukumar Swaminathan 8681*8f23e9faSHans Rosenfeld if (!port || !str || !iptr || !cnt) { 8682*8f23e9faSHans Rosenfeld return; 8683*8f23e9faSHans Rosenfeld } 8684*8f23e9faSHans Rosenfeld 868582527734SSukumar Swaminathan if (err) { 868682527734SSukumar Swaminathan msg = &emlxs_sli_err_msg; 868782527734SSukumar Swaminathan } else { 868882527734SSukumar Swaminathan msg = &emlxs_sli_detail_msg; 868982527734SSukumar Swaminathan } 869082527734SSukumar Swaminathan 869182527734SSukumar Swaminathan if (cnt) { 869282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 8693*8f23e9faSHans Rosenfeld "%s00: %08x %08x %08x %08x %08x %08x", str, *iptr, 869482527734SSukumar Swaminathan *(iptr+1), *(iptr+2), *(iptr+3), *(iptr+4), *(iptr+5)); 869582527734SSukumar Swaminathan } 869682527734SSukumar Swaminathan if (cnt > 6) { 869782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 8698*8f23e9faSHans Rosenfeld "%s06: %08x %08x %08x %08x %08x %08x", str, *(iptr+6), 869982527734SSukumar Swaminathan *(iptr+7), *(iptr+8), *(iptr+9), *(iptr+10), *(iptr+11)); 870082527734SSukumar Swaminathan } 870182527734SSukumar Swaminathan if (cnt > 12) { 870282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 870382527734SSukumar Swaminathan "%s12: %08x %08x %08x %08x %08x %08x", str, *(iptr+12), 870482527734SSukumar Swaminathan *(iptr+13), *(iptr+14), *(iptr+15), *(iptr+16), *(iptr+17)); 870582527734SSukumar Swaminathan } 870682527734SSukumar Swaminathan if (cnt > 18) { 870782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 870882527734SSukumar Swaminathan "%s18: %08x %08x %08x %08x %08x %08x", str, *(iptr+18), 870982527734SSukumar Swaminathan *(iptr+19), *(iptr+20), *(iptr+21), *(iptr+22), *(iptr+23)); 871082527734SSukumar Swaminathan } 871182527734SSukumar Swaminathan if (cnt > 24) { 871282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 871382527734SSukumar Swaminathan "%s24: %08x %08x %08x %08x %08x %08x", str, *(iptr+24), 871482527734SSukumar Swaminathan *(iptr+25), *(iptr+26), *(iptr+27), *(iptr+28), *(iptr+29)); 871582527734SSukumar Swaminathan } 871682527734SSukumar Swaminathan if (cnt > 30) { 871782527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 871882527734SSukumar Swaminathan "%s30: %08x %08x %08x %08x %08x %08x", str, *(iptr+30), 871982527734SSukumar Swaminathan *(iptr+31), *(iptr+32), *(iptr+33), *(iptr+34), *(iptr+35)); 872082527734SSukumar Swaminathan } 872182527734SSukumar Swaminathan if (cnt > 36) { 872282527734SSukumar Swaminathan EMLXS_MSGF(EMLXS_CONTEXT, msg, 872382527734SSukumar Swaminathan "%s36: %08x %08x %08x %08x %08x %08x", str, *(iptr+36), 872482527734SSukumar Swaminathan *(iptr+37), *(iptr+38), *(iptr+39), *(iptr+40), *(iptr+41)); 872582527734SSukumar Swaminathan } 872682527734SSukumar Swaminathan 872782527734SSukumar Swaminathan } /* emlxs_data_dump() */ 872882527734SSukumar Swaminathan 872982527734SSukumar Swaminathan 873082527734SSukumar Swaminathan extern void 873182527734SSukumar Swaminathan emlxs_ue_dump(emlxs_hba_t *hba, char *str) 873282527734SSukumar Swaminathan { 873382527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 8734*8f23e9faSHans Rosenfeld uint32_t status; 873582527734SSukumar Swaminathan uint32_t ue_h; 873682527734SSukumar Swaminathan uint32_t ue_l; 873782527734SSukumar Swaminathan uint32_t on1; 873882527734SSukumar Swaminathan uint32_t on2; 873982527734SSukumar Swaminathan 8740*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 8741*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 8742*8f23e9faSHans Rosenfeld ue_l = ddi_get32(hba->pci_acc_handle, 8743*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 8744*8f23e9faSHans Rosenfeld ue_h = ddi_get32(hba->pci_acc_handle, 8745*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 874682527734SSukumar Swaminathan 8747*8f23e9faSHans Rosenfeld on1 = ddi_get32(hba->pci_acc_handle, 8748*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE1)); 8749*8f23e9faSHans Rosenfeld on2 = ddi_get32(hba->pci_acc_handle, 8750*8f23e9faSHans Rosenfeld (uint32_t *)(hba->pci_addr + PCICFG_UE_STATUS_ONLINE2)); 8751*8f23e9faSHans Rosenfeld 8752*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8753*8f23e9faSHans Rosenfeld "%s: ueLow:%08x ueHigh:%08x on1:%08x on2:%08x", str, 8754*8f23e9faSHans Rosenfeld ue_l, ue_h, on1, on2); 8755*8f23e9faSHans Rosenfeld break; 8756*8f23e9faSHans Rosenfeld 8757*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 8758*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8759*8f23e9faSHans Rosenfeld hba->sli.sli4.STATUS_reg_addr); 8760*8f23e9faSHans Rosenfeld 8761*8f23e9faSHans Rosenfeld ue_l = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8762*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 8763*8f23e9faSHans Rosenfeld ue_h = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8764*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 8765*8f23e9faSHans Rosenfeld 8766*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8767*8f23e9faSHans Rosenfeld "%s: status:%08x err1:%08x err2:%08x", str, 8768*8f23e9faSHans Rosenfeld status, ue_l, ue_h); 8769*8f23e9faSHans Rosenfeld 8770*8f23e9faSHans Rosenfeld break; 8771*8f23e9faSHans Rosenfeld } 877282527734SSukumar Swaminathan 877382527734SSukumar Swaminathan #ifdef FMA_SUPPORT 877482527734SSukumar Swaminathan /* Access handle validation */ 877582527734SSukumar Swaminathan EMLXS_CHK_ACC_HANDLE(hba, hba->pci_acc_handle); 877682527734SSukumar Swaminathan #endif /* FMA_SUPPORT */ 877782527734SSukumar Swaminathan 877882527734SSukumar Swaminathan } /* emlxs_ue_dump() */ 877982527734SSukumar Swaminathan 878082527734SSukumar Swaminathan 8781a9800bebSGarrett D'Amore static void 878282527734SSukumar Swaminathan emlxs_sli4_poll_erratt(emlxs_hba_t *hba) 878382527734SSukumar Swaminathan { 878482527734SSukumar Swaminathan emlxs_port_t *port = &PPORT; 8785*8f23e9faSHans Rosenfeld uint32_t status; 878682527734SSukumar Swaminathan uint32_t ue_h; 878782527734SSukumar Swaminathan uint32_t ue_l; 8788*8f23e9faSHans Rosenfeld uint32_t error = 0; 878982527734SSukumar Swaminathan 879082527734SSukumar Swaminathan if (hba->flag & FC_HARDWARE_ERROR) { 879182527734SSukumar Swaminathan return; 879282527734SSukumar Swaminathan } 879382527734SSukumar Swaminathan 8794*8f23e9faSHans Rosenfeld switch (hba->sli_intf & SLI_INTF_IF_TYPE_MASK) { 8795*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_0: 8796*8f23e9faSHans Rosenfeld ue_l = ddi_get32(hba->pci_acc_handle, 8797*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 8798*8f23e9faSHans Rosenfeld ue_h = ddi_get32(hba->pci_acc_handle, 8799*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 8800*8f23e9faSHans Rosenfeld 8801*8f23e9faSHans Rosenfeld if ((~hba->sli.sli4.ue_mask_lo & ue_l) || 8802*8f23e9faSHans Rosenfeld (~hba->sli.sli4.ue_mask_hi & ue_h) || 8803*8f23e9faSHans Rosenfeld (hba->sli.sli4.flag & EMLXS_SLI4_HW_ERROR)) { 8804*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg, 8805*8f23e9faSHans Rosenfeld "Host Error: ueLow:%08x ueHigh:%08x maskLow:%08x " 8806*8f23e9faSHans Rosenfeld "maskHigh:%08x flag:%08x", 8807*8f23e9faSHans Rosenfeld ue_l, ue_h, hba->sli.sli4.ue_mask_lo, 8808*8f23e9faSHans Rosenfeld hba->sli.sli4.ue_mask_hi, hba->sli.sli4.flag); 8809*8f23e9faSHans Rosenfeld 8810*8f23e9faSHans Rosenfeld error = 2; 8811*8f23e9faSHans Rosenfeld } 8812*8f23e9faSHans Rosenfeld break; 8813*8f23e9faSHans Rosenfeld 8814*8f23e9faSHans Rosenfeld case SLI_INTF_IF_TYPE_2: 8815*8f23e9faSHans Rosenfeld status = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8816*8f23e9faSHans Rosenfeld hba->sli.sli4.STATUS_reg_addr); 8817*8f23e9faSHans Rosenfeld 8818*8f23e9faSHans Rosenfeld if ((status & SLI_STATUS_ERROR) || 8819*8f23e9faSHans Rosenfeld (hba->sli.sli4.flag & EMLXS_SLI4_HW_ERROR)) { 8820*8f23e9faSHans Rosenfeld ue_l = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8821*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR1_reg_addr); 8822*8f23e9faSHans Rosenfeld ue_h = ddi_get32(hba->sli.sli4.bar0_acc_handle, 8823*8f23e9faSHans Rosenfeld hba->sli.sli4.ERR2_reg_addr); 8824*8f23e9faSHans Rosenfeld 8825*8f23e9faSHans Rosenfeld error = (status & SLI_STATUS_RESET_NEEDED)? 1:2; 882682527734SSukumar Swaminathan 8827*8f23e9faSHans Rosenfeld if (error == 1) { 8828*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_debug_msg, 8829*8f23e9faSHans Rosenfeld "Host Error: status:%08x err1:%08x " 8830*8f23e9faSHans Rosenfeld "err2:%08x flag:%08x", 8831*8f23e9faSHans Rosenfeld status, ue_l, ue_h, hba->sli.sli4.flag); 8832*8f23e9faSHans Rosenfeld } else { 8833*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, 8834*8f23e9faSHans Rosenfeld &emlxs_hardware_error_msg, 8835*8f23e9faSHans Rosenfeld "Host Error: status:%08x err1:%08x " 8836*8f23e9faSHans Rosenfeld "err2:%08x flag:%08x", 8837*8f23e9faSHans Rosenfeld status, ue_l, ue_h, hba->sli.sli4.flag); 8838*8f23e9faSHans Rosenfeld } 8839*8f23e9faSHans Rosenfeld } 8840*8f23e9faSHans Rosenfeld break; 8841*8f23e9faSHans Rosenfeld } 884282527734SSukumar Swaminathan 8843*8f23e9faSHans Rosenfeld if (error == 2) { 884482527734SSukumar Swaminathan EMLXS_STATE_CHANGE(hba, FC_ERROR); 884582527734SSukumar Swaminathan 884682527734SSukumar Swaminathan emlxs_sli4_hba_flush_chipq(hba); 884782527734SSukumar Swaminathan 8848a9800bebSGarrett D'Amore emlxs_thread_spawn(hba, emlxs_shutdown_thread, 0, 0); 8849*8f23e9faSHans Rosenfeld 8850*8f23e9faSHans Rosenfeld } else if (error == 1) { 8851*8f23e9faSHans Rosenfeld EMLXS_STATE_CHANGE(hba, FC_ERROR); 8852*8f23e9faSHans Rosenfeld 8853*8f23e9faSHans Rosenfeld emlxs_sli4_hba_flush_chipq(hba); 8854*8f23e9faSHans Rosenfeld 8855*8f23e9faSHans Rosenfeld emlxs_thread_spawn(hba, emlxs_restart_thread, 0, 0); 885682527734SSukumar Swaminathan } 885782527734SSukumar Swaminathan 8858*8f23e9faSHans Rosenfeld #ifdef FMA_SUPPORT 8859*8f23e9faSHans Rosenfeld /* Access handle validation */ 8860*8f23e9faSHans Rosenfeld EMLXS_CHK_ACC_HANDLE(hba, hba->pci_acc_handle); 8861*8f23e9faSHans Rosenfeld #endif /* FMA_SUPPORT */ 8862*8f23e9faSHans Rosenfeld 886382527734SSukumar Swaminathan } /* emlxs_sli4_poll_erratt() */ 886482527734SSukumar Swaminathan 8865a9800bebSGarrett D'Amore 8866*8f23e9faSHans Rosenfeld static uint32_t 8867a9800bebSGarrett D'Amore emlxs_sli4_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param, 8868a9800bebSGarrett D'Amore emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq) 886982527734SSukumar Swaminathan { 887082527734SSukumar Swaminathan emlxs_hba_t *hba = HBA; 8871a9800bebSGarrett D'Amore NODELIST *node; 8872a9800bebSGarrett D'Amore RPIobj_t *rpip; 8873a9800bebSGarrett D'Amore uint32_t rval; 8874a9800bebSGarrett D'Amore 8875a9800bebSGarrett D'Amore /* Check for invalid node ids to register */ 8876a9800bebSGarrett D'Amore if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) { 8877a9800bebSGarrett D'Amore return (1); 8878a9800bebSGarrett D'Amore } 8879a9800bebSGarrett D'Amore 8880a9800bebSGarrett D'Amore if (did & 0xff000000) { 8881a9800bebSGarrett D'Amore return (1); 8882a9800bebSGarrett D'Amore } 8883a9800bebSGarrett D'Amore 8884*8f23e9faSHans Rosenfeld /* We don't register our own did */ 8885*8f23e9faSHans Rosenfeld if ((did == port->did) && (!(hba->flag & FC_LOOPBACK_MODE))) { 8886a9800bebSGarrett D'Amore return (1); 8887a9800bebSGarrett D'Amore } 8888a9800bebSGarrett D'Amore 8889*8f23e9faSHans Rosenfeld if (did != FABRIC_DID) { 8890*8f23e9faSHans Rosenfeld if ((rval = emlxs_mb_check_sparm(hba, param))) { 8891*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 8892*8f23e9faSHans Rosenfeld "Invalid service parameters. did=%06x rval=%d", did, 8893*8f23e9faSHans Rosenfeld rval); 8894*8f23e9faSHans Rosenfeld 8895*8f23e9faSHans Rosenfeld return (1); 8896*8f23e9faSHans Rosenfeld } 8897*8f23e9faSHans Rosenfeld } 8898*8f23e9faSHans Rosenfeld 8899a9800bebSGarrett D'Amore /* Check if the node limit has been reached */ 8900a9800bebSGarrett D'Amore if (port->node_count >= hba->max_nodes) { 8901a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg, 8902a9800bebSGarrett D'Amore "Limit reached. did=%06x count=%d", did, 8903a9800bebSGarrett D'Amore port->node_count); 8904a9800bebSGarrett D'Amore 8905a9800bebSGarrett D'Amore return (1); 8906a9800bebSGarrett D'Amore } 8907a9800bebSGarrett D'Amore 8908*8f23e9faSHans Rosenfeld node = emlxs_node_find_did(port, did, 1); 8909a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 8910a9800bebSGarrett D'Amore 8911a9800bebSGarrett D'Amore rval = emlxs_rpi_online_notify(port, rpip, did, param, (void *)sbp, 8912a9800bebSGarrett D'Amore (void *)ubp, (void *)iocbq); 8913a9800bebSGarrett D'Amore 8914a9800bebSGarrett D'Amore return (rval); 8915a9800bebSGarrett D'Amore 8916a9800bebSGarrett D'Amore } /* emlxs_sli4_reg_did() */ 8917a9800bebSGarrett D'Amore 8918a9800bebSGarrett D'Amore 8919*8f23e9faSHans Rosenfeld static uint32_t 8920a9800bebSGarrett D'Amore emlxs_sli4_unreg_node(emlxs_port_t *port, emlxs_node_t *node, 8921a9800bebSGarrett D'Amore emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq) 8922a9800bebSGarrett D'Amore { 8923a9800bebSGarrett D'Amore RPIobj_t *rpip; 8924a9800bebSGarrett D'Amore uint32_t rval; 8925a9800bebSGarrett D'Amore 8926a9800bebSGarrett D'Amore if (!node) { 8927a9800bebSGarrett D'Amore /* Unreg all nodes */ 8928a9800bebSGarrett D'Amore (void) emlxs_sli4_unreg_all_nodes(port); 8929a9800bebSGarrett D'Amore return (1); 8930a9800bebSGarrett D'Amore } 8931a9800bebSGarrett D'Amore 8932a9800bebSGarrett D'Amore /* Check for base node */ 8933a9800bebSGarrett D'Amore if (node == &port->node_base) { 8934a9800bebSGarrett D'Amore /* Just flush base node */ 8935a9800bebSGarrett D'Amore (void) emlxs_tx_node_flush(port, &port->node_base, 8936a9800bebSGarrett D'Amore 0, 0, 0); 8937a9800bebSGarrett D'Amore 8938a9800bebSGarrett D'Amore (void) emlxs_chipq_node_flush(port, 0, 8939a9800bebSGarrett D'Amore &port->node_base, 0); 8940a9800bebSGarrett D'Amore 8941a9800bebSGarrett D'Amore port->did = 0; 8942a9800bebSGarrett D'Amore 8943a9800bebSGarrett D'Amore /* Return now */ 8944a9800bebSGarrett D'Amore return (1); 8945a9800bebSGarrett D'Amore } 8946a9800bebSGarrett D'Amore 8947a9800bebSGarrett D'Amore EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8948a9800bebSGarrett D'Amore "unreg_node:%p did=%x rpi=%d", 8949a9800bebSGarrett D'Amore node, node->nlp_DID, node->nlp_Rpi); 8950a9800bebSGarrett D'Amore 8951a9800bebSGarrett D'Amore rpip = EMLXS_NODE_TO_RPI(port, node); 8952a9800bebSGarrett D'Amore 8953a9800bebSGarrett D'Amore if (!rpip) { 8954*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 8955a9800bebSGarrett D'Amore "unreg_node:%p did=%x rpi=%d. RPI not found.", 8956a9800bebSGarrett D'Amore node, node->nlp_DID, node->nlp_Rpi); 8957a9800bebSGarrett D'Amore 8958a9800bebSGarrett D'Amore emlxs_node_rm(port, node); 8959a9800bebSGarrett D'Amore return (1); 8960a9800bebSGarrett D'Amore } 8961a9800bebSGarrett D'Amore 8962a9800bebSGarrett D'Amore rval = emlxs_rpi_offline_notify(port, rpip, (void *)sbp, (void *)ubp, 8963a9800bebSGarrett D'Amore (void *)iocbq); 8964a9800bebSGarrett D'Amore 8965a9800bebSGarrett D'Amore return (rval); 8966a9800bebSGarrett D'Amore 8967a9800bebSGarrett D'Amore } /* emlxs_sli4_unreg_node() */ 8968a9800bebSGarrett D'Amore 8969a9800bebSGarrett D'Amore 8970a9800bebSGarrett D'Amore extern uint32_t 8971a9800bebSGarrett D'Amore emlxs_sli4_unreg_all_nodes(emlxs_port_t *port) 8972a9800bebSGarrett D'Amore { 897382527734SSukumar Swaminathan NODELIST *nlp; 897482527734SSukumar Swaminathan int i; 8975a9800bebSGarrett D'Amore uint32_t found; 897682527734SSukumar Swaminathan 8977a9800bebSGarrett D'Amore /* Set the node tags */ 8978a9800bebSGarrett D'Amore /* We will process all nodes with this tag */ 8979a9800bebSGarrett D'Amore rw_enter(&port->node_rwlock, RW_READER); 8980a9800bebSGarrett D'Amore found = 0; 898182527734SSukumar Swaminathan for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 898282527734SSukumar Swaminathan nlp = port->node_table[i]; 898382527734SSukumar Swaminathan while (nlp != NULL) { 8984a9800bebSGarrett D'Amore found = 1; 8985a9800bebSGarrett D'Amore nlp->nlp_tag = 1; 8986a9800bebSGarrett D'Amore nlp = nlp->nlp_list_next; 898782527734SSukumar Swaminathan } 898882527734SSukumar Swaminathan } 898982527734SSukumar Swaminathan rw_exit(&port->node_rwlock); 899082527734SSukumar Swaminathan 8991a9800bebSGarrett D'Amore if (!found) { 8992a9800bebSGarrett D'Amore return (0); 8993a9800bebSGarrett D'Amore } 8994a9800bebSGarrett D'Amore 8995a9800bebSGarrett D'Amore for (;;) { 8996a9800bebSGarrett D'Amore rw_enter(&port->node_rwlock, RW_READER); 8997a9800bebSGarrett D'Amore found = 0; 8998a9800bebSGarrett D'Amore for (i = 0; i < EMLXS_NUM_HASH_QUES; i++) { 8999a9800bebSGarrett D'Amore nlp = port->node_table[i]; 9000a9800bebSGarrett D'Amore while (nlp != NULL) { 9001a9800bebSGarrett D'Amore if (!nlp->nlp_tag) { 9002a9800bebSGarrett D'Amore nlp = nlp->nlp_list_next; 9003a9800bebSGarrett D'Amore continue; 9004a9800bebSGarrett D'Amore } 9005a9800bebSGarrett D'Amore nlp->nlp_tag = 0; 9006a9800bebSGarrett D'Amore found = 1; 9007a9800bebSGarrett D'Amore break; 9008a9800bebSGarrett D'Amore } 9009a9800bebSGarrett D'Amore 9010a9800bebSGarrett D'Amore if (found) { 9011a9800bebSGarrett D'Amore break; 9012a9800bebSGarrett D'Amore } 9013a9800bebSGarrett D'Amore } 9014a9800bebSGarrett D'Amore rw_exit(&port->node_rwlock); 9015a9800bebSGarrett D'Amore 9016a9800bebSGarrett D'Amore if (!found) { 9017a9800bebSGarrett D'Amore break; 9018a9800bebSGarrett D'Amore } 9019a9800bebSGarrett D'Amore 9020a9800bebSGarrett D'Amore (void) emlxs_sli4_unreg_node(port, nlp, 0, 0, 0); 9021a9800bebSGarrett D'Amore } 9022a9800bebSGarrett D'Amore 902382527734SSukumar Swaminathan return (0); 9024a9800bebSGarrett D'Amore 9025a9800bebSGarrett D'Amore } /* emlxs_sli4_unreg_all_nodes() */ 9026*8f23e9faSHans Rosenfeld 9027*8f23e9faSHans Rosenfeld 9028*8f23e9faSHans Rosenfeld static void 9029*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fcoe_link_event(emlxs_hba_t *hba, CQE_ASYNC_t *cqe) 9030*8f23e9faSHans Rosenfeld { 9031*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 9032*8f23e9faSHans Rosenfeld 9033*8f23e9faSHans Rosenfeld /* Handle link down */ 9034*8f23e9faSHans Rosenfeld if ((cqe->un.link.link_status == ASYNC_EVENT_LOGICAL_LINK_DOWN) || 9035*8f23e9faSHans Rosenfeld (cqe->un.link.link_status == ASYNC_EVENT_PHYS_LINK_DOWN)) { 9036*8f23e9faSHans Rosenfeld (void) emlxs_fcf_linkdown_notify(port); 9037*8f23e9faSHans Rosenfeld 9038*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 9039*8f23e9faSHans Rosenfeld hba->sli.sli4.flag &= ~EMLXS_SLI4_DOWN_LINK; 9040*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 9041*8f23e9faSHans Rosenfeld return; 9042*8f23e9faSHans Rosenfeld } 9043*8f23e9faSHans Rosenfeld 9044*8f23e9faSHans Rosenfeld /* Link is up */ 9045*8f23e9faSHans Rosenfeld 9046*8f23e9faSHans Rosenfeld /* Set linkspeed */ 9047*8f23e9faSHans Rosenfeld switch (cqe->un.link.port_speed) { 9048*8f23e9faSHans Rosenfeld case PHY_1GHZ_LINK: 9049*8f23e9faSHans Rosenfeld hba->linkspeed = LA_1GHZ_LINK; 9050*8f23e9faSHans Rosenfeld break; 9051*8f23e9faSHans Rosenfeld case PHY_10GHZ_LINK: 9052*8f23e9faSHans Rosenfeld hba->linkspeed = LA_10GHZ_LINK; 9053*8f23e9faSHans Rosenfeld break; 9054*8f23e9faSHans Rosenfeld default: 9055*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 9056*8f23e9faSHans Rosenfeld "sli4_handle_fcoe_link_event: Unknown link speed=%x.", 9057*8f23e9faSHans Rosenfeld cqe->un.link.port_speed); 9058*8f23e9faSHans Rosenfeld hba->linkspeed = 0; 9059*8f23e9faSHans Rosenfeld break; 9060*8f23e9faSHans Rosenfeld } 9061*8f23e9faSHans Rosenfeld 9062*8f23e9faSHans Rosenfeld /* Set qos_linkspeed */ 9063*8f23e9faSHans Rosenfeld hba->qos_linkspeed = cqe->un.link.qos_link_speed; 9064*8f23e9faSHans Rosenfeld 9065*8f23e9faSHans Rosenfeld /* Set topology */ 9066*8f23e9faSHans Rosenfeld hba->topology = TOPOLOGY_PT_PT; 9067*8f23e9faSHans Rosenfeld 9068*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 9069*8f23e9faSHans Rosenfeld hba->sli.sli4.flag &= ~EMLXS_SLI4_DOWN_LINK; 9070*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 9071*8f23e9faSHans Rosenfeld 9072*8f23e9faSHans Rosenfeld (void) emlxs_fcf_linkup_notify(port); 9073*8f23e9faSHans Rosenfeld 9074*8f23e9faSHans Rosenfeld return; 9075*8f23e9faSHans Rosenfeld 9076*8f23e9faSHans Rosenfeld } /* emlxs_sli4_handle_fcoe_link_event() */ 9077*8f23e9faSHans Rosenfeld 9078*8f23e9faSHans Rosenfeld 9079*8f23e9faSHans Rosenfeld static void 9080*8f23e9faSHans Rosenfeld emlxs_sli4_handle_fc_link_att(emlxs_hba_t *hba, CQE_ASYNC_t *cqe) 9081*8f23e9faSHans Rosenfeld { 9082*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 9083*8f23e9faSHans Rosenfeld 9084*8f23e9faSHans Rosenfeld /* Handle link down */ 9085*8f23e9faSHans Rosenfeld if (cqe->un.fc.att_type == ATT_TYPE_LINK_DOWN) { 9086*8f23e9faSHans Rosenfeld (void) emlxs_fcf_linkdown_notify(port); 9087*8f23e9faSHans Rosenfeld 9088*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 9089*8f23e9faSHans Rosenfeld hba->sli.sli4.flag &= ~EMLXS_SLI4_DOWN_LINK; 9090*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 9091*8f23e9faSHans Rosenfeld return; 9092*8f23e9faSHans Rosenfeld } 9093*8f23e9faSHans Rosenfeld 9094*8f23e9faSHans Rosenfeld /* Link is up */ 9095*8f23e9faSHans Rosenfeld 9096*8f23e9faSHans Rosenfeld /* Set linkspeed */ 9097*8f23e9faSHans Rosenfeld switch (cqe->un.fc.port_speed) { 9098*8f23e9faSHans Rosenfeld case 1: 9099*8f23e9faSHans Rosenfeld hba->linkspeed = LA_1GHZ_LINK; 9100*8f23e9faSHans Rosenfeld break; 9101*8f23e9faSHans Rosenfeld case 2: 9102*8f23e9faSHans Rosenfeld hba->linkspeed = LA_2GHZ_LINK; 9103*8f23e9faSHans Rosenfeld break; 9104*8f23e9faSHans Rosenfeld case 4: 9105*8f23e9faSHans Rosenfeld hba->linkspeed = LA_4GHZ_LINK; 9106*8f23e9faSHans Rosenfeld break; 9107*8f23e9faSHans Rosenfeld case 8: 9108*8f23e9faSHans Rosenfeld hba->linkspeed = LA_8GHZ_LINK; 9109*8f23e9faSHans Rosenfeld break; 9110*8f23e9faSHans Rosenfeld case 10: 9111*8f23e9faSHans Rosenfeld hba->linkspeed = LA_10GHZ_LINK; 9112*8f23e9faSHans Rosenfeld break; 9113*8f23e9faSHans Rosenfeld case 16: 9114*8f23e9faSHans Rosenfeld hba->linkspeed = LA_16GHZ_LINK; 9115*8f23e9faSHans Rosenfeld break; 9116*8f23e9faSHans Rosenfeld default: 9117*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg, 9118*8f23e9faSHans Rosenfeld "sli4_handle_fc_link_att: Unknown link speed=%x.", 9119*8f23e9faSHans Rosenfeld cqe->un.fc.port_speed); 9120*8f23e9faSHans Rosenfeld hba->linkspeed = 0; 9121*8f23e9faSHans Rosenfeld break; 9122*8f23e9faSHans Rosenfeld } 9123*8f23e9faSHans Rosenfeld 9124*8f23e9faSHans Rosenfeld /* Set qos_linkspeed */ 9125*8f23e9faSHans Rosenfeld hba->qos_linkspeed = cqe->un.fc.link_speed; 9126*8f23e9faSHans Rosenfeld 9127*8f23e9faSHans Rosenfeld /* Set topology */ 9128*8f23e9faSHans Rosenfeld hba->topology = cqe->un.fc.topology; 9129*8f23e9faSHans Rosenfeld 9130*8f23e9faSHans Rosenfeld mutex_enter(&EMLXS_PORT_LOCK); 9131*8f23e9faSHans Rosenfeld hba->sli.sli4.flag &= ~EMLXS_SLI4_DOWN_LINK; 9132*8f23e9faSHans Rosenfeld mutex_exit(&EMLXS_PORT_LOCK); 9133*8f23e9faSHans Rosenfeld 9134*8f23e9faSHans Rosenfeld (void) emlxs_fcf_linkup_notify(port); 9135*8f23e9faSHans Rosenfeld 9136*8f23e9faSHans Rosenfeld return; 9137*8f23e9faSHans Rosenfeld 9138*8f23e9faSHans Rosenfeld } /* emlxs_sli4_handle_fc_link_att() */ 9139*8f23e9faSHans Rosenfeld 9140*8f23e9faSHans Rosenfeld 9141*8f23e9faSHans Rosenfeld static int 9142*8f23e9faSHans Rosenfeld emlxs_sli4_init_extents(emlxs_hba_t *hba, MAILBOXQ *mbq) 9143*8f23e9faSHans Rosenfeld { 9144*8f23e9faSHans Rosenfeld emlxs_port_t *port = &PPORT; 9145*8f23e9faSHans Rosenfeld MAILBOX4 *mb4; 9146*8f23e9faSHans Rosenfeld IOCTL_COMMON_EXTENTS *ep; 9147*8f23e9faSHans Rosenfeld uint32_t i; 9148*8f23e9faSHans Rosenfeld uint32_t ExtentCnt; 9149*8f23e9faSHans Rosenfeld 9150*8f23e9faSHans Rosenfeld if (!(hba->sli.sli4.param.EXT)) { 9151*8f23e9faSHans Rosenfeld return (0); 9152*8f23e9faSHans Rosenfeld } 9153*8f23e9faSHans Rosenfeld 9154*8f23e9faSHans Rosenfeld mb4 = (MAILBOX4 *) mbq; 9155*8f23e9faSHans Rosenfeld 9156*8f23e9faSHans Rosenfeld /* Discover XRI Extents */ 9157*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9158*8f23e9faSHans Rosenfeld emlxs_mb_get_extents_info(hba, mbq, RSC_TYPE_FCOE_XRI); 9159*8f23e9faSHans Rosenfeld 9160*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9161*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9162*8f23e9faSHans Rosenfeld "Unable to discover XRI extents. Mailbox cmd=%x status=%x", 9163*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9164*8f23e9faSHans Rosenfeld 9165*8f23e9faSHans Rosenfeld return (EIO); 9166*8f23e9faSHans Rosenfeld } 9167*8f23e9faSHans Rosenfeld 9168*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9169*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtSize = ep->params.response.ExtentSize; 9170*8f23e9faSHans Rosenfeld ExtentCnt = ep->params.response.ExtentCnt; 9171*8f23e9faSHans Rosenfeld 9172*8f23e9faSHans Rosenfeld /* Allocate XRI Extents */ 9173*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9174*8f23e9faSHans Rosenfeld emlxs_mb_alloc_extents(hba, mbq, RSC_TYPE_FCOE_XRI, ExtentCnt); 9175*8f23e9faSHans Rosenfeld 9176*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9177*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9178*8f23e9faSHans Rosenfeld "Unable to allocate XRI extents. Mailbox cmd=%x status=%x", 9179*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9180*8f23e9faSHans Rosenfeld 9181*8f23e9faSHans Rosenfeld return (EIO); 9182*8f23e9faSHans Rosenfeld } 9183*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9184*8f23e9faSHans Rosenfeld 9185*8f23e9faSHans Rosenfeld bcopy((uint8_t *)ep->params.response.RscId, 9186*8f23e9faSHans Rosenfeld (uint8_t *)hba->sli.sli4.XRIBase, 9187*8f23e9faSHans Rosenfeld (ep->params.response.ExtentCnt * sizeof (uint16_t))); 9188*8f23e9faSHans Rosenfeld 9189*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtCount = ep->params.response.ExtentCnt; 9190*8f23e9faSHans Rosenfeld hba->sli.sli4.XRICount = hba->sli.sli4.XRIExtCount * 9191*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtSize; 9192*8f23e9faSHans Rosenfeld 9193*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9194*8f23e9faSHans Rosenfeld "XRI Ext: size=%d cnt=%d/%d", 9195*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtSize, 9196*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIExtCount, ExtentCnt); 9197*8f23e9faSHans Rosenfeld 9198*8f23e9faSHans Rosenfeld for (i = 0; i < ep->params.response.ExtentCnt; i += 4) { 9199*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9200*8f23e9faSHans Rosenfeld "XRI Ext%d: %d, %d, %d, %d", i, 9201*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIBase[i], 9202*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIBase[i+1], 9203*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIBase[i+2], 9204*8f23e9faSHans Rosenfeld hba->sli.sli4.XRIBase[i+3]); 9205*8f23e9faSHans Rosenfeld } 9206*8f23e9faSHans Rosenfeld 9207*8f23e9faSHans Rosenfeld 9208*8f23e9faSHans Rosenfeld /* Discover RPI Extents */ 9209*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9210*8f23e9faSHans Rosenfeld emlxs_mb_get_extents_info(hba, mbq, RSC_TYPE_FCOE_RPI); 9211*8f23e9faSHans Rosenfeld 9212*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9213*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9214*8f23e9faSHans Rosenfeld "Unable to discover RPI extents. Mailbox cmd=%x status=%x", 9215*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9216*8f23e9faSHans Rosenfeld 9217*8f23e9faSHans Rosenfeld return (EIO); 9218*8f23e9faSHans Rosenfeld } 9219*8f23e9faSHans Rosenfeld 9220*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9221*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtSize = ep->params.response.ExtentSize; 9222*8f23e9faSHans Rosenfeld ExtentCnt = ep->params.response.ExtentCnt; 9223*8f23e9faSHans Rosenfeld 9224*8f23e9faSHans Rosenfeld /* Allocate RPI Extents */ 9225*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9226*8f23e9faSHans Rosenfeld emlxs_mb_alloc_extents(hba, mbq, RSC_TYPE_FCOE_RPI, ExtentCnt); 9227*8f23e9faSHans Rosenfeld 9228*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9229*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9230*8f23e9faSHans Rosenfeld "Unable to allocate RPI extents. Mailbox cmd=%x status=%x", 9231*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9232*8f23e9faSHans Rosenfeld 9233*8f23e9faSHans Rosenfeld return (EIO); 9234*8f23e9faSHans Rosenfeld } 9235*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9236*8f23e9faSHans Rosenfeld 9237*8f23e9faSHans Rosenfeld bcopy((uint8_t *)ep->params.response.RscId, 9238*8f23e9faSHans Rosenfeld (uint8_t *)hba->sli.sli4.RPIBase, 9239*8f23e9faSHans Rosenfeld (ep->params.response.ExtentCnt * sizeof (uint16_t))); 9240*8f23e9faSHans Rosenfeld 9241*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtCount = ep->params.response.ExtentCnt; 9242*8f23e9faSHans Rosenfeld hba->sli.sli4.RPICount = hba->sli.sli4.RPIExtCount * 9243*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtSize; 9244*8f23e9faSHans Rosenfeld 9245*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9246*8f23e9faSHans Rosenfeld "RPI Ext: size=%d cnt=%d/%d", 9247*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtSize, 9248*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIExtCount, ExtentCnt); 9249*8f23e9faSHans Rosenfeld 9250*8f23e9faSHans Rosenfeld for (i = 0; i < ep->params.response.ExtentCnt; i += 4) { 9251*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9252*8f23e9faSHans Rosenfeld "RPI Ext%d: %d, %d, %d, %d", i, 9253*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIBase[i], 9254*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIBase[i+1], 9255*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIBase[i+2], 9256*8f23e9faSHans Rosenfeld hba->sli.sli4.RPIBase[i+3]); 9257*8f23e9faSHans Rosenfeld } 9258*8f23e9faSHans Rosenfeld 9259*8f23e9faSHans Rosenfeld 9260*8f23e9faSHans Rosenfeld /* Discover VPI Extents */ 9261*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9262*8f23e9faSHans Rosenfeld emlxs_mb_get_extents_info(hba, mbq, RSC_TYPE_FCOE_VPI); 9263*8f23e9faSHans Rosenfeld 9264*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9265*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9266*8f23e9faSHans Rosenfeld "Unable to discover VPI extents. Mailbox cmd=%x status=%x", 9267*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9268*8f23e9faSHans Rosenfeld 9269*8f23e9faSHans Rosenfeld return (EIO); 9270*8f23e9faSHans Rosenfeld } 9271*8f23e9faSHans Rosenfeld 9272*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9273*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtSize = ep->params.response.ExtentSize; 9274*8f23e9faSHans Rosenfeld ExtentCnt = ep->params.response.ExtentCnt; 9275*8f23e9faSHans Rosenfeld 9276*8f23e9faSHans Rosenfeld /* Allocate VPI Extents */ 9277*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9278*8f23e9faSHans Rosenfeld emlxs_mb_alloc_extents(hba, mbq, RSC_TYPE_FCOE_VPI, ExtentCnt); 9279*8f23e9faSHans Rosenfeld 9280*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9281*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9282*8f23e9faSHans Rosenfeld "Unable to allocate VPI extents. Mailbox cmd=%x status=%x", 9283*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9284*8f23e9faSHans Rosenfeld 9285*8f23e9faSHans Rosenfeld return (EIO); 9286*8f23e9faSHans Rosenfeld } 9287*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9288*8f23e9faSHans Rosenfeld 9289*8f23e9faSHans Rosenfeld bcopy((uint8_t *)ep->params.response.RscId, 9290*8f23e9faSHans Rosenfeld (uint8_t *)hba->sli.sli4.VPIBase, 9291*8f23e9faSHans Rosenfeld (ep->params.response.ExtentCnt * sizeof (uint16_t))); 9292*8f23e9faSHans Rosenfeld 9293*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtCount = ep->params.response.ExtentCnt; 9294*8f23e9faSHans Rosenfeld hba->sli.sli4.VPICount = hba->sli.sli4.VPIExtCount * 9295*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtSize; 9296*8f23e9faSHans Rosenfeld 9297*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9298*8f23e9faSHans Rosenfeld "VPI Ext: size=%d cnt=%d/%d", 9299*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtSize, 9300*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIExtCount, ExtentCnt); 9301*8f23e9faSHans Rosenfeld 9302*8f23e9faSHans Rosenfeld for (i = 0; i < ep->params.response.ExtentCnt; i += 4) { 9303*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9304*8f23e9faSHans Rosenfeld "VPI Ext%d: %d, %d, %d, %d", i, 9305*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIBase[i], 9306*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIBase[i+1], 9307*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIBase[i+2], 9308*8f23e9faSHans Rosenfeld hba->sli.sli4.VPIBase[i+3]); 9309*8f23e9faSHans Rosenfeld } 9310*8f23e9faSHans Rosenfeld 9311*8f23e9faSHans Rosenfeld /* Discover VFI Extents */ 9312*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9313*8f23e9faSHans Rosenfeld emlxs_mb_get_extents_info(hba, mbq, RSC_TYPE_FCOE_VFI); 9314*8f23e9faSHans Rosenfeld 9315*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9316*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9317*8f23e9faSHans Rosenfeld "Unable to discover VFI extents. Mailbox cmd=%x status=%x", 9318*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9319*8f23e9faSHans Rosenfeld 9320*8f23e9faSHans Rosenfeld return (EIO); 9321*8f23e9faSHans Rosenfeld } 9322*8f23e9faSHans Rosenfeld 9323*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9324*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtSize = ep->params.response.ExtentSize; 9325*8f23e9faSHans Rosenfeld ExtentCnt = ep->params.response.ExtentCnt; 9326*8f23e9faSHans Rosenfeld 9327*8f23e9faSHans Rosenfeld /* Allocate VFI Extents */ 9328*8f23e9faSHans Rosenfeld bzero(mbq, sizeof (MAILBOXQ)); 9329*8f23e9faSHans Rosenfeld emlxs_mb_alloc_extents(hba, mbq, RSC_TYPE_FCOE_VFI, ExtentCnt); 9330*8f23e9faSHans Rosenfeld 9331*8f23e9faSHans Rosenfeld if (emlxs_sli4_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) { 9332*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg, 9333*8f23e9faSHans Rosenfeld "Unable to allocate VFI extents. Mailbox cmd=%x status=%x", 9334*8f23e9faSHans Rosenfeld mb4->mbxCommand, mb4->mbxStatus); 9335*8f23e9faSHans Rosenfeld 9336*8f23e9faSHans Rosenfeld return (EIO); 9337*8f23e9faSHans Rosenfeld } 9338*8f23e9faSHans Rosenfeld ep = (IOCTL_COMMON_EXTENTS *)&mb4->un.varSLIConfig.payload; 9339*8f23e9faSHans Rosenfeld 9340*8f23e9faSHans Rosenfeld bcopy((uint8_t *)ep->params.response.RscId, 9341*8f23e9faSHans Rosenfeld (uint8_t *)hba->sli.sli4.VFIBase, 9342*8f23e9faSHans Rosenfeld (ep->params.response.ExtentCnt * sizeof (uint16_t))); 9343*8f23e9faSHans Rosenfeld 9344*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtCount = ep->params.response.ExtentCnt; 9345*8f23e9faSHans Rosenfeld hba->sli.sli4.VFICount = hba->sli.sli4.VFIExtCount * 9346*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtSize; 9347*8f23e9faSHans Rosenfeld 9348*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9349*8f23e9faSHans Rosenfeld "VFI Ext: size=%d cnt=%d/%d", 9350*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtSize, 9351*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIExtCount, ExtentCnt); 9352*8f23e9faSHans Rosenfeld 9353*8f23e9faSHans Rosenfeld for (i = 0; i < ep->params.response.ExtentCnt; i += 4) { 9354*8f23e9faSHans Rosenfeld EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, 9355*8f23e9faSHans Rosenfeld "VFI Ext%d: %d, %d, %d, %d", i, 9356*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIBase[i], 9357*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIBase[i+1], 9358*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIBase[i+2], 9359*8f23e9faSHans Rosenfeld hba->sli.sli4.VFIBase[i+3]); 9360*8f23e9faSHans Rosenfeld } 9361*8f23e9faSHans Rosenfeld 9362*8f23e9faSHans Rosenfeld return (0); 9363*8f23e9faSHans Rosenfeld 9364*8f23e9faSHans Rosenfeld } /* emlxs_sli4_init_extents() */ 9365*8f23e9faSHans Rosenfeld 9366*8f23e9faSHans Rosenfeld 9367*8f23e9faSHans Rosenfeld extern uint32_t 9368*8f23e9faSHans Rosenfeld emlxs_sli4_index_to_rpi(emlxs_hba_t *hba, uint32_t index) 9369*8f23e9faSHans Rosenfeld { 9370*8f23e9faSHans Rosenfeld uint32_t i; 9371*8f23e9faSHans Rosenfeld uint32_t j; 9372*8f23e9faSHans Rosenfeld uint32_t rpi; 9373*8f23e9faSHans Rosenfeld 9374*8f23e9faSHans Rosenfeld i = index / hba->sli.sli4.RPIExtSize; 9375*8f23e9faSHans Rosenfeld j = index % hba->sli.sli4.RPIExtSize; 9376*8f23e9faSHans Rosenfeld rpi = hba->sli.sli4.RPIBase[i] + j; 9377*8f23e9faSHans Rosenfeld 9378*8f23e9faSHans Rosenfeld return (rpi); 9379*8f23e9faSHans Rosenfeld 9380*8f23e9faSHans Rosenfeld } /* emlxs_sli4_index_to_rpi */ 9381*8f23e9faSHans Rosenfeld 9382*8f23e9faSHans Rosenfeld 9383*8f23e9faSHans Rosenfeld extern uint32_t 9384*8f23e9faSHans Rosenfeld emlxs_sli4_rpi_to_index(emlxs_hba_t *hba, uint32_t rpi) 9385*8f23e9faSHans Rosenfeld { 9386*8f23e9faSHans Rosenfeld uint32_t i; 9387*8f23e9faSHans Rosenfeld uint32_t lo; 9388*8f23e9faSHans Rosenfeld uint32_t hi; 9389*8f23e9faSHans Rosenfeld uint32_t index = hba->sli.sli4.RPICount; 9390*8f23e9faSHans Rosenfeld 9391*8f23e9faSHans Rosenfeld for (i = 0; i < hba->sli.sli4.RPIExtCount; i++) { 9392*8f23e9faSHans Rosenfeld lo = hba->sli.sli4.RPIBase[i]; 9393*8f23e9faSHans Rosenfeld hi = lo + hba->sli.sli4.RPIExtSize; 9394*8f23e9faSHans Rosenfeld 9395*8f23e9faSHans Rosenfeld if ((rpi < hi) && (rpi >= lo)) { 9396*8f23e9faSHans Rosenfeld index = (i * hba->sli.sli4.RPIExtSize) + (rpi - lo); 9397*8f23e9faSHans Rosenfeld break; 9398*8f23e9faSHans Rosenfeld } 9399*8f23e9faSHans Rosenfeld } 9400*8f23e9faSHans Rosenfeld 9401*8f23e9faSHans Rosenfeld return (index); 9402*8f23e9faSHans Rosenfeld 9403*8f23e9faSHans Rosenfeld } /* emlxs_sli4_rpi_to_index */ 9404*8f23e9faSHans Rosenfeld 9405*8f23e9faSHans Rosenfeld 9406*8f23e9faSHans Rosenfeld extern uint32_t 9407*8f23e9faSHans Rosenfeld emlxs_sli4_index_to_xri(emlxs_hba_t *hba, uint32_t index) 9408*8f23e9faSHans Rosenfeld { 9409*8f23e9faSHans Rosenfeld uint32_t i; 9410*8f23e9faSHans Rosenfeld uint32_t j; 9411*8f23e9faSHans Rosenfeld uint32_t xri; 9412*8f23e9faSHans Rosenfeld 9413*8f23e9faSHans Rosenfeld i = index / hba->sli.sli4.XRIExtSize; 9414*8f23e9faSHans Rosenfeld j = index % hba->sli.sli4.XRIExtSize; 9415*8f23e9faSHans Rosenfeld xri = hba->sli.sli4.XRIBase[i] + j; 9416*8f23e9faSHans Rosenfeld 9417*8f23e9faSHans Rosenfeld return (xri); 9418*8f23e9faSHans Rosenfeld 9419*8f23e9faSHans Rosenfeld } /* emlxs_sli4_index_to_xri */ 9420*8f23e9faSHans Rosenfeld 9421*8f23e9faSHans Rosenfeld 9422*8f23e9faSHans Rosenfeld 9423*8f23e9faSHans Rosenfeld 9424*8f23e9faSHans Rosenfeld extern uint32_t 9425*8f23e9faSHans Rosenfeld emlxs_sli4_index_to_vpi(emlxs_hba_t *hba, uint32_t index) 9426*8f23e9faSHans Rosenfeld { 9427*8f23e9faSHans Rosenfeld uint32_t i; 9428*8f23e9faSHans Rosenfeld uint32_t j; 9429*8f23e9faSHans Rosenfeld uint32_t vpi; 9430*8f23e9faSHans Rosenfeld 9431*8f23e9faSHans Rosenfeld i = index / hba->sli.sli4.VPIExtSize; 9432*8f23e9faSHans Rosenfeld j = index % hba->sli.sli4.VPIExtSize; 9433*8f23e9faSHans Rosenfeld vpi = hba->sli.sli4.VPIBase[i] + j; 9434*8f23e9faSHans Rosenfeld 9435*8f23e9faSHans Rosenfeld return (vpi); 9436*8f23e9faSHans Rosenfeld 9437*8f23e9faSHans Rosenfeld } /* emlxs_sli4_index_to_vpi */ 9438*8f23e9faSHans Rosenfeld 9439*8f23e9faSHans Rosenfeld 9440*8f23e9faSHans Rosenfeld extern uint32_t 9441*8f23e9faSHans Rosenfeld emlxs_sli4_vpi_to_index(emlxs_hba_t *hba, uint32_t vpi) 9442*8f23e9faSHans Rosenfeld { 9443*8f23e9faSHans Rosenfeld uint32_t i; 9444*8f23e9faSHans Rosenfeld uint32_t lo; 9445*8f23e9faSHans Rosenfeld uint32_t hi; 9446*8f23e9faSHans Rosenfeld uint32_t index = hba->sli.sli4.VPICount; 9447*8f23e9faSHans Rosenfeld 9448*8f23e9faSHans Rosenfeld for (i = 0; i < hba->sli.sli4.VPIExtCount; i++) { 9449*8f23e9faSHans Rosenfeld lo = hba->sli.sli4.VPIBase[i]; 9450*8f23e9faSHans Rosenfeld hi = lo + hba->sli.sli4.VPIExtSize; 9451*8f23e9faSHans Rosenfeld 9452*8f23e9faSHans Rosenfeld if ((vpi < hi) && (vpi >= lo)) { 9453*8f23e9faSHans Rosenfeld index = (i * hba->sli.sli4.VPIExtSize) + (vpi - lo); 9454*8f23e9faSHans Rosenfeld break; 9455*8f23e9faSHans Rosenfeld } 9456*8f23e9faSHans Rosenfeld } 9457*8f23e9faSHans Rosenfeld 9458*8f23e9faSHans Rosenfeld return (index); 9459*8f23e9faSHans Rosenfeld 9460*8f23e9faSHans Rosenfeld } /* emlxs_sli4_vpi_to_index */ 9461*8f23e9faSHans Rosenfeld 9462*8f23e9faSHans Rosenfeld 9463*8f23e9faSHans Rosenfeld 9464*8f23e9faSHans Rosenfeld 9465*8f23e9faSHans Rosenfeld extern uint32_t 9466*8f23e9faSHans Rosenfeld emlxs_sli4_index_to_vfi(emlxs_hba_t *hba, uint32_t index) 9467*8f23e9faSHans Rosenfeld { 9468*8f23e9faSHans Rosenfeld uint32_t i; 9469*8f23e9faSHans Rosenfeld uint32_t j; 9470*8f23e9faSHans Rosenfeld uint32_t vfi; 9471*8f23e9faSHans Rosenfeld 9472*8f23e9faSHans Rosenfeld i = index / hba->sli.sli4.VFIExtSize; 9473*8f23e9faSHans Rosenfeld j = index % hba->sli.sli4.VFIExtSize; 9474*8f23e9faSHans Rosenfeld vfi = hba->sli.sli4.VFIBase[i] + j; 9475*8f23e9faSHans Rosenfeld 9476*8f23e9faSHans Rosenfeld return (vfi); 9477*8f23e9faSHans Rosenfeld 9478*8f23e9faSHans Rosenfeld } /* emlxs_sli4_index_to_vfi */ 9479*8f23e9faSHans Rosenfeld 9480*8f23e9faSHans Rosenfeld 9481*8f23e9faSHans Rosenfeld static uint16_t 9482*8f23e9faSHans Rosenfeld emlxs_sli4_rqid_to_index(emlxs_hba_t *hba, uint16_t rqid) 9483*8f23e9faSHans Rosenfeld { 9484*8f23e9faSHans Rosenfeld uint16_t i; 9485*8f23e9faSHans Rosenfeld 9486*8f23e9faSHans Rosenfeld if (rqid < 0xffff) { 9487*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_RQS; i++) { 9488*8f23e9faSHans Rosenfeld if (hba->sli.sli4.rq[i].qid == rqid) { 9489*8f23e9faSHans Rosenfeld return (i); 9490*8f23e9faSHans Rosenfeld } 9491*8f23e9faSHans Rosenfeld } 9492*8f23e9faSHans Rosenfeld } 9493*8f23e9faSHans Rosenfeld 9494*8f23e9faSHans Rosenfeld return (0xffff); 9495*8f23e9faSHans Rosenfeld 9496*8f23e9faSHans Rosenfeld } /* emlxs_sli4_rqid_to_index */ 9497*8f23e9faSHans Rosenfeld 9498*8f23e9faSHans Rosenfeld 9499*8f23e9faSHans Rosenfeld static uint16_t 9500*8f23e9faSHans Rosenfeld emlxs_sli4_wqid_to_index(emlxs_hba_t *hba, uint16_t wqid) 9501*8f23e9faSHans Rosenfeld { 9502*8f23e9faSHans Rosenfeld uint16_t i; 9503*8f23e9faSHans Rosenfeld 9504*8f23e9faSHans Rosenfeld if (wqid < 0xffff) { 9505*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_WQS; i++) { 9506*8f23e9faSHans Rosenfeld if (hba->sli.sli4.wq[i].qid == wqid) { 9507*8f23e9faSHans Rosenfeld return (i); 9508*8f23e9faSHans Rosenfeld } 9509*8f23e9faSHans Rosenfeld } 9510*8f23e9faSHans Rosenfeld } 9511*8f23e9faSHans Rosenfeld 9512*8f23e9faSHans Rosenfeld return (0xffff); 9513*8f23e9faSHans Rosenfeld 9514*8f23e9faSHans Rosenfeld } /* emlxs_sli4_wqid_to_index */ 9515*8f23e9faSHans Rosenfeld 9516*8f23e9faSHans Rosenfeld 9517*8f23e9faSHans Rosenfeld static uint16_t 9518*8f23e9faSHans Rosenfeld emlxs_sli4_cqid_to_index(emlxs_hba_t *hba, uint16_t cqid) 9519*8f23e9faSHans Rosenfeld { 9520*8f23e9faSHans Rosenfeld uint16_t i; 9521*8f23e9faSHans Rosenfeld 9522*8f23e9faSHans Rosenfeld if (cqid < 0xffff) { 9523*8f23e9faSHans Rosenfeld for (i = 0; i < EMLXS_MAX_CQS; i++) { 9524*8f23e9faSHans Rosenfeld if (hba->sli.sli4.cq[i].qid == cqid) { 9525*8f23e9faSHans Rosenfeld return (i); 9526*8f23e9faSHans Rosenfeld } 9527*8f23e9faSHans Rosenfeld } 9528*8f23e9faSHans Rosenfeld } 9529*8f23e9faSHans Rosenfeld 9530*8f23e9faSHans Rosenfeld return (0xffff); 9531*8f23e9faSHans Rosenfeld 9532*8f23e9faSHans Rosenfeld } /* emlxs_sli4_cqid_to_index */ 9533