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  *
8*8f23e9faSHans Rosenfeld  * You can obtain a copy of the license at
9*8f23e9faSHans Rosenfeld  * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*8f23e9faSHans Rosenfeld  * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27291a2b48SSukumar Swaminathan #include <emlxs.h>
28fcf3ce44SJohn Forte 
29fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_ELS_C);
31fcf3ce44SJohn Forte 
32291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp);
33a9800bebSGarrett D'Amore static void	emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp);
34291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp);
35291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp);
36291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp);
37291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp);
38291a2b48SSukumar Swaminathan 
3982527734SSukumar Swaminathan static void	emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp,
40291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4182527734SSukumar Swaminathan static void	emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp,
42291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4382527734SSukumar Swaminathan static void	emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp,
44291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4582527734SSukumar Swaminathan static void	emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp,
46291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4782527734SSukumar Swaminathan static void	emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp,
48291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4982527734SSukumar Swaminathan static void	emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp,
50291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5182527734SSukumar Swaminathan static void	emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp,
52291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5382527734SSukumar Swaminathan static void	emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp,
54291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5582527734SSukumar Swaminathan static void	emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp,
56291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
57*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_echo(emlxs_port_t *port, CHANNEL *cp,
58a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
59*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_rtv(emlxs_port_t *port, CHANNEL *cp,
60a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
61*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_rls(emlxs_port_t *port, CHANNEL *cp,
62a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
63291a2b48SSukumar Swaminathan static void	emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
64291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
65291a2b48SSukumar Swaminathan static void	emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
66291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
67a9800bebSGarrett D'Amore 
68a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4)
69291a2b48SSukumar Swaminathan static void	emlxs_send_rsnn(emlxs_port_t *port);
70fcf3ce44SJohn Forte 
71a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte 
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte /* Routine Declaration - Local */
76fcf3ce44SJohn Forte /* End Routine Declaration - Local */
77fcf3ce44SJohn Forte 
78fcf3ce44SJohn Forte /*
79fcf3ce44SJohn Forte  *  emlxs_els_handle_event
80fcf3ce44SJohn Forte  *
81291a2b48SSukumar Swaminathan  *  Description: Process an ELS Response Ring cmpl
82fcf3ce44SJohn Forte  *
83fcf3ce44SJohn Forte  */
84fcf3ce44SJohn Forte extern int
emlxs_els_handle_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)8582527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
86fcf3ce44SJohn Forte {
87fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
88fcf3ce44SJohn Forte 	IOCB *iocb;
89fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
90fcf3ce44SJohn Forte 	fc_packet_t *pkt;
91fcf3ce44SJohn Forte 	uint32_t *lp0;
92fcf3ce44SJohn Forte 	uint32_t command;
93fcf3ce44SJohn Forte 	NODELIST *ndlp;
94fcf3ce44SJohn Forte 	uint32_t did;
95fcf3ce44SJohn Forte 	ELS_PKT *els;
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
98fcf3ce44SJohn Forte 
99fcf3ce44SJohn Forte 	HBASTATS.ElsEvent++;
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
102fcf3ce44SJohn Forte 
103fcf3ce44SJohn Forte 	if (!sbp) {
104fcf3ce44SJohn Forte 		/*
105fcf3ce44SJohn Forte 		 * completion with missing xmit command
106fcf3ce44SJohn Forte 		 */
107fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
108fcf3ce44SJohn Forte 
109fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
110fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
11182527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
11282527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
113291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
114fcf3ce44SJohn Forte 
115fcf3ce44SJohn Forte 		return (1);
116fcf3ce44SJohn Forte 	}
117291a2b48SSukumar Swaminathan 
11882527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_els) {
119fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
120fcf3ce44SJohn Forte 
121fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
12282527734SSukumar Swaminathan 		    "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x "
12382527734SSukumar Swaminathan 		    "status=0x%x perr=0x%x", cp->channelno, iocbq,
12482527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG,
12582527734SSukumar Swaminathan 		    iocb->ULPSTATUS, iocb->un.ulpWord[4]);
126fcf3ce44SJohn Forte 
127fcf3ce44SJohn Forte 		return (1);
128fcf3ce44SJohn Forte 	}
129291a2b48SSukumar Swaminathan 
130fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
131fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
132fcf3ce44SJohn Forte 	lp0 = (uint32_t *)pkt->pkt_cmd;
133fcf3ce44SJohn Forte 	command = *lp0 & ELS_CMD_MASK;
13482527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
137fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
13882527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
139fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
140fcf3ce44SJohn Forte 	}
141291a2b48SSukumar Swaminathan 
14282527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
143291a2b48SSukumar Swaminathan 		/*
144291a2b48SSukumar Swaminathan 		 * ELS Reply completion
145291a2b48SSukumar Swaminathan 		 */
146fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP_CX:
147fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP64_CX:
148fcf3ce44SJohn Forte 
149fcf3ce44SJohn Forte 		HBASTATS.ElsRspCompleted++;
150fcf3ce44SJohn Forte 
151fcf3ce44SJohn Forte 		if (command == ELS_CMD_ACC) {
152fcf3ce44SJohn Forte 			emlxs_handle_acc(port, sbp, iocbq, 1);
153fcf3ce44SJohn Forte 		} else {
154fcf3ce44SJohn Forte 			emlxs_handle_reject(port, sbp, iocbq, 1);
155fcf3ce44SJohn Forte 		}
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte 		break;
158fcf3ce44SJohn Forte 
159291a2b48SSukumar Swaminathan 		/*
160291a2b48SSukumar Swaminathan 		 * ELS command completion
161291a2b48SSukumar Swaminathan 		 */
162fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CR:
163fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CR:
164fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CX:
165fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CX:
166fcf3ce44SJohn Forte 
167fcf3ce44SJohn Forte 		HBASTATS.ElsCmdCompleted++;
168fcf3ce44SJohn Forte 
169fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_ELS_RSP_VALID;
170fcf3ce44SJohn Forte 
171fcf3ce44SJohn Forte 		els = (ELS_PKT *)pkt->pkt_resp;
172fcf3ce44SJohn Forte 
173fcf3ce44SJohn Forte 		pkt->pkt_resp_resid =
174fcf3ce44SJohn Forte 		    pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize;
175fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
176fcf3ce44SJohn Forte 
177fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id;
178fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
179fcf3ce44SJohn Forte 
18082527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) {
181fcf3ce44SJohn Forte 			HBASTATS.ElsCmdGood++;
182fcf3ce44SJohn Forte 
183fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
184fcf3ce44SJohn Forte 				/*
185291a2b48SSukumar Swaminathan 				 * ULP patch - ULP expects
186291a2b48SSukumar Swaminathan 				 * resp_resid = 0 on success
187fcf3ce44SJohn Forte 				 */
188fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
189fcf3ce44SJohn Forte 			}
190291a2b48SSukumar Swaminathan 
191fcf3ce44SJohn Forte 			switch (command) {
192fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
193a9800bebSGarrett D'Amore 				emlxs_handle_sol_fdisc(port, sbp);
194fcf3ce44SJohn Forte 
195fcf3ce44SJohn Forte 				break;
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
198fcf3ce44SJohn Forte 				emlxs_handle_sol_flogi(port, sbp);
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 				break;
201fcf3ce44SJohn Forte 
202fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login */
203fcf3ce44SJohn Forte 				emlxs_handle_sol_plogi(port, sbp);
204fcf3ce44SJohn Forte 
205fcf3ce44SJohn Forte 				break;
206fcf3ce44SJohn Forte 
207fcf3ce44SJohn Forte 			case ELS_CMD_ADISC:	/* Adisc */
208fcf3ce44SJohn Forte 				emlxs_handle_sol_adisc(port, sbp);
209fcf3ce44SJohn Forte 
210fcf3ce44SJohn Forte 				break;
211fcf3ce44SJohn Forte 
212fcf3ce44SJohn Forte 			case ELS_CMD_LOGO:	/* Logout */
213fcf3ce44SJohn Forte 				emlxs_handle_sol_logo(port, sbp);
214fcf3ce44SJohn Forte 
215fcf3ce44SJohn Forte 				break;
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In */
218fcf3ce44SJohn Forte 				emlxs_handle_sol_prli(port, sbp);
219fcf3ce44SJohn Forte 
220fcf3ce44SJohn Forte 				break;
221fcf3ce44SJohn Forte 
222fcf3ce44SJohn Forte 			default:
223fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
224291a2b48SSukumar Swaminathan 				    &emlxs_els_completion_msg, "%s: did=%x",
225fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did);
226fcf3ce44SJohn Forte 
227fcf3ce44SJohn Forte 				emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
228fcf3ce44SJohn Forte 
229fcf3ce44SJohn Forte 				break;
230fcf3ce44SJohn Forte 			}
231fcf3ce44SJohn Forte 
232fcf3ce44SJohn Forte 		} else {
233fcf3ce44SJohn Forte 			HBASTATS.ElsCmdError++;
234fcf3ce44SJohn Forte 
235fcf3ce44SJohn Forte 			/* Look for LS_REJECT */
23682527734SSukumar Swaminathan 			if (iocb->ULPSTATUS == IOSTAT_LS_RJT) {
237fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_LS_RJT;
238fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
239fcf3ce44SJohn Forte 				pkt->pkt_reason = iocb->un.grsp.perr.statRsn;
240fcf3ce44SJohn Forte 				pkt->pkt_expln = iocb->un.grsp.perr.statBaExp;
241fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
242fcf3ce44SJohn Forte 
243291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
244*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
245291a2b48SSukumar Swaminathan 				if (ndlp) {
246291a2b48SSukumar Swaminathan 					emlxs_log_sd_lsrjt_event(port,
247291a2b48SSukumar Swaminathan 					    (HBA_WWN *)&ndlp->nlp_portname,
248291a2b48SSukumar Swaminathan 					    command, pkt->pkt_reason,
249291a2b48SSukumar Swaminathan 					    pkt->pkt_expln);
250291a2b48SSukumar Swaminathan 				}
251291a2b48SSukumar Swaminathan #endif
252291a2b48SSukumar Swaminathan 
253fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
254fcf3ce44SJohn Forte 				    &emlxs_els_completion_msg,
255fcf3ce44SJohn Forte 				    "%s Rejected: did=%x rsn=%x exp=%x",
256fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
257fcf3ce44SJohn Forte 				    pkt->pkt_reason, pkt->pkt_expln);
25882527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
259fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
260fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
261fcf3ce44SJohn Forte 				    "%s: did=%x Local Reject. %s",
262fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
263291a2b48SSukumar Swaminathan 				    emlxs_error_xlate(iocb->un.grsp.perr.
264291a2b48SSukumar Swaminathan 				    statLocalError));
265fcf3ce44SJohn Forte 			} else {
266fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
267fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
268fcf3ce44SJohn Forte 				    "%s: did=%x %s (%02x%02x%02x%02x)",
269fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
27082527734SSukumar Swaminathan 				    emlxs_state_xlate(iocb->ULPSTATUS),
271fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statAction,
272fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statRsn,
273fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statBaExp,
274fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statLocalError);
275fcf3ce44SJohn Forte 			}
276fcf3ce44SJohn Forte 
277fcf3ce44SJohn Forte 			switch (command) {
278fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login failed */
279*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
280fcf3ce44SJohn Forte 
281fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
282fcf3ce44SJohn Forte 					/* Open the node again */
283fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28482527734SSukumar Swaminathan 					    hba->channel_fcp);
285fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28682527734SSukumar Swaminathan 					    hba->channel_ip);
287fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
288fcf3ce44SJohn Forte 					if (pkt->pkt_state == FC_PKT_LS_RJT) {
289fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
290fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
291fcf3ce44SJohn Forte 						    pkt->pkt_reason,
292fcf3ce44SJohn Forte 						    pkt->pkt_expln);
293fcf3ce44SJohn Forte 					}
294291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
295fcf3ce44SJohn Forte 				}
296291a2b48SSukumar Swaminathan 
297fcf3ce44SJohn Forte 				break;
298fcf3ce44SJohn Forte 
299fcf3ce44SJohn Forte 
300fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In failed */
301*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
302fcf3ce44SJohn Forte 
303fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
304fcf3ce44SJohn Forte 					/* Open the node again */
305fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
30682527734SSukumar Swaminathan 					    hba->channel_fcp);
307fcf3ce44SJohn Forte 				}
308291a2b48SSukumar Swaminathan 
309fcf3ce44SJohn Forte 				break;
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
312fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
313fcf3ce44SJohn Forte 				if (pkt->pkt_state == FC_PKT_LS_RJT) {
314291a2b48SSukumar Swaminathan 					/* This will cause ULP to retry */
315291a2b48SSukumar Swaminathan 					/* FLOGI requests */
316fcf3ce44SJohn Forte 					pkt->pkt_reason = FC_REASON_QFULL;
317fcf3ce44SJohn Forte 					pkt->pkt_expln = 0;
318fcf3ce44SJohn Forte 
319fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
320*8f23e9faSHans Rosenfeld 					ndlp = emlxs_node_find_did(port,
321*8f23e9faSHans Rosenfeld 					    did, 1);
322fcf3ce44SJohn Forte 					if (ndlp && ndlp->nlp_active) {
323fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
324fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
325fcf3ce44SJohn Forte 						    pkt->pkt_reason,
326fcf3ce44SJohn Forte 						    pkt->pkt_expln);
327fcf3ce44SJohn Forte 					}
328291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
329fcf3ce44SJohn Forte 				}
330291a2b48SSukumar Swaminathan 
331a9800bebSGarrett D'Amore 				if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
332*8f23e9faSHans Rosenfeld 					/* Preset the state for deferred cmpl */
333*8f23e9faSHans Rosenfeld 					emlxs_set_pkt_state(sbp,
334*8f23e9faSHans Rosenfeld 					    iocb->ULPSTATUS,
335*8f23e9faSHans Rosenfeld 					    iocb->un.grsp.perr.statLocalError,
336*8f23e9faSHans Rosenfeld 					    1);
337*8f23e9faSHans Rosenfeld 
338*8f23e9faSHans Rosenfeld 					if (emlxs_vpi_logi_failed_notify(
339*8f23e9faSHans Rosenfeld 					    sbp->port, sbp) == 0) {
340*8f23e9faSHans Rosenfeld 						/* Defer completion */
341*8f23e9faSHans Rosenfeld 						return (0);
342*8f23e9faSHans Rosenfeld 					}
343a9800bebSGarrett D'Amore 				}
344a9800bebSGarrett D'Amore 
345fcf3ce44SJohn Forte 				break;
346fcf3ce44SJohn Forte 
347fcf3ce44SJohn Forte 			default:
348fcf3ce44SJohn Forte 				break;
349fcf3ce44SJohn Forte 			}
350fcf3ce44SJohn Forte 
35182527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
352fcf3ce44SJohn Forte 			    iocb->un.grsp.perr.statLocalError, 1);
353fcf3ce44SJohn Forte 		}
354fcf3ce44SJohn Forte 
355fcf3ce44SJohn Forte 		break;
356fcf3ce44SJohn Forte 
357fcf3ce44SJohn Forte 	default:
358fcf3ce44SJohn Forte 
359fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg,
36282527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
363fcf3ce44SJohn Forte 
36482527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
365fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte 		break;
36882527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
369fcf3ce44SJohn Forte 
370fcf3ce44SJohn Forte 	return (0);
371fcf3ce44SJohn Forte 
37282527734SSukumar Swaminathan } /* emlxs_els_handle_event() */
373fcf3ce44SJohn Forte 
374fcf3ce44SJohn Forte 
375fcf3ce44SJohn Forte extern int
emlxs_els_handle_unsol_req(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)37682527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
377fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
378fcf3ce44SJohn Forte {
379fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
380fcf3ce44SJohn Forte 	uint32_t cmd_code;
381a9800bebSGarrett D'Amore 	IOCB *iocb;
382fcf3ce44SJohn Forte 
383fcf3ce44SJohn Forte 	HBASTATS.ElsCmdReceived++;
384fcf3ce44SJohn Forte 
385a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
386fcf3ce44SJohn Forte 	cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK;
387fcf3ce44SJohn Forte 
38882527734SSukumar Swaminathan 	if (!(port->flag & EMLXS_PORT_BOUND)) {
389e2ca2865SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
390e2ca2865SSukumar Swaminathan 		    "%s: sid=%x. Port not bound: Rejecting.",
391e2ca2865SSukumar Swaminathan 		    emlxs_elscmd_xlate(cmd_code),
392e2ca2865SSukumar Swaminathan 		    iocbq->iocb.un.elsreq.remoteID);
39382527734SSukumar Swaminathan 
39482527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
395e2ca2865SSukumar Swaminathan 		    cmd_code, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
39682527734SSukumar Swaminathan 
39782527734SSukumar Swaminathan 		return (0);
39882527734SSukumar Swaminathan 	}
39982527734SSukumar Swaminathan 
400fcf3ce44SJohn Forte 	switch (cmd_code) {
401fcf3ce44SJohn Forte 	case ELS_CMD_RSCN:
402fcf3ce44SJohn Forte 		HBASTATS.ElsRscnReceived++;
40382527734SSukumar Swaminathan 		emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size);
404fcf3ce44SJohn Forte 		break;
405fcf3ce44SJohn Forte 
406fcf3ce44SJohn Forte 	case ELS_CMD_FLOGI:
407fcf3ce44SJohn Forte 		HBASTATS.ElsFlogiReceived++;
40882527734SSukumar Swaminathan 		emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size);
409fcf3ce44SJohn Forte 		break;
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
412fcf3ce44SJohn Forte 		HBASTATS.ElsPlogiReceived++;
41382527734SSukumar Swaminathan 		emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size);
414fcf3ce44SJohn Forte 		break;
415fcf3ce44SJohn Forte 
416fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
417fcf3ce44SJohn Forte 		HBASTATS.ElsPrliReceived++;
41882527734SSukumar Swaminathan 		emlxs_handle_unsol_prli(port, cp, iocbq, mp, size);
419fcf3ce44SJohn Forte 		break;
420fcf3ce44SJohn Forte 
421fcf3ce44SJohn Forte 	case ELS_CMD_PRLO:
422fcf3ce44SJohn Forte 		HBASTATS.ElsPrloReceived++;
42382527734SSukumar Swaminathan 		emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size);
424fcf3ce44SJohn Forte 		break;
425fcf3ce44SJohn Forte 
426fcf3ce44SJohn Forte 	case ELS_CMD_LOGO:
427fcf3ce44SJohn Forte 		HBASTATS.ElsLogoReceived++;
42882527734SSukumar Swaminathan 		emlxs_handle_unsol_logo(port, cp, iocbq, mp, size);
429fcf3ce44SJohn Forte 		break;
430fcf3ce44SJohn Forte 
431fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
432fcf3ce44SJohn Forte 		HBASTATS.ElsAdiscReceived++;
43382527734SSukumar Swaminathan 		emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size);
434fcf3ce44SJohn Forte 		break;
435fcf3ce44SJohn Forte 
436fcf3ce44SJohn Forte 	case ELS_CMD_AUTH:
437fcf3ce44SJohn Forte 		HBASTATS.ElsAuthReceived++;
43882527734SSukumar Swaminathan 		emlxs_handle_unsol_auth(port, cp, iocbq, mp, size);
439fcf3ce44SJohn Forte 		break;
440fcf3ce44SJohn Forte 
441a9800bebSGarrett D'Amore 	case ELS_CMD_TEST:
442a9800bebSGarrett D'Amore 		HBASTATS.ElsTestReceived++;
443a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
444a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
445a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
446a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
447a9800bebSGarrett D'Amore 
448a9800bebSGarrett D'Amore 		/* drop it */
449a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
450a9800bebSGarrett D'Amore 		break;
451a9800bebSGarrett D'Amore 
452a9800bebSGarrett D'Amore 	case ELS_CMD_ESTC:
453a9800bebSGarrett D'Amore 		HBASTATS.ElsEstcReceived++;
454a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
455a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
456a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
457a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
458a9800bebSGarrett D'Amore 
459a9800bebSGarrett D'Amore 		/* drop it */
460a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
461a9800bebSGarrett D'Amore 		break;
462a9800bebSGarrett D'Amore 
463a9800bebSGarrett D'Amore 	case ELS_CMD_FARPR:
464a9800bebSGarrett D'Amore 		HBASTATS.ElsFarprReceived++;
465a9800bebSGarrett D'Amore 
466a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
467a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
468a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
469a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
470a9800bebSGarrett D'Amore 
471a9800bebSGarrett D'Amore 		/* drop it */
472a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
473a9800bebSGarrett D'Amore 		break;
474a9800bebSGarrett D'Amore 
475a9800bebSGarrett D'Amore 	case ELS_CMD_ECHO:
476a9800bebSGarrett D'Amore 		HBASTATS.ElsEchoReceived++;
477*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_echo(port, cp, iocbq, mp, size);
478a9800bebSGarrett D'Amore 		break;
479a9800bebSGarrett D'Amore 
480a9800bebSGarrett D'Amore 	case ELS_CMD_RLS:
481a9800bebSGarrett D'Amore 		HBASTATS.ElsRlsReceived++;
482*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_rls(port, cp, iocbq, mp, size);
483a9800bebSGarrett D'Amore 		break;
484a9800bebSGarrett D'Amore 
485a9800bebSGarrett D'Amore 	case ELS_CMD_RTV:
486a9800bebSGarrett D'Amore 		HBASTATS.ElsRtvReceived++;
487*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_rtv(port, cp, iocbq, mp, size);
488a9800bebSGarrett D'Amore 		break;
489a9800bebSGarrett D'Amore 
490a9800bebSGarrett D'Amore 	case ELS_CMD_ABTX:
491a9800bebSGarrett D'Amore 	case ELS_CMD_RCS:
492a9800bebSGarrett D'Amore 	case ELS_CMD_RES:
493a9800bebSGarrett D'Amore 	case ELS_CMD_RSS:
494a9800bebSGarrett D'Amore 	case ELS_CMD_RSI:
495a9800bebSGarrett D'Amore 	case ELS_CMD_ESTS:
496a9800bebSGarrett D'Amore 	case ELS_CMD_RRQ:
497a9800bebSGarrett D'Amore 	case ELS_CMD_REC:
498a9800bebSGarrett D'Amore 		HBASTATS.ElsGenReceived++;
499a9800bebSGarrett D'Amore 
500a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
501a9800bebSGarrett D'Amore 		    "%s: sid=%x. Rejecting.",
502a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
503a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
504a9800bebSGarrett D'Amore 
505a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
506a9800bebSGarrett D'Amore 		    LSRJT_CMD_UNSUPPORTED, LSEXP_NOTHING_MORE);
507a9800bebSGarrett D'Amore 		break;
508a9800bebSGarrett D'Amore 
509fcf3ce44SJohn Forte 	default:
510fcf3ce44SJohn Forte 		HBASTATS.ElsGenReceived++;
51182527734SSukumar Swaminathan 		emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size);
512fcf3ce44SJohn Forte 		break;
513fcf3ce44SJohn Forte 	}
514fcf3ce44SJohn Forte 
515fcf3ce44SJohn Forte 	return (0);
516fcf3ce44SJohn Forte 
51782527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */
518fcf3ce44SJohn Forte 
519fcf3ce44SJohn Forte 
520*8f23e9faSHans Rosenfeld static uint32_t
emlxs_els_delay_discovery(emlxs_port_t * port,emlxs_buf_t * sbp)521*8f23e9faSHans Rosenfeld emlxs_els_delay_discovery(emlxs_port_t *port, emlxs_buf_t *sbp)
522*8f23e9faSHans Rosenfeld {
523*8f23e9faSHans Rosenfeld 	emlxs_hba_t	*hba = HBA;
524*8f23e9faSHans Rosenfeld 	emlxs_config_t	*cfg;
525*8f23e9faSHans Rosenfeld 	SERV_PARM	*parm;
526*8f23e9faSHans Rosenfeld 
527*8f23e9faSHans Rosenfeld 	cfg = &CFG;
528*8f23e9faSHans Rosenfeld 	if (!cfg[CFG_DELAY_DISCOVERY].current) {
529*8f23e9faSHans Rosenfeld 		return (0);
530*8f23e9faSHans Rosenfeld 	}
531*8f23e9faSHans Rosenfeld 
532*8f23e9faSHans Rosenfeld 	parm = &port->fabric_sparam;
533*8f23e9faSHans Rosenfeld 	if (((port->prev_did != port->did) ||
534*8f23e9faSHans Rosenfeld 	    bcmp(&port->prev_fabric_sparam.portName,
535*8f23e9faSHans Rosenfeld 	    &port->fabric_sparam.portName, 8)) &&
536*8f23e9faSHans Rosenfeld 	    !(parm->cmn.CLEAN_ADDRESS_BIT)) {
537*8f23e9faSHans Rosenfeld 
538*8f23e9faSHans Rosenfeld 		/* If this is the first time, check config parameter */
539*8f23e9faSHans Rosenfeld 		if (port->prev_did || cfg[CFG_DELAY_DISCOVERY].current == 2) {
540*8f23e9faSHans Rosenfeld 
541*8f23e9faSHans Rosenfeld 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
542*8f23e9faSHans Rosenfeld 			    "Clean Address delay: sid=%x prev=%x RATOV %d",
543*8f23e9faSHans Rosenfeld 			    port->did, port->prev_did, hba->fc_ratov);
544*8f23e9faSHans Rosenfeld 
545*8f23e9faSHans Rosenfeld 			port->clean_address_sbp = sbp;
546*8f23e9faSHans Rosenfeld 			port->clean_address_timer =
547*8f23e9faSHans Rosenfeld 			    hba->timer_tics + hba->fc_ratov;
548*8f23e9faSHans Rosenfeld 
549*8f23e9faSHans Rosenfeld 			return (1);
550*8f23e9faSHans Rosenfeld 		}
551*8f23e9faSHans Rosenfeld 	}
552*8f23e9faSHans Rosenfeld 	return (0);
553*8f23e9faSHans Rosenfeld 
554*8f23e9faSHans Rosenfeld } /* emlxs_els_delay_discovery() */
555*8f23e9faSHans Rosenfeld 
556*8f23e9faSHans Rosenfeld 
557fcf3ce44SJohn Forte static void
emlxs_handle_sol_flogi(emlxs_port_t * port,emlxs_buf_t * sbp)558fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp)
559fcf3ce44SJohn Forte {
560fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
561fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
562fcf3ce44SJohn Forte 	emlxs_port_t *vport;
563fcf3ce44SJohn Forte 	SERV_PARM *sp;
564fcf3ce44SJohn Forte 	fc_packet_t *pkt;
565fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
566fcf3ce44SJohn Forte 	uint32_t did;
567fcf3ce44SJohn Forte 	IOCBQ *iocbq;
568fcf3ce44SJohn Forte 	IOCB *iocb;
569fcf3ce44SJohn Forte 	char buffer[64];
570fcf3ce44SJohn Forte 	uint32_t i;
57182527734SSukumar Swaminathan 	int rc;
572a9800bebSGarrett D'Amore 	uint16_t altBbCredit;
573fcf3ce44SJohn Forte 
574fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
575fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
57682527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
577fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
578fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
579fcf3ce44SJohn Forte 
580a9800bebSGarrett D'Amore 	mutex_enter(&EMLXS_PORT_LOCK);
581fcf3ce44SJohn Forte 
582a9800bebSGarrett D'Amore 	/* Save the fabric service parameters and did */
583a9800bebSGarrett D'Amore 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
584a9800bebSGarrett D'Amore 
585*8f23e9faSHans Rosenfeld 	/* Save E_D_TOV ticks in nanoseconds */
586*8f23e9faSHans Rosenfeld 	if (sp->cmn.edtovResolution) {
587*8f23e9faSHans Rosenfeld 		hba->fc_edtov = (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
588*8f23e9faSHans Rosenfeld 	} else {
589*8f23e9faSHans Rosenfeld 		hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
590*8f23e9faSHans Rosenfeld 	}
591*8f23e9faSHans Rosenfeld 
592*8f23e9faSHans Rosenfeld 	/* Save R_A_TOV ticks */
593*8f23e9faSHans Rosenfeld 	hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
594*8f23e9faSHans Rosenfeld 
595a9800bebSGarrett D'Amore 	if (sp->cmn.fPort) {
596fcf3ce44SJohn Forte 		hba->flag |= FC_FABRIC_ATTACHED;
597fcf3ce44SJohn Forte 		hba->flag &= ~FC_PT_TO_PT;
598fcf3ce44SJohn Forte 
599*8f23e9faSHans Rosenfeld 		port->did = iocb->un.elsreq.myID;
60082527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID);
60182527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
602fcf3ce44SJohn Forte 
603a9800bebSGarrett D'Amore 		/*
604a9800bebSGarrett D'Amore 		 * If we are a N-port connected to a Fabric,
605a9800bebSGarrett D'Amore 		 * fixup sparam's so logins to devices on remote
606a9800bebSGarrett D'Amore 		 * loops work.
607a9800bebSGarrett D'Amore 		 */
608a9800bebSGarrett D'Amore 		altBbCredit = (hba->topology != TOPOLOGY_LOOP)? 1:0;
609a9800bebSGarrett D'Amore 		hba->sparam.cmn.altBbCredit = altBbCredit;
610fcf3ce44SJohn Forte 
611a9800bebSGarrett D'Amore 		/* Set this bit in all the port sparam copies */
612a9800bebSGarrett D'Amore 		for (i = 0; i < MAX_VPORTS; i++) {
613a9800bebSGarrett D'Amore 			vport = &VPORT(i);
614291a2b48SSukumar Swaminathan 
615a9800bebSGarrett D'Amore 			if (!(vport->flag & EMLXS_PORT_BOUND)) {
616a9800bebSGarrett D'Amore 				continue;
617fcf3ce44SJohn Forte 			}
618a9800bebSGarrett D'Amore 
619a9800bebSGarrett D'Amore 			vport->sparam.cmn.altBbCredit = altBbCredit;
620fcf3ce44SJohn Forte 		}
62182527734SSukumar Swaminathan 
622fcf3ce44SJohn Forte 		if (sp->cmn.rspMultipleNPort) {
623fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_SUPPORTED;
624fcf3ce44SJohn Forte 
625fcf3ce44SJohn Forte 			if (cfg[CFG_NPIV_DELAY].current) {
626fcf3ce44SJohn Forte 				/*
627291a2b48SSukumar Swaminathan 				 * PATCH: for NPIV support on
628291a2b48SSukumar Swaminathan 				 * Brocade switch firmware 5.10b
629fcf3ce44SJohn Forte 				 */
630fcf3ce44SJohn Forte 				if ((hba->flag & FC_NPIV_ENABLED) &&
631fcf3ce44SJohn Forte 				    ((sp->nodeName.IEEE[0] == 0x00) &&
632fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[1] == 0x05) &&
633fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[2] == 0x1e))) {
634fcf3ce44SJohn Forte 					hba->flag |= FC_NPIV_DELAY_REQUIRED;
635fcf3ce44SJohn Forte 				}
636fcf3ce44SJohn Forte 			}
637fcf3ce44SJohn Forte 		} else {
638fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_UNSUPPORTED;
639fcf3ce44SJohn Forte 		}
640fcf3ce44SJohn Forte 
641fcf3ce44SJohn Forte 		if (!(hba->flag & FC_NPIV_ENABLED)) {
642*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Disabled ",
643*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
644fcf3ce44SJohn Forte 		} else if (hba->flag & FC_NPIV_SUPPORTED) {
645*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Supported ",
646*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
647fcf3ce44SJohn Forte 		} else {
648*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Unsupported ",
649*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
650fcf3ce44SJohn Forte 		}
651fcf3ce44SJohn Forte 
652fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
653fcf3ce44SJohn Forte 		if (!sp->cmn.fcsp_support) {
654*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Unsupported",
655*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
656fcf3ce44SJohn Forte 		} else if (cfg[CFG_AUTH_ENABLE].current &&
657fcf3ce44SJohn Forte 		    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
658*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Supported",
659*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
660fcf3ce44SJohn Forte 		} else {
661*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Disabled",
662*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
663fcf3ce44SJohn Forte 		}
664291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
665fcf3ce44SJohn Forte 
666fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
669*8f23e9faSHans Rosenfeld 		    "FLOGI: did=%x sid=%x prev=%x %s",
670*8f23e9faSHans Rosenfeld 		    did, port->did, port->prev_did, buffer);
67182527734SSukumar Swaminathan 
672a9800bebSGarrett D'Amore 		/* Update our service parms */
673*8f23e9faSHans Rosenfeld 		if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
674*8f23e9faSHans Rosenfeld 			/* Update our service parms */
675*8f23e9faSHans Rosenfeld 			if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
676*8f23e9faSHans Rosenfeld 			    MEM_MBOX))) {
677*8f23e9faSHans Rosenfeld 				emlxs_mb_config_link(hba, mbox);
678*8f23e9faSHans Rosenfeld 
679*8f23e9faSHans Rosenfeld 				rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
680*8f23e9faSHans Rosenfeld 				    MBX_NOWAIT, 0);
681*8f23e9faSHans Rosenfeld 				if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
682*8f23e9faSHans Rosenfeld 					emlxs_mem_put(hba, MEM_MBOX,
683*8f23e9faSHans Rosenfeld 					    (void *)mbox);
684*8f23e9faSHans Rosenfeld 				}
685*8f23e9faSHans Rosenfeld 			}
686fcf3ce44SJohn Forte 		}
687291a2b48SSukumar Swaminathan 
688fcf3ce44SJohn Forte 		/* Preset the state for the reg_did */
689fcf3ce44SJohn Forte 		emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
690fcf3ce44SJohn Forte 
691*8f23e9faSHans Rosenfeld 		if (emlxs_els_delay_discovery(port, sbp)) {
692*8f23e9faSHans Rosenfeld 			/* Deferred registration of this pkt until */
693*8f23e9faSHans Rosenfeld 			/* Clean Address timeout */
694*8f23e9faSHans Rosenfeld 			return;
695*8f23e9faSHans Rosenfeld 		}
696*8f23e9faSHans Rosenfeld 
697*8f23e9faSHans Rosenfeld 		if (EMLXS_SLI_REG_DID(port, FABRIC_DID, &port->fabric_sparam,
698fcf3ce44SJohn Forte 		    sbp, NULL, NULL) == 0) {
699291a2b48SSukumar Swaminathan 			/* Deferred completion of this pkt until */
700291a2b48SSukumar Swaminathan 			/* login is complete */
701fcf3ce44SJohn Forte 			return;
702fcf3ce44SJohn Forte 		}
703291a2b48SSukumar Swaminathan 
704fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
705fcf3ce44SJohn Forte 		    IOERR_NO_RESOURCES, 1);
706fcf3ce44SJohn Forte 
707fcf3ce44SJohn Forte 	} else {	/* No switch */
708291a2b48SSukumar Swaminathan 
709fcf3ce44SJohn Forte 		hba->flag &= ~FC_FABRIC_ATTACHED;
710fcf3ce44SJohn Forte 		hba->flag |= FC_PT_TO_PT;
711fcf3ce44SJohn Forte 
712*8f23e9faSHans Rosenfeld 		hba->flag &= ~FC_NPIV_SUPPORTED;
713*8f23e9faSHans Rosenfeld 		(void) strlcpy(buffer, "npiv:Disabled.", sizeof (buffer));
714*8f23e9faSHans Rosenfeld 
715*8f23e9faSHans Rosenfeld 		if (emlxs_wwn_cmp((uint8_t *)&sp->portName,
716*8f23e9faSHans Rosenfeld 		    (