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 usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
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 /* Copyright 2009 QLogic Corporation */
23 
24 /*
25  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26  * Use is subject to license terms.
27  */
28 
29 #pragma ident	"Copyright 2009 QLogic Corporation; ql_init.c"
30 
31 /*
32  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
33  *
34  * ***********************************************************************
35  * *									**
36  * *				NOTICE					**
37  * *		COPYRIGHT (C) 1996-2009 QLOGIC CORPORATION		**
38  * *			ALL RIGHTS RESERVED				**
39  * *									**
40  * ***********************************************************************
41  *
42  */
43 
44 #include <ql_apps.h>
45 #include <ql_api.h>
46 #include <ql_debug.h>
47 #include <ql_init.h>
48 #include <ql_iocb.h>
49 #include <ql_isr.h>
50 #include <ql_mbx.h>
51 #include <ql_xioctl.h>
52 
53 /*
54  * Local data
55  */
56 
57 /*
58  * Local prototypes
59  */
60 static uint16_t ql_nvram_request(ql_adapter_state_t *, uint32_t);
61 static int ql_nvram_24xx_config(ql_adapter_state_t *);
62 static void ql_23_properties(ql_adapter_state_t *, nvram_t *);
63 static void ql_24xx_properties(ql_adapter_state_t *, nvram_24xx_t *);
64 static int ql_check_isp_firmware(ql_adapter_state_t *);
65 static int ql_chip_diag(ql_adapter_state_t *);
66 static int ql_load_flash_fw(ql_adapter_state_t *);
67 static int ql_configure_loop(ql_adapter_state_t *);
68 static int ql_configure_hba(ql_adapter_state_t *);
69 static int ql_configure_fabric(ql_adapter_state_t *);
70 static int ql_configure_device_d_id(ql_adapter_state_t *);
71 static void ql_set_max_read_req(ql_adapter_state_t *);
72 static void ql_configure_n_port_info(ql_adapter_state_t *);
73 /*
74  * ql_initialize_adapter
75  *	Initialize board.
76  *
77  * Input:
78  *	ha = adapter state pointer.
79  *
80  * Returns:
81  *	ql local function return status code.
82  *
83  * Context:
84  *	Kernel context.
85  */
86 int
87 ql_initialize_adapter(ql_adapter_state_t *ha)
88 {
89 	int			rval;
90 	class_svc_param_t	*class3_param;
91 	caddr_t			msg;
92 	la_els_logi_t		*els = &ha->loginparams;
93 	int			retries = 5;
94 
95 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
96 
97 	do {
98 		/* Clear adapter flags. */
99 		TASK_DAEMON_LOCK(ha);
100 		ha->task_daemon_flags &= TASK_DAEMON_STOP_FLG |
101 		    TASK_DAEMON_SLEEPING_FLG | TASK_DAEMON_ALIVE_FLG |
102 		    TASK_DAEMON_IDLE_CHK_FLG;
103 		ha->task_daemon_flags |= LOOP_DOWN;
104 		TASK_DAEMON_UNLOCK(ha);
105 
106 		ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
107 		ADAPTER_STATE_LOCK(ha);
108 		ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
109 		ha->flags &= ~ONLINE;
110 		ADAPTER_STATE_UNLOCK(ha);
111 
112 		ha->state = FC_STATE_OFFLINE;
113 		msg = "Loop OFFLINE";
114 
115 		rval = ql_pci_sbus_config(ha);
116 		if (rval != QL_SUCCESS) {
117 			TASK_DAEMON_LOCK(ha);
118 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
119 				EL(ha, "ql_pci_sbus_cfg, isp_abort_needed\n");
120 				ha->task_daemon_flags |= ISP_ABORT_NEEDED;
121 			}
122 			TASK_DAEMON_UNLOCK(ha);
123 			continue;
124 		}
125 
126 		(void) ql_setup_fcache(ha);
127 
128 		/* Reset ISP chip. */
129 		ql_reset_chip(ha);
130 
131 		/* Get NVRAM configuration if needed. */
132 		if (ha->init_ctrl_blk.cb.version == 0) {
133 			(void) ql_nvram_config(ha);
134 		}
135 
136 		/* Set login parameters. */
137 		if (CFG_IST(ha, CFG_CTRL_242581)) {
138 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
139 			    ha->init_ctrl_blk.cb24.max_frame_length[0],
140 			    ha->init_ctrl_blk.cb24.max_frame_length[1]);
141 			bcopy((void *)&ha->init_ctrl_blk.cb24.port_name[0],
142 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
143 			bcopy((void *)&ha->init_ctrl_blk.cb24.node_name[0],
144 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
145 		} else {
146 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
147 			    ha->init_ctrl_blk.cb.max_frame_length[0],
148 			    ha->init_ctrl_blk.cb.max_frame_length[1]);
149 			bcopy((void *)&ha->init_ctrl_blk.cb.port_name[0],
150 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
151 			bcopy((void *)&ha->init_ctrl_blk.cb.node_name[0],
152 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
153 		}
154 
155 		/* Determine which RISC code to use. */
156 		(void) ql_check_isp_firmware(ha);
157 
158 		rval = ql_chip_diag(ha);
159 		if (rval == QL_SUCCESS) {
160 			rval = ql_load_isp_firmware(ha);
161 		}
162 
163 		if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
164 		    QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS) {
165 
166 			(void) ql_fw_ready(ha, ha->fwwait);
167 
168 			if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
169 			    ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
170 				if (ha->topology & QL_LOOP_CONNECTION) {
171 					ha->state = ha->state | FC_STATE_LOOP;
172 					msg = "Loop ONLINE";
173 					ha->task_daemon_flags |= STATE_ONLINE;
174 				} else if (ha->topology & QL_P2P_CONNECTION) {
175 					ha->state = ha->state |
176 					    FC_STATE_ONLINE;
177 					msg = "Link ONLINE";
178 					ha->task_daemon_flags |= STATE_ONLINE;
179 				} else {
180 					msg = "Unknown Link state";
181 				}
182 			}
183 		} else {
184 			TASK_DAEMON_LOCK(ha);
185 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
186 				EL(ha, "failed, isp_abort_needed\n");
187 				ha->task_daemon_flags |= ISP_ABORT_NEEDED |
188 				    LOOP_DOWN;
189 			}
190 			TASK_DAEMON_UNLOCK(ha);
191 		}
192 
193 	} while (retries-- != 0 && ha->task_daemon_flags & ISP_ABORT_NEEDED);
194 
195 	cmn_err(CE_NOTE, "!Qlogic %s(%d): %s", QL_NAME, ha->instance, msg);
196 
197 	/* Enable ISP interrupts and login parameters. */
198 	CFG_IST(ha, CFG_CTRL_242581) ? WRT32_IO_REG(ha, ictrl, ISP_EN_RISC):
199 	    WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
200 
201 	ADAPTER_STATE_LOCK(ha);
202 	ha->flags |= (INTERRUPTS_ENABLED | ONLINE);
203 	ADAPTER_STATE_UNLOCK(ha);
204 
205 	ha->task_daemon_flags &= ~(FC_STATE_CHANGE | RESET_MARKER_NEEDED |
206 	    COMMAND_WAIT_NEEDED);
207 
208 	/*
209 	 * Setup login parameters.
210 	 */
211 	els->common_service.fcph_version = 0x2006;
212 	els->common_service.btob_credit = 3;
213 	els->common_service.cmn_features = 0x8800;
214 	els->common_service.conc_sequences = 0xff;
215 	els->common_service.relative_offset = 3;
216 	els->common_service.e_d_tov = 0x07d0;
217 
218 	class3_param = (class_svc_param_t *)&els->class_3;
219 	class3_param->class_valid_svc_opt = 0x8800;
220 	class3_param->rcv_data_size = els->common_service.rx_bufsize;
221 	class3_param->conc_sequences = 0xff;
222 
223 	if (rval != QL_SUCCESS) {
224 		EL(ha, "failed, rval = %xh\n", rval);
225 	} else {
226 		/*EMPTY*/
227 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
228 	}
229 	return (rval);
230 }
231 
232 /*
233  * ql_pci_sbus_config
234  *	Setup device PCI/SBUS configuration registers.
235  *
236  * Input:
237  *	ha = adapter state pointer.
238  *
239  * Returns:
240  *	ql local function return status code.
241  *
242  * Context:
243  *	Kernel context.
244  */
245 int
246 ql_pci_sbus_config(ql_adapter_state_t *ha)
247 {
248 	uint32_t	timer;
249 	uint16_t	cmd, w16;
250 
251 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
252 
253 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
254 		w16 = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
255 		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_REVISION));
256 		EL(ha, "FPGA rev is %d.%d", (w16 & 0xf0) >> 4,
257 		    w16 & 0xf);
258 	} else {
259 		/*
260 		 * we want to respect framework's setting of PCI
261 		 * configuration space command register and also
262 		 * want to make sure that all bits of interest to us
263 		 * are properly set in command register.
264 		 */
265 		cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
266 		cmd = (uint16_t)(cmd | PCI_COMM_IO | PCI_COMM_MAE |
267 		    PCI_COMM_ME | PCI_COMM_MEMWR_INVAL |
268 		    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
269 
270 		/*
271 		 * If this is a 2300 card and not 2312, reset the
272 		 * MEMWR_INVAL due to a bug in the 2300. Unfortunately, the
273 		 * 2310 also reports itself as a 2300 so we need to get the
274 		 * fb revision level -- a 6 indicates it really is a 2300 and
275 		 * not a 2310.
276 		 */
277 
278 		if (ha->device_id == 0x2300) {
279 			/* Pause RISC. */
280 			WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
281 			for (timer = 0; timer < 30000; timer++) {
282 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) !=
283 				    0) {
284 					break;
285 				} else {
286 					drv_usecwait(MILLISEC);
287 				}
288 			}
289 
290 			/* Select FPM registers. */
291 			WRT16_IO_REG(ha, ctrl_status, 0x20);
292 
293 			/* Get the fb rev level */
294 			if (RD16_IO_REG(ha, fb_cmd) == 6) {
295 				cmd = (uint16_t)(cmd & ~PCI_COMM_MEMWR_INVAL);
296 			}
297 
298 			/* Deselect FPM registers. */
299 			WRT16_IO_REG(ha, ctrl_status, 0x0);
300 
301 			/* Release RISC module. */
302 			WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
303 			for (timer = 0; timer < 30000; timer++) {
304 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) ==
305 				    0) {
306 					break;
307 				} else {
308 					drv_usecwait(MILLISEC);
309 				}
310 			}
311 		} else if (ha->device_id == 0x2312) {
312 			/*
313 			 * cPCI ISP2312 specific code to service function 1
314 			 * hot-swap registers.
315 			 */
316 			if ((RD16_IO_REG(ha, ctrl_status) & ISP_FUNC_NUM_MASK)
317 			    != 0) {
318 				ql_pci_config_put8(ha, 0x66, 0xc2);
319 			}
320 		}
321 
322 		/* max memory read byte cnt override */
323 		if (ha->pci_max_read_req != 0) {
324 			ql_set_max_read_req(ha);
325 		}
326 
327 		ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
328 
329 		/* Set cache line register. */
330 		ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ, 0x10);
331 
332 		/* Set latency register. */
333 		ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 0x40);
334 
335 		/* Reset expansion ROM address decode enable. */
336 		w16 = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_ROM);
337 		w16 = (uint16_t)(w16 & ~BIT_0);
338 		ql_pci_config_put16(ha, PCI_CONF_ROM, w16);
339 	}
340 
341 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
342 
343 	return (QL_SUCCESS);
344 }
345 
346 /*
347  * Set the PCI max read request value.
348  *
349  * Input:
350  *	ha:		adapter state pointer.
351  *
352  * Output:
353  *	none.
354  *
355  * Returns:
356  *
357  * Context:
358  *	Kernel context.
359  */
360 
361 static void
362 ql_set_max_read_req(ql_adapter_state_t *ha)
363 {
364 	uint16_t	read_req, w16;
365 	uint16_t	tmp = ha->pci_max_read_req;
366 
367 	if ((ha->device_id == 0x2422) ||
368 	    ((ha->device_id & 0xff00) == 0x2300)) {
369 		/* check for vaild override value */
370 		if (tmp == 512 || tmp == 1024 || tmp == 2048 ||
371 		    tmp == 4096) {
372 			/* shift away the don't cares */
373 			tmp = (uint16_t)(tmp >> 10);
374 			/* convert bit pos to request value */
375 			for (read_req = 0; tmp != 0; read_req++) {
376 				tmp = (uint16_t)(tmp >> 1);
377 			}
378 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x4e);
379 			w16 = (uint16_t)(w16 & ~(BIT_3 & BIT_2));
380 			w16 = (uint16_t)(w16 | (read_req << 2));
381 			ql_pci_config_put16(ha, 0x4e, w16);
382 		} else {
383 			EL(ha, "invalid parameter value for "
384 			    "'pci-max-read-request': %d; using system "
385 			    "default\n", tmp);
386 		}
387 	} else if ((ha->device_id == 0x2432) || ((ha->device_id & 0xff00) ==
388 	    0x2500) || (ha->device_id == 0x8432)) {
389 		/* check for vaild override value */
390 		if (tmp == 128 || tmp == 256 || tmp == 512 ||
391 		    tmp == 1024 || tmp == 2048 || tmp == 4096) {
392 			/* shift away the don't cares */
393 			tmp = (uint16_t)(tmp >> 8);
394 			/* convert bit pos to request value */
395 			for (read_req = 0; tmp != 0; read_req++) {
396 				tmp = (uint16_t)(tmp >> 1);
397 			}
398 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x54);
399 			w16 = (uint16_t)(w16 & ~(BIT_14 | BIT_13 |
400 			    BIT_12));
401 			w16 = (uint16_t)(w16 | (read_req << 12));
402 			ql_pci_config_put16(ha, 0x54, w16);
403 		} else {
404 			EL(ha, "invalid parameter value for "
405 			    "'pci-max-read-request': %d; using system "
406 			    "default\n", tmp);
407 		}
408 	}
409 }
410 
411 /*
412  * NVRAM configuration.
413  *
414  * Input:
415  *	ha:		adapter state pointer.
416  *	ha->hba_buf = request and response rings
417  *
418  * Output:
419  *	ha->init_ctrl_blk = initialization control block
420  *	host adapters parameters in host adapter block
421  *
422  * Returns:
423  *	ql local function return status code.
424  *
425  * Context:
426  *	Kernel context.
427  */
428 int
429 ql_nvram_config(ql_adapter_state_t *ha)
430 {
431 	uint32_t	cnt;
432 	caddr_t		dptr1, dptr2;
433 	ql_init_cb_t	*icb = &ha->init_ctrl_blk.cb;
434 	ql_ip_init_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb;
435 	nvram_t		*nv = (nvram_t *)ha->request_ring_bp;
436 	uint16_t	*wptr = (uint16_t *)ha->request_ring_bp;
437 	uint8_t		chksum = 0;
438 	int		rval;
439 	int		idpromlen;
440 	char		idprombuf[32];
441 	uint32_t	start_addr;
442 
443 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
444 
445 	if (CFG_IST(ha, CFG_CTRL_242581)) {
446 		return (ql_nvram_24xx_config(ha));
447 	}
448 
449 	start_addr = 0;
450 	if ((rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA)) ==
451 	    QL_SUCCESS) {
452 		/* Verify valid NVRAM checksum. */
453 		for (cnt = 0; cnt < sizeof (nvram_t)/2; cnt++) {
454 			*wptr = (uint16_t)ql_get_nvram_word(ha,
455 			    (uint32_t)(cnt + start_addr));
456 			chksum = (uint8_t)(chksum + (uint8_t)*wptr);
457 			chksum = (uint8_t)(chksum + (uint8_t)(*wptr >> 8));
458 			wptr++;
459 		}
460 		ql_release_nvram(ha);
461 	}
462 
463 	/* Bad NVRAM data, set defaults parameters. */
464 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
465 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
466 	    nv->nvram_version < 1) {
467 
468 		EL(ha, "failed, rval=%xh, checksum=%xh, "
469 		    "id=%02x%02x%02x%02xh, flsz=%xh, pciconfvid=%xh, "
470 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
471 		    nv->id[2], nv->id[3], ha->xioctl->fdesc.flash_size,
472 		    ha->subven_id, nv->nvram_version);
473 
474 		/* Don't print nvram message if it's an on-board 2200 */
475 		if (!((CFG_IST(ha, CFG_CTRL_2200)) &&
476 		    (ha->xioctl->fdesc.flash_size == 0))) {
477 			cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed,"
478 			    " using driver defaults.", QL_NAME, ha->instance);
479 		}
480 
481 		/* Reset NVRAM data. */
482 		bzero((void *)nv, sizeof (nvram_t));
483 
484 		/*
485 		 * Set default initialization control block.
486 		 */
487 		nv->parameter_block_version = ICB_VERSION;
488 		nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1;
489 		nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2;
490 
491 		nv->max_frame_length[1] = 4;
492 
493 		/*
494 		 * Allow 2048 byte frames for 2300
495 		 */
496 		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
497 			nv->max_frame_length[1] = 8;
498 		}
499 		nv->max_iocb_allocation[1] = 1;
500 		nv->execution_throttle[0] = 16;
501 		nv->login_retry_count = 8;
502 
503 		idpromlen = 32;
504 
505 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
506 		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
507 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
508 		    &idpromlen) != DDI_PROP_SUCCESS) {
509 
510 			QL_PRINT_3(CE_CONT, "(%d): Unable to read idprom "
511 			    "property\n", ha->instance);
512 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
513 			    "property", QL_NAME, ha->instance);
514 
515 			nv->port_name[2] = 33;
516 			nv->port_name[3] = 224;
517 			nv->port_name[4] = 139;
518 			nv->port_name[7] = (uint8_t)
519 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
520 		} else {
521 
522 			nv->port_name[2] = idprombuf[2];
523 			nv->port_name[3] = idprombuf[3];
524 			nv->port_name[4] = idprombuf[4];
525 			nv->port_name[5] = idprombuf[5];
526 			nv->port_name[6] = idprombuf[6];
527 			nv->port_name[7] = idprombuf[7];
528 			nv->port_name[0] = (uint8_t)
529 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
530 		}
531 
532 		/* Don't print nvram message if it's an on-board 2200 */
533 		if (!(CFG_IST(ha, CFG_CTRL_2200)) &&
534 		    (ha->xioctl->fdesc.flash_size == 0)) {
535 			cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using"
536 			    " default HBA parameters and temporary WWPN:"
537 			    " %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
538 			    ha->instance, nv->port_name[0], nv->port_name[1],
539 			    nv->port_name[2], nv->port_name[3],
540 			    nv->port_name[4], nv->port_name[5],
541 			    nv->port_name[6], nv->port_name[7]);
542 		}
543 
544 		nv->login_timeout = 4;
545 
546 		/* Set default connection options for the 23xx to 2 */
547 		if (!(CFG_IST(ha, CFG_CTRL_2200))) {
548 			nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
549 			    BIT_5);
550 		}
551 
552 		/*
553 		 * Set default host adapter parameters
554 		 */
555 		nv->host_p[0] = BIT_1;
556 		nv->host_p[1] = BIT_2;
557 		nv->reset_delay = 5;
558 		nv->port_down_retry_count = 8;
559 		nv->maximum_luns_per_target[0] = 8;
560 
561 		rval = QL_FUNCTION_FAILED;
562 	}
563 
564 	/* Check for adapter node name (big endian). */
565 	for (cnt = 0; cnt < 8; cnt++) {
566 		if (nv->node_name[cnt] != 0) {
567 			break;
568 		}
569 	}
570 
571 	/* Copy port name if no node name (big endian). */
572 	if (cnt == 8) {
573 		bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
574 		nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
575 		nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
576 	}
577 
578 	/* Reset initialization control blocks. */
579 	bzero((void *)icb, sizeof (ql_init_cb_t));
580 
581 	/* Get driver properties. */
582 	ql_23_properties(ha, nv);
583 
584 	cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
585 	    "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
586 	    QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
587 	    nv->port_name[2], nv->port_name[3], nv->port_name[4],
588 	    nv->port_name[5], nv->port_name[6], nv->port_name[7],
589 	    nv->node_name[0], nv->node_name[1], nv->node_name[2],
590 	    nv->node_name[3], nv->node_name[4], nv->node_name[5],
591 	    nv->node_name[6], nv->node_name[7]);
592 
593 	/*
594 	 * Copy over NVRAM RISC parameter block
595 	 * to initialization control block.
596 	 */
597 	dptr1 = (caddr_t)icb;
598 	dptr2 = (caddr_t)&nv->parameter_block_version;
599 	cnt = (uint32_t)((uintptr_t)&icb->request_q_outpointer[0] -
600 	    (uintptr_t)&icb->version);
601 	while (cnt-- != 0) {
602 		*dptr1++ = *dptr2++;
603 	}
604 
605 	/* Copy 2nd half. */
606 	dptr1 = (caddr_t)&icb->add_fw_opt[0];
607 	cnt = (uint32_t)((uintptr_t)&icb->reserved_3[0] -
608 	    (uintptr_t)&icb->add_fw_opt[0]);
609 
610 	while (cnt-- != 0) {
611 		*dptr1++ = *dptr2++;
612 	}
613 
614 	/*
615 	 * Setup driver firmware options.
616 	 */
617 	icb->firmware_options[0] = (uint8_t)
618 	    (icb->firmware_options[0] | BIT_6 | BIT_1);
619 
620 	/*
621 	 * There is no use enabling fast post for SBUS or 2300
622 	 * Always enable 64bit addressing, except SBUS cards.
623 	 */
624 	ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
625 	if (CFG_IST(ha, (CFG_SBUS_CARD | CFG_CTRL_2300 | CFG_CTRL_6322))) {
626 		icb->firmware_options[0] = (uint8_t)
627 		    (icb->firmware_options[0] & ~BIT_3);
628 		if (CFG_IST(ha, CFG_SBUS_CARD)) {
629 			icb->special_options[0] = (uint8_t)
630 			    (icb->special_options[0] | BIT_5);
631 			ha->cfg_flags &= ~CFG_ENABLE_64BIT_ADDRESSING;
632 		}
633 	} else {
634 		icb->firmware_options[0] = (uint8_t)
635 		    (icb->firmware_options[0] | BIT_3);
636 	}
637 	/* RIO and ZIO not supported. */
638 	icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] &
639 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
640 
641 	icb->firmware_options[1] = (uint8_t)(icb->firmware_options[1] |
642 	    BIT_7 | BIT_6 | BIT_5 | BIT_2 | BIT_0);
643 	icb->firmware_options[0] = (uint8_t)
644 	    (icb->firmware_options[0] & ~(BIT_5 | BIT_4));
645 	icb->firmware_options[1] = (uint8_t)
646 	    (icb->firmware_options[1] & ~BIT_4);
647 
648 	icb->add_fw_opt[1] = (uint8_t)(icb->add_fw_opt[1] & ~(BIT_5 | BIT_4));
649 	icb->special_options[0] = (uint8_t)(icb->special_options[0] | BIT_1);
650 
651 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
652 		if ((icb->special_options[1] & 0x20) == 0) {
653 			EL(ha, "50 ohm is not set\n");
654 		}
655 	}
656 	icb->execution_throttle[0] = 0xff;
657 	icb->execution_throttle[1] = 0xff;
658 
659 	if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
660 		icb->firmware_options[1] = (uint8_t)
661 		    (icb->firmware_options[1] | BIT_7 | BIT_6);
662 		icb->add_fw_opt[1] = (uint8_t)
663 		    (icb->add_fw_opt[1] | BIT_5 | BIT_4);
664 	}
665 
666 	/*
667 	 * Set host adapter parameters
668 	 */
669 	ADAPTER_STATE_LOCK(ha);
670 	ha->nvram_version = nv->nvram_version;
671 	ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
672 	    nv->adapter_features[1]);
673 
674 	nv->host_p[0] & BIT_4 ? (ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD) :
675 	    (ha->cfg_flags &= ~CFG_DISABLE_RISC_CODE_LOAD);
676 	nv->host_p[0] & BIT_5 ? (ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1) :
677 	    (ha->cfg_flags &= ~CFG_SET_CACHE_LINE_SIZE_1);
678 
679 	nv->host_p[1] & BIT_1 ? (ha->cfg_flags |= CFG_ENABLE_LIP_RESET) :
680 	    (ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET);
681 	nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
682 	    (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
683 	nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
684 	    (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
685 
686 	nv->adapter_features[0] & BIT_3 ?
687 	    (ha->cfg_flags |= CFG_MULTI_CHIP_ADAPTER) :
688 	    (ha->cfg_flags &= ~CFG_MULTI_CHIP_ADAPTER);
689 
690 	ADAPTER_STATE_UNLOCK(ha);
691 
692 	ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
693 	    nv->execution_throttle[1]);
694 	ha->loop_reset_delay = nv->reset_delay;
695 	ha->port_down_retry_count = nv->port_down_retry_count;
696 	ha->r_a_tov = (uint16_t)(icb->login_timeout < R_A_TOV_DEFAULT ?
697 	    R_A_TOV_DEFAULT : icb->login_timeout);
698 	ha->maximum_luns_per_target = CHAR_TO_SHORT(
699 	    nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
700 	if (ha->maximum_luns_per_target == 0) {
701 		ha->maximum_luns_per_target++;
702 	}
703 
704 	/*
705 	 * Setup ring parameters in initialization control block
706 	 */
707 	cnt = REQUEST_ENTRY_CNT;
708 	icb->request_q_length[0] = LSB(cnt);
709 	icb->request_q_length[1] = MSB(cnt);
710 	cnt = RESPONSE_ENTRY_CNT;
711 	icb->response_q_length[0] = LSB(cnt);
712 	icb->response_q_length[1] = MSB(cnt);
713 
714 	icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
715 	icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
716 	icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
717 	icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
718 	icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
719 	icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
720 	icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
721 	icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
722 
723 	icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
724 	icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
725 	icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
726 	icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
727 	icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
728 	icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
729 	icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
730 	icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
731 
732 	/*
733 	 * Setup IP initialization control block
734 	 */
735 	ip_icb->version = IP_ICB_VERSION;
736 
737 	if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
738 		ip_icb->ip_firmware_options[0] = (uint8_t)
739 		    (ip_icb->ip_firmware_options[0] | BIT_2 | BIT_0);
740 	} else {
741 		ip_icb->ip_firmware_options[0] = (uint8_t)
742 		    (ip_icb->ip_firmware_options[0] | BIT_2);
743 	}
744 
745 	cnt = RCVBUF_CONTAINER_CNT;
746 	ip_icb->queue_size[0] = LSB(cnt);
747 	ip_icb->queue_size[1] = MSB(cnt);
748 
749 	ip_icb->queue_address[0] = LSB(LSW(LSD(ha->rcvbuf_dvma)));
750 	ip_icb->queue_address[1] = MSB(LSW(LSD(ha->rcvbuf_dvma)));
751 	ip_icb->queue_address[2] = LSB(MSW(LSD(ha->rcvbuf_dvma)));
752 	ip_icb->queue_address[3] = MSB(MSW(LSD(ha->rcvbuf_dvma)));
753 	ip_icb->queue_address[4] = LSB(LSW(MSD(ha->rcvbuf_dvma)));
754 	ip_icb->queue_address[5] = MSB(LSW(MSD(ha->rcvbuf_dvma)));
755 	ip_icb->queue_address[6] = LSB(MSW(MSD(ha->rcvbuf_dvma)));
756 	ip_icb->queue_address[7] = MSB(MSW(MSD(ha->rcvbuf_dvma)));
757 
758 	if (rval != QL_SUCCESS) {
759 		EL(ha, "failed, rval = %xh\n", rval);
760 	} else {
761 		/*EMPTY*/
762 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
763 	}
764 	return (rval);
765 }
766 
767 /*
768  * Get NVRAM data word
769  *	Calculates word position in NVRAM and calls request routine to
770  *	get the word from NVRAM.
771  *
772  * Input:
773  *	ha = adapter state pointer.
774  *	address = NVRAM word address.
775  *
776  * Returns:
777  *	data word.
778  *
779  * Context:
780  *	Kernel context.
781  */
782 uint16_t
783 ql_get_nvram_word(ql_adapter_state_t *ha, uint32_t address)
784 {
785 	uint32_t	nv_cmd;
786 	uint16_t	rval;
787 
788 	QL_PRINT_4(CE_CONT, "(%d): started\n", ha->instance);
789 
790 	nv_cmd = address << 16;
791 	nv_cmd = nv_cmd | NV_READ_OP;
792 
793 	rval = (uint16_t)ql_nvram_request(ha, nv_cmd);
794 
795 	QL_PRINT_4(CE_CONT, "(%d): NVRAM data = %xh\n", ha->instance, rval);
796 
797 	return (rval);
798 }
799 
800 /*
801  * NVRAM request
802  *	Sends read command to NVRAM and gets data from NVRAM.
803  *
804  * Input:
805  *	ha = adapter state pointer.
806  *	nv_cmd = Bit 26= start bit
807  *	Bit 25, 24 = opcode
808  *	Bit 23-16 = address
809  *	Bit 15-0 = write data
810  *
811  * Returns:
812  *	data word.
813  *
814  * Context:
815  *	Kernel context.
816  */
817 static uint16_t
818 ql_nvram_request(ql_adapter_state_t *ha, uint32_t nv_cmd)
819 {
820 	uint8_t		cnt;
821 	uint16_t	reg_data;
822 	uint16_t	data = 0;
823 
824 	/* Send command to NVRAM. */
825 
826 	nv_cmd <<= 5;
827 	for (cnt = 0; cnt < 11; cnt++) {
828 		if (nv_cmd & BIT_31) {
829 			ql_nv_write(ha, NV_DATA_OUT);
830 		} else {
831 			ql_nv_write(ha, 0);
832 		}
833 		nv_cmd <<= 1;
834 	}
835 
836 	/* Read data from NVRAM. */
837 
838 	for (cnt = 0; cnt < 16; cnt++) {
839 		WRT16_IO_REG(ha, nvram, NV_SELECT+NV_CLOCK);
840 		ql_nv_delay();
841 		data <<= 1;
842 		reg_data = RD16_IO_REG(ha, nvram);
843 		if (reg_data & NV_DATA_IN) {
844 			data = (uint16_t)(data | BIT_0);
845 		}
846 		WRT16_IO_REG(ha, nvram, NV_SELECT);
847 		ql_nv_delay();
848 	}
849 
850 	/* Deselect chip. */
851 
852 	WRT16_IO_REG(ha, nvram, NV_DESELECT);
853 	ql_nv_delay();
854 
855 	return (data);
856 }
857 
858 void
859 ql_nv_write(ql_adapter_state_t *ha, uint16_t data)
860 {
861 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
862 	ql_nv_delay();
863 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT | NV_CLOCK));
864 	ql_nv_delay();
865 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
866 	ql_nv_delay();
867 }
868 
869 void
870 ql_nv_delay(void)
871 {
872 	drv_usecwait(NV_DELAY_COUNT);
873 }
874 
875 /*
876  * ql_nvram_24xx_config
877  *	ISP2400 nvram.
878  *
879  * Input:
880  *	ha:		adapter state pointer.
881  *	ha->hba_buf = request and response rings
882  *
883  * Output:
884  *	ha->init_ctrl_blk = initialization control block
885  *	host adapters parameters in host adapter block
886  *
887  * Returns:
888  *	ql local function return status code.
889  *
890  * Context:
891  *	Kernel context.
892  */
893 int
894 ql_nvram_24xx_config(ql_adapter_state_t *ha)
895 {
896 	uint32_t		index, addr, chksum, saved_chksum;
897 	uint32_t		*longptr;
898 	nvram_24xx_t		nvram;
899 	int			idpromlen;
900 	char			idprombuf[32];
901 	caddr_t			src, dst;
902 	uint16_t		w1;
903 	int			rval;
904 	nvram_24xx_t		*nv = (nvram_24xx_t *)&nvram;
905 	ql_init_24xx_cb_t	*icb =
906 	    (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
907 	ql_ip_init_24xx_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb24;
908 
909 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
910 
911 	if ((rval = ql_lock_nvram(ha, &addr, LNF_NVRAM_DATA)) == QL_SUCCESS) {
912 
913 		/* Get NVRAM data and calculate checksum. */
914 		longptr = (uint32_t *)nv;
915 		chksum = saved_chksum = 0;
916 		for (index = 0; index < sizeof (nvram_24xx_t) / 4; index++) {
917 			rval = ql_24xx_read_flash(ha, addr++, longptr);
918 			if (rval != QL_SUCCESS) {
919 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
920 				break;
921 			}
922 			saved_chksum = chksum;
923 			chksum += *longptr;
924 			LITTLE_ENDIAN_32(longptr);
925 			longptr++;
926 		}
927 
928 		ql_release_nvram(ha);
929 	}
930 
931 	/* Bad NVRAM data, set defaults parameters. */
932 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
933 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
934 	    (nv->nvram_version[0] | nv->nvram_version[1]) == 0) {
935 
936 		cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed, using "
937 		    "driver defaults.", QL_NAME, ha->instance);
938 
939 		EL(ha, "failed, rval=%xh, checksum=%xh, id=%c%c%c%c, "
940 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
941 		    nv->id[2], nv->id[3], CHAR_TO_SHORT(nv->nvram_version[0],
942 		    nv->nvram_version[1]));
943 
944 		saved_chksum = ~saved_chksum + 1;
945 
946 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_NVRAM_CHKSUM_ERR, 0,
947 		    MSW(saved_chksum), LSW(saved_chksum));
948 
949 		/* Reset NVRAM data. */
950 		bzero((void *)nv, sizeof (nvram_24xx_t));
951 
952 		/*
953 		 * Set default initialization control block.
954 		 */
955 		nv->nvram_version[0] = LSB(ICB_24XX_VERSION);
956 		nv->nvram_version[1] = MSB(ICB_24XX_VERSION);
957 
958 		nv->version[0] = 1;
959 		nv->max_frame_length[1] = 8;
960 		nv->execution_throttle[0] = 16;
961 		nv->max_luns_per_target[0] = 8;
962 
963 		idpromlen = 32;
964 
965 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
966 		if (rval = ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
967 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
968 		    &idpromlen) != DDI_PROP_SUCCESS) {
969 
970 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
971 			    "property, rval=%x", QL_NAME, ha->instance, rval);
972 
973 			nv->port_name[0] = 33;
974 			nv->port_name[3] = 224;
975 			nv->port_name[4] = 139;
976 			nv->port_name[7] = (uint8_t)
977 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
978 		} else {
979 			nv->port_name[2] = idprombuf[2];
980 			nv->port_name[3] = idprombuf[3];
981 			nv->port_name[4] = idprombuf[4];
982 			nv->port_name[5] = idprombuf[5];
983 			nv->port_name[6] = idprombuf[6];
984 			nv->port_name[7] = idprombuf[7];
985 			nv->port_name[0] = (uint8_t)
986 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
987 		}
988 
989 		cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using default "
990 		    "HBA parameters and temporary "
991 		    "WWPN: %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
992 		    ha->instance, nv->port_name[0], nv->port_name[1],
993 		    nv->port_name[2], nv->port_name[3], nv->port_name[4],
994 		    nv->port_name[5], nv->port_name[6], nv->port_name[7]);
995 
996 		nv->login_retry_count[0] = 8;
997 
998 		nv->firmware_options_1[0] = BIT_2 | BIT_1;
999 		nv->firmware_options_1[1] = BIT_5;
1000 		nv->firmware_options_2[0] = BIT_5;
1001 		nv->firmware_options_2[1] = BIT_4;
1002 		nv->firmware_options_3[1] = BIT_6;
1003 
1004 		/*
1005 		 * Set default host adapter parameters
1006 		 */
1007 		nv->host_p[0] = BIT_4 | BIT_1;
1008 		nv->host_p[1] = BIT_3 | BIT_2;
1009 		nv->reset_delay = 5;
1010 		nv->max_luns_per_target[0] = 128;
1011 		nv->port_down_retry_count[0] = 30;
1012 		nv->link_down_timeout[0] = 30;
1013 
1014 		if (CFG_IST(ha, CFG_CTRL_81XX)) {
1015 			nv->firmware_options_3[2] = BIT_4;
1016 			nv->feature_mask_l[0] = 9;
1017 			nv->ext_blk.version[0] = 1;
1018 			nv->ext_blk.fcf_vlan_match = 1;
1019 			nv->ext_blk.fcf_vlan_id[0] = LSB(1002);
1020 			nv->ext_blk.fcf_vlan_id[1] = MSB(1002);
1021 		}
1022 
1023 		rval = QL_FUNCTION_FAILED;
1024 	}
1025 
1026 	/* Check for adapter node name (big endian). */
1027 	for (index = 0; index < 8; index++) {
1028 		if (nv->node_name[index] != 0) {
1029 			break;
1030 		}
1031 	}
1032 
1033 	/* Copy port name if no node name (big endian). */
1034 	if (index == 8) {
1035 		bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
1036 		nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
1037 		nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
1038 	}
1039 
1040 	/* Reset initialization control blocks. */
1041 	bzero((void *)icb, sizeof (ql_init_24xx_cb_t));
1042 
1043 	/* Get driver properties. */
1044 	ql_24xx_properties(ha, nv);
1045 
1046 	cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
1047 	    "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
1048 	    QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
1049 	    nv->port_name[2], nv->port_name[3], nv->port_name[4],
1050 	    nv->port_name[5], nv->port_name[6], nv->port_name[7],
1051 	    nv->node_name[0], nv->node_name[1], nv->node_name[2],
1052 	    nv->node_name[3], nv->node_name[4], nv->node_name[5],
1053 	    nv->node_name[6], nv->node_name[7]);
1054 
1055 	/*
1056 	 * Copy over NVRAM Firmware Initialization Control Block.
1057 	 */
1058 	dst = (caddr_t)icb;
1059 	src = (caddr_t)&nv->version;
1060 	index = (uint32_t)((uintptr_t)&icb->response_q_inpointer[0] -
1061 	    (uintptr_t)icb);
1062 	while (index--) {
1063 		*dst++ = *src++;
1064 	}
1065 	icb->login_retry_count[0] = nv->login_retry_count[0];
1066 	icb->login_retry_count[1] = nv->login_retry_count[1];
1067 	icb->link_down_on_nos[0] = nv->link_down_on_nos[0];
1068 	icb->link_down_on_nos[1] = nv->link_down_on_nos[1];
1069 
1070 	dst = (caddr_t)&icb->interrupt_delay_timer;
1071 	src = (caddr_t)&nv->interrupt_delay_timer;
1072 	index = (uint32_t)((uintptr_t)&icb->qos -
1073 	    (uintptr_t)&icb->interrupt_delay_timer);
1074 	while (index--) {
1075 		*dst++ = *src++;
1076 	}
1077 
1078 	/*
1079 	 * Setup driver firmware options.
1080 	 */
1081 	if (CFG_IST(ha, CFG_CTRL_81XX)) {
1082 		dst = (caddr_t)icb->enode_mac_addr;
1083 		src = (caddr_t)nv->mac_address;
1084 		index = sizeof (nv->mac_address);
1085 		while (index--) {
1086 			*dst++ = *src++;
1087 		}
1088 		dst = (caddr_t)&icb->ext_blk;
1089 		src = (caddr_t)&nv->ext_blk;
1090 		index = sizeof (ql_ext_icb_8100_t);
1091 		while (index--) {
1092 			*dst++ = *src++;
1093 		}
1094 	} else {
1095 		icb->firmware_options_1[0] = (uint8_t)
1096 		    (icb->firmware_options_1[0] | BIT_1);
1097 		icb->firmware_options_1[1] = (uint8_t)
1098 		    (icb->firmware_options_1[1] | BIT_5 | BIT_2);
1099 		icb->firmware_options_3[0] = (uint8_t)
1100 		    (icb->firmware_options_3[0] | BIT_1);
1101 	}
1102 	icb->firmware_options_1[0] = (uint8_t)(icb->firmware_options_1[0] &
1103 	    ~(BIT_5 | BIT_4));
1104 	icb->firmware_options_1[1] = (uint8_t)(icb->firmware_options_1[1] |
1105 	    BIT_6);
1106 	icb->firmware_options_2[0] = (uint8_t)(icb->firmware_options_2[0] &
1107 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
1108 	if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
1109 		icb->firmware_options_2[1] = (uint8_t)
1110 		    (icb->firmware_options_2[1] | BIT_4);
1111 	} else {
1112 		icb->firmware_options_2[1] = (uint8_t)
1113 		    (icb->firmware_options_2[1] & ~BIT_4);
1114 	}
1115 
1116 	icb->firmware_options_3[0] = (uint8_t)(icb->firmware_options_3[0] &
1117 	    ~BIT_7);
1118 
1119 	/* enable special N port 2 N port login behaviour */
1120 	if (CFG_IST(ha, CFG_CTRL_2425)) {
1121 		icb->firmware_options_3[1] =
1122 		    (uint8_t)(icb->firmware_options_3[1] | BIT_0);
1123 	}
1124 
1125 	icb->execution_throttle[0] = 0xff;
1126 	icb->execution_throttle[1] = 0xff;
1127 
1128 	/*
1129 	 * Set host adapter parameters
1130 	 */
1131 	ADAPTER_STATE_LOCK(ha);
1132 	ha->nvram_version = CHAR_TO_SHORT(nv->nvram_version[0],
1133 	    nv->nvram_version[1]);
1134 	nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
1135 	    (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
1136 	nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
1137 	    (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
1138 	ha->cfg_flags &= ~(CFG_DISABLE_RISC_CODE_LOAD |
1139 	    CFG_SET_CACHE_LINE_SIZE_1 | CFG_MULTI_CHIP_ADAPTER);
1140 	ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
1141 	ADAPTER_STATE_UNLOCK(ha);
1142 
1143 	ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
1144 	    nv->execution_throttle[1]);
1145 	ha->loop_reset_delay = nv->reset_delay;
1146 	ha->port_down_retry_count = CHAR_TO_SHORT(nv->port_down_retry_count[0],
1147 	    nv->port_down_retry_count[1]);
1148 	w1 = CHAR_TO_SHORT(icb->login_timeout[0], icb->login_timeout[1]);
1149 	ha->r_a_tov = (uint16_t)(w1 < R_A_TOV_DEFAULT ? R_A_TOV_DEFAULT : w1);
1150 	ha->maximum_luns_per_target = CHAR_TO_SHORT(
1151 	    nv->max_luns_per_target[0], nv->max_luns_per_target[1]);
1152 	if (ha->maximum_luns_per_target == 0) {
1153 		ha->maximum_luns_per_target++;
1154 	}
1155 
1156 	/* ISP2422 Serial Link Control */
1157 	if (CFG_IST(ha, CFG_CTRL_2422)) {
1158 		ha->serdes_param[0] = CHAR_TO_SHORT(nv->fw.isp2400.swing_opt[0],
1159 		    nv->fw.isp2400.swing_opt[1]);
1160 		ha->serdes_param[1] = CHAR_TO_SHORT(nv->fw.isp2400.swing_1g[0],
1161 		    nv->fw.isp2400.swing_1g[1]);
1162 		ha->serdes_param[2] = CHAR_TO_SHORT(nv->fw.isp2400.swing_2g[0],
1163 		    nv->fw.isp2400.swing_2g[1]);
1164 		ha->serdes_param[3] = CHAR_TO_SHORT(nv->fw.isp2400.swing_4g[0],
1165 		    nv->fw.isp2400.swing_4g[1]);
1166 	}
1167 
1168 	/*
1169 	 * Setup ring parameters in initialization control block
1170 	 */
1171 	w1 = REQUEST_ENTRY_CNT;
1172 	icb->request_q_length[0] = LSB(w1);
1173 	icb->request_q_length[1] = MSB(w1);
1174 	w1 = RESPONSE_ENTRY_CNT;
1175 	icb->response_q_length[0] = LSB(w1);
1176 	icb->response_q_length[1] = MSB(w1);
1177 
1178 	icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
1179 	icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
1180 	icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
1181 	icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
1182 	icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
1183 	icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
1184 	icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
1185 	icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
1186 
1187 	icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
1188 	icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
1189 	icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
1190 	icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
1191 	icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
1192 	icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
1193 	icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
1194 	icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
1195 
1196 	/*
1197 	 * Setup IP initialization control block
1198 	 */
1199 	ip_icb->version = IP_ICB_24XX_VERSION;
1200 
1201 	ip_icb->ip_firmware_options[0] = (uint8_t)
1202 	    (ip_icb->ip_firmware_options[0] | BIT_2);
1203 
1204 	if (rval != QL_SUCCESS) {
1205 		EL(ha, "failed, rval = %xh\n", rval);
1206 	} else {
1207 		/*EMPTY*/
1208 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1209 	}
1210 	return (rval);
1211 }
1212 
1213 /*
1214  * ql_lock_nvram
1215  *	Locks NVRAM access and returns starting address of NVRAM.
1216  *
1217  * Input:
1218  *	ha:	adapter state pointer.
1219  *	addr:	pointer for start address.
1220  *	flags:	Are mutually exclusive:
1221  *		LNF_NVRAM_DATA --> get nvram
1222  *		LNF_VPD_DATA --> get vpd data (24/25xx only).
1223  *
1224  * Returns:
1225  *	ql local function return status code.
1226  *
1227  * Context:
1228  *	Kernel context.
1229  */
1230 int
1231 ql_lock_nvram(ql_adapter_state_t *ha, uint32_t *addr, uint32_t flags)
1232 {
1233 	int	i;
1234 
1235 	if ((flags & LNF_NVRAM_DATA) && (flags & LNF_VPD_DATA)) {
1236 		EL(ha, "invalid options for function");
1237 		return (QL_FUNCTION_FAILED);
1238 	}
1239 
1240 	if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1241 		if ((flags & LNF_NVRAM_DATA) == 0) {
1242 			EL(ha, "invalid 2312/2322 option for HBA");
1243 			return (QL_FUNCTION_FAILED);
1244 		}
1245 
1246 		/* if function number is non-zero, then adjust offset */
1247 		*addr = ha->flash_nvram_addr;
1248 
1249 		/* Try to get resource lock. Wait for 10 seconds max */
1250 		for (i = 0; i < 10000; i++) {
1251 			/* if nvram busy bit is reset, acquire sema */
1252 			if ((RD16_IO_REG(ha, nvram) & 0x8000) == 0) {
1253 				WRT16_IO_REG(ha, host_to_host_sema, 1);
1254 				drv_usecwait(MILLISEC);
1255 				if (RD16_IO_REG(ha, host_to_host_sema) & 1) {
1256 					break;
1257 				}
1258 			}
1259 			drv_usecwait(MILLISEC);
1260 		}
1261 		if ((RD16_IO_REG(ha, host_to_host_sema) & 1) == 0) {
1262 			cmn_err(CE_WARN, "%s(%d): unable to get NVRAM lock",
1263 			    QL_NAME, ha->instance);
1264 			return (QL_FUNCTION_FAILED);
1265 		}
1266 	} else if (CFG_IST(ha, CFG_CTRL_2422)) {
1267 		if (flags & LNF_VPD_DATA) {
1268 			*addr = NVRAM_DATA_ADDR | ha->flash_vpd_addr;
1269 		} else if (flags & LNF_NVRAM_DATA) {
1270 			*addr = NVRAM_DATA_ADDR | ha->flash_nvram_addr;
1271 		} else {
1272 			EL(ha, "invalid 2422 option for HBA");
1273 			return (QL_FUNCTION_FAILED);
1274 		}
1275 
1276 		GLOBAL_HW_LOCK();
1277 	} else if (CFG_IST(ha, CFG_CTRL_2581)) {
1278 		if (flags & LNF_VPD_DATA) {
1279 			*addr = ha->flash_data_addr | ha->flash_vpd_addr;
1280 		} else if (flags & LNF_NVRAM_DATA) {
1281 			*addr = ha->flash_data_addr | ha->flash_nvram_addr;
1282 		} else {
1283 			EL(ha, "invalid 2581 option for HBA");
1284 			return (QL_FUNCTION_FAILED);
1285 		}
1286 
1287 		GLOBAL_HW_LOCK();
1288 	} else {
1289 		if ((flags & LNF_NVRAM_DATA) == 0) {
1290 			EL(ha, "invalid option for HBA");
1291 			return (QL_FUNCTION_FAILED);
1292 		}
1293 		*addr = 0;
1294 		GLOBAL_HW_LOCK();
1295 	}
1296 
1297 	return (QL_SUCCESS);
1298 }
1299 
1300 /*
1301  * ql_release_nvram
1302  *	Releases NVRAM access.
1303  *
1304  * Input:
1305  *	ha:	adapter state pointer.
1306  *
1307  * Context:
1308  *	Kernel context.
1309  */
1310 void
1311 ql_release_nvram(ql_adapter_state_t *ha)
1312 {
1313 	if (ha->device_id == 0x2312 || ha->device_id == 0x2322) {
1314 		/* Release resource lock */
1315 		WRT16_IO_REG(ha, host_to_host_sema, 0);
1316 	} else {
1317 		GLOBAL_HW_UNLOCK();
1318 	}
1319 }
1320 
1321 /*
1322  * ql_23_properties
1323  *	Copies driver properties to NVRAM or adapter structure.
1324  *
1325  *	Driver properties are by design global variables and hidden
1326  *	completely from administrators. Knowledgeable folks can
1327  *	override the default values using driver.conf
1328  *
1329  * Input:
1330  *	ha:	adapter state pointer.
1331  *	nv:	NVRAM structure pointer.
1332  *
1333  * Context:
1334  *	Kernel context.
1335  */
1336 static void
1337 ql_23_properties(ql_adapter_state_t *ha, nvram_t *nv)
1338 {
1339 	uint32_t	data, cnt;
1340 
1341 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1342 
1343 	/* Get frame payload size. */
1344 	if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1345 		data = 2048;
1346 	}
1347 	if (data == 512 || data == 1024 || data == 2048) {
1348 		nv->max_frame_length[0] = LSB(data);
1349 		nv->max_frame_length[1] = MSB(data);
1350 	} else {
1351 		EL(ha, "invalid parameter value for 'max-frame-length': "
1352 		    "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1353 		    nv->max_frame_length[0], nv->max_frame_length[1]));
1354 	}
1355 
1356 	/* Get max IOCB allocation. */
1357 	nv->max_iocb_allocation[0] = 0;
1358 	nv->max_iocb_allocation[1] = 1;
1359 
1360 	/* Get execution throttle. */
1361 	if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1362 		data = 32;
1363 	}
1364 	if (data != 0 && data < 65536) {
1365 		nv->execution_throttle[0] = LSB(data);
1366 		nv->execution_throttle[1] = MSB(data);
1367 	} else {
1368 		EL(ha, "invalid parameter value for 'execution-throttle': "
1369 		    "%d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1370 		    nv->execution_throttle[0], nv->execution_throttle[1]));
1371 	}
1372 
1373 	/* Get Login timeout. */
1374 	if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1375 		data = 3;
1376 	}
1377 	if (data < 256) {
1378 		nv->login_timeout = (uint8_t)data;
1379 	} else {
1380 		EL(ha, "invalid parameter value for 'login-timeout': "
1381 		    "%d; using nvram value of %d\n", data, nv->login_timeout);
1382 	}
1383 
1384 	/* Get retry count. */
1385 	if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1386 		data = 4;
1387 	}
1388 	if (data < 256) {
1389 		nv->login_retry_count = (uint8_t)data;
1390 	} else {
1391 		EL(ha, "invalid parameter value for 'login-retry-count': "
1392 		    "%d; using nvram value of %d\n", data,
1393 		    nv->login_retry_count);
1394 	}
1395 
1396 	/* Get adapter hard loop ID enable. */
1397 	data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1398 	if (data == 0) {
1399 		nv->firmware_options[0] =
1400 		    (uint8_t)(nv->firmware_options[0] & ~BIT_0);
1401 	} else if (data == 1) {
1402 		nv->firmware_options[0] =
1403 		    (uint8_t)(nv->firmware_options[0] | BIT_0);
1404 	} else if (data != 0xffffffff) {
1405 		EL(ha, "invalid parameter value for "
1406 		    "'enable-adapter-hard-loop-ID': %d; using nvram value "
1407 		    "of %d\n", data, nv->firmware_options[0] & BIT_0 ? 1 : 0);
1408 	}
1409 
1410 	/* Get adapter hard loop ID. */
1411 	data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1412 	if (data < 126) {
1413 		nv->hard_address[0] = (uint8_t)data;
1414 	} else if (data != 0xffffffff) {
1415 		EL(ha, "invalid parameter value for 'adapter-hard-loop-ID': "
1416 		    "%d; using nvram value of %d\n",
1417 		    data, nv->hard_address[0]);
1418 	}
1419 
1420 	/* Get LIP reset. */
1421 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1422 	    0xffffffff) {
1423 		data = 0;
1424 	}
1425 	if (data == 0) {
1426 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_1);
1427 	} else if (data == 1) {
1428 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_1);
1429 	} else {
1430 		EL(ha, "invalid parameter value for "
1431 		    "'enable-LIP-reset-on-bus-reset': %d; using nvram value "
1432 		    "of %d\n", data, nv->host_p[1] & BIT_1 ? 1 : 0);
1433 	}
1434 
1435 	/* Get LIP full login. */
1436 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1437 	    0xffffffff) {
1438 		data = 1;
1439 	}
1440 	if (data == 0) {
1441 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1442 	} else if (data == 1) {
1443 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1444 	} else {
1445 		EL(ha, "invalid parameter value for "
1446 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1447 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1448 	}
1449 
1450 	/* Get target reset. */
1451 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1452 	    0xffffffff) {
1453 		data = 0;
1454 	}
1455 	if (data == 0) {
1456 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1457 	} else if (data == 1) {
1458 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1459 	} else {
1460 		EL(ha, "invalid parameter value for "
1461 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1462 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1463 	}
1464 
1465 	/* Get reset delay. */
1466 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1467 		data = 5;
1468 	}
1469 	if (data != 0 && data < 256) {
1470 		nv->reset_delay = (uint8_t)data;
1471 	} else {
1472 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1473 		    "using nvram value of %d", data, nv->reset_delay);
1474 	}
1475 
1476 	/* Get port down retry count. */
1477 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1478 		data = 8;
1479 	}
1480 	if (data < 256) {
1481 		nv->port_down_retry_count = (uint8_t)data;
1482 	} else {
1483 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1484 		    " %d; using nvram value of %d\n", data,
1485 		    nv->port_down_retry_count);
1486 	}
1487 
1488 	/* Get connection mode setting. */
1489 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1490 		data = 2;
1491 	}
1492 	cnt = CFG_IST(ha, CFG_CTRL_2200) ? 3 : 2;
1493 	if (data <= cnt) {
1494 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] &
1495 		    ~(BIT_6 | BIT_5 | BIT_4));
1496 		nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
1497 		    (uint8_t)(data << 4));
1498 	} else {
1499 		EL(ha, "invalid parameter value for 'connection-options': "
1500 		    "%d; using nvram value of %d\n", data,
1501 		    (nv->add_fw_opt[0] >> 4) & 0x3);
1502 	}
1503 
1504 	/* Get data rate setting. */
1505 	if ((CFG_IST(ha, CFG_CTRL_2200)) == 0) {
1506 		if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1507 			data = 2;
1508 		}
1509 		if (data < 3) {
1510 			nv->special_options[1] = (uint8_t)
1511 			    (nv->special_options[1] & 0x3f);
1512 			nv->special_options[1] = (uint8_t)
1513 			    (nv->special_options[1] | (uint8_t)(data << 6));
1514 		} else {
1515 			EL(ha, "invalid parameter value for 'fc-data-rate': "
1516 			    "%d; using nvram value of %d\n", data,
1517 			    (nv->special_options[1] >> 6) & 0x3);
1518 		}
1519 	}
1520 
1521 	/* Get adapter id string for Sun branded 23xx only */
1522 	if ((CFG_IST(ha, CFG_CTRL_2300)) && nv->adapInfo[0] != 0) {
1523 		(void) snprintf((int8_t *)ha->adapInfo, 16, "%s",
1524 		    nv->adapInfo);
1525 	}
1526 
1527 	/* Get IP FW container count. */
1528 	ha->ip_init_ctrl_blk.cb.cc[0] = LSB(ql_ip_buffer_count);
1529 	ha->ip_init_ctrl_blk.cb.cc[1] = MSB(ql_ip_buffer_count);
1530 
1531 	/* Get IP low water mark. */
1532 	ha->ip_init_ctrl_blk.cb.low_water_mark[0] = LSB(ql_ip_low_water);
1533 	ha->ip_init_ctrl_blk.cb.low_water_mark[1] = MSB(ql_ip_low_water);
1534 
1535 	/* Get IP fast register post count. */
1536 	ha->ip_init_ctrl_blk.cb.fast_post_reg_count[0] =
1537 	    ql_ip_fast_post_count;
1538 
1539 	ADAPTER_STATE_LOCK(ha);
1540 
1541 	ql_common_properties(ha);
1542 
1543 	ADAPTER_STATE_UNLOCK(ha);
1544 
1545 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1546 }
1547 
1548 /*
1549  * ql_common_properties
1550  *	Driver properties adapter structure.
1551  *
1552  *	Driver properties are by design global variables and hidden
1553  *	completely from administrators. Knowledgeable folks can
1554  *	override the default values using driver.conf
1555  *
1556  * Input:
1557  *	ha:	adapter state pointer.
1558  *
1559  * Context:
1560  *	Kernel context.
1561  */
1562 void
1563 ql_common_properties(ql_adapter_state_t *ha)
1564 {
1565 	uint32_t	data;
1566 
1567 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1568 
1569 	/* Get extended logging trace buffer size. */
1570 	if ((data = ql_get_prop(ha, "set-ext-log-buffer-size")) !=
1571 	    0xffffffff && data != 0) {
1572 		char		*new_trace;
1573 		uint32_t	new_size;
1574 
1575 		if (ha->el_trace_desc->trace_buffer != NULL) {
1576 			new_size = 1024 * data;
1577 			new_trace = (char *)kmem_zalloc(new_size, KM_SLEEP);
1578 
1579 			if (new_trace == NULL) {
1580 				cmn_err(CE_WARN, "%s(%d): can't get new"
1581 				    " trace buffer",
1582 				    QL_NAME, ha->instance);
1583 			} else {
1584 				/* free the previous */
1585 				kmem_free(ha->el_trace_desc->trace_buffer,
1586 				    ha->el_trace_desc->trace_buffer_size);
1587 				/* Use the new one */
1588 				ha->el_trace_desc->trace_buffer = new_trace;
1589 				ha->el_trace_desc->trace_buffer_size = new_size;
1590 			}
1591 		}
1592 
1593 	}
1594 
1595 	/* Get extended logging enable. */
1596 	if ((data = ql_get_prop(ha, "extended-logging")) == 0xffffffff ||
1597 	    data == 0) {
1598 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1599 	} else if (data == 1) {
1600 		ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1601 	} else {
1602 		EL(ha, "invalid parameter value for 'extended-logging': %d;"
1603 		    " using default value of 0\n", data);
1604 		ha->cfg_flags &= ~CFG_ENABLE_EXTENDED_LOGGING;
1605 	}
1606 
1607 	/* Get extended logging trace disable. */
1608 	if ((data = ql_get_prop(ha, "disable-extended-logging-trace")) ==
1609 	    0xffffffff || data == 0) {
1610 		ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1611 	} else if (data == 1) {
1612 		ha->cfg_flags |= CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1613 	} else {
1614 		EL(ha, "invalid parameter value for "
1615 		    "'disable-extended-logging-trace': %d;"
1616 		    " using default value of 0\n", data);
1617 		ha->cfg_flags &= ~CFG_DISABLE_EXTENDED_LOGGING_TRACE;
1618 	}
1619 
1620 	/* Get FCP 2 Error Recovery. */
1621 	if ((data = ql_get_prop(ha, "enable-FCP-2-error-recovery")) ==
1622 	    0xffffffff || data == 1) {
1623 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1624 	} else if (data == 0) {
1625 		ha->cfg_flags &= ~CFG_ENABLE_FCP_2_SUPPORT;
1626 	} else {
1627 		EL(ha, "invalid parameter value for "
1628 		    "'enable-FCP-2-error-recovery': %d; using nvram value of "
1629 		    "1\n", data);
1630 		ha->cfg_flags |= CFG_ENABLE_FCP_2_SUPPORT;
1631 	}
1632 
1633 #ifdef QL_DEBUG_LEVEL_2
1634 	ha->cfg_flags |= CFG_ENABLE_EXTENDED_LOGGING;
1635 #endif
1636 
1637 	/* Get port down retry delay. */
1638 	if ((data = ql_get_prop(ha, "port-down-retry-delay")) == 0xffffffff) {
1639 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1640 	} else if (data < 256) {
1641 		ha->port_down_retry_delay = (uint8_t)data;
1642 	} else {
1643 		EL(ha, "invalid parameter value for 'port-down-retry-delay':"
1644 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1645 		ha->port_down_retry_delay = PORT_RETRY_TIME;
1646 	}
1647 
1648 	/* Get queue full retry count. */
1649 	if ((data = ql_get_prop(ha, "queue-full-retry-count")) == 0xffffffff) {
1650 		ha->qfull_retry_count = 16;
1651 	} else if (data < 256) {
1652 		ha->qfull_retry_count = (uint8_t)data;
1653 	} else {
1654 		EL(ha, "invalid parameter value for 'queue-full-retry-count':"
1655 		    " %d; using default value of 16", data);
1656 		ha->qfull_retry_count = 16;
1657 	}
1658 
1659 	/* Get queue full retry delay. */
1660 	if ((data = ql_get_prop(ha, "queue-full-retry-delay")) == 0xffffffff) {
1661 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1662 	} else if (data < 256) {
1663 		ha->qfull_retry_delay = (uint8_t)data;
1664 	} else {
1665 		EL(ha, "invalid parameter value for 'queue-full-retry-delay':"
1666 		    " %d; using default value of %d", data, PORT_RETRY_TIME);
1667 		ha->qfull_retry_delay = PORT_RETRY_TIME;
1668 	}
1669 
1670 	/* Get loop down timeout. */
1671 	if ((data = ql_get_prop(ha, "link-down-timeout")) == 0xffffffff) {
1672 		data = 0;
1673 	} else if (data > 255) {
1674 		EL(ha, "invalid parameter value for 'link-down-timeout': %d;"
1675 		    " using nvram value of 0\n", data);
1676 		data = 0;
1677 	}
1678 	ha->loop_down_abort_time = (uint8_t)(LOOP_DOWN_TIMER_START - data);
1679 	if (ha->loop_down_abort_time == LOOP_DOWN_TIMER_START) {
1680 		ha->loop_down_abort_time--;
1681 	} else if (ha->loop_down_abort_time <= LOOP_DOWN_TIMER_END) {
1682 		ha->loop_down_abort_time = LOOP_DOWN_TIMER_END + 1;
1683 	}
1684 
1685 	/* Get link down error enable. */
1686 	if ((data = ql_get_prop(ha, "enable-link-down-error")) == 0xffffffff ||
1687 	    data == 1) {
1688 		ha->cfg_flags |= CFG_ENABLE_LINK_DOWN_REPORTING;
1689 	} else if (data == 0) {
1690 		ha->cfg_flags &= ~CFG_ENABLE_LINK_DOWN_REPORTING;
1691 	} else {
1692 		EL(ha, "invalid parameter value for 'link-down-error': %d;"
1693 		    " using default value of 1\n", data);
1694 	}
1695 
1696 	/*
1697 	 * Get firmware dump flags.
1698 	 *	TAKE_FW_DUMP_ON_MAILBOX_TIMEOUT		BIT_0
1699 	 *	TAKE_FW_DUMP_ON_ISP_SYSTEM_ERROR	BIT_1
1700 	 *	TAKE_FW_DUMP_ON_DRIVER_COMMAND_TIMEOUT	BIT_2
1701 	 *	TAKE_FW_DUMP_ON_LOOP_OFFLINE_TIMEOUT	BIT_3
1702 	 */
1703 	ha->cfg_flags &= ~(CFG_DUMP_MAILBOX_TIMEOUT |
1704 	    CFG_DUMP_ISP_SYSTEM_ERROR | CFG_DUMP_DRIVER_COMMAND_TIMEOUT |
1705 	    CFG_DUMP_LOOP_OFFLINE_TIMEOUT);
1706 	if ((data = ql_get_prop(ha, "firmware-dump-flags")) != 0xffffffff) {
1707 		if (data & BIT_0) {
1708 			ha->cfg_flags |= CFG_DUMP_MAILBOX_TIMEOUT;
1709 		}
1710 		if (data & BIT_1) {
1711 			ha->cfg_flags |= CFG_DUMP_ISP_SYSTEM_ERROR;
1712 		}
1713 		if (data & BIT_2) {
1714 			ha->cfg_flags |= CFG_DUMP_DRIVER_COMMAND_TIMEOUT;
1715 		}
1716 		if (data & BIT_3) {
1717 			ha->cfg_flags |= CFG_DUMP_LOOP_OFFLINE_TIMEOUT;
1718 		}
1719 	}
1720 
1721 	/* Get the PCI max read request size override. */
1722 	ha->pci_max_read_req = 0;
1723 	if ((data = ql_get_prop(ha, "pci-max-read-request")) != 0xffffffff &&
1724 	    data != 0) {
1725 		ha->pci_max_read_req = (uint16_t)(data);
1726 	}
1727 
1728 	/* Get the attach fw_ready override value. */
1729 	ha->fwwait = 10;
1730 	if ((data = ql_get_prop(ha, "init-loop-sync-wait")) != 0xffffffff) {
1731 		if (data > 0 && data <= 240) {
1732 			ha->fwwait = (uint8_t)data;
1733 		} else {
1734 			EL(ha, "invalid parameter value for "
1735 			    "'init-loop-sync-wait': %d; using default "
1736 			    "value of %d\n", data, ha->fwwait);
1737 		}
1738 	}
1739 
1740 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1741 }
1742 
1743 /*
1744  * ql_24xx_properties
1745  *	Copies driver properties to NVRAM or adapter structure.
1746  *
1747  *	Driver properties are by design global variables and hidden
1748  *	completely from administrators. Knowledgeable folks can
1749  *	override the default values using /etc/system.
1750  *
1751  * Input:
1752  *	ha:	adapter state pointer.
1753  *	nv:	NVRAM structure pointer.
1754  *
1755  * Context:
1756  *	Kernel context.
1757  */
1758 static void
1759 ql_24xx_properties(ql_adapter_state_t *ha, nvram_24xx_t *nv)
1760 {
1761 	uint32_t	data;
1762 
1763 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
1764 
1765 	/* Get frame size */
1766 	if ((data = ql_get_prop(ha, "max-frame-length")) == 0xffffffff) {
1767 		data = 2048;
1768 	}
1769 	if (data == 512 || data == 1024 || data == 2048) {
1770 		nv->max_frame_length[0] = LSB(data);
1771 		nv->max_frame_length[1] = MSB(data);
1772 	} else {
1773 		EL(ha, "invalid parameter value for 'max-frame-length': %d;"
1774 		    " using nvram default of %d\n", data, CHAR_TO_SHORT(
1775 		    nv->max_frame_length[0], nv->max_frame_length[1]));
1776 	}
1777 
1778 	/* Get execution throttle. */
1779 	if ((data = ql_get_prop(ha, "execution-throttle")) == 0xffffffff) {
1780 		data = 32;
1781 	}
1782 	if (data != 0 && data < 65536) {
1783 		nv->execution_throttle[0] = LSB(data);
1784 		nv->execution_throttle[1] = MSB(data);
1785 	} else {
1786 		EL(ha, "invalid parameter value for 'execution-throttle':"
1787 		    " %d; using nvram default of %d\n", data, CHAR_TO_SHORT(
1788 		    nv->execution_throttle[0], nv->execution_throttle[1]));
1789 	}
1790 
1791 	/* Get Login timeout. */
1792 	if ((data = ql_get_prop(ha, "login-timeout")) == 0xffffffff) {
1793 		data = 3;
1794 	}
1795 	if (data < 65536) {
1796 		nv->login_timeout[0] = LSB(data);
1797 		nv->login_timeout[1] = MSB(data);
1798 	} else {
1799 		EL(ha, "invalid parameter value for 'login-timeout': %d; "
1800 		    "using nvram value of %d\n", data, CHAR_TO_SHORT(
1801 		    nv->login_timeout[0], nv->login_timeout[1]));
1802 	}
1803 
1804 	/* Get retry count. */
1805 	if ((data = ql_get_prop(ha, "login-retry-count")) == 0xffffffff) {
1806 		data = 4;
1807 	}
1808 	if (data < 65536) {
1809 		nv->login_retry_count[0] = LSB(data);
1810 		nv->login_retry_count[1] = MSB(data);
1811 	} else {
1812 		EL(ha, "invalid parameter value for 'login-retry-count': "
1813 		    "%d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1814 		    nv->login_retry_count[0], nv->login_retry_count[1]));
1815 	}
1816 
1817 	/* Get adapter hard loop ID enable. */
1818 	data =  ql_get_prop(ha, "enable-adapter-hard-loop-ID");
1819 	if (data == 0) {
1820 		nv->firmware_options_1[0] =
1821 		    (uint8_t)(nv->firmware_options_1[0] & ~BIT_0);
1822 	} else if (data == 1) {
1823 		nv->firmware_options_1[0] =
1824 		    (uint8_t)(nv->firmware_options_1[0] | BIT_0);
1825 	} else if (data != 0xffffffff) {
1826 		EL(ha, "invalid parameter value for "
1827 		    "'enable-adapter-hard-loop-ID': %d; using nvram value "
1828 		    "of %d\n", data,
1829 		    nv->firmware_options_1[0] & BIT_0 ? 1 : 0);
1830 	}
1831 
1832 	/* Get adapter hard loop ID. */
1833 	data =  ql_get_prop(ha, "adapter-hard-loop-ID");
1834 	if (data < 126) {
1835 		nv->hard_address[0] = LSB(data);
1836 		nv->hard_address[1] = MSB(data);
1837 	} else if (data != 0xffffffff) {
1838 		EL(ha, "invalid parameter value for 'adapter-hard-loop-ID':"
1839 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1840 		    nv->hard_address[0], nv->hard_address[1]));
1841 	}
1842 
1843 	/* Get LIP reset. */
1844 	if ((data = ql_get_prop(ha, "enable-LIP-reset-on-bus-reset")) ==
1845 	    0xffffffff) {
1846 		data = 0;
1847 	}
1848 	if (data == 0) {
1849 		ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET;
1850 	} else if (data == 1) {
1851 		ha->cfg_flags |= CFG_ENABLE_LIP_RESET;
1852 	} else {
1853 		EL(ha, "invalid parameter value for "
1854 		    "'enable-LIP-reset-on-bus-reset': %d; using value of 0\n",
1855 		    data);
1856 	}
1857 
1858 	/* Get LIP full login. */
1859 	if ((data = ql_get_prop(ha, "enable-LIP-full-login-on-bus-reset")) ==
1860 	    0xffffffff) {
1861 		data = 1;
1862 	}
1863 	if (data == 0) {
1864 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_2);
1865 	} else if (data == 1) {
1866 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_2);
1867 	} else {
1868 		EL(ha, "invalid parameter value for "
1869 		    "'enable-LIP-full-login-on-bus-reset': %d; using nvram "
1870 		    "value of %d\n", data, nv->host_p[1] & BIT_2 ? 1 : 0);
1871 	}
1872 
1873 	/* Get target reset. */
1874 	if ((data = ql_get_prop(ha, "enable-target-reset-on-bus-reset")) ==
1875 	    0xffffffff) {
1876 		data = 0;
1877 	}
1878 	if (data == 0) {
1879 		nv->host_p[1] = (uint8_t)(nv->host_p[1] & ~BIT_3);
1880 	} else if (data == 1) {
1881 		nv->host_p[1] = (uint8_t)(nv->host_p[1] | BIT_3);
1882 	} else {
1883 		EL(ha, "invalid parameter value for "
1884 		    "'enable-target-reset-on-bus-reset': %d; using nvram "
1885 		    "value of %d", data, nv->host_p[1] & BIT_3 ? 1 : 0);
1886 	}
1887 
1888 	/* Get reset delay. */
1889 	if ((data = ql_get_prop(ha, "reset-delay")) == 0xffffffff) {
1890 		data = 5;
1891 	}
1892 	if (data != 0 && data < 256) {
1893 		nv->reset_delay = (uint8_t)data;
1894 	} else {
1895 		EL(ha, "invalid parameter value for 'reset-delay': %d; "
1896 		    "using nvram value of %d", data, nv->reset_delay);
1897 	}
1898 
1899 	/* Get port down retry count. */
1900 	if ((data = ql_get_prop(ha, "port-down-retry-count")) == 0xffffffff) {
1901 		data = 8;
1902 	}
1903 	if (data < 256) {
1904 		nv->port_down_retry_count[0] = LSB(data);
1905 		nv->port_down_retry_count[1] = MSB(data);
1906 	} else {
1907 		EL(ha, "invalid parameter value for 'port-down-retry-count':"
1908 		    " %d; using nvram value of %d\n", data, CHAR_TO_SHORT(
1909 		    nv->port_down_retry_count[0],
1910 		    nv->port_down_retry_count[1]));
1911 	}
1912 
1913 	/* Get connection mode setting. */
1914 	if ((data = ql_get_prop(ha, "connection-options")) == 0xffffffff) {
1915 		data = 2;
1916 	}
1917 	if (data <= 2) {
1918 		nv->firmware_options_2[0] = (uint8_t)
1919 		    (nv->firmware_options_2[0] & ~(BIT_6 | BIT_5 | BIT_4));
1920 		nv->firmware_options_2[0] = (uint8_t)
1921 		    (nv->firmware_options_2[0] | (uint8_t)(data << 4));
1922 	} else {
1923 		EL(ha, "invalid parameter value for 'connection-options':"
1924 		    " %d; using nvram value of %d\n", data,
1925 		    (nv->firmware_options_2[0] >> 4) & 0x3);
1926 	}
1927 
1928 	/* Get data rate setting. */
1929 	if ((data = ql_get_prop(ha, "fc-data-rate")) == 0xffffffff) {
1930 		data = 2;
1931 	}
1932 	if ((CFG_IST(ha, CFG_CTRL_2422) && data < 4) ||
1933 	    (CFG_IST(ha, CFG_CTRL_2581) && data < 5)) {
1934 		nv->firmware_options_3[1] = (uint8_t)
1935 		    (nv->firmware_options_3[1] & 0x1f);
1936 		nv->firmware_options_3[1] = (uint8_t)
1937 		    (nv->firmware_options_3[1] | (uint8_t)(data << 5));
1938 	} else {
1939 		EL(ha, "invalid parameter value for 'fc-data-rate': %d; "
1940 		    "using nvram value of %d\n", data,
1941 		    (nv->firmware_options_3[1] >> 5) & 0x7);
1942 	}
1943 
1944 	/* Get IP FW container count. */
1945 	ha->ip_init_ctrl_blk.cb24.cc[0] = LSB(ql_ip_buffer_count);
1946 	ha->ip_init_ctrl_blk.cb24.cc[1] = MSB(ql_ip_buffer_count);
1947 
1948 	/* Get IP low water mark. */
1949 	ha->ip_init_ctrl_blk.cb24.low_water_mark[0] = LSB(ql_ip_low_water);
1950 	ha->ip_init_ctrl_blk.cb24.low_water_mark[1] = MSB(ql_ip_low_water);
1951 
1952 	ADAPTER_STATE_LOCK(ha);
1953 
1954 	/* Get enable flash load. */
1955 	if ((data = ql_get_prop(ha, "enable-flash-load")) == 0xffffffff ||
1956 	    data == 0) {
1957 		ha->cfg_flags &= ~CFG_LOAD_FLASH_FW;
1958 	} else if (data == 1) {
1959 		ha->cfg_flags |= CFG_LOAD_FLASH_FW;
1960 	} else {
1961 		EL(ha, "invalid parameter value for 'enable-flash-load': "
1962 		    "%d; using default value of 0\n", data);
1963 	}
1964 
1965 	/* Enable firmware extended tracing */
1966 	if ((data = ql_get_prop(ha, "enable-fwexttrace")) != 0xffffffff) {
1967 		if (data != 0) {
1968 			ha->cfg_flags |= CFG_ENABLE_FWEXTTRACE;
1969 		}
1970 	}
1971 
1972 	/* Enable firmware fc tracing */
1973 	if ((data = ql_get_prop(ha, "enable-fwfcetrace")) != 0xffffffff) {
1974 		ha->cfg_flags |= CFG_ENABLE_FWFCETRACE;
1975 		ha->fwfcetraceopt = data;
1976 	}
1977 
1978 	ql_common_properties(ha);
1979 
1980 	ADAPTER_STATE_UNLOCK(ha);
1981 
1982 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
1983 }
1984 
1985 /*
1986  * ql_get_prop
1987  *	Get property value from configuration file.
1988  *
1989  * Input:
1990  *	ha= adapter state pointer.
1991  *	string = property string pointer.
1992  *
1993  * Returns:
1994  *	0xFFFFFFFF = no property else property value.
1995  *
1996  * Context:
1997  *	Kernel context.
1998  */
1999 uint32_t
2000 ql_get_prop(ql_adapter_state_t *ha, char *string)
2001 {
2002 	char		buf[256];
2003 	uint32_t	data = 0xffffffff;
2004 
2005 	/*
2006 	 * Look for a adapter instance NPIV (virtual port) specific parameter
2007 	 */
2008 	if (CFG_IST(ha, CFG_CTRL_242581)) {
2009 		(void) sprintf(buf, "hba%d-vp%d-%s", ha->instance,
2010 		    ha->vp_index, string);
2011 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2012 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2013 		    buf, (int)0xffffffff);
2014 	}
2015 
2016 	/*
2017 	 * Get adapter instance parameter if a vp specific one isn't found.
2018 	 */
2019 	if (data == 0xffffffff) {
2020 		(void) sprintf(buf, "hba%d-%s", ha->instance, string);
2021 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2022 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip,
2023 		    0, buf, (int)0xffffffff);
2024 	}
2025 
2026 	/* Adapter instance parameter found? */
2027 	if (data == 0xffffffff) {
2028 		/* No, get default parameter. */
2029 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
2030 		data = (uint32_t)ddi_prop_get_int(DDI_DEV_T_ANY, ha->dip, 0,
2031 		    string, (int)0xffffffff);
2032 	}
2033 
2034 	return (data);
2035 }
2036 
2037 /*
2038  * ql_check_isp_firmware
2039  *	Checks if using already loaded RISC code or drivers copy.
2040  *	If using already loaded code, save a copy of it.
2041  *
2042  * Input:
2043  *	ha = adapter state pointer.
2044  *
2045  * Returns:
2046  *	ql local function return status code.
2047  *
2048  * Context:
2049  *	Kernel context.
2050  */
2051 static int
2052 ql_check_isp_firmware(ql_adapter_state_t *ha)
2053 {
2054 	int		rval;
2055 	uint16_t	word_count;
2056 	uint32_t	byte_count;
2057 	uint32_t	fw_size, *lptr;
2058 	caddr_t		bufp;
2059 	uint16_t	risc_address = (uint16_t)ha->risc_fw[0].addr;
2060 
2061 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2062 
2063 	if (CFG_IST(ha, CFG_DISABLE_RISC_CODE_LOAD)) {
2064 		if (ha->risc_code != NULL) {
2065 			kmem_free(ha->risc_code, ha->risc_code_size);
2066 			ha->risc_code = NULL;
2067 			ha->risc_code_size = 0;
2068 		}
2069 
2070 		/* Get RISC code length. */
2071 		rval = ql_rd_risc_ram(ha, risc_address + 3, ha->request_dvma,
2072 		    1);
2073 		if (rval == QL_SUCCESS) {
2074 			lptr = (uint32_t *)ha->request_ring_bp;
2075 			fw_size = *lptr << 1;
2076 
2077 			if ((bufp = kmem_alloc(fw_size, KM_SLEEP)) != NULL) {
2078 				ha->risc_code_size = fw_size;
2079 				ha->risc_code = bufp;
2080 				ha->fw_transfer_size = 128;
2081 
2082 				/* Dump RISC code. */
2083 				do {
2084 					if (fw_size > ha->fw_transfer_size) {
2085 						byte_count =
2086 						    ha->fw_transfer_size;
2087 					} else {
2088 						byte_count = fw_size;
2089 					}
2090 
2091 					word_count =
2092 					    (uint16_t)(byte_count >> 1);
2093 
2094 					rval = ql_rd_risc_ram(ha, risc_address,
2095 					    ha->request_dvma, word_count);
2096 					if (rval != QL_SUCCESS) {
2097 						kmem_free(ha->risc_code,
2098 						    ha->risc_code_size);
2099 						ha->risc_code = NULL;
2100 						ha->risc_code_size = 0;
2101 						break;
2102 					}
2103 
2104 					(void) ddi_dma_sync(
2105 					    ha->hba_buf.dma_handle,
2106 					    REQUEST_Q_BUFFER_OFFSET,
2107 					    byte_count,
2108 					    DDI_DMA_SYNC_FORKERNEL);
2109 					ddi_rep_get16(ha->hba_buf.acc_handle,
2110 					    (uint16_t *)bufp,
2111 					    (uint16_t *)ha->request_ring_bp,
2112 					    word_count, DDI_DEV_AUTOINCR);
2113 
2114 					risc_address += word_count;
2115 					fw_size -= byte_count;
2116 					bufp	+= byte_count;
2117 				} while (fw_size != 0);
2118 			}
2119 		}
2120 	} else {
2121 		rval = QL_FUNCTION_FAILED;
2122 	}
2123 
2124 	if (rval != QL_SUCCESS) {
2125 		EL(ha, "Load RISC code\n");
2126 	} else {
2127 		/*EMPTY*/
2128 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2129 	}
2130 	return (rval);
2131 }
2132 
2133 /*
2134  * Chip diagnostics
2135  *	Test chip for proper operation.
2136  *
2137  * Input:
2138  *	ha = adapter state pointer.
2139  *
2140  * Returns:
2141  *	ql local function return status code.
2142  *
2143  * Context:
2144  *	Kernel context.
2145  */
2146 static int
2147 ql_chip_diag(ql_adapter_state_t *ha)
2148 {
2149 	ql_mbx_data_t	mr;
2150 	int32_t		rval = QL_FUNCTION_FAILED;
2151 	int32_t		retries = 4;
2152 	uint16_t	id;
2153 
2154 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2155 
2156 	do {
2157 		/* Reset ISP chip. */
2158 		TASK_DAEMON_LOCK(ha);
2159 		ha->task_daemon_flags &= ~ISP_ABORT_NEEDED;
2160 		TASK_DAEMON_UNLOCK(ha);
2161 		ql_reset_chip(ha);
2162 
2163 		/* For ISP2200A reduce firmware load size. */
2164 		if (CFG_IST(ha, CFG_CTRL_2200) &&
2165 		    RD16_IO_REG(ha, mailbox[7]) == 4) {
2166 			ha->fw_transfer_size = 128;
2167 		} else {
2168 			ha->fw_transfer_size = REQUEST_QUEUE_SIZE;
2169 		}
2170 
2171 		/* Check product ID of chip */
2172 		mr.mb[1] = RD16_IO_REG(ha, mailbox[1]);
2173 		mr.mb[2] = RD16_IO_REG(ha, mailbox[2]);
2174 		mr.mb[3] = RD16_IO_REG(ha, mailbox[3]);
2175 
2176 		if (ha->device_id == 0x5432 || ha->device_id == 0x8432) {
2177 			id = 0x2432;
2178 		} else if (ha->device_id == 0x5422 ||
2179 		    ha->device_id == 0x8422) {
2180 			id = 0x2422;
2181 		} else {
2182 			id = ha->device_id;
2183 		}
2184 
2185 		if (mr.mb[1] == PROD_ID_1 &&
2186 		    (mr.mb[2] == PROD_ID_2 || mr.mb[2] == PROD_ID_2a) &&
2187 		    (mr.mb[3] == PROD_ID_3 || mr.mb[3] == id)) {
2188 
2189 			ha->adapter_stats->revlvl.isp2200 = RD16_IO_REG(ha,
2190 			    mailbox[4]);
2191 			ha->adapter_stats->revlvl.risc = RD16_IO_REG(ha,
2192 			    mailbox[5]);
2193 			ha->adapter_stats->revlvl.frmbfr = RD16_IO_REG(ha,
2194 			    mailbox[6]);
2195 			ha->adapter_stats->revlvl.riscrom = RD16_IO_REG(ha,
2196 			    mailbox[7]);
2197 			bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
2198 			    strlen(QL_VERSION));
2199 
2200 			/* Wrap Incoming Mailboxes Test. */
2201 			mr.mb[1] = 0xAAAA;
2202 			mr.mb[2] = 0x5555;
2203 			mr.mb[3] = 0xAA55;
2204 			mr.mb[4] = 0x55AA;
2205 			mr.mb[5] = 0xA5A5;
2206 			mr.mb[6] = 0x5A5A;
2207 			mr.mb[7] = 0x2525;
2208 			rval = ql_mbx_wrap_test(ha, &mr);
2209 			if (rval == QL_SUCCESS) {
2210 				if (mr.mb[1] != 0xAAAA ||
2211 				    mr.mb[2] != 0x5555 ||
2212 				    mr.mb[3] != 0xAA55 ||
2213 				    mr.mb[4] != 0x55AA ||
2214 				    mr.mb[5] != 0xA5A5 ||
2215 				    mr.mb[6] != 0x5A5A ||
2216 				    mr.mb[7] != 0x2525) {
2217 					rval = QL_FUNCTION_FAILED;
2218 					(void) ql_flash_errlog(ha,
2219 					    FLASH_ERRLOG_ISP_ERR, 0,
2220 					    RD16_IO_REG(ha, hccr),
2221 					    RD16_IO_REG(ha, istatus));
2222 				}
2223 			} else {
2224 				cmn_err(CE_WARN, "%s(%d) - reg test failed="
2225 				    "%xh!", QL_NAME, ha->instance, rval);
2226 			}
2227 		} else {
2228 			cmn_err(CE_WARN, "%s(%d) - prod id failed!, mb1=%xh, "
2229 			    "mb2=%xh, mb3=%xh", QL_NAME, ha->instance,
2230 			    mr.mb[1], mr.mb[2], mr.mb[3]);
2231 		}
2232 	} while ((retries-- != 0) && (rval != QL_SUCCESS));
2233 
2234 	if (rval != QL_SUCCESS) {
2235 		EL(ha, "failed, rval = %xh\n", rval);
2236 	} else {
2237 		/*EMPTY*/
2238 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2239 	}
2240 	return (rval);
2241 }
2242 
2243 /*
2244  * ql_load_isp_firmware
2245  *	Load and start RISC firmware.
2246  *	Uses request ring for DMA buffer.
2247  *
2248  * Input:
2249  *	ha = adapter state pointer.
2250  *
2251  * Returns:
2252  *	ql local function return status code.
2253  *
2254  * Context:
2255  *	Kernel context.
2256  */
2257 int
2258 ql_load_isp_firmware(ql_adapter_state_t *vha)
2259 {
2260 	caddr_t			risc_code_address;
2261 	uint32_t		risc_address, risc_code_size;
2262 	int			rval;
2263 	uint32_t		word_count, cnt;
2264 	size_t			byte_count;
2265 	ql_adapter_state_t	*ha = vha->pha;
2266 
2267 	if (CFG_IST(ha, CFG_LOAD_FLASH_FW)) {
2268 		return (ql_load_flash_fw(ha));
2269 	}
2270 
2271 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2272 
2273 	/* Load firmware segments */
2274 	for (cnt = 0; cnt < MAX_RISC_CODE_SEGMENTS &&
2275 	    ha->risc_fw[cnt].code != NULL; cnt++) {
2276 
2277 		risc_code_address = ha->risc_fw[cnt].code;
2278 		risc_address = ha->risc_fw[cnt].addr;
2279 		risc_code_size = ha->risc_fw[cnt].length;
2280 
2281 		while (risc_code_size) {
2282 			if (CFG_IST(ha, CFG_CTRL_242581)) {
2283 				word_count = ha->fw_transfer_size >> 2;
2284 				if (word_count > risc_code_size) {
2285 					word_count = risc_code_size;
2286 				}
2287 				byte_count = word_count << 2;
2288 
2289 				ddi_rep_put32(ha->hba_buf.acc_handle,
2290 				    (uint32_t *)risc_code_address,
2291 				    (uint32_t *)ha->request_ring_bp,
2292 				    word_count, DDI_DEV_AUTOINCR);
2293 			} else {
2294 				word_count = ha->fw_transfer_size >> 1;
2295 				if (word_count > risc_code_size) {
2296 					word_count = risc_code_size;
2297 				}
2298 				byte_count = word_count << 1;
2299 
2300 				ddi_rep_put16(ha->hba_buf.acc_handle,
2301 				    (uint16_t *)risc_code_address,
2302 				    (uint16_t *)ha->request_ring_bp,
2303 				    word_count, DDI_DEV_AUTOINCR);
2304 			}
2305 
2306 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2307 			    REQUEST_Q_BUFFER_OFFSET, byte_count,
2308 			    DDI_DMA_SYNC_FORDEV);
2309 
2310 			rval = ql_wrt_risc_ram(ha, risc_address,
2311 			    ha->request_dvma, word_count);
2312 			if (rval != QL_SUCCESS) {
2313 				EL(ha, "failed, load=%xh\n", rval);
2314 				cnt = MAX_RISC_CODE_SEGMENTS;
2315 				break;
2316 			}
2317 
2318 			risc_address += word_count;
2319 			risc_code_size -= word_count;
2320 			risc_code_address += byte_count;
2321 		}
2322 	}
2323 
2324 	/* Start firmware. */
2325 	if (rval == QL_SUCCESS) {
2326 		rval = ql_start_firmware(ha);
2327 	}
2328 
2329 	if (rval != QL_SUCCESS) {
2330 		EL(ha, "failed, rval = %xh\n", rval);
2331 	} else {
2332 		/*EMPTY*/
2333 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2334 	}
2335 
2336 	return (rval);
2337 }
2338 
2339 /*
2340  * ql_load_flash_fw
2341  *	Gets ISP24xx firmware from flash and loads ISP.
2342  *
2343  * Input:
2344  *	ha:	adapter state pointer.
2345  *
2346  * Returns:
2347  *	ql local function return status code.
2348  */
2349 static int
2350 ql_load_flash_fw(ql_adapter_state_t *ha)
2351 {
2352 	int		rval;
2353 	uint8_t		seg_cnt;
2354 	uint32_t	risc_address, xfer_size, count,	*bp, faddr;
2355 	uint32_t	risc_code_size = 0;
2356 
2357 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2358 
2359 	faddr = ha->flash_data_addr | ha->flash_fw_addr;
2360 
2361 	for (seg_cnt = 0; seg_cnt < 2; seg_cnt++) {
2362 		xfer_size = ha->fw_transfer_size >> 2;
2363 		do {
2364 			GLOBAL_HW_LOCK();
2365 
2366 			/* Read data from flash. */
2367 			bp = (uint32_t *)ha->request_ring_bp;
2368 			for (count = 0; count < xfer_size; count++) {
2369 				rval = ql_24xx_read_flash(ha, faddr++, bp);
2370 				if (rval != QL_SUCCESS) {
2371 					break;
2372 				}
2373 				ql_chg_endian((uint8_t *)bp++, 4);
2374 			}
2375 
2376 			GLOBAL_HW_UNLOCK();
2377 
2378 			if (rval != QL_SUCCESS) {
2379 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
2380 				break;
2381 			}
2382 
2383 			if (risc_code_size == 0) {
2384 				bp = (uint32_t *)ha->request_ring_bp;
2385 				risc_address = bp[2];
2386 				risc_code_size = bp[3];
2387 				ha->risc_fw[seg_cnt].addr = risc_address;
2388 			}
2389 
2390 			if (risc_code_size < xfer_size) {
2391 				faddr -= xfer_size - risc_code_size;
2392 				xfer_size = risc_code_size;
2393 			}
2394 
2395 			(void) ddi_dma_sync(ha->hba_buf.dma_handle,
2396 			    REQUEST_Q_BUFFER_OFFSET, xfer_size << 2,
2397 			    DDI_DMA_SYNC_FORDEV);
2398 
2399 			rval = ql_wrt_risc_ram(ha, risc_address,
2400 			    ha->request_dvma, xfer_size);
2401 			if (rval != QL_SUCCESS) {
2402 				EL(ha, "ql_wrt_risc_ram failed=%xh\n", rval);
2403 				break;
2404 			}
2405 
2406 			risc_address += xfer_size;
2407 			risc_code_size -= xfer_size;
2408 		} while (risc_code_size);
2409 
2410 		if (rval != QL_SUCCESS) {
2411 			break;
2412 		}
2413 	}
2414 
2415 	/* Start firmware. */
2416 	if (rval == QL_SUCCESS) {
2417 		rval = ql_start_firmware(ha);
2418 	}
2419 
2420 	if (rval != QL_SUCCESS) {
2421 		EL(ha, "failed, rval = %xh\n", rval);
2422 	} else {
2423 		/*EMPTY*/
2424 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2425 	}
2426 	return (rval);
2427 }
2428 
2429 /*
2430  * ql_start_firmware
2431  *	Starts RISC code.
2432  *
2433  * Input:
2434  *	ha = adapter state pointer.
2435  *
2436  * Returns:
2437  *	ql local function return status code.
2438  *
2439  * Context:
2440  *	Kernel context.
2441  */
2442 int
2443 ql_start_firmware(ql_adapter_state_t *vha)
2444 {
2445 	int			rval, rval2;
2446 	uint32_t		data;
2447 	ql_mbx_data_t		mr;
2448 	ql_adapter_state_t	*ha = vha->pha;
2449 
2450 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2451 
2452 	/* Verify checksum of loaded RISC code. */
2453 	rval = ql_verify_checksum(ha);
2454 	if (rval == QL_SUCCESS) {
2455 		/* Start firmware execution. */
2456 		(void) ql_execute_fw(ha);
2457 
2458 		/* Save firmware version. */
2459 		(void) ql_get_fw_version(ha, &mr);
2460 		ha->fw_major_version = mr.mb[1];
2461 		ha->fw_minor_version = mr.mb[2];
2462 		ha->fw_subminor_version = mr.mb[3];
2463 		ha->fw_ext_memory_size = ((SHORT_TO_LONG(mr.mb[4], mr.mb[5]) -
2464 		    0x100000) + 1) * 4;
2465 		ha->fw_attributes = mr.mb[6];
2466 
2467 		if (CFG_IST(ha, CFG_CTRL_81XX)) {
2468 			ha->phy_fw_major_version = LSB(mr.mb[8]);
2469 			ha->phy_fw_minor_version = MSB(mr.mb[9]);
2470 			ha->phy_fw_subminor_version = LSB(mr.mb[9]);
2471 			ha->mpi_fw_major_version = LSB(mr.mb[10]);
2472 			ha->mpi_fw_minor_version = MSB(mr.mb[11]);
2473 			ha->mpi_fw_subminor_version = LSB(mr.mb[11]);
2474 			ha->mpi_capability_list = SHORT_TO_LONG(mr.mb[13],
2475 			    mr.mb[12]);
2476 			if ((rval2 = ql_flash_access(ha, FAC_GET_SECTOR_SIZE,
2477 			    0, 0, &data)) == QL_SUCCESS) {
2478 				ha->xioctl->fdesc.block_size = data << 2;
2479 				QL_PRINT_10(CE_CONT, "(%d): fdesc.block_size="
2480 				    "%xh\n", ha->instance,
2481 				    ha->xioctl->fdesc.block_size);
2482 			} else {
2483 				EL(ha, "flash_access status=%xh\n", rval2);
2484 			}
2485 		}
2486 
2487 		/* Set Serdes Transmit Parameters. */
2488 		if (CFG_IST(ha, CFG_CTRL_2422) && ha->serdes_param[0] & BIT_0) {
2489 			mr.mb[1] = ha->serdes_param[0];
2490 			mr.mb[2] = ha->serdes_param[1];
2491 			mr.mb[3] = ha->serdes_param[2];
2492 			mr.mb[4] = ha->serdes_param[3];
2493 			(void) ql_serdes_param(ha, &mr);
2494 		}
2495 	}
2496 
2497 	if (rval != QL_SUCCESS) {
2498 		ha->task_daemon_flags &= ~FIRMWARE_LOADED;
2499 		EL(ha, "failed, rval = %xh\n", rval);
2500 	} else {
2501 		ha->task_daemon_flags |= FIRMWARE_LOADED;
2502 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2503 	}
2504 	return (rval);
2505 }
2506 
2507 /*
2508  * ql_set_cache_line
2509  *	Sets PCI cache line parameter.
2510  *
2511  * Input:
2512  *	ha = adapter state pointer.
2513  *
2514  * Returns:
2515  *	ql local function return status code.
2516  *
2517  * Context:
2518  *	Kernel context.
2519  */
2520 int
2521 ql_set_cache_line(ql_adapter_state_t *ha)
2522 {
2523 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2524 
2525 	/* Set the cache line. */
2526 	if (CFG_IST(ha->pha, CFG_SET_CACHE_LINE_SIZE_1)) {
2527 		/* Set cache line register. */
2528 		ql_pci_config_put8(ha->pha, PCI_CONF_CACHE_LINESZ, 1);
2529 	}
2530 
2531 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2532 
2533 	return (QL_SUCCESS);
2534 }
2535 
2536 /*
2537  * ql_init_rings
2538  *	Initializes firmware and ring pointers.
2539  *
2540  *	Beginning of response ring has initialization control block
2541  *	already built by nvram config routine.
2542  *
2543  * Input:
2544  *	ha = adapter state pointer.
2545  *	ha->hba_buf = request and response rings
2546  *	ha->init_ctrl_blk = initialization control block
2547  *
2548  * Returns:
2549  *	ql local function return status code.
2550  *
2551  * Context:
2552  *	Kernel context.
2553  */
2554 int
2555 ql_init_rings(ql_adapter_state_t *vha2)
2556 {
2557 	int			rval, rval2;
2558 	uint16_t		index;
2559 	ql_mbx_data_t		mr;
2560 	ql_adapter_state_t	*ha = vha2->pha;
2561 
2562 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2563 
2564 	/* Clear outstanding commands array. */
2565 	for (index = 0; index < MAX_OUTSTANDING_COMMANDS; index++) {
2566 		ha->outstanding_cmds[index] = NULL;
2567 	}
2568 	ha->osc_index = 1;
2569 
2570 	ha->pending_cmds.first = NULL;
2571 	ha->pending_cmds.last = NULL;
2572 
2573 	/* Initialize firmware. */
2574 	ha->request_ring_ptr = ha->request_ring_bp;
2575 	ha->req_ring_index = 0;
2576 	ha->req_q_cnt = REQUEST_ENTRY_CNT - 1;
2577 	ha->response_ring_ptr = ha->response_ring_bp;
2578 	ha->rsp_ring_index = 0;
2579 
2580 	if (ha->flags & VP_ENABLED) {
2581 		ql_adapter_state_t	*vha;
2582 		uint16_t		cnt;
2583 		uint32_t		max_vports;
2584 		ql_init_24xx_cb_t	*icb = &ha->init_ctrl_blk.cb24;
2585 
2586 		max_vports = (CFG_IST(ha, CFG_CTRL_2422) ?
2587 		    MAX_24_VIRTUAL_PORTS : MAX_25_VIRTUAL_PORTS);
2588 		bzero(icb->vp_count,
2589 		    ((uintptr_t)icb + sizeof (ql_init_24xx_cb_t)) -
2590 		    (uintptr_t)icb->vp_count);
2591 		icb->vp_count[0] = (uint8_t)max_vports;
2592 
2593 		/* Allow connection option 2. */
2594 		icb->global_vp_option[0] = BIT_1;
2595 
2596 		for (cnt = 0, vha = ha->vp_next; cnt < max_vports &&
2597 		    vha != NULL; vha = vha->vp_next, cnt++) {
2598 
2599 			index = (uint8_t)(vha->vp_index - 1);
2600 			bcopy(vha->loginparams.node_ww_name.raw_wwn,
2601 			    icb->vpc[index].node_name, 8);
2602 			bcopy(vha->loginparams.nport_ww_name.raw_wwn,
2603 			    icb->vpc[index].port_name, 8);
2604 
2605 			icb->vpc[index].options = VPO_TARGET_MODE_DISABLED |
2606 			    VPO_INITIATOR_MODE_ENABLED;
2607 			if (vha->flags & VP_ENABLED) {
2608 				icb->vpc[index].options = (uint8_t)
2609 				    (icb->vpc[index].options | VPO_ENABLED);
2610 			}
2611 		}
2612 	}
2613 
2614 	rval = ql_init_firmware(ha);
2615 
2616 	if (rval == QL_SUCCESS && (CFG_IST(ha, CFG_CTRL_242581)) == 0) {
2617 		/* Tell firmware to enable MBA_PORT_BYPASS_CHANGED event */
2618 		rval = ql_get_firmware_option(ha, &mr);
2619 		if (rval == QL_SUCCESS) {
2620 			mr.mb[1] = (uint16_t)(mr.mb[1] | BIT_9);
2621 			mr.mb[2] = 0;
2622 			mr.mb[3] = BIT_10;
2623 			rval = ql_set_firmware_option(ha, &mr);
2624 		}
2625 	}
2626 
2627 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWFCETRACE))) {
2628 		/* Firmware Fibre Channel Event Trace Buffer */
2629 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwfcetracebuf, FWFCESIZE,
2630 		    LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2631 			EL(ha, "fcetrace buffer alloc failed: %xh\n", rval2);
2632 		} else {
2633 			if ((rval2 = ql_fw_etrace(ha, &ha->fwfcetracebuf,
2634 			    FTO_FCE_TRACE_ENABLE)) != QL_SUCCESS) {
2635 				EL(ha, "fcetrace enable failed: %xh\n", rval2);
2636 				ql_free_phys(ha, &ha->fwfcetracebuf);
2637 			}
2638 		}
2639 	}
2640 
2641 	if ((rval == QL_SUCCESS) && (CFG_IST(ha, CFG_ENABLE_FWEXTTRACE))) {
2642 		/* Firmware Extended Trace Buffer */
2643 		if ((rval2 = ql_get_dma_mem(ha, &ha->fwexttracebuf, FWEXTSIZE,
2644 		    LITTLE_ENDIAN_DMA, QL_DMA_RING_ALIGN)) != QL_SUCCESS) {
2645 			EL(ha, "exttrace buffer alloc failed: %xh\n", rval2);
2646 		} else {
2647 			if ((rval2 = ql_fw_etrace(ha, &ha->fwexttracebuf,
2648 			    FTO_EXT_TRACE_ENABLE)) != QL_SUCCESS) {
2649 				EL(ha, "exttrace enable failed: %xh\n", rval2);
2650 				ql_free_phys(ha, &ha->fwexttracebuf);
2651 			}
2652 		}
2653 	}
2654 
2655 	if (rval == QL_SUCCESS && CFG_IST(ha, CFG_CTRL_MENLO)) {
2656 		ql_mbx_iocb_t	*pkt;
2657 		clock_t		timer;
2658 
2659 		/* Wait for firmware login of menlo. */
2660 		for (timer = 3000; timer; timer--) {
2661 			if (ha->flags & MENLO_LOGIN_OPERATIONAL) {
2662 				break;
2663 			}
2664 
2665 			if (!(ha->flags & INTERRUPTS_ENABLED) ||
2666 			    ddi_in_panic()) {
2667 				if (RD16_IO_REG(ha, istatus) & RISC_INT) {
2668 					(void) ql_isr((caddr_t)ha);
2669 					INTR_LOCK(ha);
2670 					ha->intr_claimed = B_TRUE;
2671 					INTR_UNLOCK(ha);
2672 				}
2673 			}
2674 
2675 			/* Delay for 1 tick (10 milliseconds). */
2676 			ql_delay(ha, 10000);
2677 		}
2678 
2679 		if (timer == 0) {
2680 			rval = QL_FUNCTION_TIMEOUT;
2681 		} else {
2682 			pkt = kmem_zalloc(sizeof (ql_mbx_iocb_t), KM_SLEEP);
2683 			if (pkt == NULL) {
2684 				EL(ha, "failed, kmem_zalloc\n");
2685 				rval = QL_MEMORY_ALLOC_FAILED;
2686 			} else {
2687 				pkt->mvfy.entry_type = VERIFY_MENLO_TYPE;
2688 				pkt->mvfy.entry_count = 1;
2689 				pkt->mvfy.options_status =
2690 				    LE_16(VMF_DO_NOT_UPDATE_FW);
2691 
2692 				rval = ql_issue_mbx_iocb(ha, (caddr_t)pkt,
2693 				    sizeof (ql_mbx_iocb_t));
2694 				LITTLE_ENDIAN_16(&pkt->mvfy.options_status);
2695 				LITTLE_ENDIAN_16(&pkt->mvfy.failure_code);
2696 
2697 				if (rval != QL_SUCCESS ||
2698 				    (pkt->mvfy.entry_status & 0x3c) != 0 ||
2699 				    pkt->mvfy.options_status != CS_COMPLETE) {
2700 					EL(ha, "failed, status=%xh, es=%xh, "
2701 					    "cs=%xh, fc=%xh\n", rval,
2702 					    pkt->mvfy.entry_status & 0x3c,
2703 					    pkt->mvfy.options_status,
2704 					    pkt->mvfy.failure_code);
2705 					if (rval == QL_SUCCESS) {
2706 						rval = QL_FUNCTION_FAILED;
2707 					}
2708 				}
2709 
2710 				kmem_free(pkt, sizeof (ql_mbx_iocb_t));
2711 			}
2712 		}
2713 	}
2714 
2715 	if (rval != QL_SUCCESS) {
2716 		TASK_DAEMON_LOCK(ha);
2717 		ha->task_daemon_flags &= ~FIRMWARE_UP;
2718 		TASK_DAEMON_UNLOCK(ha);
2719 		EL(ha, "failed, rval = %xh\n", rval);
2720 	} else {
2721 		TASK_DAEMON_LOCK(ha);
2722 		ha->task_daemon_flags |= FIRMWARE_UP;
2723 		TASK_DAEMON_UNLOCK(ha);
2724 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2725 	}
2726 	return (rval);
2727 }
2728 
2729 /*
2730  * ql_fw_ready
2731  *	Waits for firmware ready. If firmware becomes ready
2732  *	device queues and RISC code are synchronized.
2733  *
2734  * Input:
2735  *	ha = adapter state pointer.
2736  *	secs = max wait time, in seconds (0-255).
2737  *
2738  * Returns:
2739  *	ql local function return status code.
2740  *
2741  * Context:
2742  *	Kernel context.
2743  */
2744 int
2745 ql_fw_ready(ql_adapter_state_t *ha, uint8_t secs)
2746 {
2747 	ql_mbx_data_t	mr;
2748 	clock_t		timer;
2749 	clock_t		dly = 250000;
2750 	clock_t		sec_delay = MICROSEC / dly;
2751 	clock_t		wait = secs * sec_delay;
2752 	int		rval = QL_FUNCTION_FAILED;
2753 	uint16_t	state = 0xffff;
2754 
2755 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2756 
2757 	timer = ha->r_a_tov < secs ? secs : ha->r_a_tov;
2758 	timer = (timer + 2) * sec_delay;
2759 
2760 	/* Wait for ISP to finish LIP */
2761 	while (timer != 0 && wait != 0 &&
2762 	    !(ha->task_daemon_flags & ISP_ABORT_NEEDED)) {
2763 
2764 		rval = ql_get_firmware_state(ha, &mr);
2765 		if (rval == QL_SUCCESS) {
2766 			if (ha->task_daemon_flags & (ISP_ABORT_NEEDED |
2767 			    LOOP_DOWN)) {
2768 				wait--;
2769 			} else if (mr.mb[1] != FSTATE_READY) {
2770 				if (mr.mb[1] != FSTATE_WAIT_LOGIN) {
2771 					wait--;
2772 				}
2773 				rval = QL_FUNCTION_FAILED;
2774 			} else {
2775 				/* Firmware is ready. Get 2 * R_A_TOV. */
2776 				rval = ql_get_timeout_parameters(ha,
2777 				    &ha->r_a_tov);
2778 				if (rval != QL_SUCCESS) {
2779 					EL(ha, "failed, get_timeout_param"
2780 					    "=%xh\n", rval);
2781 				}
2782 
2783 				/* Configure loop. */
2784 				rval = ql_configure_loop(ha);
2785 				(void) ql_marker(ha, 0, 0, MK_SYNC_ALL);
2786 
2787 				if (ha->task_daemon_flags &
2788 				    LOOP_RESYNC_NEEDED) {
2789 					wait--;
2790 					EL(ha, "loop trans; tdf=%xh\n",
2791 					    ha->task_daemon_flags);
2792 				} else {
2793 					break;
2794 				}
2795 			}
2796 		} else {
2797 			wait--;
2798 		}
2799 
2800 		if (state != mr.mb[1]) {
2801 			EL(ha, "mailbox_reg[1] = %xh\n", mr.mb[1]);
2802 			state = mr.mb[1];
2803 		}
2804 
2805 		/* Delay for a tick if waiting. */
2806 		if (timer-- != 0 && wait != 0) {
2807 			if (timer % 4 == 0) {
2808 				delay(drv_usectohz(dly));
2809 			} else {
2810 				drv_usecwait(dly);
2811 			}
2812 		} else {
2813 			rval = QL_FUNCTION_TIMEOUT;
2814 		}
2815 	}
2816 
2817 	if (rval != QL_SUCCESS) {
2818 		EL(ha, "failed, rval = %xh\n", rval);
2819 	} else {
2820 		/*EMPTY*/
2821 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2822 	}
2823 	return (rval);
2824 }
2825 
2826 /*
2827  * ql_configure_loop
2828  *	Setup configurations based on loop.
2829  *
2830  * Input:
2831  *	ha = adapter state pointer.
2832  *
2833  * Returns:
2834  *	ql local function return status code.
2835  *
2836  * Context:
2837  *	Kernel context.
2838  */
2839 static int
2840 ql_configure_loop(ql_adapter_state_t *ha)
2841 {
2842 	int			rval;
2843 	ql_adapter_state_t	*vha;
2844 
2845 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
2846 
2847 	for (vha = ha; vha != NULL; vha = vha->vp_next) {
2848 		TASK_DAEMON_LOCK(ha);
2849 		if (!(vha->task_daemon_flags & LOOP_RESYNC_NEEDED) &&
2850 		    vha->vp_index != 0 && !(vha->flags & VP_ENABLED)) {
2851 			TASK_DAEMON_UNLOCK(ha);
2852 			continue;
2853 		}
2854 		vha->task_daemon_flags &= ~LOOP_RESYNC_NEEDED;
2855 		TASK_DAEMON_UNLOCK(ha);
2856 
2857 		rval = ql_configure_hba(vha);
2858 		if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2859 		    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2860 			rval = ql_configure_device_d_id(vha);
2861 			if (rval == QL_SUCCESS && !(ha->task_daemon_flags &
2862 			    (LOOP_RESYNC_NEEDED | LOOP_DOWN))) {
2863 				(void) ql_configure_fabric(vha);
2864 			}
2865 		}
2866 	}
2867 
2868 	if (rval != QL_SUCCESS) {
2869 		EL(ha, "failed, rval = %xh\n", rval);
2870 	} else {
2871 		/*EMPTY*/
2872 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
2873 	}
2874 	return (rval);
2875 }
2876 
2877 /*
2878  * ql_configure_n_port_info
2879  *	Setup configurations based on N port 2 N port topology.
2880  *
2881  * Input:
2882  *	ha = adapter state pointer.
2883  *
2884  * Returns:
2885  *	ql local function return status code.
2886  *
2887  * Context:
2888  *	Kernel context.
2889  */
2890 static void
2891 ql_configure_n_port_info(ql_adapter_state_t *ha)
2892 {
2893 	ql_tgt_t	tmp_tq;
2894 	ql_tgt_t	*tq;
2895 	uint8_t		*cb_port_name;
2896 	ql_link_t	*link;
2897 	int		index, rval;
2898 
2899 	tq = &tmp_tq;
2900 
2901 	/* Free existing target queues. */
2902 	for (index = 0; index < DEVICE_HEAD_LIST_SIZE; index++) {
2903 		link = ha->dev[index].first;
2904 		while (link != NULL) {
2905 			tq = link->base_address;
2906 			link = link->next;
2907 			ql_remove_link(&ha->dev[index], &tq->device);
2908 			ql_dev_free(ha, tq);
2909 		}
2910 	}
2911 
2912 	/*
2913 	 * If the N_Port's WWPN is larger than our's then it has the
2914 	 * N_Port login initiative.  It will have determined that and
2915 	 * logged in with the firmware.  This results in a device
2916 	 * database entry.  In this situation we will later send up a PLOGI
2917 	 * by proxy for the N_Port to get things going.
2918 	 *
2919 	 * If the N_Ports WWPN is smaller then the firmware has the
2920 	 * N_Port login initiative and does a FLOGI in order to obtain the
2921 	 * N_Ports WWNN and WWPN.  These names are required later
2922 	 * during Leadvilles FLOGI.  No PLOGI is done by the firmware in
2923 	 * anticipation of a PLOGI via the driver from the upper layers.
2924 	 * Upon reciept of said PLOGI the driver issues an ELS PLOGI
2925 	 * pass-through command and the firmware assumes the s_id
2926 	 * and the N_Port assumes the d_id and Bob's your uncle.
2927 	 */
2928 
2929 	/*
2930 	 * In N port 2 N port topology the FW provides a port database entry at
2931 	 * loop_id 0x7fe which allows us to acquire the Ports WWPN.
2932 	 */
2933 	tq->d_id.b.al_pa = 0;
2934 	tq->d_id.b.area = 0;
2935 	tq->d_id.b.domain = 0;
2936 	tq->loop_id = 0x7fe;
2937 
2938 	rval = ql_get_port_database(ha, tq, PDF_NONE);
2939 	if (rval == QL_SUCCESS || rval == QL_NOT_LOGGED_IN) {
2940 		ql_dev_id_list_t	*list;
2941 		uint32_t		list_size;
2942 		ql_mbx_data_t		mr;
2943 		port_id_t		d_id = {0, 0, 0, 0};
2944 		uint16_t		loop_id = 0;
2945 
2946 		cb_port_name = (uint8_t *)(CFG_IST(ha, CFG_CTRL_242581) ?
2947 		    &ha->init_ctrl_blk.cb24.port_name[0] :
2948 		    &ha->init_ctrl_blk.cb.port_name[0]);
2949 
2950 		if ((ql_wwn_cmp(ha, (la_wwn_t *)&tq->port_name[0],
2951 		    (la_wwn_t *)cb_port_name) == 1)) {
2952 			EL(ha, "target port has N_Port login initiative\n");
2953 		} else {
2954 			EL(ha, "host port has N_Port login initiative\n");
2955 		}
2956 
2957 		/* Capture the N Ports WWPN */
2958 
2959 		bcopy((void *)&tq->port_name[0],
2960 		    (void *)&ha->n_port->port_name[0], 8);
2961 		bcopy((void *)&tq->node_name[0],
2962 		    (void *)&ha->n_port->node_name[0], 8);
2963 
2964 		/* Resolve an n_port_handle */
2965 		ha->n_port->n_port_handle = 0x7fe;
2966 
2967 		list_size = sizeof (ql_dev_id_list_t) * DEVICE_LIST_ENTRIES;
2968 		list = (ql_dev_id_list_t *)kmem_zalloc(list_size, KM_SLEEP);
2969 
2970 		if (list != NULL &&
2971 		    ql_get_id_list(ha, (caddr_t)list, list_size, &mr) ==
2972 		    QL_SUCCESS) {
2973 			if (mr.mb[1]) {
2974 				EL(ha, "id list entries = %d\n", mr.mb[1]);
2975 				for (index = 0; index < mr.mb[1]; index++) {
2976 					ql_dev_list(ha, list, index,
2977 					    &d_id, &loop_id);
2978 					ha->n_port->n_port_handle = loop_id;
2979 				}
2980 			} else {
2981 				for (index = 0; index <= LAST_LOCAL_LOOP_ID;
2982 				    index++) {
2983 					/* resuse tq */
2984 					tq->loop_id = (uint16_t)index;
2985 					rval = ql_get_port_database(ha, tq,
2986 					    PDF_NONE);
2987 					if (rval == QL_NOT_LOGGED_IN) {
2988 						if (tq->master_state ==
2989 						    PD_STATE_PLOGI_PENDING) {
2990 							ha->n_port->
2991 							    n_port_handle =
2992 							    tq->loop_id;
2993 							break;
2994 						}
2995 					} else {
2996 						ha->n_port->n_port_handle =
2997 						    tq->loop_id;
2998 						break;
2999 					}
3000 				}
3001 			}
3002 		} else {
3003 			cmn_err(CE_WARN, "!%s(%d) didn't get list for %xh",
3004 			    QL_NAME, ha->instance, d_id.b24);
3005 		}
3006 		if (list != NULL) {
3007 			kmem_free(list, list_size);
3008 		}
3009 	}
3010 }
3011 
3012 
3013 /*
3014  * ql_configure_hba
3015  *	Setup adapter context.
3016  *
3017  * Input:
3018  *	ha = adapter state pointer.
3019  *
3020  * Returns:
3021  *	ql local function return status code.
3022  *
3023  * Context:
3024  *	Kernel context.
3025  */
3026 static int
3027 ql_configure_hba(ql_adapter_state_t *ha)
3028 {
3029 	uint8_t		*bp;
3030 	int		rval;
3031 	uint32_t	state;
3032 	ql_mbx_data_t	mr;
3033 
3034 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
3035 
3036 	/* Get host addresses. */
3037 	rval = ql_get_adapter_id(ha, &mr);
3038 	if (rval == QL_SUCCESS) {
3039 		ha->topology = (uint8_t)(ha->topology &
3040 		    ~(QL_N_PORT | QL_NL_PORT | QL_F_PORT | QL_FL_PORT));
3041 
3042 		/* Save Host d_id, alpa, loop ID. */
3043 		ha->loop_id = mr.mb[1];
3044 		ha->d_id.b.al_pa = LSB(mr.mb[2]);
3045 		ha->d_id.b.area = MSB(mr.mb[2]);
3046 		ha->d_id.b.domain = LSB(mr.mb[3]);
3047 
3048 		ADAPTER_STATE_LOCK(ha);
3049 		ha->flags &= ~FDISC_ENABLED;
3050 
3051 		/* Get loop topology. */
3052 		switch (mr.mb[6]) {
3053 		case CNX_LOOP_NO_FABRIC:
3054 			ha->topology = (uint8_t)(ha->topology | QL_NL_PORT);
3055 			break;
3056 		case CNX_FLPORT_IN_LOOP:
3057 			ha->topology = (uint8_t)(ha->topology | QL_FL_PORT);
3058 			break;
3059 		case CNX_NPORT_2_NPORT_P2P:
3060 		case CNX_NPORT_2_NPORT_NO_TGT_RSP:
3061 			ha->flags |= POINT_TO_POINT;
3062 			ha->topology = (uint8_t)(ha->topology | QL_N_PORT);
3063 			if (CFG_IST(ha, CFG_CTRL_2425)) {
3064 				ql_configure_n_port_info(ha);
3065 			}
3066 			break;
3067 		case CNX_FLPORT_P2P:
3068 			ha->flags |= POINT_TO_POINT;
3069 			ha->topology = (uint8_t)(ha->topology | QL_F_PORT);
3070 
3071 			/* Get supported option. */
3072 			if (CFG_IST(ha, CFG_CTRL_242581) &&
3073 			    mr.mb[7] & GID_FP_NPIV_SUPPORT) {
3074 				ha->flags |= FDISC_ENABLED;
3075 			}
3076 			break;
3077 		default:
3078 			QL_PRINT_2(CE_CONT, "(%d,%d): UNKNOWN topology=%xh, "
3079 			    "d_id=%xh\n", ha->instance, ha->vp_index, mr.mb[6],
3080 			    ha->d_id.b24);
3081 			rval = QL_FUNCTION_FAILED;
3082 			break;
3083 		}
3084 		ADAPTER_STATE_UNLOCK(ha);
3085 
3086 		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322 |
3087 		    CFG_CTRL_242581))) {
3088 			mr.