1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*a9800bebSGarrett D'Amore  * Copyright 2011 Emulex.  All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
2782527734SSukumar Swaminathan 
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte 
30fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
31fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_ELS_C);
32fcf3ce44SJohn Forte 
33291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp);
34*a9800bebSGarrett D'Amore static void	emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp);
35291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp);
36291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp);
37291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp);
38291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp);
39291a2b48SSukumar Swaminathan 
4082527734SSukumar Swaminathan static void	emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp,
41291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4282527734SSukumar Swaminathan static void	emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp,
43291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4482527734SSukumar Swaminathan static void	emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp,
45291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4682527734SSukumar Swaminathan static void	emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp,
47291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4882527734SSukumar Swaminathan static void	emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp,
49291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5082527734SSukumar Swaminathan static void	emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp,
51291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5282527734SSukumar Swaminathan static void	emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp,
53291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5482527734SSukumar Swaminathan static void	emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp,
55291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5682527734SSukumar Swaminathan static void	emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp,
57291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
58*a9800bebSGarrett D'Amore static void	emlxs_handle_unsol_echo_cmd(emlxs_port_t *port, CHANNEL *cp,
59*a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
60*a9800bebSGarrett D'Amore static void	emlxs_handle_unsol_rtv_cmd(emlxs_port_t *port, CHANNEL *cp,
61*a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
62*a9800bebSGarrett D'Amore static void	emlxs_handle_unsol_rls_cmd(emlxs_port_t *port, CHANNEL *cp,
63*a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
64291a2b48SSukumar Swaminathan static void	emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
65291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
66291a2b48SSukumar Swaminathan static void	emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
67291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
68*a9800bebSGarrett D'Amore 
69*a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4)
70291a2b48SSukumar Swaminathan static void	emlxs_send_rsnn(emlxs_port_t *port);
71fcf3ce44SJohn Forte 
72*a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */
73fcf3ce44SJohn Forte 
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte 
76fcf3ce44SJohn Forte /* Routine Declaration - Local */
77fcf3ce44SJohn Forte /* End Routine Declaration - Local */
78fcf3ce44SJohn Forte 
79fcf3ce44SJohn Forte /*
80fcf3ce44SJohn Forte  *  emlxs_els_handle_event
81fcf3ce44SJohn Forte  *
82291a2b48SSukumar Swaminathan  *  Description: Process an ELS Response Ring cmpl
83fcf3ce44SJohn Forte  *
84fcf3ce44SJohn Forte  */
85fcf3ce44SJohn Forte extern int
8682527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
87fcf3ce44SJohn Forte {
88fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
89fcf3ce44SJohn Forte 	IOCB *iocb;
90fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
91fcf3ce44SJohn Forte 	fc_packet_t *pkt;
92fcf3ce44SJohn Forte 	uint32_t *lp0;
93fcf3ce44SJohn Forte 	uint32_t command;
94fcf3ce44SJohn Forte 	NODELIST *ndlp;
95fcf3ce44SJohn Forte 	uint32_t did;
96fcf3ce44SJohn Forte 	ELS_PKT *els;
97fcf3ce44SJohn Forte 
98fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
99fcf3ce44SJohn Forte 
100fcf3ce44SJohn Forte 	HBASTATS.ElsEvent++;
101fcf3ce44SJohn Forte 
102fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
103fcf3ce44SJohn Forte 
104fcf3ce44SJohn Forte 	if (!sbp) {
105fcf3ce44SJohn Forte 		/*
106fcf3ce44SJohn Forte 		 * completion with missing xmit command
107fcf3ce44SJohn Forte 		 */
108fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
109fcf3ce44SJohn Forte 
110fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
111fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
11282527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
11382527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
114291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
115fcf3ce44SJohn Forte 
116fcf3ce44SJohn Forte 		return (1);
117fcf3ce44SJohn Forte 	}
118291a2b48SSukumar Swaminathan 
11982527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_els) {
120fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
121fcf3ce44SJohn Forte 
122fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
12382527734SSukumar Swaminathan 		    "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x "
12482527734SSukumar Swaminathan 		    "status=0x%x perr=0x%x", cp->channelno, iocbq,
12582527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG,
12682527734SSukumar Swaminathan 		    iocb->ULPSTATUS, iocb->un.ulpWord[4]);
127fcf3ce44SJohn Forte 
128fcf3ce44SJohn Forte 		return (1);
129fcf3ce44SJohn Forte 	}
130291a2b48SSukumar Swaminathan 
131fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
132fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
133fcf3ce44SJohn Forte 	lp0 = (uint32_t *)pkt->pkt_cmd;
134fcf3ce44SJohn Forte 	command = *lp0 & ELS_CMD_MASK;
13582527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
136fcf3ce44SJohn Forte 
137fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
138fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
13982527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
140fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
141fcf3ce44SJohn Forte 	}
142291a2b48SSukumar Swaminathan 
14382527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
144291a2b48SSukumar Swaminathan 		/*
145291a2b48SSukumar Swaminathan 		 * ELS Reply completion
146291a2b48SSukumar Swaminathan 		 */
147fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP_CX:
148fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP64_CX:
149fcf3ce44SJohn Forte 
150fcf3ce44SJohn Forte 		HBASTATS.ElsRspCompleted++;
151fcf3ce44SJohn Forte 
152fcf3ce44SJohn Forte 		if (command == ELS_CMD_ACC) {
153fcf3ce44SJohn Forte 			emlxs_handle_acc(port, sbp, iocbq, 1);
154fcf3ce44SJohn Forte 		} else {
155fcf3ce44SJohn Forte 			emlxs_handle_reject(port, sbp, iocbq, 1);
156fcf3ce44SJohn Forte 		}
157fcf3ce44SJohn Forte 
158fcf3ce44SJohn Forte 		break;
159fcf3ce44SJohn Forte 
160291a2b48SSukumar Swaminathan 		/*
161291a2b48SSukumar Swaminathan 		 * ELS command completion
162291a2b48SSukumar Swaminathan 		 */
163fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CR:
164fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CR:
165fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CX:
166fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CX:
167fcf3ce44SJohn Forte 
168fcf3ce44SJohn Forte 		HBASTATS.ElsCmdCompleted++;
169fcf3ce44SJohn Forte 
170fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_ELS_RSP_VALID;
171fcf3ce44SJohn Forte 
172fcf3ce44SJohn Forte 		els = (ELS_PKT *)pkt->pkt_resp;
173fcf3ce44SJohn Forte 
174fcf3ce44SJohn Forte 		pkt->pkt_resp_resid =
175fcf3ce44SJohn Forte 		    pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize;
176fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
177fcf3ce44SJohn Forte 
178fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id;
179fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
180fcf3ce44SJohn Forte 
18182527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) {
182fcf3ce44SJohn Forte 			HBASTATS.ElsCmdGood++;
183fcf3ce44SJohn Forte 
184fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
185fcf3ce44SJohn Forte 				/*
186291a2b48SSukumar Swaminathan 				 * ULP patch - ULP expects
187291a2b48SSukumar Swaminathan 				 * resp_resid = 0 on success
188fcf3ce44SJohn Forte 				 */
189fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
190fcf3ce44SJohn Forte 			}
191291a2b48SSukumar Swaminathan 
192fcf3ce44SJohn Forte 			switch (command) {
193fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
194*a9800bebSGarrett D'Amore 				emlxs_handle_sol_fdisc(port, sbp);
195fcf3ce44SJohn Forte 
196fcf3ce44SJohn Forte 				break;
197fcf3ce44SJohn Forte 
198fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
199fcf3ce44SJohn Forte 				emlxs_handle_sol_flogi(port, sbp);
200fcf3ce44SJohn Forte 
201fcf3ce44SJohn Forte 				break;
202fcf3ce44SJohn Forte 
203fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login */
204fcf3ce44SJohn Forte 				emlxs_handle_sol_plogi(port, sbp);
205fcf3ce44SJohn Forte 
206fcf3ce44SJohn Forte 				break;
207fcf3ce44SJohn Forte 
208fcf3ce44SJohn Forte 			case ELS_CMD_ADISC:	/* Adisc */
209fcf3ce44SJohn Forte 				emlxs_handle_sol_adisc(port, sbp);
210fcf3ce44SJohn Forte 
211fcf3ce44SJohn Forte 				break;
212fcf3ce44SJohn Forte 
213fcf3ce44SJohn Forte 			case ELS_CMD_LOGO:	/* Logout */
214fcf3ce44SJohn Forte 				emlxs_handle_sol_logo(port, sbp);
215fcf3ce44SJohn Forte 
216fcf3ce44SJohn Forte 				break;
217fcf3ce44SJohn Forte 
218fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In */
219fcf3ce44SJohn Forte 				emlxs_handle_sol_prli(port, sbp);
220fcf3ce44SJohn Forte 
221fcf3ce44SJohn Forte 				break;
222fcf3ce44SJohn Forte 
223fcf3ce44SJohn Forte 			default:
224fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
225291a2b48SSukumar Swaminathan 				    &emlxs_els_completion_msg, "%s: did=%x",
226fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did);
227fcf3ce44SJohn Forte 
228fcf3ce44SJohn Forte 				emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
229fcf3ce44SJohn Forte 
230fcf3ce44SJohn Forte 				break;
231fcf3ce44SJohn Forte 			}
232fcf3ce44SJohn Forte 
233fcf3ce44SJohn Forte 		} else {
234fcf3ce44SJohn Forte 			HBASTATS.ElsCmdError++;
235fcf3ce44SJohn Forte 
236fcf3ce44SJohn Forte 			/* Look for LS_REJECT */
23782527734SSukumar Swaminathan 			if (iocb->ULPSTATUS == IOSTAT_LS_RJT) {
238fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_LS_RJT;
239fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
240fcf3ce44SJohn Forte 				pkt->pkt_reason = iocb->un.grsp.perr.statRsn;
241fcf3ce44SJohn Forte 				pkt->pkt_expln = iocb->un.grsp.perr.statBaExp;
242fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
243fcf3ce44SJohn Forte 
244291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
245291a2b48SSukumar Swaminathan 				ndlp = emlxs_node_find_did(port, did);
246291a2b48SSukumar Swaminathan 				if (ndlp) {
247291a2b48SSukumar Swaminathan 					emlxs_log_sd_lsrjt_event(port,
248291a2b48SSukumar Swaminathan 					    (HBA_WWN *)&ndlp->nlp_portname,
249291a2b48SSukumar Swaminathan 					    command, pkt->pkt_reason,
250291a2b48SSukumar Swaminathan 					    pkt->pkt_expln);
251291a2b48SSukumar Swaminathan 				}
252291a2b48SSukumar Swaminathan #endif
253291a2b48SSukumar Swaminathan 
254fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
255fcf3ce44SJohn Forte 				    &emlxs_els_completion_msg,
256fcf3ce44SJohn Forte 				    "%s Rejected: did=%x rsn=%x exp=%x",
257fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
258fcf3ce44SJohn Forte 				    pkt->pkt_reason, pkt->pkt_expln);
25982527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
260fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
261fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
262fcf3ce44SJohn Forte 				    "%s: did=%x Local Reject. %s",
263fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
264291a2b48SSukumar Swaminathan 				    emlxs_error_xlate(iocb->un.grsp.perr.
265291a2b48SSukumar Swaminathan 				    statLocalError));
266fcf3ce44SJohn Forte 			} else {
267fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
268fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
269fcf3ce44SJohn Forte 				    "%s: did=%x %s (%02x%02x%02x%02x)",
270fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
27182527734SSukumar Swaminathan 				    emlxs_state_xlate(iocb->ULPSTATUS),
272fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statAction,
273fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statRsn,
274fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statBaExp,
275fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statLocalError);
276fcf3ce44SJohn Forte 			}
277fcf3ce44SJohn Forte 
278fcf3ce44SJohn Forte 			switch (command) {
279fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login failed */
280fcf3ce44SJohn Forte 				ndlp = emlxs_node_find_did(port, did);
281fcf3ce44SJohn Forte 
282fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
283fcf3ce44SJohn Forte 					/* Open the node again */
284fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28582527734SSukumar Swaminathan 					    hba->channel_fcp);
286fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28782527734SSukumar Swaminathan 					    hba->channel_ip);
288fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
289fcf3ce44SJohn Forte 					if (pkt->pkt_state == FC_PKT_LS_RJT) {
290fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
291fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
292fcf3ce44SJohn Forte 						    pkt->pkt_reason,
293fcf3ce44SJohn Forte 						    pkt->pkt_expln);
294fcf3ce44SJohn Forte 					}
295291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
296fcf3ce44SJohn Forte 				}
297291a2b48SSukumar Swaminathan 
298fcf3ce44SJohn Forte 				break;
299fcf3ce44SJohn Forte 
300fcf3ce44SJohn Forte 
301fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In failed */
302fcf3ce44SJohn Forte 				ndlp = emlxs_node_find_did(port, did);
303fcf3ce44SJohn Forte 
304fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
305fcf3ce44SJohn Forte 					/* Open the node again */
306fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
30782527734SSukumar Swaminathan 					    hba->channel_fcp);
308fcf3ce44SJohn Forte 				}
309291a2b48SSukumar Swaminathan 
310fcf3ce44SJohn Forte 				break;
311fcf3ce44SJohn Forte 
312fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
313fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
314fcf3ce44SJohn Forte 				if (pkt->pkt_state == FC_PKT_LS_RJT) {
315291a2b48SSukumar Swaminathan 					/* This will cause ULP to retry */
316291a2b48SSukumar Swaminathan 					/* FLOGI requests */
317fcf3ce44SJohn Forte 					pkt->pkt_reason = FC_REASON_QFULL;
318fcf3ce44SJohn Forte 					pkt->pkt_expln = 0;
319fcf3ce44SJohn Forte 
320fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
321fcf3ce44SJohn Forte 					ndlp = emlxs_node_find_did(port, did);
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 
331*a9800bebSGarrett D'Amore 				if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
332*a9800bebSGarrett D'Amore 					(void) emlxs_vpi_logi_failed_notify(
333*a9800bebSGarrett D'Amore 					    sbp->port);
334*a9800bebSGarrett D'Amore 				}
335*a9800bebSGarrett D'Amore 
336fcf3ce44SJohn Forte 				break;
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 			default:
339fcf3ce44SJohn Forte 				break;
340fcf3ce44SJohn Forte 			}
341fcf3ce44SJohn Forte 
34282527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
343fcf3ce44SJohn Forte 			    iocb->un.grsp.perr.statLocalError, 1);
344fcf3ce44SJohn Forte 		}
345fcf3ce44SJohn Forte 
346fcf3ce44SJohn Forte 		break;
347fcf3ce44SJohn Forte 
348fcf3ce44SJohn Forte 	default:
349fcf3ce44SJohn Forte 
350fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
351fcf3ce44SJohn Forte 
352fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg,
35382527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
354fcf3ce44SJohn Forte 
35582527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
356fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
357fcf3ce44SJohn Forte 
358fcf3ce44SJohn Forte 		break;
35982527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte 	return (0);
362fcf3ce44SJohn Forte 
36382527734SSukumar Swaminathan } /* emlxs_els_handle_event() */
364fcf3ce44SJohn Forte 
365fcf3ce44SJohn Forte 
366fcf3ce44SJohn Forte extern int
36782527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
368fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
369fcf3ce44SJohn Forte {
370fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
371fcf3ce44SJohn Forte 	uint32_t cmd_code;
372*a9800bebSGarrett D'Amore 	IOCB *iocb;
373fcf3ce44SJohn Forte 
374fcf3ce44SJohn Forte 	HBASTATS.ElsCmdReceived++;
375fcf3ce44SJohn Forte 
376*a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
377fcf3ce44SJohn Forte 	cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK;
378fcf3ce44SJohn Forte 
37982527734SSukumar Swaminathan 	if (!(port->flag & EMLXS_PORT_BOUND)) {
380e2ca2865SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
381e2ca2865SSukumar Swaminathan 		    "%s: sid=%x. Port not bound: Rejecting.",
382e2ca2865SSukumar Swaminathan 		    emlxs_elscmd_xlate(cmd_code),
383e2ca2865SSukumar Swaminathan 		    iocbq->iocb.un.elsreq.remoteID);
38482527734SSukumar Swaminathan 
38582527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
386e2ca2865SSukumar Swaminathan 		    cmd_code, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
38782527734SSukumar Swaminathan 
38882527734SSukumar Swaminathan 		return (0);
38982527734SSukumar Swaminathan 	}
39082527734SSukumar Swaminathan 
391fcf3ce44SJohn Forte 	switch (cmd_code) {
392fcf3ce44SJohn Forte 	case ELS_CMD_RSCN:
393fcf3ce44SJohn Forte 		HBASTATS.ElsRscnReceived++;
39482527734SSukumar Swaminathan 		emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size);
395fcf3ce44SJohn Forte 		break;
396fcf3ce44SJohn Forte 
397fcf3ce44SJohn Forte 	case ELS_CMD_FLOGI:
398fcf3ce44SJohn Forte 		HBASTATS.ElsFlogiReceived++;
39982527734SSukumar Swaminathan 		emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size);
400fcf3ce44SJohn Forte 		break;
401fcf3ce44SJohn Forte 
402fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
403fcf3ce44SJohn Forte 		HBASTATS.ElsPlogiReceived++;
40482527734SSukumar Swaminathan 		emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size);
405fcf3ce44SJohn Forte 		break;
406fcf3ce44SJohn Forte 
407fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
408fcf3ce44SJohn Forte 		HBASTATS.ElsPrliReceived++;
40982527734SSukumar Swaminathan 		emlxs_handle_unsol_prli(port, cp, iocbq, mp, size);
410fcf3ce44SJohn Forte 		break;
411fcf3ce44SJohn Forte 
412fcf3ce44SJohn Forte 	case ELS_CMD_PRLO:
413fcf3ce44SJohn Forte 		HBASTATS.ElsPrloReceived++;
41482527734SSukumar Swaminathan 		emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size);
415fcf3ce44SJohn Forte 		break;
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 	case ELS_CMD_LOGO:
418fcf3ce44SJohn Forte 		HBASTATS.ElsLogoReceived++;
41982527734SSukumar Swaminathan 		emlxs_handle_unsol_logo(port, cp, iocbq, mp, size);
420fcf3ce44SJohn Forte 		break;
421fcf3ce44SJohn Forte 
422fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
423fcf3ce44SJohn Forte 		HBASTATS.ElsAdiscReceived++;
42482527734SSukumar Swaminathan 		emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size);
425fcf3ce44SJohn Forte 		break;
426fcf3ce44SJohn Forte 
427fcf3ce44SJohn Forte 	case ELS_CMD_AUTH:
428fcf3ce44SJohn Forte 		HBASTATS.ElsAuthReceived++;
42982527734SSukumar Swaminathan 		emlxs_handle_unsol_auth(port, cp, iocbq, mp, size);
430fcf3ce44SJohn Forte 		break;
431fcf3ce44SJohn Forte 
432*a9800bebSGarrett D'Amore 	case ELS_CMD_TEST:
433*a9800bebSGarrett D'Amore 		HBASTATS.ElsTestReceived++;
434*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
435*a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
436*a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
437*a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
438*a9800bebSGarrett D'Amore 
439*a9800bebSGarrett D'Amore 		/* drop it */
440*a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
441*a9800bebSGarrett D'Amore 		break;
442*a9800bebSGarrett D'Amore 
443*a9800bebSGarrett D'Amore 	case ELS_CMD_ESTC:
444*a9800bebSGarrett D'Amore 		HBASTATS.ElsEstcReceived++;
445*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
446*a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
447*a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
448*a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
449*a9800bebSGarrett D'Amore 
450*a9800bebSGarrett D'Amore 		/* drop it */
451*a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
452*a9800bebSGarrett D'Amore 		break;
453*a9800bebSGarrett D'Amore 
454*a9800bebSGarrett D'Amore 	case ELS_CMD_FARPR:
455*a9800bebSGarrett D'Amore 		HBASTATS.ElsFarprReceived++;
456*a9800bebSGarrett D'Amore 
457*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
458*a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
459*a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
460*a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
461*a9800bebSGarrett D'Amore 
462*a9800bebSGarrett D'Amore 		/* drop it */
463*a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
464*a9800bebSGarrett D'Amore 		break;
465*a9800bebSGarrett D'Amore 
466*a9800bebSGarrett D'Amore 	case ELS_CMD_ECHO:
467*a9800bebSGarrett D'Amore 		HBASTATS.ElsEchoReceived++;
468*a9800bebSGarrett D'Amore 		emlxs_handle_unsol_echo_cmd(port, cp, iocbq, mp, size);
469*a9800bebSGarrett D'Amore 		break;
470*a9800bebSGarrett D'Amore 
471*a9800bebSGarrett D'Amore 	case ELS_CMD_RLS:
472*a9800bebSGarrett D'Amore 		HBASTATS.ElsRlsReceived++;
473*a9800bebSGarrett D'Amore 		emlxs_handle_unsol_rls_cmd(port, cp, iocbq, mp, size);
474*a9800bebSGarrett D'Amore 		break;
475*a9800bebSGarrett D'Amore 
476*a9800bebSGarrett D'Amore 	case ELS_CMD_RTV:
477*a9800bebSGarrett D'Amore 		HBASTATS.ElsRtvReceived++;
478*a9800bebSGarrett D'Amore 		emlxs_handle_unsol_rtv_cmd(port, cp, iocbq, mp, size);
479*a9800bebSGarrett D'Amore 		break;
480*a9800bebSGarrett D'Amore 
481*a9800bebSGarrett D'Amore 	case ELS_CMD_ABTX:
482*a9800bebSGarrett D'Amore 	case ELS_CMD_RCS:
483*a9800bebSGarrett D'Amore 	case ELS_CMD_RES:
484*a9800bebSGarrett D'Amore 	case ELS_CMD_RSS:
485*a9800bebSGarrett D'Amore 	case ELS_CMD_RSI:
486*a9800bebSGarrett D'Amore 	case ELS_CMD_ESTS:
487*a9800bebSGarrett D'Amore 	case ELS_CMD_RRQ:
488*a9800bebSGarrett D'Amore 	case ELS_CMD_REC:
489*a9800bebSGarrett D'Amore 		HBASTATS.ElsGenReceived++;
490*a9800bebSGarrett D'Amore 
491*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
492*a9800bebSGarrett D'Amore 		    "%s: sid=%x. Rejecting.",
493*a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
494*a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
495*a9800bebSGarrett D'Amore 
496*a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
497*a9800bebSGarrett D'Amore 		    LSRJT_CMD_UNSUPPORTED, LSEXP_NOTHING_MORE);
498*a9800bebSGarrett D'Amore 		break;
499*a9800bebSGarrett D'Amore 
500fcf3ce44SJohn Forte 	default:
501fcf3ce44SJohn Forte 		HBASTATS.ElsGenReceived++;
50282527734SSukumar Swaminathan 		emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size);
503fcf3ce44SJohn Forte 		break;
504fcf3ce44SJohn Forte 	}
505fcf3ce44SJohn Forte 
506fcf3ce44SJohn Forte 	return (0);
507fcf3ce44SJohn Forte 
50882527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */
509fcf3ce44SJohn Forte 
510fcf3ce44SJohn Forte 
511fcf3ce44SJohn Forte static void
512fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp)
513fcf3ce44SJohn Forte {
514fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
515fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
516fcf3ce44SJohn Forte 	emlxs_port_t *vport;
517fcf3ce44SJohn Forte 	SERV_PARM *sp;
518fcf3ce44SJohn Forte 	fc_packet_t *pkt;
519fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
520fcf3ce44SJohn Forte 	uint32_t did;
521fcf3ce44SJohn Forte 	IOCBQ *iocbq;
522fcf3ce44SJohn Forte 	IOCB *iocb;
523fcf3ce44SJohn Forte 	char buffer[64];
524fcf3ce44SJohn Forte 	uint32_t i;
52582527734SSukumar Swaminathan 	int rc;
526*a9800bebSGarrett D'Amore 	uint16_t altBbCredit;
527fcf3ce44SJohn Forte 
528fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
529fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
53082527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
531fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
532fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
533fcf3ce44SJohn Forte 
534*a9800bebSGarrett D'Amore 	mutex_enter(&EMLXS_PORT_LOCK);
535fcf3ce44SJohn Forte 
536*a9800bebSGarrett D'Amore 	/* Save the fabric service parameters and did */
537*a9800bebSGarrett D'Amore 	port->did = iocb->un.elsreq.myID;
538*a9800bebSGarrett D'Amore 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
539*a9800bebSGarrett D'Amore 
540*a9800bebSGarrett D'Amore 	if (sp->cmn.fPort) {
541fcf3ce44SJohn Forte 		hba->flag |= FC_FABRIC_ATTACHED;
542fcf3ce44SJohn Forte 		hba->flag &= ~FC_PT_TO_PT;
543fcf3ce44SJohn Forte 
54482527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID);
54582527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
546fcf3ce44SJohn Forte 
547fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
548fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
549fcf3ce44SJohn Forte 			hba->fc_edtov =
55082527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
551fcf3ce44SJohn Forte 		} else {
55282527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
553fcf3ce44SJohn Forte 		}
554fcf3ce44SJohn Forte 
555fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
556291a2b48SSukumar Swaminathan 		hba->fc_ratov =
55782527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
558fcf3ce44SJohn Forte 
559*a9800bebSGarrett D'Amore 		/*
560*a9800bebSGarrett D'Amore 		 * If we are a N-port connected to a Fabric,
561*a9800bebSGarrett D'Amore 		 * fixup sparam's so logins to devices on remote
562*a9800bebSGarrett D'Amore 		 * loops work.
563*a9800bebSGarrett D'Amore 		 */
564*a9800bebSGarrett D'Amore 		altBbCredit = (hba->topology != TOPOLOGY_LOOP)? 1:0;
565*a9800bebSGarrett D'Amore 		hba->sparam.cmn.altBbCredit = altBbCredit;
566fcf3ce44SJohn Forte 
567*a9800bebSGarrett D'Amore 		/* Set this bit in all the port sparam copies */
568*a9800bebSGarrett D'Amore 		for (i = 0; i < MAX_VPORTS; i++) {
569*a9800bebSGarrett D'Amore 			vport = &VPORT(i);
570291a2b48SSukumar Swaminathan 
571*a9800bebSGarrett D'Amore 			if (!(vport->flag & EMLXS_PORT_BOUND)) {
572*a9800bebSGarrett D'Amore 				continue;
573fcf3ce44SJohn Forte 			}
574*a9800bebSGarrett D'Amore 
575*a9800bebSGarrett D'Amore 			vport->sparam.cmn.altBbCredit = altBbCredit;
576fcf3ce44SJohn Forte 		}
57782527734SSukumar Swaminathan 
578fcf3ce44SJohn Forte 		if (sp->cmn.rspMultipleNPort) {
579fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_SUPPORTED;
580fcf3ce44SJohn Forte 
581fcf3ce44SJohn Forte 			if (cfg[CFG_NPIV_DELAY].current) {
582fcf3ce44SJohn Forte 				/*
583291a2b48SSukumar Swaminathan 				 * PATCH: for NPIV support on
584291a2b48SSukumar Swaminathan 				 * Brocade switch firmware 5.10b
585fcf3ce44SJohn Forte 				 */
586fcf3ce44SJohn Forte 				if ((hba->flag & FC_NPIV_ENABLED) &&
587fcf3ce44SJohn Forte 				    ((sp->nodeName.IEEE[0] == 0x00) &&
588fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[1] == 0x05) &&
589fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[2] == 0x1e))) {
590fcf3ce44SJohn Forte 					hba->flag |= FC_NPIV_DELAY_REQUIRED;
591fcf3ce44SJohn Forte 				}
592fcf3ce44SJohn Forte 			}
593fcf3ce44SJohn Forte 		} else {
594fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_UNSUPPORTED;
595fcf3ce44SJohn Forte 		}
596fcf3ce44SJohn Forte 
597fcf3ce44SJohn Forte 		if (!(hba->flag & FC_NPIV_ENABLED)) {
598fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Disabled ");
599fcf3ce44SJohn Forte 		} else if (hba->flag & FC_NPIV_SUPPORTED) {
600fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Supported ");
601fcf3ce44SJohn Forte 		} else {
602fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Unsupported ");
603fcf3ce44SJohn Forte 		}
604fcf3ce44SJohn Forte 
605fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
606fcf3ce44SJohn Forte 		if (!sp->cmn.fcsp_support) {
607fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Unsupported");
608fcf3ce44SJohn Forte 		} else if (cfg[CFG_AUTH_ENABLE].current &&
609fcf3ce44SJohn Forte 		    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
610fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Supported");
611fcf3ce44SJohn Forte 		} else {
612fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Disabled");
613fcf3ce44SJohn Forte 		}
614291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
615fcf3ce44SJohn Forte 
616fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
617fcf3ce44SJohn Forte 
618fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
619291a2b48SSukumar Swaminathan 		    "FLOGI: did=%x sid=%x %s", did, port->did, buffer);
620fcf3ce44SJohn Forte 
621*a9800bebSGarrett D'Amore 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
622*a9800bebSGarrett D'Amore 			/* Deferred completion */
623*a9800bebSGarrett D'Amore 			(void) emlxs_vpi_logi_cmpl_notify(sbp->port, sbp);
624*a9800bebSGarrett D'Amore 			return;
625*a9800bebSGarrett D'Amore 		}
626*a9800bebSGarrett D'Amore 
62782527734SSukumar Swaminathan 		if (!(mbox = (MAILBOXQ *)emlxs_mem_get(hba,
62882527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
62982527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
63082527734SSukumar Swaminathan 			    IOERR_NO_RESOURCES, 1);
63182527734SSukumar Swaminathan 			return;
63282527734SSukumar Swaminathan 		}
63382527734SSukumar Swaminathan 
634*a9800bebSGarrett D'Amore 		/* Update our service parms */
63582527734SSukumar Swaminathan 		emlxs_mb_config_link(hba, mbox);
63682527734SSukumar Swaminathan 
63782527734SSukumar Swaminathan 		rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0);
63882527734SSukumar Swaminathan 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
639*a9800bebSGarrett D'Amore 			emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
640fcf3ce44SJohn Forte 		}
641291a2b48SSukumar Swaminathan 
642fcf3ce44SJohn Forte 		/* Preset the state for the reg_did */
643fcf3ce44SJohn Forte 		emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
644fcf3ce44SJohn Forte 
64582527734SSukumar Swaminathan 		if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam,
646fcf3ce44SJohn Forte 		    sbp, NULL, NULL) == 0) {
647291a2b48SSukumar Swaminathan 			/* Deferred completion of this pkt until */
648291a2b48SSukumar Swaminathan 			/* login is complete */
649fcf3ce44SJohn Forte 			return;
650fcf3ce44SJohn Forte 		}
651291a2b48SSukumar Swaminathan 
652fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
653fcf3ce44SJohn Forte 		    IOERR_NO_RESOURCES, 1);
654fcf3ce44SJohn Forte 
655fcf3ce44SJohn Forte 	} else {	/* No switch */
656291a2b48SSukumar Swaminathan 
657fcf3ce44SJohn Forte 		hba->flag &= ~FC_FABRIC_ATTACHED;
658fcf3ce44SJohn Forte 		hba->flag |= FC_PT_TO_PT;
659fcf3ce44SJohn Forte 
660fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
661fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
662fcf3ce44SJohn Forte 			hba->fc_edtov =
66382527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
664fcf3ce44SJohn Forte 		} else {
66582527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
666fcf3ce44SJohn Forte 		}
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
669291a2b48SSukumar Swaminathan 		hba->fc_ratov =
67082527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
671fcf3ce44SJohn Forte 
672fcf3ce44SJohn Forte 		hba->flag &= ~FC_NPIV_SUPPORTED;
673fcf3ce44SJohn Forte 		(void) strcpy(buffer, "npiv:Disabled. P2P");
67482527734SSukumar Swaminathan 
67582527734SSukumar Swaminathan 		port->rdid = did;
676fcf3ce44SJohn Forte 
677fcf3ce44SJohn Forte 		/* Clear the fabric service parameters */
678fcf3ce44SJohn Forte 		bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM));
679fcf3ce44SJohn Forte 
680fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
681fcf3ce44SJohn Forte 
682fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
683291a2b48SSukumar Swaminathan 		    "FLOGI: did=%x sid=%x %s", did, port->did, buffer);
684fcf3ce44SJohn Forte 
685fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
686fcf3ce44SJohn Forte 	}
687fcf3ce44SJohn Forte 
688fcf3ce44SJohn Forte 	return;
689fcf3ce44SJohn Forte 
69082527734SSukumar Swaminathan } /* emlxs_handle_sol_flogi() */
691fcf3ce44SJohn Forte 
692fcf3ce44SJohn Forte 
693fcf3ce44SJohn Forte static void
694*a9800bebSGarrett D'Amore emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp)
695fcf3ce44SJohn Forte {
696fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
697fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
698fcf3ce44SJohn Forte 	SERV_PARM *sp;
699fcf3ce44SJohn Forte 	fc_packet_t *pkt;
700fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
701fcf3ce44SJohn Forte 	uint32_t did;
702fcf3ce44SJohn Forte 	IOCBQ *iocbq;
703fcf3ce44SJohn Forte 	IOCB *iocb;
704fcf3ce44SJohn Forte 	char buffer[64];
70582527734SSukumar Swaminathan 	int rc;
706fcf3ce44SJohn Forte 
707fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
708fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
70982527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
710fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
711fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
712fcf3ce44SJohn Forte 
713fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
714fcf3ce44SJohn Forte 
715*a9800bebSGarrett D'Amore 	/* Save the fabric service parameters and did */
716fcf3ce44SJohn Forte 	port->did = iocb->un.elsreq.myID;
717fcf3ce44SJohn Forte 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
718fcf3ce44SJohn Forte 
719*a9800bebSGarrett D'Amore 	pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
720*a9800bebSGarrett D'Amore 
721fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
722fcf3ce44SJohn Forte 
723fcf3ce44SJohn Forte 	buffer[0] = 0;
724fcf3ce44SJohn Forte 
725fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
726fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
727fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
728291a2b48SSukumar Swaminathan 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_NPIV].current) {
729fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
730fcf3ce44SJohn Forte 	} else {
731fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
732fcf3ce44SJohn Forte 	}
733291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
734fcf3ce44SJohn Forte 
735fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
736*a9800bebSGarrett D'Amore 	    "FDISC: did=%x sid=%x %s", did, port->did, buffer);
737fcf3ce44SJohn Forte 
73882527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
739*a9800bebSGarrett D'Amore 		(void) emlxs_vpi_logi_cmpl_notify(sbp->port, sbp);
74082527734SSukumar Swaminathan 		return;
74182527734SSukumar Swaminathan 	}
74282527734SSukumar Swaminathan 
743fcf3ce44SJohn Forte 	/* Update our service parms */
74482527734SSukumar Swaminathan 	if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
74582527734SSukumar Swaminathan 		emlxs_mb_config_link(hba, mbox);
746fcf3ce44SJohn Forte 
74782527734SSukumar Swaminathan 		rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
74882527734SSukumar Swaminathan 		    MBX_NOWAIT, 0);
74982527734SSukumar Swaminathan 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
750*a9800bebSGarrett D'Amore 			emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
751fcf3ce44SJohn Forte 		}
752fcf3ce44SJohn Forte 	}
753291a2b48SSukumar Swaminathan 
754fcf3ce44SJohn Forte 	/* Preset the state for the reg_did */
755fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
756fcf3ce44SJohn Forte 
75782527734SSukumar Swaminathan 	if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, sbp,
758fcf3ce44SJohn Forte 	    NULL, NULL) == 0) {
759fcf3ce44SJohn Forte 		/*
760fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
761fcf3ce44SJohn Forte 		 */
762fcf3ce44SJohn Forte 
763fcf3ce44SJohn Forte 		return;
764fcf3ce44SJohn Forte 	}
765291a2b48SSukumar Swaminathan 
766fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
767fcf3ce44SJohn Forte 
768fcf3ce44SJohn Forte 	return;
769fcf3ce44SJohn Forte 
770*a9800bebSGarrett D'Amore } /* emlxs_handle_sol_fdisc() */
771fcf3ce44SJohn Forte 
772fcf3ce44SJohn Forte 
773fcf3ce44SJohn Forte static void
774fcf3ce44SJohn Forte emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp)
775fcf3ce44SJohn Forte {
776fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
777fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
778fcf3ce44SJohn Forte 	SERV_PARM *sp;
779fcf3ce44SJohn Forte 	fc_packet_t *pkt;
780fcf3ce44SJohn Forte 	uint32_t did;
781fcf3ce44SJohn Forte 	uint32_t sid;
782fcf3ce44SJohn Forte 	NODELIST *ndlp;
783fcf3ce44SJohn Forte 	char buffer[64];
784fcf3ce44SJohn Forte 
785fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
786fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
78782527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
78882527734SSukumar Swaminathan 	sid = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.s_id);
789fcf3ce44SJohn Forte 
790fcf3ce44SJohn Forte 	buffer[0] = 0;
791fcf3ce44SJohn Forte 
792fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
793fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
794fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
795fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
796fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
797fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
798fcf3ce44SJohn Forte 	} else {
799fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
800fcf3ce44SJohn Forte 	}
801291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
802fcf3ce44SJohn Forte 
803fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
804291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x %s", sid, did, buffer);
805fcf3ce44SJohn Forte 
806fcf3ce44SJohn Forte 	/* Preset the pkt state for reg_did */
807fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
808fcf3ce44SJohn Forte 
809fcf3ce44SJohn Forte 	/*
810fcf3ce44SJohn Forte 	 * Do register login to Firmware before calling packet completion
811fcf3ce44SJohn Forte 	 */
812fcf3ce44SJohn Forte 	if (emlxs_mb_reg_did(port, did, sp, sbp, NULL, NULL) == 0) {
813fcf3ce44SJohn Forte 		/*
814fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
815fcf3ce44SJohn Forte 		 */
816fcf3ce44SJohn Forte 		return;
817fcf3ce44SJohn Forte 	}
818291a2b48SSukumar Swaminathan 
819fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
820fcf3ce44SJohn Forte 
821fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
822fcf3ce44SJohn Forte 		/* Open the node again */
82382527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
82482527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
825fcf3ce44SJohn Forte 	}
826291a2b48SSukumar Swaminathan 
827fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
828fcf3ce44SJohn Forte 
829fcf3ce44SJohn Forte 	return;
830fcf3ce44SJohn Forte 
83182527734SSukumar Swaminathan } /* emlxs_handle_sol_plogi() */
832fcf3ce44SJohn Forte 
833fcf3ce44SJohn Forte 
834fcf3ce44SJohn Forte static void
835fcf3ce44SJohn Forte emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp)
836fcf3ce44SJohn Forte {
83782527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
838fcf3ce44SJohn Forte 	fc_packet_t *pkt;
839fcf3ce44SJohn Forte 	uint32_t did;
840fcf3ce44SJohn Forte 	NODELIST *ndlp;
841fcf3ce44SJohn Forte 
842fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
84382527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
844fcf3ce44SJohn Forte 
845291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "ADISC: did=%x",
846fcf3ce44SJohn Forte 	    did);
847fcf3ce44SJohn Forte 
848fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
849fcf3ce44SJohn Forte 
850fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
851fcf3ce44SJohn Forte 		/* Open the node again */
85282527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
85382527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
85482527734SSukumar Swaminathan 
85582527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
856*a9800bebSGarrett D'Amore 
857*a9800bebSGarrett D'Amore 			emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
858*a9800bebSGarrett D'Amore 
859*a9800bebSGarrett D'Amore 			if (emlxs_rpi_resume_notify(port,
860*a9800bebSGarrett D'Amore 			    ndlp->rpip, sbp) == 0) {
86182527734SSukumar Swaminathan 				/*
86282527734SSukumar Swaminathan 				 * Delay ADISC cmpl to ULP till
86382527734SSukumar Swaminathan 				 * after RESUME_RPI
86482527734SSukumar Swaminathan 				 */
86582527734SSukumar Swaminathan 				return;
86682527734SSukumar Swaminathan 			}
86782527734SSukumar Swaminathan 		}
868fcf3ce44SJohn Forte 	}
869291a2b48SSukumar Swaminathan 
870fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
871fcf3ce44SJohn Forte 
872fcf3ce44SJohn Forte 	return;
873fcf3ce44SJohn Forte 
87482527734SSukumar Swaminathan } /* emlxs_handle_sol_adisc() */
875fcf3ce44SJohn Forte 
876fcf3ce44SJohn Forte 
877fcf3ce44SJohn Forte static void
878fcf3ce44SJohn Forte emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp)
879fcf3ce44SJohn Forte {
880fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
881fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
882fcf3ce44SJohn Forte 	fc_packet_t *pkt;
883fcf3ce44SJohn Forte 	NODELIST *ndlp;
884fcf3ce44SJohn Forte 	uint32_t did;
885fcf3ce44SJohn Forte 	PRLI *npr;
886fcf3ce44SJohn Forte 	uint32_t task_retry_id;
887fcf3ce44SJohn Forte 
888fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
889fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
89082527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
891fcf3ce44SJohn Forte 
892fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
893fcf3ce44SJohn Forte 
894fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
895fcf3ce44SJohn Forte 		/* Check for FCP support */
896fcf3ce44SJohn Forte 		if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
897fcf3ce44SJohn Forte 		    (npr->prliType == PRLI_FCP_TYPE)) {
898*a9800bebSGarrett D'Amore 			/* Clear FCP2 support if no ADISC support requested */
899*a9800bebSGarrett D'Amore 			if (cfg[CFG_ADISC_SUPPORT].current == 0) {
900*a9800bebSGarrett D'Amore 				npr->ConfmComplAllowed = 0;
901*a9800bebSGarrett D'Amore 				npr->TaskRetryIdReq = 0;
902*a9800bebSGarrett D'Amore 				npr->Retry = 0;
903*a9800bebSGarrett D'Amore 			}
904*a9800bebSGarrett D'Amore 
905fcf3ce44SJohn Forte 			/* Check for target */
906fcf3ce44SJohn Forte 			if (npr->targetFunc) {
907fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
908fcf3ce44SJohn Forte 			} else {
909fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
910fcf3ce44SJohn Forte 			}
911fcf3ce44SJohn Forte 
912fcf3ce44SJohn Forte 			/* Check for initiator */
913fcf3ce44SJohn Forte 			if (npr->initiatorFunc) {
914fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
915fcf3ce44SJohn Forte 			} else {
916fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
917fcf3ce44SJohn Forte 			}
918fcf3ce44SJohn Forte 
919291a2b48SSukumar Swaminathan 			/* If TRI support is not required then force */
920291a2b48SSukumar Swaminathan 			/* the task_retry_id value to one */
921fcf3ce44SJohn Forte 			if (cfg[CFG_TRI_REQUIRED].current == 0) {
922fcf3ce44SJohn Forte 				task_retry_id = 1;
923fcf3ce44SJohn Forte 			} else {
924fcf3ce44SJohn Forte 				task_retry_id = npr->TaskRetryIdReq;
925fcf3ce44SJohn Forte 			}
926fcf3ce44SJohn Forte 
927fcf3ce44SJohn Forte 			/* Check for FCP2 target support */
928fcf3ce44SJohn Forte 			/* Retry and TaskRetryId bits are both required here */
929fcf3ce44SJohn Forte 			if (npr->targetFunc && npr->Retry && task_retry_id) {
930fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
931fcf3ce44SJohn Forte 			} else {
932fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
933fcf3ce44SJohn Forte 			}
934fcf3ce44SJohn Forte 		}
935291a2b48SSukumar Swaminathan 
936fcf3ce44SJohn Forte 		/* Open the node again */
93782527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
938fcf3ce44SJohn Forte 
939fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
940291a2b48SSukumar Swaminathan 		    "PRLI: did=%x info=%02x", did, ndlp->nlp_fcp_info);
941fcf3ce44SJohn Forte 
942fcf3ce44SJohn Forte 		/*
943fcf3ce44SJohn Forte 		 * Report PRLI completion
944fcf3ce44SJohn Forte 		 */
945fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
946fcf3ce44SJohn Forte 
947fcf3ce44SJohn Forte 	} else {
948fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
949291a2b48SSukumar Swaminathan 		    "PRLI: did=%x: Node not found. Failing.", did);
950fcf3ce44SJohn Forte 
951fcf3ce44SJohn Forte 		/*
952fcf3ce44SJohn Forte 		 * Report PRLI failed
953fcf3ce44SJohn Forte 		 */
954fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
955fcf3ce44SJohn Forte 		    IOERR_INVALID_RPI, 1);
956fcf3ce44SJohn Forte 	}
957fcf3ce44SJohn Forte 	return;
958fcf3ce44SJohn Forte 
95982527734SSukumar Swaminathan } /* emlxs_handle_sol_prli() */
960fcf3ce44SJohn Forte 
961fcf3ce44SJohn Forte 
962fcf3ce44SJohn Forte static void
963fcf3ce44SJohn Forte emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp)
964fcf3ce44SJohn Forte {
96582527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
966fcf3ce44SJohn Forte 	fc_packet_t *pkt;
967fcf3ce44SJohn Forte 	uint32_t did;
968fcf3ce44SJohn Forte 	NODELIST *ndlp;
969fcf3ce44SJohn Forte 
970fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
97182527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
972fcf3ce44SJohn Forte 
973291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "LOGO: did=%x",
974fcf3ce44SJohn Forte 	    did);
975fcf3ce44SJohn Forte 
976fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
977fcf3ce44SJohn Forte 
978fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
979fcf3ce44SJohn Forte 		/* Close the node for any further normal IO */
98082527734SSukumar Swaminathan 		emlxs_node_close(port, ndlp, hba->channel_fcp, 60);
98182527734SSukumar Swaminathan 		emlxs_node_close(port, ndlp, hba->channel_ip, 60);
982fcf3ce44SJohn Forte 
983fcf3ce44SJohn Forte 		/* Flush tx queues */
984fcf3ce44SJohn Forte 		(void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
985fcf3ce44SJohn Forte 
986fcf3ce44SJohn Forte 		/* Flush chip queues */
987fcf3ce44SJohn Forte 		(void) emlxs_chipq_node_flush(port, 0, ndlp, 0);
988fcf3ce44SJohn Forte 	}
989291a2b48SSukumar Swaminathan 
990fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
991fcf3ce44SJohn Forte 
992fcf3ce44SJohn Forte 	return;
993fcf3ce44SJohn Forte 
99482527734SSukumar Swaminathan } /* emlxs_handle_sol_logo() */
995fcf3ce44SJohn Forte 
996fcf3ce44SJohn Forte 
997fcf3ce44SJohn Forte /* ARGSUSED */
998fcf3ce44SJohn Forte static void
99982527734SSukumar Swaminathan emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1000fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1001fcf3ce44SJohn Forte {
1002fcf3ce44SJohn Forte 	uint32_t *lp;
1003fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1004fcf3ce44SJohn Forte 	uint8_t *bp;
1005fcf3ce44SJohn Forte 	IOCB *iocb;
1006fcf3ce44SJohn Forte 	uint32_t count;
1007fcf3ce44SJohn Forte 	uint32_t sid;
1008fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1009fcf3ce44SJohn Forte 
1010fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1011fcf3ce44SJohn Forte 	bp = mp->virt;
1012291a2b48SSukumar Swaminathan 	lp = (uint32_t *)bp + 1;
1013fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1014fcf3ce44SJohn Forte 
1015291a2b48SSukumar Swaminathan 	/* Log the legacy rscn event for physical port only */
1016291a2b48SSukumar Swaminathan 	if (port->vpi == 0) {
1017291a2b48SSukumar Swaminathan 		emlxs_log_rscn_event(port, bp, size);
1018291a2b48SSukumar Swaminathan 	}
1019291a2b48SSukumar Swaminathan 
1020291a2b48SSukumar Swaminathan 	/* Log the vport rscn event for all ports */
1021291a2b48SSukumar Swaminathan 	emlxs_log_vportrscn_event(port, bp, size);
1022fcf3ce44SJohn Forte 
1023fcf3ce44SJohn Forte 	count = ((size - 4) / 4);
1024fcf3ce44SJohn Forte 
1025fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1);
1026fcf3ce44SJohn Forte 
1027fcf3ce44SJohn Forte 	if (ubp == NULL) {
1028fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1029fcf3ce44SJohn Forte 		    "RSCN rcvd: sid=%x  %d page(s): %08X, %08X. Rejecting.",
103082527734SSukumar Swaminathan 		    sid, count, LE_SWAP32(*lp),
103182527734SSukumar Swaminathan 		    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0));
1032fcf3ce44SJohn Forte 
1033fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1034291a2b48SSukumar Swaminathan 		    ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1035fcf3ce44SJohn Forte 
1036fcf3ce44SJohn Forte 		goto drop_it;
1037fcf3ce44SJohn Forte 	}
1038291a2b48SSukumar Swaminathan 
1039fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1040fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1041fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
1042fcf3ce44SJohn Forte 
1043fcf3ce44SJohn Forte 	/*
1044fcf3ce44SJohn Forte 	 * Setup frame header
1045fcf3ce44SJohn Forte 	 */
1046fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1047fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
104882527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
104982527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1050fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
105182527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1052fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1053fcf3ce44SJohn Forte 
1054fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1055291a2b48SSukumar Swaminathan 	    "RSCN: sid=%x  %d page(s): %08X, %08X  buffer=%p token=%x.", sid,
105682527734SSukumar Swaminathan 	    count, LE_SWAP32(*lp),
105782527734SSukumar Swaminathan 	    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0), ubp, ub_priv->token);
1058fcf3ce44SJohn Forte 
1059fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1060fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1061291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1062fcf3ce44SJohn Forte 
1063fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1064fcf3ce44SJohn Forte 
1065fcf3ce44SJohn Forte drop_it:
1066fcf3ce44SJohn Forte 
1067fcf3ce44SJohn Forte 	return;
1068fcf3ce44SJohn Forte 
106982527734SSukumar Swaminathan } /* emlxs_handle_unsol_rscn() */
1070fcf3ce44SJohn Forte 
1071fcf3ce44SJohn Forte 
1072fcf3ce44SJohn Forte /* This is shared by FCT driver */
1073fcf3ce44SJohn Forte extern uint32_t
1074291a2b48SSukumar Swaminathan emlxs_process_unsol_flogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1075291a2b48SSukumar Swaminathan     uint32_t size, char *buffer)
1076fcf3ce44SJohn Forte {
1077fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1078fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1079fcf3ce44SJohn Forte 	uint8_t *bp;
1080fcf3ce44SJohn Forte 	IOCB *iocb;
1081fcf3ce44SJohn Forte 	uint32_t sid;
1082fcf3ce44SJohn Forte 	SERV_PARM *sp;
1083fcf3ce44SJohn Forte 
1084fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1085fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1086fcf3ce44SJohn Forte 
1087fcf3ce44SJohn Forte 	/* Check payload size */
1088fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1089fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1090291a2b48SSukumar Swaminathan 		    "FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1091291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1092fcf3ce44SJohn Forte 
1093fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1094fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1095fcf3ce44SJohn Forte 
1096fcf3ce44SJohn Forte 		return (1);
1097fcf3ce44SJohn Forte 	}
1098291a2b48SSukumar Swaminathan 
1099fcf3ce44SJohn Forte 	bp = mp->virt;
1100fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1101fcf3ce44SJohn Forte 
1102fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
1103fcf3ce44SJohn Forte 
1104fcf3ce44SJohn Forte 	hba->flag &= ~FC_FABRIC_ATTACHED;
1105fcf3ce44SJohn Forte 	hba->flag |= FC_PT_TO_PT;
1106fcf3ce44SJohn Forte 
1107fcf3ce44SJohn Forte 	/* Save E_D_TOV ticks in nanoseconds */
1108fcf3ce44SJohn Forte 	if (sp->cmn.edtovResolution) {
1109fcf3ce44SJohn Forte 		hba->fc_edtov =
111082527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1111fcf3ce44SJohn Forte 	} else {
111282527734SSukumar Swaminathan 		hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1113fcf3ce44SJohn Forte 	}
1114fcf3ce44SJohn Forte 
1115fcf3ce44SJohn Forte 	/* Save R_A_TOV ticks */
111682527734SSukumar Swaminathan 	hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
1117fcf3ce44SJohn Forte 
1118fcf3ce44SJohn Forte 	buffer[0] = 0;
1119fcf3ce44SJohn Forte 
1120fcf3ce44SJohn Forte 	hba->flag &= ~FC_NPIV_SUPPORTED;
1121fcf3ce44SJohn Forte 	(void) strcpy(buffer, "npiv:Disabled. P2P ");
112282527734SSukumar Swaminathan 
112382527734SSukumar Swaminathan 	port->rdid = sid;
1124fcf3ce44SJohn Forte 
1125fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1126fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1127fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
1128fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current &&
1129fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1130fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
1131fcf3ce44SJohn Forte 	} else {
1132fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
1133fcf3ce44SJohn Forte 	}
1134291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1135fcf3ce44SJohn Forte 
1136fcf3ce44SJohn Forte 	/* Clear the fabric service parameters */
1137291a2b48SSukumar Swaminathan 	bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM));
1138fcf3ce44SJohn Forte 
1139fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
1140fcf3ce44SJohn Forte 
1141fcf3ce44SJohn Forte 	return (0);
1142fcf3ce44SJohn Forte 
114382527734SSukumar Swaminathan } /* emlxs_process_unsol_flogi() */
1144fcf3ce44SJohn Forte 
1145fcf3ce44SJohn Forte 
1146fcf3ce44SJohn Forte /* ARGSUSED */
1147fcf3ce44SJohn Forte static void
114882527734SSukumar Swaminathan emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1149fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1150fcf3ce44SJohn Forte {
1151fcf3ce44SJohn Forte 	uint8_t *bp;
1152fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1153fcf3ce44SJohn Forte 	IOCB *iocb;
1154fcf3ce44SJohn Forte 	uint32_t sid;
1155fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1156fcf3ce44SJohn Forte 	char buffer[64];
1157fcf3ce44SJohn Forte 
1158fcf3ce44SJohn Forte 	buffer[0] = 0;
1159fcf3ce44SJohn Forte 
1160fcf3ce44SJohn Forte 	/* Perform processing of FLOGI payload */
1161fcf3ce44SJohn Forte 	if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) {
1162fcf3ce44SJohn Forte 		return;
1163fcf3ce44SJohn Forte 	}
1164291a2b48SSukumar Swaminathan 
1165fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1166fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1167fcf3ce44SJohn Forte 	bp = mp->virt;
1168fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1169fcf3ce44SJohn Forte 
1170fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1171fcf3ce44SJohn Forte 
1172fcf3ce44SJohn Forte 	if (ubp == NULL) {
1173fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1174291a2b48SSukumar Swaminathan 		    "FLOGI rcvd: sid=%x. Rejecting.", sid);
1175fcf3ce44SJohn Forte 
1176fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1177fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1178fcf3ce44SJohn Forte 
1179fcf3ce44SJohn Forte 		goto drop_it;
1180fcf3ce44SJohn Forte 	}
1181291a2b48SSukumar Swaminathan 
1182fcf3ce44SJohn Forte 	/*
1183fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1184fcf3ce44SJohn Forte 	 */
1185fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1186fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1187fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_FLOGI;
1188fcf3ce44SJohn Forte 
1189fcf3ce44SJohn Forte 	/*
1190fcf3ce44SJohn Forte 	 * Setup frame header
1191fcf3ce44SJohn Forte 	 */
1192fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1193fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
119482527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
119582527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1196fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
119782527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1198fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1199fcf3ce44SJohn Forte 
1200fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1201291a2b48SSukumar Swaminathan 	    "FLOGI: sid=%x buffer=%p token=%x %s", sid, ubp, ub_priv->token,
1202291a2b48SSukumar Swaminathan 	    buffer);
1203fcf3ce44SJohn Forte 
1204fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1205fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1206291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1207fcf3ce44SJohn Forte 
1208fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1209fcf3ce44SJohn Forte 
1210fcf3ce44SJohn Forte drop_it:
1211fcf3ce44SJohn Forte 
1212fcf3ce44SJohn Forte 	return;
1213fcf3ce44SJohn Forte 
121482527734SSukumar Swaminathan } /* emlxs_handle_unsol_flogi() */
1215fcf3ce44SJohn Forte 
1216fcf3ce44SJohn Forte 
1217fcf3ce44SJohn Forte 
1218fcf3ce44SJohn Forte /* This is shared by FCT driver */
1219fcf3ce44SJohn Forte extern uint32_t
1220291a2b48SSukumar Swaminathan emlxs_process_unsol_plogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1221291a2b48SSukumar Swaminathan     uint32_t size, char *buffer)
1222fcf3ce44SJohn Forte {
1223fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1224fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1225fcf3ce44SJohn Forte 	uint8_t *bp;
1226fcf3ce44SJohn Forte 	IOCB *iocb;
1227fcf3ce44SJohn Forte 	uint32_t sid;
1228fcf3ce44SJohn Forte 	SERV_PARM *sp;
1229fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
1230291a2b48SSukumar Swaminathan 	emlxs_vvl_fmt_t vvl;
123182527734SSukumar Swaminathan 	int rc;
1232fcf3ce44SJohn Forte 
1233fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1234fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1235fcf3ce44SJohn Forte 
1236fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1237fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1238291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1239291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1240fcf3ce44SJohn Forte 
1241fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1242fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1243fcf3ce44SJohn Forte 
1244fcf3ce44SJohn Forte 		return (1);
1245fcf3ce44SJohn Forte 	}
1246291a2b48SSukumar Swaminathan 
1247fcf3ce44SJohn Forte 	bp = mp->virt;
1248fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1249fcf3ce44SJohn Forte 
1250291a2b48SSukumar Swaminathan 	bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t));
1251fcf3ce44SJohn Forte 
125282527734SSukumar Swaminathan 	if (sp->VALID_VENDOR_VERSION) {
1253fcf3ce44SJohn Forte 
1254291a2b48SSukumar Swaminathan 		bcopy((caddr_t *)&sp->vendorVersion[0],
1255291a2b48SSukumar Swaminathan 		    (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
125682527734SSukumar Swaminathan 		vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
125782527734SSukumar Swaminathan 		vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
1258291a2b48SSukumar Swaminathan 	}
1259291a2b48SSukumar Swaminathan 
1260291a2b48SSukumar Swaminathan 	if (port->flag & EMLXS_PORT_RESTRICTED) {
1261291a2b48SSukumar Swaminathan 		uint32_t reject_it = 0;
1262291a2b48SSukumar Swaminathan 
1263291a2b48SSukumar Swaminathan 		/* If remote port is the virtual port, then reject it */
1264291a2b48SSukumar Swaminathan 		if ((vvl.un0.w0.oui == 0x0000C9) && (vvl.un1.w1.vport)) {
1265291a2b48SSukumar Swaminathan 			reject_it = 1;
1266fcf3ce44SJohn Forte 		}
1267291a2b48SSukumar Swaminathan 
1268291a2b48SSukumar Swaminathan 		/* If we are a virtual port and the remote device */
1269291a2b48SSukumar Swaminathan 		/* is not a switch, then reject it */
127082527734SSukumar Swaminathan 		else if (port->vpi && ((sid & FABRIC_DID_MASK) !=
127182527734SSukumar Swaminathan 		    FABRIC_DID_MASK)) {
1272fcf3ce44SJohn Forte 			reject_it = 1;
1273fcf3ce44SJohn Forte 		}
1274291a2b48SSukumar Swaminathan 
1275fcf3ce44SJohn Forte 		if (reject_it) {
1276fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1277fcf3ce44SJohn Forte 			    "PLOGI rcvd: sid=%x. Restricted. Rejecting.",
1278fcf3ce44SJohn Forte 			    sid);
1279fcf3ce44SJohn Forte 
1280fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1281fcf3ce44SJohn Forte 			    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC,
1282fcf3ce44SJohn Forte 			    LSEXP_NOTHING_MORE);
1283fcf3ce44SJohn Forte 
1284*a9800bebSGarrett D'Amore 			/* Clear temporary RPI in firmware */
1285*a9800bebSGarrett D'Amore 			if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
1286*a9800bebSGarrett D'Amore 				(void) emlxs_mb_reg_did(port, sid, sp,
1287*a9800bebSGarrett D'Amore 				    NULL, NULL, (IOCBQ *)1);
1288*a9800bebSGarrett D'Amore 			}
1289fcf3ce44SJohn Forte 
1290fcf3ce44SJohn Forte 			return (1);
1291fcf3ce44SJohn Forte 		}
1292fcf3ce44SJohn Forte 	}
1293fcf3ce44SJohn Forte 
1294fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1295fcf3ce44SJohn Forte 	if (emlxs_dhc_verify_login(port, sid, sp)) {
1296fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1297291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. FCSP disabled. Rejecting.", sid);
1298fcf3ce44SJohn Forte 
1299fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1300fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1301fcf3ce44SJohn Forte 
1302fcf3ce44SJohn Forte 		return (1);
1303fcf3ce44SJohn Forte 	}
1304291a2b48SSukumar Swaminathan 
1305fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1306fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
1307fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
1308fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1309fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
1310fcf3ce44SJohn Forte 	} else {
1311fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
1312fcf3ce44SJohn Forte 	}
1313291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1314fcf3ce44SJohn Forte 
1315fcf3ce44SJohn Forte 	/* Check if this was a point to point Plogi */
1316fcf3ce44SJohn Forte 	if (hba->flag & FC_PT_TO_PT) {
1317fcf3ce44SJohn Forte 		mutex_enter(&EMLXS_PORT_LOCK);
1318fcf3ce44SJohn Forte 
1319fcf3ce44SJohn Forte 		/* Save our new port ID */
1320fcf3ce44SJohn Forte 		port->did = iocb->un.elsreq.myID;
1321fcf3ce44SJohn Forte 
1322fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
1323fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
1324fcf3ce44SJohn Forte 			hba->fc_edtov =
132582527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1326fcf3ce44SJohn Forte 		} else {
132782527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1328fcf3ce44SJohn Forte 		}
1329fcf3ce44SJohn Forte 
1330fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
1331291a2b48SSukumar Swaminathan 		hba->fc_ratov =
133282527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
1333fcf3ce44SJohn Forte 
1334fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
1335fcf3ce44SJohn Forte 
1336fcf3ce44SJohn Forte 		/* Update our service parms */
1337291a2b48SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
133882527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
133982527734SSukumar Swaminathan 			emlxs_mb_config_link(hba, mbox);
1340fcf3ce44SJohn Forte 
134182527734SSukumar Swaminathan 			rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
134282527734SSukumar Swaminathan 			    MBX_NOWAIT, 0);
134382527734SSukumar Swaminathan 			if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1344*a9800bebSGarrett D'Amore 				emlxs_mem_put(hba, MEM_MBOX, (void *)mbox);
1345fcf3ce44SJohn Forte 			}
1346291a2b48SSukumar Swaminathan 
1347fcf3ce44SJohn Forte 		}
1348fcf3ce44SJohn Forte 	}
1349291a2b48SSukumar Swaminathan 
1350fcf3ce44SJohn Forte 	return (0);
1351fcf3ce44SJohn Forte 
135282527734SSukumar Swaminathan } /* emlxs_process_unsol_plogi() */
1353fcf3ce44SJohn Forte 
1354fcf3ce44SJohn Forte 
1355fcf3ce44SJohn Forte /* ARGSUSED */
1356fcf3ce44SJohn Forte static void
135782527734SSukumar Swaminathan emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1358fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1359fcf3ce44SJohn Forte {
1360fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1361fcf3ce44SJohn Forte 	uint8_t *bp;
1362fcf3ce44SJohn Forte 	IOCB *iocb;
1363fcf3ce44SJohn Forte 	uint32_t sid;
1364fcf3ce44SJohn Forte 	uint32_t did;
1365fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1366fcf3ce44SJohn Forte 	SERV_PARM *sp;
1367fcf3ce44SJohn Forte 	char buffer[64];
1368fcf3ce44SJohn Forte 
1369fcf3ce44SJohn Forte 	buffer[0] = 0;
1370fcf3ce44SJohn Forte 
1371fcf3ce44SJohn Forte 	/* Perform processing of PLOGI payload */
1372fcf3ce44SJohn Forte 	if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) {
1373fcf3ce44SJohn Forte 		return;
1374fcf3ce44SJohn Forte 	}
1375291a2b48SSukumar Swaminathan 
1376fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1377fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1378fcf3ce44SJohn Forte 	did = iocb->un.elsreq.myID;
1379fcf3ce44SJohn Forte 	bp = mp->virt;
1380fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1381fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1382fcf3ce44SJohn Forte 
1383291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1384291a2b48SSukumar Swaminathan 	emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_PLOGI_RCV,
1385291a2b48SSukumar Swaminathan 	    (HBA_WWN *)&sp->portName, (HBA_WWN *)&sp->nodeName);
1386291a2b48SSukumar Swaminathan #endif
1387291a2b48SSukumar Swaminathan 
1388fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte 	if (ubp == NULL) {
1391fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1392291a2b48SSukumar Swaminathan 		    "PLOGI rcvd: sid=%x. Rejecting.", sid);
1393fcf3ce44SJohn Forte 
1394fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1395fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1396fcf3ce44SJohn Forte 
1397fcf3ce44SJohn Forte 		goto drop_it;
1398fcf3ce44SJohn Forte 	}
1399291a2b48SSukumar Swaminathan 
1400fcf3ce44SJohn Forte 	/*
1401fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1402fcf3ce44SJohn Forte 	 */
1403fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1404fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1405fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PLOGI;
1406fcf3ce44SJohn Forte 
1407fcf3ce44SJohn Forte 	/*
1408fcf3ce44SJohn Forte 	 * Setup frame header
1409fcf3ce44SJohn Forte 	 */
1410fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1411fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
141282527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
141382527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1414fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
141582527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1416fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1417fcf3ce44SJohn Forte 
1418fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1419291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x buffer=%p token=%x %s", sid, did, ubp,
1420291a2b48SSukumar Swaminathan 	    ub_priv->token, buffer);
1421fcf3ce44SJohn Forte 
1422fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1423fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1424291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1425fcf3ce44SJohn Forte 
1426fcf3ce44SJohn Forte 	/* Create a new node and defer callback */
1427fcf3ce44SJohn Forte 	if (emlxs_mb_reg_did(port, sid, sp, NULL, ubp, NULL) == 0) {
1428fcf3ce44SJohn Forte 		/*
1429fcf3ce44SJohn Forte 		 * Defer completion of this pkt until login is complete
1430fcf3ce44SJohn Forte 		 */
1431fcf3ce44SJohn Forte 		goto drop_it;
1432fcf3ce44SJohn Forte 	}
1433291a2b48SSukumar Swaminathan 
1434fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1435fcf3ce44SJohn Forte 
1436fcf3ce44SJohn Forte drop_it:
1437fcf3ce44SJohn Forte 
1438fcf3ce44SJohn Forte 	return;
1439fcf3ce44SJohn Forte 
144082527734SSukumar Swaminathan } /* emlxs_handle_unsol_plogi() */
1441fcf3ce44SJohn Forte 
1442fcf3ce44SJohn Forte 
1443fcf3ce44SJohn Forte /* ARGSUSED */
1444fcf3ce44SJohn Forte static void
144582527734SSukumar Swaminathan emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1446fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1447fcf3ce44SJohn Forte {
144882527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
144982527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1450fcf3ce44SJohn Forte 	IOCB *iocb;
1451fcf3ce44SJohn Forte 	uint32_t sid;
1452fcf3ce44SJohn Forte 	NODELIST *ndlp;
1453fcf3ce44SJohn Forte 	PRLI *npr;
1454fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1455fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1456*a9800bebSGarrett D'Amore 	uint32_t task_retry_id;
1457fcf3ce44SJohn Forte 
1458fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1459fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1460fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1461fcf3ce44SJohn Forte 
1462fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1463fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1464291a2b48SSukumar Swaminathan 		    "PRLI: sid=%x: Node not found. Rejecting.", sid);
1465fcf3ce44SJohn Forte 
1466fcf3ce44SJohn Forte 		/* Auto reply to PRLI's */
1467fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1468fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1469fcf3ce44SJohn Forte 
1470fcf3ce44SJohn Forte 		goto drop_it;
1471fcf3ce44SJohn Forte 	}
1472291a2b48SSukumar Swaminathan 
1473fcf3ce44SJohn Forte 	/* If node exists then save FCP2 support */
1474fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)mp->virt + sizeof (uint32_t));
1475fcf3ce44SJohn Forte 
1476fcf3ce44SJohn Forte 	/* Check for FCP2 support */
1477fcf3ce44SJohn Forte 	if ((npr->prliType == PRLI_FCP_TYPE) && npr->targetFunc) {
1478*a9800bebSGarrett D'Amore 		/* Clear FCP2 support if no ADISC support is requested */
1479*a9800bebSGarrett D'Amore 		if (cfg[CFG_ADISC_SUPPORT].current == 0) {
1480*a9800bebSGarrett D'Amore 			npr->ConfmComplAllowed = 0;
1481*a9800bebSGarrett D'Amore 			npr->TaskRetryIdReq = 0;
1482*a9800bebSGarrett D'Amore 			npr->Retry = 0;
1483*a9800bebSGarrett D'Amore 		}
1484*a9800bebSGarrett D'Amore 
1485fcf3ce44SJohn Forte 		/* Check for target */
1486fcf3ce44SJohn Forte 		if (npr->targetFunc) {
1487fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
1488fcf3ce44SJohn Forte 		} else {
1489fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
1490fcf3ce44SJohn Forte 		}
1491fcf3ce44SJohn Forte 
1492fcf3ce44SJohn Forte 		/* Check for initiator */
1493fcf3ce44SJohn Forte 		if (npr->initiatorFunc) {
1494fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
1495fcf3ce44SJohn Forte 		} else {
1496fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
1497fcf3ce44SJohn Forte 		}
1498fcf3ce44SJohn Forte 
1499*a9800bebSGarrett D'Amore 		/* If TRI support is not required then force */
1500*a9800bebSGarrett D'Amore 		/* the task_retry_id value to one */
1501*a9800bebSGarrett D'Amore 		if (cfg[CFG_TRI_REQUIRED].current == 0) {
1502*a9800bebSGarrett D'Amore 			task_retry_id = 1;
1503*a9800bebSGarrett D'Amore 		} else {
1504*a9800bebSGarrett D'Amore 			task_retry_id = npr->TaskRetryIdReq;
1505*a9800bebSGarrett D'Amore 		}
1506*a9800bebSGarrett D'Amore 
1507fcf3ce44SJohn Forte 		/* Check for FCP2 target support */
1508*a9800bebSGarrett D'Amore 		/* Retry and TaskRetryId bits are both required here */
1509*a9800bebSGarrett D'Amore 		if (npr->targetFunc && npr->Retry && task_retry_id) {
1510fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1511fcf3ce44SJohn Forte 		} else {
1512fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1513fcf3ce44SJohn Forte 		}
1514fcf3ce44SJohn Forte 	}
1515fcf3ce44SJohn Forte 
151682527734SSukumar Swaminathan #ifdef ULP_PATCH3
151782527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH3) {
151882527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
151982527734SSukumar Swaminathan 		    "PRLI: sid=%x. Accepting.", sid);
1520fcf3ce44SJohn Forte 
152182527734SSukumar Swaminathan 		/* Auto reply to PRLI's */
152282527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
152382527734SSukumar Swaminathan 		    ELS_CMD_PRLI, 0, 0);
152482527734SSukumar Swaminathan 		goto drop_it;
152582527734SSukumar Swaminathan 	}
152682527734SSukumar Swaminathan #endif /* ULP_PATCH3 */
1527fcf3ce44SJohn Forte 
1528fcf3ce44SJohn Forte 	/* Tell ULP about it */
1529fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1530fcf3ce44SJohn Forte 
1531fcf3ce44SJohn Forte 	if (ubp == NULL) {
1532fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1533291a2b48SSukumar Swaminathan 		    "PRLI rcvd: sid=%x. Rejecting.", sid);
1534fcf3ce44SJohn Forte 
1535fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1536fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1537fcf3ce44SJohn Forte 
1538fcf3ce44SJohn Forte 		goto drop_it;
1539fcf3ce44SJohn Forte 	}
1540291a2b48SSukumar Swaminathan 
1541fcf3ce44SJohn Forte 	/*
1542fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1543fcf3ce44SJohn Forte 	 */
1544fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1545fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1546fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLI;
1547fcf3ce44SJohn Forte 
1548fcf3ce44SJohn Forte 	/*
1549fcf3ce44SJohn Forte 	 * Setup frame header
1550fcf3ce44SJohn Forte 	 */
1551fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1552fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
155382527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
155482527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1555fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
155682527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1557fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1558fcf3ce44SJohn Forte 
1559fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1560291a2b48SSukumar Swaminathan 	    "PRLI: sid=%x buffer=%p token=%x info=%02x", sid, ubp,
1561291a2b48SSukumar Swaminathan 	    ub_priv->token, ndlp->nlp_fcp_info);
1562fcf3ce44SJohn Forte 
1563fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1564fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1565291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1566fcf3ce44SJohn Forte 
1567fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1568fcf3ce44SJohn Forte 
1569fcf3ce44SJohn Forte drop_it:
1570fcf3ce44SJohn Forte 
1571fcf3ce44SJohn Forte 	return;
1572fcf3ce44SJohn Forte 
157382527734SSukumar Swaminathan } /* emlxs_handle_unsol_prli() */
1574fcf3ce44SJohn Forte 
1575fcf3ce44SJohn Forte 
1576fcf3ce44SJohn Forte /* ARGSUSED */
1577fcf3ce44SJohn Forte static void
157882527734SSukumar Swaminathan emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1579fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1580fcf3ce44SJohn Forte {
1581fcf3ce44SJohn Forte 	IOCB *iocb;
1582fcf3ce44SJohn Forte 	uint32_t sid;
1583fcf3ce44SJohn Forte 	NODELIST *ndlp;
1584fcf3ce44SJohn Forte 
1585fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1586fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1587fcf3ce44SJohn Forte 
1588fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1589fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1590fcf3ce44SJohn Forte 
1591fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1592fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1593291a2b48SSukumar Swaminathan 		    "AUTH: sid=%x: Node not found. Rejecting.", sid);
1594fcf3ce44SJohn Forte 
1595fcf3ce44SJohn Forte 		/* Auto reply to AUTH_ELS's */
1596fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1597fcf3ce44SJohn Forte 		    ELS_CMD_AUTH, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1598fcf3ce44SJohn Forte 
1599fcf3ce44SJohn Forte 		goto drop_it;
1600fcf3ce44SJohn Forte 	}
1601291a2b48SSukumar Swaminathan 
1602291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "AUTH: sid=%x", sid);
1603fcf3ce44SJohn Forte 
160482527734SSukumar Swaminathan 	(void) emlxs_dhchap_state_machine(port, cp, iocbq, mp, ndlp,
1605fcf3ce44SJohn Forte 	    NODE_EVENT_RCV_AUTH_MSG);
1606fcf3ce44SJohn Forte #else
1607fcf3ce44SJohn Forte 
1608fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1609291a2b48SSukumar Swaminathan 	    "AUTH: sid=%x: Rejecting.", sid);
1610fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, ELS_CMD_AUTH,
1611fcf3ce44SJohn Forte 	    LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1612fcf3ce44SJohn Forte 
1613291a2b48SSukumar Swaminathan #endif /* DHCAHP_SUPPORT */
1614fcf3ce44SJohn Forte 
1615fcf3ce44SJohn Forte drop_it:
1616fcf3ce44SJohn Forte 
1617fcf3ce44SJohn Forte 	return;
1618fcf3ce44SJohn Forte 
161982527734SSukumar Swaminathan } /* emlxs_handle_unsol_auth() */
1620fcf3ce44SJohn Forte 
1621fcf3ce44SJohn Forte 
1622fcf3ce44SJohn Forte /* ARGSUSED */
1623fcf3ce44SJohn Forte static void
162482527734SSukumar Swaminathan emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1625fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1626fcf3ce44SJohn Forte {
1627291a2b48SSukumar Swaminathan 	IOCB		*iocb;
1628291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1629291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
1630291a2b48SSukumar Swaminathan #endif
1631291a2b48SSukumar Swaminathan 	uint32_t	sid;
1632fcf3ce44SJohn Forte 
1633fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1634fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1635fcf3ce44SJohn Forte 
1636291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1637291a2b48SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, sid);
1638291a2b48SSukumar Swaminathan 
1639291a2b48SSukumar Swaminathan 	if (ndlp) {
1640291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_ADISC_RCV,
1641291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1642291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_nodename);
1643291a2b48SSukumar Swaminathan 	}
1644291a2b48SSukumar Swaminathan #endif
1645291a2b48SSukumar Swaminathan 
1646fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1647291a2b48SSukumar Swaminathan 	    "ADISC: sid=%x: Accepting.", sid);
1648fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_ADISC, 0, 0);
1649fcf3ce44SJohn Forte 
1650fcf3ce44SJohn Forte 	return;
1651fcf3ce44SJohn Forte 
165282527734SSukumar Swaminathan } /* emlxs_handle_unsol_adisc() */
1653fcf3ce44SJohn Forte 
1654fcf3ce44SJohn Forte 
1655fcf3ce44SJohn Forte /* ARGSUSED */
1656fcf3ce44SJohn Forte static void
165782527734SSukumar Swaminathan emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1658fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1659fcf3ce44SJohn Forte {
166082527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
166182527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1662fcf3ce44SJohn Forte 	IOCB *iocb;
1663fcf3ce44SJohn Forte 	uint32_t sid;
1664fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1665fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1666fcf3ce44SJohn Forte 	NODELIST *ndlp;
1667fcf3ce44SJohn Forte 
1668fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1669fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1670fcf3ce44SJohn Forte 
1671fcf3ce44SJohn Forte 	/* Get the node */
1672fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1673fcf3ce44SJohn Forte 
1674291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1675291a2b48SSukumar Swaminathan 	if (ndlp) {
1676291a2b48SSukumar Swaminathan 		emlxs_log_sd_prlo_event(port, (HBA_WWN *)&ndlp->nlp_portname);
1677291a2b48SSukumar Swaminathan 	}
1678291a2b48SSukumar Swaminathan #endif
1679291a2b48SSukumar Swaminathan 
1680291a2b48SSukumar Swaminathan #ifdef ULP_PATCH4
168182527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH4) {
1682291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
168382527734SSukumar Swaminathan 		if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
168482527734SSukumar Swaminathan 			/* Check if this is a SCSI target */
168582527734SSukumar Swaminathan 			if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
168682527734SSukumar Swaminathan 				/* This is a SCSI target */
168782527734SSukumar Swaminathan 
168882527734SSukumar Swaminathan 				/* If only one node is present, then we can */
168982527734SSukumar Swaminathan 				/* conclude that we are direct attached */
169082527734SSukumar Swaminathan 				/* to a target */
169182527734SSukumar Swaminathan 				if (port->node_count == 1) {
169282527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
169382527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
169482527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
169582527734SSukumar Swaminathan 					    "reseting link.",
169682527734SSukumar Swaminathan 					    sid);
1697291a2b48SSukumar Swaminathan 
169882527734SSukumar Swaminathan 					/* Send Acc */
169982527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
170082527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1701fcf3ce44SJohn Forte 
170282527734SSukumar Swaminathan 					/* Spawn a thread to reset the link */
170382527734SSukumar Swaminathan 					emlxs_thread_spawn(hba,
170482527734SSukumar Swaminathan 					    emlxs_reset_link_thread,
170582527734SSukumar Swaminathan 					    NULL, NULL);
1706fcf3ce44SJohn Forte 
170782527734SSukumar Swaminathan 					goto drop_it;
1708fcf3ce44SJohn Forte 
170982527734SSukumar Swaminathan 				}
171082527734SSukumar Swaminathan 				/* Check if fabric is present */
171182527734SSukumar Swaminathan 				else if (hba->flag & FC_FABRIC_ATTACHED) {
171282527734SSukumar Swaminathan 					/* Auto reply to PRLO */
171382527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
171482527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
171582527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
171682527734SSukumar Swaminathan 					    "generating RSCN.",
171782527734SSukumar Swaminathan 					    sid);
1718fcf3ce44SJohn Forte 
171982527734SSukumar Swaminathan 					/* Send Acc */
172082527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
172182527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1722fcf3ce44SJohn Forte 
172382527734SSukumar Swaminathan 					/* Generate an RSCN to wakeup ULP */
172482527734SSukumar Swaminathan 					(void) emlxs_generate_rscn(port, sid);
1725fcf3ce44SJohn Forte 
172682527734SSukumar Swaminathan 					goto drop_it;
172782527734SSukumar Swaminathan 				}
172882527734SSukumar Swaminathan 			}
1729fcf3ce44SJohn Forte 		}
1730291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1731fcf3ce44SJohn Forte 
173282527734SSukumar Swaminathan 		/* Auto reply to PRLO */
173382527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
173482527734SSukumar Swaminathan 		    "PRLO: sid=%x. Accepting.", sid);
1735fcf3ce44SJohn Forte 
173682527734SSukumar Swaminathan 		/* Send Acc */
173782527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
173882527734SSukumar Swaminathan 		    ELS_CMD_PRLO, 0, 0);
1739fcf3ce44SJohn Forte 
174082527734SSukumar Swaminathan 		goto drop_it;
174182527734SSukumar Swaminathan 	}
174282527734SSukumar Swaminathan #endif /* ULP_PATCH4 */
1743fcf3ce44SJohn Forte 
1744fcf3ce44SJohn Forte 	/* Tell ULP about it */
1745fcf3ce44SJohn Forte 
1746fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1747fcf3ce44SJohn Forte 
1748fcf3ce44SJohn Forte 	if (ubp == NULL) {
1749fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1750291a2b48SSukumar Swaminathan 		    "PRLO recvd: sid=%x. Rejecting.", sid);
1751fcf3ce44SJohn Forte 
1752fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1753fcf3ce44SJohn Forte 		    ELS_CMD_PRLO, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1754fcf3ce44SJohn Forte 
1755fcf3ce44SJohn Forte 		goto drop_it;
1756fcf3ce44SJohn Forte 	}
1757291a2b48SSukumar Swaminathan 
1758fcf3ce44SJohn Forte 	/*
1759fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1760fcf3ce44SJohn Forte 	 */
1761fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1762fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1763fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLO;
1764fcf3ce44SJohn Forte 
1765fcf3ce44SJohn Forte 	/*
1766fcf3ce44SJohn Forte 	 * Setup frame header
1767fcf3ce44SJohn Forte 	 */
1768fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1769fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
177082527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
177182527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1772fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
177382527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1774fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1775fcf3ce44SJohn Forte 
1776fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1777291a2b48SSukumar Swaminathan 	    "PRLO: sid=%x buffeiocbr=%p token=%x.", sid, ubp, ub_priv->token);
1778fcf3ce44SJohn Forte 
1779fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1780fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1781291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1782fcf3ce44SJohn Forte 
1783fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1784fcf3ce44SJohn Forte 
1785fcf3ce44SJohn Forte drop_it:
1786fcf3ce44SJohn Forte 
1787fcf3ce44SJohn Forte 	return;
1788fcf3ce44SJohn Forte 
178982527734SSukumar Swaminathan } /* emlxs_handle_unsol_prlo() */
1790fcf3ce44SJohn Forte 
1791fcf3ce44SJohn Forte 
1792fcf3ce44SJohn Forte /* ARGSUSED */
1793fcf3ce44SJohn Forte static void
179482527734SSukumar Swaminathan emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1795fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1796fcf3ce44SJohn Forte {
1797fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
179882527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1799fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1800fcf3ce44SJohn Forte 	IOCB *iocb;
1801fcf3ce44SJohn Forte 	uint32_t sid;
1802fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1803fcf3ce44SJohn Forte 	uint32_t reply_sent = 0;
1804fcf3ce44SJohn Forte 	NODELIST *ndlp;
1805fcf3ce44SJohn Forte 
1806fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1807fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1808fcf3ce44SJohn Forte 
1809fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1810fcf3ce44SJohn Forte 
1811291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1812291a2b48SSukumar Swaminathan 	if (ndlp) {
1813291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port,  SD_ELS_SUBCATEGORY_LOGO_RCV,
1814291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1815291a2b48SSukumar Swaminathan 		    (HBA_WWN *)((uint32_t *)mp->virt + 2));
1816291a2b48SSukumar Swaminathan 	}
1817291a2b48SSukumar Swaminathan #endif
1818291a2b48SSukumar Swaminathan 
1819291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
182082527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
182182527734SSukumar Swaminathan 		/* Check if this is a SCSI target */
182282527734SSukumar Swaminathan 		if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
182382527734SSukumar Swaminathan 			/* This is a SCSI target */
1824291a2b48SSukumar Swaminathan 
182582527734SSukumar Swaminathan 			/* If only one node is present, then we can */
182682527734SSukumar Swaminathan 			/* conclude that we are direct attached to a target */
182782527734SSukumar Swaminathan 			if (port->node_count == 1) {
182882527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
182982527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and "\
183082527734SSukumar Swaminathan 				    "reseting link.", sid);
1831fcf3ce44SJohn Forte 
183282527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq,
183382527734SSukumar Swaminathan 				    ELS_CMD_ACC, ELS_CMD_LOGO, 0, 0);
1834fcf3ce44SJohn Forte 
183582527734SSukumar Swaminathan 				/* Spawn a thread to reset the link */
183682527734SSukumar Swaminathan 				emlxs_thread_spawn(hba, emlxs_reset_link_thread,
183782527734SSukumar Swaminathan 				    NULL, NULL);
1838fcf3ce44SJohn Forte 
1839fcf3ce44SJohn Forte 				goto drop_it;
1840fcf3ce44SJohn Forte 			}
184182527734SSukumar Swaminathan 			/* Check if fabric node is present */
184282527734SSukumar Swaminathan 			else if (hba->flag & FC_FABRIC_ATTACHED) {
184382527734SSukumar Swaminathan 				/* Send reply ourselves */
184482527734SSukumar Swaminathan 				/* We will block all attempts */
184582527734SSukumar Swaminathan 				/* for ULP to reply to a LOGO */
184682527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
184782527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and " \
184882527734SSukumar Swaminathan 				    "generating RSCN.", sid);
184982527734SSukumar Swaminathan 
185082527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
185182527734SSukumar Swaminathan 				    ELS_CMD_LOGO, 0, 0);
185282527734SSukumar Swaminathan 
185382527734SSukumar Swaminathan 				/* Generate an RSCN to wakeup ULP */
185482527734SSukumar Swaminathan 				if (emlxs_generate_rscn(port, sid)
185582527734SSukumar Swaminathan 				    == FC_SUCCESS) {
185682527734SSukumar Swaminathan 					goto drop_it;
185782527734SSukumar Swaminathan 				}
1858291a2b48SSukumar Swaminathan 
185982527734SSukumar Swaminathan 				reply_sent = 1;
186082527734SSukumar Swaminathan 			}
1861fcf3ce44SJohn Forte 		}
1862291a2b48SSukumar Swaminathan 	}
1863291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1864fcf3ce44SJohn Forte 
1865fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1);
1866fcf3ce44SJohn Forte 
1867fcf3ce44SJohn Forte 	if (ubp == NULL) {
1868fcf3ce44SJohn Forte 		if (!reply_sent) {
1869fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1870291a2b48SSukumar Swaminathan 			    "LOGO rcvd: sid=%x. Rejecting.", sid);
1871fcf3ce44SJohn Forte 
1872fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1873fcf3ce44SJohn Forte 			    ELS_CMD_LOGO, LSRJT_LOGICAL_BSY,
1874fcf3ce44SJohn Forte 			    LSEXP_OUT_OF_RESOURCE);
1875fcf3ce44SJohn Forte 		}
1876291a2b48SSukumar Swaminathan 
1877fcf3ce44SJohn Forte 		goto drop_it;
1878fcf3ce44SJohn Forte 
1879fcf3ce44SJohn Forte 	}
1880291a2b48SSukumar Swaminathan 
1881fcf3ce44SJohn Forte 	/* Setup unsolicited buffer and pass it up */
1882fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1883fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1884fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_LOGO;
1885fcf3ce44SJohn Forte 
1886fcf3ce44SJohn Forte 	/* Setup frame header */
1887fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1888fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
188982527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
189082527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1891fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
189282527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1893fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1894fcf3ce44SJohn Forte 
1895fcf3ce44SJohn Forte #ifdef ULP_PATCH2
189682527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH2) {
189782527734SSukumar Swaminathan 		if (!reply_sent) {
189882527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
189982527734SSukumar Swaminathan 			    "LOGO: sid=%x buffer=%p token=%x. Accepting.",
190082527734SSukumar Swaminathan 			    sid, ubp, ub_priv->token);
1901fcf3ce44SJohn Forte 
190282527734SSukumar Swaminathan 			ub_priv->flags |= EMLXS_UB_REPLY;
1903fcf3ce44SJohn Forte 
190482527734SSukumar Swaminathan 			/* Send Acc */
190582527734SSukumar Swaminathan 			/* Send reply ourselves because ULP */
190682527734SSukumar Swaminathan 			/* doesn't always reply to these */
190782527734SSukumar Swaminathan 			/* We ll block attempts for ULP to reply to a LOGO */
190882527734SSukumar Swaminathan 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
190982527734SSukumar Swaminathan 			    ELS_CMD_LOGO, 0, 0);
191082527734SSukumar Swaminathan 			reply_sent = 1;
191182527734SSukumar Swaminathan 		}
1912fcf3ce44SJohn Forte 	}
191382527734SSukumar Swaminathan #endif /* ULP_PATCH2 */
1914fcf3ce44SJohn Forte 
1915fcf3ce44SJohn Forte 	if (!reply_sent) {
1916fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1917291a2b48SSukumar Swaminathan 		    "LOGO: sid=%x buffer=%p token=%x.", sid, ubp,
1918291a2b48SSukumar Swaminathan 		    ub_priv->token);
1919fcf3ce44SJohn Forte 	}
1920fcf3ce44SJohn Forte 
1921fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1922fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1923291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1924fcf3ce44SJohn Forte 
1925*a9800bebSGarrett D'Amore 	/* Unregister the node */
192682527734SSukumar Swaminathan 	if ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) {
1927*a9800bebSGarrett D'Amore 		if (ndlp) {
1928*a9800bebSGarrett D'Amore 			if (emlxs_mb_unreg_node(port, ndlp, NULL,
1929*a9800bebSGarrett D'Amore 			    ubp, NULL) == 0) {
1930*a9800bebSGarrett D'Amore 				/*
1931*a9800bebSGarrett D'Amore 				 * Deferred completion of this ubp
1932*a9800bebSGarrett D'Amore 				 * until unreg login is complete
1933*a9800bebSGarrett D'Amore 				 */
1934*a9800bebSGarrett D'Amore 				return;
1935*a9800bebSGarrett D'Amore 			}
1936fcf3ce44SJohn Forte 		}
1937fcf3ce44SJohn Forte 	}
1938291a2b48SSukumar Swaminathan 
1939fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1940fcf3ce44SJohn Forte 
1941fcf3ce44SJohn Forte drop_it:
1942fcf3ce44SJohn Forte 
1943fcf3ce44SJohn Forte 	return;
1944fcf3ce44SJohn Forte 
194582527734SSukumar Swaminathan } /* emlxs_handle_unsol_logo() */
1946291a2b48SSukumar Swaminathan 
1947fcf3ce44SJohn Forte 
1948fcf3ce44SJohn Forte 
1949fcf3ce44SJohn Forte /* ARGSUSED */
1950fcf3ce44SJohn Forte static void
195182527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1952fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1953fcf3ce44SJohn Forte {
1954fcf3ce44SJohn Forte 	uint8_t *bp;
1955fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1956fcf3ce44SJohn Forte 	IOCB *iocb;
1957fcf3ce44SJohn Forte 	uint32_t *lp;
1958fcf3ce44SJohn Forte 	uint32_t cmd;
1959fcf3ce44SJohn Forte 	uint32_t sid;
1960fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1961fcf3ce44SJohn Forte 
1962fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1963fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1964fcf3ce44SJohn Forte 
1965fcf3ce44SJohn Forte 	bp = mp->virt;
1966fcf3ce44SJohn Forte 	lp = (uint32_t *)bp;
1967fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
1968fcf3ce44SJohn Forte 
1969fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1970fcf3ce44SJohn Forte 
1971fcf3ce44SJohn Forte 	if (ubp == NULL) {
1972fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1973291a2b48SSukumar Swaminathan 		    "%s rcvd: sid=%x: Rejecting.", emlxs_elscmd_xlate(cmd),
1974291a2b48SSukumar Swaminathan 		    sid);
1975fcf3ce44SJohn Forte 
1976fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd,
1977fcf3ce44SJohn Forte 		    LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1978fcf3ce44SJohn Forte 
1979fcf3ce44SJohn Forte 		goto drop_it;
1980fcf3ce44SJohn Forte 	}
1981291a2b48SSukumar Swaminathan 
1982fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1983fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1984fcf3ce44SJohn Forte 	ub_priv->cmd = cmd;
1985fcf3ce44SJohn Forte 
1986fcf3ce44SJohn Forte 	/* Setup frame header */
1987fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1988fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
198982527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
199082527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1991fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
199282527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1993fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1994fcf3ce44SJohn Forte 
1995fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1996291a2b48SSukumar Swaminathan 	    "%s: sid=%x buffer=%p token=%x.", emlxs_elscmd_xlate(cmd), sid,
1997291a2b48SSukumar Swaminathan 	    ubp, ub_priv->token);
1998fcf3ce44SJohn Forte 
1999fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2000fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2001291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2002fcf3ce44SJohn Forte 
2003fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2004fcf3ce44SJohn Forte 
2005fcf3ce44SJohn Forte drop_it:
2006fcf3ce44SJohn Forte 
2007fcf3ce44SJohn Forte 	return;
2008fcf3ce44SJohn Forte 
200982527734SSukumar Swaminathan } /* emlxs_handle_unsol_gen_cmd() */
2010fcf3ce44SJohn Forte 
2011fcf3ce44SJohn Forte 
2012*a9800bebSGarrett D'Amore /* ARGSUSED */
2013*a9800bebSGarrett D'Amore static void
2014*a9800bebSGarrett D'Amore emlxs_handle_unsol_echo_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2015*a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2016*a9800bebSGarrett D'Amore {
2017*a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2018*a9800bebSGarrett D'Amore 	uint8_t *bp;
2019*a9800bebSGarrett D'Amore 	IOCB *iocb;
2020*a9800bebSGarrett D'Amore 	uint32_t *lp;
2021*a9800bebSGarrett D'Amore 	uint32_t sid;
2022*a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2023*a9800bebSGarrett D'Amore 	uint32_t cmd;
2024*a9800bebSGarrett D'Amore 
2025*a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2026*a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2027*a9800bebSGarrett D'Amore 
2028*a9800bebSGarrett D'Amore 	bp = mp->virt;
2029*a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2030*a9800bebSGarrett D'Amore 	cmd = *lp & ELS_CMD_MASK;
2031*a9800bebSGarrett D'Amore 
2032*a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2033*a9800bebSGarrett D'Amore 	    size, 0, 0, KM_NOSLEEP))) {
2034*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2035*a9800bebSGarrett D'Amore 		    "ECHO: sid=%x. Unable to allocate pkt. Rejecting.",
2036*a9800bebSGarrett D'Amore 		    sid);
2037*a9800bebSGarrett D'Amore 
2038*a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2039*a9800bebSGarrett D'Amore 		    ELS_CMD_ECHO, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2040*a9800bebSGarrett D'Amore 		return;
2041*a9800bebSGarrett D'Amore 	}
2042*a9800bebSGarrett D'Amore 
2043*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2044*a9800bebSGarrett D'Amore 	    "ECHO: sid=%x. Accepting.",
2045*a9800bebSGarrett D'Amore 	    sid);
2046*a9800bebSGarrett D'Amore 
2047*a9800bebSGarrett D'Amore 	/* Common initialization */
2048*a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2049*a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2050*a9800bebSGarrett D'Amore 
2051*a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2052*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2053*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2054*a9800bebSGarrett D'Amore 	}
2055*a9800bebSGarrett D'Amore 
2056*a9800bebSGarrett D'Amore 	/* Build the fc header */
2057*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2058*a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2059*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2060*a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2061*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2062*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2063*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2064*a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2065*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2066*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2067*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2068*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2069*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2070*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2071*a9800bebSGarrett D'Amore 
2072*a9800bebSGarrett D'Amore 	/* Build the response */
2073*a9800bebSGarrett D'Amore 	*lp = ELS_CMD_ACC;
2074*a9800bebSGarrett D'Amore 	bcopy(lp, pkt->pkt_cmd, size);
2075*a9800bebSGarrett D'Amore 
2076*a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2077*a9800bebSGarrett D'Amore 		/* Free the pkt */
2078*a9800bebSGarrett D'Amore 		emlxs_pkt_free(pkt);
2079*a9800bebSGarrett D'Amore 		emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2080*a9800bebSGarrett D'Amore 	}
2081*a9800bebSGarrett D'Amore 
2082*a9800bebSGarrett D'Amore 	return;
2083*a9800bebSGarrett D'Amore 
2084*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_echo_cmd() */
2085*a9800bebSGarrett D'Amore 
2086*a9800bebSGarrett D'Amore 
2087*a9800bebSGarrett D'Amore /* ARGSUSED */
2088*a9800bebSGarrett D'Amore static void
2089*a9800bebSGarrett D'Amore emlxs_handle_unsol_rtv_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2090*a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2091*a9800bebSGarrett D'Amore {
2092*a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2093*a9800bebSGarrett D'Amore 	uint8_t *bp;
2094*a9800bebSGarrett D'Amore 	IOCB *iocb;
2095*a9800bebSGarrett D'Amore 	uint32_t *lp;
2096*a9800bebSGarrett D'Amore 	uint32_t sid;
2097*a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2098*a9800bebSGarrett D'Amore 	uint32_t cmd;
2099*a9800bebSGarrett D'Amore 	SERV_PARM *sp;
2100*a9800bebSGarrett D'Amore 
2101*a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2102*a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2103*a9800bebSGarrett D'Amore 
2104*a9800bebSGarrett D'Amore 	bp = mp->virt;
2105*a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2106*a9800bebSGarrett D'Amore 	cmd = *lp & ELS_CMD_MASK;
2107*a9800bebSGarrett D'Amore 
2108*a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2109*a9800bebSGarrett D'Amore 	    (4 * sizeof (uint32_t)), 0, 0, KM_NOSLEEP))) {
2110*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2111*a9800bebSGarrett D'Amore 		    "RTV: sid=%x. Unable to allocate pkt. Rejecting.",
2112*a9800bebSGarrett D'Amore 		    sid);
2113*a9800bebSGarrett D'Amore 
2114*a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2115*a9800bebSGarrett D'Amore 		    ELS_CMD_RTV, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2116*a9800bebSGarrett D'Amore 		return;
2117*a9800bebSGarrett D'Amore 	}
2118*a9800bebSGarrett D'Amore 
2119*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2120*a9800bebSGarrett D'Amore 	    "RTV: sid=%x. Accepting.",
2121*a9800bebSGarrett D'Amore 	    emlxs_elscmd_xlate(cmd),
2122*a9800bebSGarrett D'Amore 	    sid);
2123*a9800bebSGarrett D'Amore 
2124*a9800bebSGarrett D'Amore 	/* Common initialization */
2125*a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2126*a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2127*a9800bebSGarrett D'Amore 
2128*a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2129*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2130*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2131*a9800bebSGarrett D'Amore 	}
2132*a9800bebSGarrett D'Amore 
2133*a9800bebSGarrett D'Amore 	/* Build the fc header */
2134*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2135*a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2136*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2137*a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2138*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2139*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2140*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2141*a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2142*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2143*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2144*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2145*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2146*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2147*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2148*a9800bebSGarrett D'Amore 
2149*a9800bebSGarrett D'Amore 	/* Build the response */
2150*a9800bebSGarrett D'Amore 	sp = (SERV_PARM *)&port->sparam;
2151*a9800bebSGarrett D'Amore 	lp = (uint32_t *)pkt->pkt_cmd;
2152*a9800bebSGarrett D'Amore 	lp[0] = ELS_CMD_ACC;
2153*a9800bebSGarrett D'Amore 	lp[1] = LE_SWAP32(sp->cmn.w2.r_a_tov);
2154*a9800bebSGarrett D'Amore 	lp[2] = LE_SWAP32(sp->cmn.e_d_tov);
2155*a9800bebSGarrett D'Amore 	lp[3] = LE_SWAP32(sp->cmn.edtovResolution << 26);
2156*a9800bebSGarrett D'Amore 
2157*a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2158*a9800bebSGarrett D'Amore 		/* Free the pkt */
2159*a9800bebSGarrett D'Amore 		emlxs_pkt_free(pkt);
2160*a9800bebSGarrett D'Amore 		emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2161*a9800bebSGarrett D'Amore 	}
2162*a9800bebSGarrett D'Amore 
2163*a9800bebSGarrett D'Amore 	return;
2164*a9800bebSGarrett D'Amore 
2165*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_rtv_cmd() */
2166*a9800bebSGarrett D'Amore 
2167*a9800bebSGarrett D'Amore 
2168*a9800bebSGarrett D'Amore /* ARGSUSED */
2169*a9800bebSGarrett D'Amore static void
2170*a9800bebSGarrett D'Amore emlxs_rls_rsp_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
2171*a9800bebSGarrett D'Amore {
2172*a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)arg1;
2173*a9800bebSGarrett D'Amore 	fc_packet_t *pkt = (fc_packet_t *)arg2;
2174*a9800bebSGarrett D'Amore 	MAILBOXQ	*mbq = NULL;
2175*a9800bebSGarrett D'Amore 	MAILBOX		*mb;
2176*a9800bebSGarrett D'Amore 	la_els_rls_acc_t *rls;
2177*a9800bebSGarrett D'Amore 	uint32_t rval;
2178*a9800bebSGarrett D'Amore 
2179*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2180*a9800bebSGarrett D'Amore 	    "RLS: sid=%x. Accepting.",
2181*a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id));
2182*a9800bebSGarrett D'Amore 
2183*a9800bebSGarrett D'Amore 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
2184*a9800bebSGarrett D'Amore 		goto dropit;
2185*a9800bebSGarrett D'Amore 	}
2186*a9800bebSGarrett D'Amore 	mb = (MAILBOX *)mbq;
2187*a9800bebSGarrett D'Amore 
2188*a9800bebSGarrett D'Amore 	/* Read current link status */
2189*a9800bebSGarrett D'Amore 	emlxs_mb_read_lnk_stat(hba, mbq);
2190*a9800bebSGarrett D'Amore 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0);
2191*a9800bebSGarrett D'Amore 
2192*a9800bebSGarrett D'Amore 	if (rval != MBX_SUCCESS) {
2193*a9800bebSGarrett D'Amore 		goto dropit;
2194*a9800bebSGarrett D'Amore 	}
2195*a9800bebSGarrett D'Amore 
2196*a9800bebSGarrett D'Amore 	/* Build the response */
2197*a9800bebSGarrett D'Amore 	rls = (la_els_rls_acc_t *)pkt->pkt_cmd;
2198*a9800bebSGarrett D'Amore 	rls->ls_code.ls_code = 0x02;
2199*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_link_fail =
2200*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.linkFailureCnt;
2201*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_sync_loss =
2202*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.lossSyncCnt;
2203*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_sig_loss =
2204*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.lossSignalCnt;
2205*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_prim_seq_err =
2206*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.primSeqErrCnt;
2207*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_invalid_word =
2208*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.invalidXmitWord;
2209*a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_invalid_crc =
2210*a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.crcCnt;
2211*a9800bebSGarrett D'Amore 
2212*a9800bebSGarrett D'Amore 	LE_SWAP32_BUFFER((uint8_t *)rls, sizeof (la_els_rls_acc_t));
2213*a9800bebSGarrett D'Amore 
2214*a9800bebSGarrett D'Amore 	emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2215*a9800bebSGarrett D'Amore 	mbq = NULL;
2216*a9800bebSGarrett D'Amore 
2217*a9800bebSGarrett D'Amore 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
2218*a9800bebSGarrett D'Amore 		goto dropit;
2219*a9800bebSGarrett D'Amore 	}
2220*a9800bebSGarrett D'Amore 
2221*a9800bebSGarrett D'Amore 	return;
2222*a9800bebSGarrett D'Amore 
2223*a9800bebSGarrett D'Amore dropit:
2224*a9800bebSGarrett D'Amore 
2225*a9800bebSGarrett D'Amore 	emlxs_abort_els_exchange(hba, port, pkt->pkt_cmd_fhdr.rx_id);
2226*a9800bebSGarrett D'Amore 
2227*a9800bebSGarrett D'Amore 	emlxs_pkt_free(pkt);
2228*a9800bebSGarrett D'Amore 
2229*a9800bebSGarrett D'Amore 	if (mbq) {
2230*a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2231*a9800bebSGarrett D'Amore 	}
2232*a9800bebSGarrett D'Amore 
2233*a9800bebSGarrett D'Amore 	return;
2234*a9800bebSGarrett D'Amore 
2235*a9800bebSGarrett D'Amore } /* emlxs_rls_rsp_thread() */
2236*a9800bebSGarrett D'Amore 
2237*a9800bebSGarrett D'Amore 
2238*a9800bebSGarrett D'Amore /* ARGSUSED */
2239*a9800bebSGarrett D'Amore static void
2240*a9800bebSGarrett D'Amore emlxs_handle_unsol_rls_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2241*a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2242*a9800bebSGarrett D'Amore {
2243*a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2244*a9800bebSGarrett D'Amore 	uint8_t *bp;
2245*a9800bebSGarrett D'Amore 	IOCB *iocb;
2246*a9800bebSGarrett D'Amore 	uint32_t *lp;
2247*a9800bebSGarrett D'Amore 	uint32_t sid;
2248*a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2249*a9800bebSGarrett D'Amore 	uint32_t cmd;
2250*a9800bebSGarrett D'Amore 
2251*a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2252*a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2253*a9800bebSGarrett D'Amore 
2254*a9800bebSGarrett D'Amore 	bp = mp->virt;
2255*a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2256*a9800bebSGarrett D'Amore 	cmd = *lp++ & ELS_CMD_MASK;
2257*a9800bebSGarrett D'Amore 
2258*a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2259*a9800bebSGarrett D'Amore 	    sizeof (la_els_rls_acc_t), 0, 0, KM_NOSLEEP))) {
2260*a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2261*a9800bebSGarrett D'Amore 		    "RLS: sid=%x. Unable to allocate pkt.  Rejecting.",
2262*a9800bebSGarrett D'Amore 		    sid);
2263*a9800bebSGarrett D'Amore 
2264*a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2265*a9800bebSGarrett D'Amore 		    ELS_CMD_RLS, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2266*a9800bebSGarrett D'Amore 		return;
2267*a9800bebSGarrett D'Amore 	}
2268*a9800bebSGarrett D'Amore 
2269*a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2270*a9800bebSGarrett D'Amore 	    "RLS: sid=%x. Scheduling response.",
2271*a9800bebSGarrett D'Amore 	    sid);
2272*a9800bebSGarrett D'Amore 
2273*a9800bebSGarrett D'Amore 	/* Common initialization */
2274*a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2275*a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2276*a9800bebSGarrett D'Amore 
2277*a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2278*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2279*a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2280*a9800bebSGarrett D'Amore 	}
2281*a9800bebSGarrett D'Amore 
2282*a9800bebSGarrett D'Amore 	/* Build the fc header */
2283*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2284*a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2285*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2286*a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2287*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2288*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2289*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2290*a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2291*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2292*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2293*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2294*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2295*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2296*a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2297*a9800bebSGarrett D'Amore 
2298*a9800bebSGarrett D'Amore 	/* We must spawn a separate thread to send the */
2299*a9800bebSGarrett D'Amore 	/* read link status mailbox command becasue we are */
2300*a9800bebSGarrett D'Amore 	/* normally in a hardware interrupt context here. */
2301*a9800bebSGarrett D'Amore 	emlxs_thread_spawn(hba, emlxs_rls_rsp_thread,
2302*a9800bebSGarrett D'Amore 	    (void *)port, (void *)pkt);
2303*a9800bebSGarrett D'Amore 
2304*a9800bebSGarrett D'Amore 	return;
2305*a9800bebSGarrett D'Amore 
2306*a9800bebSGarrett D'Amore } /* emlxs_handle_unsol_rls_cmd() */
2307*a9800bebSGarrett D'Amore 
2308*a9800bebSGarrett D'Amore 
2309fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2310fcf3ce44SJohn Forte /* ARGSUSED */
2311fcf3ce44SJohn Forte static void
2312291a2b48SSukumar Swaminathan emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2313291a2b48SSukumar Swaminathan     uint32_t flag)
2314fcf3ce44SJohn Forte {
231582527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2316fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2317fcf3ce44SJohn Forte 	IOCB *iocb;
2318fcf3ce44SJohn Forte 	uint32_t did;
2319fcf3ce44SJohn Forte 	NODELIST *ndlp;
2320fcf3ce44SJohn Forte 	uint32_t ucmd;
2321fcf3ce44SJohn Forte 	uint32_t cmd;
2322fcf3ce44SJohn Forte 	uint32_t *lp;
2323fcf3ce44SJohn Forte 
2324fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2325fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
232682527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2327fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2328fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2329fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2330fcf3ce44SJohn Forte 
2331fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2332291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
233382527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2334fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2335fcf3ce44SJohn Forte 
2336fcf3ce44SJohn Forte 	switch (ucmd) {
2337fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2338fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
2339fcf3ce44SJohn Forte 
2340fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_did(port, did);
2341fcf3ce44SJohn Forte 
2342fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2343fcf3ce44SJohn Forte 			/* Open the node again */
234482527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
234582527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2346fcf3ce44SJohn Forte 		}
2347291a2b48SSukumar Swaminathan 
2348fcf3ce44SJohn Forte 		break;
2349fcf3ce44SJohn Forte 
2350fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2351fcf3ce44SJohn Forte 
2352fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_did(port, did);
2353fcf3ce44SJohn Forte 
2354fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2355fcf3ce44SJohn Forte 			/* Open the node again */
235682527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2357fcf3ce44SJohn Forte 		}
2358291a2b48SSukumar Swaminathan 
2359fcf3ce44SJohn Forte 		break;
2360fcf3ce44SJohn Forte 	}
2361fcf3ce44SJohn Forte 
236282527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2363fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2364fcf3ce44SJohn Forte 
2365fcf3ce44SJohn Forte 	return;
2366fcf3ce44SJohn Forte 
236782527734SSukumar Swaminathan } /* emlxs_handle_acc() */
2368fcf3ce44SJohn Forte 
2369fcf3ce44SJohn Forte 
2370fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2371fcf3ce44SJohn Forte /* ARGSUSED */
2372fcf3ce44SJohn Forte static void
2373291a2b48SSukumar Swaminathan emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2374291a2b48SSukumar Swaminathan     uint32_t flag)
2375fcf3ce44SJohn Forte {
237682527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2377291a2b48SSukumar Swaminathan 	fc_packet_t	*pkt;
2378291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
2379291a2b48SSukumar Swaminathan 	IOCB		*iocb;
2380291a2b48SSukumar Swaminathan 	uint32_t	did;
2381291a2b48SSukumar Swaminathan 	uint32_t	ucmd;
2382291a2b48SSukumar Swaminathan 	uint32_t	cmd;
2383291a2b48SSukumar Swaminathan 	uint32_t	*lp;
2384fcf3ce44SJohn Forte 
2385fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2386fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
238782527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2388fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2389fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2390fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2391fcf3ce44SJohn Forte 
2392291a2b48SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, did);
2393291a2b48SSukumar Swaminathan 
2394fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2395291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
239682527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2397fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2398fcf3ce44SJohn Forte 
2399fcf3ce44SJohn Forte 	switch (ucmd) {
2400fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2401fcf3ce44SJohn Forte 
2402fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2403fcf3ce44SJohn Forte 			/* Open the node again */
240482527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
240582527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2406fcf3ce44SJohn Forte 		}
2407291a2b48SSukumar Swaminathan 
2408fcf3ce44SJohn Forte 		break;
2409fcf3ce44SJohn Forte 
2410fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2411fcf3ce44SJohn Forte 
2412fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2413fcf3ce44SJohn Forte 			/* Open the node again */
241482527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2415fcf3ce44SJohn Forte 		}
2416291a2b48SSukumar Swaminathan 
2417fcf3ce44SJohn Forte 		break;
2418fcf3ce44SJohn Forte 	}
2419fcf3ce44SJohn Forte 
242082527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2421fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2422fcf3ce44SJohn Forte 
2423fcf3ce44SJohn Forte 	return;
2424fcf3ce44SJohn Forte 
242582527734SSukumar Swaminathan } /* emlxs_handle_reject() */
2426fcf3ce44SJohn Forte 
2427fcf3ce44SJohn Forte 
2428fcf3ce44SJohn Forte /* ARGSUSED */
2429fcf3ce44SJohn Forte extern int32_t
2430fcf3ce44SJohn Forte emlxs_els_reply(emlxs_port_t *port, IOCBQ *iocbq, uint32_t type,
2431fcf3ce44SJohn Forte     uint32_t type2, uint32_t reason, uint32_t explain)
2432fcf3ce44SJohn Forte {
2433fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
2434fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
2435fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2436fcf3ce44SJohn Forte 	ELS_PKT *els;
2437fcf3ce44SJohn Forte 	IOCB *iocb;
2438fcf3ce44SJohn Forte 
2439fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2440fcf3ce44SJohn Forte 
2441fcf3ce44SJohn Forte 	switch (type) {
2442fcf3ce44SJohn Forte 	case ELS_CMD_ACC:	/* Accept Response */
2443fcf3ce44SJohn Forte 
2444fcf3ce44SJohn Forte 		/* Allocate the pkt */
2445fcf3ce44SJohn Forte 		switch (type2) {
2446fcf3ce44SJohn Forte 		case ELS_CMD_FLOGI:
2447*a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2448291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (SERV_PARM), 0,
2449*a9800bebSGarrett D'Amore 			    0, KM_NOSLEEP);
2450fcf3ce44SJohn Forte 			break;
2451fcf3ce44SJohn Forte 
2452fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2453*a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2454291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (ADISC), 0, 0,
2455*a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2456fcf3ce44SJohn Forte 			break;
2457fcf3ce44SJohn Forte 
2458fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2459*a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2460291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLI), 0, 0,
2461*a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2462fcf3ce44SJohn Forte 			break;
2463fcf3ce44SJohn Forte 
2464fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2465*a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2466291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLO), 0, 0,
2467*a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2468fcf3ce44SJohn Forte 			break;
2469fcf3ce44SJohn Forte 
2470fcf3ce44SJohn Forte 		case ELS_CMD_AUTH:
2471fcf3ce44SJohn Forte 		default:
2472*a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port, sizeof (uint32_t),
2473*a9800bebSGarrett D'Amore 			    0, 0, KM_NOSLEEP);
2474*a9800bebSGarrett D'Amore 		}
2475fcf3ce44SJohn Forte 
2476*a9800bebSGarrett D'Amore 		if (!pkt) {
2477*a9800bebSGarrett D'Amore 			goto dropit;
2478fcf3ce44SJohn Forte 		}
2479fcf3ce44SJohn Forte 
2480fcf3ce44SJohn Forte 		/* Common initialization */
2481fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2482fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2483fcf3ce44SJohn Forte 
248482527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2485fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2486fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2487fcf3ce44SJohn Forte 		}
2488291a2b48SSukumar Swaminathan 
2489fcf3ce44SJohn Forte 		/* Build the fc header */
2490fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
249182527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2492291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2493291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
249482527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2495fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2496291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2497291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2498fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2499fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2500fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2501fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
250282527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2503fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2504fcf3ce44SJohn Forte 
2505fcf3ce44SJohn Forte 		/*
2506291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2507291a2b48SSukumar Swaminathan 		 * "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2),
2508fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2509fcf3ce44SJohn Forte 		 */
2510fcf3ce44SJohn Forte 
2511fcf3ce44SJohn Forte 		/* Build the command */
2512291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2513fcf3ce44SJohn Forte 		els->elsCode = 0x02;
2514fcf3ce44SJohn Forte 
2515fcf3ce44SJohn Forte 		/* Build the payload */
2516fcf3ce44SJohn Forte 		switch (type2) {
2517fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2518fcf3ce44SJohn Forte 
2519fcf3ce44SJohn Forte 			els->un.adisc.hardAL_PA =
2520fcf3ce44SJohn Forte 			    (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2521fcf3ce44SJohn Forte 			bcopy(&port->wwnn, &els->un.adisc.nodeName,
2522fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
2523fcf3ce44SJohn Forte 			bcopy(&port->wwpn, &els->un.adisc.portName,
2524fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
252582527734SSukumar Swaminathan 			els->un.adisc.DID = LE_SWAP24_LO(port->did);
2526fcf3ce44SJohn Forte 
2527fcf3ce44SJohn Forte 			break;
2528fcf3ce44SJohn Forte 
2529fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2530fcf3ce44SJohn Forte 
2531fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2532fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2533fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2534fcf3ce44SJohn Forte 
2535fcf3ce44SJohn Forte 			els->un.prli.prliType = PRLI_FCP_TYPE;
2536fcf3ce44SJohn Forte 			els->un.prli.estabImagePair = 1;
2537fcf3ce44SJohn Forte 			els->un.prli.acceptRspCode = PRLI_REQ_EXECUTED;
2538fcf3ce44SJohn Forte 
2539fcf3ce44SJohn Forte 			if (port->ini_mode) {
2540fcf3ce44SJohn Forte 				els->un.prli.initiatorFunc = 1;
2541fcf3ce44SJohn Forte 			}
2542291a2b48SSukumar Swaminathan 
2543fcf3ce44SJohn Forte 			if (port->tgt_mode) {
2544fcf3ce44SJohn Forte 				els->un.prli.targetFunc = 1;
2545fcf3ce44SJohn Forte 			}
2546291a2b48SSukumar Swaminathan 
2547fcf3ce44SJohn Forte 			els->un.prli.readXferRdyDis = 1;
2548fcf3ce44SJohn Forte 
2549*a9800bebSGarrett D'Amore 			if ((hba->vpd.feaLevelHigh >= 0x02) &&
2550*a9800bebSGarrett D'Amore 			    (cfg[CFG_ADISC_SUPPORT].current != 0)) {
2551fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 1;
2552fcf3ce44SJohn Forte 				els->un.prli.Retry = 1;
2553fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 1;
2554fcf3ce44SJohn Forte 			} else {
2555fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 0;
2556fcf3ce44SJohn Forte 				els->un.prli.Retry = 0;
2557fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 0;
2558fcf3ce44SJohn Forte 			}
2559fcf3ce44SJohn Forte 
2560fcf3ce44SJohn Forte 			break;
2561fcf3ce44SJohn Forte 
2562fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2563fcf3ce44SJohn Forte 
2564fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2565fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2566fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2567fcf3ce44SJohn Forte 
2568fcf3ce44SJohn Forte 			els->un.prlo.prloType = PRLO_FCP_TYPE;
2569fcf3ce44SJohn Forte 			els->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
2570fcf3ce44SJohn Forte 
2571fcf3ce44SJohn Forte 			break;
2572fcf3ce44SJohn Forte 
2573fcf3ce44SJohn Forte 
2574fcf3ce44SJohn Forte 		}	/* switch(type2) */
2575fcf3ce44SJohn Forte 		break;
2576fcf3ce44SJohn Forte 
2577fcf3ce44SJohn Forte 	case ELS_CMD_LS_RJT:	/* reject response */
2578fcf3ce44SJohn Forte 
2579fcf3ce44SJohn Forte 		if (!(pkt = emlxs_pkt_alloc(port,
2580fcf3ce44SJohn Forte 		    sizeof (uint32_t) + sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) {
2581*a9800bebSGarrett D'Amore 			goto dropit;
2582fcf3ce44SJohn Forte 		}
2583291a2b48SSukumar Swaminathan 
2584fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2585fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2586fcf3ce44SJohn Forte 
258782527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2588fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2589fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2590fcf3ce44SJohn Forte 		}
2591291a2b48SSukumar Swaminathan 
2592fcf3ce44SJohn Forte 		/* Build the fc header */
2593fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
259482527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2595291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2596291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
259782527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2598fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2599291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2600291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2601fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2602fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2603fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2604fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
260582527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2606fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2607fcf3ce44SJohn Forte 
2608fcf3ce44SJohn Forte 		/*
2609291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2610291a2b48SSukumar Swaminathan 		 * "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2),
2611fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2612fcf3ce44SJohn Forte 		 */
2613fcf3ce44SJohn Forte 
2614fcf3ce44SJohn Forte 		/* Build the command */
2615291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2616fcf3ce44SJohn Forte 		els->elsCode = 0x01;
2617fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsvd0 = 0;
2618fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2619fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2620fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.vendorUnique = 0x01;
2621fcf3ce44SJohn Forte 
2622fcf3ce44SJohn Forte 		break;
2623fcf3ce44SJohn Forte 	}
2624fcf3ce44SJohn Forte 
2625*a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2626fcf3ce44SJohn Forte 		/* Free the pkt */
2627fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
2628*a9800bebSGarrett D'Amore 		goto dropit;
2629fcf3ce44SJohn Forte 	}
2630291a2b48SSukumar Swaminathan 
2631*a9800bebSGarrett D'Amore 	return (0);
2632*a9800bebSGarrett D'Amore 
2633*a9800bebSGarrett D'Amore dropit:
2634*a9800bebSGarrett D'Amore 
2635*a9800bebSGarrett D'Amore 	emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2636*a9800bebSGarrett D'Amore 	return (1);
2637fcf3ce44SJohn Forte 
263882527734SSukumar Swaminathan } /* emlxs_els_reply() */
2639fcf3ce44SJohn Forte 
2640fcf3ce44SJohn Forte 
2641fcf3ce44SJohn Forte #ifdef ULP_PATCH6
2642fcf3ce44SJohn Forte 
2643fcf3ce44SJohn Forte extern uint32_t
2644fcf3ce44SJohn Forte emlxs_generate_rscn(emlxs_port_t *port, uint32_t d_id)
2645fcf3ce44SJohn Forte {
2646fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
2647fcf3ce44SJohn Forte 	fc_rscn_t *rscn;
2648fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
2649fcf3ce44SJohn Forte 	uint32_t *page;
2650fcf3ce44SJohn Forte 
2651fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, 8, FC_ELS_DATA, 1);
2652fcf3ce44SJohn Forte 
2653fcf3ce44SJohn Forte 	if (ubp == NULL) {
2654fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
2655291a2b48SSukumar Swaminathan 		    "RSCN create: sid=0xfffffd  1 page(s): %08X, 00000000. "
2656291a2b48SSukumar Swaminathan 		    "Creation failed.", d_id);
2657fcf3ce44SJohn Forte 
2658fcf3ce44SJohn Forte 		return ((uint32_t)FC_FAILURE);
2659fcf3ce44SJohn Forte 	}
2660291a2b48SSukumar Swaminathan 
2661fcf3ce44SJohn Forte 	/* Simulate an RSCN payload */
2662fcf3ce44SJohn Forte 	rscn = (fc_rscn_t *)ubp->ub_buffer;
2663fcf3ce44SJohn Forte 	rscn->rscn_code = 0x61;
2664fcf3ce44SJohn Forte 	rscn->rscn_len = 0x04;
2665fcf3ce44SJohn Forte 	rscn->rscn_payload_len = 0x0008;
2666fcf3ce44SJohn Forte 	page = ((uint32_t *)rscn);
2667fcf3ce44SJohn Forte 	page++;
2668fcf3ce44SJohn Forte 	*page = d_id;
2669fcf3ce44SJohn Forte 
2670fcf3ce44SJohn Forte #ifdef EMLXS_I386
2671fcf3ce44SJohn Forte 	/* Put payload in BE format */
267282527734SSukumar Swaminathan 	rscn->rscn_payload_len = LE_SWAP16(rscn->rscn_payload_len);
267382527734SSukumar Swaminathan 	*page = LE_SWAP32(d_id);
2674291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */
2675fcf3ce44SJohn Forte 
2676fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
2677fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
2678fcf3ce44SJohn Forte 	ub_priv->flags |= EMLXS_UB_INTERCEPT;
2679fcf3ce44SJohn Forte 
2680fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
2681fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
2682fcf3ce44SJohn Forte 	ubp->ub_frame.s_id = 0xfffffd;
268382527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(port->did);
2684fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
2685fcf3ce44SJohn Forte 	ubp->ub_frame.rx_id = 0xffff;
2686fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2687fcf3ce44SJohn Forte 
2688fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2689291a2b48SSukumar Swaminathan 	    "RSCN: sid=fffffd  1 page(s): %08X, 00000000  buffer=%p "
2690291a2b48SSukumar Swaminathan 	    "token=%x. Created.", d_id, ubp, ub_priv->token);
2691fcf3ce44SJohn Forte 
2692fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2693fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2694291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2695fcf3ce44SJohn Forte 
2696fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2697fcf3ce44SJohn Forte 
2698fcf3ce44SJohn Forte 	return (FC_SUCCESS);
2699fcf3ce44SJohn Forte 
270082527734SSukumar Swaminathan } /* emlxs_generate_rscn() */
2701fcf3ce44SJohn Forte 
2702291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
2703fcf3ce44SJohn Forte 
2704fcf3ce44SJohn Forte 
2705fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT
2706fcf3ce44SJohn Forte extern int
270782527734SSukumar Swaminathan emlxs_menlo_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2708fcf3ce44SJohn Forte {
2709fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2710fcf3ce44SJohn Forte 	IOCB *iocb;
2711fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2712fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2713fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2714fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2715fcf3ce44SJohn Forte 	menlo_cmd_t *cmd;
2716fcf3ce44SJohn Forte 	uint32_t *rsp;
2717fcf3ce44SJohn Forte 
2718fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2719fcf3ce44SJohn Forte 
2720fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2721fcf3ce44SJohn Forte 
2722fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2723fcf3ce44SJohn Forte 
2724fcf3ce44SJohn Forte 	if (!sbp) {
2725fcf3ce44SJohn Forte 		/*
2726fcf3ce44SJohn Forte 		 * completion with missing xmit command
2727fcf3ce44SJohn Forte 		 */
2728fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2729fcf3ce44SJohn Forte 
2730fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2731fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
273282527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
273382527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2734291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2735fcf3ce44SJohn Forte 
2736fcf3ce44SJohn Forte 		return (1);
2737fcf3ce44SJohn Forte 	}
2738291a2b48SSukumar Swaminathan 
273982527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2740fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2741fcf3ce44SJohn Forte 
2742fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
274382527734SSukumar Swaminathan 		    "Invalid IO channel:%d iocbq=%p", cp->channelno, iocbq);
2744fcf3ce44SJohn Forte 
2745fcf3ce44SJohn Forte 		return (1);
2746fcf3ce44SJohn Forte 	}
2747291a2b48SSukumar Swaminathan 
2748fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2749fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2750fcf3ce44SJohn Forte 
2751fcf3ce44SJohn Forte 	cmd = (menlo_cmd_t *)pkt->pkt_cmd;
275282527734SSukumar Swaminathan 	cmd_code = BE_SWAP32(cmd->code);
2753fcf3ce44SJohn Forte 
2754fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
2755fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
275682527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2757fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
2758fcf3ce44SJohn Forte 	}
2759291a2b48SSukumar Swaminathan 
276082527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
2761291a2b48SSukumar Swaminathan 	/*
2762291a2b48SSukumar Swaminathan 	 * MENLO Command completion
2763291a2b48SSukumar Swaminathan 	 */
2764fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
2765fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
2766fcf3ce44SJohn Forte 
2767fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
2768fcf3ce44SJohn Forte 
2769fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
2770fcf3ce44SJohn Forte 
2771fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
2772fcf3ce44SJohn Forte 		rsp_code = *rsp;
277382527734SSukumar Swaminathan 		rsp_code = BE_SWAP32(rsp_code);
2774fcf3ce44SJohn Forte 
277582527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
2776fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2777fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
2778fcf3ce44SJohn Forte 		} else
2779fcf3ce44SJohn Forte 		{
2780fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2781fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
2782fcf3ce44SJohn Forte 		}
2783fcf3ce44SJohn Forte 
2784fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
278582527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2786fcf3ce44SJohn Forte 
278782527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (rsp_code == MENLO_RSP_SUCCESS)) {
2788fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
2789fcf3ce44SJohn Forte 
2790fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2791fcf3ce44SJohn Forte 			    "%s: %s rxid=0x%x",
2792fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2793fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
279482527734SSukumar Swaminathan 			    iocb->ULPCONTEXT);
2795fcf3ce44SJohn Forte 
2796fcf3ce44SJohn Forte 		} else {
2797fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
2798fcf3ce44SJohn Forte 
2799fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2800fcf3ce44SJohn Forte 			    "%s: %s %s %s rxid=0x%x",
2801fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2802fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
280382527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2804291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
280582527734SSukumar Swaminathan 			    statLocalError), iocb->ULPCONTEXT);
2806fcf3ce44SJohn Forte 		}
2807fcf3ce44SJohn Forte 
280882527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2809fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2810fcf3ce44SJohn Forte 
2811fcf3ce44SJohn Forte 		break;
2812fcf3ce44SJohn Forte 
2813fcf3ce44SJohn Forte 	default:
2814fcf3ce44SJohn Forte 
2815fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2816fcf3ce44SJohn Forte 
2817fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
281882527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
2819fcf3ce44SJohn Forte 
282082527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2821fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2822fcf3ce44SJohn Forte 
2823fcf3ce44SJohn Forte 		break;
2824fcf3ce44SJohn Forte 
282582527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
2826fcf3ce44SJohn Forte 
2827fcf3ce44SJohn Forte 	return (0);
2828fcf3ce44SJohn Forte 
282982527734SSukumar Swaminathan } /* emlxs_menlo_handle_event() */
2830fcf3ce44SJohn Forte 
2831291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */
2832fcf3ce44SJohn Forte 
2833fcf3ce44SJohn Forte 
2834fcf3ce44SJohn Forte extern int
283582527734SSukumar Swaminathan emlxs_ct_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2836fcf3ce44SJohn Forte {
2837fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2838fcf3ce44SJohn Forte 	IOCB *iocb;
2839fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2840fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2841fcf3ce44SJohn Forte 	uint32_t *rsp;
2842fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtRsp;
2843fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
2844fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2845fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2846fcf3ce44SJohn Forte 
2847fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2848fcf3ce44SJohn Forte 
2849fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2850fcf3ce44SJohn Forte 
2851fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2852fcf3ce44SJohn Forte 
2853fcf3ce44SJohn Forte 	if (!sbp) {
2854fcf3ce44SJohn Forte 		/*
2855fcf3ce44SJohn Forte 		 * completion with missing xmit command
2856fcf3ce44SJohn Forte 		 */
2857fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2858fcf3ce44SJohn Forte 
2859fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2860fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
286182527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
286282527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2863291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2864fcf3ce44SJohn Forte 
2865fcf3ce44SJohn Forte 		return (1);
2866fcf3ce44SJohn Forte 	}
2867291a2b48SSukumar Swaminathan 
286882527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2869fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2870fcf3ce44SJohn Forte 
2871fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
287282527734SSukumar Swaminathan 		    "Invalid channel: channel=%d iocbq=%p", cp->channelno,
287382527734SSukumar Swaminathan 		    iocbq);
2874fcf3ce44SJohn Forte 
2875fcf3ce44SJohn Forte 		return (1);
2876fcf3ce44SJohn Forte 	}
2877291a2b48SSukumar Swaminathan 
2878fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2879fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2880291a2b48SSukumar Swaminathan 	CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd;
288182527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
2882fcf3ce44SJohn Forte 
2883fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
2884fcf3ce44SJohn Forte 		HBASTATS.CtEvent--;
288582527734SSukumar Swaminathan 		return (emlxs_dfc_handle_event(hba, cp, iocbq));
2886fcf3ce44SJohn Forte 	}
2887fcf3ce44SJohn Forte 
2888fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
2889fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
289082527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2891fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
2892fcf3ce44SJohn Forte 	}
2893291a2b48SSukumar Swaminathan 
289482527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
2895291a2b48SSukumar Swaminathan 		/*
2896291a2b48SSukumar Swaminathan 		 * CT Reply completion
2897291a2b48SSukumar Swaminathan 		 */
2898fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE_CX:
2899fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE64_CX:
2900fcf3ce44SJohn Forte 
2901fcf3ce44SJohn Forte 		HBASTATS.CtRspCompleted++;
2902fcf3ce44SJohn Forte 
2903fcf3ce44SJohn Forte 		switch (CtCmd->FsType) {
2904fcf3ce44SJohn Forte 		case 0xFC:	/* Name server */
2905fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2906291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
290782527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2908291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2909291a2b48SSukumar Swaminathan 			    statLocalError));
2910fcf3ce44SJohn Forte 			break;
2911fcf3ce44SJohn Forte 
2912fcf3ce44SJohn Forte 		case 0xFA:	/* Managment server */
2913fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2914291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_mscmd_xlate(cmd_code),
291582527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2916291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2917291a2b48SSukumar Swaminathan 			    statLocalError));
2918fcf3ce44SJohn Forte 			break;
2919fcf3ce44SJohn Forte 
2920fcf3ce44SJohn Forte 		case 0x0A:	/* Emulex Remote server */
2921fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2922291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_rmcmd_xlate(cmd_code),
292382527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2924291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2925291a2b48SSukumar Swaminathan 			    statLocalError));
2926fcf3ce44SJohn Forte 			break;
2927fcf3ce44SJohn Forte 
2928fcf3ce44SJohn Forte 		default:
2929fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2930291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
293182527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2932291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2933291a2b48SSukumar Swaminathan 			    statLocalError));
2934fcf3ce44SJohn Forte 		}
2935fcf3ce44SJohn Forte 
293682527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2937fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2938fcf3ce44SJohn Forte 
2939fcf3ce44SJohn Forte 		break;
2940fcf3ce44SJohn Forte 
2941291a2b48SSukumar Swaminathan 		/*
2942291a2b48SSukumar Swaminathan 		 * CT Command completion
2943291a2b48SSukumar Swaminathan 		 */
2944fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
2945fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
2946fcf3ce44SJohn Forte 
2947fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
2948fcf3ce44SJohn Forte 
2949fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
2950fcf3ce44SJohn Forte 
2951fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
2952fcf3ce44SJohn Forte 		CtRsp = (SLI_CT_REQUEST *)pkt->pkt_resp;
295382527734SSukumar Swaminathan 		rsp_code = LE_SWAP16(CtRsp->CommandResponse.bits.CmdRsp);
2954fcf3ce44SJohn Forte 
295582527734SSukumar Swaminathan 		if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) {
2956fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2957fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
2958fcf3ce44SJohn Forte 		} else
2959fcf3ce44SJohn Forte 		{
2960fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2961fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
2962fcf3ce44SJohn Forte 		}
2963fcf3ce44SJohn Forte 
2964fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
2965fcf3ce44SJohn Forte 
2966fcf3ce44SJohn Forte 		/*
2967291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2968291a2b48SSukumar Swaminathan 		 * "INFO: pkt_resid=%d  %d  %d  %x", pkt->pkt_resp_resid,
2969fcf3ce44SJohn Forte 		 * pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize,
2970fcf3ce44SJohn Forte 		 * iocb->un.genreq64.bdl.bdeFlags);
2971fcf3ce44SJohn Forte 		 */
2972fcf3ce44SJohn Forte 
297382527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) &&
2974fcf3ce44SJohn Forte 		    (rsp_code == SLI_CT_RESPONSE_FS_ACC)) {
2975fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
2976fcf3ce44SJohn Forte 
2977fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
2978291a2b48SSukumar Swaminathan 				/* ULP patch - ULP expects */
2979291a2b48SSukumar Swaminathan 				/* resp_resid = 0 on success */
2980fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
2981fcf3ce44SJohn Forte 			}
2982291a2b48SSukumar Swaminathan 
2983fcf3ce44SJohn Forte 			switch (CtCmd->FsType) {
2984fcf3ce44SJohn Forte 			case 0xFC:	/* Name server */
2985fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2986fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2987fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
2988fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
2989fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
2990fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
299182527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
2992fcf3ce44SJohn Forte 
2993fcf3ce44SJohn Forte #if (EMLXS_MODREV < EMLXS_MODREV4)
2994fcf3ce44SJohn Forte 				if (cmd_code == SLI_CTNS_RNN_ID) {
2995fcf3ce44SJohn Forte 					emlxs_send_rsnn(port);
2996fcf3ce44SJohn Forte 				}
2997291a2b48SSukumar Swaminathan #endif /* < EMLXS_MODREV4 */
2998fcf3ce44SJohn Forte 
2999fcf3ce44SJohn Forte 				break;
3000fcf3ce44SJohn Forte 
3001fcf3ce44SJohn Forte 			case 0xFA:	/* Managment server */
3002fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3003fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3004fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3005fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(cmd_code),
3006fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(rsp_code),
3007fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
300882527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3009fcf3ce44SJohn Forte 				break;
3010fcf3ce44SJohn Forte 
3011fcf3ce44SJohn Forte 			case 0x0A:	/* Emulex Remote server */
3012fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3013fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3014fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3015fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(cmd_code),
3016fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(rsp_code),
3017fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
301882527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3019fcf3ce44SJohn Forte 				break;
3020fcf3ce44SJohn Forte 
3021fcf3ce44SJohn Forte 			default:
3022fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3023fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3024fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3025fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
3026fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
3027fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
302882527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3029fcf3ce44SJohn Forte 			}
3030fcf3ce44SJohn Forte 		} else {
3031fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
3032fcf3ce44SJohn Forte 
3033fcf3ce44SJohn Forte 			if (rsp_code == SLI_CT_RESPONSE_FS_RJT) {
3034fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_FS_RJT;
3035fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
3036fcf3ce44SJohn Forte 				pkt->pkt_reason = CtRsp->ReasonCode;
3037fcf3ce44SJohn Forte 				pkt->pkt_expln = CtRsp->Explanation;
3038fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
3039fcf3ce44SJohn Forte 
3040fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3041fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3042fcf3ce44SJohn Forte 				    "%s: Rejected. rsn=%x exp=%x",
3043fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
3044291a2b48SSukumar Swaminathan 				    pkt->pkt_reason, pkt->pkt_expln);
304582527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
3046fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
3047fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
3048fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3049fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3050fcf3ce44SJohn Forte 					    "%s: %s %s",
3051fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3052291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
305382527734SSukumar Swaminathan 					    ULPSTATUS),
3054291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3055291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3056fcf3ce44SJohn Forte 					break;
3057fcf3ce44SJohn Forte 
3058fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
3059fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3060fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3061fcf3ce44SJohn Forte 					    "%s: %s %s",
3062fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
3063291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
306482527734SSukumar Swaminathan 					    ULPSTATUS),
3065291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3066291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3067fcf3ce44SJohn Forte 					break;
3068fcf3ce44SJohn Forte 
3069fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
3070fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3071fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3072fcf3ce44SJohn Forte 					    "%s: %s %s",
3073fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
3074291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
307582527734SSukumar Swaminathan 					    ULPSTATUS),
3076291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3077291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3078fcf3ce44SJohn Forte 					break;
3079fcf3ce44SJohn Forte 
3080fcf3ce44SJohn Forte 				default:
3081fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3082fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3083fcf3ce44SJohn Forte 					    "%s: %s %s",
3084fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3085291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
308682527734SSukumar Swaminathan 					    ULPSTATUS),
3087291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3088291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3089fcf3ce44SJohn Forte 				}
3090fcf3ce44SJohn Forte 			} else {
3091fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
3092fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
3093fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3094fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3095fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3096fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3097291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
309882527734SSukumar Swaminathan 					    ULPSTATUS),
3099fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3100fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3101fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3102291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3103291a2b48SSukumar Swaminathan 					    statLocalError);
3104fcf3ce44SJohn Forte 					break;
3105fcf3ce44SJohn Forte 
3106fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
3107fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3108fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3109fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3110fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
3111291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
311282527734SSukumar Swaminathan 					    ULPSTATUS),
3113fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3114fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3115fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3116291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3117291a2b48SSukumar Swaminathan 					    statLocalError);
3118fcf3ce44SJohn Forte 					break;
3119fcf3ce44SJohn Forte 
3120fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
3121fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3122fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3123fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3124fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
3125291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
312682527734SSukumar Swaminathan 					    ULPSTATUS),
3127fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3128fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3129fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3130291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3131291a2b48SSukumar Swaminathan 					    statLocalError);
3132fcf3ce44SJohn Forte 					break;
3133fcf3ce44SJohn Forte 
3134fcf3ce44SJohn Forte 				default:
3135fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3136fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3137fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3138fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3139291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
314082527734SSukumar Swaminathan 					    ULPSTATUS),
3141fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3142fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3143fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3144291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3145291a2b48SSukumar Swaminathan 					    statLocalError);
3146fcf3ce44SJohn Forte 				}
3147fcf3ce44SJohn Forte 			}
3148fcf3ce44SJohn Forte 		}
3149fcf3ce44SJohn Forte 
315082527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
3151fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
3152fcf3ce44SJohn Forte 
3153fcf3ce44SJohn Forte 		break;
3154fcf3ce44SJohn Forte 
3155fcf3ce44SJohn Forte 	default:
3156fcf3ce44SJohn Forte 
3157fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
3158fcf3ce44SJohn Forte 
3159fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
316082527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
3161fcf3ce44SJohn Forte 
316282527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
3163fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
3164fcf3ce44SJohn Forte 
3165fcf3ce44SJohn Forte 		break;
316682527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
3167fcf3ce44SJohn Forte 
3168fcf3ce44SJohn Forte 	return (0);
3169fcf3ce44SJohn Forte 
317082527734SSukumar Swaminathan } /* emlxs_ct_handle_event() */
3171fcf3ce44SJohn Forte 
3172fcf3ce44SJohn Forte 
3173fcf3ce44SJohn Forte extern int
317482527734SSukumar Swaminathan emlxs_ct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
3175fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
3176fcf3ce44SJohn Forte {
3177fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3178fcf3ce44SJohn Forte 	IOCB *iocb;
3179fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
3180fcf3ce44SJohn Forte 	uint32_t cmd_code;
3181fcf3ce44SJohn Forte 
3182fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
3183fcf3ce44SJohn Forte 
3184fcf3ce44SJohn Forte 	CtCmd = (SLI_CT_REQUEST *)mp->virt;
318582527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
3186fcf3ce44SJohn Forte 
3187fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
3188fcf3ce44SJohn Forte 		int rval;
3189fcf3ce44SJohn Forte 
319082527734SSukumar Swaminathan 		rval = emlxs_dfc_handle_unsol_req(port, cp, iocbq, mp, size);
3191fcf3ce44SJohn Forte 
3192fcf3ce44SJohn Forte 		return (rval);
3193fcf3ce44SJohn Forte 	}
3194fcf3ce44SJohn Forte 
3195fcf3ce44SJohn Forte 	HBASTATS.CtCmdReceived++;
3196fcf3ce44SJohn Forte 
3197fcf3ce44SJohn Forte 	switch (CtCmd->FsType) {
3198fcf3ce44SJohn Forte 	case 0xFC:	/* Name server */
3199fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3200291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
320182527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3202fcf3ce44SJohn Forte 		break;
3203fcf3ce44SJohn Forte 
3204fcf3ce44SJohn Forte 	case 0xFA:	/* Managment server */
3205fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3206291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_mscmd_xlate(cmd_code),
320782527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3208fcf3ce44SJohn Forte 		break;
3209fcf3ce44SJohn Forte 
3210fcf3ce44SJohn Forte 	case 0x0A:	/* Emulex Remote server */
3211fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3212291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_rmcmd_xlate(cmd_code),
321382527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3214fcf3ce44SJohn Forte 		break;
3215fcf3ce44SJohn Forte 
3216fcf3ce44SJohn Forte 	default:
3217fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3218291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
321982527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3220fcf3ce44SJohn Forte 	}
3221fcf3ce44SJohn Forte 
3222728bdc9bSSukumar Swaminathan 	if (emlxs_log_ct_event(port, (uint8_t *)mp->virt, size,
322382527734SSukumar Swaminathan 	    iocb->ULPCONTEXT)) {
3224728bdc9bSSukumar Swaminathan 		/* Abort the exchange */
322582527734SSukumar Swaminathan 		emlxs_abort_ct_exchange(hba, port, iocb->ULPCONTEXT);
3226728bdc9bSSukumar Swaminathan 	}
3227fcf3ce44SJohn Forte 
3228fcf3ce44SJohn Forte 	return (0);
3229fcf3ce44SJohn Forte 
323082527734SSukumar Swaminathan } /* emlxs_ct_handle_unsol_req() */
3231fcf3ce44SJohn Forte 
3232fcf3ce44SJohn Forte 
3233*a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4)
3234fcf3ce44SJohn Forte static void
3235fcf3ce44SJohn Forte emlxs_send_rsnn(emlxs_port_t *port)
3236fcf3ce44SJohn Forte {
3237fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3238fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3239fcf3ce44SJohn Forte 	SLI_CT_REQUEST *ct;
3240fcf3ce44SJohn Forte 
3241291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port, sizeof (SLI_CT_REQUEST),
3242291a2b48SSukumar Swaminathan 	    sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) {
3243fcf3ce44SJohn Forte 		return;
3244fcf3ce44SJohn Forte 	}
3245291a2b48SSukumar Swaminathan 
3246fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3247fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3248fcf3ce44SJohn Forte 
3249fcf3ce44SJohn Forte 	/* Build the fc header */
325082527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(NAMESERVER_DID);
3251fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL;
325282527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3253fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES;
3254291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3255291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
3256fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3257fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3258fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3259fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
3260fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
3261fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3262fcf3ce44SJohn Forte 
3263fcf3ce44SJohn Forte 	/* Build the command */
3264fcf3ce44SJohn Forte 	ct = (SLI_CT_REQUEST *)pkt->pkt_cmd;
3265fcf3ce44SJohn Forte 
3266fcf3ce44SJohn Forte 	ct->RevisionId.bits.Revision = SLI_CT_REVISION;
3267fcf3ce44SJohn Forte 	ct->RevisionId.bits.InId = 0;
3268fcf3ce44SJohn Forte 
3269fcf3ce44SJohn Forte 	ct->FsType = SLI_CT_DIRECTORY_SERVICE;
3270fcf3ce44SJohn Forte 	ct->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
3271fcf3ce44SJohn Forte 
3272fcf3ce44SJohn Forte 	ct->CommandResponse.bits.Size = 0;
327382527734SSukumar Swaminathan 	ct->CommandResponse.bits.CmdRsp = LE_SWAP16(SLI_CTNS_RSNN_NN);
3274fcf3ce44SJohn Forte 
3275fcf3ce44SJohn Forte 	bcopy((uint8_t *)&hba->wwnn, (char *)ct->un.rsnn.wwnn, 8);
3276fcf3ce44SJohn Forte 
3277fcf3ce44SJohn Forte 	ct->un.rsnn.snn_len = strlen(port->snn);
3278fcf3ce44SJohn Forte 	bcopy(port->snn, (char *)ct->un.rsnn.snn, ct->un.rsnn.snn_len);
3279fcf3ce44SJohn Forte 
3280291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_send_msg, "Sending RSNN_NN. [%s]",
3281fcf3ce44SJohn Forte 	    port->snn);
3282fcf3ce44SJohn Forte 
3283fcf3ce44SJohn Forte 	/* Send the pkt later in another thread */
3284fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 0) != FC_SUCCESS) {
3285fcf3ce44SJohn Forte 		/* Free the pkt */
3286fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3287fcf3ce44SJohn Forte 	}
3288291a2b48SSukumar Swaminathan 
3289fcf3ce44SJohn Forte 	return;
3290fcf3ce44SJohn Forte 
329182527734SSukumar Swaminathan } /* emlxs_send_rsnn() */
3292*a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */
3293*a9800bebSGarrett D'Amore 
3294fcf3ce44SJohn Forte 
3295fcf3ce44SJohn Forte 
3296fcf3ce44SJohn Forte extern uint32_t
3297fcf3ce44SJohn Forte emlxs_ub_send_login_acc(emlxs_port_t *port, fc_unsol_buf_t *ubp)
3298fcf3ce44SJohn Forte {
3299fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3300fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3301fcf3ce44SJohn Forte 	ELS_PKT *els;
3302fcf3ce44SJohn Forte 	uint32_t rval;
3303fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
3304fcf3ce44SJohn Forte 
3305fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
3306fcf3ce44SJohn Forte 
3307fcf3ce44SJohn Forte 	if (!(pkt = emlxs_pkt_alloc(port,
3308fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (SERV_PARM), 0, 0, KM_NOSLEEP))) {
3309fcf3ce44SJohn Forte 		return (1);
3310fcf3ce44SJohn Forte 	}
3311291a2b48SSukumar Swaminathan 
3312fcf3ce44SJohn Forte 	/* Common initialization */
3313fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3314fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3315fcf3ce44SJohn Forte 
3316fcf3ce44SJohn Forte 	if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) {
3317fcf3ce44SJohn Forte 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
3318fcf3ce44SJohn Forte 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
3319fcf3ce44SJohn Forte 	}
3320291a2b48SSukumar Swaminathan 
3321fcf3ce44SJohn Forte 	/* Build the fc header */
3322fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id;
3323291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3324291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
3325fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.s_id = ubp->ub_frame.d_id;
3326fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3327291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3328291a2b48SSukumar Swaminathan 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
3329fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3330fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3331fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3332fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff;
3333fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id;
3334fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3335fcf3ce44SJohn Forte 
3336fcf3ce44SJohn Forte 	/* Build the command */
3337291a2b48SSukumar Swaminathan 	els = (ELS_PKT *)pkt->pkt_cmd;
3338fcf3ce44SJohn Forte 	els->elsCode = 0x02;
3339291a2b48SSukumar Swaminathan 	bcopy((void *)&port->sparam, (void *)&els->un.logi,
3340291a2b48SSukumar Swaminathan 	    sizeof (SERV_PARM));
3341fcf3ce44SJohn Forte 
3342fcf3ce44SJohn Forte 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
3343fcf3ce44SJohn Forte 		/* Free the pkt */
3344fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3345fcf3ce44SJohn Forte 	} else {
3346fcf3ce44SJohn Forte 		ub_priv->flags |= EMLXS_UB_INTERCEPT;
3347fcf3ce44SJohn Forte 	}
3348fcf3ce44SJohn Forte 
3349fcf3ce44SJohn Forte 	return (rval);
3350fcf3ce44SJohn Forte 
335182527734SSukumar Swaminathan } /* emlxs_ub_send_login_acc */
3352fcf3ce44SJohn Forte 
3353fcf3ce44SJohn Forte 
3354fcf3ce44SJohn Forte extern void
3355fcf3ce44SJohn Forte emlxs_send_logo(emlxs_port_t *port, uint32_t d_id)
3356fcf3ce44SJohn Forte {
3357fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3358fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3359fcf3ce44SJohn Forte 	ELS_PKT *els;
3360fcf3ce44SJohn Forte 
3361fcf3ce44SJohn Forte 	if (hba->state <= FC_LINK_DOWN) {
3362fcf3ce44SJohn Forte 		return;
3363fcf3ce44SJohn Forte 	}
3364291a2b48SSukumar Swaminathan 
3365291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port,
3366291a2b48SSukumar Swaminathan 	    sizeof (uint32_t) + sizeof (LOGO),
3367fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (LOGO), 0, KM_NOSLEEP))) {
3368fcf3ce44SJohn Forte 		return;
3369fcf3ce44SJohn Forte 	}
3370291a2b48SSukumar Swaminathan 
3371fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3372fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3373fcf3ce44SJohn Forte 
3374fcf3ce44SJohn Forte 	/* Build the fc header */
337582527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id);
3376291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3377291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
337882527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3379fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3380291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3381291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
3382fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3383fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3384fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3385fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
3386fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
3387fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3388fcf3ce44SJohn Forte 
3389fcf3ce44SJohn Forte 	/* Build the command */
3390fcf3ce44SJohn Forte 	els = (ELS_PKT *)pkt->pkt_cmd;
3391fcf3ce44SJohn Forte 	els->elsCode = 0x05;
3392fcf3ce44SJohn Forte 	els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id;
3393291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&port->wwpn, (uint8_t *)&els->un.logo.portName,
3394291a2b48SSukumar Swaminathan 	    8);
3395fcf3ce44SJohn Forte 
3396fcf3ce44SJohn Forte 	/* Send the pkt now */
3397fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3398fcf3ce44SJohn Forte 		/* Free the pkt */
3399fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3400fcf3ce44SJohn Forte 	}
3401291a2b48SSukumar Swaminathan 
3402fcf3ce44SJohn Forte 	return;
3403fcf3ce44SJohn Forte 
3404fcf3ce44SJohn Forte } /* emlxs_send_logo() */
3405