1fcf3ce44SJohn Forte /*
2fcf3ce44SJohn Forte  * CDDL HEADER START
3fcf3ce44SJohn Forte  *
4fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7fcf3ce44SJohn Forte  *
8fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11fcf3ce44SJohn Forte  * and limitations under the License.
12fcf3ce44SJohn Forte  *
13fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18fcf3ce44SJohn Forte  *
19fcf3ce44SJohn Forte  * CDDL HEADER END
20fcf3ce44SJohn Forte  */
21fcf3ce44SJohn Forte 
22c1fad183SDaniel Beauregard /* Copyright 2010 QLogic Corporation */
23fcf3ce44SJohn Forte 
24fcf3ce44SJohn Forte /*
25*f885d00fSDaniel Beauregard  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26fcf3ce44SJohn Forte  */
27fcf3ce44SJohn Forte 
28c1fad183SDaniel Beauregard #pragma ident	"Copyright 2010 QLogic Corporation; ql_init.c"
29fcf3ce44SJohn Forte 
30fcf3ce44SJohn Forte /*
31fcf3ce44SJohn Forte  * ISP2xxx Solaris Fibre Channel Adapter (FCA) driver source file.
32fcf3ce44SJohn Forte  *
33fcf3ce44SJohn Forte  * ***********************************************************************
34fcf3ce44SJohn Forte  * *									**
35fcf3ce44SJohn Forte  * *				NOTICE					**
36c1fad183SDaniel Beauregard  * *		COPYRIGHT (C) 1996-2010 QLOGIC CORPORATION		**
37fcf3ce44SJohn Forte  * *			ALL RIGHTS RESERVED				**
38fcf3ce44SJohn Forte  * *									**
39fcf3ce44SJohn Forte  * ***********************************************************************
40fcf3ce44SJohn Forte  *
41fcf3ce44SJohn Forte  */
42fcf3ce44SJohn Forte 
43fcf3ce44SJohn Forte #include <ql_apps.h>
44fcf3ce44SJohn Forte #include <ql_api.h>
45fcf3ce44SJohn Forte #include <ql_debug.h>
46fcf3ce44SJohn Forte #include <ql_init.h>
47fcf3ce44SJohn Forte #include <ql_iocb.h>
48fcf3ce44SJohn Forte #include <ql_isr.h>
49fcf3ce44SJohn Forte #include <ql_mbx.h>
50eb82ff87SDaniel Beauregard #include <ql_nx.h>
51fcf3ce44SJohn Forte #include <ql_xioctl.h>
52fcf3ce44SJohn Forte 
53fcf3ce44SJohn Forte /*
54fcf3ce44SJohn Forte  * Local data
55fcf3ce44SJohn Forte  */
56fcf3ce44SJohn Forte 
57fcf3ce44SJohn Forte /*
58fcf3ce44SJohn Forte  * Local prototypes
59fcf3ce44SJohn Forte  */
60fcf3ce44SJohn Forte static uint16_t ql_nvram_request(ql_adapter_state_t *, uint32_t);
61fcf3ce44SJohn Forte static int ql_nvram_24xx_config(ql_adapter_state_t *);
62fcf3ce44SJohn Forte static void ql_23_properties(ql_adapter_state_t *, nvram_t *);
63fcf3ce44SJohn Forte static void ql_24xx_properties(ql_adapter_state_t *, nvram_24xx_t *);
64fcf3ce44SJohn Forte static int ql_check_isp_firmware(ql_adapter_state_t *);
65fcf3ce44SJohn Forte static int ql_chip_diag(ql_adapter_state_t *);
66fcf3ce44SJohn Forte static int ql_load_flash_fw(ql_adapter_state_t *);
67fcf3ce44SJohn Forte static int ql_configure_loop(ql_adapter_state_t *);
68fcf3ce44SJohn Forte static int ql_configure_hba(ql_adapter_state_t *);
69fcf3ce44SJohn Forte static int ql_configure_fabric(ql_adapter_state_t *);
70fcf3ce44SJohn Forte static int ql_configure_device_d_id(ql_adapter_state_t *);
71fcf3ce44SJohn Forte static void ql_set_max_read_req(ql_adapter_state_t *);
725dfd244aSDaniel Beauregard static void ql_configure_n_port_info(ql_adapter_state_t *);
73a2b3ff35SDaniel Beauregard static void ql_clear_mcp(ql_adapter_state_t *);
74f33c1cdbSDaniel Beauregard static void ql_mps_reset(ql_adapter_state_t *);
75a2b3ff35SDaniel Beauregard 
76fcf3ce44SJohn Forte /*
77fcf3ce44SJohn Forte  * ql_initialize_adapter
78fcf3ce44SJohn Forte  *	Initialize board.
79fcf3ce44SJohn Forte  *
80fcf3ce44SJohn Forte  * Input:
81fcf3ce44SJohn Forte  *	ha = adapter state pointer.
82fcf3ce44SJohn Forte  *
83fcf3ce44SJohn Forte  * Returns:
84fcf3ce44SJohn Forte  *	ql local function return status code.
85fcf3ce44SJohn Forte  *
86fcf3ce44SJohn Forte  * Context:
87fcf3ce44SJohn Forte  *	Kernel context.
88fcf3ce44SJohn Forte  */
89fcf3ce44SJohn Forte int
ql_initialize_adapter(ql_adapter_state_t * ha)90fcf3ce44SJohn Forte ql_initialize_adapter(ql_adapter_state_t *ha)
91fcf3ce44SJohn Forte {
92fcf3ce44SJohn Forte 	int			rval;
93fcf3ce44SJohn Forte 	class_svc_param_t	*class3_param;
94fcf3ce44SJohn Forte 	caddr_t			msg;
95fcf3ce44SJohn Forte 	la_els_logi_t		*els = &ha->loginparams;
96fcf3ce44SJohn Forte 	int			retries = 5;
97fcf3ce44SJohn Forte 
98fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
99fcf3ce44SJohn Forte 
100fcf3ce44SJohn Forte 	do {
101fcf3ce44SJohn Forte 		/* Clear adapter flags. */
102fcf3ce44SJohn Forte 		TASK_DAEMON_LOCK(ha);
103fcf3ce44SJohn Forte 		ha->task_daemon_flags &= TASK_DAEMON_STOP_FLG |
104fcf3ce44SJohn Forte 		    TASK_DAEMON_SLEEPING_FLG | TASK_DAEMON_ALIVE_FLG |
105fcf3ce44SJohn Forte 		    TASK_DAEMON_IDLE_CHK_FLG;
106fcf3ce44SJohn Forte 		ha->task_daemon_flags |= LOOP_DOWN;
107fcf3ce44SJohn Forte 		TASK_DAEMON_UNLOCK(ha);
108fcf3ce44SJohn Forte 
109fcf3ce44SJohn Forte 		ha->loop_down_timer = LOOP_DOWN_TIMER_OFF;
110fcf3ce44SJohn Forte 		ADAPTER_STATE_LOCK(ha);
11116dd44c2SDaniel Beauregard 		ha->flags |= ABORT_CMDS_LOOP_DOWN_TMO;
112fcf3ce44SJohn Forte 		ha->flags &= ~ONLINE;
113fcf3ce44SJohn Forte 		ADAPTER_STATE_UNLOCK(ha);
114fcf3ce44SJohn Forte 
115fcf3ce44SJohn Forte 		ha->state = FC_STATE_OFFLINE;
116fcf3ce44SJohn Forte 		msg = "Loop OFFLINE";
117fcf3ce44SJohn Forte 
118fcf3ce44SJohn Forte 		rval = ql_pci_sbus_config(ha);
119fcf3ce44SJohn Forte 		if (rval != QL_SUCCESS) {
120fcf3ce44SJohn Forte 			TASK_DAEMON_LOCK(ha);
121fcf3ce44SJohn Forte 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
122fcf3ce44SJohn Forte 				EL(ha, "ql_pci_sbus_cfg, isp_abort_needed\n");
123fcf3ce44SJohn Forte 				ha->task_daemon_flags |= ISP_ABORT_NEEDED;
124fcf3ce44SJohn Forte 			}
125fcf3ce44SJohn Forte 			TASK_DAEMON_UNLOCK(ha);
126fcf3ce44SJohn Forte 			continue;
127fcf3ce44SJohn Forte 		}
128fcf3ce44SJohn Forte 
1295dfd244aSDaniel Beauregard 		(void) ql_setup_fcache(ha);
130fcf3ce44SJohn Forte 
131fcf3ce44SJohn Forte 		/* Reset ISP chip. */
132fcf3ce44SJohn Forte 		ql_reset_chip(ha);
133fcf3ce44SJohn Forte 
134fcf3ce44SJohn Forte 		/* Get NVRAM configuration if needed. */
135fcf3ce44SJohn Forte 		if (ha->init_ctrl_blk.cb.version == 0) {
136fcf3ce44SJohn Forte 			(void) ql_nvram_config(ha);
137fcf3ce44SJohn Forte 		}
138fcf3ce44SJohn Forte 
139fcf3ce44SJohn Forte 		/* Set login parameters. */
140eb82ff87SDaniel Beauregard 		if (CFG_IST(ha, CFG_CTRL_24258081)) {
141fcf3ce44SJohn Forte 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
142fcf3ce44SJohn Forte 			    ha->init_ctrl_blk.cb24.max_frame_length[0],
143fcf3ce44SJohn Forte 			    ha->init_ctrl_blk.cb24.max_frame_length[1]);
144fcf3ce44SJohn Forte 			bcopy((void *)&ha->init_ctrl_blk.cb24.port_name[0],
145fcf3ce44SJohn Forte 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
146fcf3ce44SJohn Forte 			bcopy((void *)&ha->init_ctrl_blk.cb24.node_name[0],
147fcf3ce44SJohn Forte 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
148fcf3ce44SJohn Forte 		} else {
149fcf3ce44SJohn Forte 			els->common_service.rx_bufsize = CHAR_TO_SHORT(
150fcf3ce44SJohn Forte 			    ha->init_ctrl_blk.cb.max_frame_length[0],
151fcf3ce44SJohn Forte 			    ha->init_ctrl_blk.cb.max_frame_length[1]);
152fcf3ce44SJohn Forte 			bcopy((void *)&ha->init_ctrl_blk.cb.port_name[0],
153fcf3ce44SJohn Forte 			    (void *)&els->nport_ww_name.raw_wwn[0], 8);
154fcf3ce44SJohn Forte 			bcopy((void *)&ha->init_ctrl_blk.cb.node_name[0],
155fcf3ce44SJohn Forte 			    (void *)&els->node_ww_name.raw_wwn[0], 8);
156fcf3ce44SJohn Forte 		}
157*f885d00fSDaniel Beauregard 		bcopy(QL_VERSION, ha->adapter_stats->revlvl.qlddv,
158*f885d00fSDaniel Beauregard 		    strlen(QL_VERSION));
159fcf3ce44SJohn Forte 
160fcf3ce44SJohn Forte 		/* Determine which RISC code to use. */
161eb82ff87SDaniel Beauregard 		if ((rval = ql_check_isp_firmware(ha)) != QL_SUCCESS) {
162eb82ff87SDaniel Beauregard 			if ((rval = ql_chip_diag(ha)) == QL_SUCCESS) {
163eb82ff87SDaniel Beauregard 				rval = ql_load_isp_firmware(ha);
164eb82ff87SDaniel Beauregard 			}
165fcf3ce44SJohn Forte 		}
166fcf3ce44SJohn Forte 
167fcf3ce44SJohn Forte 		if (rval == QL_SUCCESS && (rval = ql_set_cache_line(ha)) ==
1685dfd244aSDaniel Beauregard 		    QL_SUCCESS && (rval = ql_init_rings(ha)) == QL_SUCCESS) {
169fcf3ce44SJohn Forte 
170fcf3ce44SJohn Forte 			(void) ql_fw_ready(ha, ha->fwwait);
171fcf3ce44SJohn Forte 
172fcf3ce44SJohn Forte 			if (!(ha->task_daemon_flags & QL_SUSPENDED) &&
173fcf3ce44SJohn Forte 			    ha->loop_down_timer == LOOP_DOWN_TIMER_OFF) {
174fcf3ce44SJohn Forte 				if (ha->topology & QL_LOOP_CONNECTION) {
175fcf3ce44SJohn Forte 					ha->state = ha->state | FC_STATE_LOOP;
176fcf3ce44SJohn Forte 					msg = "Loop ONLINE";
177fcf3ce44SJohn Forte 					ha->task_daemon_flags |= STATE_ONLINE;
178fcf3ce44SJohn Forte 				} else if (ha->topology & QL_P2P_CONNECTION) {
179fcf3ce44SJohn Forte 					ha->state = ha->state |
180fcf3ce44SJohn Forte 					    FC_STATE_ONLINE;
181fcf3ce44SJohn Forte 					msg = "Link ONLINE";
182fcf3ce44SJohn Forte 					ha->task_daemon_flags |= STATE_ONLINE;
183fcf3ce44SJohn Forte 				} else {
184fcf3ce44SJohn Forte 					msg = "Unknown Link state";
185fcf3ce44SJohn Forte 				}
186fcf3ce44SJohn Forte 			}
187fcf3ce44SJohn Forte 		} else {
188fcf3ce44SJohn Forte 			TASK_DAEMON_LOCK(ha);
189fcf3ce44SJohn Forte 			if (!(ha->task_daemon_flags & ABORT_ISP_ACTIVE)) {
190fcf3ce44SJohn Forte 				EL(ha, "failed, isp_abort_needed\n");
191fcf3ce44SJohn Forte 				ha->task_daemon_flags |= ISP_ABORT_NEEDED |
192fcf3ce44SJohn Forte 				    LOOP_DOWN;
193fcf3ce44SJohn Forte 			}
194fcf3ce44SJohn Forte 			TASK_DAEMON_UNLOCK(ha);
195fcf3ce44SJohn Forte 		}
196fcf3ce44SJohn Forte 
197fcf3ce44SJohn Forte 	} while (retries-- != 0 && ha->task_daemon_flags & ISP_ABORT_NEEDED);
198fcf3ce44SJohn Forte 
199fcf3ce44SJohn Forte 	cmn_err(CE_NOTE, "!Qlogic %s(%d): %s", QL_NAME, ha->instance, msg);
200fcf3ce44SJohn Forte 
201fcf3ce44SJohn Forte 	/* Enable ISP interrupts and login parameters. */
202eb82ff87SDaniel Beauregard 	if (CFG_IST(ha, CFG_CTRL_8021)) {
203eb82ff87SDaniel Beauregard 		ql_8021_enable_intrs(ha);
204eb82ff87SDaniel Beauregard 	} else if (CFG_IST(ha, CFG_CTRL_242581)) {
205eb82ff87SDaniel Beauregard 		WRT32_IO_REG(ha, ictrl, ISP_EN_RISC);
206eb82ff87SDaniel Beauregard 	} else {
207eb82ff87SDaniel Beauregard 		WRT16_IO_REG(ha, ictrl, ISP_EN_INT + ISP_EN_RISC);
208eb82ff87SDaniel Beauregard 	}
209fcf3ce44SJohn Forte 
210fcf3ce44SJohn Forte 	ADAPTER_STATE_LOCK(ha);
211fcf3ce44SJohn Forte 	ha->flags |= (INTERRUPTS_ENABLED | ONLINE);
212fcf3ce44SJohn Forte 	ADAPTER_STATE_UNLOCK(ha);
213fcf3ce44SJohn Forte 
214fcf3ce44SJohn Forte 	ha->task_daemon_flags &= ~(FC_STATE_CHANGE | RESET_MARKER_NEEDED |
215fcf3ce44SJohn Forte 	    COMMAND_WAIT_NEEDED);
216fcf3ce44SJohn Forte 
217fcf3ce44SJohn Forte 	/*
218fcf3ce44SJohn Forte 	 * Setup login parameters.
219fcf3ce44SJohn Forte 	 */
220fcf3ce44SJohn Forte 	els->common_service.fcph_version = 0x2006;
221fcf3ce44SJohn Forte 	els->common_service.btob_credit = 3;
222fcf3ce44SJohn Forte 	els->common_service.cmn_features = 0x8800;
223fcf3ce44SJohn Forte 	els->common_service.conc_sequences = 0xff;
224fcf3ce44SJohn Forte 	els->common_service.relative_offset = 3;
225fcf3ce44SJohn Forte 	els->common_service.e_d_tov = 0x07d0;
226fcf3ce44SJohn Forte 
227fcf3ce44SJohn Forte 	class3_param = (class_svc_param_t *)&els->class_3;
228fcf3ce44SJohn Forte 	class3_param->class_valid_svc_opt = 0x8800;
229fcf3ce44SJohn Forte 	class3_param->rcv_data_size = els->common_service.rx_bufsize;
230fcf3ce44SJohn Forte 	class3_param->conc_sequences = 0xff;
231fcf3ce44SJohn Forte 
232fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS) {
233fcf3ce44SJohn Forte 		EL(ha, "failed, rval = %xh\n", rval);
234fcf3ce44SJohn Forte 	} else {
235fcf3ce44SJohn Forte 		/*EMPTY*/
236fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
237fcf3ce44SJohn Forte 	}
238fcf3ce44SJohn Forte 	return (rval);
239fcf3ce44SJohn Forte }
240fcf3ce44SJohn Forte 
241fcf3ce44SJohn Forte /*
242fcf3ce44SJohn Forte  * ql_pci_sbus_config
243fcf3ce44SJohn Forte  *	Setup device PCI/SBUS configuration registers.
244fcf3ce44SJohn Forte  *
245fcf3ce44SJohn Forte  * Input:
246fcf3ce44SJohn Forte  *	ha = adapter state pointer.
247fcf3ce44SJohn Forte  *
248fcf3ce44SJohn Forte  * Returns:
249fcf3ce44SJohn Forte  *	ql local function return status code.
250fcf3ce44SJohn Forte  *
251fcf3ce44SJohn Forte  * Context:
252fcf3ce44SJohn Forte  *	Kernel context.
253fcf3ce44SJohn Forte  */
254fcf3ce44SJohn Forte int
ql_pci_sbus_config(ql_adapter_state_t * ha)255fcf3ce44SJohn Forte ql_pci_sbus_config(ql_adapter_state_t *ha)
256fcf3ce44SJohn Forte {
257fcf3ce44SJohn Forte 	uint32_t	timer;
258fcf3ce44SJohn Forte 	uint16_t	cmd, w16;
259fcf3ce44SJohn Forte 
260fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
261fcf3ce44SJohn Forte 
262fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_SBUS_CARD)) {
263fcf3ce44SJohn Forte 		w16 = (uint16_t)ddi_get16(ha->sbus_fpga_dev_handle,
264fcf3ce44SJohn Forte 		    (uint16_t *)(ha->sbus_fpga_iobase + FPGA_REVISION));
265fcf3ce44SJohn Forte 		EL(ha, "FPGA rev is %d.%d", (w16 & 0xf0) >> 4,
266fcf3ce44SJohn Forte 		    w16 & 0xf);
267fcf3ce44SJohn Forte 	} else {
268fcf3ce44SJohn Forte 		/*
269fcf3ce44SJohn Forte 		 * we want to respect framework's setting of PCI
270fcf3ce44SJohn Forte 		 * configuration space command register and also
271fcf3ce44SJohn Forte 		 * want to make sure that all bits of interest to us
272fcf3ce44SJohn Forte 		 * are properly set in command register.
273fcf3ce44SJohn Forte 		 */
274fcf3ce44SJohn Forte 		cmd = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_COMM);
275fcf3ce44SJohn Forte 		cmd = (uint16_t)(cmd | PCI_COMM_IO | PCI_COMM_MAE |
276fcf3ce44SJohn Forte 		    PCI_COMM_ME | PCI_COMM_MEMWR_INVAL |
277fcf3ce44SJohn Forte 		    PCI_COMM_PARITY_DETECT | PCI_COMM_SERR_ENABLE);
278fcf3ce44SJohn Forte 
279fcf3ce44SJohn Forte 		/*
280fcf3ce44SJohn Forte 		 * If this is a 2300 card and not 2312, reset the
281fcf3ce44SJohn Forte 		 * MEMWR_INVAL due to a bug in the 2300. Unfortunately, the
282fcf3ce44SJohn Forte 		 * 2310 also reports itself as a 2300 so we need to get the
283fcf3ce44SJohn Forte 		 * fb revision level -- a 6 indicates it really is a 2300 and
284fcf3ce44SJohn Forte 		 * not a 2310.
285fcf3ce44SJohn Forte 		 */
286fcf3ce44SJohn Forte 
287fcf3ce44SJohn Forte 		if (ha->device_id == 0x2300) {
288fcf3ce44SJohn Forte 			/* Pause RISC. */
289fcf3ce44SJohn Forte 			WRT16_IO_REG(ha, hccr, HC_PAUSE_RISC);
290fcf3ce44SJohn Forte 			for (timer = 0; timer < 30000; timer++) {
291fcf3ce44SJohn Forte 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) !=
292fcf3ce44SJohn Forte 				    0) {
293fcf3ce44SJohn Forte 					break;
294fcf3ce44SJohn Forte 				} else {
295fcf3ce44SJohn Forte 					drv_usecwait(MILLISEC);
296fcf3ce44SJohn Forte 				}
297fcf3ce44SJohn Forte 			}
298fcf3ce44SJohn Forte 
299fcf3ce44SJohn Forte 			/* Select FPM registers. */
300fcf3ce44SJohn Forte 			WRT16_IO_REG(ha, ctrl_status, 0x20);
301fcf3ce44SJohn Forte 
302fcf3ce44SJohn Forte 			/* Get the fb rev level */
303fcf3ce44SJohn Forte 			if (RD16_IO_REG(ha, fb_cmd) == 6) {
304fcf3ce44SJohn Forte 				cmd = (uint16_t)(cmd & ~PCI_COMM_MEMWR_INVAL);
305fcf3ce44SJohn Forte 			}
306fcf3ce44SJohn Forte 
307fcf3ce44SJohn Forte 			/* Deselect FPM registers. */
308fcf3ce44SJohn Forte 			WRT16_IO_REG(ha, ctrl_status, 0x0);
309fcf3ce44SJohn Forte 
310fcf3ce44SJohn Forte 			/* Release RISC module. */
311fcf3ce44SJohn Forte 			WRT16_IO_REG(ha, hccr, HC_RELEASE_RISC);
312fcf3ce44SJohn Forte 			for (timer = 0; timer < 30000; timer++) {
313fcf3ce44SJohn Forte 				if ((RD16_IO_REG(ha, hccr) & HC_RISC_PAUSE) ==
314fcf3ce44SJohn Forte 				    0) {
315fcf3ce44SJohn Forte 					break;
316fcf3ce44SJohn Forte 				} else {
317fcf3ce44SJohn Forte 					drv_usecwait(MILLISEC);
318fcf3ce44SJohn Forte 				}
319fcf3ce44SJohn Forte 			}
320fcf3ce44SJohn Forte 		} else if (ha->device_id == 0x2312) {
321fcf3ce44SJohn Forte 			/*
322fcf3ce44SJohn Forte 			 * cPCI ISP2312 specific code to service function 1
323fcf3ce44SJohn Forte 			 * hot-swap registers.
324fcf3ce44SJohn Forte 			 */
325fcf3ce44SJohn Forte 			if ((RD16_IO_REG(ha, ctrl_status) & ISP_FUNC_NUM_MASK)
326fcf3ce44SJohn Forte 			    != 0) {
327fcf3ce44SJohn Forte 				ql_pci_config_put8(ha, 0x66, 0xc2);
328fcf3ce44SJohn Forte 			}
329fcf3ce44SJohn Forte 		}
330fcf3ce44SJohn Forte 
331eb82ff87SDaniel Beauregard 		if (!(CFG_IST(ha, CFG_CTRL_8021)) &&
332eb82ff87SDaniel Beauregard 		    ha->pci_max_read_req != 0) {
333fcf3ce44SJohn Forte 			ql_set_max_read_req(ha);
334fcf3ce44SJohn Forte 		}
335fcf3ce44SJohn Forte 
336fcf3ce44SJohn Forte 		ql_pci_config_put16(ha, PCI_CONF_COMM, cmd);
337fcf3ce44SJohn Forte 
338fcf3ce44SJohn Forte 		/* Set cache line register. */
339fcf3ce44SJohn Forte 		ql_pci_config_put8(ha, PCI_CONF_CACHE_LINESZ, 0x10);
340fcf3ce44SJohn Forte 
341fcf3ce44SJohn Forte 		/* Set latency register. */
342fcf3ce44SJohn Forte 		ql_pci_config_put8(ha, PCI_CONF_LATENCY_TIMER, 0x40);
343fcf3ce44SJohn Forte 
344fcf3ce44SJohn Forte 		/* Reset expansion ROM address decode enable. */
345fcf3ce44SJohn Forte 		w16 = (uint16_t)ql_pci_config_get16(ha, PCI_CONF_ROM);
346fcf3ce44SJohn Forte 		w16 = (uint16_t)(w16 & ~BIT_0);
347fcf3ce44SJohn Forte 		ql_pci_config_put16(ha, PCI_CONF_ROM, w16);
348fcf3ce44SJohn Forte 	}
349fcf3ce44SJohn Forte 
350fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
351fcf3ce44SJohn Forte 
352fcf3ce44SJohn Forte 	return (QL_SUCCESS);
353fcf3ce44SJohn Forte }
354fcf3ce44SJohn Forte 
355fcf3ce44SJohn Forte /*
356fcf3ce44SJohn Forte  * Set the PCI max read request value.
357fcf3ce44SJohn Forte  *
358fcf3ce44SJohn Forte  * Input:
359fcf3ce44SJohn Forte  *	ha:		adapter state pointer.
360fcf3ce44SJohn Forte  *
361fcf3ce44SJohn Forte  * Output:
362fcf3ce44SJohn Forte  *	none.
363fcf3ce44SJohn Forte  *
364fcf3ce44SJohn Forte  * Returns:
365fcf3ce44SJohn Forte  *
366fcf3ce44SJohn Forte  * Context:
367fcf3ce44SJohn Forte  *	Kernel context.
368fcf3ce44SJohn Forte  */
369fcf3ce44SJohn Forte 
370fcf3ce44SJohn Forte static void
ql_set_max_read_req(ql_adapter_state_t * ha)371fcf3ce44SJohn Forte ql_set_max_read_req(ql_adapter_state_t *ha)
372fcf3ce44SJohn Forte {
373fcf3ce44SJohn Forte 	uint16_t	read_req, w16;
374fcf3ce44SJohn Forte 	uint16_t	tmp = ha->pci_max_read_req;
375fcf3ce44SJohn Forte 
376fcf3ce44SJohn Forte 	if ((ha->device_id == 0x2422) ||
377fcf3ce44SJohn Forte 	    ((ha->device_id & 0xff00) == 0x2300)) {
378fcf3ce44SJohn Forte 		/* check for vaild override value */
379fcf3ce44SJohn Forte 		if (tmp == 512 || tmp == 1024 || tmp == 2048 ||
380fcf3ce44SJohn Forte 		    tmp == 4096) {
381fcf3ce44SJohn Forte 			/* shift away the don't cares */
382fcf3ce44SJohn Forte 			tmp = (uint16_t)(tmp >> 10);
383fcf3ce44SJohn Forte 			/* convert bit pos to request value */
384fcf3ce44SJohn Forte 			for (read_req = 0; tmp != 0; read_req++) {
385fcf3ce44SJohn Forte 				tmp = (uint16_t)(tmp >> 1);
386fcf3ce44SJohn Forte 			}
387fcf3ce44SJohn Forte 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x4e);
388fcf3ce44SJohn Forte 			w16 = (uint16_t)(w16 & ~(BIT_3 & BIT_2));
389fcf3ce44SJohn Forte 			w16 = (uint16_t)(w16 | (read_req << 2));
390fcf3ce44SJohn Forte 			ql_pci_config_put16(ha, 0x4e, w16);
391fcf3ce44SJohn Forte 		} else {
392fcf3ce44SJohn Forte 			EL(ha, "invalid parameter value for "
393fcf3ce44SJohn Forte 			    "'pci-max-read-request': %d; using system "
394fcf3ce44SJohn Forte 			    "default\n", tmp);
395fcf3ce44SJohn Forte 		}
396fcf3ce44SJohn Forte 	} else if ((ha->device_id == 0x2432) || ((ha->device_id & 0xff00) ==
39716dd44c2SDaniel Beauregard 	    0x2500) || (ha->device_id == 0x8432)) {
398fcf3ce44SJohn Forte 		/* check for vaild override value */
399fcf3ce44SJohn Forte 		if (tmp == 128 || tmp == 256 || tmp == 512 ||
400fcf3ce44SJohn Forte 		    tmp == 1024 || tmp == 2048 || tmp == 4096) {
401fcf3ce44SJohn Forte 			/* shift away the don't cares */
402fcf3ce44SJohn Forte 			tmp = (uint16_t)(tmp >> 8);
403fcf3ce44SJohn Forte 			/* convert bit pos to request value */
404fcf3ce44SJohn Forte 			for (read_req = 0; tmp != 0; read_req++) {
405fcf3ce44SJohn Forte 				tmp = (uint16_t)(tmp >> 1);
406fcf3ce44SJohn Forte 			}
407fcf3ce44SJohn Forte 			w16 = (uint16_t)ql_pci_config_get16(ha, 0x54);
408fcf3ce44SJohn Forte 			w16 = (uint16_t)(w16 & ~(BIT_14 | BIT_13 |
409fcf3ce44SJohn Forte 			    BIT_12));
410fcf3ce44SJohn Forte 			w16 = (uint16_t)(w16 | (read_req << 12));
411fcf3ce44SJohn Forte 			ql_pci_config_put16(ha, 0x54, w16);
412fcf3ce44SJohn Forte 		} else {
413fcf3ce44SJohn Forte 			EL(ha, "invalid parameter value for "
414fcf3ce44SJohn Forte 			    "'pci-max-read-request': %d; using system "
415fcf3ce44SJohn Forte 			    "default\n", tmp);
416fcf3ce44SJohn Forte 		}
417fcf3ce44SJohn Forte 	}
418fcf3ce44SJohn Forte }
419fcf3ce44SJohn Forte 
420fcf3ce44SJohn Forte /*
421fcf3ce44SJohn Forte  * NVRAM configuration.
422fcf3ce44SJohn Forte  *
423fcf3ce44SJohn Forte  * Input:
424fcf3ce44SJohn Forte  *	ha:		adapter state pointer.
425fcf3ce44SJohn Forte  *	ha->hba_buf = request and response rings
426fcf3ce44SJohn Forte  *
427fcf3ce44SJohn Forte  * Output:
428fcf3ce44SJohn Forte  *	ha->init_ctrl_blk = initialization control block
429fcf3ce44SJohn Forte  *	host adapters parameters in host adapter block
430fcf3ce44SJohn Forte  *
431fcf3ce44SJohn Forte  * Returns:
432fcf3ce44SJohn Forte  *	ql local function return status code.
433fcf3ce44SJohn Forte  *
434fcf3ce44SJohn Forte  * Context:
435fcf3ce44SJohn Forte  *	Kernel context.
436fcf3ce44SJohn Forte  */
437fcf3ce44SJohn Forte int
ql_nvram_config(ql_adapter_state_t * ha)438fcf3ce44SJohn Forte ql_nvram_config(ql_adapter_state_t *ha)
439fcf3ce44SJohn Forte {
440fcf3ce44SJohn Forte 	uint32_t	cnt;
441fcf3ce44SJohn Forte 	caddr_t		dptr1, dptr2;
442fcf3ce44SJohn Forte 	ql_init_cb_t	*icb = &ha->init_ctrl_blk.cb;
443fcf3ce44SJohn Forte 	ql_ip_init_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb;
444fcf3ce44SJohn Forte 	nvram_t		*nv = (nvram_t *)ha->request_ring_bp;
445fcf3ce44SJohn Forte 	uint16_t	*wptr = (uint16_t *)ha->request_ring_bp;
446fcf3ce44SJohn Forte 	uint8_t		chksum = 0;
447fcf3ce44SJohn Forte 	int		rval;
448fcf3ce44SJohn Forte 	int		idpromlen;
449fcf3ce44SJohn Forte 	char		idprombuf[32];
450fcf3ce44SJohn Forte 	uint32_t	start_addr;
451fcf3ce44SJohn Forte 
452fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
453fcf3ce44SJohn Forte 
454eb82ff87SDaniel Beauregard 	if (CFG_IST(ha, CFG_CTRL_24258081)) {
455fcf3ce44SJohn Forte 		return (ql_nvram_24xx_config(ha));
456fcf3ce44SJohn Forte 	}
457fcf3ce44SJohn Forte 
458fcf3ce44SJohn Forte 	start_addr = 0;
459fcf3ce44SJohn Forte 	if ((rval = ql_lock_nvram(ha, &start_addr, LNF_NVRAM_DATA)) ==
460fcf3ce44SJohn Forte 	    QL_SUCCESS) {
461fcf3ce44SJohn Forte 		/* Verify valid NVRAM checksum. */
462fcf3ce44SJohn Forte 		for (cnt = 0; cnt < sizeof (nvram_t)/2; cnt++) {
463fcf3ce44SJohn Forte 			*wptr = (uint16_t)ql_get_nvram_word(ha,
464fcf3ce44SJohn Forte 			    (uint32_t)(cnt + start_addr));
465fcf3ce44SJohn Forte 			chksum = (uint8_t)(chksum + (uint8_t)*wptr);
466fcf3ce44SJohn Forte 			chksum = (uint8_t)(chksum + (uint8_t)(*wptr >> 8));
467fcf3ce44SJohn Forte 			wptr++;
468fcf3ce44SJohn Forte 		}
469fcf3ce44SJohn Forte 		ql_release_nvram(ha);
470fcf3ce44SJohn Forte 	}
471fcf3ce44SJohn Forte 
472fcf3ce44SJohn Forte 	/* Bad NVRAM data, set defaults parameters. */
473fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
474fcf3ce44SJohn Forte 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
475fcf3ce44SJohn Forte 	    nv->nvram_version < 1) {
476fcf3ce44SJohn Forte 
477fcf3ce44SJohn Forte 		EL(ha, "failed, rval=%xh, checksum=%xh, "
478fcf3ce44SJohn Forte 		    "id=%02x%02x%02x%02xh, flsz=%xh, pciconfvid=%xh, "
479fcf3ce44SJohn Forte 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
480fcf3ce44SJohn Forte 		    nv->id[2], nv->id[3], ha->xioctl->fdesc.flash_size,
481fcf3ce44SJohn Forte 		    ha->subven_id, nv->nvram_version);
482fcf3ce44SJohn Forte 
483fcf3ce44SJohn Forte 		/* Don't print nvram message if it's an on-board 2200 */
484fcf3ce44SJohn Forte 		if (!((CFG_IST(ha, CFG_CTRL_2200)) &&
485fcf3ce44SJohn Forte 		    (ha->xioctl->fdesc.flash_size == 0))) {
486fcf3ce44SJohn Forte 			cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed,"
487fcf3ce44SJohn Forte 			    " using driver defaults.", QL_NAME, ha->instance);
488fcf3ce44SJohn Forte 		}
489fcf3ce44SJohn Forte 
490fcf3ce44SJohn Forte 		/* Reset NVRAM data. */
491fcf3ce44SJohn Forte 		bzero((void *)nv, sizeof (nvram_t));
492fcf3ce44SJohn Forte 
493fcf3ce44SJohn Forte 		/*
494fcf3ce44SJohn Forte 		 * Set default initialization control block.
495fcf3ce44SJohn Forte 		 */
496fcf3ce44SJohn Forte 		nv->parameter_block_version = ICB_VERSION;
497fcf3ce44SJohn Forte 		nv->firmware_options[0] = BIT_4 | BIT_3 | BIT_2 | BIT_1;
498fcf3ce44SJohn Forte 		nv->firmware_options[1] = BIT_7 | BIT_5 | BIT_2;
499fcf3ce44SJohn Forte 
500fcf3ce44SJohn Forte 		nv->max_frame_length[1] = 4;
501fcf3ce44SJohn Forte 
502fcf3ce44SJohn Forte 		/*
503fcf3ce44SJohn Forte 		 * Allow 2048 byte frames for 2300
504fcf3ce44SJohn Forte 		 */
505fcf3ce44SJohn Forte 		if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
506fcf3ce44SJohn Forte 			nv->max_frame_length[1] = 8;
507fcf3ce44SJohn Forte 		}
508fcf3ce44SJohn Forte 		nv->max_iocb_allocation[1] = 1;
509fcf3ce44SJohn Forte 		nv->execution_throttle[0] = 16;
510fcf3ce44SJohn Forte 		nv->login_retry_count = 8;
511fcf3ce44SJohn Forte 
512fcf3ce44SJohn Forte 		idpromlen = 32;
513fcf3ce44SJohn Forte 
514fcf3ce44SJohn Forte 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
515fcf3ce44SJohn Forte 		if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
516fcf3ce44SJohn Forte 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
517fcf3ce44SJohn Forte 		    &idpromlen) != DDI_PROP_SUCCESS) {
518fcf3ce44SJohn Forte 
519fcf3ce44SJohn Forte 			QL_PRINT_3(CE_CONT, "(%d): Unable to read idprom "
520fcf3ce44SJohn Forte 			    "property\n", ha->instance);
521fcf3ce44SJohn Forte 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
522fcf3ce44SJohn Forte 			    "property", QL_NAME, ha->instance);
523fcf3ce44SJohn Forte 
524fcf3ce44SJohn Forte 			nv->port_name[2] = 33;
525fcf3ce44SJohn Forte 			nv->port_name[3] = 224;
526fcf3ce44SJohn Forte 			nv->port_name[4] = 139;
527fcf3ce44SJohn Forte 			nv->port_name[7] = (uint8_t)
528fcf3ce44SJohn Forte 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
529fcf3ce44SJohn Forte 		} else {
530fcf3ce44SJohn Forte 
531fcf3ce44SJohn Forte 			nv->port_name[2] = idprombuf[2];
532fcf3ce44SJohn Forte 			nv->port_name[3] = idprombuf[3];
533fcf3ce44SJohn Forte 			nv->port_name[4] = idprombuf[4];
534fcf3ce44SJohn Forte 			nv->port_name[5] = idprombuf[5];
535fcf3ce44SJohn Forte 			nv->port_name[6] = idprombuf[6];
536fcf3ce44SJohn Forte 			nv->port_name[7] = idprombuf[7];
537fcf3ce44SJohn Forte 			nv->port_name[0] = (uint8_t)
538fcf3ce44SJohn Forte 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
539fcf3ce44SJohn Forte 		}
540fcf3ce44SJohn Forte 
541fcf3ce44SJohn Forte 		/* Don't print nvram message if it's an on-board 2200 */
542fcf3ce44SJohn Forte 		if (!(CFG_IST(ha, CFG_CTRL_2200)) &&
543fcf3ce44SJohn Forte 		    (ha->xioctl->fdesc.flash_size == 0)) {
544fcf3ce44SJohn Forte 			cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using"
545fcf3ce44SJohn Forte 			    " default HBA parameters and temporary WWPN:"
546fcf3ce44SJohn Forte 			    " %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
547fcf3ce44SJohn Forte 			    ha->instance, nv->port_name[0], nv->port_name[1],
548fcf3ce44SJohn Forte 			    nv->port_name[2], nv->port_name[3],
549fcf3ce44SJohn Forte 			    nv->port_name[4], nv->port_name[5],
550fcf3ce44SJohn Forte 			    nv->port_name[6], nv->port_name[7]);
551fcf3ce44SJohn Forte 		}
552fcf3ce44SJohn Forte 
553fcf3ce44SJohn Forte 		nv->login_timeout = 4;
554fcf3ce44SJohn Forte 
555fcf3ce44SJohn Forte 		/* Set default connection options for the 23xx to 2 */
556fcf3ce44SJohn Forte 		if (!(CFG_IST(ha, CFG_CTRL_2200))) {
557fcf3ce44SJohn Forte 			nv->add_fw_opt[0] = (uint8_t)(nv->add_fw_opt[0] |
558fcf3ce44SJohn Forte 			    BIT_5);
559fcf3ce44SJohn Forte 		}
560fcf3ce44SJohn Forte 
561fcf3ce44SJohn Forte 		/*
562fcf3ce44SJohn Forte 		 * Set default host adapter parameters
563fcf3ce44SJohn Forte 		 */
564fcf3ce44SJohn Forte 		nv->host_p[0] = BIT_1;
565fcf3ce44SJohn Forte 		nv->host_p[1] = BIT_2;
566fcf3ce44SJohn Forte 		nv->reset_delay = 5;
567fcf3ce44SJohn Forte 		nv->port_down_retry_count = 8;
568fcf3ce44SJohn Forte 		nv->maximum_luns_per_target[0] = 8;
569fcf3ce44SJohn Forte 
570fcf3ce44SJohn Forte 		rval = QL_FUNCTION_FAILED;
571fcf3ce44SJohn Forte 	}
572fcf3ce44SJohn Forte 
573fcf3ce44SJohn Forte 	/* Check for adapter node name (big endian). */
574fcf3ce44SJohn Forte 	for (cnt = 0; cnt < 8; cnt++) {
575fcf3ce44SJohn Forte 		if (nv->node_name[cnt] != 0) {
576fcf3ce44SJohn Forte 			break;
577fcf3ce44SJohn Forte 		}
578fcf3ce44SJohn Forte 	}
579fcf3ce44SJohn Forte 
580fcf3ce44SJohn Forte 	/* Copy port name if no node name (big endian). */
581fcf3ce44SJohn Forte 	if (cnt == 8) {
582fcf3ce44SJohn Forte 		bcopy((void *)&nv->port_name[0], (void *)&nv->node_name[0], 8);
583fcf3ce44SJohn Forte 		nv->node_name[0] = (uint8_t)(nv->node_name[0] & ~BIT_0);
584fcf3ce44SJohn Forte 		nv->port_name[0] = (uint8_t)(nv->node_name[0] | BIT_0);
585fcf3ce44SJohn Forte 	}
586fcf3ce44SJohn Forte 
587fcf3ce44SJohn Forte 	/* Reset initialization control blocks. */
588fcf3ce44SJohn Forte 	bzero((void *)icb, sizeof (ql_init_cb_t));
589fcf3ce44SJohn Forte 
590fcf3ce44SJohn Forte 	/* Get driver properties. */
591fcf3ce44SJohn Forte 	ql_23_properties(ha, nv);
592fcf3ce44SJohn Forte 
593fcf3ce44SJohn Forte 	cmn_err(CE_CONT, "!Qlogic %s(%d) WWPN=%02x%02x%02x%02x"
594fcf3ce44SJohn Forte 	    "%02x%02x%02x%02x : WWNN=%02x%02x%02x%02x%02x%02x%02x%02x\n",
595fcf3ce44SJohn Forte 	    QL_NAME, ha->instance, nv->port_name[0], nv->port_name[1],
596fcf3ce44SJohn Forte 	    nv->port_name[2], nv->port_name[3], nv->port_name[4],
597fcf3ce44SJohn Forte 	    nv->port_name[5], nv->port_name[6], nv->port_name[7],
598fcf3ce44SJohn Forte 	    nv->node_name[0], nv->node_name[1], nv->node_name[2],
599fcf3ce44SJohn Forte 	    nv->node_name[3], nv->node_name[4], nv->node_name[5],
600fcf3ce44SJohn Forte 	    nv->node_name[6], nv->node_name[7]);
601fcf3ce44SJohn Forte 
602fcf3ce44SJohn Forte 	/*
603fcf3ce44SJohn Forte 	 * Copy over NVRAM RISC parameter block
604fcf3ce44SJohn Forte 	 * to initialization control block.
605fcf3ce44SJohn Forte 	 */
606fcf3ce44SJohn Forte 	dptr1 = (caddr_t)icb;
607fcf3ce44SJohn Forte 	dptr2 = (caddr_t)&nv->parameter_block_version;
608fcf3ce44SJohn Forte 	cnt = (uint32_t)((uintptr_t)&icb->request_q_outpointer[0] -
609fcf3ce44SJohn Forte 	    (uintptr_t)&icb->version);
610fcf3ce44SJohn Forte 	while (cnt-- != 0) {
611fcf3ce44SJohn Forte 		*dptr1++ = *dptr2++;
612fcf3ce44SJohn Forte 	}
613fcf3ce44SJohn Forte 
614fcf3ce44SJohn Forte 	/* Copy 2nd half. */
615fcf3ce44SJohn Forte 	dptr1 = (caddr_t)&icb->add_fw_opt[0];
616fcf3ce44SJohn Forte 	cnt = (uint32_t)((uintptr_t)&icb->reserved_3[0] -
617fcf3ce44SJohn Forte 	    (uintptr_t)&icb->add_fw_opt[0]);
618fcf3ce44SJohn Forte 
619fcf3ce44SJohn Forte 	while (cnt-- != 0) {
620fcf3ce44SJohn Forte 		*dptr1++ = *dptr2++;
621fcf3ce44SJohn Forte 	}
622fcf3ce44SJohn Forte 
623fcf3ce44SJohn Forte 	/*
624fcf3ce44SJohn Forte 	 * Setup driver firmware options.
625fcf3ce44SJohn Forte 	 */
626fcf3ce44SJohn Forte 	icb->firmware_options[0] = (uint8_t)
627fcf3ce44SJohn Forte 	    (icb->firmware_options[0] | BIT_6 | BIT_1);
628fcf3ce44SJohn Forte 
629fcf3ce44SJohn Forte 	/*
630fcf3ce44SJohn Forte 	 * There is no use enabling fast post for SBUS or 2300
6315dfd244aSDaniel Beauregard 	 * Always enable 64bit addressing, except SBUS cards.
632fcf3ce44SJohn Forte 	 */
6335dfd244aSDaniel Beauregard 	ha->cfg_flags |= CFG_ENABLE_64BIT_ADDRESSING;
634fcf3ce44SJohn Forte 	if (CFG_IST(ha, (CFG_SBUS_CARD | CFG_CTRL_2300 | CFG_CTRL_6322))) {
635fcf3ce44SJohn Forte 		icb->firmware_options[0] = (uint8_t)
636fcf3ce44SJohn Forte 		    (icb->firmware_options[0] & ~BIT_3);
637fcf3ce44SJohn Forte 		if (CFG_IST(ha, CFG_SBUS_CARD)) {
638fcf3ce44SJohn Forte 			icb->special_options[0] = (uint8_t)
639fcf3ce44SJohn Forte 			    (icb->special_options[0] | BIT_5);
6405dfd244aSDaniel Beauregard 			ha->cfg_flags &= ~CFG_ENABLE_64BIT_ADDRESSING;
641fcf3ce44SJohn Forte 		}
642fcf3ce44SJohn Forte 	} else {
643fcf3ce44SJohn Forte 		icb->firmware_options[0] = (uint8_t)
644fcf3ce44SJohn Forte 		    (icb->firmware_options[0] | BIT_3);
645fcf3ce44SJohn Forte 	}
646fcf3ce44SJohn Forte 	/* RIO and ZIO not supported. */
647fcf3ce44SJohn Forte 	icb->add_fw_opt[0] = (uint8_t)(icb->add_fw_opt[0] &
648fcf3ce44SJohn Forte 	    ~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
649fcf3ce44SJohn Forte 
650fcf3ce44SJohn Forte 	icb->firmware_options[1] = (uint8_t)(icb->firmware_options[1] |
651fcf3ce44SJohn Forte 	    BIT_7 | BIT_6 | BIT_5 | BIT_2 | BIT_0);
652fcf3ce44SJohn Forte 	icb->firmware_options[0] = (uint8_t)
653fcf3ce44SJohn Forte 	    (icb->firmware_options[0] & ~(BIT_5 | BIT_4));
654fcf3ce44SJohn Forte 	icb->firmware_options[1] = (uint8_t)
655fcf3ce44SJohn Forte 	    (icb->firmware_options[1] & ~BIT_4);
656fcf3ce44SJohn Forte 
657fcf3ce44SJohn Forte 	icb->add_fw_opt[1] = (uint8_t)(icb->add_fw_opt[1] & ~(BIT_5 | BIT_4));
658fcf3ce44SJohn Forte 	icb->special_options[0] = (uint8_t)(icb->special_options[0] | BIT_1);
659fcf3ce44SJohn Forte 
660fcf3ce44SJohn Forte 	if (CFG_IST(ha, (CFG_CTRL_2300 | CFG_CTRL_6322))) {
661fcf3ce44SJohn Forte 		if ((icb->special_options[1] & 0x20) == 0) {
662fcf3ce44SJohn Forte 			EL(ha, "50 ohm is not set\n");
663fcf3ce44SJohn Forte 		}
664fcf3ce44SJohn Forte 	}
665fcf3ce44SJohn Forte 	icb->execution_throttle[0] = 0xff;
666fcf3ce44SJohn Forte 	icb->execution_throttle[1] = 0xff;
667fcf3ce44SJohn Forte 
668fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_ENABLE_FCP_2_SUPPORT)) {
669fcf3ce44SJohn Forte 		icb->firmware_options[1] = (uint8_t)
670fcf3ce44SJohn Forte 		    (icb->firmware_options[1] | BIT_7 | BIT_6);
671fcf3ce44SJohn Forte 		icb->add_fw_opt[1] = (uint8_t)
672fcf3ce44SJohn Forte 		    (icb->add_fw_opt[1] | BIT_5 | BIT_4);
673fcf3ce44SJohn Forte 	}
674fcf3ce44SJohn Forte 
675fcf3ce44SJohn Forte 	/*
676fcf3ce44SJohn Forte 	 * Set host adapter parameters
677fcf3ce44SJohn Forte 	 */
678fcf3ce44SJohn Forte 	ADAPTER_STATE_LOCK(ha);
679fcf3ce44SJohn Forte 	ha->nvram_version = nv->nvram_version;
680fcf3ce44SJohn Forte 	ha->adapter_features = CHAR_TO_SHORT(nv->adapter_features[0],
681fcf3ce44SJohn Forte 	    nv->adapter_features[1]);
682fcf3ce44SJohn Forte 
683fcf3ce44SJohn Forte 	nv->host_p[0] & BIT_4 ? (ha->cfg_flags |= CFG_DISABLE_RISC_CODE_LOAD) :
684fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_DISABLE_RISC_CODE_LOAD);
685fcf3ce44SJohn Forte 	nv->host_p[0] & BIT_5 ? (ha->cfg_flags |= CFG_SET_CACHE_LINE_SIZE_1) :
686fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_SET_CACHE_LINE_SIZE_1);
687fcf3ce44SJohn Forte 
688fcf3ce44SJohn Forte 	nv->host_p[1] & BIT_1 ? (ha->cfg_flags |= CFG_ENABLE_LIP_RESET) :
689fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_ENABLE_LIP_RESET);
690fcf3ce44SJohn Forte 	nv->host_p[1] & BIT_2 ? (ha->cfg_flags |= CFG_ENABLE_FULL_LIP_LOGIN) :
691fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_ENABLE_FULL_LIP_LOGIN);
692fcf3ce44SJohn Forte 	nv->host_p[1] & BIT_3 ? (ha->cfg_flags |= CFG_ENABLE_TARGET_RESET) :
693fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_ENABLE_TARGET_RESET);
694fcf3ce44SJohn Forte 
695fcf3ce44SJohn Forte 	nv->adapter_features[0] & BIT_3 ?
696fcf3ce44SJohn Forte 	    (ha->cfg_flags |= CFG_MULTI_CHIP_ADAPTER) :
697fcf3ce44SJohn Forte 	    (ha->cfg_flags &= ~CFG_MULTI_CHIP_ADAPTER);
698fcf3ce44SJohn Forte 
699fcf3ce44SJohn Forte 	ADAPTER_STATE_UNLOCK(ha);
700fcf3ce44SJohn Forte 
701fcf3ce44SJohn Forte 	ha->execution_throttle = CHAR_TO_SHORT(nv->execution_throttle[0],
702fcf3ce44SJohn Forte 	    nv->execution_throttle[1]);
703fcf3ce44SJohn Forte 	ha->loop_reset_delay = nv->reset_delay;
704fcf3ce44SJohn Forte 	ha->port_down_retry_count = nv->port_down_retry_count;
705fcf3ce44SJohn Forte 	ha->r_a_tov = (uint16_t)(icb->login_timeout < R_A_TOV_DEFAULT ?
706fcf3ce44SJohn Forte 	    R_A_TOV_DEFAULT : icb->login_timeout);
707fcf3ce44SJohn Forte 	ha->maximum_luns_per_target = CHAR_TO_SHORT(
708fcf3ce44SJohn Forte 	    nv->maximum_luns_per_target[0], nv->maximum_luns_per_target[1]);
709fcf3ce44SJohn Forte 	if (ha->maximum_luns_per_target == 0) {
710fcf3ce44SJohn Forte 		ha->maximum_luns_per_target++;
711fcf3ce44SJohn Forte 	}
712fcf3ce44SJohn Forte 
713fcf3ce44SJohn Forte 	/*
714fcf3ce44SJohn Forte 	 * Setup ring parameters in initialization control block
715fcf3ce44SJohn Forte 	 */
716fcf3ce44SJohn Forte 	cnt = REQUEST_ENTRY_CNT;
717fcf3ce44SJohn Forte 	icb->request_q_length[0] = LSB(cnt);
718fcf3ce44SJohn Forte 	icb->request_q_length[1] = MSB(cnt);
719fcf3ce44SJohn Forte 	cnt = RESPONSE_ENTRY_CNT;
720fcf3ce44SJohn Forte 	icb->response_q_length[0] = LSB(cnt);
721fcf3ce44SJohn Forte 	icb->response_q_length[1] = MSB(cnt);
722fcf3ce44SJohn Forte 
723fcf3ce44SJohn Forte 	icb->request_q_address[0] = LSB(LSW(LSD(ha->request_dvma)));
724fcf3ce44SJohn Forte 	icb->request_q_address[1] = MSB(LSW(LSD(ha->request_dvma)));
725fcf3ce44SJohn Forte 	icb->request_q_address[2] = LSB(MSW(LSD(ha->request_dvma)));
726fcf3ce44SJohn Forte 	icb->request_q_address[3] = MSB(MSW(LSD(ha->request_dvma)));
727fcf3ce44SJohn Forte 	icb->request_q_address[4] = LSB(LSW(MSD(ha->request_dvma)));
728fcf3ce44SJohn Forte 	icb->request_q_address[5] = MSB(LSW(MSD(ha->request_dvma)));
729fcf3ce44SJohn Forte 	icb->request_q_address[6] = LSB(MSW(MSD(ha->request_dvma)));
730fcf3ce44SJohn Forte 	icb->request_q_address[7] = MSB(MSW(MSD(ha->request_dvma)));
731fcf3ce44SJohn Forte 
732fcf3ce44SJohn Forte 	icb->response_q_address[0] = LSB(LSW(LSD(ha->response_dvma)));
733fcf3ce44SJohn Forte 	icb->response_q_address[1] = MSB(LSW(LSD(ha->response_dvma)));
734fcf3ce44SJohn Forte 	icb->response_q_address[2] = LSB(MSW(LSD(ha->response_dvma)));
735fcf3ce44SJohn Forte 	icb->response_q_address[3] = MSB(MSW(LSD(ha->response_dvma)));
736fcf3ce44SJohn Forte 	icb->response_q_address[4] = LSB(LSW(MSD(ha->response_dvma)));
737fcf3ce44SJohn Forte 	icb->response_q_address[5] = MSB(LSW(MSD(ha->response_dvma)));
738fcf3ce44SJohn Forte 	icb->response_q_address[6] = LSB(MSW(MSD(ha->response_dvma)));
739fcf3ce44SJohn Forte 	icb->response_q_address[7] = MSB(MSW(MSD(ha->response_dvma)));
740fcf3ce44SJohn Forte 
741fcf3ce44SJohn Forte 	/*
742fcf3ce44SJohn Forte 	 * Setup IP initialization control block
743fcf3ce44SJohn Forte 	 */
744fcf3ce44SJohn Forte 	ip_icb->version = IP_ICB_VERSION;
745fcf3ce44SJohn Forte 
746fcf3ce44SJohn Forte 	if (CFG_IST(ha, CFG_ENABLE_64BIT_ADDRESSING)) {
747fcf3ce44SJohn Forte 		ip_icb->ip_firmware_options[0] = (uint8_t)
748fcf3ce44SJohn Forte 		    (ip_icb->ip_firmware_options[0] | BIT_2 | BIT_0);
749fcf3ce44SJohn Forte 	} else {
750fcf3ce44SJohn Forte 		ip_icb->ip_firmware_options[0] = (uint8_t)
751fcf3ce44SJohn Forte 		    (ip_icb->ip_firmware_options[0] | BIT_2);
752fcf3ce44SJohn Forte 	}
753fcf3ce44SJohn Forte 
754fcf3ce44SJohn Forte 	cnt = RCVBUF_CONTAINER_CNT;
755fcf3ce44SJohn Forte 	ip_icb->queue_size[0] = LSB(cnt);
756fcf3ce44SJohn Forte 	ip_icb->queue_size[1] = MSB(cnt);
757fcf3ce44SJohn Forte 
758fcf3ce44SJohn Forte 	ip_icb->queue_address[0] = LSB(LSW(LSD(ha->rcvbuf_dvma)));
759fcf3ce44SJohn Forte 	ip_icb->queue_address[1] = MSB(LSW(LSD(ha->rcvbuf_dvma)));
760fcf3ce44SJohn Forte 	ip_icb->queue_address[2] = LSB(MSW(LSD(ha->rcvbuf_dvma)));
761fcf3ce44SJohn Forte 	ip_icb->queue_address[3] = MSB(MSW(LSD(ha->rcvbuf_dvma)));
762fcf3ce44SJohn Forte 	ip_icb->queue_address[4] = LSB(LSW(MSD(ha->rcvbuf_dvma)));
763fcf3ce44SJohn Forte 	ip_icb->queue_address[5] = MSB(LSW(MSD(ha->rcvbuf_dvma)));
764fcf3ce44SJohn Forte 	ip_icb->queue_address[6] = LSB(MSW(MSD(ha->rcvbuf_dvma)));
765fcf3ce44SJohn Forte 	ip_icb->queue_address[7] = MSB(MSW(MSD(ha->rcvbuf_dvma)));
766fcf3ce44SJohn Forte 
767fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS) {
768fcf3ce44SJohn Forte 		EL(ha, "failed, rval = %xh\n", rval);
769fcf3ce44SJohn Forte 	} else {
770fcf3ce44SJohn Forte 		/*EMPTY*/
771fcf3ce44SJohn Forte 		QL_PRINT_3(CE_CONT, "(%d): done\n", ha->instance);
772fcf3ce44SJohn Forte 	}
773fcf3ce44SJohn Forte 	return (rval);
774fcf3ce44SJohn Forte }
775fcf3ce44SJohn Forte 
776fcf3ce44SJohn Forte /*
777fcf3ce44SJohn Forte  * Get NVRAM data word
778fcf3ce44SJohn Forte  *	Calculates word position in NVRAM and calls request routine to
779fcf3ce44SJohn Forte  *	get the word from NVRAM.
780fcf3ce44SJohn Forte  *
781fcf3ce44SJohn Forte  * Input:
782fcf3ce44SJohn Forte  *	ha = adapter state pointer.
783fcf3ce44SJohn Forte  *	address = NVRAM word address.
784fcf3ce44SJohn Forte  *
785fcf3ce44SJohn Forte  * Returns:
786fcf3ce44SJohn Forte  *	data word.
787fcf3ce44SJohn Forte  *
788fcf3ce44SJohn Forte  * Context:
789fcf3ce44SJohn Forte  *	Kernel context.
790fcf3ce44SJohn Forte  */
791fcf3ce44SJohn Forte uint16_t
ql_get_nvram_word(ql_adapter_state_t * ha,uint32_t address)792fcf3ce44SJohn Forte ql_get_nvram_word(ql_adapter_state_t *ha, uint32_t address)
793fcf3ce44SJohn Forte {
794fcf3ce44SJohn Forte 	uint32_t	nv_cmd;
795fcf3ce44SJohn Forte 	uint16_t	rval;
796fcf3ce44SJohn Forte 
797fcf3ce44SJohn Forte 	QL_PRINT_4(CE_CONT, "(%d): started\n", ha->instance);
798fcf3ce44SJohn Forte 
799fcf3ce44SJohn Forte 	nv_cmd = address << 16;
800fcf3ce44SJohn Forte 	nv_cmd = nv_cmd | NV_READ_OP;
801fcf3ce44SJohn Forte 
802fcf3ce44SJohn Forte 	rval = (uint16_t)ql_nvram_request(ha, nv_cmd);
803fcf3ce44SJohn Forte 
804fcf3ce44SJohn Forte 	QL_PRINT_4(CE_CONT, "(%d): NVRAM data = %xh\n", ha->instance, rval);
805fcf3ce44SJohn Forte 
806fcf3ce44SJohn Forte 	return (rval);
807fcf3ce44SJohn Forte }
808fcf3ce44SJohn Forte 
809fcf3ce44SJohn Forte /*
810fcf3ce44SJohn Forte  * NVRAM request
811fcf3ce44SJohn Forte  *	Sends read command to NVRAM and gets data from NVRAM.
812fcf3ce44SJohn Forte  *
813fcf3ce44SJohn Forte  * Input:
814fcf3ce44SJohn Forte  *	ha = adapter state pointer.
815fcf3ce44SJohn Forte  *	nv_cmd = Bit 26= start bit
816fcf3ce44SJohn Forte  *	Bit 25, 24 = opcode
817fcf3ce44SJohn Forte  *	Bit 23-16 = address
818fcf3ce44SJohn Forte  *	Bit 15-0 = write data
819fcf3ce44SJohn Forte  *
820fcf3ce44SJohn Forte  * Returns:
821fcf3ce44SJohn Forte  *	data word.
822fcf3ce44SJohn Forte  *
823fcf3ce44SJohn Forte  * Context:
824fcf3ce44SJohn Forte  *	Kernel context.
825fcf3ce44SJohn Forte  */
826fcf3ce44SJohn Forte static uint16_t
ql_nvram_request(ql_adapter_state_t * ha,uint32_t nv_cmd)827fcf3ce44SJohn Forte ql_nvram_request(ql_adapter_state_t *ha, uint32_t nv_cmd)
828fcf3ce44SJohn Forte {
829fcf3ce44SJohn Forte 	uint8_t		cnt;
830fcf3ce44SJohn Forte 	uint16_t	reg_data;
831fcf3ce44SJohn Forte 	uint16_t	data = 0;
832fcf3ce44SJohn Forte 
833fcf3ce44SJohn Forte 	/* Send command to NVRAM. */
834fcf3ce44SJohn Forte 
835fcf3ce44SJohn Forte 	nv_cmd <<= 5;
836fcf3ce44SJohn Forte 	for (cnt = 0; cnt < 11; cnt++) {
837fcf3ce44SJohn Forte 		if (nv_cmd & BIT_31) {
838fcf3ce44SJohn Forte 			ql_nv_write(ha, NV_DATA_OUT);
839fcf3ce44SJohn Forte 		} else {
840fcf3ce44SJohn Forte 			ql_nv_write(ha, 0);
841fcf3ce44SJohn Forte 		}
842fcf3ce44SJohn Forte 		nv_cmd <<= 1;
843fcf3ce44SJohn Forte 	}
844fcf3ce44SJohn Forte 
845fcf3ce44SJohn Forte 	/* Read data from NVRAM. */
846fcf3ce44SJohn Forte 
847fcf3ce44SJohn Forte 	for (cnt = 0; cnt < 16; cnt++) {
848fcf3ce44SJohn Forte 		WRT16_IO_REG(ha, nvram, NV_SELECT+NV_CLOCK);
849fcf3ce44SJohn Forte 		ql_nv_delay();
850fcf3ce44SJohn Forte 		data <<= 1;
851fcf3ce44SJohn Forte 		reg_data = RD16_IO_REG(ha, nvram);
852fcf3ce44SJohn Forte 		if (reg_data & NV_DATA_IN) {
853fcf3ce44SJohn Forte 			data = (uint16_t)(data | BIT_0);
854fcf3ce44SJohn Forte 		}
855fcf3ce44SJohn Forte 		WRT16_IO_REG(ha, nvram, NV_SELECT);
856fcf3ce44SJohn Forte 		ql_nv_delay();
857fcf3ce44SJohn Forte 	}
858fcf3ce44SJohn Forte 
859fcf3ce44SJohn Forte 	/* Deselect chip. */
860fcf3ce44SJohn Forte 
861fcf3ce44SJohn Forte 	WRT16_IO_REG(ha, nvram, NV_DESELECT);
862fcf3ce44SJohn Forte 	ql_nv_delay();
863fcf3ce44SJohn Forte 
864fcf3ce44SJohn Forte 	return (data);
865fcf3ce44SJohn Forte }
866fcf3ce44SJohn Forte 
867fcf3ce44SJohn Forte void
ql_nv_write(ql_adapter_state_t * ha,uint16_t data)868fcf3ce44SJohn Forte ql_nv_write(ql_adapter_state_t *ha, uint16_t data)
869fcf3ce44SJohn Forte {
870fcf3ce44SJohn Forte 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
871fcf3ce44SJohn Forte 	ql_nv_delay();
872fcf3ce44SJohn Forte 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT | NV_CLOCK));
873fcf3ce44SJohn Forte 	ql_nv_delay();
874fcf3ce44SJohn Forte 	WRT16_IO_REG(ha, nvram, (uint16_t)(data | NV_SELECT));
875fcf3ce44SJohn Forte 	ql_nv_delay();
876fcf3ce44SJohn Forte }
877fcf3ce44SJohn Forte 
878fcf3ce44SJohn Forte void
ql_nv_delay(void)8795dfd244aSDaniel Beauregard ql_nv_delay(void)
8805dfd244aSDaniel Beauregard {
881fcf3ce44SJohn Forte 	drv_usecwait(NV_DELAY_COUNT);
882fcf3ce44SJohn Forte }
883fcf3ce44SJohn Forte 
884fcf3ce44SJohn Forte /*
885fcf3ce44SJohn Forte  * ql_nvram_24xx_config
886fcf3ce44SJohn Forte  *	ISP2400 nvram.
887fcf3ce44SJohn Forte  *
888fcf3ce44SJohn Forte  * Input:
889fcf3ce44SJohn Forte  *	ha:		adapter state pointer.
890fcf3ce44SJohn Forte  *	ha->hba_buf = request and response rings
891fcf3ce44SJohn Forte  *
892fcf3ce44SJohn Forte  * Output:
893fcf3ce44SJohn Forte  *	ha->init_ctrl_blk = initialization control block
894fcf3ce44SJohn Forte  *	host adapters parameters in host adapter block
895fcf3ce44SJohn Forte  *
896fcf3ce44SJohn Forte  * Returns:
897fcf3ce44SJohn Forte  *	ql local function return status code.
898fcf3ce44SJohn Forte  *
899fcf3ce44SJohn Forte  * Context:
900fcf3ce44SJohn Forte  *	Kernel context.
901fcf3ce44SJohn Forte  */
902fcf3ce44SJohn Forte int
ql_nvram_24xx_config(ql_adapter_state_t * ha)903fcf3ce44SJohn Forte ql_nvram_24xx_config(ql_adapter_state_t *ha)
904fcf3ce44SJohn Forte {
905fcf3ce44SJohn Forte 	uint32_t		index, addr, chksum, saved_chksum;
906fcf3ce44SJohn Forte 	uint32_t		*longptr;
907fcf3ce44SJohn Forte 	nvram_24xx_t		nvram;
908fcf3ce44SJohn Forte 	int			idpromlen;
909fcf3ce44SJohn Forte 	char			idprombuf[32];
910fcf3ce44SJohn Forte 	caddr_t			src, dst;
911fcf3ce44SJohn Forte 	uint16_t		w1;
912fcf3ce44SJohn Forte 	int			rval;
913fcf3ce44SJohn Forte 	nvram_24xx_t		*nv = (nvram_24xx_t *)&nvram;
914fcf3ce44SJohn Forte 	ql_init_24xx_cb_t	*icb =
915fcf3ce44SJohn Forte 	    (ql_init_24xx_cb_t *)&ha->init_ctrl_blk.cb24;
916fcf3ce44SJohn Forte 	ql_ip_init_24xx_cb_t	*ip_icb = &ha->ip_init_ctrl_blk.cb24;
917fcf3ce44SJohn Forte 
918fcf3ce44SJohn Forte 	QL_PRINT_3(CE_CONT, "(%d): started\n", ha->instance);
919fcf3ce44SJohn Forte 
920fcf3ce44SJohn Forte 	if ((rval = ql_lock_nvram(ha, &addr, LNF_NVRAM_DATA)) == QL_SUCCESS) {
921fcf3ce44SJohn Forte 
922fcf3ce44SJohn Forte 		/* Get NVRAM data and calculate checksum. */
923fcf3ce44SJohn Forte 		longptr = (uint32_t *)nv;
924fcf3ce44SJohn Forte 		chksum = saved_chksum = 0;
925fcf3ce44SJohn Forte 		for (index = 0; index < sizeof (nvram_24xx_t) / 4; index++) {
926fcf3ce44SJohn Forte 			rval = ql_24xx_read_flash(ha, addr++, longptr);
927fcf3ce44SJohn Forte 			if (rval != QL_SUCCESS) {
928fcf3ce44SJohn Forte 				EL(ha, "24xx_read_flash failed=%xh\n", rval);
929fcf3ce44SJohn Forte 				break;
930fcf3ce44SJohn Forte 			}
931fcf3ce44SJohn Forte 			saved_chksum = chksum;
932fcf3ce44SJohn Forte 			chksum += *longptr;
933fcf3ce44SJohn Forte 			LITTLE_ENDIAN_32(longptr);
934fcf3ce44SJohn Forte 			longptr++;
935fcf3ce44SJohn Forte 		}
936fcf3ce44SJohn Forte 
937fcf3ce44SJohn Forte 		ql_release_nvram(ha);
938fcf3ce44SJohn Forte 	}
939fcf3ce44SJohn Forte 
940fcf3ce44SJohn Forte 	/* Bad NVRAM data, set defaults parameters. */
941fcf3ce44SJohn Forte 	if (rval != QL_SUCCESS || chksum || nv->id[0] != 'I' ||
942fcf3ce44SJohn Forte 	    nv->id[1] != 'S' || nv->id[2] != 'P' || nv->id[3] != ' ' ||
943fcf3ce44SJohn Forte 	    (nv->nvram_version[0] | nv->nvram_version[1]) == 0) {
944fcf3ce44SJohn Forte 
945fcf3ce44SJohn Forte 		cmn_err(CE_WARN, "%s(%d): NVRAM configuration failed, using "
946fcf3ce44SJohn Forte 		    "driver defaults.", QL_NAME, ha->instance);
947fcf3ce44SJohn Forte 
948fcf3ce44SJohn Forte 		EL(ha, "failed, rval=%xh, checksum=%xh, id=%c%c%c%c, "
949fcf3ce44SJohn Forte 		    "nvram_version=%x\n", rval, chksum, nv->id[0], nv->id[1],
950fcf3ce44SJohn Forte 		    nv->id[2], nv->id[3], CHAR_TO_SHORT(nv->nvram_version[0],
951fcf3ce44SJohn Forte 		    nv->nvram_version[1]));
952fcf3ce44SJohn Forte 
953fcf3ce44SJohn Forte 		saved_chksum = ~saved_chksum + 1;
954fcf3ce44SJohn Forte 
955fcf3ce44SJohn Forte 		(void) ql_flash_errlog(ha, FLASH_ERRLOG_NVRAM_CHKSUM_ERR, 0,
956fcf3ce44SJohn Forte 		    MSW(saved_chksum), LSW(saved_chksum));
957fcf3ce44SJohn Forte 
958fcf3ce44SJohn Forte 		/* Reset NVRAM data. */
959fcf3ce44SJohn Forte 		bzero((void *)nv, sizeof (nvram_24xx_t));
960fcf3ce44SJohn Forte 
961fcf3ce44SJohn Forte 		/*
962fcf3ce44SJohn Forte 		 * Set default initialization control block.
963fcf3ce44SJohn Forte 		 */
964fcf3ce44SJohn Forte 		nv->nvram_version[0] = LSB(ICB_24XX_VERSION);
965fcf3ce44SJohn Forte 		nv->nvram_version[1] = MSB(ICB_24XX_VERSION);
966fcf3ce44SJohn Forte 
967fcf3ce44SJohn Forte 		nv->version[0] = 1;
968fcf3ce44SJohn Forte 		nv->max_frame_length[1] = 8;
969fcf3ce44SJohn Forte 		nv->execution_throttle[0] = 16;
970eb82ff87SDaniel Beauregard 		nv->exchange_count[0] = 128;
971fcf3ce44SJohn Forte 		nv->max_luns_per_target[0] = 8;
972fcf3ce44SJohn Forte 
973fcf3ce44SJohn Forte 		idpromlen = 32;
974fcf3ce44SJohn Forte 
975fcf3ce44SJohn Forte 		/*LINTED [Solaris DDI_DEV_T_ANY Lint warning]*/
97616dd44c2SDaniel Beauregard 		if (rval = ddi_getlongprop_buf(DDI_DEV_T_ANY, ha->dip,
977fcf3ce44SJohn Forte 		    DDI_PROP_CANSLEEP, "idprom", (caddr_t)idprombuf,
978fcf3ce44SJohn Forte 		    &idpromlen) != DDI_PROP_SUCCESS) {
979fcf3ce44SJohn Forte 
980fcf3ce44SJohn Forte 			cmn_err(CE_WARN, "%s(%d) : Unable to read idprom "
98116dd44c2SDaniel Beauregard 			    "property, rval=%x", QL_NAME, ha->instance, rval);
982fcf3ce44SJohn Forte 
983fcf3ce44SJohn Forte 			nv->port_name[0] = 33;
984fcf3ce44SJohn Forte 			nv->port_name[3] = 224;
985fcf3ce44SJohn Forte 			nv->port_name[4] = 139;
986fcf3ce44SJohn Forte 			nv->port_name[7] = (uint8_t)
987fcf3ce44SJohn Forte 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
988fcf3ce44SJohn Forte 		} else {
989fcf3ce44SJohn Forte 			nv->port_name[2] = idprombuf[2];
990fcf3ce44SJohn Forte 			nv->port_name[3] = idprombuf[3];
991fcf3ce44SJohn Forte 			nv->port_name[4] = idprombuf[4];
992fcf3ce44SJohn Forte 			nv->port_name[5] = idprombuf[5];
993fcf3ce44SJohn Forte 			nv->port_name[6] = idprombuf[6];
994fcf3ce44SJohn Forte 			nv->port_name[7] = idprombuf[7];
995fcf3ce44SJohn Forte 			nv->port_name[0] = (uint8_t)
996fcf3ce44SJohn Forte 			    (NAA_ID_IEEE_EXTENDED << 4 | ha->instance);
997fcf3ce44SJohn Forte 		}
998fcf3ce44SJohn Forte 
999fcf3ce44SJohn Forte 		cmn_err(CE_WARN, "%s(%d): Unreliable HBA NVRAM, using default "
1000fcf3ce44SJohn Forte 		    "HBA parameters and temporary "
1001fcf3ce44SJohn Forte 		    "WWPN: %02x%02x%02x%02x%02x%02x%02x%02x", QL_NAME,
1002fcf3ce44SJohn Forte 		    ha->instance, nv->port_name[0], nv->port_name[1],
1003fcf3ce44SJohn Forte 		    nv->port_name[2], nv->port_name[3], nv->port_name[4],
1004fcf3ce44SJohn Forte 		    nv->port_name[5], nv->port_name[6], nv->port_name[7]);
1005fcf3ce44SJohn Forte 
1006fcf3ce44SJohn Forte 		nv->login_retry_count[0] = 8;
1007fcf3ce44SJohn Forte 
1008fcf3ce44SJohn Forte 		nv->firmware_options_1[0] = BIT_2 | BIT_1;
1009fcf3ce44SJohn Forte 		nv->firmware_options_1[1] = BIT_5;
1010fcf3ce44SJohn Forte 		nv->firmware_options_2[0] = BIT_5;
1011fcf3ce44SJohn Forte 		nv->firmware_options_2[1] = BIT_4;
1012fcf3ce44SJohn Forte 		nv->firmware_options_3[1] = BIT_6;
1013fcf3ce44SJohn Forte 
1014fcf3ce44SJohn Forte 		/*
1015fcf3ce44SJohn Forte 		 * Set default host adapter parameters
1016fcf3ce44SJohn Forte 		 */
1017fcf3ce44SJohn Forte 		nv->host_p[0] = BIT_4 | BIT_1;
1018fcf3ce44SJohn Forte 		nv->host_p[1] = BIT_3 | BIT_2;