1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8*8f23e9faSHans Rosenfeld  * You can obtain a copy of the license at
9*8f23e9faSHans Rosenfeld  * http://www.opensource.org/licenses/cddl1.txt.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22fcf3ce44SJohn Forte /*
23*8f23e9faSHans Rosenfeld  * Copyright (c) 2004-2012 Emulex. All rights reserved.
2482527734SSukumar Swaminathan  * Use is subject to license terms.
25fcf3ce44SJohn Forte  */
26fcf3ce44SJohn Forte 
27291a2b48SSukumar Swaminathan #include <emlxs.h>
28fcf3ce44SJohn Forte 
29fcf3ce44SJohn Forte /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30fcf3ce44SJohn Forte EMLXS_MSG_DEF(EMLXS_ELS_C);
31fcf3ce44SJohn Forte 
32291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp);
33a9800bebSGarrett D'Amore static void	emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp);
34291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp);
35291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp);
36291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp);
37291a2b48SSukumar Swaminathan static void	emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp);
38291a2b48SSukumar Swaminathan 
3982527734SSukumar Swaminathan static void	emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp,
40291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4182527734SSukumar Swaminathan static void	emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp,
42291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4382527734SSukumar Swaminathan static void	emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp,
44291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4582527734SSukumar Swaminathan static void	emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp,
46291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4782527734SSukumar Swaminathan static void	emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp,
48291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
4982527734SSukumar Swaminathan static void	emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp,
50291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5182527734SSukumar Swaminathan static void	emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp,
52291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5382527734SSukumar Swaminathan static void	emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp,
54291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
5582527734SSukumar Swaminathan static void	emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp,
56291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
57*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_echo(emlxs_port_t *port, CHANNEL *cp,
58a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
59*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_rtv(emlxs_port_t *port, CHANNEL *cp,
60a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
61*8f23e9faSHans Rosenfeld static void	emlxs_handle_unsol_rls(emlxs_port_t *port, CHANNEL *cp,
62a9800bebSGarrett D'Amore 			IOCBQ *iocbq, MATCHMAP *mp, uint32_t size);
63291a2b48SSukumar Swaminathan static void	emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp,
64291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
65291a2b48SSukumar Swaminathan static void	emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp,
66291a2b48SSukumar Swaminathan 			IOCBQ *iocbq, uint32_t flag);
67a9800bebSGarrett D'Amore 
68a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4)
69291a2b48SSukumar Swaminathan static void	emlxs_send_rsnn(emlxs_port_t *port);
70fcf3ce44SJohn Forte 
71a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */
72fcf3ce44SJohn Forte 
73fcf3ce44SJohn Forte 
74fcf3ce44SJohn Forte 
75fcf3ce44SJohn Forte /* Routine Declaration - Local */
76fcf3ce44SJohn Forte /* End Routine Declaration - Local */
77fcf3ce44SJohn Forte 
78fcf3ce44SJohn Forte /*
79fcf3ce44SJohn Forte  *  emlxs_els_handle_event
80fcf3ce44SJohn Forte  *
81291a2b48SSukumar Swaminathan  *  Description: Process an ELS Response Ring cmpl
82fcf3ce44SJohn Forte  *
83fcf3ce44SJohn Forte  */
84fcf3ce44SJohn Forte extern int
emlxs_els_handle_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)8582527734SSukumar Swaminathan emlxs_els_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
86fcf3ce44SJohn Forte {
87fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
88fcf3ce44SJohn Forte 	IOCB *iocb;
89fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
90fcf3ce44SJohn Forte 	fc_packet_t *pkt;
91fcf3ce44SJohn Forte 	uint32_t *lp0;
92fcf3ce44SJohn Forte 	uint32_t command;
93fcf3ce44SJohn Forte 	NODELIST *ndlp;
94fcf3ce44SJohn Forte 	uint32_t did;
95fcf3ce44SJohn Forte 	ELS_PKT *els;
96fcf3ce44SJohn Forte 
97fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
98fcf3ce44SJohn Forte 
99fcf3ce44SJohn Forte 	HBASTATS.ElsEvent++;
100fcf3ce44SJohn Forte 
101fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
102fcf3ce44SJohn Forte 
103fcf3ce44SJohn Forte 	if (!sbp) {
104fcf3ce44SJohn Forte 		/*
105fcf3ce44SJohn Forte 		 * completion with missing xmit command
106fcf3ce44SJohn Forte 		 */
107fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
108fcf3ce44SJohn Forte 
109fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
110fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
11182527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
11282527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
113291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
114fcf3ce44SJohn Forte 
115fcf3ce44SJohn Forte 		return (1);
116fcf3ce44SJohn Forte 	}
117291a2b48SSukumar Swaminathan 
11882527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_els) {
119fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
120fcf3ce44SJohn Forte 
121fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_els_completion_msg,
12282527734SSukumar Swaminathan 		    "Not ELS channel: channel=%d iocbq=%p cmd=0x%x iotag=0x%x "
12382527734SSukumar Swaminathan 		    "status=0x%x perr=0x%x", cp->channelno, iocbq,
12482527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPCOMMAND, (uint32_t)iocb->ULPIOTAG,
12582527734SSukumar Swaminathan 		    iocb->ULPSTATUS, iocb->un.ulpWord[4]);
126fcf3ce44SJohn Forte 
127fcf3ce44SJohn Forte 		return (1);
128fcf3ce44SJohn Forte 	}
129291a2b48SSukumar Swaminathan 
130fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
131fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
132fcf3ce44SJohn Forte 	lp0 = (uint32_t *)pkt->pkt_cmd;
133fcf3ce44SJohn Forte 	command = *lp0 & ELS_CMD_MASK;
13482527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
135fcf3ce44SJohn Forte 
136fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
137fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
13882527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
139fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
140fcf3ce44SJohn Forte 	}
141291a2b48SSukumar Swaminathan 
14282527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
143291a2b48SSukumar Swaminathan 		/*
144291a2b48SSukumar Swaminathan 		 * ELS Reply completion
145291a2b48SSukumar Swaminathan 		 */
146fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP_CX:
147fcf3ce44SJohn Forte 	case CMD_XMIT_ELS_RSP64_CX:
148fcf3ce44SJohn Forte 
149fcf3ce44SJohn Forte 		HBASTATS.ElsRspCompleted++;
150fcf3ce44SJohn Forte 
151fcf3ce44SJohn Forte 		if (command == ELS_CMD_ACC) {
152fcf3ce44SJohn Forte 			emlxs_handle_acc(port, sbp, iocbq, 1);
153fcf3ce44SJohn Forte 		} else {
154fcf3ce44SJohn Forte 			emlxs_handle_reject(port, sbp, iocbq, 1);
155fcf3ce44SJohn Forte 		}
156fcf3ce44SJohn Forte 
157fcf3ce44SJohn Forte 		break;
158fcf3ce44SJohn Forte 
159291a2b48SSukumar Swaminathan 		/*
160291a2b48SSukumar Swaminathan 		 * ELS command completion
161291a2b48SSukumar Swaminathan 		 */
162fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CR:
163fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CR:
164fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST_CX:
165fcf3ce44SJohn Forte 	case CMD_ELS_REQUEST64_CX:
166fcf3ce44SJohn Forte 
167fcf3ce44SJohn Forte 		HBASTATS.ElsCmdCompleted++;
168fcf3ce44SJohn Forte 
169fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_ELS_RSP_VALID;
170fcf3ce44SJohn Forte 
171fcf3ce44SJohn Forte 		els = (ELS_PKT *)pkt->pkt_resp;
172fcf3ce44SJohn Forte 
173fcf3ce44SJohn Forte 		pkt->pkt_resp_resid =
174fcf3ce44SJohn Forte 		    pkt->pkt_rsplen - iocb->un.elsreq64.bdl.bdeSize;
175fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
176fcf3ce44SJohn Forte 
177fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.d_id = pkt->pkt_cmd_fhdr.s_id;
178fcf3ce44SJohn Forte 		pkt->pkt_resp_fhdr.s_id = pkt->pkt_cmd_fhdr.d_id;
179fcf3ce44SJohn Forte 
18082527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (els->elsCode == 0x02)) {
181fcf3ce44SJohn Forte 			HBASTATS.ElsCmdGood++;
182fcf3ce44SJohn Forte 
183fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
184fcf3ce44SJohn Forte 				/*
185291a2b48SSukumar Swaminathan 				 * ULP patch - ULP expects
186291a2b48SSukumar Swaminathan 				 * resp_resid = 0 on success
187fcf3ce44SJohn Forte 				 */
188fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
189fcf3ce44SJohn Forte 			}
190291a2b48SSukumar Swaminathan 
191fcf3ce44SJohn Forte 			switch (command) {
192fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
193a9800bebSGarrett D'Amore 				emlxs_handle_sol_fdisc(port, sbp);
194fcf3ce44SJohn Forte 
195fcf3ce44SJohn Forte 				break;
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
198fcf3ce44SJohn Forte 				emlxs_handle_sol_flogi(port, sbp);
199fcf3ce44SJohn Forte 
200fcf3ce44SJohn Forte 				break;
201fcf3ce44SJohn Forte 
202fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login */
203fcf3ce44SJohn Forte 				emlxs_handle_sol_plogi(port, sbp);
204fcf3ce44SJohn Forte 
205fcf3ce44SJohn Forte 				break;
206fcf3ce44SJohn Forte 
207fcf3ce44SJohn Forte 			case ELS_CMD_ADISC:	/* Adisc */
208fcf3ce44SJohn Forte 				emlxs_handle_sol_adisc(port, sbp);
209fcf3ce44SJohn Forte 
210fcf3ce44SJohn Forte 				break;
211fcf3ce44SJohn Forte 
212fcf3ce44SJohn Forte 			case ELS_CMD_LOGO:	/* Logout */
213fcf3ce44SJohn Forte 				emlxs_handle_sol_logo(port, sbp);
214fcf3ce44SJohn Forte 
215fcf3ce44SJohn Forte 				break;
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In */
218fcf3ce44SJohn Forte 				emlxs_handle_sol_prli(port, sbp);
219fcf3ce44SJohn Forte 
220fcf3ce44SJohn Forte 				break;
221fcf3ce44SJohn Forte 
222fcf3ce44SJohn Forte 			default:
223fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
224291a2b48SSukumar Swaminathan 				    &emlxs_els_completion_msg, "%s: did=%x",
225fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did);
226fcf3ce44SJohn Forte 
227fcf3ce44SJohn Forte 				emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
228fcf3ce44SJohn Forte 
229fcf3ce44SJohn Forte 				break;
230fcf3ce44SJohn Forte 			}
231fcf3ce44SJohn Forte 
232fcf3ce44SJohn Forte 		} else {
233fcf3ce44SJohn Forte 			HBASTATS.ElsCmdError++;
234fcf3ce44SJohn Forte 
235fcf3ce44SJohn Forte 			/* Look for LS_REJECT */
23682527734SSukumar Swaminathan 			if (iocb->ULPSTATUS == IOSTAT_LS_RJT) {
237fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_LS_RJT;
238fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
239fcf3ce44SJohn Forte 				pkt->pkt_reason = iocb->un.grsp.perr.statRsn;
240fcf3ce44SJohn Forte 				pkt->pkt_expln = iocb->un.grsp.perr.statBaExp;
241fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
242fcf3ce44SJohn Forte 
243291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
244*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
245291a2b48SSukumar Swaminathan 				if (ndlp) {
246291a2b48SSukumar Swaminathan 					emlxs_log_sd_lsrjt_event(port,
247291a2b48SSukumar Swaminathan 					    (HBA_WWN *)&ndlp->nlp_portname,
248291a2b48SSukumar Swaminathan 					    command, pkt->pkt_reason,
249291a2b48SSukumar Swaminathan 					    pkt->pkt_expln);
250291a2b48SSukumar Swaminathan 				}
251291a2b48SSukumar Swaminathan #endif
252291a2b48SSukumar Swaminathan 
253fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
254fcf3ce44SJohn Forte 				    &emlxs_els_completion_msg,
255fcf3ce44SJohn Forte 				    "%s Rejected: did=%x rsn=%x exp=%x",
256fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
257fcf3ce44SJohn Forte 				    pkt->pkt_reason, pkt->pkt_expln);
25882527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
259fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
260fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
261fcf3ce44SJohn Forte 				    "%s: did=%x Local Reject. %s",
262fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
263291a2b48SSukumar Swaminathan 				    emlxs_error_xlate(iocb->un.grsp.perr.
264291a2b48SSukumar Swaminathan 				    statLocalError));
265fcf3ce44SJohn Forte 			} else {
266fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
267fcf3ce44SJohn Forte 				    &emlxs_bad_els_completion_msg,
268fcf3ce44SJohn Forte 				    "%s: did=%x %s (%02x%02x%02x%02x)",
269fcf3ce44SJohn Forte 				    emlxs_elscmd_xlate(command), did,
27082527734SSukumar Swaminathan 				    emlxs_state_xlate(iocb->ULPSTATUS),
271fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statAction,
272fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statRsn,
273fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statBaExp,
274fcf3ce44SJohn Forte 				    iocb->un.grsp.perr.statLocalError);
275fcf3ce44SJohn Forte 			}
276fcf3ce44SJohn Forte 
277fcf3ce44SJohn Forte 			switch (command) {
278fcf3ce44SJohn Forte 			case ELS_CMD_PLOGI:	/* NPort login failed */
279*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
280fcf3ce44SJohn Forte 
281fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
282fcf3ce44SJohn Forte 					/* Open the node again */
283fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28482527734SSukumar Swaminathan 					    hba->channel_fcp);
285fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
28682527734SSukumar Swaminathan 					    hba->channel_ip);
287fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
288fcf3ce44SJohn Forte 					if (pkt->pkt_state == FC_PKT_LS_RJT) {
289fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
290fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
291fcf3ce44SJohn Forte 						    pkt->pkt_reason,
292fcf3ce44SJohn Forte 						    pkt->pkt_expln);
293fcf3ce44SJohn Forte 					}
294291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
295fcf3ce44SJohn Forte 				}
296291a2b48SSukumar Swaminathan 
297fcf3ce44SJohn Forte 				break;
298fcf3ce44SJohn Forte 
299fcf3ce44SJohn Forte 
300fcf3ce44SJohn Forte 			case ELS_CMD_PRLI:	/* Process Log In failed */
301*8f23e9faSHans Rosenfeld 				ndlp = emlxs_node_find_did(port, did, 1);
302fcf3ce44SJohn Forte 
303fcf3ce44SJohn Forte 				if (ndlp && ndlp->nlp_active) {
304fcf3ce44SJohn Forte 					/* Open the node again */
305fcf3ce44SJohn Forte 					emlxs_node_open(port, ndlp,
30682527734SSukumar Swaminathan 					    hba->channel_fcp);
307fcf3ce44SJohn Forte 				}
308291a2b48SSukumar Swaminathan 
309fcf3ce44SJohn Forte 				break;
310fcf3ce44SJohn Forte 
311fcf3ce44SJohn Forte 			case ELS_CMD_FDISC:	/* Fabric login */
312fcf3ce44SJohn Forte 			case ELS_CMD_FLOGI:	/* Fabric login */
313fcf3ce44SJohn Forte 				if (pkt->pkt_state == FC_PKT_LS_RJT) {
314291a2b48SSukumar Swaminathan 					/* This will cause ULP to retry */
315291a2b48SSukumar Swaminathan 					/* FLOGI requests */
316fcf3ce44SJohn Forte 					pkt->pkt_reason = FC_REASON_QFULL;
317fcf3ce44SJohn Forte 					pkt->pkt_expln = 0;
318fcf3ce44SJohn Forte 
319fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
320*8f23e9faSHans Rosenfeld 					ndlp = emlxs_node_find_did(port,
321*8f23e9faSHans Rosenfeld 					    did, 1);
322fcf3ce44SJohn Forte 					if (ndlp && ndlp->nlp_active) {
323fcf3ce44SJohn Forte 						emlxs_dhc_state(port, ndlp,
324fcf3ce44SJohn Forte 						    NODE_STATE_NOCHANGE,
325fcf3ce44SJohn Forte 						    pkt->pkt_reason,
326fcf3ce44SJohn Forte 						    pkt->pkt_expln);
327fcf3ce44SJohn Forte 					}
328291a2b48SSukumar Swaminathan #endif /*  DHCHAP_SUPPORT */
329fcf3ce44SJohn Forte 				}
330291a2b48SSukumar Swaminathan 
331a9800bebSGarrett D'Amore 				if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
332*8f23e9faSHans Rosenfeld 					/* Preset the state for deferred cmpl */
333*8f23e9faSHans Rosenfeld 					emlxs_set_pkt_state(sbp,
334*8f23e9faSHans Rosenfeld 					    iocb->ULPSTATUS,
335*8f23e9faSHans Rosenfeld 					    iocb->un.grsp.perr.statLocalError,
336*8f23e9faSHans Rosenfeld 					    1);
337*8f23e9faSHans Rosenfeld 
338*8f23e9faSHans Rosenfeld 					if (emlxs_vpi_logi_failed_notify(
339*8f23e9faSHans Rosenfeld 					    sbp->port, sbp) == 0) {
340*8f23e9faSHans Rosenfeld 						/* Defer completion */
341*8f23e9faSHans Rosenfeld 						return (0);
342*8f23e9faSHans Rosenfeld 					}
343a9800bebSGarrett D'Amore 				}
344a9800bebSGarrett D'Amore 
345fcf3ce44SJohn Forte 				break;
346fcf3ce44SJohn Forte 
347fcf3ce44SJohn Forte 			default:
348fcf3ce44SJohn Forte 				break;
349fcf3ce44SJohn Forte 			}
350fcf3ce44SJohn Forte 
35182527734SSukumar Swaminathan 			emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
352fcf3ce44SJohn Forte 			    iocb->un.grsp.perr.statLocalError, 1);
353fcf3ce44SJohn Forte 		}
354fcf3ce44SJohn Forte 
355fcf3ce44SJohn Forte 		break;
356fcf3ce44SJohn Forte 
357fcf3ce44SJohn Forte 	default:
358fcf3ce44SJohn Forte 
359fcf3ce44SJohn Forte 		HBASTATS.ElsStray++;
360fcf3ce44SJohn Forte 
361fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_els_msg,
36282527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
363fcf3ce44SJohn Forte 
36482527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
365fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
366fcf3ce44SJohn Forte 
367fcf3ce44SJohn Forte 		break;
36882527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
369fcf3ce44SJohn Forte 
370fcf3ce44SJohn Forte 	return (0);
371fcf3ce44SJohn Forte 
37282527734SSukumar Swaminathan } /* emlxs_els_handle_event() */
373fcf3ce44SJohn Forte 
374fcf3ce44SJohn Forte 
375fcf3ce44SJohn Forte extern int
emlxs_els_handle_unsol_req(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)37682527734SSukumar Swaminathan emlxs_els_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
377fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
378fcf3ce44SJohn Forte {
379fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
380fcf3ce44SJohn Forte 	uint32_t cmd_code;
381a9800bebSGarrett D'Amore 	IOCB *iocb;
382fcf3ce44SJohn Forte 
383fcf3ce44SJohn Forte 	HBASTATS.ElsCmdReceived++;
384fcf3ce44SJohn Forte 
385a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
386fcf3ce44SJohn Forte 	cmd_code = *((uint32_t *)mp->virt) & ELS_CMD_MASK;
387fcf3ce44SJohn Forte 
38882527734SSukumar Swaminathan 	if (!(port->flag & EMLXS_PORT_BOUND)) {
389e2ca2865SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
390e2ca2865SSukumar Swaminathan 		    "%s: sid=%x. Port not bound: Rejecting.",
391e2ca2865SSukumar Swaminathan 		    emlxs_elscmd_xlate(cmd_code),
392e2ca2865SSukumar Swaminathan 		    iocbq->iocb.un.elsreq.remoteID);
39382527734SSukumar Swaminathan 
39482527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
395e2ca2865SSukumar Swaminathan 		    cmd_code, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
39682527734SSukumar Swaminathan 
39782527734SSukumar Swaminathan 		return (0);
39882527734SSukumar Swaminathan 	}
39982527734SSukumar Swaminathan 
400fcf3ce44SJohn Forte 	switch (cmd_code) {
401fcf3ce44SJohn Forte 	case ELS_CMD_RSCN:
402fcf3ce44SJohn Forte 		HBASTATS.ElsRscnReceived++;
40382527734SSukumar Swaminathan 		emlxs_handle_unsol_rscn(port, cp, iocbq, mp, size);
404fcf3ce44SJohn Forte 		break;
405fcf3ce44SJohn Forte 
406fcf3ce44SJohn Forte 	case ELS_CMD_FLOGI:
407fcf3ce44SJohn Forte 		HBASTATS.ElsFlogiReceived++;
40882527734SSukumar Swaminathan 		emlxs_handle_unsol_flogi(port, cp, iocbq, mp, size);
409fcf3ce44SJohn Forte 		break;
410fcf3ce44SJohn Forte 
411fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
412fcf3ce44SJohn Forte 		HBASTATS.ElsPlogiReceived++;
41382527734SSukumar Swaminathan 		emlxs_handle_unsol_plogi(port, cp, iocbq, mp, size);
414fcf3ce44SJohn Forte 		break;
415fcf3ce44SJohn Forte 
416fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
417fcf3ce44SJohn Forte 		HBASTATS.ElsPrliReceived++;
41882527734SSukumar Swaminathan 		emlxs_handle_unsol_prli(port, cp, iocbq, mp, size);
419fcf3ce44SJohn Forte 		break;
420fcf3ce44SJohn Forte 
421fcf3ce44SJohn Forte 	case ELS_CMD_PRLO:
422fcf3ce44SJohn Forte 		HBASTATS.ElsPrloReceived++;
42382527734SSukumar Swaminathan 		emlxs_handle_unsol_prlo(port, cp, iocbq, mp, size);
424fcf3ce44SJohn Forte 		break;
425fcf3ce44SJohn Forte 
426fcf3ce44SJohn Forte 	case ELS_CMD_LOGO:
427fcf3ce44SJohn Forte 		HBASTATS.ElsLogoReceived++;
42882527734SSukumar Swaminathan 		emlxs_handle_unsol_logo(port, cp, iocbq, mp, size);
429fcf3ce44SJohn Forte 		break;
430fcf3ce44SJohn Forte 
431fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
432fcf3ce44SJohn Forte 		HBASTATS.ElsAdiscReceived++;
43382527734SSukumar Swaminathan 		emlxs_handle_unsol_adisc(port, cp, iocbq, mp, size);
434fcf3ce44SJohn Forte 		break;
435fcf3ce44SJohn Forte 
436fcf3ce44SJohn Forte 	case ELS_CMD_AUTH:
437fcf3ce44SJohn Forte 		HBASTATS.ElsAuthReceived++;
43882527734SSukumar Swaminathan 		emlxs_handle_unsol_auth(port, cp, iocbq, mp, size);
439fcf3ce44SJohn Forte 		break;
440fcf3ce44SJohn Forte 
441a9800bebSGarrett D'Amore 	case ELS_CMD_TEST:
442a9800bebSGarrett D'Amore 		HBASTATS.ElsTestReceived++;
443a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
444a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
445a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
446a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
447a9800bebSGarrett D'Amore 
448a9800bebSGarrett D'Amore 		/* drop it */
449a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
450a9800bebSGarrett D'Amore 		break;
451a9800bebSGarrett D'Amore 
452a9800bebSGarrett D'Amore 	case ELS_CMD_ESTC:
453a9800bebSGarrett D'Amore 		HBASTATS.ElsEstcReceived++;
454a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
455a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
456a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
457a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
458a9800bebSGarrett D'Amore 
459a9800bebSGarrett D'Amore 		/* drop it */
460a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
461a9800bebSGarrett D'Amore 		break;
462a9800bebSGarrett D'Amore 
463a9800bebSGarrett D'Amore 	case ELS_CMD_FARPR:
464a9800bebSGarrett D'Amore 		HBASTATS.ElsFarprReceived++;
465a9800bebSGarrett D'Amore 
466a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
467a9800bebSGarrett D'Amore 		    "%s: sid=%x. Dropping.",
468a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
469a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
470a9800bebSGarrett D'Amore 
471a9800bebSGarrett D'Amore 		/* drop it */
472a9800bebSGarrett D'Amore 		emlxs_close_els_exchange(hba, port, iocb->ULPCONTEXT);
473a9800bebSGarrett D'Amore 		break;
474a9800bebSGarrett D'Amore 
475a9800bebSGarrett D'Amore 	case ELS_CMD_ECHO:
476a9800bebSGarrett D'Amore 		HBASTATS.ElsEchoReceived++;
477*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_echo(port, cp, iocbq, mp, size);
478a9800bebSGarrett D'Amore 		break;
479a9800bebSGarrett D'Amore 
480a9800bebSGarrett D'Amore 	case ELS_CMD_RLS:
481a9800bebSGarrett D'Amore 		HBASTATS.ElsRlsReceived++;
482*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_rls(port, cp, iocbq, mp, size);
483a9800bebSGarrett D'Amore 		break;
484a9800bebSGarrett D'Amore 
485a9800bebSGarrett D'Amore 	case ELS_CMD_RTV:
486a9800bebSGarrett D'Amore 		HBASTATS.ElsRtvReceived++;
487*8f23e9faSHans Rosenfeld 		emlxs_handle_unsol_rtv(port, cp, iocbq, mp, size);
488a9800bebSGarrett D'Amore 		break;
489a9800bebSGarrett D'Amore 
490a9800bebSGarrett D'Amore 	case ELS_CMD_ABTX:
491a9800bebSGarrett D'Amore 	case ELS_CMD_RCS:
492a9800bebSGarrett D'Amore 	case ELS_CMD_RES:
493a9800bebSGarrett D'Amore 	case ELS_CMD_RSS:
494a9800bebSGarrett D'Amore 	case ELS_CMD_RSI:
495a9800bebSGarrett D'Amore 	case ELS_CMD_ESTS:
496a9800bebSGarrett D'Amore 	case ELS_CMD_RRQ:
497a9800bebSGarrett D'Amore 	case ELS_CMD_REC:
498a9800bebSGarrett D'Amore 		HBASTATS.ElsGenReceived++;
499a9800bebSGarrett D'Amore 
500a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
501a9800bebSGarrett D'Amore 		    "%s: sid=%x. Rejecting.",
502a9800bebSGarrett D'Amore 		    emlxs_elscmd_xlate(cmd_code),
503a9800bebSGarrett D'Amore 		    iocbq->iocb.un.elsreq.remoteID);
504a9800bebSGarrett D'Amore 
505a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd_code,
506a9800bebSGarrett D'Amore 		    LSRJT_CMD_UNSUPPORTED, LSEXP_NOTHING_MORE);
507a9800bebSGarrett D'Amore 		break;
508a9800bebSGarrett D'Amore 
509fcf3ce44SJohn Forte 	default:
510fcf3ce44SJohn Forte 		HBASTATS.ElsGenReceived++;
51182527734SSukumar Swaminathan 		emlxs_handle_unsol_gen_cmd(port, cp, iocbq, mp, size);
512fcf3ce44SJohn Forte 		break;
513fcf3ce44SJohn Forte 	}
514fcf3ce44SJohn Forte 
515fcf3ce44SJohn Forte 	return (0);
516fcf3ce44SJohn Forte 
51782527734SSukumar Swaminathan } /* emlxs_els_handle_unsol_req() */
518fcf3ce44SJohn Forte 
519fcf3ce44SJohn Forte 
520*8f23e9faSHans Rosenfeld static uint32_t
emlxs_els_delay_discovery(emlxs_port_t * port,emlxs_buf_t * sbp)521*8f23e9faSHans Rosenfeld emlxs_els_delay_discovery(emlxs_port_t *port, emlxs_buf_t *sbp)
522*8f23e9faSHans Rosenfeld {
523*8f23e9faSHans Rosenfeld 	emlxs_hba_t	*hba = HBA;
524*8f23e9faSHans Rosenfeld 	emlxs_config_t	*cfg;
525*8f23e9faSHans Rosenfeld 	SERV_PARM	*parm;
526*8f23e9faSHans Rosenfeld 
527*8f23e9faSHans Rosenfeld 	cfg = &CFG;
528*8f23e9faSHans Rosenfeld 	if (!cfg[CFG_DELAY_DISCOVERY].current) {
529*8f23e9faSHans Rosenfeld 		return (0);
530*8f23e9faSHans Rosenfeld 	}
531*8f23e9faSHans Rosenfeld 
532*8f23e9faSHans Rosenfeld 	parm = &port->fabric_sparam;
533*8f23e9faSHans Rosenfeld 	if (((port->prev_did != port->did) ||
534*8f23e9faSHans Rosenfeld 	    bcmp(&port->prev_fabric_sparam.portName,
535*8f23e9faSHans Rosenfeld 	    &port->fabric_sparam.portName, 8)) &&
536*8f23e9faSHans Rosenfeld 	    !(parm->cmn.CLEAN_ADDRESS_BIT)) {
537*8f23e9faSHans Rosenfeld 
538*8f23e9faSHans Rosenfeld 		/* If this is the first time, check config parameter */
539*8f23e9faSHans Rosenfeld 		if (port->prev_did || cfg[CFG_DELAY_DISCOVERY].current == 2) {
540*8f23e9faSHans Rosenfeld 
541*8f23e9faSHans Rosenfeld 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
542*8f23e9faSHans Rosenfeld 			    "Clean Address delay: sid=%x prev=%x RATOV %d",
543*8f23e9faSHans Rosenfeld 			    port->did, port->prev_did, hba->fc_ratov);
544*8f23e9faSHans Rosenfeld 
545*8f23e9faSHans Rosenfeld 			port->clean_address_sbp = sbp;
546*8f23e9faSHans Rosenfeld 			port->clean_address_timer =
547*8f23e9faSHans Rosenfeld 			    hba->timer_tics + hba->fc_ratov;
548*8f23e9faSHans Rosenfeld 
549*8f23e9faSHans Rosenfeld 			return (1);
550*8f23e9faSHans Rosenfeld 		}
551*8f23e9faSHans Rosenfeld 	}
552*8f23e9faSHans Rosenfeld 	return (0);
553*8f23e9faSHans Rosenfeld 
554*8f23e9faSHans Rosenfeld } /* emlxs_els_delay_discovery() */
555*8f23e9faSHans Rosenfeld 
556*8f23e9faSHans Rosenfeld 
557fcf3ce44SJohn Forte static void
emlxs_handle_sol_flogi(emlxs_port_t * port,emlxs_buf_t * sbp)558fcf3ce44SJohn Forte emlxs_handle_sol_flogi(emlxs_port_t *port, emlxs_buf_t *sbp)
559fcf3ce44SJohn Forte {
560fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
561fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
562fcf3ce44SJohn Forte 	emlxs_port_t *vport;
563fcf3ce44SJohn Forte 	SERV_PARM *sp;
564fcf3ce44SJohn Forte 	fc_packet_t *pkt;
565fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
566fcf3ce44SJohn Forte 	uint32_t did;
567fcf3ce44SJohn Forte 	IOCBQ *iocbq;
568fcf3ce44SJohn Forte 	IOCB *iocb;
569fcf3ce44SJohn Forte 	char buffer[64];
570fcf3ce44SJohn Forte 	uint32_t i;
57182527734SSukumar Swaminathan 	int rc;
572a9800bebSGarrett D'Amore 	uint16_t altBbCredit;
573fcf3ce44SJohn Forte 
574fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
575fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
57682527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
577fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
578fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
579fcf3ce44SJohn Forte 
580a9800bebSGarrett D'Amore 	mutex_enter(&EMLXS_PORT_LOCK);
581fcf3ce44SJohn Forte 
582a9800bebSGarrett D'Amore 	/* Save the fabric service parameters and did */
583a9800bebSGarrett D'Amore 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
584a9800bebSGarrett D'Amore 
585*8f23e9faSHans Rosenfeld 	/* Save E_D_TOV ticks in nanoseconds */
586*8f23e9faSHans Rosenfeld 	if (sp->cmn.edtovResolution) {
587*8f23e9faSHans Rosenfeld 		hba->fc_edtov = (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
588*8f23e9faSHans Rosenfeld 	} else {
589*8f23e9faSHans Rosenfeld 		hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
590*8f23e9faSHans Rosenfeld 	}
591*8f23e9faSHans Rosenfeld 
592*8f23e9faSHans Rosenfeld 	/* Save R_A_TOV ticks */
593*8f23e9faSHans Rosenfeld 	hba->fc_ratov = (LE_SWAP32(sp->cmn.w2.r_a_tov) + 999) / 1000;
594*8f23e9faSHans Rosenfeld 
595a9800bebSGarrett D'Amore 	if (sp->cmn.fPort) {
596fcf3ce44SJohn Forte 		hba->flag |= FC_FABRIC_ATTACHED;
597fcf3ce44SJohn Forte 		hba->flag &= ~FC_PT_TO_PT;
598fcf3ce44SJohn Forte 
599*8f23e9faSHans Rosenfeld 		port->did = iocb->un.elsreq.myID;
60082527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.s_id = LE_SWAP24_LO(FABRIC_DID);
60182527734SSukumar Swaminathan 		pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
602fcf3ce44SJohn Forte 
603a9800bebSGarrett D'Amore 		/*
604a9800bebSGarrett D'Amore 		 * If we are a N-port connected to a Fabric,
605a9800bebSGarrett D'Amore 		 * fixup sparam's so logins to devices on remote
606a9800bebSGarrett D'Amore 		 * loops work.
607a9800bebSGarrett D'Amore 		 */
608a9800bebSGarrett D'Amore 		altBbCredit = (hba->topology != TOPOLOGY_LOOP)? 1:0;
609a9800bebSGarrett D'Amore 		hba->sparam.cmn.altBbCredit = altBbCredit;
610fcf3ce44SJohn Forte 
611a9800bebSGarrett D'Amore 		/* Set this bit in all the port sparam copies */
612a9800bebSGarrett D'Amore 		for (i = 0; i < MAX_VPORTS; i++) {
613a9800bebSGarrett D'Amore 			vport = &VPORT(i);
614291a2b48SSukumar Swaminathan 
615a9800bebSGarrett D'Amore 			if (!(vport->flag & EMLXS_PORT_BOUND)) {
616a9800bebSGarrett D'Amore 				continue;
617fcf3ce44SJohn Forte 			}
618a9800bebSGarrett D'Amore 
619a9800bebSGarrett D'Amore 			vport->sparam.cmn.altBbCredit = altBbCredit;
620fcf3ce44SJohn Forte 		}
62182527734SSukumar Swaminathan 
622fcf3ce44SJohn Forte 		if (sp->cmn.rspMultipleNPort) {
623fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_SUPPORTED;
624fcf3ce44SJohn Forte 
625fcf3ce44SJohn Forte 			if (cfg[CFG_NPIV_DELAY].current) {
626fcf3ce44SJohn Forte 				/*
627291a2b48SSukumar Swaminathan 				 * PATCH: for NPIV support on
628291a2b48SSukumar Swaminathan 				 * Brocade switch firmware 5.10b
629fcf3ce44SJohn Forte 				 */
630fcf3ce44SJohn Forte 				if ((hba->flag & FC_NPIV_ENABLED) &&
631fcf3ce44SJohn Forte 				    ((sp->nodeName.IEEE[0] == 0x00) &&
632fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[1] == 0x05) &&
633fcf3ce44SJohn Forte 				    (sp->nodeName.IEEE[2] == 0x1e))) {
634fcf3ce44SJohn Forte 					hba->flag |= FC_NPIV_DELAY_REQUIRED;
635fcf3ce44SJohn Forte 				}
636fcf3ce44SJohn Forte 			}
637fcf3ce44SJohn Forte 		} else {
638fcf3ce44SJohn Forte 			hba->flag |= FC_NPIV_UNSUPPORTED;
639fcf3ce44SJohn Forte 		}
640fcf3ce44SJohn Forte 
641fcf3ce44SJohn Forte 		if (!(hba->flag & FC_NPIV_ENABLED)) {
642*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Disabled ",
643*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
644fcf3ce44SJohn Forte 		} else if (hba->flag & FC_NPIV_SUPPORTED) {
645*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Supported ",
646*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
647fcf3ce44SJohn Forte 		} else {
648*8f23e9faSHans Rosenfeld 			(void) strlcpy(buffer, "npiv:Unsupported ",
649*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
650fcf3ce44SJohn Forte 		}
651fcf3ce44SJohn Forte 
652fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
653fcf3ce44SJohn Forte 		if (!sp->cmn.fcsp_support) {
654*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Unsupported",
655*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
656fcf3ce44SJohn Forte 		} else if (cfg[CFG_AUTH_ENABLE].current &&
657fcf3ce44SJohn Forte 		    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
658*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Supported",
659*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
660fcf3ce44SJohn Forte 		} else {
661*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, "fcsp:Disabled",
662*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
663fcf3ce44SJohn Forte 		}
664291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
665fcf3ce44SJohn Forte 
666fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
669*8f23e9faSHans Rosenfeld 		    "FLOGI: did=%x sid=%x prev=%x %s",
670*8f23e9faSHans Rosenfeld 		    did, port->did, port->prev_did, buffer);
67182527734SSukumar Swaminathan 
672a9800bebSGarrett D'Amore 		/* Update our service parms */
673*8f23e9faSHans Rosenfeld 		if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
674*8f23e9faSHans Rosenfeld 			/* Update our service parms */
675*8f23e9faSHans Rosenfeld 			if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
676*8f23e9faSHans Rosenfeld 			    MEM_MBOX))) {
677*8f23e9faSHans Rosenfeld 				emlxs_mb_config_link(hba, mbox);
678*8f23e9faSHans Rosenfeld 
679*8f23e9faSHans Rosenfeld 				rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
680*8f23e9faSHans Rosenfeld 				    MBX_NOWAIT, 0);
681*8f23e9faSHans Rosenfeld 				if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
682*8f23e9faSHans Rosenfeld 					emlxs_mem_put(hba, MEM_MBOX,
683*8f23e9faSHans Rosenfeld 					    (void *)mbox);
684*8f23e9faSHans Rosenfeld 				}
685*8f23e9faSHans Rosenfeld 			}
686fcf3ce44SJohn Forte 		}
687291a2b48SSukumar Swaminathan 
688fcf3ce44SJohn Forte 		/* Preset the state for the reg_did */
689fcf3ce44SJohn Forte 		emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
690fcf3ce44SJohn Forte 
691*8f23e9faSHans Rosenfeld 		if (emlxs_els_delay_discovery(port, sbp)) {
692*8f23e9faSHans Rosenfeld 			/* Deferred registration of this pkt until */
693*8f23e9faSHans Rosenfeld 			/* Clean Address timeout */
694*8f23e9faSHans Rosenfeld 			return;
695*8f23e9faSHans Rosenfeld 		}
696*8f23e9faSHans Rosenfeld 
697*8f23e9faSHans Rosenfeld 		if (EMLXS_SLI_REG_DID(port, FABRIC_DID, &port->fabric_sparam,
698fcf3ce44SJohn Forte 		    sbp, NULL, NULL) == 0) {
699291a2b48SSukumar Swaminathan 			/* Deferred completion of this pkt until */
700291a2b48SSukumar Swaminathan 			/* login is complete */
701fcf3ce44SJohn Forte 			return;
702fcf3ce44SJohn Forte 		}
703291a2b48SSukumar Swaminathan 
704fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
705fcf3ce44SJohn Forte 		    IOERR_NO_RESOURCES, 1);
706fcf3ce44SJohn Forte 
707fcf3ce44SJohn Forte 	} else {	/* No switch */
708291a2b48SSukumar Swaminathan 
709fcf3ce44SJohn Forte 		hba->flag &= ~FC_FABRIC_ATTACHED;
710fcf3ce44SJohn Forte 		hba->flag |= FC_PT_TO_PT;
711fcf3ce44SJohn Forte 
712*8f23e9faSHans Rosenfeld 		hba->flag &= ~FC_NPIV_SUPPORTED;
713*8f23e9faSHans Rosenfeld 		(void) strlcpy(buffer, "npiv:Disabled.", sizeof (buffer));
714*8f23e9faSHans Rosenfeld 
715*8f23e9faSHans Rosenfeld 		if (emlxs_wwn_cmp((uint8_t *)&sp->portName,
716*8f23e9faSHans Rosenfeld 		    (uint8_t *)&port->wwpn) > 0) {
717*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, " P2P Master.",
718*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
719fcf3ce44SJohn Forte 		} else {
720*8f23e9faSHans Rosenfeld 			(void) strlcat(buffer, " P2P Slave.",
721*8f23e9faSHans Rosenfeld 			    sizeof (buffer));
722fcf3ce44SJohn Forte 		}
723fcf3ce44SJohn Forte 
724*8f23e9faSHans Rosenfeld 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
725*8f23e9faSHans Rosenfeld 		    "FLOGI: did=%x sid=%x %s", did, port->did, buffer);
72682527734SSukumar Swaminathan 
727*8f23e9faSHans Rosenfeld 		mutex_exit(&EMLXS_PORT_LOCK);
728fcf3ce44SJohn Forte 
729*8f23e9faSHans Rosenfeld 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
730*8f23e9faSHans Rosenfeld 			/* Preset the state for the reg_did */
731*8f23e9faSHans Rosenfeld 			emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
732fcf3ce44SJohn Forte 
733*8f23e9faSHans Rosenfeld 			if (EMLXS_SLI_REG_DID(port, FABRIC_DID,
734*8f23e9faSHans Rosenfeld 			    &port->fabric_sparam, sbp, NULL, NULL) == 0) {
735*8f23e9faSHans Rosenfeld 				/* Deferred completion of this pkt until */
736*8f23e9faSHans Rosenfeld 				/* login is complete */
737*8f23e9faSHans Rosenfeld 				return;
738*8f23e9faSHans Rosenfeld 			}
739fcf3ce44SJohn Forte 
740*8f23e9faSHans Rosenfeld 			emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
741*8f23e9faSHans Rosenfeld 			    IOERR_NO_RESOURCES, 1);
742fcf3ce44SJohn Forte 
743*8f23e9faSHans Rosenfeld 		} else {
744*8f23e9faSHans Rosenfeld 			emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
745*8f23e9faSHans Rosenfeld 		}
746fcf3ce44SJohn Forte 	}
747fcf3ce44SJohn Forte 
748fcf3ce44SJohn Forte 	return;
749fcf3ce44SJohn Forte 
75082527734SSukumar Swaminathan } /* emlxs_handle_sol_flogi() */
751fcf3ce44SJohn Forte 
752fcf3ce44SJohn Forte 
753fcf3ce44SJohn Forte static void
emlxs_handle_sol_fdisc(emlxs_port_t * port,emlxs_buf_t * sbp)754a9800bebSGarrett D'Amore emlxs_handle_sol_fdisc(emlxs_port_t *port, emlxs_buf_t *sbp)
755fcf3ce44SJohn Forte {
756fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
757fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
758fcf3ce44SJohn Forte 	SERV_PARM *sp;
759fcf3ce44SJohn Forte 	fc_packet_t *pkt;
760fcf3ce44SJohn Forte 	uint32_t did;
761fcf3ce44SJohn Forte 	IOCBQ *iocbq;
762fcf3ce44SJohn Forte 	IOCB *iocb;
763fcf3ce44SJohn Forte 	char buffer[64];
764fcf3ce44SJohn Forte 
765fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
766fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
76782527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
768fcf3ce44SJohn Forte 	iocbq = &sbp->iocbq;
769fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
770fcf3ce44SJohn Forte 
771fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
772fcf3ce44SJohn Forte 
773a9800bebSGarrett D'Amore 	/* Save the fabric service parameters and did */
774fcf3ce44SJohn Forte 	port->did = iocb->un.elsreq.myID;
775fcf3ce44SJohn Forte 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
776fcf3ce44SJohn Forte 
777a9800bebSGarrett D'Amore 	pkt->pkt_resp_fhdr.d_id = LE_SWAP24_LO(port->did);
778a9800bebSGarrett D'Amore 
779fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
780fcf3ce44SJohn Forte 
781fcf3ce44SJohn Forte 	buffer[0] = 0;
782fcf3ce44SJohn Forte 
783fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
784fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
785*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Unsupported",
786*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
787291a2b48SSukumar Swaminathan 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_NPIV].current) {
788*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Supported",
789*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
790fcf3ce44SJohn Forte 	} else {
791*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Disabled",
792*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
793fcf3ce44SJohn Forte 	}
794291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
795fcf3ce44SJohn Forte 
796fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
797a9800bebSGarrett D'Amore 	    "FDISC: did=%x sid=%x %s", did, port->did, buffer);
798fcf3ce44SJohn Forte 
799fcf3ce44SJohn Forte 	/* Preset the state for the reg_did */
800fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
801fcf3ce44SJohn Forte 
802*8f23e9faSHans Rosenfeld 	if (emlxs_els_delay_discovery(port, sbp)) {
803*8f23e9faSHans Rosenfeld 		/* Deferred registration of this pkt until */
804*8f23e9faSHans Rosenfeld 		/* Clean Address timeout */
805*8f23e9faSHans Rosenfeld 		return;
806*8f23e9faSHans Rosenfeld 	}
807*8f23e9faSHans Rosenfeld 
808*8f23e9faSHans Rosenfeld 	if (EMLXS_SLI_REG_DID(port, FABRIC_DID, &port->fabric_sparam, sbp,
809fcf3ce44SJohn Forte 	    NULL, NULL) == 0) {
810fcf3ce44SJohn Forte 		/*
811fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
812fcf3ce44SJohn Forte 		 */
813fcf3ce44SJohn Forte 		return;
814fcf3ce44SJohn Forte 	}
815291a2b48SSukumar Swaminathan 
816fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
817fcf3ce44SJohn Forte 
818fcf3ce44SJohn Forte 	return;
819fcf3ce44SJohn Forte 
820a9800bebSGarrett D'Amore } /* emlxs_handle_sol_fdisc() */
821fcf3ce44SJohn Forte 
822fcf3ce44SJohn Forte 
823fcf3ce44SJohn Forte static void
emlxs_handle_sol_plogi(emlxs_port_t * port,emlxs_buf_t * sbp)824fcf3ce44SJohn Forte emlxs_handle_sol_plogi(emlxs_port_t *port, emlxs_buf_t *sbp)
825fcf3ce44SJohn Forte {
826fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
827fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
828fcf3ce44SJohn Forte 	SERV_PARM *sp;
829fcf3ce44SJohn Forte 	fc_packet_t *pkt;
830fcf3ce44SJohn Forte 	uint32_t did;
831fcf3ce44SJohn Forte 	uint32_t sid;
832fcf3ce44SJohn Forte 	NODELIST *ndlp;
833fcf3ce44SJohn Forte 	char buffer[64];
834fcf3ce44SJohn Forte 
835fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
836fcf3ce44SJohn Forte 	sp = (SERV_PARM *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
83782527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
83882527734SSukumar Swaminathan 	sid = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.s_id);
839fcf3ce44SJohn Forte 
840fcf3ce44SJohn Forte 	buffer[0] = 0;
841fcf3ce44SJohn Forte 
842fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
843fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
844*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Unsupported",
845*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
846fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
847fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
848*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Supported",
849*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
850fcf3ce44SJohn Forte 	} else {
851*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Disabled",
852*8f23e9faSHans Rosenfeld 		    sizeof (buffer));
853fcf3ce44SJohn Forte 	}
854291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
855fcf3ce44SJohn Forte 
856*8f23e9faSHans Rosenfeld 	if (hba->flag & FC_PT_TO_PT) {
857*8f23e9faSHans Rosenfeld 		mutex_enter(&EMLXS_PORT_LOCK);
858*8f23e9faSHans Rosenfeld 
859*8f23e9faSHans Rosenfeld 		port->did = sid;
860*8f23e9faSHans Rosenfeld 		port->rdid = did;
861*8f23e9faSHans Rosenfeld 
862*8f23e9faSHans Rosenfeld 		/* Save E_D_TOV ticks in nanoseconds */
863*8f23e9faSHans Rosenfeld 		if (sp->cmn.edtovResolution) {
864*8f23e9faSHans Rosenfeld 			hba->fc_edtov =
865*8f23e9faSHans Rosenfeld 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
866*8f23e9faSHans Rosenfeld 		} else {
867*8f23e9faSHans Rosenfeld 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
868*8f23e9faSHans Rosenfeld 		}
869*8f23e9faSHans Rosenfeld 
870*8f23e9faSHans Rosenfeld 		/* Only E_D_TOV is valid for PLOGI in pt2pt mode */
871*8f23e9faSHans Rosenfeld 
872*8f23e9faSHans Rosenfeld 		mutex_exit(&EMLXS_PORT_LOCK);
873*8f23e9faSHans Rosenfeld 	}
874*8f23e9faSHans Rosenfeld 
875fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
876291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x %s", sid, did, buffer);
877fcf3ce44SJohn Forte 
878fcf3ce44SJohn Forte 	/* Preset the pkt state for reg_did */
879fcf3ce44SJohn Forte 	emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
880fcf3ce44SJohn Forte 
881fcf3ce44SJohn Forte 	/*
882fcf3ce44SJohn Forte 	 * Do register login to Firmware before calling packet completion
883fcf3ce44SJohn Forte 	 */
884*8f23e9faSHans Rosenfeld 	if (EMLXS_SLI_REG_DID(port, did, sp, sbp, NULL, NULL) == 0) {
885fcf3ce44SJohn Forte 		/*
886fcf3ce44SJohn Forte 		 * Deferred completion of this pkt until login is complete
887fcf3ce44SJohn Forte 		 */
888fcf3ce44SJohn Forte 		return;
889fcf3ce44SJohn Forte 	}
890291a2b48SSukumar Swaminathan 
891*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, did, 1);
892fcf3ce44SJohn Forte 
893fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
894fcf3ce44SJohn Forte 		/* Open the node again */
89582527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
89682527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
897fcf3ce44SJohn Forte 	}
898291a2b48SSukumar Swaminathan 
899fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT, IOERR_NO_RESOURCES, 1);
900fcf3ce44SJohn Forte 
901fcf3ce44SJohn Forte 	return;
902fcf3ce44SJohn Forte 
90382527734SSukumar Swaminathan } /* emlxs_handle_sol_plogi() */
904fcf3ce44SJohn Forte 
905fcf3ce44SJohn Forte 
906fcf3ce44SJohn Forte static void
emlxs_handle_sol_adisc(emlxs_port_t * port,emlxs_buf_t * sbp)907fcf3ce44SJohn Forte emlxs_handle_sol_adisc(emlxs_port_t *port, emlxs_buf_t *sbp)
908fcf3ce44SJohn Forte {
90982527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
910fcf3ce44SJohn Forte 	fc_packet_t *pkt;
911fcf3ce44SJohn Forte 	uint32_t did;
912fcf3ce44SJohn Forte 	NODELIST *ndlp;
913fcf3ce44SJohn Forte 
914fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
91582527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
916fcf3ce44SJohn Forte 
917291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "ADISC: did=%x",
918fcf3ce44SJohn Forte 	    did);
919fcf3ce44SJohn Forte 
920*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, did, 1);
921fcf3ce44SJohn Forte 
922fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
923fcf3ce44SJohn Forte 		/* Open the node again */
92482527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
92582527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_ip);
92682527734SSukumar Swaminathan 
92782527734SSukumar Swaminathan 		if (hba->sli_mode == EMLXS_HBA_SLI4_MODE) {
928a9800bebSGarrett D'Amore 
929a9800bebSGarrett D'Amore 			emlxs_set_pkt_state(sbp, IOSTAT_SUCCESS, 0, 1);
930a9800bebSGarrett D'Amore 
931a9800bebSGarrett D'Amore 			if (emlxs_rpi_resume_notify(port,
932a9800bebSGarrett D'Amore 			    ndlp->rpip, sbp) == 0) {
93382527734SSukumar Swaminathan 				/*
93482527734SSukumar Swaminathan 				 * Delay ADISC cmpl to ULP till
93582527734SSukumar Swaminathan 				 * after RESUME_RPI
93682527734SSukumar Swaminathan 				 */
93782527734SSukumar Swaminathan 				return;
93882527734SSukumar Swaminathan 			}
93982527734SSukumar Swaminathan 		}
940fcf3ce44SJohn Forte 	}
941291a2b48SSukumar Swaminathan 
942fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
943fcf3ce44SJohn Forte 
944fcf3ce44SJohn Forte 	return;
945fcf3ce44SJohn Forte 
94682527734SSukumar Swaminathan } /* emlxs_handle_sol_adisc() */
947fcf3ce44SJohn Forte 
948fcf3ce44SJohn Forte 
949fcf3ce44SJohn Forte static void
emlxs_handle_sol_prli(emlxs_port_t * port,emlxs_buf_t * sbp)950fcf3ce44SJohn Forte emlxs_handle_sol_prli(emlxs_port_t *port, emlxs_buf_t *sbp)
951fcf3ce44SJohn Forte {
952fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
953fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
954fcf3ce44SJohn Forte 	fc_packet_t *pkt;
955fcf3ce44SJohn Forte 	NODELIST *ndlp;
956fcf3ce44SJohn Forte 	uint32_t did;
957fcf3ce44SJohn Forte 	PRLI *npr;
958fcf3ce44SJohn Forte 	uint32_t task_retry_id;
959fcf3ce44SJohn Forte 
960fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
961fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)pkt->pkt_resp + sizeof (uint32_t));
96282527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
963fcf3ce44SJohn Forte 
964*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, did, 1);
965fcf3ce44SJohn Forte 
966fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
967fcf3ce44SJohn Forte 		/* Check for FCP support */
968fcf3ce44SJohn Forte 		if ((npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
969fcf3ce44SJohn Forte 		    (npr->prliType == PRLI_FCP_TYPE)) {
970a9800bebSGarrett D'Amore 			/* Clear FCP2 support if no ADISC support requested */
971a9800bebSGarrett D'Amore 			if (cfg[CFG_ADISC_SUPPORT].current == 0) {
972a9800bebSGarrett D'Amore 				npr->ConfmComplAllowed = 0;
973a9800bebSGarrett D'Amore 				npr->TaskRetryIdReq = 0;
974a9800bebSGarrett D'Amore 				npr->Retry = 0;
975a9800bebSGarrett D'Amore 			}
976a9800bebSGarrett D'Amore 
977fcf3ce44SJohn Forte 			/* Check for target */
978fcf3ce44SJohn Forte 			if (npr->targetFunc) {
979fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
980fcf3ce44SJohn Forte 			} else {
981fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
982fcf3ce44SJohn Forte 			}
983*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT
984*8f23e9faSHans Rosenfeld 			emlxs_node_throttle_set(port, ndlp);
985*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */
986fcf3ce44SJohn Forte 
987fcf3ce44SJohn Forte 			/* Check for initiator */
988fcf3ce44SJohn Forte 			if (npr->initiatorFunc) {
989fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
990fcf3ce44SJohn Forte 			} else {
991fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
992fcf3ce44SJohn Forte 			}
993fcf3ce44SJohn Forte 
994291a2b48SSukumar Swaminathan 			/* If TRI support is not required then force */
995291a2b48SSukumar Swaminathan 			/* the task_retry_id value to one */
996fcf3ce44SJohn Forte 			if (cfg[CFG_TRI_REQUIRED].current == 0) {
997fcf3ce44SJohn Forte 				task_retry_id = 1;
998fcf3ce44SJohn Forte 			} else {
999fcf3ce44SJohn Forte 				task_retry_id = npr->TaskRetryIdReq;
1000fcf3ce44SJohn Forte 			}
1001fcf3ce44SJohn Forte 
1002fcf3ce44SJohn Forte 			/* Check for FCP2 target support */
1003fcf3ce44SJohn Forte 			/* Retry and TaskRetryId bits are both required here */
1004fcf3ce44SJohn Forte 			if (npr->targetFunc && npr->Retry && task_retry_id) {
1005fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1006fcf3ce44SJohn Forte 			} else {
1007fcf3ce44SJohn Forte 				ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1008fcf3ce44SJohn Forte 			}
1009fcf3ce44SJohn Forte 		}
1010291a2b48SSukumar Swaminathan 
1011fcf3ce44SJohn Forte 		/* Open the node again */
101282527734SSukumar Swaminathan 		emlxs_node_open(port, ndlp, hba->channel_fcp);
1013fcf3ce44SJohn Forte 
1014*8f23e9faSHans Rosenfeld 		EMLXS_SET_DFC_STATE(ndlp, NODE_ALLOC);
1015*8f23e9faSHans Rosenfeld 
1016fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
1017291a2b48SSukumar Swaminathan 		    "PRLI: did=%x info=%02x", did, ndlp->nlp_fcp_info);
1018fcf3ce44SJohn Forte 
1019fcf3ce44SJohn Forte 		/*
1020fcf3ce44SJohn Forte 		 * Report PRLI completion
1021fcf3ce44SJohn Forte 		 */
1022fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
1023fcf3ce44SJohn Forte 
1024fcf3ce44SJohn Forte 	} else {
1025fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
1026291a2b48SSukumar Swaminathan 		    "PRLI: did=%x: Node not found. Failing.", did);
1027fcf3ce44SJohn Forte 
1028fcf3ce44SJohn Forte 		/*
1029fcf3ce44SJohn Forte 		 * Report PRLI failed
1030fcf3ce44SJohn Forte 		 */
1031fcf3ce44SJohn Forte 		emlxs_pkt_complete(sbp, IOSTAT_LOCAL_REJECT,
1032fcf3ce44SJohn Forte 		    IOERR_INVALID_RPI, 1);
1033fcf3ce44SJohn Forte 	}
1034fcf3ce44SJohn Forte 	return;
1035fcf3ce44SJohn Forte 
103682527734SSukumar Swaminathan } /* emlxs_handle_sol_prli() */
1037fcf3ce44SJohn Forte 
1038fcf3ce44SJohn Forte 
1039fcf3ce44SJohn Forte static void
emlxs_handle_sol_logo(emlxs_port_t * port,emlxs_buf_t * sbp)1040fcf3ce44SJohn Forte emlxs_handle_sol_logo(emlxs_port_t *port, emlxs_buf_t *sbp)
1041fcf3ce44SJohn Forte {
104282527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
1043fcf3ce44SJohn Forte 	fc_packet_t *pkt;
1044fcf3ce44SJohn Forte 	uint32_t did;
1045fcf3ce44SJohn Forte 	NODELIST *ndlp;
1046fcf3ce44SJohn Forte 
1047fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
104882527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
1049fcf3ce44SJohn Forte 
1050291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg, "LOGO: did=%x",
1051fcf3ce44SJohn Forte 	    did);
1052fcf3ce44SJohn Forte 
1053*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, did, 1);
1054fcf3ce44SJohn Forte 
1055fcf3ce44SJohn Forte 	if (ndlp && ndlp->nlp_active) {
1056*8f23e9faSHans Rosenfeld 		EMLXS_SET_DFC_STATE(ndlp, NODE_LOGOUT);
1057*8f23e9faSHans Rosenfeld 
1058*8f23e9faSHans Rosenfeld 		if ((hba->sli_mode == EMLXS_HBA_SLI4_MODE) &&
1059*8f23e9faSHans Rosenfeld 		    (ndlp->nlp_DID == FABRIC_DID)) {
1060*8f23e9faSHans Rosenfeld 			(void) emlxs_vpi_logo_cmpl_notify(port);
1061*8f23e9faSHans Rosenfeld 		} else {
1062*8f23e9faSHans Rosenfeld 			/* Close the node for any further normal IO */
1063*8f23e9faSHans Rosenfeld 			emlxs_node_close(port, ndlp, hba->channel_fcp, 60);
1064*8f23e9faSHans Rosenfeld 			emlxs_node_close(port, ndlp, hba->channel_ip, 60);
1065fcf3ce44SJohn Forte 
1066*8f23e9faSHans Rosenfeld 			/* Flush tx queues */
1067*8f23e9faSHans Rosenfeld 			(void) emlxs_tx_node_flush(port, ndlp, 0, 0, 0);
1068fcf3ce44SJohn Forte 
1069*8f23e9faSHans Rosenfeld 			/* Flush chip queues */
1070*8f23e9faSHans Rosenfeld 			(void) emlxs_chipq_node_flush(port, 0, ndlp, 0);
1071*8f23e9faSHans Rosenfeld 		}
1072fcf3ce44SJohn Forte 	}
1073291a2b48SSukumar Swaminathan 
1074fcf3ce44SJohn Forte 	emlxs_pkt_complete(sbp, IOSTAT_SUCCESS, 0, 1);
1075fcf3ce44SJohn Forte 
1076*8f23e9faSHans Rosenfeld 	if ((hba->sli_mode == EMLXS_HBA_SLI3_MODE) &&
1077*8f23e9faSHans Rosenfeld 	    (ndlp->nlp_DID == FABRIC_DID)) {
1078*8f23e9faSHans Rosenfeld 		port->flag &= ~EMLXS_PORT_FLOGI_CMPL;
1079*8f23e9faSHans Rosenfeld 	}
1080*8f23e9faSHans Rosenfeld 
1081fcf3ce44SJohn Forte 	return;
1082fcf3ce44SJohn Forte 
108382527734SSukumar Swaminathan } /* emlxs_handle_sol_logo() */
1084fcf3ce44SJohn Forte 
1085fcf3ce44SJohn Forte 
1086fcf3ce44SJohn Forte /* ARGSUSED */
1087fcf3ce44SJohn Forte static void
emlxs_handle_unsol_rscn(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)108882527734SSukumar Swaminathan emlxs_handle_unsol_rscn(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1089fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1090fcf3ce44SJohn Forte {
1091fcf3ce44SJohn Forte 	uint32_t *lp;
1092fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1093fcf3ce44SJohn Forte 	uint8_t *bp;
1094fcf3ce44SJohn Forte 	IOCB *iocb;
1095fcf3ce44SJohn Forte 	uint32_t count;
1096fcf3ce44SJohn Forte 	uint32_t sid;
1097fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1098fcf3ce44SJohn Forte 
1099fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1100fcf3ce44SJohn Forte 	bp = mp->virt;
1101291a2b48SSukumar Swaminathan 	lp = (uint32_t *)bp + 1;
1102fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1103fcf3ce44SJohn Forte 
1104291a2b48SSukumar Swaminathan 	/* Log the legacy rscn event for physical port only */
1105291a2b48SSukumar Swaminathan 	if (port->vpi == 0) {
1106291a2b48SSukumar Swaminathan 		emlxs_log_rscn_event(port, bp, size);
1107291a2b48SSukumar Swaminathan 	}
1108291a2b48SSukumar Swaminathan 
1109291a2b48SSukumar Swaminathan 	/* Log the vport rscn event for all ports */
1110291a2b48SSukumar Swaminathan 	emlxs_log_vportrscn_event(port, bp, size);
1111fcf3ce44SJohn Forte 
1112fcf3ce44SJohn Forte 	count = ((size - 4) / 4);
1113fcf3ce44SJohn Forte 
1114*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1115*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 1);
1116fcf3ce44SJohn Forte 
1117fcf3ce44SJohn Forte 	if (ubp == NULL) {
1118fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1119fcf3ce44SJohn Forte 		    "RSCN rcvd: sid=%x  %d page(s): %08X, %08X. Rejecting.",
112082527734SSukumar Swaminathan 		    sid, count, LE_SWAP32(*lp),
112182527734SSukumar Swaminathan 		    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0));
1122fcf3ce44SJohn Forte 
1123fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1124291a2b48SSukumar Swaminathan 		    ELS_CMD_RSCN, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1125fcf3ce44SJohn Forte 
1126fcf3ce44SJohn Forte 		goto drop_it;
1127fcf3ce44SJohn Forte 	}
1128291a2b48SSukumar Swaminathan 
1129fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1130fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1131fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
1132fcf3ce44SJohn Forte 
1133fcf3ce44SJohn Forte 	/*
1134fcf3ce44SJohn Forte 	 * Setup frame header
1135fcf3ce44SJohn Forte 	 */
1136fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1137*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
113882527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
113982527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1140fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
114182527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1142fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1143fcf3ce44SJohn Forte 
1144fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1145291a2b48SSukumar Swaminathan 	    "RSCN: sid=%x  %d page(s): %08X, %08X  buffer=%p token=%x.", sid,
114682527734SSukumar Swaminathan 	    count, LE_SWAP32(*lp),
114782527734SSukumar Swaminathan 	    ((count > 1) ? LE_SWAP32(*(lp + 1)) : 0), ubp, ub_priv->token);
1148fcf3ce44SJohn Forte 
1149fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1150fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1151291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1152fcf3ce44SJohn Forte 
1153fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1154fcf3ce44SJohn Forte 
1155fcf3ce44SJohn Forte drop_it:
1156fcf3ce44SJohn Forte 
1157fcf3ce44SJohn Forte 	return;
1158fcf3ce44SJohn Forte 
115982527734SSukumar Swaminathan } /* emlxs_handle_unsol_rscn() */
1160fcf3ce44SJohn Forte 
1161fcf3ce44SJohn Forte 
1162fcf3ce44SJohn Forte /* This is shared by FCT driver */
1163fcf3ce44SJohn Forte extern uint32_t
emlxs_process_unsol_flogi(emlxs_port_t * port,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size,char * buffer,size_t len)1164291a2b48SSukumar Swaminathan emlxs_process_unsol_flogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1165*8f23e9faSHans Rosenfeld     uint32_t size, char *buffer, size_t len)
1166fcf3ce44SJohn Forte {
1167fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1168fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1169fcf3ce44SJohn Forte 	uint8_t *bp;
1170fcf3ce44SJohn Forte 	IOCB *iocb;
1171fcf3ce44SJohn Forte 	uint32_t sid;
1172fcf3ce44SJohn Forte 	SERV_PARM *sp;
1173fcf3ce44SJohn Forte 
1174fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1175fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1176fcf3ce44SJohn Forte 
1177fcf3ce44SJohn Forte 	/* Check payload size */
1178fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1179fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1180291a2b48SSukumar Swaminathan 		    "FLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1181291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1182fcf3ce44SJohn Forte 
1183fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1184fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1185fcf3ce44SJohn Forte 
1186fcf3ce44SJohn Forte 		return (1);
1187fcf3ce44SJohn Forte 	}
1188291a2b48SSukumar Swaminathan 
1189fcf3ce44SJohn Forte 	bp = mp->virt;
1190fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1191fcf3ce44SJohn Forte 
1192fcf3ce44SJohn Forte 	mutex_enter(&EMLXS_PORT_LOCK);
1193fcf3ce44SJohn Forte 
1194fcf3ce44SJohn Forte 	hba->flag &= ~FC_FABRIC_ATTACHED;
1195fcf3ce44SJohn Forte 	hba->flag |= FC_PT_TO_PT;
1196fcf3ce44SJohn Forte 
1197*8f23e9faSHans Rosenfeld 	bcopy((void *)sp, (void *)&port->fabric_sparam, sizeof (SERV_PARM));
1198*8f23e9faSHans Rosenfeld 
1199fcf3ce44SJohn Forte 	/* Save E_D_TOV ticks in nanoseconds */
1200fcf3ce44SJohn Forte 	if (sp->cmn.edtovResolution) {
1201fcf3ce44SJohn Forte 		hba->fc_edtov =
120282527734SSukumar Swaminathan 		    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1203fcf3ce44SJohn Forte 	} else {
120482527734SSukumar Swaminathan 		hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1205fcf3ce44SJohn Forte 	}
1206fcf3ce44SJohn Forte 
1207*8f23e9faSHans Rosenfeld 	/* Typically the FLOGI ACC rsp has the R_A_TOV value both sides use */
1208fcf3ce44SJohn Forte 
1209fcf3ce44SJohn Forte 	hba->flag &= ~FC_NPIV_SUPPORTED;
1210*8f23e9faSHans Rosenfeld 	(void) strlcpy(buffer, "npiv:Disabled.", len);
121182527734SSukumar Swaminathan 
1212*8f23e9faSHans Rosenfeld 	if (emlxs_wwn_cmp((uint8_t *)&sp->portName,
1213*8f23e9faSHans Rosenfeld 	    (uint8_t *)&port->wwpn) > 0) {
1214*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, " P2P Master.", len);
1215*8f23e9faSHans Rosenfeld 	} else {
1216*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, " P2P Slave.", len);
1217*8f23e9faSHans Rosenfeld 	}
1218fcf3ce44SJohn Forte 
1219fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1220fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1221*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, " fcsp:Unsupported", len);
1222fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current &&
1223fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1224*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, " fcsp:Supported", len);
1225fcf3ce44SJohn Forte 	} else {
1226*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, " fcsp:Disabled", len);
1227fcf3ce44SJohn Forte 	}
1228291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1229fcf3ce44SJohn Forte 
1230fcf3ce44SJohn Forte 	mutex_exit(&EMLXS_PORT_LOCK);
1231fcf3ce44SJohn Forte 
1232fcf3ce44SJohn Forte 	return (0);
1233fcf3ce44SJohn Forte 
123482527734SSukumar Swaminathan } /* emlxs_process_unsol_flogi() */
1235fcf3ce44SJohn Forte 
1236fcf3ce44SJohn Forte 
1237fcf3ce44SJohn Forte /* ARGSUSED */
1238fcf3ce44SJohn Forte static void
emlxs_handle_unsol_flogi(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)123982527734SSukumar Swaminathan emlxs_handle_unsol_flogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1240fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1241fcf3ce44SJohn Forte {
1242fcf3ce44SJohn Forte 	uint8_t *bp;
1243fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1244fcf3ce44SJohn Forte 	IOCB *iocb;
1245fcf3ce44SJohn Forte 	uint32_t sid;
1246fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1247fcf3ce44SJohn Forte 	char buffer[64];
1248fcf3ce44SJohn Forte 
1249fcf3ce44SJohn Forte 	buffer[0] = 0;
1250fcf3ce44SJohn Forte 
1251fcf3ce44SJohn Forte 	/* Perform processing of FLOGI payload */
1252*8f23e9faSHans Rosenfeld 	if (emlxs_process_unsol_flogi(port, iocbq, mp, size, buffer,
1253*8f23e9faSHans Rosenfeld 	    sizeof (buffer))) {
1254fcf3ce44SJohn Forte 		return;
1255fcf3ce44SJohn Forte 	}
1256291a2b48SSukumar Swaminathan 
1257fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1258fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1259fcf3ce44SJohn Forte 	bp = mp->virt;
1260fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1261fcf3ce44SJohn Forte 
1262*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1263*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 0);
1264fcf3ce44SJohn Forte 
1265fcf3ce44SJohn Forte 	if (ubp == NULL) {
1266fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1267291a2b48SSukumar Swaminathan 		    "FLOGI rcvd: sid=%x. Rejecting.", sid);
1268fcf3ce44SJohn Forte 
1269fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1270fcf3ce44SJohn Forte 		    ELS_CMD_FLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1271fcf3ce44SJohn Forte 
1272fcf3ce44SJohn Forte 		goto drop_it;
1273fcf3ce44SJohn Forte 	}
1274291a2b48SSukumar Swaminathan 
1275fcf3ce44SJohn Forte 	/*
1276fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1277fcf3ce44SJohn Forte 	 */
1278fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1279fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1280fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_FLOGI;
1281fcf3ce44SJohn Forte 
1282fcf3ce44SJohn Forte 	/*
1283fcf3ce44SJohn Forte 	 * Setup frame header
1284fcf3ce44SJohn Forte 	 */
1285fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1286*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
128782527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
128882527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1289fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
129082527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1291fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1292fcf3ce44SJohn Forte 
1293fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1294291a2b48SSukumar Swaminathan 	    "FLOGI: sid=%x buffer=%p token=%x %s", sid, ubp, ub_priv->token,
1295291a2b48SSukumar Swaminathan 	    buffer);
1296fcf3ce44SJohn Forte 
1297fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1298fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1299291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1300fcf3ce44SJohn Forte 
1301fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1302fcf3ce44SJohn Forte 
1303fcf3ce44SJohn Forte drop_it:
1304fcf3ce44SJohn Forte 
1305fcf3ce44SJohn Forte 	return;
1306fcf3ce44SJohn Forte 
130782527734SSukumar Swaminathan } /* emlxs_handle_unsol_flogi() */
1308fcf3ce44SJohn Forte 
1309fcf3ce44SJohn Forte 
1310fcf3ce44SJohn Forte 
1311fcf3ce44SJohn Forte /* This is shared by FCT driver */
1312fcf3ce44SJohn Forte extern uint32_t
emlxs_process_unsol_plogi(emlxs_port_t * port,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size,char * buffer,size_t len)1313291a2b48SSukumar Swaminathan emlxs_process_unsol_plogi(emlxs_port_t *port, IOCBQ *iocbq, MATCHMAP *mp,
1314*8f23e9faSHans Rosenfeld     uint32_t size, char *buffer, size_t len)
1315fcf3ce44SJohn Forte {
1316fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
1317fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
1318fcf3ce44SJohn Forte 	uint8_t *bp;
1319fcf3ce44SJohn Forte 	IOCB *iocb;
1320fcf3ce44SJohn Forte 	uint32_t sid;
1321*8f23e9faSHans Rosenfeld 	uint32_t did;
1322fcf3ce44SJohn Forte 	SERV_PARM *sp;
1323fcf3ce44SJohn Forte 	MAILBOXQ *mbox;
1324291a2b48SSukumar Swaminathan 	emlxs_vvl_fmt_t vvl;
132582527734SSukumar Swaminathan 	int rc;
1326fcf3ce44SJohn Forte 
1327fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1328*8f23e9faSHans Rosenfeld 	did = iocb->un.elsreq.myID;
1329fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1330fcf3ce44SJohn Forte 
1331fcf3ce44SJohn Forte 	if (size < (sizeof (SERV_PARM) + 4)) {
1332fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1333291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. Payload too small. %d<%d Rejecting.", sid,
1334291a2b48SSukumar Swaminathan 		    size, (sizeof (SERV_PARM) + 4));
1335fcf3ce44SJohn Forte 
1336fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1337fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_PROTOCOL_ERR, LSEXP_NOTHING_MORE);
1338fcf3ce44SJohn Forte 
1339fcf3ce44SJohn Forte 		return (1);
1340fcf3ce44SJohn Forte 	}
1341291a2b48SSukumar Swaminathan 
1342fcf3ce44SJohn Forte 	bp = mp->virt;
1343fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1344fcf3ce44SJohn Forte 
1345291a2b48SSukumar Swaminathan 	bzero((char *)&vvl, sizeof (emlxs_vvl_fmt_t));
1346fcf3ce44SJohn Forte 
134782527734SSukumar Swaminathan 	if (sp->VALID_VENDOR_VERSION) {
1348fcf3ce44SJohn Forte 
1349291a2b48SSukumar Swaminathan 		bcopy((caddr_t *)&sp->vendorVersion[0],
1350291a2b48SSukumar Swaminathan 		    (caddr_t *)&vvl, sizeof (emlxs_vvl_fmt_t));
135182527734SSukumar Swaminathan 		vvl.un0.word0 = LE_SWAP32(vvl.un0.word0);
135282527734SSukumar Swaminathan 		vvl.un1.word1 = LE_SWAP32(vvl.un1.word1);
1353291a2b48SSukumar Swaminathan 	}
1354291a2b48SSukumar Swaminathan 
1355*8f23e9faSHans Rosenfeld 	if ((port->mode == MODE_INITIATOR) &&
1356*8f23e9faSHans Rosenfeld 	    (port->flag & EMLXS_PORT_RESTRICTED)) {
1357291a2b48SSukumar Swaminathan 		uint32_t reject_it = 0;
1358291a2b48SSukumar Swaminathan 
1359291a2b48SSukumar Swaminathan 		/* If remote port is the virtual port, then reject it */
1360291a2b48SSukumar Swaminathan 		if ((vvl.un0.w0.oui == 0x0000C9) && (vvl.un1.w1.vport)) {
1361291a2b48SSukumar Swaminathan 			reject_it = 1;
1362fcf3ce44SJohn Forte 		}
1363291a2b48SSukumar Swaminathan 
1364291a2b48SSukumar Swaminathan 		/* If we are a virtual port and the remote device */
1365291a2b48SSukumar Swaminathan 		/* is not a switch, then reject it */
136682527734SSukumar Swaminathan 		else if (port->vpi && ((sid & FABRIC_DID_MASK) !=
136782527734SSukumar Swaminathan 		    FABRIC_DID_MASK)) {
1368fcf3ce44SJohn Forte 			reject_it = 1;
1369fcf3ce44SJohn Forte 		}
1370291a2b48SSukumar Swaminathan 
1371fcf3ce44SJohn Forte 		if (reject_it) {
1372fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1373fcf3ce44SJohn Forte 			    "PLOGI rcvd: sid=%x. Restricted. Rejecting.",
1374fcf3ce44SJohn Forte 			    sid);
1375fcf3ce44SJohn Forte 
1376fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1377fcf3ce44SJohn Forte 			    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC,
1378fcf3ce44SJohn Forte 			    LSEXP_NOTHING_MORE);
1379fcf3ce44SJohn Forte 
1380a9800bebSGarrett D'Amore 			/* Clear temporary RPI in firmware */
1381*8f23e9faSHans Rosenfeld 			if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
1382*8f23e9faSHans Rosenfeld 				(void) EMLXS_SLI_REG_DID(port, sid, sp,
1383a9800bebSGarrett D'Amore 				    NULL, NULL, (IOCBQ *)1);
1384a9800bebSGarrett D'Amore 			}
1385fcf3ce44SJohn Forte 
1386fcf3ce44SJohn Forte 			return (1);
1387fcf3ce44SJohn Forte 		}
1388fcf3ce44SJohn Forte 	}
1389fcf3ce44SJohn Forte 
1390fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1391fcf3ce44SJohn Forte 	if (emlxs_dhc_verify_login(port, sid, sp)) {
1392fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1393291a2b48SSukumar Swaminathan 		    "PLOGI: sid=%x. FCSP disabled. Rejecting.", sid);
1394fcf3ce44SJohn Forte 
1395fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1396fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1397fcf3ce44SJohn Forte 
1398fcf3ce44SJohn Forte 		return (1);
1399fcf3ce44SJohn Forte 	}
1400291a2b48SSukumar Swaminathan 
1401fcf3ce44SJohn Forte 	if (!sp->cmn.fcsp_support) {
1402*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Unsupported", len);
1403fcf3ce44SJohn Forte 	} else if (cfg[CFG_AUTH_ENABLE].current && cfg[CFG_AUTH_E2E].current &&
1404fcf3ce44SJohn Forte 	    (port->vpi == 0 || cfg[CFG_AUTH_NPIV].current)) {
1405*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Supported", len);
1406fcf3ce44SJohn Forte 	} else {
1407*8f23e9faSHans Rosenfeld 		(void) strlcat(buffer, "fcsp:Disabled", len);
1408fcf3ce44SJohn Forte 	}
1409291a2b48SSukumar Swaminathan #endif /* DHCHAP_SUPPORT */
1410fcf3ce44SJohn Forte 
1411fcf3ce44SJohn Forte 	/* Check if this was a point to point Plogi */
1412fcf3ce44SJohn Forte 	if (hba->flag & FC_PT_TO_PT) {
1413fcf3ce44SJohn Forte 		mutex_enter(&EMLXS_PORT_LOCK);
1414fcf3ce44SJohn Forte 
1415*8f23e9faSHans Rosenfeld 		port->did = did;
1416*8f23e9faSHans Rosenfeld 		port->rdid = sid;
1417fcf3ce44SJohn Forte 
1418fcf3ce44SJohn Forte 		/* Save E_D_TOV ticks in nanoseconds */
1419fcf3ce44SJohn Forte 		if (sp->cmn.edtovResolution) {
1420fcf3ce44SJohn Forte 			hba->fc_edtov =
142182527734SSukumar Swaminathan 			    (LE_SWAP32(sp->cmn.e_d_tov) + 999999) / 1000000;
1422fcf3ce44SJohn Forte 		} else {
142382527734SSukumar Swaminathan 			hba->fc_edtov = LE_SWAP32(sp->cmn.e_d_tov);
1424fcf3ce44SJohn Forte 		}
1425fcf3ce44SJohn Forte 
1426*8f23e9faSHans Rosenfeld 		/* Only E_D_TOV is valid for PLOGI in pt2pt mode */
1427fcf3ce44SJohn Forte 
1428fcf3ce44SJohn Forte 		mutex_exit(&EMLXS_PORT_LOCK);
1429fcf3ce44SJohn Forte 
1430*8f23e9faSHans Rosenfeld 		if (hba->sli_mode <= EMLXS_HBA_SLI3_MODE) {
1431*8f23e9faSHans Rosenfeld 			/* Update our service parms */
1432*8f23e9faSHans Rosenfeld 			if ((mbox = (MAILBOXQ *)emlxs_mem_get(hba,
1433*8f23e9faSHans Rosenfeld 			    MEM_MBOX))) {
1434*8f23e9faSHans Rosenfeld 				emlxs_mb_config_link(hba, mbox);
1435*8f23e9faSHans Rosenfeld 
1436*8f23e9faSHans Rosenfeld 				rc =  EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbox,
1437*8f23e9faSHans Rosenfeld 				    MBX_NOWAIT, 0);
1438*8f23e9faSHans Rosenfeld 				if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
1439*8f23e9faSHans Rosenfeld 					emlxs_mem_put(hba, MEM_MBOX,
1440*8f23e9faSHans Rosenfeld 					    (void *)mbox);
1441*8f23e9faSHans Rosenfeld 				}
1442291a2b48SSukumar Swaminathan 
1443*8f23e9faSHans Rosenfeld 			}
1444fcf3ce44SJohn Forte 		}
1445fcf3ce44SJohn Forte 	}
1446291a2b48SSukumar Swaminathan 
1447fcf3ce44SJohn Forte 	return (0);
1448fcf3ce44SJohn Forte 
144982527734SSukumar Swaminathan } /* emlxs_process_unsol_plogi() */
1450fcf3ce44SJohn Forte 
1451fcf3ce44SJohn Forte 
1452fcf3ce44SJohn Forte /* ARGSUSED */
1453fcf3ce44SJohn Forte static void
emlxs_handle_unsol_plogi(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)145482527734SSukumar Swaminathan emlxs_handle_unsol_plogi(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1455fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1456fcf3ce44SJohn Forte {
1457*8f23e9faSHans Rosenfeld 	emlxs_hba_t *hba = HBA;
1458fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1459fcf3ce44SJohn Forte 	uint8_t *bp;
1460fcf3ce44SJohn Forte 	IOCB *iocb;
1461fcf3ce44SJohn Forte 	uint32_t sid;
1462fcf3ce44SJohn Forte 	uint32_t did;
1463fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1464fcf3ce44SJohn Forte 	SERV_PARM *sp;
1465fcf3ce44SJohn Forte 	char buffer[64];
1466fcf3ce44SJohn Forte 
1467fcf3ce44SJohn Forte 	buffer[0] = 0;
1468fcf3ce44SJohn Forte 
1469fcf3ce44SJohn Forte 	/* Perform processing of PLOGI payload */
1470*8f23e9faSHans Rosenfeld 	if (emlxs_process_unsol_plogi(port, iocbq, mp, size, buffer,
1471*8f23e9faSHans Rosenfeld 	    sizeof (buffer))) {
1472fcf3ce44SJohn Forte 		return;
1473fcf3ce44SJohn Forte 	}
1474291a2b48SSukumar Swaminathan 
1475fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1476fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1477fcf3ce44SJohn Forte 	did = iocb->un.elsreq.myID;
1478fcf3ce44SJohn Forte 	bp = mp->virt;
1479fcf3ce44SJohn Forte 	sp = (SERV_PARM *)(bp + sizeof (uint32_t));
1480fcf3ce44SJohn Forte 	size = sizeof (SERV_PARM) + 4;
1481fcf3ce44SJohn Forte 
1482291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1483291a2b48SSukumar Swaminathan 	emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_PLOGI_RCV,
1484291a2b48SSukumar Swaminathan 	    (HBA_WWN *)&sp->portName, (HBA_WWN *)&sp->nodeName);
1485291a2b48SSukumar Swaminathan #endif
1486291a2b48SSukumar Swaminathan 
1487*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1488*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 0);
1489fcf3ce44SJohn Forte 
1490fcf3ce44SJohn Forte 	if (ubp == NULL) {
1491fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1492291a2b48SSukumar Swaminathan 		    "PLOGI rcvd: sid=%x. Rejecting.", sid);
1493fcf3ce44SJohn Forte 
1494fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1495fcf3ce44SJohn Forte 		    ELS_CMD_PLOGI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1496fcf3ce44SJohn Forte 
1497fcf3ce44SJohn Forte 		goto drop_it;
1498fcf3ce44SJohn Forte 	}
1499291a2b48SSukumar Swaminathan 
1500fcf3ce44SJohn Forte 	/*
1501fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1502fcf3ce44SJohn Forte 	 */
1503fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
1504fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1505fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PLOGI;
1506fcf3ce44SJohn Forte 
1507fcf3ce44SJohn Forte 	/*
1508fcf3ce44SJohn Forte 	 * Setup frame header
1509fcf3ce44SJohn Forte 	 */
1510fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1511*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
151282527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
151382527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1514fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
151582527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1516fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1517fcf3ce44SJohn Forte 
1518fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1519291a2b48SSukumar Swaminathan 	    "PLOGI: sid=%x did=%x buffer=%p token=%x %s", sid, did, ubp,
1520291a2b48SSukumar Swaminathan 	    ub_priv->token, buffer);
1521fcf3ce44SJohn Forte 
1522fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1523fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1524291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1525fcf3ce44SJohn Forte 
1526fcf3ce44SJohn Forte 	/* Create a new node and defer callback */
1527*8f23e9faSHans Rosenfeld 	if (EMLXS_SLI_REG_DID(port, sid, sp, NULL, ubp, NULL) == 0) {
1528fcf3ce44SJohn Forte 		/*
1529fcf3ce44SJohn Forte 		 * Defer completion of this pkt until login is complete
1530fcf3ce44SJohn Forte 		 */
1531fcf3ce44SJohn Forte 		goto drop_it;
1532fcf3ce44SJohn Forte 	}
1533291a2b48SSukumar Swaminathan 
1534fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1535fcf3ce44SJohn Forte 
1536fcf3ce44SJohn Forte drop_it:
1537fcf3ce44SJohn Forte 
1538fcf3ce44SJohn Forte 	return;
1539fcf3ce44SJohn Forte 
154082527734SSukumar Swaminathan } /* emlxs_handle_unsol_plogi() */
1541fcf3ce44SJohn Forte 
1542fcf3ce44SJohn Forte 
1543fcf3ce44SJohn Forte /* ARGSUSED */
1544fcf3ce44SJohn Forte static void
emlxs_handle_unsol_prli(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)154582527734SSukumar Swaminathan emlxs_handle_unsol_prli(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1546fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1547fcf3ce44SJohn Forte {
154882527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
154982527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1550fcf3ce44SJohn Forte 	IOCB *iocb;
1551fcf3ce44SJohn Forte 	uint32_t sid;
1552fcf3ce44SJohn Forte 	NODELIST *ndlp;
1553fcf3ce44SJohn Forte 	PRLI *npr;
1554fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1555fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1556a9800bebSGarrett D'Amore 	uint32_t task_retry_id;
1557fcf3ce44SJohn Forte 
1558fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1559fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1560*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, sid, 1);
1561fcf3ce44SJohn Forte 
1562fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1563fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1564291a2b48SSukumar Swaminathan 		    "PRLI: sid=%x: Node not found. Rejecting.", sid);
1565fcf3ce44SJohn Forte 
1566fcf3ce44SJohn Forte 		/* Auto reply to PRLI's */
1567fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1568fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1569fcf3ce44SJohn Forte 
1570fcf3ce44SJohn Forte 		goto drop_it;
1571fcf3ce44SJohn Forte 	}
1572291a2b48SSukumar Swaminathan 
1573fcf3ce44SJohn Forte 	/* If node exists then save FCP2 support */
1574fcf3ce44SJohn Forte 	npr = (PRLI *)((caddr_t)mp->virt + sizeof (uint32_t));
1575fcf3ce44SJohn Forte 
1576fcf3ce44SJohn Forte 	/* Check for FCP2 support */
1577fcf3ce44SJohn Forte 	if ((npr->prliType == PRLI_FCP_TYPE) && npr->targetFunc) {
1578a9800bebSGarrett D'Amore 		/* Clear FCP2 support if no ADISC support is requested */
1579a9800bebSGarrett D'Amore 		if (cfg[CFG_ADISC_SUPPORT].current == 0) {
1580a9800bebSGarrett D'Amore 			npr->ConfmComplAllowed = 0;
1581a9800bebSGarrett D'Amore 			npr->TaskRetryIdReq = 0;
1582a9800bebSGarrett D'Amore 			npr->Retry = 0;
1583a9800bebSGarrett D'Amore 		}
1584a9800bebSGarrett D'Amore 
1585fcf3ce44SJohn Forte 		/* Check for target */
1586fcf3ce44SJohn Forte 		if (npr->targetFunc) {
1587fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_TGT_DEVICE;
1588fcf3ce44SJohn Forte 		} else {
1589fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_TGT_DEVICE;
1590fcf3ce44SJohn Forte 		}
1591*8f23e9faSHans Rosenfeld #ifdef NODE_THROTTLE_SUPPORT
1592*8f23e9faSHans Rosenfeld 		emlxs_node_throttle_set(port, ndlp);
1593*8f23e9faSHans Rosenfeld #endif /* NODE_THROTTLE_SUPPORT */
1594fcf3ce44SJohn Forte 
1595fcf3ce44SJohn Forte 		/* Check for initiator */
1596fcf3ce44SJohn Forte 		if (npr->initiatorFunc) {
1597fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_INI_DEVICE;
1598fcf3ce44SJohn Forte 		} else {
1599fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_INI_DEVICE;
1600fcf3ce44SJohn Forte 		}
1601fcf3ce44SJohn Forte 
1602a9800bebSGarrett D'Amore 		/* If TRI support is not required then force */
1603a9800bebSGarrett D'Amore 		/* the task_retry_id value to one */
1604a9800bebSGarrett D'Amore 		if (cfg[CFG_TRI_REQUIRED].current == 0) {
1605a9800bebSGarrett D'Amore 			task_retry_id = 1;
1606a9800bebSGarrett D'Amore 		} else {
1607a9800bebSGarrett D'Amore 			task_retry_id = npr->TaskRetryIdReq;
1608a9800bebSGarrett D'Amore 		}
1609a9800bebSGarrett D'Amore 
1610fcf3ce44SJohn Forte 		/* Check for FCP2 target support */
1611a9800bebSGarrett D'Amore 		/* Retry and TaskRetryId bits are both required here */
1612a9800bebSGarrett D'Amore 		if (npr->targetFunc && npr->Retry && task_retry_id) {
1613fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1614fcf3ce44SJohn Forte 		} else {
1615fcf3ce44SJohn Forte 			ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
1616fcf3ce44SJohn Forte 		}
1617fcf3ce44SJohn Forte 	}
1618fcf3ce44SJohn Forte 
161982527734SSukumar Swaminathan #ifdef ULP_PATCH3
162082527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH3) {
162182527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
162282527734SSukumar Swaminathan 		    "PRLI: sid=%x. Accepting.", sid);
1623fcf3ce44SJohn Forte 
162482527734SSukumar Swaminathan 		/* Auto reply to PRLI's */
162582527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
162682527734SSukumar Swaminathan 		    ELS_CMD_PRLI, 0, 0);
162782527734SSukumar Swaminathan 		goto drop_it;
162882527734SSukumar Swaminathan 	}
162982527734SSukumar Swaminathan #endif /* ULP_PATCH3 */
1630fcf3ce44SJohn Forte 
1631fcf3ce44SJohn Forte 	/* Tell ULP about it */
1632*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1633*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 0);
1634fcf3ce44SJohn Forte 
1635fcf3ce44SJohn Forte 	if (ubp == NULL) {
1636fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1637291a2b48SSukumar Swaminathan 		    "PRLI rcvd: sid=%x. Rejecting.", sid);
1638fcf3ce44SJohn Forte 
1639fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1640fcf3ce44SJohn Forte 		    ELS_CMD_PRLI, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1641fcf3ce44SJohn Forte 
1642fcf3ce44SJohn Forte 		goto drop_it;
1643fcf3ce44SJohn Forte 	}
1644291a2b48SSukumar Swaminathan 
1645fcf3ce44SJohn Forte 	/*
1646fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1647fcf3ce44SJohn Forte 	 */
1648fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1649fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1650fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLI;
1651fcf3ce44SJohn Forte 
1652fcf3ce44SJohn Forte 	/*
1653fcf3ce44SJohn Forte 	 * Setup frame header
1654fcf3ce44SJohn Forte 	 */
1655fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1656*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
165782527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
165882527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1659fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
166082527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1661fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1662fcf3ce44SJohn Forte 
1663fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1664291a2b48SSukumar Swaminathan 	    "PRLI: sid=%x buffer=%p token=%x info=%02x", sid, ubp,
1665291a2b48SSukumar Swaminathan 	    ub_priv->token, ndlp->nlp_fcp_info);
1666fcf3ce44SJohn Forte 
1667fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1668fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1669291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1670fcf3ce44SJohn Forte 
1671fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1672fcf3ce44SJohn Forte 
1673fcf3ce44SJohn Forte drop_it:
1674fcf3ce44SJohn Forte 
1675fcf3ce44SJohn Forte 	return;
1676fcf3ce44SJohn Forte 
167782527734SSukumar Swaminathan } /* emlxs_handle_unsol_prli() */
1678fcf3ce44SJohn Forte 
1679fcf3ce44SJohn Forte 
1680fcf3ce44SJohn Forte /* ARGSUSED */
1681fcf3ce44SJohn Forte static void
emlxs_handle_unsol_auth(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)168282527734SSukumar Swaminathan emlxs_handle_unsol_auth(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1683fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1684fcf3ce44SJohn Forte {
1685fcf3ce44SJohn Forte 	IOCB *iocb;
1686fcf3ce44SJohn Forte 	uint32_t sid;
1687fcf3ce44SJohn Forte 	NODELIST *ndlp;
1688fcf3ce44SJohn Forte 
1689fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1690fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1691fcf3ce44SJohn Forte 
1692fcf3ce44SJohn Forte #ifdef DHCHAP_SUPPORT
1693*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, sid, 1);
1694fcf3ce44SJohn Forte 
1695fcf3ce44SJohn Forte 	if (!ndlp || !ndlp->nlp_active) {
1696fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1697291a2b48SSukumar Swaminathan 		    "AUTH: sid=%x: Node not found. Rejecting.", sid);
1698fcf3ce44SJohn Forte 
1699fcf3ce44SJohn Forte 		/* Auto reply to AUTH_ELS's */
1700fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1701fcf3ce44SJohn Forte 		    ELS_CMD_AUTH, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1702fcf3ce44SJohn Forte 
1703fcf3ce44SJohn Forte 		goto drop_it;
1704fcf3ce44SJohn Forte 	}
1705291a2b48SSukumar Swaminathan 
1706291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg, "AUTH: sid=%x", sid);
1707fcf3ce44SJohn Forte 
170882527734SSukumar Swaminathan 	(void) emlxs_dhchap_state_machine(port, cp, iocbq, mp, ndlp,
1709fcf3ce44SJohn Forte 	    NODE_EVENT_RCV_AUTH_MSG);
1710fcf3ce44SJohn Forte #else
1711fcf3ce44SJohn Forte 
1712fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1713291a2b48SSukumar Swaminathan 	    "AUTH: sid=%x: Rejecting.", sid);
1714fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, ELS_CMD_AUTH,
1715fcf3ce44SJohn Forte 	    LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
1716fcf3ce44SJohn Forte 
1717291a2b48SSukumar Swaminathan #endif /* DHCAHP_SUPPORT */
1718fcf3ce44SJohn Forte 
1719fcf3ce44SJohn Forte drop_it:
1720fcf3ce44SJohn Forte 
1721fcf3ce44SJohn Forte 	return;
1722fcf3ce44SJohn Forte 
172382527734SSukumar Swaminathan } /* emlxs_handle_unsol_auth() */
1724fcf3ce44SJohn Forte 
1725fcf3ce44SJohn Forte 
1726fcf3ce44SJohn Forte /* ARGSUSED */
1727fcf3ce44SJohn Forte static void
emlxs_handle_unsol_adisc(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)172882527734SSukumar Swaminathan emlxs_handle_unsol_adisc(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1729fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1730fcf3ce44SJohn Forte {
1731291a2b48SSukumar Swaminathan 	IOCB		*iocb;
1732291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1733291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
1734291a2b48SSukumar Swaminathan #endif
1735291a2b48SSukumar Swaminathan 	uint32_t	sid;
1736fcf3ce44SJohn Forte 
1737fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1738fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1739fcf3ce44SJohn Forte 
1740291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1741*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, sid, 1);
1742291a2b48SSukumar Swaminathan 
1743291a2b48SSukumar Swaminathan 	if (ndlp) {
1744291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port, SD_ELS_SUBCATEGORY_ADISC_RCV,
1745291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1746291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_nodename);
1747291a2b48SSukumar Swaminathan 	}
1748291a2b48SSukumar Swaminathan #endif
1749291a2b48SSukumar Swaminathan 
1750fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1751291a2b48SSukumar Swaminathan 	    "ADISC: sid=%x: Accepting.", sid);
1752fcf3ce44SJohn Forte 	(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC, ELS_CMD_ADISC, 0, 0);
1753fcf3ce44SJohn Forte 
1754fcf3ce44SJohn Forte 	return;
1755fcf3ce44SJohn Forte 
175682527734SSukumar Swaminathan } /* emlxs_handle_unsol_adisc() */
1757fcf3ce44SJohn Forte 
1758fcf3ce44SJohn Forte 
1759fcf3ce44SJohn Forte /* ARGSUSED */
1760fcf3ce44SJohn Forte static void
emlxs_handle_unsol_prlo(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)176182527734SSukumar Swaminathan emlxs_handle_unsol_prlo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1762fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1763fcf3ce44SJohn Forte {
176482527734SSukumar Swaminathan 	emlxs_hba_t	*hba = HBA;
176582527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1766fcf3ce44SJohn Forte 	IOCB *iocb;
1767fcf3ce44SJohn Forte 	uint32_t sid;
1768fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1769fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1770fcf3ce44SJohn Forte 	NODELIST *ndlp;
1771fcf3ce44SJohn Forte 
1772fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1773fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1774fcf3ce44SJohn Forte 
1775fcf3ce44SJohn Forte 	/* Get the node */
1776*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, sid, 1);
1777fcf3ce44SJohn Forte 
1778291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1779291a2b48SSukumar Swaminathan 	if (ndlp) {
1780291a2b48SSukumar Swaminathan 		emlxs_log_sd_prlo_event(port, (HBA_WWN *)&ndlp->nlp_portname);
1781291a2b48SSukumar Swaminathan 	}
1782291a2b48SSukumar Swaminathan #endif
1783291a2b48SSukumar Swaminathan 
1784291a2b48SSukumar Swaminathan #ifdef ULP_PATCH4
178582527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH4) {
1786291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
178782527734SSukumar Swaminathan 		if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
178882527734SSukumar Swaminathan 			/* Check if this is a SCSI target */
178982527734SSukumar Swaminathan 			if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
179082527734SSukumar Swaminathan 				/* This is a SCSI target */
179182527734SSukumar Swaminathan 
179282527734SSukumar Swaminathan 				/* If only one node is present, then we can */
179382527734SSukumar Swaminathan 				/* conclude that we are direct attached */
179482527734SSukumar Swaminathan 				/* to a target */
179582527734SSukumar Swaminathan 				if (port->node_count == 1) {
179682527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
179782527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
179882527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
179982527734SSukumar Swaminathan 					    "reseting link.",
180082527734SSukumar Swaminathan 					    sid);
1801291a2b48SSukumar Swaminathan 
180282527734SSukumar Swaminathan 					/* Send Acc */
180382527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
180482527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1805fcf3ce44SJohn Forte 
180682527734SSukumar Swaminathan 					/* Spawn a thread to reset the link */
180782527734SSukumar Swaminathan 					emlxs_thread_spawn(hba,
180882527734SSukumar Swaminathan 					    emlxs_reset_link_thread,
180982527734SSukumar Swaminathan 					    NULL, NULL);
1810fcf3ce44SJohn Forte 
181182527734SSukumar Swaminathan 					goto drop_it;
1812fcf3ce44SJohn Forte 
181382527734SSukumar Swaminathan 				}
181482527734SSukumar Swaminathan 				/* Check if fabric is present */
181582527734SSukumar Swaminathan 				else if (hba->flag & FC_FABRIC_ATTACHED) {
181682527734SSukumar Swaminathan 					/* Auto reply to PRLO */
181782527734SSukumar Swaminathan 					EMLXS_MSGF(EMLXS_CONTEXT,
181882527734SSukumar Swaminathan 					    &emlxs_unsol_els_msg,
181982527734SSukumar Swaminathan 					    "PRLO: sid=%x. Accepting and " \
182082527734SSukumar Swaminathan 					    "generating RSCN.",
182182527734SSukumar Swaminathan 					    sid);
1822fcf3ce44SJohn Forte 
182382527734SSukumar Swaminathan 					/* Send Acc */
182482527734SSukumar Swaminathan 					(void) emlxs_els_reply(port, iocbq,
182582527734SSukumar Swaminathan 					    ELS_CMD_ACC, ELS_CMD_PRLO, 0, 0);
1826fcf3ce44SJohn Forte 
182782527734SSukumar Swaminathan 					/* Generate an RSCN to wakeup ULP */
182882527734SSukumar Swaminathan 					(void) emlxs_generate_rscn(port, sid);
1829fcf3ce44SJohn Forte 
183082527734SSukumar Swaminathan 					goto drop_it;
183182527734SSukumar Swaminathan 				}
183282527734SSukumar Swaminathan 			}
1833fcf3ce44SJohn Forte 		}
1834291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1835fcf3ce44SJohn Forte 
183682527734SSukumar Swaminathan 		/* Auto reply to PRLO */
183782527734SSukumar Swaminathan 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
183882527734SSukumar Swaminathan 		    "PRLO: sid=%x. Accepting.", sid);
1839fcf3ce44SJohn Forte 
184082527734SSukumar Swaminathan 		/* Send Acc */
184182527734SSukumar Swaminathan 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
184282527734SSukumar Swaminathan 		    ELS_CMD_PRLO, 0, 0);
1843fcf3ce44SJohn Forte 
184482527734SSukumar Swaminathan 		goto drop_it;
184582527734SSukumar Swaminathan 	}
184682527734SSukumar Swaminathan #endif /* ULP_PATCH4 */
1847fcf3ce44SJohn Forte 
1848fcf3ce44SJohn Forte 	/* Tell ULP about it */
1849fcf3ce44SJohn Forte 
1850*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1851*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 0);
1852fcf3ce44SJohn Forte 
1853fcf3ce44SJohn Forte 	if (ubp == NULL) {
1854fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1855291a2b48SSukumar Swaminathan 		    "PRLO recvd: sid=%x. Rejecting.", sid);
1856fcf3ce44SJohn Forte 
1857fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1858fcf3ce44SJohn Forte 		    ELS_CMD_PRLO, LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
1859fcf3ce44SJohn Forte 
1860fcf3ce44SJohn Forte 		goto drop_it;
1861fcf3ce44SJohn Forte 	}
1862291a2b48SSukumar Swaminathan 
1863fcf3ce44SJohn Forte 	/*
1864fcf3ce44SJohn Forte 	 * Setup unsolicited buffer and pass it up
1865fcf3ce44SJohn Forte 	 */
1866fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1867fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1868fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_PRLO;
1869fcf3ce44SJohn Forte 
1870fcf3ce44SJohn Forte 	/*
1871fcf3ce44SJohn Forte 	 * Setup frame header
1872fcf3ce44SJohn Forte 	 */
1873fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1874*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
187582527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
187682527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1877fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
187882527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
1879fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
1880fcf3ce44SJohn Forte 
1881fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
1882291a2b48SSukumar Swaminathan 	    "PRLO: sid=%x buffeiocbr=%p token=%x.", sid, ubp, ub_priv->token);
1883fcf3ce44SJohn Forte 
1884fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
1885fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
1886291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
1887fcf3ce44SJohn Forte 
1888fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
1889fcf3ce44SJohn Forte 
1890fcf3ce44SJohn Forte drop_it:
1891fcf3ce44SJohn Forte 
1892fcf3ce44SJohn Forte 	return;
1893fcf3ce44SJohn Forte 
189482527734SSukumar Swaminathan } /* emlxs_handle_unsol_prlo() */
1895fcf3ce44SJohn Forte 
1896fcf3ce44SJohn Forte 
1897fcf3ce44SJohn Forte /* ARGSUSED */
1898fcf3ce44SJohn Forte static void
emlxs_handle_unsol_logo(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)189982527734SSukumar Swaminathan emlxs_handle_unsol_logo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
1900fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
1901fcf3ce44SJohn Forte {
1902fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
190382527734SSukumar Swaminathan 	emlxs_config_t	*cfg = &CFG;
1904fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
1905fcf3ce44SJohn Forte 	IOCB *iocb;
1906fcf3ce44SJohn Forte 	uint32_t sid;
1907fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
1908fcf3ce44SJohn Forte 	uint32_t reply_sent = 0;
1909fcf3ce44SJohn Forte 	NODELIST *ndlp;
1910fcf3ce44SJohn Forte 
1911fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
1912fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
1913fcf3ce44SJohn Forte 
1914*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, sid, 1);
1915fcf3ce44SJohn Forte 
1916291a2b48SSukumar Swaminathan #ifdef SAN_DIAG_SUPPORT
1917291a2b48SSukumar Swaminathan 	if (ndlp) {
1918291a2b48SSukumar Swaminathan 		emlxs_log_sd_basic_els_event(port,  SD_ELS_SUBCATEGORY_LOGO_RCV,
1919291a2b48SSukumar Swaminathan 		    (HBA_WWN *)&ndlp->nlp_portname,
1920291a2b48SSukumar Swaminathan 		    (HBA_WWN *)((uint32_t *)mp->virt + 2));
1921291a2b48SSukumar Swaminathan 	}
1922291a2b48SSukumar Swaminathan #endif
1923291a2b48SSukumar Swaminathan 
1924*8f23e9faSHans Rosenfeld 	EMLXS_SET_DFC_STATE(ndlp, NODE_LOGOUT);
1925*8f23e9faSHans Rosenfeld 
1926291a2b48SSukumar Swaminathan #ifdef ULP_PATCH6
192782527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH6) {
192882527734SSukumar Swaminathan 		/* Check if this is a SCSI target */
192982527734SSukumar Swaminathan 		if (ndlp && (ndlp->nlp_fcp_info & NLP_FCP_TGT_DEVICE)) {
193082527734SSukumar Swaminathan 			/* This is a SCSI target */
1931291a2b48SSukumar Swaminathan 
193282527734SSukumar Swaminathan 			/* If only one node is present, then we can */
193382527734SSukumar Swaminathan 			/* conclude that we are direct attached to a target */
193482527734SSukumar Swaminathan 			if (port->node_count == 1) {
193582527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
193682527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and "\
193782527734SSukumar Swaminathan 				    "reseting link.", sid);
1938fcf3ce44SJohn Forte 
193982527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq,
194082527734SSukumar Swaminathan 				    ELS_CMD_ACC, ELS_CMD_LOGO, 0, 0);
1941fcf3ce44SJohn Forte 
194282527734SSukumar Swaminathan 				/* Spawn a thread to reset the link */
194382527734SSukumar Swaminathan 				emlxs_thread_spawn(hba, emlxs_reset_link_thread,
194482527734SSukumar Swaminathan 				    NULL, NULL);
1945fcf3ce44SJohn Forte 
1946fcf3ce44SJohn Forte 				goto drop_it;
1947fcf3ce44SJohn Forte 			}
194882527734SSukumar Swaminathan 			/* Check if fabric node is present */
194982527734SSukumar Swaminathan 			else if (hba->flag & FC_FABRIC_ATTACHED) {
195082527734SSukumar Swaminathan 				/* Send reply ourselves */
195182527734SSukumar Swaminathan 				/* We will block all attempts */
195282527734SSukumar Swaminathan 				/* for ULP to reply to a LOGO */
195382527734SSukumar Swaminathan 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
195482527734SSukumar Swaminathan 				    "LOGO: sid=%x. Accepting and " \
195582527734SSukumar Swaminathan 				    "generating RSCN.", sid);
195682527734SSukumar Swaminathan 
195782527734SSukumar Swaminathan 				(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
195882527734SSukumar Swaminathan 				    ELS_CMD_LOGO, 0, 0);
195982527734SSukumar Swaminathan 
196082527734SSukumar Swaminathan 				/* Generate an RSCN to wakeup ULP */
196182527734SSukumar Swaminathan 				if (emlxs_generate_rscn(port, sid)
196282527734SSukumar Swaminathan 				    == FC_SUCCESS) {
196382527734SSukumar Swaminathan 					goto drop_it;
196482527734SSukumar Swaminathan 				}
1965291a2b48SSukumar Swaminathan 
196682527734SSukumar Swaminathan 				reply_sent = 1;
196782527734SSukumar Swaminathan 			}
1968fcf3ce44SJohn Forte 		}
1969291a2b48SSukumar Swaminathan 	}
1970291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
1971fcf3ce44SJohn Forte 
1972*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
1973*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 1);
1974fcf3ce44SJohn Forte 
1975fcf3ce44SJohn Forte 	if (ubp == NULL) {
1976fcf3ce44SJohn Forte 		if (!reply_sent) {
1977fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
1978291a2b48SSukumar Swaminathan 			    "LOGO rcvd: sid=%x. Rejecting.", sid);
1979fcf3ce44SJohn Forte 
1980fcf3ce44SJohn Forte 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
1981fcf3ce44SJohn Forte 			    ELS_CMD_LOGO, LSRJT_LOGICAL_BSY,
1982fcf3ce44SJohn Forte 			    LSEXP_OUT_OF_RESOURCE);
1983fcf3ce44SJohn Forte 		}
1984291a2b48SSukumar Swaminathan 
1985fcf3ce44SJohn Forte 		goto drop_it;
1986fcf3ce44SJohn Forte 
1987fcf3ce44SJohn Forte 	}
1988291a2b48SSukumar Swaminathan 
1989fcf3ce44SJohn Forte 	/* Setup unsolicited buffer and pass it up */
1990fcf3ce44SJohn Forte 	bcopy(mp->virt, ubp->ub_buffer, size);
1991fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
1992fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_LOGO;
1993fcf3ce44SJohn Forte 
1994fcf3ce44SJohn Forte 	/* Setup frame header */
1995fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
1996*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
199782527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
199882527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
1999fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
200082527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
2001fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2002fcf3ce44SJohn Forte 
2003fcf3ce44SJohn Forte #ifdef ULP_PATCH2
200482527734SSukumar Swaminathan 	if (cfg[CFG_ENABLE_PATCH].current & ULP_PATCH2) {
200582527734SSukumar Swaminathan 		if (!reply_sent) {
200682527734SSukumar Swaminathan 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
200782527734SSukumar Swaminathan 			    "LOGO: sid=%x buffer=%p token=%x. Accepting.",
200882527734SSukumar Swaminathan 			    sid, ubp, ub_priv->token);
2009fcf3ce44SJohn Forte 
201082527734SSukumar Swaminathan 			ub_priv->flags |= EMLXS_UB_REPLY;
2011fcf3ce44SJohn Forte 
201282527734SSukumar Swaminathan 			/* Send Acc */
201382527734SSukumar Swaminathan 			/* Send reply ourselves because ULP */
201482527734SSukumar Swaminathan 			/* doesn't always reply to these */
201582527734SSukumar Swaminathan 			/* We ll block attempts for ULP to reply to a LOGO */
201682527734SSukumar Swaminathan 			(void) emlxs_els_reply(port, iocbq, ELS_CMD_ACC,
201782527734SSukumar Swaminathan 			    ELS_CMD_LOGO, 0, 0);
201882527734SSukumar Swaminathan 			reply_sent = 1;
201982527734SSukumar Swaminathan 		}
2020fcf3ce44SJohn Forte 	}
202182527734SSukumar Swaminathan #endif /* ULP_PATCH2 */
2022fcf3ce44SJohn Forte 
2023fcf3ce44SJohn Forte 	if (!reply_sent) {
2024fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2025291a2b48SSukumar Swaminathan 		    "LOGO: sid=%x buffer=%p token=%x.", sid, ubp,
2026291a2b48SSukumar Swaminathan 		    ub_priv->token);
2027fcf3ce44SJohn Forte 	}
2028fcf3ce44SJohn Forte 
2029fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2030fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2031291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2032fcf3ce44SJohn Forte 
2033a9800bebSGarrett D'Amore 	/* Unregister the node */
203482527734SSukumar Swaminathan 	if ((sid & FABRIC_DID_MASK) == FABRIC_DID_MASK) {
2035a9800bebSGarrett D'Amore 		if (ndlp) {
2036*8f23e9faSHans Rosenfeld 			if (EMLXS_SLI_UNREG_NODE(port, ndlp, NULL,
2037a9800bebSGarrett D'Amore 			    ubp, NULL) == 0) {
2038a9800bebSGarrett D'Amore 				/*
2039a9800bebSGarrett D'Amore 				 * Deferred completion of this ubp
2040a9800bebSGarrett D'Amore 				 * until unreg login is complete
2041a9800bebSGarrett D'Amore 				 */
2042a9800bebSGarrett D'Amore 				return;
2043a9800bebSGarrett D'Amore 			}
2044fcf3ce44SJohn Forte 		}
2045fcf3ce44SJohn Forte 	}
2046291a2b48SSukumar Swaminathan 
2047fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2048fcf3ce44SJohn Forte 
2049fcf3ce44SJohn Forte drop_it:
2050fcf3ce44SJohn Forte 
2051fcf3ce44SJohn Forte 	return;
2052fcf3ce44SJohn Forte 
205382527734SSukumar Swaminathan } /* emlxs_handle_unsol_logo() */
2054291a2b48SSukumar Swaminathan 
2055fcf3ce44SJohn Forte 
2056fcf3ce44SJohn Forte 
2057fcf3ce44SJohn Forte /* ARGSUSED */
2058fcf3ce44SJohn Forte static void
emlxs_handle_unsol_gen_cmd(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)205982527734SSukumar Swaminathan emlxs_handle_unsol_gen_cmd(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2060fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
2061fcf3ce44SJohn Forte {
2062fcf3ce44SJohn Forte 	uint8_t *bp;
2063fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
2064fcf3ce44SJohn Forte 	IOCB *iocb;
2065fcf3ce44SJohn Forte 	uint32_t *lp;
2066fcf3ce44SJohn Forte 	uint32_t cmd;
2067fcf3ce44SJohn Forte 	uint32_t sid;
2068fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
2069fcf3ce44SJohn Forte 
2070fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2071fcf3ce44SJohn Forte 	sid = iocb->un.elsreq.remoteID;
2072fcf3ce44SJohn Forte 
2073fcf3ce44SJohn Forte 	bp = mp->virt;
2074fcf3ce44SJohn Forte 	lp = (uint32_t *)bp;
2075fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2076fcf3ce44SJohn Forte 
2077*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, size,
2078*8f23e9faSHans Rosenfeld 	    FC_TYPE_EXTENDED_LS, 0);
2079fcf3ce44SJohn Forte 
2080fcf3ce44SJohn Forte 	if (ubp == NULL) {
2081fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
2082291a2b48SSukumar Swaminathan 		    "%s rcvd: sid=%x: Rejecting.", emlxs_elscmd_xlate(cmd),
2083291a2b48SSukumar Swaminathan 		    sid);
2084fcf3ce44SJohn Forte 
2085fcf3ce44SJohn Forte 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT, cmd,
2086fcf3ce44SJohn Forte 		    LSRJT_LOGICAL_BSY, LSEXP_OUT_OF_RESOURCE);
2087fcf3ce44SJohn Forte 
2088fcf3ce44SJohn Forte 		goto drop_it;
2089fcf3ce44SJohn Forte 	}
2090291a2b48SSukumar Swaminathan 
2091fcf3ce44SJohn Forte 	bcopy(bp, ubp->ub_buffer, size);
2092fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
2093fcf3ce44SJohn Forte 	ub_priv->cmd = cmd;
2094fcf3ce44SJohn Forte 
2095fcf3ce44SJohn Forte 	/* Setup frame header */
2096fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
2097*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
209882527734SSukumar Swaminathan 	ubp->ub_frame.s_id = LE_SWAP24_LO(iocb->un.elsreq.remoteID);
209982527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2100fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
210182527734SSukumar Swaminathan 	ubp->ub_frame.rx_id = iocb->ULPCONTEXT;
2102fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2103fcf3ce44SJohn Forte 
2104fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2105291a2b48SSukumar Swaminathan 	    "%s: sid=%x buffer=%p token=%x.", emlxs_elscmd_xlate(cmd), sid,
2106291a2b48SSukumar Swaminathan 	    ubp, ub_priv->token);
2107fcf3ce44SJohn Forte 
2108fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2109fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2110291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2111fcf3ce44SJohn Forte 
2112fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2113fcf3ce44SJohn Forte 
2114fcf3ce44SJohn Forte drop_it:
2115fcf3ce44SJohn Forte 
2116fcf3ce44SJohn Forte 	return;
2117fcf3ce44SJohn Forte 
211882527734SSukumar Swaminathan } /* emlxs_handle_unsol_gen_cmd() */
2119fcf3ce44SJohn Forte 
2120fcf3ce44SJohn Forte 
2121a9800bebSGarrett D'Amore /* ARGSUSED */
2122a9800bebSGarrett D'Amore static void
emlxs_handle_unsol_echo(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)2123*8f23e9faSHans Rosenfeld emlxs_handle_unsol_echo(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2124a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2125a9800bebSGarrett D'Amore {
2126a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2127a9800bebSGarrett D'Amore 	uint8_t *bp;
2128a9800bebSGarrett D'Amore 	IOCB *iocb;
2129a9800bebSGarrett D'Amore 	uint32_t *lp;
2130a9800bebSGarrett D'Amore 	uint32_t sid;
2131a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2132a9800bebSGarrett D'Amore 	uint32_t cmd;
2133a9800bebSGarrett D'Amore 
2134a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2135a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2136a9800bebSGarrett D'Amore 
2137a9800bebSGarrett D'Amore 	bp = mp->virt;
2138a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2139a9800bebSGarrett D'Amore 	cmd = *lp & ELS_CMD_MASK;
2140a9800bebSGarrett D'Amore 
2141a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2142a9800bebSGarrett D'Amore 	    size, 0, 0, KM_NOSLEEP))) {
2143a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2144a9800bebSGarrett D'Amore 		    "ECHO: sid=%x. Unable to allocate pkt. Rejecting.",
2145a9800bebSGarrett D'Amore 		    sid);
2146a9800bebSGarrett D'Amore 
2147a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2148a9800bebSGarrett D'Amore 		    ELS_CMD_ECHO, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2149a9800bebSGarrett D'Amore 		return;
2150a9800bebSGarrett D'Amore 	}
2151a9800bebSGarrett D'Amore 
2152a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2153a9800bebSGarrett D'Amore 	    "ECHO: sid=%x. Accepting.",
2154a9800bebSGarrett D'Amore 	    sid);
2155a9800bebSGarrett D'Amore 
2156a9800bebSGarrett D'Amore 	/* Common initialization */
2157a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2158a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2159a9800bebSGarrett D'Amore 
2160a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2161a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2162a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2163a9800bebSGarrett D'Amore 	}
2164a9800bebSGarrett D'Amore 
2165a9800bebSGarrett D'Amore 	/* Build the fc header */
2166a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2167a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2168a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2169a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2170a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2171a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2172a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2173a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2174a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2175a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2176a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2177a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2178a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2179a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2180a9800bebSGarrett D'Amore 
2181a9800bebSGarrett D'Amore 	/* Build the response */
2182a9800bebSGarrett D'Amore 	*lp = ELS_CMD_ACC;
2183a9800bebSGarrett D'Amore 	bcopy(lp, pkt->pkt_cmd, size);
2184a9800bebSGarrett D'Amore 
2185a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2186a9800bebSGarrett D'Amore 		/* Free the pkt */
2187a9800bebSGarrett D'Amore 		emlxs_pkt_free(pkt);
2188a9800bebSGarrett D'Amore 		emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2189a9800bebSGarrett D'Amore 	}
2190a9800bebSGarrett D'Amore 
2191a9800bebSGarrett D'Amore 	return;
2192a9800bebSGarrett D'Amore 
2193*8f23e9faSHans Rosenfeld } /* emlxs_handle_unsol_echo() */
2194a9800bebSGarrett D'Amore 
2195a9800bebSGarrett D'Amore 
2196a9800bebSGarrett D'Amore /* ARGSUSED */
2197a9800bebSGarrett D'Amore static void
emlxs_handle_unsol_rtv(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)2198*8f23e9faSHans Rosenfeld emlxs_handle_unsol_rtv(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2199a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2200a9800bebSGarrett D'Amore {
2201a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2202a9800bebSGarrett D'Amore 	uint8_t *bp;
2203a9800bebSGarrett D'Amore 	IOCB *iocb;
2204a9800bebSGarrett D'Amore 	uint32_t *lp;
2205a9800bebSGarrett D'Amore 	uint32_t sid;
2206a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2207a9800bebSGarrett D'Amore 	uint32_t cmd;
2208a9800bebSGarrett D'Amore 	SERV_PARM *sp;
2209a9800bebSGarrett D'Amore 
2210a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2211a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2212a9800bebSGarrett D'Amore 
2213a9800bebSGarrett D'Amore 	bp = mp->virt;
2214a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2215a9800bebSGarrett D'Amore 	cmd = *lp & ELS_CMD_MASK;
2216a9800bebSGarrett D'Amore 
2217a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2218a9800bebSGarrett D'Amore 	    (4 * sizeof (uint32_t)), 0, 0, KM_NOSLEEP))) {
2219a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2220a9800bebSGarrett D'Amore 		    "RTV: sid=%x. Unable to allocate pkt. Rejecting.",
2221a9800bebSGarrett D'Amore 		    sid);
2222a9800bebSGarrett D'Amore 
2223a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2224a9800bebSGarrett D'Amore 		    ELS_CMD_RTV, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2225a9800bebSGarrett D'Amore 		return;
2226a9800bebSGarrett D'Amore 	}
2227a9800bebSGarrett D'Amore 
2228a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2229a9800bebSGarrett D'Amore 	    "RTV: sid=%x. Accepting.",
2230a9800bebSGarrett D'Amore 	    emlxs_elscmd_xlate(cmd),
2231a9800bebSGarrett D'Amore 	    sid);
2232a9800bebSGarrett D'Amore 
2233a9800bebSGarrett D'Amore 	/* Common initialization */
2234a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2235a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2236a9800bebSGarrett D'Amore 
2237a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2238a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2239a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2240a9800bebSGarrett D'Amore 	}
2241a9800bebSGarrett D'Amore 
2242a9800bebSGarrett D'Amore 	/* Build the fc header */
2243a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2244a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2245a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2246a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2247a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2248a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2249a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2250a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2251a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2252a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2253a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2254a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2255a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2256a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2257a9800bebSGarrett D'Amore 
2258a9800bebSGarrett D'Amore 	/* Build the response */
2259*8f23e9faSHans Rosenfeld 	sp = (SERV_PARM *)&port->fabric_sparam;
2260a9800bebSGarrett D'Amore 	lp = (uint32_t *)pkt->pkt_cmd;
2261a9800bebSGarrett D'Amore 	lp[0] = ELS_CMD_ACC;
2262a9800bebSGarrett D'Amore 	lp[1] = LE_SWAP32(sp->cmn.w2.r_a_tov);
2263a9800bebSGarrett D'Amore 	lp[2] = LE_SWAP32(sp->cmn.e_d_tov);
2264*8f23e9faSHans Rosenfeld 	lp[3] = sp->cmn.edtovResolution << 26;
2265a9800bebSGarrett D'Amore 
2266a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2267a9800bebSGarrett D'Amore 		/* Free the pkt */
2268a9800bebSGarrett D'Amore 		emlxs_pkt_free(pkt);
2269a9800bebSGarrett D'Amore 		emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2270a9800bebSGarrett D'Amore 	}
2271a9800bebSGarrett D'Amore 
2272a9800bebSGarrett D'Amore 	return;
2273a9800bebSGarrett D'Amore 
2274*8f23e9faSHans Rosenfeld } /* emlxs_handle_unsol_rtv() */
2275a9800bebSGarrett D'Amore 
2276a9800bebSGarrett D'Amore 
2277a9800bebSGarrett D'Amore /* ARGSUSED */
2278a9800bebSGarrett D'Amore static void
emlxs_rls_rsp_thread(emlxs_hba_t * hba,void * arg1,void * arg2)2279a9800bebSGarrett D'Amore emlxs_rls_rsp_thread(emlxs_hba_t *hba, void *arg1, void *arg2)
2280a9800bebSGarrett D'Amore {
2281a9800bebSGarrett D'Amore 	emlxs_port_t *port = (emlxs_port_t *)arg1;
2282a9800bebSGarrett D'Amore 	fc_packet_t *pkt = (fc_packet_t *)arg2;
2283a9800bebSGarrett D'Amore 	MAILBOXQ	*mbq = NULL;
2284a9800bebSGarrett D'Amore 	MAILBOX		*mb;
2285a9800bebSGarrett D'Amore 	la_els_rls_acc_t *rls;
2286a9800bebSGarrett D'Amore 	uint32_t rval;
2287a9800bebSGarrett D'Amore 
2288a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2289a9800bebSGarrett D'Amore 	    "RLS: sid=%x. Accepting.",
2290a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id));
2291a9800bebSGarrett D'Amore 
2292*8f23e9faSHans Rosenfeld 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
2293a9800bebSGarrett D'Amore 		goto dropit;
2294a9800bebSGarrett D'Amore 	}
2295a9800bebSGarrett D'Amore 	mb = (MAILBOX *)mbq;
2296a9800bebSGarrett D'Amore 
2297a9800bebSGarrett D'Amore 	/* Read current link status */
2298a9800bebSGarrett D'Amore 	emlxs_mb_read_lnk_stat(hba, mbq);
2299a9800bebSGarrett D'Amore 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_WAIT, 0);
2300a9800bebSGarrett D'Amore 
2301a9800bebSGarrett D'Amore 	if (rval != MBX_SUCCESS) {
2302a9800bebSGarrett D'Amore 		goto dropit;
2303a9800bebSGarrett D'Amore 	}
2304a9800bebSGarrett D'Amore 
2305a9800bebSGarrett D'Amore 	/* Build the response */
2306a9800bebSGarrett D'Amore 	rls = (la_els_rls_acc_t *)pkt->pkt_cmd;
2307a9800bebSGarrett D'Amore 	rls->ls_code.ls_code = 0x02;
2308a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_link_fail =
2309a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.linkFailureCnt;
2310a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_sync_loss =
2311a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.lossSyncCnt;
2312a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_sig_loss =
2313a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.lossSignalCnt;
2314a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_prim_seq_err =
2315a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.primSeqErrCnt;
2316a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_invalid_word =
2317a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.invalidXmitWord;
2318a9800bebSGarrett D'Amore 	rls->rls_link_params.rls_invalid_crc =
2319a9800bebSGarrett D'Amore 	    mb->un.varRdLnk.crcCnt;
2320a9800bebSGarrett D'Amore 
2321a9800bebSGarrett D'Amore 	LE_SWAP32_BUFFER((uint8_t *)rls, sizeof (la_els_rls_acc_t));
2322a9800bebSGarrett D'Amore 
2323a9800bebSGarrett D'Amore 	emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2324a9800bebSGarrett D'Amore 	mbq = NULL;
2325a9800bebSGarrett D'Amore 
2326a9800bebSGarrett D'Amore 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
2327a9800bebSGarrett D'Amore 		goto dropit;
2328a9800bebSGarrett D'Amore 	}
2329a9800bebSGarrett D'Amore 
2330a9800bebSGarrett D'Amore 	return;
2331a9800bebSGarrett D'Amore 
2332a9800bebSGarrett D'Amore dropit:
2333a9800bebSGarrett D'Amore 
2334a9800bebSGarrett D'Amore 	emlxs_abort_els_exchange(hba, port, pkt->pkt_cmd_fhdr.rx_id);
2335a9800bebSGarrett D'Amore 
2336a9800bebSGarrett D'Amore 	emlxs_pkt_free(pkt);
2337a9800bebSGarrett D'Amore 
2338a9800bebSGarrett D'Amore 	if (mbq) {
2339a9800bebSGarrett D'Amore 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
2340a9800bebSGarrett D'Amore 	}
2341a9800bebSGarrett D'Amore 
2342a9800bebSGarrett D'Amore 	return;
2343a9800bebSGarrett D'Amore 
2344a9800bebSGarrett D'Amore } /* emlxs_rls_rsp_thread() */
2345a9800bebSGarrett D'Amore 
2346a9800bebSGarrett D'Amore 
2347a9800bebSGarrett D'Amore /* ARGSUSED */
2348a9800bebSGarrett D'Amore static void
emlxs_handle_unsol_rls(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)2349*8f23e9faSHans Rosenfeld emlxs_handle_unsol_rls(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
2350a9800bebSGarrett D'Amore     MATCHMAP *mp, uint32_t size)
2351a9800bebSGarrett D'Amore {
2352a9800bebSGarrett D'Amore 	emlxs_hba_t *hba = HBA;
2353a9800bebSGarrett D'Amore 	uint8_t *bp;
2354a9800bebSGarrett D'Amore 	IOCB *iocb;
2355a9800bebSGarrett D'Amore 	uint32_t *lp;
2356a9800bebSGarrett D'Amore 	uint32_t sid;
2357a9800bebSGarrett D'Amore 	fc_packet_t *pkt;
2358a9800bebSGarrett D'Amore 	uint32_t cmd;
2359a9800bebSGarrett D'Amore 
2360a9800bebSGarrett D'Amore 	iocb = &iocbq->iocb;
2361a9800bebSGarrett D'Amore 	sid = iocb->un.elsreq.remoteID;
2362a9800bebSGarrett D'Amore 
2363a9800bebSGarrett D'Amore 	bp = mp->virt;
2364a9800bebSGarrett D'Amore 	lp = (uint32_t *)bp;
2365a9800bebSGarrett D'Amore 	cmd = *lp++ & ELS_CMD_MASK;
2366a9800bebSGarrett D'Amore 
2367a9800bebSGarrett D'Amore 	if (!(pkt = emlxs_pkt_alloc(port,
2368a9800bebSGarrett D'Amore 	    sizeof (la_els_rls_acc_t), 0, 0, KM_NOSLEEP))) {
2369a9800bebSGarrett D'Amore 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2370a9800bebSGarrett D'Amore 		    "RLS: sid=%x. Unable to allocate pkt.  Rejecting.",
2371a9800bebSGarrett D'Amore 		    sid);
2372a9800bebSGarrett D'Amore 
2373a9800bebSGarrett D'Amore 		(void) emlxs_els_reply(port, iocbq, ELS_CMD_LS_RJT,
2374a9800bebSGarrett D'Amore 		    ELS_CMD_RLS, LSRJT_UNABLE_TPC, LSEXP_NOTHING_MORE);
2375a9800bebSGarrett D'Amore 		return;
2376a9800bebSGarrett D'Amore 	}
2377a9800bebSGarrett D'Amore 
2378a9800bebSGarrett D'Amore 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2379a9800bebSGarrett D'Amore 	    "RLS: sid=%x. Scheduling response.",
2380a9800bebSGarrett D'Amore 	    sid);
2381a9800bebSGarrett D'Amore 
2382a9800bebSGarrett D'Amore 	/* Common initialization */
2383a9800bebSGarrett D'Amore 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2384a9800bebSGarrett D'Amore 	pkt->pkt_timeout = (2 * hba->fc_ratov);
2385a9800bebSGarrett D'Amore 
2386a9800bebSGarrett D'Amore 	if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2387a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2388a9800bebSGarrett D'Amore 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2389a9800bebSGarrett D'Amore 	}
2390a9800bebSGarrett D'Amore 
2391a9800bebSGarrett D'Amore 	/* Build the fc header */
2392a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.d_id =
2393a9800bebSGarrett D'Amore 	    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2394a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.r_ctl =
2395a9800bebSGarrett D'Amore 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
2396a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2397a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2398a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.f_ctl =
2399a9800bebSGarrett D'Amore 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2400a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_id = 0;
2401a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.df_ctl = 0;
2402a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
2403a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ox_id = (cmd >> ELS_CMD_SHIFT) & 0xff;
2404a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2405a9800bebSGarrett D'Amore 	pkt->pkt_cmd_fhdr.ro = 0;
2406a9800bebSGarrett D'Amore 
2407a9800bebSGarrett D'Amore 	/* We must spawn a separate thread to send the */
2408a9800bebSGarrett D'Amore 	/* read link status mailbox command becasue we are */
2409a9800bebSGarrett D'Amore 	/* normally in a hardware interrupt context here. */
2410a9800bebSGarrett D'Amore 	emlxs_thread_spawn(hba, emlxs_rls_rsp_thread,
2411a9800bebSGarrett D'Amore 	    (void *)port, (void *)pkt);
2412a9800bebSGarrett D'Amore 
2413a9800bebSGarrett D'Amore 	return;
2414a9800bebSGarrett D'Amore 
2415*8f23e9faSHans Rosenfeld } /* emlxs_handle_unsol_rls() */
2416a9800bebSGarrett D'Amore 
2417a9800bebSGarrett D'Amore 
2418fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2419fcf3ce44SJohn Forte /* ARGSUSED */
2420fcf3ce44SJohn Forte static void
emlxs_handle_acc(emlxs_port_t * port,emlxs_buf_t * sbp,IOCBQ * iocbq,uint32_t flag)2421291a2b48SSukumar Swaminathan emlxs_handle_acc(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2422291a2b48SSukumar Swaminathan     uint32_t flag)
2423fcf3ce44SJohn Forte {
242482527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2425fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2426fcf3ce44SJohn Forte 	IOCB *iocb;
2427fcf3ce44SJohn Forte 	uint32_t did;
2428fcf3ce44SJohn Forte 	NODELIST *ndlp;
2429fcf3ce44SJohn Forte 	uint32_t ucmd;
2430fcf3ce44SJohn Forte 	uint32_t cmd;
2431fcf3ce44SJohn Forte 	uint32_t *lp;
2432fcf3ce44SJohn Forte 
2433fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2434fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
243582527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2436fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2437fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2438fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2439fcf3ce44SJohn Forte 
2440fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2441291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
244282527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2443fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2444fcf3ce44SJohn Forte 
2445fcf3ce44SJohn Forte 	switch (ucmd) {
2446fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2447fcf3ce44SJohn Forte 	case ELS_CMD_ADISC:
2448fcf3ce44SJohn Forte 
2449*8f23e9faSHans Rosenfeld 		ndlp = emlxs_node_find_did(port, did, 1);
2450fcf3ce44SJohn Forte 
2451fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2452fcf3ce44SJohn Forte 			/* Open the node again */
245382527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
245482527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2455fcf3ce44SJohn Forte 		}
2456291a2b48SSukumar Swaminathan 
2457fcf3ce44SJohn Forte 		break;
2458fcf3ce44SJohn Forte 
2459fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2460fcf3ce44SJohn Forte 
2461*8f23e9faSHans Rosenfeld 		ndlp = emlxs_node_find_did(port, did, 1);
2462fcf3ce44SJohn Forte 
2463fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2464*8f23e9faSHans Rosenfeld 			EMLXS_SET_DFC_STATE(ndlp, NODE_ALLOC);
2465*8f23e9faSHans Rosenfeld 
2466fcf3ce44SJohn Forte 			/* Open the node again */
246782527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2468fcf3ce44SJohn Forte 		}
2469291a2b48SSukumar Swaminathan 
2470fcf3ce44SJohn Forte 		break;
2471fcf3ce44SJohn Forte 	}
2472fcf3ce44SJohn Forte 
247382527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2474fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2475fcf3ce44SJohn Forte 
2476fcf3ce44SJohn Forte 	return;
2477fcf3ce44SJohn Forte 
247882527734SSukumar Swaminathan } /* emlxs_handle_acc() */
2479fcf3ce44SJohn Forte 
2480fcf3ce44SJohn Forte 
2481fcf3ce44SJohn Forte /* This handles the reply completions to unsolicited cmds */
2482fcf3ce44SJohn Forte /* ARGSUSED */
2483fcf3ce44SJohn Forte static void
emlxs_handle_reject(emlxs_port_t * port,emlxs_buf_t * sbp,IOCBQ * iocbq,uint32_t flag)2484291a2b48SSukumar Swaminathan emlxs_handle_reject(emlxs_port_t *port, emlxs_buf_t *sbp, IOCBQ *iocbq,
2485291a2b48SSukumar Swaminathan     uint32_t flag)
2486fcf3ce44SJohn Forte {
248782527734SSukumar Swaminathan 	emlxs_hba_t *hba = HBA;
2488291a2b48SSukumar Swaminathan 	fc_packet_t	*pkt;
2489291a2b48SSukumar Swaminathan 	NODELIST	*ndlp;
2490291a2b48SSukumar Swaminathan 	IOCB		*iocb;
2491291a2b48SSukumar Swaminathan 	uint32_t	did;
2492291a2b48SSukumar Swaminathan 	uint32_t	ucmd;
2493291a2b48SSukumar Swaminathan 	uint32_t	cmd;
2494291a2b48SSukumar Swaminathan 	uint32_t	*lp;
2495fcf3ce44SJohn Forte 
2496fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2497fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
249882527734SSukumar Swaminathan 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
2499fcf3ce44SJohn Forte 	ucmd = pkt->pkt_cmd_fhdr.ox_id << ELS_CMD_SHIFT;
2500fcf3ce44SJohn Forte 	lp = (uint32_t *)pkt->pkt_cmd;
2501fcf3ce44SJohn Forte 	cmd = *lp & ELS_CMD_MASK;
2502fcf3ce44SJohn Forte 
2503*8f23e9faSHans Rosenfeld 	ndlp = emlxs_node_find_did(port, did, 1);
2504291a2b48SSukumar Swaminathan 
2505fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_els_completion_msg,
2506291a2b48SSukumar Swaminathan 	    "%s %s: did=%x %s %s", emlxs_elscmd_xlate(ucmd),
250782527734SSukumar Swaminathan 	    emlxs_elscmd_xlate(cmd), did, emlxs_state_xlate(iocb->ULPSTATUS),
2508fcf3ce44SJohn Forte 	    emlxs_error_xlate(iocb->un.grsp.perr.statLocalError));
2509fcf3ce44SJohn Forte 
2510fcf3ce44SJohn Forte 	switch (ucmd) {
2511fcf3ce44SJohn Forte 	case ELS_CMD_PLOGI:
2512fcf3ce44SJohn Forte 
2513fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2514fcf3ce44SJohn Forte 			/* Open the node again */
251582527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
251682527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_ip);
2517fcf3ce44SJohn Forte 		}
2518291a2b48SSukumar Swaminathan 
2519fcf3ce44SJohn Forte 		break;
2520fcf3ce44SJohn Forte 
2521fcf3ce44SJohn Forte 	case ELS_CMD_PRLI:
2522fcf3ce44SJohn Forte 
2523fcf3ce44SJohn Forte 		if (ndlp && ndlp->nlp_active) {
2524fcf3ce44SJohn Forte 			/* Open the node again */
252582527734SSukumar Swaminathan 			emlxs_node_open(port, ndlp, hba->channel_fcp);
2526fcf3ce44SJohn Forte 		}
2527291a2b48SSukumar Swaminathan 
2528fcf3ce44SJohn Forte 		break;
2529fcf3ce44SJohn Forte 	}
2530fcf3ce44SJohn Forte 
253182527734SSukumar Swaminathan 	emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2532fcf3ce44SJohn Forte 	    iocb->un.grsp.perr.statLocalError, 1);
2533fcf3ce44SJohn Forte 
2534fcf3ce44SJohn Forte 	return;
2535fcf3ce44SJohn Forte 
253682527734SSukumar Swaminathan } /* emlxs_handle_reject() */
2537fcf3ce44SJohn Forte 
2538fcf3ce44SJohn Forte 
2539fcf3ce44SJohn Forte /* ARGSUSED */
2540fcf3ce44SJohn Forte extern int32_t
emlxs_els_reply(emlxs_port_t * port,IOCBQ * iocbq,uint32_t type,uint32_t type2,uint32_t reason,uint32_t explain)2541fcf3ce44SJohn Forte emlxs_els_reply(emlxs_port_t *port, IOCBQ *iocbq, uint32_t type,
2542fcf3ce44SJohn Forte     uint32_t type2, uint32_t reason, uint32_t explain)
2543fcf3ce44SJohn Forte {
2544fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
2545fcf3ce44SJohn Forte 	emlxs_config_t *cfg = &CFG;
2546fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2547fcf3ce44SJohn Forte 	ELS_PKT *els;
2548fcf3ce44SJohn Forte 	IOCB *iocb;
2549fcf3ce44SJohn Forte 
2550fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2551fcf3ce44SJohn Forte 
2552fcf3ce44SJohn Forte 	switch (type) {
2553fcf3ce44SJohn Forte 	case ELS_CMD_ACC:	/* Accept Response */
2554fcf3ce44SJohn Forte 
2555fcf3ce44SJohn Forte 		/* Allocate the pkt */
2556fcf3ce44SJohn Forte 		switch (type2) {
2557fcf3ce44SJohn Forte 		case ELS_CMD_FLOGI:
2558a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2559291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (SERV_PARM), 0,
2560a9800bebSGarrett D'Amore 			    0, KM_NOSLEEP);
2561fcf3ce44SJohn Forte 			break;
2562fcf3ce44SJohn Forte 
2563fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2564a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2565291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (ADISC), 0, 0,
2566a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2567fcf3ce44SJohn Forte 			break;
2568fcf3ce44SJohn Forte 
2569fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2570a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2571291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLI), 0, 0,
2572a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2573fcf3ce44SJohn Forte 			break;
2574fcf3ce44SJohn Forte 
2575fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2576a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port,
2577291a2b48SSukumar Swaminathan 			    sizeof (uint32_t) + sizeof (PRLO), 0, 0,
2578a9800bebSGarrett D'Amore 			    KM_NOSLEEP);
2579fcf3ce44SJohn Forte 			break;
2580fcf3ce44SJohn Forte 
2581fcf3ce44SJohn Forte 		case ELS_CMD_AUTH:
2582fcf3ce44SJohn Forte 		default:
2583a9800bebSGarrett D'Amore 			pkt = emlxs_pkt_alloc(port, sizeof (uint32_t),
2584a9800bebSGarrett D'Amore 			    0, 0, KM_NOSLEEP);
2585*8f23e9faSHans Rosenfeld 			break;
2586a9800bebSGarrett D'Amore 		}
2587fcf3ce44SJohn Forte 
2588a9800bebSGarrett D'Amore 		if (!pkt) {
2589a9800bebSGarrett D'Amore 			goto dropit;
2590fcf3ce44SJohn Forte 		}
2591fcf3ce44SJohn Forte 
2592fcf3ce44SJohn Forte 		/* Common initialization */
2593fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2594fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2595fcf3ce44SJohn Forte 
259682527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2597fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2598fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2599fcf3ce44SJohn Forte 		}
2600291a2b48SSukumar Swaminathan 
2601fcf3ce44SJohn Forte 		/* Build the fc header */
2602fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
260382527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2604291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2605291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
260682527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2607fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2608291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2609291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2610fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2611fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2612fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2613fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
261482527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2615fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2616fcf3ce44SJohn Forte 
2617fcf3ce44SJohn Forte 		/*
2618291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2619291a2b48SSukumar Swaminathan 		 * "%s ACC send. oxid=%x", emlxs_elscmd_xlate(type2),
2620fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2621fcf3ce44SJohn Forte 		 */
2622fcf3ce44SJohn Forte 
2623fcf3ce44SJohn Forte 		/* Build the command */
2624291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2625fcf3ce44SJohn Forte 		els->elsCode = 0x02;
2626fcf3ce44SJohn Forte 
2627fcf3ce44SJohn Forte 		/* Build the payload */
2628fcf3ce44SJohn Forte 		switch (type2) {
2629fcf3ce44SJohn Forte 		case ELS_CMD_ADISC:
2630fcf3ce44SJohn Forte 
2631fcf3ce44SJohn Forte 			els->un.adisc.hardAL_PA =
2632fcf3ce44SJohn Forte 			    (uint8_t)cfg[CFG_ASSIGN_ALPA].current;
2633fcf3ce44SJohn Forte 			bcopy(&port->wwnn, &els->un.adisc.nodeName,
2634fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
2635fcf3ce44SJohn Forte 			bcopy(&port->wwpn, &els->un.adisc.portName,
2636fcf3ce44SJohn Forte 			    sizeof (NAME_TYPE));
263782527734SSukumar Swaminathan 			els->un.adisc.DID = LE_SWAP24_LO(port->did);
2638fcf3ce44SJohn Forte 
2639fcf3ce44SJohn Forte 			break;
2640fcf3ce44SJohn Forte 
2641fcf3ce44SJohn Forte 		case ELS_CMD_PRLI:
2642fcf3ce44SJohn Forte 
2643fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2644fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2645fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2646fcf3ce44SJohn Forte 
2647fcf3ce44SJohn Forte 			els->un.prli.prliType = PRLI_FCP_TYPE;
2648fcf3ce44SJohn Forte 			els->un.prli.estabImagePair = 1;
2649fcf3ce44SJohn Forte 			els->un.prli.acceptRspCode = PRLI_REQ_EXECUTED;
2650fcf3ce44SJohn Forte 
2651*8f23e9faSHans Rosenfeld 			if (port->mode == MODE_INITIATOR) {
2652fcf3ce44SJohn Forte 				els->un.prli.initiatorFunc = 1;
2653fcf3ce44SJohn Forte 			}
2654291a2b48SSukumar Swaminathan 
2655*8f23e9faSHans Rosenfeld 			if (port->mode == MODE_TARGET) {
2656fcf3ce44SJohn Forte 				els->un.prli.targetFunc = 1;
2657fcf3ce44SJohn Forte 			}
2658291a2b48SSukumar Swaminathan 
2659fcf3ce44SJohn Forte 			els->un.prli.readXferRdyDis = 1;
2660fcf3ce44SJohn Forte 
2661a9800bebSGarrett D'Amore 			if ((hba->vpd.feaLevelHigh >= 0x02) &&
2662a9800bebSGarrett D'Amore 			    (cfg[CFG_ADISC_SUPPORT].current != 0)) {
2663fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 1;
2664fcf3ce44SJohn Forte 				els->un.prli.Retry = 1;
2665fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 1;
2666fcf3ce44SJohn Forte 			} else {
2667fcf3ce44SJohn Forte 				els->un.prli.ConfmComplAllowed = 0;
2668fcf3ce44SJohn Forte 				els->un.prli.Retry = 0;
2669fcf3ce44SJohn Forte 				els->un.prli.TaskRetryIdReq = 0;
2670fcf3ce44SJohn Forte 			}
2671fcf3ce44SJohn Forte 
2672fcf3ce44SJohn Forte 			break;
2673fcf3ce44SJohn Forte 
2674fcf3ce44SJohn Forte 		case ELS_CMD_PRLO:
2675fcf3ce44SJohn Forte 
2676fcf3ce44SJohn Forte 			els->elsByte1 = 0x10;
2677fcf3ce44SJohn Forte 			els->elsByte2 = 0;
2678fcf3ce44SJohn Forte 			els->elsByte3 = 0x14;
2679fcf3ce44SJohn Forte 
2680fcf3ce44SJohn Forte 			els->un.prlo.prloType = PRLO_FCP_TYPE;
2681fcf3ce44SJohn Forte 			els->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
2682fcf3ce44SJohn Forte 
2683fcf3ce44SJohn Forte 			break;
2684fcf3ce44SJohn Forte 
2685fcf3ce44SJohn Forte 
2686fcf3ce44SJohn Forte 		}	/* switch(type2) */
2687fcf3ce44SJohn Forte 		break;
2688fcf3ce44SJohn Forte 
2689fcf3ce44SJohn Forte 	case ELS_CMD_LS_RJT:	/* reject response */
2690fcf3ce44SJohn Forte 
2691fcf3ce44SJohn Forte 		if (!(pkt = emlxs_pkt_alloc(port,
2692fcf3ce44SJohn Forte 		    sizeof (uint32_t) + sizeof (LS_RJT), 0, 0, KM_NOSLEEP))) {
2693a9800bebSGarrett D'Amore 			goto dropit;
2694fcf3ce44SJohn Forte 		}
2695291a2b48SSukumar Swaminathan 
2696fcf3ce44SJohn Forte 		pkt->pkt_tran_type = FC_PKT_OUTBOUND;
2697fcf3ce44SJohn Forte 		pkt->pkt_timeout = (2 * hba->fc_ratov);
2698fcf3ce44SJohn Forte 
269982527734SSukumar Swaminathan 		if ((uint32_t)iocb->ULPCLASS == CLASS2) {
2700fcf3ce44SJohn Forte 			pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
2701fcf3ce44SJohn Forte 			pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
2702fcf3ce44SJohn Forte 		}
2703291a2b48SSukumar Swaminathan 
2704fcf3ce44SJohn Forte 		/* Build the fc header */
2705fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.d_id =
270682527734SSukumar Swaminathan 		    LE_SWAP24_LO(iocb->un.elsreq.remoteID);
2707291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.r_ctl =
2708291a2b48SSukumar Swaminathan 		    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
270982527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(iocb->un.elsreq.myID);
2710fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
2711291a2b48SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.f_ctl =
2712291a2b48SSukumar Swaminathan 		    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
2713fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_id = 0;
2714fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.df_ctl = 0;
2715fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.seq_cnt = 0;
2716fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ox_id = (type2 >> ELS_CMD_SHIFT) & 0xff;
271782527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2718fcf3ce44SJohn Forte 		pkt->pkt_cmd_fhdr.ro = 0;
2719fcf3ce44SJohn Forte 
2720fcf3ce44SJohn Forte 		/*
2721291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2722291a2b48SSukumar Swaminathan 		 * "%s LS_RJT send. oxid=%x", emlxs_elscmd_xlate(type2),
2723fcf3ce44SJohn Forte 		 * pkt->pkt_cmd_fhdr.ox_id);
2724fcf3ce44SJohn Forte 		 */
2725fcf3ce44SJohn Forte 
2726fcf3ce44SJohn Forte 		/* Build the command */
2727291a2b48SSukumar Swaminathan 		els = (ELS_PKT *)pkt->pkt_cmd;
2728fcf3ce44SJohn Forte 		els->elsCode = 0x01;
2729fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsvd0 = 0;
2730fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2731fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2732fcf3ce44SJohn Forte 		els->un.lsRjt.un.b.vendorUnique = 0x01;
2733fcf3ce44SJohn Forte 
2734fcf3ce44SJohn Forte 		break;
2735*8f23e9faSHans Rosenfeld 
2736*8f23e9faSHans Rosenfeld 	default:
2737*8f23e9faSHans Rosenfeld 		return (1);
2738fcf3ce44SJohn Forte 	}
2739fcf3ce44SJohn Forte 
2740a9800bebSGarrett D'Amore 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
2741fcf3ce44SJohn Forte 		/* Free the pkt */
2742fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
2743a9800bebSGarrett D'Amore 		goto dropit;
2744fcf3ce44SJohn Forte 	}
2745291a2b48SSukumar Swaminathan 
2746a9800bebSGarrett D'Amore 	return (0);
2747a9800bebSGarrett D'Amore 
2748a9800bebSGarrett D'Amore dropit:
2749a9800bebSGarrett D'Amore 
2750a9800bebSGarrett D'Amore 	emlxs_abort_els_exchange(hba, port, iocb->ULPCONTEXT);
2751a9800bebSGarrett D'Amore 	return (1);
2752fcf3ce44SJohn Forte 
275382527734SSukumar Swaminathan } /* emlxs_els_reply() */
2754fcf3ce44SJohn Forte 
2755fcf3ce44SJohn Forte 
2756fcf3ce44SJohn Forte #ifdef ULP_PATCH6
2757fcf3ce44SJohn Forte 
2758fcf3ce44SJohn Forte extern uint32_t
emlxs_generate_rscn(emlxs_port_t * port,uint32_t d_id)2759fcf3ce44SJohn Forte emlxs_generate_rscn(emlxs_port_t *port, uint32_t d_id)
2760fcf3ce44SJohn Forte {
2761fcf3ce44SJohn Forte 	fc_unsol_buf_t *ubp;
2762fcf3ce44SJohn Forte 	fc_rscn_t *rscn;
2763fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
2764fcf3ce44SJohn Forte 	uint32_t *page;
2765fcf3ce44SJohn Forte 
2766*8f23e9faSHans Rosenfeld 	ubp = (fc_unsol_buf_t *)emlxs_ub_get(port, 8, FC_TYPE_EXTENDED_LS, 1);
2767fcf3ce44SJohn Forte 
2768fcf3ce44SJohn Forte 	if (ubp == NULL) {
2769fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_no_unsol_buf_msg,
2770291a2b48SSukumar Swaminathan 		    "RSCN create: sid=0xfffffd  1 page(s): %08X, 00000000. "
2771291a2b48SSukumar Swaminathan 		    "Creation failed.", d_id);
2772fcf3ce44SJohn Forte 
2773fcf3ce44SJohn Forte 		return ((uint32_t)FC_FAILURE);
2774fcf3ce44SJohn Forte 	}
2775291a2b48SSukumar Swaminathan 
2776fcf3ce44SJohn Forte 	/* Simulate an RSCN payload */
2777fcf3ce44SJohn Forte 	rscn = (fc_rscn_t *)ubp->ub_buffer;
2778fcf3ce44SJohn Forte 	rscn->rscn_code = 0x61;
2779fcf3ce44SJohn Forte 	rscn->rscn_len = 0x04;
2780fcf3ce44SJohn Forte 	rscn->rscn_payload_len = 0x0008;
2781fcf3ce44SJohn Forte 	page = ((uint32_t *)rscn);
2782fcf3ce44SJohn Forte 	page++;
2783fcf3ce44SJohn Forte 	*page = d_id;
2784fcf3ce44SJohn Forte 
2785fcf3ce44SJohn Forte #ifdef EMLXS_I386
2786fcf3ce44SJohn Forte 	/* Put payload in BE format */
278782527734SSukumar Swaminathan 	rscn->rscn_payload_len = LE_SWAP16(rscn->rscn_payload_len);
278882527734SSukumar Swaminathan 	*page = LE_SWAP32(d_id);
2789291a2b48SSukumar Swaminathan #endif /* EMLXS_I386 */
2790fcf3ce44SJohn Forte 
2791fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
2792fcf3ce44SJohn Forte 	ub_priv->cmd = ELS_CMD_RSCN;
2793fcf3ce44SJohn Forte 	ub_priv->flags |= EMLXS_UB_INTERCEPT;
2794fcf3ce44SJohn Forte 
2795fcf3ce44SJohn Forte 	ubp->ub_frame.r_ctl = FC_ELS_REQ;
2796*8f23e9faSHans Rosenfeld 	ubp->ub_frame.type = FC_TYPE_EXTENDED_LS;
2797fcf3ce44SJohn Forte 	ubp->ub_frame.s_id = 0xfffffd;
279882527734SSukumar Swaminathan 	ubp->ub_frame.d_id = LE_SWAP24_LO(port->did);
2799fcf3ce44SJohn Forte 	ubp->ub_frame.ox_id = ub_priv->token;
2800fcf3ce44SJohn Forte 	ubp->ub_frame.rx_id = 0xffff;
2801fcf3ce44SJohn Forte 	ubp->ub_class = FC_TRAN_CLASS3;
2802fcf3ce44SJohn Forte 
2803fcf3ce44SJohn Forte 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_els_msg,
2804291a2b48SSukumar Swaminathan 	    "RSCN: sid=fffffd  1 page(s): %08X, 00000000  buffer=%p "
2805291a2b48SSukumar Swaminathan 	    "token=%x. Created.", d_id, ubp, ub_priv->token);
2806fcf3ce44SJohn Forte 
2807fcf3ce44SJohn Forte #if (EMLXS_MODREVX == EMLXS_MODREV2X)
2808fcf3ce44SJohn Forte 	emlxs_swap_els_ub(ubp);
2809291a2b48SSukumar Swaminathan #endif /* EMLXS_MODREV2X */
2810fcf3ce44SJohn Forte 
2811fcf3ce44SJohn Forte 	emlxs_ub_callback(port, ubp);
2812fcf3ce44SJohn Forte 
2813fcf3ce44SJohn Forte 	return (FC_SUCCESS);
2814fcf3ce44SJohn Forte 
281582527734SSukumar Swaminathan } /* emlxs_generate_rscn() */
2816fcf3ce44SJohn Forte 
2817291a2b48SSukumar Swaminathan #endif /* ULP_PATCH6 */
2818fcf3ce44SJohn Forte 
2819fcf3ce44SJohn Forte 
2820fcf3ce44SJohn Forte #ifdef MENLO_SUPPORT
2821fcf3ce44SJohn Forte extern int
emlxs_menlo_handle_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)282282527734SSukumar Swaminathan emlxs_menlo_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2823fcf3ce44SJohn Forte {
2824fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2825fcf3ce44SJohn Forte 	IOCB *iocb;
2826fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2827fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2828fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2829fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2830fcf3ce44SJohn Forte 	menlo_cmd_t *cmd;
2831fcf3ce44SJohn Forte 	uint32_t *rsp;
2832fcf3ce44SJohn Forte 
2833fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2834fcf3ce44SJohn Forte 
2835fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2836fcf3ce44SJohn Forte 
2837fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2838fcf3ce44SJohn Forte 
2839fcf3ce44SJohn Forte 	if (!sbp) {
2840fcf3ce44SJohn Forte 		/*
2841fcf3ce44SJohn Forte 		 * completion with missing xmit command
2842fcf3ce44SJohn Forte 		 */
2843fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2844fcf3ce44SJohn Forte 
2845fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2846fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
284782527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
284882527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2849291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2850fcf3ce44SJohn Forte 
2851fcf3ce44SJohn Forte 		return (1);
2852fcf3ce44SJohn Forte 	}
2853291a2b48SSukumar Swaminathan 
285482527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2855fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2856fcf3ce44SJohn Forte 
2857fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
285882527734SSukumar Swaminathan 		    "Invalid IO channel:%d iocbq=%p", cp->channelno, iocbq);
2859fcf3ce44SJohn Forte 
2860fcf3ce44SJohn Forte 		return (1);
2861fcf3ce44SJohn Forte 	}
2862291a2b48SSukumar Swaminathan 
2863fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2864fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2865fcf3ce44SJohn Forte 
2866fcf3ce44SJohn Forte 	cmd = (menlo_cmd_t *)pkt->pkt_cmd;
286782527734SSukumar Swaminathan 	cmd_code = BE_SWAP32(cmd->code);
2868fcf3ce44SJohn Forte 
2869fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
2870fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
287182527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
2872fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
2873fcf3ce44SJohn Forte 	}
2874291a2b48SSukumar Swaminathan 
287582527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
2876291a2b48SSukumar Swaminathan 	/*
2877291a2b48SSukumar Swaminathan 	 * MENLO Command completion
2878291a2b48SSukumar Swaminathan 	 */
2879fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
2880fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
2881fcf3ce44SJohn Forte 
2882fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
2883fcf3ce44SJohn Forte 
2884fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
2885fcf3ce44SJohn Forte 
2886fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
2887fcf3ce44SJohn Forte 		rsp_code = *rsp;
288882527734SSukumar Swaminathan 		rsp_code = BE_SWAP32(rsp_code);
2889fcf3ce44SJohn Forte 
2890*8f23e9faSHans Rosenfeld 		if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) {
2891fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2892fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
2893*8f23e9faSHans Rosenfeld 		} else {
2894fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
2895fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
2896fcf3ce44SJohn Forte 		}
2897fcf3ce44SJohn Forte 
2898fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
289982527734SSukumar Swaminathan 		pkt->pkt_cmd_fhdr.rx_id = iocb->ULPCONTEXT;
2900fcf3ce44SJohn Forte 
290182527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) && (rsp_code == MENLO_RSP_SUCCESS)) {
2902fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
2903fcf3ce44SJohn Forte 
2904fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2905fcf3ce44SJohn Forte 			    "%s: %s rxid=0x%x",
2906fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2907fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
290882527734SSukumar Swaminathan 			    iocb->ULPCONTEXT);
2909fcf3ce44SJohn Forte 
2910fcf3ce44SJohn Forte 		} else {
2911fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
2912fcf3ce44SJohn Forte 
2913fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
2914fcf3ce44SJohn Forte 			    "%s: %s %s %s rxid=0x%x",
2915fcf3ce44SJohn Forte 			    emlxs_menlo_cmd_xlate(cmd_code),
2916fcf3ce44SJohn Forte 			    emlxs_menlo_rsp_xlate(rsp_code),
291782527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
2918291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
291982527734SSukumar Swaminathan 			    statLocalError), iocb->ULPCONTEXT);
2920fcf3ce44SJohn Forte 		}
2921fcf3ce44SJohn Forte 
292282527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2923fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2924fcf3ce44SJohn Forte 
2925fcf3ce44SJohn Forte 		break;
2926fcf3ce44SJohn Forte 
2927fcf3ce44SJohn Forte 	default:
2928fcf3ce44SJohn Forte 
2929fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2930fcf3ce44SJohn Forte 
2931fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
293282527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
2933fcf3ce44SJohn Forte 
293482527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
2935fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
2936fcf3ce44SJohn Forte 
2937fcf3ce44SJohn Forte 		break;
2938fcf3ce44SJohn Forte 
293982527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
2940fcf3ce44SJohn Forte 
2941fcf3ce44SJohn Forte 	return (0);
2942fcf3ce44SJohn Forte 
294382527734SSukumar Swaminathan } /* emlxs_menlo_handle_event() */
2944fcf3ce44SJohn Forte 
2945291a2b48SSukumar Swaminathan #endif /* MENLO_SUPPORT */
2946fcf3ce44SJohn Forte 
2947fcf3ce44SJohn Forte 
2948fcf3ce44SJohn Forte extern int
emlxs_ct_handle_event(emlxs_hba_t * hba,CHANNEL * cp,IOCBQ * iocbq)294982527734SSukumar Swaminathan emlxs_ct_handle_event(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2950fcf3ce44SJohn Forte {
2951fcf3ce44SJohn Forte 	emlxs_port_t *port = &PPORT;
2952fcf3ce44SJohn Forte 	IOCB *iocb;
2953fcf3ce44SJohn Forte 	emlxs_buf_t *sbp;
2954fcf3ce44SJohn Forte 	fc_packet_t *pkt;
2955fcf3ce44SJohn Forte 	uint32_t *rsp;
2956fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtRsp;
2957fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
2958fcf3ce44SJohn Forte 	uint32_t cmd_code = 0;
2959fcf3ce44SJohn Forte 	uint32_t rsp_code = 0;
2960fcf3ce44SJohn Forte 
2961fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
2962fcf3ce44SJohn Forte 
2963fcf3ce44SJohn Forte 	HBASTATS.CtEvent++;
2964fcf3ce44SJohn Forte 
2965fcf3ce44SJohn Forte 	sbp = (emlxs_buf_t *)iocbq->sbp;
2966fcf3ce44SJohn Forte 
2967fcf3ce44SJohn Forte 	if (!sbp) {
2968fcf3ce44SJohn Forte 		/*
2969fcf3ce44SJohn Forte 		 * completion with missing xmit command
2970fcf3ce44SJohn Forte 		 */
2971fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2972fcf3ce44SJohn Forte 
2973fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
2974fcf3ce44SJohn Forte 		    "iocbq=%p cmd=0x%x iotag=0x%x status=0x%x perr=0x%x",
297582527734SSukumar Swaminathan 		    iocbq, (uint32_t)iocb->ULPCOMMAND,
297682527734SSukumar Swaminathan 		    (uint32_t)iocb->ULPIOTAG, iocb->ULPSTATUS,
2977291a2b48SSukumar Swaminathan 		    iocb->un.ulpWord[4]);
2978fcf3ce44SJohn Forte 
2979fcf3ce44SJohn Forte 		return (1);
2980fcf3ce44SJohn Forte 	}
2981291a2b48SSukumar Swaminathan 
298282527734SSukumar Swaminathan 	if (cp->channelno != hba->channel_ct) {
2983fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
2984fcf3ce44SJohn Forte 
2985fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_ct_completion_msg,
298682527734SSukumar Swaminathan 		    "Invalid channel: channel=%d iocbq=%p", cp->channelno,
298782527734SSukumar Swaminathan 		    iocbq);
2988fcf3ce44SJohn Forte 
2989fcf3ce44SJohn Forte 		return (1);
2990fcf3ce44SJohn Forte 	}
2991291a2b48SSukumar Swaminathan 
2992fcf3ce44SJohn Forte 	pkt = PRIV2PKT(sbp);
2993fcf3ce44SJohn Forte 	port = sbp->iocbq.port;
2994291a2b48SSukumar Swaminathan 	CtCmd = (SLI_CT_REQUEST *)pkt->pkt_cmd;
299582527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
2996fcf3ce44SJohn Forte 
2997fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
2998fcf3ce44SJohn Forte 		HBASTATS.CtEvent--;
299982527734SSukumar Swaminathan 		return (emlxs_dfc_handle_event(hba, cp, iocbq));
3000fcf3ce44SJohn Forte 	}
3001fcf3ce44SJohn Forte 
3002fcf3ce44SJohn Forte 	/* Check if a response buffer was provided */
3003fcf3ce44SJohn Forte 	if (pkt->pkt_rsplen) {
300482527734SSukumar Swaminathan 		EMLXS_MPDATA_SYNC(pkt->pkt_resp_dma, 0, pkt->pkt_rsplen,
3005fcf3ce44SJohn Forte 		    DDI_DMA_SYNC_FORKERNEL);
3006fcf3ce44SJohn Forte 	}
3007291a2b48SSukumar Swaminathan 
300882527734SSukumar Swaminathan 	switch (iocb->ULPCOMMAND) {
3009291a2b48SSukumar Swaminathan 		/*
3010291a2b48SSukumar Swaminathan 		 * CT Reply completion
3011291a2b48SSukumar Swaminathan 		 */
3012fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE_CX:
3013fcf3ce44SJohn Forte 	case CMD_XMIT_SEQUENCE64_CX:
3014fcf3ce44SJohn Forte 
3015fcf3ce44SJohn Forte 		HBASTATS.CtRspCompleted++;
3016fcf3ce44SJohn Forte 
3017fcf3ce44SJohn Forte 		switch (CtCmd->FsType) {
3018fcf3ce44SJohn Forte 		case 0xFC:	/* Name server */
3019fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
3020291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
302182527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
3022291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
3023291a2b48SSukumar Swaminathan 			    statLocalError));
3024fcf3ce44SJohn Forte 			break;
3025fcf3ce44SJohn Forte 
3026fcf3ce44SJohn Forte 		case 0xFA:	/* Managment server */
3027fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
3028291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_mscmd_xlate(cmd_code),
302982527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
3030291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
3031291a2b48SSukumar Swaminathan 			    statLocalError));
3032fcf3ce44SJohn Forte 			break;
3033fcf3ce44SJohn Forte 
3034fcf3ce44SJohn Forte 		case 0x0A:	/* Emulex Remote server */
3035fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
3036291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_rmcmd_xlate(cmd_code),
303782527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
3038291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
3039291a2b48SSukumar Swaminathan 			    statLocalError));
3040fcf3ce44SJohn Forte 			break;
3041fcf3ce44SJohn Forte 
3042fcf3ce44SJohn Forte 		default:
3043fcf3ce44SJohn Forte 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
3044291a2b48SSukumar Swaminathan 			    "%s: %s %s", emlxs_ctcmd_xlate(cmd_code),
304582527734SSukumar Swaminathan 			    emlxs_state_xlate(iocb->ULPSTATUS),
3046291a2b48SSukumar Swaminathan 			    emlxs_error_xlate(iocb->un.grsp.perr.
3047291a2b48SSukumar Swaminathan 			    statLocalError));
3048fcf3ce44SJohn Forte 		}
3049fcf3ce44SJohn Forte 
305082527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
3051fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
3052fcf3ce44SJohn Forte 
3053fcf3ce44SJohn Forte 		break;
3054fcf3ce44SJohn Forte 
3055291a2b48SSukumar Swaminathan 		/*
3056291a2b48SSukumar Swaminathan 		 * CT Command completion
3057291a2b48SSukumar Swaminathan 		 */
3058fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CR:
3059fcf3ce44SJohn Forte 	case CMD_GEN_REQUEST64_CX:
3060fcf3ce44SJohn Forte 
3061fcf3ce44SJohn Forte 		HBASTATS.CtCmdCompleted++;
3062fcf3ce44SJohn Forte 
3063fcf3ce44SJohn Forte 		sbp->pkt_flags |= PACKET_CT_RSP_VALID;
3064fcf3ce44SJohn Forte 
3065fcf3ce44SJohn Forte 		rsp = (uint32_t *)pkt->pkt_resp;
3066fcf3ce44SJohn Forte 		CtRsp = (SLI_CT_REQUEST *)pkt->pkt_resp;
306782527734SSukumar Swaminathan 		rsp_code = LE_SWAP16(CtRsp->CommandResponse.bits.CmdRsp);
3068fcf3ce44SJohn Forte 
306982527734SSukumar Swaminathan 		if (hba->sli_mode >= EMLXS_HBA_SLI3_MODE) {
3070fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
3071fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->unsli3.ext_iocb.rsplen;
3072*8f23e9faSHans Rosenfeld 		} else {
3073fcf3ce44SJohn Forte 			pkt->pkt_resp_resid =
3074fcf3ce44SJohn Forte 			    pkt->pkt_rsplen - iocb->un.genreq64.bdl.bdeSize;
3075fcf3ce44SJohn Forte 		}
3076fcf3ce44SJohn Forte 
3077fcf3ce44SJohn Forte 		pkt->pkt_data_resid = pkt->pkt_datalen;
3078fcf3ce44SJohn Forte 
3079fcf3ce44SJohn Forte 		/*
3080291a2b48SSukumar Swaminathan 		 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_completion_msg,
3081291a2b48SSukumar Swaminathan 		 * "INFO: pkt_resid=%d  %d  %d  %x", pkt->pkt_resp_resid,
3082fcf3ce44SJohn Forte 		 * pkt->pkt_rsplen, iocb->un.genreq64.bdl.bdeSize,
3083fcf3ce44SJohn Forte 		 * iocb->un.genreq64.bdl.bdeFlags);
3084fcf3ce44SJohn Forte 		 */
3085fcf3ce44SJohn Forte 
308682527734SSukumar Swaminathan 		if ((iocb->ULPSTATUS == 0) &&
3087fcf3ce44SJohn Forte 		    (rsp_code == SLI_CT_RESPONSE_FS_ACC)) {
3088fcf3ce44SJohn Forte 			HBASTATS.CtCmdGood++;
3089fcf3ce44SJohn Forte 
3090fcf3ce44SJohn Forte 			if (!(sbp->pkt_flags & PACKET_ALLOCATED)) {
3091291a2b48SSukumar Swaminathan 				/* ULP patch - ULP expects */
3092291a2b48SSukumar Swaminathan 				/* resp_resid = 0 on success */
3093fcf3ce44SJohn Forte 				pkt->pkt_resp_resid = 0;
3094fcf3ce44SJohn Forte 			}
3095291a2b48SSukumar Swaminathan 
3096fcf3ce44SJohn Forte 			switch (CtCmd->FsType) {
3097fcf3ce44SJohn Forte 			case 0xFC:	/* Name server */
3098fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3099fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3100fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3101fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
3102fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
3103fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
310482527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3105fcf3ce44SJohn Forte 
3106fcf3ce44SJohn Forte #if (EMLXS_MODREV < EMLXS_MODREV4)
3107fcf3ce44SJohn Forte 				if (cmd_code == SLI_CTNS_RNN_ID) {
3108fcf3ce44SJohn Forte 					emlxs_send_rsnn(port);
3109fcf3ce44SJohn Forte 				}
3110291a2b48SSukumar Swaminathan #endif /* < EMLXS_MODREV4 */
3111fcf3ce44SJohn Forte 
3112fcf3ce44SJohn Forte 				break;
3113fcf3ce44SJohn Forte 
3114fcf3ce44SJohn Forte 			case 0xFA:	/* Managment server */
3115fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3116fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3117fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3118fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(cmd_code),
3119fcf3ce44SJohn Forte 				    emlxs_mscmd_xlate(rsp_code),
3120fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
312182527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3122fcf3ce44SJohn Forte 				break;
3123fcf3ce44SJohn Forte 
3124fcf3ce44SJohn Forte 			case 0x0A:	/* Emulex Remote server */
3125fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3126fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3127fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3128fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(cmd_code),
3129fcf3ce44SJohn Forte 				    emlxs_rmcmd_xlate(rsp_code),
3130fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
313182527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3132fcf3ce44SJohn Forte 				break;
3133fcf3ce44SJohn Forte 
3134fcf3ce44SJohn Forte 			default:
3135fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3136fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3137fcf3ce44SJohn Forte 				    "%s: %s: Rsn=%x Exp=%x [%08x,%08x]",
3138fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
3139fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(rsp_code),
3140fcf3ce44SJohn Forte 				    CtRsp->ReasonCode, CtRsp->Explanation,
314182527734SSukumar Swaminathan 				    LE_SWAP32(rsp[4]), LE_SWAP32(rsp[5]));
3142fcf3ce44SJohn Forte 			}
3143fcf3ce44SJohn Forte 		} else {
3144fcf3ce44SJohn Forte 			HBASTATS.CtCmdError++;
3145fcf3ce44SJohn Forte 
3146fcf3ce44SJohn Forte 			if (rsp_code == SLI_CT_RESPONSE_FS_RJT) {
3147fcf3ce44SJohn Forte 				pkt->pkt_state = FC_PKT_FS_RJT;
3148fcf3ce44SJohn Forte 				pkt->pkt_action = FC_ACTION_RETRYABLE;
3149fcf3ce44SJohn Forte 				pkt->pkt_reason = CtRsp->ReasonCode;
3150fcf3ce44SJohn Forte 				pkt->pkt_expln = CtRsp->Explanation;
3151fcf3ce44SJohn Forte 				sbp->pkt_flags |= PACKET_STATE_VALID;
3152fcf3ce44SJohn Forte 
3153fcf3ce44SJohn Forte 				EMLXS_MSGF(EMLXS_CONTEXT,
3154fcf3ce44SJohn Forte 				    &emlxs_ct_completion_msg,
3155fcf3ce44SJohn Forte 				    "%s: Rejected. rsn=%x exp=%x",
3156fcf3ce44SJohn Forte 				    emlxs_ctcmd_xlate(cmd_code),
3157291a2b48SSukumar Swaminathan 				    pkt->pkt_reason, pkt->pkt_expln);
315882527734SSukumar Swaminathan 			} else if (iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) {
3159fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
3160fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
3161fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3162fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3163fcf3ce44SJohn Forte 					    "%s: %s %s",
3164fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3165291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
316682527734SSukumar Swaminathan 					    ULPSTATUS),
3167291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3168291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3169fcf3ce44SJohn Forte 					break;
3170fcf3ce44SJohn Forte 
3171fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
3172fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3173fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3174fcf3ce44SJohn Forte 					    "%s: %s %s",
3175fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
3176291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
317782527734SSukumar Swaminathan 					    ULPSTATUS),
3178291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3179291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3180fcf3ce44SJohn Forte 					break;
3181fcf3ce44SJohn Forte 
3182fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
3183fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3184fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3185fcf3ce44SJohn Forte 					    "%s: %s %s",
3186fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
3187291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
318882527734SSukumar Swaminathan 					    ULPSTATUS),
3189291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3190291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3191fcf3ce44SJohn Forte 					break;
3192fcf3ce44SJohn Forte 
3193fcf3ce44SJohn Forte 				default:
3194fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3195fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3196fcf3ce44SJohn Forte 					    "%s: %s %s",
3197fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3198291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
319982527734SSukumar Swaminathan 					    ULPSTATUS),
3200291a2b48SSukumar Swaminathan 					    emlxs_error_xlate(iocb->un.grsp.
3201291a2b48SSukumar Swaminathan 					    perr.statLocalError));
3202fcf3ce44SJohn Forte 				}
3203fcf3ce44SJohn Forte 			} else {
3204fcf3ce44SJohn Forte 				switch (CtCmd->FsType) {
3205fcf3ce44SJohn Forte 				case 0xFC:	/* Name server */
3206fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3207fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3208fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3209fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3210291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
321182527734SSukumar Swaminathan 					    ULPSTATUS),
3212fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3213fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3214fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3215291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3216291a2b48SSukumar Swaminathan 					    statLocalError);
3217fcf3ce44SJohn Forte 					break;
3218fcf3ce44SJohn Forte 
3219fcf3ce44SJohn Forte 				case 0xFA:	/* Managment server */
3220fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3221fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3222fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3223fcf3ce44SJohn Forte 					    emlxs_mscmd_xlate(cmd_code),
3224291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
322582527734SSukumar Swaminathan 					    ULPSTATUS),
3226fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3227fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3228fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3229291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3230291a2b48SSukumar Swaminathan 					    statLocalError);
3231fcf3ce44SJohn Forte 					break;
3232fcf3ce44SJohn Forte 
3233fcf3ce44SJohn Forte 				case 0x0A:	/* Emulex Remote server */
3234fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3235fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3236fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3237fcf3ce44SJohn Forte 					    emlxs_rmcmd_xlate(cmd_code),
3238291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
323982527734SSukumar Swaminathan 					    ULPSTATUS),
3240fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3241fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3242fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3243291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3244291a2b48SSukumar Swaminathan 					    statLocalError);
3245fcf3ce44SJohn Forte 					break;
3246fcf3ce44SJohn Forte 
3247fcf3ce44SJohn Forte 				default:
3248fcf3ce44SJohn Forte 					EMLXS_MSGF(EMLXS_CONTEXT,
3249fcf3ce44SJohn Forte 					    &emlxs_ct_completion_msg,
3250fcf3ce44SJohn Forte 					    "%s: %s (%02x%02x%02x%02x)",
3251fcf3ce44SJohn Forte 					    emlxs_ctcmd_xlate(cmd_code),
3252291a2b48SSukumar Swaminathan 					    emlxs_state_xlate(iocb->
325382527734SSukumar Swaminathan 					    ULPSTATUS),
3254fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statAction,
3255fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statRsn,
3256fcf3ce44SJohn Forte 					    iocb->un.grsp.perr.statBaExp,
3257291a2b48SSukumar Swaminathan 					    iocb->un.grsp.perr.
3258291a2b48SSukumar Swaminathan 					    statLocalError);
3259fcf3ce44SJohn Forte 				}
3260fcf3ce44SJohn Forte 			}
3261fcf3ce44SJohn Forte 		}
3262fcf3ce44SJohn Forte 
326382527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
3264fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
3265fcf3ce44SJohn Forte 
3266fcf3ce44SJohn Forte 		break;
3267fcf3ce44SJohn Forte 
3268fcf3ce44SJohn Forte 	default:
3269fcf3ce44SJohn Forte 
3270fcf3ce44SJohn Forte 		HBASTATS.CtStray++;
3271fcf3ce44SJohn Forte 
3272fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_invalid_ct_msg,
327382527734SSukumar Swaminathan 		    "Invalid iocb: cmd=0x%x", iocb->ULPCOMMAND);
3274fcf3ce44SJohn Forte 
327582527734SSukumar Swaminathan 		emlxs_pkt_complete(sbp, iocb->ULPSTATUS,
3276fcf3ce44SJohn Forte 		    iocb->un.grsp.perr.statLocalError, 1);
3277fcf3ce44SJohn Forte 
3278fcf3ce44SJohn Forte 		break;
327982527734SSukumar Swaminathan 	}	/* switch(iocb->ULPCOMMAND) */
3280fcf3ce44SJohn Forte 
3281fcf3ce44SJohn Forte 	return (0);
3282fcf3ce44SJohn Forte 
328382527734SSukumar Swaminathan } /* emlxs_ct_handle_event() */
3284fcf3ce44SJohn Forte 
3285fcf3ce44SJohn Forte 
3286fcf3ce44SJohn Forte extern int
emlxs_ct_handle_unsol_req(emlxs_port_t * port,CHANNEL * cp,IOCBQ * iocbq,MATCHMAP * mp,uint32_t size)328782527734SSukumar Swaminathan emlxs_ct_handle_unsol_req(emlxs_port_t *port, CHANNEL *cp, IOCBQ *iocbq,
3288fcf3ce44SJohn Forte     MATCHMAP *mp, uint32_t size)
3289fcf3ce44SJohn Forte {
3290fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3291fcf3ce44SJohn Forte 	IOCB *iocb;
3292fcf3ce44SJohn Forte 	SLI_CT_REQUEST *CtCmd;
3293fcf3ce44SJohn Forte 	uint32_t cmd_code;
3294fcf3ce44SJohn Forte 
3295fcf3ce44SJohn Forte 	iocb = &iocbq->iocb;
3296fcf3ce44SJohn Forte 
3297fcf3ce44SJohn Forte 	CtCmd = (SLI_CT_REQUEST *)mp->virt;
329882527734SSukumar Swaminathan 	cmd_code = LE_SWAP16(CtCmd->CommandResponse.bits.CmdRsp);
3299fcf3ce44SJohn Forte 
3300fcf3ce44SJohn Forte 	if (cmd_code == SLI_CT_LOOPBACK) {
3301fcf3ce44SJohn Forte 		int rval;
3302fcf3ce44SJohn Forte 
330382527734SSukumar Swaminathan 		rval = emlxs_dfc_handle_unsol_req(port, cp, iocbq, mp, size);
3304fcf3ce44SJohn Forte 
3305fcf3ce44SJohn Forte 		return (rval);
3306fcf3ce44SJohn Forte 	}
3307fcf3ce44SJohn Forte 
3308fcf3ce44SJohn Forte 	HBASTATS.CtCmdReceived++;
3309fcf3ce44SJohn Forte 
3310fcf3ce44SJohn Forte 	switch (CtCmd->FsType) {
3311fcf3ce44SJohn Forte 	case 0xFC:	/* Name server */
3312fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3313291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
331482527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3315fcf3ce44SJohn Forte 		break;
3316fcf3ce44SJohn Forte 
3317fcf3ce44SJohn Forte 	case 0xFA:	/* Managment server */
3318fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3319291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_mscmd_xlate(cmd_code),
332082527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3321fcf3ce44SJohn Forte 		break;
3322fcf3ce44SJohn Forte 
3323fcf3ce44SJohn Forte 	case 0x0A:	/* Emulex Remote server */
3324fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3325291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_rmcmd_xlate(cmd_code),
332682527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3327fcf3ce44SJohn Forte 		break;
3328fcf3ce44SJohn Forte 
3329fcf3ce44SJohn Forte 	default:
3330fcf3ce44SJohn Forte 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_unsol_ct_msg,
3331291a2b48SSukumar Swaminathan 		    "%s: pl=%p size=%d rxid=%x", emlxs_ctcmd_xlate(cmd_code),
333282527734SSukumar Swaminathan 		    CtCmd, size, iocb->ULPCONTEXT);
3333fcf3ce44SJohn Forte 	}
3334fcf3ce44SJohn Forte 
3335728bdc9bSSukumar Swaminathan 	if (emlxs_log_ct_event(port, (uint8_t *)mp->virt, size,
333682527734SSukumar Swaminathan 	    iocb->ULPCONTEXT)) {
3337728bdc9bSSukumar Swaminathan 		/* Abort the exchange */
333882527734SSukumar Swaminathan 		emlxs_abort_ct_exchange(hba, port, iocb->ULPCONTEXT);
3339728bdc9bSSukumar Swaminathan 	}
3340fcf3ce44SJohn Forte 
3341fcf3ce44SJohn Forte 	return (0);
3342fcf3ce44SJohn Forte 
334382527734SSukumar Swaminathan } /* emlxs_ct_handle_unsol_req() */
3344fcf3ce44SJohn Forte 
3345fcf3ce44SJohn Forte 
3346a9800bebSGarrett D'Amore #if (EMLXS_MODREV < EMLXS_MODREV4)
3347fcf3ce44SJohn Forte static void
emlxs_send_rsnn(emlxs_port_t * port)3348fcf3ce44SJohn Forte emlxs_send_rsnn(emlxs_port_t *port)
3349fcf3ce44SJohn Forte {
3350fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3351fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3352fcf3ce44SJohn Forte 	SLI_CT_REQUEST *ct;
3353fcf3ce44SJohn Forte 
3354291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port, sizeof (SLI_CT_REQUEST),
3355291a2b48SSukumar Swaminathan 	    sizeof (SLI_CT_REQUEST), 0, KM_NOSLEEP))) {
3356fcf3ce44SJohn Forte 		return;
3357fcf3ce44SJohn Forte 	}
3358291a2b48SSukumar Swaminathan 
3359fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3360fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3361fcf3ce44SJohn Forte 
3362fcf3ce44SJohn Forte 	/* Build the fc header */
336382527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(NAMESERVER_DID);
3364fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.r_ctl = R_CTL_UNSOL_CONTROL;
336582527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3366fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_FC_SERVICES;
3367291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3368291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
3369fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3370fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3371fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3372fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
3373fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
3374fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3375fcf3ce44SJohn Forte 
3376fcf3ce44SJohn Forte 	/* Build the command */
3377fcf3ce44SJohn Forte 	ct = (SLI_CT_REQUEST *)pkt->pkt_cmd;
3378fcf3ce44SJohn Forte 
3379fcf3ce44SJohn Forte 	ct->RevisionId.bits.Revision = SLI_CT_REVISION;
3380fcf3ce44SJohn Forte 	ct->RevisionId.bits.InId = 0;
3381fcf3ce44SJohn Forte 
3382fcf3ce44SJohn Forte 	ct->FsType = SLI_CT_DIRECTORY_SERVICE;
3383fcf3ce44SJohn Forte 	ct->FsSubType = SLI_CT_DIRECTORY_NAME_SERVER;
3384fcf3ce44SJohn Forte 
3385fcf3ce44SJohn Forte 	ct->CommandResponse.bits.Size = 0;
338682527734SSukumar Swaminathan 	ct->CommandResponse.bits.CmdRsp = LE_SWAP16(SLI_CTNS_RSNN_NN);
3387fcf3ce44SJohn Forte 
3388fcf3ce44SJohn Forte 	bcopy((uint8_t *)&hba->wwnn, (char *)ct->un.rsnn.wwnn, 8);
3389fcf3ce44SJohn Forte 
3390fcf3ce44SJohn Forte 	ct->un.rsnn.snn_len = strlen(port->snn);
3391fcf3ce44SJohn Forte 	bcopy(port->snn, (char *)ct->un.rsnn.snn, ct->un.rsnn.snn_len);
3392fcf3ce44SJohn Forte 
3393291a2b48SSukumar Swaminathan 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ct_send_msg, "Sending RSNN_NN. [%s]",
3394fcf3ce44SJohn Forte 	    port->snn);
3395fcf3ce44SJohn Forte 
3396fcf3ce44SJohn Forte 	/* Send the pkt later in another thread */
3397fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 0) != FC_SUCCESS) {
3398fcf3ce44SJohn Forte 		/* Free the pkt */
3399fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3400fcf3ce44SJohn Forte 	}
3401291a2b48SSukumar Swaminathan 
3402fcf3ce44SJohn Forte 	return;
3403fcf3ce44SJohn Forte 
340482527734SSukumar Swaminathan } /* emlxs_send_rsnn() */
3405a9800bebSGarrett D'Amore #endif /* < EMLXS_MODREV4 */
3406a9800bebSGarrett D'Amore 
3407fcf3ce44SJohn Forte 
3408fcf3ce44SJohn Forte 
3409*8f23e9faSHans Rosenfeld 
3410fcf3ce44SJohn Forte extern uint32_t
emlxs_ub_send_login_acc(emlxs_port_t * port,fc_unsol_buf_t * ubp)3411fcf3ce44SJohn Forte emlxs_ub_send_login_acc(emlxs_port_t *port, fc_unsol_buf_t *ubp)
3412fcf3ce44SJohn Forte {
3413fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3414fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3415fcf3ce44SJohn Forte 	ELS_PKT *els;
3416fcf3ce44SJohn Forte 	uint32_t rval;
3417fcf3ce44SJohn Forte 	emlxs_ub_priv_t *ub_priv;
3418fcf3ce44SJohn Forte 
3419fcf3ce44SJohn Forte 	ub_priv = ubp->ub_fca_private;
3420fcf3ce44SJohn Forte 
3421fcf3ce44SJohn Forte 	if (!(pkt = emlxs_pkt_alloc(port,
3422fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (SERV_PARM), 0, 0, KM_NOSLEEP))) {
3423fcf3ce44SJohn Forte 		return (1);
3424fcf3ce44SJohn Forte 	}
3425291a2b48SSukumar Swaminathan 
3426fcf3ce44SJohn Forte 	/* Common initialization */
3427fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_OUTBOUND;
3428fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3429fcf3ce44SJohn Forte 
3430fcf3ce44SJohn Forte 	if ((uint32_t)ubp->ub_class == FC_TRAN_CLASS2) {
3431fcf3ce44SJohn Forte 		pkt->pkt_tran_flags &= ~FC_TRAN_CLASS3;
3432fcf3ce44SJohn Forte 		pkt->pkt_tran_flags |= FC_TRAN_CLASS2;
3433fcf3ce44SJohn Forte 	}
3434291a2b48SSukumar Swaminathan 
3435fcf3ce44SJohn Forte 	/* Build the fc header */
3436fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.d_id = ubp->ub_frame.s_id;
3437291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3438291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
3439fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.s_id = ubp->ub_frame.d_id;
3440fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3441291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3442291a2b48SSukumar Swaminathan 	    F_CTL_XCHG_CONTEXT | F_CTL_LAST_SEQ | F_CTL_END_SEQ;
3443fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3444fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3445fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3446fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = (ub_priv->cmd >> ELS_CMD_SHIFT) & 0xff;
3447fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = ubp->ub_frame.rx_id;
3448fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3449fcf3ce44SJohn Forte 
3450fcf3ce44SJohn Forte 	/* Build the command */
3451291a2b48SSukumar Swaminathan 	els = (ELS_PKT *)pkt->pkt_cmd;
3452fcf3ce44SJohn Forte 	els->elsCode = 0x02;
3453291a2b48SSukumar Swaminathan 	bcopy((void *)&port->sparam, (void *)&els->un.logi,
3454291a2b48SSukumar Swaminathan 	    sizeof (SERV_PARM));
3455fcf3ce44SJohn Forte 
3456fcf3ce44SJohn Forte 	if ((rval = emlxs_pkt_send(pkt, 1)) != FC_SUCCESS) {
3457fcf3ce44SJohn Forte 		/* Free the pkt */
3458fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3459fcf3ce44SJohn Forte 	} else {
3460fcf3ce44SJohn Forte 		ub_priv->flags |= EMLXS_UB_INTERCEPT;
3461fcf3ce44SJohn Forte 	}
3462fcf3ce44SJohn Forte 
3463fcf3ce44SJohn Forte 	return (rval);
3464fcf3ce44SJohn Forte 
346582527734SSukumar Swaminathan } /* emlxs_ub_send_login_acc */
3466fcf3ce44SJohn Forte 
3467fcf3ce44SJohn Forte 
3468fcf3ce44SJohn Forte extern void
emlxs_send_logo(emlxs_port_t * port,uint32_t d_id)3469fcf3ce44SJohn Forte emlxs_send_logo(emlxs_port_t *port, uint32_t d_id)
3470fcf3ce44SJohn Forte {
3471fcf3ce44SJohn Forte 	emlxs_hba_t *hba = HBA;
3472fcf3ce44SJohn Forte 	fc_packet_t *pkt;
3473fcf3ce44SJohn Forte 	ELS_PKT *els;
3474fcf3ce44SJohn Forte 
3475*8f23e9faSHans Rosenfeld 	if (!(hba->flag & FC_ONLINE_MODE)) {
3476*8f23e9faSHans Rosenfeld 		return;
3477*8f23e9faSHans Rosenfeld 	}
3478*8f23e9faSHans Rosenfeld 
3479fcf3ce44SJohn Forte 	if (hba->state <= FC_LINK_DOWN) {
3480fcf3ce44SJohn Forte 		return;
3481fcf3ce44SJohn Forte 	}
3482291a2b48SSukumar Swaminathan 
3483291a2b48SSukumar Swaminathan 	if (!(pkt = emlxs_pkt_alloc(port,
3484291a2b48SSukumar Swaminathan 	    sizeof (uint32_t) + sizeof (LOGO),
3485fcf3ce44SJohn Forte 	    sizeof (uint32_t) + sizeof (LOGO), 0, KM_NOSLEEP))) {
3486fcf3ce44SJohn Forte 		return;
3487fcf3ce44SJohn Forte 	}
3488291a2b48SSukumar Swaminathan 
3489fcf3ce44SJohn Forte 	pkt->pkt_tran_type = FC_PKT_EXCHANGE;
3490fcf3ce44SJohn Forte 	pkt->pkt_timeout = (2 * hba->fc_ratov);
3491fcf3ce44SJohn Forte 
3492fcf3ce44SJohn Forte 	/* Build the fc header */
349382527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.d_id = LE_SWAP24_LO(d_id);
3494291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.r_ctl =
3495291a2b48SSukumar Swaminathan 	    R_CTL_EXTENDED_SVC | R_CTL_SOLICITED_CONTROL;
349682527734SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.s_id = LE_SWAP24_LO(port->did);
3497fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.type = FC_TYPE_EXTENDED_LS;
3498291a2b48SSukumar Swaminathan 	pkt->pkt_cmd_fhdr.f_ctl =
3499291a2b48SSukumar Swaminathan 	    F_CTL_FIRST_SEQ | F_CTL_END_SEQ | F_CTL_SEQ_INITIATIVE;
3500fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_id = 0;
3501fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.df_ctl = 0;
3502fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.seq_cnt = 0;
3503fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ox_id = 0xffff;
3504fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.rx_id = 0xffff;
3505fcf3ce44SJohn Forte 	pkt->pkt_cmd_fhdr.ro = 0;
3506fcf3ce44SJohn Forte 
3507fcf3ce44SJohn Forte 	/* Build the command */
3508fcf3ce44SJohn Forte 	els = (ELS_PKT *)pkt->pkt_cmd;
3509fcf3ce44SJohn Forte 	els->elsCode = 0x05;
3510fcf3ce44SJohn Forte 	els->un.logo.un.nPortId32 = pkt->pkt_cmd_fhdr.s_id;
3511291a2b48SSukumar Swaminathan 	bcopy((uint8_t *)&port->wwpn, (uint8_t *)&els->un.logo.portName,
3512291a2b48SSukumar Swaminathan 	    8);
3513fcf3ce44SJohn Forte 
3514fcf3ce44SJohn Forte 	/* Send the pkt now */
3515fcf3ce44SJohn Forte 	if (emlxs_pkt_send(pkt, 1) != FC_SUCCESS) {
3516fcf3ce44SJohn Forte 		/* Free the pkt */
3517fcf3ce44SJohn Forte 		emlxs_pkt_free(pkt);
3518fcf3ce44SJohn Forte 	}
3519291a2b48SSukumar Swaminathan 
3520fcf3ce44SJohn Forte 	return;
3521fcf3ce44SJohn Forte 
3522fcf3ce44SJohn Forte } /* emlxs_send_logo() */
3523