1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*a9800bebSGarrett D'Amore  * Copyright 2010 Emulex.  All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
2782527734SSukumar Swaminathan 
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte 
3082527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
3182527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_MBOX_C);
3282527734SSukumar Swaminathan 
3382527734SSukumar Swaminathan 
3482527734SSukumar Swaminathan 
3582527734SSukumar Swaminathan emlxs_table_t emlxs_mb_cmd_table[] = {
3682527734SSukumar Swaminathan 	{MBX_SHUTDOWN, "SHUTDOWN"},
3782527734SSukumar Swaminathan 	{MBX_LOAD_SM, "LOAD_SM"},
3882527734SSukumar Swaminathan 	{MBX_READ_NV, "READ_NV"},
3982527734SSukumar Swaminathan 	{MBX_WRITE_NV, "WRITE_NV"},
4082527734SSukumar Swaminathan 	{MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"},
4182527734SSukumar Swaminathan 	{MBX_INIT_LINK, "INIT_LINK"},
4282527734SSukumar Swaminathan 	{MBX_DOWN_LINK, "DOWN_LINK"},
4382527734SSukumar Swaminathan 	{MBX_CONFIG_LINK, "CONFIG_LINK"},
4482527734SSukumar Swaminathan 	{MBX_PART_SLIM, "PART_SLIM"},
4582527734SSukumar Swaminathan 	{MBX_CONFIG_RING, "CONFIG_RING"},
4682527734SSukumar Swaminathan 	{MBX_RESET_RING, "RESET_RING"},
4782527734SSukumar Swaminathan 	{MBX_READ_CONFIG, "READ_CONFIG"},
4882527734SSukumar Swaminathan 	{MBX_READ_RCONFIG, "READ_RCONFIG"},
4982527734SSukumar Swaminathan 	{MBX_READ_SPARM, "READ_SPARM"},
5082527734SSukumar Swaminathan 	{MBX_READ_STATUS, "READ_STATUS"},
5182527734SSukumar Swaminathan 	{MBX_READ_RPI, "READ_RPI"},
5282527734SSukumar Swaminathan 	{MBX_READ_XRI, "READ_XRI"},
5382527734SSukumar Swaminathan 	{MBX_READ_REV, "READ_REV"},
5482527734SSukumar Swaminathan 	{MBX_READ_LNK_STAT, "READ_LNK_STAT"},
5582527734SSukumar Swaminathan 	{MBX_REG_LOGIN, "REG_LOGIN"},
56*a9800bebSGarrett D'Amore 	{MBX_UNREG_LOGIN, "UNREG_RPI"},
5782527734SSukumar Swaminathan 	{MBX_READ_LA, "READ_LA"},
5882527734SSukumar Swaminathan 	{MBX_CLEAR_LA, "CLEAR_LA"},
5982527734SSukumar Swaminathan 	{MBX_DUMP_MEMORY, "DUMP_MEMORY"},
6082527734SSukumar Swaminathan 	{MBX_DUMP_CONTEXT, "DUMP_CONTEXT"},
6182527734SSukumar Swaminathan 	{MBX_RUN_DIAGS, "RUN_DIAGS"},
6282527734SSukumar Swaminathan 	{MBX_RESTART, "RESTART"},
6382527734SSukumar Swaminathan 	{MBX_UPDATE_CFG, "UPDATE_CFG"},
6482527734SSukumar Swaminathan 	{MBX_DOWN_LOAD, "DOWN_LOAD"},
6582527734SSukumar Swaminathan 	{MBX_DEL_LD_ENTRY, "DEL_LD_ENTRY"},
6682527734SSukumar Swaminathan 	{MBX_RUN_PROGRAM, "RUN_PROGRAM"},
6782527734SSukumar Swaminathan 	{MBX_SET_MASK, "SET_MASK"},
6882527734SSukumar Swaminathan 	{MBX_SET_VARIABLE, "SET_VARIABLE"},
6982527734SSukumar Swaminathan 	{MBX_UNREG_D_ID, "UNREG_D_ID"},
7082527734SSukumar Swaminathan 	{MBX_KILL_BOARD, "KILL_BOARD"},
7182527734SSukumar Swaminathan 	{MBX_CONFIG_FARP, "CONFIG_FARP"},
7282527734SSukumar Swaminathan 	{MBX_LOAD_AREA, "LOAD_AREA"},
7382527734SSukumar Swaminathan 	{MBX_RUN_BIU_DIAG64, "RUN_BIU_DIAG64"},
7482527734SSukumar Swaminathan 	{MBX_CONFIG_PORT, "CONFIG_PORT"},
7582527734SSukumar Swaminathan 	{MBX_READ_SPARM64, "READ_SPARM64"},
7682527734SSukumar Swaminathan 	{MBX_READ_RPI64, "READ_RPI64"},
7782527734SSukumar Swaminathan 	{MBX_CONFIG_MSI, "CONFIG_MSI"},
7882527734SSukumar Swaminathan 	{MBX_CONFIG_MSIX, "CONFIG_MSIX"},
79*a9800bebSGarrett D'Amore 	{MBX_REG_LOGIN64, "REG_RPI"},
8082527734SSukumar Swaminathan 	{MBX_READ_LA64, "READ_LA64"},
8182527734SSukumar Swaminathan 	{MBX_FLASH_WR_ULA, "FLASH_WR_ULA"},
8282527734SSukumar Swaminathan 	{MBX_SET_DEBUG, "SET_DEBUG"},
8382527734SSukumar Swaminathan 	{MBX_GET_DEBUG, "GET_DEBUG"},
8482527734SSukumar Swaminathan 	{MBX_LOAD_EXP_ROM, "LOAD_EXP_ROM"},
8582527734SSukumar Swaminathan 	{MBX_BEACON, "BEACON"},
8682527734SSukumar Swaminathan 	{MBX_CONFIG_HBQ, "CONFIG_HBQ"},	/* SLI3 */
8782527734SSukumar Swaminathan 	{MBX_REG_VPI, "REG_VPI"},	/* NPIV */
8882527734SSukumar Swaminathan 	{MBX_UNREG_VPI, "UNREG_VPI"},	/* NPIV */
8982527734SSukumar Swaminathan 	{MBX_ASYNC_EVENT, "ASYNC_EVENT"},
9082527734SSukumar Swaminathan 	{MBX_HEARTBEAT, "HEARTBEAT"},
9182527734SSukumar Swaminathan 	{MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"},
9282527734SSukumar Swaminathan 	{MBX_READ_EVENT_LOG, "READ_EVENT_LOG"},
9382527734SSukumar Swaminathan 	{MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"},
9482527734SSukumar Swaminathan 	{MBX_NV_LOG, "NV_LOG"},
9582527734SSukumar Swaminathan 	{MBX_PORT_CAPABILITIES, "PORT_CAPABILITIES"},
9682527734SSukumar Swaminathan 	{MBX_IOV_CONTROL, "IOV_CONTROL"},
9782527734SSukumar Swaminathan 	{MBX_IOV_MBX, "IOV_MBX"},
9882527734SSukumar Swaminathan 	{MBX_SLI_CONFIG, "SLI_CONFIG"},
9982527734SSukumar Swaminathan 	{MBX_REQUEST_FEATURES, "REQUEST_FEATURES"},
10082527734SSukumar Swaminathan 	{MBX_RESUME_RPI, "RESUME_RPI"},
10182527734SSukumar Swaminathan 	{MBX_REG_VFI, "REG_VFI"},
10282527734SSukumar Swaminathan 	{MBX_REG_FCFI, "REG_FCFI"},
10382527734SSukumar Swaminathan 	{MBX_UNREG_VFI, "UNREG_VFI"},
10482527734SSukumar Swaminathan 	{MBX_UNREG_FCFI, "UNREG_FCFI"},
10582527734SSukumar Swaminathan 	{MBX_INIT_VFI, "INIT_VFI"},
10682527734SSukumar Swaminathan 	{MBX_INIT_VPI, "INIT_VPI"}
10782527734SSukumar Swaminathan };	/* emlxs_mb_cmd_table */
10882527734SSukumar Swaminathan 
10982527734SSukumar Swaminathan 
110*a9800bebSGarrett D'Amore /* SLI4 */
11182527734SSukumar Swaminathan /*ARGSUSED*/
11282527734SSukumar Swaminathan extern void
11382527734SSukumar Swaminathan emlxs_mb_resetport(emlxs_hba_t *hba, MAILBOXQ *mbq)
11482527734SSukumar Swaminathan {
115*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
11682527734SSukumar Swaminathan 
117*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
11882527734SSukumar Swaminathan 	mbq->nonembed = NULL;
11982527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
120*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
12182527734SSukumar Swaminathan 
12282527734SSukumar Swaminathan 	/*
12382527734SSukumar Swaminathan 	 * Signifies an embedded command
12482527734SSukumar Swaminathan 	 */
125*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
12682527734SSukumar Swaminathan 
127*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
128*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
129*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
130*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
13182527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
132*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_RESET;
133*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
134*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0;
13582527734SSukumar Swaminathan 
13682527734SSukumar Swaminathan 	return;
13782527734SSukumar Swaminathan 
13882527734SSukumar Swaminathan } /* emlxs_mb_resetport() */
13982527734SSukumar Swaminathan 
14082527734SSukumar Swaminathan 
141*a9800bebSGarrett D'Amore /* SLI4 */
14282527734SSukumar Swaminathan /*ARGSUSED*/
14382527734SSukumar Swaminathan extern void
14482527734SSukumar Swaminathan emlxs_mb_request_features(emlxs_hba_t *hba, MAILBOXQ *mbq)
14582527734SSukumar Swaminathan {
14682527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
147*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
14882527734SSukumar Swaminathan 
14982527734SSukumar Swaminathan 	hba->flag &= ~FC_NPIV_ENABLED;
15082527734SSukumar Swaminathan 
151*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
15282527734SSukumar Swaminathan 	mbq->nonembed = NULL;
15382527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
154*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
15582527734SSukumar Swaminathan 
156*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_REQUEST_FEATURES;
157*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
158*a9800bebSGarrett D'Amore 	mb4->un.varReqFeatures.featuresRequested |=
15982527734SSukumar Swaminathan 	    SLI4_FEATURE_FCP_INITIATOR;
16082527734SSukumar Swaminathan 
16182527734SSukumar Swaminathan 	if (cfg[CFG_NPIV_ENABLE].current) {
162*a9800bebSGarrett D'Amore 		mb4->un.varReqFeatures.featuresRequested |=
16382527734SSukumar Swaminathan 		    SLI4_FEATURE_NPIV;
16482527734SSukumar Swaminathan 	}
16582527734SSukumar Swaminathan 
16682527734SSukumar Swaminathan } /* emlxs_mb_request_features() */
16782527734SSukumar Swaminathan 
16882527734SSukumar Swaminathan 
169*a9800bebSGarrett D'Amore /* SLI4 */
17082527734SSukumar Swaminathan /*ARGSUSED*/
17182527734SSukumar Swaminathan extern void
17282527734SSukumar Swaminathan emlxs_mb_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
17382527734SSukumar Swaminathan {
174*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
17582527734SSukumar Swaminathan 	IOCTL_COMMON_NOP *nop;
17682527734SSukumar Swaminathan 
177*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
17882527734SSukumar Swaminathan 	mbq->nonembed = NULL;
17982527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
180*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
18182527734SSukumar Swaminathan 
18282527734SSukumar Swaminathan 	/*
18382527734SSukumar Swaminathan 	 * Signifies an embedded command
18482527734SSukumar Swaminathan 	 */
185*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
18682527734SSukumar Swaminathan 
187*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
188*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
189*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length = sizeof (IOCTL_COMMON_NOP) +
19082527734SSukumar Swaminathan 	    IOCTL_HEADER_SZ;
191*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
19282527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
193*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_NOP;
194*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
195*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
19682527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_NOP);
197*a9800bebSGarrett D'Amore 	nop = (IOCTL_COMMON_NOP *)&mb4->un.varSLIConfig.payload;
19882527734SSukumar Swaminathan 	nop->params.request.context = -1;
19982527734SSukumar Swaminathan 
20082527734SSukumar Swaminathan 	return;
20182527734SSukumar Swaminathan 
20282527734SSukumar Swaminathan } /* emlxs_mb_noop() */
20382527734SSukumar Swaminathan 
20482527734SSukumar Swaminathan 
205*a9800bebSGarrett D'Amore /* SLI4 */
20682527734SSukumar Swaminathan /*ARGSUSED*/
20782527734SSukumar Swaminathan extern int
20882527734SSukumar Swaminathan emlxs_mbext_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
20982527734SSukumar Swaminathan {
210*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
21182527734SSukumar Swaminathan 	IOCTL_COMMON_NOP *nop;
21282527734SSukumar Swaminathan 	MATCHMAP *mp;
21382527734SSukumar Swaminathan 	mbox_req_hdr_t	*hdr_req;
21482527734SSukumar Swaminathan 
215*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
21682527734SSukumar Swaminathan 
21782527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
21882527734SSukumar Swaminathan 		return (1);
21982527734SSukumar Swaminathan 	}
22082527734SSukumar Swaminathan 	/*
22182527734SSukumar Swaminathan 	 * Save address for completion
22282527734SSukumar Swaminathan 	 * Signifies a non-embedded command
22382527734SSukumar Swaminathan 	 */
224*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 0;
225*a9800bebSGarrett D'Amore 	mbq->nonembed = (void *)mp;
22682527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
227*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
22882527734SSukumar Swaminathan 
229*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
230*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
23182527734SSukumar Swaminathan 
23282527734SSukumar Swaminathan 	hdr_req = (mbox_req_hdr_t *)mp->virt;
23382527734SSukumar Swaminathan 	hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
23482527734SSukumar Swaminathan 	hdr_req->opcode = COMMON_OPCODE_NOP;
23582527734SSukumar Swaminathan 	hdr_req->timeout = 0;
23682527734SSukumar Swaminathan 	hdr_req->req_length = sizeof (IOCTL_COMMON_NOP);
23782527734SSukumar Swaminathan 	nop = (IOCTL_COMMON_NOP *)(hdr_req + 1);
23882527734SSukumar Swaminathan 	nop->params.request.context = -1;
23982527734SSukumar Swaminathan 
24082527734SSukumar Swaminathan 	return (0);
24182527734SSukumar Swaminathan 
24282527734SSukumar Swaminathan } /* emlxs_mbext_noop() */
24382527734SSukumar Swaminathan 
24482527734SSukumar Swaminathan 
245*a9800bebSGarrett D'Amore /* SLI4 */
24682527734SSukumar Swaminathan /*ARGSUSED*/
24782527734SSukumar Swaminathan extern void
24882527734SSukumar Swaminathan emlxs_mb_eq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
24982527734SSukumar Swaminathan {
250*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
25182527734SSukumar Swaminathan 	IOCTL_COMMON_EQ_CREATE *qp;
25282527734SSukumar Swaminathan 	uint64_t	addr;
25382527734SSukumar Swaminathan 
254*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
25582527734SSukumar Swaminathan 	mbq->nonembed = NULL;
25682527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
257*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
25882527734SSukumar Swaminathan 
25982527734SSukumar Swaminathan 	/*
26082527734SSukumar Swaminathan 	 * Signifies an embedded command
26182527734SSukumar Swaminathan 	 */
262*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
26382527734SSukumar Swaminathan 
264*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
265*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
266*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
26782527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_EQ_CREATE) + IOCTL_HEADER_SZ;
268*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
26982527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
270*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_EQ_CREATE;
271*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
272*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
27382527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_EQ_CREATE);
274*a9800bebSGarrett D'Amore 	qp = (IOCTL_COMMON_EQ_CREATE *)&mb4->un.varSLIConfig.payload;
27582527734SSukumar Swaminathan 
27682527734SSukumar Swaminathan 	/* 1024 * 4 bytes = 4K */
27782527734SSukumar Swaminathan 	qp->params.request.EQContext.Count = EQ_ELEMENT_COUNT_1024;
27882527734SSukumar Swaminathan 	qp->params.request.EQContext.Valid = 1;
27982527734SSukumar Swaminathan 	qp->params.request.EQContext.NoDelay = 0;
28082527734SSukumar Swaminathan 	qp->params.request.EQContext.DelayMult = EQ_DELAY_MULT;
28182527734SSukumar Swaminathan 
28282527734SSukumar Swaminathan 	addr = hba->sli.sli4.eq[num].addr.phys;
28382527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
28482527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
28582527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
28682527734SSukumar Swaminathan 
28782527734SSukumar Swaminathan 	return;
28882527734SSukumar Swaminathan 
28982527734SSukumar Swaminathan } /* emlxs_mb_eq_create() */
29082527734SSukumar Swaminathan 
29182527734SSukumar Swaminathan 
292*a9800bebSGarrett D'Amore /* SLI4 */
29382527734SSukumar Swaminathan /*ARGSUSED*/
29482527734SSukumar Swaminathan extern void
29582527734SSukumar Swaminathan emlxs_mb_cq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
29682527734SSukumar Swaminathan {
297*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
29882527734SSukumar Swaminathan 	IOCTL_COMMON_CQ_CREATE *qp;
29982527734SSukumar Swaminathan 	uint64_t	addr;
30082527734SSukumar Swaminathan 
301*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
30282527734SSukumar Swaminathan 	mbq->nonembed = NULL;
30382527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
304*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
30582527734SSukumar Swaminathan 
30682527734SSukumar Swaminathan 	/*
30782527734SSukumar Swaminathan 	 * Signifies an embedded command
30882527734SSukumar Swaminathan 	 */
309*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
31082527734SSukumar Swaminathan 
311*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
312*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
313*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
31482527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_CQ_CREATE) + IOCTL_HEADER_SZ;
315*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
31682527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
317*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_CQ_CREATE;
318*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
319*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
32082527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_CQ_CREATE);
321*a9800bebSGarrett D'Amore 	qp = (IOCTL_COMMON_CQ_CREATE *)&mb4->un.varSLIConfig.payload;
32282527734SSukumar Swaminathan 
32382527734SSukumar Swaminathan 	/* 256 * 16 bytes = 4K */
32482527734SSukumar Swaminathan 	qp->params.request.CQContext.Count = CQ_ELEMENT_COUNT_256;
32582527734SSukumar Swaminathan 	qp->params.request.CQContext.EQId = hba->sli.sli4.cq[num].eqid;
32682527734SSukumar Swaminathan 	qp->params.request.CQContext.Valid = 1;
32782527734SSukumar Swaminathan 	qp->params.request.CQContext.Eventable = 1;
32882527734SSukumar Swaminathan 	qp->params.request.CQContext.NoDelay = 0;
32982527734SSukumar Swaminathan 
33082527734SSukumar Swaminathan 	addr = hba->sli.sli4.cq[num].addr.phys;
33182527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
33282527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
33382527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
33482527734SSukumar Swaminathan 
33582527734SSukumar Swaminathan 	return;
33682527734SSukumar Swaminathan 
33782527734SSukumar Swaminathan } /* emlxs_mb_cq_create() */
33882527734SSukumar Swaminathan 
33982527734SSukumar Swaminathan 
340*a9800bebSGarrett D'Amore /* SLI4 */
34182527734SSukumar Swaminathan /*ARGSUSED*/
34282527734SSukumar Swaminathan extern void
34382527734SSukumar Swaminathan emlxs_mb_wq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
34482527734SSukumar Swaminathan {
345*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
34682527734SSukumar Swaminathan 	IOCTL_FCOE_WQ_CREATE *qp;
34782527734SSukumar Swaminathan 	uint64_t addr;
34882527734SSukumar Swaminathan 	int i;
34982527734SSukumar Swaminathan 
350*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
35182527734SSukumar Swaminathan 	mbq->nonembed = NULL;
35282527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
353*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
35482527734SSukumar Swaminathan 
35582527734SSukumar Swaminathan 	/*
35682527734SSukumar Swaminathan 	 * Signifies an embedded command
35782527734SSukumar Swaminathan 	 */
358*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
35982527734SSukumar Swaminathan 
360*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
361*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
362*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
36382527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_WQ_CREATE) + IOCTL_HEADER_SZ;
364*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
36582527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_FCOE;
366*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = FCOE_OPCODE_WQ_CREATE;
367*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
368*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
36982527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_WQ_CREATE);
37082527734SSukumar Swaminathan 
37182527734SSukumar Swaminathan 	addr = hba->sli.sli4.wq[num].addr.phys;
372*a9800bebSGarrett D'Amore 	qp = (IOCTL_FCOE_WQ_CREATE *)&mb4->un.varSLIConfig.payload;
37382527734SSukumar Swaminathan 
37482527734SSukumar Swaminathan 	qp->params.request.CQId = hba->sli.sli4.wq[num].cqid;
37582527734SSukumar Swaminathan 
37682527734SSukumar Swaminathan 	qp->params.request.NumPages = EMLXS_NUM_WQ_PAGES;
37782527734SSukumar Swaminathan 	for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) {
37882527734SSukumar Swaminathan 		qp->params.request.Pages[i].addrLow = PADDR_LO(addr);
37982527734SSukumar Swaminathan 		qp->params.request.Pages[i].addrHigh = PADDR_HI(addr);
38082527734SSukumar Swaminathan 		addr += 4096;
38182527734SSukumar Swaminathan 	}
38282527734SSukumar Swaminathan 
38382527734SSukumar Swaminathan 	return;
38482527734SSukumar Swaminathan 
38582527734SSukumar Swaminathan } /* emlxs_mb_wq_create() */
38682527734SSukumar Swaminathan 
38782527734SSukumar Swaminathan 
388*a9800bebSGarrett D'Amore /* SLI4 */
38982527734SSukumar Swaminathan /*ARGSUSED*/
39082527734SSukumar Swaminathan extern void
39182527734SSukumar Swaminathan emlxs_mb_rq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
392*a9800bebSGarrett D'Amore {
393*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
394*a9800bebSGarrett D'Amore 	IOCTL_FCOE_RQ_CREATE *qp;
395*a9800bebSGarrett D'Amore 	uint64_t	addr;
39682527734SSukumar Swaminathan 
397*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
398*a9800bebSGarrett D'Amore 	mbq->nonembed = NULL;
399*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
400*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
40182527734SSukumar Swaminathan 
40282527734SSukumar Swaminathan 	/*
403*a9800bebSGarrett D'Amore 	 * Signifies an embedded command
40482527734SSukumar Swaminathan 	 */
405*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
40682527734SSukumar Swaminathan 
407*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
408*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
409*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
410*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_FCOE_RQ_CREATE) + IOCTL_HEADER_SZ;
411*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
412*a9800bebSGarrett D'Amore 	    IOCTL_SUBSYSTEM_FCOE;
413*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = FCOE_OPCODE_RQ_CREATE;
414*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
415*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
416*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_FCOE_RQ_CREATE);
417*a9800bebSGarrett D'Amore 	addr = hba->sli.sli4.rq[num].addr.phys;
41882527734SSukumar Swaminathan 
419*a9800bebSGarrett D'Amore 	qp = (IOCTL_FCOE_RQ_CREATE *)&mb4->un.varSLIConfig.payload;
42082527734SSukumar Swaminathan 
421*a9800bebSGarrett D'Amore 	qp->params.request.RQContext.RQSize	= RQ_DEPTH_EXPONENT;
422*a9800bebSGarrett D'Amore 	qp->params.request.RQContext.BufferSize	= RQB_DATA_SIZE;
423*a9800bebSGarrett D'Amore 	qp->params.request.RQContext.CQIdRecv	= hba->sli.sli4.rq[num].cqid;
424fcf3ce44SJohn Forte 
425*a9800bebSGarrett D'Amore 	qp->params.request.NumPages = 1;
426*a9800bebSGarrett D'Amore 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
427*a9800bebSGarrett D'Amore 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
428fcf3ce44SJohn Forte 
429*a9800bebSGarrett D'Amore 	return;
430fcf3ce44SJohn Forte 
431*a9800bebSGarrett D'Amore } /* emlxs_mb_rq_create() */
43282527734SSukumar Swaminathan 
43382527734SSukumar Swaminathan 
434*a9800bebSGarrett D'Amore /* SLI4 */
43582527734SSukumar Swaminathan /*ARGSUSED*/
436*a9800bebSGarrett D'Amore extern void
437*a9800bebSGarrett D'Amore emlxs_mb_mq_create(emlxs_hba_t *hba, MAILBOXQ *mbq)
43882527734SSukumar Swaminathan {
439*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
440*a9800bebSGarrett D'Amore 	IOCTL_COMMON_MQ_CREATE *qp;
441*a9800bebSGarrett D'Amore 	uint64_t	addr;
44282527734SSukumar Swaminathan 
443*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
444*a9800bebSGarrett D'Amore 	mbq->nonembed = NULL;
445*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
446*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
44782527734SSukumar Swaminathan 
448*a9800bebSGarrett D'Amore 	/*
449*a9800bebSGarrett D'Amore 	 * Signifies an embedded command
450*a9800bebSGarrett D'Amore 	 */
451*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
45282527734SSukumar Swaminathan 
453*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
454*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
455*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
456*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ;
457*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
458*a9800bebSGarrett D'Amore 	    IOCTL_SUBSYSTEM_COMMON;
459*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_MQ_CREATE;
460*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
461*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
462*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_COMMON_MQ_CREATE);
46382527734SSukumar Swaminathan 
464*a9800bebSGarrett D'Amore 	addr = hba->sli.sli4.mq.addr.phys;
465*a9800bebSGarrett D'Amore 	qp = (IOCTL_COMMON_MQ_CREATE *)&mb4->un.varSLIConfig.payload;
46682527734SSukumar Swaminathan 
467*a9800bebSGarrett D'Amore 	qp->params.request.MQContext.Size = MQ_ELEMENT_COUNT_16;
468*a9800bebSGarrett D'Amore 	qp->params.request.MQContext.Valid = 1;
469*a9800bebSGarrett D'Amore 	qp->params.request.MQContext.CQId = hba->sli.sli4.mq.cqid;
47082527734SSukumar Swaminathan 
471*a9800bebSGarrett D'Amore 	qp->params.request.NumPages = 1;
472*a9800bebSGarrett D'Amore 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
473*a9800bebSGarrett D'Amore 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
47482527734SSukumar Swaminathan 
475*a9800bebSGarrett D'Amore 	return;
47682527734SSukumar Swaminathan 
477*a9800bebSGarrett D'Amore } /* emlxs_mb_mq_create() */
47882527734SSukumar Swaminathan 
47982527734SSukumar Swaminathan 
480*a9800bebSGarrett D'Amore /* SLI4 */
48182527734SSukumar Swaminathan /*ARGSUSED*/
482*a9800bebSGarrett D'Amore extern void
483*a9800bebSGarrett D'Amore emlxs_mb_mcc_create_ext(emlxs_hba_t *hba, MAILBOXQ *mbq)
48482527734SSukumar Swaminathan {
485*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
486*a9800bebSGarrett D'Amore 	IOCTL_COMMON_MCC_CREATE_EXT *qp;
487*a9800bebSGarrett D'Amore 	uint64_t	addr;
48882527734SSukumar Swaminathan 
489*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
490*a9800bebSGarrett D'Amore 	mbq->nonembed = NULL;
491*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
492*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
49382527734SSukumar Swaminathan 
494*a9800bebSGarrett D'Amore 	/*
495*a9800bebSGarrett D'Amore 	 * Signifies an embedded command
496*a9800bebSGarrett D'Amore 	 */
497*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.embedded = 1;
49882527734SSukumar Swaminathan 
499*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_SLI_CONFIG;
500*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
501*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.payload_length =
502*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ;
503*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
504*a9800bebSGarrett D'Amore 	    IOCTL_SUBSYSTEM_COMMON;
505*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.opcode =
506*a9800bebSGarrett D'Amore 	    COMMON_OPCODE_MCC_CREATE_EXT;
507*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
508*a9800bebSGarrett D'Amore 	mb4->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
509*a9800bebSGarrett D'Amore 	    sizeof (IOCTL_COMMON_MCC_CREATE_EXT);
51082527734SSukumar Swaminathan 
511*a9800bebSGarrett D'Amore 	addr = hba->sli.sli4.mq.addr.phys;
512*a9800bebSGarrett D'Amore 	qp = (IOCTL_COMMON_MCC_CREATE_EXT *)&mb4->un.varSLIConfig.payload;
51382527734SSukumar Swaminathan 
514*a9800bebSGarrett D'Amore 	qp->params.request.num_pages = 1;
515*a9800bebSGarrett D'Amore 	qp->params.request.async_event_bitmap =
516*a9800bebSGarrett D'Amore 	    ASYNC_LINK_EVENT | ASYNC_FCF_EVENT | ASYNC_GROUP5_EVENT;
517*a9800bebSGarrett D'Amore 	qp->params.request.context.Size = MQ_ELEMENT_COUNT_16;
518*a9800bebSGarrett D'Amore 	qp->params.request.context.Valid = 1;
519*a9800bebSGarrett D'Amore 	qp->params.request.context.CQId = hba->sli.sli4.mq.cqid;
52082527734SSukumar Swaminathan 
521*a9800bebSGarrett D'Amore 	qp->params.request.pages[0].addrLow = PADDR_LO(addr);
522*a9800bebSGarrett D'Amore 	qp->params.request.pages[0].addrHigh = PADDR_HI(addr);
52382527734SSukumar Swaminathan 
524*a9800bebSGarrett D'Amore 	return;
52582527734SSukumar Swaminathan 
526*a9800bebSGarrett D'Amore } /* emlxs_mb_mcc_create_ext() */
527fcf3ce44SJohn Forte 
528fcf3ce44SJohn Forte 
529291a2b48SSukumar Swaminathan /*ARGSUSED*/
530fcf3ce44SJohn Forte extern void
53182527734SSukumar Swaminathan emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOXQ *mbq)
532fcf3ce44SJohn Forte {
53382527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
53482527734SSukumar Swaminathan 
535fcf3ce44SJohn Forte 	bzero((void *) mb, MAILBOX_CMD_BSIZE);
536fcf3ce44SJohn Forte 
537fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_ASYNC_EVENT;
538fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
53982527734SSukumar Swaminathan 	mb->un.varWords[0] = hba->channel_els;
54082527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
541*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
542fcf3ce44SJohn Forte 
543fcf3ce44SJohn Forte 	return;
544fcf3ce44SJohn Forte 
545fcf3ce44SJohn Forte } /* emlxs_mb_async_event() */
546fcf3ce44SJohn Forte 
547fcf3ce44SJohn Forte 
548291a2b48SSukumar Swaminathan /*ARGSUSED*/
549fcf3ce44SJohn Forte extern void
55082527734SSukumar Swaminathan emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOXQ *mbq)
551fcf3ce44SJohn Forte {
55282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
55382527734SSukumar Swaminathan 
554fcf3ce44SJohn Forte 	bzero((void *) mb, MAILBOX_CMD_BSIZE);
555fcf3ce44SJohn Forte 
556fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_HEARTBEAT;
557fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
55882527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed for hbeat */
559*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
560fcf3ce44SJohn Forte 
561fcf3ce44SJohn Forte 	return;
562fcf3ce44SJohn Forte 
563fcf3ce44SJohn Forte } /* emlxs_mb_heartbeat() */
564fcf3ce44SJohn Forte 
565fcf3ce44SJohn Forte 
566fcf3ce44SJohn Forte #ifdef MSI_SUPPORT
567fcf3ce44SJohn Forte 
568291a2b48SSukumar Swaminathan /*ARGSUSED*/
569fcf3ce44SJohn Forte extern void
57082527734SSukumar Swaminathan emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
571fcf3ce44SJohn Forte     uint32_t intr_count)
572fcf3ce44SJohn Forte {
57382527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
574*a9800bebSGarrett D'Amore 	uint16_t i;
575fcf3ce44SJohn Forte 	uint32_t mask;
576fcf3ce44SJohn Forte 
577291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
578fcf3ce44SJohn Forte 
579fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_MSI;
580fcf3ce44SJohn Forte 
581fcf3ce44SJohn Forte 	/* Set the default message id to zero */
582fcf3ce44SJohn Forte 	mb->un.varCfgMSI.defaultPresent = 1;
583fcf3ce44SJohn Forte 	mb->un.varCfgMSI.defaultMessageNumber = 0;
584fcf3ce44SJohn Forte 
585fcf3ce44SJohn Forte 	for (i = 1; i < intr_count; i++) {
586fcf3ce44SJohn Forte 		mask = intr_map[i];
587fcf3ce44SJohn Forte 
588fcf3ce44SJohn Forte 		mb->un.varCfgMSI.attConditions |= mask;
589fcf3ce44SJohn Forte 
590fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN
591fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
592fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[3] = i;
593fcf3ce44SJohn Forte 		}
594fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
595fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[7] = i;
596fcf3ce44SJohn Forte 		}
597fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
598fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[11] = i;
599fcf3ce44SJohn Forte 		}
600fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
601fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[15] = i;
602fcf3ce44SJohn Forte 		}
603fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
604fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[29] = i;
605fcf3ce44SJohn Forte 		}
606fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
607fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[30] = i;
608fcf3ce44SJohn Forte 		}
609fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
610fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[31] = i;
611fcf3ce44SJohn Forte 		}
612fcf3ce44SJohn Forte #endif	/* EMLXS_BIG_ENDIAN */
613fcf3ce44SJohn Forte 
614fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN
615fcf3ce44SJohn Forte 		/* Accounts for half word swap of LE architecture */
616fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
617fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[2] = i;
618fcf3ce44SJohn Forte 		}
619fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
620fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[6] = i;
621fcf3ce44SJohn Forte 		}
622fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
623fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[10] = i;
624fcf3ce44SJohn Forte 		}
625fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
626fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[14] = i;
627fcf3ce44SJohn Forte 		}
628fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
629fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[28] = i;
630fcf3ce44SJohn Forte 		}
631fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
632fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[31] = i;
633fcf3ce44SJohn Forte 		}
634fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
635fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[30] = i;
636fcf3ce44SJohn Forte 		}
637fcf3ce44SJohn Forte #endif	/* EMLXS_LITTLE_ENDIAN */
638fcf3ce44SJohn Forte 	}
639fcf3ce44SJohn Forte 
640fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
64182527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
642*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
643fcf3ce44SJohn Forte 
644fcf3ce44SJohn Forte 	return;
645fcf3ce44SJohn Forte 
646fcf3ce44SJohn Forte } /* emlxs_mb_config_msi() */
647fcf3ce44SJohn Forte 
648fcf3ce44SJohn Forte 
649291a2b48SSukumar Swaminathan /*ARGSUSED*/
650fcf3ce44SJohn Forte extern void
65182527734SSukumar Swaminathan emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
652fcf3ce44SJohn Forte     uint32_t intr_count)
653fcf3ce44SJohn Forte {
65482527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
655*a9800bebSGarrett D'Amore 	uint8_t i;
656fcf3ce44SJohn Forte 	uint32_t mask;
657fcf3ce44SJohn Forte 
658291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
659fcf3ce44SJohn Forte 
660fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_MSIX;
661fcf3ce44SJohn Forte 
662fcf3ce44SJohn Forte 	/* Set the default message id to zero */
663fcf3ce44SJohn Forte 	mb->un.varCfgMSIX.defaultPresent = 1;
664fcf3ce44SJohn Forte 	mb->un.varCfgMSIX.defaultMessageNumber = 0;
665fcf3ce44SJohn Forte 
666fcf3ce44SJohn Forte 	for (i = 1; i < intr_count; i++) {
667fcf3ce44SJohn Forte 		mask = intr_map[i];
668fcf3ce44SJohn Forte 
669fcf3ce44SJohn Forte 		mb->un.varCfgMSIX.attConditions1 |= mask;
670fcf3ce44SJohn Forte 
671fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN
672fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
673fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[3] = i;
674fcf3ce44SJohn Forte 		}
675fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
676fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[7] = i;
677fcf3ce44SJohn Forte 		}
678fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
679fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[11] = i;
680fcf3ce44SJohn Forte 		}
681fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
682fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[15] = i;
683fcf3ce44SJohn Forte 		}
684fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
685fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[29] = i;
686fcf3ce44SJohn Forte 		}
687fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
688fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[30] = i;
689fcf3ce44SJohn Forte 		}
690fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
691fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[31] = i;
692fcf3ce44SJohn Forte 		}
693fcf3ce44SJohn Forte #endif	/* EMLXS_BIG_ENDIAN */
694fcf3ce44SJohn Forte 
695fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN
696fcf3ce44SJohn Forte 		/* Accounts for word swap of LE architecture */
697fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
698fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[0] = i;
699fcf3ce44SJohn Forte 		}
700fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
701fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[4] = i;
702fcf3ce44SJohn Forte 		}
703fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
704fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[8] = i;
705fcf3ce44SJohn Forte 		}
706fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
707fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[12] = i;
708fcf3ce44SJohn Forte 		}
709fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
710fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[30] = i;
711fcf3ce44SJohn Forte 		}
712fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
713fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[29] = i;
714fcf3ce44SJohn Forte 		}
715fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
716fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[28] = i;
717fcf3ce44SJohn Forte 		}
718fcf3ce44SJohn Forte #endif	/* EMLXS_LITTLE_ENDIAN */
719fcf3ce44SJohn Forte 	}
720fcf3ce44SJohn Forte 
721fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
72282527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
723*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
724fcf3ce44SJohn Forte 
725fcf3ce44SJohn Forte 	return;
726fcf3ce44SJohn Forte 
727fcf3ce44SJohn Forte } /* emlxs_mb_config_msix() */
728fcf3ce44SJohn Forte 
729fcf3ce44SJohn Forte 
730fcf3ce44SJohn Forte #endif	/* MSI_SUPPORT */
731fcf3ce44SJohn Forte 
732291a2b48SSukumar Swaminathan 
733291a2b48SSukumar Swaminathan /*ARGSUSED*/
734fcf3ce44SJohn Forte extern void
73582527734SSukumar Swaminathan emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t ringno)
736fcf3ce44SJohn Forte {
73782527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
73882527734SSukumar Swaminathan 
739291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
740fcf3ce44SJohn Forte 
741fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_RESET_RING;
742fcf3ce44SJohn Forte 	mb->un.varRstRing.ring_no = ringno;
743fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
74482527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
745*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
746fcf3ce44SJohn Forte 
747fcf3ce44SJohn Forte 	return;
748fcf3ce44SJohn Forte 
749fcf3ce44SJohn Forte } /* emlxs_mb_reset_ring() */
750fcf3ce44SJohn Forte 
751fcf3ce44SJohn Forte 
75282527734SSukumar Swaminathan /*ARGSUSED*/
75382527734SSukumar Swaminathan extern void
75482527734SSukumar Swaminathan emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
75582527734SSukumar Swaminathan {
75682527734SSukumar Swaminathan 
75782527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
758*a9800bebSGarrett D'Amore 		MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
75982527734SSukumar Swaminathan 
76082527734SSukumar Swaminathan 		/* Clear the local dump_region */
76182527734SSukumar Swaminathan 		bzero(hba->sli.sli4.dump_region.virt,
76282527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
76382527734SSukumar Swaminathan 
764*a9800bebSGarrett D'Amore 		bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
76582527734SSukumar Swaminathan 
766*a9800bebSGarrett D'Amore 		mb4->mbxCommand = MBX_DUMP_MEMORY;
767*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.type = DMP_NV_PARAMS;
768*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.entry_index = offset;
769*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.region_id = DMP_VPD_REGION;
77082527734SSukumar Swaminathan 
771*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
772*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.addrHigh =
77382527734SSukumar Swaminathan 		    PADDR_HI(hba->sli.sli4.dump_region.phys);
774*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.addrLow =
77582527734SSukumar Swaminathan 		    PADDR_LO(hba->sli.sli4.dump_region.phys);
776*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.rsp_cnt = 0;
77782527734SSukumar Swaminathan 
778*a9800bebSGarrett D'Amore 		mb4->mbxOwner = OWN_HOST;
77982527734SSukumar Swaminathan 
78082527734SSukumar Swaminathan 	} else {
78182527734SSukumar Swaminathan 		MAILBOX *mb = (MAILBOX *)mbq;
78282527734SSukumar Swaminathan 
78382527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
78482527734SSukumar Swaminathan 
78582527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
78682527734SSukumar Swaminathan 		mb->un.varDmp.cv = 1;
78782527734SSukumar Swaminathan 		mb->un.varDmp.type = DMP_NV_PARAMS;
78882527734SSukumar Swaminathan 		mb->un.varDmp.entry_index = offset;
78982527734SSukumar Swaminathan 		mb->un.varDmp.region_id = DMP_VPD_REGION;
79082527734SSukumar Swaminathan 
79182527734SSukumar Swaminathan 		/* limited by mailbox size */
79282527734SSukumar Swaminathan 		mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT;
79382527734SSukumar Swaminathan 
79482527734SSukumar Swaminathan 		mb->un.varDmp.co = 0;
79582527734SSukumar Swaminathan 		mb->un.varDmp.resp_offset = 0;
79682527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
79782527734SSukumar Swaminathan 	}
79882527734SSukumar Swaminathan 
79982527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
800*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
80182527734SSukumar Swaminathan 
80282527734SSukumar Swaminathan } /* emlxs_mb_dump_vpd() */
80382527734SSukumar Swaminathan 
80482527734SSukumar Swaminathan 
805*a9800bebSGarrett D'Amore /* SLI4 */
80682527734SSukumar Swaminathan /*ARGSUSED*/
80782527734SSukumar Swaminathan extern void
80882527734SSukumar Swaminathan emlxs_mb_dump_fcoe(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
80982527734SSukumar Swaminathan {
810*a9800bebSGarrett D'Amore 	MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
81182527734SSukumar Swaminathan 
812*a9800bebSGarrett D'Amore 	if (hba->sli_mode < EMLXS_HBA_SLI4_MODE) {
81382527734SSukumar Swaminathan 		return;
81482527734SSukumar Swaminathan 	}
815*a9800bebSGarrett D'Amore 
81682527734SSukumar Swaminathan 	/* Clear the local dump_region */
81782527734SSukumar Swaminathan 	bzero(hba->sli.sli4.dump_region.virt,
81882527734SSukumar Swaminathan 	    hba->sli.sli4.dump_region.size);
81982527734SSukumar Swaminathan 
820*a9800bebSGarrett D'Amore 	bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
82182527734SSukumar Swaminathan 
822*a9800bebSGarrett D'Amore 	mb4->mbxCommand = MBX_DUMP_MEMORY;
823*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.type = DMP_NV_PARAMS;
824*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.entry_index = offset;
825*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.region_id = DMP_FCOE_REGION;
82682527734SSukumar Swaminathan 
827*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
828*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.addrHigh =
82982527734SSukumar Swaminathan 	    PADDR_HI(hba->sli.sli4.dump_region.phys);
830*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.addrLow =
83182527734SSukumar Swaminathan 	    PADDR_LO(hba->sli.sli4.dump_region.phys);
832*a9800bebSGarrett D'Amore 	mb4->un.varDmp4.rsp_cnt = 0;
83382527734SSukumar Swaminathan 
834*a9800bebSGarrett D'Amore 	mb4->mbxOwner = OWN_HOST;
83582527734SSukumar Swaminathan 
83682527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
837*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
83882527734SSukumar Swaminathan 
83982527734SSukumar Swaminathan } /* emlxs_mb_dump_fcoe() */
84082527734SSukumar Swaminathan 
84182527734SSukumar Swaminathan 
84282527734SSukumar Swaminathan /*ARGSUSED*/
84382527734SSukumar Swaminathan extern void
84482527734SSukumar Swaminathan emlxs_mb_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset, uint32_t words)
84582527734SSukumar Swaminathan {
84682527734SSukumar Swaminathan 
84782527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
848*a9800bebSGarrett D'Amore 		MAILBOX4 *mb4 = (MAILBOX4 *)mbq;
84982527734SSukumar Swaminathan 
85082527734SSukumar Swaminathan 		/* Clear the local dump_region */
85182527734SSukumar Swaminathan 		bzero(hba->sli.sli4.dump_region.virt,
85282527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
85382527734SSukumar Swaminathan 
854*a9800bebSGarrett D'Amore 		bzero((void *) mb4, MAILBOX_CMD_SLI4_BSIZE);
85582527734SSukumar Swaminathan 
856*a9800bebSGarrett D'Amore 		mb4->mbxCommand = MBX_DUMP_MEMORY;
857*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.type = DMP_MEM_REG;
858*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.entry_index = offset;
859*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.region_id = 0;
86082527734SSukumar Swaminathan 
861*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.available_cnt = min((words*4),
86282527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
863*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.addrHigh =
86482527734SSukumar Swaminathan 		    PADDR_HI(hba->sli.sli4.dump_region.phys);
865*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.addrLow =
86682527734SSukumar Swaminathan 		    PADDR_LO(hba->sli.sli4.dump_region.phys);
867*a9800bebSGarrett D'Amore 		mb4->un.varDmp4.rsp_cnt = 0;
86882527734SSukumar Swaminathan 
869*a9800bebSGarrett D'Amore 		mb4->mbxOwner = OWN_HOST;
87082527734SSukumar Swaminathan 
87182527734SSukumar Swaminathan 	} else {
87282527734SSukumar Swaminathan 
87382527734SSukumar Swaminathan 		MAILBOX *mb = (MAILBOX *)mbq;
87482527734SSukumar Swaminathan 
87582527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
87682527734SSukumar Swaminathan 
87782527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
87882527734SSukumar Swaminathan 		mb->un.varDmp.type = DMP_MEM_REG;
87982527734SSukumar Swaminathan 		mb->un.varDmp.word_cnt = words;
88082527734SSukumar Swaminathan 		mb->un.varDmp.base_adr = offset;
88182527734SSukumar Swaminathan 
88282527734SSukumar Swaminathan 		mb->un.varDmp.co = 0;
88382527734SSukumar Swaminathan 		mb->un.varDmp.resp_offset = 0;
88482527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
88582527734SSukumar Swaminathan 	}
88682527734SSukumar Swaminathan 
88782527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
888*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
88982527734SSukumar Swaminathan 
89082527734SSukumar Swaminathan 	return;
89182527734SSukumar Swaminathan 
89282527734SSukumar Swaminathan } /* emlxs_mb_dump() */
89382527734SSukumar Swaminathan 
89482527734SSukumar Swaminathan 
89582527734SSukumar Swaminathan /*
89682527734SSukumar Swaminathan  *  emlxs_mb_read_nv  Issue a READ NVPARAM mailbox command
89782527734SSukumar Swaminathan  */
89882527734SSukumar Swaminathan /*ARGSUSED*/
89982527734SSukumar Swaminathan extern void
90082527734SSukumar Swaminathan emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOXQ *mbq)
90182527734SSukumar Swaminathan {
90282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
90382527734SSukumar Swaminathan 
90482527734SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
90582527734SSukumar Swaminathan 
90682527734SSukumar Swaminathan 	mb->mbxCommand = MBX_READ_NV;
90782527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
90882527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
909*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
91082527734SSukumar Swaminathan 
91182527734SSukumar Swaminathan } /* emlxs_mb_read_nv() */
91282527734SSukumar Swaminathan 
913fcf3ce44SJohn Forte 
914fcf3ce44SJohn Forte /*
91582527734SSukumar Swaminathan  * emlxs_mb_read_rev  Issue a READ REV mailbox command
916fcf3ce44SJohn Forte  */
917291a2b48SSukumar Swaminathan /*ARGSUSED*/
918fcf3ce44SJohn Forte extern void
91982527734SSukumar Swaminathan emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t v3)
92082527734SSukumar Swaminathan {
92182527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
92282527734SSukumar Swaminathan 
92382527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
92482527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
92582527734SSukumar Swaminathan 		mbq->nonembed = NULL;
92682527734SSukumar Swaminathan 	} else {
92782527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
92882527734SSukumar Swaminathan 
92982527734SSukumar Swaminathan 		mb->un.varRdRev.cv = 1;
93082527734SSukumar Swaminathan 
93182527734SSukumar Swaminathan 		if (v3) {
93282527734SSukumar Swaminathan 			mb->un.varRdRev.cv3 = 1;
93382527734SSukumar Swaminathan 		}
93482527734SSukumar Swaminathan 	}
93582527734SSukumar Swaminathan 
93682527734SSukumar Swaminathan 	mb->mbxCommand = MBX_READ_REV;
93782527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
93882527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
939*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
94082527734SSukumar Swaminathan 
94182527734SSukumar Swaminathan } /* emlxs_mb_read_rev() */
94282527734SSukumar Swaminathan 
94382527734SSukumar Swaminathan 
94482527734SSukumar Swaminathan /*
94582527734SSukumar Swaminathan  * emlxs_mb_run_biu_diag  Issue a RUN_BIU_DIAG mailbox command
94682527734SSukumar Swaminathan  */
94782527734SSukumar Swaminathan /*ARGSUSED*/
94882527734SSukumar Swaminathan extern uint32_t
94982527734SSukumar Swaminathan emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOXQ *mbq, uint64_t out,
95082527734SSukumar Swaminathan     uint64_t in)
95182527734SSukumar Swaminathan {
95282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
95382527734SSukumar Swaminathan 
95482527734SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
95582527734SSukumar Swaminathan 
95682527734SSukumar Swaminathan 	mb->mbxCommand = MBX_RUN_BIU_DIAG64;
95782527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
95882527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = PADDR_HI(out);
95982527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = PADDR_LO(out);
96082527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
96182527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = PADDR_HI(in);
96282527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = PADDR_LO(in);
96382527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
96482527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
965*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
96682527734SSukumar Swaminathan 
96782527734SSukumar Swaminathan 	return (0);
96882527734SSukumar Swaminathan } /* emlxs_mb_run_biu_diag() */
96982527734SSukumar Swaminathan 
97082527734SSukumar Swaminathan 
97182527734SSukumar Swaminathan /* This should only be called with active MBX_NOWAIT mailboxes */
97282527734SSukumar Swaminathan void
97382527734SSukumar Swaminathan emlxs_mb_retry(emlxs_hba_t *hba, MAILBOXQ *mbq)
97482527734SSukumar Swaminathan {
97582527734SSukumar Swaminathan 	MAILBOX	*mb;
97682527734SSukumar Swaminathan 	MAILBOX	*mbox;
97782527734SSukumar Swaminathan 	int rc;
97882527734SSukumar Swaminathan 
97982527734SSukumar Swaminathan 	mbox = (MAILBOX *)emlxs_mem_get(hba, MEM_MBOX, 1);
98082527734SSukumar Swaminathan 	if (!mbox) {
98182527734SSukumar Swaminathan 		return;
98282527734SSukumar Swaminathan 	}
98382527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
98482527734SSukumar Swaminathan 	bcopy((uint8_t *)mb, (uint8_t *)mbox, MAILBOX_CMD_BSIZE);
98582527734SSukumar Swaminathan 	mbox->mbxOwner = OWN_HOST;
98682527734SSukumar Swaminathan 	mbox->mbxStatus = 0;
98782527734SSukumar Swaminathan 
98882527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
98982527734SSukumar Swaminathan 
99082527734SSukumar Swaminathan 	HBASTATS.MboxCompleted++;
99182527734SSukumar Swaminathan 
99282527734SSukumar Swaminathan 	if (mb->mbxStatus != 0) {
99382527734SSukumar Swaminathan 		HBASTATS.MboxError++;
99482527734SSukumar Swaminathan 	} else {
99582527734SSukumar Swaminathan 		HBASTATS.MboxGood++;
99682527734SSukumar Swaminathan 	}
99782527734SSukumar Swaminathan 
998*a9800bebSGarrett D'Amore 	hba->mbox_mbq = NULL;
99982527734SSukumar Swaminathan 	hba->mbox_queue_flag = 0;
100082527734SSukumar Swaminathan 
100182527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
100282527734SSukumar Swaminathan 
100382527734SSukumar Swaminathan 	rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0);
100482527734SSukumar Swaminathan 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1005*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
100682527734SSukumar Swaminathan 	}
100782527734SSukumar Swaminathan 	return;
100882527734SSukumar Swaminathan 
100982527734SSukumar Swaminathan } /* emlxs_mb_retry() */
101082527734SSukumar Swaminathan 
101182527734SSukumar Swaminathan 
1012*a9800bebSGarrett D'Amore /* SLI3 */
1013*a9800bebSGarrett D'Amore static uint32_t
1014*a9800bebSGarrett D'Amore emlxs_read_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
1015fcf3ce44SJohn Forte {
1016*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
101782527734SSukumar Swaminathan 	MAILBOX *mb;
101882527734SSukumar Swaminathan 	MAILBOXQ *mbox;
101982527734SSukumar Swaminathan 	MATCHMAP *mp;
102082527734SSukumar Swaminathan 	READ_LA_VAR la;
102182527734SSukumar Swaminathan 	int i;
102282527734SSukumar Swaminathan 	uint32_t  control;
102382527734SSukumar Swaminathan 
102482527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
102582527734SSukumar Swaminathan 	if (mb->mbxStatus) {
102682527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
102782527734SSukumar Swaminathan 			control = mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize;
102882527734SSukumar Swaminathan 			if (control == 0) {
102982527734SSukumar Swaminathan 				(void) emlxs_mb_read_la(hba, mbq);
103082527734SSukumar Swaminathan 			}
103182527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
103282527734SSukumar Swaminathan 			return (1);
103382527734SSukumar Swaminathan 		}
103482527734SSukumar Swaminathan 		/* Enable Link Attention interrupts */
103582527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
1036fcf3ce44SJohn Forte 
103782527734SSukumar Swaminathan 		if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
103882527734SSukumar Swaminathan 			hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
103982527734SSukumar Swaminathan 			WRITE_CSR_REG(hba, FC_HC_REG(hba),
104082527734SSukumar Swaminathan 			    hba->sli.sli3.hc_copy);
104182527734SSukumar Swaminathan #ifdef FMA_SUPPORT
104282527734SSukumar Swaminathan 			/* Access handle validation */
104382527734SSukumar Swaminathan 			EMLXS_CHK_ACC_HANDLE(hba,
104482527734SSukumar Swaminathan 			    hba->sli.sli3.csr_acc_handle);
104582527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
104682527734SSukumar Swaminathan 		}
1047291a2b48SSukumar Swaminathan 
104882527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
104982527734SSukumar Swaminathan 		return (0);
105082527734SSukumar Swaminathan 	}
1051*a9800bebSGarrett D'Amore 	bcopy((void *)&mb->un.varReadLA, (void *)&la, sizeof (READ_LA_VAR));
1052fcf3ce44SJohn Forte 
105382527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
105482527734SSukumar Swaminathan 	if (mp) {
105582527734SSukumar Swaminathan 		bcopy((caddr_t)mp->virt, (caddr_t)port->alpa_map, 128);
105682527734SSukumar Swaminathan 	} else {
105782527734SSukumar Swaminathan 		bzero((caddr_t)port->alpa_map, 128);
105882527734SSukumar Swaminathan 	}
1059291a2b48SSukumar Swaminathan 
106082527734SSukumar Swaminathan 	if (la.attType == AT_LINK_UP) {
106182527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkup_atten_msg,
106282527734SSukumar Swaminathan 		    "tag=%d -> %d  ALPA=%x",
106382527734SSukumar Swaminathan 		    (uint32_t)hba->link_event_tag,
106482527734SSukumar Swaminathan 		    (uint32_t)la.eventTag,
106582527734SSukumar Swaminathan 		    (uint32_t)la.granted_AL_PA);
106682527734SSukumar Swaminathan 	} else {
106782527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkdown_atten_msg,
106882527734SSukumar Swaminathan 		    "tag=%d -> %d  ALPA=%x",
106982527734SSukumar Swaminathan 		    (uint32_t)hba->link_event_tag,
107082527734SSukumar Swaminathan 		    (uint32_t)la.eventTag,
107182527734SSukumar Swaminathan 		    (uint32_t)la.granted_AL_PA);
107282527734SSukumar Swaminathan 	}
1073fcf3ce44SJohn Forte 
107482527734SSukumar Swaminathan 	if (la.pb) {
107582527734SSukumar Swaminathan 		hba->flag |= FC_BYPASSED_MODE;
107682527734SSukumar Swaminathan 	} else {
107782527734SSukumar Swaminathan 		hba->flag &= ~FC_BYPASSED_MODE;
107882527734SSukumar Swaminathan 	}
1079fcf3ce44SJohn Forte 
108082527734SSukumar Swaminathan 	if (hba->link_event_tag == la.eventTag) {
108182527734SSukumar Swaminathan 		HBASTATS.LinkMultiEvent++;
108282527734SSukumar Swaminathan 	} else if (hba->link_event_tag + 1 < la.eventTag) {
108382527734SSukumar Swaminathan 		HBASTATS.LinkMultiEvent++;
1084291a2b48SSukumar Swaminathan 
108582527734SSukumar Swaminathan 		/* Make sure link is declared down */
108682527734SSukumar Swaminathan 		emlxs_linkdown(hba);
108782527734SSukumar Swaminathan 	}
1088291a2b48SSukumar Swaminathan 
108982527734SSukumar Swaminathan 	hba->link_event_tag = la.eventTag;
109082527734SSukumar Swaminathan 	port->lip_type = 0;
1091291a2b48SSukumar Swaminathan 
109282527734SSukumar Swaminathan 	/* If link not already up then declare it up now */
109382527734SSukumar Swaminathan 	if ((la.attType == AT_LINK_UP) && (hba->state < FC_LINK_UP)) {
1094291a2b48SSukumar Swaminathan 
109582527734SSukumar Swaminathan #ifdef MENLO_SUPPORT
109682527734SSukumar Swaminathan 		if ((hba->model_info.device_id == PCI_DEVICE_ID_LP21000_M) &&
109782527734SSukumar Swaminathan 		    (hba->flag & (FC_ILB_MODE | FC_ELB_MODE))) {
109882527734SSukumar Swaminathan 			la.topology = TOPOLOGY_LOOP;
109982527734SSukumar Swaminathan 			la.granted_AL_PA = 0;
110082527734SSukumar Swaminathan 			port->alpa_map[0] = 1;
110182527734SSukumar Swaminathan 			port->alpa_map[1] = 0;
110282527734SSukumar Swaminathan 			la.lipType = LT_PORT_INIT;
110382527734SSukumar Swaminathan 		}
110482527734SSukumar Swaminathan #endif /* MENLO_SUPPORT */
110582527734SSukumar Swaminathan 		/* Save the linkspeed */
110682527734SSukumar Swaminathan 		hba->linkspeed = la.UlnkSpeed;
110782527734SSukumar Swaminathan 
110882527734SSukumar Swaminathan 		/* Check for old model adapters that only */
110982527734SSukumar Swaminathan 		/* supported 1Gb */
111082527734SSukumar Swaminathan 		if ((hba->linkspeed == 0) &&
111182527734SSukumar Swaminathan 		    (hba->model_info.chip & EMLXS_DRAGONFLY_CHIP)) {
111282527734SSukumar Swaminathan 			hba->linkspeed = LA_1GHZ_LINK;
111382527734SSukumar Swaminathan 		}
1114291a2b48SSukumar Swaminathan 
111582527734SSukumar Swaminathan 		if ((hba->topology = la.topology) == TOPOLOGY_LOOP) {
111682527734SSukumar Swaminathan 			port->did = la.granted_AL_PA;
111782527734SSukumar Swaminathan 			port->lip_type = la.lipType;
111882527734SSukumar Swaminathan 			if (hba->flag & FC_SLIM2_MODE) {
111982527734SSukumar Swaminathan 				i = la.un.lilpBde64.tus.f.bdeSize;
112082527734SSukumar Swaminathan 			} else {
112182527734SSukumar Swaminathan 				i = la.un.lilpBde.bdeSize;
112282527734SSukumar Swaminathan 			}
1123291a2b48SSukumar Swaminathan 
112482527734SSukumar Swaminathan 			if (i == 0) {
112582527734SSukumar Swaminathan 				port->alpa_map[0] = 0;
112682527734SSukumar Swaminathan 			} else {
112782527734SSukumar Swaminathan 				uint8_t *alpa_map;
112882527734SSukumar Swaminathan 				uint32_t j;
112982527734SSukumar Swaminathan 
113082527734SSukumar Swaminathan 				/* Check number of devices in map */
113182527734SSukumar Swaminathan 				if (port->alpa_map[0] > 127) {
113282527734SSukumar Swaminathan 					port->alpa_map[0] = 127;
113382527734SSukumar Swaminathan 				}
113482527734SSukumar Swaminathan 
113582527734SSukumar Swaminathan 				alpa_map = (uint8_t *)port->alpa_map;
113682527734SSukumar Swaminathan 
113782527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
113882527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
113982527734SSukumar Swaminathan 				    "alpa_map: %d device(s):      "
114082527734SSukumar Swaminathan 				    "%02x %02x %02x %02x %02x %02x "
114182527734SSukumar Swaminathan 				    "%02x", alpa_map[0], alpa_map[1],
114282527734SSukumar Swaminathan 				    alpa_map[2], alpa_map[3],
114382527734SSukumar Swaminathan 				    alpa_map[4], alpa_map[5],
114482527734SSukumar Swaminathan 				    alpa_map[6], alpa_map[7]);
114582527734SSukumar Swaminathan 
114682527734SSukumar Swaminathan 				for (j = 8; j <= alpa_map[0]; j += 8) {
114782527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
114882527734SSukumar Swaminathan 					    &emlxs_link_atten_msg,
114982527734SSukumar Swaminathan 					    "alpa_map:             "
115082527734SSukumar Swaminathan 					    "%02x %02x %02x %02x %02x "
115182527734SSukumar Swaminathan 					    "%02x %02x %02x",
115282527734SSukumar Swaminathan 					    alpa_map[j],
115382527734SSukumar Swaminathan 					    alpa_map[j + 1],
115482527734SSukumar Swaminathan 					    alpa_map[j + 2],
115582527734SSukumar Swaminathan 					    alpa_map[j + 3],
115682527734SSukumar Swaminathan 					    alpa_map[j + 4],
115782527734SSukumar Swaminathan 					    alpa_map[j + 5],
115882527734SSukumar Swaminathan 					    alpa_map[j + 6],
115982527734SSukumar Swaminathan 					    alpa_map[j + 7]);
116082527734SSukumar Swaminathan 				}
116182527734SSukumar Swaminathan 			}
116282527734SSukumar Swaminathan 		}
116382527734SSukumar Swaminathan #ifdef MENLO_SUPPORT
116482527734SSukumar Swaminathan 		/* Check if Menlo maintenance mode is enabled */
116582527734SSukumar Swaminathan 		if (hba->model_info.device_id ==
116682527734SSukumar Swaminathan 		    PCI_DEVICE_ID_LP21000_M) {
116782527734SSukumar Swaminathan 			if (la.mm == 1) {
116882527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
116982527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
117082527734SSukumar Swaminathan 				    "Maintenance Mode enabled.");
117182527734SSukumar Swaminathan 
117282527734SSukumar Swaminathan 				mutex_enter(&EMLXS_PORT_LOCK);
117382527734SSukumar Swaminathan 				hba->flag |= FC_MENLO_MODE;
117482527734SSukumar Swaminathan 				mutex_exit(&EMLXS_PORT_LOCK);
117582527734SSukumar Swaminathan 
117682527734SSukumar Swaminathan 				mutex_enter(&EMLXS_LINKUP_LOCK);
117782527734SSukumar Swaminathan 				cv_broadcast(&EMLXS_LINKUP_CV);
117882527734SSukumar Swaminathan 				mutex_exit(&EMLXS_LINKUP_LOCK);
117982527734SSukumar Swaminathan 			} else {
118082527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
118182527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
118282527734SSukumar Swaminathan 				    "Maintenance Mode disabled.");
118382527734SSukumar Swaminathan 			}
1184291a2b48SSukumar Swaminathan 
118582527734SSukumar Swaminathan 			/* Check FCoE attention bit */
118682527734SSukumar Swaminathan 			if (la.fa == 1) {
118782527734SSukumar Swaminathan 				emlxs_thread_spawn(hba,
118882527734SSukumar Swaminathan 				    emlxs_fcoe_attention_thread,
1189*a9800bebSGarrett D'Amore 				    0, 0);
119082527734SSukumar Swaminathan 			}
119182527734SSukumar Swaminathan 		}
119282527734SSukumar Swaminathan #endif /* MENLO_SUPPORT */
1193fcf3ce44SJohn Forte 
119482527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
119582527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
119682527734SSukumar Swaminathan 			/* This should turn on DELAYED ABTS for */
119782527734SSukumar Swaminathan 			/* ELS timeouts */
119882527734SSukumar Swaminathan 			emlxs_mb_set_var(hba, mbox, 0x00052198, 0x1);
1199fcf3ce44SJohn Forte 
120082527734SSukumar Swaminathan 			emlxs_mb_put(hba, mbox);
120182527734SSukumar Swaminathan 		}
1202fcf3ce44SJohn Forte 
120382527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
120482527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
120582527734SSukumar Swaminathan 			/* If link not already down then */
120682527734SSukumar Swaminathan 			/* declare it down now */
120782527734SSukumar Swaminathan 			if (emlxs_mb_read_sparam(hba, mbox) == 0) {
120882527734SSukumar Swaminathan 				emlxs_mb_put(hba, mbox);
120982527734SSukumar Swaminathan 			} else {
1210*a9800bebSGarrett D'Amore 				emlxs_mem_put(hba, MEM_MBOX,
1211*a9800bebSGarrett D'Amore 				    (void *)mbox);
121282527734SSukumar Swaminathan 			}
121382527734SSukumar Swaminathan 		}
121482527734SSukumar Swaminathan 
121582527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
121682527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
121782527734SSukumar Swaminathan 			emlxs_mb_config_link(hba, mbox);
1218fcf3ce44SJohn Forte 
121982527734SSukumar Swaminathan 			emlxs_mb_put(hba, mbox);
122082527734SSukumar Swaminathan 		}
1221fcf3ce44SJohn Forte 
122282527734SSukumar Swaminathan 		/* Declare the linkup here */
122382527734SSukumar Swaminathan 		emlxs_linkup(hba);
1224fcf3ce44SJohn Forte 	}
1225fcf3ce44SJohn Forte 
122682527734SSukumar Swaminathan 	/* If link not already down then declare it down now */
122782527734SSukumar Swaminathan 	else if (la.attType == AT_LINK_DOWN) {
122882527734SSukumar Swaminathan 		/* Make sure link is declared down */
122982527734SSukumar Swaminathan 		emlxs_linkdown(hba);
123082527734SSukumar Swaminathan 	}
1231fcf3ce44SJohn Forte 
123282527734SSukumar Swaminathan 	/* Enable Link attention interrupt */
123382527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
1234fcf3ce44SJohn Forte 
123582527734SSukumar Swaminathan 	if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
123682527734SSukumar Swaminathan 		hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
123782527734SSukumar Swaminathan 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
123882527734SSukumar Swaminathan #ifdef FMA_SUPPORT
123982527734SSukumar Swaminathan 		/* Access handle validation */
124082527734SSukumar Swaminathan 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
124182527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
124282527734SSukumar Swaminathan 	}
1243fcf3ce44SJohn Forte 
124482527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
1245fcf3ce44SJohn Forte 
1246fcf3ce44SJohn Forte 	return (0);
124782527734SSukumar Swaminathan 
1248*a9800bebSGarrett D'Amore } /* emlxs_read_la_mbcmpl() */
1249fcf3ce44SJohn Forte 
1250fcf3ce44SJohn Forte 
1251*a9800bebSGarrett D'Amore /* SLI3 */
1252fcf3ce44SJohn Forte extern uint32_t
125382527734SSukumar Swaminathan emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
1254fcf3ce44SJohn Forte {
125582527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1256fcf3ce44SJohn Forte 	MATCHMAP *mp;
1257fcf3ce44SJohn Forte 
1258291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1259fcf3ce44SJohn Forte 
126082527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
1261fcf3ce44SJohn Forte 		mb->mbxCommand = MBX_READ_LA64;
1262fcf3ce44SJohn Forte 
1263fcf3ce44SJohn Forte 		return (1);
1264fcf3ce44SJohn Forte 	}
1265291a2b48SSukumar Swaminathan 
1266fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_LA64;
1267fcf3ce44SJohn Forte 	mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
126882527734SSukumar Swaminathan 	mb->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys);
126982527734SSukumar Swaminathan 	mb->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys);
1270fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1271*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_read_la_mbcmpl;
1272*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1273fcf3ce44SJohn Forte 
1274fcf3ce44SJohn Forte 	/*
1275fcf3ce44SJohn Forte 	 * save address for completion
1276fcf3ce44SJohn Forte 	 */
1277*a9800bebSGarrett D'Amore 	mbq->bp = (void *)mp;
1278fcf3ce44SJohn Forte 
1279fcf3ce44SJohn Forte 	return (0);
1280fcf3ce44SJohn Forte 
1281fcf3ce44SJohn Forte } /* emlxs_mb_read_la() */
1282fcf3ce44SJohn Forte 
1283fcf3ce44SJohn Forte 
1284*a9800bebSGarrett D'Amore /* SLI3 */
1285*a9800bebSGarrett D'Amore static uint32_t
1286*a9800bebSGarrett D'Amore emlxs_clear_la_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
128782527734SSukumar Swaminathan {
1288*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
128982527734SSukumar Swaminathan 	MAILBOX *mb;
129082527734SSukumar Swaminathan 	MAILBOXQ *mbox;
129182527734SSukumar Swaminathan 	emlxs_port_t *vport;
129282527734SSukumar Swaminathan 	uint32_t la_enable;
129382527734SSukumar Swaminathan 	int i, rc;
129482527734SSukumar Swaminathan 
129582527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
129682527734SSukumar Swaminathan 	if (mb->mbxStatus) {
129782527734SSukumar Swaminathan 		la_enable = 1;
129882527734SSukumar Swaminathan 
129982527734SSukumar Swaminathan 		if (mb->mbxStatus == 0x1601) {
130082527734SSukumar Swaminathan 			/* Get a buffer which will be used for */
130182527734SSukumar Swaminathan 			/* mailbox commands */
130282527734SSukumar Swaminathan 			if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
130382527734SSukumar Swaminathan 			    MEM_MBOX, 1))) {
130482527734SSukumar Swaminathan 				/* Get link attention message */
130582527734SSukumar Swaminathan 				if (emlxs_mb_read_la(hba, mbox) == 0) {
130682527734SSukumar Swaminathan 					rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba,
130782527734SSukumar Swaminathan 					    (MAILBOX *)mbox, MBX_NOWAIT, 0);
130882527734SSukumar Swaminathan 					if ((rc != MBX_BUSY) &&
130982527734SSukumar Swaminathan 					    (rc != MBX_SUCCESS)) {
1310*a9800bebSGarrett D'Amore 						emlxs_mem_put(hba,
1311*a9800bebSGarrett D'Amore 						    MEM_MBOX, (void *)mbox);
131282527734SSukumar Swaminathan 					}
131382527734SSukumar Swaminathan 					la_enable = 0;
131482527734SSukumar Swaminathan 				} else {
1315*a9800bebSGarrett D'Amore 					emlxs_mem_put(hba, MEM_MBOX,
1316*a9800bebSGarrett D'Amore 					    (void *)mbox);
131782527734SSukumar Swaminathan 				}
131882527734SSukumar Swaminathan 			}
131982527734SSukumar Swaminathan 		}
132082527734SSukumar Swaminathan 
132182527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
132282527734SSukumar Swaminathan 		if (la_enable) {
132382527734SSukumar Swaminathan 			if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
132482527734SSukumar Swaminathan 				/* Enable Link Attention interrupts */
132582527734SSukumar Swaminathan 				hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
132682527734SSukumar Swaminathan 				WRITE_CSR_REG(hba, FC_HC_REG(hba),
132782527734SSukumar Swaminathan 				    hba->sli.sli3.hc_copy);
132882527734SSukumar Swaminathan #ifdef FMA_SUPPORT
132982527734SSukumar Swaminathan 				/* Access handle validation */
133082527734SSukumar Swaminathan 				EMLXS_CHK_ACC_HANDLE(hba,
133182527734SSukumar Swaminathan 				    hba->sli.sli3.csr_acc_handle);
133282527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
133382527734SSukumar Swaminathan 			}
133482527734SSukumar Swaminathan 		} else {
133582527734SSukumar Swaminathan 			if (hba->sli.sli3.hc_copy & HC_LAINT_ENA) {
133682527734SSukumar Swaminathan 				/* Disable Link Attention interrupts */
133782527734SSukumar Swaminathan 				hba->sli.sli3.hc_copy &= ~HC_LAINT_ENA;
133882527734SSukumar Swaminathan 				WRITE_CSR_REG(hba, FC_HC_REG(hba),
133982527734SSukumar Swaminathan 				    hba->sli.sli3.hc_copy);
134082527734SSukumar Swaminathan #ifdef FMA_SUPPORT
134182527734SSukumar Swaminathan 				/* Access handle validation */
134282527734SSukumar Swaminathan 				EMLXS_CHK_ACC_HANDLE(hba,
134382527734SSukumar Swaminathan 				    hba->sli.sli3.csr_acc_handle);
134482527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
134582527734SSukumar Swaminathan 			}
134682527734SSukumar Swaminathan 		}
134782527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
134882527734SSukumar Swaminathan 
134982527734SSukumar Swaminathan 		return (0);
135082527734SSukumar Swaminathan 	}
135182527734SSukumar Swaminathan 	/* Enable on Link Attention interrupts */
135282527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
135382527734SSukumar Swaminathan 
135482527734SSukumar Swaminathan 	if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
135582527734SSukumar Swaminathan 		hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
135682527734SSukumar Swaminathan 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
135782527734SSukumar Swaminathan #ifdef FMA_SUPPORT
135882527734SSukumar Swaminathan 		/* Access handle validation */
135982527734SSukumar Swaminathan 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
136082527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
136182527734SSukumar Swaminathan 	}
136282527734SSukumar Swaminathan 
136382527734SSukumar Swaminathan 	if (hba->state >= FC_LINK_UP) {
136482527734SSukumar Swaminathan 		EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
136582527734SSukumar Swaminathan 	}
136682527734SSukumar Swaminathan 
136782527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
136882527734SSukumar Swaminathan 
136982527734SSukumar Swaminathan 	/* Adapter is now ready for FCP traffic */
137082527734SSukumar Swaminathan 	if (hba->state == FC_READY) {
1371*a9800bebSGarrett D'Amore 
137282527734SSukumar Swaminathan 		/* Register vpi's for all ports that have did's */
137382527734SSukumar Swaminathan 		for (i = 0; i < MAX_VPORTS; i++) {
137482527734SSukumar Swaminathan 			vport = &VPORT(i);
137582527734SSukumar Swaminathan 
137682527734SSukumar Swaminathan 			if (!(vport->flag & EMLXS_PORT_BOUND) ||
137782527734SSukumar Swaminathan 			    !(vport->did)) {
137882527734SSukumar Swaminathan 				continue;
137982527734SSukumar Swaminathan 			}
138082527734SSukumar Swaminathan 
138182527734SSukumar Swaminathan 			(void) emlxs_mb_reg_vpi(vport, NULL);
138282527734SSukumar Swaminathan 		}
138382527734SSukumar Swaminathan 
138482527734SSukumar Swaminathan 		/* Attempt to send any pending IO */
138582527734SSukumar Swaminathan 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[hba->channel_fcp], 0);
138682527734SSukumar Swaminathan 	}
138782527734SSukumar Swaminathan 	return (0);
138882527734SSukumar Swaminathan 
1389*a9800bebSGarrett D'Amore } /* emlxs_clear_la_mbcmpl() */
139082527734SSukumar Swaminathan 
139182527734SSukumar Swaminathan 
1392*a9800bebSGarrett D'Amore /* SLI3 */
1393fcf3ce44SJohn Forte extern void
139482527734SSukumar Swaminathan emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
1395fcf3ce44SJohn Forte {
139682527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
139782527734SSukumar Swaminathan 
1398fcf3ce44SJohn Forte #ifdef FC_RPI_CHECK
1399fcf3ce44SJohn Forte 	emlxs_rpi_check(hba);
1400fcf3ce44SJohn Forte #endif	/* FC_RPI_CHECK */
1401fcf3ce44SJohn Forte 
1402291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1403fcf3ce44SJohn Forte 
1404fcf3ce44SJohn Forte 	mb->un.varClearLA.eventTag = hba->link_event_tag;
1405fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CLEAR_LA;
1406fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1407*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_clear_la_mbcmpl;
1408*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1409fcf3ce44SJohn Forte 
1410fcf3ce44SJohn Forte 	return;
1411fcf3ce44SJohn Forte 
141282527734SSukumar Swaminathan } /* emlxs_mb_clear_la() */
1413fcf3ce44SJohn Forte 
1414fcf3ce44SJohn Forte 
1415fcf3ce44SJohn Forte /*
1416291a2b48SSukumar Swaminathan  * emlxs_mb_read_status  Issue a READ STATUS mailbox command
1417fcf3ce44SJohn Forte  */
1418291a2b48SSukumar Swaminathan /*ARGSUSED*/
1419fcf3ce44SJohn Forte extern void
142082527734SSukumar Swaminathan emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOXQ *mbq)
1421fcf3ce44SJohn Forte {
142282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
142382527734SSukumar Swaminathan 
1424291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1425fcf3ce44SJohn Forte 
1426fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_STATUS;
1427fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
142882527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1429*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
143082527734SSukumar Swaminathan 
143182527734SSukumar Swaminathan } /* fc_read_status() */
143282527734SSukumar Swaminathan 
1433fcf3ce44SJohn Forte 
1434fcf3ce44SJohn Forte /*
1435291a2b48SSukumar Swaminathan  * emlxs_mb_read_lnk_stat  Issue a LINK STATUS mailbox command
1436fcf3ce44SJohn Forte  */
1437291a2b48SSukumar Swaminathan /*ARGSUSED*/
1438fcf3ce44SJohn Forte extern void
143982527734SSukumar Swaminathan emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOXQ *mbq)
1440fcf3ce44SJohn Forte {
144182527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
144282527734SSukumar Swaminathan 
1443291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1444fcf3ce44SJohn Forte 
1445fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_LNK_STAT;
1446fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
144782527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1448*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
144982527734SSukumar Swaminathan 
145082527734SSukumar Swaminathan } /* emlxs_mb_read_lnk_stat() */
1451fcf3ce44SJohn Forte 
1452fcf3ce44SJohn Forte 
1453fcf3ce44SJohn Forte 
145482527734SSukumar Swaminathan 
1455fcf3ce44SJohn Forte 
1456fcf3ce44SJohn Forte 
1457fcf3ce44SJohn Forte /*
1458291a2b48SSukumar Swaminathan  * emlxs_mb_config_ring  Issue a CONFIG RING mailbox command
1459fcf3ce44SJohn Forte  */
1460fcf3ce44SJohn Forte extern void
146182527734SSukumar Swaminathan emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOXQ *mbq)
1462fcf3ce44SJohn Forte {
146382527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1464fcf3ce44SJohn Forte 	int32_t i;
1465fcf3ce44SJohn Forte 	int32_t j;
1466fcf3ce44SJohn Forte 
1467291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1468fcf3ce44SJohn Forte 
1469fcf3ce44SJohn Forte 	j = 0;
1470fcf3ce44SJohn Forte 	for (i = 0; i < ring; i++) {
147182527734SSukumar Swaminathan 		j += hba->sli.sli3.ring_masks[i];
1472fcf3ce44SJohn Forte 	}
1473fcf3ce44SJohn Forte 
147482527734SSukumar Swaminathan 	for (i = 0; i < hba->sli.sli3.ring_masks[ring]; i++) {
1475fcf3ce44SJohn Forte 		if ((j + i) >= 6) {
1476fcf3ce44SJohn Forte 			break;
1477fcf3ce44SJohn Forte 		}
1478291a2b48SSukumar Swaminathan 
147982527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].rval  =
148082527734SSukumar Swaminathan 		    hba->sli.sli3.ring_rval[j + i];
148182527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].rmask =
148282527734SSukumar Swaminathan 		    hba->sli.sli3.ring_rmask[j + i];
148382527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].tval  =
148482527734SSukumar Swaminathan 		    hba->sli.sli3.ring_tval[j + i];
148582527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].tmask =
148682527734SSukumar Swaminathan 		    hba->sli.sli3.ring_tmask[j + i];
1487fcf3ce44SJohn Forte 	}
1488fcf3ce44SJohn Forte 
1489fcf3ce44SJohn Forte 	mb->un.varCfgRing.ring = ring;
1490fcf3ce44SJohn Forte 	mb->un.varCfgRing.profile = 0;
1491fcf3ce44SJohn Forte 	mb->un.varCfgRing.maxOrigXchg = 0;
1492fcf3ce44SJohn Forte 	mb->un.varCfgRing.maxRespXchg = 0;
1493fcf3ce44SJohn Forte 	mb->un.varCfgRing.recvNotify = 1;
149482527734SSukumar Swaminathan 	mb->un.varCfgRing.numMask = hba->sli.sli3.ring_masks[ring];
1495fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_RING;
1496fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
149782527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1498*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1499fcf3ce44SJohn Forte 
1500fcf3ce44SJohn Forte 	return;
1501fcf3ce44SJohn Forte 
150282527734SSukumar Swaminathan } /* emlxs_mb_config_ring() */
1503fcf3ce44SJohn Forte 
1504fcf3ce44SJohn Forte 
1505fcf3ce44SJohn Forte /*
1506291a2b48SSukumar Swaminathan  *  emlxs_mb_config_link  Issue a CONFIG LINK mailbox command
1507fcf3ce44SJohn Forte  */
1508fcf3ce44SJohn Forte extern void
150982527734SSukumar Swaminathan emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
1510fcf3ce44SJohn Forte {
151182527734SSukumar Swaminathan 	MAILBOX	*mb = (MAILBOX *)mbq;
1512291a2b48SSukumar Swaminathan 	emlxs_port_t   *port = &PPORT;
1513fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1514fcf3ce44SJohn Forte 
1515291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1516fcf3ce44SJohn Forte 
1517fcf3ce44SJohn Forte 	/*
1518fcf3ce44SJohn Forte 	 * NEW_FEATURE SLI-2, Coalescing Response Feature.
1519fcf3ce44SJohn Forte 	 */
1520fcf3ce44SJohn Forte 	if (cfg[CFG_CR_DELAY].current) {
1521fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr = 1;
1522fcf3ce44SJohn Forte 		mb->un.varCfgLnk.ci = 1;
1523fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
1524fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
1525fcf3ce44SJohn Forte 	}
1526291a2b48SSukumar Swaminathan 
1527fcf3ce44SJohn Forte 	if (cfg[CFG_ACK0].current)
1528fcf3ce44SJohn Forte 		mb->un.varCfgLnk.ack0_enable = 1;
1529fcf3ce44SJohn Forte 
1530fcf3ce44SJohn Forte 	mb->un.varCfgLnk.myId = port->did;
1531fcf3ce44SJohn Forte 	mb->un.varCfgLnk.edtov = hba->fc_edtov;
1532fcf3ce44SJohn Forte 	mb->un.varCfgLnk.arbtov = hba->fc_arbtov;
1533fcf3ce44SJohn Forte 	mb->un.varCfgLnk.ratov = hba->fc_ratov;
1534fcf3ce44SJohn Forte 	mb->un.varCfgLnk.rttov = hba->fc_rttov;
1535fcf3ce44SJohn Forte 	mb->un.varCfgLnk.altov = hba->fc_altov;
1536fcf3ce44SJohn Forte 	mb->un.varCfgLnk.crtov = hba->fc_crtov;
1537fcf3ce44SJohn Forte 	mb->un.varCfgLnk.citov = hba->fc_citov;
1538fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_LINK;
1539fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
154082527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
1541*a9800bebSGarrett D'Amore 	mbq->port = (void *)port;
1542fcf3ce44SJohn Forte 
1543fcf3ce44SJohn Forte 	return;
1544fcf3ce44SJohn Forte 
1545fcf3ce44SJohn Forte } /* emlxs_mb_config_link() */
1546fcf3ce44SJohn Forte 
1547fcf3ce44SJohn Forte 
1548*a9800bebSGarrett D'Amore static uint32_t
1549*a9800bebSGarrett D'Amore emlxs_init_link_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
155082527734SSukumar Swaminathan {
1551*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
155282527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
155382527734SSukumar Swaminathan 	MAILBOX *mb;
155482527734SSukumar Swaminathan 
155582527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
155682527734SSukumar Swaminathan 	if (mb->mbxStatus) {
155782527734SSukumar Swaminathan 		if ((hba->flag & FC_SLIM2_MODE) &&
155882527734SSukumar Swaminathan 		    (hba->mbox_queue_flag == MBX_NOWAIT)) {
155982527734SSukumar Swaminathan 			/* Retry only MBX_NOWAIT requests */
156082527734SSukumar Swaminathan 
156182527734SSukumar Swaminathan 			if ((cfg[CFG_LINK_SPEED].current > 0) &&
156282527734SSukumar Swaminathan 			    ((mb->mbxStatus == 0x0011) ||
156382527734SSukumar Swaminathan 			    (mb->mbxStatus == 0x0500))) {
156482527734SSukumar Swaminathan 
156582527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
156682527734SSukumar Swaminathan 				    &emlxs_mbox_event_msg,
156782527734SSukumar Swaminathan 				    "Retrying.  %s: status=%x. Auto-speed set.",
156882527734SSukumar Swaminathan 				    emlxs_mb_cmd_xlate(mb->mbxCommand),
156982527734SSukumar Swaminathan 				    (uint32_t)mb->mbxStatus);
157082527734SSukumar Swaminathan 
157182527734SSukumar Swaminathan 				mb->un.varInitLnk.link_flags &=
157282527734SSukumar Swaminathan 				    ~FLAGS_LINK_SPEED;
157382527734SSukumar Swaminathan 				mb->un.varInitLnk.link_speed = 0;
157482527734SSukumar Swaminathan 
157582527734SSukumar Swaminathan 				emlxs_mb_retry(hba, mbq);
157682527734SSukumar Swaminathan 				return (1);
157782527734SSukumar Swaminathan 			}
157882527734SSukumar Swaminathan 		}
157982527734SSukumar Swaminathan 	}
158082527734SSukumar Swaminathan 	return (0);
158182527734SSukumar Swaminathan 
1582*a9800bebSGarrett D'Amore } /* emlxs_init_link_mbcmpl() */
158382527734SSukumar Swaminathan 
158482527734SSukumar Swaminathan 
1585fcf3ce44SJohn Forte /*
1586291a2b48SSukumar Swaminathan  *  emlxs_mb_init_link  Issue an INIT LINK mailbox command
1587fcf3ce44SJohn Forte  */
1588fcf3ce44SJohn Forte extern void
158982527734SSukumar Swaminathan emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t topology,
1590fcf3ce44SJohn Forte     uint32_t linkspeed)
1591fcf3ce44SJohn Forte {
159282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1593291a2b48SSukumar Swaminathan 	emlxs_vpd_t	*vpd = &VPD;
1594291a2b48SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1595fcf3ce44SJohn Forte 
159682527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
159782527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
159882527734SSukumar Swaminathan 		mbq->nonembed = NULL;
159982527734SSukumar Swaminathan 		mbq->mbox_cmpl = NULL; /* no cmpl needed */
1600*a9800bebSGarrett D'Amore 		mbq->port = (void *)&PPORT;
160182527734SSukumar Swaminathan 
160282527734SSukumar Swaminathan 		mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
160382527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
160482527734SSukumar Swaminathan 		return;
160582527734SSukumar Swaminathan 	}
160682527734SSukumar Swaminathan 
1607291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1608fcf3ce44SJohn Forte 
1609fcf3ce44SJohn Forte 	switch (topology) {
1610fcf3ce44SJohn Forte 	case FLAGS_LOCAL_LB:
1611fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
1612fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB;
1613fcf3ce44SJohn Forte 		break;
1614fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_LOOP_PT:
1615fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
1616fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
1617fcf3ce44SJohn Forte 		break;
1618fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_PT_PT:
1619fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
1620fcf3ce44SJohn Forte 		break;
1621fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_LOOP:
1622fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
1623fcf3ce44SJohn Forte 		break;
1624fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_PT_LOOP:
1625fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
1626fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
1627fcf3ce44SJohn Forte 		break;
1628fcf3ce44SJohn Forte 	}
1629fcf3ce44SJohn Forte 
1630fcf3ce44SJohn Forte 	if (cfg[CFG_LILP_ENABLE].current == 0) {
1631fcf3ce44SJohn Forte 		/* Disable LIRP/LILP support */
1632fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP;
1633fcf3ce44SJohn Forte 	}
1634291a2b48SSukumar Swaminathan 
1635fcf3ce44SJohn Forte 	/*
1636fcf3ce44SJohn Forte 	 * Setting up the link speed
1637fcf3ce44SJohn Forte 	 */
1638fcf3ce44SJohn Forte 	switch (linkspeed) {
1639fcf3ce44SJohn Forte 	case 0:
1640fcf3ce44SJohn Forte 		break;
1641fcf3ce44SJohn Forte 
1642fcf3ce44SJohn Forte 	case 1:
1643fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_1GB_CAPABLE)) {
1644fcf3ce44SJohn Forte 			linkspeed = 0;
1645fcf3ce44SJohn Forte 		}
1646fcf3ce44SJohn Forte 		break;
1647fcf3ce44SJohn Forte 
1648fcf3ce44SJohn Forte 	case 2:
1649fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_2GB_CAPABLE)) {
1650fcf3ce44SJohn Forte 			linkspeed = 0;
1651fcf3ce44SJohn Forte 		}
1652fcf3ce44SJohn Forte 		break;
1653fcf3ce44SJohn Forte 
1654fcf3ce44SJohn Forte 	case 4:
1655fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_4GB_CAPABLE)) {
1656fcf3ce44SJohn Forte 			linkspeed = 0;
1657fcf3ce44SJohn Forte 		}
1658fcf3ce44SJohn Forte 		break;
1659fcf3ce44SJohn Forte 
1660fcf3ce44SJohn Forte 	case 8:
1661fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_8GB_CAPABLE)) {
1662fcf3ce44SJohn Forte 			linkspeed = 0;
1663fcf3ce44SJohn Forte 		}
1664fcf3ce44SJohn Forte 		break;
1665fcf3ce44SJohn Forte 
1666fcf3ce44SJohn Forte 	case 10:
1667fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_10GB_CAPABLE)) {
1668fcf3ce44SJohn Forte 			linkspeed = 0;
1669fcf3ce44SJohn Forte 		}
1670fcf3ce44SJohn Forte 		break;
1671fcf3ce44SJohn Forte 
1672fcf3ce44SJohn Forte 	default:
1673fcf3ce44SJohn Forte 		linkspeed = 0;
1674fcf3ce44SJohn Forte 		break;
1675fcf3ce44SJohn Forte 
1676fcf3ce44SJohn Forte 	}
1677fcf3ce44SJohn Forte 
1678fcf3ce44SJohn Forte 	if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) {
1679fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
1680fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_speed = linkspeed;
1681fcf3ce44SJohn Forte 	}
1682291a2b48SSukumar Swaminathan 
1683fcf3ce44SJohn Forte 	mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN;
1684fcf3ce44SJohn Forte 
1685291a2b48SSukumar Swaminathan 	mb->un.varInitLnk.fabric_AL_PA =
1686291a2b48SSukumar Swaminathan 	    (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
1687fcf3ce44SJohn Forte 	mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
1688fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1689*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_init_link_mbcmpl;
1690*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1691fcf3ce44SJohn Forte 
1692fcf3ce44SJohn Forte 
1693fcf3ce44SJohn Forte 	return;
1694fcf3ce44SJohn Forte 
1695fcf3ce44SJohn Forte } /* emlxs_mb_init_link() */
1696fcf3ce44SJohn Forte 
1697fcf3ce44SJohn Forte 
1698fcf3ce44SJohn Forte /*
1699291a2b48SSukumar Swaminathan  *  emlxs_mb_down_link  Issue a DOWN LINK mailbox command
1700fcf3ce44SJohn Forte  */
1701291a2b48SSukumar Swaminathan /*ARGSUSED*/
1702fcf3ce44SJohn Forte extern void
170382527734SSukumar Swaminathan emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
1704fcf3ce44SJohn Forte {
170582527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
170682527734SSukumar Swaminathan 
1707291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1708fcf3ce44SJohn Forte 
1709fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_DOWN_LINK;
1710fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
171182527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
1712*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1713fcf3ce44SJohn Forte 
1714fcf3ce44SJohn Forte 	return;
1715fcf3ce44SJohn Forte 
1716fcf3ce44SJohn Forte } /* emlxs_mb_down_link() */
1717fcf3ce44SJohn Forte 
1718fcf3ce44SJohn Forte 
1719*a9800bebSGarrett D'Amore static uint32_t
1720*a9800bebSGarrett D'Amore emlxs_read_sparam_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
172182527734SSukumar Swaminathan {
1722*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
172382527734SSukumar Swaminathan 	MAILBOX *mb;
172482527734SSukumar Swaminathan 	MATCHMAP *mp;
172582527734SSukumar Swaminathan 	emlxs_port_t *vport;
172682527734SSukumar Swaminathan 	int32_t i;
172782527734SSukumar Swaminathan 	uint32_t  control;
172882527734SSukumar Swaminathan 	uint8_t null_wwn[8];
172982527734SSukumar Swaminathan 
173082527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
173182527734SSukumar Swaminathan 	if (mb->mbxStatus) {
173282527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
173382527734SSukumar Swaminathan 			control = mb->un.varRdSparm.un.sp64.tus.f.bdeSize;
173482527734SSukumar Swaminathan 			if (control == 0) {
173582527734SSukumar Swaminathan 				(void) emlxs_mb_read_sparam(hba, mbq);
173682527734SSukumar Swaminathan 			}
173782527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
173882527734SSukumar Swaminathan 			return (1);
173982527734SSukumar Swaminathan 		}
174082527734SSukumar Swaminathan 		return (0);
174182527734SSukumar Swaminathan 	}
174282527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
174382527734SSukumar Swaminathan 	if (!mp) {
174482527734SSukumar Swaminathan 		return (0);
174582527734SSukumar Swaminathan 	}
174682527734SSukumar Swaminathan 
174782527734SSukumar Swaminathan 	bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM));
174882527734SSukumar Swaminathan 
174982527734SSukumar Swaminathan 	/* Initialize the node name and port name only once */
175082527734SSukumar Swaminathan 	bzero(null_wwn, 8);
175182527734SSukumar Swaminathan 	if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) &&
175282527734SSukumar Swaminathan 	    (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) {
175382527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam.nodeName,
175482527734SSukumar Swaminathan 		    (caddr_t)&hba->wwnn, sizeof (NAME_TYPE));
175582527734SSukumar Swaminathan 
175682527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam.portName,
175782527734SSukumar Swaminathan 		    (caddr_t)&hba->wwpn, sizeof (NAME_TYPE));
175882527734SSukumar Swaminathan 	} else {
175982527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->wwnn,
176082527734SSukumar Swaminathan 		    (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE));
176182527734SSukumar Swaminathan 
176282527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->wwpn,
176382527734SSukumar Swaminathan 		    (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE));
176482527734SSukumar Swaminathan 	}
176582527734SSukumar Swaminathan 
176682527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
1767*a9800bebSGarrett D'Amore 	    "SPARAM: EDTOV hba=%x mbox_csp=%x BBC=%x",
176882527734SSukumar Swaminathan 	    hba->fc_edtov, hba->sparam.cmn.e_d_tov,
176982527734SSukumar Swaminathan 	    hba->sparam.cmn.bbCreditlsb);
177082527734SSukumar Swaminathan 
177182527734SSukumar Swaminathan 	hba->sparam.cmn.e_d_tov = hba->fc_edtov;
177282527734SSukumar Swaminathan 
177382527734SSukumar Swaminathan 	/* Initialize the physical port */
177482527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->sparam,
177582527734SSukumar Swaminathan 	    (caddr_t)&port->sparam, sizeof (SERV_PARM));
177682527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->wwpn, (caddr_t)&port->wwpn,
177782527734SSukumar Swaminathan 	    sizeof (NAME_TYPE));
177882527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->wwnn, (caddr_t)&port->wwnn,
177982527734SSukumar Swaminathan 	    sizeof (NAME_TYPE));
178082527734SSukumar Swaminathan 
178182527734SSukumar Swaminathan 	/* Initialize the virtual ports */
178282527734SSukumar Swaminathan 	for (i = 1; i < MAX_VPORTS; i++) {
178382527734SSukumar Swaminathan 		vport = &VPORT(i);
178482527734SSukumar Swaminathan 		if (vport->flag & EMLXS_PORT_BOUND) {
178582527734SSukumar Swaminathan 			continue;
178682527734SSukumar Swaminathan 		}
178782527734SSukumar Swaminathan 
178882527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam,
178982527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam,
179082527734SSukumar Swaminathan 		    sizeof (SERV_PARM));
179182527734SSukumar Swaminathan 
179282527734SSukumar Swaminathan 		bcopy((caddr_t)&vport->wwnn,
179382527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam.nodeName,
179482527734SSukumar Swaminathan 		    sizeof (NAME_TYPE));
179582527734SSukumar Swaminathan 
179682527734SSukumar Swaminathan 		bcopy((caddr_t)&vport->wwpn,
179782527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam.portName,
179882527734SSukumar Swaminathan 		    sizeof (NAME_TYPE));
179982527734SSukumar Swaminathan 	}
180082527734SSukumar Swaminathan 
180182527734SSukumar Swaminathan 	return (0);
180282527734SSukumar Swaminathan 
1803*a9800bebSGarrett D'Amore } /* emlxs_read_sparam_mbcmpl() */
180482527734SSukumar Swaminathan 
180582527734SSukumar Swaminathan 
1806fcf3ce44SJohn Forte /*
1807291a2b48SSukumar Swaminathan  * emlxs_mb_read_sparam  Issue a READ SPARAM mailbox command
1808fcf3ce44SJohn Forte  */
1809fcf3ce44SJohn Forte extern uint32_t
181082527734SSukumar Swaminathan emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOXQ *mbq)
1811fcf3ce44SJohn Forte {
181282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1813fcf3ce44SJohn Forte 	MATCHMAP *mp;
1814fcf3ce44SJohn Forte 
1815291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1816fcf3ce44SJohn Forte 
181782527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
1818fcf3ce44SJohn Forte 		mb->mbxCommand = MBX_READ_SPARM64;
1819fcf3ce44SJohn Forte 
1820fcf3ce44SJohn Forte 		return (1);
1821fcf3ce44SJohn Forte 	}
1822291a2b48SSukumar Swaminathan 
1823fcf3ce44SJohn Forte 	mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
182482527734SSukumar Swaminathan 	mb->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys);
182582527734SSukumar Swaminathan 	mb->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys);
1826fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_SPARM64;
1827fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1828*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_read_sparam_mbcmpl;
1829*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1830fcf3ce44SJohn Forte 
1831fcf3ce44SJohn Forte 	/*
1832fcf3ce44SJohn Forte 	 * save address for completion
1833fcf3ce44SJohn Forte 	 */
1834*a9800bebSGarrett D'Amore 	mbq->bp = (void *)mp;
1835fcf3ce44SJohn Forte 
1836fcf3ce44SJohn Forte 	return (0);
1837fcf3ce44SJohn Forte 
1838fcf3ce44SJohn Forte } /* emlxs_mb_read_sparam() */
1839fcf3ce44SJohn Forte 
1840fcf3ce44SJohn Forte 
1841fcf3ce44SJohn Forte /*
1842291a2b48SSukumar Swaminathan  * emlxs_mb_read_rpi    Issue a READ RPI mailbox command
1843fcf3ce44SJohn Forte  */
1844291a2b48SSukumar Swaminathan /*ARGSUSED*/
1845fcf3ce44SJohn Forte extern uint32_t
184682527734SSukumar Swaminathan emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOXQ *mbq,
1847291a2b48SSukumar Swaminathan     uint32_t flag)
1848fcf3ce44SJohn Forte {
184982527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
185082527734SSukumar Swaminathan 
1851291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1852fcf3ce44SJohn Forte 
1853fcf3ce44SJohn Forte 	/*
1854fcf3ce44SJohn Forte 	 * Set flag to issue action on cmpl
1855fcf3ce44SJohn Forte 	 */
1856fcf3ce44SJohn Forte 	mb->un.varWords[30] = flag;
1857fcf3ce44SJohn Forte 	mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi;
1858fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_RPI64;
1859fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
186082527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1861*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
1862fcf3ce44SJohn Forte 
1863fcf3ce44SJohn Forte 	return (0);
186482527734SSukumar Swaminathan } /* emlxs_mb_read_rpi() */
1865fcf3ce44SJohn Forte 
1866fcf3ce44SJohn Forte 
1867fcf3ce44SJohn Forte /*
1868291a2b48SSukumar Swaminathan  * emlxs_mb_read_xri    Issue a READ XRI mailbox command
1869fcf3ce44SJohn Forte  */
1870291a2b48SSukumar Swaminathan /*ARGSUSED*/
1871fcf3ce44SJohn Forte extern uint32_t
187282527734SSukumar Swaminathan emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOXQ *mbq,
1873291a2b48SSukumar Swaminathan     uint32_t flag)
1874fcf3ce44SJohn Forte {
187582527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
187682527734SSukumar Swaminathan 
1877291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1878fcf3ce44SJohn Forte 
1879fcf3ce44SJohn Forte 	/*
1880fcf3ce44SJohn Forte 	 * Set flag to issue action on cmpl
1881fcf3ce44SJohn Forte 	 */
1882fcf3ce44SJohn Forte 	mb->un.varWords[30] = flag;
1883291a2b48SSukumar Swaminathan 	mb->un.varRdXRI.reqXri = (volatile uint16_t)xri;
1884fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_XRI;
1885fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
188682527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1887*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
188882527734SSukumar Swaminathan 
188982527734SSukumar Swaminathan 	return (0);
189082527734SSukumar Swaminathan } /* emlxs_mb_read_xri() */
189182527734SSukumar Swaminathan 
189282527734SSukumar Swaminathan 
189382527734SSukumar Swaminathan /*ARGSUSED*/
189482527734SSukumar Swaminathan extern int32_t
189582527734SSukumar Swaminathan emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp)
189682527734SSukumar Swaminathan {
189782527734SSukumar Swaminathan 	uint32_t nsp_value;
189882527734SSukumar Swaminathan 	uint32_t *iptr;
189982527734SSukumar Swaminathan 
190082527734SSukumar Swaminathan 	if (nsp->cmn.fPort) {
190182527734SSukumar Swaminathan 		return (0);
190282527734SSukumar Swaminathan 	}
190382527734SSukumar Swaminathan 
190482527734SSukumar Swaminathan 	/* Validate the service parameters */
190582527734SSukumar Swaminathan 	iptr = (uint32_t *)&nsp->portName;
190682527734SSukumar Swaminathan 	if (iptr[0] == 0 && iptr[1] == 0) {
190782527734SSukumar Swaminathan 		return (1);
190882527734SSukumar Swaminathan 	}
190982527734SSukumar Swaminathan 
191082527734SSukumar Swaminathan 	iptr = (uint32_t *)&nsp->nodeName;
191182527734SSukumar Swaminathan 	if (iptr[0] == 0 && iptr[1] == 0) {
191282527734SSukumar Swaminathan 		return (2);
191382527734SSukumar Swaminathan 	}
191482527734SSukumar Swaminathan 
191582527734SSukumar Swaminathan 	if (nsp->cls2.classValid) {
191682527734SSukumar Swaminathan 		nsp_value =
191782527734SSukumar Swaminathan 		    ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls2.
191882527734SSukumar Swaminathan 		    rcvDataSizeLsb;
191982527734SSukumar Swaminathan 
192082527734SSukumar Swaminathan 		/* If the receive data length is zero then set it to */
192182527734SSukumar Swaminathan 		/* the CSP value */
192282527734SSukumar Swaminathan 		if (!nsp_value) {
192382527734SSukumar Swaminathan 			nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
192482527734SSukumar Swaminathan 			nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
192582527734SSukumar Swaminathan 			return (0);
192682527734SSukumar Swaminathan 		}
192782527734SSukumar Swaminathan 	}
192882527734SSukumar Swaminathan 
192982527734SSukumar Swaminathan 	if (nsp->cls3.classValid) {
193082527734SSukumar Swaminathan 		nsp_value =
193182527734SSukumar Swaminathan 		    ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls3.
193282527734SSukumar Swaminathan 		    rcvDataSizeLsb;
193382527734SSukumar Swaminathan 
193482527734SSukumar Swaminathan 		/* If the receive data length is zero then set it to */
193582527734SSukumar Swaminathan 		/* the CSP value */
193682527734SSukumar Swaminathan 		if (!nsp_value) {
193782527734SSukumar Swaminathan 			nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
193882527734SSukumar Swaminathan 			nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
193982527734SSukumar Swaminathan 			return (0);
194082527734SSukumar Swaminathan 		}
194182527734SSukumar Swaminathan 	}
194282527734SSukumar Swaminathan 
194382527734SSukumar Swaminathan 	return (0);
194482527734SSukumar Swaminathan 
194582527734SSukumar Swaminathan } /* emlxs_mb_check_sparm() */
194682527734SSukumar Swaminathan 
194782527734SSukumar Swaminathan 
1948*a9800bebSGarrett D'Amore /* SLI3 */
1949*a9800bebSGarrett D'Amore static uint32_t
1950*a9800bebSGarrett D'Amore emlxs_reg_did_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
195182527734SSukumar Swaminathan {
1952*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
195382527734SSukumar Swaminathan 	MAILBOX *mb;
195482527734SSukumar Swaminathan 	MATCHMAP *mp;
195582527734SSukumar Swaminathan 	NODELIST *ndlp;
195682527734SSukumar Swaminathan 	emlxs_port_t *vport;
1957*a9800bebSGarrett D'Amore 	SERV_PARM *sp;
195882527734SSukumar Swaminathan 	int32_t i;
195982527734SSukumar Swaminathan 	uint32_t  control;
196082527734SSukumar Swaminathan 	uint32_t ldata;
196182527734SSukumar Swaminathan 	uint32_t ldid;
196282527734SSukumar Swaminathan 	uint16_t lrpi;
196382527734SSukumar Swaminathan 	uint16_t lvpi;
196482527734SSukumar Swaminathan 
196582527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
1966*a9800bebSGarrett D'Amore 
196782527734SSukumar Swaminathan 	if (mb->mbxStatus) {
196882527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
196982527734SSukumar Swaminathan 			control = mb->un.varRegLogin.un.sp.bdeSize;
197082527734SSukumar Swaminathan 			if (control == 0) {
197182527734SSukumar Swaminathan 				/* Special handle for vport PLOGI */
197282527734SSukumar Swaminathan 				if (mbq->iocbq == (uint8_t *)1) {
197382527734SSukumar Swaminathan 					mbq->iocbq = NULL;
197482527734SSukumar Swaminathan 				}
197582527734SSukumar Swaminathan 				return (0);
197682527734SSukumar Swaminathan 			}
197782527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
197882527734SSukumar Swaminathan 			return (1);
197982527734SSukumar Swaminathan 		}
198082527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_RPI_FULL) {
198182527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
198282527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
198382527734SSukumar Swaminathan 			    "Limit reached. count=%d", port->node_count);
198482527734SSukumar Swaminathan 		}
198582527734SSukumar Swaminathan 
198682527734SSukumar Swaminathan 		/* Special handle for vport PLOGI */
198782527734SSukumar Swaminathan 		if (mbq->iocbq == (uint8_t *)1) {
198882527734SSukumar Swaminathan 			mbq->iocbq = NULL;
198982527734SSukumar Swaminathan 		}
199082527734SSukumar Swaminathan 
199182527734SSukumar Swaminathan 		return (0);
199282527734SSukumar Swaminathan 	}
199382527734SSukumar Swaminathan 
199482527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
199582527734SSukumar Swaminathan 	if (!mp) {
199682527734SSukumar Swaminathan 		return (0);
199782527734SSukumar Swaminathan 	}
1998*a9800bebSGarrett D'Amore 
199982527734SSukumar Swaminathan 	ldata = mb->un.varWords[5];
200082527734SSukumar Swaminathan 	lvpi = (ldata & 0xffff) - hba->vpi_base;
200182527734SSukumar Swaminathan 	port = &VPORT(lvpi);
200282527734SSukumar Swaminathan 
200382527734SSukumar Swaminathan 	/* First copy command data */
200482527734SSukumar Swaminathan 	ldata = mb->un.varWords[0];	/* get rpi */
200582527734SSukumar Swaminathan 	lrpi = ldata & 0xffff;
200682527734SSukumar Swaminathan 
200782527734SSukumar Swaminathan 	ldata = mb->un.varWords[1];	/* get did */
200882527734SSukumar Swaminathan 	ldid = ldata & MASK_DID;
200982527734SSukumar Swaminathan 
2010*a9800bebSGarrett D'Amore 	sp = (SERV_PARM *)mp->virt;
201182527734SSukumar Swaminathan 
2012*a9800bebSGarrett D'Amore 	/* Create or update the node */
2013*a9800bebSGarrett D'Amore 	ndlp = emlxs_node_create(port, ldid, lrpi, sp);
201482527734SSukumar Swaminathan 
2015*a9800bebSGarrett D'Amore 	if (ndlp->nlp_DID == FABRIC_DID) {
2016*a9800bebSGarrett D'Amore 		/* FLOGI/FDISC successfully completed on this port */
201782527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
2018*a9800bebSGarrett D'Amore 		port->flag |= EMLXS_PORT_FLOGI_CMPL;
201982527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
202082527734SSukumar Swaminathan 
202182527734SSukumar Swaminathan 		/* If CLEAR_LA has been sent, then attempt to */
202282527734SSukumar Swaminathan 		/* register the vpi now */
202382527734SSukumar Swaminathan 		if (hba->state == FC_READY) {
202482527734SSukumar Swaminathan 			(void) emlxs_mb_reg_vpi(port, NULL);
202582527734SSukumar Swaminathan 		}
2026fcf3ce44SJohn Forte 
202782527734SSukumar Swaminathan 		/*
202882527734SSukumar Swaminathan 		 * If NPIV Fabric support has just been established on
202982527734SSukumar Swaminathan 		 * the physical port, then notify the vports of the
203082527734SSukumar Swaminathan 		 * link up
203182527734SSukumar Swaminathan 		 */
203282527734SSukumar Swaminathan 		if ((lvpi == 0) &&
203382527734SSukumar Swaminathan 		    (hba->flag & FC_NPIV_ENABLED) &&
203482527734SSukumar Swaminathan 		    (hba->flag & FC_NPIV_SUPPORTED)) {
203582527734SSukumar Swaminathan 			/* Skip the physical port */
203682527734SSukumar Swaminathan 			for (i = 1; i < MAX_VPORTS; i++) {
203782527734SSukumar Swaminathan 				vport = &VPORT(i);
203882527734SSukumar Swaminathan 
203982527734SSukumar Swaminathan 				if (!(vport->flag & EMLXS_PORT_BOUND) ||
2040*a9800bebSGarrett D'Amore 				    !(vport->flag &
2041*a9800bebSGarrett D'Amore 				    EMLXS_PORT_ENABLE)) {
204282527734SSukumar Swaminathan 					continue;
204382527734SSukumar Swaminathan 				}
204482527734SSukumar Swaminathan 
204582527734SSukumar Swaminathan 				emlxs_port_online(vport);
204682527734SSukumar Swaminathan 			}
2047fcf3ce44SJohn Forte 		}
2048fcf3ce44SJohn Forte 	}
2049291a2b48SSukumar Swaminathan 
2050*a9800bebSGarrett D'Amore 	/* Check for special restricted login flag */
205182527734SSukumar Swaminathan 	if (mbq->iocbq == (uint8_t *)1) {
205282527734SSukumar Swaminathan 		mbq->iocbq = NULL;
2053*a9800bebSGarrett D'Amore 		(void) emlxs_mb_unreg_node(port, ndlp, NULL, NULL, NULL);
2054*a9800bebSGarrett D'Amore 		return (0);
2055*a9800bebSGarrett D'Amore 	}
2056*a9800bebSGarrett D'Amore 
2057*a9800bebSGarrett D'Amore 	/* Needed for FCT trigger in emlxs_mb_deferred_cmpl */
2058*a9800bebSGarrett D'Amore 	if (mbq->sbp) {
2059*a9800bebSGarrett D'Amore 		((emlxs_buf_t *)mbq->sbp)->node = ndlp;
206082527734SSukumar Swaminathan 	}
2061fcf3ce44SJohn Forte 
206282527734SSukumar Swaminathan #ifdef DHCHAP_SUPPORT
206382527734SSukumar Swaminathan 	if (mbq->sbp || mbq->ubp) {
206482527734SSukumar Swaminathan 		if (emlxs_dhc_auth_start(port, ndlp, mbq->sbp,
206582527734SSukumar Swaminathan 		    mbq->ubp) == 0) {
206682527734SSukumar Swaminathan 			/* Auth started - auth completion will */
206782527734SSukumar Swaminathan 			/* handle sbp and ubp now */
206882527734SSukumar Swaminathan 			mbq->sbp = NULL;
206982527734SSukumar Swaminathan 			mbq->ubp = NULL;
2070fcf3ce44SJohn Forte 		}
2071fcf3ce44SJohn Forte 	}
207282527734SSukumar Swaminathan #endif	/* DHCHAP_SUPPORT */
207382527734SSukumar Swaminathan 
2074fcf3ce44SJohn Forte 	return (0);
2075fcf3ce44SJohn Forte 
2076*a9800bebSGarrett D'Amore } /* emlxs_reg_did_mbcmpl() */
2077fcf3ce44SJohn Forte 
2078fcf3ce44SJohn Forte 
2079*a9800bebSGarrett D'Amore /* SLI3 */
2080fcf3ce44SJohn Forte extern uint32_t
2081fcf3ce44SJohn Forte emlxs_mb_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param,
2082fcf3ce44SJohn Forte     emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq)
2083fcf3ce44SJohn Forte {
2084291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
2085291a2b48SSukumar Swaminathan 	MATCHMAP	*mp;
2086291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
2087291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
2088291a2b48SSukumar Swaminathan 	uint32_t	rval;
2089fcf3ce44SJohn Forte 
2090*a9800bebSGarrett D'Amore 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2091*a9800bebSGarrett D'Amore 		rval = emlxs_sli4_reg_did(port, did, param, sbp, ubp, iocbq);
2092*a9800bebSGarrett D'Amore 		return (rval);
2093*a9800bebSGarrett D'Amore 	}
2094*a9800bebSGarrett D'Amore 
2095fcf3ce44SJohn Forte 	/* Check for invalid node ids to register */
2096291a2b48SSukumar Swaminathan 	if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
2097291a2b48SSukumar Swaminathan 		return (1);
2098291a2b48SSukumar Swaminathan 	}
2099291a2b48SSukumar Swaminathan 
2100291a2b48SSukumar Swaminathan 	if (did & 0xff000000) {
2101fcf3ce44SJohn Forte 		return (1);
2102fcf3ce44SJohn Forte 	}
2103291a2b48SSukumar Swaminathan 
2104fcf3ce44SJohn Forte 	if ((rval = emlxs_mb_check_sparm(hba, param))) {
2105fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2106291a2b48SSukumar Swaminathan 		    "Invalid service parameters. did=%06x rval=%d", did,
2107291a2b48SSukumar Swaminathan 		    rval);
2108fcf3ce44SJohn Forte 
2109fcf3ce44SJohn Forte 		return (1);
2110fcf3ce44SJohn Forte 	}
2111291a2b48SSukumar Swaminathan 
2112fcf3ce44SJohn Forte 	/* Check if the node limit has been reached */
2113fcf3ce44SJohn Forte 	if (port->node_count >= hba->max_nodes) {
2114fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2115291a2b48SSukumar Swaminathan 		    "Limit reached. did=%06x count=%d", did,
2116291a2b48SSukumar Swaminathan 		    port->node_count);
2117fcf3ce44SJohn Forte 
2118fcf3ce44SJohn Forte 		return (1);
2119fcf3ce44SJohn Forte 	}
2120291a2b48SSukumar Swaminathan 
212182527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
212282527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
212382527734SSukumar Swaminathan 		    "Unable to allocate mailbox. did=%x", did);
212482527734SSukumar Swaminathan 
2125fcf3ce44SJohn Forte 		return (1);
2126fcf3ce44SJohn Forte 	}
212782527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
2128*a9800bebSGarrett D'Amore 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2129291a2b48SSukumar Swaminathan 
2130fcf3ce44SJohn Forte 	/* Build login request */
213182527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
2132*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2133*a9800bebSGarrett D'Amore 
213482527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
213582527734SSukumar Swaminathan 		    "Unable to allocate buffer. did=%x", did);
2136fcf3ce44SJohn Forte 		return (1);
2137fcf3ce44SJohn Forte 	}
2138291a2b48SSukumar Swaminathan 	bcopy((void *)param, (void *)mp->virt, sizeof (SERV_PARM));
2139291a2b48SSukumar Swaminathan 
2140fcf3ce44SJohn Forte 	mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
214182527734SSukumar Swaminathan 	mb->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys);
214282527734SSukumar Swaminathan 	mb->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys);
2143fcf3ce44SJohn Forte 	mb->un.varRegLogin.did = did;
2144fcf3ce44SJohn Forte 	mb->un.varWords[30] = 0;	/* flags */
2145fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_REG_LOGIN64;
2146fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2147*a9800bebSGarrett D'Amore 	mb->un.varRegLogin.vpi = port->vpi;
2148*a9800bebSGarrett D'Amore 	mb->un.varRegLogin.rpi = 0;
2149fcf3ce44SJohn Forte 
2150*a9800bebSGarrett D'Amore 	mbq->sbp = (void *)sbp;
2151*a9800bebSGarrett D'Amore 	mbq->ubp = (void *)ubp;
2152*a9800bebSGarrett D'Amore 	mbq->iocbq = (void *)iocbq;
2153*a9800bebSGarrett D'Amore 	mbq->bp = (void *)mp;
2154*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_reg_did_mbcmpl;
2155*a9800bebSGarrett D'Amore 	mbq->context = NULL;
2156*a9800bebSGarrett D'Amore 	mbq->port = (void *)port;
2157fcf3ce44SJohn Forte 
215882527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
215982527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2160*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_BUF, (void *)mp);
2161*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2162*a9800bebSGarrett D'Amore 
2163*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2164*a9800bebSGarrett D'Amore 		    "Unable to send mbox. did=%x", did);
2165*a9800bebSGarrett D'Amore 		return (1);
2166fcf3ce44SJohn Forte 	}
2167291a2b48SSukumar Swaminathan 
2168fcf3ce44SJohn Forte 	return (0);
2169fcf3ce44SJohn Forte 
2170fcf3ce44SJohn Forte } /* emlxs_mb_reg_did() */
2171fcf3ce44SJohn Forte 
2172*a9800bebSGarrett D'Amore /* SLI3 */
2173*a9800bebSGarrett D'Amore /*ARGSUSED*/
2174*a9800bebSGarrett D'Amore static uint32_t
2175*a9800bebSGarrett D'Amore emlxs_unreg_node_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
2176fcf3ce44SJohn Forte {
2177*a9800bebSGarrett D'Amore 	emlxs_port_t	*port = (emlxs_port_t *)mbq->port;
2178291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
2179*a9800bebSGarrett D'Amore 	NODELIST	*node;
2180*a9800bebSGarrett D'Amore 	uint16_t	rpi;
218182527734SSukumar Swaminathan 
2182*a9800bebSGarrett D'Amore 	node = (NODELIST *)mbq->context;
2183*a9800bebSGarrett D'Amore 	mb = (MAILBOX *)mbq;
2184*a9800bebSGarrett D'Amore 	rpi = (node)? node->nlp_Rpi:0xffff;
2185fcf3ce44SJohn Forte 
2186*a9800bebSGarrett D'Amore 	if (mb->mbxStatus) {
2187*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2188*a9800bebSGarrett D'Amore 		    "unreg_node_mbcmpl:failed. node=%p rpi=%x status=%x",
2189*a9800bebSGarrett D'Amore 		    node, rpi, mb->mbxStatus);
2190fcf3ce44SJohn Forte 
2191*a9800bebSGarrett D'Amore 		return (0);
2192fcf3ce44SJohn Forte 	}
2193291a2b48SSukumar Swaminathan 
2194*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2195*a9800bebSGarrett D'Amore 	    "unreg_node_mbcmpl: node=%p rpi=%x",
2196*a9800bebSGarrett D'Amore 	    node, rpi);
2197*a9800bebSGarrett D'Amore 
2198*a9800bebSGarrett D'Amore 	if (node) {
2199*a9800bebSGarrett D'Amore 		emlxs_node_rm(port, node);
2200*a9800bebSGarrett D'Amore 
2201*a9800bebSGarrett D'Amore 	} else {  /* All nodes */
2202*a9800bebSGarrett D'Amore 		emlxs_node_destroy_all(port);
220382527734SSukumar Swaminathan 	}
220482527734SSukumar Swaminathan 
2205fcf3ce44SJohn Forte 	return (0);
2206fcf3ce44SJohn Forte 
2207*a9800bebSGarrett D'Amore } /* emlxs_unreg_node_mbcmpl */
220882527734SSukumar Swaminathan 
2209*a9800bebSGarrett D'Amore 
2210*a9800bebSGarrett D'Amore /* SLI3 */
2211fcf3ce44SJohn Forte extern uint32_t
2212*a9800bebSGarrett D'Amore emlxs_mb_unreg_node(emlxs_port_t *port, NODELIST *node, emlxs_buf_t *sbp,
2213fcf3ce44SJohn Forte     fc_unsol_buf_t *ubp, IOCBQ *iocbq)
2214fcf3ce44SJohn Forte {
2215291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
2216291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
2217291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
2218*a9800bebSGarrett D'Amore 	uint16_t	rpi;
2219*a9800bebSGarrett D'Amore 	uint32_t	rval;
2220fcf3ce44SJohn Forte 
2221*a9800bebSGarrett D'Amore 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2222*a9800bebSGarrett D'Amore 		rval = emlxs_sli4_unreg_node(port, node, sbp, ubp, iocbq);
2223*a9800bebSGarrett D'Amore 		return (rval);
2224*a9800bebSGarrett D'Amore 	}
2225*a9800bebSGarrett D'Amore 
2226*a9800bebSGarrett D'Amore 	if (node) {
2227fcf3ce44SJohn Forte 		/* Check for base node */
2228*a9800bebSGarrett D'Amore 		if (node == &port->node_base) {
2229fcf3ce44SJohn Forte 			/* just flush base node */
2230fcf3ce44SJohn Forte 			(void) emlxs_tx_node_flush(port, &port->node_base,
2231fcf3ce44SJohn Forte 			    0, 0, 0);
2232291a2b48SSukumar Swaminathan 			(void) emlxs_chipq_node_flush(port, 0,
2233291a2b48SSukumar Swaminathan 			    &port->node_base, 0);
2234fcf3ce44SJohn Forte 
2235*a9800bebSGarrett D'Amore 			port->did = 0;
2236*a9800bebSGarrett D'Amore 
2237fcf3ce44SJohn Forte 			/* Return now */
2238fcf3ce44SJohn Forte 			return (1);
2239fcf3ce44SJohn Forte 		}
2240291a2b48SSukumar Swaminathan 
2241*a9800bebSGarrett D'Amore 		rpi = (uint16_t)node->nlp_Rpi;
2242291a2b48SSukumar Swaminathan 
2243*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2244*a9800bebSGarrett D'Amore 		    "unreg_node:%p  rpi=%d", node, rpi);
2245291a2b48SSukumar Swaminathan 
2246*a9800bebSGarrett D'Amore 		/* This node must be (0xFFFFFE) which registered by vport */
2247*a9800bebSGarrett D'Amore 		if (rpi == 0) {
2248*a9800bebSGarrett D'Amore 			emlxs_node_rm(port, node);
2249*a9800bebSGarrett D'Amore 			return (0);
2250fcf3ce44SJohn Forte 		}
2251291a2b48SSukumar Swaminathan 
2252*a9800bebSGarrett D'Amore 	} else {	/* Unreg all nodes */
2253*a9800bebSGarrett D'Amore 		rpi = 0xffff;
2254291a2b48SSukumar Swaminathan 
2255*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2256*a9800bebSGarrett D'Amore 		    "unreg_node: All");
2257fcf3ce44SJohn Forte 	}
2258291a2b48SSukumar Swaminathan 
225982527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
2260*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2261*a9800bebSGarrett D'Amore 		    "unreg_node:failed. Unable to allocate mbox");
2262fcf3ce44SJohn Forte 		return (1);
2263fcf3ce44SJohn Forte 	}
2264291a2b48SSukumar Swaminathan 
2265291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
2266*a9800bebSGarrett D'Amore 	mb->un.varUnregLogin.rpi = rpi;
2267*a9800bebSGarrett D'Amore 	mb->un.varUnregLogin.vpi = port->VPIobj.VPI;
2268*a9800bebSGarrett D'Amore 
2269*a9800bebSGarrett D'Amore 	mb->mbxCommand = MBX_UNREG_LOGIN;
2270fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2271*a9800bebSGarrett D'Amore 	mbq->sbp = (void *)sbp;
2272*a9800bebSGarrett D'Amore 	mbq->ubp = (void *)ubp;
2273*a9800bebSGarrett D'Amore 	mbq->iocbq = (void *)iocbq;
2274*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_unreg_node_mbcmpl;
2275*a9800bebSGarrett D'Amore 	mbq->context = (void *)node;
2276*a9800bebSGarrett D'Amore 	mbq->port = (void *)port;
2277fcf3ce44SJohn Forte 
227882527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
227982527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2280*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2281*a9800bebSGarrett D'Amore 		    "unreg_node:failed. Unable to send request.");
2282*a9800bebSGarrett D'Amore 
2283*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2284*a9800bebSGarrett D'Amore 		return (1);
2285fcf3ce44SJohn Forte 	}
2286291a2b48SSukumar Swaminathan 
2287fcf3ce44SJohn Forte 	return (0);
2288fcf3ce44SJohn Forte 
2289*a9800bebSGarrett D'Amore } /* emlxs_mb_unreg_node() */
2290fcf3ce44SJohn Forte 
229182527734SSukumar Swaminathan 
2292fcf3ce44SJohn Forte 
2293fcf3ce44SJohn Forte 
2294fcf3ce44SJohn Forte /*
2295291a2b48SSukumar Swaminathan  * emlxs_mb_set_var   Issue a special debug mbox command to write slim
2296fcf3ce44SJohn Forte  */
2297291a2b48SSukumar Swaminathan /*ARGSUSED*/
2298fcf3ce44SJohn Forte extern void
229982527734SSukumar Swaminathan emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t addr,
2300291a2b48SSukumar Swaminathan     uint32_t value)
2301fcf3ce44SJohn Forte {
230282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
230382527734SSukumar Swaminathan 
2304291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2305fcf3ce44SJohn Forte 
2306fcf3ce44SJohn Forte 	/* addr = 0x090597 is AUTO ABTS disable for ELS commands */
2307fcf3ce44SJohn Forte 	/* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
2308fcf3ce44SJohn Forte 	/* addr = 0x100506 is for setting PCI MAX READ value */
2309fcf3ce44SJohn Forte 
2310fcf3ce44SJohn Forte 	/*
2311fcf3ce44SJohn Forte 	 * Always turn on DELAYED ABTS for ELS timeouts
2312fcf3ce44SJohn Forte 	 */
2313fcf3ce44SJohn Forte 	if ((addr == 0x052198) && (value == 0)) {
2314fcf3ce44SJohn Forte 		value = 1;
2315fcf3ce44SJohn Forte 	}
2316291a2b48SSukumar Swaminathan 
2317fcf3ce44SJohn Forte 	mb->un.varWords[0] = addr;
2318fcf3ce44SJohn Forte 	mb->un.varWords[1] = value;
2319fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_VARIABLE;
2320fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
232182527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2322*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
232382527734SSukumar Swaminathan 
232482527734SSukumar Swaminathan } /* emlxs_mb_set_var() */
2325fcf3ce44SJohn Forte 
2326fcf3ce44SJohn Forte 
2327fcf3ce44SJohn Forte /*
2328fcf3ce44SJohn Forte  * Disable Traffic Cop
2329fcf3ce44SJohn Forte  */
2330291a2b48SSukumar Swaminathan /*ARGSUSED*/
2331fcf3ce44SJohn Forte extern void
233282527734SSukumar Swaminathan emlxs_disable_tc(emlxs_hba_t *hba, MAILBOXQ *mbq)
2333fcf3ce44SJohn Forte {
233482527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
233582527734SSukumar Swaminathan 
2336291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2337fcf3ce44SJohn Forte 
2338fcf3ce44SJohn Forte 	mb->un.varWords[0] = 0x50797;
2339fcf3ce44SJohn Forte 	mb->un.varWords[1] = 0;
2340fcf3ce44SJohn Forte 	mb->un.varWords[2] = 0xfffffffe;
2341fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_VARIABLE;
2342fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
234382527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2344*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
2345fcf3ce44SJohn Forte 
234682527734SSukumar Swaminathan } /* emlxs_disable_tc() */
2347fcf3ce44SJohn Forte 
2348fcf3ce44SJohn Forte 
2349fcf3ce44SJohn Forte extern void
235082527734SSukumar Swaminathan emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOXQ *mbq, int hbq_id)
2351fcf3ce44SJohn Forte {
2352291a2b48SSukumar Swaminathan 	HBQ_INIT_t	*hbq;
235382527734SSukumar Swaminathan 	MAILBOX		*mb = (MAILBOX *)mbq;
2354291a2b48SSukumar Swaminathan 	int		i;
2355fcf3ce44SJohn Forte 
2356291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2357fcf3ce44SJohn Forte 
235882527734SSukumar Swaminathan 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
2359fcf3ce44SJohn Forte 
2360fcf3ce44SJohn Forte 	mb->un.varCfgHbq.hbqId = hbq_id;
2361fcf3ce44SJohn Forte 	mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries;
2362fcf3ce44SJohn Forte 	mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify;
2363fcf3ce44SJohn Forte 	mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask;
2364fcf3ce44SJohn Forte 	mb->un.varCfgHbq.profile = hbq->HBQ_profile;
2365fcf3ce44SJohn Forte 	mb->un.varCfgHbq.ringMask = hbq->HBQ_ringMask;
2366fcf3ce44SJohn Forte 	mb->un.varCfgHbq.headerLen = hbq->HBQ_headerLen;
2367fcf3ce44SJohn Forte 	mb->un.varCfgHbq.logEntry = hbq->HBQ_logEntry;
236882527734SSukumar Swaminathan 	mb->un.varCfgHbq.hbqaddrLow = PADDR_LO(hbq->HBQ_host_buf.phys);
236982527734SSukumar Swaminathan 	mb->un.varCfgHbq.hbqaddrHigh = PADDR_HI(hbq->HBQ_host_buf.phys);
2370fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_HBQ;
2371fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
237282527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
2373*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
2374fcf3ce44SJohn Forte 
2375fcf3ce44SJohn Forte 	/* Copy info for profiles 2,3,5. Other profiles this area is reserved */
2376fcf3ce44SJohn Forte 	if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) ||
2377fcf3ce44SJohn Forte 	    (hbq->HBQ_profile == 5)) {
2378fcf3ce44SJohn Forte 		bcopy(&hbq->profiles.allprofiles,
2379fcf3ce44SJohn Forte 		    &mb->un.varCfgHbq.profiles.allprofiles,
2380fcf3ce44SJohn Forte 		    sizeof (hbq->profiles));
2381fcf3ce44SJohn Forte 	}
2382291a2b48SSukumar Swaminathan 
2383fcf3ce44SJohn Forte 	/* Return if no rctl / type masks for this HBQ */
2384fcf3ce44SJohn Forte 	if (!hbq->HBQ_num_mask) {
2385fcf3ce44SJohn Forte 		return;
2386fcf3ce44SJohn Forte 	}
2387291a2b48SSukumar Swaminathan 
2388fcf3ce44SJohn Forte 	/* Otherwise we setup specific rctl / type masks for this HBQ */
2389fcf3ce44SJohn Forte 	for (i = 0; i < hbq->HBQ_num_mask; i++) {
2390291a2b48SSukumar Swaminathan 		mb->un.varCfgHbq.hbqMasks[i].tmatch =
2391291a2b48SSukumar Swaminathan 		    hbq->HBQ_Masks[i].tmatch;
2392fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask;
2393fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].rctlmatch =
2394fcf3ce44SJohn Forte 		    hbq->HBQ_Masks[i].rctlmatch;
2395fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].rctlmask =
2396fcf3ce44SJohn Forte 		    hbq->HBQ_Masks[i].rctlmask;
2397fcf3ce44SJohn Forte 	}
2398fcf3ce44SJohn Forte 
2399fcf3ce44SJohn Forte 	return;
2400fcf3ce44SJohn Forte 
2401fcf3ce44SJohn Forte } /* emlxs_mb_config_hbq() */
2402fcf3ce44SJohn Forte 
240382527734SSukumar Swaminathan 
2404*a9800bebSGarrett D'Amore /* SLI3 */
2405*a9800bebSGarrett D'Amore static uint32_t
2406*a9800bebSGarrett D'Amore emlxs_reg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
240782527734SSukumar Swaminathan {
2408*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
240982527734SSukumar Swaminathan 	MAILBOX *mb;
241082527734SSukumar Swaminathan 
241182527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
241282527734SSukumar Swaminathan 
2413*a9800bebSGarrett D'Amore 	mutex_enter(&EMLXS_PORT_LOCK);
241482527734SSukumar Swaminathan 
241582527734SSukumar Swaminathan 	if (mb->mbxStatus != MBX_SUCCESS) {
2416*a9800bebSGarrett D'Amore 		port->flag &= ~EMLXS_PORT_REG_VPI;
2417*a9800bebSGarrett D'Amore 		mutex_exit(&EMLXS_PORT_LOCK);
241882527734SSukumar Swaminathan 
2419*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2420*a9800bebSGarrett D'Amore 		    "cmpl_reg_vpi:%d failed. status=%x",
2421*a9800bebSGarrett D'Amore 		    port->vpi, mb->mbxStatus);
242282527734SSukumar Swaminathan 		return (0);
242382527734SSukumar Swaminathan 	}
242482527734SSukumar Swaminathan 
2425*a9800bebSGarrett D'Amore 	port->flag |= EMLXS_PORT_REG_VPI_CMPL;
242682527734SSukumar Swaminathan 
2427*a9800bebSGarrett D'Amore 	mutex_exit(&EMLXS_PORT_LOCK);
242882527734SSukumar Swaminathan 
2429*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2430*a9800bebSGarrett D'Amore 	    "cmpl_reg_vpi:%d ",
2431*a9800bebSGarrett D'Amore 	    port->vpi);
243282527734SSukumar Swaminathan 
243382527734SSukumar Swaminathan 	return (0);
2434*a9800bebSGarrett D'Amore 
2435*a9800bebSGarrett D'Amore } /* emlxs_reg_vpi_mbcmpl */
243682527734SSukumar Swaminathan 
243782527734SSukumar Swaminathan 
2438*a9800bebSGarrett D'Amore /* SLI3 */
243982527734SSukumar Swaminathan extern uint32_t
244082527734SSukumar Swaminathan emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp)
244182527734SSukumar Swaminathan {
244282527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
244382527734SSukumar Swaminathan 	MAILBOXQ *mbq;
244482527734SSukumar Swaminathan 	MAILBOX	*mb;
244582527734SSukumar Swaminathan 	int rval;
2446fcf3ce44SJohn Forte 
2447*a9800bebSGarrett D'Amore 	if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) {
2448*a9800bebSGarrett D'Amore 		return (1);
2449*a9800bebSGarrett D'Amore 	}
2450*a9800bebSGarrett D'Amore 
2451fcf3ce44SJohn Forte 	if (!(hba->flag & FC_NPIV_ENABLED)) {
2452*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2453*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. NPIV disabled.",
2454*a9800bebSGarrett D'Amore 		    port->vpi);
2455*a9800bebSGarrett D'Amore 		return (1);
2456*a9800bebSGarrett D'Amore 	}
2457*a9800bebSGarrett D'Amore 
2458*a9800bebSGarrett D'Amore 	if (port->flag & EMLXS_PORT_REG_VPI) {
2459*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2460*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. Already registered.",
2461*a9800bebSGarrett D'Amore 		    port->vpi);
2462fcf3ce44SJohn Forte 		return (0);
2463fcf3ce44SJohn Forte 	}
2464291a2b48SSukumar Swaminathan 
2465fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
2466fcf3ce44SJohn Forte 
2467fcf3ce44SJohn Forte 	/* Can't reg vpi until ClearLA is sent */
2468fcf3ce44SJohn Forte 	if (hba->state != FC_READY) {
2469fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
2470fcf3ce44SJohn Forte 
2471*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2472*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. HBA state not READY",
2473*a9800bebSGarrett D'Amore 		    port->vpi);
2474fcf3ce44SJohn Forte 		return (1);
2475fcf3ce44SJohn Forte 	}
2476291a2b48SSukumar Swaminathan 
2477fcf3ce44SJohn Forte 	/* Must have port id */
2478fcf3ce44SJohn Forte 	if (!port->did) {
2479fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
2480fcf3ce44SJohn Forte 
2481*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2482*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. Port did=0",
2483*a9800bebSGarrett D'Amore 		    port->vpi);
2484fcf3ce44SJohn Forte 		return (1);
2485fcf3ce44SJohn Forte 	}
2486291a2b48SSukumar Swaminathan 
248782527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
2488fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
2489fcf3ce44SJohn Forte 
2490*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2491*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. Unable to allocate mbox.",
2492*a9800bebSGarrett D'Amore 		    port->vpi);
2493fcf3ce44SJohn Forte 		return (1);
2494fcf3ce44SJohn Forte 	}
2495291a2b48SSukumar Swaminathan 
2496*a9800bebSGarrett D'Amore 	port->flag |= EMLXS_PORT_REG_VPI;
2497fcf3ce44SJohn Forte 
2498fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
2499fcf3ce44SJohn Forte 
2500291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
2501*a9800bebSGarrett D'Amore 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
250282527734SSukumar Swaminathan 
2503*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2504*a9800bebSGarrett D'Amore 	    "reg_vpi:%d", port->vpi);
250582527734SSukumar Swaminathan 
2506*a9800bebSGarrett D'Amore 	mb->un.varRegVpi.vpi = port->vpi;
2507fcf3ce44SJohn Forte 	mb->un.varRegVpi.sid = port->did;
2508fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_REG_VPI;
2509fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2510fcf3ce44SJohn Forte 
2511*a9800bebSGarrett D'Amore 	mbq->sbp = (void *)sbp;
2512*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_reg_vpi_mbcmpl;
2513*a9800bebSGarrett D'Amore 	mbq->context = NULL;
2514*a9800bebSGarrett D'Amore 	mbq->port = (void *)port;
2515*a9800bebSGarrett D'Amore 
251682527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
251782527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2518*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2519*a9800bebSGarrett D'Amore 		    "reg_vpi:%d failed. Unable to send request.",
2520*a9800bebSGarrett D'Amore 		    port->vpi);
2521*a9800bebSGarrett D'Amore 
2522*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2523*a9800bebSGarrett D'Amore 		return (1);
2524fcf3ce44SJohn Forte 	}
2525291a2b48SSukumar Swaminathan 
2526fcf3ce44SJohn Forte 	return (0);
2527fcf3ce44SJohn Forte 
2528fcf3ce44SJohn Forte } /* emlxs_mb_reg_vpi() */
2529fcf3ce44SJohn Forte 
2530fcf3ce44SJohn Forte 
2531*a9800bebSGarrett D'Amore /* SLI3 */
2532*a9800bebSGarrett D'Amore static uint32_t
2533*a9800bebSGarrett D'Amore emlxs_unreg_vpi_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
253482527734SSukumar Swaminathan {
2535*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
2536*a9800bebSGarrett D'Amore 	MAILBOX *mb;
253782527734SSukumar Swaminathan 
2538*a9800bebSGarrett D'Amore 	mb  = (MAILBOX *)mbq->mbox;
2539*a9800bebSGarrett D'Amore 
2540*a9800bebSGarrett D'Amore 	if (mb->mbxStatus != MBX_SUCCESS) {
2541*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2542*a9800bebSGarrett D'Amore 		    "unreg_vpi_mbcmpl:%d failed. status=%x",
2543*a9800bebSGarrett D'Amore 		    port->vpi, mb->mbxStatus);
2544*a9800bebSGarrett D'Amore 		return (0);
254582527734SSukumar Swaminathan 	}
2546*a9800bebSGarrett D'Amore 
2547*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2548*a9800bebSGarrett D'Amore 	    "unreg_vpi_mbcmpl:%d", port->vpi);
2549*a9800bebSGarrett D'Amore 
2550*a9800bebSGarrett D'Amore 	mutex_enter(&EMLXS_PORT_LOCK);
2551*a9800bebSGarrett D'Amore 	port->flag &= ~EMLXS_PORT_REG_VPI_CMPL;
2552*a9800bebSGarrett D'Amore 	mutex_exit(&EMLXS_PORT_LOCK);
2553*a9800bebSGarrett D'Amore 
255482527734SSukumar Swaminathan 	return (0);
255582527734SSukumar Swaminathan 
2556*a9800bebSGarrett D'Amore } /* emlxs_unreg_vpi_mbcmpl() */
255782527734SSukumar Swaminathan 
255882527734SSukumar Swaminathan 
2559*a9800bebSGarrett D'Amore /* SLI3 */
2560fcf3ce44SJohn Forte extern uint32_t
2561fcf3ce44SJohn Forte emlxs_mb_unreg_vpi(emlxs_port_t *port)
2562fcf3ce44SJohn Forte {
2563291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
2564291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
2565291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
256682527734SSukumar Swaminathan 	int		rval;
2567fcf3ce44SJohn Forte 
2568*a9800bebSGarrett D'Amore 	if (hba->sli_mode > EMLXS_HBA_SLI3_MODE) {
2569*a9800bebSGarrett D'Amore 		return (1);
2570*a9800bebSGarrett D'Amore 	}
2571*a9800bebSGarrett D'Amore 
2572fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
2573fcf3ce44SJohn Forte 
2574*a9800bebSGarrett D'Amore 	if (!(port->flag & EMLXS_PORT_REG_VPI) ||
2575*a9800bebSGarrett D'Amore 	    !(port->flag & EMLXS_PORT_REG_VPI_CMPL)) {
2576*a9800bebSGarrett D'Amore 
2577*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2578*a9800bebSGarrett D'Amore 		    "unreg_vpi:%d failed. Not registered. flag=%x",
2579*a9800bebSGarrett D'Amore 		    port->vpi, port->flag);
2580*a9800bebSGarrett D'Amore 
2581fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
2582fcf3ce44SJohn Forte 		return (0);
2583fcf3ce44SJohn Forte 	}
2584291a2b48SSukumar Swaminathan 
258582527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
2586*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2587*a9800bebSGarrett D'Amore 		    "unreg_vpi:%d failed. Unable to allocate mbox.",
2588*a9800bebSGarrett D'Amore 		    port->vpi);
2589*a9800bebSGarrett D'Amore 
2590fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
2591fcf3ce44SJohn Forte 		return (1);
2592fcf3ce44SJohn Forte 	}
2593291a2b48SSukumar Swaminathan 
2594*a9800bebSGarrett D'Amore 	port->flag &= ~EMLXS_PORT_REG_VPI;
2595fcf3ce44SJohn Forte 
2596fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
2597fcf3ce44SJohn Forte 
2598*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2599*a9800bebSGarrett D'Amore 	    "unreg_vpi:%d", port->vpi);
2600291a2b48SSukumar Swaminathan 
2601*a9800bebSGarrett D'Amore 	mb = (MAILBOX *)mbq->mbox;
2602*a9800bebSGarrett D'Amore 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2603*a9800bebSGarrett D'Amore 	mb->un.varUnregVpi.vpi = port->vpi;
2604*a9800bebSGarrett D'Amore 	mb->mbxCommand = MBX_UNREG_VPI;
2605*a9800bebSGarrett D'Amore 	mb->mbxOwner = OWN_HOST;
260682527734SSukumar Swaminathan 
2607*a9800bebSGarrett D'Amore 	mbq->mbox_cmpl = emlxs_unreg_vpi_mbcmpl;
2608*a9800bebSGarrett D'Amore 	mbq->context = NULL;
2609*a9800bebSGarrett D'Amore 	mbq->port = (void *)port;
261082527734SSukumar Swaminathan 
2611*a9800bebSGarrett D'Amore 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
2612*a9800bebSGarrett D'Amore 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
2613*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2614*a9800bebSGarrett D'Amore 		    "unreg_vpi:%d failed. Unable to send request.",
2615*a9800bebSGarrett D'Amore 		    port->vpi);
261682527734SSukumar Swaminathan 
2617*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2618*a9800bebSGarrett D'Amore 		return (1);
261982527734SSukumar Swaminathan 	}
2620*a9800bebSGarrett D'Amore 
2621fcf3ce44SJohn Forte 	return (0);
2622fcf3ce44SJohn Forte 
2623fcf3ce44SJohn Forte } /* emlxs_mb_unreg_vpi() */
2624fcf3ce44SJohn Forte 
2625fcf3ce44SJohn Forte 
2626fcf3ce44SJohn Forte /*
2627291a2b48SSukumar Swaminathan  * emlxs_mb_config_farp  Issue a CONFIG FARP mailbox command
2628fcf3ce44SJohn Forte  */
2629fcf3ce44SJohn Forte extern void
263082527734SSukumar Swaminathan emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOXQ *mbq)
2631fcf3ce44SJohn Forte {
263282527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
263382527734SSukumar Swaminathan 
2634291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2635fcf3ce44SJohn Forte 
2636291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&hba->wwpn,
2637291a2b48SSukumar Swaminathan 	    (uint8_t *)&mb->un.varCfgFarp.portname, sizeof (NAME_TYPE));
2638fcf3ce44SJohn Forte 
2639291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&hba->wwpn,
2640291a2b48SSukumar Swaminathan 	    (uint8_t *)&mb->un.varCfgFarp.nodename, sizeof (NAME_TYPE));
2641fcf3ce44SJohn Forte 
2642fcf3ce44SJohn Forte 	mb->un.varCfgFarp.filterEnable = 1;
2643fcf3ce44SJohn Forte 	mb->un.varCfgFarp.portName = 1;
2644fcf3ce44SJohn Forte 	mb->un.varCfgFarp.nodeName = 1;
2645fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_FARP;
2646fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
264782527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2648*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
2649*a9800bebSGarrett D'Amore 
2650fcf3ce44SJohn Forte } /* emlxs_mb_config_farp() */
2651fcf3ce44SJohn Forte 
2652fcf3ce44SJohn Forte 
2653fcf3ce44SJohn Forte /*
2654291a2b48SSukumar Swaminathan  * emlxs_mb_read_nv  Issue a READ CONFIG mailbox command
2655fcf3ce44SJohn Forte  */
2656291a2b48SSukumar Swaminathan /*ARGSUSED*/
2657fcf3ce44SJohn Forte extern void
265882527734SSukumar Swaminathan emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOXQ *mbq)
2659fcf3ce44SJohn Forte {
266082527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
266182527734SSukumar Swaminathan 
266282527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
266382527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
266482527734SSukumar Swaminathan 		mbq->nonembed = NULL;
266582527734SSukumar Swaminathan 	} else {
266682527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
266782527734SSukumar Swaminathan 	}
2668fcf3ce44SJohn Forte 
2669fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_CONFIG;
2670fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
267182527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2672*a9800bebSGarrett D'Amore 	mbq->port = (void *)&PPORT;
2673*a9800bebSGarrett D'Amore 
2674fcf3ce44SJohn Forte } /* emlxs_mb_read_config() */
2675fcf3ce44SJohn Forte 
2676fcf3ce44SJohn Forte 
2677fcf3ce44SJohn Forte /*
2678fcf3ce44SJohn Forte  * NAME:     emlxs_mb_put
2679fcf3ce44SJohn Forte  *
2680fcf3ce44SJohn Forte  * FUNCTION: put mailbox cmd onto the mailbox queue.
2681fcf3ce44SJohn Forte  *
2682fcf3ce44SJohn Forte  * EXECUTION ENVIRONMENT: process and interrupt level.
2683fcf3ce44SJohn Forte  *
2684fcf3ce44SJohn Forte  * NOTES:
2685fcf3ce44SJohn Forte  *
268682527734SSukumar Swaminathan  * CALLED FROM: EMLXS_SLI_ISSUE_MBOX_CMD
2687fcf3ce44SJohn Forte  *
2688291a2b48SSukumar Swaminathan  * INPUT: hba           - pointer to the device info area
2689291a2b48SSukumar Swaminathan  *      mbp             - pointer to mailbox queue entry of mailbox cmd
2690fcf3ce44SJohn Forte  *
2691fcf3ce44SJohn Forte  * RETURNS: NULL - command queued
2692fcf3ce44SJohn Forte  */
2693fcf3ce44SJohn Forte extern void
2694fcf3ce44SJohn Forte emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq)
2695fcf3ce44SJohn Forte {
2696fcf3ce44SJohn Forte 
2697fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
2698fcf3ce44SJohn Forte 
2699fcf3ce44SJohn Forte 	if (hba->mbox_queue.q_first) {
2700fcf3ce44SJohn Forte 
2701fcf3ce44SJohn Forte 		/*
2702fcf3ce44SJohn Forte 		 * queue command to end of list
2703fcf3ce44SJohn Forte 		 */
2704291a2b48SSukumar Swaminathan 		((MAILBOXQ *)hba->mbox_queue.q_last)->next = mbq;
2705fcf3ce44SJohn Forte 		hba->mbox_queue.q_last = (uint8_t *)mbq;
2706fcf3ce44SJohn Forte 		hba->mbox_queue.q_cnt++;
2707fcf3ce44SJohn Forte 	} else {
2708fcf3ce44SJohn Forte 
2709fcf3ce44SJohn Forte 		/*
2710fcf3ce44SJohn Forte 		 * add command to empty list
2711fcf3ce44SJohn Forte 		 */
2712fcf3ce44SJohn Forte 		hba->mbox_queue.q_first = (uint8_t *)mbq;
2713fcf3ce44SJohn Forte 		hba->mbox_queue.q_last = (uint8_t *)mbq;
2714fcf3ce44SJohn Forte 		hba->mbox_queue.q_cnt = 1;
2715fcf3ce44SJohn Forte 	}
2716fcf3ce44SJohn Forte 
2717fcf3ce44SJohn Forte 	mbq->next = NULL;
2718fcf3ce44SJohn Forte 
2719fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
2720fcf3ce44SJohn Forte } /* emlxs_mb_put() */
2721fcf3ce44SJohn Forte 
2722fcf3ce44SJohn Forte 
2723fcf3ce44SJohn Forte /*
2724fcf3ce44SJohn Forte  * NAME:     emlxs_mb_get
2725fcf3ce44SJohn Forte  *
2726fcf3ce44SJohn Forte  * FUNCTION: get a mailbox command from mailbox command queue
2727fcf3ce44SJohn Forte  *
2728fcf3ce44SJohn Forte  * EXECUTION ENVIRONMENT: interrupt level.
2729fcf3ce44SJohn Forte  *
2730fcf3ce44SJohn Forte  * NOTES:
2731fcf3ce44SJohn Forte  *
2732fcf3ce44SJohn Forte  * CALLED FROM: emlxs_handle_mb_event
2733fcf3ce44SJohn Forte  *
2734fcf3ce44SJohn Forte  * INPUT: hba       - pointer to the device info area
2735fcf3ce44SJohn Forte  *
2736fcf3ce44SJohn Forte  * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command
2737fcf3ce44SJohn Forte  */
2738fcf3ce44SJohn Forte extern MAILBOXQ *
2739fcf3ce44SJohn Forte emlxs_mb_get(emlxs_hba_t *hba)
2740fcf3ce44SJohn Forte {
2741291a2b48SSukumar Swaminathan 	MAILBOXQ	*p_first = NULL;
2742fcf3ce44SJohn Forte 
2743fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
2744fcf3ce44SJohn Forte 
2745fcf3ce44SJohn Forte 	if (hba->mbox_queue.q_first) {
2746291a2b48SSukumar Swaminathan 		p_first = (MAILBOXQ *)hba->mbox_queue.q_first;
2747fcf3ce44SJohn Forte 		hba->mbox_queue.q_first = (uint8_t *)p_first->next;
2748fcf3ce44SJohn Forte 
2749fcf3ce44SJohn Forte 		if (hba->mbox_queue.q_first == NULL) {
2750fcf3ce44SJohn Forte 			hba->mbox_queue.q_last = NULL;
2751fcf3ce44SJohn Forte 			hba->mbox_queue.q_cnt = 0;
2752fcf3ce44SJohn Forte 		} else {
2753fcf3ce44SJohn Forte 			hba->mbox_queue.q_cnt--;
2754fcf3ce44SJohn Forte 		}
2755fcf3ce44SJohn Forte 
2756fcf3ce44SJohn Forte 		p_first->next = NULL;
2757fcf3ce44SJohn Forte 	}
2758291a2b48SSukumar Swaminathan 
2759fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
2760fcf3ce44SJohn Forte 
2761fcf3ce44SJohn Forte 	return (p_first);
2762fcf3ce44SJohn Forte 
2763fcf3ce44SJohn Forte } /* emlxs_mb_get() */
2764fcf3ce44SJohn Forte 
2765fcf3ce44SJohn Forte 
2766fcf3ce44SJohn Forte /* EMLXS_PORT_LOCK must be held when calling this */
2767291a2b48SSukumar Swaminathan void
2768fcf3ce44SJohn Forte emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
2769fcf3ce44SJohn Forte {
2770291a2b48SSukumar Swaminathan 	MATCHMAP	*mp;
2771fcf3ce44SJohn Forte 
2772fcf3ce44SJohn Forte 	HBASTATS.MboxIssued++;
2773fcf3ce44SJohn Forte 	hba->mbox_queue_flag = flag;
2774fcf3ce44SJohn Forte 
2775fcf3ce44SJohn Forte 	/* Set the Mailbox timer */
2776fcf3ce44SJohn Forte 	hba->mbox_timer = hba->timer_tics + tmo;
2777fcf3ce44SJohn Forte 
2778fcf3ce44SJohn Forte 	/* Initialize mailbox */
2779fcf3ce44SJohn Forte 	mbq->flag &= MBQ_INIT_MASK;
2780fcf3ce44SJohn Forte 	mbq->next = 0;
2781fcf3ce44SJohn Forte 
2782fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
2783*a9800bebSGarrett D'Amore 	hba->mbox_mbq = (void *)mbq;
2784fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
2785fcf3ce44SJohn Forte 
278682527734SSukumar Swaminathan 	if (mbq->nonembed) {
278782527734SSukumar Swaminathan 		mp = (MATCHMAP *) mbq->nonembed;
278882527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
2789fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORDEV);
2790fcf3ce44SJohn Forte 	}
2791291a2b48SSukumar Swaminathan 
279282527734SSukumar Swaminathan 	if (mbq->bp) {
279382527734SSukumar Swaminathan 		mp = (MATCHMAP *) mbq->bp;
279482527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
279582527734SSukumar Swaminathan 		    DDI_DMA_SYNC_FORDEV);
2796fcf3ce44SJohn Forte 	}
2797fcf3ce44SJohn Forte 	return;
2798fcf3ce44SJohn Forte 
2799fcf3ce44SJohn Forte } /* emlxs_mb_init() */
2800fcf3ce44SJohn Forte 
2801fcf3ce44SJohn Forte 
2802fcf3ce44SJohn Forte extern void
2803fcf3ce44SJohn Forte emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus)
2804fcf3ce44SJohn Forte {
2805291a2b48SSukumar Swaminathan 	emlxs_port_t	*port = &PPORT;
280682527734SSukumar Swaminathan 	MATCHMAP	*mbox_nonembed;
2807291a2b48SSukumar Swaminathan 	MATCHMAP	*mbox_bp;
2808291a2b48SSukumar Swaminathan 	emlxs_buf_t	*mbox_sbp;
2809291a2b48SSukumar Swaminathan 	fc_unsol_buf_t	*mbox_ubp;
2810291a2b48SSukumar Swaminathan 	IOCBQ		*mbox_iocbq;
2811291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbox_mbq;
2812291a2b48SSukumar Swaminathan 	MAILBOX		*mbox;
2813291a2b48SSukumar Swaminathan 	uint32_t	mbox_queue_flag;
2814fcf3ce44SJohn Forte 
2815fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
2816fcf3ce44SJohn Forte 
2817fcf3ce44SJohn Forte 	if (hba->mbox_queue_flag) {
2818fcf3ce44SJohn Forte 		HBASTATS.MboxCompleted++;
2819fcf3ce44SJohn Forte 
2820fcf3ce44SJohn Forte 		if (mbxStatus != MBX_SUCCESS) {
2821fcf3ce44SJohn Forte 			HBASTATS.MboxError++;
2822fcf3ce44SJohn Forte 		} else {
2823fcf3ce44SJohn Forte 			HBASTATS.MboxGood++;
2824fcf3ce44SJohn Forte 		}
2825fcf3ce44SJohn Forte 	}
2826291a2b48SSukumar Swaminathan 
282782527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MBOX_LOCK);
2828fcf3ce44SJohn Forte 	mbox_queue_flag = hba->mbox_queue_flag;
282982527734SSukumar Swaminathan 	mbox_mbq = (MAILBOXQ *)hba->mbox_mbq;
2830fcf3ce44SJohn Forte 
283182527734SSukumar Swaminathan 	if (mbox_mbq) {
283282527734SSukumar Swaminathan 		mbox_nonembed = (MATCHMAP *)mbox_mbq->nonembed;
283382527734SSukumar Swaminathan 		mbox_bp = (MATCHMAP *)mbox_mbq->bp;
283482527734SSukumar Swaminathan 		mbox_sbp = (emlxs_buf_t *)mbox_mbq->sbp;
283582527734SSukumar Swaminathan 		mbox_ubp = (fc_unsol_buf_t *)mbox_mbq->ubp;
283682527734SSukumar Swaminathan 		mbox_iocbq = (IOCBQ *)mbox_mbq->iocbq;
283782527734SSukumar Swaminathan 	} else {
283882527734SSukumar Swaminathan 		mbox_nonembed = NULL;
283982527734SSukumar Swaminathan 		mbox_bp = NULL;
284082527734SSukumar Swaminathan 		mbox_sbp = NULL;
284182527734SSukumar Swaminathan 		mbox_ubp = NULL;
284282527734SSukumar Swaminathan 		mbox_iocbq = NULL;
284382527734SSukumar Swaminathan 	}
2844fcf3ce44SJohn Forte 
2845*a9800bebSGarrett D'Amore 	hba->mbox_mbq = NULL;
2846fcf3ce44SJohn Forte 	hba->mbox_queue_flag = 0;
284782527734SSukumar Swaminathan 	hba->mbox_timer = 0;
284882527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MBOX_LOCK);
2849fcf3ce44SJohn Forte 
2850fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
2851fcf3ce44SJohn Forte 
285282527734SSukumar Swaminathan 	if (mbox_queue_flag == MBX_NOWAIT) {
285382527734SSukumar Swaminathan 		/* Check for deferred MBUF cleanup */
285482527734SSukumar Swaminathan 		if (mbox_bp) {
2855*a9800bebSGarrett D'Amore 			emlxs_mem_put(hba, MEM_BUF, (void *)mbox_bp);
285682527734SSukumar Swaminathan 		}
285782527734SSukumar Swaminathan 		if (mbox_nonembed) {
2858*a9800bebSGarrett D'Amore 			emlxs_mem_put(hba, MEM_BUF,
2859*a9800bebSGarrett D'Amore 			    (void *)mbox_nonembed);
2860fcf3ce44SJohn Forte 		}
286182527734SSukumar Swaminathan 		if (mbox_mbq) {
2862*a9800bebSGarrett D'Amore 			emlxs_mem_put(hba, MEM_MBOX,
2863*a9800bebSGarrett D'Amore 			    (void *)mbox_mbq);
286482527734SSukumar Swaminathan 		}
286582527734SSukumar Swaminathan 	} else {  /* MBX_WAIT */
286682527734SSukumar Swaminathan 		if (mbox_mbq) {
286782527734SSukumar Swaminathan 			if (mb) {
286882527734SSukumar Swaminathan 				/* Copy the local mailbox provided back into */
286982527734SSukumar Swaminathan 				/* the original mailbox */
287082527734SSukumar Swaminathan 				if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
287182527734SSukumar Swaminathan 					bcopy((uint32_t *)mb,
287282527734SSukumar Swaminathan 					    (uint32_t *)mbox_mbq,
287382527734SSukumar Swaminathan 					    MAILBOX_CMD_SLI4_BSIZE);
287482527734SSukumar Swaminathan 				} else {
287582527734SSukumar Swaminathan 					bcopy((uint32_t *)mb,
287682527734SSukumar Swaminathan 					    (uint32_t *)mbox_mbq,
287782527734SSukumar Swaminathan 					    MAILBOX_CMD_BSIZE);
287882527734SSukumar Swaminathan 				}
287982527734SSukumar Swaminathan 			}
2880291a2b48SSukumar Swaminathan 
288182527734SSukumar Swaminathan 			mbox = (MAILBOX *)mbox_mbq;
2882*a9800bebSGarrett D'Amore 			mbox->mbxStatus = (uint16_t)mbxStatus;
2883fcf3ce44SJohn Forte 
288482527734SSukumar Swaminathan 			/* Mark mailbox complete */
288582527734SSukumar Swaminathan 			mbox_mbq->flag |= MBQ_COMPLETED;
288682527734SSukumar Swaminathan 		}
2887fcf3ce44SJohn Forte 
2888fcf3ce44SJohn Forte 		/* Wake up the sleeping thread */
2889fcf3ce44SJohn Forte 		if (mbox_queue_flag == MBX_SLEEP) {
2890fcf3ce44SJohn Forte 			mutex_enter(&EMLXS_MBOX_LOCK);
2891fcf3ce44SJohn Forte 			cv_broadcast(&EMLXS_MBOX_CV);
2892fcf3ce44SJohn Forte 			mutex_exit(&EMLXS_MBOX_LOCK);
2893fcf3ce44SJohn Forte 		}
2894fcf3ce44SJohn Forte 	}
2895291a2b48SSukumar Swaminathan 
2896fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
289782527734SSukumar Swaminathan 	if (mb && mbox_sbp && mbox_sbp->fct_cmd) {
2898fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
2899fcf3ce44SJohn Forte 		    "FCT mailbox: %s: status=%x",
2900fcf3ce44SJohn Forte 		    emlxs_mb_cmd_xlate(mb->mbxCommand),
2901fcf3ce44SJohn Forte 		    (uint32_t)mb->mbxStatus);
2902fcf3ce44SJohn Forte 	}
2903291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
2904fcf3ce44SJohn Forte 
2905*a9800bebSGarrett D'Amore 	emlxs_mb_deferred_cmpl(port, mbxStatus, mbox_sbp, mbox_ubp, mbox_iocbq);
2906*a9800bebSGarrett D'Amore 
2907*a9800bebSGarrett D'Amore 	return;
2908*a9800bebSGarrett D'Amore 
2909*a9800bebSGarrett D'Amore } /* emlxs_mb_fini() */
2910*a9800bebSGarrett D'Amore 
2911*a9800bebSGarrett D'Amore 
2912*a9800bebSGarrett D'Amore extern void
2913*a9800bebSGarrett D'Amore emlxs_mb_deferred_cmpl(emlxs_port_t *port, uint32_t mbxStatus, emlxs_buf_t *sbp,
2914*a9800bebSGarrett D'Amore     fc_unsol_buf_t *ubp, IOCBQ *iocbq)
2915*a9800bebSGarrett D'Amore {
2916*a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2917*a9800bebSGarrett D'Amore 	emlxs_ub_priv_t	*ub_priv;
2918*a9800bebSGarrett D'Amore 
2919*a9800bebSGarrett D'Amore #ifdef SFCT_SUPPORT
2920*a9800bebSGarrett D'Amore 	if ((mbxStatus == MBX_SUCCESS) && sbp && sbp->fct_cmd) {
2921*a9800bebSGarrett D'Amore 		emlxs_buf_t *cmd_sbp = sbp;
2922*a9800bebSGarrett D'Amore 
2923*a9800bebSGarrett D'Amore 		if ((cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) &&
2924*a9800bebSGarrett D'Amore 		    (cmd_sbp->node)) {
2925*a9800bebSGarrett D'Amore 
2926*a9800bebSGarrett D'Amore 			mutex_enter(&EMLXS_PKT_LOCK);
2927*a9800bebSGarrett D'Amore 			cmd_sbp->fct_flags |= EMLXS_FCT_REGISTERED;
2928*a9800bebSGarrett D'Amore 			cv_broadcast(&EMLXS_PKT_CV);
2929*a9800bebSGarrett D'Amore 			mutex_exit(&EMLXS_PKT_LOCK);
2930*a9800bebSGarrett D'Amore 
2931*a9800bebSGarrett D'Amore 			sbp = NULL;
2932*a9800bebSGarrett D'Amore 		}
2933*a9800bebSGarrett D'Amore 	}
2934*a9800bebSGarrett D'Amore #endif /* SFCT_SUPPORT */
2935*a9800bebSGarrett D'Amore 
2936fcf3ce44SJohn Forte 	/* Check for deferred pkt completion */
2937*a9800bebSGarrett D'Amore 	if (sbp) {
2938fcf3ce44SJohn Forte 		if (mbxStatus != MBX_SUCCESS) {
2939fcf3ce44SJohn Forte 			/* Set error status */
2940*a9800bebSGarrett D'Amore 			sbp->pkt_flags &= ~PACKET_STATE_VALID;
2941*a9800bebSGarrett D'Amore 			emlxs_set_pkt_state(sbp, IOSTAT_LOCAL_REJECT,
2942fcf3ce44SJohn Forte 			    IOERR_NO_RESOURCES, 1);
2943fcf3ce44SJohn Forte 		}
2944291a2b48SSukumar Swaminathan 
2945*a9800bebSGarrett D'Amore 		emlxs_pkt_complete(sbp, -1, 0, 1);
2946fcf3ce44SJohn Forte 	}
2947291a2b48SSukumar Swaminathan 
2948fcf3ce44SJohn Forte 	/* Check for deferred ub completion */
2949*a9800bebSGarrett D'Amore 	if (ubp) {
2950*a9800bebSGarrett D'Amore 		ub_priv = ubp->ub_fca_private;
2951fcf3ce44SJohn Forte 
2952*a9800bebSGarrett D'Amore 		if (mbxStatus == MBX_SUCCESS) {
2953*a9800bebSGarrett D'Amore 			emlxs_ub_callback(ub_priv->port, ubp);
2954*a9800bebSGarrett D'Amore 		} else {
2955*a9800bebSGarrett D'Amore 			(void) emlxs_fca_ub_release(ub_priv->port, 1,
2956*a9800bebSGarrett D'Amore 			    &ubp->ub_token);
2957*a9800bebSGarrett D'Amore 		}
2958fcf3ce44SJohn Forte 	}
2959291a2b48SSukumar Swaminathan 
2960*a9800bebSGarrett D'Amore 	/* Special handling for restricted login */
2961*a9800bebSGarrett D'Amore 	if (iocbq == (IOCBQ *)1) {
2962*a9800bebSGarrett D'Amore 		iocbq = NULL;
296382527734SSukumar Swaminathan 	}
296482527734SSukumar Swaminathan 
2965fcf3ce44SJohn Forte 	/* Check for deferred iocb tx */
2966*a9800bebSGarrett D'Amore 	if (iocbq) {
296782527734SSukumar Swaminathan 		/* Check for driver special codes */
296882527734SSukumar Swaminathan 		/* These indicate the mailbox is being flushed */
296982527734SSukumar Swaminathan 		if (mbxStatus >= MBX_DRIVER_RESERVED) {
297082527734SSukumar Swaminathan 			/* Set the error status and return it */
2971*a9800bebSGarrett D'Amore 			iocbq->iocb.ULPSTATUS = IOSTAT_LOCAL_REJECT;
2972*a9800bebSGarrett D'Amore 			iocbq->iocb.un.grsp.perr.statLocalError =
297382527734SSukumar Swaminathan 			    IOERR_ABORT_REQUESTED;
297482527734SSukumar Swaminathan 
2975*a9800bebSGarrett D'Amore 			emlxs_proc_channel_event(hba, iocbq->channel,
2976*a9800bebSGarrett D'Amore 			    iocbq);
297782527734SSukumar Swaminathan 		} else {
2978*a9800bebSGarrett D'Amore 			EMLXS_SLI_ISSUE_IOCB_CMD(hba, iocbq->channel,
2979*a9800bebSGarrett D'Amore 			    iocbq);
298082527734SSukumar Swaminathan 		}
2981fcf3ce44SJohn Forte 	}
2982*a9800bebSGarrett D'Amore 
2983fcf3ce44SJohn Forte 	return;
2984fcf3ce44SJohn Forte 
2985*a9800bebSGarrett D'Amore } /* emlxs_mb_deferred_cmpl() */
2986fcf3ce44SJohn Forte 
2987fcf3ce44SJohn Forte 
298882527734SSukumar Swaminathan extern void
298982527734SSukumar Swaminathan emlxs_mb_flush(emlxs_hba_t *hba)
2990fcf3ce44SJohn Forte {
2991291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
299282527734SSukumar Swaminathan 	uint32_t	mbxStatus;
2993fcf3ce44SJohn Forte 
299482527734SSukumar Swaminathan 	mbxStatus = (hba->flag & FC_HARDWARE_ERROR) ?
299582527734SSukumar Swaminathan 	    MBX_HARDWARE_ERROR : MBX_NOT_FINISHED;
2996fcf3ce44SJohn Forte 
299782527734SSukumar Swaminathan 	/* Flush out the active mbox command */
299882527734SSukumar Swaminathan 	emlxs_mb_fini(hba, NULL, mbxStatus);
2999fcf3ce44SJohn Forte 
300082527734SSukumar Swaminathan 	/* Flush out the queued mbox commands */
300182527734SSukumar Swaminathan 	while (mbq = (MAILBOXQ *)emlxs_mb_get(hba)) {
300282527734SSukumar Swaminathan 		mutex_enter(&EMLXS_MBOX_LOCK);
300382527734SSukumar Swaminathan 		hba->mbox_queue_flag = MBX_NOWAIT;
3004*a9800bebSGarrett D'Amore 		hba->mbox_mbq = (void *)mbq;
300582527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MBOX_LOCK);
3006fcf3ce44SJohn Forte 
300782527734SSukumar Swaminathan 		emlxs_mb_fini(hba, NULL, mbxStatus);
300882527734SSukumar Swaminathan 	}
3009fcf3ce44SJohn Forte 
3010fcf3ce44SJohn Forte 	return;
3011fcf3ce44SJohn Forte 
301282527734SSukumar Swaminathan } /* emlxs_mb_flush */
3013fcf3ce44SJohn Forte 
3014fcf3ce44SJohn Forte 
3015291a2b48SSukumar Swaminathan extern char *
3016291a2b48SSukumar Swaminathan emlxs_mb_cmd_xlate(uint8_t cmd)
3017fcf3ce44SJohn Forte {
3018291a2b48SSukumar Swaminathan 	static char	buffer[32];
3019291a2b48SSukumar Swaminathan 	uint32_t	i;
3020291a2b48SSukumar Swaminathan 	uint32_t	count;
3021fcf3ce44SJohn Forte 
3022fcf3ce44SJohn Forte 	count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t);
3023fcf3ce44SJohn Forte 	for (i = 0; i < count; i++) {
3024fcf3ce44SJohn Forte 		if (cmd == emlxs_mb_cmd_table[i].code) {
3025fcf3ce44SJohn Forte 			return (emlxs_mb_cmd_table[i].string);
3026fcf3ce44SJohn Forte 		}
3027fcf3ce44SJohn Forte 	}
3028fcf3ce44SJohn Forte 
3029fcf3ce44SJohn Forte 	(void) sprintf(buffer, "Cmd=0x%x", cmd);
3030fcf3ce44SJohn Forte 	return (buffer);
3031fcf3ce44SJohn Forte 
3032fcf3ce44SJohn Forte } /* emlxs_mb_cmd_xlate() */
3033