xref: /titanic_51/usr/src/uts/common/io/fibre-channel/fca/emlxs/emlxs_sli3.c (revision 8f23e9fa8abcb5857661066b954e63400d589b65)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at
9  * http://www.opensource.org/licenses/cddl1.txt.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2004-2012 Emulex. All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <emlxs.h>
28 
29 /* Required for EMLXS_CONTEXT in EMLXS_MSGF calls */
30 EMLXS_MSG_DEF(EMLXS_SLI3_C);
31 
32 static void emlxs_sli3_issue_iocb(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq);
33 static void emlxs_sli3_handle_link_event(emlxs_hba_t *hba);
34 static void emlxs_sli3_handle_ring_event(emlxs_hba_t *hba, int32_t ring_no,
35 	uint32_t ha_copy);
36 #ifdef SFCT_SUPPORT
37 static uint32_t emlxs_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
38 #endif /* SFCT_SUPPORT */
39 
40 static uint32_t	emlxs_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp);
41 
42 static uint32_t emlxs_disable_traffic_cop = 1;
43 
44 static int			emlxs_sli3_map_hdw(emlxs_hba_t *hba);
45 
46 static void			emlxs_sli3_unmap_hdw(emlxs_hba_t *hba);
47 
48 static int32_t			emlxs_sli3_online(emlxs_hba_t *hba);
49 
50 static void			emlxs_sli3_offline(emlxs_hba_t *hba,
51 					uint32_t reset_requested);
52 
53 static uint32_t			emlxs_sli3_hba_reset(emlxs_hba_t *hba,
54 					uint32_t restart, uint32_t skip_post,
55 					uint32_t quiesce);
56 
57 static void			emlxs_sli3_hba_kill(emlxs_hba_t *hba);
58 static void			emlxs_sli3_hba_kill4quiesce(emlxs_hba_t *hba);
59 static uint32_t			emlxs_sli3_hba_init(emlxs_hba_t *hba);
60 
61 static uint32_t			emlxs_sli2_bde_setup(emlxs_port_t *port,
62 					emlxs_buf_t *sbp);
63 static uint32_t			emlxs_sli3_bde_setup(emlxs_port_t *port,
64 					emlxs_buf_t *sbp);
65 static uint32_t			emlxs_sli2_fct_bde_setup(emlxs_port_t *port,
66 					emlxs_buf_t *sbp);
67 static uint32_t			emlxs_sli3_fct_bde_setup(emlxs_port_t *port,
68 					emlxs_buf_t *sbp);
69 
70 
71 static void			emlxs_sli3_issue_iocb_cmd(emlxs_hba_t *hba,
72 					CHANNEL *rp, IOCBQ *iocb_cmd);
73 
74 
75 static uint32_t			emlxs_sli3_issue_mbox_cmd(emlxs_hba_t *hba,
76 					MAILBOXQ *mbq, int32_t flg,
77 					uint32_t tmo);
78 
79 
80 #ifdef SFCT_SUPPORT
81 static uint32_t			emlxs_sli3_prep_fct_iocb(emlxs_port_t *port,
82 					emlxs_buf_t *cmd_sbp, int channel);
83 
84 #endif /* SFCT_SUPPORT */
85 
86 static uint32_t			emlxs_sli3_prep_fcp_iocb(emlxs_port_t *port,
87 					emlxs_buf_t *sbp, int ring);
88 
89 static uint32_t			emlxs_sli3_prep_ip_iocb(emlxs_port_t *port,
90 					emlxs_buf_t *sbp);
91 
92 static uint32_t			emlxs_sli3_prep_els_iocb(emlxs_port_t *port,
93 					emlxs_buf_t *sbp);
94 
95 
96 static uint32_t			emlxs_sli3_prep_ct_iocb(emlxs_port_t *port,
97 					emlxs_buf_t *sbp);
98 
99 
100 static void			emlxs_sli3_poll_intr(emlxs_hba_t *hba);
101 
102 static int32_t			emlxs_sli3_intx_intr(char *arg);
103 #ifdef MSI_SUPPORT
104 static uint32_t			emlxs_sli3_msi_intr(char *arg1, char *arg2);
105 #endif /* MSI_SUPPORT */
106 
107 static void			emlxs_sli3_enable_intr(emlxs_hba_t *hba);
108 
109 static void			emlxs_sli3_disable_intr(emlxs_hba_t *hba,
110 					uint32_t att);
111 
112 
113 static void			emlxs_handle_ff_error(emlxs_hba_t *hba);
114 
115 static uint32_t			emlxs_handle_mb_event(emlxs_hba_t *hba);
116 
117 static void			emlxs_sli3_timer_check_mbox(emlxs_hba_t *hba);
118 
119 static uint32_t			emlxs_mb_config_port(emlxs_hba_t *hba,
120 					MAILBOXQ *mbq, uint32_t sli_mode,
121 					uint32_t hbainit);
122 static void			emlxs_enable_latt(emlxs_hba_t *hba);
123 
124 static uint32_t			emlxs_check_attention(emlxs_hba_t *hba);
125 
126 static uint32_t			emlxs_get_attention(emlxs_hba_t *hba,
127 					int32_t msgid);
128 static void			emlxs_proc_attention(emlxs_hba_t *hba,
129 					uint32_t ha_copy);
130 /* static int			emlxs_handle_rcv_seq(emlxs_hba_t *hba, */
131 					/* CHANNEL *cp, IOCBQ *iocbq); */
132 /* static void			emlxs_update_HBQ_index(emlxs_hba_t *hba, */
133 					/* uint32_t hbq_id); */
134 /* static void			emlxs_hbq_free_all(emlxs_hba_t *hba, */
135 					/* uint32_t hbq_id); */
136 static uint32_t			emlxs_hbq_setup(emlxs_hba_t *hba,
137 					uint32_t hbq_id);
138 static void			emlxs_sli3_timer(emlxs_hba_t *hba);
139 
140 static void			emlxs_sli3_poll_erratt(emlxs_hba_t *hba);
141 
142 static uint32_t			emlxs_sli3_reg_did(emlxs_port_t *port,
143 					uint32_t did, SERV_PARM *param,
144 					emlxs_buf_t *sbp, fc_unsol_buf_t *ubp,
145 					IOCBQ *iocbq);
146 
147 static uint32_t			emlxs_sli3_unreg_node(emlxs_port_t *port,
148 					NODELIST *node, emlxs_buf_t *sbp,
149 					fc_unsol_buf_t *ubp, IOCBQ *iocbq);
150 
151 
152 /* Define SLI3 API functions */
153 emlxs_sli_api_t emlxs_sli3_api = {
154 	emlxs_sli3_map_hdw,
155 	emlxs_sli3_unmap_hdw,
156 	emlxs_sli3_online,
157 	emlxs_sli3_offline,
158 	emlxs_sli3_hba_reset,
159 	emlxs_sli3_hba_kill,
160 	emlxs_sli3_issue_iocb_cmd,
161 	emlxs_sli3_issue_mbox_cmd,
162 #ifdef SFCT_SUPPORT
163 	emlxs_sli3_prep_fct_iocb,
164 #else
165 	NULL,
166 #endif /* SFCT_SUPPORT */
167 	emlxs_sli3_prep_fcp_iocb,
168 	emlxs_sli3_prep_ip_iocb,
169 	emlxs_sli3_prep_els_iocb,
170 	emlxs_sli3_prep_ct_iocb,
171 	emlxs_sli3_poll_intr,
172 	emlxs_sli3_intx_intr,
173 	emlxs_sli3_msi_intr,
174 	emlxs_sli3_disable_intr,
175 	emlxs_sli3_timer,
176 	emlxs_sli3_poll_erratt,
177 	emlxs_sli3_reg_did,
178 	emlxs_sli3_unreg_node
179 };
180 
181 
182 /*
183  * emlxs_sli3_online()
184  *
185  * This routine will start initialization of the SLI2/3 HBA.
186  */
187 static int32_t
188 emlxs_sli3_online(emlxs_hba_t *hba)
189 {
190 	emlxs_port_t *port = &PPORT;
191 	emlxs_config_t *cfg;
192 	emlxs_vpd_t *vpd;
193 	MAILBOX *mb = NULL;
194 	MAILBOXQ *mbq = NULL;
195 	RING *rp;
196 	CHANNEL *cp;
197 	MATCHMAP *mp = NULL;
198 	MATCHMAP *mp1 = NULL;
199 	uint8_t *inptr;
200 	uint8_t *outptr;
201 	uint32_t status;
202 	uint16_t i;
203 	uint32_t j;
204 	uint32_t read_rev_reset;
205 	uint32_t key = 0;
206 	uint32_t fw_check;
207 	uint32_t kern_update = 0;
208 	uint32_t rval = 0;
209 	uint32_t offset;
210 	uint8_t vpd_data[DMP_VPD_SIZE];
211 	uint32_t MaxRbusSize;
212 	uint32_t MaxIbusSize;
213 	uint32_t sli_mode;
214 	uint32_t sli_mode_mask;
215 
216 	cfg = &CFG;
217 	vpd = &VPD;
218 	MaxRbusSize = 0;
219 	MaxIbusSize = 0;
220 	read_rev_reset = 0;
221 	hba->chan_count = MAX_RINGS;
222 
223 	if (hba->bus_type == SBUS_FC) {
224 		(void) READ_SBUS_CSR_REG(hba, FC_SHS_REG(hba));
225 	}
226 
227 	/* Set the fw_check flag */
228 	fw_check = cfg[CFG_FW_CHECK].current;
229 
230 	if ((fw_check & 0x04) ||
231 	    (hba->fw_flag & FW_UPDATE_KERNEL)) {
232 		kern_update = 1;
233 	}
234 
235 	hba->mbox_queue_flag = 0;
236 	hba->sli.sli3.hc_copy = 0;
237 	hba->fc_edtov = FF_DEF_EDTOV;
238 	hba->fc_ratov = FF_DEF_RATOV;
239 	hba->fc_altov = FF_DEF_ALTOV;
240 	hba->fc_arbtov = FF_DEF_ARBTOV;
241 
242 	/*
243 	 * Get a buffer which will be used repeatedly for mailbox commands
244 	 */
245 	mbq = (MAILBOXQ *) kmem_zalloc((sizeof (MAILBOXQ)), KM_SLEEP);
246 
247 	mb = (MAILBOX *)mbq;
248 
249 	/* Initialize sli mode based on configuration parameter */
250 	switch (cfg[CFG_SLI_MODE].current) {
251 	case 2:	/* SLI2 mode */
252 		sli_mode = EMLXS_HBA_SLI2_MODE;
253 		sli_mode_mask = EMLXS_SLI2_MASK;
254 		break;
255 
256 	case 3:	/* SLI3 mode */
257 		sli_mode = EMLXS_HBA_SLI3_MODE;
258 		sli_mode_mask = EMLXS_SLI3_MASK;
259 		break;
260 
261 	case 0:	/* Best available */
262 	case 1:	/* Best available */
263 	default:
264 		if (hba->model_info.sli_mask & EMLXS_SLI3_MASK) {
265 			sli_mode = EMLXS_HBA_SLI3_MODE;
266 			sli_mode_mask = EMLXS_SLI3_MASK;
267 		} else if (hba->model_info.sli_mask & EMLXS_SLI2_MASK) {
268 			sli_mode = EMLXS_HBA_SLI2_MODE;
269 			sli_mode_mask = EMLXS_SLI2_MASK;
270 		} else {
271 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
272 			    "No SLI mode available.");
273 			rval = EIO;
274 			goto failed;
275 		}
276 		break;
277 	}
278 	/* SBUS adapters only available in SLI2 */
279 	if (hba->bus_type == SBUS_FC) {
280 		sli_mode = EMLXS_HBA_SLI2_MODE;
281 		sli_mode_mask = EMLXS_SLI2_MASK;
282 	}
283 
284 reset:
285 	/* Reset & Initialize the adapter */
286 	if (emlxs_sli3_hba_init(hba)) {
287 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
288 		    "Unable to init hba.");
289 
290 		rval = EIO;
291 		goto failed;
292 	}
293 
294 #ifdef FMA_SUPPORT
295 	/* Access handle validation */
296 	if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle)
297 	    != DDI_FM_OK) ||
298 	    (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
299 	    != DDI_FM_OK) ||
300 	    (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.csr_acc_handle)
301 	    != DDI_FM_OK)) {
302 		EMLXS_MSGF(EMLXS_CONTEXT,
303 		    &emlxs_invalid_access_handle_msg, NULL);
304 
305 		rval = EIO;
306 		goto failed;
307 	}
308 #endif	/* FMA_SUPPORT */
309 
310 	/* Check for PEGASUS (This is a special case) */
311 	/* We need to check for dual channel adapter */
312 	if (hba->model_info.device_id == PCI_DEVICE_ID_PEGASUS) {
313 		/* Try to determine if this is a DC adapter */
314 		if (emlxs_get_max_sram(hba, &MaxRbusSize, &MaxIbusSize) == 0) {
315 			if (MaxRbusSize == REDUCED_SRAM_CFG) {
316 				/* LP9802DC */
317 				for (i = 1; i < emlxs_pci_model_count; i++) {
318 					if (emlxs_pci_model[i].id == LP9802DC) {
319 						bcopy(&emlxs_pci_model[i],
320 						    &hba->model_info,
321 						    sizeof (emlxs_model_t));
322 						break;
323 					}
324 				}
325 			} else if (hba->model_info.id != LP9802) {
326 				/* LP9802 */
327 				for (i = 1; i < emlxs_pci_model_count; i++) {
328 					if (emlxs_pci_model[i].id == LP9802) {
329 						bcopy(&emlxs_pci_model[i],
330 						    &hba->model_info,
331 						    sizeof (emlxs_model_t));
332 						break;
333 					}
334 				}
335 			}
336 		}
337 	}
338 
339 	/*
340 	 * Setup and issue mailbox READ REV command
341 	 */
342 	vpd->opFwRev = 0;
343 	vpd->postKernRev = 0;
344 	vpd->sli1FwRev = 0;
345 	vpd->sli2FwRev = 0;
346 	vpd->sli3FwRev = 0;
347 	vpd->sli4FwRev = 0;
348 
349 	vpd->postKernName[0] = 0;
350 	vpd->opFwName[0] = 0;
351 	vpd->sli1FwName[0] = 0;
352 	vpd->sli2FwName[0] = 0;
353 	vpd->sli3FwName[0] = 0;
354 	vpd->sli4FwName[0] = 0;
355 
356 	vpd->opFwLabel[0] = 0;
357 	vpd->sli1FwLabel[0] = 0;
358 	vpd->sli2FwLabel[0] = 0;
359 	vpd->sli3FwLabel[0] = 0;
360 	vpd->sli4FwLabel[0] = 0;
361 
362 	/* Sanity check */
363 	if (hba->model_info.sli_mask & EMLXS_SLI4_MASK) {
364 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
365 		    "Adapter / SLI mode mismatch mask:x%x",
366 		    hba->model_info.sli_mask);
367 
368 		rval = EIO;
369 		goto failed;
370 	}
371 
372 	EMLXS_STATE_CHANGE(hba, FC_INIT_REV);
373 	emlxs_mb_read_rev(hba, mbq, 0);
374 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
375 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
376 		    "Unable to read rev. Mailbox cmd=%x status=%x",
377 		    mb->mbxCommand, mb->mbxStatus);
378 
379 		rval = EIO;
380 		goto failed;
381 	}
382 
383 	if (mb->un.varRdRev.rr == 0) {
384 		/* Old firmware */
385 		if (read_rev_reset == 0) {
386 			read_rev_reset = 1;
387 
388 			goto reset;
389 		} else {
390 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
391 			    "Outdated firmware detected.");
392 		}
393 
394 		vpd->rBit = 0;
395 	} else {
396 		if (mb->un.varRdRev.un.b.ProgType != FUNC_FIRMWARE) {
397 			if (read_rev_reset == 0) {
398 				read_rev_reset = 1;
399 
400 				goto reset;
401 			} else {
402 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
403 				    "Non-operational firmware detected. "
404 				    "type=%x",
405 				    mb->un.varRdRev.un.b.ProgType);
406 			}
407 		}
408 
409 		vpd->rBit = 1;
410 		vpd->sli1FwRev = mb->un.varRdRev.sliFwRev1;
411 		bcopy((char *)mb->un.varRdRev.sliFwName1, vpd->sli1FwLabel,
412 		    16);
413 		vpd->sli2FwRev = mb->un.varRdRev.sliFwRev2;
414 		bcopy((char *)mb->un.varRdRev.sliFwName2, vpd->sli2FwLabel,
415 		    16);
416 
417 		/*
418 		 * Lets try to read the SLI3 version
419 		 * Setup and issue mailbox READ REV(v3) command
420 		 */
421 		EMLXS_STATE_CHANGE(hba, FC_INIT_REV);
422 
423 		/* Reuse mbq from previous mbox */
424 		bzero(mbq, sizeof (MAILBOXQ));
425 
426 		emlxs_mb_read_rev(hba, mbq, 1);
427 
428 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
429 		    MBX_SUCCESS) {
430 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
431 			    "Unable to read rev (v3). Mailbox cmd=%x status=%x",
432 			    mb->mbxCommand, mb->mbxStatus);
433 
434 			rval = EIO;
435 			goto failed;
436 		}
437 
438 		if (mb->un.varRdRev.rf3) {
439 			/*
440 			 * vpd->sli2FwRev = mb->un.varRdRev.sliFwRev1;
441 			 * Not needed
442 			 */
443 			vpd->sli3FwRev = mb->un.varRdRev.sliFwRev2;
444 			bcopy((char *)mb->un.varRdRev.sliFwName2,
445 			    vpd->sli3FwLabel, 16);
446 		}
447 	}
448 
449 	if ((sli_mode == EMLXS_HBA_SLI3_MODE) && (vpd->sli3FwRev == 0)) {
450 		if (vpd->sli2FwRev) {
451 			sli_mode = EMLXS_HBA_SLI2_MODE;
452 			sli_mode_mask = EMLXS_SLI2_MASK;
453 		} else {
454 			sli_mode = 0;
455 			sli_mode_mask = 0;
456 		}
457 	}
458 
459 	else if ((sli_mode == EMLXS_HBA_SLI2_MODE) && (vpd->sli2FwRev == 0)) {
460 		if (vpd->sli3FwRev) {
461 			sli_mode = EMLXS_HBA_SLI3_MODE;
462 			sli_mode_mask = EMLXS_SLI3_MASK;
463 		} else {
464 			sli_mode = 0;
465 			sli_mode_mask = 0;
466 		}
467 	}
468 
469 	if (!(hba->model_info.sli_mask & sli_mode_mask)) {
470 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
471 		    "Firmware not available. sli-mode=%d",
472 		    cfg[CFG_SLI_MODE].current);
473 
474 		rval = EIO;
475 		goto failed;
476 	}
477 
478 	/* Save information as VPD data */
479 	vpd->postKernRev = mb->un.varRdRev.postKernRev;
480 	vpd->opFwRev = mb->un.varRdRev.opFwRev;
481 	bcopy((char *)mb->un.varRdRev.opFwName, vpd->opFwLabel, 16);
482 	vpd->biuRev = mb->un.varRdRev.biuRev;
483 	vpd->smRev = mb->un.varRdRev.smRev;
484 	vpd->smFwRev = mb->un.varRdRev.un.smFwRev;
485 	vpd->endecRev = mb->un.varRdRev.endecRev;
486 	vpd->fcphHigh = mb->un.varRdRev.fcphHigh;
487 	vpd->fcphLow = mb->un.varRdRev.fcphLow;
488 	vpd->feaLevelHigh = mb->un.varRdRev.feaLevelHigh;
489 	vpd->feaLevelLow = mb->un.varRdRev.feaLevelLow;
490 
491 	/* Decode FW names */
492 	emlxs_decode_version(vpd->postKernRev, vpd->postKernName,
493 	    sizeof (vpd->postKernName));
494 	emlxs_decode_version(vpd->opFwRev, vpd->opFwName,
495 	    sizeof (vpd->opFwName));
496 	emlxs_decode_version(vpd->sli1FwRev, vpd->sli1FwName,
497 	    sizeof (vpd->sli1FwName));
498 	emlxs_decode_version(vpd->sli2FwRev, vpd->sli2FwName,
499 	    sizeof (vpd->sli2FwName));
500 	emlxs_decode_version(vpd->sli3FwRev, vpd->sli3FwName,
501 	    sizeof (vpd->sli3FwName));
502 	emlxs_decode_version(vpd->sli4FwRev, vpd->sli4FwName,
503 	    sizeof (vpd->sli4FwName));
504 
505 	/* Decode FW labels */
506 	emlxs_decode_label(vpd->opFwLabel, vpd->opFwLabel, 1,
507 	    sizeof (vpd->opFwLabel));
508 	emlxs_decode_label(vpd->sli1FwLabel, vpd->sli1FwLabel, 1,
509 	    sizeof (vpd->sli1FwLabel));
510 	emlxs_decode_label(vpd->sli2FwLabel, vpd->sli2FwLabel, 1,
511 	    sizeof (vpd->sli2FwLabel));
512 	emlxs_decode_label(vpd->sli3FwLabel, vpd->sli3FwLabel, 1,
513 	    sizeof (vpd->sli3FwLabel));
514 	emlxs_decode_label(vpd->sli4FwLabel, vpd->sli4FwLabel, 1,
515 	    sizeof (vpd->sli4FwLabel));
516 
517 	/* Reuse mbq from previous mbox */
518 	bzero(mbq, sizeof (MAILBOXQ));
519 
520 	key = emlxs_get_key(hba, mbq);
521 
522 	/* Get adapter VPD information */
523 	offset = 0;
524 	bzero(vpd_data, sizeof (vpd_data));
525 	vpd->port_index = (uint32_t)-1;
526 
527 	while (offset < DMP_VPD_SIZE) {
528 		/* Reuse mbq from previous mbox */
529 		bzero(mbq, sizeof (MAILBOXQ));
530 
531 		emlxs_mb_dump_vpd(hba, mbq, offset);
532 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
533 		    MBX_SUCCESS) {
534 			/*
535 			 * Let it go through even if failed.
536 			 * Not all adapter's have VPD info and thus will
537 			 * fail here. This is not a problem
538 			 */
539 
540 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
541 			    "No VPD found. offset=%x status=%x", offset,
542 			    mb->mbxStatus);
543 			break;
544 		} else {
545 			if (mb->un.varDmp.ra == 1) {
546 				uint32_t *lp1, *lp2;
547 				uint32_t bsize;
548 				uint32_t wsize;
549 
550 				/*
551 				 * mb->un.varDmp.word_cnt is actually byte
552 				 * count for the dump reply
553 				 */
554 				bsize = mb->un.varDmp.word_cnt;
555 
556 				/* Stop if no data was received */
557 				if (bsize == 0) {
558 					break;
559 				}
560 
561 				/* Check limit on byte size */
562 				bsize = (bsize >
563 				    (sizeof (vpd_data) - offset)) ?
564 				    (sizeof (vpd_data) - offset) : bsize;
565 
566 				/*
567 				 * Convert size from bytes to words with
568 				 * minimum of 1 word
569 				 */
570 				wsize = (bsize > 4) ? (bsize >> 2) : 1;
571 
572 				/*
573 				 * Transfer data into vpd_data buffer one
574 				 * word at a time
575 				 */
576 				lp1 = (uint32_t *)&mb->un.varDmp.resp_offset;
577 				lp2 = (uint32_t *)&vpd_data[offset];
578 
579 				for (i = 0; i < wsize; i++) {
580 					status = *lp1++;
581 					*lp2++ = BE_SWAP32(status);
582 				}
583 
584 				/* Increment total byte count saved */
585 				offset += (wsize << 2);
586 
587 				/*
588 				 * Stop if less than a full transfer was
589 				 * received
590 				 */
591 				if (wsize < DMP_VPD_DUMP_WCOUNT) {
592 					break;
593 				}
594 
595 			} else {
596 				EMLXS_MSGF(EMLXS_CONTEXT,
597 				    &emlxs_init_debug_msg,
598 				    "No VPD acknowledgment. offset=%x",
599 				    offset);
600 				break;
601 			}
602 		}
603 
604 	}
605 
606 	if (vpd_data[0]) {
607 		(void) emlxs_parse_vpd(hba, (uint8_t *)vpd_data, offset);
608 
609 		/*
610 		 * If there is a VPD part number, and it does not
611 		 * match the current default HBA model info,
612 		 * replace the default data with an entry that
613 		 * does match.
614 		 *
615 		 * After emlxs_parse_vpd model holds the VPD value
616 		 * for V2 and part_num hold the value for PN. These
617 		 * 2 values are NOT necessarily the same.
618 		 */
619 
620 		rval = 0;
621 		if ((vpd->model[0] != 0) &&
622 		    (strcmp(&vpd->model[0], hba->model_info.model) != 0)) {
623 
624 			/* First scan for a V2 match */
625 
626 			for (i = 1; i < emlxs_pci_model_count; i++) {
627 				if (strcmp(&vpd->model[0],
628 				    emlxs_pci_model[i].model) == 0) {
629 					bcopy(&emlxs_pci_model[i],
630 					    &hba->model_info,
631 					    sizeof (emlxs_model_t));
632 					rval = 1;
633 					break;
634 				}
635 			}
636 		}
637 
638 		if (!rval && (vpd->part_num[0] != 0) &&
639 		    (strcmp(&vpd->part_num[0], hba->model_info.model) != 0)) {
640 
641 			/* Next scan for a PN match */
642 
643 			for (i = 1; i < emlxs_pci_model_count; i++) {
644 				if (strcmp(&vpd->part_num[0],
645 				    emlxs_pci_model[i].model) == 0) {
646 					bcopy(&emlxs_pci_model[i],
647 					    &hba->model_info,
648 					    sizeof (emlxs_model_t));
649 					break;
650 				}
651 			}
652 		}
653 
654 		/*
655 		 * Now lets update hba->model_info with the real
656 		 * VPD data, if any.
657 		 */
658 
659 		/*
660 		 * Replace the default model description with vpd data
661 		 */
662 		if (vpd->model_desc[0] != 0) {
663 			(void) strncpy(hba->model_info.model_desc,
664 			    vpd->model_desc,
665 			    (sizeof (hba->model_info.model_desc)-1));
666 		}
667 
668 		/* Replace the default model with vpd data */
669 		if (vpd->model[0] != 0) {
670 			(void) strncpy(hba->model_info.model, vpd->model,
671 			    (sizeof (hba->model_info.model)-1));
672 		}
673 
674 		/* Replace the default program types with vpd data */
675 		if (vpd->prog_types[0] != 0) {
676 			emlxs_parse_prog_types(hba, vpd->prog_types);
677 		}
678 	}
679 
680 	/*
681 	 * Since the adapter model may have changed with the vpd data
682 	 * lets double check if adapter is not supported
683 	 */
684 	if (hba->model_info.flags & EMLXS_NOT_SUPPORTED) {
685 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
686 		    "Unsupported adapter found.  "
687 		    "Id:%d  Device id:0x%x  SSDID:0x%x  Model:%s",
688 		    hba->model_info.id, hba->model_info.device_id,
689 		    hba->model_info.ssdid, hba->model_info.model);
690 
691 		rval = EIO;
692 		goto failed;
693 	}
694 
695 	/* Read the adapter's wakeup parms */
696 	(void) emlxs_read_wakeup_parms(hba, &hba->wakeup_parms, 1);
697 	emlxs_decode_version(hba->wakeup_parms.u0.boot_bios_wd[0],
698 	    vpd->boot_version, sizeof (vpd->boot_version));
699 
700 	/* Get fcode version property */
701 	emlxs_get_fcode_version(hba);
702 
703 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
704 	    "Firmware: kern=%08x stub=%08x sli1=%08x", vpd->postKernRev,
705 	    vpd->opFwRev, vpd->sli1FwRev);
706 
707 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
708 	    "Firmware: sli2=%08x sli3=%08x sli4=%08x fl=%x", vpd->sli2FwRev,
709 	    vpd->sli3FwRev, vpd->sli4FwRev, vpd->feaLevelHigh);
710 
711 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
712 	    "BIOS: boot=%s fcode=%s", vpd->boot_version, vpd->fcode_version);
713 
714 	/*
715 	 * If firmware checking is enabled and the adapter model indicates
716 	 * a firmware image, then perform firmware version check
717 	 */
718 	hba->fw_flag = 0;
719 	hba->fw_timer = 0;
720 
721 	if (((fw_check & 0x1) &&
722 	    (hba->model_info.flags & EMLXS_ORACLE_BRANDED) &&
723 	    hba->model_info.fwid) || ((fw_check & 0x2) &&
724 	    hba->model_info.fwid)) {
725 		emlxs_firmware_t *fw;
726 
727 		/* Find firmware image indicated by adapter model */
728 		fw = NULL;
729 		for (i = 0; i < emlxs_fw_count; i++) {
730 			if (emlxs_fw_table[i].id == hba->model_info.fwid) {
731 				fw = &emlxs_fw_table[i];
732 				break;
733 			}
734 		}
735 
736 		/*
737 		 * If the image was found, then verify current firmware
738 		 * versions of adapter
739 		 */
740 		if (fw) {
741 			if (!kern_update &&
742 			    ((fw->kern && (vpd->postKernRev != fw->kern)) ||
743 			    (fw->stub && (vpd->opFwRev != fw->stub)))) {
744 
745 				hba->fw_flag |= FW_UPDATE_NEEDED;
746 
747 			} else if ((fw->kern && (vpd->postKernRev !=
748 			    fw->kern)) ||
749 			    (fw->stub && (vpd->opFwRev != fw->stub)) ||
750 			    (fw->sli1 && (vpd->sli1FwRev != fw->sli1)) ||
751 			    (fw->sli2 && (vpd->sli2FwRev != fw->sli2)) ||
752 			    (fw->sli3 && (vpd->sli3FwRev != fw->sli3)) ||
753 			    (fw->sli4 && (vpd->sli4FwRev != fw->sli4))) {
754 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
755 				    "Firmware update needed. "
756 				    "Updating. id=%d fw=%d",
757 				    hba->model_info.id, hba->model_info.fwid);
758 
759 #ifdef MODFW_SUPPORT
760 				/*
761 				 * Load the firmware image now
762 				 * If MODFW_SUPPORT is not defined, the
763 				 * firmware image will already be defined
764 				 * in the emlxs_fw_table
765 				 */
766 				emlxs_fw_load(hba, fw);
767 #endif /* MODFW_SUPPORT */
768 
769 				if (fw->image && fw->size) {
770 					uint32_t rc;
771 
772 					rc = emlxs_fw_download(hba,
773 					    (char *)fw->image, fw->size, 0);
774 					if ((rc != FC_SUCCESS) &&
775 					    (rc != EMLXS_REBOOT_REQUIRED)) {
776 						EMLXS_MSGF(EMLXS_CONTEXT,
777 						    &emlxs_init_msg,
778 						    "Firmware update failed.");
779 						hba->fw_flag |=
780 						    FW_UPDATE_NEEDED;
781 					}
782 #ifdef MODFW_SUPPORT
783 					/*
784 					 * Unload the firmware image from
785 					 * kernel memory
786 					 */
787 					emlxs_fw_unload(hba, fw);
788 #endif /* MODFW_SUPPORT */
789 
790 					fw_check = 0;
791 
792 					goto reset;
793 				}
794 
795 				hba->fw_flag |= FW_UPDATE_NEEDED;
796 
797 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
798 				    "Firmware image unavailable.");
799 			} else {
800 				EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
801 				    "Firmware update not needed.");
802 			}
803 		} else {
804 			/* This should not happen */
805 
806 			/*
807 			 * This means either the adapter database is not
808 			 * correct or a firmware image is missing from the
809 			 * compile
810 			 */
811 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
812 			    "Firmware image unavailable. id=%d fw=%d",
813 			    hba->model_info.id, hba->model_info.fwid);
814 		}
815 	}
816 
817 	/*
818 	 * Add our interrupt routine to kernel's interrupt chain & enable it
819 	 * If MSI is enabled this will cause Solaris to program the MSI address
820 	 * and data registers in PCI config space
821 	 */
822 	if (EMLXS_INTR_ADD(hba) != DDI_SUCCESS) {
823 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
824 		    "Unable to add interrupt(s).");
825 
826 		rval = EIO;
827 		goto failed;
828 	}
829 
830 	EMLXS_STATE_CHANGE(hba, FC_INIT_CFGPORT);
831 
832 	/* Reuse mbq from previous mbox */
833 	bzero(mbq, sizeof (MAILBOXQ));
834 
835 	(void) emlxs_mb_config_port(hba, mbq, sli_mode, key);
836 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
837 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
838 		    "Unable to configure port. "
839 		    "Mailbox cmd=%x status=%x slimode=%d key=%x",
840 		    mb->mbxCommand, mb->mbxStatus, sli_mode, key);
841 
842 		for (sli_mode--; sli_mode > 0; sli_mode--) {
843 			/* Check if sli_mode is supported by this adapter */
844 			if (hba->model_info.sli_mask &
845 			    EMLXS_SLI_MASK(sli_mode)) {
846 				sli_mode_mask = EMLXS_SLI_MASK(sli_mode);
847 				break;
848 			}
849 		}
850 
851 		if (sli_mode) {
852 			fw_check = 0;
853 
854 			goto reset;
855 		}
856 
857 		hba->flag &= ~FC_SLIM2_MODE;
858 
859 		rval = EIO;
860 		goto failed;
861 	}
862 
863 	/* Check if SLI3 mode was achieved */
864 	if (mb->un.varCfgPort.rMA &&
865 	    (mb->un.varCfgPort.sli_mode == EMLXS_HBA_SLI3_MODE)) {
866 
867 		if (mb->un.varCfgPort.vpi_max > 1) {
868 			hba->flag |= FC_NPIV_ENABLED;
869 
870 			if (hba->model_info.chip >= EMLXS_SATURN_CHIP) {
871 				hba->vpi_max =
872 				    min(mb->un.varCfgPort.vpi_max,
873 				    MAX_VPORTS - 1);
874 			} else {
875 				hba->vpi_max =
876 				    min(mb->un.varCfgPort.vpi_max,
877 				    MAX_VPORTS_LIMITED - 1);
878 			}
879 		}
880 
881 #if (EMLXS_MODREV >= EMLXS_MODREV5)
882 		hba->fca_tran->fca_num_npivports =
883 		    (cfg[CFG_NPIV_ENABLE].current) ? hba->vpi_max : 0;
884 #endif /* >= EMLXS_MODREV5 */
885 
886 		if (mb->un.varCfgPort.gerbm && mb->un.varCfgPort.max_hbq) {
887 			hba->flag |= FC_HBQ_ENABLED;
888 		}
889 
890 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
891 		    "SLI3 mode: flag=%x vpi_max=%d", hba->flag, hba->vpi_max);
892 	} else {
893 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
894 		    "SLI2 mode: flag=%x", hba->flag);
895 		sli_mode = EMLXS_HBA_SLI2_MODE;
896 		sli_mode_mask = EMLXS_SLI2_MASK;
897 		hba->sli_mode = sli_mode;
898 #if (EMLXS_MODREV >= EMLXS_MODREV5)
899 		hba->fca_tran->fca_num_npivports = 0;
900 #endif /* >= EMLXS_MODREV5 */
901 
902 	}
903 
904 	/* Get and save the current firmware version (based on sli_mode) */
905 	emlxs_decode_firmware_rev(hba, vpd);
906 
907 	emlxs_pcix_mxr_update(hba, 0);
908 
909 	/* Reuse mbq from previous mbox */
910 	bzero(mbq, sizeof (MAILBOXQ));
911 
912 	emlxs_mb_read_config(hba, mbq);
913 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
914 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
915 		    "Unable to read configuration.  Mailbox cmd=%x status=%x",
916 		    mb->mbxCommand, mb->mbxStatus);
917 
918 		rval = EIO;
919 		goto failed;
920 	}
921 
922 	/* Save the link speed capabilities */
923 	vpd->link_speed = (uint16_t)mb->un.varRdConfig.lmt;
924 	emlxs_process_link_speed(hba);
925 
926 	/* Set the max node count */
927 	if (cfg[CFG_NUM_NODES].current > 0) {
928 		hba->max_nodes =
929 		    min(cfg[CFG_NUM_NODES].current,
930 		    mb->un.varRdConfig.max_rpi);
931 	} else {
932 		hba->max_nodes = mb->un.varRdConfig.max_rpi;
933 	}
934 
935 	/* Set the io throttle */
936 	hba->io_throttle = mb->un.varRdConfig.max_xri - IO_THROTTLE_RESERVE;
937 
938 	/* Set max_iotag */
939 	if (cfg[CFG_NUM_IOTAGS].current) {
940 		hba->max_iotag = (uint16_t)cfg[CFG_NUM_IOTAGS].current;
941 	} else {
942 		hba->max_iotag = mb->un.varRdConfig.max_xri;
943 	}
944 
945 	/* Set out-of-range iotag base */
946 	hba->fc_oor_iotag = hba->max_iotag;
947 
948 	/*
949 	 * Allocate some memory for buffers
950 	 */
951 	if (emlxs_mem_alloc_buffer(hba) == 0) {
952 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
953 		    "Unable to allocate memory buffers.");
954 
955 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
956 		return (ENOMEM);
957 	}
958 
959 	/*
960 	 * Setup and issue mailbox RUN BIU DIAG command Setup test buffers
961 	 */
962 	if (((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) ||
963 	    ((mp1 = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0)) {
964 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
965 		    "Unable to allocate diag buffers.");
966 
967 		rval = ENOMEM;
968 		goto failed;
969 	}
970 
971 	bcopy((caddr_t)&emlxs_diag_pattern[0], (caddr_t)mp->virt,
972 	    MEM_ELSBUF_SIZE);
973 	EMLXS_MPDATA_SYNC(mp->dma_handle, 0, MEM_ELSBUF_SIZE,
974 	    DDI_DMA_SYNC_FORDEV);
975 
976 	bzero(mp1->virt, MEM_ELSBUF_SIZE);
977 	EMLXS_MPDATA_SYNC(mp1->dma_handle, 0, MEM_ELSBUF_SIZE,
978 	    DDI_DMA_SYNC_FORDEV);
979 
980 	/* Reuse mbq from previous mbox */
981 	bzero(mbq, sizeof (MAILBOXQ));
982 
983 	(void) emlxs_mb_run_biu_diag(hba, mbq, mp->phys, mp1->phys);
984 
985 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
986 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
987 		    "Unable to run BIU diag.  Mailbox cmd=%x status=%x",
988 		    mb->mbxCommand, mb->mbxStatus);
989 
990 		rval = EIO;
991 		goto failed;
992 	}
993 
994 	EMLXS_MPDATA_SYNC(mp1->dma_handle, 0, MEM_ELSBUF_SIZE,
995 	    DDI_DMA_SYNC_FORKERNEL);
996 
997 #ifdef FMA_SUPPORT
998 	if (mp->dma_handle) {
999 		if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
1000 		    != DDI_FM_OK) {
1001 			EMLXS_MSGF(EMLXS_CONTEXT,
1002 			    &emlxs_invalid_dma_handle_msg,
1003 			    "sli3_online: hdl=%p",
1004 			    mp->dma_handle);
1005 			rval = EIO;
1006 			goto failed;
1007 		}
1008 	}
1009 
1010 	if (mp1->dma_handle) {
1011 		if (emlxs_fm_check_dma_handle(hba, mp1->dma_handle)
1012 		    != DDI_FM_OK) {
1013 			EMLXS_MSGF(EMLXS_CONTEXT,
1014 			    &emlxs_invalid_dma_handle_msg,
1015 			    "sli3_online: hdl=%p",
1016 			    mp1->dma_handle);
1017 			rval = EIO;
1018 			goto failed;
1019 		}
1020 	}
1021 #endif  /* FMA_SUPPORT */
1022 
1023 	outptr = mp->virt;
1024 	inptr = mp1->virt;
1025 
1026 	for (i = 0; i < MEM_ELSBUF_SIZE; i++) {
1027 		if (*outptr++ != *inptr++) {
1028 			outptr--;
1029 			inptr--;
1030 
1031 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1032 			    "BIU diagnostic failed. "
1033 			    "offset %x value %x should be %x.",
1034 			    i, (uint32_t)*inptr, (uint32_t)*outptr);
1035 
1036 			rval = EIO;
1037 			goto failed;
1038 		}
1039 	}
1040 
1041 	/* Free the buffers since we were polling */
1042 	emlxs_mem_put(hba, MEM_BUF, (void *)mp);
1043 	mp = NULL;
1044 	emlxs_mem_put(hba, MEM_BUF, (void *)mp1);
1045 	mp1 = NULL;
1046 
1047 	hba->channel_fcp = FC_FCP_RING;
1048 	hba->channel_els = FC_ELS_RING;
1049 	hba->channel_ip = FC_IP_RING;
1050 	hba->channel_ct = FC_CT_RING;
1051 	hba->sli.sli3.ring_count = MAX_RINGS;
1052 
1053 	hba->channel_tx_count = 0;
1054 	hba->io_count = 0;
1055 	hba->fc_iotag = 1;
1056 
1057 	for (i = 0; i < hba->chan_count; i++) {
1058 		cp = &hba->chan[i];
1059 
1060 		/* 1 to 1 mapping between ring and channel */
1061 		cp->iopath = (void *)&hba->sli.sli3.ring[i];
1062 
1063 		cp->hba = hba;
1064 		cp->channelno = i;
1065 	}
1066 
1067 	/*
1068 	 * Setup and issue mailbox CONFIGURE RING command
1069 	 */
1070 	for (i = 0; i < (uint32_t)hba->sli.sli3.ring_count; i++) {
1071 		/*
1072 		 * Initialize cmd/rsp ring pointers
1073 		 */
1074 		rp = &hba->sli.sli3.ring[i];
1075 
1076 		/* 1 to 1 mapping between ring and channel */
1077 		rp->channelp = &hba->chan[i];
1078 
1079 		rp->hba = hba;
1080 		rp->ringno = (uint8_t)i;
1081 
1082 		rp->fc_cmdidx = 0;
1083 		rp->fc_rspidx = 0;
1084 		EMLXS_STATE_CHANGE(hba, FC_INIT_CFGRING);
1085 
1086 		/* Reuse mbq from previous mbox */
1087 		bzero(mbq, sizeof (MAILBOXQ));
1088 
1089 		emlxs_mb_config_ring(hba, i, mbq);
1090 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
1091 		    MBX_SUCCESS) {
1092 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1093 			    "Unable to configure ring. "
1094 			    "Mailbox cmd=%x status=%x",
1095 			    mb->mbxCommand, mb->mbxStatus);
1096 
1097 			rval = EIO;
1098 			goto failed;
1099 		}
1100 	}
1101 
1102 	/*
1103 	 * Setup link timers
1104 	 */
1105 	EMLXS_STATE_CHANGE(hba, FC_INIT_INITLINK);
1106 
1107 	/* Reuse mbq from previous mbox */
1108 	bzero(mbq, sizeof (MAILBOXQ));
1109 
1110 	emlxs_mb_config_link(hba, mbq);
1111 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
1112 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1113 		    "Unable to configure link. Mailbox cmd=%x status=%x",
1114 		    mb->mbxCommand, mb->mbxStatus);
1115 
1116 		rval = EIO;
1117 		goto failed;
1118 	}
1119 
1120 #ifdef MAX_RRDY_SUPPORT
1121 	/* Set MAX_RRDY if one is provided */
1122 	if (cfg[CFG_MAX_RRDY].current) {
1123 
1124 		/* Reuse mbq from previous mbox */
1125 		bzero(mbq, sizeof (MAILBOXQ));
1126 
1127 		emlxs_mb_set_var(hba, (MAILBOX *)mbq, 0x00060412,
1128 		    cfg[CFG_MAX_RRDY].current);
1129 
1130 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
1131 		    MBX_SUCCESS) {
1132 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1133 			    "MAX_RRDY: Unable to set.  status=%x " \
1134 			    "value=%d",
1135 			    mb->mbxStatus, cfg[CFG_MAX_RRDY].current);
1136 		} else {
1137 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1138 			    "MAX_RRDY: %d", cfg[CFG_MAX_RRDY].current);
1139 		}
1140 	}
1141 #endif /* MAX_RRDY_SUPPORT */
1142 
1143 	/* Reuse mbq from previous mbox */
1144 	bzero(mbq, sizeof (MAILBOXQ));
1145 
1146 	/*
1147 	 * We need to get login parameters for NID
1148 	 */
1149 	(void) emlxs_mb_read_sparam(hba, mbq);
1150 	mp = (MATCHMAP *)mbq->bp;
1151 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
1152 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1153 		    "Unable to read parameters. Mailbox cmd=%x status=%x",
1154 		    mb->mbxCommand, mb->mbxStatus);
1155 
1156 		rval = EIO;
1157 		goto failed;
1158 	}
1159 
1160 	/* Free the buffer since we were polling */
1161 	emlxs_mem_put(hba, MEM_BUF, (void *)mp);
1162 	mp = NULL;
1163 
1164 	/* If no serial number in VPD data, then use the WWPN */
1165 	if (vpd->serial_num[0] == 0) {
1166 		outptr = (uint8_t *)&hba->wwpn.IEEE[0];
1167 		for (i = 0; i < 12; i++) {
1168 			status = *outptr++;
1169 			j = ((status & 0xf0) >> 4);
1170 			if (j <= 9) {
1171 				vpd->serial_num[i] =
1172 				    (char)((uint8_t)'0' + (uint8_t)j);
1173 			} else {
1174 				vpd->serial_num[i] =
1175 				    (char)((uint8_t)'A' + (uint8_t)(j - 10));
1176 			}
1177 
1178 			i++;
1179 			j = (status & 0xf);
1180 			if (j <= 9) {
1181 				vpd->serial_num[i] =
1182 				    (char)((uint8_t)'0' + (uint8_t)j);
1183 			} else {
1184 				vpd->serial_num[i] =
1185 				    (char)((uint8_t)'A' + (uint8_t)(j - 10));
1186 			}
1187 		}
1188 
1189 		/*
1190 		 * Set port number and port index to zero
1191 		 * The WWN's are unique to each port and therefore port_num
1192 		 * must equal zero. This effects the hba_fru_details structure
1193 		 * in fca_bind_port()
1194 		 */
1195 		vpd->port_num[0] = 0;
1196 		vpd->port_index = 0;
1197 	}
1198 
1199 	/*
1200 	 * Make first attempt to set a port index
1201 	 * Check if this is a multifunction adapter
1202 	 */
1203 	if ((vpd->port_index == (uint32_t)-1) &&
1204 	    (hba->model_info.chip >= EMLXS_THOR_CHIP)) {
1205 		char *buffer;
1206 		int32_t i;
1207 
1208 		/*
1209 		 * The port address looks like this:
1210 		 * 1	- for port index 0
1211 		 * 1,1	- for port index 1
1212 		 * 1,2	- for port index 2
1213 		 */
1214 		buffer = ddi_get_name_addr(hba->dip);
1215 
1216 		if (buffer) {
1217 			vpd->port_index = 0;
1218 
1219 			/* Reverse scan for a comma */
1220 			for (i = strlen(buffer) - 1; i > 0; i--) {
1221 				if (buffer[i] == ',') {
1222 					/* Comma found - set index now */
1223 					vpd->port_index =
1224 					    emlxs_strtol(&buffer[i + 1], 10);
1225 					break;
1226 				}
1227 			}
1228 		}
1229 	}
1230 
1231 	/* Make final attempt to set a port index */
1232 	if (vpd->port_index == (uint32_t)-1) {
1233 		dev_info_t *p_dip;
1234 		dev_info_t *c_dip;
1235 
1236 		p_dip = ddi_get_parent(hba->dip);
1237 		c_dip = ddi_get_child(p_dip);
1238 
1239 		vpd->port_index = 0;
1240 		while (c_dip && (hba->dip != c_dip)) {
1241 			c_dip = ddi_get_next_sibling(c_dip);
1242 			vpd->port_index++;
1243 		}
1244 	}
1245 
1246 	if (vpd->port_num[0] == 0) {
1247 		if (hba->model_info.channels == EMLXS_MULTI_CHANNEL) {
1248 			(void) snprintf(vpd->port_num,
1249 			    (sizeof (vpd->port_num)-1),
1250 			    "%d", vpd->port_index);
1251 		}
1252 	}
1253 
1254 	if (vpd->id[0] == 0) {
1255 		(void) strncpy(vpd->id, hba->model_info.model_desc,
1256 		    (sizeof (vpd->id)-1));
1257 	}
1258 
1259 	if (vpd->manufacturer[0] == 0) {
1260 		(void) strncpy(vpd->manufacturer, hba->model_info.manufacturer,
1261 		    (sizeof (vpd->manufacturer)-1));
1262 	}
1263 
1264 	if (vpd->part_num[0] == 0) {
1265 		(void) strncpy(vpd->part_num, hba->model_info.model,
1266 		    (sizeof (vpd->part_num)-1));
1267 	}
1268 
1269 	if (vpd->model_desc[0] == 0) {
1270 		(void) strncpy(vpd->model_desc, hba->model_info.model_desc,
1271 		    (sizeof (vpd->model_desc)-1));
1272 	}
1273 
1274 	if (vpd->model[0] == 0) {
1275 		(void) strncpy(vpd->model, hba->model_info.model,
1276 		    (sizeof (vpd->model)-1));
1277 	}
1278 
1279 	if (vpd->prog_types[0] == 0) {
1280 		emlxs_build_prog_types(hba, vpd);
1281 	}
1282 
1283 	/* Create the symbolic names */
1284 	(void) snprintf(hba->snn, (sizeof (hba->snn)-1),
1285 	    "Emulex %s FV%s DV%s %s",
1286 	    hba->model_info.model, hba->vpd.fw_version, emlxs_version,
1287 	    (char *)utsname.nodename);
1288 
1289 	(void) snprintf(hba->spn, (sizeof (hba->spn)-1),
1290 	    "Emulex PPN-%01x%01x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
1291 	    hba->wwpn.nameType, hba->wwpn.IEEEextMsn, hba->wwpn.IEEEextLsb,
1292 	    hba->wwpn.IEEE[0], hba->wwpn.IEEE[1], hba->wwpn.IEEE[2],
1293 	    hba->wwpn.IEEE[3], hba->wwpn.IEEE[4], hba->wwpn.IEEE[5]);
1294 
1295 	if (cfg[CFG_NETWORK_ON].current) {
1296 		if ((hba->sparam.portName.nameType != NAME_IEEE) ||
1297 		    (hba->sparam.portName.IEEEextMsn != 0) ||
1298 		    (hba->sparam.portName.IEEEextLsb != 0)) {
1299 
1300 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
1301 			    "WWPN doesn't conform to IP profile: "
1302 			    "nameType=%x. Disabling networking.",
1303 			    hba->sparam.portName.nameType);
1304 
1305 			cfg[CFG_NETWORK_ON].current = 0;
1306 		}
1307 	}
1308 
1309 	if (cfg[CFG_NETWORK_ON].current) {
1310 		/* Reuse mbq from previous mbox */
1311 		bzero(mbq, sizeof (MAILBOXQ));
1312 
1313 		/* Issue CONFIG FARP */
1314 		emlxs_mb_config_farp(hba, mbq);
1315 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
1316 		    MBX_SUCCESS) {
1317 			/*
1318 			 * Let it go through even if failed.
1319 			 */
1320 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_msg,
1321 			    "Unable to configure FARP. "
1322 			    "Mailbox cmd=%x status=%x",
1323 			    mb->mbxCommand, mb->mbxStatus);
1324 		}
1325 	}
1326 #ifdef MSI_SUPPORT
1327 	/* Configure MSI map if required */
1328 	if (hba->intr_count > 1) {
1329 
1330 		if (hba->intr_type == DDI_INTR_TYPE_MSIX) {
1331 			/* always start from 0 */
1332 			hba->last_msiid = 0;
1333 		}
1334 
1335 		/* Reuse mbq from previous mbox */
1336 		bzero(mbq, sizeof (MAILBOXQ));
1337 
1338 		emlxs_mb_config_msix(hba, mbq, hba->intr_map, hba->intr_count);
1339 
1340 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) ==
1341 		    MBX_SUCCESS) {
1342 			goto msi_configured;
1343 		}
1344 
1345 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1346 		    "Unable to config MSIX.  Mailbox cmd=0x%x status=0x%x",
1347 		    mb->mbxCommand, mb->mbxStatus);
1348 
1349 		/* Reuse mbq from previous mbox */
1350 		bzero(mbq, sizeof (MAILBOXQ));
1351 
1352 		emlxs_mb_config_msi(hba, mbq, hba->intr_map, hba->intr_count);
1353 
1354 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) ==
1355 		    MBX_SUCCESS) {
1356 			goto msi_configured;
1357 		}
1358 
1359 
1360 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1361 		    "Unable to config MSI.  Mailbox cmd=0x%x status=0x%x",
1362 		    mb->mbxCommand, mb->mbxStatus);
1363 
1364 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1365 		    "Attempting single interrupt mode...");
1366 
1367 		/* First cleanup old interrupts */
1368 		(void) emlxs_msi_remove(hba);
1369 		(void) emlxs_msi_uninit(hba);
1370 
1371 		status = emlxs_msi_init(hba, 1);
1372 
1373 		if (status != DDI_SUCCESS) {
1374 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1375 			    "Unable to initialize interrupt. status=%d",
1376 			    status);
1377 
1378 			rval = EIO;
1379 			goto failed;
1380 		}
1381 
1382 		/*
1383 		 * Reset adapter - The adapter needs to be reset because
1384 		 * the bus cannot handle the MSI change without handshaking
1385 		 * with the adapter again
1386 		 */
1387 
1388 		(void) emlxs_mem_free_buffer(hba);
1389 		fw_check = 0;
1390 		goto reset;
1391 	}
1392 
1393 msi_configured:
1394 
1395 
1396 	if ((hba->intr_count >= 1) &&
1397 	    (hba->sli_mode == EMLXS_HBA_SLI3_MODE)) {
1398 		/* intr_count is a sequence of msi id */
1399 		/* Setup msi2chan[msi_id] */
1400 		for (i = 0; i < hba->intr_count; i ++) {
1401 			hba->msi2chan[i] = i;
1402 			if (i >= hba->chan_count)
1403 				hba->msi2chan[i] = (i - hba->chan_count);
1404 		}
1405 	}
1406 #endif /* MSI_SUPPORT */
1407 
1408 	/*
1409 	 * We always disable the firmware traffic cop feature
1410 	 */
1411 	if (emlxs_disable_traffic_cop) {
1412 		/* Reuse mbq from previous mbox */
1413 		bzero(mbq, sizeof (MAILBOXQ));
1414 
1415 		emlxs_disable_tc(hba, mbq);
1416 		if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) !=
1417 		    MBX_SUCCESS) {
1418 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1419 			    "Unable to disable traffic cop. "
1420 			    "Mailbox cmd=%x status=%x",
1421 			    mb->mbxCommand, mb->mbxStatus);
1422 
1423 			rval = EIO;
1424 			goto failed;
1425 		}
1426 	}
1427 
1428 
1429 	/* Reuse mbq from previous mbox */
1430 	bzero(mbq, sizeof (MAILBOXQ));
1431 
1432 	/* Register for async events */
1433 	emlxs_mb_async_event(hba, mbq);
1434 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
1435 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1436 		    "Async events disabled. Mailbox status=%x",
1437 		    mb->mbxStatus);
1438 	} else {
1439 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1440 		    "Async events enabled.");
1441 		hba->flag |= FC_ASYNC_EVENTS;
1442 	}
1443 
1444 	EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN);
1445 
1446 	emlxs_sli3_enable_intr(hba);
1447 
1448 	if (hba->flag & FC_HBQ_ENABLED) {
1449 		if (port->flag & EMLXS_TGT_ENABLED) {
1450 			if (emlxs_hbq_setup(hba, EMLXS_FCT_HBQ_ID)) {
1451 				EMLXS_MSGF(EMLXS_CONTEXT,
1452 				    &emlxs_init_failed_msg,
1453 				    "Unable to setup FCT HBQ.");
1454 
1455 				rval = ENOMEM;
1456 
1457 #ifdef SFCT_SUPPORT
1458 				/* Check if we can fall back to just */
1459 				/* initiator mode */
1460 				if ((hba->pm_state == EMLXS_PM_IN_ATTACH) &&
1461 				    (port->flag & EMLXS_INI_ENABLED) &&
1462 				    (cfg[CFG_DTM_ENABLE].current == 1) &&
1463 				    (cfg[CFG_TARGET_MODE].current == 0)) {
1464 
1465 					cfg[CFG_DTM_ENABLE].current = 0;
1466 
1467 					EMLXS_MSGF(EMLXS_CONTEXT,
1468 					    &emlxs_init_failed_msg,
1469 					    "Disabling dynamic target mode. "
1470 					    "Enabling initiator mode only.");
1471 
1472 					/* This will trigger the driver to */
1473 					/* reattach */
1474 					rval = EAGAIN;
1475 				}
1476 #endif /* SFCT_SUPPORT */
1477 				goto failed;
1478 			}
1479 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1480 			    "FCT Ring: Posted %d buffers.", MEM_FCTBUF_COUNT);
1481 		}
1482 
1483 		if (cfg[CFG_NETWORK_ON].current) {
1484 			if (emlxs_hbq_setup(hba, EMLXS_IP_HBQ_ID)) {
1485 				EMLXS_MSGF(EMLXS_CONTEXT,
1486 				    &emlxs_init_failed_msg,
1487 				    "Unable to setup IP HBQ.");
1488 
1489 				rval = ENOMEM;
1490 				goto failed;
1491 			}
1492 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1493 			    "IP  Ring: Posted %d buffers.", MEM_IPBUF_COUNT);
1494 		}
1495 
1496 		if (emlxs_hbq_setup(hba, EMLXS_ELS_HBQ_ID)) {
1497 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1498 			    "Unable to setup ELS HBQ.");
1499 			rval = ENOMEM;
1500 			goto failed;
1501 		}
1502 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1503 		    "ELS Ring: Posted %d buffers.", MEM_ELSBUF_COUNT);
1504 
1505 		if (emlxs_hbq_setup(hba, EMLXS_CT_HBQ_ID)) {
1506 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1507 			    "Unable to setup CT HBQ.");
1508 
1509 			rval = ENOMEM;
1510 			goto failed;
1511 		}
1512 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1513 		    "CT  Ring: Posted %d buffers.", MEM_CTBUF_COUNT);
1514 	} else {
1515 		if (port->flag & EMLXS_TGT_ENABLED) {
1516 			/* Post the FCT unsol buffers */
1517 			rp = &hba->sli.sli3.ring[FC_FCT_RING];
1518 			for (j = 0; j < MEM_FCTBUF_COUNT; j += 2) {
1519 				(void) emlxs_post_buffer(hba, rp, 2);
1520 			}
1521 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1522 			    "FCP Ring: Posted %d buffers.", MEM_FCTBUF_COUNT);
1523 		}
1524 
1525 		if (cfg[CFG_NETWORK_ON].current) {
1526 			/* Post the IP unsol buffers */
1527 			rp = &hba->sli.sli3.ring[FC_IP_RING];
1528 			for (j = 0; j < MEM_IPBUF_COUNT; j += 2) {
1529 				(void) emlxs_post_buffer(hba, rp, 2);
1530 			}
1531 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1532 			    "IP  Ring: Posted %d buffers.", MEM_IPBUF_COUNT);
1533 		}
1534 
1535 		/* Post the ELS unsol buffers */
1536 		rp = &hba->sli.sli3.ring[FC_ELS_RING];
1537 		for (j = 0; j < MEM_ELSBUF_COUNT; j += 2) {
1538 			(void) emlxs_post_buffer(hba, rp, 2);
1539 		}
1540 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1541 		    "ELS Ring: Posted %d buffers.", MEM_ELSBUF_COUNT);
1542 
1543 
1544 		/* Post the CT unsol buffers */
1545 		rp = &hba->sli.sli3.ring[FC_CT_RING];
1546 		for (j = 0; j < MEM_CTBUF_COUNT; j += 2) {
1547 			(void) emlxs_post_buffer(hba, rp, 2);
1548 		}
1549 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
1550 		    "CT  Ring: Posted %d buffers.", MEM_CTBUF_COUNT);
1551 	}
1552 
1553 	(void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ));
1554 
1555 	/* Check persist-linkdown */
1556 	if (cfg[CFG_PERSIST_LINKDOWN].current) {
1557 		EMLXS_STATE_CHANGE(hba, FC_LINK_DOWN_PERSIST);
1558 		return (0);
1559 	}
1560 
1561 #ifdef SFCT_SUPPORT
1562 	if ((port->mode == MODE_TARGET) &&
1563 	    !(port->fct_flags & FCT_STATE_PORT_ONLINE)) {
1564 		emlxs_enable_latt(hba);
1565 		return (0);
1566 	}
1567 #endif /* SFCT_SUPPORT */
1568 
1569 	/*
1570 	 * Setup and issue mailbox INITIALIZE LINK command
1571 	 * At this point, the interrupt will be generated by the HW
1572 	 */
1573 	mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX);
1574 	if (mbq == NULL) {
1575 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1576 		    "Unable to allocate mailbox buffer.");
1577 
1578 		rval = EIO;
1579 		goto failed;
1580 	}
1581 	mb = (MAILBOX *)mbq;
1582 
1583 	emlxs_mb_init_link(hba, mbq, cfg[CFG_TOPOLOGY].current,
1584 	    cfg[CFG_LINK_SPEED].current);
1585 
1586 	rval = emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0);
1587 	if ((rval != MBX_SUCCESS) && (rval != MBX_BUSY)) {
1588 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_failed_msg,
1589 		    "Unable to initialize link. " \
1590 		    "Mailbox cmd=%x status=%x",
1591 		    mb->mbxCommand, mb->mbxStatus);
1592 
1593 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
1594 		mbq = NULL;
1595 		rval = EIO;
1596 		goto failed;
1597 	}
1598 
1599 	/*
1600 	 * Enable link attention interrupt
1601 	 */
1602 	emlxs_enable_latt(hba);
1603 
1604 	/* Wait for link to come up */
1605 	i = cfg[CFG_LINKUP_DELAY].current;
1606 	while (i && (hba->state < FC_LINK_UP)) {
1607 		/* Check for hardware error */
1608 		if (hba->state == FC_ERROR) {
1609 			EMLXS_MSGF(EMLXS_CONTEXT,
1610 			    &emlxs_init_failed_msg,
1611 			    "Adapter error.");
1612 
1613 			mbq = NULL;
1614 			rval = EIO;
1615 			goto failed;
1616 		}
1617 
1618 		BUSYWAIT_MS(1000);
1619 		i--;
1620 	}
1621 
1622 	/*
1623 	 * The leadvile driver will now handle the FLOGI at the driver level
1624 	 */
1625 
1626 	return (0);
1627 
1628 failed:
1629 
1630 	EMLXS_STATE_CHANGE(hba, FC_ERROR);
1631 
1632 	if (hba->intr_flags & EMLXS_MSI_ADDED) {
1633 		(void) EMLXS_INTR_REMOVE(hba);
1634 	}
1635 
1636 	if (mp) {
1637 		emlxs_mem_put(hba, MEM_BUF, (void *)mp);
1638 		mp = NULL;
1639 	}
1640 
1641 	if (mp1) {
1642 		emlxs_mem_put(hba, MEM_BUF, (void *)mp1);
1643 		mp1 = NULL;
1644 	}
1645 
1646 	(void) emlxs_mem_free_buffer(hba);
1647 
1648 	if (mbq) {
1649 		(void) kmem_free((uint8_t *)mbq, sizeof (MAILBOXQ));
1650 		mbq = NULL;
1651 		mb = NULL;
1652 	}
1653 
1654 	if (rval == 0) {
1655 		rval = EIO;
1656 	}
1657 
1658 	return (rval);
1659 
1660 } /* emlxs_sli3_online() */
1661 
1662 
1663 /*ARGSUSED*/
1664 static void
1665 emlxs_sli3_offline(emlxs_hba_t *hba, uint32_t reset_requested)
1666 {
1667 	/* Reverse emlxs_sli3_online */
1668 
1669 	/* Kill the adapter */
1670 	emlxs_sli3_hba_kill(hba);
1671 
1672 	/* Free driver shared memory */
1673 	(void) emlxs_mem_free_buffer(hba);
1674 
1675 } /* emlxs_sli3_offline() */
1676 
1677 
1678 static int
1679 emlxs_sli3_map_hdw(emlxs_hba_t *hba)
1680 {
1681 	emlxs_port_t		*port = &PPORT;
1682 	dev_info_t		*dip;
1683 	ddi_device_acc_attr_t	dev_attr;
1684 	int			status;
1685 
1686 	dip = (dev_info_t *)hba->dip;
1687 	dev_attr = emlxs_dev_acc_attr;
1688 
1689 	if (hba->bus_type == SBUS_FC) {
1690 
1691 		if (hba->sli.sli3.slim_acc_handle == 0) {
1692 			status = ddi_regs_map_setup(dip,
1693 			    SBUS_DFLY_SLIM_RINDEX,
1694 			    (caddr_t *)&hba->sli.sli3.slim_addr,
1695 			    0, 0, &dev_attr, &hba->sli.sli3.slim_acc_handle);
1696 			if (status != DDI_SUCCESS) {
1697 				EMLXS_MSGF(EMLXS_CONTEXT,
1698 				    &emlxs_attach_failed_msg,
1699 				    "(SBUS) ddi_regs_map_setup SLIM failed. "
1700 				    "status=%x", status);
1701 				goto failed;
1702 			}
1703 		}
1704 		if (hba->sli.sli3.csr_acc_handle == 0) {
1705 			status = ddi_regs_map_setup(dip,
1706 			    SBUS_DFLY_CSR_RINDEX,
1707 			    (caddr_t *)&hba->sli.sli3.csr_addr,
1708 			    0, 0, &dev_attr, &hba->sli.sli3.csr_acc_handle);
1709 			if (status != DDI_SUCCESS) {
1710 				EMLXS_MSGF(EMLXS_CONTEXT,
1711 				    &emlxs_attach_failed_msg,
1712 				    "(SBUS) ddi_regs_map_setup DFLY CSR "
1713 				    "failed. status=%x", status);
1714 				goto failed;
1715 			}
1716 		}
1717 		if (hba->sli.sli3.sbus_flash_acc_handle == 0) {
1718 			status = ddi_regs_map_setup(dip, SBUS_FLASH_RDWR,
1719 			    (caddr_t *)&hba->sli.sli3.sbus_flash_addr, 0, 0,
1720 			    &dev_attr, &hba->sli.sli3.sbus_flash_acc_handle);
1721 			if (status != DDI_SUCCESS) {
1722 				EMLXS_MSGF(EMLXS_CONTEXT,
1723 				    &emlxs_attach_failed_msg,
1724 				    "(SBUS) ddi_regs_map_setup Fcode Flash "
1725 				    "failed. status=%x", status);
1726 				goto failed;
1727 			}
1728 		}
1729 		if (hba->sli.sli3.sbus_core_acc_handle == 0) {
1730 			status = ddi_regs_map_setup(dip, SBUS_TITAN_CORE_RINDEX,
1731 			    (caddr_t *)&hba->sli.sli3.sbus_core_addr, 0, 0,
1732 			    &dev_attr, &hba->sli.sli3.sbus_core_acc_handle);
1733 			if (status != DDI_SUCCESS) {
1734 				EMLXS_MSGF(EMLXS_CONTEXT,
1735 				    &emlxs_attach_failed_msg,
1736 				    "(SBUS) ddi_regs_map_setup TITAN CORE "
1737 				    "failed. status=%x", status);
1738 				goto failed;
1739 			}
1740 		}
1741 
1742 		if (hba->sli.sli3.sbus_csr_handle == 0) {
1743 			status = ddi_regs_map_setup(dip, SBUS_TITAN_CSR_RINDEX,
1744 			    (caddr_t *)&hba->sli.sli3.sbus_csr_addr,
1745 			    0, 0, &dev_attr, &hba->sli.sli3.sbus_csr_handle);
1746 			if (status != DDI_SUCCESS) {
1747 				EMLXS_MSGF(EMLXS_CONTEXT,
1748 				    &emlxs_attach_failed_msg,
1749 				    "(SBUS) ddi_regs_map_setup TITAN CSR "
1750 				    "failed. status=%x", status);
1751 				goto failed;
1752 			}
1753 		}
1754 	} else {	/* ****** PCI ****** */
1755 
1756 		if (hba->sli.sli3.slim_acc_handle == 0) {
1757 			status = ddi_regs_map_setup(dip, PCI_SLIM_RINDEX,
1758 			    (caddr_t *)&hba->sli.sli3.slim_addr,
1759 			    0, 0, &dev_attr, &hba->sli.sli3.slim_acc_handle);
1760 			if (status != DDI_SUCCESS) {
1761 				EMLXS_MSGF(EMLXS_CONTEXT,
1762 				    &emlxs_attach_failed_msg,
1763 				    "(PCI) ddi_regs_map_setup SLIM failed. "
1764 				    "stat=%d mem=%p attr=%p hdl=%p",
1765 				    status, &hba->sli.sli3.slim_addr, &dev_attr,
1766 				    &hba->sli.sli3.slim_acc_handle);
1767 				goto failed;
1768 			}
1769 		}
1770 
1771 		/*
1772 		 * Map in control registers, using memory-mapped version of
1773 		 * the registers rather than the I/O space-mapped registers.
1774 		 */
1775 		if (hba->sli.sli3.csr_acc_handle == 0) {
1776 			status = ddi_regs_map_setup(dip, PCI_CSR_RINDEX,
1777 			    (caddr_t *)&hba->sli.sli3.csr_addr,
1778 			    0, 0, &dev_attr, &hba->sli.sli3.csr_acc_handle);
1779 			if (status != DDI_SUCCESS) {
1780 				EMLXS_MSGF(EMLXS_CONTEXT,
1781 				    &emlxs_attach_failed_msg,
1782 				    "ddi_regs_map_setup CSR failed. status=%x",
1783 				    status);
1784 				goto failed;
1785 			}
1786 		}
1787 	}
1788 
1789 	if (hba->sli.sli3.slim2.virt == 0) {
1790 		MBUF_INFO	*buf_info;
1791 		MBUF_INFO	bufinfo;
1792 
1793 		buf_info = &bufinfo;
1794 
1795 		bzero(buf_info, sizeof (MBUF_INFO));
1796 		buf_info->size = SLI_SLIM2_SIZE;
1797 		buf_info->flags =
1798 		    FC_MBUF_DMA | FC_MBUF_SNGLSG | FC_MBUF_DMA32;
1799 		buf_info->align = ddi_ptob(dip, 1L);
1800 
1801 		(void) emlxs_mem_alloc(hba, buf_info);
1802 
1803 		if (buf_info->virt == NULL) {
1804 			goto failed;
1805 		}
1806 
1807 		hba->sli.sli3.slim2.virt = buf_info->virt;
1808 		hba->sli.sli3.slim2.phys = buf_info->phys;
1809 		hba->sli.sli3.slim2.size = SLI_SLIM2_SIZE;
1810 		hba->sli.sli3.slim2.data_handle = buf_info->data_handle;
1811 		hba->sli.sli3.slim2.dma_handle = buf_info->dma_handle;
1812 		bzero((char *)hba->sli.sli3.slim2.virt, SLI_SLIM2_SIZE);
1813 	}
1814 
1815 	/* offset from beginning of register space */
1816 	hba->sli.sli3.ha_reg_addr = (uint32_t *)(hba->sli.sli3.csr_addr +
1817 	    (sizeof (uint32_t) * HA_REG_OFFSET));
1818 	hba->sli.sli3.ca_reg_addr = (uint32_t *)(hba->sli.sli3.csr_addr +
1819 	    (sizeof (uint32_t) * CA_REG_OFFSET));
1820 	hba->sli.sli3.hs_reg_addr = (uint32_t *)(hba->sli.sli3.csr_addr +
1821 	    (sizeof (uint32_t) * HS_REG_OFFSET));
1822 	hba->sli.sli3.hc_reg_addr = (uint32_t *)(hba->sli.sli3.csr_addr +
1823 	    (sizeof (uint32_t) * HC_REG_OFFSET));
1824 	hba->sli.sli3.bc_reg_addr = (uint32_t *)(hba->sli.sli3.csr_addr +
1825 	    (sizeof (uint32_t) * BC_REG_OFFSET));
1826 
1827 	if (hba->bus_type == SBUS_FC) {
1828 		/* offset from beginning of register space */
1829 		/* for TITAN registers */
1830 		hba->sli.sli3.shc_reg_addr =
1831 		    (uint32_t *)(hba->sli.sli3.sbus_csr_addr +
1832 		    (sizeof (uint32_t) * SBUS_CTRL_REG_OFFSET));
1833 		hba->sli.sli3.shs_reg_addr =
1834 		    (uint32_t *)(hba->sli.sli3.sbus_csr_addr +
1835 		    (sizeof (uint32_t) * SBUS_STAT_REG_OFFSET));
1836 		hba->sli.sli3.shu_reg_addr =
1837 		    (uint32_t *)(hba->sli.sli3.sbus_csr_addr +
1838 		    (sizeof (uint32_t) * SBUS_UPDATE_REG_OFFSET));
1839 	}
1840 	hba->chan_count = MAX_RINGS;
1841 
1842 	return (0);
1843 
1844 failed:
1845 
1846 	emlxs_sli3_unmap_hdw(hba);
1847 	return (ENOMEM);
1848 
1849 } /* emlxs_sli3_map_hdw() */
1850 
1851 
1852 static void
1853 emlxs_sli3_unmap_hdw(emlxs_hba_t *hba)
1854 {
1855 	MBUF_INFO	bufinfo;
1856 	MBUF_INFO	*buf_info = &bufinfo;
1857 
1858 	if (hba->sli.sli3.csr_acc_handle) {
1859 		ddi_regs_map_free(&hba->sli.sli3.csr_acc_handle);
1860 		hba->sli.sli3.csr_acc_handle = 0;
1861 	}
1862 
1863 	if (hba->sli.sli3.slim_acc_handle) {
1864 		ddi_regs_map_free(&hba->sli.sli3.slim_acc_handle);
1865 		hba->sli.sli3.slim_acc_handle = 0;
1866 	}
1867 
1868 	if (hba->sli.sli3.sbus_flash_acc_handle) {
1869 		ddi_regs_map_free(&hba->sli.sli3.sbus_flash_acc_handle);
1870 		hba->sli.sli3.sbus_flash_acc_handle = 0;
1871 	}
1872 
1873 	if (hba->sli.sli3.sbus_core_acc_handle) {
1874 		ddi_regs_map_free(&hba->sli.sli3.sbus_core_acc_handle);
1875 		hba->sli.sli3.sbus_core_acc_handle = 0;
1876 	}
1877 
1878 	if (hba->sli.sli3.sbus_csr_handle) {
1879 		ddi_regs_map_free(&hba->sli.sli3.sbus_csr_handle);
1880 		hba->sli.sli3.sbus_csr_handle = 0;
1881 	}
1882 
1883 	if (hba->sli.sli3.slim2.virt) {
1884 		bzero(buf_info, sizeof (MBUF_INFO));
1885 
1886 		if (hba->sli.sli3.slim2.phys) {
1887 			buf_info->phys = hba->sli.sli3.slim2.phys;
1888 			buf_info->data_handle = hba->sli.sli3.slim2.data_handle;
1889 			buf_info->dma_handle = hba->sli.sli3.slim2.dma_handle;
1890 			buf_info->flags = FC_MBUF_DMA;
1891 		}
1892 
1893 		buf_info->virt = hba->sli.sli3.slim2.virt;
1894 		buf_info->size = hba->sli.sli3.slim2.size;
1895 		emlxs_mem_free(hba, buf_info);
1896 
1897 		hba->sli.sli3.slim2.virt = NULL;
1898 	}
1899 
1900 
1901 	return;
1902 
1903 } /* emlxs_sli3_unmap_hdw() */
1904 
1905 
1906 static uint32_t
1907 emlxs_sli3_hba_init(emlxs_hba_t *hba)
1908 {
1909 	emlxs_port_t *port = &PPORT;
1910 	emlxs_port_t *vport;
1911 	emlxs_config_t *cfg;
1912 	uint16_t i;
1913 	VPIobj_t *vpip;
1914 
1915 	cfg = &CFG;
1916 	i = 0;
1917 
1918 	/* Restart the adapter */
1919 	if (emlxs_sli3_hba_reset(hba, 1, 0, 0)) {
1920 		return (1);
1921 	}
1922 
1923 	hba->channel_fcp = FC_FCP_RING;
1924 	hba->channel_els = FC_ELS_RING;
1925 	hba->channel_ip = FC_IP_RING;
1926 	hba->channel_ct = FC_CT_RING;
1927 	hba->chan_count = MAX_RINGS;
1928 	hba->sli.sli3.ring_count = MAX_RINGS;
1929 
1930 	/*
1931 	 * WARNING: There is a max of 6 ring masks allowed
1932 	 */
1933 	/* RING 0 - FCP */
1934 	if (port->flag & EMLXS_TGT_ENABLED) {
1935 		hba->sli.sli3.ring_masks[FC_FCP_RING] = 1;
1936 		hba->sli.sli3.ring_rval[i] = FC_FCP_CMND;
1937 		hba->sli.sli3.ring_rmask[i] = 0;
1938 		hba->sli.sli3.ring_tval[i] = FC_TYPE_SCSI_FCP;
1939 		hba->sli.sli3.ring_tmask[i++] = 0xFF;
1940 	} else {
1941 		hba->sli.sli3.ring_masks[FC_FCP_RING] = 0;
1942 	}
1943 
1944 	hba->sli.sli3.ring[FC_FCP_RING].fc_numCiocb = SLIM_IOCB_CMD_R0_ENTRIES;
1945 	hba->sli.sli3.ring[FC_FCP_RING].fc_numRiocb = SLIM_IOCB_RSP_R0_ENTRIES;
1946 
1947 	/* RING 1 - IP */
1948 	if (cfg[CFG_NETWORK_ON].current) {
1949 		hba->sli.sli3.ring_masks[FC_IP_RING] = 1;
1950 		hba->sli.sli3.ring_rval[i] = FC_UNSOL_DATA; /* Unsol Data */
1951 		hba->sli.sli3.ring_rmask[i] = 0xFF;
1952 		hba->sli.sli3.ring_tval[i] = FC_TYPE_IS8802_SNAP; /* LLC/SNAP */
1953 		hba->sli.sli3.ring_tmask[i++] = 0xFF;
1954 	} else {
1955 		hba->sli.sli3.ring_masks[FC_IP_RING] = 0;
1956 	}
1957 
1958 	hba->sli.sli3.ring[FC_IP_RING].fc_numCiocb = SLIM_IOCB_CMD_R1_ENTRIES;
1959 	hba->sli.sli3.ring[FC_IP_RING].fc_numRiocb = SLIM_IOCB_RSP_R1_ENTRIES;
1960 
1961 	/* RING 2 - ELS */
1962 	hba->sli.sli3.ring_masks[FC_ELS_RING] = 1;
1963 	hba->sli.sli3.ring_rval[i] = FC_ELS_REQ;	/* ELS request/rsp */
1964 	hba->sli.sli3.ring_rmask[i] = 0xFE;
1965 	hba->sli.sli3.ring_tval[i] = FC_TYPE_EXTENDED_LS;	/* ELS */
1966 	hba->sli.sli3.ring_tmask[i++] = 0xFF;
1967 
1968 	hba->sli.sli3.ring[FC_ELS_RING].fc_numCiocb = SLIM_IOCB_CMD_R2_ENTRIES;
1969 	hba->sli.sli3.ring[FC_ELS_RING].fc_numRiocb = SLIM_IOCB_RSP_R2_ENTRIES;
1970 
1971 	/* RING 3 - CT */
1972 	hba->sli.sli3.ring_masks[FC_CT_RING] = 1;
1973 	hba->sli.sli3.ring_rval[i] = FC_UNSOL_CTL;	/* CT request/rsp */
1974 	hba->sli.sli3.ring_rmask[i] = 0xFE;
1975 	hba->sli.sli3.ring_tval[i] = FC_TYPE_FC_SERVICES;	/* CT */
1976 	hba->sli.sli3.ring_tmask[i++] = 0xFF;
1977 
1978 	hba->sli.sli3.ring[FC_CT_RING].fc_numCiocb = SLIM_IOCB_CMD_R3_ENTRIES;
1979 	hba->sli.sli3.ring[FC_CT_RING].fc_numRiocb = SLIM_IOCB_RSP_R3_ENTRIES;
1980 
1981 	if (i > 6) {
1982 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_attach_failed_msg,
1983 		    "hba_init: Too many ring masks defined. cnt=%d", i);
1984 		return (1);
1985 	}
1986 
1987 	/* Initialize all the port objects */
1988 	hba->vpi_max = 0;
1989 	for (i = 0; i < MAX_VPORTS; i++) {
1990 		vport = &VPORT(i);
1991 		vport->hba = hba;
1992 		vport->vpi = i;
1993 
1994 		vpip = &vport->VPIobj;
1995 		vpip->index = i;
1996 		vpip->VPI = i;
1997 		vpip->port = vport;
1998 		vpip->state = VPI_STATE_OFFLINE;
1999 		vport->vpip = vpip;
2000 	}
2001 
2002 	/*
2003 	 * Initialize the max_node count to a default value if needed
2004 	 * This determines how many node objects we preallocate in the pool
2005 	 * The actual max_nodes will be set later based on adapter info
2006 	 */
2007 	if (hba->max_nodes == 0) {
2008 		if (cfg[CFG_NUM_NODES].current > 0) {
2009 			hba->max_nodes = cfg[CFG_NUM_NODES].current;
2010 		} else if (hba->model_info.chip >= EMLXS_SATURN_CHIP) {
2011 			hba->max_nodes = 4096;
2012 		} else {
2013 			hba->max_nodes = 512;
2014 		}
2015 	}
2016 
2017 	return (0);
2018 
2019 } /* emlxs_sli3_hba_init() */
2020 
2021 
2022 /*
2023  * 0: quiesce indicates the call is not from quiesce routine.
2024  * 1: quiesce indicates the call is from quiesce routine.
2025  */
2026 static uint32_t
2027 emlxs_sli3_hba_reset(emlxs_hba_t *hba, uint32_t restart, uint32_t skip_post,
2028 	uint32_t quiesce)
2029 {
2030 	emlxs_port_t *port = &PPORT;
2031 	MAILBOX *swpmb;
2032 	MAILBOX *mb;
2033 	uint32_t word0;
2034 	uint16_t cfg_value;
2035 	uint32_t status = 0;
2036 	uint32_t status1;
2037 	uint32_t status2;
2038 	uint32_t i;
2039 	uint32_t ready;
2040 	emlxs_port_t *vport;
2041 	RING *rp;
2042 	emlxs_config_t *cfg = &CFG;
2043 
2044 	if (!cfg[CFG_RESET_ENABLE].current) {
2045 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg,
2046 		    "Adapter reset disabled.");
2047 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
2048 
2049 		return (1);
2050 	}
2051 
2052 	/* Kill the adapter first */
2053 	if (quiesce == 0) {
2054 		emlxs_sli3_hba_kill(hba);
2055 	} else {
2056 		emlxs_sli3_hba_kill4quiesce(hba);
2057 	}
2058 
2059 	if (restart) {
2060 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2061 		    "Restarting.");
2062 		EMLXS_STATE_CHANGE(hba, FC_INIT_START);
2063 
2064 		ready = (HS_FFRDY | HS_MBRDY);
2065 	} else {
2066 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2067 		    "Resetting.");
2068 		EMLXS_STATE_CHANGE(hba, FC_WARM_START);
2069 
2070 		ready = HS_MBRDY;
2071 	}
2072 
2073 	hba->flag &= ~(FC_SLIM2_MODE | FC_HARDWARE_ERROR);
2074 
2075 	mb = FC_SLIM1_MAILBOX(hba);
2076 	swpmb = (MAILBOX *)&word0;
2077 
2078 reset:
2079 
2080 	i = 0;
2081 
2082 	/* Save reset time */
2083 	HBASTATS.ResetTime = hba->timer_tics;
2084 
2085 	if (restart) {
2086 		/* First put restart command in mailbox */
2087 		word0 = 0;
2088 		swpmb->mbxCommand = MBX_RESTART;
2089 		swpmb->mbxHc = 1;
2090 		WRITE_SLIM_ADDR(hba, ((volatile uint32_t *)mb), word0);
2091 
2092 		/* Only skip post after emlxs_sli3_online is completed */
2093 		if (skip_post) {
2094 			WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb) + 1),
2095 			    1);
2096 		} else {
2097 			WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb) + 1),
2098 			    0);
2099 		}
2100 
2101 	}
2102 
2103 	/*
2104 	 * Turn off SERR, PERR in PCI cmd register
2105 	 */
2106 	cfg_value = ddi_get16(hba->pci_acc_handle,
2107 	    (uint16_t *)(hba->pci_addr + PCI_COMMAND_REGISTER));
2108 
2109 	ddi_put16(hba->pci_acc_handle,
2110 	    (uint16_t *)(hba->pci_addr + PCI_COMMAND_REGISTER),
2111 	    (uint16_t)(cfg_value & ~(CMD_PARITY_CHK | CMD_SERR_ENBL)));
2112 
2113 	hba->sli.sli3.hc_copy = HC_INITFF;
2114 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
2115 
2116 	/* Wait 1 msec before restoring PCI config */
2117 	BUSYWAIT_MS(1);
2118 
2119 	/* Restore PCI cmd register */
2120 	ddi_put16(hba->pci_acc_handle,
2121 	    (uint16_t *)(hba->pci_addr + PCI_COMMAND_REGISTER),
2122 	    (uint16_t)cfg_value);
2123 
2124 	/* Wait 3 seconds before checking */
2125 	BUSYWAIT_MS(3000);
2126 	i += 3;
2127 
2128 	/* Wait for reset completion */
2129 	while (i < 30) {
2130 		/* Check status register to see what current state is */
2131 		status = READ_CSR_REG(hba, FC_HS_REG(hba));
2132 
2133 		/* Check to see if any errors occurred during init */
2134 		if (status & HS_FFERM) {
2135 			status1 = READ_SLIM_ADDR(hba, ((volatile uint8_t *)
2136 			    hba->sli.sli3.slim_addr + 0xa8));
2137 			status2 = READ_SLIM_ADDR(hba, ((volatile uint8_t *)
2138 			    hba->sli.sli3.slim_addr + 0xac));
2139 
2140 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg,
2141 			    "HS_FFERM: status=0x%x status1=0x%x status2=0x%x",
2142 			    status, status1, status2);
2143 
2144 			EMLXS_STATE_CHANGE(hba, FC_ERROR);
2145 			return (1);
2146 		}
2147 
2148 		if ((status & ready) == ready) {
2149 			/* Reset Done !! */
2150 			goto done;
2151 		}
2152 
2153 		/*
2154 		 * Check every 1 second for 15 seconds, then reset board
2155 		 * again (w/post), then check every 1 second for 15 * seconds.
2156 		 */
2157 		BUSYWAIT_MS(1000);
2158 		i++;
2159 
2160 		/* Reset again (w/post) at 15 seconds */
2161 		if (i == 15) {
2162 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
2163 			    "Reset failed. Retrying...");
2164 
2165 			goto reset;
2166 		}
2167 	}
2168 
2169 #ifdef FMA_SUPPORT
2170 reset_fail:
2171 #endif  /* FMA_SUPPORT */
2172 
2173 	/* Timeout occurred */
2174 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_reset_failed_msg,
2175 	    "Timeout: status=0x%x", status);
2176 	EMLXS_STATE_CHANGE(hba, FC_ERROR);
2177 
2178 	/* Log a dump event */
2179 	emlxs_log_dump_event(port, NULL, 0);
2180 
2181 	return (1);
2182 
2183 done:
2184 
2185 	/* Initialize hc_copy */
2186 	hba->sli.sli3.hc_copy = READ_CSR_REG(hba, FC_HC_REG(hba));
2187 
2188 #ifdef FMA_SUPPORT
2189 	/* Access handle validation */
2190 	if ((emlxs_fm_check_acc_handle(hba, hba->pci_acc_handle)
2191 	    != DDI_FM_OK) ||
2192 	    (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
2193 	    != DDI_FM_OK) ||
2194 	    (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.csr_acc_handle)
2195 	    != DDI_FM_OK)) {
2196 		EMLXS_MSGF(EMLXS_CONTEXT,
2197 		    &emlxs_invalid_access_handle_msg, NULL);
2198 		goto reset_fail;
2199 	}
2200 #endif  /* FMA_SUPPORT */
2201 
2202 	/* Reset the hba structure */
2203 	hba->flag &= FC_RESET_MASK;
2204 	hba->channel_tx_count = 0;
2205 	hba->io_count = 0;
2206 	hba->iodone_count = 0;
2207 	hba->topology = 0;
2208 	hba->linkspeed = 0;
2209 	hba->heartbeat_active = 0;
2210 	hba->discovery_timer = 0;
2211 	hba->linkup_timer = 0;
2212 	hba->loopback_tics = 0;
2213 
2214 	/* Reset the ring objects */
2215 	for (i = 0; i < MAX_RINGS; i++) {
2216 		rp = &hba->sli.sli3.ring[i];
2217 		rp->fc_mpon = 0;
2218 		rp->fc_mpoff = 0;
2219 	}
2220 
2221 	/* Reset the port objects */
2222 	for (i = 0; i < MAX_VPORTS; i++) {
2223 		vport = &VPORT(i);
2224 
2225 		vport->flag &= EMLXS_PORT_RESET_MASK;
2226 		vport->did = 0;
2227 		vport->prev_did = 0;
2228 		vport->lip_type = 0;
2229 		bzero(&vport->fabric_sparam, sizeof (SERV_PARM));
2230 		bzero(&vport->prev_fabric_sparam, sizeof (SERV_PARM));
2231 
2232 		bzero((caddr_t)&vport->node_base, sizeof (NODELIST));
2233 		vport->node_base.nlp_Rpi = 0;
2234 		vport->node_base.nlp_DID = 0xffffff;
2235 		vport->node_base.nlp_list_next = NULL;
2236 		vport->node_base.nlp_list_prev = NULL;
2237 		vport->node_base.nlp_active = 1;
2238 		vport->node_count = 0;
2239 
2240 		if (vport->ub_count < EMLXS_UB_TOKEN_OFFSET) {
2241 			vport->ub_count = EMLXS_UB_TOKEN_OFFSET;
2242 		}
2243 	}
2244 
2245 	return (0);
2246 
2247 } /* emlxs_sli3_hba_reset */
2248 
2249 
2250 #define	BPL_CMD		0
2251 #define	BPL_RESP	1
2252 #define	BPL_DATA	2
2253 
2254 static ULP_BDE64 *
2255 emlxs_pkt_to_bpl(fc_packet_t *pkt, ULP_BDE64 *bpl, uint32_t bpl_type)
2256 {
2257 	ddi_dma_cookie_t *cp;
2258 	uint_t	i;
2259 	int32_t	size;
2260 	uint_t	cookie_cnt;
2261 	uint8_t bdeFlags;
2262 
2263 #if (EMLXS_MODREV >= EMLXS_MODREV3)
2264 	switch (bpl_type) {
2265 	case BPL_CMD:
2266 		cp = pkt->pkt_cmd_cookie;
2267 		cookie_cnt = pkt->pkt_cmd_cookie_cnt;
2268 		size = (int32_t)pkt->pkt_cmdlen;
2269 		bdeFlags = 0;
2270 		break;
2271 
2272 	case BPL_RESP:
2273 		cp = pkt->pkt_resp_cookie;
2274 		cookie_cnt = pkt->pkt_resp_cookie_cnt;
2275 		size = (int32_t)pkt->pkt_rsplen;
2276 		bdeFlags = BUFF_USE_RCV;
2277 		break;
2278 
2279 
2280 	case BPL_DATA:
2281 		cp = pkt->pkt_data_cookie;
2282 		cookie_cnt = pkt->pkt_data_cookie_cnt;
2283 		size = (int32_t)pkt->pkt_datalen;
2284 		bdeFlags = (pkt->pkt_tran_type == FC_PKT_FCP_READ) ?
2285 		    BUFF_USE_RCV : 0;
2286 		break;
2287 
2288 	default:
2289 		return (NULL);
2290 	}
2291 
2292 #else
2293 	switch (bpl_type) {
2294 	case BPL_CMD:
2295 		cp = &pkt->pkt_cmd_cookie;
2296 		cookie_cnt = 1;
2297 		size = (int32_t)pkt->pkt_cmdlen;
2298 		bdeFlags = 0;
2299 		break;
2300 
2301 	case BPL_RESP:
2302 		cp = &pkt->pkt_resp_cookie;
2303 		cookie_cnt = 1;
2304 		size = (int32_t)pkt->pkt_rsplen;
2305 		bdeFlags = BUFF_USE_RCV;
2306 		break;
2307 
2308 
2309 	case BPL_DATA:
2310 		cp = &pkt->pkt_data_cookie;
2311 		cookie_cnt = 1;
2312 		size = (int32_t)pkt->pkt_datalen;
2313 		bdeFlags = (pkt->pkt_tran_type == FC_PKT_FCP_READ) ?
2314 		    BUFF_USE_RCV : 0;
2315 		break;
2316 
2317 	default:
2318 		return (NULL);
2319 	}
2320 #endif	/* >= EMLXS_MODREV3 */
2321 
2322 	for (i = 0; i < cookie_cnt && size > 0; i++, cp++) {
2323 		bpl->addrHigh =
2324 		    BE_SWAP32(PADDR_HI(cp->dmac_laddress));
2325 		bpl->addrLow =
2326 		    BE_SWAP32(PADDR_LO(cp->dmac_laddress));
2327 		bpl->tus.f.bdeSize = MIN(size, cp->dmac_size);
2328 		bpl->tus.f.bdeFlags = bdeFlags;
2329 		bpl->tus.w = BE_SWAP32(bpl->tus.w);
2330 
2331 		bpl++;
2332 		size -= cp->dmac_size;
2333 	}
2334 
2335 	return (bpl);
2336 
2337 } /* emlxs_pkt_to_bpl */
2338 
2339 
2340 static uint32_t
2341 emlxs_sli2_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
2342 {
2343 	emlxs_hba_t	*hba = HBA;
2344 	fc_packet_t	*pkt;
2345 	MATCHMAP	*bmp;
2346 	ULP_BDE64	*bpl;
2347 	uint64_t	bp;
2348 	IOCB		*iocb;
2349 	IOCBQ		*iocbq;
2350 	CHANNEL	*cp;
2351 	uint32_t	data_cookie_cnt;
2352 	uint32_t	channelno;
2353 
2354 	cp = sbp->channel;
2355 	iocb = (IOCB *) & sbp->iocbq;
2356 	pkt = PRIV2PKT(sbp);
2357 
2358 	if (hba->sli.sli3.bpl_table) {
2359 		bmp = hba->sli.sli3.bpl_table[sbp->iotag];
2360 	} else {
2361 		bmp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BPL);
2362 	}
2363 
2364 	if (!bmp) {
2365 		return (1);
2366 	}
2367 
2368 	sbp->bmp = bmp;
2369 	bpl = (ULP_BDE64 *)bmp->virt;
2370 	bp = bmp->phys;
2371 
2372 #if (EMLXS_MODREV >= EMLXS_MODREV3)
2373 	data_cookie_cnt = pkt->pkt_data_cookie_cnt;
2374 #else
2375 	data_cookie_cnt = 1;
2376 #endif	/* >= EMLXS_MODREV3 */
2377 
2378 	iocbq = &sbp->iocbq;
2379 
2380 	channelno = (iocbq->flag & IOCB_FCP_CMD)? FC_FCP_RING:cp->channelno;
2381 	switch (channelno) {
2382 		case FC_FCP_RING:
2383 
2384 		/* CMD payload */
2385 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_CMD);
2386 		if (! bpl) {
2387 			return (1);
2388 		}
2389 
2390 		/* Check if response & data payloads are needed */
2391 		if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
2392 			break;
2393 		}
2394 
2395 		/* RSP payload */
2396 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_RESP);
2397 		if (! bpl) {
2398 			return (1);
2399 		}
2400 
2401 		/* Check if data payload is needed */
2402 		if ((pkt->pkt_datalen == 0) ||
2403 		    (data_cookie_cnt == 0)) {
2404 			break;
2405 		}
2406 
2407 		/* DATA payload */
2408 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_DATA);
2409 		if (! bpl) {
2410 			return (1);
2411 		}
2412 		break;
2413 
2414 	case FC_IP_RING:
2415 
2416 		/* CMD payload */
2417 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_CMD);
2418 		if (! bpl) {
2419 			return (1);
2420 		}
2421 		break;
2422 
2423 	case FC_ELS_RING:
2424 
2425 		/* CMD payload */
2426 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_CMD);
2427 		if (! bpl) {
2428 			return (1);
2429 		}
2430 
2431 		/* Check if response payload is needed */
2432 		if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
2433 			break;
2434 		}
2435 
2436 		/* RSP payload */
2437 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_RESP);
2438 		if (! bpl) {
2439 			return (1);
2440 		}
2441 		break;
2442 
2443 	case FC_CT_RING:
2444 
2445 		/* CMD payload */
2446 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_CMD);
2447 		if (! bpl) {
2448 			return (1);
2449 		}
2450 
2451 		/* Check if response payload is needed */
2452 		if ((pkt->pkt_tran_type == FC_PKT_OUTBOUND) &&
2453 		    (pkt->pkt_cmd_fhdr.type != EMLXS_MENLO_TYPE)) {
2454 			break;
2455 		}
2456 
2457 		/* RSP payload */
2458 		bpl = emlxs_pkt_to_bpl(pkt, bpl, BPL_RESP);
2459 		if (! bpl) {
2460 			return (1);
2461 		}
2462 		break;
2463 
2464 	}
2465 
2466 	iocb->un.genreq64.bdl.bdeFlags = BUFF_TYPE_BDL;
2467 	iocb->un.genreq64.bdl.addrHigh = PADDR_HI(bp);
2468 	iocb->un.genreq64.bdl.addrLow  = PADDR_LO(bp);
2469 	iocb->un.genreq64.bdl.bdeSize  =
2470 	    (uint32_t)(((uintptr_t)bpl - (uintptr_t)bmp->virt) & 0xFFFFFFFF);
2471 	iocb->ULPBDECOUNT = 1;
2472 	iocb->ULPLE = 1;
2473 
2474 	return (0);
2475 
2476 } /* emlxs_sli2_bde_setup */
2477 
2478 
2479 static uint32_t
2480 emlxs_sli3_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
2481 {
2482 	ddi_dma_cookie_t *cp_cmd;
2483 	ddi_dma_cookie_t *cp_resp;
2484 	ddi_dma_cookie_t *cp_data;
2485 	fc_packet_t	*pkt;
2486 	ULP_BDE64	*bde;
2487 	int		data_cookie_cnt;
2488 	uint32_t	i;
2489 	uint32_t	channelno;
2490 	IOCB		*iocb;
2491 	IOCBQ		*iocbq;
2492 	CHANNEL		*cp;
2493 
2494 	pkt = PRIV2PKT(sbp);
2495 #if (EMLXS_MODREV >= EMLXS_MODREV3)
2496 	if ((pkt->pkt_cmd_cookie_cnt > 1) ||
2497 	    (pkt->pkt_resp_cookie_cnt > 1) ||
2498 	    ((pkt->pkt_cmd_cookie_cnt + pkt->pkt_resp_cookie_cnt +
2499 	    pkt->pkt_data_cookie_cnt) > SLI3_MAX_BDE)) {
2500 		i = emlxs_sli2_bde_setup(port, sbp);
2501 		return (i);
2502 	}
2503 
2504 	cp_cmd = pkt->pkt_cmd_cookie;
2505 	cp_resp = pkt->pkt_resp_cookie;
2506 	cp_data = pkt->pkt_data_cookie;
2507 	data_cookie_cnt = pkt->pkt_data_cookie_cnt;
2508 #else
2509 	cp_cmd  = &pkt->pkt_cmd_cookie;
2510 	cp_resp = &pkt->pkt_resp_cookie;
2511 	cp_data = &pkt->pkt_data_cookie;
2512 	data_cookie_cnt = 1;
2513 #endif	/* >= EMLXS_MODREV3 */
2514 
2515 	cp = sbp->channel;
2516 	iocbq = &sbp->iocbq;
2517 	iocb = (IOCB *)iocbq;
2518 	iocb->unsli3.ext_iocb.ebde_count = 0;
2519 
2520 	channelno = (iocbq->flag & IOCB_FCP_CMD)? FC_FCP_RING:cp->channelno;
2521 	switch (channelno) {
2522 	case FC_FCP_RING:
2523 		/* CMD payload */
2524 		iocb->un.fcpi64.bdl.addrHigh =
2525 		    PADDR_HI(cp_cmd->dmac_laddress);
2526 		iocb->un.fcpi64.bdl.addrLow =
2527 		    PADDR_LO(cp_cmd->dmac_laddress);
2528 		iocb->un.fcpi64.bdl.bdeSize  = pkt->pkt_cmdlen;
2529 		iocb->un.fcpi64.bdl.bdeFlags = 0;
2530 
2531 		/* Check if a response & data payload are needed */
2532 		if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
2533 			break;
2534 		}
2535 
2536 		/* RSP payload */
2537 		iocb->unsli3.ext_iocb.ebde1.addrHigh =
2538 		    PADDR_HI(cp_resp->dmac_laddress);
2539 		iocb->unsli3.ext_iocb.ebde1.addrLow =
2540 		    PADDR_LO(cp_resp->dmac_laddress);
2541 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeSize = pkt->pkt_rsplen;
2542 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeFlags = 0;
2543 		iocb->unsli3.ext_iocb.ebde_count = 1;
2544 
2545 		/* Check if a data payload is needed */
2546 		if ((pkt->pkt_datalen == 0) ||
2547 		    (data_cookie_cnt == 0)) {
2548 			break;
2549 		}
2550 
2551 		/* DATA payload */
2552 		bde = (ULP_BDE64 *)&iocb->unsli3.ext_iocb.ebde2;
2553 		for (i = 0; i < data_cookie_cnt; i++) {
2554 			bde->addrHigh = PADDR_HI(cp_data->dmac_laddress);
2555 			bde->addrLow = PADDR_LO(cp_data->dmac_laddress);
2556 			bde->tus.f.bdeSize = cp_data->dmac_size;
2557 			bde->tus.f.bdeFlags = 0;
2558 			cp_data++;
2559 			bde++;
2560 		}
2561 		iocb->unsli3.ext_iocb.ebde_count += data_cookie_cnt;
2562 
2563 		break;
2564 
2565 	case FC_IP_RING:
2566 		/* CMD payload */
2567 		iocb->un.xseq64.bdl.addrHigh =
2568 		    PADDR_HI(cp_cmd->dmac_laddress);
2569 		iocb->un.xseq64.bdl.addrLow =
2570 		    PADDR_LO(cp_cmd->dmac_laddress);
2571 		iocb->un.xseq64.bdl.bdeSize  = pkt->pkt_cmdlen;
2572 		iocb->un.xseq64.bdl.bdeFlags = 0;
2573 
2574 		break;
2575 
2576 	case FC_ELS_RING:
2577 
2578 		/* CMD payload */
2579 		iocb->un.elsreq64.bdl.addrHigh =
2580 		    PADDR_HI(cp_cmd->dmac_laddress);
2581 		iocb->un.elsreq64.bdl.addrLow =
2582 		    PADDR_LO(cp_cmd->dmac_laddress);
2583 		iocb->un.elsreq64.bdl.bdeSize  = pkt->pkt_cmdlen;
2584 		iocb->un.elsreq64.bdl.bdeFlags = 0;
2585 
2586 		/* Check if a response payload is needed */
2587 		if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
2588 			break;
2589 		}
2590 
2591 		/* RSP payload */
2592 		iocb->unsli3.ext_iocb.ebde1.addrHigh =
2593 		    PADDR_HI(cp_resp->dmac_laddress);
2594 		iocb->unsli3.ext_iocb.ebde1.addrLow =
2595 		    PADDR_LO(cp_resp->dmac_laddress);
2596 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeSize = pkt->pkt_rsplen;
2597 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeFlags = BUFF_USE_RCV;
2598 		iocb->unsli3.ext_iocb.ebde_count = 1;
2599 		break;
2600 
2601 	case FC_CT_RING:
2602 
2603 		/* CMD payload */
2604 		iocb->un.genreq64.bdl.addrHigh =
2605 		    PADDR_HI(cp_cmd->dmac_laddress);
2606 		iocb->un.genreq64.bdl.addrLow =
2607 		    PADDR_LO(cp_cmd->dmac_laddress);
2608 		iocb->un.genreq64.bdl.bdeSize  = pkt->pkt_cmdlen;
2609 		iocb->un.genreq64.bdl.bdeFlags = 0;
2610 
2611 		/* Check if a response payload is needed */
2612 		if ((pkt->pkt_tran_type == FC_PKT_OUTBOUND) &&
2613 		    (pkt->pkt_cmd_fhdr.type != EMLXS_MENLO_TYPE)) {
2614 			break;
2615 		}
2616 
2617 		/* RSP payload */
2618 		iocb->unsli3.ext_iocb.ebde1.addrHigh =
2619 		    PADDR_HI(cp_resp->dmac_laddress);
2620 		iocb->unsli3.ext_iocb.ebde1.addrLow =
2621 		    PADDR_LO(cp_resp->dmac_laddress);
2622 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeSize = pkt->pkt_rsplen;
2623 		iocb->unsli3.ext_iocb.ebde1.tus.f.bdeFlags = BUFF_USE_RCV;
2624 		iocb->unsli3.ext_iocb.ebde_count = 1;
2625 		break;
2626 	}
2627 
2628 	iocb->ULPBDECOUNT = 0;
2629 	iocb->ULPLE = 0;
2630 
2631 	return (0);
2632 
2633 } /* emlxs_sli3_bde_setup */
2634 
2635 
2636 /* Only used for FCP Data xfers */
2637 #ifdef SFCT_SUPPORT
2638 /*ARGSUSED*/
2639 static uint32_t
2640 emlxs_sli2_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
2641 {
2642 	emlxs_hba_t *hba = HBA;
2643 	scsi_task_t *fct_task;
2644 	MATCHMAP *bmp;
2645 	ULP_BDE64 *bpl;
2646 	uint64_t bp;
2647 	uint8_t bdeFlags;
2648 	IOCB *iocb;
2649 	uint32_t size;
2650 	MATCHMAP *mp;
2651 
2652 	iocb = (IOCB *)&sbp->iocbq.iocb;
2653 	sbp->bmp = NULL;
2654 
2655 	if (!sbp->fct_buf) {
2656 		iocb->un.fcpt64.bdl.addrHigh = 0;
2657 		iocb->un.fcpt64.bdl.addrLow = 0;
2658 		iocb->un.fcpt64.bdl.bdeSize = 0;
2659 		iocb->un.fcpt64.bdl.bdeFlags = 0;
2660 		iocb->un.fcpt64.fcpt_Offset = 0;
2661 		iocb->un.fcpt64.fcpt_Length = 0;
2662 		iocb->ULPBDECOUNT = 0;
2663 		iocb->ULPLE = 1;
2664 		return (0);
2665 	}
2666 
2667 	if (hba->sli.sli3.bpl_table) {
2668 		bmp = hba->sli.sli3.bpl_table[sbp->iotag];
2669 	} else {
2670 		bmp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BPL);
2671 	}
2672 
2673 	if (!bmp) {
2674 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
2675 		    "fct_sli2_bde_setup: Unable to BPL buffer. iotag=%d",
2676 		    sbp->iotag);
2677 
2678 		iocb->un.fcpt64.bdl.addrHigh = 0;
2679 		iocb->un.fcpt64.bdl.addrLow = 0;
2680 		iocb->un.fcpt64.bdl.bdeSize = 0;
2681 		iocb->un.fcpt64.bdl.bdeFlags = 0;
2682 		iocb->un.fcpt64.fcpt_Offset = 0;
2683 		iocb->un.fcpt64.fcpt_Length = 0;
2684 		iocb->ULPBDECOUNT = 0;
2685 		iocb->ULPLE = 1;
2686 		return (1);
2687 	}
2688 
2689 	bpl = (ULP_BDE64 *)bmp->virt;
2690 	bp = bmp->phys;
2691 
2692 	fct_task = (scsi_task_t *)sbp->fct_cmd->cmd_specific;
2693 
2694 	size = sbp->fct_buf->db_data_size;
2695 	mp = (MATCHMAP *)sbp->fct_buf->db_port_private;
2696 
2697 	bdeFlags = (fct_task->task_flags & TF_WRITE_DATA) ? BUFF_USE_RCV : 0;
2698 
2699 	/* Init the buffer list */
2700 	bpl->addrHigh = BE_SWAP32(PADDR_HI(mp->phys));
2701 	bpl->addrLow = BE_SWAP32(PADDR_LO(mp->phys));
2702 	bpl->tus.f.bdeSize = size;
2703 	bpl->tus.f.bdeFlags = bdeFlags;
2704 	bpl->tus.w = BE_SWAP32(bpl->tus.w);
2705 
2706 	/* Init the IOCB */
2707 	iocb->un.fcpt64.bdl.addrHigh = PADDR_HI(bp);
2708 	iocb->un.fcpt64.bdl.addrLow = PADDR_LO(bp);
2709 	iocb->un.fcpt64.bdl.bdeSize = sizeof (ULP_BDE64);
2710 	iocb->un.fcpt64.bdl.bdeFlags = BUFF_TYPE_BDL;
2711 
2712 	iocb->un.fcpt64.fcpt_Length =
2713 	    (fct_task->task_flags & TF_WRITE_DATA) ? size : 0;
2714 	iocb->un.fcpt64.fcpt_Offset = 0;
2715 
2716 	iocb->ULPBDECOUNT = 1;
2717 	iocb->ULPLE = 1;
2718 	sbp->bmp = bmp;
2719 
2720 	return (0);
2721 
2722 } /* emlxs_sli2_fct_bde_setup */
2723 #endif /* SFCT_SUPPORT */
2724 
2725 
2726 #ifdef SFCT_SUPPORT
2727 /*ARGSUSED*/
2728 static uint32_t
2729 emlxs_sli3_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
2730 {
2731 	scsi_task_t *fct_task;
2732 	IOCB *iocb;
2733 	MATCHMAP *mp;
2734 	uint32_t bdeFlags;
2735 	uint32_t size;
2736 
2737 	iocb = (IOCB *)&sbp->iocbq;
2738 
2739 	if (!sbp->fct_buf) {
2740 		iocb->un.fcpt64.bdl.addrHigh = 0;
2741 		iocb->un.fcpt64.bdl.addrLow = 0;
2742 		iocb->un.fcpt64.bdl.bdeSize = 0;
2743 		iocb->un.fcpt64.bdl.bdeFlags = 0;
2744 		iocb->un.fcpt64.fcpt_Offset = 0;
2745 		iocb->un.fcpt64.fcpt_Length = 0;
2746 		iocb->ULPBDECOUNT = 0;
2747 		iocb->ULPLE = 0;
2748 		iocb->unsli3.ext_iocb.ebde_count = 0;
2749 		return (0);
2750 	}
2751 
2752 	fct_task = (scsi_task_t *)sbp->fct_cmd->cmd_specific;
2753 
2754 	size = sbp->fct_buf->db_data_size;
2755 	mp = (MATCHMAP *)sbp->fct_buf->db_port_private;
2756 
2757 	bdeFlags = (fct_task->task_flags & TF_WRITE_DATA) ? BUFF_USE_RCV : 0;
2758 
2759 	/* Init first BDE */
2760 	iocb->un.fcpt64.bdl.addrHigh = PADDR_HI(mp->phys);
2761 	iocb->un.fcpt64.bdl.addrLow = PADDR_LO(mp->phys);
2762 	iocb->un.fcpt64.bdl.bdeSize = size;
2763 	iocb->un.fcpt64.bdl.bdeFlags = bdeFlags;
2764 
2765 	iocb->unsli3.ext_iocb.ebde_count = 0;
2766 	iocb->un.fcpt64.fcpt_Length =
2767 	    (fct_task->task_flags & TF_WRITE_DATA) ? size : 0;
2768 	iocb->un.fcpt64.fcpt_Offset = 0;
2769 
2770 	iocb->ULPBDECOUNT = 0;
2771 	iocb->ULPLE = 0;
2772 
2773 	return (0);
2774 
2775 } /* emlxs_sli3_fct_bde_setup */
2776 #endif /* SFCT_SUPPORT */
2777 
2778 
2779 static void
2780 emlxs_sli3_issue_iocb_cmd(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
2781 {
2782 #ifdef FMA_SUPPORT
2783 	emlxs_port_t *port = &PPORT;
2784 #endif	/* FMA_SUPPORT */
2785 	PGP *pgp;
2786 	emlxs_buf_t *sbp;
2787 	SLIM2 *slim2p = (SLIM2 *)hba->sli.sli3.slim2.virt;
2788 	RING *rp;
2789 	uint32_t nextIdx;
2790 	uint32_t status;
2791 	void *ioa2;
2792 	off_t offset;
2793 	uint32_t count = 0;
2794 	uint32_t flag;
2795 	uint32_t channelno;
2796 	int32_t throttle;
2797 #ifdef NODE_THROTTLE_SUPPORT
2798 	int32_t node_throttle;
2799 	NODELIST *marked_node = NULL;
2800 #endif /* NODE_THROTTLE_SUPPORT */
2801 
2802 	channelno = cp->channelno;
2803 	rp = (RING *)cp->iopath;
2804 
2805 	throttle = 0;
2806 
2807 	/* Check if FCP ring and adapter is not ready */
2808 	/* We may use any ring for FCP_CMD */
2809 	if (iocbq && (iocbq->flag & IOCB_FCP_CMD) && (hba->state != FC_READY)) {
2810 		if (!(iocbq->flag & IOCB_SPECIAL) || !iocbq->port ||
2811 		    (((emlxs_port_t *)iocbq->port)->mode == MODE_INITIATOR)) {
2812 			emlxs_tx_put(iocbq, 1);
2813 			return;
2814 		}
2815 	}
2816 
2817 	/* Attempt to acquire CMD_RING lock */
2818 	if (mutex_tryenter(&EMLXS_CMD_RING_LOCK(channelno)) == 0) {
2819 		/* Queue it for later */
2820 		if (iocbq) {
2821 			if ((hba->io_count -
2822 			    hba->channel_tx_count) > 10) {
2823 				emlxs_tx_put(iocbq, 1);
2824 				return;
2825 			} else {
2826 
2827 				/*
2828 				 * EMLXS_MSGF(EMLXS_CONTEXT,
2829 				 * &emlxs_ring_watchdog_msg,
2830 				 * "%s host=%d port=%d cnt=%d,%d  RACE
2831 				 * CONDITION3 DETECTED.",
2832 				 * emlxs_ring_xlate(channelno),
2833 				 * rp->fc_cmdidx, rp->fc_port_cmdidx,
2834 				 * hba->channel_tx_count,
2835 				 * hba->io_count);
2836 				 */
2837 				mutex_enter(&EMLXS_CMD_RING_LOCK(channelno));
2838 			}
2839 		} else {
2840 			return;
2841 		}
2842 	}
2843 	/* CMD_RING_LOCK acquired */
2844 
2845 	/* Throttle check only applies to non special iocb */
2846 	if (iocbq && (!(iocbq->flag & IOCB_SPECIAL))) {
2847 		/* Check if HBA is full */
2848 		throttle = hba->io_throttle - hba->io_active;
2849 		if (throttle <= 0) {
2850 			/* Hitting adapter throttle limit */
2851 			/* Queue it for later */
2852 			if (iocbq) {
2853 				emlxs_tx_put(iocbq, 1);
2854 			}
2855 
2856 			goto busy;
2857 		}
2858 	}
2859 
2860 	/* Read adapter's get index */
2861 	pgp = (PGP *)
2862 	    &((SLIM2 *)hba->sli.sli3.slim2.virt)->mbx.us.s2.port[channelno];
2863 	offset =
2864 	    (off_t)((uint64_t)((unsigned long)&(pgp->cmdGetInx)) -
2865 	    (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
2866 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset, 4,
2867 	    DDI_DMA_SYNC_FORKERNEL);
2868 	rp->fc_port_cmdidx = BE_SWAP32(pgp->cmdGetInx);
2869 
2870 	/* Calculate the next put index */
2871 	nextIdx =
2872 	    (rp->fc_cmdidx + 1 >= rp->fc_numCiocb) ? 0 : rp->fc_cmdidx + 1;
2873 
2874 	/* Check if ring is full */
2875 	if (nextIdx == rp->fc_port_cmdidx) {
2876 		/* Try one more time */
2877 		EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset, 4,
2878 		    DDI_DMA_SYNC_FORKERNEL);
2879 		rp->fc_port_cmdidx = BE_SWAP32(pgp->cmdGetInx);
2880 
2881 		if (nextIdx == rp->fc_port_cmdidx) {
2882 			/* Queue it for later */
2883 			if (iocbq) {
2884 				emlxs_tx_put(iocbq, 1);
2885 			}
2886 
2887 			goto busy;
2888 		}
2889 	}
2890 
2891 	/*
2892 	 * We have a command ring slot available
2893 	 * Make sure we have an iocb to send
2894 	 */
2895 	if (iocbq) {
2896 		mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2897 
2898 		/* Check if the ring already has iocb's waiting */
2899 		if (cp->nodeq.q_first != NULL) {
2900 			/* Put the current iocbq on the tx queue */
2901 			emlxs_tx_put(iocbq, 0);
2902 
2903 			/*
2904 			 * Attempt to replace it with the next iocbq
2905 			 * in the tx queue
2906 			 */
2907 			iocbq = emlxs_tx_get(cp, 0);
2908 		}
2909 
2910 		mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2911 	} else {
2912 		/* Try to get the next iocb on the tx queue */
2913 		iocbq = emlxs_tx_get(cp, 1);
2914 	}
2915 
2916 sendit:
2917 	count = 0;
2918 
2919 	/* Process each iocbq */
2920 	while (iocbq) {
2921 		sbp = iocbq->sbp;
2922 
2923 #ifdef NODE_THROTTLE_SUPPORT
2924 		if (sbp && sbp->node && sbp->node->io_throttle) {
2925 			node_throttle = sbp->node->io_throttle -
2926 			    sbp->node->io_active;
2927 			if (node_throttle <= 0) {
2928 				/* Node is busy */
2929 				/* Queue this iocb and get next iocb from */
2930 				/* channel */
2931 
2932 				if (!marked_node) {
2933 					marked_node = sbp->node;
2934 				}
2935 
2936 				mutex_enter(&EMLXS_TX_CHANNEL_LOCK);
2937 				emlxs_tx_put(iocbq, 0);
2938 
2939 				if (cp->nodeq.q_first == marked_node) {
2940 					mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2941 					goto busy;
2942 				}
2943 
2944 				iocbq = emlxs_tx_get(cp, 0);
2945 				mutex_exit(&EMLXS_TX_CHANNEL_LOCK);
2946 				continue;
2947 			}
2948 		}
2949 		marked_node = 0;
2950 #endif /* NODE_THROTTLE_SUPPORT */
2951 
2952 		if (sbp && (sbp->pkt_flags & PACKET_DELAY_REQUIRED)) {
2953 			/*
2954 			 * Update adapter if needed, since we are about to
2955 			 * delay here
2956 			 */
2957 			if (count) {
2958 				count = 0;
2959 
2960 				/* Update the adapter's cmd put index */
2961 				if (hba->bus_type == SBUS_FC) {
2962 					slim2p->mbx.us.s2.host[channelno].
2963 					    cmdPutInx =
2964 					    BE_SWAP32(rp->fc_cmdidx);
2965 
2966 					/* DMA sync the index for the adapter */
2967 					offset = (off_t)
2968 					    ((uint64_t)
2969 					    ((unsigned long)&(slim2p->mbx.us.
2970 					    s2.host[channelno].cmdPutInx)) -
2971 					    (uint64_t)((unsigned long)slim2p));
2972 					EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.
2973 					    dma_handle, offset, 4,
2974 					    DDI_DMA_SYNC_FORDEV);
2975 				} else {
2976 					ioa2 = (void *)
2977 					    ((char *)hba->sli.sli3.slim_addr +
2978 					    hba->sli.sli3.hgp_ring_offset +
2979 					    ((channelno * 2) *
2980 					    sizeof (uint32_t)));
2981 					WRITE_SLIM_ADDR(hba,
2982 					    (volatile uint32_t *)ioa2,
2983 					    rp->fc_cmdidx);
2984 				}
2985 
2986 				status = (CA_R0ATT << (channelno * 4));
2987 				WRITE_CSR_REG(hba, FC_CA_REG(hba),
2988 				    (volatile uint32_t)status);
2989 
2990 			}
2991 			/* Perform delay */
2992 			if ((channelno == FC_ELS_RING) &&
2993 			    !(iocbq->flag & IOCB_FCP_CMD)) {
2994 				drv_usecwait(100000);
2995 			} else {
2996 				drv_usecwait(20000);
2997 			}
2998 		}
2999 
3000 		/*
3001 		 * At this point, we have a command ring slot available
3002 		 * and an iocb to send
3003 		 */
3004 		flag =  iocbq->flag;
3005 
3006 		/* Send the iocb */
3007 		emlxs_sli3_issue_iocb(hba, rp, iocbq);
3008 		/*
3009 		 * After this, the sbp / iocb should not be
3010 		 * accessed in the xmit path.
3011 		 */
3012 
3013 		count++;
3014 		if (iocbq && (!(flag & IOCB_SPECIAL))) {
3015 			/* Check if HBA is full */
3016 			throttle = hba->io_throttle - hba->io_active;
3017 			if (throttle <= 0) {
3018 				goto busy;
3019 			}
3020 		}
3021 
3022 		/* Calculate the next put index */
3023 		nextIdx =
3024 		    (rp->fc_cmdidx + 1 >=
3025 		    rp->fc_numCiocb) ? 0 : rp->fc_cmdidx + 1;
3026 
3027 		/* Check if ring is full */
3028 		if (nextIdx == rp->fc_port_cmdidx) {
3029 			/* Try one more time */
3030 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3031 			    offset, 4, DDI_DMA_SYNC_FORKERNEL);
3032 			rp->fc_port_cmdidx = BE_SWAP32(pgp->cmdGetInx);
3033 
3034 			if (nextIdx == rp->fc_port_cmdidx) {
3035 				goto busy;
3036 			}
3037 		}
3038 
3039 		/* Get the next iocb from the tx queue if there is one */
3040 		iocbq = emlxs_tx_get(cp, 1);
3041 	}
3042 
3043 	if (count) {
3044 		/* Update the adapter's cmd put index */
3045 		if (hba->bus_type == SBUS_FC) {
3046 			slim2p->mbx.us.s2.host[channelno].
3047 			    cmdPutInx = BE_SWAP32(rp->fc_cmdidx);
3048 
3049 			/* DMA sync the index for the adapter */
3050 			offset = (off_t)
3051 			    ((uint64_t)((unsigned long)&(slim2p->mbx.us.s2.
3052 			    host[channelno].cmdPutInx)) -
3053 			    (uint64_t)((unsigned long)slim2p));
3054 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3055 			    offset, 4, DDI_DMA_SYNC_FORDEV);
3056 		} else {
3057 			ioa2 =
3058 			    (void *)((char *)hba->sli.sli3.slim_addr +
3059 			    hba->sli.sli3.hgp_ring_offset +
3060 			    ((channelno * 2) * sizeof (uint32_t)));
3061 			WRITE_SLIM_ADDR(hba, (volatile uint32_t *)ioa2,
3062 			    rp->fc_cmdidx);
3063 		}
3064 
3065 		status = (CA_R0ATT << (channelno * 4));
3066 		WRITE_CSR_REG(hba, FC_CA_REG(hba),
3067 		    (volatile uint32_t)status);
3068 
3069 		/* Check tx queue one more time before releasing */
3070 		if ((iocbq = emlxs_tx_get(cp, 1))) {
3071 			/*
3072 			 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ring_watchdog_msg,
3073 			 * "%s host=%d port=%d   RACE CONDITION1
3074 			 * DETECTED.", emlxs_ring_xlate(channelno),
3075 			 * rp->fc_cmdidx, rp->fc_port_cmdidx);
3076 			 */
3077 			goto sendit;
3078 		}
3079 	}
3080 
3081 #ifdef FMA_SUPPORT
3082 	/* Access handle validation */
3083 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
3084 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
3085 #endif  /* FMA_SUPPORT */
3086 
3087 	mutex_exit(&EMLXS_CMD_RING_LOCK(channelno));
3088 
3089 	return;
3090 
3091 busy:
3092 
3093 	/*
3094 	 * Set ring to SET R0CE_REQ in Chip Att register.
3095 	 * Chip will tell us when an entry is freed.
3096 	 */
3097 	if (count) {
3098 		/* Update the adapter's cmd put index */
3099 		if (hba->bus_type == SBUS_FC) {
3100 			slim2p->mbx.us.s2.host[channelno].cmdPutInx =
3101 			    BE_SWAP32(rp->fc_cmdidx);
3102 
3103 			/* DMA sync the index for the adapter */
3104 			offset = (off_t)
3105 			    ((uint64_t)((unsigned long)&(slim2p->mbx.us.s2.
3106 			    host[channelno].cmdPutInx)) -
3107 			    (uint64_t)((unsigned long)slim2p));
3108 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3109 			    offset, 4, DDI_DMA_SYNC_FORDEV);
3110 		} else {
3111 			ioa2 =
3112 			    (void *)((char *)hba->sli.sli3.slim_addr +
3113 			    hba->sli.sli3.hgp_ring_offset +
3114 			    ((channelno * 2) * sizeof (uint32_t)));
3115 			WRITE_SLIM_ADDR(hba, (volatile uint32_t *)ioa2,
3116 			    rp->fc_cmdidx);
3117 		}
3118 	}
3119 
3120 	status = ((CA_R0ATT | CA_R0CE_REQ) << (channelno * 4));
3121 	WRITE_CSR_REG(hba, FC_CA_REG(hba), (volatile uint32_t)status);
3122 
3123 	if (throttle <= 0) {
3124 		HBASTATS.IocbThrottled++;
3125 	} else {
3126 		HBASTATS.IocbRingFull[channelno]++;
3127 	}
3128 
3129 #ifdef FMA_SUPPORT
3130 	/* Access handle validation */
3131 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
3132 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
3133 #endif  /* FMA_SUPPORT */
3134 
3135 	mutex_exit(&EMLXS_CMD_RING_LOCK(channelno));
3136 
3137 	return;
3138 
3139 } /* emlxs_sli3_issue_iocb_cmd() */
3140 
3141 
3142 /* MBX_NOWAIT - returns MBX_BUSY or MBX_SUCCESS or MBX_HARDWARE_ERROR */
3143 /* MBX_WAIT   - returns MBX_TIMEOUT or mailbox_status */
3144 /* MBX_SLEEP  - returns MBX_TIMEOUT or mailbox_status */
3145 /* MBX_POLL   - returns MBX_TIMEOUT or mailbox_status */
3146 
3147 static uint32_t
3148 emlxs_sli3_issue_mbox_cmd(emlxs_hba_t *hba, MAILBOXQ *mbq, int32_t flag,
3149     uint32_t tmo)
3150 {
3151 	emlxs_port_t		*port;
3152 	SLIM2			*slim2p = (SLIM2 *)hba->sli.sli3.slim2.virt;
3153 	MAILBOX			*mbox;
3154 	MAILBOX			*mb;
3155 	volatile uint32_t	word0;
3156 	volatile uint32_t	ldata;
3157 	off_t			offset;
3158 	MATCHMAP		*mbox_bp;
3159 	uint32_t		tmo_local;
3160 	MAILBOX			*swpmb;
3161 
3162 	if (!mbq->port) {
3163 		mbq->port = &PPORT;
3164 	}
3165 
3166 	port = (emlxs_port_t *)mbq->port;
3167 
3168 	mb = (MAILBOX *)mbq;
3169 	swpmb = (MAILBOX *)&word0;
3170 
3171 	mb->mbxStatus = MBX_SUCCESS;
3172 
3173 	/* Check for minimum timeouts */
3174 	switch (mb->mbxCommand) {
3175 	/* Mailbox commands that erase/write flash */
3176 	case MBX_DOWN_LOAD:
3177 	case MBX_UPDATE_CFG:
3178 	case MBX_LOAD_AREA:
3179 	case MBX_LOAD_EXP_ROM:
3180 	case MBX_WRITE_NV:
3181 	case MBX_FLASH_WR_ULA:
3182 	case MBX_DEL_LD_ENTRY:
3183 	case MBX_LOAD_SM:
3184 		if (tmo < 300) {
3185 			tmo = 300;
3186 		}
3187 		break;
3188 
3189 	default:
3190 		if (tmo < 30) {
3191 			tmo = 30;
3192 		}
3193 		break;
3194 	}
3195 
3196 	/* Convert tmo seconds to 10 millisecond tics */
3197 	tmo_local = tmo * 100;
3198 
3199 	/* Adjust wait flag */
3200 	if (flag != MBX_NOWAIT) {
3201 		/* If interrupt is enabled, use sleep, otherwise poll */
3202 		if (hba->sli.sli3.hc_copy & HC_MBINT_ENA) {
3203 			flag = MBX_SLEEP;
3204 		} else {
3205 			flag = MBX_POLL;
3206 		}
3207 	}
3208 
3209 	mutex_enter(&EMLXS_PORT_LOCK);
3210 
3211 	/* Check for hardware error */
3212 	if (hba->flag & FC_HARDWARE_ERROR) {
3213 		mb->mbxStatus = (hba->flag & FC_OVERTEMP_EVENT) ?
3214 		    MBX_OVERTEMP_ERROR : MBX_HARDWARE_ERROR;
3215 
3216 		mutex_exit(&EMLXS_PORT_LOCK);
3217 
3218 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3219 		    "Hardware error reported. %s failed. status=%x mb=%p",
3220 		    emlxs_mb_cmd_xlate(mb->mbxCommand), mb->mbxStatus, mb);
3221 
3222 		return (MBX_HARDWARE_ERROR);
3223 	}
3224 
3225 	if (hba->mbox_queue_flag) {
3226 		/* If we are not polling, then queue it for later */
3227 		if (flag == MBX_NOWAIT) {
3228 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3229 			    "Busy.      %s: mb=%p NoWait.",
3230 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
3231 
3232 			emlxs_mb_put(hba, mbq);
3233 
3234 			HBASTATS.MboxBusy++;
3235 
3236 			mutex_exit(&EMLXS_PORT_LOCK);
3237 
3238 			return (MBX_BUSY);
3239 		}
3240 
3241 		while (hba->mbox_queue_flag) {
3242 			mutex_exit(&EMLXS_PORT_LOCK);
3243 
3244 			if (tmo_local-- == 0) {
3245 				EMLXS_MSGF(EMLXS_CONTEXT,
3246 				    &emlxs_mbox_event_msg,
3247 				    "Timeout.   %s: mb=%p tmo=%d Waiting.",
3248 				    emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
3249 				    tmo);
3250 
3251 				/* Non-lethalStatus mailbox timeout */
3252 				/* Does not indicate a hardware error */
3253 				mb->mbxStatus = MBX_TIMEOUT;
3254 				return (MBX_TIMEOUT);
3255 			}
3256 
3257 			BUSYWAIT_MS(10);
3258 			mutex_enter(&EMLXS_PORT_LOCK);
3259 
3260 			/* Check for hardware error */
3261 			if (hba->flag & FC_HARDWARE_ERROR) {
3262 				mb->mbxStatus =
3263 				    (hba->flag & FC_OVERTEMP_EVENT) ?
3264 				    MBX_OVERTEMP_ERROR : MBX_HARDWARE_ERROR;
3265 
3266 				mutex_exit(&EMLXS_PORT_LOCK);
3267 
3268 				EMLXS_MSGF(EMLXS_CONTEXT,
3269 				    &emlxs_mbox_detail_msg,
3270 				    "Hardware error reported. %s failed. "
3271 				    "status=%x mb=%p",
3272 				    emlxs_mb_cmd_xlate(mb->mbxCommand),
3273 				    mb->mbxStatus, mb);
3274 
3275 				return (MBX_HARDWARE_ERROR);
3276 			}
3277 		}
3278 	}
3279 
3280 	/* Initialize mailbox area */
3281 	emlxs_mb_init(hba, mbq, flag, tmo);
3282 
3283 	switch (flag) {
3284 	case MBX_NOWAIT:
3285 
3286 		if (mb->mbxCommand != MBX_HEARTBEAT) {
3287 			if (mb->mbxCommand != MBX_DOWN_LOAD &&
3288 			    mb->mbxCommand != MBX_DUMP_MEMORY) {
3289 				EMLXS_MSGF(EMLXS_CONTEXT,
3290 				    &emlxs_mbox_detail_msg,
3291 				    "Sending.   %s: mb=%p NoWait.",
3292 				    emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
3293 			}
3294 		}
3295 
3296 		break;
3297 
3298 	case MBX_SLEEP:
3299 		if (mb->mbxCommand != MBX_DOWN_LOAD &&
3300 		    mb->mbxCommand != MBX_DUMP_MEMORY) {
3301 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3302 			    "Sending.   %s: mb=%p Sleep.",
3303 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
3304 		}
3305 
3306 		break;
3307 
3308 	case MBX_POLL:
3309 		if (mb->mbxCommand != MBX_DOWN_LOAD &&
3310 		    mb->mbxCommand != MBX_DUMP_MEMORY) {
3311 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3312 			    "Sending.   %s: mb=%p Polled.",
3313 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb);
3314 		}
3315 		break;
3316 	}
3317 
3318 	mb->mbxOwner = OWN_CHIP;
3319 
3320 	/* Clear the attention bit */
3321 	WRITE_CSR_REG(hba, FC_HA_REG(hba), HA_MBATT);
3322 
3323 	if (hba->flag & FC_SLIM2_MODE) {
3324 		/* First copy command data */
3325 		mbox = FC_SLIM2_MAILBOX(hba);
3326 		offset =
3327 		    (off_t)((uint64_t)((unsigned long)mbox)
3328 		    - (uint64_t)((unsigned long)slim2p));
3329 
3330 #ifdef MBOX_EXT_SUPPORT
3331 		if (mbq->extbuf) {
3332 			uint32_t *mbox_ext =
3333 			    (uint32_t *)((uint8_t *)mbox +
3334 			    MBOX_EXTENSION_OFFSET);
3335 			off_t offset_ext   = offset + MBOX_EXTENSION_OFFSET;
3336 
3337 			BE_SWAP32_BCOPY((uint8_t *)mbq->extbuf,
3338 			    (uint8_t *)mbox_ext, mbq->extsize);
3339 
3340 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3341 			    offset_ext, mbq->extsize,
3342 			    DDI_DMA_SYNC_FORDEV);
3343 		}
3344 #endif /* MBOX_EXT_SUPPORT */
3345 
3346 		BE_SWAP32_BCOPY((uint8_t *)mb, (uint8_t *)mbox,
3347 		    MAILBOX_CMD_BSIZE);
3348 
3349 		EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset,
3350 		    MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORDEV);
3351 	} else {	/* SLIM 1 */
3352 
3353 		mbox = FC_SLIM1_MAILBOX(hba);
3354 
3355 #ifdef MBOX_EXT_SUPPORT
3356 		if (mbq->extbuf) {
3357 			uint32_t *mbox_ext =
3358 			    (uint32_t *)((uint8_t *)mbox +
3359 			    MBOX_EXTENSION_OFFSET);
3360 			WRITE_SLIM_COPY(hba, (uint32_t *)mbq->extbuf,
3361 			    mbox_ext, (mbq->extsize / 4));
3362 		}
3363 #endif /* MBOX_EXT_SUPPORT */
3364 
3365 		/* First copy command data */
3366 		WRITE_SLIM_COPY(hba, &mb->un.varWords, &mbox->un.varWords,
3367 		    (MAILBOX_CMD_WSIZE - 1));
3368 
3369 		/* copy over last word, with mbxOwner set */
3370 		ldata = *((volatile uint32_t *)mb);
3371 		WRITE_SLIM_ADDR(hba, ((volatile uint32_t *)mbox), ldata);
3372 	}
3373 
3374 	/* Interrupt board to do it right away */
3375 	WRITE_CSR_REG(hba, FC_CA_REG(hba), CA_MBATT);
3376 
3377 	mutex_exit(&EMLXS_PORT_LOCK);
3378 
3379 #ifdef FMA_SUPPORT
3380 	/* Access handle validation */
3381 	if ((emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
3382 	    != DDI_FM_OK) ||
3383 	    (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.csr_acc_handle)
3384 	    != DDI_FM_OK)) {
3385 		EMLXS_MSGF(EMLXS_CONTEXT,
3386 		    &emlxs_invalid_access_handle_msg, NULL);
3387 		return (MBX_HARDWARE_ERROR);
3388 	}
3389 #endif  /* FMA_SUPPORT */
3390 
3391 	switch (flag) {
3392 	case MBX_NOWAIT:
3393 		return (MBX_SUCCESS);
3394 
3395 	case MBX_SLEEP:
3396 
3397 		/* Wait for completion */
3398 		/* The driver clock is timing the mailbox. */
3399 		/* emlxs_mb_fini() will be called externally. */
3400 
3401 		mutex_enter(&EMLXS_MBOX_LOCK);
3402 		while (!(mbq->flag & MBQ_COMPLETED)) {
3403 			cv_wait(&EMLXS_MBOX_CV, &EMLXS_MBOX_LOCK);
3404 		}
3405 		mutex_exit(&EMLXS_MBOX_LOCK);
3406 
3407 		if (mb->mbxStatus == MBX_TIMEOUT) {
3408 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
3409 			    "Timeout.   %s: mb=%p tmo=%d. Sleep.",
3410 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo);
3411 		} else {
3412 			if (mb->mbxCommand != MBX_DOWN_LOAD &&
3413 			    mb->mbxCommand != MBX_DUMP_MEMORY) {
3414 				EMLXS_MSGF(EMLXS_CONTEXT,
3415 				    &emlxs_mbox_detail_msg,
3416 				    "Completed. %s: mb=%p status=%x Sleep.",
3417 				    emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
3418 				    mb->mbxStatus);
3419 			}
3420 		}
3421 
3422 		break;
3423 
3424 	case MBX_POLL:
3425 
3426 		/* Convert tmo seconds to 500 usec tics */
3427 		tmo_local = tmo * 2000;
3428 
3429 		/* Get first word of mailbox */
3430 		if (hba->flag & FC_SLIM2_MODE) {
3431 			mbox = FC_SLIM2_MAILBOX(hba);
3432 			offset = (off_t)((uint64_t)((unsigned long)mbox) -
3433 			    (uint64_t)((unsigned long)slim2p));
3434 
3435 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3436 			    offset, sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
3437 			word0 = *((volatile uint32_t *)mbox);
3438 			word0 = BE_SWAP32(word0);
3439 		} else {
3440 			mbox = FC_SLIM1_MAILBOX(hba);
3441 			word0 =
3442 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mbox));
3443 		}
3444 
3445 		/* Wait for command to complete */
3446 		while ((swpmb->mbxOwner == OWN_CHIP) &&
3447 		    !(mbq->flag & MBQ_COMPLETED)) {
3448 			if (!hba->timer_id && (tmo_local-- == 0)) {
3449 				/* self time */
3450 				EMLXS_MSGF(EMLXS_CONTEXT,
3451 				    &emlxs_mbox_timeout_msg,
3452 				    "%s: mb=%p tmo=%d Polled.",
3453 				    emlxs_mb_cmd_xlate(mb->mbxCommand),
3454 				    mb, tmo);
3455 
3456 				hba->flag |= FC_MBOX_TIMEOUT;
3457 				EMLXS_STATE_CHANGE(hba, FC_ERROR);
3458 				emlxs_mb_fini(hba, NULL, MBX_TIMEOUT);
3459 
3460 				break;
3461 			}
3462 
3463 			BUSYWAIT_US(500);
3464 
3465 			/* Get first word of mailbox */
3466 			if (hba->flag & FC_SLIM2_MODE) {
3467 				EMLXS_MPDATA_SYNC(
3468 				    hba->sli.sli3.slim2.dma_handle, offset,
3469 				    sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
3470 				word0 = *((volatile uint32_t *)mbox);
3471 				word0 = BE_SWAP32(word0);
3472 			} else {
3473 				word0 =
3474 				    READ_SLIM_ADDR(hba,
3475 				    ((volatile uint32_t *)mbox));
3476 			}
3477 
3478 		}	/* while */
3479 
3480 		if (mb->mbxStatus == MBX_TIMEOUT) {
3481 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_event_msg,
3482 			    "Timeout.   %s: mb=%p tmo=%d. Polled.",
3483 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb, tmo);
3484 
3485 			break;
3486 		}
3487 
3488 		/* Check for config port command */
3489 		if ((swpmb->mbxCommand == MBX_CONFIG_PORT) &&
3490 		    (swpmb->mbxStatus == MBX_SUCCESS)) {
3491 			/* Setup host mbox for cmpl */
3492 			mbox = FC_SLIM2_MAILBOX(hba);
3493 			offset = (off_t)((uint64_t)((unsigned long)mbox)
3494 			    - (uint64_t)((unsigned long)slim2p));
3495 
3496 			hba->flag |= FC_SLIM2_MODE;
3497 		}
3498 
3499 		/* copy results back to user */
3500 		if (hba->flag & FC_SLIM2_MODE) {
3501 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
3502 			    offset, MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL);
3503 
3504 			BE_SWAP32_BCOPY((uint8_t *)mbox, (uint8_t *)mb,
3505 			    MAILBOX_CMD_BSIZE);
3506 		} else {
3507 			READ_SLIM_COPY(hba, (uint32_t *)mb,
3508 			    (uint32_t *)mbox, MAILBOX_CMD_WSIZE);
3509 		}
3510 
3511 #ifdef MBOX_EXT_SUPPORT
3512 		if (mbq->extbuf) {
3513 			uint32_t *mbox_ext =
3514 			    (uint32_t *)((uint8_t *)mbox +
3515 			    MBOX_EXTENSION_OFFSET);
3516 			off_t offset_ext   = offset + MBOX_EXTENSION_OFFSET;
3517 
3518 			if (hba->flag & FC_SLIM2_MODE) {
3519 				EMLXS_MPDATA_SYNC(
3520 				    hba->sli.sli3.slim2.dma_handle, offset_ext,
3521 				    mbq->extsize, DDI_DMA_SYNC_FORKERNEL);
3522 
3523 				BE_SWAP32_BCOPY((uint8_t *)mbox_ext,
3524 				    (uint8_t *)mbq->extbuf, mbq->extsize);
3525 			} else {
3526 				READ_SLIM_COPY(hba,
3527 				    (uint32_t *)mbq->extbuf, mbox_ext,
3528 				    (mbq->extsize / 4));
3529 			}
3530 		}
3531 #endif /* MBOX_EXT_SUPPORT */
3532 
3533 		/* Sync the memory buffer */
3534 		if (mbq->bp) {
3535 			mbox_bp = (MATCHMAP *)mbq->bp;
3536 			EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0,
3537 			    mbox_bp->size, DDI_DMA_SYNC_FORKERNEL);
3538 		}
3539 
3540 		if (mb->mbxCommand != MBX_DOWN_LOAD &&
3541 		    mb->mbxCommand != MBX_DUMP_MEMORY) {
3542 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
3543 			    "Completed. %s: mb=%p status=%x Polled.",
3544 			    emlxs_mb_cmd_xlate(mb->mbxCommand), mb,
3545 			    mb->mbxStatus);
3546 		}
3547 
3548 		/* Process the result */
3549 		if (!(mbq->flag & MBQ_PASSTHRU)) {
3550 			if (mbq->mbox_cmpl) {
3551 				(void) (mbq->mbox_cmpl)(hba, mbq);
3552 			}
3553 		}
3554 
3555 		/* Clear the attention bit */
3556 		WRITE_CSR_REG(hba, FC_HA_REG(hba), HA_MBATT);
3557 
3558 		/* Clean up the mailbox area */
3559 		emlxs_mb_fini(hba, NULL, mb->mbxStatus);
3560 
3561 		break;
3562 
3563 	}	/* switch (flag) */
3564 
3565 	return (mb->mbxStatus);
3566 
3567 } /* emlxs_sli3_issue_mbox_cmd() */
3568 
3569 
3570 #ifdef SFCT_SUPPORT
3571 /*ARGSUSED*/
3572 static uint32_t
3573 emlxs_sli3_prep_fct_iocb(emlxs_port_t *port, emlxs_buf_t *cmd_sbp,
3574 	int channel)
3575 {
3576 	emlxs_hba_t *hba = HBA;
3577 	emlxs_config_t *cfg = &CFG;
3578 	fct_cmd_t *fct_cmd;
3579 	stmf_data_buf_t *dbuf;
3580 	scsi_task_t *fct_task;
3581 	fc_packet_t *pkt;
3582 	uint32_t did;
3583 	IOCBQ *iocbq;
3584 	IOCB *iocb;
3585 	uint32_t timeout;
3586 	uint32_t iotag;
3587 	emlxs_node_t *ndlp;
3588 	CHANNEL *cp;
3589 	ddi_dma_cookie_t *cp_cmd;
3590 
3591 	pkt = PRIV2PKT(cmd_sbp);
3592 
3593 	cp = (CHANNEL *)cmd_sbp->channel;
3594 
3595 	iocbq = &cmd_sbp->iocbq;
3596 	iocb = &iocbq->iocb;
3597 
3598 
3599 	/* Get the iotag by registering the packet */
3600 	iotag = emlxs_register_pkt(cp, cmd_sbp);
3601 
3602 	if (!iotag) {
3603 		/* No more command slots available, retry later */
3604 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3605 		    "Adapter Busy. Unable to allocate iotag. did=0x%x",
3606 		    cmd_sbp->did);
3607 
3608 		return (IOERR_NO_RESOURCES);
3609 	}
3610 
3611 
3612 	/* Point of no return */
3613 
3614 	if (iocb->ULPCOMMAND == CMD_ABORT_XRI_CX) {
3615 
3616 		ndlp = cmd_sbp->node;
3617 		cp->ulpSendCmd++;
3618 
3619 		/* Initalize iocbq */
3620 		iocbq->port = (void *)port;
3621 		iocbq->node = (void *)ndlp;
3622 		iocbq->channel = (void *)cp;
3623 
3624 		/*
3625 		 * Don't give the abort priority, we want the IOCB
3626 		 * we are aborting to be processed first.
3627 		 */
3628 		iocbq->flag |= IOCB_SPECIAL;
3629 
3630 		iocb->ULPCONTEXT = pkt->pkt_cmd_fhdr.rx_id;
3631 		iocb->ULPIOTAG = (uint16_t)iotag;
3632 		iocb->ULPLE = 1;
3633 		iocb->ULPCLASS = cmd_sbp->class;
3634 		iocb->ULPOWNER = OWN_CHIP;
3635 
3636 		if (hba->state >= FC_LINK_UP) {
3637 			/* Create the abort IOCB */
3638 			iocb->un.acxri.abortType = ABORT_TYPE_ABTS;
3639 			iocb->ULPCOMMAND = CMD_ABORT_XRI_CX;
3640 
3641 		} else {
3642 			/* Create the close IOCB */
3643 			iocb->ULPCOMMAND = CMD_CLOSE_XRI_CX;
3644 
3645 		}
3646 
3647 		iocb->ULPRSVDBYTE =
3648 		    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
3649 		/* Set the pkt timer */
3650 		cmd_sbp->ticks = hba->timer_tics + pkt->pkt_timeout +
3651 		    ((pkt->pkt_timeout > 0xff) ? 0 : 10);
3652 
3653 		return (IOERR_SUCCESS);
3654 
3655 	} else if (iocb->ULPCOMMAND == CMD_FCP_TRSP64_CX) {
3656 
3657 		ndlp = cmd_sbp->node;
3658 		cp->ulpSendCmd++;
3659 
3660 		/* Initalize iocbq */
3661 		iocbq->port = (void *)port;
3662 		iocbq->node = (void *)ndlp;
3663 		iocbq->channel = (void *)cp;
3664 
3665 #if (EMLXS_MODREV >= EMLXS_MODREV3)
3666 		cp_cmd = pkt->pkt_cmd_cookie;
3667 #else
3668 		cp_cmd  = &pkt->pkt_cmd_cookie;
3669 #endif	/* >= EMLXS_MODREV3 */
3670 
3671 		iocb->un.fcpt64.bdl.addrHigh = PADDR_HI(cp_cmd->dmac_laddress);
3672 		iocb->un.fcpt64.bdl.addrLow = PADDR_LO(cp_cmd->dmac_laddress);
3673 		iocb->un.fcpt64.bdl.bdeSize = pkt->pkt_cmdlen;
3674 		iocb->un.fcpt64.bdl.bdeFlags = 0;
3675 
3676 		if (hba->sli_mode < 3) {
3677 			iocb->ULPBDECOUNT = 1;
3678 			iocb->ULPLE = 1;
3679 		} else {	/* SLI3 */
3680 
3681 			iocb->ULPBDECOUNT = 0;
3682 			iocb->ULPLE = 0;
3683 			iocb->unsli3.ext_iocb.ebde_count = 0;
3684 		}
3685 
3686 		/* Initalize iocb */
3687 		iocb->ULPCONTEXT = (uint16_t)pkt->pkt_cmd_fhdr.rx_id;
3688 		iocb->ULPIOTAG = (uint16_t)iotag;
3689 		iocb->ULPRSVDBYTE =
3690 		    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
3691 		iocb->ULPOWNER = OWN_CHIP;
3692 		iocb->ULPCLASS = cmd_sbp->class;
3693 		iocb->ULPCOMMAND = CMD_FCP_TRSP64_CX;
3694 
3695 		/* Set the pkt timer */
3696 		cmd_sbp->ticks = hba->timer_tics + pkt->pkt_timeout +
3697 		    ((pkt->pkt_timeout > 0xff) ? 0 : 10);
3698 
3699 		if (pkt->pkt_cmdlen) {
3700 			EMLXS_MPDATA_SYNC(pkt->pkt_cmd_dma, 0, pkt->pkt_cmdlen,
3701 			    DDI_DMA_SYNC_FORDEV);
3702 		}
3703 
3704 		return (IOERR_SUCCESS);
3705 	}
3706 
3707 	dbuf = cmd_sbp->fct_buf;
3708 	fct_cmd = cmd_sbp->fct_cmd;
3709 	fct_task = (scsi_task_t *)fct_cmd->cmd_specific;
3710 	ndlp = *(emlxs_node_t **)fct_cmd->cmd_rp->rp_fca_private;
3711 	did = fct_cmd->cmd_rportid;
3712 
3713 	iocbq->channel = (void *)cmd_sbp->channel;
3714 
3715 	if (emlxs_fct_bde_setup(port, cmd_sbp)) {
3716 		/* Unregister the packet */
3717 		(void) emlxs_unregister_pkt(cmd_sbp->channel, iotag, 0);
3718 
3719 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3720 		    "Adapter Busy. Unable to setup buffer list. did=%x", did);
3721 
3722 		return (IOERR_INTERNAL_ERROR);
3723 	}
3724 
3725 	if (cfg[CFG_TIMEOUT_ENABLE].current) {
3726 		timeout =
3727 		    ((2 * hba->fc_ratov) < 60) ? 60 : (2 * hba->fc_ratov);
3728 	} else {
3729 		timeout = 0x80000000;
3730 	}
3731 
3732 	cmd_sbp->ticks =
3733 	    hba->timer_tics + timeout + ((timeout > 0xff) ? 0 : 10);
3734 
3735 	/* Initalize iocbq */
3736 	iocbq->port = (void *)port;
3737 	iocbq->node = (void *)ndlp;
3738 
3739 	/* Initalize iocb */
3740 	iocb->ULPCONTEXT = (uint16_t)fct_cmd->cmd_rxid;
3741 	iocb->ULPIOTAG = (uint16_t)iotag;
3742 	iocb->ULPRSVDBYTE = ((timeout > 0xff) ? 0 : timeout);
3743 	iocb->ULPOWNER = OWN_CHIP;
3744 	iocb->ULPCLASS = cmd_sbp->class;
3745 
3746 	iocb->ULPPU = 1;	/* Wd4 is relative offset */
3747 	iocb->un.fcpt64.fcpt_Offset = dbuf->db_relative_offset;
3748 
3749 	if (fct_task->task_flags & TF_WRITE_DATA) {
3750 		iocb->ULPCOMMAND = CMD_FCP_TRECEIVE64_CX;
3751 	} else {	/* TF_READ_DATA */
3752 
3753 		iocb->ULPCOMMAND = CMD_FCP_TSEND64_CX;
3754 
3755 		if ((hba->sli_mode == EMLXS_HBA_SLI3_MODE) &&
3756 		    (dbuf->db_data_size >=
3757 		    fct_task->task_expected_xfer_length)) {
3758 			iocb->ULPCT = 0x1;
3759 			/* enable auto-rsp AP feature */
3760 		}
3761 	}
3762 
3763 	return (IOERR_SUCCESS);
3764 
3765 } /* emlxs_sli3_prep_fct_iocb() */
3766 #endif /* SFCT_SUPPORT */
3767 
3768 /* ARGSUSED */
3769 static uint32_t
3770 emlxs_sli3_prep_fcp_iocb(emlxs_port_t *port, emlxs_buf_t *sbp, int channel)
3771 {
3772 	emlxs_hba_t *hba = HBA;
3773 	fc_packet_t *pkt;
3774 	CHANNEL *cp;
3775 	IOCBQ *iocbq;
3776 	IOCB *iocb;
3777 	NODELIST *ndlp;
3778 	uint16_t iotag;
3779 	uint32_t did;
3780 
3781 	pkt = PRIV2PKT(sbp);
3782 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
3783 	cp = &hba->chan[FC_FCP_RING];
3784 
3785 	iocbq = &sbp->iocbq;
3786 	iocb = &iocbq->iocb;
3787 
3788 	/* Find target node object */
3789 	ndlp = (NODELIST *)iocbq->node;
3790 
3791 	/* Get the iotag by registering the packet */
3792 	iotag = emlxs_register_pkt(cp, sbp);
3793 
3794 	if (!iotag) {
3795 		/*
3796 		 * No more command slots available, retry later
3797 		 */
3798 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3799 		    "Adapter Busy. Unable to allocate iotag: did=0x%x", did);
3800 
3801 		return (FC_TRAN_BUSY);
3802 	}
3803 
3804 	/* Initalize iocbq */
3805 	iocbq->port = (void *) port;
3806 	iocbq->channel = (void *) cp;
3807 
3808 	/* Indicate this is a FCP cmd */
3809 	iocbq->flag |= IOCB_FCP_CMD;
3810 
3811 	if (emlxs_bde_setup(port, sbp)) {
3812 		/* Unregister the packet */
3813 		(void) emlxs_unregister_pkt(cp, iotag, 0);
3814 
3815 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3816 		    "Adapter Busy. Unable to setup buffer list. did=%x", did);
3817 
3818 		return (FC_TRAN_BUSY);
3819 	}
3820 	/* Point of no return */
3821 
3822 	/* Initalize iocb */
3823 	iocb->ULPCONTEXT = ndlp->nlp_Rpi;
3824 	iocb->ULPIOTAG = iotag;
3825 	iocb->ULPRSVDBYTE =
3826 	    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
3827 	iocb->ULPOWNER = OWN_CHIP;
3828 
3829 	switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) {
3830 	case FC_TRAN_CLASS1:
3831 		iocb->ULPCLASS = CLASS1;
3832 		break;
3833 	case FC_TRAN_CLASS2:
3834 		iocb->ULPCLASS = CLASS2;
3835 		/* iocb->ULPCLASS = CLASS3; */
3836 		break;
3837 	case FC_TRAN_CLASS3:
3838 	default:
3839 		iocb->ULPCLASS = CLASS3;
3840 		break;
3841 	}
3842 
3843 	/* if device is FCP-2 device, set the following bit */
3844 	/* that says to run the FC-TAPE protocol. */
3845 	if (ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) {
3846 		iocb->ULPFCP2RCVY = 1;
3847 	}
3848 
3849 	if (pkt->pkt_datalen == 0) {
3850 		iocb->ULPCOMMAND = CMD_FCP_ICMND64_CR;
3851 	} else if (pkt->pkt_tran_type == FC_PKT_FCP_READ) {
3852 		iocb->ULPCOMMAND = CMD_FCP_IREAD64_CR;
3853 		iocb->ULPPU = PARM_XFER_CHECK;
3854 		iocb->un.fcpi64.fcpi_parm = pkt->pkt_datalen;
3855 	} else {
3856 		iocb->ULPCOMMAND = CMD_FCP_IWRITE64_CR;
3857 	}
3858 
3859 	return (FC_SUCCESS);
3860 
3861 } /* emlxs_sli3_prep_fcp_iocb() */
3862 
3863 
3864 static uint32_t
3865 emlxs_sli3_prep_ip_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
3866 {
3867 	emlxs_hba_t *hba = HBA;
3868 	fc_packet_t *pkt;
3869 	IOCBQ *iocbq;
3870 	IOCB *iocb;
3871 	CHANNEL *cp;
3872 	NODELIST *ndlp;
3873 	uint16_t iotag;
3874 	uint32_t did;
3875 
3876 	pkt = PRIV2PKT(sbp);
3877 	cp = &hba->chan[FC_IP_RING];
3878 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
3879 
3880 	iocbq = &sbp->iocbq;
3881 	iocb = &iocbq->iocb;
3882 	ndlp = (NODELIST *)iocbq->node;
3883 
3884 	/* Get the iotag by registering the packet */
3885 	iotag = emlxs_register_pkt(cp, sbp);
3886 
3887 	if (!iotag) {
3888 		/*
3889 		 * No more command slots available, retry later
3890 		 */
3891 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3892 		    "Adapter Busy. Unable to allocate iotag: did=0x%x", did);
3893 
3894 		return (FC_TRAN_BUSY);
3895 	}
3896 
3897 	/* Initalize iocbq */
3898 	iocbq->port = (void *) port;
3899 	iocbq->channel = (void *) cp;
3900 
3901 	if (emlxs_bde_setup(port, sbp)) {
3902 		/* Unregister the packet */
3903 		(void) emlxs_unregister_pkt(cp, iotag, 0);
3904 
3905 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3906 		    "Adapter Busy. Unable to setup buffer list. did=%x", did);
3907 
3908 		return (FC_TRAN_BUSY);
3909 	}
3910 	/* Point of no return */
3911 
3912 	/* Initalize iocb */
3913 	iocb->un.xseq64.w5.hcsw.Fctl = 0;
3914 
3915 	if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_FIRST_SEQ) {
3916 		iocb->un.xseq64.w5.hcsw.Fctl |= FSEQ;
3917 	}
3918 	if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_SEQ_INITIATIVE) {
3919 		iocb->un.xseq64.w5.hcsw.Fctl |= SI;
3920 	}
3921 
3922 	/* network headers */
3923 	iocb->un.xseq64.w5.hcsw.Dfctl = pkt->pkt_cmd_fhdr.df_ctl;
3924 	iocb->un.xseq64.w5.hcsw.Rctl = pkt->pkt_cmd_fhdr.r_ctl;
3925 	iocb->un.xseq64.w5.hcsw.Type = pkt->pkt_cmd_fhdr.type;
3926 
3927 	iocb->ULPIOTAG = iotag;
3928 	iocb->ULPRSVDBYTE =
3929 	    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
3930 	iocb->ULPOWNER = OWN_CHIP;
3931 
3932 	if (pkt->pkt_tran_type == FC_PKT_BROADCAST) {
3933 		HBASTATS.IpBcastIssued++;
3934 
3935 		iocb->ULPCOMMAND = CMD_XMIT_BCAST64_CN;
3936 		iocb->ULPCONTEXT = 0;
3937 
3938 		if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
3939 			if (hba->topology != TOPOLOGY_LOOP) {
3940 				iocb->ULPCT = 0x1;
3941 			}
3942 			iocb->ULPCONTEXT = port->vpi;
3943 		}
3944 	} else {
3945 		HBASTATS.IpSeqIssued++;
3946 
3947 		iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CX;
3948 		iocb->ULPCONTEXT = ndlp->nlp_Xri;
3949 	}
3950 
3951 	switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) {
3952 	case FC_TRAN_CLASS1:
3953 		iocb->ULPCLASS = CLASS1;
3954 		break;
3955 	case FC_TRAN_CLASS2:
3956 		iocb->ULPCLASS = CLASS2;
3957 		break;
3958 	case FC_TRAN_CLASS3:
3959 	default:
3960 		iocb->ULPCLASS = CLASS3;
3961 		break;
3962 	}
3963 
3964 	return (FC_SUCCESS);
3965 
3966 } /* emlxs_sli3_prep_ip_iocb() */
3967 
3968 
3969 static uint32_t
3970 emlxs_sli3_prep_els_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
3971 {
3972 	emlxs_hba_t *hba = HBA;
3973 	fc_packet_t *pkt;
3974 	IOCBQ *iocbq;
3975 	IOCB *iocb;
3976 	CHANNEL *cp;
3977 	uint16_t iotag;
3978 	uint32_t did;
3979 	uint32_t cmd;
3980 
3981 	pkt = PRIV2PKT(sbp);
3982 	cp = &hba->chan[FC_ELS_RING];
3983 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
3984 
3985 	iocbq = &sbp->iocbq;
3986 	iocb = &iocbq->iocb;
3987 
3988 
3989 	/* Get the iotag by registering the packet */
3990 	iotag = emlxs_register_pkt(cp, sbp);
3991 
3992 	if (!iotag) {
3993 		/*
3994 		 * No more command slots available, retry later
3995 		 */
3996 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
3997 		    "Adapter Busy. Unable to allocate iotag. did=0x%x", did);
3998 
3999 		return (FC_TRAN_BUSY);
4000 	}
4001 	/* Initalize iocbq */
4002 	iocbq->port = (void *) port;
4003 	iocbq->channel = (void *) cp;
4004 
4005 	if (emlxs_bde_setup(port, sbp)) {
4006 		/* Unregister the packet */
4007 		(void) emlxs_unregister_pkt(cp, iotag, 0);
4008 
4009 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
4010 		    "Adapter Busy. Unable to setup buffer list. did=%x", did);
4011 
4012 		return (FC_TRAN_BUSY);
4013 	}
4014 	/* Point of no return */
4015 
4016 	/* Initalize iocb */
4017 	if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
4018 		/* ELS Response */
4019 		iocb->ULPCONTEXT = (volatile uint16_t) pkt->pkt_cmd_fhdr.rx_id;
4020 		iocb->ULPCOMMAND = CMD_XMIT_ELS_RSP64_CX;
4021 	} else {
4022 		/* ELS Request */
4023 		iocb->un.elsreq64.remoteID = (did == BCAST_DID) ? 0 : did;
4024 		iocb->ULPCONTEXT =
4025 		    (did == BCAST_DID) ? pkt->pkt_cmd_fhdr.seq_id : 0;
4026 		iocb->ULPCOMMAND = CMD_ELS_REQUEST64_CR;
4027 
4028 		if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
4029 			if (hba->topology != TOPOLOGY_LOOP) {
4030 				cmd = *((uint32_t *)pkt->pkt_cmd);
4031 				cmd &= ELS_CMD_MASK;
4032 
4033 				if ((cmd == ELS_CMD_FLOGI) ||
4034 				    (cmd == ELS_CMD_FDISC)) {
4035 					iocb->ULPCT = 0x2;
4036 				} else {
4037 					iocb->ULPCT = 0x1;
4038 				}
4039 			}
4040 			iocb->ULPCONTEXT = port->vpi;
4041 		}
4042 	}
4043 	iocb->ULPIOTAG = iotag;
4044 	iocb->ULPRSVDBYTE =
4045 	    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
4046 	iocb->ULPOWNER = OWN_CHIP;
4047 
4048 	switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) {
4049 	case FC_TRAN_CLASS1:
4050 		iocb->ULPCLASS = CLASS1;
4051 		break;
4052 	case FC_TRAN_CLASS2:
4053 		iocb->ULPCLASS = CLASS2;
4054 		break;
4055 	case FC_TRAN_CLASS3:
4056 	default:
4057 		iocb->ULPCLASS = CLASS3;
4058 		break;
4059 	}
4060 	sbp->class = iocb->ULPCLASS;
4061 
4062 	return (FC_SUCCESS);
4063 
4064 } /* emlxs_sli3_prep_els_iocb() */
4065 
4066 
4067 static uint32_t
4068 emlxs_sli3_prep_ct_iocb(emlxs_port_t *port, emlxs_buf_t *sbp)
4069 {
4070 	emlxs_hba_t *hba = HBA;
4071 	fc_packet_t *pkt;
4072 	IOCBQ *iocbq;
4073 	IOCB *iocb;
4074 	CHANNEL *cp;
4075 	NODELIST *ndlp;
4076 	uint16_t iotag;
4077 	uint32_t did;
4078 
4079 	pkt = PRIV2PKT(sbp);
4080 	did = LE_SWAP24_LO(pkt->pkt_cmd_fhdr.d_id);
4081 	cp = &hba->chan[FC_CT_RING];
4082 
4083 	iocbq = &sbp->iocbq;
4084 	iocb = &iocbq->iocb;
4085 	ndlp = (NODELIST *)iocbq->node;
4086 
4087 	/* Get the iotag by registering the packet */
4088 	iotag = emlxs_register_pkt(cp, sbp);
4089 
4090 	if (!iotag) {
4091 		/*
4092 		 * No more command slots available, retry later
4093 		 */
4094 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
4095 		    "Adapter Busy. Unable to allocate iotag. did=0x%x", did);
4096 
4097 		return (FC_TRAN_BUSY);
4098 	}
4099 
4100 	if (emlxs_bde_setup(port, sbp)) {
4101 		/* Unregister the packet */
4102 		(void) emlxs_unregister_pkt(cp, iotag, 0);
4103 
4104 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_pkt_trans_msg,
4105 		    "Adapter Busy. Unable to setup buffer list. did=%x", did);
4106 
4107 		return (FC_TRAN_BUSY);
4108 	}
4109 
4110 	/* Point of no return */
4111 
4112 	/* Initalize iocbq */
4113 	iocbq->port = (void *) port;
4114 	iocbq->channel = (void *) cp;
4115 
4116 	/* Fill in rest of iocb */
4117 	iocb->un.genreq64.w5.hcsw.Fctl = LA;
4118 
4119 	if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_LAST_SEQ) {
4120 		iocb->un.genreq64.w5.hcsw.Fctl |= LSEQ;
4121 	}
4122 	if (pkt->pkt_cmd_fhdr.f_ctl & F_CTL_SEQ_INITIATIVE) {
4123 		iocb->un.genreq64.w5.hcsw.Fctl |= SI;
4124 	}
4125 
4126 	/* Initalize iocb */
4127 	if (pkt->pkt_tran_type == FC_PKT_OUTBOUND) {
4128 		/* CT Response */
4129 		iocb->ULPCOMMAND = CMD_XMIT_SEQUENCE64_CX;
4130 		iocb->un.genreq64.w5.hcsw.Dfctl  = pkt->pkt_cmd_fhdr.df_ctl;
4131 		iocb->ULPCONTEXT  = pkt->pkt_cmd_fhdr.rx_id;
4132 	} else {
4133 		/* CT Request */
4134 		iocb->ULPCOMMAND  = CMD_GEN_REQUEST64_CR;
4135 		iocb->un.genreq64.w5.hcsw.Dfctl = 0;
4136 		iocb->ULPCONTEXT  = ndlp->nlp_Rpi;
4137 	}
4138 
4139 	iocb->un.genreq64.w5.hcsw.Rctl  = pkt->pkt_cmd_fhdr.r_ctl;
4140 	iocb->un.genreq64.w5.hcsw.Type  = pkt->pkt_cmd_fhdr.type;
4141 
4142 	iocb->ULPIOTAG    = iotag;
4143 	iocb->ULPRSVDBYTE =
4144 	    ((pkt->pkt_timeout > 0xff) ? 0 : pkt->pkt_timeout);
4145 	iocb->ULPOWNER    = OWN_CHIP;
4146 
4147 	switch (FC_TRAN_CLASS(pkt->pkt_tran_flags)) {
4148 	case FC_TRAN_CLASS1:
4149 		iocb->ULPCLASS = CLASS1;
4150 		break;
4151 	case FC_TRAN_CLASS2:
4152 		iocb->ULPCLASS = CLASS2;
4153 		break;
4154 	case FC_TRAN_CLASS3:
4155 	default:
4156 		iocb->ULPCLASS = CLASS3;
4157 		break;
4158 	}
4159 
4160 	return (FC_SUCCESS);
4161 
4162 } /* emlxs_sli3_prep_ct_iocb() */
4163 
4164 
4165 #ifdef SFCT_SUPPORT
4166 static uint32_t
4167 emlxs_fct_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
4168 {
4169 	emlxs_hba_t *hba = HBA;
4170 	uint32_t rval;
4171 
4172 	if (sbp->fct_buf->db_sglist_length != 1) {
4173 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_fct_error_msg,
4174 		    "fct_bde_setup: Only 1 sglist entry supported: %d",
4175 		    sbp->fct_buf->db_sglist_length);
4176 		return (1);
4177 	}
4178 
4179 	if (hba->sli_mode < EMLXS_HBA_SLI3_MODE) {
4180 		rval = emlxs_sli2_fct_bde_setup(port, sbp);
4181 	} else {
4182 		rval = emlxs_sli3_fct_bde_setup(port, sbp);
4183 	}
4184 
4185 	return (rval);
4186 
4187 } /* emlxs_fct_bde_setup() */
4188 #endif /* SFCT_SUPPORT */
4189 
4190 
4191 static uint32_t
4192 emlxs_bde_setup(emlxs_port_t *port, emlxs_buf_t *sbp)
4193 {
4194 	uint32_t	rval;
4195 	emlxs_hba_t	*hba = HBA;
4196 
4197 	if (hba->sli_mode < EMLXS_HBA_SLI3_MODE) {
4198 		rval = emlxs_sli2_bde_setup(port, sbp);
4199 	} else {
4200 		rval = emlxs_sli3_bde_setup(port, sbp);
4201 	}
4202 
4203 	return (rval);
4204 
4205 } /* emlxs_bde_setup() */
4206 
4207 
4208 static void
4209 emlxs_sli3_poll_intr(emlxs_hba_t *hba)
4210 {
4211 	uint32_t ha_copy;
4212 
4213 	/* Check attention bits once and process if required */
4214 
4215 	ha_copy = emlxs_check_attention(hba);
4216 
4217 	if (ha_copy == 0) {
4218 		return;
4219 	}
4220 
4221 	mutex_enter(&EMLXS_PORT_LOCK);
4222 	ha_copy = emlxs_get_attention(hba, -1);
4223 	mutex_exit(&EMLXS_PORT_LOCK);
4224 
4225 	emlxs_proc_attention(hba, ha_copy);
4226 
4227 	return;
4228 
4229 } /* emlxs_sli3_poll_intr() */
4230 
4231 
4232 #ifdef MSI_SUPPORT
4233 static uint32_t
4234 emlxs_sli3_msi_intr(char *arg1, char *arg2)
4235 {
4236 	emlxs_hba_t *hba = (emlxs_hba_t *)arg1;
4237 #ifdef FMA_SUPPORT
4238 	emlxs_port_t *port = &PPORT;
4239 #endif  /* FMA_SUPPORT */
4240 	uint16_t msgid;
4241 	uint32_t hc_copy;
4242 	uint32_t ha_copy;
4243 	uint32_t restore = 0;
4244 
4245 	/*
4246 	 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
4247 	 * "sli3_msi_intr: arg1=%p arg2=%p", arg1, arg2);
4248 	 */
4249 
4250 	/* Check for legacy interrupt handling */
4251 	if (hba->intr_type == DDI_INTR_TYPE_FIXED) {
4252 		mutex_enter(&EMLXS_PORT_LOCK);
4253 
4254 		if (hba->flag & FC_OFFLINE_MODE) {
4255 			mutex_exit(&EMLXS_PORT_LOCK);
4256 
4257 			if (hba->bus_type == SBUS_FC) {
4258 				return (DDI_INTR_CLAIMED);
4259 			} else {
4260 				return (DDI_INTR_UNCLAIMED);
4261 			}
4262 		}
4263 
4264 		/* Get host attention bits */
4265 		ha_copy = emlxs_get_attention(hba, -1);
4266 
4267 		if (ha_copy == 0) {
4268 			if (hba->intr_unclaimed) {
4269 				mutex_exit(&EMLXS_PORT_LOCK);
4270 				return (DDI_INTR_UNCLAIMED);
4271 			}
4272 
4273 			hba->intr_unclaimed = 1;
4274 		} else {
4275 			hba->intr_unclaimed = 0;
4276 		}
4277 
4278 		mutex_exit(&EMLXS_PORT_LOCK);
4279 
4280 		/* Process the interrupt */
4281 		emlxs_proc_attention(hba, ha_copy);
4282 
4283 		return (DDI_INTR_CLAIMED);
4284 	}
4285 
4286 	/* DDI_INTR_TYPE_MSI  */
4287 	/* DDI_INTR_TYPE_MSIX */
4288 
4289 	/* Get MSI message id */
4290 	msgid = (uint16_t)((unsigned long)arg2);
4291 
4292 	/* Validate the message id */
4293 	if (msgid >= hba->intr_count) {
4294 		msgid = 0;
4295 	}
4296 
4297 	mutex_enter(&EMLXS_INTR_LOCK(msgid));
4298 
4299 	mutex_enter(&EMLXS_PORT_LOCK);
4300 
4301 	/* Check if adapter is offline */
4302 	if (hba->flag & FC_OFFLINE_MODE) {
4303 		mutex_exit(&EMLXS_PORT_LOCK);
4304 		mutex_exit(&EMLXS_INTR_LOCK(msgid));
4305 
4306 		/* Always claim an MSI interrupt */
4307 		return (DDI_INTR_CLAIMED);
4308 	}
4309 
4310 	/* Disable interrupts associated with this msgid */
4311 	if (msgid == 0 && (hba->model_info.chip == EMLXS_ZEPHYR_CHIP)) {
4312 		hc_copy = hba->sli.sli3.hc_copy & ~hba->intr_mask;
4313 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hc_copy);
4314 		restore = 1;
4315 	}
4316 
4317 	/* Get host attention bits */
4318 	ha_copy = emlxs_get_attention(hba, msgid);
4319 
4320 	mutex_exit(&EMLXS_PORT_LOCK);
4321 
4322 	/* Process the interrupt */
4323 	emlxs_proc_attention(hba, ha_copy);
4324 
4325 	/* Restore interrupts */
4326 	if (restore) {
4327 		mutex_enter(&EMLXS_PORT_LOCK);
4328 		WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
4329 #ifdef FMA_SUPPORT
4330 		/* Access handle validation */
4331 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
4332 #endif  /* FMA_SUPPORT */
4333 		mutex_exit(&EMLXS_PORT_LOCK);
4334 	}
4335 
4336 	mutex_exit(&EMLXS_INTR_LOCK(msgid));
4337 
4338 	return (DDI_INTR_CLAIMED);
4339 
4340 } /* emlxs_sli3_msi_intr() */
4341 #endif /* MSI_SUPPORT */
4342 
4343 
4344 static int
4345 emlxs_sli3_intx_intr(char *arg)
4346 {
4347 	emlxs_hba_t *hba = (emlxs_hba_t *)arg;
4348 	uint32_t ha_copy = 0;
4349 
4350 	mutex_enter(&EMLXS_PORT_LOCK);
4351 
4352 	if (hba->flag & FC_OFFLINE_MODE) {
4353 		mutex_exit(&EMLXS_PORT_LOCK);
4354 
4355 		if (hba->bus_type == SBUS_FC) {
4356 			return (DDI_INTR_CLAIMED);
4357 		} else {
4358 			return (DDI_INTR_UNCLAIMED);
4359 		}
4360 	}
4361 
4362 	/* Get host attention bits */
4363 	ha_copy = emlxs_get_attention(hba, -1);
4364 
4365 	if (ha_copy == 0) {
4366 		if (hba->intr_unclaimed) {
4367 			mutex_exit(&EMLXS_PORT_LOCK);
4368 			return (DDI_INTR_UNCLAIMED);
4369 		}
4370 
4371 		hba->intr_unclaimed = 1;
4372 	} else {
4373 		hba->intr_unclaimed = 0;
4374 	}
4375 
4376 	mutex_exit(&EMLXS_PORT_LOCK);
4377 
4378 	/* Process the interrupt */
4379 	emlxs_proc_attention(hba, ha_copy);
4380 
4381 	return (DDI_INTR_CLAIMED);
4382 
4383 } /* emlxs_sli3_intx_intr() */
4384 
4385 
4386 /* EMLXS_PORT_LOCK must be held when call this routine */
4387 static uint32_t
4388 emlxs_get_attention(emlxs_hba_t *hba, int32_t msgid)
4389 {
4390 #ifdef FMA_SUPPORT
4391 	emlxs_port_t *port = &PPORT;
4392 #endif  /* FMA_SUPPORT */
4393 	uint32_t ha_copy = 0;
4394 	uint32_t ha_copy2;
4395 	uint32_t mask = hba->sli.sli3.hc_copy;
4396 
4397 #ifdef MSI_SUPPORT
4398 
4399 read_ha_register:
4400 
4401 	/* Check for default MSI interrupt */
4402 	if (msgid == 0) {
4403 		/* Read host attention register to determine interrupt source */
4404 		ha_copy2 = READ_CSR_REG(hba, FC_HA_REG(hba));
4405 
4406 		/* Filter out MSI non-default attention bits */
4407 		ha_copy2 &= ~(hba->intr_cond);
4408 	}
4409 
4410 	/* Check for polled or fixed type interrupt */
4411 	else if (msgid == -1) {
4412 		/* Read host attention register to determine interrupt source */
4413 		ha_copy2 = READ_CSR_REG(hba, FC_HA_REG(hba));
4414 	}
4415 
4416 	/* Otherwise, assume a mapped MSI interrupt */
4417 	else {
4418 		/* Convert MSI msgid to mapped attention bits */
4419 		ha_copy2 = hba->intr_map[msgid];
4420 	}
4421 
4422 #else /* !MSI_SUPPORT */
4423 
4424 	/* Read host attention register to determine interrupt source */
4425 	ha_copy2 = READ_CSR_REG(hba, FC_HA_REG(hba));
4426 
4427 #endif /* MSI_SUPPORT */
4428 
4429 	/* Check if Hardware error interrupt is enabled */
4430 	if ((ha_copy2 & HA_ERATT) && !(mask & HC_ERINT_ENA)) {
4431 		ha_copy2 &= ~HA_ERATT;
4432 	}
4433 
4434 	/* Check if link interrupt is enabled */
4435 	if ((ha_copy2 & HA_LATT) && !(mask & HC_LAINT_ENA)) {
4436 		ha_copy2 &= ~HA_LATT;
4437 	}
4438 
4439 	/* Check if Mailbox interrupt is enabled */
4440 	if ((ha_copy2 & HA_MBATT) && !(mask & HC_MBINT_ENA)) {
4441 		ha_copy2 &= ~HA_MBATT;
4442 	}
4443 
4444 	/* Check if ring0 interrupt is enabled */
4445 	if ((ha_copy2 & HA_R0ATT) && !(mask & HC_R0INT_ENA)) {
4446 		ha_copy2 &= ~HA_R0ATT;
4447 	}
4448 
4449 	/* Check if ring1 interrupt is enabled */
4450 	if ((ha_copy2 & HA_R1ATT) && !(mask & HC_R1INT_ENA)) {
4451 		ha_copy2 &= ~HA_R1ATT;
4452 	}
4453 
4454 	/* Check if ring2 interrupt is enabled */
4455 	if ((ha_copy2 & HA_R2ATT) && !(mask & HC_R2INT_ENA)) {
4456 		ha_copy2 &= ~HA_R2ATT;
4457 	}
4458 
4459 	/* Check if ring3 interrupt is enabled */
4460 	if ((ha_copy2 & HA_R3ATT) && !(mask & HC_R3INT_ENA)) {
4461 		ha_copy2 &= ~HA_R3ATT;
4462 	}
4463 
4464 	/* Accumulate attention bits */
4465 	ha_copy |= ha_copy2;
4466 
4467 	/* Clear attentions except for error, link, and autoclear(MSIX) */
4468 	ha_copy2 &= ~(HA_ERATT | HA_LATT);	/* | hba->intr_autoClear */
4469 
4470 	if (ha_copy2) {
4471 		WRITE_CSR_REG(hba, FC_HA_REG(hba), ha_copy2);
4472 	}
4473 
4474 #ifdef FMA_SUPPORT
4475 	/* Access handle validation */
4476 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
4477 #endif  /* FMA_SUPPORT */
4478 
4479 	return (ha_copy);
4480 
4481 } /* emlxs_get_attention() */
4482 
4483 
4484 static void
4485 emlxs_proc_attention(emlxs_hba_t *hba, uint32_t ha_copy)
4486 {
4487 #ifdef FMA_SUPPORT
4488 	emlxs_port_t *port = &PPORT;
4489 #endif  /* FMA_SUPPORT */
4490 
4491 	/* ha_copy should be pre-filtered */
4492 
4493 	/*
4494 	 * EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
4495 	 * "proc_attention: ha_copy=%x", ha_copy);
4496 	 */
4497 
4498 	if (hba->state < FC_WARM_START) {
4499 		return;
4500 	}
4501 
4502 	if (!ha_copy) {
4503 		return;
4504 	}
4505 
4506 	if (hba->bus_type == SBUS_FC) {
4507 		(void) READ_SBUS_CSR_REG(hba, FC_SHS_REG(hba));
4508 	}
4509 
4510 	/* Adapter error */
4511 	if (ha_copy & HA_ERATT) {
4512 		HBASTATS.IntrEvent[6]++;
4513 		emlxs_handle_ff_error(hba);
4514 		return;
4515 	}
4516 
4517 	/* Mailbox interrupt */
4518 	if (ha_copy & HA_MBATT) {
4519 		HBASTATS.IntrEvent[5]++;
4520 		(void) emlxs_handle_mb_event(hba);
4521 	}
4522 
4523 	/* Link Attention interrupt */
4524 	if (ha_copy & HA_LATT) {
4525 		HBASTATS.IntrEvent[4]++;
4526 		emlxs_sli3_handle_link_event(hba);
4527 	}
4528 
4529 	/* event on ring 0 - FCP Ring */
4530 	if (ha_copy & HA_R0ATT) {
4531 		HBASTATS.IntrEvent[0]++;
4532 		emlxs_sli3_handle_ring_event(hba, 0, ha_copy);
4533 	}
4534 
4535 	/* event on ring 1 - IP Ring */
4536 	if (ha_copy & HA_R1ATT) {
4537 		HBASTATS.IntrEvent[1]++;
4538 		emlxs_sli3_handle_ring_event(hba, 1, ha_copy);
4539 	}
4540 
4541 	/* event on ring 2 - ELS Ring */
4542 	if (ha_copy & HA_R2ATT) {
4543 		HBASTATS.IntrEvent[2]++;
4544 		emlxs_sli3_handle_ring_event(hba, 2, ha_copy);
4545 	}
4546 
4547 	/* event on ring 3 - CT Ring */
4548 	if (ha_copy & HA_R3ATT) {
4549 		HBASTATS.IntrEvent[3]++;
4550 		emlxs_sli3_handle_ring_event(hba, 3, ha_copy);
4551 	}
4552 
4553 	if (hba->bus_type == SBUS_FC) {
4554 		WRITE_SBUS_CSR_REG(hba, FC_SHS_REG(hba), SBUS_STAT_IP);
4555 	}
4556 
4557 	/* Set heartbeat flag to show activity */
4558 	hba->heartbeat_flag = 1;
4559 
4560 #ifdef FMA_SUPPORT
4561 	if (hba->bus_type == SBUS_FC) {
4562 		/* Access handle validation */
4563 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.sbus_csr_handle);
4564 	}
4565 #endif  /* FMA_SUPPORT */
4566 
4567 	return;
4568 
4569 } /* emlxs_proc_attention() */
4570 
4571 
4572 /*
4573  * emlxs_handle_ff_error()
4574  *
4575  *    Description: Processes a FireFly error
4576  *    Runs at Interrupt level
4577  */
4578 static void
4579 emlxs_handle_ff_error(emlxs_hba_t *hba)
4580 {
4581 	emlxs_port_t *port = &PPORT;
4582 	uint32_t status;
4583 	uint32_t status1;
4584 	uint32_t status2;
4585 	int i = 0;
4586 
4587 	/* do what needs to be done, get error from STATUS REGISTER */
4588 	status = READ_CSR_REG(hba, FC_HS_REG(hba));
4589 
4590 	/* Clear Chip error bit */
4591 	WRITE_CSR_REG(hba, FC_HA_REG(hba), HA_ERATT);
4592 
4593 	/* If HS_FFER1 is set, then wait until the HS_FFER1 bit clears */
4594 	if (status & HS_FFER1) {
4595 
4596 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
4597 		    "HS_FFER1 received");
4598 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
4599 		(void) emlxs_offline(hba, 1);
4600 		while ((status & HS_FFER1) && (i < 300)) {
4601 			status =
4602 			    READ_CSR_REG(hba, FC_HS_REG(hba));
4603 			BUSYWAIT_MS(1000);
4604 			i++;
4605 		}
4606 	}
4607 
4608 	if (i == 300) {
4609 		/* 5 minutes is up, shutdown HBA */
4610 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
4611 		    "HS_FFER1 clear timeout");
4612 
4613 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
4614 		emlxs_thread_spawn(hba, emlxs_shutdown_thread, NULL, NULL);
4615 
4616 		goto done;
4617 	}
4618 
4619 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
4620 	    "HS_FFER1 cleared");
4621 
4622 	if (status & HS_OVERTEMP) {
4623 		status1 =
4624 		    READ_SLIM_ADDR(hba,
4625 		    ((volatile uint8_t *)hba->sli.sli3.slim_addr + 0xb0));
4626 
4627 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
4628 		    "Maximum adapter temperature exceeded (%d �C).", status1);
4629 
4630 		hba->temperature = status1;
4631 		hba->flag |= FC_OVERTEMP_EVENT;
4632 
4633 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
4634 		emlxs_thread_spawn(hba, emlxs_shutdown_thread,
4635 		    NULL, NULL);
4636 
4637 	} else {
4638 		status1 =
4639 		    READ_SLIM_ADDR(hba,
4640 		    ((volatile uint8_t *)hba->sli.sli3.slim_addr + 0xa8));
4641 		status2 =
4642 		    READ_SLIM_ADDR(hba,
4643 		    ((volatile uint8_t *)hba->sli.sli3.slim_addr + 0xac));
4644 
4645 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_hardware_error_msg,
4646 		    "Host Error Attention: "
4647 		    "status=0x%x status1=0x%x status2=0x%x",
4648 		    status, status1, status2);
4649 
4650 		EMLXS_STATE_CHANGE(hba, FC_ERROR);
4651 
4652 		if (status & HS_FFER6) {
4653 			emlxs_thread_spawn(hba, emlxs_restart_thread,
4654 			    NULL, NULL);
4655 		} else {
4656 			emlxs_thread_spawn(hba, emlxs_shutdown_thread,
4657 			    NULL, NULL);
4658 		}
4659 	}
4660 
4661 done:
4662 #ifdef FMA_SUPPORT
4663 	/* Access handle validation */
4664 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
4665 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
4666 #endif  /* FMA_SUPPORT */
4667 
4668 	return;
4669 
4670 } /* emlxs_handle_ff_error() */
4671 
4672 
4673 /*
4674  *  emlxs_sli3_handle_link_event()
4675  *
4676  *    Description: Process a Link Attention.
4677  */
4678 static void
4679 emlxs_sli3_handle_link_event(emlxs_hba_t *hba)
4680 {
4681 	emlxs_port_t *port = &PPORT;
4682 	MAILBOXQ *mbq;
4683 	int rc;
4684 
4685 	HBASTATS.LinkEvent++;
4686 
4687 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_link_event_msg, "event=%x",
4688 	    HBASTATS.LinkEvent);
4689 
4690 	/* Make sure link is declared down */
4691 	emlxs_linkdown(hba);
4692 
4693 	/* Get a buffer which will be used for mailbox commands */
4694 	if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
4695 		/* Get link attention message */
4696 		if (emlxs_mb_read_la(hba, mbq) == 0) {
4697 			rc =  emlxs_sli3_issue_mbox_cmd(hba, mbq,
4698 			    MBX_NOWAIT, 0);
4699 			if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
4700 				emlxs_mem_put(hba, MEM_MBOX,
4701 				    (void *)mbq);
4702 			}
4703 
4704 			mutex_enter(&EMLXS_PORT_LOCK);
4705 
4706 			/*
4707 			 * Clear Link Attention in HA REG
4708 			 */
4709 			WRITE_CSR_REG(hba, FC_HA_REG(hba), HA_LATT);
4710 
4711 #ifdef FMA_SUPPORT
4712 			/* Access handle validation */
4713 			EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
4714 #endif  /* FMA_SUPPORT */
4715 
4716 			mutex_exit(&EMLXS_PORT_LOCK);
4717 		} else {
4718 			emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
4719 		}
4720 	}
4721 
4722 } /* emlxs_sli3_handle_link_event()  */
4723 
4724 
4725 /*
4726  *  emlxs_sli3_handle_ring_event()
4727  *
4728  *    Description: Process a Ring Attention.
4729  */
4730 static void
4731 emlxs_sli3_handle_ring_event(emlxs_hba_t *hba, int32_t ring_no,
4732     uint32_t ha_copy)
4733 {
4734 	emlxs_port_t *port = &PPORT;
4735 	SLIM2 *slim2p = (SLIM2 *)hba->sli.sli3.slim2.virt;
4736 	CHANNEL *cp;
4737 	RING *rp;
4738 	IOCB *entry;
4739 	IOCBQ *iocbq;
4740 	IOCBQ local_iocbq;
4741 	PGP *pgp;
4742 	uint32_t count;
4743 	volatile uint32_t chipatt;
4744 	void *ioa2;
4745 	uint32_t reg;
4746 	uint32_t channel_no;
4747 	off_t offset;
4748 	IOCBQ *rsp_head = NULL;
4749 	IOCBQ *rsp_tail = NULL;
4750 	emlxs_buf_t *sbp = NULL;
4751 
4752 	count = 0;
4753 	rp = &hba->sli.sli3.ring[ring_no];
4754 	cp = rp->channelp;
4755 	channel_no = cp->channelno;
4756 
4757 	/*
4758 	 * Isolate this ring's host attention bits
4759 	 * This makes all ring attention bits equal
4760 	 * to Ring0 attention bits
4761 	 */
4762 	reg = (ha_copy >> (ring_no * 4)) & 0x0f;
4763 
4764 	/*
4765 	 * Gather iocb entries off response ring.
4766 	 * Ensure entry is owned by the host.
4767 	 */
4768 	pgp = (PGP *)&slim2p->mbx.us.s2.port[ring_no];
4769 	offset =
4770 	    (off_t)((uint64_t)((unsigned long)&(pgp->rspPutInx)) -
4771 	    (uint64_t)((unsigned long)slim2p));
4772 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset, 4,
4773 	    DDI_DMA_SYNC_FORKERNEL);
4774 	rp->fc_port_rspidx = BE_SWAP32(pgp->rspPutInx);
4775 
4776 	/* While ring is not empty */
4777 	while (rp->fc_rspidx != rp->fc_port_rspidx) {
4778 		HBASTATS.IocbReceived[channel_no]++;
4779 
4780 		/* Get the next response ring iocb */
4781 		entry =
4782 		    (IOCB *)(((char *)rp->fc_rspringaddr +
4783 		    (rp->fc_rspidx * hba->sli.sli3.iocb_rsp_size)));
4784 
4785 		/* DMA sync the response ring iocb for the adapter */
4786 		offset = (off_t)((uint64_t)((unsigned long)entry)
4787 		    - (uint64_t)((unsigned long)slim2p));
4788 		EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset,
4789 		    hba->sli.sli3.iocb_rsp_size, DDI_DMA_SYNC_FORKERNEL);
4790 
4791 		count++;
4792 
4793 		/* Copy word6 and word7 to local iocb for now */
4794 		iocbq = &local_iocbq;
4795 
4796 		BE_SWAP32_BCOPY((uint8_t *)entry + (sizeof (uint32_t) * 6),
4797 		    (uint8_t *)iocbq + (sizeof (uint32_t) * 6),
4798 		    (sizeof (uint32_t) * 2));
4799 
4800 		/* when LE is not set, entire Command has not been received */
4801 		if (!iocbq->iocb.ULPLE) {
4802 			/* This should never happen */
4803 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_ring_error_msg,
4804 			    "ulpLE is not set. "
4805 			    "ring=%d iotag=%d cmd=%x status=%x",
4806 			    channel_no, iocbq->iocb.ULPIOTAG,
4807 			    iocbq->iocb.ULPCOMMAND, iocbq->iocb.ULPSTATUS);
4808 
4809 			goto next;
4810 		}
4811 
4812 		sbp = NULL;
4813 		switch (iocbq->iocb.ULPCOMMAND) {
4814 #ifdef SFCT_SUPPORT
4815 		case CMD_CLOSE_XRI_CX:
4816 		case CMD_CLOSE_XRI_CN:
4817 		case CMD_ABORT_XRI_CX:
4818 			if (port->mode == MODE_TARGET) {
4819 				sbp = emlxs_unregister_pkt(cp,
4820 				    iocbq->iocb.ULPIOTAG, 0);
4821 			}
4822 			break;
4823 #endif /* SFCT_SUPPORT */
4824 
4825 			/* Ring 0 registered commands */
4826 		case CMD_FCP_ICMND_CR:
4827 		case CMD_FCP_ICMND_CX:
4828 		case CMD_FCP_IREAD_CR:
4829 		case CMD_FCP_IREAD_CX:
4830 		case CMD_FCP_IWRITE_CR:
4831 		case CMD_FCP_IWRITE_CX:
4832 		case CMD_FCP_ICMND64_CR:
4833 		case CMD_FCP_ICMND64_CX:
4834 		case CMD_FCP_IREAD64_CR:
4835 		case CMD_FCP_IREAD64_CX:
4836 		case CMD_FCP_IWRITE64_CR:
4837 		case CMD_FCP_IWRITE64_CX:
4838 #ifdef SFCT_SUPPORT
4839 		case CMD_FCP_TSEND_CX:
4840 		case CMD_FCP_TSEND64_CX:
4841 		case CMD_FCP_TRECEIVE_CX:
4842 		case CMD_FCP_TRECEIVE64_CX:
4843 		case CMD_FCP_TRSP_CX:
4844 		case CMD_FCP_TRSP64_CX:
4845 #endif /* SFCT_SUPPORT */
4846 
4847 			/* Ring 1 registered commands */
4848 		case CMD_XMIT_BCAST_CN:
4849 		case CMD_XMIT_BCAST_CX:
4850 		case CMD_XMIT_SEQUENCE_CX:
4851 		case CMD_XMIT_SEQUENCE_CR:
4852 		case CMD_XMIT_BCAST64_CN:
4853 		case CMD_XMIT_BCAST64_CX:
4854 		case CMD_XMIT_SEQUENCE64_CX:
4855 		case CMD_XMIT_SEQUENCE64_CR:
4856 		case CMD_CREATE_XRI_CR:
4857 		case CMD_CREATE_XRI_CX:
4858 
4859 			/* Ring 2 registered commands */
4860 		case CMD_ELS_REQUEST_CR:
4861 		case CMD_ELS_REQUEST_CX:
4862 		case CMD_XMIT_ELS_RSP_CX:
4863 		case CMD_ELS_REQUEST64_CR:
4864 		case CMD_ELS_REQUEST64_CX:
4865 		case CMD_XMIT_ELS_RSP64_CX:
4866 
4867 			/* Ring 3 registered commands */
4868 		case CMD_GEN_REQUEST64_CR:
4869 		case CMD_GEN_REQUEST64_CX:
4870 
4871 			sbp =
4872 			    emlxs_unregister_pkt(cp, iocbq->iocb.ULPIOTAG, 0);
4873 			break;
4874 		}
4875 
4876 		/* If packet is stale, then drop it. */
4877 		if (sbp == STALE_PACKET) {
4878 			cp->hbaCmplCmd_sbp++;
4879 			/* Copy entry to the local iocbq */
4880 			BE_SWAP32_BCOPY((uint8_t *)entry,
4881 			    (uint8_t *)iocbq, hba->sli.sli3.iocb_rsp_size);
4882 
4883 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_stale_msg,
4884 			    "channelno=%d iocb=%p cmd=%x status=%x "
4885 			    "error=%x iotag=%d context=%x info=%x",
4886 			    channel_no, iocbq, (uint8_t)iocbq->iocb.ULPCOMMAND,
4887 			    iocbq->iocb.ULPSTATUS,
4888 			    (uint8_t)iocbq->iocb.un.grsp.perr.statLocalError,
4889 			    (uint16_t)iocbq->iocb.ULPIOTAG,
4890 			    (uint16_t)iocbq->iocb.ULPCONTEXT,
4891 			    (uint8_t)iocbq->iocb.ULPRSVDBYTE);
4892 
4893 			goto next;
4894 		}
4895 
4896 		/*
4897 		 * If a packet was found, then queue the packet's
4898 		 * iocb for deferred processing
4899 		 */
4900 		else if (sbp) {
4901 #ifdef SFCT_SUPPORT
4902 			fct_cmd_t *fct_cmd;
4903 			emlxs_buf_t *cmd_sbp;
4904 
4905 			fct_cmd = sbp->fct_cmd;
4906 			if (fct_cmd) {
4907 				cmd_sbp =
4908 				    (emlxs_buf_t *)fct_cmd->cmd_fca_private;
4909 				mutex_enter(&cmd_sbp->fct_mtx);
4910 				EMLXS_FCT_STATE_CHG(fct_cmd, cmd_sbp,
4911 				    EMLXS_FCT_IOCB_COMPLETE);
4912 				mutex_exit(&cmd_sbp->fct_mtx);
4913 			}
4914 #endif /* SFCT_SUPPORT */
4915 			cp->hbaCmplCmd_sbp++;
4916 			atomic_dec_32(&hba->io_active);
4917 #ifdef NODE_THROTTLE_SUPPORT
4918 			if (sbp->node) {
4919 				atomic_dec_32(&sbp->node->io_active);
4920 			}
4921 #endif /* NODE_THROTTLE_SUPPORT */
4922 
4923 			/* Copy entry to sbp's iocbq */
4924 			iocbq = &sbp->iocbq;
4925 			BE_SWAP32_BCOPY((uint8_t *)entry,
4926 			    (uint8_t *)iocbq, hba->sli.sli3.iocb_rsp_size);
4927 
4928 			iocbq->next = NULL;
4929 
4930 			/*
4931 			 * If this is NOT a polled command completion
4932 			 * or a driver allocated pkt, then defer pkt
4933 			 * completion.
4934 			 */
4935 			if (!(sbp->pkt_flags &
4936 			    (PACKET_POLLED | PACKET_ALLOCATED))) {
4937 				/* Add the IOCB to the local list */
4938 				if (!rsp_head) {
4939 					rsp_head = iocbq;
4940 				} else {
4941 					rsp_tail->next = iocbq;
4942 				}
4943 
4944 				rsp_tail = iocbq;
4945 
4946 				goto next;
4947 			}
4948 		} else {
4949 			cp->hbaCmplCmd++;
4950 			/* Copy entry to the local iocbq */
4951 			BE_SWAP32_BCOPY((uint8_t *)entry,
4952 			    (uint8_t *)iocbq, hba->sli.sli3.iocb_rsp_size);
4953 
4954 			iocbq->next = NULL;
4955 			iocbq->bp = NULL;
4956 			iocbq->port = &PPORT;
4957 			iocbq->channel = cp;
4958 			iocbq->node = NULL;
4959 			iocbq->sbp = NULL;
4960 			iocbq->flag = 0;
4961 		}
4962 
4963 		/* process the channel event now */
4964 		emlxs_proc_channel_event(hba, cp, iocbq);
4965 
4966 next:
4967 		/* Increment the driver's local response get index */
4968 		if (++rp->fc_rspidx >= rp->fc_numRiocb) {
4969 			rp->fc_rspidx = 0;
4970 		}
4971 
4972 	}	/* while (TRUE) */
4973 
4974 	if (rsp_head) {
4975 		mutex_enter(&cp->rsp_lock);
4976 		if (cp->rsp_head == NULL) {
4977 			cp->rsp_head = rsp_head;
4978 			cp->rsp_tail = rsp_tail;
4979 		} else {
4980 			cp->rsp_tail->next = rsp_head;
4981 			cp->rsp_tail = rsp_tail;
4982 		}
4983 		mutex_exit(&cp->rsp_lock);
4984 
4985 		emlxs_thread_trigger2(&cp->intr_thread, emlxs_proc_channel, cp);
4986 	}
4987 
4988 	/* Check if at least one response entry was processed */
4989 	if (count) {
4990 		/* Update response get index for the adapter */
4991 		if (hba->bus_type == SBUS_FC) {
4992 			slim2p->mbx.us.s2.host[channel_no].rspGetInx
4993 			    = BE_SWAP32(rp->fc_rspidx);
4994 
4995 			/* DMA sync the index for the adapter */
4996 			offset = (off_t)
4997 			    ((uint64_t)((unsigned long)&(slim2p->mbx.us.s2.
4998 			    host[channel_no].rspGetInx))
4999 			    - (uint64_t)((unsigned long)slim2p));
5000 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
5001 			    offset, 4, DDI_DMA_SYNC_FORDEV);
5002 		} else {
5003 			ioa2 =
5004 			    (void *)((char *)hba->sli.sli3.slim_addr +
5005 			    hba->sli.sli3.hgp_ring_offset + (((channel_no * 2) +
5006 			    1) * sizeof (uint32_t)));
5007 			WRITE_SLIM_ADDR(hba, (volatile uint32_t *)ioa2,
5008 			    rp->fc_rspidx);
5009 #ifdef FMA_SUPPORT
5010 			/* Access handle validation */
5011 			EMLXS_CHK_ACC_HANDLE(hba,
5012 			    hba->sli.sli3.slim_acc_handle);
5013 #endif  /* FMA_SUPPORT */
5014 		}
5015 
5016 		if (reg & HA_R0RE_REQ) {
5017 			/* HBASTATS.chipRingFree++; */
5018 
5019 			mutex_enter(&EMLXS_PORT_LOCK);
5020 
5021 			/* Tell the adapter we serviced the ring */
5022 			chipatt = ((CA_R0ATT | CA_R0RE_RSP) <<
5023 			    (channel_no * 4));
5024 			WRITE_CSR_REG(hba, FC_CA_REG(hba), chipatt);
5025 
5026 #ifdef FMA_SUPPORT
5027 			/* Access handle validation */
5028 			EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
5029 #endif  /* FMA_SUPPORT */
5030 
5031 			mutex_exit(&EMLXS_PORT_LOCK);
5032 		}
5033 	}
5034 
5035 	if ((reg & HA_R0CE_RSP) || hba->channel_tx_count) {
5036 		/* HBASTATS.hostRingFree++; */
5037 
5038 		/* Cmd ring may be available. Try sending more iocbs */
5039 		emlxs_sli3_issue_iocb_cmd(hba, cp, 0);
5040 	}
5041 
5042 	/* HBASTATS.ringEvent++; */
5043 
5044 	return;
5045 
5046 } /* emlxs_sli3_handle_ring_event() */
5047 
5048 
5049 extern int
5050 emlxs_handle_rcv_seq(emlxs_hba_t *hba, CHANNEL *cp, IOCBQ *iocbq)
5051 {
5052 	emlxs_port_t *port = &PPORT;
5053 	IOCB *iocb;
5054 	RING *rp;
5055 	MATCHMAP *mp = NULL;
5056 	uint64_t bdeAddr;
5057 	uint32_t vpi = 0;
5058 	uint32_t channelno;
5059 	uint32_t size = 0;
5060 	uint32_t *RcvError;
5061 	uint32_t *RcvDropped;
5062 	uint32_t *UbPosted;
5063 	emlxs_msg_t *dropped_msg;
5064 	char error_str[64];
5065 	uint32_t buf_type;
5066 	uint32_t *word;
5067 
5068 	channelno = cp->channelno;
5069 	rp = &hba->sli.sli3.ring[channelno];
5070 
5071 	iocb = &iocbq->iocb;
5072 	word = (uint32_t *)iocb;
5073 
5074 	switch (channelno) {
5075 #ifdef SFCT_SUPPORT
5076 	case FC_FCT_RING:
5077 		HBASTATS.FctRingEvent++;
5078 		RcvError = &HBASTATS.FctRingError;
5079 		RcvDropped = &HBASTATS.FctRingDropped;
5080 		UbPosted = &HBASTATS.FctUbPosted;
5081 		dropped_msg = &emlxs_fct_detail_msg;
5082 		buf_type = MEM_FCTBUF;
5083 		break;
5084 #endif /* SFCT_SUPPORT */
5085 
5086 	case FC_IP_RING:
5087 		HBASTATS.IpRcvEvent++;
5088 		RcvError = &HBASTATS.IpDropped;
5089 		RcvDropped = &HBASTATS.IpDropped;
5090 		UbPosted = &HBASTATS.IpUbPosted;
5091 		dropped_msg = &emlxs_unsol_ip_dropped_msg;
5092 		buf_type = MEM_IPBUF;
5093 		break;
5094 
5095 	case FC_ELS_RING:
5096 		HBASTATS.ElsRcvEvent++;
5097 		RcvError = &HBASTATS.ElsRcvError;
5098 		RcvDropped = &HBASTATS.ElsRcvDropped;
5099 		UbPosted = &HBASTATS.ElsUbPosted;
5100 		dropped_msg = &emlxs_unsol_els_dropped_msg;
5101 		buf_type = MEM_ELSBUF;
5102 		break;
5103 
5104 	case FC_CT_RING:
5105 		HBASTATS.CtRcvEvent++;
5106 		RcvError = &HBASTATS.CtRcvError;
5107 		RcvDropped = &HBASTATS.CtRcvDropped;
5108 		UbPosted = &HBASTATS.CtUbPosted;
5109 		dropped_msg = &emlxs_unsol_ct_dropped_msg;
5110 		buf_type = MEM_CTBUF;
5111 		break;
5112 
5113 	default:
5114 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_iocb_invalid_msg,
5115 		    "channel=%d cmd=%x  %s %x %x %x %x",
5116 		    channelno, iocb->ULPCOMMAND,
5117 		    emlxs_state_xlate(iocb->ULPSTATUS), word[4], word[5],
5118 		    word[6], word[7]);
5119 		return (1);
5120 	}
5121 
5122 	if (iocb->ULPSTATUS) {
5123 		if ((iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) &&
5124 		    (iocb->un.grsp.perr.statLocalError ==
5125 		    IOERR_RCV_BUFFER_TIMEOUT)) {
5126 			(void) strlcpy(error_str, "Out of posted buffers:",
5127 			    sizeof (error_str));
5128 			iocb->ULPBDECOUNT = 0;
5129 		} else if ((iocb->ULPSTATUS == IOSTAT_LOCAL_REJECT) &&
5130 		    (iocb->un.grsp.perr.statLocalError ==
5131 		    IOERR_RCV_BUFFER_WAITING)) {
5132 			(void) strlcpy(error_str, "Buffer waiting:",
5133 			    sizeof (error_str));
5134 			iocb->ULPBDECOUNT = 0;
5135 			goto done;
5136 		} else if (iocb->ULPSTATUS == IOSTAT_NEED_BUFF_ENTRY) {
5137 			(void) strlcpy(error_str, "Need Buffer Entry:",
5138 			    sizeof (error_str));
5139 			iocb->ULPBDECOUNT = 0;
5140 			goto done;
5141 		} else {
5142 			(void) strlcpy(error_str, "General error:",
5143 			    sizeof (error_str));
5144 		}
5145 
5146 		goto failed;
5147 	}
5148 
5149 	if (hba->flag & FC_HBQ_ENABLED) {
5150 		HBQ_INIT_t *hbq;
5151 		HBQE_t *hbqE;
5152 		uint32_t hbqe_tag;
5153 		uint32_t hbq_id;
5154 
5155 		(*UbPosted)--;
5156 
5157 		hbqE = (HBQE_t *)iocb;
5158 		hbq_id = hbqE->unt.ext.HBQ_tag;
5159 		hbqe_tag = hbqE->unt.ext.HBQE_tag;
5160 
5161 		hbq = &hba->sli.sli3.hbq_table[hbq_id];
5162 
5163 		if (hbqe_tag >= hbq->HBQ_numEntries) {
5164 			(void) snprintf(error_str, sizeof (error_str),
5165 			    "Invalid HBQE iotag=%d:", hbqe_tag);
5166 			goto dropped;
5167 		}
5168 
5169 		mp = hba->sli.sli3.hbq_table[hbq_id].HBQ_PostBufs[hbqe_tag];
5170 
5171 		size = iocb->unsli3.ext_rcv.seq_len;
5172 	} else {
5173 		bdeAddr =
5174 		    PADDR(iocb->un.cont64[0].addrHigh,
5175 		    iocb->un.cont64[0].addrLow);
5176 
5177 		/* Check for invalid buffer */
5178 		if (iocb->un.cont64[0].tus.f.bdeFlags & BUFF_TYPE_INVALID) {
5179 			(void) strlcpy(error_str, "Invalid buffer:",
5180 			    sizeof (error_str));
5181 			goto dropped;
5182 		}
5183 
5184 		mp = emlxs_mem_get_vaddr(hba, rp, bdeAddr);
5185 
5186 		size = iocb->un.rcvseq64.rcvBde.tus.f.bdeSize;
5187 	}
5188 
5189 	if (!mp) {
5190 		(void) strlcpy(error_str, "Buffer not mapped:",
5191 		    sizeof (error_str));
5192 		goto dropped;
5193 	}
5194 
5195 #ifdef FMA_SUPPORT
5196 	if (mp->dma_handle) {
5197 		if (emlxs_fm_check_dma_handle(hba, mp->dma_handle)
5198 		    != DDI_FM_OK) {
5199 			EMLXS_MSGF(EMLXS_CONTEXT,
5200 			    &emlxs_invalid_dma_handle_msg,
5201 			    "handle_rcv_seq: hdl=%p",
5202 			    mp->dma_handle);
5203 			goto dropped;
5204 		}
5205 	}
5206 #endif  /* FMA_SUPPORT */
5207 
5208 	if (!size) {
5209 		(void) strlcpy(error_str, "Buffer empty:", sizeof (error_str));
5210 		goto dropped;
5211 	}
5212 
5213 	/* To avoid we drop the broadcast packets */
5214 	if (channelno != FC_IP_RING) {
5215 		/* Get virtual port */
5216 		if (hba->flag & FC_NPIV_ENABLED) {
5217 			vpi = iocb->unsli3.ext_rcv.vpi;
5218 			if (vpi >= hba->vpi_max) {
5219 				(void) snprintf(error_str, sizeof (error_str),
5220 				"Invalid VPI=%d:", vpi);
5221 				goto dropped;
5222 			}
5223 
5224 			port = &VPORT(vpi);
5225 		}
5226 	}
5227 
5228 	/* Process request */
5229 	switch (channelno) {
5230 	case FC_FCT_RING:
5231 		if (port->mode == MODE_INITIATOR) {
5232 			(void) strlcpy(error_str, "Target mode disabled:",
5233 			    sizeof (error_str));
5234 			goto dropped;
5235 #ifdef SFCT_SUPPORT
5236 		} else if (port->mode == MODE_TARGET) {
5237 			(void) emlxs_fct_handle_unsol_req(port, cp, iocbq, mp,
5238 			    size);
5239 #endif /* SFCT_SUPPORT */
5240 		} else {
5241 			(void) snprintf(error_str, sizeof (error_str),
5242 			    "Invalid mode=%x:", port->mode);
5243 			goto dropped;
5244 		}
5245 		break;
5246 
5247 	case FC_IP_RING:
5248 		if (port->mode == MODE_INITIATOR) {
5249 			(void) emlxs_ip_handle_unsol_req(port, cp, iocbq,
5250 			    mp, size);
5251 #ifdef SFCT_SUPPORT
5252 		} else if (port->mode == MODE_TARGET) {
5253 			(void) strlcpy(error_str, "Initiator mode disabled:",
5254 			    sizeof (error_str));
5255 			goto dropped;
5256 #endif /* SFCT_SUPPORT */
5257 		} else {
5258 			(void) snprintf(error_str, sizeof (error_str),
5259 			    "Invalid mode=%x:", port->mode);
5260 			goto dropped;
5261 		}
5262 		break;
5263 
5264 	case FC_ELS_RING:
5265 		if (port->mode == MODE_INITIATOR) {
5266 			(void) emlxs_els_handle_unsol_req(port, cp, iocbq, mp,
5267 			    size);
5268 #ifdef SFCT_SUPPORT
5269 		} else if (port->mode == MODE_TARGET) {
5270 			(void) emlxs_fct_handle_unsol_els(port, cp, iocbq, mp,
5271 			    size);
5272 #endif /* SFCT_SUPPORT */
5273 		} else {
5274 			(void) snprintf(error_str, sizeof (error_str),
5275 			    "Invalid mode=%x:", port->mode);
5276 			goto dropped;
5277 		}
5278 		break;
5279 
5280 	case FC_CT_RING:
5281 		(void) emlxs_ct_handle_unsol_req(port, cp, iocbq, mp, size);
5282 		break;
5283 	}
5284 
5285 	goto done;
5286 
5287 dropped:
5288 	(*RcvDropped)++;
5289 
5290 	EMLXS_MSGF(EMLXS_CONTEXT, dropped_msg,
5291 	    "%s: cmd=%x  %s %x %x %x %x",
5292 	    error_str, iocb->ULPCOMMAND, emlxs_state_xlate(iocb->ULPSTATUS),
5293 	    word[4], word[5], word[6], word[7]);
5294 
5295 	if (channelno == FC_FCT_RING) {
5296 		uint32_t sid;
5297 
5298 		if (hba->sli_mode == EMLXS_HBA_SLI3_MODE) {
5299 			emlxs_node_t *ndlp;
5300 			ndlp = emlxs_node_find_rpi(port, iocb->ULPIOTAG);
5301 			if (! ndlp) {
5302 				goto done;
5303 			}
5304 			sid = ndlp->nlp_DID;
5305 		} else {
5306 			sid = iocb->un.ulpWord[4] & 0xFFFFFF;
5307 		}
5308 
5309 		emlxs_send_logo(port, sid);
5310 	}
5311 
5312 	goto done;
5313 
5314 failed:
5315 	(*RcvError)++;
5316 
5317 	EMLXS_MSGF(EMLXS_CONTEXT, dropped_msg,
5318 	    "%s: cmd=%x %s  %x %x %x %x  hba:%x %x",
5319 	    error_str, iocb->ULPCOMMAND, emlxs_state_xlate(iocb->ULPSTATUS),
5320 	    word[4], word[5], word[6], word[7], hba->state, hba->flag);
5321 
5322 done:
5323 
5324 	if (hba->flag & FC_HBQ_ENABLED) {
5325 		if (iocb->ULPBDECOUNT) {
5326 			HBQE_t *hbqE;
5327 			uint32_t hbq_id;
5328 
5329 			hbqE = (HBQE_t *)iocb;
5330 			hbq_id = hbqE->unt.ext.HBQ_tag;
5331 
5332 			emlxs_update_HBQ_index(hba, hbq_id);
5333 		}
5334 	} else {
5335 		if (mp) {
5336 			emlxs_mem_put(hba, buf_type, (void *)mp);
5337 		}
5338 
5339 		if (iocb->ULPBDECOUNT) {
5340 			(void) emlxs_post_buffer(hba, rp, 1);
5341 		}
5342 	}
5343 
5344 	return (0);
5345 
5346 } /* emlxs_handle_rcv_seq() */
5347 
5348 
5349 /* EMLXS_CMD_RING_LOCK must be held when calling this function */
5350 static void
5351 emlxs_sli3_issue_iocb(emlxs_hba_t *hba, RING *rp, IOCBQ *iocbq)
5352 {
5353 	emlxs_port_t *port;
5354 	IOCB *icmd;
5355 	IOCB *iocb;
5356 	emlxs_buf_t *sbp;
5357 	off_t offset;
5358 	uint32_t ringno;
5359 
5360 	ringno = rp->ringno;
5361 	sbp = iocbq->sbp;
5362 	icmd = &iocbq->iocb;
5363 	port = iocbq->port;
5364 
5365 	HBASTATS.IocbIssued[ringno]++;
5366 
5367 	/* Check for ULP pkt request */
5368 	if (sbp) {
5369 		mutex_enter(&sbp->mtx);
5370 
5371 		if (sbp->node == NULL) {
5372 			/* Set node to base node by default */
5373 			iocbq->node = (void *)&port->node_base;
5374 			sbp->node = (void *)&port->node_base;
5375 		}
5376 
5377 		sbp->pkt_flags |= PACKET_IN_CHIPQ;
5378 		mutex_exit(&sbp->mtx);
5379 
5380 		atomic_inc_32(&hba->io_active);
5381 #ifdef NODE_THROTTLE_SUPPORT
5382 		if (sbp->node) {
5383 			atomic_inc_32(&sbp->node->io_active);
5384 		}
5385 #endif /* NODE_THROTTLE_SUPPORT */
5386 
5387 #ifdef SFCT_SUPPORT
5388 #ifdef FCT_IO_TRACE
5389 		if (sbp->fct_cmd) {
5390 			emlxs_fct_io_trace(port, sbp->fct_cmd,
5391 			    EMLXS_FCT_IOCB_ISSUED);
5392 			emlxs_fct_io_trace(port, sbp->fct_cmd,
5393 			    icmd->ULPCOMMAND);
5394 		}
5395 #endif /* FCT_IO_TRACE */
5396 #endif /* SFCT_SUPPORT */
5397 
5398 		rp->channelp->hbaSendCmd_sbp++;
5399 		iocbq->channel = rp->channelp;
5400 	} else {
5401 		rp->channelp->hbaSendCmd++;
5402 	}
5403 
5404 	/* get the next available command ring iocb */
5405 	iocb =
5406 	    (IOCB *)(((char *)rp->fc_cmdringaddr +
5407 	    (rp->fc_cmdidx * hba->sli.sli3.iocb_cmd_size)));
5408 
5409 	/* Copy the local iocb to the command ring iocb */
5410 	BE_SWAP32_BCOPY((uint8_t *)icmd, (uint8_t *)iocb,
5411 	    hba->sli.sli3.iocb_cmd_size);
5412 
5413 	/* DMA sync the command ring iocb for the adapter */
5414 	offset = (off_t)((uint64_t)((unsigned long)iocb)
5415 	    - (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
5416 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset,
5417 	    hba->sli.sli3.iocb_cmd_size, DDI_DMA_SYNC_FORDEV);
5418 
5419 	/*
5420 	 * After this, the sbp / iocb should not be
5421 	 * accessed in the xmit path.
5422 	 */
5423 
5424 	/* Free the local iocb if there is no sbp tracking it */
5425 	if (!sbp) {
5426 		emlxs_mem_put(hba, MEM_IOCB, (void *)iocbq);
5427 	}
5428 
5429 	/* update local ring index to next available ring index */
5430 	rp->fc_cmdidx =
5431 	    (rp->fc_cmdidx + 1 >= rp->fc_numCiocb) ? 0 : rp->fc_cmdidx + 1;
5432 
5433 
5434 	return;
5435 
5436 } /* emlxs_sli3_issue_iocb() */
5437 
5438 
5439 static void
5440 emlxs_sli3_hba_kill(emlxs_hba_t *hba)
5441 {
5442 	emlxs_port_t *port = &PPORT;
5443 	MAILBOX *swpmb;
5444 	MAILBOX *mb2;
5445 	MAILBOX *mb1;
5446 	uint32_t word0;
5447 	uint32_t j;
5448 	uint32_t interlock_failed;
5449 	uint32_t ha_copy;
5450 	uint32_t value;
5451 	off_t offset;
5452 	uint32_t size;
5453 
5454 	/* Perform adapter interlock to kill adapter */
5455 	interlock_failed = 0;
5456 
5457 	mutex_enter(&EMLXS_PORT_LOCK);
5458 	if (hba->flag & FC_INTERLOCKED) {
5459 		EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED);
5460 
5461 		mutex_exit(&EMLXS_PORT_LOCK);
5462 
5463 		return;
5464 	}
5465 
5466 	j = 0;
5467 	while (j++ < 10000) {
5468 		if (hba->mbox_queue_flag == 0) {
5469 			break;
5470 		}
5471 
5472 		mutex_exit(&EMLXS_PORT_LOCK);
5473 		BUSYWAIT_US(100);
5474 		mutex_enter(&EMLXS_PORT_LOCK);
5475 	}
5476 
5477 	if (hba->mbox_queue_flag != 0) {
5478 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5479 		    "Interlock failed. Mailbox busy.");
5480 		mutex_exit(&EMLXS_PORT_LOCK);
5481 		return;
5482 	}
5483 
5484 	hba->flag |= FC_INTERLOCKED;
5485 	hba->mbox_queue_flag = 1;
5486 
5487 	/* Disable all host interrupts */
5488 	hba->sli.sli3.hc_copy = 0;
5489 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
5490 	WRITE_CSR_REG(hba, FC_HA_REG(hba), 0xffffffff);
5491 
5492 	mb2 = FC_SLIM2_MAILBOX(hba);
5493 	mb1 = FC_SLIM1_MAILBOX(hba);
5494 	swpmb = (MAILBOX *)&word0;
5495 
5496 	if (!(hba->flag & FC_SLIM2_MODE)) {
5497 		goto mode_B;
5498 	}
5499 
5500 mode_A:
5501 
5502 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5503 	    "Attempting SLIM2 Interlock...");
5504 
5505 interlock_A:
5506 
5507 	value = 0x55555555;
5508 	word0 = 0;
5509 	swpmb->mbxCommand = MBX_KILL_BOARD;
5510 	swpmb->mbxOwner = OWN_CHIP;
5511 
5512 	/* Write value to SLIM */
5513 	WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1), value);
5514 	WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb1)), word0);
5515 
5516 	/* Send Kill board request */
5517 	mb2->un.varWords[0] = value;
5518 	mb2->mbxCommand = MBX_KILL_BOARD;
5519 	mb2->mbxOwner = OWN_CHIP;
5520 
5521 	/* Sync the memory */
5522 	offset = (off_t)((uint64_t)((unsigned long)mb2)
5523 	    - (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
5524 	size = (sizeof (uint32_t) * 2);
5525 
5526 	BE_SWAP32_BCOPY((uint8_t *)mb2, (uint8_t *)mb2, size);
5527 
5528 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset, size,
5529 	    DDI_DMA_SYNC_FORDEV);
5530 
5531 	/* interrupt board to do it right away */
5532 	WRITE_CSR_REG(hba, FC_CA_REG(hba), CA_MBATT);
5533 
5534 	/* First wait for command acceptence */
5535 	j = 0;
5536 	while (j++ < 1000) {
5537 		value = READ_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1));
5538 
5539 		if (value == 0xAAAAAAAA) {
5540 			break;
5541 		}
5542 
5543 		BUSYWAIT_US(50);
5544 	}
5545 
5546 	if (value == 0xAAAAAAAA) {
5547 		/* Now wait for mailbox ownership to clear */
5548 		while (j++ < 10000) {
5549 			word0 =
5550 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mb1));
5551 
5552 			if (swpmb->mbxOwner == 0) {
5553 				break;
5554 			}
5555 
5556 			BUSYWAIT_US(50);
5557 		}
5558 
5559 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5560 		    "Interlock succeeded.");
5561 
5562 		goto done;
5563 	}
5564 
5565 	/* Interlock failed !!! */
5566 	interlock_failed = 1;
5567 
5568 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg, "Interlock failed.");
5569 
5570 mode_B:
5571 
5572 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5573 	    "Attempting SLIM1 Interlock...");
5574 
5575 interlock_B:
5576 
5577 	value = 0x55555555;
5578 	word0 = 0;
5579 	swpmb->mbxCommand = MBX_KILL_BOARD;
5580 	swpmb->mbxOwner = OWN_CHIP;
5581 
5582 	/* Write KILL BOARD to mailbox */
5583 	WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1), value);
5584 	WRITE_SLIM_ADDR(hba, ((volatile uint32_t *)mb1), word0);
5585 
5586 	/* interrupt board to do it right away */
5587 	WRITE_CSR_REG(hba, FC_CA_REG(hba), CA_MBATT);
5588 
5589 	/* First wait for command acceptence */
5590 	j = 0;
5591 	while (j++ < 1000) {
5592 		value = READ_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1));
5593 
5594 		if (value == 0xAAAAAAAA) {
5595 			break;
5596 		}
5597 
5598 		BUSYWAIT_US(50);
5599 	}
5600 
5601 	if (value == 0xAAAAAAAA) {
5602 		/* Now wait for mailbox ownership to clear */
5603 		while (j++ < 10000) {
5604 			word0 =
5605 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mb1));
5606 
5607 			if (swpmb->mbxOwner == 0) {
5608 				break;
5609 			}
5610 
5611 			BUSYWAIT_US(50);
5612 		}
5613 
5614 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5615 		    "Interlock succeeded.");
5616 
5617 		goto done;
5618 	}
5619 
5620 	/* Interlock failed !!! */
5621 
5622 	/* If this is the first time then try again */
5623 	if (interlock_failed == 0) {
5624 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5625 		    "Interlock failed. Retrying...");
5626 
5627 		/* Try again */
5628 		interlock_failed = 1;
5629 		goto interlock_B;
5630 	}
5631 
5632 	/*
5633 	 * Now check for error attention to indicate the board has
5634 	 * been kiilled
5635 	 */
5636 	j = 0;
5637 	while (j++ < 10000) {
5638 		ha_copy = READ_CSR_REG(hba, FC_HA_REG(hba));
5639 
5640 		if (ha_copy & HA_ERATT) {
5641 			break;
5642 		}
5643 
5644 		BUSYWAIT_US(50);
5645 	}
5646 
5647 	if (ha_copy & HA_ERATT) {
5648 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5649 		    "Interlock failed. Board killed.");
5650 	} else {
5651 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
5652 		    "Interlock failed. Board not killed.");
5653 	}
5654 
5655 done:
5656 
5657 	hba->mbox_queue_flag = 0;
5658 
5659 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED);
5660 
5661 #ifdef FMA_SUPPORT
5662 	/* Access handle validation */
5663 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
5664 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
5665 #endif  /* FMA_SUPPORT */
5666 
5667 	mutex_exit(&EMLXS_PORT_LOCK);
5668 
5669 	return;
5670 
5671 } /* emlxs_sli3_hba_kill() */
5672 
5673 
5674 static void
5675 emlxs_sli3_hba_kill4quiesce(emlxs_hba_t *hba)
5676 {
5677 	emlxs_port_t *port = &PPORT;
5678 	MAILBOX *swpmb;
5679 	MAILBOX *mb2;
5680 	MAILBOX *mb1;
5681 	uint32_t word0;
5682 	off_t offset;
5683 	uint32_t j;
5684 	uint32_t value;
5685 	uint32_t size;
5686 
5687 	/* Disable all host interrupts */
5688 	hba->sli.sli3.hc_copy = 0;
5689 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
5690 	WRITE_CSR_REG(hba, FC_HA_REG(hba), 0xffffffff);
5691 
5692 	mb2 = FC_SLIM2_MAILBOX(hba);
5693 	mb1 = FC_SLIM1_MAILBOX(hba);
5694 	swpmb = (MAILBOX *)&word0;
5695 
5696 	value = 0x55555555;
5697 	word0 = 0;
5698 	swpmb->mbxCommand = MBX_KILL_BOARD;
5699 	swpmb->mbxOwner = OWN_CHIP;
5700 
5701 	/* Write value to SLIM */
5702 	WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1), value);
5703 	WRITE_SLIM_ADDR(hba, (((volatile uint32_t *)mb1)), word0);
5704 
5705 	/* Send Kill board request */
5706 	mb2->un.varWords[0] = value;
5707 	mb2->mbxCommand = MBX_KILL_BOARD;
5708 	mb2->mbxOwner = OWN_CHIP;
5709 
5710 	/* Sync the memory */
5711 	offset = (off_t)((uint64_t)((unsigned long)mb2)
5712 	    - (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
5713 	size = (sizeof (uint32_t) * 2);
5714 
5715 	BE_SWAP32_BCOPY((uint8_t *)mb2, (uint8_t *)mb2, size);
5716 
5717 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset, size,
5718 	    DDI_DMA_SYNC_FORDEV);
5719 
5720 	/* interrupt board to do it right away */
5721 	WRITE_CSR_REG(hba, FC_CA_REG(hba), CA_MBATT);
5722 
5723 	/* First wait for command acceptence */
5724 	j = 0;
5725 	while (j++ < 1000) {
5726 		value = READ_SLIM_ADDR(hba, (((volatile uint32_t *)mb1) + 1));
5727 
5728 		if (value == 0xAAAAAAAA) {
5729 			break;
5730 		}
5731 		BUSYWAIT_US(50);
5732 	}
5733 	if (value == 0xAAAAAAAA) {
5734 		/* Now wait for mailbox ownership to clear */
5735 		while (j++ < 10000) {
5736 			word0 =
5737 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mb1));
5738 			if (swpmb->mbxOwner == 0) {
5739 				break;
5740 			}
5741 			BUSYWAIT_US(50);
5742 		}
5743 		goto done;
5744 	}
5745 
5746 done:
5747 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_KILLED);
5748 
5749 #ifdef FMA_SUPPORT
5750 	/* Access handle validation */
5751 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
5752 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
5753 #endif  /* FMA_SUPPORT */
5754 	return;
5755 
5756 } /* emlxs_sli3_hba_kill4quiesce */
5757 
5758 
5759 
5760 
5761 /*
5762  * emlxs_handle_mb_event
5763  *
5764  * Description: Process a Mailbox Attention.
5765  * Called from host_interrupt to process MBATT
5766  *
5767  *   Returns:
5768  *
5769  */
5770 static uint32_t
5771 emlxs_handle_mb_event(emlxs_hba_t *hba)
5772 {
5773 	emlxs_port_t		*port = &PPORT;
5774 	MAILBOX			*mb;
5775 	MAILBOX			*swpmb;
5776 	MAILBOX			*mbox;
5777 	MAILBOXQ		*mbq = NULL;
5778 	volatile uint32_t	word0;
5779 	MATCHMAP		*mbox_bp;
5780 	off_t			offset;
5781 	uint32_t		i;
5782 	int			rc;
5783 
5784 	swpmb = (MAILBOX *)&word0;
5785 
5786 	mutex_enter(&EMLXS_PORT_LOCK);
5787 	switch (hba->mbox_queue_flag) {
5788 	case 0:
5789 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg,
5790 		    "No mailbox active.");
5791 
5792 		mutex_exit(&EMLXS_PORT_LOCK);
5793 		return (0);
5794 
5795 	case MBX_POLL:
5796 
5797 		/* Mark mailbox complete, this should wake up any polling */
5798 		/* threads. This can happen if interrupts are enabled while */
5799 		/* a polled mailbox command is outstanding. If we don't set */
5800 		/* MBQ_COMPLETED here, the polling thread may wait until */
5801 		/* timeout error occurs */
5802 
5803 		mutex_enter(&EMLXS_MBOX_LOCK);
5804 		mbq = (MAILBOXQ *)hba->mbox_mbq;
5805 		if (mbq) {
5806 			port = (emlxs_port_t *)mbq->port;
5807 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
5808 			    "Mailbox event. Completing Polled command.");
5809 			mbq->flag |= MBQ_COMPLETED;
5810 		}
5811 		mutex_exit(&EMLXS_MBOX_LOCK);
5812 
5813 		mutex_exit(&EMLXS_PORT_LOCK);
5814 		return (0);
5815 
5816 	case MBX_SLEEP:
5817 	case MBX_NOWAIT:
5818 		/* Check mbox_timer, it acts as a service flag too */
5819 		/* The first to service the mbox queue will clear the timer */
5820 		if (hba->mbox_timer) {
5821 			hba->mbox_timer = 0;
5822 
5823 			mutex_enter(&EMLXS_MBOX_LOCK);
5824 			mbq = (MAILBOXQ *)hba->mbox_mbq;
5825 			mutex_exit(&EMLXS_MBOX_LOCK);
5826 		}
5827 
5828 		if (!mbq) {
5829 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
5830 			    "Mailbox event. No service required.");
5831 			mutex_exit(&EMLXS_PORT_LOCK);
5832 			return (0);
5833 		}
5834 
5835 		mb = (MAILBOX *)mbq;
5836 		mutex_exit(&EMLXS_PORT_LOCK);
5837 		break;
5838 
5839 	default:
5840 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_completion_error_msg,
5841 		    "Invalid Mailbox flag (%x).");
5842 
5843 		mutex_exit(&EMLXS_PORT_LOCK);
5844 		return (0);
5845 	}
5846 
5847 	/* Set port context */
5848 	port = (emlxs_port_t *)mbq->port;
5849 
5850 	/* Get first word of mailbox */
5851 	if (hba->flag & FC_SLIM2_MODE) {
5852 		mbox = FC_SLIM2_MAILBOX(hba);
5853 		offset = (off_t)((uint64_t)((unsigned long)mbox)
5854 		    - (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
5855 
5856 		EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset,
5857 		    sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
5858 		word0 = *((volatile uint32_t *)mbox);
5859 		word0 = BE_SWAP32(word0);
5860 	} else {
5861 		mbox = FC_SLIM1_MAILBOX(hba);
5862 		word0 = READ_SLIM_ADDR(hba, ((volatile uint32_t *)mbox));
5863 	}
5864 
5865 	i = 0;
5866 	while (swpmb->mbxOwner == OWN_CHIP) {
5867 		if (i++ > 10000) {
5868 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_stray_mbox_intr_msg,
5869 			    "OWN_CHIP: %s: status=%x",
5870 			    emlxs_mb_cmd_xlate(swpmb->mbxCommand),
5871 			    swpmb->mbxStatus);
5872 
5873 			return (1);
5874 		}
5875 
5876 		/* Get first word of mailbox */
5877 		if (hba->flag & FC_SLIM2_MODE) {
5878 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
5879 			    offset, sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
5880 			word0 = *((volatile uint32_t *)mbox);
5881 			word0 = BE_SWAP32(word0);
5882 		} else {
5883 			word0 =
5884 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mbox));
5885 		}
5886 	}
5887 
5888 	/* Now that we are the owner, DMA Sync entire mailbox if needed */
5889 	if (hba->flag & FC_SLIM2_MODE) {
5890 		EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, offset,
5891 		    MAILBOX_CMD_BSIZE, DDI_DMA_SYNC_FORKERNEL);
5892 
5893 		BE_SWAP32_BCOPY((uint8_t *)mbox, (uint8_t *)mb,
5894 		    MAILBOX_CMD_BSIZE);
5895 	} else {
5896 		READ_SLIM_COPY(hba, (uint32_t *)mb, (uint32_t *)mbox,
5897 		    MAILBOX_CMD_WSIZE);
5898 	}
5899 
5900 #ifdef MBOX_EXT_SUPPORT
5901 	if (mbq->extbuf) {
5902 		uint32_t *mbox_ext =
5903 		    (uint32_t *)((uint8_t *)mbox + MBOX_EXTENSION_OFFSET);
5904 		off_t offset_ext   = offset + MBOX_EXTENSION_OFFSET;
5905 
5906 		if (hba->flag & FC_SLIM2_MODE) {
5907 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
5908 			    offset_ext, mbq->extsize,
5909 			    DDI_DMA_SYNC_FORKERNEL);
5910 			BE_SWAP32_BCOPY((uint8_t *)mbox_ext,
5911 			    (uint8_t *)mbq->extbuf, mbq->extsize);
5912 		} else {
5913 			READ_SLIM_COPY(hba, (uint32_t *)mbq->extbuf,
5914 			    mbox_ext, (mbq->extsize / 4));
5915 		}
5916 	}
5917 #endif /* MBOX_EXT_SUPPORT */
5918 
5919 #ifdef FMA_SUPPORT
5920 	if (!(hba->flag & FC_SLIM2_MODE)) {
5921 		/* Access handle validation */
5922 		EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
5923 	}
5924 #endif  /* FMA_SUPPORT */
5925 
5926 	/* Now sync the memory buffer if one was used */
5927 	if (mbq->bp) {
5928 		mbox_bp = (MATCHMAP *)mbq->bp;
5929 		EMLXS_MPDATA_SYNC(mbox_bp->dma_handle, 0, mbox_bp->size,
5930 		    DDI_DMA_SYNC_FORKERNEL);
5931 	}
5932 
5933 	/* Mailbox has been completely received at this point */
5934 
5935 	if (mb->mbxCommand == MBX_HEARTBEAT) {
5936 		hba->heartbeat_active = 0;
5937 		goto done;
5938 	}
5939 
5940 	if (hba->mbox_queue_flag == MBX_SLEEP) {
5941 		if (swpmb->mbxCommand != MBX_DOWN_LOAD &&
5942 		    swpmb->mbxCommand != MBX_DUMP_MEMORY) {
5943 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
5944 			    "Received.  %s: status=%x Sleep.",
5945 			    emlxs_mb_cmd_xlate(swpmb->mbxCommand),
5946 			    swpmb->mbxStatus);
5947 		}
5948 	} else {
5949 		if (swpmb->mbxCommand != MBX_DOWN_LOAD &&
5950 		    swpmb->mbxCommand != MBX_DUMP_MEMORY) {
5951 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
5952 			    "Completed. %s: status=%x",
5953 			    emlxs_mb_cmd_xlate(swpmb->mbxCommand),
5954 			    swpmb->mbxStatus);
5955 		}
5956 	}
5957 
5958 	/* Filter out passthru mailbox */
5959 	if (mbq->flag & MBQ_PASSTHRU) {
5960 		goto done;
5961 	}
5962 
5963 	if (mb->mbxStatus) {
5964 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
5965 		    "%s: status=0x%x", emlxs_mb_cmd_xlate(mb->mbxCommand),
5966 		    (uint32_t)mb->mbxStatus);
5967 	}
5968 
5969 	if (mbq->mbox_cmpl) {
5970 		rc = (mbq->mbox_cmpl)(hba, mbq);
5971 		/* If mbox was retried, return immediately */
5972 		if (rc) {
5973 			return (0);
5974 		}
5975 	}
5976 
5977 done:
5978 
5979 	/* Clean up the mailbox area */
5980 	emlxs_mb_fini(hba, mb, mb->mbxStatus);
5981 
5982 	mbq = (MAILBOXQ *)emlxs_mb_get(hba);
5983 	if (mbq) {
5984 		/* Attempt to send pending mailboxes */
5985 		rc =  emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_NOWAIT, 0);
5986 		if ((rc != MBX_BUSY) && (rc != MBX_SUCCESS)) {
5987 			emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
5988 		}
5989 	}
5990 	return (0);
5991 
5992 } /* emlxs_handle_mb_event() */
5993 
5994 
5995 static void
5996 emlxs_sli3_timer(emlxs_hba_t *hba)
5997 {
5998 	/* Perform SLI3 level timer checks */
5999 
6000 	emlxs_sli3_timer_check_mbox(hba);
6001 
6002 } /* emlxs_sli3_timer() */
6003 
6004 
6005 static void
6006 emlxs_sli3_timer_check_mbox(emlxs_hba_t *hba)
6007 {
6008 	emlxs_port_t *port = &PPORT;
6009 	emlxs_config_t *cfg = &CFG;
6010 	MAILBOX *mb = NULL;
6011 	uint32_t word0;
6012 	uint32_t offset;
6013 	uint32_t ha_copy = 0;
6014 
6015 	if (!cfg[CFG_TIMEOUT_ENABLE].current) {
6016 		return;
6017 	}
6018 
6019 	mutex_enter(&EMLXS_PORT_LOCK);
6020 
6021 	/* Return if timer hasn't expired */
6022 	if (!hba->mbox_timer || (hba->timer_tics < hba->mbox_timer)) {
6023 		mutex_exit(&EMLXS_PORT_LOCK);
6024 		return;
6025 	}
6026 
6027 	/* Mailbox timed out, first check for error attention */
6028 	ha_copy = emlxs_check_attention(hba);
6029 
6030 	if (ha_copy & HA_ERATT) {
6031 		hba->mbox_timer = 0;
6032 		mutex_exit(&EMLXS_PORT_LOCK);
6033 		emlxs_handle_ff_error(hba);
6034 		return;
6035 	}
6036 
6037 	if (hba->mbox_queue_flag) {
6038 		/* Get first word of mailbox */
6039 		if (hba->flag & FC_SLIM2_MODE) {
6040 			mb = FC_SLIM2_MAILBOX(hba);
6041 			offset =
6042 			    (off_t)((uint64_t)((unsigned long)mb) - (uint64_t)
6043 			    ((unsigned long)hba->sli.sli3.slim2.virt));
6044 
6045 			EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle,
6046 			    offset, sizeof (uint32_t), DDI_DMA_SYNC_FORKERNEL);
6047 			word0 = *((volatile uint32_t *)mb);
6048 			word0 = BE_SWAP32(word0);
6049 		} else {
6050 			mb = FC_SLIM1_MAILBOX(hba);
6051 			word0 =
6052 			    READ_SLIM_ADDR(hba, ((volatile uint32_t *)mb));
6053 #ifdef FMA_SUPPORT
6054 			/* Access handle validation */
6055 			EMLXS_CHK_ACC_HANDLE(hba,
6056 			    hba->sli.sli3.slim_acc_handle);
6057 #endif  /* FMA_SUPPORT */
6058 		}
6059 
6060 		mb = (MAILBOX *)&word0;
6061 
6062 		/* Check if mailbox has actually completed */
6063 		if (mb->mbxOwner == OWN_HOST) {
6064 			/* Read host attention register to determine */
6065 			/* interrupt source */
6066 			uint32_t ha_copy = emlxs_check_attention(hba);
6067 
6068 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_detail_msg,
6069 			    "Mailbox attention missed: %s. Forcing event. "
6070 			    "hc=%x ha=%x", emlxs_mb_cmd_xlate(mb->mbxCommand),
6071 			    hba->sli.sli3.hc_copy, ha_copy);
6072 
6073 			mutex_exit(&EMLXS_PORT_LOCK);
6074 
6075 			(void) emlxs_handle_mb_event(hba);
6076 
6077 			return;
6078 		}
6079 
6080 		/* The first to service the mbox queue will clear the timer */
6081 		/* We will service the mailbox here */
6082 		hba->mbox_timer = 0;
6083 
6084 		mutex_enter(&EMLXS_MBOX_LOCK);
6085 		mb = (MAILBOX *)hba->mbox_mbq;
6086 		mutex_exit(&EMLXS_MBOX_LOCK);
6087 	}
6088 
6089 	if (mb) {
6090 		switch (hba->mbox_queue_flag) {
6091 		case MBX_NOWAIT:
6092 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg,
6093 			    "%s: Nowait.",
6094 			    emlxs_mb_cmd_xlate(mb->mbxCommand));
6095 			break;
6096 
6097 		case MBX_SLEEP:
6098 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg,
6099 			    "%s: mb=%p Sleep.",
6100 			    emlxs_mb_cmd_xlate(mb->mbxCommand),
6101 			    mb);
6102 			break;
6103 
6104 		case MBX_POLL:
6105 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg,
6106 			    "%s: mb=%p Polled.",
6107 			    emlxs_mb_cmd_xlate(mb->mbxCommand),
6108 			    mb);
6109 			break;
6110 
6111 		default:
6112 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg,
6113 			    "%s: mb=%p (%d).",
6114 			    emlxs_mb_cmd_xlate(mb->mbxCommand),
6115 			    mb, hba->mbox_queue_flag);
6116 			break;
6117 		}
6118 	} else {
6119 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mbox_timeout_msg, NULL);
6120 	}
6121 
6122 	hba->flag |= FC_MBOX_TIMEOUT;
6123 	EMLXS_STATE_CHANGE_LOCKED(hba, FC_ERROR);
6124 
6125 	mutex_exit(&EMLXS_PORT_LOCK);
6126 
6127 	/* Perform mailbox cleanup */
6128 	/* This will wake any sleeping or polling threads */
6129 	emlxs_mb_fini(hba, NULL, MBX_TIMEOUT);
6130 
6131 	/* Trigger adapter shutdown */
6132 	emlxs_thread_spawn(hba, emlxs_shutdown_thread, NULL, NULL);
6133 
6134 	return;
6135 
6136 } /* emlxs_sli3_timer_check_mbox() */
6137 
6138 
6139 /*
6140  * emlxs_mb_config_port  Issue a CONFIG_PORT mailbox command
6141  */
6142 static uint32_t
6143 emlxs_mb_config_port(emlxs_hba_t *hba, MAILBOXQ *mbq, uint32_t sli_mode,
6144     uint32_t hbainit)
6145 {
6146 	MAILBOX		*mb = (MAILBOX *)mbq;
6147 	emlxs_vpd_t	*vpd = &VPD;
6148 	emlxs_port_t	*port = &PPORT;
6149 	emlxs_config_t	*cfg;
6150 	RING		*rp;
6151 	uint64_t	pcb;
6152 	uint64_t	mbx;
6153 	uint64_t	hgp;
6154 	uint64_t	pgp;
6155 	uint64_t	rgp;
6156 	MAILBOX		*mbox;
6157 	SLIM2		*slim;
6158 	SLI2_RDSC	*rdsc;
6159 	uint64_t	offset;
6160 	uint32_t	Laddr;
6161 	uint32_t	i;
6162 
6163 	cfg = &CFG;
6164 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
6165 	mbox = NULL;
6166 	slim = NULL;
6167 
6168 	mb->mbxCommand = MBX_CONFIG_PORT;
6169 	mb->mbxOwner = OWN_HOST;
6170 	mbq->mbox_cmpl = NULL;
6171 
6172 	mb->un.varCfgPort.pcbLen = sizeof (PCB);
6173 	mb->un.varCfgPort.hbainit[0] = hbainit;
6174 
6175 	pcb = hba->sli.sli3.slim2.phys +
6176 	    (uint64_t)((unsigned long)&(slim->pcb));
6177 	mb->un.varCfgPort.pcbLow = PADDR_LO(pcb);
6178 	mb->un.varCfgPort.pcbHigh = PADDR_HI(pcb);
6179 
6180 	/* Set Host pointers in SLIM flag */
6181 	mb->un.varCfgPort.hps = 1;
6182 
6183 	/* Initialize hba structure for assumed default SLI2 mode */
6184 	/* If config port succeeds, then we will update it then   */
6185 	hba->sli_mode = sli_mode;
6186 	hba->vpi_max = 0;
6187 	hba->flag &= ~FC_NPIV_ENABLED;
6188 
6189 	if (sli_mode == EMLXS_HBA_SLI3_MODE) {
6190 		mb->un.varCfgPort.sli_mode = EMLXS_HBA_SLI3_MODE;
6191 		mb->un.varCfgPort.cerbm = 1;
6192 		mb->un.varCfgPort.max_hbq = EMLXS_NUM_HBQ;
6193 
6194 		if (cfg[CFG_NPIV_ENABLE].current) {
6195 			if (vpd->feaLevelHigh >= 0x09) {
6196 				if (hba->model_info.chip >= EMLXS_SATURN_CHIP) {
6197 					mb->un.varCfgPort.vpi_max =
6198 					    MAX_VPORTS - 1;
6199 				} else {
6200 					mb->un.varCfgPort.vpi_max =
6201 					    MAX_VPORTS_LIMITED - 1;
6202 				}
6203 
6204 				mb->un.varCfgPort.cmv = 1;
6205 			} else {
6206 				EMLXS_MSGF(EMLXS_CONTEXT,
6207 				    &emlxs_init_debug_msg,
6208 				    "CFGPORT: Firmware does not support NPIV. "
6209 				    "level=%d", vpd->feaLevelHigh);
6210 			}
6211 
6212 		}
6213 	}
6214 
6215 	/*
6216 	 * Now setup pcb
6217 	 */
6218 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.type = TYPE_NATIVE_SLI2;
6219 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.feature = FEATURE_INITIAL_SLI2;
6220 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.maxRing =
6221 	    (hba->sli.sli3.ring_count - 1);
6222 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.mailBoxSize =
6223 	    sizeof (MAILBOX) + MBOX_EXTENSION_SIZE;
6224 
6225 	mbx = hba->sli.sli3.slim2.phys +
6226 	    (uint64_t)((unsigned long)&(slim->mbx));
6227 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.mbAddrHigh = PADDR_HI(mbx);
6228 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.mbAddrLow = PADDR_LO(mbx);
6229 
6230 
6231 	/*
6232 	 * Set up HGP - Port Memory
6233 	 *
6234 	 * CR0Put   - SLI2(no HBQs) =	0xc0, With HBQs =	0x80
6235 	 * RR0Get			0xc4			0x84
6236 	 * CR1Put			0xc8			0x88
6237 	 * RR1Get			0xcc			0x8c
6238 	 * CR2Put			0xd0			0x90
6239 	 * RR2Get			0xd4			0x94
6240 	 * CR3Put			0xd8			0x98
6241 	 * RR3Get			0xdc			0x9c
6242 	 *
6243 	 * Reserved			0xa0-0xbf
6244 	 *
6245 	 * If HBQs configured:
6246 	 * HBQ 0 Put ptr  0xc0
6247 	 * HBQ 1 Put ptr  0xc4
6248 	 * HBQ 2 Put ptr  0xc8
6249 	 * ...
6250 	 * HBQ(M-1)Put Pointer 0xc0+(M-1)*4
6251 	 */
6252 
6253 	if (sli_mode >= EMLXS_HBA_SLI3_MODE) {
6254 		/* ERBM is enabled */
6255 		hba->sli.sli3.hgp_ring_offset = 0x80;
6256 		hba->sli.sli3.hgp_hbq_offset = 0xC0;
6257 
6258 		hba->sli.sli3.iocb_cmd_size = SLI3_IOCB_CMD_SIZE;
6259 		hba->sli.sli3.iocb_rsp_size = SLI3_IOCB_RSP_SIZE;
6260 
6261 	} else { /* SLI2 */
6262 		/* ERBM is disabled */
6263 		hba->sli.sli3.hgp_ring_offset = 0xC0;
6264 		hba->sli.sli3.hgp_hbq_offset = 0;
6265 
6266 		hba->sli.sli3.iocb_cmd_size = SLI2_IOCB_CMD_SIZE;
6267 		hba->sli.sli3.iocb_rsp_size = SLI2_IOCB_RSP_SIZE;
6268 	}
6269 
6270 	/* The Sbus card uses Host Memory. The PCI card uses SLIM POINTER */
6271 	if (hba->bus_type == SBUS_FC) {
6272 		hgp = hba->sli.sli3.slim2.phys +
6273 		    (uint64_t)((unsigned long)&(mbox->us.s2.host));
6274 		((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.hgpAddrHigh =
6275 		    PADDR_HI(hgp);
6276 		((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.hgpAddrLow =
6277 		    PADDR_LO(hgp);
6278 	} else {
6279 		((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.hgpAddrHigh =
6280 		    (uint32_t)ddi_get32(hba->pci_acc_handle,
6281 		    (uint32_t *)(hba->pci_addr + PCI_BAR_1_REGISTER));
6282 
6283 		Laddr =
6284 		    ddi_get32(hba->pci_acc_handle,
6285 		    (uint32_t *)(hba->pci_addr + PCI_BAR_0_REGISTER));
6286 		Laddr &= ~0x4;
6287 		((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.hgpAddrLow =
6288 		    (uint32_t)(Laddr + hba->sli.sli3.hgp_ring_offset);
6289 
6290 #ifdef FMA_SUPPORT
6291 		/* Access handle validation */
6292 		EMLXS_CHK_ACC_HANDLE(hba, hba->pci_acc_handle);
6293 #endif  /* FMA_SUPPORT */
6294 
6295 	}
6296 
6297 	pgp = hba->sli.sli3.slim2.phys +
6298 	    (uint64_t)((unsigned long)&(mbox->us.s2.port));
6299 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.pgpAddrHigh =
6300 	    PADDR_HI(pgp);
6301 	((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.pgpAddrLow =
6302 	    PADDR_LO(pgp);
6303 
6304 	offset = 0;
6305 	for (i = 0; i < 4; i++) {
6306 		rp = &hba->sli.sli3.ring[i];
6307 		rdsc = &((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb.rdsc[i];
6308 
6309 		/* Setup command ring */
6310 		rgp = hba->sli.sli3.slim2.phys +
6311 		    (uint64_t)((unsigned long)&(slim->IOCBs[offset]));
6312 		rdsc->cmdAddrHigh = PADDR_HI(rgp);
6313 		rdsc->cmdAddrLow = PADDR_LO(rgp);
6314 		rdsc->cmdEntries = rp->fc_numCiocb;
6315 
6316 		rp->fc_cmdringaddr =
6317 		    (void *)&((SLIM2 *)hba->sli.sli3.slim2.virt)->IOCBs[offset];
6318 		offset += rdsc->cmdEntries * hba->sli.sli3.iocb_cmd_size;
6319 
6320 		/* Setup response ring */
6321 		rgp = hba->sli.sli3.slim2.phys +
6322 		    (uint64_t)((unsigned long)&(slim->IOCBs[offset]));
6323 		rdsc->rspAddrHigh = PADDR_HI(rgp);
6324 		rdsc->rspAddrLow = PADDR_LO(rgp);
6325 		rdsc->rspEntries = rp->fc_numRiocb;
6326 
6327 		rp->fc_rspringaddr =
6328 		    (void *)&((SLIM2 *)hba->sli.sli3.slim2.virt)->IOCBs[offset];
6329 		offset += rdsc->rspEntries * hba->sli.sli3.iocb_rsp_size;
6330 	}
6331 
6332 	BE_SWAP32_BCOPY((uint8_t *)
6333 	    (&((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb),
6334 	    (uint8_t *)(&((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb),
6335 	    sizeof (PCB));
6336 
6337 	offset = ((uint64_t)((unsigned long)
6338 	    &(((SLIM2 *)hba->sli.sli3.slim2.virt)->pcb)) -
6339 	    (uint64_t)((unsigned long)hba->sli.sli3.slim2.virt));
6340 	EMLXS_MPDATA_SYNC(hba->sli.sli3.slim2.dma_handle, (off_t)offset,
6341 	    sizeof (PCB), DDI_DMA_SYNC_FORDEV);
6342 
6343 	return (0);
6344 
6345 } /* emlxs_mb_config_port() */
6346 
6347 
6348 static uint32_t
6349 emlxs_hbq_setup(emlxs_hba_t *hba, uint32_t hbq_id)
6350 {
6351 	emlxs_port_t *port = &PPORT;
6352 	HBQ_INIT_t *hbq;
6353 	MATCHMAP *mp;
6354 	HBQE_t *hbqE;
6355 	MAILBOX *mb;
6356 	MAILBOXQ *mbq;
6357 	void *ioa2;
6358 	uint32_t j;
6359 	uint32_t count;
6360 	uint32_t size;
6361 	uint32_t ringno;
6362 	uint32_t seg;
6363 
6364 	switch (hbq_id) {
6365 	case EMLXS_ELS_HBQ_ID:
6366 		count = MEM_ELSBUF_COUNT;
6367 		size = MEM_ELSBUF_SIZE;
6368 		ringno = FC_ELS_RING;
6369 		seg = MEM_ELSBUF;
6370 		HBASTATS.ElsUbPosted = count;
6371 		break;
6372 
6373 	case EMLXS_IP_HBQ_ID:
6374 		count = MEM_IPBUF_COUNT;
6375 		size = MEM_IPBUF_SIZE;
6376 		ringno = FC_IP_RING;
6377 		seg = MEM_IPBUF;
6378 		HBASTATS.IpUbPosted = count;
6379 		break;
6380 
6381 	case EMLXS_CT_HBQ_ID:
6382 		count = MEM_CTBUF_COUNT;
6383 		size = MEM_CTBUF_SIZE;
6384 		ringno = FC_CT_RING;
6385 		seg = MEM_CTBUF;
6386 		HBASTATS.CtUbPosted = count;
6387 		break;
6388 
6389 #ifdef SFCT_SUPPORT
6390 	case EMLXS_FCT_HBQ_ID:
6391 		count = MEM_FCTBUF_COUNT;
6392 		size = MEM_FCTBUF_SIZE;
6393 		ringno = FC_FCT_RING;
6394 		seg = MEM_FCTBUF;
6395 		HBASTATS.FctUbPosted = count;
6396 		break;
6397 #endif /* SFCT_SUPPORT */
6398 
6399 	default:
6400 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
6401 		    "hbq_setup: Invalid HBQ id. (%x)", hbq_id);
6402 		return (1);
6403 	}
6404 
6405 	/* Configure HBQ */
6406 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
6407 	hbq->HBQ_numEntries = count;
6408 
6409 	/* Get a Mailbox buffer to setup mailbox commands for CONFIG_HBQ */
6410 	if ((mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX)) == 0) {
6411 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
6412 		    "hbq_setup: Unable to get mailbox.");
6413 		return (1);
6414 	}
6415 	mb = (MAILBOX *)mbq;
6416 
6417 	/* Allocate HBQ Host buffer and Initialize the HBQEs */
6418 	if (emlxs_hbq_alloc(hba, hbq_id)) {
6419 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
6420 		    "hbq_setup: Unable to allocate HBQ.");
6421 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
6422 		return (1);
6423 	}
6424 
6425 	hbq->HBQ_recvNotify = 1;
6426 	hbq->HBQ_num_mask = 0;			/* Bind to ring */
6427 	hbq->HBQ_profile = 0;			/* Selection profile */
6428 						/* 0=all, 7=logentry */
6429 	hbq->HBQ_ringMask = 1 << ringno;	/* b0100 * ringno - Binds */
6430 						/* HBQ to a ring */
6431 						/* Ring0=b0001, Ring1=b0010, */
6432 						/* Ring2=b0100 */
6433 	hbq->HBQ_headerLen = 0;			/* 0 if not profile 4 or 5 */
6434 	hbq->HBQ_logEntry = 0;			/* Set to 1 if this HBQ will */
6435 						/* be used for */
6436 	hbq->HBQ_id = hbq_id;
6437 	hbq->HBQ_PutIdx_next = 0;
6438 	hbq->HBQ_PutIdx = hbq->HBQ_numEntries - 1;
6439 	hbq->HBQ_GetIdx = 0;
6440 	hbq->HBQ_PostBufCnt = hbq->HBQ_numEntries;
6441 	bzero(hbq->HBQ_PostBufs, sizeof (hbq->HBQ_PostBufs));
6442 
6443 	/* Fill in POST BUFFERs in HBQE */
6444 	hbqE = (HBQE_t *)hbq->HBQ_host_buf.virt;
6445 	for (j = 0; j < hbq->HBQ_numEntries; j++, hbqE++) {
6446 		/* Allocate buffer to post */
6447 		if ((mp = (MATCHMAP *)emlxs_mem_get(hba,
6448 		    seg)) == 0) {
6449 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_mem_alloc_msg,
6450 			    "hbq_setup: Unable to allocate HBQ buffer. "
6451 			    "cnt=%d", j);
6452 			emlxs_hbq_free_all(hba, hbq_id);
6453 			return (1);
6454 		}
6455 
6456 		hbq->HBQ_PostBufs[j] = mp;
6457 
6458 		hbqE->unt.ext.HBQ_tag = hbq_id;
6459 		hbqE->unt.ext.HBQE_tag = j;
6460 		hbqE->bde.tus.f.bdeSize = size;
6461 		hbqE->bde.tus.f.bdeFlags = 0;
6462 		hbqE->unt.w = BE_SWAP32(hbqE->unt.w);
6463 		hbqE->bde.tus.w = BE_SWAP32(hbqE->bde.tus.w);
6464 		hbqE->bde.addrLow =
6465 		    BE_SWAP32(PADDR_LO(mp->phys));
6466 		hbqE->bde.addrHigh =
6467 		    BE_SWAP32(PADDR_HI(mp->phys));
6468 	}
6469 
6470 	/* Issue CONFIG_HBQ */
6471 	emlxs_mb_config_hbq(hba, mbq, hbq_id);
6472 	if (emlxs_sli3_issue_mbox_cmd(hba, mbq, MBX_WAIT, 0) != MBX_SUCCESS) {
6473 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_init_debug_msg,
6474 		    "hbq_setup: Unable to config HBQ. cmd=%x status=%x",
6475 		    mb->mbxCommand, mb->mbxStatus);
6476 
6477 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
6478 		emlxs_hbq_free_all(hba, hbq_id);
6479 		return (1);
6480 	}
6481 
6482 	/* Setup HBQ Get/Put indexes */
6483 	ioa2 = (void *)((char *)hba->sli.sli3.slim_addr +
6484 	    (hba->sli.sli3.hgp_hbq_offset + (hbq_id * sizeof (uint32_t))));
6485 	WRITE_SLIM_ADDR(hba, (volatile uint32_t *)ioa2, hbq->HBQ_PutIdx);
6486 
6487 	hba->sli.sli3.hbq_count++;
6488 
6489 	emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
6490 
6491 #ifdef FMA_SUPPORT
6492 	/* Access handle validation */
6493 	if (emlxs_fm_check_acc_handle(hba, hba->sli.sli3.slim_acc_handle)
6494 	    != DDI_FM_OK) {
6495 		EMLXS_MSGF(EMLXS_CONTEXT,
6496 		    &emlxs_invalid_access_handle_msg, NULL);
6497 		emlxs_hbq_free_all(hba, hbq_id);
6498 		return (1);
6499 	}
6500 #endif  /* FMA_SUPPORT */
6501 
6502 	return (0);
6503 
6504 } /* emlxs_hbq_setup() */
6505 
6506 
6507 extern void
6508 emlxs_hbq_free_all(emlxs_hba_t *hba, uint32_t hbq_id)
6509 {
6510 	HBQ_INIT_t *hbq;
6511 	MBUF_INFO *buf_info;
6512 	MBUF_INFO bufinfo;
6513 	uint32_t seg;
6514 	uint32_t j;
6515 
6516 	switch (hbq_id) {
6517 	case EMLXS_ELS_HBQ_ID:
6518 		seg = MEM_ELSBUF;
6519 		HBASTATS.ElsUbPosted = 0;
6520 		break;
6521 
6522 	case EMLXS_IP_HBQ_ID:
6523 		seg = MEM_IPBUF;
6524 		HBASTATS.IpUbPosted = 0;
6525 		break;
6526 
6527 	case EMLXS_CT_HBQ_ID:
6528 		seg = MEM_CTBUF;
6529 		HBASTATS.CtUbPosted = 0;
6530 		break;
6531 
6532 #ifdef SFCT_SUPPORT
6533 	case EMLXS_FCT_HBQ_ID:
6534 		seg = MEM_FCTBUF;
6535 		HBASTATS.FctUbPosted = 0;
6536 		break;
6537 #endif /* SFCT_SUPPORT */
6538 
6539 	default:
6540 		return;
6541 	}
6542 
6543 
6544 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
6545 
6546 	if (hbq->HBQ_host_buf.virt != 0) {
6547 		for (j = 0; j < hbq->HBQ_PostBufCnt; j++) {
6548 			emlxs_mem_put(hba, seg,
6549 			    (void *)hbq->HBQ_PostBufs[j]);
6550 			hbq->HBQ_PostBufs[j] = NULL;
6551 		}
6552 		hbq->HBQ_PostBufCnt = 0;
6553 
6554 		buf_info = &bufinfo;
6555 		bzero(buf_info, sizeof (MBUF_INFO));
6556 
6557 		buf_info->size = hbq->HBQ_host_buf.size;
6558 		buf_info->virt = hbq->HBQ_host_buf.virt;
6559 		buf_info->phys = hbq->HBQ_host_buf.phys;
6560 		buf_info->dma_handle = hbq->HBQ_host_buf.dma_handle;
6561 		buf_info->data_handle = hbq->HBQ_host_buf.data_handle;
6562 		buf_info->flags = FC_MBUF_DMA;
6563 
6564 		emlxs_mem_free(hba, buf_info);
6565 
6566 		hbq->HBQ_host_buf.virt = NULL;
6567 	}
6568 
6569 	return;
6570 
6571 } /* emlxs_hbq_free_all() */
6572 
6573 
6574 extern void
6575 emlxs_update_HBQ_index(emlxs_hba_t *hba, uint32_t hbq_id)
6576 {
6577 #ifdef FMA_SUPPORT
6578 	emlxs_port_t *port = &PPORT;
6579 #endif  /* FMA_SUPPORT */
6580 	void *ioa2;
6581 	uint32_t status;
6582 	uint32_t HBQ_PortGetIdx;
6583 	HBQ_INIT_t *hbq;
6584 
6585 	switch (hbq_id) {
6586 	case EMLXS_ELS_HBQ_ID:
6587 		HBASTATS.ElsUbPosted++;
6588 		break;
6589 
6590 	case EMLXS_IP_HBQ_ID:
6591 		HBASTATS.IpUbPosted++;
6592 		break;
6593 
6594 	case EMLXS_CT_HBQ_ID:
6595 		HBASTATS.CtUbPosted++;
6596 		break;
6597 
6598 #ifdef SFCT_SUPPORT
6599 	case EMLXS_FCT_HBQ_ID:
6600 		HBASTATS.FctUbPosted++;
6601 		break;
6602 #endif /* SFCT_SUPPORT */
6603 
6604 	default:
6605 		return;
6606 	}
6607 
6608 	hbq = &hba->sli.sli3.hbq_table[hbq_id];
6609 
6610 	hbq->HBQ_PutIdx =
6611 	    (hbq->HBQ_PutIdx + 1 >=
6612 	    hbq->HBQ_numEntries) ? 0 : hbq->HBQ_PutIdx + 1;
6613 
6614 	if (hbq->HBQ_PutIdx == hbq->HBQ_GetIdx) {
6615 		HBQ_PortGetIdx =
6616 		    BE_SWAP32(((SLIM2 *)hba->sli.sli3.slim2.virt)->mbx.us.s2.
6617 		    HBQ_PortGetIdx[hbq_id]);
6618 
6619 		hbq->HBQ_GetIdx = HBQ_PortGetIdx;
6620 
6621 		if (hbq->HBQ_PutIdx == hbq->HBQ_GetIdx) {
6622 			return;
6623 		}
6624 	}
6625 
6626 	ioa2 = (void *)((char *)hba->sli.sli3.slim_addr +
6627 	    (hba->sli.sli3.hgp_hbq_offset + (hbq_id * sizeof (uint32_t))));
6628 	status = hbq->HBQ_PutIdx;
6629 	WRITE_SLIM_ADDR(hba, (volatile uint32_t *)ioa2, status);
6630 
6631 #ifdef FMA_SUPPORT
6632 	/* Access handle validation */
6633 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.slim_acc_handle);
6634 #endif  /* FMA_SUPPORT */
6635 
6636 	return;
6637 
6638 } /* emlxs_update_HBQ_index() */
6639 
6640 
6641 static void
6642 emlxs_sli3_enable_intr(emlxs_hba_t *hba)
6643 {
6644 #ifdef FMA_SUPPORT
6645 	emlxs_port_t *port = &PPORT;
6646 #endif  /* FMA_SUPPORT */
6647 	uint32_t status;
6648 
6649 	/* Enable mailbox, error attention interrupts */
6650 	status = (uint32_t)(HC_MBINT_ENA);
6651 
6652 	/* Enable ring interrupts */
6653 	if (hba->sli.sli3.ring_count >= 4) {
6654 		status |=
6655 		    (HC_R3INT_ENA | HC_R2INT_ENA | HC_R1INT_ENA |
6656 		    HC_R0INT_ENA);
6657 	} else if (hba->sli.sli3.ring_count == 3) {
6658 		status |= (HC_R2INT_ENA | HC_R1INT_ENA | HC_R0INT_ENA);
6659 	} else if (hba->sli.sli3.ring_count == 2) {
6660 		status |= (HC_R1INT_ENA | HC_R0INT_ENA);
6661 	} else if (hba->sli.sli3.ring_count == 1) {
6662 		status |= (HC_R0INT_ENA);
6663 	}
6664 
6665 	hba->sli.sli3.hc_copy = status;
6666 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
6667 
6668 #ifdef FMA_SUPPORT
6669 	/* Access handle validation */
6670 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
6671 #endif  /* FMA_SUPPORT */
6672 
6673 } /* emlxs_sli3_enable_intr() */
6674 
6675 
6676 static void
6677 emlxs_enable_latt(emlxs_hba_t *hba)
6678 {
6679 #ifdef FMA_SUPPORT
6680 	emlxs_port_t *port = &PPORT;
6681 #endif  /* FMA_SUPPORT */
6682 
6683 	mutex_enter(&EMLXS_PORT_LOCK);
6684 	hba->sli.sli3.hc_copy |= HC_LAINT_ENA;
6685 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
6686 #ifdef FMA_SUPPORT
6687 	/* Access handle validation */
6688 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
6689 #endif  /* FMA_SUPPORT */
6690 	mutex_exit(&EMLXS_PORT_LOCK);
6691 
6692 } /* emlxs_enable_latt() */
6693 
6694 
6695 static void
6696 emlxs_sli3_disable_intr(emlxs_hba_t *hba, uint32_t att)
6697 {
6698 #ifdef FMA_SUPPORT
6699 	emlxs_port_t *port = &PPORT;
6700 #endif  /* FMA_SUPPORT */
6701 
6702 	/* Disable all adapter interrupts */
6703 	hba->sli.sli3.hc_copy = att;
6704 	WRITE_CSR_REG(hba, FC_HC_REG(hba), hba->sli.sli3.hc_copy);
6705 #ifdef FMA_SUPPORT
6706 	/* Access handle validation */
6707 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
6708 #endif  /* FMA_SUPPORT */
6709 
6710 } /* emlxs_sli3_disable_intr() */
6711 
6712 
6713 static uint32_t
6714 emlxs_check_attention(emlxs_hba_t *hba)
6715 {
6716 #ifdef FMA_SUPPORT
6717 	emlxs_port_t *port = &PPORT;
6718 #endif  /* FMA_SUPPORT */
6719 	uint32_t ha_copy;
6720 
6721 	ha_copy = READ_CSR_REG(hba, FC_HA_REG(hba));
6722 #ifdef FMA_SUPPORT
6723 	/* Access handle validation */
6724 	EMLXS_CHK_ACC_HANDLE(hba, hba->sli.sli3.csr_acc_handle);
6725 #endif  /* FMA_SUPPORT */
6726 	return (ha_copy);
6727 
6728 } /* emlxs_check_attention() */
6729 
6730 
6731 static void
6732 emlxs_sli3_poll_erratt(emlxs_hba_t *hba)
6733 {
6734 	uint32_t ha_copy;
6735 
6736 	ha_copy = emlxs_check_attention(hba);
6737 
6738 	/* Adapter error */
6739 	if (ha_copy & HA_ERATT) {
6740 		HBASTATS.IntrEvent[6]++;
6741 		emlxs_handle_ff_error(hba);
6742 	}
6743 
6744 } /* emlxs_sli3_poll_erratt() */
6745 
6746 
6747 static uint32_t
6748 emlxs_sli3_reg_did_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
6749 {
6750 	emlxs_port_t *port = (emlxs_port_t *)mbq->port;
6751 	MAILBOXQ *mboxq;
6752 	MAILBOX *mb;
6753 	MATCHMAP *mp;
6754 	NODELIST *ndlp;
6755 	emlxs_port_t *vport;
6756 	SERV_PARM *sp;
6757 	int32_t i;
6758 	uint32_t  control;
6759 	uint32_t ldata;
6760 	uint32_t ldid;
6761 	uint16_t lrpi;
6762 	uint16_t lvpi;
6763 	uint32_t rval;
6764 
6765 	mb = (MAILBOX *)mbq;
6766 
6767 	if (mb->mbxStatus) {
6768 		if (mb->mbxStatus == MBXERR_NO_RESOURCES) {
6769 			control = mb->un.varRegLogin.un.sp.bdeSize;
6770 			if (control == 0) {
6771 				/* Special handle for vport PLOGI */
6772 				if (mbq->iocbq == (uint8_t *)1) {
6773 					mbq->iocbq = NULL;
6774 				}
6775 				return (0);
6776 			}
6777 			emlxs_mb_retry(hba, mbq);
6778 			return (1);
6779 		}
6780 		if (mb->mbxStatus == MBXERR_RPI_FULL) {
6781 			EMLXS_MSGF(EMLXS_CONTEXT,
6782 			    &emlxs_node_create_failed_msg,
6783 			    "Limit reached. count=%d", port->node_count);
6784 		}
6785 
6786 		/* Special handle for vport PLOGI */
6787 		if (mbq->iocbq == (uint8_t *)1) {
6788 			mbq->iocbq = NULL;
6789 		}
6790 
6791 		return (0);
6792 	}
6793 
6794 	mp = (MATCHMAP *)mbq->bp;
6795 	if (!mp) {
6796 		return (0);
6797 	}
6798 
6799 	ldata = mb->un.varWords[5];
6800 	lvpi = (ldata & 0xffff);
6801 	port = &VPORT(lvpi);
6802 
6803 	/* First copy command data */
6804 	ldata = mb->un.varWords[0];	/* get rpi */
6805 	lrpi = ldata & 0xffff;
6806 
6807 	ldata = mb->un.varWords[1];	/* get did */
6808 	ldid = ldata & MASK_DID;
6809 
6810 	sp = (SERV_PARM *)mp->virt;
6811 
6812 	/* Create or update the node */
6813 	ndlp = emlxs_node_create(port, ldid, lrpi, sp);
6814 
6815 	if (ndlp == NULL) {
6816 		emlxs_ub_priv_t *ub_priv;
6817 
6818 		/*
6819 		 * Fake a mailbox error, so the mbox_fini
6820 		 * can take appropriate action
6821 		 */
6822 		mb->mbxStatus = MBXERR_RPI_FULL;
6823 		if (mbq->ubp) {
6824 			ub_priv = ((fc_unsol_buf_t *)mbq->ubp)->ub_fca_private;
6825 			ub_priv->flags |= EMLXS_UB_REPLY;
6826 		}
6827 
6828 		/* This must be (0xFFFFFE) which was registered by vport */
6829 		if (lrpi == 0) {
6830 			return (0);
6831 		}
6832 
6833 		if (!(mboxq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
6834 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
6835 			    "reg_did_mbcmpl:failed. Unable to allocate mbox");
6836 			return (0);
6837 		}
6838 
6839 		mb = (MAILBOX *)mboxq->mbox;
6840 		mb->un.varUnregLogin.rpi = lrpi;
6841 		mb->un.varUnregLogin.vpi = lvpi;
6842 
6843 		mb->mbxCommand = MBX_UNREG_LOGIN;
6844 		mb->mbxOwner = OWN_HOST;
6845 		mboxq->sbp = NULL;
6846 		mboxq->ubp = NULL;
6847 		mboxq->iocbq = NULL;
6848 		mboxq->mbox_cmpl = NULL;
6849 		mboxq->context = NULL;
6850 		mboxq->port = (void *)port;
6851 
6852 		rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mboxq, MBX_NOWAIT, 0);
6853 		if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
6854 			EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
6855 			    "reg_did_mbcmpl:failed. Unable to send request.");
6856 
6857 			emlxs_mem_put(hba, MEM_MBOX, (void *)mboxq);
6858 			return (0);
6859 		}
6860 
6861 		return (0);
6862 	}
6863 
6864 	if (ndlp->nlp_DID == FABRIC_DID) {
6865 		/* FLOGI/FDISC successfully completed on this port */
6866 		mutex_enter(&EMLXS_PORT_LOCK);
6867 		port->flag |= EMLXS_PORT_FLOGI_CMPL;
6868 		mutex_exit(&EMLXS_PORT_LOCK);
6869 
6870 		/* If CLEAR_LA has been sent, then attempt to */
6871 		/* register the vpi now */
6872 		if (hba->state == FC_READY) {
6873 			(void) emlxs_mb_reg_vpi(port, NULL);
6874 		}
6875 
6876 		/*
6877 		 * If NPIV Fabric support has just been established on
6878 		 * the physical port, then notify the vports of the
6879 		 * link up
6880 		 */
6881 		if ((lvpi == 0) &&
6882 		    (hba->flag & FC_NPIV_ENABLED) &&
6883 		    (hba->flag & FC_NPIV_SUPPORTED)) {
6884 			/* Skip the physical port */
6885 			for (i = 1; i < MAX_VPORTS; i++) {
6886 				vport = &VPORT(i);
6887 
6888 				if (!(vport->flag & EMLXS_PORT_BOUND) ||
6889 				    !(vport->flag &
6890 				    EMLXS_PORT_ENABLED)) {
6891 					continue;
6892 				}
6893 
6894 				emlxs_port_online(vport);
6895 			}
6896 		}
6897 	}
6898 
6899 	/* Check for special restricted login flag */
6900 	if (mbq->iocbq == (uint8_t *)1) {
6901 		mbq->iocbq = NULL;
6902 		(void) EMLXS_SLI_UNREG_NODE(port, ndlp, NULL, NULL, NULL);
6903 		return (0);
6904 	}
6905 
6906 	/* Needed for FCT trigger in emlxs_mb_deferred_cmpl */
6907 	if (mbq->sbp) {
6908 		((emlxs_buf_t *)mbq->sbp)->node = ndlp;
6909 	}
6910 
6911 #ifdef DHCHAP_SUPPORT
6912 	if (mbq->sbp || mbq->ubp) {
6913 		if (emlxs_dhc_auth_start(port, ndlp, mbq->sbp,
6914 		    mbq->ubp) == 0) {
6915 			/* Auth started - auth completion will */
6916 			/* handle sbp and ubp now */
6917 			mbq->sbp = NULL;
6918 			mbq->ubp = NULL;
6919 		}
6920 	}
6921 #endif	/* DHCHAP_SUPPORT */
6922 
6923 	return (0);
6924 
6925 } /* emlxs_sli3_reg_did_mbcmpl() */
6926 
6927 
6928 static uint32_t
6929 emlxs_sli3_reg_did(emlxs_port_t *port, uint32_t did, SERV_PARM *param,
6930     emlxs_buf_t *sbp, fc_unsol_buf_t *ubp, IOCBQ *iocbq)
6931 {
6932 	emlxs_hba_t	*hba = HBA;
6933 	MATCHMAP	*mp;
6934 	MAILBOXQ	*mbq;
6935 	MAILBOX		*mb;
6936 	uint32_t	rval;
6937 
6938 	/* Check for invalid node ids to register */
6939 	if ((did == 0) && (!(hba->flag & FC_LOOPBACK_MODE))) {
6940 		return (1);
6941 	}
6942 
6943 	if (did & 0xff000000) {
6944 		return (1);
6945 	}
6946 
6947 	if ((rval = emlxs_mb_check_sparm(hba, param))) {
6948 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
6949 		    "Invalid service parameters. did=%06x rval=%d", did,
6950 		    rval);
6951 
6952 		return (1);
6953 	}
6954 
6955 	/* Check if the node limit has been reached */
6956 	if (port->node_count >= hba->max_nodes) {
6957 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
6958 		    "Limit reached. did=%06x count=%d", did,
6959 		    port->node_count);
6960 
6961 		return (1);
6962 	}
6963 
6964 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
6965 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
6966 		    "Unable to allocate mailbox. did=%x", did);
6967 
6968 		return (1);
6969 	}
6970 	mb = (MAILBOX *)mbq->mbox;
6971 	bzero((void *)mb, MAILBOX_CMD_BSIZE);
6972 
6973 	/* Build login request */
6974 	if ((mp = (MATCHMAP *)emlxs_mem_get(hba, MEM_BUF)) == 0) {
6975 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
6976 
6977 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
6978 		    "Unable to allocate buffer. did=%x", did);
6979 		return (1);
6980 	}
6981 	bcopy((void *)param, (void *)mp->virt, sizeof (SERV_PARM));
6982 
6983 	mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (SERV_PARM);
6984 	mb->un.varRegLogin.un.sp64.addrHigh = PADDR_HI(mp->phys);
6985 	mb->un.varRegLogin.un.sp64.addrLow = PADDR_LO(mp->phys);
6986 	mb->un.varRegLogin.did = did;
6987 	mb->un.varWords[30] = 0;	/* flags */
6988 	mb->mbxCommand = MBX_REG_LOGIN64;
6989 	mb->mbxOwner = OWN_HOST;
6990 	mb->un.varRegLogin.vpi = port->vpi;
6991 	mb->un.varRegLogin.rpi = 0;
6992 
6993 	mbq->sbp = (void *)sbp;
6994 	mbq->ubp = (void *)ubp;
6995 	mbq->iocbq = (void *)iocbq;
6996 	mbq->bp = (void *)mp;
6997 	mbq->mbox_cmpl = emlxs_sli3_reg_did_mbcmpl;
6998 	mbq->context = NULL;
6999 	mbq->port = (void *)port;
7000 
7001 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
7002 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
7003 		emlxs_mem_put(hba, MEM_BUF, (void *)mp);
7004 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
7005 
7006 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_node_create_failed_msg,
7007 		    "Unable to send mbox. did=%x", did);
7008 		return (1);
7009 	}
7010 
7011 	return (0);
7012 
7013 } /* emlxs_sli3_reg_did() */
7014 
7015 
7016 /*ARGSUSED*/
7017 static uint32_t
7018 emlxs_sli3_unreg_node_mbcmpl(emlxs_hba_t *hba, MAILBOXQ *mbq)
7019 {
7020 	emlxs_port_t	*port = (emlxs_port_t *)mbq->port;
7021 	MAILBOX		*mb;
7022 	NODELIST	*node;
7023 	uint16_t	rpi;
7024 
7025 	node = (NODELIST *)mbq->context;
7026 	mb = (MAILBOX *)mbq;
7027 	rpi = (node)? node->nlp_Rpi:0xffff;
7028 
7029 	if (mb->mbxStatus) {
7030 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7031 		    "unreg_node_mbcmpl:failed. node=%p rpi=%d status=%x",
7032 		    node, rpi, mb->mbxStatus);
7033 
7034 		return (0);
7035 	}
7036 
7037 	EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7038 	    "unreg_node_mbcmpl: node=%p rpi=%d",
7039 	    node, rpi);
7040 
7041 	if (node) {
7042 		emlxs_node_rm(port, node);
7043 
7044 	} else {  /* All nodes */
7045 		emlxs_node_destroy_all(port);
7046 	}
7047 
7048 	return (0);
7049 
7050 } /* emlxs_sli3_unreg_node_mbcmpl */
7051 
7052 
7053 static uint32_t
7054 emlxs_sli3_unreg_node(emlxs_port_t *port, NODELIST *node, emlxs_buf_t *sbp,
7055     fc_unsol_buf_t *ubp, IOCBQ *iocbq)
7056 {
7057 	emlxs_hba_t	*hba = HBA;
7058 	MAILBOXQ	*mbq;
7059 	MAILBOX		*mb;
7060 	uint16_t	rpi;
7061 	uint32_t	rval;
7062 
7063 	if (node) {
7064 		/* Check for base node */
7065 		if (node == &port->node_base) {
7066 			/* just flush base node */
7067 			(void) emlxs_tx_node_flush(port, &port->node_base,
7068 			    0, 0, 0);
7069 			(void) emlxs_chipq_node_flush(port, 0,
7070 			    &port->node_base, 0);
7071 
7072 			port->did = 0;
7073 
7074 			/* Return now */
7075 			return (1);
7076 		}
7077 
7078 		rpi = (uint16_t)node->nlp_Rpi;
7079 
7080 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7081 		    "unreg_node:%p  rpi=%d", node, rpi);
7082 
7083 		/* This node must be (0xFFFFFE) which registered by vport */
7084 		if (rpi == 0) {
7085 			emlxs_node_rm(port, node);
7086 			return (0);
7087 		}
7088 
7089 	} else {	/* Unreg all nodes */
7090 		rpi = 0xffff;
7091 
7092 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7093 		    "unreg_node: All");
7094 	}
7095 
7096 	if (!(mbq = (MAILBOXQ *)emlxs_mem_get(hba, MEM_MBOX))) {
7097 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7098 		    "unreg_node:failed. Unable to allocate mbox");
7099 		return (1);
7100 	}
7101 
7102 	mb = (MAILBOX *)mbq->mbox;
7103 	mb->un.varUnregLogin.rpi = rpi;
7104 	mb->un.varUnregLogin.vpi = port->vpip->VPI;
7105 
7106 	mb->mbxCommand = MBX_UNREG_LOGIN;
7107 	mb->mbxOwner = OWN_HOST;
7108 	mbq->sbp = (void *)sbp;
7109 	mbq->ubp = (void *)ubp;
7110 	mbq->iocbq = (void *)iocbq;
7111 	mbq->mbox_cmpl = emlxs_sli3_unreg_node_mbcmpl;
7112 	mbq->context = (void *)node;
7113 	mbq->port = (void *)port;
7114 
7115 	rval = EMLXS_SLI_ISSUE_MBOX_CMD(hba, mbq, MBX_NOWAIT, 0);
7116 	if ((rval != MBX_BUSY) && (rval != MBX_SUCCESS)) {
7117 		EMLXS_MSGF(EMLXS_CONTEXT, &emlxs_sli_detail_msg,
7118 		    "unreg_node:failed. Unable to send request.");
7119 
7120 		emlxs_mem_put(hba, MEM_MBOX, (void *)mbq);
7121 		return (1);
7122 	}
7123 
7124 	return (0);
7125 
7126 } /* emlxs_sli3_unreg_node() */
7127