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 /*
23291a2b48SSukumar Swaminathan  * Copyright 2009 Emulex.  All rights reserved.
24*82527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27*82527734SSukumar Swaminathan 
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte 
30*82527734SSukumar Swaminathan /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31*82527734SSukumar Swaminathan EMLXS_MSG_DEF(EMLXS_MBOX_C);
32*82527734SSukumar Swaminathan 
33*82527734SSukumar Swaminathan static void	emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOXQ *mbq,
34*82527734SSukumar Swaminathan 			uint32_t hbainit);
35*82527734SSukumar Swaminathan static void	emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOXQ *mbq,
36*82527734SSukumar Swaminathan 			uint32_t mask, uint32_t ringno);
37*82527734SSukumar Swaminathan static void	emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOXQ *mbq,
38*82527734SSukumar Swaminathan 			uint32_t word0, uint32_t word1, uint32_t word2);
39*82527734SSukumar Swaminathan static void	emlxs_mb_write_nv(emlxs_hba_t *hba, MAILBOXQ *mbq);
40*82527734SSukumar Swaminathan 
41*82527734SSukumar Swaminathan 
42*82527734SSukumar Swaminathan emlxs_table_t emlxs_mb_cmd_table[] = {
43*82527734SSukumar Swaminathan 	{MBX_SHUTDOWN, "SHUTDOWN"},
44*82527734SSukumar Swaminathan 	{MBX_LOAD_SM, "LOAD_SM"},
45*82527734SSukumar Swaminathan 	{MBX_READ_NV, "READ_NV"},
46*82527734SSukumar Swaminathan 	{MBX_WRITE_NV, "WRITE_NV"},
47*82527734SSukumar Swaminathan 	{MBX_RUN_BIU_DIAG, "RUN_BIU_DIAG"},
48*82527734SSukumar Swaminathan 	{MBX_INIT_LINK, "INIT_LINK"},
49*82527734SSukumar Swaminathan 	{MBX_DOWN_LINK, "DOWN_LINK"},
50*82527734SSukumar Swaminathan 	{MBX_CONFIG_LINK, "CONFIG_LINK"},
51*82527734SSukumar Swaminathan 	{MBX_PART_SLIM, "PART_SLIM"},
52*82527734SSukumar Swaminathan 	{MBX_CONFIG_RING, "CONFIG_RING"},
53*82527734SSukumar Swaminathan 	{MBX_RESET_RING, "RESET_RING"},
54*82527734SSukumar Swaminathan 	{MBX_READ_CONFIG, "READ_CONFIG"},
55*82527734SSukumar Swaminathan 	{MBX_READ_RCONFIG, "READ_RCONFIG"},
56*82527734SSukumar Swaminathan 	{MBX_READ_SPARM, "READ_SPARM"},
57*82527734SSukumar Swaminathan 	{MBX_READ_STATUS, "READ_STATUS"},
58*82527734SSukumar Swaminathan 	{MBX_READ_RPI, "READ_RPI"},
59*82527734SSukumar Swaminathan 	{MBX_READ_XRI, "READ_XRI"},
60*82527734SSukumar Swaminathan 	{MBX_READ_REV, "READ_REV"},
61*82527734SSukumar Swaminathan 	{MBX_READ_LNK_STAT, "READ_LNK_STAT"},
62*82527734SSukumar Swaminathan 	{MBX_REG_LOGIN, "REG_LOGIN"},
63*82527734SSukumar Swaminathan 	{MBX_UNREG_LOGIN, "UNREG_LOGIN"},
64*82527734SSukumar Swaminathan 	{MBX_READ_LA, "READ_LA"},
65*82527734SSukumar Swaminathan 	{MBX_CLEAR_LA, "CLEAR_LA"},
66*82527734SSukumar Swaminathan 	{MBX_DUMP_MEMORY, "DUMP_MEMORY"},
67*82527734SSukumar Swaminathan 	{MBX_DUMP_CONTEXT, "DUMP_CONTEXT"},
68*82527734SSukumar Swaminathan 	{MBX_RUN_DIAGS, "RUN_DIAGS"},
69*82527734SSukumar Swaminathan 	{MBX_RESTART, "RESTART"},
70*82527734SSukumar Swaminathan 	{MBX_UPDATE_CFG, "UPDATE_CFG"},
71*82527734SSukumar Swaminathan 	{MBX_DOWN_LOAD, "DOWN_LOAD"},
72*82527734SSukumar Swaminathan 	{MBX_DEL_LD_ENTRY, "DEL_LD_ENTRY"},
73*82527734SSukumar Swaminathan 	{MBX_RUN_PROGRAM, "RUN_PROGRAM"},
74*82527734SSukumar Swaminathan 	{MBX_SET_MASK, "SET_MASK"},
75*82527734SSukumar Swaminathan 	{MBX_SET_VARIABLE, "SET_VARIABLE"},
76*82527734SSukumar Swaminathan 	{MBX_UNREG_D_ID, "UNREG_D_ID"},
77*82527734SSukumar Swaminathan 	{MBX_KILL_BOARD, "KILL_BOARD"},
78*82527734SSukumar Swaminathan 	{MBX_CONFIG_FARP, "CONFIG_FARP"},
79*82527734SSukumar Swaminathan 	{MBX_LOAD_AREA, "LOAD_AREA"},
80*82527734SSukumar Swaminathan 	{MBX_RUN_BIU_DIAG64, "RUN_BIU_DIAG64"},
81*82527734SSukumar Swaminathan 	{MBX_CONFIG_PORT, "CONFIG_PORT"},
82*82527734SSukumar Swaminathan 	{MBX_READ_SPARM64, "READ_SPARM64"},
83*82527734SSukumar Swaminathan 	{MBX_READ_RPI64, "READ_RPI64"},
84*82527734SSukumar Swaminathan 	{MBX_CONFIG_MSI, "CONFIG_MSI"},
85*82527734SSukumar Swaminathan 	{MBX_CONFIG_MSIX, "CONFIG_MSIX"},
86*82527734SSukumar Swaminathan 	{MBX_REG_LOGIN64, "REG_LOGIN64"},
87*82527734SSukumar Swaminathan 	{MBX_READ_LA64, "READ_LA64"},
88*82527734SSukumar Swaminathan 	{MBX_FLASH_WR_ULA, "FLASH_WR_ULA"},
89*82527734SSukumar Swaminathan 	{MBX_SET_DEBUG, "SET_DEBUG"},
90*82527734SSukumar Swaminathan 	{MBX_GET_DEBUG, "GET_DEBUG"},
91*82527734SSukumar Swaminathan 	{MBX_LOAD_EXP_ROM, "LOAD_EXP_ROM"},
92*82527734SSukumar Swaminathan 	{MBX_BEACON, "BEACON"},
93*82527734SSukumar Swaminathan 	{MBX_CONFIG_HBQ, "CONFIG_HBQ"},	/* SLI3 */
94*82527734SSukumar Swaminathan 	{MBX_REG_VPI, "REG_VPI"},	/* NPIV */
95*82527734SSukumar Swaminathan 	{MBX_UNREG_VPI, "UNREG_VPI"},	/* NPIV */
96*82527734SSukumar Swaminathan 	{MBX_ASYNC_EVENT, "ASYNC_EVENT"},
97*82527734SSukumar Swaminathan 	{MBX_HEARTBEAT, "HEARTBEAT"},
98*82527734SSukumar Swaminathan 	{MBX_READ_EVENT_LOG_STATUS, "READ_EVENT_LOG_STATUS"},
99*82527734SSukumar Swaminathan 	{MBX_READ_EVENT_LOG, "READ_EVENT_LOG"},
100*82527734SSukumar Swaminathan 	{MBX_WRITE_EVENT_LOG, "WRITE_EVENT_LOG"},
101*82527734SSukumar Swaminathan 	{MBX_NV_LOG, "NV_LOG"},
102*82527734SSukumar Swaminathan 	{MBX_PORT_CAPABILITIES, "PORT_CAPABILITIES"},
103*82527734SSukumar Swaminathan 	{MBX_IOV_CONTROL, "IOV_CONTROL"},
104*82527734SSukumar Swaminathan 	{MBX_IOV_MBX, "IOV_MBX"},
105*82527734SSukumar Swaminathan 	{MBX_SLI_CONFIG, "SLI_CONFIG"},
106*82527734SSukumar Swaminathan 	{MBX_REQUEST_FEATURES, "REQUEST_FEATURES"},
107*82527734SSukumar Swaminathan 	{MBX_RESUME_RPI, "RESUME_RPI"},
108*82527734SSukumar Swaminathan 	{MBX_REG_VFI, "REG_VFI"},
109*82527734SSukumar Swaminathan 	{MBX_REG_FCFI, "REG_FCFI"},
110*82527734SSukumar Swaminathan 	{MBX_UNREG_VFI, "UNREG_VFI"},
111*82527734SSukumar Swaminathan 	{MBX_UNREG_FCFI, "UNREG_FCFI"},
112*82527734SSukumar Swaminathan 	{MBX_INIT_VFI, "INIT_VFI"},
113*82527734SSukumar Swaminathan 	{MBX_INIT_VPI, "INIT_VPI"}
114*82527734SSukumar Swaminathan };	/* emlxs_mb_cmd_table */
115*82527734SSukumar Swaminathan 
116*82527734SSukumar Swaminathan 
117*82527734SSukumar Swaminathan /*
118*82527734SSukumar Swaminathan  * emlxs_mb_resetport  Issue a Port Reset mailbox command
119*82527734SSukumar Swaminathan  */
120*82527734SSukumar Swaminathan /*ARGSUSED*/
121*82527734SSukumar Swaminathan extern void
122*82527734SSukumar Swaminathan emlxs_mb_resetport(emlxs_hba_t *hba, MAILBOXQ *mbq)
123*82527734SSukumar Swaminathan {
124*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
125*82527734SSukumar Swaminathan 
126*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
127*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
128*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
129*82527734SSukumar Swaminathan 
130*82527734SSukumar Swaminathan 	/*
131*82527734SSukumar Swaminathan 	 * Signifies an embedded command
132*82527734SSukumar Swaminathan 	 */
133*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
134*82527734SSukumar Swaminathan 
135*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
136*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
137*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length = IOCTL_HEADER_SZ;
138*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
139*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
140*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_RESET;
141*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
142*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length = 0;
143*82527734SSukumar Swaminathan 
144*82527734SSukumar Swaminathan 	return;
145*82527734SSukumar Swaminathan 
146*82527734SSukumar Swaminathan } /* emlxs_mb_resetport() */
147*82527734SSukumar Swaminathan 
148*82527734SSukumar Swaminathan 
149*82527734SSukumar Swaminathan /*
150*82527734SSukumar Swaminathan  * emlxs_mb_request_features  Issue a REQUEST FEATURES mailbox command
151*82527734SSukumar Swaminathan  */
152*82527734SSukumar Swaminathan /*ARGSUSED*/
153*82527734SSukumar Swaminathan extern void
154*82527734SSukumar Swaminathan emlxs_mb_request_features(emlxs_hba_t *hba, MAILBOXQ *mbq)
155*82527734SSukumar Swaminathan {
156*82527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
157*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
158*82527734SSukumar Swaminathan 
159*82527734SSukumar Swaminathan 	hba->flag &= ~FC_NPIV_ENABLED;
160*82527734SSukumar Swaminathan 
161*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
162*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
163*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
164*82527734SSukumar Swaminathan 
165*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_REQUEST_FEATURES;
166*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
167*82527734SSukumar Swaminathan 	mb->un.varReqFeatures.featuresRequested |=
168*82527734SSukumar Swaminathan 	    SLI4_FEATURE_FCP_INITIATOR;
169*82527734SSukumar Swaminathan 
170*82527734SSukumar Swaminathan 	if (cfg[CFG_NPIV_ENABLE].current) {
171*82527734SSukumar Swaminathan 		mb->un.varReqFeatures.featuresRequested |=
172*82527734SSukumar Swaminathan 		    SLI4_FEATURE_NPIV;
173*82527734SSukumar Swaminathan 	}
174*82527734SSukumar Swaminathan 
175*82527734SSukumar Swaminathan } /* emlxs_mb_request_features() */
176*82527734SSukumar Swaminathan 
177*82527734SSukumar Swaminathan 
178*82527734SSukumar Swaminathan /*
179*82527734SSukumar Swaminathan  * emlxs_mb_resume_rpi  Issue a RESUME_RPI mailbox command
180*82527734SSukumar Swaminathan  */
181*82527734SSukumar Swaminathan /*ARGSUSED*/
182*82527734SSukumar Swaminathan extern int
183*82527734SSukumar Swaminathan emlxs_mb_resume_rpi(emlxs_hba_t *hba, emlxs_buf_t *sbp, uint16_t rpi)
184*82527734SSukumar Swaminathan {
185*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
186*82527734SSukumar Swaminathan 	MAILBOXQ *mbq;
187*82527734SSukumar Swaminathan 	uint32_t rval;
188*82527734SSukumar Swaminathan 
189*82527734SSukumar Swaminathan 	(void) emlxs_sli4_find_rpi(hba, rpi);
190*82527734SSukumar Swaminathan 
191*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
192*82527734SSukumar Swaminathan 		return (1);
193*82527734SSukumar Swaminathan 	}
194*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
195*82527734SSukumar Swaminathan 
196*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
197*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
198*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
199*82527734SSukumar Swaminathan 	mbq->sbp = (uint8_t *)sbp;
200*82527734SSukumar Swaminathan 
201*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_RESUME_RPI;
202*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
203*82527734SSukumar Swaminathan 	mb->un.varResumeRPI.EventTag = hba->link_event_tag;
204*82527734SSukumar Swaminathan 	mb->un.varResumeRPI.RPI = rpi;
205*82527734SSukumar Swaminathan 
206*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
207*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
208*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
209*82527734SSukumar Swaminathan 	}
210*82527734SSukumar Swaminathan 	return (rval);
211*82527734SSukumar Swaminathan 
212*82527734SSukumar Swaminathan } /* emlxs_mb_resume_rpi() */
213*82527734SSukumar Swaminathan 
214*82527734SSukumar Swaminathan 
215*82527734SSukumar Swaminathan /*ARGSUSED*/
216*82527734SSukumar Swaminathan extern void
217*82527734SSukumar Swaminathan emlxs_mb_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
218*82527734SSukumar Swaminathan {
219*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
220*82527734SSukumar Swaminathan 	IOCTL_COMMON_NOP *nop;
221*82527734SSukumar Swaminathan 
222*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
223*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
224*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
225*82527734SSukumar Swaminathan 
226*82527734SSukumar Swaminathan 	/*
227*82527734SSukumar Swaminathan 	 * Signifies an embedded command
228*82527734SSukumar Swaminathan 	 */
229*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
230*82527734SSukumar Swaminathan 
231*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
232*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
233*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length = sizeof (IOCTL_COMMON_NOP) +
234*82527734SSukumar Swaminathan 	    IOCTL_HEADER_SZ;
235*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
236*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
237*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_NOP;
238*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
239*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
240*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_NOP);
241*82527734SSukumar Swaminathan 	nop = (IOCTL_COMMON_NOP *)&mb->un.varSLIConfig.payload;
242*82527734SSukumar Swaminathan 	nop->params.request.context = -1;
243*82527734SSukumar Swaminathan 
244*82527734SSukumar Swaminathan 	return;
245*82527734SSukumar Swaminathan 
246*82527734SSukumar Swaminathan } /* emlxs_mb_noop() */
247*82527734SSukumar Swaminathan 
248*82527734SSukumar Swaminathan 
249*82527734SSukumar Swaminathan /*ARGSUSED*/
250*82527734SSukumar Swaminathan extern int
251*82527734SSukumar Swaminathan emlxs_mbext_noop(emlxs_hba_t *hba, MAILBOXQ *mbq)
252*82527734SSukumar Swaminathan {
253*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
254*82527734SSukumar Swaminathan 	IOCTL_COMMON_NOP *nop;
255*82527734SSukumar Swaminathan 	MATCHMAP *mp;
256*82527734SSukumar Swaminathan 	mbox_req_hdr_t	*hdr_req;
257*82527734SSukumar Swaminathan 
258*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
259*82527734SSukumar Swaminathan 
260*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
261*82527734SSukumar Swaminathan 		return (1);
262*82527734SSukumar Swaminathan 	}
263*82527734SSukumar Swaminathan 	/*
264*82527734SSukumar Swaminathan 	 * Save address for completion
265*82527734SSukumar Swaminathan 	 * Signifies a non-embedded command
266*82527734SSukumar Swaminathan 	 */
267*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 0;
268*82527734SSukumar Swaminathan 	mbq->nonembed = (uint8_t *)mp;
269*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
270*82527734SSukumar Swaminathan 
271*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
272*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
273*82527734SSukumar Swaminathan 
274*82527734SSukumar Swaminathan 	hdr_req = (mbox_req_hdr_t *)mp->virt;
275*82527734SSukumar Swaminathan 	hdr_req->subsystem = IOCTL_SUBSYSTEM_COMMON;
276*82527734SSukumar Swaminathan 	hdr_req->opcode = COMMON_OPCODE_NOP;
277*82527734SSukumar Swaminathan 	hdr_req->timeout = 0;
278*82527734SSukumar Swaminathan 	hdr_req->req_length = sizeof (IOCTL_COMMON_NOP);
279*82527734SSukumar Swaminathan 	nop = (IOCTL_COMMON_NOP *)(hdr_req + 1);
280*82527734SSukumar Swaminathan 	nop->params.request.context = -1;
281*82527734SSukumar Swaminathan 
282*82527734SSukumar Swaminathan 	return (0);
283*82527734SSukumar Swaminathan 
284*82527734SSukumar Swaminathan } /* emlxs_mbext_noop() */
285*82527734SSukumar Swaminathan 
286*82527734SSukumar Swaminathan 
287*82527734SSukumar Swaminathan int
288*82527734SSukumar Swaminathan emlxs_cmpl_read_fcf_table(void *arg1, MAILBOXQ *mbq)
289*82527734SSukumar Swaminathan {
290*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
291*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
292*82527734SSukumar Swaminathan 	mbox_rsp_hdr_t	*hdr_rsp;
293*82527734SSukumar Swaminathan 	IOCTL_FCOE_READ_FCF_TABLE *fcf;
294*82527734SSukumar Swaminathan 	FCF_RECORD_t *fcfrec;
295*82527734SSukumar Swaminathan 	FCFIobj_t *fcfp;
296*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
297*82527734SSukumar Swaminathan 	MATCHMAP *mp;
298*82527734SSukumar Swaminathan 	MAILBOXQ *fcfmbq;
299*82527734SSukumar Swaminathan 	uint32_t i, *iptr;
300*82527734SSukumar Swaminathan 	uint16_t s, *sptr;
301*82527734SSukumar Swaminathan 	int rc;
302*82527734SSukumar Swaminathan 
303*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
304*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->nonembed;
305*82527734SSukumar Swaminathan 	hdr_rsp = (mbox_rsp_hdr_t *)mp->virt;
306*82527734SSukumar Swaminathan 
307*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
308*82527734SSukumar Swaminathan 	    "CMPL read fcf: stats: %x %x %x",
309*82527734SSukumar Swaminathan 	    mb->mbxStatus, hdr_rsp->status, hdr_rsp->extra_status);
310*82527734SSukumar Swaminathan 
311*82527734SSukumar Swaminathan 	if (mb->mbxStatus || hdr_rsp->status) {
312*82527734SSukumar Swaminathan 		/* Wait for FCF found async event */
313*82527734SSukumar Swaminathan 		return (0);
314*82527734SSukumar Swaminathan 	}
315*82527734SSukumar Swaminathan 
316*82527734SSukumar Swaminathan 	/*
317*82527734SSukumar Swaminathan 	 * Only support 1 FCF for now, so we don't need to walk
318*82527734SSukumar Swaminathan 	 * thru the FCF table.
319*82527734SSukumar Swaminathan 	 */
320*82527734SSukumar Swaminathan 	fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_rsp + 1);
321*82527734SSukumar Swaminathan 	fcfrec = &fcf->params.response.fcf_entry[0];
322*82527734SSukumar Swaminathan 
323*82527734SSukumar Swaminathan 	/* Fix up data in FCF record */
324*82527734SSukumar Swaminathan 	BE_SWAP32_BUFFER(&fcfrec->fabric_name_identifier[0], 8);
325*82527734SSukumar Swaminathan 	BE_SWAP32_BUFFER(&fcfrec->switch_name_identifier[0], 8);
326*82527734SSukumar Swaminathan 	BE_SWAP32_BUFFER(&fcfrec->vlan_bitmap[0], 512);
327*82527734SSukumar Swaminathan 	iptr = (uint32_t *)&fcfrec->fcf_mac_address_hi[0];
328*82527734SSukumar Swaminathan 	i = *iptr;
329*82527734SSukumar Swaminathan 	*iptr = BE_SWAP32(i);
330*82527734SSukumar Swaminathan 	sptr = (uint16_t *)&fcfrec->fcf_mac_address_low[0];
331*82527734SSukumar Swaminathan 	s = *sptr;
332*82527734SSukumar Swaminathan 	*sptr = BE_SWAP16(s);
333*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN
334*82527734SSukumar Swaminathan 	i = fcfrec->fc_map[0];
335*82527734SSukumar Swaminathan 	fcfrec->fc_map[0] = fcfrec->fc_map[2];
336*82527734SSukumar Swaminathan 	fcfrec->fc_map[2] = i;
337*82527734SSukumar Swaminathan #endif
338*82527734SSukumar Swaminathan 
339*82527734SSukumar Swaminathan 	/* Assign a FCFI object for the fcf_index */
340*82527734SSukumar Swaminathan 	fcfp = emlxs_sli4_assign_fcfi(hba, fcfrec);
341*82527734SSukumar Swaminathan 	if (!fcfp) {
342*82527734SSukumar Swaminathan 		return (0);
343*82527734SSukumar Swaminathan 	}
344*82527734SSukumar Swaminathan 	fcfp->EventTag = fcf->params.response.event_tag;
345*82527734SSukumar Swaminathan 
346*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
347*82527734SSukumar Swaminathan 	    "CMPL read fcf: info: x%x x%x",
348*82527734SSukumar Swaminathan 	    fcfp->EventTag, fcf->params.response.next_valid_fcf_index);
349*82527734SSukumar Swaminathan 
350*82527734SSukumar Swaminathan 	if (emlxs_sli4_bind_fcfi(hba)) {
351*82527734SSukumar Swaminathan 		/*
352*82527734SSukumar Swaminathan 		 * In this phase, if we successfully bind to just
353*82527734SSukumar Swaminathan 		 * 1 FCFI we are done.
354*82527734SSukumar Swaminathan 		 */
355*82527734SSukumar Swaminathan 		return (0);
356*82527734SSukumar Swaminathan 	}
357*82527734SSukumar Swaminathan 
358*82527734SSukumar Swaminathan 	if (fcf->params.response.next_valid_fcf_index == 0xffff) {
359*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
360*82527734SSukumar Swaminathan 		    "Waiting for a valid FCF to be discovered");
361*82527734SSukumar Swaminathan 		return (0);
362*82527734SSukumar Swaminathan 	}
363*82527734SSukumar Swaminathan 
364*82527734SSukumar Swaminathan 	/* Get the next one */
365*82527734SSukumar Swaminathan 	if (!(fcfmbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
366*82527734SSukumar Swaminathan 		return (0);
367*82527734SSukumar Swaminathan 	}
368*82527734SSukumar Swaminathan 	rc =  emlxs_mbext_read_fcf_table(hba, fcfmbq,
369*82527734SSukumar Swaminathan 	    fcf->params.response.next_valid_fcf_index);
370*82527734SSukumar Swaminathan 	if (rc == 0) {
371*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)fcfmbq);
372*82527734SSukumar Swaminathan 		return (0);
373*82527734SSukumar Swaminathan 	}
374*82527734SSukumar Swaminathan 
375*82527734SSukumar Swaminathan 	rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, fcfmbq, MBX_NOWAIT, 0);
376*82527734SSukumar Swaminathan 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
377*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)fcfmbq);
378*82527734SSukumar Swaminathan 	}
379*82527734SSukumar Swaminathan 	return (0);
380*82527734SSukumar Swaminathan } /* emlxs_cmpl_read_fcf_table() */
381*82527734SSukumar Swaminathan 
382*82527734SSukumar Swaminathan 
383*82527734SSukumar Swaminathan extern int
384*82527734SSukumar Swaminathan emlxs_mbext_read_fcf_table(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t index)
385*82527734SSukumar Swaminathan {
386*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
387*82527734SSukumar Swaminathan 	IOCTL_FCOE_READ_FCF_TABLE *fcf;
388*82527734SSukumar Swaminathan 	MATCHMAP *mp;
389*82527734SSukumar Swaminathan 	mbox_req_hdr_t	*hdr_req;
390*82527734SSukumar Swaminathan 
391*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
392*82527734SSukumar Swaminathan 
393*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
394*82527734SSukumar Swaminathan 		return (0);
395*82527734SSukumar Swaminathan 	}
396*82527734SSukumar Swaminathan 	/*
397*82527734SSukumar Swaminathan 	 * Save address for completion
398*82527734SSukumar Swaminathan 	 * Signifies a non-embedded command
399*82527734SSukumar Swaminathan 	 */
400*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 0;
401*82527734SSukumar Swaminathan 	mbq->nonembed = (uint8_t *)mp;
402*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_read_fcf_table;
403*82527734SSukumar Swaminathan 
404*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
405*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
406*82527734SSukumar Swaminathan 
407*82527734SSukumar Swaminathan 	hdr_req = (mbox_req_hdr_t *)mp->virt;
408*82527734SSukumar Swaminathan 	hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE;
409*82527734SSukumar Swaminathan 	hdr_req->opcode = FCOE_OPCODE_READ_FCF_TABLE;
410*82527734SSukumar Swaminathan 	hdr_req->timeout = 0;
411*82527734SSukumar Swaminathan 	hdr_req->req_length = sizeof (IOCTL_FCOE_READ_FCF_TABLE);
412*82527734SSukumar Swaminathan 	fcf = (IOCTL_FCOE_READ_FCF_TABLE *)(hdr_req + 1);
413*82527734SSukumar Swaminathan 	fcf->params.request.fcf_index = index;
414*82527734SSukumar Swaminathan 
415*82527734SSukumar Swaminathan 	return (1);
416*82527734SSukumar Swaminathan 
417*82527734SSukumar Swaminathan } /* emlxs_mbext_read_fcf_table() */
418*82527734SSukumar Swaminathan 
419*82527734SSukumar Swaminathan 
420*82527734SSukumar Swaminathan int
421*82527734SSukumar Swaminathan emlxs_cmpl_add_fcf_table(void *arg1, MAILBOXQ *mbq)
422*82527734SSukumar Swaminathan {
423*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
424*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
425*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
426*82527734SSukumar Swaminathan 	MAILBOXQ *mq;
427*82527734SSukumar Swaminathan 	MATCHMAP *mp;
428*82527734SSukumar Swaminathan 	mbox_rsp_hdr_t *hdr_rsp;
429*82527734SSukumar Swaminathan 	uint32_t rc;
430*82527734SSukumar Swaminathan 
431*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
432*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->nonembed;
433*82527734SSukumar Swaminathan 
434*82527734SSukumar Swaminathan 	hdr_rsp = (mbox_rsp_hdr_t *)mp->virt;
435*82527734SSukumar Swaminathan 
436*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
437*82527734SSukumar Swaminathan 	    "CMPL add fcf: stats: %x %x %x",
438*82527734SSukumar Swaminathan 	    mb->mbxStatus, hdr_rsp->status, hdr_rsp->extra_status);
439*82527734SSukumar Swaminathan 
440*82527734SSukumar Swaminathan 	if (mbq->nonembed) {
441*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mbq->nonembed);
442*82527734SSukumar Swaminathan 		mbq->nonembed = 0;
443*82527734SSukumar Swaminathan 	}
444*82527734SSukumar Swaminathan 
445*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
446*82527734SSukumar Swaminathan 		/* In nonFIP mode, FCF Entries are persistent */
447*82527734SSukumar Swaminathan 		if (!hdr_rsp->status ||
448*82527734SSukumar Swaminathan 		    (hdr_rsp->status != MGMT_STATUS_FCF_IN_USE)) {
449*82527734SSukumar Swaminathan 			return (0);
450*82527734SSukumar Swaminathan 		}
451*82527734SSukumar Swaminathan 	}
452*82527734SSukumar Swaminathan 
453*82527734SSukumar Swaminathan 	/*
454*82527734SSukumar Swaminathan 	 * Now that we have a fcf table entry, read it back
455*82527734SSukumar Swaminathan 	 * to fall into the normal link up processing.
456*82527734SSukumar Swaminathan 	 */
457*82527734SSukumar Swaminathan 	if (!(mq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
458*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
459*82527734SSukumar Swaminathan 		    "CMPL add fcf: Cannot alloc mbox");
460*82527734SSukumar Swaminathan 		return (0);
461*82527734SSukumar Swaminathan 	}
462*82527734SSukumar Swaminathan 	rc =  emlxs_mbext_read_fcf_table(hba, mq, -1);
463*82527734SSukumar Swaminathan 
464*82527734SSukumar Swaminathan 	if (rc == 0) {
465*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
466*82527734SSukumar Swaminathan 		    "CMPL add fcf: Cannot build read fcf mbox");
467*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mq);
468*82527734SSukumar Swaminathan 		return (0);
469*82527734SSukumar Swaminathan 	}
470*82527734SSukumar Swaminathan 
471*82527734SSukumar Swaminathan 	rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mq, MBX_NOWAIT, 0);
472*82527734SSukumar Swaminathan 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
473*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
474*82527734SSukumar Swaminathan 		    "CMPL add fcf: Cannot issue read fcf mbox");
475*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mq);
476*82527734SSukumar Swaminathan 	}
477*82527734SSukumar Swaminathan 	return (0);
478*82527734SSukumar Swaminathan } /* emlxs_cmpl_add_fcf_table() */
479*82527734SSukumar Swaminathan 
480*82527734SSukumar Swaminathan 
481*82527734SSukumar Swaminathan extern int
482*82527734SSukumar Swaminathan emlxs_mbext_add_fcf_table(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t index)
483*82527734SSukumar Swaminathan {
484*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
485*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
486*82527734SSukumar Swaminathan 	IOCTL_FCOE_ADD_FCF_TABLE *fcf;
487*82527734SSukumar Swaminathan 	FCF_RECORD_t *fcfrec;
488*82527734SSukumar Swaminathan 	MATCHMAP *mp;
489*82527734SSukumar Swaminathan 	mbox_req_hdr_t	*hdr_req;
490*82527734SSukumar Swaminathan 
491*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
492*82527734SSukumar Swaminathan 
493*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
494*82527734SSukumar Swaminathan 		return (0);
495*82527734SSukumar Swaminathan 	}
496*82527734SSukumar Swaminathan 	/*
497*82527734SSukumar Swaminathan 	 * Save address for completion
498*82527734SSukumar Swaminathan 	 * Signifies a non-embedded command
499*82527734SSukumar Swaminathan 	 */
500*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 0;
501*82527734SSukumar Swaminathan 	mbq->nonembed = (uint8_t *)mp;
502*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_add_fcf_table;
503*82527734SSukumar Swaminathan 
504*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
505*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
506*82527734SSukumar Swaminathan 
507*82527734SSukumar Swaminathan 	hdr_req = (mbox_req_hdr_t *)mp->virt;
508*82527734SSukumar Swaminathan 	hdr_req->subsystem = IOCTL_SUBSYSTEM_FCOE;
509*82527734SSukumar Swaminathan 	hdr_req->opcode = FCOE_OPCODE_ADD_FCF_TABLE;
510*82527734SSukumar Swaminathan 	hdr_req->timeout = 0;
511*82527734SSukumar Swaminathan 	hdr_req->req_length = sizeof (IOCTL_FCOE_ADD_FCF_TABLE);
512*82527734SSukumar Swaminathan 	fcf = (IOCTL_FCOE_ADD_FCF_TABLE *)(hdr_req + 1);
513*82527734SSukumar Swaminathan 	fcf->params.request.fcf_index = index;
514*82527734SSukumar Swaminathan 
515*82527734SSukumar Swaminathan 	fcfrec = &fcf->params.request.fcf_entry;
516*82527734SSukumar Swaminathan 	fcfrec->max_recv_size = EMLXS_FCOE_MAX_RCV_SZ;
517*82527734SSukumar Swaminathan 	fcfrec->fka_adv_period = 0;
518*82527734SSukumar Swaminathan 	fcfrec->fip_priority = 128;
519*82527734SSukumar Swaminathan #ifdef EMLXS_BIG_ENDIAN
520*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[0] = FCOE_FCF_MAC3;
521*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[1] = FCOE_FCF_MAC2;
522*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[2] = FCOE_FCF_MAC1;
523*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[3] = FCOE_FCF_MAC0;
524*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_low[0] = FCOE_FCF_MAC5;
525*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_low[1] = FCOE_FCF_MAC4;
526*82527734SSukumar Swaminathan 	fcfrec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[2];
527*82527734SSukumar Swaminathan 	fcfrec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
528*82527734SSukumar Swaminathan 	fcfrec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[0];
529*82527734SSukumar Swaminathan #endif
530*82527734SSukumar Swaminathan #ifdef EMLXS_LITTLE_ENDIAN
531*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[0] = FCOE_FCF_MAC0;
532*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[1] = FCOE_FCF_MAC1;
533*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[2] = FCOE_FCF_MAC2;
534*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_hi[3] = FCOE_FCF_MAC3;
535*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_low[0] = FCOE_FCF_MAC4;
536*82527734SSukumar Swaminathan 	fcfrec->fcf_mac_address_low[1] = FCOE_FCF_MAC5;
537*82527734SSukumar Swaminathan 	fcfrec->fc_map[0] = hba->sli.sli4.cfgFCOE.FCMap[0];
538*82527734SSukumar Swaminathan 	fcfrec->fc_map[1] = hba->sli.sli4.cfgFCOE.FCMap[1];
539*82527734SSukumar Swaminathan 	fcfrec->fc_map[2] = hba->sli.sli4.cfgFCOE.FCMap[2];
540*82527734SSukumar Swaminathan #endif
541*82527734SSukumar Swaminathan 
542*82527734SSukumar Swaminathan 	if (hba->sli.sli4.cfgFCOE.fip_flags & TLV_FCOE_VLAN) {
543*82527734SSukumar Swaminathan 		uint16_t i;
544*82527734SSukumar Swaminathan 		uint8_t bitmap[512];
545*82527734SSukumar Swaminathan 
546*82527734SSukumar Swaminathan 		bzero((void *) bitmap, 512);
547*82527734SSukumar Swaminathan 		i = hba->sli.sli4.cfgFCOE.VLanId;
548*82527734SSukumar Swaminathan 		bitmap[i / 8] = (1 << (i % 8));
549*82527734SSukumar Swaminathan 		BE_SWAP32_BCOPY(bitmap, fcfrec->vlan_bitmap, 512);
550*82527734SSukumar Swaminathan 	}
551*82527734SSukumar Swaminathan 
552*82527734SSukumar Swaminathan 	fcfrec->fcf_valid = 1;
553*82527734SSukumar Swaminathan 	fcfrec->fcf_available = 1;
554*82527734SSukumar Swaminathan 
555*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
556*82527734SSukumar Swaminathan 	    "ADD FCF %d: av: %x %x ste %x macp %x "
557*82527734SSukumar Swaminathan 	    "addr: %02x:%02x:%02x:%02x:%02x:%02x",
558*82527734SSukumar Swaminathan 	    fcfrec->fcf_index,
559*82527734SSukumar Swaminathan 	    fcfrec->fcf_available,
560*82527734SSukumar Swaminathan 	    fcfrec->fcf_valid,
561*82527734SSukumar Swaminathan 	    fcfrec->fcf_state,
562*82527734SSukumar Swaminathan 	    fcfrec->mac_address_provider,
563*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_hi[0],
564*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_hi[1],
565*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_hi[2],
566*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_hi[3],
567*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_low[0],
568*82527734SSukumar Swaminathan 	    fcfrec->fcf_mac_address_low[1]);
569*82527734SSukumar Swaminathan 	return (1);
570*82527734SSukumar Swaminathan 
571*82527734SSukumar Swaminathan } /* emlxs_mbext_add_fcf_table() */
572*82527734SSukumar Swaminathan 
573*82527734SSukumar Swaminathan 
574*82527734SSukumar Swaminathan /*ARGSUSED*/
575*82527734SSukumar Swaminathan extern void
576*82527734SSukumar Swaminathan emlxs_mb_eq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
577*82527734SSukumar Swaminathan {
578*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
579*82527734SSukumar Swaminathan 	IOCTL_COMMON_EQ_CREATE *qp;
580*82527734SSukumar Swaminathan 	uint64_t	addr;
581*82527734SSukumar Swaminathan 
582*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
583*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
584*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
585*82527734SSukumar Swaminathan 
586*82527734SSukumar Swaminathan 	/*
587*82527734SSukumar Swaminathan 	 * Signifies an embedded command
588*82527734SSukumar Swaminathan 	 */
589*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
590*82527734SSukumar Swaminathan 
591*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
592*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
593*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length =
594*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_EQ_CREATE) + IOCTL_HEADER_SZ;
595*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
596*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
597*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_EQ_CREATE;
598*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
599*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
600*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_EQ_CREATE);
601*82527734SSukumar Swaminathan 	qp = (IOCTL_COMMON_EQ_CREATE *)&mb->un.varSLIConfig.payload;
602*82527734SSukumar Swaminathan 
603*82527734SSukumar Swaminathan 	/* 1024 * 4 bytes = 4K */
604*82527734SSukumar Swaminathan 	qp->params.request.EQContext.Count = EQ_ELEMENT_COUNT_1024;
605*82527734SSukumar Swaminathan 	qp->params.request.EQContext.Valid = 1;
606*82527734SSukumar Swaminathan 	qp->params.request.EQContext.NoDelay = 0;
607*82527734SSukumar Swaminathan 	qp->params.request.EQContext.DelayMult = EQ_DELAY_MULT;
608*82527734SSukumar Swaminathan 
609*82527734SSukumar Swaminathan 	addr = hba->sli.sli4.eq[num].addr.phys;
610*82527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
611*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
612*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
613*82527734SSukumar Swaminathan 
614*82527734SSukumar Swaminathan 	return;
615*82527734SSukumar Swaminathan 
616*82527734SSukumar Swaminathan } /* emlxs_mb_eq_create() */
617*82527734SSukumar Swaminathan 
618*82527734SSukumar Swaminathan 
619*82527734SSukumar Swaminathan /*ARGSUSED*/
620*82527734SSukumar Swaminathan extern void
621*82527734SSukumar Swaminathan emlxs_mb_cq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
622*82527734SSukumar Swaminathan {
623*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
624*82527734SSukumar Swaminathan 	IOCTL_COMMON_CQ_CREATE *qp;
625*82527734SSukumar Swaminathan 	uint64_t	addr;
626*82527734SSukumar Swaminathan 
627*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
628*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
629*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
630*82527734SSukumar Swaminathan 
631*82527734SSukumar Swaminathan 	/*
632*82527734SSukumar Swaminathan 	 * Signifies an embedded command
633*82527734SSukumar Swaminathan 	 */
634*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
635*82527734SSukumar Swaminathan 
636*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
637*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
638*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length =
639*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_CQ_CREATE) + IOCTL_HEADER_SZ;
640*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
641*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
642*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_CQ_CREATE;
643*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
644*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
645*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_CQ_CREATE);
646*82527734SSukumar Swaminathan 	qp = (IOCTL_COMMON_CQ_CREATE *)&mb->un.varSLIConfig.payload;
647*82527734SSukumar Swaminathan 
648*82527734SSukumar Swaminathan 	/* 256 * 16 bytes = 4K */
649*82527734SSukumar Swaminathan 	qp->params.request.CQContext.Count = CQ_ELEMENT_COUNT_256;
650*82527734SSukumar Swaminathan 	qp->params.request.CQContext.EQId = hba->sli.sli4.cq[num].eqid;
651*82527734SSukumar Swaminathan 	qp->params.request.CQContext.Valid = 1;
652*82527734SSukumar Swaminathan 	qp->params.request.CQContext.Eventable = 1;
653*82527734SSukumar Swaminathan 	qp->params.request.CQContext.NoDelay = 0;
654*82527734SSukumar Swaminathan 
655*82527734SSukumar Swaminathan 	addr = hba->sli.sli4.cq[num].addr.phys;
656*82527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
657*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
658*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
659*82527734SSukumar Swaminathan 
660*82527734SSukumar Swaminathan 	return;
661*82527734SSukumar Swaminathan 
662*82527734SSukumar Swaminathan } /* emlxs_mb_cq_create() */
663*82527734SSukumar Swaminathan 
664*82527734SSukumar Swaminathan 
665*82527734SSukumar Swaminathan /*ARGSUSED*/
666*82527734SSukumar Swaminathan extern void
667*82527734SSukumar Swaminathan emlxs_mb_wq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
668*82527734SSukumar Swaminathan {
669*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
670*82527734SSukumar Swaminathan 	IOCTL_FCOE_WQ_CREATE *qp;
671*82527734SSukumar Swaminathan 	uint64_t addr;
672*82527734SSukumar Swaminathan 	int i;
673*82527734SSukumar Swaminathan 
674*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
675*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
676*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
677*82527734SSukumar Swaminathan 
678*82527734SSukumar Swaminathan 	/*
679*82527734SSukumar Swaminathan 	 * Signifies an embedded command
680*82527734SSukumar Swaminathan 	 */
681*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
682*82527734SSukumar Swaminathan 
683*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
684*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
685*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length =
686*82527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_WQ_CREATE) + IOCTL_HEADER_SZ;
687*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
688*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_FCOE;
689*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = FCOE_OPCODE_WQ_CREATE;
690*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
691*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
692*82527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_WQ_CREATE);
693*82527734SSukumar Swaminathan 
694*82527734SSukumar Swaminathan 	addr = hba->sli.sli4.wq[num].addr.phys;
695*82527734SSukumar Swaminathan 	qp = (IOCTL_FCOE_WQ_CREATE *)&mb->un.varSLIConfig.payload;
696*82527734SSukumar Swaminathan 
697*82527734SSukumar Swaminathan 	qp->params.request.CQId = hba->sli.sli4.wq[num].cqid;
698*82527734SSukumar Swaminathan 
699*82527734SSukumar Swaminathan 	qp->params.request.NumPages = EMLXS_NUM_WQ_PAGES;
700*82527734SSukumar Swaminathan 	for (i = 0; i < EMLXS_NUM_WQ_PAGES; i++) {
701*82527734SSukumar Swaminathan 		qp->params.request.Pages[i].addrLow = PADDR_LO(addr);
702*82527734SSukumar Swaminathan 		qp->params.request.Pages[i].addrHigh = PADDR_HI(addr);
703*82527734SSukumar Swaminathan 		addr += 4096;
704*82527734SSukumar Swaminathan 	}
705*82527734SSukumar Swaminathan 
706*82527734SSukumar Swaminathan 	return;
707*82527734SSukumar Swaminathan 
708*82527734SSukumar Swaminathan } /* emlxs_mb_wq_create() */
709*82527734SSukumar Swaminathan 
710*82527734SSukumar Swaminathan 
711*82527734SSukumar Swaminathan /*ARGSUSED*/
712*82527734SSukumar Swaminathan extern void
713*82527734SSukumar Swaminathan emlxs_mb_rq_create(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t num)
714*82527734SSukumar Swaminathan {
715*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
716*82527734SSukumar Swaminathan 	IOCTL_FCOE_RQ_CREATE *qp;
717*82527734SSukumar Swaminathan 	uint64_t	addr;
718*82527734SSukumar Swaminathan 
719*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
720*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
721*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
722*82527734SSukumar Swaminathan 
723*82527734SSukumar Swaminathan 	/*
724*82527734SSukumar Swaminathan 	 * Signifies an embedded command
725*82527734SSukumar Swaminathan 	 */
726*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
727*82527734SSukumar Swaminathan 
728*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
729*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
730*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length =
731*82527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_RQ_CREATE) + IOCTL_HEADER_SZ;
732*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
733*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_FCOE;
734*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = FCOE_OPCODE_RQ_CREATE;
735*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
736*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
737*82527734SSukumar Swaminathan 	    sizeof (IOCTL_FCOE_RQ_CREATE);
738*82527734SSukumar Swaminathan 	addr = hba->sli.sli4.rq[num].addr.phys;
739*82527734SSukumar Swaminathan 
740*82527734SSukumar Swaminathan 	qp = (IOCTL_FCOE_RQ_CREATE *)&mb->un.varSLIConfig.payload;
741*82527734SSukumar Swaminathan 
742*82527734SSukumar Swaminathan 	qp->params.request.RQContext.RQSize	= RQ_DEPTH_EXPONENT;
743*82527734SSukumar Swaminathan 	qp->params.request.RQContext.BufferSize	= RQB_DATA_SIZE;
744*82527734SSukumar Swaminathan 	qp->params.request.RQContext.CQIdRecv	= hba->sli.sli4.rq[num].cqid;
745*82527734SSukumar Swaminathan 
746*82527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
747*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
748*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
749*82527734SSukumar Swaminathan 
750*82527734SSukumar Swaminathan 	return;
751*82527734SSukumar Swaminathan 
752*82527734SSukumar Swaminathan } /* emlxs_mb_rq_create() */
753*82527734SSukumar Swaminathan 
754*82527734SSukumar Swaminathan 
755*82527734SSukumar Swaminathan /*ARGSUSED*/
756*82527734SSukumar Swaminathan extern void
757*82527734SSukumar Swaminathan emlxs_mb_mq_create(emlxs_hba_t *hba, MAILBOXQ *mbq)
758*82527734SSukumar Swaminathan {
759*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
760*82527734SSukumar Swaminathan 	IOCTL_COMMON_MQ_CREATE *qp;
761*82527734SSukumar Swaminathan 	uint64_t	addr;
762*82527734SSukumar Swaminathan 
763*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
764*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
765*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
766*82527734SSukumar Swaminathan 
767*82527734SSukumar Swaminathan 	/*
768*82527734SSukumar Swaminathan 	 * Signifies an embedded command
769*82527734SSukumar Swaminathan 	 */
770*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.embedded = 1;
771*82527734SSukumar Swaminathan 
772*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_SLI_CONFIG;
773*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
774*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.payload_length =
775*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_MQ_CREATE) + IOCTL_HEADER_SZ;
776*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.subsystem =
777*82527734SSukumar Swaminathan 	    IOCTL_SUBSYSTEM_COMMON;
778*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.opcode = COMMON_OPCODE_MQ_CREATE;
779*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.timeout = 0;
780*82527734SSukumar Swaminathan 	mb->un.varSLIConfig.be.un_hdr.hdr_req.req_length =
781*82527734SSukumar Swaminathan 	    sizeof (IOCTL_COMMON_MQ_CREATE);
782*82527734SSukumar Swaminathan 
783*82527734SSukumar Swaminathan 	addr = hba->sli.sli4.mq.addr.phys;
784*82527734SSukumar Swaminathan 	qp = (IOCTL_COMMON_MQ_CREATE *)&mb->un.varSLIConfig.payload;
785*82527734SSukumar Swaminathan 
786*82527734SSukumar Swaminathan 	qp->params.request.MQContext.Size = MQ_ELEMENT_COUNT_16;
787*82527734SSukumar Swaminathan 	qp->params.request.MQContext.Valid = 1;
788*82527734SSukumar Swaminathan 	qp->params.request.MQContext.CQId = hba->sli.sli4.mq.cqid;
789*82527734SSukumar Swaminathan 
790*82527734SSukumar Swaminathan 	qp->params.request.NumPages = 1;
791*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrLow = PADDR_LO(addr);
792*82527734SSukumar Swaminathan 	qp->params.request.Pages[0].addrHigh = PADDR_HI(addr);
793*82527734SSukumar Swaminathan 
794*82527734SSukumar Swaminathan 	return;
795*82527734SSukumar Swaminathan 
796*82527734SSukumar Swaminathan } /* emlxs_mb_mq_create() */
797*82527734SSukumar Swaminathan 
798*82527734SSukumar Swaminathan 
799*82527734SSukumar Swaminathan static int
800*82527734SSukumar Swaminathan emlxs_cmpl_reg_fcfi(void *arg1, MAILBOXQ *mbq)
801*82527734SSukumar Swaminathan {
802*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
803*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
804*82527734SSukumar Swaminathan 	FCFIobj_t *fcfp;
805*82527734SSukumar Swaminathan 	VFIobj_t *vfip;
806*82527734SSukumar Swaminathan 	RPIobj_t *rpip;
807*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
808*82527734SSukumar Swaminathan 
809*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
810*82527734SSukumar Swaminathan 	fcfp = (FCFIobj_t *)mbq->context;
811*82527734SSukumar Swaminathan 
812*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
813*82527734SSukumar Swaminathan 	    "CMPL reg fcfi: status: %x", mb->mbxStatus);
814*82527734SSukumar Swaminathan 
815*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
816*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
817*82527734SSukumar Swaminathan 		    "Unable to register FCFI for FCFI %d index %d",
818*82527734SSukumar Swaminathan 		    mb->un.varRegFCFI.FCFI, mb->un.varRegFCFI.InfoIndex);
819*82527734SSukumar Swaminathan 		(void) emlxs_sli4_free_fcfi(hba, fcfp);
820*82527734SSukumar Swaminathan 		return (0);
821*82527734SSukumar Swaminathan 	}
822*82527734SSukumar Swaminathan 
823*82527734SSukumar Swaminathan 	fcfp->state |= RESOURCE_FCFI_REG;
824*82527734SSukumar Swaminathan 
825*82527734SSukumar Swaminathan 	if (!fcfp->fcf_vfi) {
826*82527734SSukumar Swaminathan 		vfip = emlxs_sli4_alloc_vfi(hba, fcfp);
827*82527734SSukumar Swaminathan 		if (!vfip) {
828*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
829*82527734SSukumar Swaminathan 			    "Unable to alloc VFI for Fabric, fcf index %d",
830*82527734SSukumar Swaminathan 			    fcfp->FCF_index);
831*82527734SSukumar Swaminathan 			(void) emlxs_sli4_free_fcfi(hba, fcfp);
832*82527734SSukumar Swaminathan 			return (0);
833*82527734SSukumar Swaminathan 		}
834*82527734SSukumar Swaminathan 		fcfp->fcf_vfi = vfip;
835*82527734SSukumar Swaminathan 	}
836*82527734SSukumar Swaminathan 
837*82527734SSukumar Swaminathan 	if (!fcfp->fcf_vpi) {
838*82527734SSukumar Swaminathan 		fcfp->fcf_vpi = port;
839*82527734SSukumar Swaminathan 		port->VFIp = fcfp->fcf_vfi;
840*82527734SSukumar Swaminathan 		port->VFIp->outstandingVPIs++;
841*82527734SSukumar Swaminathan 	}
842*82527734SSukumar Swaminathan 
843*82527734SSukumar Swaminathan 	rpip = &fcfp->scratch_rpi;
844*82527734SSukumar Swaminathan 	rpip->state = RESOURCE_ALLOCATED;
845*82527734SSukumar Swaminathan 	rpip->VPIp = fcfp->fcf_vpi;
846*82527734SSukumar Swaminathan 	rpip->RPI = 0xffff;
847*82527734SSukumar Swaminathan 	rpip->index = 0xffff;
848*82527734SSukumar Swaminathan 
849*82527734SSukumar Swaminathan 	fcfp->FCFI = mb->un.varRegFCFI.FCFI;
850*82527734SSukumar Swaminathan 
851*82527734SSukumar Swaminathan 	/* Declare the linkup here */
852*82527734SSukumar Swaminathan 	if (!(fcfp->state & RESOURCE_FCFI_DISC)) {
853*82527734SSukumar Swaminathan 		fcfp->state |= RESOURCE_FCFI_DISC;
854*82527734SSukumar Swaminathan 		emlxs_linkup(hba);
855*82527734SSukumar Swaminathan 	}
856*82527734SSukumar Swaminathan 	return (0);
857*82527734SSukumar Swaminathan 
858*82527734SSukumar Swaminathan } /* emlxs_cmpl_reg_fcfi() */
859*82527734SSukumar Swaminathan 
860*82527734SSukumar Swaminathan 
861*82527734SSukumar Swaminathan /*ARGSUSED*/
862*82527734SSukumar Swaminathan extern void
863*82527734SSukumar Swaminathan emlxs_mb_reg_fcfi(emlxs_hba_t *hba, MAILBOXQ *mbq, FCFIobj_t *fcfp)
864*82527734SSukumar Swaminathan {
865*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
866*82527734SSukumar Swaminathan 
867*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
868*82527734SSukumar Swaminathan 
869*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_REG_FCFI;
870*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
871*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.FCFI = 0; /* FCFI will be returned by firmware */
872*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.InfoIndex = fcfp->FCF_index;
873*82527734SSukumar Swaminathan 
874*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.RQId0 = hba->sli.sli4.rq[EMLXS_FCFI_RQ0_INDEX].qid;
875*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.Id0_rctl_mask = EMLXS_FCFI_RQ0_RMASK;
876*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.Id0_rctl = EMLXS_FCFI_RQ0_RCTL;
877*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.Id0_type_mask = EMLXS_FCFI_RQ0_TMASK;
878*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.Id0_type = EMLXS_FCFI_RQ0_TYPE;
879*82527734SSukumar Swaminathan 
880*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.RQId1 = 0xffff;
881*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.RQId2 = 0xffff;
882*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.RQId3 = 0xffff;
883*82527734SSukumar Swaminathan 
884*82527734SSukumar Swaminathan 	if (fcfp->state & RESOURCE_FCFI_VLAN_ID) {
885*82527734SSukumar Swaminathan 		mb->un.varRegFCFI.vv = 1;
886*82527734SSukumar Swaminathan 		mb->un.varRegFCFI.vlanTag = fcfp->vlan_id;
887*82527734SSukumar Swaminathan 	}
888*82527734SSukumar Swaminathan 
889*82527734SSukumar Swaminathan 	/* Ignore the fcf record and force FPMA */
890*82527734SSukumar Swaminathan 	mb->un.varRegFCFI.mam = EMLXS_REG_FCFI_MAM_FPMA;
891*82527734SSukumar Swaminathan 
892*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_reg_fcfi;
893*82527734SSukumar Swaminathan 	mbq->context = (uint8_t *)fcfp;
894*82527734SSukumar Swaminathan 	return;
895*82527734SSukumar Swaminathan 
896*82527734SSukumar Swaminathan } /* emlxs_mb_reg_fcfi() */
897*82527734SSukumar Swaminathan 
898*82527734SSukumar Swaminathan 
899*82527734SSukumar Swaminathan /* SLI4 */
900*82527734SSukumar Swaminathan static int
901*82527734SSukumar Swaminathan emlxs_cmpl_unreg_fcfi(void *arg1, MAILBOXQ *mbq)
902*82527734SSukumar Swaminathan {
903*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
904*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
905*82527734SSukumar Swaminathan 	FCFIobj_t *fcfp;
906*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
907*82527734SSukumar Swaminathan 
908*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
909*82527734SSukumar Swaminathan 	fcfp = (FCFIobj_t *)mbq->context;
910*82527734SSukumar Swaminathan 
911*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
912*82527734SSukumar Swaminathan 	    "CMPL unreg fcfi: status: %x", mb->mbxStatus);
913*82527734SSukumar Swaminathan 
914*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
915*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
916*82527734SSukumar Swaminathan 		    "Unable to unregister FCFI %d index %d",
917*82527734SSukumar Swaminathan 		    fcfp->FCFI, fcfp->FCF_index);
918*82527734SSukumar Swaminathan 	}
919*82527734SSukumar Swaminathan 
920*82527734SSukumar Swaminathan 	(void) emlxs_sli4_free_fcfi(hba, fcfp);
921*82527734SSukumar Swaminathan 
922*82527734SSukumar Swaminathan 	/* Make sure link is declared down */
923*82527734SSukumar Swaminathan 	emlxs_linkdown(hba);
924*82527734SSukumar Swaminathan 
925*82527734SSukumar Swaminathan 	return (0);
926*82527734SSukumar Swaminathan 
927*82527734SSukumar Swaminathan } /* emlxs_cmpl_unreg_fcfi() */
928*82527734SSukumar Swaminathan 
929*82527734SSukumar Swaminathan 
930*82527734SSukumar Swaminathan /* ARGSUSED */
931*82527734SSukumar Swaminathan extern int
932*82527734SSukumar Swaminathan emlxs_mb_unreg_fcfi(emlxs_hba_t *hba, FCFIobj_t *fcfp)
933*82527734SSukumar Swaminathan {
934*82527734SSukumar Swaminathan 	MAILBOXQ *mbq;
935*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
936*82527734SSukumar Swaminathan 	uint32_t rval;
937*82527734SSukumar Swaminathan 
938*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
939*82527734SSukumar Swaminathan 
940*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
941*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
942*82527734SSukumar Swaminathan 		return (1);
943*82527734SSukumar Swaminathan 	}
944*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
945*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
946*82527734SSukumar Swaminathan 
947*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
948*82527734SSukumar Swaminathan 
949*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_UNREG_FCFI;
950*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
951*82527734SSukumar Swaminathan 	mb->un.varUnRegFCFI.FCFI = fcfp->FCFI;
952*82527734SSukumar Swaminathan 
953*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_unreg_fcfi;
954*82527734SSukumar Swaminathan 	mbq->context = (uint8_t *)fcfp;
955*82527734SSukumar Swaminathan 	fcfp->fcf_vfi = NULL;
956*82527734SSukumar Swaminathan 	fcfp->fcf_vpi = NULL;
957*82527734SSukumar Swaminathan 
958*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
959*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
960*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
961*82527734SSukumar Swaminathan 	}
962*82527734SSukumar Swaminathan 
963*82527734SSukumar Swaminathan 	return (0);
964*82527734SSukumar Swaminathan 
965*82527734SSukumar Swaminathan } /* emlxs_mb_unreg_fcfi() */
966*82527734SSukumar Swaminathan 
967*82527734SSukumar Swaminathan 
968*82527734SSukumar Swaminathan int
969*82527734SSukumar Swaminathan emlxs_mb_cmpl_reg_vfi(void *arg1, MAILBOXQ *mbq)
970*82527734SSukumar Swaminathan {
971*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
972*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
973*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
974*82527734SSukumar Swaminathan 	MAILBOXQ *mbox;
975*82527734SSukumar Swaminathan 	MATCHMAP *mp;
976*82527734SSukumar Swaminathan 	NODELIST *ndlp;
977*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
978*82527734SSukumar Swaminathan 	VFIobj_t *vfip;
979*82527734SSukumar Swaminathan 	uint8_t *wwn;
980*82527734SSukumar Swaminathan 	volatile SERV_PARM *sp;
981*82527734SSukumar Swaminathan 	int32_t i;
982*82527734SSukumar Swaminathan 	uint32_t ldid;
983*82527734SSukumar Swaminathan 	emlxs_vvl_fmt_t vvl;
984*82527734SSukumar Swaminathan 
985*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
986*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
987*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT,
988*82527734SSukumar Swaminathan 		    &emlxs_sli_detail_msg,
989*82527734SSukumar Swaminathan 		    "REG_VFI failed. status=x%x", mb->mbxStatus);
990*82527734SSukumar Swaminathan 		return (0);
991*82527734SSukumar Swaminathan 	}
992*82527734SSukumar Swaminathan 
993*82527734SSukumar Swaminathan 	vport = (emlxs_port_t *)mbq->context;
994*82527734SSukumar Swaminathan 	vfip = vport->VFIp;
995*82527734SSukumar Swaminathan 	vfip->state |= RESOURCE_VFI_REG;
996*82527734SSukumar Swaminathan 
997*82527734SSukumar Swaminathan 	if (mb->un.varRegVFI4.vp) {
998*82527734SSukumar Swaminathan 		vport->flag |= EMLXS_PORT_REGISTERED;
999*82527734SSukumar Swaminathan 	}
1000*82527734SSukumar Swaminathan 
1001*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
1002*82527734SSukumar Swaminathan 	if (!mp) {
1003*82527734SSukumar Swaminathan 		return (0);
1004*82527734SSukumar Swaminathan 	}
1005*82527734SSukumar Swaminathan 	sp = (volatile SERV_PARM *)mp->virt;
1006*82527734SSukumar Swaminathan 
1007*82527734SSukumar Swaminathan 	ldid = FABRIC_DID;
1008*82527734SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, ldid);
1009*82527734SSukumar Swaminathan 
1010*82527734SSukumar Swaminathan 	if (!ndlp) {
1011*82527734SSukumar Swaminathan 		/* Attempt to create a node */
1012*82527734SSukumar Swaminathan 		if ((ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP, 0))) {
1013*82527734SSukumar Swaminathan 			ndlp->nlp_Rpi = 0xffff;
1014*82527734SSukumar Swaminathan 			ndlp->nlp_DID = ldid;
1015*82527734SSukumar Swaminathan 
1016*82527734SSukumar Swaminathan 			bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
1017*82527734SSukumar Swaminathan 			    sizeof (SERV_PARM));
1018*82527734SSukumar Swaminathan 
1019*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->nodeName,
1020*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_nodename,
1021*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
1022*82527734SSukumar Swaminathan 
1023*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->portName,
1024*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_portname,
1025*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
1026*82527734SSukumar Swaminathan 
1027*82527734SSukumar Swaminathan 			ndlp->nlp_active = 1;
1028*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ct]  |= NLP_CLOSED;
1029*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_els] |= NLP_CLOSED;
1030*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_fcp] |= NLP_CLOSED;
1031*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ip]  |= NLP_CLOSED;
1032*82527734SSukumar Swaminathan 
1033*82527734SSukumar Swaminathan 			/* Add the node */
1034*82527734SSukumar Swaminathan 			emlxs_node_add(port, ndlp);
1035*82527734SSukumar Swaminathan 
1036*82527734SSukumar Swaminathan 			/* Open the node */
1037*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ct);
1038*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_els);
1039*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
1040*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
1041*82527734SSukumar Swaminathan 		} else {
1042*82527734SSukumar Swaminathan 			wwn = (uint8_t *)&sp->portName;
1043*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
1044*82527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
1045*82527734SSukumar Swaminathan 			    "Unable to allocate node. did=%06x "
1046*82527734SSukumar Swaminathan 			    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
1047*82527734SSukumar Swaminathan 			    ldid, wwn[0], wwn[1], wwn[2],
1048*82527734SSukumar Swaminathan 			    wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
1049*82527734SSukumar Swaminathan 
1050*82527734SSukumar Swaminathan 			return (0);
1051*82527734SSukumar Swaminathan 		}
1052*82527734SSukumar Swaminathan 	} else {
1053*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
1054*82527734SSukumar Swaminathan 
1055*82527734SSukumar Swaminathan 		ndlp->nlp_Rpi = 0xffff;
1056*82527734SSukumar Swaminathan 		ndlp->nlp_DID = ldid;
1057*82527734SSukumar Swaminathan 
1058*82527734SSukumar Swaminathan 		bcopy((uint8_t *)sp,
1059*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->sparm, sizeof (SERV_PARM));
1060*82527734SSukumar Swaminathan 
1061*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->nodeName,
1062*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_nodename, sizeof (NAME_TYPE));
1063*82527734SSukumar Swaminathan 
1064*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->portName,
1065*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_portname, sizeof (NAME_TYPE));
1066*82527734SSukumar Swaminathan 
1067*82527734SSukumar Swaminathan 		wwn = (uint8_t *)&ndlp->nlp_portname;
1068*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
1069*82527734SSukumar Swaminathan 		    "node=%p did=%06x rpi=%x "
1070*82527734SSukumar Swaminathan 		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
1071*82527734SSukumar Swaminathan 		    ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
1072*82527734SSukumar Swaminathan 		    wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
1073*82527734SSukumar Swaminathan 
1074*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
1075*82527734SSukumar Swaminathan 
1076*82527734SSukumar Swaminathan 		/* Open the node */
1077*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ct);
1078*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_els);
1079*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
1080*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
1081*82527734SSukumar Swaminathan 	}
1082*82527734SSukumar Swaminathan 
1083*82527734SSukumar Swaminathan 	bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t));
1084*82527734SSukumar Swaminathan 
1085*82527734SSukumar Swaminathan 	if (sp->VALID_VENDOR_VERSION) {
1086*82527734SSukumar Swaminathan 
1087*82527734SSukumar Swaminathan 		bcopy((caddr_t *)&sp->vendorVersion[0],
1088*82527734SSukumar Swaminathan 		    (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
1089*82527734SSukumar Swaminathan 
1090*82527734SSukumar Swaminathan 		vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
1091*82527734SSukumar Swaminathan 		vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
1092*82527734SSukumar Swaminathan 
1093*82527734SSukumar Swaminathan 		if ((vvl.un0.w0.oui == 0x0000C9) &&
1094*82527734SSukumar Swaminathan 		    (vvl.un1.w1.vport)) {
1095*82527734SSukumar Swaminathan 			ndlp->nlp_fcp_info |= NLP_EMLX_VPORT;
1096*82527734SSukumar Swaminathan 		}
1097*82527734SSukumar Swaminathan 	}
1098*82527734SSukumar Swaminathan 
1099*82527734SSukumar Swaminathan 	if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
1100*82527734SSukumar Swaminathan 		/* If link not already down then */
1101*82527734SSukumar Swaminathan 		/* declare it down now */
1102*82527734SSukumar Swaminathan 		if (emlxs_mb_read_sparam(hba, mbox) == 0) {
1103*82527734SSukumar Swaminathan 			emlxs_mb_put(hba, mbox);
1104*82527734SSukumar Swaminathan 		} else {
1105*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_MBOX,
1106*82527734SSukumar Swaminathan 			    (uint8_t *)mbox);
1107*82527734SSukumar Swaminathan 		}
1108*82527734SSukumar Swaminathan 	}
1109*82527734SSukumar Swaminathan 
1110*82527734SSukumar Swaminathan 	/* Since this is a fabric login */
1111*82527734SSukumar Swaminathan 	/*
1112*82527734SSukumar Swaminathan 	 * If NPIV Fabric support has just been established on
1113*82527734SSukumar Swaminathan 	 * the physical port, then notify the vports of the
1114*82527734SSukumar Swaminathan 	 * link up
1115*82527734SSukumar Swaminathan 	 */
1116*82527734SSukumar Swaminathan 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
1117*82527734SSukumar Swaminathan 	if ((hba->flag & FC_NPIV_ENABLED) &&
1118*82527734SSukumar Swaminathan 	    (hba->flag & FC_NPIV_SUPPORTED)) {
1119*82527734SSukumar Swaminathan 		/* Skip the physical port */
1120*82527734SSukumar Swaminathan 		for (i = 1; i < MAX_VPORTS; i++) {
1121*82527734SSukumar Swaminathan 			vport = &VPORT(i);
1122*82527734SSukumar Swaminathan 
1123*82527734SSukumar Swaminathan 			if (!(vport->flag & EMLXS_PORT_BOUND) ||
1124*82527734SSukumar Swaminathan 			    !(vport->flag & EMLXS_PORT_ENABLE)) {
1125*82527734SSukumar Swaminathan 				continue;
1126*82527734SSukumar Swaminathan 			}
1127*82527734SSukumar Swaminathan 
1128*82527734SSukumar Swaminathan 			emlxs_port_online(vport);
1129*82527734SSukumar Swaminathan 		}
1130*82527734SSukumar Swaminathan 	}
1131*82527734SSukumar Swaminathan 
1132*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
1133*82527734SSukumar Swaminathan 	if (mbq->sbp && ((emlxs_buf_t *)mbq->sbp)->fct_cmd) {
1134*82527734SSukumar Swaminathan 		emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)mbq->sbp;
1135fcf3ce44SJohn Forte 
1136*82527734SSukumar Swaminathan 		if (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) {
1137*82527734SSukumar Swaminathan 			mbq->sbp = NULL;
1138fcf3ce44SJohn Forte 
1139*82527734SSukumar Swaminathan 			mutex_enter(&EMLXS_PKT_LOCK);
1140*82527734SSukumar Swaminathan 			cmd_sbp->node = ndlp;
1141*82527734SSukumar Swaminathan 			cv_broadcast(&EMLXS_PKT_CV);
1142*82527734SSukumar Swaminathan 			mutex_exit(&EMLXS_PKT_LOCK);
1143*82527734SSukumar Swaminathan 		}
1144*82527734SSukumar Swaminathan 	}
1145*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
1146*82527734SSukumar Swaminathan 	return (0);
1147fcf3ce44SJohn Forte 
1148*82527734SSukumar Swaminathan } /* emlxs_mb_cmpl_reg_vfi */
1149*82527734SSukumar Swaminathan 
1150*82527734SSukumar Swaminathan 
1151*82527734SSukumar Swaminathan /*ARGSUSED*/
1152*82527734SSukumar Swaminathan extern int
1153*82527734SSukumar Swaminathan emlxs_mb_reg_vfi(emlxs_hba_t *hba, MAILBOXQ *mbq, VFIobj_t *vfip,
1154*82527734SSukumar Swaminathan     emlxs_port_t *port)
1155*82527734SSukumar Swaminathan {
1156*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
1157*82527734SSukumar Swaminathan 	FCFIobj_t *fcfp;
1158*82527734SSukumar Swaminathan 	MATCHMAP *mp;
1159*82527734SSukumar Swaminathan 
1160*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1161*82527734SSukumar Swaminathan 
1162*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
1163*82527734SSukumar Swaminathan 		return (0);
1164*82527734SSukumar Swaminathan 	}
1165*82527734SSukumar Swaminathan 
1166*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_REG_VFI;
1167*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1168*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.vfi = vfip->VFI;
1169*82527734SSukumar Swaminathan 	if (!(port->flag & EMLXS_PORT_REGISTERED)) {
1170*82527734SSukumar Swaminathan 		mb->un.varRegVFI4.vp = 1;
1171*82527734SSukumar Swaminathan 		mb->un.varRegVFI4.vpi = port->vpi + hba->vpi_base;
1172*82527734SSukumar Swaminathan 	}
1173*82527734SSukumar Swaminathan 	fcfp = vfip->FCFIp;
1174*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.fcfi = fcfp->FCFI;
1175*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.sid = port->did;
1176*82527734SSukumar Swaminathan 
1177*82527734SSukumar Swaminathan 	/* in ms */
1178*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.edtov = fcfp->fcf_sparam.cmn.e_d_tov;
1179*82527734SSukumar Swaminathan 
1180*82527734SSukumar Swaminathan 	/* Convert to seconds */
1181*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.ratov = (fcfp->fcf_sparam.cmn.w2.r_a_tov +
1182*82527734SSukumar Swaminathan 	    999) / 1000;
1183*82527734SSukumar Swaminathan 
1184*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.bde.tus.f.bdeSize = sizeof (SERV_PARM);
1185*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.bde.addrHigh = PADDR_HI(mp->phys);
1186*82527734SSukumar Swaminathan 	mb->un.varRegVFI4.bde.addrLow = PADDR_LO(mp->phys);
1187*82527734SSukumar Swaminathan 	bcopy((uint32_t *)&fcfp->fcf_sparam,
1188*82527734SSukumar Swaminathan 	    (uint32_t *)mp->virt, sizeof (SERV_PARM));
1189*82527734SSukumar Swaminathan 
1190*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_mb_cmpl_reg_vfi;
1191*82527734SSukumar Swaminathan 
1192*82527734SSukumar Swaminathan 	/*
1193*82527734SSukumar Swaminathan 	 * save address for completion
1194*82527734SSukumar Swaminathan 	 */
1195*82527734SSukumar Swaminathan 	mbq->bp = (uint8_t *)mp;
1196*82527734SSukumar Swaminathan 	mbq->context = (uint8_t *)port;
1197*82527734SSukumar Swaminathan 	return (1);
1198*82527734SSukumar Swaminathan 
1199*82527734SSukumar Swaminathan } /* emlxs_mb_reg_vfi() */
1200*82527734SSukumar Swaminathan 
1201*82527734SSukumar Swaminathan 
1202*82527734SSukumar Swaminathan /*ARGSUSED*/
1203*82527734SSukumar Swaminathan extern int
1204*82527734SSukumar Swaminathan emlxs_mb_unreg_vfi(emlxs_hba_t *hba, VFIobj_t *vfip)
1205*82527734SSukumar Swaminathan {
1206*82527734SSukumar Swaminathan 	FCFIobj_t *fcfp;
1207*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
1208*82527734SSukumar Swaminathan 	MAILBOXQ *mbq;
1209*82527734SSukumar Swaminathan 	uint32_t rval;
1210*82527734SSukumar Swaminathan 
1211*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
1212*82527734SSukumar Swaminathan 	if (!(vfip->state & RESOURCE_VFI_REG)) {
1213*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
1214*82527734SSukumar Swaminathan 		return (1);
1215*82527734SSukumar Swaminathan 
1216*82527734SSukumar Swaminathan 	}
1217*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
1218*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
1219*82527734SSukumar Swaminathan 		return (1);
1220*82527734SSukumar Swaminathan 	}
1221*82527734SSukumar Swaminathan 
1222*82527734SSukumar Swaminathan 	vfip->state &= ~RESOURCE_VFI_REG;
1223*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
1224*82527734SSukumar Swaminathan 
1225*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq->mbox;
1226*82527734SSukumar Swaminathan 
1227*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1228*82527734SSukumar Swaminathan 
1229*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_UNREG_VFI;
1230*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1231*82527734SSukumar Swaminathan 
1232*82527734SSukumar Swaminathan 	mb->un.varUnRegVFI4.vfi = vfip->VFI;
1233*82527734SSukumar Swaminathan 
1234*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
1235*82527734SSukumar Swaminathan 
1236*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
1237*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
1238*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
1239*82527734SSukumar Swaminathan 	}
1240*82527734SSukumar Swaminathan 
1241*82527734SSukumar Swaminathan 	fcfp = vfip->FCFIp;
1242*82527734SSukumar Swaminathan 	if (vfip == fcfp->fcf_vfi) {
1243*82527734SSukumar Swaminathan 		fcfp->fcf_vfi = NULL;
1244*82527734SSukumar Swaminathan 	}
1245*82527734SSukumar Swaminathan 	emlxs_sli4_free_vfi(hba, vfip);
1246*82527734SSukumar Swaminathan 	return (1);
1247*82527734SSukumar Swaminathan 
1248*82527734SSukumar Swaminathan } /* emlxs_mb_unreg_vfi() */
1249fcf3ce44SJohn Forte 
1250fcf3ce44SJohn Forte 
1251291a2b48SSukumar Swaminathan /*ARGSUSED*/
1252fcf3ce44SJohn Forte extern void
1253*82527734SSukumar Swaminathan emlxs_mb_async_event(emlxs_hba_t *hba, MAILBOXQ *mbq)
1254fcf3ce44SJohn Forte {
1255*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1256*82527734SSukumar Swaminathan 
1257fcf3ce44SJohn Forte 	bzero((void *) mb, MAILBOX_CMD_BSIZE);
1258fcf3ce44SJohn Forte 
1259fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_ASYNC_EVENT;
1260fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1261*82527734SSukumar Swaminathan 	mb->un.varWords[0] = hba->channel_els;
1262*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1263fcf3ce44SJohn Forte 
1264fcf3ce44SJohn Forte 	return;
1265fcf3ce44SJohn Forte 
1266fcf3ce44SJohn Forte } /* emlxs_mb_async_event() */
1267fcf3ce44SJohn Forte 
1268fcf3ce44SJohn Forte 
1269291a2b48SSukumar Swaminathan /*ARGSUSED*/
1270fcf3ce44SJohn Forte extern void
1271*82527734SSukumar Swaminathan emlxs_mb_heartbeat(emlxs_hba_t *hba, MAILBOXQ *mbq)
1272fcf3ce44SJohn Forte {
1273*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1274*82527734SSukumar Swaminathan 
1275fcf3ce44SJohn Forte 	bzero((void *) mb, MAILBOX_CMD_BSIZE);
1276fcf3ce44SJohn Forte 
1277fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_HEARTBEAT;
1278fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1279*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed for hbeat */
1280fcf3ce44SJohn Forte 
1281fcf3ce44SJohn Forte 	return;
1282fcf3ce44SJohn Forte 
1283fcf3ce44SJohn Forte } /* emlxs_mb_heartbeat() */
1284fcf3ce44SJohn Forte 
1285fcf3ce44SJohn Forte 
1286fcf3ce44SJohn Forte #ifdef MSI_SUPPORT
1287fcf3ce44SJohn Forte 
1288291a2b48SSukumar Swaminathan /*ARGSUSED*/
1289fcf3ce44SJohn Forte extern void
1290*82527734SSukumar Swaminathan emlxs_mb_config_msi(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
1291fcf3ce44SJohn Forte     uint32_t intr_count)
1292fcf3ce44SJohn Forte {
1293*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1294fcf3ce44SJohn Forte 	uint32_t i;
1295fcf3ce44SJohn Forte 	uint32_t mask;
1296fcf3ce44SJohn Forte 
1297291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1298fcf3ce44SJohn Forte 
1299fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_MSI;
1300fcf3ce44SJohn Forte 
1301fcf3ce44SJohn Forte 	/* Set the default message id to zero */
1302fcf3ce44SJohn Forte 	mb->un.varCfgMSI.defaultPresent = 1;
1303fcf3ce44SJohn Forte 	mb->un.varCfgMSI.defaultMessageNumber = 0;
1304fcf3ce44SJohn Forte 
1305fcf3ce44SJohn Forte 	for (i = 1; i < intr_count; i++) {
1306fcf3ce44SJohn Forte 		mask = intr_map[i];
1307fcf3ce44SJohn Forte 
1308fcf3ce44SJohn Forte 		mb->un.varCfgMSI.attConditions |= mask;
1309fcf3ce44SJohn Forte 
1310fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN
1311fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
1312fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[3] = i;
1313fcf3ce44SJohn Forte 		}
1314fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
1315fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[7] = i;
1316fcf3ce44SJohn Forte 		}
1317fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
1318fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[11] = i;
1319fcf3ce44SJohn Forte 		}
1320fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
1321fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[15] = i;
1322fcf3ce44SJohn Forte 		}
1323fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
1324fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[29] = i;
1325fcf3ce44SJohn Forte 		}
1326fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
1327fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[30] = i;
1328fcf3ce44SJohn Forte 		}
1329fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
1330fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[31] = i;
1331fcf3ce44SJohn Forte 		}
1332fcf3ce44SJohn Forte #endif	/* EMLXS_BIG_ENDIAN */
1333fcf3ce44SJohn Forte 
1334fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN
1335fcf3ce44SJohn Forte 		/* Accounts for half word swap of LE architecture */
1336fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
1337fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[2] = i;
1338fcf3ce44SJohn Forte 		}
1339fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
1340fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[6] = i;
1341fcf3ce44SJohn Forte 		}
1342fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
1343fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[10] = i;
1344fcf3ce44SJohn Forte 		}
1345fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
1346fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[14] = i;
1347fcf3ce44SJohn Forte 		}
1348fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
1349fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[28] = i;
1350fcf3ce44SJohn Forte 		}
1351fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
1352fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[31] = i;
1353fcf3ce44SJohn Forte 		}
1354fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
1355fcf3ce44SJohn Forte 			mb->un.varCfgMSI.messageNumberByHA[30] = i;
1356fcf3ce44SJohn Forte 		}
1357fcf3ce44SJohn Forte #endif	/* EMLXS_LITTLE_ENDIAN */
1358fcf3ce44SJohn Forte 	}
1359fcf3ce44SJohn Forte 
1360fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1361*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1362fcf3ce44SJohn Forte 
1363fcf3ce44SJohn Forte 	return;
1364fcf3ce44SJohn Forte 
1365fcf3ce44SJohn Forte } /* emlxs_mb_config_msi() */
1366fcf3ce44SJohn Forte 
1367fcf3ce44SJohn Forte 
1368291a2b48SSukumar Swaminathan /*ARGSUSED*/
1369fcf3ce44SJohn Forte extern void
1370*82527734SSukumar Swaminathan emlxs_mb_config_msix(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t *intr_map,
1371fcf3ce44SJohn Forte     uint32_t intr_count)
1372fcf3ce44SJohn Forte {
1373*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1374fcf3ce44SJohn Forte 	uint32_t i;
1375fcf3ce44SJohn Forte 	uint32_t mask;
1376fcf3ce44SJohn Forte 
1377291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1378fcf3ce44SJohn Forte 
1379fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_MSIX;
1380fcf3ce44SJohn Forte 
1381fcf3ce44SJohn Forte 	/* Set the default message id to zero */
1382fcf3ce44SJohn Forte 	mb->un.varCfgMSIX.defaultPresent = 1;
1383fcf3ce44SJohn Forte 	mb->un.varCfgMSIX.defaultMessageNumber = 0;
1384fcf3ce44SJohn Forte 
1385fcf3ce44SJohn Forte 	for (i = 1; i < intr_count; i++) {
1386fcf3ce44SJohn Forte 		mask = intr_map[i];
1387fcf3ce44SJohn Forte 
1388fcf3ce44SJohn Forte 		mb->un.varCfgMSIX.attConditions1 |= mask;
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte #ifdef EMLXS_BIG_ENDIAN
1391fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
1392fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[3] = i;
1393fcf3ce44SJohn Forte 		}
1394fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
1395fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[7] = i;
1396fcf3ce44SJohn Forte 		}
1397fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
1398fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[11] = i;
1399fcf3ce44SJohn Forte 		}
1400fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
1401fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[15] = i;
1402fcf3ce44SJohn Forte 		}
1403fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
1404fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[29] = i;
1405fcf3ce44SJohn Forte 		}
1406fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
1407fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[30] = i;
1408fcf3ce44SJohn Forte 		}
1409fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
1410fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[31] = i;
1411fcf3ce44SJohn Forte 		}
1412fcf3ce44SJohn Forte #endif	/* EMLXS_BIG_ENDIAN */
1413fcf3ce44SJohn Forte 
1414fcf3ce44SJohn Forte #ifdef EMLXS_LITTLE_ENDIAN
1415fcf3ce44SJohn Forte 		/* Accounts for word swap of LE architecture */
1416fcf3ce44SJohn Forte 		if (mask & HA_R0ATT) {
1417fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[0] = i;
1418fcf3ce44SJohn Forte 		}
1419fcf3ce44SJohn Forte 		if (mask & HA_R1ATT) {
1420fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[4] = i;
1421fcf3ce44SJohn Forte 		}
1422fcf3ce44SJohn Forte 		if (mask & HA_R2ATT) {
1423fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[8] = i;
1424fcf3ce44SJohn Forte 		}
1425fcf3ce44SJohn Forte 		if (mask & HA_R3ATT) {
1426fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[12] = i;
1427fcf3ce44SJohn Forte 		}
1428fcf3ce44SJohn Forte 		if (mask & HA_LATT) {
1429fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[30] = i;
1430fcf3ce44SJohn Forte 		}
1431fcf3ce44SJohn Forte 		if (mask & HA_MBATT) {
1432fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[29] = i;
1433fcf3ce44SJohn Forte 		}
1434fcf3ce44SJohn Forte 		if (mask & HA_ERATT) {
1435fcf3ce44SJohn Forte 			mb->un.varCfgMSIX.messageNumberByHA[28] = i;
1436fcf3ce44SJohn Forte 		}
1437fcf3ce44SJohn Forte #endif	/* EMLXS_LITTLE_ENDIAN */
1438fcf3ce44SJohn Forte 	}
1439fcf3ce44SJohn Forte 
1440fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1441*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1442fcf3ce44SJohn Forte 
1443fcf3ce44SJohn Forte 	return;
1444fcf3ce44SJohn Forte 
1445fcf3ce44SJohn Forte } /* emlxs_mb_config_msix() */
1446fcf3ce44SJohn Forte 
1447fcf3ce44SJohn Forte 
1448fcf3ce44SJohn Forte #endif	/* MSI_SUPPORT */
1449fcf3ce44SJohn Forte 
1450291a2b48SSukumar Swaminathan 
1451291a2b48SSukumar Swaminathan /*ARGSUSED*/
1452fcf3ce44SJohn Forte extern void
1453*82527734SSukumar Swaminathan emlxs_mb_reset_ring(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t ringno)
1454fcf3ce44SJohn Forte {
1455*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1456*82527734SSukumar Swaminathan 
1457291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1458fcf3ce44SJohn Forte 
1459fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_RESET_RING;
1460fcf3ce44SJohn Forte 	mb->un.varRstRing.ring_no = ringno;
1461fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1462*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1463fcf3ce44SJohn Forte 
1464fcf3ce44SJohn Forte 	return;
1465fcf3ce44SJohn Forte 
1466fcf3ce44SJohn Forte } /* emlxs_mb_reset_ring() */
1467fcf3ce44SJohn Forte 
1468fcf3ce44SJohn Forte 
1469*82527734SSukumar Swaminathan /*ARGSUSED*/
1470*82527734SSukumar Swaminathan extern void
1471*82527734SSukumar Swaminathan emlxs_mb_dump_vpd(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
1472*82527734SSukumar Swaminathan {
1473*82527734SSukumar Swaminathan 
1474*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1475*82527734SSukumar Swaminathan 		MAILBOX4 *mb = (MAILBOX4 *)mbq;
1476*82527734SSukumar Swaminathan 
1477*82527734SSukumar Swaminathan 		/* Clear the local dump_region */
1478*82527734SSukumar Swaminathan 		bzero(hba->sli.sli4.dump_region.virt,
1479*82527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
1480*82527734SSukumar Swaminathan 
1481*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1482*82527734SSukumar Swaminathan 
1483*82527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
1484*82527734SSukumar Swaminathan 		mb->un.varDmp4.type = DMP_NV_PARAMS;
1485*82527734SSukumar Swaminathan 		mb->un.varDmp4.entry_index = offset;
1486*82527734SSukumar Swaminathan 		mb->un.varDmp4.region_id = DMP_VPD_REGION;
1487*82527734SSukumar Swaminathan 
1488*82527734SSukumar Swaminathan 		mb->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
1489*82527734SSukumar Swaminathan 		mb->un.varDmp4.addrHigh =
1490*82527734SSukumar Swaminathan 		    PADDR_HI(hba->sli.sli4.dump_region.phys);
1491*82527734SSukumar Swaminathan 		mb->un.varDmp4.addrLow =
1492*82527734SSukumar Swaminathan 		    PADDR_LO(hba->sli.sli4.dump_region.phys);
1493*82527734SSukumar Swaminathan 		mb->un.varDmp4.rsp_cnt = 0;
1494*82527734SSukumar Swaminathan 
1495*82527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
1496*82527734SSukumar Swaminathan 
1497*82527734SSukumar Swaminathan 	} else {
1498*82527734SSukumar Swaminathan 		MAILBOX *mb = (MAILBOX *)mbq;
1499*82527734SSukumar Swaminathan 
1500*82527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
1501*82527734SSukumar Swaminathan 
1502*82527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
1503*82527734SSukumar Swaminathan 		mb->un.varDmp.cv = 1;
1504*82527734SSukumar Swaminathan 		mb->un.varDmp.type = DMP_NV_PARAMS;
1505*82527734SSukumar Swaminathan 		mb->un.varDmp.entry_index = offset;
1506*82527734SSukumar Swaminathan 		mb->un.varDmp.region_id = DMP_VPD_REGION;
1507*82527734SSukumar Swaminathan 
1508*82527734SSukumar Swaminathan 		/* limited by mailbox size */
1509*82527734SSukumar Swaminathan 		mb->un.varDmp.word_cnt = DMP_VPD_DUMP_WCOUNT;
1510*82527734SSukumar Swaminathan 
1511*82527734SSukumar Swaminathan 		mb->un.varDmp.co = 0;
1512*82527734SSukumar Swaminathan 		mb->un.varDmp.resp_offset = 0;
1513*82527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
1514*82527734SSukumar Swaminathan 	}
1515*82527734SSukumar Swaminathan 
1516*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1517*82527734SSukumar Swaminathan 
1518*82527734SSukumar Swaminathan } /* emlxs_mb_dump_vpd() */
1519*82527734SSukumar Swaminathan 
1520*82527734SSukumar Swaminathan 
1521*82527734SSukumar Swaminathan /*ARGSUSED*/
1522*82527734SSukumar Swaminathan extern void
1523*82527734SSukumar Swaminathan emlxs_mb_dump_fcoe(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset)
1524*82527734SSukumar Swaminathan {
1525*82527734SSukumar Swaminathan 	MAILBOX4 *mb = (MAILBOX4 *)mbq;
1526*82527734SSukumar Swaminathan 
1527*82527734SSukumar Swaminathan 	if (hba->sli_mode != EMLXS_HBA_SLI4_MODE) {
1528*82527734SSukumar Swaminathan 		return;
1529*82527734SSukumar Swaminathan 	}
1530*82527734SSukumar Swaminathan 	/* Clear the local dump_region */
1531*82527734SSukumar Swaminathan 	bzero(hba->sli.sli4.dump_region.virt,
1532*82527734SSukumar Swaminathan 	    hba->sli.sli4.dump_region.size);
1533*82527734SSukumar Swaminathan 
1534*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1535*82527734SSukumar Swaminathan 
1536*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_DUMP_MEMORY;
1537*82527734SSukumar Swaminathan 	mb->un.varDmp4.type = DMP_NV_PARAMS;
1538*82527734SSukumar Swaminathan 	mb->un.varDmp4.entry_index = offset;
1539*82527734SSukumar Swaminathan 	mb->un.varDmp4.region_id = DMP_FCOE_REGION;
1540*82527734SSukumar Swaminathan 
1541*82527734SSukumar Swaminathan 	mb->un.varDmp4.available_cnt = hba->sli.sli4.dump_region.size;
1542*82527734SSukumar Swaminathan 	mb->un.varDmp4.addrHigh =
1543*82527734SSukumar Swaminathan 	    PADDR_HI(hba->sli.sli4.dump_region.phys);
1544*82527734SSukumar Swaminathan 	mb->un.varDmp4.addrLow =
1545*82527734SSukumar Swaminathan 	    PADDR_LO(hba->sli.sli4.dump_region.phys);
1546*82527734SSukumar Swaminathan 	mb->un.varDmp4.rsp_cnt = 0;
1547*82527734SSukumar Swaminathan 
1548*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1549*82527734SSukumar Swaminathan 
1550*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1551*82527734SSukumar Swaminathan 
1552*82527734SSukumar Swaminathan } /* emlxs_mb_dump_fcoe() */
1553*82527734SSukumar Swaminathan 
1554*82527734SSukumar Swaminathan 
1555*82527734SSukumar Swaminathan /*ARGSUSED*/
1556*82527734SSukumar Swaminathan extern void
1557*82527734SSukumar Swaminathan emlxs_mb_dump(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t offset, uint32_t words)
1558*82527734SSukumar Swaminathan {
1559*82527734SSukumar Swaminathan 
1560*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1561*82527734SSukumar Swaminathan 		MAILBOX4 *mb = (MAILBOX4 *)mbq;
1562*82527734SSukumar Swaminathan 
1563*82527734SSukumar Swaminathan 		/* Clear the local dump_region */
1564*82527734SSukumar Swaminathan 		bzero(hba->sli.sli4.dump_region.virt,
1565*82527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
1566*82527734SSukumar Swaminathan 
1567*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1568*82527734SSukumar Swaminathan 
1569*82527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
1570*82527734SSukumar Swaminathan 		mb->un.varDmp4.type = DMP_MEM_REG;
1571*82527734SSukumar Swaminathan 		mb->un.varDmp4.entry_index = offset;
1572*82527734SSukumar Swaminathan 		mb->un.varDmp4.region_id = 0;
1573*82527734SSukumar Swaminathan 
1574*82527734SSukumar Swaminathan 		mb->un.varDmp4.available_cnt = min((words*4),
1575*82527734SSukumar Swaminathan 		    hba->sli.sli4.dump_region.size);
1576*82527734SSukumar Swaminathan 		mb->un.varDmp4.addrHigh =
1577*82527734SSukumar Swaminathan 		    PADDR_HI(hba->sli.sli4.dump_region.phys);
1578*82527734SSukumar Swaminathan 		mb->un.varDmp4.addrLow =
1579*82527734SSukumar Swaminathan 		    PADDR_LO(hba->sli.sli4.dump_region.phys);
1580*82527734SSukumar Swaminathan 		mb->un.varDmp4.rsp_cnt = 0;
1581*82527734SSukumar Swaminathan 
1582*82527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
1583*82527734SSukumar Swaminathan 
1584*82527734SSukumar Swaminathan 	} else {
1585*82527734SSukumar Swaminathan 
1586*82527734SSukumar Swaminathan 		MAILBOX *mb = (MAILBOX *)mbq;
1587*82527734SSukumar Swaminathan 
1588*82527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
1589*82527734SSukumar Swaminathan 
1590*82527734SSukumar Swaminathan 		mb->mbxCommand = MBX_DUMP_MEMORY;
1591*82527734SSukumar Swaminathan 		mb->un.varDmp.type = DMP_MEM_REG;
1592*82527734SSukumar Swaminathan 		mb->un.varDmp.word_cnt = words;
1593*82527734SSukumar Swaminathan 		mb->un.varDmp.base_adr = offset;
1594*82527734SSukumar Swaminathan 
1595*82527734SSukumar Swaminathan 		mb->un.varDmp.co = 0;
1596*82527734SSukumar Swaminathan 		mb->un.varDmp.resp_offset = 0;
1597*82527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
1598*82527734SSukumar Swaminathan 	}
1599*82527734SSukumar Swaminathan 
1600*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1601*82527734SSukumar Swaminathan 
1602*82527734SSukumar Swaminathan 	return;
1603*82527734SSukumar Swaminathan 
1604*82527734SSukumar Swaminathan } /* emlxs_mb_dump() */
1605*82527734SSukumar Swaminathan 
1606*82527734SSukumar Swaminathan 
1607*82527734SSukumar Swaminathan /*
1608*82527734SSukumar Swaminathan  *  emlxs_mb_read_nv  Issue a READ NVPARAM mailbox command
1609*82527734SSukumar Swaminathan  */
1610*82527734SSukumar Swaminathan /*ARGSUSED*/
1611*82527734SSukumar Swaminathan extern void
1612*82527734SSukumar Swaminathan emlxs_mb_read_nv(emlxs_hba_t *hba, MAILBOXQ *mbq)
1613*82527734SSukumar Swaminathan {
1614*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1615*82527734SSukumar Swaminathan 
1616*82527734SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1617*82527734SSukumar Swaminathan 
1618*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_READ_NV;
1619*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1620*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1621*82527734SSukumar Swaminathan 
1622*82527734SSukumar Swaminathan } /* emlxs_mb_read_nv() */
1623*82527734SSukumar Swaminathan 
1624fcf3ce44SJohn Forte 
1625fcf3ce44SJohn Forte /*
1626*82527734SSukumar Swaminathan  * emlxs_mb_read_rev  Issue a READ REV mailbox command
1627fcf3ce44SJohn Forte  */
1628291a2b48SSukumar Swaminathan /*ARGSUSED*/
1629fcf3ce44SJohn Forte extern void
1630*82527734SSukumar Swaminathan emlxs_mb_read_rev(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t v3)
1631*82527734SSukumar Swaminathan {
1632*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1633*82527734SSukumar Swaminathan 
1634*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
1635*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
1636*82527734SSukumar Swaminathan 		mbq->nonembed = NULL;
1637*82527734SSukumar Swaminathan 	} else {
1638*82527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
1639*82527734SSukumar Swaminathan 
1640*82527734SSukumar Swaminathan 		mb->un.varRdRev.cv = 1;
1641*82527734SSukumar Swaminathan 
1642*82527734SSukumar Swaminathan 		if (v3) {
1643*82527734SSukumar Swaminathan 			mb->un.varRdRev.cv3 = 1;
1644*82527734SSukumar Swaminathan 		}
1645*82527734SSukumar Swaminathan 	}
1646*82527734SSukumar Swaminathan 
1647*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_READ_REV;
1648*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1649*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
1650*82527734SSukumar Swaminathan 
1651*82527734SSukumar Swaminathan } /* emlxs_mb_read_rev() */
1652*82527734SSukumar Swaminathan 
1653*82527734SSukumar Swaminathan 
1654*82527734SSukumar Swaminathan /*
1655*82527734SSukumar Swaminathan  * emlxs_mb_run_biu_diag  Issue a RUN_BIU_DIAG mailbox command
1656*82527734SSukumar Swaminathan  */
1657*82527734SSukumar Swaminathan /*ARGSUSED*/
1658*82527734SSukumar Swaminathan extern uint32_t
1659*82527734SSukumar Swaminathan emlxs_mb_run_biu_diag(emlxs_hba_t *hba, MAILBOXQ *mbq, uint64_t out,
1660*82527734SSukumar Swaminathan     uint64_t in)
1661*82527734SSukumar Swaminathan {
1662*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1663*82527734SSukumar Swaminathan 
1664*82527734SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1665*82527734SSukumar Swaminathan 
1666*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_RUN_BIU_DIAG64;
1667*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
1668*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.addrHigh = PADDR_HI(out);
1669*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.xmit_bde64.addrLow = PADDR_LO(out);
1670*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.tus.f.bdeSize = MEM_ELSBUF_SIZE;
1671*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.addrHigh = PADDR_HI(in);
1672*82527734SSukumar Swaminathan 	mb->un.varBIUdiag.un.s2.rcv_bde64.addrLow = PADDR_LO(in);
1673*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
1674*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
1675*82527734SSukumar Swaminathan 
1676*82527734SSukumar Swaminathan 	return (0);
1677*82527734SSukumar Swaminathan } /* emlxs_mb_run_biu_diag() */
1678*82527734SSukumar Swaminathan 
1679*82527734SSukumar Swaminathan 
1680*82527734SSukumar Swaminathan /* This should only be called with active MBX_NOWAIT mailboxes */
1681*82527734SSukumar Swaminathan void
1682*82527734SSukumar Swaminathan emlxs_mb_retry(emlxs_hba_t *hba, MAILBOXQ *mbq)
1683*82527734SSukumar Swaminathan {
1684*82527734SSukumar Swaminathan 	MAILBOX	*mb;
1685*82527734SSukumar Swaminathan 	MAILBOX	*mbox;
1686*82527734SSukumar Swaminathan 	int rc;
1687*82527734SSukumar Swaminathan 
1688*82527734SSukumar Swaminathan 	mbox = (MAILBOX *)emlxs_mem_get(hba, MEM_MBOX, 1);
1689*82527734SSukumar Swaminathan 	if (!mbox) {
1690*82527734SSukumar Swaminathan 		return;
1691*82527734SSukumar Swaminathan 	}
1692*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
1693*82527734SSukumar Swaminathan 	bcopy((uint8_t *)mb, (uint8_t *)mbox, MAILBOX_CMD_BSIZE);
1694*82527734SSukumar Swaminathan 	mbox->mbxOwner = OWN_HOST;
1695*82527734SSukumar Swaminathan 	mbox->mbxStatus = 0;
1696*82527734SSukumar Swaminathan 
1697*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
1698*82527734SSukumar Swaminathan 
1699*82527734SSukumar Swaminathan 	HBASTATS.MboxCompleted++;
1700*82527734SSukumar Swaminathan 
1701*82527734SSukumar Swaminathan 	if (mb->mbxStatus != 0) {
1702*82527734SSukumar Swaminathan 		HBASTATS.MboxError++;
1703*82527734SSukumar Swaminathan 	} else {
1704*82527734SSukumar Swaminathan 		HBASTATS.MboxGood++;
1705*82527734SSukumar Swaminathan 	}
1706*82527734SSukumar Swaminathan 
1707*82527734SSukumar Swaminathan 	hba->mbox_mbq = 0;
1708*82527734SSukumar Swaminathan 	hba->mbox_queue_flag = 0;
1709*82527734SSukumar Swaminathan 
1710*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
1711*82527734SSukumar Swaminathan 
1712*82527734SSukumar Swaminathan 	rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0);
1713*82527734SSukumar Swaminathan 	if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1714*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox);
1715*82527734SSukumar Swaminathan 	}
1716*82527734SSukumar Swaminathan 	return;
1717*82527734SSukumar Swaminathan 
1718*82527734SSukumar Swaminathan } /* emlxs_mb_retry() */
1719*82527734SSukumar Swaminathan 
1720*82527734SSukumar Swaminathan 
1721*82527734SSukumar Swaminathan int
1722*82527734SSukumar Swaminathan emlxs_cmpl_read_la(void *arg1, MAILBOXQ *mbq)
1723fcf3ce44SJohn Forte {
1724*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
1725*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
1726*82527734SSukumar Swaminathan 	MAILBOX *mb;
1727*82527734SSukumar Swaminathan 	MAILBOXQ *mbox;
1728*82527734SSukumar Swaminathan 	MATCHMAP *mp;
1729*82527734SSukumar Swaminathan 	READ_LA_VAR la;
1730*82527734SSukumar Swaminathan 	int i;
1731*82527734SSukumar Swaminathan 	uint32_t  control;
1732*82527734SSukumar Swaminathan 
1733*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
1734*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
1735*82527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
1736*82527734SSukumar Swaminathan 			control = mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize;
1737*82527734SSukumar Swaminathan 			if (control == 0) {
1738*82527734SSukumar Swaminathan 				(void) emlxs_mb_read_la(hba, mbq);
1739*82527734SSukumar Swaminathan 			}
1740*82527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
1741*82527734SSukumar Swaminathan 			return (1);
1742*82527734SSukumar Swaminathan 		}
1743*82527734SSukumar Swaminathan 		/* Enable Link Attention interrupts */
1744*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
1745fcf3ce44SJohn Forte 
1746*82527734SSukumar Swaminathan 		if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1747*82527734SSukumar Swaminathan 			hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1748*82527734SSukumar Swaminathan 			WRITE_CSR_REG(hba, FC_HC_REG(hba),
1749*82527734SSukumar Swaminathan 			    hba->sli.sli3.hc_copy);
1750*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT
1751*82527734SSukumar Swaminathan 			/* Access handle validation */
1752*82527734SSukumar Swaminathan 			EMLXS_CHK_ACC_HANDLE(hba,
1753*82527734SSukumar Swaminathan 			    hba->sli.sli3.csr_acc_handle);
1754*82527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
1755*82527734SSukumar Swaminathan 		}
1756291a2b48SSukumar Swaminathan 
1757*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
1758*82527734SSukumar Swaminathan 		return (0);
1759*82527734SSukumar Swaminathan 	}
1760*82527734SSukumar Swaminathan 	bcopy((uint32_t *)((char *)mb + sizeof (uint32_t)),
1761*82527734SSukumar Swaminathan 	    (uint32_t *)&la, sizeof (READ_LA_VAR));
1762fcf3ce44SJohn Forte 
1763*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
1764*82527734SSukumar Swaminathan 	if (mp) {
1765*82527734SSukumar Swaminathan 		bcopy((caddr_t)mp->virt, (caddr_t)port->alpa_map, 128);
1766*82527734SSukumar Swaminathan 	} else {
1767*82527734SSukumar Swaminathan 		bzero((caddr_t)port->alpa_map, 128);
1768*82527734SSukumar Swaminathan 	}
1769291a2b48SSukumar Swaminathan 
1770*82527734SSukumar Swaminathan 	if (la.attType == AT_LINK_UP) {
1771*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkup_atten_msg,
1772*82527734SSukumar Swaminathan 		    "tag=%d -> %d  ALPA=%x",
1773*82527734SSukumar Swaminathan 		    (uint32_t)hba->link_event_tag,
1774*82527734SSukumar Swaminathan 		    (uint32_t)la.eventTag,
1775*82527734SSukumar Swaminathan 		    (uint32_t)la.granted_AL_PA);
1776*82527734SSukumar Swaminathan 	} else {
1777*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_linkdown_atten_msg,
1778*82527734SSukumar Swaminathan 		    "tag=%d -> %d  ALPA=%x",
1779*82527734SSukumar Swaminathan 		    (uint32_t)hba->link_event_tag,
1780*82527734SSukumar Swaminathan 		    (uint32_t)la.eventTag,
1781*82527734SSukumar Swaminathan 		    (uint32_t)la.granted_AL_PA);
1782*82527734SSukumar Swaminathan 	}
1783fcf3ce44SJohn Forte 
1784*82527734SSukumar Swaminathan 	if (la.pb) {
1785*82527734SSukumar Swaminathan 		hba->flag |= FC_BYPASSED_MODE;
1786*82527734SSukumar Swaminathan 	} else {
1787*82527734SSukumar Swaminathan 		hba->flag &= ~FC_BYPASSED_MODE;
1788*82527734SSukumar Swaminathan 	}
1789fcf3ce44SJohn Forte 
1790*82527734SSukumar Swaminathan 	if (hba->link_event_tag == la.eventTag) {
1791*82527734SSukumar Swaminathan 		HBASTATS.LinkMultiEvent++;
1792*82527734SSukumar Swaminathan 	} else if (hba->link_event_tag + 1 < la.eventTag) {
1793*82527734SSukumar Swaminathan 		HBASTATS.LinkMultiEvent++;
1794291a2b48SSukumar Swaminathan 
1795*82527734SSukumar Swaminathan 		/* Make sure link is declared down */
1796*82527734SSukumar Swaminathan 		emlxs_linkdown(hba);
1797*82527734SSukumar Swaminathan 	}
1798291a2b48SSukumar Swaminathan 
1799*82527734SSukumar Swaminathan 	hba->link_event_tag = la.eventTag;
1800*82527734SSukumar Swaminathan 	port->lip_type = 0;
1801291a2b48SSukumar Swaminathan 
1802*82527734SSukumar Swaminathan 	/* If link not already up then declare it up now */
1803*82527734SSukumar Swaminathan 	if ((la.attType == AT_LINK_UP) && (hba->state < FC_LINK_UP)) {
1804291a2b48SSukumar Swaminathan 
1805*82527734SSukumar Swaminathan #ifdef MENLO_SUPPORT
1806*82527734SSukumar Swaminathan 		if ((hba->model_info.device_id == PCI_DEVICE_ID_LP21000_M) &&
1807*82527734SSukumar Swaminathan 		    (hba->flag & (FC_ILB_MODE | FC_ELB_MODE))) {
1808*82527734SSukumar Swaminathan 			la.topology = TOPOLOGY_LOOP;
1809*82527734SSukumar Swaminathan 			la.granted_AL_PA = 0;
1810*82527734SSukumar Swaminathan 			port->alpa_map[0] = 1;
1811*82527734SSukumar Swaminathan 			port->alpa_map[1] = 0;
1812*82527734SSukumar Swaminathan 			la.lipType = LT_PORT_INIT;
1813*82527734SSukumar Swaminathan 		}
1814*82527734SSukumar Swaminathan #endif /* MENLO_SUPPORT */
1815*82527734SSukumar Swaminathan 		/* Save the linkspeed */
1816*82527734SSukumar Swaminathan 		hba->linkspeed = la.UlnkSpeed;
1817*82527734SSukumar Swaminathan 
1818*82527734SSukumar Swaminathan 		/* Check for old model adapters that only */
1819*82527734SSukumar Swaminathan 		/* supported 1Gb */
1820*82527734SSukumar Swaminathan 		if ((hba->linkspeed == 0) &&
1821*82527734SSukumar Swaminathan 		    (hba->model_info.chip & EMLXS_DRAGONFLY_CHIP)) {
1822*82527734SSukumar Swaminathan 			hba->linkspeed = LA_1GHZ_LINK;
1823*82527734SSukumar Swaminathan 		}
1824291a2b48SSukumar Swaminathan 
1825*82527734SSukumar Swaminathan 		if ((hba->topology = la.topology) == TOPOLOGY_LOOP) {
1826*82527734SSukumar Swaminathan 			port->did = la.granted_AL_PA;
1827*82527734SSukumar Swaminathan 			port->lip_type = la.lipType;
1828*82527734SSukumar Swaminathan 			if (hba->flag & FC_SLIM2_MODE) {
1829*82527734SSukumar Swaminathan 				i = la.un.lilpBde64.tus.f.bdeSize;
1830*82527734SSukumar Swaminathan 			} else {
1831*82527734SSukumar Swaminathan 				i = la.un.lilpBde.bdeSize;
1832*82527734SSukumar Swaminathan 			}
1833291a2b48SSukumar Swaminathan 
1834*82527734SSukumar Swaminathan 			if (i == 0) {
1835*82527734SSukumar Swaminathan 				port->alpa_map[0] = 0;
1836*82527734SSukumar Swaminathan 			} else {
1837*82527734SSukumar Swaminathan 				uint8_t *alpa_map;
1838*82527734SSukumar Swaminathan 				uint32_t j;
1839*82527734SSukumar Swaminathan 
1840*82527734SSukumar Swaminathan 				/* Check number of devices in map */
1841*82527734SSukumar Swaminathan 				if (port->alpa_map[0] > 127) {
1842*82527734SSukumar Swaminathan 					port->alpa_map[0] = 127;
1843*82527734SSukumar Swaminathan 				}
1844*82527734SSukumar Swaminathan 
1845*82527734SSukumar Swaminathan 				alpa_map = (uint8_t *)port->alpa_map;
1846*82527734SSukumar Swaminathan 
1847*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
1848*82527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
1849*82527734SSukumar Swaminathan 				    "alpa_map: %d device(s):      "
1850*82527734SSukumar Swaminathan 				    "%02x %02x %02x %02x %02x %02x "
1851*82527734SSukumar Swaminathan 				    "%02x", alpa_map[0], alpa_map[1],
1852*82527734SSukumar Swaminathan 				    alpa_map[2], alpa_map[3],
1853*82527734SSukumar Swaminathan 				    alpa_map[4], alpa_map[5],
1854*82527734SSukumar Swaminathan 				    alpa_map[6], alpa_map[7]);
1855*82527734SSukumar Swaminathan 
1856*82527734SSukumar Swaminathan 				for (j = 8; j <= alpa_map[0]; j += 8) {
1857*82527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
1858*82527734SSukumar Swaminathan 					    &emlxs_link_atten_msg,
1859*82527734SSukumar Swaminathan 					    "alpa_map:             "
1860*82527734SSukumar Swaminathan 					    "%02x %02x %02x %02x %02x "
1861*82527734SSukumar Swaminathan 					    "%02x %02x %02x",
1862*82527734SSukumar Swaminathan 					    alpa_map[j],
1863*82527734SSukumar Swaminathan 					    alpa_map[j + 1],
1864*82527734SSukumar Swaminathan 					    alpa_map[j + 2],
1865*82527734SSukumar Swaminathan 					    alpa_map[j + 3],
1866*82527734SSukumar Swaminathan 					    alpa_map[j + 4],
1867*82527734SSukumar Swaminathan 					    alpa_map[j + 5],
1868*82527734SSukumar Swaminathan 					    alpa_map[j + 6],
1869*82527734SSukumar Swaminathan 					    alpa_map[j + 7]);
1870*82527734SSukumar Swaminathan 				}
1871*82527734SSukumar Swaminathan 			}
1872*82527734SSukumar Swaminathan 		}
1873*82527734SSukumar Swaminathan #ifdef MENLO_SUPPORT
1874*82527734SSukumar Swaminathan 		/* Check if Menlo maintenance mode is enabled */
1875*82527734SSukumar Swaminathan 		if (hba->model_info.device_id ==
1876*82527734SSukumar Swaminathan 		    PCI_DEVICE_ID_LP21000_M) {
1877*82527734SSukumar Swaminathan 			if (la.mm == 1) {
1878*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
1879*82527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
1880*82527734SSukumar Swaminathan 				    "Maintenance Mode enabled.");
1881*82527734SSukumar Swaminathan 
1882*82527734SSukumar Swaminathan 				mutex_enter(&EMLXS_PORT_LOCK);
1883*82527734SSukumar Swaminathan 				hba->flag |= FC_MENLO_MODE;
1884*82527734SSukumar Swaminathan 				mutex_exit(&EMLXS_PORT_LOCK);
1885*82527734SSukumar Swaminathan 
1886*82527734SSukumar Swaminathan 				mutex_enter(&EMLXS_LINKUP_LOCK);
1887*82527734SSukumar Swaminathan 				cv_broadcast(&EMLXS_LINKUP_CV);
1888*82527734SSukumar Swaminathan 				mutex_exit(&EMLXS_LINKUP_LOCK);
1889*82527734SSukumar Swaminathan 			} else {
1890*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
1891*82527734SSukumar Swaminathan 				    &emlxs_link_atten_msg,
1892*82527734SSukumar Swaminathan 				    "Maintenance Mode disabled.");
1893*82527734SSukumar Swaminathan 			}
1894291a2b48SSukumar Swaminathan 
1895*82527734SSukumar Swaminathan 			/* Check FCoE attention bit */
1896*82527734SSukumar Swaminathan 			if (la.fa == 1) {
1897*82527734SSukumar Swaminathan 				emlxs_thread_spawn(hba,
1898*82527734SSukumar Swaminathan 				    emlxs_fcoe_attention_thread,
1899*82527734SSukumar Swaminathan 				    NULL, NULL);
1900*82527734SSukumar Swaminathan 			}
1901*82527734SSukumar Swaminathan 		}
1902*82527734SSukumar Swaminathan #endif /* MENLO_SUPPORT */
1903fcf3ce44SJohn Forte 
1904*82527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1905*82527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
1906*82527734SSukumar Swaminathan 			/* This should turn on DELAYED ABTS for */
1907*82527734SSukumar Swaminathan 			/* ELS timeouts */
1908*82527734SSukumar Swaminathan 			emlxs_mb_set_var(hba, mbox, 0x00052198, 0x1);
1909fcf3ce44SJohn Forte 
1910*82527734SSukumar Swaminathan 			emlxs_mb_put(hba, mbox);
1911*82527734SSukumar Swaminathan 		}
1912fcf3ce44SJohn Forte 
1913*82527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1914*82527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
1915*82527734SSukumar Swaminathan 			/* If link not already down then */
1916*82527734SSukumar Swaminathan 			/* declare it down now */
1917*82527734SSukumar Swaminathan 			if (emlxs_mb_read_sparam(hba, mbox) == 0) {
1918*82527734SSukumar Swaminathan 				emlxs_mb_put(hba, mbox);
1919*82527734SSukumar Swaminathan 			} else {
1920*82527734SSukumar Swaminathan 				(void) emlxs_mem_put(hba, MEM_MBOX,
1921*82527734SSukumar Swaminathan 				    (uint8_t *)mbox);
1922*82527734SSukumar Swaminathan 			}
1923*82527734SSukumar Swaminathan 		}
1924*82527734SSukumar Swaminathan 
1925*82527734SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1926*82527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
1927*82527734SSukumar Swaminathan 			emlxs_mb_config_link(hba, mbox);
1928fcf3ce44SJohn Forte 
1929*82527734SSukumar Swaminathan 			emlxs_mb_put(hba, mbox);
1930*82527734SSukumar Swaminathan 		}
1931fcf3ce44SJohn Forte 
1932*82527734SSukumar Swaminathan 		/* Declare the linkup here */
1933*82527734SSukumar Swaminathan 		emlxs_linkup(hba);
1934fcf3ce44SJohn Forte 	}
1935fcf3ce44SJohn Forte 
1936*82527734SSukumar Swaminathan 	/* If link not already down then declare it down now */
1937*82527734SSukumar Swaminathan 	else if (la.attType == AT_LINK_DOWN) {
1938*82527734SSukumar Swaminathan 		/* Make sure link is declared down */
1939*82527734SSukumar Swaminathan 		emlxs_linkdown(hba);
1940*82527734SSukumar Swaminathan 	}
1941fcf3ce44SJohn Forte 
1942*82527734SSukumar Swaminathan 	/* Enable Link attention interrupt */
1943*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
1944fcf3ce44SJohn Forte 
1945*82527734SSukumar Swaminathan 	if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
1946*82527734SSukumar Swaminathan 		hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
1947*82527734SSukumar Swaminathan 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
1948*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT
1949*82527734SSukumar Swaminathan 		/* Access handle validation */
1950*82527734SSukumar Swaminathan 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
1951*82527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
1952*82527734SSukumar Swaminathan 	}
1953fcf3ce44SJohn Forte 
1954*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
1955fcf3ce44SJohn Forte 
1956*82527734SSukumar Swaminathan 	/* Log the link event */
1957*82527734SSukumar Swaminathan 	emlxs_log_link_event(port);
1958fcf3ce44SJohn Forte 	return (0);
1959*82527734SSukumar Swaminathan 
1960*82527734SSukumar Swaminathan } /* emlxs_cmpl_read_la() */
1961fcf3ce44SJohn Forte 
1962fcf3ce44SJohn Forte 
1963fcf3ce44SJohn Forte /*
1964291a2b48SSukumar Swaminathan  *  emlxs_mb_read_la  Issue a READ LA mailbox command
1965fcf3ce44SJohn Forte  */
1966fcf3ce44SJohn Forte extern uint32_t
1967*82527734SSukumar Swaminathan emlxs_mb_read_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
1968fcf3ce44SJohn Forte {
1969*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
1970fcf3ce44SJohn Forte 	MATCHMAP *mp;
1971fcf3ce44SJohn Forte 
1972291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
1973fcf3ce44SJohn Forte 
1974*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
1975fcf3ce44SJohn Forte 		mb->mbxCommand = MBX_READ_LA64;
1976fcf3ce44SJohn Forte 
1977fcf3ce44SJohn Forte 		return (1);
1978fcf3ce44SJohn Forte 	}
1979291a2b48SSukumar Swaminathan 
1980fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_LA64;
1981fcf3ce44SJohn Forte 	mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
1982*82527734SSukumar Swaminathan 	mb->un.varReadLA.un.lilpBde64.addrHigh = PADDR_HI(mp->phys);
1983*82527734SSukumar Swaminathan 	mb->un.varReadLA.un.lilpBde64.addrLow = PADDR_LO(mp->phys);
1984fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
1985*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_read_la;
1986fcf3ce44SJohn Forte 
1987fcf3ce44SJohn Forte 	/*
1988fcf3ce44SJohn Forte 	 * save address for completion
1989fcf3ce44SJohn Forte 	 */
1990fcf3ce44SJohn Forte 	((MAILBOXQ *)mb)->bp = (uint8_t *)mp;
1991fcf3ce44SJohn Forte 
1992fcf3ce44SJohn Forte 	return (0);
1993fcf3ce44SJohn Forte 
1994fcf3ce44SJohn Forte } /* emlxs_mb_read_la() */
1995fcf3ce44SJohn Forte 
1996fcf3ce44SJohn Forte 
1997*82527734SSukumar Swaminathan int
1998*82527734SSukumar Swaminathan emlxs_cmpl_clear_la(void *arg1, MAILBOXQ *mbq)
1999*82527734SSukumar Swaminathan {
2000*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
2001*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
2002*82527734SSukumar Swaminathan 	MAILBOX *mb;
2003*82527734SSukumar Swaminathan 	MAILBOXQ *mbox;
2004*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
2005*82527734SSukumar Swaminathan 	uint32_t la_enable;
2006*82527734SSukumar Swaminathan 	int i, rc;
2007*82527734SSukumar Swaminathan 
2008*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
2009*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
2010*82527734SSukumar Swaminathan 		la_enable = 1;
2011*82527734SSukumar Swaminathan 
2012*82527734SSukumar Swaminathan 		if (mb->mbxStatus == 0x1601) {
2013*82527734SSukumar Swaminathan 			/* Get a buffer which will be used for */
2014*82527734SSukumar Swaminathan 			/* mailbox commands */
2015*82527734SSukumar Swaminathan 			if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
2016*82527734SSukumar Swaminathan 			    MEM_MBOX, 1))) {
2017*82527734SSukumar Swaminathan 				/* Get link attention message */
2018*82527734SSukumar Swaminathan 				if (emlxs_mb_read_la(hba, mbox) == 0) {
2019*82527734SSukumar Swaminathan 					rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba,
2020*82527734SSukumar Swaminathan 					    (MAILBOX *)mbox, MBX_NOWAIT, 0);
2021*82527734SSukumar Swaminathan 					if ((rc != MBX_BUSY) &&
2022*82527734SSukumar Swaminathan 					    (rc != MBX_SUCCESS)) {
2023*82527734SSukumar Swaminathan 						(void) emlxs_mem_put(hba,
2024*82527734SSukumar Swaminathan 						    MEM_MBOX, (uint8_t *)mbox);
2025*82527734SSukumar Swaminathan 					}
2026*82527734SSukumar Swaminathan 					la_enable = 0;
2027*82527734SSukumar Swaminathan 				} else {
2028*82527734SSukumar Swaminathan 					(void) emlxs_mem_put(hba, MEM_MBOX,
2029*82527734SSukumar Swaminathan 					    (uint8_t *)mbox);
2030*82527734SSukumar Swaminathan 				}
2031*82527734SSukumar Swaminathan 			}
2032*82527734SSukumar Swaminathan 		}
2033*82527734SSukumar Swaminathan 
2034*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
2035*82527734SSukumar Swaminathan 		if (la_enable) {
2036*82527734SSukumar Swaminathan 			if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
2037*82527734SSukumar Swaminathan 				/* Enable Link Attention interrupts */
2038*82527734SSukumar Swaminathan 				hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
2039*82527734SSukumar Swaminathan 				WRITE_CSR_REG(hba, FC_HC_REG(hba),
2040*82527734SSukumar Swaminathan 				    hba->sli.sli3.hc_copy);
2041*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT
2042*82527734SSukumar Swaminathan 				/* Access handle validation */
2043*82527734SSukumar Swaminathan 				EMLXS_CHK_ACC_HANDLE(hba,
2044*82527734SSukumar Swaminathan 				    hba->sli.sli3.csr_acc_handle);
2045*82527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
2046*82527734SSukumar Swaminathan 			}
2047*82527734SSukumar Swaminathan 		} else {
2048*82527734SSukumar Swaminathan 			if (hba->sli.sli3.hc_copy & HC_LAINT_ENA) {
2049*82527734SSukumar Swaminathan 				/* Disable Link Attention interrupts */
2050*82527734SSukumar Swaminathan 				hba->sli.sli3.hc_copy &= ~HC_LAINT_ENA;
2051*82527734SSukumar Swaminathan 				WRITE_CSR_REG(hba, FC_HC_REG(hba),
2052*82527734SSukumar Swaminathan 				    hba->sli.sli3.hc_copy);
2053*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT
2054*82527734SSukumar Swaminathan 				/* Access handle validation */
2055*82527734SSukumar Swaminathan 				EMLXS_CHK_ACC_HANDLE(hba,
2056*82527734SSukumar Swaminathan 				    hba->sli.sli3.csr_acc_handle);
2057*82527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
2058*82527734SSukumar Swaminathan 			}
2059*82527734SSukumar Swaminathan 		}
2060*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
2061*82527734SSukumar Swaminathan 
2062*82527734SSukumar Swaminathan 		return (0);
2063*82527734SSukumar Swaminathan 	}
2064*82527734SSukumar Swaminathan 	/* Enable on Link Attention interrupts */
2065*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_PORT_LOCK);
2066*82527734SSukumar Swaminathan 
2067*82527734SSukumar Swaminathan 	if (!(hba->sli.sli3.hc_copy & HC_LAINT_ENA)) {
2068*82527734SSukumar Swaminathan 		hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
2069*82527734SSukumar Swaminathan 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
2070*82527734SSukumar Swaminathan #ifdef FMA_SUPPORT
2071*82527734SSukumar Swaminathan 		/* Access handle validation */
2072*82527734SSukumar Swaminathan 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
2073*82527734SSukumar Swaminathan #endif  /* FMA_SUPPORT */
2074*82527734SSukumar Swaminathan 	}
2075*82527734SSukumar Swaminathan 
2076*82527734SSukumar Swaminathan 	if (hba->state >= FC_LINK_UP) {
2077*82527734SSukumar Swaminathan 		EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
2078*82527734SSukumar Swaminathan 	}
2079*82527734SSukumar Swaminathan 
2080*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_PORT_LOCK);
2081*82527734SSukumar Swaminathan 
2082*82527734SSukumar Swaminathan 	/* Adapter is now ready for FCP traffic */
2083*82527734SSukumar Swaminathan 	if (hba->state == FC_READY) {
2084*82527734SSukumar Swaminathan 		/* Register vpi's for all ports that have did's */
2085*82527734SSukumar Swaminathan 		for (i = 0; i < MAX_VPORTS; i++) {
2086*82527734SSukumar Swaminathan 			vport = &VPORT(i);
2087*82527734SSukumar Swaminathan 
2088*82527734SSukumar Swaminathan 			if (!(vport->flag & EMLXS_PORT_BOUND) ||
2089*82527734SSukumar Swaminathan 			    !(vport->did)) {
2090*82527734SSukumar Swaminathan 				continue;
2091*82527734SSukumar Swaminathan 			}
2092*82527734SSukumar Swaminathan 
2093*82527734SSukumar Swaminathan 			(void) emlxs_mb_reg_vpi(vport, NULL);
2094*82527734SSukumar Swaminathan 		}
2095*82527734SSukumar Swaminathan 
2096*82527734SSukumar Swaminathan 		/* Attempt to send any pending IO */
2097*82527734SSukumar Swaminathan 		EMLXS_SLI_ISSUE_IOCB_CMD(hba, &hba->chan[hba->channel_fcp], 0);
2098*82527734SSukumar Swaminathan 	}
2099*82527734SSukumar Swaminathan 	return (0);
2100*82527734SSukumar Swaminathan 
2101*82527734SSukumar Swaminathan } /* emlxs_cmpl_clear_la() */
2102*82527734SSukumar Swaminathan 
2103*82527734SSukumar Swaminathan 
2104fcf3ce44SJohn Forte /*
2105291a2b48SSukumar Swaminathan  *  emlxs_mb_clear_la  Issue a CLEAR LA mailbox command
2106fcf3ce44SJohn Forte  */
2107fcf3ce44SJohn Forte extern void
2108*82527734SSukumar Swaminathan emlxs_mb_clear_la(emlxs_hba_t *hba, MAILBOXQ *mbq)
2109fcf3ce44SJohn Forte {
2110*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2111*82527734SSukumar Swaminathan 
2112fcf3ce44SJohn Forte #ifdef FC_RPI_CHECK
2113fcf3ce44SJohn Forte 	emlxs_rpi_check(hba);
2114fcf3ce44SJohn Forte #endif	/* FC_RPI_CHECK */
2115fcf3ce44SJohn Forte 
2116291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2117fcf3ce44SJohn Forte 
2118fcf3ce44SJohn Forte 	mb->un.varClearLA.eventTag = hba->link_event_tag;
2119fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CLEAR_LA;
2120fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2121*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_clear_la;
2122fcf3ce44SJohn Forte 
2123fcf3ce44SJohn Forte 	return;
2124fcf3ce44SJohn Forte 
2125*82527734SSukumar Swaminathan } /* emlxs_mb_clear_la() */
2126fcf3ce44SJohn Forte 
2127fcf3ce44SJohn Forte 
2128fcf3ce44SJohn Forte /*
2129291a2b48SSukumar Swaminathan  * emlxs_mb_read_status  Issue a READ STATUS mailbox command
2130fcf3ce44SJohn Forte  */
2131291a2b48SSukumar Swaminathan /*ARGSUSED*/
2132fcf3ce44SJohn Forte extern void
2133*82527734SSukumar Swaminathan emlxs_mb_read_status(emlxs_hba_t *hba, MAILBOXQ *mbq)
2134fcf3ce44SJohn Forte {
2135*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2136*82527734SSukumar Swaminathan 
2137291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2138fcf3ce44SJohn Forte 
2139fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_STATUS;
2140fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2141*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2142*82527734SSukumar Swaminathan 
2143*82527734SSukumar Swaminathan } /* fc_read_status() */
2144*82527734SSukumar Swaminathan 
2145fcf3ce44SJohn Forte 
2146fcf3ce44SJohn Forte /*
2147291a2b48SSukumar Swaminathan  * emlxs_mb_read_lnk_stat  Issue a LINK STATUS mailbox command
2148fcf3ce44SJohn Forte  */
2149291a2b48SSukumar Swaminathan /*ARGSUSED*/
2150fcf3ce44SJohn Forte extern void
2151*82527734SSukumar Swaminathan emlxs_mb_read_lnk_stat(emlxs_hba_t *hba, MAILBOXQ *mbq)
2152fcf3ce44SJohn Forte {
2153*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2154*82527734SSukumar Swaminathan 
2155291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2156fcf3ce44SJohn Forte 
2157fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_LNK_STAT;
2158fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2159*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2160*82527734SSukumar Swaminathan 
2161*82527734SSukumar Swaminathan } /* emlxs_mb_read_lnk_stat() */
2162fcf3ce44SJohn Forte 
2163fcf3ce44SJohn Forte 
2164fcf3ce44SJohn Forte /*
2165291a2b48SSukumar Swaminathan  * emlxs_mb_write_nv  Issue a WRITE NVPARAM mailbox command
2166fcf3ce44SJohn Forte  */
2167fcf3ce44SJohn Forte static void
2168*82527734SSukumar Swaminathan emlxs_emb_mb_write_nv(emlxs_hba_t *hba, MAILBOXQ *mbq)
2169fcf3ce44SJohn Forte {
2170*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2171291a2b48SSukumar Swaminathan 	int32_t		i;
2172291a2b48SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
2173fcf3ce44SJohn Forte 
2174291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2175fcf3ce44SJohn Forte 
2176291a2b48SSukumar Swaminathan 	bcopy((void *)&hba->wwnn,
2177291a2b48SSukumar Swaminathan 	    (void *)mb->un.varWTnvp.nodename, sizeof (NAME_TYPE));
2178fcf3ce44SJohn Forte 
2179291a2b48SSukumar Swaminathan 	bcopy((void *)&hba->wwpn,
2180291a2b48SSukumar Swaminathan 	    (void *)mb->un.varWTnvp.portname, sizeof (NAME_TYPE));
2181fcf3ce44SJohn Forte 
2182fcf3ce44SJohn Forte 	mb->un.varWTnvp.pref_DID = 0;
2183fcf3ce44SJohn Forte 	mb->un.varWTnvp.hardAL_PA = (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2184fcf3ce44SJohn Forte 	mb->un.varWTnvp.rsvd1[0] = 0xffffffff;
2185fcf3ce44SJohn Forte 	mb->un.varWTnvp.rsvd1[1] = 0xffffffff;
2186fcf3ce44SJohn Forte 	mb->un.varWTnvp.rsvd1[2] = 0xffffffff;
2187fcf3ce44SJohn Forte 	for (i = 0; i < 21; i++) {
2188fcf3ce44SJohn Forte 		mb->un.varWTnvp.rsvd3[i] = 0xffffffff;
2189fcf3ce44SJohn Forte 	}
2190fcf3ce44SJohn Forte 
2191fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_WRITE_NV;
2192fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2193*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2194*82527734SSukumar Swaminathan 
2195*82527734SSukumar Swaminathan } /* emlxs_mb_write_nv() */
2196fcf3ce44SJohn Forte 
2197fcf3ce44SJohn Forte 
2198fcf3ce44SJohn Forte /*
2199291a2b48SSukumar Swaminathan  * emlxs_mb_part_slim  Issue a PARTITION SLIM mailbox command
2200fcf3ce44SJohn Forte  */
2201fcf3ce44SJohn Forte static void
2202*82527734SSukumar Swaminathan emlxs_mb_part_slim(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t hbainit)
2203fcf3ce44SJohn Forte {
2204*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2205*82527734SSukumar Swaminathan 
2206291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2207fcf3ce44SJohn Forte 
2208fcf3ce44SJohn Forte 
2209*82527734SSukumar Swaminathan 	mb->un.varSlim.numRing = hba->chan_count;
2210fcf3ce44SJohn Forte 	mb->un.varSlim.hbainit = hbainit;
2211fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_PART_SLIM;
2212fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2213*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2214*82527734SSukumar Swaminathan 
2215*82527734SSukumar Swaminathan } /* emlxs_mb_part_slim() */
2216fcf3ce44SJohn Forte 
2217fcf3ce44SJohn Forte 
2218fcf3ce44SJohn Forte /*
2219291a2b48SSukumar Swaminathan  * emlxs_mb_config_ring  Issue a CONFIG RING mailbox command
2220fcf3ce44SJohn Forte  */
2221fcf3ce44SJohn Forte extern void
2222*82527734SSukumar Swaminathan emlxs_mb_config_ring(emlxs_hba_t *hba, int32_t ring, MAILBOXQ *mbq)
2223fcf3ce44SJohn Forte {
2224*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2225fcf3ce44SJohn Forte 	int32_t i;
2226fcf3ce44SJohn Forte 	int32_t j;
2227fcf3ce44SJohn Forte 
2228291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2229fcf3ce44SJohn Forte 
2230fcf3ce44SJohn Forte 	j = 0;
2231fcf3ce44SJohn Forte 	for (i = 0; i < ring; i++) {
2232*82527734SSukumar Swaminathan 		j += hba->sli.sli3.ring_masks[i];
2233fcf3ce44SJohn Forte 	}
2234fcf3ce44SJohn Forte 
2235*82527734SSukumar Swaminathan 	for (i = 0; i < hba->sli.sli3.ring_masks[ring]; i++) {
2236fcf3ce44SJohn Forte 		if ((j + i) >= 6) {
2237fcf3ce44SJohn Forte 			break;
2238fcf3ce44SJohn Forte 		}
2239291a2b48SSukumar Swaminathan 
2240*82527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].rval  =
2241*82527734SSukumar Swaminathan 		    hba->sli.sli3.ring_rval[j + i];
2242*82527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].rmask =
2243*82527734SSukumar Swaminathan 		    hba->sli.sli3.ring_rmask[j + i];
2244*82527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].tval  =
2245*82527734SSukumar Swaminathan 		    hba->sli.sli3.ring_tval[j + i];
2246*82527734SSukumar Swaminathan 		mb->un.varCfgRing.rrRegs[i].tmask =
2247*82527734SSukumar Swaminathan 		    hba->sli.sli3.ring_tmask[j + i];
2248fcf3ce44SJohn Forte 	}
2249fcf3ce44SJohn Forte 
2250fcf3ce44SJohn Forte 	mb->un.varCfgRing.ring = ring;
2251fcf3ce44SJohn Forte 	mb->un.varCfgRing.profile = 0;
2252fcf3ce44SJohn Forte 	mb->un.varCfgRing.maxOrigXchg = 0;
2253fcf3ce44SJohn Forte 	mb->un.varCfgRing.maxRespXchg = 0;
2254fcf3ce44SJohn Forte 	mb->un.varCfgRing.recvNotify = 1;
2255*82527734SSukumar Swaminathan 	mb->un.varCfgRing.numMask = hba->sli.sli3.ring_masks[ring];
2256fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_RING;
2257fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2258*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2259fcf3ce44SJohn Forte 
2260fcf3ce44SJohn Forte 	return;
2261fcf3ce44SJohn Forte 
2262*82527734SSukumar Swaminathan } /* emlxs_mb_config_ring() */
2263fcf3ce44SJohn Forte 
2264fcf3ce44SJohn Forte 
2265fcf3ce44SJohn Forte /*
2266291a2b48SSukumar Swaminathan  *  emlxs_mb_config_link  Issue a CONFIG LINK mailbox command
2267fcf3ce44SJohn Forte  */
2268fcf3ce44SJohn Forte extern void
2269*82527734SSukumar Swaminathan emlxs_mb_config_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
2270fcf3ce44SJohn Forte {
2271*82527734SSukumar Swaminathan 	MAILBOX	*mb = (MAILBOX *)mbq;
2272291a2b48SSukumar Swaminathan 	emlxs_port_t   *port = &PPORT;
2273fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
2274fcf3ce44SJohn Forte 
2275291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2276fcf3ce44SJohn Forte 
2277fcf3ce44SJohn Forte 	/*
2278fcf3ce44SJohn Forte 	 * NEW_FEATURE SLI-2, Coalescing Response Feature.
2279fcf3ce44SJohn Forte 	 */
2280fcf3ce44SJohn Forte 	if (cfg[CFG_CR_DELAY].current) {
2281fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr = 1;
2282fcf3ce44SJohn Forte 		mb->un.varCfgLnk.ci = 1;
2283fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr_delay = cfg[CFG_CR_DELAY].current;
2284fcf3ce44SJohn Forte 		mb->un.varCfgLnk.cr_count = cfg[CFG_CR_COUNT].current;
2285fcf3ce44SJohn Forte 	}
2286291a2b48SSukumar Swaminathan 
2287fcf3ce44SJohn Forte 	if (cfg[CFG_ACK0].current)
2288fcf3ce44SJohn Forte 		mb->un.varCfgLnk.ack0_enable = 1;
2289fcf3ce44SJohn Forte 
2290fcf3ce44SJohn Forte 	mb->un.varCfgLnk.myId = port->did;
2291fcf3ce44SJohn Forte 	mb->un.varCfgLnk.edtov = hba->fc_edtov;
2292fcf3ce44SJohn Forte 	mb->un.varCfgLnk.arbtov = hba->fc_arbtov;
2293fcf3ce44SJohn Forte 	mb->un.varCfgLnk.ratov = hba->fc_ratov;
2294fcf3ce44SJohn Forte 	mb->un.varCfgLnk.rttov = hba->fc_rttov;
2295fcf3ce44SJohn Forte 	mb->un.varCfgLnk.altov = hba->fc_altov;
2296fcf3ce44SJohn Forte 	mb->un.varCfgLnk.crtov = hba->fc_crtov;
2297fcf3ce44SJohn Forte 	mb->un.varCfgLnk.citov = hba->fc_citov;
2298fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_LINK;
2299fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2300*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
2301fcf3ce44SJohn Forte 
2302fcf3ce44SJohn Forte 	return;
2303fcf3ce44SJohn Forte 
2304fcf3ce44SJohn Forte } /* emlxs_mb_config_link() */
2305fcf3ce44SJohn Forte 
2306fcf3ce44SJohn Forte 
2307*82527734SSukumar Swaminathan int
2308*82527734SSukumar Swaminathan emlxs_cmpl_init_link(void *arg1, MAILBOXQ *mbq)
2309*82527734SSukumar Swaminathan {
2310*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
2311*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
2312*82527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
2313*82527734SSukumar Swaminathan 	MAILBOX *mb;
2314*82527734SSukumar Swaminathan 
2315*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
2316*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
2317*82527734SSukumar Swaminathan 		if ((hba->flag & FC_SLIM2_MODE) &&
2318*82527734SSukumar Swaminathan 		    (hba->mbox_queue_flag == MBX_NOWAIT)) {
2319*82527734SSukumar Swaminathan 			/* Retry only MBX_NOWAIT requests */
2320*82527734SSukumar Swaminathan 
2321*82527734SSukumar Swaminathan 			if ((cfg[CFG_LINK_SPEED].current > 0) &&
2322*82527734SSukumar Swaminathan 			    ((mb->mbxStatus == 0x0011) ||
2323*82527734SSukumar Swaminathan 			    (mb->mbxStatus == 0x0500))) {
2324*82527734SSukumar Swaminathan 
2325*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
2326*82527734SSukumar Swaminathan 				    &emlxs_mbox_event_msg,
2327*82527734SSukumar Swaminathan 				    "Retrying.  %s: status=%x. Auto-speed set.",
2328*82527734SSukumar Swaminathan 				    emlxs_mb_cmd_xlate(mb->mbxCommand),
2329*82527734SSukumar Swaminathan 				    (uint32_t)mb->mbxStatus);
2330*82527734SSukumar Swaminathan 
2331*82527734SSukumar Swaminathan 				mb->un.varInitLnk.link_flags &=
2332*82527734SSukumar Swaminathan 				    ~FLAGS_LINK_SPEED;
2333*82527734SSukumar Swaminathan 				mb->un.varInitLnk.link_speed = 0;
2334*82527734SSukumar Swaminathan 
2335*82527734SSukumar Swaminathan 				emlxs_mb_retry(hba, mbq);
2336*82527734SSukumar Swaminathan 				return (1);
2337*82527734SSukumar Swaminathan 			}
2338*82527734SSukumar Swaminathan 		}
2339*82527734SSukumar Swaminathan 	}
2340*82527734SSukumar Swaminathan 	return (0);
2341*82527734SSukumar Swaminathan 
2342*82527734SSukumar Swaminathan } /* emlxs_cmpl_init_link() */
2343*82527734SSukumar Swaminathan 
2344*82527734SSukumar Swaminathan 
2345fcf3ce44SJohn Forte /*
2346291a2b48SSukumar Swaminathan  *  emlxs_mb_init_link  Issue an INIT LINK mailbox command
2347fcf3ce44SJohn Forte  */
2348fcf3ce44SJohn Forte extern void
2349*82527734SSukumar Swaminathan emlxs_mb_init_link(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t topology,
2350fcf3ce44SJohn Forte     uint32_t linkspeed)
2351fcf3ce44SJohn Forte {
2352*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2353291a2b48SSukumar Swaminathan 	emlxs_vpd_t	*vpd = &VPD;
2354291a2b48SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
2355fcf3ce44SJohn Forte 
2356*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2357*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
2358*82527734SSukumar Swaminathan 		mbq->nonembed = NULL;
2359*82527734SSukumar Swaminathan 		mbq->mbox_cmpl = NULL; /* no cmpl needed */
2360*82527734SSukumar Swaminathan 
2361*82527734SSukumar Swaminathan 		mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
2362*82527734SSukumar Swaminathan 		mb->mbxOwner = OWN_HOST;
2363*82527734SSukumar Swaminathan 		return;
2364*82527734SSukumar Swaminathan 	}
2365*82527734SSukumar Swaminathan 
2366291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2367fcf3ce44SJohn Forte 
2368fcf3ce44SJohn Forte 	switch (topology) {
2369fcf3ce44SJohn Forte 	case FLAGS_LOCAL_LB:
2370fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2371fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LOCAL_LB;
2372fcf3ce44SJohn Forte 		break;
2373fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_LOOP_PT:
2374fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2375fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
2376fcf3ce44SJohn Forte 		break;
2377fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_PT_PT:
2378fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
2379fcf3ce44SJohn Forte 		break;
2380fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_LOOP:
2381fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
2382fcf3ce44SJohn Forte 		break;
2383fcf3ce44SJohn Forte 	case FLAGS_TOPOLOGY_MODE_PT_LOOP:
2384fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
2385fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
2386fcf3ce44SJohn Forte 		break;
2387fcf3ce44SJohn Forte 	}
2388fcf3ce44SJohn Forte 
2389fcf3ce44SJohn Forte 	if (cfg[CFG_LILP_ENABLE].current == 0) {
2390fcf3ce44SJohn Forte 		/* Disable LIRP/LILP support */
2391fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LIRP_LILP;
2392fcf3ce44SJohn Forte 	}
2393291a2b48SSukumar Swaminathan 
2394fcf3ce44SJohn Forte 	/*
2395fcf3ce44SJohn Forte 	 * Setting up the link speed
2396fcf3ce44SJohn Forte 	 */
2397fcf3ce44SJohn Forte 	switch (linkspeed) {
2398fcf3ce44SJohn Forte 	case 0:
2399fcf3ce44SJohn Forte 		break;
2400fcf3ce44SJohn Forte 
2401fcf3ce44SJohn Forte 	case 1:
2402fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_1GB_CAPABLE)) {
2403fcf3ce44SJohn Forte 			linkspeed = 0;
2404fcf3ce44SJohn Forte 		}
2405fcf3ce44SJohn Forte 		break;
2406fcf3ce44SJohn Forte 
2407fcf3ce44SJohn Forte 	case 2:
2408fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_2GB_CAPABLE)) {
2409fcf3ce44SJohn Forte 			linkspeed = 0;
2410fcf3ce44SJohn Forte 		}
2411fcf3ce44SJohn Forte 		break;
2412fcf3ce44SJohn Forte 
2413fcf3ce44SJohn Forte 	case 4:
2414fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_4GB_CAPABLE)) {
2415fcf3ce44SJohn Forte 			linkspeed = 0;
2416fcf3ce44SJohn Forte 		}
2417fcf3ce44SJohn Forte 		break;
2418fcf3ce44SJohn Forte 
2419fcf3ce44SJohn Forte 	case 8:
2420fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_8GB_CAPABLE)) {
2421fcf3ce44SJohn Forte 			linkspeed = 0;
2422fcf3ce44SJohn Forte 		}
2423fcf3ce44SJohn Forte 		break;
2424fcf3ce44SJohn Forte 
2425fcf3ce44SJohn Forte 	case 10:
2426fcf3ce44SJohn Forte 		if (!(vpd->link_speed & LMT_10GB_CAPABLE)) {
2427fcf3ce44SJohn Forte 			linkspeed = 0;
2428fcf3ce44SJohn Forte 		}
2429fcf3ce44SJohn Forte 		break;
2430fcf3ce44SJohn Forte 
2431fcf3ce44SJohn Forte 	default:
2432fcf3ce44SJohn Forte 		linkspeed = 0;
2433fcf3ce44SJohn Forte 		break;
2434fcf3ce44SJohn Forte 
2435fcf3ce44SJohn Forte 	}
2436fcf3ce44SJohn Forte 
2437fcf3ce44SJohn Forte 	if ((linkspeed > 0) && (vpd->feaLevelHigh >= 0x02)) {
2438fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
2439fcf3ce44SJohn Forte 		mb->un.varInitLnk.link_speed = linkspeed;
2440fcf3ce44SJohn Forte 	}
2441291a2b48SSukumar Swaminathan 
2442fcf3ce44SJohn Forte 	mb->un.varInitLnk.link_flags |= FLAGS_PREABORT_RETURN;
2443fcf3ce44SJohn Forte 
2444291a2b48SSukumar Swaminathan 	mb->un.varInitLnk.fabric_AL_PA =
2445291a2b48SSukumar Swaminathan 	    (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2446fcf3ce44SJohn Forte 	mb->mbxCommand = (volatile uint8_t) MBX_INIT_LINK;
2447fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2448*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_init_link;
2449fcf3ce44SJohn Forte 
2450fcf3ce44SJohn Forte 
2451fcf3ce44SJohn Forte 	return;
2452fcf3ce44SJohn Forte 
2453fcf3ce44SJohn Forte } /* emlxs_mb_init_link() */
2454fcf3ce44SJohn Forte 
2455fcf3ce44SJohn Forte 
2456fcf3ce44SJohn Forte /*
2457291a2b48SSukumar Swaminathan  *  emlxs_mb_down_link  Issue a DOWN LINK mailbox command
2458fcf3ce44SJohn Forte  */
2459291a2b48SSukumar Swaminathan /*ARGSUSED*/
2460fcf3ce44SJohn Forte extern void
2461*82527734SSukumar Swaminathan emlxs_mb_down_link(emlxs_hba_t *hba, MAILBOXQ *mbq)
2462fcf3ce44SJohn Forte {
2463*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2464*82527734SSukumar Swaminathan 
2465291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2466fcf3ce44SJohn Forte 
2467fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_DOWN_LINK;
2468fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2469*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
2470fcf3ce44SJohn Forte 
2471fcf3ce44SJohn Forte 	return;
2472fcf3ce44SJohn Forte 
2473fcf3ce44SJohn Forte } /* emlxs_mb_down_link() */
2474fcf3ce44SJohn Forte 
2475fcf3ce44SJohn Forte 
2476*82527734SSukumar Swaminathan int
2477*82527734SSukumar Swaminathan emlxs_cmpl_read_sparam(void *arg1, MAILBOXQ *mbq)
2478*82527734SSukumar Swaminathan {
2479*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
2480*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
2481*82527734SSukumar Swaminathan 	MAILBOX *mb;
2482*82527734SSukumar Swaminathan 	MATCHMAP *mp;
2483*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
2484*82527734SSukumar Swaminathan 	int32_t i;
2485*82527734SSukumar Swaminathan 	uint32_t  control;
2486*82527734SSukumar Swaminathan 	uint8_t null_wwn[8];
2487*82527734SSukumar Swaminathan 
2488*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
2489*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
2490*82527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
2491*82527734SSukumar Swaminathan 			control = mb->un.varRdSparm.un.sp64.tus.f.bdeSize;
2492*82527734SSukumar Swaminathan 			if (control == 0) {
2493*82527734SSukumar Swaminathan 				(void) emlxs_mb_read_sparam(hba, mbq);
2494*82527734SSukumar Swaminathan 			}
2495*82527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
2496*82527734SSukumar Swaminathan 			return (1);
2497*82527734SSukumar Swaminathan 		}
2498*82527734SSukumar Swaminathan 		return (0);
2499*82527734SSukumar Swaminathan 	}
2500*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
2501*82527734SSukumar Swaminathan 	if (!mp) {
2502*82527734SSukumar Swaminathan 		return (0);
2503*82527734SSukumar Swaminathan 	}
2504*82527734SSukumar Swaminathan 
2505*82527734SSukumar Swaminathan 	bcopy((caddr_t)mp->virt, (caddr_t)&hba->sparam, sizeof (SERV_PARM));
2506*82527734SSukumar Swaminathan 
2507*82527734SSukumar Swaminathan 	/* Initialize the node name and port name only once */
2508*82527734SSukumar Swaminathan 	bzero(null_wwn, 8);
2509*82527734SSukumar Swaminathan 	if ((bcmp((caddr_t)&hba->wwnn, (caddr_t)null_wwn, 8) == 0) &&
2510*82527734SSukumar Swaminathan 	    (bcmp((caddr_t)&hba->wwpn, (caddr_t)null_wwn, 8) == 0)) {
2511*82527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam.nodeName,
2512*82527734SSukumar Swaminathan 		    (caddr_t)&hba->wwnn, sizeof (NAME_TYPE));
2513*82527734SSukumar Swaminathan 
2514*82527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam.portName,
2515*82527734SSukumar Swaminathan 		    (caddr_t)&hba->wwpn, sizeof (NAME_TYPE));
2516*82527734SSukumar Swaminathan 	} else {
2517*82527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->wwnn,
2518*82527734SSukumar Swaminathan 		    (caddr_t)&hba->sparam.nodeName, sizeof (NAME_TYPE));
2519*82527734SSukumar Swaminathan 
2520*82527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->wwpn,
2521*82527734SSukumar Swaminathan 		    (caddr_t)&hba->sparam.portName, sizeof (NAME_TYPE));
2522*82527734SSukumar Swaminathan 	}
2523*82527734SSukumar Swaminathan 
2524*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
2525*82527734SSukumar Swaminathan 	    "SPARAM: EDTOV hba=x%x mbox_csp=x%x,  BBC=x%x",
2526*82527734SSukumar Swaminathan 	    hba->fc_edtov, hba->sparam.cmn.e_d_tov,
2527*82527734SSukumar Swaminathan 	    hba->sparam.cmn.bbCreditlsb);
2528*82527734SSukumar Swaminathan 
2529*82527734SSukumar Swaminathan 	hba->sparam.cmn.e_d_tov = hba->fc_edtov;
2530*82527734SSukumar Swaminathan 
2531*82527734SSukumar Swaminathan 	/* Initialize the physical port */
2532*82527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->sparam,
2533*82527734SSukumar Swaminathan 	    (caddr_t)&port->sparam, sizeof (SERV_PARM));
2534*82527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->wwpn, (caddr_t)&port->wwpn,
2535*82527734SSukumar Swaminathan 	    sizeof (NAME_TYPE));
2536*82527734SSukumar Swaminathan 	bcopy((caddr_t)&hba->wwnn, (caddr_t)&port->wwnn,
2537*82527734SSukumar Swaminathan 	    sizeof (NAME_TYPE));
2538*82527734SSukumar Swaminathan 
2539*82527734SSukumar Swaminathan 	/* Initialize the virtual ports */
2540*82527734SSukumar Swaminathan 	for (i = 1; i < MAX_VPORTS; i++) {
2541*82527734SSukumar Swaminathan 		vport = &VPORT(i);
2542*82527734SSukumar Swaminathan 		if (vport->flag & EMLXS_PORT_BOUND) {
2543*82527734SSukumar Swaminathan 			continue;
2544*82527734SSukumar Swaminathan 		}
2545*82527734SSukumar Swaminathan 
2546*82527734SSukumar Swaminathan 		bcopy((caddr_t)&hba->sparam,
2547*82527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam,
2548*82527734SSukumar Swaminathan 		    sizeof (SERV_PARM));
2549*82527734SSukumar Swaminathan 
2550*82527734SSukumar Swaminathan 		bcopy((caddr_t)&vport->wwnn,
2551*82527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam.nodeName,
2552*82527734SSukumar Swaminathan 		    sizeof (NAME_TYPE));
2553*82527734SSukumar Swaminathan 
2554*82527734SSukumar Swaminathan 		bcopy((caddr_t)&vport->wwpn,
2555*82527734SSukumar Swaminathan 		    (caddr_t)&vport->sparam.portName,
2556*82527734SSukumar Swaminathan 		    sizeof (NAME_TYPE));
2557*82527734SSukumar Swaminathan 	}
2558*82527734SSukumar Swaminathan 
2559*82527734SSukumar Swaminathan 	return (0);
2560*82527734SSukumar Swaminathan 
2561*82527734SSukumar Swaminathan } /* emlxs_cmpl_read_sparam() */
2562*82527734SSukumar Swaminathan 
2563*82527734SSukumar Swaminathan 
2564fcf3ce44SJohn Forte /*
2565291a2b48SSukumar Swaminathan  * emlxs_mb_read_sparam  Issue a READ SPARAM mailbox command
2566fcf3ce44SJohn Forte  */
2567fcf3ce44SJohn Forte extern uint32_t
2568*82527734SSukumar Swaminathan emlxs_mb_read_sparam(emlxs_hba_t *hba, MAILBOXQ *mbq)
2569fcf3ce44SJohn Forte {
2570*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2571fcf3ce44SJohn Forte 	MATCHMAP *mp;
2572fcf3ce44SJohn Forte 
2573291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2574fcf3ce44SJohn Forte 
2575*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
2576fcf3ce44SJohn Forte 		mb->mbxCommand = MBX_READ_SPARM64;
2577fcf3ce44SJohn Forte 
2578fcf3ce44SJohn Forte 		return (1);
2579fcf3ce44SJohn Forte 	}
2580291a2b48SSukumar Swaminathan 
2581fcf3ce44SJohn Forte 	mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
2582*82527734SSukumar Swaminathan 	mb->un.varRdSparm.un.sp64.addrHigh = PADDR_HI(mp->phys);
2583*82527734SSukumar Swaminathan 	mb->un.varRdSparm.un.sp64.addrLow = PADDR_LO(mp->phys);
2584fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_SPARM64;
2585fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2586*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_read_sparam;
2587fcf3ce44SJohn Forte 
2588fcf3ce44SJohn Forte 	/*
2589fcf3ce44SJohn Forte 	 * save address for completion
2590fcf3ce44SJohn Forte 	 */
2591*82527734SSukumar Swaminathan 	mbq->bp = (uint8_t *)mp;
2592fcf3ce44SJohn Forte 
2593fcf3ce44SJohn Forte 	return (0);
2594fcf3ce44SJohn Forte 
2595fcf3ce44SJohn Forte } /* emlxs_mb_read_sparam() */
2596fcf3ce44SJohn Forte 
2597fcf3ce44SJohn Forte 
2598fcf3ce44SJohn Forte /*
2599291a2b48SSukumar Swaminathan  * emlxs_mb_read_rpi    Issue a READ RPI mailbox command
2600fcf3ce44SJohn Forte  */
2601291a2b48SSukumar Swaminathan /*ARGSUSED*/
2602fcf3ce44SJohn Forte extern uint32_t
2603*82527734SSukumar Swaminathan emlxs_mb_read_rpi(emlxs_hba_t *hba, uint32_t rpi, MAILBOXQ *mbq,
2604291a2b48SSukumar Swaminathan     uint32_t flag)
2605fcf3ce44SJohn Forte {
2606*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2607*82527734SSukumar Swaminathan 
2608291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2609fcf3ce44SJohn Forte 
2610fcf3ce44SJohn Forte 	/*
2611fcf3ce44SJohn Forte 	 * Set flag to issue action on cmpl
2612fcf3ce44SJohn Forte 	 */
2613fcf3ce44SJohn Forte 	mb->un.varWords[30] = flag;
2614fcf3ce44SJohn Forte 	mb->un.varRdRPI.reqRpi = (volatile uint16_t) rpi;
2615fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_RPI64;
2616fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2617*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2618fcf3ce44SJohn Forte 
2619fcf3ce44SJohn Forte 	return (0);
2620*82527734SSukumar Swaminathan } /* emlxs_mb_read_rpi() */
2621fcf3ce44SJohn Forte 
2622fcf3ce44SJohn Forte 
2623fcf3ce44SJohn Forte /*
2624291a2b48SSukumar Swaminathan  * emlxs_mb_read_xri    Issue a READ XRI mailbox command
2625fcf3ce44SJohn Forte  */
2626291a2b48SSukumar Swaminathan /*ARGSUSED*/
2627fcf3ce44SJohn Forte extern uint32_t
2628*82527734SSukumar Swaminathan emlxs_mb_read_xri(emlxs_hba_t *hba, uint32_t xri, MAILBOXQ *mbq,
2629291a2b48SSukumar Swaminathan     uint32_t flag)
2630fcf3ce44SJohn Forte {
2631*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
2632*82527734SSukumar Swaminathan 
2633291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
2634fcf3ce44SJohn Forte 
2635fcf3ce44SJohn Forte 	/*
2636fcf3ce44SJohn Forte 	 * Set flag to issue action on cmpl
2637fcf3ce44SJohn Forte 	 */
2638fcf3ce44SJohn Forte 	mb->un.varWords[30] = flag;
2639291a2b48SSukumar Swaminathan 	mb->un.varRdXRI.reqXri = (volatile uint16_t)xri;
2640fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_XRI;
2641fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
2642*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
2643*82527734SSukumar Swaminathan 
2644*82527734SSukumar Swaminathan 	return (0);
2645*82527734SSukumar Swaminathan } /* emlxs_mb_read_xri() */
2646*82527734SSukumar Swaminathan 
2647*82527734SSukumar Swaminathan 
2648*82527734SSukumar Swaminathan /*ARGSUSED*/
2649*82527734SSukumar Swaminathan extern int32_t
2650*82527734SSukumar Swaminathan emlxs_mb_check_sparm(emlxs_hba_t *hba, SERV_PARM *nsp)
2651*82527734SSukumar Swaminathan {
2652*82527734SSukumar Swaminathan 	uint32_t nsp_value;
2653*82527734SSukumar Swaminathan 	uint32_t *iptr;
2654*82527734SSukumar Swaminathan 
2655*82527734SSukumar Swaminathan 	if (nsp->cmn.fPort) {
2656*82527734SSukumar Swaminathan 		return (0);
2657*82527734SSukumar Swaminathan 	}
2658*82527734SSukumar Swaminathan 
2659*82527734SSukumar Swaminathan 	/* Validate the service parameters */
2660*82527734SSukumar Swaminathan 	iptr = (uint32_t *)&nsp->portName;
2661*82527734SSukumar Swaminathan 	if (iptr[0] == 0 && iptr[1] == 0) {
2662*82527734SSukumar Swaminathan 		return (1);
2663*82527734SSukumar Swaminathan 	}
2664*82527734SSukumar Swaminathan 
2665*82527734SSukumar Swaminathan 	iptr = (uint32_t *)&nsp->nodeName;
2666*82527734SSukumar Swaminathan 	if (iptr[0] == 0 && iptr[1] == 0) {
2667*82527734SSukumar Swaminathan 		return (2);
2668*82527734SSukumar Swaminathan 	}
2669*82527734SSukumar Swaminathan 
2670*82527734SSukumar Swaminathan 	if (nsp->cls2.classValid) {
2671*82527734SSukumar Swaminathan 		nsp_value =
2672*82527734SSukumar Swaminathan 		    ((nsp->cls2.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls2.
2673*82527734SSukumar Swaminathan 		    rcvDataSizeLsb;
2674*82527734SSukumar Swaminathan 
2675*82527734SSukumar Swaminathan 		/* If the receive data length is zero then set it to */
2676*82527734SSukumar Swaminathan 		/* the CSP value */
2677*82527734SSukumar Swaminathan 		if (!nsp_value) {
2678*82527734SSukumar Swaminathan 			nsp->cls2.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
2679*82527734SSukumar Swaminathan 			nsp->cls2.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
2680*82527734SSukumar Swaminathan 			return (0);
2681*82527734SSukumar Swaminathan 		}
2682*82527734SSukumar Swaminathan 	}
2683*82527734SSukumar Swaminathan 
2684*82527734SSukumar Swaminathan 	if (nsp->cls3.classValid) {
2685*82527734SSukumar Swaminathan 		nsp_value =
2686*82527734SSukumar Swaminathan 		    ((nsp->cls3.rcvDataSizeMsb & 0x0f) << 8) | nsp->cls3.
2687*82527734SSukumar Swaminathan 		    rcvDataSizeLsb;
2688*82527734SSukumar Swaminathan 
2689*82527734SSukumar Swaminathan 		/* If the receive data length is zero then set it to */
2690*82527734SSukumar Swaminathan 		/* the CSP value */
2691*82527734SSukumar Swaminathan 		if (!nsp_value) {
2692*82527734SSukumar Swaminathan 			nsp->cls3.rcvDataSizeMsb = nsp->cmn.bbRcvSizeMsb;
2693*82527734SSukumar Swaminathan 			nsp->cls3.rcvDataSizeLsb = nsp->cmn.bbRcvSizeLsb;
2694*82527734SSukumar Swaminathan 			return (0);
2695*82527734SSukumar Swaminathan 		}
2696*82527734SSukumar Swaminathan 	}
2697*82527734SSukumar Swaminathan 
2698*82527734SSukumar Swaminathan 	return (0);
2699*82527734SSukumar Swaminathan 
2700*82527734SSukumar Swaminathan } /* emlxs_mb_check_sparm() */
2701*82527734SSukumar Swaminathan 
2702*82527734SSukumar Swaminathan 
2703*82527734SSukumar Swaminathan int
2704*82527734SSukumar Swaminathan emlxs_cmpl_reg_did(void *arg1, MAILBOXQ *mbq)
2705*82527734SSukumar Swaminathan {
2706*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
2707*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
2708*82527734SSukumar Swaminathan 	MAILBOX *mb;
2709*82527734SSukumar Swaminathan 	MATCHMAP *mp;
2710*82527734SSukumar Swaminathan 	NODELIST *ndlp;
2711*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
2712*82527734SSukumar Swaminathan 	uint8_t *wwn;
2713*82527734SSukumar Swaminathan 	volatile SERV_PARM *sp;
2714*82527734SSukumar Swaminathan 	int32_t i;
2715*82527734SSukumar Swaminathan 	uint32_t  control;
2716*82527734SSukumar Swaminathan 	uint32_t ldata;
2717*82527734SSukumar Swaminathan 	uint32_t ldid;
2718*82527734SSukumar Swaminathan 	uint16_t lrpi;
2719*82527734SSukumar Swaminathan 	uint16_t lvpi;
2720*82527734SSukumar Swaminathan 	emlxs_vvl_fmt_t vvl;
2721*82527734SSukumar Swaminathan 
2722*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
2723*82527734SSukumar Swaminathan 	if (mb->mbxStatus) {
2724*82527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
2725*82527734SSukumar Swaminathan 			control = mb->un.varRegLogin.un.sp.bdeSize;
2726*82527734SSukumar Swaminathan 			if (control == 0) {
2727*82527734SSukumar Swaminathan 				/* Special handle for vport PLOGI */
2728*82527734SSukumar Swaminathan 				if (mbq->iocbq == (uint8_t *)1) {
2729*82527734SSukumar Swaminathan 					mbq->iocbq = NULL;
2730*82527734SSukumar Swaminathan 				}
2731*82527734SSukumar Swaminathan 				return (0);
2732*82527734SSukumar Swaminathan 			}
2733*82527734SSukumar Swaminathan 			emlxs_mb_retry(hba, mbq);
2734*82527734SSukumar Swaminathan 			return (1);
2735*82527734SSukumar Swaminathan 		}
2736*82527734SSukumar Swaminathan 		if (mb->mbxStatus == MBXERR_RPI_FULL) {
2737*82527734SSukumar Swaminathan 			port = &VPORT((mb->un.varRegLogin.vpi - hba->vpi_base));
2738*82527734SSukumar Swaminathan 
2739*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
2740*82527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
2741*82527734SSukumar Swaminathan 			    "Limit reached. count=%d", port->node_count);
2742*82527734SSukumar Swaminathan 		}
2743*82527734SSukumar Swaminathan 
2744*82527734SSukumar Swaminathan 		/* Special handle for vport PLOGI */
2745*82527734SSukumar Swaminathan 		if (mbq->iocbq == (uint8_t *)1) {
2746*82527734SSukumar Swaminathan 			mbq->iocbq = NULL;
2747*82527734SSukumar Swaminathan 		}
2748*82527734SSukumar Swaminathan 
2749*82527734SSukumar Swaminathan 		return (0);
2750*82527734SSukumar Swaminathan 	}
2751*82527734SSukumar Swaminathan 
2752*82527734SSukumar Swaminathan 	mp = (MATCHMAP *)mbq->bp;
2753*82527734SSukumar Swaminathan 	if (!mp) {
2754*82527734SSukumar Swaminathan 		return (0);
2755*82527734SSukumar Swaminathan 	}
2756*82527734SSukumar Swaminathan 	ldata = mb->un.varWords[5];
2757*82527734SSukumar Swaminathan 	lvpi = (ldata & 0xffff) - hba->vpi_base;
2758*82527734SSukumar Swaminathan 	port = &VPORT(lvpi);
2759*82527734SSukumar Swaminathan 
2760*82527734SSukumar Swaminathan 	/* First copy command data */
2761*82527734SSukumar Swaminathan 	ldata = mb->un.varWords[0];	/* get rpi */
2762*82527734SSukumar Swaminathan 	lrpi = ldata & 0xffff;
2763*82527734SSukumar Swaminathan 
2764*82527734SSukumar Swaminathan 	ldata = mb->un.varWords[1];	/* get did */
2765*82527734SSukumar Swaminathan 	ldid = ldata & MASK_DID;
2766*82527734SSukumar Swaminathan 
2767*82527734SSukumar Swaminathan 	sp = (volatile SERV_PARM *)mp->virt;
2768*82527734SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, ldid);
2769*82527734SSukumar Swaminathan 
2770*82527734SSukumar Swaminathan 	if (!ndlp) {
2771*82527734SSukumar Swaminathan 		/* Attempt to create a node */
2772*82527734SSukumar Swaminathan 		if ((ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP, 0))) {
2773*82527734SSukumar Swaminathan 			ndlp->nlp_Rpi = lrpi;
2774*82527734SSukumar Swaminathan 			ndlp->nlp_DID = ldid;
2775*82527734SSukumar Swaminathan 
2776*82527734SSukumar Swaminathan 			bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
2777*82527734SSukumar Swaminathan 			    sizeof (SERV_PARM));
2778*82527734SSukumar Swaminathan 
2779*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->nodeName,
2780*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_nodename,
2781*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
2782*82527734SSukumar Swaminathan 
2783*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->portName,
2784*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_portname,
2785*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
2786*82527734SSukumar Swaminathan 
2787*82527734SSukumar Swaminathan 			ndlp->nlp_active = 1;
2788*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ct]  |= NLP_CLOSED;
2789*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_els] |= NLP_CLOSED;
2790*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_fcp] |= NLP_CLOSED;
2791*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ip]  |= NLP_CLOSED;
2792*82527734SSukumar Swaminathan 
2793*82527734SSukumar Swaminathan 			/* Add the node */
2794*82527734SSukumar Swaminathan 			emlxs_node_add(port, ndlp);
2795*82527734SSukumar Swaminathan 
2796*82527734SSukumar Swaminathan 			/* Open the node */
2797*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ct);
2798*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_els);
2799*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2800*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2801*82527734SSukumar Swaminathan 		} else {
2802*82527734SSukumar Swaminathan 			wwn = (uint8_t *)&sp->portName;
2803*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
2804*82527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
2805*82527734SSukumar Swaminathan 			    "Unable to allocate node. did=%06x rpi=%x "
2806*82527734SSukumar Swaminathan 			    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
2807*82527734SSukumar Swaminathan 			    ldid, lrpi, wwn[0], wwn[1], wwn[2],
2808*82527734SSukumar Swaminathan 			    wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
2809*82527734SSukumar Swaminathan 
2810*82527734SSukumar Swaminathan 			return (0);
2811*82527734SSukumar Swaminathan 		}
2812*82527734SSukumar Swaminathan 	} else {
2813*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
2814fcf3ce44SJohn Forte 
2815*82527734SSukumar Swaminathan 		ndlp->nlp_Rpi = lrpi;
2816*82527734SSukumar Swaminathan 		ndlp->nlp_DID = ldid;
2817fcf3ce44SJohn Forte 
2818*82527734SSukumar Swaminathan 		bcopy((uint8_t *)sp,
2819*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->sparm, sizeof (SERV_PARM));
2820fcf3ce44SJohn Forte 
2821*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->nodeName,
2822*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_nodename, sizeof (NAME_TYPE));
2823fcf3ce44SJohn Forte 
2824*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->portName,
2825*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_portname, sizeof (NAME_TYPE));
2826*82527734SSukumar Swaminathan 
2827*82527734SSukumar Swaminathan 		wwn = (uint8_t *)&ndlp->nlp_portname;
2828*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
2829*82527734SSukumar Swaminathan 		    "node=%p did=%06x rpi=%x "
2830*82527734SSukumar Swaminathan 		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
2831*82527734SSukumar Swaminathan 		    ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
2832*82527734SSukumar Swaminathan 		    wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
2833*82527734SSukumar Swaminathan 
2834*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
2835*82527734SSukumar Swaminathan 
2836*82527734SSukumar Swaminathan 		/* Open the node */
2837*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ct);
2838*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_els);
2839*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
2840*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
2841fcf3ce44SJohn Forte 	}
2842291a2b48SSukumar Swaminathan 
2843*82527734SSukumar Swaminathan 	bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t));
2844*82527734SSukumar Swaminathan 
2845*82527734SSukumar Swaminathan 	if (sp->VALID_VENDOR_VERSION) {
2846*82527734SSukumar Swaminathan 
2847*82527734SSukumar Swaminathan 		bcopy((caddr_t *)&sp->vendorVersion[0],
2848*82527734SSukumar Swaminathan 		    (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
2849*82527734SSukumar Swaminathan 
2850*82527734SSukumar Swaminathan 		vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
2851*82527734SSukumar Swaminathan 		vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
2852*82527734SSukumar Swaminathan 
2853*82527734SSukumar Swaminathan 		if ((vvl.un0.w0.oui == 0x0000C9) &&
2854*82527734SSukumar Swaminathan 		    (vvl.un1.w1.vport)) {
2855*82527734SSukumar Swaminathan 			ndlp->nlp_fcp_info |= NLP_EMLX_VPORT;
2856*82527734SSukumar Swaminathan 		}
2857fcf3ce44SJohn Forte 	}
2858291a2b48SSukumar Swaminathan 
2859*82527734SSukumar Swaminathan 	if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) &&
2860*82527734SSukumar Swaminathan 	    (ndlp->nlp_DID == NAMESERVER_DID)) {
2861*82527734SSukumar Swaminathan 			EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
2862fcf3ce44SJohn Forte 	}
2863291a2b48SSukumar Swaminathan 
2864*82527734SSukumar Swaminathan 	/* If this was a fabric login */
2865*82527734SSukumar Swaminathan 	if (ndlp->nlp_DID == FABRIC_DID) {
2866*82527734SSukumar Swaminathan 		/* If CLEAR_LA has been sent, then attempt to */
2867*82527734SSukumar Swaminathan 		/* register the vpi now */
2868*82527734SSukumar Swaminathan 		if (hba->state == FC_READY) {
2869*82527734SSukumar Swaminathan 			(void) emlxs_mb_reg_vpi(port, NULL);
2870*82527734SSukumar Swaminathan 		}
2871fcf3ce44SJohn Forte 
2872*82527734SSukumar Swaminathan 		/*
2873*82527734SSukumar Swaminathan 		 * If NPIV Fabric support has just been established on
2874*82527734SSukumar Swaminathan 		 * the physical port, then notify the vports of the
2875*82527734SSukumar Swaminathan 		 * link up
2876*82527734SSukumar Swaminathan 		 */
2877*82527734SSukumar Swaminathan 		if ((lvpi == 0) &&
2878*82527734SSukumar Swaminathan 		    (hba->flag & FC_NPIV_ENABLED) &&
2879*82527734SSukumar Swaminathan 		    (hba->flag & FC_NPIV_SUPPORTED)) {
2880*82527734SSukumar Swaminathan 			/* Skip the physical port */
2881*82527734SSukumar Swaminathan 			for (i = 1; i < MAX_VPORTS; i++) {
2882*82527734SSukumar Swaminathan 				vport = &VPORT(i);
2883*82527734SSukumar Swaminathan 
2884*82527734SSukumar Swaminathan 				if (!(vport->flag & EMLXS_PORT_BOUND) ||
2885*82527734SSukumar Swaminathan 				    !(vport->flag & EMLXS_PORT_ENABLE)) {
2886*82527734SSukumar Swaminathan 					continue;
2887*82527734SSukumar Swaminathan 				}
2888*82527734SSukumar Swaminathan 
2889*82527734SSukumar Swaminathan 				emlxs_port_online(vport);
2890*82527734SSukumar Swaminathan 			}
2891fcf3ce44SJohn Forte 		}
2892fcf3ce44SJohn Forte 	}
2893291a2b48SSukumar Swaminathan 
2894*82527734SSukumar Swaminathan 	if (mbq->iocbq == (uint8_t *)1) {
2895*82527734SSukumar Swaminathan 		mbq->iocbq = NULL;
2896*82527734SSukumar Swaminathan 		(void) emlxs_mb_unreg_did(port, ldid, NULL, NULL, NULL);
2897*82527734SSukumar Swaminathan 	}
2898fcf3ce44SJohn Forte 
2899*82527734SSukumar Swaminathan #ifdef DHCHAP_SUPPORT
2900*82527734SSukumar Swaminathan 	if (mbq->sbp || mbq->ubp) {
2901*82527734SSukumar Swaminathan 		if (emlxs_dhc_auth_start(port, ndlp, mbq->sbp,
2902*82527734SSukumar Swaminathan 		    mbq->ubp) == 0) {
2903*82527734SSukumar Swaminathan 			/* Auth started - auth completion will */
2904*82527734SSukumar Swaminathan 			/* handle sbp and ubp now */
2905*82527734SSukumar Swaminathan 			mbq->sbp = NULL;
2906*82527734SSukumar Swaminathan 			mbq->ubp = NULL;
2907fcf3ce44SJohn Forte 		}
2908fcf3ce44SJohn Forte 	}
2909*82527734SSukumar Swaminathan #endif	/* DHCHAP_SUPPORT */
2910*82527734SSukumar Swaminathan 
2911*82527734SSukumar Swaminathan #ifdef SFCT_SUPPORT
2912*82527734SSukumar Swaminathan 	if (mbq->sbp && ((emlxs_buf_t *)mbq->sbp)->fct_cmd) {
2913*82527734SSukumar Swaminathan 		emlxs_buf_t *cmd_sbp = (emlxs_buf_t *)mbq->sbp;
2914*82527734SSukumar Swaminathan 
2915*82527734SSukumar Swaminathan 		if (cmd_sbp->fct_state == EMLXS_FCT_REG_PENDING) {
2916*82527734SSukumar Swaminathan 			mbq->sbp = NULL;
2917291a2b48SSukumar Swaminathan 
2918*82527734SSukumar Swaminathan 			mutex_enter(&EMLXS_PKT_LOCK);
2919*82527734SSukumar Swaminathan 			cmd_sbp->node = ndlp;
2920*82527734SSukumar Swaminathan 			cv_broadcast(&EMLXS_PKT_CV);
2921*82527734SSukumar Swaminathan 			mutex_exit(&EMLXS_PKT_LOCK);
2922*82527734SSukumar Swaminathan 		}
2923*82527734SSukumar Swaminathan 	}
2924*82527734SSukumar Swaminathan #endif /* SFCT_SUPPORT */
2925fcf3ce44SJohn Forte 	return (0);
2926fcf3ce44SJohn Forte 
2927*82527734SSukumar Swaminathan } /* emlxs_cmpl_reg_did() */
2928fcf3ce44SJohn Forte 
2929fcf3ce44SJohn Forte 
2930fcf3ce44SJohn Forte /*
2931291a2b48SSukumar Swaminathan  * emlxs_mb_reg_did  Issue a REG_LOGIN mailbox command
2932fcf3ce44SJohn Forte  */
2933fcf3ce44SJohn Forte extern uint32_t
2934fcf3ce44SJohn Forte emlxs_mb_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param,
2935fcf3ce44SJohn Forte     emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq)
2936fcf3ce44SJohn Forte {
2937291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
2938291a2b48SSukumar Swaminathan 	MATCHMAP	*mp;
2939291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
2940291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
2941*82527734SSukumar Swaminathan 	NODELIST	*node;
2942*82527734SSukumar Swaminathan 	RPIobj_t	*rp = NULL;
2943291a2b48SSukumar Swaminathan 	uint32_t	rval;
2944fcf3ce44SJohn Forte 
2945fcf3ce44SJohn Forte 	/* Check for invalid node ids to register */
2946291a2b48SSukumar Swaminathan 	if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
2947291a2b48SSukumar Swaminathan 		return (1);
2948291a2b48SSukumar Swaminathan 	}
2949291a2b48SSukumar Swaminathan 
2950291a2b48SSukumar Swaminathan 	if (did & 0xff000000) {
2951fcf3ce44SJohn Forte 		return (1);
2952fcf3ce44SJohn Forte 	}
2953291a2b48SSukumar Swaminathan 
2954fcf3ce44SJohn Forte 	if ((rval = emlxs_mb_check_sparm(hba, param))) {
2955fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2956291a2b48SSukumar Swaminathan 		    "Invalid service parameters. did=%06x rval=%d", did,
2957291a2b48SSukumar Swaminathan 		    rval);
2958fcf3ce44SJohn Forte 
2959fcf3ce44SJohn Forte 		return (1);
2960fcf3ce44SJohn Forte 	}
2961291a2b48SSukumar Swaminathan 
2962fcf3ce44SJohn Forte 	/* Check if the node limit has been reached */
2963fcf3ce44SJohn Forte 	if (port->node_count >= hba->max_nodes) {
2964fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2965291a2b48SSukumar Swaminathan 		    "Limit reached. did=%06x count=%d", did,
2966291a2b48SSukumar Swaminathan 		    port->node_count);
2967fcf3ce44SJohn Forte 
2968fcf3ce44SJohn Forte 		return (1);
2969fcf3ce44SJohn Forte 	}
2970291a2b48SSukumar Swaminathan 
2971*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
2972*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2973*82527734SSukumar Swaminathan 		    "Unable to allocate mailbox. did=%x", did);
2974*82527734SSukumar Swaminathan 
2975fcf3ce44SJohn Forte 		return (1);
2976fcf3ce44SJohn Forte 	}
2977*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
2978291a2b48SSukumar Swaminathan 
2979fcf3ce44SJohn Forte 	/* Build login request */
2980*82527734SSukumar Swaminathan 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF, 1)) == 0) {
2981*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
2982*82527734SSukumar Swaminathan 		    "Unable to allocate buffer. did=%x", did);
2983*82527734SSukumar Swaminathan 
2984fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
2985fcf3ce44SJohn Forte 		return (1);
2986fcf3ce44SJohn Forte 	}
2987fcf3ce44SJohn Forte 
2988*82527734SSukumar Swaminathan 	/*
2989*82527734SSukumar Swaminathan 	 * If we are SLI4, the RPI number gets assigned by the driver.
2990*82527734SSukumar Swaminathan 	 * For SLI3, the firmware assigns the RPI number.
2991*82527734SSukumar Swaminathan 	 */
2992*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
2993*82527734SSukumar Swaminathan 		node = emlxs_node_find_did(port, did);
2994*82527734SSukumar Swaminathan 		rp = EMLXS_NODE_TO_RPI(hba, node);
2995*82527734SSukumar Swaminathan 
2996*82527734SSukumar Swaminathan 		if (!rp) {
2997*82527734SSukumar Swaminathan 			rp = emlxs_sli4_alloc_rpi(port);
2998*82527734SSukumar Swaminathan 		}
2999*82527734SSukumar Swaminathan 
3000*82527734SSukumar Swaminathan 		if (!rp) {
3001*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
3002*82527734SSukumar Swaminathan 			    "Unable to get an rpi. did=%x", did);
3003*82527734SSukumar Swaminathan 
3004*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3005*82527734SSukumar Swaminathan 			return (1);
3006*82527734SSukumar Swaminathan 		}
3007*82527734SSukumar Swaminathan 		rp->state &= ~RESOURCE_RPI_PAUSED;
3008*82527734SSukumar Swaminathan 	}
3009*82527734SSukumar Swaminathan 
3010291a2b48SSukumar Swaminathan 	bcopy((void *)param, (void *)mp->virt, sizeof (SERV_PARM));
3011291a2b48SSukumar Swaminathan 
3012fcf3ce44SJohn Forte 	mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
3013*82527734SSukumar Swaminathan 	mb->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys);
3014*82527734SSukumar Swaminathan 	mb->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys);
3015fcf3ce44SJohn Forte 	mb->un.varRegLogin.did = did;
3016fcf3ce44SJohn Forte 	mb->un.varWords[30] = 0;	/* flags */
3017fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_REG_LOGIN64;
3018fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3019*82527734SSukumar Swaminathan 	mb->un.varRegLogin.vpi = port->vpi + hba->vpi_base;
3020*82527734SSukumar Swaminathan 	mb->un.varRegLogin.rpi = (rp)? rp->RPI: 0;
3021fcf3ce44SJohn Forte 
3022fcf3ce44SJohn Forte 	mbq->sbp = (uint8_t *)sbp;
3023fcf3ce44SJohn Forte 	mbq->ubp = (uint8_t *)ubp;
3024fcf3ce44SJohn Forte 	mbq->iocbq = (uint8_t *)iocbq;
3025fcf3ce44SJohn Forte 	mbq->bp = (uint8_t *)mp;
3026*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_reg_did;
3027fcf3ce44SJohn Forte 
3028*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3029*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3030fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3031*82527734SSukumar Swaminathan 		if (rp) {
3032*82527734SSukumar Swaminathan 			emlxs_sli4_free_rpi(hba, rp);
3033*82527734SSukumar Swaminathan 		}
3034fcf3ce44SJohn Forte 	}
3035291a2b48SSukumar Swaminathan 
3036fcf3ce44SJohn Forte 	return (0);
3037fcf3ce44SJohn Forte 
3038fcf3ce44SJohn Forte } /* emlxs_mb_reg_did() */
3039fcf3ce44SJohn Forte 
3040fcf3ce44SJohn Forte /*
3041291a2b48SSukumar Swaminathan  * emlxs_mb_unreg_rpi  Issue a UNREG_LOGIN mailbox command
3042fcf3ce44SJohn Forte  */
3043fcf3ce44SJohn Forte extern uint32_t
3044fcf3ce44SJohn Forte emlxs_mb_unreg_rpi(emlxs_port_t *port, uint32_t rpi, emlxs_buf_t *sbp,
3045fcf3ce44SJohn Forte     fc_unsol_buf_t *ubp, IOCBQ *iocbq)
3046fcf3ce44SJohn Forte {
3047291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
3048291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
3049291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
3050291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
3051*82527734SSukumar Swaminathan 	int rval;
3052fcf3ce44SJohn Forte 
3053fcf3ce44SJohn Forte 	if (rpi != 0xffff) {
3054fcf3ce44SJohn Forte 		/* Make sure the node does already exist */
3055fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_rpi(port, rpi);
3056fcf3ce44SJohn Forte 
3057fcf3ce44SJohn Forte 
3058fcf3ce44SJohn Forte 		if (ndlp) {
3059fcf3ce44SJohn Forte 			/*
3060291a2b48SSukumar Swaminathan 			 * If we just unregistered the host node then
3061291a2b48SSukumar Swaminathan 			 * clear the host DID
3062fcf3ce44SJohn Forte 			 */
3063fcf3ce44SJohn Forte 			if (ndlp->nlp_DID == port->did) {
3064fcf3ce44SJohn Forte 				port->did = 0;
3065fcf3ce44SJohn Forte 			}
3066291a2b48SSukumar Swaminathan 
3067fcf3ce44SJohn Forte 			/* remove it */
3068fcf3ce44SJohn Forte 			emlxs_node_rm(port, ndlp);
3069fcf3ce44SJohn Forte 
3070fcf3ce44SJohn Forte 		} else {
3071fcf3ce44SJohn Forte 			return (1);
3072fcf3ce44SJohn Forte 		}
3073fcf3ce44SJohn Forte 	} else {	/* Unreg all */
3074291a2b48SSukumar Swaminathan 
3075fcf3ce44SJohn Forte 		emlxs_node_destroy_all(port);
3076fcf3ce44SJohn Forte 	}
3077fcf3ce44SJohn Forte 
3078*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
3079fcf3ce44SJohn Forte 		return (1);
3080fcf3ce44SJohn Forte 	}
3081291a2b48SSukumar Swaminathan 
3082291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
3083fcf3ce44SJohn Forte 
3084*82527734SSukumar Swaminathan #define	INDEX_INDICATOR_VPI	1
3085*82527734SSukumar Swaminathan 
3086*82527734SSukumar Swaminathan 	if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) && (rpi == 0xffff)) {
3087*82527734SSukumar Swaminathan 		mb->un.varUnregLogin.ll = INDEX_INDICATOR_VPI;
3088*82527734SSukumar Swaminathan 		mb->un.varUnregLogin.rpi = (uint16_t)port->vpi + hba->vpi_base;
3089*82527734SSukumar Swaminathan 	} else {
3090*82527734SSukumar Swaminathan 		mb->un.varUnregLogin.rpi = (uint16_t)rpi;
3091*82527734SSukumar Swaminathan 	}
3092fcf3ce44SJohn Forte 
3093*82527734SSukumar Swaminathan 	mb->un.varUnregLogin.vpi = port->vpi + hba->vpi_base;
3094fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_UNREG_LOGIN;
3095fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3096fcf3ce44SJohn Forte 	mbq->sbp = (uint8_t *)sbp;
3097fcf3ce44SJohn Forte 	mbq->ubp = (uint8_t *)ubp;
3098fcf3ce44SJohn Forte 	mbq->iocbq = (uint8_t *)iocbq;
3099*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
3100fcf3ce44SJohn Forte 
3101*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3102*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3103fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3104fcf3ce44SJohn Forte 	}
3105291a2b48SSukumar Swaminathan 
3106*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3107*82527734SSukumar Swaminathan 		port->outstandingRPIs--;
3108*82527734SSukumar Swaminathan 		if ((port->outstandingRPIs == 0) &&
3109*82527734SSukumar Swaminathan 		    (hba->state == FC_LINK_DOWN)) {
3110*82527734SSukumar Swaminathan 			/* No more RPIs so unreg the VPI */
3111*82527734SSukumar Swaminathan 			(void) emlxs_mb_unreg_vpi(port);
3112*82527734SSukumar Swaminathan 		}
3113*82527734SSukumar Swaminathan 	}
3114*82527734SSukumar Swaminathan 
3115fcf3ce44SJohn Forte 	return (0);
3116fcf3ce44SJohn Forte } /* emlxs_mb_unreg_rpi() */
3117fcf3ce44SJohn Forte 
3118*82527734SSukumar Swaminathan 
3119fcf3ce44SJohn Forte /*
3120291a2b48SSukumar Swaminathan  * emlxs_mb_unreg_did  Issue a UNREG_DID mailbox command
3121fcf3ce44SJohn Forte  */
3122fcf3ce44SJohn Forte extern uint32_t
3123fcf3ce44SJohn Forte emlxs_mb_unreg_did(emlxs_port_t *port, uint32_t did, emlxs_buf_t *sbp,
3124fcf3ce44SJohn Forte     fc_unsol_buf_t *ubp, IOCBQ *iocbq)
3125fcf3ce44SJohn Forte {
3126291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
3127291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
3128291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
3129291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
3130*82527734SSukumar Swaminathan 	int rval = 0;
3131fcf3ce44SJohn Forte 
3132fcf3ce44SJohn Forte 	/*
3133fcf3ce44SJohn Forte 	 * Unregister all default RPIs if did == 0xffffffff
3134fcf3ce44SJohn Forte 	 */
3135fcf3ce44SJohn Forte 	if (did != 0xffffffff) {
3136fcf3ce44SJohn Forte 		/* Check for base node */
3137*82527734SSukumar Swaminathan 		if (did == BCAST_DID) {
3138fcf3ce44SJohn Forte 			/* just flush base node */
3139fcf3ce44SJohn Forte 			(void) emlxs_tx_node_flush(port, &port->node_base,
3140fcf3ce44SJohn Forte 			    0, 0, 0);
3141291a2b48SSukumar Swaminathan 			(void) emlxs_chipq_node_flush(port, 0,
3142291a2b48SSukumar Swaminathan 			    &port->node_base, 0);
3143fcf3ce44SJohn Forte 
3144fcf3ce44SJohn Forte 			/* Return now */
3145fcf3ce44SJohn Forte 			return (1);
3146fcf3ce44SJohn Forte 		}
3147291a2b48SSukumar Swaminathan 
3148291a2b48SSukumar Swaminathan 
3149fcf3ce44SJohn Forte 		/*
3150fcf3ce44SJohn Forte 		 * A zero DID means that we are trying to unreg the host node
3151fcf3ce44SJohn Forte 		 * after a link bounce
3152fcf3ce44SJohn Forte 		 */
3153fcf3ce44SJohn Forte 
3154fcf3ce44SJohn Forte 		/*
3155fcf3ce44SJohn Forte 		 * If the prev_did == 0 then the adapter has been reset and
3156fcf3ce44SJohn Forte 		 * there is no need in unregistering
3157fcf3ce44SJohn Forte 		 */
3158fcf3ce44SJohn Forte 
3159fcf3ce44SJohn Forte 		/*
3160291a2b48SSukumar Swaminathan 		 * If the prev_did != 0 then we can look for the hosts
3161291a2b48SSukumar Swaminathan 		 * last known DID node
3162fcf3ce44SJohn Forte 		 */
3163fcf3ce44SJohn Forte 
3164fcf3ce44SJohn Forte 		if (did == 0) {
3165fcf3ce44SJohn Forte 			if (port->prev_did == 0) {
3166fcf3ce44SJohn Forte 				return (1);
3167fcf3ce44SJohn Forte 			}
3168291a2b48SSukumar Swaminathan 
3169fcf3ce44SJohn Forte 			did = port->prev_did;
3170fcf3ce44SJohn Forte 		}
3171291a2b48SSukumar Swaminathan 
3172fcf3ce44SJohn Forte 		/* Make sure the node does already exist */
3173fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_did(port, did);
3174fcf3ce44SJohn Forte 
3175fcf3ce44SJohn Forte 		if (ndlp) {
3176*82527734SSukumar Swaminathan 			if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3177*82527734SSukumar Swaminathan 				/* Use UNREG_RPI for SLI4 */
3178*82527734SSukumar Swaminathan 				if (ndlp->nlp_Rpi != 0xffff) {
3179*82527734SSukumar Swaminathan 					rval = emlxs_mb_unreg_rpi(port,
3180*82527734SSukumar Swaminathan 					    ndlp->nlp_Rpi, sbp, ubp, iocbq);
3181*82527734SSukumar Swaminathan 				}
3182*82527734SSukumar Swaminathan 				return (rval);
3183*82527734SSukumar Swaminathan 			}
3184fcf3ce44SJohn Forte 			/* remove it */
3185fcf3ce44SJohn Forte 			emlxs_node_rm(port, ndlp);
3186fcf3ce44SJohn Forte 
3187fcf3ce44SJohn Forte 			/*
3188291a2b48SSukumar Swaminathan 			 * If we just unregistered the host node then
3189291a2b48SSukumar Swaminathan 			 * clear the host DID
3190fcf3ce44SJohn Forte 			 */
3191fcf3ce44SJohn Forte 			if (did == port->did) {
3192fcf3ce44SJohn Forte 				port->did = 0;
3193fcf3ce44SJohn Forte 			}
3194291a2b48SSukumar Swaminathan 
3195fcf3ce44SJohn Forte 		} else {
3196fcf3ce44SJohn Forte 			return (1);
3197fcf3ce44SJohn Forte 		}
3198*82527734SSukumar Swaminathan 	} else {
3199*82527734SSukumar Swaminathan 		/* SLI4 doesn't have dflt RPIs in SLI Port */
3200*82527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3201*82527734SSukumar Swaminathan 			return (0);
3202*82527734SSukumar Swaminathan 		}
3203fcf3ce44SJohn Forte 	}
3204291a2b48SSukumar Swaminathan 
3205*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
3206fcf3ce44SJohn Forte 		return (1);
3207fcf3ce44SJohn Forte 	}
3208291a2b48SSukumar Swaminathan 
3209291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
3210fcf3ce44SJohn Forte 	mb->un.varUnregDID.did = did;
3211*82527734SSukumar Swaminathan 	mb->un.varUnregDID.vpi = port->vpi + hba->vpi_base;
3212fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_UNREG_D_ID;
3213fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3214fcf3ce44SJohn Forte 	mbq->sbp = (uint8_t *)sbp;
3215fcf3ce44SJohn Forte 	mbq->ubp = (uint8_t *)ubp;
3216fcf3ce44SJohn Forte 	mbq->iocbq = (uint8_t *)iocbq;
3217*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3218fcf3ce44SJohn Forte 
3219*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3220*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3221fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3222fcf3ce44SJohn Forte 	}
3223291a2b48SSukumar Swaminathan 
3224fcf3ce44SJohn Forte 	return (0);
3225fcf3ce44SJohn Forte 
3226*82527734SSukumar Swaminathan } /* emlxs_mb_unreg_did() */
3227fcf3ce44SJohn Forte 
3228fcf3ce44SJohn Forte 
3229fcf3ce44SJohn Forte /*
3230291a2b48SSukumar Swaminathan  * emlxs_mb_set_mask   Issue a SET MASK mailbox command
3231fcf3ce44SJohn Forte  */
3232291a2b48SSukumar Swaminathan /*ARGSUSED*/
3233fcf3ce44SJohn Forte static void
3234*82527734SSukumar Swaminathan emlxs_mb_set_mask(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t mask,
3235fcf3ce44SJohn Forte     uint32_t ringno)
3236fcf3ce44SJohn Forte {
3237*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3238*82527734SSukumar Swaminathan 
3239291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3240fcf3ce44SJohn Forte 
3241fcf3ce44SJohn Forte 	mb->un.varWords[0] = 0x11223344;	/* set passwd */
3242fcf3ce44SJohn Forte 	mb->un.varWords[1] = mask;	/* set mask */
3243fcf3ce44SJohn Forte 	mb->un.varWords[2] = ringno;	/* set ringno */
3244fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_MASK;
3245fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3246*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3247*82527734SSukumar Swaminathan 
3248*82527734SSukumar Swaminathan } /* emlxs_mb_set_mask() */
3249fcf3ce44SJohn Forte 
3250fcf3ce44SJohn Forte 
3251fcf3ce44SJohn Forte /*
3252291a2b48SSukumar Swaminathan  * emlxs_mb_set_debug  Issue a special debug mailbox command
3253fcf3ce44SJohn Forte  */
3254291a2b48SSukumar Swaminathan /*ARGSUSED*/
3255fcf3ce44SJohn Forte static void
3256*82527734SSukumar Swaminathan emlxs_mb_set_debug(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t word0,
3257fcf3ce44SJohn Forte     uint32_t word1, uint32_t word2)
3258fcf3ce44SJohn Forte {
3259*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3260*82527734SSukumar Swaminathan 
3261291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3262fcf3ce44SJohn Forte 
3263fcf3ce44SJohn Forte 	mb->un.varWords[0] = word0;
3264fcf3ce44SJohn Forte 	mb->un.varWords[1] = word1;
3265fcf3ce44SJohn Forte 	mb->un.varWords[2] = word2;
3266fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_DEBUG;
3267fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3268*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3269*82527734SSukumar Swaminathan 
3270*82527734SSukumar Swaminathan } /* emlxs_mb_set_debug() */
3271fcf3ce44SJohn Forte 
3272fcf3ce44SJohn Forte 
3273fcf3ce44SJohn Forte /*
3274291a2b48SSukumar Swaminathan  * emlxs_mb_set_var   Issue a special debug mbox command to write slim
3275fcf3ce44SJohn Forte  */
3276291a2b48SSukumar Swaminathan /*ARGSUSED*/
3277fcf3ce44SJohn Forte extern void
3278*82527734SSukumar Swaminathan emlxs_mb_set_var(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t addr,
3279291a2b48SSukumar Swaminathan     uint32_t value)
3280fcf3ce44SJohn Forte {
3281*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3282*82527734SSukumar Swaminathan 
3283291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3284fcf3ce44SJohn Forte 
3285fcf3ce44SJohn Forte 	/* addr = 0x090597 is AUTO ABTS disable for ELS commands */
3286fcf3ce44SJohn Forte 	/* addr = 0x052198 is DELAYED ABTS enable for ELS commands */
3287fcf3ce44SJohn Forte 	/* addr = 0x100506 is for setting PCI MAX READ value */
3288fcf3ce44SJohn Forte 
3289fcf3ce44SJohn Forte 	/*
3290fcf3ce44SJohn Forte 	 * Always turn on DELAYED ABTS for ELS timeouts
3291fcf3ce44SJohn Forte 	 */
3292fcf3ce44SJohn Forte 	if ((addr == 0x052198) && (value == 0)) {
3293fcf3ce44SJohn Forte 		value = 1;
3294fcf3ce44SJohn Forte 	}
3295291a2b48SSukumar Swaminathan 
3296fcf3ce44SJohn Forte 	mb->un.varWords[0] = addr;
3297fcf3ce44SJohn Forte 	mb->un.varWords[1] = value;
3298fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_VARIABLE;
3299fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3300*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3301*82527734SSukumar Swaminathan 
3302*82527734SSukumar Swaminathan } /* emlxs_mb_set_var() */
3303fcf3ce44SJohn Forte 
3304fcf3ce44SJohn Forte 
3305fcf3ce44SJohn Forte /*
3306fcf3ce44SJohn Forte  * Disable Traffic Cop
3307fcf3ce44SJohn Forte  */
3308291a2b48SSukumar Swaminathan /*ARGSUSED*/
3309fcf3ce44SJohn Forte extern void
3310*82527734SSukumar Swaminathan emlxs_disable_tc(emlxs_hba_t *hba, MAILBOXQ *mbq)
3311fcf3ce44SJohn Forte {
3312*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3313*82527734SSukumar Swaminathan 
3314291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3315fcf3ce44SJohn Forte 
3316fcf3ce44SJohn Forte 	mb->un.varWords[0] = 0x50797;
3317fcf3ce44SJohn Forte 	mb->un.varWords[1] = 0;
3318fcf3ce44SJohn Forte 	mb->un.varWords[2] = 0xfffffffe;
3319fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_SET_VARIABLE;
3320fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3321*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3322fcf3ce44SJohn Forte 
3323*82527734SSukumar Swaminathan } /* emlxs_disable_tc() */
3324fcf3ce44SJohn Forte 
3325fcf3ce44SJohn Forte 
3326fcf3ce44SJohn Forte extern void
3327*82527734SSukumar Swaminathan emlxs_mb_config_hbq(emlxs_hba_t *hba, MAILBOXQ *mbq, int hbq_id)
3328fcf3ce44SJohn Forte {
3329291a2b48SSukumar Swaminathan 	HBQ_INIT_t	*hbq;
3330*82527734SSukumar Swaminathan 	MAILBOX		*mb = (MAILBOX *)mbq;
3331291a2b48SSukumar Swaminathan 	int		i;
3332fcf3ce44SJohn Forte 
3333291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3334fcf3ce44SJohn Forte 
3335*82527734SSukumar Swaminathan 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
3336fcf3ce44SJohn Forte 
3337fcf3ce44SJohn Forte 	mb->un.varCfgHbq.hbqId = hbq_id;
3338fcf3ce44SJohn Forte 	mb->un.varCfgHbq.numEntries = hbq->HBQ_numEntries;
3339fcf3ce44SJohn Forte 	mb->un.varCfgHbq.recvNotify = hbq->HBQ_recvNotify;
3340fcf3ce44SJohn Forte 	mb->un.varCfgHbq.numMask = hbq->HBQ_num_mask;
3341fcf3ce44SJohn Forte 	mb->un.varCfgHbq.profile = hbq->HBQ_profile;
3342fcf3ce44SJohn Forte 	mb->un.varCfgHbq.ringMask = hbq->HBQ_ringMask;
3343fcf3ce44SJohn Forte 	mb->un.varCfgHbq.headerLen = hbq->HBQ_headerLen;
3344fcf3ce44SJohn Forte 	mb->un.varCfgHbq.logEntry = hbq->HBQ_logEntry;
3345*82527734SSukumar Swaminathan 	mb->un.varCfgHbq.hbqaddrLow = PADDR_LO(hbq->HBQ_host_buf.phys);
3346*82527734SSukumar Swaminathan 	mb->un.varCfgHbq.hbqaddrHigh = PADDR_HI(hbq->HBQ_host_buf.phys);
3347fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_HBQ;
3348fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3349*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL;
3350fcf3ce44SJohn Forte 
3351fcf3ce44SJohn Forte 	/* Copy info for profiles 2,3,5. Other profiles this area is reserved */
3352fcf3ce44SJohn Forte 	if ((hbq->HBQ_profile == 2) || (hbq->HBQ_profile == 3) ||
3353fcf3ce44SJohn Forte 	    (hbq->HBQ_profile == 5)) {
3354fcf3ce44SJohn Forte 		bcopy(&hbq->profiles.allprofiles,
3355fcf3ce44SJohn Forte 		    &mb->un.varCfgHbq.profiles.allprofiles,
3356fcf3ce44SJohn Forte 		    sizeof (hbq->profiles));
3357fcf3ce44SJohn Forte 	}
3358291a2b48SSukumar Swaminathan 
3359fcf3ce44SJohn Forte 	/* Return if no rctl / type masks for this HBQ */
3360fcf3ce44SJohn Forte 	if (!hbq->HBQ_num_mask) {
3361fcf3ce44SJohn Forte 		return;
3362fcf3ce44SJohn Forte 	}
3363291a2b48SSukumar Swaminathan 
3364fcf3ce44SJohn Forte 	/* Otherwise we setup specific rctl / type masks for this HBQ */
3365fcf3ce44SJohn Forte 	for (i = 0; i < hbq->HBQ_num_mask; i++) {
3366291a2b48SSukumar Swaminathan 		mb->un.varCfgHbq.hbqMasks[i].tmatch =
3367291a2b48SSukumar Swaminathan 		    hbq->HBQ_Masks[i].tmatch;
3368fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].tmask = hbq->HBQ_Masks[i].tmask;
3369fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].rctlmatch =
3370fcf3ce44SJohn Forte 		    hbq->HBQ_Masks[i].rctlmatch;
3371fcf3ce44SJohn Forte 		mb->un.varCfgHbq.hbqMasks[i].rctlmask =
3372fcf3ce44SJohn Forte 		    hbq->HBQ_Masks[i].rctlmask;
3373fcf3ce44SJohn Forte 	}
3374fcf3ce44SJohn Forte 
3375fcf3ce44SJohn Forte 	return;
3376fcf3ce44SJohn Forte 
3377fcf3ce44SJohn Forte } /* emlxs_mb_config_hbq() */
3378fcf3ce44SJohn Forte 
3379*82527734SSukumar Swaminathan int
3380*82527734SSukumar Swaminathan emlxs_cmpl_init_vpi(void *arg1, MAILBOXQ *mbq)
3381*82527734SSukumar Swaminathan {
3382*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
3383*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
3384*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
3385*82527734SSukumar Swaminathan 	MAILBOX4 *mb;
3386*82527734SSukumar Swaminathan 
3387*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq;
3388*82527734SSukumar Swaminathan 
3389*82527734SSukumar Swaminathan 	if (mb->mbxStatus == MBX_SUCCESS) {
3390*82527734SSukumar Swaminathan 		vport = &VPORT((mb->un.varInitVPI4.vpi - hba->vpi_base));
3391*82527734SSukumar Swaminathan 		vport->flag |= EMLXS_PORT_INIT_VPI_CMPL;
3392*82527734SSukumar Swaminathan 	}
3393*82527734SSukumar Swaminathan 
3394*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
3395*82527734SSukumar Swaminathan 	    "CMPL init_vpi: stats: %x", mb->mbxStatus);
3396*82527734SSukumar Swaminathan 
3397*82527734SSukumar Swaminathan 	return (0);
3398*82527734SSukumar Swaminathan 
3399*82527734SSukumar Swaminathan } /* emlxs_cmpl_init_vpi() */
3400fcf3ce44SJohn Forte 
3401fcf3ce44SJohn Forte 
3402fcf3ce44SJohn Forte extern uint32_t
3403*82527734SSukumar Swaminathan emlxs_mb_init_vpi(emlxs_port_t *port)
3404fcf3ce44SJohn Forte {
3405291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
3406*82527734SSukumar Swaminathan 	emlxs_port_t    *phy_port = &PPORT;
3407291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
3408*82527734SSukumar Swaminathan 	MAILBOX4	*mb;
3409*82527734SSukumar Swaminathan 	int rval;
3410*82527734SSukumar Swaminathan 
3411*82527734SSukumar Swaminathan 	if (!(hba->flag & FC_NPIV_ENABLED)) {
3412*82527734SSukumar Swaminathan 		return (0);
3413*82527734SSukumar Swaminathan 	}
3414*82527734SSukumar Swaminathan 
3415*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
3416*82527734SSukumar Swaminathan 		return (1);
3417*82527734SSukumar Swaminathan 	}
3418*82527734SSukumar Swaminathan 
3419*82527734SSukumar Swaminathan 
3420*82527734SSukumar Swaminathan 	mb = (MAILBOX4 *)mbq->mbox;
3421*82527734SSukumar Swaminathan 	bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
3422*82527734SSukumar Swaminathan 	mbq->nonembed = NULL;
3423*82527734SSukumar Swaminathan 	mb->un.varInitVPI4.vfi = phy_port->VFIp->VFI;
3424*82527734SSukumar Swaminathan 	mb->un.varInitVPI4.vpi = port->vpi + hba->vpi_base;
3425*82527734SSukumar Swaminathan 	mb->mbxCommand = MBX_INIT_VPI;
3426*82527734SSukumar Swaminathan 	mb->mbxOwner = OWN_HOST;
3427*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = emlxs_cmpl_init_vpi;
3428*82527734SSukumar Swaminathan 
3429*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0);
3430*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3431*82527734SSukumar Swaminathan 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3432*82527734SSukumar Swaminathan 	}
3433*82527734SSukumar Swaminathan 
3434*82527734SSukumar Swaminathan 	return (0);
3435*82527734SSukumar Swaminathan 
3436*82527734SSukumar Swaminathan } /* emlxs_mb_init_vpi() */
3437*82527734SSukumar Swaminathan 
3438*82527734SSukumar Swaminathan 
3439*82527734SSukumar Swaminathan /* Leadville wll start sending PLOGI right after */
3440*82527734SSukumar Swaminathan /* FDISC completion, we need to wait for REG_VPI */
3441*82527734SSukumar Swaminathan /* completion, before sending back the FDISK request */
3442*82527734SSukumar Swaminathan /* Also, allocate a node structure for Fabric port */
3443*82527734SSukumar Swaminathan int
3444*82527734SSukumar Swaminathan emlxs_cmpl_reg_vpi(void *arg1, MAILBOXQ *mbq)
3445*82527734SSukumar Swaminathan {
3446*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
3447*82527734SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
3448*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
3449*82527734SSukumar Swaminathan 	MAILBOX *mb;
3450*82527734SSukumar Swaminathan 	emlxs_buf_t *sbp;
3451*82527734SSukumar Swaminathan 	SERV_PARM *sp;
3452*82527734SSukumar Swaminathan 	fc_packet_t *pkt;
3453*82527734SSukumar Swaminathan 	NODELIST *ndlp;
3454*82527734SSukumar Swaminathan 	uint32_t ldid;
3455*82527734SSukumar Swaminathan 	uint8_t *wwn;
3456*82527734SSukumar Swaminathan 
3457*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
3458*82527734SSukumar Swaminathan 
3459*82527734SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
3460*82527734SSukumar Swaminathan 	    "CMPL reg_vpi: stats: %x", mb->mbxStatus);
3461*82527734SSukumar Swaminathan 
3462*82527734SSukumar Swaminathan 	if (mb->mbxStatus != MBX_SUCCESS) {
3463*82527734SSukumar Swaminathan 		return (0);
3464*82527734SSukumar Swaminathan 	}
3465*82527734SSukumar Swaminathan 
3466*82527734SSukumar Swaminathan 	vport = &VPORT((mb->un.varRegVpi.vpi - hba->vpi_base));
3467*82527734SSukumar Swaminathan 	vport->flag |= EMLXS_PORT_REG_VPI_CMPL;
3468*82527734SSukumar Swaminathan 	sbp = (emlxs_buf_t *)mbq->sbp;
3469*82527734SSukumar Swaminathan 
3470*82527734SSukumar Swaminathan 	if (!sbp) {
3471*82527734SSukumar Swaminathan 		return (0);
3472*82527734SSukumar Swaminathan 	}
3473*82527734SSukumar Swaminathan 
3474*82527734SSukumar Swaminathan 	pkt = PRIV2PKT(sbp);
3475*82527734SSukumar Swaminathan 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
3476*82527734SSukumar Swaminathan 
3477*82527734SSukumar Swaminathan 	vport->VFIp->outstandingVPIs++;
3478*82527734SSukumar Swaminathan 
3479*82527734SSukumar Swaminathan 	ldid = FABRIC_DID;
3480*82527734SSukumar Swaminathan 	ndlp = emlxs_node_find_did(vport, ldid);
3481*82527734SSukumar Swaminathan 
3482*82527734SSukumar Swaminathan 	if (!ndlp) {
3483*82527734SSukumar Swaminathan 		/* Attempt to create a node */
3484*82527734SSukumar Swaminathan 		if ((ndlp = (NODELIST *)emlxs_mem_get(hba, MEM_NLP, 0))) {
3485*82527734SSukumar Swaminathan 			ndlp->nlp_Rpi = 0xffff;
3486*82527734SSukumar Swaminathan 			ndlp->nlp_DID = ldid;
3487*82527734SSukumar Swaminathan 
3488*82527734SSukumar Swaminathan 			bcopy((uint8_t *)sp, (uint8_t *)&ndlp->sparm,
3489*82527734SSukumar Swaminathan 			    sizeof (SERV_PARM));
3490*82527734SSukumar Swaminathan 
3491*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->nodeName,
3492*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_nodename,
3493*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
3494*82527734SSukumar Swaminathan 
3495*82527734SSukumar Swaminathan 			bcopy((uint8_t *)&sp->portName,
3496*82527734SSukumar Swaminathan 			    (uint8_t *)&ndlp->nlp_portname,
3497*82527734SSukumar Swaminathan 			    sizeof (NAME_TYPE));
3498*82527734SSukumar Swaminathan 
3499*82527734SSukumar Swaminathan 			ndlp->nlp_active = 1;
3500*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ct]  |= NLP_CLOSED;
3501*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_els] |= NLP_CLOSED;
3502*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_fcp] |= NLP_CLOSED;
3503*82527734SSukumar Swaminathan 			ndlp->nlp_flag[hba->channel_ip]  |= NLP_CLOSED;
3504*82527734SSukumar Swaminathan 
3505*82527734SSukumar Swaminathan 			/* Add the node */
3506*82527734SSukumar Swaminathan 			emlxs_node_add(vport, ndlp);
3507*82527734SSukumar Swaminathan 
3508*82527734SSukumar Swaminathan 			/* Open the node */
3509*82527734SSukumar Swaminathan 			emlxs_node_open(vport, ndlp, hba->channel_ct);
3510*82527734SSukumar Swaminathan 			emlxs_node_open(vport, ndlp, hba->channel_els);
3511*82527734SSukumar Swaminathan 			emlxs_node_open(vport, ndlp, hba->channel_ip);
3512*82527734SSukumar Swaminathan 			emlxs_node_open(vport, ndlp, hba->channel_fcp);
3513*82527734SSukumar Swaminathan 		} else {
3514*82527734SSukumar Swaminathan 			wwn = (uint8_t *)&sp->portName;
3515*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
3516*82527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
3517*82527734SSukumar Swaminathan 			    "Unable to allocate node. did=%06x "
3518*82527734SSukumar Swaminathan 			    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
3519*82527734SSukumar Swaminathan 			    ldid, wwn[0], wwn[1], wwn[2],
3520*82527734SSukumar Swaminathan 			    wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
3521*82527734SSukumar Swaminathan 
3522*82527734SSukumar Swaminathan 			return (0);
3523*82527734SSukumar Swaminathan 		}
3524*82527734SSukumar Swaminathan 	} else {
3525*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_PORT_LOCK);
3526*82527734SSukumar Swaminathan 
3527*82527734SSukumar Swaminathan 		ndlp->nlp_Rpi = 0xffff;
3528*82527734SSukumar Swaminathan 		ndlp->nlp_DID = ldid;
3529*82527734SSukumar Swaminathan 
3530*82527734SSukumar Swaminathan 		bcopy((uint8_t *)sp,
3531*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->sparm, sizeof (SERV_PARM));
3532*82527734SSukumar Swaminathan 
3533*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->nodeName,
3534*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_nodename, sizeof (NAME_TYPE));
3535*82527734SSukumar Swaminathan 
3536*82527734SSukumar Swaminathan 		bcopy((uint8_t *)&sp->portName,
3537*82527734SSukumar Swaminathan 		    (uint8_t *)&ndlp->nlp_portname, sizeof (NAME_TYPE));
3538*82527734SSukumar Swaminathan 
3539*82527734SSukumar Swaminathan 		wwn = (uint8_t *)&ndlp->nlp_portname;
3540*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_update_msg,
3541*82527734SSukumar Swaminathan 		    "node=%p did=%06x rpi=%x "
3542*82527734SSukumar Swaminathan 		    "wwpn=%02x%02x%02x%02x%02x%02x%02x%02x",
3543*82527734SSukumar Swaminathan 		    ndlp, ndlp->nlp_DID, ndlp->nlp_Rpi, wwn[0],
3544*82527734SSukumar Swaminathan 		    wwn[1], wwn[2], wwn[3], wwn[4], wwn[5], wwn[6], wwn[7]);
3545*82527734SSukumar Swaminathan 
3546*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_PORT_LOCK);
3547*82527734SSukumar Swaminathan 
3548*82527734SSukumar Swaminathan 		/* Open the node */
3549*82527734SSukumar Swaminathan 		emlxs_node_open(vport, ndlp, hba->channel_ct);
3550*82527734SSukumar Swaminathan 		emlxs_node_open(vport, ndlp, hba->channel_els);
3551*82527734SSukumar Swaminathan 		emlxs_node_open(vport, ndlp, hba->channel_ip);
3552*82527734SSukumar Swaminathan 		emlxs_node_open(vport, ndlp, hba->channel_fcp);
3553*82527734SSukumar Swaminathan 	}
3554*82527734SSukumar Swaminathan 
3555*82527734SSukumar Swaminathan 	return (0);
3556*82527734SSukumar Swaminathan } /* emlxs_cmpl_reg_vpi */
3557*82527734SSukumar Swaminathan 
3558*82527734SSukumar Swaminathan 
3559*82527734SSukumar Swaminathan extern uint32_t
3560*82527734SSukumar Swaminathan emlxs_mb_reg_vpi(emlxs_port_t *port, emlxs_buf_t *sbp)
3561*82527734SSukumar Swaminathan {
3562*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
3563*82527734SSukumar Swaminathan 	MAILBOXQ *mbq;
3564*82527734SSukumar Swaminathan 	MAILBOX	*mb;
3565*82527734SSukumar Swaminathan 	int rval;
3566fcf3ce44SJohn Forte 
3567fcf3ce44SJohn Forte 	if (!(hba->flag & FC_NPIV_ENABLED)) {
3568fcf3ce44SJohn Forte 		return (0);
3569fcf3ce44SJohn Forte 	}
3570291a2b48SSukumar Swaminathan 
3571fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
3572fcf3ce44SJohn Forte 
3573fcf3ce44SJohn Forte 	/* Can't reg vpi until ClearLA is sent */
3574fcf3ce44SJohn Forte 	if (hba->state != FC_READY) {
3575fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
3576fcf3ce44SJohn Forte 
3577fcf3ce44SJohn Forte 		return (1);
3578fcf3ce44SJohn Forte 	}
3579291a2b48SSukumar Swaminathan 
3580fcf3ce44SJohn Forte 	/* Must have port id */
3581fcf3ce44SJohn Forte 	if (!port->did) {
3582fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
3583fcf3ce44SJohn Forte 
3584fcf3ce44SJohn Forte 		return (1);
3585fcf3ce44SJohn Forte 	}
3586291a2b48SSukumar Swaminathan 
3587*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
3588fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
3589fcf3ce44SJohn Forte 
3590fcf3ce44SJohn Forte 		return (1);
3591fcf3ce44SJohn Forte 	}
3592291a2b48SSukumar Swaminathan 
3593fcf3ce44SJohn Forte 	port->flag |= EMLXS_PORT_REGISTERED;
3594fcf3ce44SJohn Forte 
3595fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
3596fcf3ce44SJohn Forte 
3597291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
3598*82527734SSukumar Swaminathan 
3599*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3600*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
3601*82527734SSukumar Swaminathan 		mbq->nonembed = NULL;
3602*82527734SSukumar Swaminathan 		mb->un.varRegVpi.vfi = port->VFIp->VFI;
3603*82527734SSukumar Swaminathan 		mbq->mbox_cmpl = emlxs_cmpl_reg_vpi;
3604*82527734SSukumar Swaminathan 	} else {
3605*82527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
3606*82527734SSukumar Swaminathan 		mbq->mbox_cmpl = NULL; /* no cmpl needed */
3607*82527734SSukumar Swaminathan 	}
3608*82527734SSukumar Swaminathan 
3609*82527734SSukumar Swaminathan 	if (sbp) {
3610*82527734SSukumar Swaminathan 		mbq->sbp = (uint8_t *)sbp;
3611*82527734SSukumar Swaminathan 	}
3612*82527734SSukumar Swaminathan 
3613*82527734SSukumar Swaminathan 	mb->un.varRegVpi.vpi = port->vpi + hba->vpi_base;
3614fcf3ce44SJohn Forte 	mb->un.varRegVpi.sid = port->did;
3615fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_REG_VPI;
3616fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3617fcf3ce44SJohn Forte 
3618*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3619*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3620fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3621fcf3ce44SJohn Forte 	}
3622291a2b48SSukumar Swaminathan 
3623fcf3ce44SJohn Forte 	return (0);
3624fcf3ce44SJohn Forte 
3625fcf3ce44SJohn Forte } /* emlxs_mb_reg_vpi() */
3626fcf3ce44SJohn Forte 
3627fcf3ce44SJohn Forte 
3628*82527734SSukumar Swaminathan int
3629*82527734SSukumar Swaminathan emlxs_cmpl_unreg_vpi(void *arg1, MAILBOXQ *mbq)
3630*82527734SSukumar Swaminathan {
3631*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
3632*82527734SSukumar Swaminathan 	emlxs_port_t *vport;
3633*82527734SSukumar Swaminathan 	MAILBOX *mb;
3634*82527734SSukumar Swaminathan 
3635*82527734SSukumar Swaminathan 	mb = (MAILBOX *)mbq;
3636*82527734SSukumar Swaminathan 	if (mb->mbxStatus == MBX_SUCCESS) {
3637*82527734SSukumar Swaminathan 		vport = &VPORT(mb->un.varUnregVpi.vpi);
3638*82527734SSukumar Swaminathan 		vport->flag &= ~EMLXS_PORT_INIT_VPI_CMPL;
3639*82527734SSukumar Swaminathan 		vport->flag &= ~EMLXS_PORT_REG_VPI_CMPL;
3640*82527734SSukumar Swaminathan 	}
3641*82527734SSukumar Swaminathan 	return (0);
3642*82527734SSukumar Swaminathan 
3643*82527734SSukumar Swaminathan } /* emlxs_cmpl_unreg_vpi() */
3644*82527734SSukumar Swaminathan 
3645*82527734SSukumar Swaminathan 
3646fcf3ce44SJohn Forte extern uint32_t
3647fcf3ce44SJohn Forte emlxs_mb_unreg_vpi(emlxs_port_t *port)
3648fcf3ce44SJohn Forte {
3649291a2b48SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
3650291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
3651291a2b48SSukumar Swaminathan 	MAILBOX		*mb;
3652*82527734SSukumar Swaminathan 	VFIobj_t	*vfip;
3653*82527734SSukumar Swaminathan 	FCFIobj_t	*fcfp;
3654*82527734SSukumar Swaminathan 	int		rval;
3655fcf3ce44SJohn Forte 
3656fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
3657fcf3ce44SJohn Forte 
3658fcf3ce44SJohn Forte 	if (!(port->flag & EMLXS_PORT_REGISTERED)) {
3659fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
3660fcf3ce44SJohn Forte 		return (0);
3661fcf3ce44SJohn Forte 	}
3662291a2b48SSukumar Swaminathan 
3663*82527734SSukumar Swaminathan 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
3664fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
3665fcf3ce44SJohn Forte 		return (1);
3666fcf3ce44SJohn Forte 	}
3667291a2b48SSukumar Swaminathan 
3668fcf3ce44SJohn Forte 	port->flag &= ~EMLXS_PORT_REGISTERED;
3669fcf3ce44SJohn Forte 
3670fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
3671fcf3ce44SJohn Forte 
3672291a2b48SSukumar Swaminathan 	mb = (MAILBOX *)mbq->mbox;
3673291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3674*82527734SSukumar Swaminathan 	mb->un.varUnregVpi.vpi = port->vpi + hba->vpi_base;
3675fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_UNREG_VPI;
3676fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3677fcf3ce44SJohn Forte 
3678*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3679*82527734SSukumar Swaminathan 		mbq->mbox_cmpl = emlxs_cmpl_unreg_vpi;
3680*82527734SSukumar Swaminathan 	} else {
3681*82527734SSukumar Swaminathan 		mbq->mbox_cmpl = NULL; /* no cmpl needed */
3682*82527734SSukumar Swaminathan 	}
3683*82527734SSukumar Swaminathan 
3684*82527734SSukumar Swaminathan 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
3685*82527734SSukumar Swaminathan 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
3686fcf3ce44SJohn Forte 		(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbq);
3687fcf3ce44SJohn Forte 	}
3688291a2b48SSukumar Swaminathan 
3689*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3690*82527734SSukumar Swaminathan 		if ((vfip = port->VFIp) != NULL) {
3691*82527734SSukumar Swaminathan 
3692*82527734SSukumar Swaminathan 			fcfp = vfip->FCFIp;
3693*82527734SSukumar Swaminathan 			if (port == fcfp->fcf_vpi) {
3694*82527734SSukumar Swaminathan 				fcfp->fcf_vpi = NULL;
3695*82527734SSukumar Swaminathan 			}
3696*82527734SSukumar Swaminathan 
3697*82527734SSukumar Swaminathan 			mutex_enter(&EMLXS_PORT_LOCK);
3698*82527734SSukumar Swaminathan 			vfip->outstandingVPIs--;
3699*82527734SSukumar Swaminathan 			if ((vfip->outstandingVPIs == 0) &&
3700*82527734SSukumar Swaminathan 			    (hba->state == FC_LINK_DOWN)) {
3701*82527734SSukumar Swaminathan 				mutex_exit(&EMLXS_PORT_LOCK);
3702*82527734SSukumar Swaminathan 
3703*82527734SSukumar Swaminathan 				/* No more VPIs so unreg the VFI */
3704*82527734SSukumar Swaminathan 				(void) emlxs_mb_unreg_vfi(hba, vfip);
3705*82527734SSukumar Swaminathan 			} else {
3706*82527734SSukumar Swaminathan 				mutex_exit(&EMLXS_PORT_LOCK);
3707*82527734SSukumar Swaminathan 			}
3708*82527734SSukumar Swaminathan 		}
3709*82527734SSukumar Swaminathan 	}
3710fcf3ce44SJohn Forte 	return (0);
3711fcf3ce44SJohn Forte 
3712fcf3ce44SJohn Forte } /* emlxs_mb_unreg_vpi() */
3713fcf3ce44SJohn Forte 
3714fcf3ce44SJohn Forte 
3715fcf3ce44SJohn Forte /*
3716291a2b48SSukumar Swaminathan  * emlxs_mb_config_farp  Issue a CONFIG FARP mailbox command
3717fcf3ce44SJohn Forte  */
3718fcf3ce44SJohn Forte extern void
3719*82527734SSukumar Swaminathan emlxs_mb_config_farp(emlxs_hba_t *hba, MAILBOXQ *mbq)
3720fcf3ce44SJohn Forte {
3721*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3722*82527734SSukumar Swaminathan 
3723291a2b48SSukumar Swaminathan 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
3724fcf3ce44SJohn Forte 
3725291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&hba->wwpn,
3726291a2b48SSukumar Swaminathan 	    (uint8_t *)&mb->un.varCfgFarp.portname, sizeof (NAME_TYPE));
3727fcf3ce44SJohn Forte 
3728291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&hba->wwpn,
3729291a2b48SSukumar Swaminathan 	    (uint8_t *)&mb->un.varCfgFarp.nodename, sizeof (NAME_TYPE));
3730fcf3ce44SJohn Forte 
3731fcf3ce44SJohn Forte 	mb->un.varCfgFarp.filterEnable = 1;
3732fcf3ce44SJohn Forte 	mb->un.varCfgFarp.portName = 1;
3733fcf3ce44SJohn Forte 	mb->un.varCfgFarp.nodeName = 1;
3734fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_CONFIG_FARP;
3735fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3736*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3737fcf3ce44SJohn Forte } /* emlxs_mb_config_farp() */
3738fcf3ce44SJohn Forte 
3739fcf3ce44SJohn Forte 
3740fcf3ce44SJohn Forte /*
3741291a2b48SSukumar Swaminathan  * emlxs_mb_read_nv  Issue a READ CONFIG mailbox command
3742fcf3ce44SJohn Forte  */
3743291a2b48SSukumar Swaminathan /*ARGSUSED*/
3744fcf3ce44SJohn Forte extern void
3745*82527734SSukumar Swaminathan emlxs_mb_read_config(emlxs_hba_t *hba, MAILBOXQ *mbq)
3746fcf3ce44SJohn Forte {
3747*82527734SSukumar Swaminathan 	MAILBOX *mb = (MAILBOX *)mbq;
3748*82527734SSukumar Swaminathan 
3749*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3750*82527734SSukumar Swaminathan 		bzero((void *) mb, MAILBOX_CMD_SLI4_BSIZE);
3751*82527734SSukumar Swaminathan 		mbq->nonembed = NULL;
3752*82527734SSukumar Swaminathan 	} else {
3753*82527734SSukumar Swaminathan 		bzero((void *)mb, MAILBOX_CMD_BSIZE);
3754*82527734SSukumar Swaminathan 	}
3755fcf3ce44SJohn Forte 
3756fcf3ce44SJohn Forte 	mb->mbxCommand = MBX_READ_CONFIG;
3757fcf3ce44SJohn Forte 	mb->mbxOwner = OWN_HOST;
3758*82527734SSukumar Swaminathan 	mbq->mbox_cmpl = NULL; /* no cmpl needed */
3759fcf3ce44SJohn Forte } /* emlxs_mb_read_config() */
3760fcf3ce44SJohn Forte 
3761fcf3ce44SJohn Forte 
3762fcf3ce44SJohn Forte /*
3763fcf3ce44SJohn Forte  * NAME:     emlxs_mb_put
3764fcf3ce44SJohn Forte  *
3765fcf3ce44SJohn Forte  * FUNCTION: put mailbox cmd onto the mailbox queue.
3766fcf3ce44SJohn Forte  *
3767fcf3ce44SJohn Forte  * EXECUTION ENVIRONMENT: process and interrupt level.
3768fcf3ce44SJohn Forte  *
3769fcf3ce44SJohn Forte  * NOTES:
3770fcf3ce44SJohn Forte  *
3771*82527734SSukumar Swaminathan  * CALLED FROM: EMLXS_SLI_ISSUE_MBOX_CMD
3772fcf3ce44SJohn Forte  *
3773291a2b48SSukumar Swaminathan  * INPUT: hba           - pointer to the device info area
3774291a2b48SSukumar Swaminathan  *      mbp             - pointer to mailbox queue entry of mailbox cmd
3775fcf3ce44SJohn Forte  *
3776fcf3ce44SJohn Forte  * RETURNS: NULL - command queued
3777fcf3ce44SJohn Forte  */
3778fcf3ce44SJohn Forte extern void
3779fcf3ce44SJohn Forte emlxs_mb_put(emlxs_hba_t *hba, MAILBOXQ *mbq)
3780fcf3ce44SJohn Forte {
3781fcf3ce44SJohn Forte 
3782fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
3783fcf3ce44SJohn Forte 
3784fcf3ce44SJohn Forte 	if (hba->mbox_queue.q_first) {
3785fcf3ce44SJohn Forte 
3786fcf3ce44SJohn Forte 		/*
3787fcf3ce44SJohn Forte 		 * queue command to end of list
3788fcf3ce44SJohn Forte 		 */
3789291a2b48SSukumar Swaminathan 		((MAILBOXQ *)hba->mbox_queue.q_last)->next = mbq;
3790fcf3ce44SJohn Forte 		hba->mbox_queue.q_last = (uint8_t *)mbq;
3791fcf3ce44SJohn Forte 		hba->mbox_queue.q_cnt++;
3792fcf3ce44SJohn Forte 	} else {
3793fcf3ce44SJohn Forte 
3794fcf3ce44SJohn Forte 		/*
3795fcf3ce44SJohn Forte 		 * add command to empty list
3796fcf3ce44SJohn Forte 		 */
3797fcf3ce44SJohn Forte 		hba->mbox_queue.q_first = (uint8_t *)mbq;
3798fcf3ce44SJohn Forte 		hba->mbox_queue.q_last = (uint8_t *)mbq;
3799fcf3ce44SJohn Forte 		hba->mbox_queue.q_cnt = 1;
3800fcf3ce44SJohn Forte 	}
3801fcf3ce44SJohn Forte 
3802fcf3ce44SJohn Forte 	mbq->next = NULL;
3803fcf3ce44SJohn Forte 
3804fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
3805fcf3ce44SJohn Forte } /* emlxs_mb_put() */
3806fcf3ce44SJohn Forte 
3807fcf3ce44SJohn Forte 
3808fcf3ce44SJohn Forte /*
3809fcf3ce44SJohn Forte  * NAME:     emlxs_mb_get
3810fcf3ce44SJohn Forte  *
3811fcf3ce44SJohn Forte  * FUNCTION: get a mailbox command from mailbox command queue
3812fcf3ce44SJohn Forte  *
3813fcf3ce44SJohn Forte  * EXECUTION ENVIRONMENT: interrupt level.
3814fcf3ce44SJohn Forte  *
3815fcf3ce44SJohn Forte  * NOTES:
3816fcf3ce44SJohn Forte  *
3817fcf3ce44SJohn Forte  * CALLED FROM: emlxs_handle_mb_event
3818fcf3ce44SJohn Forte  *
3819fcf3ce44SJohn Forte  * INPUT: hba       - pointer to the device info area
3820fcf3ce44SJohn Forte  *
3821fcf3ce44SJohn Forte  * RETURNS: NULL - no match found mb pointer - pointer to a mailbox command
3822fcf3ce44SJohn Forte  */
3823fcf3ce44SJohn Forte extern MAILBOXQ *
3824fcf3ce44SJohn Forte emlxs_mb_get(emlxs_hba_t *hba)
3825fcf3ce44SJohn Forte {
3826291a2b48SSukumar Swaminathan 	MAILBOXQ	*p_first = NULL;
3827fcf3ce44SJohn Forte 
3828fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
3829fcf3ce44SJohn Forte 
3830fcf3ce44SJohn Forte 	if (hba->mbox_queue.q_first) {
3831291a2b48SSukumar Swaminathan 		p_first = (MAILBOXQ *)hba->mbox_queue.q_first;
3832fcf3ce44SJohn Forte 		hba->mbox_queue.q_first = (uint8_t *)p_first->next;
3833fcf3ce44SJohn Forte 
3834fcf3ce44SJohn Forte 		if (hba->mbox_queue.q_first == NULL) {
3835fcf3ce44SJohn Forte 			hba->mbox_queue.q_last = NULL;
3836fcf3ce44SJohn Forte 			hba->mbox_queue.q_cnt = 0;
3837fcf3ce44SJohn Forte 		} else {
3838fcf3ce44SJohn Forte 			hba->mbox_queue.q_cnt--;
3839fcf3ce44SJohn Forte 		}
3840fcf3ce44SJohn Forte 
3841fcf3ce44SJohn Forte 		p_first->next = NULL;
3842fcf3ce44SJohn Forte 	}
3843291a2b48SSukumar Swaminathan 
3844fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
3845fcf3ce44SJohn Forte 
3846fcf3ce44SJohn Forte 	return (p_first);
3847fcf3ce44SJohn Forte 
3848fcf3ce44SJohn Forte } /* emlxs_mb_get() */
3849fcf3ce44SJohn Forte 
3850fcf3ce44SJohn Forte 
3851fcf3ce44SJohn Forte /* EMLXS_PORT_LOCK must be held when calling this */
3852291a2b48SSukumar Swaminathan void
3853fcf3ce44SJohn Forte emlxs_mb_init(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t flag, uint32_t tmo)
3854fcf3ce44SJohn Forte {
3855291a2b48SSukumar Swaminathan #ifdef FMA_SUPPORT
3856291a2b48SSukumar Swaminathan 	emlxs_port_t *port = &PPORT;
3857291a2b48SSukumar Swaminathan #endif	/* FMA_SUPPORT */
3858291a2b48SSukumar Swaminathan 	MATCHMAP	*mp;
3859fcf3ce44SJohn Forte 
3860fcf3ce44SJohn Forte 	HBASTATS.MboxIssued++;
3861fcf3ce44SJohn Forte 	hba->mbox_queue_flag = flag;
3862fcf3ce44SJohn Forte 
3863fcf3ce44SJohn Forte 	/* Set the Mailbox timer */
3864fcf3ce44SJohn Forte 	hba->mbox_timer = hba->timer_tics + tmo;
3865fcf3ce44SJohn Forte 
3866fcf3ce44SJohn Forte 	/* Initialize mailbox */
3867fcf3ce44SJohn Forte 	mbq->flag &= MBQ_INIT_MASK;
3868fcf3ce44SJohn Forte 	mbq->next = 0;
3869fcf3ce44SJohn Forte 
3870fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_MBOX_LOCK);
3871*82527734SSukumar Swaminathan 	hba->mbox_mbq = (uint8_t *)mbq;
3872fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_MBOX_LOCK);
3873fcf3ce44SJohn Forte 
3874*82527734SSukumar Swaminathan 	if (mbq->nonembed) {
3875*82527734SSukumar Swaminathan 		mp = (MATCHMAP *) mbq->nonembed;
3876*82527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
3877fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORDEV);
3878fcf3ce44SJohn Forte 	}
3879291a2b48SSukumar Swaminathan 
3880*82527734SSukumar Swaminathan 	if (mbq->bp) {
3881*82527734SSukumar Swaminathan 		mp = (MATCHMAP *) mbq->bp;
3882*82527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(mp->dma_handle, 0, mp->size,
3883*82527734SSukumar Swaminathan 		    DDI_DMA_SYNC_FORDEV);
3884fcf3ce44SJohn Forte 	}
3885fcf3ce44SJohn Forte 	return;
3886fcf3ce44SJohn Forte 
3887fcf3ce44SJohn Forte } /* emlxs_mb_init() */
3888fcf3ce44SJohn Forte 
3889fcf3ce44SJohn Forte 
3890fcf3ce44SJohn Forte extern void
3891fcf3ce44SJohn Forte emlxs_mb_fini(emlxs_hba_t *hba, MAILBOX *mb, uint32_t mbxStatus)
3892fcf3ce44SJohn Forte {
3893291a2b48SSukumar Swaminathan 	emlxs_port_t	*port = &PPORT;
3894*82527734SSukumar Swaminathan 	MATCHMAP	*mbox_nonembed;
3895291a2b48SSukumar Swaminathan 	MATCHMAP	*mbox_bp;
3896291a2b48SSukumar Swaminathan 	emlxs_buf_t	*mbox_sbp;
3897291a2b48SSukumar Swaminathan 	fc_unsol_buf_t	*mbox_ubp;
3898291a2b48SSukumar Swaminathan 	IOCBQ		*mbox_iocbq;
3899291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbox_mbq;
3900291a2b48SSukumar Swaminathan 	MAILBOX		*mbox;
3901291a2b48SSukumar Swaminathan 	uint32_t	mbox_queue_flag;
3902291a2b48SSukumar Swaminathan 	emlxs_ub_priv_t	*ub_priv;
3903fcf3ce44SJohn Forte 
3904fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
3905fcf3ce44SJohn Forte 
3906fcf3ce44SJohn Forte 	if (hba->mbox_queue_flag) {
3907fcf3ce44SJohn Forte 		HBASTATS.MboxCompleted++;
3908fcf3ce44SJohn Forte 
3909fcf3ce44SJohn Forte 		if (mbxStatus != MBX_SUCCESS) {
3910fcf3ce44SJohn Forte 			HBASTATS.MboxError++;
3911fcf3ce44SJohn Forte 		} else {
3912fcf3ce44SJohn Forte 			HBASTATS.MboxGood++;
3913fcf3ce44SJohn Forte 		}
3914fcf3ce44SJohn Forte 	}
3915291a2b48SSukumar Swaminathan 
3916*82527734SSukumar Swaminathan 	mutex_enter(&EMLXS_MBOX_LOCK);
3917fcf3ce44SJohn Forte 	mbox_queue_flag = hba->mbox_queue_flag;
3918*82527734SSukumar Swaminathan 	mbox_mbq = (MAILBOXQ *)hba->mbox_mbq;
3919fcf3ce44SJohn Forte 
3920*82527734SSukumar Swaminathan 	if (mbox_mbq) {
3921*82527734SSukumar Swaminathan 		mbox_nonembed = (MATCHMAP *)mbox_mbq->nonembed;
3922*82527734SSukumar Swaminathan 		mbox_bp = (MATCHMAP *)mbox_mbq->bp;
3923*82527734SSukumar Swaminathan 		mbox_sbp = (emlxs_buf_t *)mbox_mbq->sbp;
3924*82527734SSukumar Swaminathan 		mbox_ubp = (fc_unsol_buf_t *)mbox_mbq->ubp;
3925*82527734SSukumar Swaminathan 		mbox_iocbq = (IOCBQ *)mbox_mbq->iocbq;
3926*82527734SSukumar Swaminathan 	} else {
3927*82527734SSukumar Swaminathan 		mbox_nonembed = NULL;
3928*82527734SSukumar Swaminathan 		mbox_bp = NULL;
3929*82527734SSukumar Swaminathan 		mbox_sbp = NULL;
3930*82527734SSukumar Swaminathan 		mbox_ubp = NULL;
3931*82527734SSukumar Swaminathan 		mbox_iocbq = NULL;
3932*82527734SSukumar Swaminathan 	}
3933fcf3ce44SJohn Forte 
3934fcf3ce44SJohn Forte 	hba->mbox_mbq = 0;
3935fcf3ce44SJohn Forte 	hba->mbox_queue_flag = 0;
3936*82527734SSukumar Swaminathan 	hba->mbox_timer = 0;
3937*82527734SSukumar Swaminathan 	mutex_exit(&EMLXS_MBOX_LOCK);
3938fcf3ce44SJohn Forte 
3939fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
3940fcf3ce44SJohn Forte 
3941*82527734SSukumar Swaminathan 	if (mbox_queue_flag == MBX_NOWAIT) {
3942*82527734SSukumar Swaminathan 		/* Check for deferred MBUF cleanup */
3943*82527734SSukumar Swaminathan 		if (mbox_bp) {
3944*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_BUF, (uint8_t *)mbox_bp);
3945*82527734SSukumar Swaminathan 		}
3946*82527734SSukumar Swaminathan 		if (mbox_nonembed) {
3947*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_BUF,
3948*82527734SSukumar Swaminathan 			    (uint8_t *)mbox_nonembed);
3949fcf3ce44SJohn Forte 		}
3950*82527734SSukumar Swaminathan 		if (mbox_mbq) {
3951*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_MBOX,
3952*82527734SSukumar Swaminathan 			    (uint8_t *)mbox_mbq);
3953*82527734SSukumar Swaminathan 		}
3954*82527734SSukumar Swaminathan 	} else {  /* MBX_WAIT */
3955*82527734SSukumar Swaminathan 		if (mbox_mbq) {
3956*82527734SSukumar Swaminathan 			if (mb) {
3957*82527734SSukumar Swaminathan 				/* Copy the local mailbox provided back into */
3958*82527734SSukumar Swaminathan 				/* the original mailbox */
3959*82527734SSukumar Swaminathan 				if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
3960*82527734SSukumar Swaminathan 					bcopy((uint32_t *)mb,
3961*82527734SSukumar Swaminathan 					    (uint32_t *)mbox_mbq,
3962*82527734SSukumar Swaminathan 					    MAILBOX_CMD_SLI4_BSIZE);
3963*82527734SSukumar Swaminathan 				} else {
3964*82527734SSukumar Swaminathan 					bcopy((uint32_t *)mb,
3965*82527734SSukumar Swaminathan 					    (uint32_t *)mbox_mbq,
3966*82527734SSukumar Swaminathan 					    MAILBOX_CMD_BSIZE);
3967*82527734SSukumar Swaminathan 				}
3968*82527734SSukumar Swaminathan 			}
3969291a2b48SSukumar Swaminathan 
3970*82527734SSukumar Swaminathan 			mbox = (MAILBOX *)mbox_mbq;
3971*82527734SSukumar Swaminathan 			mbox->mbxStatus = mbxStatus;
3972fcf3ce44SJohn Forte 
3973*82527734SSukumar Swaminathan 			/* Mark mailbox complete */
3974*82527734SSukumar Swaminathan 			mbox_mbq->flag |= MBQ_COMPLETED;
3975*82527734SSukumar Swaminathan 		}
3976fcf3ce44SJohn Forte 
3977fcf3ce44SJohn Forte 		/* Wake up the sleeping thread */
3978fcf3ce44SJohn Forte 		if (mbox_queue_flag == MBX_SLEEP) {
3979fcf3ce44SJohn Forte 			mutex_enter(&EMLXS_MBOX_LOCK);
3980fcf3ce44SJohn Forte 			cv_broadcast(&EMLXS_MBOX_CV);
3981fcf3ce44SJohn Forte 			mutex_exit(&EMLXS_MBOX_LOCK);
3982fcf3ce44SJohn Forte 		}
3983fcf3ce44SJohn Forte 	}
3984291a2b48SSukumar Swaminathan 
3985fcf3ce44SJohn Forte #ifdef SFCT_SUPPORT
3986*82527734SSukumar Swaminathan 	if (mb && mbox_sbp && mbox_sbp->fct_cmd) {
3987fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_detail_msg,
3988fcf3ce44SJohn Forte 		    "FCT mailbox: %s: status=%x",
3989fcf3ce44SJohn Forte 		    emlxs_mb_cmd_xlate(mb->mbxCommand),
3990fcf3ce44SJohn Forte 		    (uint32_t)mb->mbxStatus);
3991fcf3ce44SJohn Forte 	}
3992291a2b48SSukumar Swaminathan #endif /* SFCT_SUPPORT */
3993fcf3ce44SJohn Forte 
3994fcf3ce44SJohn Forte 	/* Check for deferred pkt completion */
3995fcf3ce44SJohn Forte 	if (mbox_sbp) {
3996fcf3ce44SJohn Forte 		if (mbxStatus != MBX_SUCCESS) {
3997fcf3ce44SJohn Forte 			/* Set error status */
3998fcf3ce44SJohn Forte 			mbox_sbp->pkt_flags &= ~PACKET_STATE_VALID;
3999fcf3ce44SJohn Forte 			emlxs_set_pkt_state(mbox_sbp, IOSTAT_LOCAL_REJECT,
4000fcf3ce44SJohn Forte 			    IOERR_NO_RESOURCES, 1);
4001fcf3ce44SJohn Forte 		}
4002291a2b48SSukumar Swaminathan 
4003fcf3ce44SJohn Forte 		emlxs_pkt_complete(mbox_sbp, -1, 0, 1);
4004fcf3ce44SJohn Forte 	}
4005291a2b48SSukumar Swaminathan 
4006fcf3ce44SJohn Forte 	/* Check for deferred ub completion */
4007fcf3ce44SJohn Forte 	if (mbox_ubp) {
4008fcf3ce44SJohn Forte 		ub_priv = mbox_ubp->ub_fca_private;
4009fcf3ce44SJohn Forte 		port = ub_priv->port;
4010fcf3ce44SJohn Forte 
4011fcf3ce44SJohn Forte 		emlxs_ub_callback(port, mbox_ubp);
4012fcf3ce44SJohn Forte 	}
4013291a2b48SSukumar Swaminathan 
4014*82527734SSukumar Swaminathan 	/* Special handling for vport PLOGI */
4015*82527734SSukumar Swaminathan 	if (mbox_iocbq == (IOCBQ *)1) {
4016*82527734SSukumar Swaminathan 		mbox_iocbq = NULL;
4017*82527734SSukumar Swaminathan 	}
4018*82527734SSukumar Swaminathan 
4019fcf3ce44SJohn Forte 	/* Check for deferred iocb tx */
4020fcf3ce44SJohn Forte 	if (mbox_iocbq) {
4021*82527734SSukumar Swaminathan 		/* Check for driver special codes */
4022*82527734SSukumar Swaminathan 		/* These indicate the mailbox is being flushed */
4023*82527734SSukumar Swaminathan 		if (mbxStatus >= MBX_DRIVER_RESERVED) {
4024*82527734SSukumar Swaminathan 			/* Set the error status and return it */
4025*82527734SSukumar Swaminathan 			mbox_iocbq->iocb.ULPSTATUS = IOSTAT_LOCAL_REJECT;
4026*82527734SSukumar Swaminathan 			mbox_iocbq->iocb.un.grsp.perr.statLocalError =
4027*82527734SSukumar Swaminathan 			    IOERR_ABORT_REQUESTED;
4028*82527734SSukumar Swaminathan 
4029*82527734SSukumar Swaminathan 			emlxs_proc_channel_event(hba, mbox_iocbq->channel,
4030*82527734SSukumar Swaminathan 			    mbox_iocbq);
4031*82527734SSukumar Swaminathan 		} else {
4032*82527734SSukumar Swaminathan 			EMLXS_SLI_ISSUE_IOCB_CMD(hba, mbox_iocbq->channel,
4033*82527734SSukumar Swaminathan 			    mbox_iocbq);
4034*82527734SSukumar Swaminathan 		}
4035fcf3ce44SJohn Forte 	}
4036fcf3ce44SJohn Forte 	return;
4037fcf3ce44SJohn Forte 
4038fcf3ce44SJohn Forte } /* emlxs_mb_fini() */
4039fcf3ce44SJohn Forte 
4040fcf3ce44SJohn Forte 
4041*82527734SSukumar Swaminathan extern void
4042*82527734SSukumar Swaminathan emlxs_mb_flush(emlxs_hba_t *hba)
4043fcf3ce44SJohn Forte {
4044291a2b48SSukumar Swaminathan 	MAILBOXQ	*mbq;
4045*82527734SSukumar Swaminathan 	uint32_t	mbxStatus;
4046fcf3ce44SJohn Forte 
4047*82527734SSukumar Swaminathan 	mbxStatus = (hba->flag & FC_HARDWARE_ERROR) ?
4048*82527734SSukumar Swaminathan 	    MBX_HARDWARE_ERROR : MBX_NOT_FINISHED;
4049fcf3ce44SJohn Forte 
4050*82527734SSukumar Swaminathan 	/* Flush out the active mbox command */
4051*82527734SSukumar Swaminathan 	emlxs_mb_fini(hba, NULL, mbxStatus);
4052fcf3ce44SJohn Forte 
4053*82527734SSukumar Swaminathan 	/* Flush out the queued mbox commands */
4054*82527734SSukumar Swaminathan 	while (mbq = (MAILBOXQ *)emlxs_mb_get(hba)) {
4055*82527734SSukumar Swaminathan 		mutex_enter(&EMLXS_MBOX_LOCK);
4056*82527734SSukumar Swaminathan 		hba->mbox_queue_flag = MBX_NOWAIT;
4057*82527734SSukumar Swaminathan 		hba->mbox_mbq = (uint8_t *)mbq;
4058*82527734SSukumar Swaminathan 		mutex_exit(&EMLXS_MBOX_LOCK);
4059fcf3ce44SJohn Forte 
4060*82527734SSukumar Swaminathan 		emlxs_mb_fini(hba, NULL, mbxStatus);
4061*82527734SSukumar Swaminathan 	}
4062fcf3ce44SJohn Forte 
4063fcf3ce44SJohn Forte 	return;
4064fcf3ce44SJohn Forte 
4065*82527734SSukumar Swaminathan } /* emlxs_mb_flush */
4066fcf3ce44SJohn Forte 
4067fcf3ce44SJohn Forte 
4068291a2b48SSukumar Swaminathan extern char *
4069291a2b48SSukumar Swaminathan emlxs_mb_cmd_xlate(uint8_t cmd)
4070fcf3ce44SJohn Forte {
4071291a2b48SSukumar Swaminathan 	static char	buffer[32];
4072291a2b48SSukumar Swaminathan 	uint32_t	i;
4073291a2b48SSukumar Swaminathan 	uint32_t	count;
4074fcf3ce44SJohn Forte 
4075fcf3ce44SJohn Forte 	count = sizeof (emlxs_mb_cmd_table) / sizeof (emlxs_table_t);
4076fcf3ce44SJohn Forte 	for (i = 0; i < count; i++) {
4077fcf3ce44SJohn Forte 		if (cmd == emlxs_mb_cmd_table[i].code) {
4078fcf3ce44SJohn Forte 			return (emlxs_mb_cmd_table[i].string);
4079fcf3ce44SJohn Forte 		}
4080fcf3ce44SJohn Forte 	}
4081fcf3ce44SJohn Forte 
4082fcf3ce44SJohn Forte 	(void) sprintf(buffer, "Cmd=0x%x", cmd);
4083fcf3ce44SJohn Forte 	return (buffer);
4084fcf3ce44SJohn Forte 
4085fcf3ce44SJohn Forte } /* emlxs_mb_cmd_xlate() */
4086