1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23291a2b48SSukumar Swaminathan  * Copyright 2009 Emulex.  All rights reserved.
24*82527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27*82527734SSukumar Swaminathan 
28291a2b48SSukumar Swaminathan #include <emlxs.h>
29fcf3ce44SJohn Forte 
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);
34291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_fdisk(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 
40*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp,
41291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
42*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp,
43291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
44*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp,
45291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
46*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp,
47291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
48*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp,
49291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
50*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp,
51291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
52*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp,
53291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
54*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp,
55291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
56*82527734SSukumar Swaminathan static void	emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp,
57291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
58291a2b48SSukumar Swaminathan static void	emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
59291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
60291a2b48SSukumar Swaminathan static void	emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
61291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
62291a2b48SSukumar Swaminathan static void	emlxs_send_rsnn(emlxs_port_t *port);
63fcf3ce44SJohn Forte 
64fcf3ce44SJohn Forte 
65fcf3ce44SJohn Forte 
66fcf3ce44SJohn Forte 
67fcf3ce44SJohn Forte /* Routine Declaration - Local */
68fcf3ce44SJohn Forte /* End Routine Declaration - Local */
69fcf3ce44SJohn Forte 
70fcf3ce44SJohn Forte /*
71fcf3ce44SJohn Forte  *  emlxs_els_handle_event
72fcf3ce44SJohn Forte  *
73291a2b48SSukumar Swaminathan  *  Description: Process an ELS Response Ring cmpl
74fcf3ce44SJohn Forte  *
75fcf3ce44SJohn Forte  */
76fcf3ce44SJohn Forte extern int
77*82527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
78fcf3ce44SJohn Forte {
79fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
80fcf3ce44SJohn Forte 	IOCB *iocb;
81fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
82fcf3ce44SJohn Forte 	fc_packet_t *pkt;
83fcf3ce44SJohn Forte 	uint32_t *lp0;
84fcf3ce44SJohn Forte 	uint32_t command;
85fcf3ce44SJohn Forte 	NODELIST *ndlp;
86fcf3ce44SJohn Forte 	uint32_t did;
87fcf3ce44SJohn Forte 	ELS_PKT *els;
88fcf3ce44SJohn Forte 
89fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
90fcf3ce44SJohn Forte 
91fcf3ce44SJohn Forte 	HBASTATS.ElsEvent++;
92fcf3ce44SJohn Forte 
93fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
94fcf3ce44SJohn Forte 
95fcf3ce44SJohn Forte 	if (!sbp) {
96fcf3ce44SJohn Forte 		/*
97fcf3ce44SJohn Forte 		 * completion with missing xmit command
98fcf3ce44SJohn Forte 		 */
99fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
102fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
103*82527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
104*82527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
105291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
106fcf3ce44SJohn Forte 
107fcf3ce44SJohn Forte 		return (1);
108fcf3ce44SJohn Forte 	}
109291a2b48SSukumar Swaminathan 
110*82527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_els) {
111fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
112fcf3ce44SJohn Forte 
113fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
114*82527734SSukumar Swaminathan 		    "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x "
115*82527734SSukumar Swaminathan 		    "status=0x%x perr=0x%x", cp->channelno, iocbq,
116*82527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG,
117*82527734SSukumar Swaminathan 		    iocb->ULPSTATUS, iocb->un.ulpWord[4]);
118fcf3ce44SJohn Forte 
119fcf3ce44SJohn Forte 		return (1);
120fcf3ce44SJohn Forte 	}
121291a2b48SSukumar Swaminathan 
122fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
123fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
124fcf3ce44SJohn Forte 	lp0 = (uint32_t *)pkt->pkt_cmd;
125fcf3ce44SJohn Forte 	command = *lp0 & ELS_CMD_MASK;
126*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
127fcf3ce44SJohn Forte 
128fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
129fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
130*82527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
131fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
132fcf3ce44SJohn Forte 	}
133291a2b48SSukumar Swaminathan 
134*82527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
135291a2b48SSukumar Swaminathan 		/*
136291a2b48SSukumar Swaminathan 		 * ELS Reply completion
137291a2b48SSukumar Swaminathan 		 */
138fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP_CX:
139fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP64_CX:
140fcf3ce44SJohn Forte 
141fcf3ce44SJohn Forte 		HBASTATS.ElsRspCompleted++;
142fcf3ce44SJohn Forte 
143fcf3ce44SJohn Forte 		if (command == ELS_CMD_ACC) {
144fcf3ce44SJohn Forte 			emlxs_handle_acc(port, sbp, iocbq, 1);
145fcf3ce44SJohn Forte 		} else {
146fcf3ce44SJohn Forte 			emlxs_handle_reject(port, sbp, iocbq, 1);
147fcf3ce44SJohn Forte 		}
148fcf3ce44SJohn Forte 
149fcf3ce44SJohn Forte 		break;
150fcf3ce44SJohn Forte 
151291a2b48SSukumar Swaminathan 		/*
152291a2b48SSukumar Swaminathan 		 * ELS command completion
153291a2b48SSukumar Swaminathan 		 */
154fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CR:
155fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CR:
156fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CX:
157fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CX:
158fcf3ce44SJohn Forte 
159fcf3ce44SJohn Forte 		HBASTATS.ElsCmdCompleted++;
160fcf3ce44SJohn Forte 
161fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_ELS_RSP_VALID;
162fcf3ce44SJohn Forte 
163fcf3ce44SJohn Forte 		els = (ELS_PKT *)pkt->pkt_resp;
164fcf3ce44SJohn Forte 
165fcf3ce44SJohn Forte 		pkt->pkt_resp_resid =
166fcf3ce44SJohn Forte 		    pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize;
167fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
168fcf3ce44SJohn Forte 
169fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id;
170fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
171fcf3ce44SJohn Forte 
172*82527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) {
173fcf3ce44SJohn Forte 			HBASTATS.ElsCmdGood++;
174fcf3ce44SJohn Forte 
175fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
176fcf3ce44SJohn Forte 				/*
177291a2b48SSukumar Swaminathan 				 * ULP patch - ULP expects
178291a2b48SSukumar Swaminathan 				 * resp_resid = 0 on success
179fcf3ce44SJohn Forte 				 */
180fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
181fcf3ce44SJohn Forte 			}
182291a2b48SSukumar Swaminathan 
183fcf3ce44SJohn Forte 			switch (command) {
184fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
185fcf3ce44SJohn Forte 				emlxs_handle_sol_fdisk(port, sbp);
186fcf3ce44SJohn Forte 
187fcf3ce44SJohn Forte 				break;
188fcf3ce44SJohn Forte 
189fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
190fcf3ce44SJohn Forte 				emlxs_handle_sol_flogi(port, sbp);
191fcf3ce44SJohn Forte 
192fcf3ce44SJohn Forte 				break;
193fcf3ce44SJohn Forte 
194fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login */
195fcf3ce44SJohn Forte 				emlxs_handle_sol_plogi(port, sbp);
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 				break;
198fcf3ce44SJohn Forte 
199fcf3ce44SJohn Forte 			case ELS_CMD_ADISC:	/* Adisc */
200fcf3ce44SJohn Forte 				emlxs_handle_sol_adisc(port, sbp);
201fcf3ce44SJohn Forte 
202fcf3ce44SJohn Forte 				break;
203fcf3ce44SJohn Forte 
204fcf3ce44SJohn Forte 			case ELS_CMD_LOGO:	/* Logout */
205fcf3ce44SJohn Forte 				emlxs_handle_sol_logo(port, sbp);
206fcf3ce44SJohn Forte 
207fcf3ce44SJohn Forte 				break;
208fcf3ce44SJohn Forte 
209fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In */
210fcf3ce44SJohn Forte 				emlxs_handle_sol_prli(port, sbp);
211fcf3ce44SJohn Forte 
212fcf3ce44SJohn Forte 				break;
213fcf3ce44SJohn Forte 
214fcf3ce44SJohn Forte 			default:
215fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
216291a2b48SSukumar Swaminathan 				    &emlxs_els_completion_msg, "%s: did=%x",
217fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did);
218fcf3ce44SJohn Forte 
219fcf3ce44SJohn Forte 				emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
220fcf3ce44SJohn Forte 
221fcf3ce44SJohn Forte 				break;
222fcf3ce44SJohn Forte 			}
223fcf3ce44SJohn Forte 
224fcf3ce44SJohn Forte 		} else {
225fcf3ce44SJohn Forte 			HBASTATS.ElsCmdError++;
226fcf3ce44SJohn Forte 
227fcf3ce44SJohn Forte 			/* Look for LS_REJECT */
228*82527734SSukumar Swaminathan 			if (iocb->ULPSTATUS == IOSTAT_LS_RJT) {
229fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_LS_RJT;
230fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
231fcf3ce44SJohn Forte 				pkt->pkt_reason = iocb->un.grsp.perr.statRsn;
232fcf3ce44SJohn Forte 				pkt->pkt_expln = iocb->un.grsp.perr.statBaExp;
233fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
234fcf3ce44SJohn Forte 
235291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
236291a2b48SSukumar Swaminathan 				ndlp = emlxs_node_find_did(port, did);
237291a2b48SSukumar Swaminathan 				if (ndlp) {
238291a2b48SSukumar Swaminathan 					emlxs_log_sd_lsrjt_event(port,
239291a2b48SSukumar Swaminathan 					    (HBA_WWN *)&ndlp->nlp_portname,
240291a2b48SSukumar Swaminathan 					    command, pkt->pkt_reason,
241291a2b48SSukumar Swaminathan 					    pkt->pkt_expln);
242291a2b48SSukumar Swaminathan 				}
243291a2b48SSukumar Swaminathan #endif
244291a2b48SSukumar Swaminathan 
245fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
246fcf3ce44SJohn Forte 				    &emlxs_els_completion_msg,
247fcf3ce44SJohn Forte 				    "%s Rejected: did=%x rsn=%x exp=%x",
248fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
249fcf3ce44SJohn Forte 				    pkt->pkt_reason, pkt->pkt_expln);
250*82527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
251fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
252fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
253fcf3ce44SJohn Forte 				    "%s: did=%x Local Reject. %s",
254fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
255291a2b48SSukumar Swaminathan 				    emlxs_error_xlate(iocb->un.grsp.perr.
256291a2b48SSukumar Swaminathan 				    statLocalError));
257fcf3ce44SJohn Forte 			} else {
258fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
259fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
260fcf3ce44SJohn Forte 				    "%s: did=%x %s (%02x%02x%02x%02x)",
261fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
262*82527734SSukumar Swaminathan 				    emlxs_state_xlate(iocb->ULPSTATUS),
263fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statAction,
264fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statRsn,
265fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statBaExp,
266fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statLocalError);
267fcf3ce44SJohn Forte 			}
268fcf3ce44SJohn Forte 
269fcf3ce44SJohn Forte 			switch (command) {
270fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login failed */
271fcf3ce44SJohn Forte 				ndlp = emlxs_node_find_did(port, did);
272fcf3ce44SJohn Forte 
273fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
274fcf3ce44SJohn Forte 					/* Open the node again */
275fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
276*82527734SSukumar Swaminathan 					    hba->channel_fcp);
277fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
278*82527734SSukumar Swaminathan 					    hba->channel_ip);
279fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
280fcf3ce44SJohn Forte 					if (pkt->pkt_state == FC_PKT_LS_RJT) {
281fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
282fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
283fcf3ce44SJohn Forte 						    pkt->pkt_reason,
284fcf3ce44SJohn Forte 						    pkt->pkt_expln);
285fcf3ce44SJohn Forte 					}
286291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
287fcf3ce44SJohn Forte 				}
288291a2b48SSukumar Swaminathan 
289fcf3ce44SJohn Forte 				break;
290fcf3ce44SJohn Forte 
291fcf3ce44SJohn Forte 
292fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In failed */
293fcf3ce44SJohn Forte 				ndlp = emlxs_node_find_did(port, did);
294fcf3ce44SJohn Forte 
295fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
296fcf3ce44SJohn Forte 					/* Open the node again */
297fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
298*82527734SSukumar Swaminathan 					    hba->channel_fcp);
299fcf3ce44SJohn Forte 				}
300291a2b48SSukumar Swaminathan 
301fcf3ce44SJohn Forte 				break;
302fcf3ce44SJohn Forte 
303fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
304fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
305fcf3ce44SJohn Forte 				if (pkt->pkt_state == FC_PKT_LS_RJT) {
306291a2b48SSukumar Swaminathan 					/* This will cause ULP to retry */
307291a2b48SSukumar Swaminathan 					/* FLOGI requests */
308fcf3ce44SJohn Forte 					pkt->pkt_reason = FC_REASON_QFULL;
309fcf3ce44SJohn Forte 					pkt->pkt_expln = 0;
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
312fcf3ce44SJohn Forte 					ndlp = emlxs_node_find_did(port, did);
313fcf3ce44SJohn Forte 					if (ndlp && ndlp->nlp_active) {
314fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
315fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
316fcf3ce44SJohn Forte 						    pkt->pkt_reason,
317fcf3ce44SJohn Forte 						    pkt->pkt_expln);
318fcf3ce44SJohn Forte 					}
319291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
320fcf3ce44SJohn Forte 				}
321291a2b48SSukumar Swaminathan 
322fcf3ce44SJohn Forte 				break;
323fcf3ce44SJohn Forte 
324fcf3ce44SJohn Forte 			default:
325fcf3ce44SJohn Forte 				break;
326fcf3ce44SJohn Forte 			}
327fcf3ce44SJohn Forte 
328*82527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
329fcf3ce44SJohn Forte 			    iocb->un.grsp.perr.statLocalError, 1);
330fcf3ce44SJohn Forte 
331fcf3ce44SJohn Forte 		}
332fcf3ce44SJohn Forte 
333fcf3ce44SJohn Forte 
334fcf3ce44SJohn Forte 		break;
335fcf3ce44SJohn Forte 
336fcf3ce44SJohn Forte 	default:
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
339fcf3ce44SJohn Forte 
340fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg,
341*82527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
342fcf3ce44SJohn Forte 
343*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
344fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
345fcf3ce44SJohn Forte 
346fcf3ce44SJohn Forte 		break;
347*82527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
348fcf3ce44SJohn Forte 
349fcf3ce44SJohn Forte 	return (0);
350fcf3ce44SJohn Forte 
351*82527734SSukumar Swaminathan } /* emlxs_els_handle_event() */
352fcf3ce44SJohn Forte 
353fcf3ce44SJohn Forte 
354fcf3ce44SJohn Forte extern int
355*82527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
356fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
357fcf3ce44SJohn Forte {
358fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
359fcf3ce44SJohn Forte 	uint32_t cmd_code;
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte 	HBASTATS.ElsCmdReceived++;
362fcf3ce44SJohn Forte 
363fcf3ce44SJohn Forte 	cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK;
364fcf3ce44SJohn Forte 
365*82527734SSukumar Swaminathan 	if (!(port->flag & EMLXS_PORT_BOUND)) {
366*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg,
367*82527734SSukumar Swaminathan 		    "ELS rcvd (0x%x): sid=%x Port not bound: Rejecting.",
368*82527734SSukumar Swaminathan 		    cmd_code, iocbq->iocb.un.elsreq.remoteID);
369*82527734SSukumar Swaminathan 
370*82527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
371*82527734SSukumar Swaminathan 		    ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
372*82527734SSukumar Swaminathan 
373*82527734SSukumar Swaminathan 		return (0);
374*82527734SSukumar Swaminathan 	}
375*82527734SSukumar Swaminathan 
376fcf3ce44SJohn Forte 	switch (cmd_code) {
377fcf3ce44SJohn Forte 	case ELS_CMD_RSCN:
378fcf3ce44SJohn Forte 		HBASTATS.ElsRscnReceived++;
379*82527734SSukumar Swaminathan 		emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size);
380fcf3ce44SJohn Forte 		break;
381fcf3ce44SJohn Forte 
382fcf3ce44SJohn Forte 	case ELS_CMD_FLOGI:
383fcf3ce44SJohn Forte 		HBASTATS.ElsFlogiReceived++;
384*82527734SSukumar Swaminathan 		emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size);
385fcf3ce44SJohn Forte 		break;
386fcf3ce44SJohn Forte 
387fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
388fcf3ce44SJohn Forte 		HBASTATS.ElsPlogiReceived++;
389*82527734SSukumar Swaminathan 		emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size);
390fcf3ce44SJohn Forte 		break;
391fcf3ce44SJohn Forte 
392fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
393fcf3ce44SJohn Forte 		HBASTATS.ElsPrliReceived++;
394*82527734SSukumar Swaminathan 		emlxs_handle_unsol_prli(port, cp, iocbq, mp, size);
395fcf3ce44SJohn Forte 		break;
396fcf3ce44SJohn Forte 
397fcf3ce44SJohn Forte 	case ELS_CMD_PRLO:
398fcf3ce44SJohn Forte 		HBASTATS.ElsPrloReceived++;
399*82527734SSukumar Swaminathan 		emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size);
400fcf3ce44SJohn Forte 		break;
401fcf3ce44SJohn Forte 
402fcf3ce44SJohn Forte 	case ELS_CMD_LOGO:
403fcf3ce44SJohn Forte 		HBASTATS.ElsLogoReceived++;
404*82527734SSukumar Swaminathan 		emlxs_handle_unsol_logo(port, cp, iocbq, mp, size);
405fcf3ce44SJohn Forte 		break;
406fcf3ce44SJohn Forte 
407fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
408fcf3ce44SJohn Forte 		HBASTATS.ElsAdiscReceived++;
409*82527734SSukumar Swaminathan 		emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size);
410fcf3ce44SJohn Forte 		break;
411fcf3ce44SJohn Forte 
412fcf3ce44SJohn Forte 	case ELS_CMD_AUTH:
413fcf3ce44SJohn Forte 		HBASTATS.ElsAuthReceived++;
414*82527734SSukumar Swaminathan 		emlxs_handle_unsol_auth(port, cp, iocbq, mp, size);
415fcf3ce44SJohn Forte 		break;
416fcf3ce44SJohn Forte 
417fcf3ce44SJohn Forte 	default:
418fcf3ce44SJohn Forte 		HBASTATS.ElsGenReceived++;
419*82527734SSukumar Swaminathan 		emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size);
420fcf3ce44SJohn Forte 		break;
421fcf3ce44SJohn Forte 	}
422fcf3ce44SJohn Forte 
423fcf3ce44SJohn Forte 	return (0);
424fcf3ce44SJohn Forte 
425*82527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */
426fcf3ce44SJohn Forte 
427fcf3ce44SJohn Forte 
428fcf3ce44SJohn Forte static void
429fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp)
430fcf3ce44SJohn Forte {
431fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
432fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
433fcf3ce44SJohn Forte 	emlxs_port_t *vport;
434fcf3ce44SJohn Forte 	SERV_PARM *sp;
435fcf3ce44SJohn Forte 	fc_packet_t *pkt;
436fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
437fcf3ce44SJohn Forte 	uint32_t did;
438fcf3ce44SJohn Forte 	IOCBQ *iocbq;
439fcf3ce44SJohn Forte 	IOCB *iocb;
440fcf3ce44SJohn Forte 	char buffer[64];
441fcf3ce44SJohn Forte 	uint32_t i;
442*82527734SSukumar Swaminathan 	int rc;
443fcf3ce44SJohn Forte 
444fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
445fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
446*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
447fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
448fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
449fcf3ce44SJohn Forte 
450fcf3ce44SJohn Forte 	if (sp->cmn.fPort) {
451fcf3ce44SJohn Forte 		mutex_enter(&EMLXS_PORT_LOCK);
452fcf3ce44SJohn Forte 
453fcf3ce44SJohn Forte 		hba->flag |= FC_FABRIC_ATTACHED;
454fcf3ce44SJohn Forte 		hba->flag &= ~FC_PT_TO_PT;
455fcf3ce44SJohn Forte 
456fcf3ce44SJohn Forte 		/* Save our new port ID */
457fcf3ce44SJohn Forte 		port->did = iocb->un.elsreq.myID;
458*82527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID);
459*82527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
460fcf3ce44SJohn Forte 
461fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
462fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
463fcf3ce44SJohn Forte 			hba->fc_edtov =
464*82527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
465fcf3ce44SJohn Forte 		} else {
466*82527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
467fcf3ce44SJohn Forte 		}
468fcf3ce44SJohn Forte 
469fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
470291a2b48SSukumar Swaminathan 		hba->fc_ratov =
471*82527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
472fcf3ce44SJohn Forte 
473fcf3ce44SJohn Forte 		if (hba->topology != TOPOLOGY_LOOP) {
474fcf3ce44SJohn Forte 			/*
475291a2b48SSukumar Swaminathan 			 * If we are a N-port connected to a Fabric,
476291a2b48SSukumar Swaminathan 			 * fixup sparam's so logins to devices on remote
477291a2b48SSukumar Swaminathan 			 * loops work.
478fcf3ce44SJohn Forte 			 */
479fcf3ce44SJohn Forte 			hba->sparam.cmn.altBbCredit = 1;
480fcf3ce44SJohn Forte 
481fcf3ce44SJohn Forte 			/* Set this bit in all the port sparam copies */
482fcf3ce44SJohn Forte 			for (i = 0; i < MAX_VPORTS; i++) {
483fcf3ce44SJohn Forte 				vport = &VPORT(i);
484fcf3ce44SJohn Forte 
485fcf3ce44SJohn Forte 				if (!(vport->flag & EMLXS_PORT_BOUND)) {
486fcf3ce44SJohn Forte 					continue;
487fcf3ce44SJohn Forte 				}
488291a2b48SSukumar Swaminathan 
489fcf3ce44SJohn Forte 				vport->sparam.cmn.altBbCredit = 1;
490fcf3ce44SJohn Forte 			}
491fcf3ce44SJohn Forte 		}
492*82527734SSukumar Swaminathan 
493fcf3ce44SJohn Forte 		if (sp->cmn.rspMultipleNPort) {
494fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_SUPPORTED;
495fcf3ce44SJohn Forte 
496fcf3ce44SJohn Forte 			if (cfg[CFG_NPIV_DELAY].current) {
497fcf3ce44SJohn Forte 				/*
498291a2b48SSukumar Swaminathan 				 * PATCH: for NPIV support on
499291a2b48SSukumar Swaminathan 				 * Brocade switch firmware 5.10b
500fcf3ce44SJohn Forte 				 */
501fcf3ce44SJohn Forte 				if ((hba->flag & FC_NPIV_ENABLED) &&
502fcf3ce44SJohn Forte 				    ((sp->nodeName.IEEE[0] == 0x00) &&
503fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[1] == 0x05) &&
504fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[2] == 0x1e))) {
505fcf3ce44SJohn Forte 					hba->flag |= FC_NPIV_DELAY_REQUIRED;
506fcf3ce44SJohn Forte 				}
507fcf3ce44SJohn Forte 			}
508fcf3ce44SJohn Forte 		} else {
509fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_UNSUPPORTED;
510fcf3ce44SJohn Forte 		}
511fcf3ce44SJohn Forte 
512fcf3ce44SJohn Forte 		if (!(hba->flag & FC_NPIV_ENABLED)) {
513fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Disabled ");
514fcf3ce44SJohn Forte 		} else if (hba->flag & FC_NPIV_SUPPORTED) {
515fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Supported ");
516fcf3ce44SJohn Forte 		} else {
517fcf3ce44SJohn Forte 			(void) strcpy(buffer, "npiv:Unsupported ");
518fcf3ce44SJohn Forte 		}
519fcf3ce44SJohn Forte 
520fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
521fcf3ce44SJohn Forte 		if (!sp->cmn.fcsp_support) {
522fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Unsupported");
523fcf3ce44SJohn Forte 		} else if (cfg[CFG_AUTH_ENABLE].current &&
524fcf3ce44SJohn Forte 		    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
525fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Supported");
526fcf3ce44SJohn Forte 		} else {
527fcf3ce44SJohn Forte 			(void) strcat(buffer, "fcsp:Disabled");
528fcf3ce44SJohn Forte 		}
529291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
530fcf3ce44SJohn Forte 
531fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
532fcf3ce44SJohn Forte 
533fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
534291a2b48SSukumar Swaminathan 		    "FLOGI: did=%x sid=%x %s", did, port->did, buffer);
535fcf3ce44SJohn Forte 
536fcf3ce44SJohn Forte 		/* Update our service parms */
537*82527734SSukumar Swaminathan 		if (!(mbox = (MAILBOXQ *)emlxs_mem_get(hba,
538*82527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
539*82527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
540*82527734SSukumar Swaminathan 			    IOERR_NO_RESOURCES, 1);
541*82527734SSukumar Swaminathan 			return;
542*82527734SSukumar Swaminathan 
543*82527734SSukumar Swaminathan 		}
544*82527734SSukumar Swaminathan 
545*82527734SSukumar Swaminathan 		/* For SLI4 we replace CONFIG_LINK and REG_LOGIN of */
546*82527734SSukumar Swaminathan 		/* Fabric with a REG_VFI mailbox command. */
547*82527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
548*82527734SSukumar Swaminathan 			emlxs_port_t *vpip = sbp->port;
549*82527734SSukumar Swaminathan 			VFIobj_t *vfip;
550*82527734SSukumar Swaminathan 			FCFIobj_t *fcfp;
551*82527734SSukumar Swaminathan 			uint32_t regvfi;
552*82527734SSukumar Swaminathan 
553*82527734SSukumar Swaminathan 			vfip = vpip->VFIp;
554*82527734SSukumar Swaminathan 			fcfp = vfip->FCFIp;
555*82527734SSukumar Swaminathan 			regvfi = vfip->state & RESOURCE_VFI_REG;
556fcf3ce44SJohn Forte 
557*82527734SSukumar Swaminathan 			/* Save the FCF service parameters */
558*82527734SSukumar Swaminathan 			bcopy((void *)sp, (void *)&fcfp->fcf_sparam,
559*82527734SSukumar Swaminathan 			    sizeof (SERV_PARM));
560*82527734SSukumar Swaminathan 
561*82527734SSukumar Swaminathan 			if (emlxs_mb_check_sparm(hba, sp)) {
562*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT,
563*82527734SSukumar Swaminathan 				    &emlxs_node_create_failed_msg,
564*82527734SSukumar Swaminathan 				    "Invalid Fabric parameters. did=%06x",
565*82527734SSukumar Swaminathan 				    port->did);
566fcf3ce44SJohn Forte 				(void) emlxs_mem_put(hba, MEM_MBOX,
567fcf3ce44SJohn Forte 				    (uint8_t *)mbox);
568*82527734SSukumar Swaminathan 				emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
569*82527734SSukumar Swaminathan 				    IOERR_NO_RESOURCES, 1);
570*82527734SSukumar Swaminathan 				return;
571*82527734SSukumar Swaminathan 			}
572*82527734SSukumar Swaminathan 
573*82527734SSukumar Swaminathan 			if (!regvfi) {
574*82527734SSukumar Swaminathan 				if (emlxs_mb_reg_vfi(hba, mbox, vfip, vpip) ==
575*82527734SSukumar Swaminathan 				    0) {
576*82527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
577*82527734SSukumar Swaminathan 					    &emlxs_sli_detail_msg,
578*82527734SSukumar Swaminathan 					    "Cannot REG_VFI for FCF: sid=%x",
579*82527734SSukumar Swaminathan 					    port->did);
580*82527734SSukumar Swaminathan 
581*82527734SSukumar Swaminathan 					(void) emlxs_mem_put(hba, MEM_MBOX,
582*82527734SSukumar Swaminathan 					    (uint8_t *)mbox);
583*82527734SSukumar Swaminathan 					emlxs_pkt_complete(sbp,
584*82527734SSukumar Swaminathan 					    IOSTAT_LOCAL_REJECT,
585*82527734SSukumar Swaminathan 					    IOERR_NO_RESOURCES, 1);
586*82527734SSukumar Swaminathan 					return;
587*82527734SSukumar Swaminathan 				}
588*82527734SSukumar Swaminathan 				mbox->sbp = (uint8_t *)sbp;
589*82527734SSukumar Swaminathan 
590*82527734SSukumar Swaminathan 				rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
591*82527734SSukumar Swaminathan 				    MBX_NOWAIT, 0);
592*82527734SSukumar Swaminathan 				if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
593*82527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
594*82527734SSukumar Swaminathan 					    &emlxs_sli_detail_msg,
595*82527734SSukumar Swaminathan 					    "Cannot REG_VFI for FCF: sid=%x",
596*82527734SSukumar Swaminathan 					    port->did);
597*82527734SSukumar Swaminathan 
598*82527734SSukumar Swaminathan 					(void) emlxs_mem_put(hba, MEM_MBOX,
599*82527734SSukumar Swaminathan 					    (uint8_t *)mbox);
600*82527734SSukumar Swaminathan 					emlxs_pkt_complete(sbp,
601*82527734SSukumar Swaminathan 					    IOSTAT_LOCAL_REJECT,
602*82527734SSukumar Swaminathan 					    IOERR_NO_RESOURCES, 1);
603*82527734SSukumar Swaminathan 					return;
604*82527734SSukumar Swaminathan 				}
605*82527734SSukumar Swaminathan 				/* Preset the state for the REG_VFI cmpl */
606*82527734SSukumar Swaminathan 				emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
607*82527734SSukumar Swaminathan 
608*82527734SSukumar Swaminathan 				/* Deferred completion of this pkt until */
609*82527734SSukumar Swaminathan 				/* REG_VFI is complete */
610*82527734SSukumar Swaminathan 				return;
611fcf3ce44SJohn Forte 			}
612*82527734SSukumar Swaminathan 			/* VFI is already Registered */
613291a2b48SSukumar Swaminathan 
614*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox);
615*82527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
616*82527734SSukumar Swaminathan 
617*82527734SSukumar Swaminathan 			EMLXS_STATE_CHANGE_LOCKED(hba, FC_READY);
618*82527734SSukumar Swaminathan 			if (regvfi) {
619*82527734SSukumar Swaminathan 				/*
620*82527734SSukumar Swaminathan 				 * If NPIV Fabric support has just been
621*82527734SSukumar Swaminathan 				 * established on the physical port, then
622*82527734SSukumar Swaminathan 				 * notify the vports of the link up.
623*82527734SSukumar Swaminathan 				 */
624*82527734SSukumar Swaminathan 				if ((hba->flag & FC_NPIV_ENABLED) &&
625*82527734SSukumar Swaminathan 				    (hba->flag & FC_NPIV_SUPPORTED)) {
626*82527734SSukumar Swaminathan 					/* Skip the physical port */
627*82527734SSukumar Swaminathan 					for (i = 1; i < MAX_VPORTS; i++) {
628*82527734SSukumar Swaminathan 						vport = &VPORT(i);
629*82527734SSukumar Swaminathan 
630*82527734SSukumar Swaminathan 						if (!(vport->flag &
631*82527734SSukumar Swaminathan 						    EMLXS_PORT_BOUND) ||
632*82527734SSukumar Swaminathan 						    !(vport->flag &
633*82527734SSukumar Swaminathan 						    EMLXS_PORT_ENABLE)) {
634*82527734SSukumar Swaminathan 							continue;
635*82527734SSukumar Swaminathan 						}
636*82527734SSukumar Swaminathan 
637*82527734SSukumar Swaminathan 						emlxs_port_online(vport);
638*82527734SSukumar Swaminathan 					}
639*82527734SSukumar Swaminathan 				}
640*82527734SSukumar Swaminathan 			}
641*82527734SSukumar Swaminathan 			return;
642*82527734SSukumar Swaminathan 		}
643*82527734SSukumar Swaminathan 
644*82527734SSukumar Swaminathan 		/* Save the fabric service parameters */
645*82527734SSukumar Swaminathan 		bcopy((void *)sp, (void *)&port->fabric_sparam,
646*82527734SSukumar Swaminathan 		    sizeof (SERV_PARM));
647*82527734SSukumar Swaminathan 
648*82527734SSukumar Swaminathan 		emlxs_mb_config_link(hba, mbox);
649*82527734SSukumar Swaminathan 
650*82527734SSukumar Swaminathan 		rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox, MBX_NOWAIT, 0);
651*82527734SSukumar Swaminathan 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
652*82527734SSukumar Swaminathan 			(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox);
653fcf3ce44SJohn Forte 		}
654291a2b48SSukumar Swaminathan 
655fcf3ce44SJohn Forte 		/* Preset the state for the reg_did */
656fcf3ce44SJohn Forte 		emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
657fcf3ce44SJohn Forte 
658*82527734SSukumar Swaminathan 		if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam,
659fcf3ce44SJohn Forte 		    sbp, NULL, NULL) == 0) {
660291a2b48SSukumar Swaminathan 			/* Deferred completion of this pkt until */
661291a2b48SSukumar Swaminathan 			/* login is complete */
662fcf3ce44SJohn Forte 			return;
663fcf3ce44SJohn Forte 		}
664291a2b48SSukumar Swaminathan 
665fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
666fcf3ce44SJohn Forte 		    IOERR_NO_RESOURCES, 1);
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 	} else {	/* No switch */
669291a2b48SSukumar Swaminathan 
670fcf3ce44SJohn Forte 		mutex_enter(&EMLXS_PORT_LOCK);
671fcf3ce44SJohn Forte 
672fcf3ce44SJohn Forte 		hba->flag &= ~FC_FABRIC_ATTACHED;
673fcf3ce44SJohn Forte 		hba->flag |= FC_PT_TO_PT;
674fcf3ce44SJohn Forte 
675fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
676fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
677fcf3ce44SJohn Forte 			hba->fc_edtov =
678*82527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
679fcf3ce44SJohn Forte 		} else {
680*82527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
681fcf3ce44SJohn Forte 		}
682fcf3ce44SJohn Forte 
683fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
684291a2b48SSukumar Swaminathan 		hba->fc_ratov =
685*82527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
686fcf3ce44SJohn Forte 
687fcf3ce44SJohn Forte 		hba->flag &= ~FC_NPIV_SUPPORTED;
688fcf3ce44SJohn Forte 		(void) strcpy(buffer, "npiv:Disabled. P2P");
689*82527734SSukumar Swaminathan 
690*82527734SSukumar Swaminathan 		port->rdid = did;
691fcf3ce44SJohn Forte 
692fcf3ce44SJohn Forte 		/* Clear the fabric service parameters */
693fcf3ce44SJohn Forte 		bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM));
694fcf3ce44SJohn Forte 
695fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
696fcf3ce44SJohn Forte 
697fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
698291a2b48SSukumar Swaminathan 		    "FLOGI: did=%x sid=%x %s", did, port->did, buffer);
699fcf3ce44SJohn Forte 
700fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
701fcf3ce44SJohn Forte 	}
702fcf3ce44SJohn Forte 
703fcf3ce44SJohn Forte 	return;
704fcf3ce44SJohn Forte 
705*82527734SSukumar Swaminathan } /* emlxs_handle_sol_flogi() */
706fcf3ce44SJohn Forte 
707fcf3ce44SJohn Forte 
708fcf3ce44SJohn Forte static void
709fcf3ce44SJohn Forte emlxs_handle_sol_fdisk(emlxs_port_t *port, emlxs_buf_t *sbp)
710fcf3ce44SJohn Forte {
711fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
712fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
713fcf3ce44SJohn Forte 	SERV_PARM *sp;
714fcf3ce44SJohn Forte 	fc_packet_t *pkt;
715fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
716fcf3ce44SJohn Forte 	uint32_t did;
717fcf3ce44SJohn Forte 	IOCBQ *iocbq;
718fcf3ce44SJohn Forte 	IOCB *iocb;
719fcf3ce44SJohn Forte 	char buffer[64];
720*82527734SSukumar Swaminathan 	int rc;
721fcf3ce44SJohn Forte 
722fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
723fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
724*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
725fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
726fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
727fcf3ce44SJohn Forte 
728fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
729fcf3ce44SJohn Forte 
730fcf3ce44SJohn Forte 	/* Save our new port ID */
731fcf3ce44SJohn Forte 	port->did = iocb->un.elsreq.myID;
732*82527734SSukumar Swaminathan 	pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
733fcf3ce44SJohn Forte 
734fcf3ce44SJohn Forte 	/* Save the fabric service parameters */
735fcf3ce44SJohn Forte 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
736fcf3ce44SJohn Forte 
737fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
738fcf3ce44SJohn Forte 
739fcf3ce44SJohn Forte 	buffer[0] = 0;
740fcf3ce44SJohn Forte 
741fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
742fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
743fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
744291a2b48SSukumar Swaminathan 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_NPIV].current) {
745fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
746fcf3ce44SJohn Forte 	} else {
747fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
748fcf3ce44SJohn Forte 	}
749291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
750fcf3ce44SJohn Forte 
751fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
752291a2b48SSukumar Swaminathan 	    "FDISK: did=%x sid=%x %s", did, port->did, buffer);
753fcf3ce44SJohn Forte 
754*82527734SSukumar Swaminathan 	if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
755*82527734SSukumar Swaminathan 		emlxs_port_t *pport = &PPORT;
756*82527734SSukumar Swaminathan 
757*82527734SSukumar Swaminathan 		port->VFIp = pport->VFIp;
758*82527734SSukumar Swaminathan 
759*82527734SSukumar Swaminathan 		if (emlxs_mb_check_sparm(hba, sp)) {
760*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT,
761*82527734SSukumar Swaminathan 			    &emlxs_node_create_failed_msg,
762*82527734SSukumar Swaminathan 			    "Invalid Fabric parameters. did=%06x",
763*82527734SSukumar Swaminathan 			    port->did);
764*82527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
765*82527734SSukumar Swaminathan 			    IOERR_NO_RESOURCES, 1);
766*82527734SSukumar Swaminathan 			return;
767*82527734SSukumar Swaminathan 		}
768*82527734SSukumar Swaminathan 
769*82527734SSukumar Swaminathan 		/* Preset the state for the REG_VFI cmpl */
770*82527734SSukumar Swaminathan 		emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
771*82527734SSukumar Swaminathan 
772*82527734SSukumar Swaminathan 		if (port->flag & EMLXS_PORT_REG_VPI_CMPL) {
773*82527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, -1, 0, 1);
774*82527734SSukumar Swaminathan 		} else {
775*82527734SSukumar Swaminathan 			/* Deferred completion of this pkt until */
776*82527734SSukumar Swaminathan 			/* REG_VPI is complete */
777*82527734SSukumar Swaminathan 			(void) emlxs_mb_reg_vpi(port, sbp);
778*82527734SSukumar Swaminathan 		}
779*82527734SSukumar Swaminathan 
780*82527734SSukumar Swaminathan 		return;
781*82527734SSukumar Swaminathan 	}
782*82527734SSukumar Swaminathan 
783fcf3ce44SJohn Forte 	/* Update our service parms */
784*82527734SSukumar Swaminathan 	if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX, 1))) {
785*82527734SSukumar Swaminathan 		emlxs_mb_config_link(hba, mbox);
786fcf3ce44SJohn Forte 
787*82527734SSukumar Swaminathan 		rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
788*82527734SSukumar Swaminathan 		    MBX_NOWAIT, 0);
789*82527734SSukumar Swaminathan 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
790fcf3ce44SJohn Forte 			(void) emlxs_mem_put(hba, MEM_MBOX, (uint8_t *)mbox);
791fcf3ce44SJohn Forte 		}
792fcf3ce44SJohn Forte 	}
793291a2b48SSukumar Swaminathan 
794fcf3ce44SJohn Forte 	/* Preset the state for the reg_did */
795fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
796fcf3ce44SJohn Forte 
797*82527734SSukumar Swaminathan 	if (emlxs_mb_reg_did(port, FABRIC_DID, &port->fabric_sparam, sbp,
798fcf3ce44SJohn Forte 	    NULL, NULL) == 0) {
799fcf3ce44SJohn Forte 		/*
800fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
801fcf3ce44SJohn Forte 		 */
802fcf3ce44SJohn Forte 
803fcf3ce44SJohn Forte 		return;
804fcf3ce44SJohn Forte 	}
805291a2b48SSukumar Swaminathan 
806fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
807fcf3ce44SJohn Forte 
808fcf3ce44SJohn Forte 	return;
809fcf3ce44SJohn Forte 
810*82527734SSukumar Swaminathan } /* emlxs_handle_sol_fdisk() */
811fcf3ce44SJohn Forte 
812fcf3ce44SJohn Forte 
813fcf3ce44SJohn Forte static void
814fcf3ce44SJohn Forte emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp)
815fcf3ce44SJohn Forte {
816fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
817fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
818fcf3ce44SJohn Forte 	SERV_PARM *sp;
819fcf3ce44SJohn Forte 	fc_packet_t *pkt;
820fcf3ce44SJohn Forte 	uint32_t did;
821fcf3ce44SJohn Forte 	uint32_t sid;
822fcf3ce44SJohn Forte 	NODELIST *ndlp;
823fcf3ce44SJohn Forte 	char buffer[64];
824fcf3ce44SJohn Forte 
825fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
826fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
827*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
828*82527734SSukumar Swaminathan 	sid = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.s_id);
829fcf3ce44SJohn Forte 
830fcf3ce44SJohn Forte 	buffer[0] = 0;
831fcf3ce44SJohn Forte 
832fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
833fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
834fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
835fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
836fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
837fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
838fcf3ce44SJohn Forte 	} else {
839fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
840fcf3ce44SJohn Forte 	}
841291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
842fcf3ce44SJohn Forte 
843fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
844291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x %s", sid, did, buffer);
845fcf3ce44SJohn Forte 
846fcf3ce44SJohn Forte 	/* Preset the pkt state for reg_did */
847fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
848fcf3ce44SJohn Forte 
849fcf3ce44SJohn Forte 	/*
850fcf3ce44SJohn Forte 	 * Do register login to Firmware before calling packet completion
851fcf3ce44SJohn Forte 	 */
852fcf3ce44SJohn Forte 	if (emlxs_mb_reg_did(port, did, sp, sbp, NULL, NULL) == 0) {
853fcf3ce44SJohn Forte 		/*
854fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
855fcf3ce44SJohn Forte 		 */
856fcf3ce44SJohn Forte 		return;
857fcf3ce44SJohn Forte 	}
858291a2b48SSukumar Swaminathan 
859fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
860fcf3ce44SJohn Forte 
861fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
862fcf3ce44SJohn Forte 		/* Open the node again */
863*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
864*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
865fcf3ce44SJohn Forte 	}
866291a2b48SSukumar Swaminathan 
867fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
868fcf3ce44SJohn Forte 
869fcf3ce44SJohn Forte 	return;
870fcf3ce44SJohn Forte 
871*82527734SSukumar Swaminathan } /* emlxs_handle_sol_plogi() */
872fcf3ce44SJohn Forte 
873fcf3ce44SJohn Forte 
874fcf3ce44SJohn Forte static void
875fcf3ce44SJohn Forte emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp)
876fcf3ce44SJohn Forte {
877*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
878fcf3ce44SJohn Forte 	fc_packet_t *pkt;
879fcf3ce44SJohn Forte 	uint32_t did;
880fcf3ce44SJohn Forte 	NODELIST *ndlp;
881*82527734SSukumar Swaminathan 	RPIobj_t *rp;
882fcf3ce44SJohn Forte 
883fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
884*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
885fcf3ce44SJohn Forte 
886291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "ADISC: did=%x",
887fcf3ce44SJohn Forte 	    did);
888fcf3ce44SJohn Forte 
889fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
890fcf3ce44SJohn Forte 
891fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
892fcf3ce44SJohn Forte 		/* Open the node again */
893*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
894*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
895*82527734SSukumar Swaminathan 
896*82527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
897*82527734SSukumar Swaminathan 			rp = emlxs_sli4_find_rpi(hba, ndlp->nlp_Rpi);
898*82527734SSukumar Swaminathan 			if (rp && (rp->state & RESOURCE_RPI_PAUSED)) {
899*82527734SSukumar Swaminathan 				(void) emlxs_mb_resume_rpi(hba, sbp,
900*82527734SSukumar Swaminathan 				    ndlp->nlp_Rpi);
901*82527734SSukumar Swaminathan 				rp->state &= ~RESOURCE_RPI_PAUSED;
902*82527734SSukumar Swaminathan 				/*
903*82527734SSukumar Swaminathan 				 * Delay ADISC cmpl to ULP till
904*82527734SSukumar Swaminathan 				 * after RESUME_RPI
905*82527734SSukumar Swaminathan 				 */
906*82527734SSukumar Swaminathan 				return;
907*82527734SSukumar Swaminathan 			}
908*82527734SSukumar Swaminathan 		}
909fcf3ce44SJohn Forte 	}
910291a2b48SSukumar Swaminathan 
911fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
912fcf3ce44SJohn Forte 
913fcf3ce44SJohn Forte 	return;
914fcf3ce44SJohn Forte 
915*82527734SSukumar Swaminathan } /* emlxs_handle_sol_adisc() */
916fcf3ce44SJohn Forte 
917fcf3ce44SJohn Forte 
918fcf3ce44SJohn Forte static void
919fcf3ce44SJohn Forte emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp)
920fcf3ce44SJohn Forte {
921fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
922fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
923fcf3ce44SJohn Forte 	fc_packet_t *pkt;
924fcf3ce44SJohn Forte 	NODELIST *ndlp;
925fcf3ce44SJohn Forte 	uint32_t did;
926fcf3ce44SJohn Forte 	PRLI *npr;
927fcf3ce44SJohn Forte 	uint32_t task_retry_id;
928fcf3ce44SJohn Forte 
929fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
930fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
931*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
932fcf3ce44SJohn Forte 
933fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
934fcf3ce44SJohn Forte 
935fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
936fcf3ce44SJohn Forte 		/* Check for FCP support */
937fcf3ce44SJohn Forte 		if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
938fcf3ce44SJohn Forte 		    (npr->prliType == PRLI_FCP_TYPE)) {
939fcf3ce44SJohn Forte 			/* Check for target */
940fcf3ce44SJohn Forte 			if (npr->targetFunc) {
941fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
942fcf3ce44SJohn Forte 			} else {
943fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
944fcf3ce44SJohn Forte 			}
945fcf3ce44SJohn Forte 
946fcf3ce44SJohn Forte 			/* Check for initiator */
947fcf3ce44SJohn Forte 			if (npr->initiatorFunc) {
948fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
949fcf3ce44SJohn Forte 			} else {
950fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
951fcf3ce44SJohn Forte 			}
952fcf3ce44SJohn Forte 
953291a2b48SSukumar Swaminathan 			/* If TRI support is not required then force */
954291a2b48SSukumar Swaminathan 			/* the task_retry_id value to one */
955fcf3ce44SJohn Forte 			if (cfg[CFG_TRI_REQUIRED].current == 0) {
956fcf3ce44SJohn Forte 				task_retry_id = 1;
957fcf3ce44SJohn Forte 			} else {
958fcf3ce44SJohn Forte 				task_retry_id = npr->TaskRetryIdReq;
959fcf3ce44SJohn Forte 			}
960fcf3ce44SJohn Forte 
961fcf3ce44SJohn Forte 			/* Check for FCP2 target support */
962fcf3ce44SJohn Forte 			/* Retry and TaskRetryId bits are both required here */
963fcf3ce44SJohn Forte 			if (npr->targetFunc && npr->Retry && task_retry_id) {
964fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
965fcf3ce44SJohn Forte 			} else {
966fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
967fcf3ce44SJohn Forte 			}
968fcf3ce44SJohn Forte 		}
969291a2b48SSukumar Swaminathan 
970fcf3ce44SJohn Forte 		/* Open the node again */
971*82527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
972fcf3ce44SJohn Forte 
973fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
974291a2b48SSukumar Swaminathan 		    "PRLI: did=%x info=%02x", did, ndlp->nlp_fcp_info);
975fcf3ce44SJohn Forte 
976fcf3ce44SJohn Forte 		/*
977fcf3ce44SJohn Forte 		 * Report PRLI completion
978fcf3ce44SJohn Forte 		 */
979fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
980fcf3ce44SJohn Forte 
981fcf3ce44SJohn Forte 	} else {
982fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
983291a2b48SSukumar Swaminathan 		    "PRLI: did=%x: Node not found. Failing.", did);
984fcf3ce44SJohn Forte 
985fcf3ce44SJohn Forte 		/*
986fcf3ce44SJohn Forte 		 * Report PRLI failed
987fcf3ce44SJohn Forte 		 */
988fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
989fcf3ce44SJohn Forte 		    IOERR_INVALID_RPI, 1);
990fcf3ce44SJohn Forte 	}
991fcf3ce44SJohn Forte 	return;
992fcf3ce44SJohn Forte 
993*82527734SSukumar Swaminathan } /* emlxs_handle_sol_prli() */
994fcf3ce44SJohn Forte 
995fcf3ce44SJohn Forte 
996fcf3ce44SJohn Forte static void
997fcf3ce44SJohn Forte emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp)
998fcf3ce44SJohn Forte {
999*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
1000fcf3ce44SJohn Forte 	fc_packet_t *pkt;
1001fcf3ce44SJohn Forte 	uint32_t did;
1002fcf3ce44SJohn Forte 	NODELIST *ndlp;
1003fcf3ce44SJohn Forte 
1004fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
1005*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
1006fcf3ce44SJohn Forte 
1007291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "LOGO: did=%x",
1008fcf3ce44SJohn Forte 	    did);
1009fcf3ce44SJohn Forte 
1010fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, did);
1011fcf3ce44SJohn Forte 
1012fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
1013fcf3ce44SJohn Forte 		/* Close the node for any further normal IO */
1014*82527734SSukumar Swaminathan 		emlxs_node_close(port, ndlp, hba->channel_fcp, 60);
1015*82527734SSukumar Swaminathan 		emlxs_node_close(port, ndlp, hba->channel_ip, 60);
1016fcf3ce44SJohn Forte 
1017fcf3ce44SJohn Forte 		/* Flush tx queues */
1018fcf3ce44SJohn Forte 		(void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
1019fcf3ce44SJohn Forte 
1020fcf3ce44SJohn Forte 		/* Flush chip queues */
1021fcf3ce44SJohn Forte 		(void) emlxs_chipq_node_flush(port, 0, ndlp, 0);
1022fcf3ce44SJohn Forte 	}
1023291a2b48SSukumar Swaminathan 
1024fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
1025fcf3ce44SJohn Forte 
1026fcf3ce44SJohn Forte 	return;
1027fcf3ce44SJohn Forte 
1028*82527734SSukumar Swaminathan } /* emlxs_handle_sol_logo() */
1029fcf3ce44SJohn Forte 
1030fcf3ce44SJohn Forte 
1031fcf3ce44SJohn Forte /* ARGSUSED */
1032fcf3ce44SJohn Forte static void
1033*82527734SSukumar Swaminathan emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1034fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1035fcf3ce44SJohn Forte {
1036fcf3ce44SJohn Forte 	uint32_t *lp;
1037fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1038fcf3ce44SJohn Forte 	uint8_t *bp;
1039fcf3ce44SJohn Forte 	IOCB *iocb;
1040fcf3ce44SJohn Forte 	uint32_t count;
1041fcf3ce44SJohn Forte 	uint32_t sid;
1042fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1043fcf3ce44SJohn Forte 
1044fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1045fcf3ce44SJohn Forte 	bp = mp->virt;
1046291a2b48SSukumar Swaminathan 	lp = (uint32_t *)bp + 1;
1047fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1048fcf3ce44SJohn Forte 
1049291a2b48SSukumar Swaminathan 	/* Log the legacy rscn event for physical port only */
1050291a2b48SSukumar Swaminathan 	if (port->vpi == 0) {
1051291a2b48SSukumar Swaminathan 		emlxs_log_rscn_event(port, bp, size);
1052291a2b48SSukumar Swaminathan 	}
1053291a2b48SSukumar Swaminathan 
1054291a2b48SSukumar Swaminathan 	/* Log the vport rscn event for all ports */
1055291a2b48SSukumar Swaminathan 	emlxs_log_vportrscn_event(port, bp, size);
1056fcf3ce44SJohn Forte 
1057fcf3ce44SJohn Forte 	count = ((size - 4) / 4);
1058fcf3ce44SJohn Forte 
1059fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1);
1060fcf3ce44SJohn Forte 
1061fcf3ce44SJohn Forte 	if (ubp == NULL) {
1062fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1063fcf3ce44SJohn Forte 		    "RSCN rcvd: sid=%x  %d page(s): %08X, %08X. Rejecting.",
1064*82527734SSukumar Swaminathan 		    sid, count, LE_SWAP32(*lp),
1065*82527734SSukumar Swaminathan 		    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0));
1066fcf3ce44SJohn Forte 
1067fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1068291a2b48SSukumar Swaminathan 		    ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1069fcf3ce44SJohn Forte 
1070fcf3ce44SJohn Forte 		goto drop_it;
1071fcf3ce44SJohn Forte 	}
1072291a2b48SSukumar Swaminathan 
1073fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1074fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1075fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
1076fcf3ce44SJohn Forte 
1077fcf3ce44SJohn Forte 	/*
1078fcf3ce44SJohn Forte 	 * Setup frame header
1079fcf3ce44SJohn Forte 	 */
1080fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1081fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1082*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1083*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1084fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1085*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1086fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1087fcf3ce44SJohn Forte 
1088fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1089291a2b48SSukumar Swaminathan 	    "RSCN: sid=%x  %d page(s): %08X, %08X  buffer=%p token=%x.", sid,
1090*82527734SSukumar Swaminathan 	    count, LE_SWAP32(*lp),
1091*82527734SSukumar Swaminathan 	    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0), ubp, ub_priv->token);
1092fcf3ce44SJohn Forte 
1093fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1094fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1095291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1096fcf3ce44SJohn Forte 
1097fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1098fcf3ce44SJohn Forte 
1099fcf3ce44SJohn Forte drop_it:
1100fcf3ce44SJohn Forte 
1101fcf3ce44SJohn Forte 	return;
1102fcf3ce44SJohn Forte 
1103*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_rscn() */
1104fcf3ce44SJohn Forte 
1105fcf3ce44SJohn Forte 
1106fcf3ce44SJohn Forte /* This is shared by FCT driver */
1107fcf3ce44SJohn Forte extern uint32_t
1108291a2b48SSukumar Swaminathan emlxs_process_unsol_flogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1109291a2b48SSukumar Swaminathan     uint32_t size, char *buffer)
1110fcf3ce44SJohn Forte {
1111fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1112fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1113fcf3ce44SJohn Forte 	uint8_t *bp;
1114fcf3ce44SJohn Forte 	IOCB *iocb;
1115fcf3ce44SJohn Forte 	uint32_t sid;
1116fcf3ce44SJohn Forte 	SERV_PARM *sp;
1117fcf3ce44SJohn Forte 
1118fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1119fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1120fcf3ce44SJohn Forte 
1121fcf3ce44SJohn Forte 	/* Check payload size */
1122fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1123fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1124291a2b48SSukumar Swaminathan 		    "FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1125291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1126fcf3ce44SJohn Forte 
1127fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1128fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1129fcf3ce44SJohn Forte 
1130fcf3ce44SJohn Forte 		return (1);
1131fcf3ce44SJohn Forte 	}
1132291a2b48SSukumar Swaminathan 
1133fcf3ce44SJohn Forte 	bp = mp->virt;
1134fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1135fcf3ce44SJohn Forte 
1136fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
1137fcf3ce44SJohn Forte 
1138fcf3ce44SJohn Forte 	hba->flag &= ~FC_FABRIC_ATTACHED;
1139fcf3ce44SJohn Forte 	hba->flag |= FC_PT_TO_PT;
1140fcf3ce44SJohn Forte 
1141fcf3ce44SJohn Forte 	/* Save E_D_TOV ticks in nanoseconds */
1142fcf3ce44SJohn Forte 	if (sp->cmn.edtovResolution) {
1143fcf3ce44SJohn Forte 		hba->fc_edtov =
1144*82527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1145fcf3ce44SJohn Forte 	} else {
1146*82527734SSukumar Swaminathan 		hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1147fcf3ce44SJohn Forte 	}
1148fcf3ce44SJohn Forte 
1149fcf3ce44SJohn Forte 	/* Save R_A_TOV ticks */
1150*82527734SSukumar Swaminathan 	hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
1151fcf3ce44SJohn Forte 
1152fcf3ce44SJohn Forte 	buffer[0] = 0;
1153fcf3ce44SJohn Forte 
1154fcf3ce44SJohn Forte 	hba->flag &= ~FC_NPIV_SUPPORTED;
1155fcf3ce44SJohn Forte 	(void) strcpy(buffer, "npiv:Disabled. P2P ");
1156*82527734SSukumar Swaminathan 
1157*82527734SSukumar Swaminathan 	port->rdid = sid;
1158fcf3ce44SJohn Forte 
1159fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1160fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1161fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
1162fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current &&
1163fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1164fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
1165fcf3ce44SJohn Forte 	} else {
1166fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
1167fcf3ce44SJohn Forte 	}
1168291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1169fcf3ce44SJohn Forte 
1170fcf3ce44SJohn Forte 	/* Clear the fabric service parameters */
1171291a2b48SSukumar Swaminathan 	bzero((void *)&port->fabric_sparam, sizeof (SERV_PARM));
1172fcf3ce44SJohn Forte 
1173fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
1174fcf3ce44SJohn Forte 
1175fcf3ce44SJohn Forte 	return (0);
1176fcf3ce44SJohn Forte 
1177*82527734SSukumar Swaminathan } /* emlxs_process_unsol_flogi() */
1178fcf3ce44SJohn Forte 
1179fcf3ce44SJohn Forte 
1180fcf3ce44SJohn Forte /* ARGSUSED */
1181fcf3ce44SJohn Forte static void
1182*82527734SSukumar Swaminathan emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1183fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1184fcf3ce44SJohn Forte {
1185fcf3ce44SJohn Forte 	uint8_t *bp;
1186fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1187fcf3ce44SJohn Forte 	IOCB *iocb;
1188fcf3ce44SJohn Forte 	uint32_t sid;
1189fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1190fcf3ce44SJohn Forte 	char buffer[64];
1191fcf3ce44SJohn Forte 
1192fcf3ce44SJohn Forte 	buffer[0] = 0;
1193fcf3ce44SJohn Forte 
1194fcf3ce44SJohn Forte 	/* Perform processing of FLOGI payload */
1195fcf3ce44SJohn Forte 	if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer)) {
1196fcf3ce44SJohn Forte 		return;
1197fcf3ce44SJohn Forte 	}
1198291a2b48SSukumar Swaminathan 
1199fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1200fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1201fcf3ce44SJohn Forte 	bp = mp->virt;
1202fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1203fcf3ce44SJohn Forte 
1204fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1205fcf3ce44SJohn Forte 
1206fcf3ce44SJohn Forte 	if (ubp == NULL) {
1207fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1208291a2b48SSukumar Swaminathan 		    "FLOGI rcvd: sid=%x. Rejecting.", sid);
1209fcf3ce44SJohn Forte 
1210fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1211fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1212fcf3ce44SJohn Forte 
1213fcf3ce44SJohn Forte 		goto drop_it;
1214fcf3ce44SJohn Forte 	}
1215291a2b48SSukumar Swaminathan 
1216fcf3ce44SJohn Forte 	/*
1217fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1218fcf3ce44SJohn Forte 	 */
1219fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1220fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1221fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_FLOGI;
1222fcf3ce44SJohn Forte 
1223fcf3ce44SJohn Forte 	/*
1224fcf3ce44SJohn Forte 	 * Setup frame header
1225fcf3ce44SJohn Forte 	 */
1226fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1227fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1228*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1229*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1230fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1231*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1232fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1233fcf3ce44SJohn Forte 
1234fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1235291a2b48SSukumar Swaminathan 	    "FLOGI: sid=%x buffer=%p token=%x %s", sid, ubp, ub_priv->token,
1236291a2b48SSukumar Swaminathan 	    buffer);
1237fcf3ce44SJohn Forte 
1238fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1239fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1240291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1241fcf3ce44SJohn Forte 
1242fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1243fcf3ce44SJohn Forte 
1244fcf3ce44SJohn Forte drop_it:
1245fcf3ce44SJohn Forte 
1246fcf3ce44SJohn Forte 	return;
1247fcf3ce44SJohn Forte 
1248*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_flogi() */
1249fcf3ce44SJohn Forte 
1250fcf3ce44SJohn Forte 
1251fcf3ce44SJohn Forte 
1252fcf3ce44SJohn Forte /* This is shared by FCT driver */
1253fcf3ce44SJohn Forte extern uint32_t
1254291a2b48SSukumar Swaminathan emlxs_process_unsol_plogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1255291a2b48SSukumar Swaminathan     uint32_t size, char *buffer)
1256fcf3ce44SJohn Forte {
1257fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1258fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1259fcf3ce44SJohn Forte 	uint8_t *bp;
1260fcf3ce44SJohn Forte 	IOCB *iocb;
1261fcf3ce44SJohn Forte 	uint32_t sid;
1262fcf3ce44SJohn Forte 	SERV_PARM *sp;
1263fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
1264291a2b48SSukumar Swaminathan 	emlxs_vvl_fmt_t vvl;
1265*82527734SSukumar Swaminathan 	int rc;
1266fcf3ce44SJohn Forte 
1267fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1268fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1269fcf3ce44SJohn Forte 
1270fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1271fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1272291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1273291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1274fcf3ce44SJohn Forte 
1275fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1276fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1277fcf3ce44SJohn Forte 
1278fcf3ce44SJohn Forte 		return (1);
1279fcf3ce44SJohn Forte 	}
1280291a2b48SSukumar Swaminathan 
1281fcf3ce44SJohn Forte 	bp = mp->virt;
1282fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1283fcf3ce44SJohn Forte 
1284291a2b48SSukumar Swaminathan 	bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t));
1285fcf3ce44SJohn Forte 
1286*82527734SSukumar Swaminathan 	if (sp->VALID_VENDOR_VERSION) {
1287fcf3ce44SJohn Forte 
1288291a2b48SSukumar Swaminathan 		bcopy((caddr_t *)&sp->vendorVersion[0],
1289291a2b48SSukumar Swaminathan 		    (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
1290*82527734SSukumar Swaminathan 		vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
1291*82527734SSukumar Swaminathan 		vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
1292291a2b48SSukumar Swaminathan 	}
1293291a2b48SSukumar Swaminathan 
1294291a2b48SSukumar Swaminathan 	if (port->flag & EMLXS_PORT_RESTRICTED) {
1295291a2b48SSukumar Swaminathan 		uint32_t reject_it = 0;
1296291a2b48SSukumar Swaminathan 
1297291a2b48SSukumar Swaminathan 		/* If remote port is the virtual port, then reject it */
1298291a2b48SSukumar Swaminathan 		if ((vvl.un0.w0.oui == 0x0000C9) && (vvl.un1.w1.vport)) {
1299291a2b48SSukumar Swaminathan 			reject_it = 1;
1300fcf3ce44SJohn Forte 		}
1301291a2b48SSukumar Swaminathan 
1302291a2b48SSukumar Swaminathan 		/* If we are a virtual port and the remote device */
1303291a2b48SSukumar Swaminathan 		/* is not a switch, then reject it */
1304*82527734SSukumar Swaminathan 		else if (port->vpi && ((sid & FABRIC_DID_MASK) !=
1305*82527734SSukumar Swaminathan 		    FABRIC_DID_MASK)) {
1306fcf3ce44SJohn Forte 			reject_it = 1;
1307fcf3ce44SJohn Forte 		}
1308291a2b48SSukumar Swaminathan 
1309fcf3ce44SJohn Forte 		if (reject_it) {
1310fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1311fcf3ce44SJohn Forte 			    "PLOGI rcvd: sid=%x. Restricted. Rejecting.",
1312fcf3ce44SJohn Forte 			    sid);
1313fcf3ce44SJohn Forte 
1314fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1315fcf3ce44SJohn Forte 			    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC,
1316fcf3ce44SJohn Forte 			    LSEXP_NOTHING_MORE);
1317fcf3ce44SJohn Forte 
1318fcf3ce44SJohn Forte 			/*
1319291a2b48SSukumar Swaminathan 			 * We still need to do reg_did and unreg_did
1320291a2b48SSukumar Swaminathan 			 * to free up rpi
1321fcf3ce44SJohn Forte 			 */
1322fcf3ce44SJohn Forte 			(void) emlxs_mb_reg_did(port, sid, sp, NULL, NULL,
1323fcf3ce44SJohn Forte 			    (IOCBQ *)1);
1324fcf3ce44SJohn Forte 
1325fcf3ce44SJohn Forte 			return (1);
1326fcf3ce44SJohn Forte 		}
1327fcf3ce44SJohn Forte 	}
1328fcf3ce44SJohn Forte 
1329fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1330fcf3ce44SJohn Forte 	if (emlxs_dhc_verify_login(port, sid, sp)) {
1331fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1332291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. FCSP disabled. Rejecting.", sid);
1333fcf3ce44SJohn Forte 
1334fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1335fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1336fcf3ce44SJohn Forte 
1337fcf3ce44SJohn Forte 		return (1);
1338fcf3ce44SJohn Forte 	}
1339291a2b48SSukumar Swaminathan 
1340fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1341fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Unsupported");
1342fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
1343fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1344fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Supported");
1345fcf3ce44SJohn Forte 	} else {
1346fcf3ce44SJohn Forte 		(void) strcat(buffer, "fcsp:Disabled");
1347fcf3ce44SJohn Forte 	}
1348291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1349fcf3ce44SJohn Forte 
1350fcf3ce44SJohn Forte 	/* Check if this was a point to point Plogi */
1351fcf3ce44SJohn Forte 	if (hba->flag & FC_PT_TO_PT) {
1352fcf3ce44SJohn Forte 		mutex_enter(&EMLXS_PORT_LOCK);
1353fcf3ce44SJohn Forte 
1354fcf3ce44SJohn Forte 		/* Save our new port ID */
1355fcf3ce44SJohn Forte 		port->did = iocb->un.elsreq.myID;
1356fcf3ce44SJohn Forte 
1357fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
1358fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
1359fcf3ce44SJohn Forte 			hba->fc_edtov =
1360*82527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1361fcf3ce44SJohn Forte 		} else {
1362*82527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1363fcf3ce44SJohn Forte 		}
1364fcf3ce44SJohn Forte 
1365fcf3ce44SJohn Forte 		/* Save R_A_TOV ticks */
1366291a2b48SSukumar Swaminathan 		hba->fc_ratov =
1367*82527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
1368fcf3ce44SJohn Forte 
1369fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
1370fcf3ce44SJohn Forte 
1371fcf3ce44SJohn Forte 		/* Update our service parms */
1372291a2b48SSukumar Swaminathan 		if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1373*82527734SSukumar Swaminathan 		    MEM_MBOX, 1))) {
1374*82527734SSukumar Swaminathan 			emlxs_mb_config_link(hba, mbox);
1375fcf3ce44SJohn Forte 
1376*82527734SSukumar Swaminathan 			rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
1377*82527734SSukumar Swaminathan 			    MBX_NOWAIT, 0);
1378*82527734SSukumar Swaminathan 			if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1379fcf3ce44SJohn Forte 				(void) emlxs_mem_put(hba, MEM_MBOX,
1380fcf3ce44SJohn Forte 				    (uint8_t *)mbox);
1381fcf3ce44SJohn Forte 			}
1382291a2b48SSukumar Swaminathan 
1383fcf3ce44SJohn Forte 		}
1384fcf3ce44SJohn Forte 	}
1385291a2b48SSukumar Swaminathan 
1386fcf3ce44SJohn Forte 	return (0);
1387fcf3ce44SJohn Forte 
1388*82527734SSukumar Swaminathan } /* emlxs_process_unsol_plogi() */
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte 
1391fcf3ce44SJohn Forte /* ARGSUSED */
1392fcf3ce44SJohn Forte static void
1393*82527734SSukumar Swaminathan emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1394fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1395fcf3ce44SJohn Forte {
1396fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1397fcf3ce44SJohn Forte 	uint8_t *bp;
1398fcf3ce44SJohn Forte 	IOCB *iocb;
1399fcf3ce44SJohn Forte 	uint32_t sid;
1400fcf3ce44SJohn Forte 	uint32_t did;
1401fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1402fcf3ce44SJohn Forte 	SERV_PARM *sp;
1403fcf3ce44SJohn Forte 	char buffer[64];
1404fcf3ce44SJohn Forte 
1405fcf3ce44SJohn Forte 	buffer[0] = 0;
1406fcf3ce44SJohn Forte 
1407fcf3ce44SJohn Forte 	/* Perform processing of PLOGI payload */
1408fcf3ce44SJohn Forte 	if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer)) {
1409fcf3ce44SJohn Forte 		return;
1410fcf3ce44SJohn Forte 	}
1411291a2b48SSukumar Swaminathan 
1412fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1413fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1414fcf3ce44SJohn Forte 	did = iocb->un.elsreq.myID;
1415fcf3ce44SJohn Forte 	bp = mp->virt;
1416fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1417fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1418fcf3ce44SJohn Forte 
1419291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1420291a2b48SSukumar Swaminathan 	emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_PLOGI_RCV,
1421291a2b48SSukumar Swaminathan 	    (HBA_WWN *)&sp->portName, (HBA_WWN *)&sp->nodeName);
1422291a2b48SSukumar Swaminathan #endif
1423291a2b48SSukumar Swaminathan 
1424fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1425fcf3ce44SJohn Forte 
1426fcf3ce44SJohn Forte 	if (ubp == NULL) {
1427fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1428291a2b48SSukumar Swaminathan 		    "PLOGI rcvd: sid=%x. Rejecting.", sid);
1429fcf3ce44SJohn Forte 
1430fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1431fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1432fcf3ce44SJohn Forte 
1433fcf3ce44SJohn Forte 		goto drop_it;
1434fcf3ce44SJohn Forte 	}
1435291a2b48SSukumar Swaminathan 
1436fcf3ce44SJohn Forte 	/*
1437fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1438fcf3ce44SJohn Forte 	 */
1439fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1440fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1441fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PLOGI;
1442fcf3ce44SJohn Forte 
1443fcf3ce44SJohn Forte 	/*
1444fcf3ce44SJohn Forte 	 * Setup frame header
1445fcf3ce44SJohn Forte 	 */
1446fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1447fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1448*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1449*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1450fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1451*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1452fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1453fcf3ce44SJohn Forte 
1454fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1455291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x buffer=%p token=%x %s", sid, did, ubp,
1456291a2b48SSukumar Swaminathan 	    ub_priv->token, buffer);
1457fcf3ce44SJohn Forte 
1458fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1459fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1460291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1461fcf3ce44SJohn Forte 
1462fcf3ce44SJohn Forte 	/* Create a new node and defer callback */
1463fcf3ce44SJohn Forte 	if (emlxs_mb_reg_did(port, sid, sp, NULL, ubp, NULL) == 0) {
1464fcf3ce44SJohn Forte 		/*
1465fcf3ce44SJohn Forte 		 * Defer completion of this pkt until login is complete
1466fcf3ce44SJohn Forte 		 */
1467fcf3ce44SJohn Forte 		goto drop_it;
1468fcf3ce44SJohn Forte 	}
1469291a2b48SSukumar Swaminathan 
1470fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1471fcf3ce44SJohn Forte 
1472fcf3ce44SJohn Forte drop_it:
1473fcf3ce44SJohn Forte 
1474fcf3ce44SJohn Forte 	return;
1475fcf3ce44SJohn Forte 
1476*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_plogi() */
1477fcf3ce44SJohn Forte 
1478fcf3ce44SJohn Forte 
1479fcf3ce44SJohn Forte /* ARGSUSED */
1480fcf3ce44SJohn Forte static void
1481*82527734SSukumar Swaminathan emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1482fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1483fcf3ce44SJohn Forte {
1484*82527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
1485*82527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1486fcf3ce44SJohn Forte 	IOCB *iocb;
1487fcf3ce44SJohn Forte 	uint32_t sid;
1488fcf3ce44SJohn Forte 	NODELIST *ndlp;
1489fcf3ce44SJohn Forte 	PRLI *npr;
1490fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1491fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1492fcf3ce44SJohn Forte 
1493fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1494fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1495fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1496fcf3ce44SJohn Forte 
1497fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1498fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1499291a2b48SSukumar Swaminathan 		    "PRLI: sid=%x: Node not found. Rejecting.", sid);
1500fcf3ce44SJohn Forte 
1501fcf3ce44SJohn Forte 		/* Auto reply to PRLI's */
1502fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1503fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1504fcf3ce44SJohn Forte 
1505fcf3ce44SJohn Forte 		goto drop_it;
1506fcf3ce44SJohn Forte 	}
1507291a2b48SSukumar Swaminathan 
1508fcf3ce44SJohn Forte 	/* If node exists then save FCP2 support */
1509fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)mp->virt + sizeof (uint32_t));
1510fcf3ce44SJohn Forte 
1511fcf3ce44SJohn Forte 	/* Check for FCP2 support */
1512fcf3ce44SJohn Forte 	if ((npr->prliType == PRLI_FCP_TYPE) && npr->targetFunc) {
1513fcf3ce44SJohn Forte 		/* Check for target */
1514fcf3ce44SJohn Forte 		if (npr->targetFunc) {
1515fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
1516fcf3ce44SJohn Forte 		} else {
1517fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
1518fcf3ce44SJohn Forte 		}
1519fcf3ce44SJohn Forte 
1520fcf3ce44SJohn Forte 		/* Check for initiator */
1521fcf3ce44SJohn Forte 		if (npr->initiatorFunc) {
1522fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
1523fcf3ce44SJohn Forte 		} else {
1524fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
1525fcf3ce44SJohn Forte 		}
1526fcf3ce44SJohn Forte 
1527fcf3ce44SJohn Forte 		/* Check for FCP2 target support */
1528fcf3ce44SJohn Forte 		if (npr->targetFunc && npr->Retry) {
1529fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1530fcf3ce44SJohn Forte 		} else {
1531fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1532fcf3ce44SJohn Forte 		}
1533fcf3ce44SJohn Forte 	}
1534fcf3ce44SJohn Forte 
1535*82527734SSukumar Swaminathan #ifdef ULP_PATCH3
1536*82527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH3) {
1537*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1538*82527734SSukumar Swaminathan 		    "PRLI: sid=%x. Accepting.", sid);
1539fcf3ce44SJohn Forte 
1540*82527734SSukumar Swaminathan 		/* Auto reply to PRLI's */
1541*82527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
1542*82527734SSukumar Swaminathan 		    ELS_CMD_PRLI, 0, 0);
1543*82527734SSukumar Swaminathan 		goto drop_it;
1544*82527734SSukumar Swaminathan 	}
1545*82527734SSukumar Swaminathan #endif /* ULP_PATCH3 */
1546fcf3ce44SJohn Forte 
1547fcf3ce44SJohn Forte 	/* Tell ULP about it */
1548fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1549fcf3ce44SJohn Forte 
1550fcf3ce44SJohn Forte 	if (ubp == NULL) {
1551fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1552291a2b48SSukumar Swaminathan 		    "PRLI rcvd: sid=%x. Rejecting.", sid);
1553fcf3ce44SJohn Forte 
1554fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1555fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1556fcf3ce44SJohn Forte 
1557fcf3ce44SJohn Forte 		goto drop_it;
1558fcf3ce44SJohn Forte 	}
1559291a2b48SSukumar Swaminathan 
1560fcf3ce44SJohn Forte 	/*
1561fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1562fcf3ce44SJohn Forte 	 */
1563fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1564fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1565fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLI;
1566fcf3ce44SJohn Forte 
1567fcf3ce44SJohn Forte 	/*
1568fcf3ce44SJohn Forte 	 * Setup frame header
1569fcf3ce44SJohn Forte 	 */
1570fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1571fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1572*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1573*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1574fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1575*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1576fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1577fcf3ce44SJohn Forte 
1578fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1579291a2b48SSukumar Swaminathan 	    "PRLI: sid=%x buffer=%p token=%x info=%02x", sid, ubp,
1580291a2b48SSukumar Swaminathan 	    ub_priv->token, ndlp->nlp_fcp_info);
1581fcf3ce44SJohn Forte 
1582fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1583fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1584291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1585fcf3ce44SJohn Forte 
1586fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1587fcf3ce44SJohn Forte 
1588fcf3ce44SJohn Forte drop_it:
1589fcf3ce44SJohn Forte 
1590fcf3ce44SJohn Forte 	return;
1591fcf3ce44SJohn Forte 
1592*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_prli() */
1593fcf3ce44SJohn Forte 
1594fcf3ce44SJohn Forte 
1595fcf3ce44SJohn Forte /* ARGSUSED */
1596fcf3ce44SJohn Forte static void
1597*82527734SSukumar Swaminathan emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1598fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1599fcf3ce44SJohn Forte {
1600fcf3ce44SJohn Forte 	IOCB *iocb;
1601fcf3ce44SJohn Forte 	uint32_t sid;
1602fcf3ce44SJohn Forte 	NODELIST *ndlp;
1603fcf3ce44SJohn Forte 
1604fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1605fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1606fcf3ce44SJohn Forte 
1607fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1608fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1609fcf3ce44SJohn Forte 
1610fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1611fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1612291a2b48SSukumar Swaminathan 		    "AUTH: sid=%x: Node not found. Rejecting.", sid);
1613fcf3ce44SJohn Forte 
1614fcf3ce44SJohn Forte 		/* Auto reply to AUTH_ELS's */
1615fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1616fcf3ce44SJohn Forte 		    ELS_CMD_AUTH, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1617fcf3ce44SJohn Forte 
1618fcf3ce44SJohn Forte 		goto drop_it;
1619fcf3ce44SJohn Forte 	}
1620291a2b48SSukumar Swaminathan 
1621291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "AUTH: sid=%x", sid);
1622fcf3ce44SJohn Forte 
1623*82527734SSukumar Swaminathan 	(void) emlxs_dhchap_state_machine(port, cp, iocbq, mp, ndlp,
1624fcf3ce44SJohn Forte 	    NODE_EVENT_RCV_AUTH_MSG);
1625fcf3ce44SJohn Forte #else
1626fcf3ce44SJohn Forte 
1627fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1628291a2b48SSukumar Swaminathan 	    "AUTH: sid=%x: Rejecting.", sid);
1629fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, ELS_CMD_AUTH,
1630fcf3ce44SJohn Forte 	    LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1631fcf3ce44SJohn Forte 
1632291a2b48SSukumar Swaminathan #endif /* DHCAHP_SUPPORT */
1633fcf3ce44SJohn Forte 
1634fcf3ce44SJohn Forte drop_it:
1635fcf3ce44SJohn Forte 
1636fcf3ce44SJohn Forte 	return;
1637fcf3ce44SJohn Forte 
1638*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_auth() */
1639fcf3ce44SJohn Forte 
1640fcf3ce44SJohn Forte 
1641fcf3ce44SJohn Forte /* ARGSUSED */
1642fcf3ce44SJohn Forte static void
1643*82527734SSukumar Swaminathan emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1644fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1645fcf3ce44SJohn Forte {
1646291a2b48SSukumar Swaminathan 	IOCB		*iocb;
1647291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1648291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
1649291a2b48SSukumar Swaminathan #endif
1650291a2b48SSukumar Swaminathan 	uint32_t	sid;
1651fcf3ce44SJohn Forte 
1652fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1653fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1654fcf3ce44SJohn Forte 
1655291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1656291a2b48SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, sid);
1657291a2b48SSukumar Swaminathan 
1658291a2b48SSukumar Swaminathan 	if (ndlp) {
1659291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_ADISC_RCV,
1660291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1661291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_nodename);
1662291a2b48SSukumar Swaminathan 	}
1663291a2b48SSukumar Swaminathan #endif
1664291a2b48SSukumar Swaminathan 
1665fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1666291a2b48SSukumar Swaminathan 	    "ADISC: sid=%x: Accepting.", sid);
1667fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_ADISC, 0, 0);
1668fcf3ce44SJohn Forte 
1669fcf3ce44SJohn Forte 	return;
1670fcf3ce44SJohn Forte 
1671*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_adisc() */
1672fcf3ce44SJohn Forte 
1673fcf3ce44SJohn Forte 
1674fcf3ce44SJohn Forte /* ARGSUSED */
1675fcf3ce44SJohn Forte static void
1676*82527734SSukumar Swaminathan emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1677fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1678fcf3ce44SJohn Forte {
1679*82527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
1680*82527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1681fcf3ce44SJohn Forte 	IOCB *iocb;
1682fcf3ce44SJohn Forte 	uint32_t sid;
1683fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1684fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1685fcf3ce44SJohn Forte 	NODELIST *ndlp;
1686fcf3ce44SJohn Forte 
1687fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1688fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1689fcf3ce44SJohn Forte 
1690fcf3ce44SJohn Forte 	/* Get the node */
1691fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1692fcf3ce44SJohn Forte 
1693291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1694291a2b48SSukumar Swaminathan 	if (ndlp) {
1695291a2b48SSukumar Swaminathan 		emlxs_log_sd_prlo_event(port, (HBA_WWN *)&ndlp->nlp_portname);
1696291a2b48SSukumar Swaminathan 	}
1697291a2b48SSukumar Swaminathan #endif
1698291a2b48SSukumar Swaminathan 
1699291a2b48SSukumar Swaminathan #ifdef ULP_PATCH4
1700*82527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH4) {
1701291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
1702*82527734SSukumar Swaminathan 		if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
1703*82527734SSukumar Swaminathan 			/* Check if this is a SCSI target */
1704*82527734SSukumar Swaminathan 			if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
1705*82527734SSukumar Swaminathan 				/* This is a SCSI target */
1706*82527734SSukumar Swaminathan 
1707*82527734SSukumar Swaminathan 				/* If only one node is present, then we can */
1708*82527734SSukumar Swaminathan 				/* conclude that we are direct attached */
1709*82527734SSukumar Swaminathan 				/* to a target */
1710*82527734SSukumar Swaminathan 				if (port->node_count == 1) {
1711*82527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
1712*82527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
1713*82527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
1714*82527734SSukumar Swaminathan 					    "reseting link.",
1715*82527734SSukumar Swaminathan 					    sid);
1716291a2b48SSukumar Swaminathan 
1717*82527734SSukumar Swaminathan 					/* Send Acc */
1718*82527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
1719*82527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1720fcf3ce44SJohn Forte 
1721*82527734SSukumar Swaminathan 					/* Spawn a thread to reset the link */
1722*82527734SSukumar Swaminathan 					emlxs_thread_spawn(hba,
1723*82527734SSukumar Swaminathan 					    emlxs_reset_link_thread,
1724*82527734SSukumar Swaminathan 					    NULL, NULL);
1725fcf3ce44SJohn Forte 
1726*82527734SSukumar Swaminathan 					goto drop_it;
1727fcf3ce44SJohn Forte 
1728*82527734SSukumar Swaminathan 				}
1729*82527734SSukumar Swaminathan 				/* Check if fabric is present */
1730*82527734SSukumar Swaminathan 				else if (hba->flag & FC_FABRIC_ATTACHED) {
1731*82527734SSukumar Swaminathan 					/* Auto reply to PRLO */
1732*82527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
1733*82527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
1734*82527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
1735*82527734SSukumar Swaminathan 					    "generating RSCN.",
1736*82527734SSukumar Swaminathan 					    sid);
1737fcf3ce44SJohn Forte 
1738*82527734SSukumar Swaminathan 					/* Send Acc */
1739*82527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
1740*82527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1741fcf3ce44SJohn Forte 
1742*82527734SSukumar Swaminathan 					/* Generate an RSCN to wakeup ULP */
1743*82527734SSukumar Swaminathan 					(void) emlxs_generate_rscn(port, sid);
1744fcf3ce44SJohn Forte 
1745*82527734SSukumar Swaminathan 					goto drop_it;
1746*82527734SSukumar Swaminathan 				}
1747*82527734SSukumar Swaminathan 			}
1748fcf3ce44SJohn Forte 		}
1749291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1750fcf3ce44SJohn Forte 
1751*82527734SSukumar Swaminathan 		/* Auto reply to PRLO */
1752*82527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1753*82527734SSukumar Swaminathan 		    "PRLO: sid=%x. Accepting.", sid);
1754fcf3ce44SJohn Forte 
1755*82527734SSukumar Swaminathan 		/* Send Acc */
1756*82527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
1757*82527734SSukumar Swaminathan 		    ELS_CMD_PRLO, 0, 0);
1758fcf3ce44SJohn Forte 
1759*82527734SSukumar Swaminathan 		goto drop_it;
1760*82527734SSukumar Swaminathan 	}
1761*82527734SSukumar Swaminathan #endif /* ULP_PATCH4 */
1762fcf3ce44SJohn Forte 
1763fcf3ce44SJohn Forte 	/* Tell ULP about it */
1764fcf3ce44SJohn Forte 
1765fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1766fcf3ce44SJohn Forte 
1767fcf3ce44SJohn Forte 	if (ubp == NULL) {
1768fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1769291a2b48SSukumar Swaminathan 		    "PRLO recvd: sid=%x. Rejecting.", sid);
1770fcf3ce44SJohn Forte 
1771fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1772fcf3ce44SJohn Forte 		    ELS_CMD_PRLO, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1773fcf3ce44SJohn Forte 
1774fcf3ce44SJohn Forte 		goto drop_it;
1775fcf3ce44SJohn Forte 	}
1776291a2b48SSukumar Swaminathan 
1777fcf3ce44SJohn Forte 	/*
1778fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1779fcf3ce44SJohn Forte 	 */
1780fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1781fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1782fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLO;
1783fcf3ce44SJohn Forte 
1784fcf3ce44SJohn Forte 	/*
1785fcf3ce44SJohn Forte 	 * Setup frame header
1786fcf3ce44SJohn Forte 	 */
1787fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1788fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1789*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1790*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1791fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1792*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1793fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1794fcf3ce44SJohn Forte 
1795fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1796291a2b48SSukumar Swaminathan 	    "PRLO: sid=%x buffeiocbr=%p token=%x.", sid, ubp, ub_priv->token);
1797fcf3ce44SJohn Forte 
1798fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1799fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1800291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1801fcf3ce44SJohn Forte 
1802fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1803fcf3ce44SJohn Forte 
1804fcf3ce44SJohn Forte drop_it:
1805fcf3ce44SJohn Forte 
1806fcf3ce44SJohn Forte 	return;
1807fcf3ce44SJohn Forte 
1808*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_prlo() */
1809fcf3ce44SJohn Forte 
1810fcf3ce44SJohn Forte 
1811fcf3ce44SJohn Forte /* ARGSUSED */
1812fcf3ce44SJohn Forte static void
1813*82527734SSukumar Swaminathan emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1814fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1815fcf3ce44SJohn Forte {
1816fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1817*82527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1818fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1819fcf3ce44SJohn Forte 	IOCB *iocb;
1820fcf3ce44SJohn Forte 	uint32_t sid;
1821fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1822fcf3ce44SJohn Forte 	uint32_t reply_sent = 0;
1823fcf3ce44SJohn Forte 	NODELIST *ndlp;
1824fcf3ce44SJohn Forte 
1825fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1826fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1827fcf3ce44SJohn Forte 
1828fcf3ce44SJohn Forte 	ndlp = emlxs_node_find_did(port, sid);
1829fcf3ce44SJohn Forte 
1830291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1831291a2b48SSukumar Swaminathan 	if (ndlp) {
1832291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port,  SD_ELS_SUBCATEGORY_LOGO_RCV,
1833291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1834291a2b48SSukumar Swaminathan 		    (HBA_WWN *)((uint32_t *)mp->virt + 2));
1835291a2b48SSukumar Swaminathan 	}
1836291a2b48SSukumar Swaminathan #endif
1837291a2b48SSukumar Swaminathan 
1838291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
1839*82527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
1840*82527734SSukumar Swaminathan 		/* Check if this is a SCSI target */
1841*82527734SSukumar Swaminathan 		if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
1842*82527734SSukumar Swaminathan 			/* This is a SCSI target */
1843291a2b48SSukumar Swaminathan 
1844*82527734SSukumar Swaminathan 			/* If only one node is present, then we can */
1845*82527734SSukumar Swaminathan 			/* conclude that we are direct attached to a target */
1846*82527734SSukumar Swaminathan 			if (port->node_count == 1) {
1847*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1848*82527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and "\
1849*82527734SSukumar Swaminathan 				    "reseting link.", sid);
1850fcf3ce44SJohn Forte 
1851*82527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq,
1852*82527734SSukumar Swaminathan 				    ELS_CMD_ACC, ELS_CMD_LOGO, 0, 0);
1853fcf3ce44SJohn Forte 
1854*82527734SSukumar Swaminathan 				/* Spawn a thread to reset the link */
1855*82527734SSukumar Swaminathan 				emlxs_thread_spawn(hba, emlxs_reset_link_thread,
1856*82527734SSukumar Swaminathan 				    NULL, NULL);
1857fcf3ce44SJohn Forte 
1858fcf3ce44SJohn Forte 				goto drop_it;
1859fcf3ce44SJohn Forte 			}
1860*82527734SSukumar Swaminathan 			/* Check if fabric node is present */
1861*82527734SSukumar Swaminathan 			else if (hba->flag & FC_FABRIC_ATTACHED) {
1862*82527734SSukumar Swaminathan 				/* Send reply ourselves */
1863*82527734SSukumar Swaminathan 				/* We will block all attempts */
1864*82527734SSukumar Swaminathan 				/* for ULP to reply to a LOGO */
1865*82527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1866*82527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and " \
1867*82527734SSukumar Swaminathan 				    "generating RSCN.", sid);
1868*82527734SSukumar Swaminathan 
1869*82527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
1870*82527734SSukumar Swaminathan 				    ELS_CMD_LOGO, 0, 0);
1871*82527734SSukumar Swaminathan 
1872*82527734SSukumar Swaminathan 				/* Generate an RSCN to wakeup ULP */
1873*82527734SSukumar Swaminathan 				if (emlxs_generate_rscn(port, sid)
1874*82527734SSukumar Swaminathan 				    == FC_SUCCESS) {
1875*82527734SSukumar Swaminathan 					goto drop_it;
1876*82527734SSukumar Swaminathan 				}
1877291a2b48SSukumar Swaminathan 
1878*82527734SSukumar Swaminathan 				reply_sent = 1;
1879*82527734SSukumar Swaminathan 			}
1880fcf3ce44SJohn Forte 		}
1881291a2b48SSukumar Swaminathan 	}
1882291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1883fcf3ce44SJohn Forte 
1884fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 1);
1885fcf3ce44SJohn Forte 
1886fcf3ce44SJohn Forte 	if (ubp == NULL) {
1887fcf3ce44SJohn Forte 		if (!reply_sent) {
1888fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1889291a2b48SSukumar Swaminathan 			    "LOGO rcvd: sid=%x. Rejecting.", sid);
1890fcf3ce44SJohn Forte 
1891fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1892fcf3ce44SJohn Forte 			    ELS_CMD_LOGO, LSRJT_LOGICAL_BSY,
1893fcf3ce44SJohn Forte 			    LSEXP_OUT_OF_RESOURCE);
1894fcf3ce44SJohn Forte 		}
1895291a2b48SSukumar Swaminathan 
1896fcf3ce44SJohn Forte 		goto drop_it;
1897fcf3ce44SJohn Forte 
1898fcf3ce44SJohn Forte 	}
1899291a2b48SSukumar Swaminathan 
1900fcf3ce44SJohn Forte 	/* Setup unsolicited buffer and pass it up */
1901fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1902fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1903fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_LOGO;
1904fcf3ce44SJohn Forte 
1905fcf3ce44SJohn Forte 	/* Setup frame header */
1906fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1907fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
1908*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
1909*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1910fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
1911*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1912fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1913fcf3ce44SJohn Forte 
1914fcf3ce44SJohn Forte #ifdef ULP_PATCH2
1915*82527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH2) {
1916*82527734SSukumar Swaminathan 		if (!reply_sent) {
1917*82527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1918*82527734SSukumar Swaminathan 			    "LOGO: sid=%x buffer=%p token=%x. Accepting.",
1919*82527734SSukumar Swaminathan 			    sid, ubp, ub_priv->token);
1920fcf3ce44SJohn Forte 
1921*82527734SSukumar Swaminathan 			ub_priv->flags |= EMLXS_UB_REPLY;
1922fcf3ce44SJohn Forte 
1923*82527734SSukumar Swaminathan 			/* Send Acc */
1924*82527734SSukumar Swaminathan 			/* Send reply ourselves because ULP */
1925*82527734SSukumar Swaminathan 			/* doesn't always reply to these */
1926*82527734SSukumar Swaminathan 			/* We ll block attempts for ULP to reply to a LOGO */
1927*82527734SSukumar Swaminathan 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
1928*82527734SSukumar Swaminathan 			    ELS_CMD_LOGO, 0, 0);
1929*82527734SSukumar Swaminathan 			reply_sent = 1;
1930*82527734SSukumar Swaminathan 		}
1931fcf3ce44SJohn Forte 	}
1932*82527734SSukumar Swaminathan #endif /* ULP_PATCH2 */
1933fcf3ce44SJohn Forte 
1934fcf3ce44SJohn Forte 	if (!reply_sent) {
1935fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1936291a2b48SSukumar Swaminathan 		    "LOGO: sid=%x buffer=%p token=%x.", sid, ubp,
1937291a2b48SSukumar Swaminathan 		    ub_priv->token);
1938fcf3ce44SJohn Forte 	}
1939fcf3ce44SJohn Forte 
1940fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1941fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1942291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1943fcf3ce44SJohn Forte 
1944fcf3ce44SJohn Forte 	/* Clear the RPI */
1945*82527734SSukumar Swaminathan 	if ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) {
1946fcf3ce44SJohn Forte 		if (emlxs_mb_unreg_did(port, sid, NULL, ubp, NULL) == 0) {
1947fcf3ce44SJohn Forte 			/*
1948291a2b48SSukumar Swaminathan 			 * Deferred completion of this ubp
1949291a2b48SSukumar Swaminathan 			 * until unreg login is complete
1950fcf3ce44SJohn Forte 			 */
1951fcf3ce44SJohn Forte 
1952fcf3ce44SJohn Forte 			return;
1953fcf3ce44SJohn Forte 		}
1954fcf3ce44SJohn Forte 	}
1955291a2b48SSukumar Swaminathan 
1956fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1957fcf3ce44SJohn Forte 
1958fcf3ce44SJohn Forte drop_it:
1959fcf3ce44SJohn Forte 
1960fcf3ce44SJohn Forte 	return;
1961fcf3ce44SJohn Forte 
1962*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_logo() */
1963291a2b48SSukumar Swaminathan 
1964fcf3ce44SJohn Forte 
1965fcf3ce44SJohn Forte 
1966fcf3ce44SJohn Forte /* ARGSUSED */
1967fcf3ce44SJohn Forte static void
1968*82527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1969fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1970fcf3ce44SJohn Forte {
1971fcf3ce44SJohn Forte 	uint8_t *bp;
1972fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1973fcf3ce44SJohn Forte 	IOCB *iocb;
1974fcf3ce44SJohn Forte 	uint32_t *lp;
1975fcf3ce44SJohn Forte 	uint32_t cmd;
1976fcf3ce44SJohn Forte 	uint32_t sid;
1977fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1978fcf3ce44SJohn Forte 
1979fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1980fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1981fcf3ce44SJohn Forte 
1982fcf3ce44SJohn Forte 	bp = mp->virt;
1983fcf3ce44SJohn Forte 	lp = (uint32_t *)bp;
1984fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
1985fcf3ce44SJohn Forte 
1986fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size, FC_ELS_DATA, 0);
1987fcf3ce44SJohn Forte 
1988fcf3ce44SJohn Forte 	if (ubp == NULL) {
1989fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1990291a2b48SSukumar Swaminathan 		    "%s rcvd: sid=%x: Rejecting.", emlxs_elscmd_xlate(cmd),
1991291a2b48SSukumar Swaminathan 		    sid);
1992fcf3ce44SJohn Forte 
1993fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd,
1994fcf3ce44SJohn Forte 		    LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1995fcf3ce44SJohn Forte 
1996fcf3ce44SJohn Forte 		goto drop_it;
1997fcf3ce44SJohn Forte 	}
1998291a2b48SSukumar Swaminathan 
1999fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
2000fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
2001fcf3ce44SJohn Forte 	ub_priv->cmd = cmd;
2002fcf3ce44SJohn Forte 
2003fcf3ce44SJohn Forte 	/* Setup frame header */
2004fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
2005fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
2006*82527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2007*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2008fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
2009*82527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
2010fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2011fcf3ce44SJohn Forte 
2012fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2013291a2b48SSukumar Swaminathan 	    "%s: sid=%x buffer=%p token=%x.", emlxs_elscmd_xlate(cmd), sid,
2014291a2b48SSukumar Swaminathan 	    ubp, ub_priv->token);
2015fcf3ce44SJohn Forte 
2016fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2017fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2018291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2019fcf3ce44SJohn Forte 
2020fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2021fcf3ce44SJohn Forte 
2022fcf3ce44SJohn Forte drop_it:
2023fcf3ce44SJohn Forte 
2024fcf3ce44SJohn Forte 	return;
2025fcf3ce44SJohn Forte 
2026*82527734SSukumar Swaminathan } /* emlxs_handle_unsol_gen_cmd() */
2027fcf3ce44SJohn Forte 
2028fcf3ce44SJohn Forte 
2029fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2030fcf3ce44SJohn Forte /* ARGSUSED */
2031fcf3ce44SJohn Forte static void
2032291a2b48SSukumar Swaminathan emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2033291a2b48SSukumar Swaminathan     uint32_t flag)
2034fcf3ce44SJohn Forte {
2035*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2036fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2037fcf3ce44SJohn Forte 	IOCB *iocb;
2038fcf3ce44SJohn Forte 	uint32_t did;
2039fcf3ce44SJohn Forte 	NODELIST *ndlp;
2040fcf3ce44SJohn Forte 	uint32_t ucmd;
2041fcf3ce44SJohn Forte 	uint32_t cmd;
2042fcf3ce44SJohn Forte 	uint32_t *lp;
2043fcf3ce44SJohn Forte 
2044fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2045fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2046*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2047fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2048fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2049fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2050fcf3ce44SJohn Forte 
2051fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2052291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
2053*82527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2054fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2055fcf3ce44SJohn Forte 
2056fcf3ce44SJohn Forte 	switch (ucmd) {
2057fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2058fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
2059fcf3ce44SJohn Forte 
2060fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_did(port, did);
2061fcf3ce44SJohn Forte 
2062fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2063fcf3ce44SJohn Forte 			/* Open the node again */
2064*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2065*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2066fcf3ce44SJohn Forte 		}
2067291a2b48SSukumar Swaminathan 
2068fcf3ce44SJohn Forte 		break;
2069fcf3ce44SJohn Forte 
2070fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2071fcf3ce44SJohn Forte 
2072fcf3ce44SJohn Forte 		ndlp = emlxs_node_find_did(port, did);
2073fcf3ce44SJohn Forte 
2074fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2075fcf3ce44SJohn Forte 			/* Open the node again */
2076*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2077fcf3ce44SJohn Forte 		}
2078291a2b48SSukumar Swaminathan 
2079fcf3ce44SJohn Forte 		break;
2080fcf3ce44SJohn Forte 	}
2081fcf3ce44SJohn Forte 
2082*82527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2083fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2084fcf3ce44SJohn Forte 
2085fcf3ce44SJohn Forte 	return;
2086fcf3ce44SJohn Forte 
2087*82527734SSukumar Swaminathan } /* emlxs_handle_acc() */
2088fcf3ce44SJohn Forte 
2089fcf3ce44SJohn Forte 
2090fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2091fcf3ce44SJohn Forte /* ARGSUSED */
2092fcf3ce44SJohn Forte static void
2093291a2b48SSukumar Swaminathan emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2094291a2b48SSukumar Swaminathan     uint32_t flag)
2095fcf3ce44SJohn Forte {
2096*82527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2097291a2b48SSukumar Swaminathan 	fc_packet_t	*pkt;
2098291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
2099291a2b48SSukumar Swaminathan 	IOCB		*iocb;
2100291a2b48SSukumar Swaminathan 	uint32_t	did;
2101291a2b48SSukumar Swaminathan 	uint32_t	ucmd;
2102291a2b48SSukumar Swaminathan 	uint32_t	cmd;
2103291a2b48SSukumar Swaminathan 	uint32_t	*lp;
2104fcf3ce44SJohn Forte 
2105fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2106fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2107*82527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2108fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2109fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2110fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2111fcf3ce44SJohn Forte 
2112291a2b48SSukumar Swaminathan 	ndlp = emlxs_node_find_did(port, did);
2113291a2b48SSukumar Swaminathan 
2114fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2115291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
2116*82527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2117fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2118fcf3ce44SJohn Forte 
2119fcf3ce44SJohn Forte 	switch (ucmd) {
2120fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2121fcf3ce44SJohn Forte 
2122fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2123fcf3ce44SJohn Forte 			/* Open the node again */
2124*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2125*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2126fcf3ce44SJohn Forte 		}
2127291a2b48SSukumar Swaminathan 
2128fcf3ce44SJohn Forte 		break;
2129fcf3ce44SJohn Forte 
2130fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2131fcf3ce44SJohn Forte 
2132fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2133fcf3ce44SJohn Forte 			/* Open the node again */
2134*82527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2135fcf3ce44SJohn Forte 		}
2136291a2b48SSukumar Swaminathan 
2137fcf3ce44SJohn Forte 		break;
2138fcf3ce44SJohn Forte 	}
2139fcf3ce44SJohn Forte 
2140*82527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2141fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2142fcf3ce44SJohn Forte 
2143fcf3ce44SJohn Forte 	return;
2144fcf3ce44SJohn Forte 
2145*82527734SSukumar Swaminathan } /* emlxs_handle_reject() */
2146fcf3ce44SJohn Forte 
2147fcf3ce44SJohn Forte 
2148fcf3ce44SJohn Forte /* ARGSUSED */
2149fcf3ce44SJohn Forte extern int32_t
2150fcf3ce44SJohn Forte emlxs_els_reply(emlxs_port_t *port, IOCBQ *iocbq, uint32_t type,
2151fcf3ce44SJohn Forte     uint32_t type2, uint32_t reason, uint32_t explain)
2152fcf3ce44SJohn Forte {
2153fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
2154fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
2155fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2156fcf3ce44SJohn Forte 	ELS_PKT *els;
2157fcf3ce44SJohn Forte 	uint32_t rval;
2158fcf3ce44SJohn Forte 	IOCB *iocb;
2159fcf3ce44SJohn Forte 
2160fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2161fcf3ce44SJohn Forte 
2162fcf3ce44SJohn Forte 	switch (type) {
2163fcf3ce44SJohn Forte 	case ELS_CMD_ACC:	/* Accept Response */
2164fcf3ce44SJohn Forte 
2165fcf3ce44SJohn Forte 		/* Allocate the pkt */
2166fcf3ce44SJohn Forte 		switch (type2) {
2167fcf3ce44SJohn Forte 		case ELS_CMD_FLOGI:
2168fcf3ce44SJohn Forte 			if (!(pkt = emlxs_pkt_alloc(port,
2169291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (SERV_PARM), 0,
2170291a2b48SSukumar Swaminathan 			    0, KM_NOSLEEP))) {
2171fcf3ce44SJohn Forte 				return (1);
2172fcf3ce44SJohn Forte 			}
2173fcf3ce44SJohn Forte 			break;
2174fcf3ce44SJohn Forte 
2175fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2176fcf3ce44SJohn Forte 			if (!(pkt = emlxs_pkt_alloc(port,
2177291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (ADISC), 0, 0,
2178291a2b48SSukumar Swaminathan 			    KM_NOSLEEP))) {
2179fcf3ce44SJohn Forte 				return (1);
2180fcf3ce44SJohn Forte 			}
2181fcf3ce44SJohn Forte 			break;
2182fcf3ce44SJohn Forte 
2183fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2184fcf3ce44SJohn Forte 			if (!(pkt = emlxs_pkt_alloc(port,
2185291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLI), 0, 0,
2186291a2b48SSukumar Swaminathan 			    KM_NOSLEEP))) {
2187fcf3ce44SJohn Forte 				return (1);
2188fcf3ce44SJohn Forte 			}
2189fcf3ce44SJohn Forte 			break;
2190fcf3ce44SJohn Forte 
2191fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2192fcf3ce44SJohn Forte 			if (!(pkt = emlxs_pkt_alloc(port,
2193291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLO), 0, 0,
2194291a2b48SSukumar Swaminathan 			    KM_NOSLEEP))) {
2195fcf3ce44SJohn Forte 				return (1);
2196fcf3ce44SJohn Forte 			}
2197fcf3ce44SJohn Forte 			break;
2198fcf3ce44SJohn Forte 
2199fcf3ce44SJohn Forte 		case ELS_CMD_AUTH:
2200fcf3ce44SJohn Forte 		default:
2201fcf3ce44SJohn Forte 
2202291a2b48SSukumar Swaminathan 			if (!(pkt = emlxs_pkt_alloc(port, sizeof (uint32_t),
2203291a2b48SSukumar Swaminathan 			    0, 0, KM_NOSLEEP))) {
2204fcf3ce44SJohn Forte 				return (1);
2205fcf3ce44SJohn Forte 			}
2206fcf3ce44SJohn Forte 		}
2207fcf3ce44SJohn Forte 
2208fcf3ce44SJohn Forte 		/* Common initialization */
2209fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2210fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2211fcf3ce44SJohn Forte 
2212*82527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2213fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2214fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2215fcf3ce44SJohn Forte 		}
2216291a2b48SSukumar Swaminathan 
2217fcf3ce44SJohn Forte 		/* Build the fc header */
2218fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
2219*82527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2220291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2221291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2222*82527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2223fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2224291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2225291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2226fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2227fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2228fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2229fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
2230*82527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2231fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2232fcf3ce44SJohn Forte 
2233fcf3ce44SJohn Forte 		/*
2234291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2235291a2b48SSukumar Swaminathan 		 * "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2),
2236fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2237fcf3ce44SJohn Forte 		 */
2238fcf3ce44SJohn Forte 
2239fcf3ce44SJohn Forte 		/* Build the command */
2240291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2241fcf3ce44SJohn Forte 		els->elsCode = 0x02;
2242fcf3ce44SJohn Forte 
2243fcf3ce44SJohn Forte 		/* Build the payload */
2244fcf3ce44SJohn Forte 		switch (type2) {
2245fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2246fcf3ce44SJohn Forte 
2247fcf3ce44SJohn Forte 			els->un.adisc.hardAL_PA =
2248fcf3ce44SJohn Forte 			    (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2249fcf3ce44SJohn Forte 			bcopy(&port->wwnn, &els->un.adisc.nodeName,
2250fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
2251fcf3ce44SJohn Forte 			bcopy(&port->wwpn, &els->un.adisc.portName,
2252fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
2253*82527734SSukumar Swaminathan 			els->un.adisc.DID = LE_SWAP24_LO(port->did);
2254fcf3ce44SJohn Forte 
2255fcf3ce44SJohn Forte 			break;
2256fcf3ce44SJohn Forte 
2257fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2258fcf3ce44SJohn Forte 
2259fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2260fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2261fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2262fcf3ce44SJohn Forte 
2263fcf3ce44SJohn Forte 			els->un.prli.prliType = PRLI_FCP_TYPE;
2264fcf3ce44SJohn Forte 			els->un.prli.estabImagePair = 1;
2265fcf3ce44SJohn Forte 			els->un.prli.acceptRspCode = PRLI_REQ_EXECUTED;
2266fcf3ce44SJohn Forte 
2267fcf3ce44SJohn Forte 			if (port->ini_mode) {
2268fcf3ce44SJohn Forte 				els->un.prli.initiatorFunc = 1;
2269fcf3ce44SJohn Forte 			}
2270291a2b48SSukumar Swaminathan 
2271fcf3ce44SJohn Forte 			if (port->tgt_mode) {
2272fcf3ce44SJohn Forte 				els->un.prli.targetFunc = 1;
2273fcf3ce44SJohn Forte 			}
2274291a2b48SSukumar Swaminathan 
2275fcf3ce44SJohn Forte 			els->un.prli.readXferRdyDis = 1;
2276fcf3ce44SJohn Forte 
2277fcf3ce44SJohn Forte 			if (hba->vpd.feaLevelHigh >= 0x02) {
2278fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 1;
2279fcf3ce44SJohn Forte 				els->un.prli.Retry = 1;
2280fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 1;
2281fcf3ce44SJohn Forte 			} else {
2282fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 0;
2283fcf3ce44SJohn Forte 				els->un.prli.Retry = 0;
2284fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 0;
2285fcf3ce44SJohn Forte 			}
2286fcf3ce44SJohn Forte 
2287fcf3ce44SJohn Forte 			break;
2288fcf3ce44SJohn Forte 
2289fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2290fcf3ce44SJohn Forte 
2291fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2292fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2293fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2294fcf3ce44SJohn Forte 
2295fcf3ce44SJohn Forte 			els->un.prlo.prloType = PRLO_FCP_TYPE;
2296fcf3ce44SJohn Forte 			els->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
2297fcf3ce44SJohn Forte 
2298fcf3ce44SJohn Forte 			break;
2299fcf3ce44SJohn Forte 
2300fcf3ce44SJohn Forte 
2301fcf3ce44SJohn Forte 		}	/* switch(type2) */
2302fcf3ce44SJohn Forte 		break;
2303fcf3ce44SJohn Forte 
2304fcf3ce44SJohn Forte 	case ELS_CMD_LS_RJT:	/* reject response */
2305fcf3ce44SJohn Forte 
2306fcf3ce44SJohn Forte 		if (!(pkt = emlxs_pkt_alloc(port,
2307fcf3ce44SJohn Forte 		    sizeof (uint32_t) + sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) {
2308fcf3ce44SJohn Forte 			return (1);
2309fcf3ce44SJohn Forte 		}
2310291a2b48SSukumar Swaminathan 
2311fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2312fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2313fcf3ce44SJohn Forte 
2314*82527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2315fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2316fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2317fcf3ce44SJohn Forte 		}
2318291a2b48SSukumar Swaminathan 
2319fcf3ce44SJohn Forte 		/* Build the fc header */
2320fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
2321*82527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2322291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2323291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2324*82527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2325fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2326291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2327291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2328fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2329fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2330fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2331fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
2332*82527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2333fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2334fcf3ce44SJohn Forte 
2335fcf3ce44SJohn Forte 		/*
2336291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2337291a2b48SSukumar Swaminathan 		 * "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2),
2338fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2339fcf3ce44SJohn Forte 		 */
2340fcf3ce44SJohn Forte 
2341fcf3ce44SJohn Forte 		/* Build the command */
2342291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2343fcf3ce44SJohn Forte 		els->elsCode = 0x01;
2344fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsvd0 = 0;
2345fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2346fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2347fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.vendorUnique = 0x01;
2348fcf3ce44SJohn Forte 
2349fcf3ce44SJohn Forte 		break;
2350fcf3ce44SJohn Forte 	}
2351fcf3ce44SJohn Forte 
2352fcf3ce44SJohn Forte 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
2353fcf3ce44SJohn Forte 		/* Free the pkt */
2354fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
2355fcf3ce44SJohn Forte 	}
2356291a2b48SSukumar Swaminathan 
2357fcf3ce44SJohn Forte 	return (rval);
2358fcf3ce44SJohn Forte 
2359*82527734SSukumar Swaminathan } /* emlxs_els_reply() */
2360fcf3ce44SJohn Forte 
2361fcf3ce44SJohn Forte 
2362fcf3ce44SJohn Forte #ifdef ULP_PATCH6
2363fcf3ce44SJohn Forte 
2364fcf3ce44SJohn Forte extern uint32_t
2365fcf3ce44SJohn Forte emlxs_generate_rscn(emlxs_port_t *port, uint32_t d_id)
2366fcf3ce44SJohn Forte {
2367fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
2368fcf3ce44SJohn Forte 	fc_rscn_t *rscn;
2369fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
2370fcf3ce44SJohn Forte 	uint32_t *page;
2371fcf3ce44SJohn Forte 
2372fcf3ce44SJohn Forte 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, 8, FC_ELS_DATA, 1);
2373fcf3ce44SJohn Forte 
2374fcf3ce44SJohn Forte 	if (ubp == NULL) {
2375fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
2376291a2b48SSukumar Swaminathan 		    "RSCN create: sid=0xfffffd  1 page(s): %08X, 00000000. "
2377291a2b48SSukumar Swaminathan 		    "Creation failed.", d_id);
2378fcf3ce44SJohn Forte 
2379fcf3ce44SJohn Forte 		return ((uint32_t)FC_FAILURE);
2380fcf3ce44SJohn Forte 	}
2381291a2b48SSukumar Swaminathan 
2382fcf3ce44SJohn Forte 	/* Simulate an RSCN payload */
2383fcf3ce44SJohn Forte 	rscn = (fc_rscn_t *)ubp->ub_buffer;
2384fcf3ce44SJohn Forte 	rscn->rscn_code = 0x61;
2385fcf3ce44SJohn Forte 	rscn->rscn_len = 0x04;
2386fcf3ce44SJohn Forte 	rscn->rscn_payload_len = 0x0008;
2387fcf3ce44SJohn Forte 	page = ((uint32_t *)rscn);
2388fcf3ce44SJohn Forte 	page++;
2389fcf3ce44SJohn Forte 	*page = d_id;
2390fcf3ce44SJohn Forte 
2391fcf3ce44SJohn Forte #ifdef EMLXS_I386
2392fcf3ce44SJohn Forte 	/* Put payload in BE format */
2393*82527734SSukumar Swaminathan 	rscn->rscn_payload_len = LE_SWAP16(rscn->rscn_payload_len);
2394*82527734SSukumar Swaminathan 	*page = LE_SWAP32(d_id);
2395291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */
2396fcf3ce44SJohn Forte 
2397fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
2398fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
2399fcf3ce44SJohn Forte 	ub_priv->flags |= EMLXS_UB_INTERCEPT;
2400fcf3ce44SJohn Forte 
2401fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
2402fcf3ce44SJohn Forte 	ubp->ub_frame.type = FC_ELS_DATA;
2403fcf3ce44SJohn Forte 	ubp->ub_frame.s_id = 0xfffffd;
2404*82527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(port->did);
2405fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
2406fcf3ce44SJohn Forte 	ubp->ub_frame.rx_id = 0xffff;
2407fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2408fcf3ce44SJohn Forte 
2409fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2410291a2b48SSukumar Swaminathan 	    "RSCN: sid=fffffd  1 page(s): %08X, 00000000  buffer=%p "
2411291a2b48SSukumar Swaminathan 	    "token=%x. Created.", d_id, ubp, ub_priv->token);
2412fcf3ce44SJohn Forte 
2413fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2414fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2415291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2416fcf3ce44SJohn Forte 
2417fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2418fcf3ce44SJohn Forte 
2419fcf3ce44SJohn Forte 	return (FC_SUCCESS);
2420fcf3ce44SJohn Forte 
2421*82527734SSukumar Swaminathan } /* emlxs_generate_rscn() */
2422fcf3ce44SJohn Forte 
2423291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
2424fcf3ce44SJohn Forte 
2425fcf3ce44SJohn Forte 
2426fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT
2427fcf3ce44SJohn Forte extern int
2428*82527734SSukumar Swaminathan emlxs_menlo_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2429fcf3ce44SJohn Forte {
2430fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2431fcf3ce44SJohn Forte 	IOCB *iocb;
2432fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2433fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2434fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2435fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2436fcf3ce44SJohn Forte 	menlo_cmd_t *cmd;
2437fcf3ce44SJohn Forte 	uint32_t *rsp;
2438fcf3ce44SJohn Forte 
2439fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2440fcf3ce44SJohn Forte 
2441fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2442fcf3ce44SJohn Forte 
2443fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2444fcf3ce44SJohn Forte 
2445fcf3ce44SJohn Forte 	if (!sbp) {
2446fcf3ce44SJohn Forte 		/*
2447fcf3ce44SJohn Forte 		 * completion with missing xmit command
2448fcf3ce44SJohn Forte 		 */
2449fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2450fcf3ce44SJohn Forte 
2451fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2452fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
2453*82527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
2454*82527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2455291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2456fcf3ce44SJohn Forte 
2457fcf3ce44SJohn Forte 		return (1);
2458fcf3ce44SJohn Forte 	}
2459291a2b48SSukumar Swaminathan 
2460*82527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2461fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2462fcf3ce44SJohn Forte 
2463fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2464*82527734SSukumar Swaminathan 		    "Invalid IO channel:%d iocbq=%p", cp->channelno, iocbq);
2465fcf3ce44SJohn Forte 
2466fcf3ce44SJohn Forte 		return (1);
2467fcf3ce44SJohn Forte 	}
2468291a2b48SSukumar Swaminathan 
2469fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2470fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2471fcf3ce44SJohn Forte 
2472fcf3ce44SJohn Forte 	cmd = (menlo_cmd_t *)pkt->pkt_cmd;
2473*82527734SSukumar Swaminathan 	cmd_code = BE_SWAP32(cmd->code);
2474fcf3ce44SJohn Forte 
2475fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
2476fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
2477*82527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2478fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
2479fcf3ce44SJohn Forte 	}
2480291a2b48SSukumar Swaminathan 
2481*82527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
2482291a2b48SSukumar Swaminathan 	/*
2483291a2b48SSukumar Swaminathan 	 * MENLO Command completion
2484291a2b48SSukumar Swaminathan 	 */
2485fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
2486fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
2487fcf3ce44SJohn Forte 
2488fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
2489fcf3ce44SJohn Forte 
2490fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
2491fcf3ce44SJohn Forte 
2492fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
2493fcf3ce44SJohn Forte 		rsp_code = *rsp;
2494*82527734SSukumar Swaminathan 		rsp_code = BE_SWAP32(rsp_code);
2495fcf3ce44SJohn Forte 
2496*82527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
2497fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2498fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
2499fcf3ce44SJohn Forte 		} else
2500fcf3ce44SJohn Forte 		{
2501fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2502fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
2503fcf3ce44SJohn Forte 		}
2504fcf3ce44SJohn Forte 
2505fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
2506*82527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2507fcf3ce44SJohn Forte 
2508*82527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (rsp_code == MENLO_RSP_SUCCESS)) {
2509fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
2510fcf3ce44SJohn Forte 
2511fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2512fcf3ce44SJohn Forte 			    "%s: %s rxid=0x%x",
2513fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2514fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
2515*82527734SSukumar Swaminathan 			    iocb->ULPCONTEXT);
2516fcf3ce44SJohn Forte 
2517fcf3ce44SJohn Forte 		} else {
2518fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
2519fcf3ce44SJohn Forte 
2520fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2521fcf3ce44SJohn Forte 			    "%s: %s %s %s rxid=0x%x",
2522fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2523fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
2524*82527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2525291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2526*82527734SSukumar Swaminathan 			    statLocalError), iocb->ULPCONTEXT);
2527fcf3ce44SJohn Forte 		}
2528fcf3ce44SJohn Forte 
2529*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2530fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2531fcf3ce44SJohn Forte 
2532fcf3ce44SJohn Forte 		break;
2533fcf3ce44SJohn Forte 
2534fcf3ce44SJohn Forte 	default:
2535fcf3ce44SJohn Forte 
2536fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2537fcf3ce44SJohn Forte 
2538fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
2539*82527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
2540fcf3ce44SJohn Forte 
2541*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2542fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2543fcf3ce44SJohn Forte 
2544fcf3ce44SJohn Forte 		break;
2545fcf3ce44SJohn Forte 
2546*82527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
2547fcf3ce44SJohn Forte 
2548fcf3ce44SJohn Forte 	return (0);
2549fcf3ce44SJohn Forte 
2550*82527734SSukumar Swaminathan } /* emlxs_menlo_handle_event() */
2551fcf3ce44SJohn Forte 
2552291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */
2553fcf3ce44SJohn Forte 
2554fcf3ce44SJohn Forte 
2555fcf3ce44SJohn Forte extern int
2556*82527734SSukumar Swaminathan emlxs_ct_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2557fcf3ce44SJohn Forte {
2558fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2559fcf3ce44SJohn Forte 	IOCB *iocb;
2560fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2561fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2562fcf3ce44SJohn Forte 	uint32_t *rsp;
2563fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtRsp;
2564fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
2565fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2566fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2567fcf3ce44SJohn Forte 
2568fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2569fcf3ce44SJohn Forte 
2570fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2571fcf3ce44SJohn Forte 
2572fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2573fcf3ce44SJohn Forte 
2574fcf3ce44SJohn Forte 	if (!sbp) {
2575fcf3ce44SJohn Forte 		/*
2576fcf3ce44SJohn Forte 		 * completion with missing xmit command
2577fcf3ce44SJohn Forte 		 */
2578fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2579fcf3ce44SJohn Forte 
2580fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2581fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
2582*82527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
2583*82527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2584291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2585fcf3ce44SJohn Forte 
2586fcf3ce44SJohn Forte 		return (1);
2587fcf3ce44SJohn Forte 	}
2588291a2b48SSukumar Swaminathan 
2589*82527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2590fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2591fcf3ce44SJohn Forte 
2592fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2593*82527734SSukumar Swaminathan 		    "Invalid channel: channel=%d iocbq=%p", cp->channelno,
2594*82527734SSukumar Swaminathan 		    iocbq);
2595fcf3ce44SJohn Forte 
2596fcf3ce44SJohn Forte 		return (1);
2597fcf3ce44SJohn Forte 	}
2598291a2b48SSukumar Swaminathan 
2599fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2600fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2601291a2b48SSukumar Swaminathan 	CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd;
2602*82527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
2603fcf3ce44SJohn Forte 
2604fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
2605fcf3ce44SJohn Forte 		HBASTATS.CtEvent--;
2606*82527734SSukumar Swaminathan 		return (emlxs_dfc_handle_event(hba, cp, iocbq));
2607fcf3ce44SJohn Forte 	}
2608fcf3ce44SJohn Forte 
2609fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
2610fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
2611*82527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2612fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
2613fcf3ce44SJohn Forte 	}
2614291a2b48SSukumar Swaminathan 
2615*82527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
2616291a2b48SSukumar Swaminathan 		/*
2617291a2b48SSukumar Swaminathan 		 * CT Reply completion
2618291a2b48SSukumar Swaminathan 		 */
2619fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE_CX:
2620fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE64_CX:
2621fcf3ce44SJohn Forte 
2622fcf3ce44SJohn Forte 		HBASTATS.CtRspCompleted++;
2623fcf3ce44SJohn Forte 
2624fcf3ce44SJohn Forte 		switch (CtCmd->FsType) {
2625fcf3ce44SJohn Forte 		case 0xFC:	/* Name server */
2626fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2627291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
2628*82527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2629291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2630291a2b48SSukumar Swaminathan 			    statLocalError));
2631fcf3ce44SJohn Forte 			break;
2632fcf3ce44SJohn Forte 
2633fcf3ce44SJohn Forte 		case 0xFA:	/* Managment server */
2634fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2635291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_mscmd_xlate(cmd_code),
2636*82527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2637291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2638291a2b48SSukumar Swaminathan 			    statLocalError));
2639fcf3ce44SJohn Forte 			break;
2640fcf3ce44SJohn Forte 
2641fcf3ce44SJohn Forte 		case 0x0A:	/* Emulex Remote server */
2642fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2643291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_rmcmd_xlate(cmd_code),
2644*82527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2645291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2646291a2b48SSukumar Swaminathan 			    statLocalError));
2647fcf3ce44SJohn Forte 			break;
2648fcf3ce44SJohn Forte 
2649fcf3ce44SJohn Forte 		default:
2650fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2651291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
2652*82527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2653291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
2654291a2b48SSukumar Swaminathan 			    statLocalError));
2655fcf3ce44SJohn Forte 		}
2656fcf3ce44SJohn Forte 
2657*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2658fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2659fcf3ce44SJohn Forte 
2660fcf3ce44SJohn Forte 		break;
2661fcf3ce44SJohn Forte 
2662291a2b48SSukumar Swaminathan 		/*
2663291a2b48SSukumar Swaminathan 		 * CT Command completion
2664291a2b48SSukumar Swaminathan 		 */
2665fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
2666fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
2667fcf3ce44SJohn Forte 
2668fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
2669fcf3ce44SJohn Forte 
2670fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
2671fcf3ce44SJohn Forte 
2672fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
2673fcf3ce44SJohn Forte 		CtRsp = (SLI_CT_REQUEST *)pkt->pkt_resp;
2674*82527734SSukumar Swaminathan 		rsp_code = LE_SWAP16(CtRsp->CommandResponse.bits.CmdRsp);
2675fcf3ce44SJohn Forte 
2676*82527734SSukumar Swaminathan 		if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) {
2677fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2678fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
2679fcf3ce44SJohn Forte 		} else
2680fcf3ce44SJohn Forte 		{
2681fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2682fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
2683fcf3ce44SJohn Forte 		}
2684fcf3ce44SJohn Forte 
2685fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
2686fcf3ce44SJohn Forte 
2687fcf3ce44SJohn Forte 		/*
2688291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2689291a2b48SSukumar Swaminathan 		 * "INFO: pkt_resid=%d  %d  %d  %x", pkt->pkt_resp_resid,
2690fcf3ce44SJohn Forte 		 * pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize,
2691fcf3ce44SJohn Forte 		 * iocb->un.genreq64.bdl.bdeFlags);
2692fcf3ce44SJohn Forte 		 */
2693fcf3ce44SJohn Forte 
2694*82527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) &&
2695fcf3ce44SJohn Forte 		    (rsp_code == SLI_CT_RESPONSE_FS_ACC)) {
2696fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
2697fcf3ce44SJohn Forte 
2698fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
2699291a2b48SSukumar Swaminathan 				/* ULP patch - ULP expects */
2700291a2b48SSukumar Swaminathan 				/* resp_resid = 0 on success */
2701fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
2702fcf3ce44SJohn Forte 			}
2703291a2b48SSukumar Swaminathan 
2704fcf3ce44SJohn Forte 			switch (CtCmd->FsType) {
2705fcf3ce44SJohn Forte 			case 0xFC:	/* Name server */
2706fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2707fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2708fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
2709fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
2710fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
2711fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
2712*82527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
2713fcf3ce44SJohn Forte 
2714fcf3ce44SJohn Forte #if (EMLXS_MODREV < EMLXS_MODREV4)
2715fcf3ce44SJohn Forte 				if (cmd_code == SLI_CTNS_RNN_ID) {
2716fcf3ce44SJohn Forte 					emlxs_send_rsnn(port);
2717fcf3ce44SJohn Forte 				}
2718291a2b48SSukumar Swaminathan #endif /* < EMLXS_MODREV4 */
2719fcf3ce44SJohn Forte 
2720fcf3ce44SJohn Forte 				break;
2721fcf3ce44SJohn Forte 
2722fcf3ce44SJohn Forte 			case 0xFA:	/* Managment server */
2723fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2724fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2725fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
2726fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(cmd_code),
2727fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(rsp_code),
2728fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
2729*82527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
2730fcf3ce44SJohn Forte 				break;
2731fcf3ce44SJohn Forte 
2732fcf3ce44SJohn Forte 			case 0x0A:	/* Emulex Remote server */
2733fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2734fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2735fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
2736fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(cmd_code),
2737fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(rsp_code),
2738fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
2739*82527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
2740fcf3ce44SJohn Forte 				break;
2741fcf3ce44SJohn Forte 
2742fcf3ce44SJohn Forte 			default:
2743fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2744fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2745fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
2746fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
2747fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
2748fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
2749*82527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
2750fcf3ce44SJohn Forte 			}
2751fcf3ce44SJohn Forte 		} else {
2752fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
2753fcf3ce44SJohn Forte 
2754fcf3ce44SJohn Forte 			if (rsp_code == SLI_CT_RESPONSE_FS_RJT) {
2755fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_FS_RJT;
2756fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
2757fcf3ce44SJohn Forte 				pkt->pkt_reason = CtRsp->ReasonCode;
2758fcf3ce44SJohn Forte 				pkt->pkt_expln = CtRsp->Explanation;
2759fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
2760fcf3ce44SJohn Forte 
2761fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
2762fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
2763fcf3ce44SJohn Forte 				    "%s: Rejected. rsn=%x exp=%x",
2764fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
2765291a2b48SSukumar Swaminathan 				    pkt->pkt_reason, pkt->pkt_expln);
2766*82527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
2767fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
2768fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
2769fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2770fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2771fcf3ce44SJohn Forte 					    "%s: %s %s",
2772fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
2773291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2774*82527734SSukumar Swaminathan 					    ULPSTATUS),
2775291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
2776291a2b48SSukumar Swaminathan 					    perr.statLocalError));
2777fcf3ce44SJohn Forte 					break;
2778fcf3ce44SJohn Forte 
2779fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
2780fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2781fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2782fcf3ce44SJohn Forte 					    "%s: %s %s",
2783fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
2784291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2785*82527734SSukumar Swaminathan 					    ULPSTATUS),
2786291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
2787291a2b48SSukumar Swaminathan 					    perr.statLocalError));
2788fcf3ce44SJohn Forte 					break;
2789fcf3ce44SJohn Forte 
2790fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
2791fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2792fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2793fcf3ce44SJohn Forte 					    "%s: %s %s",
2794fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
2795291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2796*82527734SSukumar Swaminathan 					    ULPSTATUS),
2797291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
2798291a2b48SSukumar Swaminathan 					    perr.statLocalError));
2799fcf3ce44SJohn Forte 					break;
2800fcf3ce44SJohn Forte 
2801fcf3ce44SJohn Forte 				default:
2802fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2803fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2804fcf3ce44SJohn Forte 					    "%s: %s %s",
2805fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
2806291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2807*82527734SSukumar Swaminathan 					    ULPSTATUS),
2808291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
2809291a2b48SSukumar Swaminathan 					    perr.statLocalError));
2810fcf3ce44SJohn Forte 				}
2811fcf3ce44SJohn Forte 			} else {
2812fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
2813fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
2814fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2815fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2816fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
2817fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
2818291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2819*82527734SSukumar Swaminathan 					    ULPSTATUS),
2820fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
2821fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
2822fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
2823291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
2824291a2b48SSukumar Swaminathan 					    statLocalError);
2825fcf3ce44SJohn Forte 					break;
2826fcf3ce44SJohn Forte 
2827fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
2828fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2829fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2830fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
2831fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
2832291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2833*82527734SSukumar Swaminathan 					    ULPSTATUS),
2834fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
2835fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
2836fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
2837291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
2838291a2b48SSukumar Swaminathan 					    statLocalError);
2839fcf3ce44SJohn Forte 					break;
2840fcf3ce44SJohn Forte 
2841fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
2842fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2843fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2844fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
2845fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
2846291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2847*82527734SSukumar Swaminathan 					    ULPSTATUS),
2848fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
2849fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
2850fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
2851291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
2852291a2b48SSukumar Swaminathan 					    statLocalError);
2853fcf3ce44SJohn Forte 					break;
2854fcf3ce44SJohn Forte 
2855fcf3ce44SJohn Forte 				default:
2856fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
2857fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
2858fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
2859fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
2860291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
2861*82527734SSukumar Swaminathan 					    ULPSTATUS),
2862fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
2863fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
2864fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
2865291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
2866291a2b48SSukumar Swaminathan 					    statLocalError);
2867fcf3ce44SJohn Forte 				}
2868fcf3ce44SJohn Forte 			}
2869fcf3ce44SJohn Forte 		}
2870fcf3ce44SJohn Forte 
2871*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2872fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2873fcf3ce44SJohn Forte 
2874fcf3ce44SJohn Forte 		break;
2875fcf3ce44SJohn Forte 
2876fcf3ce44SJohn Forte 	default:
2877fcf3ce44SJohn Forte 
2878fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2879fcf3ce44SJohn Forte 
2880fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
2881*82527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
2882fcf3ce44SJohn Forte 
2883*82527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2884fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2885fcf3ce44SJohn Forte 
2886fcf3ce44SJohn Forte 		break;
2887*82527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
2888fcf3ce44SJohn Forte 
2889fcf3ce44SJohn Forte 	return (0);
2890fcf3ce44SJohn Forte 
2891*82527734SSukumar Swaminathan } /* emlxs_ct_handle_event() */
2892fcf3ce44SJohn Forte 
2893fcf3ce44SJohn Forte 
2894fcf3ce44SJohn Forte extern int
2895*82527734SSukumar Swaminathan emlxs_ct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2896fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
2897fcf3ce44SJohn Forte {
2898fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
2899fcf3ce44SJohn Forte 	IOCB *iocb;
2900fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
2901fcf3ce44SJohn Forte 	uint32_t cmd_code;
2902fcf3ce44SJohn Forte 
2903fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2904fcf3ce44SJohn Forte 
2905fcf3ce44SJohn Forte 	CtCmd = (SLI_CT_REQUEST *)mp->virt;
2906*82527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
2907fcf3ce44SJohn Forte 
2908fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
2909fcf3ce44SJohn Forte 		int rval;
2910fcf3ce44SJohn Forte 
2911*82527734SSukumar Swaminathan 		rval = emlxs_dfc_handle_unsol_req(port, cp, iocbq, mp, size);
2912fcf3ce44SJohn Forte 
2913fcf3ce44SJohn Forte 		return (rval);
2914fcf3ce44SJohn Forte 	}
2915fcf3ce44SJohn Forte 
2916fcf3ce44SJohn Forte 	HBASTATS.CtCmdReceived++;
2917fcf3ce44SJohn Forte 
2918fcf3ce44SJohn Forte 	switch (CtCmd->FsType) {
2919fcf3ce44SJohn Forte 	case 0xFC:	/* Name server */
2920fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
2921291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
2922*82527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
2923fcf3ce44SJohn Forte 		break;
2924fcf3ce44SJohn Forte 
2925fcf3ce44SJohn Forte 	case 0xFA:	/* Managment server */
2926fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
2927291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_mscmd_xlate(cmd_code),
2928*82527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
2929fcf3ce44SJohn Forte 		break;
2930fcf3ce44SJohn Forte 
2931fcf3ce44SJohn Forte 	case 0x0A:	/* Emulex Remote server */
2932fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
2933291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_rmcmd_xlate(cmd_code),
2934*82527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
2935fcf3ce44SJohn Forte 		break;
2936fcf3ce44SJohn Forte 
2937fcf3ce44SJohn Forte 	default:
2938fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
2939291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
2940*82527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
2941fcf3ce44SJohn Forte 	}
2942fcf3ce44SJohn Forte 
2943728bdc9bSSukumar Swaminathan 	if (emlxs_log_ct_event(port, (uint8_t *)mp->virt, size,
2944*82527734SSukumar Swaminathan 	    iocb->ULPCONTEXT)) {
2945728bdc9bSSukumar Swaminathan 		/* Abort the exchange */
2946*82527734SSukumar Swaminathan 		emlxs_abort_ct_exchange(hba, port, iocb->ULPCONTEXT);
2947728bdc9bSSukumar Swaminathan 	}
2948fcf3ce44SJohn Forte 
2949fcf3ce44SJohn Forte 	return (0);
2950fcf3ce44SJohn Forte 
2951*82527734SSukumar Swaminathan } /* emlxs_ct_handle_unsol_req() */
2952fcf3ce44SJohn Forte 
2953fcf3ce44SJohn Forte 
2954fcf3ce44SJohn Forte static void
2955fcf3ce44SJohn Forte emlxs_send_rsnn(emlxs_port_t *port)
2956fcf3ce44SJohn Forte {
2957fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
2958fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2959fcf3ce44SJohn Forte 	SLI_CT_REQUEST *ct;
2960fcf3ce44SJohn Forte 
2961291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port, sizeof (SLI_CT_REQUEST),
2962291a2b48SSukumar Swaminathan 	    sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) {
2963fcf3ce44SJohn Forte 		return;
2964fcf3ce44SJohn Forte 	}
2965291a2b48SSukumar Swaminathan 
2966fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
2967fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2968fcf3ce44SJohn Forte 
2969fcf3ce44SJohn Forte 	/* Build the fc header */
2970*82527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(NAMESERVER_DID);
2971fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL;
2972*82527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
2973fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES;
2974291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
2975291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
2976fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
2977fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2978fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2979fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
2980fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
2981fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
2982fcf3ce44SJohn Forte 
2983fcf3ce44SJohn Forte 	/* Build the command */
2984fcf3ce44SJohn Forte 	ct = (SLI_CT_REQUEST *)pkt->pkt_cmd;
2985fcf3ce44SJohn Forte 
2986fcf3ce44SJohn Forte 	ct->RevisionId.bits.Revision = SLI_CT_REVISION;
2987fcf3ce44SJohn Forte 	ct->RevisionId.bits.InId = 0;
2988fcf3ce44SJohn Forte 
2989fcf3ce44SJohn Forte 	ct->FsType = SLI_CT_DIRECTORY_SERVICE;
2990fcf3ce44SJohn Forte 	ct->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
2991fcf3ce44SJohn Forte 
2992fcf3ce44SJohn Forte 	ct->CommandResponse.bits.Size = 0;
2993*82527734SSukumar Swaminathan 	ct->CommandResponse.bits.CmdRsp = LE_SWAP16(SLI_CTNS_RSNN_NN);
2994fcf3ce44SJohn Forte 
2995fcf3ce44SJohn Forte 	bcopy((uint8_t *)&hba->wwnn, (char *)ct->un.rsnn.wwnn, 8);
2996fcf3ce44SJohn Forte 
2997fcf3ce44SJohn Forte 	ct->un.rsnn.snn_len = strlen(port->snn);
2998fcf3ce44SJohn Forte 	bcopy(port->snn, (char *)ct->un.rsnn.snn, ct->un.rsnn.snn_len);
2999fcf3ce44SJohn Forte 
3000291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_send_msg, "Sending RSNN_NN. [%s]",
3001fcf3ce44SJohn Forte 	    port->snn);
3002fcf3ce44SJohn Forte 
3003fcf3ce44SJohn Forte 	/* Send the pkt later in another thread */
3004fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 0) != FC_SUCCESS) {
3005fcf3ce44SJohn Forte 		/* Free the pkt */
3006fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3007fcf3ce44SJohn Forte 	}
3008291a2b48SSukumar Swaminathan 
3009fcf3ce44SJohn Forte 	return;
3010fcf3ce44SJohn Forte 
3011*82527734SSukumar Swaminathan } /* emlxs_send_rsnn() */
3012fcf3ce44SJohn Forte 
3013fcf3ce44SJohn Forte 
3014fcf3ce44SJohn Forte extern uint32_t
3015fcf3ce44SJohn Forte emlxs_ub_send_login_acc(emlxs_port_t *port, fc_unsol_buf_t *ubp)
3016fcf3ce44SJohn Forte {
3017fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3018fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3019fcf3ce44SJohn Forte 	ELS_PKT *els;
3020fcf3ce44SJohn Forte 	uint32_t rval;
3021fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
3022fcf3ce44SJohn Forte 
3023fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
3024fcf3ce44SJohn Forte 
3025fcf3ce44SJohn Forte 	if (!(pkt = emlxs_pkt_alloc(port,
3026fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (SERV_PARM), 0, 0, KM_NOSLEEP))) {
3027fcf3ce44SJohn Forte 		return (1);
3028fcf3ce44SJohn Forte 	}
3029291a2b48SSukumar Swaminathan 
3030fcf3ce44SJohn Forte 	/* Common initialization */
3031fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3032fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3033fcf3ce44SJohn Forte 
3034fcf3ce44SJohn Forte 	if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) {
3035fcf3ce44SJohn Forte 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
3036fcf3ce44SJohn Forte 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
3037fcf3ce44SJohn Forte 	}
3038291a2b48SSukumar Swaminathan 
3039fcf3ce44SJohn Forte 	/* Build the fc header */
3040fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id;
3041291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3042291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
3043fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.s_id = ubp->ub_frame.d_id;
3044fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3045291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3046291a2b48SSukumar Swaminathan 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
3047fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3048fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3049fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3050fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff;
3051fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id;
3052fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3053fcf3ce44SJohn Forte 
3054fcf3ce44SJohn Forte 	/* Build the command */
3055291a2b48SSukumar Swaminathan 	els = (ELS_PKT *)pkt->pkt_cmd;
3056fcf3ce44SJohn Forte 	els->elsCode = 0x02;
3057291a2b48SSukumar Swaminathan 	bcopy((void *)&port->sparam, (void *)&els->un.logi,
3058291a2b48SSukumar Swaminathan 	    sizeof (SERV_PARM));
3059fcf3ce44SJohn Forte 
3060fcf3ce44SJohn Forte 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
3061fcf3ce44SJohn Forte 		/* Free the pkt */
3062fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3063fcf3ce44SJohn Forte 	} else {
3064fcf3ce44SJohn Forte 		ub_priv->flags |= EMLXS_UB_INTERCEPT;
3065fcf3ce44SJohn Forte 	}
3066fcf3ce44SJohn Forte 
3067fcf3ce44SJohn Forte 	return (rval);
3068fcf3ce44SJohn Forte 
3069*82527734SSukumar Swaminathan } /* emlxs_ub_send_login_acc */
3070fcf3ce44SJohn Forte 
3071fcf3ce44SJohn Forte 
3072fcf3ce44SJohn Forte extern void
3073fcf3ce44SJohn Forte emlxs_send_logo(emlxs_port_t *port, uint32_t d_id)
3074fcf3ce44SJohn Forte {
3075fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3076fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3077fcf3ce44SJohn Forte 	ELS_PKT *els;
3078fcf3ce44SJohn Forte 
3079fcf3ce44SJohn Forte 	if (hba->state <= FC_LINK_DOWN) {
3080fcf3ce44SJohn Forte 		return;
3081fcf3ce44SJohn Forte 	}
3082291a2b48SSukumar Swaminathan 
3083291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port,
3084291a2b48SSukumar Swaminathan 	    sizeof (uint32_t) + sizeof (LOGO),
3085fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (LOGO), 0, KM_NOSLEEP))) {
3086fcf3ce44SJohn Forte 		return;
3087fcf3ce44SJohn Forte 	}
3088291a2b48SSukumar Swaminathan 
3089fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3090fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3091fcf3ce44SJohn Forte 
3092fcf3ce44SJohn Forte 	/* Build the fc header */
3093*82527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id);
3094291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3095291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
3096*82527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3097fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3098291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3099291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
3100fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3101fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3102fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3103fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
3104fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
3105fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3106fcf3ce44SJohn Forte 
3107fcf3ce44SJohn Forte 	/* Build the command */
3108fcf3ce44SJohn Forte 	els = (ELS_PKT *)pkt->pkt_cmd;
3109fcf3ce44SJohn Forte 	els->elsCode = 0x05;
3110fcf3ce44SJohn Forte 	els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id;
3111291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&port->wwpn, (uint8_t *)&els->un.logo.portName,
3112291a2b48SSukumar Swaminathan 	    8);
3113fcf3ce44SJohn Forte 
3114fcf3ce44SJohn Forte 	/* Send the pkt now */
3115fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3116fcf3ce44SJohn Forte 		/* Free the pkt */
3117fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3118fcf3ce44SJohn Forte 	}
3119291a2b48SSukumar Swaminathan 
3120fcf3ce44SJohn Forte 	return;
3121fcf3ce44SJohn Forte 
3122fcf3ce44SJohn Forte } /* emlxs_send_logo() */
3123